流批一体计算引擎-9-[Flink]中的数量窗与时间窗

news2024/7/6 19:16:38

1 数量窗

1.1 数量滚动窗口

0基础学习PyFlink——个数滚动窗口(Tumbling Count Windows)

1.1.1 代码分析

Tumbling Count Windows是指按元素个数计数的滚动窗口。
滚动窗口是指没有元素重叠的窗口。
(1)构造了一个KeyedStream,用于存储word_count_data中的数据。

word_count_data = [("A",), ("A", ), ("B", ), ("A",)]
def word_count():
    env = StreamExecutionEnvironment.get_execution_environment()
    env.set_runtime_mode(RuntimeExecutionMode.STREAMING)
    env.set_parallelism(1)  # 将所有数据写到一个文件

    source_type_info = Types.TUPLE([Types.STRING()])
    # 从列表生成source,指定列表中每个元素的类型
    source = env.from_collection(word_count_data, source_type_info)

    # 按键分组
    keyed_stream = source.key_by(lambda i: i[0])

我们并没有让Source是流的形式,是因为为了降低例子复杂度。但是我们将runntime mode设置为流(STREAMING)模式。

(2)定义一个Reduce类,用于对元组中的数据进行计算。
这个类需要继承于WindowFunction,并实现相应方法(本例中是apply)。
apply会计算一个相同key的元素个数。

class SumWindowFunction(WindowFunction[tuple, tuple, str, CountWindow]):
    def apply(self, key: str, window: CountWindow, inputs: Iterable[tuple]):
        print(inputs, window)
        return [(key, len(inputs))]

(3)keyed_stream.count_window(2)将此keyyedstream窗口转换为滚动计数窗口或滑动计数窗口。

out_type_info = Types.TUPLE([Types.STRING(), Types.INT()])
    reduced = (keyed_stream.count_window(2)
               .apply(SumWindowFunction(), out_type_info))

1.1.2 整体代码

from typing import Iterable
from pyflink.common import Types
from pyflink.datastream import StreamExecutionEnvironment, RuntimeExecutionMode, WindowFunction
from pyflink.datastream.window import CountWindow


class SumWindowFunction(WindowFunction[tuple, tuple, str, CountWindow]):
    def apply(self, key: str, window: CountWindow, inputs: Iterable[tuple]):
        print(inputs, window)
        return [(key, len(inputs))]


word_count_data = [("A",), ("A", ), ("B", ), ("A",)]
def word_count():
    env = StreamExecutionEnvironment.get_execution_environment()
    env.set_runtime_mode(RuntimeExecutionMode.STREAMING)
    env.set_parallelism(1)  # 将所有数据写到一个文件

    source_type_info = Types.TUPLE([Types.STRING()])
    # 从列表生成source,指定列表中每个元素的类型
    source = env.from_collection(word_count_data, source_type_info)

    # 按键分组
    keyed_stream = source.key_by(lambda i: i[0])

    # reducing
    out_type_info = Types.TUPLE([Types.STRING(), Types.INT()])
    reduced = (keyed_stream.count_window(4)
               .apply(SumWindowFunction(), out_type_info))

    # # define the sink
    reduced.print()

    # submit for execution
    env.execute()


if __name__ == '__main__':
    word_count()

1.1.3 结果

(1)window=1,
A的个数是3,被3个窗口承载
B的个数是1,被1个窗口承载
在这里插入图片描述

(2)window=2
A的个数是3,但是会产生两个窗口,第一个窗口承载了前两个元素,第二个窗口当前只有一个元素。于是第一个窗口进行了Reduce计算,得出一个(A,2);第二个窗口还没进行reduce计算,就没有展现出结果;
B的个数是1,被1个窗口承载,只有一个元素,还没进行reduce计算,没有展示结果。
在这里插入图片描述
(3)window=3
A的个数是3,被1个窗口承载,有3个元素;
B的个数是1,被1个窗口承载,只有一个元素,还没进行reduce计算,没有展示结果。
在这里插入图片描述
(4)window=4
A的个数是3,被1个窗口承载,只有3个元素,还没进行reduce计算,没有展示结果。
B的个数是1,被1个窗口承载,只有1个元素,还没进行reduce计算,没有展示结果。
输出空

