retro-coding — 代码复盘透镜
适用范围与边界
本 skill 覆盖代码编写、bug 修复和代码审查中的质量问题。
与其它 skill 的区分:
- 做了架构层面的设计决策(选型、分层)→
retro-design - 代码中数据处理逻辑的问题 →
retro-data - 调试和排错的过程 →
retro-debugging
不适用场景:架构选型/技术决策(用 retro-design)、算法设计(用 retro-experiment)、配置管理/部署脚本。
评估维度
1. 正确性
- 逻辑是否按预期工作?(不只是"看起来对",是否验证过?)
- 边界条件是否覆盖?(空输入、极值、特殊字符、0、负数)
- 是否有 off-by-one 错误?
- 条件判断是否正确?(
>vs>=、andvsor)
2. 健壮性与错误处理
- 错误是否被静默吞掉?(空的 except、没有日志的 catch)
- 外部依赖失败时是否有降级策略?(API 挂了、文件不存在、网络超时)
- 重试逻辑是否正确?(指数退避、最大重试次数、幂等性)
- 输入验证是否充分?(用户输入、文件内容、API 响应)
- 并发/异步场景下是否有竞态条件、死锁或异步异常处理遗漏?
3. 安全性
- 是否有硬编码的密钥/密码/Token?
- SQL 查询是否有注入风险?
- 文件路径是否有目录遍历风险?
- 敏感数据是否被意外记录到日志?
- 第三方依赖是否有已知漏洞?依赖版本是否过时?
4. 可维护性
- 命名是否清晰?(变量名、函数名一看就知道是干什么的)
- 函数是否单一职责?(一个函数做太多事?)
- 是否有必要的注释?(不是"做了什么"而是"为什么这样做")
- 配置是否与代码分离?(硬编码的路径/阈值/参数?)
5. 性能与效率
- 是否有不必要的重复计算?
- 数据结构选择是否合理?
- 是否有 N+1 查询问题?
- 大文件/大数据是否流式处理而非全部加载到内存?
6. 测试
- 关键路径是否有测试?
- 边界条件是否被测试覆盖?
- 是否有回归测试防止老 bug 复发?
常见反模式
| 反模式 | 检测信号 |
|---|---|
| 静默失败 | 空的 try-except,没有日志输出的错误处理 |
| 硬编码 | 代码中出现具体路径、IP、密码、阈值数字 |
| 过度工程化 | 为"可能的"需求写了一大堆抽象,当前只用到一个 |
| 过早优化 | 牺牲可读性换取不一定需要的性能 |
| 复制粘贴 | 同样的逻辑出现两次以上但没有抽取 |
| 注释与代码不一致 | 代码改了但注释没更新 |
| 不验证输入 | 直接使用用户输入/文件内容/API 响应不检查 |
| 缺少测试 | 关键路径无测试覆盖,边界条件未被测试验证 |
| 测试覆盖不均 | 只测了 happy path,错误路径和边界条件零覆盖 |
已固化模式
| 模式 | 适用信号 | 验证 | 来源 | |------|----------|------| | (待复盘时自动追加) | | | |
关键追问
挑刺式(找改进空间)
- 如果这段代码明天就出 bug,最可能出在哪里?
- 什么输入会让这段代码崩溃?
- 错误信息是否足够让后来者快速定位问题?
- 这段代码给后面的人挖坑了吗?(有隐含假设没写清楚?)
- 有没有更简单但同样有效的实现方式?
正向式(找值得复用的)
- 这次写的代码中,有没有写得特别漂亮、下次可以直接复用的模块或模式? (信号:某段代码被反复引用/参考、某个函数签名设计得特别好、某个抽象在后续任务中直接复用无修改)
- 有没有某个错误处理/边界检查的方式特别有效,值得固化为编码习惯? (信号:这个检查方式在不止一处被用到、或在后续任务中拦截了潜在 bug)
- 有没有某个代码组织方式或命名约定被证明特别清晰,减少了后续维护的认知负担?
反证条件指引
对于代码的正确性假设,追问:什么具体的输入或场景会让这段代码暴露出问题? (引导写出可操作的反证条件——如"如果输入 encoding 不是 UTF-8"而非空洞的"如果输入格式不对")