三、Kafka 基础入门

3.1 Kafka 是什么

Kafka 最初由 LinkedIn 公司开发,是一个开源的分布式事件流平台,后成为 Apache 基金会的顶级项目 。它不仅仅是一个简单的消息队列,更是一个分布式流处理平台,具备强大的消息队列、存储系统和流处理能力。Kafka 采用发布 - 订阅的消息模型,能够以极高的吞吐量处理海量的消息,并且支持将消息持久化到磁盘,确保数据的可靠性和可回溯性。

Kafka 的设计目标主要包括以下几个方面:

  • 高吞吐量:Kafka 在设计上充分考虑了性能因素,通过一系列优化手段,如顺序读写、零拷贝技术等,使其能够在普通的商用硬件上实现单机每秒处理 100K 条以上消息的传输,甚至在集群环境下,吞吐量可以达到每秒百万级别的消息处理能力,这使得它非常适合处理大规模的实时数据。
  • 持久化存储:Kafka 将所有消息都持久化到磁盘上,通过高效的日志存储机制,保证消息的不丢失。它采用追加式的日志写入方式,减少了磁盘寻道时间,提高了写入性能。同时,Kafka 还支持数据的多副本复制,进一步增强了数据的可靠性,即使部分节点出现故障,也不会导致数据丢失。
  • 分布式与扩展性:Kafka 基于分布式架构,一个 Kafka 集群可以由多个 Kafka 服务器(Broker)组成,这些服务器可以分布在不同的物理节点上,实现水平扩展。通过分区(Partition)机制,Kafka 可以将一个大的主题(Topic)分布到多个 Broker 上,从而提高系统的处理能力和负载均衡能力。当业务量增长时,可以方便地添加新的 Broker 节点来扩展集群的容量和性能。
  • 顺序保证:对于同一个分区内的消息,Kafka 能够严格保证它们的顺序性,这在一些对消息顺序有严格要求的场景中非常重要,如金融交易记录、日志记录等。虽然跨分区的消息顺序无法保证,但在很多实际应用中,通过合理的分区设计,可以满足大部分业务对消息顺序的需求。
  • 支持多种客户端和语言:Kafka 提供了丰富的客户端库,支持 Java、C/C++、Scala、Python、Go、Erlang、Node.js 等多种编程语言,方便不同技术栈的开发者在各自的项目中集成和使用 Kafka。

3.2 Kafka 的核心概念

3.2.1 生产者(Producer)

生产者是 Kafka 中负责向 Kafka 集群发送消息的客户端应用程序。它可以将各种类型的数据,如日志信息、业务事件、实时监控数据等,封装成 Kafka 消息,并发送到指定的主题(Topic)中。

在实际应用中,生产者通常会根据业务需求对消息进行一些配置和处理。例如,在一个电商系统中,订单服务作为生产者,当有新订单生成时,它会将订单相关的信息(如订单号、用户 ID、商品信息、订单金额等)封装成 Kafka 消息,并发送到名为 “order - topic” 的主题中。生产者在发送消息时,可以设置消息的键(Key),键的作用主要有两个方面:一是可以用于决定消息被发送到主题的哪个分区,通过对键进行哈希计算,可以将具有相同特征的消息发送到同一个分区,从而保证这些消息在分区内的顺序性;二是在一些场景下,消费者可以根据键来进行消息的筛选和处理,提高处理效率。此外,生产者还可以设置消息的一些属性,如消息的时间戳、压缩方式等,以满足不同的业务需求。生产者发送消息的过程可以是同步的,也可以是异步的。同步发送时,生产者会等待 Kafka 集群的确认响应,确保消息成功发送后才继续执行后续操作;异步发送时,生产者将消息发送到缓冲区后就立即返回,由后台线程负责将缓冲区中的消息批量发送到 Kafka 集群,这种方式可以提高发送效率,适用于对实时性要求不高但对吞吐量要求较高的场景。

3.2.2 消费者(Consumer)

消费者是从 Kafka 集群接收并处理消息的客户端应用程序。它通过订阅一个或多个主题,获取主题中的消息,并按照业务逻辑进行相应的处理。

