如何选择最适合的消息队列?详解 Kafka、RocketMQ、RabbitMQ 的使用场景

news2024/11/13 11:54:58

引言

在日常开发中,消息队列已经成为业务场景中几乎不可或缺的一部分。无论是订单系统、日志收集、分布式事务,还是大数据实时流处理,消息队列都在支撑着这些关键环节。目前市面上常用的消息队列有三种(ActiveMQ 虽然在企业集成中仍有应用,但由于性能和扩展性在高并发、大数据量场景下的局限性,相较于其他消息队列已显得较为陈旧),分别是 RabbitMQKafkaRocketMQ

今天,我们将深入了解这三种消息队列的实现原理区别应用场景,并探讨如何根据不同的业务需求进行合理选型。同样,这三种消息队列也是技术面试中经常被问到的知识点,掌握它们不仅有助于日常工作,更能帮助我们在面试中应对相关问题。

什么是消息队列?

消息队列是一个用于在分布式系统中传递消息的机制。它通过生产、存储和消费消息的方式,在不同系统或服务之间建立通信桥梁,帮助实现解耦和异步处理。消息队列的三大核心部分包括:

  1. 生产者(Producer)

    • 生产者是消息的创建者。它负责将消息发送到消息队列中。生产者可以是系统中的某个模块、服务,或者用户操作触发的事件。无论消息的来源是什么,生产者的作用就是生成需要传递的信息。
    • 在业务系统中,生产者通常是业务事件的触发方,例如用户下单时生成订单信息,并将该信息发送到消息队列中,以便其他系统能够接收和处理该信息。
  2. 存储处理中心

    • 存储处理中心(即消息队列本身)是消息暂存和处理的核心。消息在队列中存储,等待消费者读取和处理。这一中心还具有消息的路由、优先级排序等管理功能,可以根据系统需求决定消息的传递顺序和逻辑。
    • 消息队列的处理中心还具备高可靠性和持久化能力,确保消息不会丢失,即使系统出现故障,消息依然可以安全地被消费。此外,不同消息队列系统还提供不同的消息存储机制(如磁盘或内存存储)来适应不同的性能和可靠性要求。
  3. 消费者(Consumer)

    • 消费者是消息的接收者,它负责从队列中取出消息并进行业务处理。消费者可以是一个服务、一个模块,甚至是多个实例,以实现负载均衡。
    • 消费者通常在处理完消息后,会将消息从队列中移除,确保消息的正确处理。此外,消费者可能会根据业务需求进行异步处理,避免直接与生产者耦合。

为什么要使用消息队列?

在分布式架构中,直接调用可能会导致系统之间的耦合度过高,影响扩展性和稳定性。消息队列的引入能够帮助系统实现模块化,提高系统的灵活性和可靠性。主要有以下几大优势:

  1. 异步处理:在某些情况下,业务流程的实时性并不要求极高,消息队列可以将任务异步化处理,将耗时的操作交给消息队列,提升系统响应速度。例如,用户下单后发通知短信可以通过异步方式完成。
  2. 削峰填谷:在高并发场景中,短时间内的请求量可能远远超出系统处理能力,消息队列可以通过缓冲的方式平滑流量,将请求合理分配到较长的时间段中,从而避免系统崩溃。
  3. 系统解耦:消息队列可以隔离生产者和消费者,使得不同系统之间无需直接调用,实现系统间的松耦合。这样,生产者和消费者可以独立扩展、独立开发和部署,降低耦合度,提升灵活性。
  4. 流量控制:消息队列可以根据消费者的处理能力来分发消息,从而对系统流量进行有效控制,避免某个服务因负载过高而宕机。

消息队列的模式

  1. 点对点(P2P)模式:每条消息只能被一个消费者消费,这种模式下消息是单播的,适用于任务分发等场景。
  2. 发布/订阅(Pub/Sub)模式:消息可以被多个消费者消费,消息发布到一个主题中,订阅该主题的消费者都能接收消息,适用于广播通知、实时消息推送等场景。

工作常用的消息队列

在日常开发中,常用的消息队列主要包括以下三种:

  1. RabbitMQ
  2. Kafka
  3. RocketMQ

接下来,我们逐一了解每种消息队列的概念、架构和工作原理。

本篇文章只讲解一下每类消息队列的工作原理以及区别和选型。不做实际演示 方便我们在自己业务场景中做合适选型和面试了解哈。


RabbitMQ

概念

