CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
系统设计入门/课时/综合练习
RawBlame
课时目录12 节

系统设计入门

  1. 01系统设计是什么
  2. 02性能与扩展基础
  3. 03一致性与 CAP
  4. 04负载均衡
  5. 05缓存模式
  6. 06异步与消息
  7. 07数据架构
  8. 08微服务与网关
  9. 09云设计模式
  10. 10可靠性模式
  11. 11性能反模式
  12. 12综合练习

综合练习

设计 CodeRoadMap 只读 API 的高可用架构草图。

40 分钟

综合练习

这一课你将能做到

  1. 独立完成一份完整系统设计答卷:「判题平台支撑 10 万日活」从澄清到深挖 45 分钟闭环
  2. 产出三阶段演进路线(现状 → 10× → 100×),每阶段写清改动、预期容量、代价与风险
  3. 用面试官的评分表给自己的设计打分,并完成一轮同伴互审

为什么要学

前 11 课的每个概念(估算、CAP、负载均衡、缓存、消息、分片、网关、云模式、可靠性、反模式)都是零件,这道综合题是把零件装成整机——面试就是这么考的,技术方案评审也是这么写的。

人话:学零件时你是修理工,这道题让你当总工程师。总工程师的标志不是会用所有零件,而是知道每一步的代价、每条路径的故障行为、每个假设的验证方法。

先建立图像

题目(模拟面试原题):

背景:本站在线判题/学习平台,现状单体 Spring Boot 3.5 + MySQL 8,
     2 个 API 实例 + 1 台判题机,无 Redis、无 Kafka、Nginx 单层。
现状:峰值 800 QPS,P99 450ms,判题排队高峰 5 分钟。
目标:推广活动后 10 万日活;比赛场景瞬时提交 500 QPS 持续 1 分钟;
     SLA 99.9%,判题结果查询 P99 < 300ms,允许排行榜分钟级延迟。

第一反应必须是澄清与估算(第 1 课四步法):

项假设推导结论
浏览流量人均 30 页/天300 万/天峰值 ~175 QPS
提交流量人均 5 次/天50 万/天峰值 ~30 QPS,比赛瞬时 500 QPS
判题并发10s/次30 QPS × 10s300 并发槽,判题机 ≥ 30 台核
读写比看题为主—9:1,读路径是优化主战场
存储2KB/条50 万/天1GB/天,一年 365GB → 100 天单表触顶

关键结论先行:浏览量不大(单机都能扛),真正的三座山是判题吞吐、比赛洪峰、提交表增长。设计要对着这三座山打。

跟着做

步骤 1:画目标架构图(每条线标注流量)

                 浏览器
                   │
          CDN(静态资源 + 题目描述)
                   │
          Nginx L7(限流 + 路由 + 探活)      ← 第 4 课
                   │
     ┌─────────────┼──────────────┐
     │             │              │
  题目服务×2    提交API×3      查询API×3      ← 无状态,水平扩展
     │             │              │
     │         Kafka judge-task   │            ← 第 6 课,24 分区
     │             │              │
     │      判题机池 ×N(沙箱)     │            ← CPU 密集独立池
     │             │              │
     └──── Redis ──┴──── MySQL ───┘
      题目缓存       主从 + 提交表分片  ← 第 5/7 课
      排行榜ZSet

标流量:CDN 承接 70% 浏览 → Nginx 进 175 QPS → 提交 API 30 QPS 写库+发消息 → 判题机池 ≥100 QPS 消费能力 → 查询 API 读 Redis 95% 命中、5% 回源从库。

步骤 2:逐组件写清「它解决什么 + 挂了怎么办」

每个组件两句话过审,这是评审与面试的通用纪律:

Redis:解决读路径 95% 命中(题目 JSON + 排行榜 ZSet);
      挂了降级直查从库 + 读接口限流,排行榜退回 MySQL 聚合页。  ← 第 5/10 课
Kafka:解决比赛 500 QPS 洪峰削峰,积压 2.4 万条 ≈ 排队 4 分钟可见;
      挂了提交降级为「写库 PENDING + 定时扫描」,提交不丢。      ← 第 6 课
判题池:解决 300 并发 CPU 槽,与 API 部署隔离(舱壁思想到物理层);
      沙箱限时限内存禁网络,防恶意代码打满池。                  ← 第 9 课
MySQL:读写分离 + 提交表按 userId 分 4 片 + 90 天冷热归档;
      主库挂半同步切换 RPO=0、RTO 60s。                        ← 第 7/10 课

