Skip to content

分布式场景面试高频问题汇总

分布式系统是面试的重头戏。

很多候选人能在简历上写「熟悉分布式系统」,但问到细节就卡壳了。

今天汇总分布式场景的面试高频问题,附上回答思路和追问方向。

问题一:如何保证缓存和数据库一致性?

回答思路

这道题考察的是 Cache Aside 模式的理解。

  1. Cache Aside 模式:读操作 Cache 命中返回,未命中查 DB 写 Cache;写操作先更新 DB,再删缓存(不是更新缓存)
  2. 为什么删而不是更新:删除代价小,避免脏写
  3. 可能的问题:并发情况下可能出现短暂不一致

关键要点

  • 读:Cache 命中 → 返回;未命中 → 查 DB → 写 Cache → 返回
  • 写:更新 DB → 删除 Cache(不是更新)
  • 不能先删 Cache 再更新 DB,会导致并发时缓存是旧值

可能的追问

  • 先更新 DB 还是先删 Cache?(答:先更新 DB,再删 Cache)
  • 延迟双删是什么?(答:删除 Cache 后延迟一段时间再删除一次,防止并发)
  • 能做到强一致吗?(答:不能,只能做到最终一致,强一致需要分布式事务)

问题二:分布式 Session 如何实现?

回答思路

考察的是对分布式 Session 方案的理解。

  1. Session 共享问题:单机 Session 无法跨机器共享
  2. Spring Session + Redis:将 Session 存储到 Redis
  3. 核心原理:Filter 拦截请求,替换 HttpSession 实现

关键要点

  • Session 存在 JVM 内存,集群环境下各节点不共享
  • Spring Session 通过 Filter 将 Session 存入 Redis
  • 使用 @EnableRedisHttpSession 开启

可能的追问

  • Session 数据序列化用什么?(答:推荐 JSON,避免 Java 序列化)
  • Session 过期时间和 Redis TTL 怎么保持一致?(答:Spring Session 自动同步)
  • Session 和 Token 哪个更好?(答:各有优劣,Session 有状态管理方便,Token 无状态扩展性好)

问题三:如何设计一个单点登录系统?

回答思路

考察的是对 CAS 原理的理解。

  1. SSO 定义:一次登录,多处访问
  2. CAS 流程:用户访问 A 系统 → 重定向到 CAS Server → 验证用户名密码 → 返回 ST → A 验证 ST
  3. 三个核心票据:TGT、TGC、ST

关键要点

  • CAS Server 统一认证,各系统验证 Ticket
  • ST 一次性使用,防止冒用
  • TGC 存在浏览器 Cookie,TGT 存在 CAS Server

可能的追问

  • CAS 和 OAuth2 的区别?(答:CAS 专注单点登录,OAuth2 支持授权)
  • CAS 如何实现登出?(答:销毁 TGT,各系统收到通知清除 Session)
  • CAS 的 ST 为什么设计成一次性的?(答:防止 ST 被截获后冒用)

问题四:如何实现接口幂等性?

回答思路

考察的是对幂等性实现的理解。

  1. 幂等性定义:多次执行结果一致
  2. 常用方案:Token 机制、唯一键、状态机
  3. Token 机制:提交前获取 Token,请求时携带 Token,服务端删除 Token

关键要点

  • 插入操作:唯一键冲突捕获
  • 更新操作:状态机 + 版本号
  • 删除操作:天然幂等
  • Token 机制:Redis 存储 Token,请求前获取,执行时校验并删除

可能的追问

  • POST 请求怎么幂等?(答:Token 机制)
  • 分布式锁能保证幂等吗?(答:能,但性能损耗大)
  • 消息队列消费怎么幂等?(答:消息 ID + 业务去重表)

问题五:如何设计一个分布式任务调度系统?

回答思路

考察的是对分布式任务调度的理解。

  1. 分片模式:大任务拆分为多个小任务并行处理
  2. 防重复执行:分布式锁 + 状态检查
  3. 任务框架:ElasticJob、XXL-JOB

关键要点

  • 分片策略:Hash 分片、范围分片
  • 分布式锁:保证同一时刻只有一个节点执行
  • 状态检查:乐观锁 + 状态更新

可能的追问

  • 任务失败了怎么办?(答:重试机制 + 失败告警)
  • 任务超时怎么处理?(答:超时监控 + 中断)
  • 广播模式和分片模式的区别?(答:广播所有节点都执行,分片每个节点执行一部分)