消费者在 Kafka 中是以消费者组(Consumer Group)的形式存在的。一个消费者组可以包含多个消费者实例,这些消费者实例共同消费一个或多个主题中的消息。在同一个消费者组内,每个消费者负责消费不同分区的数据,这样可以实现消息的并行处理,提高消费效率。例如,假设有一个名为 “user - behavior - topic” 的主题,用于记录用户在网站上的行为数据,它有 4 个分区。现在有一个消费者组,包含 3 个消费者实例。Kafka 会将这 4 个分区分配给这 3 个消费者实例,可能的分配方式是消费者实例 1 消费分区 1 和分区 2,消费者实例 2 消费分区 3,消费者实例 3 消费分区 4。这样,3 个消费者实例可以同时从各自负责的分区中读取消息并进行处理,大大提高了消息的消费速度。

消费者组的这种设计模式使得 Kafka 既支持消息的广播(Broadcast)模式,也支持消息的单播(Unicast)模式。当所有消费者都属于同一个消费者组时,消息会被均衡地投递给每一个消费者,即每条消息只会被一个消费者处理,这就实现了单播模式,类似于点对点的消息传递;当所有消费者都属于不同的消费者组时,消息会被广播给所有的消费者,即每条消息会被所有的消费者处理,这就实现了广播模式,类似于发布 - 订阅模式。

消费者在消费消息时,采用的是拉(Pull)模式,即消费者主动从 Kafka 集群中拉取消息。这种模式与推(Push)模式相比,具有更好的灵活性和可控性,消费者可以根据自身的处理能力来调整拉取消息的频率和数量,避免因为生产者推送消息的速度过快而导致消费者处理不过来的情况。同时,消费者还需要维护一个消费位移(Offset),它表示消费者在分区中已经消费到的位置。每次消费者成功消费消息后,会将消费位移提交给 Kafka 集群,以便在下次消费时能够从上次消费的位置继续读取消息,保证消息的顺序消费和不重复消费。

3.2.3 主题(Topic)

主题是 Kafka 中消息的逻辑分类,它类似于传统消息队列中的队列概念,但又有所不同。每个主题可以看作是一个独立的消息通道,生产者将消息发送到特定的主题,而消费者通过订阅感兴趣的主题来获取消息。

在实际应用中,主题通常根据业务功能或数据类型来划分。例如,在一个社交媒体平台中,可能会有 “user - registration - topic” 主题用于记录用户注册信息,“post - creation - topic” 主题用于记录用户发布的帖子内容,“comment - topic” 主题用于记录用户对帖子的评论等。通过将不同类型的消息划分到不同的主题中,可以方便地对消息进行管理和处理,提高系统的可维护性和可扩展性。

一个 Kafka 集群可以包含多个主题,每个主题可以有多个分区,并且可以为每个主题设置不同的配置参数,如消息的保留时间、副本数量等。生产者在发送消息时,需要指定消息所属的主题;消费者在订阅消息时,也需要指定要订阅的主题。这样,通过主题的概念,Kafka 实现了消息的分类管理和灵活订阅,使得不同的业务模块可以独立地进行消息的生产和消费,而互不干扰。

3.2.4 分区(Partition)

分区是主题的物理细分,每个主题可以包含一个或多个分区。分区的主要作用是提高 Kafka 的并行处理能力和数据可靠性。

从并行处理的角度来看,当一个主题有多个分区时,生产者发送的消息会被分布到不同的分区中,消费者组中的不同消费者实例可以同时从不同的分区中读取消息并进行处理,从而实现了消息的并行消费,大大提高了系统的吞吐量。例如,一个电商系统的 “order - topic” 主题有 10 个分区,当有大量订单生成时,生产者可以将订单消息均匀地分布到这 10 个分区中。同时,一个包含 5 个消费者实例的消费者组可以分别从不同的分区中读取订单消息进行处理,这样可以在短时间内处理大量的订单消息,满足高并发场景下的业务需求。

