springboot simple (12) springboot RabbitMQ

news2024/9/28 17:35:15

这里首先简单的介绍了RabbitMQ ,然后实现了springboot集成RabbitMQ ,包含两个工程:
1 Producer 生产者
2 Consumer 消费者

1 RabbitMQ 简介

AMQP :Advanced Message Queue,高级消息队列协议。
RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。

RabbitMQ是一个生产者和消费者模型,用于实现消息的接收、存储、转发。
模型如下图所示:
在这里插入图片描述
Producer 生产者
Consumer 消费者
Exchange 交换机
Queue :队列,存储消息

常用的交换机Exchange
1)fanout Exchange(扇形交换机)
2)direct Exchange(直连交换机)
3)topic Exchange(主题交换机)
4)headers Exchange(头交换机)

2 springboot 集成RabbitMQ

第1步:pom中引入依赖的包:

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-amqp</artifactId>
			<version>3.0.1</version>
		</dependency>

第2步:application.properties设置相关参数:

#rabbitmq相关配置
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.publisher-confirm-type=correlated
spring.rabbitmq.publisher-returns=true
spring.main.allow-bean-definition-overriding = true

2.1 fanout Exchange(扇形交换机)

特点:将消息路由到所有与该交换机绑定的队列中。
在这里插入图片描述
第1步:创建配置类FanoutConfig,创建了:
交换机(exchange):fanout_exchange
队列(Queue):fanout_queue_A
绑定(Binding):fanoutBindA
队列(Queue):fanout_queue_B
绑定(Binding):fanoutBindB

@Configuration
public class FanoutConfig {
    @Bean("fanout_exchange")
    public FanoutExchange fanoutExchange() {
        return ExchangeBuilder.fanoutExchange("fanout_exchange").durable(true).build();
    }

    @Bean("fanout_queue_A")
    public Queue fanoutQueueA(){
        return QueueBuilder.durable("fanout_queue_A").build();
    }

    @Bean
    public Binding fanoutBindA(){
        return BindingBuilder.bind(fanoutQueueA()).to(fanoutExchange());
    }

    @Bean("fanout_queue_B")
    public Queue fanoutQueueB(){
        return QueueBuilder.durable("fanout_queue_B").build();
    }

    @Bean
    public Binding fanoutBindB(){
        return BindingBuilder.bind(fanoutQueueB()).to(fanoutExchange());
    }
}

第2步:Producer 项目创建发送消息的类FanoutService :

@Slf4j
@Service
public class FanoutService {
    String exchange = "fanout_exchange";

    @Resource
    private RabbitTemplate rabbitTemplate;

    public void sendData(String data) {
        log.info("------------fanout producer begin------------");
        rabbitTemplate.convertAndSend(exchange, "", data);
        log.info("exchange:"+exchange);
        log.info("send data:"+data);
        log.info("------------fanout producer end------------");
    }
}

第3步:Consumer 创建接收消息的类FanoutListener :

@Component
@Slf4j
public class FanoutListener {
    /**
     * .接收队列fanout_queue_A的数据
     */
    @RabbitListener(queues = {"fanout_queue_A"})
    @RabbitHandler
    public void receiveDataFromQueueA(Message message, Channel channel) throws IOException {
        long tag = message.getMessageProperties().getDeliveryTag();
        channel.basicAck( tag, true);
        log.info("------------fanout consumer begin------------");
        log.info("queue: fanout_queue_A");
        log.info("receive Data: " + new String(message.getBody()));
        log.info("------------fanout consumer end------------");
    }

    /**
     * .接收队列fanout_queue_B的数据
     */
    @RabbitListener(queues = {"fanout_queue_B"})
    @RabbitHandler
    public void receiveDataFromQueueB(Message message, Channel channel) throws IOException {
        long tag = message.getMessageProperties().getDeliveryTag();
        channel.basicAck( tag, true);
        log.info("------------fanout consumer begin------------");
        log.info("queue: fanout_queue_B");
        log.info("receive Data: " + new String(message.getBody()));
        log.info("------------fanout consumer end------------");
    }
}

2.2 direct Exchange(直连交换机)

特点:根据消息默认的路由键(队列名称)将消息投递到相应的队列中。
在这里插入图片描述
第1步:创建配置类DirectConfig,创建了:
交换机(exchange):direct_exchange_A
队列(Queue):direct_queue_A
绑定(Binding):directBindA

