解密Flink的状态管理:探索流处理框架的数据保留之道,释放流处理的无限潜能!

水善利万物而不争,处众人之所恶,故几于道💦

文章目录

    • 一、什么是状态
    • 二、应用场景
    • 三、Flink中状态的分类
    • 四、算子状态
      • 1. 列表状态(List State)
      • 2. 广播状态(Broadcast State)
    • 五、键控状态
      • 1. ValueState
      • 2. ListState
      • 3. ReducingState
      • 4. AggregatingState<IN, OUT>
        • 1)类实现累加器 - 示例代码
        • 2)元组实现累加器 - 示例代码
      • 5. MapState<UK, UV>

一、什么是状态

  在流式计算中,有些计算的中间结果需要进行保存,为下一个计算提供参考,比如,有一个数据流,我需要实时的计算这个流中的总消费金额,那么就需要一个变量来存储截止目前的总消费金额,当下一条数据来的时候我就直接在以前总消费金额的基础上,加上这条数据的消费金额就可以了。那么这个例子中的那个存储总消费金额的变量(或者说是累加变量)就叫状态。

二、应用场景

  在流式处理中,状态的应用场景非常广泛。

去重

  如果我们需要对数据流中的数据进行去重统计时,我们可以利用状态管理。通过状态来记录数据是否流过应用,当新数据流入时,根据状态来判断去重。

检测

  检测输入流中的数据是否符合某个特定的模式。这里的模式不是指数据的格式,而是指数据之间的关系是否符合某个需求模型。比如,根据一个网站访问记录流中的数据,判断用户是否连续登录,然后给予相应的奖励。

聚合

  对某个特定时间内的数据进行聚合统计分析。比如统计每小时的 PV 量。

三、Flink中状态的分类

  Flink中包括两种基本的状态Managed StateRaw State,分别是管理状态和原始状态

在这里插入图片描述

  原始状态基本用不到,因为官方提供的管理状态已经够我们使用了


  管理状态又分为两类,分别是算子状态(Operator State)和键控状态(Keyed State)

  1. 算子状态可用于所有的算子,但是常用于source算子和sink算子;他是一个算子的子任务对应一个状态,也就是一个并行度里面一个状态;它通过实现CheckpointedFunction接口创建;它支持的数据结构有ListState,UnionListStste 和 BroadCastState。

  2. 键控状态只能用于KeyedStream上的算子;这个是一个key对应一个状态,他只和key有关;创建的时候重写RichFunction,通过里面的getRuntimeContext().get…State()获取状态对象;键控状态支持的数据结构有 ValueState,ListState,MapState,ReduceState,AggregatingState

在这里插入图片描述

四、算子状态

1. 列表状态(List State)

  将状态表示为一组数据的列表。向状态中添加元素add()、更新状态中的所有元素update(),取出状态中的所有元素get(),它会返回一个迭代器。


例:将输入的单词存入到状态中,当程序重启的时候,可以把状态中存的单词恢复。

示例代码:

public class Flink01_State_Operator_List {public static void main(String[] args) {Configuration conf = new Configuration();conf.setInteger("rest.port",1000);StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(conf);env.setParallelism(2);// 启用checkpoint 周期是2000毫秒,也就是2秒,每隔2s将状态保存一下env.enableCheckpointing(2000);env.socketTextStream("hadoop101",9999).map(new MyMapFunction()).print();try {env.execute();} catch (Exception e) {e.printStackTrace();}}// 算子状态,不能用内部类了,因为要实现两个接口,算子状态要实现CheckpointedFunction接口private static class MyMapFunction implements MapFunction<String,String>, CheckpointedFunction {List<String> words = new ArrayList();private ListState<String> wordsState;@Overridepublic String map(String line) throws Exception {//抛个异常他就会自动重启,输入x就让他抛异常if (line.contains("x")) {throw new RuntimeException("手动抛出异常...");  }String[] data = line.split(" ");words.addAll(Arrays.asList(data));return words.toString();}// 保存状态:周期性的执行// 每个并行度都会周期性的执行@Overridepublic void snapshotState(FunctionSnapshotContext context) throws Exception {// 这个方法是把数据存入到算子状态(状态列表)
//            System.out.println("MyMapFunction.snapshotState");//            wordsState.clear();       清空状态
//            wordsState.addAll(words);   向状态中写数据// 上面两个方法能用下面这一个方法代替wordsState.update(words);}// 程序启动的时候每个并行度执行一次// 这个方法可以把状态中的数据恢复到Java的集合中@Overridepublic void initializeState(FunctionInitializationContext context) throws Exception {// 从状态中恢复数据//System.out.println("MyMapFunction.initializeState");System.out.println("程序重启,从状态中恢复数据...");// 获取列表状态wordsState = context.getOperatorStateStore().getListState(new ListStateDescriptor<String>("wordsState", String.class));// 从列表中获取数据// 将状态中的数据遍历出来,在添加到集合中,也就是恢复数据
//            Iterable<String> it = wordsState.get();for (String word : wordsState.get()) {words.add(word);}}}
}

输入数据:
在这里插入图片描述

运行结果:
在这里插入图片描述

2. 广播状态(Broadcast State)