RabbitMQ 是基于 AMQP(Advanced Message Queuing Protocol)协议的消息代理中间件,能够在不同系统、应用和服务之间实现消息传递、异步处理、负载均衡等功能。它以其稳定性和灵活性著称,广泛应用于订单系统、分布式事务管理和异步消息处理等对消息可靠性要求高的场景。

架构

RabbitMQ 的架构主要包括以下核心组件:

  • Producer(生产者) :负责生成并发送消息到 RabbitMQ。
  • Exchange(交换机) :接收生产者的消息,并根据路由规则将消息分发到对应的队列。
  • Queue(队列) :用于存储消息的容器,消息在队列中等待被消费。
  • Consumer(消费者) :从队列中获取消息进行消费。
  • Binding(绑定) :将交换机和队列关联起来,以便消息能够根据路由规则从交换机到达特定的队列。

交换机是 RabbitMQ 路由消息的核心,它支持多种路由策略,灵活地满足不同的消息传递需求。常见的交换机类型有 Direct、Fanout、Topic 和 Headers,每种交换机类型都适用于特定的场景。

工作原理

RabbitMQ 的消息传递机制可以分为以下几个步骤:

  1. 消息生产:生产者向 RabbitMQ 中的交换机发送消息。消息会带有路由键(routing key),用于指引消息的传递方向。

  2. 消息路由:交换机根据路由键和自身的类型,将消息路由到特定的队列中:

    • Direct 交换机:根据完全匹配的路由键,将消息发送到相应的队列。
    • Fanout 交换机:将消息广播到所有绑定的队列中,忽略路由键。
    • Topic 交换机:基于模糊匹配的路由键分发消息,适用于复杂的路由需求。
    • Headers 交换机:通过消息头中的属性来匹配路由,不使用路由键。
  3. 消息存储:消息在队列中存储,等待消费者消费。RabbitMQ 支持消息持久化,确保在系统故障时不丢失数据。

  4. 消息消费:消费者从队列中取出消息进行处理。在消息被消费后,如果消费者返回确认,RabbitMQ 会将该消息标记为已消费并从队列中删除;否则消息会重新入队,确保消息不会丢失。

  5. 消息确认与重试:RabbitMQ 支持消息确认机制(ACK),消费者可以在成功处理后确认消息。如果消息处理失败,可以配置 RabbitMQ 将消息重新投递(如 Dead Letter Queue)。这一特性确保了消息传递的可靠性。

  6. 延迟消费:RabbitMQ 支持延迟消息处理(延迟消费),可以通过插件或死信队列(Dead Letter Queue, DLQ)实现。借助延迟队列或 TTL(Time to Live,存活时间)功能,可以设置消息的延迟时间,使得消息在指定的时间后才被消费。这一特性在订单超时、任务延迟处理等场景中非常实用。

    • TTL(消息过期时间):可以为消息设置存活时间,到期后消息将自动转入死信队列。
    • 延迟插件:可以实现更精确的延迟消费时间控制,使得消息在精确的时间点被消费。

RabbitMQ 以其灵活的路由策略、可靠的消息传递、延迟消费和丰富的插件支持,被广泛用于需要高度解耦、异步处理的场景。它的延迟消费特性进一步增强了 RabbitMQ 在任务调度、订单处理等领域的适用性,使其成为高可靠性场景中的重要选型。


RocketMQ

概念

RocketMQ 是阿里巴巴开源的分布式消息中间件,专为高吞吐量、低延迟和高可靠性设计。它具有灵活的消息传输模型和强大的消息路由功能,特别适用于金融级别的高可靠、高性能需求场景,例如支付系统、订单系统等。RocketMQ 支持海量消息的处理,是一种非常高效的消息队列系统。

架构

RocketMQ 的架构设计包括以下核心组件:

  • Producer(生产者) :负责将消息发送到 RocketMQ 的 Broker。RocketMQ 支持同步、异步和单向三种消息发送模式,以满足不同业务场景的需求。
  • Broker(代理服务器) :消息存储的核心,负责接收消息、存储消息,并将消息推送给消费者。Broker 还具有分区功能,可以通过分片实现高并发处理。
  • Consumer(消费者) :负责从 Broker 中拉取消息进行消费。RocketMQ 支持推模式和拉模式的消费方式,可以根据需要选择合适的消费模式。
  • Name Server(名称服务器) :名称服务器负责管理 Broker 和 Topic(主题)的元数据信息,用于消息的路由。生产者和消费者通过 Name Server 找到对应的 Broker 和 Topic,实现消息的精确投递。

