编程进阶网 编程进阶网
首页
  • 在线工具
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 加解密
  • 时间日期
  • 网络工具
  • 颜色设计
  • 二维码
  • 开发实用
  • 计算机的原理
  • 操作系统原理
  • 网络协议原理
  • 数据库的原理
  • 序卷导读
  • 数据本质
  • 运行模型
  • 并发设计
  • 内存真相
  • 交互系统
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 技能之旅
  • 体系建设
  • 代码品质
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 性能优化
  • 数据结构导论
  • 线性结构详解
  • 树哈希结构论
  • 容器设计实战
  • 经典算法思想
  • 工程案例剖析
  • 算法题库精练
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++编程技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript案例
  • JavaScript高级
  • Kotlin精通
  • Android库解读
  • Android专栏
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • 毛选解读
  • 自我精进
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接

杨充

专注编程 · 终身学习者
首页
  • 在线工具
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 加解密
  • 时间日期
  • 网络工具
  • 颜色设计
  • 二维码
  • 开发实用
  • 计算机的原理
  • 操作系统原理
  • 网络协议原理
  • 数据库的原理
  • 序卷导读
  • 数据本质
  • 运行模型
  • 并发设计
  • 内存真相
  • 交互系统
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 技能之旅
  • 体系建设
  • 代码品质
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 性能优化
  • 数据结构导论
  • 线性结构详解
  • 树哈希结构论
  • 容器设计实战
  • 经典算法思想
  • 工程案例剖析
  • 算法题库精练
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++编程技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript案例
  • JavaScript高级
  • Kotlin精通
  • Android库解读
  • Android专栏
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • 毛选解读
  • 自我精进
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接
  • README
  • 面向对象设计

  • 常见设计原则

  • 巧学设计模式

  • 系统架构设计

  • 程序员精进路

    • README
    • 1.技术方案设计能力
    • 2.架构演进决策能力
    • 3.技术讨论表达能力
    • 4.应对技术质疑能力
    • 5.代码审查攻防能力
      • 1. 案例引入
        • 1.1 被 Diss 17 次的 PR
        • 1.2 顺藤摸到根因
        • 1.3 我们要回答什么
      • 2. Code Review 全景图
        • 2.1 五种 Review 目的
        • 2.2 目的错配的悲剧
      • 3. 收 Diss 五级分类
      • 4. 被 Diss 的应对姿势
        • 4.1 就事回击
        • 4.2 让步升级
        • 4.3 存档与外部背书
      • 5. 评审别人的黄金句式
        • 5.1 措辞的杀伤力
        • 5.2 十条黄金句式
        • 5.3 提问代替断言
      • 6. Review 分层策略
        • 6.1 三层评审模型
        • 6.2 层次决定深度
        • 6.3 谁 Review 什么
      • 7. 大 PR 的评审技巧
        • 7.1 一次能读多少
        • 7.2 分段评审法
        • 7.3 走查会议辅助
      • 8. Review 反模式
      • 9. 把 Review 变教学场
        • 9.1 每次评审留一课
        • 9.2 团队评审规范
        • 9.3 Review 数据度量
      • 10. 综合案例串讲
        • 10.1 糖果充的第 18 次评论
        • 10.2 一次成熟评审全貌
        • 10.3 评审哲学回扣
        • 10.4 评审话术速查
    • 6.做事闭环执行能力
    • 7.资深程序员软能力
    • 8.需求评审博弈能力
    • 9.线上故障应急能力
    • 10.向上沟通汇报能力
    • 11.跨团队协作推进能力
    • 12.技术团队建设能力
    • 13.技术债与系统治理
  • 编程
  • 程序员精进路
杨充
2026-07-10
目录

5.代码审查攻防能力

# 5.代码审查攻防能力

