
小微便利店的运营系统在毕设选题里算是一个常青树了。每年都有大量学生选类似题目但真正能把一个收银、库存、会员、报表完整闭环跑通的并不多见。标题里这几个关键词——SpringBoot、Vue.js、前后端分离、社区零售店铺智能管理平台几乎把技术栈和业务场景都点透了。我做过好几个类似的模拟项目今天就把这类系统从需求拆解、数据库设计、核心模块实现到联调排坑的完整过程按我的实操经验捋一遍给正在做或者准备做这个方向的同学一个可以直接参考的底稿。先说这个系统到底适合谁。如果你是计算机相关专业的毕业生需要一个技术栈主流、业务逻辑完整、演示效果直观的项目来应对毕设答辩这类“小程序/管理系统”方向就很合适。它不追求算法深度但覆盖面广后端有事务、权限、数据建模前端有组件化、状态管理、可视化图表联调中有跨域、鉴权、并发等真实问题。把这些讲清楚答辩时比一个花哨但单薄的微服务项目更能撑住场面。1. 项目拆解这个便利店系统到底在解决什么问题1.1 小微便利店的经营痛点很多没去过便利店后台的人会以为小店老板只需要摆摆货、收收钱。实际上一个小微便利店日常面对的问题比我一开始想象的复杂得多。商品SKU通常几百到上千饮料、零食、日化、烟酒、冷冻食品混在一起进货周期短则两三天长的可能一个月。靠手工本子记账、靠脑子记价格的店主并不少见但一旦遇到促销、临期处理、供应商退换货账目就容易乱成一团。库存积压和缺货是最典型的矛盾。热销商品补货不及时一天要少卖几十单而滞销品一进就是整箱堆在仓库里占用资金还面临过期报废。生鲜和短保商品的损耗更是绕不开的痛点。再加上会员积分、满减优惠、储值余额这些营销玩法靠Excel表格管理已经力不从心了。所以一个小微便利店运营系统本质上不是做一个“高级进销存”而是把进货、库存、销售、会员这些日常动作变成一条顺畅的数据流。这是我在设计整个系统时始终盯住的主线。1.2 系统核心价值与功能边界这套系统的价值在于让店主用最低成本完成数字化。不需要收银机硬件一台普通电脑或者平板打开浏览器就能收银不需要专业财务知识报表直接告诉你今天卖了多少、毛利多少、哪些商品该补货、哪些商品该清仓。功能边界上我建议控制在六个核心模块内商品管理、库存管理、收银台、会员管理、供应商与进货管理、经营统计。再往外延伸的采购审批、多门店调拨、员工排班都不建议在毕设中碰因为一旦做进去系统的复杂度会成倍上升而答辩时间有限根本展示不完。请记住一个原则毕设项目的完成度远比功能数量重要一个闭环的麻雀系统比一个处处破洞的老鹰系统更有说服力。1.3 用户角色与权限模型便利店系统里至少有店主和店员两类角色。店主关心的是经营数据、进货审批、商品管理权限店员日常只需要开单收银、查看库存、操作会员充值。因此用户表里需要一个角色字段或者维护一张简单的权限表通过后端拦截器控制接口访问。不用设计得太细一个角色字段加多个权限接口校验在毕设阶段已经绰绰有余了。这里有个小提醒很多同学做这类系统时会一上来就设计五张表以上的权限模型用户表、角色表、菜单表、权限表、用户角色关联表、角色菜单关联表但便利店业务里根本没有复杂的组织层级。过度设计会让代码体量暴涨却不能在答辩中体现出业务理解。用简单的角色判断反而更容易把每个接口的权限逻辑说清楚。2. 技术选型SpringBoot与Vue.js为什么这么契合2.1 后端选型的底层逻辑Java生态里做一个管理后台最常见的组合就是SpringBoot加MyBatis或者MyBatis-Plus。SpringBoot的价值在于“约定优于配置”内嵌Tomcat、自动装配Starter把过去SpringMVC时代繁琐的XML配置全部简化掉了。对毕设而言这意味着你可以把大量时间花在业务逻辑上而不是浪费在配置文件的坑里。有人会问现在Spring Cloud微服务这么流行能不能用我不建议。微服务是分布式场景下的解决方案一个单体便利店系统用微服务拆纯粹是给自己挖坑。服务拆分后要处理服务注册、配置中心、分布式事务、链路追踪每一个都是无底洞而且对答辩来说单体应用的事务处理反而更容易讲清楚“下单扣库存”这类核心业务。选MyBatis-Plus比原生MyBatis舒服很多代码生成器能一键生成实体类、Mapper、Service分页插件、逻辑删除、自动填充这些高频需求都有现成方案。答辩时如果被问“为什么用这个”直接说是为了提高开发效率、减少重复代码同时保留手写SQL的灵活性比如后面要讲到的乐观锁扣库存MyBatis-Plus照样可以写自定义SQL。2.2 前端组件化开发的优势Vue.js做管理系统核心优势有两个组件化和数据响应式。拿收银台举例左侧商品列表、右侧购物车结算区、顶部搜索栏每个区域都是一个独立组件各自维护自己的数据状态。商品数量变化时购物车总金额自动重新计算这就是数据响应式带来的开发效率提升——不需要手动操作DOM去更新价格文本。搭配Element UI这类组件库后台管理页面在很短时间内就能拼出来。表格、表单、对话框、日期选择器、分页组件全部现成样式统一且美观。如果你手动写CSS去实现一个数据表格光排序、筛选、分页交互就够折腾好几天。Vue生态里的Vuex或Pinia做全局状态管理登录用户信息、购物车状态都可以放在里面跨组件通信不再需要事件总线那套绕来绕去的方式。也有同学纠结要不要用React。如果团队里没人熟悉React选Vue更稳妥。Vue的中文文档和社区资料丰富遇到问题能快速查到答案模板语法对新手友好这对需要赶进度的毕设来说太重要了。2.3 前后端分离的核心收益前后端分离是一个经常被写进标题但很多人说不清的技术点。它指的是前端和后端不再由服务端渲染模板比如JSP糅合在一起而是前端通过HTTP接口以JSON格式获取数据各司其职、独立部署。这个架构对毕设最直接的好处就是前后端可以并行开发、分开调试。后端同学专注写接口用Swagger或Knife4j生成接口文档前端同学对着文档开发页面用Mock数据模拟后端返回不再互相阻塞。部署上前端打包成静态文件扔到Nginx后端打成Jar包运行两端互不影响。如果做的是前后端不分离的JSP项目一个小问题就要前后端串起来排查开发体验会比较痛苦。从答辩角度讲前后端分离也踩中了当前企业级项目的主流架构。面试官或答辩老师大概率会问“为什么不用JSP”这时候你回答“JSP由服务端渲染前后端职责不清不利于多端复用和并行开发而前后端分离可以天然支持后续的小程序端、移动端接入”这句话本身就是加分项。3. 数据库设计便利店业务的数据地基3.1 核心表结构与字段细节我设计这种系统时数据库表一般控制在十张左右用户表、角色表、商品表、商品分类表、库存表也可以合并进商品表、供应商表、进货单表、进货单明细表、会员表、订单表、订单明细表、积分记录表。每张表都要想清楚两个问题这个表解决什么业务表和表之间怎么关联以商品表为例最核心的字段是这些商品编码条码、名称、分类ID、规格、进货价、零售价、会员价、当前库存、预警库存、状态上架/下架、图片URL、创建时间、更新时间、逻辑删除标记。这里有两个点特别容易踩坑。一个是价格字段一定要用decimal不要用float或double否则会出现0.1加0.2不等于0.3这种浮点精度问题金额一旦算错整个系统就不可信了。另一个是库存字段是独立成表还是放在商品表里我建议独立出一张库存表因为在后续做入库流水和库存变动记录时这种拆分能保住数据流的完整闭环。3.2 订单与库存的数据流建模订单相关的表设计是系统的大脑。订单主表保存整笔交易的汇总信息订单号、收银员ID、会员ID可空、商品总金额、优惠金额、实付金额、支付方式、支付状态、下单时间。订单明细表则逐条记录每个商品的快照商品ID、商品名称、单价、数量、小计。为什么要存商品名称快照因为商品名称和价格以后可能调整而订单作为历史凭证必须留住交易发生时的样子。这个细节在答辩时随口说出来老师会觉得你真的理解业务。库存变动如何建模是整个系统最关键的数据流设计。我采用的方案是“进货单增加库存、销售订单扣减库存、手动调整走盘点单”。这样一来任何一次库存变化都有据可查不会出现库存数字跳变却找不出原因的情况。进货单分为主表和明细表主表记录供应商、进货总金额、进货日期明细表记录每个商品的进货价、数量、生产日期和保质期。有了这个结构后续做临期商品提醒、毛利核算都非常方便。这里我得强调一个毕设中常见的错误直接在商品表里改库存字段没有任何流水记录。短期看能跑通但一旦被老师追问“你如何追溯这个商品的库存为什么变了”局面就会比较尴尬。补一个库存变动日志表记录变动类型入库/销售/盘点/报损、变动前数量、变动后数量、关联业务单号这个设计瞬间就能提升系统的专业度。3.3 索引设计与数据一致性考虑数据库表结构确定后索引不能乱建但也不能不建。订单表要按照下单时间查日结报表所以下单时间字段需要加索引商品表按照条码精确查询条码字段必须建唯一索引这是收银台扫码时的查询主路径会员表按手机号登录或者查询手机号字段也要唯一索引。但索引不是越多越好每张表的索引控制在三到四个以内就够了否则插入和更新时索引维护成本会拖慢性能。这是我在调优实测中得出的感受便利店系统的数据量远未达到需要复杂索引调优的程度合理够用就行。数据一致性上最核心的就是事务。下单操作涉及多张表变更——校验库存、创建订单主表、创建订单明细、扣减库存、更新会员积分任何一步失败都不能让其他步骤生效。所以下单接口必须整体包裹在事务里一旦出现异常就整体回滚。我在后面第四章会贴出核心代码来说明这个事务怎么写。4. 核心功能模块实现解析4.1 商品管理与库存预警商品管理模块是整个系统的数据源头。前端页面一般是一个表格加搜索栏支持按名称、分类、条码筛选右上角是新增和导入按钮。新增商品表单里要校验条码唯一性、价格必须大于等于零、库存不能为负数。后端接收请求时不能只依赖前端校验必须再次校验因为接口可以被直接调用绕过前端是常规操作。库存预警是这类系统里很有展示价值的模块。实现逻辑并不复杂库存表里有一个预警阈值字段每次库存变动后判断当前库存是否小于预警阈值如果小于就生成一条预警记录在首页醒目的位置展示哪些商品需要补货。预警阈值的设置可以根据商品的销售速度来滞销品阈值设低一点热销品阈值设高一点。我在实际测试中发现把阈值设成“该商品近7天日均销量乘以补货周期”会更合理。举个例子某种饮料平均每天卖10瓶供应商送货周期是2天那预警阈值就是10乘以2再加一个安全缓冲比如25瓶低于这个数就应该触发补货提醒。这个计算逻辑不算复杂但能体现你对业务的理解不是简单拍脑袋定一个固定数字。商品图片上传也是一个容易卡住的地方。本地存储时要注意服务器重启后临时目录会被清空图片就丢失了。毕设项目可以直接把图片存到项目的静态资源目录或配置一个独立的上传目录后端返回可访问的URL前端直接展示。如果为了省事也可以给商品表增加一个图片URL字段前端用图床或Base64直接存储但Base64会让数据库膨胀不推荐。4.2 收银台与订单流转收银台是整个系统里最核心也最出彩的页面。理想的交互流程是焦点自动落在扫码框扫到商品条码立刻加入购物车、自动播放一声提示音然后继续扫下一件不需要每次点按钮。购物区显示当前商品列表数量可加减支持手动删除。结算时选择会员非必填、录入实收金额自动计算找零点击结算后弹出支付结果界面。后端的订单接口我按下面的流程设计Transactional(rollbackFor Exception.class) public Order createOrder(CreateOrderRequest request) { // 1. 校验参数商品列表不能为空数量必须为正整数 // 2. 遍历商品明细查出当前库存逐个校验库存是否充足 // 3. 计算商品总金额如果选中的是会员应用会员价或折扣 // 4. 生成订单主表记录状态设为“已支付”生成订单号 // 5. 批量插入订单明细表 // 6. 执行库存扣减SQL更新库存表中的库存数量 // 7. 如果使用了会员更新积分、累计消费金额 // 8. 返回完整的订单对象给前端 }这里最关键的是第6步的库存扣减它必须依赖数据库层面的原子操作来完成。正确写法不是“先查询库存判断大于0再更新库存”因为两个并发请求同时查到的库存可能都是1然后各自判断满足条件都执行更新结果库存变成-1超卖了。正确做法是用一条带条件的UPDATE语句让扣减和判断在数据库层面原子完成UPDATE inventory SET stock stock - #{count} WHERE goods_id #{goodsId} AND stock #{count}这条SQL执行后如果返回的影响行数为0说明库存不足直接抛出库存异常的提示并回滚整个事务。这个方案对便利店这种低并发场景完全够用也是面试官最想听到的答案。订单号生成也有讲究。时间戳加随机数容易出现重复用数据库自增主键当订单号又太容易泄露业务量。我习惯用年月日时分秒加四位随机数的组合例如“202506141530001234”再加上前端展示时分段显示效果比较自然。如果要求更严格的全局唯一可以用雪花算法但毕设没必要引入额外依赖。4.3 会员管理与积分体系会员模块的设计直接关系到一个便利店的复购率。系统里会员表至少要有会员卡号、手机号、姓名、积分余额、储值余额、累计消费金额、等级、开卡时间。积分规则一般是消费1元积1分100积分抵1元现金结账时收银员询问是否使用积分抵扣这个过程在系统里要能灵活配置不能写死在代码里。正因如此我建议设计一张系统配置表把积分兑换比例、满减门槛这些规则参数化。这个细节做出来以后演示时告诉老师“营销规则是动态配置的业务人员不需要改代码就能调整活动力度”通常能拿到不错的评价。会员开卡流程也要设计得顺滑。收银台结账时如果顾客想办会员直接输入手机号系统自动判断是否已存在不存在就创建一个新会员并默认设置初始积分已经存在就调出会员信息并绑定到当前订单。这里要特别注意手机号的格式校验前端加正则后端再校验一遍避免脏数据进库。储值功能考虑起来会复杂一些。储值相当于预付款涉及资金安全毕设里可以只做余额增减的流水记录不做真正的支付对接。充值时要记录充值流水消费时要记录消费流水会员详情页显示余额及最近流水列表。这里我又要强调一次流水表的重要性只要涉及钱的变化就必须有记录否则账对不上。4.4 经营统计与报表展示统计报表是给店主用的核心价值模块也是答辩演示时最直观的效果页面。主流的做法是首页放一组关键指标卡片今日销售额、今日订单数、本月毛利、库存预警数量下面用折线图展示最近7天的销售趋势用柱状图展示商品销量排行Top10用饼图展示不同品类销售占比。这些图表用ECharts实现非常快后端只需提供对应的统计数据接口。比如近七日销售趋势接口一次查询返回过去7天的日期和对应销售额前端直接塞进折线图。商品销量排行则按订单明细表聚合按商品ID分组后求销售数量总和再关联商品表返回名称排序后取前十条。在实现层面有个取舍要说清楚是实时聚合查询还是定时任务先把统计结果算好存一张统计表。便利店系统的订单数据量一天可能就几百条实时聚合完全没有性能压力直接查就行代码简单且数据永远是最新的。但如果做的是百万级数据量的大型平台才需要考虑数据仓库、离线计算、预聚合这些重型方案。毕设阶段别给自己加戏实时查询加数据库索引已经足够和老师解释清楚这个取舍背后的原因反而显得你有架构思维。报表接口要注意做空值处理。某一天没有订单销售额就返回0不能是null否则前端折线图会断线。商品销量排行为空时返回空数组前端图表也要正常渲染。这些边界情况是测试中容易忽略的但答辩演示时一旦出现空白页印象分会大打折扣。5. 前后端联调与问题排查实录5.1 跨域问题处理环境准备前端开发服务器跑在8080端口后端接口服务跑在8081端口浏览器打开前端页面时页面向8081端口发请求这就构成了跨域请求。浏览器默认会拦截这种跨域请求控制台会报经典的CORS错误。这几乎是我见过的、前后端分离项目里最先出现的拦路虎也是每次答辩老师必问的风险点。解决方式常见的就两种。第一种是开发环境用前端代理在Vue的配置文件里配置devServer.proxy把含“/api”前缀的请求转发到后端地址这样浏览器看到的请求始终是同源的自然不存在跨域问题。配置非常简单// vue.config.js module.exports { devServer: { proxy: { /api: { target: http://localhost:8081, changeOrigin: true } } } }第二种方式是后端直接开启CORS在SpringBoot里写一个配置类允许指定来源的跨域请求。这种方式在生产环境也能用但要注意只开放你信任的前端地址不要用“*”通配符允许所有来源否则任何网站都能调用你的接口存在安全风险。我实际测试下来的感受是开发环境首选代理方案它不需要修改后端代码如果后端部署到服务器后还要让前端跨域访问那就用后端配置CORS或部署Nginx反向代理。把这个取舍过程梳理一遍比背一个答案更能应对老师的追问。5.2 登录态与权限校验前后端分离架构下Session不再是默认选择。因为前端和后端可能不在同一个域名下SessionId的传递要么依赖浏览器自动携带Cookie要么需要手动处理而跨域时Cookie的携带机制被浏览器严格限制麻烦不断。更主流、也更适合毕设讲解的方式是用JWT做Token认证。JWT由三部分组成Header声明类型和加密算法、Payload存放用户ID、用户名、过期时间等信息、Signature对前两部分签名防止篡改。后端登录成功后签发一个Token返回给前端前端存在localStorage之后每次请求都在请求头里带上“Authorization: Bearer 你的Token”。后端写一个拦截器在请求到达Controller之前校验Token是否有效、是否过期。这个机制本身不复杂但落地时有几个细节必须注意。第一个细节是过期时间的处理。Token过期后前端拿到的响应是401状态码此时页面要跳回登录页。这个能力不能光靠后端实现前端要在axios的响应拦截器里统一判断状态码为401时清除本地Token并跳转到登录页。很多同学只做后端拦截器忘记前端拦截就会出现用户Token过期后页面一直报错却不跳转登录页的尴尬情况。另一个细节是静态资源的放行。登录页、注册接口、验证码接口这些路径不能拦截否则未登录用户无法访问登录页。所以拦截器里要配置白名单或者用注解方式标记哪些接口不需要认证。public class JwtInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 从请求头中取出Token校验签名和有效期 // 通过则放行并将用户ID存入Request上下文 // 失败则返回JSON格式的401响应并中止请求 } }5.3 库存并发扣减的真实战场我在第四节已经提到了预防超卖的方案这里再展开说说实际测试中的教训。一种常见的错误实现是“先查库存再判断扣减”这在单线程测试时看不出问题但并发测试一启动问题立刻暴露。正确的做法是依赖数据库的原子更新也就是上面那段“库存充足才扣减”的SQL。如果再保险一点可以在库存表中加一个版本号字段用乐观锁机制来控制更新// 乐观锁更新适用于允许一定冲突重试的场景 int rows inventoryMapper.deductStock(goodsId, count, version); if (rows 0) { throw new BusinessException(库存不足或数据已变更请重试); }对应SQL里的条件就是“stock count AND version 传入版本号”更新成功会后置version加1。便利店系统的并发量几乎不可能把并发冲突打得很严重但这个机制体现的是你对数据一致性的理解很多面试官就吃这套。另外开启事务时还必须注意异常要正确回滚。SpringBoot的Transactional注解默认只对RuntimeException回滚如果你业务中抛出的是自定义的CheckedException必须在注解里声明rollbackFor否则可能出现订单没生成但库存被扣减的脏数据。这个问题我在第一次联调时就踩到过排查了很久才定位到。5.4 前端打包部署与刷新404系统写完后需要部署到服务器上跑起来。前端在本地执行“npm run build”会生成一个dist目录里面是编译压缩后的静态文件把它扔到Nginx的根目录即可。后端的Jar包用“java -jar”命令启动监听8081端口。这里最经典的一个坑是history路由刷新404。Vue Router默认用history模式时URL是真实的路径形式比如“/goods/list”。当你在Nginx上直接访问这个地址时Nginx会去找磁盘上对应的物理文件找不到就返回404。但问题是这个路径是前端路由不是真实文件刷新请求时必须要让Nginx把请求重新指向index.html由前端路由接管。解决方案是在Nginx配置里加一段try_fileslocation / { try_files $uri $uri/ /index.html; }这段话的意思是如果请求的文件不存在就回退到首页的index.html再由前端路由解析。加完这段配置后刷新页面就不会再出现404了。这个坑几乎每个部署Vue项目的人都会遇到提前记下来两个月后你会感谢现在的自己。5.5 前端开发中容易忽略的体验细节联调过程中前后端的接口对接除了数据格式还有几个常见的体验细节。一个是在请求加载时的loading状态特别是查询报表和商品列表这类稍慢的接口没有loading的话用户会以为系统卡死。另一个是接口统一返回体的设计我在项目中用的返回结构是“code message data”前端axios响应拦截器里统一判断code是否为200不是200就弹出错误提示而不是在每个页面里重复写一遍。这样统一处理后接口返回的错误信息展示逻辑收敛到一处代码清爽很多。前端的表单校验也不能全部依赖后端。比如新增商品的条码重复校验如果校验动作全部放到后端用户填完所有字段提交后才被告知条码重复体验很差。正确做法是前端在条码输入框失焦时就调用接口做一次轻量校验如果是重复条码当场标红提示。这个功能看起来小但对收银员日常工作流的顺畅度影响很大也是我在测试中用得最多的功能之一。6. 答辩高频问题与项目提亮建议6.1 答辩老师最常追问的几个点答辩环节其实是项目的第二次展示回答得好整个项目的完成度会上一个台阶。老师最常问的几类问题我整理一下基本逃不开以下这些。“为什么选这个选题”如果你回答“因为我们学校要求做管理系统”这个答案等于什么都没说。更好的切入点是社区零售行业存在庞大的小微商户群体他们的数字化程度偏低市场上缺乏价格适中的轻量级解决方案这个项目就是在用主流技术栈解决真实存在的问题。这类回答把灵感来源、市场分析、实际意义串了起来老师就知道你不是随便选了个题目。“为什么用SpringBoot不用SSM/SSH”可以答SpringBoot极大简化了项目配置内嵌容器让应用可以独立运行生态成熟与Vue前端分离后可以快速迭代同时覆盖了Java企业级开发的主流技术栈。SSM配置繁琐开发效率低而且学习成本更高。这个对比要提前准备好口头描述的时候要流利。“你项目中遇到的难点是什么怎么解决的”这个问题是最能拉开差距的。我的建议是选择一个真实发生过且你已经解决的技术问题比如并发扣库存超卖问题。把现象、排查过程、解决方案、解决效果完整讲一遍老师会很有兴趣。千万不要回答“我这个项目还行没什么难点”那样等于放弃了展示自己能力的机会。6.2 演示稿的数据脚本设计答辩演示最忌讳的就是现场连数据库查半天页面空空如也。提前准备一套完整的演示数据和操作脚本这个习惯一定要有。演示时先把商品数据都准备好几百条商品记录分布在多个分类下库存预警记录要有三五条会员数据要有一条带历史消费记录的订单数据要覆盖近七天让趋势图有内容展示。演示顺序也很关键。我建议的流程是先演示登录和权限控制再进收银台跑一笔完整交易中间穿插扫到库存不足商品的提示、选会员打折、使用积分抵扣最后去订单列表核对这笔订单再去统计报表看数据变化。这套流程一气呵成既展示了业务闭环又自然覆盖了核心功能模块。如果时间充裕再演示一下库存预警处理找到预警商品做一次入库操作回到首页看预警数量减少。一个演示做完系统的主要模块就全部串起来了。6.3 个人实操体会与扩展思路做了几个类似的模拟项目之后我最大的感受是一个系统的核心价值不在于用了多新的技术而在于业务闭环是否真正跑通。技术方案不需要多炫关键是把库存和订单的数据流理清楚。如果只花一个晚上调外形不如花三天把数据流这条主线梳理透。系统的扩展方向答辩时被问到可以提这是展示前瞻性的地方。最自然的扩展是从单店走向多门店给商品表增加门店ID字段、订单表增加门店ID和收银员ID增加门店之间调拨流程。再往下延伸可以做小程序端顾客线上下单便利店门店作为前置仓配送。如果要做真正的智能化可以基于历史销售数据做销量预测和智能补货建议把原本人工设定预警阈值的方式升级为算法自动推荐。这些扩展方向不用实现口头论述即可但能让老师看到你的思考深度。最后分享一个我个人的小技巧开发期间每完成一个模块就写一段简洁的测试记录包括测试场景、预期结果、实际结果和问题描述。这些记录不仅是联调阶段的抓手最后整理成项目测试文档或者答辩PPT都会省下大量时间。捷足先登的周报事迹我从不少同学那里听过临时抱佛脚整理材料的滋味确实不好受。从开发第一天就坚持记录后面会轻松很多。