【学习笔记】kafka学习二

news2025/8/16 6:38:05

生产者-同步消息发送

如果生产者发送消息没有收到ack,会阻塞到3s时间,如果还没收到消息,会重试,重试3次

生产者-异步消息发送(缺点:消息丢失情况,同步更优)

生产者发送消息后可以直接执行后面的业务,Broker接收到消息后异步调用生产者提供的callback回调方法

 生产者-ack配置prop.put(ProducerConfig.ACKS_CONFIG,"1");

-ack = 0:kafka集群不需要任何的broker收到消息,就立即返回ack给生产者,最容易丢消息,性能是最高的。

-ack = 1:多个副本之间的leader已经收到消息,并把消息写入本地的log中,才会返回ack给生产者,性能和安全性最均衡。

-ack =-1/all:里面有默认配置min.insync.replicas=1(默认为1即和ack=1相同,推荐配置大于等于2)min.insync.replicas=3即将消息写入本地的log,且三个副本(即follower和leader同步)都同步后才返回。

生产者-关于消息发送的缓冲区

 Kafka默认会创建一个消息缓冲区,用来存放要发送的消息,缓冲区为32m

prop.put(ProducerConfig.BUFFER_MEMORY_CONFIG,33554432);

Kafka本地线程会去缓冲区中一次拉16k的数据,发送到Broker

prop.put(ProducerConfig.BATCH_SIZE_CONFIG,16384);

如果线程拉不到16k,间隔10ms也会将已拉倒的数据发送给Broker

prop.put(ProducerConfig.LINGER_MS_CONFIG,10);

消费者需要将所属的消费组+消费的主体+消费的某个分区+消费的偏移量,将信息提交到集群的_consumer_offsets主题里面

消费者-自动提交

消息poll下来以后直接提交offset

可能丢消息:假设消费者poll消息下来(3条),offset提交3,还没消费消息消费者就宕了,再启动另一条消费者去消费,offset为3,从3以后拉取消费消息,前三条消息丢失未消费

消费者-手动提交

在消费消息时/后提交offset

自动提交设为false

prop.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false");

同时消费完消息,手动将offset提交上去

 

手动同步提交,程序应用会进行阻塞,而手动异步提交解决了这个问题,但是异步提交没有重试机制。因为如果程序返回提交失败,消息可能会出现重复消费的情况,假设发起异步提交A,此时提交偏移量是2000,同时又发起异步提交B为3000,此时A成功B失败,会将3000回滚到2000,出现消息重复消费

消费消息poll的细节

poll拉取消息设置拉取消息条数:500条——长轮询1秒

ConsumerRecords<String, String> poll = consumer.poll(1000);


    //1、假设拉到500条消息,则直接消费消息
    //2.假设没有拉到500条,如果时间到了,也进行for循环消费消息

prop.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG,500);


可以根据消费速度来设置,如果两次Poll时间超过30s时间间隔,kafka会认为该消费者消费能力弱,从而踢出消费组,将分区分配给其他消费者
prop.put(ConsumerConfig.MAX_POLL_INTERVAL_MS_CONFIG,30*1000);//30秒

消费者指定分区偏移量和时间消费

consumer给broker发送心跳的时间间隔,1s一次
prop.put(ConsumerConfig.HEARTBEAT_INTERVAL_MS_CONFIG,1000);//1s


kafka如果超过10秒没有收到消费者的心跳,则会吧消费和踢出消费组,进行rebalance,把分区重新分配给其他消费者
prop.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG,10 * 100);

指定主题和分区
consumer.assign(Collections.singleton(new TopicPartition("wangting",0)));

//从头开始消费,可以重复消费消息
consumer.seekToBeginning(Collections.singleton(new TopicPartition("wangting",0)));


//指定位置消费
consumer.seek(new TopicPartition("wangting",0),10);

新消费组消费offset规则

//新消费组消费规则
// earliest 从最早的开始(不记录提交点),如果消费者是新的,则从头,下次则从offset开始
//latest 从最新的开始(记录提交点)从当前分区的最后一条消息的offset+1开始消费(默认!)
//none 报错

prop.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");

 

Kafka线上问题优化

如何防止消息丢失

发送方:ack是1 或者-1/all 可以防止消息丢失,如果要做到99.9999%,ack设成al,把min.insync.replicas配置成分区备份数。消费方:把自动提交改为手动提交。

如何防止消息的重复消费

