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

RocketMQ快速入门:消息发送、延迟消息、消费重试

一起学编程,让生活更随和!

如果你觉得是个同道中人,欢迎关注博主gzh:【随和的皮蛋桑】。

专注于Java基础、进阶、面试以及计算机基础知识分享🐳。偶尔认知思考、日常水文🐌。

在这里插入图片描述


目录

  • 1、RocketMQ消息结构
    • 1.1、消息结构
    • 1.2、三种消息发松方式
  • 2、快速搭建工程
    • 2.1、创建rocketmq-demo父工程
    • 2.2、生产者工程
    • 2.3、消费者工程
    • 2.4、消息发送过程
  • 3、消息发送过程
  • 4、三种消息发送方式
    • 4.1、同步消息
    • 4.2、异步消息
    • 4.3、单向消息
  • 5、自定义消息格式
  • 6、延迟消息
    • 6.1、延迟消息介绍
    • 6.2、同步消息延迟发送
    • 6.3、异步消息延迟发送
  • 7、消费重试
    • 7.1、什么是消费重试
    • 7.2、处理策略

1、RocketMQ消息结构

1.1、消息结构

RocketMQ的消息包括基础属性和扩展属性两部分:

1)基础属性

  1. topic : 主题相当于消息的一级分类,具有相同topic的消息将发送至该topic下的消息队列中,比方说一个电商系统可以分为商品消息、订单消息、物流消息等,就可以在broker中创建商品主题、订单主题等,所有商品的消息发送至该主题下的消息队列中。
  2. 消息体:即消息的内容 ,可以的字符串、对象等类型(可系列化)。消息的最大长度 是4M。
  3. 消息Flag:消息的一个标记,RocketMQ不处理,留给业务系统使用。

2)扩展属性:

  1. tag :相当于消息的二级分类,用于消费消息时进行过滤,可为空 。
  2. keys: Message 索引键,在运维中可以根据这些 key 快速检索到消息, 可为空 。
  3. waitStoreMsgOK:消息发送时是否等消息存储完成后再返回 。Message 的基础属性主要包括消息所属主题 topic , 消息 Flag(RocketMQ 不做处理)、 扩展属性、消息体 。

1.2、三种消息发松方式

RocketMQ 支持 3 种消息发送方式 :

1)同步消息(sync message )

producer向 broker 发送消息,执行 API 时同步等待, 直到broker 服务器返回发送结果 。

2)异步消息(async message)

producer向 broker 发送消息时指定消息发送成功及发送异常的回调方法,调用 API 后立即返回,
producer发送消息线程不阻塞 ,消息发送成功或失败的回调任务在一个新的线程中执行 。

3)单向消息(oneway message)

producer向 broker 发送消息,执行 API 时直接返回,不等待broker 服务器的结果 。

2、快速搭建工程

2.1、创建rocketmq-demo父工程

在这里插入图片描述

pom.xml引入一下依赖:

		<!-- spring-boot父依赖 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.12.RELEASE</version><relativePath/></parent><dependencies><!-- starter-test --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><!-- starter-web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- rocketmq --><dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.1.0</version></dependency></dependencies>

2.2、生产者工程

1)创建rocketmq-producer生产者工程

在这里插入图片描述

2)新建rocketmq-producer工程的application.yml文件

# 端口号、上下文路径
server:port: 8181servlet:context-path: /rocketmq-producer# 服务名
spring:application:name: rocketmq-producer# rocketmq
rocketmq:name-server: 106.15.0.30:9876 #命名空间地址和端口号producer:group: demo-producer-group #生产者组

3) 新建启动类

package com.wbs;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** @author yixiujun* @version Id: ProducerApplication.java, v 0.1 Administrator Exp $$* @date 2023-02-15 09:22:20* @desc 生产者启动类*/
@SpringBootApplication
public class ProducerApplication {public static void main(String[] args) {SpringApplication.run(ProducerApplication.class, args);}}

4)创建发送同步消息方法

package com.wbs.test.message;import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.stereotype.Component;import javax.annotation.Resource;/*** @author yixiujun* @version Id: ProducerSimple.java, v 0.1 Administrator Exp $$* @date 2023-02-15 09:24:13* @desc rocketmq发送消息类*/
@Component
public class ProducerSimple {@Resourceprivate RocketMQTemplate rocketMQTemplate;/*** 发送同步消息** @param topic 主题* @param msg   消息*/public void sendSyncMsg(String topic, String msg) {rocketMQTemplate.syncSend(topic, msg);}}

