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

002 JavaClent操作RabbitMQ

Java Client操作RabbitMQ

文章目录

  • Java Client操作RabbitMQ
    • 1.pom依赖
    • 2.连接工具类
    • 3.简单模式
    • 4.工作队列模式(work)
      • 公平调度
      • 示例
    • 5.发布/订阅模式(fanout)
      • 交换机
      • 绑定
      • 示例代码
    • 6.路由模式(direct)
    • 7.Topic匹配模式

1.pom依赖

<!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp-client -->
<dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.20.0</version>
</dependency>

2.连接工具类

/*** rabbitmq连接工具类* @author moshangshang*/
@Slf4j
public class RabbitMQUtil {private static final String HOST_ADDRESS="192.168.1.102";private static final Integer PORT=5672;private static final String VIRTUAL_HOST="my_vhost";private static final String USER_NAME="root";private static final String PASSWORD="root";public static Connection getConnection() throws Exception {com.rabbitmq.client.ConnectionFactory factory=new com.rabbitmq.client.ConnectionFactory();factory.setHost(HOST_ADDRESS);factory.setPort(PORT);factory.setVirtualHost(VIRTUAL_HOST);factory.setUsername(USER_NAME);factory.setPassword(PASSWORD);return factory.newConnection();}public static void main(String[] args) {Connection connection = null;try {connection = getConnection();} catch (Exception e) {log.error("get rabbitmq connection exception....",e);}finally {try {if(connection!=null){connection.close();}} catch (IOException e) {log.error("close rabbitmq connection exception....",e);}}}}

3.简单模式

生产者投递消费到队列进行消费

在这里插入图片描述

消息发送

public class Send {private final static String QUEUE_NAME = "hello";public static void main(String[] argv) throws Exception {Connection connection = RabbitMQUtil.getConnection();try (Channel channel = connection.createChannel()) {//声明队列/**  如果队列不存在,则会创建*  Rabbitmq不允许创建两个相同的队列名称,否则会报错。**  @params1: queue 队列的名称*  @params2: durable 队列是否持久化*  @params3: exclusive 是否排他,即是否私有的,如果为true,会对当前队列加锁,其他的通道不能访问,并且连接自动关闭*  @params4: autoDelete 是否自动删除,当最后一个消费者断开连接之后是否自动删除消息。*  @params5: arguments 可以设置队列附加参数,设置队列的有效期,消息的最大长度,队列的消息生命周期等等。* */channel.queueDeclare(QUEUE_NAME, false, false, false, null);String message = "Hello World!";channel.basicPublish("", QUEUE_NAME, null, message.getBytes());System.out.println(" [x] Sent '" + message + "'");}}
}

消息接收

因为希望在消费者异步监听消息到达时,当前程序能够继续执行,而不是退出。

因为提供了一个DeliverCallback回调,该回调将缓冲消息,直到准备使用它们。

public class Recv {private final static String QUEUE_NAME = "hello";public static void main(String[] argv) throws Exception {Connection connection = RabbitMQUtil.getConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), StandardCharsets.UTF_8);System.out.println(" [x] Received '" + message + "'");};channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });}
}

4.工作队列模式(work)

生产者直接投递消息到队列,存在多个消费者情况

  • 创建一个工作队列,用于在多个工作人员之间分配耗时的任务。
  • 工作队列(又名:任务队列)背后的主要思想是避免立即执行资源密集型任务,并必须等待其完成。相反,我们把任务安排在以后完成。我们将任务封装为消息并将其发送到队列。在后台运行的工作进程将弹出任务并最终执行作业。当你运行多个worker时,任务将在它们之间共享。
  • 这个概念在web应用程序中特别有用,因为在短的HTTP请求窗口内无法处理复杂的任务。
  • 默认情况下,消费者会进行轮询调度
  • RabbitMQ支持消息确认。消费者发送回一个确认,告诉RabbitMQ已经收到、处理了一条特定的消息,RabbitMQ可以自由删除它。
  • 如果一个消费者在没有发送ack的情况下死亡(其通道关闭、连接关闭或TCP连接丢失),RabbitMQ将理解消息未完全处理,并将其重新排队。如果同时有其他消费者在线,它将迅速将其重新传递给另一个消费者。这样,即使worker偶尔挂掉,也可以确保没有信息丢失。
  • 消费者交付确认时强制执行超时(默认为30分钟)。这有助于检测一直没有确认的消费者。
  • 默认情况下,手动消息确认已打开。在前面的示例中,我们通过autoAck=true标志明确地关闭了它们。一旦我们完成了一项任务,是时候将此标志设置为false并从worker发送适当的确认了。