从数据可靠性的角度来看,每个分区都可以有多个副本(Replica),这些副本分布在不同的 Kafka 服务器(Broker)上。其中,一个副本被选举为领导者(Leader)副本,其他副本为跟随者(Follower)副本。生产者发送的消息会首先被写入到 Leader 副本中,然后 Follower 副本会从 Leader 副本中同步数据,以保持数据的一致性。当 Leader 副本所在的 Broker 出现故障时,Kafka 会从 Follower 副本中选举出一个新的 Leader 副本,继续提供服务,从而保证了数据的可靠性和系统的高可用性。

此外,分区还可以根据键(Key)来进行数据的分配。如果生产者在发送消息时指定了键,Kafka 会根据键的哈希值将消息分配到相应的分区中,这样可以保证具有相同键的消息会被发送到同一个分区,从而满足一些对消息顺序有要求的业务场景。例如,在一个订单处理系统中,将订单 ID 作为消息的键,那么同一个订单的所有相关消息(如订单创建、订单支付、订单发货等)都会被发送到同一个分区,消费者在消费这些消息时,可以按照顺序处理,确保订单处理的正确性和一致性。

四、Kafka 实现异步通信

4.1 异步通信原理

Kafka 的异步通信基于生产者 - 消费者模型和发布 - 订阅模型。在这个模型中,生产者负责将消息发送到 Kafka 集群的指定主题(Topic),而消费者则从感兴趣的主题中订阅并获取消息进行处理。

当生产者有消息要发送时,它并不会直接将消息发送给消费者,而是将消息发送到 Kafka 集群的主题中。Kafka 集群会将这些消息持久化存储在磁盘上,并根据分区(Partition)策略将消息分配到不同的分区中。生产者发送消息的过程是异步的,它在将消息发送到 Kafka 集群后,不需要等待 Kafka 集群的确认响应,就可以继续执行其他操作。这大大提高了生产者的发送效率,减少了因为等待响应而造成的时间浪费,使得生产者能够在短时间内发送大量的消息,提高了系统的吞吐量。

消费者则通过订阅主题来获取消息。消费者可以以消费者组(Consumer Group)的形式存在,同一个消费者组内的不同消费者实例可以同时从同一个主题的不同分区中读取消息并进行处理,实现了消息的并行消费。消费者在消费消息时,采用的是拉(Pull)模式,即消费者主动从 Kafka 集群中拉取消息。消费者会定期向 Kafka 集群发送拉取请求,Kafka 集群根据消费者的请求,将相应分区中的消息返回给消费者。消费者接收到消息后,根据自身的业务逻辑进行处理。处理完成后,消费者会将消费位移(Offset)提交给 Kafka 集群,以便在下次消费时能够从上次消费的位置继续读取消息,保证消息的顺序消费和不重复消费。

这种异步通信机制实现了生产者和消费者之间的解耦。生产者不需要关心消费者是否能够及时接收和处理消息,它只需要将消息发送到 Kafka 集群即可;消费者也不需要关心消息是由哪个生产者发送的,它只需要从 Kafka 集群中获取自己感兴趣的消息进行处理。通过 Kafka 这个中间层,生产者和消费者之间的依赖关系被大大降低,它们可以独立地进行扩展、升级和维护,而不会相互影响。

4.2 Kafka 异步通信的优势

4.2.1 解耦服务

在微服务架构中,各个微服务之间往往存在复杂的依赖关系。如果采用同步通信方式,一个微服务的接口发生变化,可能会导致依赖它的其他微服务也需要进行相应的修改,这增加了系统的维护成本和风险。而 Kafka 的异步通信机制通过消息队列将微服务之间的直接调用转换为间接的消息传递,实现了服务之间的解耦。每个微服务只需要关注自己的业务逻辑和与 Kafka 的交互,不需要关心其他微服务的实现细节和接口变化。例如,在一个电商系统中,订单服务在创建订单后,将订单消息发送到 Kafka 的 “order - topic” 主题中,库存服务和物流服务通过订阅该主题来获取订单消息并进行相应的处理。当订单服务的业务逻辑发生变化,或者需要对订单消息的格式进行调整时,只需要在订单服务内部进行修改,而不会影响到库存服务和物流服务的正常运行,因为它们是通过 Kafka 的消息队列进行通信的,彼此之间没有直接的依赖关系。

