代码走查的建议为什么总是说了等于没说

62 阅读19分钟

代码走查的建议,为什么总是"说了等于没说"?

上个月,我在一次代码走查里又说了那句话:

"这个不用这次改,下次咱们统一注意一下。"

说完我自己就愣住了。因为这已经是第三次说同一句话了。第一次是三个月前,第二次是上个月,第三次是现在。每次都是"下次注意",每次都没人注意——包括我自己,也没真正记住。

这件事让我开始认真想一个问题:

为什么代码走查(Code Review)里的建议,大多数都像扔进水里的石头,连个响都没有?


一、先承认一个残酷的事实

如果把过去半年代码走查里提出来的建议翻出来看,真正被执行的比例低得可怜。

剩下的去哪了?大致分三类:

  • "这次先不改,下次注意" —— 这类占最多,且基本等于"永远不改"
  • "线下跟他说一下" —— 说完就忘,没有任何记录
  • "提了,但当时在忙别的,回头就忘了" —— 连提的人自己都忘了

这不是态度问题,也不是谁不负责。这是机制问题。

人脑不会自动记住"待办事项",尤其是那些没有后果的待办。你口头说一句"下次注意",这句话在你脑子里存活可能不超过 10 分钟。


二、为什么"口头提醒"必然失效

我们来拆解一下,一句走查建议从"说出"到"执行",中间要跨过几道坎:

环节现实情况结果
建议被提出会议里口头说的没有载体
建议被记录没记,或只记在个人脑子里大概率丢失
建议被分配没明确到人、没截止时间无人负责
建议被跟踪没有人回头看无疾而终
建议被执行全靠自觉看心情

只要中间任何一环断了,这条建议就死了。

而口头提醒这条链路,每一环都是断的。

更糟的是,"这次不用改,下次注意"这句话本身就有毒——它给了对方一个免于行动的许可,同时也给了自己一个不用较真的台阶。大家都很体面,问题一个没解决。


三、最真实的借口:"任务紧,没时间改"

上面那套链路分析,还是有点"理想化"。因为现实里最常见的情况,其实是这样一句话:

"知道要改,但这两天需求太赶了,先这样,回头有空再说。"

这句话几乎是每个团队的日常。它比"下次注意"更具体,也更无可奈何——因为它某种程度上是真的。项目有排期,需求有 deadline,季度有考核,改一个"不影响功能"的规范问题,优先级天然排在最后。

但问题在于:"回头有空"永远不会到来。

我们来算一笔账,这类建议的典型命运:

时间状态
走查当天"记下了,回头改"
一周后需求上线了,忙着处理线上问题,忘了
一个月后完全想不起来了,代码已经上线,改的成本变高了
三个月后同一个人在新代码里,又犯了同样的问题

注意最后一行。 这才是真正致命的地方:

"没时间改"不会让问题消失,它只会让问题以更高的成本、在更多的地方重新出现。

你今天省下的那半小时,会在未来以十倍的成本还回来——而且还不止还一次。

所以"任务紧"不是不改的理由,它是"必须让机器来管"的理由:

  • 靠人改,永远排在需求后面,永远"没时间"
  • 靠机器拦,它在提交那一刻就挡下来,成本最低、耗时为零、不需要任何人"抽时间"

能被机器自动修的,就别让它占用人的"赶需求时间"。 能被机器拦住的问题,从一开始就不该进入"队排到后面"这个队列。

换言之:不是要挤出时间改,而是要让这类问题根本不消耗时间。


四、更底层的问题:走查的时机,本身就是错的

上面说的都是"建议提出之后"的问题。但还有一件事,比这些更根本。

一种很常见的做法是:代码写完,再走查。而且走查代码的同时,顺便走查技术方案。

看起来挺全面,但其实这里藏着一个流程错误:

技术方案,本应该在编码之前就定下来。

现在的实际情况往往是:

阶段本该发生的事实际发生的事
需求 → 设计技术方案评审、定架构、定关键实现常常跳过,或草草口头对一下
设计 → 编码按方案实现边写边想,方案在脑子里
编码 → 走查检查"实现是否符合方案"方案和实现一起审,边审边定方案

看出问题了吗?

当你在走查代码的时候还在讨论技术方案,意味着方案是"在代码里"定的——而那时候,代码已经写完了。

这带来两个后果:

第一,方案错误会被"实现成本"绑架。 方案放在编码前评审,改起来只是改几张图、几段文档;放到编码后评审,改起来就是推倒重写。所以人会很自然地妥协——"算了,都写完了,先这样吧"。于是方案错误被固化进了代码。

