Flink系列之:Joins

Flink系列之:Joins

  • 一、Joins
  • 二、Regular Joins
  • 三、INNER Equi-JOIN
  • 四、OUTER Equi-JOIN
  • 五、Interval Joins
  • 六、Temporal Joins
  • 七、事件时间 Temporal Join
  • 八、处理时间 Temporal Join
  • 九、时态表函数连接
  • 十、Lookup Join
  • 十一、数组展开
  • 十二、表功能

一、Joins

  • 适用于流、批一体

Flink SQL支持对动态表进行复杂而灵活的连接操作。 为了处理不同的场景,需要多种查询语义,因此有几种不同类型的 Join。

默认情况下,joins 的顺序是没有优化的。表的 join 顺序是在 FROM 从句指定的。可以通过把更新频率最低的表放在第一个、频率最高的放在最后这种方式来微调 join 查询的性能。需要确保表的顺序不会产生笛卡尔积,因为不支持这样的操作并且会导致查询失败。

二、Regular Joins

Regular join 是最通用的 join 类型。在这种 join 下,join 两侧表的任何新记录或变更都是可见的,并会影响整个 join 的结果。 例如:如果左边有一条新纪录,在 Product.id 相等的情况下,它将和右边表的之前和之后的所有记录进行 join。

SELECT * FROM Orders
INNER JOIN Product
ON Orders.productId = Product.id

对于流式查询,regular join 的语法是最灵活的,允许任何类型的更新(插入、更新、删除)输入表。 然而,这种操作具有重要的操作意义:Flink 需要将 Join 输入的两边数据永远保持在状态中。 因此,计算查询结果所需的状态可能会无限增长,这取决于所有输入表的输入数据量。你可以提供一个合适的状态 time-to-live (TTL) 配置来防止状态过大。注意:这样做可能会影响查询的正确性。

三、INNER Equi-JOIN

根据 join 限制条件返回一个简单的笛卡尔积。目前只支持 equi-joins,即:至少有一个等值条件。不支持任意的 cross join 和 theta join。(cross join 指的是类似 SELECT * FROM table_a CROSS JOIN table_b,theta join 指的是类似 SELECT * FROM table_a, table_b)

SELECT *
FROM Orders
INNER JOIN Product
ON Orders.product_id = Product.id

四、OUTER Equi-JOIN

返回所有符合条件的笛卡尔积(即:所有通过 join 条件连接的行),加上所有外表没有匹配到的行。Flink 支持 LEFT、RIGHT 和 FULL outer joins。目前只支持 equi-joins,即:至少有一个等值条件。不支持任意的 cross join 和 theta join。

SELECT *
FROM Orders
LEFT JOIN Product
ON Orders.product_id = Product.idSELECT *
FROM Orders
RIGHT JOIN Product
ON Orders.product_id = Product.id
SELECT *
FROM Orders
FULL OUTER JOIN Product
ON Orders.product_id = Product.id

这个Flink SQL查询的目标是通过将Orders表与Product表进行FULL OUTER JOIN,获取所有订单和产品的信息。

  • 使用SELECT *来选择所有列。
  • 使用FULL OUTER JOIN将Orders表和Product表连接起来,连接条件是Orders表的product_id列与Product表的id列相等。
  • FULL OUTER JOIN操作将返回所有匹配和不匹配的行,因此查询结果将包括Orders表和Product表中的所有数据。
  • 这个查询的结果将包含所有订单和产品的信息。

五、Interval Joins

返回一个符合 join 条件和时间限制的简单笛卡尔积。Interval join 需要至少一个 equi-join 条件和一个 join 两边都包含的时间限定 join 条件。范围判断可以定义成就像一个条件(<, <=, >=, >),也可以是一个 BETWEEN 条件,或者两边表的一个相同类型(即:处理时间 或 事件时间)的时间属性 的等式判断。

例如:如果订单是在被接收到4小时后发货,这个查询会把所有订单和它们相应的 shipments join 起来。

SELECT *
FROM Orders o, Shipments s
WHERE o.id = s.order_id
AND o.order_time BETWEEN s.ship_time - INTERVAL '4' HOUR AND s.ship_time

这个SQL查询的目标是,从订单数据表(Orders)和发货数据表(Shipments)中选择符合条件的所有列。

  • 首先,我们使用FROM关键字将Orders表和Shipments表进行连接(使用逗号表示进行内连接)。
  • 然后,我们使用WHERE子句来指定连接条件,即订单(Orders)和发货(Shipments)的订单ID必须相等。
  • 除此之外,我们还使用AND子句来指定一个条件,即订单时间(o.order_time)必须在发货时间(s.ship_time)之前的4小时内。
  • 最后,使用SELECT *语句选择所有的列。
  • 这个查询的结果将返回满足连接条件和时间范围条件的所有订单和发货数据。

