Kafka 面试题

参考:

  1. https://javabetter.cn/interview/kafka-40.html
  2. https://javaguide.cn/high-performance/message-queue/kafka-questions-01.html

Kafka 架构

在这里插入图片描述

名词概念

  1. Producer(生产者) : 产生消息的一方。

  2. Consumer(消费者) : 消费消息的一方。

  3. Broker(代理) : 可以看作是一个独立的 Kafka 实例。多个 Kafka Broker 组成一个 Kafka Cluster。

    1. Topic(主题) : Producer 将消息发送到特定的主题,Consumer 通过订阅特定的 Topic(主题) 来消费消息。同一 Topic 下的 Partition 可以分布在不同的 Broker 上。

    2. Partition(分区) : Partition 属于 Topic 的一部分。一个 Topic 可以有多个 Partition 。

      Kafka 中的 Partition(分区) 实际上可以对应成为消息队列中的队列

      img

zookeeper在 Kafka 中的作用?

  1. Broker 注册:在 Zookeeper 上会有一个专门用来进行 Broker 服务器列表记录的节点。每个 Broker 在启动时,都会到 Zookeeper 上进行注册,即到 /brokers/ids 下创建属于自己的节点。

  2. Topic 注册:在 Kafka 中,同一个Topic 的消息会被分成多个分区并将其分布在多个 Broker 上,这些分区信息及与 Broker 的对应关系也都是由 Zookeeper 在维护。

    比如我创建了一个名字为 my-topic 的主题并且它有两个分区,对应到 zookeeper 中会创建这些文件夹:/brokers/topics/my-topic/Partitions/0/brokers/topics/my-topic/Partitions/1

  3. 负载均衡:上面也说过了 Kafka 通过给特定 Topic 指定多个 Partition,各个 Partition 可以分布在不同的 Broker(Kafka实例)上**。对于同一个 Topic 的不同 Partition,Kafka 会尽力将这些 Partition 分布到不同的 Broker 服务器上**。当 Consumer 消费的时候,Zookeeper 可以根据当前的 Partition 数量以及 Consumer 数量来实现动态负载均衡。

Kafka 中可以不要 zookeeper 吗?

答:可以,在 Kafka 2.8 之后,引入了基于 Raft 协议的 KRaft 模式,不再依赖 Zookeeper,大大简化了 Kafka 的架构,让你可以以一种轻量级的方式来使用 Kafka。

Kafka 的消息模型?知道队列模型吗?

1、早期的消息模型:队列模型。使用队列(Queue)作为消息通信载体,满足生产者与消费者模式,一条消息只能被一个消费者使用,未被消费的消息在队列中保留直到被消费或超时。存在的问题:

  • 不能将一条消息发送给多个消费者。

队列模型

2、Kafka 消息模型:发布-订阅模式。这种模式可以让一条消息发送给多个消费者。

  • 发布订阅模型(Pub-Sub) 使用主题(Topic) 作为消息通信载体,类似于广播模式
  • 发布者发布一条消息,该消息通过主题传递给所有的订阅者。(在一条消息广播之后才订阅的用户则是收不到该条消息的)

发布订阅模型

Kafka 多副本机制

Kafka 为分区(Partition)引入了多副本(Replica)机制。分区(Partition)中的多个副本之间会有一个叫做 leader 的家伙,其他副本称为 follower。

  • 我们发送的消息会被发送到 leader 副本,然后 follower 副本才能从 leader 副本中拉取消息进行同步。
  • 生产者和消费者只与 leader 副本交互。你可以理解为其他副本只是 leader 副本的拷贝,它们的存在只是为了保证消息存储的安全性。

Kafka 用途

Kafka 是一个分布式流式处理平台。流平台具有三个关键功能:

  1. 消息队列:发布和订阅消息流,这个功能类似于消息队列,这也是 Kafka 也被归类为消息队列的原因。

  2. 容错的持久方式存储记录消息流:Kafka 会把消息持久化到磁盘,有效避免了消息丢失的风险。

  3. 流式处理平台: 在消息发布的时候进行处理,Kafka 提供了一个完整的流式处理类库,可以实时处理数据。

    例如,一个传感器的数据被消费者读取后可以进行处理。比如:,可以进行过滤、转换、聚合、窗口操作等。在检测异常情况的场景中,可能会对传感器数据进行实时分析,比如检查温度是否超过某个阈值、压力是否突然变化等。