1.2 数量滑动窗口

0基础学习PyFlink——个数滑动窗口(Sliding Count Windows)

1.2.1 整体代码

“滑动”是指这个窗口沿着一定的方向,按着一定的速度“滑行”。
滚动窗口,则是一个个“衔接着”,而不是像上面那样交错着。
它们的相同之处就是:只有窗口内的事件数量到达窗口要求的数值时,这些窗口才会触发计算。

from typing import Iterable
from pyflink.common import Types
from pyflink.datastream import StreamExecutionEnvironment, RuntimeExecutionMode, WindowFunction
from pyflink.datastream.window import CountWindow


class SumWindowFunction(WindowFunction[tuple, tuple, str, CountWindow]):
    def apply(self, key: str, window: CountWindow, inputs: Iterable[tuple]):
        print(inputs, window)
        return [(key, len(inputs))]


word_count_data = [("A",), ("A", ), ("B", ), ("A",)]
def word_count():
    env = StreamExecutionEnvironment.get_execution_environment()
    env.set_runtime_mode(RuntimeExecutionMode.STREAMING)
    env.set_parallelism(1)  # 将所有数据写到一个文件

    source_type_info = Types.TUPLE([Types.STRING()])
    # 从列表生成source,指定列表中每个元素的类型
    source = env.from_collection(word_count_data, source_type_info)

    # 按键分组
    keyed_stream = source.key_by(lambda i: i[0])

    # reducing
    out_type_info = Types.TUPLE([Types.STRING(), Types.INT()])
    reduced = (keyed_stream.count_window(2,1)
               .apply(SumWindowFunction(), out_type_info))

    # # define the sink
    reduced.print()

    # submit for execution
    env.execute()


if __name__ == '__main__':
    word_count()

1.2.2 结果

(1)window=1,slide=1
在这里插入图片描述

(2)window=2,slide=1
在这里插入图片描述
(3)window=1,slide=2
在这里插入图片描述

2 时间窗

2.1 时间滚动窗口(处理时间)

参考0基础学习PyFlink——时间滚动窗口(Tumbling Time Windows)
对于数量滚动窗口,如果窗口内元素数量没有达到窗口大小时,计算个数的函数是不会被调用的。
如果想让不满足数量的窗口,也执行计算,就可以使用时间滚动窗口。
它不依赖于窗口中元素的个数,而是窗口的时间,即窗口时间到了,计算就会进行。

2.1.1 代码分析

(1)构造了一个KeyedStream,用于存储word_count_data中的数据。

word_count_data = [("A",), ("A", ), ("B", ), ("A",), ("A", ), ("B", ), ("A",)]
def word_count():
    env = StreamExecutionEnvironment.get_execution_environment()
    env.set_runtime_mode(RuntimeExecutionMode.STREAMING)
    env.set_parallelism(1)  # 将所有数据写到一个文件

    source_type_info = Types.TUPLE([Types.STRING()])
    # 从列表生成source,指定列表中每个元素的类型
    source = env.from_collection(word_count_data, source_type_info)

    # 按键分组
    keyed_stream = source.key_by(lambda i: i[0])

我们并没有让Source是流的形式,是因为为了降低例子复杂度。但是我们将runntime mode设置为流(STREAMING)模式。

(2)定义一个Reduce类,用于对元组中的数据进行计算。
这个类需要继承于WindowFunction,并实现相应方法(本例中是apply)。
apply会计算一个相同key的元素个数。

class SumWindowFunction(WindowFunction[tuple, tuple, str, TimeWindow]):
    def apply(self, key: str, window: TimeWindow, inputs: Iterable[tuple]):
        print(inputs, window)
        return [(key, len(inputs))]

(3)这儿我们的Window使用的是滚动时间窗口(处理时间),其中参数Time.milliseconds(2)是指窗口时长,即2毫秒一个窗口。

 # reducing
    out_type_info = Types.TUPLE([Types.STRING(), Types.INT()])
    reduced = (keyed_stream\
                .window(TumblingProcessingTimeWindows.of(Time.milliseconds(2)))\
               .apply(SumWindowFunction(), out_type_info))

    # define the sink
    reduced.print()

    # submit for execution
    env.execute()

