文 / STEM Career 编辑部
Code Review 面试需要你阅读一个改动,判断哪些问题影响行为、哪些属于后续优化,并把意见说成作者能执行的修改。找到很多风格细节,不一定代表评审有价值。
下面用原创 Python 金额汇总函数,练习从需求、差异、边界与测试出发。它是教学例子,不是任何企业的真实面试题,也不处理真实订单或财务数据。
先确认改动要完成什么
教学需求是:输入订单记录,汇总 status 为 paid 的金额;金额使用整数最小单位;空列表返回零;重复调用不应受到先前调用影响。示例记录格式由题目保证,暂不处理退款与多币种。
这些条件应该先于评审意见。若题目没有说明金额单位、负值或状态范围,先询问,再决定是否存在缺陷。不要因为现实业务复杂,就给一个小任务强加所有可能需求。
阅读一段有问题的初稿
def paid_total(orders, seen=[]):
total = 0
for order in orders:
if order['status'] == 'paid':
seen.append(order['amount_minor'])
for amount in seen:
total += amount
return total
第一轮先按一条 paid 和一条其他状态的记录手算。再想函数连续调用会怎样。默认列表会在调用之间保留,因此第二次结果可能混入第一次的金额。
问题不是变量名不够漂亮,而是行为违反独立调用的要求。一个最小反例能让评审意见更容易确认,也能避免靠语气争论。
用具体输入展示影响
第一次输入 paid 金额三百,预期三百;第二次输入 paid 金额二百,预期二百。初稿第二次会把已有三百一起算进来,得到五百。
如果先前没有 paid 记录,问题可能暂时不显现。因此只测一次正常调用会漏掉它。评审时说明触发条件和结果,比笼统写“这个默认参数有风险”更有帮助。
Python 官方默认参数说明解释了相关语言行为。面试里仍需要把这个行为连接到当前需求与反例。
提出最小而完整的修复
def paid_total(orders):
return sum(
order['amount_minor']
for order in orders
if order['status'] == 'paid'
)
本题不需要保留 seen。修复移除了跨调用状态,同时保留题设中的整数金额与状态过滤。若业务后来需要按订单去重,应另加明确标识与规则,不能假定金额相同就是重复订单。
代码更短不是修复成立的依据;关键是它满足需求,并能通过对独立调用与边界的检查。
检查要能揭示旧问题
assert paid_total([]) == 0
assert paid_total([
{'status': 'paid', 'amount_minor': 300},
{'status': 'pending', 'amount_minor': 900}
]) == 300
assert paid_total([
{'status': 'paid', 'amount_minor': 200}
]) == 200
这组顺序调用覆盖了原缺陷,同时检查空输入与状态过滤。还可以增加零金额和多条 paid。每项都说明它保护什么要求,不为凑数量重复同一种输入。
Google 的代码评审指南讨论了设计、功能和测试等关注点。用于本题时,把关注点落到实际代码与证据,而不只逐项念原则。
怎样排列修改优先级
会导致错误汇总的问题需要先修。题设没有规定的退款、输入校验或多币种,先列为澄清项;变量命名和形式调整,可以在行为确认后再讨论。
| 意见类型 | 本题例子 | 推荐表达 |
|---|---|---|
| 必须修复 | 跨调用列表保留金额 | 给出连续调用反例 |
| 需要确认 | 是否允许退款或多币种 | 询问输入与规则 |
| 可后续优化 | 文档或命名调整 | 说明具体阅读收益 |
优先级要随影响解释,不能只用“严重”“最佳实践”等标签。作者需要知道为什么改,以及怎样确认改好。
评审评论可以怎样写
原创评论示例:“默认列表会在多次调用间保留。先调用金额 300,再调用金额 200,第二次会返回 500。当前需求要求独立汇总,建议移除共享列表,并加入连续调用检查。”
这段话包含位置、机制、影响和建议。语气可以直接而友好,不需要对作者能力作判断。若某项只是个人偏好,可以标明可选,避免让次要意见阻塞主要修复。
如果不能确定问题,先表达疑问与验证办法。比如“不清楚 amount_minor 是否已经统一币种,能否确认数据契约?”比直接要求加入完整换汇系统更合适。
新条件出现后怎样继续
同伴现在提出:“同一订单可能因重试出现两次。”先问是否有稳定订单标识,以及同一标识的状态是否可能变化。确认后再选择数据层或函数层的去重方式。
如果两条记录金额一样但订单不同,不能合并。若同一订单先 pending 后 paid,需要定义以什么时间或版本判断。新的需求改变了模型,原修复不能自动解决。
这轮追问检验你能否持续阅读需求,而不是背下某种语言陷阱。也能让你说明哪些问题属于当前改动、哪些需要后续范围确认。
与调试和自己写代码的区别
调试通常从错误现象追踪原因,评审则从变更与需求判断是否可接受。两者都需要证据,但信息起点和协作方式不同。
可以用软件调试练习训练定位,再用技术面试沟通与测试练习解释。完整准备应让你既能指出问题,也能说明修改与验证。
面试前安排一次短评审
给自己十分钟阅读需求和 diff,写下最重要的两条意见;随后用五分钟口头说明,再让同伴扮演作者提出一个条件变化。时间安排只是练习建议,实际按邀请要求执行。
复盘时看自己是否先抓行为、是否给出反例、是否区分确定缺陷与待确认条件。找到很多评论并不自动更好,优先讲清最有影响的部分。
金额单位清楚以后再谈扩展
本题用整数最小单位,避免在教学汇总中引入浮点表示问题。它不意味着可以把不同币种直接相加,也不意味着退款一定应该用负值表示。这些都属于需要新规则的业务条件。
假设输入现在出现两条金额同为三百的记录,但订单标识不同,它们应分别计入;如果同一标识出现两次,则需要按已确认的重复规则处理。仅用金额去重,会把两笔真实交易错误合并。
可以在评审中把这些问题列为契约澄清,同时保留当前确定的缺陷优先级。不要因为能够想到更多复杂情境,就让已经证明的错误迟迟无法修复。
测试之间也要保持独立
如果检查只在单独运行时通过、按不同顺序执行就失败,可能存在共享状态。原例的默认列表正会产生这种表现。可以先运行一笔订单,再运行空列表,观察旧实现仍带出先前金额;修复后空列表始终返回零。
这个反例直接保护独立调用要求,属于有意义的验证。复盘时记录触发顺序与预期结果,让作者和评审者都能复现,而不是仅写“所有测试通过”。
修复评论与可选优化可以分开写,帮助作者先完成最重要的行为变更。你也可以肯定一个已经合理的设计,再具体指出问题;反馈的目标是让改动可理解、可验证,而不是证明评审者能找到最多细节。
加微信时说明评审任务
如果能写代码,但不确定怎样阅读别人的改动、提出优先级或解释边界,可以加微信说明目标岗位、技术栈和面试形式。还没收到邀请,也可以先沟通专项准备范围。
通过技术面试与项目辅导,先用代表性任务找出缺口,再安排代码、测试和表达练习,更容易形成能迁移到新题的工程判断。
常见问题(FAQ)
评审应先改风格吗?
先看需求与行为影响,再讨论次要优化。
为什么默认列表会出错?
可变默认值在多次调用之间保留,案例会混入旧金额。
新需求出现后能直接套旧修复吗?
需重新核对数据契约和业务规则。
- Python 官方默认参数说明· Python
- Google 的代码评审指南· Google
如果能写代码,却不知道怎样解释别人代码中的风险,加微信说明面试形式和技术栈,可以先沟通适合做哪类专项练习。
