3.RabbitMQ工作模式介绍

news2024/11/23 15:53:41

3.RabbitMQ工作模式介绍.md

文章目录

      • 3.RabbitMQ工作模式介绍.md
        • 1.简单模式
          • 1.1总结
        • 2.Work Queues 工作队列模式
          • 2.1 模式说明
          • 2.2 代码编写
          • 2.3 总结
        • 3.Pub/Sub 订阅模式
          • 3.1 模式说明
          • 3.2 使用场景
          • 3.3 代码实现
          • 3.4 总结:
        • 4.Routing 路由模式
          • 4.1 模式说明
          • 4.2 代码编写
          • 4.3 总结:
        • 5. Topics 通配符模式
          • 5.1 模式说明
        • 6、工作模式总结

RabbitMQ 提供了 6 种工作模式:简单模式、work queues、Publish/Subscribe 发布与订阅模式、 Routing 路由模式、Topics 主题模式、RPC 远程调用模式(远程调用,不太算 MQ;暂不作介绍)。 官网对应模式介绍:https://www.rabbitmq.com/getstarted.htm

在这里插入图片描述

1.简单模式

1.1案例实现

需求:使用简单模式完成消息传递

maven依赖如下

       <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
        </dependency>

生产者如下:

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 Producer {
    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        //设置主机信息
        connectionFactory.setHost("81.71.14.7");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("user");
        connectionFactory.setPassword("password");
        connectionFactory.setVirtualHost("/vhost");
        //获取TCP长连接
        Connection connection = connectionFactory.newConnection();
        //创建通信“通道” 相当于TCP的虚拟连接
        Channel channel = connection.createChannel();
        //创建队列,声明并创建一个队列,如果队列已存在,则使用这个队列
        //第一个参数:队列名称ID
        //第二个参数:是否持久化,false对应不持久化数据,MQ停掉数据就会丢失
        //第三个参数:是否队列私有化,false则代表所有消费者都可以访问,true代表只有第一次拥有它的消费者才能一直使用
        //第四个参数:是否自动删除,false 代表连接停掉后不自动删除这个队列
        //其他额外参数,null
        channel.queueDeclare("helloWord",false,false,false,null);
        String message = "你好RabbitMQ";
        //第一个参数 exchange 交换机,暂时不用,进行发布订阅的时候才用
        //第二个参数:队列名称
        //第三个参数:额外设置属性
        //第四个参数:消息字节数组
        channel.basicPublish("","helloWord",null,message.getBytes());
        channel.close();
        connection.close();
        System.out.println("===发送成功===");

    }
}

消费者如下:

import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Consumer {
    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        //设置主机信息
        connectionFactory.setHost("81.71.14.7");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("user");
        connectionFactory.setPassword("password");
        connectionFactory.setVirtualHost("/vhost");
        //获取TCP长连接
        Connection connection = connectionFactory.newConnection();
        //创建通信“通道” 相当于TCP的虚拟连接
        final Channel channel = connection.createChannel();
        //创建队列,声明并创建一个队列,如果队列已存在,则使用这个队列
        //第一个参数:队列名称ID
        //第二个参数:是否持久化,false对应不持久化数据,MQ停掉数据就会丢失
        //第三个参数:是否队列私有化,false则代表所有消费者都可以访问,true代表只有第一次拥有它的消费者才能一直使用
        //第四个参数:是否自动删除,false 代表连接停掉后不自动删除这个队列
        //其他额外参数,null
        channel.queueDeclare("helloWord",false,false,false,null);
        //第一个参数:队列名
        //第二个参数:参数代表是否自动确认收到消息,false 代表手动确认消息,是MQ推荐做法
        //第三个参数:传入DefaultConsumer 的实现类。
        channel.basicConsume("helloWord",false,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
               String message = new String (body);
                System.out.println("消费者接收到的消息:"+message);
                long tagId =  envelope.getDeliveryTag();
                //第二个参数:只确认签收当前消息,设置true 代表签收该消息者所有未签收的消息
                channel.basicAck(tagId,false);
            }
        });
    }
}
1.1总结

