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

RabbitMQ的5种消息队列

RabbitMQ的5种消息队列

1、七种模式介绍与应用场景

1.1 简单模式(Hello World)

在这里插入图片描述

一个生产者对应一个消费者,RabbitMQ 相当于一个消息代理,负责将 A 的消息转发给 B。

应用场景:将发送的电子邮件放到消息队列,然后邮件服务在队列中获取邮件并发送给收件人。

1.2 工作队列模式(Work queues)

在这里插入图片描述

在多个消费者之间分配任务(竞争的消费者模式),一个生产者对应多个消费者,一般适用于执行资源密集型任务,

单个消费者处理不过来,需要多个消费者进行处理。

应用场景:一个订单的处理需要10s,有多个订单可以同时放到消息队列,然后让多个消费者同时处理,这样就是

并行了,而不是单个消费者的串行情况。

1.3 订阅模式(Publish/Subscribe)

在这里插入图片描述

一次向许多消费者发送消息,一个生产者发送的消息会被多个消费者获取,也就是将消息将广播到所有的消费者

中。

应用场景:更新商品库存后需要通知多个缓存和多个数据库,这里的结构应该是:

  • 一个 fanout 类型交换机扇出两个个消息队列,分别为缓存消息队列、数据库消息队列
  • 一个缓存消息队列对应着多个缓存消费者
  • 一个数据库消息队列对应着多个数据库消费者

1.4 路由模式(Routing)

在这里插入图片描述

有选择地 (Routing key) 接收消息,发送消息到交换机并且要指定路由 key,消费者将队列绑定到交换机时需要指

定路由 key,仅消费指定路由 key 的消息。

应用场景:如在商品库存中增加了 1 台 iphone12,iphone12 促销活动消费者指定 routing key 为 iphone12,只

有此促销活动会接收到消息,其它促销活动不关心也不会消费此 routing key 的消息。

1.5 主题模式(Topics)

在这里插入图片描述

根据主题 (Topics) 来接收消息,将路由 key 和某模式进行匹配,此时队列需要绑定在一个模式上,#匹配一个词

或多个词,*只匹配一个词。

应用场景:同上 iphone 促销活动可以接收主题为 iphone 的消息,如 iphone12、iphone13 等。

1.6 远程过程调用(RPC)

在这里插入图片描述

如果我们需要在远程计算机上运行功能并等待结果就可以使用 RPC,具体流程可以看图。

应用场景:需要等待接口返回数据,如订单支付。

1.7 发布者确认(Publisher Confirms)

与发布者进行可靠的发布确认,发布者确认是 RabbitMQ 扩展,可以实现可靠的发布。在通道上启用发布者确认

后,RabbitMQ 将异步确认发送者发布的消息,这意味着它们已在服务器端处理。

应用场景:对于消息可靠性要求较高,比如钱包扣款。

2、代码演示

<dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.6.0</version>
</dependency>

2.1 简单模式