下面列举了一些有效的 interval join 时间条件:

  • ltime = rtime
  • ltime >= rtime AND ltime < rtime + INTERVAL ‘10’ MINUTE
  • ltime BETWEEN rtime - INTERVAL ‘10’ SECOND AND rtime + INTERVAL ‘5’ SECOND

对于流式查询,对比 regular join,interval join 只支持有时间属性的非更新表。 由于时间属性是递增的,Flink 从状态中移除旧值也不会影响结果的正确性。

六、Temporal Joins

时态表(Temporal table)是一个随时间变化的表:在 Flink 中被称为动态表。时态表中的行与一个或多个时间段相关联,所有 Flink 中的表都是时态的(Temporal)。 时态表包含一个或多个版本的表快照,它可以是一个变化的历史表,跟踪变化(例如,数据库变化日志,包含所有快照)或一个变化的维度表,也可以是一个将变更物化的维表(例如,存放最终快照的数据表)。

七、事件时间 Temporal Join

基于事件时间的 Temporal join 允许对版本表进行 join。 这意味着一个表可以使用变化的元数据来丰富,并在某个时间点检索其具体值。

Temporal Joins 使用任意表(左侧输入/探测端)的每一行与版本表中对应的行进行关联(右侧输入/构建端)。 Flink 使用 SQL:2011标准 中的 FOR SYSTEM_TIME AS OF 语法去执行操作。 Temporal join 的语法如下:

SELECT [column_list]
FROM table1 [AS <alias1>]
[LEFT] JOIN table2 FOR SYSTEM_TIME AS OF table1.{ proctime | rowtime } [AS <alias2>]
ON table1.column-name1 = table2.column-name1

有了事件时间属性(即:rowtime 属性),就能检索到过去某个时间点的值。 这允许在一个共同的时间点上连接这两个表。 版本表将存储自最后一个 watermark 以来的所有版本(按时间标识)。

例如,假设我们有一个订单表,每个订单都有不同货币的价格。 为了正确地将该表统一为单一货币(如美元),每个订单都需要与下单时相应的汇率相关联。

-- 创建订单表。这是一个标准
-- 仅追加动态表。
CREATE TABLE orders (order_id    STRING,price       DECIMAL(32,2),currency    STRING,order_time  TIMESTAMP(3),WATERMARK FOR order_time AS order_time - INTERVAL '15' SECOND
) WITH (/* ... */);-- 定义版本化的货币汇率表。
-- 这可能来自变更数据捕获
-- 例如 Debezium、压缩的 Kafka 主题或任何其他
-- 定义版本化表的方法。
CREATE TABLE currency_rates (currency STRING,conversion_rate DECIMAL(32, 2),update_time TIMESTAMP(3) METADATA FROM `values.source.timestamp` VIRTUAL,WATERMARK FOR update_time AS update_time - INTERVAL '15' SECOND,PRIMARY KEY(currency) NOT ENFORCED
) WITH ('connector' = 'kafka','value.format' = 'debezium-json',/* ... */
);SELECT order_id,price,orders.currency,conversion_rate,order_time
FROM orders
LEFT JOIN currency_rates FOR SYSTEM_TIME AS OF orders.order_time
ON orders.currency = currency_rates.currency;order_id  price  currency  conversion_rate  order_time
========  =====  ========  ===============  =========
o_001     11.11  EUR       1.14             12:00:00
o_002     12.51  EUR       1.10             12:06:00

这个Flink SQL查询的目标是将订单数据和货币汇率数据进行连接,并在连接后的结果中选择特定的列。

  • 首先,我们使用CREATE TABLE语句创建了一个名为orders的表。该表包含了订单的相关信息,如订单ID、价格、货币类型和订单时间。在定义该表时,我们还为订单时间添加了一个WATERMARK。WATERMARK用于指定事件时间,以便Flink能够按照事件时间进行处理。
  • 接下来,我们使用CREATE TABLE语句创建了一个名为currency_rates的表。该表用于存储货币汇率的相关信息,包括货币类型、兑换率和更新时间。这个表是一个版本化的表,可以通过变更数据捕获(如Debezium)、压缩的Kafka主题或其他方式创建。
  • 最后,我们使用SELECT语句从orders表中选择了订单ID、价格、订单货币类型、兑换率和订单时间这几个列。在选择这些列时,我们还使用了LEFT JOIN关键字将orders表和currency_rates表进行连接。连接条件是订单的货币类型(orders.currency)和货币汇率表中的货币类型(currency_rates.currency)必须相等。此外,我们还使用了FOR SYSTEM_TIME AS OF orders.order_time指定使用订单时间来选择货币汇率表中的数据。这样,查询的结果将返回订单数据和相应的货币汇率信息。
  • 查询结果中的order_id、price、currency、conversion_rate和order_time列分别表示订单ID、价格、货币类型、兑换率和订单时间。每一行表示一个订单及其相应的货币汇率。

