代码评审的“人效陷阱”:太严格拖慢进度,太松全是Bug

代码评审的“人效陷阱”:太严格拖慢进度,太松全是Bug

——一场关于“代码洁癖”与“交付速度”的拉锯战


前言

代码评审(Code Review,简称 CR)大概是技术团队里最微妙的存在。

不做吧,心里发虚——谁知道那个刚毕业的小伙子又把什么祖传代码提交上来了;做吧,又怕变成“大家来找茬”,一个 if 语句的缩进能讨论半小时,需求上线的时间线就这么被一寸一寸地蚕食。

我带过团队,也被别人评审过。我见过因为 CR 太松,线上事故频发,整个组周末都在救火的;也见过因为 CR 太严,一个功能从周一拖到周五,最后产品经理冲到工位前拍桌子的。

这中间的度,到底怎么拿捏?


一、两个极端:洁癖患者 vs 摆烂选手

先说说我见过的两种典型“人效陷阱”。

陷阱 A:完美主义者的泥沼

老张是我们组的高级工程师,技术很好,但有个“毛病”——眼里容不得一粒沙子

一次 CR,一个新功能提交上来,逻辑没问题,测试也通过了。老张开始评审:

“第 47 行的变量名 data 太泛了,建议改成 userOrderList。”

“这个工具类我们组之前有个类似的,建议抽成公共的。”

“这里的注释不够详细,建议补充一下边界条件的说明。”

每一条都有道理。但问题是,这个需求明天就要上线,而这些修改跟业务逻辑一毛钱关系没有。

作者乖乖改完,重新提交。老张又来了:

“嗯,变量名改了,但这个地方的空指针校验是不是可以再提前一点?”

一圈下来,一个 2 天的需求,CR 环节花了 1.5 天。

团队里开始流传一句话:“千万别让老张审你的代码,他会跟你讨论花括号换行的哲学。”

结果是什么? ​ 进度拖慢,大家开始“挑软柿子捏”——专找 junior 工程师互审,绕过老张。老张不高兴了,觉得团队不重视代码质量。团队也不高兴,觉得老张不接地气。

陷阱 B:走过场的灾难

另一边,小李的风格截然相反。

他的 CR 标准是:能跑就行。

“LGTM(Looks Good To Me)。”

“逻辑我看了,没啥问题,过吧。”

“测试通过了吧?那行,我点了。”

有一次,一个核心支付链路的逻辑被改了。小李审了 3 分钟,LGTM。结果上线后,因为少处理了一种异常分支,导致部分订单状态卡死。排查了一整夜,最后发现那个分支在代码里就少了一个 else

太松的 CR,等于没 CR。 ​ 它给你一种“我们已经审查过了”的安全感,但实际上什么漏洞都没拦住。


二、为什么我们会掉进这两个坑?

说白了,CR 的困境在于:评审者不知道自己该对什么负责。

太严的人,潜意识里觉得“我要对每一行代码的质量负责”。他们害怕将来出问题,追溯起来是自己放行的,所以把标准拉到最高。

太松的人,潜意识里觉得“代码是作者写的,我只负责看看有没有明显的低级错误”。他们把 CR 当成一个流程节点,而不是一个质量关卡。

两种心态,都跑偏了。

CR 的目的不是“让代码完美”,也不是“让代码不出错”。CR 的目的是在合理的时间内,以合理的成本,把风险降到可接受的范围。


三、我的解法:分层评审

踩过几次坑之后,我给团队定了一套“分层评审”的规则。核心思路是:不是所有代码都值得用同一个标准去审。

第一层:必须拦住的(红线)

这些东西,不管多急,都必须指出,必须改:

  • 安全漏洞:SQL 注入、越权访问、敏感信息明文打印
  • 数据一致性风险:事务缺失、并发问题、边界条件未处理
  • 性能隐患:N+1 查询、大循环里调 RPC、全表扫描
  • 可回滚性:上线后如果出问题,能不能快速回滚

这些东西一旦漏到线上,代价远大于多花 30 分钟改代码。

第二层:建议优化的(黄线)

这些东西,指出,但给作者选择权:

  • 命名不够清晰
  • 代码结构可以更好(比如方法太长、职责不单一)
  • 有重复代码可以抽公共
  • 注释缺失或不够准确

怎么处理? ​ 在评审里标注为“建议”,不阻塞合并。如果作者觉得有道理,顺手改了;如果觉得当前没时间,可以记一个 TODO,后续迭代优化。

第三层:纯风格问题(灰线)

这些东西,直接忽略:

  • 缩进风格
  • 花括号位置
  • import 顺序
  • 注释的标点符号

靠什么解决? ​ 靠工具。EditorConfig + Checkstyle + Spotless + Pre-commit Hook。人不要浪费时间在格式化上,让机器去管。


四、流程上的几个关键设计

光有分层标准还不够,流程设计决定了 CR 的效率和体验。

1. 控制评审粒度:别一次审 2000 行

一个 PR 超过 400 行,评审质量断崖式下降。这不是评审者的问题,是人脑的带宽限制。

做法: ​ 大功能拆成多个小 PR。每个 PR 只做一件事——要么加一个接口,要么改一个模块,要么修一个 bug。这样评审者可以在 15-20 分钟内审完,质量有保障。

如果实在拆不开(比如重构),那就提前跟评审者沟通,约个时间一起看,而不是甩一个 2000 行的 PR 到群里等人审。

2. 设定 SLA:评审不是无限期的

我们定了规矩:PR 提交后,2 小时内必须有人开始评审,8 小时内必须给出结论。

为什么?因为作者提交代码后,上下文还在脑子里。如果 2 天后才有人评审,作者可能已经切到别的需求了,再切回来改代码,上下文切换成本巨大。

紧急需求怎么办? ​ 标 urgent 标签,评审者 30 分钟内响应。如果评审者不在,找 backup。

3. 评审者不超过 2 人

一个人审太片面,三个人审效率灾难。我们规定:每个 PR 最多 2 个评审者。 ​ 一个是模块负责人(懂业务),一个是轮值评审(交叉学习)。

4. 用"评论类型"区分优先级

在评审工具里,我们要求用前缀标注评论的优先级:

  • [block] —— 必须改,阻塞合并
  • [suggest] —— 建议改,不阻塞
  • [nit] —— 吹毛求疵,可忽略

这样作者一眼就知道哪些评论是"必须处理的",哪些是"有空再看"。评审者也会被这个约定反向约束——你标了 [block],就得想清楚它到底值不值得阻塞。


五、一个真实的对比

我们组实施这套规则前后,数据对比:

指标之前之后
平均 PR 评审耗时1.5 天4 小时
平均 PR 行数800+250
线上 Bug 率(CR 后漏出的)每两周 3-4 个每两周 0-1 个
开发者对 CR 的满意度"又来了""还行,不怎么耽误事"

最关键的变化是心态。 ​ 以前大家把 CR 当成一个"审判",现在当成一个"协作"。评审者不再纠结于缩进,作者也不再觉得被冒犯。


六、最后想说的

代码评审的本质,不是找错,也不是炫技。它是一个团队在"交付速度"和"代码质量"之间达成共识的过程。

太严,团队会绕过你;太松,系统会绕过你。

好的 CR 标准应该是:漏出去的 Bug 你愿意在凌晨三点爬起来修,同时评审的时间不会让你的需求延期到被产品经理骂。

0
0
0
0
评论
未登录
暂无评论