计算机类毕业设计实战指南:从选题到部署的全链路技术闭环
摘要:很多同学的毕业设计卡在“能跑就行”,结果答辩时被老师一句“如果线上 1000 人同时用,你怎么办?”直接问懵。本文用“校园二手书交易平台”这个小而全的 Web 项目做样本,带你走完需求→技术选型→编码→部署→压测→安全加固的完整闭环,让代码不仅“能跑”,还能“上简历”。
1. 背景痛点:老师一看就摇头的 3 大顽疾
- 代码写完就扔,单元测试覆盖率 0%,现场演示还得祈祷数据库别崩。
- 所有逻辑塞在 Controller,一个文件 2000 行,老师问“如果加二手手机板块怎么改?”——当场社死。
- 部署全靠“学长电脑”,IP 地址写死在内网,答辩现场打不开,老师直接扣分。
一句话:缺的不是功能,是工程思维。
2. 技术选型对比:别让框架选择变成抛硬币
| 维度 | Spring Boot 2.7 | Flask 2.3 | 备注 |
|---|---|---|---|
| 学习曲线 | 中等(注解多) | 低(10 行 Hello) | 若团队只会 Python,直接 Flask |
| 生态 | 全家桶(Security、Validation) | 小而美,需自己拼 | Spring 一站式,Flask 灵活 |
| 性能 | 预热后 2000 RPS | Gunicorn + Gevent 1500 RPS | 毕设量级两者都够 |
| 容器镜像体积 | 120 MB(JRE slim) | 60 MB(python:3.11-slim) | 校园网 push 时,越小越快 |
结论:
- 想冲“Java 技术栈”简历,选 Spring Boot;
- 想 3 天搭完 MVP,选 Flask。
数据库同理:
- MySQL 8:老师都认识,网上资料多,答辩好解释。
- PostgreSQL 14:JSON 字段爽,但 windows 安装包 200 MB,实验室装半天。
部署方式:
- Docker + Docker Compose:本地一键
docker-compose up,老师笔记本也能跑。 - 传统 war→Tomcat:老教程多,但端口 8080 常被校园网封。
3. 核心实现:Clean Code 不是“多写注释”
3.1 用户鉴权(Spring Security 版)
@RestController @RequestMapping("/api/auth") @RequiredArgsConstructor public class AuthController { private final AuthService authService; @PostMapping("/login") public ApiResp<TokenDto> login(@Valid @RequestBody LoginCmd cmd) { // 1. 参数校验已由 @Valid 完成 // 2. 业务逻辑下沉到 Service,Controller 仅路由 TokenDto token = authService.login(cmd); return ApiResp.success(token); } }关键点:
- DTO 命名
*Cmd表“命令”,与*Dto查询结果区分,可读性↑。 - 统一返回
ApiResp<T>,前端无需判断 200 里再套 code。
3.2 异步任务(Flask 版)
# tasks.py from celery import Celery cel = Celery('tasks', broker='redis://localhost:6379/0') @cel.task def compress_image(path: str) -> str: """接收图片路径,压缩后返回新路径""" from PIL import Image with Image.open(path) as im: im.thumbnail((800, 800)) new_path = path.replace('.jpg', '_min.jpg') im.save(new_path, quality=85) return new_path调用处:
# views.py from tasks import compress_image @app.post('/api/book') def publish_book(): ... compress_image.delay(save_path) # 非阻塞,立即返回 return {'id': book.id}避坑:
- 把
Celery实例独立到tasks.py,避免循环 import。 - 任务函数必须可序列化,别直接传 ORM 对象。
4. 部署与验证:让代码“离开 IDE”也能活
4.1 Dockerfile(以 Spring Boot 为例)
FROM openjdk:17-jre-slim WORKDIR /app COPY target/book-swap-0.0.1-SNAPSHOT.jar app.jar EXPOSE 8080 ENTRYPOINT ["java","-Dspring.profiles.active=docker","-jar","app.jar"]构建:
mvn -DskipTests package docker build -t book-swap:latest .4.2 docker-compose.yml
version: "3.9" services: mysql: image: mysql:8 environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: book_swap ports: ["3306:3306"] app: image: book-swap:latest ports: ["8080:8080"] depends_on: [mysql] environment: SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/book_swap一键启动:
docker-compose up -d4.3 Nginx 反向代理(前端静态页 + 后端 API)
server { listen 80; server_name your-domain.com; location / { root /usr/share/nginx/html; # 前端 dist try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://app:8080/; # 容器名直联 proxy_set_header Host $host; } }4.4 基础压测:wrk 跑一把
安装:
sudo apt install wrk命令:
wrk -t4 -c100 -d30s --latency http://localhost:8080/api/book/hot结果示例:
Running 30s test @ http://localhost:8080/api/book/hot 4 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 35.21ms 12.10ms 91.02ms 71.12% Req/Sec 713.45 81.29 0.89k 68.50% 85412 requests in 30.05s, 48.52MB read Requests/sec: 2842.31若 QPS < 1000,检查:
- 是否开启连接池(HikariCP 默认 10,太小)。
- 是否 Nginx 未开
gzip。
5. 安全性与避坑指南:别让“小项目”变成“大事故”
- SQL 注入:
- MyBatis 用
#{}别用${};JPA 用@Param+ 方法名绑定即可。
- MyBatis 用
- 环境变量:
- 把
jwt.secret、数据库密码全丢进.env,application-docker.yml只读${JWT_SECRET}。 - 绝对不要把
.env提交 Git,用.env.example模板占位。
- 把
- Git 提交:
- 采用
<type>(<scope>): <subject>,例feat(auth): 增加手机号一键登录。 - 每行 72 字内,方便老师
git log一眼看懂。
- 采用
- 接口幂等:
- 下单、发帖用
POST /api/orders带Idempotency-Key头,后端用 RedisSETNX去重。
- 下单、发帖用
- 日志:
- 统一 JSON 输出,字段
traceId贯穿,答辩现场可快速定位错误。
- 统一 JSON 输出,字段
6. 重构你的毕设:把“玩具”变“产品”
- 先删掉所有
System.out.println,换成logback-spring.xml分级日志。 - 把
application.properties拆成dev / prod / docker三份,现场演示秒级切换。 - 写 5 条核心接口的单元测试(MockMvc / pytest),报告截图贴进论文,老师一看就觉得“专业”。
- 用 GitHub Actions 做 CI:每次 push 自动跑测试、构建镜像,README 放徽章,面试直接甩链接。
让毕设成为简历亮点,而不是“占一行”。当面试官问“这个项目上线了吗?”你能把公网 IP、Docker 镜像、压测报告摆出来,就已经赢过 90% 竞争者。
最后,把今天这份闭环流程套到你的选题上:
- 如果是“校园失物招领”→加图片压缩、站内信、小程序码,一样走全套。
- 如果是“旧衣捐赠交换”→把支付模块换成物流回调,照样能部署、压测、写单元测试。
毕业设计不是终点,而是第一张“生产级”名片。祝你答辩顺利,也祝你把这份代码自信地写进简历,让面试官忍不住约你面试。