一条消息被消费者消费多次。如果为了消息的不重复消费,而把生产端的重试机制关闭、消费端的手动提交改成自动提交,这样反而会出现消息丢失,那么可以直接在防治消息丢失的手段上再加上消费消息时的幂等性保证,就能解决消息的重复消费问题。幂等性如何保证:

  1. mysql 插入业务id作为主键,主键是唯一的,所以一次只能插入一条
  2. 使用redis或zk的分布式锁(主流的方案)

如何做到顺序消费

发送方:在发送时将ack不能设置0,关闭重试,使用同步发送,等到发送成功再发送下一条。确保消息是顺序发送的

接收方:消息是发送到一个分区中,只能有一个消费组的消费者来接收消息。

因此,kafka的顺序消费会牺牲掉性能。

解决消息积压问题

消息积压会导致很多问题,比如磁盘被打满、生产端发消息导致kafka性能过慢,就容易出现服务雪崩,就需要有相应的手段:

方案一: 在一个消费者中启动多个线程,让多个线程同时消费。一一提升一个消费者的消费能力。

方案二: 如果方案一还不够的话,这个时候可以启动多个消费者,多个消费者部署在不同的服务器上。其实多个消费者部署在同一服务器上也可以提高消费能力一一充分利用服务器的cpu资源。

方案三: 让一个消费者去把收到的消息往另外一个topic上发,另一个topic设置多个分区和多个消费者,进行具体的业务消费。

延迟队列

延迟队列的应用场景:在订单创建成功后如果超过30分钟没有付款,则需要取消订单,此时可用延时队列来实现。

  1. 创建多个topic,每个topic表示延时的间隔
  1. topic_5s:延时5s执行的队列
  2. topic_1m: 延时1分钟执行的队列
  3. topic_30m:延时30分钟执行的队列
  1. 消息发送者发送消息到相应的topic,并带上消息的发送时间
  2. 消费者订阅相应的topic,消费时轮询消费整个topic中的消息
  1. 如果消息的发送时间,和消费的当前时间超过预设的值,比如30分钟
  2. 如果消息的发送时间,和消费的当前时间没有超过预设的值,则不消费当前的offset及之后的offset的所有消息都消费
  3. 下次继续消费该offset处的消息,判断时间是否已满足预设值

JAVA实现生产者消费者

<dependency>
    <groupId>org.apache.kafka</groupId>
    <artifactId>kafka-clients</artifactId>
    <version>2.0.0</version>
</dependency>
import net.sf.jsqlparser.statement.select.Top;
import org.apache.kafka.clients.consumer.*;
import org.apache.kafka.clients.producer.*;
import org.apache.kafka.common.PartitionInfo;
import org.apache.kafka.common.TopicPartition;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.kafka.common.serialization.StringSerializer;
import org.junit.Test;

import javax.xml.crypto.Data;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class KafkaTest {
    @Test
    public void consumer(){
        Properties prop = new Properties();
        //设置集群地址
        prop.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.235.137:9092");
        //设置key序列化器
        prop.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        //设置值的序列化器
        prop.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        prop.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, "30000");
        prop.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false");
        prop.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "1000");
        //earliest 从最早的开始(不记录提交点)
        //latest 从最新的开始(记录提交点)
        //none 报错
        prop.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
        //模拟多消费者在同一个消费者分组里G2
        prop.put(ConsumerConfig.GROUP_ID_CONFIG, "G2");

        //是否自动提交offset,默认是true
        prop.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG,"true");
        //自动提交offset时间间隔
        prop.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG,"1000");


        for (int i = 0; i < 3; i++) {
            new Thread(() -> {
                KafkaConsumer<String, String> consumer = new KafkaConsumer<>(prop);
                System.out.println(2);
                consumer.subscribe(Collections.singleton("wangting"));
                while (true){
                    ConsumerRecords<String, String> poll = consumer.poll(100);
                    for (ConsumerRecord<String,String> record: poll) {
                        System.out.println(Thread.currentThread().getName()+"\t"+record.offset() + "\t" + record.key() + "\t" + record.value());
                    }
                }
            }).start();
        }
    }

    @Test
    public void oneConsumer(){
        Properties prop = new Properties();
        prop.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.235.137:9092");
        prop.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        prop.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        prop.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false");
        prop.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "1000");
        //新消费组消费规则
        // earliest 从最早的开始(不记录提交点),如果消费者是新的,则从头,下次则从offset开始
        //latest 从最新的开始(记录提交点)从当前分区的最后一条消息的offset+1开始消费(默认!)
        //none 报错
        prop.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
        //分组
        prop.put(ConsumerConfig.GROUP_ID_CONFIG, "G1");
        //consumer给broker发送心跳的时间间隔
        prop.put(ConsumerConfig.HEARTBEAT_INTERVAL_MS_CONFIG,1000);
        //kafka如果超过10秒没有收到消费者的心跳,则会吧消费和踢出消费组,进行rebalance,把分区重新分配给其他消费者
        prop.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG,10 * 100);
        //poll拉取消息设置拉取消息条数:500条——长轮询1秒
            //1、假设拉到500条消息,则直接消费消息
            //2.假设没有拉到500条,如果时间到了,也进行for循环消费消息
        prop.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG,500);
        //可以根据消费速度来设置,如果两次Poll时间间隔超过30s,kafka会认为该消费者消费能力弱,从而踢出消费组,将分区分配给其他消费者
        prop.put(ConsumerConfig.MAX_POLL_INTERVAL_MS_CONFIG,30*1000);



        KafkaConsumer<String, String> consumer = new KafkaConsumer<>(prop);
        //消费者订阅主题