交换机(exchange):direct_exchange_B
队列(Queue):direct_queue_B
绑定(Binding):directBindB

@Configuration
public class DirectConfig {
    @Bean("direct_exchange_A")
    public DirectExchange directExchangeA() {
        return ExchangeBuilder.directExchange("direct_exchange_A").durable(true).build();
    }

    @Bean("direct_queue_A")
    public Queue directQueueA() {
        return QueueBuilder.durable("direct_queue_A").build();
    }

    @Bean
    public Binding directBindA(@Qualifier("direct_queue_A")Queue queue,
                              @Qualifier("direct_exchange_A")DirectExchange directExchange){
        return BindingBuilder.bind(queue)
                .to(directExchange).withQueueName();
    }

    @Bean("direct_exchange_B")
    public DirectExchange directExchangeB() {
        return ExchangeBuilder.directExchange("direct_exchange_B").durable(true).build();
    }

    @Bean("direct_queue_B")
    public Queue directQueueB() {
        return QueueBuilder.durable("direct_queue_B").build();
    }

    @Bean
    public Binding directBindB(@Qualifier("direct_queue_B")Queue queue,
                               @Qualifier("direct_exchange_B")DirectExchange directExchange){
        return BindingBuilder.bind(queue)
                .to(directExchange).withQueueName();
    }
}

.withQueueName() 可见绑定key为queue名称。

第2步:Producer 项目创建发送消息的类DirectService :

@Slf4j
@Service
public class DirectService {
    String routeKey = "direct_queue_A";

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendData(String data) {
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        log.info("------------direct producer begin------------");
        rabbitTemplate.convertAndSend(routeKey, data);
        log.info("routeKey:"+routeKey);
        log.info("send data:"+data);
        log.info("------------direct producer end------------");
    }
}

第3步:Consumer 创建接收消息的类DirectListener :

@Component
@Slf4j
public class DirectListener {

    /**
     * .接收队列direct_queue_A的数据
     */
    @RabbitListener(queues = {"direct_queue_A"})
    public void receiveDataFromQueueA(Message message, Channel channel) throws IOException {
        long tag = message.getMessageProperties().getDeliveryTag();
        channel.basicAck(tag, true);
        log.info("------------direct consumer begin------------");
        log.info("queue: fanout_queue_A");
        log.info("receive Data: " + new String(message.getBody()));
        log.info("------------direct consumer end------------");
    }

    /**
     * .接收队列direct_queue_B的数据
     */
    @RabbitListener(queues = {"direct_queue_B"})
    public void receiveDataFromQueueB(Message message, Channel channel) throws IOException {
        long tag = message.getMessageProperties().getDeliveryTag();
        channel.basicAck(tag, true);
        log.info("------------direct consumer begin------------");
        log.info("queue: fanout_queue_B");
        log.info("receive Data: " + new String(message.getBody()));
        log.info("------------direct consumer end------------");
    }
}

2.3 topic Exchange(主题交换机)

特点:将消息路由到路由键(RoutingKey)和绑定键(BindKey)相匹配的队列中。
在这里插入图片描述

第1步:创建配置类TopicConfig,创建了:
交换机(exchange):topic_exchange
队列(Queue):topic_queue_A
绑定(Binding):topicBindA
绑定key(BindKey):project1.station1.*
交换机(exchange):topic_exchange
队列(Queue):topic_queue_B
绑定(Binding):topicBindB
绑定key(BindKey):project1.."

@Configuration
public class TopicConfig {
    String routeKeyA = "project1.station1.*";
    String routeKeyB = "project1.*.*";

    @Bean("topic_exchange")
    public TopicExchange topicExchange() {
        return ExchangeBuilder.topicExchange("topic_exchange").durable(true).build();
    }

    @Bean("topic_queue_A")
    public Queue topicQueueA(){
        return QueueBuilder.durable("topic_queue_A").build();
    }

    @Bean
    public Binding topicBindA(){
        return BindingBuilder.bind(topicQueueA()).to(topicExchange()).with(routeKeyA);
    }

    @Bean("topic_queue_B")
    public Queue topicQueueB(){
        return QueueBuilder.durable("topic_queue_B").build();
    }

    @Bean
    public Binding topicBindB(){
        return BindingBuilder.bind(topicQueueB()).to(topicExchange()).with(routeKeyB);
    }
}

第2步:Producer 项目创建发送消息的类TopicService :

