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

从 JMS 到 ActiveMQ:API 设计与扩展机制分析(一)

引言

{"type":"load_by_key","key":"auto_image_0_0","image_type":"search"}

在当今的分布式系统开发中,消息中间件扮演着举足轻重的角色,它为应用程序之间提供了可靠的异步通信机制。JMS(Java Message Service)作为 Java 平台上的消息服务规范,定义了一套通用的 API,使得开发者能够编写与具体消息中间件实现无关的代码,实现了更高层次的抽象和可移植性。而 ActiveMQ 则是 JMS 规范的一种流行实现,它不仅完全支持 JMS API,还提供了丰富的特性和强大的功能,如消息持久化、事务支持、集群部署等,在企业级应用中被广泛使用。

深入分析 JMS 和 ActiveMQ 的 API 设计与扩展机制,对于开发者来说具有多方面的重要意义。在 API 设计层面,理解 JMS 规范中定义的接口和类,如 ConnectionFactory、Connection、Session、Destination、MessageProducer、MessageConsumer 等,能让开发者熟练掌握如何创建连接、发送和接收消息,以及管理消息的生命周期,从而编写出简洁、高效且符合规范的消息处理代码。同时,研究 ActiveMQ 对 JMS API 的具体实现方式,能帮助开发者更好地利用 ActiveMQ 的特性,优化消息处理性能,例如在高并发场景下合理配置 ActiveMQ 的连接池和线程池。

在扩展机制方面,了解 JMS 的可插拔性和扩展性设计理念,有助于开发者根据业务需求,定制和扩展消息处理逻辑,实现诸如自定义消息序列化方式、消息过滤策略等功能。而 ActiveMQ 自身提供的丰富扩展点,如插件机制、协议扩展、存储扩展等,能让开发者灵活地对 ActiveMQ 进行二次开发,以满足不同的应用场景需求,比如在金融领域实现对消息的严格顺序控制和高可靠性传输。

本文将详细剖析 JMS 和 ActiveMQ 的 API 设计与扩展机制,通过理论阐述、代码示例和实际案例分析,帮助读者深入理解它们的工作原理和应用方法,从而在分布式系统开发中更好地运用消息中间件技术。

一、JMS 与 ActiveMQ 简介

(一)JMS 基础回顾

JMS 即 Java 消息服务(Java Message Service),是 Java 平台上关于面向消息中间件(MOM)的 API ,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。它定义了一组通用的接口和类,使得 Java 应用程序能够与各种消息中间件进行交互,而无需关心具体的实现细节。这就好比 JDBC 为 Java 应用程序提供了统一访问各种关系数据库的接口,JMS 则为消息通信提供了类似的抽象层,大大提高了代码的可移植性和可维护性。

JMS 的核心概念丰富而关键。连接工厂(ConnectionFactory)是创建连接的工厂,它就像是一个生产连接的 “车间”,通过它可以获取到与消息中间件的连接。连接(Connection)则是客户端与消息中间件之间的通信链路,是消息传递的基础通道。会话(Session)是在连接之上创建的单线程上下文,用于发送和接收消息,它就像是一个消息处理的 “工作区”,在这个区域内可以进行消息的各种操作 。

目的地(Destination)是消息的发送目标和接收来源,它分为队列(Queue)和主题(Topic)两种类型,分别对应着不同的消息模型。消息生产者(MessageProducer)负责创建并发送消息,就像是消息的 “发送者”,而消息消费者(MessageConsumer)则用于接收并处理消息,是消息的 “接收者”。

JMS 定义了两种主要的消息模型:点对点(Point-to-Point,P2P)模型和发布 / 订阅(Publish/Subscribe,Pub/Sub)模型。在 P2P 模型中,消息被发送到队列中,每个消息只能被一个消费者接收。就好比寄信,一封信只能被一个收件人收到。消息生产者和消费者之间没有时间上的严格相关性,即使消费者在生产者发送消息时不在线,只要消息在队列中未被消费,消费者上线后依然可以获取到消息 。

在 Pub/Sub 模型中,消息被发布到主题,多个订阅者可以同时接收同一个消息,类似于广播的形式,一个消息可以被多个听众听到。生产者和消费者之间存在一定的时间相关性,订阅者需要先订阅主题,才能接收到后续发布到该主题的消息。不过,JMS 也允许创建持久订阅,使得订阅者即使在离线状态下,也能在重新上线后接收到离线期间发布的消息。