# 目录介绍

  • 1. 案例引入
    • 1.1 被 Diss 17 次的 PR
    • 1.2 顺藤摸到根因
    • 1.3 我们要回答什么
  • 2. Code Review 全景图
    • 2.1 五种 Review 目的
    • 2.2 目的错配的悲剧
  • 3. 收 Diss 五级分类
  • 4. 被 Diss 的应对姿势
    • 4.1 就事回击
    • 4.2 让步升级
    • 4.3 存档与外部背书
  • 5. 评审别人的黄金句式
    • 5.1 措辞的杀伤力
    • 5.2 十条黄金句式
    • 5.3 提问代替断言
  • 6. Review 分层策略
    • 6.1 三层评审模型
    • 6.2 层次决定深度
    • 6.3 谁 Review 什么
  • 7. 大 PR 的评审技巧
    • 7.1 一次能读多少
    • 7.2 分段评审法
    • 7.3 走查会议辅助
  • 8. Review 反模式
  • 9. 把 Review 变教学场
    • 9.1 每次评审留一课
    • 9.2 团队评审规范
    • 9.3 Review 数据度量
  • 10. 综合案例串讲
    • 10.1 糖果充的第 18 次评论
    • 10.2 一次成熟评审全貌
    • 10.3 评审哲学回扣
    • 10.4 评审话术速查

# 1. 案例引入

# 1.1 被 Diss 17 次的 PR

糖果充支付重构进入编码阶段,第一周就交出一个大 PR——支付路由算法核心 300 行。信心满满,自我 review 三遍才提。结果 PR 上线 4 小时,已经收到 17 条评论,来自 5 位不同架构师:

评论 1  (架构师 A): "这个 if-else 太长, 改用策略模式"
评论 2  (架构师 A): "变量名 c 是什么? 至少写 channel"
评论 3  (架构师 B): "为什么不用 Guava Cache?"
评论 4  (架构师 B): "这段和你 3 个月前那个 PR 一模一样, 不能抽出来吗?"
评论 5  (架构师 C): "线程安全没考虑, 你这个 map 是 HashMap"
评论 6  (架构师 C): "test 覆盖率不够 40%"
评论 7  (架构师 D): "命名不符合我们的 style guide, 见 P.12"
评论 8  (架构师 D): "这个方法太长, 拆成 3 个"
评论 9  (架构师 E): "为什么不用 Optional 而用 null 判断?"
评论 10 (架构师 A): "构造函数参数太多, 用 Builder"
评论 11 (架构师 B): "Log 级别写错了, 这应该是 warn 不是 info"
评论 12 (架构师 C): "SQL 拼接有注入风险, 用 PreparedStatement"
评论 13 (架构师 D): "这段代码和 3 年前老王写的 PayHelper 有点像"
评论 14 (架构师 E): "你这写法有点像刚入行的......"
评论 15 (架构师 A): "package 结构不对, 应该按 DDD"
评论 16 (架构师 B): "@糖果充 你确定这个业务场景是这么定义的?"
评论 17 (架构师 A): "综上, 建议这个 PR 整体推翻重写"

结论:糖果充看完五味杂陈。其中有真正的技术问题,有 style 挑剔,有 3 年前的旧账,还有阴阳怪气。他花了 6 小时逐条回复,越回越气,最后差点删库跑路。3 天后 PR 还没合并,找 Leader 老王吐槽:

糖果充: "老王, 我这 PR 是真有那么烂吗?"
老王: (看了看) "有的评论确实要改, 有的其实可以怼回去,
              有的是这几位架构师之间的口水战, 跟你无关。
              你分不清哪个是哪个, 一律全改, 所以 3 天了还没进展。"

糖果充: "那我该怎么应对?"
老王: "你要学会给每条评论定级——什么必须改、什么可以让、
      什么必须怼、什么请上级仲裁。
      不是所有 Diss 都值得回应, 也不是所有意见都必须接受。"

# 1.2 顺藤摸到根因

带着这条线往下挖:代码烂?不是,方案通过、逻辑正确;架构师故意刁难?部分,但大部分是善意;那问题在哪?评论没分级 + 应对没策略;为什么老手能处理 17 条不崩?他们有分级机制——Nit/Question/Suggestion/Blocker/Attack 五级;每级怎么应对?不一样,有的接、有的驳、有的升级。这些机制就是本篇主线。

翻车现场的表象与真实问题:

表象                          真实问题
────────────────────────────────────────────
17 条一起看崩溃                → 没分级, 大脑处理不了 17 个并行冲突
每条都逐字回复                 → 没策略, 时间被稀释到 nit 上
"我改我改我都改"              → 无原则让步, 失去自主权
"你这写法像刚入行"          → 被攻击后没反击, 心态崩了
3 天不 merge                   → 没主动 escalate 到老王仲裁

