当前位置: 首页 > news >正文

Mall脚手架总结(四) —— SpringBoot整合RabbitMQ实现超时订单处理

前言

        在电商项目中,订单因为某种特殊情况被取消或者超时未支付都是比较常规的用户行为,而实现该功能我们就要借助消息中间件来为我们维护这么一个消息队列。在mall脚手架中选择了RabbitMQ消息中间件,接下来荔枝就会根据功能需求来梳理一下超时订单处理功能以及相应的背景知识。希望对正在学习的小伙伴有帮助~~~


文章目录

前言

一、整合RabbitMQ实现延时消息

1.1 RabbitMQ管理界面的VirtualHost

1.2 回顾:枚举类的优点

1.3 划重点:Spring AMQP框架 

1.3.1 AMQPTemplate

1.3.2 Message

1.3.3 @RabbitListener注解

1.4 订单超时未支付取消订单的流程

总结


一、整合RabbitMQ实现延时消息

1.1 RabbitMQ管理界面的VirtualHost

        Virtual Host虚拟主机,相当于是一个个的相对独立的RabbitMQ服务器。每个虚拟主机都有自己独立的用户、权限、交换机(exchange)、队列(queue)和绑定关系。在RabbitMQ中,每个连接到服务器的客户端都必须选择一个虚拟主机进行操作。如果客户端没有指定虚拟主机,默认会使用/作为虚拟主机,也就是RabbitMQ默认的虚拟主机。为保证隔离性,这里声明了一个/mall的虚拟主机,与我们默认的用户虚拟主机/隔离开来。

1.2 回顾:枚举类的优点

枚举类Enum是一种特殊的数据库类型,用于表示固定数量的命名常量,枚举类定义了一个新的数据类型,该类型可以包含一组预定义的值。

优点:

  • 安全性:保证方法参数的类型的安全性,避免非法值的传入;
  • 避免魔法数字: 枚举类可以帮助你避免在代码中使用魔法数字(magic numbers)。魔法数字是指在代码中直接使用的、没有明确含义的数字。使用枚举类可以为这些常量提供有意义的名字。
  • 支持迭代器(Iteration): 枚举类提供了一种便捷的方式来遍历枚举值。

所以在脚手架中我们定义交换机名称、队列名称和routingKey就借助了枚举类。

/*** @auther lzddl* @description 消息队列枚举配置*/
@Getter
public enum QueueEnum {/*** 消息通知队列*/QUEUE_ORDER_CANCEL("mall.order.direct", "mall.order.cancel", "mall.order.cancel"),/*** 消息通知ttl队列*/QUEUE_TTL_ORDER_CANCEL("mall.order.direct.ttl", "mall.order.cancel.ttl", "mall.order.cancel.ttl");/*** 交换机名称*/private String exchange;/*** 队列名称*/private String name;/*** 路由键*/private String routeKey;QueueEnum(String exchange, String name, String routeKey) {this.exchange = exchange;this.name = name;this.routeKey = routeKey;}
}

1.3 划重点:Spring AMQP框架 

        Spring AMQP是一个基于AMQP协议的强大的消息中间件框架,它提供了一个简单的API来发送和接收异步、可靠的消息。AMQP是Spring框架的一部分,可以与Spring Boot和其他Spring项目一起使用。Spring AMQP支持多种消息协议,包括RabbitMQ、Apache ActiveMQ和Qpid等。它提供了一个高级的消息模型,包括消息确认、事务和消息监听器等功能,使得开发者可以轻松地编写可靠的消息应用程序。同时Spring AMQP还提供了一些高级特性,如消息转换器、消息路由、消息过滤和消息拦截等。总的来说,Spring AMQP 是对 Spring 基于 AMQP 的消息收发解决方案,在SpringBoot项目中操作消息中间件RabbitMQ的相关操作的时候,我们需要借助Spring提供的AMQP框架!

AMQP:高级消息队列协议,是面向消息的中间件的平台中立的线级协议。

Spring AMQP的核心组件:

  • ConnectionFactory:连接工厂接口,用于创建连接。

  • AmqpAdmin:封装了RabbitMQ的基础管理操作,比如对交换机、队列、绑定的声明和删除等。
  • Message:Spring AMQP 对消息的封装。两个重要的属性:body:消息内容;messageProperties:消息属性。
  • 消息模板AmqpTemplate: 用来简化消息的收发,支持消息的确认与返回。跟 JDBCTemplate一 样,它封装了创建连接 、创建消息信道、收发消息、消息格式转换、关闭信道、关闭连接等等操作。

  • 消息监听Messager Listener: Spring AMQP 异步消息投递的监听器接口,它只有一个方法onMessage,用于处理消息队列推送来的消息。

  • 转换器MessageConvertor:用来处理消息对象的序列化和反序列化的操作工具,它可以将消息对象转换为消息队列可以处理的格式,并将接收到的消息转换为Java对象。

