聊《Codex 实战:把学习路线变成作品集》之前,先说一句实在的:别急着背概念,先看它在真实项目里到底解决什么问题。
摘要
本文概述文章目标、核心观点和实践价值。
很多刚转行或者想在大模型时代突围的开发者,最大的痛点不是“不会写代码”,而是“不知道怎么写能进面试”。我见过太多简历上写着“熟悉 LLM API 调用”,但项目经历却只是简单的 Hello World 或者没有业务逻辑的玩具 Demo。HR 和技术面试官一眼就能看出这种项目的单薄。
真正的竞争力,在于你能不能把一个看似普通的业务模块,用 AI 辅助重构得既优雅又稳健。
这次我不讲复杂的 Agent 架构,也不扯那些虚头巴脑的概念。我就拿手头的 Java 后端项目为例,演示如何用 OpenAI Codex(及其背后的代码生成能力)把一个老旧的 CRUD 接口,改造为带有单元测试、异常处理和清晰文档的高质量服务。这不仅是提效,更是你简历上最硬核的“作品集”素材。
目录
- Codex 的定位:是副驾驶,不是自动司机
- 项目上下文理解:拒绝黑盒输入
- 代码修改流程:迭代优于一次性生成
- 测试与验证:被忽视的加分项
- 团队使用建议:规范先行
- 总结:把过程写进简历
Codex 的定位:是副驾驶,不是自动司机

首先要纠正一个误区:Codex 不是用来替代你思考业务逻辑的。它是一个极佳的“样板码生成器”和“逻辑校验者”。
在我的实际工作中,我把 Codex 当作两个角色:
1. 资深初级工程师:当你懒得写繁琐的 DTO 转换、日志打印或单元测试骨架时,让它干。
2. 代码审查员:当你写完核心逻辑,扔给它说“找出潜在的空指针风险”,它往往能指出你没注意到的边缘情况。
如果你指望它直接生成一套完整的、无需修改的生产级微服务,那你大概率会失望。但如果你把它嵌入到你的开发流中,它的价值是指数级增长的。
项目上下文理解:拒绝黑盒输入

很多新手用 AI 编程失败的原因,是一次性把整个文件丢进去让 AI “重写”。这是大忌。AI 缺乏上下文感知,尤其是缺失了你项目特有的配置、依赖和业务规则。
我们需要先建立“上下文”。以一个用户权限校验模块为例,我们有一个现有的 UserService 和一个自定义注解 @RequireRole。
在开始编码前,我先整理了以下信息片段,作为 Prompt 的前置背景:
# 项目背景
- 框架: Spring Boot 2.7 + MyBatis Plus
- 权限方案: 基于 RBAC,自定义注解 @RequireRole(role="ADMIN")
- 现有问题: Controller 层充斥着大量的 if-else 判断,且缺少统一的异常处理,导致错误信息泄露给前端。
# 目标
- 使用 AOP 拦截 @RequireRole 注解
- 统一返回标准 JSON 格式
- 编写 JUnit 5 单元测试覆盖正常和非法访问场景
看,这就是“作品集”的起点。你没有在简历上写“我用了 AOP”,你写的是“通过 AOP 重构权限校验,消除 80% 的重复代码,并建立标准化异常响应机制”。区别巨大。

