跳到正文
docai.cc

DOCAI · 课程 · L3 · 20 分钟 · 基础入门

代码修改与优化

改代码之前先摸清影响面,把「不能动什么」写进需求;重构、提速、补类型都拆成小步,每步用测试证明原有行为没被破坏。

Claude Code 程序员 · 基础使用指南

你将学会

  • 能在动手前问清调用方与影响范围
  • 能把兼容性约束写进修改需求
  • 能把重构与性能优化拆成可验证的小步

改之前,先问影响面

新增代码只影响自己,修改代码却牵动所有调用方。所以第一步不是下命令,而是摸底:

先别动手。这个邮箱校验函数被哪些地方引用、改动后哪些入口会受影响、现有测试能覆盖到什么程度,把这三件事列清楚再说话。

拿到调用清单,你再决定哪些行为必须保留。看不见的依赖,往往是线上事故的来源。清单列完再动手,能避免改到一半才发现方向错了。

把限制写进需求

改动的质量,取决于你有没有说清「不能动什么」。三条约束最常用:旧参数必须保留、接口签名不能变、不新增依赖。

给现有的搜索接口加一个排序参数,默认按相关度排序。 旧调用不传这个参数时,返回结果与现在完全一致。 不改返回结构,不新增第三方依赖。

这样写,它会在兼容的前提下扩展,而不是顺手把接口重设计一遍。加字段、加方法、加可选参数,都适用同一套说法。约束不是不信任,而是把返工挡在提交之前。

重构:一次只做一件事

重构最容易失控的地方,是「顺手」:拆函数时顺手改名,改名时顺手改逻辑。改完测试挂了,你都不知道是哪一步惹的。

目标 这一轮只做 留到下一轮
拆长函数 把代码搬进小函数,逻辑原样 改名、改判断顺序
消除重复 抽出公共处理 统一各处细节行为
改善命名 换名字,保留行为 调整结构
压平嵌套 把不满足的情况逐个提前挡回 合并条件、换算法

最后一项值得单独说:三层嵌套的判断,重构成「先挡掉不满足的情况,最后只剩成功路径」,读起来会顺很多。但这一步只调整结构,不改变任何分支的结果。判断条件本身是否合理,是另一件事,别在同一轮里改。

还有一个常被忽略的约束:改动的范围要和需求对得上。让它修一个空指针,结果它顺手重排了整个文件,diff 里几十行无关变化,审查的人根本看不出哪一行是关键。需求里写明「只改这一个函数」,diff 才会干净。

每一轮结束都跑一次相关测试。测试通过,再进入下一轮。

性能:先测量,再动手

没有测量数据的「优化」,多数只是换个写法。先定位瓶颈,再选手段:

  • 循环里反复查库,改成一次批量查询;
  • 热点数据加缓存,同时想清楚键名、过期时间和更新时怎么失效;
  • 列表渲染开销大,只在输入变化时重新计算;
  • 首屏图片太多,进入视口再加载。

每次只处理一个瓶颈,改完复测同一组指标。快了多少要有数字,不能凭感觉。

质量和安全:让验证可重复

补错误处理时,把行为写成清单:失败重试几次、间隔怎么增长、最终抛什么错、请求能不能中途取消。重试与退避的取舍见退避与重试。

把模糊类型换成具体类型、按项目配置统一格式、清理调试输出,这些都属于低风险改动,但同样要跑测试。大改造则拆成小步:先抽出一块,验证,再抽下一块,任何一步都能单独回滚。

改完做两件事:跑与该模块相关的测试,看输出而不是听话术;再看一遍改动范围,确认没有夹带无关修改。把这两件事变成习惯,修改才敢交给它做。

扩展与迁移:两类改动的固定动作

给现有函数加参数。 新参数一律可选,默认值等于旧行为。比如日期格式化原来只输出年月日,现在要支持三种格式:

formatDate(value)                 // 旧行为,保持 YYYY-MM-DD
formatDate(value, 'datetime')     // 带时分秒
formatDate(value, 'relative')     // 显示相对时间

指令里把三种取值和默认值写全,再补一句「不传第二参时,输出与现在逐字符一致」。接口加筛选参数同理:role、status、createdAfter 各自可选、可以组合,不传时结果集不变。

迁移到新格式。 依赖升级、第三方响应改结构、JavaScript 换 TypeScript,都走三项固定动作:先找全调用点,再机械替换,最后跑类型检查和测试。比如响应从 { data: { user } } 变成 { result: { userData } },先让它列出所有读旧字段的位置,确认清单完整再动手;缺一个,线上就多一个空值。

改完怎么判断有没有把握,见评估改动。三类症状对应三种处理:

现象 为什么 怎么办
单测全绿,线上仍报错 测试没覆盖真实调用方 先列调用点,补一条走真实入口的测试
优化后反而更慢 没有改前基线,凭感觉选手段 先记录耗时和次数,改完复测同一组指标
差异里混着大量格式变化 指令范围太宽,顺手格式化了整个文件 限定「只改这个函数」,提交前逐行看差异

改得动,还要讲得清。下一节看怎么把改动变成团队能接手的提交与审查:基础代码协作。

自测

先自己回答,再展开对照;答不上来就回到对应小节。
  1. 01为什么修改前要先问调用方有哪些?看答案

    同一个函数往往被多处复用,参数含义或返回结构一变,受影响的不只是你眼前这个页面。先列出调用点,才能判断哪些约束必须保留。

  2. 02重构和性能优化为什么不适合放在同一次改动里?看答案

    两者的验收标准不同。混在一起,一旦测试失败就分不清是结构问题还是性能改动引入的,回滚也会牵连无关部分。

查看 Markdown

涉及的概念

在知识树上