package simple;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Sender {private final static String QUEUE_NAME = "simple_queue";public static void main(String[] args) throws IOException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();// 声明队列// queue: 队列名// durable: 是否持久化// exclusive: 是否排外,即只允许该channel访问该队列,一般等于true的话用于一个队列只能有一个消费者来消费的场景// autoDelete: 是否自动删除,消费完删除// arguments: 其他属性channel.queueDeclare(QUEUE_NAME, false, false, false, null);// 消息内容String message = "simplest mode message";channel.basicPublish("", QUEUE_NAME, null, message.getBytes());System.out.println("[x]Sent '" + message + "'");// 最后关闭通关和连接channel.close();connection.close();}
}
package simple;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Receiver {private final static String QUEUE_NAME = "simple_queue";public static void main(String[] args) throws IOException, TimeoutException {// 获取连接ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x] Received '" + delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");};channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {});}
}
[x]Sent 'simplest mode message'[x] Received 'simple_queue':'simplest mode message'

2.2 工作队列模式

package work;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Receiver1 {private final static String QUEUE_NAME = "queue_work";public static void main(String[] args) throws IOException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);// 同一时刻服务器只会发送一条消息给消费者channel.basicQos(1);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x-1] Received '" + delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");};channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {});}
}
package work;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Receiver2 {private final static String QUEUE_NAME = "queue_work";public static void main(String[] args) throws IOException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);// 同一时刻服务器只会发送一条消息给消费者channel.basicQos(1);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x-2] Received '" + delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");};channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {});}
}
package work;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Sender {private final static String QUEUE_NAME = "queue_work";public static void main(String[] args) throws IOException, InterruptedException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();// 声明队列channel.queueDeclare(QUEUE_NAME, false, false, false, null);for (int i = 0; i < 10; i++) {String message = "work mode message" + i;channel.basicPublish("", QUEUE_NAME, null, message.getBytes());System.out.println("[x] Sent '" + message + "'");Thread.sleep(i * 10);}channel.close();connection.close();}
}
[x] Sent 'work mode message0'
[x] Sent 'work mode message1'
[x] Sent 'work mode message2'
[x] Sent 'work mode message3'
[x] Sent 'work mode message4'
[x] Sent 'work mode message5'
[x] Sent 'work mode message6'
[x] Sent 'work mode message7'
[x] Sent 'work mode message8'
[x] Sent 'work mode message9'[x-1] Received 'queue_work':'work mode message0'
[x-1] Received 'queue_work':'work mode message2'
[x-1] Received 'queue_work':'work mode message4'
[x-1] Received 'queue_work':'work mode message6'
[x-1] Received 'queue_work':'work mode message8'[x-2] Received 'queue_work':'work mode message1'
[x-2] Received 'queue_work':'work mode message3'
[x-2] Received 'queue_work':'work mode message5'
[x-2] Received 'queue_work':'work mode message7'
[x-2] Received 'queue_work':'work mode message9'

2.3 发布订阅模式

package publishsubscribe;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;public class Receive1 {private static final String EXCHANGE_NAME = "logs";public static void main(String[] argv) throws Exception {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.exchangeDeclare(EXCHANGE_NAME, "fanout");String queueName = channel.queueDeclare().getQueue();channel.queueBind(queueName, EXCHANGE_NAME, "");System.out.println(" [*] Waiting for messages. To exit press CTRL+C");// 订阅消息的回调函数DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x-1] Received '" + message + "'");};// 消费者,有消息时出发订阅回调函数channel.basicConsume(queueName, true, deliverCallback, consumerTag -> {});}
}
package publishsubscribe;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;public class Receive2 {private static final String EXCHANGE_NAME = "logs";public static void main(String[] argv) throws Exception {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.exchangeDeclare(EXCHANGE_NAME, "fanout");String queueName = channel.queueDeclare().getQueue();channel.queueBind(queueName, EXCHANGE_NAME, "");System.out.println(" [*] Waiting for messages. To exit press CTRL+C");// 订阅消息的回调函数DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x-2] Received2 '" + message + "'");};// 消费者,有消息时出发订阅回调函数channel.basicConsume(queueName, true, deliverCallback, consumerTag -> {});}
}
package publishsubscribe;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;public class Sender {private static final String EXCHANGE_NAME = "logs";public static void main(String[] argv) throws Exception {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.exchangeDeclare(EXCHANGE_NAME, "fanout");String message = "publish subscribe message";channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes("UTF-8"));System.out.println(" [x] Sent '" + message + "'");channel.close();connection.close();}
}
[x] Sent 'publish subscribe message'[*] Waiting for messages. To exit press CTRL+C
[x-1] Received 'publish subscribe message'[*] Waiting for messages. To exit press CTRL+C
[x-2] Received2 'publish subscribe message'

2.4 路由模式

package router;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Receiver1 {private final static String QUEUE_NAME = "queue_routing";private final static String EXCHANGE_NAME = "exchange_direct";public static void main(String[] args) throws IOException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);// 指定路由的key,接收key和key2channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "key");channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "key2");channel.basicQos(1);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x-1] Received '" + delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");};channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {});}
}
package router;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Receiver2 {private final static String QUEUE_NAME = "queue_routing2";private final static String EXCHANGE_NAME = "exchange_direct";public static void main(String[] args) throws IOException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);// 仅接收key2channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "key2");channel.basicQos(1);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x-2] Received '" +delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");};channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {});}
}
package router;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Sender {private final static String EXCHANGE_NAME = "exchange_direct";private final static String EXCHANGE_TYPE = "direct";public static void main(String[] args) throws IOException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();// 交换机声明channel.exchangeDeclare(EXCHANGE_NAME, EXCHANGE_TYPE);// 只有routingKey相同的才会消费String message = "routing mode message";channel.basicPublish(EXCHANGE_NAME, "key2", null, message.getBytes());System.out.println("[x] Sent '" + message + "'");// channel.basicPublish(EXCHANGE_NAME, "key", null, message.getBytes());// System.out.println("[x] Sent '" + message + "'");channel.close();connection.close();}
}
[x] Sent 'routing mode message'[x-1] Received 'key2':'routing mode message'[x-2] Received 'key2':'routing mode message'