根因:糖果充以为"Code Review = 别人挑错我改错",其实 Code Review = 集体优化代码的协作博弈。博弈就有策略,不该全盘接受。这一段藏着 8 个原理点:① Review 到底要达成什么、就是挑错吗?→ 第 2 章;② 17 条怎么分类才不崩?→ 第 3 章;③ 每种评论怎么应对?→ 第 4 章;④ 评审别人时怎么措辞不树敌?→ 第 5 章;⑤ 大 PR 怎么评审不漏?→ 第 6-7 章;⑥ 谁应该看什么?→ 第 6 章;⑦ 常见反模式?→ 第 8 章;⑧ Review 能否变成团队成长机会?→ 第 9 章。

# 1.3 我们要回答什么

这个事故就是本篇的主线案例。本篇路线:Review 全景图(第 2 章)→ 收 Diss 五级(第 3 章,"分类")→ 应对姿势(第 4 章,"分类后怎么办")→ 评审黄金句式(第 5 章,"评别人不树敌")→ 分层策略(第 6 章,"谁看什么")→ 大 PR 技巧(第 7 章)→ 反模式(第 8 章)→ Review 变教学场(第 9 章)→ 综合案例(第 10 章,糖果充的第 18 次评论)。

📌 本篇定位:Code Review 是日更的战场——每周你会经历数十次。这些 daily interaction 累积决定了你在团队中的位置。评审能力好的人,3 年后是 Tech Lead;评审能力差的,3 年后还在写 CRUD。

# 2. Code Review 全景图

# 2.1 五种 Review 目的

Code Review 不是一件事,是五件事:① 缺陷发现(找 bug/性能/安全);② 知识共享(打破孤岛);③ 风格对齐(命名/格式/包结构);④ 教学指导(资深带新人);⑤ 集体所有权("代码是团队的,不是你的",避免单点)。

对照糖果充的 17 条评论:

① 缺陷 (要改):   #5, #11, #12       (线程安全/日志/SQL 注入)
② 知识 (可讨论): #4, #13            (是否可复用旧代码)
③ 风格 (小改):   #2, #7, #8, #15    (命名/style/结构)
④ 教学 (选择性): #1, #3, #9, #10    (策略模式/Guava/Optional/Builder)
⑤ 集体 (讨论):   #6                 (测试覆盖率)
攻击 (要顶):     #14                (阴阳怪气)
无效 (拒绝):     #17                (整体推翻建议)
过时 (拒绝):     #4                 (3 年前的旧账)

17 条 = 4 条必改 + 3 条可讨论 + 5 条小改 + 3 条选择性 + 2 条要驳。不是全都要接受。

# 2.2 目的错配的悲剧

Review 者和作者对"目的"理解不同会怎样?目的错配是 Review 冲突的根源:作者眼中"我在做 P0 交付,Review 是缺陷发现";Reviewer 眼中"我在教年轻人,Review 是教学指导"。冲突:作者想快速 merge 只改 bug,Reviewer 想让作者学会最佳实践逐行挑,结果作者觉得"挑刺"、Reviewer 觉得"不听话"。

关键动作:PR 描述里主动申明本次 Review 的目的:

PR 描述模板:

## 变更目的
XX 支付路由算法, 关闭 issue #123

## Review 期望
- 主评审: 老王 (功能正确性 + 架构一致性)
- 副评审: 老李 (性能 + 线程安全)
- 建议评审: 老张 (代码风格)

## 时间紧迫度
下周三前必须上线 (灰度 M2 依赖)

## 特别请关注
- 支付路由核心算法 (PayRouter.java line 45-180)
- 缓存策略 (是否用 Guava, 请老王决策)

结论:主动申明目的 + 主评审 + 时间线——评审者按你的框架来,冲突降 80%。

# 3. 收 Diss 五级分类

面对 N 条评论,第一步是归类。五级定义、判别、示例、应对姿势一览:

级别 特征 判别信号 典型示例 应对姿势
① Nit 挑刺 微小、可改可不改、多为审美 nit: 前缀 / "这行末尾多空格" 变量名 c → channel;import 顺序 全接受,5 分钟改完,别争
② Question 疑问 不确定,想问清楚 "为什么用 A 而不是 B?" "为什么用 HashMap 不用 ConcurrentHashMap?" 认真答,展示思考深度(评论者在"帮你想",不是"挑刺")
③ Suggestion 建议 建议 A 改 B,未强制 "或许 / 可以考虑" / optional: "建议改策略模式";"或许 Guava Cache 更好?" 判断价值 + 时间,采纳或拒绝(附理由)——决策权在你
④ Blocker 拦截 必须改,否则不能 merge 语气严肃 / must fix / P0 SQL 注入;HashMap 并发;泄漏手机号 立刻改 + 感谢指出(涉及 bug/安全/合规/架构一致性)
⑤ Attack 攻击 对人不对代码,带情绪 阴阳怪气 / 提及资历 "你这写法像刚入行的" 就事回击 + 存档 + 私下 Leader 反馈(详见 4.3)

