Flink四大基石之State(状态) 的使用详解

news2024/12/26 18:39:06

目录

一、有状态计算与无状态计算

(一)概念差异

(二)应用场景

二、有状态计算中的状态分类

(一)托管状态(Managed State)与原生状态(Raw State)

两者的区别

具体区别

管理方式

数据结构支持

使用场景

(二)托管状态细分  Keyed State 和 Operator State

Keyed State(键控状态)

按键分区状态(Keyed State)分类

Operator State(算子状态)

列表状态(ListState)

联合列表状态(UnionListState)

广播状态(BroadcastState)

三、Keyed State 详解与代码实战

(一)数据格式

(二)代码示例:模拟 maxBy 求每个 key 的最大值

(三)代码示例 :体温异常监测统计输出

四、总结


        在大数据流处理领域,Apache Flink 凭借其卓越的性能和丰富的功能备受青睐。而 Flink 中的状态(State)管理机制,更是支撑复杂流处理任务的关键支柱。无论是数据去重、模式匹配还是窗口聚合分析,状态管理都发挥着不可或缺的作用。本文将深入浅出地剖析 Flink 状态相关知识,结合实际代码案例助你理解这一重要概念。

一、有状态计算与无状态计算

(一)概念差异

无状态计算

        无需考虑历史数据,具有幂等性,相同输入必然得到相同输出。例如 map 操作,输入单词 “hello” 就记为 (hello, 1),每次输入 “hello” 输出结果恒定。

有状态计算

        要依据历史数据,相同输入可能因状态变化产生不同输出。像 sumreducemaxBy 等聚合操作,首次输入 (hello, 1) 得 (hello, 1),再输入 (hello, 1) 会更新状态输出 (hello, 2)

(二)应用场景

无状态计算场景

        适用于数据转换、过滤等基础操作,直接采用 mapfilter 算子便捷高效。比如只想筛选出日志数据中特定级别的信息进行输出,用 filter 按日志级别规则过滤即可。

有状态计算场景

        涉及聚合(求和、求最值等)、比较操作时,就得倚仗有状态算子。像统计电商平台各品类商品销售额,借助 sum 基于商品品类 key 聚合金额数据。

二、有状态计算中的状态分类

Flink状态 
 - 托管状态
   - KeyedState ( 在keyBy之后可以使用状态 )
      - ValueState  (存储一个值)
      - ListState   (存储多个值)
      - MapState    (存储key-value) 
   - OperatorState ( 没有keyBy的情况下也可以使用 ) [不用]
 - 原生状态 (不用)

        有状态的计算是流处理框架要实现的重要功能,因为稍复杂的流处理场景都需要记录状态(State),然后在新流入数据的基础上不断更新状态。下面的几个场景都需要使用流处理的状态功能:

  • 数据流中的数据有重复,想对重复数据去重,需要记录哪些数据已经流入过应用,当新数据流入时,根据已流入过的数据来判断去重。
  • 检查输入流是否符合某个特定的模式,需要将之前流入的元素以状态的形式缓存下来。比如,判断一个温度传感器数据流中的温度是否在持续上升。
  • 对一个时间窗口内的数据进行聚合分析,分析一个小时内某项指标的75分位或99分位的数值。

其实窗口本身就是状态,他不是立即出结果,而是将数据都保存起来,达到触发条件才计算。

        一个状态更新和获取的流程如下图所示,一个算子子任务接收输入流,获取对应的状态,根据新的计算结果更新状态。一个简单的例子是对一个时间窗口内输入流的某个整数字段求和,那么当算子子任务接收到新元素时,会获取已经存储在状态中的数值,然后将当前输入加到状态上,并将状态数据更新。

以wordcout为例,说明上图的流程

(一)托管状态(Managed State)与原生状态(Raw State)

两者的区别

        Managed State是由Flink管理的,Flink帮忙存储、恢复和优化,Raw State是开发者自己管理的,需要自己序列化。

具体区别

管理方式
  • 托管状态:由 Flink Runtime 托管,自动存储、恢复,并行度调整时能自动重新分布状态,开发者无需操心底层存储细节,Flink 已做优化处理。
  • 原生状态:开发者全程自主把控,要手动序列化,以字节数组存储,Flink 不了解存储的数据结构,管理成本高。
数据结构支持
  • 托管状态:支持 ValueState(存单值)、ListState(存列表值)、MapState(存键值对)等多样结构,方便依业务逻辑选择适配。
  • 原生状态:仅支持字节,上层复杂数据结构得自行序列化为字节数组再操作。