上面案例使用的是简单模式如下图

在这里插入图片描述

上图概念如下:

  • P:生产者,也就是要发送消息的程序
  • C:消费者,消息的接受者,会一直等待消息到来
  • Queue:消息队列,图中红色部分;类似一个邮箱,可以缓存消息,生产者向其中投递消息,消费者从其中取出消息。

2.Work Queues 工作队列模式

2.1 模式说明

在这里插入图片描述

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

Work Queues与简单模式的代码几乎是一样的。可以复制,并多复制一个消费者进行多个消费者同时对消息消费的测试。

连接工具类

import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class ConnectionUtil {
    public static Connection getConnection() throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        //设置主机信息
        connectionFactory.setHost("81.71.14.7");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("user");
        connectionFactory.setPassword("password");
        connectionFactory.setVirtualHost("/vhost");
        //获取TCP长连接
        return connectionFactory.newConnection();
    }
}

消息发生产类:

import com.google.gson.Gson;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import rabbitmq.ConnectionUtil;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class OrderSystem {
    public static void main(String[] args) throws IOException, TimeoutException {
        String queueStr = "sm";
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        channel.queueDeclare(queueStr,false,false,false,null);
        for(int i=0;i<100;i++){
            SMS sms = new SMS("乘客"+i,"15600000000","你的车票已经预定成功");
            String jsonSms = new Gson().toJson(sms);
            channel.basicPublish("",queueStr,null,jsonSms.getBytes());
        }
        System.out.println("====发送数据成功===");
        channel.close();
        connection.close();
    }
    // 短信封装类
    static class SMS{
        private String name;
        private String mobile;
        private String content;
        public SMS(String name,String mobile,String content){
            this.name = name;
            this.mobile = mobile;
            this.content = content;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getMobile() {
            return mobile;
        }

        public void setMobile(String mobile) {
            this.mobile = mobile;
        }

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }
    }
}

消息消费类:

import com.rabbitmq.client.*;
import rabbitmq.ConnectionUtil;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class SMSSender1 {
    public static void main(String[] args) throws IOException, TimeoutException {
        String queueStr = "sm";
        Connection connection = ConnectionUtil.getConnection();
        final Channel channel = connection.createChannel();
        channel.queueDeclare(queueStr,false,false,false,null);
        //如果不写basicQos(1) 则MQ自动将所有请求平均发送给所有的消费者
        //basicQos(1) ,MQ 不在对消费者一次发送多个请求,而是消费者处理完一个消息后(确认后),在从队列中获取一个新的
        channel.basicQos(1);//处理完一个取一个。
        channel.basicConsume(queueStr,false,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String jsonSMS = new String(body);
                System.out.println("SMSSender1===短信发送成功:"+jsonSMS);
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        });
    }
}
2.3 总结
  • 在一个队列中如果有多个消费者,那么消费者之间对于同一个消息的关系是竞争的关系。
  • Work Queue 对于任务过重或任务较多情况使用工作队列可以提高任务处理的速度。
  • 消费是注意channel.basicQos(1); 处理完一个取一个。

3.Pub/Sub 订阅模式

3.1 模式说明

在这里插入图片描述

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

  • P:生产者,也就是要发送消息的程序,但是不再发送到队列中,而是发给X(交换机)
  • C:消费者,消息的接收者,会一直等待消息到来 Queue:消息队列,接收消息、缓存消息
  • Exchange:交换机(X)。一方面,**接收生产者发送的消息。另一方面,知道如何处理消息,**例如递交给某个特别队列、递交给所有队列、或是将消息丢弃。到底如何操作,取决于Exchange的类型。Exchange有常见以下3种类型
    Fanout:广播,将消息交给所有绑定到交换机的队列
    Direct:定向,把消息交给符合指定routing key 的队列
    Topic:通配符,把消息交给符合routing pattern(路由模式)的队列

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

