Flink的简单学习四

news2024/10/7 14:33:52

一 有状态计算

1.1 概念

1.状态;上一次计算的结果

2.需要基于上一个结果来进行计算,被称为有状态计算

1.2 未使用有状态计算

1.下面这个代码将相同的key发送到同一个task任务里面计算。就是因为这个导致了,明明之前没有输入b,但是输入b之后,立马变成了2个。说明他是将上一条计算结果直接拿来用了,没有考虑key是不是一样

2.process算子可以在kvDS上面直接进行操作,里面需要传入重写了KeyedProcessFunction里面的processElement方法的对象。

package com.shujia.flink.state;

import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStream;

import org.apache.flink.streaming.api.datastream.KeyedStream;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.KeyedProcessFunction;
import org.apache.flink.util.Collector;

public class Demo1State {
    public static void main(String[] args)throws Exception {

        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        DataStream<String> linesDS = env.socketTextStream("master", 8888);

        KeyedStream<String, String> keyByDS = linesDS.keyBy(word -> word);

        //KeyedProcessFunction<KEY, T, R> keyedProcessFunction
        SingleOutputStreamOperator<Tuple2<String, Integer>> process = keyByDS.process(new KeyedProcessFunction<String, String, Tuple2<String, Integer>>() {

            int count = 0;

            /**
             *
             * @param word 一行数据
             * @param ctx 上下文对象
             * @param out 用于将结果发送到下游
             *
             */
            @Override
            public void processElement(String word,
                                       KeyedProcessFunction<String, String, Tuple2<String, Integer>>.Context ctx,
                                       Collector<Tuple2<String, Integer>> out) throws Exception {
                out.collect(Tuple2.of(word, count));
                count++;

            }
        });

        process.print();

        env.execute();


    }
}

1.3 使用有状态计算

1.使用HashMap保存结果。

package com.shujia.flink.state;

import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.datastream.KeyedStream;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.KeyedProcessFunction;
import org.apache.flink.util.Collector;

import java.util.HashMap;

public class Demo2State {
    public static void main(String[] args)throws Exception {

        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        DataStream<String> wordsDS = env.socketTextStream("master", 8888);

        //分组
        KeyedStream<String, String> keyByDS = wordsDS.keyBy(word -> word);

        /*
         * process算子时flink提供的一个底层算子,可以获取到flink底层的状态,时间和数据
         */
        DataStream<Tuple2<String, Integer>> countDS = keyByDS
                .process(new KeyedProcessFunction<String, String, Tuple2<String, Integer>>() {
                    //保存之前统计的结果(状态)
                    //问题:同一个task中的数据共享同一个count变量
                    //int count = 0;
                    //需要为每一个key保存一个结果
                    //使用单词作为key,数量作为value
                    //问题:使用hashmap保存计算的中间结果,flink的checkpoint不会将hashmap中的数据持久化到hdfs总
                    //所以任务失败重启会丢失之前的结果
                    final HashMap<String, Integer> map = new HashMap<>();
                    /**
                     * processElement方法每一条数据执行一次
                     * @param word 一行数据
                     * @param ctx 上下文对象,可以获取到flink的key和时间属性
                     * @param out 用于将处理结果发送到下游
                     */
                    @Override
                    public void processElement(String word,
                                               KeyedProcessFunction<String, String, Tuple2<String, Integer>>.Context ctx,
                                               Collector<Tuple2<String, Integer>> out) throws Exception {

                        System.out.println(map);
                        //1、通过key获取value
                        //获取之前的结果(状态)
                        Integer count = map.getOrDefault(word, 0);
                        //基于之前的结果进行计算
                        count++;
                        //将计算结果发送到下游
                        out.collect(Tuple2.of(word, count));
                        //更新之前的结果
                        map.put(word, count);
                    }
                });

        countDS.print();

        env.execute();


    }
}

运行过后输入f,会提示之前没有数据,输入h,会提示有个f,因为是在同一个task里面,再输入一个f,会显示2个h一个f

2.但是这些结果都不能持久化保存,想要持久化保存请看2.4节 

 二 checkpointing

2.1 概念

1.可以定时将flink计算的状态持久化到hdfs中,如果任务执行失败,可以基于hdfs中保存到的状态恢复任务,保证之前的结果不丢失。