//        consumer.subscribe(Arrays.asList("wangting"));或
        consumer.subscribe(Collections.singleton("wangting"));
        //指定主题和分区
        consumer.assign(Collections.singleton(new TopicPartition("wangting",0)));
        //从头开始消费,可以重复消费消息
        consumer.seekToBeginning(Collections.singleton(new TopicPartition("wangting",0)));
        //指定位置消费
        consumer.seek(new TopicPartition("wangting",0),10);


        //从指定时间点开始消费
//        List<PartitionInfo> partitionInfos = consumer.partitionsFor("wangting");
//        //从一小时前开始消费
//        long fetchDateTime = new Date().getTime() - 1000 * 60 * 60;
//        Map<TopicPartition,Long> map = new HashMap<>();
//        for(PartitionInfo part : partitionInfos){
//            map.put(new TopicPartition("wangting",part.partition()),fetchDateTime);
//        }
//        Map<TopicPartition,OffsetAndTimestamp> parMap = consumer.offsetsForTimes(map);
//        for(Map.Entry<TopicPartition,OffsetAndTimestamp> entry : parMap.entrySet()){
//            TopicPartition key = entry.getKey();
//            OffsetAndTimestamp value = entry.getValue();
//            if(key == null || value == null) continue;
//            Long offset = value.offset();
//            //根据消费者的timestamp确定offset
//            if(value != null){
//                consumer.assign(Arrays.asList(key));
//                consumer.seek(key ,offset);
//            }
//        }




        //一个消费者组G1里只有一个消费者
        while (true){
            //如果1s内每1s内没有poll到任何消息,则继续poll消息,知道Poll到消息。如果超过1s长轮询结束
            ConsumerRecords<String, String> poll = consumer.poll(1000);
            for (ConsumerRecord<String,String> record: poll) {
                System.out.println(record.offset() + "\t" + record.key() + "\t" + record.value());

            }
            //消息到这已经全部消费完
            if(poll.count() > 0){
                //有消息,手动同步提交offset,当前线程会阻塞,直到offset提交成功
                consumer.commitSync();

                //手动异步提交,当前线程提交offset不会阻塞,可以继续处理后面的业务
//                consumer.commitAsync(new OffsetCommitCallback() {
//                    @Override
//                    public void onComplete(Map<TopicPartition, OffsetAndMetadata> map, Exception e) {
//                        if(e != null){
//                            System.out.println("给"+map+"提交失败"+e.getStackTrace());
//                        }
//                    }
//                });
            }
        }
    }

    @Test
    public void oneProducer() throws InterruptedException {
        Properties prop = new Properties();
        prop.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.235.137:9092");
        prop.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        prop.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);

        //重试次数-10次
        prop.put(ProducerConfig.RETRIES_CONFIG,10);

        //重试间隔设置,300ms
        prop.put(ProducerConfig.RETRY_BACKOFF_MS_CONFIG,300);

        //设置缓冲区大小
        prop.put(ProducerConfig.BUFFER_MEMORY_CONFIG,33554432);

        //kafka本地线程从缓冲区取数据,批量发送给Broker,默认值16kb,即16384,batch满16k就发送出去
        prop.put(ProducerConfig.BATCH_SIZE_CONFIG,16384);
        prop.put(ProducerConfig.LINGER_MS_CONFIG,10);

        //ack配置
        //prop.put(ProducerConfig.ACKS_CONFIG,"1");
        KafkaProducer<String, String> producer = new KafkaProducer<>(prop);

        //要发五条消息
        int msgNum = 5;
        final CountDownLatch downLatch = new CountDownLatch(msgNum);
        for(int i = 0;i < 5;i++){
            SimpleDateFormat format = new SimpleDateFormat();
            Date date = new Date(System.currentTimeMillis());
            ProducerRecord<String,String> record = new ProducerRecord<>("wangting",format.format(date));

            //异步,发五条就要五个反馈
            producer.send(record,new Callback(){
                @Override
                public void onCompletion(RecordMetadata recordMetadata, Exception e) {
                    if(e != null){
                        System.out.println("发送消息失败");
                    }
                    if(recordMetadata != null){
                        System.out.println("异步发送消息"+recordMetadata.topic()+recordMetadata.partition()+recordMetadata.offset());
                    }
                    downLatch.countDown();//减一
                }
            });

            //同步
            //        try{
//            producer.send(record);
//
//        }catch (Exception e){
//            e.printStackTrace();
//        }
        }

        Thread.sleep(1000000);
        downLatch.await(5, TimeUnit.SECONDS);//如果不是0继续等5秒
        producer.close();
    }
}