第二,走查被迫同时承担两个目标,反而都做不好。 "审方案"需要发散、讨论、权衡;"审实现"需要聚焦、对照标准。这两件事混在一次会议里,结果就是方案没讨论透,实现也没查干净——而这批没查干净的问题,又变成了下一轮的"下次注意"。

所以这一层的问题是:

走查的位置放错了。它被当成了"方案 + 实现"的兜底,而不是"实现是否符合既定方案"的验证。

正常的逻辑应该是:

  1. 编码前:技术方案先评审、先定稿(哪怕只是一页纸)
  2. 编码中:实现对照方案走,方案变了就回头改方案
  3. 编码后:走查只做一件事——检查实现与方案是否一致,以及方案没覆盖到的细节问题

把走查从"方案评审"里解放出来,它才可能真正聚焦在"规范执行"上。

而这也解释了为什么很多建议总是"下次注意"——因为这一轮走查里,一半的精力用去补前面该做但没做的方案评审了。

那该怎么办?——走查本身应该分阶段

顺着这个思路,其实解法也是清楚的:走查不该是一次性的,而要跟着任务的大小分阶段。

一个任务如果很大、代码量很多,一次性走查必然出问题——评审者看不过来,讨论没重点,问题没查透。合理的做法是按阶段拆开:

阶段走查内容时机关注点
第一阶段整体代码框架骨架搭好、还没填满细节时分层是否合理、模块划分对不对、关键抽象是否成立
第二阶段核心逻辑实现主体代码完成后思路是否正确、边界是否考虑、异常是否处理
第三阶段细节与规范功能基本完成后命名、日志、注释、代码风格、细节实现

这样拆的好处很明显:

第一,问题在"最便宜"的时候被发现。 框架错了,在第一阶段改,只是调几个类;如果等到全部写完再走查,框架问题就意味着大规模重构。越早发现,越不用"下次注意"。

第二,每次走查都是"单目标"的。 第一阶段只讨论结构,不纠结命名;第三阶段只管细节,不推翻架构。评审者精力集中,问题才查得干净。

第三,大任务被拆成了可执行的小任务。 "这次先不改,下次注意"有时候真的不是态度问题——是任务太大,改动面太广,一次改不完。分阶段走查之后,每个阶段的改动都是收敛的,执行成本自然就降下来了。

所以你看,"走查频率"本身就是一个规范:任务越大,越要拆成更多阶段;一次性堆到最后走查,几乎必然会积压一堆"下次注意"。

问题不在于"这次要不要改",而在于"这个问题本该在哪个阶段就被发现"。


五、核心矛盾:能被机器管的事,我们在用嘴管

我认为问题的根子在这里:

我们用了太多"人治"的手段,去管那些本该"机制"来管的事情。

展开说,走查建议其实分两类:

第一类:能被机器判断的(占多数)

比如:

  • 命名不规范
  • 某个方法太长、嵌套太深
  • 日志打得不规范
  • 层与层之间不该跨的依赖(Controller 直接调 DAO)
  • 重复代码
  • 异常处理不规范

这些全都可以被工具自动检测。但你却在用嘴说,说完对方还用脑子记,记完还靠自觉改。

这是巨大的浪费。 机器一秒能做一万次的事,你在用一次会议、三句话、一个人脑去完成。

第二类:机器判断不了的(少数)

比如:

  • 命名是否符合业务语义
  • 这个抽象是否合理
  • 业务逻辑放在这一层是否合适

这类才需要人。但即便是这类,也不该用"下次注意"来处理,而应该变成可追踪的条目。


六、更隐蔽的损失:交接一次代码,那些"下次注意"去哪了?

前面所有讨论,其实都默认了一个前提:说的人和改的人是同一批人。

但现实里,代码是会流转的。人会走、团队会换、模块会交接。而一旦发生这种事,前面那些问题会被成倍放大。

因为在交接场景下,"口头建议"的命运是这样的:

场景口头建议的命运
同一个人、同一个团队至少还有机会"下次注意"
代码交接给另一个人口头建议直接归零
交接 + 原负责人离职"为什么这么写"彻底失传

具体来说,交接会带来三个新问题。

问题一:口头建议根本无法传递

"这个不用改,下次注意"——这句话只存在于当时的那次会议里。

它没有被写下来,没有被分配,没有被跟踪。所以当代码交接出去的时候,这条建议不会出现在任何交接材料里。

新人接手后,甚至不知道曾经有人提过这个建议。这不是新人不上心,是这条信息压根没被保存过。

问题二:技术债被"静默继承"

比丢失建议更糟的是,上一任攒下的技术债,会以"历史遗留"的名义被下一任继承。

新人看到一段说不清的代码,心里想的往往是:

"这应该是历史原因吧,我也搞不清为什么这么写,先别动它。"