5)测试

test包下创建单元测试ProducerSimpleTest 类:

package com.wbs.test.message;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;import javax.annotation.Resource;/*** @author yixiujun* @version Id: ProducerSimpleTest.java, v 0.1 Administrator Exp $$* @date 2023-02-19 16:24:20* @desc 生产者发送消息测试*/
@SpringBootTest
@RunWith(SpringRunner.class)
public class ProducerSimpleTest {@Resourceprivate ProducerSimple producerSimple;/*** 测试发送同步消息*/@Testpublic void testSendSyncMsg() {this.producerSimple.sendSyncMsg("my-topic", "第一条同步消息");System.out.println("end...");}}

启动服务器端

  • NameServer
  • Broker
  • console管理端

执行上述单元测试testSendSyncMsg方法,观察控制台和管理端控制台出现end...表示消息发送成功。

在这里插入图片描述

进入管理端,查询消息。

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

2.3、消费者工程

1)创建消息消费者工程rocketmq-consumer

在这里插入图片描述

**2)创建application.yml文件 **

# 端口号、上下文路径
server:port: 8182servlet:context-path: /rocketmq-consumer# 服务名
spring:application:name: rocketmq-consumer# rocketmq
rocketmq:name-server: 106.15.0.30:9876producer:group: demo-consumer-group

3)创建启动类

package com.wbs;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** @author yixiujun* @version Id: ConsumerApplication.java, v 0.1 Administrator Exp $$* @date 2023-02-19 16:46:00* @desc 消费者启动类*/
@SpringBootApplication
public class ConsumerApplication {public static void main(String[] args) {SpringApplication.run(ConsumerApplication.class, args);}}

4)消费消息

编写消费消息监听类:

package com.wbs.test.message;import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Component;/*** @author yixiujun* @version Id: ConsumerSimple.java, v 0.1 Administrator Exp $$* @date 2023-02-19 16:48:16* @desc 消费者监听类*/
@Component
@RocketMQMessageListener(topic = "my-topic", consumerGroup = "demo-consumer-group")
public class ConsumerSimple implements RocketMQListener<String> {/*** 接收到消息后调用此方法* @param s 消息内容*/@Overridepublic void onMessage(String s) {System.out.println(s + ":已被消费!");}}

监听消息队列 需要指定:

  • topic:监听的主题
  • consumerGroup:消费组,相同消费组的消费者共同消费该主题的消息,它们组成一个集群。

2.4、消息发送过程

启动消费者工程,观察控制台输出“第一条同步消息”消息内容,这说明从消息队列已经读取到消息。

保证消费者工程已启动,再次发送消息,观察控制台是否输出“第一条同步消息”消息内容,输出则说明接收消息成功。

在这里插入图片描述

3、消息发送过程

通过快速入门对消息的发送和接收有一个粗略的认识,下边分析具体的消息发送过程,如下图:
在这里插入图片描述

消息发送流程如下:

1、Producer从NameServer中获取主题路由信息

Broker将自己的状态上报给NameServer,NameServer中存储了每个Broker及主题、消息队列的信息。

Producer根据 topic从NameServer查询所有消息队列,查询到的结果例如:

[{"brokerName":"Broker‐1","queueId":0},{"brokerName":"Broker‐1","queueId":1},{"brokerName":"Broker‐2","queueId":0},{"brokerName":"Broker‐2","queueId":1}
]

Producer按选择算法从以上队列中选择一个进行消息发送,如果发送消息失败则在下次选择的时候 会规避掉失败的broker。

2、构建消息,发送消息

发送消息前进行校验,比如消息的内容长度不能为0、消息最大长度、消息必要的属性是否具备等(topic、消息体,生产组等)。

如果该topic下还没有队列则自动创建,默认一个topic下自动创建4个写队列,4个读队列 。为什么要多个队列 ?

  • 高可用:当某个队列不可用时其它队列顶上。
  • 提高并发:发送消息是选择队列进行发送,提高发送消息的并发能力。消息消费时每个消费者可以监听多个队列,提高消费消息的并发能力。