@Slf4j
@Service
public class TopicService {
    String exchange = "topic_exchange";
    //String routeKey = "project1.station1.device1";
    String routeKey = "project1.station2.device1";
    @Resource
    private RabbitTemplate rabbitTemplate;

    public void sendData(String data) {
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        log.info("------------topic producer begin------------");
        rabbitTemplate.convertAndSend(exchange, routeKey, data);
        log.info("routeKey:"+routeKey);
        log.info("send data:"+data);
        log.info("------------topic producer end------------");
    }
}

第3步:Consumer 创建接收消息的类TopicListener :

@Component
@Slf4j
public class TopicListener {
    /**
     * .接收队列topic_queue_A的数据
     */
    @RabbitListener(queues = {"topic_queue_A"})
    public void receiveDataFromQueueA(Message message, Channel channel) throws IOException {
        long tag = message.getMessageProperties().getDeliveryTag();
        channel.basicAck( tag, true);
        log.info("------------topic_ consumer begin------------");
        log.info("queue: topic_queue_A");
        log.info("receive Data: " + new String(message.getBody()));
        log.info("------------topic_ consumer end------------");
    }

    /**
     * .接收队列topic_queue_B的数据
     */
    @RabbitListener(queues = {"topic_queue_B"})
    public void receiveDataFromQueueB(Message message, Channel channel) throws IOException {
        long tag = message.getMessageProperties().getDeliveryTag();
        channel.basicAck( tag, true);
        log.info("------------topic_ consumer begin------------");
        log.info("queue: topic_queue_B");
        log.info("receive Data: " + new String(message.getBody()));
        log.info("------------topic_ consumer end------------");
    }
}

2.4 headers Exchange(头交换机)

特点:路由规则是建立在头属性值之上,而不是路由键。
在这里插入图片描述

第1步:创建配置类TopicConfig,创建了:
交换机(exchange):headers_exchange
队列(Queue):headers_queue_A
绑定(Binding):headersBindA
头(headers):
headerValues.put(“type”, “gass”);
headerValues.put(“data”, “realTime”);
匹配规则:whereAll

队列(Queue):headers_queue_B
绑定(Binding):headersBindB
头(headers):
headerValues.put(“type”, “gass”);
headerValues.put(“data”, “realTime”);
匹配规则:whereAny

@Configuration
public class HeadersConfig {

    @Bean("headers_exchange")
    public HeadersExchange headersExchange() {
        return ExchangeBuilder.headersExchange("headers_exchange").durable(true).build();
    }

    @Bean("headers_queue_A")
    public Queue headerQueueA(){
        return QueueBuilder.durable("headers_queue_A").build();
    }

    @Bean
    public Binding headersBindA(){
        Map<String,Object> headerValues = new HashMap<>();
        headerValues.put("type", "gass");
        headerValues.put("data", "realTime");
        return BindingBuilder.bind(headerQueueA()).to(headersExchange()).whereAll(headerValues).match();
    }

    @Bean("headers_queue_B")
    public Queue headerQueueB(){
        return QueueBuilder.durable("headers_queue_B").build();
    }

    @Bean
    public Binding headersBindB(){
        Map<String,Object> headerValues = new HashMap<>();
        headerValues.put("type", "gass");
        headerValues.put("data", "realTime");
        return BindingBuilder.bind(headerQueueB()).to(headersExchange()).whereAny(headerValues).match();
    }
}

第2步:Producer 项目创建发送消息的类HeadersService :

@Slf4j
@Service
public class HeadersService {
    String exchange = "headers_exchange";
    String routeKey = "";

    @Resource
    private RabbitTemplate rabbitTemplate;

    public void sendData(String data) {
        log.info("------------headers producer begin------------");
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setHeader("type", "gass");
        messageProperties.setHeader("data", "realTime");
        //messageProperties.setHeader("data", "history");
        Message message = new Message(data.getBytes(), messageProperties);
        rabbitTemplate.convertAndSend(exchange, routeKey, message);
        log.info("send data:"+data);
        log.info("------------headers producer end------------");
    }
}

第3步:Consumer 创建接收消息的类HeadersListener :

@Component
@Slf4j
public class HeadersListener {
    /**
     * .接收队列headers_queue_A的数据
     */
    @RabbitListener(queues = {"headers_queue_A"})
    public void receiveDataFromQueueA(Message message, Channel channel) throws IOException {
        long tag = message.getMessageProperties().getDeliveryTag();
        channel.basicAck( tag, true);
        log.info("------------headers consumer begin------------");
        log.info("queue: headers_queue_A");
        log.info("receive Data: " + new String(message.getBody()));
        log.info("------------headers consumer begin------------");
    }