然后在这段代码上面,继续加新的功能。

于是技术债不仅没被还,还成了新代码的地基。时间越久,越没人敢碰;越没人敢碰,它就越烂在那里。

问题三:最贵的损失——设计意图失传

这是三者里最隐蔽、也最贵的。

代码本身是能看到的,但**"为什么这么设计"往往只存在于原作者的脑子里**。

比如:

  • 这里本来有个更优雅的方案,因为某个坑没敢用
  • 这个看似冗余的判断,是踩过线上故障才加的
  • 这个"下次要重构"的地方,其实埋着一个还没解决的问题

这些全都不在代码里,也不在交接文档里。

结果就是两种灾难:

  • 新人推翻了一个本来有道理的设计,重新踩一遍当年的坑
  • 或者新人保留了一个本来就是错的实现,还以为它是"最佳实践"

代码可以交接,但"意图"如果没有被固化,就会随着人一起离开。

结论:这恰恰证明——建议必须被"固化"

回到最初的问题:走查建议为什么执行不了?

加上交接这个维度后,答案变得更强了:

因为建议没有被"固化成资产"。 而没有被固化的建议,连自己的寿命都撑不过一次人员变动。

这就回到了前面那条原则:能被机器管的,写成规则;不能被机器管的,变成可追踪的条目。

只有这两样东西,能跨越时间和人的变动存活下来:

  • 一条写进 CI 的规则,不会因为换人而失效
  • 一条登记在案的技术债条目,不会因为交接而消失

所以,交接场景不是"另一个问题",它是"必须把建议机制化"的最强论据。


七、真正有效的做法:把"建议"变成"机制"

如果让我重新设计一套走查机制,我会这么做。

原则一:能被机器拦的,绝不靠嘴说

把所有"下次一定要遵守"的规则,全部写成检查规则,接入 CI,不通过就不让合并。

规则能自动化的部分,交给:

  • 格式类:提交时自动格式化,不合规直接失败
  • 静态检查类:质量门禁,新代码问题超标直接阻断合并
  • 架构约束类:把"不许跨层调用""不许直接 new"这类纪律,写成可执行的测试规则

关键不是"检测出来",而是"拦截合并"。 只检测不拦截的检查,和没做一样——因为总有人会点"忽略"。

只提醒不阻断,就是温柔的无效。

原则二:机器判断不了的,必须变成"可追踪的条目"

一句话说清楚:

"本次不改"的建议,必须当场变成一条明确的任务,指派到人,带上截止时间。否则它就是一句客气话。

具体要求:

  • 所有建议落到代码评审系统的评论里,不再口头说
  • 要改的,标记为阻塞项,不改不给合
  • 本次不改的,当场创建任务,关联到代码变更,指派到人,设定时间

这样,三个月后你再回头看,每条建议的生死都有据可查。

原则三:让"重复出现的建议"自动升级为规则

这是最关键的一条。

同一条建议,如果你已经说过 3 次以上,那就说明:

这不是那个人不听话,是你的机制没跟上。

一条建议被重复提三次,它就应该从"口头建议",升级为"检查规则"。它不该继续靠人提醒,而该被写进工具,让机器替你说第 100 遍。


八、AI 的出现,正在补上最后一块拼图

上面这套方法论,其实有个一直没解决的死结:成本。

  • 写检查规则有成本,尤其架构约束那类,门槛很高
  • 把每条建议变成可追踪任务,靠人做,一样会忘
  • 判断"哪些问题值得固化成规则",需要经验,普通人做不了

过去,正是这些成本让"机制化"只停留在口号上——规则写起来太麻烦,不如口头说一句省事。

但这两年,编程大模型和代码智能体的进展,恰好把这几个成本全部打下来了。

变化一:规则的"生成"成本,几乎降为零

过去写一条架构约束规则,要查 API、写测试、调半天。现在你可以直接对模型说:

"检查一下这个模块,找出所有 Controller 直接依赖 DAO 的地方,并生成一条可以接入 CI 的架构约束规则。"

模型能读懂你的代码库,直接生成可执行的规则。

这意味着什么?意味着"把口头规范变成机器规则"这件事,从"工程师的额外工作"变成了"一句话的事"。

前面那条"重复三次就升级为规则"的原则,过去因为写规则太贵而无法执行,现在它变得可行了。

变化二:代码智能体,让"走查"可以按阶段自动执行

前面说走查要分阶段(框架 → 实现 → 细节),但人力有限,评审者不可能每个阶段都跟。

代码智能体正好补位:

走查阶段AI 智能体能做什么
框架阶段检查分层是否合理、依赖方向是否正确、是否有循环依赖
实现阶段检查边界条件、异常处理、空指针、资源泄漏
细节阶段检查命名、日志、注释、格式规范
全流程把"本轮新引入的问题"和"历史存量问题"分开报

