ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于SpringBoot+Vue的导师双选系统:毕业设计完整实战指南

基于SpringBoot+Vue的导师双选系统:毕业设计完整实战指南 距离我在毕设选题系统里看到基于SpringBootVue的毕业生导师双选系统这个题目已经过去一年多了。说实话当时第一反应是这不就是又一个增删改查吗但真正准备开题、设计数据库、写代码、排着队调试、最后站上答辩台之后我的看法完全变了。这个题目看起来普通但它恰好踩中了毕业设计考察的全部核心点多角色权限管理、带状态流转的业务流程、前后端分离协作、资源分配规则的设计甚至连匹配算法都能延伸出不少可以写进论文里的讨论。这篇文章就从一个做完过的人的角度把这个系统从选题逻辑、数据库设计、前后端实现一直到答辩准备的完整链路拆开讲一遍目标是让正在做类似毕设的同学少走弯路别把时间浪费在低级坑上。这个题目适合谁三个字大多数人。如果你没有特别强的算法背景但想认认真真做一个完整的Web系统又希望论文有话可写、答辩有东西可讲导师双选系统是一个很合适的选择。前端不太熟没关系Vue的生态环境足以让你用最少的代码撑起一个完整的管理端后端不熟也没关系Spring Boot把配置基本都收拢了你需要专注的是业务本身。1. 毕业设计选题的底层逻辑为什么普通题目反而是最佳选择1.1 毕设论文真正考查的是哪些能力很多同学选题时有个误区觉得题目越炫酷分数越高。实际上本科答辩现场老师看的是你是否完整走了一遍软件工程的流程而不是你的技术栈有多新。你用了Redis、Kafka、Docker如果说不清为什么用、解决了什么问题在老师眼里反而不如一个把业务逻辑理得清清楚楚的系统。一个导师双选系统的题目天然覆盖了四个论文必备部分需求分析三种角色的诉求差异、系统设计数据库表结构、模块划分、系统实现后端接口开发、前端页面开发、系统测试测试用例设计、流程验证。也就是说你不需要额外找角度去凑字数整个业务就在那里只要老老实实把每个环节做扎实论文的每一章都有现成的素材可用。我见过一些同学选了个基于深度学习的某某预测系统结果光环境配置就花了两周模型训练结果还一塌糊涂最后论文全靠套话撑场面答辩被问几句就露馅了。相比之下双选系统这种基本功导向的题目翻车概率小得多。1.2 双选系统的业务闭环绝对不是一个简单CRUD我得先说一个大多数没做过的人容易忽略的点。导师双选系统的核心不在于增删改查而在于双向二字。普通的学生管理系统是单向数据流管理员录入学生信息学生只能被动地被管理业务链路短状态变化少。双选系统完全不一样学生可以填写志愿选择导师导师可以接收或拒绝学生管理员需要对整个流程进行宏观控制。这里涉及三个角色、两个核心阶段、一条贯穿始终的流程线学生查看导师列表与剩余名额填报志愿查询双选结果导师维护个人简介与招生名额查看填报自己志愿的学生列表选择确认或拒绝管理员管理师生账号、设置开放时间、监控双选进度对异常情况人工干预。这三个角色的操作不是互相独立的而是层层关联的。学生填的志愿会实时影响导师端可见的学生列表导师的确认操作会直接影响学生端看到的最终结果管理员还要能中途介入。这种一个动作引发另一端状态变化的交互模式是纯CRUD题目给不了你的。你在论文里可以说清楚状态如何流转、数据如何保持一致这就是加分项。我自己在写论文的时候把这条流程梳理成一张状态流转图放在系统设计章节里老师翻到那一页就停留了好一会儿说明这种业务分析深度比堆功能列表有价值得多。1.3 和其他热门毕业设计题目对比后的结论我把当时几个常见题目的情况做了一张表你们感受一下题目类型业务复杂度权限体系可扩展空间答辩亮点图书馆管理系统低很弱基本是管理员单角色小做完就是做完功能堆砌无亮点电商购物系统较高中用户/管理员一般但业务链路长支付流程有故事学生选课系统中中学生/教师/管理员一般单选为主选课调度逻辑导师双选系统中等强三角色互相关联大可加算法和消息通知双向选择与匹配规则对比完之后你会发现图书馆管理系统太单薄答辩时论文全是表格截图没什么可讲的技术点电商和选课系统虽然业务链条长但本质上和双选系统一样绕不开增删改查只是故事换了个壳。而导师双选系统有一个其他系统很难替代的优点双向性。单向系统的核心逻辑是谁操作谁双向系统的核心逻辑是怎么匹配后者在论文里可以单独写一小节匹配策略设计光这一小节就够你讲出技术含量。2. 技术选型Spring Boot Vue到底赢在哪儿2.1 后端为什么选Spring Boot而不是SSM现在很多Java课程还在教SSMSpring Spring MVC MyBatis但如果你去看招聘网站和开源项目Spring Boot已经是绝对主流。原因很简单SSM需要大量的XML配置把一个环境跑起来可能要折腾小半天而Spring Boot的自动配置机制把这些工作全部接管了。你可以把Spring Boot理解为已经把厨房装修好的房子SSM则是毛坯房一切请自己动手。从原理上说Spring Boot通过SpringBootApplication注解和spring-boot-autoconfigure依赖在启动时根据classpath中的jar包自动推断并创建对应的Bean。比如你的pom.xml里引入了spring-boot-starter-web内嵌的Tomcat就会自动启动传统的web.xml配置完全不需要了。这个机制说白了就是一套约定优于配置的思路——框架替你做好了默认选择你只需要在application.yml里覆盖个别自定义项。对于毕业设计来说这意味着你少踩十几个配置坑可以把时间用在业务逻辑上。另外内嵌Tomcat这一点也非常重要。以前用SSM你需要单独下载Tomcat、部署war包、出问题还要查日志。Spring Boot内置Tomcat之后一个mvn spring-boot:run直接就能跑起来打包成jar也能直接java -jar运行。答辩现场如果老师让演示你只需要双击一个命令不用再当着老师的面前后折腾环境。2.2 Vue的选择版本怎么定组件库要不要Vue现在面临一个选择Vue2还是Vue3。如果你现在才开始做我建议直接用Vue3原因不是它的Composition API多么高级而是生态已经成熟了。Vue3有script setup语法糖写起来比Vue2的Options API直观很多组件内逻辑归拢得更清晰。唯一要注意的是你的Node版本不能太低环境配置时我实测过Vite需要Node 14.18以上推荐直接用16或18的稳定版省得在启动阶段就卡住。组件库方面Element Plus和Vue3是黄金搭配。你可能在网上看到很多教程还在用Element UI那是Vue2时代的产物如果你项目是Vue3强行兼容会非常痛苦。有一个细节要提醒在npm安装Element Plus时最好把版本锁住例如npm install element-plus2.x。我自己曾经因为直接装了最新版结果和Vue3的某个小版本出现样式编译冲突排查了一上午最后发现是依赖版本不匹配把版本固定之后问题立刻消失。这套组合做管理后台页面效率极高表格、表单、弹窗、消息提示全是现成组件你要写的只是业务逻辑和样式微调。2.3 环境配置阶段的三个大坑从最高频搜索的几个问题来看很多人在起步阶段就翻车了。这里我集中讲三个我实测遇到过的第一个坑Maven构建太慢。国内网络环境下载依赖很慢解决方案是在settings.xml里配置阿里云中央仓库镜像。路径一般在Maven安装目录的conf目录下或者你的用户目录下的.m2文件夹里。在mirrors节点中加入mirror配置把central镜像指向https://maven.aliyun.com/repository/public。改完之后再去IDEA里刷新一下Maven工程依赖下载速度会有质的提升。第二个坑Vue安装依赖失败。如果你用npm装包装一半报错优先考虑切换镜像源npm config set registry https://registry.npmmirror.com。然后删掉node_modules目录和package-lock.json重新npm install。不要硬着头皮继续依赖装不干净后面全是连锁报错比如启动时提示Cannot find module根本找不出真正原因。第三个坑端口冲突。Spring Boot默认8080端口经常被其他程序占用启动时会报Port already in use。在application.yml里把端口改掉就好server.port: 8081。前端Vite默认端口是5173但如果你启动时遇到5173被占用Vite会自动换端口你反而要注意后端接口地址和代理配置是不是还指向原来的端口。提示如果你用Vite代理解决跨域一旦端口变化vite.config.js里的server.proxy配置也要同步改否则接口全部404。最简单的方法是在vite.config.js中显式锁定server.port不给它自动换端口的机会。3. 数据库设计一张好的ER图决定整个项目的天花板3.1 核心表结构五个表就能撑起整个业务数据库是整个系统的地基。我见过太多人一开始就急着写代码写到大半发现数据表少了字段、字段类型不对回头改牵一发动全身。正确的顺序是先设计好表再动手写代码。对于导师双选系统这里给出一套可以直接照着用的最小表结构用户表t_user主键、用户名、密码、角色类型student/teacher/admin、真实姓名、邮箱、手机号。这张表只负责登录认证和身份标识。学生表t_student用户ID、学号、专业、年级、平均绩点、个人简介、意向研究方向。这张表存学生维度的扩展信息和用户表是一对一关系。导师表t_teacher用户ID、工号、职称、所属院系、研究方向、招生名额、已选人数、个人主页简介。这张表同样和用户表一对一。志愿表t_wish主键、学生ID、导师ID、志愿序号、填报时间、状态待确认/已接受/已拒绝/已失效。这张表是双选过程的核心。双选结果表t_selection_result主键、学生ID、导师ID、确认时间、操作人。这张表存最终的绑定关系。很多同学会问为什么还要单独建一个结果表志愿表里的已接受状态不就代表结果吗这么问的人还没有理解状态设计的意义。志愿表存的是过程结果表存的是结论。比如一个学生第一志愿没被选中第二志愿被导师接受在最终结果出来之前他的志愿表里可能同时有一条已拒绝和一条已接受记录。如果没有独立的最终结果表统计每个导师的实时已选人数时就要扫一遍志愿表把所有已接受状态算出来逻辑绕弯子效率也低。过程和结论分离这是数据库设计里一个很重要的习惯论文里也可以用一句话点出来。3.2 四个容易被忽略的字段设计问题先说容量字段。导师表里招生名额和已选人数这两个字段我建议都保留。虽然表面上看已选人数 名额 - 剩余名额可以推算出来但实际业务中管理员可能会手动干预例如临时给某个导师加名额这时候已选人数作为冗余字段可以直接参与容量校验避免每次都要现算。再看学生表的平均绩点。有人会问导师选学生要看成绩直接按需查询数据库再排序不行吗问题是成绩这个字段可能来自多个数据源手动录入的成绩单和教务系统同步的成绩格式不一致有必要在表里存一个标准化字段方便做优先级排序。这也是后面匹配规则能落地的数据前提。第三是时间字段。双选系统有时段限制例如志愿填报阶段3月1日到3月15日导师确认阶段3月16日到3月25日。我建议在系统参数表里存这两个时间区间而不是硬编码在代码里。因为答辩时老师们最常问的一个问题就是如果学院调整了双选时间怎么办——你把时间做成可配置参数回答这个问题就非常从容前端展示和接口校验都从参数表读取一行配置代码都不用改。第四是逻辑删除字段。现在很多公司级的项目规范里都会有deleted字段用来做软删除。毕设里不一定强制要求但如果你做管理员删除导师这个功能硬删除会导致历史志愿记录失去外键关联统计报表对不上。加一个deleted字段查询时统一过滤逻辑简单很多。3.3 状态字段怎么设计才能撑起双选流程双选流程中一个志愿最少有四种状态待确认、已接受、已拒绝、已失效。有些同学图省事用一个is_accept布尔字段0和1一存完事。但你仔细想初始状态怎么办导师还没确认你也存0导师拒绝了你还是0那么还没看和拒绝了就彻底混在一起了。整个流程就乱套了后续统计、展示、权限控制全都会出错。正确的做法是使用状态枚举在Java里用Integer字段存储搭配枚举类说明含义。例如public enum WishStatus { PENDING(0, 待确认), ACCEPTED(1, 已接受), REJECTED(2, 已拒绝), INVALID(3, 已失效); }用数字存储、用枚举语义化既方便数据库存储又能让代码可读。更重要的如果你后续想加学生撤销状态只需要在枚举里加一个值流程逻辑可以平滑扩展。这也是答辩时一个可讲的点你的系统不是一套写死的流程而是具备可扩展性的状态机设计。还有一个设计细节当导师确认了一个学生系统应该自动把该学生的其他志愿全部置为已失效。这一步不能靠前端控制必须由后端在同一个事务里处理否则会出现同一个学生同时拥有两个已接受志愿的脏数据。4. 后端核心实现从接口规划到事务与权限落地4.1 项目分层与统一返回结构Spring Boot项目的经典结构是controller-service-mapper三层。你要是翻过一些开源项目会发现好的项目结构几乎都有固定范式。我的建议是controller接收请求参数校验返回结果不做业务逻辑service业务逻辑事务管理流程控制mapper数据库操作一个接口对应一条SQLentity实体类与数据库表一一对应dto数据传输对象用于接收前端传参vo视图对象用于返回给前端的数据结构。分层的好处在于答辩时老师翻开你的代码即使他不上机运行也能通过代码结构判断你的工程化素养。如果一堆SQL写在Controller里整个类几百行看起来就像一个大泥球会被直接扣印象分。统一返回结构也是必须做的。我见过不少项目每个接口返回类型都不一样有的返回Map有的直接返回实体类前端联调时痛苦不堪。统一的做法是定一个ResultT类包含code、message、data三个字段所有接口统一返回这个结构。前端axios响应拦截器里统一判断code整个系统的错误处理规则就只有一套。Data public class ResultT { private Integer code; private String message; private T data; public static T ResultT success(T data) { ResultT result new Result(); result.setCode(200); result.setMessage(success); result.setData(data); return result; } public static T ResultT error(String message) { ResultT result new Result(); result.setCode(500); result.setMessage(message); return result; } }4.2 登录认证与角色权限JWT加拦截器是毕设最稳的方案很多教程会推荐Spring Security或Shiro但对于一个毕业设计来说整这两套框架的成本不小配置类多、概念复杂学明白需要好几天而且一旦配错排查起来非常痛苦。我以实际经历告诉你用JWT加HandlerInterceptor的方案足以支撑这个系统的全部权限需求而且实现起来清晰直接论文里也好解释。思路是这样的用户登录成功后后端生成一个JWT令牌返回给前端前端每次请求时在请求头Authorization中带上这个令牌。后端写一个拦截器拦截所有/api/**的请求校验令牌有效性并把用户ID和角色从令牌中取出来放到ThreadLocal里后续业务逻辑随时取用。JWT的好处是服务端不用存session天然适合前后端分离的场景。但有几个坑要注意JWT签发时要设置过期时间一般建议2小时到1天。答辩演示时如果老师隔了很久再操作令牌过期会导致接口返回401你要在代码里处理这种登录过期的提示并引导重新登录。不要在JWT里放密码等敏感信息。JWT的payload只是Base64编码不是加密任何人拿到都能解码看内容。拦截器只负责身份认证角色判断可以放在拦截器里根据请求路径前缀来做例如/api/student/**只允许学生角色访问。简单做法是硬编码路径但对毕设够用了。4.3 双选核心接口的逻辑实现学生填报与导师确认把所有接口列出来会有几十个但核心只有几个。我挑最关键的两个讲透。接口一学生填报志愿这个接口的逻辑表面上看是插入一条志愿记录但实际边界条件很多。我当初的实现顺序是public ResultString addWish(WishDTO wishDTO) { // 1. 校验当前时间是否处于志愿填报阶段 // 2. 校验学生是否已有被确认的双选结果已被确定不能再填 // 3. 校验志愿数量是否超过系统允许的最大志愿数例如3个 // 4. 校验目标导师是否存在且名额未满 // 5. 校验同一导师不能重复填报 // 6. 插入志愿记录 }这每一步都对应一个业务规则的验证。你会发现一个看起来简单的接口因为业务规则多代码量自然就上来了。答辩的时候老师很可能就问如果学生填了三个志愿第一个导师已经满了后来管理员给第一个导师加了名额学生需不需要重新填这个问题没有标准答案但你的系统必须有一套明确的处理规则并且能在论文里写清楚。我当时的处理是只检查填报时的容量不回溯历史志愿如果管理员加了名额学生需要自己再进入系统把导师加为志愿系统不做自动补录。接口二导师确认学生导师确认时涉及一个并发问题。如果两个导师同时确认同一个学生呢现实中不会发生因为一个学生最终只能绑定一个导师但代码层面很可能因为前端页面没做好限制而出现。解决的办法是给志愿表加一个联合唯一索引比如(student_id, teacher_id)在数据库层面保证一个学生对一个导师只能有一条志愿记录。更彻底的做法在双选结果表上也给student_id加唯一索引保证一个学生只能有一条最终结果。这里还有一个容易忽略的点导师确认学生时要在同一个事务里完成三件事——把该志愿状态改成已接受、把该学生的其他志愿全部改成已失效、给导师表的已选人数加一。如果这三步没有事务包裹中途任何一个报错都会造成数据不一致。用Transactional注解包住就对了。Transactional public ResultString confirmStudent(Integer wishId) { // 1. 更新当前志愿状态为ACCEPTED // 2. 将该学生其他志愿设置为INVALID // 3. 导师表已选人数 1 }5. 前端Vue实现页面组织、路由守卫与前后端联调5.1 页面视图与组件划分一个页面只做一件事前端部分我用Vue3 Vite Element Plus Pinia这套组合前端代码结构大致如下views/Login.vue统一登录入口登录后根据角色跳转到不同首页views/student/学生端页面导师列表、志愿填报、双选结果views/teacher/导师端页面个人主页维护、志愿学生列表、确认操作views/admin/管理员端页面用户管理、导师管理、时间设置、双选监控router/index.js路由配置store/Pinia状态管理存放当前登录用户信息。组件划分时有一个原则一个页面只做一件事。比如导师列表页面不要自己写导师信息展示卡片而应该拆出一个TeacherCard.vue组件负责展示单个导师的姓名、研究方向、名额信息和填报志愿按钮。页面只负责数据获取和组件的拼装。这样代码复用性好结构也容易读。答辩时老师问你如何组织前端代码你拿这套组件化思路回答比说都写在App.vue里好一百倍。5.2 路由守卫和角色权限别让用户自己敲URL就进管理页前端权限控制是很多人容易忽略的。很多新手做完登录功能发现只要在浏览器地址栏输入/admin就能直接进管理员页面就是因为没做路由守卫。Vue Router提供了beforeEach全局前置守卫可以实现基于角色的访问控制。基本思路是在路由的meta字段里声明roles守卫里判断当前用户角色是否在允许列表里router.beforeEach((to, from, next) { const userStore useUserStore(); if (to.path /login) { next(); return; } // 未登录统一跳回登录页 if (!userStore.isLoggedIn) { next(/login); return; } // 角色不匹配跳转到无权限提示页 if (to.meta.roles !to.meta.roles.includes(userStore.role)) { next(/403); return; } next(); });这一套写下来有一个细节要放在心上用户刷新页面时Pinia里的用户信息会丢失需要从localStorage里重新读取用户信息。最好在store初始化时就读取本地缓存否则刷新一下就被弹回登录页整个系统的体验会很糟糕。5.3 前后端联调的常见问题与排查思路联调阶段最经典的问题就是跨域。前端页面在localhost:5173后端在localhost:8081浏览器会因为同源策略拦截后端响应。解决办法有两种我建议优先使用前端代理方案。在vite.config.js里设置server.proxy把/api前缀的请求转发到后端地址export default defineConfig({ server: { port: 5173, proxy: { /api: { target: http://localhost:8081, changeOrigin: true } } } })这样前端代码里请求路径统一写/api/xxx不需要处理跨域头。另一个方案是在后端加CORS配置类把跨域策略放开。我实测下来代理方案更干净而且将来如果要部署到同一台服务器把前端打包后的dist目录放进Spring Boot的静态资源目录一个jar就能跑不会有跨域问题。联调时如果接口返回数据不对先看浏览器Network面板确认请求有没有发出去、状态码是多少、响应体长什么样不要一上来就打断点。后端排查时也优先看控制台日志Spring Boot会打印每条SQL语句对照一下就能快速定位是SQL写错了还是参数传错了。这种先看网络请求、再看后端日志的排查顺序能帮你解决90%的联调问题。6. 双选匹配的逻辑设计从第一志愿到容量均衡的取舍6.1 双选规则的本质是带容量的双边匹配如果说前面那些是工程基本功那么匹配规则就是导师双选系统的灵魂。很多同学做这个题目双选规则就一句话学生填志愿导师选学生选中的就绑定然后就完了。论文这部分一两页纸就凑完了答辩时老师问如果多个学生填了同一个导师而导师只能选两个你怎么处理你就只能支支吾吾。双选规则本质上是带容量限制的双边匹配问题。学生有志愿排序导师有名额限制还有一个共同的时间线。最简单的实现方式是志愿优先、导师确认规则系统按志愿序号从1到N逐轮处理每轮把第一志愿相同的学生按某个优先级排序比如按绩点排名导师按名额依次确认被确认的学生在后续轮次中不再参与。这个方法实现简单但有一个明显的缺陷如果一个高分学生第一志愿落空他在第二轮以第二志愿参与竞争时可能竞争不过一个把他放第一志愿但分数更低的学生。这在现实中其实是合理的——导师更倾向录取把他作为第一志愿的学生因为这说明学生有诚意。但这个合理要用一套明确规则去表达而不是靠模糊的人情。另一种思路是让导师给学生排序学生给导师排序然后用Gale-Shapley算法延迟接受算法做匹配。这个算法的好处是结果稳定匹配完成后不存在一个学生和一个导师互相更喜欢对方但没匹配上的情况。代价是代码实现比简单轮询复杂对本科生来说理解证明过程也需要时间。如果要选这条路论文里可以写的内容会很丰富但风险是代码调试时间会拉长。6.2 我最终采用的简化匹配策略考虑到代码量和论文篇幅的平衡我建议采用这种简化策略也算是我自己实盘验证过的方案志愿填报阶段结束后系统进入导师确认阶段导师端展示第一志愿填报自己的学生列表按绩点和填报时间综合排序导师从列表中勾选学生并确认当已确认人数达到招生名额时剩余学生自动落空系统提示名额已满落空的学生在补选阶段可以查看还有名额的导师重新填报一个志愿进入下一轮导师确认。这个策略没有算法全自动匹配那么炫酷但更贴近实际教务场景而且给管理员预留了人工干预空间。论文里可以这样写本系统的匹配规则结合了学生志愿优先和导师自主决策两种思想第一阶段以学生志愿为核心组织候选列表最终决策权在导师手中管理员在边缘状态下兜底。这么写既诚实又清楚不会出现程序自动匹配结果让师生都看不懂的情况。6.3 边界情况的处理清单答辩考官最爱问的角落不管选哪种匹配策略下面这些边界情况都要处理好答辩大概率会被问到导师名额为零前端直接把填报志愿按钮置灰或提示暂无剩余名额后端接口也要二次校验学生撤销志愿撤销后释放名额该学生剩下的志愿序号重新排列双选时间截止后端接口需要统一校验当前时间前端在阶段结束后隐藏填报入口并提示本阶段已结束管理员干预管理员可以把一个学生的导师手动改掉但需要保留操作日志论文里可以说这是审计需求并发重复确认同一个学生被两个导师同时确认靠数据库唯一索引兜底防止脏数据。这些边界情况的处理不需要很高深的代码但必须在设计文档里体现出来。每一次边界情况的处理在答辩老师眼里都是这人是真的考虑过实际业务的证据比任何花哨框架都加分。7. 文档写作与答辩准备代码写完了不代表项目结束7.1 论文结构怎么组织从系统设计到核心代码展示这里分享一个很多同学都会忽略的细节论文里的系统设计部分老师最反感看到直接贴一大段代码。你要做的是先画用例图、ER图、系统架构图把整个系统的结构关系说清楚再针对每个模块展开设计思路最后挑最核心的接口给出关键代码并加以解释。核心接口不需要全部贴贴出三五个最核心的就行比如学生填报志愿、导师确认学生、管理员导入导师信息配合每个接口的事务处理和状态流转来说明清楚。论文目录可以这样安排第一章引言背景和意义、第二章相关技术Spring Boot、Vue、MySQL的简介注意要写出为什么选它而不是抄百度百科、第三章需求分析用例图、功能需求、非功能需求、第四章系统设计架构设计、数据库设计、模块设计、第五章系统实现每个模块的界面截图加核心代码、第六章系统测试测试用例表、测试结果、第七章总结。这个结构是一个稳妥的骨架基本不会出错。7.2 系统演示环节要提前做的四件事毕设答辩通常有一个演示环节演示翻车比论文翻车还尴尬。我总结几个必须提前检查的点本地数据库要先启动并导入最新数据现场启动项目只点一次运行绝不要现场安装依赖或改配置提前准备演示数据比如10个学生、5个导师、若干志愿记录让页面打开时就是有内容的状态而不是空表空页面预设一条完整的双选流程脚本学生登录填报志愿、切换导师账号确认、再切学生账号查看结果。按剧本走不要现场临场发挥很容易点错或忘记某一步如果现场没网络优先使用本地运行方式不要依赖在线地图、短信服务或其他第三方接口。我记得答辩那天有个同学演示购物系统结果现场网络不好支付宝沙箱环境进不去整个演示卡在支付环节场面非常尴尬。这种事只要提前做一遍离线预演完全可以避免。7.3 几个大概率被问到的答辩问题与回答思路最后列几个我答辩时实际遇到的以及和身边同学交流后整理出的高频问题你的系统用什么方法保证一个学生不会同时被两个导师选中——答双选结果表对student_id建唯一索引数据库层面兜底同时后端在导师确认的事务里会先检查该学生是否已有结果记录。导师已经满了学生还能不能填报——答填报时校验导师剩余名额剩余为0则不允许提交同时前端在导师卡片上显示已满员标签并禁用按钮。如果一个学生没被任何导师选中怎么办——答双选结束后管理员在后台查看未匹配学生清单手动为其调配还有名额的导师或进入补选阶段重新开放该学生的志愿填报。你的登录密码存的是明文吗——答不是使用了BCrypt加密存储即使数据库泄露密码也无法反推。匹配算法为什么选择这种简化方案——答考虑到实际教务场景中导师与学生的评价是多维度的完全自动匹配并不能保证公平性采用志愿优先导师自主决策管理员兜底更符合现实。我当时在答辩时最深刻的一个体会是只要系统每一步操作都有日志可查、状态有数字编码、异常有兜底处理老师问什么问题你都不会慌。另外分享一个小技巧答辩前把你系统的核心流程图画在一张A4纸上带进去老师问的时候你一边讲一边看着流程走一遍会比干讲顺畅很多。最后提醒一句如果你的时间预算只有一个月优先把主线流程做通、把接口做稳、把演示数据备整齐至于那些锦上添花的通知推送、统计分析功能有时间再上没时间就先砍掉主线扎实了整个项目就立住了。
返回列表