    /**
     * .接收队列headers_queue_B的数据
     */
    @RabbitListener(queues = {"headers_queue_B"})
    public void receiveDataFromQueueB(Message message, Channel channel) throws IOException {
        long tag = message.getMessageProperties().getDeliveryTag();
        channel.basicAck( tag, true);
        log.info("------------headers consumer begin------------");
        log.info("queue: headers_queue_B");
        log.info("receive Data: " + new String(message.getBody()));
        log.info("------------headers consumer begin------------");
    }
}

3 测试验证

3.1 fanout Exchange验证

第1步:postman发送请求:
http://127.0.0.1:8081/rabbitMq/sendMessageByFanout?msg=hello,fanout exchangge!
在这里插入图片描述
第2步:可以看到producer发送消息:
在这里插入图片描述
第3步:可以看到consumer接收消息:
在这里插入图片描述
可见:与交换机fanout_exchange绑定的两个队列fanout_queue_A、fanout_queue_B都收到了消息。

3.2 direct Exchange验证

第1步:postman发送请求:
http://127.0.0.1:8081/rabbitMq/sendMessageByDirect?msg=hello,direct exchangge!
在这里插入图片描述
第2步:可以看到producer发送消息:
在这里插入图片描述
第3步:可以看到consumer接收消息:
在这里插入图片描述
可见:routeKey 和BindKey都为queue名称direct_queue_A,队列direct_queue_A收到了消息。

3.3 topic Exchange验证

3.3.1 topic_queue_A、topic_queue_B都匹配

路由键(routeKey):project1.station1.device1
绑定key(BindKey):project1.station1.*
绑定key(BindKey):project1.."

第1步:postman发送请求:
http://127.0.0.1:8081/rabbitMq/sendMessageByTopic?msg=hello,topic exchangge!
在这里插入图片描述
第2步:可以看到producer发送消息:
在这里插入图片描述
第3步:可以导刊consumer接收消息:
在这里插入图片描述
可以看到两个队列 topic_queue_A、topic_queue_B都收到了消息。

3.3.2 只有topic_queue_B匹配

路由键(routeKey):project1.station2.device1
绑定key(BindKey):project1.station1.*
绑定key(BindKey):project1.."

第1步:postman发送请求:
http://127.0.0.1:8081/rabbitMq/sendMessageByTopic?msg=hello,topic exchangge!
在这里插入图片描述
第2步:可以看到producer发送消息:
在这里插入图片描述
第3步:可以看到consumer接收消息:
在这里插入图片描述
可以看到只有队列topic_queue_B收到了消息。

3.4 headers Exchange验证

3.4.1 headers_queue_A、headers_queue_B都匹配

发送消息的header:

messageProperties.setHeader("type", "gass");
messageProperties.setHeader("data", "realTime");

第1步:postman发送请求:
http://127.0.0.1:8081/rabbitMq/sendMessageByHeaders?msg=hello,headers exchangge!
在这里插入图片描述
第2步:可以看到producer发送消息:
在这里插入图片描述
第3步:可以看到consumer接收消息:
在这里插入图片描述
可见headers_queue_A、headers_queue_B都收到了消息。

3.4.2 只有headers_queue_B匹配

发送消息的header:

messageProperties.setHeader("type", "gass");
messageProperties.setHeader("data", "history");

第1步:postman发送请求:
http://127.0.0.1:8081/rabbitMq/sendMessageByHeaders?msg=hello,headers exchangge!
在这里插入图片描述

第2步:可以看到producer发送消息:
在这里插入图片描述
第3步:可以看到consumer接收消息:
在这里插入图片描述
可见:只有headers_queue_B收到了消息。

代码详见:
https://gitee.com/linghufeixia/springboot-simple
chapter6-4 producer项目
chapter6-5 consumer项目


教程列表
springboot simple(0) springboot简介
springboot simple(1) springboot Helloworld
springboot simple(2) springboot Starter
springboot simple(3 )springboot Web开发
springboot simple(4)springboot 数据持久化
springboot simple (5) springboot Nosql
springboot simple (6) springboot mqtt
springboot simple (7) springboot thrift
springboot simple (8) springboot kafka
springboot simple (9) springboot jpa(Hibernate)
springboot simple (10) springboot protobuf
springboot simple (11) springboot protostuff
springboot simple (12) springboot RabbitMQ

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

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

