Chapter 01

系统设计方法论

在混乱中建立秩序。掌握面试框架、需求分析与容量估算,
学会用工程师的方式拆解任何系统设计问题。

RESHADED 面试框架

系统设计面试没有标准答案,但有标准的思考流程。RESHADED 是业界广泛认可的面试框架,帮助你在45分钟内有条不紊地展示架构思维。

R — Requirements
需求分析:功能性需求(系统做什么)+ 非功能性需求(如何做好)。先问清楚,再动手设计。
E — Estimation
容量估算:估算 QPS、存储、带宽。确定系统规模,决定后续技术选型。
S — Storage Schema
数据模型:核心数据实体是什么,如何存储,关系型还是 NoSQL?
H — High-Level Design
高层架构:画出系统的主要模块和数据流,不深入细节,先把骨架立起来。
A — API Design
接口设计:定义核心 API,明确输入输出,澄清接口边界。
D — Deep Dive
深入细节:针对面试官最关心的模块深挖,展示技术深度。
E — Evaluate
评估权衡:主动分析你的方案有哪些优缺点,什么场景下会遇到瓶颈。
D — Distinctive
亮点展示:提出你的独到见解,监控方案、优化思路或替代方案。
▶ 面试要点

面试官最讨厌的是候选人埋头画图,不沟通。先问需求,再估算,边画边讲。沉默超过30秒就是信号——要么说出你在思考什么,要么向面试官确认方向。

需求分析:功能性 vs 非功能性

系统设计的第一步永远是搞清楚要做什么。需求分为两类,缺一不可:

功能性需求(Functional)

  • 系统的核心业务能力
  • 用户可以做什么操作
  • 数据的输入和输出是什么
  • 例:「用户可以上传图片」
  • 例:「系统生成短链接」

非功能性需求(Non-Functional)

  • 可用性:SLA 99.9% 还是 99.99%?
  • 延迟:P99 延迟要低于多少毫秒?
  • 规模:DAU(日活)是多少?
  • 一致性:强一致还是最终一致?
  • 耐久性:数据丢失容忍度?

提问模板:面试开场5分钟

// 设计一个 Instagram 这样的照片分享系统
// 你应该问的问题:

功能性需求澄清:
- 用户可以上传、查看、删除照片吗?
- 需要 Follow/粉丝 功能吗?
- 需要点赞、评论功能吗?
- 是否需要视频,还是仅图片?
- 需要搜索功能吗?

非功能性需求澄清:
- 预期 DAU 是多少?(假设1亿)
- 读写比例?(图片系统通常读多写少,100:1)
- 延迟要求?(Feed 加载 < 200ms)
- 可用性要求?(99.99%)
- 全球化还是单地区?

容量估算(Back-of-the-Envelope)

容量估算不是精确计算,是数量级判断。目的是判断你的方案能不能撑住流量,决定是否需要分布式、缓存、分片等方案。

常用数字速记

单位含义记忆技巧
1K1,000一千
1M1,000,000百万
1B1,000,000,000十亿
1 day~86,400 秒约 10万秒(粗估用)
1 month~2.6M 秒约260万秒
1 year~31.5M 秒约3000万秒
SSD 读速~500 MB/s 顺序随机读约 100μs
内存读速~10 GB/s约 100ns
网络往返同机房 <1ms跨洲 ~150ms

案例:估算 Twitter 的 QPS

日活用户(DAU):3亿 平均每用户每天发推:0.1 条(大多数是只读用户) 每用户每天读 Feed:50 次(刷新 Feed 页面) 写 QPS: 300M × 0.1 / 86400 ≈ 350 QPS(峰值 × 2 = 700 QPS) 读 QPS(Feed 请求): 300M × 50 / 86400 ≈ 174,000 QPS ≈ 175K QPS 结论:读写比 = 175,000 / 350 ≈ 500:1 → 这是典型的「读重型」系统,缓存优化是关键! 存储估算(推文文字,保留5年): 每天发推:300M × 0.1 = 30M 条 每条推文约 140B 文字 + 500B 元数据 ≈ 640B 每天存储:30M × 640B ≈ 20 GB/day 5年总量:20GB × 365 × 5 ≈ 36 TB (仅文字,图片/视频另算,通常是文字的100倍以上)
💡 估算技巧

