第6课:实战交互——分析、生成与修改代码
环境、认证、模式都搞定了,现在让 Codex 真正干活。本课不空谈理论, **三种场景速览** | 场景 | 适用场景 | 典型任务 | 所需模式 | 输出形式 | | --- | --- | --- | --- | --- | | 分析 | 面试准备、性能排查、读懂陌生代码 | 时间复杂度/空间复杂度分析、可读性评估、性能瓶颈定位 | 对话模式 | 分析结论、推导过程、优化建议 | | 生成 | 补齐测试、类型定义等模板化任务 | 单元测试、TypeScript 类型定义 | 对话模式 | 可直接粘贴的完整代码或文件 | | 修改 | 已有代码重构、命名优化、错误修复 | 重构、拆分长函数、修语法错误 | `auto-edit` 模式 | 直接修改后的文件内容 | 直接给你三个可以立刻套用的实战场景:**分析、生成、修改**。 ## 一、代码分析:让 Codex 帮你读懂与评估 **场景:时间复杂度分析** 把函数丢给 Codex,让它评估算法复杂度: ```text 请分析下面这个函数的时间复杂度和空间复杂度,并指出可能的性能瓶颈: [粘贴代码] ``` 它会给出复杂度结论、推导过程,甚至指出哪里有优化空间。对于面试准备、性能排查都很有价值。 **提示词要点** 举一个具体的 Python 函数示例: ```python def has_duplicate(nums): """判断列表中是否存在重复元素(O(n²) 版本)。""" for i in range(len(nums)): for j in range(i + 1, len(nums)): if nums[i] == nums[j]: return True return False # 调用示例 print(has_duplicate([1, 2, 3, 4])) # 输出:False print(has_duplicate([1, 2, 3, 2])) # 输出:True print(has_duplicate([])) # 输出:False ``` 把它和前面的 Prompt 一起发给 Codex,可能得到这样的结论: - **时间复杂度:O(n²)**。两层嵌套循环逐对比较,最坏情况下需要比较约 `n(n-1)/2` 次。 - **空间复杂度:O(1)**。函数只使用两个整型循环变量,没有开辟随输入规模增长的额外空间。 - **可能的性能瓶颈**:重复比较过多;如果允许额外空间,可使用哈希集合把时间降到 O(n),但空间会升到 O(n)。 **优化前后对比** 把上面的函数改成哈希集合版本: ```python def has_duplicate_fast(nums): """判断列表中是否存在重复元素(O(n) 版本)。""" seen = set() for num in nums: if num in seen: return True seen.add(num) return False # 调用示例 print(has_duplicate_fast([1, 2, 3, 4])) # 输出:False print(has_duplicate_fast([1, 2, 3, 2])) # 输出:True ``` | 版本 | 时间复杂度 | 空间复杂度 | 数据规模 10 万时的大致表现 | | --- | --- | --- | --- | | 双层循环版 | O(n²) | O(1) | 约 50 亿次比较,明显卡顿 | | 哈希集合版 | O(n) | O(n) | 约 10 万次操作,毫秒级返回 | 可以看到,**用空间换时间**后,处理大规模数据时性能差距是数量级的。这正是让 Codex 做复杂度分析的价值:它不仅能告诉你结论,还能指出这条优化路径。 ## 二、代码生成:单元测试与类型定义 **场景 1:生成单元测试** 这是 Codex 最擅长的苦力活之一: ```text 为下面这个函数生成完整的单元测试,覆盖正常路径、边界条件和异常情况: [粘贴函数] ``` **场景 2:生成类型定义** 对于 JavaScript 等语言,可以快速补齐类型: ```text 为下面的数据结构生成完整的 TypeScript 类型定义: [粘贴数据结构] ``` 你会发现,这些“必须做但没人喜欢做”的任务,恰恰是 Codex 最能帮上忙的地方。 ## 三、代码修改:默认的自动编辑 在 `auto-edit` 模式下,你可以直接下修改指令: ```text 把上面这个函数重构成更清晰的命名,并拆分过长的逻辑,保持行为不变。 ``` Codex 会尝试直接修改文件。这里体现的是**从“给出建议”到“动手改”**的跨越——也是它区别于聊天 AI 的关键。 **常见错误与排查** Codex 修改代码也不总是一次到位,最常见的两类问题是: - **语法错误**:比如漏掉右括号、缩进层级不一致、引号不配对,或使用了当前语言不支持的写法。排查时直接看编译器/解释器给出的报错行,语法问题通常定位很快。 - **逻辑错误**:表面能运行,但结果不符合预期,例如改错了判断条件、把循环边界写错,或改变了对外接口的返回值类型。这类问题更隐蔽,需要结合测试用例来验证。 一个具体的错误示例:让 Codex 把函数改成列表推导式时,可能漏掉右方括号,导致 `SyntaxError`: ```python def filter_positive(nums): return [n for n in nums if n > 0 ``` 修复时,可以把完整的报错信息连同原函数一起回填给 Codex,并补充一句“请修正语法并保证返回类型与原函数一致”。运行单元测试,或至少用 `filter_positive([1, -2, 3])` 这样的简单输入复核结果,能更早发现这类低级错误。 **逻辑错误示例:返回值类型被悄悄改变** 比语法错误更隐蔽的是逻辑错误——代码能跑,但对外接口变了。比如让 Codex 把一个返回 `bool` 的函数改成“更简洁”的写法,它可能把返回值改成了 `int`: ```python # 原函数:返回 True/False def is_even(n): return n % 2 == 0 # Codex 修改后:返回 0/1,类型变了 def is_even(n): return n % 2 ``` 调用方原本这样用: ```python if is_even(4) is True: print("偶数") ``` 修改后 `is_even(4)` 返回的是 `1`,而 `1 is True` 在 Python 中为 `False`,于是这段代码静默地不再打印任何内容——**不报错,但行为错了**。这类问题比 `SyntaxError` 更难发现,因为它不会打断运行。 **如何用单元测试发现并修复** 1. **先写断言再改代码**:在让 Codex 动手前,先为原函数写好测试,锁定返回值类型与行为: ```python def test_is_even(): assert is_even(4) is True # 类型与值都要校验 assert is_even(3) is False assert is_even(0) is True ``` 2. **改完立刻跑测试**:Codex 修改后运行 `pytest`,`test_is_even` 会因 `is_even(4) is True` 失败而亮红灯,问题立刻暴露。 3. **把失败信息回填给 Codex**:将测试报错连同“请保持返回类型为 `bool`,不要返回 `int`”一起发回,让它修正: ```text 测试 test_is_even 失败了:is_even(4) 返回 1 而不是 True。 请保持返回类型为 bool,不要改变对外接口。 ``` 4. **再次运行测试直到全绿**:确认 `is_even(4) is True` 通过,再继续下一步。 这正是“给出验收标准”的价值——**单元测试就是最硬的验收标准**,它能把“悄悄改坏接口”这类逻辑错误,从“上线后才发现”提前到“改完立刻发现”。 ## 四、让结果更稳定的三个技巧 1. **给出验收标准**:告诉它“改完应通过现有测试”“不要改变对外接口”。 2. **限定范围**:明确“只改这一个文件”“不要动其他函数”。 3. **小步推进**:一次只让它做一件事,比一次塞一堆需求成功率更高。 ## 小结 - 分析:明确“分析什么”,提供完整上下文。 - 生成:单元测试、类型定义是 Codex 的高价值场景。 - 修改:在 auto-edit 下可直接改文件,记得给验收标准。 - 三个稳定技巧:**验收标准、限定范围、小步推进**。 下一课,我们掌握会话控制的斜杠命令,让多轮协作不再混乱。 > 本文是《OpenAI Codex 从零基础到精通》第 6 课。