在企业级应用中,JMS 扮演着异步通信的关键角色。例如,在一个电商系统中,用户下单后,订单系统可以通过 JMS 发送消息给库存系统、物流系统和支付系统等。库存系统接收到消息后进行库存扣减,物流系统安排发货,支付系统处理支付流程。这样,订单系统无需等待其他系统的处理结果,可以立即返回给用户响应,提高了系统的响应速度和用户体验。同时,各个系统之间通过 JMS 进行解耦,降低了系统之间的耦合度,使得每个系统可以独立进行升级和维护 。

(二)ActiveMQ 概述

ActiveMQ 是 Apache 出品的最流行的开源消息中间件之一,它是一个完全支持 JMS 1.1 和 J2EE 1.4 规范的 JMS Provider 实现。这意味着它不仅遵循 JMS 规范,提供了标准的 JMS API 实现,还在此基础上进行了大量的功能扩展和优化,以满足不同场景下的消息通信需求。

ActiveMQ 具有众多突出的特点和优势。它支持多种协议,如 OpenWire、AMQP、MQTT、STOMP 等,这使得它能够与不同类型的应用程序和系统进行集成。无论是传统的企业级应用,还是新兴的物联网设备,都可以通过合适的协议与 ActiveMQ 进行通信。同时,ActiveMQ 支持多种语言的客户端,包括 Java、C、C++、C#、Ruby、Perl、Python、PHP 等,极大地扩大了其应用范围,开发者可以根据项目的技术栈选择合适的客户端语言进行开发。

ActiveMQ 对 Spring 框架有着良好的支持,这在基于 Spring 的企业级开发中尤为重要。通过 Spring 的配置和管理,开发者可以方便地集成 ActiveMQ,实现消息的发送和接收,并且可以利用 Spring 的事务管理、依赖注入等特性来增强消息处理的功能和可靠性。例如,在一个基于 Spring Boot 的项目中,只需要简单地添加 ActiveMQ 的依赖,并在配置文件中进行一些基本配置,就可以快速搭建起消息通信的功能。

在分布式系统中,ActiveMQ 有着广泛的应用场景。它可以用于实现系统之间的异步通信,解耦不同模块之间的依赖关系。比如在一个微服务架构中,各个微服务之间通过 ActiveMQ 进行消息传递,实现数据的同步和业务流程的协同。同时,ActiveMQ 还可以用于实现消息的持久化存储,确保在系统故障或重启的情况下,消息不会丢失。在高并发场景下,ActiveMQ 可以通过集群部署和负载均衡技术,提高系统的吞吐量和可用性,保证消息的可靠传输和处理 。

二、JMS API 设计剖析

(一)核心接口详解

  1. ConnectionFactory 接口:ConnectionFactory 是用于创建 Connection 的工厂接口,它是 JMS 客户端与 JMS Provider 之间连接的创建者。在实际应用中,不同的 JMS Provider 会提供各自的 ConnectionFactory 实现类,例如 ActiveMQ 提供的 ActiveMQConnectionFactory。通过 ConnectionFactory,开发者可以获取到与消息中间件的连接,并且可以设置一些连接相关的参数,如连接地址、用户名、密码等。它就像是一个连接的 “生产车间”,负责制造出符合要求的连接对象,为后续的消息通信搭建基础通道。
  1. Connection 接口:Connection 代表了 JMS 客户端与 JMS Provider 之间的物理连接,是消息传递的基础。它负责管理与 JMS Provider 的通信,包括建立连接、启动和停止连接等操作。在一个 Connection 中,可以创建多个 Session,每个 Session 用于执行一组消息操作。当 Connection 建立后,客户端就可以通过它与 JMS Provider 进行交互,发送和接收消息。同时,Connection 还提供了一些方法来管理事务,例如开始事务、提交事务和回滚事务等,确保消息操作的原子性和一致性 。
  1. Session 接口:Session 是在 Connection 之上创建的单线程上下文,用于发送和接收消息。它就像是一个消息处理的 “工作区”,在这个区域内可以进行消息的创建、发送、接收等各种操作。Session 还负责管理消息的确认模式,即当消费者接收消息后,如何通知 JMS Provider 消息已被成功接收。JMS 提供了几种确认模式,如自动确认(AUTO_ACKNOWLEDGE)、客户端手动确认(CLIENT_ACKNOWLEDGE)和事务性确认(SESSION_TRANSACTED) 。在自动确认模式下,当消费者接收到消息后,JMS Provider 会自动将消息标记为已接收;在客户端手动确认模式下,消费者需要调用消息的 acknowledge () 方法来手动确认消息;在事务性确认模式下,消息的确认与事务相关联,只有当事务成功提交时,消息才会被确认 。