记忆口诀:Nit 全接、Q 认真答、S 自决策、Blocker 秒改、Attack 必顶。分错级 = 后面动作全错。

# 4. 被 Diss 的应对姿势

# 4.1 就事回击

什么样的评论必须回击而不是接受?回击的三种情形:① 评论技术上错——评论说"HashMap 线程不安全",现实是只在单线程构造后不可变,回击、解释场景;② 评论过时——评论提"3 年前老王的 PayHelper 类似",现实是老代码已过时、不复用是有意为之,回击、说明原因;③ 评论是个人偏好——评论说"我觉得应该用 Optional",现实是热路径有性能开销,回击、拿数据。

回击的姿势三段式:

① 承认关切: "谢谢指出" / "这个问题我也想过"
② 陈述事实: "但实际上 X 因为 Y" (给数据/场景/文档)
③ 请对方评估: "看这样解释您还有疑问吗?"

示范 - 评论 #5 "线程安全没考虑, 你这个 map 是 HashMap":
糖果充回复:
"谢谢老李, 关于线程安全我要澄清:
 这个 map (channelMap) 在构造函数中初始化后即为只读,
 参考 line 32 的 Collections.unmodifiableMap.
 在只读场景下 HashMap 是安全的。
 如果我漏考虑了什么并发场景, 请具体指出? 我马上验证。"

关键:回击不是对抗,是"帮 Reviewer 理解上下文"。Reviewer 会感激,而不是记仇。

# 4.2 让步升级

让步的三种情形:① 评论技术上对(SQL 注入 → 立刻改,感谢指出);② 评论虽有争议但影响不大(变量名 c → channel,别争 nit);③ Reviewer 是权威且不改也没大问题(老王建议用 Builder,5 分钟改完的事不值得较劲)。

升级的两种情形:

① 评论方法论层面, 涉及团队规范
   评论: "package 结构应该按 DDD"
   现实: 这不是一个 PR 能决定的, 涉及整个团队
   → 升级到 Leader / 架构组统一决策
   话术: "package 结构涉及全项目, 建议起一个专门议题
         在下周架构对齐会上讨论, 本 PR 沿用现有约定"

② 评论超过你能承担的返工
   评论: "综上建议整体推翻"
   现实: 已经写了 3 天, 时间不允许
   → 升级到 Leader / 项目经理
   话术: "整体重写会影响 M2 交付,
         建议本 PR 满足功能 + 关键指标,
         优化项拆到下个迭代, 已录 Ticket #456"

结论:让步、回击、升级三选一——根据评论级别 + 时间 + 权威度决定。

# 4.3 存档与外部背书

面对攻击型评论怎么办?攻击型评论要处理,但不能激化。三步走:

Step 1: 就事论事回复, 语气平静
Step 2: 私下找 Leader 反映, 存档
Step 3: 请第三方架构师背书

示范 - 面对"你这写法有点像刚入行":

公开回复 (专业):
"感谢您指出, 想具体请教一下:
 '刚入行的写法'具体是哪个点? 是命名、结构、还是逻辑?
 我想理解并改进。"

私下 (Leader 反馈):
"老王, 这条评论 (贴链接) 我觉得越界了。
 具体的技术问题都欢迎, 但我希望后续避免这种表述。
 我已经在 PR 里做了专业回复, 想跟您对齐处理原则。"

外部背书 (架构师):
"老陈, 我这个方案下周想请您独立评审一下,
 主要是这段 (贴链接), 想听听您的看法。"

关键:你越平静,Reviewer 越显失态。观众判定站在你这边。Code Review 不是私斗——存档 + 上报 + 背书三管齐下,把关系博弈拉回到"技术评审"。

# 5. 评审别人的黄金句式

# 5.1 措辞的杀伤力

反过来,我 Review 别人时怎么措辞才不伤人?同一件事,措辞不同,效果差 10 倍:

❌ 断言式:  "这里错了"
❌ 教导式:  "你应该这样写"
❌ 人身式:  "你怎么这么写?"
❌ 讽刺式:  "这写法真是......"

✅ 请教式:  "这里我有个疑问, 场景 X 下会不会出问题?"
✅ 共谋式:  "如果这样改, 是不是能避免 Y?"
✅ 数据式:  "我们的规范 P.12 里推荐用 Z, 这里是不是也用一下?"

心理原理:代码是作者的孩子。你怎么说他的孩子,决定他怎么回应你。

# 5.2 十条黄金句式

收藏这 10 条,直接用在你的评论里:

1.  "有个疑问, 场景 X 下会怎么处理?"         (Question 型)
2.  "建议考虑改用 X, 因为 Y。可选。"          (Suggestion 型)
3.  "nit: 变量名建议改成 X"                   (明确标 nit, 表明不强制)
4.  "这里必须改, 因为涉及 X (安全/合规)。"    (Blocker 型, 说清原因)
5.  "我在 X 场景下遇过类似坑, 供参考: <链接>" (给经验)
6.  "跟我们规范 P.X 不一致, 是有意为之?"     (给规范)
7.  "如果是我我会 X, 但你的做法也 OK, 你判断。"(给选择权)
8.  "这段和 X 类似, 是否可以复用?"           (探询)
9.  "整体思路很好, 只有 3 个 nit 请看下。"   (先肯定后细节)
10. "赞 X 的做法, 值得团队推广。"             (显性认可)

结论:这 10 条覆盖 95% 场景,记住 3 个也够用。

# 5.3 提问代替断言

核心技巧:尽量把断言改成提问:

断言           →   提问
──────────────────────────────────────────
"这里错了"     →   "这里我不太确定, 能否解释一下?"
"用 Redis"    →   "有没有考虑过 Redis?"
"应该拆分"     →   "拆成 3 个是否更清晰?"
"命名不对"     →   "这个名字含义是什么? 我担心 XX 场景会误解"
"不应该复制"   →   "这段和 XX 类似, 有无复用可能?"

心理原理:断言 → 作者感觉"被评判" → 防御 → 冲突;提问 → 作者感觉"被咨询" → 思考 → 合作。Review 的目的是让代码更好,不是让作者认错。提问比断言效果好 3 倍。

# 6. Review 分层策略

# 6.1 三层评审模型

所有 PR 都应该被所有人 review 吗?Review 分三层,深度不同:

Layer 关注点 主要评审人 预期投入
L1 功能正确性 Correctness 逻辑对不对、边界条件、测试覆盖 主评审(最熟业务的人,有 approve 权) 30-60 分钟,逐行看核心逻辑
L2 架构一致性 Architecture 分层是否合规、循环依赖、命名/包/接口合规 副评审(Tech Lead / 架构师,有架构否决权) 15-30 分钟
L3 风格与优化 Style & Polish 命名、格式、注释、微优化 建议评审(任意团队成员,无 merge 阻断权) 5-15 分钟

# 6.2 层次决定深度

关键规则:每个 PR 必须至少 1 位 L1 主评审 + 1 位 L2 副评审;作者 24h 内响应所有评论。对照糖果充案例:5 位架构师参与全是 L2/L3,L1 主评审老王反而没时间深看——结果糖果充被 L2/L3 意见淹没,L1 核心正确性反而没充分讨论。分层错位 = 大 PR 灾难。规范里应该定义"每个 PR 必须有 1 位 L1 主评审"。

# 6.3 谁 Review 什么

推荐规则:

PR 类型 L1 主评审 L2 副评审 L3 建议
业务功能 同组资深 Tech Lead 任意
架构改造 Tech Lead 架构组 Leader
核心中间件 该中间件 owner 架构组 + 安全 任意
数据库 schema DBA Tech Lead 任意
前端 UI UI 设计师 + 前端 Lead / 任意

关键:PR 描述里明确写出主评审是谁——避免 5 位都以为自己是主评审的悲剧。

# 7. 大 PR 的评审技巧

# 7.1 一次能读多少

300 行的 PR 到底能不能一次评审?Cisco 研究 (2006):200 行以下缺陷发现率 70%+;200-400 行 40%;400-800 行 25%;800+ 行 < 10%。每 200 行是一个"评审注意力单元"。300 行 PR 已在"低效评审区"——Reviewer 只能挑到表面问题,深层 bug 溜过去。

