简介:一份面向高校计算机相关专业毕业设计使用的JSP高校智能排课系统完整源码与论文资料包。系统基于JavaServer Pages技术开发,涵盖用户管理、课程管理、教师管理、教室管理、排课算法与报表查询等模块,采用MVC模式组织代码,并通过合理的数据库设计存储教师、课程、教室、学生、课表等核心数据,排课算法可依据预设约束避免教师连堂、教室冲突。所附论文对JSP技术、系统架构、数据库设计、源码实现逻辑均有展开,开题报告与答辩要点也一并收录,便于直接参考或二次开发。压缩包大小约11.07MB,主要文件类型为JSP页面、Java类、配置文件及Word论文文档,目录结构清晰。已有351人学习下载,适合需要完成毕业设计、课程设计或希望深入理解JSP+Servlet+数据库综合开发的读者。
1. jsp 高校智能排课系统是什么:一个“源码+论文”齐活的经典毕设方向
抽到“jsp 高校智能排课系统”这个计算机专业本科毕设题目的同学,十有八九会下载到这样一个 zip:名字里带着“毕业设计”“IT计算机”“源代码+论文”的标签,解压后是一套能运行的 Java Web 老项目,外加一篇能改的 Word 论文。它不是黑科技,而是过去十几年毕业设计题库里的常青树:业务模型清楚、页面数量适中、排课算法能讲出深度,刚好够一篇本科论文的体量。它能解决你两件最实际的事:论文有东西可写、答辩有系统可演示。适合想快速交付毕设,或者想顺手把 JSP + Servlet 经典三层结构补一遍的同学。
2. 先拆骨架:排课五元组、数据库表与 JSP 三层代码的分工
2.1 排课的本质是约束满足:把硬约束和软约束分开看
高校排课,表面上是个“排课表”的功能,本质上是一个带约束的资源分配问题:把课程、班级、教师、教室四个对象,放进一周的某个时间片里,并保证四个对象在同一时间不冲突。绝大多数学校的作息是周一到周五、每天 12 节(上午 4 节、下午 4 节、晚上 4 节),也就是 5×12=60 个时间片。这 60 个时间片,乘以学校可用教室数,就是系统能排的“总坑位”。排课系统要做的,就是把课程逐个放进坑位。
这里先拆“硬约束”:同一班级同一时间只能上一门课;同一教师同一时间不能出现在两个教室;同一教室同一时间只能容纳一门课;教室容量不能小于上课人数。这几条只要违反,课表就没法执行,算法必须保证。软约束则更接近“好课表”的标准:专业核心课尽量排在上午、同一门课一周内的间隔不要太密、教师可以登记不想排课的时间段、合班上课时尽量让各专业人数均衡。能全部满足软约束的排课系统很少,老毕设里大多数只做硬约束检测。
提示:答辩时被问到“什么是硬约束、什么是软约束”,能指着代码里 hasConflict 方法说清楚哪几行实现了硬约束,比背概念有用得多。
软约束和硬约束的区别,决定了系统“智能”程度的上限。判断一个源码包的算法水平,先找它的排课类里有没有独立的软约束打分函数。只有冲突检测、没有评分函数的,基本就是“不冲突即可”的方案。能对冲突数和教室利用率做统计的,已经算有优化意识。常见约束条目可以汇总成下表:
| 约束类型 | 常见条目 | 违反后果 |
|---|---|---|
| 硬约束 | 班级、教师、教室在同一时间片唯一占用 | 课表无法执行 |
| 硬约束 | 教室容量 ≥ 上课人数 | 教室坐不下 |
| 硬约束 | 课程总学时与每周排课节数一致 | 学期末课时不够 |
| 软约束 | 上午优先排主课 | 教学效果打折 |
| 软约束 | 教师指定不可排课时间 | 教师投诉 |
| 软约束 | 同一课程每周分散排 | 集中上完容易忘 |
而如果你只是把这些约束记在脑子里,答辩时依然容易穿帮——因为大多数老项目把约束写死在代码里,而不是数据库里。这一点看到表结构就明白了。
2.2 数据库表的最小集合:课程、班级、教师、教室与结果表怎么建
拿到包之后的第一步不是运行,而是打开 SQL 文件看表结构。一套排课系统再花哨,核心也就是这几张表:班级表、教师表、课程表、教室表、排课结果表。很多老项目还会加用户表做登录权限、加学期表做多学期课表隔离。下面是一个常见的建表脚本,主键、唯一约束和关键字段都写上,方便对照你手里的源码库。
CREATE TABLE t_class ( class_id INT PRIMARY KEY AUTO_INCREMENT, class_name VARCHAR(50) NOT NULL, grade_year VARCHAR(10), student_count INT DEFAULT 0 ); CREATE TABLE t_teacher ( teacher_id INT PRIMARY KEY AUTO_INCREMENT, teacher_no VARCHAR(20) UNIQUE, teacher_name VARCHAR(50), title VARCHAR(20), max_hours_week INT DEFAULT 20 ); CREATE TABLE t_course ( course_id INT PRIMARY KEY AUTO_INCREMENT, course_name VARCHAR(100) NOT NULL, course_hours INT, course_type VARCHAR(20), -- 专业课 / 公共课 / 选修课 class_id INT, -- 必修课时可以直接绑定班级 teacher_id INT, preferred_days VARCHAR(20) -- 教师偏好,逗号分隔,可为空 ); CREATE TABLE t_classroom ( classroom_id INT PRIMARY KEY AUTO_INCREMENT, room_no VARCHAR(20), capacity INT, has_media TINYINT DEFAULT 0 ); CREATE TABLE t_schedule ( schedule_id INT PRIMARY KEY AUTO_INCREMENT, term VARCHAR(20), -- 2024-2025-1 这类学期号 class_id INT, course_id INT, teacher_id INT, classroom_id INT, week_day TINYINT, -- 1~5 period_no TINYINT, -- 1~12 UNIQUE KEY uk_class_slot (term, class_id, week_day, period_no), UNIQUE KEY uk_teacher_slot (term, teacher_id, week_day, period_no), UNIQUE KEY uk_room_slot (term, classroom_id, week_day, period_no) );这段脚本里最有价值的不是字段名,而是 t_schedule 上那三个唯一键:同一班级、同一教师、同一教室,在同一个学期、同一天、同一个节次都只能出现一次。这是数据库层防冲突的最后一道闸门。很多老毕设把冲突全部交给算法判断,结果就是算法有 bug 时,数据库里会直接出现两个班抢同一教室的记录,课表页面一团乱。读源码时先看它有没有这三个键——没有的话,说明系统的稳定性全部押在 Java 代码的 hasConflict 上。
外键在老项目里通常不建,原因很实际:增删改查全在管理页面里做,外键反而容易挡住删除操作。所以课程表的 class_id、teacher_id 我都没有写成 FOREIGN KEY,只是普通索引字段。答辩问起来就说“用程序层维护引用完整性,删除前先检查关联数据”,这是老 JSP 项目最常见的做法。
有些带“教室平面图”的排课系统,会在 t_classroom 上挂座位坐标字段,比如 seat_map 存 JSON,然后在 JSP 页面里对图片做坐标定位,把座位点渲染到背景图上。这类功能对排课冲突检测没有实际帮助,但截图放进论文“系统实现”里非常好看,也能回应题目里“智能”两个字。
2.3 JSP 项目怎么分层:从页面、Servlet 到 DAO 的代码识别方法
打开源码包之后,不要急着点开 JSP,先看目录。老 JSP 项目最常见的是 Model 2 分层:JSP 只做展示,Servlet 接收请求、控制跳转,DAO 负责 SQL 读写。一个典型的包结构大概长这样:
src/com/xxx/ servlet/ LoginServlet.java、CourseServlet.java、ScheduleServlet.java dao/ CourseDao.java、ScheduleDao.java、ClassroomDao.java entity/ Course.java、Teacher.java、Classroom.java util/ DBUtil.java、EncodingFilter.java WebRoot/ login.jsp、courseList.jsp、classList.jsp、teacherList.jsp schedule.jsp、timetableView.jsp WEB-INF/web.xml代码不长,整个系统通常在三十到五十个类之间,去掉页面也就几万行。跟网上讨论大模型源代码多少行完全是两个量级的项目,但这个体量对本科论文刚好:能讲清楚设计、能截图、能测试。识别分层时有个经验:包名下带 servlet 的类是控制层,带 dao 的是数据访问层,entity 里是 JavaBean;页面层看 WebRoot 或 webcontent 目录下的 JSP 文件名,基本能反推功能模块。
页面虽然多,但翻来覆去就是登录页面、个人信息展示页面、列表管理页面、表单提交页面、课表页面这几个套路。你同学抽到的《基于 JSP 的毕业论文管理过程系统设计与实现》也是同样结构:登录、列表、增删改查、报表导出。看透一个老 JSP 项目,其他 JSP 毕设都一个样。
特别提醒:Java Web 的 .java 文件规范是类名首字母大写,但老毕设里经常出现 ScheduleDao dao = new ScheduleDao() 这种对象名小写的写法,很正常。真要注意的是 JSP 页面里有没有大量 Scriptlet——也就是 <% %> 直接写 Java 代码。有 Scriptlet 说明项目是 Model 1 早期风格,逻辑全堆在页面上;全用 JSTL + EL 的是后来规范化的写法。毕业设计里两种都常见,别因为页面里嵌了 Java 代码就觉得项目烂,先看能不能跑。
2.4 “智能”到底在哪里:贪心填槽、冲突检测与进化算法的论文选型
“智能排课”四个字里,“智能”是最容易被挑战的部分。大多数毕业设计源码包的排课算法,其实就是带优先级的贪心填槽:先把课程按“专业课 > 公共课 > 选修课”排个序,然后从周一到周五、从第 1 节到第 12 节,逐间教室试槽位,找到一个四条硬约束都不冲突的位置就落座;找不到就跳过并记录下来。对应到代码,核心逻辑大概是下面这个样子:
// 排课主流程:按优先级从高到低,贪心寻找第一个可用槽位 List<Course> courses = courseDao.loadByPriority(term); for (Course c : courses) { boolean placed = false; outer: for (int day = 1; day <= 5 && !placed; day++) { for (int period = 1; period <= 12 && !placed; period++) { for (Classroom room : classroomDao.findAll()) { if (!hasConflict(c, term, day, period, room)) { scheduleDao.save(c, term, day, period, room); placed = true; break outer; // 找到就跳出所有循环,继续下一门课 } } } } if (!placed) { log.warn("课程 [" + c.getName() + "] 在学期 " + term + " 中无法安排"); } }hasConflict 是这段代码的灵魂,它执行三件事:查 t_schedule 里同一个班级在这个时间片有没有课、同一个教师有没有课、同一个教室有没有被占。这三条 SELECT 可以用一个联合查询替代,老项目通常分三次查,性能无所谓,课表规模本来就不大。这段逻辑配上刚才表里的硬约束,就是论文“算法设计”一章的全部内容。贪心的时间复杂度是“课程数 × 时间片数 × 教室数”,几千门课的学校也扛得住,算下来毫秒到秒级。
这里有个细节值得留意:Java 里 break 默认只跳出最内层循环。老代码里经常有人只写 break,结果教室循环跳出去了,day 和 period 循环还在继续跑,导致同一门课被排进后面好几个时间片。我写的是带标签的 break outer,跳出全部循环。如果在你手里的源码里看到这种 bug,论文的“系统测试”部分正好可以加一条冲突修正记录。
更“智能”一档的做法是遗传算法:把一张完整的课表编码成染色体,每个基因是一门课排到的时间片和教室,交叉、变异之后用适应度函数淘汰冲突多、软约束差的个体,迭代几百代后收敛。这个方向适合用来加分,但写论文之前要有心理准备:你至少得回答种群大小为什么是 100 而不是 10、交叉率为什么取 0.8、算法会不会早熟,这些实验数据不是抄一段描述就能糊弄过去的。我见过的本科排课毕设里,贪心 + 手动微调占绝大多数,遗传属于想拿优秀论文的人才会碰。先确认你手里的源码属于哪一档,再决定论文怎么写,别把不存在的算法写成自己的系统。
3. 把源码包跑起来:JDK、Tomcat、MySQL 的版本搭配与最小命令
3.1 环境版本怎么选:JDK 1.8、Tomcat 8.5、MySQL 5.7 的理由
老 JSP 项目对环境极其挑剔,版本选对,部署十分钟;版本选错,报错两小时。我一般固定用下面这组搭配,能覆盖九成以上的老毕设:
| 组件 | 推荐版本 | 为什么这样选 |
|---|---|---|
| JDK | 1.8(8u202 及以上) | 老代码大量使用过时 API,JDK 9+ 移除后直接 NoClassDefFoundError |
| Tomcat | 8.5.x | 对应 Servlet 3.1 + JSP 2.3,和老项目编译级别匹配 |
| MySQL | 5.7.x | mysql-connector-java 5.1.x 与 MySQL 8 的认证插件不兼容 |
| JDBC 驱动 | mysql-connector-java 5.1.49 | 5.1 系列最终版,兼容 JDK 8,不踩 MySQL 8 认证坑 |
| IDE | Eclipse 或任意编辑器 | Eclipse 导入老项目方便,但不是必需 |
这套版本组合的核心逻辑是“让代码跑在它被写出来的年代”。JDK 8 是兼容性最好的分水岭:再老的项目也基本能在上面编译,而 JDK 11 开始删掉了不少老 API。Tomcat 8.5 能跑绝大多数 Servlet 2.5~3.1 的项目,Tomcat 9 以后对 JSP 的 Tag 库和 EL 处理有变化,老项目容易在启动时报错。
连 MySQL 数据库时,如果机器上已经装的是 MySQL 8,我的经验是别硬刚,直接装一个 MySQL 5.7 的实例,或者用 Docker 起一个 5.7 容器专门给毕设用。省下的时间比看着报错查文档划算得多。等系统跑通、答辩结束,再去研究 MySQL 8 的认证插件也不迟。
3.2 初始化数据库:建库、导 SQL 与连接串的参数修正
源码包里通常带一个 .sql 文件,有的叫 timetable.sql,有的叫 db.sql。第一步是建库导入,命令在 Linux、macOS 和 Windows 上通用(Windows 用户把 mysql 命令换成 mysql.exe 的完整路径即可)。
# 1. 建库,指定 utf8mb4 字符集,避免后面中文乱码 mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS timetabling DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" # 2. 导入项目附带的 SQL 文件 mysql -u root -p timetabling < sql/timetabling.sql # 3. 确认表都建好了 mysql -u root -p -e "USE timetabling; SHOW TABLES;"导入成功后,打开项目里的 db.properties 或 DBUtil.java,把连接串、用户名、密码改成你自己的。老项目常见的连接串长这样:
jdbc.url=jdbc:mysql://localhost:3306/timetabling?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai jdbc.username=root jdbc.password=你自己数据库的密码连接串里有三个参数不是摆设:characterEncoding=utf8 保证读写中文不乱码;useSSL=false 避免 MySQL 5.7 在 SSL 握手时报 warning;serverTimezone=Asia/Shanghai 是给 MySQL 6+ 用的,5.7 不写也不报错。如果项目原来是 GBK 编码,建议把整个项目的字符集统一成 UTF-8,而不是去一个个页面改乱码。改完连接串保存,先别急着启动,下一步是确认 web.xml 里的 Servlet 映射和欢迎页面路径对吗。
3.3 部署到 Tomcat:命令行发布与 Eclipse 导入两种路径
部署老 JSP 项目有两条路。第一条是命令行直接发布:把项目整个目录或者打好的 war 包丢进 Tomcat 的 webapps 目录,启动 Tomcat,它自己解压和编译。优点是绕开 IDE 的工程配置,干净利落。
# 把项目目录拷到 Tomcat 的 webapps 下,目录名就是访问路径 cp -r timetablingWeb "$CATALINA_HOME/webapps/timetabling" # 启动 Tomcat(Windows 下执行 %CATALINA_HOME%\bin\startup.bat) "$CATALINA_HOME/bin/startup.sh" # 等 3~5 秒后看日志 tail -f "$CATALINA_HOME/logs/catalina.out"启动成功后访问 http://localhost:8080/timetabling/,能看到登录页就说明部署成功。如果页面 404,先看 webapps/timetabling 下有没有 WEB-INF,再看 web.xml 里 welcome-file 是不是 login.jsp。如果 500,去看 catalina.out 最下面的异常堆栈,十有八九是 JDBC 驱动没进 WEB-INF/lib。
第二条路是 Eclipse 导入。File → Import → Existing Projects into Workspace,选择解压后的目录,注意不要勾选 Copy projects into workspace,直接引用原目录,这样改代码和改文件能实时同步。然后在 Servers 视图里添加 Tomcat 8.5,右键项目 Run As → Run on Server。Eclipse 会自动把项目发布到 Tomcat 的 wtpwebapps,方便调试。但有两个前提:项目的 Java 版本是 1.8、项目的 Dynamic Web Module 版本在 Eclipse 里有对应 Facet。这两个对不上,就会看到满屏红叉,具体怎么解决放在第 4 章。
3.4 论文与代码怎么对上号:读论文时重点验证的四处内容
“源代码+论文”的 zip 里,论文同样重要。不少同学把系统跑通了,论文却还是原封不动的模板,答辩演示时讲到模块和代码对不上,被问两句就卡住。我的习惯是拿论文目录对着源码逐个盖章:
| 论文位置 | 源码验证点 | 容易被问到的点 |
|---|---|---|
| 需求分析中的用例图 | 登录、课程管理、排课管理、课表查看四个入口 | 你的系统有几种角色?权限怎么控制? |
| 总体设计中的功能模块图 | WebRoot 下的 JSP 目录层级 | 课表模块和教室模块之间怎么跳转 |
| 数据库设计中的 ER 图和表清单 | 对比实际建表 SQL 与 t_schedule 字段 | 班级表和课程表为什么不建外键? |
| 系统测试中的测试用例 | 每组测试数据能重新演示一遍 | 测试用例里的预期结果和实际输出一致吗? |
这里有个血泪经验:拿到包第一件事,把原始 zip 和解压目录分开放,各自保留一份,不要在原目录上改。老项目没有版本管理,你今天改两行代码,明天改两个页面,后天发现回不去了。把这个目录初始化成 Git 仓库,每调通一个模块就提交一次,等于给自己留了后悔药。这个习惯比写论文还重要。
4. 避坑:老 JSP 项目最容易翻车的 5 个现场与排查顺序
4.1 页面 500:ClassNotFoundException 和缺 jar 的解法
现象:Tomcat 能正常启动,但访问登录页不到一秒就报 500;日志里出现 java.lang.ClassNotFoundException: com.mysql.jdbc.Driver,或者 NoClassDefFoundError。
原因:最常见的两种情况,一是项目 WEB-INF/lib 目录里没有 MySQL 驱动 jar;二是机器装的 JDK 版本太高,老代码运行时差一个类。后者在 JDK 11+ 上尤其多,比如 java.xml.bind 包整个被移除,老代码一引用就崩。
解决:先把 mysql-connector-java-5.1.49.jar 放进 WEB-INF/lib,然后确认 java -version 输出是 1.8。如果机器只有高版本 JDK,去 Oracle 官网下载 JDK 8,安装后在 Eclipse 的 Window → Preferences → Java → Installed JREs 里加进去,并把项目的 JRE System Library 切到 JDK 8。改完执行 Project → Clean,让 Tomcat 把项目重新编译一遍再访问。
4.2 数据库连接失败:MySQL 8 驱动与认证插件的隐形坑
现象:登录页面能打开,但点登录按钮后跳到一个纯白或 500 页面;日志里有 Communications link failure,或者 Client does not support authentication protocol requested by server; consider upgrading MySQL client。
原因:MySQL 8 默认的认证插件是 caching_sha2_password,老驱动 mysql-connector-java 5.1.4x 只认 mysql_native_password,两边握手失败。这种现象在毕设圈子里极其常见,因为大家新装的 MySQL 基本都是 8.0。
解决:最简单的办法是换 MySQL 5.7,连接串里再带上前一章写的 useSSL=false。如果坚持用 MySQL 8,连接串要加 allowPublicKeyRetrieval=true,并且确认驱动不低于 8.0.x:
jdbc.url=jdbc:mysql://localhost:3306/timetabling?useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai注意,allowPublicKeyRetrieval=true 在有安全要求的场合不能乱开,但本机毕设环境用它解决认证握手问题是最直接的。换版本后记得清一下项目里 Tomcat 的缓存目录,有时候 jar 没更新也会继续报旧错。
4.3 中文乱码:页面、请求、数据库三层编码统一法
现象:登录后页面上的教师姓名、课程名称全是问号和乱码;往数据库里插入中文,查出来是 ??;同一个系统里有的页面中文正常,有的不正常。
原因:老 JSP 项目的编码没有全局约定,页面 pageEncoding 可能写了 GBK,Tomcat 接收 POST 参数又默认按 ISO-8859-1 解,数据库连接串里的 characterEncoding 也可能没写。三层里任何一层不对,中文就会翻车。
解决:统一成 UTF-8。在项目里加一个编码过滤器,一劳永逸地处理请求和响应的编码:
// 编码过滤器:统一请求与响应编码为 UTF-8 public class EncodingFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); chain.doFilter(request, response); } }然后在 web.xml 里注册这个过滤器,放行所有路径,同时保证每个 JSP 开头都有 <%@ page pageEncoding="UTF-8" %>,数据库连接串里保留 characterEncoding=utf8。三层全部对齐,乱码基本消失。如果页面原来写的是 GBK,要么全局换成 UTF-8,要么全局统一成 GBK,最怕页面一半 GBK 一半 UTF-8,那种乱码排查起来相当玄学。
4.4 端口被占用:Tomcat 起不来的常规死法
现象:startup.sh 或者 startup.bat 执行后,控制台一闪而过,日志里出现 Address already in use: JVM_Bind:8080;或者浏览器打开 8080 端口看到的不是你的系统。
原因:Tomcat 重复启动了一个实例,也可能是系统里有其他服务占用了 8080。
解决:先找到占用端口的进程并处理:
# Windows netstat -ano | findstr :8080 taskkill /PID 这里填PID /F # Linux / macOS lsof -i :8080 kill -9 这里填PID如果 8080 是别的服务,比如已经装好的另一个 Tomcat,我一般直接改 conf/server.xml 里的 Connector port,从 8080 改成 8081,然后访问 http://localhost:8081/timetabling/。这个改动看起来简单,但很容易忽略一个细节:有些老项目里写死了跳转地址的端口,页面登录成功后跳到一个 :8080 的路径,白屏半天才发现问题。
4.5 编译红叉:Eclipse 导入老项目的 JDK 版本错位
现象:Eclipse 导入项目后,项目名带红叉,Java 文件和 JSP 文件大面积报错,Problem 视图里全是 Project 'xxx' is missing required source folder,或者 Java compiler level does not match the version of the installed Java project facet。
原因:老项目没有 Maven 或 Gradle 管理,导入时 Eclipse 用机器上的高版本 JDK 默认编译。JDK 17 下,老代码里 new Integer(1) 这类写法会直接报编译错误,JSP 里引用的 Tag Library 也可能找不到。
解决:按顺序做三件事。项目右键 Properties → Java Compiler,把 Compiler compliance level 设为 1.8;项目右键 Properties → Java Build Path → Libraries,移除高版本 JRE,添加 JDK 1.8;项目右键 Properties → Project Facets,把 Dynamic Web Module 设为 3.0,Java 版本同样切到 1.8。做完 Project → Clean 全量重编译。如果这三处对不上,项目会一直处于“看起来能跑、一编译全是错”的假死状态。Eclipse 里处理老项目翻车,七成都是版本错位,先查这三个地方再去看代码。
5. 让“智能”二字立得住:排课结果验证、答辩加分与一条升级主线
系统跑通、论文能讲之后,还有一个问题躲不掉:它凭什么叫“智能排课”?我建议拿数据回答,而不是概念。取一个只有 5 个班级、20 门课、6 间教室的小数据集,手动排一版课表,再让系统自动排一版,统计三个指标:课程冲突数、教室平均利用率、教师每天连续上课的最大节数。冲突数应当为零,教室利用率大概率自动排比手动排高一些,连续节数则是老旧系统常被吐槽的点。把对比结果做成柱状图放论文“系统测试”章,比写三段“本系统提高了排课效率”有说服力得多。
答辩现场想加分,最划算的功能是“手动微调”:在课表页面上把某一节课从原时间片移到另一个空槽位,保存前再执行一次 hasConflict,不冲突才允许提交。这个功能代码量不大,但能补上贪心算法“排完就改不了”的短板,演示时给评委一种系统很完整的感觉。另一个被问概率很高的点是课表导出,用 POI 把 t_schedule 聚合后导出成 Excel,操作简单,却是很多老毕设都没有的部分。
如果毕业后还想走 Java 这条路,JSP 本身不推荐继续深挖,升级主线很清晰:把 DAO 层逻辑平移到 Spring Boot + MyBatis,页面换成 Thymeleaf,排课接口改成 REST,算法类和数据库表结构完全不动。排课这类老系统的核心价值从来不在页面技术,而在那张 t_schedule 和 hasConflict 上。
我当年拿到类似的项目,第一件事是去啃算法代码,结果环境没跑起来,越看越像玄学。后来老老实实按“先备份、再建库、后启动、最后看算法”的顺序走,才发现 80% 的时间都花在版本错配上。排课系统的代码结构并不神秘,跑通之后你甚至能判断出它哪部分是抄的、哪部分是真的能改。希望帮到你。
本文还有配套的精品资源,点击获取