Kafka 优势(与 其他消息中间件对比)

Kafka 与 RocketMQ、RabbitMQ 对比。Kafka 具有哪些优势:

  1. 极致的性能:基于 Scala 和 Java 语言开发,设计中大量使用了批量处理和异步的思想,最高可以每秒处理千万级别的消息。
  2. 生态系统兼容性无可匹敌:Kafka 与周边生态系统的兼容性是最好的没有之一,尤其在大数据和流计算领域。

Kafka 为什么要把消息分区(partition)?如何分区?

答:

1、把消息分区有利于:

  • 提高吞吐量:一个Topic可以有多个Partition组成,那么就可以实现并行处理,提高吞吐量。多个消费者可同时处理不同分区的消息。

  • 增强容错性:一个分区故障不影响其他分区,且分区有副本可保证数据可用性。

  • 便于实现负载均衡。可根据消费者数量自动分配分区,确保处理均衡。

    当有多个消费者同时订阅一个主题时,Kafka 会根据消费者的数量自动分配主题的分区给这些消费者。

2、如何分区的:

  • 指明 Partition 的情况:如果生产者在发送消息时明确指定了 Partition 值,那么 Kafka 就直接将该指定的值作为消息要发送到的 Partition。

  • 有 key 但无指定 Partition 的情况:当没有明确指定 Partition 但消息有 key 时,Kafka 会计算 key 的哈希值,然后与该Topic 的分区数量取余,得到的余数就是要放入分区的ID。

    这样可以确保具有相同 key 的消息被分配到同一个 Partition,方便后续的处理和消费。

  • 既无 Partition 也无 key 的情况:在既没有指定 Partition 也没有 key 的情况下,第一次发送消息时,Kafka 会随机生成一个整数。之后每次发送消息,在这个整数上自增,然后将这个值与主题可用的 Partition 总数取余,得到消息要被发送到的 Partition。

    这种方式类似于轮询(round-robin)算法,确保消息在各个 Partition 之间相对均衡地分布。

Kafka 如何保证消息的消费顺序?

答:

具体的分析:Kafka 中 Partition(分区)是真正保存消息的地方,我们发送的消息都被放在了这里。而我们的 Partition(分区) 又存在于 Topic(主题) 这个概念中,并且我们可以给特定 Topic 指定多个 Partition。每次添加消息到 Partition(分区) 的时候都会采用尾加法,如下图所示。 Kafka 只能为我们保证 Partition(分区) 中的消息有序。

消息在被追加到 Partition(分区)的时候都会分配一个特定的偏移量(offset)。Kafka 通过偏移量(offset)来保证消息在分区内的顺序性。

img

因此,常用的 Kafka 保证消息消费的顺序,有两种方式:

  1. 1 个 Topic 只对应一个 Partition。(但是这种办法效率不高)

  2. (推荐)发送消息的时候指定 key/Partition:Kafka 中发送 1 条消息的时候,可以指定 topic, partitionkeydata(数据) 4 个参数。如果你发送消息的时候指定了 Partition 的话,所有消息都会被发送到指定的 Partition。并且,同一个 key 的消息可以保证只发送到同一个 partition。

    例如,在一个电商系统中,如果以订单 ID 作为 “key”,那么所有与同一个订单相关的操作消息(如订单创建、支付、发货等)在发送时都带有相同的订单 ID 这个 “key”。根据 Kafka 的规则,这些具有相同 “key” 的消息会被分配到同一个分区。

Kafka 如何发现消息丢失?

这需要根据消息丢失的位置,具体分析:

  • 生产者端消息丢失
  • 消费者端消息丢失
  • Kafka(broker)服务之间消息同步时,消息丢失

生产者丢失消息、如何知道是否丢失?

丢失情况:生产者(Producer) 调用send方法发送消息之后,消息可能因为网络问题并没有发送过去。

