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

ActiveMQ 源码剖析:消息存储与通信协议实现(二)

四、KahaDB 消息存储实现细节

(一)存储原理分析

KahaDB 作为 ActiveMQ 从 5.4 版本开始的默认消息存储引擎,其基于日志文件的存储原理具有独特的设计和优势 。在 KahaDB 的存储目录(如${activemq.data}/kahadb)下,主要包含以下关键文件,它们共同构成了 KahaDB 的存储体系:

  • db-*.log:这是数据日志文件,用于按顺序存储消息内容 。消息以追加的方式写入这些日志文件,充分利用了磁盘的顺序 I/O 特性,极大地提高了写入性能。每个日志文件有默认的大小限制,通常为 32MB ,当一个日志文件写满时,会创建新的日志文件继续写入,文件名中的数字会递增,如db-1.log、db-2.log等 。这种设计使得消息写入高效且有序,即使在高并发的消息写入场景下,也能保证良好的性能。例如,在一个电商订单处理系统中,大量的订单消息可以快速地顺序写入db-*.log文件,确保消息的及时存储。
  • db.data:该文件以 B 树结构存储消息索引 。B 树索引通过消息 ID 建立对db-*.log中消息的引用,能够快速定位到消息在日志文件中的位置,从而实现高效的消息检索 。当消费者需要获取某条特定 ID 的消息时,系统可以通过db.data中的 B 树索引快速找到该消息在db-*.log中的存储位置,大大提高了消息读取的速度。例如,在一个分布式系统中,多个服务之间通过 ActiveMQ 进行消息通信,当某个服务需要获取特定消息时,借助db.data的索引功能,可以迅速定位到所需消息。
  • db.redo:用于在 KahaDB 消息存储强制退出后启动时恢复 B 树索引 。当系统发生异常(如突然断电、服务器崩溃等)导致 KahaDB 非正常关闭时,db.redo文件中的信息可以帮助系统重建 B 树索引,确保数据的完整性和可恢复性 。这就好比一个数据备份,在关键时刻能够恢复系统的关键数据结构,保证消息存储的可靠性。
  • lock:在集群环境下,用于表示当前获得 KahaDB 读写权限的 broker 。只有获得锁的 broker 才有权限对 KahaDB 进行读写操作,这样可以避免多个 broker 同时对 KahaDB 进行读写操作导致的数据不一致问题 。例如,在一个多节点的 ActiveMQ 集群中,通过lock文件可以协调各个节点对 KahaDB 的访问,保证数据的一致性和正确性。

与 AMQ 存储相比,KahaDB 在文件组织和索引结构上有显著差异 。AMQ 存储为每个索引使用两个分隔文件,且每个目的地都有一个索引,这在代理拥有大量队列时,会导致文件描述符的大量使用和管理复杂性增加 。而 KahaDB 使用单个db.data文件存储所有目的地的 B 树索引,减少了文件描述符的使用,提高了存储的紧凑性和管理的便利性 。在消息持久化流程上,KahaDB 通过事务日志和索引文件的配合,确保消息的持久化和快速检索,相比 AMQ 存储,具有更快的存储恢复机制,能够更好地应对系统异常情况,保证消息的可靠性和完整性 。

