---
name: system-design
description: 系统设计通用方法出题：需求澄清与容量估算、存储选型、扩展性与分片、一致性与幂等、容错与降级。二面、架构面以及后端/全栈/基础架构岗位加载。
keywords: [系统设计, 架构设计, 高并发, 容量估算, 分布式, 一致性, 缓存, 消息队列, 限流, 容错, system design, architecture, 后端, 基础架构, 全栈]
layer: base
---

## 岗位职责与考察重点

系统设计题在国内一线互联网公司通常出现在二面或三面，形式是给一个业务场景（短链、秒杀、feed、IM、点赞计数、订单超时关闭、分布式 ID），让候选人从零设计并接受连续追问；外企的 system design round 更强调候选人主导流程：澄清需求、估算规模、画出高层设计、深入一两个组件、讨论权衡与失败模式。面试官真正评估的不是画出的架构图有多完整，而是候选人能否把每一个组件的存在理由说清楚，能否在被追问"如果 X 变了"时调整方案而不是崩溃。

校招候选人的系统设计题会明显降低复杂度：问的是"为什么要有缓存、为什么要有队列、怎么保证不超卖"这种单点决策，以及能否用估算把"高并发"变成具体的数字；社招则要求完整的取舍能力：CAP 层面的选择、数据分片键的确定、跨服务一致性的处理、灰度与回滚、成本。

面试官最在意三件事：第一，先问清楚再设计——不问规模、读写比、一致性要求就直接上架构图的候选人几乎必然得低分；第二，数字感——能把"千万用户"翻译成 QPS、存储量、带宽，并据此判断需不需要分片、需不需要缓存；第三，失败模式——每一个组件挂了系统会怎样，数据会不会丢、会不会重、会不会不一致，候选人有没有想过。

## 主题

### 需求澄清与范围界定
- 阶梯：让候选人列出该问什么 → 功能需求与非功能需求（延迟、可用性、一致性）的区分 → 哪些需求互相冲突、怎么排优先级 → 面试官故意改一个约束，看方案怎么变
- 好题：设计一个短链服务，在动手之前你需要问我哪些问题？我现在告诉你日均 1 亿次跳转、写读比 1:100、允许 1 秒内的短链不可用，你的设计里哪些部分会因此简化？
- 危险信号：不问任何问题直接画图；把所有需求都当成必须满足；说不出功能需求与非功能需求的区别。
- 期望信号：先问规模、读写比、延迟与一致性要求；能识别关键约束；主动声明假设并请面试官确认。

### 容量估算
- 阶梯：日活转换成 QPS 的方法 → 峰值与均值的倍数、存储量的推算 → 用估算结果决定单机能否扛住、需不需要分片 → 估算偏差一个量级时设计是否仍然成立
- 好题：一个 5000 万日活的 feed 系统，平均每人每天刷 20 次、每次拉 10 条、每条 1KB，请估算读 QPS、峰值带宽和三年存储量，并据此说明数据库要不要分片、缓存要多大。
- 危险信号：不会把日活转成 QPS；估算完不回到设计决策；数量级错误却没有察觉（比如算出单机需要 10TB 内存仍然不改方案）。
- 期望信号：估算过程有假设、有单位换算；能说出峰值倍数的依据；估算结果直接驱动分片、缓存、异步化的决策。

### 存储选型
- 阶梯：关系型和 NoSQL 的适用场景 → 按访问模式选存储（点查、范围、全文、时序、图） → 一个业务里为什么会同时用多种存储、数据怎么同步 → 选错存储的代价与迁移路径
- 好题：一个 IM 系统的消息表，写多读少、按会话拉取最近 N 条、需要保留三年，你会选 MySQL、Cassandra/HBase 还是别的？分区键怎么设？为什么？
- 危险信号：所有场景都选 MySQL 或都选 MongoDB；说不出访问模式和存储结构的关系；把"NoSQL 快"当理由。
- 期望信号：从访问模式和数据模型出发；能说出各存储的写放大、读放大或一致性代价；知道多存储共存时的同步方案。

