代码评审最怕什么?不是技术分歧。是没人说话。
代码评审不是流程仪式,是工程动作。一个拉取请求挂了两天,下面只有一句“LGTM”。看着挺和谐。其实没人真正读过。等上线炸了,大家才发现那个空指针、那个没加的索引、那个被改掉的超时时间。麻烦在于,代码评审经常被当成流程仪式,而不是工程动作。
先别急着夸代码优雅
我见过不少评审现场。有人一上来就挑命名,说变量名不够表意。有人抓着缩进和分号不放。还有人把个人偏好包装成最佳实践。说实话,这些不是不能聊,但它们不该占掉评审的主要注意力。
评审先看什么?看这段变更会不会把系统搞坏。边界条件、错误处理、并发竞争、权限校验、数据迁移、回滚路径。再看它能不能被下一个人维护。最后才是风格。风格能交给 formatter 和 linter 的,就别用人眼去吵。

有个很简单的判断:如果一条评论删掉,代码行为不变,只是写法变了,它大概率是 nit。nit 可以提,但要标清楚。别让作者以为不改正就不能合并。阻塞性评论和非阻塞性评论混在一起,是评审效率的隐形杀手。
八百行 PR 谁看谁麻
大 PR 是灾难现场。不是评审者懒,是人的工作记忆就那么点。你让一个人一次看八百行,他只能扫描。扫描出来的结论通常很浅:看起来没问题。然后合并。然后事故。
拆小。按逻辑拆,不是按文件拆。一个 PR 只做一件事。重构和功能别混在一起。格式化提交单独放。依赖升级单独放。这样评审者能建立上下文,作者也容易回滚。
麻烦在于,拆分本身要花时间。很多人赶进度,心想先合并再说。代价呢?评审质量下降,缺陷漏出,后期修 bug 的时间翻倍。这笔账不复杂,只是经常被忽略。

还有一种情况:PR 不大,但描述等于没有。“修复问题”“优化逻辑”“调整配置”。评审者得自己猜意图。这很耗人。作者多写三行:改了什么,为什么改,怎么验证,风险在哪。评审速度会明显不同。
评论只写这里有问题等于没说
评论要带证据。最好带替代方案。只写“这里有问题”,作者得猜。猜错了,来回好几轮。更糟的是,语气一冲,讨论变成防御。代码评审不该是权力游戏。
我会建议一个简单的写法:指出具体行为,说明触发条件,给出建议,标明优先级。比如“这个重试没有幂等键,网络抖动时可能重复扣款。能不能在进入重试前生成唯一键?这个我觉得是阻塞项。” 短,但信息够。
作者也别急着回“我本地没问题”。本地没问题不代表生产没问题。评审者看到的是风险,不是对你人的否定。把评论当成排雷报告,会好受很多。
工具能干的别让人干
工具能干的别让人干。单元测试、类型检查、静态扫描、依赖漏洞、格式检查,这些应该进 CI。人只在工具报不出来或者报得太多的地方介入。人肉检查格式,纯属浪费。评审时间应该花在语义上:这个状态机是否完整,这个缓存失效策略是否安全,这个数据库查询会不会在数据量上来后拖垮接口。
但工具也不是万能。有些缺陷需要业务上下文。比如一个优惠券叠加逻辑,测试全绿,但产品规则里“互斥”和“可叠加”的边界没覆盖。评审者如果懂业务,就能问出来。这也是代码评审的价值:知识在团队里流动,而不是锁在某个人的脑子里。

异步评审为主,同步评审兜底。复杂设计、跨模块改动、争议大的方案,约个短会,屏幕共享走一遍。别把所有评审都拖进会议。也别把所有评审都丢进评论区。看情况。
文化坏了流程再漂亮也没用

最怕两种极端。一种是橡皮图章,秒过。另一种是过度评审,每个 PR 都像答辩。前者积累技术债,后者消耗士气。中间那条线,靠团队自己磨。
评审者轮值是个办法。别总让最资深的人看所有代码。他会累,其他人也长不大。新人评审可以先看小 PR,跟着老人学怎么提问题。作者也要学会过滤反馈:该改的改,不认同的给出理由,别沉默。
代码评审不是为了让代码变得完美。完美不存在。它是为了在成本还低的时候,把明显的问题拦住。顺便让团队对系统有共同理解。这事没那么玄。认真读,具体说,及时回。能做到这三点,已经赢过很多团队了。