|
17线程池的处理流程 1.先判断线程池中的核心线程们是否空闲,如果空闲,就把这个新的任务指派给某一个空闲线程去执行。如果没有空闲,并且当前线程池中的核心线程数还小于 corePoolSize,那就再创建一个核心线程。 2.如果线程池的线程数已经达到核心线程数,并且这些线程都繁忙,就把这个新来的任务放到等待队列中去。如果等待队列又满了,那么查看一下当前线程数是否到达maximumPoolSize,如果还未到达,就继续创建线程。 3.如果已经到达了,就交给RejectedExecutionHandler(拒绝策略)来决定怎么处理这个任务。 18.线程池有哪些参数?分别有什么用?如果任务数超过的核心线程数,会发生什么? 1.线程池有哪些参数?分别有什么用? corePollSize:核心线程数。在创建了线程池后,线程中没有任何线程,等到有任务到来时才创建线程去执行任务。默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中。 maximumPoolSize:最大线程数。表明线程中最多能够创建的线程数量。 keepAliveTime:空闲的线程保留的时间。 TimeUnit:空闲线程的保留时间单位。 BlockingQueue<Runnable>:阻塞队列,存储等待执行的任务。参数有ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue可选。 ThreadFactory:线程工厂,用来创建线程 RejectedExecutionHandler:队列已满,而且任务量大于最大线程的异常处理策略。有以下取值。 2.如果任务数超过的核心线程数,会发生什么? 线程池中的核心线程数,当提交一个任务时,线程池创建一个新线程执行任务,直到当前线程数等于corePoolSize;如果当前线程数为corePoolSize,继续提交的任务被保存到阻塞队列中,等待被执行;如果阻塞队列满了,那就创建新的线程执行当前任务;直到线程池中的线程数达到maxPoolSize,这时再有任务来,只能执行reject()处理该任务; 19. 数据库索引?B+树?为什么要建索引?什么样的字段需要建索引,建索引的时候一般考虑什么? 1. 索引(Index)是帮助MySQL高效获取数据的数据结构。提取句子主干,就可以得到索引的本质:索引是数据结构。 2. MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等。 3. 索引用于快速找出在某个列中有一特定值的行,不使用索引,MySQL必须从第一条记录开始读完整个表,直到找出相关的行,表越大,查询数据所花费的时间就越多,如果表中查询的列有一个索引,MySQL能够快速到达一个位置去搜索数据文件,而不必查看所有数据,那么将会节省很大一部分时间。 4. 1.主键自动建立唯一索引; 2.频繁作为查询条件的字段应该创建索引; 3.查询中与其他表有关联的字段,例如外键关系; 4.频繁更新的字段不适合创建索引,因为每次更新不单单是更新记录,还会更新索引,保存索引文件; 5.where条件里用不到的字段,不创建索引; 6.高并发的情况下一般选择复合索引; 7.查询中排序的字段创建索引将大大提高排序的速度(索引就是排序加快速查找); 8.查询中统计或者分组的字段; 9.表记录太少,不需要创建索引; 10.经常增删改的表; 11.数据重复且分布平均的字段,因此为经常查询的和经常排序的字段建立索引。注意某些数据包含大量重复数据,因此他建立索引就没有太大的效果,例如性别字段,只有男女,不适合建立索引。 20. Springcould和dubbo的区别 Dubbo底层是使用Netty这样的NIO框架,是基于TCP协议传输的,配合以Hession序列化完成RPC通信。而SpringCloud是基于Http协议+rest接口调用远程过程的通信,相对来说,Http请求会有更大的报文,占的带宽也会更多。但是REST相比RPC更为灵活,服务提供方和调用方的依赖只依靠一纸契约,不存在代码级别的强依赖,这在强调快速演化的微服务环境下,显得更为合适,至于注重通信速度还是方便灵活性,具体情况具体考虑。 [size=16.0000pt]21. SOA架构和微服务架构的区别 1.SOA(Service Oriented Architecture)“面向服务的架构”:他是一种设计方法,其中包含多个服务, 服务之间通过相互依赖最终提供一系列的功能。一个服务 通常以独立的形式存在与操作系统进程中。各个服务之间 通过网络调用。 1. 微服务架构:其实和 SOA 架构类似,微服务是在 SOA 上做的升华,微服务架构强调的一个重点是“业务需要彻底的组件化和服务化”,原有的单个业务系统会拆分为多个可以独立开发、设计、运行的小应用。这些小应用之间通过服务完成交互和集成。 22. ActiveMQ如何做到消息幂等 上半场的幂等性设计 file:///C:\Users\guibin\AppData\Local\Temp\ksohtml17360\wps1.jpg 1,发送端MQ-client将消息发给服务端MQ-server 2,服务端MQ-server将消息落地 3,服务端MQ-server回ACK给发送端MQ-client 如果3丢失,发送端MQ-client超时后会重发消息,可能导致服务端MQ-server收到重复消息。 此时重发是MQ-client发起的,消息的处理是MQ-server,为了避免步骤2落地重复的消息,对每条消息,MQ系统内部必须生成一个inner-msg-id,作为去重和幂等的依据,这个内部消息ID的特性是: (1)全局唯一 (2)MQ生成,具备业务无关性,对消息发送方和消息接收方屏蔽 有了这个inner-msg-id,就能保证上半场重发,也只有1条消息落到MQ-server的DB中,实现上半场幂等。 下半场的幂等性设计 三、下半场的幂等性设计 file:///C:\Users\guibin\AppData\Local\Temp\ksohtml17360\wps2.jpg MQ消息发送下半场,即上图中的4-6 4,服务端MQ-server将消息发给接收端MQ-client 5,接收端MQ-client回ACK给服务端 6,服务端MQ-server将落地消息删除 需要强调的是,接收端MQ-client回ACK给服务端MQ-server,是消息消费业务方的主动调用行为,不能由MQ-client自动发起,因为MQ系统不知道消费方什么时候真正消费成功。 如果5丢失,服务端MQ-server超时后会重发消息,可能导致MQ-client收到重复的消息。 此时重发是MQ-server发起的,消息的处理是消息消费业务方,消息重发势必导致业务方重复消费,为了保证业务幂等性,业务消息体中,必须有一个biz-id,作为去重和幂等的依据,这个业务ID的特性是: (1)对于同一个业务场景,全局唯一 (2)由业务消息发送方生成,业务相关,对MQ透明 (3)由业务消息消费方负责判重,以保证幂等 最常见的业务ID有:支付ID,订单ID,帖子ID等。 23. Spring Bean的生命周期 我们知道一个对象的生命周期:创建(实例化-初始化)-使用-销毁,而在Spring中,Bean对象周期当然遵从这一过程,但是Spring提供了许多对外接口,允许开发者对三个过程(实例化、初始化、销毁)的前后做一些操作。 这里就实例化、初始化区别做一个说明,在Spring Bean中,实例化是为bean对象开辟空间(具体可以理解为构造函数的调用),初始化则是对属性的初始化,说的具体点,这里的属性初始化应该是属性的注入(构造函数也可以有属性的初始化语句,但不属于这一部分),属性注入是通过setter方法注入属性(不管是注解方式还是bean配置property属性方式,其实质都是通过属性的setter方法实现的)。 file:///C:\Users\guibin\AppData\Local\Temp\ksohtml17360\wps3.jpg
|