☰
分布式高频面试65题:CAP、Netty、锁、事务、分库分表与ID
2026/10/21 2:50:51 网站建设 项目流程

每年到面试季,总能看到同一类求助:分布式这块知识点太散,Netty、分布式锁、分布式事务、分库分表、分布式 ID 各看各的,看完就忘。这次整理的是一套分布式方向的高频面试题合集,一共 65 问,按六个模块组织,覆盖分布式基础与高频场景、Netty 与网络编程、分布式锁、分布式事务、分库分表、分布式 ID。每一问都给出核心回答框架和加分点,重点不是让你背答案,而是让你知道面试官问“CAP 为什么无法三者兼得”“雪花算法时钟回拨怎么办”时,真正想听到的是哪一层内容。

如果你正在准备 2026 年的后端开发、分布式中间件或高级 Java 岗位面试,这套题单可以作为自测清单直接使用;如果你已经工作两年以上,想系统检查自己对分布式体系的掌握情况,用它做查漏补缺也很合适。全文按“整体结构 -> 分模块真题解析 -> 自我测试与复习路线”组织,建议先看答案解析,再脱离答案逐题口述。

文中对每个模块都会先给出考查方向和难度,再挑最常考的几题做深度解析,最后列清该模块剩下的题目清单。下面的内容会直接进入正题,不铺垫背景,也不绕弯子。

1. 65 问整体结构与能力覆盖

模块题目数难度考查频率核心考点
分布式基础与高频场景10低到中必考CAP、BASE、共识算法、Session、幂等
Netty 与网络编程10中到高高线程模型、粘包拆包、零拷贝、心跳
分布式锁10中必考Redis、Redisson、ZooKeeper 实现与选型
分布式事务15高高2PC、TCC、SAGA、Seata、事务消息
分库分表12中到高高路由策略、跨库查询、扩容、中间件
分布式 ID8中必考雪花、号段、时钟回拨

从结构上能看出三个规律。第一,分布式基础概念题数量不大,但它是其他所有模块的地基,建议最先过一遍;第二,分布式事务是题目最重的模块,因为它的变体最多,2PC、TCC、SAGA、本地消息表、事务消息、Seata 每一种都得说清原理差异和适用场景;第三,分布式锁和分布式 ID 属于“必考但题量小”的模块,适合用碎片时间反复刷。

这套题单的能力覆盖可以按四个层级划分。第一层是概念理解,比如 CAP 的定义;第二层是原理推导,比如为什么 2PC 会被 3PC 改进;第三层是方案对比,比如 Redis 锁和 ZooKeeper 锁怎么选;第四层是工程落地,比如分库分表后怎么平滑扩容。面试里从第二层开始才是分水岭,只停留在第一层概念记忆,大概率过不了二面。

2. 第一模块:分布式基础与高频场景(10 问)

这个模块是所有分布式知识的入口。面试官用这几道题判断你的基本功是否扎实,回答要求是“定义准确、例子常见、取舍清楚”。

2.1 CAP 为什么无法三者兼得

问题 1:CAP 定理怎么理解?为什么无法同时满足?

先给出定义:C 是一致性,所有节点在同一时刻看到同一份数据;A 是可用性,每个请求都能收到非错误的响应;P 是分区容错性,网络分区发生时系统依然能工作。核心观点是:分布式系统中网络分区是统计学上必然出现的事件,P 必须选,因此真正的问题变成分区发生时选 C 还是选 A。如果选 C,分区期间需要拒绝部分请求来等待数据对齐,可用性受损;如果选 A,各分区继续独立服务,数据可能不一致。

加分点是补一句“CAP 不是三选二,而是分区发生时二选一;系统正常运行时 C 和 A 可以同时满足”。再带上常见例子:ZooKeeper 是 CP 倾向,Eureka 是 AP 倾向,RocketMQ 在有主从副本策略时也需要做一致性取舍。扣分点是把 CAP 说成“三个只能选两个”,这是最常见的错误理解。

2.2 Raft 与 Paxos 的区别

问题 2:Raft 和 Paxos 的定位有什么区别?为什么推荐先学 Raft?