相关文章

智能大屏兴起,酷开科技赋能营销战略!

随着科技的发展&#xff0c;智能大屏的功能与技术都在日新月异的快速更迭&#xff0c;年轻消费群体也对大尺寸智能大屏表现出了特别的偏爱&#xff0c;以前说到看视频、网上购物、阅读书籍时&#xff0c;人们第一时间就会想到手机&#xff0c;但随着智能大屏的出现&#xff0c;…

商用设计素材库,设计师必备。

免费、商用设计素材网站。 1、菜鸟图库 https://www.sucai999.com/?vNTYxMjky站内平面海报、UI设计、电商淘宝、免抠、高清图片、样机模板等素材非常齐全。还有在线抠图、CDR版本转换功能&#xff0c;能有效的为设计师节省找素材时间&#xff0c;提高工作效率。网站素材都能免…

LeetCode链表经典题目(二)

1. LeetCode203. 移除链表元素 2. LeetCode707.设计链表 3. LeetCode206. 反转链表 4. LeetCode24. 两两交换链表中的节点​ 5. LeetCode19. 删除链表的倒数第 N 个结点 6. LeetCode面试题 02.07. 链表相交 7. LeetCode142. 环形链表 II​ 1. LeetCode203. 移除链表元素 …

基于同豪的道路桥梁设计方案如何实现数字化交付(web发布)

0序&#xff1a; 当下有部分设计人员除了使用Revit、Microstation之外也使用过程的同豪软件进行道路桥梁的BIM建模。如何对同豪的BIM模型进行数字化交付呢&#xff1f; 1数据导出为FBX 具体导出过程可以参考&#xff1a; 数据的导出只要按步骤导出就行&#xff0c;非常简单…

2023最让人期待的日历!每个IT技术人必备

一转眼&#xff0c;2022年已经要接近尾声了..... 这一年的你过的怎么样呢&#xff1f;相比上一年的自己有什么变化呢&#xff1f; 凡是过往皆为序章&#xff0c;所有将来皆为可盼&#xff01;在2023年即将到来之际给大家推荐一本非常适合IT技术人的日历&#x1f449;「小滴日历…

python—you-get下载工具、wget下载工具

目录 wget you-get wget wget工具下载&#xff1a;GNU Wget 1.21.3 for Windows wget工具见&#xff1a;python-外部程序的调用os库、subprocess 模块_觅远的博客-CSDN博客_python外部库调用调出 you-get you-get是一款实用的网站视频下载工具。可以很轻松的下载到网络上…

极限学习机ELM回归预测(MATLAB代码实现)

&#x1f352;&#x1f352;&#x1f352;欢迎关注&#x1f308;&#x1f308;&#x1f308; &#x1f4dd;个人主页&#xff1a;我爱Matlab &#x1f44d;点赞➕评论➕收藏 养成习惯&#xff08;一键三连&#xff09;&#x1f33b;&#x1f33b;&#x1f33b; &#x1f34c;希…

【数据结构与算法】第十七篇:图论万字解析(进阶篇)

&#x1f440;作者简介&#xff1a;大家好&#xff0c;我是 快到碗里来~ &#x1f6a9;&#x1f6a9; 个人主页&#xff1a;快到碗里来~ 支持我&#xff1a;点赞关注~不迷路&#x1f9e1;&#x1f9e1;&#x1f9e1; ✔系列专栏&#xff1a;数据结构与算法⚡⚡⚡ (❁◡❁)励志格…

代码随想录算法训练营第十一天(栈与队列)| 20. 有效的括号,1047. 删除字符串中的所有相邻重复项,150. 逆波兰表达式求值

代码随想录算法训练营第十一天&#xff08;栈与队列&#xff09;| 20. 有效的括号&#xff0c;1047. 删除字符串中的所有相邻重复项&#xff0c;150. 逆波兰表达式求值 20. 有效的括号 讲完了栈实现队列&#xff0c;队列实现栈&#xff0c;接下来就是栈的经典应用了。 大家先…

激发原创力量,逐梦数智未来 | 麒麟信安闪耀openEuler Summit 2022