在这里插入图片描述

公平调度

由于默认轮询调度,有些任务执行时间长,有些短,所以会导致部分worker压力大

使用预取计数=1设置的basicQos方法。这条消息告诉RabbitMQ一次不要给一个worker发送多条消息。在处理并确认前一条消息之前,不要向worker发送新消息。相反,它会将其发送给下一个不忙的worker。

int prefetchCount = 1;
channel.basicQos(prefetchCount);

示例

public class WorkProvider {private static final String TASK_QUEUE_NAME = "work_queue";public static void main(String[] argv) throws Exception {Connection connection = RabbitMQUtil.getConnection();try (Channel channel = connection.createChannel()) {channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);for (int i = 0; i < 8; i++) {String message = String.valueOf(i);channel.basicPublish("", TASK_QUEUE_NAME,MessageProperties.PERSISTENT_TEXT_PLAIN,message.getBytes(StandardCharsets.UTF_8));System.out.println(" 消息发送 :'" + i + "'");}}}
}
public class WorkerConsumer1 {private static final String TASK_QUEUE_NAME = "work_queue";public static void main(String[] argv) throws Exception {final Connection connection = RabbitMQUtil.getConnection();final Channel channel = connection.createChannel();channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);System.out.println(" 消息监听中。。。。。。");//控制ack流速,表示每次进行ack确认前只会处理一条消息//channel.basicQos(1);DeliverCallback deliverCallback = (consumerTag, delivery) -> {//获取消息String message = new String(delivery.getBody(), StandardCharsets.UTF_8);System.out.println("worker1 消息消费:'" + message + "'");try {doWork(message);} finally {System.out.println(" 执行结束。。");//消息确认,根据消息序号(false只确认当前一个消息收到,true确认所有比当前序号小的消息(成功消费,消息从队列中删除 ))channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);}};//设置自动应答channel.basicConsume(TASK_QUEUE_NAME, false, deliverCallback, consumerTag -> { });}}

消费者1的方法处理

  private static void doWork(String task) {try {Thread.sleep(1000);} catch (InterruptedException ignored) {Thread.currentThread().interrupt();}}

消费者2的方法处理

  private static void doWork(String task) {return;}

启动两个worker消费者,执行结果如下(轮询):

在这里插入图片描述
在这里插入图片描述

若设置公平调度

channel.basicQos(1);

测试结果:

在这里插入图片描述
在这里插入图片描述

5.发布/订阅模式(fanout)

  • 不同于工作队列,同一消息在所有消费者共享,但只能有一个消费者消费,而发布订阅则会将同一消息发送给多个消费者,则将消息广播给所有订阅者

  • 在之前的模式中,都是直接将消息发送给队列,然后从队列消费,事实上之前使用了一个默认的交换机,即“”空字符串的

  • RabbitMQ消息传递模型的核心思想是生产者从不直接向队列发送任何消息。实际上,很多时候,生产者甚至根本不知道消息是否会被传递到任何队列。