2.2 设置

2.2.1 代码中设置

1.代码

flink计算的状态会先保存在taskmanager中,当触发checkpoint时会将状态持久化到hdfs中

// 每 1000ms 开始一次 checkpoint
env.enableCheckpointing(5000);
// 高级选项:
// 当手动取消任务时,是否保留HDFS中保留hdfs中的快照
env.getCheckpointConfig().setExternalizedCheckpointCleanup(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);
//flink计算的状态会先保存在taskmanager中,当触发checkpoint时会将状态持久化到hdfs中
//指定状态在算子中保存的位置(状态后端)
//HashMapStateBackend:将状态保存在taskmanager的内存中
env.setStateBackend(new HashMapStateBackend());
//指定checkpoint保存快照的位置
env.getCheckpointConfig().setCheckpointStorage("hdfs://master:9000/flink/checkpoint");
1.ui界面第一次提交

提交jar包跟主类名即可

2.任务取消后,基于hdfs的快照重启任务 

需要找到快照的位置,先在任务取消之前,查看任务id

 再去hdfs上找到这个id相关的路径

 提交的时候加上hdfs://master:9000//然后后面跟上路径

 3.命令行第一次提交

flink run -t yarn-session -p 3 -Dyarn.application.id=application_1717552958247_0001 -c com.shujia.flink.state.Demo1CheckPointing flink-1.0.jar

4.任务取消或者失败后重新提交

1.先在hdfs上找到相对应的任务编号,然后点到chk那边

2.输入命令

flink run -t yarn-session -p 3 -Dyarn.application.id=application_1717552958247_0001 -c com.shujia.flink.state.Demo1CheckPointing -s

hdfs://master:9000/flink/checkpoint/9f54421b62240b04fbde1bc413c98934/chk-2105 flink-1.0.jar

2.2.2 配置文件中设置

1.修改flink-conf.yaml,然后重启Hadoop

execution.checkpointing.interval: 5000
execution.checkpointing.externalized-checkpoint-retention: RETAIN_ON_CANCELLATION
execution.checkpointing.max-concurrent-checkpoints: 1
execution.checkpointing.min-pause: 0
execution.checkpointing.mode: EXACTLY_ONCE
execution.checkpointing.timeout: 10min
execution.checkpointing.tolerable-failed-checkpoints: 0
execution.checkpointing.unaligned: false
state.backend: hashmap
state.checkpoints.dir: hdfs://master:9000/flink/checkpoint

2.提交的方法跟上面一样

2.3 原理

1.JobManager的checkpoint Coordonator(协调器)定期向SourceTask发送Checkpoint Trigger(触发器)。

2.SourceTask在数据流中安排Checkpoint barrier(障碍)

3.SourceTask向下游传递barrier,并自身同步进行快照并将状态写入持久化存储中。

4.整个Task完成后,会汇总最终的快照结果,并将之前的快照删除

 

        

2.4 checkpoint所识别的ValueState

1.因为1.3节使用Java自动HashMap不能被Flink识别,中间状态不能被持久化保留,所以我们要用flink自带的接口去接收中间状态

2.中间状态可以接收的接口

  • ValueState<T>: 保存一个可以更新和检索的值(如上所述,每个值都对应到当前的输入数据的 key,因此算子接收到的每个 key 都可能对应一个值)。 这个值可以通过 update(T) 进行更新,通过 T value() 进行检索。

  • ListState<T>: 保存一个元素的列表。可以往这个列表中追加数据,并在当前的列表上进行检索。可以通过 add(T) 或者 addAll(List<T>) 进行添加元素,通过 Iterable<T> get() 获得整个列表。还可以通过 update(List<T>) 覆盖当前的列表。

  • ReducingState<T>: 保存一个单值,表示添加到状态的所有值的聚合。接口与 ListState 类似,但使用 add(T) 增加元素,会使用提供的 ReduceFunction 进行聚合。

  • AggregatingState<IN, OUT>: 保留一个单值,表示添加到状态的所有值的聚合。和 ReducingState 相反的是, 聚合类型可能与 添加到状态的元素的类型不同。 接口与 ListState 类似,但使用 add(IN) 添加的元素会用指定的 AggregateFunction 进行聚合。

  • MapState<UK, UV>: 维护了一个映射列表。 你可以添加键值对到状态中,也可以获得反映当前所有映射的迭代器。使用 put(UK,UV) 或者 putAll(Map<UK,UV>) 添加映射。 使用 get(UK) 检索特定 key。 使用 entries()keys() 和 values() 分别检索映射、键和值的可迭代视图。你还可以通过 isEmpty() 来判断是否包含任何键值对

