ARTICLE DETAIL

资讯详情

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

Spring Boot + Vue毕设全流程:从选题、开发到部署答辩

Spring Boot + Vue毕设全流程:从选题、开发到部署答辩 每年到了毕设季后台就会涌进一批类似的提问Java毕设选题做什么好Spring Boot项目从哪里下手答辩老师一般会问些什么这其实暴露了一个很普遍的问题很多同学在学校里做过课设、写过实验报告却从来没有完整地走过一遍从“一个想法”到“一套能演示的系统”再到“一篇能过审的论文”的全流程。这篇文章就是来补上这一课。我会顺着Java毕业设计最典型的一条技术路线——Spring Boot MyBatis-Plus MySQL前端配Vue——把选题、需求分析、数据库设计、核心功能实现、部署上线、论文答辩这一整套链路里的关键节点、决策理由和常见坑点完整讲一遍。适合两类人看一是正在做Java毕设、需要有人帮你理清整体思路的同学二是哪怕不写论文也想知道一个真实业务系统到底是怎么一步一步落地的开发者。1. 毕设整体设计选题、需求与技术选型1.1 选题怎么定才不后悔先说选题。很多同学第一步就摔跟头选了三个典型方向的题目要么太大、要么太旧、要么太偏。题目太大的典型代表是“智慧校园综合管理平台”“企业级微服务电商系统”。这种题目听起来唬人但毕设周期就一个学期你一个人要完成用户端、管理员端、商家端、物流、支付、推荐、大数据分析……做到最后必然是每个模块都只做了个壳子代码深度不够论文全是截图堆砌答辩时老师随便挑一个模块追问两句就露馅。题目太旧的更好识别“基于JSP的图书管理系统”“基于Servlet的学生信息管理系统”技术栈停留在十年前虽然好做但答辩老师会直接问你为什么不使用主流框架这会显得你对技术趋势毫无感知。我自己的经验是选题有一个比较稳的公式适中规模 真实场景 技术可解释。规模上核心实体表控制在8到15张之间最舒服场景上选你身边真的有用户在用的东西比如校园二手交易、实验室设备预约、社团活动报名、毕业设计选题管理这类场景你熟悉业务规则需求不容易编歪技术上能说清楚“我为什么用这个”比“我用了多少新技术”更重要。如果你非要碰“算力调度系统开发”这类偏底层的题目也不是不行但要有心理准备这类系统对资源监控、任务分配算法、并发控制的要求很高光是一个任务队列的可靠性设计就能让你多写两万字论文。实力不够的时候选题保守一点不是丢人的事毕设的核心目标是让你完整走一遍系统开发流程而不是挑战业界难题。1.2 需求分析别急着写代码定完题目的第二天就打开IDE写代码这是效率最低的启动方式。我见过太多人写到一半返工原因是发现少了一张关联表或者管理员需要的功能根本没有接口。这些问题在需求分析阶段都能避免。需求分析不需要用非常规范的UML那套东西但要产出三样东西角色清单、功能清单、核心业务规则。先说角色清单。一个典型的Java毕设系统通常有2到3类角色。拿“实验室设备预约系统”举例至少要有学生、教师、管理员。学生查设备、提交预约教师审核预约、查看使用记录管理员管设备信息、管用户、维护基础数据。你把角色列出来后面设计权限和菜单就清晰了。功能清单要落到“动词 对象”的粒度。别只写“设备管理”四个字就完事要拆成新增设备、编辑设备、停用设备、按名称/类型模糊查询、导出设备清单。这个清单后面有两个大用处一是核算开发量如果发现功能点超过40个就主动砍掉低频功能二是直接作为论文里“系统功能结构图”的原始素材。核心业务规则是你最容易漏掉的部分。比如预约能不能取消、取消后设备是否立即释放、一个时间段能不能被多个人同时预约、设备故障谁来标记。这些规则不提前想清楚编码阶段写出来的逻辑必然来回改。我的习惯是用文字把核心流程走一遍比如学生提交预约 → 系统检查设备状态和时段冲突 → 预约变为待审核 → 教师通过后变为已预约 → 学生使用完毕点击归还 → 设备状态恢复空闲。流程走通之后再画ER图、建表后面开发就顺畅得多。1.3 技术栈选型为什么是这套“黄金组合”现在毕业设计用的技术栈我几乎无脑推荐Spring Boot MyBatis-Plus MySQL Vue这套组合。原因不是它最炫而是它综合考虑了开发效率、学习成本、资料查询便利性和答辩说服力。对比维度JSP/Servlet 老套路Spring Boot 全家桶微服务分布式开发效率低重复代码太多高约定大于配置中基建成本高学习曲线平缓但过时平缓中文资料极多陡峭需要分布式基础答辩说服力容易被质疑技术旧贴近当前企业主流答不好会显得空洞工作量风险功能简单但论文单薄可控功能与深度平衡单体都搞不定就别碰选这套组合有一个额外的好处招聘市场上Java后端岗位的要求基本就是围绕这个技术体系展开的。你做完这个毕设简历上多了一个“基于Spring Boot的XXX系统”面试被问到的概率非常高而且你踩过的每个坑都可能成为面试时的“项目难点”。JDK版本方面如果不是学校有硬性要求直接用JDK 8或者JDK 17都没问题。JDK 8胜在兼容性绝大多数教程都基于它JDK 17是长期支持版本性能更好。注意不要用太新的版本比如JDK 21虽然已经发布但有些第三方依赖还没有完全适配毕设阶段不必给自己增加这种无谓的兼容性风险。开发工具这块我建议IntelliJ IDEA学生可以申请教育授权免费使用也可以直接用社区版日常开发完全够用。没必要纠结破解版的问题把精力花在项目本身上。Maven是必须的依赖管理和打包都靠它。数据库客户端我推荐Navicat或者DBeaver看你个人习惯。2. 开发环境准备与工程搭建2.1 JDK、IDE、Maven的配置细节先说JDK环境变量。我知道很多同学在第一步就卡住了其实原理非常简单。JAVA_HOME指的是JDK安装目录比如C:\Program Files\Java\jdk-17然后在Path里加入%JAVA_HOME%\bin。为什么大家都让你配JAVA_HOME而不是直接把bin目录加进Path因为以后你要换JDK版本时只需要改JAVA_HOME一个变量Path里的配置不用动。Maven的配置点有两个一是本地仓库路径二是镜像源。本地仓库默认在C盘用户目录下的.m2文件夹建议改成其他盘避免C盘越来越肿。镜像源直接用阿里云的在settings.xml里加一段mirror配置否则国内网络从Maven中央仓库拉依赖会让你怀疑人生。mirror idaliyunmaven/id mirrorOfcentral/mirrorOf namealiyun maven mirror/name urlhttps://maven.aliyun.com/repository/public/url /mirrorIDEA里创建Spring Boot项目时默认走的start.spring.io在国内经常超时。解决办法是在Spring Initializr配置里改成阿里云的地址https://start.aliyun.com。这一步能帮你省下很多无意义的等待。还有一个很容易忽略的配置字符编码。我强烈建议把IDEA的GlobalEncoding、Project Encoding、Properties Files编码全部设为UTF-8否则后面写个中文注释都能乱码更别提页面传参时中文乱码了。如果你用VSCode跑Java项目遇到乱码多半也是编码没统一的问题先检查控制台编码和文件编码是不是一致再检查编译选项里有没有强制指定-Dfile.encodingUTF-8。2.2 工程结构与第一个接口项目创建成功后先别急着写业务。我习惯的包结构是固定的顺序和分窗口如下com.xxx.system ├── common // 公共类统一返回体、异常处理、工具类 ├── config // 配置类分页插件、CORS、拦截器注册 ├── controller // 接口层接收参数、返回结果 ├── entity // 实体类对应数据库表 ├── mapper // 数据访问层MyBatis-Plus的Mapper接口 ├── service // 业务层核心逻辑 │ └── impl └── vo // 视图对象给前端返回的数据结构这个结构的核心思想是分层各层职责单一出了问题好定位答辩时也好讲。Controller只做参数接收和结果封装业务写在Service里数据库操作在Mapper层。很多同学图省事把业务全堆在Controller里短期内代码能跑但一旦业务复杂Controller会膨胀到几百行后期调试非常痛苦。搭好结构后先写一个最简单的接口验证环境是通的。在Controller里加一个/hello接口返回“Hello from Spring Boot”。然后启动项目访问http://localhost:8080/hello看到返回结果说明基础链路没问题。接下来配置数据库连接。在application.yml里写上数据源信息server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/your_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: your_password driver-class-name: com.mysql.cj.jdbc.Driver注意MySQL 8以上驱动类名是com.mysql.cj.jdbc.Driver老写法com.mysql.jdbc.Driver在新版本里已经废弃了。serverTimezone参数建议写Asia/Shanghai否则可能报时区错误。这里有个小技巧端口尽量不要用8080因为本地开发经常碰到端口被占用的问题。我一般改成8081或者8090省心很多。3. 数据库设计ER图、表结构与数据文档3.1 从需求到ER图很多同学图省事建表之前跳过ER图直接开写SQL结果表建到一半发现关系理不清后面改表结构比重新来一遍还痛苦。ER图是需求到表结构之间的桥梁画清楚了建表就是照图施工。ER图的核心就三件事实体、属性、关系。实体对应表属性对应字段关系对应外键或者中间表。以二手交易系统为例实体至少有用户、商品、订单、收藏、留言。商品属于用户这是一对多订单包含商品这是一对一或一对多用户和商品之间通过收藏产生多对多多对多就要拆出一张收藏中间表带收藏时间和状态字段。关系判断有一个实用技巧先问“一个A能对应几个B”再问“一个B能对应几个A”。两边都是一就是一对一一边是一一边是多就是一对多两边都是多就必须拆中间表。中间表两边各带一个外键还可以扩展业务字段。画图工具我用过ProcessOn、draw.io、visio都可以。最终交付的时候ER图要放进论文里所以画得规范一些每个实体标注主键和关键字段关系线上标注1和N。不要用一张截图的模糊图糊弄过去答辩老师是真的会看细节的。3.2 数据表设计的几个关键细节表结构是系统的地基建表时踩的坑后面几乎都会变成Bug。我给你列几个最重要的细节。命名规范上表名和字段名都统一用下划线小写风格比如user_info、order_detail。这既是行业惯例也是MyBatis-Plus驼峰映射的默认约定数据库create_time对应实体类createTime省去一堆手写映射。主键策略方面单体毕设项目用数据库自增id就够了简单可靠。表关联时注意主键和对应外键的类型必须完全一致比如都是bigint否则关联查询会踩到隐式类型转换的坑数据量一大性能就崩。字段类型的选择值得单独说说。金额一定用decimal不要用float或double二进制浮点计算金额会产生精度问题这是做支付相关功能的大忌。状态字段用tinyint比如0表示禁用、1表示启用并在字段注释里写清楚每个值的含义。时间字段用datetime如果业务需要记录更新时间加上ON UPDATE CURRENT_TIMESTAMP。还有两个“习惯性字段”我强烈建议加上create_time创建时间和update_time更新时间。后面写论文的测试记录、做数据统计、排查线上问题都需要它们。逻辑删除字段deleted也建议留下用0和1标记避免真正删数据后无法追溯。索引这块只要记住一个原则查询频繁的字段加索引修改频繁的字段少加索引。where条件里高频出现的字段比如订单表的user_id、商品表的type_id直接加上普通索引。至于外键约束很多企业级规范都建议在业务层维护逻辑关系不在数据库层面硬加物理外键尤其是并发量上来之后物理外键会影响插入性能。毕设阶段你可以不建物理外键但ER图上还是要把逻辑关系画清楚。3.3 自动生成数据库设计文档论文里的“数据库设计”章节需要把每张表逐字段写清楚几十张字段表手敲Word相当浪费时间。我的做法是直接从MySQL元数据里查生成结构化数据再整理成表格。下面这条SQL会把你指定库里的所有表名、字段名、类型、是否为空、键、注释一次性拉出来SELECT table_name AS 表名, column_name AS 字段名, column_type AS 字段类型, is_nullable AS 是否为空, column_key AS 键, column_comment AS 字段说明 FROM information_schema.columns WHERE table_schema 你的库名 ORDER BY table_name, ordinal_position;查询结果粘贴到Excel里按表名和字段顺序整理再逐表截图或者复制到Word里配上字段说明一份规范的表结构文档就完成了。整个过程不会超过半小时比对着建表语句一条条复制高效太多。如果还想要带表关系说明的完整文档可以用开源工具比如Screw它支持从数据库直接导出数据库设计文档格式比手写的整齐放在论文附录里很加分。注意不要过度依赖工具生成的内容论文里对核心表的设计思路还是要自己写一段话解释体现你真的思考过。4. 核心模块实现登录、权限与业务功能4.1 分层架构与代码组织到了编码阶段第一件事是定好统一返回体和全局异常处理这两样决定了整个项目代码写起来是否干净。统一返回体一般长这样Data public class RT { private Integer code; private String msg; private T data; public static T RT ok(T data) { RT r new R(); r.setCode(200); r.setMsg(success); r.setData(data); return r; } public static T RT fail(String msg) { RT r new R(); r.setCode(500); r.setMsg(msg); return r; } }所有接口都返回RT类型前端拿到code200就知道业务成功否则弹出msg里的错误信息。这样既统一了前后端对接协议也避免了每个方法里手动拼装Map返回的痛苦。全局异常处理用RestControllerAdvice标注一个类针对业务异常、参数校验异常、兜底异常分别写处理方法。没有它只要代码里抛出异常前端收到的一定是一堆看不懂的堆栈信息用户体验极差而且答辩演示时万一操作失误页面会直接暴露错误堆栈非常难看。业务逻辑写在Service层Controller只做三件事解析参数、调用Service、返回R。这个约束看起来简单但坚持下来项目结构会越来越好维护。实体类Entity对应数据库表字段不要把前端需要展示但数据库里不存在的内容硬塞进去额外的数据用VO承接这样写出来的代码层次清晰答辩时被问到模块划分也能讲得头头是道。4.2 登录与权限Session还是JWT登录认证是所有业务系统的入口也是答辩时老师喜欢追问的部分。毕设阶段最常见的方案有两种传统的Session登录和现在主流的前后端分离式JWT认证。如果你做的是前后端不分离、页面直接由后端渲染的项目用Session完全够用逻辑上也简单。但如果你的前端是Vue独立部署、通过接口调后端我推荐用JWT。原理一句话就能讲清楚用户登录成功后服务端签发一个带签名和过期时间的token返回给前端前端每次请求在请求头里带上这个token后端拦截器校验token合法则放行不合法则返回401。拦截器是JWT认证落地的关键核心代码长这样public class JwtInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (OPTIONS.equalsIgnoreCase(request.getMethod())) { return true; } String token request.getHeader(Authorization); if (StringUtils.hasText(token) JwtUtil.isValid(token)) { return true; } response.setStatus(401); response.getWriter().write({\code\:401,\msg\:\未登录或token已过期\}); return false; } }注册拦截器时要放行登录接口、验证码接口、静态资源路径其他接口全部拦截。很多同学第一次写这里会漏了放行登录取导致前端还没拿到token就被拦了排查半天才发现。密码存储方面我建议至少用BCrypt做哈希处理Spring Security的spring-security-crypto包里直接有工具类引入依赖后几行代码就能完成加密和校验。千万不用MD5现在MD5撞库太容易了论文里写“MD5加密存储”属于减分项答辨时被问到密码安全性基本答不上来。JWT方案还有一个容易忽略的细节token过期时间。我见过挺多毕设把过期时间设成7天甚至30天理由是“这样用户不用老登录”但从安全角度讲非常不合适一般2到12小时比较合理。如果担心频繁过期体验差可以做刷新token机制不过毕设阶段2小时过期已经够用别过度设计。4.3 分页、文件上传等高频功能落地业务系统里出现频率最高的三个功能是分页查询、文件上传、数据导出。这三个功能单独看起来不难但做不好会在答辩演示时翻车。分页查询用MyBatis-Plus自带分页插件配置一个分页拦截器即可Configuration public class MybatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }查询接口接收pageNum和pageSize两个参数Service层用LambdaQueryWrapper构造条件最后调用page方法返回分页结果。注意返回给前端的数据要包含总记录数和总页数前端表格组件才能正确渲染页码。文件上传的坑集中在三个方面文件命名、存储路径、访问方式。前端传过来的文件名一定要重命名最简单的是用UUID加时间戳拼一个新名字避免中文乱码和重名覆盖。存储路径不要直接写死绝对路径可以在配置项里维护一个file.upload-dir方便部署环境切换。访问方式建议通过Controller写一个静态资源映射接口来获取文件这样对前端友好也方便后面做权限控制。导出功能的性价比之王是EasyExcel它和MyBatis-Plus是同一个团队维护的API风格一致导出Excel只需要在实体上标注ExcelProperty(列名)然后一行代码就能生成文件。毕设里做统计报表导出时这个库能帮你省下大量时间论文里写“基于EasyExcel实现报表导出”也有一定的技术含量。5. 测试、打包与部署上线5.1 本地测试与接口调试项目开发完成后千万不要急着打包部署。先在本地把核心接口完整测一遍这一步能发现至少一半的隐藏Bug。接口测试我推荐用Apifox或Postman这类可视化工具把登录、增删改查、分页、文件上传、权限拦截这几个核心场景全部跑一遍。不要一个接口一个接口孤立地测要模拟真实业务链路。比如测试预约流程登录获取token → 提交预约 → 管理员审核 → 用户确认使用 → 归还设备——这条链路走通了系统才算真正可用。事务问题是Service层最容易犯的错。比如预约成功之后既要插入预约记录又要更新设备状态如果第二步抛异常而第一步已经执行数据库就会出现脏数据。解决办法是在Service方法上加Transactional注解让两步操作处于同一个事务里出错时自动回滚。这里有个小坑Transactional默认只回滚运行时异常如果方法里捕获了异常但没有重新抛出事务是不会生效的很多人在这个问题上栽过。日志这块我也多说一句不要用System.out.println代替日志框架。Spring Boot自带Logback在application.yml里配好日志级别和日志文件路径业务关键节点打上info日志异常栈打成error日志。答辩演示时如果系统出了问题一个清晰的日志直接定位到代码行会显得你很专业。5.2 服务器部署与公网访问本地测试通过后下一步是部署到服务器让系统可以远程访问。这一步的核心目标不是让你学会复杂的运维而是让答辩时老师能通过浏览器看到你的系统。先用Maven把项目打包成可执行的jar包mvn clean package -Dmaven.test.skiptrue打包产物在target目录下名字类似xxx-0.0.1-SNAPSHOT.jar。把它上传到服务器在jar包所在目录执行nohup java -jar xxx-0.0.1-SNAPSHOT.jar app.log 21 nohup保证进程在SSH断开后依然运行 app.log 21把日志写到文件这个命令是部署jar包最基本的形式。如果想更规范一点可以写一个systemd服务文件支持开机自启和异常自动重启不过毕设阶段用nohup就够了。部署后访问不了90%的原因出在三个地方。第一端口没放行。云服务器的安全组规则里要允许你配置的端口入站同时服务器防火墙也要放行比如CentOS上执行firewall-cmd --add-port8081/tcp --permanent然后reload。第二数据库连接被拒绝。线上MySQL默认只监听本地回环地址而且root用户默认只能在服务器本地登录需要创建一个允许远程访问的账号。第三JDK环境不一致本地用的17服务器装的是8启动直接报UnsupportedClassVersionError上传jar包前先确认一下服务器上的Java版本。如果是前后端分离项目推荐用Nginx把前端打包后的dist目录托管起来同时配置反向代理把/api开头的请求转发到后端的Java服务。这样做的好处是一举两得解决了前后端跨域问题也避免了前端直接暴露Java服务的端口安全性和美观性都更好。server { listen 80; server_name your.domain.com; location / { root /opt/frontend/dist; index index.html; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8081; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }6. 论文撰写、答辩准备与常见问题排查6.1 把项目变成论文系统做完了论文写不出来是另一种意义上的白干。其实论文和质量报告没有本质区别你的开发和设计过程就是最核心的素材不需要虚构。论文的结构一般固定在七个章节摘要、绪论、需求分析、系统设计、系统实现、系统测试、总结。对应关系很清楚需求分析写你前期的角色清单和功能清单系统设计写ER图、表结构、架构图系统实现写每个核心模块的关键代码和截图系统测试写测试用例和执行结果。只要开发过程有记录论文就等于把每个环节写清楚。截图是个容易被忽略的加分项。不要只截整个页面的大图要“关键步骤分段截”新增用户弹窗填完数据、保存成功后的列表刷新、删除操作前的确认框、权限拦截时的提示信息——这些细节截图放进去论文显得饱满答辩讲起来也有抓手。测试部分必须要有测试用例表格式大概是用例编号、测试功能、操作步骤、预期结果、实际结果、是否通过。不用写几十条核心模块每个写3到4条重要的就够了重点突出你系统里争议最大、最容易出错的功能点这恰恰证明你认真测过。6.2 答辩现场“怎么问都不慌”答辩答辩答而不辩是原则并不意味着你可以不准备。老师大概率会从三个方向发问为什么用这个技术、某个功能怎么实现的、你目前有什么不足。“为什么用这个技术”最常出现在技术栈选型上。比如“Spring Boot和传统Spring有什么区别”你要能说出自动化配置内嵌服务器等关键点。这个环节本质就是一场简化版的Java面试很多常问内容跟面试八股文高度重合。比如老师顺着Spring Boot可能问到IOC容器再问到AOP底层那动态代理就绕不开JDK动态代理基于接口CGLIB基于继承Spring在类实现接口时优先用JDK代理否则用CGLIB代理。能讲到这里老师对你的评价会明显上一个档次。“某个功能怎么实现的”最好提前准备一个“亮点小故事”。选出系统里最有技术含量的功能比如“多条件联合分页查询如何避免SQL注入”“设备预约的冲突检测如何防止并发下超卖”“文件上传如何防止非法文件类型”。每个功能按“需求背景 → 实现思路 → 核心代码 → 遇到的问题 → 如何优化”这个套路讲五分钟不用背稿子把开发时的真实思考和踩坑经历讲出来就很有说服力。“你目前有什么不足”这种问题是送分题不是送命题。千万不要说“我这个系统没有不足”而是坦诚地说“目前系统在并发性能上还有优化空间如果数据量上来可能需要引入缓存来解决热点数据的读压力”——这个回答既显得你有自省能力又顺带展示了你对系统扩展路径的理解。6.3 常见问题速查表最后整理一份毕设开发阶段我见过最多的高频问题速查表遇到故障直接对照排查。问题现象常见原因解决办法启动报“Access denied for user”数据库账号密码错误或权限不足检查账号密码用授权SQL给用户分配访问权限中文数据乱码项目编码、数据库编码、连接参数不一致统一为UTF-8连接URL加characterEncodingutf8端口被占用其他程序占了端口换一个端口Windows下用netstat -ano查进程并结束Maven依赖下载慢或失败默认中央仓库网络不稳定替换阿里云镜像删除本地仓库不完整的lastUpdated文件重试接口报跨域前后端域名或端口不同后端配置CORS拦截器或改成Nginx反向代理找不到Mapper对应方法MapperScan遗漏、xml namespace错误启动类加MapperScan检查xml命名空间和mapper接口包路径JSON序列化无限递归实体类多对多关系互相引用对关联属性加JsonIgnore或者返回统一VO对象前端传参后端全是nullJSON键名和下划线/驼峰不匹配后端使用RequestBody接JSON对象确认前端字段名和后端属性名一致这块我是真心有体会。这套速查表里的每一行几乎都是我当年做项目时熬夜排查出来的记录。毕设就是这样一个过程看起来是写一个系统实际上是把需求分析、工程规范、数据库设计、框架运用、测试部署、技术表达这些能力全部串联起来走一遍。走完这一遍再回头看“Java系统开发”这个概念你会发现自己已经不再是只会跟着教程敲代码的阶段了。我个人的一个小习惯在最后分享给你从项目第一天开始每天做一次Git提交commit message写清楚今天完成了哪个模块。写论文时需要还原开发过程的时候直接把提交记录拉出来筛选一遍时间线和功能对应关系一目了然比翻聊天记录找进度舒服太多了。而且答辩时如果老师问“这个项目你做了多久、怎么推进的”你能报出一次提交树就足以证明这确实是亲手做出来的东西。祝顺利。
返回列表