不要追求精确,数量级对即可。峰值 = 平均值 × 2~3。内存比磁盘快100倍,磁盘比网络快10倍,跨数据中心比同机房慢100倍。这些比例关系记住即可做到快速判断。

设计权衡的思维方式

系统设计中没有"最好"的方案,只有"最合适"的方案。每个技术决策背后都是权衡(Trade-off)

维度Avs维度B典型取舍场景
一致性
Consistency
可用性
Availability
银行转账要一致性;社交 Feed 可接受最终一致
延迟
Latency
吞吐量
Throughput
批量写入提高吞吐但增加延迟
写入性能 读取性能 数据库索引牺牲写性能换读性能
存储成本 查询性能 反范式化存储冗余数据加速查询
开发简单 运维复杂度 微服务 vs 单体,没有绝对好坏
⚠ 常见误区

不要为了技术而技术。面试官最反感「我会用 Kafka + Kubernetes + 微服务来实现」——如果你的系统每天只有1000个用户,这些都是过度设计。先从简单方案出发,再说什么情况下需要扩展到复杂方案

如何画系统架构图

架构图是沟通工具,不是艺术品。重要的是清晰传达数据流向和系统边界

标准架构图元素

┌─────────────────────────────────────────────────────────┐ │ 系统边界 │ │ │ │ Client Load Balancer App Server │ │ ┌──────┐ ┌──────────┐ ┌──────────┐ │ │ │ Web │────────▶│ Nginx │────────▶│ Service │ │ │ │ App │ │ │ │ Instance │ │ │ └──────┘ └──────────┘ ┌───▶│ (x3) │ │ │ │ └──────────┘ │ │ │ │ │ │ Read │ Write│ │ │ │ ▼ │ │ ┌──────┴───┐ ┌──────────┐ │ │ │ Cache │ │ DB │ │ │ │ Redis │ │ Primary │ │ │ └──────────┘ └────┬─────┘ │ │ │Repl │ │ ┌────▼─────┐ │ │ │ DB │ │ │ │ Replica │ │ │ └──────────┘ │ └─────────────────────────────────────────────────────────┘ 图例说明: ────▶ 同步调用 / 数据流方向 ····▶ 异步调用 / 消息队列 ════▶ 外部系统调用 [ ] 数据库/存储 ( ) 缓存/临时存储

架构图绘制原则

  1. 从左到右:用户在左,存储在右,数据流从左向右
  2. 标注数量:写清楚几个实例,比如 「App Server ×3」
  3. 标注协议:HTTP/HTTPS/gRPC/TCP,让人知道通信方式
  4. 分组边界:用虚线框划分逻辑分区(如机房、VPC、服务组)
  5. 数据量标注:关键链路旁边标注 QPS 或数据量
ℹ 工具推荐

面试时用白板徒手画即可。日常工作推荐:draw.io(免费、离线可用)、Excalidraw(手绘风格、协作友好)、Mermaid(代码即图表、版本管理友好)。

完整的面试流程示例

面试官:「请设计一个 URL 短链接服务」 00:00-05:00 需求澄清 → 功能:生成短链、重定向、统计点击量 → 规模:每天1亿次生成,1000亿次重定向 → 延迟:重定向 <100ms → 可用性:99.99% → 短链有效期:默认永久,支持设置过期 05:00-10:00 容量估算 → 写 QPS:100M / 86400 ≈ 1200 QPS → 读 QPS:100B / 86400 ≈ 1.2M QPS,读写比 1000:1 → 存储(5年):100M × 365 × 5 = 1825亿条,约100TB 10:00-20:00 高层设计 → 画出:Client → CDN → LB → App Server → DB/Cache → 短链生成算法:Base62 编码 + 随机哈希 or 全局ID 20:00-35:00 深入关键模块 → 短链生成:如何保证唯一性(DB自增 or 分布式ID) → 重定向缓存:热门短链 Redis 缓存,命中率 99%+ → 存储选型:写少读多,关系型足够;超大规模用 NoSQL 35:00-40:00 权衡分析 → 方案A:DB自增ID + Base62,简单但单点瓶颈 → 方案B:分布式ID(Snowflake),高性能但复杂 → 选方案B,并说明原因 40:00-45:00 延伸讨论 → 如何防止恶意短链 → 全球化部署(多地区) → 统计数据如何做(异步写入时序数据库)