系统设计面试:从准备到实战

最近参加了几个高级岗位的面试,系统设计是必考项。总结经验。

面试形式

通常 45 分钟:

阶段时间内容
需求澄清5 分钟理解问题
高层设计10 分钟核心架构
深入设计20 分钟关键组件
总结讨论10 分钟权衡、扩展

方法论:RESHADE

字母含义说明
RRequirements明确需求
EEstimation容量估算
SStorage存储设计
HHigh-level高层架构
AAPIs接口设计
DDeep dive深入细节
EEvaluation评估权衡

需求澄清

不要急着画图。先问清楚:

功能需求:
- 核心功能是什么?
- 用户是谁?
- 平台是什么(Web/App)?

非功能需求:
- 用户量级?
- 性能要求?
- 可用性要求?
- 一致性要求?

约束条件:
- 技术栈限制?
- 预算限制?

示例(设计 Twitter):

Q: 发推和读推哪个更重要?
A: 读推更重要

Q: 需要支持图片视频吗?
A: 支持

Q: 需要实时性吗?
A: 几秒延迟可接受

容量估算

计算模板

指标公式
QPSDAU × 每日操作次数 / 86400
存储写入 QPS × 单条大小 × 天数
带宽读 QPS × 单条大小

示例(设计 URL 短链接):

假设:
- 每月 1 亿新链接
- 每条链接 500 字节

写入 QPS = 100M / (30 × 86400) ≈ 40 QPS
峰值 QPS = 40 × 5 = 200 QPS

读 QPS = 写入 QPS × 100 = 4000 QPS
峰值读 QPS = 20000 QPS

存储:
每月 100M × 500B = 50GB
5 年 = 3TB

高层架构

画核心组件:

[客户端] → [负载均衡] → [API 服务器] → [数据库]

            [缓存]

关键问题:

问题考虑点
负载均衡L4 vs L7
数据库SQL vs NoSQL
缓存缓存策略
消息队列是否需要

存储设计

数据库选型

场景推荐
结构化数据、事务PostgreSQL / MySQL
文档存储MongoDB
键值存储Redis
时序数据TimescaleDB
搜索Elasticsearch

分片策略

用户 ID 分片:
- 好处:用户数据集中
- 问题:热点用户

时间分片:
- 好处:查询方便
- 问题:写入热点

哈希分片:
- 好处:均匀分布
- 问题:范围查询困难

接口设计

RESTful 风格:

POST /api/v1/urls
请求:{ "long_url": "https://..." }
响应:{ "short_url": "abc123" }

GET /api/v1/urls/{short_code}
响应:{ "long_url": "https://...", "clicks": 100 }

深入设计

选一个核心问题深入:

示例:短链接生成

方案一:自增 ID
- 简单
- 可预测、有泄露风险

方案二:哈希
- 快速
- 可能冲突

方案三:预生成
- 性能好
- 需要维护池

选择方案三并解释原因。

架构图示例

权衡讨论

没有完美方案,只有适合的方案:

选择优点缺点
SQL事务、成熟扩展性差
NoSQL灵活、扩展一致性弱
缓存一致性、成本
分片扩展复杂度

示例回答:

如果用户量继续增长,我会考虑对数据库进行分片。先按用户 ID 分片,因为读多写少,这样可以保证用户相关数据在同一分片,查询效率高。未来如果热点用户问题严重,可以引入缓存层或改用一致性哈希。

常见题型

类型示例
Web 应用设计微博、电商网站
服务平台设计 Uber、外卖平台
基础设施设计消息队列、缓存系统
特殊系统设计分布式 ID 生成器

准备建议

学习资源

资源说明
System Design PrimerGitHub 开源项目
Designing Data-Intensive Applications经典书籍
Grokking the System Design Interview课程

练习方法

  1. 自己设计:画图、写接口
  2. 看答案:对比差距
  3. 重做:不看答案再设计
  4. 讲出来:模拟面试

白板技巧

  • 从左到右画
  • 组件用方框
  • 数据流用箭头
  • 边画边说

总结

系统设计面试考的是:

  1. 分析问题的能力
  2. 系统思维的广度
  3. 权衡决策的深度
  4. 沟通表达的清晰度

不是找”正确答案”,是看思考过程。