5、flink任务中可以使用哪些转换算子(Transformation)

news2025/1/23 7:13:18

1、什么是Flink中的转换算子

        在使用 Flink DataStream API 开发流式计算任务时,可以将一个或多个 DataStream 转换成新的 DataStream,在应用程序中可以将多个数据转换算子合并成一个复杂的数据流拓扑图。


2、常用的转换算子 

        Flink提供了功能各异的转换算子,Map,FlatMap,Filter,KeyBy,Reduce,Window,WindowAll...
通过操作各种转换算子,来获取新的DataStream及子类的实例,来完成计算需求。

Tips: 下面测试用例基于 Flink1.17.0、java1.8 编写


3、基本转换算子(map/ filter/ flatMap)

3.1 Map

功能说明:

DataStream[T] → DataStream[R]
输入一个元素同时输出一个元素,可以对元素的数据类型和内容做转换,好比SQL中的UDF函数

代码示例:

package com.baidu.datastream.transform;

import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;

public class Map {
    public static void main(String[] args) throws Exception {
        // 1.获取执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        // 2.使用 Map 算子
        // 方式1:使用 Lambda表达式
        env.fromElements("刘备", "张飞", "关羽", "赵云", "马超", "黄忠")
                .map(value -> value + "_")
                .print();

        // 方式2:使用 MapFunction实现类
        /*
         *  TODO MapFunction<T, O>
         *   功能说明:
         *      对元素做1:1映射转换
         *   泛型说明:
         *      @T : 输入数据类型
         *      @O : 输出数据类型
         * */
        MapFunction<String, Integer> mapFunction = new MapFunction<String, Integer>() {
            @Override
            public Integer map(String value) throws Exception {
                return value.length();
            }
        };

        env.fromElements("刘备", "张飞", "关羽", "赵云", "马超", "黄忠")
                .map(mapFunction)
                .print();

        // 3.触发程序执行
        env.execute();
    }
}

执行结果:


 3.2 FlatMap 

功能说明:

DataStream[T] → DataStream[R]
输入一个元素同时产生零个、一个或多个元素,好比SQL中的UDTF(1对多)函数

 代码示例:

package com.baidu.datastream.transform;

import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.util.Collector;

public class FlatMap {
    public static void main(String[] args) throws Exception {
        // 1.获取执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        // 2.使用 FlatMap 算子

        // 方式:使用 flatMapFunction实现类
        /*
         *  TODO flatMapFunction<T, O>
         *   功能说明:
         *      对输入元素做1:多的转换(好比SQL中的UDTF函数)
         *   泛型说明:
         *      @T : 输入数据类型
         *      @O : 输出数据类型
         * */
        FlatMapFunction<String, String> flatMapFunction = new FlatMapFunction<String, String>() {

            @Override
            public void flatMap(String value, Collector<String> out) throws Exception {
                for (String s : value.split("_")) {
                    out.collect(s);
                }
            }
        };

        env.fromElements("刘_备", "张_飞", "关_羽", "赵_云", "马_超", "黄_忠")
                .flatMap(flatMapFunction)
                .print();

        // 3.触发程序执行
        env.execute();
    }
}

执行结果:


3.3 Filter

功能说明:

DataStream[T] → DataStream[T]
为每个元素执行一个逻辑判断,并保留那些判断为 true 的元素,好比SQL中的where

代码示例:

package com.baidu.datastream.transform;

import org.apache.flink.api.common.functions.FilterFunction;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;

public class Filter {
    public static void main(String[] args) throws Exception {
        // 1.获取执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        // 2.使用 Filter 算子
        // 方式1:使用 Lambda表达式
        env.fromElements("刘备", "张飞", "关羽", "赵云", "马超", "黄忠")
                .filter(value -> value.equals("刘备"))
                .print();

        // 方式2:使用 FilterFunction实现类
        /*
         *  TODO FilterFunction<T, O>
         *   功能说明:
         *      对元素过滤处理
         *   泛型说明:
         *      @T : 输入数据类型
         * */
        FilterFunction<String> filterFunction = new FilterFunction<String>() {

            @Override
            public boolean filter(String value) throws Exception {
                return value.equals("张飞");
            }
        };

        env.fromElements("刘备", "张飞", "关羽", "赵云", "马超", "黄忠")
                .filter(filterFunction)
                .print();

        // 3.触发程序执行
        env.execute();
    }
}

