Flink 窗口触发器(Trigger)(二)
Flink 窗口触发器(Trigger)(一)
Flink 窗口触发器(Trigger)(二)
Apache Flink 是一个开源流处理框架,用于处理无界和有界数据流。在 Flink 的时间窗口操作中,触发器(Trigger)是一个非常重要的概念,它决定了窗口何时应该被计算并输出结果。触发器定义了窗口何时准备好被处理(即何时触发计算)的条件。
窗口类型
- 时间窗口(Time Windows):基于时间划分的窗口,如滚动时间窗口(Tumbling Time Windows)和滑动时间窗口(Sliding Time Windows)。
- 事件时间窗口(Event Time Windows):基于事件时间戳的窗口,它可以处理乱序数据。
Trigger
触发器用于定义窗口何时准备好进行计算的条件。Flink 提供了一些内置的触发器,同时允许用户根据需要自定义触发器。
内置触发器
- ProcessingTimeTrigger:基于处理时间的触发器,每当达到指定的时间间隔时触发。
- EventTimeTrigger:基于事件时间的触发器,当窗口的结束时间到达时触发。这适用于处理有序或乱序的事件时间数据流。
- CountTrigger:基于元素数量的触发器,当窗口中的元素数量达到指定阈值时触发。
自定义触发器
用户可以通过实现 Trigger 接口来创建自定义触发器。自定义触发器可以基于复杂的逻辑来决定何时触发窗口的计算。自定义触发器通常需要实现以下几个方法:
- onElement(element, timestamp, window, ctx): 当元素被添加到窗口时调用。
- onEventTime(time, window, ctx, out): 当窗口的事件时间到达时调用。
- onProcessingTime(time, window, ctx, out): 当窗口的处理时间到达时调用。
- onMerge(other): 当两个窗口合并时调用(例如,在会话窗口中使用)。
- canMerge(): 表示触发器是否支持窗口合并。
作用
- 触发器的主要作用是控制窗口的计算时机,使得 Flink 的窗口操作更加灵活和强大。通过选择合适的触发器,可以优化流处理应用的性能和资源利用率。
示例
以下是一个使用 Flink 窗口和触发器的简单示例(假设使用 Java API):
DataStream<Tuple2<String, Integer>> dataStream = ...; dataStream .keyBy(value -> value.f0) .window(TumblingEventTimeWindows.of(Time.seconds(10))) .trigger(ContinuousEventTimeTrigger.of(Time.seconds(5))) // 自定义触发间隔 .sum(1) .print();
在这个示例中,使用了基于事件时间的滚动窗口,但自定义了触发间隔为 5 秒,这意味着每 5 秒,即使窗口没有结束,也会触发一次计算。
注意:ContinuousEventTimeTrigger 并不是 Flink 的一个内置触发器,这里只是为了说明如何可能自定义触发器行为。实际上,可能需要实现自己的 Trigger 逻辑或使用现有的内置触发器。
触发器
EventTimeTrigger
EventTimeTrigger 是一个基于事件时间的触发器,它通常用于事件时间窗口(如滚动时间窗口、滑动时间窗口或会话窗口)。当窗口的结束时间(对于滚动窗口和滑动窗口)或窗口的“活动”结束时间(对于会话窗口)根据事件时间戳到达时,EventTimeTrigger 会触发窗口的计算。
下面是一个使用 TumblingEventTimeWindows 的示例,它隐式地使用了事件时间触发器:
DataStream<Tuple2<String, Integer>> input = ...; // 输入数据流 // 假设已经设置了TimeCharacteristic为EventTime,并且数据流中的元素有事件时间戳
input .assignTimestampsAndWatermarks(...) // 设置时间戳和水印 .keyBy(value -> value.f0) // 根据键进行分组 .window(TumblingEventTimeWindows.of(Time.seconds(10))) // 定义10秒滚动事件时间窗口 .sum(1) // 对窗口内的元素进行求和 .print(); // 输出结果
TumblingEventTimeWindows.of(Time.seconds(10)) 创建了一个 10 秒的滚动事件时间窗口。由于我们使用了事件时间窗口,Flink 会自动使用基于事件时间的触发逻辑来触发窗口的计算。当窗口的结束时间(基于事件时间戳)到达时,窗口会被计算并输出结果。
ProcessingTimeTrigger
ProcessingTimeTrigger 是一种基于处理时间(Processing Time)的触发器。处理时间是指事件被 Flink 系统处理的时间,即事件到达 Flink 算子并被处理的时间。由于处理时间是由 Flink 系统的内部时钟决定的,因此它不受事件本身时间戳的影响,也不依赖于任何外部时间服务。
用途:
ProcessingTimeTrigger 通常用于那些对实时性要求很高,但不需要严格事件时间语义的场景。例如,可能希望每秒计算一次窗口内的数据聚合,而不关心事件的实际发生时间。
在 Flink 中,可以通过指定窗口的触发器来使用 ProcessingTimeTrigger。以下是一个简单的示例,展示了如何为 Flink DataStream API 中的时间窗口指定 ProcessingTimeTrigger:
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.windowing.assigners.TumblingProcessingTimeWindows;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.streaming.api.windowing.triggers.ProcessingTimeTrigger; DataStream<Tuple2<String, Long>> input = ...; // 你的输入数据流 // 使用 ProcessingTimeTrigger 定义一个每秒触发的滚动窗口
DataStream<Tuple2<String, Long>> result = input .keyBy(0) // 假设第一个字段是键 .window(TumblingProcessingTimeWindows.of(Time.seconds(1))) // 指定窗口大小 .trigger(ProcessingTimeTrigger.create()) // 使用 ProcessingTimeTrigger .sum(1); // 对第二个字段(假设是 Long 类型)进行求和 // 输出结果
result.print();
在这个例子中,没有显式地调用 .trigger(ProcessingTimeTrigger.create()),因为 TumblingProcessingTimeWindows 已经默认使用了 ProcessingTimeTrigger。但是,了解如何显式地指定触发器是有用的,特别是在需要自定义触发器行为时。
注意事项
- 使用处理时间时,请注意 Flink 集群内部时钟的同步问题。虽然 Flink 在大多数情况下能够很好地处理时钟不同步的问题,但在某些极端情况下,时钟差异可能会影响处理时间的准确性。
- 处理时间不会考虑事件的实际时间戳,因此它不适合需要严格时间顺序或事件时间语义的场景。
CountTrigger
CountTrigger 是一种基于数据量的触发器,它根据窗口内收集到的元素数量来决定是否触发窗口的计算。当窗口内的元素数量达到预设的阈值时,CountTrigger 会触发窗口的计算操作。
工作原理:
CountTrigger 内部通常使用一个计数器来跟踪窗口内元素的数量。每当有元素被添加到窗口中时,计数器就会增加。一旦计数器的值达到或超过预设的阈值,CountTrigger 就会触发窗口的计算,并可以选择性地清除窗口内的数据或状态,以便进行下一轮的计算。
使用:
在 Flink 的 DataStream API 中,可以通过调用窗口操作的 .trigger() 方法来指定 CountTrigger。但是,需要注意的是,Flink 的内置 API 可能并不直接提供一个名为 CountTrigger 的类(尽管存在类似的功能),但可以通过自定义触发器或使用 Flink 提供的窗口分配器和触发器组合来达到类似的效果。
然而,Flink 的 CountWindow 默认就是基于计数触发的,不需要显式地指定 CountTrigger。但如果想要更细粒度的控制,比如与其他类型的触发器(如时间触发器)结合使用,可能需要自定义触发器或查找 Flink 社区提供的扩展库。
以下是一个假设性的示例,展示了如何在 Flink 中使用类似于 CountTrigger 的逻辑(注意:这并非 Flink API 的直接调用方式,而是为了说明概念):
// 假设 Flink API 提供了类似的方法,但实际上可能需要自定义或查找扩展库
DataStream<Tuple2<String, Integer>> input = ...; // 输入数据流 // 使用一个假设的 countWindow 方法,它内部可能使用了 CountTrigger
DataStream<Integer> sum = input .keyBy(0) // 假设第一个字段是键 .countWindow(10) // 假设这是一个接受计数阈值的窗口方法 .sum(1); // 对第二个字段进行求和 sum.print(); // 输出结果
然而,在 Flink 的实际 API 中,可能会使用类似 countWindow(Time.seconds(x)) 的方法来定义一个固定时间间隔内的计数窗口,但这并不是基于元素数量的直接触发。如果需要基于元素数量的触发,可能需要使用 GlobalWindows 并结合自定义触发器,或者简单地使用 countWindow(如果 Flink 版本中直接支持该方法)并接受它默认的计数触发行为。
ContinuousEventTimeTrigger
根据间隔时间周期性触发窗口或者当 Window 的结束时间小于当前的 watermark 时触发窗口计算。
ContinuousEventTimeTrigger.of(Duration.ofSeconds(3))
ContinuousProcessingTimeTrigger
ContinuousProcessingTimeTrigger 是一种基于处理时间的触发器,它允许根据设定的时间间隔周期性地触发窗口计算,而不仅仅是在窗口结束时触发。这种触发器特别适用于需要更频繁地获取窗口内数据聚合结果的场景。
原理:
ContinuousProcessingTimeTrigger 通过在窗口内设置定时器来实现周期性触发。每当有新的元素到达窗口时,触发器会检查是否需要触发计算。如果需要,它会根据当前时间和设定的时间间隔来更新定时器,并在适当的时候触发窗口计算。
使用方法:
在Flink的DataStream API中,可以通过调用窗口操作的.trigger()方法,并传入ContinuousProcessingTimeTrigger.of(Time.seconds(interval))(其中interval是希望触发的时间间隔,以秒为单位)来指定ContinuousProcessingTimeTrigger。
以下是一个使用ContinuousProcessingTimeTrigger的示例代码片段(假设已经有了一个Flink环境env和一个数据流sourceStream):
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.windowing.assigners.TumblingProcessingTimeWindows;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.streaming.api.windowing.triggers.ContinuousProcessingTimeTrigger; DataStream<String> sourceStream = ...; // 输入数据流 // 使用ContinuousProcessingTimeTrigger定义一个每隔5秒触发的滚动处理时间窗口
DataStream<Tuple2<String, Long>> result = sourceStream .keyBy(value -> value.substring(0, 1)) // 假设按字符串的第一个字符分组 .window(TumblingProcessingTimeWindows.of(Time.seconds(30))) // 定义一个30秒的滚动窗口 .trigger(ContinuousProcessingTimeTrigger.of(Time.seconds(5))) // 每5秒触发一次 .aggregate(new MySumAggregationFunction()); // 使用自定义的聚合函数 // 输出结果
result.print();
**注意:**上面的代码示例是一个简化的表示,用于说明如何使用ContinuousProcessingTimeTrigger。在实际应用中,可能需要根据自己的需求调整窗口大小、分组键和聚合函数。
注意事项
- 使用ContinuousProcessingTimeTrigger时,请确保Flink集群时间同步良好,以避免因时间差异导致的触发问题。
- 触发间隔的设置应该根据具体需求和数据流的特点来确定。过短的间隔可能会导致过多的计算和资源消耗,而过长的间隔则可能无法满足实时性要求。
- Flink的API和功能可能会随着版本的更新而发生变化,因此建议查阅最新的Flink文档以获取准确的信息和示例。
DeltaTrigger
DeltaTrigger具有一个DeltaFunction,该函数的逻辑需要用户自己定义。该函数比较上一次触发计算的元素和目前到来的元素。比较结果为一个double类型阈值。如果阈值超过DeltaTrigger配置的阈值,会返回TriggerResult.FIRE
public TriggerResult onElement(T element, long timestamp, W window, TriggerContext ctx) throws Exception {// 获取上个元素的储存状态ValueState<T> lastElementState = ctx.getPartitionedState(stateDesc);// 确保存入第一个到来的元素if (lastElementState.value() == null) {lastElementState.update(element);return TriggerResult.CONTINUE;}if (deltaFunction.getDelta(lastElementState.value(), element) > this.threshold) {// 重点:只要触发条件满足的时候,才会更新lastElementState,使用新的element替代上一个elementlastElementState.update(element);// 触发计算return TriggerResult.FIRE;}return TriggerResult.CONTINUE;
}
PurgingTrigger
PurgingTrigger 是一种特殊的触发器,它主要用于在触发窗口计算后立即清除窗口中的所有数据,从而帮助释放内存资源。这种触发器通常与其他触发器结合使用,以便在窗口计算完成后立即清理数据。
原理:
PurgingTrigger 本身并不直接决定何时触发窗口计算,而是作为一个包装器(wrapper)或修饰符(modifier),将其他触发器(如 EventTimeTrigger、ProcessingTimeTrigger、CountTrigger 等)转换为具有清除功能的触发器。当被包装的触发器触发窗口计算时,PurgingTrigger 会执行该计算,并在计算完成后清除窗口中的数据。
使用:
在Flink中,可以通过调用 .trigger() 方法并传入 PurgingTrigger.of(…) 来使用 PurgingTrigger。其中,of(…) 方法的参数是想要包装的其他触发器实例。
例如,如果想要使用基于处理时间的滚动窗口,并在每个窗口计算完成后清除数据,可以这样做:
DataStream<...> input = ...; // 输入数据流 DataStream<...> result = input .keyBy(...) // 根据需要进行分组 .window(TumblingProcessingTimeWindows.of(Time.seconds(10))) // 定义一个10秒的滚动处理时间窗口 .trigger(PurgingTrigger.of(ProcessingTimeTrigger.create())) // 使用PurgingTrigger包装ProcessingTimeTrigger .aggregate(...); // 使用聚合函数进行计算 result.print(); // 输出结果
**注意:**上面的代码示例是一个简化的表示,用于说明如何使用 PurgingTrigger。在实际应用中,需要根据自己的需求调整窗口分配器、分组键和聚合函数。
注意事项
- PurgingTrigger 的主要作用是清除数据,以释放内存资源。因此,在使用它时,请确保这是期望的行为。
- 当使用 PurgingTrigger 包装其他触发器时,被包装的触发器的行为(即何时触发窗口计算)仍然有效。PurgingTrigger 只是在此基础上添加了清除数据的操作。
- Flink的API和功能可能会随着版本的更新而发生变化。因此,建议查阅最新的Flink文档以获取准确的信息和示例。
自定义触发器
在 Apache Flink 中,自定义触发器(Trigger)是用于定义如何在流处理中的窗口操作(如 Tumbling Windows, Sliding Windows, Session Windows 等)触发计算的。自定义触发器需要实现 Trigger 接口或继承 Trigger 的某个实现类(如 ContinuousProcessingTimeTrigger、ContinuousEventTimeTrigger 等)。
以下是一个自定义触发器的简单示例,该触发器将在每个窗口的最后一个元素到达时触发计算,并且如果窗口在一段时间内没有接收到新元素,则也会触发计算(类似于超时机制):
import org.apache.flink.streaming.api.windowing.assigners.WindowAssigner;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.streaming.api.windowing.triggers.Trigger;
import org.apache.flink.streaming.api.windowing.triggers.TriggerResult;
import org.apache.flink.streaming.api.windowing.windows.TimeWindow;
import org.apache.flink.util.Collector;public class CustomEventTimeTrigger<W extends WindowAssigner.Window> extends Trigger<Object, W> {private static final long serialVersionUID = 1L;// 定义超时时间(毫秒)private final long timeout;public CustomEventTimeTrigger(long timeout) {this.timeout = timeout;}@Overridepublic TriggerResult onElement(Object element, long timestamp, W window, TriggerContext ctx) throws Exception {// 在元素到达时,不做任何事情,因为我们将依赖 onProcessingTime 来触发return TriggerResult.CONTINUE;}@Overridepublic TriggerResult onProcessingTime(long time, W window, TriggerContext ctx) throws Exception {// 检查是否超时if (time - window.getEnd() >= timeout) {// 如果超时,则触发窗口return TriggerResult.FIRE_AND_PURGE;}return TriggerResult.CONTINUE;}@Overridepublic TriggerResult onEventTime(long time, W window, TriggerContext ctx) throws Exception {// 当窗口的最后一个元素到达时触发if (time >= window.getEnd()) {return TriggerResult.FIRE;}return TriggerResult.CONTINUE;}@Overridepublic TriggerResult onMerge(W window, OnMergeContext ctx) throws Exception {// 在窗口合并时调用,根据你的需要来处理// 通常这里可以返回 CONTINUE 或 FIRE_AND_PURGEreturn TriggerResult.CONTINUE;}@Overridepublic void clear(W window, TriggerContext ctx) throws Exception {// 清除窗口的上下文信息}
}
在这个示例中,CustomEventTimeTrigger 继承了 Trigger 接口,并重写了所需的方法。它使用了事件时间(onEventTime)和处理时间(onProcessingTime)来触发窗口。当窗口的最后一个元素到达时(onEventTime),或者当窗口在处理时间中超时(onProcessingTime)时,窗口会被触发。
要使用这个自定义触发器,可以在 Flink 的 DataStream API 中创建一个窗口分配器,并将其与自定义触发器一起使用:
DataStream<...> input = ...; // 输入流input.keyBy(...) // 按键分区.timeWindow(Time.seconds(10), new CustomEventTimeTrigger<>(Time.seconds(5))) // 使用自定义触发器.apply(...); // 窗口函数
在使用 Apache Flink 的 Trigger 时,需要注意以下几个事项:
- 理解Trigger的作用:
Trigger 决定了窗口中的数据何时可以被 window function 处理。每个窗口分配器(WindowAssigner)都有一个默认的触发器,但也可以根据需要指定一个自定义的触发器。- 触发器的类型:
Flink 提供了多种内置的触发器,如 EventTimeTrigger、ProcessingTimeTrigger、CountTrigger 等,它们分别基于事件时间、处理时间和元素数量来触发窗口计算。如果需要更复杂的触发逻辑,可以自定义 Trigger。- 返回值与操作:
触发器的几个关键方法(onElement, onEventTime, onProcessingTime)都返回一个 TriggerResult 对象,它决定了窗口数据的处理方式,如 CONTINUE(不执行任何操作)、FIRE(触发计算)、PURGE(清除窗口中的元素)、FIRE_AND_PURGE(触发计算并清除窗口中的元素)等。- 状态与合并:
当使用有状态的触发器(如 SessionWindow)时,需要注意窗口合并时的状态合并逻辑。这通常通过 onMerge 方法实现。- 清除操作:
clear 方法用于执行删除相应窗口所需的任何操作。但请注意,清除操作只会移除窗口的内容,而不会移除关于窗口的元信息(meta-information)和触发器的状态。- 时间属性:
触发器可以访问流的时间属性以及定时器,并可以对 state 状态进行编程。因此,在设计触发器时,需要明确流是基于事件时间(EventTime)还是处理时间(ProcessingTime)。- 自定义触发器的设计:
如果需要自定义触发器,需要仔细考虑触发逻辑。例如,可以根据窗口内的元素数量、特定的事件或时间间隔来触发窗口计算34。- 性能考虑:
触发器在 Flink 窗口处理中起着关键作用,因此其性能可能会影响整个作业的性能。在设计触发器时,需要考虑其执行效率和资源消耗。- 测试与验证:
在实际使用触发器之前,建议进行充分的测试和验证,以确保其符合预期并能在各种情况下正常工作。- 与Flink版本保持同步:
Flink 不断更新和改进其 API 和功能,因此建议查阅最新的 Flink 文档以获取关于 Trigger 的最新信息和最佳实践。
相关文章:
Flink 窗口触发器(Trigger)(二)
Flink 窗口触发器(Trigger)(一) Flink 窗口触发器(Trigger)(二) Apache Flink 是一个开源流处理框架,用于处理无界和有界数据流。在 Flink 的时间窗口操作中,触发器(Trigger)是一个非常重要的概念,它决定了窗口何时应…...
CH12_函数和事件
第12章:Javascript的函数和事件 本章目标 函数的概念掌握常用的系统函数掌握类型转换掌握Javascript的常用事件 课程回顾 Javascript中的循环有那些?Javascript中的各个循环特点是什么?Javascript中的各个循环语法分别是什么?…...
Android- Framework 非Root权限实现修改hosts
一、背景 修改system/etc/hosts,需要具备root权限,而且remount后,才能修改,本文介绍非root状态下修改system/etc/hosts方案。 环境:高通 Android 13 二、方案 非root,system/etc/hosts只有只读权限&…...
mac安装达梦数据库
参考:mac安装达梦数据库 实践如下: 1、下载达梦Docker镜像文件 同参考链接 2、导入镜像 镜像可以随便放在某个目录,相当于安装包,导入后就没有作用了。 查找达梦镜像名称:dm8_20240613_rev229704_x86…...
14-41 剑和诗人15 - RLAIF 大模型语言强化培训
介绍 大型语言模型 (LLM) 在自然语言理解和生成方面表现出了巨大的能力。然而,这些模型仍然存在严重的缺陷,例如输出不可靠、推理能力有限以及缺乏一致的个性或价值观一致性。 为了解决这些限制,研究人员采用了一种名为“人工…...
每日一题~oj(贪心)
对于位置 i来说,如果 不选她,那她的贡献是 vali-1 *2,如果选他 ,那么她的贡献是 ai. 每一个数的贡献 是基于前一个数的贡献 来计算的。只要保证这个数的前一个数的贡献是最优的,那么以此类推下去,整体的val…...
成人高考报名条件及收费标准详解
成人高考报名条件及收费标准详解 您想通过成人高考改变自己的命运,但不知道报名条件和收费标准?本文将为您详细介绍成人高考报名条件和收费标准,并为您提供专业的成人教育服务。 深圳成人高考www.shenzhixun.com 成人高考报名条件 成人高考…...
openmetadata1.3.1 自定义连接器 开发教程
openmetadata自定义连接器开发教程 一、开发通用自定义连接器教程 官网教程链接: 1.https://docs.open-metadata.org/v1.3.x/connectors/custom-connectors 2.https://github.com/open-metadata/openmetadata-demo/tree/main/custom-connector (一&…...
PostgreSQL 如何优化存储过程的执行效率?
文章目录 一、查询优化1. 正确使用索引2. 避免不必要的全表扫描3. 使用合适的连接方式4. 优化子查询 二、参数传递1. 避免传递大对象2. 参数类型匹配 三、减少数据量处理1. 限制返回结果集2. 提前筛选数据 四、优化逻辑结构1. 分解复杂的存储过程2. 避免过度使用游标 五、事务处…...
普中51单片机:数码管显示原理与实现详解(四)
文章目录 引言数码管的结构数码管的工作原理静态数码管电路图开发板IO连接图代码演示 动态数码管实现步骤数码管驱动方式电路图开发板IO连接图真值表代码演示1代码演示2代码演示3 引言 数码管(Seven-Segment Display)是一种常见的显示设备,广…...
web缓存代理服务器
一、web缓存代理 web代理的工作机制 代理服务器是一个位于客户端和原始(资源)服务器之间的服务器,为了从原始服务器取得内容,客户端向代理服务器发送一个请求,并指定目标原始服务器,然后代理服务器向原始…...
容器:queue(队列)
以下是关于queue容器的总结 1、构造函数:queue [queueName] 2、添加、删除元素: push() 、pop() 3、获取队头/队尾元素:front()、back() 4、获取栈的大小:size() 5、判断栈是否为空:empty() #include <iostream> #include …...
探索 WebKit 的后台同步新纪元:Web Periodic Background Synchronization 深度解析
探索 WebKit 的后台同步新纪元:Web Periodic Background Synchronization 深度解析 随着 Web 应用逐渐成为我们日常生活中不可或缺的一部分,用户对应用的响应速度和可靠性有了更高的期待。Web Periodic Background Synchronization API(周期…...
ctfshow web入门 web338--web344
web338 原型链污染 comman.js module.exports {copy:copy };function copy(object1, object2){for (let key in object2) {if (key in object2 && key in object1) {copy(object1[key], object2[key])} else {object1[key] object2[key]}}}login.js var express …...
mupdf加载PDF显示中文乱码
现象 加载PDF显示乱码,提示非嵌入字体 non-embedded font using identity encoding调式 在pdf-font.c中加载字体 调试源码发现pdf文档的字体名字居然是GBK,估计又是哪个windows下写的pdf生成工具生成pdf 字体方法: static pdf_font_desc * load_cid…...
常用的限流工具Guava RateLimiter 或Redisson RRateLimiter
在分布式系统和高并发场景中,限流是一个非常常见且重要的需求。以下是一些常用的限流工具和库,包括它们的特点和使用场景: 1. Guava RateLimiter Google 的 Guava 库中的 RateLimiter 是一个简单且高效的限流工具,适用于单节点应…...
卷积神经网络(CNN)和循环神经网络(RNN) 的区别与联系
卷积神经网络(CNN)和循环神经网络(RNN)是两种广泛应用于深度学习的神经网络架构,它们在设计理念和应用领域上有显著区别,但也存在一些联系。 ### 卷积神经网络(CNN) #### 主要特点…...
Unity【入门】场景切换和游戏退出及准备
1、必备知识点场景切换和游戏退出 文章目录 1、必备知识点场景切换和游戏退出1、场景切换2、鼠标隐藏锁定相关3、随机数和自带委托4、模型资源的导入1、模型由什么构成2、Unity支持的模型格式3、如何指导美术同学导出模型4、学习阶段在哪里获取模型资源 2、小项目准备工作需求分…...
Python 函数递归
以下是一个使用递归计算阶乘的 Python 函数示例 : 应用场景: 1. 动态规划问题:在一些需要逐步求解子问题并利用其结果的动态规划场景中,递归可以帮助直观地表达问题的分解和求解过程。 2. 遍历具有递归结构的数据:如递…...
MyBatis(27)如何配置 MyBatis 实现打印可执行的 SQL 语句
在开发过程中,打印可执行的SQL语句对于调试和性能优化是非常有帮助的。MyBatis提供了几种方式来实现SQL语句的打印。 1. 使用日志框架 MyBatis可以通过配置其内部使用的日志框架(如Log4j、Logback等)来打印SQL语句。这是最常用的方法。 Lo…...
3.js - 裁剪平面(clipIntersection:交集、并集)
看图 代码 // ts-nocheck// 引入three.js import * as THREE from three// 导入轨道控制器 import { OrbitControls } from three/examples/jsm/controls/OrbitControls// 导入lil.gui import { GUI } from three/examples/jsm/libs/lil-gui.module.min.js// 导入tween import …...
在5G/6G应用中实现高性能放大器的建模挑战
来源:Modelling Challenges for Enabling High Performance Amplifiers in 5G/6G Applications {第28届“集成电路和系统的混合设计”(Mixed Design of Integrated Circuits and Systems)国际会议论文集,2021年6月24日至26日,波兰洛迪} 本文讨…...
Perl 数据类型
Perl 数据类型 Perl 是一种功能丰富的编程语言,广泛应用于系统管理、网络编程、GUI 开发等领域。在 Perl 中,数据类型是编程的基础,决定了变量存储信息的方式以及可以对这些信息执行的操作。本文将详细介绍 Perl 中的主要数据类型࿰…...
网络协议 -- IP、ICMP、TCP、UDP字段解析
网络协议报文解析及工具使用介绍 1. 以太网帧格式及各字段作用 -------------------------------- | Destination MAC Address (48 bits) | -------------------------------- | Source MAC Address (48 bits) …...
【工具】豆瓣自动回贴软件
转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~ 相比于之前粗糙丑陋的黑命令框版本,这个版本新增了UI界面,从此可以不需要再挨个去翻配置文件了。 另外,升级了隐藏浏…...
初学Spring之动态代理模式
动态代理和静态代理角色一样 动态代理的代理类是动态生成的 动态代理分为两大类: 基于接口的动态代理(JDK 动态代理)、基于类的动态代理(cglib) 也可以用 Java 字节码实现(Javassist) Prox…...
Visual studio 2023下使用 installer projects 打包C#程序并创建 CustomAction 类
Visual studio 2023下使用 installer projects 打包C#程序并创建 CustomAction 类 1 安装Visual studio 20203,并安装插件1.1 下载并安装 Visual Studio1.2 步骤二:安装 installer projects 扩展插件2 创建安装项目2.1 创建Windows安装项目2.2 新建应用程序安装文件夹2.3 添加…...
vue学习笔记(购物车小案例)
用一个简单的购物车demo来回顾一下其中需要注意的细节。 先看一下最终效果 功能: (1)全选按钮和下面的商品项的选中状态同步,当下面的商品全部选中时,全选勾选,反之,则不勾选。 (…...
昇思25天学习打卡营第19天 | RNN实现情感分类
RNN实现情感分类 概述 情感分类是自然语言处理中的经典任务,是典型的分类问题。本节使用MindSpore实现一个基于RNN网络的情感分类模型,实现如下的效果: 输入: This film is terrible 正确标签: Negative 预测标签: Negative输入: This fil…...
【VUE基础】VUE3第三节—核心语法之ref标签、props
ref标签 作用:用于注册模板引用。 用在普通DOM标签上,获取的是DOM节点。 用在组件标签上,获取的是组件实例对象。 用在普通DOM标签上: <template><div class"person"><h1 ref"title1">…...
生物化学笔记:电阻抗基础+电化学阻抗谱EIS+电化学系统频率响应分析
视频教程地址 引言 方法介绍 稳定:撤去扰动会到原始状态,反之不稳定,还有近似稳定的 阻抗谱图形(Nyquist和Bode图) 阻抗谱图形是用于分析电化学系统和材料的工具,主要有两种类型:Nyquist图和B…...
SQL使用join查询方式找出没有分类的电影id以及名称
系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 描述 现有电影信息…...
对MsgPack与JSON进行序列化的效率比较
序列化是将对象转换为字节流的过程,以便在内存或磁盘上存储。常见的序列化方法包括MsgPack和JSON。以下将详细探讨MsgPack和JSON在序列化效率方面的差异。 1. MsgPack的效率: 优点: 高压缩率: MsgPack采用高效的二进制编码格式&…...
Unix\Linux 执行shell报错:“$‘\r‘: 未找到命令” 解决
linux执行脚本sh xxx.sh报错:$xxx\r: 未找到命令 原因:shell脚本在Windows编写导致的换行问题: Windows 的换行符号为 CRLF(\r\n),而 Unix\Linux 为 LF(\n)。 缩写全称ASCII转义说…...
动态路由--RIP配置(思科cisco)
一、简介 RIP协议(Routing Information Protocol,路由信息协议)是一种基于距离矢量的动态路由选择协议。 在RIP协议中,如果路由器A和网络B直接相连,那么路由器A到网络B的距离被定义为1跳。若从路由器A出发到达网络B需要…...
python - 函数 / 字典 / 集合
一.函数 形参和实参: >>> def MyFirstFunction(name): 函数定义过程中的name是叫形参 ... print(传递进来的 name 叫做实参,因为Ta是具体的参数值!) print前面要加缩进tab,否则会出错。 >>> MyFirstFun…...
connect to github中personal access token生成token方法
一、问题 执行git push时弹出以下提示框 二、解决方法 去github官网生成Token,步骤如下 选择要授予此 令牌token 的 范围 或 权限 要使用 token 从命令行访问仓库,请选择 repo 。 要使用 token 从命令行删除仓库,请选择 delete_repo 其他根…...
Appium启动APP时报错Security exception: Permission Denial
报错内容Security exception: Permission Denial: starting Intent 直接通过am命令尝试也是同样的报错 查阅资料了解到:android:exported | App quality | Android Developers exported属性默认false,所以android:exported"false"修改为t…...
ubuntu22 使用ufw防火墙
专栏总目录 一、安装 sudo apt update sudo apt install ufw 二、启动防火墙 (一)启动命令 sudo ufw enable (二)重启命令 sudo ufw reload 三、配置规则 #允许SSH连接 sudo ufw allow ssh #如果sshd服务端口指定到了8888&a…...
初识STM32:开发方式及环境
STM32的编程模型 假如使用C语言的方式写了一段程序,这段程序首先会被烧录到芯片当中(Flash存储器中),Flash存储器中的程序会逐条的进入CPU里面去执行。 CPU相当于人的一个大脑,虽然能执行运算和执行指令,…...
详解Amivest 流动性比率
详解Amivest 流动性比率 Claude-3.5-Sonnet Poe Amivest流动性比率是一个衡量证券市场流动性的重要指标。这个比率主要用于评估在不对价格造成重大影响的情况下,市场能够吸收多少交易量。以下是对Amivest流动性比率的详细解释: 定义: Amivest流动性比率是交易额与绝对收益率的…...
pycharm小游戏制作
以下是一个使用 Python 和 PyGame库在 PyCharm中创建一个简单的小游戏(贪吃蛇游戏)的示例代码,希望对您有所帮助: import pygame import random# 基础设置 # 屏幕高度 SCREEN_HEIGHT 480 # 屏幕宽度 SCREEN_WIDTH 600 # 小方格…...
昇思11天
基于 MindSpore 实现 BERT 对话情绪识别 BERT模型概述 BERT(Bidirectional Encoder Representations from Transformers)是由Google于2018年开发并发布的一种新型语言模型。BERT在许多自然语言处理(NLP)任务中发挥着重要作用&am…...
AI绘画Stable Diffusion【图生图教程】:图片高清修复的三种方案详解,你一定能用上!(附资料)
大家好,我是画画的小强 今天给大家分享一下用AI绘画Stable Diffusion 进行 高清修复(Hi-Res Fix),这是用于提升图像分辨率和细节的技术。在生成图像时,初始的低分辨率图像会通过放大算法和细节增强技术被转换为高分辨…...
适用于Mac和Windows的最佳iPhone恢复软件
本文将指导您选择一款出色的iPhone数据恢复软件来检索您的宝贵数据。 市场上有许多所谓的iPhone恢复程序。各种程序很难选择并选择其中之一。一旦您做出了错误的选择,您的数据就会有风险。 最好的iPhone数据恢复软件应包含以下功能。 1.安全可靠。 2.恢复成功率高…...
64.ThreadLocal造成的内存泄漏
内存泄漏 程序中已动态分配的堆内存,由于某种原因程序为释放和无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。内存泄漏的堆积终将导致内存溢出。 内存溢出 没有足够的内存提供申请者使用。 ThreadLocal出现内存泄漏的真实原因 内存泄漏的发…...
深入刨析Redis存储技术设计艺术(二)
三、Redis主存储 3.1、存储相关结构体 redisServer:服务器 server.h struct redisServer { /* General */ pid_t pid; /* Main process pid. */ pthread_t main_thread_id; /* Main thread id */ char *configfile; /* Absolut…...
python读取写入txt文本文件
读取 txt 文件 def read_txt_file(file_path):"""读取文本文件的内容:param file_path: 文本文件的路径:return: 文件内容"""try:with open(file_path, r, encodingutf-8) as file:content file.read()return contentexcept FileNotFoundError…...
日期选取限制日期范围antdesign vue
限制选取的日期范围 效果图 <a-date-pickerv-model"dateTime"format"YYYY-MM-DD":disabled-date"disabledDate"valueFormat"YYYY-MM-DD"placeholder"请选择日期"allowClear />methods:{//回放日期选取范围限制&…...
【大模型】衡量巨兽:解读评估LLM性能的关键技术指标
衡量巨兽:解读评估LLM性能的关键技术指标 引言一、困惑度:语言模型的试金石1.1 定义与原理1.2 计算公式1.3 应用与意义 二、BLEU 分数:翻译质量的标尺2.1 定义与原理2.2 计算方法2.3 应用与意义 三、其他评估指标:综合考量下的多元…...