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

使用Java创建RabbitMQ消息生产者的详细指南

目录

在现代分布式系统中,消息队列是实现异步通信的重要工具。RabbitMQ作为一种流行的开源消息代理,支持多种消息协议,广泛应用于微服务架构和事件驱动的应用程序中。本文将深入探讨如何使用Java创建RabbitMQ的消息生产者,发送消息到指定的交换机和队列,并涵盖相关的概念、配置和最佳实践。

1. 环境准备

Maven依赖

2. 创建生产者代码

代码解析

3. 运行程序

验证消息是否发送成功

4. RabbitMQ的概念与特性

4.1 消息

4.2 交换机

4.3 队列

4.4 路由键

5. 发送不同类型的消息

6. 消费者的实现

代码解析

运行消费者

7. 发送和接收不同类型的消息

发送和接收JSON消息的示例

更新生产者发送JSON消息

创建接收JSON消息的消费者

8. 处理异常和保证消息传递

9. RabbitMQ最佳实践

10. 总结


在现代分布式系统中,消息队列是实现异步通信的重要工具。RabbitMQ作为一种流行的开源消息代理,支持多种消息协议,广泛应用于微服务架构和事件驱动的应用程序中。本文将深入探讨如何使用Java创建RabbitMQ的消息生产者,发送消息到指定的交换机和队列,并涵盖相关的概念、配置和最佳实践。

1. 环境准备

在开始之前,我们需要确保开发环境的准备工作就绪。首先,确保您已经安装了RabbitMQ服务器,并且能够正常访问。您可以在RabbitMQ官方网站下载并安装RabbitMQ。安装完成后,启动RabbitMQ服务,并确保其在默认端口5672上运行。

Maven依赖

在Java项目中使用RabbitMQ,您需要在pom.xml文件中添加RabbitMQ的AMQP客户端库依赖。以下是所需的Maven依赖项:

<dependency>  <groupId>com.rabbitmq</groupId>  <artifactId>amqp-client</artifactId>  <version>5.15.0</version> <!-- 请根据需要选择合适的版本 -->  
</dependency>

确保您的项目能够访问Maven中央仓库,以便下载所需的依赖项。

2. 创建生产者代码

接下来,我们将创建一个简单的RabbitMQ消息生产者。以下是完整的Java代码示例:

import com.rabbitmq.client.*;  public class Producer {  public static void main(String[] args) throws Exception {  // RabbitMQ服务器的连接信息  String host = "10.56.11.34"; // RabbitMQ服务器地址  String userName = "DHCloud7X"; // 用户名  String passWord = "Cloud0#1nw2qezr"; // 密码  String exchangeName = "cnk_exchangeName"; // 交换机名称  String queueName = "cnk_queueName"; // 队列名称  // 创建连接工厂并设置连接参数  ConnectionFactory connectionFactory = new ConnectionFactory();  connectionFactory.setHost(host);  connectionFactory.setUsername(userName);  connectionFactory.setPassword(passWord);  connectionFactory.setPort(5672); // 默认端口  connectionFactory.setConnectionTimeout(20000); // 超时时间,单位毫秒  connectionFactory.setRequestedHeartbeat(10); // 心跳,单位秒  // 启用重连机制  connectionFactory.setAutomaticRecoveryEnabled(true); // 设置网络异常重连  connectionFactory.setNetworkRecoveryInterval(10000); // 设置10秒重连一次  connectionFactory.setTopologyRecoveryEnabled(true); // 设置重新声明交换器、队列等信息  // 创建连接和信道  try (Connection connection = connectionFactory.newConnection();   Channel channel = connection.createChannel()) {  // 声明交换机  channel.exchangeDeclare(exchangeName, BuiltinExchangeType.DIRECT, true, false, null);  // 声明队列  channel.queueDeclare(queueName, true, false, false, null);  // 队列绑定  channel.queueBind(queueName, exchangeName, queueName);  // 发送消息  String message = "hello rabbitMq";  channel.basicPublish(exchangeName, queueName, null, message.getBytes());  System.out.println("发送成功!");  } catch (Exception e) {  e.printStackTrace();  }  }  
}

代码解析

  1. 连接参数:我们使用ConnectionFactory来配置RabbitMQ的连接参数,包括主机、端口、用户名和密码等。

  2. 重连机制:为了提高系统的健壮性,我们启用了自动重连和拓扑重连功能。这意味着在网络故障或RabbitMQ服务重启的情况下,生产者能够自动恢复连接。

  3. 创建连接和信道:通过connectionFactory.newConnection()创建连接,并使用connection.createChannel()创建信道。信道是执行RabbitMQ操作的主要接口。

  4. 声明交换机和队列:使用channel.exchangeDeclare()channel.queueDeclare()声明交换机和队列。我们使用DIRECT类型的交换机,这意味着消息将根据路由键精确路由到绑定的队列。

  5. 绑定队列:通过channel.queueBind()将队列与交换机绑定,指定路由键。

  6. 发送消息:使用channel.basicPublish()方法发送消息。消息的内容在这里是一个简单的字符串“hello rabbitMq”。

  7. 关闭资源:使用try-with-resources语句自动关闭信道和连接,确保资源得到释放。

3. 运行程序

确保RabbitMQ服务正在运行后,编译并运行上述代码。如果一切正常,您将看到“发送成功!”的提示,表示消息已成功发送。

验证消息是否发送成功

要验证消息是否成功发送到队列中,您可以使用RabbitMQ管理界面。访问http://localhost:15672(如未更改默认配置),使用您的RabbitMQ凭据登录。

在管理界面中,您可以查看交换机、队列及其消息状态。您将看到我们创建的队列cnk_queueName,并且其中应该有一条消息。

4. RabbitMQ的概念与特性

在深入RabbitMQ之前,了解一些基本概念是非常重要的:

4.1 消息

消息是RabbitMQ中传递的数据单元。它由消息体和一些元数据(如路由键、属性等)组成。消息体可以是任意字节数据,通常是字符串、JSON或序列化对象。

4.2 交换机

交换机是RabbitMQ的核心组件之一,负责接收来自生产者的消息并根据路由规则将其分发到一个或多个队列。RabbitMQ支持多种类型的交换机,包括:

  • Direct Exchange:根据路由键精确路由消息。
  • Fanout Exchange:将消息广播到所有绑定的队列。
  • Topic Exchange:根据路由键的模式匹配路由消息。
  • Headers Exchange:根据消息的头部属性路由消息。

4.3 队列

队列是RabbitMQ中存储消息的地方。消息在队列中等待消费者处理。队列具有以下特性:

  • 持久性:队列可以设置为持久化,以确保在RabbitMQ重启后消息不会丢失。
  • 消息确认:消费者在处理消息后需要确认,以确保消息被成功消费。

4.4 路由键

路由键是消息的一个重要属性,用于决定消息的路由路径。生产者在发送消息时指定路由键,交换机根据路由键将消息路由到相应的队列。

5. 发送不同类型的消息

在实际应用中,您可能需要发送不同类型的消息,例如JSON格式或二进制数据。以下是如何发送JSON格式消息的示例:

import com.rabbitmq.client.*;  
import com.fasterxml.jackson.databind.ObjectMapper;  public class JsonProducer {  public static void main(String[] args) throws Exception {  // 连接参数同上...  String exchangeName = "json_exchange";  String queueName = "json_queue";  ConnectionFactory connectionFactory = new ConnectionFactory();  // 设置连接参数...  try (Connection connection = connectionFactory.newConnection();   Channel channel = connection.createChannel()) {  // 声明交换机和队列...  channel.exchangeDeclare(exchangeName, BuiltinExchangeType.DIRECT, true, false, null);  channel.queueDeclare(queueName, true, false, false, null);  channel.queueBind(queueName, exchangeName, queueName);  // 创建一个对象并转换为JSON格式  Message messageObj = new Message("Hello, RabbitMQ!", 1);  ObjectMapper objectMapper = new ObjectMapper();  String jsonMessage = objectMapper.writeValueAsString(messageObj);  // 发送JSON消息  channel.basicPublish(exchangeName, queueName, null, jsonMessage.getBytes());  System.out.println("JSON消息发送成功!");  } catch (Exception e) {  e.printStackTrace();  }  }  static class Message {  private String content;  private int id;  public Message(String content, int id) {  this.content = content;  this.id = id;  }  // getters and setters...  }  
}

在这个示例中,我们使用Jackson库将一个简单的Java对象转换为JSON格式,并将其发送到RabbitMQ。确保在pom.xml中添加Jackson的依赖:

<dependency>  <groupId>com.fasterxml.jackson.core</groupId>  <artifactId>jackson-databind</artifactId>  <version>2.14.0</version> <!-- 请根据需要选择合适的版本 -->  
</dependency>

6. 消费者的实现

为了完整性,我们也需要实现一个消费者来接收和处理消息。以下是一个简单的RabbitMQ消费者示例:

import com.rabbitmq.client.*;  public class Consumer {  public static void main(String[] args) throws Exception {  // RabbitMQ连接信息  String host = "10.56.11.34"; // RabbitMQ服务器地址  String userName = "DHCloud7X"; // 用户名  String passWord = "Cloud0#1nw2qezr"; // 密码  String exchangeName = "cnk_exchangeName"; // 交换机名称  String queueName = "cnk_queueName"; // 队列名称  // 创建连接工厂并设置连接参数  ConnectionFactory connectionFactory = new ConnectionFactory();  connectionFactory.setHost(host);  connectionFactory.setUsername(userName);  connectionFactory.setPassword(passWord);  connectionFactory.setPort(5672); // 默认端口  connectionFactory.setConnectionTimeout(20000); // 超时时间,单位毫秒  connectionFactory.setRequestedHeartbeat(10); // 心跳,单位秒  // 启用重连机制  connectionFactory.setAutomaticRecoveryEnabled(true); // 设置网络异常重连  connectionFactory.setNetworkRecoveryInterval(10000); // 设置10秒重连一次  connectionFactory.setTopologyRecoveryEnabled(true); // 设置重新声明交换器、队列等信息  // 创建连接和信道  try (Connection connection = connectionFactory.newConnection();  Channel channel = connection.createChannel()) {  // 声明队列(确保队列存在)  channel.queueDeclare(queueName, true, false, false, null);  // 定义消息处理回调  DeliverCallback deliverCallback = (consumerTag, delivery) -> {  String message = new String(delivery.getBody(), "UTF-8");  System.out.println("接收到消息: " + message);  };  // 开始消费消息  channel.basicConsume(queueName, true, deliverCallback, consumerTag -> { });  System.out.println("消费者已启动,等待接收消息...");  // 保持程序运行以接收消息  Thread.sleep(Long.MAX_VALUE);  } catch (Exception e) {  e.printStackTrace();  }  }  
}

代码解析

  1. 连接配置:与生产者相似,消费者也需要设置连接信息,包括RabbitMQ的主机、用户名和密码等。

  2. 声明队列:使用channel.queueDeclare()确保要订阅的队列存在。即使队列已经存在,调用此方法也不会对其进行修改。

  3. 消息处理回调:定义一个DeliverCallback回调,用于处理接收到的消息。delivery.getBody()获取消息的内容,并转换为字符串形式进行打印。

  4. 开始消费消息:使用channel.basicConsume()开始消费消息,这里我们传入队列名称、自动确认模式(设置为true表示处理完消息后自动确认)、处理消息的回调和一个空的取消回调。

  5. 保持程序运行:通过调用Thread.sleep(Long.MAX_VALUE)保持程序运行,以便持续接收消息。

运行消费者

在运行消费者之前,确保RabbitMQ服务器正常运行,并使用前面步骤发送了一些消息。启动消费者代码后,它将持续监听队列并打印接收到的消息。

7. 发送和接收不同类型的消息

在实践中,您可能需要处理多种格式的消息。RabbitMQ允许您发送和接收二进制数据、字符串、JSON和XML等。

发送和接收JSON消息的示例

为了实现更复杂的消息处理,您可以将消息体设计为JSON格式,以下是发送和接收JSON格式消息的示例。

更新生产者发送JSON消息

我们已经在前面的部分中创建了一个发送JSON消息的生产者。这里简单回顾一下:

import com.fasterxml.jackson.databind.ObjectMapper;  public class JsonProducer {  public static void main(String[] args) throws Exception {  // 连接和信道的配置同上...  String exchangeName = "json_exchange";  String queueName = "json_queue";  // 创建连接和信道  try (Connection connection = connectionFactory.newConnection();   Channel channel = connection.createChannel()) {  // 创建对象  Message messageObj = new Message("Hello, RabbitMQ!", 1);  ObjectMapper objectMapper = new ObjectMapper();  String jsonMessage = objectMapper.writeValueAsString(messageObj);  // 发送JSON消息  channel.basicPublish(exchangeName, queueName, null, jsonMessage.getBytes());  System.out.println("JSON消息发送成功!");  }  }  static class Message {  private String content;  private int id;  public Message(String content, int id) {  this.content = content;  this.id = id;  }  // getters和setters...  }  
}
创建接收JSON消息的消费者

以下是一个简单的消费者示例,用于接收JSON消息并转换为对象:

import com.fasterxml.jackson.databind.ObjectMapper;  
import com.rabbitmq.client.*;  public class JsonConsumer {  public static void main(String[] args) throws Exception {  // 连接和信道的配置同上...  String exchangeName = "json_exchange";  String queueName = "json_queue";  // 创建连接和信道  try (Connection connection = connectionFactory.newConnection();   Channel channel = connection.createChannel()) {  // 声明队列(确保队列存在)  channel.queueDeclare(queueName, true, false, false, null);  // JSON处理器  ObjectMapper objectMapper = new ObjectMapper();  DeliverCallback deliverCallback = (consumerTag, delivery) -> {  String jsonMessage = new String(delivery.getBody(), "UTF-8");  // 将接收到的JSON字符串转换为Message对象  Message message = objectMapper.readValue(jsonMessage, Message.class);  System.out.println("接收到消息: 内容 = " + message.getContent() + ", ID = " + message.getId());  };  // 开始消费消息  channel.basicConsume(queueName, true, deliverCallback, consumerTag -> { });  System.out.println("JSON消费者已启动,等待接收消息...");  // 保持程序运行以接收消息  Thread.sleep(Long.MAX_VALUE);  }  }  static class Message {  private String content;  private int id;  // Getters 和 Setters...  public String getContent() {  return content;  }  public void setContent(String content) {  this.content = content;  }  public int getId() {  return id;  }  public void setId(int id) {  this.id = id;  }  }  
}

8. 处理异常和保证消息传递

在实际应用中,需要注意异常处理和消息的可靠性。这包括:

  • 消息确认:使用手动确认模式来确保消息被消费者成功处理。可以在basicConsume时将第二个参数设置为false,消费者处理完消息后使用channel.basicAck(deliveryTag, false)确认。

  • 消息重试与死信队列:在处理消息失败时,可以选择重试或将其发送到死信队列(DLQ),以便后续分析和处理。

  • 事务:RabbitMQ支持事务,您可以使用channel.txSelect()channel.txCommit()channel.txRollback()来管理事务。但需要注意,事务可能会引入性能开销。

9. RabbitMQ最佳实践

  • 合理配置队列:根据业务需求配置持久性、消息 TTL(存活时间)、最大长度等,确保队列能够高效工作。

  • 监控和管理:使用RabbitMQ管理插件来监控队列、交换机和消费者的性能和状态,及时发现和解决问题。

  • 异步处理:利用消息队列的异步特性解耦系统,让生产者与消费者独立扩展。

  • 安全性考虑:确保RabbitMQ的访问权限配置合理,使用SSL/TLS加密连接,以增强系统的安全性。

10. 总结

  • 在本文中,我们深入探讨了如何使用Java创建RabbitMQ的消息生产者和消费者,并介绍了RabbitMQ的基本概念及其关键特性。通过这些示例,您可以更好地理解异步消息通信的实现方法以及RabbitMQ在现代分布式系统中的应用价值。

    RabbitMQ不仅为系统间的通信提供了解耦的解决方案,其强大的功能和灵活的配置选项使其成为很多企业首选的消息队列方案。希望这篇指南能帮助您在未来的项目中灵活运用RabbitMQ。

相关文章:

使用Java创建RabbitMQ消息生产者的详细指南

目录 在现代分布式系统中&#xff0c;消息队列是实现异步通信的重要工具。RabbitMQ作为一种流行的开源消息代理&#xff0c;支持多种消息协议&#xff0c;广泛应用于微服务架构和事件驱动的应用程序中。本文将深入探讨如何使用Java创建RabbitMQ的消息生产者&#xff0c;发送消息…...

笔记本外接显示屏没声音

1、笔记本正常有声音&#xff0c;但是外接显示屏后没有声音了怎么回事呢&#xff1f;原来外接显示屏后笔记本的声音输出会自动选择显示屏的音频输出&#xff0c;但是显示屏可能没有声音输出所以导致笔记本没有声音。 2、解决办法&#xff1a;打开笔记本设置&#xff0c;选择声…...

【Linux】Linux权限管理:文件与目录的全面指南

在Linux系统中&#xff0c;权限管理是确保数据安全的关键。本文将为大家介绍Linux文件与目录的权限管理&#xff0c;帮助你理解如何设置和管理访问权限。无论你是新手还是有经验的用户&#xff0c;这里都将提供实用的技巧和知识&#xff0c;助你更好地掌握Linux环境。让我们一起…...

并发在前端中的应用?

‌并发在前端中的应用主要体现在处理多个请求和优化页面加载速度方面‌。前端并发处理通常涉及在极短时间内发送多个数据请求&#xff0c;例如在页面渲染时同时请求多个数据。通过并发处理&#xff0c;可以显著减少页面加载时间&#xff0c;提升用户体验。 前端并发处理的具体…...

Spring Boot助力,一键解锁招聘全流程信息精细化管理

2系统相关技术 2.1 Java语言介绍 Java是由SUN公司推出&#xff0c;该公司于2010年被oracle公司收购。Java本是印度尼西亚的一个叫做爪洼岛的英文名称&#xff0c;也因此得来java是一杯正冒着热气咖啡的标识。Java语言在移动互联网的大背景下具备了显著的优势和广阔的前景&#…...

沉浸式多用户跟踪解决方案

沉浸式多用户VR跟踪解决方案&#xff0c;支持使用HTC VIVE或Valve Index等消费级虚拟现实头盔在房间内执行大范围多用户跟踪。该解决方案不仅能够跟踪处于坐姿或其他静止用户的头部和控制器&#xff0c;还支持房间内多用户动态跟踪。 通常房间内的跟踪受限于特定的系统能力&…...

“切片赋值”创建列表批量操作“新”方法(Python)

[start:end]切片赋值&#xff0c;扩展了list批量增减元素的操作能力。 (笔记模板由python脚本于2024年12月06日 15:07:56创建&#xff0c;本篇笔记适合研python基础的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;…...

Linux中-vvv详细输出命令

在 Shell 脚本中&#xff0c;有时会看到某些命令后面加上 -vvv 或类似的选项。这个选项的作用通常与命令的 **调试模式** 或 **详细输出** 相关。不同的命令和工具对于选项的解释和处理方式不同&#xff0c;因此 -vvv 的具体含义取决于它所跟随的命令。 ### 一般来说&#xff…...

获取淘宝商品评论数据的API应用:市场调研|产品更新|用户数据

下面是一段我用item_review&#xff08;获取商品评论数据&#xff09;抓来的商品评论数据&#xff1a; "items": {"total_results": 375,"totalpage": 38,"page_size": 10,"page": "1","item": [{&quo…...

VRRP的知识点总结及实验

1、VRRP VRRP(Virtual Router Redundancy Protocol&#xff0c;虚拟路由器冗余协议)既能够实现网关的备份&#xff0c;又能解决多个网关之间互相冲突的问题&#xff0c;从而提高网络可靠性。 2、VRRP技术概述&#xff1a; 通过把几台路由设备联合组成一台虚拟的“路由设备”…...

群控系统服务端开发模式-应用开发-邮件发送工具类

一、邮件发送工具类开发 1、添加框架对应的SDK composer require phpmailer/phpmailer 2、添加工具集 在根目录下extend文件夹下创建Email文件夹&#xff0c;在Email文件夹下添加工具集控制并命名为EmailSender.php <?php /*** 邮件发送工具* User: 龙哥三年风水* Date: …...

pytest 的简单介绍

官方文档&#xff1a;pytest 文档 1. pytest 概述 pytest 是一个功能强大的 Python 测试框架&#xff0c;旨在简化单元测试和功能测试的编写与执行。它不仅支持简单的单元测试&#xff0c;还能进行更复杂的测试&#xff0c;如数据驱动的测试、并发测试等。pytest 支持自动化发…...

【C语言】库函数常见的陷阱与缺陷(2):字符串转化函数

目录 一、atoi 函数 1.1. 功能与用法 1.2. 陷阱与缺陷 1.2.1. 输入验证不足 1.2.2. 溢出问题 1.3 安全替代 1.4. 代码示例 二、atof 函数 2.1. 功能与用法 2.2. 陷阱与缺陷 2.3. 安全使用建议 2.4. 代码示例 三、strtol 函数 3.1. 功能与用法 3.2. 陷阱与缺陷 …...

【LeetCode每日一题】LeetCode 976.三角形的最大周长

LeetCode 976.三角形的最大周长 题目描述 给定一个包含非负整数的数组 nums&#xff0c;其中每个元素表示一个线段的长度。你需要从中选出三个线段&#xff0c;组成一个三角形&#xff0c;使得三角形的周长最大&#xff0c;并返回这个最大周长。如果无法组成三角形&#xff0…...

在 Ubuntu 24 上安装 Redis 7.0.15 并配置允许所有 IP 访问

前提条件 一台运行 Ubuntu 24 的服务器拥有 sudo 权限的用户 步骤一&#xff1a;更新系统包 首先&#xff0c;确保系统包是最新的&#xff0c;以避免潜在的依赖问题。 sudo apt update sudo apt upgrade -y步骤二&#xff1a;安装编译 Redis 所需的依赖 Redis 需要一些编译…...

C# 中的异常处理:构建健壮和可靠的程序

C#中的异常处理&#xff08;Exception Handling&#xff09;。异常处理是编程中非常重要的一部分&#xff0c;它允许开发者优雅地处理程序运行时可能出现的错误或意外情况。通过有效的异常处理&#xff0c;可以使应用程序更加健壮、可靠&#xff0c;并提供更好的用户体验。以下…...

Prime2_解法二:openssl解密凭据

Prime2_解法二&#xff1a;openssl解密凭据 本博客提供的所有信息仅供学习和研究目的&#xff0c;旨在提高读者的网络安全意识和技术能力。请在合法合规的前提下使用本文中提供的任何技术、方法或工具。如果您选择使用本博客中的任何信息进行非法活动&#xff0c;您将独自承担全…...

数据结构 ——数状存储的基本概念

数据结构 ——数状存储的基本概念 一、树状存储基本概念 1、 深度&#xff08;层数&#xff09;&#xff1a;计算一个节点的深度&#xff0c;从根节点算起&#xff08;从1开始计数&#xff09;&#xff0c;到该节点所经过的节点数&#xff08;包括此节点&#xff09;为树的深度…...

【网盘系统】递归删除批量文件、从回收站恢复文件、彻底删除文件

为何需要用到递归&#xff1f; 在网盘系统中&#xff0c;文件的类型分为文件和文件夹两种类型。当我们想要批量删除文件时&#xff0c;不乏其中会包含文件夹&#xff0c;而想要删除这个文件夹&#xff0c;自然其中所包含的文件都要删除&#xff0c;而其中所包含的文件也有可能…...

C++ 列表初始化(initializer_list)

列表初始化(initializer_list) 列表初始化是C中的一种语法特性&#xff0c;引入于C11&#xff0c;用于更简单直观地初始化变量、对象或容器。它使用花括号 {}&#xff0c;提供了更安全的初始化方式&#xff0c;避免了类型窄化转换等潜在错误。 定义 列表初始化是用花括号 {}…...

【Keil】Keil MDK 已经不再提供 ARM Compiler v5

该问题出现在 Keil MDK v5.12 之后 用必应搜索相关问题&#xff0c;发现早已在 ARM community 提了 How can I install Compiler Version 5 for Keil vision 5 回答给出了这个文档 Documentation - Arm Developer 文档提到了 ARM Compiler 5 的下载地址&#xff0c;但是得登录 …...

Knowledge Graph Studio:让知识图谱构建更简单、更智能

一、前言 上周和研究院的同事讨论 2025 年大模型产品规划时&#xff0c;让我产生了一些疑惑和不解&#xff0c;因为从大家交流的规划方向来看&#xff0c;更多的还是集中在Prompt提示词工程&#xff08;包括提示词的管理、测试、评估、调优&#xff09;这一块规划的确实挺细&a…...

【jvm】垃圾判别阶段算法

目录 1. 说明2. 引用计数算法2. 可达性分析算法3. 垃圾判别阶段的过程 1. 说明 1.JVM主要使用两种垃圾判别算法&#xff1a;引用计数算法和可达性分析算法。 2. 引用计数算法 1.原理&#xff1a;为每个对象维护一个引用计数器&#xff0c;每当有地方引用该对象时&#xff0c…...

深入理解Linux进程管理机制

个人主页&#xff1a;chian-ocean 文章专栏-Linux 前言 进程是现代操作系统中一个不可或缺的概念&#xff0c;其主要目的在于管理资源、实现并发、提高系统效率&#xff0c;并确保系统的稳定性和安全性。 进程的定义 进程&#xff08;Process&#xff09; 是计算机操作系统中…...

OV2640摄像头模块介绍

目录 一、引言 二、模块概述 三、技术特点 四、工作原理 五、接口类型 六、应用领域 七、使用方法 八、参数设置 九、图像数据处理 十、调试和故障排除 十一、结语 一、引言 在当今的科技时代&#xff0c;图像采集和处理技术在众多领域发挥着至关重要的作用。其中&…...

机器人的动力学前馈控制

机器人前馈技术可加快伺服驱动器内部的误差收敛速度&#xff0c;进而改善机器人的动态响应特性&#xff0c;解决机器人在运动过程中的抖动问题&#xff0c;提升机器人系统的精度和效率。 对于关节型机器人而言&#xff0c;在理想的刚性连接下&#xff0c;若给定每个关节所需要的…...

Python+OpenCV系列:图像的几何变换

Python OpenCV 系列&#xff1a;图像的几何变换 引言 在图像处理领域&#xff0c;几何变换是一个非常重要的操作&#xff0c;它可以改变图像的位置、大小、方向或形状。在计算机视觉中&#xff0c;这些操作对于图像预处理、特征提取和图像增强至关重要。本文将介绍如何利用 …...

IC验证基础知识系列随笔

一、断言 and 和 和 intersect 区别 And 指的是两个序列具有相同的起始点&#xff0c;终点可以不同。 Intersect 指的是两个序列具有相同的起始点和终点。 Or 指的是两个序列只要满足一个就可以 Throughout 指的是满足前面要求才能执行后面的序列 二、Break&#xff1b;co…...

网络测速工具

1. SPEEDTEST https://www.speedtest.net/ 2. 测速网 测速网 - 专业测网速, 网速测试, 宽带提速, 游戏测速, 直播测速, 5G测速, 物联网监测,Wi-Fi 7,Wi-Fi 6,FTTR,全屋Wi-Fi - SpeedTest.cn 3. 字节比特换算 bps&#xff08;bits per second&#xff09; 字节和比特的换算…...

windows将文件推给Android真机/实机

记录一下 因为以前只试过从真机实机中将文件推给windows 但是从windows只简单复制粘贴的话会一直报错。 1.电脑安装adb 2.手机开启开发者模式 usb调试 3.usb连接选择文件传输 4.推送命令adb push 文件路径 /sdcard/download 步骤1和2和3不作赘述&#xff0c;可以搜相关配置教程…...

Scratch教学作品 | 3D飞行模拟器——体验飞行的无限乐趣! ✈️

今天为大家推荐一款令人惊叹的Scratch作品——《3D飞行模拟器》&#xff01;由BamBozzle制作&#xff0c;这款游戏完全用Scratch构建&#xff0c;带你体验开放世界飞行的自由与乐趣。从起飞到降落&#xff0c;每一步都需要你的精准操作&#xff01;更棒的是&#xff0c;这款游戏…...

nonolog转化为ctf的困难

nonolog转化为ctf的困难 nanolog分析的中间的总结二者之间的差别 nanolog分析的中间的总结 如果目标是转nanolog为CTF格式&#xff0c;最重要的应该是meta的定义的转换的问题了。 目前我是稍有气馁。 感觉这不是一个好的方向。 如果领导能给连续的时间&#xff0c;完全开发自定…...

Sqoop导入数据(mysql---->>hive)

目录 数据传输流程脚本报错和异常说明1. Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.hive.conf.HiveConf2. 数据导入hive后显示NULL 数据传输流程 mysql---->>hdfs---->>hive 数据从mysql表中取出&#xff0c;放到hdfs上&#xff08;由targ…...

vivado bd文件复制

不同工程是无法进行BD文件复制的&#xff0c;可以通过将被复制的BD文件添加到需要复制的BD文件的工程中&#xff0c;然后再工程内进行复制...

2024年深圳杯数学建模C题编译器版本的识别问题解题全过程文档及程序

2024年深圳杯数学建模 C题 编译器版本的识别问题 原题再现&#xff1a; 作为一种重要的工具&#xff0c;电子计算机自诞生以来&#xff0c;经历了极为快速的发展。区区百年的时间内&#xff0c;无论从体积、能耗、计算速度&#xff0c;还是应用能力等方面&#xff0c;电子计算…...

介绍一下希尔排序法(c基础)

hi , I am 36 适合对象c语言初学者 希尔排序&#xff08;Shell Sort&#xff09;是一种改进的插入排序算法&#xff0c;它通过将原始数据分成多个子序列来改善插入排序在处理大规模无序数组时性能较差的情况。 基本原理 希尔排序的基本思想是先将整个待排序的记录序列分割成为…...

SQL,根据数据的时间跨度进行不同粒度的统计

MSSQL 的某个视图会生成时间跨度不同的数据&#xff0c;当时间跨度小于 30 天时&#xff1a; idbranchIdtotalPricecreatedAt8512718.662022-07-03 08:49:27.7272613832.692022-07-06 09:08:06.8808919569.852022-07-07 04:13:09.2308011523.622022-07-07 04:38:29.3131512500…...

OPenCV 图片局部放大

m_image cv::imread("C:/Code/JPG/1.jpg");if (m_image.empty()) return;cv::imshow("原始图像", m_image); // TODO: 在此添加控件通知处理程序代码int width m_image.cols;int height m_image.rows;// 确定要放大的区域&#xff08;这里是图像中心部分…...

【C#设计模式(19)——备忘录模式(MementoPattern)】

前言 备忘录模式&#xff1a;将想要备份的信息交给备忘录对象来管理。通过设置初始、备份、修改、恢复等状态展示备忘录模式的使用。 代码 //备忘录类 public class Memento {private string state;public string State { get>state;}public Memento(string state){this.st…...

使用 Nginx 在同一端口部署两个前端项目并配置子路径

在现代 Web 开发中&#xff0c;我们经常需要在同一台服务器上部署多个前端项目。这不仅可以节省资源&#xff0c;还可以简化管理。本文将指导你如何使用Nginx在同一端口上部署两个前端项目&#xff0c;并通过配置子路径来区分它们。 环境准备 首先&#xff0c;我们需要准备两…...

CISC和RISC的区别

CISC是什么 CISC是一种指令集设计方式&#xff0c;全程叫复杂指令集&#xff0c;这种指令设计模式包含大量的复杂指令和复杂的寻址方式&#xff0c; 以下是CISC架构的一些主要特点&#xff1a; 丰富的指令集&#xff1a;CISC处理器通常包含大量的指令&#xff0c;这些指令覆盖…...

学生信息管理系统(简化版)后端接口

目录 allAPI __init__.py是空文件&#xff0c;目的让python知道这个文件夹是个包 ClassInfo.py from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from API.database import get_db, Base from sqlalchemy import Column, String,…...

一、开启 GD32 单片机的学习之门

文章目录 一、开启GD32单片机的学习之门二、筑牢根基&#xff1a;GD32单片机基础知识全解析&#xff08;一&#xff09;单片机概述 三、开发环境搭建&#xff08;一&#xff09;软件下载与安装&#xff08;二&#xff09;安装GD32F450设备支持包&#xff08;三&#xff09;编译…...

计算生成报价单小程序系统开发方案

计算生成报价单小程序报价系统&#xff0c;是根据商品品牌、类型、型号、规格、芯数、特性、颜色、分类进行选择不同的参数进行生成报价单&#xff0c;要求报价单支持生成图片、pdf、excel表格。 计算生成报价单小程序系统的主要功能模块有&#xff1a; 1、在线生成报价单&…...

高效整合聚水潭库存数据至MySQL的实现

聚水潭数据集成到MySQL&#xff1a;商品库存查询案例分享 在本次技术案例中&#xff0c;我们将详细探讨如何通过轻易云数据集成平台&#xff0c;将聚水潭的商品库存数据高效、可靠地集成到MySQL数据库中。具体方案为“聚水潭-商品库存查询-->BI彩度-商品库存表”&#xff0…...

深入理解 JVM 的栈帧结构

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…...

爬虫基础之HTTP基本原理

URL和URI 我们先了解一下 URI和 URL。URI的全称为 Uniform Resource ldentifer,即统一资源标志符;URL的全称为 Universal Resource Locator&#xff0c;即统一资源定位符。它们是什么意思呢?举例来说&#xff0c;https:/github.com/favicon.ico 既是一个 URI&#xff0c;也是…...

PyQt5:一个逗号引发的闪退血案

【日常小计】 在开发PyQt5程序时&#xff0c;调用了一个写入excel表格的后端方法&#xff0c;但是每次打开页面点击对应的动作&#xff0c;窗口就会闪退&#xff0c;而且Python后台也没有提示出任何的异常堆栈&#xff0c;后来经过在后端一点一点的单点测试&#xff0c;终于发…...

python学opencv|读取图像(五)读取灰度图像像素

【1】引言 前序学习了图像的基本读取&#xff0c;掌握了imread()、imshow()和imwrite()函数的基本功能和使用技巧&#xff0c;参考文章链接为&#xff1a; python学opencv|读取图像-CSDN博客 然后陆续掌握了彩色图像保存、图像放大和缩小以及对imshow()函数的大胆尝试技巧&a…...

LiDAR点云 反射强度 常见物体反射强度

1.激光点云发射的点无法全部被反射回来的原因 激光点云发射的点无法全部被反射回来的原因主要包括以下几点&#xff1a; 目标物表面特性&#xff1a;某些物体表面具有高反射率&#xff0c;导致激光雷达接收到的反射能量过强&#xff0c;从而产生噪点&#xff0c;影响点云数据的…...