(二)存储过程中的数据操作

  1. 消息写入:当生产者发送消息时,KahaDB 首先将消息追加写入db-*.log文件 。消息以顺序写入的方式,充分利用磁盘顺序 I/O 的高性能优势 。同时,在db.data文件中创建对应的 B 树索引,将消息 ID 与消息在db-*.log中的位置进行关联 。例如,在一个实时监控系统中,传感器不断产生大量的监控数据消息,这些消息会快速地顺序写入db-*.log文件,同时在db.data中建立索引,以便后续快速查询和处理。为了保证数据的一致性,KahaDB 在写入过程中会根据enableJournalDiskSyncs配置项(默认为 true)决定是否将消息同步写入磁盘 。如果设置为 true,消息会在写入磁盘后才返回确认给生产者,确保消息在磁盘上的持久化;如果设置为 false,写入性能会有所提升,但在系统崩溃等异常情况下,可能会导致部分未同步的消息丢失 。
  1. 消息读取:消费者读取消息时,首先通过db.data中的 B 树索引根据消息 ID 定位到消息在db-*.log中的位置 。然后从db-*.log文件中读取相应的消息内容 。在这个过程中,KahaDB 会利用缓存机制(如indexCacheSize配置的索引缓存)来提高读取性能 。如果缓存中已经存在所需的索引信息,就可以直接从缓存中获取,避免了磁盘 I/O 操作 。例如,在一个电商订单查询系统中,用户查询订单相关消息时,系统可以通过索引快速从db-*.log中读取到对应的消息,同时利用缓存加速索引查找,提高查询效率 。如果消息是持久订阅的,KahaDB 还会根据activemq_acks表(如果使用 JDBC 存储时)或相关的订阅信息存储(如在 KahaDB 自身存储机制中)来管理订阅关系和消息的消费进度 。
  1. 消息删除:当消息被成功消费后,KahaDB 会将其从存储中删除 。对于db-*.log文件中的消息,当该文件中的所有消息都被消费后,文件会被标记为可删除,在后续的清理阶段,该文件会被删除或归档,以释放磁盘空间 。在删除消息时,KahaDB 会同时更新db.data中的 B 树索引,确保索引的一致性 。例如,在一个任务处理系统中,任务完成后对应的消息被消费并删除,此时 KahaDB 会及时清理相关的存储和索引,保证系统的存储资源得到合理利用 。如果消息是事务性的,KahaDB 会根据事务的状态进行相应的处理,确保事务的原子性和数据的一致性 。若事务提交成功,才会真正删除消息;若事务回滚,则消息会保留在存储中 。

五、LevelDB 消息存储实现细节

(一)独特特性分析

LevelDB 是从 ActiveMQ 5.8 之后引入的一种基于文件的本地数据库存储形式 ,它的出现为 ActiveMQ 的消息存储带来了新的性能提升和特性优化。LevelDB 之所以被引入,主要是为了满足对消息存储更高性能的需求。它基于 Google 开源的 LevelDB 库,针对消息存储场景进行了优化,提供了比 KahaDB 更快的持久性。

LevelDB 采用了独特的存储结构和算法 。它将索引保存到包含消息的日志文件中,并且使用了基于跳跃表(Skip List)的数据结构和对磁盘上的数据日志结构进行归并(LSM)的核心操作策略 。当 LevelDB 接收到新的消息时,会同步写两个地方:内存中的 MemTable 区域和磁盘上的 Log 文件 。直接写 Log 文件是为了在系统异常退出并重启时,能够将 LevelDB 恢复到退出前的结构;同时将消息写入内存的 MemTable 区域,MemTable 区域的数据组织结构是跳跃表,这样可以在读取内存中信息时快速完成信息定位 。当 MemTable 区域的数据达到一定的阈值时,会将其转换为 Immutable MemTable,并生成一个新的 MemTable 用于接收新的写入操作,Immutable MemTable 会被异步地刷写到磁盘上,形成一个新的 SSTable(Sorted String Table)文件 。

在实际应用中,LevelDB 的高性能优势得到了充分体现 。在一个对消息处理实时性要求极高的金融交易系统中,使用 LevelDB 作为消息存储,能够快速地持久化大量的交易消息,确保消息不丢失的同时,还能快速响应消费者对消息的读取请求,大大提高了系统的交易处理效率和稳定性 。与 KahaDB 相比,LevelDB 在写入性能上有显著提升,尤其在高并发写入场景下,能够减少磁盘 I/O 操作,提高系统的吞吐量 。而且,LevelDB 在垃圾回收机制上也更为高效,能够减少垃圾回收过程中对系统性能的影响 。