3.我们使用ValueState,需要在底层算子process中,先重写open方法,用来创建状态接收对象。

  ValueState<Integer> valueState;

                    //open方法每一个task启动的时候执行一次,一般用于初始化
                    @Override
                    public void open(Configuration parameters) throws Exception {
                        //获取flink环境对象
                        RuntimeContext runtimeContext = getRuntimeContext();
                        //创建状态的描述对象。指定状态的类型和名称
                        ValueStateDescriptor<Integer> valueStateDescriptor = new ValueStateDescriptor<>("count", Types.INT);
                        //初始化状态
                        //ValueState: 单值状态,为每一个key在状态中保存一个值
                        valueState=runtimeContext.getState(valueStateDescriptor);
                    }

ValueState中的value方法是获取上一阶段的状态值,update是更新数据的。完整代码如下

package com.shujia.flink.state;

import org.apache.flink.api.common.functions.RuntimeContext;
import org.apache.flink.api.common.state.ValueState;
import org.apache.flink.api.common.state.ValueStateDescriptor;
import org.apache.flink.api.common.typeinfo.Types;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.datastream.KeyedStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.KeyedProcessFunction;
import org.apache.flink.util.Collector;

import java.util.HashMap;

public class Demo4ValueState {
    public static void main(String[] args)throws Exception {

        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        DataStream<String> wordsDS = env.socketTextStream("master", 8888);

        //分组
        KeyedStream<String, String> keyByDS = wordsDS.keyBy(word -> word);

        /*
         * process算子时flink提供的一个底层算子,可以获取到flink底层的状态,时间和数据
         */
        DataStream<Tuple2<String, Integer>> countDS = keyByDS
                .process(new KeyedProcessFunction<String, String, Tuple2<String, Integer>>() {

                    ValueState<Integer> valueState;

                    //open方法每一个task启动的时候执行一次,一般用于初始化
                    @Override
                    public void open(Configuration parameters) throws Exception {
                        //获取flink环境对象
                        RuntimeContext runtimeContext = getRuntimeContext();
                        //创建状态的描述对象。指定状态的类型和名称
                        ValueStateDescriptor<Integer> valueStateDescriptor = new ValueStateDescriptor<>("count", Types.INT);
                        //初始化状态
                        //ValueState: 单值状态,为每一个key在状态中保存一个值
                        valueState=runtimeContext.getState(valueStateDescriptor);
                    }

                    /**
                     * processElement方法每一条数据执行一次
                     * @param word 一行数据
                     * @param ctx 上下文对象,可以获取到flink的key和时间属性
                     * @param out 用于将处理结果发送到下游
                     */
                    @Override
                    public void processElement(String word,
                                               KeyedProcessFunction<String, String, Tuple2<String, Integer>>.Context ctx,
                                               Collector<Tuple2<String, Integer>> out) throws Exception {
                        //获取状态中保存和值
                        Integer count = valueState.value();
                        //判断count是否为null
                        if (count==null){
                            count=0;
                        }
                        //累加计算
                        count++;
                        //将结果发送到下游
                        out.collect(Tuple2.of(word,count));
                        //更新数据
                        valueState.update(count);
                    }
                });

        countDS.print();

        env.execute();


    }
}

这个是我第一次执行任务输入的

取消任务,看看能不能保存这个状态,然后提交重新提交任务,

发现还在

 

三 Exactly Once

3.1 生产端

1.kafka 0.11之后,Producer的send操作现在是幂等的,在任何导致producer重试的情况下,相同的消息,如果被producer发送多次,也只会被写入Kafka一次 ACKS机制+副本,保证数据不丢失

 kafka保存数据处理的唯一一次:

幂等性:保持数据不重复

事务:保存数据不重复

ACKS+副本:保证数据不丢失

3.1.1 kafka事务

1.开启事务

package com.shujia.flink.state;

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;

import java.util.Properties;

