系统设计面试模板:从需求到架构
系统设计面试的通用框架
系统设计面试考察的是你将模糊需求转化为可扩展架构的能力。掌握一套可复用的思维模板,能帮助你从容应对大多数设计题目。下面这个模板涵盖了从需求分析到最终架构的完整流程,每一步都有明确的产出物。
第一步:需求澄清 (5分钟)
不要一上来就画图。先通过提问把模糊的问题收敛成一个边界清晰的设计任务。
关键问题清单
- 核心功能:用户能用这个系统做什么?(列出3-5个最关键的功能)
- 非功能需求:对延迟、可用性、一致性的要求有多高?(例如:读延迟 < 200ms,99.9% 可用)
- 用户规模与流量:日活用户多少?读写比例大概是多少?
- 数据特征:数据增长速度如何?存储保留多久?是否有文件/图片等非结构化数据?
- 客户端类型:需要支持Web、App还是第三方API?
产出物:一份简洁的功能与非功能需求列表,以及明确的量级假设(例如 DAU 1000万,写 QPS 5000)。
第二步:资源估算 (5分钟)
利用前一步的量级假设快速估算关键资源指标。目的不是给出精确数字,而是让架构决策有数据支撑。
必须估算的数值
- 存储容量:每日新增数据 × 保留天数 × 副本系数 × 1.5(预留缓冲)
- 带宽/流量:日均请求数 × 平均请求大小 / 86400(粗略估算峰值QPS)
- 读/写 QPS:根据日活和读写比例推算(例如读QPS = 日活×平均每人读请求数/86400)
简易换算参考
| 指标 | 示例计算 |
|---|---|
| 日活1亿用户 | 读 QPS 约 10万-50万级别 |
| 1TB 存储/天 | 保留30天 ≈ 30TB |
| 每请求1KB | 1百万QPS ≈ 1GB/s 带宽 |
如果估算出的存储/流量远超单机能力,那么分区、缓存、CDN就成了必选项。
产出物:记录 QPS、存储容量、带宽峰值几个关键数字,后续设计会反复用到。
第三步:定义 API (5分钟)
根据第一步的功能列表,粗略定义核心的REST或RPC接口。不需要写出完整文档,只定义端点即可。
示例:设计一个简化版 Twitter
POST /tweets // 发推
GET /timeline // 获取首页时间线
POST /follow // 关注用户
GET /users/:id // 获取用户信息
注意
- 标明哪些是写操作,哪些是读操作(对应后续的数据模型和缓存策略)
- 如果涉及文件上传/下载,注明是否走专门的存储接口(如 AWS S3)
产出物:3-5个核心API端点,及简要的参数说明。
第四步:数据模型设计 (5-10分钟)
根据API和查询模式,设计数据库表结构或NoSQL数据模型。选择 SQL 还是 NoSQL 要明确说清理由。
决策原则
- 关系型数据、强一致性、复杂查询 → SQL (PostgreSQL, MySQL)
- 海量数据、无复杂关联、需要高写入吞吐 → NoSQL (Cassandra, DynamoDB)
- 社交关系、关注/粉丝 → 图数据库 (Neo4j) 或基于列的存储
- 非结构化文件 → 对象存储 (S3)
必须考虑的读/写模式
- 发一条推,写表一次,同时可能要更新粉丝的时间线(推模式/拉模式)
- 读取时间线是高并发场景,可能需要冗余存储或缓存
产出物:简要的ER图或表结构(用文字描述即可),例如:
用户表: id, username, created_at
推文表: id, user_id, content, created_at
关注表: follower_id, followee_id
时间线表: user_id, tweet_id, timestamp (如果采用推模式)
第五步:高层架构设计 (10分钟)
画出系统的方块图。从客户端开始,逐层展开,明确每个组件的作用和数据流。
标准分层
客户端 → CDN/DNS → 负载均衡器 → API 网关 → 应用服务器 → 缓存层 → 数据库 → 文件存储/消息队列。
画出关键路径
- 对于读密集型请求:可以引入 Redis 缓存、Memcached、CDN
- 对于写密集型请求:使用消息队列(Kafka)削峰,异步处理
- 对于有状态连接:考虑 WebSocket 或长轮询
不要在第一步就引入复杂组件。先给出一个最简单的可行架构,然后和面试官讨论瓶颈点,再逐步演进。
产出物:一张高层架构白板图(用文字描述),标明数据流向、组件间的通信协议。
第六步:核心功能深挖 (10-15分钟)
选取1-2个最复杂的功能点深入设计,展示你处理细节和权衡的能力。
常见深挖方向
- 如何生成唯一ID? 雪花算法、UUID、数据库自增 vs 分布式ID生成器
- 如何实现高并发的 Feed 流? 推模式 vs 拉模式 vs 推拉结合,粉丝数多的处理
- 如何实现分布式缓存一致性? 旁路缓存、写穿/写回,失效策略
- 如何保证数据不丢失? 主从复制、WAL、Kafka持久化
- 如何做全文搜索? Elasticsearch 索引构建,数据同步管道
表述技巧
- 先说“简单方案”,再指出在高并发下的瓶颈
- 再说“改进方案”,解释引入新组件的代价和收益
- 最后总结:“我倾向于方案X,因为它在Y场景下更优,代价是可以接受的”
产出物:对选定功能的设计决策树,包括备选方案和最终选型。
第七步:扩展性与故障处理 (5分钟)
说完理想状态后,主动讨论系统如何应对增长和故障。这部分体现你的运维意识。
扩展策略
- 垂直扩展 vs 水平扩展:业务初期垂直,后期水平分片
- 数据库分片:按用户ID分片,一致性哈希,分片键选择
- 缓存扩展:Redis Cluster,分片,一致性哈希
- 无状态服务:便于横向扩展,只需加机器
故障处理
- 单点故障消除:负载均衡器/数据库/缓存都需冗余
- 熔断与降级:(Sentinel/Hystrix)在某个服务不可用时,返回兜底数据
- 限流:令牌桶/漏桶算法,防止突发流量打垮系统
- 监控与告警:哪些指标最关键?QPS、延迟、错误率、服务器负载
产出物:一张标注了扩展点和容错机制的架构图(补充文字说明)。
第八步:总结与回顾 (2分钟)
用30秒快速回顾整个设计,从需求到瓶颈再到解决方案,让面试官看到你全局视角。
黄金结构
- 重申核心需求
- 简要复述架构:用了哪些组件
- 点出1-2个关键权衡点,以及为什么这样取舍
- 如果时间充裕,提一句未来优化方向(就像代码TODO)
模板速查卡片
| 步骤 | 时间(总45分钟) | 关键动作 |
|---|---|---|
| 需求澄清 | 5min | 确认功能/非功能,亮出假设 |
| 资源估算 | 5min | 算存储、QPS、带宽 |
| API设计 | 5min | 列出核心端点 |
| 数据模型 | 5-10min | 选存储,画表结构 |
| 高层架构 | 10min | 方块图,数据流 |
| 核心深挖 | 10-15min | 1-2个功能点,讨论权衡 |
| 扩展与容错 | 5min | 水平扩展、故障方案 |
| 总结回顾 | 2min | 全局复盘 |
真实面试不会严格按钟表划分,但始终保持这个节奏会显得专业且条理清晰。多用“假设”、“对于这个场景”、“这里有一个权衡”等表述,展现工程思维。