SpringBoot在线考试系统开发实战与架构设计
1. 项目概述
这个基于SpringBoot和JavaWeb技术的在线考试系统,是我去年为一个地方教育机构开发的实战项目。系统从需求分析到最终上线历时3个月,目前已经稳定运行了8个月,累计服务了3000+考生。相比传统考试方式,系统将阅卷效率提升了15倍,错误率降低了90%。
2. 系统架构设计
2.1 技术选型考量
后端采用SpringBoot 2.7.3 + MyBatis Plus组合,这个选择经过了仔细权衡:
- SpringBoot的自动配置特性让项目搭建时间缩短了60%
- MyBatis Plus的代码生成器使DAO层开发效率提升3倍
- 放弃了JPA是考虑到团队更熟悉MyBatis语法
前端使用Thymeleaf + Bootstrap 5:
- 模板引擎选择Thymeleaf而非Freemarker,因其更好的HTML5支持
- Bootstrap 5的响应式布局完美适配移动端考试需求
2.2 核心模块划分
系统采用经典的三层架构:
- 表现层:处理HTTP请求和视图渲染
- 业务层:核心考试逻辑实现
- 数据层:MySQL 8.0持久化存储
特别设计了防作弊模块:
- 题目乱序算法(Fisher-Yates洗牌)
- 页面焦点检测(JavaScript)
- 切屏次数统计
3. 数据库设计
3.1 关键表结构
用户表采用RBAC模型:
CREATE TABLE `sys_user` ( `user_id` bigint NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL COMMENT '登录账号', `password` varchar(100) NOT NULL COMMENT '密码', `salt` varchar(20) DEFAULT NULL COMMENT '盐值', `real_name` varchar(50) DEFAULT NULL COMMENT '真实姓名', `avatar` varchar(255) DEFAULT NULL COMMENT '头像', `status` tinyint DEFAULT '1' COMMENT '状态(0锁定 1正常)', PRIMARY KEY (`user_id`), UNIQUE KEY `username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;试卷表设计考虑了并发控制:
CREATE TABLE `exam_paper` ( `paper_id` bigint NOT NULL AUTO_INCREMENT, `paper_name` varchar(255) NOT NULL, `subject_id` int NOT NULL, `total_score` int NOT NULL DEFAULT '100', `duration` int NOT NULL COMMENT '考试时长(分钟)', `start_time` datetime DEFAULT NULL, `end_time` datetime DEFAULT NULL, `version` int NOT NULL DEFAULT '1' COMMENT '乐观锁版本号', PRIMARY KEY (`paper_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;3.2 性能优化措施
- 为高频查询字段添加组合索引:
ALTER TABLE `exam_question` ADD INDEX `idx_subject_type` (`subject_id`, `question_type`);大文本字段单独分表存储
使用Redis缓存热点数据:
@Cacheable(value = "paperCache", key = "#paperId") public ExamPaper getPaperById(Long paperId) { return paperMapper.selectById(paperId); }4. 核心功能实现
4.1 考试过程控制
采用状态机模式管理考试流程:
public enum ExamStatus { NOT_STARTED, IN_PROGRESS, SUBMITTED, TIMEOUT, CHEATING } // 状态转换检查 public void changeStatus(Long examId, ExamStatus newStatus) { ExamStatus currentStatus = getCurrentStatus(examId); if (!transitionRules.get(currentStatus).contains(newStatus)) { throw new IllegalStateException("无效状态转换"); } // 更新状态... }4.2 自动阅卷算法
选择题采用精确匹配:
public boolean checkChoiceAnswer(Question q, String userAnswer) { return q.getCorrectAnswer().equalsIgnoreCase(userAnswer); }主观题使用相似度算法:
public float checkEssayScore(String standardAnswer, String userAnswer) { // 使用余弦相似度计算文本相似度 return CosineSimilarity.calculate(standardAnswer, userAnswer); }4.3 高并发处理
考试提交高峰期使用消息队列削峰:
@RabbitListener(queues = "exam.submit.queue") public void processSubmit(ExamSubmit submit) { // 异步处理答卷提交 gradingService.gradePaper(submit); }5. 安全防护方案
5.1 防SQL注入
使用预编译语句:
@Select("SELECT * FROM exam_question WHERE question_id = #{id}") Question getById(@Param("id") Long id);5.2 XSS防护
全局过滤器处理参数:
public class XssFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { HttpServletRequest req = (HttpServletRequest) request; XssHttpServletRequestWrapper wrappedRequest = new XssHttpServletRequestWrapper(req); chain.doFilter(wrappedRequest, response); } }5.3 权限控制
基于注解的细粒度控制:
@PreAuthorize("hasRole('TEACHER') or hasPermission(#paperId, 'paper:review')") public void reviewPaper(Long paperId) { // 阅卷逻辑 }6. 部署实践
6.1 生产环境配置
采用Docker Compose部署:
version: '3' services: app: image: openjdk:11-jre ports: - "8080:8080" volumes: - ./app.jar:/app.jar command: java -jar /app.jar depends_on: - redis - mysql mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: exam@123 MYSQL_DATABASE: exam_db redis: image: redis:6.26.2 性能调优
JVM参数配置:
-server -Xms2g -Xmx2g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:ParallelGCThreads=47. 踩坑实录
- MyBatis批量插入优化:
// 错误做法:循环单条插入 for(Question q : questions) { mapper.insert(q); } // 正确做法:批量插入 mapper.insertBatch(questions);- 事务超时问题解决:
@Transactional(timeout = 30) // 设置合适的事务超时 public void importQuestions(List<Question> questions) { // 批量处理 }- 日期比较陷阱:
// 错误:直接比较LocalDateTime if (startTime.equals(endTime)) {...} // 正确:使用时间差比较 if (Duration.between(startTime, endTime).toMinutes() == 0) {...}8. 扩展建议
- 可增加AI监考功能:
- 使用OpenCV实现面部识别
- 行为异常检测算法
- 试卷智能组卷:
- 基于知识图谱的题目推荐
- 难度系数自动平衡算法
- 移动端适配:
- 开发微信小程序版本
- 使用Flutter跨平台方案
项目源码中包含了完整的单元测试(覆盖率85%+)和API文档(Swagger UI),建议二次开发前先阅读test目录下的测试用例。