  • 相反,生产者只能向exchange发送消息。exchange是一件非常简单的事情。它一方面接收来自生产者的消息,另一方面将它们推送到队列。exchange必须确切地知道如何处理它收到的消息。

在这里插入图片描述

将消息生产投递到exchange,由交换机去投递消息到队列

交换机

有几种exchange类型可供选择:directtopicheadersfanout。我们将专注于最后一个fanout

//创建交换机名称为logs
channel.exchangeDeclare("logs", "fanout");/*** exchange:交换机的名称* type:交换机的类型* durable 队列是否持久化* autoDelete:是否自动删除,(当该交换机上绑定的最后一个队列解除绑定后,该交换机自动删除)* internal:是否是内置的,true表示内置交换器。(则无法直接发消息给内置交换机,只能通过其他交换机路由到该交换机)* argument:其他一些参数*/channel.exchangeDeclare(EXCHANGE_NAME,"fanout",false,false,false,null);

第一个参数是exchange的名称。空字符串表示默认或未命名的交换:消息将被路由到routingKey指定名称的队列(如果存在)。

channel.basicPublish( "logs", "", null, message.getBytes());

绑定

我们已经创建了一个fanout交换机和一个队列。现在我们需要告诉exchange向我们的队列发送消息。交换和队列之间的关系称为绑定。

交换机会向绑定的队列通过路由key将消息路由到指定的队列中,fanout分发不需要路由key

在这里插入图片描述

//其中,第一个参数为绑定的队列,第二个参数为绑定的交换机,第三个参数为路由key
channel.queueBind(queueName, "logs", "");
#列出所有得绑定
rabbitmqctl list_bindings

示例代码

public class FanoutProvider {//声明交换机public static final String EXCHANGE_NAME="fanoutTest";//声明队列public static final String QUEUE_NAME1="queue_name1";public static final String QUEUE_NAME2="queue_name2";public static void main(String[] argv) throws Exception {Connection connection = RabbitMQUtil.getConnection();try (Channel channel = connection.createChannel()) {//声明交换机channel.exchangeDeclare(EXCHANGE_NAME,"fanout",false,false,false,null);//声明队列channel.queueDeclare(QUEUE_NAME1,false,false,false,null);channel.queueDeclare(QUEUE_NAME2,false,false,false,null);//进行队列绑定channel.queueBind(QUEUE_NAME1,EXCHANGE_NAME,"");channel.queueBind(QUEUE_NAME2,EXCHANGE_NAME,"");String message = "fanout模式消息推送。。。。。";//消息推送//参数说明:交换机,路由key/队列,消息属性,消息体channel.basicPublish(EXCHANGE_NAME, "", MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes(StandardCharsets.UTF_8));System.out.println(" 消息发送 :'" +message + "'");}}}
public class FanoutConsumer1 {public static final String EXCHANGE_NAME="fanoutTest";public static final String QUEUE_NAME1="queue_name1";public static void main(String[] argv) throws Exception {Connection connection = RabbitMQUtil.getConnection();//创建信道Channel channel = connection.createChannel();//声明交换机channel.exchangeDeclare(EXCHANGE_NAME, "fanout");//绑定队列channel.queueBind(QUEUE_NAME1, EXCHANGE_NAME, "");DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), StandardCharsets.UTF_8);System.out.println(" fanout 消费者1:'" + message + "'");};channel.basicConsume(QUEUE_NAME1, true, deliverCallback, consumerTag -> {});}}
public class FanoutConsumer2 {public static final String EXCHANGE_NAME="fanoutTest";public static final String QUEUE_NAME2="queue_name2";public static void main(String[] argv) throws Exception {Connection connection = RabbitMQUtil.getConnection();//创建信道Channel channel = connection.createChannel();//声明交换机channel.exchangeDeclare(EXCHANGE_NAME, "fanout");//绑定队列channel.queueBind(QUEUE_NAME2, EXCHANGE_NAME, "");DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), StandardCharsets.UTF_8);System.out.println(" fanout 消费者2:'" + message + "'");};channel.basicConsume(QUEUE_NAME2, true, deliverCallback, consumerTag -> { });}}

6.路由模式(direct)

由交换机通过路由key绑定key进行消息推送,也可以将同一个路由key绑定到多个队列或所有队列,此时相当于fanout

如果推送消息的路由key不存在,则该消息会丢弃

public class DirectProvider {public static final String EXCHANGE_NAME="direct-exchange";public static final String QUEUE_NAME1="direct-queue";public static final String ROUTING_KEY="change:direct";public static void main(String[] argv) throws Exception {Connection connection = RabbitMQUtil.getConnection();try (Channel channel = connection.createChannel()) {//声明交换机channel.exchangeDeclare(EXCHANGE_NAME,"direct",false,false,false,null);//声明队列channel.queueDeclare(QUEUE_NAME1,false,false,false,null);String message = "direct模式消息推送。。。。。";//参数说明:交换机,路由key/队列,消息属性,消息体channel.basicPublish(EXCHANGE_NAME, ROUTING_KEY, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes(StandardCharsets.UTF_8));System.out.println(" 消息发送 :'" +message + "'");}}}
public class DirectConsumer {public static final String EXCHANGE_NAME="direct-exchange";public static final String QUEUE_NAME1="direct-queue";public static final String BINDING_KEY="change:direct";public static void main(String[] argv) throws Exception {Connection connection = RabbitMQUtil.getConnection();//创建信道Channel channel = connection.createChannel();//声明交换机channel.exchangeDeclare(EXCHANGE_NAME, "direct");//绑定队列channel.queueBind(QUEUE_NAME1, EXCHANGE_NAME, BINDING_KEY);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), StandardCharsets.UTF_8);System.out.println(" direct 消费者1:'" + message + "'");};channel.basicConsume(QUEUE_NAME1, true, deliverCallback, consumerTag -> { });}}

7.Topic匹配模式