RocketMQ 的架构以 Broker 为核心,通过 Name Server 提供路由元数据支持,将生产者和消费者连接到正确的 Broker 和分区,实现高效的数据传输和消费。

工作原理

RocketMQ 的消息处理过程可以分为以下几个步骤:

  1. 消息生产:生产者将消息发送到 Broker,消息在发送时会指定 Topic,并可以选择指定的 Tag 进行分类。RocketMQ 支持多种消息发送模式,包括:

    • 同步发送:生产者在发送消息后会等待 Broker 的确认响应,确保消息成功存储。
    • 异步发送:生产者发送消息后不等待响应,而是通过回调函数处理响应,适合对响应时间要求不高的场景。
    • 单向发送:生产者仅发送消息,不等待任何响应,适用于日志或监控等不关心确认的场景。
  2. 消息存储:Broker 将接收的消息写入磁盘,并可以选择将消息持久化,保证消息的可靠性。RocketMQ 支持高效的存储机制,通过 CommitLog 和 Consumer Queue 实现顺序存储和高效读取。

  3. 消息路由:生产者和消费者通过 Name Server 发现 Broker 和 Topic 的分布信息,从而根据消息的 Topic 找到对应的 Broker 并获取消息。Name Server 维护着 Broker 的路由表,支持动态注册和注销,确保消息路由的灵活性和实时性。

  4. 消息消费:消费者根据消费策略从 Broker 拉取消息。RocketMQ 支持多种消费模式:

    • 集群消费模式:多个消费者组成一个消费组,组内每个消费者处理不同分区的数据,保证消息只被消费一次,实现负载均衡。
    • 广播消费模式:消息会被同一个消费组中的所有消费者接收,适用于多实例同时处理同一份数据的场景。
  5. 顺序消息和延迟消息:RocketMQ 支持顺序消息,即消息按照严格的顺序写入和消费,适用于对顺序性有严格要求的场景。此外,RocketMQ 原生支持延迟消息,通过延时级别控制消息的延迟消费,例如订单支付的延迟处理、超时通知等。

  6. 事务消息:RocketMQ 支持分布式事务,通过“半消息”的机制来实现。事务消息发送后,RocketMQ 会先保存消息的预发送状态,等待事务完成确认。这一机制适用于金融系统中的分布式事务,如订单支付和库存扣减等操作。

RocketMQ 以其高吞吐量、低延迟、分布式事务和顺序消费等特性,在金融和互联网行业中得到广泛应用。它在处理海量数据、确保消息顺序性和事务一致性方面表现出色,是高并发、强一致性业务场景下的优选消息队列。


Kafka

概念

Kafka 是一个由 LinkedIn 开发、后被 Apache 基金会接管的分布式流处理平台。它最初设计为高吞吐量的分布式消息队列,但逐渐发展成实时数据流处理平台。Kafka 以高吞吐量和持久化设计著称,主要用于日志收集、实时分析和大数据处理等场景,广泛应用于金融、互联网、和电商行业。

架构

Kafka 的架构主要包括以下核心组件:

  • Producer(生产者) :负责向 Kafka 集群中的 Topic(主题)发送消息。
  • Broker(代理服务器) :Kafka 集群的节点,负责接收、存储、转发消息。Kafka 的每个 Broker 可以处理大量数据和客户端连接。
  • Consumer(消费者) :从 Kafka 中读取消息并处理,消费者可以根据业务需求从指定的 Topic 中拉取消息。
  • Zookeeper:用于存储 Kafka 的元数据(如 Broker 信息和消费者的偏移量),支持分布式协调和故障恢复。
  • Topic(主题) :Kafka 中的逻辑分类单元,生产者将消息发送至指定的 Topic,消费者从指定的 Topic 中读取消息。每个 Topic 可以划分为多个分区(Partition),以实现负载均衡和并发处理。

Kafka 采用分布式、分区化的架构,使其具备高吞吐量、高可用性的特性,能够处理海量实时数据流。

工作原理