得知消息丢失:通过send()方法返回值查看消息是否发送成功。

  1. 方式1:同步方式,生产者将消息发送出去之后,需要等待消息发送的结果返回。

    // 使用get()方法,是同步的方式
    SendResult<String, Object> sendResult = kafkaTemplate.send(topic, o).get();
    if (sendResult.getRecordMetadata() != null) {
      logger.info("生产者成功发送消息到" + sendResult.getProducerRecord().topic() + "-> " + sendRe
                  sult.getProducerRecord().value().toString());
    }
    
  2. 方式2:异步回调的方式。可以采用异步回调的方式,获取消息发送的结果,从而得知消息是否丢失。

    // send()方法默认的是异步方式        
    ListenableFuture<SendResult<String, Object>> future = kafkaTemplate.send(topic, o);
            future.addCallback(result -> logger.info("生产者成功发送消息到topic:{} partition:{}的消息", result.getRecordMetadata().topic(), result.getRecordMetadata().partition()),
                    ex -> logger.error("生产者发送消失败,原因:{}", ex.getMessage()));
    
生产者端尽量避免消息丢失的方法

设置重试次数、重试间隔(注意重试机制 生产者、消费者都可以用)。这是一种尽可能的避免消息丢失的策略。即当消息发送失败时,可以多重试几次,增加发送成功的几率。

具体方法:

  • 为 Producer 的retries(重试次数)设置一个比较合理的值,一般是 3 ,但是为了保证消息不丢失的话一般会设置比较大一点。设置完成之后,当出现网络问题之后能够自动重试消息发送,避免消息丢失。
  • 另外,建议还要设置重试间隔,因为间隔太小的话重试的效果就不明显了,网络波动一次你 3 次一下子就重试完了。
@Configuration
public class KafkaProducerConfig {

    @Bean
    public ProducerFactory<String, String> producerFactory() {
        Map<String, Object> configProps = new HashMap<>();
        configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "your_kafka_bootstrap_servers");
        configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);

        // 设置重试次数和重试间隔
        RetryTemplate retryTemplate = new RetryTemplate();
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
        retryPolicy.setMaxAttempts(10);
        retryTemplate.setRetryPolicy(retryPolicy);

        FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
        backOffPolicy.setBackOffPeriod(1000); // 重试间隔为 1 秒
        retryTemplate.setBackOffPolicy(backOffPolicy);

        configProps.put(ProducerConfig.RETRIES_CONFIG, retryTemplate);

        return new DefaultKafkaProducerFactory<>(configProps);
    }

    @Bean
    public KafkaTemplate<String, String> kafkaTemplate() {
        return new KafkaTemplate<>(producerFactory());
    }
}

消费者丢失消息的情况,如何知道丢失?

消费者端丢失消息的情况:当消费者拉取到了分区的某个消息之后,消费者会自动提交了 offset。此时会有问题,当消费者刚拿到这个消息准备进行真正消费的时候,突然挂掉了,消息实际上并没有被消费,但是 offset 却被自动提交了。

消息在被追加到 Partition(分区)的时候都会分配一个特定的偏移量(offset)。偏移量(offset)表示 Consumer 当前消费到的 Partition(分区)的所在的位置。Kafka 通过偏移量(offset)可以保证消息在分区内的顺序性。

得知消息丢失的办法:手动关闭自动提交 offset,每次在真正消费完消息之后再自己手动提交 offset

弊端:这样会带来消息被重新消费的问题。比如你刚刚消费完消息之后,还没提交 offset,结果自己挂掉了,那么这个消息理论上就会被消费两次。

Kafka服务端消息丢失,如何避免丢失?

Kafka 为分区(Partition)引入了多副本(Replica)机制。假如 leader 副本所在的 broker 突然挂掉,那么就要从 follower 副本重新选出一个 leader ,但是 leader 的数据还有一些没有被 follower 副本的同步的话,就会造成消息丢失

如何避免丢失?这需要通过以下参数共同起作用:

  1. acks:生产者发送消息后要求的确认机制级别。

    1. acks=0:产者发送消息后,不需要等待任何来自服务器的响应。种设置下,生产者发送消息的速度最快,但消息可能会在网络传输等过程中丢失,因为没有任何确认机制来保证消息已经被成功接收和存储。

    2. acks=1:生产者发送消息后,只要集群中的 leader 成功接收到消息,就会向生产者发送确认响应,而不会管follower 是否接收成功。

    3. acks=all(也可以用acks=-1表示):生产者发送消息后,需要等待所有的同步副本(In-Sync Replicas,ISR)都成功接收到消息后,才会收到来自服务器的确认响应。

      也就是 该分区的 leader、和与leader数据时同步的followers 都接收消息成功。

  2. replication.factor >= 3:指定了一个主题(topic)的副本因子数量,即一个分区(partition)有多少个副本(这里设置为每个分区有一个 leader 副本和3个 follower 副本)。虽然造成了数据冗余,但是带来了数据的安全性

  3. min.insync.replicas > 1:指定了为了被认为是 “已同步” 的,一个分区(partition)中最少需要保持同步状态的副本数量。这样配置代表消息至少要被写入到 2 个副本才算是被成功发送。

  4. unclean.leader.election.enable=false:控制是否允许非同步副本(不在 ISR 中的副本,即与leader数据时同步的followers)成为 leader。当 leader 副本发生故障时就不会从 follower 副本中和 leader 同步程度达不到要求的副本中选择出 leader ,这样降低了消息丢失的可能性。