public class Demo6KafkaAffairs {
    public static void main(String[] args)throws Exception {
        Properties properties = new Properties();

        //指定broker列表
        properties.setProperty("bootstrap.servers", "master:9092,node2:9092,node2:9092");

        //指定key和value的数据格式
        properties.setProperty("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        properties.setProperty("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        //给事务取一个名字
        properties.setProperty("transactional.id", "hhh");

        Producer<String, String> producer = new KafkaProducer<String, String>(properties);

        //开启事务
        producer.initTransactions();
        producer.beginTransaction();

        //ProducerRecord<K, V> record
        producer.send(new ProducerRecord<>("train","java"));
        Thread.sleep(10000);
        producer.send(new ProducerRecord<>("train","flink"));

        //提交事务
        producer.commitTransaction();

        producer.flush();

        producer.close();
    }
}

2.消费的命令记得使用读并提交。发现两条数据是一起过来的,如果中间有一条数据是失败的,那么整个数据都过不来,这样保证了数据不重复。

3.1.2 ACKS+副本

1.topic创建是需要多个副本

2.将acks设置成-1或者all。

acks机制:当acks=1时(默认),当主分区写入成功,就会返回成功。如果这个时候主分区所在的节点挂了,刚刚写入的数据就会丢失。当acks=0时,生产者只负责生产数据,不负责验证数据是否写入成功,会丢失数据,但是写入的性能好。当acks=-1或者all时,生产者生产数据后必须等到所有副本都同步成功才会返回成功,这样不会丢失数据,但是写入的性能差。

3.1.3 幂等性

Producer的send操作现在是幂等的,在任何导致producer重试的情况下,相同的消息,如果被producer发送多次,也只会被写入Kafka一次

3.2 消费端

1.Flink 分布式快照保存数据计算的状态和消费的偏移量,保证程序重启之后不丢失状态和消费偏移量

2.flink的数据源如果来自于socket,那么在发生checkpoint之前,有数据进去了并又取消了任务,那么这个数据没有写进hdfs。所以我们换数据源,换成Kafka的生产者产生的数据。这样checkpoint会定时将flink的计算状态和Kafka消费偏移量同时保存到hdfs中,这样不会丢失数据

package com.shujia.flink.state;

import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import org.apache.flink.api.common.serialization.SimpleStringSchema;
import org.apache.flink.api.common.typeinfo.Types;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.connector.kafka.source.KafkaSource;
import org.apache.flink.connector.kafka.source.enumerator.initializer.OffsetsInitializer;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.datastream.KeyedStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;

public class Demo7ExactlyOnce {
    public static void main(String[] args) throws Exception{
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        //创建kafka source
        KafkaSource<String> source = KafkaSource.<String>builder()
                .setBootstrapServers("master:9092,node1:9092,node2:9092")//kafka集群列表
                .setTopics("kafka_flink")//指定消费的topic
                .setGroupId("my-group")//指定消费者组
                .setStartingOffsets(OffsetsInitializer.earliest())
                .setValueOnlyDeserializer(new SimpleStringSchema())//指定读取数据的格式
                .build();

        //使用kafka source
        DataStream<String> wordsDS = env
                .fromSource(source, WatermarkStrategy.noWatermarks(), "Kafka Source");

        //3、统计单词的数量
        DataStream<Tuple2<String, Integer>> kvDS = wordsDS
                .map(word -> Tuple2.of(word, 1), Types.TUPLE(Types.STRING, Types.INT));

        //分组统计单词的数量
        KeyedStream<Tuple2<String, Integer>, String> keyByDS = kvDS.keyBy(kv -> kv.f0);

        //对下标为1的列求和
        DataStream<Tuple2<String, Integer>> countDS = keyByDS.sum(1);

        //打印数据
        countDS.print();

        //启动flink
        env.execute();


    }
}

3.3 sink端

1.flink在聚合计算后将结果写进hdfs或者kafka中,如果在中间某一个时间有数据进去但是任务又取消或者失败了,但是这样结果不会重复。然而,在非聚合计算中,如果在中间某一个时间有数据进去但是任务又取消或者失败了,这样kafka或者hdfs中数据会重复

package com.shujia.flink.state;

import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import org.apache.flink.api.common.serialization.SimpleStringSchema;
import org.apache.flink.connector.base.DeliveryGuarantee;
import org.apache.flink.connector.kafka.sink.KafkaRecordSerializationSchema;
import org.apache.flink.connector.kafka.sink.KafkaSink;
import org.apache.flink.connector.kafka.source.KafkaSource;
import org.apache.flink.connector.kafka.source.enumerator.initializer.OffsetsInitializer;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;

import java.util.Properties;

public class Demo8ExactlyOnceKafkaSink {
    public static void main(String[] args)throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        //创建kafka source
        KafkaSource<String> source = KafkaSource.<String>builder()
                .setBootstrapServers("master:9092,node1:9092,node2:9092")//kafka集群列表
                .setTopics("kafka_flink")//指定消费的topic
                .setGroupId("my-group")//指定消费者组
                .setStartingOffsets(OffsetsInitializer.earliest())
                .setValueOnlyDeserializer(new SimpleStringSchema())//指定读取数据的格式
                .build();