SpringBoot整合Kafka

<dependency>
   <groupId>org.springframework.kafka</groupId>
   <artifactId>spring-kafka</artifactId>
</dependency>
spring:
  kafka:
    bootstrap-servers: 192.168.235.137:9092,192.168.235.137:9093,192.168.235.137:9094
    producer:
      # 重试次数,默认Integer.MAX_VALUE
      retries: 1
      # 同一批次内存大小(默认16K)
      batch-size: 16384
      # 生产者内存缓存区大小(32M)
      buffer-memory: 33554432
      # key和value的序列化(默认,可以不设置)
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.apache.kafka.common.serialization.StringSerializer
      # ack应答机制,默认1,即只需要确认leader收到消息
      acks: 1
        # springboot1.5.16自动装配中不支持properties下的其他配置,不知道为啥。2.x版本可以
        #properties:
        # 使用自定义的分区选择器
      #{partitioner.class: com.msy.kafka.MyPartition, acks: all}
    consumer:
      group-id: test
      enable-auto-commit: false
      # earliest:从头开始消费   latest:从最新的开始消费   默认latest
      auto-offset-reset: latest
      # key和value反序列化(默认,可以不设置)
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
    listener:
      # 消费者并发能力
      concurrency: 6
      # 设置手动提交的时候,需要设置ackMode
#      RECORD :当listener一读到消息,就提交offset
#      BATCH: poll() 函数读取到的所有消息,就提交offset
#      TIME: 当超过设置的ackTime ,即提交Offset
#      COUNT :当超过设置的COUNT,即提交Offset
#      COUNT_TIME :TIME和COUNT两个条件都满足,提交offset
#      MANUAL : 当每批poll的消息全部处理完,Acknowledgment.acknowledge()即提交Offset,和Batch类似
#      MANUAL_IMMEDIATE: 只要调用Acknowledgment.acknowledge()即提交Offset
      ack-mode: MANUAL
    topic: wangting
@RestController
public class MyKafkaController {
    @Resource
    private KafkaTemplate<String,String> kafkaTemplate;

    @RequestMapping("/send")
    public String senMessage(){
        kafkaTemplate.send("wangtng",0,"key","this is a message");
        return "send success;";
    }

}

 

@Component
public class MyConsumer {
    //消费xx主题,为x消费组
//    @KafkaListener(topics = "wangting",groupId = "test")
//    public void listenGroup(ConsumerRecord<String,String> record, Acknowledgment ack){
//        //对每条消息处理
//        String value = record.value();
//        System.out.println(value);
//        System.out.println(record);
//        //手动提交时如果不调用这个方法,消息会重复消费
//        ack.acknowledge();a
//    }

    @KafkaListener(groupId = "test",topicPartitions = {
            @TopicPartition(topic = "topic1",partitions = {"0","1"}),
            @TopicPartition(topic = "topic2",partitions = "0",partitionOffsets = @PartitionOffset(partition = "1",initialOffset = "100"))},
            //在消费topic2主题时,消费0分区不指定,消费1号分区从offset100位置消费
    concurrency = "3")//在这个组下,kafka创建3个消费者去消费,并发消费,建议小于等于分区总数
    public void listenGroup(ConsumerRecord<String,String> record, Acknowledgment ack){
        //对每条消息处理
        String value = record.value();
        System.out.println(value);
        System.out.println(record);
        //手动提交时如果不调用这个方法,消息会重复消费
        ack.acknowledge();
    }
}

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

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

