互联网 Java 工程师进阶知识完全扫盲
1. 1.1 消息队列
0.1 1.1.1 为什么使用消息队列?消息队列有什么优点和缺点?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么优点和缺点?
0.2 1.1.2 如何保证消息队列的高可用?
0.3 1.1.3 如何保证消息不被重复消费?(如何保证消息消费的幂等性)
0.4 1.1.4 如何保证消息的可靠性传输?(如何处理消息丢失的问题)
0.5 1.1.5 如何保证消息的顺序性?
0.6 1.1.6 如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时,说说怎么解决?
0.7 1.1.7 如果让你写一个消息队列,该如何进行架构设计啊?说一下你的思路。
2. 1.2 搜索引擎
1.1 1.2.1 es 的分布式架构原理能说一下么(es 是如何实现分布式的啊)?
1.2 1.2.2 es 写入数据的工作原理是什么啊?es 查询数据的工作原理是什么啊?底层的 lucene 介绍一下呗?倒排索引了解吗?
1.3 1.2.3 es 在数据量很大的情况下(数十亿级别)如何提高查询效率啊?
1.4 1.2.4 es 生产集群的部署架构是什么?每个索引的数据量大概有多少?每个索引大概有多少个分片?
1.5 1.3.1 在项目中缓存是如何使用的?缓存如果使用不当会造成什么后果?
1.6 1.3.2 Redis 和 Memcached 有什么区别?Redis 的线程模型是什么?为什么单线程的 Redis 比多线程的 Memcached 效率要高得多?
1.7 1.3.3 Redis 都有哪些数据类型?分别在哪些场景下使用比较合适?
1.8 1.3.4 Redis 的过期策略都有哪些?手写一下 LRU 代码实现?
1.9 1.3.5 如何保证 Redis 高并发、高可用?Redis 的主从复制原理能介绍一下么?Redis 的哨兵原理能介绍一下么?
1.10 1.3.6 Redis 的持久化有哪几种方式?不同的持久化机制都有什么优缺点?持久化机制具体底层是如何实现的?
1.11 1.3.7 Redis 集群模式的工作原理能说一下么?在集群模式下,Redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗?如何动态增加和删除一个节点?
1.12 1.3.8 了解什么是 redis 的雪崩、穿透和击穿?Redis 崩溃之后会怎么样?系统该如何应对这种情况?如何处理 Redis 的穿透?
1.13 1.3.9 如何保证缓存与数据库的双写一致性?
1.14 1.3.10 Redis 的并发竞争问题是什么?如何解决这个问题?了解 Redis 事务的 CAS 方案吗?
1.15 1.3.11 生产环境中的 Redis 是怎么部署的?
1.16 1.4.1 为什么要分库分表(设计高并发系统的时候,数据库层面该如何设计)?用过哪些分库分表中间件?不同的分库分表中间件都有什么优点和缺点?你们具体是如何对数据库如何进行垂直拆分或水平拆分的?
1.17 1.4.2 现在有一个未分库分表的系统,未来要分库分表,如何设计才可以让系统从未分库分表动态切换到分库分表上?
1.18 1.4.3 如何设计可以动态扩容缩容的分库分表方案?
1.19 1.4.4 分库分表之后,id 主键如何处理?
1.20 1.5.1 如何实现 MySQL 的读写分离?MySQL 主从复制原理是啥?如何解决 MySQL 主从同步的延时问题?
1.21 1.6.1 如何设计一个高并发系统?
3. 2.1 面试连环炮
2.1 2.2.1 为什么要进行系统拆分?如何进行系统拆分?拆分后不用 Dubbo 可以吗?
2.2 2.3.1 说一下 Dubbo 的工作原理?注册中心挂了可以继续通信吗?
2.3 2.3.2 Dubbo 支持哪些序列化协议?说一下 Hessian 的数据结构?PB 知道吗?为什么 PB 的效率是最高的?
2.4 2.3.3 Dubbo 负载均衡策略和集群容错策略都有哪些?动态代理策略呢?
2.5 2.3.4 Dubbo 的 spi 思想是什么?
2.6 2.3.5 如何基于 Dubbo 进行服务治理、服务降级、失败重试以及超时重试?
2.7 2.3.6 分布式服务接口的幂等性如何设计(比如不能重复扣款)?
2.8 2.3.7 分布式服务接口请求的顺序性如何保证?
2.9 2.3.8 如何自己设计一个类似 Dubbo 的 RPC 框架?
2.10 2.4.1 Zookeeper 都有哪些应用场景?
2.11 2.4.2 使用 Redis 如何设计分布式锁?使用 Zookeeper 来设计分布式锁可以吗?以上两种分布式锁的实现方式哪种效率比较高?
2.12 2.5.1 分布式事务了解吗?你们如何解决分布式事务问题的?TCC 如果出现网络连不通怎么办?XA 的一致性如何保证?
2.13 2.6.1 集群部署时的分布式 Session 如何实现?
2.14 3.1.1 Hystrix 介绍
2.15 3.1.2 电商网站详情页系统架构
2.16 3.1.3 Hystrix 线程池技术实现资源隔离
2.17 3.1.4 Hystrix 信号量机制实现资源隔离
2.18 3.1.5 Hystrix 隔离策略细粒度控制
2.19 3.1.6 深入 Hystrix 执行时内部原理
2.20 3.1.7 基于 request cache 请求缓存技术优化批量商品数据查询接口
2.21 3.1.8 基于本地缓存的 fallback 降级机制
2.22 3.1.9 深入 Hystrix 断路器执行原理
2.23 3.1.10 深入 Hystrix 线程池隔离与接口限流
2.24 3.1.11 基于 timeout 机制为服务接口调用超时提供安全保护
4. 4.1 关于微服务架构的描述