下面通过一段代码示例来展示如何使用这些核心接口创建连接和会话:

 

import javax.jms.Connection;

import javax.jms.ConnectionFactory;

import javax.jms.Session;

import org.apache.activemq.ActiveMQConnectionFactory;

public class JMSExample {

public static void main(String[] args) throws Exception {

// 创建ConnectionFactory

ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");

// 创建Connection

Connection connection = factory.createConnection();

// 启动连接

connection.start();

// 创建Session,第一个参数为是否支持事务,第二个参数为确认模式

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

// 这里可以进行消息发送和接收等操作

// 关闭Session

session.close();

// 关闭Connection

connection.close();

}

}

在上述代码中,首先创建了一个 ActiveMQConnectionFactory 对象,通过它指定了连接到 ActiveMQ 的地址。然后使用该工厂创建了一个 Connection 对象,并启动了连接。接着,在连接的基础上创建了一个 Session 对象,设置为非事务模式且采用自动确认模式。这样就完成了 JMS 连接和会话的创建,后续可以在这个会话中进行消息的生产和消费操作。

在消息生产和消费流程中,这些核心接口起着关键作用。ConnectionFactory 为整个消息通信提供了连接创建的基础,就像是搭建了一条通往消息中间件的道路;Connection 建立了与消息中间件的实际连接,是消息传输的载体;而 Session 则提供了一个操作消息的环境,就像是在这条道路上划分出了一个个的 “工作区域”,使得消息的生产和消费能够有条不紊地进行 。例如,在消息生产过程中,生产者通过 Session 创建 MessageProducer,然后使用 MessageProducer 将消息发送到目的地;在消息消费过程中,消费者通过 Session 创建 MessageConsumer,从目的地接收消息并进行处理 。

(二)消息模型相关 API

  1. 点对点模型相关 API:在点对点(P2P)模型中,主要涉及 Queue、MessageProducer 和 MessageConsumer 接口。Queue 代表一个消息队列,它是消息的存储和转发中心,就像是一个 “信箱”,消息生产者将消息发送到这个 “信箱” 中,而消息消费者从这里取出消息进行处理。MessageProducer 用于创建并发送消息到 Queue,它就像是消息的 “发送者”,通过调用其 send 方法将消息发送到指定的 Queue 中。MessageConsumer 则用于从 Queue 中接收消息,是消息的 “接收者”,可以通过其 receive 方法来获取消息,receive 方法有多种重载形式,可以设置等待消息的超时时间等参数 。
  1. 发布订阅模型相关 API:在发布 / 订阅(Pub/Sub)模型中,主要涉及 Topic、MessageProducer 和 MessageConsumer 接口。Topic 代表一个主题,它类似于一个 “广播中心”,消息生产者将消息发布到这个主题上,而所有订阅了该主题的消息消费者都可以接收到消息。与 Queue 不同,Topic 的消息会被发送给所有订阅者,实现了一对多的消息传递。MessageProducer 同样用于发送消息,但这里是将消息发送到 Topic,而 MessageConsumer 则是从 Topic 订阅并接收消息。对于持久订阅,订阅者需要在创建 MessageConsumer 时设置相应的标识,这样即使订阅者在消息发布时离线,也能在重新上线后获取到离线期间发布的消息 。

下面通过代码示例展示不同模型下消息生产和消费的操作:

点对点模型示例
 

import javax.jms.Connection;

import javax.jms.ConnectionFactory;

import javax.jms.MessageProducer;

import javax.jms.Queue;

import javax.jms.Session;

import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

public class P2PProducer {

public static void main(String[] args) throws Exception {

ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");

Connection connection = factory.createConnection();

connection.start();

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

Queue queue = session.createQueue("myQueue");

MessageProducer producer = session.createProducer(queue);

TextMessage message = session.createTextMessage("Hello, P2P!");

producer.send(message);

System.out.println("Sent message: " + message.getText());

producer.close();

session.close();

connection.close();

}

}

 

