济南建站公司电话/东莞关键词排名推广
🎉🎉欢迎来到我的CSDN主页!🎉🎉
🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚
🌟推荐给大家我的专栏《RabbitMQ实战》。🎯🎯
👉点击这里,就可以查看我的主页啦!👇👇
Java方文山的个人主页
🎁如果感觉还不错的话请给我点赞吧!🎁🎁
💖期待你的加入,一起学习,一起进步!💖💖
✨前言
了解延迟队列之前我们先了解两个概念TTL和 DXL两个概念:
TTL概念
TTL 顾名思义:指的是消息的存活时间,RabbitMQ可以通过x-message-tt参数来设置指定Queue(队列)和 Message(消息)上消息的存活时间,它的值是一个非负整数,单位为微秒。
RabbitMQ 可以从两种维度设置消息过期时间,分别是队列和消息本身
设置队列过期时间,那么队列中所有消息都具有相同的过期时间。
设置消息过期时间,对队列中的某一条消息设置过期时间,每条消息TTL都可以不同。
如果同时设置队列和队列中消息的TTL,则TTL值以两者中较小的值为准。而队列中的消息存在队列中的时间,一旦超过TTL过期时间则成为Dead Letter(死信)。
DLX概念
消息变成死信一般是由于以下几种情况:🎈 消息被拒绝( Basic.Reject/Basic.Nack ),并且设置 requeue 参数为 false ;🎈 消息过期(TTL过期);🎈队列达到最大长度。
延迟队列的使用场景有很多,比如:
- 在订单系统中,一个用户下单之后通常有 30 分钟的时间进行支付,如果 30 分钟之内没有支付成功,那么这个订单将进行异常处理,这时就可以使用延迟队列来处理这些订单了。
- 用户希望通过手机远程遥控家里的智能设备在指定的时间进行工作。这时候就可以将用户指令发送到延迟队列,当指令设定的时间到了再将指令推送到智能设备。
🎉死信交换机的使用
1.案例分析
下面我会讲解两种使用死信的方式:
第一种是我们不为正常的交换机设置消费者,为该队列中的消息设置TTL如果消息过期了就会变为死信就会被发送到死信交换机中处理对应的事务
假设我们有一个订单系统,订单有一个待支付状态,如果在30分钟内未支付,则自动变为已取消状态。我们可以通过 RabbitMQ 的 TTL 机制和死信队列来实现这个功能。
具体步骤如下:
创建一个普通的交换机(例如
orderExchange
)和一个普通的队列(例如orderQueue
)。将队列绑定到交换机上。创建一个死信交换机(例如
deadLetterExchange
)和一个死信队列(例如deadLetterQueue
)。将死信队列绑定到死信交换机上。将普通队列设置为有 TTL 的队列,并指定 TTL 的时间为30分钟。这样,如果消息在队列中存活时间超过30分钟,就会变为死信。
设置普通队列的死信交换机和死信路由键。当消息变为死信时,会被发送到死信交换机,并根据死信路由键路由到对应的死信队列。
创建一个死信消费者,监听死信队列中的消息。当收到订单消息时,判断订单是否已经支付,如果未支付则将其修改为已取消状态。
这种方式可以灵活地处理订单超时自动取消的需求,并且不需要为每个订单单独创建消费者,降低了系统的复杂性。同时,通过使用 RabbitMQ 的 TTL 机制和死信队列,还可以实现其他类似的延迟任务处理场景。
第二种则是为正常队列创建一个消费者但是开启手动确认,什么意思呢,我们的RabbitMQ中的消费者都是自动消费的,所以我们可以设置为手动确认消费,我接收到你这个消息了,但我还未处理,而是由消费者主动发送确认信号(ACK)给 RabbitMQ,告知消息已经成功处理,这条消息才算是被消费了。
以下情况会使用这种方式:
并发处理:当多个消费者同时消费同一个队列中的消息时,为了保证消息不被重复消费或丢失,可以使用手动签收。消费者在处理完消息后,手动发送 ACK 确认消息处理完成,这样 RabbitMQ 就知道该消息已经被正确处理,可以将其标记为已消费。
消息处理失败:如果消费者在处理消息时发生了异常或错误,可以选择不发送 ACK,即不确认消息的消费完成。这样 RabbitMQ 就会重新将该消息发送给其他消费者进行处理,确保消息不会丢失。
消息处理耗时较长:某些消息的处理可能需要较长的时间,为了防止 RabbitMQ 认为该消息处理超时而重新发送给其他消费者,可以使用手动签收。消费者在开始处理消息时,发送 ACK 告知 RabbitMQ 接收到消息并开始处理,然后在处理完成后再发送 ACK 确认消息处理完成。
2.案例1实践
创建交换机、队列以及它们的绑定关系
package org.example.produce.config;import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.HashMap;
import java.util.Map;@Configuration
@SuppressWarnings("all")
public class RabbitConfig {/*** 定义正常队列* @return*/@Beanpublic Queue QueueA(){Map<String, Object> config = new HashMap<>();config.put("x-message-ttl", 10000);//message在该队列queue的存活时间最大为10秒config.put("x-dead-letter-exchange", "deadExchange"); //x-dead-letter-exchange参数是设置该队列的死信交换器(DLX)config.put("x-dead-letter-routing-key", "bb");//x-dead-letter-routing-key参数是给这个DLX指定路由键return new Queue("QueueA", true, true, false, config);}/*** 定义死信队列* @return*/@Beanpublic Queue QueueB(){return new Queue("QueueB");}/*** 自定义直连交换机* @return*/@Beanpublic DirectExchange directExchangeA(){return new DirectExchange("direct-exchangeA",true,false);}/*** 自定义死信交换机* @return*/@Beanpublic DirectExchange directExchangeB(){return new DirectExchange("direct-exchangeB",true,false);}/*** 将正常队列与直连交换机进行绑定,并设置路由键与死信交换机以及队列* @return*/@Beanpublic Binding bindingExchangeA(){return BindingBuilder.bind(QueueA()).to(directExchangeA()).with("aa");}/*** 将死信队列与死信交换机进行绑定,并设置路由键* @return*/@Beanpublic Binding bindingExchangeB(){return BindingBuilder.bind(QueueB()).to(directExchangeB()).with("bb");}}
x-message-ttl
参数是设置消息在队列中的存活时间,单位为毫秒。在这个例子中,设置了 10000 毫秒,即 10 秒钟。如果一个消息在该队列中未被消费者接收并确认处理,那么该消息就会被自动移除出队列,避免消息的过期占用队列资源。
x-dead-letter-exchange
参数是设置该队列的死信交换器(DLX),表示当一个消息变成死信时,会被发送到指定的 DLX 中。在这个例子中,设置的死信交换器为 "direct-exchangeB",即将死信消息发送到名为 "direct-exchangeB" 的交换器。
x-dead-letter-routing-key
参数是给该 DLX 指定一个路由键。当消息变成死信时,会根据该路由键将它发送到绑定该路由键的队列中。在这个例子中,设置的路由键为 "bb",即将死信消息发送到名为 "QueueB" 的队列中。
创建消息的生产者
package org.example.produce.controller;import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
import java.util.Map;@RestController
public class Sender {@Autowiredprivate AmqpTemplate rabbitTemplate;@RequestMapping("/send")public String send() {Map<String,Object> data=new HashMap<>();data.put("msg","订单ID:121452623345");rabbitTemplate.convertAndSend("direct-exchangeA","aa", data);return "😎";}
}
创建死信队列的消费者
package org.example.produce.controller;import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;import java.util.Map;@Component
@RabbitListener(queues = {"QueueB"})
public class BReceiver {@RabbitHandlerpublic void handler(Map<String,Object> json){System.out.println(json);}
}
效果展示:
访问一下http://localhost:8081/send
访问一下http://118.178.124.148:15672
可以看到已经有我们的队列了,现在我们开启消费者服务查看一下
也是可以拿到原先队列中的消息的,说明我们的死信交换机和死信队列生效了
RabbitMQ死信队列优化
如果我们想要第一条消息在6s后变成了死信消息,然后被消费者消费掉,第二条消息在60s之后变成了死信消息,然后被消费掉,这样,岂不是每增加一个新的时间需求,就要新增一个队列,这里只有6s和60s两个时间选项,如果需要一个小时后处理,那么就需要增加TTL为一个小时的队列,如果是预定会议室然后提前通知这样的场景,岂不是要增加无数个队列才能满足需求??
其实我们可以增加一个延时队列,用于接收设置为任意延时时长的消息,增加一个相应的死信队列和routingkey
创建交换机、队列以及它们的绑定关系
package org.example.produce.config;import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.HashMap;
import java.util.Map;@Configuration
@SuppressWarnings("all")
public class RabbitConfig {/*** 定义正常队列* @return*/@Beanpublic Queue QueueA(){Map<String, Object> config = new HashMap<>();config.put("x-message-ttl", 10000);//message在该队列queue的存活时间最大为10秒config.put("x-dead-letter-exchange", "direct-exchangeB"); //x-dead-letter-exchange参数是设置该队列的死信交换器(DLX)config.put("x-dead-letter-routing-key", "bb");//x-dead-letter-routing-key参数是给这个DLX指定路由键return new Queue("QueueA", true, true, false, config);}/*** 定义死信队列* @return*/@Beanpublic Queue QueueB(){return new Queue("QueueB");}// 声明延时队列C 不设置TTL@Beanpublic Queue QueueC(){Map<String, Object> config = new HashMap<>();// x-dead-letter-exchange 这里声明当前队列绑定的正常交换机config.put("x-dead-letter-exchange","direct-exchangeA");// x-dead-letter-routing-key 这里声明当前队列的死信路由keyconfig.put("x-dead-letter-routing-key", "aa");return new Queue("QueueC", true, true, false, config);}/*** 自定义直连交换机* @return*/@Beanpublic DirectExchange directExchangeA(){return new DirectExchange("direct-exchangeA",true,false);}/*** 自定义死信交换机* @return*/@Beanpublic DirectExchange directExchangeB(){return new DirectExchange("direct-exchangeB",true,false);}/*** 自定义延迟交换机* @return*/@Beanpublic DirectExchange directExchangeC(){return new DirectExchange("direct-exchangeC",true,false);}/*** 将正常队列与直连交换机进行绑定,并设置路由键与死信交换机以及队列* @return*/@Beanpublic Binding bindingExchangeA(){return BindingBuilder.bind(QueueA()).to(directExchangeA()).with("aa");}/*** 将死信队列与死信交换机进行绑定,并设置路由键* @return*/@Beanpublic Binding bindingExchangeB(){return BindingBuilder.bind(QueueB()).to(directExchangeB()).with("bb");}/*** 将正常队列与直连交换机进行绑定,并设置路由键与死信交换机以及队列* @return*/@Beanpublic Binding bindingExchangeC(){return BindingBuilder.bind(QueueC()).to(directExchangeC()).with("cc");}/}
创建消息的生产者
package org.example.produce.controller;import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.Date;
import java.util.HashMap;
import java.util.Map;@RestController
@Slf4j
public class Sender {@Autowiredprivate AmqpTemplate rabbitTemplate;@RequestMapping("send02")public void sendMsg( Integer delay) {Map<String,Object> data=new HashMap<>();data.put("msg","延迟队列");rabbitTemplate.convertAndSend("direct-exchangeC", "cc",data , message -> {// 设置延迟毫秒值message.getMessageProperties().setExpiration(String.valueOf(delay * 1000));return message;});}
}
3.案例2实践
-
消息通过 ACK 确认是否被正确接收,每个 Message 都要被确认(acknowledged),可以手动去 ACK 或自动 ACK
-
自动确认会在消息发送给消费者后立即确认,但存在丢失消息的可能,如果消费端消费逻辑抛出异常,也就是消费端没有处理成功这条消息,那么就相当于丢失了消息
-
如果消息已经被处理,但后续代码抛出异常,使用 Spring 进行管理的话消费端业务逻辑会进行回滚,这也同样造成了实际意义的消息丢失
-
如果手动确认则当消费者调用 ack、nack、reject 几种方法进行确认,手动确认可以在业务失败后进行一些操作,如果消息未被 ACK 则会发送到下一个消费者
-
如果某个服务忘记 ACK 了,则 RabbitMQ 不会再发送数据给它,因为 RabbitMQ 认为该服务的处理能力有限
-
ACK 机制还可以起到限流作用,比如在接收到某条消息时休眠几秒钟
-
消息确认模式有:
-
AcknowledgeMode.NONE:自动确认
-
AcknowledgeMode.AUTO:根据情况确认
-
AcknowledgeMode.MANUAL:手动确认
-
配置yml文件关闭自动确认
server:port: 9999
spring:application:name: consumerabbitmq:host: localhostusername: weiweipassword: 123456port: 5672virtual-host: my_vhostlistener:simple:acknowledge-mode: manual
为QueueA创建一个消费者并且手动确认
在刚刚上一个案例中我们不是没有为正常队列创建消费者吗,现在我们创建一个
package org.example.produce.controller;import com.rabbitmq.client.Channel;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;import java.io.IOException;
import java.util.Map;@Component
@RabbitListener(queues = {"QueueA"})
public class AReceiver {@RabbitHandlerpublic void handler(Map<String,Object> json, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws Exception {System.out.println("QA接到消息"+json); // 打印接收到的消息channel.basicAck(tag,true); // 确认消息已被消费}
}
需要注意的 basicAck 方法需要传递两个参数
deliveryTag(唯一标识 ID):当一个消费者向 RabbitMQ 注册后,会建立起一个 Channel ,RabbitMQ 会用 basic.deliver 方法向消费者推送消息,这个方法携带了一个 delivery tag, 它代表了 RabbitMQ 向该 Channel 投递的这条消息的唯一标识 ID,是一个单调递增的正整数,delivery tag 的范围仅限于 Channel
multiple:为了减少网络流量,手动确认可以被批处理,当该参数为 true 时,则可以一次性确认 delivery_tag 小于等于传入值的所有消息
现在我们看一下我们的消息是否会是怎么样的
2024-01-25 19:55:27.744 INFO 13668 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2024-01-25 19:55:27.744 INFO 13668 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2024-01-25 19:55:27.745 INFO 13668 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
QA接到消息{msg=订单ID:121452623345}
QA接到消息{msg=订单ID:121452623345}
直接被QA接收消费,那么如果我拒绝呢?
消费者拒绝消息
package org.example.produce.controller;import com.rabbitmq.client.Channel;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;import java.util.Map;@Component
@RabbitListener(queues = {"QueueA"})
public class AReceiver {@RabbitHandlerpublic void handler(Map<String,Object> json, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws Exception {System.out.println("拒绝"+json);channel.basicReject(tag,false); // 拒绝消息Thread.sleep(1000);}
}
basicReject(tag,false)是用于拒绝消息并可选择是否将消息重新放回队列的方法。
具体来说,
basicReject()
方法用于告知 RabbitMQ 服务器拒绝处理特定的消息,并可以选择将消息重新放回队列中等待重新投递。这样可以用于处理无法处理的消息或者避免消息丢失。
- 参数
tag
表示消息的标签(delivery tag),它是一个唯一的标识符,用于表示消息在通道中的位置。每个消息都会被分配一个单独的标签。通过将正确的标签传递给basicReject()
方法,可以告诉 RabbitMQ 服务器要拒绝哪个具体的消息。- 第二个参数
false
表示不将消息重新放回队列,即将消息丢弃。如果将其设置为true
,则表示将消息重新放回队列中等待重新投递。
被拒绝就会变成死信消息转到我们的死信交换机然后发送给死信队列
但是我们的死信也没有进行消费 ,只是消息保存在了队列中,那是因为我们开启了全局的手动消息确认,也就是上面所编写的配置,我们只需要像刚刚那样手动确认即可
package org.example.produce.controller;import com.rabbitmq.client.Channel;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;import java.util.Map;@Component
@RabbitListener(queues = {"QueueB"})
public class BReceiver {@RabbitHandlerpublic void handler(Map<String,Object> json, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws Exception {System.out.println("QB接到消息"+json); // 打印接收到的消息channel.basicAck(tag,true); // 确认消息已被消费}
}
可以看到在消息被拒后消息就会跑到死信队列中做处理
2024-01-25 20:00:53.759 INFO 13444 --- [ restartedMain] org.example.produce.ProduceApplication : Started ProduceApplication in 3.916 seconds (JVM running for 4.403)
2024-01-25 20:01:16.094 INFO 13444 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2024-01-25 20:01:16.095 INFO 13444 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2024-01-25 20:01:16.095 INFO 13444 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 0 ms
拒绝{msg=订单ID:121452623345}
QB接到消息{msg=订单ID:121452623345}
到这里我的分享就结束了,欢迎到评论区探讨交流!!
💖如果觉得有用的话还请点个赞吧 💖
相关文章:

【RabbitMQ】延迟队列之死信交换机
🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的专栏《RabbitMQ实战》。🎯🎯 &am…...

2024交通运输工程与土木建筑工程国际会议(ICTECCE2024)
2024交通运输工程与土木建筑工程国际会议(ICTECCE2024) 会议简介 2024年国际交通工程和土木建筑工程会议(ICTECCE 2024)将在中国杭州举行。ICTECCE 2024致力于为交通工程和土木工程材料领域的学者、工程师和研究人员提供一个大型学术交流平台和双向交流…...

搜索引擎Elasticsearch了解
1.Lucene 是什么? 2.模块介绍 Lucene是什么: 一种高性能,可伸缩的信息搜索(IR)库 在2000年开源,最初由鼎鼎大名的Doug Cutting开发 是基于Java实现的高性能的开源项目 Lucene采用了基于倒排表的设计原理,可以非常高效地实现文本查找,在底层采用了分段的存储模式,使它在读…...

【操作系统基础】【CPU访存原理】:寄存 缓存 内存 外存、内存空间分区、虚拟地址转换、虚拟地址的映射
存储器怎么存储数据、内存空间分区、虚拟地址转换 计算机的存储器:寄存 缓存 内存 外存(按功能划分) 计算机的处理器需要一个存储器来存储大量的指令和数据以便自己不断取指执行和访问数据。 内存(内存就是运行内存,…...

windows下git pull超时,ping不通github
报错 ssh: connect to host github.com port 22: Connection timed out fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists. 解决办法 修改hosts 最后加一行,文件位置:…...

springboot快速写接口
1. 建proj形式 name会变成文件夹的名字,相当于你的项目名称 基础包 2. 基础依赖 3. 配置数据库 这里要打开mysql,并且创建数据库 方法: 安装好数据库,改好账号密码用navicat来建表和账号配置properties.yml文件即可 4.用res…...

数据结构排序算详解(动态图+代码描述)
目录 1、直接插入排序(升序) 2、希尔排序(升序) 3、选择排序(升序) 方式一(一个指针) 方式二(两个指针) 4、堆排序(升序) 5、冒…...

2024-01-25 力扣高频SQL50题目1174. 即时食物配送
题目如下: 配送表: Delivery -------------------------------------- | Column Name | Type | -------------------------------------- | delivery_id | int | | customer_id | int | | order_date…...

java web 校园健康管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
一、源码特点 java Web校园健康管理系统是一套完善的java web信息管理系统 ,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysq…...

回归预测 | Matlab基于SSA-SVR麻雀算法优化支持向量机的数据多输入单输出回归预测
回归预测 | Matlab基于SSA-SVR麻雀算法优化支持向量机的数据多输入单输出回归预测 目录 回归预测 | Matlab基于SSA-SVR麻雀算法优化支持向量机的数据多输入单输出回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab基于SSA-SVR麻雀算法优化支持向量机的数据…...

Java转成m3u8,hls格式
Java转成m3u8,hls格式 需求分析 大致思路 循环文件夹下面所有文件判断当前文件是否是视频文件,如果是视频文件先转为ts文件 因为听别人说先转成ts之后再切片会快很多 转成ts文件,并为这些文件单独生成一个目录,如果目录不存在则新建一个目…...

jmeter之接口测试实现参数化(利用函数助手),参数值为1-9(自增的数字)
1.前言 思考:为什么不用postman,用postman的话就得导入csv文件/json文件 如果不想导入文件,postman是实现不了,因为postman每次只会运行一次 2.jmeter函数助手实现参数化 (1)新建“线程组”--新建“http…...

如何在 Ubuntu 22.04 上安装 Apache Web 服务器
前些天发现了一个人工智能学习网站,通俗易懂,风趣幽默,最重要的屌图甚多,忍不住分享一下给大家。点击跳转到网站。 如何在 Ubuntu 22.04 上安装 Apache Web 服务器 介绍 Apache HTTP 服务器是世界上使用最广泛的 Web 服务器。它…...

【python爬虫】爬虫编程技术的解密与实战
🌈个人主页:Sarapines Programmer🔥 系列专栏: 爬虫】网络爬虫探秘⏰诗赋清音:云生高巅梦远游, 星光点缀碧海愁。 山川深邃情难晤, 剑气凌云志自修。 目录 🌼实验目的 …...

VisualSVN Server下载安装和使用方法、服务器搭建、使用TortoiseSvn将项目上传到云端服务器、各种错误解决方法
VisualSVN Server下载安装和使用方法、服务器搭建、使用TortoiseSvn将项目上传到云端服务器、各种错误解决方法 0.写在前面00.电脑配置01.思路 1.VisualSVN Server下载安装01.下载02.安装03.电脑命名不能有中文04.制作VisualSVN Server快捷方式05.License limits exceeded, Som…...

Python模块与包:扩展功能、提高效率的利器
文章目录 一、引言1.1 模块与包对于Python开发的重要性1.2 Python作为拥有丰富生态系统的编程语言 二、为什么学习模块与包2.1 复用代码:利用现有模块与包加速开发过程2.2 扩展功能:通过模块与包提供的功能增强应用的能力 三、模块的使用3.1 导入模块&am…...

【每日一题】4.LeetCode——杨辉三角
📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️ 🙏小杨水平有限,欢迎各位大佬指点&…...

蓝桥杯(Python)每日练Day5
题目 OJ1229 题目分析 题目完全符合栈的特征,后进先出。如果能够熟练使用列表的9种方法那么这道题很容易解出。 题解 a[]#存衣服 nint(input()) for i in range(n):llist(input().split())#判断每一步的操作if len(l[0])2:a.append(l[1])else:while a.pop()!l…...

SpringCloud(二)
Spring Cloud 文章目录 Spring Cloud任务三:Spring Cloud与微服务架构1.Spring Cloud课程内容介绍2.单体应用架构2.1 互联网应用架构演进2.2 单体应用架构 3.垂直应用架构4.SOA应用架构5.微服务应用架构介绍6.微服务架构核心思想及优缺点7.微服务架构的核心概念8.Sp…...

【java】常见的面试问题
目录 一、异常 1、 throw 和 throws 的区别? 2、 final、finally、finalize 有什么区别? 3、try-catch-finally 中哪个部分可以省略? 4、try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗&#…...

虚幻UE 插件-像素流送实现和优化
本笔记记录了像素流送插件的实现和优化过程。 UE version:5.3 文章目录 一、像素流送二、实现步骤1、开启像素流送插件2、设置参数3、打包程序4、打包后的程序进行像素流参数设置5、下载NodeJS6、下载信令服务器7、对信令服务器进行设置8、启动像素流送 三、优化1、…...

Vue2 props组件通信
一、父组件向子组件传值 1、流程图 2、父组件代码 <template><div class"app"><UserInfo:usernameusername:ageage:isSingleisSingle:carcar:hobbyhobby></UserInfo></div> </template><script> import UserInfo from .…...

重构改善既有代码的设计-学习(三):重新组织数据
1、拆分变量(Split Variable) 有些变量用于保存一段冗长代码的运算结果,以便稍后使用。这种变量应该只被赋值一次。 如果它们被赋值超过一次,就意味它们在函数中承担了一个以上的责任。如果变量承担多个责任,它就应该被…...

群狼调研(长沙品牌忠诚度测试)|广告效果测评方法
广告效果测评方法可以根据具体的目标和需求而有所差异,以下是一些常见的广告效果测评方法: 1.品牌调研和调查:通过定量或定性的调研和调查方法,评估广告对品牌认知、品牌形象和品牌偏好的影响,包括品牌知名度、品牌关联…...

Gradle学习笔记:Gradle的使用方法
文章目录 1.初始化项目2.构建脚本语言选择3.项目命名4.项目构建过程 1.初始化项目 创建一个test空文件夹,在该文件夹下打开终端,并执行命令:gradle init. 会有一个选项让你选择项目的类型。下面是每个选项的含义和用途: basic&am…...

少儿编程 2023年12月电子学会图形化编程等级考试Scratch二级真题解析(选择题)
2023年12月scratch编程等级考试二级真题 选择题(共25题,每题2分,共50分) 1、在制作推箱子游戏时,地图是用数字形式储存在电脑里的,下图是一个推箱子地图,地图表示如下:第一行( 111111)第二行( 132231) 第三行( 126621) 第四行( ) 第五行( 152321) 第六行( 111111 ) 根…...

基于Java+SpringMvc+vue+element实现上海汽车博物馆平台
基于JavaSpringMvcvueelement实现上海汽车博物馆平台 🍅 作者主页 央顺技术团队 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 文末获取源码联系方式 📝 🍅 查看下方微信号获取联系方式 承接各种定制系统 …...

Sybase PowerDesigner15安装配置
1,软件介绍 Power Designer 是Sybase公司的CASE工具集,使用它可以方便地对管理信息系统进行分析设计,他几乎包括了数据库模型设计的全过程。利用Power Designer可以制作数据流程图、概念数据模型、物理数据模型,还可以为数据仓…...

基于物联网设计的水稻田智能灌溉系统(STM32+华为云IOT)
一、项目介绍 随着科技的不断发展和人们生活水平的提高,农业生产也逐渐向智能化、高效化的方向发展。水稻作为我国主要的粮食作物之一,其生长过程中的灌溉管理尤为重要。传统的灌溉方式往往依赖于人工观察和控制,不仅效率低下,而…...

【数据结构】数据结构初识
前言: 数据结构是计算存储,组织数据的方式。数据结构是指相互间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。 Data Structure Vi…...