4.2.2 削峰填谷

在一些业务场景中,系统可能会面临突发的高并发请求,例如电商平台的促销活动、社交媒体平台的热点事件等。如果采用同步通信方式,系统可能会因为无法及时处理大量的请求而导致性能下降甚至崩溃。Kafka 的异步通信机制可以很好地解决这个问题,它通过消息队列的缓冲作用,将大量的请求消息暂时存储起来,然后在系统负载较低时,再将消息逐步发送给消费者进行处理,实现了削峰填谷的功能。例如,在电商促销活动期间,短时间内会产生大量的订单请求,订单服务将这些订单消息发送到 Kafka 的 “order - topic” 主题中,Kafka 集群可以存储这些大量的订单消息。库存服务和物流服务可以根据自身的处理能力,从 Kafka 集群中逐步拉取订单消息进行处理,避免了因为瞬间高并发请求而导致系统负载过高的问题,保证了系统的稳定性和可靠性。

4.2.3 提升系统响应速度

由于 Kafka 的异步通信机制使得生产者在发送消息后不需要等待消费者的响应,就可以继续执行其他操作,这大大提高了系统的响应速度。在一些对响应时间要求较高的业务场景中,如用户注册、下单等操作,用户希望能够尽快得到系统的反馈。通过使用 Kafka 进行异步通信,生产者可以快速地将消息发送到 Kafka 集群,然后立即返回响应给用户,而不需要等待相关业务逻辑的全部处理完成。例如,在一个在线教育平台中,用户进行课程购买操作时,订单服务将订单消息发送到 Kafka 集群后,立即返回 “订单提交成功” 的响应给用户,后续的课程分配、支付处理等操作由其他微服务通过订阅 Kafka 消息来异步完成。这样,用户能够在最短的时间内得到系统的响应,提升了用户体验,同时也提高了系统的整体处理能力,因为各个微服务可以在后台并行地处理消息,而不会相互阻塞。

4.3 代码示例

以下是使用 Java 语言实现 Kafka 生产者和消费者的代码示例,并对关键配置和消息收发逻辑进行解释。

首先,需要在项目中引入 Kafka 的客户端依赖。如果使用 Maven 项目,可以在pom.xml文件中添加以下依赖:

 

<dependencies>

<dependency>

<groupId>org.apache.kafka</groupId>

<artifactId>kafka-clients</artifactId>

<version>3.1.0</version>

</dependency>

</dependencies>

4.3.1 Kafka 生产者代码示例
 

import org.apache.kafka.clients.producer.*;

import java.util.Properties;

import java.util.concurrent.ExecutionException;

public class KafkaProducerExample {

public static void main(String[] args) throws ExecutionException, InterruptedException {

// Kafka集群地址

String bootstrapServers = "localhost:9092";

// 要发送到的主题

String topic = "test-topic";

// 配置生产者属性

Properties props = new Properties();

// Kafka集群地址

props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);

// 消息的键序列化器

props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");

// 消息的值序列化器

props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");

// 确认机制,"all"表示等待所有副本确认

props.put(ProducerConfig.ACKS_CONFIG, "all");

// 创建生产者实例

KafkaProducer<String, String> producer = new KafkaProducer<>(props);

// 要发送的消息

String key = "key1";

String value = "Hello, Kafka!";

// 创建消息记录

ProducerRecord<String, String> record = new ProducerRecord<>(topic, key, value);

try {

// 发送消息,并同步获取发送结果

RecordMetadata metadata = producer.send(record).get();

System.out.println("Message sent successfully: " +

"Topic: " + metadata.topic() +

", Partition: " + metadata.partition() +

", Offset: " + metadata.offset());

} catch (InterruptedException | ExecutionException e) {

System.out.println("Failed to send message: " + e.getMessage());

} finally {

// 关闭生产者

producer.close();

}

}

}