生产组有什么用?

在事务消息中broker需要回查producer,同一个生产组的producer组成一个集群,提高并发能力。

3、监听队列,消费消息

一个消费组可以包括多个消费者,一个消费组可以订阅多个主题。

一个队列同时只允许一个消费者消费,一个消费者可以消费多个队列中的消息。

消费组有两种消费模式:

1)集群模式

一个消费组内的消费者组成一个集群,主题下的一条消息只能被一个消费者消费。

2)广播模式

主题下的一条消息能被消费组下的所有消费者消费。

消费者和broker之间通过推模式拉模式接收消息,推模式即broker推送给消费者,拉模式是消费者主动从broker查询消息。

4、三种消息发送方式

RocketMQ 支持 3 种消息发送方式 ,即

  • 同步消息(sync message )
  • 异步消息(async message)
  • 单向消息(oneway message)

4.1、同步消息

参考2快速搭建工程(同步消息的简单示例)。

4.2、异步消息

producerbroker发送消息时指定消息发送成功及发送异常的回调方法,调用 API 后立即返回,producer发送消息线程不阻塞 ,消息发送成功或失败的回调任务在一个新的线程中执行 。

ProducerSimple中编写发送异步消息的方法:

	/*** 发送异步消息** @param topic 主题* @param msg   消息*/public void sendAsyncMsg(String topic, String msg) {rocketMQTemplate.asyncSend(topic, msg, new SendCallback() {@Overridepublic void onSuccess(SendResult sendResult) {// 回调成功System.out.println(sendResult.getSendStatus());}@Overridepublic void onException(Throwable throwable) {// 回调异常System.out.println(throwable.getMessage());}});}

单元测试:

	/*** 测试发送异步消息** @throws InterruptedException 异常*/@Testpublic void testSendASyncMsg() throws InterruptedException {this.producerSimple.sendAsyncMsg("my-topic", "第一条异步消息");System.out.println("end……");// 异步消息,为跟踪回调线程这里加入延迟Thread.sleep(3000);}

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

4.3、单向消息

producerbroker发送消息,执行 API 时直接返回,不等待broker服务器的结果 。

ProducerSimple中编写发送单项消息的方法:

	/*** 发送单向消息** @param topic 主题* @param msg   消息*/public void sendOneWayMsg(String topic, String msg) {this.rocketMQTemplate.sendOneWay(topic, msg);}

测试:

	/*** 测试发送异步消息*/@Testpublic void testSendOneWayMsg() {this.producerSimple.sendOneWayMsg("my-topic", "第一条单项消息");System.out.println("end……");}

在这里插入图片描述

5、自定义消息格式

前边我们发送的消息内容格式都是字符串,在生产开发中消息内容格式是相对较复杂的,下面介绍如何对消息格式进行自定义

JSON是互联网开发中非常常用的数据格式,它具有格式标准,扩展方便的特点,将消息的格式使用JSON进行定义,可以提高消息内容的扩展性,RocketMQ支持传递JSON数据格式。

在生产端和消费端定义模型类:

package com.wbs.test.model;/*** 自定义消息实体类** @author yixiujun* @version Id: OrderExt.java, v 0.1 Administrator Exp $$* @date 2023-02-19 20:55:25*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class OrderExt implements Serializable {private final static Long SERIALIZABLE_UID = -1L;/*** 主键id*/private String id;/*** 创建时间*/private Date createTime;/*** money*/private Long money;/*** 标题*/private String title;}

创建ProducerUserDefineSimple用户发送自定义消息模板类,创建发送消息内容为json格式的方法,

生产端:

package com.wbs.test.message;/*** 用户发送自定义消息模板** @author yixiujun* @version Id: ProducerUserDefineSimple.java, v 0.1 Administrator Exp $$* @date 2023-02-19 21:07:16*/
@Component
public class ProducerUserDefineSimple {@Resourceprivate RocketMQTemplate rocketMQTemplate;/*** 消息内容为json格式** @param topic 主题* @param orderExt   消息实体*/public void sendMsgByJson(String topic, OrderExt orderExt) {// 发送同步消息,消息内容将orderExt转为jsonthis.rocketMQTemplate.convertAndSend(topic, orderExt);System.out.printf("send msg : %s", orderExt);}}

编写单元测试方法:

	/*** 测试发送JSON格式的内容消息*/@Testpublic void sendMsgByJson() {OrderExt orderExt = new OrderExt();orderExt.setId("001");orderExt.setCreateTime(new Date());orderExt.setMoney(10000L);orderExt.setTitle("这是JSON格式数据");this.producerUserDefineSimple.sendMsgByJson("my-topic", orderExt);System.out.println("end……");}

在这里插入图片描述

消费端:

@Component
@RocketMQMessageListener(topic = "my-topic-obj", consumerGroup = "demo-consumer-group-obj")
public class ConsumerUserDefineSimple implements RocketMQListener<String> {/*** 接收到消息后调用此方法** @param s 消息内容*/@Overridepublic void onMessage(String s) {// 如果是json数据,可以将json转为对象OrderExt orderExt = JSON.parseObject(s, OrderExt.class);System.out.println(orderExt);}}

上例实现了RocketMQ传输JSON消息的过程,消费端在接收到JSON手动将JSON转成对象,也可以自动转换成对象,定义新的监听类,RocketMQListener泛型指定要转换的对象类型

在这里插入图片描述

6、延迟消息

6.1、延迟消息介绍

延迟消息也叫作定时消息,比如在电商项目的交易系统中,当用户下单之后超过一段时间之后仍然没有支付,此时就需要将该订单关l闭。

要实现该功能的话,可以在用户创建订单时就发送一条包含订单内容的延迟消息,该消息在一段时间之后投递给消息消费者,当消息消费者接收到该消息后,判断该订单的支付状态,如果处于未支付状态,则将该订单关闭。

RocketMQ的延迟消息实现非常简单,只需要发送消息前设置延迟的时间,延迟时间存在十八个等级
(1s/5s/10s/30s/1m/2m/3m/4m/5m/6m/7m/8m/9m/10m/20m/30m/1h/2h),调用setDelayTimeLevel()设置与时间相对应的延迟级别即可。

6.2、同步消息延迟发送

生产端:

    /*** 发送同步延迟消息(消息内容为json格式)** @param topic     主题* @param orderExt  消息体*/public void sendMsgByJsonDelay(String topic, OrderExt orderExt) {// 发送同步消息,消息内容将orderExt转为jsonMessage<OrderExt> message = MessageBuilder.withPayload(orderExt).build();// 指定发送超时时间(毫秒)和延迟等级this.rocketMQTemplate.syncSend(topic, message, 1000, 3);System.out.printf("send msg : %s", orderExt);}

消费端监听:

/*** 消费者监听类* * @author yixiujun* @version Id: ConsumerSimple.java, v 0.1 Administrator Exp $$* @date 2023-02-19 16:48:16*/
@Component
@RocketMQMessageListener(topic = "my-topic-obj", consumerGroup = "demo-consumer-group-obj")
public class ConsumerUserDefineSimple implements RocketMQListener<OrderExt> {/*** 根据泛型默认接收将接收到的json数据转化为对应的实体类** @param orderExt json对应实体*/@Overridepublic void onMessage(OrderExt orderExt) {System.out.println(orderExt);}
}

单元测试:

    /*** 测试发送同步延迟消息*/@Testpublic void testSendMsgByJsonDelay() {OrderExt orderExt = new OrderExt();orderExt.setId(UUID.randomUUID().toString());orderExt.setCreateTime(new Date());orderExt.setMoney(20000L);orderExt.setTitle("测试订单");this.producerUserDefineSimple.sendMsgByJsonDelay("my-topic-obj", orderExt);System.out.println("end……");}

在这里插入图片描述

6.3、异步消息延迟发送

生产端:

    /*** 发送异步延迟消息(消息内容为json格式)** @param topic     主题* @param orderExt  消息体*/public void sendAsyncMsgByJsonDelay(String topic, OrderExt orderExt) throws JsonProcessingException, RemotingException, InterruptedException, MQClientException {// 消息内容将orderExt转为jsonObjectMapper objectMapper = new ObjectMapper();String jsonData = objectMapper.writeValueAsString(orderExt);org.apache.rocketmq.common.message.Message message = new org.apache.rocketmq.common.message.Message(topic, jsonData.getBytes(StandardCharsets.UTF_8));// 设置延迟等级message.setDelayTimeLevel(3);// 发送异步消息this.rocketMQTemplate.getProducer().send(message, new SendCallback() {@Overridepublic void onSuccess(SendResult sendResult) {try {System.out.println(objectMapper.writeValueAsString(sendResult));} catch (JsonProcessingException e) {e.printStackTrace();}}@Overridepublic void onException(Throwable throwable) {System.out.println(throwable.getMessage());}});System.out.printf("send msg : %s",orderExt);}

消费端监听:

/*** 消费者监听类* * @author yixiujun* @version Id: ConsumerSimple.java, v 0.1 Administrator Exp $$* @date 2023-02-19 16:48:16*/
@Component
@RocketMQMessageListener(topic = "my-topic-obj", consumerGroup = "demo-consumer-group-obj")
public class ConsumerUserDefineSimple implements RocketMQListener<OrderExt> {/*** 根据泛型默认接收将接收到的json数据转化为对应的实体类** @param orderExt json对应实体*/@Overridepublic void onMessage(OrderExt orderExt) {System.out.println(orderExt);}
}

单元测试:

	/*** 测试发送异步延迟消息* * @throws InterruptedException* @throws RemotingException* @throws JsonProcessingException* @throws MQClientException*/@Testpublic void testSendAsyncMsgByJsonDelay() throws InterruptedException, RemotingException, JsonProcessingException, MQClientException {OrderExt orderExt = new OrderExt();orderExt.setId(UUID.randomUUID().toString());orderExt.setCreateTime(new Date());orderExt.setMoney(30000L);orderExt.setTitle("测试订单");this.producerUserDefineSimple.sendAsyncMsgByJsonDelay("my-topic-obj", orderExt);System.out.println("end……");Thread.sleep(20000);}

在这里插入图片描述

启动消费者,查看控制台,生产者发送几次,消费者只要监听到就会接收:

在这里插入图片描述

7、消费重试

7.1、什么是消费重试

当消息发送到Broker成功,在被消费者消费时如果消费者没有正常消费,此时消息会重试消费,消费重试存在两种场景:

  1. 消息没有被消费者接收,比如消费者与broker存在网络异常。此种情况消息会一直被消费重试。
  2. 当消息已经被消费者成功接收,但是在进行消息处理时出现异常,消费端无法向Broker返回成功,这种情况下RocketMQ会不断重试。

针对第二种消费重试的场景,borker是怎么知道重试呢?

消费者在消费消息成功会向broker返回成功状态,否则会不断进行消费重试。

7.2、处理策略

当消息在消费时出现异常,此时消息被不断重试消费。RocketMQ会一直重试消费吗?

答案是不会!

消息会按照延迟消息的延迟时间等级(1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h)从第3级开始重试,每试一次如果还不成功则延迟等级加1。

比如:一条消息消费失败,等待10s(第3级)进行重试,如果还没有被成功消费则延迟等级加1,即按第4级别延迟等待,等30s继续进行重试,如此进行下去,直到重试16次。

当重试了16次还未被成功消费将会投递到死信队列,到达死信队列的消息将不再被消费。

实际生产中的处理策略是什么呢?

实际生产中不会让消息重试这么多次,通常在重试一定的次数后将消息写入数据库,由另外单独的程序或人工去处理。

项目使用的Spring整合RocketMQ的方式,消费者实现RocketMQListeneronMessage方法,在此方法中实现处理策略的示例代码如下:

/*** 消费者监听类** @author yixiujun* @version Id: ConsumerSimple.java, v 0.1 Administrator Exp $$* @date 2023-02-19 16:48:16*/
@Component
@RocketMQMessageListener(topic = "my-topic-obj", consumerGroup = "demo-consumer-group-obj")
public class ConsumerUserDefineSimple implements RocketMQListener<MessageExt> {/*** 根据泛型默认接收将接收到的json数据转化为对应的实体类** @param messageExt 消息实体*/@Overridepublic void onMessage(MessageExt messageExt) {// 取出当前重试次数int reconsumeTimes = messageExt.getReconsumeTimes();// 当大于一定的次数后将消息写入数据库,由单独的程序或人工去处理if (reconsumeTimes >= 2) {// 将消息写入数据库,之后正常返回// ……return;}throw new RuntimeException(String.format("第%s次处理失败..",reconsumeTimes));}}

处理策略可根据实际业务场景需要自定义后续操作处理。

妥了,简单入门就先到这!


在这里插入图片描述


相关文章:

RocketMQ快速入门:消息发送、延迟消息、消费重试

一起学编程&#xff0c;让生活更随和&#xff01; 如果你觉得是个同道中人&#xff0c;欢迎关注博主gzh&#xff1a;【随和的皮蛋桑】。 专注于Java基础、进阶、面试以及计算机基础知识分享&#x1f433;。偶尔认知思考、日常水文&#x1f40c;。 目录1、RocketMQ消息结构1.1…...

FANUC机器人通过KAREL程序实现与PLC位置坐标通信的具体方法示例

FANUC机器人通过KAREL程序实现与PLC位置坐标通信的具体方法示例 在通信IO点位数量足够的情况下,可以使用机器人的IO点传输位置数据,这里以传输机器人的实时位置为例进行说明。 基本流程如下图所示: 基本步骤可参考如下: 首先确认机器人控制柜已经安装了总线通信软件(例如…...

[蓝桥杯 2015 省 B] 移动距离

蓝桥杯 2015 年省赛 B 组 H 题题目描述X 星球居民小区的楼房全是一样的&#xff0c;并且按矩阵样式排列。其楼房的编号为 1,2,3,⋯ 。当排满一行时&#xff0c;从下一行相邻的楼往反方向排号。比如&#xff1a;当小区排号宽度为 6 时&#xff0c;开始情形如下&#xff1a;我们的…...

Pandas库入门仅需10分钟

数据处理的时候经常性需要整理出表格&#xff0c;在这里介绍pandas常见使用&#xff0c;目录如下&#xff1a; 数据结构导入导出文件对数据进行操作 – 增加数据&#xff08;创建数据&#xff09; – 删除数据 – 改动数据 – 查找数据 – 常用操作&#xff08;转置&#xff0…...

python的socket通信中,如何设置可以让两台主机通过外网访问?

要让两台主机通过外网进行Socket通信&#xff0c;需要在网络设置和代码实现两个方面进行相应的配置。下面是具体的步骤&#xff1a; 确认网络环境&#xff1a;首先要确保两台主机都能够通过外网访问。可以通过ping命令或者telnet命令来测试两台主机之间是否可以互相访问。 确定…...

检测数据的方法(回顾)

检测数据类型的4种方法typeofinstanceofconstructor{}.toString.call() 检测数据类型的4种方法 typeof 定义 用来检测数据类型的运算符 返回一个字符串&#xff0c;表示操作值的数据类型(7种) number&#xff0c;string&#xff0c;boolean&#xff0c;object&#xff0c;u…...

比特数据结构与算法(第三章_上)栈的概念和实现(力扣:20. 有效的括号)

一、栈&#xff08;stack&#xff09;栈的概念&#xff1a;① 栈是一种特殊的线性表&#xff0c;它只允许在固定的一端进行插入和删除元素的操作。② 进行数据插入的删除和操作的一端&#xff0c;称为栈顶 。另一端则称为 栈底 。③ 栈中的元素遵守后进先出的原则&#xff0c;即…...

JVM13 类的生命周期

1. 概述 在 Java 中数据类型分为基本数据类型和引用数据类型。基本数据类型由虚拟机预先定义&#xff0c;引用数据类型则需要进行类的加载。 按照 Java 虚拟机规范&#xff0c;从 class 文件到加载到内存中的类&#xff0c;到类卸载出内存为止&#xff0c;它的整个生命周期包…...

Docker网络模式解析

目录 前言 一、常用基本命令 &#xff08;一&#xff09;查看网络 &#xff08;二&#xff09;创建网络 &#xff08;三&#xff09;查看网络源数据 &#xff08;四&#xff09;删除网络 二、网络模式 &#xff08;一&#xff09;总体介绍 &#xff08;二&#xff09…...

游山城重庆

山城楼梯多&#xff0c;路都是上坡。 为了赶早上8点从成都到重庆的动车&#xff0c;凌晨5点半就爬起床来&#xff0c;由于昨天喝了咖啡&#xff0c;所以我将尽3点才睡觉&#xff0c;这意味着我只睡了2个多小时。起来简单休息之后&#xff0c;和朋友协商好时间就一起出门了。 …...

Vuex的创建和简单使用

Vuex 1.简介 1.1简介 1.框框里面才是Vuex state&#xff1a;状态数据action&#xff1a;处理异步mutations&#xff1a;处理同步&#xff0c;视图可以同步进行渲染1.2项目创建 1.vue create 名称 2.运行后 3.下载vuex。采用的是基于vue2的版本。 npm install vuex3 --save 4.vu…...

Arduino IDE搭建Heltec开发板开发环境

Arduino IDE搭建Heltec开发板开发环境Heltec开发板开发环境下载与搭建Arduino IDE下载与安装搭建Heltec开发板的开发环境添加package URL方法通过Git的方法安装离线安装Heltec开发板开发环境下载与搭建 Arduino IDE下载与安装 Heltec的ESP系列和大部分的LoRa系列开发板都是用A…...

Using the GNU Compiler Collection 目录翻译

文章目录Introduction1 Programming Languages Supported by GCC2 Language Standards Supported by GCC2.1 C Language3 GCC Command Options3.1 Option Summary4 C Implementation-Defined Behavior6 Extensions to the C Language Family9 Binary Compatibility其他工具10 g…...

使用 OpenCV for Android 进行图像特征检测

android 开发人员&#xff0c;可能熟悉使用activities, fragments, intents以及最重要的一系列开源依赖库。但是&#xff0c;注入需要本机功能的依赖关系(如计算机视觉框架)并不像在 gradle 文件中直接添加实现语句那样简单&#xff01;今天&#xff0c;将专注于使用 OpenCV 库…...

chatGPT笔记

文章目录 一、GPT之技术演进时间线二、chatGPT中的语言模型instructGPT跟传统语言LM模型最大不同点是什么?三、instructGPT跟GPT-3的网络结构是否一样四、GPT和BERT有啥区别五、chatGPT的训练过程是怎样的?六、GPT3在算数方面的能力七、GPT相比于bert的优点是什么八、元学习(…...

这么好的政策和创新基地,年轻人有梦想你就来

周末有空去参观了下一个朋友办的公司。位置和环境真不错&#xff0c;且租金低的离谱&#xff0c;半年租金才2000元&#xff0c;且提供4个工位。这个创新基地真不赖啊&#xff0c;国家鼓励创新创业&#xff0c;助力年轻人实现梦想。场地有办公区&#xff0c;休息区应有尽有&…...

【Kubernetes】【十九】安全认证

第九章 安全认证 本章节主要介绍Kubernetes的安全认证机制。 访问控制概述 ​ Kubernetes作为一个分布式集群的管理工具&#xff0c;保证集群的安全性是其一个重要的任务。所谓的安全性其实就是保证对Kubernetes的各种客户端进行认证和鉴权操作。 客户端 在Kubernetes集群…...

Apache Flink 实时计算在美的多业务场景下的应用与实践

摘要&#xff1a;本文整理自美的集团实时数据负责人、资深数据架构师董奇&#xff0c;在 Flink Forward Asia 2022 主会场的分享。本篇内容主要分为四个部分&#xff1a; 实时生态系统在美的的发展和建设现状 核心传统业务场景 Flink 实时数字化转型实践 新兴业务场景 Flink …...

27 pandas 数据透视

文章目录pivot_table 函数1、index需要聚合的列名&#xff0c;默认情况下聚合所有数据值的列2、values在结果透视的行上进行分组的列名或其它分组键【就是透视表里显示的列】3、columns在结果透视表的列上进行分组的列名或其它分组键4、Aggfunc聚合函数或函数列表&#xff08;默…...

1.2 学习环境准备

文章目录1.MariaDB简介2.MariaDB服务端和客户端安装1.MariaDB简介 因为MariaDB作为MySQL的延申&#xff0c;其包含MySQL所有的有点&#xff0c;并且其包含了更丰富的特性。比如微秒的支持、线程池、子查询优化、组提交、进度报告等&#xff1b; 所以我们接下来将已MariaDB作为…...

Java持久层技术对比:Hibernate、MyBatis与JPA的选择与应用

目录 简介持久层技术概述Hibernate详解MyBatis详解JPA详解技术选型对比最佳实践与应用场景性能优化策略未来发展趋势总结与建议 简介 在Java企业级应用开发中&#xff0c;持久层&#xff08;Persistence Layer&#xff09;作为连接业务逻辑与数据存储的桥梁&#xff0c;其技…...

字符串 金额转换

package heima.Test09;import java.util.Scanner;public class Money {public static void main(String[] args) {//1。键盘录入一个金额Scanner sc new Scanner(System.in);//请输入一个数据String result "";int money;while (true) {System.out.println("请…...

应用案例 | 设备分布广, 现场维护难? 宏集Cogent DataHub助力分布式锅炉远程运维, 让现场变“透明”

在日本&#xff0c;能源利用与环保问题再次成为社会关注的焦点。越来越多的工业用户开始寻求更高效、可持续的方式来运营设备、管理能源。而作为一家专注于节能与自动化系统集成的企业&#xff0c;日本大阪的TESS工程公司给出了一个值得借鉴的答案。 01 锅炉远程监控难题如何破…...

逻辑回归与Softmax

Softmax函数是一种将一个含任意实数的K维向量转化为另一个K维向量的函数,这个输出向量的每个元素都在(0, 1)区间内,并且所有元素之和等于1。 因此,它可以被看作是某种概率分布,常用于多分类问题中作为输出层的激活函数。这里我们以拓展逻辑回归解决多分类的角度对Softmax函…...

高股息打底+政策催化增强+永续经营兜底

通过分析农业银行&#xff08;政策红利高股息&#xff09;与长江电力&#xff08;垄断资源现金流堡垒&#xff09;的共性&#xff0c;提炼出以下策略框架&#xff1a; ​​1. 核心筛选标准​​ • 高股息防御性&#xff1a;股息率>3%&#xff0c;分红率稳定&#xff08;40%…...

SoloSpeech - 高质量语音处理模型,一键提取指定说话人音频并提升提取音频清晰度和质量 本地一键整合包下载

视频教程&#xff1a; 一个强大的语音分离和降噪软件 SoloSpeech 是由约翰霍普金斯大学、香港中文大学、南洋理工大学、清华大学及布拉格理工大学等多所高校共同主导开源的一个创新的语音处理项目&#xff0c;旨在解决在多人同时说话的环境中&#xff0c;准确提取并清晰呈现特定…...

简化复杂系统的优雅之道:深入解析 Java 外观模式

一、外观模式的本质与核心价值 在软件开发的世界里&#xff0c;我们经常会遇到这样的场景&#xff1a;一个复杂的子系统由多个相互协作的类组成&#xff0c;这些类之间可能存在错综复杂的依赖关系和交互逻辑。当外部客户端需要使用这个子系统时&#xff0c;往往需要了解多个类…...

【Linux命令学习】获取cpu信息 - lscpu命令学习

lscpu命令显示的是服务器cpu架构相关信息&#xff0c;lscpu从伪文件系统(sysfs)、/proc/cpuinfo和任何可用的特定体系架构库中收集cpu架构信息。输出内容包括&#xff1a;CPU、线程、内核的数量以及非同一存储器存取节点。此外还包括关于CPU高速缓存和高速缓存共享的信息&#…...

GPU加速与非加速的深度学习张量计算对比Demo,使用PyTorch展示关键差异

import torch import time # 创建大型随机张量 (10000x10000) tensor_size 10000 x_cpu torch.randn(tensor_size, tensor_size) x_gpu x_cpu.cuda() # 转移到GPU # CPU矩阵乘法 start time.time() result_cpu torch.mm(x_cpu, x_cpu.t()) cpu_time time.time() - sta…...

Python 训练营打卡 Day 33-神经网络

简单神经网络的流程 1.数据预处理&#xff08;归一化、转换成张量&#xff09; 2.模型的定义 继承nn.Module类 定义每一个层 定义前向传播流程 3.定义损失函数和优化器 4.定义训练过程 5.可视化loss过程 预处理补充&#xff1a; 分类任务中&#xff0c;若标签是整…...