vlambda博客
学习文章列表

java系统架构常见问题解答

 jdk相关

1 Java常用集合的区别以及用法  

1.1 Set List区别  

Set是无序的元素不可重复  List是有序可重复 

1.2 hashmap的数据结构

链表加数组 通过拉链法解决hash碰撞。相同的hashCode会在对应数组元素底下放链表,链表长度超过8会转化成红黑树,红黑树元素低于6转化成链表。初始长度为16膨胀系数为2负载因子0.75

 

1.3 HashMap reHash过程 为什么会有死循环 怎么解决

HashMap的元素个数超过当前容量的0.75倍时,将会触发HashMap reHash操作,长度扩展为原来的2倍。

 

并发的情况,发生扩容时,可能会产生循环链表,在执行get的时候,会触发死循环,引起CPU的100%问题

解决的办法是并发环境用ConcurrentHashMap,只有在单线程的情况下才采用HashMap  

   

 

1.4 ConcurrentHash  

ConcurrentHashMap采用分段锁的方式来实现并发访问,将数组分成八段,同一时间只有一段加锁。Jdk1.8以后采用cas乐观锁的方式实现并发访问。

2 多线程 

2.1线程有哪几种状态,

线程有等待,就绪,阻塞,运行,销毁等状态

 

 

2.2多线程的实现方式有哪些?

多线程通过实现Runnable接口或继承Thread类并重写run()方法来实现多线程,或者通过线程池的方式来创建多线程。

 

2.3线程池有哪些参数 以及参数的含义

corePoolSize:线程池核心线程大小

线程池中会维护一个最小的线程数量,即使这些线程处理空闲状态,他们也不会被销毁,除非设置了allowCoreThreadTimeOut。这里的最小线程数量即是corePoolSize。

 

maximumPoolSize:线程池最大线程数量

一个任务被提交到线程池以后,首先会找有没有空闲存活线程,如果有则直接将任务交给这个空闲线程来执行,如果没有则会缓存到工作队列(后面会介绍)中,如果工作队列满了,才会创建一个新线程,然后从工作队列的头部取出一个任务交由新线程来处理,而将刚提交的任务放入工作队列尾部。线程池不会无限制的去创建新线程,它会有一个最大线程数量的限制,这个数量即由maximunPoolSize指定。

 

keepAliveTime :空闲线程存活时间

一个线程如果处于空闲状态,并且当前的线程数量大于corePoolSize,那么在指定时间后,这个空闲线程会被销毁,这里的指定时间由keepAliveTime来设定

 

unit:空闲线程存活时间单位,keepAliveTime的计量单位

 

workQueue:工作队列

新任务被提交后,会先进入到此工作队列中,任务调度时再从队列中取出任务。jdk中提供了四种工作队列:

①ArrayBlockingQueue

基于数组的有界阻塞队列,按FIFO排序。新任务进来后,会放到该队列的队尾,有界的数组可以防止资源耗尽问题。当线程池中线程数量达到corePoolSize后,再有新任务进来,则会将任务放入该队列的队尾,等待被调度。如果队列已经是满的,则创建一个新线程,如果线程数量已经达到maxPoolSize,则会执行拒绝策略。

②LinkedBlockingQuene

基于链表的无界阻塞队列(其实最大容量为Interger.MAX),按照FIFO排序。由于该队列的近似无界性,当线程池中线程数量达到corePoolSize后,再有新任务进来,会一直存入该队列,而不会去创建新线程直到maxPoolSize,因此使用该工作队列时,参数maxPoolSize其实是不起作用的。

③SynchronousQuene

一个不缓存任务的阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。也就是说新任务进来时,不会缓存,而是直接被调度执行该任务,如果没有可用线程,则创建新线程,如果线程数量达到maxPoolSize,则执行拒绝策略。

④PriorityBlockingQueue

具有优先级的无界阻塞队列,优先级通过参数Comparator实现。

 

threadFactory:线程工厂

创建一个新线程时使用的工厂,可以用来设定线程名、是否为daemon线程等等

 

Handler:拒绝策略

