题干与适用场景
这道题考察你能否把一次重要技术取舍变成可检索、可评审、可演进的团队记忆。候选人需要说明何时值得写 ADR、如何记录被否决的选项、如何让记录服务代码评审和后续排障,以及如何处理被新决定取代的旧记录。
适用对象包括后端、平台、SRE、技术负责人和需要跨团队协作的工程师。假设团队已有代码仓库和评审流程,但没有统一的决策记录规范;方案可能涉及可靠性、安全、接口、依赖或不可逆的成本取舍。
面试官考察点
第一,能否识别“架构上重要”的决定,而不是把每个实现细节都写成文档。第二,能否用中性背景、约束、选项和后果解释为什么做出选择。第三,能否把 ADR 放进提案、评审、接受和取代的生命周期。第四,能否让记录在代码评审、入职和故障排查中真正被使用。
回答前需要澄清的问题
- 这次决定影响系统结构、关键质量属性、公开接口还是普通实现细节?
- 当前有哪些硬约束,例如延迟、可用性、合规、团队技能、迁移窗口和成本?
- 方案是否已经上线,还是仍处于 Proposed 状态?谁有接受或拒绝权限?
- 团队把 ADR 放在代码仓库、文档库还是两者同步?如何搜索和通知受影响团队?
- 未来哪些信号会触发重新评估,例如流量、故障率、成本或法规变化?
30 秒回答框架
“我先确认这是否会影响系统结构、关键质量属性或难以逆转的接口;如果是,就创建一份短小的 ADR。记录问题背景、约束、候选方案、被否决原因、最终决定、权衡、风险和状态,并让受影响团队在 Proposed 阶段评审。接受后把记录视为不可变历史,需求变化时新增一份 Superseding ADR,链接旧记录并更新索引。最后把 ADR 放到团队能访问的版本库,在设计评审、代码评审、入职和排障时引用。”
分步骤深入解答
第一步:判断是否达到记录门槛
当决定影响系统结构、关键质量属性、公开接口、重要依赖或难以逆转的成本时写 ADR。普通变量命名、一次性重构细节和已有明确标准覆盖的选择不必单独建档。门槛的目标是保留真正会影响未来判断的上下文,避免文档噪声让重要决定失去可见性。
第二步:用中性背景描述问题
先写问题、用户或业务影响、功能与非功能要求、期限和不可违反的约束。不要把偏好的方案写进背景,也不要用“某团队坚持”代替事实。背景应让没有参加讨论的新成员理解为什么现在必须做决定。
第三步:列出选项和取舍
列出实际考虑过的方案,包括被否决的选项及原因。用可比较的维度说明延迟、可用性、故障半径、安全、迁移成本、运维负担和团队能力;无法量化时明确假设和信心等级。候选方案不需要写成完整设计指南,细节可以链接到独立的评估文档。
第四步:写出明确的决定与后果
决定句应能单独阅读,例如“我们采用区域化队列,并接受跨区域切换需要人工审批”。随后写预期收益、代价、风险、需要补充的控制和受影响的组件。只写“选择方案 A”无法支持未来评审,因为读者看不到当时的理由和承担的代价。
第五步:设置状态、所有者和评审
常见状态包括 Proposed、Accepted、Rejected、Deprecated 和 Superseded。指定记录所有者,邀请受影响团队在 Proposed 阶段阅读并评论;接受时补充日期、利益相关者和版本。评审目标是确认事实、约束、选项和后果完整,而不是追求所有人永远同意。
第六步:把 ADR 放进工程工作流
将 ADR 与代码仓库或团队文档库一起版本化,建立可检索索引。设计评审和代码评审遇到违反已接受决定的改动时,应链接对应 ADR 并要求明确的变更记录。新人入职、交接和线上排障也应能从 ADR 了解“为什么这样做”,减少重复争论。
第七步:需求变化时新增记录
接受或拒绝后的 ADR 保持不可变。若新证据、规模、成本或法规改变了结论,创建一份新的 ADR,记录变化背景、旧决定的限制和新取舍;新记录接受后,将旧记录标为 Superseded 并互相链接。这样既保留历史,又让读者能快速找到当前有效决定。
高质量示范回答
“我会先确认这是不是影响系统结构、关键质量属性、接口或难以逆转成本的决定;如果只是局部实现细节,就不增加 ADR。达到门槛后,我在 Proposed 记录问题背景、用户和非功能要求、约束、候选方案、被否决原因、最终选择、权衡、风险和信心等级。
我会邀请受影响团队在评审时间内先阅读,再讨论未解决的问题;记录状态、所有者、日期和利益相关者。接受后把 ADR 放在可检索的版本库中,在设计评审、代码评审、入职和排障时引用。记录保持短小、事实化,不替代完整设计文档。
如果需求或证据变化,我不会改写已接受记录。我会创建新的 ADR,说明旧决定为何不再适用、有哪些新选项和后果;新记录接受后把旧记录标记为 Superseded 并建立链接。这样团队看到的是当前决定,同时仍能追溯每次取舍。”
常见错误
- 把 ADR 写成完整设计文档 → 读者找不到决定本身 → 保留背景、选项、决定和后果,细节另链。
- 只记录最终方案 → 未来重复争论 → 写出被否决选项和当时约束。
- 用个人偏好替代约束 → 记录无法复核 → 使用中性、可观察的事实与假设。
- 接受后直接修改原文 → 历史被覆盖 → 新增记录并标记旧记录为 Superseded。
- 没有状态和所有者 → 团队不知道是否生效 → 设置生命周期、负责人和接受日期。
- ADR 存在但没人引用 → 文档成本没有收益 → 接入设计评审、代码评审、入职和排障。
追问及应对
追问 1:团队意见不一致时能接受 ADR 吗?
可以。记录未解决的异议、风险和接受权限;评审的目标是让决定和代价可见,而不是制造虚假的一致。若需要补数据,可以保持 Proposed 并安排验证任务。
追问 2:什么时候应该回溯补写 ADR?
当现有系统有重要但没人能解释的结构、接口或质量属性取舍时,可以基于提交记录、事故资料和维护者访谈补写,并明确标注这是对既有决定的回溯记录,避免把推测写成当时事实。
追问 3:ADR 应该放在仓库还是 wiki?
优先放在受影响代码附近的版本库,便于和实现一起评审;如果业务和安全团队需要更广访问,可以同步索引或摘要,但要保留单一权威来源,避免两处内容漂移。
追问 4:如何证明 ADR 有价值?
观察新成员理解关键决策所需时间、重复争论次数、代码评审中违反已接受决定的发现率,以及事故排查时能否快速找到背景。指标用于发现盲点,不应把文档数量当作目标。