执行结果:


4、聚合算子

4.1 KeyBy(按键分区)

功能说明:

DataStream[T] → KeyedStream[T,K]
根据指定的字段(key),将数据划分到不相交的分区中。相同key的元素会被分到同一个分区中。

分区规则:
          分区编号 =  指定字段(key) 的哈希值 % 分区个数(并行度)   

思考:

        1、哪些 数据类型 不能作为分区的key?

                  数组类型不能作为key     

                  当key的类型为bean类型时,bean类必须要重写hashCode方法

 代码示例:

package com.baidu.datastream.transform;

import com.baidu.bean.FlinkUser;
import org.apache.flink.api.java.functions.KeySelector;
import org.apache.flink.streaming.api.datastream.KeyedStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;

public class KeyBy {
    public static void main(String[] args) throws Exception {
        // 1.获取执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(3);

        // 2.使用 KeyBy 算子

        // 方式1:使用 Lambda表达式
        // TODO key的类型为 String
        KeyedStream<String, String> stringKeyedStream = env.fromElements("蜀_刘备", "蜀_关羽", "魏_曹操", "吴_孙权", "吴_孙坚", "吴_孙策").keyBy(value -> value.split("_")[0]);
        stringKeyedStream.print();

        // TODO key的类型为 bean (需重写hashCode方法)
        KeyedStream<FlinkUser, FlinkUser> userKeyedStream = env.fromElements(new FlinkUser(1L, "x", 100L), new FlinkUser(2L, "x", 110L), new FlinkUser(3L, "y", 120L), new FlinkUser(4L, "y", 130L), new FlinkUser(5L, "z", 140L)).keyBy(user -> user);

        // TODO key的类型为 数组(不支持)
//        KeyedStream<String, String[]> arrayKeyedStream = env.fromElements("蜀_刘备", "蜀_关羽", "魏_曹操", "吴_孙权", "吴_孙坚", "吴_孙策")
//                .keyBy(value -> value.split("_"));

        // 方式2:使用 KeySelector实现类
        /*
         * TODO KeySelector<IN, KEY>
         *   功能说明:
         *       从输入的数据中提取key,然后根据 `key的hashcode%并行度` 进行分区
         *       注意:这里的分区是逻辑分区
         *   泛型说明:
         *       @IN  : 输入数据类型
         *       @KEY : key的数据类型
         *   重要提示:
         *       什么类型的数据不能作为key呢?
         *          1.当 POJO 类且没有重写 hashCode() 方法而是依赖依赖于 Object.hashCode() 实现时
         *          2.任意类型的数组
         * */
        KeySelector<FlinkUser, String> keySelector = new KeySelector<FlinkUser, String>() {

            @Override
            public String getKey(FlinkUser value) throws Exception {
                return value.name;
            }
        };
        KeyedStream<FlinkUser, String> userNameKeyedStream = env.fromElements(new FlinkUser(1L, "x", 100L), new FlinkUser(2L, "x", 110L), new FlinkUser(3L, "y", 120L), new FlinkUser(4L, "y", 130L), new FlinkUser(5L, "z", 140L)).keyBy(keySelector);

        // max("字段名称") pojo类一定要含有空参构造
        //userNameKeyedStream.sum("id").print();

        // 3.触发程序执行
        env.execute();
    }
}

执行结果:


4.2 Reduce

功能说明:

KeyedStream[T,K] → DataStream[T]
在相同key的数据流上`滚动`执行聚合操作。将当前元素与上次一次聚合后得到的值(保存的状态值)组合然后输出新值,并将这个值作为状态进行保存。

Reduce函数的弊端:
        聚合前数据类型 = 聚合后数据类型,不能修改数据类型
        不能提供初始值进行聚合操作,当只有一个元素时,不会触发reduce函数

代码示例:

package com.baidu.datastream.transform;

import org.apache.flink.api.common.RuntimeExecutionMode;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.common.functions.ReduceFunction;
import org.apache.flink.api.java.functions.KeySelector;
import org.apache.flink.api.java.tuple.Tuple;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;