注意: 事件时间 temporal join 是通过左和右两侧的 watermark 触发的; 这里的 INTERVAL 时间减法用于等待后续事件,以确保 join 满足预期。 请确保 join 两边设置了正确的 watermark 。

注意: 事件时间 temporal join 需要包含主键相等的条件,即:currency_rates 表的主键 currency_rates.currency 包含在条件 orders.currency = currency_rates.currency 中。

与 regular joins 相比,就算 build side(例子中的 currency_rates 表)发生变更了,之前的 temporal table 的结果也不会被影响。 与 interval joins 对比,temporal join没有定义join的时间窗口。 Probe side (例子中的 orders 表)的记录总是在 time 属性指定的时间与 build side 的版本行进行连接。因此,build side 表的行可能已经过时了。 随着时间的推移,不再被需要的记录版本(对于给定的主键)将从状态中删除。

八、处理时间 Temporal Join

基于处理时间的 temporal join 使用处理时间属性将数据与外部版本表(例如 mysql、hbase)的最新版本相关联。

通过定义一个处理时间属性,这个 join 总是返回最新的值。可以将 build side 中被查找的表想象成一个存储所有记录简单的 HashMap<K,V>。 这种 join 的强大之处在于,当无法在 Flink 中将表具体化为动态表时,它允许 Flink 直接针对外部系统工作。

下面这个处理时间 temporal join 示例展示了一个追加表 orders 与 LatestRates 表进行 join。 LatestRates 是一个最新汇率的维表,比如 HBase 表,在 10:15,10:30,10:52这些时间,LatestRates 表的数据看起来是这样的:

10:15> SELECT * FROM LatestRates;currency   rate
======== ======
US Dollar   102
Euro        114
Yen           110:30> SELECT * FROM LatestRates;currency   rate
======== ======
US Dollar   102
Euro        114
Yen           110:52> SELECT * FROM LatestRates;currency   rate
======== ======
US Dollar   102
Euro        116     <==== changed from 114 to 116
Yen           1

LastestRates 表的数据在 10:15 和 10:30 是相同的。 欧元(Euro)的汇率(rate)在 10:52 从 114 变更为 116。

Orders 表示支付金额的 amount 和currency的追加表。 例如:在 10:15 ,有一个金额为 2 Euro 的 order。

SELECT * FROM Orders;amount currency
====== =========2 Euro             <== arrived at time 10:151 US Dollar        <== arrived at time 10:302 Euro             <== arrived at time 10:52

给出下面这些表,我们希望所有 Orders 表的记录转换为一个统一的货币。

amount currency     rate   amount*rate
====== ========= ======= ============2 Euro          114          228    <== arrived at time 10:151 US Dollar     102          102    <== arrived at time 10:302 Euro          116          232    <== arrived at time 10:52

目前,temporal join 还不支持与任意 view/table 的最新版本 join 时使用 FOR SYSTEM_TIME AS OF 语法。可以像下面这样使用 temporal table function 语法来实现(时态表函数):

SELECTo_amount, r_rate
FROMOrders,LATERAL TABLE (Rates(o_proctime))
WHEREr_currency = o_currency

这个Flink SQL查询的目标是将订单数据和货币汇率数据进行连接,并在连接后的结果中选择特定的列。

  • 首先,通过FROM子句指定了两个输入表,即Orders和LATERAL TABLE (Rates(o_proctime))。Orders表示订单数据表,而LATERAL TABLE (Rates(o_proctime))表示根据订单处理时间获取的货币汇率表。
  • 接下来,在WHERE子句中指定了连接条件,即货币汇率表中的货币类型(r_currency)必须与订单表中的货币类型(o_currency)相等。
  • 最后,在SELECT子句中选择了o_amount和r_rate这两个列,分别表示订单金额和货币汇率。
  • 查询结果将返回订单金额和对应的货币汇率。