### 缓存策略
- 阶梯：为什么要缓存、放哪一层 → 缓存与数据库的一致性策略（cache-aside、write-through、延迟双删） → 穿透、击穿、雪崩各怎么防，热 key 怎么发现与处理 → 缓存命中率多少以下就不值得
- 好题：点赞数用 Redis 计数、异步落库，一个大 V 的帖子突然爆了导致单个 key 的 QPS 超过单节点上限，你怎么发现、怎么处理？处理后的数据一致性如何保证？
- 危险信号：只会背"三个雪崩"名词；一致性策略只有"先删缓存再更新数据库"却说不出竞态；对热 key 没有任何思路。
- 期望信号：能说出一致性策略的失败窗口；有本地缓存加多级缓存的热 key 方案；知道缓存监控指标；能评估缓存引入的复杂度。

### 数据分片与扩展性
- 阶梯：单库单表的上限在哪 → 分片键怎么选、为什么 → 跨分片查询、跨分片事务、热点分片怎么办 → 扩容时数据怎么迁移、一致性哈希与范围分片的取舍
- 好题：订单表按用户 ID 分片后，商家后台需要按商家 ID 查所有订单，你怎么解决？如果再加一个"按时间范围查全站订单"的需求呢？
- 危险信号：分片键随手选主键 ID；对跨分片查询的回答只有"用 ES"；不知道扩容需要迁移数据。
- 期望信号：分片键从查询模式反推；有异构索引表或冗余写的方案；能说出扩容方案与双写迁移的步骤。

### 一致性与幂等
- 阶梯：强一致、最终一致分别适用什么场景 → 幂等的实现手段（唯一键、状态机、去重表、token） → 跨服务写操作的一致性方案（本地消息表、事务消息、Saga、TCC）与各自失败点 → 什么时候该放弃分布式事务用对账兜底
- 好题：支付回调可能重复到达、也可能乱序到达（先退款后支付成功），你的订单状态机怎么设计？幂等键放在哪一层？对账系统的作用是什么？
- 危险信号：所有跨服务写都答"用分布式事务框架"；幂等只说"加个唯一索引"不考虑乱序；不知道对账。
- 期望信号：能区分一致性等级并对应业务；幂等设计考虑并发与乱序；知道最终一致的补偿与人工介入路径。

### 消息队列与异步化
- 阶梯：为什么要引入队列、削峰和解耦分别指什么 → 消息丢失、重复、乱序的成因与对策 → 消费积压怎么发现与处理、死信怎么办 → 同步改异步后用户体验与可观测性的代价
- 好题：秒杀下单走队列异步落库，用户下单后看不到订单，你怎么设计让用户既能立即得到反馈又不丢单？消费端积压到十万条时你按什么顺序处理？
- 危险信号：把队列当万能解耦而不谈可靠性；不知道至少一次投递意味着必须幂等；积压只答"加消费者"。
- 期望信号：能说出投递语义与业务匹配；有积压监控与限流、扩容、丢弃策略；考虑了异步后的状态查询。

### 限流、降级与容错
- 阶梯：限流算法（固定窗口、滑动窗口、令牌桶、漏桶）的差异 → 限流放在网关还是服务、按什么维度 → 依赖服务超时或宕机时的熔断、降级、兜底数据 → 降级开关谁来拨、怎么防误伤核心链路
- 好题：你的服务依赖一个推荐接口，它的 p99 从 50ms 涨到 2 秒，你的线程池被拖垮，用户全部 504。你事前应该做什么、事中怎么止血、事后怎么改？
- 危险信号：只会背限流算法名；不知道超时应该短于调用方超时；降级方案是"返回错误"。
- 期望信号：超时、重试、熔断、隔离（线程池或信号量）成体系；有兜底数据方案；知道重试风暴与退避。

### 高可用与故障处理
- 阶梯：单点在哪、怎么消除 → 主从切换的数据丢失窗口与脑裂 → 一次机房故障时哪些功能可用、哪些不可用 → 多活的成本与一致性代价，什么业务值得做
- 好题：你的系统 MySQL 主库挂了，从切换到恢复用户会看到什么？切换期间的写请求怎么处理？如果切过去后发现有几秒数据丢了，业务上怎么补？
- 危险信号：高可用只说"部署多台"；不知道主从切换会丢数据；把多活当默认选项。
- 期望信号：能说出每个组件的故障模式和恢复时间；有数据丢失的业务补偿方案；对多活有成本认知。