2.5 主题模式

package topic;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Receiver1 {private final static String QUEUE_NAME = "queue_topic";private final static String EXCHANGE_NAME = "exchange_topic";public static void main(String[] args) throws IOException, InterruptedException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);// 可以接收key.1channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "key.*");channel.basicQos(1);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x-1] Received '" + delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");};channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {});}
}
package topic;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Receiver2 {private final static String QUEUE_NAME = "queue_topic2";private final static String EXCHANGE_NAME = "exchange_topic";private final static String EXCHANGE_TYPE = "topic";public static void main(String[] args) throws IOException, InterruptedException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);// *号代表单个单词,可以接收key.1channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "*.*");// #号代表多个单词,可以接收key.1.2channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "*.#");channel.basicQos(1);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x-2] Received '" + delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");};channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {});}
}
package topic;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Sender {private final static String EXCHANGE_NAME = "exchange_topic";private final static String EXCHANGE_TYPE = "topic";public static void main(String[] args) throws IOException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.exchangeDeclare(EXCHANGE_NAME, EXCHANGE_TYPE);String message = "topics model message with key.1";channel.basicPublish(EXCHANGE_NAME, "key.1", null, message.getBytes());System.out.println("[x] Sent '" + message + "'");String message2 = "topics model message with key.1.2";channel.basicPublish(EXCHANGE_NAME, "key.1.2", null, message2.getBytes());System.out.println("[x] Sent '" + message2 + "'");channel.close();connection.close();}
}
[x] Sent 'topics model message with key.1'
[x] Sent 'topics model message with key.1.2'[x-1] Received 'key.1':'topics model message with key.1'[x-2] Received 'key.1':'topics model message with key.1'
[x-2] Received 'key.1.2':'topics model message with key.1.2'

3、四种交换机介绍

  • 直连交换机( Direct exchange ):具有路由功能的交换机,绑定到此交换机的时候需要指定一个

    routing_key,交换机发送消息的时候需要 routing_key,会将消息发送道对应的队列。

  • 扇形交换机( Fanout exchange ):广播消息到所有队列,没有任何处理,速度最快。

  • 主题交换机( Topic exchange ):在直连交换机基础上增加模式匹配,也就是对 routing_key 进行模式匹配,

    * 代表一个单词,# 代表多个单词。

  • 首部交换机( Headers exchange ):忽略 routing_key,使用 Headers 信息(一个 Hash 的数据结构)进行匹

    配,优势在于可以有更多更灵活的匹配规则。

相关文章:

RabbitMQ的5种消息队列

RabbitMQ的5种消息队列 1、七种模式介绍与应用场景 1.1 简单模式(Hello World) 一个生产者对应一个消费者&#xff0c;RabbitMQ 相当于一个消息代理&#xff0c;负责将 A 的消息转发给 B。 应用场景&#xff1a;将发送的电子邮件放到消息队列&#xff0c;然后邮件服务在队列…...