面试题

如何设计一个高并发系统?

面试官心理分析

说实话,如果面试官问你这个题目,那么你必须要使出全身吃奶劲了。为啥?因为你没看到现在很多公司招聘的 JD 里都是说啥,有高并发就经验者优先。

如果你确实有真才实学,在互联网公司里干过高并发系统,那你确实拿 offer 基本如探囊取物,没啥问题。面试官也绝对不会这样来问你,否则他就是蠢。

假设你在某知名电商公司干过高并发系统,用户上亿,一天流量几十亿,高峰期并发量上万,甚至是十万。那么人家一定会仔细盘问你的系统架构,你们系统啥架构?怎么部署的?部署了多少台机器?缓存咋用的?MQ 咋用的?数据库咋用的?就是深挖你到底是如何扛住高并发的。

因为真正干过高并发的人一定知道,脱离了业务的系统架构都是在纸上谈兵,真正在复杂业务场景而且还高并发的时候,那系统架构一定不是那么简单的,用个 redis,用 mq 就能搞定?当然不是,真实的系统架构搭配上业务之后,会比这种简单的所谓“高并发架构”要复杂很多倍。

如果有面试官问你个问题说,如何设计一个高并发系统?那么不好意思,一定是因为你实际上没干过高并发系统。面试官看你简历就没啥出彩的,感觉就不咋地,所以就会问问你,如何设计一个高并发系统?其实说白了本质就是看看你有没有自己研究过,有没有一定的知识积累。

最好的当然是招聘个真正干过高并发的哥儿们咯,但是这种哥儿们人数稀缺,不好招。所以可能次一点的就是招一个自己研究过的哥儿们,总比招一个啥也不会的哥儿们好吧!

所以这个时候你必须得做一把个人秀了,秀出你所有关于高并发的知识!

面试题剖析

其实所谓的高并发,如果你要理解这个问题呢,其实就得从高并发的根源出发,为啥会有高并发?为啥高并发就很牛逼?

我说的浅显一点,很简单,就是因为刚开始系统都是连接数据库的,但是要知道数据库支撑到每秒并发两三千的时候,基本就快完了。所以才有说,很多公司,刚开始干的时候,技术比较 low,结果业务发展太快,有的时候系统扛不住压力就挂了。

当然会挂了,凭什么不挂?你数据库如果瞬间承载每秒 5000/8000,甚至上万的并发,一定会宕机,因为比如 mysql 就压根儿扛不住这么高的并发量。

