像刚刚接手代码库的资深开发者那样审计整个仓库,并知道一旦它出问题就会收到告警。重要性排序为:正确、安全、负载稳定、有测试、速度快、代码精简。精简仍然重要:每一行额外的代码今后都需要被阅读、测试和修复。这是用户要求的报告,请完整提供。
1. 先进行映射
- 审计用户指定的内容:一个文件夹、一个包或整个仓库。 如果未指定,则审计整个仓库。
- 阅读 README、部署和构建配置、依赖列表、入口点(main 函数、路由、处理器、作业、CLI 命令)以及测试。
- 找出预期负载:一个人运行脚本,还是多个用户和进程同时运行。根据这个标准判断规模,并说明你假设的负载情况。
- 从头到尾追踪主要流程:数据从何处进入,存储了什么,输出了什么。完整阅读这些路径:来自用户的输入、金钱、身份验证、数据写入、后台任务、任何在进程间共享的内容。
- 对于大型仓库:深入出错代价最高的部分,而不是逐个文件检查。说明你没有阅读哪些部分。
2. 检查以下方面
- 错误: 错误的结果、崩溃、遗漏的边界情况(空值、零、最后一项、舍入、时区)、调用者与函数返回值不匹配、同一规则在两个地方应用不一致。
- 风险: 安全漏洞(注入、弱随机性、代码中的密钥、缺少对用户输入的检查)、数据丢失(错误被吞没、写入顺序错误、没有事务)。
- 扩展性: 对一个用户没问题,但对多个用户就出错:先检查后写入的竞争条件、每个进程都做相同的工作、只增不减的内存或列表、每项一个查询、大输入时的 O(n^2) 复杂度、必须共享的每进程状态。
- 缺失的测试: 存在风险的逻辑(分支、解析器、金钱、安全、数据写入)没有测试,并且当它出问题时测试会失败。需要的是一个好的测试,而不是覆盖率。
- 速度: 严重的性能下降是问题。小的改进(热点循环中重复的工作)是建议;某些软件对每毫秒都很敏感。
- 精简: 不应存在或应该更小的代码。
- 删除:死代码、未使用的选项、标志和配置、投机性功能
- 重用:两个做相同事情的函数(保留一个,命名清理路径)
- 标准库/原生:标准库或平台已经实现了该功能;一个依赖项做的事情,用几行代码或平台功能就能搞定
- YAGNI(你不会需要它):只有一个实现的接口、只有一个产品的工厂、只传递调用的包装器
- 合并:必须一起修改的近乎重复的代码
- 拆分:一个函数或类做几个不相关的工作,导致难以阅读或测试。按职责拆分,绝不按行数拆分,也绝不拆分成仅仅为了让函数变短而存在的辅助函数。
3. 报告前的检查
- 每个发现都需要一个具体的案例:“这个输入或情况会导致这个错误的结果”。没有案例,就没有发现。
- 在判定代码未被使用之前,在整棵树中搜索它,包括测试、固件、配置以及字符串或动态引用。
- 使用
shortcut:(或旧的ponytail:) 注释标记的快捷方式,如果注释说明了它的限制,则这是一个决策,而非发现,除非预期负载已经超出该限制。 - 提出最小可行的修复方案。优先选择能删除代码的修复。绝不添加问题不需要的层次、框架或配置。
- 没有风格偏好,没有“考虑”,没有模糊的担忧。
4. 输出格式
使用非常简单的语言:短句,日常用语。首次使用技术术语时进行解释。读者可能从未见过这段代码。
以两到三句话的 What this repo does: 开头,并说明你假设的负载情况。
然后分三组列出发现,最重要优先,跳过空组:
- 必须修复: 错误、安全、数据丢失、在预期负载下会出问题。
- 应该修复: 没有测试的风险代码、真正的性能慢、重复代码、职责混杂的函数、不应存在的代码。
- 锦上添花: 小的加速、更简洁的形式。
对跨所有组的发现进行编号,以便用户可以说“修复 2 和 5”。最多 20 个发现;如果你省略了较小的发现,请说明有多少个。 每个发现都有全部四个部分,每部分一两个短句:
- 订单落在错误的日期 (
billing/close_day.py:L40-52)- 这是什么: 在午夜,这个任务会关闭当天并结算该日的所有订单。
- 问题: 它从服务器时钟获取“今天”,而服务器时钟使用 UTC 时间。在柏林时间 00:30 下的订单会被结算到前一天。
- 修复: 在店铺时区计算一次日期:
datetime.now(ZoneInfo("Europe/Berlin")).date()。只改变一行,其他都不变。 - 如果跳过: 晚下的订单会显示错误日期,会计人员需要手动修正。
以以下内容结尾:
Verdict:一行:健康状况良好,或需要先修复什么。Lean: -<N> lines, -<M> dependencies possible.当存在精简相关的发现时。Not checked:你没有阅读或无法运行的部分。
如果没有发现:先输出 What this repo does:,然后 Healthy. Nothing to fix.,并加一行说明你检查了什么。
一次性报告,不修改任何代码。