public class Reduce {
    public static void main(String[] args) throws Exception {
        // 1.获取执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(4);


        // 2.使用 Reduce 算子
        /*
        * TODO ReduceFunction<T>
        *   功能说明:
        *       对相同key中的元素进行聚合操作(依次聚合)
        *   泛型说明:
        *       输入数据和输出数据的类型
        *   重要说明:
        *       这种聚合方式不能修改value的数据类型
        *
        * */
        ReduceFunction<Tuple2<String, Integer>> reduceFunction = new ReduceFunction<Tuple2<String, Integer>>() {

            @Override
            public Tuple2<String, Integer> reduce(Tuple2<String, Integer> value1, Tuple2<String, Integer> value2) throws Exception {
                return new Tuple2(value1.f0, value1.f1 + value2.f1);
            }
        };

        // 统计每个国家出现的次数
        env.fromElements("蜀_刘备", "蜀_关羽", "魏_曹操", "吴_孙权", "吴_孙坚", "吴_孙策")
                .map(
                        new MapFunction<String, Tuple2<String, Integer>>() {
                            @Override
                            public Tuple2<String, Integer> map(String value) throws Exception {
                                return new Tuple2(value.split("_")[0], 1);
                            }
                        }
                )
                .keyBy(
                        new KeySelector<Tuple2<String, Integer>, String>() {
                            @Override
                            public String getKey(Tuple2<String, Integer> value) throws Exception {
                                return value.f0;
                            }
                        }

                )
                .reduce(reduceFunction)
                .print()
        ;


        // 3.触发程序执行
        env.execute();
    }
}

运行结果:


 4.3 sum、min、max、minBy、maxBy

功能说明:

KeyedStream[T,K] → DataStream[T]
在相同key的数据流上`滚动`执行相应聚合操作。

min、minBy的区别:
             min:聚合状态中保存的是第一个元素的非聚合字段
         minBy:聚合状态中保存的是当前元素的非聚合字段

代码示例:

package com.baidu.datastream.transform;

import com.baidu.bean.FlinkUser;
import org.apache.flink.streaming.api.datastream.KeyedStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;

public class SumMinMaxMinByMaxBy {
    public static void main(String[] args) throws Exception {
        // 1.获取执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(1);

        KeyedStream<FlinkUser, String> userKeyedStream = env.fromElements(
                new FlinkUser(1L, "x", 100L),
                new FlinkUser(2L, "x", 110L),
                new FlinkUser(3L, "x", 120L),
                new FlinkUser(4L, "x", 130L),
                new FlinkUser(5L, "y", 140L)
        ).keyBy(user -> user.name);

        /*
         * TODO max("")、max(num)
         *   功能说明:
         *      根据指定的字段,做聚合操作
         *   怎样指定聚合字段:
         *      当 value类型为 pojo时,通过 max("字段名称") 来指定字段
         *      当 value类型为 tuple时,通过 max(num) 来指定字段
         *   重点说明:
         *      当 value类型为pojo时,必须实现空参构造方法,才能提取字段
         * */
        //userKeyedStream.max("id").print();
        //userKeyedStream.min("id").print();
        //userKeyedStream.sum("id").print();
        //userKeyedStream.maxBy("id").print();
        userKeyedStream.minBy("id").print();


        env.execute();


    }
}

5、物理分区算子

Flink提供了将数据重新分区的方法,当任务发生数据倾斜时,这个算子会很有用。

5.1 shuffle - 随机分区

功能说明:

        DataStream[T] → DataStream[T]
        将元素随机地均匀分配到下游分区

Tips:
        因为是完全随机,当输入相同时,每次执行的结果可能会不同

代码示例:

package com.baidu.datastream.transform;

import com.baidu.bean.FlinkUser;
import org.apache.flink.streaming.api.datastream.KeyedStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;

public class Shuffle {
    public static void main(String[] args) throws Exception {
        // 1.获取执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(3);

        KeyedStream<FlinkUser, String> userKeyedStream = env.fromElements(
                new FlinkUser(1L, "x", 100L),
                new FlinkUser(2L, "x", 110L),
                new FlinkUser(3L, "x", 120L),
                new FlinkUser(4L, "x", 130L),
                new FlinkUser(5L, "x", 140L),
                new FlinkUser(6L, "x", 150L)).keyBy(user -> user.name);

        /*
         * TODO 问题:由于 keyBy 算子,导致数据倾斜(key相同,导致数据都被同一个并行子任务处理)
         *    我们可以使用 shuffle 算子将数据均匀的在分配到其他并行子任务中去
         * 重点提示:
         *    shuffle 算子只能操作 DataStream,不能操作 KeyedStream
         * */
        userKeyedStream.sum("id").shuffle().print();

        env.execute();

    }
}