Paxos 是 Leslie Lamport 提出的共识算法家族,理论严谨但实现难度极高,原始论文里 Multi-Paxos 的细节需要自行推导,工业落地时每个团队的理解可能都不一样。Raft 把共识问题分解成领导者选举、日志复制、安全性三个子问题,并引入任期和随机超时选举机制,让算法可理解和可实现。回答时要指出一个关键差异:Paxos 允许任意节点发起提案,多提案需要 quorum 仲裁;Raft 强制同一任期只有一个 Leader,所有写请求经由 Leader 复制到 Follower,因此工程上更可控。

面试官通常会追加一题:Raft 怎么保证日志不会丢失?回答方向是“Leader 选举时候选者必须包含全部已提交日志,日志提交需要大多数节点确认,Follower 落后会持续追赶日志”。能把这个追加题答好,说明你对共识不是停留在概念记忆。

2.3 脑裂与缓存一致性

问题 3:分布式系统为什么会脑裂?Raft 如何解决?

脑裂指节点间网络中断后,多个分区同时认为自己是主节点。Raft 的解决思路是任期与多数派:每个任期最多一个 Leader 能获得大多数节点投票,网络分区后少数派无法获得过半数赞成,也就无法产生有效 Leader;同时旧 Leader 收到更高任期的请求后会主动让位。实践中还会搭配租约、fencing token 等机制,防止旧 Leader 在网络恢复前继续写数据。

问题 4:缓存与数据库的一致性怎么保证?

这是高频场景题。读路径用 Cache Aside 模式,先读缓存,未命中则读数据库并回填;写路径先更新数据库再删除缓存,而不是先删缓存再更新数据库,因为后一种会引入更大的并发窗口。更严格的做法是延迟双删,或删除失败时通过 MQ 重试;追求强一致则用 Canal 订阅 binlog 同步缓存,并接受引入组件的复杂度。加分点:说明删除缓存优于更新缓存,原因在于更新缓存需要处理并发写覆盖和缓存与库的不一致窗口。

2.4 本模块完整题目清单

题号题目自测结果
1什么是分布式系统,它要解决什么问题?口述 3 分钟
2CAP 为什么无法三者兼得?需要讲出分区案例
3BASE 理论和 ACID 是什么关系?对应到具体系统
4Raft 和 Paxos 的区别?讲出 Leader 与任期
5脑裂是怎么发生的?怎么解决?结合 Raft 回答
6数据副本同步的几种方式?同步/异步/半同步
7分布式 Session 有哪些方案?Redis、粘性、复制
8缓存与数据库一致性怎么保证?Cache Aside + 删缓存
9接口幂等怎么设计?唯一索引、状态机
10负载均衡策略有哪些?结合网关场景说明

3. 第二模块:Netty 与网络编程(10 问)

Netty 题面试官一般用来考查候选人对高性能网络编程的理解,回答重点从“会用 API”上升到“理解线程模型和内存模型”。这组题不是背 API,而是讲清楚 Netty 为什么快、快在哪里、边界在哪里。

3.1 线程模型与 Reactor

问题 1:Netty 相比 Java NIO 解决了什么问题?

Java NIO 的 Selector 只提供了多路复用基础能力,使用起来要自己处理线程模型、ByteBuffer 复用、半包读写等问题,稍不注意还会出现线程安全和内存释放错误。Netty 在此基础上封装了完整的 Reactor 线程模型、责任链 Pipeline、自动拆包解码器以及池化内存管理,让开发者关注业务编解码而不是底层轮询细节。回答时建议从三方面对比:API 友好度、线程模型升级、内存管理能力。

问题 2:Netty 的线程模型是什么?

核心是 Reactor 模型,常见三种形态。单线程 Reactor:一个线程同时处理 accept、read、write,适合连接数极少的场景;多线程 Reactor:一个 acceptor 线程接受连接,一组 worker 线程处理 IO;主从 Reactor:对应 Netty 的 BossGroup 和 WorkerGroup,Boss 负责 accept,Worker 负责 read/write,业务解码再丢到单独的业务线程池。加分点:说明 Netty 的每个 EventLoop 绑定一个线程,且一个 Channel 生命周期内的 IO 事件都在同一个 EventLoop 上执行,因此不需要加锁;同时强调不要在 IO 线程中做耗时业务,否则会阻塞该 EventLoop 上的所有 Channel。

