很多准备跳槽的同学都会遇到这样一个问题:分布式面试题刷了不少,Redis 分布式锁、Zookeeper 锁、分布式事务、分库分表、分布式 ID,每一个专题都能背出来几条,但一到面试现场,面试官稍微追问两句"为什么"就卡住了。
原因很简单:你背的是题,不是体系。
这个现象在近两年的后端面试里越来越明显。分布式已经不是一个加分项,而是初中级向高级跨越的必考项。面试官不再满足于"会不会用 Redisson",而是更关心"你知不知道 Redis 锁在极端情况下会失效""分库分表之后怎么做全链路查询""分布式事务到底哪些场景才真的需要"。这些问题背后考察的,其实是你对分布式系统全貌的理解程度。
这篇文章不打算再做一份"题目搬运清单"。正文会围绕分布式面试里最常出现的六大专题,把高频问题、参考答案思路和容易踩的坑放在一起讲清楚,顺便给你一条相对完整的复习主线。如果你正在准备 2026 年的跳槽面试,或者想系统梳理分布式知识,这篇文章值得先收藏再慢慢看。
1. 分布式面试到底在考什么
先说一个判断:分布式面试题看上去五花八门,但本质上只考四件事。
第一,数据一致性。分布式锁丢了怎么办,分布式事务最终一致怎么做,缓存和数据库怎么避免不一致,这些都是围绕一致性展开的。
第二,可用性与容灾。集群里一个节点挂了流量怎么切换,服务降级怎么做,熔断限流怎么兜底。
第三,性能与扩展性。单机写不下了怎么分库分表,读多写少怎么加缓存,连接数扛不住怎么上 Netty。
第四,全局唯一性问题。多台机器同时生成 ID 怎么保证不重复,订单号怎么做全局递增或趋势递增。
把这四条主线放在脑子里,再看市面上任何一份"分布式面试 N 问",你会发现题目只是这些主线的具体场景化表达。所以这篇文章的章节顺序也是按这条主线展开的:先讲分布式锁和事务怎么保障一致性,再讲分库分表怎么做扩展,然后讲分布式 ID 怎么保证唯一,最后讲 Netty 怎么解决高并发 IO,最后补上缓存一致性、幂等、会话管理等高频旁支问题。
2. 分布式锁专题:先别急着写代码,想清楚锁到底锁什么
分布式锁是面试中出现频率最高的题目之一,也是一个"看起来简单,深挖全是坑"的专题。
2.1 Redis 实现分布式锁的正确姿势
面试官通常不会直接问"你怎么用 Redis 实现分布式锁",他更可能会问:"用 SETNX 能不能实现分布式锁?有什么问题?"
SETNX 可以,但只靠 SETNX 不行。经典实现里,获取锁要保证原子性,所以一般会用 SET key value NX PX 30000 这样的命令。它同时做到了两件事:key 不存在时才设置成功,这就保证了互斥;设置过期时间,这就避免了死锁。
SET lock_key unique_value NX PX 30000但这里有一个容易被追问的点:过期时间设多长合适?
设短了,业务没执行完锁就自动释放了,另一个线程拿到锁进来,并发问题立刻出现;设长了,如果持有锁的节点宕机,其他节点要等很久才能拿到锁。这个时间没有标准答案,只能根据业务接口的预估耗时来设置,并且要留出足够的缓冲。
释放锁的代码同样有讲究。很多人用 DEL 直接删,但这是错的。如果线程 A 的锁已经过期自动释放了,线程 B 拿到了锁,此时 A 执行完业务再执行 DEL,删的就是 B 的锁。所以释放锁之前必须先判断 value 是否是自己写入的那个唯一标识。
// 释放锁前判断是否持有锁 if (jedis.get(lockKey).equals(lockValue)) { jedis.del(lockKey); }更稳妥的办法是使用 Lua 脚本保证"判断+删除"的原子性。这也是 Redisson 底层释放锁的做法。
2.2 Redisson 的看门狗机制是加分项
如果只是在 Redis 上加锁释放锁,这道题只能算及格。想拿高分,必须提到Redisson 的看门狗(Watch Dog)机制。
Redisson 加锁时默认会启动一个后台定时任务,每隔一段时间(默认是锁过期时间的三分之一)检查锁是否还在持有中,如果还在,就自动续期。这样业务没执行完,锁不会提前过期;业务执行完了,锁会主动释放,看门狗也就跟着取消。
这个机制解决的核心问题就是:"过期时间设长还是设短"这个两难选择题。Redisson 的做法是"动态续期",而不是让开发者去猜一个固定时间。
RLock lock = redissonClient.getLock("order:pay:" + orderId); try { // 尝试加锁,最多等待 5 秒 boolean locked = lock.tryLock(5, TimeUnit.SECONDS); if (locked) { // 业务逻辑 } } finally { if (lock.isHeldByCurrentThread()) { lock.unlock(); } }但这里也存在一个必须知道的坑:如果 Redis 主节点在加锁后立刻宕机了,锁还没同步到从节点,主从切换后,新的主节点上没有这把锁的信息,另一个线程就能加锁成功。这就是 RedLock 算法要解决的场景,不过在多数互联网业务里,引入 RedLock 的成本很高,面试里能说清楚它的思路和局限性就已经是加分项了。
2.3 Zookeeper 分布式锁与 Redis 锁怎么选
Zookeeper 分布式锁的核心原理是临时顺序节点 + Watcher 监听机制。多个客户端同时创建临时顺序节点,只有序号最小的客户端能拿到锁;其他客户端监听比自己序号小的节点,等它释放后继续竞争。
// Zookeeper 分布式锁核心思想(伪代码) String lockPath = "/locks/lock_"; String currentNode = zk.create(lockPath, data, OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); List<String> children = zk.getChildren("/locks", false); // 判断自己是否是最小节点 // 如果不是,监听前一个节点两者的核心差异在于可靠性模型的取舍:
- Redis 锁:AP 模型,高可用、性能好,但在极端故障下可能失效。
- Zookeeper 锁:CP 模型,强一致性,可靠性高,但性能相对弱一些,而且 ZK 本身也要维护。
实际项目中,缓存类、短任务类场景用 Redis 锁更多;对一致性要求极高、且业务愿意接受 ZK 运维成本的项目,才会考虑 Zookeeper 锁。这个选择本身没有绝对正确,关键在于你能不能说出来"为什么你的场景选了它"。
2.4 分布式锁专题小结论
能回答"为什么不用 SETNX""过期时间怎么定""释放锁为什么用 Lua""主从切换锁失效怎么办"这几个问题,分布式锁这一关基本就稳了。记住一个主线:分布式锁考察的不是 API 调用,而是你对"互斥、超时、原子性、故障恢复"这四个要素的理解深度。
3. 分布式事务专题:不是所有场景都该上 Seata
分布式事务是面试里第二个高频大专题,也是最容易被"背偏"的专题。很多同学能把 2PC、3PC、TCC、MQ 事务消息讲一遍,但问到"你的项目到底为什么需要分布式事务",就说不清了。
3.1 从 CAP 与 BASE 讲起
讲分布式事务之前,先要把理论基础说清楚。CAP 定理指出,分布式系统在一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)三者中最多同时满足两个。而在分布式环境下,网络分区是必然的,所以 P 必须选,剩下的 C 和 A 只能二选一。
BASE 理论是"最终一致性"的理论支撑:基本可用(Basically Available)、软状态(Soft State)、最终一致(Eventually Consistent)。绝大多数互联网业务走的都是 BASE 路线,而不是追求强一致的 ACID。
3.2 2PC 和 3PC 的经典套路
2PC(两阶段提交)分为准备阶段和提交阶段。协调者先问所有参与者"能不能提交",所有参与者都回复 YES 后,协调者再统一发 COMMIT。
2PC 的核心问题是同步阻塞和协调者单点。参与者要一直占着资源等待协调者的最终指令,如果协调者挂了,参与者就只能一直等。
3PC 引入了超时机制和预提交阶段,降低了阻塞范围,但依然没有从根本上解决数据一致性问题,而且实现复杂度更高,实际使用场景并不多。面试里能说清楚 2PC 的核心流程和问题点就够了。
3.3 TCC:补偿型事务的经典实现
TCC 是一个面试必须掌握的方案。它把业务拆成三个动作:Try(预留资源)、Confirm(确认执行)、Cancel(取消释放)。
一个典型的转账场景:A 账户扣钱,B 账户加钱。Try 阶段分别冻结 A 的扣款金额和检查 B 账户是否可入账;Confirm 阶段真正执行扣款和入账;如果 B 入账失败,则执行 Cancel,把 A 的冻结金额解冻。
// TCC 接口设计示例 public interface TransferService { // 第一阶段:预留资源 boolean tryTransfer(Account from, Account to, BigDecimal amount); // 第二阶段:确认执行 boolean confirmTransfer(Account from, Account to, BigDecimal amount); // 第三阶段:取消释放 boolean cancelTransfer(Account from, Account to, BigDecimal amount); }TCC 的优势是性能比 2PC 好,不需要长期占用数据库资源;劣势是对业务侵入性强,每个操作都要写三个方法,而且空回滚、悬挂、幂等等问题都要自己处理。
3.4 本地消息表与 MQ 事务消息
本地消息表是理解起来最直观的方案:业务操作和写消息放在同一个本地事务里,然后通过定时任务把消息表里的消息发送到 MQ。消费者消费成功后再更新消息状态。
MQ 事务消息把"本地事务+消息表"这件事搬到了 MQ 侧。以 RocketMQ 为例,producer 先发送 half message,然后执行本地事务,事务成功后提交消息,事务失败则回滚消息;如果长时间没有收到确认,MQ 会主动回查事务状态。
// RocketMQ 事务消息发送端核心流程 TransactionMQProducer producer = new TransactionMQProducer("group"); producer.setTransactionListener(new TransactionListener() { @Override public LocalTransactionState executeLocalTransaction(Message msg, Object arg) { // 执行本地业务事务 // 返回 COMMIT_MESSAGE 或 ROLLBACK_MESSAGE } @Override public LocalTransactionState checkLocalTransaction(MessageExt msg) { // 回查本地事务状态 } });3.5 Seata 的 AT 模式和 TCC 模式怎么选
Seata 是目前应用最广的分布式事务框架。它的 AT 模式对业务侵入最小:通过代理数据源,在业务 SQL 执行前后自动记录快照,事务回滚时用快照恢复数据。
# Seata 配置示例 seata.tx-service-group=my_test_tx_group seata.service.vgroup-mapping.my_test_tx_group=default seata.service.grouplist.default=127.0.0.1:8091AT 模式适合那种"SQL 简单、不想改造业务代码"的项目,但它也有代价:全局锁会对性能有影响。TCC 模式适合性能要求高、愿意为每个事务写三个方法的场景。面试里如果能说出"我们最终选了哪个模式,因为什么权衡",效果远好于只背八股。
3.6 分布式事务专题小结论
分布式事务是典型的**"方案越多,越要回到场景"**的专题。面试官想验证的是:你知不知道强一致和最终一致的区别,你能不能判断一个需求是不是真的需要分布式事务,你能不能为了一个很小的概率把系统复杂度拉高。真正的加分点,是"你说清楚了我们项目里哪个操作用了事务消息,哪个用了 Seata,为什么这么设计"。
4. 分库分表专题:面试题背后的容量规划
分库分表的题目通常不会直接问你语法,而是从一个问题开始:"单表数据到了多少,你真的需要分库分表?"
4.1 分库分表前先确认:真的需要吗
一个很常见的误区是:数据量刚到千万级别就急着分表。其实很多团队在单表几千万甚至上亿时依然跑得好好的,关键在于索引设计是否合理、查询是否走索引、写入量是否还在单库承受范围内。
分库分表的本质是容量规划和性能规划,不是"数据多了就分"。该不该分,主要看两个指标:
- 单表数据量是否已经明显影响读写性能。
- 单库的连接数、IO 是否已经成为瓶颈。
如果只是读压力大,优先考虑加缓存加从库;如果写入和存储都到了瓶颈,再考虑分片。
4.2 垂直拆分与水平拆分要分清
垂直拆分是按业务维度拆表或拆库,比如订单库、用户库、商品库分开。它解决的是"单库表太多、IO 竞争严重"的问题。
水平拆分是把一张大表按某个字段拆到多张表或多个库中,比如把订单表按用户 ID 取模拆成 32 张表。它解决的是"单表数据量过大、写入查询变慢"的问题。
面试里容易混淆的是:垂直拆分解决的是"宽度"问题,让单库更轻;水平拆分解决的是"高度"问题,让单表更矮。这两个概念别看简单,真到设计方案时很多人会弄混。
4.3 分片键的选择是全局最关键的一步
分片键选错了,分库分表就是给自己挖坑。核心规则是:选查询频率最高的字段、且这个字段的值分布足够均匀。
订单场景通常按 user_id 分片,因为用户查询自己的订单是最高频请求;如果按 order_id 分片,用户查询订单列表时就要在所有分片里扫一遍,性能反而更差。同时要避免把 hot key 聚到一个分片里,否则会出现单分片过热问题。
-- 分片规则示例:按 user_id 取模分 32 片 -- 分片编号 = user_id % 32 SELECT * FROM order_0 WHERE user_id = 10086;还有一个问题是:如果查询条件里没有分片键怎么办?常见的兜底方案是建立映射关系表,把 order_id 和 user_id 的对应关系单独存起来,二次查询时先查映射表得到 user_id,再定位分片。这通方案会增加一次查询,但能解决"查询不走分片键"的问题。
4.4 分库分表后的读扩散问题
分库分表后,最典型的问题是读扩散。比如后台需要按时间范围查订单,或者按商家 ID 查订单,这些查询都得遍历多个分片再聚合。
互联网公司常见的解法是引入异构数据同步,比如把分库分表后的数据通过 Canal 同步到 Elasticsearch,复杂查询走 ES,简单查询走分片。面试里能主动提到这个思路,说明你真正做过或者认真思考过系统的全链路设计。
4.5 分库分表专题小结论
分库分表的面试题,核心考察的是分片策略、分片键选择、查询路由和数据迁移这四件事。答案不需要多花哨,但一定要能解释清楚:为什么选这个分片键、扩容时数据怎么迁移、查询不带上分片键时系统怎么兜底。
5. 分布式 ID 专题:雪花算法不只是背个公式
分布式 ID 几乎是分库分表的必带题目,因为分表之后数据库自增主键就失效了,必须要有全局唯一的 ID 生成方案。
5.1 分布式 ID 的核心要求
一个合格的分布式 ID 方案要满足这几个要求:
- 全局唯一,这是底线。
- 趋势递增,对数据库索引友好,能减少页分裂。
- 高性能,生成 ID 不能成为系统的性能瓶颈。
- 高可用,生成服务不能单点。
注意是"趋势递增"而不是"严格递增"。严格递增意味着所有生成请求要排队,分布式环境下几乎不可能做到;趋势递增只需要整体趋势上涨,允许个别 ID 略小,这已经能满足索引需求。
5.2 常见方案对比
数据库自增 ID 在老系统里很常见,但一旦分表就会冲突,而且每次生成都要一次 DB 操作,性能有限。
Redis INCR 命令可以生成递增 ID,性能不错,但要注意 Redis 持久化丢失可能导致 ID 重复,并且要维护 Redis 集群的可用性。
UUID 是最简单的方案,但生成的 ID 是字符串、无序的,作为主键时索引性能差,而且存储空间占用大。
雪花算法(Snowflake)是当前最主流的方案。
5.3 雪花算法:结构拆解与时钟回拨
雪花算法生成的 64 位 long 型 ID 通常由四部分组成:1 位符号位(固定 0),41 位时间戳,10 位工作机器 ID,12 位序列号。一毫秒内可以生成 4096 个 ID。
// 雪花算法核心生成逻辑(伪代码) long id = (timestamp - twEpoch) << 22 // 时间戳部分 | (workerId << 12) // 机器ID部分 | sequence; // 序列号部分雪花算法的最大隐患是时钟回拨。如果服务器时间被手动调回去,或者 NTP 同步导致时间回退,就可能生成重复 ID。
处理思路通常是:
- 如果回拨时间很短,允许等待,等时钟追上来。
- 如果回拨时间较长,可以临时改用 Redis 等其他方案生成 ID。
- 在集群层面做监控,及时发现时钟回拨。
面试里提到雪花算法不要只背公式,如果能说出"我们为了防止时钟回拨还做了备用 ID 生成链路",这道题就答出了深度。
5.4 分布式 ID 专题小结论
分布式 ID 的考察点看起来是"方案选型",实际上是"你看不看得到系统边界"。自增 ID 适合单机,UUID 适合对索引不敏感的场景,雪花算法适合大部分互联网业务,而真正好的方案往往不是某一个算法的模板,而是一个兜底链路。
6. Netty 专题:从 BIO 到 NIO 再到 Reactor 模型
Netty 在面试里通常有两种考法:一种是问"Netty 是什么、有什么用";另一种是让你手写一个 Echo Server,然后追问线程模型和粘包拆包。无论哪种,核心都绕不开IO 模型演进。
6.1 为什么高并发一定要 Netty
传统 BIO 模型下,一个连接一个线程,每个线程在等待 IO 时都会阻塞。连接数上来后,线程数量爆炸,上下文切换开销直线上升,系统扛不住。
NIO 模型引入了 Channel、Buffer、Selector,一个线程可以通过 Selector 管理多个 Channel 上的事件,只有在真正可读可写时才进行处理。这就把"一个线程服务一个连接"变成了"一个线程服务多个连接"。
Netty 是对 NIO 的更高层封装,它解决了 NIO 原生 API 太繁琐的问题,并且提供了更成熟的线程模型、编解码框架、粘包拆包方案和连接管理能力。
6.2 Reactor 线程模型是必考内容
Netty 的线程模型是 Reactor 模型的典型实现。主从 Reactor 模型中,Boss Group 负责接受连接,Worker Group 负责处理读写事件。一个 Boss 线程 accept 到连接后,把该连接注册到某个 Worker 线程的 Selector 上,后续这个连接上的 IO 事件都由同一个 Worker 线程处理。
Boss Group(接受连接) ↓ 注册 Worker Group(处理读写) ↓ 执行 Channel Handler(业务逻辑)这个模型的核心价值是:连接和读写解耦、每个连接上的事件处理天然串行、避免了并发安全问题。面试时能画出这条链路,再配合代码说清楚"为什么一个 Channel 上的操作不需要加锁",比单纯背概念有用得多。
6.3 Netty 服务端最小可运行代码
下面是一个基于 Netty 的 Echo Server 核心代码,通常用来做面试手写题的基础模板。
// 文件路径:src/main/java/com/example/netty/EchoServer.java public class EchoServer { public static void main(String[] args) throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) { ch.pipeline().addLast(new EchoServerHandler()); } }); ChannelFuture future = bootstrap.bind(8080).sync(); future.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } }// 文件路径:src/main/java/com/example/netty/EchoServerHandler.java public class EchoServerHandler extends SimpleChannelInboundHandler<ByteBuf> { @Override protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) { ctx.writeAndFlush(msg.retain()); } }Netty 的面试题中还有一个高频考点是粘包拆包。TCP 是流式协议,没有消息边界,多个消息可能粘在一起(粘包),一个大消息也可能被拆成多段(拆包)。Netty 提供了多种解码器解决这个问题,比如 LineBasedFrameDecoder(换行符)、DelimiterBasedFrameDecoder(自定义分隔符)、FixedLengthFrameDecoder(固定长度),以及最常用的 LengthFieldBasedFrameDecoder(长度字段)。
// 基于长度字段的拆包配置 pipeline.addLast(new LengthFieldBasedFrameDecoder( 1024, 0, 4, 0, 4));这段配置的含义是:最大帧长度 1024 字节,长度字段从第 0 个字节开始、占 4 字节,长度字段和实际数据之间的偏移为 0,解码后丢弃长度字段前的 4 个字节。这是实际项目中最常见的拆包方式之一。
6.4 Netty 专题小结论
Netty 相关的面试题,背后的主线是:高并发 IO 场景下,如何用有限的线程处理海量的连接。回答时先讲清楚 BIO 到 NIO 的演进,再画 Reator 线程模型,最后落到粘包拆包、心跳机制、断线重连这些工程细节,基本就能覆盖大多数追问方向。
7. 分布式其他高频问题:一致性、幂等与分布式会话
除了上面六大专题,还有一些高频旁支问题经常在面试中被穿插提问,这里一起梳理掉。
7.1 缓存一致性:Cache Aside 模式还是双删
缓存与数据库的一致性是必问题。最常用的方案是 Cache Aside 模式:读的时候先读缓存,缓存没有则读数据库,然后回填缓存;写的时候先更新数据库,再删除缓存。
为什么是"删除缓存"而不是"更新缓存"?因为更新缓存存在并发问题:两个线程并发写数据库,后写的缓存可能被先写的线程覆盖。而删除缓存后,下一次读会触发回填,得到的是最新值。
但是这个方案还有一个经典问题:先删缓存再更新数据库会造成短暂的不一致。推荐的顺序是先更新数据库,再删除缓存。如果有极端一致性要求的场景,可以在删除缓存失败时利用消息队列重试,或者使用订阅数据库 binlog 的方式异步刷新缓存。
7.2 幂等性问题:接口要能重复调用
分布式系统中,网络超时会导致客户端重试,重试就意味着同一个请求可能被执行多次。如果接口没有幂等设计,就会出现重复下单、重复扣款。
幂等的常见实现方式有:
- 唯一键约束:靠数据库唯一索引兜底,这是最可靠的方案。
- 状态机:订单只能从"待支付"到"已支付",状态变化是单向的,重复请求无法产生无效流转。
- 分布式锁或 Redis SETNX:在请求处理前加锁,重复请求直接拒绝。
面试中如果能举一个真实的例子并被追问"如果加锁之后业务执行异常了怎么办",然后回答"锁要有过期时间,业务要要有补偿机制",这个问题就闭环了。
7.3 分布式会话:Session 不再跟着单机走
单体应用中 Session 存在单台服务器内存里,但分布式架构下同一个用户的请求可能被负载均衡到不同节点,Session 就丢了。
常见方案有三种:
- Session 复制:节点间同步 Session,简单但传输量大。
- Session 黏滞(Sticky Session):同一个用户的请求发到同一台机器,实现简单但失去了负载均衡弹性。
- 集中式 Session:把 Session 存到 Redis,所有节点共享,这也是当前最主流的方案。
// 基于 Redis 的分布式 Session 存储思路 // 将 Session 数据序列化后写入 Redis,key 为 sessionId redisTemplate.opsForValue().set("session:" + sessionId, sessionData, Duration.ofMinutes(30));现在很多新项目直接用 JWT 这类无状态 Token 替代 Session,服务端不保存会话状态,配合 Redis 做黑名单控制,已经逐渐成为主流方案。面试里对比这两种方案的适用场景,比单方面吹其中一个更有说服力。
8. 一套可复用的面试复习路径
题刷得再多,面试时还是要回到"能不能讲成一个完整的故事"。
这里给出一条比较高效的复习路径,适合在准备周期 2 到 4 周内执行:
第一周,先把分布式基础补齐。重点看 CAP、BASE、一致性哈希、RPC 和注册中心的基本原理。这些是串联其他专题的地基,基础不牢,后面每个专题都容易答得飘。
第二周,主攻数据一致性专题。把 Redis 分布式锁、Zookeeper 锁、分布式事务的 2PC/TCC/事务消息/Seata 选型全部过一遍,并整理出自己项目里可以用到的对应场景。
第三周,攻克高并发扩展专题。分库分表的分片策略和分片键选择、分布式 ID 的雪花算法、Netty 的线程模型和粘包拆包,这些题目偏重设计,需要多画画图、多写写伪代码。
第四周,回归项目本身。没有项目支撑的分布式知识是空中楼阁。把每一道题的答案套进自己真实做过的模块里,哪怕只是设计过、没有完全落地,也要能说出"为什么这么设计、有什么取舍、如果数据量再翻十倍怎么改"。
另外建议大家准备时多做一件事:把每个专题整理出一个 200 字左右的纯口语化答案。面试官其实不喜欢你背官方定义,更愿意听到你用大白话把原理讲明白。
9. 这份 65 问清单的正确打开方式
如果你手里已经有一份"分布式面试 65 问"之类的清单,建议不要从头到尾背一遍。更有效的用法是:先把问题按本文的六大专题分类,再给每道题打一个标签——基础题、原理题、场景题、深挖题。
基础题用一句话能说清楚的就不要展开;原理题要能画出流程图;场景题必须结合自己的项目经历准备;深挖题则是面试官用来区分"背题"和"真懂"的关键,值得多花时间推敲。
面试的真相是:大部分题目不是要你给出标准答案,而是要验证你有没有真实的分布式系统设计思维。不管是 Netty 的技术选型、分布式锁的可靠性权衡,还是分库分表的分片键设计,背后都在考察一件事:面对不确定性,你能不能通过合理的技术手段把风险控制住。
这份"65 问"覆盖的面已经很全了,但真正的价值不在于题目数量,而在于你能不能把散落的题目串成一个系统。按本文这条主线去梳理一次,把每一个专题都落到自己的项目和真实场景里,你会在面试中比大多数人多一份从容。