注意 Temporal join 不支持与 table/view 的最新版本进行 join 时使用 FOR SYSTEM_TIME AS OF 语法是出于语义考虑,因为左流的连接处理不会等待 temporal table 的完整快照,这可能会误导生产环境中的用户。处理时间 temporal join 使用 temporal table function 也存在相同的语义问题,但它已经存在了很长时间,因此我们从兼容性的角度支持它。

processing-time 的结果是不确定的。 processing-time temporal join 常常用在使用外部系统来丰富流的数据。(例如维表)

与 regular joins 的差异,就算 build side(例子中的 currency_rates 表)发生变更了,之前的 temporal table 结果也不会被影响。 与 interval joins 的差异,temporal join 没有定义数据连接的时间窗口。即:旧数据没存储在状态中。

九、时态表函数连接

使用 temporal table function 去 join 表的语法和 Table Function 相同。

注意:目前只支持 inner join 和 left outer join。

假设Rates是一个 temporal table function,这个 join 在 SQL 中可以被表达为:

SELECTo_amount, r_rate
FROMOrders,LATERAL TABLE (Rates(o_proctime))
WHEREr_currency = o_currency

上述 temporal table DDL 和 temporal table function 的主要区别在于:

  • SQL 中可以定义 temporal table DDL,但不能定义 temporal table 函数;
  • temporal table DDL 和 temporal table function 都支持 temporal join 版本表,但只有 temporal table function 可以 temporal join 任何表/视图的最新版本(即"处理时间 Temporal Join")。

十、Lookup Join

lookup join 通常用于使用从外部系统查询的数据来丰富表。join 要求一个表具有处理时间属性,另一个表由查找源连接器(lookup source connnector)支持。

lookup join 和上面的 处理时间 Temporal Join 语法相同,右表使用查找源连接器支持。

下面的例子展示了 lookup join 的语法。

-- Customers 由 JDBC 连接器支持,可用于查找连接
CREATE TEMPORARY TABLE Customers (id INT,name STRING,country STRING,zip STRING
) WITH ('connector' = 'jdbc','url' = 'jdbc:mysql://mysqlhost:3306/customerdb','table-name' = 'customers'
);-- 用客户信息丰富每个订单
SELECT o.order_id, o.total, c.country, c.zip
FROM Orders AS oJOIN Customers FOR SYSTEM_TIME AS OF o.proc_time AS cON o.customer_id = c.id;

在上面的示例中,Orders 表由保存在 MySQL 数据库中的 Customers 表数据来丰富。带有后续 process time 属性的 FOR SYSTEM_TIME AS OF 子句确保在联接运算符处理 Orders 行时,Orders 的每一行都与 join 条件匹配的 Customer 行连接。它还防止连接的 Customer 表在未来发生更新时变更连接结果。lookup join 还需要一个强制的相等连接条件,在上面的示例中是 o.customer_id = c.id。

十一、数组展开

返回给定数组中每个元素的新行。尚不支持 WITH ORDINALITY(会额外生成一个标识顺序的整数列)展开。

SELECT order_id, tag
FROM Orders CROSS JOIN UNNEST(tags) AS t (tag)

十二、表功能

将表与表函数的结果联接。左侧(外部)表的每一行都与表函数的相应调用产生的所有行相连接。用户自定义表函数 必须在使用前注册。

INNER JOIN

如果表函数调用返回一个空结果,那么左表的这行数据将不会输出。

SELECT order_id, res
FROM Orders,
LATERAL TABLE(table_func(order_id)) t(res)

这个Flink SQL查询的目标是从订单数据表中获取订单ID和通过自定义表函数根据订单ID计算得出的结果。

  • 首先,通过FROM子句指定了输入表Orders。
  • 然后,通过LATERAL TABLE子句调用了自定义的表函数table_func,并将订单ID作为参数传递给函数。表函数的作用是根据订单ID计算得出一个结果。
  • 接下来,在SELECT子句中选择了order_id和res这两个列,分别表示订单ID和通过表函数计算得到的结果。
  • 查询结果将返回订单ID和对应的表函数计算结果。

LEFT OUTER JOIN

如果表函数调用返回了一个空结果,则保留相应的行,并用空值填充未关联到的结果。当前,针对 lateral table 的 left outer join 需要 ON 子句中有一个固定的 TRUE 连接条件。

SELECT order_id, res
FROM Orders
LEFT OUTER JOIN LATERAL TABLE(table_func(order_id)) t(res)ON TRUE