3.2 粘包拆包与解码器

问题 3:TCP 粘包拆包是什么原因?Netty 怎么解决?

粘包指多个消息被合并在一个包中,拆包指一个消息被拆到多个包中,根因是 TCP 是字节流协议,应用层没有消息边界。Netty 解决方式是使用解码器:LineBasedFrameDecoder 按换行符切分,DelimiterBasedFrameDecoder 按自定义分隔符切分,FixedLengthFrameDecoder 按固定长度切分,LengthFieldBasedFrameDecoder 在消息头存储消息长度,是最通用的方案。回答时重点说最后一种,并说明 lengthFieldOffset、lengthFieldLength 等关键参数配置;加分点是结合自定义协议设计,比如 4 字节 magic + 1 字节版本 + 4 字节长度 + body。

3.3 零拷贝与心跳机制

问题 4:Netty 的零拷贝体现在哪些方面?

在 Netty 语境下零拷贝至少包含三层意思。第一层是 ByteBuf 的引用计数和池化复用,避免反复创建和释放直接内存;第二层是 CompositeByteBuf 可以把多个缓冲区组合成一个逻辑缓冲区,避免多次遍历;第三层是 FileRegion 配合 NIO 的 transferTo,让文件发送从用户态直接到内核态,减少拷贝次数。加分点:把零拷贝和内核态、用户态结合说明,面试官会更认可深度。

问题 5:心跳和断线重连怎么设计?

心跳用 IdleStateHandler 检测读写空闲,空闲超时后触发事件,由 ChannelHandler 关闭异常连接或发送 Ping 探测。断线重连一般放在客户端:捕获连接断开异常后使用指数退避策略重连,同时注意连接状态标记,避免重复发起重连。更完整的方案是服务端定期清理死连接、客户端与服务端互相 ping-pong,并配合重连次数上限。

3.4 本模块完整题目清单

题号题目自测结果
1Netty 相比 Java NIO 的优势?线程模型 + 内存
2Reactor 模型三种形态分别适用什么场景?画图说明
3Channel、Pipeline、ChannelHandler 的关系?责任链思想
4TCP 粘包拆包的原因和解决方式?LengthField 必会
5Netty 零拷贝体现在哪些方面?至少说三层
6心跳与断线重连怎么实现?指数退避
7ByteBuf 相比 ByteBuffer 优势?动态扩容、池化
8EventLoop 绑定线程有什么好处?无锁串行
9什么是背压,Netty 怎么处理?写缓冲高水位
10为什么 RPC 框架用 Netty 做通信?性能 + 扩展性

4. 第三模块:分布式锁(10 问)

分布式锁是工作中用得最多、面试最常考的模块,考查重点集中在三件事:为什么加过期时间、释放锁为什么用 Lua、Redis 和 ZooKeeper 怎么选。

4.1 Redis 锁的基础实现

问题 1:基于 Redis 的分布式锁怎么实现?

最基础方案是 SET key value NX PX 30000:NX 保证只有 key 不存在时才能设置成功,PX 设置过期时间避免死锁,value 使用客户端唯一标识。加锁成功后返回业务执行;释放锁时必须先比较 value 是否自己的锁,匹配才删除,直接给出 Lua 脚本:

-- 释放锁:先校验 value,再删除,保证原子性 if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end

强调为什么不用先 get 再 del:两条命令中间可能插入其他请求的删除操作,导致把自己的锁误删。这也是 Lua 脚本在这个场景存在的意义。value 里建议放 UUID 加线程号组成的唯一标识,保证只能释放自己持有的锁。

问题 2:锁过期了业务没执行完怎么办?

这是必搭追问。基础方案是把过期时间设长,或临结束时检查续期;标准方案是 Redisson 的看门狗机制,默认每 10 秒对锁续期一次,把过期时间重置为 30 秒,业务线程退出时自动释放。加分点:说明看门狗同样有边界问题,如果主进程发生长 GC 或网络分区,续期也可能失败,所以任何分布式锁都不能 100% 保证互斥,只能通过 fencing token 等手段规避极端情况。

4.2 ZooKeeper 锁与选型