import javax.jms.Connection;

import javax.jms.ConnectionFactory;

import javax.jms.Message;

import javax.jms.MessageConsumer;

import javax.jms.Queue;

import javax.jms.Session;

import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

public class P2PConsumer {

public static void main(String[] args) throws Exception {

ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");

Connection connection = factory.createConnection();

connection.start();

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

Queue queue = session.createQueue("myQueue");

MessageConsumer consumer = session.createConsumer(queue);

Message message = consumer.receive();

if (message instanceof TextMessage) {

TextMessage textMessage = (TextMessage) message;

System.out.println("Received message: " + textMessage.getText());

}

consumer.close();

session.close();

connection.close();

}

}

发布订阅模型示例
 

import javax.jms.Connection;

import javax.jms.ConnectionFactory;

import javax.jms.MessageProducer;

import javax.jms.Topic;

import javax.jms.Session;

import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

public class PubSubProducer {

public static void main(String[] args) throws Exception {

ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");

Connection connection = factory.createConnection();

connection.start();

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

Topic topic = session.createTopic("myTopic");

MessageProducer producer = session.createProducer(topic);

TextMessage message = session.createTextMessage("Hello, Pub/Sub!");

producer.send(message);

System.out.println("Sent message: " + message.getText());

producer.close();

session.close();

connection.close();

}

}

 

import javax.jms.Connection;

import javax.jms.ConnectionFactory;

import javax.jms.Message;

import javax.jms.MessageConsumer;

import javax.jms.Topic;

import javax.jms.Session;

import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

public class PubSubConsumer {

public static void main(String[] args) throws Exception {

ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");

Connection connection = factory.createConnection();

connection.start();

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

Topic topic = session.createTopic("myTopic");

MessageConsumer consumer = session.createConsumer(topic);

Message message = consumer.receive();

if (message instanceof TextMessage) {

TextMessage textMessage = (TextMessage) message;

System.out.println("Received message: " + textMessage.getText());

}

consumer.close();

session.close();

connection.close();

}

}

对比两种模型的 API 差异,主要体现在目的地的类型上,P2P 模型使用 Queue,而 Pub/Sub 模型使用 Topic。这也导致了消息传递的方式不同,P2P 模型中消息只能被一个消费者接收,而 Pub/Sub 模型中消息可以被多个订阅者接收。在适用场景方面,P2P 模型适用于需要确保消息被唯一处理的场景,例如订单处理系统,每个订单消息只需要被一个处理模块接收并处理;而 Pub/Sub 模型适用于需要广播消息的场景,如实时新闻推送系统,新闻消息需要发送给所有订阅的用户 。

相关文章:

从 JMS 到 ActiveMQ:API 设计与扩展机制分析(一)

引言 在当今的分布式系统开发中,消息中间件扮演着举足轻重的角色,它为应用程序之间提供了可靠的异步通信机制。JMS(Java Message Service)作为 Java 平台上的消息服务规范,定义了一套通用的 API,使得开发者…...

第J7周:ResNeXt解析

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 目标 具体实现 (一)环境 语言环境:Python 3.10 编 译 器: PyCharm 框 架: Tensorflow (二)具体…...

机器学习-无量纲化与特征降维(一)