当工作队列中的任务已到达最大限制,并且线程池中的线程数量也达到最大限制,这时如果有新任务提交进来,该如何处理呢。这里的拒绝策略,就是解决这个问题的,jdk中提供了4拒绝策略:

①CallerRunsPolicy

该策略下,在调用者线程中直接执行被拒绝任务的run方法,除非线程池已经shutdown,则直接抛弃任务。

②AbortPolicy

该策略下,直接丢弃任务,并抛出RejectedExecutionException异常。

③DiscardPolicy

该策略下,直接丢弃任务,什么都不做。

④DiscardOldestPolicy

该策略下,抛弃进入队列最早的那个任务,然后尝试把这次拒绝的任务放入队列

 

2.4   join

sleep()方法只是停掉线程但是不释放资源

wait()方法停掉线程并释放资源

join()方法使线程由并行执行 变成串行执行

yeid()方法暂停当前正在执行的线程,释放资源,执行其他线程

notify()只唤醒一个等待线程,notifyAll()唤醒所有等待线程。

当多个线程互相持有对方需要的资源时会进入死锁状态,解决死锁的办法是加入等待超时机制,等待超时则放弃执行并释放资源。

 

 

 

并发编程锁机制

 

3.1悲观锁 乐观锁的区别, 

悲观锁假设资源竞争一定会有,所以锁死这个资源在一段时间内只能一个线程访问。

乐观锁就是不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止

 

3.2lock

lock是一个接口,而synchronized是java的一个关键字,synchronized是内置的语言实现;synchronized在发生异常时候会自动释放占有的锁,因此不会出现死锁;而lock发生异常时候,不会主动释放占有的锁,必须手动unlock来释放锁,可能引起死锁的发生。(所以最好将同步代码块用try catch包起来,finally中写入unlock,避免死锁的发生。)lock等待锁过程中可以用interrupt来中断等待,而synchronized只能等待锁的释放,不能响应中断;Lock可以通过trylock来知道有没有获取锁,而synchronized不能;

Lock可以提高多个线程进行读操作的效率。(可以通过readwritelock实现读写分离)

在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。所以说,在具体使用时要根据适当情况选择。

synchronized使用Object对象本身的wait 、notify、notifyAll调度机制,而Lock可以使用Condition进行线程之间的调度,

3.3 cas的原理,可能出现的问题 解决方法

cascompare and swap的缩写,意思是比较然后交换,线程带着期望值来,如果期望值和当前值一样则进行操作,如果不一样则不操作,会产生ABA的问题,即比较对象被改过了,又改回来了,导致当前线程以为操作对象没有改过,于是操作产生并发错误。解决办法是加个version版本号,每次修改都要改version,这样就避免了ABA问题。

3.4 AQS的原理,公平锁和非公平锁的区别

 AQS的全称是AbstractQueuedSynchrizeder(抽象队列同步器)。原理请看链接 https://blog.csdn.net/qingtian211/article/details/81316067?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0.pc_relevant_default&spm=1001.2101.3001.4242.1&utm_relevant_index=3

 

公平锁就是按照等待线程队列的顺序去唤醒第一个线程,非公平锁就是不按照顺序去唤醒线程,谁抢到锁就是谁的。

 

4  面向对象设计 

 

4.1 面向对象的特点

封装性: 属性和操作封装在一个个对象里,有利于对现实世界的模拟和抽象

继承性:子类可以集成父类的属性和方法,代码可以重用。

多态性:子类对象指向父类引用,增加程序的灵活性。一只猫可以当作猫来操作,也可以作为一只动物来操作。

 

4.2  spring里用到了哪些设计模式

七大原则见链接 https://www.jianshu.com/p/d7ded306787c?tdsourcetag=s_pctim_aiomsg

23种基本设计模式见链接

https://www.cnblogs.com/geek6/p/3951677.html

挑常见的单例模式,工厂模式和观察者模式考察即可

spring用到的有单例模式,工厂模式,观察者模式等

 

 

 

5 怎么实现自定义注解,注解解析器如何实现