  广播状态一般是两个流用,一个数据流,一个广播流,用广播流中的数据控制数据流中数据的处理逻辑。向状态里面写数据用put(),从状态里面拿数据用get()


例:通过广播流输入1,2,3…控制数据流中的数据使用不同的处理逻辑

示例代码:

public class Flink03_State_Operator_BroadCast {public static void main(String[] args) {Configuration conf = new Configuration();conf.setInteger("rest.port",1000);StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(conf);env.setParallelism(2);//获取一个数据流DataStreamSource<String> dataStream = env.socketTextStream("hadoop101", 8888);// 获取一个配置流DataStreamSource<String> configStream = env.socketTextStream("hadoop101", 9999);// 1. 把配置流做成一个广播流   需要一个map状态描述器   一个key的类型,一个valueMapStateDescriptor<String, String> bcStateDesc = new MapStateDescriptor<>("bcState", String.class, String.class);BroadcastStream<String> bcStream = configStream.broadcast(bcStateDesc);// 2. 让数据流去connect广播流BroadcastConnectedStream<String, String> coStream = dataStream.connect(bcStream);// 泛型分别表示,数据流类型,广播流类型,输出类型coStream.process(new BroadcastProcessFunction<String, String, String>() {// 4. 处理数据流中的数据:从广播状态中取配置@Overridepublic void processElement(String value,ReadOnlyContext ctx,Collector<String> out) throws Exception {System.out.println("Flink03_State_Operator_BroadCast.processElement");ReadOnlyBroadcastState<String, String> broadcastState = ctx.getBroadcastState(bcStateDesc);String conf = broadcastState.get("aSwitch");if("1".equals(conf)){out.collect(value +" 使用 1 号逻辑...");}else if ("2".equals(conf)){out.collect(value +" 使用 2 号逻辑...");}else if ("3".equals(conf)){out.collect(value +" 使用 3 号逻辑...");}else {out.collect(value +" 使用 default 号逻辑...");}}// 3. 把广播流中的数据放入到广播状态@Overridepublic void processBroadcastElement(String value, // 广播流中的数据Context ctx,  // 上下文Collector<String> out) throws Exception {System.out.println("Flink03_State_Operator_BroadCast.processBroadcastElement");// 获取广播状态,把配置信息写入到状态中BroadcastState<String, String> broadcastState = ctx.getBroadcastState(bcStateDesc);broadcastState.put("aSwitch",value);}}).print();try {env.execute();} catch (Exception e) {e.printStackTrace();}}
}

输入数据:

在这里插入图片描述

运行结果:

在这里插入图片描述

五、键控状态

1. ValueState

  保存单个值. 每个key有一个状态值. 向状态中保存数据使用 update(T)方法, 获取状态中的数据使用value()方法。


例:检测传感器的水位值,如果连续的两个水位值超过10,就输出报警。

示例代码:

public class Flink04_State_Key_Value {public static void main(String[] args) {Configuration conf = new Configuration();conf.setInteger("rest.port",1000);StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(conf);env.setParallelism(2);env.socketTextStream("hadoop101", 9999) // socket只能是1.map(line -> {String[] data = line.split(",");return new WaterSensor(data[0],Long.valueOf(data[1]),Integer.valueOf(data[2]));}).keyBy(WaterSensor::getId)// 键控状态必须在keyBy后使用.process(new KeyedProcessFunction<String, WaterSensor, String>() {// 状态private ValueState<Integer> lastVcState;// 每个并行度执行一次   初始化的时候执行一次@Overridepublic void open(Configuration parameters) throws Exception {
//                        System.out.println("Flink04_State_Key_Value.open");// 因为他已经把状态封装在运行时上下文了,所以直接获取就行了lastVcState = getRuntimeContext().getState(new ValueStateDescriptor<Integer>("lastVcState", Integer.class));}@Overridepublic void processElement(WaterSensor value,Context ctx,Collector<String> out) throws Exception {// 获取状态里面的值  通过 .value() 方法Integer lastVc = lastVcState.value();System.out.println(lastVc+ "" +"  " + value.getVc());if (lastVc != null) {if (value.getVc() >10 && lastVc > 10) {out.collect(ctx.getCurrentKey()+" 连续两次超过10,发出红色预警...");}}// 更新状态的值   只能保存一个值,所以用update更新lastVcState.update(value.getVc());}}).print();try {env.execute();} catch (Exception e) {e.printStackTrace();}}
}

输入数据:

在这里插入图片描述

运行结果:

在这里插入图片描述

2. ListState

