摘要:本文详细介绍基于Java+SpringBoot+Vue的高校毕业生实习管理系统设计与实现。系统采用B/S架构,集成协同过滤+随机森林混合推荐算法实现个性化岗位推荐,支持WebSocket实时通信与AI智能问答。涵盖学生、教师、管理员三端权限,实现实习岗位发布、申请审批、周志管理、过程监管、综合评价等全流程数字化管理。适用于高校实习管理、毕业设计参考、Java全栈开发学习等场景,提供完整源码与文档支持。

💗博主介绍:✌全网粉丝20W+,CSDN全栈领域优质创作者,博客之星、掘金/华为云/阿里云等平台优质作者,计算机毕设实战导师。目前专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌
💗主要服务内容免费功能设计、选题定题、开题报告、任务书、程序开发、论文编写和辅导、论文降重、程序讲解、答辩辅导等,欢迎咨询~
👇🏻 精彩专栏 推荐订阅👇🏻
计算机毕业设计精品项目案例(持续更新,值得收藏!)✅
2026-2027年计算机毕业设计选题推荐:计算机专业毕业设计题目大全✅
全网最全计算机毕业设计选题推荐:计算机毕设选题指导及避坑指南✅
🌟文末获取源码+数据库+文档🌟
感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以和学长沟通,希望帮助更多的人

一.项目概述

在这里插入图片描述

高校毕业生实习是人才培养的核心实践环节,直接决定学生岗位适配能力与就业质量。现阶段多数高校仍采用线下登记、表格填报、人工审核的传统管理模式,存在诸多弊端:一是实习岗位信息分散,学生筛选成本高、岗位匹配随机性强;二是实习申请、周志提交、进度汇报等流程线下流转,审批效率低下、数据易丢失;三是教师无法实时监管学生实习动态,过程性考核缺失;四是师生沟通渠道单一,问题答疑、经验交流滞后;五是实习数据人工统计,准确率低、无法为院校教学优化提供数据支撑。

为解决上述痛点,本文依托Java开发语言、SpringBoot轻量化后端框架、Vue前端框架,搭配MySQL关系型数据库,搭建B/S架构的高校毕业生实习管理系统。系统以“智能赋能、流程闭环、全程可溯、多方协同”为核心设计理念,构建多角色分级权限体系,区分学生前台操作端、教师与管理员后台管理端,重构实习管理全业务流程。通过引入混合推荐算法、实时通信技术与AI智能模型,打破传统系统功能单一、智能化程度低的局限,实现实习信息集约化存储、业务流程标准化流转、实习过程可视化监管、数据成果智能化分析,全面提升高校实习管理的工作效率与信息化水平。


二.开发技术栈

2.1 基础环境

JDK:1.8 及以上
数据库:MySQL 5.7(指定版本,保证数据兼容性)
项目构建工具:Maven 3.6.1
开发工具:IntelliJ IDEA / Eclipse

2.2 核心技术架构

系统整体采用前后端分离架构,彻底解耦前端页面展示与后端业务逻辑,提升开发效率与后期维护性,各端核心技术分工明确:
后端技术:以Java为基础语言,SpringBoot框架为核心,简化SSM框架繁琐配置,快速实现接口开发、业务逻辑处理、数据持久化与权限管控;整合拦截器、JWT令牌、文件处理等组件,保障系统安全稳定运行。
前端技术:基于Vue渐进式框架+ElementUI组件库搭建交互界面,搭配HTML5、CSS3完成页面渲染,实现页面轻量化、响应式展示,适配PC端多尺寸设备。
拓展核心技术:集成WebSocket实时通信、ECharts数据可视化、协同过滤+随机森林混合推荐算法、AI智能问答模型,赋能系统智能化、实时化、可视化能力。
数据存储:采用MySQL数据库,通过主键约束、唯一约束、外键约束、非空约束,保障业务数据的完整性、一致性与可追溯性。


三.系统分析