2.1.2 整体代码

from typing import Iterable
from pyflink.common import Types, Time
from pyflink.datastream import StreamExecutionEnvironment, RuntimeExecutionMode, WindowFunction
from pyflink.datastream.window import TimeWindow, TumblingProcessingTimeWindows


class SumWindowFunction(WindowFunction[tuple, tuple, str, TimeWindow]):
    def apply(self, key: str, window: TimeWindow, inputs: Iterable[tuple]):
        print(inputs, window)
        return [(key, len(inputs))]


word_count_data = [("A",), ("A", ), ("B", ), ("A",), ("A", ), ("B", ), ("A",)]

def word_count():
    env = StreamExecutionEnvironment.get_execution_environment()
    env.set_runtime_mode(RuntimeExecutionMode.STREAMING)
    env.set_parallelism(1)  # 将所有数据写到一个文件

    source_type_info = Types.TUPLE([Types.STRING()])
    # 从列表生成source,指定列表中每个元素的类型
    source = env.from_collection(word_count_data, source_type_info)

    # 按键分组
    keyed_stream = source.key_by(lambda i: i[0])


    # reducing
    out_type_info = Types.TUPLE([Types.STRING(), Types.INT()])
    reduced = (keyed_stream\
                .window(TumblingProcessingTimeWindows.of(Time.milliseconds(2)))\
               .apply(SumWindowFunction(), out_type_info))

    # define the sink
    reduced.print()

    # submit for execution
    env.execute()


if __name__ == '__main__':
    word_count()

2.1.3 结果

运行多次代码可以得到不同的结果。
可以发现结果并不稳定。但是可以发现,每个元素都参与了计算,而不像数量滚动窗口那样部分数据没有被触发计算。
这是因为每次运行时,CPU等系统资源的繁忙程度是不一样的,这就影响了最后的运行结果。
(1)第一次运行
在这里插入图片描述
(2)第二次运行
在这里插入图片描述
(3)第三次运行
在这里插入图片描述

2.2 时间滑动窗口(处理时间)

0基础学习PyFlink——时间滑动窗口(Sliding Time Windows)

2.2.1 整体代码

from typing import Iterable
from pyflink.common import Types, Time
from pyflink.datastream import StreamExecutionEnvironment, RuntimeExecutionMode, WindowFunction
from pyflink.datastream.window import TimeWindow, SlidingProcessingTimeWindows


class SumWindowFunction(WindowFunction[tuple, tuple, str, TimeWindow]):
    def apply(self, key: str, window: TimeWindow, inputs: Iterable[tuple]):
        print(inputs, window)
        return [(key, len(inputs))]


word_count_data = [("A",), ("A", ), ("B", ), ("A",), ("A", ), ("B", ), ("A",)]

def word_count():
    env = StreamExecutionEnvironment.get_execution_environment()
    env.set_runtime_mode(RuntimeExecutionMode.STREAMING)
    env.set_parallelism(1)  # 将所有数据写到一个文件

    source_type_info = Types.TUPLE([Types.STRING()])
    # 从列表生成source,指定列表中每个元素的类型
    source = env.from_collection(word_count_data, source_type_info)

    # 按键分组
    keyed_stream = source.key_by(lambda i: i[0])


    # reducing
    out_type_info = Types.TUPLE([Types.STRING(), Types.INT()])
    reduced = (keyed_stream\
                .window(SlidingProcessingTimeWindows.of(Time.milliseconds(2),Time.milliseconds(1)))\
               .apply(SumWindowFunction(), out_type_info))

    # define the sink
    reduced.print()

    # submit for execution
    env.execute()


if __name__ == '__main__':
    word_count()

2.2.2 结果

运行两次上述代码,我们发现每次都不同,而且有重叠计算的元素。
(1)第一次运行
A:9,B:3
在这里插入图片描述
(2)第二次运行
A:7,B:3
在这里插入图片描述

4.3 时间滚动窗口(事件时间)