3.2 使用场景
  • 发布订阅模式因为所有的消费者获得相同的消息,所以特别适合“数据提供与应用”
  • 例如:天气推送、公众号订阅、微博/抖音/快手的关注等
3.3 代码实现

订阅模式和之前的Work Queues工作队列模式相比多了一个Exchange交换机的新的概念,之前生产者直接发送到队列,现在直接发送到交换机。消费者还是直接从队列中获取消息,但是需要消费者创建队列并且把队列和交换机绑定。

注意:代码中注释的地方,一般是之前没出现过的,或者使用新的参数了,Exchange是需要通过管理界面创建的类型为Fanout

生产者代码:

获取Connection工具类省略了。

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import rabbitmq.ConnectionUtil;

import java.util.Scanner;

public class WeatherBureau {
    public static void main(String[] args)  throws Exception{
        String exchangeStr = "exchange-weather";
        Connection connection = ConnectionUtil.getConnection();
        //从控制台输入发布内容
        String input = new Scanner(System.in).next();
        Channel channel = connection.createChannel();
        //第一个参数:交换机名字
        channel.basicPublish(exchangeStr,"",null,input.getBytes());
        channel.close();
        connection.close();
    }
}

消费者代码:

import com.rabbitmq.client.*;
import rabbitmq.ConnectionUtil;
import java.io.IOException;

public class BaiduConsumer {
    public static void main(String[] args) throws Exception {
        String exchangeStr = "exchange-weather";
        String baiduQueue = "baidu-queue";
        Connection connection = ConnectionUtil.getConnection();
        final Channel channel = connection.createChannel();
        channel.queueDeclare(baiduQueue,false,false,false,null);
        //queueBing 用于将队列和交换机绑定
        //参数1:队列名,参数2:交换机名,参数三:路由key 在路由模式用的
        channel.queueBind(baiduQueue,exchangeStr,"");
        channel.basicQos(1);
        channel.basicConsume(baiduQueue,false,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String weatherStr = new String(body);
                System.out.println("SMSSender1===短信发送成功:"+weatherStr);
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        });
    }
}
3.4 总结:

发布订阅模式比WorkQueue 工作模式多了一个交换机的概念,并且生产者发布消息不是直接到队列Queue,而是发给交换机,消费者需要创建队列,在通过Bing把交换机和队列绑定。

4.Routing 路由模式

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

在这里插入图片描述

上图解释如下:

  • P:生产者,向 Exchange 发送消息,发送消息时,会指定一个routing key
  • X:Exchange(交换机),接收生产者的消息,然后把消息递交给与 routing key 完全匹配的队列
  • C1:消费者,其所在队列指定了需要 routing key 为 error 的消息
  • C2:消费者,其所在队列指定了需要 routing key 为 info、error、warning 的消息
4.2 代码编写

注意:获取Connection工具类省略了,Exchange需要在管理界面创建且类型为Direct

生产者代码

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import rabbitmq.ConnectionUtil;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class WeatherBureau {
    public static void main(String[] args)  throws Exception{
        String exchangeStr = "exchange_weather_routing";
        Map<String,String> area = new HashMap();
        area.put("china.beijing.20221128","北京20221128号天气晴朗!");
        area.put("china.zhengzhou.20221128","郑州20221128号天气小雪!");
        area.put("us.NewYork.20221129","纽约20221129号天气晴朗!");
        area.put("us.Washington.20221129","华盛顿20221129号天气小雪!");
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        Iterator<Map.Entry<String, String>> itr = area.entrySet().iterator();
        while (itr.hasNext()){
            Map.Entry<String, String> m = itr.next();
            //第一个参数:交换机名字,第二个参数:消息的Routing key
            channel.basicPublish(exchangeStr,m.getKey(),null,m.getValue().getBytes());
        }
        channel.close();
        connection.close();
    }
}