3.1 需求分析与角色划分

3.1.1 总体功能需求

本系统采用前后端分离架构,后端基于 Spring Boot 框架、前端基于 Vue 框架开发,选用 MySQL 数据库完成数据持久化,依托约束机制保障数据一致性、完整性与安全性。技术层面集成多种技术组件:运用协同过滤 + 随机森林混合推荐算法实现实习岗位精准推荐;借助 WebSocket 技术搭建实时社交互动模块;通过 ECharts 完成业务数据可视化;结合 AI 大模型实现智能数据分析与自动问答功能。
系统围绕高校实习全流程开展设计,覆盖岗位推荐、申请审批、过程监管、成果评价、实时交流、智能问答、数据统计等核心业务,兼顾多角色操作需求,同时具备良好的可维护性与扩展性。

3.1.2 技术需求

数据存储:采用 MySQL 关系型数据库,设置数据约束,保证数据完整、一致、安全可靠。
架构与开发:前后端分离架构,通过接口完成数据交互;后端使用 Spring Boot,前端使用 Vue。
智能推荐:基于协同过滤 + 随机森林混合算法,实现个性化实习岗位推荐。
实时通信:采用 WebSocket 全双工通信,实现论坛实时发帖、回复、评论等社交互动。
数据可视化:结合 ECharts 组件,对业务数据进行图表化展示。
智能应用:引入 AI 大模型,完成数据深度分析、结论输出以及实习问题自动答疑,支持问题人工转接。

3.1.3 角色划分

结合业务场景与权限差异,将系统用户划分为管理员、指导教师、学生三类角色,不同角色拥有独立操作权限与业务功能,具体定位如下:
管理员:系统最高权限管理者,负责后台整体运维、用户管理、交流内容审核、数据统计分析、智能问答人工兜底处理,统筹系统正常运转。
指导教师:实习业务核心管理者,主要负责实习岗位维护、学生实习申请审核、实习过程监管、实习成果评价,完成实习全流程管控。
学生:系统前台使用主体,主要进行岗位浏览与申请、实习周志填报、进度与评价查询、在线交流、智能问答等操作,完成个人实习相关业务。

3.1.4 各角色细分功能需求

(1)管理员功能需求
账号登录:凭账号密码登录系统后台,依据权限访问对应功能。
用户信息管理:查询、维护全体用户基础信息,维护系统基础数据。
实习交流管理:管理论坛板块,审核帖子内容,删除违规言论、置顶优质精华帖。
统计分析管理:依托 AI 大模型分析岗位、实习申请等数据并输出分析结论,通过 ECharts 实现数据图表可视化展示。
问答运维管理:承接智能问答无法解答的用户问题,进行人工回复处理。
(2)指导教师功能需求
账号登录:凭账号密码登录教师后台,使用对应权限功能。
实习岗位管理:编辑、维护实习岗位名称、任职要求、所属单位等信息。
实习申请审核:对学生实习申请进行同意 / 驳回操作,填写审核意见并同步结果。
实习过程管理:查看学生实习周志与实习进度,批阅周志内容,监督实习开展。
实习评价管理:针对学生实习表现进行打分与综合评价,评价结果统一存档。
(3)学生功能需求
账号登录:使用学号登录系统前台,进入个人实习中心。
个人信息管理:查看、修改个人基础信息。
岗位推荐浏览:查看系统基于混合算法推送的个性化实习岗位,查阅岗位详情。
实习申请:选择意向岗位并提交申请,查看申请状态。
实习周志管理:定期填写、提交实习周志,留存实习记录。
进度与评价查询:实时查看个人实习进度、教师给出的实习评价。
实时交流互动:在交流板块发帖、回复、评论,实现实时在线沟通。
智能问答:在问答专区提交问题,获取 AI 自动解答,支持问题转接人工处理。

3.2 用例设计

结合业务需求绘制学生用例图、教师用例图、管理员用例图,清晰定义各角色可执行操作:
在这里插入图片描述