1.3.1 AMQPTemplate

AMQPTemplate是Spring AMQP框架提供的一个接口,它定义了一系列用于发送和接收消息的方法。我们来看看源码并归类一下这些方法:

public interface AmqpTemplate {void send(Message var1) throws AmqpException;void send(String var1, Message var2) throws AmqpException;void send(String var1, String var2, Message var3) throws AmqpException;void convertAndSend(Object var1) throws AmqpException;void convertAndSend(String var1, Object var2) throws AmqpException;void convertAndSend(String var1, String var2, Object var3) throws AmqpException;void convertAndSend(Object var1, MessagePostProcessor var2) throws AmqpException;void convertAndSend(String var1, Object var2, MessagePostProcessor var3) throws AmqpException;void convertAndSend(String var1, String var2, Object var3, MessagePostProcessor var4) throws AmqpException;@NullableMessage receive() throws AmqpException;@NullableMessage receive(String var1) throws AmqpException;@NullableMessage receive(long var1) throws AmqpException;@NullableMessage receive(String var1, long var2) throws AmqpException;@NullableObject receiveAndConvert() throws AmqpException;@NullableObject receiveAndConvert(String var1) throws AmqpException;@NullableObject receiveAndConvert(long var1) throws AmqpException;@NullableObject receiveAndConvert(String var1, long var2) throws AmqpException;@Nullable<T> T receiveAndConvert(ParameterizedTypeReference<T> var1) throws AmqpException;@Nullable<T> T receiveAndConvert(String var1, ParameterizedTypeReference<T> var2) throws AmqpException;@Nullable<T> T receiveAndConvert(long var1, ParameterizedTypeReference<T> var3) throws AmqpException;@Nullable<T> T receiveAndConvert(String var1, long var2, ParameterizedTypeReference<T> var4) throws AmqpException;<R, S> boolean receiveAndReply(ReceiveAndReplyCallback<R, S> var1) throws AmqpException;<R, S> boolean receiveAndReply(String var1, ReceiveAndReplyCallback<R, S> var2) throws AmqpException;<R, S> boolean receiveAndReply(ReceiveAndReplyCallback<R, S> var1, String var2, String var3) throws AmqpException;<R, S> boolean receiveAndReply(String var1, ReceiveAndReplyCallback<R, S> var2, String var3, String var4) throws AmqpException;<R, S> boolean receiveAndReply(ReceiveAndReplyCallback<R, S> var1, ReplyToAddressCallback<S> var2) throws AmqpException;<R, S> boolean receiveAndReply(String var1, ReceiveAndReplyCallback<R, S> var2, ReplyToAddressCallback<S> var3) throws AmqpException;@NullableMessage sendAndReceive(Message var1) throws AmqpException;@NullableMessage sendAndReceive(String var1, Message var2) throws AmqpException;@NullableMessage sendAndReceive(String var1, String var2, Message var3) throws AmqpException;@NullableObject convertSendAndReceive(Object var1) throws AmqpException;@NullableObject convertSendAndReceive(String var1, Object var2) throws AmqpException;@NullableObject convertSendAndReceive(String var1, String var2, Object var3) throws AmqpException;@NullableObject convertSendAndReceive(Object var1, MessagePostProcessor var2) throws AmqpException;@NullableObject convertSendAndReceive(String var1, Object var2, MessagePostProcessor var3) throws AmqpException;@NullableObject convertSendAndReceive(String var1, String var2, Object var3, MessagePostProcessor var4) throws AmqpException;@Nullable<T> T convertSendAndReceiveAsType(Object var1, ParameterizedTypeReference<T> var2) throws AmqpException;@Nullable<T> T convertSendAndReceiveAsType(String var1, Object var2, ParameterizedTypeReference<T> var3) throws AmqpException;@Nullable<T> T convertSendAndReceiveAsType(String var1, String var2, Object var3, ParameterizedTypeReference<T> var4) throws AmqpException;@Nullable<T> T convertSendAndReceiveAsType(Object var1, MessagePostProcessor var2, ParameterizedTypeReference<T> var3) throws AmqpException;@Nullable<T> T convertSendAndReceiveAsType(String var1, Object var2, MessagePostProcessor var3, ParameterizedTypeReference<T> var4) throws AmqpException;@Nullable<T> T convertSendAndReceiveAsType(String var1, String var2, Object var3, MessagePostProcessor var4, ParameterizedTypeReference<T> var5) throws AmqpException;
}