使用场景
  • 托管状态:多数算子继承 Rich 函数类等接口即可轻松使用,涵盖日常众多流处理任务。
  • 原生状态:在现有算子与托管状态无法满足特殊、复杂自定义需求,比如自研特殊聚合逻辑算子时才会启用。

(二)托管状态细分  Keyed State 和 Operator State

Keyed State(键控状态)

       

        Flink 为每个键值维护一个状态实例,并将具有相同键的所有数据,都分区到同一个算子任务中,这个任务会维护和处理这个key对应的状态。当任务处理一条数据时,它会自动将状态的访问范围限定为当前数据的key。因此,具有相同key的所有数据都会访问相同的状态。

        需要注意的是键控状态只能在 KeyedStream 上进行使用,可以通过 stream.keyBy(...) 来得到 KeyedStream 。

按键分区状态(Keyed State)分类

Flink 提供了以下数据格式来管理和存储键控状态 (Keyed State)

  • ValueState:存储单值类型的状态。可以使用 update(T) 进行更新,并通过 T value() 进行检索。
  • ListState:存储列表类型的状态。可以使用 add(T) 或 addAll(List) 添加元素;并通过 get() 获得整个列表。
  • ReducingState:用于存储经过 ReduceFunction 计算后的结果,使用 add(T) 增加元素。
  • AggregatingState:用于存储经过 AggregatingState 计算后的结果,使用 add(IN) 添加元素。
  • FoldingState:已被标识为废弃,会在未来版本中移除,官方推荐使用 AggregatingState 代替。
  • MapState:维护 Map 类型的状态。

Operator State(算子状态)

引用:Flink中的状态管理_flink有状态和无状态-CSDN博客 三.算子状态(Operator State)

        算子状态(Operator State)就是一个算子并行实例上定义的状态,作用范围被限定为当前算子任务。(每个算子子任务共享一个算子状态,子任务间不共享)

        算子状态的实际应用场景不如Keyed State多,一般用在Source或Sink等与外部系统连接的算子上,一般使用不多。

当算子的并行度发生变化时,算子状态也支持在并行的算子任务实例之间进行重组分配。根据状态类型的不同,重组分配的方案也会有所差异。

        综上所述,算子状态是一种在特定算子上定义的状态,其作用范围仅限于该算子任务,且与数据的键值无关。相比之下,按键分区状态提供了更丰富的功能和操作,适用于处理与特定键值相关联的数据。在实际应用中,需要根据具体需求和场景选择合适的状态类型来管理数据和共享状态。

        算子状态也支持不同的结构类型,主要有三种:ListState、UnionListState和BroadcastState

列表状态(ListState)

        与Keyed State中的ListState一样,将状态表示为一组数据的列表。

        与Keyed State中的列表状态的区别是,在算子状态的上下文中,不会按键(key)分别处理状态,所以每一个并行子任务上只会保留一个“列表”(list),也就是当前并行子任务上所有状态项的集合。列表中的状态项就是可以重新分配的最细粒度,彼此之间完全独立。

        当算子并行度进行缩放调整时,算子的状态列表将会被全部收集收集起来,再通过轮询的方式重新依次分配给新的所有并行任务。

        算子状态中不会存在“键组”(key group)这样的结构,所以为了方便重组分配,就把它直接定义成了“列表”(list)。这也就解释了,为什么算子状态中没有最简单的值状态(ValueState)。


联合列表状态(UnionListState)

        与ListState类似,联合列表状态也会将状态表示为一个列表。它与常规列表状态的区别在于,算子并行度进行缩放调整时对于状态的分配方式不同。

        在并行度进行缩放调整时,联合列表与普通列表不同,联合列表会将所有并行子任务的列表状态收集起来,并直接向所有并行子任务广播完整的列表。如果列表中状态项太多则不推荐使用联合里欸包状态。

        使用上也与ListState类似,只需要在实现CheckpointedFunction类的initializeState方法时,通过上下文获取算子状态使用 .getUnionListState() 即可,其他与ListState无异。


广播状态(BroadcastState)

        有时我们希望算子并行子任务都保持同一份“全局”状态,用来做统一的配置和规则设定。这时所有分区的所有数据都会访问到同一个状态,状态就像被“广播”到所有分区一样,这种特殊的算子状态,就叫作广播状态(BroadcastState)。

        在并行度进行缩放操作时,由于是全局状态,也不会造成影响。
        

        简单来说,就是一条流广播后专门读取配置,与普通的数据流进行连结,然后广播流将配置加载到广播状态中,这样普通的数据流就能够在不重启程序的情况下通过上下文动态读取配置。