0基础学习PyFlink——事件时间和运行时间的窗口
使用的是运行时间(Tumbling ProcessingTimeWindows)作为窗口的参考时间,得到的结果是不稳定的。
这是因为每次运行时,CPU等系统资源的繁忙程度是不一样的,这就影响了最后的运行结果。
为了让结果稳定,我们可以不依赖运行时间(ProcessingTime),而使用不依赖于运行环境,只依赖于数据的事件时间(EventTime)。

一般,我们需要大数据处理的数据,往往存在一个字段用于标志该条数据的“顺序”。
这个信息可以是单调递增的ID,也可以是不唯一的时间戳,我们可以将这类信息看做事件发生的时间。

那如何让输入的数据中的“事件时间”参与到窗口时长的计算中呢?这儿就要引入时间戳和Watermark(水位线)的概念
假如我们把数据看成一张纸上的内容,水位线则是这张纸的背景。它并不影响纸上内容的表达,只是系统要用它来做更多的事情。
将数据中表达“顺序”的数据转换成时间戳,我们可以使用水位线单调递增时间戳分配器

2.3.1 代码分析

(1)构造了一个Stream,用于存储word_count_data中的数据。

word_count_data = [("A","2024-06-04 08:10:11.100"),
                   ("A", "2024-06-04 08:10:11.101"),
                   ("B", "2024-06-04 08:10:11.102"),
                   ("A","2024-06-04 08:10:11.103")]
def word_count():
    env = StreamExecutionEnvironment.get_execution_environment()
    env.set_runtime_mode(RuntimeExecutionMode.STREAMING)
    env.set_parallelism(1)  # 将所有数据写到一个文件

    source_type_info = Types.TUPLE([Types.STRING(),Types.STRING()])
    source = env.from_collection(word_count_data, source_type_info)

(2)定制策略

class ElementTimestampAssigner(TimestampAssigner):
    def extract_timestamp(self, value, record_timestamp)-> int:
        time_str = value[1]
        dt = datetime.datetime.strptime(time_str, "%Y-%m-%d %H:%M:%S.%f")
        ts_s = dt.timestamp()  # 时间戳,单位秒
        ts_ms = int(ts_s * 1000)  # 时间戳,单位毫秒
        return ts_ms
# 定义水位线策略
watermark_strategy = WatermarkStrategy.for_monotonous_timestamps() \
    .with_timestamp_assigner(ElementTimestampAssigner())

for_monotonous_timestamps会分配一个水位线单调递增时间戳分配器,然后使用with_timestamp_assigner告知输入数据中“顺序”字段的值。这样系统就会根据这个字段的值生成一个单调递增的时间戳。这个时间戳相对顺序就和输入数据一样,是稳定的。
(3)运行策略
然后对原始数据使用该策略,这样source_with_wartermarks中的数据就包含了时间戳。

# 对原始数据使用该策略
source_with_wartermarks = source.assign_timestamps_and_watermarks(watermark_strategy)

(4)使用TumblingEventTimeWindows,即事件时间(EventTime)窗口,而不是运行时间(ProcessingTime)窗口。

# reducing
out_type_info = Types.TUPLE([Types.STRING(), Types.INT()])
reduced = (source_with_wartermarks.key_by(lambda i: i[0])\
            .window(TumblingEventTimeWindows.of(Time.milliseconds(2)))\
           .apply(SumWindowFunction(), out_type_info))

# # define the sink
reduced.print()

# submit for execution
env.execute()

2.3.2 整体代码

from typing import Iterable
from pyflink.common import Types, Time, WatermarkStrategy
from pyflink.common.watermark_strategy import TimestampAssigner
from pyflink.datastream import StreamExecutionEnvironment, RuntimeExecutionMode, WindowFunction
from pyflink.datastream.window import TimeWindow,  TumblingEventTimeWindows
import datetime

class SumWindowFunction(WindowFunction[tuple, tuple, str, TimeWindow]):
    def apply(self, key: str, window: TimeWindow, inputs: Iterable[tuple]):
        print(inputs, window)
        return [(key, len(inputs))]