所以为啥高并发牛逼?就是因为现在用互联网的人越来越多,很多 app、网站、系统承载的都是高并发请求,可能高峰期每秒并发量几千,很正常的。如果是什么双十一之类的,每秒并发几万几十万都有可能。

那么如此之高的并发量,加上原本就如此之复杂的业务,咋玩儿?真正厉害的,一定是在复杂业务系统里玩儿过高并发架构的人,但是你没有,那么我给你说一下你该怎么回答这个问题:

可以分为以下 6 点:

  • 系统拆分
  • 缓存
  • MQ
  • 分库分表
  • 读写分离
  • ElasticSearch

high-concurrency-system-design

系统拆分

将一个系统拆分为多个子系统,用 dubbo 来搞。然后每个系统连一个数据库,这样本来就一个库,现在多个数据库,不也可以扛高并发么。

缓存

缓存,必须得用缓存。大部分的高并发场景,都是读多写少,那你完全可以在数据库和缓存里都写一份,然后读的时候大量走缓存不就得了。毕竟人家 redis 轻轻松松单机几万的并发。所以你可以考虑考虑你的项目里,那些承载主要请求的读场景,怎么用缓存来抗高并发

MQ

MQ,必须得用 MQ。可能你还是会出现高并发写的场景,比如说一个业务操作里要频繁搞数据库几十次,增删改增删改,疯了。那高并发绝对搞挂你的系统,你要是用 redis 来承载写那肯定不行,人家是缓存,数据随时就被 LRU 了,数据格式还无比简单,没有事务支持。所以该用 mysql 还得用 mysql 啊。那你咋办?用 MQ 吧,大量的写请求灌入 MQ 里,排队慢慢玩儿,后边系统消费后慢慢写,控制在 mysql 承载范围之内。所以你得考虑考虑你的项目里,那些承载复杂写业务逻辑的场景里,如何用 MQ 来异步写,提升并发性。MQ 单机抗几万并发也是 ok 的,这个之前还特意说过。

分库分表

分库分表,可能到了最后数据库层面还是免不了抗高并发的要求,好吧,那么就将一个数据库拆分为多个库,多个库来扛更高的并发;然后将一个表拆分为多个表,每个表的数据量保持少一点,提高 sql 跑的性能。

读写分离

读写分离,这个就是说大部分时候数据库可能也是读多写少,没必要所有请求都集中在一个库上吧,可以搞个主从架构,主库写入,从库读取,搞一个读写分离。读流量太多的时候,还可以加更多的从库

ElasticSearch

Elasticsearch,简称 es。es 是分布式的,可以随便扩容,分布式天然就可以支撑高并发,因为动不动就可以扩容加机器来扛更高的并发。那么一些比较简单的查询、统计类的操作,可以考虑用 es 来承载,还有一些全文搜索类的操作,也可以考虑用 es 来承载。

上面的 6 点,基本就是高并发系统肯定要干的一些事儿,大家可以仔细结合之前讲过的知识考虑一下,到时候你可以系统的把这块阐述一下,然后每个部分要注意哪些问题,之前都讲过了,你都可以阐述阐述,表明你对这块是有点积累的。

说句实话,毕竟你真正厉害的一点,不是在于弄明白一些技术,或者大概知道一个高并发系统应该长什么样?其实实际上在真正的复杂的业务系统里,做高并发要远远比上面提到的点要复杂几十倍到上百倍。你需要考虑:哪些需要分库分表,哪些不需要分库分表,单库单表跟分库分表如何 join,哪些数据要放到缓存里去,放哪些数据才可以扛住高并发的请求,你需要完成对一个复杂业务系统的分析之后,然后逐步逐步的加入高并发的系统架构的改造,这个过程是无比复杂的,一旦做过一次,并且做好了,你在这个市场上就会非常的吃香。

其实大部分公司,真正看重的,不是说你掌握高并发相关的一些基本的架构知识,架构中的一些技术,RocketMQ、Kafka、Redis、Elasticsearch,高并发这一块,你了解了,也只能是次一等的人才。对一个有几十万行代码的复杂的分布式系统,一步一步架构、设计以及实践过高并发架构的人,这个经验是难能可贵的。