  保存元素列表。添加一个元素用add(T),添加多个元素用addAll(List<T>),获取元素用get()他会返回一个迭代器,可遍历出每个元素,覆盖所有元素用update(List<T>)


例:针对每个传感器输出最高的3个水位值

示例代码:

public class Flink05_State_Key_List {public static void main(String[] args) {Configuration conf = new Configuration();conf.setInteger("rest.port",1000);StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(conf);env.setParallelism(2);env.socketTextStream("hadoop101", 9999) // socket只能是1.map(line -> {String[] data = line.split(",");return new WaterSensor(data[0],Long.valueOf(data[1]),Integer.valueOf(data[2]));}).keyBy(WaterSensor::getId)// 键控状态必须在keyBy后使用.process(new KeyedProcessFunction<String, WaterSensor, String>() {private ListState<Integer> top3VcState;@Overridepublic void open(Configuration parameters) throws Exception {top3VcState = getRuntimeContext().getListState(new ListStateDescriptor<Integer>("top3VcState", Integer.class));}@Overridepublic void processElement(WaterSensor value,Context ctx,Collector<String> out) throws Exception {// 因为用的是list状态,可以存多个值,所以每来一个数据要先存进状态top3VcState.add(value.getVc());// 获取状态里面的元素Iterable<Integer> iterable = top3VcState.get();List<Integer> list = AnqclnUtil.toList(iterable);list.sort(new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o2.compareTo(o1);}});// 因为要取的是前三,所以第四个元素进来的时候就不要了if (list.size() ==4){list.remove(list.size()-1);}top3VcState.update(list);out.collect(ctx.getCurrentKey()+" 最高的三个水位值:"+list);}}).print();try {env.execute();} catch (Exception e) {e.printStackTrace();}}
}

输入数据:
在这里插入图片描述

运行结果:
在这里插入图片描述

3. ReducingState

  存储单个值,表示把所有元素的聚合结果添加到状态中,当向状态中添加元素的时候,他会使用指定的ReduceFunction进行聚合。添加元素是add(T),取出元素是get()


例:计算每个传感器的水位和

示例代码:

public class Flink06_State_Key_Reduce {public static void main(String[] args) {Configuration conf = new Configuration();conf.setInteger("rest.port", 1000);StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(conf);env.setParallelism(2);env.socketTextStream("hadoop101", 9999) // socket只能是1.map(line -> {String[] data = line.split(",");return new WaterSensor(data[0],Long.valueOf(data[1]),Integer.valueOf(data[2]));}).keyBy(WaterSensor::getId)// 键控状态必须在keyBy后使用.process(new KeyedProcessFunction<String, WaterSensor, String>() {private ReducingState<WaterSensor> vcSumState;@Overridepublic void open(Configuration parameters) throws Exception {vcSumState = getRuntimeContext().getReducingState(new ReducingStateDescriptor<WaterSensor>("vcSumState",new ReduceFunction<WaterSensor>() {@Overridepublic WaterSensor reduce(WaterSensor value1,WaterSensor value2) throws Exception {value1.setVc(value1.getVc() + value2.getVc());return value1;}},WaterSensor.class));}@Overridepublic void processElement(WaterSensor value,Context ctx,Collector<String> out) throws Exception {// 将传过来的每个元素加入到状态里面去,然后就行了,他会自己聚合,因为在上面创建状态的时候就已经写了聚合的逻辑vcSumState.add(value);out.collect(ctx.getCurrentKey()+" 的水位和为:"+vcSumState.get().getVc());}}).print();try {env.execute();} catch (Exception e) {e.printStackTrace();}}
}

输入数据:

在这里插入图片描述
运行结果:

在这里插入图片描述

4. AggregatingState<IN, OUT>

