尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

SpringBoot+小程序+大数据:外卖推荐系统实战全解析

SpringBoot+小程序+大数据:外卖推荐系统实战全解析 1. 项目全景拆解当SpringBoot、小程序和大数据凑到一起1.1 这个项目到底在做什么先说结论这是一个典型的前后端分离 推荐系统落地的全栈项目技术关键词是SpringBoot、微信小程序和大数据。它做的核心事情是——让用户打开小程序后能看到一个“懂你口味”的外卖点餐界面系统根据你过去的下单记录、浏览行为、菜品类别偏好从成千上万个菜品里找出你大概率会点的那些排到前面展示。很多同学看到“大数据”这三个字就怕觉得一定是Hadoop、Spark、Flink一整套分布式集群没有8G内存16核CPU跑不起来。实际上在外卖点餐这个场景下真正让系统“聪明”起来的东西是一套完整的用户行为数据链路用户看了什么、点了什么、加购了什么、在哪个时间段下单、倾向什么价位这些数据被采集、清洗、分析最后变成推荐结果。大数据在这里更重要的是“思维方式”和“数据处理流程”而不是非要堆出一套集群来。从毕设的角度看这个项目的定位也很精准它同时覆盖了后端开发、小程序前端、数据库设计、推荐算法、数据可视化这几个模块。每一块都是可以单独拿出来讲半天的点组合在一起就是一个结构完整、能演示、能答辩、能写进简历的项目。1.2 为什么选这套技术栈选型逻辑这个技术组合不是随便凑出来的每一层都有它的合理性和不可替代性。SpringBoot负责后端接口服务。它最大的价值是“开箱即用”内置Tomcat、自动配置、starter机制让你把精力放在业务逻辑而不是环境搭建上。相比传统的SSH框架SpringBoot省掉了大量XML配置同时也非常贴合企业级开发的主流技术栈。在一线开发中SpringBoot MyBatis Plus MySQL这套组合基本是中小型项目的标配拿去面试也不虚。小程序负责用户端。选择微信小程序而不是独立APP核心原因有两个一是开发成本低一套WXML WXSS JS就能跑起来不需要上架应用商店、不需要考虑iOS和Android双端适配二是微信生态自带用户体系和分享裂变能力外卖点餐这个场景天然适合在微信里传播。毕设答辩的时候老师掏出手机扫码就能看效果比在电脑上装APK方便太多。大数据板块则负责整个系统的“智商担当”。它的落地形态包括用户行为日志采集、订单数据统计分析、基于协同过滤的推荐算法、以及管理后台的数据可视化大屏。技术实现上不一定非要用分布式框架但整个数据处理流程——从数据采集、清洗、特征提取到建模和推荐——是完整的大数据思维链路。1.3 “大数据”在这个项目里的完整数据流很多人做毕设最容易犯的错误是数据库里建了几张表、用SQL查一下数据就管自己叫“大数据项目”。答辩的时候老师一问数据量多大、怎么处理的就答不上来。真正的“大数据处理思路”是有一套完整链路的。在外卖点餐推荐这个系统里整个数据流是这样的数据采集层用户在小程序端的每一个关键行为浏览商品、搜索关键词、点击菜品详情、加入购物车、提交订单、取消订单、收藏店铺都会通过埋点接口记录到后端日志表或消息队列中。数据存储层原始行为日志存在日志表业务数据用户、店铺、菜品、订单存在MySQL统计结果和推荐结果可以存到Redis缓存或者额外的中间表中兼顾实时性和查询效率。数据处理层通过定时任务如Spring的Scheduled或者xxl-job对行为日志进行清洗、汇总、分析计算每个用户的偏好矩阵、每个菜品的被偏好度、相似度矩阵。数据应用层推荐算法基于处理好的偏好数据为用户生成个性化菜品列表管理后台基于统计结果渲染ECharts可视化图表。数据反馈层用户对推荐结果的点击、下单行为再次被记录成为下一轮推荐的训练数据形成闭环。这套链路讲清楚之后你的项目就已经比市面上80%的“假大数据毕设”要扎实了。哪怕数据量真的只有几千条但你把这个处理框架搭起来了老师看到的是一个完整的数据工程思维。2. 核心推荐系统解析与代码落地2.1 推荐系统在毕设里的合理定位推荐系统是这个项目最大的亮点也是最容易翻车的部分。很多同学一上来就想搞深度学习、搞神经网络觉得这样才显得高级。但作为一个毕设项目推荐系统的核心评价标准不是模型有多新而是逻辑是否清晰、实现是否完整、效果是否可解释。在外卖点餐场景下用户的需求是“快速找到想吃的”所以推荐策略应该围绕三个维度展开个性化偏好匹配根据用户历史订单和浏览记录推荐他常点的品类、口味和价位。相似用户挖掘找到“口味相似”的其他用户把他们点过的、而你还没尝试过的菜品推荐给你。热门与新品补充避免推荐结果太“窄”需要混入一定比例的全局热销菜品和新品给用户新鲜感。这三种策略正好对应了推荐系统领域最经典的三种算法思路基于内容的推荐、基于用户的协同过滤、基于物品的协同过滤。毕设里面选协同过滤是最稳妥的因为算法原理好讲、代码量可控、效果可见而且面试的时候也是高频考点。2.2 协同过滤的核心原理通俗版协同过滤Collaborative Filtering的核心思想其实特别朴素物以类聚人以群分。先看基于用户的协同过滤(UserCFUser Collaborative Filtering)。假设张三和李四都点过黄焖鸡米饭和麻辣香锅说明两个人的口味比较接近。这时候李四又点了一份螺蛳粉张三没点过那系统就会把螺蛳粉推荐给张三——因为“口味相似的你喜欢的东西你大概率也喜欢”。再看基于物品的协同过滤(ItemCFItem Collaborative Filtering)。它的逻辑反过来了不是找相似的人而是找相似的物品。比如大量点过“炸鸡”的用户同时也会点“可乐”那这两样东西就被打上了“相似”的标签。以后用户在浏览炸鸡的时候系统会自动把可乐附加上去。外卖平台上的“喜欢这道菜的人也点了……”就是典型的ItemCF。两种策略的适用场景不太一样。用户量少的时候UserCF效果好一些因为用户的行为数据更容易形成矩阵物品数量少、用户量大的时候ItemCF效果更好。外卖点餐场景下菜品数量通常远大于用户数量对单一学校周边而言所以我建议以ItemCF为主、UserCF为辅这样计算量相对可控。2.3 一个“能跑又好看”的推荐实现方案下面直接给出一套可以落地的实现方案。这套方案我在实际项目中验证过代码量不多但效果和讲解空间都很好。第一步准备偏好数据矩阵先通过SQL从订单表和浏览日志表统计出“用户-菜品”评分矩阵。评分规则可以这样定下单1次 3分加入购物车 2分浏览详情页 1分收藏 2分这个规则可以根据实际业务调整但答辩时一定要能说出“为什么这么定”——低价值行为给低分高转化行为给高分这是评分设计的基本原则。第二步计算物品相似度使用余弦相似度Cosine Similarity计算菜品之间的相似度。公式是similarity(A, B) (A·B) / (|A| × |B|)在代码里的实现思路是public double calculateSimilarity(MapInteger, Double itemVectorA, MapInteger, Double itemVectorB) { SetInteger commonUsers new HashSet(itemVectorA.keySet()); commonUsers.retainAll(itemVectorB.keySet()); if (commonUsers.isEmpty()) { return 0.0; } double dotProduct 0.0; double normA 0.0; double normB 0.0; for (Integer userId : itemVectorA.keySet()) { normA Math.pow(itemVectorA.get(userId), 2); } for (Integer userId : itemVectorB.keySet()) { normB Math.pow(itemVectorB.get(userId), 2); } for (Integer userId : commonUsers) { dotProduct itemVectorA.get(userId) * itemVectorB.get(userId); } return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB)); }第三步生成推荐列表对用户u未购买过的菜品i预测其偏好分数prediction(u, i) sum( similarity(i, j) × rating(u, j) ) / sum( abs(similarity(i, j)) )其中j是用户u已经评分过点过的物品。算完所有候选物品的预测分后按分数从高到低取Top N比如Top 10推荐给用户。这套算法的复杂量级是O(m×n×k)其中m是物品数n是用户数k是平均评分物品数。当数据量真正大到单机算不动的时候就可以引出Spark MLlib、分布式矩阵分解等进阶方案——这也可以作为论文里的“未来展望”逻辑非常顺畅。2.4 冷启动和数据稀疏问题怎么处理这是推荐系统里最经典的两个问题答辩时大概率会被问到提前准备好回答思路。冷启动问题指新用户没有任何行为数据协同过滤无法计算。解决方案有三个层次给新用户默认推荐全局热销榜单按照销量、评分、好评率综合排序。新用户注册时引导选择偏好标签口味偏好辣/不辣/清淡品类偏好中餐/西餐/快餐价位偏好10-20/20-30/30用标签匹配菜品。用户产生少量行为后立即切换到基于内容的推荐再过渡到协同过滤。数据稀疏问题指用户行为的交叉度太低大部分用户只点过很少几个菜品导致相似度矩阵中大量为0。解决方案是引入“类别降维”不直接计算菜品和菜品的相似度而是先算“品类”和“品类”的相似度再映射回具体菜品。使用“惩罚系数”降低过于热门菜品的影响避免推荐的菜品都是人人都点过的爆款。混合推荐策略兜底当某用户可用的协同过滤数据不足时自动降级为基于内容的推荐根据菜品标签、口味、价格匹配。在代码实现中可以设置一个“推荐策略路由”逻辑public ListDish recommend(Integer userId) { int userBehaviorCount userBehaviorMapper.countByUserId(userId); if (userBehaviorCount 5) { // 行为数据太少走冷启动策略 return hotDishRecommendService.recommend(); } else if (userBehaviorCount 20) { // 行为数据一般走基于内容的推荐 return contentBasedRecommendService.recommend(userId); } else { // 行为数据充足走协同过滤 return collaborativeFilterRecommendService.recommend(userId); } }这个“分级路由”的思路在真实互联网产品中非常常见也能体现你对推荐系统落地问题的理解深度。3. 数据库设计与SpringBoot后端落地3.1 多角色实体关系设计外卖点餐系统涉及的实体包括用户端和管理端多种角色数据库设计是否合理直接影响后续开发的效率。可以直接参考下面这张表结构清单。表名核心字段作用说明userid, openid, nickname, avatar, gender, taste_tags用户基础信息openid关联微信shopid, shop_name, address, phone, avg_price, score, category商家/店铺信息dishid, shop_id, dish_name, price, image, category, taste, monthly_sales菜品信息推荐算法的核心数据来源ordersid, user_id, shop_id, total_price, status, create_time订单主表order_itemid, order_id, dish_id, dish_name, price, quantity订单明细用于分析用户偏好user_behaviorid, user_id, dish_id, behavior_type, score, create_time用户行为日志浏览/加购/收藏/下单dish_similarityid, dish_id_a, dish_id_b, similarity_value菜品相似度矩阵推荐算法预处理结果recommend_logid, user_id, dish_ids, strategy, create_time推荐结果日志用于效果追踪这里最核心的设计要点是user_behavior表。它不是一个普通业务表而是整个推荐系统的“数据粮仓”。每条用户行为都会实时落库然后由定时任务定期将行为数据聚合到评分矩阵中。有了这张表你后续做报表、做可视化、做数据统计全都顺手了。dish_similarity表是推荐算法的加速神器。如果推荐请求来了才实时计算相似度响应时间会非常难看。正确做法是每天凌晨用定时任务把相似度矩阵算好存进这张表推荐接口直接查表取数毫秒级返回。3.2 Redis在推荐系统里的角色一个容易被忽略但非常加分的点是利用Redis加快推荐接口的响应速度。推荐结果有一个特点同一用户短期内多次访问首页推荐结果其实没必要每次重新计算。完全可以把推荐结果缓存起来设置过期时间例如2小时或者一天。具体做法是用户第一次请求首页推荐时SpringBoot服务查数据库、跑算法、拿到Top N菜品列表然后用用户ID作为key把菜品列表JSON序列化后存进Redis并设置过期时间。后续请求直接从缓存读取命中率可以做到很高。当用户产生了新的下单/浏览行为后可以主动删除对应缓存让下次请求重新计算推荐结果保证推荐内容及时反映用户最新偏好。这比单纯依赖过期时间要“聪明”得多。对应SpringBoot的实现思路如下Service public class RecommendService { public ListDishVO getRecommendDishes(Integer userId) { String cacheKey recommend:user: userId; String cachedData redisTemplate.opsForValue().get(cacheKey); if (cachedData ! null) { return JSON.parseArray(cachedData, DishVO.class); } // 缓存未命中走推荐算法 ListDishVO recommendList doRecommend(userId); redisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(recommendList), 2, TimeUnit.HOURS); return recommendList; } }大一统业务的同时还能体现你对缓存策略、Redis数据结构的掌握这本身就是答辩的加分项。3.3 登录鉴权与小程序身份打通小程序端的登录流程和传统网页APP不太一样。小程序的登录核心是调用wx.login()获取code然后用这个code去后端换openid。openid是用户在微信生态里唯一标识后端通过它来识别具体是哪个用户。安全上有个重要细节不要把openid直接返回给小程序前端做身份凭证。正确做法是后端拿到openid后查数据库找到或创建对应user记录然后生成一个自定义的token返回给小程序。小程序后续的所有请求都在header里带这个token后端用一个Interceptor拦截器统一校验token是否有效。Configuration public class WebMvcConfig implements WebMvcConfigurer { Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()) .addPathPatterns(/api/**) .excludePathPatterns(/api/user/login, /api/shop/list, /api/dish/list); } }这里还涉及一个热词中提到的“小程序备案”信息。小程序在正式上线前微信要求完成ICP备案也就是说需要填一个备案备注通常就是一句话描述这个小程序的服务内容例如“提供校园周边外卖点餐及个性化菜品推荐服务”。毕设阶段部署体验版不需要备案但如果以后真的想上线运营这个流程是绕不开的提前了解没坏处。4. 前端小程序与可视化大屏的实现4.1 小程序端功能结构与页面拆解小程序端的页面结构直接对应了外卖APP的核心功能闭环。建议按下面的tabBar来组织首页推荐流核心页面顶部搜索框 轮播图 banner 推荐菜品列表。推荐列表是核心中的核心需要用scroll-view做滚动分页加载给用户流畅浏览体验。分类页按品类快餐便当、烧烤夜宵、甜品奶茶、麻辣烫等筛选菜品配合左侧一级侧边栏 右侧二级菜品列表。购物车页已选菜品列表、数量加减、价格汇总、结算按钮。订单页订单列表按状态分类待付款/待收货/已完成/已取消。我的页个人信息、收藏列表、地址管理、口味标签设置、联系客服。每个页面都对应一套后端接口典型接口清单如下POST /api/user/login 微信登录 GET /api/dish/recommend 获取推荐菜品列表 GET /api/dish/category/{cid} 按分类获取菜品 GET /api/dishes/search?kwxx 菜品搜索 POST /api/cart/add 加入购物车 POST /api/cart/update 修改购物车数量 POST /api/cart/clear 清空购物车 POST /api/order/create 创建订单 GET /api/order/list?statusx 获取订单列表 POST /api/order/cancel 取消订单 POST /api/collect/add 收藏/取消收藏 GET /api/behavior/report 行为上报关于“小程序动态设置标题”这个高频搜索点实现起来其实很简单调用小程序的wx.setNavigationBarTitle()方法在onLoad里根据当前页面参数动态改标题。比如从分类页进入一个店铺时可以把这个店铺的名字设为标题体验会好很多。代码就是这样一行wx.setNavigationBarTitle({ title: 老王烧烤 - 外卖点餐 });如果要在分享卡片里也显示特定标题需要在onShareAppMessage里设置title字段。4.2 数据可视化大屏怎么做管理后台的数据可视化是整个项目里视觉冲击力最强、答辩最出效果的部分。技术选型推荐SpringBoot ECharts再套一个AdminLTE或自己写一个简单管理页面模板即可。可以部署这几个核心图表近7日订单趋势图折线图X轴日期Y轴订单量直观展示业务增长情况。菜品销量Top10排行榜横向柱状图一眼看出爆款菜品。用户消费金额分布饼图/环形图展示不同消费区间用户占比。分类销售占比如饼图展示快餐、甜品、烧烤等类别的销量占比。时段下单热度图柱状图展示一天24小时的订单分布可以看出中餐和晚餐两个高峰。ECharts的数据来源接口也很直白RestController RequestMapping(/api/statistics) public class StatisticsController { GetMapping(/daily-orders) public Result getDailyOrders() { // 按日期分组统计订单数 ListMapString, Object list orderMapper.selectOrderCountByDate(); return Result.success(list); } GetMapping(/top-dishes) public Result getTopDishes() { // 按销量/热度取前10菜品 ListDish topDishes dishMapper.selectTopBySales(10); return Result.success(topDishes); } }把接收到的JSON数据喂给ECharts图表就出来了。前端管理后台的开发量不算大但它直接决定了答辩演示的“第一眼观感”。务必花时间把管理后台的UI和布局做得清爽一点至少比普通表格多花一点心思。4.3 地理位置与配送逻辑的处理外卖点餐这个场景绕不开“配送”的话题。小程序可以通过wx.getLocation()获取用户当前位置再把经纬度传给后端后端匹配出当前位置附近一定范围内比如3公里内的商家。附近商家的计算可以用MySQL原生的ST_Distance函数或者手动用Haversine公式distance 2 × R × arcsin( sqrt( sin²((lat2-lat1)/2) cos(lat1) × cos(lat2) × sin²((lng2-lng1)/2) ) )其中R是地球半径取6371公里。如果用户没授权地理位置就默认展示全量商家。这个功能的代码量很小但却能体现出你对实际业务场景的理解。顺带提醒一个细节清单里的搜索热词有“app字体设置”。小程序里全局设置字号可以在app.json里配置style: v2然后用wx.getSystemInfo获取系统字体大小设置针对字体放大的用户做好适配避免页面文字溢出。这种小细节往往是大厂技术面试时喜欢问的“用户体感”问题。5. 毕设答辩与远程调试避坑实录5.1 数据量不足推荐效果出不来怎么办这是毕设项目里最扎心的一个场景推荐算法辛辛苦苦写完了结果库里只有30个测试用户、50个菜品、200条订单算出来的相似度矩阵效果惨不忍睹推荐出来的菜品看起来完全“不智能”。解决这个问题的思路有两条线。第一条线是造数据。可以写一个Mock数据生成器模拟生成100个用户、200个菜品、每个用户10~30条行为数据数据量达到几千条甚至几万条。造数据不是随便造要注意逻辑合理性——用户的行为偏好要符合某种消费习惯。比如给用户A生成的订单里60%是川湘菜那么浏览行为里川湘菜的比例也应该偏高价格都落在15~30元区间。这样推荐算法算出来的结果才“像回事”演示的时候才有说服力。第二条线是展示策略。演示推荐效果时不要只展示一个平面的推荐列表。可以故意找一个偏好特别明显的用户比如全是湘菜订单的用户展示给他推荐的湘菜比例明显高于其他用户再对比一个口味清淡的用户两者推荐结果形成鲜明差异。这样对比演示的逻辑远比“我的推荐准确率是95%”这种数字更有冲击力。5.2 远程调试常见问题排查“远程调试”是毕设交付时最耗心力的环节之一因为你的代码跑在别人电脑或者服务器上各种环境问题像开盲盒一样不可预知。根据经验远程调试中最容易翻车的有以下几个点问题典型现象排查思路端口未开放接口访问超时检查服务器安全组、防火墙是否放行8080端口数据库连接失败启动报错access denied检查MySQL用户名密码是否与配置一致、是否允许远程访问Redis连接拒绝缓存相关接口报错检查bind配置、protected-mode是否关闭微信小程序域名白名单request:fail url not in domain list开发阶段在微信开发者工具里勾选“不校验合法域名”时区问题订单日期差8小时配置jdbc连接串加serverTimezoneAsia/ShanghaiJDK版本不匹配启动报UnsupportedClassVersionError确认JDK版本与pom里java.version一致每次远程调试之前先把对方的JDK版本、MySQL版本、Redis版本、端口占用情况全部问清楚能省下一个下午的时间。还有一个细节代码里所有绝对路径比如上传图片保存的目录、日志文件路径都改成相对路径或者由配置文件去注入不然换一台电脑就跪。5.3 让答辩老师理解“大数据”的讲解话术答辩环节最重要的能力是“把复杂的东西讲简单”。面对不同背景的老师侧重点也要不一样。如果老师是软件工程方向的重点讲架构设计和技术选型为什么要用SpringBoot、为什么用协同过滤而不是深度学习数据量达不到深度学习的要求协同过滤在中小规模数据下效果更好且可解释性更强、表结构怎么设计的、缓存策略怎么做的。如果老师是数据科学方向的重点讲数据处理流程和算法细节评分矩阵怎么构建的、相似度用什么公式算的、冷启动怎么解决的、数据稀疏怎么降维处理的。如果老师是做业务的重点讲系统解决了什么问题用户点外卖时面对几百个菜品有选择困难系统通过分析历史偏好帮他快速找到想吃的商家可以通过系统洞察用户偏好优化菜品排序和菜单结构。准备2~3张清晰的技术架构图、数据流图比背半个小时的稿子有效得多。图要自己画不要直接贴网上找的模板老师问到细节你答不上来就尴尬了。提示论文里的“大数据”章节不要写一堆不相关的大数据发展史空话。直接写你项目里数据的采集方式、数据格式、存储方案、分析流程、应用结果每句话都紧扣自己的系统这才是论文评审老师想看到的。5.4 常见问题速查表最后整理一份我在开发这类项目时反复遇到的坑收藏一下能少走很多弯路。MyBatis Plus 分页失效记得配置MybatisPlusInterceptor并添加PaginationInnerInterceptor不然分页查询永远是全量数据。小程序图片不显示开发阶段在详情工具里勾选“不校验合法域名”生产环境把图片上传到服务器并且使用HTTPS域名。定时任务不执行确认Scheduled所在的类是否被Spring扫描到、是否在启动类上加EnableScheduling。局部会话失效在做登录拦截时排除掉所有不需要登录的URL否则小程序第一次加载首页时会因为token不存在而报401。大JSON传输慢后端返回的菜品列表不要每次都把详情字段查全列表接口只返回必要字段详情接口再全量返回。Redis数据序列化乱码配置RedisTemplate时用Jackson2JsonRedisSerializer或者FastJson的序列化方式不然存进去是Java对象二进制读出来是乱码。多数据源事务问题如果推荐计算涉及的写操作分散在多张表用Transactional统一管理尤其注意在类内部调用this.xxx()时事务是不生效的。6. 从“毕设能过”到“项目能打”的扩展思路6.1 低成本高性价比的加分项如果你做完基础功能后还有富余时间下面几个方向投入产出比极高。引入RabbitMQ做异步解耦。用户的行为上报接口如果每次都是同步写库高峰期会拖慢主流程的响应速度。可以把行为写入MQ后端用消费者异步落库。这既提升了接口性能也让你在简历上多了一个“消息队列”的技术点。代码量不大但面试时说到“为什么用MQ”就能展开讲一大段。增加WebSocket实时通知。用户下单后商家管理后台实时收到新订单提醒不用刷新页面。这个小功能用SpringBoot的WebSocket实现工作量不大但演示效果特别“动感”老师会觉得你的系统很鲜活。引入Redis缓存店铺和菜品热点数据。这两个表属于读多写少的高频访问数据做缓存后能显著减轻MySQL的压力技术上来讲也符合真实系统的缓存设计思路。可以在答辩时给老师展示一个对比数据缓存命中前后接口响应时间从500ms降到了50ms直接量化体现优化效果。做一个A/B测试对比展示页面。管理后台同时展示“个性化推荐”和“热门排序”两个列表在相同用户上的差异并用点击率指标对比两者效果。这会让你的项目在数据驱动决策这个维度上提升一个档次。6.2 扩展成“真大数据”的演进路线这个部分不用真的在毕设里做出来但论文的“展望”章节或者面试场景下如果你能说清楚演进路径会让人觉得你是一个有架构视野的人。当数据量增长到MySQL单机扛不住的时候演进路线大致是存储层MySQL做主从分离 MyCat/ShardingSphere分库分表行为日志迁移到HBase或者ClickHouse。计算层离线统计用Hive Spark SQL跑批相似度矩阵用Spark MLlib里的分布式协同过滤替代单机版本。实时层用户行为通过Kafka接入Flink做实时特征计算把热门榜、实时偏好结果写回Redis缓存。算法层当数据量足够时引入ALS交替最小二乘法做矩阵分解或者用DeepFM一类深度推荐模型做排序。这个演进路线不必全部实现但答辩或面试时能把“当前阶段遇到的问题”和“下一阶段的解决方案”对应起来会给人留下非常深刻的印象。6.3 关于项目定制的最后一点建议如果你不是从头开发而是基于获取到的参考项目进行“定制”和“二次开发”切记不要把别人的项目原封不动交上去。至少做到以下三点第一跑通项目之后把数据库表结构调整一两处比如增加一个字段或一张新表并同步修改对应的后端代码和前端页面做到“从数据库到接口到页面”全链路通畅。第二给自己增加一个别人没有的小功能模块比如“口味偏好标签设置”“好友分享点单”“营销优惠券系统”。不用多一个就够但这个功能最好要贯穿三层表结构、后端接口、前端页面这样讲解的时候从需求、设计到实现有完整的叙事线。第三把代码全部过一遍确保每个文件你都看得懂。答辩现场最怕的是老师随便点开一个类文件问你这个方法做了什么结果你支支吾吾说不出所以然前面的印象分全部归零。我在开发类似项目时的体会是毕设项目最大的价值不在于技术多牛而在于你能否把一个完整的业务闭环讲清楚并让听的人相信这里面确实有你自己的思考。与其堆砌十个你讲不明白的技术名词不如把一个推荐逻辑讲透把一个缓存策略讲明白把一条数据链路讲顺畅。能做到这一点这个项目已经不仅仅是“能过”而是会成为你简历上真正能打的亮点。最后再分享一个小技巧把项目里所有接口的Api注解用起来生成一套完整的Swagger接口文档。演示的时候打开Swagger页面给老师看几十个接口分门别类列在那里比你说一万句“功能完善”都有说服力。而且面试的时候知道用Swagger做接口管理和联调本身就是一线开发的基本素养。
返回列表