一个学 Java 后端的大学生用 AI Coding 从零开发了一个 AI 面试陪练工具和大家聊聊全过程踩坑与收获作者MuYi | Java 后端学习者项目地址https://gitee.com/MuYi-2025/interview-assistance-system前言大家好我是一名正在找 Java 后端实习的大学生。最近秋招/春招季身边同学都在忙着刷八股、改简历、投递记录。我发现大家面临的问题出奇地一致八股背了就忘看的时候觉得都会面试一问就卡壳简历写完不知道质量如何找学长看又不好意思总麻烦人家投了几十家公司根本记不清哪家到什么阶段了于是我花了些时间做了一个AI 面试教练Interview Copilot用 LLM 来帮助大家系统化地准备面试。写这篇文章一方面是分享这个工具的使用方法另一方面也聊聊我在开发过程中的一些思考和收获。一、这个工具能做什么先上功能清单功能说明面试模拟从题库抽题逐题作答AI 实时评分 反馈简历诊断上传 PDFAI 从六个维度分析简历质量岗位匹配粘贴 JDAI 分析简历匹配度和改进建议场景出题根据你的技能标签AI 生成真实业务场景题题库管理批量导入面试题支持 JSON/CSV/TXT投递记录管理求职进度状态筛选 统计概览核心思路很简单把面试准备这件事从散装学习变成系统化训练。二、为什么用 LLM 而不是传统方案做这个项目之前我也想过用传统的规则引擎来做面试评分。但很快就发现了问题面试题的回答是开放式的。比如问HashMap 的底层原理你可以说数组 链表 红黑树也可以说通过 key 的 hashCode 定位桶冲突时用链表链表过长转红黑树。两种回答都对但深度不同。用传统方案很难评判这种差异而 LLM 天然擅长这个。它能理解回答的语义而不是做关键词匹配从准确性、完整性、表达清晰度多个维度打分给出具体的改进建议而不是泛泛的答得不错这就是为什么选择 LLM 作为核心引擎。三、架构设计项目采用前后端分离架构整体分为三层┌─────────────────────────────────────────────┐ │ Vue 3 前端 (Element Plus) │ │ 首页 │ 简历管理 │ 面试练习 │ 题库 │ 投递记录 │ └──────────────────┬──────────────────────────┘ │ HTTP / SSE流式传输 ┌──────────────────▼──────────────────────────┐ │ FastAPI 后端 (Python) │ │ 用户管理 │ 简历分析 │ 面试引擎 │ 投递记录 │ └──────────────────┬──────────────────────────┘ │ ┌──────────────────▼──────────────────────────┐ │ 基础设施层 │ │ DeepSeek LLM │ 百炼向量模型 │ ChromaDB │ │ JSON 文件存储 │ pdfplumber PDF 解析 │ └─────────────────────────────────────────────┘技术选型考量组件选择为什么LLMDeepSeek性价比高OpenAI 兼容接口切换成本低向量模型阿里云百炼 text-embedding-v4中文语义理解好同样是 OpenAI 兼容接口向量库ChromaDB轻量级无需额外部署服务本地文件即可运行后端FastAPIPython 生态 异步支持 自动 API 文档前端Vue 3 Element Plus组件丰富上手快适合快速开发数据存储JSON 文件简历、面试记录这类文本数据量不大JSON 文件足够用省去数据库部署关于数据存储多说两句。一开始我尝试过用 MySQL 存面试记录但发现一个尴尬的问题面试记录里有大量的文本问题、回答、反馈、报告这些内容塞进 MySQL 的 TEXT 字段并不优雅而且对于个人工具来说部署一个 MySQL 服务太重了。最终决定全部用 JSON 文件存储配合目录结构来组织数据简洁且可移植。这也是很多 CLI 工具如 VS Code 的配置、npm 的 package-lock.json采用的方案。四、核心流程详解4.1 面试模拟流程这是整个项目最核心的功能流程如下用户选择难度和题数 │ ▼ 无放回随机抽题random.sample │ ▼ ┌─→ 展示第 N 题 ←─────────────────┐ │ │ │ │ ▼ │ │ 用户作答 │ │ │ │ │ ▼ │ │ SSE 流式评分LLM 逐 token 输出│ │ │ │ │ ▼ │ │ 显示评分 反馈 │ │ │ │ │ └── 还有下一题── 是 ────────┘ │ │ │ 否 │ ▼ │ SSE 流式生成综合报告 │ │ │ ▼ │ 保存到 JSON 文件 │ 题目、回答、评分、报告关于抽题算法最初用random.choice()循环抽题但发现题库较小时重复率很高。后来改成random.sample()做无放回抽样一次抽好 N 道题天然不重复。这是一个很典型的小优化解决大问题的例子。关于流式传输LLM 生成完整报告可能需要 10-30 秒。如果用传统的同步请求用户盯着 loading 转圈体验很差。改用 SSEServer-Sent Events后用户能实时看到文字一个个蹦出来等待感大幅降低。实现方式并不复杂后端FastAPIdefevent_stream():forchunkinllm.stream(prompt):ifchunk.content:yieldfdata:{json.dumps({chunk:chunk.content})}\n\nreturnStreamingResponse(event_stream(),media_typetext/event-stream)前端Vue 3 fetchconstresponseawaitfetch(url,{method:POST,body:...})constreaderresponse.body.getReader()while(true){const{done,value}awaitreader.read()if(done)break// 解析 SSE 数据追加到显示区域}4.2 简历诊断流程上传 PDF → pdfplumber 提取文本 │ ▼ LLM 六维度诊断流式 - 基本信息完整性 - 技术栈匹配度 - 项目经历质量 - 成果量化程度 - 排版与表达 - 整体竞争力 │ ▼ 自动提取技能清单 用于后续场景出题 │ ▼ 保存报告 技能 → 可下载 Markdown关于 PDF 解析用的是 pdfplumber纯 Python 库不需要安装额外依赖。它能很好地处理大多数简历的排版提取出干净的文本。遇到扫描版 PDF纯图片会提取失败这种情况下会提示用户。4.3 RAG 场景出题这个功能结合了向量检索和LLM 生成用户技能标签[Java, Spring, MySQL] │ ▼ 对每个技能用向量模型在题库中检索最相关的 3 道题 │ ▼ 将检索到的题目作为参考连同技能标签一起发给 LLM │ ▼ LLM 生成结合实际项目场景的面试题这比单纯让 LLM 出题效果好很多因为有了题库的锚点生成的题目更有针对性不会跑偏。向量检索的实现用 ChromaDB 阿里云百炼的 embedding 模型fromchromadbimportPersistentClientfromlangchain_openaiimportOpenAIEmbeddings# 初始化embeddingsOpenAIEmbeddings(modeltext-embedding-v4)clientPersistentClient(pathchroma_db)collectionclient.get_or_create_collection(questions)# 检索query_vectorembeddings.embed_query(Java 集合框架)resultscollection.query(query_embeddingsquery_vector,n_results3)4.4 投递记录管理这个功能相对简单就是对 JSON 文件的 CRUD 操作。但有一个设计细节值得说一下状态流转。投递状态有标准的流转顺序未投递 → 已投递 → 测评 → 笔试 → 一面 → 二面 → 三面 → 终面 → offer / 已终止同时还需要处理历史数据中的旧状态名称比如笔试进行中要映射到笔试所以单独抽了一个normalize_status()函数来做状态归一化。五、开箱即用5 分钟跑起来这个项目的另一个目标是低门槛。不想让大家为了用一个工具先折腾半天环境。准备工作Python 3.10Node.js 18DeepSeek API Key去 platform.deepseek.com 注册获取阿里云百炼 API Key去 dashscope.console.aliyun.com 获取3 步启动# 第 1 步配置环境变量cp.env.example .env# 编辑 .env填入两个 API Key# 第 2 步启动后端pipinstall-rrequirements.txt python main.py# → http://localhost:8000/docs 自带 API 文档# 第 3 步启动前端cdfrontendnpminstallnpmrun dev# → http://localhost:5173打开浏览器创建用户上传简历开始练习。就是这么简单。不需要安装数据库不需要配置 Docker不需要申请额外的云服务。两个 API Key 两个命令搞定一切。如果你不想用 Web 界面也可以直接python main.py --cli走命令行交互。六、开发过程中的一些感悟6.1 从能用到好用的距离项目的第一版是纯 CLI 的能跑通核心流程但体验很原始。后来加了 Web 界面后才发现能用和好用之间差了很多东西流式传输LLM 生成需要时间用户盯着 loading 圈会焦虑。改成流式输出后用户能看到内容在生长心理感受完全不同。Markdown 渲染LLM 输出的是 Markdown 格式的文本直接显示就是一堆##和**。用 md-editor-v3 的预览组件渲染后报告的可读性提升了一个档次。报告下载分析完一份简历后用户可能想保存或分享。加了下载为 Markdown按钮后这个需求就闭环了。这些都不是核心功能但每一个都能让用户多用几次。6.2 关于数据存储的取舍一开始我用 MySQL 存面试记录后来改成了 JSON 文件。这个过程让我理解了一个道理技术选型要看场景不要看正确性。MySQL 是正确的关系型数据库但对于一个个人工具来说面试记录主要是文本数据不适合塞进关系表部署 MySQL 对于小工具来说太重了JSON 文件可读、可编辑、可版本控制、可直接复制备份后来我把这个思路也用在了其他项目上小工具用文件大系统用数据库别一开始就上重型方案。6.3 Prompt Engineering 比代码更重要这个项目里真正写代码的时间可能只占 40%剩下 60% 都在调 prompt。举个例子评分 prompt 经历了三个版本V1太简单请给这个面试回答打分。→ 输出格式不统一分数解析困难。V2加了维度请从准确性、完整性、表达清晰度三个维度打分每项 0-10 分。→ 格式统一了但反馈太泛像准确性不错建议提升完整性。V3加了约束请从三个维度打分每个维度给出分数后必须指出回答中具体的亮点和不足并给出改进建议。格式准确性X 分 - …→ 反馈具体了能指出你提到了红黑树但没说明触发条件。Prompt 就是和 AI 沟通的代码它的质量直接决定了输出质量。这个认知对我帮助很大不仅在这个项目里后来做其他 LLM 相关的尝试时都会先花时间打磨 prompt。6.4 关于重复造轮子做这个项目的过程中我也犹豫过市面上不是有类似的工具吗为什么还要自己做后来想通了造轮子不是为了替代别人的轮子而是为了理解轮子是怎么转的。通过这个项目我学到了RAG 架构向量检索 LLM 生成的结合方式SSE 流式传输前后端如何实现实时数据流PDF 文本提取pdfplumber 的使用和局限性前端状态管理Pinia 在实际项目中的用法API 设计RESTful 接口的规划和文档化这些经验是看再多教程也换不来的。七、未来计划目前项目已经覆盖了面试准备的基本场景后续还打算面试历史回顾查看过去的面试记录跟踪进步轨迹更多题型支持目前主要是八股文后续加入算法题、系统设计题面试报告对比多次练习后对比不同时间的得分趋势导出更多格式支持导出 PDF 格式的报告写在最后这个项目是我学习后端开发过程中的一个实践。它不完美但对我而言意义重大——从学知识到做东西这个跨越只有动手了才能完成。如果你也在准备面试或者对 LLM 应用开发感兴趣欢迎试试这个工具也欢迎提 issue 和 PR。项目地址https://gitee.com/MuYi-2025/interview-assistance-systemGitHubhttps://github.com/Y-MuYi/Interview-Copilot.git觉得有用的话点个 Star 支持一下吧如果这篇文章对你有帮助欢迎点赞、收藏、转发。有问题也可以在评论区交流~
从零做了一个 AI 面试陪练工具,聊聊全过程
一个学 Java 后端的大学生用 AI Coding 从零开发了一个 AI 面试陪练工具和大家聊聊全过程踩坑与收获作者MuYi | Java 后端学习者项目地址https://gitee.com/MuYi-2025/interview-assistance-system前言大家好我是一名正在找 Java 后端实习的大学生。最近秋招/春招季身边同学都在忙着刷八股、改简历、投递记录。我发现大家面临的问题出奇地一致八股背了就忘看的时候觉得都会面试一问就卡壳简历写完不知道质量如何找学长看又不好意思总麻烦人家投了几十家公司根本记不清哪家到什么阶段了于是我花了些时间做了一个AI 面试教练Interview Copilot用 LLM 来帮助大家系统化地准备面试。写这篇文章一方面是分享这个工具的使用方法另一方面也聊聊我在开发过程中的一些思考和收获。一、这个工具能做什么先上功能清单功能说明面试模拟从题库抽题逐题作答AI 实时评分 反馈简历诊断上传 PDFAI 从六个维度分析简历质量岗位匹配粘贴 JDAI 分析简历匹配度和改进建议场景出题根据你的技能标签AI 生成真实业务场景题题库管理批量导入面试题支持 JSON/CSV/TXT投递记录管理求职进度状态筛选 统计概览核心思路很简单把面试准备这件事从散装学习变成系统化训练。二、为什么用 LLM 而不是传统方案做这个项目之前我也想过用传统的规则引擎来做面试评分。但很快就发现了问题面试题的回答是开放式的。比如问HashMap 的底层原理你可以说数组 链表 红黑树也可以说通过 key 的 hashCode 定位桶冲突时用链表链表过长转红黑树。两种回答都对但深度不同。用传统方案很难评判这种差异而 LLM 天然擅长这个。它能理解回答的语义而不是做关键词匹配从准确性、完整性、表达清晰度多个维度打分给出具体的改进建议而不是泛泛的答得不错这就是为什么选择 LLM 作为核心引擎。三、架构设计项目采用前后端分离架构整体分为三层┌─────────────────────────────────────────────┐ │ Vue 3 前端 (Element Plus) │ │ 首页 │ 简历管理 │ 面试练习 │ 题库 │ 投递记录 │ └──────────────────┬──────────────────────────┘ │ HTTP / SSE流式传输 ┌──────────────────▼──────────────────────────┐ │ FastAPI 后端 (Python) │ │ 用户管理 │ 简历分析 │ 面试引擎 │ 投递记录 │ └──────────────────┬──────────────────────────┘ │ ┌──────────────────▼──────────────────────────┐ │ 基础设施层 │ │ DeepSeek LLM │ 百炼向量模型 │ ChromaDB │ │ JSON 文件存储 │ pdfplumber PDF 解析 │ └─────────────────────────────────────────────┘技术选型考量组件选择为什么LLMDeepSeek性价比高OpenAI 兼容接口切换成本低向量模型阿里云百炼 text-embedding-v4中文语义理解好同样是 OpenAI 兼容接口向量库ChromaDB轻量级无需额外部署服务本地文件即可运行后端FastAPIPython 生态 异步支持 自动 API 文档前端Vue 3 Element Plus组件丰富上手快适合快速开发数据存储JSON 文件简历、面试记录这类文本数据量不大JSON 文件足够用省去数据库部署关于数据存储多说两句。一开始我尝试过用 MySQL 存面试记录但发现一个尴尬的问题面试记录里有大量的文本问题、回答、反馈、报告这些内容塞进 MySQL 的 TEXT 字段并不优雅而且对于个人工具来说部署一个 MySQL 服务太重了。最终决定全部用 JSON 文件存储配合目录结构来组织数据简洁且可移植。这也是很多 CLI 工具如 VS Code 的配置、npm 的 package-lock.json采用的方案。四、核心流程详解4.1 面试模拟流程这是整个项目最核心的功能流程如下用户选择难度和题数 │ ▼ 无放回随机抽题random.sample │ ▼ ┌─→ 展示第 N 题 ←─────────────────┐ │ │ │ │ ▼ │ │ 用户作答 │ │ │ │ │ ▼ │ │ SSE 流式评分LLM 逐 token 输出│ │ │ │ │ ▼ │ │ 显示评分 反馈 │ │ │ │ │ └── 还有下一题── 是 ────────┘ │ │ │ 否 │ ▼ │ SSE 流式生成综合报告 │ │ │ ▼ │ 保存到 JSON 文件 │ 题目、回答、评分、报告关于抽题算法最初用random.choice()循环抽题但发现题库较小时重复率很高。后来改成random.sample()做无放回抽样一次抽好 N 道题天然不重复。这是一个很典型的小优化解决大问题的例子。关于流式传输LLM 生成完整报告可能需要 10-30 秒。如果用传统的同步请求用户盯着 loading 转圈体验很差。改用 SSEServer-Sent Events后用户能实时看到文字一个个蹦出来等待感大幅降低。实现方式并不复杂后端FastAPIdefevent_stream():forchunkinllm.stream(prompt):ifchunk.content:yieldfdata:{json.dumps({chunk:chunk.content})}\n\nreturnStreamingResponse(event_stream(),media_typetext/event-stream)前端Vue 3 fetchconstresponseawaitfetch(url,{method:POST,body:...})constreaderresponse.body.getReader()while(true){const{done,value}awaitreader.read()if(done)break// 解析 SSE 数据追加到显示区域}4.2 简历诊断流程上传 PDF → pdfplumber 提取文本 │ ▼ LLM 六维度诊断流式 - 基本信息完整性 - 技术栈匹配度 - 项目经历质量 - 成果量化程度 - 排版与表达 - 整体竞争力 │ ▼ 自动提取技能清单 用于后续场景出题 │ ▼ 保存报告 技能 → 可下载 Markdown关于 PDF 解析用的是 pdfplumber纯 Python 库不需要安装额外依赖。它能很好地处理大多数简历的排版提取出干净的文本。遇到扫描版 PDF纯图片会提取失败这种情况下会提示用户。4.3 RAG 场景出题这个功能结合了向量检索和LLM 生成用户技能标签[Java, Spring, MySQL] │ ▼ 对每个技能用向量模型在题库中检索最相关的 3 道题 │ ▼ 将检索到的题目作为参考连同技能标签一起发给 LLM │ ▼ LLM 生成结合实际项目场景的面试题这比单纯让 LLM 出题效果好很多因为有了题库的锚点生成的题目更有针对性不会跑偏。向量检索的实现用 ChromaDB 阿里云百炼的 embedding 模型fromchromadbimportPersistentClientfromlangchain_openaiimportOpenAIEmbeddings# 初始化embeddingsOpenAIEmbeddings(modeltext-embedding-v4)clientPersistentClient(pathchroma_db)collectionclient.get_or_create_collection(questions)# 检索query_vectorembeddings.embed_query(Java 集合框架)resultscollection.query(query_embeddingsquery_vector,n_results3)4.4 投递记录管理这个功能相对简单就是对 JSON 文件的 CRUD 操作。但有一个设计细节值得说一下状态流转。投递状态有标准的流转顺序未投递 → 已投递 → 测评 → 笔试 → 一面 → 二面 → 三面 → 终面 → offer / 已终止同时还需要处理历史数据中的旧状态名称比如笔试进行中要映射到笔试所以单独抽了一个normalize_status()函数来做状态归一化。五、开箱即用5 分钟跑起来这个项目的另一个目标是低门槛。不想让大家为了用一个工具先折腾半天环境。准备工作Python 3.10Node.js 18DeepSeek API Key去 platform.deepseek.com 注册获取阿里云百炼 API Key去 dashscope.console.aliyun.com 获取3 步启动# 第 1 步配置环境变量cp.env.example .env# 编辑 .env填入两个 API Key# 第 2 步启动后端pipinstall-rrequirements.txt python main.py# → http://localhost:8000/docs 自带 API 文档# 第 3 步启动前端cdfrontendnpminstallnpmrun dev# → http://localhost:5173打开浏览器创建用户上传简历开始练习。就是这么简单。不需要安装数据库不需要配置 Docker不需要申请额外的云服务。两个 API Key 两个命令搞定一切。如果你不想用 Web 界面也可以直接python main.py --cli走命令行交互。六、开发过程中的一些感悟6.1 从能用到好用的距离项目的第一版是纯 CLI 的能跑通核心流程但体验很原始。后来加了 Web 界面后才发现能用和好用之间差了很多东西流式传输LLM 生成需要时间用户盯着 loading 圈会焦虑。改成流式输出后用户能看到内容在生长心理感受完全不同。Markdown 渲染LLM 输出的是 Markdown 格式的文本直接显示就是一堆##和**。用 md-editor-v3 的预览组件渲染后报告的可读性提升了一个档次。报告下载分析完一份简历后用户可能想保存或分享。加了下载为 Markdown按钮后这个需求就闭环了。这些都不是核心功能但每一个都能让用户多用几次。6.2 关于数据存储的取舍一开始我用 MySQL 存面试记录后来改成了 JSON 文件。这个过程让我理解了一个道理技术选型要看场景不要看正确性。MySQL 是正确的关系型数据库但对于一个个人工具来说面试记录主要是文本数据不适合塞进关系表部署 MySQL 对于小工具来说太重了JSON 文件可读、可编辑、可版本控制、可直接复制备份后来我把这个思路也用在了其他项目上小工具用文件大系统用数据库别一开始就上重型方案。6.3 Prompt Engineering 比代码更重要这个项目里真正写代码的时间可能只占 40%剩下 60% 都在调 prompt。举个例子评分 prompt 经历了三个版本V1太简单请给这个面试回答打分。→ 输出格式不统一分数解析困难。V2加了维度请从准确性、完整性、表达清晰度三个维度打分每项 0-10 分。→ 格式统一了但反馈太泛像准确性不错建议提升完整性。V3加了约束请从三个维度打分每个维度给出分数后必须指出回答中具体的亮点和不足并给出改进建议。格式准确性X 分 - …→ 反馈具体了能指出你提到了红黑树但没说明触发条件。Prompt 就是和 AI 沟通的代码它的质量直接决定了输出质量。这个认知对我帮助很大不仅在这个项目里后来做其他 LLM 相关的尝试时都会先花时间打磨 prompt。6.4 关于重复造轮子做这个项目的过程中我也犹豫过市面上不是有类似的工具吗为什么还要自己做后来想通了造轮子不是为了替代别人的轮子而是为了理解轮子是怎么转的。通过这个项目我学到了RAG 架构向量检索 LLM 生成的结合方式SSE 流式传输前后端如何实现实时数据流PDF 文本提取pdfplumber 的使用和局限性前端状态管理Pinia 在实际项目中的用法API 设计RESTful 接口的规划和文档化这些经验是看再多教程也换不来的。七、未来计划目前项目已经覆盖了面试准备的基本场景后续还打算面试历史回顾查看过去的面试记录跟踪进步轨迹更多题型支持目前主要是八股文后续加入算法题、系统设计题面试报告对比多次练习后对比不同时间的得分趋势导出更多格式支持导出 PDF 格式的报告写在最后这个项目是我学习后端开发过程中的一个实践。它不完美但对我而言意义重大——从学知识到做东西这个跨越只有动手了才能完成。如果你也在准备面试或者对 LLM 应用开发感兴趣欢迎试试这个工具也欢迎提 issue 和 PR。项目地址https://gitee.com/MuYi-2025/interview-assistance-systemGitHubhttps://github.com/Y-MuYi/Interview-Copilot.git觉得有用的话点个 Star 支持一下吧如果这篇文章对你有帮助欢迎点赞、收藏、转发。有问题也可以在评论区交流~