  存储单个值。 与ReducingState类似, 都是进行聚合。 不同的是,AggregatingState的聚合的结果和输入的元素类型可以不一样。存数据用add(),取数据用get()


例:计算每个传感器的平均水位

1)类实现累加器 - 示例代码

public class Flink07_State_Key_Aggregate {public static void main(String[] args) {Configuration conf = new Configuration();conf.setInteger("rest.port", 1000);StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(conf);env.setParallelism(2);env.socketTextStream("hadoop101", 9999) // socket只能是1.map(line -> {String[] data = line.split(",");return new WaterSensor(data[0],Long.valueOf(data[1]),Integer.valueOf(data[2]));}).keyBy(WaterSensor::getId)// 键控状态必须在keyBy后使用.process(new KeyedProcessFunction<String, WaterSensor, String>() {private AggregatingState<WaterSensor, Double> avgVcState;@Overridepublic void open(Configuration parameters) throws Exception {avgVcState = getRuntimeContext().getAggregatingState(new AggregatingStateDescriptor<WaterSensor, Avg, Double>("avgVcState",new AggregateFunction<WaterSensor, Avg, Double>() {@Overridepublic Avg createAccumulator() {return new Avg();}@Overridepublic Avg add(WaterSensor value, Avg acc) {acc.sum += value.getVc();acc.count++;return acc;}@Overridepublic Double getResult(Avg acc) {return acc.avg();}@Overridepublic Avg merge(Avg a, Avg b) {return null;}},Avg.class));}@Overridepublic void processElement(WaterSensor value,Context ctx,Collector<String> out) throws Exception {avgVcState.add(value);out.collect(ctx.getCurrentKey()+" 的平均水位:"+avgVcState.get());}}).print();try {env.execute();} catch (Exception e) {e.printStackTrace();}}private static class Avg {public Integer sum = 0;public Long count = 0L;public Double avg(){return sum *1.0 / count;}}
}

输入数据:

在这里插入图片描述

运行结果:

在这里插入图片描述

2)元组实现累加器 - 示例代码

public class Flink08_State_Key_Aggregate_Tuple2 {public static void main(String[] args) {Configuration conf = new Configuration();conf.setInteger("rest.port", 1000);StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(conf);env.setParallelism(2);env.socketTextStream("hadoop101", 9999) // socket只能是1.map(line -> {String[] data = line.split(",");return new WaterSensor(data[0],Long.valueOf(data[1]),Integer.valueOf(data[2]));}).keyBy(WaterSensor::getId)// 键控状态必须在keyBy后使用.process(new KeyedProcessFunction<String, WaterSensor, String>() {private AggregatingState<WaterSensor, Double> avgVcState;@Overridepublic void open(Configuration parameters) throws Exception {avgVcState = getRuntimeContext().getAggregatingState(new AggregatingStateDescriptor<WaterSensor, Tuple2<Integer, Long>, Double>("avgVcState",new AggregateFunction<WaterSensor, Tuple2<Integer, Long>, Double>() {@Overridepublic Tuple2<Integer, Long> createAccumulator() {return new Tuple2<Integer, Long>(0,0L);}@Overridepublic Tuple2<Integer, Long> add(WaterSensor value, Tuple2<Integer, Long> acc) {acc.f0 += value.getVc();acc.f1++;return acc;}@Overridepublic Double getResult(Tuple2<Integer, Long> acc) {return acc.f0 * 1.0 / acc.f1;}@Overridepublic Tuple2<Integer, Long> merge(Tuple2<Integer, Long> a, Tuple2<Integer, Long> b) {return null;}},
//                                TypeInformation.of(new TypeHint<Tuple2<Integer, Long>>() {})// 类型还可以这样声明,简单Types.TUPLE(Types.INT,Types.LONG)));}@Overridepublic void processElement(WaterSensor value,Context ctx,Collector<String> out) throws Exception {avgVcState.add(value);out.collect(ctx.getCurrentKey()+" 的平均水位:"+avgVcState.get());}}).print();try {env.execute();} catch (Exception e) {e.printStackTrace();}}
}

输入数据:

在这里插入图片描述

运行结果:

在这里插入图片描述

5. MapState<UK, UV>

  存储键值对列表。