相关文章

脚本是什么意思?有什么特点?与RPA有哪些区别?

脚本是什么意思&#xff1f;有什么特点&#xff1f;与RPA有哪些区别&#xff1f;相信还有不少人对于这三个问题不是很清楚&#xff0c;今天我们小编就给大家来简单回答一下&#xff0c;仅供参考哦&#xff01; 脚本是什么意思&#xff1f; 脚本简单地说就是一条条的文字命令&a…

Linux系统如何重装Windows系统

背景 因为种种原因安装了Linux系统Ubuntu 18.04.6,随之迎来了种种麻烦&#xff0c;于是决定安装回Windows 10系统。 安装步骤如下&#xff1a; 安装步骤一、选择需要安装的系统二、查看CPU运行位数三、下载镜像&#xff08;换一台Windows系统或者使用虚拟机&#xff09;四、创建…

《FFmpeg Basics》中文版-04-调整和伸缩视频

正文 在FFmpeg中调整视频的大小意味着可以通过一个选项改变其宽度和高度&#xff0c;而缩放则意味着使用一个具有高级功能的scale filter来改变帧的大小。 调整视频 输出视频的宽度和高度可以在输出文件名之前设置-s选项。视频分辨率以wxh格式输入&#xff0c;其中w为像素宽…

驱动——ioctl数组及结构体传递

1、ioctl函数是用户程序来控制设备的函数 int ioctl(int fd, unsigned long request, ...); 函数功能&#xff1a;设备控制 参数&#xff1a; fd:文件描述符 request&#xff1a;请求码 ...:可变参数 需要传递地址 返回值&#xff1a;成功返回0&#xff0c;失败返回-1&a…

【ARXIV2207】LightViT: Towards Light-Weight Convolution-Free Vision Transformers

【ARXIV2207】LightViT: Towards Light-Weight Convolution-Free Vision Transformers 论文地址&#xff1a;https://arxiv.org/abs/2207.05557 代码地址&#xff1a;https://github.com/hunto/LightViT 1、研究动机 作者认为&#xff0c;在ViT中混合 convolution&#xff0c;…

高校部署房产管理系统前要认真做好那些基础工作?

高校部署数图互通房产管理系统的目的是为了在学校产权范围的基础上&#xff0c;确保开发工作的合理性、房产资源调配的科学性&#xff0c;强化房产资源的使用&#xff0c;切实将学校房产作用功能发挥出来。 一、在部署房产管理系统前期基础性工作包括&#xff1a; 1、摸清家底…

【C语言】-程序环境和预处理指令

文章目录前言1、翻译环境2、执行环境前言 1、翻译环境 我们的代码运行出来&#xff0c;变为我们人眼可以看到的结果的这个过程会经过两个过程。 一、程序的翻译环境&#xff1a;在这个环境中&#xff0c;源代码会变成可以执行的机器指令。这个过程就是把我们人能看懂的语言转换…

操作系统4小时速成:内存管理,程序执行过程,扩充内存,连续分配,非连续分配,虚拟内存,页面替换算法

操作系统4小时速成&#xff1a;内存管理&#xff0c;程序执行过程&#xff0c;扩充内存&#xff0c;连续分配&#xff0c;非连续分配&#xff0c;虚拟内存&#xff0c;页面替换算法 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&…

艾美捷C1q天然蛋白的应用和化学性质说明

C1q是构成C1的一个重要成分&#xff0c;由小肠、结肠上皮细胞、血液中单核细胞、腹膜巨噬细胞、上皮细胞、肝脏、脾脏等合成。活化后能启发补体经典激活途径。 C1q蛋白家族由众多含C1q结构域的蛋白组成, 从细菌到高等哺乳动物中都有分布。这类蛋白由一条信号肽、胶原样区(Colla…

Java BIO基本介绍

Java BIO基本介绍Java BIO基本介绍工作原理BIO传统通讯实现总结BIO实现多发和多收结果&#xff1a;Java BIO基本介绍 &#x1f4dc;Java BIO就是传统的java io 编程&#xff0c;其相关的类和接口在java.io&#x1f4dc;Blo(blockingl/O):同步阻塞&#xff0c;服务器实现模式为…