尤其最后一条很关键。 人做走查时最大的困扰就是"存量问题太多,新问题被淹没"。而 AI 可以只盯着本次变更,精准指出"你这次新引入的问题"——这正是"下次注意"最容易漏掉的。

变化三:AI 让"建议"变得可执行、可分级

过去一条建议是"这个方法太长了"——抽象、无从下手。

现在可以让模型直接给出:

  • 具体怎么改:拆成哪几个方法,每个方法叫什么
  • 改动影响面:哪些调用方会受影响
  • 优先级建议:这是必须改的,还是可以进技术债池的

建议从"口头提醒"变成了"可执行的任务"。 前面说的"任务紧没时间改",有一部分原因就是建议太模糊、启动成本太高——现在这个门槛被大幅降低了。

变化四:最好的部分是——AI 自己就能被"规范约束"

还有一个更妙的点:

你可以把团队的规范,喂给 AI,让它在生成代码时就遵守。

过去规范是"事后检查",现在是"生成时对齐"。问题从"发现了还要不要改",变成了"压根不会产生"。

这是质的区别:

从"事后拦截" → 到"事前对齐"

但要警惕:AI 不能替代"机制"

这里必须泼一盆冷水。很多团队正在犯一个错:以为接入了 AI 代码助手,代码质量就自动上去了。

不会的。原因很简单:

  • AI 提了建议,如果没人追踪,还是会被忽略——问题没变
  • AI 发现了问题,如果不阻断合并,还是会被点"忽略"——问题没变
  • AI 每次都在提,但没人把它沉淀成规则——下次它还得再提一遍

AI 解决的是"发现问题和生成解决方案"的成本,解决不了"执行"的成本。

执行,依然要靠机制。

所以正确的组合是:

AI 负责"发现 + 生成规则 + 解释方案",机制负责"拦截 + 追踪 + 统计"。

两者缺一不可:

  • 只有人,没有 AI → 效率低,覆盖不全,靠自觉
  • 只有 AI,没有机制 → 建议一大堆,没人执行,噪音更大
  • AI + 机制 → 规则自动生成、自动拦截、自动追踪,人只做最后的判断

顺带说一个反直觉的观察

AI 时代,"代码走查"这件事的价值反而上升了。

因为代码的生产速度被 AI 大幅提高了。写代码越来越快,但"这段代码该不该这么写"的判断,依然需要人。生产快 → 需要评审的量更大 → 评审机制的重要性更高。

过去瓶颈在"写",现在瓶颈在"审"。谁能把"审"变成机制,谁就能真正把 AI 的产能释放出来。


九、一个反直觉的结论

想清楚这套机制之后,我意识到一件事:

代码走查最大的价值,不是"发现新问题",而是"发现应该被固化的规则"。

每一次走查,如果只是发现问题、口头说一句、然后结束——那这次走查的价值几乎为零,因为同类问题下次一定还会出现。

但如果每次走查的产出,都能沉淀成:

  • 一条新的检查规则(能被机器管的)
  • 或者一条可追踪的任务(不能被机器管的)

那么走查就在让团队的下限不断抬高。

走查不是为了让人改这一次,是为了让这件事以后再也不用说。


十、一个还在想的问题

写到这里,其实我还没完全解决它。上面这套方法论,落地起来还是有很重的成本:

  • 写检查规则要成本,尤其架构约束那类,门槛不低
  • 把每条"下次注意"变成可追踪任务,如果没有工具支撑,光靠人做,一样会忘
  • 规则散落在 CI 脚本、检查配置、任务系统里,没有一个地方能统一看到"我们跟哪些规范较劲过"

我现在的判断是:"能被机器管的规则"和"能被追踪的建议"之间,缺一个统一的、轻量的机制把它们串起来。

不知道是不是只有我遇到了这个问题。


说说你们的情况

如果你也是团队的 Tech Lead、或经常做代码走查,我想听听:

  1. 你们团队代码走查的建议,真正执行的比例大概是多少?
  2. 你是怎么处理"这次不改,下次注意"这类建议的?
  3. 有没有哪个"说了一百遍还是有人犯"的规范,最让你头疼?

如果你也觉得这个问题真实存在,欢迎在评论区聊聊,或者直接私信我。

我最近在琢磨做一个小工具,专门解决这个问题——把团队的口头规范变成机器强制、可追踪、可统计的机制。

如果你感兴趣,可以告诉我你想要的是什么样子的。也许你的一个反馈,就能决定它该长什么样。


(本文只讨论通用的工程管理方法论,不涉及任何具体公司、系统或代码。)