规则:✅ ≤ 200 行一次评审;✅ 200-400 行强烈建议拆分;❌ > 400 行必须拆分,除非有特殊理由。

# 7.2 分段评审法

拆不了怎么办?拆不了就分段评审:

糖果充 300 行 PR 分段建议:

第 1 段 (Line 1-60):    接口定义 + 数据模型   评审 15 min  重点: 契约设计
第 2 段 (Line 61-150):  核心算法              评审 30 min  重点: 逻辑正确性
第 3 段 (Line 151-250): 缓存/优化             评审 15 min  重点: 性能
第 4 段 (Line 251-300): 测试                  评审 10 min  重点: 覆盖率

Reviewer 侧技巧:一次评审只看一段,分 4 次评审完,注意力恢复后缺陷发现率维持在 60%。

# 7.3 走查会议辅助

太复杂的 PR 光看 diff 不够怎么办?走查会议 (Code Walkthrough)——作者屏幕分享,主评审面对面看。

适用场景: PR > 300 行 / 涉及新架构 / 有 3+ 位关键 Reviewer

流程 (45 分钟):
- 0-5 min:   作者讲背景 + 变更目标
- 5-25 min:  逐段过代码, 主评审提问
- 25-40 min: 副评审提问
- 40-45 min: 达成共识 + 下一步 Action

产出:
- 会议纪要列出必改项 (Blocker)
- 建议项作者自行判断
- 会后 24h 内作者更新 PR

结论:走查会议 = 大 PR 的救命稻草,比 17 条书面评论有效 5 倍。

# 8. Review 反模式

Review 场上最常见的六种死法,一张表看清:

反模式 症状 危害 修复动作
① 只挑不给方案 "这里不对"/"这样不好"——没说怎么改 作者不知怎么办,来回问、效率极低 每条评论必须包含"改进方向"——即使"建议试试 X"也比"这里不对"好 10 倍
② 无关个人偏好 "我不喜欢 Streams,你别用"/"都用 Optional" 把私人品味当团队规范,作者无所适从 只针对团队规范和技术必要性提意见——个人偏好不该出现在 Review 里
③ 教条主义评审 "必须用策略模式"/"违反 SOLID" 为模式而模式,过度设计、增加复杂度 逼问"这个改动能带来什么具体收益"——说不出的模式改造不该强推
④ 迟评审黑洞 PR 提了 3 天没人 review 作者上下文丢失、冷启动成本高,分支越搁越难 rebase 团队 SLA:24h 内至少 1 次响应,48h 内主评审给出定性
⑤ 情绪化对抗 作者"我改的都对!"/Reviewer"你懂什么!" 技术讨论变私斗,观众取关,项目瘫痪 Leader 介入,把 PR 移到走查会议——能公开讨论的不该在评论里对撕
⑥ 一次否决全部 "综上,建议整体推翻重写" 极度打击作者——3 天代码被一句话否决 否决整体前必须 Leader / 架构组一起决策——单个 Reviewer 无一票否决权

判词:六种反模式的共同根因是**"把 Review 当审判而非协作"**。把它当"集体优化",六种病一起消。

# 9. 把 Review 变教学场

# 9.1 每次评审留一课

Review 除了改 bug,还能怎么产出价值?每次 Review 都是团队知识流转的机会:方法:每次 Review 结束后,作者 / 主评审抽 5 分钟总结,写入 Wiki。

PR #123 复盘 (存到 Wiki)
─────────────────────────────
变更: 支付路由算法
教学点:
  1. 只读 Map 用 unmodifiableMap 包装
  2. SQL 必须用 PreparedStatement
  3. 大 PR 应该拆分成 3-4 个
团队规范更新:
  - 已提 PR #456 更新规范 P.15

结论:Review 教学化 = 团队复利——同样的 bug 不会在下一个 PR 重犯。

# 9.2 团队评审规范

建议团队制定 Review 规范(示例):

团队 Code Review 规范 V1.0

1. PR 大小
   - ≤ 200 行: 常规评审
   - 200-400 行: 需要拆分说明
   - > 400 行: 走查会议

2. 评审角色
   - 主评审: 1 位 (功能+架构 approve 权)
   - 副评审: 1-2 位 (架构一致性)
   - 建议评审: 任意 (nit 与 suggestion)

