RabbitMQ入门教程(精细版二带图)

news2024/11/22 13:53:44

目录

六 RabbitMQ工作模式

6.1Hello World简单模式

6.1.1 什么是简单模式

6.1.2 RabbitMQ管理界面操作

6.1.3 生产者代码

6.1.4 消费者代码

6.2 Work queues工作队列模式

6.2.1 什么是工作队列模式

6.2.2 RabbitMQ管理界面操作

6.2.3 生产者代码

6.2.4 消费者代码

6.3 三种模式概览

6.4 Publish/Subscribe发布与订阅模式

6.4.1 什么是发布订阅模式

6.4.2 RabbitMQ管理界面操作

6.4.3 生产者代码

6.4.4 消费者代码

6.5 Routing路由模式

6.5.1 什么是路由模式

6.5.2 RabbitMQ管理界面操作

6.5.3 生产者代码

6.5.4 消费者代码

6.6 Topics通配符模式(主题模式)

6.6.1 什么是通配符(主题)模式

6.6.2 RabbitMQ管理界面操作

6.6.3 生产者代码

6.6.4 消费者代码

6.7 模式总结RabbitMQ

6.8 使用代码创建队列和交换机

6.8.1 初始化exchange、queue

6.8.2 发布消息到RabbitMQ

6.8.3 创建消费者监听消息


官方文档  RabbitMQ Documentation | RabbitMQ

 MQ全称为Message Queue,消息队列是应用程序和应用程序之间的通信方法。

RabbitMQ是一个Erlang开发的AMQP(高级消息排队 协议)(英文全称:Advanced Message Queuing Protocol )的开源实现。-------------接上章 

六 RabbitMQ工作模式

6.1Hello World简单模式

6.1.1 什么是简单模式

在上图的模型中,有以下概念:

P:生产者: 也就是要发送消息的程序

C:消费者:消息的接受者,会一直等待消息到来。

queue:消息队列,图中红色部分。类似一个邮箱,可以缓存消息;生产者向其中投递消息,消费者从其中取出消息。

6.1.2 RabbitMQ管理界面操作
  • 创建simple_queue队列用于演示Hello World简单模式

6.1.3 生产者代码
  • rabbitmq_producer项目测试代码如下:

package com.tingyi.test;
​
import com.tingyi.rabbitmq.ProducerApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
​
/**
 * @author 听忆
 */
@SpringBootTest(classes = ProducerApplication.class)
@RunWith(SpringRunner.class)
public class TestSimple {
    @Autowired
    private RabbitTemplate rabbitTemplate;
​
    @Test
    public void testSimpleSend() {
        rabbitTemplate.convertAndSend("simple_queue", "你好哇, 听忆!");
    }
}

6.1.4 消费者代码
  • rabbitmq_consumer项目创建监听器:

@Component
@RabbitListener(queues = "simple_queue")
public class SimpleListen {
​
    @RabbitHandler
    public void onMessage(String message){
        System.out.println(message);
    }
}

然后启动ConsumerApplication.java, 就可以接收到RabbitMQ服务器发送来的消息

6.2 Work queues工作队列模式

6.2.1 什么是工作队列模式

Work Queues与入门程序的简单模式相比,多了一个或一些消费端,多个消费端共同消费同一个队列中的消息。应用场景:对于任务过重或任务较多情况使用工作队列可以提高任务处理的速度。

在一个队列中如果有多个消费者,那么消费者之间对于同一个消息的关系是竞争的关系。

6.2.2 RabbitMQ管理界面操作
  • 创建 work_queue 队列用于演示work工作队列模式

6.2.3 生产者代码

rabbitmq_producer项目测试代码如下:

package com.qf.test;
​
import com.tingyi.rabbitmq.ProducerApplication;
import org.junit.Test;99
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
​
/**
 * @author 听忆
 */
@SpringBootTest(classes = ProducerApplication.class)
@RunWith(SpringRunner.class)
public class TestWork {
    @Autowired
    private RabbitTemplate rabbitTemplate;
​
    @Test
    public void testWorkSend() {
        for (int i = 0; i < 1000; i++){
            rabbitTemplate.convertAndSend("work_queue", "你好哇, 听忆" + i);
        }
​
    }
}

6.2.4 消费者代码
  • rabbitmq_consumer项目创建监听器1:

package com.tingyi.rabbitmq.work;
​
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
​
/**
 * @author 听忆
 */
@Component
@RabbitListener(queues = "work_queue")
public class WorkListener1 {
    @RabbitHandler
    public void testListener(String message) {
        System.out.println("======WorkListener1接收到的消息为:======" + message);
    }
}
  • rabbitmq_consumer项目创建监听器2:

package com.tingyi.rabbitmq.work;
​
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
​
/**
 * @author 听忆
 */
@Component
@RabbitListener(queues = "work_queue")
public class WorkListener2 {
    @RabbitHandler
    public void testListener(String message) {
        System.out.println("======WorkListener2接收到的消息为:======" + message);
    }
}

6.3 三种模式概览

前面2个案例中,只有3个角色:

  • P:生产者,也就是要发送消息的程序

  • C:消费者:消息的接受者,会一直等待消息到 来。

  • queue:消息队列,图中红色部分

而在订阅模型中,多了一个exchange角色,而且过程略有变化:

  • P:生产者,也就是要发送消息的程序,但是不再发送到队列中,而是发给X(交换机)

  • C:消费者,消息的接受者,会一直等待消息到来。

  • Queue:消息队列,接收消息、缓存消息。

  • Exchange:交换机,图中的X。一方面,接收生产者发送的消息。另一方面,知道如何处理消息,例如递交给某个特别队列、递交给所有队列、或是将消息丢弃。到底如何操作,取决于Exchange的类型。

Exchange有常见以下3种类型:

  • Fanout:广播 将消息交给所有绑定到交换机的队列, 不处理路由键。只需要简单的将队列绑定到交换机上。fanout 类型交换机转发消息是最快的。

    • Direct:定向 把消息交给符合指定routing key 的队列. 处理路由键。需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。如果一个队列绑定到该交换机上要求路由键 “dog”,则只有被标记为 “dog” 的消息才被转发,不会转发 dog.puppy,也不会转发 dog.guard,只会转发dog。

    其中,路由模式使用的是 direct 类型的交换机。

    • Topic:主题(通配符) 把消息交给符合routing pattern(路由模式)的队列. 将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号 # 匹配一个或多个词,符号*匹配不多不少一个词。因此“audit.#” 能够匹配到“audit.irs.corporate”,但是“audit.*” 只会匹配到 “audit.irs”。

    其中,主题模式(通配符模式)使用的是 topic 类型的交换机。

Exchange(交换机)只负责转发消息,不具备存储消息的能力,因此如果没有任何队列与Exchange绑定,或者没有符合路由规则的队列,那么消息会丢失

6.4 Publish/Subscribe发布与订阅模式

6.4.1 什么是发布订阅模式

发布订阅模式:

​ 1、每个消费者监听自己的队列。

​ 2、生产者将消息发给broker,由交换机将消息转发到绑定此交换机的每个队列,每个绑定交换机的队列都将接收到消息

6.4.2 RabbitMQ管理界面操作
  • 创建两个队列 ps_queue1ps_queue2

  • 创建Exchange交换器 fanout_exchange

  • 将创建的fanout_exchange交换器和 ps_queue1 , ps_queue2 队列绑定

6.4.3 生产者代码
  • rabbitmq_producer项目测试代码如下:

package com.tingyi.test;
​
import com.tingyi.rabbitmq.ProducerApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
​
/**
 * @author 听忆
 */
@SpringBootTest(classes = ProducerApplication.class)
@RunWith(SpringRunner.class)
public class TestPubAndSub {
    @Autowired
    private RabbitTemplate rabbitTemplate;
​
    @Test
    public void testPubAndSubSend() {
        for(int i = 1; i < 100; i++) {
            rabbitTemplate.convertAndSend("fanout_exchange","" , "你好哇,2024听忆 " + i);
        }
    }
}

6.4.4 消费者代码
  • rabbitmq_consumer项目创建监听器:

package com.tingyi.rabbitmq.ps;
​
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
​
/**
 * @author 听忆
 */
@Component
@RabbitListener(queues = "ps_queue1")
public class TestListener1 {
    @RabbitHandler
    public void testListener(String message) {
        System.out.println("======ps_queue1接收到的消息为:======" + message);
    }
}
  • rabbitmq_consumer项目创建监听器:

package com.tingyi.rabbitmq.ps;
​
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
​
/**
 * @author 听忆
 */
@Component
@RabbitListener(queues = "ps_queue2")
public class TestListener2 {
    @RabbitHandler
    public void testListener(String message) {
        System.out.println("======ps_queue2接收到的消息为:======" + message);
    }
}

6.5 Routing路由模式

6.5.1 什么是路由模式

路由模式特点:队列与交换机的绑定,不能是任意绑定了,而是要指定一个RoutingKey(路由key)消息的发送方在向 Exchange发送消息时,也必须指定消息的RoutingKey。Exchange不再把消息交给每一个绑定的队列,而是根据消息的Routing Key进行判断,只有队列的Routingkey与消息的Routing key完全一致,才会接收到消息.

图解:

P:生产者,向Exchange发送消息,发送消息时,会指定一个routing key。

X:Exchange(交换机),接收生产者的消息,然后把消息递交给与routing key完全匹配的队列

C1:消费者,其所在队列指定了需要routing key 为 error 的消息

C2:消费者,其所在队列指定了需要routing key 为 info、error、warning 的消息

6.5.2 RabbitMQ管理界面操作
  • 创建两个队列分别叫做 direct_queue_insertdirect_queue_update 用户演示

  • 创建交换器 direct_exchange , 类型为 direct , 用于演示路由模式

  • 设置绑定: 将创建的交换器 direct_exchangedirect_queue_insert , direct_queue_update 绑定在一起, 路由键Routing Key分别为 insertKeyupdateKey

6.5.3 生产者代码
  • rabbitmq_producer项目测试代码如下:

package com.tingyi.test;
​
import com.tingyi.rabbitmq.ProducerApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
​
/**
 * @author 听忆
 */
@SpringBootTest(classes = ProducerApplication.class)
@RunWith(SpringRunner.class)
public class TestRouting {
    @Autowired
    private RabbitTemplate rabbitTemplate;
​
    @Test
    public void testPubAndSubSend() {
        for(int i = 1; i < 100; i++) {
            if (i % 2 == 0) {
                rabbitTemplate.convertAndSend("direct_exchange","insert_key" , "你好, 2024听忆" + i);
            } else {
                rabbitTemplate.convertAndSend("direct_exchange","update_key" , "你好, 小崔" + i);
            }
        }
    }
}

6.5.4 消费者代码
  • rabbitmq_consumer项目创建监听器:

package com.tingyi.rabbitmq.routing;
​
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
​
/**
 * @author 听忆
 */
@Component
@RabbitListener(queues = "direct_queue_insert")
public class TestInsertListener {
    @RabbitHandler
    public void testListener(String message) {
        System.out.println("======test1_queue接收到的消息为:======" + message);
    }
}
  • rabbitmq_consumer项目创建监听器:

package com.tingyi.rabbitmq.routing;
​
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
​
/**
 * @author 听忆
 */
@Component
@RabbitListener(queues = "direct_queue_update")
public class TestUpdateListener {
    @RabbitHandler
    public void testListener(String message) {
        System.out.println("======test2_queue接收到的消息为:======" + message);
    }
}

6.6 Topics通配符模式(主题模式)

6.6.1 什么是通配符(主题)模式

Topic类型与Direct相比,都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routing key的时候使用通配符!

Routingkey: 一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如:item.insert

通配符规则:

#:匹配一个或多个

*:匹配不多不少恰好1个词

举例:

item.#: 能够匹配item.insert.abc或者item.insert

item.*:只能匹配item.insert item.update

图解:

  • 红色Queue:绑定的是usa.#,因此凡是以usa.开头的routing key都会被匹配到

  • 黄色Queue:绑定的是#.news,因此凡是以.news结尾的routing key都会被匹配

6.6.2 RabbitMQ管理界面操作
  • 创建队列 topic_queue1topic_queue1

  • 创建交换器 topic_exchange , type类型为 topic

  • 设置绑定:

    topic_queue1绑定的Routing Key路由键为item.*

    topic_queue2绑定的Routing Key路由键为item.#

6.6.3 生产者代码
  • rabbitmq_producer项目测试代码如下:

package com.tingyi.test;
​
import com.tingyi.rabbitmq.ProducerApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
​
/**
 * @author 听忆
 */