运行结果:

 5.2 rebalance - 轮询分区

功能说明:

        DataStream[T] → DataStream[T]
        使用Round-Robin负载均衡算法,将输入的数据平均的分配到下游分区中去。   

 代码示例:

package com.baidu.datastream.transform;

import com.baidu.bean.FlinkUser;
import org.apache.flink.streaming.api.datastream.KeyedStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;

public class Rebalance {
    public static void main(String[] args) throws Exception {
        // 1.获取执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(3);

        KeyedStream<FlinkUser, String> userKeyedStream = env.fromElements(
                new FlinkUser(1L, "x", 100L),
                new FlinkUser(2L, "x", 110L),
                new FlinkUser(3L, "x", 120L),
                new FlinkUser(4L, "x", 130L),
                new FlinkUser(5L, "x", 140L),
                new FlinkUser(6L, "x", 150L)).keyBy(user -> user.name);

        /*
         * TODO 问题:由于 keyBy 算子,导致数据倾斜(key相同,导致数据都被同一个并行子任务处理)
         *    我们可以使用 rebalance 算子将数据均匀的在分配到其他并行子任务中去
         * 重点提示:
         *    rebalance 算子只能操作 DataStream,不能操作 KeyedStream
         * */
        userKeyedStream.sum("id").rebalance().print();

        env.execute();
    }
}

运行结果:

5.3 rescale - 重缩分区

功能说明:

        DataStream[T] → DataStream[T]
        使用Round-Robin负载均衡算法,将以分区为单位将输入的数据平均的分配到下游分区中去。

和rebalance的区别:

          rebalance将输入数据作为一个整体,根据数据输入的顺序随机分发到下游分区(涉及到了网络传输)
          rescale将以上游分区为单位,随机的分配到下游分区中去

使用场景:    

         当source算子为可并发数据源时(如kafka,5个分区),设置5个Task来读取分别读取每个分区的数据
    此时,可以使用rescale来分发到下游实现负载均衡,这样可以做到数据只在本地传输而不是网络传输

5.4 global - 全局分区

功能说明:

        DataStream[T] → DataStream[T]
        将元素分发到下游的一个分区中去 

5.5 broadcast - 广播分区

 功能说明:

        DataStream[T] → DataStream[T]
        将元素广播到下游的每个分区 

Tips:
        数据被广播后,会在下游算子的每个分区中都保留一份,可以将数据进行重复处理

代码示例:

package com.baidu.datastream.transform;

import com.baidu.bean.FlinkUser;
import org.apache.flink.streaming.api.datastream.KeyedStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;

public class Broadcast {
    public static void main(String[] args) throws Exception {
        // 1.获取执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(3);

        KeyedStream<FlinkUser, String> userKeyedStream = env.fromElements(
                new FlinkUser(1L, "x", 100L),
                new FlinkUser(2L, "x", 110L),
                new FlinkUser(3L, "x", 120L),
                new FlinkUser(4L, "x", 130L),
                new FlinkUser(5L, "x", 140L),
                new FlinkUser(6L, "x", 150L)).keyBy(user -> user.name);

        userKeyedStream.sum("id").broadcast().print();

        env.execute();
    }
}

运行结果:

 5.6  自定义分区

功能说明:

        DataStream[T] → DataStream[T]
        使用用户定义的 Partitioner 将元素分发到下游算子的分区中去

代码示例:

package com.baidu.datastream.transform;

import com.baidu.bean.FlinkUser;
import org.apache.flink.api.common.functions.Partitioner;
import org.apache.flink.api.java.functions.KeySelector;
import org.apache.flink.streaming.api.datastream.KeyedStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;

