
从零整理一份 system design 笔记我到底在记什么如果你跟我一样不是科班出身、半路转行做后端早晚会被系统设计system design这门课虐一遍。它不是算法题没有标准答案也不是背几个名词就能过关它考的是你“能不能把一个模糊的问题拆成能落地的东西”。所以我从去年开始老老实实维护了一份 system-design-notes把每次面试复盘、每次看论文、每次重构系统时的思考都沉淀进去。这份笔记帮我拿了几个 offer也让我在日常工作里做技术方案时明显更笃定。这篇博文不是教你背八股而是想聊聊我这份笔记到底在记什么、怎么组织、以及里面最核心的知识点大概有哪些。如果你也在准备系统设计或者只是想让自己的架构能力更扎实一点可以参考我这个思路从零搭一套属于你自己的笔记体系。1. 笔记背后的核心思路系统设计到底在考察什么1.1 它和刷算法题的本质区别刷 LeetCode 的时候题目边界条件都写清楚了输入输出明确你只需要在无数解法里找最优解。系统设计完全不是这么回事。面试官扔给你一句“设计一个短链接系统”然后就开始观察你怎么思考。这个“模糊性”其实是刻意的它考察的是你在信息不完整的情况下怎么一步步把问题变具体。系统设计的考察点基本可以分成四层。第一层是最基本的你有没有掌握常见组件缓存、消息队列、负载均衡、数据库、对象存储的特性和使用场景。第二层是你能不能根据业务场景做技术选型比如这个场景到底该用 PostgreSQL 还是 DynamoDB该用 Redis 还是 CDN。第三层是权衡能力也就是你能不能清晰地说出每种方案的代价而不是只讲好处。第四层是沟通能力你能不能把一个复杂的系统用合适的抽象层级讲给别人听懂。这也是我在面试里最大的体会系统设计没有“正确答案”只有“合理且自洽的方案”。面试官真正想看的是你面对 trade-off 的时候有没有一套稳定的决策思路。所以我的笔记第一个落脚点不是写“什么方案最好”而是写“什么场景下选什么、为什么”。1.2 我决定用“组件 场景 案例”三层来组织笔记试过市面上不少系统设计教学资源有的按“设计 Twitter”“设计 Uber”这种具体题目来写有的按“缓存、消息队列”这种组件来写。学完之后发现一个尴尬的问题知识点会但一遇到新的题就不知道先想什么。后来我把笔记重构了一遍分成了三层。第一层是组件层也就是把 Load Balancer、Cache、Message Queue、Database 这些基础积木的机制、选型要点、常见坑都记下来。第二层是场景层按业务类型归类比如读多写少的资讯类系统、写多读少的日志系统、强一致性的支付系统、弱一致性的 feed 流系统记录每种业务场景下最适合的架构骨架。第三层是案例层就是经典的“设计 XX”题目把它们当“综合应用题”来练。这个三层结构的妙处在于碰到新题的时候你会自动先判断它属于哪个场景层再从组件层里把需要的零件和权衡条件调出来。不是背题是搭积木。2. 核心知识拆解系统设计绕不开的那些基础组件2.1 负载均衡所有流量入口的第一个决策点负载均衡Load Balancer是系统设计里最常用、也最容易被忽略的组件。很多人觉得它没啥好讲的选个 Nginx 或者 AWS ALB 就完事了。但实际上负载均衡层藏着很多决策细节因为它直接决定了后面的架构怎么搭。笔记里我会重点记三件事。第一件事是负载均衡部署在网络模型的哪一层L4 转发和 L7 转发到底有什么区别。L4 基于 IP 和端口做转发效率高但看不到 HTTP 请求内容L7 能看到 URL、Header 这些应用层信息可以做更智能的路由比如按路径转发到不同的服务。缺点也明显L4 性能好但功能单一L7 功能丰富但是要终结 TLS、解析 HTTP性能和复杂度都是成本。第二件事是负载均衡的算法。Round Robin 是最简单的轮询适合后端实例能力接近的场景Least Connections 适合长连接场景IP Hash 能保证同一个用户始终打到同一台服务器如果业务状态是会话本地的这种方式就比较有效。还有一致性哈希Consistent Hashing这个在分布式缓存场景里几乎必考它能解决节点增删时大量 key 失效的问题。第三件事是健康检查机制。负载均衡不是随便把流量分发过去就完事它需要定期探测后端实例的健康状态如果实例挂了就要自动摘除。我在笔记里特地记了一个“被动健康检查 vs 主动健康检查”的对比。主动就是 LB 定期发心跳请求被动就是 LB 观察到连续错误次数达到阈值就自动摘除节点。实际生产里一般两者结合用。2.2 缓存不是所有数据都值得进内存缓存是提升系统性能的第一选择也是系统设计面试里最常问到的话题。但很多人犯了同一个错误面试官一说“性能不行”他马上回答“加缓存”。我写笔记的时候特别提醒自己缓存是为了解决“读多写少”的问题而且缓存有明确的代价。第一个代价是数据一致性。缓存和数据库之间天然存在时间窗口的不一致。Cache Aside 模式里你先更新数据库再删除缓存还是先删缓存再更新数据库前者有短暂的不一致后者有缓存击穿的风险。更稳妥的做法是延迟双删先删缓存、更新数据库、隔一小段时间再删一次缓存。但延迟双删也不是完美方案它只是在工程上能接受的近似方案。第二个代价是缓存失效的连锁反应。缓存穿透查询一个一定不存在的 key导致请求直接打到数据库、缓存击穿某个热点 key 失效大量请求同时打到数据库、缓存雪崩大量 key 同时失效或者缓存集群整体宕机这三个问题我在笔记里分开记了各自的解决方案。穿透用布隆过滤器或缓存空值击穿用互斥锁雪崩用过期时间加随机值、多级缓存、高可用集群。第三个代价是容量和淘汰策略。缓存不是用来存全量数据的LRU、LFU、FIFO 三种淘汰策略各自的适用场景不一样。LRU 实现简单、适合大多数场景LFU 能抵挡热点数据的稀疏访问但实现复杂且有“冷启动”问题。还有 Redis 的过期策略惰性删除 定期删除也值得深入理解面试官很喜欢让你对比“为什么不用定时删除”。2.3 数据库选型与分库分表的地平线数据库是整个系统设计里最核心、也最不能出错的一环。很多系统设计的题目本质就是在考察你怎么处理数据。数据量小的时候单机数据库最省心但数据量一上来你就得面对分库分表、读写分离、垂直拆分、水平拆分这些问题。我的笔记里这个部分是最厚的。我按场景把数据库分成了几类关系型数据库MySQL、PostgreSQL适合强一致性和复杂事务文档型数据库MongoDB适合灵活 schema 和海量写入列式存储BigTable、Cassandra适合大规模分析和时间序列数据图数据库Neo4j适合社交关系、推荐系统搜索引擎Elasticsearch适合全文检索和日志分析。这背后其实是一个很关键的认知高性能不等于高复杂度选型不该看哪个最厉害而该看哪个味道最匹配。我见过太多人明明只是要存结构化数据非得上 MongoDB结果搞出一堆一致性补偿代码。数据库选型的第一原则是用最小满足需求的复杂度把最简单可靠的方案作为默认选项。至于分库分表我记了几个核心原则。第一能不拆就不拆读写分离解决的是读压力缓存也优先于分库分表。第二拆的时候优先水平拆分因为垂直拆分只是把宽表拆成窄表解决不了单表数据量大的问题。第三水平拆分要提前想好分片键Shard Key选错分片键基本等于白拆。比如订单表里用 user_id 分片查找用户订单列表就很高效但后台运营要按商家维度统计就很麻烦用 order_id 分片则反过来。没有十全十美的分片键只能根据主要查询模式做权衡。2.4 消息队列系统解耦和削峰填谷的功臣消息队列在系统设计里出现的频率极高它解决的是“同步请求处理不过来”和“多个模块耦合太紧”这两个问题。我笔记里对消息队列的定位是它是系统设计里的“缓冲垫”把强同步依赖变成弱异步依赖。选型上我主要比较了三类。第一类是 Kafka吞吐量极高、分区模型设计精妙适合日志收集、事件流、大数据管道。第二类是 RabbitMQ功能丰富支持各种路由协议和死信队列适合业务系统里复杂路由、任务分发等场景。第三类是 Pulsar、RocketMQ 这一类各有特色Pulsar 的存算分离做得比较彻底RocketMQ 在交易场景有大量实践。使用消息队列有个绕不开的核心问题怎么保证消息不丢、不重、不乱序。这个在笔记里我标记为“必考三连”。不丢需要生产端确认、Broker 持久化、消费端手动 ack 三层配合不重需要消费端做幂等设计因为至少一次语义下重复投递是必然的不乱序需要把同一订单的消息发给同一个 partition然后单 partition 单消费者消费。还有一个很容易忽略的点消息队列不是银弹它引入了分布式事务的复杂度。比如你下单后发了消息但消息发送失败怎么办本地消息表、事务消息还是 outbox 模式这些都是在引入 MQ 之后必须立刻想清楚的问题。我在笔记里把 Outbox Pattern 单独写了一节因为它在生产实践里真的很常用业务操作和写事件表在同一个本地事务里完成然后由后台进程把事件表数据发到 MQ能保证业务操作和消息发送的一致性。2.5 分布式一致性系统设计里最贵的奢侈品一致性是我在笔记里花时间最多、也最“劝退”新人的一个话题。它比较抽象不像缓存那样直观。我的理解方式是把它看成一笔生意在分布式系统里你不可能同时拥有强一致、高可用和低延迟你需要做取舍。CAP 定理几乎所有的系统设计资料都会提但很多人只是背了“三选二”的口诀这在真实场景里其实容易误导。因为 CAP 说的是网络分区P发生时你只能在一致性C和可用性A里二选一。如果网络没有分区C 和 A 可以同时满足所以你平时设计的重点不是“三选二”而是“分区发生时怎么处理”。具体的实现手段里我记了两个典型方向。一个是强一致方向用 Paxos/Raft 共识算法典型代表是 etcd、ZooKeeper。另一个是最终一致方向用各种补偿和协调机制比如 Saga、TCC、本地消息表。这里我要特别说一句大多数互联网业务场景根本不需要强一致最终一致 兜底补偿才是性价比最高的方案。拿电商下单举例整个流程拆成扣库存、创建订单、发优惠券、加积分几个步骤如果用强一致事务分布式事务的复杂度和性能损耗都极高。用 Saga 模式每个步骤都有对应的补偿操作如果第二步失败了就触发第一步的补偿把库存加回去虽然中间有一段时间用户看到的库存可能不准但最终整个流程是收敛的。系统设计面试里能把这个权衡讲清楚比把 CAP 背得滚瓜烂熟更能拿分。3. 实操方法论我如何把一份系统设计笔记真正用起来3.1 从零起步先搭骨架再看大量案例很多人拿到“系统设计笔记”这种主题第一反应是“我得先学完所有知识才能开始写”。不是的。学习系统设计是一个“螺旋上升”的过程先有一个粗糙的大框架然后在案例里不断填充细节、修正认知。我的做法是第一周先不做具体题目只做两件事。第一件事是把核心组件列成清单API Gateway、Load Balancer、CDN、Cache、Message Queue、SQL Database、NoSQL Database、Object Storage、Search Engine 这些。每个组件只写三行是什么、解决了什么问题、什么时候不该用。这个清单不需要完美甚至会有错误但它是后续所有笔记的锚点。第二件事是选定一套经典的题目列表一般是十道左右短链接系统、新闻 Feed 流、聊天系统、网盘系统、秒杀系统、爬虫系统、限流系统、打车系统、推荐系统、监控系统。从第一道题就开始写“自己的题解”哪怕写得很烂也不要紧因为等你写到第五道再回头看第一道你会发现自己的视角和深度完全不一样了这就是进步的证据。3.2 面试现场的笔记流跟随四步法来组织思路系统设计面试通常只有 45 分钟到 1 小时你不可能写完一份详细设计文档。所以你需要一套固定的答题框架让自己在没有模板可以查的场合下也能稳定发挥。我把这套框架称为“四步法”每步都在笔记里有对应的速查章节。第一步是需求厘清。先别动笔画架构先用 3-5 分钟把业务背景、功能需求、非功能需求问清楚。短链接系统你得问清楚用户量多少短链有效期多长要不要自定义别名需不需要统计点击量这些问题的答案决定了后续所有设计决策。我在笔记里把它总结成一句话没有错误的需求理解只有没有问清楚就开始画图的人。第二步是容量估算。面试官通常不会让你非常精确地算但你得给出一个数量级正确的估算。QPS 是多少每天新增数据量多少需要存储多少年这决定了你需不需要分库分表、需不需要缓存、需不需要异步化。笔记里我放了几张常用的数字速查表每台普通服务器的 QPS 大约支撑多少、MySQL 单表数据量建议不超过多少、Redis 单实例内存一般多少比较合理等等。第三步是高层设计。画出核心组件和调用链重点画数据如何流转。比如短链接系统前端请求到 API Gateway再按写请求/读请求分发到不同服务写服务生成短码并存库读服务先查缓存再查数据库这就是一个完整的高层设计。第四步是深入细节。根据剩下的时间选择一两个重点模块展开讲。如果是短链接系统就展开讲短码生成算法哈希截断、自增 ID Base62、发号器如果是 feed 流系统就展开讲推拉结合的模型怎么设计。我把这套四步法写进笔记的第一页每次面试前只看这一页提醒自己不要一上来就画图。3.3 怎么用一篇笔记干掉一整类题目笔记最有价值的地方不是让你记住一道题而是让你发现“原来这几道题的内核是同一个”。举个例子短链接系统、网盘系统、URL 去重服务它们的核心都在处理同一个问题怎么用一个短的 ID 或路径快速定位一个数据。你在笔记里把这层“元模式”提炼出来以后遇到类似题目就能快速迁移。我笔记里提炼了不少这样的元模式。比如“读多写少”模式适用的优化链路基本是 CDN - 缓存 - 数据库在数据库层还可以做读写分离“写多读少”模式重点是削峰填谷消息队列 批量写入是标准套路“高并发秒杀”模式核心思路是“层层拦截请求”前端页面静态化、API 层限流、MQ 削峰、数据库层最终扣减“全局唯一 ID”模式Snowflake、Redis INCR、UUID、数据库号段四种方案各有取舍选型依据是对有序性和可用性的要求。我在笔记里给每个模式单独开了一节用“适用场景 组件清单 典型题目 踩坑点”来组织这样记起来很有条理用的时候也可以快速定位。4. 从一道题看全文核心设计短链接系统的笔记实录4.1 需求与容量估算我拿最经典的短链接系统来完整走一遍。为什么选它因为它麻雀虽小五脏俱全缓存、数据库、哈希算法、并发控制全都有。如果你能完整理解这道题很多类似题目的思路就通了。需求阶段要问清楚的事QPS 是多少、链接有效期是多久、要不要自定义短链、要不要点击统计、需不需要过期清理。假设业务目标如下每天新生成短链 1 亿条读 QPS 约 10 万写 QPS 约 1200。按这个量级来估算一年新增数据约 365 亿条如果每条记录占 100 字节一年就是 36.5 TB 的数据量。这个数据量说明了什么说明必须引入缓存必须对数据库做分片不可能让所有请求都打到单机数据库上。还要算一下短码的长度。如果短码只用 6 位 Base62 字符大小写字母加数字共 62 个总容量是 62^6 ≈ 568 亿够用几年。如果将来不够可以平滑升级到 7 位、8 位。这个容量估算写在笔记里面试时直接背出来就能展示你思考过数量级。4.2 短码生成方案对比短码生成是短链接系统的灵魂也是面试官最想听到细节的地方。我笔记里记了三种方案它们的取舍很典型。第一种是哈希截断法。用 MD5 或 SHA-256 对原始 URL 取哈希再截取前 6 位作为短码。优点是实现简单、无需额外状态缺点也很明显哈希冲突会导致不同 URL 生成同一个短码需要加盐或不断重新哈希而且哈希结果是随机的不具备单调性不利于后续做范围分片。第二种是自增 ID Base62 编码。用数据库自增主键把十进制 ID 转成 62 进制短码。优点是短码有序、无冲突缺点是 ID 自增在分布式场景下成为瓶颈而且短码可以被逐个遍历隐私性差一些。第三种是发号器方案。预生成一批 ID 放到内存里应用启动时批量取号用完再取下一批。发号器可以单机或分布式部署。这套方案的优点是性能好、短码单调递增缺点是需要额外维护发号器组件和高水位管理。我的最终选型思路是这样的如果是中小规模系统数据库自增 ID Base62 是性价比最高的方案如果 QPS 极高、需要分布式部署就需要引入雪花算法或发号器方案这时候短码有序性会下降但换来了更高的吞吐和扩展性。方案没有绝对优劣你在笔记里要写清楚自己对取舍的判断逻辑。4.3 读写链路的细节设计短链接系统核心有两条链路读链路和写链路。我在笔记里分别画了流程图然后配文字解释关键决策点。写链路是这样用户提交原始 URL服务端校验 URL 合法性生成短码后写入数据库同时把短码到原 URL 的映射写入缓存并异步把链路点击元信息写入埋点消息队列。这里有个容易被忽略的细节先写缓存还是先写数据库我的策略是先写数据库再写缓存。因为短链接创建后短时间内的读请求可能很少先写缓存属于写放大只有读链路真正查不到的时候才从数据库回源并写回缓存。读链路是重点用户访问短链DNS 解析到短链服务短链服务先查缓存命中则返回 302 重定向到原 URL未命中则查数据库查到后回填缓存查不到则返回 404。为了抗住 10 万 QPS 的读流量缓存命中率至少要达到 95% 以上否则数据库扛不住。这里还要考虑一个缓存持久化的问题如果缓存节点宕机热点数据会全部失效直接打满数据库。所以生产环境一般会做缓存集群高可用或者在缓存失效时用“请求合并 分布式锁”避免数据库被压垮。4.4 更多细节可观测性、限流与数据清理一个生产级的短链接系统不能只有主链路。我笔记里会额外记三个非功能性设计。可观测性方面一个亿级流量的系统必须把 QPS、P99 延迟、缓存命中率、DB 慢查询、短码生成失败率等指标全部接入监控。没有监控的系统出了问题只能靠猜这对任何系统设计面试都是大扣分项。限流方面短链接服务对外暴露写接口必须防止恶意用户刷接口否则会把发号器和数据库压垮。常用的限流算法是令牌桶和漏桶。令牌桶允许一定程度的突发适合应对正常流量抖动漏桶平滑流量适合保护下游系统。我用一张对比表记录了它们的区别令牌桶是“先发令牌有桶才能请求”允许攒令牌实现突发漏桶是“请求进桶匀速流出”无论上游多猛下游永远匀速。真实场景里令牌桶更常见因为突发流量在互联网业务里很正常。数据清理方面短链接如果是短时效的比如活动 UV/PV 统计链接7 天或 30 天后就应该被清理。不清理的话冷数据会拖慢查询性能、增加存储成本。我的方案是用“过期时间 异步任务”来处理短链接记录带上 expire_at 字段读链路判断过期直接返回 404然后异步任务定期清理过期数据。缓存侧用 Redis 的 TTL 来兜底到点自动释放内存。5. 系统设计怎么判优劣从给分点反推准备策略5.1 面试官的高分逻辑清晰大于炫技我后来有机会跟做过系统设计面试官的朋友聊过打分逻辑。他说了一个让我印象很深的结论他面试的候选人里大多数人不是挂在知识量不够而是挂在讲解不清、结构混乱、盲目堆砌框架。很多候选人动辄谈“我们上 Kubernetes、上 Service Mesh”问他为什么回答是“因为大家都在用”这反而是最大的减分项。面试官心中的强答案通常是这个样子。能主动澄清需求而不是假设一大堆条件能给出数量级正确的容量估算而不是随口报一个数字能画出组件清晰、调用方向明确的高层设计图能在深挖某个点时说出权衡和代价还能主动提到监控、限流、灾备这些非功能性设计。所以我在笔记里特别设了一张“自检清单”每次模拟面试完对着清单逐项打分需求问了几个问题是否有明确的功能/非功能划分容量估算是否给了数字和推导过程架构图有几个组件有没有说明数据流向有没有主动提到幂等、重试、限流、监控每一项都打钩或打叉就知道自己还有哪里欠火候。5.2 新手和老手的笔记区别纠错驱动 vs 知识驱动经常有人问我系统设计笔记应该记到什么程度才算合格我的答案其实慢慢在变。刚开始写笔记的时候我什么都记感觉自己像个知识搬运工。但后来我发现真正让我成长的笔记不是那些搬运来的知识而是我在实战案例里犯过的错、踩过的坑、事后复盘总结出来的教训。举个例子有一段时间我在设计缓存策略时默认所有热点数据都放 Redis结果碰到了缓存击穿导致数据源被打爆。后来我在笔记里专门开了一个“缓存失效踩坑记录”板块不仅记了问题现象还把排查思路和修复方案都写上去。这个板块后来帮我在另一次面试里讲出“缓存击穿和缓存雪崩其实并不是一回事处理方式也不同”面试官明显眼神一亮。所以如果你也想做一份 system 设计笔记我的建议是前期可以以知识驱动为主先把一个个组件搞清楚中期一定要转为纠错驱动每做一道设计题就复盘一次自己哪里想得不够后期再回归知识驱动把你已经掌握的方案不断抽象成更通用的模式。5.3 怎么把笔记变成自己的架构方法论笔记积累到一定程度你会进入一个“融会贯通”的阶段。你发现短链接系统里学到的发号器思想可以迁移到订单 ID 生成feed 流系统里学的推拉结合模型可以用在站内通知系统秒杀系统里学的层层限流可以用在任何高点值的活动系统。这些跨场景的迁移能力才是系统设计笔记带来的最大财富。要实现这个目标有一个很具体的练习方法给每个已学的系统设计题写一段一句话总结。比如短链接系统的总结是“核心在全局唯一短码的生成与存储”秒杀系统的总结是“大量请求在读链路就被拦截真正落到写链路的请求被极致压缩”feed 流系统的总结是“读扩散和写扩散的权衡以及推拉结合怎么实现”。这些一句话总结会沉淀成你脑子里的一套“决策卡片”遇到新问题时快速匹配。6. 常见问题与踩坑实录我在这条路上吃过的亏6.1 误区一上来就画架构图我早期犯的最大错误就是一听到题目就开始画图。用户量多大、读写比例多少、数据一致性要求多高统统没问直接画了一个微服务网格。面试官后来反馈说当时就看出来我没有“需求驱动设计”的思维习惯。现在我会强制自己在纸上写三个问题这个系统最核心的 read 和 write 模式是什么数据量和访问量大概在什么数量级允许的延迟和数据丢失率是多少这三个问题没想清楚之前不让手去碰笔画图。这个习惯在真实工作中也同样受益做技术方案评审时遇到需求模糊的需求我会带着同样的问题去和业务方对齐。6.2 误区二背方案而不是背权衡以前我会把“设计 Twitter”的参考方案背得滚瓜烂熟但面试官稍微改一下题目背景比如把“用户看推文”改成“用户看自己收藏的列表”我的方案就卡壳了。后来我才想明白问题的本质不是让你复现某个方案而是要你根据限制条件找出合理方案。所以我的笔记里每个方案必带前缀这个方案在什么场景下成立、代价是什么、如果条件变化我应该怎么做。时间久了我的脑子里就不是零散的方案而是一张决策树。面试官问“如果 QPS 提高十倍怎么办”我能顺着树往下分支而不是支支吾吾说“上多级缓存”。6.3 误区三忽视容量估算容量估算在系统设计里很常见但一开始我觉得它“又简单又没用”不就是加减乘除嘛。后来有一次面试面试官问我“你说要上缓存那你预计缓存要开多少内存”我瞬间愣住了。因为我没有估算过有多少热点数据内存规格完全拍脑袋。从那以后我把容量估算当成系统设计的“地基”。每次设计任何模块前先问自己QPS 多少、平均响应时间多少、数据量多少、保存多久、带宽多少估算出来的数字不需要精确但在数量级上不能错。这个习惯在真实系统里价值极大。一次我评估某个功能需要增设缓存先估算出每秒查询 5000 次、单个 value 2KB、缓存 TTL 10 分钟得出结论 Redis 需要约 6GB 内存于是直接按 8GB 规格申请上线后各项指标非常平稳几乎没调过参数。场景常见容量估算公式备注QPS 估算日活用户 × 平均请求次数 / 86400再乘以峰值系数 3-5存储估算日新增数据量 × 存储天数 × 冗余系数弹性冗余 1.5-2 倍缓存估算QPS 峰值 × 平均响应时间 × 单条数据大小还要考虑过期窗口内的热点数据量带宽估算QPS × 平均包体大小 × 8 bit/byte别忘了出口带宽和入口带宽都要算6.4 踩坑实录缓存一致性是我翻车最多的地方最后讲一个我印象很深的线上事故。有段时间我们的列表页接口响应时间突然飙升DB 负载爆表。查了半天发现是新版本代码把“先更新数据库再删缓存”写成了“先删缓存再更新数据库”导致在更新数据库之前缓存一直是空窗大量请求直接打到数据库。当时整个团队熬到凌晨三点才定位到问题。事后我在笔记里专门写了这一段教训提炼成三条铁律。第一Cache Aside 模式下更新操作要确保“更新数据库”和“失效缓存”的顺序稳定第二如果必须“先删缓存再更新数据库”一定要配合延迟双删或分布式锁第三任何缓存预热方案都要考虑缓存雪崩场景不同 key 的过期时间要加随机值错开。这些“用钱和觉买来”的经验比任何教程都更让我记忆深刻。你在做系统设计练习时也许没法经历真实的线上事故但可以通过读技术博客、和大佬交流、复盘复杂系统的线上 issue把别人的教训也沉淀到自己的笔记里。这些都是系统设计笔记里最宝贵的内容。7. 最后再聊聊我怎么持续维护这份笔记我记得这个项目最开始只是面试前一晚上临时拼的一份草稿Word 文档塞了一堆截图和链接。后来我逐渐挪到 Markdown 文件用 Git 做版本管理之后才发现笔记的生命力在于更新不在于初始多完整。我现在维护它的节奏大概是这样每做完一道系统设计题或一次面试当天必须花 30 分钟把痛点、盲点、回答卡壳的地方记录下来每周至少花 1 小时翻一翻之前的笔记把旧内容里过时或错误的地方修订掉每季度做一次大扫除把已经内化到不需要看的知识点折叠归档把新学到的复杂模式提升为新的主题章节。还有一个心态上的建议系统设计的学习周期非常长可能会持续半年、一年甚至更久。在这个过程中最忌“收藏符合”——在 GitHub 上点 star 不算学会把知识点写进自己的笔记、能给别人讲明白一次才算真正内化。我个人的体会是做这份 system-design-notes 的过程本质上是在“给自己建一个外置的大脑”。它让我在面试高压环境下不用临时拼凑答案也让我在日常架构设计中更有底气。如果你也准备开始别贪多先搭好组件清单然后选一道短链接题目写出你的第一版题解不管它多简陋先迈出第一步就对了。后续你会慢慢发现那些曾经让你头皮发麻的分布式系统问题其实都有一以贯之的解题底层逻辑。