news 2026/4/21 9:48:20

苍穹外卖Day09Day10笔记

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
苍穹外卖Day09Day10笔记

苍穹外卖笔记Day09Day10

1. SpringTask 定时任务(苍穹外卖实战)

1.1 基本概念

SpringTask 是Spring 框架原生自带的定时任务工具,无需整合 Quartz 等第三方中间件,轻量、简单、开箱即用,专门用于处理苍穹外卖中「周期性、定时执行」的业务场景,无需手动触发,自动按配置时间执行。

1.2 核心作用(苍穹外卖实战场景)

  1. 定时清理:定时清理过期未支付订单(如 30 分钟未支付自动取消)、清理过期优惠券、清理日志数据;
  2. 定时统计:每日凌晨统计前一天的订单量、营业额、用户新增数量,生成运营报表;
  3. 定时同步:定时同步商品库存、同步用户积分、同步配送状态;
  4. 定时提醒:定时提醒商家处理待接单订单、提醒配送员取餐。

1.3 核心注解(必背,面试高频)

(1)@EnableScheduling
  • 作用:开启 SpringTask 定时任务功能,必须加在SpringBoot 启动类配置类上,否则定时任务不生效。
  • 苍穹外卖实战示例(启动类):
    @SpringBootApplication@EnableScheduling// 开启定时任务publicclassSkyApplication{publicstaticvoidmain(String[]args){SpringApplication.run(SkyApplication.class,args);}}