Kafka 如何保证消息不重复消费?

参考:https://www.cnblogs.com/yangyongjie/p/14675119.html

先说为什么 Kafka 会重复消费消息?

答:主要有如下情况

  1. 消费者宕机、重启等。导致消息已经消费但是没有提交offset。

  2. 消费者在处理耗时的任务,处理时间超过Kafka服务器设置的max.poll.interval.ms时间,Kafka 会误认为这个消费者死掉,会触发再均衡(rebalance)。(在重平衡过程中,其他消费者可能会被分配到之前由该问题消费者处理的分区,而由于偏移量未正确处理,可能会导致重复消费之前已经处理过的消息)

    max.poll.interval.ms参数用于控制消费者在两次调用poll()方法之间的最大时间间隔。超过这个间隔时间这个消费者就会被认为挂掉了。

解决办法:

  1. 幂等校验:消费消息服务做幂等校验,比如 Redis 的 set、MySQL 的主键等天然的幂等功能。这种方法最有效。【推荐】

    比如,消费者在本地存储(如数据库、缓存等)中检查(比如通过订单ID)是否已经处理过具有相同订单号的消息,处理过就不会再次处理了。

  2. 关闭自动提交 offset,改为手动提交 offset。但这种方式可能会有两个问题:

    1. 如果是处理完消息再提交:依旧有消息重复消费的风险,和自动提交一样
    2. 如果是拉取到消息即提交:会有消息丢失的风险。允许消息延时的场景,一般会采用这种方式。然后,通过定时任务在业务不繁忙(比如凌晨)的时候做数据兜底

Kafka 的重试机制?

Kafka 的重试机制

Kafka 的重试机制既可以针对生产者,也可以针对消费者。

  • 当生产者发送消息到 Kafka 集群时,如果出现网络问题、Broker 故障等情况导致消息发送失败,生产者可以配置重试机制来自动重新发送消息,以提高消息发送的成功率。
  • 消费者在消费消息时,如果处理消息的过程中出现异常,也可以通过一定的方式进行重试,以确保消息能够被正确处理。

重试机制默认最多重试10次,每次重试的时间间隔为 0,即立即进行重试。如果在 10 次重试后仍然无法成功消费消息,则不再进行重试,消息将被视为消费失败。当然也可以自定义重试次数、重试间隔。

重试失败后,如何告警?

答:自定义重试失败后逻辑,需要手动实现,以下是一个简单的例子,重写 DefaultErrorHandlerhandleRemaining 函数,加上自定义的告警等操作。

@Slf4j
public class DelErrorHandler extends DefaultErrorHandler {

    public DelErrorHandler(FixedBackOff backOff) {
        super(null,backOff);
    }

    @Override
    public void handleRemaining(Exception thrownException, List<ConsumerRecord<?, ?>> records, Consumer<?, ?> consumer, MessageListenerContainer container) {
        super.handleRemaining(thrownException, records, consumer, container);
        log.info("重试多次失败");
        // 自定义操作
    }
}

重试失败后的数据如何再次处理?-- 死信队列

当达到最大重试次数后,数据会直接被跳过,继续向后进行。当代码修复后,如何重新消费这些重试失败的数据呢?

答:当 Kafka 中的数据重试失败后,可以使用**死信队列(Dead Letter Queue,DLQ)**来进行再次处理。

  • 死信队列(Dead Letter Queue,DLQ):未被正常消费的消息 会被放入死信队列中,在死信队列中,可以进一步分析、处理这些无法正常消费的消息,以便定位问题、修复错误,并采取适当的措施。
  • 在实际使用过程中,可以使用@DltHandler 注解处理。