3. SLA
   - 24h 内至少 1 次响应
   - 48h 内主评审给出定性
   - 作者 24h 内响应所有评论

4. 评论格式
   - nit: xxx (可改可不改)
   - Q:   xxx (疑问)
   - Suggestion: xxx (建议)
   - Blocker: xxx (必改)

5. 冲突升级
   - 24h 内 Reviewer/作者未达成一致 → Tech Lead 仲裁
   - 涉及架构原则 → 架构组仲裁

# 9.3 Review 数据度量

度量指标(月度):① 首次响应时间 < 4h 工作时间;② PR 平均评论轮次 < 3 轮;③ Merge 前平均时长 < 24h;④ 大 PR 比例(> 400 行)< 10%;⑤ 复审率(上线后因 Review 漏过而回滚)< 1%。度量 → 复盘 → 改进 → 循环。没度量的 Review 规范 = 一纸空文。

# 10. 综合案例串讲

# 10.1 糖果充的第 18 次评论

回到糖果充。他跟老王聊完后,静下心把 17 条评论按五级分类:

分类结果:

Blocker (4 条 - 必改):
  #5  线程安全澄清
  #11 Log 级别改 warn
  #12 SQL 注入 → PreparedStatement
  #6  测试覆盖率补到 80%

Suggestion (5 条 - 选择性接受):
  #1  策略模式 → 现阶段 if-else 更清晰, 拒绝
  #3  Guava Cache → 采纳
  #9  Optional → 热路径, 拒绝
  #10 Builder → 采纳
  #15 DDD package → 升级到架构组

Nit (5 条 - 全改):
  #2, #7, #8, #13 → 全部 15 分钟改完

Question (2 条 - 认真回答):
  #4  和 3 年前旧代码重合 → 解释不复用原因
  #16 业务场景定义 → 附上 PRD 链接

Attack (1 条 - 就事回击):
  #14 "刚入行的写法" → 请教具体点

否决 (1 条 - 升级):
  #17 整体推翻 → 升级到老王仲裁

然后他把第 18 条自评论放在 PR 顶部:

[作者说明] 感谢 5 位架构师提出的 17 条评论。
我按以下策略处理, 请指教:

## 必改 (Blocker) - 已修复
- #5  线程安全: 澄清 channelMap 只读, 已加 unmodifiableMap
- #11 Log 级别: warn ✅
- #12 SQL: PreparedStatement ✅
- #6  测试: 覆盖率提到 82% ✅

## 采纳 (Suggestion)
- #3  Guava Cache: 已引入
- #10 Builder: 已重构 PayContext

## 说明后暂不改 (Suggestion)
- #1  策略模式: 当前 3 个分支, if-else 更易读,
       拆分留待第 5 个分支加入时
- #9  Optional: 热路径每秒 3 万次, 有性能开销.
       已 benchmark 附在 P.5

## 升级仲裁
- #15 DDD package: 涉及全项目, 已升级到架构组 (@老陈)
- #17 整体推翻: 已请 Leader (@老王) 仲裁

## 认真回答
- #4  3 年前旧代码不复用: 因业务逻辑已迭代, 复用反而增耦合. 详见附录 A.
- #16 业务场景: PRD 链接 <url>, section 3.2

## 就事请教
- #14 "刚入行的写法": 想请具体指出是命名、结构、还是逻辑? 愿意听并改进.

