每年六月的宿舍楼下都会出现同一幕毕业生把台灯、书架、自行车、考研资料堆在楼道口贴张免费自取的纸条几个小时后被保洁清走同一时间另一栋楼里的新生正在各种群里刷屏求购同款。两拨人物理距离不到三百米信息却完全不通。校园二手交易网站要解决的就是这个错位——把我带不走的东西和我正需要的东西在同一个封闭圈子里对上。而这套带源码和开题的材料本质上是一份完整的毕业设计交付物一边是可跑起来的系统一边是能过审的开题文档。它的受众很明确——正在找毕设题目的同学、想练一遍完整全栈流程的新手以及真打算给学校做一个内部小工具的开发者。我经手过几个类似的项目也帮人改过不少这类开题下面把踩过的坑和真正管用的做法一次讲透。1. 先想清楚校园二手交易和通用二手平台差在哪很多人拿到这个题目第一反应是把通用二手平台的功能砍一半搬过来做出来的东西能跑但没灵魂答辩时老师一句那和现成平台有什么区别就卡住了。真正的差异不在功能多少而在交易半径和信任成本这两个变量上。1.1 三公里范围内的交易逻辑和全国包邮完全不同通用二手平台的核心矛盾是如何让陌生人敢把钱打给另一个陌生人所以重资产地做担保交易、物流对接、纠纷仲裁。校园场景里这三件事全都不成立交易半径基本在一个校区或相邻两个校区内买卖双方可以十分钟内见面身份可以通过学号、校园邮箱做一次低成本核验纠纷大概率是这本书缺了两页这种几十块钱的事走仲裁流程纯属浪费。所以这类系统的设计重心应该放在撮合效率上而不是资金安全上。具体落到功能上就是商品要按校区、按宿舍区、按楼栋筛选发布流程要短到能在食堂排队时两分钟发完联系方式要在双方确认意向后立刻可见而不是让用户自己想办法留微信。我见过一个反面案例某同学把系统做成了完整担保交易买家下单后钱进平台账户卖家发货买家确认收货才放款。功能确实完整但演示时老师问钱进谁的账户你有支付牌照吗直接答不上来。这类系统不要碰资金池线上只做意向撮合和状态记录实际钱货两清在线下完成这是最稳妥也最符合真实使用场景的做法。1.2 功能清单按没有它系统就转不动来排序拿到题目别急着画功能架构图先按必要性分三档。第一档是缺了就没法完成一次完整交易的最小闭环第二档是有明显加分但可以砍的第三档是锦上添花、时间不够直接放弃的。优先级功能模块必要性说明P0 必须注册登录与校园身份标识没有身份后续的信任机制无从谈起P0 必须商品发布标题、描述、价格、成色、图片、校区系统的核心数据来源P0 必须分类浏览与关键词搜索用户找东西的唯一入口P0 必须卖家联系方式/站内留言交易达成的临门一脚P0 必须管理后台商品下架、用户封禁、举报处理没有它系统一周内就会被垃圾信息淹掉P1 加分收藏、浏览记录提升留存实现成本极低P1 加分订单状态流转待确认/已锁定/已完成体现业务思考深度答辩很吃这套P1 加分信用评价双刃剑做不好反而增加复杂度P2 可选站内即时聊天WebSocket 的工作量比想象中大P2 可选求购专区反向撮合能做但优先级低这张表最实际的用处是砍需求。毕设周期普遍在两到三个月中间还要写论文真正留给编码的时间可能只有五周。P0 全做完已经够答辩了P1 挑两三个做P2 一律放到后续展望里写在开题报告和论文最后一章——这反而是加分项说明你知道边界在哪。1.3 求购需求被严重低估大部分同类系统的源码里只有卖没有买。实际调研一下就会发现新生入学季的求购需求甚至比出售需求更旺——他不知道自己需要的东西谁会卖只能发帖问。加一个轻量的求购模块数据结构几乎复用商品表只是把价格换成预算区间把状态换成求购中/已解决。实现成本很低但在开题报告里可以写出一个像样的研究点双向撮合。你可以说本系统在传统单向发布的基础上增加了求购信息流并对求购与在售商品做简单的关键词匹配推荐。这一句能撑起半页研究内容的篇幅而且技术上确实做了东西不是空话。2. 技术选型为什么这套系统大概率落在 SpringBoot Vue MySQL选型这件事在毕设里有个隐藏评价维度老师看得懂吗答辩时能不能讲清楚。你用一套很时髦但自己只跑通了 Demo 的技术栈被追问两句就露馅不如用最主流的组合把每个环节都吃透。2.1 三种常见组合的真实取舍我把这几年见过的主流组合列一下重点说各自的真实坑点不是泛泛比较优劣。组合上手难度适合人群真实坑点SpringBoot Vue MySQL中等计算机相关专业想走 Java 路线配置文件多、依赖版本互相打架、前端跨域Python Django/Flask MySQL低编程基础一般想快速出成果部署到服务器时环境依赖麻烦异步能力弱Node.js Express MongoDB中等前端基础好想做全栈事务支持弱交易状态流转容易出脏数据微信小程序 云开发低想强调移动端体验源码可移植性差答辩时被问后端在哪如果你的目标是稳选第一行。SpringBoot 的生态太成熟了任何你想到的功能都有现成方案出问题也能搜到答案。Vue 的组件库Element Plus、Vant能让你在一天内搭出能看的界面这在毕设里非常重要——老师对界面的第一印象直接影响评分。有一点必须提醒不要把前后端分离做成前后端割裂。我见过太多项目前端跑在 8080后端跑在 8081然后靠一堆 CORS 配置硬撑。正确做法是在 Vue 的vue.config.js里配 proxy让开发环境走同源代理生产环境用 Nginx 反向代理。这一步在开题报告的技术路线里写一句能体现你确实想过部署问题。// vue.config.js 开发环境代理配置 module.exports { devServer: { port: 8080, proxy: { /api: { target: http://localhost:8081, changeOrigin: true, pathRewrite: { ^/api: } } } } }2.2 数据库设计八个表撑起整个系统表结构是这套系统里最容易被低估的部分。很多人上来就写代码写到一半发现字段不够回头改表、改实体、改前端返工成本极高。我建议先把表画完再动手。核心就是八张表-- 用户表校园身份标识是关键 CREATE TABLE user ( id BIGINT PRIMARY KEY AUTO_INCREMENT, student_no VARCHAR(20) NOT NULL UNIQUE COMMENT 学号用于校园身份核验, nickname VARCHAR(32) NOT NULL, avatar VARCHAR(255), campus_zone VARCHAR(32) COMMENT 校区/宿舍区用于同城筛选, phone VARCHAR(20), credit_score INT DEFAULT 100 COMMENT 信用分初始100, status TINYINT DEFAULT 1 COMMENT 1正常 0封禁, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); -- 商品表成色和交易方式是两个高频筛选维度 CREATE TABLE item ( id BIGINT PRIMARY KEY AUTO_INCREMENT, seller_id BIGINT NOT NULL, category_id INT NOT NULL, title VARCHAR(100) NOT NULL, description TEXT, price DECIMAL(10,2) NOT NULL, original_price DECIMAL(10,2) COMMENT 原价用于展示折扣力度, condition_level TINYINT COMMENT 1全新 2几乎全新 3轻微使用 4明显使用, trade_mode TINYINT COMMENT 1面交 2可邮寄, campus_zone VARCHAR(32), status TINYINT DEFAULT 1 COMMENT 1在售 2已锁定 3已售出 4已下架, view_count INT DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, KEY idx_cate_status (category_id, status), KEY idx_zone (campus_zone) );剩下六张表是商品图片表一对多独立存便于排序和删除、分类表支持二级分类、订单表记录交易状态流转、留言表买卖双方的沟通记录、收藏表、举报表。注意索引不是随便加的——idx_cate_status这个联合索引对应的是按分类查在售商品这个最高频查询idx_zone对应校区筛选这两个索引能把列表页的查询从全表扫描降到索引扫描。有个细节价格用 DECIMAL 不要用 FLOAT。二手交易里 19.9 元这种价格太常见FLOAT 存储会有精度误差展示出来变成 19.900000000000002虽然用户可以忍受但在答辩演示时被看到就很尴尬。2.3 图片上传是新手第一个卡壳点商品图片这件事看起来简单实际上坑最多。很多源码里的做法是把图片转成 Base64 直接存数据库字段本地跑得挺顺一部署就崩——一张 2MB 的图转成 Base64 约 2.7MB商品列表页加载二十条就是五十多兆页面直接卡死。正确做法分两步存储上走文件系统或对象存储数据库只存 URL上传前在前端做压缩。前端压缩用 canvas 就能实现不用引入大库// 上传前压缩到宽度 1080px、质量 0.8 function compressImage(file, maxWidth 1080, quality 0.8) { return new Promise((resolve) { const img new Image(); const reader new FileReader(); reader.onload (e) { img.onload () { const scale Math.min(1, maxWidth / img.width); const canvas document.createElement(canvas); canvas.width img.width * scale; canvas.height img.height * scale; canvas.getContext(2d).drawImage(img, 0, 0, canvas.width, canvas.height); canvas.toBlob(resolve, image/jpeg, quality); }; img.src e.target.result; }; reader.readAsDataURL(file); }); }后端用本地磁盘存储时一定要配静态资源映射否则上传完访问 404很多人在这一步卡一整天。SpringBoot 里加一个配置类把上传目录映射到 URL 路径上即可。还有一个更隐蔽的坑上传目录不要放在项目目录里。项目重新打包部署时target目录会被清空用户上传的图全没了。我一般会放在项目外的固定路径比如/data/upload/配置文件里写死部署脚本不去碰它。3. 源码落地从跑起来到跑得稳要跨的三道坎拿到一份校园二手交易网站的源码绝大多数人的动作是git clone、改数据库密码、mvn spring-boot:run跑起来看见登录页就以为大功告成。真正的问题在后面。3.1 统一返回结构决定了后期维护成本源码质量高低看第一个接口就能判断。低质量的写法是每个 Controller 直接返回实体对象或者 Map前端拿到的东西五花八门错误处理全靠猜 HTTP 状态码。规范做法是定义一个统一响应结构public class ResultT { private Integer code; // 200成功4xx业务错误500系统错误 private String msg; private T data; private Long timestamp; public static T ResultT ok(T data) { ResultT r new Result(); r.code 200; r.msg ok; r.data data; r.timestamp System.currentTimeMillis(); return r; } public static T ResultT fail(Integer code, String msg) { ResultT r new Result(); r.code code; r.msg msg; r.timestamp System.currentTimeMillis(); return r; } }配套要做的是全局异常处理器。不配的话一旦某处抛出自定义业务异常Spring 默认返回 500 加一大段堆栈信息前端解析不了用户看到的是一张白屏。加一个RestControllerAdvice注解的类把业务异常、参数校验异常、兜底异常统一转换前端只处理code字段就行。这套东西在你自己的系统里价值有限但在开题报告的系统设计章节里非常好写因为它体现了分层思想。而且答辩老师如果翻代码看到统一返回和全局异常处理印象分会明显不一样。3.2 列表页的查询是性能分水岭商品列表页有个经典误区先查出全部商品再在前端做筛选和分页。数据量小的时候完全无感一旦插进去几千条测试数据页面加载时间从 0.2 秒变成 8 秒演示当场翻车。正确的做法是分页放在数据库层同时把筛选条件拼成动态 SQL。MyBatis-Plus 的LambdaQueryWrapper用起来最顺手条件拼接清晰且类型安全public IPageItemVO search(ItemQuery query, int page, int size) { LambdaQueryWrapperItem wrapper new LambdaQueryWrapper(); wrapper.eq(Item::getStatus, 1); // 只查在售 wrapper.eq(StringUtils.hasText(query.getKeyword()), Item::getTitle, query.getKeyword()) // 实际应用 like .eq(query.getCategoryId() ! null, Item::getCategoryId, query.getCategoryId()) .eq(StringUtils.hasText(query.getZone()), Item::getCampusZone, query.getZone()) .eq(query.getConditionLevel() ! null, Item::getConditionLevel, query.getConditionLevel()) .orderByDesc(Item::getCreatedAt); return itemMapper.selectPage(new Page(page, size), wrapper); }这里有个关联查询的坑要提前避列表页需要显示卖家昵称和头像。如果先分页查商品再循环查用户十条数据就是十一次数据库查询这叫 N1 问题。解决办法要么用 JOIN 一次查完要么先批量收集 sellerId 再一次性查用户表用 Map 做内存关联。后者在分页场景下更稳因为 JOIN 加 ORDER BY 在数据量大时会产生临时表反而更慢。还有一个小细节浏览量不要用UPDATE item SET view_count view_count 1同步写。商品详情页每次打开都写库热门商品会锁行。简单做法是详情页读缓存、定时批量回写或者直接用 Redis 的 INCR但毕设规模下其实不必要——只要知道这回事答辩被问到能答上来就够了。3.3 交易状态机是这个系统的灵魂为什么说状态机是灵魂因为校园二手交易的核心不是下单支付而是多个买家同时联系一个卖家。现实场景是同一本教材五个买家都发消息说我要卖家先跟 A 约了线下见面结果 A 临时放鸽子卖家得回头找 B——这时候系统如果只记录已售出卖家根本分不清谁先谁后。所以订单状态必须设计得能表达这个过程。我用的方案是四态状态含义触发动作可流转到待确认买家发起交易意向买家点击我想要已锁定 / 已取消已锁定卖家同意商品对其他买家隐藏卖家确认已完成 / 已取消已完成线下交易成功买卖任一方确认完成终态已取消任一方取消或超时未确认主动取消/超时终态关键在已锁定这个状态。商品一旦进入锁定列表页就不再展示给其他人但又不算成交。同时要加超时机制锁定超过 24 小时没确认完成自动回退到在售状态避免卖家忘记处理导致商品被永久占住。Transactional public void lockItem(Long itemId, Long buyerId) { Item item itemMapper.selectById(itemId); // 乐观锁只有状态为在售时才更新成功 int rows itemMapper.updateStatusFrom(itemId, 1, 2); if (rows 0) { throw new BusinessException(手慢了该商品已被其他人锁定); } orderMapper.insert(new Order(itemId, buyerId, item.getSellerId(), 1)); }updateStatusFrom(itemId, 1, 2)对应的 SQL 是UPDATE item SET status 2 WHERE id ? AND status 1。这一句是并发抢单的关键——用状态字段本身当乐观锁两个人同时点数据库层面保证只有一个成功。这条 SQL 值得在论文里单独写一段因为它用最轻的方式解决了并发问题比上分布式锁实在得多。3.4 校园身份核验别做成形式主义几乎所有同类系统都有注册时填写学号这一步但大部分只是个普通字符串字段随便填个 123456 也能过。这在答辩时很容易被问怎么保证都是本校学生诚实的回答是完全保证做不到但可以做分层核验。我的做法是三级基础级学号格式校验用正则约束长度和位数规律能挡住随手乱填的进阶级校园邮箱验证码发送到xxx学校邮箱域名能验证邮箱归属实际部署时这个接口需要申请毕设演示可以做成可开关的模拟模式运营级新用户发布前两条商品进入人工审核队列管理员后台点通过才展示开题报告里写清楚这三层比强行说做了实名认证要可信得多。而且第三层给你的后台管理模块找到了一个必须存在的理由——很多系统的后台管理形同虚设只有这一个审核功能是真正被用到的。4. 开题报告怎么写才不像从模板里抄的源码部分再漂亮开题写崩了照样过不了。我审过、改过的这类开题文档少说也有几十份共性问题非常集中背景写成了宏大叙事研究现状写成了产品介绍技术路线写成了名词罗列。4.1 选题背景要落在具体问题上不要从某某行业蓬勃发展起笔最常见的开头是这样的随着互联网技术的飞速发展和电子商务的普及二手交易市场规模不断扩大……。这种句子在评审眼里等于零信息量因为它可以套在任何题目上。好的背景应该从可观察的具体现象切入然后引出信息不对称这个真问题。比如可以这样组织校内每学期末产生大量闲置物品处理方式以丢弃和低价甩卖为主同时新学期有大量购置需求两者在时间和空间上高度重叠当前的信息传递依赖社交群聊信息生命周期短、检索困难、无法沉淀现有综合性二手平台面向全社会缺乏校内场景需要的区域筛选与身份约束。四句话层层递进把为什么需要一个专门的校园系统讲清楚了。意义部分不要写成具有重要的理论意义和现实意义这种空话分成两块写实践意义是降低校内闲置物品流转的信息成本提高物品复用率技术意义是完整实践一次前后端分离架构下的业务系统开发涉及权限控制、状态流转、并发处理等典型问题。后者才是毕设真正要证明的东西——你不是在创业你是在证明自己具备工程能力。4.2 研究现状分两条线写别写成产品评测研究现状是重灾区。很多人写着写着就变成了某平台功能强大、用户众多甚至带上主观评价。规范写法是分两条线综合类二手交易平台和校园垂直类系统。综合类这块概括其共性特征即可面向全社会、交易半径大、重担保交易与物流对接、功能全面但对小范围高频交易而言过重。不要点名具体产品用以国内主流的综合性二手交易平台为例这种表述既安全又专业。校园垂直类这块重点讲已有研究的共性与不足。共性是多数实现了商品发布与浏览的基本功能部分引入了信用评价不足集中在三点——缺乏对线下撮合场景的状态建模、缺少对同一商品多买家竞争的处理、区域筛选粒度粗只有城市级没有校区级。这三点不足正好对应你系统里要做的三个改进点。这样写出来的逻辑是闭合的评审一眼就能看出你想清楚了。4.3 技术路线用分层描述配一张自己画的结构说明技术路线不需要写成长篇大论但必须有清晰的分层。我一般按四层写表示层用 Vue 框架配合组件库构建单页应用负责页面渲染与交互接口层用 SpringBoot 提供 RESTful 接口通过拦截器实现登录态校验业务层按用户、商品、交易、后台四个模块划分 Service模块间通过接口调用数据层用 MySQL 存储业务数据MyBatis-Plus 做对象关系映射文件资源单独存放。写完这四层再补一句关键设计决策的理由比如选择前后端分离而非服务端渲染是为了让移动端小程序后续可以复用同一套接口。这一句的作用是证明你的选型是有依据的不是跟风。进度安排用表格按周划分重点是留出缓冲。我建议这么分第 1-2 周需求分析与数据库设计第 3-6 周后端核心模块开发第 7-8 周前端页面开发与联调第 9 周测试与问题修复第 10-11 周论文撰写第 12 周修改与答辩准备。注意测试单独占一周很多人不留这一周最后提交前一天还在改 bug论文根本没时间写。4.4 答辩老师最爱追问的几个点提前准备我把高频问题整理一下都是实打实会被问到的追问想考察什么建议回答方向和现成平台比你的系统价值在哪选题合理性强调校内封闭性带来的信任成本优势与区域筛选粒度两个人同时买同一件商品怎么处理并发意识讲乐观锁更新状态字段配合订单唯一约束商品信息里出现违规内容怎么办内容治理意识关键词过滤 举报 后台人工审核三道关图片存在哪量大了怎么办存储设计当前本地存储 预留对象存储扩展接口用户密码怎么存的安全意识BCrypt 加盐哈希绝不存明文登录态用 token最后一条尤其重要。我见过源码里密码字段直接存明文的这种被问到基本就是扣分项。改成BCryptPasswordEncoder只需要几行代码成本极低收益极高。5. 演示和交付阶段最容易翻车的地方代码写完、论文交上去最后还有一关是现场演示。这一关的失败率比想象中高因为演示环境的变数太多。5.1 演示数据要提前编排不要现场录入最典型的翻车场景打开首页空空如也然后现场开始一条一条发商品一边发一边解释。老师的耐心只有三分钟。正确做法是准备一个数据初始化脚本提前插入结构化数据至少三个用户含一个被封禁的用于演示管理功能、六个分类、四十条商品图片用统一尺寸的占位图避免加载缓慢、十五条不同状态的订单覆盖待确认、已锁定、已完成、已取消。数据要有真实感——书名要像真的教材名价格要符合二手行情描述要写成像学生随手发的。-- 演示数据要有场景感不要用测试商品1 INSERT INTO item (seller_id, category_id, title, description, price, original_price, condition_level, trade_mode, campus_zone, status) VALUES (2, 3, 高等数学同济第七版 上下册, 大一用过笔记做在便利贴上已撕掉书页干净无涂鸦。上册书角有点卷不影响翻阅。打包出单买也行。, 18.00, 89.00, 3, 1, 东区3号楼, 1);另外有个小技巧演示前把浏览器缩放调到 110%字体大一点投影到教室屏幕上后排也能看清。这个细节没人提但实际影响观感很大。5.2 内容审核这块宁可做得简单也不能没有校园二手交易系统天然会遇到几类问题信息代写代考、证件买卖、违规电子产品、以及一些擦边内容。毕设阶段做完整的智能审核不现实但关键词过滤必须有一个哪怕就是一个简单的字符串匹配。实现上我一般用 Aho-Corasick 或者更简单的 Trie 树把敏感词库放在配置文件或数据库表里发布商品和发留言时先过一遍。命中就拦截并提示同时记录一条待审核日志进后台。这部分的代码量不到两百行但它在开题和论文里能支撑起一个内容安全小节答辩时也是一张能打出的牌。还有一点举报功能要留入口。商品详情页放一个不起眼的举报按钮后台能看到举报列表并处理后下架。这套机制在真实系统里是标配在毕设里是加分项。5.3 部署到服务器时的三个必踩坑本地跑通不等于线上跑通。我把这类小系统部署时最常遇到的问题列一下第一个是文件路径。本地开发时上传目录写的是相对路径打包成 jar 后工作目录变了图片全部失效。解决办法是在配置文件里用绝对路径${user.dir}或者外部配置项部署时通过启动参数指定。第二个是数据库连接池。默认配置的连接数往往偏小演示时多人同时点击会出现等待。SpringBoot 里把 HikariCP 的maximum-pool-size调到 20 左右connection-timeout调到 3 秒体验会好很多。第三个是时间时区。数据库存的时间显示出来差 8 小时这个问题十个项目有八个中招。解决办法是 JDBC URL 里加上serverTimezoneAsia/Shanghai同时数据库服务端时区也确认一下。看着是小问题但商品发布时间显示成1970-01-01就很致命。spring: datasource: url: jdbc:mysql://127.0.0.1:3306/campus_market?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse hikari: maximum-pool-size: 20 connection-timeout: 3000 servlet: multipart: max-file-size: 5MB max-request-size: 20MB6. 拿到源码之后怎么改成自己的东西最后说一个很现实的问题直接拿一份源码改改就交风险其实不小。一是查重二是答辩时讲不清细节。正确的用法是把源码当参考实现重点看它怎么组织分层、怎么处理状态流转、怎么做分页查询然后自己动手重写一遍核心模块。6.1 改哪几处能显著提升这是我做的的可信度第一处是界面。至少把首页布局、商品卡片样式、详情页信息结构重做一遍。用同一套组件库不同的间距、圆角、配色、信息密度视觉上立刻就不一样了。这部分投入一天时间收益比改十行后端代码都大。第二处是业务细节。在原版基础上加一两个原版没有的小功能比如商品的同款推荐按分类取最近发布的其他商品、或者降价提醒用户收藏的商品价格变动时站内通知。功能虽小但你能完整讲出设计思路这比什么都强。第三处是数据统计页。后台加一个简单的数据看板展示本周新增商品数、成交数、活跃用户数、热门分类分布。用 ECharts 画两三个图数据从数据库聚合查询中来。这个模块在开题报告的研究内容里可以单独列一条在论文里能占一章实现成本还低。6.2 几个我踩过才知道的细节分类不要做成无限层级。一开始我按通用电商的做法支持任意多级结果所有树形操作都要写递归前端选择器也变得复杂。校园二手交易两级分类足够了——一级是教材书籍/电子数码/生活用品/运动器材/服饰鞋包/其他二级最多七八个。定死两级代码量减一半。商品状态变更要记日志。哪怕只是一张简单的流水表记录谁在什么时候把商品从什么状态改成了什么状态。出问题时能追溯答辩时被问怎么保证数据一致性也能拿出来说。别在订单表里冗余存商品标题。我见过不少源码这么做理由是防止商品被删后订单查不到。正确做法是商品做逻辑删除is_deleted字段订单通过外键关联查询。冗余存储会在商品改价后出现前后不一致反而更麻烦。留言功能别做成实时聊天。我第一版用了 WebSocket本地测试很爽部署到有反向代理的环境里连接一直掉。后来改成轮询——前端每 30 秒查一次新消息体验差一点点但稳定性提升了不止一个档次。毕设阶段能稳定演示的价值远高于技术上更先进。给管理员的批量操作加二次确认。下架商品、封禁用户这类操作没有确认弹窗很容易误点演示时点错一次全场都看得到。写一个弹窗拦截十行代码的事。预留扩展接口。比如图片存储抽象出一个StorageService接口默认实现走本地磁盘注释里写清楚如需切换到对象存储实现该接口即可。这种代码在评审眼里是加分项因为它证明你思考过演进方向而不是只为了把功能做出来。开题报告的预期成果与展望部分写这个比写将不断优化系统性能实在得多。我在实际操作中的体会是这类毕设系统的难点从来不在技术复杂度上而在取舍——知道哪些功能必须有、哪些可以砍、哪些可以留给未来。一份能跑的系统加上一份讲得清楚的开题比一份功能堆满但每处都半吊子的交付物分数高得多。真要说的话把商品发布到交易的这条主链路打磨到丝滑比多做五个边缘模块划算。
阅读完成 · 觉得有帮助?