Kafka 的消息处理流程可以分为以下几个步骤:

  1. 消息生产:Producer 将消息发送到 Kafka 中的特定 Topic,生产者可以选择发送到 Topic 的特定分区(Partition)。生产者可以根据消息的键值(key)来确定消息的分区,以保证同一键值的消息顺序性。例如,基于用户 ID 的消息会发送到同一分区,以确保消息按顺序处理。

  2. 消息存储与分区:Kafka 中的每个 Topic 可以分为多个分区,每个分区在 Broker 中以日志文件的形式顺序存储。分区的设计确保了 Kafka 可以通过多个 Broker 承载大规模的数据流量,支持水平扩展和高吞吐量。

    • 每个分区在 Broker 上保存了消息的偏移量(Offset),用于标记消息在分区中的位置。偏移量是唯一的序号,保证消息的有序性。
    • Kafka 的分区设计使得消费者可以并行处理同一个 Topic 中的不同分区,从而提升系统的并发处理能力。
  3. 消息消费:Consumer 根据偏移量(Offset)从 Topic 的分区中读取消息。Kafka 提供了两种主要的消费方式:

    • 传统消费:消费者从指定的偏移量开始读取消息,可以通过手动提交偏移量来实现精准控制。
    • 消费者组(Consumer Group) :多个消费者组成一个消费组,每个分区只能被组内一个消费者消费,确保了消费的负载均衡和横向扩展性。不同的消费组之间互不干扰,便于在不同的应用中复用相同的数据流。
  4. 持久化和可靠性:Kafka 支持消息持久化,将消息存储到磁盘中,即使系统崩溃或重启,数据也不会丢失。Kafka 的副本机制还允许每个分区在多个 Broker 上创建副本,通过主从复制和故障转移保证高可用性。

    • 主从复制:Kafka 中的每个分区都有一个主副本和多个从副本。主副本负责读写,从副本负责数据备份,当主副本不可用时,从副本可以立即接管,确保服务不间断。
    • 数据一致性:Kafka 提供 “At Least Once” 和 “Exactly Once” 的消费语义,满足不同业务对消息一致性的要求。
  5. 顺序消息与延迟消息:Kafka 保证分区内消息的顺序性,生产者发送到同一分区的消息会按顺序被消费,但不支持跨分区的全局顺序。Kafka 本身不支持直接的延迟消费功能,但可以通过流处理方式或借助 Kafka Streams 等工具实现定时处理。

  6. 实时流处理:Kafka 逐渐演变为实时流数据处理平台,结合 Kafka Streams 或 Apache Flink 等流处理框架,可以在消息流中进行实时的数据分析、过滤、聚合等操作,适用于监控、实时推荐等场景。

Kafka 以其高吞吐量、分布式架构、可靠的消息持久化和灵活的消费模型,成为日志处理和流数据处理领域的首选消息队列。Kafka 的分区和副本机制使它在大规模数据处理和高并发场景中表现出色,适用于需要实时数据流的复杂业务系统。


三个消息队列的区别

1. 架构设计与消息模型
  • RabbitMQ

    • 基于 AMQP 协议,具有复杂的路由功能,支持多种交换机类型(如 Direct、Fanout、Topic)。
    • 主要用于实现可靠的消息传递和复杂的消息流控制,适合需要高灵活性的业务场景。
  • Kafka

    • 基于分布式日志系统设计,强调高吞吐量和持久化,采用分区和副本机制实现数据冗余和负载均衡。
    • 主要用于日志收集和实时流数据处理,擅长处理大数据和流式数据。
  • RocketMQ

    • 具有高性能和灵活的分布式架构,支持多种消息模型,包括同步、异步、顺序、事务消息。
    • 专为金融级别的高可靠和高并发场景设计,适合金融支付、订单处理等场景。
2. 消息持久化与可靠性
  • RabbitMQ

    • 支持消息持久化和确认机制,确保消息在系统崩溃后不丢失。通过 ACK 确认消息处理,消息可在消费失败时重新投递。
    • 对于高可靠性要求,RabbitMQ 可以通过镜像队列实现多节点冗余。
  • Kafka

    • 消息持久化能力强,消息存储在磁盘上,具备持久化和高可用性。通过分区的主从复制机制,提供数据备份和故障恢复。
    • 提供 “At Least Once” 和 “Exactly Once” 的消费语义,保证数据一致性。
  • RocketMQ

    • 支持消息的持久化,采用 CommitLog 和 Consumer Queue 实现高效存储和消息消费。
    • 支持事务消息,能够实现分布式事务中的半消息机制,适合复杂业务流程中的一致性要求。
