四、JMS规范

JMS规范

  • 一、JMS是什么
  • 二、MQ中间件对比
  • 三、JMS组成
    • 1.JMS Provider
    • 2.JMS Producer
    • 3.JMS Consumer
    • 4.JSM Message
      • 4.1 消息头
      • 4.2 消息体
        • 4.2.1 生产者
        • 4.2.2 消费者
      • 4.3 消息属性
  • 四、JMS可靠性
    • 1.PERSISTENT - 持久化
      • 1.1 参数设置
      • 1.2 Queue持久化
      • 1.3 Topic持久化
        • 1.3.1 持久的发布主题生产者
        • 1.3.2 持久的订阅主题消费者
    • 2.Transaction - 事务
      • 2.1 生产者开启事务
      • 2.2 消费者开启事务
    • 3.Acknowledge - 签收
      • 3.1 案例-手动签收
    • 4.签收和事务的关系

一、JMS是什么

  • 首先需要区分JavaSE、JavaEE、JMS
    • JavaSE:是一门编程语言
    • JavaEE:是一套使用Java进行企业级应用开发的大家一致遵循的13个核心规范工业标准。JavaEE平台提供了一个基于组件的方法来加快设计,开发。装配及部署企业应用程序。
      • DBC(Java Databease)数据库连接
      • JNDI(Java Naming and Directory Interfaces)Java的命令和目录接口
      • EJB(Enterprise JavaBean)
      • RMI(Remote Method Invoke)远程方法调用
      • Java IDL(Interface Description Language)/CORBA(Common Object Broker Architecture)接口定义语言/共用对象请求代理程序体系结构
      • JSP(Java Server Page)
      • Servlet
      • XML(Extensible Markup Language)可标记白标记语言
      • JMS(Java Message Service)Java消息服务
      • JTA(Java Transaction API)Java事务API
      • JTS(Java Transaction Service)Java事务服务
      • JavaMail
      • JAF(JavaBean Activation Framework)
  • JMS(Java Message Service)是JavaEE中的一个技术,是消息服务
    • Java消息服务:指的是两个应用程序之间进行异步通信的API,它为标准协议和消息服务提供了一组通用接口,包括创建、发送、读取消息等,用于支持Java应用程序开发。在JavaEE中,当两个应用程序使用JMS进行通信时,它们之间不是直接相连的,而是通过一个共同的消息收发服务组件关联起来以达到解耦/异步削峰的效果。
      在这里插入图片描述

二、MQ中间件对比

特性ActiveMQRabbitMQKafkaRocketMQ
PRODUCER-CUMSUMER支持支持支持支持
PUBLISH-SUBSCRIBE支持支持支持支持
REQUEST-REPLY(请求-响应)支持支持-支持
API完备性低(静态配置)
多语言支持支持,Java优先语言无关支持,Java优先支持
单机吞吐量万级万级十万级单机万级
消息延迟-微秒级毫秒级-
可用性高(主从)高(主从)非常高(分布式)
消息丢失-理论上不会丢失-
消息重复-可控制理论上会有重复-
文档的完备性
提供快速入门
首次部署难度-

三、JMS组成

1.JMS Provider

  • 实现JMS接口和规范的消息中间件,也就是我们说的MQ服务器

2.JMS Producer

  • 消息生产者,创建和发送JMS消息的客户端应用

3.JMS Consumer

  • 消息消费者,接收和处理JMS消息的客户端应用

4.JSM Message

4.1 消息头

  • JMSDestination:消息发送的目的地,主要是指Queue和Topic
  • JMSDeliveryMode:持久模式和非持久模式。
    • 一条持久性的消息:应该被传送“一次仅仅一次”,这就意味着如果JMS提供者出现故障,该消息并不会丢失,它会在服务器恢复之后再次传递。
    • 一条非持久的消息:最多会传递一次,这意味着服务器出现故障,该消息将会永远丢失。
  • JMSExpiration:可以设置消息在一定时间后过期,默认是永不过期
    • 消息过期时间,等于Destination的send方法中的timeToLive值加上发送时刻的GMT时间值。
    • 如果timeToLive值等于0,则JMSExpiration被设为0,表示该消息永不过期。
    • 如果发送后,在消息过期时间之后还没有被发送到目的地,则该消息被清除。
  • JMSPriority:消息优先级,从0-9十个级别,0-4是普通消息5-9是加急消息。
    • JMS不要求MQ严格按照这十个优先级发送消息但必须保证加急消息要先于普通消息到达。默认是4级。
  • JMSMessageID:唯一标识每个消息的标识由MQ产生。