(二)与其他存储方式的对比

  1. 与 KahaDB 对比:LevelDB 和 KahaDB 都是基于文件的存储方式,但它们在实现细节和性能表现上有明显差异 。KahaDB 使用自定义的 B 树实现来索引写前日志,而 LevelDB 使用基于 LevelDB 的索引 。在性能方面,LevelDB 的写入性能通常优于 KahaDB,因为它采用的 LSM 树结构和跳跃表索引,使得写入操作能够更高效地进行 。在高并发写入场景下,LevelDB 能够更快地将消息持久化到磁盘,减少了写入延迟 。但在读取性能上,两者各有优劣,KahaDB 的 B 树索引在某些查询场景下可能更适合快速定位消息 。从适用场景来看,KahaDB 适用于大多数常规的消息存储场景,它的稳定性和成熟度较高;而 LevelDB 更适合对写入性能要求极高,且对数据一致性和读写性能有特定需求的场景,如实时数据处理系统、高频交易系统等 。
  1. 与 AMQ 对比:AMQ 是 ActiveMQ 早期的存储方式,与 LevelDB 相比,它在文件组织和索引方式上有很大不同 。AMQ 为每个索引使用两个分隔文件,且每个目的地都有一个索引,这在代理拥有大量队列时,会导致文件描述符的大量使用和管理复杂性增加 。而 LevelDB 的存储结构更为紧凑和高效 。在性能上,AMQ 在写入速度上有一定优势,但在索引重建和文件管理方面存在不足 。当 Broker 崩溃时,AMQ 重建索引的速度非常慢,而 LevelDB 由于其独特的存储结构和恢复机制,能够更快地恢复数据 。适用场景上,AMQ 适用于早期版本的 ActiveMQ,以及对性能要求不是特别高、数据量较小的简单场景;而 LevelDB 则更适合现代高性能、大规模的消息存储需求 。
  1. 与 JDBC 对比:JDBC 存储将消息持久化到数据库中,与 LevelDB 基于文件的存储方式有本质区别 。JDBC 存储的优点是可以利用成熟的数据库管理系统的特性,如事务处理、数据备份与恢复等 。在一些对数据一致性和事务处理要求严格的企业级应用中,JDBC 存储是一个可靠的选择 。在银行转账系统中,需要确保消息的原子性和一致性,JDBC 存储可以借助数据库的事务功能来满足这一需求 。但 JDBC 存储的缺点也很明显,数据库的 I/O 操作可能会成为性能瓶颈,尤其是在高并发场景下,数据库的连接和读写操作会带来较大的延迟 。而 LevelDB 作为基于文件的本地存储,在性能上通常优于 JDBC 存储,能够更快地进行消息的读写操作 。适用场景上,JDBC 存储适合对数据一致性和事务处理要求高,且已经有成熟数据库基础设施的企业级应用;LevelDB 则更适合对性能要求高,对数据一致性要求相对较低的高性能消息处理场景 。

六、JDBC 消息存储实现细节

(一)配置与使用

使用 JDBC 进行消息存储时,配置步骤如下:

  1. 添加数据库驱动包:根据所使用的数据库类型,将对应的数据库驱动包添加到 ActiveMQ 的lib目录下 。如果使用 MySQL 数据库,需要将mysql-connector-java-x.x.x.jar添加到该目录 。这一步是为了让 ActiveMQ 能够与数据库建立连接,因为驱动包中包含了与数据库通信所需的类和方法。
  1. 修改 activemq.xml 配置文件:在activemq.xml文件中,注释掉原有的其他存储方式(如 KahaDB)的配置,并添加 JDBC 存储的配置 。找到<persistenceAdapter>标签,将其内容修改为<jdbcPersistenceAdapter dataSource="#mysql-ds" createTableOnStartup="true"/> 。其中,dataSource属性指定了要引用的数据库连接池的 bean 名称,createTableOnStartup属性表示是否在启动时创建数据表,默认值为true,建议在第一次启动时设置为true,后续启动时改为false,以避免重复创建表的操作 。
  1. 配置数据库连接池:在activemq.xml文件的</broker>与<import resource="jetty.xml"/>中间添加数据库连接池的配置 。如果使用org.apache.commons.dbcp2.BasicDataSource连接池,配置示例如下:
 

<bean id="mysql-ds" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">

<property name="driverClassName" value="com.mysql.jdbc.Driver"/>

<property name="url" value="jdbc:mysql://localhost:3306/activemq?relaxAutoCommit=true"/>

<property name="username" value="root"/>

<property name="password" value="123456"/>

<property name="poolPreparedStatements" value="true"/>

</bean>

在这个配置中,driverClassName指定了数据库驱动类,url指定了数据库的连接地址,username和password分别是数据库的用户名和密码,poolPreparedStatements表示是否缓存预编译语句,设置为true可以提高性能 。

完成上述配置后,启动 ActiveMQ,它会根据配置连接到指定的数据库,并使用 JDBC 进行消息存储 。在数据库中,会自动创建三个表:activemq_msgs用于存储 queue 和 topic 的消息;activemq_acks用于存储持久订阅的信息和最后一个持久订阅接收的消息 ID;activemq_lock在集群环境下才有用,确保只有一个 Broker 可以访问,称为 Master Broker 。