class ElementTimestampAssigner(TimestampAssigner):
    def extract_timestamp(self, value, record_timestamp)-> int:
        time_str = value[1]
        dt = datetime.datetime.strptime(time_str, "%Y-%m-%d %H:%M:%S.%f")
        ts_s = dt.timestamp()  # 时间戳,单位秒
        ts_ms = int(ts_s * 1000)  # 时间戳,单位毫秒
        return ts_ms


word_count_data = [("A","2024-06-04 08:10:11.100"),
                   ("A", "2024-06-04 08:10:11.110"),
                   ("B", "2024-06-04 08:10:11.102"),
                   ("A","2024-06-04 08:10:11.103")]
def word_count():
    env = StreamExecutionEnvironment.get_execution_environment()
    env.set_runtime_mode(RuntimeExecutionMode.STREAMING)
    env.set_parallelism(1)  # 将所有数据写到一个文件

    source_type_info = Types.TUPLE([Types.STRING(),Types.STRING()])
    source = env.from_collection(word_count_data, source_type_info)

    # 定义水位线策略
    watermark_strategy = WatermarkStrategy.for_monotonous_timestamps() \
        .with_timestamp_assigner(ElementTimestampAssigner())
    # 对原始数据使用该策略
    source_with_wartermarks = source.assign_timestamps_and_watermarks(watermark_strategy)

    # reducing
    out_type_info = Types.TUPLE([Types.STRING(), Types.INT()])
    reduced = (source_with_wartermarks.key_by(lambda i: i[0])\
                .window(TumblingEventTimeWindows.of(Time.milliseconds(2)))\
               .apply(SumWindowFunction(), out_type_info))

    # # define the sink
    reduced.print()

    # submit for execution
    env.execute()


if __name__ == '__main__':
    word_count()

2.3.3 结果

数据乱序也没关系,会自动排序。
在这里插入图片描述

在这里插入图片描述

2.4 时间滑动窗口(事件时间)

2.4.1 整体代码

from typing import Iterable
from pyflink.common import Types, Time, WatermarkStrategy
from pyflink.common.watermark_strategy import TimestampAssigner
from pyflink.datastream import StreamExecutionEnvironment, RuntimeExecutionMode, WindowFunction
from pyflink.datastream.window import TimeWindow,  SlidingEventTimeWindows
import datetime

class SumWindowFunction(WindowFunction[tuple, tuple, str, TimeWindow]):
    def apply(self, key: str, window: TimeWindow, inputs: Iterable[tuple]):
        print(inputs, window)
        return [(key, len(inputs))]




class ElementTimestampAssigner(TimestampAssigner):
    def extract_timestamp(self, value, record_timestamp)-> int:
        time_str = value[1]
        dt = datetime.datetime.strptime(time_str, "%Y-%m-%d %H:%M:%S.%f")
        ts_s = dt.timestamp()  # 时间戳,单位秒
        ts_ms = int(ts_s * 1000)  # 时间戳,单位毫秒
        return ts_ms


word_count_data = [("A","2024-06-04 08:10:11.100"),
                   ("A", "2024-06-04 08:10:11.110"),
                   ("B", "2024-06-04 08:10:11.102"),
                   ("A","2024-06-04 08:10:11.103")]
def word_count():
    env = StreamExecutionEnvironment.get_execution_environment()
    env.set_runtime_mode(RuntimeExecutionMode.STREAMING)
    env.set_parallelism(1)  # 将所有数据写到一个文件

    source_type_info = Types.TUPLE([Types.STRING(),Types.STRING()])
    source = env.from_collection(word_count_data, source_type_info)

    # 定义水位线策略
    watermark_strategy = WatermarkStrategy.for_monotonous_timestamps() \
        .with_timestamp_assigner(ElementTimestampAssigner())
    # 对原始数据使用该策略
    source_with_wartermarks = source.assign_timestamps_and_watermarks(watermark_strategy)

    # reducing
    out_type_info = Types.TUPLE([Types.STRING(), Types.INT()])
    reduced = (source_with_wartermarks.key_by(lambda i: i[0])\
                .window(SlidingEventTimeWindows.of(Time.milliseconds(4),Time.milliseconds(2)))\
               .apply(SumWindowFunction(), out_type_info))

    # # define the sink
    reduced.print()

    # submit for execution
    env.execute()


if __name__ == '__main__':
    word_count()

