← 返回思维链目录
系统设计权衡思维链
面试官让你设计一个系统,你脑子里怎么一步步想
1. 系统设计通用套路
现象
面试官:"设计一个短链系统"
别上来就画架构图,先想清楚再画。
本质:
系统设计不是"画多复杂的图",而是
展示你的思考过程
—— 怎么拆解问题、怎么做取舍。每个决策说清"为什么这么选、不选另一个会怎样"。
直觉:
先问清楚规模和需求,再估算,再选方案,最后考虑扩展和容灾。
🌊 六步走
① 澄清
先问清楚
:核心功能?用户量?读多写多?延迟?一致性要求?→ 别假设,要问
功能/非功能需求
读写比
延迟/一致性
② 估算
信封背面计算
:QPS?存储?带宽?→ 例:1 亿用户每天 10 次 → QPS ~1.2 万 → 决定要不要分库分表
QPS 估算
存储估算
峰值倍数
③ 建模
核心数据模型 + API
:有哪些表?对外什么接口?→ 例:短链 = {短码, 长URL, 时间} + 生成/跳转 API
数据模型
表设计
REST API
④ 架构
分层架构
:客户端→负载均衡→应用→数据→缓存/MQ → 画出来讲数据流向
负载均衡
无状态应用
读写分离
⑤ 难点
深入核心难点 + 权衡
:最难的是什么?(短链发号/秒杀防超卖/Feed 推拉)→ 给 2-3 方案,讲取舍
核心难点
方案对比
权衡取舍
⑥ 扩展
扩展 + 容灾
:流量翻 10 倍?(分库分表/微服务)→ 挂了?(主备/多机房/限流降级)
横向扩展
分库分表
高可用
关键:
每个决策说清"为什么这么选、不选另一个会怎样"。面试官想看你的
思考过程
,不是答案。
2. 短链系统
案例
设计 t.cn/xxx 短链系统
本质:
长 URL 变短码,核心是"发号"(唯一短码)+ 缓存(读多写少)+ 重定向(跳转)。
🌊 顺藤摸瓜
① 发号
长 URL 怎么变短码? → ①
哈希
(MD5 取前 6 位,有冲突);②
发号器
(自增 ID 转 62 进制,唯一不冲突)→ 推荐
哈希方案
发号器
Base62 编码
② 跳转
用户点短链 → 查库 →
301/302 重定向
→ 301 浏览器缓存(少查库)/ 302 每次统计点击
301 永久重定向
302 临时
点击统计
③ 缓存
读(跳转)远多于写(生成)→ 加
Redis 缓存
→ 短码→长URL,命中直接返回不查库
读写比悬殊
Redis 缓存
布隆过滤器
④ 扩展
数据量大了?→ 短码分库分表(哈希分片)→ 发号器分布式(
Snowflake 雪花 ID
)
分库分表
哈希分片
Snowflake
3. 秒杀系统
案例
100 件商品 10 万人抢
本质:
秒杀 = 瞬间高并发抢有限库存。核心是
让尽量少的请求碰到数据库
—— 限流挡住、缓存预减、异步削峰。
🌊 顺藤摸瓜
① 防超卖
"查库存-减库存"非原子 → 并发超卖 → ①
DB 乐观锁
(WHERE stock>0);②
Redis 原子扣减
(Lua DECR)
竞态条件
DB 乐观锁
Redis Lua
② 挡流量
10 万人不能全打 DB → 分层挡:① 前端
防抖+验证码
;②
CDN 静态页
;③
Nginx 限流
;④
Redis 预减库存
前端防抖
CDN
Nginx 限流
Redis 预减
③ 异步
抢到的下单慢 → 异步 →
MQ 削峰
(抢到=发消息,消费者慢慢下单)→ 用户看到"排队中"
MQ 异步削峰
消费者下单
最终一致
④ 防刷
黄牛脚本抢 → ①
限购
(用户ID+商品ID 唯一索引);②
风控
识别机器人;③ IP/设备限频
唯一索引防重
风控
设备指纹
三板斧:
限流(挡住)+ 缓存(预减)+ 异步(削峰)。
核心:让尽量少的请求碰到 DB。
4. Feed 流:推 vs 拉
案例
设计朋友圈 Feed 流
本质:
一条动态要让所有粉丝看到。核心是"发的时候推给粉丝"还是"粉丝来的时候去拉"。
🌊 顺藤摸瓜
① 推(写扩散)
发布时推到所有粉丝收件箱 → 读时直接读自己收件箱(快)→ 问题:
大 V 发一条推千万份,写放大
写扩散
读快
大 V 写放大
② 拉(读扩散)
发布只存自己主页,读时拉关注人最新 → 写快 → 问题:
关注人多,读时要合并很多源,慢
读扩散
写快
读时聚合慢
③ 混合
普通人用推(粉丝少),大 V 用拉(粉丝多)→
阈值切换
(粉丝 > N 走拉)→ 微博/微信都这么干
推拉结合
大 V 阈值
实际方案
5. CAP:为什么不能全都要
现象
分布式系统,一致性、可用性、分区容错为什么只能选两个?
本质:
网络一定会断(分区 P 必选)。断了之后,要么牺牲一致性保可用,要么牺牲可用性保一致,只能二选一。
🌊 顺藤摸瓜
① CAP
P(分区)必选 → 只能 CP 或 AP →
CP
(银行转账,宁可不可用也不能数据错)/
AP
(朋友圈点赞,可用优先,短暂不一致没事)
一致性 C
可用性 A
CP/AP 场景
② BASE
实际大多选 AP +
BASE
:基本可用 + 软状态 +
最终一致
→ 允许短暂不一致,但最终会一致
BASE
最终一致
柔性事务
总结
环节
脑子里想什么
澄清
多大规模?读多写多?延迟?一致性?
估算
QPS?存储?带宽?要不要分库分表?
建模
什么表?什么 API?
架构
负载均衡→应用→数据→缓存
难点
最难的是什么?给方案+权衡
扩展
流量翻 10 倍?挂了怎么办?
本质:
系统设计 = "先想清楚,再画图"。
没有完美方案,只有适合场景的权衡
—— 这才是系统设计的精髓。