Nit 部分已全部修改 (#2, #7, #8, #13).

请各位再看一轮, 提前感谢! 目标下周三前 merge.

# 10.2 一次成熟评审全貌

24 小时后,结果:

Reviewer A (架构师):
- #1  策略模式:      "OK, 按你的判断"
- #15 DDD package:  "已跟架构组对齐, 本 PR 沿用"

Reviewer B:
- #3  Guava:        "赞"
- #4  3 年旧代码:    "理解, 通过"

Reviewer C:
- #5  线程安全:      "unmodifiableMap 我漏看了, 我的问题"
- #6  覆盖率:        "82% 达标, 通过"

Reviewer D:
- #14 (原作者):     "抱歉之前措辞不当, 具体是 line 78 的 if 嵌套太深,
                     建议提早 return. 已提新评论 #19"

Reviewer E:
- #9  Optional:     "看到 benchmark, 说服了"
- #10 Builder:      "赞"

Leader 老王:
- #17 整体推翻:      "本 PR 保持不动, 未来 refactor 单独立项"

48 小时后:PR merged。所有 Reviewer 认可,老王事后跟糖果充说:

老王: "这次你处理得漂亮。三件事我特别欣赏:
      1. 分类回复, 没被淹死
      2. 部分坚持, 用数据说话
      3. 引架构组仲裁 DDD package, 是资深动作"

糖果充: "我明白了, Code Review 不是挨批, 是博弈。"

# 10.3 评审哲学回扣

回望糖果充这次翻盘,代码审查攻防能力的本质是段位递进:初级全部接受(被淹)→ 中级部分接受(会挑刺)→ 高级分级应对(Nit/Q/Sug/Blocker/Attack)→ 资深引导 Review(指定主评审 + 分段 + 走查)→ 大师Review 教学化(每次留一课,团队复利)。

Review 应对的三层修炼:第一层分类能力(17 条不再淹死你);第二层应对策略(回击/让步/升级三选一);第三层主导 Review(PR 描述指定主评审 + 分段)。

核心命题:Code Review 是团队日更的战场——你处理 Review 的方式,累积决定你在团队中的位置。能优雅处理 17 条评论的人 = 能扛住 100 人团队——这是资深工程师的重要能力信号。

# 10.4 评审话术速查

Code Review 应对速查表:

场景 动作
收到 Blocker 立刻改 + 感谢指出
收到 Suggestion 判断价值/时间,采纳或拒绝(附理由)
收到 Question 认真回答 + 展示思考深度
收到 Nit 全接受,5 分钟改完
收到 Attack 就事回复 + 存档 + 私下反馈 Leader
收到"整体推翻" 立刻升级 Leader / 架构组仲裁
PR 冲突升级 24h 未达一致 → Tech Lead 仲裁
大 PR 300+ 行 拆分 or 走查会议
PR 描述必写 目的 + 主评审 + 时间线 + 关注点
作者自评论 顶部说明"如何处理 N 条评论"

十条黄金句式(Review 别人时)+ PR 描述模板:

1.  "有个疑问, 场景 X 会怎么处理?"
2.  "建议改用 X, 因为 Y。可选。"
3.  "nit: 变量名建议改成 X"
4.  "这里必须改, 因为 X (安全)。"
5.  "我在 X 场景遇过类似坑: <链接>"
6.  "跟规范 P.X 不一致, 有意为之?"
7.  "如果是我我会 X, 你的做法也 OK, 你判断。"
8.  "这段和 X 类似, 可以复用吗?"
9.  "整体很好, 有 3 个 nit 请看下。"
10. "赞 X 做法, 值得团队推广。"

─── PR 描述模板 ───
## 变更目的
XX 支付路由算法, 关闭 issue #123
## Review 期望
- 主评审: 老王 (功能+架构)
- 副评审: 老李 (性能)
- 建议评审: 老张 (风格)
## 时间紧迫度
下周三前必须上线
## 特别请关注
- 支付路由核心 (PayRouter.java L45-180)
- 缓存策略 (是否用 Guava)

下一集预告:Higress 网关方案落地过程中,糖果充发现需要四个部门协作——业务/架构/运维/安全。第一次跨部门推进,老板下命令"两周搞定",结果第 3 周他还在群里问"XX 什么时候能给数据",项目原地打转。**第 06 篇《做事闭环执行能力》**告诉他"拿结果不是交作业"。


本篇速查表:

维度 关键武器
分类 Nit / Q / Sug / Blocker / Attack 五级
应对 就事回击 / 让步 / 升级 三选一
评审措辞 提问代替断言 + 十条黄金句式
分层 Layer 1 / 2 / 3 + 主/副/建议评审
大 PR ≤ 200 行 / 分段 / 走查会议
反模式 只挑不给 / 私人偏好 / 教条 / 迟评 / 情绪 / 一票否决
教学化 每次留一课 + 团队规范 + 度量
#Code Review#协作#软技能
上次更新: 2026/07/21, 18:07:53
4.应对技术质疑能力
6.做事闭环执行能力

← 4.应对技术质疑能力 6.做事闭环执行能力→

最近更新
01
audit
07-27
02
C++入门教程全章思考题汇编
07-24
03
12.技术团队建设能力
07-21
更多文章>
Theme by Vdoing | Copyright © 2019-2026 杨充 | MIT License | 鄂ICP备2024073355号-1 | 鄂ICP备2024073355号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式