Java本地搭建宝塔部署实战springboot仓库管理系统源码

大家好啊&#xff0c;我是测评君&#xff0c;欢迎来到web测评。 本期给大家带来一套Java开发的springboot仓库管理系统源码。 技术架构 技术框架&#xff1a;jdk8 jQuery MySQL5.7 mybatisplus layui shiro运行环境&#xff1a;jdk8 IntelliJ IDEA maven3 宝塔面板 本…

云计算HCIA学习笔记-云计算基础概念

第1章 云计算基础概念 1.1 云计算课程安排说明 &#xff08;IA-虚拟化-FC / IP-Linux OpenStack 桌面云/IE-备份容灾迁移&#xff09; 1.2 为什么云计算IA讲虚拟化&#xff1f; 提前告知学员&#xff0c;为什么IA课程要重点讲解虚拟化&#xff1f;云计算基于OpenStack&…

c++多线程(一)线程管理

来源&#xff1a;微信公众号「编程学习基地」 文章目录1.启动线程2.等待线程完成2.1特殊情况下的等待2.2使用RAII等待线程完成2.3后台运行线程2.4量产线程&#xff0c;等待结束2.传递参数3.转移线程所有权4.运行时决定线程数量2.5 识别线程1.启动线程 当把函数对象传入到线程…

G1D15-fraud-APT-汇报-基础模型与LR相关内容总结-KG-cs224w colab1-ctf rce41-44

一、fraud 跑了一个lr模型&#xff0c;从正则&#xff0c;一直看到了极大似然和最大后验估计emmm。一路跑偏&#xff0c;已经0954了。先把实验结果抄一抄 本来想把模型都跑完&#xff0c;没想到看R补充了大量的基本知识&#xff08;L1\L2正则、先验概率 今天先来看fraud 看的…

Hive——详细总结Hive中各大查询语法

✅作者简介&#xff1a;最近接触到大数据方向的程序员&#xff0c;刚入行的小白一枚 &#x1f34a;作者博客主页&#xff1a;皮皮皮皮皮皮皮卡乒的博客 &#x1f34b;当前专栏&#xff1a;Hive学习进阶之旅 &#x1f352;研究方向&#xff1a;大数据方向&#xff0c;数据汇聚&a…

单隐层神经网络在Matlab上实现及其简单应用

&#x1f352;&#x1f352;&#x1f352;欢迎关注&#x1f308;&#x1f308;&#x1f308; &#x1f4dd;个人主页&#xff1a;我爱Matlab &#x1f44d;点赞➕评论➕收藏 养成习惯&#xff08;一键三连&#xff09;&#x1f33b;&#x1f33b;&#x1f33b; &#x1f34c;希…

Kafka 认证三:添加 Kerberos 认证详细流程

背景 上一章节介绍了 Kerberos 服务端和客户端的部署过程&#xff0c;本章节继续介绍 Kafka 添加 Kerberos 认证的部署流程&#xff0c;及 Java API 操作的注意事项。 sasl.kerberos.service.name 配置的含义 Kafka 添加 Kerberos 部署的核心是 Kafka 服务端的 Principal 配…

基于gensim实现word2vec模型(附案例实战)

目录 什么是word2vec&#xff1f; Word2Vec的原理 gensim实现word2vec模型&#xff08;实战&#xff09; 什么是word2vec&#xff1f; Word2Vec是google在2013年推出的一个NLP工具&#xff0c;它的特点是能够将单词转化为向量来表示&#xff0c;这样词与词之间就可以定量的…

20+个很棒的 Python 脚本的集合(迷你项目)

&#x1f482; 个人网站:【海拥】【摸鱼小游戏】【神级源码资源网站】&#x1f91f; 风趣幽默的前端学习课程&#xff1a;&#x1f449;28个案例趣学前端&#x1f485; 想寻找共同学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】&#x1f4ac; 免费且实用的 前…

【软件分析第17讲-学习笔记】程序综合 Program Synthesis

文章目录前言正文程序综合枚举法CEGIS&#xff1a;基于反例的优化约束求解法启发式搜索法统计法基于组件的程序综合 Component-Based Synthesis小结参考文献前言 创作开始时间&#xff1a; 如题&#xff0c;学习一下程序综合 Program Synthesis的相关知识。参考&#xff1a;熊…