【C语言】选择排序

基本原理 先找到数组中最大的那个数&#xff0c;将最大的数放到数组最右端&#xff08;交换a[maxid]和a[len-1]这两个数的位置&#xff09;&#xff0c;然后继续从a[0]到a[len-2]中找到最大的数&#xff0c;然后交换a[maxid]和a[len-2]位置&#xff0c;依次查找交换&#xff0c…...

异步更新队列 - Vue2 响应式

前言 这篇文章分析了 Vue 更新过程中使用的异步更新队列的相关代码。通过对异步更新队列的研究和学习&#xff0c;加深对 Vue 更新机制的理解 什么是异步更新队列 先看看下面的例子&#xff1a; <div id"app"><div id"div" v-if"isShow&…...

【Unity的URP渲染管线下实现扩展后处理Volume组件_TemporalAntiAliasing(TAA)_抗锯齿(附带下载链接)】

【Unity的URP渲染管线下的TAA抗锯齿】 背景:1. Unity内置的抗锯齿只能够满足部分画面需求。展示一个锯齿示例。2. 在75寸大屏电视上跑通展示一个锯齿示例。- 在Camera上配置3. 安装了一个TAA组建,最后打包APK在安卓机上运行报错。- 经过测试排查,发现是没有将后处理的shader…...

NineData通过AWS FTR认证,打造安全可靠的数据管理平台

近日&#xff0c;NineData 作为新一代的云原生智能数据管理平台&#xff0c;成功通过了 AWS&#xff08;Amazon Web Service&#xff09;的 FTR 认证。NineData 在 FTR 认证过程中表现出色&#xff0c;成功通过了各项严格的测试和评估&#xff0c;在数据安全管理、技术应用、流…...

Qt应用开发(基础篇)——滚屏区域类 QScrollArea

一、前言 QScrollArea类继承于QAbstractScrollArea&#xff0c;QAbstractScrollArea继承于QFrame&#xff0c;是Qt滚动视图的常用部件。 滚屏区域基类 QAbstractScrollArea 框架类 QFrame QScrollArea类提供了对另一个小部件的滚动视图&#xff0c;基础功能、滚动条控制、界面策…...

安装最新版chromedriver 116,亲测可用

Version Selection...

html题库

什么是HTML? HTML的全称为 超文本标记语言 &#xff0c;是一种 标记语言 。 它包括一系列标签 &#xff0c;通过这些标签可以将网络上的文档格式统一&#xff0c;使分散的 Internet 资源连接为一个逻辑整体。 DOCTYPE 的作用是什么&#xff1f;标准模式与兼容模式&#xff08;…...

Android11 中 LED 使用-RK3568

