中级Java开发工程师面经(2)
技术要点回答提炼
深入理解多线程知识
线程池核心参数:核心线程数、最大线程数、阻塞队列、线程工厂、线程回收时间、线程回收时间单位、拒绝策略
阻塞队列:同步队列,
通过继承Thread类、实现Runable\Callable接口创建任务
countDownLauth 线程计数:核心实现逻辑aqs中的state计数 是volitale关键字修饰的,并且是通过cas改值。
CyclicBarrier循环栅栏:内部有个变量count计数,可循环使用。利用condition作为条件阻塞线程,达到条件后唤醒等待线程继续下一次任务。
CountDownLatch 是一次性的,CyclicBarrier 是可循环利用的
深入研究volatile、synchronized硬件级别原理
volatile保证了有序性和可见性。从jmm的架构层面 分了几层缓存、因为cpu的执行速度和缓存的执行速度是差几个数量级的,所有我们本地线程执行的时候 会有一个本地缓存和主内存交互。为了保证数据的修改能在其他线程可见,voliatile利用了mesi协议以及内存屏障,读取数据强制从主存读、写数据强制刷新主存来保证数据可见。有序性也是通过内存屏障来解决的,load屏障 write屏障。
synchroized保证了线程的有序性可见性和原子性。加锁是通过jvm的moniter监视器,加锁通过moniter enter 和moniter exit指令来加锁 底层调用的是mutex lock。加锁在方法上是通过ACC_SYNCHRONIZED标识来实现的。锁对象(不同对象不影响)锁静待方法(类锁,相同类是互斥的)。
熟练掌握Redis分布式缓存的高可用、高并发、高性能设计方案。
Redis 多副本(主从)
Redis Sentinel(哨兵):Redis Sentinel 集群和 Redis 数据集群、解决 Redis 主从模式下的高可用切换问题
Redis Cluster(分布式集群方案)、无中心架构;
数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布;
可扩展性:可线性扩展到 1000 多个节点,节点可动态添加或删除;
数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布;
可扩展性:可线性扩展到 1000 多个节点,节点可动态添加或删除;
深入理解分布式事务常用方案
两阶段提交:一阶段:决策、二阶段:提交 存在单点故障和数据不一致问题、多用于单服务多数据库的场景
三阶段提交:一阶段:询问、二阶段:预提交、三阶段:提交。解决了二阶段的单点故障问题引入了超时机制、超时未收到协调者提交事务(未收到取消通知),导致数据不一致问题。
tcc方案:try阶段:资源预留、confirm阶段:提交业务事务、cancel阶段:回滚阶段。解决了数据不一致的问题、有了补偿机制(定时任务轮训未执行事务)保证了数据一致性。但对业务侵入比较大,多用于订单、资金相关的强一致性业务。
事务消息:rocektMQ的事务消息、单独实现可靠消息服务、多用于对实时性要求不高的业务,能够保证数据最终一致性。
最大努力通知消息:多用于消息提醒等业务
seata事务框架:
深入理解消息中间件rocketMQ的使用场景,熟悉消息有序性、可靠性、幂等性、消息事务等解决方案
有序性:rocektMQ的熟悉消息。生产者根据id保证同一id消息分发到相同的messageQueue上、消费者通过内存队列保证消息顺序,并且用同一线程消费消息。
可靠性:生产者端:同步发送消息、异步发送消息回调(重试发送)、 单向发送无回调不阻塞(消息不可靠)、MQ端:同步刷盘(默认异步刷盘)、消费端:先消费成功后提交
幂等性:业务数据库记录幂等、数据库主键、全局id缓存redis、
消息事务:rocketMQ的消息事务:预提交消息到MQ上、执行本地事务、提交确认消息。(提供业务事务查询的接口查询本地事务是否成功)。
Redis、Zookeeper分布式锁的实现方案
redis分布式锁,redisson框架实现、可重入锁,加锁时会根据key进行crc16算法对16384个槽进行计算,划分到某一个槽,然后加锁成功后,底层是通过lua脚本实现的,加锁成功后会有一个定时任务10s执行一次,看门狗,对锁过期时间进行重置。会生成线程id,加锁次数1,其他线程加锁时会一直阻塞,重试。
zookeeper分布式锁,通过临时节点来当做分布式锁,其他线程可以监听当前节点,可以实现公平锁、非公平锁、相对于redis分布式锁获取锁不需要重复尝试、基于监听器实现。
关于AQS你的理解
队列同步器:内部有一个state值 用来加锁,节点存储了节点的状态 和线程的信息。
关于MQ的选型、为什么选了RocketMQ
ActiveMQ、RabbitMQ的吞吐量是万级
RocketMQ和Kafka是十万级的,Kafka的单机吞吐量可以达到百万级。RocketMQ的topic可以达到几百几千的级别,且性能小幅小降、Kafka的topic 从几十到几百个时候,吞吐量会大幅度下降、这就是RocketMQ适合业务处理的原因。RocketMQ的功能较为完善、且是阿里开源java开发,后面出现问题可以快速定位修复。
Rocket的消息存储是先存储在MessageQueue上 存储了消息在commitLog的索引。kafka的消息存储则是每个partition都有一个存储文件,partition多了之后,随机io也多了 性能会下降。
一个请求从浏览器到后台经历了哪些过程。
dns解析出ip地址,通过htttp协议建立连接,包装htttp包、ip包、mac地址包。再通过tcp 三次握手、四次挥手进行连接。
为啥需要三次握手、二次握手不行吗:如果是两次握手、
到后端springmvc 通过dispatcherServert转发到相对应的handlermapping 找出对应的hadler处理之后在渲染view组件返回给前端。
地址:https://www.processon.com/view/link/6264f7365653bb498e2a7f66

浙公网安备 33010602011771号