2.4.2 结果

在这里插入图片描述

3 pyflink中文乱码的问题

pyflink遇到的问题

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

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

相关文章

creo学习一

设置好当前配置后,导出config配置文件,并覆盖掉此路径下的旧文件,使得新配置永久生效,这样每次打开软件都是新配置的设置: 系统颜色的导出: 打开版本的问题: 不能有弱尺寸: 注意&a…

【Android Studio】导入import android.support.v7.app.AppcompatActivity;时报错

一、问题描述 在进行安卓项目开发时使用import android.support.v7.app.AppcompatActivity;报错: 运行后会有乱码出现: 二、解决办法 将import android.support.v7.app.AppcompatActivity;改为import androidx.appcompat.app.AppCompatActivity;基本上…

代码随想录算法训练营第五十四 | ● 392.判断子序列 ● 115.不同的子序列

392.判断子序列 https://programmercarl.com/0392.%E5%88%A4%E6%96%AD%E5%AD%90%E5%BA%8F%E5%88%97.html class Solution { public:bool isSubsequence(string s, string t) {if(s.size()0 )return true;if(t.size()0)return false;vector<vector<int>> dp(s.size(…

学生信息管理(C语言)

学生信息管理 (1)问题描述 学生信息包括:学号,姓名,年龄,性别,出生年月,地址,电话,E-mail等。试设计一学生信息管理系统,使之能提供以下功能: 系统以菜单方式工作学生信息录入功能(学生信息用文件保存)---输入学生信息浏览功能---输出查询、排序功能---算法1、…

Zabbix6.0自动发现Linux服务器并添加主机

文章目录 一、整体流程二、操作过程 一、整体流程 Zabbix自动发现主机功能是Zabbix监控系统的一个重要功能&#xff0c;它能够自动发现并添加新的主机到监控系统中&#xff0c;从而减少人为繁琐的操作&#xff01; 步骤操作1️⃣ 第一步创建自动发现规则2️⃣ ​第二步创建自…

上汽集团25届暑期实习测评校招笔试题库已发(真题)

&#x1f4e3;上汽集团 25届暑期实习测评已发&#xff0c;正在申请的小伙伴看过来哦&#x1f440; ㊙️本次实习项目面向2025届国内外毕业生&#xff0c;开放了新媒体运营、销售策略、市场运营、物流、质量分析等岗位~ ✅测评讲解&#xff1a; &#x1f449;测评自收到起需在…

PawSQL优化 | 分页查询太慢?别忘了投影下推

​在进行数据库应用开发中&#xff0c;分页查询是一项非常常见而又至关重要的任务。但你是否曾因为需要获取总记录数的性能而感到头疼&#xff1f;现在&#xff0c;让PawSQL的投影下推优化来帮你轻松解决这一问题&#xff01;本文以TPCH的Q12为案例进行验证&#xff0c;经过Paw…

万能表单与AI的完美融合,打造个性化AI小程序

在人工智能技术日益成熟的今天&#xff0c;如何将AI智能与用户界面无缝结合&#xff0c;已成为软件开发领域的新挑战。MyCms 以其创新的“万能表单结合AI”功能&#xff0c;为开发者提供了一个全新的解决方案&#xff0c;让个性化AI小程序的开发变得前所未有的简单和高效。 一、…

powerdesigner各种字体设置

1、设置左侧菜单&#xff1a; 步骤如下&#xff1a; tools —> general options —> fonts —> defalut UI font ,选择字体样式及大小即可&#xff0c;同下图。 2、设置Table的字体大小 Tools------>Display Prefrences------>Table------->Format---------…

基于机器学习的锂电池RUL SOH预测

数据集为NASA锂电池数据集。 import datetimeimport numpy as npimport pandas as pdfrom scipy.io import loadmatfrom sklearn.preprocessing import MinMaxScalerfrom sklearn.metrics import mean_squared_errorfrom sklearn import metricsimport matplotlib.pyplot as p…

从GPU到ASIC,博通和Marvell成赢家