(2)@Scheduled
  • 作用:标记在「要定时执行的方法」上,指定任务的执行时间、频率。
  • 方法要求:无参数、无返回值(void),否则定时任务会报错。
  • 苍穹外卖实战示例(定时取消过期订单):
    @ServicepublicclassOrderServiceImplimplementsOrderService{// 定时执行:每1分钟检查一次,取消30分钟未支付的订单@Scheduled(cron="0 */1 * * * ?")publicvoidcancelExpiredOrder(){// 业务逻辑:查询30分钟未支付、未取消的订单,执行取消操作List<Order>expiredOrders=orderMapper.selectExpiredUnpaidOrders();for(Orderorder:expiredOrders){order.setStatus(OrderStatus.CANCELLED);order.setCancelReason("订单超时未支付,自动取消");orderMapper.update(order);}}}

1.4 @Scheduled 三大执行方式(面试重点,区分清楚)

(1)fixedRate:固定频率执行(不推荐用于苍穹外卖核心场景)
  • 核心逻辑:从上一次任务开始执行的时间计算,每隔指定时间执行一次,无论上一次任务是否执行完毕。
  • 示例:@Scheduled(fixedRate = 5000)→ 每 5 秒执行一次,即使上一次任务执行了 3 秒,下一次也会在第 5 秒准时启动。
  • 缺点:如果任务执行时间超过设定频率,会导致任务堆积,占用线程资源,苍穹外卖中很少使用(除非是轻量、快速执行的任务)。
(2)fixedDelay:固定间隔执行(苍穹外卖常用)
  • 核心逻辑:从上一次任务执行结束的时间计算,等待指定时间后,再执行下一次任务,避免任务堆积。
  • 示例:@Scheduled(fixedDelay = 5000)→ 上一次任务执行完后,等待 5 秒,再执行下一次。
  • 适用场景:苍穹外卖中耗时较短的定时任务(如每 10 分钟同步一次库存)。
(3)cron 表达式:精准定时(最常用、面试必问)
  • 核心逻辑:通过表达式,精准控制任务的执行时间(支持秒、分、时、日、月、周、年),功能最强大,适配苍穹外卖中所有复杂定时场景。
  • 语法(7个字段,空格分隔):秒 分 时 日 月 周 年(可选)
    • 通配符说明(面试常考):
      • *:匹配所有值(如秒位写 *,表示每秒执行);
      • ?:仅用于「日」和「周」,表示不指定值(避免日和周冲突);
      • /:表示递增(如 0/5 * * * * ? → 每 5 秒执行一次);
      • -:表示范围(如 0 0 9-18 * * ? → 每天 9 点到 18 点,整点执行);
      • ,:表示多个值(如 0 0 12,18 * * ? → 每天 12 点、18 点各执行一次)。
  • 苍穹外卖常用 Cron 示例(面试必背):
    1. 0 0 2 * * ?→ 每天凌晨 2 点(执行日志清理、报表统计);
    2. 0 */1 * * * ?→ 每 1 分钟(检查过期订单);
    3. 0 0 0 * * ?→ 每天凌晨 0 点(重置当日数据统计);
    4. 0 0 12 * * ?→ 每天中午 12 点(推送当日订单统计给商家)。

1.5 SpringTask 执行机制(面试高频,坑点)

(1)默认机制

SpringTask 默认是单线程执行,所有定时任务共用一个线程;如果一个任务执行时间过长(如清理大量日志耗时 5 分钟),会导致其他定时任务延迟执行,甚至卡死。

(2)多线程配置(生产环境必须配置,苍穹外卖实战)

解决单线程阻塞问题,配置线程池,让不同任务在不同线程中执行,互不影响。

  • 配置类代码(面试可直接写):
    @Configuration@EnableSchedulingpublicclassScheduledConfigimplementsSchedulingConfigurer{// 配置线程池,核心线程数根据任务数量调整(苍穹外卖建议5-10个)@OverridepublicvoidconfigureTasks(ScheduledTaskRegistrartaskRegistrar){taskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));}}
  • 面试考点:为什么要配置多线程?答:避免单线程任务阻塞,保证所有定时任务按时执行,提升系统稳定性。

1.6 面试高频问题(结合苍穹外卖)

  1. 苍穹外卖中,SpringTask 用在哪些场景?(答:清理过期订单、统计报表、同步库存、定时提醒);
  2. @EnableScheduling 和 @Scheduled 的作用分别是什么?(答:前者开启定时任务功能,后者标记定时方法);
  3. fixedRate 和 fixedDelay 的区别?(答:前者从任务开始计时,后者从任务结束计时,后者避免堆积);
  4. SpringTask 默认是单线程还是多线程?如何优化?(答:默认单线程,配置线程池优化);
  5. 写出一个“每天凌晨 2 点执行”的 Cron 表达式?(答:0 0 2 * * ?)。

2. WebSocket 详细讲解(苍穹外卖实战)

2.1 基本概念

WebSocket 是一种全双工、双向通信的网络协议,基于 TCP 连接,允许客户端(浏览器/APP)和服务器之间建立持久连接,实现「实时通信」—— 服务器可以主动向客户端推送消息,客户端也可以主动向服务器发送消息,无需客户端频繁发起请求(区别于 HTTP 单向通信)。

2.2 核心作用(区别于 HTTP,面试重点)

HTTP 协议是「请求-响应」模式:客户端发起请求,服务器才会返回响应,服务器无法主动向客户端推送消息;
WebSocket 协议是「持久连接」模式:连接建立后,双方可随时互发消息,实时性极高,无需频繁请求,减少网络开销。

2.3 苍穹外卖实战场景(除了实时提醒新订单)

(1)核心场景1:新订单实时提醒(基础)
  • 商家端:用户下单后,服务器通过 WebSocket 实时向商家推送新订单消息(无需商家刷新页面);
  • 配送端:商家接单后,实时向配送员推送待取餐订单,同步订单地址、取餐时间。
(2)核心场景2:订单状态实时同步(高频)
  • 用户端:用户下单后,实时同步订单状态(待接单 → 待配送 → 配送中 → 已完成),无需刷新页面;
  • 商家端:实时同步订单支付状态(未支付 → 已支付)、取消状态,及时处理订单。
(3)核心场景3:实时聊天(苍穹外卖增值功能)
  • 用户与商家聊天:用户咨询菜品、修改订单,商家实时回复;
  • 用户与配送员聊天:用户询问配送进度,配送员实时反馈。
(4)核心场景4:库存实时更新(秒杀/热销场景)
  • 商家端:热销菜品库存不足时,实时推送库存预警(如“番茄炒蛋库存仅剩5份”);
  • 用户端:用户下单时,实时推送库存变化(如“库存不足,无法下单”)。
(5)核心场景5:实时通知(运营/系统通知)
  • 商家端:平台推送活动通知(如“周末满减活动开启”)、违规提醒、系统维护通知;
  • 配送端:推送配送范围调整、配送费调整通知;
  • 用户端:推送优惠券到账、会员权益更新、订单评价提醒。
(6)核心场景6:实时数据统计(商家后台)
  • 商家端实时查看当日订单量、营业额、接单率,数据随订单变化实时更新,无需手动刷新报表。

2.4 WebSocket 核心原理(面试必背)

  1. 握手阶段:客户端发起 HTTP 请求,请求头中携带Upgrade: websocket,表示要升级为 WebSocket 协议;
  2. 连接建立:服务器响应同意升级,双方建立持久 TCP 连接,后续通信不再使用 HTTP 协议;
  3. 数据传输:连接建立后,客户端和服务器可通过帧(Frame)互发消息,支持文本、二进制数据;
  4. 连接关闭:客户端或服务器主动发送关闭帧,释放连接。

2.5 苍穹外卖 WebSocket 核心实现(简化版,面试可写)

(1)引入依赖(SpringBoot 整合 WebSocket)
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>
(2)配置类(开启 WebSocket 支持)
@ConfigurationpublicclassWebSocketConfig{@BeanpublicServerEndpointExporterserverEndpointExporter(){// 注册 WebSocket 端点,开启 WebSocket 支持returnnewServerEndpointExporter();}}
(3)WebSocket 核心服务类(处理连接、消息推送)
// 端点路径:ws://localhost:8080/ws/order/{merchantId}(商家端,按商家ID区分连接)@ServerEndpoint("/ws/order/{merchantId}")@ComponentpublicclassOrderWebSocketServer{// 存储商家ID与对应的WebSocket连接(key:商家ID,value:连接对象)privatestaticMap<Long,Session>sessionMap=newConcurrentHashMap<>();// 连接建立时执行(商家打开后台页面,建立连接)@OnOpenpublicvoidonOpen(Sessionsession,@PathParam("merchantId")LongmerchantId){sessionMap.put(merchantId,session);}// 连接关闭时执行(商家关闭页面,释放连接)@OnClosepublicvoidonClose(@PathParam("merchantId")LongmerchantId){sessionMap.remove(merchantId);}// 接收客户端消息(商家发送消息给服务器)@OnMessagepublicvoidonMessage(Stringmessage,@PathParam("merchantId")LongmerchantId){// 处理商家消息(如确认接单、拒绝订单)System.out.println("收到商家"+merchantId+"的消息:"+message);}// 核心方法:服务器向指定商家推送消息(如新订单提醒)publicvoidsendMessage(LongmerchantId,Stringmessage){Sessionsession=sessionMap.get(merchantId);if(session!=null&&session.isOpen()){try{session.getBasicRemote().sendText(message);}catch(IOExceptione){e.printStackTrace();}}}}
(4)业务层调用(推送新订单消息)
@ServicepublicclassOrderServiceImplimplementsOrderService{@AutowiredprivateOrderWebSocketServerwebSocketServer;// 下单成功后,向商家推送新订单消息@OverridepublicvoidcreateOrder(OrderDTOorderDTO){// 1. 生成订单、入库等业务逻辑...// 2. 向对应商家推送新订单消息LongmerchantId=orderDTO.getMerchantId();Stringmessage="您有新订单,请及时处理!订单号:"+orderDTO.getOrderNumber();webSocketServer.sendMessage(merchantId,message);}}

2.6 面试高频问题(结合苍穹外卖)

  1. WebSocket 和 HTTP 的区别?(答:HTTP 单向请求-响应,无法主动推送;WebSocket 双向全双工,持久连接,实时性高,减少请求开销);
  2. 苍穹外卖中,WebSocket 除了新订单提醒,还有哪些用途?(答:订单状态同步、实时聊天、库存预警、实时通知、数据统计);
  3. WebSocket 连接建立的过程?(答:客户端发起 HTTP 升级请求 → 服务器响应升级 → 建立 TCP 持久连接);
  4. 如何保证 WebSocket 连接的稳定性?(答:心跳检测、重连机制、异常关闭时释放连接);
  5. 苍穹外卖中,如何区分不同商家的 WebSocket 连接?(答:通过商家ID作为key,存储连接对象,推送消息时根据商家ID定位连接)。

3. 总结(面试重点)

  1. SpringTask:Spring 原生定时工具,核心注解 @EnableScheduling + @Scheduled,三大执行方式(fixedRate、fixedDelay、cron),必须配置多线程避免阻塞,苍穹外卖主要用于定时清理、统计、同步任务;
  2. WebSocket:双向实时通信协议,核心是持久连接,苍穹外卖除新订单提醒,还用于订单状态同步、实时聊天、库存预警等场景,核心实现是端点配置 + 连接管理 + 消息推送;
  3. 两者关联:SpringTask 可定时触发 WebSocket 消息推送(如每天中午推送订单统计),共同支撑苍穹外卖的定时、实时业务需求。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/21 9:47:15

终极指南:3步实现微信平板模式,轻松突破安卓多设备登录限制

终极指南&#xff1a;3步实现微信平板模式&#xff0c;轻松突破安卓多设备登录限制 【免费下载链接】WeChatPad 强制使用微信平板模式 项目地址: https://gitcode.com/gh_mirrors/we/WeChatPad 你是否曾为微信"手机与平板不能同时在线"的限制而烦恼&#xff1…

作者头像 李华
网站建设 2026/4/21 9:43:21

Qianfan-OCR详细步骤:Gradio WebUI本地部署与Layout-as-Thought调用

Qianfan-OCR详细步骤&#xff1a;Gradio WebUI本地部署与Layout-as-Thought调用 1. 项目概述 Qianfan-OCR是百度千帆推出的开源端到端文档智能多模态模型&#xff0c;基于4B参数的Qwen3-4B语言模型构建。这个多模态视觉语言模型(VLM)采用Apache 2.0协议&#xff0c;完全开源且…

作者头像 李华
网站建设 2026/4/21 9:40:21

STM32F4 + FreeRTOS + LwIP 2.1.3 网络栈移植保姆级避坑指南(附完整源码)

STM32F4 FreeRTOS LwIP 2.1.3 网络栈移植实战全解析 在嵌入式系统开发中&#xff0c;网络功能的实现往往是最具挑战性的环节之一。当我们需要在STM32F4平台上结合FreeRTOS实时操作系统和LwIP轻量级TCP/IP协议栈构建网络应用时&#xff0c;版本兼容性、接口适配和系统整合等问…

作者头像 李华
网站建设 2026/4/21 9:40:19

PinWin窗口置顶工具:告别窗口切换烦恼,让多任务效率翻倍

PinWin窗口置顶工具&#xff1a;告别窗口切换烦恼&#xff0c;让多任务效率翻倍 【免费下载链接】PinWin Pin any window to be always on top of the screen 项目地址: https://gitcode.com/gh_mirrors/pin/PinWin 你是否曾经在编写代码时&#xff0c;需要频繁地在编辑…

作者头像 李华
网站建设 2026/4/21 9:39:22

合并两个有序数组

题目思路两个数组非递减有序&#xff0c;合并到nums1且原地修改。采用从后往前双指针&#xff1a;i指向nums1有效尾部&#xff0c;j指向nums2尾部k指向nums1最终尾部&#xff0c;每次放较大元素最后把nums2剩余元素直接复制进nums1。难点从前向后会覆盖nums1原数据&#xff0c;…

作者头像 李华
网站建设 2026/4/21 9:38:20

实战:用Java版TinyRadius客户端,给你的Spring Boot应用加上RADIUS双因素认证

实战&#xff1a;用Java版TinyRadius客户端为Spring Boot应用集成RADIUS双因素认证 在企业级应用开发中&#xff0c;安全认证始终是系统架构的核心环节。随着网络安全威胁日益复杂&#xff0c;传统的用户名密码认证已无法满足高安全场景需求。本文将深入探讨如何利用TinyRadius…

作者头像 李华