消费者代码

import com.rabbitmq.client.*;
import rabbitmq.ConnectionUtil;
import java.io.IOException;

public class BaiduConsumer {
    public static void main(String[] args) throws Exception {
        String exchangeStr = "exchange_weather_routing";
        String baiduQueue = "baidu-queue";
        Connection connection = ConnectionUtil.getConnection();
        final Channel channel = connection.createChannel();
        channel.queueDeclare(baiduQueue,false,false,false,null);
        //queueBing 用于将队列和交换机绑定
        //参数1:队列名,参数2:交换机名,参数三:路由key 在路由模式用的
        channel.queueBind(baiduQueue,exchangeStr,"china.beijing.20221128");
        channel.queueBind(baiduQueue,exchangeStr,"china.zhengzhou.20221128");
        channel.queueBind(baiduQueue,exchangeStr,"us.NewYork.20221129");

        channel.basicQos(1);
        channel.basicConsume(baiduQueue,false,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String weatherStr = new String(body);
                System.out.println("SMSSender1===短信发送成功:"+weatherStr);
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        });
    }
}

注意:生产者发送了4个路由ke,但消费者只接受了3个,剩余的一个会退回生产者,因为没有队列存储。

4.3 总结:

Routing 模式要求队列在绑定交换机时要指定routing key ,消息转发到符合routing key的队列。不符合的不转发,此模式比较麻烦,使用比较少。

5. Topics 通配符模式

5.1 模式说明
  • Topic 类型与 Direct 相比,都是可以根据 RoutingKey 把消息路由到不同的队列。只不过 Topic 类型Exchange 可以让队列在绑定 Routing key 的时候使用通配符!
  • Routingkey 一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如:item.insert
  • 通配符规则:#匹配一个或多个词,*匹配不多不少恰好1个词,例如:item.# 能够匹配 item.insert.abc 或者 item.insert,item. 只能匹配 item.insert

代码就不写和路由模式是一样的,消费者代码不需要每一个绑定路由,只需要写一个通配符就可以。

6、工作模式总结

  1. 简单模式 HelloWorld
    一个生产者、一个消费者,不需要设置交换机(使用默认的交换机)。
  2. 工作队列模式 Work Queue
    一个生产者、多个消费者(竞争关系),不需要设置交换机(使用默认的交换机)。
  3. 发布订阅模式 Publish/subscribe
    需要设置类型为 fanout 的交换机,并且交换机和队列进行绑定,当发送消息到交换机后,交换机会将消息发送到绑定的队列。
  4. 路由模式 Routing
    需要设置类型为 direct 的交换机,交换机和队列进行绑定,并且指定 routing key,当发送消息到交换机后,交换机会根据 routing key 将消息发送到对应的队列。
  5. 通配符模式 Topic
    需要设置类型为 topic 的交换机,交换机和队列进行绑定,并且指定通配符方式的 routing key,当发送消
    息到交换机后,交换机会根据 routing key 将消息发送到对应的队列.

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

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

相关文章

CAS:304014-13-9,淬灭剂QSY21 NHS ,QSY 21NHS 试剂供应

一&#xff1a;产品描述 1、名称 QSY 21NHS 淬灭剂QSY21 NHS 淬灭剂QSY21 NHS ester 2、CAS编号&#xff1a;304014-13-9 3、分子式&#xff1a;C45H39ClN4O7S 4、分子量&#xff1a;815.34 5、外观&#xff1a; 紫色固体 &#xff08;具体由其分子量大小决定外观&am…

ORB-SLAM2 ---- KeyFrameDatabase::DetectRelocalizationCandidates函数

