高并发与系统设计题库
这部分是综合技术面、技术总监面特别容易问的。
重点不是背“高并发三板斧”,而是要让对方感觉你真的做过:
- 高峰流量
- 长链路
- 并发冲突
- 报表与查询压力
- 状态一致性
- 超时关闭、补偿、回调治理
一、高并发系统你先看什么
你可以直接答
我一般先看 5 件事:
- 哪个环节最吃资源
- 读多还是写多
- 是否可以异步化
- 是否存在热点
- 一致性要求是强一致还是最终一致
二、高并发常见手段
- 缓存
- 异步解耦
- 限流
- 降级
- 批处理
- 读写分离
- 水平扩展
- 幂等控制
- 热点隔离
三、为什么要做异步解耦
很多链路不适合同步串到底。同步链路越长,延迟越大,失败点越多,高峰期也越容易被拖垮。
结合你的项目怎么讲
在推广 ROI 线里,点击处理、归因、回传、报表更新不适合都放在同步接口里,所以通过 Kafka 解耦,把可延迟处理的逻辑拆出去。
四、如何设计订单超时关闭
如果量小,可以扫订单表;如果量大,不应该全表扫描,而应该把超时事件独立出来,比如延迟队列、Redis ZSet、时间轮等。
真正关闭时,要通过状态机和条件更新保证幂等,只允许待支付订单关闭,防止和支付回调并发冲突。
五、如何防止重复消费
消息系统里重复消费是常态,不是异常。
解决方式一般是:
- 定义唯一业务键
- Redis / DB 做幂等控制
- 消费逻辑本身做状态判断
- 失败可重试,但重复不能打乱状态
六、如何处理热点 key / 热点请求
- 本地缓存 + Redis 多级缓存
- 热点隔离
- 限流
- 异步削峰
- 拆分热点
七、缓存和数据库一致性怎么做
- 先更新数据库,再删缓存
- 延迟双删
- 通过订阅 / binlog 异步刷新
更稳的说法
缓存一致性没有万能方案,要看业务能容忍多大的短暂不一致。交易和支付状态这种敏感数据,我会更谨慎,不会过度依赖缓存。
八、报表查询慢怎么处理
- 区分业务主库和分析库
- 不要把分析型查询长期压在 MySQL 主库上
- 把聚合和统计拆到 ClickHouse / 数仓
九、如果接口慢,你怎么排查
我一般按链路拆:
- 网关 / 接入层
- 应用层
- 数据库
- 缓存
- 外部依赖
- 消息积压
十、系统设计题:如何设计一个秒杀系统
建议按这个顺序答:
- 限流
- 库存预扣
- 异步下单
- 去重和幂等
- 热点隔离
- 最终一致性
十一、系统设计题:如何设计 AI 对话服务
- 网关层鉴权
- 会话服务管理上下文
- Prompt / 工具编排层
- 模型调用层
- 流式返回层
- 日志、审计、限流、配额
- 缓存和降级
十二、系统设计题:如何做高可用
- 无单点
- 超时和重试
- 限流和熔断
- 降级
- 健康检查
- 日志、监控、告警
- 灰度和回滚
十三、技术总监最容易追问你的点
1. 你做过的最复杂并发问题是什么
支付状态并发、回调重入、消息重复消费、点击回传链路高峰都可以讲。
2. 报表为什么慢,为什么不用继续优化 MySQL
因为本质是分析型查询,不是事务型查询,继续压在主库上收益很差。
3. 你如何平衡一致性和性能
核心链路保强一致,扩展链路尽量最终一致;不是所有动作都要一个大事务包住。
十四、支付回调、退款、恢复订阅怎么保证状态一致
这是非常适合你发挥的一题,因为它能把支付、订阅、幂等、状态机、补偿和系统设计一起讲出来。
推荐回答
我不会只用一个 status 字段去承接所有语义,而是先拆:
- 支付状态
- 订阅状态
- 用户权益状态
然后把购买成功、退款、恢复订阅、续订失败、回调重试这些入口统一收敛到一套状态处理逻辑里。
真正做稳通常要几层一起上:
- 事件唯一键去重
- 数据库事务
- 状态机限制非法流转
- 关键副作用二次幂等
- 定时对账 / 补偿任务兜底
面试里一句更稳的说法
这类系统难的不是接上回调,而是同一笔业务会被多个异步事件反复改。我会先统一状态模型,再用幂等、状态机和补偿把乱序、重试和重复通知兜住。
十五、分布式锁和数据库幂等怎么配合
很多人会把这两个东西混在一起,其实它们解决的问题不一样。
推荐回答
- 分布式锁解决的是:同一时刻别让多个 worker 并发改同一个资源
- 数据库幂等解决的是:同一个事件今天、明天、下周重试过来都别重复生效
真正稳的方案一般是:
- 先拿事件唯一键落库
- 用数据库唯一索引做第一层去重
- 需要时再加分布式锁串行化同一资源
- 事务里更新主状态和副作用
面试里怎么说更像做过
我不会把 Redis 锁讲成万能。锁更多解决并发,真正能抗历史重试的主防线还是数据库唯一键、事务和状态机。
十六、什么时候该上领域设计
高并发和系统设计不只是组件堆叠,很多时候真正难的是业务边界没拆清楚。
推荐回答
如果系统已经进入下面这些阶段,我会考虑领域设计:
- 状态很多,而且经常跨模块互相影响
- 同一个业务词在不同团队里理解不一致
- controller、job、listener 里开始反复出现同一套规则
- 代码越来越像“到处补判断”,而不是在稳定模型上演进
这时我会重新梳理:
- 哪些是核心实体
- 哪些只是值对象
- 哪些对象必须一起保持一致
- 哪些规则应该归到领域服务
更直白的面试说法
如果业务还只是 CRUD,我不会强上 DDD;但如果已经是支付、退款、订阅、审批、库存这种复杂规则系统,我会用领域边界来约束代码演进。
十七、你最适合背的总结句
我做高并发和系统设计时,重点不是先上什么组件,而是先看链路、数据类型和一致性要求,再决定哪些地方用缓存、哪些地方异步、哪些地方需要状态机、幂等和补偿。像支付、订阅、回调、推广回传、报表分析这些场景,我更习惯先把问题拆层,再做方案,而不是直接堆技术。