ASIC市场上&#xff0c;博通预计今年AI收入将达到110亿美元以上&#xff0c;主要来自与Google和Meta的合作&#xff1b;Marvell预计2028年AI收入将达到70亿至80亿美元&#xff0c;主要来自与Amazon和Google的合作。 随着芯片设计和系统复杂性的增加&#xff0c;科技大厂将更多地…

Python 全栈体系【四阶】(五十八)

第五章 深度学习 十三、自然语言处理&#xff08;NLP&#xff09; 3. 文本表示 3.1 One-hot One-hot&#xff08;独热&#xff09;编码是一种最简单的文本表示方式。如果有一个大小为V的词表&#xff0c;对于第i个词 w i w_i wi​&#xff0c;可以用一个长度为V的向量来表示…

OBS 录屏软件 for Mac 视频录制和视频实时交流软件 安装

Mac分享吧 文章目录 效果一、准备工作二、开始安装注意事项&#xff1a;包内有两个版本及圆形图片&#xff0c;请根据自身需要版本进行安装演示为&#xff1a;MacBook Pro M3芯片1、双击运行软件&#xff0c;将其从左侧拖入右侧文件夹中&#xff08;最终目的&#xff1a;安装进…

vuInhub靶场实战系列--Kioptrix Level #3

免责声明 本文档仅供学习和研究使用,请勿使用文中的技术源码用于非法用途,任何人造成的任何负面影响,与本人无关。 目录 免责声明前言一、环境配置1.1 靶场信息1.2 靶场配置 二、信息收集2.1 主机发现2.1.1 netdiscover2.1.2 arp-scan主机扫描 2.2 端口扫描2.3 指纹识别2.4 目…

27-LINUX--I/O复用-poll

一.poll概述 poll是一个多路复用的I/O模型&#xff0c;一个进程监视多个文件描述符&#xff0c;当文件描述符就绪时&#xff0c;poll返回可读并做相应处理。 1.poll的模型 #include <poll.h>struct pollfd {int fd; //文件描述符short events; //事件类型 s…

5 个你不知道的隐藏 CSS 属性

层叠样式表 (CSS) 是网页设计的骨架&#xff0c;它可以帮助我们轻松的设置网页的样式和格式。虽然大多数的 CSS 属性&#xff0c;例如颜色、字体大小和边距都被大家熟知&#xff0c;但还有许多鲜为人知的属性可以帮助我们设计添加功能。在这篇文章中&#xff0c;我们将介绍 5 个…

数据结构与算法笔记:基础篇 - 红黑树(上):为什么工程中都用红黑树这种二叉树?

概述 上两篇文章&#xff0c;我们依次讲解了树、二叉树、二叉查找树。二叉查找树是最常用的一种二叉树&#xff0c;它支持快速插入、删除、查找操作&#xff0c;各个操作的时间复杂度跟树的高度成正比&#xff0c;理想情况下&#xff0c;时间复杂度是 O ( l o g n ) O(logn) …

【PL理论】(16) 形式化语义:语义树 | <Φ, S> ⇒ M | 形式化语义 | 为什么需要形式化语义 | 事实:部分编程语言的设计者并不会形式化语义

&#x1f4ad; 写在前面&#xff1a;本章我们将继续探讨形式化语义&#xff0c;讲解语义树&#xff0c;然后我们将讨论“为什么需要形式化语义”&#xff0c;以及讲述一个比较有趣的事实&#xff08;大部分编程语言设计者其实并不会形式化语义的定义&#xff09;。 目录 0x00…

第十四周 6.4 内部类部分知识点

一、理解 1.定义在一个类内部的类称为内部类 2.语法: class 类名{ class 类名{} } 3.内部类编译之后生成独立的.class文件&#xff0c;文件命名为:外部类类名$内部类的类名.class 4.内部类分类:成员内部类、静…

插卡式仪器模块:波形发生模块(插入式)

• 16 位分辨率 • 125 MHz 刷新率 • 支持生成 FSK/ASK 信号 • 生成任意标准波形或用户自定义波形 • 在特殊协议通信中模拟某个波形 • 无线充电&#xff08;信号调制&#xff09; 通道11输出阻抗Low-ZLow-Z输出范围 5 V 5 V耦合DCDC带宽4 MHz10 MHzADC 分辨率16 Bits1…