@SpringBootTest(classes = ProducerApplication.class)
@RunWith(SpringRunner.class)
public class TestTopic {
    @Autowired
    private RabbitTemplate rabbitTemplate;
​
    @Test
    public void testTopicSend() {
        rabbitTemplate.convertAndSend("topic_exchange","item.select" , "你好, 2024听忆");
        rabbitTemplate.convertAndSend("topic_exchange","item.select.abc" , "你好, 2024小崔");
    }
}

6.6.4 消费者代码
  • rabbitmq_consumer项目创建监听器:

package com.tingyi.rabbitmq.topic;
​
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
​
/**
 * @author 听忆
 */
@Component
@RabbitListener(queues = "topic_queue1")
public class TestTopicListener1 {
    @RabbitHandler
    public void testListener(String message) {
        System.out.println("======topic_queue1接收到的消息为:======" + message);
    }
}
  • rabbitmq_consumer项目创建监听器:

package com.tingyi.rabbitmq.topic;
​
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
​
/**
 * @author 听忆
 */
@Component
@RabbitListener(queues = "topic_queue2")
public class TestTopicListener2 {
    @RabbitHandler
    public void testListener(String message) {
        System.out.println("======topic_queue2接收到的消息为:======" + message);
    }
}

6.7 模式总结RabbitMQ

工作模式:

1、简单模式 HelloWorld : 一个生产者、一个消费者,不需要设置交换机(使用默认的交换机)

2、工作队列模式 Work Queue: 一个生产者、多个消费者(竞争关系),不需要设置交换机(使用默认的交换机)

3、发布订阅模式 Publish/subscribe: 需要设置类型为fanout的交换机,并且交换机和队列进行绑定,当发送消息到交换机后,交换机会将消息发送到绑定的队列

4、路由模式 Routing: 需要设置类型为direct的交换机,交换机和队列进行绑定,并且指定routing key,当发送消息到交换机后,交换机会根据routing key将消息发送到对应的队列

5、通配符模式 Topic: 需要设置类型为topic的交换机,交换机和队列进行绑定,并且指定通配符方式的routing key,当发送消息到交换机后,交换机会根据routing key将消息发送到对应的队列

6.8 使用代码创建队列和交换机

6.8.1 初始化exchange、queue
  • 下面初始化队列和交换器类放在消费方和生产方都可以.

package com.tingyi.rabbitmq.config;
​
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
​
/**
 * @author 听忆
 */
@Configuration
public class RabbitMQConfig {
​
    /**
     * 1. 创建exchange - topic
     * 第一个参数: 交换器名称
     * 第二个参数: 交换器是否持久化, 也就是服务器重启交换器是否自动删除
     * 第三个参数: 如果没有消费者, 交换器是否自动删除
     */
    @Bean
    public TopicExchange getTopicExchange(){
        return new TopicExchange("boot-topic-exchange",true,false);
    }
​
    /**
     * 2. 创建queue
     * 第一个参数: 队列名称
     * 第二个参数: 队列是否持久化, 也就是服务器重启队列是否自动删除
     * 第三个参数: 是否排外的,有两个作用,
     *          1.当连接关闭时该队列是否会自动删除;
     *          2.该队列是否是私有的private,如果不是排外的,
     *              可以使用两个消费者都访问同一个队列,没有任何问题,如果是排外的,
     *              会对当前队列加锁,其他通道channel是不能访问的
     * 第四个参数: 队列是否自动删除, 也就是当没有消费者时, 队列是否自动删除
     * 第五个参数: 队列参数, 比如是否设置为延时队列等参数.
     */
    @Bean
    public Queue getQueue(){
        return new Queue("boot-queue",true,false,false,null);
    }
​
    /**
     * 3. 队列和交换器绑定在一起
     */
    @Bean
    public Binding getBinding(TopicExchange topicExchange,Queue queue){
        return BindingBuilder.bind(queue).to(topicExchange).with("*.red.*");
    }
}
6.8.2 发布消息到RabbitMQ
@Autowired
private RabbitTemplate rabbitTemplate;
​
@Test
public void testContextLoads() {
    rabbitTemplate.convertAndSend("boot-topic-exchange","slow.red.dog","听忆哇!!");
}
6.8.3 创建消费者监听消息
package com.tingyi.rabbitmq.topic;
​
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
​
/**
 * @author 听忆
 */
