山东大学软件学院项目实训:基于大模型的模拟面试系统项目总结(九)
在山东大学软件学院的项目实训中,团队成员们围绕基于大模型的模拟面试系统展开了一系列开发与优化工作。以下是本周项目的核心进展与成果总结。
前端界面优化与 Bug 修复(吴尤)
Logo 显示问题修复
在项目开发过程中,团队发现项目左上角的 SVG 格式 logo 存在两个主要问题:一是经常遮挡博客标题的输入区域;二是点击 logo 外围透明区域时也会触发返回主页的操作。通过使用专业的 SVG 编辑工具(如 Adobe Illustrator 或 Inkscape)进行图形裁剪,导出优化后的 SVG 文件,成功解决了这些问题,修复后点击热区与可视图形完全匹配,不再遮挡标题区域。
按钮消失 Bug 修复
当用户选中任意面试话题、删除该话题记录时,底部“新建面试对话”按钮会消失。经过代码审查发现,handleDeleteRecord
方法中存在逻辑缺陷,删除当前激活记录时将 currentInterviewer
误设为 null,导致按钮显示条件失效。修改后的核心逻辑不再重置 currentInterviewer
,修复了这一问题,按钮在删除操作后保持正常显示,用户体验得到改善。
导航栏视觉升级
原导航栏存在纯文字菜单缺乏视觉引导、层级结构不够清晰、不符合现代 UI 设计趋势等问题。团队为导航栏添加了图标系统,使用 Element UI 内置图标库,保持一致的右边距,按功能类别选择语义化图标。同时,增加了垂直间距,使用更现代的字体组合,添加平滑的 hover 动画效果,提升了导航栏的视觉效果和用户体验。
名称截断处理
对于可能过长的名称显示,团队采用了统一的截断方案,保留完整 tooltip 提示,并适配响应式布局,确保了界面的整洁性和信息的完整展示。
面试官和面试记录分享功能开发(李一铭)
卡片渲染
开发了面试官和面试记录的卡片渲染功能,使用 Element UI 的卡片组件展示面试官和面试记录的信息。面试官卡片显示面试官的头像、名称和描述,面试记录卡片显示面试记录的主题、面试官名称和操作按钮。用户可以通过点击按钮获取面试官或面试记录,增强了系统的互动性。
前后端对接
实现了获取分享的面试官信息和面试记录的前后端对接。前端通过调用后端的 /api/share/interviewShareToUser
和 /api/share/chatShareToUser
接口,将面试官或面试记录的 ID 传递给后端。后端接收到请求后,将对应的面试官或面试记录数据复制到当前用户的账户下,并返回成功提示。这一功能的实现,使得用户可以方便地分享和获取优质的面试官和面试记录资源。
数据处理与标签优化(孙旭)
标签层次结构设计方案
在微调算法题推荐功能的开发过程中,团队面临了微调数据中特征属性过多、标签分布稀疏的问题。经过研究和比较,选择了标签层次结构设计方案,通过手动设计多层次的标签体系,将原始标签归类到不同的类别和子类别中。这一方案不仅保留了原始标签的语义信息,结构清晰,易于理解和维护,还符合领域专家的认知方式,更贴合实际应用场景。通过实现标签层次结构,解决了标签稀疏性问题,提高了推荐精度,增强了系统的可解释性。
方案比较:研究了三种可能的解决方案,包括PCA + 特征选择组合、卷积神经网络(CNN)+ 聚类、标签层次结构设计。最终选择了标签层次结构设计方案,因为它更符合算法和数据结构领域的层次关系,且系统需要保持结果的可解释性。
标签层次结构实现:通过代码实现了标签层次结构,包括关键标签筛选、层次化特征生成等步骤。代码中定义了核心算法标签列表和层次化映射字典,通过分析标签重要性、选择重要标签、创建层次化特征等步骤,将原始标签优化为更有效的特征体系。
主处理流程框架:描述了整个特征处理的总控流程,包括数据读取、基本统计、特征分配策略、核心标签筛选、层次特征生成、结果保存等步骤,并计算了信息保留度。
关键标签筛选策略:采用三重机制筛选核心标签,优先选择关键算法标签,然后是高频标签和高共现标签。
层次化特征生成:将非关键标签按逻辑分类聚合,使用反向映射机制和层次化规则,过滤低频类别。
数据分析与验证:包括标签共现矩阵计算、完整性检查、信息保留率验证等,确保处理结果的质量。
详细报告生成:生成可追溯的处理日志,包括关键标签保留清单、层次化标签的组成说明、被合并标签的映射关系等。
MCP服务器工具改进
修改了MCP服务器中的工具函数,增强了题目推荐的精准度。通过调用工具函数“generate_problem_selection_prompt”,根据面试表现和简历信息生成算法题选择提示。
在面试官AI的提示词模板中增加了对这些工具的调用说明,使AI能够在合适的时机根据候选人的表现调用相应的工具函数。
题目管理与数据统计功能完善(吴浩明)
题目添加功能
实现了题目的添加功能,丰富了题库内容。在后端的 ProblemController.java
中,完善了题目的添加逻辑,通过接收前端传递的 ProblemDTO
对象,并进行参数校验、设置默认值、创建时间和更新时间等操作,最后调用服务层的方法将题目信息持久化到数据库。前端的 add.vue
文件中,使用 Element UI 组件构建了题目添加的表单,实现了数据双向绑定和表单校验规则,并通过调用后端接口发送 POST 请求完成题目的添加。
数据统计功能
完成了用户练习情况、题目通过率等关键指标的统计与展示。在后端的 ProblemServiceImpl.java
中,实现了用户练习情况的统计逻辑,查询当前用户的所有提交记录,统计用户已接受的题目 ID 集合和已尝试的题目 ID 集合,以及题目总数,并将统计结果封装到 Map 中返回。前端的 index.vue
文件中,通过调用后端接口获取统计数据,并使用 Element UI 的卡片和进度条组件展示总题数、已解决和尝试过的题目数量及其对应的比率。同时,对统计准确性进行了修正,确保只统计可见的题目,并移除了 Redis 缓存逻辑,改为直接从数据库读取数据,保证了数据的实时性。
判题逻辑优化
调整了获取用户提交记录的逻辑,不再进行 distinct
操作,确保 acceptedProblemIds
根据题目 ID 进行去重且提交状态为 ACCEPTED
,attemptedProblemIds
根据题目 ID 进行去重且不限制提交状态。这一优化提高了判题的准确性和效率。
题目总数统计修正
修正了题目总数统计逻辑,确保只统计可见的题目,避免了因统计不准确导致的用户困惑和系统专业性受损。
缓存策略调整
移除了数据统计功能中的 Redis 缓存逻辑,改为直接从数据库读取数据,以保证数据的实时性。这一调整虽然可能会略微增加数据库的访问压力,但确保了用户看到的统计数据是最新的,提升了系统的可靠性和用户体验。
AI面试官及与AI的聊天记录分享(王博凡)
这篇文章主要介绍了山东大学软件学院项目实训中,基于大模型的模拟面试系统的AI面试官与聊天记录分享功能的设计与实现。以下是文章的核心内容总结:
功能概述
用户可以将自己创建或使用过的AI面试官及与AI的聊天记录,通过文章的形式分享给其他用户。
其他用户可以查看分享的AI资源,并一键将其添加到自己的账户下使用。
分享的内容以“快照”形式存在,即分享出去的是一个独立副本,原作者后续的修改不影响已分享的内容,反之亦然。
数据结构设计
新增ShareReference
表:存储文章与分享的AI资源(面试官/聊天记录快照)之间的关联关系。
扩展ArticleDTO
:增加用于承载分享内容的列表,分别用于存储聊天记录快照和面试官快照。
核心流程设计
用户选择要分享的AI面试官或聊天记录。
系统对每个被选中的资源执行深度拷贝操作,生成独立副本(快照),并与特定的系统用户关联。
创建新的ShareReference
记录,关联文章ID、快照类型和快照ID。
如果是更新文章,会先删除旧的ShareReference
记录及旧快照数据,再创建新的快照和关联。
通过文章ID查询ShareReference
表,获取关联的分享项。
根据type
和对应的chatId
或interviewerId
,获取快照的详细信息。
在前端以卡片样式展示分享的AI资源,提供预览信息和“添加到我的”按钮。
前端将快照ID和类型传递给后端API。
后端调用相应的deepCopy
服务,将快照内容复制到当前登录用户的账户下。
用户获得一个属于自己的、全新的副本,可自由修改,不影响原始快照。
深度拷贝机制
为目标用户在Milvus中创建新的Collection。
遍历源知识库中的文件,重新解析文件内容,分割成文本块,生成向量。
将新的KnowledgeRecord
批量插入到新的Collection中。
- 更新MongoDB中的
MilvusDatabase
和MilvusFile
元数据。
调用milvusService.deepCopy
复制知识库,获取新的知识库ID。
创建新的Interviewer
对象,设置新知识库ID和其他属性。
保存新的Interviewer
对象。
调用interviewerService.deepCopy
复制关联的面试官,获取新的面试官ID。
创建新的ChatRecords
对象,关联新的面试官ID和目标用户ID。
保存新的ChatRecords
以获得其ID。
遍历源聊天记录的所有Branch
,调用branchDeepCopy
复制每个分支及其消息。
处理children
(子分支ID列表)的映射,确保它们指向新复制的子分支ID。