        //使用kafka source
        DataStream<String> wordsDS = env
                .fromSource(source, WatermarkStrategy.noWatermarks(), "Kafka Source");

        DataStream<String> filterDS = wordsDS.filter(word -> !"".equals(word));

//        Properties properties = new Properties();
        //指定事务超时时间,不能大于15分钟
//        properties.setProperty("transaction.timeout.ms", 1000 * 60 * 10 + "");

        //创建kafka sink
        KafkaSink<String> sink = KafkaSink.<String>builder()
                .setBootstrapServers("master:9092,node1:9092,node2:9092")//kafka集群列表
//                .setKafkaProducerConfig(properties)
                .setRecordSerializer(KafkaRecordSerializationSchema.builder()
                        .setTopic("filter")//指定topic
                        .setValueSerializationSchema(new SimpleStringSchema())//指定数据格式
                        .build()
                )
                //指定数据处理的语义
                .setDeliverGuarantee(DeliveryGuarantee.AT_LEAST_ONCE)
                .build();

        //使用kafka sink
        filterDS.sinkTo(sink);

        //启动flink
        env.execute();


    }
}

提交这个任务代码,执行一次后,再他执行checkpoint之前再次输入shujiashujia,取消任务,然后再通过上一次的checkpoint重启任务,发现:消费端居然消费了两次shujiashujia

生产端:

消费端:

2.为了避免在非聚合计算中,状态或者消费的偏移量存储到kafka或者hdfs中,数据不重复,我们需要开启 Kafka事务。代码如下

package com.shujia.flink.state;

import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import org.apache.flink.api.common.serialization.SimpleStringSchema;
import org.apache.flink.connector.base.DeliveryGuarantee;
import org.apache.flink.connector.kafka.sink.KafkaRecordSerializationSchema;
import org.apache.flink.connector.kafka.sink.KafkaSink;
import org.apache.flink.connector.kafka.source.KafkaSource;
import org.apache.flink.connector.kafka.source.enumerator.initializer.OffsetsInitializer;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;

import java.util.Properties;

public class Demo8ExactlyOnceKafkaSink {
    public static void main(String[] args)throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        //创建kafka source
        KafkaSource<String> source = KafkaSource.<String>builder()
                .setBootstrapServers("master:9092,node1:9092,node2:9092")//kafka集群列表
                .setTopics("kafka_flink")//指定消费的topic
                .setGroupId("my-group")//指定消费者组
                .setStartingOffsets(OffsetsInitializer.earliest())
                .setValueOnlyDeserializer(new SimpleStringSchema())//指定读取数据的格式
                .build();

        //使用kafka source
        DataStream<String> wordsDS = env
                .fromSource(source, WatermarkStrategy.noWatermarks(), "Kafka Source");

        DataStream<String> filterDS = wordsDS.filter(word -> !"".equals(word));

        Properties properties = new Properties();
        //指定事务超时时间,不能大于15分钟
        properties.setProperty("transaction.timeout.ms", 1000 * 60 * 10 + "");