关键配置解释

  • BOOTSTRAP_SERVERS_CONFIG:指定 Kafka 集群的地址,生产者通过该地址与 Kafka 集群建立连接。
  • KEY_SERIALIZER_CLASS_CONFIG和VALUE_SERIALIZER_CLASS_CONFIG:分别指定消息的键和值的序列化器,用于将消息转换为字节数组发送到 Kafka 集群。这里使用StringSerializer将字符串类型的键和值进行序列化。
  • ACKS_CONFIG:指定生产者的确认机制。"all" 表示生产者在发送消息后,需要等待所有副本都确认收到消息后才认为发送成功,这可以保证消息的可靠性,但会降低发送的性能;"1" 表示生产者只需要等待领导者副本确认收到消息即可;"0" 表示生产者发送消息后不需要等待任何确认。

消息发送逻辑解释

  1. 创建Properties对象,设置生产者的配置属性。
  1. 使用配置属性创建KafkaProducer实例。
  1. 创建ProducerRecord对象,指定要发送的主题、消息的键和值。
  1. 使用producer.send(record).get()方法发送消息,并通过get()方法同步获取发送结果。如果发送成功,get()方法会返回一个RecordMetadata对象,包含消息发送到的主题、分区和偏移量等信息;如果发送失败,会抛出InterruptedException或ExecutionException异常。
  1. 最后,在finally块中关闭生产者,释放资源。
4.3.2 Kafka 消费者代码示例
 

import org.apache.kafka.clients.consumer.*;

import java.time.Duration;

import java.util.Collections;

import java.util.Properties;

public class KafkaConsumerExample {

public static void main(String[] args) {

// Kafka集群地址

String bootstrapServers = "localhost:9092";

// 消费者组ID

String groupId = "test-group";

// 要订阅的主题

String topic = "test-topic";

// 配置消费者属性

Properties props = new Properties();

// Kafka集群地址

props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);

// 消费者组ID

props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);

// 消息的键反序列化器

props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");

// 消息的值反序列化器

props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");

// 自动提交位移的时间间隔

props.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "1000");

// 自动提交位移

props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "true");

// 创建消费者实例

KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);

// 订阅主题

consumer.subscribe(Collections.singletonList(topic));

try {

while (true) {

// 拉取消息,每次拉取等待100毫秒

ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));

for (ConsumerRecord<String, String> record : records) {

System.out.println("Message received: " +

"Topic: " + record.topic() +

", Partition: " + record.partition() +

", Offset: " + record.offset() +

", Key: " + record.key() +

", Value: " + record.value());

}

}

} finally {

// 关闭消费者

consumer.close();

}

}

}

关键配置解释

  • BOOTSTRAP_SERVERS_CONFIG:指定 Kafka 集群的地址,消费者通过该地址与 Kafka 集群建立连接。
  • GROUP_ID_CONFIG:指定消费者组 ID,同一个消费者组内的消费者共同消费订阅主题的消息。
  • KEY_DESERIALIZER_CLASS_CONFIG和VALUE_DESERIALIZER_CLASS_CONFIG:分别指定消息的键和值的反序列化器,用于将从 Kafka 集群接收到的字节数组转换为具体的对象类型。这里使用StringDeserializer将字节数组反序列化为字符串类型的键和值。
  • AUTO_COMMIT_INTERVAL_MS_CONFIG:指定自动提交消费位移的时间间隔,单位为毫秒。消费者在拉取并处理消息后,会按照这个时间间隔自动将消费位移提交给 Kafka 集群。
  • ENABLE_AUTO_COMMIT_CONFIG:设置是否开启自动提交消费位移功能,"true" 表示开启,"false" 表示关闭。如果关闭自动提交,需要手动调用consumer.commitSync()或consumer.commitAsync()方法来提交消费位移。

消息接收逻辑解释

  1. 创建Properties对象,设置消费者的配置属性。
  1. 使用配置属性创建KafkaConsumer实例。
  1. 使用consumer.subscribe(Collections.singletonList(topic))方法订阅指定的主题,这里Collections.singletonList(topic)表示将主题封装成一个单元素的列表。
  1. 在一个无限循环中,使用consumer.poll(Duration.ofMillis(100))方法拉取消息,每次拉取等待 100 毫秒。poll()方法会返回一个ConsumerRecords对象,包含拉取到的所有消息。
  1. 遍历ConsumerRecords对象,获取每个ConsumerRecord,并打印消息的相关信息,包括主题、分区、偏移量、键和值。
  1. 最后,在finally块中关闭消费者,释放资源。

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

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