文章目录 前言原理图设备树驱动前言 现在我们来学习点亮LED 原理图 然后对应在核心板原理图上查找 Working_LEDEN_H_GPIO0_B7,如下图所示: 那么我们只要控制 GPIO0_B7 即可控制 led 的亮灭。 设备树 leds: leds {compatible = "gpio-leds";work_led: work {gpi…...

BC77 有序序列插入一个数

描述 有一个有序数字序列&#xff0c;从小到大排序&#xff0c;将一个新输入的数插入到序列中&#xff0c;保证插入新数后&#xff0c;序列仍然是升序。 输入描述 第一行输入一个整数(0≤N≤50)。 第二行输入N个升序排列的整数&#xff0c;输入用空格分隔的N个整数。 第三…...

通过脚本使用Cppcheck做静态测试并生成报告(Windows)

1.安装cppcheck 先从cppcheck官方网站下载cppcheck的安装包。 注&#xff1a; &#xff08;1&#xff09;官网地址&#xff1a;https://sourceforge.net/projects/cppcheck &#xff08;2&#xff09;截止2023年8月&#xff0c;官方发布的最新版本是cppcheck-2.11-x64-Setup.…...

工业安全生产信息化平台的基本架构和关键功能分享

工业安全生产信息化平台是指利用信息技术手段&#xff0c;将工业安全生产管理与数据采集、传输、处理相结合&#xff0c;实现对工业安全生产全过程的数字化、信息化、智能化管理的平台。它通过集成多种信息系统和设备&#xff0c;实现对重大危险源监控预警、安全风险分级管控、…...

每日一道面试题之session 和 cookie 有什么区别?

Session和Cookie是两种在Web开发中用于跟踪用户状态的机制&#xff1a; 它们之间的区别如下&#xff1a; 存储位置&#xff1a;Cookie是存储在用户浏览器中的小型文本文件&#xff0c;而Session是存储在服务器上的数据结构。 数据安全性&#xff1a;Cookie中的数据可以被用户…...

SHELL 基础 显示字符颜色, 修改历史命令,Linux里的命令 执行顺序

echo 打印命令 &#xff1a; 显示字符串 &#xff1a; [rootserver ~]# echo this is SHELL language this is SHELL language [rootserver ~]# echo this is SHELL language this is SHELL language [rootserver ~]# echo "this is SHELL language" this is SH…...

Vue 和 JQuery 的区别在哪?为什么 JQuery 会被 Vue 取代?

在 Web 前端开发领域&#xff0c;我们经常会遇到一些不同的工具和框架&#xff0c;其中 Vue 和 JQuery, JQuery 是曾经备受欢迎的选择&#xff0c;而现在 Vue 是大多数人的选择。本文将探讨 Vue 和 JQuery 之间的区别&#xff0c;并讨论为什么越来越多的开发人员放弃 JQuery 而…...

Spring 中 Bean 注入与获取

Spring 中有哪些方式可以把 Bean 注入到 IOC 容器&#xff1f; 关于这个问题&#xff0c;我的回答入下&#xff1a;把 Bean 注入到 IOC 容器里面的方式有 7 种方式 1. 使用 xml 的方式来声明 Bean 的定义&#xff0c;Spring 容器在启动的时候会加载并解析这 个 xml&#xff0c;…...

STM32 中断复习

中断 打断CPU执行正常的程序&#xff0c;转而处理紧急程序&#xff0c;然后返回原暂停的程序继续运行&#xff0c;就叫中断。 在确定时间内对相应事件作出响应&#xff0c;如&#xff1a;温度监控&#xff08;定时器中断&#xff09;。故障处理&#xff0c;检测到故障&#x…...

Django的模型

定义模型 from django.db import models class User(models.Model):# 类属性是表示表的字段username models.CharField(max_length50,uniqueTrue)password models.CharField(max_length200)create_time models.DateTimeField(auto_now_addTrue) # auto_now_add新增数据时间…...

非计算机科班如何丝滑转码

近年来&#xff0c;很多人想要从其他行业跳槽转入计算机领域。非计算机科班如何丝滑转码&#xff1f; 方向一&#xff1a;如何规划才能实现转码&#xff1f; 对于非计算机科班的人来说&#xff0c;想要在计算机领域实现顺利的转码并不是一件容易的事情&#xff0c;但也并非不…...

PyTorch深度学习实战(12)——数据增强

PyTorch深度学习实战&#xff08;12&#xff09;——数据增强 0. 前言1. 图像增强1.1 仿射变换1.2 亮度修改1.3 添加噪音1.4 联合使用多个增强方法 2. 对批图像执行图像增强3. 利用数据增强训练模型小结系列链接 0. 前言 数据增强是指通过对原始数据进行一系列变换和处理&…...

OpenOCD入门到精通:第23章 添加新的 JTAG 适配器驱动

第23章 添加新的 JTAG 适配器驱动 导读摘要:OpenOCD 支持 40 余种调试适配器,每种适配器背后都有一个遵循统一接口规范的驱动程序。本章从 adapter_driver 结构体出发,逐一解析其回调函数语义,介绍 libusb/HIDAPI 通信层封装,并通过一个完整的简易驱动实现示例,帮助读者掌…...

Nemo文件管理器终极指南:Cinnamon桌面环境下的高效文件管理神器

Nemo文件管理器终极指南&#xff1a;Cinnamon桌面环境下的高效文件管理神器 【免费下载链接】nemo File browser for Cinnamon 项目地址: https://gitcode.com/gh_mirrors/ne/nemo Nemo是Cinnamon桌面环境的官方文件管理器&#xff0c;作为一个免费开源的软件项目&#…...

手把手调试Android触摸反馈:用Systrace和日志追踪小圆点显示的全过程

Android触摸反馈调试实战&#xff1a;从Systrace到Logcat的全链路追踪 在移动应用开发中&#xff0c;触摸反馈的准确性和即时性直接影响用户体验。当用户手指接触屏幕时&#xff0c;那个跟随指尖跳动的小圆点看似简单&#xff0c;背后却隐藏着复杂的系统级交互。本文将带你深入…...

QQ音乐加密音频终极解密指南:qmcdump完整教程与实战应用

QQ音乐加密音频终极解密指南&#xff1a;qmcdump完整教程与实战应用 【免费下载链接】qmcdump 一个简单的QQ音乐解码&#xff08;qmcflac/qmc0/qmc3 转 flac/mp3&#xff09;&#xff0c;仅为个人学习参考用。 项目地址: https://gitcode.com/gh_mirrors/qm/qmcdump 你是…...

鸿蒙应用开发全景解析与高阶面试指南

第一章 鸿蒙生态技术演进与开发环境鸿蒙操作系统&#xff08;HarmonyOS&#xff09;的分布式架构实现了跨设备算力调度&#xff0c;其核心设计思想可抽象为&#xff1a; $$ \text{Device}i \xrightarrow{\text{IDMS}} \text{Pool}{\text{compute}} \xrightarrow{\text{DistSche…...

TAICHI-flet终极排障指南:从新手到高手的完整解决方案

TAICHI-flet终极排障指南&#xff1a;从新手到高手的完整解决方案 【免费下载链接】TAICHI-flet 基于flet的一款windows桌面应用&#xff0c;实现了浏览图片、音乐、小说、漫画、各种资源的功能。 项目地址: https://gitcode.com/GitHub_Trending/ta/TAICHI-flet TAICHI…...

PyTorch 2.8镜像保姆级教程:RTX 4090D下模型量化工具AutoGPTQ实操

PyTorch 2.8镜像保姆级教程&#xff1a;RTX 4090D下模型量化工具AutoGPTQ实操 1. 环境准备与快速部署 在开始使用AutoGPTQ进行模型量化之前&#xff0c;我们需要确保PyTorch 2.8镜像环境已经正确部署。本镜像专为RTX 4090D 24GB显卡优化&#xff0c;预装了CUDA 12.4和所有必要…...

手把手教你用STM32F405和SD卡,在阿里云物联网平台上实现OTA升级(MQTT协议详解)

STM32F405实战&#xff1a;基于SD卡与阿里云物联网平台的OTA升级全流程解析 当嵌入式设备部署在野外或工业现场时&#xff0c;固件升级往往成为工程师的噩梦。传统方式需要技术人员携带烧录器奔赴现场&#xff0c;不仅效率低下&#xff0c;在设备数量庞大或分布广泛时更是不切实…...

梦幻动漫魔法工坊:5分钟零基础搭建,小白也能生成专属二次元头像

梦幻动漫魔法工坊&#xff1a;5分钟零基础搭建&#xff0c;小白也能生成专属二次元头像 想不想拥有一个独一无二的二次元头像&#xff0c;却苦于不会画画&#xff1f;或者想为你的游戏角色、小说人物创造一个生动的形象&#xff0c;却找不到合适的画师&#xff1f;今天&#x…...

Pixel Fashion Atelier实操手册:批量生成时利用CSV导入多组Enchantment参数

Pixel Fashion Atelier实操手册&#xff1a;批量生成时利用CSV导入多组Enchantment参数 1. 引言&#xff1a;为什么需要批量生成功能 在时尚设计领域&#xff0c;设计师经常需要快速生成多个不同风格的服装设计方案。传统方式需要逐个输入参数、等待生成、再调整参数&#xf…...