基于javaweb的毕业设计选题系统设计与实现

时间:2026-10-17 05:06:58 来源:力不从心网

去年帮系里整理毕业设计选题,基于发现一个挺尴尬的毕业事:全系327个题目,有41个是设计设计实现重复的,还有十几个题目只有标题没有描述。选题系统学生选题靠QQ群接龙,基于教务老师手动统计,毕业前后折腾了将近两周。设计设计实现这种事情放在2024年,选题系统实在说不过去。基于

这套基于JavaWeb的毕业选题系统,核心要解决的设计设计实现就是三个问题:题目去重、双向选择、选题系统流程可追溯。基于技术选型没什么花哨的毕业,SpringBoot + MyBatis + MySQL,设计设计实现前端用Thymeleaf配合Bootstrap。有人问为什么不用Vue前后端分离,我的判断是——毕业设计选题系统的用户量撑死几千人,并发峰值出现在选题开放那几分钟,单体架构完全扛得住,没必要为了技术而技术。

数据库设计决定了系统好不好用

整个系统最关键的几张表:topic(题目表)、selection(选题记录表)、user(用户表)。题目表里加了一个status字段,取值分别是待审核、已通过、已选、已满。选题记录表用联合唯一索引锁住(student_id, topic_id),从数据库层面防止一个学生选多个题目。

这里踩过一个坑。最初设计时把“教师出题”和“学生选题”放在同一张操作日志表里,结果查询时字段含义混乱,后来拆成了topic_audit_log和selection_log两张表。分开之后,不管是教师查看自己题目的审核进度,还是管理员追溯某个学生的选题操作,查询逻辑都清爽很多。

选题的并发问题比想象中严重

选题开放那一刻,几十个学生同时点“确认选择”同一个题目。如果不在代码层面做控制,就会出现一个题目被多个学生选中的情况。解决办法是在Service层用SELECT ... FOR UPDATE加行锁,配合数据库事务。具体代码不展开,思路就是:先锁题目行记录,判断status是否为“已通过”且未满员,再插入选题记录并更新题目状态。整个过程在一个事务里完成。

测试的时候用JMeter模拟了200个并发请求抢10个题目,加了行锁之后没有出现超选。不过锁的粒度要控制好,一开始锁了整个topic表,性能明显下降,改成按题目ID锁行之后就正常了。

教师端的功能设计要克制

很多选题系统给教师端堆了一堆功能——批量导入、模板下载、数据导出。实际调研下来,教师最常用的就两个操作:提交题目和查看选题结果。所以教师端首页只放了一个题目列表,支持按状态筛选,每个题目右侧有“编辑”和“查看学生”两个按钮。没了。

有个细节值得说:题目提交后进入待审核状态,管理员审核通过才会对学生可见。审核不通过时要求填写驳回原因,这个原因会直接展示给教师。之前没有这个反馈机制,教师提交完就石沉大海,体验很差。

部署比开发更让人头疼

开发环境用的SpringBoot内置Tomcat,部署到系里的服务器时遇到了JDK版本不兼容的问题——服务器上装的是JDK 8,而项目编译用了JDK 17。重新编译打包花了半天。后来在pom.xml里把maven.compiler.source和target都固定为1.8,这个问题才算根治。

数据库连接池用的Druid,配置了慢SQL监控。上线第一周就发现一条查询语句执行时间超过3秒——是管理员端的选题统计报表,查了全表没有加索引。在selection表的create_time字段上加了索引之后降到200毫秒以内。

目前这套系统已经在系里跑了一个学期,327个题目全部线上管理,选题阶段从原来的两周压缩到三天。当然问题还有,比如移动端适配做得粗糙,学生用手机选题目体验一般。下一步打算把前端换成响应式布局,但那是另一个故事了。

推荐内容