一.无量纲化-预处理 无量纲,即没有单位的数据 无量纲化包括"归一化"和"标准化",这样做有什么用呢?假设用欧式距离计算一个公司员工之间的差距,有身高(m)、体重(kg&#x…...

Shiro(八):JWT介绍

1、什么是JWT? JWT(JSON Web Token,JSON Web令牌)是一种开放标准(RFC 7519),用于在网络应 用环境间安全地传递声明(claims)作为JSON对象;JWT会按指定的加密算…...

linux0.11内核源码修仙传第十六章——获取硬盘信息

🚀 前言 书接第十四章:linux0.11内核源码修仙传第十四章——进程调度之fork函数,在这一节博客中已经通过fork进程创建了一个新的进程1,并且可以被调度,接下来接着主线继续走下去。希望各位给个三连,拜托啦&…...

画家沈燕的山水实验:在传统皴法里植入时代密码

导语:当宋代山水遇上AI算法,当青绿颜料邂逅生态数据,沈燕在宣纸与人工智能的交界处,开启了一场关于水墨基因的“基因突变”实验。她的画笔既似考古学家的洛阳铲,又似未来学家的扫描仪,在古今对话中重构山水…...

聊聊四种实时通信技术:短轮询、长轮询、WebSocket 和 SSE

这篇文章,我们聊聊 四种实时通信技术:短轮询、长轮询、WebSocket 和 SSE 。 1 短轮询 浏览器 定时(如每秒)向服务器发送 HTTP 请求,服务器立即返回当前数据(无论是否有更新)。 优点&#xff1…...

国联股份卫多多与北京经纬智诚签署战略合作协议

5月9日,北京经纬智诚电子商务有限公司(以下简称“经纬智诚”)总经理王学文一行到访国联股份卫多多,同卫多多/纸多多副总裁、产发部总经理段任飞,卫多多机器人产业链总经理郭碧波展开深入交流,双方就未来合作…...

在 Envoy 的配置文件中出现的 “@type“ 字段

在 Envoy 的配置文件中出现的 "type" 字段是 Protocol Buffers(Protobuf)的 JSON/YAML 编码规范的一部分,属于 Typed Struct 的表示方式。它的作用是明确指定当前配置对象的 Protobuf 类型,以便 Envoy 正确解析配置。以…...

编译原理实验 之 语法分析程序自动生成工具Yacc实验

文章目录 实验环境准备复现实验例子分析总的文件架构实验任务 什么是Yacc Yacc(Yet Another Compiler Compiler)是一个语法分析程序自动生成工具,Yacc实验通常是在编译原理相关课程中进行的实践项目,旨在让学生深入理解编译器的语法分析阶段以及掌握Yac…...

【大模型】LLM概念相关问题(上)

1.主流的大语言模型 截至2025年,主流的大型语言模型(LLM)体系涵盖了多个国家和机构的成果,具有多样的架构设计、参数规模和应用场景。以下是一些具有代表性的开源和闭源 LLM 体系: 🇺🇸 OpenA…...

AWS IoT Core与MSK集成实战:打造高可靠实时IoT数据管道

在物联网快速发展的今天,如何高效、安全地处理海量设备数据成为企业面临的一大挑战。本文将带您深入探索AWS IoT Core与Amazon MSK(Managed Streaming for Apache Kafka)的集成方案,手把手教您搭建一个可靠、可扩展的实时IoT数据处理管道。无论您是IoT开发者、大数据工程师还是…...

智慧交通-车门开关状态检测数据集VOC+YOLO格式1006张2类

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):1006 标注数量(xml文件个数):1006 标注数量(txt文件个数):1006 …...

【传感器】代码——DHT11温湿度传感器

目录 一、代码流程 二、模块.c代码 三、模块.h代码 四、主函数代码 一、代码流程 1.模块复位:主机发送开始通信时序,从机做出响应(需检测是否有响应) 2.MCU读取1Bit数据 3.MCU读取1Byte数据 4.MCU读取8Byte数据组成完整Dat…...

MySQL 的事务(Transaction)

1. 什么是事务?​​ 事务是​​一组原子性的数据库操作序列​​,这些操作要么​​全部执行成功​​,要么​​全部失败回滚​​。事务的目的是确保数据库从一个一致状态转换到另一个一致状态,即使在执行过程中发生错误或中断。 ​…...

vue知识点总结 依赖注入 动态组件 异步加载

一 依赖注入 使用场景:当需要多层组件需要传值 如 祖宗-》父亲-》儿子-》孙子如祖宗的数据需要直接传给孙子 在祖宗组件中写: data(){return {}} provide(){ return {shujukey:数据值 } }在孙子组件中接收,模板代码中直接使用{{shujukey}}获取数据 dat…...

【软件设计师:存储】16.计算机存储系统

一、主存储器 存储器是计算机系统中的记忆设备,用来存放程序和数据。 计算机中全部信息,包括输入的原始数据、计算机程序、中间运 行结果和最终运行结果都保存在存储器中。 存储器分为: 寄存器Cache(高速缓冲存储器)主存储器辅存储器一、存储器的存取方式 二、存储器的性…...

快速开发-基于gin的中间件web项目开发

一、概述 在 Gin 框架中,中间件(Middleware)是一种在处理 HTTP 请求之前或之后执行的函数。使用中间件可以方便地实现诸如身份验证(Auth)、日志记录、请求限流等功能。 二、编写中间件 // 中间件 func StartCost1(c …...

