高并发与系统设计题库

这部分是综合技术面、技术总监面特别容易问的。

重点不是背“高并发三板斧”,而是要让对方感觉你真的做过:

  • 高峰流量
  • 长链路
  • 并发冲突
  • 报表与查询压力
  • 状态一致性
  • 超时关闭、补偿、回调治理

一、高并发系统你先看什么

你可以直接答

我一般先看 5 件事:

  1. 哪个环节最吃资源
  2. 读多还是写多
  3. 是否可以异步化
  4. 是否存在热点
  5. 一致性要求是强一致还是最终一致

二、高并发常见手段

  • 缓存
  • 异步解耦
  • 限流
  • 降级
  • 批处理
  • 读写分离
  • 水平扩展
  • 幂等控制
  • 热点隔离

三、为什么要做异步解耦

很多链路不适合同步串到底。同步链路越长,延迟越大,失败点越多,高峰期也越容易被拖垮。

结合你的项目怎么讲

在推广 ROI 线里,点击处理、归因、回传、报表更新不适合都放在同步接口里,所以通过 Kafka 解耦,把可延迟处理的逻辑拆出去。

四、如何设计订单超时关闭

如果量小,可以扫订单表;如果量大,不应该全表扫描,而应该把超时事件独立出来,比如延迟队列、Redis ZSet、时间轮等。

真正关闭时,要通过状态机和条件更新保证幂等,只允许待支付订单关闭,防止和支付回调并发冲突。

五、如何防止重复消费

消息系统里重复消费是常态,不是异常。

解决方式一般是:

  • 定义唯一业务键
  • Redis / DB 做幂等控制
  • 消费逻辑本身做状态判断
  • 失败可重试,但重复不能打乱状态

六、如何处理热点 key / 热点请求

  • 本地缓存 + Redis 多级缓存
  • 热点隔离
  • 限流
  • 异步削峰
  • 拆分热点

七、缓存和数据库一致性怎么做

  • 先更新数据库,再删缓存
  • 延迟双删
  • 通过订阅 / binlog 异步刷新

更稳的说法

缓存一致性没有万能方案,要看业务能容忍多大的短暂不一致。交易和支付状态这种敏感数据,我会更谨慎,不会过度依赖缓存。

八、报表查询慢怎么处理

  • 区分业务主库和分析库
  • 不要把分析型查询长期压在 MySQL 主库上
  • 把聚合和统计拆到 ClickHouse / 数仓

九、如果接口慢,你怎么排查

我一般按链路拆:

  1. 网关 / 接入层
  2. 应用层
  3. 数据库
  4. 缓存
  5. 外部依赖
  6. 消息积压

十、系统设计题:如何设计一个秒杀系统

建议按这个顺序答:

  1. 限流
  2. 库存预扣
  3. 异步下单
  4. 去重和幂等
  5. 热点隔离
  6. 最终一致性

十一、系统设计题:如何设计 AI 对话服务

  1. 网关层鉴权
  2. 会话服务管理上下文
  3. Prompt / 工具编排层
  4. 模型调用层
  5. 流式返回层
  6. 日志、审计、限流、配额
  7. 缓存和降级

十二、系统设计题:如何做高可用

  • 无单点
  • 超时和重试
  • 限流和熔断
  • 降级
  • 健康检查
  • 日志、监控、告警
  • 灰度和回滚

十三、技术总监最容易追问你的点

1. 你做过的最复杂并发问题是什么

支付状态并发、回调重入、消息重复消费、点击回传链路高峰都可以讲。

2. 报表为什么慢,为什么不用继续优化 MySQL

因为本质是分析型查询,不是事务型查询,继续压在主库上收益很差。

3. 你如何平衡一致性和性能

核心链路保强一致,扩展链路尽量最终一致;不是所有动作都要一个大事务包住。

十四、支付回调、退款、恢复订阅怎么保证状态一致

这是非常适合你发挥的一题,因为它能把支付、订阅、幂等、状态机、补偿和系统设计一起讲出来。

推荐回答

我不会只用一个 status 字段去承接所有语义,而是先拆:

  • 支付状态
  • 订阅状态
  • 用户权益状态

然后把购买成功、退款、恢复订阅、续订失败、回调重试这些入口统一收敛到一套状态处理逻辑里。

真正做稳通常要几层一起上:

  • 事件唯一键去重
  • 数据库事务
  • 状态机限制非法流转
  • 关键副作用二次幂等
  • 定时对账 / 补偿任务兜底

面试里一句更稳的说法

这类系统难的不是接上回调,而是同一笔业务会被多个异步事件反复改。我会先统一状态模型,再用幂等、状态机和补偿把乱序、重试和重复通知兜住。

十五、分布式锁和数据库幂等怎么配合

很多人会把这两个东西混在一起,其实它们解决的问题不一样。

推荐回答

  • 分布式锁解决的是:同一时刻别让多个 worker 并发改同一个资源
  • 数据库幂等解决的是:同一个事件今天、明天、下周重试过来都别重复生效

真正稳的方案一般是:

  1. 先拿事件唯一键落库
  2. 用数据库唯一索引做第一层去重
  3. 需要时再加分布式锁串行化同一资源
  4. 事务里更新主状态和副作用

面试里怎么说更像做过

我不会把 Redis 锁讲成万能。锁更多解决并发,真正能抗历史重试的主防线还是数据库唯一键、事务和状态机。

十六、什么时候该上领域设计

高并发和系统设计不只是组件堆叠,很多时候真正难的是业务边界没拆清楚。

推荐回答

如果系统已经进入下面这些阶段,我会考虑领域设计:

  • 状态很多,而且经常跨模块互相影响
  • 同一个业务词在不同团队里理解不一致
  • controller、job、listener 里开始反复出现同一套规则
  • 代码越来越像“到处补判断”,而不是在稳定模型上演进

这时我会重新梳理:

  • 哪些是核心实体
  • 哪些只是值对象
  • 哪些对象必须一起保持一致
  • 哪些规则应该归到领域服务

更直白的面试说法

如果业务还只是 CRUD,我不会强上 DDD;但如果已经是支付、退款、订阅、审批、库存这种复杂规则系统,我会用领域边界来约束代码演进。

十七、你最适合背的总结句

我做高并发和系统设计时,重点不是先上什么组件,而是先看链路、数据类型和一致性要求,再决定哪些地方用缓存、哪些地方异步、哪些地方需要状态机、幂等和补偿。像支付、订阅、回调、推广回传、报表分析这些场景,我更习惯先把问题拆层,再做方案,而不是直接堆技术。