当前位置: 首页 > news >正文

Flink的窗口机制

窗口机制

  • tumble(滚动窗口)

  • hop(滑动窗口)

  • session(会话窗口)

  • cumulate(渐进式窗口)

  • Over(聚合窗口)

滚动窗口(tumble)

概念

滚动窗口 (tumble): 窗口大小 = 滑动距离。

它的窗口是紧密排布的,中间没有任何的数据重复和丢失。

案例 - SQL

--创建表
CREATE TABLE source_table ( user_id STRING, price BIGINT,`timestamp` bigint,row_time AS TO_TIMESTAMP(FROM_UNIXTIME(`timestamp`)),watermark for row_time as row_time - interval '0' second
) WITH ('connector' = 'socket','hostname' = 'node1',        'port' = '9999','format' = 'csv'
);--语法
tumble(row_time,时间间隔),比如,如下的sql
tumble(row_time,interval '5' second),每隔5秒滚动一次。--业务查询逻辑(传统方式)
select 
user_id,
count(*) as pv,
sum(price) as sum_price,
UNIX_TIMESTAMP(CAST(tumble_start(row_time, interval '5' second) AS STRING)) * 1000  as window_start,
UNIX_TIMESTAMP(CAST(tumble_end(row_time, interval '5' second) AS STRING)) * 1000  as window_end
from source_table
group byuser_id,tumble(row_time, interval '5' second);

运行结果如下:

案例 - DataStream API

package day04;import org.apache.flink.api.common.eventtime.SerializableTimestampAssigner;
import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.common.typeinfo.Types;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.api.java.tuple.Tuple3;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.KeyedStream;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.datastream.WindowedStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.windowing.assigners.TumblingEventTimeWindows;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.streaming.api.windowing.windows.TimeWindow;/*** @desc: 演示基于事件时间的滚动窗口。* 从socket数据源中接收数据(id,price,ts)*/
public class Demo01_TumbleWindow {public static void main(String[] args) throws Exception {//1.创建流式执行环境StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();env.setParallelism(1);//2.数据源DataStreamSource<String> source = env.socketTextStream("node1", 9999);//3.数据处理//3.1 数据切分,转成Tuple3//3.2 分配窗口/*** WatermarkStrategy的策略有四种:* forMonotonousTimestamps,单调递增水印* forBoundedOutOfOrderness,允许乱序数据(数据迟到)的水印* forGenerator,自定义水印* noWatermarks,没有水印*/SingleOutputStreamOperator<Tuple3<String, Integer, Long>> mapAndWatermarkStream = source.map(new MapFunction<String, Tuple3<String, Integer, Long>>() {@Overridepublic Tuple3<String, Integer, Long> map(String value) throws Exception {String[] lines = value.split(",");/*** lines分为3个字段:String id,Integer price,Long ts*/return Tuple3.of(lines[0], Integer.valueOf(lines[1]), Long.parseLong(lines[2]));}}).assignTimestampsAndWatermarks(WatermarkStrategy.<Tuple3<String, Integer, Long>>forMonotonousTimestamps().withTimestampAssigner(new SerializableTimestampAssigner<Tuple3<String, Integer, Long>>() {@Overridepublic long extractTimestamp(Tuple3<String, Integer, Long> element, long recordTimestamp) {//这个方法就是用来标识(标记)哪个列是用来表示时间戳的return element.f2 * 1000L;}}));mapAndWatermarkStream.print("源数据:");//3.3 根据id进行分组KeyedStream<Tuple3<String, Integer, Long>, String> keyedStream = mapAndWatermarkStream.keyBy(value -> value.f0);//3.4分组后,进行窗口划分//3.5 划分窗口后,对窗口内的数据进行sum//3.6为了显示的友好性,我们对Tuple3<String,Integer,Long>进行转换成Tuple2<String,Integer>SingleOutputStreamOperator<Tuple2<String, Integer>> result = keyedStream.window(TumblingEventTimeWindows.of(Time.seconds(5))).sum(1).map(value -> Tuple2.of(value.f0, value.f1)).returns(Types.TUPLE(Types.STRING, Types.INT));//4.数据输出result.printToErr("聚合后的数据:");//5.启动流式任务env.execute();}
}

运行结果如下:

SQL案例TVF写法

--语法,跟3个参数:
--参数1:表名
--参数2:表中事件时间列
--参数3:窗口大小
from table(tumble(table source,descriptor(row_time),interval '5' second))--业务逻辑
SELECT user_id,UNIX_TIMESTAMP(CAST(window_start AS STRING)) * 1000 as window_start,UNIX_TIMESTAMP(CAST(window_end AS STRING)) * 1000 as window_end,sum(price) as sum_price
FROM TABLE(TUMBLE(TABLE source_table, DESCRIPTOR(row_time), INTERVAL '5' SECOND))
GROUP BY window_start, window_end,user_id;
--window_start,window_end是新写法的关键字--对照前面的方式:
select 
user_id,
count(*) as pv,
sum(price) as sum_price,
UNIX_TIMESTAMP(CAST(tumble_start(row_time, interval '5' second) AS STRING)) * 1000  as window_start,
UNIX_TIMESTAMP(CAST(tumble_end(row_time, interval '5' second) AS STRING)) * 1000  as window_end
from source_table
group byuser_id,tumble(row_time, interval '5' second);

运行结果如下:

滑动窗口(hop)

概念

滑动窗口 :滑动距离 不等于 窗口大小。

(1)如果滑动距离小于窗口大小,则会产生数据重复

(2)如果滑动距离等于窗口大小,这就是滚动窗口

(3)如果滑动距离大于窗口大小,则会产生数据丢失(不考虑)

案例 - SQL

--创建表
CREATE TABLE source_table ( user_id STRING, price BIGINT,`timestamp` bigint,row_time AS TO_TIMESTAMP(FROM_UNIXTIME(`timestamp`)),watermark for row_time as row_time - interval '0' second
) WITH ('connector' = 'socket','hostname' = 'node1',        'port' = '9999','format' = 'csv'
);--语法
hop(事件时间列,滑动间隔,窗口大小)
hop(row_time,interval '2' second, interval '5' second)--业务SQL
SELECT user_id,
UNIX_TIMESTAMP(CAST(hop_start(row_time, interval '2' SECOND, interval '5' SECOND) AS STRING)) * 1000 as window_start,
UNIX_TIMESTAMP(CAST(hop_end(row_time, interval '2' SECOND, interval '5' SECOND) AS STRING)) * 1000 as window_end, sum(price) as sum_price
FROM source_table
GROUP BY user_id, hop(row_time, interval '2' SECOND, interval '5' SECOND);--每隔两秒滑动一次