消费者消息消费时,失败之后会怎么样?

在默认配置下,当消费异常会进行重试,重试多次后会跳过当前消息,继续进行后续消息的消费,不会一直卡在当前消息。

因此,即使某个消息消费异常,Kafka 消费者仍然能够继续消费后续的消息,不会一直卡在当前消息,保证了业务的正常进行。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL---创建数据库(基于SQLyog)

目录 0.前言 1.基本认识 1.1编码集 1.2检验规则 2.库的创建和销毁 2.1指令介绍 2.2你可能会出现的问题 3.查看数据库属性 4.创建指定数据库 5.创建表操作 0.前言 之前写过一篇这个关于表的创建和销毁的操作&#xff0c;但是当时是第一次学习&#xff0c;肯定有些地方…

failed to load steamui.dll的多种处理方法,steamui.dll的作用

在使用Steam平台时&#xff0c;不少玩家可能会遇到“failed to load steamui.dll”这样令人头疼的错误提示。这个错误会阻碍Steam客户端的正常运行&#xff0c;影响我们享受游戏和Steam平台的各种服务。不过&#xff0c;不必过于担心&#xff0c;因为有多种方法可以尝试解决这个…

【Linux】当前进展

驱动层日志添加了下文件目录&#xff0c;函数&#xff0c;代码行的打印&#xff08;这里要小心&#xff0c;驱动目录源代码打印日志里边添进程号可能有问题&#xff0c;因为在驱动初始化的时候&#xff0c;内核还没有创建进程&#xff0c;不过猜测可以先不打印进程相关信息&…

C++ | Leetcode C++题解之第419题棋盘上的战舰

题目&#xff1a; 题解&#xff1a; class Solution { public:int countBattleships(vector<vector<char>>& board) {int row board.size();int col board[0].size();int ans 0;for (int i 0; i < row; i) {for (int j 0; j < col; j) { if (board…

Linux下线程间的通信

为什么需要线程通信&#xff1f; 线程是操作系统调度的最小单元&#xff0c;拥有自己的栈空间。如果线程之间孤立运行&#xff0c;可能会导致资源浪费。线程需要协调工作以完成共同的任务&#xff0c;这就需要线程间相互通信 在 Linux 系统中&#xff0c;线程间通信&#xff…

MySQL数据库进阶知识(四)《视图、存储过程、触发器》

学习目标&#xff1a; 掌握数据库视图基础知识 掌握数据库存储过程原理 掌握数据库触发器相关知识 学习内容&#xff1a; 一. 视图 介绍 视图&#xff08;View&#xff09;是一种虚拟存在的表。视图中的数据并不在数据库中实际存在&#xff0c;行和列数据来自定义视图的查询…

基于GIKT深度知识追踪模型的习题推荐系统源代码+数据库+使用说明,后端采用flask,前端采用vue

基于GIKT深度知识追踪模型的习题推荐系统 目录结构 Flask-BackEnd flask后端 app 后端主体文件 alg 深度学习模块 data 数据集data_process.py 数据预处理gikt.py GIKT模型pebg.py PEBG模型params.py 一些参数train.py 仅模型训练train_test.py 模型训练和测试-五折交叉验证t…

Docker 天池代码提交

参考零基础入门Docker-cuda练习场_学习赛_天池大赛-阿里云天池的赛制 (aliyun.com) ​ 在Docker零基础入门-CSDN博客中我已经安装了docker,现在开始创建自己的镜像仓库。 1. 开通阿里云容器镜像服务(镜像仓库) 进入容器镜像服务 (aliyun.com) 1.1. 创建个人实例 点击“…

try catch 应该在for循环里面还是外面?

今天咱们就来聊聊“try catch 应该在 for 循环里面还是外面”的问题&#xff0c;别小看这句话&#xff0c;背后可是有大智慧的。 首先&#xff0c;咱得明确一点&#xff0c;try catch 是为了处理异常的。它能让你的代码在遇到问题时不至于“崩溃”&#xff0c;更像是你职场生涯…

实景三维夯实数字乡村孪生底座

随着数字乡村建设的不断推进&#xff0c;实景三维技术在乡村规划、管理、服务等方面发挥着越来越重要的作用。本文将探讨实景三维技术如何夯实数字乡村的孪生底座&#xff0c;为乡村的可持续发展提供强有力的支撑。 一、数字乡村建设的背景 数字乡村建设是推动乡村全面振兴、…