步骤 3:写出三阶段演进(每阶段可独立交付)

阶段改动预期容量代价与风险
Phase 1 稳基线题目读路径加 Redis cache-aside(TTL 抖动+空值防穿透);提交接口接入 Kafka + 判题机独立池;Tomcat/HikariCP 超时与池参数校准~3000 QPS;比赛洪峰排队可控缓存一致性要写双删;Kafka 运维新增
Phase 2 拆读写读走从库 + 读己之写粘滞;Nginx 限流 + 网关统一鉴权;读/写舱壁隔离;放大倍数监控上线~6000 QPS;P99 < 200ms主从延迟产品文案;限流阈值需压测校准
Phase 3 抗增长提交表分 4 片 + 冷热归档;排行榜 CQRS 对账;多 AZ 部署 + 健康检查三层 + 月度故障演练10000+ QPS;SLA 99.9% 可承诺分片键选定后迁移成本高(双写切换);演练要排期

顺序原则(第 2 课):每阶段从便宜到贵、可独立回退,Phase 1 就能扛住推广活动——不要被「一步到位」诱惑。

步骤 4:用评分表自审(面试官视角)

□ 需求澄清:有没有把 NFR(延迟/一致性/SLA)确认成假设?        ← 第 1 课
□ 估算:QPS/并发/存储是否给了数量级和推导过程?               ← 第 1/2 课
□ 一致性:提交状态强一致、排行榜最终一致,标注了吗?           ← 第 3 课
□ 扩展路径:无状态、缓存、读写分离的顺序对吗?                 ← 第 2/4 课
□ 异步设计:削峰算过账吗?消费端幂等怎么保证?                 ← 第 6 课
□ 数据架构:分片键为什么是 userId?跨片查询怎么兜?            ← 第 7 课
□ 故障行为:每个组件「挂了怎么办」都能一句话回答吗?           ← 第 10 课
□ 反模式自查:放大倍数、重试四件套、无缓存读路径排除了吗?      ← 第 11 课
□ 权衡与代价:每步改动说了人机成本吗?

八项里能主动讲出六项,面试设计关就稳了。

步骤 5:同伴互审的两个问题

互审只问两个问题(模拟面试官追问):

  1. 「这套架构第一个崩的是什么?」——压力逐级放大时的观察顺序:判题池 CPU 100% → Kafka lag 增长 → Redis 命中率下降(热点题目变多)→ MySQL 连接耗尽。答不出顺序说明容量数字是拍脑袋的。
  2. 「比赛开始 10 秒后用户看到什么?」——标准答案:提交成功返回「排队第 N 位」(N 来自 lag),状态轮询 P99 仍 < 300ms(读路径与写路径已隔离),排行榜延迟标注「分钟级」。答「页面卡住」就是读写没有隔离。

讲清楚要点

  1. 先结论后细节:答卷开头一句话给结论(「瓶颈在判题池与洪峰,读路径单机即可起步」),再展开推导——面试官 45 分钟里最先想听的是你的判断力。
  2. 每个数字必须可追溯:DAU→操作→QPS→并发→资源,链条断了就承认是假设并标注验证方式(压测),不要让任何数字裸奔。
  3. 架构的每一个组件都要「双句过审」:一句「解决什么问题」,一句「挂了怎么办」。两句都答不上来的组件,从图上删掉。
  4. 演进阶段以「独立可交付」为界:每个 Phase 单独上线、单独回滚、单独产生收益。评审通过的是路线图,不是终态图。
  5. 一致性标注是暗线:整份答卷里,提交状态(强)、排行榜(最终)、CDN 题目描述(弱)三条线的取舍贯穿读写两侧——面试官会沿这条线追问。