4.2 消息体

  • 封装具体的消息数据
  • 5种消息格式
    • TxtMessage:普通字符串消息,包含一个String
    • MapMessage:一个Map类型的消息,key为Strng类型,而值为Java基本类型
    • BytesMessage:二进制数组消息,包含一个byte[]
    • StreamMessage:Java数据流消息,用标准流操作来顺序填充和读取
    • ObjectMessage:对象消息,包含一个可序列化的Java对象
  • 注意:发送和接收的消息体类型必须一致对应
4.2.1 生产者
package com.qingsi.activemq;import org.apache.activemq.ActiveMQConnectionFactory;import javax.jms.*;public class JmsProduce {public static final String ACTIVEMQ_URL = "tcp://192.168.86.128:61616";public static final String QUEUE_NAME = "queue01";public static void main(String[] args) throws JMSException {// 1.创建连接工厂, 采用默认的用户名密码ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);// 2.通过连接工厂,获得connection并启动访问Connection connection = activeMQConnectionFactory.createConnection();connection.start();// 3.创建会话session// 两个参数,第一个叫事务,第二个叫签收Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);// 4.创建目的地(是队列还是主题)Queue queue = session.createQueue(QUEUE_NAME);// 5.创建消息的生产者MessageProducer producer = session.createProducer(queue);// 6.使用生产者生成3条消息发送到MQ队列for (int i = 1; i <= 3; i++) {// 7.1 创建文本消息TextMessage textMessage = session.createTextMessage("msg--" + i);// 最简单的字符串producer.send(textMessage);// 7.2 创建Map类型的消息MapMessage mapMessage = session.createMapMessage();mapMessage.setString("k1", "v1");producer.send(mapMessage);// 7.3 创建 BytesMessageBytesMessage bytesMessage = session.createBytesMessage();bytesMessage.writeBytes("hello".getBytes());bytesMessage.writeBytes("world".getBytes());producer.send(bytesMessage);// 7.4 创建 StreamMessageStreamMessage streamMessage = session.createStreamMessage();streamMessage.writeString("hello");streamMessage.writeInt(123);producer.send(streamMessage);// 7.5 创建 ObjectMessage// ObjectMessage objectMessage = session.createObjectMessage();// MyObject myObject = new MyObject();// myObject.setName("张三");// myObject.setAge(20);// objectMessage.setObject(myObject);// producer.send(objectMessage);}// 9.关闭资源producer.close();session.close();connection.close();System.out.println("MQ消息发布完成");}}
4.2.2 消费者
package com.qingsi.activemq;import org.apache.activemq.ActiveMQConnectionFactory;import javax.jms.*;
import java.io.IOException;public class JmsConsumer {public static final String ACTIVEMQ_URL = "tcp://192.168.86.128:61616";public static final String QUEUE_NAME = "queue01";public static void main(String[] args) throws JMSException, IOException {// 1.创建连接工厂, 采用默认的用户名密码ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);// 2.通过连接工厂,获得connection并启动访问Connection connection = activeMQConnectionFactory.createConnection();connection.start();// 3.创建会话session// 两个参数,第一个叫事务,第二个叫签收Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);// 4.创建目的地(是队列还是主题)Queue queue = session.createQueue(QUEUE_NAME);// 5.创建消息的消费者MessageConsumer consumer = session.createConsumer(queue);// 6.通过监听的方式来消费消息consumer.setMessageListener(new MessageListener() {@Overridepublic void onMessage(Message message) {if (message instanceof TextMessage) {TextMessage textMessage = (TextMessage) message;try {System.out.println("消费者消费消息:" + textMessage.getText());} catch (JMSException e) {e.printStackTrace();}}if (message instanceof MapMessage) {MapMessage mapMessage = (MapMessage) message;try {System.out.println("消费者消费map消息:" + mapMessage.getString("k1"));} catch (JMSException e) {e.printStackTrace();}}if (message instanceof BytesMessage) {BytesMessage bytesMessage = (BytesMessage) message;byte[] bytes = new byte[0];try {bytes = new byte[(int) bytesMessage.getBodyLength()];} catch (JMSException e) {e.printStackTrace();}try {bytesMessage.readBytes(bytes);} catch (JMSException e) {e.printStackTrace();}String content = new String(bytes);System.out.println("消费者消费 BytesMessage 消息:" + content);}if (message instanceof StreamMessage) {StreamMessage streamMessage = (StreamMessage) message;String text = null;try {text = streamMessage.readString();} catch (JMSException e) {e.printStackTrace();}int number = 0;try {number = streamMessage.readInt();} catch (JMSException e) {e.printStackTrace();}System.out.println("消费者消费 StreamMessage 消息:" + text + ", " + number);}// if (message instanceof ObjectMessage) {//     ObjectMessage objectMessage = (ObjectMessage) message;//     Serializable object = objectMessage.getObject();//     if (object instanceof MyObject) {//        MyObject myObject = (MyObject) object;//        System.out.println("消费者消费 ObjectMessage 消息:" + myObject.getName() + ", " + myObject.getAge());//    }//}}});// 保证控制台不关掉System.in.read();consumer.close();session.close();connection.close();}
}

4.3 消息属性

  • 如果需要除消息字段以外的值,那么可以使用消息属性
  • 识别/去重/重点标注等操作非常有用的方法
  • 有以下API
    在这里插入图片描述

四、JMS可靠性

1.PERSISTENT - 持久化

1.1 参数设置

  • 非持久:当服务器宕机,消息不存在。
    • messageProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT)
  • 持久:持久化:当服务器宕机,消息依然存在。
    • messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT)

1.2 Queue持久化

  • Queue默认是持久

1.3 Topic持久化

  • 场景:只要订阅了之后,离线了重新上线,就会继续消费
    • 类似微信公众号
  • 注意:先启动定阅消费者再启动定阅生产者
  • 当所有的消息必须被接收,则用持久订阅。当消息丢失能够被容忍,则用非持久订阅
1.3.1 持久的发布主题生产者
package com.qingsi.activemq;import org.apache.activemq.ActiveMQConnectionFactory;import javax.jms.*;public class JmsTopicProduce {public static final String ACTIVEMQ_URL = "tcp://192.168.86.128:61616";public static final String TOPIC_NAME = "topic01";public static void main(String[] args) throws JMSException {// 1.创建连接工厂, 采用默认的用户名密码ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);// 2.通过连接工厂,获得connection并启动访问Connection connection = activeMQConnectionFactory.createConnection();// 3.创建会话session// 两个参数,第一个叫事务,第二个叫签收Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);// 4.创建目的地(是队列还是主题)Topic topic = session.createTopic(TOPIC_NAME);// 5.创建消息的生产者MessageProducer producer = session.createProducer(topic);//6.设置生产者生产持久化的Topicproducer.setDeliveryMode(DeliveryMode.PERSISTENT);//7.启动连接connection.start();// 8.使用生产者生成3条消息发送到MQ主题for (int i = 1; i <= 3; i++) {// 9.创建消息TextMessage textMessage = session.createTextMessage("msg-topic--" + i);// 最简单的字符串// 10.通过producer发送给mqproducer.send(textMessage);}// 11.关闭资源producer.close();session.close();connection.close();System.out.println("MQ消息发布到topic完成");}}
1.3.2 持久的订阅主题消费者
package com.qingsi.activemq;import org.apache.activemq.ActiveMQConnectionFactory;import javax.jms.*;
import java.io.IOException;public class JmsTopicConsumer {public static final String ACTIVEMQ_URL = "tcp://192.168.86.128:61616";public static final String TOPIC_NAME = "topic01";public static void main(String[] args) throws JMSException, IOException {System.out.println("我是1号消费者");// 1.创建连接工厂, 采用默认的用户名密码ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);// 2.通过连接工厂,获得connection并启动访问Connection connection = activeMQConnectionFactory.createConnection();connection.setClientID("王五");// 3.创建会话session// 两个参数,第一个叫事务,第二个叫签收Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);// 4.创建目的地(是队列还是主题)Topic topic = session.createTopic(TOPIC_NAME);//5.通过session创建持久化订阅TopicSubscriber topicSubscriber = session.createDurableSubscriber(topic, "我是王五");//6.启动连接connection.start();// 7.通过监听的方式来消费消息topicSubscriber.setMessageListener(new MessageListener() {@Overridepublic void onMessage(Message message) {if (message instanceof TextMessage){TextMessage textMessage = (TextMessage) message;try {System.out.println("我是1号消费者消费消息:" + textMessage.getText());} catch (JMSException e) {e.printStackTrace();}}}});System.in.read();session.close();connection.close();}
}

订阅者在线
在这里插入图片描述

订阅者离线

  • 这个必须订阅(启动过一次程序)过一次才行
    在这里插入图片描述

2.Transaction - 事务

  • 事务偏生产者
  • 注意:如果生产者开了事务,那么签收默认就是自动签收(指定了其他签收类型,也是自动签收)
  • Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)
    • createSession的第一个参数决定是否开启。如果开启了 需要提交事务才会起效
    • 关闭事务:只要执行send,就进入到队列中。关闭事务,那第2个签收参数的设置需要有效
    • 开启事务:先执行send再执行commit,消息才被真正提交到队列中。消息需要批量提交,需要缓冲处理。
      • 如果开启了事务,那么级别是比签收更高一些。
  • 事务场景:涉及到一次性发送两条及以上的消息,那么需要使用事务。
  • 容易出现的生产事故:消费者开启了事务,但是没有commit,就会造成消息重复消费。

2.1 生产者开启事务

package com.qingsi.activemq;import org.apache.activemq.ActiveMQConnectionFactory;import javax.jms.*;public class JmsProduce {public static final String ACTIVEMQ_URL = "tcp://192.168.86.128:61616";public static final String QUEUE_NAME = "queue01";public static void main(String[] args) throws JMSException {//1.创建连接工厂,按照给定的URL,采用默认的用户名密码ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);//2.通过连接工厂,获得connection并启动访问Connection connection = activeMQConnectionFactory.createConnection();connection.start();//3.创建会话session//两个参数transacted=事务,acknowledgeMode=确认模式(签收)//开启事务需要commitSession session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);//4.创建目的地(具体是队列queue还是主题topic)Queue queue = session.createQueue(QUEUE_NAME);//5.创建消息的生产者,并设置不持久化消息MessageProducer producer = session.createProducer(queue);//6.通过使用消息生产者,生产三条消息,发送到MQ的队列里面try {for (int i = 0; i < 3; i++) {TextMessage textMessage = session.createTextMessage("tx msg--" + i);producer.send(textMessage);}//7.提交事务session.commit();System.out.println("消息发送完成");} catch (Exception e) {System.out.println("出现异常,消息回滚");session.rollback();} finally {//8.关闭资源producer.close();session.close();connection.close();}}}

2.2 消费者开启事务

package com.qingsi.activemq;import org.apache.activemq.ActiveMQConnectionFactory;import javax.jms.*;public class JmsConsumer {public static final String ACTIVEMQ_URL = "tcp://192.168.86.128:61616";public static final String QUEUE_NAME = "queue01";public static void main(String[] args) throws JMSException {//1.创建连接工厂,按照给定的URL,采用默认的用户名密码ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);//2.通过连接工厂,获得connection并启动访问Connection connection = activeMQConnectionFactory.createConnection();connection.start();//3.创建会话session//两个参数transacted=事务,acknowledgeMode=确认模式(签收)//消费者开启了事务就必须手动提交,不然会重复消费消息Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);//4.创建目的地(具体是队列queue还是主题topic)Queue queue = session.createQueue(QUEUE_NAME);//5.创建消息的消费者,指定消费哪一个队列里面的消息MessageConsumer messageConsumer = session.createConsumer(queue);//6.通过监听的方式消费消息messageConsumer.setMessageListener(new MessageListener() {int a = 0;@Overridepublic void onMessage(Message message) {if (message instanceof TextMessage) {try {if (a == 2) {System.out.println(1 / 0);}TextMessage textMessage = (TextMessage) message;System.out.println("***消费者接收到的消息:   " + textMessage.getText());session.commit();a = a + 1;} catch (Exception e) {System.out.println("出现异常,消费失败,放弃消费");try {session.rollback();a=0;} catch (JMSException ex) {ex.printStackTrace();}}}}});//7.关闭资源}
}

3.Acknowledge - 签收

  • 签收偏消费者
  • 签收(Acknowledge)是指消费者告知消息代理(Broker)已经成功处理并消费了特定消息的操作。
  • 签收的作用主要有以下几点:
    • 1.确保可靠性:当消费者接收到一条消息时,可以对该消息进行签收。通过签收,消费者向 Broker 表示已经成功处理了该消息,并且要求 Broker 删除该消息或将其标记为已消费,以确保消息不会再次被传递给其他消费者。
    • 2.消息顺序:签收还可以控制消息的消费顺序。在 ActiveMQ 中,可以使用消息的签收方式来控制消息的顺序性。例如,如果消费者使用手动签收模式(MANUAL_ACKNOWLEDGE),消费者可以在处理完当前消息后再进行签收,这样可以确保消息按照顺序进行消费。
    • 3.事务支持:签收和事务密切相关。在使用事务模式时,消费者可以批量消费多条消息,并在事务提交时进行签收。如果事务回滚,则消息将被重新传递给消费者,以确保消息的可靠性处理。
  • 签收是非事务的
  • 签收类型(以下标红的是常用):
    • 自动签收(默认):Session.AUTO_ACKNOWLEDGE
      • 在这种模式下,当消费者从队列或主题中接收到消息后,消息代理会立即将该消息视为已经被消费,不需要消费者显式地调用acknowledge()方法进行确认。因此,存在一定的消息传递风险,因为如果消费者在处理消息期间发生故障,消息可能会丢失。
    • 手动签收:Session.CLIENT_ACKNOWLEDGE
      • 在这种模式下,消费者必须显式地调用acknowledge()方法来确认消息的接收。消费者可以在处理完消息后手动调用acknowledge()方法,以通知消息代理该消息已成功处理。这种方式能够确保消息在被消费后才会被视为已被消费,从而增加了消息传递的可靠性。
    • 延迟确认:Session.DUPS_OK_ACKNOWLEDGE。
      • 消费者不需要在接收消息时就立即确认。消息代理会允许消息重复传递,但是这种模式可以提高消息的传递性能。消费者可以在后续的某个时间点调用acknowledge()方法来确认消息的接收。
    • 事务签收:Session.SESSION_TRANSACTED(事务签收)
      • 在使用会话(Session)进行消息接收时,可以选择开启事务,并在事务提交时进行消息的确认。这种方式可以确保一组消息要么全部被消费,要么全部不被消费,从而保证消息的一致性和可靠性。

3.1 案例-手动签收

package com.qingsi.activemq;import org.apache.activemq.ActiveMQConnectionFactory;import javax.jms.*;
import java.io.IOException;public class JmsConsumer {public static final String ACTIVEMQ_URL = "tcp://192.168.86.128:61616";public static final String QUEUE_NAME = "queue01";public static void main(String[] args) throws JMSException, IOException {//1.创建连接工厂,按照给定的URL,采用默认的用户名密码ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);//2.通过连接工厂,获得connection并启动访问Connection connection = activeMQConnectionFactory.createConnection();connection.start();//3.创建会话session//两个参数transacted=事务,acknowledgeMode=确认模式(签收)//消费者开启了事务就必须手动提交,不然会重复消费消息Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);//4.创建目的地(具体是队列queue还是主题topic)Queue queue = session.createQueue(QUEUE_NAME);//5.创建消息的消费者,指定消费哪一个队列里面的消息MessageConsumer messageConsumer = session.createConsumer(queue);//6.通过监听的方式消费消息messageConsumer.setMessageListener(new MessageListener() {@Overridepublic void onMessage(Message message) {if (message instanceof TextMessage) {try {TextMessage textMessage = (TextMessage) message;System.out.println("***消费者接收到的消息:   " + textMessage.getText());// 手动签收textMessage.acknowledge();} catch (Exception e) {System.out.println("出现异常,消费失败,放弃消费");}}}});//7.关闭资源System.in.read();messageConsumer.close();session.close();connection.close();}
}

4.签收和事务的关系

  • 在事务性会话中,当一个事务被成功提交则消息被自动签收。如果事务回滚,则消息会被再次传送。
  • 非事务性会话中,消息何时被确认取决于创建会话时的应答模式(acknowledgement mode)

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

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

相关文章

Linux文件操作类命令 touch | stat | cp | scp | alias | mv | dd | cat | head | tail

touch 1.创建空文件&#xff08;只有元数据信息&#xff0c;没有数据段内容&#xff09;touch 1.txt 2.对创建或已经存在的文件改变元数据信息的时间记录值-d 改变创建时间touch -d 20240101 1.txt -a改变访问时间 -m改变修改时间stat 查看元数据信息 Blocks是512字…

排序算法---桶排序

原创不易&#xff0c;转载请注明出处。欢迎点赞收藏~ 桶排序&#xff08;Bucket Sort&#xff09;是一种排序算法&#xff0c;它将待排序的数据分到几个有序的桶中&#xff0c;每个桶再分别进行排序&#xff0c;最后将各个桶中的数据按照顺序依次取出&#xff0c;即可得到有序序…

【机器学习笔记】 9 集成学习

集成学习方法概述 Bagging 从训练集中进行子抽样组成每个基模型所需要的子训练集&#xff0c;对所有基模型预测的结果进行综合产生最终的预测结果&#xff1a; 假设一个班级每个人的成绩都不太好&#xff0c;每个人单独做的考卷分数都不高&#xff0c;但每个人都把自己会做的…

在 Android 上部署自定义 YOLOv8 教程

在本教程中&#xff0c;我将向您展示如何在 Android 设备上使用自定义数据集部署 YOLOv8。想要了解如何在 Android 设备上使用您自己的数据集部署 YOLOv8&#xff1f;本文将展示如何操作。 Android 上的 自定义 YOLOv8 &#x1f525; ⚡️ 结果显示标题 对从 GoPro 流式传输到移…

Sora时代,我们的AI应该何去何从?——关于Sora大模型的思考

Sora时代&#xff0c;我们的AI应该何去何从?——关于Sora大模型的思考 一、Sora大模型&#xff1a;横空出世&#xff0c;让AI生成所有领域瑟瑟发抖二、Sora的出现代表了相关行业的灭亡&#xff1f;三、我们将何去何从&#xff1f; 一、Sora大模型&#xff1a;横空出世&#xf…

1.8 NLP自然语言处理

NLP自然语言处理 更多内容&#xff0c;请关注&#xff1a; github&#xff1a;https://github.com/gotonote/Autopilot-Notes.git 一、简介 seq2seq(Sequence to Sequence)是一种输入不定长序列&#xff0c;产生不定长序列的模型&#xff0c;典型的处理任务是机器翻译&#…

前端常见的设计模式

说到设计模式&#xff0c;大家想到的就是六大原则&#xff0c;23种模式。这么多模式&#xff0c;并非都要记住&#xff0c;但作为前端开发&#xff0c;对于前端出现率高的设计模式还是有必要了解并掌握的&#xff0c;浅浅掌握9种模式后&#xff0c;整理了这份文章。 六大原则&…

Linux第一个小程序-进度条

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 一、回车和换行 二、行缓冲区概念 三、倒计时 四、进度条代码 版本一&#xff1a; ​编辑 版本二&#xff1a; 总结 前言 世上有两种耀眼的光芒&#xff0c;一…

第七篇【传奇开心果系列】Python微项目技术点案例示例:数据可视化界面图形化经典案例

传奇开心果微博系列 系列微博目录Python微项目技术点案例示例系列 微博目录一、微项目开发背景和项目目标&#xff1a;二、雏形示例代码三、扩展思路介绍四、数据输入示例代码五、数据分析示例代码六、排名统计示例代码七、数据导入导出示例代码八、主题定制示例代码九、数据过…

蓝桥杯第十四届电子类单片机组程序设计

目录 前言 蓝桥杯大赛历届真题&#xff08;点击查看&#xff09; 一、第十四届比赛题目 1.比赛原题 2.题目解读 1&#xff09;任务要求 2&#xff09;注意事项 二、任务实现 1.NE555读取时机的问题 1&#xff09;缩短计数时间 2&#xff09;实时读取 2.温度传感器读…

<网络安全>《35 网络攻防专业课<第一课 - 网络攻防准备>》

1 主要内容 认识黑客 认识端口 常见术语与命令 网络攻击流程 VMWare虚拟环境靶机搭建 2 认识黑客 2.1 白帽、灰帽和黑帽黑客 白帽黑客是指有能力破坏电脑安全但不具恶意目的黑客。 灰帽黑客是指对于伦理和法律态度不明的黑客。 黑帽黑客经常用于区别于一般&#xff08;正面…

问题:在额定电压500V以下的电路中,使用的各种用电设备,一般称为(_ _ _)用电设备 #媒体#媒体#媒体

问题&#xff1a;在额定电压500V以下的电路中,使用的各种用电设备,一般称为&#xff08;_ _ _)用电设备 参考答案如图所示

【dofile版本】实证研究Stata代码命令汇总

一、引言 在现代社会科学研究领域&#xff0c;Stata已成为欧美地区最受欢迎的计量分析软件之一。然而&#xff0c;许多研究人员在使用上仍显生疏 为了帮助研究人员更好地利用Stata&#xff0c;整理了一套Stata实证命令汇总&#xff0c;覆盖了从数据的初步处理到高级统计分析的…

Mysql第一关之常规用法

简介 介绍Mysql常规概念&#xff0c;用法。包括DDL、DCL、DML、DQL&#xff0c;关键字、分组、连表、函数、排序、分页等。 一、 SQL DCMQ&#xff0c;分别代表DDL、DCL、DML、DQL。 模糊简记为DCMQ&#xff0c;看起来像一个消息队列。 D&#xff1a;Definition 定义语句 M…

【Vue前端】vue使用笔记0基础到高手第2篇:Vue知识点介绍(附代码,已分享)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论vue相关知识。Vue.js是前端三大新框架&#xff1a;Angular.js、React.js、Vue.js之一&#xff0c;Vue.js目前的使用和关注程度在三大框架中稍微胜出&#xff0c;并且它的热度还在递增。Vue.js是一个轻巧、高性能、可组件…

[ai笔记7] google浏览器ai学习提效定制优化+常用插件推荐

欢迎来到文思源想的ai空间&#xff0c;这是技术老兵重学ai以及成长思考的第7篇分享&#xff01; 工欲善其事必先利其器&#xff0c;为了ai学习的效能提升&#xff0c;放假期间对google浏览器做了一次系统整改&#xff0c;添加了一些配置和插件&#xff0c;这里既有一些显示、主…

在Visual Studio中搭建Dynamo Python开发环境,效率飞一般的增长

最近在学习Dynamo中Python Script的用法&#xff0c;发现这个东西用起来太不友好了&#xff0c;不支持自动缩进&#xff0c;不支持自动填充和提示。用过Visual Studio做二开的都知道&#xff0c;在引用了Revit api以后&#xff0c;就可以自动填充和提示了。 本来英语就不好&am…

Netty中的内置通信模式、Bootstrap和ChannelInitializer

内置通信传输模式 NIO:io.netty.channel.socket.nio 使用java.nio.channels包作为基础–基于选择器的方式Epoll:io.netty.channel.epoll由JNI驱动的epoll()和非阻塞IO.这个传输支持只有在Linux上可用的多种特性&#xff0c;如果SO_REUSEPORT&#xff0c;比NIO传输更快&#xf…

代码随想录 Leetcode435. 无重叠区间

题目&#xff1a; 代码(首刷看解析 2024年2月17日&#xff09;&#xff1a; class Solution { private:const static bool cmp(vector<int>& a,vector<int>& b) {return a[0] < b[0];} public:int eraseOverlapIntervals(vector<vector<int>&…

MessageQueue --- RabbitMQ

MessageQueue --- RabbitMQ RabbitMQ IntroRabbitMQ 核心概念RabbitMQ 分发类型Dead letter (死信)保证消息的可靠传递 RabbitMQ Intro 2007年发布&#xff0c;是一个在AMQP&#xff08;高级消息队列协议&#xff09;基础上完成的&#xff0c;可复用的企业消息系统&#xff0c;…