使用Crawler实例进行网页内容抓取

网页内容抓取的背景 随着互联网的快速发展&#xff0c;网页上的信息量日益庞大。如何从海量的网页中快速、准确地抓取所需信息&#xff0c;成为了一个技术挑战。网页内容抓取技术通过自动化的方式&#xff0c;模拟用户浏览网页的过程&#xff0c;获取网页上的文本、图片、链接…

探索未来:MultiOn,AI的下一个革命

文章目录 探索未来&#xff1a;MultiOn&#xff0c;AI的下一个革命背景&#xff1a;为什么选择MultiOn&#xff1f;MultiOn是什么&#xff1f;如何安装MultiOn&#xff1f;简单的库函数使用方法场景应用常见问题及解决方案总结 探索未来&#xff1a;MultiOn&#xff0c;AI的下一…

深度学习与应用:行人跟踪

**实验 深度学习与应用&#xff1a;行人跟踪 ** ------ **1、 实验目的** ------ - 了解行人跟踪模型基础处理流程 - 熟悉行人跟踪模型的基本原理 - 掌握 行人跟踪模型的参数微调训练以及推理的能力 - 掌握行人跟踪模型对实际问题的应用能力&#xff0c;了解如何在特定的场景和…

pycirclize python包画circos环形图

pycirclize python包画circos环形图 很多小伙伴都有画环形图的需求&#xff0c;网上也有很多画环形图的教程&#xff0c;讲解circos软件和circlize R包的比较多&#xff0c;本文介绍一款python包:pyCirclize。适合喜欢python且希望更灵活作图的小伙伴。 pyCirclize包实际上也…

LSI SAS 9361-8i和SAS3008 12 gb / s PCIe 3.0 RAID 阵列卡配置

LSI SAS 9361-8i和SAS3008 12 gb / s PCIe 3.0 RAID 阵列卡配置 开机&#xff0c;BIOS自检&#xff0c;可以看到设备硬盘信息&#xff0c;以及提示CtrlR进入Raid卡配置界面。 按CtrlR进入Raid卡配置界面&#xff0c;一般来说使用CtrlR进入Raid卡配置界面的Raid卡配置都通用。 …

【Qualcomm】高通SNPE框架的使用 | 原始模型转换为量化的DLC文件 | 在Android的DSP端运行模型

目录 ① 激活snpe环境 ② 设置环境变量 ③ 模型转换 ④ run 首先&#xff0c;默认SNPE工具已经下载并且Setup相关工作均已完成。同时&#xff0c;拥有原始模型文件&#xff0c;本文使用的模型文件为SNPE 框架示例的inception_v3_2016_08_28_frozen.pb文件。image_file_list…

点餐小程序实战教程11数据源设计

目录 1 设计图2 创建数据源2.1 菜品分类2.2 菜品表 3 创建管理应用4 设置上架下架功能总结 我们用了10篇讲解了一下用户管理及权限设计&#xff0c;有了用户和权限相当于有了骨架&#xff0c;但是我们还需要有良好的设计来确保我们的小程序的开发顺利进行。 在数据源的设计中&a…

通信工程学习:什么是PNF物理网络功能

PNF:物理网络功能 PNF(Physical Network Function)即物理网络功能,是指支持网络功能的物理设备。以下是关于PNF的详细解释: 一、定义与特点 定义: PNF是网络设备厂商(如Cisco、华为、H3C等)通过专用硬件实体提供软件功能的设备。这些设备直接在物理服务器上运…

拓数派荣获上海数据交易所“数据治理服务商”认证

近期&#xff0c;杭州拓数派科技发展有限公司&#xff08;以下简称“拓数派”&#xff09;荣获上海数据交易所“数据治理服务商”认证&#xff0c;标志着拓数派正式加入上海数据交易所数商生态&#xff0c;成为上海数据交易所官方认证的数据治理服务商。拓数派企业发展部总监吴…

初识 C 语言(一)

目录 一、 第一个 C 程序1. printf() 函数和 stdio.h 头文件2. main() 函数和 return 语句 二、类型和变量1. C 语言中的基本类型2. 变量的创建和命名规则3. 类型和变量的大小 三、printf() 函数和 scanf() 函数1. printf() 函数的使用2. 各种类型的输出格式3. scanf() 函数的使…