三、Keyed State 详解与代码实战

(一)数据格式

Flink 为 Keyed State 提供多种实用数据格式:

  1. ValueState:存储单个值,用 update(T) 更新,T value() 检索取值,常用于保存当前最值、计数等单一数据指标。
  2. ListState:能存多个值,通过 add(T)addAll(List) 添加元素,get() 获取完整列表,适合缓存历史数据序列,如记录用户近期操作记录列表。
  3. ReducingState:基于 ReduceFunction 计算结果存储,add(T) 增添元素,持续归约数据。
  4. AggregatingState:存放 AggregatingState 计算结果,按自定义聚合逻辑 add(IN) 处理输入更新状态,满足复杂聚合求值。
  5. MapState:维护 Map 类型状态,灵活处理键值对形式数据存储与操作。

(二)代码示例:模拟 maxBy 求每个 key 的最大值

import org.apache.flink.api.common.RuntimeExecutionMode;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.common.functions.RichMapFunction;
import org.apache.flink.api.common.state.ValueState;
import org.apache.flink.api.common.state.ValueStateDescriptor;
import org.apache.flink.api.java.functions.KeySelector;
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.environment.StreamExecutionEnvironment;

public class _01_KeyedStateDemo {

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

        //1. env-准备环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setRuntimeMode(RuntimeExecutionMode.AUTOMATIC);

        //2. source-加载数据
        DataStream<Tuple2<String, Long>> tupleDS = env.fromElements(
                Tuple2.of("北京", 1L),
                Tuple2.of("上海", 2L),
                Tuple2.of("北京", 6L),
                Tuple2.of("上海", 8L),
                Tuple2.of("北京", 3L),
                Tuple2.of("上海", 4L),
                Tuple2.of("北京", 7L)
        );

        //2. source-加载数据
        tupleDS.keyBy(new KeySelector<Tuple2<String, Long>, String>() {

            @Override
            public String getKey(Tuple2<String, Long> value) throws Exception {
                return value.f0;
            }
        }).map(new RichMapFunction<Tuple2<String, Long>, Tuple2<String,Long>>() {

            // 借助状态这个API实现

            ValueState<Long> maxValueState= null;
            @Override
            public void open(Configuration parameters) throws Exception {
                // 就是对ValueState初始化
                ValueStateDescriptor<Long> stateDescriptor = new ValueStateDescriptor<Long>("valueState",Long.class);
                maxValueState = getRuntimeContext().getState(stateDescriptor);
            }



            @Override
            public Tuple2<String, Long> map(Tuple2<String, Long> value) throws Exception {

                Long val = value.f1;
                if(maxValueState.value() == null){
                    maxValueState.update(val);
                }else{
                    if(maxValueState.value() < val){
                        maxValueState.update(val);
                    }
                }
                return Tuple2.of(value.f0,maxValueState.value());
            }
        }).print();
                //.maxBy(1).print();
        //3. transformation-数据处理转换
        //4. sink-数据输出


        //5. execute-执行
        env.execute();
    }
}

        在此代码中,先构建 Flink 执行环境、加载数据,按城市 keyBy 后,在 map 里利用 ValueState。open 方法初始化状态,map 里对比输入值与状态存储的最大值,按需更新并输出对应城市及最大值,清晰展示 Keyed State 求最值用法。

通过Map计算最大值的案例

完整代码

package com.bigdata.state;

import org.apache.flink.api.common.RuntimeExecutionMode;
import org.apache.flink.api.common.functions.RichMapFunction;
import org.apache.flink.api.common.state.ValueState;
import org.apache.flink.api.common.state.ValueStateDescriptor;
import org.apache.flink.api.java.functions.KeySelector;
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.environment.StreamExecutionEnvironment;

import java.util.HashMap;
import java.util.Map;


public class _01_KeyedStateDemo_MapTest {

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

        //1. env-准备环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setRuntimeMode(RuntimeExecutionMode.AUTOMATIC);

        //2. source-加载数据
        DataStream<Tuple2<String, Long>> tupleDS = env.fromElements(
            Tuple2.of("北京", 1L),
            Tuple2.of("上海", 2L),
            Tuple2.of("北京", 6L),
            Tuple2.of("上海", 8L),
            Tuple2.of("北京", 3L),
            Tuple2.of("上海", 4L),
            Tuple2.of("北京", 7L)
        );