        //创建kafka sink
        KafkaSink<String> sink = KafkaSink.<String>builder()
                .setBootstrapServers("master:9092,node1:9092,node2:9092")//kafka集群列表
                .setKafkaProducerConfig(properties)
                .setRecordSerializer(KafkaRecordSerializationSchema.builder()
                        .setTopic("filter")//指定topic
                        .setValueSerializationSchema(new SimpleStringSchema())//指定数据格式
                        .build()
                )
                //指定数据处理的语义
                .setDeliverGuarantee(DeliveryGuarantee.EXACTLY_ONCE)
                .build();

        //使用kafka sink
        filterDS.sinkTo(sink);

        //启动flink
        env.execute();


    }
}

这样我们在生产端产生数据,只有产生checkpoint,才会消费数据(消费端使用读并提交的方式)

但是这样会增加数据延迟

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

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

相关文章

算数运算符与表达式(打印被10整除的数)

打印100以内&#xff08;包含100&#xff09;能被10整除的正整数 #include <stdio.h>#define UPPER 100int main() {int i 1;while (i < UPPER)if (i % 10 0)printf("%d\n", i);return 0; } 自增运算符 i 用于递增变量 i 的值。在 while 循环中&#xf…

GPT-4欺骗人类的惊人成功率达99.16%!

PNAS重磅研究揭示&#xff0c;LLM推理能力越强欺骗率越高&#xff01;&#xff01; 此前&#xff0c;MIT的研究发现&#xff0c;AI在各类游戏中为了达到目的&#xff0c;不择手段&#xff0c;学会用佯装和歪曲偏好等方式欺骗人类。 GPT-4o深夜发布&#xff01;Plus免费可用&…

CANoe-Trace窗口无法解析SOME/IP报文、Demo License激活方式改变

1、Trace窗口无法解析SOME/IP报文 在文章《如何让CANoe或Wireshark自动解析应用层协议》中,我们通过设置指定端口号为SOME/IP报文的方式,可以让CANoe中的Trace窗口对此端口号的报文当成是SOME/IP报文进行解析。 Trace窗口就可以根据传输层端口号对payload数据按照SOME/IP协议…

system 和 exec 的区别

在 linux 中&#xff0c;使用 system 和 exec 都可以执行一个程序或者执行一个命令。两者的区别如下&#xff1a; system 中创建了一个子进程&#xff0c;在子进程中执行用户的命令&#xff0c;子进程执行完毕之后&#xff0c;system 会返回。exec 不会创建子进程&#xff0c;…

深入Llama2:掌握未来语言模型的秘密

Llama2是一个基于Transformer架构的大型语言模型&#xff0c;它旨在处理和理解大规模的文本数据。作为技术人员&#xff0c;了解Llama2的工作原理、模型结构和训练方法对于有效利用该模型至关重要。本文将详细介绍Llama2的基本概念、主要作用、使用方法及注意事项。 一、简介 …

msvcr120.dll丢失怎样修复?为什么msvcr120.dll文件很重要

msvcr120.dll​ 是一个属于 Microsoft Visual C 2013 Redistributable package 的动态链接库文件。这个文件对于运行使用 Visual Studio 2013 开发的应用程序是必要的&#xff0c;因为它包含了C运行时库的一部分功能&#xff0c;这些功能是标准C库中与输入/输出操作、字符串操作…

MySQL的PrepareStatement真的是预编译语句么?

PrepareStatement真的是预编译语句么&#xff1f; ChatGPT对PrepareStatement的定义是&#xff1a; PrepareStatement 是 Java 数据库连接&#xff08;JDBC&#xff09;API 中用于执行预编译 SQL 语句的接口。通过使用 PreparedStatement&#xff0c;可以预编译 SQL 语句&…

66. UE5 RPG 实现远程攻击武器配合角色攻击动画

在制作游戏中&#xff0c;我们制作远程攻击角色&#xff0c;他们一般会使用弓箭&#xff0c;弩&#xff0c;弹弓等武器来进行攻击。比如你使用弓箭时&#xff0c;如果角色在播放拉弓弦的动画&#xff0c;但是弓箭武器没有对应的表现&#xff0c;会显得很突兀。所以&#xff0c;…

小白都可以通过U盘重装系统,再也不用花50块钱去安装系统啦

下载Ventoy 软件 1、今天带着大家通过Ventoy 安装Windows 11 系统。 2、首先我们通过官网如下地址&#xff1a;https://www.ventoy.net/cn/&#xff0c;找到我们对应系统的Ventoy 软件安装包。 3、通过官网可以找到软件包的地址地址&#xff0c;如下图所示。 4、如下就是我下…