耀圣-气动带刮刀硬密封法兰球阀:攻克颗粒高粘度介质的自清洁 “利器”

气动带刮刀硬密封法兰球阀:攻克颗粒高粘度介质的自清洁 “利器” 在化工、矿业、食品加工等行业中,带颗粒高粘度介质、料浆及高腐蚀性介质的输送与控制一直是行业难题。普通阀门极易因介质附着、颗粒堆积导致卡阻失效,密封面磨损加剧&#x…...

MySQL + Elasticsearch:为什么要使用ES,使用场景与架构设计详解

MySQL Elasticsearch:为什么要使用ES,使用场景与架构设计详解 前言一、MySQL Elasticsearch的背景与需求1.1 为什么要使用Elasticsearch(ES)?1.2 为什么MySQL在某些场景下不足以满足需求?1.3 MySQL Elas…...

【C语言】--指针超详解(三)

目录 一.数组名的理解 二.使用指针访问数组 三.一维数组传参的本质 四.冒泡排序 五.二级指针 六.指针数组 6.1--指针数组的定义 6.2--指针数组模拟二维数组 🔥个人主页:草莓熊Lotso的个人主页 🎬作者简介:C方向学习者 &…...

污水处理厂逆袭:Ethernet/IP 转 CANopen 开启“智净”时代

在我们的日常生活中,污水处理厂发挥着至关重要的作用,它们处理着城市污水,确保我们的水源安全。然而,这些关键设施的运行和管理并非易事,尤其是在数字化转型的大潮中。现在,我们有了一款创新的解决方案——…...

ROS导航局部路径规划算法

在导航功能包中,局部路径规划器的位置如图红框所示。它接受全局路径规划器生成的全局路径以及里程计信息和局部代价地图,最后输出速度控制信息 一、DWA(Dynamic Window Approach) 原理介绍 DWA 是一种基于动态窗口采样的局部路…...

《深挖Java中的对象生命周期与垃圾回收机制》

大家好呀!👋 今天我们要聊一个Java中超级重要的话题——对象的生命周期和垃圾回收机制。 一、先来认识Java世界的"居民"——对象 👶 在Java世界里,一切皆对象。就像现实世界中的人一样,每个Java对象也有自…...

Java——包装类

目录 3.5 包装类 3.5 包装类 有时需要把基本类型转换为对象。所有基本类型都有一个与之对应的类。这些类称为包装器/类。这些类是不可变类,即一旦构造了包装器/类,就不允许改变包装在其中的值。其次包装类还是final,不用可以被继承。 为什么要…...

【谭浩强】第七章第14题

实验结果&#xff1a;当M1时输出的结果 实验总结&#xff1a;用define定义要频繁使用的值可以节省时间&#xff1b;求完一门课平均成绩之后要让sum重新等于0&#xff1b;求最高分对应的学生和对应的课程要循环完一遍覆盖一遍r和c的值&#xff1b; 程序代码 #include <stdi…...

Linux 内核中的 security_sk_free:安全模块与 Socket 释放机制解析

引言 在 Linux 内核中,网络通信和进程间交互(IPC)的核心数据结构之一是 struct sock(即 socket)。其生命周期管理涉及复杂的资源分配与释放逻辑。本文聚焦于 security_sk_free 这一函数,探讨其作用、调用场景以及与安全模块的交互机制,并解答一个常见疑问:在单机间 TC…...

学习笔记:黑马程序员JavaWeb开发教程(2025.4.1)

11.10 案例-配置文件-yml配置文件 Yml语法&#xff1a; 数据格式&#xff1a; 11.11 案例-配置文件-ConfigurationProperties 配置项自动注入&#xff0c;需要保持KEY的属性名一样&#xff0c;需要在文件中加上Data注解&#xff0c;要将这个类交给IOC容器管理&#xff0c;使其成…...

深度学习-161-Dify工具之对比使用工作流和聊天流生成图表可视化的html文件

文章目录 1 任务背景2 使用chatflow聊天流2.1 开始节点2.2 文档提取器2.3 LLM2.4 参数提取器2.5 代码执行2.6 直接回复2.7 应用展示3 生成html文件可视化图表3.1 使用workflow工作流3.1.1 LLM3.1.2 效果展示3.2 使用chatflow聊天流3.2.1 LLM3.2.2 效果展示4 参考附录分别使用聊…...