3. 是否支持顺序消费
  • RabbitMQ

    • 支持顺序消费,但需要通过特定的配置和单一消费者实现。在负载均衡模式下,顺序性可能无法保证。
  • Kafka

    • 支持分区内消息的顺序消费。生产者发送到同一分区的消息按照顺序被消费,但无法保证跨分区的全局顺序。
  • RocketMQ

    • 原生支持顺序消费,通过分区和标签(Tag)机制实现严格的顺序性,是对顺序性有严格需求的业务的理想选择。
4. 是否支持事务消息
  • RabbitMQ

    • 支持消息确认(ACK)机制,但不支持复杂的分布式事务。
  • Kafka

    • 支持 “Exactly Once” 语义和事务性写入,允许实现跨分区、跨主题的事务,是数据一致性要求高的场景中的一大优势。
  • RocketMQ

    • 原生支持事务消息,通过“半消息”机制实现分布式事务。消息发送后可以等待事务确认,适合金融支付和订单操作等场景。
5. 是否支持延迟消息
  • RabbitMQ

    • 支持延迟消息,但需要借助插件(如 rabbitmq_delayed_message_exchange)或通过死信队列(DLQ)与 TTL 配合实现。
  • Kafka

    • 不直接支持延迟消息功能,但可以通过 Kafka Streams 或其他调度系统来实现延迟消息处理。
  • RocketMQ

    • 原生支持延迟消息,可以根据延迟级别控制消息的消费时间,配置简单,适合任务调度、延迟通知等场景。
6. 吞吐量与延迟
  • RabbitMQ

    • 适合中小规模的消息传递。吞吐量相对 Kafka 和 RocketMQ 较低,但具有较低的消息延迟,适合对实时性要求高的业务。
  • Kafka

    • 吞吐量最高,能够在高并发场景中处理数百万级别的消息,是大数据实时处理的首选。延迟相对较低,适合日志处理和流式计算。
  • RocketMQ

    • 吞吐量较高,性能介于 RabbitMQ 和 Kafka 之间。延迟控制好,支持高并发、低延迟的业务场景。
7. 生态与社区支持
  • RabbitMQ

    • 生态成熟,插件支持丰富,广泛应用于企业应用系统中。易于集成,适合需要快速实现消息中间件的项目。
  • Kafka

    • 拥有庞大的社区支持和丰富的生态系统,如 Kafka Streams 和 Kafka Connect,便于与大数据平台集成,是实时数据处理和大数据分析的首选。
  • RocketMQ

    • 社区支持和发展较好,尤其在国内互联网和金融行业得到广泛应用。支持复杂的消息场景,如分布式事务和延迟消息。

消息队列特性对比

特性RabbitMQKafkaRocketMQ
顺序消费支持部分支持分区内支持支持
事务消息支持不支持支持支持
延迟消息支持支持(插件)不支持原生支持
消息持久化较好
吞吐量中等最高
延迟较低较低中等
生态与社区支持成熟庞大逐渐增强

消息队列选型分析

Kafka

Kafka 是为高吞吐量场景设计的消息队列,最初用于日志收集和传输,并逐渐演变为实时流处理的核心组件。其分布式架构和分区机制使其在高并发下表现出色,非常适合需要处理海量数据的互联网服务,如日志收集、事件跟踪和大数据管道。对于那些生成大量数据、需要快速处理和持久化的大型互联网公司,Kafka 是首选方案,尤其在日志采集、实时分析等场景中展现了强大的处理能力。Kafka 的丰富生态系统,如 Kafka Streams 和 Kafka Connect,使其在数据管道构建和流式数据处理方面无可替代。

适用场景:大数据流处理、日志收集与分析、事件溯源、实时数据传输。

RocketMQ

RocketMQ 是为高可靠性和高并发设计的分布式消息系统,特别适用于金融和电商领域。在这些场景中,消息的可靠传输和严格的顺序保证至关重要,例如订单支付、库存更新等关键业务操作。RocketMQ 原生支持分布式事务、延迟消息和顺序消费,是在复杂业务场景中确保消息一致性和稳定性的理想选择。阿里巴巴在其年度“双 11”大促中,RocketMQ 经受住了超高并发的考验,证明了其在大规模并发和高可靠性需求下的稳定性和可扩展性。

适用场景:电商订单处理、支付系统、削峰填谷、需要分布式事务的应用。

RabbitMQ