        //2. source-加载数据
        tupleDS.keyBy(new KeySelector<Tuple2<String, Long>, String>() {

            @Override
            public String getKey(Tuple2<String, Long> value) throws Exception {
                return value.f0;
            }
        }).map(new RichMapFunction<Tuple2<String, Long>, Tuple2<String,Long>>() {

            // 借助状态这个API实现

            Map<String,Long> map = new HashMap<String,Long>();


            @Override
            public Tuple2<String, Long> map(Tuple2<String, Long> value) throws Exception {

                Long val = value.f1;
                if(!map.containsKey(value.f0)){
                    map.put(value.f0,value.f1);
                }else{
                    Long mapValue = map.get(value.f0);
                    if(mapValue < val){
                        map.put(value.f0,value.f1);
                    }
                }
                return Tuple2.of(value.f0,map.get(value.f0));
            }
        }).print();
        //.maxBy(1).print();
        //3. transformation-数据处理转换
        //4. sink-数据输出


        //5. execute-执行
        env.execute();
    }
}

(三)代码示例 :体温异常监测统计输出

package com.bigdata.state;

import org.apache.flink.api.common.RuntimeExecutionMode;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.common.functions.RichFlatMapFunction;
import org.apache.flink.api.common.state.ListState;
import org.apache.flink.api.common.state.ListStateDescriptor;
import org.apache.flink.api.common.state.ValueState;
import org.apache.flink.api.common.state.ValueStateDescriptor;
import org.apache.flink.api.java.functions.KeySelector;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.planner.expressions.In;
import org.apache.flink.util.Collector;

import java.util.ArrayList;

public class _02_KeyedStateDemo2 {

    // 如果一个人的体温超过阈值38度,超过3次及以上,则输出: 姓名 [温度1,温度2,温度3]
    public static void main(String[] args) throws Exception {

        //1. env-准备环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setRuntimeMode(RuntimeExecutionMode.AUTOMATIC);

        //2. source-加载数据
        DataStreamSource<String> dataStreamSource = env.socketTextStream("localhost", 8889);
        //3. transformation-数据处理转换   zs,37
        dataStreamSource.map(new MapFunction<String, Tuple2<String,Integer>>() {
            @Override
            public Tuple2<String, Integer> map(String value) throws Exception {
                String[] arr = value.split(",");
                return Tuple2.of(arr[0],Integer.valueOf(arr[1]));
            }
        }).keyBy(new KeySelector<Tuple2<String, Integer>, String>() {
            @Override
            public String getKey(Tuple2<String, Integer> value) throws Exception {
                return value.f0;
            }
        }).flatMap(new RichFlatMapFunction<Tuple2<String, Integer>, Tuple2<String, ArrayList<Integer>>>() {

            ValueState<Integer> valueState = null;
            ListState<Integer> listState = null;

            @Override
            public void open(Configuration parameters) throws Exception {

                ValueStateDescriptor<Integer> stateDescriptor = new ValueStateDescriptor<Integer>("numState",Integer.class);
                valueState = getRuntimeContext().getState(stateDescriptor);

                ListStateDescriptor<Integer> listStateDescriptor = new ListStateDescriptor<>("listState", Integer.class);
                listState = getRuntimeContext().getListState(listStateDescriptor);

            }

            @Override
            public void flatMap(Tuple2<String, Integer> value, Collector<Tuple2<String, ArrayList<Integer>>> out) throws Exception {


                Integer tiwen = value.f1;
                if(tiwen >= 38){
                    valueState.update(valueState.value()==null?1:(valueState.value()+1));
                    listState.add(tiwen);
                }
                if(valueState.value()!=null && valueState.value() >= 3){
                    ArrayList<Integer> list = new ArrayList<>();
                    Iterable<Integer> iterable = listState.get();
                    for (Integer tiwenwen : iterable) {
                        list.add(tiwenwen);
                    }
                    out.collect(Tuple2.of(value.f0,list));
                }

            }
        }).print();
        //4. sink-数据输出


        //5. execute-执行
        env.execute();
    }
}

        这段代码从本地 socket 读取姓名与体温数据,转换格式后按姓名 keyBy。在 flatMap 里,用 ValueState 统计体温超 38 度次数,ListState 缓存超温数据,次数达标则输出对应姓名及体温列表,巧妙实现复杂业务规则监测。