[中国&#xff0c;北京&#xff0c;2022年12月29日]由欧拉开源社区发起并联合华为、麒麟信安、麒麟软件、统信软件等伙伴&#xff0c;共同举办的openEuler Summit 2022于线上举行。 会上&#xff0c;开放原子开源基金会宣布openEuler项目群成立&#xff1b;同时&#xff0c;新…

CVPR 2021|Deep-SfM-Revisited:DeepLearn+经典SfM流程

&#x1f3c6;前言&#xff1a;文章回顾了深度学习在SfM中的应用&#xff0c;并提出了一种新的深度两视图SfM框架。该框架结合了深度学习和经典SfM几何算法的优点。在各个数据集上取得较好的结果。 文章目录解决的问题基本流程实施细节光流估计相机位姿估计尺度不变的深度估计损…

关于安科瑞电力监控系统在电力工程中的应用与对策

摘要&#xff1a;随着经济的发展&#xff0c;能源消耗速度正不断加快&#xff0c;因此我国提出了绿色可持续发展战略&#xff0c;要求在发展建设中以节能为主&#xff0c;不断减少资源能耗&#xff0c;而电能便是首要控制内容。如今我国为电能使用&#xff0c;对计量表进行了优…

《PyTorch深度学习实践》完结合集-P4反向传播作业

二次函数的反向传播 代码&#xff1a; import torch x_data [1.0, 2.0, 3.0] y_data [2.0, 4.0, 6.0] w1 torch.Tensor([1.0]) w1.requires_grad True #定义要进行反向传播 w2 torch.Tensor([1.0]) w2.requires_grad True b torch.Tensor([1.0]) b.requires_grad T…

PHP结课报告-简单的点菜系统(完整版,附源码与数据库)

1 系统背景及意义 1.1系统开发背景介绍 餐饮业在我国有着悠久的发展历史&#xff0c;是与人民生活密切相关的 行业之一&#xff0c;同时也是我国经济增长的新亮点&#xff0c;在 2010 年全国餐饮零 售总额高达 15913 亿元&#xff0c;实际增长约 14.3。在信息系统相对普及的 今…

项目经理通过甘特图编制项目计划的方法

项目有个特征叫 渐进明晰 &#xff0c;指一个项目不可能一开始就能想到最后交付成果的全部细节&#xff0c;项目最终的交付成果到底长啥样是随着项目的推进慢慢变得清晰的&#xff0c;而这个变化的过程不仅需要项目经理的经验与能力&#xff0c;还需要借助项目管理工具的帮助。…

一文讲清「敏捷路线图」,从此不再掉入瀑布陷阱

尽管许多组织和团队声称自己非常敏捷&#xff0c;但他们仍在使用瀑布的方式规划产品。为什么会这样&#xff1f;我们该如何改变这种「错误敏捷」&#xff1f; 原则上&#xff0c;践行敏捷开发很简单&#xff1a;构建一个增量&#xff1b;测试这个增量&#xff1b;了解需要改变…

webdriver的尝试:四 【移动端的使用appium-定位与获取代码】

文章目录界面的简单认识和使用参考我们前面使用webdriver可以实现&#xff1a;使用代码&#xff0c;自动化打开浏览器及指定页面&#xff0c;定位元素&#xff0c;获取内容或者模仿操作那么使用移动端&#xff0c;依然需要实现定位与操作 主要就是在appium inspector上进行操作…

开源全球公司贡献 49 名,涛思数据荣登 2022 中国开发者影响力年度榜单

12 月 28 日&#xff0c;CSDN 在北京举行 “2022 中国开发者影响力盛典暨 CSDN 企业生态汇”活动&#xff0c;同时正式发布 2022 中国开发者影响力年度榜单。本次公布的榜单主要包括年度开源贡献企业、年度开源影响力项目、年度开发者社区、年度数字化创新企业、年度优秀雇主企…

蓝桥杯Python练习题13-圆的面积

资源限制   内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述   给定圆的半径r&#xff0c;求圆的面积。 输入格式   输入包含一个整数r&#xff0c;表示圆的半径。 输出格式   输出…

自然语言处理复习

目录 第 3 章 深度学习基础 第 4 章 语言模型词向量 第 5 章 NLP中的注意力机制 第 6 章 NLP基础任务 第 7 章 预训练语言模型 第 3 章 深度学习基础 1. 人工神经网络 2. 激活函数 &#xff08;1&#xff09;激活函数的作用 为了增强网络的表达能力&#xff0c;需要引入…