Nginx的https功能和防盗链

目录 一.HTTPS功能简介 二.https自签名证书 三.防盗链 一.HTTPS功能简介 Web网站的登录页面都是使用https加密传输的&#xff0c;加密数据以保障数据的安全&#xff0c;HTTPS能够加密信息&#xff0c;以免敏感信息被第三方获取&#xff0c;所以很多银行网站或电子邮箱等等安…

clickHouse实现表自增ID的代码及相关逻辑

一、介绍 clickHourse表自增ID主要时两种方式&#xff1a; insert数据时&#xff0c;手动维护一个全局ID给表设置uuid字段&#xff0c;使用 generateUUIDv4()函数赋予默认值。 这里的话推荐手动维护一个全局的自增ID&#xff0c;不推荐使用UUID的方式&#xff0c;主要原因有…

java —— 线程(一)

一、进程与线程 一个进程可以包含一个以上的线程&#xff0c;CPU 时间片切换的基本单位是线程。 二、创建线程 &#xff08;一&#xff09;继承 Thread 类 public class Task extends Thread{Override //重写run方法public void run(){System.out.pr…

Nginx部署多web进程

1、nginx介绍 Nginx是一个高性能的、开源的、跨平台的Web服务器和反向代理服务器。它是由俄罗斯的程序员Igor Sysoev开发的&#xff0c;并于2004年首次公开发布。 Nginx的特点包括&#xff1a; 高性能&#xff1a;Nginx使用事件驱动的架构&#xff0c;能够处理大量的并发连接…

HarmonyOS鸿蒙应用开发——ArkUI组件封装最佳实践

文章目录 背景与案例描述静态注册属性-封装UI组件动态注册属性-封装UI组件总结 背景与案例描述 在应用开发中&#xff0c;对一些频繁使用的业务UI组件常常会进行一层封装&#xff0c;提取到公共基础库中实现组件的复用&#xff0c;避免类似的逻辑重复编写&#xff0c;减少代码…

【前端技术】 ES6 介绍及常用语法说明

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

LabVIEW缝缺陷图像标注库

LabVIEW缝缺陷图像标注库 开发了一个基于LabVIEW平台构建的船舶焊缝缺陷图像标注库。该库旨在通过高效和简洁的方式处理和标注船舶焊缝缺陷图像&#xff0c;提高缺陷识别的准确性和效率&#xff0c;进而保障船舶的结构安全。 项目背景 在船舶制造过程中&#xff0c;焊接质量…

递归【1】(全排列andN皇后)(排列型回溯)

全排列 分治与递归 递归是实现分治的一种方法 思想思路 题目&#xff1a; 全排列i 我这样直接输出会多输出一个空行&#xff08;最后一个\n&#xff09; #include<stdio.h>using namespace std; const int maxn10; int an[maxn]; int n; bool hash[maxn]{0}; int c0…

STM32-15-DMA

STM32-01-认识单片机 STM32-02-基础知识 STM32-03-HAL库 STM32-04-时钟树 STM32-05-SYSTEM文件夹 STM32-06-GPIO STM32-07-外部中断 STM32-08-串口 STM32-09-IWDG和WWDG STM32-10-定时器 STM32-11-电容触摸按键 STM32-12-OLED模块 STM32-13-MPU STM32-14-FSMC_LCD 文章目录 STM…

【Java面试】十七、并发篇(上)

文章目录 1、synchronized关键字的底层原理&#xff1a;Monitor2、synchronized相关2.1 为什么说synchronized是重量级锁2.2 synchronized锁升级之偏向锁2.3 synchronized锁升级之轻量级锁 3、Java内存模型JMM4、CAS4.1 CAS流程4.2 CAS底层实现 5、volatile关键字的理解5.1 可见…

区块链(Blockchain)调查研究(一)

文章目录 1. 区块链是什么&#xff1f;2. 区块链分类和特点3. 区块链核心关键技术3.1 共识机制3.2 密码学技术3.4 分布式存储3.5 智能合约 4. 区块链未来发展趋势5. 区块链能做什么、不能做什么&#xff1f;5.1 第一部分5.2 第二部分5.3 第三部分&#xff08;结论&#xff09; …