见链接 https://www.cnblogs.com/dalaoyang/p/8657030.html

步骤,先定义自定义注解,注解的目标类型,注解的使用范围,注解的参数和方法等,然后实现注解解析器。实现注解解析器通过反射机制拿到注解的参数和方法并做相应处理。

 

 框架

1 spring的两大特点 什么是IOC,什么是AOP,spring是怎么实现的,aop的两种实现方式

 

spring的两大特点是IOC(控制反转也叫依赖注入)和AOP(面向切面编程)

IOC指的是Bean对象由IOC容器通过读取配置产生,而不是直接new一个新对象 由set注入构造器注入,属性注入等。spring通过bean的初始化过程来实现IOC,本质上是解析xml配置文档或者注解解析通过反射机制来实现。

AOP指的是面向切面编程,通过统一控制切面,在切点处注入通用处理逻辑。spring通过cglib或者jdk自带的proxy接口来实现AOP。

 

 

 

2 spring的scope有哪几种 分别应用于哪些场景

 

singleton(单例)和prototype(多例)以及web场景下的request,session和application

 

3 spring的bean的生命周期以及bean的初始化过程

 

见链接 https://baijiahao.baidu.com/s?id=1724716900810750570

 

4 spring mvc的实现原理,请求处理流程

 

见链接 https://www.cnblogs.com/leskang/p/6101368.html

 

5 spring boot的特点和实现原理

见链接 http://www.360doc.com/content/20/0529/10/57127015_915286345.shtml

 

 

6 什么是微服务,微服务有什么样的优缺点,spring cloud常用的组件及其特点,网关的原理,熔断降级限流的原理,负载均衡的原理

 

见链接 https://blog.csdn.net/cjtxzg/article/details/80535685

 

 

7 微服务治理的工具有哪些,怎么实现日志监控,链路监控和系统监控

日志监控ELK,链路监控zipkin 系统监控 zabbix或者grafana加prometheus

 

8 微服务场景下如何实现蓝绿发布和灰度发布

 

K8s的滚动发布,或者采用特殊的中间件在同一个环境部署多个版本微服务

 

7 什么是CAP理论 什么样的场景用到CAP,raft和paxos算法原理

 

在分布式环境下一致性,高可用和分布式容错不能全部满足,最多只能满足两个。分布式的场景下会遇到CAP的取舍问题,raft和paxos算法见链接 https://blog.csdn.net/qinwenjng120/article/details/108885808

 

 

8 mybatis和hibernate的优缺点比较

1)hibernate是全自动,而mybatis是半自动

 

hibernate完全可以通过对象关系模型实现对数据库的操作,拥有完整的JavaBean对象与数据库的映射结构来自动生成sql。而mybatis仅有基本的字段映射,对象数据以及对象实际关系仍然需要通过手写sql来实现和管理。

 

2)hibernate数据库移植性远大于mybatis

 

hibernate通过它强大的映射结构和hql语言,大大降低了对象与数据库(Oracle、MySQL等)的耦合性,而mybatis由于需要手写sql,因此与数据库的耦合性直接取决于程序员写sql的方法,如果sql不具通用性而用了很多某数据库特性的sql语句的话,移植性也会随之降低很多,成本很高。

 

3)hibernate拥有完整的日志系统,mybatis则欠缺一些

 

hibernate日志系统非常健全,涉及广泛,包括:sql记录、关系异常、优化警告、缓存提示、脏数据警告等;而mybatis则除了基本记录功能外,功能薄弱很多。

 

4)mybatis相比hibernate需要关心很多细节

 

hibernate配置要比mybatis复杂多,学习成本也比mybatis高。但也正因为mybatis使用简单,才导致它要比hibernate关心很多技术细节。mybatis由于不用考虑很多细节,开发模式上与传统jdbc区别很小,因此很容易上手并开发项目,但忽略细节会导致项目前期bug较多,因而开发出相对稳定的软件很慢,而开发出软件却很快。hibernate则正好与之相反。但是如果使用hibernate很熟练的话,实际上开发效率丝毫不差于甚至超越mybatis。

 