 运行结果如下:

SQL案例TVF写法

--语法
--table:表名
--descriptor:事件时间列
--滑动距离:interval 2 second
--窗口大小:interval 5 second
from table(hop(table 表名,descriptor(事件时间列),滑动间隔,窗口大小))
from table(hop(table source,descriptor(row_time),interval '2' second,interval '5' second))--业务SQL
SELECT user_id,
UNIX_TIMESTAMP(CAST(window_start AS STRING)) * 1000 as window_start,  
UNIX_TIMESTAMP(CAST(window_end AS STRING)) * 1000 as window_end, sum(price) as sum_price
FROM TABLE(HOP(TABLE source_table, DESCRIPTOR(row_time), interval '2' SECOND, interval '6' SECOND))
GROUP BY window_start, window_end,user_id;

 运行结果如下:

案例 - DataStream API

package day04;import org.apache.flink.api.common.eventtime.SerializableTimestampAssigner;
import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import org.apache.flink.api.common.typeinfo.Types;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.api.java.tuple.Tuple3;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.windowing.assigners.SlidingEventTimeWindows;
import org.apache.flink.streaming.api.windowing.time.Time;/*** @desc: 演示基于事件时间的滑动窗口。* 从socket数据源中接收数据(id,price,ts)*/
public class Demo02_SlideWindow {public static void main(String[] args) throws Exception {//1.创建流式执行环境StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();env.setParallelism(1);//2.数据源DataStreamSource<String> source = env.socketTextStream("node1", 9999);//3.数据处理//3.1数据map转换操作,转成Tuple3SingleOutputStreamOperator<Tuple3<String, Integer, Long>> mapStream = source.map(value -> {/*** 由一行数据中,用逗号进行切分【id,price,ts】* String id* Integer price* Long ts*/String[] lines = value.split(",");return Tuple3.of(lines[0], Integer.valueOf(lines[1]), Long.parseLong(lines[2]));}).returns(Types.TUPLE(Types.STRING, Types.INT, Types.LONG));//3.2把Tuple3的数据添加Watermark(monotonousTimestamps)/*** WatermarkStrategy生成水印的策略有四种:* forMonotonousTimestamps,单调递增水印(用的次多)* forBoundedOutOfOrderness,运行数据迟到(乱序)(用的最多)* forGeneric,自定义水印(不用)* noWatermark,没有水印(不用)*/SingleOutputStreamOperator<Tuple3<String, Integer, Long>> watermarks = mapStream.assignTimestampsAndWatermarks(WatermarkStrategy.<Tuple3<String, Integer, Long>>forMonotonousTimestamps().withTimestampAssigner(new SerializableTimestampAssigner<Tuple3<String, Integer, Long>>() {@Overridepublic long extractTimestamp(Tuple3<String, Integer, Long> element, long recordTimestamp) {return element.f2 * 1000L;}}));//3.3把数据根据id进行分组watermarks.print("源数据:");SingleOutputStreamOperator<Tuple3<String, Integer, Long>> sumStream = watermarks.keyBy(value -> value.f0)//3.4分组之后,设置滑动事件时间窗口,并且制定窗口大小为5秒钟,滑动间隔为2秒。/*** SlidingEventTimeWindows,滑动事件时间窗口,带2个参数:* 参数1:窗口大小* 参数2:滑动间隔*/.window(SlidingEventTimeWindows.of(Time.seconds(5), Time.seconds(2)))//3.5对窗口内的数据进行sum操作.sum(1);//3.6把Tuple3转成了Tuple2(取id和sum的值)SingleOutputStreamOperator<Tuple2<String, Integer>> result = sumStream.map(value -> Tuple2.of(value.f0, value.f1)).returns(Types.TUPLE(Types.STRING,Types.INT));//4.数据输出result.printToErr("聚合后的数据:");//5.启动流式任务env.execute();}
}

运行结果如下:

会话窗口(session)

概念

会话窗口:在一个会话周期内,窗口的数据会累积,超过会话周期就会触发窗口的计算,同时开辟下一个新窗口。

注意:

数据本身的事件时间大于窗口间隔,才会触发当前窗口的计算。

案例 - SQL

--创建表
CREATE TABLE source_table ( user_id STRING, price BIGINT,`timestamp` bigint,row_time AS TO_TIMESTAMP(FROM_UNIXTIME(`timestamp`)),watermark for row_time as row_time - interval '0' second
) WITH ('connector' = 'socket','hostname' = 'node1',        'port' = '9999','format' = 'csv'
);--语法
session(事件时间列,窗口间隔)
session(row_time,interval '5' second)--业务SQL
SELECT user_id,
UNIX_TIMESTAMP(CAST(session_start(row_time, interval '5' SECOND) AS STRING)) * 1000 as window_start,
UNIX_TIMESTAMP(CAST(session_end(row_time, interval '5' SECOND) AS STRING)) * 1000 as window_end, sum(price) as sum_price
FROM source_table
GROUP BY user_id, session(row_time, interval '5' SECOND);

运行结果如下:

案例 - DataStream API

package day04;import org.apache.flink.api.common.eventtime.SerializableTimestampAssigner;
import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.common.typeinfo.Types;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.api.java.tuple.Tuple3;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.windowing.assigners.EventTimeSessionWindows;
import org.apache.flink.streaming.api.windowing.time.Time;/*** @desc: 演示基于事件时间的会话窗口。* 从socket数据源中接收数据(id,price,ts)*/
public class Demo03_SessionWindow {public static void main(String[] args) throws Exception {//1.创建流式执行环境StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();env.setParallelism(1);//2.数据源DataStreamSource<String> source = env.socketTextStream("node1", 9999);//3.数据处理//3.1数据map转换操作,转成Tuple3SingleOutputStreamOperator<Tuple3<String, Integer, Long>> mapStream = source.map(new MapFunction<String, Tuple3<String, Integer, Long>>() {@Overridepublic Tuple3<String, Integer, Long> map(String value) throws Exception {/*** String id* Integer price* Long ts*/String[] lines = value.split(",");return Tuple3.of(lines[0], Integer.valueOf(lines[1]), Long.parseLong(lines[2]));}});//3.2把Tuple3的数据添加Watermark(monotonousTimestamps)SingleOutputStreamOperator<Tuple3<String, Integer, Long>> watermarks = mapStream.assignTimestampsAndWatermarks(WatermarkStrategy.<Tuple3<String, Integer, Long>>forMonotonousTimestamps().withTimestampAssigner(new SerializableTimestampAssigner<Tuple3<String, Integer, Long>>() {@Overridepublic long extractTimestamp(Tuple3<String, Integer, Long> element, long recordTimestamp) {return element.f2 * 1000L;}}));watermarks.print("源数据:");//3.3把数据根据id进行分组//3.4分组之后,设置会话事件时间窗口,并且指定窗口间隔为5秒钟。//3.5对窗口内的数据进行sum操作SingleOutputStreamOperator<Tuple3<String, Integer, Long>> sumStream = watermarks.keyBy(value -> value.f0).window(EventTimeSessionWindows.withGap(Time.seconds(5))).sum(1);//3.6把Tuple3转成了Tuple2(取id和sum的值)SingleOutputStreamOperator<Tuple2<String, Integer>> result = sumStream.map(value -> Tuple2.of(value.f0, value.f1)).returns(Types.TUPLE(Types.STRING, Types.INT));//4.数据输出result.printToErr("聚合后的结果:");//5.启动流式任务env.execute();}
}

运行结果如下:

 渐进式窗口(cumulate)

概念

渐进式窗口:在固定时间内,结果是单调递增的。比如周期性累计求某些指标。

如下图所示:

案例 -TVF方式

 

--语法
--1.source:表名
--2.事件时间列
--3.时间间隔,每隔多久把窗口内的数据统计一次
--4.窗口大小,窗口的时间长度
from table(cumulate(table source,descriptor(事件时间列),时间间隔,窗口大小))--建表
CREATE TABLE source_table (-- 用户 iduser_id BIGINT,-- 用户money BIGINT,-- 事件时间戳row_time AS cast(CURRENT_TIMESTAMP as timestamp(3)),-- watermark 设置WATERMARK FOR row_time AS row_time - INTERVAL '0' SECOND
) WITH ('connector' = 'datagen','rows-per-second' = '10','fields.user_id.min' = '1','fields.user_id.max' = '100000','fields.money.min' = '1','fields.money.max' = '100000'
);--业务SQL
SELECT 
FROM_UNIXTIME(UNIX_TIMESTAMP(CAST(window_start AS STRING)))  as window_start,FROM_UNIXTIME(UNIX_TIMESTAMP(CAST(window_end AS STRING))) as window_end, sum(money) as sum_money,count(distinct user_id) as count_distinct_id
FROM TABLE(CUMULATE(TABLE source_table, DESCRIPTOR(row_time), INTERVAL '5' SECOND, INTERVAL '30' SECOND))
GROUP BYwindow_start, window_end;--上面的cumulate窗口翻译如下:
--每隔5秒,统计最近30秒内的数据(总金额,用户量)

运行结果如下:

补充:

1.渐进式窗口没有普通SQL的写法。

2.渐进式窗口没有DataStream API。

Over 窗口

聚合窗口,用的不多。

Over 窗口分为两类:

  • 时间区间范围

  • 行数

时间区间范围

--语法
--range:范围,
--between ... and ... : 在...之间
--INTERVAL '1' HOUR PRECEDING:一小时前
--CURRENT ROW:当前行
RANGE BETWEEN 起始时间范围 AND CURRENT ROW
RANGE BETWEEN INTERVAL '1' HOUR PRECEDING AND CURRENT ROW--建表SQL
CREATE TABLE source_table (order_id BIGINT,product BIGINT,amount BIGINT,order_time as cast(CURRENT_TIMESTAMP as TIMESTAMP(3)),WATERMARK FOR order_time AS order_time - INTERVAL '0' SECOND
) WITH ('connector' = 'datagen','rows-per-second' = '1','fields.order_id.min' = '1','fields.order_id.max' = '2','fields.amount.min' = '1','fields.amount.max' = '10','fields.product.min' = '1','fields.product.max' = '2'
);--业务SQL
SELECT product, order_time, amount,SUM(amount) OVER (PARTITION BY productORDER BY order_time-- 标识统计范围是一个 product 的最近 30秒的数据RANGE BETWEEN INTERVAL '1' HOUR PRECEDING AND CURRENT ROW) AS one_hour_prod_amount_sum
FROM source_table;

运行结果如下:

行数

--语法
--ROWS:行数
--行数 preceding:往前多少行
--:CURRENT ROW:当前行
ROWS BETWEEN 行数 PRECEDING AND CURRENT ROW
--统计最近100行到当前行的指标
ROWS BETWEEN 100 PRECEDING AND CURRENT ROW
对比前面的时间区间语法:
RANGE BETWEEN INTERVAL '1' HOUR PRECEDING AND CURRENT ROW--创建表
CREATE TABLE source_table (order_id BIGINT,product BIGINT,amount BIGINT,order_time as cast(CURRENT_TIMESTAMP as TIMESTAMP(3)),WATERMARK FOR order_time AS order_time - INTERVAL '0' SECOND
) WITH ('connector' = 'datagen','rows-per-second' = '1','fields.order_id.min' = '1','fields.order_id.max' = '2','fields.amount.min' = '1','fields.amount.max' = '2','fields.product.min' = '1','fields.product.max' = '2'
);--业务SQL
SELECT product, order_time, amount,SUM(amount) OVER (PARTITION BY productORDER BY order_time-- 标识统计范围是一个 product 的最近 5 行数据ROWS BETWEEN 100 PRECEDING AND CURRENT ROW) AS one_hour_prod_amount_sum
FROM source_table;

运行结果如下:

 

补充:

1.Over窗口没有传统窗口的SQL写法。

2.Over窗口没有DataStream API的写法。

相关文章:

Flink的窗口机制

窗口机制 tumble&#xff08;滚动窗口&#xff09; hop&#xff08;滑动窗口&#xff09; session&#xff08;会话窗口&#xff09; cumulate&#xff08;渐进式窗口&#xff09; Over&#xff08;聚合窗口&#xff09; 滚动窗口&#xff08;tumble&#xff09; 概念 滚…...

了解分布式Session

大家好&#xff0c;我这名CRUD工程师又来了&#xff0c;最近我的一个同事突然在看分布式Seesion的问题&#xff0c;然后我们两个也是互相讨论了一下&#xff0c;今天我就想着把分布式Session的知识点好好的梳理一下。 在很多系统中&#xff0c;用户的登录功能都是用Session去实…...

仿真创新大赛—国三省一 智能鱼缸(proteus)(stm32)

⏩ 大家好哇&#xff01;我是小光&#xff0c;嵌入式爱好者&#xff0c;一个想要成为系统架构师的大三学生。 ⏩去年下半年参加了全国仿真创新大赛&#xff0c;也是取得了国赛三等奖&#xff0c;省赛一等奖的好成绩。 ⏩本篇文章对我们的参赛作品《智能鱼缸》做一个简介。 ⏩感…...

【ARMv8 编程】A64 数据处理指令——位域字节操作指令

有些指令将字节、半字或字扩展到寄存器大小&#xff0c;可以是 X 或 W。这些指令存在于有符号&#xff08;SXTB、SXTH、SXTW&#xff09;和无符号&#xff08;UXTB、UXTH&#xff09;变体中&#xff0c;并且是适当的位域操作指令。 这些指令的有符号和无符号变体都将字节、半字…...

ctfshow 愚人杯菜狗杯部分题目(flasksession伪造ssti)

目录 <1>愚人杯 (1) easy_signin (2) easy_ssti(无过滤ssti) (3) easy_flask(flash-session伪造) (4) easy_php(C:开头序列化数据) <2> 菜狗杯 (1) 抽老婆(flask_session伪造) (2) 一言既出&#xff0c;驷马难追(intval) (3) 传说之下&#xff08;js控制台&…...

linux拓展笔记——【补充学习知识点】

文章目录1. ./configure --prefix中的prefix详解1. ./configure --prefix中的prefix详解 源码的安装一般由3个步骤组成&#xff1a;配置(configure)、编译(make)、安装(makeinstall)。 Configure是一个可执行脚本&#xff0c;在待安装的源码路径下使用命令./configure–help输…...

为何银行各岗位之间的薪酬差别如此之大?

银行里的职位种类相对较多&#xff0c;观观整理了5个最常见的职位&#xff0c;看一下你要申请的职位薪资水平到底是怎样的&#xff1f;根据如信银行考试中心发布&#xff1a; 1、客户经理岗 客户经理分为对公客户经理和对私客户经理&#xff0c;他们的主要工作不同&#xff0…...

TensorFlow 深度学习第二版:1~5

原文&#xff1a;Deep Learning with TensorFlow Second Edition 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 深度学习 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 不要担心自己的形象&#xff0c;只…...

微前端micro-app的使用

演示效果 子应用的项目 基应用嵌入子应用效果图 目录 前言 一、微前端是什么&#xff1f; 它主要解决了两个问题&#xff1a; 二、使用步骤 1.安装依赖 2.在入口处引入 3.子应用的路由&#xff08;&#xff09; 4.分配一个路由给子应用&#xff08;重要&#xff09;&#xff0…...

【JUC】Java内存模型之JMM

【JUC】Java内存模型之JMM 文章目录【JUC】Java内存模型之JMM1. 概念2. JMM三大特性2.1 可见性2.2 原子性2.3 有序性3. 多线程对变量的读写过程4. 先行发生原则——happens-before4.1 happens-before八条规则4.1.1 次序规则4.1.2 锁定规则4.1.3 volatile变量规则4.1.4 传递规则…...

Win11快速打开便签和使用技巧分享

Win11快速打开便签和使用技巧分享。Win11系统中为用户提供了一个非常实用的系统组件&#xff0c;就是便签功能&#xff0c;使用这个功能可以帮助我们便捷的进行一些重要内容的记录。那么如何去开启开启这个程序来使用呢&#xff1f;来看看以下的详情分享吧。 详细分享&#xff…...

CSS:横向导航栏

横向导航栏&#xff08;盗版导航栏&#xff0c;B站仿写。&#xff09; 原视频链接 <html><head><title>demo</title><style>*{margin: 0;padding: 0;list-style: none;text-decoration: none;}body{display: flex;justify-content: center;a…...

视频动态库测试及心得

视频动态库测试及心得 这几天一直在弄动态库测试&#xff0c;h给的写好的动态库--预处理模块的库。视频处理项目一部分&#xff0c;需要连接实际情况测试。 需求&#xff1a; 1.把实际相机连接到&#xff0c;并读取实时数据流&#xff0c;保存到双循环链表里面; 2.测试背景建模…...

陶泓达:4.18午间欧盘黄金原油最新精准操作建议!

黄金方面&#xff1a; 黄金消息面解析&#xff1a;周一&#xff08;4月17日&#xff09;美市盘中&#xff0c;美国公布的4月纽约联储制造业指数和4月NAHB房产市场指数均超出预期&#xff0c;提振了美联储在5月继续加息的预期。数据公布之后&#xff0c;美元指数加速上扬&#x…...

环境变量相关知识

目录 目录 谢谢你的阅读&#xff0c;这是对我最大的鼓舞 先说结论&#xff1a; 开始论述&#xff1a; 让我们举个例子 相关指令 创建本地变量 创建环境变量 方法一&#xff1a; 方法二&#xff1a; 删除环境变量 子进程中也有环境变量 第一种&#xff1a; 第二种 …...

如何快速入门ChatGPT

作为一个AI模型&#xff0c;ChatGPT并不需要像人一样“学习”&#xff0c;它已经通过大量的训练数据和算法进行了预训练&#xff0c;可以回答广泛的问题。 然而&#xff0c;如果你想学习如何使用ChatGPT来进行对话或者问答&#xff0c;以下是一些建议&#xff1a; 一、了解Ch…...

Akka定时任务schedule()方法

Akka定时任务schedule()方法 文章目录Akka定时任务schedule()方法什么是Akka定时任务schedule()方法&#xff1f;如何使用Akka定时任务schedule()方法&#xff1f;如何在actor外部获取Scheduler对象为什么需要提供一个隐式的ExecutionContext对象&#xff0c;用于执行定时任务&…...

Python实现处理和分析大规模文本数据集,包括数据清洗、标注和预处理

处理和分析大规模文本数据集,包括数据清洗、标注和预处理,是自然语言处理(NLP)中非常重要的一步。Python 是一种非常流行的编程语言,拥有丰富的 NLP 库和工具,可以帮助我们完成这些任务。以下是一个简单的实现示例,包括数据清洗、标注和预处理: import re import nltk…...

灌区量测水系统

1)灌区量测水 灌区量测水是水资源管理的基础&#xff0c;是推进节水农业和水价改革的重要手段。常规在主要水闸处&#xff0c;监测闸前和闸后水位及闸门开启状态(闸位)&#xff0c;通过实时监测数据&#xff0c;计算过闸流量。要实现全灌区水资源动态配置、精准灌溉&#xff0…...

3.3 泰勒公式

学习目标&#xff1a; 复习微积分基础知识。泰勒公式是微积分的一个重要应用&#xff0c;因此在学习泰勒公式之前&#xff0c;需要复习微积分的基本概念和技能&#xff0c;包括函数的导数和微分、极限、定积分等。可以参考MIT的微积分课程进行复习和加强。 学习泰勒级数和泰勒…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...