  • 发送到主题交换的消息不能有任意的路由key,它必须是一个由点分隔的单词列表。单词可以是任何东西,但通常它们指定了与消息相关的一些特征。一些有效的路由key示例:stock.usd.nyse、nyse.vmw、quick.orange.rabbit。路由密钥中可以有任意多的单词,最多255个字节。
  • 绑定key也必须采用相同的形式。topic交换机背后的逻辑类似于direct交换机,使用特定路由key发送的消息将被传递到所有使用绑定key绑定的所有队列。但是,绑定密钥有两个重要的特殊情况:
  • *(星号)只能代替一个单词
  • #(hash)可以替代零个或多个单词
public class TopicProvider {public static final String EXCHANGE_NAME="topic-exchange";public static final String QUEUE_NAME1="topic-queue";public static final String ROUTING_KEY="com.orange.test";public static final String ROUTING_KEY2="com.orange.test.aaa";public static void main(String[] argv) throws Exception {Connection connection = RabbitMQUtil.getConnection();try (Channel channel = connection.createChannel()) {//声明交换机channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC,false,false,false,null);//声明队列channel.queueDeclare(QUEUE_NAME1,false,false,false,null);String message1 = "topic test模式消息推送。。。。。";String message2 = "topic test.aaa模式消息推送。。。。。";//参数说明:交换机,路由key/队列,消息属性,消息体channel.basicPublish(EXCHANGE_NAME, ROUTING_KEY, MessageProperties.PERSISTENT_TEXT_PLAIN, message1.getBytes(StandardCharsets.UTF_8));channel.basicPublish(EXCHANGE_NAME, ROUTING_KEY2, MessageProperties.PERSISTENT_TEXT_PLAIN, message2.getBytes(StandardCharsets.UTF_8));System.out.println(" 消息发送 :'" +message1 + "'");System.out.println(" 消息发送 :'" +message2 + "'");}}}
public class TopicConsumer {public static final String EXCHANGE_NAME="topic-exchange";public static final String QUEUE_NAME1="topic-queue";public static final String BINDING_KEY="*.orange.#";public static void main(String[] argv) throws Exception {Connection connection = RabbitMQUtil.getConnection();//创建信道Channel channel = connection.createChannel();//声明交换机channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC);//绑定队列channel.queueBind(QUEUE_NAME1, EXCHANGE_NAME, BINDING_KEY);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), StandardCharsets.UTF_8);System.out.println(" topic 消费者1:'" + message + "'");};channel.basicConsume(QUEUE_NAME1, true, deliverCallback, consumerTag -> { });}}

相关文章:

002 JavaClent操作RabbitMQ

Java Client操作RabbitMQ 文章目录 Java Client操作RabbitMQ1.pom依赖2.连接工具类3.简单模式4.工作队列模式&#xff08;work&#xff09;公平调度示例 5.发布/订阅模式&#xff08;fanout&#xff09;交换机绑定示例代码 6.路由模式&#xff08;direct&#xff09;7.Topic匹配…...

lablelme标注的数据转成YOLO v8 格式

1 labelme 转 yolov8 格式 import json import cv2 import numpy as np import os def json2yolo(path):# dic{N_shaoxi:0, N_qiaoqi:1, N_qiaojie:2, N_pianyi:3, N_yiwu: 4, \# NV_shaoxi: 5, NV_qiaoqi: 6, NV_qiaojie: 7, NV_pianyi: 8, NV_yiwu: 9,\# …...

【linux】cat 命令

cat 命令是 Linux 和 Unix 系统中非常基础且常用的一个命令&#xff0c;它的全称是 "concatenate" 的缩写&#xff0c;意为“连接”或“串联”。尽管名字听起来像是专门用于连接文件的&#xff0c;但 cat 命令的用途远不止于此。它主要用于查看、创建、合并文件内容&…...

速通sass基础语法

速通Sass语法&#xff1a; sass的特点&#xff1a; 由于css的缺陷&#xff1a;无法自定义变量&#xff0c;不可引用&#xff0c;嵌套等。sass/scss/less等css预处理器产生。以sass为例&#xff0c;引入了变量、嵌套、运算、混入(Mixin)、继承、颜色处理、函数等诸多功能。方便…...

Vue: watch5种监听情况

目录 一.watch的性质与作用 1.watch 的性质包括&#xff1a; 2.watch 常用于以下场景&#xff1a; 二.监视ref定义的基本类型数据 三.监视ref定义的对象类型数据 四.监视reactive定义的对象类型数据 五.监视ref或reactive定义的对象类型数据中的某个属性 六.监视上述的…...

Android 车联网——汽车系统介绍(附2)

汽车系统指的是由多个模块或组件组成的系统,如发动机系统、制动系统、空调系统等,这些系统通常由多个 ECU 协同工作来完成特定的任务。 一、汽车系统 1、防抱死制动系统 ABS(Anti-lock Braking System,防抱死制动系统)是一项重要的汽车安全技术,其主要功能是在车辆紧急…...

C++ 链表

基本用法 C++提供了list容器,这是一个双向链表,能高效进行数据添加和删除。 引入头文件 #include <iostream> #include <list> // 引入list头文件 using namespace std;创建和初始化 list...

中国初创公司数量下降了98%

近年来&#xff0c;中国风险投资市场的风云变幻&#xff0c;通过IT Juzi&#xff08;IT桔子&#xff09;等权威数据服务提供商的透镜&#xff0c;得以清晰展现。数据显示&#xff0c;自2018年的鼎盛时期——拥有51,302家初创公司以来&#xff0c;这一数字在短短五年内急剧下降至…...

【SSRF漏洞】——http协议常见绕过

改变的确很难&#xff0c;但结果值得冒险 本文如有错误之处&#xff0c;还请各位师傅指正 一.ssrf概述 SSRF全称为Server-side Request Fogery,中文含义服务器端请求伪造 SSRF是一种由攻击者构造形成由目标服务端发起请求的一个安全漏洞。一般情况下&#xff0c;SSRF攻击的目标…...

[网络][CISCO]CISCO_华为网络设备端口镜像配置

CISCO 华为网络设备端口镜像配置大全 isco交换机通常支持2组镜像&#xff0c;4000系列有支持6组镜象的。支持所全端口镜像。 Cisco catylist2820 有2个菜单选项 先进入menu选项&#xff0c;enable port monitor 进入cli模式&#xff0c; en conf term interface fast0/…...

第二十五章 添加数字签名

文章目录 第二十五章 添加数字签名数字签名概述添加数字签名 第二十五章 添加数字签名 本主题介绍如何向 IRIS Web 服务和 Web 客户端发送的 SOAP 消息添加数字签名。 通常&#xff0c;会同时执行加密和签名。为简单起见&#xff0c;本主题仅介绍签名。有关结合加密和签名的信…...

GHOST重装后DEF盘数据救援指南

一、现象解析&#xff1a;GHOST重装后的DEF盘失踪之谜 在计算机维护的日常中&#xff0c;GHOST重装因其快速便捷的特点&#xff0c;成为众多用户解决系统问题的首选方法。然而&#xff0c;这一操作虽能迅速恢复系统至初始状态&#xff0c;却也暗藏风险&#xff0c;尤其是当不慎…...

使用blender快速制作metahuman面部以及身体绑定教程

【metablriger教程】使用blender一键绑定自定义角色metahuman绑定并导入UE5引擎教程_哔哩哔哩_bilibili 目前市面上的制作metahuman绑定的工具大多是maya的&#xff0c;metablriger是一个帮助用户快速制作metahuman绑定的blender插件&#xff0c;可以平替市面上已有的metahuma…...

OpenHarmony鸿蒙( Beta5.0)智能窗户通风设备开发详解

鸿蒙开发往期必看&#xff1a; 一分钟了解”纯血版&#xff01;鸿蒙HarmonyOS Next应用开发&#xff01; “非常详细的” 鸿蒙HarmonyOS Next应用开发学习路线&#xff01;&#xff08;从零基础入门到精通&#xff09; “一杯冰美式的时间” 了解鸿蒙HarmonyOS Next应用开发路…...

pandas 将多条记录整合成一条记录,每条记录的year和month字段组成新的字段名

你可以使用 Pandas 的 pivot_table() 或 groupby() 方法&#xff0c;将多条记录整合成一条&#xff0c;并通过 year 和 month 这两个字段生成新的字段名。具体的实现方法是通过 pivot_table() 将 year 和 month 作为列标签&#xff0c;将其他列中的数据进行整合。 假设你的数据…...

C# 中的多线程同步:原子变量、原子操作、内存顺序和可见性

C# 中的多线程同步&#xff1a;原子变量、原子操作、内存顺序和可见性 引言 随着现代计算机系统的发展&#xff0c;多核处理器已经变得非常普遍。在这种环境下&#xff0c;多线程编程成为提高应用程序性能的关键技术之一。然而&#xff0c;多线程编程带来了新的挑战&#xff…...

视图(mysql)

一、什么是视图 视图是⼀个虚拟的表&#xff0c;它是基于⼀个或多个基本表或其他视图的查询结果集。视图本⾝不存储数 据&#xff0c;⽽是通过执⾏查询来动态⽣成数据。⽤⼾可以像操作普通表⼀样使⽤视图进⾏查询、更新和管 理。视图本⾝并不占⽤物理存储空间&#xff0c;它仅…...

elementui组件el-upload实现批量文件上传

el-upload组件上传文件时&#xff0c;每传一个文件会调一次接口&#xff0c;所以当上传多个文件的时候&#xff0c;有 n 个文件就要调 n 次接口。 刚好之前工作中遇到使用el-upload组件批量上传文件的需求&#xff0c;来看看怎么实现。 思路&#xff1a; 1.取消组件的自动上…...

【JAVA入门】Day45 - 压缩流 / 解压缩流

【JAVA入门】Day45 - 压缩流 / 解压缩流 文章目录 【JAVA入门】Day45 - 压缩流 / 解压缩流一、解压缩流二、压缩流 在文件传输过程中&#xff0c;文件体积比较大&#xff0c;传输较慢&#xff0c;因此我们发明了一种方法&#xff0c;把文件里的数据压缩到一种压缩文件中&#x…...

Qt_自定义信号

目录 1、自定义信号的规定 2、创建自定义信号 3、带参数的信号与槽 4、一个信号连接多个槽 5、信号与槽的断开 结语 前言&#xff1a; 虽然Qt已经内置了大量的信号&#xff0c;并且这些信号能够满足大部分的开发场景&#xff0c;但是Qt仍然允许开发者自定义信号&#…...

【运维方案】某系统运维需求方案参考(doc全原件2024)

系统运维需求方案 1服务目标 2服务人力需求、服务资源需求 3信息资产统计服务需求 4业务应用软件服务需求 5网络、安全系统运维服务需求 6主机、存储系统运维服务需求 7数据库系统运维服务需求 8终端运维服务需求 9综合布线系统服务需求 10大屏幕显示系统的维护需求 11视频会议…...

Linux环境使用Git同步教程

&#x1f4d6; 前言&#xff1a;由于CentOS 7已于2024年06月30日停止维护&#xff0c;为了避免操作系统停止维护带来的影响&#xff0c;我们将把系统更换为Ubuntu并迁移数据&#xff0c;在此之前简要的学习Git的上传下载操作。 目录 &#x1f552; 1. 连接&#x1f558; 1.1 配…...

c++临时对象导致的生命周期问题

对象的生命周期是c中非常重要的概念&#xff0c;它直接决定了你的程序是否正确以及是否存在安全问题。 今天要说的临时变量导致的生命周期问题是非常常见的&#xff0c;很多时候没有一定经验甚至没法识别出来。光是我自己写、review、回答别人的问题就犯了或者看到了许许多多这…...

CSP-J 算法基础 深度优先搜索

文章目录 前言深度优先搜索通俗解释例子深度优先搜索的步骤DFS 的特点生活中的类比 为什么递归问题会变成深度优先搜索&#xff1f;递归与深度优先搜索的关系&#xff1a;递归与系统栈递归调用的过程&#xff1a;栈的作用&#xff1a; 递归与系统栈的简单示例递归实现 DFS 的简…...

LeetCode题练习与总结:基本计算器 Ⅱ--227

一、题目描述 给你一个字符串表达式 s &#xff0c;请你实现一个基本计算器来计算并返回它的值。 整数除法仅保留整数部分。 你可以假设给定的表达式总是有效的。所有中间结果将在 [-2^31, 2^31 - 1] 的范围内。 注意&#xff1a;不允许使用任何将字符串作为数学表达式计算…...

Elasticsearch基础(七):Logstash如何开启死信队列

文章目录 Logstash如何开启死信队列 一、确保 Elasticsearch 输出插件启用 DLQ 支持 二、配置 Logstash DLQ 设置 三、查看死信队列 四、排查 CSV 到 Elasticsearch 数据量不一致的问题 Logstash如何开启死信队列 在 Logstash 中&#xff0c;死信队列&#xff08;Dead Le…...

c语言--力扣简单题目(链表的中间节点)讲解

题目如下&#xff1a; 给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[3,4,5] 解释&#xff1a;链表只有一个中间结点…...

【STM32 Blue Pill编程】-定时器计数模式

定时器计数模式 文章目录 定时器计数模式1、定时器计数模式介绍2、硬件准备及接线3、模块配置3.1 定时器计数模式配置3.2 定时器中断配置3.3 串口配置4、代码实现在本文中,我们将讨论如何在计数器模式下配置 STM32 Blue Pill 定时器模块。 要将定时器用作计数器,我们将其配置…...

【例题】lanqiao1331 二进制中 1 的个数

二进制中 1 的个数 题目描述 给定一个整数 x&#xff0c;输出该数二进制表示中 1 的个数。 例&#xff1a;9 的二进制表示为 1001&#xff0c;有 2 位是 1 &#xff0c;所以函数返回 2。 输入描述 输入 x​ &#xff08;内存空间为 32 位的整数&#xff09;。 输出描述 第一…...

【论文解读】图像序列识别:CRNN技术在场景文本识别中的应用与突破(附论文地址)

论文地址&#xff1a;https://arxiv.org/pdf/1507.05717 这篇文章的标题是《An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application to Scene Text Recognition》&#xff0c;作者是Baoguang Shi, Xiang Bai和Cong Yao&#xff0c…...