(二)性能考量与优化

  1. 性能特点分析:JDBC 存储的性能特点与数据库的性能密切相关 。由于消息的读写操作都需要通过数据库的 I/O 来完成,在高并发场景下,数据库的 I/O 操作可能会成为性能瓶颈 。频繁的消息写入和读取会导致数据库的负载增加,从而影响消息处理的速度 。数据库的事务处理也会消耗一定的资源,尤其是在处理大量事务性消息时,会对性能产生较大影响 。不过,JDBC 存储也有其优势,它可以利用成熟的数据库管理系统的特性,如数据备份与恢复、数据一致性保障等 。
  1. 性能优化建议
    • 合理设置数据库连接池参数:连接池的参数设置对性能有重要影响 。maxActive参数设置连接池的最大活动连接数,应根据系统的并发访问量合理设置 。如果设置过小,在高并发时可能会导致连接不足,影响消息处理速度;如果设置过大,可能会占用过多的系统资源 。maxIdle参数设置连接池的最大空闲连接数,合理设置可以避免过多的空闲连接占用资源 。minIdle参数设置连接池的最小空闲连接数,确保在系统低负载时也有一定数量的空闲连接可用 。
    • 优化 SQL 语句:对用于消息存储和查询的 SQL 语句进行优化 。避免使用复杂的查询语句,尽量使用简单高效的 SQL 操作 。在查询消息时,使用索引可以大大提高查询效率 。可以在activemq_msgs表的常用查询字段(如消息 ID、时间戳等)上创建索引 。同时,减少不必要的字段查询,只查询需要的字段,以减少数据传输量 。
    • 批量操作:在进行消息写入和删除等操作时,尽量采用批量操作 。JDBC 提供了批量执行 SQL 语句的方法,通过批量操作可以减少数据库连接的开销,提高操作效率 。在写入大量消息时,可以将多条消息的插入操作合并为一个批量插入操作 。
    • 数据库缓存优化:合理利用数据库的缓存机制 。可以调整数据库的缓存参数,如 InnoDB 存储引擎的innodb_buffer_pool_size参数,增加缓存大小,以提高数据读取的命中率,减少磁盘 I/O 操作 。还可以使用数据库的查询缓存功能,对一些频繁查询且数据变动较小的查询结果进行缓存 。
    • 定期清理数据:定期清理数据库中已过期或不再需要的消息数据 。可以通过定时任务执行删除操作,避免数据量过大导致数据库性能下降 。同时,对数据库进行定期的优化和维护,如整理索引、清理碎片等 。

相关文章:

ActiveMQ 源码剖析:消息存储与通信协议实现(二)

四、KahaDB 消息存储实现细节 &#xff08;一&#xff09;存储原理分析 KahaDB 作为 ActiveMQ 从 5.4 版本开始的默认消息存储引擎&#xff0c;其基于日志文件的存储原理具有独特的设计和优势 。在 KahaDB 的存储目录&#xff08;如${activemq.data}/kahadb&#xff09;下&am…...

明远智睿SD2351核心板:工业AIoT时代的创新引擎

在当今工业互联网飞速发展的浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;与物联网&#xff08;IoT&#xff09;的深度融合正以前所未有的态势重塑着传统制造业的格局。从自动化生产线的精准控制到智能仓储的高效管理&#xff0c;从设备运行的实时监测到产品质量的严格…...

iPhone 和 Android 在日期格式方面的区别

整篇文章由iPhone 和 Android 在日期格式方面有所不同引起,大致介绍了,两种时间标准,以及在 JavaScript 下的格式转换方法。 Unix 时间戳是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒。 iPhone 和 Android 在日期格式方面有所不同。其中,iPhone(iOS)使…...

使用VSCode在Windows 11上编译运行项目

使用VSCode在Windows 11上编译运行项目 VSCode是一个功能强大的跨平台代码编辑器&#xff0c;可以很好地支持C/C项目开发。以下是使用VSCode在Windows 11上编译运行此项目的详细步骤。 1. 安装VSCode 访问VSCode官网下载并安装VSCode安装完成后&#xff0c;启动VSCode 2. 安…...

边缘计算,运维架构从传统的集中式向分布式转变

在当今数字化时代&#xff0c;边缘计算的崛起正在改变着运维的格局。随着物联网、5G 等技术的快速发展&#xff0c;越来越多的数据和应用正在向边缘设备迁移&#xff0c;这给运维团队带来了新的挑战和机遇。 一、边缘计算崛起带来的运维挑战 边缘计算将计算和数据存储靠近数据…...

【基础篇】prometheus热更新解读

文章目录 本篇内容讲解热更新参数源码解读本篇总结本篇内容讲解 prometheus热更新源码解读 热更新参数 –web.enable-lifecycle : 代表开启热更新配置 修改配置文件发http请求# curl -X POST -vvv localhost:9090/-/reload * About to connect() to localhost port 9090 (…...