关于VScode的调试

调试代码要有这么几个工具&#xff1a;源代码、带调试符号的程序、MAP表&#xff0c;调试器。 在启动调试器之前&#xff0c;要首先编译带有符号表的程序&#xff0c;生成对应map。然后启动调试器。 不同的语言有不同的特性&#xff0c;比如解释型语言不需要编译成可执行程序…...

(x ^ 2 + 2y − 1) ^ 3 − x ^ 2 * y ^ 3 = 1

二元高次方程 EquationSolver20250509.java package math;import org.apache.commons.math3.analysis.MultivariateFunction; import org.apache.commons.math3.optim.InitialGuess; import org.apache.commons.math3.optim.MaxEval; import org.apache.commons.math3.optim.P…...

弹窗表单的使用,基于element-ui二次封装

el-dialog-form 介绍 基于element-ui封装的弹窗式表单组件 示例 git地址 https://gitee.com/chenfency/el-dialog-form.git 更新日志 2021-8-12 版本1.0.0 2021-8-17 优化组件&#xff0c;兼容element原组件所有Attributes及Events 2021-9-9 新增tip提示 安装教程 npm install …...

关系模式-无损连接和保持函数依赖的判断

1、怎样判断一个关系模式的分解是否是无损连接&#xff1f; 方法一&#xff1a;公式定理法 关系模式R<U,F>的一个分解具有无损连接的充分必要条件是&#xff1a; 或 方法二&#xff1a;表格法&#xff08;常用与分解成3个及以上关系模式&#xff09; a. 通过立一张j…...

Vmware 最新下载教程和安装教程,外带免下载文件

一、VMware 的简介 VMware 是一款功能强大的桌面虚拟计算机软件&#xff0c;提供用户可在单一的桌面上同时运行不同的操作系统&#xff0c;和进行开发、测试 、部署新的应用程序的最佳解决方案。VMware可在一部实体机器上模拟完整的网络环境&#xff0c;以及可便于携带的虚拟机…...

开平机:从原理到实践的全面技术剖析

一、开平机核心模块技术解析 1. 校平辊系的力学建模与辊型设计 校平机精度核心在于辊系设计&#xff0c;需通过弹塑性力学模型计算变形量。典型校平辊配置参数&#xff1a; 辊径比&#xff1a;校平辊直径&#xff08;D&#xff09;与板材厚度&#xff08;t&#xff09;需满足…...

Edu教育邮箱申请2025年5月

各位好&#xff0c;这里是aigc创意人竹相左边 如你所见&#xff0c;这里是第3部分 现在是选择大学的学科专业 选专业的时候记得考虑一下当前的时间日期。 比如现在是夏天&#xff0c;所以你选秋天入学是合理的。...

文本框碰撞测试

1.核心代码: // 初始化舞台和变量 var stage, textField, bounds, velocity;function init() {// 创建舞台stage = new createjs.Stage("canvas");// 设置矩形边界bounds = {x: 50, y: 50, width: 400, height: 300};// 绘制边界矩形var border = new createjs.Shap…...

LeRobot 项目部署运行逻辑(六)——visualize_dataset_html.py/visualize_dataset.py

可视化脚本包括了两个方法&#xff1a;远程下载 huggingface 上的数据集和使用本地数据集 脚本主要使用两个&#xff1a; 目前来说&#xff0c;ACT 采集训练用的是统一时间长度的数据集&#xff0c;此外&#xff0c;这两个脚本最大的问题在于不能裁剪&#xff0c;这也是比较好…...

Python函数:从基础到进阶的完整指南

在Python编程中&#xff0c;函数是构建高效、可维护代码的核心工具。无论是开发Web应用、数据分析还是人工智能模型&#xff0c;函数都能将复杂逻辑模块化&#xff0c;提升代码复用率与团队协作效率。本文将从函数基础语法出发&#xff0c;深入探讨参数传递机制、高阶特性及最佳…...

图灵爬虫练习平台第七题千山鸟飞绝js逆向

题目七&#xff1a;千山鸟飞绝 还是先进入开发者模式&#xff0c;一进来还是一个无限debugger&#xff0c;直接右键点击一律不在此处停留 然后点击下一页&#xff0c;复制curl进行代码生成&#xff0c;然后就会发现加密内容是headers中的m,ts&#xff0c;还有参数中的x&#xf…...