四、总结

        Flink 状态管理是构建强大流处理应用的基石,合理运用有状态、无状态计算,精准抉择托管状态类型及对应数据格式,结合实战代码灵活处理业务逻辑,能解锁 Flink 在大数据场景无限潜能,高效应对各类数据处理挑战,助你在大数据开发之路上稳步前行。后续可深入探索状态持久化、故障恢复等进阶特性,深挖 Flink 流处理精髓。

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

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

相关文章

【数据结构计数排序】计数排序

非比较排序概念 非比较排序是一种排序算法&#xff0c;它不是通过比较元素大小进行排序的&#xff0c;而是基于元素的特征和属性排序。这种排序方法在特定情况下&#xff0c;可以做到比元素比较排序&#xff08;快排&#xff0c;归并&#xff09;更有效率。尤其是在处理大量数…

Java GET请求 请求参数在Body中使用Json格式传参

业务需要调个三方接口 使用GET请求方式 但是&#xff01;请求参数不在Query中&#xff0c;竟然在Body中&#xff0c;使用Json格式传参 在API调试工具里面可以调通 在java代码里&#xff0c;死活调不通 网上搜了搜&#xff0c;找到一个靠谱的&#xff0c;记录一下 import o…

Linux的文件系统

这里写目录标题 一.文件系统的基本组成索引节点目录项文件数据的存储扇区三个存储区域 二.虚拟文件系统文件系统分类进程文件表读写过程 三.文件的存储连续空间存放方式缺点 非连续空间存放方式链表方式隐式链表缺点显示链接 索引数据库缺陷索引的方式优点&#xff1a;多级索引…

[golang][MAC]Go环境搭建+VsCode配置

一、go环境搭建 1.1 安装SDK 1、下载go官方SDK 官方&#xff1a;go 官方地址 中文&#xff1a;go 中文社区 根据你的设备下载对应的安装包&#xff1a; 2、打开压缩包&#xff0c;根据引导一路下一步安装。 3、检测安装是否完成打开终端&#xff0c;输入&#xff1a; go ve…

从繁琐到高效:智能生成PPT的神秘力量

在这个技术爆炸的时代&#xff0c;一场精彩的演讲离不开一份出色的PPT。但制作PPT&#xff0c;就像是一场与时间的博弈&#xff0c;费尽心思构思版式、精炼文案、选择配图&#xff0c;稍不留神&#xff0c;就会被拖入无底深渊。可是你知道吗&#xff1f;现在只需动动手指&#…

二分法篇——于上下边界的扭转压缩间,窥见正解辉映之光(1)

前言 二分法&#xff0c;这一看似简单却又充满哲理的算法&#xff0c;犹如一道精巧的数学之门&#xff0c;带领我们在问题的迷雾中找到清晰的道路。它的名字虽简单&#xff0c;却深藏着智慧的光辉。在科学的浩瀚星空中&#xff0c;二分法如一颗璀璨的星辰&#xff0c;指引着我们…

【软件各类应用解决方案】ERP企业资源管理系统整体解决方案,采购管理方案,仓库管理方案,财务管理方案,人力管理方案,资产管理方案,对账管理(word完整版)

目录 第一部分 概述 第二部分 方案介绍 第三部分 系统业务流程 3.1 关键需求概括分析 3.1.1 销售管理方面 3.1.2 采购管理方面 3.1.3 仓库管理方面 3.1.4 财务管理方面 3.1.5 人力资源方面 3.2 关键需求具体分析 3.2.1 财务管理 3.2.1.1会计凭证解决 3.2.1.2钞…

实验二 选择结构程序设计

实验名称 实验二 选择结构程序设计 实验目的 &#xff08;1&#xff09;掌握关系运算符和逻辑运算符的使用方法&#xff0c;能够表达复杂的逻辑条件。 &#xff08;2&#xff09;掌握if语句的使用方法&#xff0c;掌握多重条件下的if语句嵌套使用。 &#xff08;3&#xff09;…

第33周:运动鞋识别(Tensorflow实战第五周)

目录 前言 一、前期工作 1.1 设置GPU 1.2 导入数据 1.3 查看数据 二、数据预处理 2.1 加载数据 2.2 可视化数据 2.3 再次检查数据 2.4 配置数据集 2.4.1 基本概念介绍 2.4.2 代码完成 三、构建CNN网络 四、训练模型 4.1 设置动态学习率 4.2 早停与保存最佳模型…