为了结合后端而学习前端的学习日志(1)——纯CSS静态卡片案例

前端设计专栏 使用纯CSS创建简洁名片卡片的学习实践 在这篇技术博客中&#xff0c;我将分享我的前端学习过程&#xff0c;如何使用纯HTML和CSS创建一个简洁美观的名片式卡片&#xff0c;就像我博客首页展示的那样。这种卡片设计非常适合作为个人简介、产品展示或团队成员介绍…...

汽车服务小程序功能点开发

汽车养护服务功能 智能保养预约&#xff1a;根据车辆品牌、型号及行驶里程&#xff0c;自动推荐保养项目&#xff0c;支持线上预约 4S 店或合作维修厂&#xff0c;选择服务时间与地点。故障诊断与维修&#xff1a;车主上传车辆故障现象&#xff0c;系统智能初步诊断&#xff0…...

SENSE2020BSI sCMOS科学级相机主要参数及应用场景

SENSE2020BSI sCMOS科学级相机是一款面向宽光谱成像需求的高性能科学成像设备&#xff0c;结合了背照式&#xff08;Back-Side Illuminated, BSI&#xff09;CMOS技术与先进信号处理算法&#xff0c;适用于天文观测、生物医学成像、工业检测等领域。以下是其核心特点及技术细节…...

《汽车噪声控制》复习重点

题型 选择 填空 分析 计算 第一章 噪声定义 不需要的声音&#xff0c;妨碍正常工作、学习、生活&#xff0c;危害身体健康的声音&#xff0c;统称为噪声 噪声污染 与大气污染、水污染并称现代社会三大公害 声波基本概念 定义 媒质质点的机械振动由近及远传播&am…...

物流无人机结构与载货设计分析!

一、物流无人机的结构与载货设计模块运行方式 1.结构设计特点 垂直起降与固定翼结合&#xff1a;针对复杂地形&#xff08;如山区、城市&#xff09;需求&#xff0c;采用垂直起降&#xff08;VTOL&#xff09;与固定翼结合的复合布局&#xff0c;例如“天马”H型无人机&am…...

docker创建一个centOS容器安装软件(以宝塔为例)的详细步骤

备忘&#xff1a;后续偶尔忘记了docker虚拟机与宿主机的端口映射关系&#xff0c;来这里查看即可&#xff1a; docker run -d \ --name baota \ --privilegedtrue \ -p 8888:8888 \ -p 8880:80 \ -p 8443:443 \ -p 8820:20 \ -p 8821:21 \ -v /home/www:/www/wwwroot \ centos…...

D盘出现不知名文件

各位大佬&#xff0c;电脑D盘去年还干干净净的&#xff0c;后来突然就出现了所圈部分的几个不知名文件&#xff0c;请问这是什么东西&#xff1f;是否可以删除&#xff1f;...

Rust 中 Arc 的深度分析:从原理到性能优化实践

在 Rust 的并发编程中&#xff0c;Arc&#xff08;Atomic Reference Counted&#xff09; 是一个非常关键的智能指针类型&#xff0c;用于在多个线程之间共享数据的所有权。它通过原子操作维护引用计数&#xff0c;确保在多线程环境下安全地管理堆内存资源。然而&#xff0c;很…...

qsort函数

在本篇中&#xff0c;将深入了解qsort函数的用法。 1.qsort函数的基础知识 该函数是用来排序的&#xff0c;这是一个可以直接用来排序数据的库函数&#xff08;#include<stdlib.h>&#xff09;&#xff0c;底层使用的是快速排序的方式。 常见的排序方式有&#xff1a; …...

01 一文了解大数据存储框架:数据库、数据仓库、数据集市、数据网格、数据湖、数据湖仓

1. 大数据存储框架 1.1 定义 数据库&#xff08;Database&#xff09;&#xff1a;数据库是按照数据结构来组织、存储和管理数据的仓库&#xff0c;是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。数据仓库&#xff08;Data Warehouse&#xff…...

QT —— QWidget(2)

QT —— QWidget&#xff08;2&#xff09; windowTitlewindowIconQt 资源系统 (qrc 机制) 详解基本概念使用方法1. 创建 .qrc 文件 设置背景windowOpacity 我们今天继续来学习QWidget&#xff0c;如果大家上一次的博客还没有看过&#xff0c;可以点击这里&#xff1a; https:/…...