  添加键值对: put(UK, UV)putAll(Map<UK, UV>)

  根据key获取值: get(UK)

  获取所有: entries()keys()values()

  检测是否为空: isEmpty()


例:去重: 去掉重复的水位值. 思路: 把水位值作为MapState的key来实现去重, value随意

示例代码:

public class Flink09_State_Key_Map {public static void main(String[] args) {Configuration conf = new Configuration();conf.setInteger("rest.port", 1000);StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(conf);env.setParallelism(2);env.socketTextStream("hadoop101", 9999) // socket只能是1.map(line -> {String[] data = line.split(",");return new WaterSensor(data[0],Long.valueOf(data[1]),Integer.valueOf(data[2]));}).keyBy(WaterSensor::getId)// 键控状态必须在keyBy后使用.process(new KeyedProcessFunction<String, WaterSensor, String>() {private MapState<Integer, Object> vcMapState;@Overridepublic void open(Configuration parameters) throws Exception {vcMapState = getRuntimeContext().getMapState(new MapStateDescriptor<Integer, Object>("vcMapState",TypeInformation.of(new TypeHint<Integer>() {}),TypeInformation.of(new TypeHint<Object>() {})));}@Overridepublic void processElement(WaterSensor value,Context ctx,Collector<String> out) throws Exception {vcMapState.put(value.getVc(),new Object());Iterable<Integer> keys = vcMapState.keys();out.collect(ctx.getCurrentKey() + " 的所有不同水位: " + AnqclnUtil.toList(keys));}}).print();try {env.execute();} catch (Exception e) {e.printStackTrace();}}
}

输入数据:

在这里插入图片描述

运行结果:

在这里插入图片描述

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

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

相关文章

股票指数——RSI指数

RSI指数的计算非常简单&#xff0c;就是使用一段时间内的平均上涨除以平均上涨加平均下跌&#xff08;取正值&#xff09;。也就意味着RSI指数的取值是[0,100]之间&#xff0c;其中0表示周期内没有上涨的&#xff0c;100表示周期内没有下跌的。RSI的直观意义是它表示了一段周期…

用神经网络玩转数据聚类:自编码器的原理与实践

目录 引言一、什么是自编码器二、自编码器的应用场景三、自编码器的优缺点四、如何实现基于自编码器的聚类算法五、总结 引言 随着数据量的爆炸性增长&#xff0c;如何有效地处理和分析数据成为了一个重要的问题。数据聚类是一种常用的数据分析方法&#xff0c;它可以将数据集…

gateway做token校验

本文使用springcloud的gateway做token校验 登录的本质&#xff1a;拿用户名和密码 换 token。 token会返回给浏览器&#xff08;存储&#xff09;&#xff0c;当访问的时候&#xff0c;携带token 发起请求。 token校验图 引入redis依赖 <dependency><groupId>or…

codeforces代:

感受思维的美丽&#xff0c;abcde题目的思路是怎么样的&#xff1a; 上蓝 上紫 可以代 &#xff1a;有问题可以评论区 直接问我 也可以q: 639682754

Django入门

Day1 django环境安装 创建虚拟环境 # step1 创建虚拟环境 python3 -m venv datawhale_django # step2 mac进入虚拟环境 source ./datawhale_django/bin/activate # step3 退出虚拟环境 deactivate安装包 pip3 install django ​pip3 install djangorestframework​​ pip3 …

关于selenium 元素定位的浅度解析

一、By类单一属性定位 元素名称 描述 Webdriver API id id属性 driver.find_element(By.ID, "id属性值") name name属性 driver.find_element(By.NAME, "name属性值") class_name class属性 driver.find_element(By.CLASS_NAME, "class_na…

【Vue-Router】路由入门

路由&#xff08;Routing&#xff09;是指确定网站或应用程序中特定页面的方式。在Web开发中&#xff0c;路由用于根据URL的不同部分来确定应用程序中应该显示哪个内容。 构建前端项目 npm init vuelatest //或者 npm init vitelatest安装依赖和路由 npm install npm instal…

VSCode如何设置高亮

一、概述 本文主要介绍在 VSCode 看代码时&#xff0c;怎样使某个单词高亮显示&#xff0c;主要通过以下三步实现&#xff1a; 安装 highlight-words 插件 配置 highlight-words 插件 设置高亮快捷键F8 工作是嵌入式开发的&#xff0c;代码主要是C/C的&#xff0c;之前一直用…

什么是媒体代发布?媒体代发布注意事项

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体代发布是指将新闻稿或其他宣传内容委托给专业的媒体代理机构或公司进行发布和推广的活动。这些机构通常拥有丰富的媒体资源、人脉和经验&#xff0c;能够更好地将信息传递给目标受众…

数学分析:曲线曲面积分

这一章还是很重要的&#xff0c;可以看到为什么dt1^dt2和dt1dt2是一样的。 可以看到&#xff0c;核心还是黎曼和&#xff0c;我们把两种微分的黎曼和都列出来&#xff0c;并且证明两个相等&#xff0c;即可。 这里要注意&#xff0c;微分形式的积分&#xff0c;在黎曼和的情况…

布置Zabbix监控

一、在 Web 页面中添加 agent 主机 1.1打开Zabbix的Web页面 2.2在 Web 页面中添加 agent 主机 二、在 Web 页面创建自定义监控项模板 2.1创建模版

django实现登录和登录的鉴权

1、创建数据库的管理员表 在models.py 中定义admin表&#xff0c;为了简单&#xff0c;表里只有用户名和密码还有默认加的id 三个字段 from django.db import models# Create your models here.class Admin(models.Model):username models.CharField(verbose_name"用户…

【JavaEE进阶】Spring 更简单的读取和存储对象

文章目录 一. 存储Bean对象1. 配置扫描路径2. 添加注解存储 Bean 对象2.1 使用五大类注解存储Bean2.2 为什么要有五大类注解&#xff1f;2.3 有关获取Bean参数的命名规则 3. 使用方法注解储存 Bean 对象3.1 方法注解储存对象的用法3.2 Bean的重命名3.3 同⼀类型多个 Bean 报错 …

【力扣每日一题】88. 合并两个有序数组 双指针 辅助数组 8.13打卡

文章目录 题目思路代码 题目 88. 合并两个有序数组 难度&#xff1a; 简单 描述&#xff1a; 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&am…

Excel(1):表头或列头冻结

1.需求 对于较大的excel&#xff0c;通常需要固定一部分内容&#xff0c;另一份内容为可翻动。 2.解决方式 在视图中选择冻结窗格&#xff0c;需要注意的是&#xff0c;选择冻结窗格时&#xff0c;窗格的左上方的表格区域是固定不动的&#xff0c;只可以向下或者向右活动。

TCP/IP 下的计算机网络江湖

〇、引言 在当今数字化时代,计算机网络宛如广袤江湖,涵盖着五大门派:物理层、数据链路层、网络层、传输层和应用层。每个门派独具技能,共同构筑着现代网络的框架。物理层宛如江湖基石,将比特流传输;数据链路层如武林传承,组织数据帧传递;网络层则像导航大师,寻找传送路…

EMQX Enterprise 5.1 正式发布:生产环境就绪的 MQTT over QUIC、基于 MQTT 的文件传输支持

近日&#xff0c;企业级 MQTT 物联网接入平台 EMQX Enterprise 5.1 正式发布。该版本为用户提供了更强大、更灵活的物联网解决方案&#xff0c;通过简化功能操作与管理流程&#xff0c;帮助用户快速构建所需的业务。 新版本提供了更大规模且更具伸缩性的全新集群架构&#xff…

Mac M2 Pro安装使用Cocoapods

Mac Pro M2安装使用Cocoapods 在新公司要做iOS开发&#xff0c;所以在新电脑上安装Cocoapods 在升级gem&#xff0c;sudo gem update --system&#xff0c;和安装cocoapods时都遇到如下的提示&#xff1a; ERROR: While executing gem ... (Errno::EPERM)Operation not per…

探讨uniapp的网络通信问题

uni-app 中有很多原生的 API&#xff0c;其中我们经常会用到的肯定有&#xff1a;uni.request(OBJECT) method 有效值 注意&#xff1a;method有效值必须大写&#xff0c;每个平台支持的method有效值不同&#xff0c;详细见下表。 success 返回参数说明 data 数据说明 最终…

赛事 | 第25届中国机器人及人工智能大赛全国决赛榜单发布

第25届中国机器人及人工智能大赛成功举办 2023年6月13日至14日&#xff0c;第二十五届中国机器人及人工智能大赛于海南科技职业大学成功举办。大赛由中国人工智能学会主办&#xff0c;共有来自清华大学、哈尔滨工业大学、中国科学技术大学、西安交通大学等500多所高校进入全国…