
1. 这个在线教育平台到底要做什么以及我从哪里开始拆解这是一套典型的毕业设计级前后端分离项目技术栈锁定在Vue3 Spring Boot核心业务覆盖三个大块课程管理、作业管理、在线考试。很多同学拿到这类题目后第一反应是先搭个框架然后把页面做出来、接口能跑通就交差。但实际去答辩或者面试的时候面试官/评委问得最多的问题往往不是你做了什么而是你为什么要这么设计这个表为什么是这么设计的某个具体场景你考虑过没有。我这次做下来最大的感触是在线教育平台这个题目看似比电商、社交简单但真要做得合理它背后藏着的三类并发模型、两种状态流转、以及一套权限边界足够你把Spring Boot的核心玩明白。这个平台的价值在于三个方向一是运营方管理员要管课程、管老师、管分类二是老师要发布课程内容、布置作业、创建试卷、批阅打分三是学生要在PC端看视频、做作业、上考场。这三类角色如果共用一套接口或者一套页面那维护会是灾难。所以在设计上我走的是前后端完全分离的路子——Vue负责交互和路由Spring Boot只做Restful API。第一次开发这种规模项目的人最容易犯的错就是沉迷于一个方法查完所有数据比如查看课程详情的时候把课程信息、章节列表、视频地址、老师信息全部塞进一个JSON里返回。当时图省事确实爽但后面做作业模块和考试模块时就发现这种大接口根本没法复用还容易踩到懒加载和缓存失效的坑。我建议的拆解维度是从数据血缘上下手账号体系是一棵树课程体系是一棵树作业和考试分别挂在课程节点下。这种结构关系如果是画成图几乎一眼就能看出表该怎么建。我下面会把这些拆成详细的表和字段但先记住一条总原则在线教育系统的核心不是视频播放有多顺也不是页面有多炫而是状态机——课程从创建到上架的流转作业从发布到批阅的流转考试从开始到成绩归档的流转这几个状态流转做对了整个系统就立住了。2. 技术选型为什么是Vue3 Spring Boot以及那些默认就该会的环境细节2.1 前后端分离到底分的是什么我先说结论Vue负责的是状态用户在页面上看到什么、点击之后UI怎么变Spring Boot负责的是数据谁有权限做什么、数据落库成什么样。之前很多教程喜欢用Thymeleaf把页面和接口揉在一起对于课设来说不是不行但你一旦上了Spring Boot Vue的分离架构后面你写简历、走面试至少比别人多一个可以深聊的工程化话题。前端我做的是Vue 3 Vite Vue Router Pinia。Vue 3对比Vue 2最大的变化是组合式APIComposition API比如定义响应式数据用ref/reactive逻辑复用用hooks。在做课程列表筛选、考试倒计时这种场景时hooks的复用价值非常明显。Vite做开发服务器那真是舒服热更新比Webpack快一个量级但有个细节很容易被忽略Vite默认的代理配置如果没做开发时前端所有请求跨域会直接让你怀疑人生。我是在vite.config.js里配了server.proxy把/api前缀统一转发到后端的http://localhost:8080这样前端写的baseURL就是/api而不是完整地址。后端我用的是Spring Boot 2.7.xSpring Boot 3也出了但要JDK 17起课设环境很多还是JDK 8为了兼容我选了2.7。配合MyBatis-Plus做ORMJWT做无状态认证Spring Security做权限拦截。这套组合是当前Java Web领域最主流、社区问答最全的搭配你几乎能在网上找到任何报错的处理方案。2.2 环境配置的三个隐藏坑第一个坑是Maven镜像。国内直接拉Maven中央仓库卡到你怀疑网络有问题。我是一开始在settings.xml里配了阿里云镜像后面又额外加了华为云的War包仓库。框架用的是Spring Initializr生成的但很多人在这步会卡住JDK版本、Maven版本、Spring Boot版本必须匹配比如Spring Boot 2.7配JDK 8没问题但如果你用IDEA自带的Maven 3.9去跑老项目有时会出现各种奇怪的依赖冲突。第二个坑是Node版本。Vite 4要求Node 14.18或者16如果你机器上Node是老版本npm run dev会直接启动不起来。我实际开发机是Node 16.20算是比较稳妥的版本。装依赖的时候官网推荐用npm install但我个人更建议用pnpm不仅快还能避免一些奇怪的幽灵依赖问题。如果你对包管理不熟就用npm也别有压力这不是核心考核点。第三个坑是数据库字符集。设计表结构之前我先把MySQL的字符集统一成了utf8mb4不然课程介绍里一旦有表情符号存进去直接乱码或者报错。连接串里也要加上characterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai这几个参数少一个都会在后续测试时遇到隐藏的时区或SSL问题。2.3 项目结构一个能扩展的包结构长什么样我见过太多课设把所有类都堆在controller下面UserController、CourseController、HomeworkController、ExamController然后service层空有一层壳逻辑全写在Controller里。这种写法在答辩时被问一句你们Service层写了什么几乎就崩了。我的包结构是按照业务模块划分的这样每个人都有明确的归属而且不同的模块之间不会互相污染config存放JWT拦截器配置、跨域配置、MyBatis-Plus分页插件配置common统一返回结果类Result、异常处理、常量定义controller只做参数接收和逻辑转发不写任何业务service接口 实现业务逻辑的主要存放地mapperMyBatis-Plus的Mapper接口entity数据库表对应的实体类dto接收前端参数的类避免直接用实体类接收防止字段被恶意填充这样的好处是当你想加一个成绩导出功能时你只需要在service里加一个方法然后在controller加一个接口端点其他的不动。这就是把变化隔离在了特定层里比东一块西一块的代码好维护太多了。3. 核心数据库表设计以及成绩、考试这类场景为什么要这么建模3.1 用户权限带来的表设计差异平台要支持三种角色管理员、教师、学生。我建了一张user表存公共字段id、username、password、real_name、role、avatar等然后单独建了student表和teacher表去存扩展信息比如学号、教师职称吗最后我并没有这么做而是直接把角色字段放在user表里另外用一张user_role关系表去维护用户和角色的绑定。为什么因为课设规模下根本没有必要搞复杂的用户扩展信息。如果以后要加专业、班级、学院等字段可以直接在user表上扩展或者再建一张profile表。但有一个点必须单独处理密码不能明文存。我用的是BCrypt加密Spring Security自带的BCryptPasswordEncoder加了盐能够有效抵御彩虹表攻击。注册接口在做的时候我记得特别清楚很多同学会直接把前端传过来的password塞进数据库答辩的时候一旦演示到用户表数据被评委看到明文密码这印象分基本就没了。3.2 课程模块章和节的层级怎么落库课程设计成两级结构课程course→ 章节chapter→ 小节section。course表最核心的字段有title、cover、description、teacher_id、status0未发布/1已发布、category_id。chapter表的字段是course_id、title、sort。section表的字段是chapter_id、title、video_url、duration、sort。为什么要把小节单独拆出来因为一个章节下可能有多个视频、多个文档。如果你只设计到章节那每次新增一个视频都要去alter章节表数据灵活性很差。我当时还把视频的播放时长存了下来虽然看起来不起眼但后面显示课程总时长、学习进度全靠它。这里有一个容易被忽视的隐藏需求教师上传视频后学生网页端怎么播放。主流方案是走M3U8切片播放这也就是热词里有vue播放m3u8的原因。后端如果用MinIO这类对象存储视频上传后可以做转码切片前端用hls.js或者video.js直接加载.m3u8地址就能播放能支持拖动进度。如果只是做课设你可以直接存MP4地址用video标签播放但涉及播放器防盗链或者跨域建议了解一下M3U8 HLS协议的前后端配合方式。3.3 作业模块提交的是文件还是表单作业homework挂在课程下。作业表字段是course_id、title、content要求描述、deadline、teacher_id、status。学生提交作业需要一张homework_submission表homework_id、student_id、submit_content、attach_url、submit_time、status0未批阅/1已批阅、score。这里有个关键的约束一个学生对一个作业只能有一条有效提交记录。所以我在建表时加了唯一索引uk_homework_student(homework_id, student_id)。为了防止学生在截止日期后还能提交我不仅在前端做了倒计时禁用更是在后端保存时做了时间校验超过deadline直接抛出作业已截止异常。前端校验只是体验上的后端校验才是硬保证。文件上传我用的是本地磁盘存储方案配置一个upload目录然后把文件存到resources/static/upload下配合ResourceHandler做静态资源映射。这样前端拿到的就是http://ip:8080/upload/xxx.docx直接可访问。正式环境你可以替换成OSS/MinIO但课设阶段这个方案是最直白、最容易解释的。3.4 考试模块客观题自动判分与试卷-题目关联考试是整个系统的重头戏。核心表有三张考试表exam、题目表question、考试题目关联表exam_question。考试表字段course_id、title、start_time、end_time、duration考试时长分钟、total_score、pass_score、status0未开始/1进行中/2已结束。题目表我设计了题型字段单选、多选、判断、简答。其中单选和判断能做自动判分多选需要与标准答案集合做比较简答留给教师人工批改。题目表字段有type、content、optionsJSON字符串选项内容、answer标准答案客观题用、analysis答案解析、score每题分值、teacher_id。考试题目关联表是比较容易设计错的地方。很多人会直接建一个exam_question表字段是exam_id、question_id然后点对点关联。但在组卷场景里同一道题可能在不同考试中出现这就天然是多对多关系关系表里还必须存score因为同一道题在不同试卷里的分值可能不同。如果忽略了这一点后面随机组卷或者固定组卷时都要返工。学生的答题记录单独建一张exam_record表exam_id、student_id、question_id、student_answer、is_correct、gain_score。考试结束后客观题自动判分简答题进入待批改状态。这里有一个很实用的设计考试中途学生交卷时前端会把每一道题的学生答案逐条保存到后端后端批量插入exam_record最后再根据标准答案统一算分。这种先落答案、后统分的方式比前端算完分再提交给后端更安全因为前端数据可以被篡改。4. 后端核心模块的实现细节从JWT鉴权到考试算分4.1 登录与JWT不要让拦截器变成全校通闸登录接口接收用户名和密码先查user表然后用BCryptPasswordEncoder.matches()校验密码通过后生成JWT返回给前端。JWT的payload里我放的是userId、username、role过期时间设置为24小时。前端拿到token后存储在localStorage里之后每次请求通过Axios拦截器在请求头携带Authorization: Bearer token。后端写了一个JwtInterceptor继承HandlerInterceptor在preHandle里解析token。如果token解析失败或过期返回401。涉及到权限控制的部分我在方法上自定义了RequireRole(TEACHER)之类的注解再用拦截器配合反射去判断当前用户角色是否匹配。为什么不用Spring Security的注解PreAuthorize因为配置复杂对新手不友好而且课设规模下用注解拦截器已经能覆盖所有场景还能让你在答辩时解释得更清楚。4.2 API设计统一返回体与异常处理前后端对接最容易乱的就是返回格式。我定义了一个Result类统一结构是{ code: 200, message: success, data: {...} }。所有Controller的方法都返回Result前端的Axios响应拦截器先判断code是否为200是就取data不是就弹出错误信息。这样前端不需要每个接口都写一遍异常处理逻辑。同时我写了一个GlobalExceptionHandler用RestControllerAdvice注解针对BusinessException自定义、MethodArgumentNotValidException参数校验、Exception兜底分别返回不同的code和message。这样后端不会把500堆栈直接抛给前端面试时被问异常处理怎么做这一套回答就很完整。4.3 在线考试的核心算分逻辑考试模块后端最核心的接口是提交试卷和自动判分。提交试卷的时候前端会传一个数组每一项包含questionId和studentAnswer。后端接收到之后开事务逐条存入exam_record然后根据题型判断单选/判断直接比较student_answer与question.answer等值即正确记录is_correct和gain_score多选将学生答案按逗号分割去重排序后与标准答案的集合比较注意要考虑部分给分还是全对给分我这里是全对才得分简答/填空先存答案is_correct置为nullgain_score为0等到教师批阅时更新交卷成功后我需要更新exam_record里的考试状态提交完成、用时等然后在exam_student表学生考试记录表用来记录某学生某场考试的参与状态、剩余重试次数、最终成绩里落一条总成绩记录。考试过程中如果学生刷新页面前端需要做一个本地草稿箱把已作答的内容存到localStorage并在倒计时结束后自动提交避免学生因为切页面丢失全部答题记录。4.4 大文件上传不只是拖一个input那么简单课程视频、作业附件都涉及文件上传。直接默认Spring MVC的MultipartFile处理没问题但一次上传500MB的视频会面临两个问题请求超时、内存溢出。我实现了分片上传前端把文件按每片5MB切片然后逐片上传后端接收后先存临时目录全部传完后触发合并接口把分片合并成完整文件并返回访问URL。为什么这么做一方面是为了体验断点续传后用户不用重传整个大文件另一方面是为了内存Spring Boot默认单个请求的最大文件大小是1MB多部分请求是10MB你要是不改配置视频根本传不上去。我在application.yml里设置了spring.servlet.multipart.max-file-size: 1024MB和max-request-size: 1024MB同时配合前端分片逻辑整体效果会很稳定。另外合并文件时要按分片顺序合并最好用FileOutputStream循环写而不是用Files.copy把零散分片拼一起时因为顺序错乱导致文件损坏。我在这里踩过一个坑前端并发上传分片后端接收时如果不能保证顺序文件名需要加上序号例如filename_001.part、filename_002.part合并的时候先按序号排序再合并这是基本的工程素养。5. 前端Vue3的实际搭建播放器、路由守卫、状态管理5.1 项目初始化与路由守卫前端我创建了student、teacher、admin三个大目录分别对应三种角色的页面。路由上通过meta.role标记该路由允许哪些角色访问然后在router.beforeEach守卫里做判断。逻辑很简单如果没有token直接跳登录如果token有但角色不匹配跳403页面如果角色匹配放行。这种守卫生效后学生手动输入/teacher开头的路径是进不去的配合后端接口的RequireRole就形成了双保险。我遇到的一个细节问题刷新页面时Pinia里存的用户信息会丢失而路由守卫又要判断角色所以每次刷新后都要重新调用/user/info接口拉取用户信息再放行。这个逻辑不处理好刷新就跳登录页体验非常糟糕。我的解法是在main.js里先调用用户信息接口拿到数据后再app.use(router).mount(#app)确保路由初始化时用户信息已经就绪。5.2 课程与视频播放页面课程列表页是学生登录后看到的首页用卡片布局展示课程封面、标题、教师、进度。点击课程进入详情页左侧是章节/小节树右侧是视频播放器或作业/考试入口。我用的是video.js播放MP4上面提到过如果视频是M3U8切片需要额外引入hls.js。很多同学在部署时会发现本地MP4能播放但打包部署到服务器后播放不了大概率是跨域或MIME类型问题。在Spring Boot的WebMvcConfigurer里设置静态资源映射时要确保.mp4的MIME类型被正确返回浏览器才会走视频流。课程进度记录通过course_progress表实现student_id、section_id、watch_duration、is_completed。每10秒向前端发送一次心跳记录播放位置当播放到视频末尾时标注该小节完成。页面右上角显示课程总进度已完成小节数/总小节数。这部分逻辑不难但能体现出你对实际业务场景的思考深度。5.3 考试页面的倒计时与自动交卷考试页是学生端UI交互最复杂的页面。我设计成顶栏固定显示剩余时间左侧是题目列表带题号状态已答/未答/标记右侧是当前题目的答题区域。核心逻辑是学生每选一道题立即以{ questionId, answer }形式存入Pinia的examStore同时更新localStorage做草稿。倒计时由setInterval每秒触发时间到直接调用交卷接口。这里有一个关键细节防作弊。前端要禁止复制、切屏、右键但也要诚实地说前端防作弊只是辅助真正的检测要靠后端记录学生的切屏次数、进入考试时间、交卷时间教师端可以查看这些元数据。我在考试表里增加了一个字段cheat_count学生在考试过程中如果触发visibilitychange事件前端就向后端上报一次切屏记录教师批阅试卷时就能看到该生切屏3次的提示。5.4 前端路由懒加载与打包优化Vue路由用component: () import(../views/xxx.vue)做按需加载这样首屏不会把所有页面的JS都下载下来。打包时我把echarts用在管理端看数据统计、video.js这些体积较大的库做了CDN外链没有打进vendor包。通过vite-plugin-compression做gzip压缩把包体进一步减小。部署时后端直接用Spring Boot的resources/static目录托管前端打包后的dist文件这样只需要一个Java进程就能同时提供API和前端页面部署成本很低也方便演示。6. 考试防作弊、成绩导出、消息提醒这几个加分项怎么落到代码里6.1 防作弊的一整套组合拳除了上面提到的切屏检测我还在考试开始前增加了人脸识别吗没有课设阶段做不了那么重。我用的是考试前必须阅读并勾选承诺书、考试开始后5分钟内不允许交卷、考试中每30秒从后端获取一次服务器时间这三个方案。最后一点很重要前端倒计时如果只用客户端时间被篡改系统时间就会出问题所以倒计时的基准时间应该以后端返回的服务器时间加deadline为准。我写了一个/exam/currentTime接口前端每次到达某节点就跟服务器时间对齐一次。6.2 成绩导出Excel管理端非常出效果的一个功能是成绩导出。后端引入EasyExcel阿里开源的Excel工具在查询出考试列表后一行一行写入Excel输出为.xlsx文件供前端下载。这里用EasyExcel而不是POI是因为它对大数据的处理性能更好而且API简单。如果你用过POI写Excel你会发现代码量多到怀疑人生。EasyExcel只需要定义一个StudentScoreDTO用ExcelProperty注解标记列名几行代码就能完成导出。这是我在答辩时展示的重点因为面试官非常喜欢问你有没有做过数据导出而EasyExcel是很多真实企业项目里都在用的方案。前端下载文件用axios请求responseType为blob的接口拿到文件流后通过URL.createObjectURL(blob)生成临时下载链接再用a标签模拟点击下载。这里注意文件名要通过响应头Content-Disposition获取前端不能直接在固定文件名写死因为不同日期的导出文件名是不同的。6.3 消息通知与事务一致性我用了WebSocket做站内消息推送教师批改完一份作业后学生端能实时收到你的作业已批改的通知。Spring Boot端配置一个WebSocketConfigurer注册一个/ws/notify端点前端在登录后建立WebSocket连接并把userId作为参数传过去后端用ConcurrentHashMap保存userId对应的Session。当教师批改作业或考试成绩发布时后端调用NotificationService.sendToUser(userId, message)就能定向推送消息。为什么选择WebSocket而不是SSE或者轮询因为在线教育场景里消息不频繁但要求实时性高。SSE适合服务端单向推送WebSocket在双向通信上更灵活虽然课设用不到双向但写起来并不复杂。如果不想上WebSocket用前端定时5秒调一次未读消息数接口也是可以的只是显得不够优雅。事务一致性方面有个常见案例删除课程时需要同时删除该课程下的章节、小节、作业、考试记录、学生选课记录。我用Transactional包裹了一个deleteCourse方法并在Service层按依赖顺序删除子表数据。如果某个删除失败事务回滚课程还在。这个操作看起来简单但容易漏掉的是homework_submission和exam_record这类与课程没有直接外键关联的表要通过子表关联的id级联删除不然就产生孤儿数据。7. 上线部署的关键配置与踩坑记录从Docker到服务器防火墙7.1 Spring Boot打包与部署后端用Maven打包成jarmvn clean package -DskipTests。如果用了外部依赖文件比如上传的图片、视频部署时要确保application.yml里的上传路径和静态资源映射路径存在并且有写权限。我一开始就在/usr/local/edu-platform下单独建了upload目录然后把jar包放这个目录通过nohup java -jar edu-platform.jar app.log 21 启动日志输出到app.log方便排查问题。有些人会问Spring Boot为什么不用外部Tomcat因为内嵌Tomcat已经是默认行为直接把应用打成可执行jar包部署时不需要安装配置独立Tomcat对服务器运维更友好。这个操作如果放在传统Java Web开发里至少要装个Tomcat、配置数据源、部署war包非常麻烦。7.2 Nginx反向代理与前端history路由前端部署有两种方式一是直接把dist目录放到Spring Boot的resources/static里由Java进程托管二是单独用Nginx托管前端并把/api反向代理到后端服务。我推荐第二种因为Nginx的静态资源托管效率更高、更接近线上项目结构。Nginx的配置核心是server { listen 80; server_name your-domain.com; root /usr/share/nginx/html; index index.html; location /api/ { proxy_pass http://127.0.0.1:8080/api/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location / { try_files $uri $uri/ /index.html; } }注意try_files这一行如果没有它Vue Router使用history模式刷新页面时会出现404因为Nginx会去找实际的路径文件找不到就返回404。加上try_files后所有非/api路径都会回退到index.html前端路由接管后的页面刷新就能正常工作。7.3 Docker Compose一键编排我最后把MySQL、Redis如果有用到缓存、后端服务、前端Nginx全部用Docker Compose编排起来。主要体现工程化能力。配置里MySQL容器会挂载一个init.sql首次启动时自动建表并插入管理员账号后端容器通过环境变量传数据库地址和密码前端Nginx配置里写了上游代理地址。用docker-compose up -d一条命令就能把整个平台拉起来这在答辩演示时非常加分。如果你对Docker不熟先用本地跑通再尝试容器化切忌一上来就容器化否则报错都不知道去哪查。8. 我踩过最深的坑从上线就崩到稳定运行的故障复盘8.1 数据库连接池耗尽上线后有一天学生集中登录后端日志开始大量报Connection is not available, request timed out after 30000ms。排查后发现是HikariCP连接池默认最大连接数为10而课程视频详情页、考试答题页面请求非常多连接被瞬间抢完。解决方案是把spring.datasource.hikari.maximum-pool-size从10调到50同时排查慢SQL给经常查询的字段如course_id、student_id、exam_id加索引。这个故障让我意识到很多时候系统崩了并不只是代码逻辑问题而是并发模型没考虑清楚。8.2 前端Token过期后页面卡死当JWT过期时后端返回401但前端Axios拦截器没有统一处理导致每个请求都报401页面一直显示加载中。后来我在响应拦截器里加了401判断清除token并跳转登录页同时通过window.location强制刷新清空内存中的用户状态。所有接口都要走统一拦截不要自己catch异常否则每个页面都得处理一遍。8.3 考试结束时大量请求并发到了整点几百个学生同时交卷后端在一瞬间涌入大量写请求数据库CPU飙升。我用的是先接收答卷内容写临时表然后异步判分的方式交卷接口只负责把exam_record批量插入数据库判分逻辑放到Async线程池里执行。这样交卷操作从几百毫秒降到了几十毫秒判分结果通过WebSocket异步返回给学生端。这个设计在答辩时也值得展开讲它涉及异步处理和削峰填谷的思想比单纯用事务包着所有的操作要高明不少。9. 项目复盘一个在线教育系统设计里最容易被追问的五个问题9.1 你的权限控制是怎么实现的前端有Vue Router守卫后端有JwtInterceptor 自定义角色注解。答案要分两层前端只是页面级控制后端接口才是真正的安全边界。我会现场演示用学生账号手动访问教师接口返回403前端路由跳转403页面。这个问题面试官基本必问一定要把两层机制说清楚尤其强调后端校验才是安全的关键。9.2 如果同一门课同时有1000人在线看视频你的后端会崩吗这题不是考题但它考察你是否理解静态资源与动态资源的分离。视频文件本身不应该走Java应用而是走对象存储OSS/MinIO加CDN。Java后端只负责返回视频地址和进度记录接口。在课设级别的部署里Nginx已经能对视频做静态缓存和限流是性价比最高的方案。9.3 一节课的作业提交后老师批改时是怎么看到哪些学生没交的这道题考的是左连接查询。用homework表左连接homework_submission表通过submission.id IS NULL来筛选哪些学生未交。表设计时必须要有一个学生选课表student_course做中间关系否则无法判断一门课有哪些学生应该提交作业。如果当初没做选课功能这题就比较难答。9.4 考试试卷和成绩能不能被恶意篡改这是我在答辩时被问到的最尖锐的问题。我的回答是从数据库上考试成绩的计算完全由后端完成前端只传questionId和studentAnswer不传最终分数从传输上JWT有效期和HTTPS保证请求不被篡改从逻辑上改数据库需要数据库账号权限这属于安全运维范畴。理论上任何一个系统都无法完全抵御有数据库权限的攻击者但至少我做到了应用层不可篡改。9.5 为什么用MyBatis-Plus而不是JPA我的答案很简单MyBatis-Plus上手门槛低CRUD开箱即用复杂SQL可以自己写XMLJPA面向对象思想强但Hibernate的N1问题和懒加载坑在课设背景下调试成本太高。MyBatis-Plus在中文社区非常流行出现问题搜索方案也快。对实际开发来说国内互联网公司用到MyBatis系的比例远高于JPA这个选型在就业方向上也更贴近市场需求。10. 最后给你一份可执行的开发顺序清单从零开始做这个项目建议按下面的顺序推进而不是想到哪写到哪先花两天把权限系统做出来用户表、注册登录、JWT拦截、Vue路由守卫。这是所有功能的地基不做完它后面都别想。再做课程模块课程表、章节表、小节表配上教师端的课程管理和学生端的课程列表、课程详情、视频播放。做完你就已经拥有一个视频课程网站了。然后加作业模块作业表、提交表、教师批量查看提交列表、学生提交和截止时间校验。这个阶段你会接触到文件上传和批量查询。接着是考试模块题目表、试卷关联表、在线答题页、自动判分、考试成绩列表。这是最有挑战也最容易出彩的部分多留一周时间在这里。最后补管理端课程分类、用户管理、数据统计把整个平台串起来后再统一调试部署。你在每一阶段完成时都做一次测试记录把核心接口的请求数据和返回结果保存下来。这些记录就是你毕业论文里的测试截图和效果展示素材也是答辩时能讲清楚我做了什么的重要依据。整个项目做完不要急着发布先找两个同学分别模拟老师和学生走一遍教师发布课程→布置作业→创建考试→学生选课→提交作业→参加考试→教师批改→学生查看成绩的完整链路走完一遍你会发现很多细节需要修改比如时间格式、状态命名、按钮权限这些细节直接决定你的系统是能用还是好用。