问题 3:ZooKeeper 分布式锁怎么实现?

利用临时顺序节点:客户端创建 /locks/lock_ 临时顺序节点,然后检查自己是不是序号最小的节点,是则获得锁;不是则监听前一个节点,前一个节点删除后重新尝试。临时节点的好处是客户端异常退出时节点自动删除,不会出现 Redis 的“锁记录持久存在”问题;同时可以通过 watch 机制实现锁释放通知。缺点是频繁的节点创建删除和 watch 触发对 ZooKeeper 压力较大,性能一般不如 Redis。

4.3 本模块完整题目清单

题号题目自测结果
1什么场景需要分布式锁?秒杀、任务调度、幂等写
2SETNX 实现锁的核心步骤?SET NX PX
3为什么必须设置过期时间?防死锁
4锁过期业务没结束怎么办?看门狗续期
5释放锁为什么用 Lua?原子性比对删除
6Redisson 可重入锁实现?Hash + 计数
7RedLock 是什么,有什么问题?时钟与多数派
8ZooKeeper 临时顺序节点加锁流程?监听前节点
9Redis 和 ZooKeeper 锁怎么选?性能 vs 可靠性
10分布式锁怎么设计续期和容错?看门狗 + 降级

选型结论可以概括为一句话:业务要求高性能、能接受极端情况小概率失效,选 Redis;业务要求强可靠、服务治理基础设施里已有 ZooKeeper,选 ZooKeeper。无论选哪种,都不能替代业务层的幂等设计,锁只是第一道防线。

5. 第四模块:分布式事务(15 问)

分布式事务是 65 问里分量最重的一块,15 道题覆盖从理论到框架的全链路。这里的总纲是:先判断业务要强一致还是最终一致,再选方案。

5.1 2PC 与 TCC 的原理和问题

问题 1:2PC 的流程是什么?有什么缺陷?

两阶段提交分为准备阶段和提交阶段。协调者先向所有参与者发 prepare,参与者执行事务但先不提交,返回 ready 或 abort;如果全部 ready,协调者发 commit,否则发 rollback。缺陷从三方面说:一是同步阻塞,prepare 之后参与者占用资源等待协调者决策;二是协调者单点,协调者宕机时参与者卡在阻塞状态;三是数据不一致,commit 阶段网络断裂时部分参与者提交、部分没有提交,无法通过 2PC 自身修复。

问题 2:TCC 模式的核心思想和常见坑?

TCC 把每个业务操作拆成 Try、Confirm、Cancel 三步。Try 阶段检查资源并预留,Confirm 阶段真正执行,Cancel 阶段释放预留资源。三个高频坑:空回滚,Try 没执行但 Cancel 被调用,需要根据事务状态判断是否回滚;幂等,Confirm 和 Cancel 可能被重复调用,必须有幂等控制;悬挂,Cancel 先于 Try 执行,导致资源永远无法释放。加分点:说明 TCC 的代码侵入性很高,每个业务接口都要写三个方法,一般只在核心链路使用。

5.2 消息事务与 Seata

问题 3:本地消息表和 RocketMQ 事务消息的区别?

本地消息表是经典方案:业务数据与消息表在同一个本地数据库事务中落库,再通过定时任务扫描消息表发送消息,并根据回执更新消息状态。事务消息方案是 RocketMQ 提供的半消息机制:先发送 half 消息,broker 暂不投递;本地执行完业务后提交二次确认,broker 才真正投递;如果长时间没确认,broker 反向查询业务状态。两者都解决“发消息和本地事务不一致”的问题,区别是本地消息表依赖定时任务有延迟,事务消息由 MQ 端保证状态查询,延迟更小。

应用发送 half 消息 -> 本地业务事务 -> commit/rollback -> broker 投递/删除 -> 未确认时回查业务状态

真实业务里还需要配合消费幂等,否则 MQ 重复投递会造成数据重复写入。判断方案优劣时要结合已有中间件:已经引入 RocketMQ,优先事务消息;依赖较少时,本地消息表用数据库就能实现。

问题 4:Seata AT 模式原理是什么?

