很多来找我咨询毕设题目的同学第一句话往往是“学长学生宿舍管理系统这种题是不是太简单了老师会不会觉得没技术含量”说实话这种想法恰恰是误区。宿舍管理系统确实属于经典的Web管理类项目但正因为所有评审老师都见过、都审过这类题目它反而最能拉开差距业务建模是否闭环、权限设计是否严密、分配逻辑能否真正处理并发冲突、数据统计是否经得起追问这些细节决定了你拿到的是“及格毕设”还是“优秀毕设”。这篇内容我会围绕一个JavaSpringBoot架构的高校宿舍智能管理平台Web项目展开从业务建模、技术选型、数据库设计、核心功能实现一路写到踩坑记录和答辩准备。文章面向的是正在做毕业设计、或者刚学完Java Web想拿一个完整项目练手的同学内容会尽量贴近真实开发思路而不是教科书式的步骤罗列。如果你正在纠结这类系统“到底怎么做才能不落俗套”这篇文章应该能帮你省下不少时间。1. 宿舍管理系统的业务边界角色、流程与功能清单很多同学拿到题目第一件事就是打开IDE开始建表写代码这是最要命的做法。宿舍管理系统看似简单但如果你没想清楚“谁在用、用哪些功能、流程怎么走”写着写着就会发现表结构要返工、接口要推翻重来。我见过太多人做到宿舍分配那一步卡住就是因为当初没把业务边界画清楚。1.1 三类角色与权限矩阵高校宿舍管理平台至少要拆出三类角色不要合并也不要再多。合并会导致权限失控再多就会把毕设拖入无底洞。角色核心诉求典型操作系统管理员管理全局基础数据楼栋维护、宿舍信息维护、账号管理、数据统计宿管员负责本楼栋日常运营入住审核、退宿办理、查寝登记、报修处理、水电抄表学生使用宿舍服务入住申请、调宿申请、报修提交、公告查看、个人信息维护我建议在项目里把这三种角色做成独立的实体用角色字段区分而不是给用户表加一个“type”就草草了事。角色背后对应的是菜单权限和接口权限这一块做到了答辩时你就有东西可以讲。1.2 核心业务流程闭环一个完整的宿舍管理平台至少要覆盖“入住—住宿—退宿”的全生命周期加上围绕住宿产生的服务流。入住流程学生提交入住申请 → 宿管员审核 → 系统分配床位 → 生成入住记录调宿流程学生提交调宿申请 → 宿管员审核 → 释放原床位 → 分配新床位 → 更新入住记录报修流程学生提交报修单 → 宿管员接单 → 维修完成 → 学生确认评价查寝流程宿管员按楼栋发起查寝 → 登记在寝/离寝状态 → 生成查寝记录 → 异常信息可通知辅导员退宿流程学生申请退宿 → 宿管员确认 → 释放床位 → 归档历史入住数据这里有一个很容易忽略的点入住记录不能简单地在学生表上存一个“宿舍ID”字段就完事。正确的做法是建立独立的入住记录表保留时间维度。这样退宿之后历史数据还在调宿的轨迹也能追踪统计“当前住宿人数”和“历史入住人数”时才不会乱。我见过好多项目在这个细节上栽跟头答辩时被老师一问就卡壳。1.3 功能清单的减法与加法毕设项目最忌讳一上来就铺一大堆功能最后哪个都没做透。我的建议是核心功能做深加分功能做亮。核心功能必须做到位学生管理基本信息维护、院系班级维护宿舍管理楼栋、楼层、房间、床位四层结构入住与退宿申请、审核、分配、释放报修管理提交、派单、完成、评价查寝管理发起、登记、统计公告管理发布、查看加分功能用最少的成本换最好的印象宿舍可视化统计按楼栋、性别、入住率展示图表水电费管理每月录入用量生成费用记录Excel导出学生名单、入住报表、查寝异常名单一键导出报修单PDF打印方便线下归档加分项不需要多做两到三个就够。重点是让老师看到你不只是会写CRUD而是有“用户体验”和“落地场景”意识。2. 技术选型复盘JavaSpringBoot组合的取舍逻辑技术选型是答辩时老师必问的问题。你要能说清楚“为什么选它”而不只是“我只会这个”。这里我把我的选型思路完整复盘一遍你照着这个逻辑去准备基本不会再被问住。2.1 为什么是SpringBoot而不是SSM或SpringCloud很多学校的课程还在讲SSMSpringSpringMVCMyBatis但如果你做毕设还写一堆XML配置纯粹是给自己找不痛快。SpringBoot的核心价值是“约定优于配置”内嵌Tomcat容器一个mvn spring-boot:run就能把服务跑起来。从答辩角度讲SpringBoot有一个巨大的优势它能让你把精力花在业务逻辑上而不是纠结applicationContext.xml里那个bean到底注没注入成功。一旦SSM项目启动报错排查成本非常高而SpringBoot的自动配置和错误提示已经帮你挡掉了大部分低级问题。那为什么不用SpringCloud微服务答案很直接宿舍管理系统是典型的单体应用业务量级远没有到需要拆服务的程度。硬上微服务会引入注册中心、网关、配置中心、分布式事务这些复杂概念以毕设的开发周期和你的精力来看完全得不偿失。答辩时老师问“为什么不用微服务”你就说单体架构在这个业务规模下具备最高的开发效率和运维成本优势微服务的拆分是业务复杂度驱动的结果不应为了技术而技术。这句话一出口档次就不一样了。2.2 前端方案的权衡模板引擎还是前后端分离这个选择决定了你项目的整体长相。我的经验是如果团队里没人真正写过Vue老老实实用Thymeleaf模板引擎加上Bootstrap或者小体积的AdminLTE后台模板三天就能把管理后台界面搭得像模像样。如果你已经能熟练使用Vue3ViteElement Plus那前后端分离是更好的选择。它的优势在于动态菜单权限更好做、组件复用度高、答辩演示时页面响应更快。但代价是你要额外处理跨域、Token存储、打包部署这些问题。我个人建议除非你对前端已经比较熟悉否则不要轻易为了“技术潮流”强行上前后端分离。毕设的核心是完整度和逻辑自洽界面干净整洁、功能流畅已经足够拿高分。当然如果你已经在简历里写了“熟悉Vue”那还是上前后端分离吧不然面试时容易露馅。2.3 项目分层结构与包命名规范无论选哪种前端方案后端的分层结构都建议保持清晰。我的标准结构如下com.example.dormitory ├── controller ├── service │ ├── impl ├── mapper ├── entity ├── dto ├── vo ├── config ├── common │ ├── result │ ├── exception │ └── utilscontroller只做参数接收和结果包装不写业务逻辑service层做业务编排和事务控制mapper层只做数据访问entity对应数据库表结构dto用于接收前端参数vo用于返回前端数据config放Web配置、拦截器配置、跨域配置一定要把entity和vo分开。很多同学图省事直接把数据库实体返回给前端结果密码字段、内部备注字段全暴露了。你分开了答辩时就可以讲“我通过VO对象隔离了敏感字段保证数据安全”这又是一个加分点。2.4 MyBatis-Plus在快速开发中的定位MyBatis-Plus在这类项目中几乎是必选的。它的核心价值不是花哨而是实打实帮你省掉70%的单表CRUD代码。BaseMapper提供现成的selectById、selectPage、insert、updateById配合LambdaQueryWrapper可以写出可读性很强的条件查询。还有一个容易被忽略的杀手级功能分页插件。你只需要在配置类里注册一个MybatisPlusInterceptor把PaginationInnerInterceptor加进去然后调用selectPage分页就自动完成了。手写分页SQL的时代真的可以过去了。3. 数据库设计与MyBatis-Plus建表从实体类到SQL的落地路径数据库设计是宿舍管理系统真正的分水岭。表建得好后面写代码是享受表建得烂后面每写一个查询都在还债。这一章我直接把核心表结构和几个关键设计决策讲透。3.1 核心表结构与字段设计意图我梳理了一套比较标准的表结构你做的时候可以直接参考表名用途关键字段t_user系统账号表id, username, password, role, statust_student学生信息表id, user_id, student_no, name, gender, college, major, phonet_dormitory_building楼栋表id, building_no, name, floors, gender_type, manager_idt_dormitory_room房间表id, building_id, room_no, floor, capacity, bed_count, used_bed_countt_check_in_record入住记录表id, student_id, room_id, bed_index, check_in_time, check_out_time, statust_repair_order报修单表id, student_id, room_id, content, images, status, create_timet_dormitory_check查寝记录表id, building_id, check_date, checker_id, statust_check_detail查寝明细表id, check_id, student_id, is_present, remarkt_notice公告表id, title, content, create_by, create_timet_water_electricity水电费表id, room_id, period, water_usage, electricity_usage, fee这里重点讲几个容易犯迷糊的设计。房间表为什么要冗余bed_count和used_bed_count两个字段因为宿舍分配时系统需要快速判断“这个房间还有没有空床位”。如果每次都去做子查询统计入住记录表数据量大了以后性能会很差。冗余这两个字段配合used_bed_count bed_count条件一次查询就能过滤出可分配房间。代价是入住和退宿时需要维护这个计数但这在事务控制下成本很低收益却很大。为什么要独立的t_check_in_record表而不是在学生表上改字段因为“当前住在哪个宿舍”只是学生的一个状态而“住过哪个宿舍”是一段历史。用状态字段表达历史数据更新即丢失用记录表才能保留完整轨迹。退宿、调宿都是往这张表里插入新的记录并关闭旧记录而不是物理删除。这样设计之后“统计本学年入住人次”“查某个学生的住宿轨迹”就都变得非常简单答辩时说到数据可追溯性又有东西可讲了。3.2 床位分配模型的两种实现思路床位分配是宿舍管理系统最核心的业务难点。我见过两种主流做法各有利弊。方案A宿舍表不维护床位数只在入住记录表里靠房间维度存储做法分配时先查入住记录表统计当前入住人数和房间容量做对比手动计算余位。问题一旦并发操作比如两个请求同时看到还剩一个床位同时分配就超员了。数据量大后每次分配都要聚合统计性能也很差。这个方案在毕设里虽然也能跑通但并发冲突你很难圆回来。方案B宿舍表冗余床位数和使用数分配时通过条件更新保证不超员做法分配时执行一条带条件的UPDATEUPDATE t_dormitory_room SET used_bed_count used_bed_count 1 WHERE id ? AND used_bed_count bed_count。如果更新影响行数为0说明这个房间已经满了就换一个房间试。这个方案利用数据库行锁天然解决了并发超卖问题代码还简单。方案B在答辩时非常有优势因为你可以很清晰地解释“我用数据库的原子更新避免了超员类似秒杀场景的库存扣减思路”。老师一听就知道你理解并发控制分数不会低。3.3 从实体类到建表SQL的注解映射与常见坑MyBatis-Plus官方并不支持直接根据实体类自动生成建表SQL但网上确实有不少工具可以做类似的事情很多同学也习惯先写实体类再手动写SQL。这里有几个映射层面的坑我提醒一下。第一TableName注解里表名如果带下划线实体类名是驼峰比如DormitoryRoom对应t_dormitory_room一定要显式标注别依赖默认规则不然PIUS的驼峰映射在某些边缘场景会失灵。第二如果表里带了逻辑删除字段比如deleted字段实体类对应属性要加TableLogic。这样MyBatis-Plus执行deleteById时实际生成的是UPDATE而不是DELETE数据不会真丢。做毕设时这个功能很有用比如误删学生信息还能恢复答辩时也是加分项。第三时间字段类型要统一。MySQL的datetime对应Java的LocalDateTime配合MyBatis-Plus的MetaObjectHandler可以实现插入和更新时自动填充create_time、update_time省得每次手动set值。具体做法是实现一个MetaObjectHandler的Bean在insertFill和updateFill里统一处理。第四字段里不要用数据库关键字做列名。我就见过有人把表字段命名为desc、rank结果查询时SQL直接报错排查半天发现是关键字冲突。类似命名的敏感词提前避开。第五如果你确实需要根据实体类生成SQL可以自己写一段简单的生成工具解析实体类的TableName、TableField注解生成CREATE TABLE语句。这个工具本身也可以作为一个小亮点写进毕业论文里标题就叫“基于注解解析的实体类自动建表工具设计与实现”老师会觉得你有工程化意识。4. 核心功能实现拆解登录鉴权、宿舍分配与统计报表功能实现是项目的重头戏也是最能体现代码功底的地方。这一章挑三个关键模块展开讲每个都是我实际开发时反复打磨过的逻辑。4.1 JWT登录鉴权与拦截器配置宿舍管理系统有学生、宿管员、管理员三类角色登录后的权限差异必须通过鉴权层解决。我推荐用JWT 拦截器的方案而不是引入Spring Security或者Shiro。原因很简单毕设项目功能边界清晰引入安全框架反而要写大量配置类而且框架本身的过滤器链在初学者手里极易出问题一旦登录进不去排查成本极高。JWT的核心逻辑是用户在登录接口验证用户名密码成功后后端生成一个包含用户ID和角色的Token返回给前端。前端将Token存在本地每次请求时放在请求头的Authorization字段中。后端写一个HandlerInterceptor在preHandle里从请求头取出Token、解析、校验有效期把用户信息塞到ThreadLocal里供后续业务代码读取。核心代码大概是这个思路public class JwtUtil { private static final String SECRET your-secret-key; private static final long EXPIRE 7 * 24 * 60 * 60 * 1000L; public static String generateToken(Long userId, String role) { return Jwts.builder() .claim(userId, userId) .claim(role, role) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() EXPIRE)) .signWith(SignatureAlgorithm.HS256, SECRET) .compact(); } public static Claims parseToken(String token) { return Jwts.parser() .setSigningKey(SECRET) .parseClaimsJws(token) .getBody(); } }拦截器注册这一块我犯过一个低级错误静态资源也被拦截了导致登录页面加载不出CSS。后来我在WebMvcConfigurer里加上了排除路径把/api/auth/**、静态资源路径、错误页全部放行问题才解决。你在做的时候要记得registry.addInterceptor(jwtInterceptor()) .addPathPatterns(/api/**) .excludePathPatterns(/api/auth/login, /api/auth/register, /error);这里还有一个进阶话题密码存储。绝对不要明文存密码。至少用BCrypt或者至少加盐MD5。我给你的建议是直接用Spring Security Crypto包里的BCryptPasswordEncoder引入依赖也不需要启用整个安全框架。密码加密这件事答辩时被问到的概率极高这是安全底线问题。4.2 宿舍分配与调宿的事务控制宿舍分配是最容易出现“数据不一致”的模块。分配动作涉及两步更新房间的used_bed_count然后插入入住记录。这两步要么同时成功要么同时失败必须放在一个事务里。Transactional注解是最简单的做法Transactional(rollbackFor Exception.class) public void assignRoom(Long studentId, Long roomId) { // 1. 原子更新床位条件带上 used_bed_count bed_count int rows dormitoryRoomMapper.increaseUsedBed(roomId); if (rows 0) { throw new BusinessException(该房间已满员请选择其他房间); } // 2. 查询床位序号 Integer bedIndex dormitoryRoomMapper.countUsedBed(roomId); // 3. 插入入住记录 CheckInRecord record new CheckInRecord(); record.setStudentId(studentId); record.setRoomId(roomId); record.setBedIndex(bedIndex); record.setStatus(1); // 1在住 checkInRecordMapper.insert(record); }注意几点。第一rollbackFor Exception.class一定要写不然运行时异常归运行时异常但某些非预期异常可能不会触发事务回滚这是默认策略问题。第二bedIndex的查询和入住记录插入之间理论上还有极小的并发窗口但对于毕设规模的项目来说配合上面的原子UPDATE已经足够。如果你想让逻辑更严密可以在房间表加一个bed_status字符串字段比如101表示1号床位占用、0号床位空闲用位运算处理。但这就过度设计了不建议在毕设里搞。调宿的处理稍微复杂它等于“释放旧床位 分配新床位 更新入住记录状态”同样加个Transactional包裹即可。这里有个业务细节要注意调宿申请应该有审核状态审核通过之后才执行分配逻辑。很多同学把“提交调宿申请”和“执行调宿”混在一起结果学生自己就能换宿舍逻辑上说不通。正确做法是申请表里有status字段0待审核、1通过、2拒绝。宿管员点击通过时后端才执行宿舍切换的完整事务。这一步体现了你对业务流审批状态的理解答辩时值得强调。4.3 统计报表与Excel导出统计报表是让项目看起来“高级”的利器。宿舍管理系统最值得做的统计有三个第一个入住率统计。按楼栋分组查询总床位数、已用床位数计算入住率。这个数据直接喂给前端ECharts的柱状图或者饼图展示。核心SQL大概是SELECT b.id, b.name, SUM(r.bed_count) AS total_beds, SUM(r.used_bed_count) AS used_beds FROM t_dormitory_building b LEFT JOIN t_dormitory_room r ON b.id r.building_id GROUP BY b.id, b.name第二个报修统计分析。按报修类型、楼栋、时间范围聚合统计展示哪类问题最多、哪个楼栋报修最频繁。这些数据虽然是简单的COUNTGROUP BY但是配合图表呈现出来说服力极强。第三个查寝异常统计。统计每个学生本学期缺勤次数、晚归次数生成异常名单。Excel导出我建议用EasyExcel而不是POI。原因就一个POI的API太底层写一个导出要几十行代码而EasyExcel封装好了三五行就能搞定处理大文件时内存占用还更低。导出的数据记得通过VO对象组装不要直接把实体类塞给导出工具避免把用户密码这类字段漏出去。5. 项目开发中的真实踩坑记录版本、映射与联调这里写几个我在实际开发中遇到过的典型问题也是很多同学反复问我的内容。提前看到这些能帮你少走很多弯路。5.1 SpringBoot版本过高引发的连锁问题很多同学现在新建项目直接去Spring官网生成最新版SpringBoot结果是3.x甚至更高。SpringBoot 3.0之后有一个大变化javax包迁移到了jakarta。这导致网上大量旧教程里的代码直接报错——import javax.servlet.*根本找不到类。如果你用SpringBoot 3.x所有涉及HttpServletRequest、HttpServletResponse的代码都必须改成jakarta.servlet前缀。而且很多第三方starter的兼容版本可能还没跟上尤其是某些老牌的Shiro整合方案在SpringBoot 3上会遇到比较尴尬的境地。这也是我前面建议用JWT 拦截器的原因之一。如果你不想折腾这些兼容性问题最稳妥的做法是选择SpringBoot 2.7.x。它的生态最成熟教程最多所有依赖都能找到匹配版本对毕设来说完全够用。别因为追求新版本给自己挖坑。5.2 MyBatis-Plus版本不匹配与自动填充失效MyBatis-Plus的版本和SpringBoot版本要匹配。SpringBoot 2.x对应MP 3.5.xSpringBoot 3.x需要MP 3.5.3以上的版本。版本不匹配最直观的表现是启动报错比如Failed to configure a DataSource或者找不到SqlSessionFactory。我之前帮一个同学排查他把SpringBoot升到3.0但MP还是3.5.1结果启动失败换新版本MP就好了。还有MetaObjectHandler自动填充失效的问题。如果插入记录时create_time没有自动填充多半是实体类字段没加TableField(fill FieldFill.INSERT)注解。自动填充有三个要素缺一不可实体类字段注解、MetaObjectHandler实现类、注册为SpringBean。少一个就不生效排查时按这三个环节逐个检查。5.3 前后端联调中的跨域与Token失效如果你做了前后端分离跨域是绕不开的问题。后端写个配置类就能解决Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOriginPatterns(*) .allowedMethods(GET, POST, PUT, DELETE, OPTIONS) .allowedHeaders(*) .allowCredentials(true) .maxAge(3600); } }但这里有一个很隐蔽的坑允许携带凭证cookie时allowedOriginPatterns(*)才能生效如果写allowedOrigins(*)会被浏览器拒绝因为带了allowCredentials(true)的白名单不允许通配符。改掉这个细节跨域问题基本就解决了。Token失效问题也是高频问题。常见表现是登录之后访问接口偶尔成功偶尔401。排查思路一般是三个方向。第一前端有没有在每次请求时从本地取Token并放入请求头第二Token过期时间设置得太短比如设了30分钟学生填个表单就过期了第三后端拦截器对OPTIONS预检请求的处理是否正确。关于第三点我自己就踩过坑前端发POST请求时浏览器会先发一个OPTIONS预检请求如果拦截器把它拦截下来并返回401浏览器就直接报跨域错误。解决办法是在拦截器preHandle里判断请求方法为OPTIONS时直接放行。5.4 时间与JSON序列化问题前后端交互时时间格式不一致是特别容易出现的问题。后端返回LocalDateTime默认序列化成2025-01-17T10:30:00这种带T的格式前端拿到之后显示在表格里非常难看。解决方案有两种一种是在application.yml里配置全局格式另一种是在VO的时间字段上使用JsonFormat注解。我推荐两种结合全局兜底局部定制。还有时区问题。如果服务器和数据库不在一个时区或者MySQL连接串里没有加serverTimezoneAsia/Shanghai查询出来的时间可能会差8个小时。这个坑很阴因为它不是报错而是数据看起来“不对”但你又说不清哪里不对。排查时第一反应就查时区配置。6. 部署与答辩准备最后一公里的加分细节程序写完了功能跑通了距离拿高分还差最后的部署打磨和答辩准备。这一章的经验是我带过好几届学生总结出来的每个细节都可能影响你的最终成绩。6.1 打包部署与服务器上线后端部署最简单的方式就是用Maven打成jar包然后丢到服务器上运行mvn clean package -DskipTests java -jar dormitory-system.jar --spring.profiles.activeprod这里有几个新手容易犯的错。端口被占用服务器上8080端口被别的进程占用启动报错。用lsof -i:8080查看占用进程换端口或者杀掉旧进程。防火墙和安全组很多云服务器默认防火墙没有放开你的应用端口外网访问不通但本地curl又正常。检查安全组入站规则和系统防火墙。数据库连接配置本地开发用的localhost数据库连接部署到服务器后要改成服务器的数据库地址账号密码也要对应。我建议用application-dev.yml和application-prod.yml两套配置用--spring.profiles.active切换避免每次部署都要改配置再重新打包。静态资源路径上传的文件比如报修单图片要保存到配置的绝对路径下而不是打包进jar内部。jar包内的/tmp路径在重启后会丢失文件就没了。外部依赖Tomcat是内嵌的不需要单独安装但要保证服务器上装了对应版本的JDK。SpringBoot 2.x需要JDK 8或11SpringBoot 3.x需要JDK 17。版本不匹配启动会直接报错。免费Web服务器方面如果你只是演示用国内各大云平台的轻量服务器基础套餐对学生来说性价比很高新用户还有优惠活动。如果纯粹本地演示笔记本上启动jar包用局域网访问也同样可以。关键是演示前要实测一遍完整流程不要在答辩现场跑出“页面白屏”或“数据库连不上”这种尴尬问题。6.2 演示数据准备与演示预案答辩演示最怕的不是功能少而是数据“秃”。空荡荡的表格没有说服力。我建议提前准备一套完整、真实感强的演示数据至少两个楼栋一个男生楼一个女生楼每个楼栋三到五层每层四到六个房间每个房间六人间或四人间分配一部分住满、一部分有空位学生信息覆盖多个学院、多个专业报修单准备几条不同状态的数据待处理、已接单、已完成查寝记录准备两到三天的数据其中有一天有异常记录水电费准备好最近三个月的记录这样演示的时候每个界面一打开都有内容统计图表也能正确渲染。不要小看这个细节很多项目功能是好的但演示时数据太少看起来像半成品。演示之前最好把整套流程从头到尾走三遍登录、入住分配、报修、查寝、退宿、统计。注意每一遍都在一个干净的口径下操作看看有没有异常。我当时带的一个学生演示前一晚才发现调宿功能在中间态情况下会报空指针查了一晚上才找到是调宿申请审核通过时目标房间刚好被退宿释放导致房间ID为空。这类边界条件只有反复模拟真实流程才能暴露出来。6.3 答辩高频问题与应对思路我把学生被问过的问题整理成了一个清单这些问题出现的概率极高提前准备好思路答辩会从容很多。高频问题参考回答思路为什么用SpringBoot而不是SSMSpringBoot基于约定优于配置内嵌容器、自动配置开发效率高配套生态成熟适合中小型单体系统权限控制是怎么实现的基于角色的访问控制RBACJWT鉴权拦截器校验Token提取角色信息判断接口访问权限宿舍满了怎么办并发怎么处理通过UPDATE ... SET used_bed_count used_bed_count 1 WHERE used_bed_count bed_count这种方式用数据库原子操作保证不会超分如果调宿时目标房间刚好被占用了怎么办调宿审核通过后执行切换动作时使用事务加房间更新的条件判断占用失败则回滚并提示用户密码为什么加密用的什么算法BCrypt加盐哈希即使数据库泄露明文密码不会直接暴露数据量增大后系统会不会卡关键查询走了索引列表页使用分页查询统计类报表通过聚合查询当前业务体量下单库单表完全够用系统能不能扩展成微服务可以但当前业务规模下单体架构开发效率最高如果未来增加多校区管理、消息推送等场景可以按领域拆分回答问题时有个技巧不求说得深但求说得顺。把每个问题都用自己的话讲一遍不要背概念要结合你项目里的具体做法来说。老师最反感的就是“我配了这个框架具体原理不太清楚”这种回答。你只要能把“做了什么、为什么这么做、遇到什么问题、怎么解决的”讲清楚就已经超过大多数人了。最后再分享一个小技巧做系统的时候把核心业务的关键日志打出来。比如宿舍分配成功时打印insertLog(分配宿舍, 学生ID, 楼栋-房间-床位)。答辩时如果你能现场调出日志展示“同学某年某月某日办理入住分配了6号楼302房间3号床位”老师会眼前一亮——这说明你的系统具备可审计性而这个能力在企业级系统中是实实在在的刚需。一个宿舍管理系统做到这个程度你拿到的就不仅仅是一个毕业设计的高分而是一段可以在面试时自信讲出来的工程项目经验。