相关文章

Lighthouse与首屏优化

之前提到首屏优化&#xff0c;想到的就是Vue项目首页打开很慢需要优化。一般都是肉眼看看&#xff0c;对当前的加载速度并没有一个准确的衡量标准&#xff0c;也没有很清晰的解决思路。 前两天我想给自己的网站申请谷歌广告&#xff0c;听说审核对网站的性能要求很高。于是网上…

Maven 之 打包项目时没有使用本地仓库依赖问题

背景 pom 中使用了第三方jar包&#xff0c;远程仓库设置的是阿里云&#xff0c;之前运行很好&#xff0c;今天不知道怎么的&#xff0c;打包总是报错&#xff0c;阿里云仓库无法找到依赖包(本来也没有)&#xff0c;按理来说&#xff0c;编译打包时会优先选择本地仓库的包才对&a…

Mysql基础入门\期末速成

DDL 操作数据库语句 创建&删除数据库语句 创建数据库 create database 数据库名称; -- 直接创建 create database if not exists 数据库名称; -- 如果不存在&#xff0c;则创建 create database 数据库名称 default charset utf8mb4; -- 创建编译类型utf8的数据类型 cre…

SCADA|KingSCADA4.0中历史趋势控件与之前版本的差异

哈喽,你好啊,我是雷工! 最近用到KingSCADA4.0信创版本,也算尝鲜使用。 在使用的过程中发现有些功能或多或少存在一些差异, 这里将遇到的一些不同总结一下,便于后期更好的使用。 01 历史趋势控件 在KingSCADA中有一个历史趋势曲线控件KSHTrend。 该控件既可以连接King…

ubuntu 拒绝ssh连接,连不上ssh,无法远程登录: Connection failed.

目录 问题描述视窗 可视化桌面命令行 问题描述 [C:\~]$ Connecting to 192.166.8.85:22... Could not connect to 192.166.8.85 (port 22): Connection failed.Type help to learn how to use Xshell prompt. [C:\~]$ Connecting to 192.166.8.85:22... Could not connect to …

【大模型应用开发】向量数据库向量检索方法存在问题及优化

一、检索结果重复 1. 问题分析 在构建向量数据库时&#xff0c;对文档分割会存在重复块&#xff08;chunk_overlap&#xff1a;指两个块之间共享的字符数量&#xff0c;用于保持上下文的连贯性&#xff0c;避免分割丢失上下文信息&#xff09;&#xff0c;如下图所示&#xf…

MySQL常用函数详解之数值函数

MySQL常用函数详解之数值函数 一、数值函数概述1.1 数值函数的作用1.2 数值函数分类 二、算术运算函数2.1 加法运算&#xff08;&#xff09;2.2 减法运算&#xff08;-&#xff09;2.3 乘法运算&#xff08;*&#xff09;2.4 除法运算&#xff08;/ 或 DIV&#xff09;2.5 取模…

13、Redis进阶二之Redis数据安全性分析

⼀ 、Redis性能压测脚本介绍 Redis的所有数据是保存在内存当中的&#xff0c; 得益于内存⾼效的读写性能&#xff0c; Redis的性能是⾮常强悍的 。但 是&#xff0c;内存的缺点是断电即丢失&#xff0c;所以 &#xff0c;在实际项⽬中&#xff0c; Redis—旦需要保存—些重要的…

【系统分析师】2011年真题:综合知识-答案及详解

文章目录 【第1题】【第2~3题】【第4~5题】【第6题】【第7~8题】【第9题】【第10题】【第11题】【第12题】【第13题】【第14题】【第15题】【第16题】【第17题】【第18题】【第19~20题】【第21题】【第22题】【第23题】【第24~25题】【第26题】【第27题】【第28题】【第29题】【…

FastAPI-MCP构建自定义MCP工具实操指南