微信小程序预览文件 兼容性苹果

uni.request({url: url,method: GET,header: {Authorization: token,responseType: blob,},responseType: "arraybuffer",success: (res) > {uni.hideLoading()const fs wx.getFileSystemManager(); //获取全局唯一的文件管理器let index url.lastIndexOf("…...

QT:qt5调用打开exe程序并获取调用按钮控件实例2025.5.7

为实现在 VS2015 的 Qt 开发环境下打开外部 exe&#xff0c;列出其界面按钮控件的序号与文本名&#xff0c;然后点击包含特定文本的按钮控件。以下是更新后的代码&#xff1a; #include <QCoreApplication> #include <QProcess> #include <QDebug> #include…...

Flink + Kafka 数据血缘追踪与审计机制实战

一、引言 在实时数据系统中,“我的数据从哪来?去往何处?” 是业务方最关心的问题之一。 尤其在以下场景下: 📉 金融风控:模型出现预警,需回溯数据源链路。 🧾 合规审计:监管要求提供数据全流程路径。 🛠 运维排查:Kafka Topic 数据乱序或错发后快速定位来源。 …...

【图书管理系统】详细讲解用户登录:后端代码实现及讲解、前端代码讲解

1. 约定前后端交互接口 [请求] /user/login [参数] userName&password [响应] 登录成功返回–true&#xff1b;登录失败返回–false 2. 后端代码 2.1 后端代码的逻辑 Controller层&#xff1a; &#xff08;1&#xff09;从请求和参数可以得出&#xff0c;前端通过127.0.…...

uni-app实现完成任务解锁拼图功能

界面如下 代码如下 <template><view class"puzzle-container"><view class"puzzle-title">任务进度 {{completedCount}}/{{totalPieces}}</view><view class"puzzle-grid"><viewv-for"(piece, index) in…...

鸿蒙开发——1.ArkTS声明式开发(UI范式基本语法)

鸿蒙开发——1、ArkTS声明式开发:UI范式基本语法 [TOC](鸿蒙开发——1、ArkTS声明式开发:UI范式基本语法)一、ArkTS的基本组成&#xff08;1&#xff09;核心概念&#xff08;像贴标签一样控制组件&#xff09;&#xff08;2&#xff09;基础工具包&#xff08;现成的积木块&am…...

ChatGPT-4o:临床医学科研与工作的创新引擎

技术点目录 2024大语言模型最新进展介绍ChatGPT-4o提示词使用方法与技巧ChatGPT-4o助力临床医学日常生活、学习与工作ChatGPT-4o助力临床医学课题申报、论文选题及实验方案设计ChatGPT-4o助力信息检索、总结分析、论文写作与投稿、专利idea构思与交底书的撰写ChatGPT-4o助力临床…...

Excel点击单元格内容消失

Excel点击单元格内容消失 前言一、原因说明二、解决方案1.菜单栏中找到“审阅”&#xff0c;选择“撤销工作表保护”2.输入密码3.解除成功 前言 Excel想要编辑单元格内容时&#xff0c;无论是单击还是双击单元格内容都莫名其妙的消失了 一、原因说明 单击或者双击Excel中单元…...

单片机-STM32部分:7、GPIO输入 按键

飞书文档https://x509p6c8to.feishu.cn/wiki/RtuVw6GgZiuwyBkxmdDcdsAFnKk 根据原理图&#xff0c;找到KEY1对应的PC3 找到CubeMX中的PC3&#xff0c;设置为GPIO_Input 右击&#xff0c;修改引脚名称为KEY1 或者在GPIO配置属性中修改 引脚模式&#xff1a;这里默认为输入模式&…...

从创意到变现:独立创造者的破局之路——解码《Make:独立创造者手册》

在创业浪潮奔涌的时代,独立创造者正成为商业领域中一股不可忽视的新兴力量。他们凭借对创新的执着、对问题的敏锐洞察,以及对自由创业模式的追求,试图在竞争激烈的市场中开辟属于自己的天地。《Make:独立创造者手册》如同一位经验丰富的创业导师,为独立创造者们提供了一套…...

14前端项目----登录/注册

登录/注册 assets用户注册模块登录模块tokenlogin组件业务token校验获取用户登录信息 登录成功---Header组件 assets assets文件夹:一般也是放置静态资源–>一般是多个组件共用的静态资源 webpack 会把 assests 静态资源当作是一个模块&#xff0c;打包到 js 文件里,不存在a…...

【FreeRTOS-消息队列】

参照正点原子以及以下gitee笔记整理本博客&#xff0c;并将实验结果附在文末。 https://gitee.com/xrbin/FreeRTOS_learning/tree/master 一、队列简介 1、FreeRTOS中的消息队列是什么 答&#xff1a;消息队列是任务到任务、任务到中断、中断到任务数据交流的一种机制(消息传…...

二叉查找树,平衡二叉树(AVL),b树,b+树,红黑树

🌲 一、二叉查找树(Binary Search Tree,简称 BST) 📌 定义 二叉查找树是一棵二叉树,它满足这样的特性: 每个节点最多有两个子节点(左、右)对于任意一个节点: 它左子树的所有节点值都比它小它右子树的所有节点值都比它大📈 举个例子 复制代码 10/ \5 20/ \ …...

可执行文件格式(ELF格式)以及进程地址空间第二讲【Linux操作系统】

文章目录 可执行文件的格式可执行文件中存储了什么可执行文件中的虚拟地址以及加载 进程地址空间第二讲CPU如何执行进程的代码再谈进程地址空间的区域划分 可执行文件的格式 源文件被编译器编译之后的可执行文件&#xff0c;并不是只有代码和数据&#xff0c;还有一定的格式&a…...

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】8.1 基础图表绘制(折线图/柱状图/散点图)

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 PostgreSQL数据分析实战&#xff1a;基础图表绘制&#xff08;折线图/柱状图/散点图&#xff09;8.1 基础图表绘制8.1.1 折线图&#xff1a;展现数据趋势数据准备图表绘制步…...

Yii2.0 模型规则(rules)详解

一、基本语法结构 public function rules() {return [// 规则1[[attribute1, attribute2], validator, options > value, ...],// 规则2[attribute, validator, options > value, ...],// 规则3...]; }二、规则类型分类 1、核心验证器&#xff08;内置验证器&#xff0…...

Notepad++中XML格式化插件介绍

Notepad++中XML格式化插件介绍 背景安装指南安装步骤验证安装成功安装失败可尝试使用说明XML文件格式正确时格式化错误格式检查XML Tools插件核心功能盘点常见问题格式化后没变化中文显示乱码拯救杂乱XML格式!Notepad++这个神器插件,必须接收!背景 接手别人写的XML,缩进乱成…...

在 R 中,清除包含 NA(缺失值)的数据

在 R 中&#xff0c;清除包含 NA&#xff08;缺失值&#xff09;的数据可以通过多种方式实现&#xff0c;具体取决于你希望如何处理这些缺失值。以下是几种常见的方法&#xff0c;包括删除包含 NA 的行、删除包含 NA 的列&#xff0c;或者用特定值填充 NA。 1. 删除包含 NA 的…...

Linux复习笔记(一)基础命令和操作

遇到的问题&#xff0c;都有解决方案&#xff0c;希望我的博客能为你提供一点帮助。 一、Linux中的基础命令和操作&#xff08;约30%-40%) 1.用户和组&#xff08;5%左右&#xff09; 1.1用户简介&#xff08;了解&#xff09; 要求&#xff1a;了解&#xff0c;知道有三个用户…...

多线程的出现解决了什么问题?深入解析多线程的核心价值

多线程的出现解决了什么问题?深入解析多线程的核心价值 1. 引言 在计算机科学中,多线程(Multithreading) 是一种重要的并发编程技术,它允许一个进程同时执行多个任务,从而提高程序的性能和响应能力。那么,多线程究竟是为了解决哪些问题而诞生的?它的核心价值是什么?…...

java集合菜鸟教程

1、Java集合的分类 1Java中的集合类可以分为两大类&#xff1a; &#xff08;1&#xff09;实现Collection接口&#xff0c;Collection是一个基本的集合接口&#xff0c;Collection中可以容纳一组集合元素&#xff08;Element&#xff09;&#xff0c;图1是Collection与子类的…...

体育培训的实验室管理痛点 质检LIMS如何重构体育检测价值链

在竞技体育与全民健身并行的时代背景下&#xff0c;体育培训机构正面临双重挑战&#xff1a;既要通过科学训练提升学员竞技水平&#xff0c;又需严格把控运动安全风险。作为实验室数字化管理的核心工具&#xff0c;质检LIMS系统凭借其标准化流程管控与智能化数据分析能力&#…...

3、食品包装控制系统 - /自动化与控制组件/food-packaging-control

76个工业组件库示例汇总 食品包装线控制系统 这是一个用于食品包装线控制系统的自定义组件&#xff0c;提供了食品包装生产线的可视化监控与控制界面。组件采用工业风格设计&#xff0c;包含生产流程控制、实时数据监控和逻辑编程三个主要功能区域。 功能特点 工业风格UI设…...

AbMole的Calcein-AM/PI细胞双染试剂盒,精准区分细胞活死状态

在细胞生物学研究中&#xff0c;细胞活性检测是基础且关键的实验环节。然而&#xff0c;传统方法在检测活细胞和死细胞时常常面临诸多挑战&#xff1a;例如&#xff0c;检测过程复杂、耗时&#xff0c;容易受到细胞类型和实验条件的限制&#xff1b;荧光信号不稳定&#xff0c;…...

力扣刷题Day 37:LRU 缓存(146)

1.题目描述 2.思路 方法1&#xff1a;直接用Python封装好的数据结构OrderedDict&#xff08;兼具哈希表与双向链表的数据结构&#xff09;。 方法2&#xff1a;哈希表辅以双向链表。 3.代码&#xff08;Python3&#xff09; 方法1&#xff1a; class LRUCache(collections…...

动态规划之01背包——三道题助你理解01背包

目录 二维数组实现 一维数组实现 例一P1164 小A点菜 P1048 [NOIP 2005 普及组] 采药 P1802 5 倍经验日 首先做动规很好的一个办法就是卡哥提出的动规五部曲个人觉得很好用 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 确定递推公式 dp数组如何初始化 确定遍…...

【前端笔记】CSS 选择器的常见用法

目录 1. CSS 的基本语法规范2. CSS 的引入方式3. CSS 选择器的种类3.1 标签选择器3.2 类选择器3.3 id 选择器3.4 复合选择器3.5 通配符选择器 4. 补充内容 1. CSS 的基本语法规范 选择器 {1 条 / n 条声明} 选择器决定的是修改谁声明决定的是怎么修改声明的属性是键值对&…...

电脑桌面悬浮窗便签,好用的电脑桌面便签工具

不知道大家有没有发现&#xff0c;我们每天要处理的事情越来越多&#xff1a;工作会议、项目截止日期、临时灵感、购物清单...光靠大脑记忆显然不够靠谱。你可能试过用手机备忘录&#xff0c;但工作时频繁切换设备又很影响效率。 这时候&#xff0c;一款好用的电脑桌面便签工具…...

Windows环境下maven的安装与配置

1.检查JAVA_HOME环境变量 Maven是使用java开发的&#xff0c;所以必须知道当前系统环境中的JDK的安装目录。 搜索栏直接输入“cmd” 或者 WinR 输入cmd 在打开的终端窗口输入“echo %JAVA_HOME”&#xff0c;就可以看到jdk的位置了。 如果没有的话&#xff0c;请参考我的文章&a…...

PyTorch 中如何针对 GPU 和 TPU 使用不同的处理方式

一个简单的矩阵乘法例子来演示在 PyTorch 中如何针对 GPU 和 TPU 使用不同的处理方式。 这个例子会展示核心的区别在于如何获取和指定计算设备&#xff0c;以及&#xff08;对于 TPU&#xff09;可能需要额外的库和同步操作。 示例代码&#xff1a; import torch import tim…...

数据库同步方案:构建企业数据流通的高速通道

在数字经济时代&#xff0c;数据已成为企业核心资产。根据Gartner统计&#xff0c;超过70%的企业因数据孤岛问题导致决策延迟&#xff0c;而高效可靠的数据库同步方案正是破解这一困局的关键技术。本文将深度解析数据库同步的核心逻辑、主流方案及实践策略&#xff0c;助企业构…...

微信小程序开发,登录注册实现

文章目录 1. 官方文档教程2. 注册实现3. 登录实现4. 关于作者其它项目视频教程介绍 1. 官方文档教程 https://developers.weixin.qq.com/miniprogram/dev/framework/路由跳转的几种方式&#xff1a; https://developers.weixin.qq.com/miniprogram/dev/api/route/wx.switchTab…...

VSCode怎么同时打开多个页面

VSCode中打开一个文件会把另一个文件覆盖&#xff0c;始终保持打开一个文件的状态&#xff0c;相对于其他IDE是不太习惯的&#xff0c;如果同时打开两个文件页面怎么去设置呢 1、禁用预览模式 2、快速分屏快捷键&#xff1a; Ctrl\ (Windows/Linux) 或 Cmd\ (macOS)...