前言

这一篇主要讲解和同事探讨每一个技术点深入提问,深入如何回答的一个篇章

一、基础问题

  • 1.1、http请求是否请求一次就会创建一个线程?
    每个http请求分配到一个线程去处理。处理的线程可以是新建线程,也可以是从线程池中获取。一个线程可以处理多个请求,tomcat有同步和异步。

  • 1.2、多次http请求是否会异步执行,还是同步?
    看tomcat容器设置的是BIO(同)或者NIO(异)

  • 1.3、http请求和多线程的区别在哪里?

    • http请求就是tomcat线程池提供的线程处理每一个请求(tomcat线程池)
    • 多线程是程序里面线程池提供的处理具体逻辑(jdk线程池)
    • tomcat中的线程池excutor主要负责请求的处理,而代码中使用的异步线程池是自己自定义的
  • 1.4、一个http请求,多线程是如何分配?
    每一个请求,容器都会分配线程去处理逻辑

  • 1.5、同步异步区别?

  • 1.6、lamda表达式底层怎么实现的?

  • 1.7、你们使用网关什么功能

  • 1.8、降级原理是怎么实现的

  • 1.9、你们使用nginx什么功能

  • 1.10、mysql啥时候触发行级锁、表级锁,死锁如何解决

  • 1.11、string原理

二、tomcat

2.1、了解tomcat线程池配置

  • 1:最大连接数:maxThreads
  • 2、最大排队数 acceptCount

三、spring boot 源码

面试第二专题

四、调优

面试第八专题

五、数据幂

概念

幂等的的意思就是一个操作不会修改状态信息,并且每次操作的时候都返回同样的结果。即:做多次和做一次的效果是一样 的。一般用在新增和修改来做数据幂等性

使用场景

  • 网络波动
  • 订单购物经典场景
  • 用户重复点击
  • MQ重复发送(收到消息,网络中断,一直发送,没收到确认,就重复发送)
  • 应用重试或者远程调用重试机制

前端处理:

  • 1、前段幂等性点击置灰操作控制
  • 2、接口幂token机制

后端:

  • 1、数据库唯一索引
唯一约束来保证数据重复插入,避免脏数据产生。这种做法比较简单粗暴,直接抛出异常信息即可。
  • 2、数据库状态控制(状态单向不可逆)
购物下单,状态设计成单向不可逆方式
如:update table set status=下一种状态 where id =1 and status=已付款
  • 3、数据库悲观锁实现
更新数据时候,使用version来做乐观锁,乐观锁version字段在更新业务数据时值要自增
update table set q =q,version = version + 1 where id =1 and version =#{version }
  • 4、防重表(增加一个表)
将防重表当作锁的功能,使用唯一主键如:uuid去做防重表的唯一索引,每次请求,第一次请求由于没有记录插入成功,成功后进行后续业务处理,处理完后(无论成功或失败)删除去重表中的数据。
如果处理过程中有同uuid请求过来的话,因为表中唯一索引从而达到插入失败
  • 5、分布式锁
在进入方法时,先获取锁,假如获取到锁,就继续后面流程。假设没有获取到锁,就等待锁的释放直到获取锁,当执行完方法时,释放锁,当然,锁要设个超时时间,防止意外没有释放到锁,它可以用来解决分布式系统的幂等性;

常用的分布式锁实现方案是redis 和 zookeeper 等工具。

使用分布式锁类似于防重表,将防重并发放到了缓存中,较为高效,同一时间只能完成一次操作。
  • 6、缓存队列
请求快速的接收,放入缓冲队列中,后续使用异步任务处理队列的数据,过滤掉重复请求,我们可以用LinkedList来实现队列,一个HashSet来实现去重。
此方法优点是异步处理、高吞吐,不足是不能及时返回请求结果,需要后续轮询处理结果。
  • 7、全局唯一ID
将请求关键性数据或者请求的全部数据组合生成md5码,这样的话,重复请求都是一个相同ID;如果所有请求包括重复请求都要唯一ID,那么可以用UUID或者用雪花算法生成唯一ID。

六、分布式锁

zk实现分布式锁的流程
image.png

七、分布式事务

八、redis

面试第六专题

九、RabbitMq

如何保证MQ的消息可靠性
如何保证MQ的消息重复发送、重复消费问题
如何保证MQ的消息顺序性

十、mysql

  • 如何分库分表
  • 事务
    • 什么是事务
    • 事务特征
    • 事务隔离级别
    • 并发执行事务可能导致的问题
  • 数据库如何优化
  • 索引结构
  • 死锁如何解决

十一、线程

  • 线程的状态
  • 线程的生命周期
  • 线程池常用的几个参数
  • 线程如何保证串行化执行
  • 线程有哪些创建方式,为啥很多人喜欢使用Runnable

十二、spring框架

  • spring使用了哪些设计模式

十三、了解那些并发包