系统设计面试:从准备到实战
最近参加了几个高级岗位的面试,系统设计是必考项。总结经验。
面试形式
通常 45 分钟:
| 阶段 | 时间 | 内容 |
|---|---|---|
| 需求澄清 | 5 分钟 | 理解问题 |
| 高层设计 | 10 分钟 | 核心架构 |
| 深入设计 | 20 分钟 | 关键组件 |
| 总结讨论 | 10 分钟 | 权衡、扩展 |
方法论:RESHADE
| 字母 | 含义 | 说明 |
|---|---|---|
| R | Requirements | 明确需求 |
| E | Estimation | 容量估算 |
| S | Storage | 存储设计 |
| H | High-level | 高层架构 |
| A | APIs | 接口设计 |
| D | Deep dive | 深入细节 |
| E | Evaluation | 评估权衡 |
需求澄清
不要急着画图。先问清楚:
功能需求:
- 核心功能是什么?
- 用户是谁?
- 平台是什么(Web/App)?
非功能需求:
- 用户量级?
- 性能要求?
- 可用性要求?
- 一致性要求?
约束条件:
- 技术栈限制?
- 预算限制?
示例(设计 Twitter):
Q: 发推和读推哪个更重要?
A: 读推更重要
Q: 需要支持图片视频吗?
A: 支持
Q: 需要实时性吗?
A: 几秒延迟可接受
容量估算
计算模板
| 指标 | 公式 |
|---|---|
| QPS | DAU × 每日操作次数 / 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 Primer | GitHub 开源项目 |
| Designing Data-Intensive Applications | 经典书籍 |
| Grokking the System Design Interview | 课程 |
练习方法
- 自己设计:画图、写接口
- 看答案:对比差距
- 重做:不看答案再设计
- 讲出来:模拟面试
白板技巧
- 从左到右画
- 组件用方框
- 数据流用箭头
- 边画边说
总结
系统设计面试考的是:
- 分析问题的能力
- 系统思维的广度
- 权衡决策的深度
- 沟通表达的清晰度
不是找”正确答案”,是看思考过程。