图1:管理员用例图

在这里插入图片描述

图2:学生用例图

在这里插入图片描述

图3:教师用例图

3.3 系统功能模块设计

结合业务需求与角色权限差异,采用分层模块化设计思想,将系统整体划分为学生前台、教师后台、管理员后台三大功能体系,各模块独立解耦、协同联动,覆盖实习管理全业务流程,架构层次清晰、功能覆盖全面。
(1)学生前台功能模块
面向学生用户提供一站式实习服务,核心包含系统首页、智能岗位推荐、实习资讯浏览、实时交流社区、AI智能问答、个人中心六大模块。其中个人中心集成密码修改、实习申请管理、实习周志提交、指导记录查询、实习进度追踪、实习评价查阅、岗位收藏、个人发帖管理等精细化功能,全面满足学生实习全流程线上操作需求。
(2)教师后台功能模块
聚焦教师实习管控核心业务,涵盖实习岗位维护、学生实习申请审核、实习周志批阅、实习指导记录管理、实习进度监管、学生实习综合评价、个人信息管理七大核心模块,支撑教师完成实习全过程指导、监督与考核工作。
(3)管理员后台功能模块
承担系统全局运维与数据管控工作,功能覆盖用户信息管理、专业与岗位类型管理、实习岗位统筹管理、实习申请监管、实习周志核查、指导记录审核、实习进度管控、实习评价管理、实习资讯维护、社区内容审核、系统基础配置等全维度模块,实现平台业务、用户、内容、数据的一体化管控。系统整体功能模块结构如图所示。
在这里插入图片描述

图4:功能模块结构图

3.4 系统流程分析

系统以用户登录为业务起点,构建标准化、闭环式实习管理业务流程,全程线上流转、全程可追溯。整体流程如下:用户完成账号登录后,学生可浏览系统智能推荐的实习岗位,筛选心仪岗位并提交实习申请;教师与管理员在后台实时接收申请工单,结合岗位要求与学生信息完成审核,并同步审核结果与意见;审核通过后学生正式开展实习,按周期在线填报实习周志、更新实习进度;教师实时查看学生实习动态,在线批阅周志、记录指导过程,完成实习全过程监管;实习结束后,教师根据学生整体表现完成综合评价与打分;管理员全程统筹所有业务数据,进行统计分析与运维管控,形成完整的实习管理业务闭环。系统流程图如图所示:
在这里插入图片描述

图5:系统流程图

四.数据设计

本系统基于MySQL数据库完成数据架构设计,围绕高校实习全业务场景,针对性设计17张核心业务数据表,全面覆盖用户信息、岗位信息、实习申请、周志记录、指导过程、实习评价、社区交流、智能问答、系统配置等所有业务场景。所有数据表统一规范设计:采用自增主键保障数据唯一性,默认配置系统创建时间字段,对状态类、标识类字段预设编码规则与默认值,通过约束机制保障数据完整性、一致性与安全性,支撑系统查询、提交、审核、流转、统计等全功能稳定运行。
为直观展示各实体数据关联关系,本文展示学生、教师、实习交流、实习申请核心实体E-R图及系统总体E-R图,清晰呈现各数据表的字段属性、关联关系与业务映射逻辑。
学生实体关系如图所示:
在这里插入图片描述

图6:学生实体E-R图

教师实体关系如图所示:
在这里插入图片描述

图7:教师实体E-R图

实习交流实体关系如图所示:
在这里插入图片描述

图8:实习交流实体E-R图

实习申请实体关系如图所示:
在这里插入图片描述

图9:实习申请实体E-R图

系统总体E-R图如图所示:
在这里插入图片描述

图10:系统总体E-R图

五.部分效果展示

5.1前台学生功能实现效果

生在登录页输入学号与密码提交,系统校验账号信息并生成有效访问凭证,登录成功后进入首页并可访问岗位、资讯与个人中心等功能入口。学生登录界面图如下所示:
在这里插入图片描述