5)sql直接优化上,mybatis要比hibernate方便很多

 

由于mybatis的sql都是写在xml里,因此优化sql比hibernate方便很多。而hibernate的sql很多都是自动生成的,无法直接维护sql;虽有hql,但功能还是不及sql强大,见到报表等变态需求时,hql也歇菜,也就是说hql是有局限的;hibernate虽然也支持原生sql,但开发模式上却与orm不同,需要转换思维,因此使用上不是非常方便。总之写sql的灵活度上hibernate不及mybatis。

 

6)缓存机制上,hibernate要比mybatis更好一些

 

MyBatis的二级缓存配置都是在每个具体的表-对象映射中进行详细配置,这样针对不同的表可以自定义不同的缓存机制。并且Mybatis可以在命名空间中共享相同的缓存配置和实例,通过Cache-ref来实现。

 

Hibernate对查询对象有着良好的管理机制,用户无需关心SQL。所以在使用二级缓存时如果出现脏数据,系统会报出错误并提示。

9 spring的事务传播机制

 

 

10 springBoot如何实现自定义starter

 见链接 https://www.cnblogs.com/cjsblog/p/10926408.html

 

 

11 如何实现bean增强

见链接 https://blog.csdn.net/qq_31854907/article/details/109283707

 

12 什么是service mesh,istio有哪些组件,分别是做什么用的

见链接 https://blog.csdn.net/weixin_40274679/article/details/106232119

 

 数据库

1 事务的隔离级别 什么是脏读 不可重复读和幻读 mysql的默认隔离级别

事务的隔离级别有读未提交 读已提交 可重复读和串行化

脏读 就是事务1去修改了一个值 事务2读到了这个值 结果事务1取消了修改,事务2读到一个无效的值。

不可重复读 是指在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据。这是由于查询时系统中其他事务修改的提交而引起的。

幻读指的是事务中两次查询 后一次查询看到了前一次查询中没有看到的数据

mysql的默认隔离级别是可重复读

 

 

2 mysql索引丢失的场景

 

NOT、!=、<>、!<、!>、NOT IN、NOT LIKE, like有% ,not exist,is null,is not null 索引字段用内置函数都会导致索引丢失

 

3 mysql索引机制,联合索引的最左匹配特点

innoDB用的是聚簇索引 索引和数据是在一起的,myisam用的是非聚簇索引 索引不放数据

innoDB索引的数据结构是B+ 非叶子节点不存数据 只有叶子节点才放数据

ABC联合索引 A,AB,ABC能命中索引,BC不会命中索引

 

4 mysql索引的数据结构 为什么要用B+树而不用B树

 

数据结构是B+ 非叶子节点不存数据 只有叶子节点才放数据 

B+树是因为B+树的非叶子节点没有数据,内存中的一页可以放更多个树节点,减少IO,加快索引速度。

5 mysql的主从同步原理,主从同步延迟太大的解决办法

从数据库通过读binLog来同步数据。主从同步延迟太大可以通过消息中间件同步数据来取代,分库分表加缓存来减轻压力。

 

6 mysql的存储引擎有哪些,有什么区别,innoDB的存储结构

innoDB和myisam

innoDB支持事务,支持行级锁,聚簇索引

myisam不支持事务,不支持行级锁,非聚簇索引

innoDB存储结构见链接 https://blog.csdn.net/bohu83/article/details/81086474

 

 

7 mysql有哪些日志文件,这些日志是做什么用的

Redolog 执行事务日志

Undolog 事务回滚日志

Binlog 数据更改日志

8 mysql的XA 分布式事务是怎么实现的

见链接 https://www.jianshu.com/p/a7d1c4f2542c

9 用mysql实现分布式锁

把锁数据放在数据库里,从数据库里拿到锁,然后删除锁即可

10 mysql执行sql的过程,以及sql优化的底层原理

见链接 https://blog.csdn.net/weter_drop/article/details/93386581

11 如何实现分库分表,mycat分库分表的原理

通过hash对key取余来分库分表,key采用雪花算法等方式产生全局id。

