最近我干了一件事:拿手头的飞算 JavaAI,从一个相当“没有想象力”的需求开始——学生成绩管理系统。这个项目在 Java 课程设计里几乎快被写烂了,在 Java 面试八股里也常年出镜,我偏偏想看看,如果连这种需求边界极度清晰的老项目都能被 AI 辅助开发流程跑通,那这套工具的性价比其实就很好估算了。实测下来,30 分钟确实能搞定一个能登录、能录成绩、能统计排名、能拿去答辩演示的系统,但前提是你得先想清楚怎么把需求喂给 AI,以及哪些代码生成之后必须人工兜底。这篇文章就把我整个踩坑和落地的过程拆开讲。
如果你正好在准备 Java 相关的课设或面试项目,或者手里有了一个 AI 编程工具却不知道怎么用出价值,这篇经验可以省下你不少摸索时间。我讲的不只是“给 AI 发一句话然后等结果”,而是从需求拆解、表结构设计、代码生成、接口验收到排错修复的完整链路。
1. 为什么我选“学生成绩管理系统”这种老掉牙项目来测飞算 JavaAI
1.1 一个 CRUD 系统把 Java 后端完整链路都串起来了
很多人觉得学生成绩管理系统太简单,无非是增删改查。可如果你认真拆,它其实覆盖了一个 Java 后端项目里几乎全部的基础组件:用户登录认证、拦截器、实体建模、多表关联、一对多成绩记录、分组聚合统计、按分数排序、分页查询、事务处理、全局异常捕获。这些东西单独看都能找到教程,但要在同一个项目里自然组合出来,并且跑得通、说得清,恰恰是多数初学者和准备面试的人跨不过去的坎。
所以我用“飞算 JavaAI”时,给它定下的第一个目标并不是生成一个花哨的首页,而是让它老老实实把上面这套后端链路完整搭出来。我核心关心的是:它生成的代码是“能跑”还是“能扛”?增删改查看起来简单,可一旦涉及重复学号约束、成绩唯一性、删除策略、统计精度这些细节,AI 是否有能力一次到位?这些疑问不实测,心里永远没底。
1.2 “30分钟”不是噱头,而是一种筛选标准
我以前手工搭过类似系统,连环境配置加前后端调试,怎么也要一整个下午。如果只把 AI 看作自动补全工具,那提升有限;但如果把它看作“能按描述批量产出模块的结对程序员”,那时间账就完全不一样了。
我给这次实战设了一个硬性时间上限:30 分钟。这 30 分钟里包含需求确认、数据库生成、后端代码生成、简单页面联调和演示,不包括我临时去背 Java 语法、去查 Spring Boot 注解怎么写的成本。这个标准比较现实,因为真正限制 AI 项目落地速度的往往不是打字速度,而是你对需求的拆解速度,以及你遇到报错之后的排查速度。这两个能力,AI 不能替你完成,但它能放大你的效率。
1.3 先划清楚 AI 能做什么、不能做什么
实测前我先给自己划了条边界。飞算 JavaAI 这类工具擅长的是在给定技术栈和需求描述后,批量生成稳定、重复、模块化的 Java 代码,比如 Mapper 接口、Service 实现、Controller 路由、基础页面模板。这部分极其省力。
但它不擅长替你拍板,比如“学生被删除后,历史成绩应该怎么处理”“登录用 Session 还是 JWT”“成绩是否允许小数”。如果需求文档里没写清楚,它就会自己按默认习惯猜,猜错以后你反而要花更多时间去返工。所以所谓的“AI 生成”,真正前置工作是“人把需求压缩成 AI 不用猜的规格说明书”。这也是全篇最核心的方法论。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 动手前 5 分钟,把需求“压实”到 AI 输入框之前
2.1 拆需求先拆角色,别急着拆页面
很多人拿到“学生成绩管理系统”后,第一反应是打开画图工具开始画页面,这就反了。页面是给角色用的,角色没定,页面和接口都会失控。
我这次把角色收敛成两类:
- 管理员:负责学生信息、课程信息、成绩的维护,能查看所有统计结果。
- 学生:登录后只能查看自己的成绩、平均分和课程排名,不能修改任何业务数据。
请注意,我没有加“教师”角色。教师角色会牵扯到“教师管哪些班级、哪些课程”之类的权限模型,对这个 30 分钟项目来说是明显的范围蔓延。真正跑完需求你会发现,学生能看自己的成绩,管理员能维护一切,已经完全能满足演示和答辩需要。系统做得大不是本事,界定清楚不做什么才是本事。
有了角色列表之后,功能清单就顺理成章了:
- 登录与退出,不同角色登录后展示不同菜单。
- 学生信息管理:新增、编辑、删除、按学号/姓名/班级筛选。删除采用逻辑删除。
- 课程信息管理:新增、编辑、删除。
- 成绩管理:录入、修改、删除。同一学生同一课程只能有一条成绩。
- 成绩统计:按课程查看平均分、及格率、分数排名;学生个人查看自己的各科成绩汇总。
2.2 我发给 AI 的“项目开工提示词”长什么样
这一步是整个 30 分钟里最值得投入的 5 分钟。我给 AI 的初始提示词不是一句话,而是一份精简版需求规格书,我会包含背景、技术栈、实体关系、功能边界和数据库要求。下面是我实际使用过的模板,你可以直接复制修改:
text复制请用 Java + Spring Boot + MyBatis-Plus + MySQL + Thymeleaf + Bootstrap 5
帮我生成一个学生成绩管理系统。
用户角色只分两种:管理员和学生。
实体包括学生、课程、成绩。关系:
- 学生表存储学号、姓名、班级、性别、是否逻辑删除;
- 课程表存储课程编号、课程名称、学分;
- 成绩表存储学生ID、课程ID、成绩分数,并且同一学生同一课程最多只能有一条成绩。
功能要求:
1. 管理员登录后可以维护学生、课程和成绩;
2. 学生登录后只能查看自己的成绩列表、个人平均分和单科排名;
3. 所有请求必须做登录校验,未登录跳转登录页;
4. 统计功能需要输出总分、平均分、按分数降序排名;
5. 成绩分数允许 0 到 100 的两位小数;
6. 学生采用逻辑删除,删除后保留历史成绩;
7. 数据库使用 MySQL 8,字符集 utf8mb4;
8. 请先生成完整建表 SQL,再生成全项目代码,代码分层为 controller/service/mapper/entity。
注意提醒 AI 不要自由发挥。如果你不写“不要加教师角色”这个约束,它很可能会为了“系统完整”给你生成角色管理、权限管理、班级管理、学期管理,最后出来的项目远远超出需求,跑起来反而一团乱。
2.3 把模糊业务规则变成可校验的约束
需求描述里最忌讳的词就是“可以”“支持”“管理”这类空泛表述。什么叫“支持成绩管理”?是支持录入、修改还是删除?删除是物理删还是逻辑删?同一门课考两次怎么办?平均分保留几位?
我在开工前把这些坑都做成了可校验规则。比如成绩表的唯一约束是 (student_id, course_id),这条约束写在 SQL 里,比写在业务代码里可靠得多;学生删除我最终采用 is_deleted 标记,这样历史成绩不会被物理连带删除。之所以要提前定义,是因为 AI 在生成 Mapper 和 Service 时,会直接按照约束来设计过滤条件和唯一校验逻辑。需求清楚,生成结果大概率的清楚;需求含糊,后面就会陷入“反复重新生成”的循环。
3. 数据库表:AI 生成的背后,必须人工逐条复查
3.1 推荐的核心表结构,以及为什么这样设计
飞算 JavaAI 会自动生成建表语句,但表结构是系统的地基,这一层我不会盲目信任 AI 的第一版输出。我最终采用的表结构大致长这样,你也可以作为参考:
sql复制CREATE TABLE student (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
student_no VARCHAR(32) NOT NULL UNIQUE,
name VARCHAR(64) NOT NULL,
class_name VARCHAR(64),
gender TINYINT DEFAULT 0 COMMENT '0未知 1男 2女',
phone VARCHAR(20),
status TINYINT DEFAULT 1,
is_deleted TINYINT DEFAULT 0,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_student_no (student_no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学生表';
sql复制CREATE TABLE course (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
course_no VARCHAR(32) NOT NULL UNIQUE,
course_name VARCHAR(128) NOT NULL,
credit DECIMAL(3,1) DEFAULT 0,
teacher_name VARCHAR(32),
create_time DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='课程表';
sql复制CREATE TABLE score (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
student_id BIGINT NOT NULL,
course_id BIGINT NOT NULL,
score DECIMAL(5,2) NOT NULL,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_student_course (student_id, course_id),
KEY idx_course_id (course_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='成绩表';
这里我故意没有让 AI 给成绩表添加物理外键约束。很多人做课设时喜欢给 student_id 和 course_id 加上 FOREIGN KEY,结果测试时一删学生就报外键冲突,最后只能把代码改成先删成绩再删学生,反而破坏业务。实际项目里也几乎不用物理外键,我们靠索引和应用层服务来维护数据一致性,这在面试时反而能讲出道理。
3.2 AI 建表最容易踩的三个雷
第一版 AI 生成的成绩表,我检查后发现没有加 UNIQUE KEY uk_student_course。这意味着同一学生同一课程可以被插入多条记录,学生在页面上看到自己同一门课出现好几个成绩,排在后面的还可能是重复录入的错误分数。这个问题如果不在数据库层拦住,光靠 Service 代码去查一遍再判断,不仅慢,还很容易被并发请求绕过。
第二个问题是对删除策略理解不一致。AI 默认生成的“删除学生”大多数是 DELETE FROM student WHERE id = ?,也就是物理删除。如果学生已经考过试,物理删除后成绩表里剩下一条悬空记录,统计平均分时根本查不到这个学生是谁。所以我在表里增加了 is_deleted 字段,并要求所有查询默认带上 is_deleted = 0 过滤。
第三个问题是精度和字段类型。AI 生成成绩字段时,有时会给 INT,那就无法录入 89.5 这样的成绩;有时会给 FLOAT,而浮点数在涉及大量成绩汇总求和时容易出现精度漂移。最终我改成 DECIMAL(5,2),计算平均分时精度可控。
3.3 用一条统计 SQL 验证成绩统计的真实坑
AI 生成统计功能时,输出结果不一定错,但可能存在隐藏的坑。比如计算某个课程的平均分和及格率,正确写法通常是这样:
sql复制SELECT
c.course_name,
COUNT(s.id) AS total_student,
AVG(s.score) AS avg_score,
SUM(CASE WHEN s.score >= 60 THEN 1 ELSE 0 END) / COUNT(s.id) * 100 AS pass_rate
FROM course c
LEFT JOIN score s ON c.id = s.course_id
GROUP BY c.id, c.course_name;
这里有个容易忽视的细节:统计时如果把 COUNT(*) 换成 COUNT(s.score),在遇到某学生该课程还没有成绩的情况时结果会不同。用 LEFT JOIN 是为了让没有成绩的课程也能出现在统计列表里,但统计分母要不要算上无成绩学生,其实要看业务定义。AI 生成时不会自己判断“无成绩学生是否应该计入及格率分母”,如果没有提前约定,这个输出就可能是错的。
3.4 成绩排名:从“手写冒泡”到正确的排序方式
话题稍微偏一下。因为“冒泡排序 Java”一直是高热搜索词,所以每次有学生做到成绩排名,都会问我能不能用冒泡排序去实现名次功能。我的回答是:你在数据结构课上练冒泡没问题,但工程上千万不要拿冒泡去排一个班级甚至全年级的成绩。真正该做的是把排序交给数据库,或者在内存里用 Comparator 和 Stream 做多级排序。
如果按单科显示名次,用窗口函数最省事:
sql复制SELECT
t.student_no,
t.student_name,
t.score,
RANK() OVER (PARTITION BY t.course_id ORDER BY t.score DESC) AS rk
FROM score t
WHERE t.course_id = ?
ORDER BY rk ASC;
用 RANK() 的好处是成绩相同的学生会并列同一位次,比如两个人都考了 95 分,那就都是第 1 名,下一个是第 3 名。如果业务希望 95、95 之后第三个直接排第 2,就要换成 DENSE_RANK()。这两个选择 AI 不会替你决定,你必须在需求里写明白。
4. 按 30 分钟时间轴复盘,每一步到底在赶什么
4.1 时间切分表:每一段都为下一步留出余量
我做完整个流程后,可以把时间线大概画成这样:
| 时间段 | 主要动作 | 产出物 |
|---|---|---|
| 0-3 分钟 | 整理需求清单,落实角色边界和业务约束 | 给 AI 的初始提示词 |
| 3-6 分钟 | 让 AI 生成建表 SQL,人工复查唯一约束和删除策略 | 数据库脚本 |
| 6-12 分钟 | 让 AI 生成项目骨架、实体、Mapper 和 Service 基础层 | 可编译的后端基础项目 |
| 12-18 分钟 | 生成登录认证、拦截器和学生/课程管理模块 | 登录后可跳转的核心页面 |
| 18-25 分钟 | 生成成绩管理和统计查询,处理页面字段联调 | 完整可操作的成绩流程 |
| 25-30 分钟 | 按验收清单跑全流程冒烟测试,修掉明显问题 | 可演示版本 |
这个时间表并不是绝对的,但它强调了一个原则:每一大步完成之后,我会跑一次或编译一次,而不是等全部代码生成完再一起处理。把错误隔离开,是 AI 辅助开发里最节省时间的习惯。如果你让 AI 一次性输出全项目,再自己通读几百个文件去定位问题,那就不是在利用 AI,而是在给自己制造大型代码审查现场。
4.2 启动阶段最容易卡住的往往不是代码,是环境
如果你平时就在本机跑 Java 项目,“Java 安装”这种问题可能早被忽略了。但 AI 生成的代码通常会默认使用较新的 Spring Boot 版本,如果本地依然是 JDK 8,就可能出现编译失败。我自己这次就遇到过:AI 默认生成了 Spring Boot 3.x 的依赖,而 Spring Boot 3.x 强制要求 JDK 17。本地没有 JDK 17 的话,项目一启动就会在依赖解析阶段直接报错。
如果你也是 JDK 8 环境,最稳妥的做法是在初始提示词里就写清楚“使用 Spring Boot 2.7 + JDK 8”。别小看这一句,它能让你少折腾半小时。还有一次我让 AI 生成的 Spring Boot 项目在 IDEA 里启动到一半抛出内存不足,报错信息里出现了 java: outofmemoryerror 这类关键字。这通常是本机项目多、IDEA 分配的堆内存不够导致,不是代码问题。处理方式是调大 IDEA 的 -Xmx 参数,或者给 Spring Boot 应用设置合理的 JVM 启动参数。
4.3 生成前端页面时,把“效果描述”写进提示词
用飞算 JavaAI 做后端接口速度一般很快,真正影响演示效果的是前端。如果你只说“生成一个学生列表页面”,它给你的可能是很朴素的一大张表格,能看但不够体面。这次我在提示词里主动加了页面布局约束:
- 登录页用 Bootstrap 5 卡片居中,带学校名称和用户类型提示;
- 后台页面采用左侧菜单 + 顶部标题栏 + 主内容卡片布局;
- 成绩列表每个页面显示 10 条,表格要带斑马纹;
- 操作按钮统一使用不同颜色区分:新增蓝色、编辑黄色、删除红色。
加入这些描述之后,生成出来的页面可用度会明显上一个台阶。尤其是演示时,一个排版整齐、按钮色统一的界面给人的专业感,远超过一个功能全但乱糟糟的界面。
4.4 每轮生成结束后的“最小验证动作”
我给这个流程增加了一条强制纪律:“每次 AI 生成完一批文件,先启动应用,把刚生成的功能点手动点一遍,再进入下一个功能的生成。”一轮改动后如果启动失败,我不会继续叠加新代码,因为错误一旦堆叠,排查的复杂度会指数上升。先解决启动问题,再继续扩展功能,这是我在多次踩坑之后总结出的最实用步骤。
5. 核心接口生成之后,人工验收要比写代码更花心思
5.1 登录认证:不是所有项目都该一上来就上 JWT
AI 生成的登录方案,通常会先问你要 Session 还是 JWT。如果你不做约束,它可能默认生成 JWT,因为 JWT 一听更高级。但对学生成绩管理系统这个需求来说,我的建议是优先选择 HttpSession + 拦截器。原因有几点:项目本身是同源部署,不存在移动端和多服务共享会话的需求;实现拦截逻辑直观,代码量少,调试容易;答辩或面试时,你能把 Session 的会话维持机制讲得很清楚。
JWT 不是不能用,但一旦引入,你就得同时考虑 token 过期刷新、密钥管理、无状态登录失效等问题。这些不是不能学,而是对 30 分钟的项目来说,属于“自己给自己加戏”。等你想做前后端分离项目,或者想把微服务登录体系当亮点的时候,再单独用 JWT 重写登录也不迟。
5.2 CRUD 接口的冒烟测试:别以为页面能打开就万事大吉
代码生成后,我会按下面这份冒烟清单快速测试。你不用全部写自动化,人工在页面上点一遍就行:
- 新增一个学生,使用重复学号,系统必须报错而不是新增成功。
- 修改学生信息后,列表刷新出现修改后的内容。
- 给一个学生重复录入相同课程成绩,系统必须被数据库唯一约束拦住。
- 删除一个已有成绩的学生后,历史成绩列表不报错,且统计平均分时不再包含这个学生。
- 不登录直接访问
/score/list,会被拦截到登录页。 - 使用学生账号登录后,页面上不能出现“新增学生”“删除课程”这类管理按钮。
这份清单是我人工验收的基本盘。只要这几项全过,项目就能拿去演示了。更大的性能问题、权限漏洞,不是这个阶段要考虑的首要目标。
5.3 成绩统计与排序的功能,值得在 Service 层单独走查
成绩统计是最容易出现逻辑 Bug 的功能。我给 AI 的需求是:按课程统计平均分、及格率和参与人数。AI 生成的 Controller 代码里,偶尔会把统计 SQL 拼在 Controller 里,表面上功能能跑,但结构非常糟糕。如果我把所有 SQL 都堆在 Controller 里,后面维护人员想死的心都有。
于是我会专门要求 AI:“统计逻辑必须写在 Service 层,Controller 只负责接收参数和返回结果,统计函数单独抽取。”这个约束直接决定了项目质量。另外,删除接口和录入接口要记得加事务。比如“录入成绩”时如果同时要更新课程平均分冗余字段,就需要 @Transactional。不过我在上面的表结构里已经把平均分设计成查询时计算,并不冗余存储,所以事务的边界相对简单,只在涉及多个写操作时补上。
5.4 我的项目验收清单长这样
| 检查维度 | 具体检查项 | 是否通过 |
|---|---|---|
| 数据库 | 唯一约束是否存在,逻辑删除字段是否正常过滤 | 是 |
| 后端分层 | Controller 是否保持轻薄,业务是否在 Service 层 | 是 |
| 登录安全 | 未登录访问内部接口是否被拦截 | 是 |
| 业务规则 | 重复学号、重复成绩是否被禁止 | 是 |
| 统计正确性 | 平均分保留两位小数,及格率分母符合定义 | 是 |
| 前端基本体验 | 页面布局可用,错误提示友好 | 是 |
这个清单同时可以作为面试时回答“你的项目质量如何保证”的素材,比空口说“我做了单元测试”有说服力得多。
6. AI 排错实录:四类高频报错是如何一步步被定位的
6.1 required a bean of type ...:Mapper 没被 Spring 管起来
这是我这次遇到次数最多的问题之一。启动项目时,Spring 容器直接报错:
text复制Field studentMapper in com.example.demo.service.impl.StudentServiceImpl
required a bean of type 'com.example.demo.mapper.StudentMapper' that could not be found.
大多数人的第一反应是去检查 StudentMapper 接口代码,看是不是接口里写错了。其实这个报错基本与接口内部方法无关,等于是 Spring 在启动时扫描了所有 Bean,却完全不知道存在这个 Mapper。我按这个顺序排查:
- 先看
StudentMapper接口上有没有加@Mapper注解,AI 有时会漏加。 - 再看启动类是否配置了
@MapperScan,如果没有,需要在启动类上指定 Mapper 接口所在包。 - 最后看 Mapper XML 文件里的
namespace是否和接口全限定名一致。
第三次测试时,AI 一次性生成了多个 Mapper,结果 @MapperScan 写到了其中一个 Mapper 接口上而不是启动类上,导致其他 Mapper 没被扫描到。这里要记住一个原则:把扫描注解放在启动类或独立配置类里,不要分散在各接口上。
6.2 SQL 字段名撞上了保留字,启动时可能完全不报错
成绩表或者课程表里,如果字段被命名为 desc、rank、order 这类词,用 MyBatis-Plus 的 QueryWrapper 时可能正常,但一旦使用原生 SQL,比如 ORDER BY desc,MySQL 就会觉得语法不对。这个坑最麻烦的地方在于代码编译期不报错,只有跑到那一行查询才会突然炸出来。
定位思路是先看报错栈里提到的 SQL 片段,锁定是哪个字段的问题,然后处理两种方案之一:给字段加反引号,比如 `desc`;或者更彻底一点,把字段重命名成 description、rank_no。我更推荐后者,因为它让你的 Java 实体字段、数据库字段和前端传参都不需要带着奇怪的符号到处跑。
6.3 日期时间字段返回格式不是前端想要的
页面刚能跑通时,我看到成绩列表里的 createTime 显示成了 2025-01-11T10:23:45,这个格式在后端和数据库里很正常,但放到页面上就很突兀。问题出在 Java 对象序列化成 JSON 时使用了默认的 ISO 格式。解决方法是在实体里对时间字段加注解统一格式化:
java复制@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime createTime;
你当然也可以配置全局 Jackson 格式化,但在这个小项目里,我倾向于让 AI 把实体类时间字段统一加上注解,简单直接。如果你是前后端分离架构,再考虑全局策略。
6.4 NullPointerException 出现得最随意,要顺着调用链查回登录态
学生登录后访问个人成绩时,AI 在 Service 里写了一句类似“从 Session 拿当前用户,再拿用户 ID 查询成绩”的代码。但当会话过期或者用户未登录时,loginUser 直接为 null,代码执行到 loginUser.getId() 就抛 NPE。
排查时不要只盯空指针报错的那一行,要往前看这个对象是从哪来的。如果是从 Session 取的,就需要确认之前是否做了登录拦截;如果是从参数传入的,就要确认前端是否遗漏了用户 ID 字段。我的做法是在拦截器层面统一判断登录态,没有登录就不允许进入 Service,这样 Service 内部就能默认“能进来的都是合法用户”。
把这条链路理解清楚很重要。很多人在面试时被问“空指针你一般怎么定位”,如果你能讲出“从堆栈第一行往下倒推,看对象来源,再全局统一收口”的思路,比背一堆空指针预防技巧更有实战感。
7. 项目收尾之后,这 30 分钟还能压榨出多少剩余价值
7.1 把成绩系统变成“Java 面试八股”的复习锚点
我做完这个项目之后的最大体会是:它本身就是一本行走的 Java 面试题集合。与其对着“Java 八股文”死记硬背,不如把这个项目里的每个点都当成面试题的引子。
比如,查询学生列表的时候,你可以聊聊 MySQL 索引为什么建在 student_no 上和唯一索引的底层结构;录入成绩时,可以聊聊为什么这里需要事务;运行时报找不到 Mapper Bean,可以聊聊 Spring 容器扫描机制。把这些真实发生的经历串起来,远比背书里的定义更容易让人记住。我记得在做成绩排名时还顺便复习了 Comparable 和 Comparator 的区别,因为业务里确实需要按分数降序、再按学号升序排列,这就是“多级排序”的实战场景。
7.2 避免让面试官一眼看穿项目是 AI 生成的
这里说句实在话,AI 写项目痕迹重不重,面试官一眼就能看出来。满屏没意义的注释、脱离业务的泛化命名、代码里到处是几个人看不懂的英文模板,这些都是典型特征。
我是这样处理的:拿到 AI 代码后,我会主动删掉它生成的无聊注释,只保留真正的业务逻辑说明;把统计排名的 SQL 单独抽出来,自己用命令行执行一遍确认输出;把登录拦截器的每一行都读一遍并加少量自己的改动。这样在面试时被问到“这个拦截器怎么实现的”,我能从头讲到尾,而不是支支吾吾说这是 AI 写的。另外,我不建议在项目里堆一堆自己完全没跑通的扩展点,一个能讲清逻辑的简单系统,比一个华丽但一问三不知的系统更打动面试官。
7.3 这套“需求压紧→AI生成→人工验收”流程可以复用到哪
这次跑通的不只是学生成绩管理系统,而是整个流程的模板。你完全可以把它迁到其他项目上,例如会议室预约系统、班级社团管理系统、小型仓储管理系统。流程不变:先花几分钟把角色和功能边界压紧,再让 AI 生成数据库脚本和代码,人工重点检查唯一约束、删除策略和统计逻辑,最后跑一遍核心业务冒烟测试。
我第一次意识到提前把“学生删除后不能丢失历史成绩”这条规则写进提示词时,数据库直接做成了 is_deleted 逻辑删除,后面所有查询都自动带上了过滤条件,这就是需求拆分带来的收益。后面做类似系统,我都会在需求表里提前问自己一句:这个业务动作到底是物理性删除,还是只让数据在普通列表里“消失”?想清楚这一句,能省掉 AI 生成的不少返工。
回归到飞算 JavaAI,30 分钟生成一个完整的学生成绩管理系统是完全可行的。但说句公道话,真正有价值的并不是最后那一堆代码,而是你为了跑通它而理顺的需求逻辑,以及你在排查那些报错过程中对 Spring 容器、MyBatis 机制和 SQL 行为的认知升级。这也是我现在向身边人推荐 AI 辅助开发时最爱强调的一点:不要把它当成终点,要把它当成一块能让你更快碰到真实问题的跳板,跳上去之后,真正决定高度的还是你自己对项目的理解。