这个Flink SQL查询的目标是从订单数据表中获取订单ID和通过自定义表函数根据订单ID计算得出的结果,并使用左外连接将计算结果与订单数据进行关联。

  • 首先,通过FROM子句指定了输入表Orders。
  • 然后,通过LATERAL TABLE子句调用了自定义的表函数table_func,并将订单ID作为参数传递给函数。表函数的作用是根据订单ID计算得出一个结果。
  • 接下来,使用LEFT OUTER JOIN关键字将计算结果与订单数据进行连接。使用ON TRUE来指定连接条件,这意味着对所有的订单都执行连接操作。
  • 最后,在SELECT子句中选择了order_id和res这两个列,分别表示订单ID和通过表函数计算得到的结果。
  • 查询结果将返回订单ID和对应的表函数计算结果,如果没有计算结果的话,会返回NULL值。

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

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

相关文章

【PHP入门】1.2-常量与变量

-常量与变量- PHP是一种动态网站开发的脚本语言&#xff0c;动态语言特点是交互性&#xff0c;会有数据的传递&#xff0c;而PHP作为“中间人”&#xff0c;需要进行数据的传递&#xff0c;传递的前提就是PHP能自己存储数据&#xff08;临时存储&#xff09; 1.2.1变量基本概…

微服务实战系列之ZooKeeper(下)

前言 通过前序两篇关于ZooKeeper的介绍和总结&#xff0c;我们可以大致理解了它是什么&#xff0c;它有哪些重要组成部分。 今天&#xff0c;博主特别介绍一下ZooKeeper的一个核心应用场景&#xff1a;分布式锁。 应用ZooKeeper Q&#xff1a;什么是分布式锁 首先了解一下&…

04 python函数

4.1 函数的快速开发体验 """ 演示&#xff0c;快速体验函数的开发和使用 """#需求&#xff0c;统计字符串的长度&#xff0c;不使用内置函数len()str1 itheima str2 itcast str3 python#定义一个计数的变量 count 0 for i in str1:count 1…

FPGA使用乘法的方式

FPGA使用乘法的方式 方法一:直接使用乘法符“*” 源代码 module multiply(input [7:0] a,input [7:0] b,output wire [15:0] result);(*use_dsp48 = "yes"*) wire [15:0] result;assign result = a*b; endmodule仿真代码 module multiply_tb();reg [7:0] a; re…

Python实验 —— 图形化编程入门案例

Python实验 —— 图形化编程 实验目的实验内容实验结果蟒蛇绘制程序计算Pi值树的绘制词频统计绘制艺术图 实验目的 &#xff08;1&#xff09;熟悉 PYTHON 的语法格式 &#xff08;2&#xff09;熟练使用集成开发环境 SPYDER 或者 PyCharm &#xff08;3&#xff09;熟练 PYTH…

java minio通过getPresignedObjectUrl设置(自定义)预签名URL下载文件的响应文件名之minio源码改造方案

Minio预签名URL自定义响应文件名之Minio源码改造 需求说明Minio源码改造一、环境准备二、下载Minio源代码三、修改源代码1.修改cmd目录下的api-router.go这个代码文件2.将filename参数值设置到响应头4.修改验证签名时是否需要带入filename参数验证 四、大功告成&#xff0c;编译…

残差网络中的BN (Batch Normalization 批标准化层)的作用是什么?

文章目录 什么是BN &#xff08;Batch Normalization 批标准化层&#xff09;一、BN层对输入信号进行以下操作:二、BN 层有什么作用&#xff1f; 什么是BN &#xff08;Batch Normalization 批标准化层&#xff09; BN层的全称是Batch Normalization层,中文可以翻译为批标准化…

如何让.NET应用使用更大的内存

我一直在思考为何Redis这种应用就能独占那么大的内存空间而我开发的应用为何只有4GB大小左右&#xff0c;在此基础上也问了一些大佬&#xff0c;最终还是验证下自己的猜测。 操作系统限制 主要为32位操作系统和64位操作系统。 每个进程自身还分为了用户进程空间和内核进程空…

【C语言】7-55 分寝室 分数 20

7-55 分寝室 分数 20 全屏浏览题目 切换布局 作者 陈越 单位 浙江大学 学校新建了宿舍楼&#xff0c;共有 n 间寝室。等待分配的学生中&#xff0c;有女生 n0​ 位、男生 n1​ 位。所有待分配的学生都必须分到一间寝室。所有的寝室都要分出去&#xff0c;最后不能有寝室留空…