mycat分库分表见链接 https://blog.csdn.net/xl_1803/article/details/105750354

 

12 mysql的mvcc是怎么实现的

见链接 

https://www.cnblogs.com/shujiying/p/11347632.html

 

 jvm


1  jvm有哪些部分组成,栈上放的是哪些内容,堆的划分

jvm由堆,栈,程序计数器,元数据区和本地方法区构成

栈上放的是局部变量,方法的入口和出口,指向对象的引用。

堆通常划分为 年轻代和老年代  通常比例为12

年轻代划分为eden区s0区和s1 通常比例为811

 

2  GC有哪些,分别有哪些优缺点,GC的算法有哪些,分别用于哪些场景

serial  单线程  stop   复制算法  

 

parnew  多线程  stop 复制算法    吞吐量 停顿时间  

 

Parallel Scavenge  多线程  stop 复制算法   jvm参数  

 

Serial Old  单线程 标记整理算法  

 

Parallel Old    多线程  标记整理  

  

cms 最短回收停顿 并发标记清理    初始 并发 重新标记 标记清除     并发 低停顿       cpu敏感  无法处理浮动垃圾    产生大量空间碎片导致大对象无法分配而full gc  

 

g1  并行与并发  利用多核优势 缩短停顿时间  业务线程继续执行   分代收集  空间整合 没有碎片  标记整理   可预测停顿  记忆集合    初始 并发 最终标记  Region   把回收对象集中起来 统一管理  

还有最新的zgc

 

3  什么是可达性分析,为什么不用根搜索算法

可达性分析算法的主要思路是先找出一批根节点对象集合作为GC Roots(可称为根节点枚举),然后从这批根节点出发,查找其引用关系(类似于深度优先搜索),如果对象不在引用链上则标记为可回收。根节点通常在: 

虚拟机栈中引用的对象(参数,局部变量等)

方法区中类静态变量

方法区中常量引用的对象

本地方法栈中引用的对象

被同步锁(synchronized)持有的对象

JMXBean等

根搜索算法会有循环依赖的问题。

 

4  java类加载机制  为什么要用双亲委派 怎么打破双亲委派

 

加载过程为加载,验证,准备,解析,初始化,

java的类加载机制为双亲委派机制,加载类要到父类去加载,父类如果还有父类就继续找父类直到找到原始类加载,如果父类加载不了,再让子类加载。

双亲委派可以防止类的重复加载,

线程上下文类加载器(contextClassLoader)来加载类可以破坏双亲委派模式。

5 一个对象什么时候会进入老年代,

当一个对象太大 年轻代装不下时,会进入老年代,当对象被gc扫过很多次,默认是超过15次时会进入老年代。

6  jvm优化会用到哪些工具,怎么使用它们来分析问题

Jconsole看各种运行指标,jmap看内存快照,jstat 看线程,jprofile看综合数据。

 

7 jvm的调参通常会调哪些参数

参数名称

含义

默认值


-Xms

初始堆大小

物理内存的1/64(<1GB)

默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制.

-Xmx

最大堆大小

物理内存的1/4(<1GB)

默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制

-Xmn

年轻代大小(1.4or lator)


注意:此处的大小是(eden+ 2 survivor space).与jmap -heap中显示的New gen是不同的。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小.增大年轻代后,将会减小年老代大小.此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8

-XX:NewSize

设置年轻代大小(for 1.3/1.4)



-XX:MaxNewSize

年轻代最大值(for 1.3/1.4)



-XX:PermSize

设置持久代(perm gen)初始值

物理内存的1/64


-XX:MaxPermSize

设置持久代最大值

物理内存的1/4


-Xss

每个线程的堆栈大小


JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K.更具应用的线程所需内存大小进行 调整.在相同物理内存下,减小这个值能生成更多的线程.但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右一般小的应用, 如果栈不是很深, 应该是128k够用的 大的应用建议使用256k。这个选项对性能影响比较大,需要严格的测试。(校长)和threadstacksize选项解释很类似,官方文档似乎没有解释,在论坛中有这样一句话:"”-Xss is translated in a VM flag named ThreadStackSize”一般设置这个值就可以了。