使用Python和OpenCV实现实时人脸检测与识别

前言 在计算机视觉领域&#xff0c;人脸检测与识别是两个非常重要的任务。人脸检测是指在图像中定位人脸的位置&#xff0c;而人脸识别则是进一步识别出人脸的身份。随着深度学习的发展&#xff0c;这些任务的准确性和效率都有了显著提升。OpenCV是一个开源的计算机视觉库&…...

Excel实现单元格内容拼接

一、应用场景&#xff1a; 场景A&#xff1a;将多个单元格拼接&#xff0c;比如写测试用例时&#xff0c;将多个模块拼接&#xff0c;中间用“-”隔开 场景B&#xff1a;将某单元格内容插入另一单元格固定位置&#xff08;例如在B1中添加A1的内容&#xff09; 二、实际应用&a…...

C语言实现:打印素数、最大公约数

本片博客起源于作者在经历了学校的测试之后猛然发现自己居然忘记了一些比较基础的代码&#xff0c;因此写了本片博客加强记忆 以下算法仅供参考 打印素数 打印&#xff1a;0到200之间所有的素数 #define _CRT_SECURE_NO_WARNINGS#include<stdio.h> #include<math.h&…...

TDengine 在智慧油田领域的应用

简介 智慧油田&#xff0c;亦称为数字油田或智能油田&#xff0c;是一种采用尖端信息技术与先进装备的现代油田开发模式。该模式通过实时更新油气田层析图及动态生产数据&#xff0c;显著提高了油气田的开发效率与经济价值。 信息技术在此领域发挥着至关重要的作用&#xff0…...

将 iconfont 图标转换成element-plus也能使用的图标组件

在做项目时发现&#xff0c;element-plus的图标组件&#xff0c;不能像文档示例中那样使用 iconfont 的图标。经过研究发现&#xff0c;element-plus的图标封装成了vue组件&#xff0c;组件内容是一个svg&#xff0c;然后以组件的方式引入和调用图标。根据这个思路&#xff0c;…...

使用程序绘制中文字体——中文字体的参数化设计方案初探

目录 写在前面基本设计思路笔画骨架参数设计笔画风格参数设计起笔风格转角风格字重变化弯曲程度 字形的“组装拟合”基于骨架的结构调整笔画绘制二三事撇的两侧轮廓绘制——不是两条贝塞尔曲线那么简单转角的处理&#xff0c;怎样能显得不突兀&#xff1f;笔画骨架关键点的拖拽…...

高频数据结构面试题总结

基础数据结构 1. 数组(Array) 特点&#xff1a;连续内存、固定大小、随机访问O(1)常见问题&#xff1a; 两数之和/三数之和合并两个有序数组删除排序数组中的重复项旋转数组最大子数组和(Kadane算法) 2. 链表(Linked List) 类型&#xff1a;单链表、双链表、循环链表常见问…...

工业设计破局密码:3D 可视化技术点燃产业升级引擎

3D可视化是一种将数据、信息或抽象概念以三维图形、模型和动画的形式呈现出来的技术。3D可视化技术通过构建三维数字孪生体&#xff0c;将设计思维转化为可交互的虚拟原型&#xff0c;不仅打破了传统二维设计的空间局限&#xff0c;更在效率、精度与用户体验层面开创了全新维度…...

【动态导通电阻】p-GaN HEMTs正向和反向导通下的动态导通电阻

2024 年,浙江大学的 Zonglun Xie 等人基于多组双脉冲测试方法,研究了两种不同技术的商用 p-GaN 栅极 HEMTs 在正向和反向导通模式以及硬开关和软开关条件下的动态导通电阻(RON)特性。实验结果表明,对于肖特基型 p-GaN 栅极 HEMTs,反向导通时动态 RON 比正向导通高 3%-5%;…...

Python代码编程基础

字符串 str.[]实现根据下标定位实现对元素的截取 for 循环可以实现遍历 while 循环可以在实现遍历的同时实现对某一下标数值的修改 字符串前加 r 可以实现对字符串的完整内容输出 字符串前加 f 可以实现对字符串内{}中包裹内容的格式化输出&#xff0c;仅在 v3.6 之后可用…...