核心方法论
145 张方法论卡片,用「道—法—术—器—势」把 Java 专家 · 架构师 · 高级开发 工程能力知识库 织成一张网:M 是道法术,G/K 是器与反器,C/E/S/A/D 是领域落点,势横贯时机与规模。 从深度 Q&A 篇章 C 252 道(另含 AI 纵深 A 74)提炼可迁移骨架。
以道定方向,以法立骨架,以术落地,以器固化,因势而变。吞吐与可用的哲学投影仍是——找出竞争与故障域,再拆分;把「大单点」拆成「小故障域 + 可并行资源」,且拆分必须挂在闭环与稳态上,而不是堆中间件。
五层是因果链而非并列标签:道定取舍边界 → 法落成骨架与责任表 → 术打招式并暴露调参 → 器把门禁/组件固化可替换 → 势判断时机与量级。读任一 M 卡都要能挂回这条链。枢纽卡:M05.01 事前-事中-事后(法骨架)、错误预算三角(M05.10→M09.12→M11.01)、发布三角(M05.11/M06.06/M09.05)。道 29 · 法 50 · 术 55 · 势 11(见上表)。
本库不是 22 篇平行说明书。篇章(C)与 AI 工程纵深(A)、核心原理(E)、场景(S)、垂直领域(D)是器与术的领域切片——A/D 为独立专篇轴,计数并入题目总量;工程化(G)是门禁化的器;踩坑(K)是器失效的反例;方法论(M)提供可挂载的道/法/术。读一篇 C/A/D 而不回 M,知识是点;只背 G 清单而无 M05.01,是以器代术、以术代法。设计阶段先取法卡立 ADR,实现阶段只带已引用的术/器卡号。
来源对照:深度 Q&A 篇章 C 252 + AI 纵深 A 74 + 核心原理 E 74 + 场景 S 74 + 垂直领域 D 72 = 题目总量 546;其中篇章+A 合计 326。
| 层 | 问什么 | 本库落点 | 判据 |
|---|---|---|---|
| 道 | 信什么 / 为什么 | M01–M02(29) | 换行业仍成立 |
| 法 | 按什么骨架做 | M03–M07(50;R2 另含 M12) | 能画阶段/责任表 |
| 术 | 这一招怎么打 | M08–M15(55;R2 不含 M12) | 要调参、有取舍 |
| 器 | 用什么固化 | G 八组门禁 · K 八组事故 · C01–C15 / E / S | 能安装、能替换 |
| 势 | 何时下手 | 横贯:规模、事故窗口、组织共识、技术周期、业务节奏(M01.05 / SLO / 大促);势定律收口见 M16 | 阻力来自人与时机 |
| 合计 M | 145 = 道 29 + 法 50 + 术 55 + 势 11 | ||
十六组卡数(组头另标):M01–M16 如下。
| Module | 卡 | Module | 卡 |
|---|---|---|---|
| M01 第一性 | 16 | M07 分布式 | 4 |
| M02 日常思维 | 13 | M08 高并发 | 11 |
| M03 设计原则 | 7 | M09 高可用 | 14 |
| M04 领域风格 | 3 | M10 高性能 | 8 |
| M05 工程决策 | 25 | M11 变更纪律 | 3 |
| M06 运行时原则 | 11 | M12 Java 生态 | 6 |
| M13 安全 | 5 | M14 AI 工程 | 1 |
| M15 排障与复盘 | 7 | M16 势定律 | 11 |
器侧八组门禁见工程化;势的五个横坐标:规模、事故窗口、组织共识、技术周期、业务节奏(5)。M13 安全 5 卡已在组头。G 组数对照 8。
工程能力知识库"] KB --> DAO["道 M01–M02"] KB --> FA["法 M03–M07"] KB --> SHU["术 M08–M15"] KB --> QI["器 G · K · C/E/S"] KB --> SHI["势 横贯时机与规模(定律收口 M16)"] FA --> SHU SHU --> QI SHI -.加速或阻断.-> FA SHI -.加速或阻断.-> QI style KB fill:#f3e8ff,stroke:#7c3aed style DAO fill:#dbeafe,stroke:#2563eb style FA fill:#dcfce7,stroke:#059669 style SHU fill:#fef3c7,stroke:#d97706 style QI fill:#e2e8f0,stroke:#475569 style SHI fill:#ffe4e6,stroke:#e11d48
节点计数:道 29 · 法 50 · 术 55 · 势 11
贯穿全库的心法可凝成八字——抽象、边界、权衡、演进。它们是递进元动作,不是并列技巧:抽象剥噪声、留决策模型;边界定职责与依赖方向;权衡在约束下写明放弃项与回退;演进在量级失配时再开循环,并把技术债记入 M05.05。映射到主题:吞吐抽象瓶颈再拆分,可用划故障域,性能在层次链上权衡,安全与排障在演进中守底座。M05 决策、M06 运行时、M11 变更闸门、M14 AI 纪律把证据、回滚、幂等、对账、评测收成可引用条目,避免口径散落在篇章。
八字与五维架构思维——全局、分类、分层、抽象、变化——同构:抽象≈全局+抽象,边界≈分类+分层,权衡≈约束下取舍,演进≈变化。读法固定为道→法→术→器,势横贯:道给世界观,法给骨架与责任表,术给招式与调参,器给可安装门禁;势回答「现在能不能做」。高级到架构的跃迁,是能从术回溯到法与道,而不是多背几张组件图。
| 八字 | 五维 | 本库落点 |
|---|---|---|
| 抽象 | 全局 + 抽象 | M01.03 抽象与系统思维 |
| 边界 | 分类 + 分层 | M02.02 边界思维(高内聚低耦合) / M03.03 高内聚低耦合与关注点分离 |
| 权衡 | 约束下取舍 | M01.04 取舍思维 |
| 演进 | 变化 | M01.05 演进思维 / M05.05 技术债管理 |
同一词跨层:三例竖切
权威树按主锚放卡;同一词可以同时是道、法、术、器,势决定何时下手。三例只示范读法,不穷举:隔离、回滚、容量预算、可观测也是同一词跨层,落到对应主锚卡。
- 事前-事中-事后:道 M01.02 稳态与闭环反馈 → 法 M05.01 事前-事中-事后 → 术 M08.11 高并发设计流程 / M09.14 高可用保障流程 / M10.08 性能优化流程 / M15.07 线上问题处理流程 → 器 G01 发布 / G02 可观测 → 势:事故窗口能否立法。
- 防抖 / 稳定窗口:道 M01.02 稳态与闭环反馈 → 法 M06.02 迟滞阈值与稳定窗口 → 术 熔断半开 / TTL → 器 G03.08 HPA 冷却 → 势:扩缩震荡窗口。
- 灰度 / 可逆发布:道 M01.05 演进思维 → 法 M06.06 回滚优先与安全发布 / M09.05 安全发布方法论 → 术 金丝雀 → 器 G01.01 / G01.05 → 势:错误预算未破才放量。
四种错位
| 错位 | 样子 | 纠偏 |
|---|---|---|
| 以道代法 | 只喊闭环、取舍,画不出阶段表 | 落到 M05.01 事前-事中-事后 / ADR |
| 以术代法 | 直接上熔断参数,没有稳定窗口规范 | 先 M06.02 迟滞阈值与稳定窗口 再调参 |
| 以器代术 | 只背 G 清单 / 堆 SDK,说不清招式取舍 | 先术再器;G 是固化不是思想 |
| 逆势而为 | 错误预算已破仍发不可逆变更;规模未到先上异地多活 | 看势的五个横坐标再动手 |
公理层两段共 16 卡。思维范式(M01.01–.07):第一性定方向;稳态与闭环定控制论信念;抽象 / 取舍 / 演进(加减元操作)/ 定性定量给决策语言;模型思维提醒「模型有用但都错」。经典约束(M01.08–.16):代价守恒、康威、Goodhart/Hyrum、反脆弱、阿姆达尔·Kingman·古斯塔夫森、Ashby/Lampson、局部性、复杂度守恒、熵增。技术债的账本在法侧 M05.05,本组只给熵增公理。织网:C01/C02 是资源竞争的器;八字里的抽象 / 权衡 / 演进主文在本组。
本组是整条链的起点:M01.02 稳态与闭环是控制论信念,向下贯通 M05.01 事前-事中-事后(法)、M08.11/M09.14/M10.08/M15.07 各流程卡(术)、G01/G02(器);向上承接八字心法的抽象/权衡/演进。九张定律卡可两两对照:代价转移(M01.08)与复杂度守恒(M01.15)同讲「没有免费午餐」,瓶颈上限(M01.12)与局部性(M01.14)同讲「约束在哪」。
架构判断先回到可证伪的公理,而不是清单。性能问题多数可归约为资源竞争或算法复杂度(CPU/内存/IO/锁/GC,或 O(n²) 这类不可靠堆机器消掉的代价);可用性问题多数可归约为故障域过大或恢复路径缺失——经典单点是其一,相关失效、级联饱和、变更炸伤同样致命。高并发、高性能、高可用相互制约:吞吐常以单请求代价换(切换、锁、一致性开销),可用常以延迟与成本换(复制、冗余、协调)。三角没有“都要”,只有当前业务优先保哪一维、容忍哪一维的代价。
工程主路径仍是两条:压缩竞争面(局部性/缓存、异步、无锁或细粒度锁、分片)与缩小故障域并缩短恢复(冗余、自动转移、降级、限流、隔离)。动静分离、读写分离、分库分表、微服务、多活,大多是这两条在不同层的投影;若改完既没减竞争、也没缩故障域,多半是在堆组件。
"找出单点 / 故障域"是可用公理的工程化;"进行拆分 / 压缩竞争"是性能公理的工程化——把 N 争 1 变成可并行的资源面。动静分离、读写分离、分库分表,每一级都在回答:竞争或故障域在哪,怎么切开而不只是加机器。
被问"高并发和高性能矛盾吗"时,用三维度制约模型回答:高并发通过池化、异步、分片提升吞吐量,但线程切换和锁竞争降低了单请求性能;高可用通过冗余和同步复制保障可靠性,但复制延迟增加了写入 RT。所以三者不是"都要",而是"在当前业务场景下优先保哪个、容忍哪个的代价"。比如电商大促优先高并发和高可用,容忍分析查询性能下降;金融交易优先高可用和强一致,容忍吞吐量下降。
故障是常态;无反馈的系统必然失控。稳定优先于瞬时响应:把噪声当信号、把尖峰当趋势,会把系统拖进振荡。道这一层只定方向——闭环必有反馈、预防优于救火、状态必须可预期——不写 debounce 参数。
控制论:感知→决策→执行→反馈。噪声≠有效状态变更。干预成本随时间上升(未病<欲病<已病)。Java 生产里对应:超时与饱和信号、错误预算、容量基线,而不是多加一台机器碰运气。
抽象与系统思维是架构师的元能力,包含两个互补的视角:抽象思维是"纵向剥离"——穿过界面、技术细节与时域噪声,聚焦问题本质,只保留对当前决策必要的模型。比如支付系统抽象出"交易""账户""风控"三个核心实体,再谈 UI 与协议;系统思维是"横向关联"——把系统视为相互作用的有机整体,追问"改这里的 A 会如何波及 B/C",而非孤立看待一个模块。二者叠加,架构从"画一堆组件"升维为"看清组件之间不可见的约束与因果"。
抽象讲究"度":抽象程度过低会被细节淹没(只见树木不见森林),抽象程度过高又脱离现实、无法指导行动。好的抽象应当分层层进——从业务概念到领域模型再到技术实现逐层剥离,只保留影响决策的关键特征,舍弃当前阶段无关的信息。检验抽象是否有效,看它能否解释多个具体案例、能否帮助预测与决策、还原到现实是否可操作。
在 Java 生态,抽象思维落到接口、抽象类、泛型、领域模型、DTO/VO/Entity 分层,本质是"把稳定契约对外、把易变实现隔离";尤其依赖倒置(DIP)——高层依赖抽象而非实现,让变化被挡住、本质被保留。系统思维落到DDD 的领域/子域边界(分形解构)、依赖方向的单向性、以及事务/一致性在组件间的传播路径——凡"高内聚、低耦合"的架构,都是在用边界隔离服务于"看整体"的代价可控。复杂度控制是它的执行面,而看到整体才是前提。
被问"如何设计一个业务系统 / 如何建模"时,先展示抽象:① 先命名核心实体与它们的关系,再谈选型;② 说清每个抽象层的职责边界(表现层只管交互、领域层只管规则、基础设施隔离外部依赖);③ 用系统思维补一句波及分析"这个改动会连带影响谁、为什么影响、如何隔离"。能把"实体一张图+波及一句话"讲清楚,与只堆框架名、背模式清单,是架构表达与实现表达的分水岭。
架构里没有银弹,每一个"优点"都对应一个"代价"。架构师的价值不在于知道某方案好,而在于能说清它放弃了什么。DNS 放弃一致性换高可用与分区容错;ClickHouse 放弃行存点查/事务便利,换列存聚合吞吐与近线性扩展;BASE 放弃强一致换可用性。单向吹捧某方案是噪声;讲清取舍、边界与回退条件,才是架构判断。
生产里到处是取舍:缓存不过期缓解了击穿,却把淘汰与内存上限变成新悖论;消息队列削峰解耦了写入,却引入丢失、重复、积压;K8s 高可用常只覆盖能集群化的部分,网关与流量洪峰仍是别层的单点。取舍不是口号,是把新问题写进方案。
回答任何选型题,必须给出三句话:选 A 牺牲了什么、选 B 牺牲了什么、我的场景为什么容忍 A 的代价。比如"WebFlux 还是 Web MVC"——WebFlux 换来了非阻塞高并发,代价是调试与排障更难、阻塞库兼容与线程模型心智更重;Web MVC 换来了开发效率,代价是线程阻塞下的资源浪费。当前团队 Java 21 + 虚拟线程可用时,Web MVC 可能是更好的选择,因为虚拟线程让同步代码获得了异步的并发能力。
取舍的守恒形态见 M01.08 代价转移与资源守恒:说清交换单纯形上哪一维在付账。
没有架构是初始设计出来的,都是被业务逼出来的。过度设计和不演进一样危险。架构师要能说出"现在到哪一步、下一步去哪、什么信号触发演进"。一个 10 万 DAU 的系统上来就异地多活,不是技术先进,是资源浪费;一个百万 QPS 的系统还在用单机 MySQL,不是技术克制,是事故预警。
演进的前置是识别系统的稳定部分与易变部分:稳定部分形成基础结构,易变部分保持相对独立、预留调整空间。为变化预留空间不等于预测所有未来、无限增加设计——只关注概率较高、影响较大且调整代价高的变化,用模块化、低耦合、可替换的方式提高适应力。
演进的两种元操作:加法叠能力(副本、缓存层、校验层换能力),减法熵减(解耦、裁剪、删并、YAGNI 降复杂度)。二者方向不同——加法换能力(容量、韧性),减法换清晰(复杂度控制见 M02.01 复杂度控制思维、边界清晰见 M02.02 边界思维);两套动作同在守恒框架内搬运复杂度(见 M01.08 代价转移与资源守恒 的「分合增减转」)。决策时先问「这一步是加还是减、换来了什么」。可逆决策快决、不可逆决策慢决(双向门);ADR 是记录器,可逆性才是决策法。组织侧见 M01.09 组织与沟通结构。
典型数据面演进路径不是上来就异地多活:单机扛不住→动静分离→读写分离→分库分表→分布式存储→地域拆分。每一级解决上一级新单点,性价比递减、容量与运维复杂度递增;跳级往往是成本与事故的叠加。
被问"你会怎么设计"时,给出分阶段方案:当前量级用 A,3 倍量级演进到 B,10 倍量级演进到 C,并说明触发信号(如 QPS 阈值、数据量阈值、延迟阈值)。比如设计微博 feed 流:当前用推模式够用,但用户粉丝破百万后推模式写放大严重,届时演进为拉模式或推拉结合。这一句"演进路径"就是架构思维和高级开发的分水岭。
讲演进路径时用加减开口:早期加副本扛量(加),体量到阈值抽公共能力(减/合),尾期下线与归档(减)。一句"先加能力后减熵"比堆组件清单更像架构判断。
定性定方向,定量定程度。定性回答「是什么、该不该、行不行」——架构合理性、风险识别、方案对错(如:本地锁不能用于集群环境,必须上分布式锁,这一步不需要压测数据,属于定性结论);定量回答「有多少、差多少、值不值得」——RT/TPS/QPS、GC 停顿、覆盖率、成本与告警阈值(如:RT 从 800ms 降到 120ms,量化收益)。定性先行:没有定性判断,定量数据毫无意义——方向错了,数字再好看也没有价值(TPS 很高但存在数据一致性漏洞);定量收尾:只有定性就成了经验主义的「我觉得慢」,无法衡量收益、容易过度优化。
双轮驱动六步闭环:① 定性分析锁定方向与风险 → ② 定量测量现状基线 → ③ 定量设定目标(RT 降 50%、FullGC ≤ 1 次/天)→ ④ 落地改造 → ⑤ 定量验证效果 → ⑥ 定性复盘(有没有引入新问题、架构是否变得更复杂)。定量侧的「测量→假设→实验→验证→回归」五步是中间的执行引擎(见 M10.08 性能优化流程),定性在两端把关:开头定方向、结尾防「指标达标但架构劣化」。
双短板对偶:定性的反面是经验主义(凭感觉、拍脑袋、无法证伪);定量的反面是被数据欺骗(指标可达成但方向性错误、局部最优掩盖全局问题)。二者互为对方漏洞的补丁,缺一不可。
被问「怎么优化慢接口 / 要不要重构 / 如何选型」:先定性(读多写少才适合缓存、一致性风险在哪、重构方向对不对),再定量(基线 RT=720ms、DB 占 650ms;目标 200ms),落地后定量验证(130ms),最后定性复盘(缓存与 DB 不一致、过期雪崩隐患)。反例:❌ 只定性「系统慢了就加 Redis」是盲目优化;❌ 只定量「RT 降到 200ms 达标」却没分析穿透与一致性,是在埋故障。
成长三阶段自检:初级只看定量(调参战士,堆参数改配置看报错);中高级定性变强但易经验主义、拍脑袋决策;架构师定性定方向、定量定程度——先保证大方向不走偏,再用数据证明收益、控制成本。与取舍思维(M01.04 取舍思维)、数据驱动思维(M02.06 数据驱动思维)互补:取舍给出定性判断的价值框架,数据驱动给出定量侧的度量纪律,本卡把二者拧成一条决策流水线。
所有模型都是错的,但有些有用(乔治·伯克斯 / Box)。架构图、容量估算、性能模型、SLO 都是对现实的近似,不是现实本身。把"理论吞吐"当"实际容量"、把"图上的调用"当"运行时的依赖",是架构师最常见的认知陷阱。
模型是决策的脚手架而非结论:用定量模型(阿姆达尔 M01.12、利特尔定律)定方向,再用实测校准;明确区分"模型结论"与"实测结论",承认不确定性、预留误差预算。与 M01.06 定性与定量 同气:定量是定性的近似,模型是定量的简化。墨菲定律提醒(工程落点见 M02.03 故障前置)"模型没覆盖的失败模式必然发生",故模型外要留兜底。
被问"这架构能扛多少 QPS":先给模型估算(阿姆达尔/排队论),立刻补"这是模型、必须压测校准",并说明误差来源(长尾、慢调用、GC、热点 key)。架构图是沟通模型不是部署契约;复盘时区分"模型错了"还是"现实变了"。反例:❌ 拿理论 TPS 直接承诺容量、❌ 把 C4 图当运行拓扑、❌ 用"上次也行"代替本轮实测。
系统里没有免费的收益。任何优化都只是把代价换了地方(时间↔空间、CPU↔IO、现在↔未来、本地↔远程)或换了人付(自己↔下游↔用户↔运维)。代价不会消失,只会被隐藏或延后。这是取舍思维的守恒律,不是又一套独立的「道」。
元动作可收成:分、合、增、减、转、换。加法叠能力(副本、缓存层、校验层);减法做熵减(删、并、YAGNI)。缓、批、异、隔是术侧展开,不在本卡写参数。
四象限都是同一守恒的实例:空间换时间(缓存、索引、预计算);时间换空间(压缩、懒加载、按需算);彼时间换此时间(预热、批处理、错峰、异步);彼空间换此空间(多级缓存、CDN、分片)。方案评审三问:谁付?何时付?付多少?与 M10.02 调优先定目标函数 是同一条法的两面。
被问「要不要上缓存 / 要不要压缩」时,先说转移了哪一维、谁在付账,再挂术:四象限实例见 M10.07 时空互换。具体 SDK/框架参数不在本卡展开。加法/减法作为演进操作见 M01.05 演进思维。
微服务 / DDD 常见失败根因之一是团队拓扑与服务边界错配——C10 已写过这句事故,方法论要把「组织即架构」立成道。平台工程、内部开发者门户、流对齐团队,是把沟通结构工程化的法;脚手架与 BOM 见 M05.02 黄金路径降低认知负荷。
被问「要不要拆微服务」时,先问团队边界、值班半径、接口所有权,再谈技术拆分。说得出「先逆康威还是先拆库」比背组件清单更接近架构判断。领域切片见 C10。
Goodhart:指标一旦成为目标就不再是好指标。SLO、错误预算、KPI 没有这条解毒剂,必然被博弈。Hyrum:凡可观察行为终将被依赖——这是旧接口改不动、必须契约测试与弃用窗口的底层原因。
数据驱动(M02.06 数据驱动思维)回答「看数」;本卡回答「数会撒谎、行为会被寄生」。错误预算政策见 M09.12 SLO 与错误预算 / M11.01 变更可回滚与错误预算;配置与代理契约见 M12.06 Spring 代理边界与配置契约。灰度与兼容是 Hyrum 的术,不在本卡写发布参数。
被问「如何用 SLO 管变更」时,先说燃尽则停功能开发,再说数字;被问「这个内部字段能不能改」时,先问谁在观察它。本卡讲指标异化与可观察依赖,不展开埋点实现细则。
「反脆弱」(Taleb)指系统能从冲击、波动、无序中获益并成长,强于「坚韧/鲁棒」仅能抵抗冲击。系统分三类:脆弱(错则崩)、坚韧(扛住)、反脆弱(越挫越强)。架构上要把故障演练、复盘、混沌、小步试错设计成系统的养分,而非单纯防御。
与 M02.03 故障前置(防)互补为「养」——前置降发生概率,反脆弱提恢复后更强,类免疫(适度暴露换长期抗体)。工程对应:混沌工程常态化、错误预算燃尽倒逼可靠性投资、blameless 复盘改进项闭环,让每次事故都提升系统而非只填坑。
被问「如何设计高可用」时,不止答冗余与熔断,要补「让系统从故障中变强」:定期混沌演练、blameless 复盘、用错误预算当可靠性闸门。避免把系统养成「从未出过事所以脆弱」的温室——零事故可能只是没被检验。
加速有上限。阿姆达尔定律:整体加速受限于必须串行的比例(即使 99% 并行,1% 串行上限约 100 倍)。古斯塔夫森:问题规模可随并行扩大,弱加速更现实。Kingman 公式:队列等待随利用率与方差非线性恶化(ρ→1 时等待趋无穷)。三者是并发与性能的数学地基。
阿姆达尔定调「先找串行瓶颈」;古斯塔夫森定调「用更大问题喂满并行」;Kingman 定调「留余量、控方差」。高并发章节(M08)每条优化都可回溯:缓存降串行比例、分片扩并行规模、限流与背压控利用率防排队爆炸。
被问「加机器为啥没线性提速」时,用阿姆达尔回「有串行临界区/锁」;被问「CPU 才 70% 就开始排队」时,用 Kingman 回「利用率高+请求方差大→等待非线性上升,需限流/降方差/留余量」。把定律当解释框架而非背公式。
Ashby 必要多样性定律:控制系统多样性须≥被控系统,否则失控(「只有猫的复杂度能管好老鼠」)。Lampson 机制-策略分离:把稳定的「机制」(能力/原语)与易变的「策略」(规则/配置)分开,让同一机制承载多变策略。二者是弹性治理与框架设计的底层依据。
必要多样性解释「为何单一网关规则压不住千面流量」——需分层防御(限流/熔断/降级/鉴权各管一类);也解释平台须提供足够「原语」让团队自组合。机制-策略分离解释框架为何给 SPI/拦截器/配置而把业务规则外置:机制稳、策略活。
被问「框架怎么设计才灵活」时,答「机制下沉、策略上浮」:稳定能力做内核,变化规则走插件/配置/DSL。被问「告警这么多还漏事」时,答「多样性不足,单维监控压不住系统复杂性,需多信号交叉(指标/日志/链路)」。
局部性(Denning 1968):时间局部性(近期访问的近期再访)+空间局部性(相邻数据将被访问)。「数据离计算越近,性能越高、容量越小」是高性能第一原则。缓存、预取、批处理、寄存器、CDN 都是局部性的工程化。
是 M10.04(术层局部性应用)的公理层。每一层存储都是「速度 vs 容量」取舍(CPU L1→内存→SSD→磁盘→网络,每远一层延迟高一个数量级)。架构师的性能优化本质是在层次链上把热点往上层推;B+ 树叶子链表利用磁盘空间局部性即例证。
被问「怎么优化性能」时,先讲局部性而非直接甩缓存:把热点数据放回上层(缓存/内存/本地),把相邻访问批量(预读/批处理),避免跨层抖动。挂术层 M10.04 讲具体实现,道层只立「近则快」这一不变量。
Brooks 本质复杂度不可消灭,只能转移、拆分、隐藏。任何「简化」都是把复杂度搬了地方(ORM 把 SQL 复杂度藏进映射,微服务把单体复杂度搬成分布式复杂度)。M01.08 代价转移是其应用面,本卡立「守恒」公理本身:世上没有免费的结构。
与熵增(M01.16)互补——守恒说「总量不变」,熵增说「不清理由有序走向无序」。二者共同约束架构师:不能消灭复杂度,只能选它待在哪、由谁付账、是否可控。抽象、分层、封装都是「把复杂度收拢到一处」的守恒操作。
被问「上 X 框架是不是更简单了」时,答「只是把复杂度从你的代码移到框架与运维」,再估转移后的总账(学习成本、调试黑盒、升级负担)。架构评审时问「这个复杂度被消灭了,还是被藏到哪了、谁在付」。
系统必随迭代走向耦合腐化——新增需求搭便车改旧代码、临时分支久不合并、告警被习惯性忽略,有序度持续下降。这是技术债管理(见 M05.05 技术债管理)的底层依据:技术债是熵增的显性化。
对抗熵增靠持续治理:定期重构(偿还债息)、防腐层隔离变化、契约测试锁边界、删死代码做熵减(M01.05 演进的减法)。热力学第二定律在软件的体现:不投入能量(治理成本),系统必然退化成「大泥球」。
被问「为什么老系统越来越难改」时,答「熵增,没人持续付治理能量」;被问「怎么防止」时,答「把熵减做成常态:每迭代留 10–20% 还债配额、CI 卡复杂度/覆盖率、定期架构审视」。治理是持续能量注入,不是一次性大重构。
日常认知 13 卡:控复杂度、划边界、故障前置、二八优先级,再落到业务 / 数据 / 成本;后半是协作与估算纪律(布鲁克斯规模律、邓宁-克鲁格、汉隆、侯世达、帕金森、惠顿)。邓巴细节归 M16.02。织网:边界→M03.03;故障前置→M06.01 / M09.03;成本→G03。八字「边界」主文在 M02.02。
M02 把道从公理层下沉到日常判断:边界思维(M02.02)是 M03.03 高内聚低耦合的思维母题,故障前置是 M06.01 面向失败、M09.03 术的源头;业务/数据/成本/规模四视角与 M05 工程决策、G03 容量、K 事故反例一一呼应。日常思维不产招式,但决定招式往哪打。
软件最大的敌人是无序增长的复杂度,控制复杂度是高级与初级之间最大的鸿沟。手段:拆分、抽象、封装、隔离、约束。本质复杂度不可消灭(没有银弹),只能转移、拆分、隐藏。能简单绝不复杂;必须复杂时,把复杂收拢到一处,不让复杂度扩散。核心是识别"稳定点与变化点"——从共性中提取抽象,保留扩展点应对变化。
分而治之把大系统拆小、大方法拆小函数;信息隐藏让模块内部细节对外不可见;正交性保证"改 A 不影响 B"。复杂度不是被消灭而是被管理:每个模块的复杂度上限可控,依赖路径是可数的。抽象与建模是配合手段——识别实体、流程与变化点,而不是直接堆代码。
被问"怎么面对复杂业务"时,回答"先拆维度、再收拢复杂度":按业务域拆分、每层只暴露最少必要接口、把脏逻辑封装成黑盒、用分层约束依赖方向。追问时举例:状态用枚举而非魔法值、条件用策略而非 if-else 堆叠。能说出"哪里复杂、为什么必须复杂、怎么不让它扩散"就是答案。
模块、服务、类、方法都要有清晰边界——什么该我管,什么不该我管。高内聚低耦合的本质就是边界清晰。遵循依赖方向:具体依赖抽象、外层依赖内层;稳定层不依赖易变层(易变可依赖稳定)。分清三类代码:领域内逻辑、外部依赖、胶水代码。
迪米特法则(最少知识)减少耦合;组合优于继承避免继承破坏封装;依赖倒置 + 接口隔离让边界可替换;六边形架构用端口把核心与基础设施隔开。Maven 模块化、ArchUnit 包约束守护依赖方向。边界不清的系统必然退化成"大泥球"——到处互相调用、改一处崩多处。
边界落到交互处就是契约思维:内部方法、RPC、HTTP 的接口都要明确入参、出参、异常、语义、版本,契约变更必须向后兼容。契约清晰让"谁管什么"真正可执行——边界不只是代码目录,更是可验证的接口规约。
被问"怎么划分模块或服务边界",先答"以职责和变更理由为界":一个类或一个服务只有一个变更理由(高内聚),对外只开必要插座(低耦合)。用依赖方向图自检:稳定模块不能依赖易变模块、不能有环。一句"边界清晰"能回答一半的模块拆分题。
法的落点见 M03.03 高内聚低耦合与关注点分离——本卡是道层信念,M03.03 是法层操作。
不要等线上出问题才补救,设计阶段就推演风险。分布式系统中网络、磁盘、时钟、第三方服务都可能失败;默认所有调用都可能超时、重复、乱序、丢失。每做方案先写风险点与应对策略:单点?一致性?流量突增?数据膨胀?回滚?降级?可观测?先问"这一步失败系统会怎样"。
前置是「防」;从波动中获益是「养」(反脆弱)。混沌工程是术,见 M09.13 混沌工程。
面向失败设计是分布式不确定性的回应——超时、重试、限流、熔断、降级、隔离;故障预演(混沌工程/故障演练)主动注入故障验证韧性;先恢复再根因、blameless 复盘。容错大于零故障:追求故障可控、影响面小、快速恢复,而非追求永远不出错。
被问"设计某系统",结尾必加"风险与兜底"段:单点冗余、一致性取舍、流量洪峰限流、变更回滚、凌晨三点靠什么日志定位根因。这一句"我先想了它会怎么挂"就直接把普通方案提升到架构方案。
补一条生产口径:混沌与故障演练是证明,不是可选项;「演练证明」优先于纸面容灾。
帕累托法则:多数结果由少数原因造成——20% 的缺陷导致 80% 的崩溃,20% 的功能贡献 80% 的价值,20% 的用户产生 80% 的负载。资源永远有限,平均用力等于重点失守。
用二八分布做优先级与止损决策:先打高频崩溃、聚焦核心链路、保护头部用户;区分"重要"与"紧急",不让长尾低影响项挤掉关键路径。与 M02.06 数据驱动(用数据找那 20%)、M02.07 成本思维(投入产出比)互补——二八定"打哪",数据定"打多狠",成本定"值不值"。
被问"需求/缺陷太多怎么排":先按影响面×频率二八切,先修高频崩溃(Top 崩溃聚类)、先做核心域链路、先保 P0 接口;对长尾低影响项设 SLA 下限而非逐一攻坚。反例:❌ 在长尾美化上耗光迭代、❌ 用"都重要"掩盖没有取舍、❌ 把精力压在老板看得见但影响面小的项。
技术是解决问题的工具,不是目的。先搞清业务痛点、约束、规模再选技术,而不是拿着技术找场景。反面是"技术崇拜":为了 React、Redis、MQ、微服务而强行改造业务。从业务模型、价值流、核心域/支撑域/通用域理解系统;用业务语言讲技术、用技术支撑业务。
ROI 导向——技术投入要有可衡量的回报;优先成熟开源方案降低机会成本。系统思维关注整体与关联性:数据库慢查询可能引发服务雪崩,需设计熔断隔离。业务思维与 DDD 统一语言一致,让技术方案直击业务痛点而非功能堆砌。
被问"你做过最有价值的架构决策",落点在"解决了什么业务问题、带来什么收益",而非"用了多新多炫的技术"。表述模板:业务痛点 → 约束 → 数据与边界梳理 → 方案 → 收益与成本 → 风险,以业务价值收尾。
不凭感觉猜性能、猜瓶颈;优先看现象、指标、日志、压测结论,而不是脑补。优化前先测量再定位,用数据说话。设计时先自问:数据量涨一百倍,这段逻辑还撑得住吗?抢先看清数据与热点,而不是等事故。
性能工程方法论"测量→定位→优化→验证";避免过早优化但要有性能预算与基准;容量评估靠数据而非拍脑袋。数据与状态思维:区分事实数据、派生数据、会话状态、缓存、持久化状态及各生命周期与一致性要求。
被问"怎么优化慢查询或性能",第一步永远是"先看监控与 Profiler 数据定位瓶颈",而不是直接改代码。追问时给出量化闭环:基线 → 假设 → 验证 → 回归基准,证明收益可度量。这体现你不是凭经验瞎调。
与篇章导读中的「证据优于经验 / 数据说话」对齐:离线指标与线上抽样双确认,拒绝感觉驱动放量;调参与 AI 放量同此纪律。
指标成目标即失效(Goodhart),解毒见 M01.10 度量异化与可观察依赖。
架构决策要算全成本:开发成本、运维成本、机器成本、人力成本、时间成本、机会成本。不是技术越新越好,而是"合适的技术解决合适的问题"。一个方案再好,团队驾驭不了就是坏方案;学习成本与维护成本是隐性成本。
成本复杂度 vs 业务收益的权衡;合适技术适配规模与团队;避免过度设计(YAGNI)与为假想未来堆栈。成本思维让架构"可回退、可解释",建立同等级别人的"控成本"意识,而非炫技。
被问选型,必答"为什么不用更重的方案":规模与团队不支持微服务时就选单体或模块化单体,并给出演进触发信号(如 QPS、团队规模阈值)。展示你在控成本而不是在堆组件,这是架构师与"技术狂热者"的区别。
机会成本与 TCO 要进账;云账单工程化见 C11.20 FinOps,不在方法论再开专卡。
人的规模律主锚是布鲁克斯定律:向已延期项目加人通常更延——沟通面近似 O(n²),新人先吸走老人产能。团队扩张不是线性产能;过阈值后沟通熵超过产出。协作半径的认知上限(邓巴数)是配套约束,细节归势侧 M16.02 邓巴数,本卡不复述 ~150 教条。
是 M01.09 组织与沟通结构(康威)的配套——康威说结构复刻沟通,规模律说沟通有容量上限。二者共同指向:用团队拓扑(流对齐/平台)与明确边界把沟通面压到可控,而非无脑加人。
被问「人多为啥反而慢」:先用布鲁克斯回「沟通面与教导成本」,再决定是否切边界/上平台;邓巴只作「认知半径是否已破」的二次检查(见 M16.02)。避免「加人救火」——延期项目加人常加速崩溃。
能力不足者往往意识不到自己不足;懂的越少越容易高估自己("愚昧山峰")。资深者也会陷入"熟练盲区"——因太熟而忽略边界条件。
与 M01.07 模型思维与认知谦逊 同源:模型都有误差,人也有认知误差。用代码评审、自动化测试、复盘会对冲个体偏差;保持"我知道我不知道"的开放,比"敢改一切"更安全。
被问"新人什么都敢改 / 估算过度自信"——用评审门禁、灰度发布、快速回滚兜住;自己也要定期请人挑战方案、做 retrospective。警惕拿"感觉能行"替代证据;认知谦逊是架构师可持续决策的地基。
汉隆剃刀:能解释为疏忽、信息不全或历史约束的,就不要先归因恶意。多数事故与「烂代码」来自认知负荷、期限压力、隐性约束,而非蓄意破坏。恶意要有证据;默认恶意会把复盘变成追责会,系统问题永远修不到。
与 M02.03 故障前置、M02.07 成本思维 同气——先假定善意再查根因,对事不对人;建设性复盘聚焦系统改进而非追责。
面对故障 / 烂代码,先问"当时为什么这样写"(约束 / 历史 / 认知负荷),而非归咎个人。减少内耗、提升团队可持续性;复盘产出"防再发的机制"而非"背锅名单"。
侯世达定律:即使把该定律本身算进去,事情仍往往更久。估算偏乐观,因为漏掉联调、环境、评审返工、依赖方延迟与「未知未知」。对策不是拍更长的死日期,而是区间估计 + 历史 lead time 校准 + 尽早切开未知。
与 M02.06 数据驱动、M02.04 二八优先级 同气——用历史周期时间(lead time)校准而非拍脑袋;缓冲 + 滚动规划吸收不确定性。
被问排期——给区间而非死日期,预留缓冲,用燃尽图 / 里程碑滚动修正;承诺前先拆最小可交付(MVP),让"未知"尽早暴露而不是堆到末尾。
帕金森定律:工作会膨胀到填满可用时间。排期越松,边角打磨越吞噬核心交付;没有时间盒,二八优先级也会失效。用小迭代、WIP 上限、明确「够用」定义对抗膨胀,而不是靠意志力。
与 M02.11 侯世达、M02.04 二八 同气——时间盒(timebox)、小迭代、WIP 上限制造紧迫感与节奏,让重点不被稀释。
被问"为啥迭代老延期"——用时间盒 + WIP 上限 + 小批交付;把"打磨完美"换成"先跑通再迭代";节奏比一次性完美更重要,延期项目靠加人只会更延(见 M02.08 规模律)。
惠顿定律(Wil Wheaton):别当那个破坏协作的人。技术收益建立在可持续关系上——对事不对人的评审、可升级的冲突路径、不把压力转成羞辱。文化护栏失效时,再好的架构也会被内耗拖垮。
与 M02.10 汉隆 同气——善意 + 尊重是工程文化地基;不专业的内耗会吞噬技术收益。
code review 与方案讨论中对事不对人,用"建议 / 质疑"而非"你错了";文化问题早建护栏(评审礼仪、冲突升级路径),它决定团队能走多远。
设计原则 7 卡:SOLID、DRY/KISS/YAGNI、高内聚低耦合与关注点分离是主轴;鲁棒性(Postel)、切斯特森围栏、哈特伯(Hutber)、自行车棚约束「改/评」行为。织网:C05 Spring;风格见 M04。边界原则落点 M03.03,与道侧 M02.02 成对。
SOLID/DRY/KISS 是法的词汇表:M03.03 高内聚低耦合是 M02.02 边界思维的设计层落地,也是 M04 整洁架构、M12 依赖方向的判据;DRY 与 M05.05 技术债同源(重复是债的前兆)。原则不解决具体问题,但让 M08–M15 的术有统一评审尺度。
SOLID 是面向对象基石:单一职责(一个类只有一个变更理由)、开闭(对扩展开放、对修改关闭)、里氏替换(子类可替换父类不破坏逻辑)、接口隔离(接口小而专一,不强迫实现不需要的方法)、依赖倒置(高层与低层都依赖抽象)。
目的都是降低变更成本:SRP 让变更局部化、OCP 用接口或抽象承接扩展、LSP 保证继承安全、ISP 避免胖接口、DIP 是 Spring 依赖注入的本质。落地靠设计模式(策略消灭 if-else、模板、装饰器)而非教条硬套——过度 SOLID 也会制造大量小类增加复杂度。
被问"SOLID 你怎么理解,会不会教条使用",先讲五条含义,再强调"降低变更成本才是目的,要结合业务规模权衡过度拆分"。给一个反例:为了单一职责把一个聚合操作拆成五六个类,反而更复杂。这展示你懂原则背后的动机。
DRY 不要重复自己、KISS 保持简单、YAGNI 现在不需要就不提前实现。很多线上 bug 来源于过度精巧的复杂实现。配套原则:组合优于继承、迪米特法则(最少知识)、最小惊讶(行为符合直觉)、显式优于隐式、约定优于配置(减少样板代码)。
复杂性是成本,简洁不是偷懒而是刻意取舍。DRY 的误用是强行合并不相关业务变成"大泥球";KISS 让人优先可读可测;YAGNI 拒绝为假想未来写大量代码,未来真需要再重构扩展。这三者是"简单工程"的理念共识,也是线上稳定的根基。
被问"你写代码最重要的原则",第一句回答"简单清晰优先,单一职责,高内聚低耦合,防御式编程,考虑异常与失败,便于测试和维护"。追问时用两个自检:改动是否只影响一处、新人能否秒懂。答案朴素但几乎覆盖所有代码质量的根因。
模块内部紧密相关(高内聚)、模块之间尽量少而薄的接口(低耦合),这是架构第一原则。关注点分离把不同变化原因的代码分开:业务、缓存、消息、数据库、校验各自独立,改一个不牵连另一个。
内聚=内部强相关,耦合=依赖度;迪米特、依赖倒置、接口隔离都服务于此;稳定依赖与无环依赖原则约束依赖方向。耦合不清会退化成"改 A 必动 B/C/D"的脆弱系统。这是所有拆分方法的底层理由。
被问"怎么提高可维护性",先答"高内聚低耦合 + 关注点分离",举例:支付与日志胶水分开、校验与业务分开、状态与数据层分开。追问时用"变更影响面"自检是否达标——改一处是否牵一发动全身。
道层信念见 M02.02 边界思维(高内聚低耦合)——同一件事的跨层参见,不重复展开。
波斯特尔定律 / 鲁棒性原则:对自己输出保守(严格合规),对他人输入宽容(可解析则解析)。协议与 API 靠它降适配成本;滥用「输入宽容」会变成静默吞错——宽容解析必须配可观测与明确错误语义,否则排障成本外溢。
与 M03.02 简洁三原则、M03.03 高内聚低耦合 同气——边界清晰;但宽容解析需有界,否则会掩盖发送方错误,与"隐式接口定律"冲突。
API 入参严格校验、出错明确拒绝(4xx);出参严格符合契约。现代实践更强调"明确拒绝非法输入"而非无脑宽容——非法输入进监控告警而非静默吞掉;宽容只到"能容错但不纵容"为止。
切斯特森围栏:弄清栅栏为何存在前,不要拆它。看似多余的校验、开关、兼容分支,往往是事故或合规买来的约束。先还原历史、威胁与依赖,再决定删、留或替换;盲目「清理」常把旧伤变成新故障。
与 M03.03 关注点分离、M02.10 汉隆 同气——现有结构是历史约束的产物;"顺手重构"易踩未知雷。
被要求删 / 改一段陌生代码——先追 commit / 文档 / 原作者问"为什么存在";用特性开关或绞杀者模式渐进替换,而非大刀阔斧一次性重写;改动前写清动机与回滚方案。
哈特伯定律:改善即恶化——局部改进常把代价挪到别处或藏进更难观察的层。缓存换延迟却抬一致性风险;抽象降样板却抬认知负担。评审要问「恶化转移到哪、谁付账」,与 M01.08 代价守恒同气。
与 M03.03 关注点分离、M02.06 数据驱动 同气——任何"优化"都要看全局副作用,不能只看单点指标。
做优化必配监控 + 回归测试兜住隐性退化;用 A/B 或影子流量验证收益真实;拒绝单点指标美化(指标成目标即失效,见 M01.10 度量异化)。
领域与风格仅 3 卡,刻意不堆招式:DDD 对齐问题空间与统一语言;模式给可共享词汇;整洁/六边形/洋葱约束依赖方向。织网:落 C05/C09/C10;招式仍回各术组。
DDD 划问题空间、模式给词汇、整洁/六边形/洋葱约束依赖方向——三者共同把 M03 原则变成可落地的模块边界。落点是 C05 Spring、C10 微服务;与 M12 Java 生态心智、M02.02 边界思维构成「边界三连」。架构风格选择本质是 M01.04 取舍:在耦合/复用/演化成本间定权重。
DDD 把业务语言映射成代码模型:限界上下文划清业务边界(微服务划分的重要依据之一)、统一语言消除沟通鸿沟、战术要素(实体/值对象/聚合/聚合根/领域服务/领域事件)让代码围绕业务而非数据库表。适用于复杂业务;小系统不要硬套 DDD 模板。
战略设计划分上下文与子域(核心/支撑/通用);战术设计落地领域模型;分层架构领域层→应用层→基础设施层依赖向内。DDD 不是一套类模板,而是"分析业务的思维",防止"大泥球系统"。C4 模型把架构分层表达:系统→容器→组件→代码。
被问"如何划分微服务边界",用限界上下文作答,而非"按技术栈或按人数";给出聚合根厘清对象归属;强调统一语言拉通业务与开发。追问时补 C4/4+1 视图,展示你对"架构表达"有多维度理解。
23 种经典设计模式是词汇表不是教条——识别重复问题后选合适方案,而不是套模板。重构是日常行为,不是项目结束后的专项:识别坏味道、小步重构、用测试保护。Code Review 文化让缺陷前置发现、风格统一、知识共享。
设计模式消除重复问题的样板;重构的安全依赖自动化测试护网与"红-绿-重构"循环;坏味道(万能大类/大方法、copy-paste、过深嵌套、switch 分发)是重构触发器。组合优于继承,Java 8+ 函数式接口 + 默认方法可实现轻量策略。
被问"讲一个你用过的设计模式",不要只报名字,给"遇到什么问题→为什么选它→代价是什么"三段式。追问重构经验,强调"小步 + 测试保护 + 每次只改一处并提交"。能讲清模式的代价,说明你真的用过而非背题。
三者同一核心:业务核心不依赖框架、数据库、Web 等外部细节;依赖规则外层依赖内层,内层通过接口定义端口,适配器实现端口。换数据库、换 Web 框架、升级依赖,都不影响核心业务模型。业务逻辑是主角,技术细节是配角。
依赖倒置让依赖方向可控——实体与用例在最内层,接口定义端口,适配器在最外层;模块化 + 包约束(ArchUnit)守护依赖方向;可测试性源于核心不依赖外部(可注入桩)。这正是"依赖向内、细节向外"原则的工程化。
如何表达这套架构:C4 模型按"系统上下文→容器→组件→代码"四层递进描述,4+1 视图从逻辑/开发/进程/物理/场景五视角刻画,二者与整洁架构配合,把"依赖方向正确"落成看得见、讲得清的架构文档。
被问"业务代码为什么要分层 / 要不要用整洁架构",回答核心思想 + 适用前提:复杂业务值得,简单 CRUD 属于过度设计。落地口径:先写业务用例接口,再补外部适配器,依赖方向一律向内。重点讲"为什么"而非"怎么搭"。
工程决策与演进共 25 卡,三段地图:① 骨架 M05.01–M05.07(事前-事中-事后、黄金路径、ADR、TDD、技术债、并发三性总则、快环/可逆);② 运营闸门 M05.08–M05.14(事件/IC、错误预算政策、发布决策树、变更分级、迁移四步、退役);③ 规模化治理 M05.15–M05.25(数据/需求/测试/FinOps/拓扑/ATAM/绞杀/兼容/DevOps/左移/治理)。织网:预算执行 M11.01;SLO 度量 M09.12;发布策略 M09.05;流程挂 M05.01。
M05 是法侧枢纽:M05.01 事前-事中-事后是贯穿全库的流程骨架,被 M08.11/M09.14/M10.08/M15.07 术卡挂接;黄金路径(M05.02)降认知税;ADR(M05.03)留决策痕;TDD/BDD(M05.04)是可测性实践。后半组(M05.08–M05.25)是运营闸门与规模化治理。M05 是「法→术」转接口:任何术招式都能回 M05.01 找位置;技术债(M05.05)是演进账本,连回 M01.05 与 M16 势信号。
把连续时间流切成三个责任区:事前防、事中控、事后改。它不是某项技术,是可迁移的过程骨架。没有这根梁,熔断、灰度、复盘只是散落的术——典型「以术代法」。
事前:预案、评审、容量、演练、门禁。事中:告警可行动、止血、熔断/限流/降级、变更冻结。事后:根因、改进项闭环、案例入库。每段要有责任人与产出物;信念层见 M01.02 稳态与闭环反馈。
关键架构决策要成文,四个要素:背景(为什么需要)、决策(选了什么方案)、取舍(优缺点分析)、结果(预期效果)。让"为什么这样设计"的上下文留存,后人不用靠猜。
ADR 是可回溯的决策资产,与演进式架构互补;C4 把架构分层表达(系统→容器→组件→代码),4+1 从逻辑/开发/进程/物理/场景五视图描述。把它们合起来就是"架构即文档化"的工程方法。
被问"你如何做架构决策 / 怎么积累架构经验",用 ADR 范式作答:每个选型写一张决策卡,记录备选方案、取舍与结果复盘。追问时给一张卡片示例。这体现你决策有纪律、经验可沉淀,而不是凭感觉拍板。
TDD 红-绿-重构:先写测试再写实现,用测试定义行为边界;BDD 用业务语言描述行为,拉通业务、开发、测试。工程实践:CI/CD 流水线(提交即构建测试部署回滚)、DevOps/SRE(You build it, you run it)、Feature Toggle(灰度/AB/快速回滚)、敏捷/精益/看板(快速交付价值、限制 WIP)。
失败用例定义行为边界 → 最简实现 → 重构;测试是设计反馈环,大量 static、硬编码依赖难以被测试,本身就是坏味道。小步提交 + 自动化一切 + 持续改进内建质量;可测试性优先——代码容易写单测,往往设计就不差。
被问"如何保证质量",回答测试分层(单测/集成/契约/E2E)+ CI 门禁 + 小步提交 + 代码评审。追问时说明"可测性差通常反映依赖设计差",可用来反驳"没空写测试"。别把 TDD 说成宗教,说成工程纪律。
技术债(Ward Cunningham 提出)不是"坏的代码",而是为了换取短期交付速度而暂时放弃的长远质量代价。它像金融债务一样会复利:借钱本身没错,错的是"借钱无记录、无期限、无成本意识"——第一次改动绕过旧坑还行,第十次绕坑时成本已远超当初省下的时间。架构师的关键不在于"消灭技术债"(那等于停止交付),而在于显式管理技术债:让每一笔债都入账、可量化、有偿还计划,而不是让债在暗处利滚利。
用 Fowler 四象限区分债的性质:有意的谨慎债(明知有更好方案但快速交付,最健康)> 无意的谨慎债(被业务快速变化逼出,次优但诚实)> 有意的鲁莽债(明知坑还冲,高风险投机)> 无意的鲁莽债(根本没意识到在欠债,最危险——这种团队往往直到事故才惊醒)。管理的首要行动是让"无意的"变"有意的",让债从暗处摆到台面上。
技术债的典型形态:强耦合(改 A 要动 B/C/D)、copy-paste 代码(一份逻辑多处维护)、加层绕过而不修根(打补丁堆叠)、死代码与孤儿系统(没人敢删的配置/接口)、脏数据(缺校验埋下的坑)、过时依赖(绿债,升级成本随时间指数增长)。每笔债都降低"可演进性"——而可演进性正是架构师的核心资产。
偿还策略与"演进思维"闭环:先还高利率的债(改动最频繁、最脆弱的耦合点),再还低成本的债;配合自动化测试做护网(重构不回归)、灰度发布做增量放量、架构治理守则(依赖方向、分层规范)防止借新债。原则是"每演进一步,先清理脚下的低息债,避免在错误的脚手架上继续盖楼"。
负债容量随阶段收敛:初创期可容忍更高「高利率债」占比(活下来优先),成长期收紧,成熟期须把事故级与高频改动路径上的债压到团队书面阈值内——用改动耗时/缺陷率等可度量口径,而非无定义分母的「代码百分比」。配合"男孩侦察兵法则"——每次修改代码留下比发现时更好的代码,让存量债随日常改动自然递减。
被问"你如何看技术债/接手一个全是历史包袱的单体系统"时,四步回答:① 分象限识债——先盘点哪些是"有意的谨慎债"(可缓)、哪些是"无意的鲁莽债"(高危,优先排雷);② 排出偿还优先级——先还"血债"(已导致或即将导致事故的债)和"改动最频繁处的债",余债进技术债台账;③ 用护栏保证还债不坏账——补测试护网 + 单元粒度的增量重构 + 灰度上线,向业务证明重构不打乱交付节奏;④ 量化还债回报——用"每周改动平均耗时下降 %、线上缺陷减少 %、回归修复时间缩短 %"向业务方要重构时间。最后强调一条红线规则:"借新债必须显式记录并定下偿还窗口,不允许无意识的欠债"。
系统自然走向无序(熵增);技术债是负熵账单。本卡管账本,守恒与熵见 M01.08 代价转移与资源守恒。
并发正确性的三个维度:可见性(一个线程的写对其它线程何时可见)、原子性(操作是否不可分割、不被打断)、有序性(操作的实际执行顺序是否被重排)。任何并发模型都绕不开这三性——先定性缺了哪一性,再选机制,比直接堆锁更可靠。
三性由内存模型与同步原语兑现:可见性靠内存屏障 / volatile 类语义;原子性靠互斥或原子指令(CAS / Lock-Free);有序性靠 happens-before 规则。这是语言无关的工程纪律;落到 Java 见 M12.01 并发思维 与 M12.02 先三性后原语。
被问并发正确性,先画三性与不变量:① 哪里共享可变状态 ② 缺的是可见 / 原子 / 有序哪一性 ③ 靠哪条顺序关系(happens-before)保证。三性分析先于原语选择——原语选错(如用 volatile 保原子)比写得慢更危险。量化锚点见 M12.02。
OODA(Observe-Orient-Decide-Act)是 John Boyd 提出的决策快环:观察→定向→决策→行动,再回到观察。它的威力不在"第一次就正确",而在用更短的周期压缩"感知-理解-决断-执行"——你不需要一开始就想清楚,只要环跑得够快,就能在行动中持续修正。线上故障、容量险情、攻防对抗的本质都是"时间竞争":谁先完成一轮 OODA,谁就掌握主动权。架构师的竞争力不只在于决策对不对,更在于决策快不快——在告警风暴里慢一拍,就是一次故障扩散。
四步各有工程抓手:Observe=可观测性三支柱(指标/日志/链路,见 M06.07)+ 实时态势板;Orient=用已知模型(容量模型/依赖拓扑/故障模式)把原始信号解释成态势,这步最吃第一性原理与系统思维(M01.01/M01.03),也是新手与老手的分水岭;Decide=在可逆/不可逆之间选路(配 M05.08 决策可逆性分层),优先选可回退的动作;Act=止损执行(限流/降级/切流/回滚,见 M06.01/M06.06)。每轮 Act 又成为下一轮 Observe,环自闭环。
与 M05.01 事前-事中-事后 互补:慢环建制度(预案/演练/复盘),快环救现场(战时应激)。慢环是快环的"训练场",快环是慢环的"检验场"——没有慢环,快环每次都从零开始;没有快环,慢环只是纸面流程。
被问"线上出问题你怎么决策",用 OODA 作答:先 Observe 拉全貌(影响面/错误率/依赖链/P99),再 Orient 判断根因方向(是容量、依赖还是变更引入),Decide 选最快止血路径(能回滚先回滚、能降级先降级,遵循 M11.01 变更纪律),Act 执行并持续 Observe 验证。强调"决策时延是竞争力":用决策时长 SLO 量化(如重大故障 5 分钟内出首个止损动作),把"反应慢"从感受变成可改进指标。
配合 M15.02 排障证据链(快环中沉淀证据)与 M05.09 事件指挥(多人并发时谁掌 OODA 环)。注意边界:OODA 是"战时"快环,日常选型仍走 ADR/评审慢环(M05.03),不要用快环替代需要审慎的 Type1 决策(M05.08)。
决策分两类:Type1 不可逆(删库、强一致数据迁移、对外契约破坏性变更),一旦出错代价极高、难回退;Type2 可逆(特性开关、灰度、双写回退),错了能撤回。用可逆性决定审批权重——不可逆要慢、审慎评审;可逆可快、允许试错。
把可逆性当设计目标:尽量用特性开关 / 双写 / 蓝绿把 Type1 改造为 Type2;评审资源向不可逆决策倾斜。与 OODA(M05.07) 配合——快环只在可逆域高速转,不可逆域走慢环评审。
被问"这个变更要不要评审",先判可逆性:不可逆→设计回滚预案 + 双人评审;可逆→自动化流水线 + 快速试错。实例:可逆化优先用特性开关/双写;DDL 用在线变更降低锁定风险,但删列/改类型等仍属 Type1,须可回退脚本与兼容窗,不能假定「在线」即「可逆」。
事故中的混乱多源于无指挥、信息不汇聚。设 IC(事件指挥)角色与固定沟通节奏(如每 30min 同步)把混乱变有序。事后用无责复盘(blameless)聚焦系统而非个人,才能拿到真因。
无责复盘五步:还原时间线→评估影响→定位根因→产出改进项→验证闭环;改进项必须带 owner + 期限 + 可验证手段,否则复盘无效。与 OODA(M05.07) 快环衔接——战时 Observe→Orient→Decide→Act(观察→定向→决策→行动)止损,平时复盘→加固。
被问"线上事故怎么处理",按 接警→IC 指挥→止损→无责复盘→改进闭环 作答;强调改进项要能复验(压测 / 演练),忌写"加强监控"这类虚项。
错误预算 = 1 − SLO。本卡立的是决策政策:预算是可消耗的可靠性额度,不是 KPI 排行榜。耗尽则冻结功能、转投可靠性——用「停功能」换稳定,避免反复踩线后口头追责。
灰度策略矩阵 = 维度(用户群 / 流量比例 / 地域 / 功能开关)× 推进节奏(金丝雀→分批→全量);与面向失败(M06.01) 配合——假设一定会出错,让错误范围可控。
矩阵把组织注意力投在不可逆处:可回滚的中危可缩短观测;不可逆或涉数据的高危即使「改动行数少」也走高危通道。审批强度、灰度粒度、观测时长、是否双人,是级别的函数,不是职级的函数。
被问「变更怎么管」,先画 3×3:影响面(单服务/跨服务/数据)× 可回滚(秒级/小时/不可逆)× 契约(无/API/事件/schema)。高危:双人评审 + 金丝雀 + 长观测 + 回滚演练记录;低危:主干绿灯即发。分级表要进 Runbook,避免口头「这次特批」。
数据迁移最易翻车。权威四步:双写(新旧并存)→ 对账(差异可解释并收敛)→ 切读(灰度读新)→ 停写(下线旧写)。无对账不切读;停写前保留可秒级回切窗口。流量染色与放量节奏见 M09.05,本卡只管数据面。
每步写清失败回退:双写失败停扩;对账差异超阈值不切读;切读异常率升则切回旧读;停写后旧链路保留只读至归档完成。
四步与 M05.21 绞杀者、M05.22 兼容治理配套:能力迁移常伴数据迁移;兼容窗口决定双写能开多久。对账工具链(抽样哈希 / 全量校验 / 差异工单)是可信前提。
被问「数据怎么迁」,按四步作答并给出:对账差异阈值、回切 SLA、与金丝雀百分比的职责边界(百分比在 M09.05)。本库统一双写→对账→切读→停写,禁止与「三步法」混用。
系统要有死法。退役不是迁移的简单逆操作:迁移保业务连续,退役消灭成本与攻击面。标准含:触发(调用量/成本/已有替代)、依赖审计、公告→只读→停写→下线、数据归档与合规留存、DNS/证书/密钥吊销清单。
下线前的「幽灵依赖」(暗链、定时任务、BI 抽数)比功能缺失更危险——必须用流量与配置扫描证明零依赖。
被问「旧系统怎么下」,按 触发判定→依赖审计→公告→只读→停写→归档→吊销→下线 作答;强调「有替代且零依赖证明」先于下线,并给出回滚窗口(发现幽灵流量可临时只读复活)。
治理降的是「数据不可信」熵:多源冲突、静默改字段、无主数据 owner。SSOT 消除口径战;契约让下游可规划;血缘支撑事故影响面;分层控成本与合规。
被问「数据怎么治」,按四支柱作答;追问时给一例:订单金额以结算库为准(SSOT),报表仓是衍生;字段改名走兼容窗,不是发版当天静默改。
不是所有需求都值得做。用需求分层(用户/系统/质量)澄清范围;用 RICE/WSJF 把「我觉得重要」变成可比较分数;用 MVP 切片最小验证,避免需求黑洞。
架构非功能(延迟、一致、合规)必须进分母:只算业务故事点会系统性低估可靠性与演进成本。与 M05.20 ATAM、M05.24 左移衔接。
示例(示意):Reach 0.3、Impact 3、Confidence 0.8、Effort 5 → RICE≈0.144;对比另一需求用同一公式说话。质量属性需求用「不做时的事故成本」进入 Impact。
被问「怎么排期」,按 分层→打分→MVP 切片→增量验证 作答;展示一张含非功能的评分表,而不是只排功能列表。
金字塔/trophy 控制反馈延迟:单测秒级、契约分钟级、E2E 慎重。环境与数据策略失败时,再多断言也是噪声。与安全左移(M06.11)共用 PR 门禁,但本卡管测试形状,不写威胁建模。
被问「怎么设计测试」,按 分层比例→契约边界→数据策略→性能预算→门禁时长 作答;强调 E2E 失败要能归因到层,而不是「再跑一遍绿了」。
成本是单位经济,不是事后账单。闭环:预算→计量→分摊→优化→复盘。用单请求/单租户/单交易成本找闲置与错误弹性;归因到服务与团队,优化才有 owner。与 M05.16、G03 容量对照。
可见、可归因、可优化三步缺一不可:只有账单没有分摊=无法问责;只有节省口号没有单位经济=砍错骨头。弹性伸缩要进成本复盘,避免「为 SLA 常开两倍机器」。
被问「成本怎么控」,给出单位经济公式示例(如 每千次 API 成本=(计算+存储+出口)/调用量),再谈闲置识别;优化项进迭代看板,有 owner 与验收指标。
架构边界追随团队边界(逆康威)。四拓扑:流对齐(端到端业务)、平台(自助能力产品)、复杂子系统(深领域)、赋能(短期嵌入)。平台工程把重复能力做成有 SLA 的自助产品,是 M05.02 黄金路径 的因;没有版本承诺的「公共库」只会制造等待。
认知负载与 M01.09 康威 呼应:拓扑是因,黄金路径是果。流对齐减少跨队同步;平台降低每条流的认知税;赋能防止平台变成新墙。
被问「团队怎么切」,按业务流选流对齐,把构建/观测/发布收成平台产品;复杂算法/支付内核可进子系统队。平台 KPI 是「自助成功率与等待时间」,不是「工单关闭数」。
ATAM 把质量从形容词变成可测场景:刺激→环境→响应→度量。用场景暴露权衡点与敏感点,再收成风险主题。没有数字的「高可用」不算场景。与开篇质量属性 × 生命周期自检互证。
示例:刺激=机房断电;环境=双活已部署;响应=5 分钟内切流;度量=RTO≤5min、数据丢失=0。敏感点可能是会话存储位置。
场景驱动迫使取舍显式化:要 RTO 就付双活成本;要强一致就付延迟。风险主题进 ADR(M05.03),避免评估会开完无落痕。
被问「架构怎么评」,按 质量场景表→权衡/敏感点→风险主题→ADR 作答;当场写一条带数字的场景,拒绝「系统要高可用」式空话。
旧系统忌大爆炸重写。绞杀:facade/网关引流 → 按能力切片迁移 → 旧模块退役。每步可独立回退。切片顺序优先「高价值低耦合」能力;数据面配合 M05.13;双写窗口靠对账,不靠感觉。
被问「老系统怎么换」,按 facade→逐能力切流→数据四步→下线 作答;强调「禁止绕过 facade 的暗链」与每能力独立回退开关。
寿命取决于向后兼容承诺:API / 事件 / 数据 / 配置四处都要管。用语义化版本表达边界;破坏性变更走 MAJOR + 弃用窗口(示意:至少一个发布周期,按消费者数量加长)。消费者契约测试锁住不兼容回归。与 Hyrum(M01.10)同气:被依赖的行为即契约。
渐进演进靠兼容窗,不靠强制升级日。绞杀与迁移(M05.21/M05.13)在窗口内完成双读双写;窗口结束才停旧。
被问「怎么演进不伤客户」,按 兼容承诺→semver→弃用公告与双轨→契约测门禁→关旧 作答;PATCH/MINOR 不得破坏已发布契约。
流水线是快环载体;部署≠发布,才能「随时可部署、按需放量」。DORA 四指标(前置时间、部署频率、变更失败率、恢复时间)度量效能,与错误预算联动可靠性投入。
被问「怎么提升交付」,按 流水线→部署/发布解耦→DORA 度量→错误预算联动 作答;避免把「站会」当成 DevOps 全部。
三线门禁:静态与单测(快)、依赖/密钥扫描(安全)、关键路径契约与冒烟(集成)。门禁超时与抖失败会逼人绕过——速度是质量策略的一部分。
被问「质量怎么保障」,按 左移三线→PR 门禁清单→与 ATAM 质量属性对照 作答;门禁失败必须可归因到文件/用例,而不是红一片。
运行时原则 11 卡:面向失败为根,迟滞/稳定窗口防振荡;隔离、无状态、自治、回滚优先、可观测三支柱;防御式编程与安全四原则 + 威胁建模门禁。安全招式在 M13,本卡只立法。织网:三板斧 M09.03;可观测用法 M15.05;HPA 冷却 G03.08。
M06 把面向失败(M06.01)作为运行时第一性,迟滞阈值与稳定窗口(M06.02)是 M01.02 稳态的定量版,回滚优先(M06.06)是 M01.05 演进的可逆落地。无状态(M06.04)直接决定 M08 水平扩展能否成立;可观测(M06.07)是 G02 与 M15 证据链的根。运行时原则是术招式的「前置约束」。
面向失败设计(超时、重试、限流、熔断、降级、隔离)是对分布式不确定性确定性的回应——失败不可避免,目标是失败快、影响可控、快速恢复。所有写操作尽量幂等以支持重试;下游消费不过来时上游要能感知并限速(背压)。
熔断避免对下游持续雪崩、降级保证核心链路优先、限流保护自身不被打垮、超时防止无限阻塞、重试+幂等容忍瞬态失败。容错大于零故障,这是故障设计方法论的主体。
被问"你怎么做系统稳定性",按"超时→重试幂等→限流→熔断→降级→隔离"层层递进作答,并强调每一层都要有兜底与观测。追问时给一个典型故障,逐一展示每一层的防御动作。
补强超时与重试预算:端到端可加总,重试有上限与抖动,防风暴;与「调用有预算」同构。
口径:本卡立总则——熔断/限流/降级/冗余的立法(为什么、各自防什么);参数化实践(算法选型、阈值、三级联防)见术层 M09.03 流量治理三板斧 与 M09.11 冗余与容错。
阈值附近的高频振荡会把故障放大:扩缩震荡、告警风暴、熔断抖动、配置连推。法是状态变更必须经过稳定窗口——迟滞、阈值、确认、缓冲、冷却、收敛。实现细节是术,组件是器。
迟滞(hysteresis)防止临界来回切换;确认/冷却合并短时重复事件;缓冲吸收突发。与面向失败(M06.01 面向失败设计(熔断/降级/限流))互补:那边是失败要降级,这边是「别把噪声当成失败」。
术/器参见:G03.08 HPA 冷却、熔断半开观察窗、流量三板斧、注册中心推送 debounce。具体 debounce/冷却参数下沉到术/器,本卡只定迟滞与稳定窗口。道见 M01.02 稳态与闭环反馈。
故障隔离、资源隔离、数据隔离——一个业务炸掉不拖垮整个系统。线程池/信号量隔离、进程/容器隔离、单元化/机房隔离。隔离让"爆炸半径"可控,配上限流把故障冲击面限制在局部。
无界队列与共享线程池是隔离的天敌;微服务本身是进程级隔离。故障隔离 + 服务自治实现"独立伸缩、独立故障、快速恢复"。依赖隔离(线程池、超时)是防"雪崩"的工程基础。
被问"怎么防一个服务拖垮其他服务",答线程池/信号量隔离 + 限流熔断 + 依赖超时。追问时给实例:某下游变慢导致上游线程池耗尽、请求全排队——用独立线程池与熔断把影响圈在局部。能画出"隔离边界"就是答案。
服务尽量无状态,便于水平扩容;会话/缓存/持久化状态下沉到 Redis 或 DB。共享可变状态是万恶之源——无状态让实例可任意加减、重启无副作用、故障直接替换。
状态外置(session 落 Redis、配置外置)让应用层幂等无状态;不可变对象优先减少并发问题;基础设施即代码 + 不可变基础设施让运维可版本化。这与"避免可变全局状态"是同一思想在不同层级的表现。
被问"水平扩容为什么难",大多结于"有状态":Web 层 session 存本地就无法多实例。答"无状态优先 + 状态外置"给出解法;追问时点明缓存与 DB 才是状态真正的归属地。这是高并发扩容题的标准开篇。
每个服务管理自己的数据,尽量不跨服务直接访问数据库(服务自治),避免强耦合。架构设计先梳理数据模型与数据流,再写接口(数据优先)——很多架构问题的根源是数据模型混乱。
数据是系统的核心资产:明确数据归属(谁的数据谁写)、生命周期与一致性要求;数据流先行决定服务边界。服务自治让故障、升级、扩容局部化,靠 API 或事件协作而非共享库表。
被问"如何划分服务依赖 / 要不要拆库",以数据归属与访问边界作答:先画数据流与数据模型再谈接口。追问时给反例:"两个服务共享同一张表是典型坏味道"。数据优先是区分"架构师思路"与"堆接口"的分水岭。
任何变更必须有回滚方案,不能只考虑成功路径。安全发布 = 可回滚 + 可灰度 + 可监控;上线必须安全、失败能快速还原。灰度发布、双写迁移、版本化让变更风险可控、演进可逆。
演进式架构的可逆决策:分库分表用中间件路由,便于调整分片策略;Feature Toggle 实现功能灰度与快速回滚;数据库迁移要向前兼容并有回退策略。回滚优先是"上线安全"原则工程化的落地。
可观测性三支柱:日志、指标、链路追踪。不是出问题才看日志,而是系统设计时就埋点;任何请求能追踪、任何状态能查询。凌晨三点报警响了,靠现有日志能不能十分钟定位根因。
指标(Prometheus/Grafana)看趋势、日志(ELK)看细节、链路(SkyWalking/OpenTelemetry)看关系,用 traceId 关联三者。可观测是架构设计之初就要考虑的,兑现"系统健康优先于功能完成"的工程观。
被问"系统出问题怎么排查",用三支柱作答:先看指标定位范围 → 看链路找到故障链路 → 看日志定位根因。追问时强调"埋点要提前设计而非事后补救",体现你把可观测当架构能力而非运维工具。
导读高频「可观测默认」:三支柱与服务同生,是交付标准;告警必须可行动并绑定 Runbook。
口径:本卡立三支柱信号之法——日志/指标/链路是系统必须产出的信号;三者的用法(谁答什么、成本梯度、交叉定位)见术层 M15.05 可观测性原则,两卡互引不复述。
UnknownHostException;TLS 看握手耗时与证书链;传输层看重传率与 RTT;应用层看 RT 分布与错误码。 资源上限:ulimit -n(FD)、连接池 max(≈ 下游可承受并发 × 0.8)、TCP backlog、TIME_WAIT 回收;泄漏信号:FD 30 分钟单调上涨、CLOSE_WAIT 占比 > 20%、池 waiting > 0 持续。代码不是跑在理想环境,要预判异常、边界、脏数据。入参校验、空防护、失败降级、超时、重试幂等、资源释放。不仅处理正常流程,重点思考:失败会发生什么、下游挂了怎么办、数据错了怎么办、并发乱了怎么办。默认不信任任何输入与外部调用。防御式编程是「把失败路径当一等公民设计」的工程纪律,与面向失败设计(见 M06 组)同源。
Fail Fast 前置校验与快速异常尽早暴露问题;不吞异常、不用异常做业务逻辑,区分业务异常与系统异常;资源用 try-with-resources 释放。防御不是堆 try-catch,而是把失败路径当一等路径设计——与面向失败、故障前置思维同源。
被问"如何写健壮代码",按四个防御面作答:输入(校验/占位)、组件(降级/兜底)、时间(超时/重试幂等)、并发(不可变/无共享状态)。追问时给实例:RPC 调用必须设超时、明确失败语义并加幂等键。把"会不会挂"挂在嘴边,就是防御式思维。
安全不是"加一层防线",而是四条可证伪的工程原则:最小权限(只给刚好够的权限,默认拒绝)、零信任(永不信任、持续校验,边界内也不豁免)、纵深防御(多层异构防护,单点失守不致命)、安全左移(在需求/编码/构建阶段就介入,而非上线后补)。这四条是"安全总则";落到 M13 安全 才是具体招式。架构师对安全的责任不是写加密代码,而是把四条原则变成系统设计约束——安全是"设计属性",不是"附加功能"。
四条彼此强化:最小权限→服务账号/角色/IAM 按功能最小化,密钥轮转、临时凭证、无长期静态密钥;零信任→mTLS、SPIFFE、每次请求鉴权,彻底弃用"内网即安全"假设,把信任从网络位置移到身份与意图;纵深防御→WAF+网关+服务网格+应用层校验+数据层脱敏,各层独立失效、互不信任;安全左移→SAST/DAST/依赖扫描进 CI、威胁建模在方案阶段,让前三条在成本最低处落地。
与 M06.09 防御式编程(输入不可信)和 M06.11 威胁建模(具体门禁)在法层呼应:本卡立"总则",M06.11 给"手法",M13 给"术式"。原则之间是乘法关系——任一条缺失,整体安全水位由最短木板决定。
被问"如何保证系统安全",先抛四原则框架再挂招式:最小权限见 M13 凭证管理,零信任见 C10.13 零信任/网关,纵深防御见 M09.03 流量治理 与 M13,安全左移见 M06.11 威胁建模门禁。强调能区分"会用 HTTPS"和"懂零信任的边界假设"是高级信号;可被追问时给一张"四原则自检表":每条原则当前由哪一层落地、单点失效会暴露什么。
安全不是上线前扫一遍,要威胁建模前置:用 STRIDE(欺骗 / 篡改 / 抵赖 / 信息泄露 / 拒绝服务 / 权限提升)系统性枚举威胁;再用左移门禁(SAST / DAST / 依赖扫描)在 PR 阶段拦截。
威胁建模把"攻击者视角"制度化;SBOM(软件物料清单)让依赖风险可见,漏洞按 SLA 分级修复;与安全四原则(M06.10) 配合——原则是目标,门禁是手段。
被问"安全怎么落地",按 STRIDE 建模→左移门禁(SAST/DAST/依赖)→SBOM + 漏洞 SLA→与安全总则(M06.10) 对照 作答;强调威胁建模在 design 阶段做,不是 code 完成后补。
分布式心智 4 卡:一致模型与故障域先行;缓存非源必付一致性代价;最终一致/Saga/TCC 是手段菜单;八大谬论防天真假设。术侧选型树见 M09.07 / M09.09,本组不写中间件参数。织网:C09/C11;缓存窗口→M10.05。
M07 先立一致模型与故障域(法),再让缓存(M07.02)付一致性代价、Saga/TCC(M07.03)成分布式招式;八大谬论(M07.04)是防坑清单。与 M09 高可用、M13 安全、M16.03 技术成熟度(选型避开过热)同属「跨节点信任」主题;康威定律(M01.09)在此表现为「服务边界≈团队边界」。
网络不可靠、时钟不可靠、消息可能重复、进程可能崩溃。分布式事务优先"最终一致、消息表、Saga、TCC"而非 XA;CAP/BASE 在一致性、可用性、分区容错间取舍,绝大多数互联网业务选最终一致。核心问:如果这一步失败,系统会怎样。
CAP:分区容错必然存在,只在一致性与可用性之间取舍;BASE:基本可用、软状态、最终一致 + 补偿。幂等、补偿、消息可靠性共同实现最终一致;12-Factor App 是云原生设计的方法论。服务调用必须有超时、重试、熔断、幂等。
分布式系统的八条错误假设——网络可靠、延迟为零、带宽无限、网络绝对安全、拓扑不变、只有一个管理员、传输成本为零、网络同构——在单机内几乎全部成立,一旦跨进程就逐条失效。防坑不是"更努力地保证可靠",而是把每一条假设改写成显式契约:超时与重试预算、幂等键、限流与熔断、零信任与最小权限、服务发现与拓扑刷新、跨团队接口与 SLA、序列化与流量成本、协议与版本兼容。核心问:这条链路上,我把哪一条谬论当成了默认前提?
八条谬论各自落到已建卡上:① 网络可靠 → 故障前置 M02.03 / 面向失败 M06.01;② 延迟为零 → 远程调用比本地慢 3~6 个数量级,须先定目标函数 M10.02;③ 带宽无限 → 序列化与传输量是预算项;④ 网络绝对安全 → 安全设计四原则 M06.10 / 纵深防御 M13.02;⑤ 拓扑不变 → 故障域与容量漂移 M07.01;⑥ 只有一个管理员 → 组织与沟通结构 M01.09 / 边界思维 M02.02;⑦ 传输成本为零 → 成本思维 M02.07;⑧ 网络同构 → 兼容与演进治理 M05.22 / 鲁棒性原则 M03.04。CAP 与 BASE 是八条的推论:承认分区与延迟必然存在,因此只能在一致性、可用性之间取舍。
架构评审把八条当清单逐条过:这条调用超时多少、重试几次、幂等键是什么、下游不可用时降级成什么、跨机房延迟预算多少、谁对这条链路负责。答不出即打回,与 M07.01 的一致承诺三问同源。
被问"分布式系统为什么难"时,用谬论清单回答——不是"网络慢",而是"我错误地把网络当成了可靠的、把延迟当成了零",并给出每条的显式对策;比背 CAP 定义更能体现工程判断。反例:❌ 只答"加熔断就好了"却说不清超时与重试预算、❌ 把"内网"当安全边界、❌ 认为跨机房延迟可以忽略。
吞吐 11 卡:拆分思维与顺序开路;异步、水平扩展、计划驱动;背压分「机制」(M08.06)与「契约」(M08.07);热点、负载分型、容量定律;M08.11 流程收口并挂 M05.01。织网:C04、C10、G03、K03。
M08 是术的入口:单点拆分开路(M08.01)即开篇「找单点·拆分」的工程化,拆分顺序/异步/水平扩展/背压/热点/容量(M08.02–M08.10)串成设计流程(M08.11)挂 M05.01。每招都回 M01 公理(资源竞争/单点)与 M06 运行时约束;容量(M08.10)连 G03 与 M16 规模势。
单点是系统中"一旦故障或达到瓶颈就影响全局"的资源。拆分的本质是把一个"大单点"变成"一个小单点 + N 个并行资源"——单点压力下降一个数量级,系统容量上升一个数量级。拆分可递归进行,直到单点不再是瓶颈。每一次拆分都在回答同一个问题:当前的资源竞争在哪,怎么把它拆开。
单点不只是服务器——数据库是单点、缓存是单点、消息队列是单点、甚至机房和地域都是单点。架构师的核心能力就是递归地识别每一层单点并选择正确的拆分维度。
可用公理的工程化:多数可用性问题可归约为故障域过大或恢复路径缺失(经典单点是其一)。单点就是那个"一旦故障就影响全局"的资源。动静分离把静态资源和动态请求的竞争消除;读写分离把读和写的竞争消除;分库分表把数据层面的竞争消除。每一级拆分都在回答:当前的资源竞争在哪,怎么把它拆开。
被问"如何设计高并发系统"时,第一句话是"先找单点",而不是直接抛方案。画出系统架构图,标注每个组件的 QPS 上限,找出最先到达瓶颈的那个——那就是第一拆分目标。这句话本身就是架构思维和高级开发的分水岭。
拆分有顺序,性价比递减但容量递增:动静分离 → 读写分离 → 负载均衡 → 分库分表 → 异地多活。每一级解决上一级产生的新单点。不是上来就异地多活,而是被业务逼着一步步演进。一个 10 万 DAU 的系统上来就异地多活不是技术先进,是资源浪费;一个百万 QPS 的系统还在单机 MySQL 不是技术克制,是事故预警。
AKF 三轴的工程落地——动静分离是 Y 轴(功能拆分)、读写分离是 X 轴(数据复制/只读副本)、负载均衡是 X 轴(水平复制)、分库分表是 Z 轴(数据分区)、异地多活是 Z 轴(地理分区)。每一级拆分都在 AKF 立方体上推进一个维度。
画出拆分阶梯图,标注每级的触发信号。被问"你会怎么设计电商系统"时,给出分阶段方案:当前用动静分离+读写分离够用,QPS 破 5000 演进到分库分表,QPS 破 5 万演进到异地多活。关键是说清每一步的触发条件和取舍代价。
同步调用是最大的单点耦合——下游慢则上游堵,上游堵则全局雪崩。消息队列把"同步等待"变成"异步投递",削峰填谷、故障隔离。代价是引入三个新问题:消息丢失、消息重复、消息积压。异步不是银弹,是把"同步的确定性"换成了"异步的吞吐量"。
异步解耦的精髓在于核心链路同步、非核心链路异步。电商下单:扣库存+创建订单走同步(核心),发短信+推物流+记日志走异步(非核心)。如果全异步,一致性难以保证;如果全同步,吞吐量上不去。
将串行资源竞争(等待下游响应占用线程)变为并行(投递后立即释放线程),减少资源竞争。从利特尔定律角度看,异步降低了 W(平均等待时间),在相同 L(并发数)下提升了 λ(吞吐量)。
被问"如何设计秒杀系统"时,用异步解耦回答:用户请求先入消息队列(削峰),后端按消费能力处理订单。前端立即返回"排队中"。吞吐量提升 10 倍,代价是用户体验从"即时"变成"排队"。
AKF X 轴——无状态服务在负载均衡器后运行多个相同副本。实现最简单,但要求服务无状态(状态外置到 Redis/DB)。有状态服务的水平扩展需要一致性哈希或分片,复杂度陡增。这是"无状态设计"成为架构原则的根本原因。
水平扩展的瓶颈不在应用层(加机器即可),而在数据层——数据库不能简单地加副本解决写入瓶颈。所以水平扩展通常配合读写分离、分库分表一起使用。
把 1 个资源的竞争分散到 N 个副本,每个副本压力降为 1/N。从利特尔定律看:L(并发数)不变,但分散到 N 个副本后每个副本的 L/N 很小,排队等待时间 W 大幅下降,吞吐量 λ 近线性增长。
被问"如何扩容"时,先问"有状态还是无状态"——无状态直接加机器+负载均衡,有状态先拆状态(Session 外置到 Redis)再扩容。这个反问本身就是架构思维的体现。
long_query_time 建议 0.1s;rows_examined / rows_sent 比值 > 100 视为扫描放大/访问路径低效信号(未必等于索引未使用);连接池 waiting > 0 持续即容量不足。 分片前置条件:单机写入 > 5000 TPS,或单表 > 2000 万行且索引优化后仍不达标;切分键必须先出 ADR 再动手。当上游生产速率超过下游消费速率时,下游向上游施加反向压力,防止自身被压垮。本质是流量控制——宁可快速失败也不要无界缓冲(无界缓冲 = 延迟失败 + 资源耗尽)。Java 9 Flow API / Reactive Streams 采用信用机制(credit-based flow control),下游告诉上游"我还能处理 N 个"。
线程池的拒绝策略就是背压的工程实现:队列满后,新请求被拒绝(AbortPolicy)或由调用者执行(CallerRunsPolicy)。这不是"bug"而是"背压设计"——用快速失败防止全局雪崩。
利特尔定律 L = λ × W 中 L(并发请求数)的有界化。无界队列导致 L→∞,最终 OOM。背压通过限制 L 的上界,保证系统在过载时"优雅降级"而非"崩溃"。
被问"线程池满了怎么办"时,回答"拒绝策略是背压设计,不是异常。CallerRunsPolicy 让调用者线程执行,自然降低上游投递速率;AbortPolicy 快速失败,让上游感知过载。关键是不要用无界队列——那是把雪崩从下游转移到上游内存"。
响应式背压契约(prefetch / onBackpressure* / 半响应式零容忍)见 M08.07;本卡管线程池拒绝与有界队列的工程背压。
prefetch 默认 256(flatMap 再乘并发度)是常见隐藏缓冲点。 onBackpressureBuffer 必须给容量上限;drop / latest 须业务书面允许后启用,且拒绝必须可观测。热点问题的本质是"流量在空间上的不均匀分布导致局部资源竞争"——99% 的请求打到 1% 的资源上。治理核心是一个字:"打散"。高并发系统的热点不只是热点 Key(缓存),还有热点账户(数据库行锁)、热点商品(秒杀)、热点分区(消息队列)。
热点治理三层模型:识别 → 拆散 → 削峰。识别靠监控(单 Key QPS 超阈值告警);拆散靠分桶(影子账户/分片/本地缓存);削峰靠异步(MQ 聚合 + 批量处理)。三层递进,从"发现问题"到"消除瓶颈"到"平滑流量"。
热点账户经典方案——"记账分离 + 异步汇总 + 影子账户":将记账(写流水)与更新余额解耦,高并发请求只写流水表(按 accountId 分库无热点),余额更新异步聚合批量执行(单账户从 3 万 TPS 降到几百 TPS);极端热点用影子账户拆分——主账户拆为 N 个子账户,请求按 Hash 路由并行扣减消除单行锁,定时汇总回主账户。本质是 AKF 的 Z 轴(数据分区)在单行级别的微观落地——把一个热点行拆成 N 个非热点行。
被问"热点账户怎么处理"时,三层治理框架回答:"第一层识别——监控单账户 QPS 和锁等待时间,超阈值告警;第二层拆散——影子账户把主账户拆 16 个子账户,按 txId Hash 路由并行扣减,消除单行锁竞争;第三层削峰——扣款请求先入 Kafka 按 accountId 分区,消费者聚合 100ms 窗口内同账户流水批量更新余额,单账户 TPS 从 3 万降到几百"。最后补一句"读余额走缓存准实时,强一致读走 DB for update,T+1 对账兜底"。
synchronized(JDK 24/JEP 491 前)与 JNI/native 帧;ThreadLocal 不致 pin,但海量 VT 下占内存,宜 ScopedValue/显式上下文传递。利特尔定律(Little's Law):L = λ × W——系统中平均并发请求数 = 平均到达率 × 平均响应时间。这是容量规划的数学基础:
- 响应时间 W 不变时,吞吐量 λ 与并发数 L 成正比 → 提吞吐需提并发能力
- 吞吐量 λ 不变时,降低响应时间 W 可减少系统内排队请求数 L → 减少资源占用
- 解释了无界队列的危险:W 增大导致 L 无限增长,最终 OOM
L 就是竞争同一资源的请求数,L 越大资源竞争越激烈。利特尔定律把"资源竞争"从定性描述变成了可计算的数学公式,是高并发容量规划的定量基础。
被问"系统支撑多少 QPS"时,用 L=λ×W 反推:已知单请求平均 200ms,线程池 200 个线程,则 λ = L/W = 200/0.2 = 1000 QPS。要提升到 5000 QPS,要么加线程到 1000 个(受 CPU 核数限制),要么把响应时间降到 40ms(优化 DB 查询/缓存)。
利用率靠近 1 时延迟非线性恶化(排队 / Kingman,见 M01.12);本卡 Little 管稳态 L=λW 关系,不替代高利用率尾延迟模型。
结构化四步——①识别单点(压测/监控定位瓶颈)→ ②选择拆分维度(AKF 三轴:X 水平复制 / Y 功能分解 / Z 数据分区)→ ③评估取舍代价(一致性/延迟/复杂度/成本)→ ④实施并验证(灰度→全量→监控)。每步都有明确的输入输出和决策点,不是"想到哪做到哪"。
将"找出单点→拆分"从口号变成可执行流程。第①步是"找出单点",第②步是"选择拆分维度",第③步是"说清取舍代价",第④步是"验证拆分有效"——完美映射核心哲学的三步闭环。
被问到"你会怎么设计高并发系统"时,按四步推进而不是直接抛方案:"第一步我先压测找瓶颈,假设瓶颈在 DB;第二步我选择读写分离+分库分表拆分数据单点;第三步取舍是引入最终一致性;第四步灰度切换并监控慢查询"。这个回答结构本身就是可审计的设计表达:假设→拆分→取舍→观测。
总骨架见 M05.01 事前-事中-事后。
可用 14 卡:思维(M09.01)定「故障无感」;方法论(M09.02)按 RTO/RPO 选冗余级别;三板斧、容灾、安全发布、容量、一致性/消息、CAP·PACELC、渐近一致、冗余、SLO、混沌;流程 M09.14 挂 M05.01。发布决策树在 M05.11,回滚原则在 M06.06——本卡写流量与冗余招式。织网:C10、G01、K01。
M09 把高可用思维(M09.01)当开路,三板斧到混沌工程(M09.12)收口为保障流程(M09.14)挂 M05.01。熔断灰度(M09.05/M09.02)是 M06.02 稳定窗口的术版;容灾(M09.04)、安全发布(M09.05)、容量(M09.06)对应 K01/K08 事故反例与 G01 发布门禁。可用性本质是 M01.02 稳态在故障域的延伸。
高可用不是"不故障"(不可能),而是"故障后用户无感"。核心是冗余 + 自动故障转移。架构师要假设每个组件都会故障,设计时问"它挂了系统还能跑吗"。可用性公式:Availability = MTBF / (MTBF + MTTR),提升可用性 = 降 MTTR(恢复快)或升 MTBF(少故障)。
关键认知:100% 可靠是不现实的,也是不必要的——100% 可靠会扼杀创新速度。架构师要定义"够用的可用性"(SLO),用量化的错误预算管理稳定性与迭代速度的平衡。
可用公理:故障域过大或恢复路径缺失是主因(经典单点是其一)。冗余把单点变多副本,故障转移让故障透明。MTBF 对应"消除单点"(冗余越多单点越少),MTTR 对应"快速恢复"(自动转移比人工快)。
被问"如何保证高可用"时,不列技术清单,而是按"冗余→检测→转移→恢复"四步回答:"第一层冗余——多副本部署;第二层检测——心跳探针+健康检查;第三层转移——自动 failover;第四层恢复——故障节点修复后自动加入集群"。
可用性级别与 RTO/RPO 选型方法论见 M09.02;本卡立「故障无感」思维与冗余检测转移。
多活架构分级——冷备(备机待命不服务,切换慢)→ 热备(备机同步数据,切换快)→ 主从(主写从读,读高可用)→ 双活(双中心同时服务,写路径须防双写冲突)→ 多活(异地多活,机房级容灾)。级别越高可用性越好但复杂度越高。
选择依据是 RTO(恢复时间目标,故障后多久恢复)和 RPO(恢复点目标,最多丢多少数据)。金融级 RTO<30s → 多活;互联网 RTO<5min → 主从+自动切换;日志类 RTO<1h → 冷备即可。
冗余程度递增——从 1 份到 N 份,从同步到异步,从单机房到跨地域。每一级都在消除更大范围的单点:冷备消除进程单点,主从消除单机单点,双活消除机房单点,多活消除地域单点。
被问"你的系统可用性方案"时,先给 RTO/RPO 需求再给方案:"业务要求 RTO<1min、RPO=0,所以选 MySQL MHA+同步半复制(主从级)+同城双活(机房级),不选异地多活因为成本超预算"。
高可用落地检查单
- SLO 定义:可用性 / 延迟 / 错误率指标与阈值已明确?
- 冗余拓扑:单点是否消除到对应机房 / 地域级?
- 故障演练:定期混沌 / 切换演练,RTO/RPO 真实验证?
- 容量余量:峰值水位 < 70%,扩容预案就绪?
- 监控覆盖:关键链路指标有告警与 oncall 闭环?
可用性公式与思维开路见 M09.01。HA 级别是目标,不等于复制拓扑商品名;金融 RTO 目标是充分条件参考,同城同步亦可达成部分场景。
口径:熔断/限流/降级的总则见法层 M06.01 面向失败设计(熔断/降级/限流);本卡只留参数化实践(算法选型、阈值、三级联防)。
三板斧各有定位——限流(入口防护,控制请求量)、熔断(中间防护,防止级联失败)、降级(末端防护,保核心弃非核心)。
限流算法:固定计数器(简单但有临界突刺)→ 滑动窗口(平滑)→ 漏桶(平滑输出,不允许突发)→ 令牌桶(允许突发,最常用)。熔断三状态:Closed(正常)→ Open(跳闸快速失败)→ Half-Open(试探恢复)。降级:返回默认值/过期缓存/关闭非核心功能。
全链路限流是三板斧在生产环境的高级形态——从单机限流到三级联防:第一级 Nginx 限流(limit_req 按 IP/URI 挡恶意流量),第二级网关集群限流(Redis + Lua 分布式令牌桶,按服务/API 维度),第三级 Sentinel 应用级限流(QPS/并发线程数维度,保护单实例)。三级阈值需协调配合:网关阈值 > 应用阈值 × 实例数,避免互相打架。核心原则是就近防御——在离故障源最近的地方熔断,避免故障向上游扩散。
从利特尔定律看:限流控制 λ(到达率),熔断缩短 W(减少等待时间),降级减少 L(并发请求数)。三者都在控制利特尔定律的变量,防止系统过载后雪崩。
限流算法选型矩阵:计数器适合总量控制(如每天 1000 次),实现简单但有临界突刺;滑动窗口适合平滑统计(如每秒 QPS),解决临界突刺但无法控制突发速率;漏桶适合匀速出口(如保护下游 DB),固定速率出水但不允许突发;令牌桶适合允许突发入口(如 API 网关),按需取令牌且可累积突发。实践中网关层用令牌桶(允许突发流量),下游保护用漏桶(匀速消费保护 DB),两者配合形成"入口突发 + 出口匀速"的流量整形闭环。
设计秒杀系统时,三层防线:网关限流(令牌桶 1 万 QPS)→ 订单服务熔断(错误率 50% 跳闸 10s)→ 非核心降级(关闭推荐/评论/搜索)。被问"三者区别"时,一句话:"限流防外部压垮,熔断防内部级联,降级保核心链路"。
容灾能力递进模型——数据冷备 → 同城双活 → 异地双活 → 两地三中心,每一级解决上一级的单点:同城双活消除机房级单点,异地双活消除城市级单点。容灾不是一步到位,而是随业务规模和 SLA 要求逐级演进。一个日均百万级交易、SLA 99.9% 的系统上异地多活不是技术先进,是资源浪费。
异地多活的核心难题不是同步技术,而是路由闭环——单元化架构(Cell-Based)按用户维度切分流量,让读写闭环在单个单元内完成,从根本上避免跨城双写冲突。Fencing 租约锁是切换原子性的最后防线。
单元化架构三要素:① 路由层——按用户 ID 哈希取模将流量固定路由到归属单元,保证同一用户读写同一单元;② 数据同步层——基于 Binlog 增量同步做闭环复制(A→B 且 B→A),延迟控制在 50ms 内,每日全量校验补偿;③ 调度层——DNS/GSLB 入口调度 + Fencing 租约锁保证切换原子性,先停写再切流防脑裂。RPO=0 的核心在于"同步落盘后再应答"或"单元内强一致 + 跨单元异步但有补偿校验"。
被问"如何设计容灾架构"时,先反问 RTO/RPO 要求和业务规模,再给分级方案:日均百万级用同城双活够用;千万级且 SLA 99.99% 需异地双活;金融级需两地三中心。关键说清三个核心难点:单元化路由如何避免跨城双写、Binlog 闭环同步延迟与补偿、Fencing 租约锁如何防脑裂。最后补一句"每月做一次真实切流演练"——很多团队建了异地多活但从没演练过。
发布是高可用最大的变量——每次发布都是一次受控故障。灰度的本质是缩小爆炸半径:小流量验证假设,用数据决定是否放量。前置条件只有两条:可观测 + 可回滚;没有可演练回滚的灰度是在赌。数据迁移是发布的特殊形态,步骤权威在 M05.13 数据迁移四步法,本卡只讲流量面策略,不复述迁移四步。
被问"如何做零停机发布"时,四步回答:① "流量染色——网关按用户 Hash 打灰度标签,全链路透传到 RPC 和 MQ";② "灰度策略——先金丝雀 1% 观察 RT 和错误率,达标后滚动放量到 10%→50%→100%";③ "数据面——金丝雀打真实生产数据以验证假设;影子表/染色压测另案隔离,勿与灰度混用";④ "回滚机制——Nacos 动态配置秒级切回全量旧版本,无需重新部署"。如果涉及数据迁移,补充"双写+校验+切流+可回滚"四步法。
容量评估的本质是"用数学证明系统能扛住大促"——从经验估算(拍脑袋)到全链路压测(数学证明)的演进。核心矛盾是"压测真实性":压测流量模型与真实用户行为越接近,容量结论越可靠。一个关键认知:容量瓶颈永远在最弱环节,全链路压测的价值就是提前暴露这个环节。
容量评估不是一次性活动,而是持续运营:每次大促后更新容量基线,每次架构变更后重新压测,形成"压测→建模→告警→扩容"的闭环。
五步压测法:① 流量染色——压测请求携带统一标记(Header x-stress-test=1),全链路透传;② 影子隔离——压测数据路由到影子库表(stress_ 前缀),Redis 用独立 DB Index;③ Mock 兜底——第三方接口用 MockServer 返回固定响应,避免触发风控或产生费用;④ 梯度加压——从 1× 日常流量开始,每 10 分钟增加 1×,错误率 > 0.1% 或 RT 翻倍时停止;⑤ 容量建模——用 Little's Law(L = λ × W)换算:所需机器数 = (峰值 QPS × 目标 RT) / (单核处理能力 × 目标 CPU 利用率)。
被问"大促前如何做容量评估"时,结构化回答:"第一步定基线——单机压测得到单实例极限 QPS 和 RT;第二步找瓶颈——全链路压测暴露最弱环节,通常是 DB 或下游依赖;第三步做隔离——流量染色 + 影子库表 + Mock 下游,确保压测不污染生产;第四步梯度加压——1×→3×→5×→10× 逐步加压,记录每级资源利用率;第五步容量建模——用 Little's Law 换算所需机器数,预留 30% 安全冗余"。
选型决策树:① Seata AT——改造小、有全局锁损耗,适合 CRUD;② TCC——侵入大但精确控制资源;③ 本地消息表——同事务落库再投递,通用最终一致;④ 事务消息——半消息协议。共同前提:幂等。不变量决定级别,工具只是实现。
被问"分布式事务怎么做"时,先分类再选型:"核心交易链路(下单扣库存扣券)用 TCC——Try 冻结库存和券、Confirm 确认扣减、Cancel 释放,性能高且精确控制;非核心链路(积分、通知)用本地消息表——订单与消息同事务写入,异步投递保证最终一致。如果团队不熟悉 TCC,降级用 Seata AT——无侵入自动回滚,但 TPS 有损耗。关键强调:所有方案都必须做幂等,否则重试导致数据错乱"。
消息可靠性的本质是"用幂等 + 重试 + 死信对冲分布式系统的不确定性"——不丢、不重、不积压难以同时极致(工程上的张力,不是形式化定理),工程上通过分段保障逼近最优解。消息丢失发生在生产、Broker、消费三个环节,每个环节都需独立保障;消息重复在网络环境下不可避免,必须在业务层幂等;消息积压是生产消费速率不匹配,需动态扩容与降级。
三段式保障链路:① 生产端可靠——RocketMQ 事务消息(半消息 → 本地事务 → commit/rollback)或本地消息表(业务与消息同事务写入,定时扫描投递),保证消息一定到 Broker;② Broker 可靠——同步刷盘(SYNC_FLUSH)+ 主从同步复制(SYNC_MASTER),牺牲 30%-50% TPS 换零丢失;③ 消费端可靠——关闭自动 ACK,业务成功后手动 CONSUME_SUCCESS,失败进重试队列,16 次后进死信队列(DLQ)人工处理。幂等设计用 Redis SETNX + DB 唯一索引双保险,消息体携带 bizId 去重。顺序保证用分区顺序——同一 orderId 路由到同一 Queue,单线程消费。
被问"如何保证消息不丢不重"时,全链路分析:"防丢失三段式——生产端用事务消息或本地消息表保证必达 Broker,Broker 配同步刷盘+主从复制保证持久化,消费端手动 ACK + 重试 + 死信队列。防重复——消费者维护幂等表(Redis+DB 双保险),bizId 去重。保顺序——同一业务 Key 路由到同一 Queue 分区顺序消费。治积压——三层降级:动态扩消费者、批量消费、降级非核心消息"。
CAP(Brewer 2000):分区时一致性 C 和可用性 A 二选一。分布式系统 P 必选,故实际在 CP vs AP 间权衡。PACELC(Abadi 2010)补充了无分区时的权衡:if Partition 则 PA vs PC,Else 则 Latency vs Consistency。BASE是 AP 的实践落地:基本可用 + 软状态 + 最终一致。
典型选型:DynamoDB = PA/EL(分区时重可用,平时重延迟);Spanner = PC/EC(分区时重一致,平时也重一致)。大多数互联网系统选 AP+最终一致,金融系统选 CP+强一致。
CAP(Gilbert–Lynch)说的是:出现网络分区时,线性一致与可用性不可兼得——不是流行课上的「C/A/P 三选二不可能三角」。PACELC 补上无分区时的延迟 vs 一致。选型时写清分区策略与平时延迟预算,而不是背「选 AP」。Dynamo/Spanner 是经典坐标,产品线已有强一致选项,勿当死标签。
被问"CAP 怎么选"时,不答"选 AP"就完了,而是用 PACELC 回答:"分区时选 AP(保可用),平时选 EL(重延迟),因为用户容忍秒级延迟但不能容忍超时。如果做支付系统则反过来:PC+EC,因为一致性比延迟重要"。
最终一致性不是"不管",而是"保证最终收敛"。手段:读修复(读时发现不一致则修复)、反熵(后台 Gossip 协议同步)、向量时钟(冲突检测)、CRDT(无冲突复制数据类型,从数据结构层面保证最终一致)。
工程实践中,缓存一致性是最常见的渐近一致性场景——"先更新 DB 再删缓存 + 延迟双删"容忍秒级不一致窗口,用最小复杂度换取可用性和性能。
BASE 中"E"(Eventually Consistent)的工程实现——不是放弃一致性,而是将同步一致性降级为异步收敛。取舍思维:用秒级不一致窗口换取写入吞吐量和系统可用性。
被问"缓存和 DB 不一致怎么办"时,回答"这是最终一致性的工程实现——先更新 DB 再删缓存,配合延迟双删解决主从延迟。如果需要强一致则用 Write-Through 模式,但写入延迟会增加 2-3 倍"。
口径:冗余/容错的总则见法层 M06.01 面向失败设计(熔断/降级/限流);本卡只讲参数化实践(副本数、仲裁、脑裂)。
冗余是手段,容错是目的。主从冗余解决读单点;主备冗余解决写单点;多活冗余解决机房单点。故障转移的关键挑战是脑裂(split-brain)——多节点同时认为自己是主,需仲裁机制(Quorum / Raft / ZooKeeper)。故障检测要避免误判(网络抖动→假死→误切换)。
N 个副本可容忍的故障数:Paxos/Raft 需多数派(N/2+1),即 3 副本容忍 1 故障,5 副本容忍 2 故障。副本越多可用性越高但写入延迟越大(同步复制开销)。
消除单点 = 增加冗余副本。冗余副本间的数据同步引入一致性问题(CAP 取舍),副本越多一致性协调开销越大。这是"消除单点"与"减少资源竞争"之间的张力。
被问"主从切换脑裂怎么办"时,回答"Quorum 仲裁——多数派确认才算主,少数派自动降级为从。3 节点集群需 2 票当选,网络分区时少数派(1 节点)无法当选,避免双主"。被问"几个副本合适"时,回答"3 副本容忍 1 故障是性价比最高的配置"。
把"可用性"从定性描述变为可量化的工程指标,让取舍有数据支撑。这是取舍思维在运维领域的落地——不是"越稳定越好",而是"在错误预算内追求最大迭代速度"。
被问"如何平衡稳定性和迭代速度"时,用 Error Budget 回答:"SLO 定 99.9% 请求成功,错误预算按失败请求额度核算(时间型可用性才谈分钟)。预算内放手发版(预算耗尽时的冻结与发布闸门归 M11.01)。用 Burn Rate 告警——1 小时烧掉 2% 预算就告警,不用等预算耗尽才发现问题"。
通过在生产环境主动注入故障(杀节点/断网络/满磁盘),验证系统在动荡条件下的稳态。四步实验法:①定义稳态指标(吞吐量/错误率/延迟)→ ②假设稳态在控制组和实验组都会持续 → ③注入真实故障 → ④通过寻找两组稳态差异来证伪假设。核心不是"制造混乱"而是"验证稳态假设"。
五个高级原则:围绕稳态行为建立假设、变化真实世界事件、在生产环境运行实验、自动化持续运行、最小化爆炸半径。
从被动等故障(MTBF 驱动)到主动发现弱点(MTTR 驱动),是高可用保障的演进。混沌工程把"故障演练"从偶发事件变成持续实验,让冗余和故障转移设计在真实故障前得到验证。
被问"如何验证高可用"时,回答"混沌工程——定期杀节点演练,验证故障转移是否真的自动。先在测试环境跑,再逐步到生产。重点不是'制造混乱'而是'验证稳态假设'——如果杀一个节点系统吞吐量下降,说明负载均衡或健康检查有问题"。
全生命周期四阶段——①设计期(冗余架构 + SLO 定义)→ ②开发期(防御性编程 + 故障测试)→ ③运行期(监控告警 + 混沌演练)→ ④故障期(止血→排查→复盘→改进)。每阶段有明确产出物和检查点,形成闭环。
关键认知:高可用不是一次性设计,而是持续运营。设计期的冗余架构决定上限,运行期的混沌演练决定下限,故障期的复盘改进决定演进速度。
将"消除单点"从一次性设计变成持续运营的闭环流程。演进思维在高可用领域的落地——每次故障都是高可用能力的演进输入,每次混沌演练都是对冗余设计的验证。
被问到"你的高可用方案"时,按四阶段回答而不是只讲架构图:"设计期——多副本+自动 failover+SLO 定 99.95%;开发期——防御性编程+故障注入测试;运行期——Prometheus 告警+月度混沌演练;故障期——5 分钟止血+24 小时复盘+改进项跟踪"。
总骨架见 M05.01 事前-事中-事后。
性能 8 卡:先定目标函数(M10.02)再谈调参;思维/方法论分层 ROI;局部性术面挂公理 M01.14;缓存、存储引擎、时空互换;流程 M10.08。织网:C02、C07、C08。
M10 先思维(M10.01)与目标函数(M10.02),再方法论(M10.03);局部性术面(M10.04)挂公理 M01.14;缓存/存储/时空互换(M10.05–M10.07)是专题;流程(M10.08)挂 M05.01。性能招式回 M01.12 瓶颈上限(阿姆达尔限定加速上限)与 M16.05 摩尔(非关键路径可等硬件);缓存(M10.05)与 M07.02 一致代价、M08 吞吐同源。
性能优化不是"调参数",而是"消除等待"。等待来自四类——CPU 等待(计算密集)、IO 等待(磁盘/网络)、锁等待(并发竞争)、GC 等待(内存回收)。先 profiling 定位等待类型,再对症下药。二八定律:80% 性能问题来自 20% 代码。
关键认知:不同等待类型的优化路径完全不同——CPU 等待优化算法/数据结构、IO 等待加缓存/批处理/异步、锁等待减少临界区/用无锁结构、GC 等待调 GC 参数/减少对象分配。混淆等待类型是性能调优最常见的错误。
资源竞争的不同形态——CPU 竞争(计算资源)、IO 竞争(带宽资源)、锁竞争(并发资源)、内存竞争(GC 回收资源)。高性能思维就是精准识别竞争类型并消除它。
-XX:MaxGCPauseMillis 作停顿目标)或 ZGC(天生低延迟,勿依赖 MaxGCPauseMillis)并接受吞吐下降;高吞吐优先用 Parallel GC + 大堆并接受单次长停顿;低足迹优先收紧 -XX:MaxRAMPercentage 并做对象复用。 调参前的对照基线必须包含四项:GC 暂停 P99、gc.time / wall_time 比值、分配速率(MB/s)、晋升速率。无基线的调参视为无效。分层优化,ROI 递减——架构层(缓存/异步/拆分,10 倍提升)→ 系统层(连接池/线程池/IO 模型,2-5 倍)→ 应用层(算法/批处理,2-3 倍)→ 代码层(减少锁/避免逃逸,1.5 倍)→ JVM 层(GC 调优,1.2 倍)→ 硬件层(SSD/内存,1.5 倍)。先解决上层瓶颈再往下走。
关键认知:一个缓存可能比所有 JVM 调优加起来效果大。过早优化是万恶之源——先测量再优化,遵循二八定律。
每一层都在消除该层的资源竞争——架构层消除请求级竞争(缓存减少 DB 访问),系统层消除资源级竞争(连接池减少连接创建),JVM 层消除 GC 停顿竞争。上层竞争消除后,下层竞争才会暴露。
被问"性能优化从哪入手"时,回答"从架构层——一个缓存可能比所有 JVM 调优加起来效果大。先加缓存解决 80% 的 DB IO 等待,再考虑连接池/线程池优化系统层,最后才到 JVM GC 调优。过早优化是万恶之源"。
性能落地检查单
- 目标量化:延迟 / 吞吐 / QPS 目标与基线已测出?
- 瓶颈定位:profile / 火焰图确认热点,非拍脑袋?
- 压测口径:压测场景 / 数据 / 并发模型与生产对齐?
- 优化优先级:按 ROI 分层(架构→系统→应用),先高后低?
- 回归防护:性能基线测试进 CI,防止劣化回潮?
公理层「近则快」见 M01.14 局部性原理。本卡只谈术:存储层次链 L1/L2/L3 → 内存 → SSD → 磁盘 → 网络,每远一层延迟约高一个数量级。优化动作是把热点往上层推,并认清每一层都是速度 vs 容量的取舍。ClickHouse 类 OLAP 可放弃热缓存、用并行扫盘换扩展,不适合 OLTP 延迟画像。Buffer Pool 命中率、缓存行对齐、批量预读,都是局部性在引擎上的落点——先问数据在哪一层,再谈调 SQL。
时间局部性 → 热点缓存 / TTL 策略;空间局部性 → 预读、批处理、顺序 IO。B+ 树叶子链表适合磁盘预读,是空间局部性的教材例;缓存有效 = 局部性被利用,而不是「多加一层 Redis」本身。
被问"如何优化慢查询"时,第一问"数据在内存还是磁盘"——Buffer Pool 命中率是第一指标。如果命中率低于 95%,说明数据频繁从磁盘读取,优化索引让热点数据留在内存比调 SQL 更有效。
被问"为什么 B+ 树比 B 树更适合数据库"时,用空间局部性回答——"B+ 树叶子节点用顺序链表连接,磁盘预读时可以一次性读取连续页,利用空间局部性。B 树非叶子节点也存数据,预读效率低"。
四种缓存模式——Cache-Aside(旁路,最常用,应用负责一致性)、Read-Through(读穿透,缓存层代理读 DB)、Write-Through(写穿透,同步写缓存+DB,强一致但延迟高)、Write-Behind(异步写回,只写缓存异步刷 DB,高吞吐但有丢失风险)。写操作推荐"先更新 DB 再删除缓存"而非更新缓存,避免并发写导致脏数据。
缓存三大问题:穿透(查不存在→布隆过滤器/缓存空值)、击穿(热点 key 过期→互斥锁/永不过期+异步更新)、雪崩(大量 key 同时过期→过期时间加随机偏移/多级缓存/高可用集群)。
缓存 = 空间换时间 + 局部性利用。把数据从慢层(磁盘)推到快层(内存),利用时间局部性(热点数据反复读)。三大问题本质是缓存失效后的资源竞争——穿透是无效请求竞争 DB、击穿是并发请求竞争同一 DB 行、雪崩是大量请求同时竞争 DB。
设计缓存方案时,先选模式(Cache-Aside 默认)、再防三大问题、最后考虑一致性策略。被问"缓存一致性怎么保证"时,回答"先更新 DB 再删缓存+延迟双删,容忍秒级不一致。需要强一致则 Write-Through 但写入延迟翻倍。没有完美方案只有合适场景"。
三种引擎各有定位——B+Tree(行存):OLTP,点查/范围查/事务,MySQL InnoDB,读优化。列存:OLAP,聚合分析,ClickHouse/Doris,压缩率高只读所需列。LSM-Tree:写多读少,HBase/Cassandra/RocksDB,随机写转顺序写+后台 compaction,写优化但有读放大/空间放大。
选型决策树:事务+点查→B+Tree、分析聚合→列存、海量写入→LSM-Tree。没有万能引擎,选型本质是取舍——读优化牺牲写、写优化牺牲读、分析优化牺牲事务。
不同引擎优化不同局部性——B+Tree 优化点查局部性(索引定位)、列存优化列级聚合局部性(只读所需列)、LSM-Tree 优化写入局部性(顺序写)。选型就是选择优化哪种局部性。
被问"为什么不用 MySQL 做分析"时,回答"行存在聚合时要扫全行(100 列读 5 列浪费 95 列 IO),列存只读所需列+高压缩率,10-100 倍差距。MySQL 适合 OLTP 点查事务,ClickHouse 适合 OLAP 聚合分析"。
术侧四象限,道在 M01.08 代价转移与资源守恒。空间换时间:缓存、索引、预计算、冗余。时间换空间:压缩、稀疏、懒加载。彼时间换此时间:预热、批处理、错峰、异步。彼空间换此空间:多级缓存、CDN、分片。
反向取舍:OLAP 列存常不靠行级热缓存吃满命中率,而用高压缩 + 只读所需列 + 并行扫盘换吞吐——是「少读无效字节」相对「堆行级缓存」的路径,不是「放弃内存」。ClickHouse 仍大量用内存(查询缓存、字典、uncompressed cache);真正放弃的是 OLTP 点查与行级事务便利。
取舍思维在性能领域的体现——不是所有场景都空间换时间。OLTP 热点少,缓存有效;OLAP 宽表扫描多,行级缓存命中率低,列存压缩+并行扫描往往更优。
被问"为什么用 Redis"时,回答"空间换时间——用内存空间换磁盘 IO 时间,代价是内存成本和一致性。但如果场景是全表扫描的 OLAP,缓存命中率低,不如用列存+并行扫描"。
结构化五步——①测量(profiling 定位瓶颈,火焰图/Arthas)→ ②假设(基于分层方法论推测瓶颈层)→ ③实验(针对性优化一层)→ ④验证(对比优化前后指标)→ ⑤回归(确保无副作用)。先测量再优化,避免过早优化。
关键认知:不测量就优化等于盲人摸象。性能优化的第一步永远是 profiling,不是猜。优化后必须回归测试——一个"优化"可能引入新的性能问题(如缓存减少了 DB 压力但增加了 GC 压力)。
将"减少资源竞争"从直觉变为可重复的工程流程。测量找到竞争点,假设推测竞争类型,实验消除竞争,验证竞争是否消除,回归确保不引入新竞争。
被问到"系统 RT 突然升高怎么排查"时,按五步推进——"第一步 Arthas 看火焰图定位热点方法,不要猜。假设是 DB 慢查询,实验加索引/缓存,验证 RT 下降,回归确保不影响写入"。
总骨架见 M05.01 事前-事中-事后。
变更纪律 3 卡,专管「能不能动」:可回滚 + 错误预算闸门(M11.01)、副作用幂等与超时预算、对账兜底。SLO 定义在 M09.12,预算政策在 M05.10——本卡是执行闸。织网:G01、G04、K01/K04。
M11 是术的「纪律层」:变更可回滚(M11.01 连 M06.06/M09.05)、副作用幂等(M11.02 连 M09 重试/消息)、对账兜底(M11.03 连 G04 数据变更)。三板斧把 M05.01 事中防护具体化,反例在 K01/K04。变更纪律是 M16.08 死海效应(骨干流失→流程僵化)的工程解药。
Java 生态 6 卡、三对:并发思维 ↔ 先三性后原语;JVM 思维 ↔ 落区/容器预算;Spring/数据访问 ↔ 代理边界与配置契约。R2 视角可标法,章节 TOC 收在术后。织网:C03、C01/C02、C05/C06。
M12 把并发(M12.01–M12.03)、JVM(M12.04–M12.05)、Spring/数据访问(M12.06)收为 Java 专属术;R2 仍标法(见 TOC 后置)。并发心智回 M08 异步/背压,JVM 心智回 C01/C02 资源竞争,Spring 代理事务回 M04 整洁架构与 M07 分布式事务。M12 是「器」侧最厚的 Java 落地层。
并发正确性的三个维度(可见性 / 原子性 / 有序性)已在 M05.06 并发三性总则 立总则。本卡聚焦 Java 如何以 JMM 与原语兑现这三性:理解 JMM、happens-before、线程池、锁、CAS、AQS、CompletableFuture、虚拟线程;认清三大并发问题的 Java 表现。共享可变状态是万恶之源——优先不可变对象、并发集合、无状态。
volatile 保证可见性但不保证原子性;synchronized 与 ReentrantLock 实现互斥;CAS + AQS 支撑并发包;不可变对象天然无并发问题。异步不是目的,解耦和吞吐才是;虚拟线程让同步代码获得并发能力,缓解阻塞代价。
被问并发问题,从"共享可变状态"切入:能不可变更不可变、能无状态则无状态、必须共享则用并发集合与显式锁;区分业务线程池与 IO 线程池避免相互阻塞。追问时说清三大并发问题与对应的解决手段。
成对卡见 M12.02 并发先三性后原语:先分型负载与取消语义,再选锁/CAS/VT;虚拟线程盯 pin 与同步阻塞。上下文显式传递,拒绝隐式 ThreadLocal 穿透请求边界。
synchronized、Lock 或 CAS;原语选错比写慢更危险。 量化锚点:原子性缺失多见于 i++ 与 check-then-act;可见性缺失多见于无 volatile 的共享标志位(循环不退出);有序性缺失多见于双重检查锁漏 volatile。 原语选择:写多场景 LongAdder 相对 AtomicLong 吞吐可差数倍;短临界区用 synchronized;需条件等待用 Lock。JDK 24 起 JEP 491 让 synchronized 不再固定载体线程,但混跑场景仍须压测验证。理解对象生命周期、GC 算法、类加载机制、JIT、字节码;写代码时考虑对象的创建成本、内存占用、逃逸分析、GC 压力。调优时看 GC 日志、堆转储、JFR/JMC。写 JVM 友好的代码是 Java 专家的底色。
GC 分代与算法选择影响吞吐与延迟;逃逸分析/标量替换决定能否栈上分配;避免过度创建、超大对象、无界缓存,合理设置堆与 GC 参数。Java 工程原则:优先不可变对象、减少 Raw Types(泛型保类型安全)、遵循 Effective Java 条目。
被问"线上 OOM 或 GC 问题",按"现象→堆转储/GC 日志→定位→调参或改码→验证"作答;追问时展示对类加载与元空间/堆的分层理解。强调 JVM 调优一定以数据(JFR/JMC)驱动,不靠猜。
成对卡见 M12.04 JVM 落区归因与容器预算:先分诊 OOM vs OOMKilled,再把堆/元空间预算映射 cgroup;先证据链(JFR/heap dump)再改 -Xmx。
Java heap space + 堆转储;元空间看 Metaspace(默认无上限,须设 -XX:MaxMetaspaceSize);直接内存看 Direct buffer memory;线程创建失败看 unable to create native thread。 容器内 -Xmx 建议取容器 limit 的 70%(另留 25% 给元空间 / 栈 / 直接内存 + 5% 余量),或用 -XX:MaxRAMPercentage=70 显式表达。Spring 核心是 IoC 和 AOP——理解 Bean 生命周期与自动配置原理;不滥用反射与动态代理;声明式事务要理解传播机制与失效场景。数据访问要理解事务边界、ORM 阻抗失配、N+1 问题、连接池、批处理、分页。
IoC 反转让依赖从硬编码 new 变为容器注入(依赖倒置落地);AOP 把事务/日志/安全等横切关注点抽离。数据库视角:索引设计、慢 SQL、读写分离、分库分表;缓存设计处理穿透、击穿、雪崩与一致性。
被问"为什么 Spring 事务失效",从代理机制(自调用、非 public 方法、异常被吞)作答;被问"列表查询慢",答 N+1→使用批量抓取或联查。体现你对框架机制与底层 SQL 语义都懂,而非只会用注解。
成对卡见 M12.06 Spring 代理边界与配置契约:代理边界决定事务是否生效;配置即契约;启动失败即失败——条件装配必须可解释,半初始化不接流量。
rollbackFor 内(默认只回滚 RuntimeException 与 Error)。 配置核对以 /actuator/env 的 propertySources 顺序为准:命令行 > 系统属性 > 环境变量 > 外部配置 > application-{profile} > application。安全 5 卡:思维卡挂法侧四原则(M06.10),再落到纵深、认证授权、数据保护、密码学选型。威胁建模门禁在 M06.11。织网:安全 Checkpoint、G08、K08。
M13 从思维(M13.01)到纵深防御(M13.02)、认证授权(M13.03)、数据保护(M13.04)、密码学选型(M13.05):思维层连 M01.02 稳态/故障前置,纵深防御连 M06.01 面向失败与 M09 高可用,数据保护连 G08 与 K08 反例。安全是「道(不信任)→法(纵深)→术(招式)」的全链示范。
安全不是功能,是约束:假设每个组件都会被攻破,问「它失守后系统是否仍可接受」。四原则(最小权限 / 零信任 / 纵深 / 左移)的立法在法层 M06.10,本卡不再复述定义;术侧补失败安全(异常默认拒绝)与够用的安全——攻击成本高于收益即可,金融可上 HSM,普通业务不必按金融选型。
被问安全架构时,先挂法层四原则(M06.10:最小权限 / 零信任 / 纵深 / 左移),再补术侧失败安全(异常默认拒绝、不泄堆栈)。落地:权限与凭证→M13.03;纵深与网关→M13.02 / C10.13;左移门禁→M06.11;密码学与数据→M13.04/M13.05。安全是成本权衡,按业务敏感度选型,不另立第二套「四大」。
纵深防御的核心是"不把鸡蛋放在一个篮子里"——网络层、应用层、数据层各自独立防护,任一层被突破不导致全盘失守。业务层不可将安全责任完全外包给网关或框架——WAF 拦不住业务逻辑漏洞,Spring Security 挡不住 SQL 注入如果用了 ${} 拼接。
四道纵深防线:认证授权(你是谁、你能做什么)→ 会话管理(会话令牌安全、CSRF 防护)→ 输入验证(白名单优先、注入防御)→ 输出编码(按上下文编码、CSP 策略)。每道防线独立有效,不依赖前一道。
输入安全三原则:白名单优先(只允许已知合法输入,黑名单永远不完备)、全入口校验(所有外部数据都需校验,包括 HTTP 参数、Header、MQ 消息、文件内容)、上下文输出编码(HTML 上下文用 HTML 实体编码、JS 上下文用 JS 编码、URL 上下文用 URL 编码)。注入防御:SQL 用 #{} 不用 ${},命令注入用白名单参数化,XXE 禁用外部实体,反序列化禁原生 ObjectInputStream 处理不可信数据。CSRF 防护:SameSite Cookie + anti-CSRF token,GET 禁止状态变更。
被问"你的 Web 安全防护体系"时,四道防线回答:"第一道认证授权——OAuth2+JWT+RBAC,服务端强制校验不信任前端;第二道会话管理——HttpOnly+Secure+SameSite Cookie,CSRF 用 token 防护;第三道输入验证——MyBatis #{} 防注入、文件上传魔数校验、反序列化用 ObjectInputFilter;第四道输出编码——按上下文编码 + CSP 策略防 XSS"。强调"每道防线独立有效,不依赖前一道"。
认证(Authentication)解决"你是谁",授权(Authorization)解决"你能做什么"——两者不可混淆,认证通过不等于授权通过。口令存储的核心原则是"加盐 + 自适应慢哈希",工作因子可随硬件升级定期提升,使 GPU 爆破成本始终高于攻击收益。
授权遵循默认拒绝原则:权限显式授予,未明确允许即禁止。服务端必须强制执行授权校验,不可信任前端的隐藏菜单、按钮或路由守卫。IDOR(不安全直接对象引用)是最常见的授权漏洞——用自增 ID 暴露资源且不做归属校验。
口令存储优先级链(OWASP Password Storage):Argon2id(PHC 获奖,抗 GPU/ASIC,内存困难型)> scrypt > bcrypt(cost ≥10)> PBKDF2-HMAC-SHA-256(迭代 ≥600000;若用 SHA-512 则 ≥210000)。禁用 MD5/SHA-1/SHA-256 直接哈希口令(CWE-916),禁用全局共享 salt(CWE-759/760)。OAuth2 用授权码 + PKCE,禁用隐式流程。JWT 必须显式指定算法防 alg=none 攻击,access_token 短生命(15min),refresh_token 可撤销。MFA 中 TOTP 优于短信 OTP(SIM 劫持风险),WebAuthn/Passkey 抗钓鱼。
被问"口令怎么存"时:"用 Argon2id 加盐慢哈希,每用户唯一 salt,工作因子定期评估。禁止 MD5/SHA 直接哈希——GPU 秒级爆破"。被问"OAuth2 安全"时:"用授权码 + PKCE,严格白名单匹配 redirect_uri,校验 state 防 CSRF;OIDC 另校验 nonce 防重放,禁用隐式流程"。被问"JWT 安全"时:"显式指定算法防 alg=none,access_token 15 分钟过期,refresh_token 可撤销,不存敏感信息在 payload"。
数据保护三维度——机密性(加密存储 + 传输加密)、完整性(HMAC/签名校验)、可用性(备份 + 冗余)。密钥全生命周期管理是核心:生成 → 存储(HSM/KMS)→ 轮换 → 销毁(byte[] 清零)。密钥泄露等于加密形同虚设。
错误处理是安全被忽视的攻击面——OWASP 2025 新增 A10「异常条件处理不当」。失败安全原则:异常时默认拒绝,不泄露堆栈信息,不降级为明文处理。生产环境必须关闭 actuator/swagger 调试端点。
数据保护工程实践:敏感数据加密存储——3 亿用户敏感数据用 AES-GCM 加密,密钥存 HSM/KMS 不落库;密钥轮换——定期轮换(如 90 天),旧密钥只解密不加密,双密钥过渡期平滑迁移;数据脱敏——手机号脱敏为 138****8888,身份证脱敏为前 6 后 4,日志全链路脱敏;API 响应最小化——字段裁剪只返回必要字段,分页防全量爬取;错误处理——全局异常处理器返回统一错误码,不输出堆栈到客户端,日志记录完整堆栈但不返回;审计日志——记录安全事件 who/what/when/result,禁止记录口令/密钥/令牌,日志防篡改。
被问"敏感数据怎么保护"时,三维度回答:"机密性——AES-GCM 加密存储,密钥存 KMS 不落库,90 天轮换,TLS 1.3 传输加密;完整性——HMAC 或数字签名校验;不可否认——仅非对称签名(HMAC 不能抗抵赖);可用性——异地备份+冗余。补充:日志全链路脱敏(手机号 138****8888),API 响应最小化只返回必要字段,生产关闭 swagger/actuator 调试端点,异常处理不泄露堆栈"。
密码学第一原则:不自实现密码算法——用 JCA/Bouncy Castle 标准库,不自己拼 AES/RSA。Kerckhoffs 原则:安全性依赖密钥而非算法保密。AEAD(认证加密)优先——同时提供机密性和完整性,AES-GCM 是事实标准。
NIST SP 800-131A 将 SHA-1、RSA-1024、两密钥 3DES 等列入过渡/禁用路径;DES/RC4 等更早被业界与相关规范弃用——选型以当前 SP 800-131A 与 FIPS 批准算法为准,勿把 RC4 误记为 131A 专表条目。后量子密码(PQC)标准 ML-KEM/ML-DSA/SLH-DSA 已于 2024 年正式发布(FIPS 203/204/205),高风险系统 2030 前需启动迁移。
选型速查:对称加密用 AES-128/256-GCM(AEAD,IV 不可重复,禁 ECB),非对称加密用 RSA-OAEP(≥2048 位),签名用 RSA-PSS 或 ECDSA(确定性签名 RFC6979),哈希用 SHA-256/SHA-3(禁 MD5/SHA-1),口令哈希用 Argon2id(每用户 salt + pepper 分离存储),MAC用 HMAC-SHA-256/512(常量时间比较),随机数用 SecureRandom CSPRNG(禁 java.util.Random/Math.random),TLS≥1.2 优选 1.3(ECDHE+GCM,HSTS,禁 trustAll)。密钥管理:生成用 KeyGenerator,存储用 HSM/KMS,轮换有周期,销毁用 Arrays.fill 清零 byte[]。
被问"加密算法怎么选"时,分类回答:"对称加密用 AES-GCM——AEAD 同时提供机密性和完整性,IV 不可重复,禁 ECB;非对称用 RSA-OAEP 2048 位以上;哈希用 SHA-256 或 SHA-3,禁 MD5/SHA-1;口令用 Argon2id 加盐慢哈希;随机数用 SecureRandom 不用 Random;TLS 1.3 + HSTS"。最后强调"不自实现密码算法,用标准库"。
AI 纪律目前 1 卡压舱:变更必回归、工具必有契约;评测/灰度/成本细节进 C12 与 G07。织网:C12、G07、K07 静默塌方。
M14 把 AI 变更必回归与工具有契约(M14.01)收为术;回 M11 变更纪律与 M05 演进。AI 门禁连 G07 评测与 K07 静默塌方反例。AI 工程化的特殊风险(静默退化)使 M06.07 可观测与 M15 复盘比通用术更关键。
排障 7 卡:思维与证据链起手;方法论 / 自愈 / 可观测用法(M15.05,信号立法在 M06.07) / 5Whys;流程 M15.07 挂 M05.01。织网:G02、K02。
M15 从思维与证据链(M15.01–M15.02)起,方法论/自愈/可观测/复盘(M15.03–M15.07)收口;处理流程(M15.07)挂 M05.01。证据链(M15.02)是 G02 可观测的工程表达;可观测用法在 M15.05(信号立法在 M06.07);复盘(M15.06 5Whys)连 M01.07 与 M16.08。排障是 M01.02 稳态闭环在故障现场的重演。
核心原则——"先止血再排查"。故障发生时优先恢复服务;止血动作按故障类型选路(变更引入→回滚;过载→降级/限流/扩容;机房/依赖域故障→切流量),不要把「切流量」固定排在末位当普适全序,不要在故障现场 debug。保留现场(dump/日志)后离线分析。止血速度决定 MTTR,MTTR 决定可用性。
关键认知:在故障现场 debug 是最大的错误——每多一分钟排查,MTTR 就多一分钟,用户影响就多一分钟。正确做法是:先止血恢复服务,保留现场快照(jstack/jmap/tcpdump),然后离线分析。
线上问题处理是高可用设计的兜底防线——设计再好也会有故障,排障能力决定故障影响范围。止血优先 = 降 MTTR = 提可用性。这和高可用思维中"Availability = MTBF/(MTBF+MTTR)"直接对应。
被问"线上 CPU 100% 怎么办"时,第一句"先止血——扩容/限流保业务,同时 jstack dump 线程保留现场。然后离线分析 dump 找死循环/GC 频繁的原因。不要在生产环境直接 debug"。
四步闭环——①止血(恢复服务,保留现场)→ ②定位(可观测性三支柱交叉定位)→ ③根因(5Whys 深挖)→ ④复盘(blameless postmortem + 改进项跟踪)。每步有明确的工具和产出物。
常见误区:跳过止血直接 debug(MTTR 飙升)、止了血不保留现场(根因丢失)、复盘变成追责会(团队不敢报问题)、有改进项无跟踪(同样的问题反复发生)。
将"找出单点"从设计阶段延伸到运行阶段——排障就是在故障中找单点。止血是"隔离故障单点",定位是"找出故障单点",根因是"理解单点为何故障",复盘是"防止单点再次故障"。
描述一次线上故障处理经历时,按四步闭环讲述——"先止血(3 分钟回滚恢复服务),保留 jstack dump 后定位(Arthas 找到死锁线程),根因(5Whys 发现是锁顺序不一致),复盘(加锁顺序规范+静态检查工具+改进项跟踪)"。突出止血速度和复盘改进。
排障检查单
- 止血:先恢复服务、保留现场(dump / 日志)?
- 定位:可观测三支柱交叉,缩小范围?
- 根因:5Whys 深挖到机制层面?
- 复盘:blameless,改进项有 owner / 期限 / 验证?
- 防呆:把根因变成检查 / 自动化,避免再发?
故障自愈的本质是"把人的经验沉淀为机器的自动决策"——从人工排障(MTTR 15 分钟)到自动止血(MTTR 小于 5 分钟)的跃迁。核心不是"替代人",而是把高频、有确定处理方案的故障自动化,让人聚焦于复杂、未知的故障。
自愈的边界:网络抖动、实例 OOM、依赖超时、以及已演练的自动 failover 可自愈;数据损坏、错误配置扩散、未演练的脑裂/切换须人工介入。自愈动作必须可回滚、可观测——"宁可慢一点摘除,也不要误摘除"。
"感知 → 决策 → 执行 → 恢复"四阶段闭环:感知层——多级健康检查(K8s Liveness/Readiness 探针 + 自定义业务探针检测 DB/Redis 连通性)+ 监控指标实时采集;决策层——基于规则的决策引擎(连续 N 次失败摘除、超时 M 秒重启),结合熔断器状态判断故障等级;执行层——渐进式摘除(先降权重 50% → 观察 → 全摘除)、重启容器、切流;恢复层——健康检查恢复后自动加回流量,未完成请求走幂等重试 / 补偿队列 / 事务消息,而非 Binlog 回放。核心原则:自愈动作要可回滚、可观测,自愈与人工干预的边界通过告警升级机制区分。
被问"如何实现故障自愈"时,四阶段闭环回答:"感知层——K8s Liveness/Readiness 探针 + 自定义业务探针检测依赖连通性,5 秒一次;决策层——规则引擎判断:连续 3 次失败摘除、OOM 重启、单机房故障切流;执行层——渐进式摘除先降权重 50% 观察,不是一刀切;恢复层——健康检查通过后自动加回流量,切流时未完成请求走幂等重试 / 补偿队列 / 事务消息,而非 Binlog 回放。最后强调自愈边界:可自愈的自动化处理,不可自愈的告警升级到人工"。
三支柱各有定位——Metrics(可聚合,低成本,回答"发生了什么",告警驱动)、Logging(离散事件,高成本,回答"为什么发生",诊断驱动)、Tracing(请求作用域,中等成本,回答"在哪里发生",调用链驱动)。三者互补不替代,运维成本梯度:Metrics(低)→ Tracing(中)→ Logging(高)。
关键认知:没有可观测性就是"盲飞"——故障发生了不知道,知道了不知道在哪,找到了不知道为什么。可观测性是高可用和线上排障的基础设施。
术层口径:三支柱信号的立法见法层 M06.07 可观测性三支柱;本卡只讲用法——各自定位、成本梯度、交叉定位,不复述原则。
可观测性是"找出单点"在运行阶段的眼睛——Metrics 发现异常(单点表现),Tracing 定位链路(单点位置),Logging 提供细节(单点原因)。三者交叉验证才能精确定位。
被问"如何设计监控系统"时,按三支柱回答——"Metrics 做告警(Prometheus + Grafana,低成本高覆盖),Logging 做诊断(ELK,高成本但细节全),Tracing 做定位(Jaeger,中等成本串联调用链)。三者通过 traceId 关联,告警触发后可快速跳转到 trace 和 log"。
丰田生产系统方法论——对问题连续追问"为什么"直到触及根本原因。原则:关注流程和系统问题而非"谁犯错"(blameless);避免停留在表面现象或人为失误;根因应指向可改进的系统/流程/自动化缺陷。Google SRE 提倡无指责复盘(Blameless Postmortem)——假设所有人在当时信息下做了最佳决策。
复盘是"演进思维"在故障领域的应用——每次故障都是系统演进的输入。5Whys 是"递归拆分"在故障分析中的体现:把"大问题"一层层拆成"小根因",直到找到可修复的最底层。
描述复盘流程时,给出 5Whys 示例——"为什么超时?→GC 停顿 3s →为什么 GC 停顿?→FullGC →为什么 FullGC?→老年代空间耗尽 →为什么耗尽?→未分页一次加载 10 万条导致大对象晋升高频填满老年代 →根因:代码缺陷 + Code Review 缺失。改进:加分页 + Review checklist + 大对象告警"。
完整时间线——告警触发 → 值班响应(3min 内)→ 止血决策(回滚/降级/限流)→ 现场保留(jstack/jmap/tcpdump)→ 根因排查(日志+链路+监控交叉)→ 修复验证 → 复盘文档(24h 内)→ 改进项落地(负责人+截止日)→ 混沌演练验证。关键指标:MTTD(发现时间)、MTTR(恢复时间)。
将"止血→排查→复盘"从经验变为可重复的标准流程。每个环节都有明确的工具、产出物和时间要求,确保不同的人处理同一个故障都能达到相同的效率和质量。
被问到"讲一次你处理的线上故障"时,按完整时间线讲述——"告警触发(Prometheus P99 延迟告警)→ 3 分钟响应 → 5 分钟止血(回滚上一次发布)→ 保留 jstack → 离线分析定位死锁 → 24h 内复盘文档 → 改进项(加锁顺序规范+静态检查+混沌演练验证)。MTTR 15 分钟"。
总骨架见 M05.01 事前-事中-事后。
势定律 11 卡:规模与网络(90-9-1、邓巴、梅特卡夫、里德)、技术周期(摩尔、成熟度曲线、Putnam/SLIM)、组织病理(死海、呆伯特、彼得、舍基)。读法是「何时能做 / 何时做不动」,不是段子集。布鲁克斯在 M02.08。
M16 十一条势定律是整条链的「外部判据」:规模(M16.04 梅特卡夫/M16.07 里德/M16.05 摩尔)、组织(M16.02 邓巴/M16.06 Putnam/SLIM/M16.09 呆伯特/M16.10 彼得/M16.08 死海/M16.11 舍基)、技术周期(M16.03 成熟度)共同决定「何时下手、量级是否失配」。势不产招式,但能让法/术加速或阻断——例如规模失配触发 M01.05 演进、组织边界触发 M01.09 康威。势定律与开篇五层、四种错位(#hang-misalign)互锁。
在线社区约 90% 潜水、9% 偶尔贡献、1% 持续创造;长尾沉默是常态而非异常。
该律与梅特卡夫/里德(M16.04/M16.07)同源:价值在头部少数节点,但成本与风险散在长尾;长尾沉默是系统常态,不是缺陷信号。
价值由少数高频贡献者驱动;多数用户是被动消费者,其“不反馈”不等于“无需求”。
对应 M01.02 稳态——「无反馈」不等于「无状态」;用抽样与埋点推断长尾,而非等长尾主动发声。
监控/告警/内部工具要让那 1% 的建设者极低摩擦地贡献;关键决策不能等长尾自发提需求,靠主动访谈与埋点推断;平台冷启动优先服务好前 1%。
内部平台把那 1% 建设者当核心用户做需求访谈与贡献激励;告警降噪让 1% 不被噪音淹没;社区/文档冷启动靠种子用户而非广撒网。对照 G02 可观测的「信号 vs 噪音」。
人能维持稳定社会关系的数量约 150,超出则靠制度而非信任维系。
150 是认知半径的近似上限;超出后信任让位于流程、文档与契约——这是康威定律(M01.09)的组织前提。
组织/团队的认知半径有限;系统边界应贴合团队边界(康威定律)。
系统边界应贴合团队边界:单团队规模参考邓巴数(约 150 人);单服务认知负载另用接口面/变更频率约束;超大单体团队必然靠层层审批补信任缺口,反而拖慢。
单服务/单团队耦合上限参考 ~150 人;微服务按认知半径切,避免超大单体团队;跨团队接口用契约与文档补足信任缺口。
微服务按认知半径切,避免「一个巨服务养一个巨团队」;跨团队接口用契约测试与 API 文档补足信任;新团队组建参考 ~150 上限做信息辐射结构。
新技术必经萌芽→过热→谷底→复苏→平稳;“热门”常与“可用”错峰。
过热期常被「叙事」推高,平稳期才被「工程约束」验证;热门与可用常错峰 1–3 年。
选型避开过热期陷阱;关键系统用进入平稳期的成熟技术。
与 M05.05 技术债一致:追新引入的隐性债,常在谷底期集中爆发。
对新技术设观察期与回退方案,不追新;核心链路用 plateau 技术,边缘才放新技术;架构留可替换接缝。
对新组件设观察期 + 回退开关;核心链路只用 plateau 技术,边缘才放实验;架构留可替换接缝(M04 整洁架构),避免被单一技术锁定。
网络价值随节点数平方增长;平台/双边系统赢在临界规模。
价值 ∝ n²,但爆炸半径与协调成本也 ∝ n²——规模红利与规模风险同源。
价值在规模,但故障爆炸半径与协调成本也随 n² 放大。
对应 M01.15 复杂度守恒:n² 增长不消灭复杂度,只是把它转移到治理与隔离层。
平台优先达临界规模;规模化同时配套治理、隔离与熔断,避免一处故障全网雪崩;迁移/扩容按 n² 重估影响面。
平台优先冲临界规模;规模化同时配治理/隔离/熔断(M09 高可用);迁移与扩容按 n² 重估影响面,避免一处故障全网雪崩。
算力约每 18–24 月翻倍,是历史趋势而非物理定律。
是历史趋势曲线,非物理定律;近年增速已放缓,不能当无限免费红利。
硬件红利可缓解部分性能问题,但延迟敏感路径不受算力线性惠及。
对应 M01.12 瓶颈上限:延迟敏感路径不受算力线性惠及,阿姆达尔限定加速上限。
非关键路径可用“等硬件”换架构简化;容量规划按代际预留;延迟敏感/确定性要求处仍现在优化,不为未来算力过度设计。
非关键路径可用「等硬件」换架构简化;容量规划按代际预留 headroom;延迟敏感/确定性要求处仍现在优化(M10),不为未来算力过度设计。
扩大团队很少带来线性产能:沟通、协调与集成开销上升,交付速率常呈亚线性。人规模公理见 M02.08(布鲁克斯);Putnam/SLIM 用软件方程描述规模与工期/人力的非线性关系。本卡给势侧推论:关键路径上堆人往往减速。
并行度受关键路径与沟通成本约束;加人可能减速(Brooks)。对应 M01.08:把「人力」代价转成「沟通」代价,未必净赚。排期用历史 lead time 分位数,不按人头线性外推。
关键路径靠少而精小队;拆服务须配接口契约,避免沟通爆炸;新人按 ramp-up 折算产能。闸门:无契约的扩编申请一律驳回。
群体形成网络(可任意分组)的价值随节点数指数增长,快于梅特卡夫。
可任意分组的群体价值 ∝ 2ⁿ,快于梅特卡夫;但群体治理成本也指数上升。
“可组合”的能力会触发生态级价值;但群体治理成本也指数上升。
对应 M01.13 必要多样性:系统要匹配环境多样性,可组合能力正是多样性的工程红利。
设计插件/扩展点/平台让使用者自发成组;中台/平台价值在“让业务自己拼”,但须配套治理防止碎片化。
设计插件/扩展点/平台让使用者自发成组(中台/平台价值在「让业务自己拼」);同时配治理防碎片化(M11 变更纪律、M04 边界)。
能力强者易流失、弱者沉淀,组织能力随时间下沉(Bruce Webster)。
能力强者因环境僵化而流失,弱者沉淀,组织能力随时间下沉——这是熵增(M01.16)的组织版。
技术债/流程僵化会驱逐骨干;健康度靠流动而非滞留。
对应 M01.05 演进:健康度靠流动而非滞留;技术债/流程僵化是骨干流失的诱因。
保持技术清晰度与成长路径;定期架构/组织健康复盘;用轮岗与难题保留骨干,避免“逆选择”固化。
保持技术清晰度与成长路径;定期架构/组织健康复盘;用轮岗与难题保留骨干,避免逆选择固化;对照 K 事故反例中「流程失灵」。
企业常把最不胜任的人提拔到管理岗,以最小化其对产出的破坏。
脱离技术判断的管理层易做反架构决策;行政层级不等于技术权威。
脱离技术判断的管理层易做出反架构决策。
对应 M01.09 组织沟通:决策权位置决定系统形状(康威)。
设技术决策 IC 通道(架构师/技术委员会),不让纯行政层级垄断技术拍板;管理岗要有技术判断力门槛。
设技术决策 IC 通道(架构师/技术委员会),不让纯行政层级垄断技术拍板;管理岗设技术判断力门槛;关键架构评审多角色参与。
人会被提拔到其不胜任的层级后停滞。
人停在「不胜任层级」后,能力信号被层级遮蔽,决策质量下降。
关键架构角色应按能力而非资历;双通道防“为晋升而转管理”。
对应 M01.07 认知谦逊:层级不增判断力,反而可能放大错误自信。
建立技术线/管理线双通道;专家不必转管理也能晋升;技术评审防“层级遮蔽”导致的劣化决策。
建技术线/管理线双通道;专家不必转管理也能晋升;技术评审防「层级遮蔽」导致的劣化决策(连 M09/M13 门禁)。
机构会努力维持它本应解决的问题,以证明自身存在(Clay Shirky)。
机构会维持它本应解决的问题以自证存在;工具/流程可能异化为目的本身。
工具/流程若自身成为瓶颈,就背离了初衷。
对应 M01.10 度量异化(Goodhart):被考核的指标取代真实目标。
中台/平台/审批流定期做价值审计,砍掉“为流程而流程”的环节;判断标准是“是否解决了用户问题”,而非“是否证明了部门存在”。
中台/平台/审批流定期做价值审计,砍掉「为流程而流程」环节;判断标准是「是否解决用户问题」而非「是否证明部门存在」;对照 G 门禁的「门禁为质量非为存在」。