-XX:ThreadStackSize

Thread Stack Size


(0 means use default stack size) [Sparc: 512; Solaris x86: 320 (was 256 prior in 5.0 and earlier); Sparc 64 bit: 1024; Linux amd64: 1024 (was 0 in 5.0 and earlier); all others 0.]

-XX:NewRatio

年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)


-XX:NewRatio=4表示年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5Xms=Xmx并且设置了Xmn的情况下,该参数不需要进行设置。

-XX:SurvivorRatio

Eden区与Survivor区的大小比值


设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10

-XX:LargePageSizeInBytes

内存页的大小不可设置过大, 会影响Perm的大小


=128m

-XX:+UseFastAccessorMethods

原始类型的快速优化



-XX:+DisableExplicitGC

关闭System.gc()


这个参数需要严格的测试

-XX:MaxTenuringThreshold

垃圾最大年龄


如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代. 对于年老代比较多的应用,可以提高效率.如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活 时间,增加在年轻代即被回收的概率该参数只有在串行GC时才有效.

-XX:+AggressiveOpts

加快编译



-XX:+UseBiasedLocking

锁机制的性能改善



-Xnoclassgc

禁用垃圾回收



-XX:SoftRefLRUPolicyMSPerMB

每兆堆空闲空间中SoftReference的存活时间

1s

softly reachable objects will remain alive for some amount of time after the last time they were referenced. The default value is one second of lifetime per free megabyte in the heap

-XX:PretenureSizeThreshold

对象超过多大是直接在旧生代分配

0

单位字节 新生代采用Parallel Scavenge GC时无效另一种直接在旧生代分配的情况是大的数组对象,且数组中无外部引用对象.

-XX:TLABWasteTargetPercent

TLAB占eden区的百分比

1%


-XX:+CollectGen0First

FullGC时是否先YGC

false


 

 中间件

1  redis有哪些数据类型,有什么特点,分别是做什么用的

String存字符串,Hash存对象,List存列表,Set存无重复集合,Zset存有序集合等,

2  redis如何实现和数据库的数据保持一致

 

当数据有变化时,直接让redis数据失效即可

 

3  redis cluster的实现原理 哨兵模式原理

 

多主多从 从节点从主节点更新数据,主节点通过gossip协议的ping pang来维持节点心跳。如果一个主节点故障了,其他主节点从这个主节点的从节点中选择一个节点来做主节点,

哨兵模式是有一个节点负责管理整个集群节点的增删改和任务的分配。是整个集群的入口。

 

4  redis的持久化方式有哪些 各有什么特点

 

AOF和RDB

AOF存的是redis的增删改的操作命令,AOF有很好的实时性,恢复较慢,不影响性能

RDB存的是数据,实时性不够好,影响性能。恢复速度快

 

 

5  redis实现分布式锁

通过setNX来设置锁

6  rabbitMQ的特点,如何实现消息不丢失,如何解决重复消费的问题,延时队列怎么实现,队列淤塞怎么解决,如何实现事务型消息

 

完整的实现了AMQP协议,消息机制很完善,消息消费成功会有一个成功消息,如果消息没有消费成功,则转到消息队列末端继续消费,解决重复消费将消费接口设置成幂等即可。延时队列采用死信队列即可。队列淤塞则加大客户端的微服务实例数量或者增加新客户端加快消费速度。实现事务型消息要要开启信道的事务机制分别如下:

1  channel.txSelect()  声明启动事务模式

2.channel.txCommit() 提交事务

3.channel.txRollback()回滚事务

 

 

7  rabbitMQ有哪几种消息机制,分别是什么 怎么配置

 

fanout类型的Exchange是把收到的消息投到所有跟它绑定的Queue中;

 

direct类型的Exchange是精确匹配投递,把消息投到和它的RoutingKey相同的BindingKey对应的队列上;

 

