考勤这个事,看起来简单,真正做过的人才知道有多琐碎。我见过不少学校里其实还在用最传统的点名方式:老师拿着一张打印好的名单,挨个喊名字,底下学生应一声,老师画个勾。遇到大课一百多人,点完一轮名字十分钟就过去了,下课还得人工统计出勤率,再录入电脑存档。这套流程效率低不说,还特别容易出错——有人替答到、有人名字太生僻老师念错、统计的时候漏行,都是常态。
我之前帮人做过一个专门解决这类问题的学生考勤管理系统,技术栈用了 Java + SSM(Spring + SpringMVC + MyBatis)做主后端,另外还用 Python 的 Flask 搭了一个辅助服务来做数据统计和报表导出。项目交付的内容里除了完整源码,还有配套的毕业论文、调试文档和讲解视频,属于那种能直接拿去用、也能直接拿去做课程设计的完整方案。这篇文章我就把这个项目的前前后后拆开讲一遍,从技术选型思路到数据库设计,从核心模块实现到部署踩坑,把能说的细节全倒出来。
1. 整体设计思路与技术选型
1.1 为什么是 SSM + Flask 的混合架构
先说这个项目最容易被问到的一个问题:既然已经有了 SSM 这套完整的 Java Web 技术栈,为什么还要再引入一个 Flask?
答案不复杂。SSM 确实能做考勤系统的全部业务逻辑——学生管理、课程管理、考勤记录的增删改查,这些用 SpringMVC 管接口、MyBatis 管数据库、Spring 管对象依赖,配合得非常丝滑。但考勤系统有一个天然的特殊点:它生成的数据最终都要落到“统计”和“报表”上。一个学期下来,每个学生几十条考勤记录,一个班几百条,一个学院几千条,系统需要快速地按课程、按班级、按时间维度聚合这些数据,算出出勤率、缺勤次数、趋势变化。这一块如果用 Java 写,当然也能做,但代码量会比较可观,尤其是涉及到 Excel 报表导出、图表数据聚合这些活,Java 得引入 POI、ECharts 接口封装之类的额外依赖,写起来又长又绕。
Flask 的强项恰恰在这里。Python 生态里有 pandas 这种处理表格数据的利器,几行代码就能完成分组统计,配合 openpyxl 或者 xlsxwriter 生成带格式的 Excel 报表也非常顺手。所以这个项目的架构思路是:SSM 负责核心业务和数据持久化,Flask 负责数据分析和报表生成,两者通过 HTTP 接口通信。简单说,就是用合适的工具干合适的活,而不是用一把锤子去拧螺丝。
这种混合架构还有一层现实考虑:很多做课设的同学想同时在简历上体现 Java 和 Python 两种技术栈的实践经验,这个项目天然满足了这一诉求。SSM 部分体现你在 Java Web 领域的功底,Flask 部分体现你的 Python 数据与接口开发能力,项目亮点和面试谈资都有了。
1.2 功能模块拆解:考勤系统到底需要哪些东西
学生考勤系统听起来是个小项目,但真拆起来功能并不少。我当时做需求梳理的时候,把系统分成了四个核心功能域:
- 基础信息管理:学生信息(学号、姓名、班级、专业、入校年份)、课程信息(课程名、授课教师、上课时间、上课地点)、班级信息。这些是整个系统的基础数据,考勤和统计都得依赖它们。
- 考勤登记:这是系统最核心的日常操作。老师登录后选择一个课程和一个班级,系统展示当前应到学生列表,老师可以逐个标记正常、迟到、早退、请假、缺勤五种状态。为了照顾大班课的点名场景,我还加了批量操作——默认全部标记正常,只需把异常的学生挑出来改状态即可,这样能把一张百人名单的操作时间压缩到一两分钟内。
- 出勤统计:按单个学生统计某段时间内的出勤率,按班级统计某门课程的平均出勤率,按课程统计整个学期的出勤趋势。统计结果需要同时支持页面表格和 Excel 导出两种呈现方式。
- 系统管理:管理员维护教师账号和密码,教师可以修改自己的密码。考虑到这是个实际要用的系统,角色的权限边界要清楚:管理员管所有数据,老师只管自己授课范围内的数据。
这些功能设计不是随手拍脑袋想的,每一块都对应了实际使用中的痛点。比如批量点名这个功能,就是因为我真的经历过那种一百二十人的大课,如果挨个点,学生等着烦,老师也烦。再比如统计维度必须拆分到学生、班级、课程三个粒度,因为不同角色的关注点不一样——辅导员看班级整体出勤率,任课老师看单个学生的缺勤情况,教务员看某门课的整体到课趋势。
数据库的设计也围绕这些模块展开,核心就是三张表:student(学生表)、course(课程表)、attendance(考勤记录表)。另外还有 admin 表存账号信息,course_student 表做课程和学生的多对多关联。考勤记录表是数据量增长最快的表,一个学生一学期选十门课,每门课三十次课,就产生三百条记录,所以我在设计时专门给这个表加了索引,组合索引(course_id + student_id + attend_date),这样按课程按学生查询统计的时候走索引,速度能快不少。这也是后来 MyBatis 写 SQL 时要注意配合的一个点——索引建了,SQL 的 where 条件顺序就得和索引匹配,否则索引白建。
2. 核心模块实现与关键技术细节
2.1 学生管理与课程管理的实现要点
学生管理模块是系统的门面,也是 CRUD 最典型的场景。SSM 三层架构在这一块体现得最完整:Controller 层接收请求参数,Service 层处理业务校验,Mapper 层操作数据库。
学生信息的增删改查,听起来就是四个方法的事,但实操里有很多细节要注意。比如学号是业务主键,我用它做唯一性校验,新增学生时如果数据库里已经存在相同学号,必须在 Service 层拦住,不能等到数据库报唯一约束异常才处理——那样用户看到的就只是一个 500 错误,体验很差。我的处理方式是在 Service 层先调用一个 countByStudentNo 方法查一下,查到大于 0 就直接返回“该学号已存在”的业务提示,这种前置校验比异常处理更友好。
学生列表的分页查询也值得说一下。前端用的是 layui 的分页组件,传 page 和 limit 两个参数进来,后端用 PageHelper 插件处理分页。PageHelper 的用法有个坑:它基于 MyBatis 拦截器实现,分页参数绑定在紧接着的下一条 SQL 上,所以如果你在查询方法前面多写了别的 SQL 操作,分页就可能失效。我调试这个问题的时候花了半天,最后才意识到是 Service 层在查询学生列表之前先做了一次班级名称的辅助查询,导致 PageHelper 应用错了 SQL。解决办法是把辅助查询移到分页查询之后,或者改用 ThreadLocal 显式传参的方式,总之必须保证分页紧跟目标 SQL。
课程管理的逻辑比学生管理稍微复杂一点,因为涉及和教师、班级的关联。课程表里有 teacher_id 外键,查询课程列表时需要 join admin 表把教师姓名带出来。如果课程和班级也要绑定,就得用 course_class 中间表。实操中的典型场景是:老师创建一门课程后,要把自己教的班级挂到课程下面,这样点名的时候就能直接按班级过滤学生了。这个关联操作我用了一个批量插入接口,前端传班级 ID 数组,后端循环插入中间表,为了防重复,中间表加了 course_id + class_id 联合唯一索引,插入前先查一遍已存在的记录,梳理清楚再插。这种去重策略在真实项目里是标配,不然一旦前端逻辑有 bug 或用户手抖点两次,数据就乱了。
2.2 考勤登记流程:从页面操作到数据落库
考勤登记是整个系统使用频率最高的功能,所以它在交互设计和技术实现上都花了最多心思。
老师端的操作流程是这样的:登录系统 → 进入考勤登记页面 → 选择课程和班级 → 系统加载该班级选了这门课的所有学生 → 老师标记出勤状态 → 提交保存。
后端接口设计上,我没有选择一条条提交考勤记录的方案,因为那样在百人场景下会产生大量请求,数据库压力大,前端也卡。而是设计成一次性提交整个班级的考勤结果:前端收集所有人的状态,组成一个 JSON 数组,POST 到一个批量保存接口。接口接收 List,遍历插入数据库。
批量插入的性能优化也是一个务实问题。如果循环单条 insert,一百条记录就要和数据库交互一百次,虽然数据量小也能跑,但太慢了。我改用 MyBatis 的 foreach 批量 insert 语法,一条 SQL 插入全部记录,实测百人的考勤保存从原来的两三秒降到零点几秒。不过要注意,MySQL 对单条 SQL 的包大小有限制,批量插入的条数也别太极端,实测下来五百条以内是安全的,超出的话可以分批。
考勤状态的字段设计我用了 tinyint 枚举:0 正常、1 迟到、2 早退、3 请假、4 缺勤。用数字而不是字符串的好处是数据库存储更省空间,查询时再用字典表或 Java 常量类做映射。这种设计还有一个好处,就是做统计聚合时可以直接用 SQL 的 SUM 函数按状态值计算,比如统计缺勤次数就是 SUM(status = 4) 的写法,非常方便。
2.3 出勤统计与报表导出:Flask 的用武之地
到了统计报表这一步,就轮到 Flask 出马了。SSM 后端负责提供统计数据的数据接口,Flask 服务负责接收这些数据、进行深度聚合处理、生成 Excel 文件并返回下载链接。
我在 Flask 端实现了一个数据统计服务,暴露了三个核心接口:
- /api/statistics/student:接收学号和时间范围,返回该学生的出勤统计
- /api/statistics/course:接收课程 ID,返回该课程的班级出勤率汇总
- /api/statistics/export:接收课程 ID 和时间范围,生成 Excel 报表文件
这里有个设计取舍要说清楚。有人可能会问:统计数据直接从数据库算不就行了,为什么要通过 Flask 中转?我的答案是:SSM 端确实可以直接做基础统计,但更复杂的场景——比如跨多张表做透视表、计算趋势变化、生成带格式的 Excel——用 pandas 处理数据、用 xlsxwriter 控制单元格样式,确实比 Java 端写起来舒服太多。比如生成一份带“出勤趋势图”数据源的报表,pandas 几句话就能把数据重塑成需要的透视表结构,Java 端要实现同等效果,得写不少 POI 的样式设置代码。
Flask 服务启动在 5000 端口,SSM 端通过 RestTemplate 调用它的接口。两个服务公用同一个 MySQL 数据库,Flask 通过 SQLAlchemy 连接。这样一来,Flask 能直接查表做统计,不需要 SSM 先把数据取出来再传过去,减少了一次数据中转的开销。SSM 这边只需要把用户请求转发给 Flask,拿到统计结果再返回给前端渲染。这个链路在逻辑上是通的,实际跑起来也很顺畅。
Flask 端统计的核心逻辑用 pandas 实现,代码简洁得让人舒服:
import pandas as pd from flask import Flask, jsonify, request from sqlalchemy import create_engine app = Flask(__name__) engine = create_engine('mysql+pymysql://root:password@localhost:3306/attendance_db?charset=utf8') @app.route('/api/statistics/course', methods=['GET']) def course_statistics(): course_id = request.args.get('courseId') sql = """ SELECT s.student_no, s.student_name, a.status, a.attend_date FROM student s JOIN attendance a ON s.student_id = a.student_id WHERE a.course_id = %s """ df = pd.read_sql(sql, engine, params=(course_id,)) total = len(df) normal = (df['status'] == 0).sum() late = (df['status'] == 1).sum() leave = (df['status'] == 3).sum() absent = (df['status'] == 4).sum() rate = round((normal + late) / total * 100, 2) if total > 0 else 0 return jsonify({ 'total': total, 'normal': int(normal), 'late': int(late), 'leave': int(leave), 'absent': int(absent), 'attendanceRate': rate })这段代码已经足够回答“为什么不建议用 Java 写统计”这个问题了。用 pandas 读库、分组计算、出结果,整个逻辑没有一行循环,全部是向量化操作。
3. 实操过程:从零搭建到联调运行
3.1 环境准备与项目初始化
搭建这个项目的环境,我用的是经典的一套组合:JDK 1.8、Maven 3.6、MySQL 5.7、Tomcat 8、Python 3.8。选 JDK 1.8 不是因为新版本不好,而是 SSM 框架在 1.8 下的兼容性最稳,很多老项目都跑在这上面,遇到问题时社区答案也最多。这个项目不建议一上来就上 JDK 17,除非你对整个工具链的新老兼容问题非常有把握。
数据库初始化这步要细心。我准备了一个 init.sql 脚本,建库建表加基础数据一步到位。这里有一个我反反复复强调很多次的点:MySQL 的建表语句一定要指定 utf8mb4 字符集,不然后面插入中文学生姓名时会因为字符集问题出现乱码,查起来非常头疼。我的建表语句里统一写了 DEFAULT CHARSET=utf8mb4,包括存储 emoji 表情的需求也能覆盖,算是彻底断绝了后患。
项目初始化我用 Spring Initializr 的思路手搭目录。标准 Maven 工程结构:src/main/java 放 Java 源码,src/main/resources 放配置文件,src/main/webapp 放前端页面。SSM 的配置有三件套需要分别处理:Spring 的 applicationContext.xml 管 Service 层和 Mapper 扫描,SpringMVC 的 spring-mvc.xml 管 Controller 扫描和视图解析器,MyBatis 的 mybatis-config.xml 管数据库连接和别名。
3.2 SSM 后端搭建的关键步骤
SSM 的搭建流程,我总结成一套顺序,按这个顺序走基本不会出乱子:
- pom.xml 引入依赖:spring-webmvc、mybatis、mybatis-spring、mysql-connector-java、druid 连接池、jackson-databind、pagehelper、lombok。lombok 省去了写 getter/setter 的样板代码,大幅缩减了实体类的行数。
- 配置数据源和 MyBatis:在 applicationContext.xml 里配置 Druid 数据源,注入 MyBatis 的 SqlSessionFactoryBean,指定 mapper 文件位置。
- 配置事务管理器:用 DataSourceTransactionManager 管理 Service 层的事务,批量插入考勤记录这种多条写操作必须有事务保护。
- 配置 SpringMVC 和注解驱动:在 spring-mvc.xml 里开启注解扫描和 JSON 消息转换器。
- 编写实体类、Mapper 接口、XML 映射文件、Service 接口和实现类、Controller 类,按模块从上到下过一遍。
这里有个很容易被忽略的细节:数据库表字段如果是下划线风格的(比如 student_no),实体类属性是驼峰风格(studentNo),在 MyBatis 的映射文件里必须手动写 resultMap,或者在 mybatis-config.xml 里开启驼峰映射(mapUnderscoreToCamelCase=true)。我直接开启了驼峰映射,这样增删改查的 resultType 就能自动匹配,不用每个实体都写一长串 resultMap,省事很多。但注意,如果你用了 PageHelper 的分页查询返回 Page 对象,驼峰映射这开关是全局生效的,不需要额外配置。
3.3 Flask 服务搭建与部署
Flask 服务部分的核心是数据统计接口和 Excel 导出功能,依赖比较少:flask 本身、pandas、openpyxl(xlsxwriter 也可以)、pymysql、sqlalchemy。我把这些写进 requirements.txt 里,部署的时候 pip install -r requirements.txt 一条命令搞定。
Excel 导出我用了 xlsxwriter 库。它比 openpyxl 的优点在于对单元格样式的控制更精细,能在生成报表的同时把标题加粗、设置背景色、调整列宽、冻结首行,导出的文件拿来就能直接打印。生成文件后保存到服务器的 uploads 目录,返回相对路径给前端,前端拼接完整 URL 下载。
Flask 部署我推荐用 waitress 或者 gunicorn,不要直接跑自带的开发服务器。开发服务器在访问量稍大时表现不稳定,生产环境下直接用它是个典型的坑。我在本地测试时用 gunicorn -w 4 -b 0.0.0.0:5000 app:app 启动,四个 worker 线程保持并发稳定。
3.4 前后端联调:接口对接与跨域问题
联调是项目搭建中最能暴露问题的阶段。SSM 端页面在 8080 端口,Flask 端在 5000 端口,这两个不同端口之间通信必然涉及跨域问题。
我处理的方式很直接:在 Flask 端写一个简单的 CORS 中间件,给所有接口加上允许跨域的响应头。这里不要偷懒只在某个接口上加,因为 Flask 的接口数量会持续增长,统一处理最稳妥。
SSM 端调 Flask 时用的是 RestTemplate:
RestTemplate restTemplate = new RestTemplate(); String url = "http://localhost:5000/api/statistics/course?courseId=" + courseId; JSONObject result = restTemplate.getForObject(url, JSONObject.class);这里我踩过一个坑:RestTemplate 默认用的是 JDK 的 HttpURLConnection,如果 Flask 返回 JSON 格式不规范(比如有多余的 BOM 头),JSONObject 的解析会报错。所以 Flask 端所有 JSON 响应的编码务必统一成 UTF-8,用 jsonify 返回的数据默认就是这个编码,但如果手动构造 Response 就得注意设置 content_type。
4. 常见问题与调试实录
4.1 数据库连接与环境配置类问题
这个项目里出现频率最高的报错之一,是数据库连接失败。典型场景是配置了 localhost:3306 但数据库端口实际是 3307,或者用了错误的用户名密码。排查这类问题我有一套固定流程:先试命令行直接连数据库,确认账号密码和端口没问题,再检查 applicationContext.xml 里的连接串是否一致,最后看 MyBatis 的驱动类是否引入正确。注意 MySQL 5.7 和 8.0 的驱动类和连接串格式不同,如果用 MySQL 8 就要引入 com.mysql.cj.jdbc.Driver,并且连接串要多带一个 serverTimezone=Asia/Shanghai 参数,否则会报时区错误。
另一个高频问题是 JDK 版本和项目编译级别不匹配。Maven 项目如果 pom.xml 里没有显式指定编译版本,默认用的是 JDK 1.5 的编译级别,高版本 JDK 编译出来的类可能在运行时各种报错。解决办法是在 pom.xml 里加如下配置:
<properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties>这组配置要是不加,你用 JDK 8 写代码也可能因为它默认按 1.5 编译而无法使用 lambda 表达式等语法特性,直接在编译期就报错,很让人摸不着头脑。
4.2 MyBatis 映射与 SQL 问题
MyBatis 是 SSM 里最容易出问题的环节,基本的错都集中在 XML 映射文件的 namespace 不一致、SQL 语句多了一个空格少了一个逗号、foreach 参数没加 collection 等。我调试时最常用的方法是打开 MyBatis 的日志输出,在 mybatis-config.xml 里加:
<settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>这样每条 SQL 都会在控制台打出来,参数值也能看到,排错效率翻倍。实际干活的时候这个开关几乎是必开的,等上线再关掉。
批量插入考勤记录时还有一个高频报错,是 foreach 里参数名写错。如果接口参数是一个 List,Mapper 接口里必须用 @Param("list") 注解给参数命名,XML 里写 foreach collection="list"。如果不加 @Param 注解,MyBatis 默认的参数名是 list 或者 collection,但有时候也会生成一些绕口的自定义名称,导致 XML 里找不到参数。我的建议是永远手动加上 @Param,明确指定一个名字,这样 XML 里写什么都清楚。
复杂统计 SQL 的性能问题也是要注意的。考勤记录表数据量大之后,如果没建索引,按课程统计出勤率的 SQL 可能跑到几秒钟。我的经验是在建表之初就规划好索引:attendance 表建联合索引 (course_id, student_id, attend_date),student 表建唯一索引 (student_no)。索引也不是越多越好,每张表五六个索引就是一个合理上限,再多会影响写入性能。
4.3 前后端交互的典型掉坑点
前后端数据交互这块也有几个高频问题值得单独提出来。
第一个是中文乱码。这个问题在 SSM 老项目中特别常见,源头一般是三个:数据库连接串没指定 characterEncoding=utf8、响应没设置 UTF-8、JSP 页面本身编码不对。我在 spring-mvc.xml 里配置了 CharacterEncodingFilter,强制请求和响应都走 UTF-8。如果不配这个过滤器,POST 请求带中文参数时在 Controller 拿到的就是问号,排查起来特别误导人。
第二个是 JSON 序列化循环引用。如果实体类之间有双向关联关系,比如 Student 里面有 List courses,Course 里面又有 List students,用 JSON 序列化时会发生循环引用无限递归,最终导致 StackOverflowError 或者序列化失败。解决方式是在一方的属性上加上 @JsonIgnore 注解,或者用 DTO 类去承接前端要展示的字段,只把需要的字段暴露出去。这种方式也符合接口设计的“最小暴露”原则,不会把内部数据模型完整暴露给前端。
第三个是前端分页参数丢失。 layui 的分页组件切换页码后,默认只传 page 和 limit,但如果查询条件里有搜索关键词,这些关键词不会自动带到下一页的请求里。处理方式是在 table.reload 的时候手动把之前存下来的搜索条件重新传进去,否则切页之后搜索条件丢失,显示的数据就和预期不一致了。这个小问题看起来不严重,但实际操作时特别容易忽略。
4.4 项目打包与部署的避坑指南
Java Web 项目最终打成 WAR 包部署到 Tomcat。这里我强烈建议用 Maven 的 package 命令来打包,而不是在 IDEA 里手动导 Artifact。Maven 打包会按照 pom.xml 里的配置自动处理依赖和资源文件,出错的概率小很多。手动导 Artifact 经常遇到依赖缺失、配置文件被遗漏、lib 目录重复等一堆问题。
打包之前记得在 IDEA 的 Project Structure 里把 Artifacts 配置好,或者用 maven-war-plugin 统一管理。如果用的是内置的 Tomcat 调试没问题,但部署到外部 Tomcat 就需要注意编码问题——外部 Tomcat 的 conf/server.xml 里要配置 URIEncoding="UTF-8",否则 GET 请求的中文参数会乱码。
Flask 部分的部署相对简单,但也有一些环境问题要注意。比如 Python 的依赖包版本冲突,pandas 和 numpy 的版本要匹配,建议直接用 requirements.txt 来锁定版本。另外如果服务器上同时跑多个 Python 服务,建议用虚拟环境把依赖隔离开,避免互相影响。
5. 让项目“更值钱”的那些升级空间
如果你做完这个系统之后还想让它继续升级拿得出手,我建议从这几个方向着手。
第一个方向是把 SSM 端升级成 Spring Boot。Spring Boot 的自动配置和 starter 机制能大幅度减少 SSM 中繁琐的 XML 配置,项目结构也更清爽。其实这个考勤系统的业务逻辑和 Spring Boot 完全兼容,把 Web 依赖换成 spring-boot-starter-web、MyBatis 换成 mybatis-spring-boot-starter,配置文件改成 application.yml,迁移成本不到半天。迁移完成之后,整个项目的可维护性和简历上的“含金量”都会提升一个档次。
第二个方向是给 Flask 部分加一个可视化仪表盘。目前的数据统计已经产出了出勤率、缺勤次数这些核心指标,前端页面可以直接接 ECharts 做折线图和柱状图,展示一个班级从开学到期中的出勤趋势。技术上其实就是把统计数据传给 ECharts,配置好它的 series 和 xAxis。但效果立竿见影,系统一下子就从“能用”变得“好看”了。
第三个方向是引入消息队列做异步处理。如果学校规模很大,几百个老师同时点名,统计报表的生成会变得很慢,同步生成 Excel 可能要等好几秒。引入 RabbitMQ 或者 Redis 队列,把报表导出任务丢到异步任务队列里,生成完毕后通知用户下载。但这个要看实际并发量,如果只是课设级别或者几百人规模,同步处理完全够了,不要过度设计。
第四,可以考虑在 Flask 端增加人脸识别打卡接口。学生的考勤数据如果靠手动点名录入,还是有一定的人工成本。接入一个人脸识别的 Python 库,摄像头识别到人脸后自动打点标记,考勤的效率和准确度都会有质的提升。这个方向同时也是目前智慧校园比较热门的功能点,在毕业设计答辩上会是加分项。
6. 我的实操体会与心得建议
做这个项目最大的体会是:一个考勤系统,业务本身并不复杂,复杂的是把看似简单的业务做顺、做稳、做得让人愿意用。比如批量考勤登记这个功能,说实话技术上就一个批量 insert,但它的交互设计——默认全勤、只标异常——才是真正从用户角度出发思考的结果。技术永远是为使用场景服务的,这比任何花哨的框架都重要。
给准备拿这个项目做课设或者毕设的同学提几条建议。第一,拿到源码之后别急着改代码,先完整跑通流程,把数据库建好、服务启动、页面走一遍,对整个系统的运行机制建立直观认识后,再动手深入阅读代码。第二,重点理解 SSM 三层架构下请求如何从 Controller 流到 Service 再到 Mapper,这个链路是 Java Web 面试几乎必问的基本功。第三,答辩和面试时不要只讲“我做了什么”,要讲“我为什么这么做”,比如挑出批量插入的性能优化、Flask 和 SSM 的混合架构选型思路、索引设计的考量,这些才是体现你思考深度的细节。
最后分享一个小技巧。Flask 和 SSM 联调时,如果觉得每次都要同时启动两个服务很麻烦,可以把两个启动命令写成一个 bat 或 shell 脚本,一键启动。另外给 Flask 服务加一个简单的健康检查接口 /api/health,联调时先确认这个接口通,再测具体的数据接口,排查问题会清晰很多。这些小工具虽然是旁枝末节,但在实际操作中确实能显著提升效率。