大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
反馈技巧
这一课你将能做到
- 写出「对事不对人」的建设性 review 评论,降低作者防御心理
- 区分「必须修改」「建议修改」「仅供参考」三种反馈强度
- 处理 reviewer 和作者之间的分歧,避免 PR 陷入僵局
为什么要学
Code Review 最大的成本不是时间,是人际关系成本。一句「这写的什么」可能让作者三天不想提交代码;一句「这里如果这样改会更好,因为...」能让作者心甘情愿改完还感谢你。
人话:Review 的目的是让代码变好,不是证明你比作者强。表达方式决定你的意见会不会被采纳。
先建立图像
反馈的三层强度
P0 - 阻断(Must Fix)
└─ 「这里存在 SQL 注入风险,攻击者可以通过 keyword 参数
注入恶意 SQL。必须改为参数化查询。」
→ 不修改不能合并
P1 - 强烈建议(Should Fix)
└─ 「这个函数 80 行,包含 3 个职责,建议拆分为
validateOrder / buildOrder / saveOrder 三个函数,
可读性和可测试性都会提升。」
→ 建议修改,但可协商
P2 - 仅供参考(Nit / Optional)
└─ 「nit: 变量名 `list` 太泛了,改成 `courseList` 更明确。
不改也行,看个人习惯。」
→ 可改可不改
标记强度能让作者快速判断优先级,避免在 P2 上浪费时间。
跟着做
步骤 1:用「提问」代替「断言」
❌ 反例:
这个实现是错的。
这样写性能很差。
你不应该这么设计。
✅ 正例:
如果两个用户同时调用这个方法,会不会都通过校验导致超卖?
我印象中这种写法在数据量大的情况下会有性能问题,
你有没有做过 benchmark 验证?
这个设计和现有模块的风格不太一致,是出于什么考虑?
为什么有效:提问让作者自己发现问题,比被告知「你错了」更容易接受。即使作者最后证明你错了,他也不会觉得被冒犯。
步骤 2:给理由,不给命令
❌ 反例:
改成用 Optional。
把这个拆成两个函数。
不要用这种方式。
✅ 正例:
建议用 Optional 包装返回值,因为调用方目前需要处理
null 的情况,用 Optional 可以强制调用方显式处理空值,
避免遗漏。
这个函数目前做了「校验 + 计算 + 持久化」三件事,
建议拆分为三个函数,这样每个函数可以独立测试,
后续修改时影响面也更小。
公式:建议 + 理由 +(可选)示例代码。
步骤 3:标记反馈强度
❌ 反例:所有评论混在一起,作者不知道哪些必须改
1. 这里有空指针风险
2. 变量名可以更好
3. 建议添加缓存
4. 这里逻辑不对
✅ 正例:明确分级
[blocker] 第 45 行存在空指针风险,当 course 为 null 时会 NPE。
必须修复。
[suggestion] 变量名 `list` 建议改为 `courseList`,更明确。
不改也行,看团队习惯。
[question] 这里每次查询都新建 Redis 连接,是出于什么考虑?
如果是担心连接池问题,我们可以用 Lettuce 的连接池。
[nit] 这个注释是多余的,代码本身已经很清晰了。
常用标签:
[blocker]/[must]:不修复不能合并[suggestion]/[should]:强烈建议修复[question]:需要作者解释[nit]/[optional]:吹毛求疵,可改可不改
步骤 4:处理分歧
❌ 反例:评论里来回争论
Reviewer: 建议用策略模式
Author: 这里用 if-else 就够了
Reviewer: 策略模式扩展性更好
Author: 现在只有两种情况,不需要扩展
Reviewer: 但以后可能增加
... 20 条评论后 ...
✅ 正例:升级到语音/面对面
Reviewer: 建议用策略模式,方便后续扩展新的支付方式。
你觉得呢?
Author: 目前只有支付宝和微信两种,短期内不会增加。
if-else 更简单。
Reviewer: 理解。那我们先保持简单,如果后续真的需要扩展,
再重构为策略模式。我在评论里标记一下这个技术债。
[resolved]
规则:评论来回超过 3 轮没结论,立刻转语音/面对面。文字容易升级情绪,语音能快速对齐。
步骤 5:写「正面反馈」
❌ 反例:只挑刺,不表扬
(全是修改意见,作者看完心情低落)
✅ 正例:认可好的部分
这个错误处理写得很到位,考虑了超时和重试的场景。
测试覆盖率很全面,连并发场景都覆盖了,赞。
这个重构把原来的 200 行函数拆得很清晰,可读性提升很多。
为什么重要:只挑刺会让作者觉得「review 就是挨批」,逐渐抵触提交 PR。正面反馈能强化好的行为,让作者知道「什么是对的」。
讲清楚要点
- 对事不对人:评论针对代码,不针对作者。「这里可能存在并发问题」而不是「你怎么没考虑并发」。
- 给理由不给命令:解释「为什么这样改更好」,让作者理解背后的原理,而不是机械执行。
- 标记反馈强度:用
[blocker]/[suggestion]/[nit]分级,让作者知道优先级。 - 提问优于断言:「这样会不会有问题」比「这样是错的」更容易被接受。
- 分歧及时升级:评论来回 3 轮没结论,转语音/面对面。文字争论效率极低且伤感情。
你可能会懵的地方
-
Reviewer 语气很好但作者还是不接受怎么办? 先确认是不是「理解层面」的问题——作者可能没理解你的建议。如果是,换种方式解释(画图、写示例代码)。如果是「观点层面」的分歧(你认为该扩展,他认为该简单),尊重作者的决定——他是代码的负责人。
-
作者代码写得很烂,怎么委婉地说? 聚焦在「具体的问题」而不是「整体的评价」。不说「这个设计太复杂了」,而说「这个函数包含了 5 个职责,建议拆分为 A、B、C 三个函数」。具体的问题有解决方案,整体的评价只会让人防御。
-
Reviewer 自己也不确定,要不要提? 要,但标记为
[question]或[uncertain]。「我不确定这里是否有并发问题,你验证过吗?」既表达了关切,又承认了自己的不确定性。 -
作者是我的上级,怎么提意见? 同样的原则:对事不对人、给理由、标记强度。职位高低不影响技术讨论。如果真遇到「职位压人」的情况,说明团队文化有问题,不是 review 技巧能解决的。
-
Reviewer 提的意见我不想改,怎么回应? 礼貌地解释理由:「感谢建议。我考虑过这种方案,但因为 XX 原因(性能、兼容性、时间),选择了当前方案。如果后续有扩展需求,我会按你建议的方向重构。」如果 reviewer 坚持,可以拉第三人仲裁。
错法对照
| 错法 | 问题 | 正解 |
|---|---|---|
| 「这写的什么」 | 人身攻击,引发防御 | 「这里可能存在 XX 问题」 |
| 只给命令不给理由 | 作者不理解为什么 | 建议 + 理由 + 示例 |
| 所有评论混在一起 | 作者不知道优先级 | 标记 [blocker] / [nit] |
| 评论里来回争论 | 效率低、伤感情 | 3 轮没结论转语音 |
| 只挑刺不表扬 | 作者抵触提交 PR | 认可好的部分 |
卡点急救
-
Review 气氛很紧张:暂停评论,私聊作者:「我感觉我们对这个问题的理解可能有偏差,要不要语音聊 10 分钟?」大多数情况下是误会。
-
作者对所有评论都回复「不改」:检查是不是评论方式问题(太强硬、没给理由)。如果不是,可能是作者防御心理过重,建议团队内做 review 培训。
-
Reviewer 提的意见明显是错的:礼貌地指出:「感谢建议。我查了一下文档,这种情况下应该用 XX 方式,因为 YY。你觉得呢?」给 reviewer 台阶下,同时坚持技术正确性。
面试常问
-
怎么处理 Review 中的分歧? 三步:① 评论里先尝试理解对方观点(提问而非断言);② 3 轮没结论转语音/面对面;③ 还无法达成一致,拉第三人或 tech lead 仲裁。关键是「不让 PR 卡住超过一天」。
-
怎么给负面反馈又不伤害作者? 公式:具体的问题 + 影响 + 建议的解决方案 + 理由。例如:「这里直接访问了数据库(具体),在并发场景下会导致连接池耗尽(影响),建议改为从连接池获取并限制并发数(方案),这样可以避免连接泄露(理由)。」避免「你总是」「你从来不」这种全称判断。
-
Reviewer 和作者谁有最终决定权? 作者有最终决定权,但 reviewer 有「不 approve 就不合并」的否决权。理想状态是「共识驱动」——双方说服对方或找到折中方案。如果实在无法达成一致,按「作者负责」原则:作者可以合并,但要承担后续维护责任。团队应该避免「reviewer 强压」或「作者硬闯」的文化。
自测三问
- 「提问式反馈」和「断言式反馈」在效果上有什么区别?
- 为什么要在 review 评论里标记
[blocker]/[nit]等强度标签? - Reviewer 和作者在评论里争论了 5 轮还没结论,应该怎么办?
小结一句话
反馈技巧的核心是「对事不对人、给理由不给命令、分级给优先级、分歧及时升级」——让 review 成为技术交流,而不是权力斗争。
延伸
- Google Engineering Practices - How to do a code review
- 《非暴力沟通》(马歇尔·卢森堡)
- 《Radical Candor》(Kim Scott)
- 下一课:团队实践——CODEOWNERS 与 SLA。