代码走查的建议,为什么总是"说了等于没说"?
上个月,我在一次代码走查里又说了那句话:
"这个不用这次改,下次咱们统一注意一下。"
说完我自己就愣住了。因为这已经是第三次说同一句话了。第一次是三个月前,第二次是上个月,第三次是现在。每次都是"下次注意",每次都没人注意——包括我自己,也没真正记住。
这件事让我开始认真想一个问题:
为什么代码走查(Code Review)里的建议,大多数都像扔进水里的石头,连个响都没有?
一、先承认一个残酷的事实
如果把过去半年代码走查里提出来的建议翻出来看,真正被执行的比例低得可怜。
剩下的去哪了?大致分三类:
- "这次先不改,下次注意" —— 这类占最多,且基本等于"永远不改"
- "线下跟他说一下" —— 说完就忘,没有任何记录
- "提了,但当时在忙别的,回头就忘了" —— 连提的人自己都忘了
这不是态度问题,也不是谁不负责。这是机制问题。
人脑不会自动记住"待办事项",尤其是那些没有后果的待办。你口头说一句"下次注意",这句话在你脑子里存活可能不超过 10 分钟。
二、为什么"口头提醒"必然失效
我们来拆解一下,一句走查建议从"说出"到"执行",中间要跨过几道坎:
| 环节 | 现实情况 | 结果 |
|---|---|---|
| 建议被提出 | 会议里口头说的 | 没有载体 |
| 建议被记录 | 没记,或只记在个人脑子里 | 大概率丢失 |
| 建议被分配 | 没明确到人、没截止时间 | 无人负责 |
| 建议被跟踪 | 没有人回头看 | 无疾而终 |
| 建议被执行 | 全靠自觉 | 看心情 |
只要中间任何一环断了,这条建议就死了。
而口头提醒这条链路,每一环都是断的。
更糟的是,"这次不用改,下次注意"这句话本身就有毒——它给了对方一个免于行动的许可,同时也给了自己一个不用较真的台阶。大家都很体面,问题一个没解决。
三、最真实的借口:"任务紧,没时间改"
上面那套链路分析,还是有点"理想化"。因为现实里最常见的情况,其实是这样一句话:
"知道要改,但这两天需求太赶了,先这样,回头有空再说。"
这句话几乎是每个团队的日常。它比"下次注意"更具体,也更无可奈何——因为它某种程度上是真的。项目有排期,需求有 deadline,季度有考核,改一个"不影响功能"的规范问题,优先级天然排在最后。
但问题在于:"回头有空"永远不会到来。
我们来算一笔账,这类建议的典型命运:
| 时间 | 状态 |
|---|---|
| 走查当天 | "记下了,回头改" |
| 一周后 | 需求上线了,忙着处理线上问题,忘了 |
| 一个月后 | 完全想不起来了,代码已经上线,改的成本变高了 |
| 三个月后 | 同一个人在新代码里,又犯了同样的问题 |
注意最后一行。 这才是真正致命的地方:
"没时间改"不会让问题消失,它只会让问题以更高的成本、在更多的地方重新出现。
你今天省下的那半小时,会在未来以十倍的成本还回来——而且还不止还一次。
所以"任务紧"不是不改的理由,它是"必须让机器来管"的理由:
- 靠人改,永远排在需求后面,永远"没时间"
- 靠机器拦,它在提交那一刻就挡下来,成本最低、耗时为零、不需要任何人"抽时间"
能被机器自动修的,就别让它占用人的"赶需求时间"。 能被机器拦住的问题,从一开始就不该进入"队排到后面"这个队列。
换言之:不是要挤出时间改,而是要让这类问题根本不消耗时间。
四、更底层的问题:走查的时机,本身就是错的
上面说的都是"建议提出之后"的问题。但还有一件事,比这些更根本。
一种很常见的做法是:代码写完,再走查。而且走查代码的同时,顺便走查技术方案。
看起来挺全面,但其实这里藏着一个流程错误:
技术方案,本应该在编码之前就定下来。
现在的实际情况往往是:
| 阶段 | 本该发生的事 | 实际发生的事 |
|---|---|---|
| 需求 → 设计 | 技术方案评审、定架构、定关键实现 | 常常跳过,或草草口头对一下 |
| 设计 → 编码 | 按方案实现 | 边写边想,方案在脑子里 |
| 编码 → 走查 | 检查"实现是否符合方案" | 方案和实现一起审,边审边定方案 |
看出问题了吗?
当你在走查代码的时候还在讨论技术方案,意味着方案是"在代码里"定的——而那时候,代码已经写完了。
这带来两个后果:
第一,方案错误会被"实现成本"绑架。 方案放在编码前评审,改起来只是改几张图、几段文档;放到编码后评审,改起来就是推倒重写。所以人会很自然地妥协——"算了,都写完了,先这样吧"。于是方案错误被固化进了代码。
第二,走查被迫同时承担两个目标,反而都做不好。 "审方案"需要发散、讨论、权衡;"审实现"需要聚焦、对照标准。这两件事混在一次会议里,结果就是方案没讨论透,实现也没查干净——而这批没查干净的问题,又变成了下一轮的"下次注意"。
所以这一层的问题是:
走查的位置放错了。它被当成了"方案 + 实现"的兜底,而不是"实现是否符合既定方案"的验证。
正常的逻辑应该是:
- 编码前:技术方案先评审、先定稿(哪怕只是一页纸)
- 编码中:实现对照方案走,方案变了就回头改方案
- 编码后:走查只做一件事——检查实现与方案是否一致,以及方案没覆盖到的细节问题
把走查从"方案评审"里解放出来,它才可能真正聚焦在"规范执行"上。
而这也解释了为什么很多建议总是"下次注意"——因为这一轮走查里,一半的精力用去补前面该做但没做的方案评审了。
那该怎么办?——走查本身应该分阶段
顺着这个思路,其实解法也是清楚的:走查不该是一次性的,而要跟着任务的大小分阶段。
一个任务如果很大、代码量很多,一次性走查必然出问题——评审者看不过来,讨论没重点,问题没查透。合理的做法是按阶段拆开:
| 阶段 | 走查内容 | 时机 | 关注点 |
|---|---|---|---|
| 第一阶段 | 整体代码框架 | 骨架搭好、还没填满细节时 | 分层是否合理、模块划分对不对、关键抽象是否成立 |
| 第二阶段 | 核心逻辑实现 | 主体代码完成后 | 思路是否正确、边界是否考虑、异常是否处理 |
| 第三阶段 | 细节与规范 | 功能基本完成后 | 命名、日志、注释、代码风格、细节实现 |
这样拆的好处很明显:
第一,问题在"最便宜"的时候被发现。 框架错了,在第一阶段改,只是调几个类;如果等到全部写完再走查,框架问题就意味着大规模重构。越早发现,越不用"下次注意"。
第二,每次走查都是"单目标"的。 第一阶段只讨论结构,不纠结命名;第三阶段只管细节,不推翻架构。评审者精力集中,问题才查得干净。
第三,大任务被拆成了可执行的小任务。 "这次先不改,下次注意"有时候真的不是态度问题——是任务太大,改动面太广,一次改不完。分阶段走查之后,每个阶段的改动都是收敛的,执行成本自然就降下来了。
所以你看,"走查频率"本身就是一个规范:任务越大,越要拆成更多阶段;一次性堆到最后走查,几乎必然会积压一堆"下次注意"。
问题不在于"这次要不要改",而在于"这个问题本该在哪个阶段就被发现"。
五、核心矛盾:能被机器管的事,我们在用嘴管
我认为问题的根子在这里:
我们用了太多"人治"的手段,去管那些本该"机制"来管的事情。
展开说,走查建议其实分两类:
第一类:能被机器判断的(占多数)
比如:
- 命名不规范
- 某个方法太长、嵌套太深
- 日志打得不规范
- 层与层之间不该跨的依赖(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、或经常做代码走查,我想听听:
- 你们团队代码走查的建议,真正执行的比例大概是多少?
- 你是怎么处理"这次不改,下次注意"这类建议的?
- 有没有哪个"说了一百遍还是有人犯"的规范,最让你头疼?
如果你也觉得这个问题真实存在,欢迎在评论区聊聊,或者直接私信我。
我最近在琢磨做一个小工具,专门解决这个问题——把团队的口头规范变成机器强制、可追踪、可统计的机制。
如果你感兴趣,可以告诉我你想要的是什么样子的。也许你的一个反馈,就能决定它该长什么样。
(本文只讨论通用的工程管理方法论,不涉及任何具体公司、系统或代码。)