图11:学生登录效果图

学生进入首页浏览系统导航与信息列表,可查看实习资讯标题与发布人等内容并快速进入详情页,首页同时作为进入岗位查询与交流入口的起点页面。学生首页界面图如下所示:

在这里插入图片描述

图12:学生首页效果图

学生进入实习岗位页可按岗位类型、单位与地点等信息进行查询,查看岗位名称、实习周期与薪资待遇等详情,选择意向岗位后进入申请流程并形成申请记录。实习岗位界面图如下所示:

在这里插入图片描述

图13:实习岗位效果图

学生进入个人中心可修改个人信息与密码,并查看实习申请审核状态与审核回复,按要求提交周志与进度,同时查看指导记录与评价结果,统一管理收藏与发布内容。学生个人中心界面图如下所示:
在这里插入图片描述

图14:个人中心效果图

5.2后台管理员功能实现效果

管理员在登录页输入用户名与密码进入后台,系统校验账号与角色信息后建立管理会话,登录成功后进入后台首页并获得全局管理与审核权限入口。管理员登录界面图如下所示:
在这里插入图片描述

图15:管理员登录效果图

管理员进入后台首页可查看功能导航并进入岗位、申请、周志与评价等业务模块,首页用于集中访问管理入口并支持对内容管理与基础数据维护的快速跳转。管理员首页界面图如下所示:
在这里插入图片描述

图16:管理员首页效果图

管理员进入实习岗位管理页可新增与维护岗位信息,设置实习单位、岗位名称、岗位类型与薪资待遇等字段,发布后岗位信息在学生端可查询并支持收藏计数更新。实习岗位管理界面图如下所示:

在这里插入图片描述

图17:实习岗位管理效果图

管理员进入实习申请管理页可按学号、姓名与申请时间查询记录,查看申请说明并处理审核状态与审核回复,审核结果回写后学生端可在个人中心查看变化。实习申请管理界面图如下所示:

在这里插入图片描述

图18:实习申请管理效果图

管理员进入实习周志管理页可按实习编号、周志标题查询内容,查看学生填写时间与实习内容等信息,必要时进行记录维护以保证过程资料完整可追溯。实习周志管理界面图如下所示:
在这里插入图片描述

图19:实习周志管理效果图

管理员进入指导记录管理页可查看教师账号、指导老师与指导时间等信息,核对实习指导与监督内容是否完整,确保指导过程记录与学生周志形成对应关系。指导记录管理界面图如下所示:
在这里插入图片描述

图20:指导记录管理效果图

管理员进入实习进度管理页可查看学生提交时间与实习进度内容,结合完成情况字段了解阶段目标达成,必要时督促补充信息以维持过程记录连续性。实习进度管理界面图如下所示:
在这里插入图片描述

图21:实习进度管理效果图

管理员进入实习评价管理页可查看教师姓名、学号与评价时间等信息,核对完成情况、实习表现与评价内容,确认成绩字段填写规范并支撑最终质量归档。实习评价管理界面图所示:
在这里插入图片描述

图21:实习评价管理效果图

管理员进入实习交流管理页可按帖子标题与状态查询内容,处理是否审核与审核回复并设置置顶状态,管理后交流内容在学生端可按规则展示并保留发布痕迹。实习交流管理界面图所示:
在这里插入图片描述

图22:实习交流管理效果图

5.3后台教师功能实现效果

教师进入后台首页可查看与指导相关的功能导航,按学生学号与实习编号定位业务记录,进入指导记录与评价模块填写指导时间、监督内容与评价内容等信息。后台主界面图所示:
在这里插入图片描述

图23:教师主页效果图

六.部分代码实现

6.1 项目开发核心技术难点说明