Robot Screw Theory (Product of Exponentials)机器人螺旋理论(指数积)

Screw Theory 螺旋理论 Screw theory uses the fact that every rigid body transformation can be expressed by a rotational and translational movement.螺旋理论利用了每个刚体变换都可以通过旋转和平移运动来表示这一事实。 Robert Ball developed the theory in 19th ce…

【maven-5】Maven 项目构建的生命周期:深入理解与应用

1. 生命周期是什么 ​在Maven出现之前&#xff0c;项目构建的生命周期就已经存在&#xff0c;软件开发人员每天都在对项目进行清理&#xff0c;编译&#xff0c;测试及部署。虽然大家都在不停地做构建工作&#xff0c;但公司和公司间&#xff0c;项目和项目间&#xff0c;往往…

skywalking 配置elasticsearch持久化

下载和启动elasticsearch elasticsearch-7.17.25-linux-x86_64.tar.gz&#xff0c;解密文件tar -xvf elasticsearch-7.17.25-linux-x86_64.tar.gz 进入到bin目录&#xff0c;启动 elasticsearch -d 后台运行 下载skywalking服务包 apache-skywalking-apm-9.3.0.tar.gz&#x…

MySQL 复合查询

实际开发中往往数据来自不同的表&#xff0c;所以需要多表查询。本节我们用一个简单的公司管理系统&#xff0c;有三张表EMP,DEPT,SALGRADE 来演示如何进行多表查询。表结构的代码以及插入的数据如下&#xff1a; DROP database IF EXISTS scott; CREATE database IF NOT EXIST…

数据集-目标检测系列- 海边漫步锻炼人检测数据集 person >> DataBall

数据集-目标检测系列- 海边漫步锻炼人检测数据集 person >> DataBall DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种数据集&#xff0c;持续增加中。 需要更多数据资源和技术解决方案&#xff0c;知识星球&#xff1a; “DataBall - X 数据球…

【汇编语言】call 和 ret 指令(三) —— 深度解析汇编语言中的批量数据传递与寄存器冲突

文章目录 前言1. 批量数据的传递1.1 存在的问题1.2 如何解决这个问题1.3 示例演示1.3.1 问题说明1.3.2 程序实现 2. 寄存器冲突问题的引入2.1 问题引入2.2 分析与解决问题2.2.1 字符串定义方式2.2.2 分析子程序功能2.2.3 得到子程序代码 2.3 子程序的应用2.3.1 示例12.3.2 示例…

刷题日常(找到字符串中所有字母异位词,​ 和为 K 的子数组​,​ 滑动窗口最大值​,全排列)

找到字符串中所有字母异位词 给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 题目分析&#xff1a; 1.将p里面的字符先丢进一个hash1中&#xff0c;只需要在S字符里面找到多少个和他相同的has…

Git 快速入门:全面了解与安装步骤

Git 快速入门&#xff1a;全面了解与安装步骤 一、关于Git 1.1 简介 Git 是一个开源的分布式版本控制系统&#xff0c;由 Linus Torvalds 于 2005 年创建&#xff0c;最初是为了更好地管理 Linux 内核开发而设计。 Git用于跟踪计算机文件的变化&#xff0c;特别是源代码文件…

私有库gitea安装

一 gitea是什么 Gitea是一款自助Git服务&#xff0c;简单来说&#xff0c;就是可以一个私有的github。 搭建很容易。 Gitea依赖于Git。 类似Gitea的还有GitHub、Gitee、GitLab等。 以下是安装步骤。 二 安装sqilite 参考&#xff1a; 在windows上安装sqlite 三 安装git…

[CTF/网络安全] 攻防世界 upload1 解题详析

[CTF/网络安全] 攻防世界 upload1 解题详析 考察文件上传&#xff0c;具体原理及姿势不再赘述。 姿势 在txt中写入一句话木马<?php eval($_POST[qiu]);?> 回显如下&#xff1a; 查看源代码&#xff1a; Array.prototype.contains function (obj) { var i this.…

基于HTML+CSS的房地产销售网站设计与实现

摘 要 房地产销售系统&#xff0c;在二十年来互联网时代下有着巨大的意义&#xff0c;随着互联网不断的发展扩大&#xff0c;一个方便直 观的房地产管理系统的网站开发是多么地有意义&#xff0c;不仅打破了传统的线下看房&#xff0c;线下获取资讯&#xff0c;也给房地产从业…