代码修改流程:迭代优于一次性生成
有了上下文,我们分步进行。不要试图一步到位。
第一步:生成切面基础结构
我向 Codex 发送指令:
> “请基于 Spring AOP 实现一个 @RequireRole 的切面。从 SecurityContext 获取当前用户角色,如果用户角色不在允许列表中,抛出自定义的 AccessDeniedException。请提供完整的 Java 类代码。”
Codex 很快给出了如下代码:
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class RoleAuthorizationAspect {
@Around("@annotation(requireRole)")
public Object checkRole(ProceedingJoinPoint joinPoint, RequireRole requireRole) throws Throwable {
// 1. 获取当前登录用户
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
// 这里假设 principal 是一个 UserDetails 对象
if (!(principal instanceof UserDetails)) {
throw new AccessDeniedException("未认证用户");
}
UserDetails userDetails = (UserDetails) principal;
// 2. 检查角色
boolean hasRole = userDetails.getAuthorities().stream()
.anyMatch(a -> a.getAuthority().equals(requireRole.role()));
if (!hasRole) {
throw new AccessDeniedException("无权限访问,需要角色: " + requireRole.role());
}
// 3. 执行目标方法
return joinPoint.proceed();
}
}
第二步:注入业务逻辑与优化
这段代码看起来不错,但有两个问题:
1. 它没有处理 SecurityContextHolder 可能为空的情况(比如匿名访问)。
2. 它没有集成到我们要的统一异常处理器中。
我再次交互:
> “上面的代码在匿名访问时会 NPE。请添加空值检查。另外,请将抛出的异常转换为全局异常处理器的风格,假设我有一个 GlobalExceptionHandler 捕获 AccessDeniedException 并返回 403。”
Codex 会根据你的反馈修正逻辑。这种“对话式”的开发过程,本身就是你技术深度的体现。你在简历中可以描述:“通过与 AI 辅助迭代,优化了空指针防御机制,提升了代码鲁棒性。”
测试与验证:被忽视的加分项
大多数人的 AI 辅助止步于业务代码。但作为技术人员,可测试的代码才是可信的代码。
这是区分“调包侠”和“工程师”的关键。我让 Codex 基于刚才的 Aspect 编写单元测试。
> “请为 RoleAuthorizationAspect 编写 JUnit 5 单元测试。使用 Mockito 模拟 SecurityContextHolder 和 ProceedingJoinPoint。测试用例包括:1. 拥有正确角色的用户通过;2. 没有角色的用户被拒绝;3. 未登录用户被拒绝。”
生成的测试代码如下:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.aspectj.lang.ProceedingJoinPoint;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class RoleAuthorizationAspectTest {
@InjectMocks
private RoleAuthorizationAspect aspect;
@Mock
private ProceedingJoinPoint joinPoint;
@Mock
private RequireRole requireRole;
@Test
void shouldAllowAccessWhenRoleMatches() throws Throwable {
when(requireRole.role()).thenReturn("ADMIN");
when(joinPoint.proceed()).thenReturn("success");
// 设置 Mock 的安全上下文...
SecurityContextHolder.getContext().setAuthentication(mock(Authentication.class));
Object result = aspect.checkRole(joinPoint, requireRole);
assertEquals("success", result);
verify(joinPoint).proceed();
}
@Test
void shouldDenyAccessWhenRoleMismatch() throws Throwable {
when(requireRole.role()).thenReturn("ADMIN");
// 设置无 ADMIN 权限的上下文...
assertThrows(AccessDeniedException.class, () -> aspect.checkRole(joinPoint, requireRole));
verify(joinPoint, never()).proceed();
}
}
注意,这里的 SecurityContextHolder 模拟可能需要更细致的配置,AI 可能会给出不准确的 Mockito 设置。这时候你需要介入,手动调整 Mock 的细节。这种“审查 AI 生成的测试”的能力,比直接复制粘贴更有价值。
团队使用建议:规范先行
在你的项目中引入 AI 编程,必须配合团队规范,否则会产生代码垃圾山。
1. Code Review 不变:AI 生成的代码必须经过人工 Review。重点关注安全漏洞、性能瓶颈和业务逻辑一致性。
2. Prompt 模板化:团队内部沉淀一套高质量的 Prompt 模板。例如,“生成 RESTful Controller 的标准 Prompt”、“生成 DAO 层的标准 Prompt”。这能保证风格统一。
3. 版本控制意识:不要在主分支直接应用 AI 生成的代码。始终使用 Feature Branch,并通过 Diff 查看变更。
总结:把过程写进简历
回到初衷,为什么我们要做这个实战?
因为当面试官问你:“你在项目中如何应用新技术?”
普通回答:“我用了 AI 工具来写代码。”(太泛,无说服力)
优秀回答:“我在重构权限模块时,利用 Codex 快速生成了 AOP 切面和对应的单元测试骨架。在这个过程中,我发现 AI 在处理复杂安全上下文模拟时有局限,因此我手动补充了边界条件的 Mock 逻辑,并通过两轮迭代优化了异常处理机制。最终将代码覆盖率从 40% 提升到 90%,并将重复代码减少了 60%。”
前者是工具的奴隶,后者是工具的主人。
Codex 只是一个杠杆,你能撬动多大的价值,取决于你对代码质量、测试覆盖和业务逻辑的理解深度。把你的学习路线变成一个个可展示、可量化、有思考深度的小项目,这才是你在 AI 时代最好的作品集。
资料展示
下面是我整理的AI大模型学习资料和工具包预览,适合收藏后按主题逐步学习。



如果你想看完整资料目录,可以在评论区留言「资料」;也欢迎告诉我你更关注AI大模型里的哪类内容。


1479

被折叠的 条评论
为什么被折叠?