问题六:如何实现全链路限流?

回答思路

考察的是对分层限流的理解。

  1. 限流层次:网关层 → 应用层 → 资源层
  2. 限流算法:滑动窗口、令牌桶、漏桶
  3. Sentinel 限流:注解 + 规则配置

关键要点

  • 网关层:Nginx/Lua,限制总入口流量
  • 应用层:Sentinel/Hystrix,限制接口 QPS
  • 资源层:数据库连接池,限制数据库连接

可能的追问

  • 滑动窗口和令牌桶的区别?(答:滑动窗口统计一段时间内请求数,令牌桶按固定速率放行)
  • 限流后返回什么?(答:友好错误、兜底数据、排队)
  • Sentinel 和 Hystrix 的区别?(答:Sentinel 是滑动窗口,Hystrix 是滚动窗口)

问题七:如何设计一个异地多活架构?

回答思路

考察的是对单元化架构的理解。

  1. 单元化:每个地域是独立单元,自包含
  2. 流量路由:按用户 ID 或地域路由
  3. 数据同步:单元内强一致,单元间最终一致

关键要点

  • 单元内:分布式数据库,强一致
  • 单元间:异步复制,最终一致
  • 跨单元事务:TCC 或 Saga 模式

可能的追问

  • 单元化架构的核心思想是什么?(答:每个单元自包含,数据和流量隔离)
  • 如何处理跨单元事务?(答:TCC、Saga 或接受最终一致)
  • 同城双活和异地多活的区别?(答:同城延迟低,异地可应对城市级别灾难)

问题八:如何处理缓存穿透、击穿、雪崩?

回答思路

考察的是对缓存问题的全面理解。

  1. 穿透:查询不存在的数据 → 布隆过滤器
  2. 击穿:热点 key 过期 → 互斥锁 / 逻辑过期
  3. 雪崩:大量 key 同时过期 → 过期时间随机化 + 熔断降级

关键要点

  • 穿透:布隆过滤器快速判断 key 是否存在
  • 击穿:互斥锁保证只有一个线程查 DB,逻辑过期不阻塞
  • 雪崩:过期时间随机化 + 本地缓存兜底 + 熔断降级

可能的追问

  • 布隆过滤器为什么不能删除?(答:删除会影响其他 key 的判断)
  • 互斥锁和逻辑过期的区别?(答:互斥锁数据一致但有等待,逻辑过期无等待但可能返回脏数据)
  • 如何选择降级策略?(答:根据业务容忍度决定)

问题九:如何实现分布式链路追踪?

回答思路

考察的是对 TraceId 机制的理解。

  1. TraceId:请求链路的唯一标识
  2. SpanId:每一步的编号
  3. MDC:Logback 集成 TraceId

关键要点

  • TraceId 在网关生成,在整个链路中传递
  • HTTP Header / RPC RpcContext / MQ 消息 Header 传递
  • Logback MDC 将 TraceId 写入日志

可能的追问

  • TraceId 怎么生成?(答:UUID 或 Snowflake)
  • Skywalking 和 Zipkin 的区别?(答:Skywalking 功能更强,Zipkin 更轻量)
  • 如何在日志中看到 TraceId?(答:Logback MDC 配置)

问题十:如何设计一个分库分表方案?

回答思路

考察的是对分库分表的理解。

  1. 分片键选择:选择分布均匀的字段
  2. ID 生成:号段模式或雪花算法
  3. 分片中间件:ShardingSphere、MyCat

关键要点

  • 分片键:尽量选择 ID 或时间,避免热点
  • ID 生成:号段模式批量取,雪花算法不依赖外部
  • 分片后的问题:跨分片查询、分页

可能的追问

  • 雪花算法时钟回拨怎么办?(答:等待、使用上一个 Sequence)
  • 分库分表后如何做分页查询?(答:Scatter-Gather 并行查询所有分片)
  • 分库分表后如何做跨库 JOIN?(答:绑定表广播、单库内 JOIN)

总结

分布式场景的面试题,本质上考察的是:

  1. 对问题的理解:能不能说清楚问题的本质
  2. 对方案的理解:能不能说清楚方案的原理和取舍
  3. 对细节的掌握:能不能说出实现的关键点

背答案是没有用的,理解原理才是关键。

基于 VitePress 构建