Seata 是一款分布式事务框架,AT 模式基于数据源代理自动生成 undo_log:业务 SQL 执行前记录前镜像和后镜像,分支事务注册后参与全局提交;回滚时根据 undo_log 反向生成补偿 SQL。和 TCC 相比,AT 模式对业务代码侵入小,只需要在入口方法加 @GlobalTransactional 注解,但要求数据库支持本地事务,且全局锁和 undo_log 会带来额外开销。加分点:说明 AT 模式也有隔离性问题,Seata 通过全局锁避免写冲突,但长时间持有全局锁会影响并发。

5.3 本模块完整题目清单

题号题目自测结果
1分布式事务产生的本质原因?跨资源无法本地原子
22PC 的流程和缺陷?阻塞、单点、不一致
33PC 解决了 2PC 的哪些问题?引入超时避免阻塞
4TCC 空回滚、悬挂、幂等怎么处理?事务状态表
5SAGA 模式怎么编排补偿?正向 + 反向补偿
6本地消息表怎么实现?同库 + 定时扫描
7RocketMQ 事务消息原理?half + 回查
8Seata AT 模式如何用 undo_log 回滚?前后镜像
9AT 和 TCC 怎么选?侵入性 vs 灵活性
10事务消息和本地消息表的差异?延迟与依赖
11怎么保证事务消息不丢失?ack + 重试 + 告警
12事务中的幂等控制?唯一键、状态位
13Seata 全局锁与隔离级别?写冲突保护
14@GlobalTransactional 完整流程?TM/RM/TC 交互
15强一致与最终一致如何权衡?业务场景判断

6. 第五模块:分库分表(12 问)

分库分表题考查数据库架构设计能力和权衡能力。面试官最关心三个点:什么时候做、怎么路由、拆了之后新问题怎么解决。只背一个“用户表按 ID 取模”是远远不够的。

6.1 拆分策略与分片键

问题 1:什么时候需要分库分表?

先给触发条件:单表数据量超过千万级、写入并发超过单库瓶颈、单库连接数不够用;再强调不要过早拆分,优先考虑索引优化、读写分离、缓存、归档。分库分表是最后手段,因为它带来查询复杂度上升、分布式事务和扩容成本。加分点:说明“阈值本身不是硬性标准,还要看数据增长速度和查询模式”。

问题 2:分片键怎么选?

分片键选择影响所有路由。原则是选择查询频率最高、值分布均匀的字段,例如订单表按 user_id 分片,那所有按 user_id 的查询都能定位到单表;如果业务经常按商家维度和用户维度双向查询,通常选一个主维度分片,另一个维度通过冗余或搜索引擎解决。扣分点:如果分片键是“订单号”而业务大量按“用户 ID”查,查询就会变成全表广播。

6.2 跨库查询和扩容

问题 3:跨库 join 怎么解决?

标准回答从外到内:优先做字段冗余,把关联字段冗余到查询表中;其次做应用层组装,分别在多个分片查询后在应用内合并;再次引入搜索服务,复杂查询交给 Elasticsearch。反例是使用跨库 join,会让分库失去扩展意义。加分点:说明分页排序也是同类问题,limit offset 在分片环境下要对多个分片的结果做二次归并。

问题 4:数据平滑扩容怎么做?

一次到位式的“翻倍扩容 + 重新哈希”在线上不可接受,因为迁移过程需要停机或大量双写。常见思路是使用一致性哈希或范围分片减少迁移范围;更工程化的方案是提前建立双分片键映射,或用影子表迁移、发布订阅同步新库,灰度切换读流量到新库,验证稳定后再切写流量。加分点:强调扩容一定要配合数据校验和回滚预案。

6.3 中间件与完整题目清单

ShardingSphere 是当前最常用的分库分表中间件之一,配置上通过 YAML 声明分片规则:

rules: - !SHARDING tables: t_order: actualDataNodes: ds_${0..1}.t_order_${0..1} tableStrategy: standard: shardingColumn: user_id shardingAlgorithmName: t_order_inline keyGenerateStrategy: column: order_id keyGeneratorName: snowflake shardingAlgorithms: t_order_inline: type: INLINE props: algorithm-expression: t_order_${user_id % 2} keyGenerators: snowflake: type: SNOWFLAKE