### 分布式 ID 与延迟任务
- 阶梯：为什么不能用自增主键 → 雪花算法的位分配与时钟回拨、号段模式的双 buffer → 发号服务本身挂了怎么办 → 延迟任务（订单超时）用轮询、Redis ZSet、MQ 延迟消息的取舍
- 好题：订单 30 分钟未支付要自动关闭，日订单一千万，你会用数据库轮询、Redis 过期事件、还是延迟队列？每种方案在服务重启和任务丢失时表现如何？
- 危险信号：延迟任务只答"定时扫表"不考虑压力；不知道 Redis 过期事件不可靠；雪花算法说不出时钟回拨。
- 期望信号：方案按量级与可靠性要求选择；考虑了任务丢失与重复执行；发号有降级路径。

### 可观测性与上线
- 阶梯：新系统上线前要有什么监控 → 指标、日志、链路追踪各解决什么问题 → 一次"接口偶发超时"从哪些指标开始查 → 灰度发布怎么切流量、怎么定回滚标准
- 好题：你的新系统上线后，你会盯哪五个指标？其中哪一个先动通常意味着什么？灰度到 5% 时用什么标准决定继续还是回滚？
- 危险信号：监控只有"看日志"；说不出 SLO；上线方式是全量直接切。
- 期望信号：有 RED 或 USE 类指标体系；有告警阈值与 SLO；灰度有量化的推进与回滚标准。

### 完整场景推演
- 阶梯：给一个常见系统（短链、点赞、IM、秒杀、feed）要求完整设计 → 深入其中一个组件的读写路径 → 面试官注入一个故障或十倍流量看方案调整 → 讨论这个设计最先需要重构的地方
- 好题：设计一个 10 万人抢 10 件库存的秒杀：从前端到数据库你在每一层拦截多少流量、怎么保证不超卖、怎么保证一人一单、库存回滚怎么做？
- 危险信号：直接背出一张图但说不清每一层的存在理由；被注入故障后方案推倒重来；不知道自己设计的瓶颈在哪。
- 期望信号：分层漏斗有数字；每个组件有失败模式说明；能指出自己设计的下一个瓶颈与演进方向。

## 好题 / 坏题对比

- 坏：说说 CAP 理论。
- 好：你设计的订单系统在数据库主从切换的几秒里，写请求你选择拒绝还是接受？分别会带来什么后果？业务上怎么补？
- 坏：缓存雪崩、穿透、击穿是什么？
- 好：一个大 V 帖子的点赞 key 突然把单个 Redis 节点打满了，你怎么在五分钟内止血，之后怎么改架构让它不再发生？
- 坏：请设计一个高并发系统。
- 好：日均一亿次跳转的短链服务，写读比 1:100，请先估算 QPS 和存储量，再说明要不要分片、缓存放哪一层、301 还是 302。

## 项目结合钩子

- 简历出现"高并发""秒杀""抢购" → 追每一层拦截的流量数字、防超卖手段、幂等设计。
- 简历出现 Redis 缓存 → 追一致性策略的失败窗口、热 key 处理、命中率。
- 简历出现消息队列 → 追投递语义、消费幂等、积压处理与监控。
- 简历出现分库分表 → 追分片键选择依据、跨分片查询方案、扩容迁移步骤。
- 简历出现微服务 → 追服务边界划分依据、跨服务一致性方案、超时与熔断配置。
- 简历出现"高可用""99.9%" → 追单点在哪、主从切换的数据窗口、真实故障经历。
- 简历出现自研中间件或框架 → 追为什么不用现成的、设计的失败模式、被谁用过。

## 出题原则

- 系统设计题必须从需求澄清开始，候选人不问规模就动手时先不打断，之后用"如果流量是你假设的十分之一/十倍"检验其设计是否过度或不足。
- 每个组件都追问"去掉它会怎样"和"它挂了会怎样"，考存在理由与失败模式，不考画图完整度。
- 校招把题目降到单点决策与估算，重点看数字感与因果推理；社招必须涉及跨服务一致性、分片、故障恢复与成本取舍。
- 不考中间件的名词版本与配置项，考选型理由与替代方案；候选人用了不熟悉的中间件时允许其用自己熟悉的替代来讨论。