难点1:跨域访问与域名校验问题
系统适配多端访问,前端页面与后端接口域名、端口不一致,同时微信小程序存在严格的域名白名单校验机制,极易出现跨域请求失败、接口拦截问题,严重影响系统调试与线上运行。
**解决方案:**开发阶段通过开发者工具关闭域名校验策略,规避本地跨域限制,提升调试效率;项目上线前,将后端公网HTTPS域名配置至微信小程序合法域名白名单,同时在SpringBoot后端配置全局跨域拦截器,统一放行前端跨域请求,彻底解决前后端接口跨域通信问题,保障多端接口稳定交互。
难点2:用户会话安全与Token有效期管控
传统Session机制依赖服务器会话存储,适配性差、扩展性低,无法满足移动端长期在线需求;Token永久有效易引发账号被盗、信息泄露风险,有效期过短则会导致用户频繁掉线,影响使用体验。
**解决方案:**采用JWT无状态Token认证机制,替代传统Session会话,减轻服务器存储压力,适配分布式部署场景;合理配置Token有效期,兼顾账号安全性与用户体验;自定义全局拦截器,统一校验Token的合法性、有效性、过期状态,拦截所有非法请求与过期会话,全方位保障系统接口安全。
难点3:文件上传超限与安全风险问题
系统支持用户头像、实习配图、周志附件、岗位图片等多类型文件上传,大文件上传易导致接口卡顿、服务器资源占用过高、程序崩溃,同时存在非法格式文件上传的安全隐患。
**解决方案:**在SpringBoot配置文件中全局限制单文件大小与单次请求总文件大小,从底层拦截超大文件;后端代码增加文件非空校验、文件后缀白名单校验、文件格式过滤,杜绝空文件、恶意文件、非法格式文件上传;通过时间戳生成唯一文件名,避免文件重名覆盖,保障文件上传接口的安全性、稳定性与唯一性。
难点4:单一推荐算法精准度低、适配性差
传统实习管理系统仅采用单一协同过滤或基于规则的推荐方式,存在冷启动严重、特征挖掘不全面、泛化能力弱的问题,无法精准匹配学生个性化岗位需求,推荐效果同质化严重。
解决方案:创新性采用协同过滤+随机森林混合推荐架构,结合两种算法的核心优势:通过协同过滤挖掘用户历史交互行为、相似用户偏好,实现行为维度推荐;通过随机森林算法训练学生专业、意向、学历、岗位属性等多维度特征,实现特征分类推荐。同时基于Java反射机制实现多实体通用数据预处理,解决不同业务实体字段适配问题,通过加权融合算法整合双模型推荐结果,过滤用户已交互数据,实现精准、个性化、无重复的岗位推荐,大幅提升推荐准确率

6.2 文件上传接口

用于小程序图片、活动配图、头像等文件上传,自动生成唯一文件名并存储至项目静态资源目录,支持模板文件特殊处理。

/**
 * 文件上传接口
 * @param file 前端上传文件
 * @param type 文件类型标记
 * @return 上传结果与文件名称
 * @throws Exception 文件读写异常
 */
@RequestMapping("/upload")
@IgnoreAuth  // 跳过权限校验
public R upload(@RequestParam("file") MultipartFile file,String type) throws Exception {
    // 校验文件是否为空
    if (file.isEmpty()) {
        throw new EIException("上传文件不能为空");
    }
    // 截取文件后缀名
    String fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1);
    // 定义文件存储根路径
    File path = new File(ResourceUtils.getURL("classpath:static").getPath());
    if(!path.exists()) {
        path = new File("");
    }
    // 拼接upload上传目录
    File upload = new File(path.getAbsolutePath(),"/upload/");
    if(!upload.exists()) {
        upload.mkdirs();
    }
    // 基于时间戳生成唯一文件名,防止重名覆盖
    String fileName = new Date().getTime()+"."+fileExt;
    // 模板文件特殊处理
    if(StringUtils.isNotBlank(type) && type.contains("_template")) {
        fileName = type + "."+fileExt;
        new File(upload.getAbsolutePath()+"/"+fileName).deleteOnExit();
    }
    // 执行文件写入
    File dest = new File(upload.getAbsolutePath()+"/"+fileName);
    file.transferTo(dest);
    // 若为头像类型,同步更新系统配置表
    if(StringUtils.isNotBlank(type) && type.equals("1")) {
        ConfigEntity configEntity = configService.selectOne(new EntityWrapper<ConfigEntity>().eq("name", "faceFile"));
        if(configEntity==null) {
            configEntity = new ConfigEntity();
            configEntity.setName("faceFile");
            configEntity.setValue(fileName);
        } else {
            configEntity.setValue(fileName);
        }
        configService.insertOrUpdate(configEntity);
    }
    // 返回成功结果与文件名称
    return R.ok().put("file", fileName);
}