public class PartitionCustom {
    public static void main(String[] args) throws Exception {
        // 1.获取执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(3);

        KeyedStream<FlinkUser, String> userKeyedStream = env.fromElements(
                new FlinkUser(1L, "x", 100L),
                new FlinkUser(2L, "x", 110L),
                new FlinkUser(3L, "x", 120L),
                new FlinkUser(4L, "x", 130L),
                new FlinkUser(5L, "x", 140L),
                new FlinkUser(6L, "x", 150L)).keyBy(user -> user.name);

        /*
         *  TODO Partitioner<K>
         *   功能说明:
         *       自定义分区器,根据输入的数据获取分区编号
         *   泛型说明:
         *       @K : key的数据类型
         * */
        Partitioner<Long> partitioner = new Partitioner<Long>() {
            @Override
            public int partition(Long key, int numPartitions) {
                if (key == 1L || key == 2L) {
                    return 0;
                } else if (key == 3L || key == 4L) {
                    return 1;
                } else {
                    return 2;
                }
            }
        };

        /*
         * TODO KeySelector<IN, KEY>
         *  功能说明:
         *       key提取器,根据输入的数据,获取key
         *  泛型说明:
         *       @IN  : 输入数据类型
         *       @KEY : 输出数据类型(key)
         * */
        KeySelector<FlinkUser, Long> keySelector = new KeySelector<FlinkUser, Long>() {
            @Override
            public Long getKey(FlinkUser value) throws Exception {
                return value.id;
            }
        };

        userKeyedStream.sum("id").partitionCustom(partitioner, keySelector).print();

        env.execute();
    }
}

运行结果:


6、分流

        在处理数据的时候,经常会将一条流或者一个表根据某些条件拆分成多条流或者多个表

flink中提供了分流的方式:1、使用filter算子分流   2、使用侧输出流分流

 6.1 使用filter算子分流 - 不推荐

这种分流方式的弊端:

        需要将原始流复制多份,并对每一份做一次判断,效率很低 (多次读取,多次判断)

代码示例:

    // 通过 filter 分流
    public static void ByFilter() throws Exception {
        // 1.获取执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        // 根据国家,将 totalStream 分为三股流
        DataStreamSource<String> totalStream = env.fromElements("蜀_刘备", "蜀_关羽", "魏_曹操", "吴_孙权", "吴_孙坚", "吴_孙策");

        SingleOutputStreamOperator<String> weiStream = totalStream.filter(e -> e.contains("魏"));
        SingleOutputStreamOperator<String> shuStream = totalStream.filter(e -> e.contains("蜀"));
        SingleOutputStreamOperator<String> wuStream = totalStream.filter(e -> e.contains("吴"));

        weiStream.print();
        shuStream.print();
        wuStream.print();

        // 3.触发程序执行
        env.execute();
    }

6.2 使用侧输出流分流 - 推荐

        避免了使用filter算子的弊端,指定source读取一次,判断一次即可完成分流操作

代码示例:

    // 通过 侧输入流 分流
    public static void ByOutputTag() throws Exception {
        // 1.获取执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        // 根据国家,将 totalStream 分为三股流
        DataStreamSource<String> totalStream = env.fromElements("蜀_刘备", "蜀_关羽", "魏_曹操", "吴_孙权", "吴_孙坚", "吴_孙策");

        // 初始化侧输出流
        OutputTag weiOutputTag = new OutputTag("wei", Types.STRING);
        OutputTag shuOutputTag = new OutputTag("shu", Types.STRING);
        OutputTag wuOutputTag = new OutputTag("wu", Types.STRING);

        // 通过 ProcessFunction向 侧输出流发送数据
        SingleOutputStreamOperator<String> process = totalStream.process(
                new ProcessFunction<String, String>() {
                    @Override
                    public void processElement(String value, ProcessFunction<String, String>.Context ctx, Collector<String> out) throws Exception {
                        // 往侧输出流中发送数据
                        if (value.contains("魏")) {
                            ctx.output(weiOutputTag, value);
                        } else if (value.contains("蜀")) {
                            ctx.output(shuOutputTag, value);
                        } else if (value.contains("吴")) {
                            ctx.output(wuOutputTag, value);
                        }

                    }
                }
        );

        SideOutputDataStream weiStream = process.getSideOutput(weiOutputTag);
        SideOutputDataStream shuStream = process.getSideOutput(shuOutputTag);
        SideOutputDataStream wuStream = process.getSideOutput(wuOutputTag);

        weiStream.print();
        shuStream.print();
        wuStream.print();

        // 3.触发程序执行
        env.execute();
    }