topic类型的Exchange跟direct类型有点类似,但BindingKey可以用通配符(*匹配一个词,#表示匹配多个词),它把消息投递到所有跟消息RoutingKey匹配的Bindingkey对应的队列上,特别的BingingKey为#时,匹配所有的消息的RoutingKey,此时Exchange收到的所有消息都会投递到该队列中;

 

header类型的Exchange是根据消息的header属性匹配,用的较少。

 

8  kafka的原理,kafka怎么实现消息的有序性,kafka如何保证消息不丢失,如何解决重复消费的问题,如何实现事务型消息

kafka是个分布式的消息中间件,

见链接https://blog.csdn.net/suifeng3051/article/details/48053965

保证消息的有序性可以kafka topic 只设置一个partition分区  或者producer将消息发送到指定partition分区

解决重复消费问题将消费端设计成幂等的

kafka实现事务型消息见链接https://blog.csdn.net/qq_35930102/article/details/108185765

 

9  es集群全文检索的过程,什么是倒排索引,为什么要用倒排索引,如何优化es的性能

全文检索原理见链接:https://blog.csdn.net/zhoushimiao1990/article/details/103226496

倒排索引是指把索引放在前面 对应的文件放后边 这样可以提高检索速度

es性能优化见链接 https://blog.csdn.net/u013982921/article/details/99733480

10 什么是docker,有什么优缺点 什么是K8s k8s的原理和特点   spring cloud如何部署在k8s上,有什么注意点,

docker原理见链接 https://zhuanlan.zhihu.com/p/22382728

K8s原理见链接https://www.cnblogs.com/gunxiaoshi/p/11052927.html

Spring cloud部署在k8s需要替换服务注册与发现组件将服务注册与发现组件替换为k8s自带的etcd

 

 设计问题

1 领域驱动设计如何划分业务领域

将业务按照功能划分为一个个子域,分为支撑域(为系统核心域提供支撑的域),核心域(包含核心业务流程),通用域(可以用通用组件实现的甚至可外包出去的域)

 

2 领域驱动设计实体和值对象如何区分

实体是看得到、摸得着的实实在在的业务对象,实体具有业务属性、业务行为和业务逻辑。而值对象只是若干个属性的集合,只有数据初始化操作和有限的不涉及修改数据的行为,基本不包含业务逻辑。值对象的属性集虽然在物理上独立出来了,

 

 

3 领域驱动设计中如何确定聚合,聚合根如何确定

见链接 https://blog.csdn.net/diechou1315/article/details/102213569

 

4 单体应用拆分成微服务要解决哪些问题

 

业务功能拆解,数据库拆分,分布式事务问题,数据一致性问题,

 

5 跨洲际部署架构如何解决网络延迟大的问题

前端部署CDN,数据端要有本地缓存,数据同步采用非实时同步策略

6 订单拆分的业务设计

主单和子单采用父子关联设计

7 负载均衡有哪些实现方案,具体的实现算法有哪些

随机,轮询,权重算法

8 高并发场景下如何实现系统的高可用,高吞吐量和弹性伸缩

多线程并发处理,页面静态化,微服务化,服务端多级缓存,CDN,容器化,负载均衡,服务的熔断降级和限流。

 

9 系统的安全性设计有哪些方案,oauth2的设计实现

加密算法(对称DES和非对称RSA算法)

防止SQL注入

防止XSS攻击

防止DDOS攻击

采用token和accessCode机制访问

OAuth2的设计见链接 https://www.jianshu.com/p/84a4b4a1e833

 

10 实现模型字段的动态可配的实现方案

json定义和解析或者是宽表方案

 

11 分布式事务有哪些实现方案,分别适用于哪些场景

采用消息组件实现的事务补偿机制 一般重试三次 适用于需要高性能但实时性要求不高的场景

TCC方式即try confirm和cancel机制 在业务端实现二阶段提交适用于对高性能和实时性都有要求的场景

二阶段提交 采用数据库的XA机制 适用于对实时性要求非常高的场景

可以使用阿里的seata框架实现

 

 

12 如何实现各个微服务之间的数据一致性

 

通过调用RPC接口调用的方式实现数据同步,也可以通过MQ的消息方式实现数据同步。