6.3 用户登录接口

基于账号密码完成身份校验,校验通过后生成唯一 Token 作为后续接口身份凭证,实现无状态登录。

/**
 * 用户登录接口
 * @param username 账号
 * @param password 密码
 * @param captcha 验证码
 * @param request 请求对象
 * @return 登录结果 + Token令牌
 */
@IgnoreAuth
@RequestMapping(value = "/login")
public R login(String username, String password, String captcha, HttpServletRequest request) {
    // 根据账号查询用户信息
    YonghuEntity u = yonghuService.selectOne(new EntityWrapper<YonghuEntity>().eq("yonghuzhanghao", username));
    // 校验账号密码
    if(u==null || !u.getMima().equals(password)) {
        return R.error("账号或密码不正确");
    }
    // 生成用户Token令牌(配置固定有效期,保障接口安全)
    String token = tokenService.generateToken(u.getId(), username,"yonghu",  "用户" );
    return R.ok().put("token", token);
}

6.4 智能推荐方法

// ======================== 随机森林推荐模型 ========================

    public static class RandomForestModel implements Serializable {
        private static final long serialVersionUID = 1L;
        private RandomForest forest; // Weka随机森林实例
        private List<String> allItemIds; // 所有物品ID列表
        private Map<String, Map<String, Object>> userFeatures; // 用户特征映射
        private List<String> featureNames; // 特征名称列表(用于构建输入)

        /**
         * 训练随机森林模型
         *
         * @param userFeatures   用户特征(buildUserFeatures的输出)
         * @param userItemMatrix 用户-物品交互矩阵(buildUserItemMatrix的输出)
         */
        public void train(Map<String, Map<String, Object>> userFeatures,
                          Map<String, Map<String, String>> userItemMatrix) {
            this.userFeatures = userFeatures;

            // 提取所有物品ID
            Set<String> itemIdSet = new HashSet<>();
            userItemMatrix.values().forEach(itemMap -> itemIdSet.addAll(itemMap.keySet()));
            this.allItemIds = new ArrayList<>(itemIdSet);

            // 提取特征名称(在构建训练数据之前)
            if (!userFeatures.isEmpty()) {
                Map<String, Object> sampleFeat = userFeatures.values().iterator().next();
                this.featureNames = new ArrayList<>(sampleFeat.keySet());
                // 添加itemId特征名
                this.featureNames.add("itemId");
            } else {
                this.featureNames = new ArrayList<>();
            }

            try {
                // 构建训练数据集(含正负样本)
                Instances trainingData = buildTrainingInstances(userFeatures, userItemMatrix);

                // 初始化并训练随机森林(Weka 3.8.5兼容)
                forest = new RandomForest();
                //forest.setNTrees(100); // 设置树数量(注意方法名是setNTrees)
                forest.buildClassifier(trainingData);
            } catch (Exception e) {
                throw new RuntimeException("随机森林训练失败", e);
            }
        }


        /**
         * 为指定用户推荐物品
         *
         * @param userId 用户ID
         * @param limit  推荐数量
         * @return 物品ID列表(按推荐分数降序)
         */
        public List<String> predict(String userId, int limit) {
            if (forest == null || !userFeatures.containsKey(userId)) {
                return Collections.emptyList();
            }

            Map<String, Double> itemScores = new HashMap<>();
            Map<String, Object> userFeat = userFeatures.get(userId);

            // 计算所有物品的推荐分数
            for (String itemId : allItemIds) {
                try {
                    Instance instance = buildInstance(userFeat, itemId);
                    double score = forest.classifyInstance(instance); // 预测交互概率
                    itemScores.put(itemId, score);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            // 按分数排序并取前N
            return itemScores.entrySet().stream()
                    .sorted(Map.Entry.<String, Double>comparingByValue().reversed())
                    .limit(limit)
                    .map(Map.Entry::getKey)
                    .collect(Collectors.toList());
        }

        /**
         * 构建Weka训练数据集(含正负样本)
         */
        private Instances buildTrainingInstances(Map<String, Map<String, Object>> userFeatures,
                                                 Map<String, Map<String, String>> userItemMatrix) {
            // 定义特征属性
            ArrayList<Attribute> attributes = new ArrayList<>();

            // 添加用户特征属性(如专业、性别)
            if (!userFeatures.isEmpty() && featureNames != null) {
                for (String featName : featureNames) {
                    if (!featName.equals("itemId")) {
                        attributes.add(new Attribute(featName));
                    }
                }
            }

            // 添加物品ID属性
            attributes.add(new Attribute("itemId"));

            // 添加标签属性(1=交互,0=未交互)
            List<String> classLabels = Arrays.asList("0", "1");
            attributes.add(new Attribute("label", classLabels));

            // 初始化数据集
            Instances instances = new Instances("user_item_data", attributes, 0);
            instances.setClassIndex(attributes.size() - 1); // 最后一列为标签

            // 添加正样本(用户已交互的物品)
            for (Map.Entry<String, Map<String, String>> userEntry : userItemMatrix.entrySet()) {
                String userId = userEntry.getKey();
                Map<String, String> itemMap = userEntry.getValue();
                Map<String, Object> userFeat = userFeatures.get(userId);

                // 增加空值检查
                if (userFeat == null || userFeat.isEmpty()) continue;

                for (String itemId : itemMap.keySet()) {
                    Instance instance = buildInstance(userFeat, itemId, instances);
                    instance.setClassValue("1");
                    instances.add(instance);
                }
            }

            // 添加负样本(数量与正样本相当)
            int positiveCount = instances.size();
            int negativeCount = 0;
            Random random = new Random();
            for (Map.Entry<String, Map<String, String>> userEntry : userItemMatrix.entrySet()) {
                String userId = userEntry.getKey();
                Map<String, String> interactedItems = userEntry.getValue();
                Map<String, Object> userFeat = userFeatures.get(userId);

                // 增加空值检查
                if (userFeat == null || userFeat.isEmpty()) continue;

                int maxAttempts = allItemIds.size() * 10; // 最大尝试次数
                int attempts = 0;
                while (negativeCount < positiveCount && attempts < maxAttempts) {
                    String randomItemId = allItemIds.get(random.nextInt(allItemIds.size()));
                    attempts++;
                    if (!interactedItems.containsKey(randomItemId)) {
                        Instance instance = buildInstance(userFeat, randomItemId, instances);
                        instance.setClassValue("0");
                        instances.add(instance);
                        negativeCount++;
                        break;
                    }
                }

            }

            return instances;
        }


源码及文档获取

文章下方名片联系我即可~
大家点赞、收藏、关注、评论啦 、查看👇🏻获取联系方式👇🏻
精彩专栏推荐订阅:在下方专栏👇🏻

最新计算机毕业设计选题篇-选题推荐
小程序毕业设计精品项目案例-200套
Java毕业设计精品项目案例-200套
Python毕业设计精品项目案例-200套
大数据毕业设计精品项目案例-200套
💟💟如果大家有任何疑虑,欢迎在下方位置详细交流。

更多推荐