7、合并流

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

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

相关文章

尚硅谷大数据项目《在线教育之离线数仓》笔记002

视频地址&#xff1a;尚硅谷大数据项目《在线教育之离线数仓》_哔哩哔哩_bilibili 目录 P025 P026 P027 P028 P029 P030 P031 P032 P033 P034 P035 P036 P037 P038 P025 在Hive所在节点部署Spark P026 3&#xff09;Hive on Spark测试 &#xff08;1&#xff09;…

kali linux查看局域网下所有IP,并对指定IP攻击

kali linux查看局域网下所有IP&#xff0c;并对指定IP实施局域网内攻击 首先我们打开我们熟悉的kali linux操作系统&#xff0c;利用指令&#xff1a; ifconfig来确认本机的ip地址 确认了本机的ip地址之后&#xff0c;利用一下的指令查看局域网下所有ip: fping -g 本机IP地址…

SpringMVC-1-解密Spring MVC:构建优雅、灵活的Web应用的秘诀

今日目标 能够编写SpringMVC入门案例 了解SpringMVC原理 1. SpringMVC介绍 1.1 SpringMVC概述 思考:SpringMVC框架有什么优点&#xff1f; SpringMVC是一种基于Java实现MVC模型的轻量级Web框架 优点 使用简单&#xff0c;开发便捷&#xff08;相比于Servlet&#xff09; 天…

Java进阶篇--迭代器模式

目录 同步迭代器&#xff08;Synchronous Iterator&#xff09;&#xff1a; Iterator 接口 常用方法&#xff1a; 注意&#xff1a; 扩展小知识: 异步迭代器&#xff08;Asynchronous Iterator&#xff09;&#xff1a; 常用的方法 注意&#xff1a; 总结&#xff1a…

【S32K 进阶之旅】S32K 芯片的解锁

在使用 S32K1xx MCU 的过程中&#xff0c;因为某些不当操作导致芯片被锁、加密的情况偶有发生&#xff0c;在此总结一篇如何解锁芯片的文档&#xff0c;希望能够帮到有需要的人。 1. S32K 芯片被锁的现象及原因分析1&#xff09;在S32K 系列 MCU 开发和生产过程中&#xff…

【Unity细节】Unity中的层级LayerMask

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 &#x1f636;‍&#x1f32b;️收录于专栏&#xff1a;unity细节和bug &#x1f636;‍&#x1f32b;️优质专栏 ⭐【…

元宇宙是什么?有哪些应用方向?一文了解元宇宙虚拟展厅

引言&#xff1a; 在当今数字科技飞速发展的时代&#xff0c;元宇宙作为一个令人向往的概念正逐渐进入大众的视野。那么&#xff0c;什么是元宇宙&#xff1f;元宇宙又有哪些应用方向呢&#xff1f;元宇宙虚拟展厅又有哪些优势呢&#xff1f; 一&#xff0e;元宇宙是什么 元宇…

eNSP 打开警告:请将eNSP相关应用程序添加到windows firewall的允许程序列表,并允许其在公用网络上运行!

文章目录 1 警告截图2 解决办法 1 警告截图 2 解决办法 思路&#xff1a;按照警告的提示信息&#xff0c;将 eNSP 相关应用添加到 windows firewall&#xff08;防火墙&#xff09;的允许程序列表&#xff0c;并允许其在公用网络上运行&#xff01;此处以 Win 10 为例

怎么把人物抠到一个视频里?这个视频抠像方法一看就会

在视频中&#xff0c;人物抠像可以用于创建有趣的视觉效果&#xff0c;例如将人物放置在不同的场景中&#xff0c;或者创建动画效果。此外&#xff0c;它还可以用于制作特效&#xff0c;例如将人物的外观更改为其他形象&#xff0c;或者在人物移动时添加轨迹效果。那么怎么把人…

Eclipse常见的使用技巧(快捷键)大全