RabbitMQ 基于 Erlang 构建,得益于 Erlang 本身的并发优势,在中小规模场景中表现良好。它支持复杂的路由机制、多协议适配,以及丰富的插件生态,具有较高的灵活性和可定制性。对于开发维护而言,RabbitMQ 可能不如其他消息队列在二次开发和深度调优上方便,但其活跃的社区和支持文档能够有效帮助解决开发中的问题。对于数据量适中、不需要超高并发的场景,小型企业可以优先选择 RabbitMQ,以获得快速实现和灵活的消息传递功能。

适用场景:订单系统、任务队列、通知和邮件发送、中小型业务系统的异步处理。


如何选择适合的消息队列?

  1. 高吞吐量和大数据需求:对于需要处理巨量数据并追求高吞吐量的场景,如日志采集和实时数据处理,Kafka 是理想的选择。
  2. 高可靠性和分布式事务:在涉及支付、库存更新等需要强一致性和可靠性的场景中,RocketMQ 更值得信赖,尤其在高并发业务如电商促销活动中。
  3. 中小规模和功能灵活性:如果业务数据量不大且需要快速集成,RabbitMQ 是不错的选择,适用于中小型企业的任务调度和异步处理需求。

通过综合考虑业务需求的特点,如数据量、实时性、并发性、扩展性和开发维护成本,可以帮助团队做出更好的消息队列选型。

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

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

相关文章

优选算法 - 1 ( 双指针 移动窗口 8000 字详解 )

一&#xff1a;双指针 1.1 移动零 题目链接&#xff1a;283.移动零 class Solution {public void moveZeroes(int[] nums) {for(int cur 0, dest -1 ; cur < nums.length ; cur){if(nums[cur] 0){}else{dest; // dest 先向后移动⼀位int tmp nums[cur];nums[cur] num…

鸿蒙操作系统是什么?与安卓系统有什么区别?

鸿蒙操作系统 鸿蒙操作系统&#xff08;HarmonyOS&#xff09;是华为公司发布的一款基于微内核的面向全场景的分布式操作系统。 发展历程&#xff1a; 早期规划&#xff1a;华为从2012 年开始规划自有操作系统&#xff0c;并在芬兰赫尔辛基设立智能手机研发中心&#xff0c;招…

现场工程师日记-MSYS2迅速部署PostgreSQL主从备份数据库

文章目录 一、概要二、整体架构流程1. 安装 MSYS2 环境2. 安装postgresql 三、技术名词解释1.MSYS22.postgresql 四、技术细节1. 创建主数据库2.添加从数据库复制权限3. 按需修改参数&#xff08;1&#xff09;WAL保留空间&#xff08;2&#xff09;监听地址 4. 启动主服务器5.…

第二届计算机网络技术与电子信息工程国际学术会议(CNTEIE 2024,12月6-8日)

第二届计算机网络技术与电子信息工程国际学术会议&#xff08;CNTEIE 2024&#xff09; 2024 2nd International Conference on Computer Network Technology and Electronic and Information Engineering 重要信息 会议官网&#xff1a;www.cnteie.org 2024 2nd Internation…

Git 入门篇(一)

前言 操作系统&#xff1a;win11 64位 与gitee搭配使用 Git 入门篇&#xff08;一&#xff09; Git 入门篇&#xff08;二&#xff09; Git 入门篇&#xff08;三&#xff09; 目录 git下载、安装与配置 下载 安装 配置 git下载、安装与配置 下载 官网&#xff1a;git-…

WPS文档中的“等线”如何删除

如何删除“等线”占用的行如何删除表格之间的空行WPS文档中的“等线”是什么如果删除脚注文本占用的行 如下这种&#xff0c;在文档中添加了表格和脚注&#xff0c;发现上下表格之间有多行空行&#xff0c;鼠标选中&#xff0c;显示是“等线”&#xff0c;那么如何去除等线占用…

题目讲解15 合并两个排序的链表

原题链接&#xff1a; 合并两个排序的链表_牛客题霸_牛客网 思路分析&#xff1a; 第一步&#xff1a;写一个链表尾插数据的方法。 typedef struct ListNode ListNode;//申请结点 ListNode* BuyNode(int x) {ListNode* node (ListNode*)malloc(sizeof(ListNode));node->…

计算机网络基本概念总结

IP地址 概念 使网络中的设备都有唯一的地址标识&#xff0c;用于表示其在网络中的位置。 格式 IP地址是一个32位的二进制数&#xff0c;通常被分割为4个8位二进制数&#xff08;也就是4个字节&#xff09;&#xff0c;如&#xff1a;01100100.00001000.00001010.00000110。通常…