@Component
public class Consumer {
​
    @RabbitListener(queues = "boot-queue")
    public void getMessage(Object message){
        System.out.println("接收到消息:" + message);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1893937.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

谷粒商城学习-06-使用vagrant快速创建linux虚拟机

这一节的内容是在Windows上安装虚拟机。 为什么要按照虚拟机呢&#xff1f; 原因是很多软件只能在Linux下运行&#xff0c;有的虽然也可以在Windows上运行&#xff0c;但从安装到运行会遇到很多问题&#xff0c;为这些解决这些问题花时间对于大多数人特别是初学者是没有什么价…

WPS操作技巧:制作可以打对勾的方框,只需简单几步!沈阳wps办公软件培训

日常工作中&#xff0c;我们经常需要在表格中添加复选框&#xff0c;比如【性别选择】、【任务完成状态】等等&#xff0c;通过打对勾来确定状态。今天就分别从WPS的Excel表格和Word文档2种场景&#xff0c;介绍制作可以打对勾的复选框的方法技巧&#xff0c;掌握技巧&#xff…

k8s-第十节-Ingress

Ingress 介绍 Ingress 为外部访问集群提供了一个 统一 入口,避免了对外暴露集群端口;功能类似 Nginx,可以根据域名、路径把请求转发到不同的 Service。可以配置 https跟 LoadBalancer 有什么区别? `LoadBalancer`` 需要对外暴露端口,不安全;无法根据域名、路径转发流量到…

Linux之文本三剑客

Linux之三剑客 Linux的三个命令,主要是用来处理文本,grep,sed,awk,处理日志的时候使用的非常多 1 grep 对文本的内容进行查找 1) 基础用法 语法 grep 选项 内容|正则表达式 文件选项: -i 不区分大小写 -v 排除,反选 -n 显示行号 -c 统计个数查看文件里包含有的内容 [roo…

rtsp地址 + 测试网站 + java(免环境、免插件、零编码转换http播放)

目录 1、创建rtsp网站 2、测试rtsp网站 3、Java实现rtsp播放 ①maven添加依赖 ②访问http地址即可展示视频内容 1、创建rtsp网站 填写邮箱即可获得两个可用的rtsp网站&#xff08;每月可免费用2G&#xff09;&#xff1a; https://rtsp.stream/ 2、测试rtsp网站 测试网络…

k8s kubectl top pod报错error Metrics API not available

文章目录 1、场景2、解决方法1、确认Metrics Server是否已经在集群中安装2、安装metric-server组件2.1、组件地址2.2、组件与K8S集群版本对应关系2.3、apply资源清单文件2.4、验证Metrics Server正常工作 1、场景 在使用kubectl top pod 命令时遇到了error: Metrics API not a…

人力资源中的人工智能:你应该知道的一切

人工智能已经成为行业讨论更广泛的突出话题。人力资源(HR)对于人力资源专业人士来说&#xff0c;了解这门课程也是如此。除了简要介绍什么是人工智能&#xff0c;以及你可能遇到的主要人工智能类型(或者你可能很快就会遇到它&#xff01;)此外&#xff0c;本文还将探讨人工智能…

工业智能网关在现代工业生产中的重要性-天拓四方

工业智能网关是一款具备挖掘工业设备数据并接入到自主开发的云平台的智能嵌入式网络设备。它具备数据采集、协议解析、边缘计算&#xff0c;以及4G/5G/WiFi数据传输等功能&#xff0c;并能接入工业云平台。这种网关不仅支持采集PLC、传感器、仪器仪表和各种控制器&#xff0c;还…

公用对象池

什么是对象池&#xff1f; 对象池顾名思义就是存放对象的池子&#xff0c;主要是为了重复利用对象。将不用的对象扔进池子里&#xff0c;需要用的时候再从池子中取出来。这样的一套机制我们称为对象池。 为什么用对象池&#xff1f; 其实从定义我们就可以看出来&#xff0c;…

基于矩阵分解算法的评分预测实现---信息检索课设以及所涉及的深度学习原理

一、实验环境 Windows,Python 3 Python作为主要编程语言,使用Python的Pandas、NumPy、Matplotlib等库 二、实验内容 主要任务 查阅相关资料,了解矩阵分解算法的基本概念、应用场景及其难点。重点了解SVD(Singular Value Decomposition,奇异值分解)系列方法。掌握Pyth…

2023年的Facebook营销:超级完整指南

Facebook营销不是可选的&#xff0c;是必须的。Facebook是世界上使用最多的社交平台&#xff0c;每天吸引22.9亿活跃用户。 它也不全是度假照片和虚张声势。对于53.2% 的 16-24 岁互联网用户&#xff0c;社交媒体是他们进行品牌研究的主要来源。而且&#xff0c;66% 的 Facebo…

红黑树插入删除流程(流程图)

红黑树插入删除流程&#xff08;流程图&#xff09; 红黑树性质 左根右(二叉树&#xff09;根叶黑&#xff08;根节点是黑色的&#xff09;不红红&#xff08;不存在相邻两个红色节点&#xff09;黑路同&#xff08;对于每个节点&#xff0c;从该节点出发到任一空叶节点所经过…

学会python——用python制作一个登录和注册窗口(python实例十八)

目录 1.认识Python 2.环境与工具 2.1 python环境 2.2 Visual Studio Code编译 3.登录和注册窗口 3.1 代码构思 3.2 代码实例 3.3 运行结果 4.总结 1.认识Python Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的可读…

tapd 与国内外主流的8大项目管理软件大对比

对比Tapd与8大项目管理工具&#xff1a;PingCode、Worktile、Redmine、Teambition、广联达、Jira、禅道、飞书。 Tapd 是腾讯推出的一款敏捷开发管理工具&#xff0c;特别适合那些需要高效协作和快速迭代的敏捷开发团队。它支持多种敏捷方法论&#xff0c;包括Scrum和Kanban&am…

二轴机器人装箱机:重塑物流效率,精准灵活,引领未来装箱新潮流

在现代化物流领域&#xff0c;高效、精准与灵活性无疑是各大企业追求的核心目标。而在这个日益追求自动化的时代&#xff0c;二轴机器人装箱机凭借其较佳的性能和出色的表现&#xff0c;正逐渐成为装箱作业的得力助手&#xff0c;引领着未来装箱新潮流。 一、高效&#xff1a;重…

字节码编程ASM之生成变量并sout

写在前面 本文看下如何通过asm生成变量并sout。 1&#xff1a;代码 直接看代码吧&#xff0c;注释很详细&#xff0c;有不懂的&#xff0c;留言告诉我&#xff1a; package com.dahuyuo.asmtest;import org.objectweb.asm.*; import org.objectweb.asm.commons.AdviceAdapt…

PE文件学习

一、介绍 PE文件&#xff0c;即Portable Executable文件&#xff0c;是一种标准的文件格式&#xff0c;主要用于微软的Windows操作系统上。这种格式被用来创建可执行程序&#xff08;如.exe文件&#xff09;、动态链接库&#xff08;.DLL文件&#xff09;、设备驱动&#xff0…

千万不要用国产BI,不然你会发现它性价比奇高——以奥威BI软件为例

在信息技术日新月异的今天&#xff0c;企业对于商业智能&#xff08;BI&#xff09;软件的选择往往陷入了一个误区&#xff1a;盲目追求国际品牌&#xff0c;却忽视了身边那些性价比极高的国产精品。如果你不慎踏入了“千万不要用国产BI”的陷阱&#xff0c;那么奥威BI软件将是…

豆包Marscode体验官,体验云编程和AI助手加持的快乐

我正在参加「豆包MarsCode初体验」征文活动&#xff0c;活动链接&#xff1a;https://juejin.cn/post/7384997062416252939?utm_sourcejuejin&utm_mediumpush&utm_campaigntiyanguan Marscode官网地址&#xff1a;工作台 - MarsCode 其实早在前不久&#xff0c;我就…

谷歌地图 | 路线优化 API 助力企业解锁物流新潜能

在当今竞争激烈的市场环境中&#xff0c;企业面临着越来越大的压力&#xff0c;需要提高运营效率、降低成本并满足不断增长的客户期望。对于依赖车队进行交付或服务的企业来说&#xff0c;这些挑战尤为艰巨。 近日&#xff0c; Google 地图平台路线优化 API 已经正式上线。路线…