Flink面试题及详细答案100道(1-20)- 基础概念与架构

前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,SQL,Linux… 。

前后端面试题-专栏总目录

在这里插入图片描述

文章目录

  • 一、本文面试题目录
      • 1. 什么是Flink?它与Spark、Storm等流处理框架相比有哪些核心优势?
      • 2. 简述Flink的核心架构组件及其作用
      • 3. Flink中的“流(Stream)”和“批(Batch)”是如何统一的?其设计思想是什么?
      • 4. 解释Flink中的“状态(State)”概念,为什么状态管理对Flink至关重要?
      • 5. 什么是Flink的“时间特性”?包括哪几种时间类型,各自的应用场景是什么?
      • 6. 简述Flink的“检查点(Checkpoint)”机制,其作用是什么?
      • 7. Flink的“保存点(Savepoint)”与检查点有何区别?何时需要使用保存点?
      • 8. 解释Flink中的“并行度(Parallelism)”概念,如何设置和调整并行度?
      • 9. Flink的“Slot”是什么?它与并行度的关系是什么?
      • 10. 什么是Flink的“作业图(JobGraph)”“执行图(ExecutionGraph)”和“物理执行图(Physical Graph)”?三者的转换关系是什么?
      • 11. Flink支持哪几种部署模式?各有什么特点?
      • 12. 解释Flink中的“算子(Operator)”概念,常见的算子有哪些?
      • 13. Flink的“数据交换策略(Data Exchange Strategy)”有哪几种?分别适用于什么场景?
      • 14. 什么是Flink的“窗口(Window)”?为什么窗口是流处理中的核心概念?
      • 15. Flink的“背压(Backpressure)”是什么?如何检测和处理背压问题?
      • 16. 简述Flink的“类型系统(Type System)”,为什么需要关注数据类型?
      • 17. Flink的“ExecutionConfig”有什么作用?可以配置哪些核心参数?
      • 18. 什么是Flink的“动态缩放(Dynamic Scaling)”?其实现原理是什么?
      • 19. 解释Flink中的“Watermark”机制,它如何解决数据乱序问题?
      • 20. Flink的“Exactly-Once”语义是如何保证的?依赖哪些核心机制?
  • 二、100道Flink 面试题目录列表

一、本文面试题目录

1. 什么是Flink?它与Spark、Storm等流处理框架相比有哪些核心优势?

Flink是一个开源的分布式流处理框架,专注于实时数据处理和批处理,能够同时支持高吞吐、低延迟、 Exactly-Once语义和状态管理等特性。

核心优势:

  • 处理模型:Flink以“流优先”为设计理念,将批处理视为流处理的一种特殊情况(有界流),而Spark基于微批处理模拟流处理,Storm虽为纯流处理但缺乏批处理能力。
  • 时间特性:Flink内置事件时间(Event Time)支持,能更准确处理乱序数据;Spark Streaming依赖处理时间(Processing Time),对乱序数据处理能力较弱。
  • 状态管理:Flink提供丰富的状态后端(如RocksDB)和状态访问API,支持大规模状态存储和高效访问;Storm的状态管理需依赖外部系统。
  • 容错机制:Flink的Checkpoint机制轻量且高效,能在毫秒级完成快照;Spark Streaming的Checkpoint开销较大。
  • 延迟与吞吐:Flink可实现毫秒级延迟且保持高吞吐;Spark Streaming延迟通常在秒级,Storm虽延迟低但吞吐受限。

2. 简述Flink的核心架构组件及其作用

Flink的核心架构组件包括:

  • JobManager:集群的“大脑”,负责作业的调度和管理。
    • 接收客户端提交的作业,生成执行计划(ExecutionGraph)。
    • 协调Checkpoint,故障恢复时重新分配任务。
    • 管理TaskManager的资源分配。
  • TaskManager:执行具体任务的工作节点。
    • 运行任务(Task),处理数据并与其他节点交换数据。
    • 提供Slot资源(任务运行的内存隔离单元)。
    • 向JobManager汇报自身状态和资源使用情况。
  • ResourceManager:负责集群资源的管理和分配(仅在YARN/K8s等集群模式下生效)。
    • 为新提交的作业分配TaskManager资源。
    • 监控资源使用情况,回收闲置资源。
  • Dispatcher:接收客户端连接和作业提交,为每个作业启动对应的JobManager。
    • 提供Web UI用于作业监控和管理。
    • 在高可用模式下协调JobManager的故障转移。