Pandas | 特征列大量数据异常需要填充数据时注意事项

问题描述 一组数据如下&#xff1a; df.isnull().sum()城市 0 名称 0 星级 1529 评分 0 价格 1 销量 1 省/市/区 0 坐标 0 简介 41 是否免费 0 具体地址 3 dtype: int64df[星级]0…

Science Robotics 综述揭示演化研究新范式,从机器人复活远古生物!

在地球46亿年的漫长历史长河中&#xff0c;生命的演化过程充满着未解之谜。如何从零散的化石证据中还原古生物的真实面貌&#xff1f;如何理解关键演化节点的具体过程&#xff1f;10月23日&#xff0c;Science Robotics发表重磅综述&#xff0c;首次系统性提出"古生物启发…

[编译报错]ImportError: No module named _sqlite3解决办法

1. 问题描述&#xff1a; 在使用python进行代码编译时&#xff0c;提示下面报错&#xff1a; "/home/bspuser/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py", line 18, in <module>import sqlite3File "/usr/local/lib/python2.7/sqlite3/_…

EasyExcel的AbstractColumnWidthStyleStrategy注入CellStyle不生效

设置背景色 CellStyle style workbook.createCellStyle();style.setFillForegroundColor(IndexedColors.RED.getIndex()); // 是设置前景色不是背景色style.setFillPattern(FillPatternType.SOLID_FOREGROUND)EasyExcel.writerTable(0).head(Head1.class).registerWriteHandl…

iphone怎么删除重复的照片的新策略

Phone用户常常面临存储空间不足的问题&#xff0c;其中一个主要原因是相册中的重复照片。这些重复项不仅占用了大量的存储空间&#xff0c;还会影响设备的整体性能。本文将向您展示iphone怎么删除重复的照片的方法&#xff0c;包括一些利用工具来自动化这个过程的创新方法。 识…

AI4SCIENSE(鄂维南院士:再谈AI for Science)

鄂维南院士&#xff1a;再谈AI for Science_哔哩哔哩_bilibili 以往处理高维问题 量子力学&#xff1a;单变量乘积 统计学&#xff1a;旋转 AI4S 处理数据 蛋白质折叠&#xff1f; 不是纯粹的数据驱动 物理学等学科基本原理 例&#xff1a;分子动力学 数据模型 流程图 这…

learn C++ NO.31——类型转换

C语言中的类型转换 在C语言中&#xff0c;当赋值符号两边的类型不匹配的时候&#xff0c;或者是形参类型和实参类型不匹配时&#xff0c;返回值类型与接受返回值类型不匹配时&#xff0c;都会需要类型转换。C语言的类型转换有两种&#xff1a;显示类型转换和隐式类型转换。 显…

基于Spring Boot的养老保险管理系统的设计与实现,LW+源码+讲解

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统养老保险管理系统信息管理难度大&#xff0c;容错率低&a…

w029基于springboot的网上购物商城系统研发

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0…

Unet++改进8:添加SpatialGroupEnhance||空间群智能增强:改进卷积网络中的语义特征学习

本文内容:添加SpatialGroupEnhance 论文简介 卷积神经网络(Convolutional Neural Networks, cnn)通过收集分层的、不同部分的语义子特征来生成复杂对象的特征表示。这些子特征通常以分组的形式分布在每一层的特征向量中[43,32],代表各种语义实体。然而,这些子特征的激活往往…

十八:Spring Boot 依赖(3)-- spring-boot-starter-data-jpa 依赖详解

目录 1. 理解 JPA&#xff08;Java Persistence API&#xff09; 1.1 什么是 JPA&#xff1f; 1.2 JPA 与 Hibernate 的关系 1.3 JPA 的基本注解&#xff1a;Entity, Table, Id, GeneratedValue 1.4 JPA 与数据库表的映射 2. Spring Data JPA 概述 2.1 什么是 Spring Dat…

MQTT协议解析 : 物联网领域的最佳选择

1. MQTT协议概述 1.1 MQTT协议是什么 MQTT : Message Queuing Telemetry Transport 模式 : 发布 / 订阅主题优点 : 代码量小、低带宽、实时可靠应用 : 物联网、小型设备、移动应用MQTT 常用端口 : 1883 MQTT是一个网络协议&#xff0c;和HTTP类似&#xff0c;因为轻量简单&…