1. 项目背景与核心价值
高校实习信息管理一直是困扰教务部门和学生的痛点问题。传统的Excel表格+微信群方式存在信息分散、更新不及时、检索困难等弊端。去年帮母校计算机学院开发实习管理系统时,系主任提到他们每年要处理3000+条实习信息,人工匹配效率极低。这正是我选择这个毕业设计方向的初衷——用Spring技术栈构建一个专业化实习信息平台。
这个系统要实现的核心功能包括:
- 企业端:实习岗位发布、简历筛选、面试安排
- 学生端:岗位检索、简历投递、进度查询
- 管理员:院系管理、数据统计、黑名单机制
相比市面通用招聘平台,高校定制化系统能深度对接教务数据(如课程表、学分信息),实现智能化的"课表冲突检测"、"专业匹配度评分"等特色功能。这也是答辩时评委最感兴趣的技术亮点。
2. 技术架构设计
2.1 整体技术选型
采用经典的SpringBoot + MyBatis Plus组合,前端选用Thymeleaf模板引擎而非主流Vue/React,主要考虑:
- 学校服务器环境限制(仅支持Tomcat部署)
- 降低学习成本(评委老师更熟悉传统MVC模式)
- 快速开发需求(毕业设计周期通常仅3个月)
mermaid复制graph TD
A[前端] -->|Thymeleaf| B(SpringBoot)
B -->|MyBatis Plus| C[MySQL]
B --> D[Redis缓存]
C --> E[定时备份]
特别注意:学校环境通常禁用外网访问,所有依赖必须打包进war文件。建议使用maven-shade-plugin打包所有第三方jar。
2.2 数据库关键设计
实习信息表的字段设计颇有讲究,核心字段包括:
| 字段名 | 类型 | 特殊约束 | 业务意义 |
|---|---|---|---|
| start_date | DATE | 必须大于当前日期 | 防止过期岗位 |
| work_city | VARCHAR | 建立空间索引 | 支持地图检索 |
| credit_require | INT | 默认0 | 学分要求 |
sql复制-- 专业匹配度计算函数
CREATE FUNCTION major_match(student_id INT, post_id INT)
RETURNS FLOAT
BEGIN
DECLARE score FLOAT;
SELECT COUNT(*) INTO score
FROM student_course
WHERE student_id = student_id
AND course_name IN (SELECT require_skill FROM post_skill WHERE post_id = post_id);
RETURN score * 0.2; -- 权重系数需调整
END
3. 核心功能实现
3.1 智能推荐算法
在StudentServiceImpl中实现的推荐逻辑:
java复制public List<InternshipPost> recommendPosts(Long studentId) {
// 1. 获取学生专业课程
List<String> courses = studentCourseMapper.selectByStudent(studentId);
// 2. 检索匹配岗位(带缓存)
String cacheKey = "recommend:" + studentId;
List<InternshipPost> posts = redisTemplate.opsForValue().get(cacheKey);
if(posts == null) {
posts = postMapper.selectRecommend(courses);
redisTemplate.opsForValue().set(cacheKey, posts, 1, TimeUnit.HOURS);
}
// 3. 课表冲突过滤
return posts.stream()
.filter(p -> !scheduleConflict(studentId, p.getWorkDays()))
.sorted(comparing(InternshipPost::getMatchScore).reversed())
.collect(Collectors.toList());
}
3.2 文件上传安全处理
企业上传营业执照时需特别注意:
java复制@PostMapping("/upload")
public String uploadLicense(@RequestParam MultipartFile file) {
// 1. 文件类型校验
String ext = FilenameUtils.getExtension(file.getOriginalFilename());
if(!Arrays.asList("jpg","png").contains(ext.toLowerCase())){
throw new IllegalFileTypeException();
}
// 2. 病毒扫描(调用ClamAV)
scanService.scan(file);
// 3. 重命名存储
String newName = UUID.randomUUID() + "." + ext;
Path path = Paths.get("/certificates", newName);
Files.copy(file.getInputStream(), path);
return newName;
}
4. 部署踩坑实录
4.1 学校服务器特殊配置
-
端口限制:通常只开放80/443端口,需修改application.properties:
properties复制server.port=80 server.tomcat.uri-encoding=UTF-8 -
MySQL版本问题:学校机房多用MySQL 5.7,需注意:
- 禁用GROUP BY新特性
- 调整datetime默认值语法
-
路径权限:Linux服务器通常禁止写入/webapps以外目录,解决方案:
bash复制chmod o+w /var/lib/tomcat9/webapps/ROOT/WEB-INF/upload
4.2 答辩演示技巧
-
准备两套数据库:
- 精简版(50条记录)用于演示
- 完整版(5000+记录)供评委查验
-
关键SQL添加执行计划注释:
sql复制EXPLAIN SELECT /*+ INDEX(post idx_city) */ * FROM post WHERE work_city='上海' AND status=1; -
压力测试报告要包含:
- JMeter模拟100并发注册
- 导出GC日志分析图表
5. 扩展建议
-
微信通知集成:
使用学校企业微信API实现:java复制public void sendWechatNotice(String openId, String content) { String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + getToken(); JSONObject msg = new JSONObject(); msg.put("touser", openId); msg.put("msgtype", "text"); msg.put("agentid", config.getAgentId()); msg.put("text", new JSONObject().put("content", content)); restTemplate.postForObject(url, msg, String.class); } -
简历解析方案对比:
方案 准确率 成本 适用场景 正则匹配 60% 低 固定格式简历 百度OCR 85% 中 图片简历 阿里NLP 92% 高 复杂版式 -
智能排班算法:
基于贪心算法的实现思路:python复制def schedule_interviews(students, slots): sorted_students = sorted(students, key=lambda s: s.priority) result = [] for student in sorted_students: for slot in slots: if slot.available and compatible(student, slot): result.append((student, slot)) slot.available = False break return result
这个项目最让我有成就感的是看到学弟学妹们实际使用系统时,不再需要像我们当年那样在十几个群里爬楼找实习信息。特别是"课表冲突检测"功能,帮一个学妹避免了入职后发现每周三下午有必修课的尴尬情况。如果时间允许,下一步想用Elasticsearch重构检索模块,解决目前LIKE查询的性能瓶颈。