3. Flink中的“流(Stream)”和“批(Batch)”是如何统一的?其设计思想是什么?

Flink通过“有界流”和“无界流”的概念统一流处理和批处理:

  • 无界流(Unbounded Stream):数据持续产生,无终止点(如实时日志),对应传统流处理场景。
  • 有界流(Bounded Stream):数据有明确的开始和结束(如历史数据文件),对应批处理场景。

设计思想:

  • 以流处理为基础,将批处理视为流处理的特例(有界流),共享同一套核心引擎。
  • 统一的API层(DataStream API)同时支持两种模式,开发者无需切换框架即可处理不同类型的数据。
  • 优化器根据数据是否有界自动调整执行策略(如批处理可使用更高效的排序和 shuffle 算法)。

示例:同一套代码可处理实时流和历史批数据

// 读取无界流(Kafka)
DataStream<String> stream = env.addSource(new FlinkKafkaConsumer<>("topic", new SimpleStringSchema(), props));// 读取有界流(文件)
DataStream<String> batch = env.readTextFile("file:///path/to/data");// 统一处理逻辑
stream.filter(...).map(...).print();
batch.filter(...).map(...).print();

4. 解释Flink中的“状态(State)”概念,为什么状态管理对Flink至关重要?

状态(State)是Flink算子在处理数据过程中需要保存的中间结果或元数据(如计数器、聚合结果、窗口状态等)。

状态管理的重要性:

  • 支持有状态计算:许多流处理场景(如累加计数、会话窗口、关联分析)需要依赖历史状态。
  • 保证容错性:通过Checkpoint机制持久化状态,故障恢复时可恢复到最近的一致状态。
  • 提升性能:Flink提供本地状态存储(如内存或RocksDB),避免频繁访问外部系统。

状态类型:

  • 托管状态(Managed State):由Flink自动管理,支持Checkpoint和故障恢复(如ValueState、ListState)。
  • 原始状态(Raw State):用户自行管理,Flink仅保存字节数组,不提供序列化和恢复支持。

示例:使用ValueState统计单词出现次数

public class WordCountState extends RichFlatMapFunction<String, Tuple2<String, Integer>> {private transient ValueState<Integer> countState;@Overridepublic void open(Configuration parameters) {// 初始化状态ValueStateDescriptor<Integer> descriptor = new ValueStateDescriptor<>("count", Integer.class);countState = getRuntimeContext().getState(descriptor);}@Overridepublic void flatMap(String word, Collector<Tuple2<String, Integer>> out) throws Exception {Integer count = countState.value() == null ? 0 : countState.value();count++;countState.update(count);out.collect(new Tuple2<>(word, count));}
}

5. 什么是Flink的“时间特性”?包括哪几种时间类型,各自的应用场景是什么?

Flink的时间特性指流处理中对时间的定义方式,用于处理事件的时序关系,尤其是乱序数据。

三种时间类型:

  • 事件时间(Event Time):事件实际产生的时间(如日志中的timestamp字段)。
    • 应用场景:需要精确计算事件时序的场景(如实时监控、异常检测),不受处理延迟影响。
  • 处理时间(Processing Time):事件被Flink算子处理时的系统时间。
    • 应用场景:对时间精度要求不高,追求低延迟的场景(如实时报表预览)。
  • 摄入时间(Ingestion Time):事件进入Flink系统的时间(如Source算子接收数据的时间)。
    • 应用场景:介于事件时间和处理时间之间,无需显式指定事件时间字段时使用。

示例:设置事件时间和Watermark

// 设置事件时间特性
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);// 从数据中提取事件时间并生成Watermark
DataStream<Event> stream = env.addSource(...).assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor<Event>(Time.seconds(5)) {@Overridepublic long extractTimestamp(Event element) {return element.getTimestamp(); // 提取事件时间字段}});

6. 简述Flink的“检查点(Checkpoint)”机制,其作用是什么?

Checkpoint是Flink实现容错的核心机制,通过周期性地对算子状态和数据流位置进行快照,实现故障后的状态恢复。

工作原理:

  1. JobManager的Checkpoint Coordinator发起Checkpoint。
  2. 各算子接收到Checkpoint请求后,将自身状态写入持久化存储(如HDFS)。
  3. 状态写入完成后,算子向Coordinator确认Checkpoint完成。
  4. 所有算子完成后,Checkpoint标记为成功。

作用:

  • 故障恢复:当TaskManager崩溃时,JobManager可基于最近的Checkpoint重启作业并恢复状态。
  • 保证Exactly-Once语义:通过Checkpoint和两阶段提交(2PC)确保数据处理的一致性。

示例:配置Checkpoint

// 启用Checkpoint,间隔1000ms
env.enableCheckpointing(1000);// 配置Checkpoint参数
CheckpointConfig config = env.getCheckpointConfig();
config.setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE); // 精确一次语义
config.setMinPauseBetweenCheckpoints(500); // 两次Checkpoint最小间隔
config.setCheckpointTimeout(60000); // 超时时间
config.setMaxConcurrentCheckpoints(1); // 最大并发Checkpoint数

7. Flink的“保存点(Savepoint)”与检查点有何区别?何时需要使用保存点?

区别:

  • 触发方式:Checkpoint由系统自动周期性触发;Savepoint需用户手动触发。
  • 用途:Checkpoint用于故障恢复,生命周期与作业绑定(作业终止后自动删除);Savepoint用于作业版本升级、迁移或暂停后重启,需手动删除。
  • 存储格式:Savepoint使用更稳定的二进制格式,跨版本兼容性更好;Checkpoint格式可能随版本变化。

使用场景:

  • 作业升级:修改代码后,从Savepoint恢复作业以保留历史状态。
  • 集群迁移:将作业从一个集群迁移到另一个集群。
  • 资源调整:调整并行度或资源配置后重启作业。
  • 暂停与重启:暂时停止作业,后续从相同状态继续运行。

示例:触发和使用Savepoint

# 触发Savepoint
bin/flink savepoint <job-id> <savepoint-path># 从Savepoint恢复作业
bin/flink run -s <savepoint-path> -c <main-class> <jar-file>

8. 解释Flink中的“并行度(Parallelism)”概念,如何设置和调整并行度?

并行度(Parallelism)指Flink作业中算子的任务(Task)数量,决定了作业的并行处理能力。每个Task独立运行在不同的Slot中。

设置方式(优先级从高到低):

  1. 算子级别:operator.setParallelism(n)
  2. 执行环境级别:env.setParallelism(n)
  3. 客户端提交时:bin/flink run -p n <jar-file>
  4. 配置文件级别:flink-conf.yaml中设置parallelism.default

示例:设置并行度

// 环境级别并行度
ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(4);// 算子级别并行度(覆盖环境设置)
DataStream<String> stream = env.readTextFile("data.txt").filter(...).map(...).setParallelism(8); // 该map算子并行度为8

调整并行度:通过Savepoint停止作业后,重新提交时指定新的并行度。

9. Flink的“Slot”是什么?它与并行度的关系是什么?

Slot是TaskManager中资源隔离的单元,代表一个固定大小的资源子集(主要是内存)。每个TaskManager可配置多个Slot(如taskmanager.numberOfTaskSlots: 4)。

与并行度的关系:

  • 每个Slot可运行一个或多个Task(属于不同算子),但同一算子的不同Task不能运行在同一Slot。
  • 作业的总并行度受限于集群的总Slot数(总Slot = 所有TaskManager的Slot数之和)。
  • 例如:集群总Slot为10,作业并行度最多为10;若作业并行度为8,则使用8个Slot。

Slot的作用:

  • 资源隔离:避免不同作业/任务争夺资源。
  • 资源共享:同一作业的不同算子Task可共享Slot,提高资源利用率。

10. 什么是Flink的“作业图(JobGraph)”“执行图(ExecutionGraph)”和“物理执行图(Physical Graph)”?三者的转换关系是什么?

  • 作业图(JobGraph):客户端将用户代码转换的最初始图,包含算子(Operator)和它们之间的数据流,未考虑并行度。

    • 由客户端生成,提交给JobManager。
  • 执行图(ExecutionGraph):JobManager将JobGraph按并行度拆分后生成的图,包含并行化的任务(ExecutionVertex)和中间结果分区(IntermediateResultPartition)。

    • 是JobGraph的并行化版本,用于调度和执行。
  • 物理执行图(Physical Graph):任务在TaskManager上实际运行的图,包含具体的Task实例和物理数据传输链路。

    • 由TaskManager根据ExecutionGraph部署后生成,反映实际运行状态。

转换关系:
用户代码 → JobGraph(客户端)→ ExecutionGraph(JobManager)→ 物理执行图(TaskManager)

11. Flink支持哪几种部署模式?各有什么特点?

Flink支持多种部署模式:

  • 本地模式(Local):

    • 特点:在单个JVM中运行,无需集群,适合开发和测试。
    • 启动方式:bin/start-cluster.sh local
  • standalone模式:

  • 特点:Flink独立集群,不依赖外部资源管理器,部署简单,适合中小规模集群。

  • 组件:包含JobManager、TaskManager和内部ResourceManager。

  • YARN模式:

    • 特点:集成Hadoop YARN,由YARN管理资源,适合已有的Hadoop生态环境。
    • 两种模式:Session模式(共享集群资源)和Per-Job模式(每个作业独占资源)。
  • Kubernetes(K8s)模式:

    • 特点:容器化部署,支持弹性扩缩容,适合云原生环境。
    • 优势:自动部署、故障自愈、资源隔离。
  • Mesos模式:

    • 特点:适用于Mesos资源管理平台,较少使用。

12. 解释Flink中的“算子(Operator)”概念,常见的算子有哪些?

算子(Operator)是Flink中对数据进行转换处理的基本单元,接收一个或多个输入数据流,产生一个输出数据流。

常见算子:

  • 转换算子(Transformation):

    • map:对每个元素应用函数转换。
    • filter:根据条件过滤元素。
    • flatMap:将一个元素转换为多个元素。
    • keyBy:按key分组,将流转换为KeyedStream。
    • reduce:对KeyedStream进行聚合,生成单个结果。
    • aggregations:如summinmax等聚合操作。
  • 窗口算子(Window):

    • window:基于时间或计数定义窗口。
    • windowAll:对整个流开窗(并行度为1)。
    • apply:对窗口内数据应用处理逻辑。
  • 连接算子(Connection):

    • union:合并多个同类型数据流。
    • connect:连接两个不同类型的数据流,保留各自类型。
    • join:基于条件关联两个数据流(通常在窗口中使用)。
  • 输出算子(Sink):

    • print:打印到控制台。
    • writeAsText:写入文本文件。
    • addSink:自定义输出(如写入Kafka、Elasticsearch)。

示例:使用多种算子

DataStream<String> input = env.socketTextStream("localhost", 9999);input.flatMap((String line, Collector<Tuple2<String, Integer>> out) -> {for (String word : line.split(" ")) {out.collect(new Tuple2<>(word, 1));}}).keyBy(tuple -> tuple.f0).timeWindow(Time.seconds(5)).sum(1).print();

13. Flink的“数据交换策略(Data Exchange Strategy)”有哪几种?分别适用于什么场景?

数据交换策略指算子之间的数据传输方式,决定了上游任务如何向下游任务发送数据。

常见策略:

  • Forward(转发):

  • 特点:上游任务直接将数据发送给下游同并行度的任务(一对一)。

  • 适用场景:mapfilter等无需重分区的算子,数据本地传输,效率高。

  • Shuffle(洗牌):

    • 特点:上游任务将数据随机分配给下游所有任务。
    • 适用场景:groupByreduce等需要全局聚合的场景,会产生网络传输。
  • Broadcast(广播):

    • 特点:上游任务将数据发送给下游所有任务(每个下游任务都接收完整数据)。
    • 适用场景:小表关联(如将配置数据广播到所有任务)。
  • Key Group(按Key分组):

    • 特点:根据Key的哈希值将数据发送到对应的下游任务(相同Key的数据进入同一任务)。
    • 适用场景:keyBy后的算子(如sumwindow),保证同一Key的数据被同一任务处理。
  • Rebalance(重平衡):

    • 特点:上游任务通过轮询方式均匀分配数据到下游任务。
    • 适用场景:数据倾斜时重新分配负载,平衡各任务压力。

14. 什么是Flink的“窗口(Window)”?为什么窗口是流处理中的核心概念?

窗口(Window)是流处理中将无限数据流分割为有限数据块进行处理的机制,是处理无界流的核心手段。

窗口的作用:

  • 流数据是无限的,窗口将其划分为有限的“批”,便于进行聚合、关联等操作(如统计每5分钟的订单量)。
  • 解决数据乱序问题,通过窗口等待延迟数据到达。

窗口类型:

  • 时间窗口(Time Window):

    • 滚动窗口(Tumbling Window):固定大小,无重叠(如每小时一个窗口)。
    • 滑动窗口(Sliding Window):固定大小,有重叠(如每30分钟统计前1小时数据)。
    • 会话窗口(Session Window):基于空闲时间划分,无活动时窗口关闭。
  • 计数窗口(Count Window):

    • 滚动计数窗口:达到指定数量的元素时触发(如每100个元素一个窗口)。
    • 滑动计数窗口:每N个元素滑动一次,窗口包含M个元素(M > N)。

示例:滚动时间窗口

DataStream<Tuple2<String, Integer>> stream = ...;// 按Key分组,每5秒一个窗口,求和
stream.keyBy(tuple -> tuple.f0).timeWindow(Time.seconds(5)).sum(1).print();

15. Flink的“背压(Backpressure)”是什么?如何检测和处理背压问题?

背压指流处理中,下游算子处理速度慢于上游算子发送速度,导致数据在中间环节积压的现象。若不处理,可能导致内存溢出或作业崩溃。

检测背压:

  • Flink Web UI:在“Job Graph”页面查看算子的“Backpressure”指标(OK/WARN/High)。
  • Metrics:监控backpressure.timeMsPerSecond等指标。
  • 日志:查看TaskManager日志中的“Backpressure detected”警告。

处理背压:

  • 优化下游算子:提高处理效率(如减少复杂计算、使用更高效的数据结构)。
  • 增加并行度:提高下游算子的并行度,提升整体处理能力。
  • 调整Checkpoint:减少Checkpoint频率或优化状态存储(如使用RocksDB)。
  • 限流:在Source端限制输入速度(如env.setBufferTimeout(-1)关闭缓冲)。
  • 数据倾斜处理:若因数据倾斜导致部分任务背压,需均衡数据分布。

16. 简述Flink的“类型系统(Type System)”,为什么需要关注数据类型?

Flink的类型系统用于描述数据流中元素的数据类型,确保序列化、反序列化和状态管理的正确性。

核心类型:

  • 基础类型:Integer、String、Double等Java基本类型及其包装类。
  • 复合类型:Tuple(元组)、POJO(普通Java对象)、Enum(枚举)。
  • 集合类型:List、Map、Array等。
  • 特殊类型:Option、Either、GenericType等。

关注数据类型的原因:

  • 序列化:Flink需将数据序列化后在网络传输或写入状态后端,类型信息确保序列化正确。
  • 状态管理:状态存储依赖类型信息,错误的类型可能导致状态无法恢复。
  • 性能优化:Flink对POJO等类型有特殊优化,使用合适的类型可提升性能。

示例:定义POJO类型(需满足无参构造函数、字段可见或有getter/setter)

public class User {private String name;private int age;// 无参构造函数public User() {}// getter和setterpublic String getName() { return name; }public void setName(String name) { this.name = name; }public int getAge() { return age; }public void setAge(int age) { this.age = age; }
}

17. Flink的“ExecutionConfig”有什么作用?可以配置哪些核心参数?

ExecutionConfig是Flink作业的执行配置对象,用于设置作业级别的执行参数,影响作业的性能和行为。

核心配置参数:

  • 并行度:setParallelism(int parallelism)
  • 检查点模式:setCheckpointingMode(CheckpointingMode mode)
  • 状态后端:setStateBackend(StateBackend backend)
  • 自动类型注册:enableAutoTypeRegistration(boolean enabled)
  • 类加载器模式:setClassLoader(ClassLoader classLoader)
  • 优化器参数:如setUseSnapshotCompression(boolean enable)启用快照压缩。

示例:配置ExecutionConfig

ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
ExecutionConfig config = env.getConfig();// 设置默认并行度
config.setParallelism(4);// 启用类型自动注册
config.enableAutoTypeRegistration(true);// 配置状态后端为RocksDB
config.setStateBackend(new RocksDBStateBackend("hdfs:///flink/checkpoints"));

18. 什么是Flink的“动态缩放(Dynamic Scaling)”?其实现原理是什么?

动态缩放指在作业运行过程中调整算子的并行度,无需停止作业,以适应数据量变化(如峰值时增加并行度,低谷时减少)。

实现原理:

  1. 触发缩放:通过Flink CLI或REST API发起缩放请求,指定新的并行度。
  2. 生成Savepoint:Flink自动触发一次Savepoint,保存当前作业状态。
  3. 重启作业:基于Savepoint停止旧作业,以新并行度重启作业。
  4. 状态重分配:将原有状态按新并行度重新分配给新任务(基于Key的哈希值)。

限制:

  • 仅支持有状态作业,且状态需可重分配(如Keyed State)。
  • 无状态作业可直接缩放,无需Savepoint。

示例:动态调整并行度

# 动态将作业并行度调整为10
bin/flink scale <job-id> 10

19. 解释Flink中的“Watermark”机制,它如何解决数据乱序问题?

Watermark是Flink中用于处理乱序数据的机制,本质是一个时间戳,标识“小于该时间戳的事件已全部到达”,用于触发窗口计算。

工作原理:

  • 生成Watermark:Source算子或自定义算子根据事件时间生成Watermark,通常设置为“当前最大事件时间 - 允许的延迟时间”。
  • 传递Watermark:Watermark在数据流中传播,下游算子根据接收到的Watermark判断是否触发窗口。
  • 触发窗口:当Watermark时间戳大于等于窗口结束时间时,触发窗口计算,处理窗口内所有数据。

解决乱序问题:

  • 通过设置合理的延迟时间(如5秒),等待迟到的数据到达后再触发窗口。
  • 对于超出Watermark的迟到数据,可通过sideOutputLateData收集到侧输出流处理。

示例:生成Watermark

DataStream<Event> stream = ...;DataStream<Event> withWatermarks = stream.assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor<Event>(Time.seconds(5)) {@Overridepublic long extractTimestamp(Event element) {return element.getEventTime(); // 提取事件时间}}
);// 处理迟到数据
OutputTag<Event> lateTag = new OutputTag<Event>("late-data"){};
SingleOutputStreamOperator<Result> result = withWatermarks.keyBy(...).timeWindow(Time.seconds(10)).sideOutputLateData(lateTag).apply(...);DataStream<Event> lateData = result.getSideOutput(lateTag);

20. Flink的“Exactly-Once”语义是如何保证的?依赖哪些核心机制?

Exactly-Once语义指数据在流处理中被精确处理一次,既不重复也不丢失,是流处理的最高一致性保证。

实现依赖的核心机制:

  1. 检查点(Checkpoint):

    • 周期性快照算子状态和数据源偏移量,故障时可恢复到一致状态。
  2. 两阶段提交(2PC):

    • 预提交(Pre-commit):各算子将状态写入临时存储,确认所有算子完成预提交。
    • 提交(Commit):Checkpoint成功后,正式提交状态和数据源偏移量。
  3. 幂等性Sink:

    • Sink算子支持幂等写入(如基于主键更新),即使重复写入也不会产生副作用。
  4. 可重放的数据源:

    • 数据源支持从指定偏移量重放数据(如Kafka的offset),确保故障后可重新消费未处理的数据。

示例:Flink与Kafka结合实现Exactly-Once

// 配置Kafka消费者为Exactly-Once
Properties consumerProps = new Properties();
consumerProps.setProperty("bootstrap.servers", "localhost:9092");
consumerProps.setProperty("group.id", "test-group");
FlinkKafkaConsumer<String> consumer = new FlinkKafkaConsumer<>("input-topic",new SimpleStringSchema(),consumerProps
);
consumer.setStartFromEarliest();
consumer.setCommitOffsetsOnCheckpoints(true); // Checkpoint成功后提交offset// 配置Kafka生产者为Exactly-Once
Properties producerProps = new Properties();
producerProps.setProperty("bootstrap.servers", "localhost:9092");
FlinkKafkaProducer<String> producer = new FlinkKafkaProducer<>("output-topic",new KeyedSerializationSchemaWrapper<>(new SimpleStringSchema()),producerProps,FlinkKafkaProducer.Semantic.EXACTLY_ONCE // 启用Exactly-Once
);// 启用Checkpoint
env.enableCheckpointing(1000, CheckpointingMode.EXACTLY_ONCE);// 处理流程
env.addSource(consumer).map(...).addSink(producer);

二、100道Flink 面试题目录列表

文章序号Flink 100道
1Flink面试题及详细答案100道(01-20)
2Flink面试题及详细答案100道(21-40)
3Flink面试题及详细答案100道(41-60)
4Flink面试题及详细答案100道(61-80)
5Flink面试题及详细答案100道(81-100)

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

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

相关文章

爬虫逆向之滑块验证码加密分析(轨迹和坐标)

本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的。否则由此产生的一切后果均与作者无关&#xff01;在爬虫开发过程中&#xff0c;滑块验证码常常成为我们获取数据的一大阻碍。而滑块验证码的加密方式多种多样&#xff0c;其中轨迹加密和坐标加密是比较常见的…

微信小程序实现导航至目的地

本人做的导航页面相关功能和效果的代码 javascript相关 Page({data: {markers: [],latitude: , // 中心点坐标longitude: ,FIXED_LAT: 31.2304, // 1. 写死的目标点坐标, 示例&#xff1a;上海人民广场FIXED_LNG: 121.4737},onLoad: function () {// 如果要显示地图可以看onLo…

中国科学社简史

中国科学社简史中国科学社&#xff0c;作为中国近代史上第一个民间综合性科学团体&#xff0c;为中国现代科学文化事业的发展做出了卓越贡献。其历程不仅见证了中国科学从萌芽到蓬勃发展的转变&#xff0c;还反映了中国科学体制化的艰难探索与辉煌成就。中国科学社的起源可追溯…

若尔当型,Jordon Form

文章目录一、相似二、若尔当型1.1 认识若尔当型1.2 凯莱-哈密顿定理 (Cayley-Hamilton Theorem)一、相似 Every matrix CB−1ABC B^{-1}ABCB−1AB has the same eigenvalues as A. These C’s are similar to A. 任意一个矩阵C&#xff0c;满足 CB−1ABC B^{-1}ABCB−1AB 都和…

解决uni-app微信小程序编译报错:unexpected character `1`

问题原因在uni-app微信小程序开发中&#xff0c;当template模板中包含英文符号<或>时&#xff0c;微信小程序的编译器会将这些符号误认为是HTML标签的开闭符号&#xff0c;从而导致类似unexpected character 1的编译错误。错误示例<view class"plan-bmi">…

[Linux] RAID存储技术

目录 RAID实现方式 RAID 0 RAID 1 RAID 5 RAID 10 管理RAID0 创建RAID 查看RAID 格式化和挂载 删除RAID 管理RAID1 创建RAID 查看RAID 格式化和挂载 增加热备盘 模拟故障 删除故障磁盘 删除RAID 管理RAID5 创建RAID 查看RAID md5设备划分分区 RAID实现方…

程序设计|C语言教学——C语言基础4:进阶

一、预处理指令预处理指令在编译前执行&#xff0c;除了#include&#xff0c;还有以下常用指令&#xff1a;1. #define 宏定义无参宏&#xff1a;定义常量或代码片段&#xff0c;编译时直接替换&#xff08;无类型检查&#xff09;。#define PI 3.1415926 // 定义常量 #define…

数据结构之heap算法

文章目录前言1. heap结构概述2. push_heap3. pop_heap4. sort_heap5. make_heap前言 heap这种数据结构&#xff0c;允许用户以任何次序将任何数据放入该结构中&#xff0c;但是最后取出数据的时候一定是权值最高&#xff08;或者最低&#xff09;的元素。主要和实现有关&#x…

MCU 软件断点调试注意事项!!!

——为什么调试器会在运行中改我的Flash程序&#xff1f;调试单片机时&#xff0c;很多人都有这样的疑问&#xff1a;明明我在调试前刷进去的固件是好的&#xff0c;为什么加了一个断点之后&#xff0c;调试器居然去改了 Flash&#xff1f; 如果我拔掉调试器&#xff0c;这个固…

启发式合并 + 莫队 恋恋的心跳大冒险

题目来源&#xff1a;2025 Wuhan University of Technology Programming Contest 比赛链接&#xff1a;Dashboard - 2025 Wuhan University of Technology Programming Contest - Codeforces 题目大意&#xff1a; Solution&#xff1a; 首先肯定要预处理出以每个节点为起点…

JCTools 无锁并发队列基础:ConcurrentCircularArrayQueue

ConcurrentCircularArrayQueue ConcurrentCircularArrayQueue 是一个抽象类&#xff0c;它为基于数组的并发循环队列提供了基础功能。从其命名可以看出几个关键特性&#xff1a;​​Concurrent​​&#xff1a;常指无锁并发。​​Circular Array​​&#xff1a;内部使用循环数…

力扣(LeetCode) ——622. 设计循环队列(C语言)

题目&#xff1a;622. 设计循环队列示例1&#xff1a; MyCircularQueue circularQueue new MyCircularQueue(3); // 设置长度为 3 circularQueue.enQueue(1); // 返回 true circularQueue.enQueue(2); // 返回 true circularQueue.enQueue(3); // 返回 true circularQueue.…

在JVM跑JavaScript脚本 | Oracle GraalJS 简介与实践

这是2024年初的 GraalVM 系列博文&#xff0c;当时写了大纲&#xff0c;知道一年半后的现在才得以完成发布&#x1f604; 1、概述 实话说&#xff0c;标题的场景为小众需求&#xff0c;日常开发基本用不到&#xff0c;我是最近在做一个低代码轮子玩具 app-meta 需要实现 FaaS&…

基于 EC 数据与大模型技术实现天气预报:从数据到上线的全栈方法

1. 先校准“EC 数据”与“AI 预报”的语境 EC 数据家族(常用) IFS/HRES:确定性全球模式,水平分辨率约 9 km,常用预报范围 10 天; IFS/ENS:51 成员集合预报,提供 15 天概率信息; ERA5:再分析数据,小时级、0.25,可追溯至 1940 年,用作训练/评测黄金基准。 AI 预报…

迭代器模式及优化

迭代器模式&#xff08;Iterator Pattern&#xff09;是一种行为型设计模式&#xff0c;用于提供一种统一的方式遍历聚合对象&#xff08;如集合、容器&#xff09;中的元素&#xff0c;而无需暴露对象的内部实现细节。它将遍历逻辑与聚合对象分离&#xff0c;使得遍历操作可以…

纯Qt手撕gb28181协议/gb28181协议服务端/gb28181协议设备端/gb28181设备模拟器/gb28181虚拟监控设备

一、前言说明 搞完onvif设备模拟器&#xff0c;总想着把28181设备模拟也实现&#xff0c;因为之前已经花了大力气把28181平台软件端实现了&#xff0c;为了实现这个组件&#xff0c;头发掉了一大把&#xff0c;专门把国标文档看了好几遍&#xff0c;逐行阅读&#xff0c;针对需…

【渗透实战】无下载器环境(curl/wget)下玩转 Metasploit 自动利用

1. 背景与问题场景 在渗透测试或漏洞利用中&#xff0c;Metasploit&#xff08;MSF&#xff09;是业界最常用的框架之一。 其许多 RCE&#xff08;远程代码执行&#xff09;模块在落地 payload&#xff08;如 Meterpreter 或反弹 shell&#xff09;时&#xff0c;采用了 CMD St…

jd-hotkey探测热点key

对任意突发性的无法预先感知的热点数据&#xff0c;包括并不限于热点数据&#xff08;如突发大量请求同一个商品&#xff09;、热用户&#xff08;如恶意爬虫刷子&#xff09;、热接口&#xff08;突发海量请求同一个接口&#xff09;等&#xff0c;进行毫秒级精准探测到。然后…

C#WPF实战出真汁07--【系统设置】--菜品类型设置

1、菜品设置介绍 菜品设置跟餐桌设置的功能目的是相同的&#xff0c;包括了新增&#xff0c;删除&#xff0c;编辑&#xff0c;分页&#xff0c;查询&#xff0c;重置&#xff0c;全选&#xff0c;全消&#xff0c;列表功能&#xff0c;实现流程也是布局设计&#xff0c;后台逻…

aave v3 存款与借款利息的计算方式

本文只涉及到利率计算的数学原理&#xff0c;不作源码解析:存款首先我们假设小明在aave里面存了10000usdt&#xff0c;存的时候年化收益率是5%,那么半年后其存款的利息是多少呢?常规的计算方式如下:利息10000*5%*(存款的时长/一年的时长)这么做有什么问题呢&#xff1f;假设现…