注意:示例中的路由表达式需要按实际表名和分片键替换,真实项目还要补充绑定表、广播表规则,并考虑分片键变更和扩容方案。

题号题目自测结果
1什么情况下才需要分库分表?先优化再拆
2垂直拆分和水平拆分的区别?按业务 vs 按行
3常见路由策略有哪些?取模、范围、一致性哈希
4分片键怎么选?高频 + 均匀
5跨库 join 怎么办?冗余、组装、搜索
6分库分表后主键怎么生成?雪花或号段
7全局表和广播表怎么处理?所有节点冗余
8分页排序怎么做?归并排序
9数据平滑扩容方案?双写、影子表、灰度
10ShardingSphere 和 MyCat 怎么选?标准 SQL vs 代理
11读写分离和分库分表怎么组合?主写从读
12分库分表引入的新问题?事务、join、ID、扩容

7. 第六模块:分布式 ID(8 问)

分布式 ID 题通常作为分库分表题的延伸,也可以单独出道。核心答法是“先列需求,再对比方案,最后深入雪花算法”。

7.1 需求与方案对比

问题 1:分布式 ID 需要满足什么要求?

全局唯一、趋势递增、高可用、高吞吐,如果 ID 会暴露在订单号或用户号里,还要考虑安全性,不能让人从相邻 ID 推测出业务量。回答时强调“趋势递增”而不是“严格递增”,因为严格递增在高并发下会成为单点瓶颈。

问题 2:UUID、数据库自增、Redis INCR 各自有什么问题?

UUID 无需部署但太长、无序,不利于数据库索引;数据库自增实现简单,但单库有吞吐瓶颈,跨库时需要分段设置步长;Redis INCR 性能高,但依赖 Redis 可用性,且 ID 连续可被猜测。正是这些问题推动了雪花算法的流行。

7.2 雪花算法详解与时钟回拨

问题 3:雪花算法的结构和优缺点?

标准雪花 ID 共 64 位:1 位符号位 + 41 位时间戳 + 5 位数据中心 + 5 位机器号 + 12 位序列号。同一毫秒内可生成 4096 个 ID,整体趋势递增。给出一个教学用最小实现:

public class SnowflakeIdGenerator { private static final long SEQUENCE_BITS = 12L; private static final long WORKER_ID_BITS = 5L; private static final long DATACENTER_ID_BITS = 5L; private static final long MAX_SEQUENCE = ~(-1L << SEQUENCE_BITS); private static final long WORKER_ID_SHIFT = SEQUENCE_BITS; private static final long DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS; private static final long TIMESTAMP_SHIFT = DATACENTER_ID_SHIFT + DATACENTER_ID_BITS; private static final long EPOCH = 1288834974657L; private long workerId; private long datacenterId; private long sequence = 0L; private long lastTimestamp = -1L; public synchronized long nextId() { long timestamp = System.currentTimeMillis(); if (timestamp < lastTimestamp) { // 时钟回拨:根据回拨范围选择等待、抛异常或使用备用时钟 throw new IllegalStateException("Clock moved backwards"); } if (timestamp == lastTimestamp) { sequence = (sequence + 1) & MAX_SEQUENCE; if (sequence == 0) { timestamp = waitNextMillis(lastTimestamp); } } else { sequence = 0L; } lastTimestamp = timestamp; return ((timestamp - EPOCH) << TIMESTAMP_SHIFT) | (datacenterId << DATACENTER_ID_SHIFT) | (workerId << WORKER_ID_SHIFT) | sequence; } private long waitNextMillis(long lastTimestamp) { long timestamp = System.currentTimeMillis(); while (timestamp <= lastTimestamp) { timestamp = System.currentTimeMillis(); } return timestamp; } }

生产环境还要补充时钟回拨策略、Worker ID 分配、监控和日志,不能直接拿最小实现上线。

问题 4:时钟回拨怎么处理?

标准思路有四种。小回拨,比如几十到几百毫秒,可以等待时钟追平再继续;中量回拨,可以记录上次发号时间,回拨期间序列号不从 0 开始;大量回拨,只能标识异常并暂停发号;更保险的方案是在发号服务里增加备用时钟对比,或者使用雪花 ID 加号段模式混合。加分点:说明美团 Leaf 在纯雪花方案之外提供的号段模式,就是为了规避时钟和服务依赖问题。

7.3 本模块完整题目清单

题号题目自测结果
1分布式 ID 必须满足哪些要求?全局唯一、趋势递增
2UUID 为什么不适合当主键?无序、太长
3数据库自增方案的优缺点?简单但单点
4Redis INCR 方案的问题?依赖 Redis
5雪花算法的位结构?41 + 5 + 5 + 12
6时钟回拨怎么处理?等待、异常、备用
7号段模式原理?批量取号、内存发放
8美团 Leaf 和 UidGenerator 对比?号段 vs 雪花变体

8. 自我测试方法与答题验证

这套题单不能用“看一遍”的方式学。建议用“脱离答案口述 + 录音回听”的方式自测:每题给自己 3 分钟,说清楚三个层次——定义是什么、为什么这样设计、换了场景怎么变。说不出来的题标记为核心弱点,集中复习后再测一次。只看不说的效果很差,因为面试本质是口头表达,不是选择题。

推荐的答题框架是“定义-取舍-场景”三层法。第一层直接给结论,比如“分布式锁就是跨进程互斥”;第二层说取舍,比如“Redis 锁性能高但极端情况可靠性弱,ZooKeeper 锁可靠但性能一般”;第三层落到场景,比如“秒杀链路用 Redis 锁,配置中心变更用 ZooKeeper 锁”。这套方法能覆盖大部分面试追问。六本模块的题目清单就是天然的抽查表,打乱顺序逐题口述,比按顺序背更接近真实面试。

建议每次模拟面试后更新一张自查表:

题目类别当前得分最大问题下次复习时间
CAP 与共识算法2/3讲不出脑裂案例第 3 天
Netty 线程模型1/3画不出主从 Reactor第 5 天
分布式事务选型2/3TCC 悬挂没讲清第 7 天

自查表的作用不是给你成就感,而是告诉你第二遍复习时重点看什么。每次只解决三到五个最弱的问题,比把整份题单重读一遍更有效。

9. 复习路线与避坑清单

如果目标是两周内吃掉这套题,推荐顺序是:分布式基础 -> 分布式 ID -> 分布式锁 -> 分布式事务 -> 分库分表 -> Netty。前三个模块适合先建立体系,题量小、见效快;分布式事务内容最多,建议单独安排三天;Netty 放在最后,因为它的前置是 Java 并发和 NIO 基础。每天先过提问清单再看解析,再脱离答案口述一次,错题反复练。面试前三天再按模块快速过一遍完整题目清单,重点回看自查表里得分最低的部分。

避坑清单里最值得注意的五条。第一,不要把 CAP 说成“三选二”,要说是“分区发生时二选一”。第二,不要认为 Redis 锁绝对安全,任何锁都可能因 GC、网络分区失效,要配合幂等和 fencing token。第三,不要把 TCC 和 2PC 混为一谈,TCC 是业务级方案,2PC 是资源级方案。第四,分库分表不是越早越好,拆完之后的事务代价和查询复杂度要一起讲清楚。第五,雪花算法看似简单,但生产环境必须处理时钟回拨和 Worker ID 分配,只写核心几行代码会给面试官留下缺乏工程经验的印象。

面到项目部分时,如果简历里有分布式项目,尽量把题单里的方案和项目结合:比如你的系统用了 Seata,就主动讲 AT 模式的 undo_log 流程和隔离性取舍;用了分库分表,就讲分片键选择和扩容遇到的坑。把“答题模式”切换成“项目模式”,技术深度会明显更好。

10. 最后总结

这 65 问的价值不在一题一题背出来,而在帮你把分布式体系的骨架理顺:基础概念定方向,Netty 管通信,分布式锁解决资源竞争,分布式事务保证多资源一致性,分库分表应对数据增长,分布式 ID 解决全局主键。每个模块单独看都有大量资料,但放进同一个问题清单里,才能形成面试时的应答网络。

建议收藏备用。先按第 8 节的自测方法过一轮,找出三到五个薄弱点,再对照对应模块的题目精读;第二轮复习时尝试不看书,把六张题目清单里的所有题目口述一遍,能完成这一步,这套题基本就吃透了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询