目录 1.函数作用 2.步骤 3.code 4.函数解析 4.1 找出和当前帧具有公共单词(word)的所有关键帧 4.2 统计上述关键帧中与当前帧F具有共同单词最多的单词数maxCommonWords&#xff0c;用来设定阈值1 4.3 遍历上述关键帧&#xff0c;挑选出共有单词数大于阈值1的及其和当…

JUC并发编程第五篇,如何优雅的使用线程中断机制和线程等待唤醒机制?

JUC并发编程第五篇&#xff0c;如何优雅的使用线程中断机制和线程等待唤醒机制&#xff1f;一、线程中断机制1. 什么是线程中断&#xff1f;2. 你知道 interrupt() 方法的含义吗&#xff1f;3. 如何使用中断标识优雅的停止线程&#xff1f;第一种&#xff1a;通过volatile变量实…

元年智答|数据洞察功能介绍

什么是数据洞察 随着企业积累数据量增多&#xff0c;数据分析师常常需要处理“长且宽”的数据集。依靠人的经验处理海量数据&#xff0c;从海量数据中发掘出有用的信息无异于大海捞针。虽然人工智能技术的普及和单位算力价格的下降大大降低了数据挖掘的门槛&#xff0c;但是面…

消息队列概述与扩展

一、消息队列的特性 与业务解藕&#xff1a;一个具有普适性质的消息队列组件不需要考虑上层的业务模型&#xff0c;只做好消息的分发就可以了&#xff0c;上层业务的不同模块反而需要依赖消息队列所定义的规范进行通信。FIFO&#xff1a;先投递先到达的保证是一个消息队列和一…

【HTML】猜拳小游戏

博主&#xff1a;&#x1f44d;不许代码码上红 欢迎&#xff1a;&#x1f40b;点赞、收藏、关注、评论。 格言&#xff1a; 大鹏一日同风起&#xff0c;扶摇直上九万里。 文章目录一、HTML完整源码二、效果三、完整资源文件一、HTML完整源码 <!DOCTYPE html PUBLIC "…

文本分类方案,飞浆PaddleNLP涵盖了所有

文章目录1.前言2.核心技术2.1 文本分类方案全覆盖2.1.1 分类场景齐全2.1.2 多方案满足定制需求方案一&#xff1a;预训练模型微调方案二&#xff1a;提示学习方案三&#xff1a;语义索引2.2 更懂中文的训练基座2.3 高效模型调优方案2.4 产业级全流程方案3. 快速开始4. 常用中文…

Photoshop、Illustrator、Sketch哪个更好

以前在交流组经常能看到大家争论哪个设计软件好&#xff1f;到底是你的吗&#xff1f;Illustrator好还是我的CorelDRAW或者他的Photoshop强大&#xff1f;但是跟着UI流行的设计&#xff0c;Sketch软件也加入了争论&#xff01;让我们和你分享一下这篇文章。让我们来看看平面设计…

云原生周刊 | AWS 开源 macOS 容器开发工具 Finch | 2022-11-28

今年的北美 KubeCon 大会结束后&#xff0c;来自 uptime.build 的 Jan Mundin 给会场的所有展台都拍了照&#xff0c;详细分析展台上的每一个单词&#xff0c;并汇总成了词云&#xff0c;其中热门词汇只有“安全”和“平台”&#xff0c;并不包含“自动化”和 DevOps。整个会场…

第四章 数字逻辑电路设计方法【Verilog】

第四章 数字逻辑电路设计方法【Verilog】前言推荐第四章 数字逻辑电路设计方法概览4.2 组合逻辑设计裁判表决电路方法1&#xff1a;真值表方式方法2&#xff1a;逻辑代数方式方法3&#xff1a;结构描述方式方法4&#xff1a;抽象描述方式测试结果4.2.1数字加法器2输入1 bit信号…

ATJ2157ATJ2127音乐按文件名拼音排序---标案是按内码进行排序

