引言
在软件工程领域,人工智能正成为缔造应用的强大工具。本文记录了一次借助 AI 编程插件,从自然语言指令开始,历经需求分析、接口设计、数据库建模、全量代码生成,最终成功部署在线考试系统的实践过程。旨在揭示 AI 辅助编程在真实项目中的潜力与最佳实践。
利用 AI 工具快速构建在线考试系统,通过自然语言指令完成需求分析、接口设计、数据库建模及代码生成。系统包含用户权限、题库管理、试卷管理及自动阅卷功能,采用 Spring Boot 和 MyBatis-Plus 技术栈。实践显示 AI 能提升编码效率与规范性,使开发者聚焦核心业务。

在软件工程领域,人工智能正成为缔造应用的强大工具。本文记录了一次借助 AI 编程插件,从自然语言指令开始,历经需求分析、接口设计、数据库建模、全量代码生成,最终成功部署在线考试系统的实践过程。旨在揭示 AI 辅助编程在真实项目中的潜力与最佳实践。
在开始之前,请确保您的开发环境满足以下基本条件:
安装过程极为便捷,全程图形化操作,无需复杂的命令行配置。
File -> Settings 或使用快捷键 Ctrl+Alt+S 打开设置面板。在左侧导航栏中选择 Plugins。Install 按钮。Apply 按钮使插件配置生效,随后点击 OK 关闭面板。此时,无需重启 IDE,插件已准备就绪。传统软件开发的起点是厚重的需求文档和反复的需求澄清会议。而现在,我们只需要一句清晰的指令。
在项目的 src/main/java 目录下,右键调出菜单,选择 AI 编程的相关功能,启动交互窗口。输入本次项目的核心指令:
帮我进行在线考试系统的设计与实现 这句指令,将作为驱动整个系统自动设计的'第一推动力'。 AI 的分析结果,精准地覆盖了一个标准在线考试系统的核心域:
遵循现代软件工程的'面向接口编程'原则,AI 在确认了功能模块后,开始为系统设计 Service 层的 API 接口。这些接口是系统业务能力的契约,定义了模块间的交互边界。 AI 为我们生成了多个职责分明的业务接口,例如:
IUserService: 定义用户注册、登录、信息查询、角色分配等操作。IQuestionService: 封装题库中所有与试题相关的原子操作。IPaperService: 定义试卷的创建、题目管理、预览等功能。IExamService: 核心业务接口,负责考试的发布、状态管理、学生参加考试的流程控制。IExamRecordService: 用于处理学生考试记录的提交、成绩的存储与查询。数据是应用的基石。一个健壮的数据库模型是系统稳定性的保障。AI 基于前两步的分析,自动推导并设计出了一套完整的数据库表结构。 AI 设计的核心数据表包括:
sys_user: 用户表,存储用户的基本信息及角色。sys_role: 角色表。sys_user_role: 用户角色关联表。question: 题库表,包含题干、选项、答案、题型、难度等字段。paper: 试卷信息表。paper_question: 试卷 - 题目关联表,用于解决多对多关系。exam: 考试场次表,定义一场考试的名称、时间、时长等。exam_record: 学生考试记录总表,记录学生得分等信息。在完成所有高层设计之后,AI 进入了执行阶段。它将依据之前确定的接口定义和数据模型,自动编写所有必要的 Java 代码。 用户只需点击'下一步',AI 便开始进行处理逻辑分析,并将分析结果转化为代码。随后的代码生成过程是全自动的。AI 会基于标准的 Spring Boot 项目结构,一次性生成包括 Controller, Service, ServiceImpl, Mapper, Entity, DTO 在内的所有分层代码,并自动处理好依赖注入关系。 整个过程耗时仅数分钟。当 AI 提示'生成完毕',一个结构完整、代码规范的后端工程便已静静地躺在我们的项目目录中。
代码质量是检验 AI 能力的最终试金石。让我们深入项目内部,对 AI 生成的代码进行一次全面的 Review。
AI 生成的项目是典型的企业级 Spring Boot 应用结构,分层清晰,一目了然:
com.example.onlineexam
├── common // 公共组件,如统一结果返回类、异常处理
├── controller // 控制器层 (API Endpoints)
├── service // 业务逻辑层
│ └── impl
├── mapper // 数据访问层 (MyBatis Mapper)
├── entity // 数据库实体
├── dto // 数据传输对象
└── OnlineExamApplication.java // Spring Boot 启动类
以 Question(题目)实体为例,代码质量非常高。
package com.example.onlineexam.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("question")
@ApiModel(value = "Question 对象", description = "题目信息表")
public class Question implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "题目 ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "题干")
private String content;
@ApiModelProperty(value = "题型:1-单选 2-多选 3-判断")
private Integer type;
@ApiModelProperty(value = "选项,使用 JSON 格式存储")
private String options;
@ApiModelProperty(value = "标准答案")
private String answer;
@ApiModelProperty(value = "题目解析")
private String analysis;
@ApiModelProperty(value = "难度等级:1-易 2-中 3-难")
private Integer difficulty;
@ApiModelProperty(value = "创建者 ID")
private Integer creatorId;
}
@Data 等注解,代码极其简洁。@TableName 和 @TableId 注解无缝对接 ORM 框架。@ApiModel 和 @ApiModelProperty 注解,这意味着项目天生就具备了生成 API 文档的能力,极大方便了前后端协作。AI 选用了业界流行的 MyBatis-Plus 作为数据访问框架。
package com.example.onlineexam.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.onlineexam.entity.Question;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface QuestionMapper extends BaseMapper<Question> {
/**
* 根据多个条件动态查询题目
* @param type 题型
* @param difficulty 难度
* @return 题目列表
*/
@Select("<script>" +
"SELECT * FROM question " +
"<where>" +
"<if test='type != null'> AND type = #{type} </if>" +
"<if test='difficulty != null'> AND difficulty = #{difficulty} </if>" +
"</where>" +
"</script>")
List<Question> findQuestionsByCriteria(@Param("type") Integer type, @Param("difficulty") Integer difficulty);
}
BaseMapper 后,无需手写任何 XML 或注解,即可获得强大的单表 CRUD 能力。Service 层是业务的核心,我们来看 ExamServiceImpl 中一个关键方法——submitExam(提交试卷)。
package com.example.onlineexam.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.onlineexam.common.BusinessException;
import com.example.onlineexam.dto.SubmissionDTO;
import com.example.onlineexam.entity.Exam;
import com.example.onlineexam.entity.ExamRecord;
import com.example.onlineexam.entity.Question;
import com.example.onlineexam.mapper.ExamMapper;
import com.example.onlineexam.mapper.QuestionMapper;
import com.example.onlineexam.service.IExamRecordService;
import com.example.onlineexam.service.IExamService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDateTime;
@Service
public class ExamServiceImpl extends ServiceImpl<ExamMapper, Exam> implements IExamService {
@Resource
private QuestionMapper questionMapper;
@Resource
private IExamRecordService examRecordService;
@Override
@Transactional(rollbackFor = Exception.class)
public double submitExam(SubmissionDTO submission) {
// 1. 业务校验:考试是否存在,是否在允许提交的时间内
Exam exam = this.getById(submission.getExamId());
if (exam == null || LocalDateTime.now().isAfter(exam.getEndTime())) {
throw new BusinessException(500, "考试不存在或已截止提交");
}
// 2. 核心逻辑:自动阅卷,计算得分
double totalScore = 0.0;
final double scorePerQuestion = 10.0; // 假设每题 10 分
for (SubmissionDTO.AnswerDetail answerDetail : submission.getAnswers()) {
Question question = questionMapper.selectById(answerDetail.getQuestionId());
if (question != null && question.getAnswer().equalsIgnoreCase(answerDetail.getStudentAnswer())) {
totalScore += scorePerQuestion;
}
}
// 3. 数据持久化:保存考试记录
ExamRecord record = new ExamRecord();
record.setStudentId(submission.getStudentId());
record.setExamId(submission.getExamId());
record.setScore(totalScore);
record.setSubmitTime(LocalDateTime.now());
examRecordService.save(record);
// ... 此处还可以扩展保存每道题的详细作答记录 ...
return totalScore;
}
}
@Resource 注解,遵循 JSR-250 规范,实现依赖注入。submitExam 方法被 @Transactional 注解标记。这意味着整个提交过程(计算分数、保存记录)是一个原子操作,要么全部成功,要么在出现任何异常时全部回滚,强力保障了数据一致性。BusinessException,这是企业级应用中进行统一异常处理的最佳实践。Controller 层作为 API 入口,代码同样规范。
package com.example.onlineexam.controller;
import com.example.onlineexam.common.Result;
import com.example.onlineexam.dto.SubmissionDTO;
import com.example.onlineexam.service.IExamService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@Api(tags = "考试管理接口")
@RestController
@RequestMapping("/api/exam")
public class ExamController {
@Resource
private IExamService examService;
@ApiOperation("学生提交试卷")
@PostMapping("/submit")
public Result<Double> submitExam(@RequestBody SubmissionDTO submission) {
double score = examService.submitExam(submission);
return Result.success(score);
}
}
Result 类对所有 API 的返回进行统一封装,包含了状态码、消息和数据,便于前端进行统一处理。@Api 和 @ApiOperation 注解使得该接口能被 Swagger 自动扫描并生成美观的 API 文档。一个后端项目,只有当它能被成功部署并为前端提供稳定服务时,才算真正完成了使命。我们将 AI 生成的代码打包并部署到服务器上,配合开发好的前端界面,一个完整的在线考试系统就此诞生。 以下是系统各核心模块的最终运行效果截图:
QuestionController 在提供服务。ExamController 中的相应 API 提供支持。本次基于 AI 插件的开发实践,是一次对未来软件开发模式的深刻预演。我们亲身体验了从一个简单的自然语言需求,到一套企业级的、可部署的、高质量的后端代码的极速生成过程。 核心收获:

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online