你可能会懵的地方

  • 45 分钟答不完这么多内容怎么办? 优先级就是答案:澄清估算 10 分钟 → 主路径图 + 三座山 15 分钟 → 挑面试官最感兴趣的组件深挖 15 分钟(判题池/缓存/分片三选一)→ 收尾故障行为与演进 5 分钟。深挖点跟着面试官的眼神走,而不是按自己的提纲硬讲。

  • 设计里没有微服务、没有 K8s,会不会显得太简单? 不会,反而加分。10 万日活的正确形态就是「单体多实例 + 缓存 + 消息 + 分库预备」,把微服务塞进这份需求是过度设计的典型信号(第 8 课的判断框架自己说了「没有组织痛点不拆」)。能论证「不做什么」比堆组件高级。

  • 面试官对我的分片键提出质疑(比如「按 create_time 范围分片更好」)怎么办? 不要立刻认怂,也不要硬顶:先复述对方的场景(范围分片对时间范围查询友好),再给出本站高频查询是 userId 维度的事实,最后说「若运营统计上升为主要负载,可以为其建按时间的异构读模型而不是改分片键」。这展示的是权衡能力而非立场。

  • 如果被问到完全没准备的方向(比如国际化部署)怎么办? 诚实 + 方法迁移:「这块我没实操过,按现有框架推:判题沙箱涉及代码合规不能出境,所以要按地域做 deployment stamp,每 stamp 独立数据、全局流量按地域路由——具体合规细节我会上线前专门确认。」承认边界 + 用已有模式推理,比胡编强得多。

  • 这份设计离「真实生产」还差什么? 三样:演练验证(月度故障演练证明 RTO)、成本核算(每 Phase 的月账单)、灰度策略(切流比例与回退按钮)。设计文档的最后一章永远是「怎么验证我说的这些都是真的」。

错法对照

错法问题正解
开口就画全家桶(K8s+微服务+多机房)过度设计,说不清每个组件的必要性对着三座山逐个上组件,双句过审
只画终态不画路径评审无法排期,面试显得没做过三阶段演进,每阶段独立交付
数字全是「大概几万」不可信,暴露没做过估算链条推导 + 声明假设 + 标注压测验证
只讲正常路径故障才是深挖主战场每组件一句「挂了怎么办」
深挖被质疑时慌乱改口失去判断力的信号复述对方场景→给数据→给折中方案

卡点急救

  1. 一动手就把估算忘了:把「DAU→操作→QPS→并发→资源」五步写在草稿纸顶上,画图前必须先填完这行——机械纪律比灵感可靠。
  2. 图越画越乱:分层重画——客户端层/入口层/服务层/数据层/异步层五条泳道,每个组件只出现在自己泳道里;对话中临时讨论的组件(如 ES)画在旁边虚线,标注「待评估」。
  3. 收尾时间不够:提前准备「电梯总结」——30 秒讲完主路径 + 三座山 + 阶段划分,被叫停时用这段收尾。永远让面试官听到完整闭环。

面试常问

  • 用 45 分钟设计这个判题平台,你的整体节奏? 开场直接说节奏:「我计划 10 分钟澄清估算、15 分钟主路径、15 分钟按你感兴趣的方向深挖、5 分钟故障与演进。」然后严格执行。主动管理时间结构本身就是系统设计能力的展示。

  • 你的设计里最可能先崩的组件是什么?为什么? 给出放大顺序并说明监测点:判题池(CPU 先顶,看沙箱并发数)→ Kafka lag(洪峰时最先涨的指标)→ Redis 命中率(热点扩容时降)→ MySQL(分片前的连接数)。同时说明每个监测点对应的告警阈值——把「会崩」讲成「可观测的何时崩」。

  • 如果要支撑 100 万日活,这份设计哪里最先不成立? 考演化思维:提交表分 4 片不够(10× 数据 → 8~16 片 + 一致性哈希迁移)、单 Redis 集群要上分片集群(热点题 100 万 QPS 需要本地多级缓存)、Nginx 单层要加 L4 入口层、判题机池按地域 stamp 部署。答案方向对即可,关键是知道「哪里会先碎」。

自测三问

  1. 不看课文,默写这道题的五个估算数字及其推导链。
  2. 说出你的架构里三个组件的「双句过审」(解决什么 + 挂了怎么办)。
  3. 三阶段演进中,哪一阶段就能扛住推广活动?为什么不留到 Phase 3?

小结一句话

综合设计的核心是「结论先行、数字可溯、组件双句过审、演进可回退」——能分阶段讲清代价与故障行为,比一张炫技架构图有工程价值得多。

延伸

  • 《System Design Interview》Vol.2:多组件综合题(含判题类系统)的完整范例
  • Google SRE Workbook — Emergency Response:故障演练与应急响应的落地方法
  • Microsoft Azure — Cloud Design Patterns 全目录:把本 track 出现过的模式对照原文再过一遍
  • 本 track 已完结。下一步建议:① 把本课答卷扩写成正式设计文档并做一次同伴评审;② 按 system-design 路线图 回查 12 课覆盖的节点查漏;③ 进阶阅读 DDIA 第 2 部分与 Google SRE Book;④ 在本站用「系统设计」标签刷题,把四步法用到每一道新题上。
加载本节练习…
← 上一课性能反模式