音乐按文件名拼音进行排序参考网站ATJ2157&ATJ2127 排序是按照内码(汉字为GBK即GBK936)排序的按拼音排序unicode与拼音的对比表(U2P.DAT)&#xff0c;需要打包到固件中U2P.DAT数据结构U2P.DAT生成代码是使用DEV-C生成其他说明U2P.DAT与ATJ2127平台代码参考网站 各种字符对…

springboot奥运会志愿者管理系统

当我知道奥运会志愿申请成功&#xff0c;也刚好是我的毕业&#xff0c;觉得自已需要做点什么&#xff0c;奥运会申请成功觉得自已去做一个志愿者&#xff0c;这样不断丰富了自已的经历&#xff0c;还能给自已在现实生活中上了一课&#xff0c;为了迎合志愿者需求&#xff0c;决…

SSM毕设项目 - 基于SSM的毕业设计管理系统(含源码+论文)

文章目录1 项目简介2 实现效果2.1 界面展示3 设计方案3.1 概述3.2 系统流程3.2.1 系统开发流程3.3.2 教师登录流程3.3.3 系统操作流程3.3 系统结构设计4 项目获取1 项目简介 Hi&#xff0c;各位同学好呀&#xff0c;这里是M学姐&#xff01; 今天向大家分享一个今年(2022)最新…

经典Mysql入门必刷50题及全网最新最详细的笔记记录

文章目录Mysql50题练习题1练习题2练习题3练习题4练习题5练习题6练习题7练习题10练习题11练习题12练习题13练习题14练习题15练习题16练习题17练习题18练习题1919.按各科平均成绩进行排序&#xff0c;并显示排名练习题20练习题21练习题22练习题24练习题25练习题26.练习题27练习题…

代码随想录刷题| LeetCode 121. 买卖股票的最佳时机 122.买卖股票的最佳时机II

目录 121. 买卖股票的最佳时机 思路 暴力解法 贪心算法 动态规划 买卖股票的最佳时机 贪心算法 动态规划 122.买卖股票的最佳时机II 思路 分析递推公式 买卖股票的最佳时机II 贪心算法 动态规划 121. 买卖股票的最佳时机 题目链接&#xff1a;力扣 思路 暴力解法 暴力解答会超…

3D视觉应用案例:法兰件/引擎盖/控制臂上料,轮毂抓取上架

法兰件上料 某大型汽配厂 项目背景 客户为某知名外资汽车零部件企业&#xff0c;其位于华东的工厂需求3D视觉实现喷砂机床的上料自动化。工件为板状多孔金属件&#xff0c; 厚度仅5mm&#xff0c;有序堆叠于深筐&#xff0c;需匹配喷砂机床高速上料作业。 作业流程 • 人工…

【抽样调查】CH3 分层随机抽样

目录 前言 一、概述 1.相关定义 &#xff08;1&#xff09;层 &#xff08;2&#xff09;分层抽样 2.分层随机抽样的步骤 3.分层抽样优于简单随机抽样的理由 4.分层原则 5.例 &#xff08;1&#xff09; &#xff08;2&#xff09; 6.符号 二、简单估计量及其性质 …

[附源码]Python计算机毕业设计Django大学生创新项目管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Briefings in bioinformatics2021 | QSAR模型中,传统表征要优于molecular embedding?

论文标题&#xff1a;Using molecular embeddings in QSAR modeling: does it make a difference? GitHub - VirginiaSabando/MolecularEmbeddings: Official site for "Using Molecular Embeddings in QSAR modeling: Does it Make a Difference?" (Briefings in…

uniapp组件传值的方法(父传子,子传父,对象传值)案例

文章目录前言父组件给子组件传值子组件给父组件传值父组件给父组件传对象值前言 最近看到uniapp组件传值的方法&#xff0c;这里记录一下&#xff0c;学过vue的应该都觉得很简单&#xff0c;传值的方法基本与vue的写法差不多 父组件给子组件传值 创建子组件comp.vue&#xf…