ARTICLE DETAIL

资讯详情

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

SpringBoot+大数据+AI电商平台:从架构设计到答辩实战

SpringBoot+大数据+AI电商平台:从架构设计到答辩实战 每年毕业季SpringBoot商城项目大概是最不缺同类品的题目了。你在各种代码仓库里一搜能翻出上万套“SpringBootVue”的电商系统功能清单长得跟复制粘贴似的登录注册、商品管理、购物车、订单、支付。如果只是把这些东西再拼一遍答辩的时候老师翻两页就困了。真正让题目脱胎换骨的往往是你怎么理解“智慧商城”“大数据”“AI”这几个词而不是你堆了多少页面。这套“慧购”一体化电商运营平台我前前后后做了三个多月核心心得就一句话SpringBoot只是底座数据才是这个项目的灵魂。下面把设计思路、踩坑过程、答辩准备完整拆给大家。1. 从选题到系统定位这个毕设为什么值得做、怎么做才不烂大街1.1 题目拆解三个关键词背后是三种能力先说“智慧商城”。很多同学把它理解成“商城 推荐位”数据库里存个商品表、前端放几个轮播图就完事。但“智慧”二字真正的含义应该是系统能够理解用户行为并且根据行为动态调整运营策略。也就是说商品展示、促销活动、客服应答这些环节不再是人拍脑袋配置的静态页面而是有数据依据的动态结果。再说“一体化运营平台”。光有用户下单的C端还不够还得有运营人员使用的B端后台、管理层看的数据大屏、客服用的智能应答模块。这四个端的数据必须打通用户在手机端的每一次点击、停留、加购、下单最终都能在运营后台和数据大屏上以指标形式呈现形成一个从“用户行为”到“运营决策”的闭环。最后是“大数据与AI”。在春招和毕设里这两个词被用得很烂但我认为它们在本项目里承担的是实打实的工程任务大数据负责处理用户行为日志的采集、清洗、聚合产出PV、UV、GMV、转化率等指标AI负责推荐排序、客服意图识别、搜索词联想。它们不是炫技而是为了让一个传统CRUD商城拥有“自适应”的能力。1.2 功能边界哪些做哪些坚决不做做毕业设计最容易翻车的地方是野心太大。一开始我也想过接入支付、接入物流、做秒杀系统后来冷静下来把功能边界划成一张表只保留对“数据闭环”有价值的部分模块核心功能数据价值用户端商城登录、商品浏览、搜索、购物车、下单、评价、客服咨询行为日志、订单事实运营后台商品管理、类目管理、订单管理、用户管理、营销活动配置运营配置数据、审核链路过账数据大屏实时GMV、订单量、热销榜、区域分布、转化漏斗数据聚合结果展示推荐引擎首页猜你喜欢、商品详情相似推荐、搜索联想推荐点击率、曝光日志智能客服商品咨询、订单状态查询、售后意图识别会话日志、意图分类结果系统支撑登录鉴权、数据权限、操作审计、限流管控安全保障与追踪支付和真实物流被我砍掉了。原因很现实毕设项目不接入真实支付通道多一个支付模块只会增加联调成本和演示风险物流同理既没有真实运单数据也没有办法模拟全链路状态对核心数据闭环没有边际贡献。项目名里的“轻量级”不是说功能做得少而是把资源集中在容易展示、容易被评委追问的数据链路上。1.3 技术选型轻量但要有东西可以讲技术栈我最终定为Spring Boot 2.7 作为底座MyBatis-Plus 操作数据库MySQL 存业务数据Redis 做缓存与SessionKafka 做行为日志的削峰缓冲Flink 做实时指标计算Hive 做离线数仓的批处理Vue 3 Element Plus 搭前端ECharts 画大屏。这套选型看起来组件不少但每个组件都能说出明确的职责评审老师问“为什么引入Kafka/Flink”时你不至于只会说“业界都在用”。有同学建议我上微服务把用户、商品、订单都拆成独立服务。我犹豫了很久还是没拆。毕设场景下微服务的注册发现、配置中心、链路追踪会吞噬掉大量本该用于业务逻辑的时间而且单体多模块架构完全能讲清楚模块边界和依赖方向。反而是一上来就拆十几二十个微服务的项目最后往往因为服务间调用逻辑混乱而被评委连环追问。2. SpringBoot工程架构设计模块边界与自定义自动配置2.1 Maven多模块让项目结构本身就是一张架构图我见过太多“一个SpringBoot项目里塞几百个Controller”的毕业设计controller、service、mapper全在同一个包里最后类之间互相引用看得人头皮发麻。这套“慧购”平台从一开始就按Maven多模块来组织工程结构因为模块边界本身就是最直接的架构表达。huigou-parent父POM统一版本号与依赖管理 ├── huigou-common通用工具统一返回体、异常、脱敏工具、时间工具 ├── huigou-system核心业务用户、商品、订单、购物车、营销 ├── huigou-analytics大数据模块埋点接收、Kafka生产者、实时/离线任务入口 ├── huigou-aiAI模块推荐引擎、意图识别、搜索联想 ├── huigou-adminB端运营后台接口商品审核、订单处理、数据查询 └── huigou-web对外聚合层Controller入口、鉴权过滤、跨域处理模块间的依赖方向是单向的web 依赖 system、analytics、aisystem 依赖 commonanalytics 依赖 commonai 依赖 common 和 system 的查询接口。谁都不允许反向依赖否则编译期就报错这在公司里叫“依赖方向约束”在毕业设计里同样管用。2.2 自定义自动配置看似“炫技”实则解耦项目里有个比较容易被忽略但也值得写进简历的点是自定义自动配置。因为 common、analytics 这些模块要被 web 集成我不想在每个模块里重复写ComponentScan而是直接在 resources 目录下放了一个META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件把每个模块的自动配置类注册进去。AutoConfiguration ConditionalOnClass(RedisTemplate.class) EnableConfigurationProperties(HuigouCacheProperties.class) public class HuigouCacheAutoConfiguration { Bean ConditionalOnMissingBean public CacheManager cacheManager(RedisConnectionFactory factory) { RedisCacheManager.Builder builder RedisCacheManager.builder(factory); // 设置默认过期时间 30 分钟支持按缓存名覆盖 builder.cacheDefaults(RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofMinutes(30)) .serializeValuesWith(SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))); return builder.build(); } }这里最核心的是ConditionalOnClass和ConditionalOnMissingBean这两个条件注解。前者保证没有Redis依赖时这个配置直接跳过不会启动报错后者保证如果使用方自定义了CacheManager自动配置不会去覆盖它。用这种方式每个模块都可以独立维护自己的默认配置同时又允许业务方按需定制比把配置全部堆在启动类里干净得多。2.3 SpringBoot版本不用追新但别掉进旧坑Spring Boot 版本这块我提一句热词里总有人搜“springboot版本太高”这种焦虑我太理解了。我一开始用了 Spring Boot 3.0结果发现 javax 包改成 jakarta 了Spring Security 的配置方式也变了很多博客里的旧代码直接跑不起来。后来我老老实实退回 2.7.x理由很简单2.7 是 2.x 的最后一个稳定大版本网上资料最多、踩坑记录最全、mybatis-plus 和各种第三方组件的兼容性最稳。如果你非要用 3.x也不是不行但需要额外处理三件事一是所有javax.*的依赖注入要改为jakarta.*二是spring.factories自动配置方式被废弃改用 AutoConfiguration.imports三是某些中间件客户端要升级到适配 Spring Boot 3 的版本。作为毕设这些迁移成本换来的收益并不明显所以我建议老实待在 2.7。3. 大数据链路从埋点到数据大屏把每个环节跑通这一章是整套系统最核心的部分也是答辩时最可能被重点追问的部分。大数据如果只是写几个 SQL 去 count 一下表那跟普通管理后台没有本质区别。真正的数据链路应该是前端行为产生日志 → Kafka 传输 → Flink 实时聚合 → MySQL/Redis 结果表 → 数据大屏展示同时原始日志落地 HDFS → Hive 离线清洗 → 数仓分层 → 离线报表。3.1 前端埋点与数据接入埋点是一个容易被轻视的环节。我在用户端页面里引入了一个轻量级埋点 SDK核心代码其实不复杂就是拦截点击事件然后异步把行为数据发给后端。// analytics.js 简化版埋点SDK function track(eventName, params {}) { const data { event: eventName, userId: getUserId() || anonymous, page: window.location.pathname, timestamp: Date.now(), params }; // 用sendBeacon保证页面跳转时也能发出 navigator.sendBeacon(/api/analytics/collect, JSON.stringify(data)); } // 商品曝光 document.addEventListener(click, (e) { const el e.target.closest([data-product-id]); if (el) { track(product_click, { productId: el.dataset.productId }); } });后端收集接口收到日志后没有立刻写 MySQL而是先发送到 Kafka 的user-behavior-topic。这个设计的目的是削峰。如果大量用户同时点击直接暴打数据库数据库会瞬间压力很大引入 Kafka 后日志先缓冲在生产消息队列里Flink 按照自己的处理速度拉取数据数据库就稳了。在真实场景里这叫“异步削峰”。我在本地模拟过 200 个并发用户持续点击 5 分钟Kafka 的生产延迟在 10 毫秒以内Flink 消费端吞吐量稳定在每秒 3000 条以上。3.2 Flink实时指标计算窗口怎么选口径怎么定Flink 任务我用了三种窗口类型来计算不同指标浏览 PV 用滚动窗口Tumbling每 10 秒输出一次UV 用会话窗口Session60 秒无新行为就切一个新会话热销榜用滑动窗口Sliding每 5 分钟刷新一次最近 30 分钟的下单商品排名。// 简化版的实时热销榜逻辑 DataStreamBehaviorEvent stream ...; stream.filter(_.eventType.equals(order_create)) .map(e - Tuple2.of(e.productId, 1L)) .keyBy(t - t.f0) .window(SlidingEventTimeWindows.of(Time.minutes(30), Time.minutes(5))) .aggregate(new SumAggregator()) .keyBy(t - t.f0) .process(new TopNProcessFunction(50));这里有一个特别容易被问住的细节实时计算里的 GMV和离线数的 GMV 不一致怎么办我在设计里定了这么一套对齐口径实时 GMV 统计的是订单支付成功事件离线 GMV 统计的是数据库订单表中支付状态为已支付的数据两者会存在因数据同步延迟造成的短暂差异。我在数据大屏上特意标注“数据更新延迟不超过1分钟”这是对自己口径极其重要的一个保护一要提前想清楚二要主动写在系统说明里。3.3 离线数仓Hive分层让报表查询不再全表扫描离线这块我按标准数仓的四层模型来建-- ODS层原始日志分区按天 CREATE TABLE ods_user_behavior_log ( user_id STRING, product_id STRING, event_type STRING, page_url STRING, event_time TIMESTAMP ) PARTITIONED BY (dt STRING); -- DWD层清洗明细去掉空值和无效事件 INSERT OVERWRITE TABLE dwd_user_behavior_log PARTITION(dt) SELECT user_id, product_id, event_type, page_url, event_time FROM ods_user_behavior_log WHERE dt ${yesterday} AND user_id IS NOT NULL AND product_id IS NOT NULL; -- DWS层按商品维度的日汇总 INSERT OVERWRITE TABLE dws_product_daily PARTITION(dt) SELECT product_id, COUNT(DISTINCT user_id) AS uv, SUM(IF(event_typeadd_to_cart,1,0)) AS cart_cnt, SUM(IF(event_typeorder_create,1,0)) AS order_cnt FROM dwd_user_behavior_log WHERE dt ${yesterday} GROUP BY product_id;这套分层最大的好处是口径统一。ODS 保留最原始数据DWD 做清洗DWS 做汇总ADS 层再做业务口径的宽表每一层职责清晰出问题能回查源头。很多同学直接用 SQL 从原始表 count 出结果应用层一改口径就要重算后来排查到哪一步出了问题完全没有数的血缘关系这是不应该的。3.4 数据大屏不只是图表更是“数据说服力”大屏是整个项目最直观的展示出口。我用 ECharts 做了实时订单流、热销商品排行榜和区域地图。数据从后端聚合接口获取接口先去 Redis 读读不到再查 MySQL 并回填 Redis缓存时间设 30 秒。因为大屏接口是高频轮询直接打 MySQL 会把自己打崩。轮询频率我定在每 5 秒一次这个节奏刚好不会刷新太快看着眼花也不会慢到让观众觉得“卡了”。关于大屏还有一个展示上的建议一定要给每个图表配上指标说明文字和一个“数据更新时间”。答辩的时候老师看着跳动的数字第一反应往往是“这数据是真的假的”。如果你的大屏上写着“最近30分钟热销商品榜 每5分钟更新”这个质疑就消掉大半。3.5 数据权限运营后台的行与列控制热词里也提到了“大数据行列权限设计”这个问题在运营后台特别现实。不是所有运营都能看全部数据的。我的方案是双层权限行级别通过部门数据域控制比如华东运营组只能查华东区域订单列级别通过字段脱敏控制比如客服角色查询用户时手机号中间四位自动打码收货地址只显示到区和街道。// 列脱敏的自定义处理示例 Sensitive(type SensitiveType.MOBILE_PHONE) private String mobile; // 行级过滤MyBatis-Plus 拦截器注入 InterceptorIgnore public class DataScopeInterceptor implements InnerInterceptor { Override public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { // 根据当前登录用户的数据域拼接 SQL 条件 String sql boundSql.getSql(); String filteredSql SELECT * FROM ( sql ) t WHERE t.region IN (...权限范围...); // 使用反射修改 BoundSql 中的 sql 字段 } }这块代码看着不多但完成壮观的权限演示效果很好。演示的时候我先用超管账号看全部数据再切换到区域运营账号屏幕上的订单列表立刻少了一半。老师一眼就能看懂你做了数据权限控制这一点比写一百行权限接口代码都直观。4. AI功能落地推荐系统的冷启动与智能客服的工程化实现AI 模块是最容易被评委“刨根问底”的地方。如果只写一个“接入了大模型API”老师很可能会追问你的 API Key 是怎么管理的如果断网了怎么办这算你自己的工程成果吗所以我的策略是推荐算法自行实现客服走检索式问答与规则意图识别把可解释性放在第一位。4.1 推荐引擎为什么选 ItemCF而不是复杂的深度学习我用的主推荐算法是物品协同过滤Item-Centric Collaborative Filtering简称 ItemCF。它的核心思想很简单如果用户A同时喜欢商品X和商品Y说明X和Y有一定相似性那么给喜欢X的用户B推荐Y就有较大概率被接受。计算商品相似度的公式是sim(i, j) |喜欢商品i的用户集合 ∩ 喜欢商品j的用户集合| / sqrt(|喜欢i的用户数| * |喜欢j的用户数|)选择 ItemCF 而不是 UserCF是因为商城场景下用户量远大于商品量商品数量稳定在几千到几万计算商品间的相似度矩阵成本可控而且实时性好。深度学习召回模型对数据量和训练资源要求高在毕设有限样本下反而容易过拟合。选型时我做了个对比方案优点劣势是否适合本项目UserCF发现用户新兴趣用户量巨大时矩阵计算困难否ItemCF可解释性强计算量小无法给用户推荐全新品类是深度学习召回精度上限高需要大量样本和训练资源否为了给推荐结果提供解释依据我在推荐结果接口里返回了推荐理由比如“因为买了 iPhone 充电器推荐同品牌数据线”。这个小小设计在演示时非常有说服力因为它让推荐结果不再是一个玄学黑盒。4.2 冷启动新用户和新商品怎么处理新用户没有任何行为数据协同过滤直接失效。我做了三层兜底策略第一层新用户登录后先看运营配置的热门榜单从 Redis 里直接取最近 7 天销量 Top20 的商品第二层根据用户注册时选的兴趣标签数码、服装、美妆等做品类初筛第三层等用户产生了 5 次以上点击行为后系统才开始为他跑 ItemCF 实时推荐并随着行为数增加逐渐加大协同过滤结果的权重。新商品的处理同样棘手新商品没有用户行为ItemCF 算出来的相似度是 0。我给新商品打上“新品”标记在前 7 天优先走类目冷启动池将其推荐给那些对同类目商品点击较多的用户等积累起足够行为数据再进入常规推荐流程。4.3 智能客服检索式问答比生成式更稳智能客服我没有上大模型生成式对话而是做了“意图识别 检索问答”的方案。先用 HanLP 对用户提问做分词和词性标注再通过关键词规则映射到预定义意图商品咨询、订单查询、退款售后、物流咨询、人工转接。每个意图绑定一个知识库表通过 BM25 做相关性检索返回最匹配的答案。// 意图识别简化逻辑 public Intent matchIntent(String question) { ListString words hanlp.segment(question); if (containsAny(words, 退款, 退货, 售后)) { return Intent.AFTER_SALE; } if (containsAny(words, 订单, 发货, 物流)) { return Intent.ORDER_STATUS; } if (containsAny(words, 多少钱, 价格, 优惠)) { return Intent.PRODUCT_PRICE; } return Intent.FALLBACK; }这样设计的好处是每一句回答都能溯源到知识库里的哪一条完全可控。答辩如果问“你这客服翻车怎么办”你可以直接回答“业务规则之外会转人工不会让模型自由发挥”。在演示时我输入“手机什么时候发货”客服自动回了一段订单状态查询结果评委的追问方向马上就转向会话逻辑设计而不是纠结于模型幻觉。4.4 为什么不在核心链路里硬塞大模型我不是否定大模型而是认为在毕设场景里引入大模型需要先想好四件事一是本地部署大模型的硬件成本二是生成式结果不可控的演示隐患三是知识库更新时检索效果不稳定四是学校答辩环境不一定有稳定的外网连接。我的处理方式是把大模型接口做成了一个预留的ChatProvider抽象如果将来有条件、有网络可以随时替换掉规则回答的实现类不需要动其他代码。这种“预留但不依赖”的做法在答辩时反而是加分项。5. 前后端工程化从Vite本地联调到SpringBoot一体化打包很多毕设项目前后端用两个端口部署前端跑 5173后端跑 8080最后把两个包一压就交了。实际上这暴露了工程化能力的欠缺。整的系统的最终产物应该是一个可以直接java -jar启动的独立 SpringBoot 应用前端资源全部打包进 Jar 包。5.1 开发环境Vite代理解跨域开发时前后端分离前端调用接口需要走代理不然浏览器会拦截跨域请求。我在vite.config.js里这样配export default defineConfig({ server: { port: 5173, proxy: { /api: { target: http://localhost:8080, changeOrigin: true, rewrite: path path.replace(/^\/api/, ) } } } })这里有个细节后端接口路径统一不带/api前缀前端代理才需要把/api去掉后端跨域配置里再允许http://localhost:5173这个来源。双保险开发时基本不会遇到跨域问题。5.2 Vue打包进SpringBoot路由模式的坑打包前的关键一步是把 Vue 的编译产物放进 SpringBoot 的src/main/resources/static目录。但首页直接刷新会 404因为 Vue 用 history 路由模式时浏览器请求一个不存在于静态文件里的路径SpringBoot 找不到对应的资源就会抛 404。解法有两种一是改用 hash 路由地址栏会带#二是在后端加一个路由转发控制器把所有非 API 路径请求转发到index.html。Controller public class SpaForwardController { RequestMapping(value {/, /product/**, /cart/**, /order/**, /user/**}) public String forward() { return forward:/index.html; } }我选了第二种因为地址栏干净而且更接近真实生产项目的处理方式。转发配置必须放在 API 接口之外只拦截前端路由会涉及的路径。5.3 打包优化用cdn还是本地依赖Element Plus 和 ECharts 的体积都不小打进静态资源后 Jar 包会变得很臃肿。我做了几项优化组件库按需导入ECharts 只注册用到的图表类型路由懒加载最终 Jar 包大小控制在 120MB 左右。这里我不建议把公共库全部改成 CDN 引入因为演示环境网络状况不可控真遇到没网的情况页面全白那就尴尬了。本地依赖虽然让包大一点但稳定性才是第一位的。5.4 部署一个jar搞定演示环境部署我用的是 Dockerfile基础镜像用eclipse-temurin:8-jre把 Jar 包放进去开放 8080 端口。FROM eclipse-temurin:8-jre WORKDIR /app COPY target/huigou-platform.jar app.jar EXPOSE 8080 ENTRYPOINT [java, -Xmx512m, -jar, app.jar]在演示用的笔记本上跑这个容器启动内存控制在 512MB 以内后台同时跑 MySQL、Redis、Kafka、Flink 本地任务也不至于卡死。这个选型经过深思熟虑因为毕设现场往往不会给你一台高性能服务器轻量、省资源是最大的生存法则。6. 权限、缓存与性能答辩中躲不开的工程问题功能做出来了业务逻辑都通但如果问你性能优化、安全防护、缓存穿透你答不上来整个项目评价就会降级。这一章我自己整理了一份高频追问清单。6.1 RBAC与数据权限用户表之外还要有角色和菜单用户端没什么复杂的权限逻辑登录后拿到 Token 就能访问商城接口。但运营后台不一样必须有完整的 RBAC 模型用户表、角色表、菜单表、用户角色关系表、角色菜单关系表。前端根据接口返回的权限码渲染菜单和按钮后端在拦截器里校验每个接口的权限码。数据权限单独设计。部门表里存数据域编码比如华东、华南用户所属部门决定了能查哪些区域的数据。查询订单时通过 MyBatis-Plus 的拦截器自动拼接区域条件业务代码无感知。这个组合拳在答辩时讲五分钟都不重样关键是你确实实现了不是背概念。6.2 Redis缓存别让数据库裸奔商品详情是热点数据查询量最大。我用 Redis 做了两级保护第一层热门商品详情直接缓存 30 分钟第二层用逻辑过期解决缓存击穿即缓存中存一份带过期时间的商品数据如果发现过期先返回旧数据同时异步去数据库刷新缓存。缓存穿透也做了防护。查询一个不存在的商品 ID 时Redis 查不到数据库也查不到请求全打在数据库上就穿透了。我采用布隆过滤器拦截不存在的 ID再用“缓存空结果 短过期时间”兜底双管齐下。压测结果没有缓存时商品详情接口 300 并发下数据库连接池直接饱和平均响应 3.2 秒加了 Redis 缓存后平均响应降到 20 毫秒以内数据库只承受了业务写入压力。6.3 接口安全与限流参数校验、SQL注入、防刷接口安全这块我做了三件事。第一所有前端查询接口参数强制用 DTO 接收NotBlank、Size这类注解做基础校验第二MyBatis 全部使用#{}预编译参数禁止字符串拼接SQL第三针对发送验证码、搜索这类可被刷的接口用 Guava 的 RateLimiter 做单机限流每用户每分钟最多请求 10 次。还有日志脱敏。用户手机号、身份证号这类敏感字段在日志输出时自动打码避免运维排查问题时数据泄露。这些细节未必会在答辩现场被看到但写在系统说明里会显得专业。6.4 数据一致性订单和库存怎么联动电商系统里最容易被追问的是超卖问题。我在下单接口里用 SQL 条件更新控制扣减库存而不是先查库存再扣减UPDATE product_sku SET stock stock - #{count} WHERE sku_id #{skuId} AND stock #{count};这个语句执行后如果影响行数为 0说明库存不足或商品下架直接返回“库存不足”即可不需要分布式锁简单可靠。用 Redis 预减库存的策略虽然高性能但对于毕设来说一旦缓存和数据库不一致就被评委抓住把柄。追求简单可解释的方案在工程上是同样被看重的取舍。7. 演示流程与答辩准备细节决定最终分数7.1 演示路径先C端后B端最后放大招演示的顺序很重要。我的建议是先花 30 秒介绍项目定位和技术栈然后走一遍用户端完整购物流程注册、浏览商品、加购、下单、支付模拟、查看订单接着切到运营后台展示商品上下架、订单审核、用户管理最后打开数据大屏让评委看到之前操作产生的订单实时跳动在屏幕上再打开推荐结果页解释为什么给这个用户推荐这些商品。这套路径本质上是先建立信任感再展示工程量最后通过数据埋点把前两个部分串成一个闭环。评委看到你在用户端下单然后数据大屏的 GMV 数字增长那种“数据通起来了”的直观感受比任何 PPT 都有效。7.2 高频追问与参考答案我整理了现场最可能被问到的六个问题每个都有对应的回答思路为什么用 Flink 不用 Spark Streaming答毕设场景需要快速开发、窗口 API 友好Flink 的精确一次语义和低延迟更适合实时指标场景Spark 更偏批处理流处理适合用于更复杂的生产链路。实时和离线指标不一致怎么办答定义口径和使用场景不同实时用于大屏监控离线用于每日复盘前端标注延迟范围。商品推荐冷启动怎么解决答热榜兜底、行为数据积累后再切协同过滤。你的系统单机能承受多少并发答给出本地压测的具体数据同时说出性能瓶颈在数据库连接和 GC不至于空口吹。为什么不做微服务答单体多模块足够承载业务关注可部署性和可解释性对毕设评审来说正确取舍比盲目分布式更重要。Kafka 挂了怎么办答埋点日志先落在本地缓存Kafka 恢复后重发同时订单核心链路不依赖 Kafka业务主流程照常运行。7.3 做这个项目我最后悔没早点做的事如果重来一遍我会一开始就写好数据处理的口径文档而不是边写边想等大屏做完发现实时指标和离线报表对不上返工了整整一个星期。还有一个建议是从写第一行代码之前就录屏。我最后录了 15 分钟的完整演示视频放在项目说明里。答辩现场如果投影仪出问题或者演示环境网络不稳这段视频能救你一命。另外一个实际经验是把每个模块的测试数据做得尽量真实。商品名称不要用“商品1”“商品2”而是真实品类和品牌当然不要拿真实品牌做商用暗示用户注册信息也不要 desist 全是“张三李四”。评委在演示时看到“华为手机壳”“优衣库基础款T恤”这类数据会觉得你对业务场景有真实理解而不是在糊弄。数据质量本身也是毕设的一部分这个细节很多人会忽略。
返回列表