常用设置&#xff0c;非常建议 1.代码提示设置 2.快捷键设置 代码编写技巧 注意&#xff1a; 如果你设置了代码提示&#xff0c;那么下面操作快捷方式回车即可生成&#xff0c;不必alt/ 换行 ShiftEnter回车&#xff0c;不管光标在哪里都会换行&#xff01;非常好用&…

向日葵如何截图

场景 向日葵远程时&#xff0c;有时需要截图&#xff0c;但是客户电脑上没有qq、微信等软件提供快捷截图。 怎么办呢? 解决方案 其实向日葵肯定支持这些功能的。 设置 | 热键设置 | 勾选 远控其他设备时&#xff0c;可输入热键进行以下操作。 如果&#xff1a; altq 切换…

性能测试-并发用户数估算(超细整理)

前言 并发用户数&#xff1a;是指现实系统中操作业务的用户&#xff0c;在性能测试工具中&#xff0c;一般称为虚拟用户数(Virutal User)。 并发用户数和注册用户数、在线用户数的概念不同。 并发用户数一定会对服务器产生压力的&#xff1b; 而在线用户数只是 ”挂” 在系统…

一万字关于java数据结构堆的讲解,让你从入门到精通

目录 java类和接口总览 队列(Queue) 1. 概念 2. 队列的使用 以下是一些常用的队列操作&#xff1a; 1.入队操作 2.出队操作 3.判断队列是否为空 4.获取队列大小 5.其它 优先级队列(堆) 1. 优先级队列概念 Java中的PriorityQueue具有以下特点 2.常用的PriorityQue…

Doris的执行计划生成、分发与执行

目录 一、执行计划的生成 二、执行计划的分发 三、执行计划的执行 一、执行计划的生成 在Doris的FE端&#xff0c;与大多数数据库系统一样&#xff0c;要从SQL或某种http请求&#xff0c;生成执行计划&#xff0c;从SQL生成&#xff0c;一开始是“抽象语法树”&#xff08;…

FreeRTOS 从入门到精通-任务调度

初写FreeRTOS 从入门到精通系列文章之初&#xff0c;笔者只是当作可以随时回顾的学习笔记来写&#xff0c;并没有想到这些偏技术的文章收获了意料之外的阅读量和关注。首先当然很欣喜自己的文章能够得到了读者们的认可&#xff0c;但同时也有种使命感&#xff0c;既期望启迪并与…

模型评估的常用指标

模型评估的指标 模型是在大量的数据集上训练而来的,无论一个模型是从零训练的还是基于某一个模型,通过微调方法得到的,靠人工评价模型的效果都是异常困难的。那么要想客观的、自动化的评价一个LLM模型,就需要能够选择正确评估模型效果的指标或者基准测试,来客观和自动化的…

C语言刷题指南(二)

&#x1f4d9;作者简介&#xff1a; 清水加冰&#xff0c;目前大二在读&#xff0c;正在学习C/C、Python、操作系统、数据库等。 &#x1f4d8;相关专栏&#xff1a;C语言初阶、C语言进阶、C语言刷题训练营、数据结构刷题训练营、有感兴趣的可以看一看。 欢迎点赞 &#x1f44d…

腾讯开启2024校招,主要招聘5大类岗位

近日&#xff0c;腾讯的大动作一个接一个&#xff0c;前脚刚公布2023上半年财报&#xff0c;后脚就开启了2024校招&#xff0c;不得不让人感叹腾讯真速度&#xff01; 此次招聘对象为毕业时间在2023年9月至2024年8月期间的2024届应届毕业生&#xff0c;覆盖北上广深等多个城市…

Python中定时任务APScheduler库用法详解

在日常工作中&#xff0c;常常会用到需要周期性执行的任务&#xff0c;一种方式是采用 Linux 系统自带的 crond 结合命令行实现。另外一种方式是直接使用Python。 当每隔一段时间就要执行一段程序&#xff0c;或者往复循环执行某一个任务&#xff0c;这就需要使用定时任务来执…

如何搭建游戏服务器?有哪些操作步骤

​  选择游戏服务器提供商 为确保游戏服务器的稳定运行和及时响应问题&#xff0c;选择一个正规、靠谱的游戏服务器提供商非常重要。 选择服务器操作系统 根据不同游戏的需求&#xff0c;选择适合的操作系统&#xff0c;通常可选择Linux或WindowsServer操作系统。 上传、安装…