一、简介 • FastAPI-MCP是一个基于python FastAPI框架开发的开源项目&#xff0c;可以自动识别并暴露FastAPI接口为MCP工具 • 拥有FastAPI框架的所有优点&#xff0c;如异步高并发、独立远程部署、OpenAPI文档 • 提供SSE、mcp-remote接入方式&#xff0c;支持设置授权访问…

LLMs之Memory:《LLMs Do Not Have Human-Like Working Memory》翻译与解读

LLMs之Memory&#xff1a;《LLMs Do Not Have Human-Like Working Memory》翻译与解读 导读&#xff1a;该论文通过三个精心设计的实验&#xff0c;证明了当前的大型语言模型&#xff08;LLMs&#xff09;缺乏类似人类的工作记忆。实验结果表明&#xff0c;LLMs无法在没有明确外…

Node.js验证码:从生成到验证的趣味之旅

文章目录 Node.js验证码&#xff1a;从生成到验证的趣味之旅&#x1f4dc; 引言&#xff1a;为什么需要验证码&#xff1f;1. 验证码的基本原理 &#x1f9e0;验证码工作流程示意图 2. 技术栈准备 &#x1f6e0;️3. 验证码生成详解 &#x1f3a8;3.1 生成SVG验证码3.2 转换为P…

芯科科技携最新Matter演示和参考应用精彩亮相Matter开放日和开发者大会

全面展示赋能Matter设备实现跨协议和跨海内外生态的技术能力 作为Matter标准创始厂商之一和其解决方案的领先供应商&#xff0c;Silicon Labs&#xff08;亦称“芯科科技”&#xff09;于6月12至13日参加由连接标准联盟中国成员组&#xff08;CMGC&#xff09;主办的Matter年度…

AndroidStudio下载的SDK没有tool目录,或者想要使用uiautomatorviewer工具

1.如果没有tool目录可以使用下面的地址进行下载 https://dl.google.com/android/repository/tools_r25.2.5-windows.zip 2.并且把下载的文件解压到放在AndroidStudio的目录中 3.如果使用uiautomatorviewer.bat出现下面的错误 Unable to connect to adb.Check if adb is instal…

FastJSON等工具序列化特殊字符时会加转义字符\

在Java中JSON数据格式用String接收时&#xff0c;此时在FastJSON层面看来该JSON只是普通字符串&#xff0c;所以对原字符串序列化会得到转义字符\ 得到转义后字符串&#xff0c;再反序列化转义后字符串会得到原字符串 String json"{\"name\": \"张三\&quo…

数据结构 学习 队列 2025年6月14日 11点22分

循环队列 循环队列是一种线性数据结构&#xff0c;它遵循FIFO&#xff08;先进先出&#xff09;原则&#xff0c;但与普通队列不同的是&#xff0c;循环队列的最后一个元素连接回第一个元素&#xff0c;形成一个环形结构。这种设计有效解决了普通队列的"假溢出"问题&…

打造丝滑滚动体验:Scroll-driven Animations 正式上线!

&#x1f300; 打造丝滑滚动体验&#xff1a;Scroll-driven Animations 正式上线&#xff01; &#x1f6a8; 告别 JS 手动监听滚动条&#xff0c;CSS 新能力让你用两行代码实现高级滚动动效。 &#x1f50d; 什么是 Scroll-driven Animations&#xff1f; Scroll-driven anim…

知识体系_研究模型_价格敏感度测试模型(PSM)

1 概述 价格敏感度测试模型(Price Sensitivity Measurement,PSM) ,通过调研潜在用户对于不同价格的满意或接受程度,从而制定出合适的产品价格。 价格敏感度PSM模型的分析一般分为以下几个步骤: (1)确定多个价格 (2)通过一定的方式(通常是问卷)收集目标客户对不同价…

C++11函数封装器 std::function

✅ 1. 什么是 std::function std::function 是 C11 引入的标准库工具&#xff0c;是一个通用的函数封装器&#xff0c;可以包装以下任意可调用对象&#xff1a; 普通函数Lambda 表达式函数指针成员函数指针函数对象&#xff08;也叫仿函数&#xff0c;定义了 operator() 的类…