Mybatis-Spring整合原理:MapperFactoryBean和MapperScannerConfigurer的区别及源码剖析

文章目录 引言MapperFactoryBean的用法和优缺点MapperScannerConfigurer的用法和优缺点MapperFactoryBean源码分析MapperScannerConfigurer源码分析Spring容器初始化流程回顾核心方法&#xff1a;postProcessBeanDefinitionRegistryBeanDefinitionRegistryPostProcessor和BeanF…

Java 并发编程(六)-Fork/Join异步回调

一、并发编程 1、Fork/Join分支合并框架 Fork/Join它可以将一个大的任务拆分成多个子任务进行并行处理&#xff0c;最后将子任务结果合并成最后的计算结果&#xff0c;并进行输出。Fork/Join框架要完成两件事情&#xff1a; Fork&#xff1a;把一个复杂任务进行分拆&#xff0…

BP神经网络原理,基于BP神经网络的去噪算法,基于BP神经网络的调制信号去噪

目录 BP神经网络的原理 BP神经网络的定义 BP神经网络的基本结构 BP神经网络的神经元 BP神经网络的激活函数, BP神经网络的传递函数 遗传算法原理 遗传算法主要参数 遗传算法流程图 完整代码包含数据下载链接: 基于BP神经网络的去噪算法,基于BP神经网络的调制信号去噪(代码…

下午好~ 我的论文【CV边角料】(第三期)

文章目录 CV边角料Pixel ShuffleSENetCBAMGlobal Context Block (GC)Criss-Cross Attention modules (CC) CV边角料 Pixel Shuffle Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural Network pixelshuffle算法的实现流…

EXCEL SUM类函数

目录 一. SUM二. SUMIF三. SUMIFS四. SUMPRODUCT 一. SUM ⏹对一列或一组单元格中的数字进行求和。 基本语法 SUM(number1, [number2], ...)✅统计所有产品的总数量 SUM(C2:C13) 二. SUMIF ⏹按照特定条件对范围内的单元格进行求和的函数。 基本语法 SUMIF(条件区域, 指定…

山西电力市场日前价格预测【2023-12-16】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-12-16&#xff09;山西电力市场全天平均日前电价为259.00元/MWh。其中&#xff0c;最高日前电价为333.74元/MWh&#xff0c;预计出现在18:00。最低日前电价为0.00元/MWh&#xff0c;预计出…

Golang 二分查找 LEETCODE704 小记

二分查找 leetcode704 前面部分第4题&#xff0c;包括使用条件等感谢代码随想录&#xff1a;&#xff09; leetcode704 二分查找用于在有序且不重复的元素列表中寻找需要的元素&#xff0c;返回其位置或错误 当要求算法的时间复杂度在O&#xff08;logn) 等带log的复杂度时&am…

C语言训练:三个字符串比较大小,实现两个整数数的交换统计二进制中1的个数

目录 一、编写程序&#xff0c;输入三个字符串&#xff0c;比较它们的大小&#xff0c;并将它们按由小到大的顺序输出。要求用函数、指针实现。要求:要采用函数调用&#xff0c;并用指向函数的指针作为函数的参数。 1.不使用函数指针作为参数&#xff0c;并自己模拟strcmp。 …

Flume 安装与部署

目录 Flume 下载地址 &#xff08;1&#xff09;将 apache-flume-1.9.0-bin.tar.gz 上传到 linux 的 /opt/software 目录下 &#xff08;2&#xff09;解压 apache-flume-1.9.0-bin.tar.gz 到 /opt/module/ 目录下 huweihadoop101 ~]$ tar -zxvf /opt/software/apache-flume-…

001 Windows虚拟机

一、虚拟机安装Windows10 选自定义安装 升级是针对你电脑上有系统的情况下&#xff0c;你要升级&#xff1b;没有系统就选择自定义。 硬盘60G 直接单击下一步就是一个盘 如果你想对磁盘进行分区 分第一个区的时候它会去创建系统的保留分区和系统分区&#xff0c;然后还剩20…

acwing算法提高之动态规划--状态压缩DP

目录 1 基础知识2 模板3 工程化 1 基础知识 暂无。。。 2 模板 暂无。。。 3 工程化 题目1&#xff1a;小国王。 解题思路&#xff1a;状态压缩DP。 状态定义f[i][j][a]&#xff1a;表示已经考虑了前i行&#xff0c;并且摆放了j个国王&#xff0c;且第i行的状态是a的总方…