从源码中我们可以了解到,其实该接口提供了八种类型的消息操作方法,因为不同方法都采用了重载所以看起来有点吓人,接下来我们大致根据方法名弄清楚这些方法的功能即可。

send()和receive()就不说了,根据给出的参数来发送消息和接收消息

  • convertAndSend:转化并发送消息;
  • receiveAndConvert:接收并转化消息
  • receiveAndReply:接收并回复消息
  • sendAndReceive:发送并接收消息
  • convertSendAndReceive:转化发送和接收
  • convertSendAndReceiveAsType:根据类型来发送接收

其实AMQPTemplate是一个比较抽象的接口,其中操作RabbitMQ更为具体的接口的实现类是RabbitMQTemplate。而关于RabbitMQTemplate的源码这里就不展示了(一千多行呢~)

 //给延迟队列发送消息
amqpTemplate.convertAndSend(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getExchange(), QueueEnum.QUEUE_TTL_ORDER_CANCEL.getRouteKey(), orderId, new MessagePostProcessor() {@Overridepublic Message postProcessMessage(Message message) throws AmqpException {//给消息设置延迟毫秒值message.getMessageProperties().setExpiration(String.valueOf(delayTimes));return message;}
});

可以看到我们调用了RabbitMQTemplate实现的AMQPTemplate接口方法来发送消息。

1.3.2 Message

Message消息,是服务器与应用程序之间传递的数据,由Properties和Body组成, Properties可以对消息进行修饰,如消息的优先级、传输格式(如JSON)、延迟等高级特性,Body则就是消息体内容。

Message类的使用场景:

  • 发送消息时:通常使用最多的是编写消息体内容、设置过期时间、设置持久化;发送消息的类型分为两种情况:基本类型和对象; 
  • 接收消息时:实际是把二进制byte转为需要的类型,再进行数据传递和业务处理,接收消息的类型分为两种情况:基本类型和对象

在脚手架中我们看到使用了Message来反取消息对象的属性并设置相应的消息过期时间:

message.getMessageProperties().setExpiration(String.valueOf(delayTimes));

其余的核心组件具体内容可以参考这位大佬的博文: https://blog.csdn.net/weixin_45596022/article/details/113359009

1.3.3 @RabbitListener注解

        @RabbitListener注解是Spring AMQP框架提供的注解,用于简化RabbitMQ消息消费者的创建。当你在方法上使用@RabbitListener注解时,Spring会自动创建一个RabbitMQ消息监听器,用于监听指定队列上的消息,并在消息到达时调用被注解的方法来处理消息。

因此在脚手架中我们通过该注解来实现死信队列消费者的创建:

@Component
@RabbitListener(queues = "mall.order.cancel")
public class CancelOrderReceiver {private static Logger LOGGER =LoggerFactory.getLogger(CancelOrderReceiver.class);@Autowiredprivate OmsPortalOrderService portalOrderService;@RabbitHandlerpublic void handle(Long orderId){LOGGER.info("receive delay message orderId:{}",orderId);portalOrderService.cancelOrder(orderId);}
}

1.4 订单超时未支付取消订单的流程

        在mall脚手架中模拟了一个订单到期未支付取消下单的操作,首先用户在购买之后会创建订单(随之可能会有锁定库存、判断会员身份或者积分、优惠券等操作),Controller层中的generateOrder()就会创建一个带有过期时间的延时消息,这部分是通过一个之前已经定义好了的CancelOrderSender也就是延时消息的发送者类发送延时消息到死信队列中。这里我们来看一下配置死信队列的配置类方法:

    /*** 订单延迟队列(死信队列)*/@Beanpublic Queue orderTtlQueue() {return QueueBuilder.durable(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getName()).withArgument("x-dead-letter-exchange", QueueEnum.QUEUE_ORDER_CANCEL.getExchange())//到期后转发的交换机.withArgument("x-dead-letter-routing-key", QueueEnum.QUEUE_ORDER_CANCEL.getRouteKey())//到期后转发的路由键.build();}

        由于我们定义了一个死信队列和一个延时队列,订单下单之后我们就会把消息发送到死信队列,由于用户迟迟不支付,所以死信队列中的消息一直没有被消费,等到TTL时间一到就会转发到普通队列中被消费者消费。前面在讲@RabbitListener注解的时候已经给出了消费者的demo,消费者监听的就是普通队列。当消费者消费后会触发取消订单的API进行订单取消的操作(释放库存、扣除优惠券或积分等操作)


总结

        RabbitMQ整合进脚手架的功能还是比较简单的哈哈,当然了脚手架只是为了让我们了解一些基础知识以便于快速上手项目,重点的还是要学习有关AMQP的操作以及相应的在RabbitMQ对应的接口实现类。梳理完后接下来的文章荔枝就可以开始整合MinIO了,一起加油吧~

今朝已然成为过去,明日依然向往未来!我是荔枝,在技术成长之路上与您相伴~~~

如果博文对您有帮助的话,可以给荔枝一键三连嘿,您的支持和鼓励是荔枝最大的动力!

如果博文内容有误,也欢迎各位大佬在下方评论区批评指正!!!

相关文章:

Mall脚手架总结(四) —— SpringBoot整合RabbitMQ实现超时订单处理

前言 在电商项目中&#xff0c;订单因为某种特殊情况被取消或者超时未支付都是比较常规的用户行为&#xff0c;而实现该功能我们就要借助消息中间件来为我们维护这么一个消息队列。在mall脚手架中选择了RabbitMQ消息中间件&#xff0c;接下来荔枝就会根据功能需求来梳理一下超时…...

python实现图像的直方图均衡化

直方图均衡化是一种用于增强图像对比度的图像处理技术。它通过重新分配图像中的像素值&#xff0c;使得图像的像素值分布更加均匀&#xff0c;增强图像的对比度&#xff0c;从而改善图像的视觉效果。 直方图均衡化的过程如下&#xff1a; 灰度转换&#xff1a;如果图像是彩色…...

哪种烧录单片机的方法合适?

哪种烧录单片机的方法合适&#xff1f; 首先&#xff0c;让我们来探讨一下单片机烧录的方式。虽然单片机烧录程序的具体方法会因为单片机型号、然后很多小伙伴私我想要嵌入式资料&#xff0c;通宵总结整理后&#xff0c;我十年的经验和入门到高级的学习资料&#xff0c;只需一…...

安规电容总结

安规电容 顾名思义&#xff1a;电容即使失效后&#xff0c;也不会漏电或者放电伤人&#xff0c;要符合安全规定 多数高压认证产品都需要。 上图&#xff1a; X电容&#xff1a; Y电容&#xff1a; 区别&#xff1a; 电路示意&#xff1a;...

MyCat分片垂直拆分

场景 在业务系统中 , 涉及以下表结构 , 但是由于用户与订单每天都会产生大量的数据 , 单台服务器的数据 存储及处理能力是有限的 , 可以对数据库表进行拆分 , 原有的数据库表如下。 现在考虑将其进行垂直分库操作&#xff0c;将商品相关的表拆分到一个数据库服务器&#…...

MongoDB bin目录没有mongo.exe命令

MongoDB从6.0版本开始就取消了在Bin目录中加入Compass连接工具&#xff0c;需要大家自行安装。 可以定位到我的文章 链接地址 点击右侧目录的 标题三&#xff1a;MongoDB Compass连接MongoDBMongoDB Compass的安装方法哦~...

Zookeeper分布式一致性协议ZAB源码剖析

文章目录 1、ZAB协议介绍2、消息广播 1、ZAB协议介绍 ZAB 协议全称&#xff1a;Zookeeper Atomic Broadcast&#xff08;Zookeeper 原子广播协议&#xff09;。 Zookeeper 是一个为分布式应用提供高效且可靠的分布式协调服务。在解决分布式一致性方面&#xff0c;Zookeeper 并…...

微软 AR 眼镜新专利:包含热拔插电池

近日&#xff0c;微软在增强现实&#xff08;AR&#xff09;领域进行深入的研究&#xff0c;并申请了一项有关于“热插拔电池”的专利。该专利于2023年10月5日发布&#xff0c;描述了一款采用模块化设计的AR眼镜&#xff0c;其热插拔电池放置在镜腿部分&#xff0c;可以直接替代…...

软件TFN 2K的分布式拒绝攻击(DDos)实战详解

写在前头 本人写这篇博客的目的&#xff0c;并不是我想成为黑客或者鼓励大家做损坏任何人安全和利益的事情。因科研需要&#xff0c;我学习软件TFN 2K的分布式拒绝攻击&#xff0c;只是分享自己的学习过程和经历&#xff0c;有助于大家更好的关注到网络安全及网络维护上。 需要…...

计算机网络第四章——网络层(末)

赌书消得泼茶香当时只道是寻常 文章目录 概述&#xff1a;组播机制是让源计算机一次发送的单个分组可以抵达用一个组地址标识的若干目标主机&#xff0c;并被它们正确接收&#xff0c;组播仅应用于UDP 因特网中的IP组播也使用组播组的概念&#xff0c;每个组都有一个特别分配的…...

Newman基本使用

目录 简介 安装 使用 官网 运行 输出测试报告文件 htmlextra 使用 简介 Newman 是 Postman 推出的一个 nodejs 库&#xff0c;直接来说就是 Postman 的json文件可以在命令行执行的插件。   Newman 可以方便地运行和测试集合&#xff0c;并用之构造接口自动化测试和持续集成…...

左值引用右值引用

文章目录 左值和右值什么是左值什么是右值左值引用与右值引用的比较左值引用总结右值引用的总结&#xff1a; 右值引用使用场景和意义左值引用的使用场景左值引用的短板 右值引用和移动语义解决上面的问题不仅仅有移动构造还有移动赋值 右值引用引用左值及其一些更深入的使用场…...

学习开发一个RISC-V上的操作系统(汪辰老师) — 一次RV32I加法指令的反汇编

前言 &#xff08;1&#xff09;此系列文章是跟着汪辰老师的RISC-V课程所记录的学习笔记。 &#xff08;2&#xff09;该课程相关代码gitee链接&#xff1b; &#xff08;3&#xff09;PLCT实验室实习生长期招聘&#xff1a;招聘信息链接 前置知识 RISC-V 汇编指令编码格式 &a…...

IDEA中点击New没有Java Class

解决办法&#xff1a;右键src&#xff0c;也可以是其他文件名&#xff0c;点击Mark Directory as 点击Sources Root即可...

打造炫酷效果:用Java优雅地制作Excel迷你图

摘要&#xff1a;本文由葡萄城技术团队原创并首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 前言 迷你图是一种简洁而有效的数据可视化方式&#xff0c;常用于展示趋势和变化。它通常由一…...

pycharm设置pyuic和pyrcc

pyuic设置 适合任何虚拟环境&#xff0c;直接用虚拟环境的python解决一切。。。 E:\anaconda3\envs\qt5\python.exe-m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py$FileDir$pyrcc设置 E:\anaconda3\envs\qt5\python.exe-m PyQt5.pyrcc_main $FileName$ -o…...

OpenCV6-图形绘制

OpenCV6-图形绘制 1.绘制圆形2.绘制直线3.绘制椭圆4.绘制多边形5.文字生成6.demo 1.绘制圆形 void cv::circle(InputOutputArray img, // 需要绘制圆形的图像Point center, // 圆心坐标int radius, // 半径&#xff0c;单位为像素const Scalar& colo…...

kafka消费者程序日志报错Offset commit failed问题研究

生产环境偶尔会遇到kafka消费者程序日志报错的问题 截取主要日志如下&#xff1a; 2023-10-02 19:35:28.554 {trace: d7f97f70dd693e3d} ERROR[Thread-49:137] ConsumerCoordinator$OffsetCommitResponseHandler.handle(812) - [Consumer clientIdconsumer-1, groupIdcid_yin…...

SpringBoot+原生HTML+MySQL开发的电子病历系统源码

电子病历系统源码 电子病历编辑器源码 云端SaaS服务 电子病历系统&#xff0c;采用 “所见即所得、一体化方式”&#xff0c;协助医生和护士准确、标准、快捷实现病历书写、修改、审阅、打印、体温单浏览、医嘱管理等&#xff0c;是提供病历快速简洁化完成的一系列综合型医生病…...

软件测试/测试开发/人工智能丨聊聊AutoGPT那些事儿

点此获取更多相关资料 简介 在 ChatGPT 问世之后&#xff0c;大家很容易就发现其依然具备一些很难解决的问题&#xff0c;比如&#xff1a; Token 超出限制怎么办&#xff1f;&#xff08;目前最新的 GPT4 支持最多8,192 tokens&#xff09;。如何完全自动化&#xff1f;任务…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...

Unity中的transform.up

2025年6月8日&#xff0c;周日下午 在Unity中&#xff0c;transform.up是Transform组件的一个属性&#xff0c;表示游戏对象在世界空间中的“上”方向&#xff08;Y轴正方向&#xff09;&#xff0c;且会随对象旋转动态变化。以下是关键点解析&#xff1a; 基本定义 transfor…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...