Flink系列之:SQL提示

news2024/11/14 18:46:58

Flink系列之:SQL提示

  • 一、动态表选项
  • 二、语法
  • 三、例子
  • 四、查询提示
  • 五、句法
  • 六、加入提示
  • 七、播送
  • 八、随机散列
  • 九、随机合并
  • 十、嵌套循环
  • 十一、LOOKUP
  • 十二、进一步说明
  • 十三、故障排除
  • 十四、连接提示中的冲突案例
  • 十五、什么是查询块

SQL 提示可以与 SQL 语句一起使用来更改执行计划。本章解释如何使用提示来强制执行各种方法。

一般来说,提示可用于:

  • 执行计划器:没有完美的计划器,因此实现提示以让用户更好地控制执行是有意义的;
  • 附加元数据(或统计信息):一些统计信息,例如“扫描的表索引”和“某些洗牌键的倾斜信息”对于查询来说有些动态,使用提示配置它们会非常方便,因为我们来自规划器的规划元数据很多时候并不那么准确;
  • 算子资源限制:在很多情况下,我们会给执行算子一个默认的资源配置,即最小并行度或托管内存(资源消耗UDF)或特殊资源要求(GPU或SSD磁盘)等等,这将非常灵活使用每个查询的提示(而不是作业)来分析资源。

一、动态表选项

动态表选项允许动态指定或覆盖表选项,与使用 SQL DDL 或连接 API 定义的静态表选项不同,这些选项可以在每个查询的每个表范围内灵活指定。

因此它非常适合用于交互式终端中的临时查询,例如,在 SQL-CLI 中,您可以通过添加动态选项 /*+ OPTIONS(’ 来指定忽略 CSV 源的解析错误csv.ignore-parse-errors’=‘true’) */。

二、语法

为了不破坏SQL兼容性,我们使用Oracle风格的SQL提示语法:

table_path /*+ OPTIONS(key=val [, key=val]*) */

key:
    stringLiteral
val:
    stringLiteral

三、例子

CREATE TABLE kafka_table1 (id BIGINT, name STRING, age INT) WITH (...);
CREATE TABLE kafka_table2 (id BIGINT, name STRING, age INT) WITH (...);

-- 覆盖查询源中的表选项
select id, name from kafka_table1 /*+ OPTIONS('scan.startup.mode'='earliest-offset') */;

-- 覆盖连接中的表选项
select * from
    kafka_table1 /*+ OPTIONS('scan.startup.mode'='earliest-offset') */ t1
    join
    kafka_table2 /*+ OPTIONS('scan.startup.mode'='earliest-offset') */ t2
    on t1.id = t2.id;

-- 覆盖 INSERT 目标表的表选项
insert into kafka_table1 /*+ OPTIONS('sink.partitioner'='round-robin') */ select * from kafka_table2;

四、查询提示

查询提示可用于建议优化器影响指定查询范围内的查询执行计划。它们的有效范围是指定查询提示的当前查询块(什么是查询块?)。现在,Flink Query Hints 仅支持 Join Hints。

五、句法

Flink 中的查询提示语法遵循 Apache Calcite 中的查询提示语法:

# Query Hints:
SELECT /*+ hint [, hint ] */ ...

hint:
        hintName
    |   hintName '(' optionKey '=' optionVal [, optionKey '=' optionVal ]* ')'
    |   hintName '(' hintOption [, hintOption ]* ')'

optionKey:
        simpleIdentifier
    |   stringLiteral

optionVal:
        stringLiteral

hintOption:
        simpleIdentifier
    |   numericLiteral
    |   stringLiteral

六、加入提示

连接提示允许用户向优化器建议连接策略,以获得更高性能的执行计划。现在 Flink Join Hints 支持 BROADCAST、SHUFFLE_HASH、SHUFFLE_MERGE 和 NEST_LOOP。

笔记:

  • 连接提示中指定的表必须存在。否则,将抛出表不存在错误。
  • Flink Join Hints 只支持一个查询块中包含一个提示块,如果指定多个提示块,如 /*+ BROADCAST(t1) / /+ SHUFFLE_HASH(t1) */,则解析该查询语句时会抛出异常。
  • 在一个提示块中,在单个连接提示中指定多个表,例如 /*+ BROADCAST(t1, t2, …, tn) / 或指定多个连接提示,例如 /+ BROADCAST(t1), BROADCAST(t2), …、BROADCAST(tn) */ 均受支持。
  • 对于单个 Join Hints 中的多个表或一个hint 块中的多个 Join Hints,Flink Join Hints 可能会发生冲突。如果发生冲突,Flink 将选择最匹配的表或连接策略。 (参见:连接提示中的冲突案例)

七、播送

BROADCAST 建议 Flink 使用 BroadCast join。无论table.optimizer.join.broadcast-threshold如何,带有hint的join端都会被广播,因此当表的hint端数据量很小时,它表现良好。

注意:BROADCAST 仅支持等价连接条件的连接,不支持 Full Outer Join。

例子:

CREATE TABLE t1 (id BIGINT, name STRING, age INT) WITH (...);
CREATE TABLE t2 (id BIGINT, name STRING, age INT) WITH (...);
CREATE TABLE t3 (id BIGINT, name STRING, age INT) WITH (...);

-- Flink 将使用广播连接,t1 将是广播表。
SELECT /*+ BROADCAST(t1) */ * FROM t1 JOIN t2 ON t1.id = t2.id;

-- Flink 将使用广播连接来进行连接,并且 t1、t3 将是广播表。
SELECT /*+ BROADCAST(t1, t3) */ * FROM t1 JOIN t2 ON t1.id = t2.id JOIN t3 ON t1.id = t3.id;

-- BROADCAST 不支持非等价连接条件。
-- Join Hint 将不起作用,并且只能应用嵌套循环连接。
SELECT /*+ BROADCAST(t1) */ * FROM t1 join t2 ON t1.id > t2.id;

-- BROADCAST 不支持完全外连接。
-- 这种情况下Join Hint不起作用,规划器会根据成本选择合适的Join策略。
SELECT /*+ BROADCAST(t1) */ * FROM t1 FULL OUTER JOIN t2 ON t1.id = t2.id;

八、随机散列

SHUFFLE_HASH建议Flink使用Shuffle Hash join。带hint的join端将是join构建端,当表的hint端数据量不太大时,它表现良好。

注意:SHUFFLE_HASH 仅支持等价连接条件的连接。

例子:

CREATE TABLE t1 (id BIGINT, name STRING, age INT) WITH (...);
CREATE TABLE t2 (id BIGINT, name STRING, age INT) WITH (...);
CREATE TABLE t3 (id BIGINT, name STRING, age INT) WITH (...);

-- Flink 将使用哈希连接,t1 将作为构建端。
SELECT /*+ SHUFFLE_HASH(t1) */ * FROM t1 JOIN t2 ON t1.id = t2.id;

-- Flink 将使用 hash join 进行连接,t1、t3 将作为连接构建端。
SELECT /*+ SHUFFLE_HASH(t1, t3) */ * FROM t1 JOIN t2 ON t1.id = t2.id JOIN t3 ON t1.id = t3.id;

-- SHUFFLE_HASH 不支持非等价连接条件。
-- 对于这种情况,Join Hint 将不起作用,只能应用嵌套循环连接。
SELECT /*+ SHUFFLE_HASH(t1) */ * FROM t1 join t2 ON t1.id > t2.id;

九、随机合并

SHUFFLE_MERGE 建议 Flink 使用 Sort Merge join。这种类型的Join Hint推荐用于两个大表之间的Join场景或者Join两边的数据都已经有序的场景。

注意:SHUFFLE_MERGE 仅支持具有等价连接条件的连接。

例子:

CREATE TABLE t1 (id BIGINT, name STRING, age INT) WITH (...);
CREATE TABLE t2 (id BIGINT, name STRING, age INT) WITH (...);
CREATE TABLE t3 (id BIGINT, name STRING, age INT) WITH (...);

-- 采用排序合并连接策略。
SELECT /*+ SHUFFLE_MERGE(t1) */ * FROM t1 JOIN t2 ON t1.id = t2.id;

-- 这两种连接均采用排序合并连接策略。
SELECT /*+ SHUFFLE_MERGE(t1, t3) */ * FROM t1 JOIN t2 ON t1.id = t2.id JOIN t3 ON t1.id = t3.id;

-- SHUFFLE_MERGE don't support non-equivalent join conditions.
-- Join Hint will not work, and only nested loop join can be applied.
SELECT /*+ SHUFFLE_MERGE(t1) */ * FROM t1 join t2 ON t1.id > t2.id;

– SHUFFLE_MERGE 不支持非等价连接条件。
– Join Hint 将不起作用,并且只能应用嵌套循环连接。

十、嵌套循环

NEST_LOOP 建议 Flink 使用 Nested Loop join。如果没有特殊场景需求,不建议使用此类连接提示。

注意:NEST_LOOP 支持等效和非等效连接条件。

例子:

CREATE TABLE t1 (id BIGINT, name STRING, age INT) WITH (...);
CREATE TABLE t2 (id BIGINT, name STRING, age INT) WITH (...);
CREATE TABLE t3 (id BIGINT, name STRING, age INT) WITH (...);

-- Flink 将使用嵌套循环连接,t1 将作为构建端。
SELECT /*+ NEST_LOOP(t1) */ * FROM t1 JOIN t2 ON t1.id = t2.id;

-- Flink 将使用嵌套循环连接来进行连接,t1、t3 将是连接构建端。
SELECT /*+ NEST_LOOP(t1, t3) */ * FROM t1 JOIN t2 ON t1.id = t2.id JOIN t3 ON t1.id = t3.id;

十一、LOOKUP

LOOKUP 提示允许用户建议 Flink 优化器:

  • 使用同步(sync)或异步(async)查找功能
  • 配置异步参数
  • 启用查找的延迟重试策略

查找提示选项:

在这里插入图片描述
笔记:

  • 'table’选项为必填项,仅支持表名(与FROM子句中的保持一致),注意如果表有别名,则只能使用别名。
  • async选项都是可选的,如果没有配置将使用默认值。
    重试选项没有默认值,需要启用重试时,所有重试选项都应设置为有效值。

1.使用同步和异步查找功能#
如果连接器同时具有异步和同步查找功能,则用户可以指定选项值“async”=“false”以建议规划器使用同步查找或“async”=“true”以使用异步查找:

例子:

-- suggest the optimizer to use sync lookup
LOOKUP('table'='Customers', 'async'='false')

-- suggest the optimizer to use async lookup
LOOKUP('table'='Customers', 'async'='true')

注意:如果未指定“async”选项,优化器更喜欢异步查找,在以下情况下它将始终使用同步查找:

  • 连接器仅实现同步查找
  • 用户启用“table.optimizer.non-definistic-update.strategy”的“TRY_RESOLVE”模式,并且优化器已检查是否存在由非确定性更新引起的正确性问题。
  1. 配置异步参数 #
    用户可以通过异步查找模式下的异步选项配置异步参数。

例子:

-- configure the async parameters: 'output-mode', 'capacity', 'timeout', can set single one or multi params
LOOKUP('table'='Customers', 'async'='true', 'output-mode'='allow_unordered', 'capacity'='100', 'timeout'='180s')

注意:异步选项与作业级别执行选项中的异步选项一致,如果不设置将使用作业级别配置。另一个区别是LOOKUP提示的范围更小,仅限于当前查找操作中设置的提示选项对应的表名(其他查找操作不会受到LOOKUP提示的影响)。

例如,如果作业级别配置是:

table.exec.async-lookup.output-mode: ORDERED
table.exec.async-lookup.buffer-capacity: 100
table.exec.async-lookup.timeout: 180s

然后出现以下提示:

1. LOOKUP('table'='Customers', 'async'='true', 'output-mode'='allow_unordered')
2. LOOKUP('table'='Customers', 'async'='true', 'timeout'='300s')

相当于:

3. LOOKUP('table'='Customers', 'async'='true', 'output-mode'='allow_unordered', 'capacity'='100', 'timeout'='180s')
4. LOOKUP('table'='Customers', 'async'='true', 'output-mode'='ordered', 'capacity'='100', 'timeout'='300s')
  1. 启用查找延迟重试策略 #
    查找连接的延迟重试旨在解决外部系统延迟更新导致流数据意外丰富的问题​​。提示选项’retry-predicate’='lookup_miss’可以启用同步和异步查找重试,目前仅支持固定延迟重试策略。

固定延迟重试策略选项:

'retry-strategy'='fixed_delay'
-- fixed delay duration
'fixed-delay'='10s'
-- max number of retry(counting from the retry operation, if set to '1', then a single lookup process
-- for a specific lookup key will actually execute up to 2 lookup requests)
'max-attempts'='3'

例子:

1.启用异步查找重试

LOOKUP('table'='Customers', 'async'='true', 'retry-predicate'='lookup_miss', 'retry-strategy'='fixed_delay', 'fixed-delay'='10s','max-attempts'='3')

2.启用同步查找重试

LOOKUP('table'='Customers', 'async'='false', 'retry-predicate'='lookup_miss', 'retry-strategy'='fixed_delay', 'fixed-delay'='10s','max-attempts'='3')

如果查找源只有一种功能,则可以省略“异步”模式选项:

LOOKUP('table'='Customers', 'retry-predicate'='lookup_miss', 'retry-strategy'='fixed_delay', 'fixed-delay'='10s','max-attempts'='3')

十二、进一步说明

启用缓存对重试的影响

FLIP-221 增加了对查找源的缓存支持,有 PARTIAL 和 FULL 缓存模式(NONE 模式表示禁用缓存)。当启用完整缓存时,根本不会重试(因为通过查找源的完整缓存镜像重试查找是没有意义的)。当启用 PARTIAL 缓存时,它将首先从本地缓存查找即将到来的记录,如果缓存未命中,将通过后端连接器进行外部查找(如果缓存命中,则立即返回记录),这将在查找结果时触发重试为空(与禁用缓存相同),重试完成时确定最终查找结果(在PARTIAL缓存模式下,也会更新本地缓存)。

关于查找键和‘retry-predicate’=‘lookup_miss’重试条件的注意事项

对于不同的连接器,索引查找能力可能会有所不同,例如内置的HBase连接器只能在rowkey上查找(没有二级索引),而内置的JDBC连接器可以提供更强大的任意列的索引查找能力,这是由不同的连接器决定的。物理存储。这里提到的查找键是索引查找的字段或字段组合,以查找连接为例,其中c.id是连接条件“ON o.customer_id = c.id”的查找键:

SELECT o.order_id, o.total, c.country, c.zip
FROM Orders AS o
  JOIN Customers FOR SYSTEM_TIME AS OF o.proc_time AS c
    ON o.customer_id = c.id

如果我们将连接条件更改为“ON o.customer_id = c.id and c.country = ‘US’”:

SELECT o.order_id, o.total, c.country, c.zip
FROM Orders AS o
  JOIN Customers FOR SYSTEM_TIME AS OF o.proc_time AS c
    ON o.customer_id = c.id and c.country = 'US'

当 Customers 表存储在 MySql 中时,c.id 和 c.country 都将用作查找键:

CREATE TEMPORARY TABLE Customers (
  id INT,
  name STRING,
  country STRING,
  zip STRING
) WITH (
  'connector' = 'jdbc',
  'url' = 'jdbc:mysql://mysqlhost:3306/customerdb',
  'table-name' = 'customers'
)

当Customers表存储在HBase中时,只有c.id可以作为查找键,其余连接条件c.country = 'US’将在查找结果返回后进行评估

CREATE TEMPORARY TABLE Customers (
  id INT,
  name STRING,
  country STRING,
  zip STRING,
  PRIMARY KEY (id) NOT ENFORCED
) WITH (
  'connector' = 'hbase-2.2',
  ...
)

因此,当启用“lookup_miss”重试谓词和固定延迟重试策略时,上述查询将对不同存储产生不同的重试效果。

例如,如果 Customers 表中有一行:

id=100, country='CN'

在处理订单流中id=100的记录时,在jdbc连接器中,对应的查找结果为空(country='CN’不满足条件c.country = ‘US’),因为c.country=‘US’。 id 和 c.country 用作查找键,因此这将触发重试。

当在’hbase’连接器中时,仅使用c.id作为查找键,相应的查找结果不会为空(会返回记录id=100,country=‘CN’),因此不会触发重试(对于返回的记录,剩余的连接条件 c.country = ‘US’ 将被评估为不正确)。

目前基于SQL语义考虑,只提供了lookup_miss重试谓词,当需要等待维度表的延迟更新时(表中已经存在而不是不存在历史版本记录),用户可以使用可以尝试两种解决方案:

  • 使用 DataStream Async I/O 中新的重试支持实现自定义重试谓词(允许对返回的记录进行更复杂的判断)。
  • 通过添加另一个连接条件(包括比较由时间戳生成的某种数据版本)来启用延迟重试,对于上面的示例,假设 Customers 表每小时更新一次,我们可以添加一个新的与时间相关的版本字段 update_version,该字段保留为每小时精度,例如,记录的更新时间“2022-08-15 12:01:02”会将 update_version 存储为“2022-08-15 12:00”
CREATE TEMPORARY TABLE Customers (
  id INT,
  name STRING,
  country STRING,
  zip STRING,
  -- the newly added time-dependent version field
  update_version STRING
) WITH (
  'connector' = 'jdbc',
  'url' = 'jdbc:mysql://mysqlhost:3306/customerdb',
  'table-name' = 'customers'
)

将 Order 流的时间字段和 Customers.update_version 上的相等条件附加到连接条件:

ON o.customer_id = c.id AND DATE_FORMAT(o.order_timestamp, 'yyyy-MM-dd HH:mm') = c.update_version

那么当Order的记录无法在Customers表中查找到‘12:00’版本的新记录时,我们可以启用延迟重试。

十三、故障排除

当开启延迟重试查找时,查找节点更有可能遇到背压问题,这可以通过Web ui“任务管理器”页面上的“线程转储”快速确认。分别从异步和同步查找中,线程睡眠的调用堆栈将出现在:

  • 异步查找:RetryableAsyncLookupFunctionDelegator
  • 同步查找:RetryableLookupFunctionDelegator

笔记:

  • 带重试的异步查找无法对所有输入数据进行固定延迟处理(应使用其他较轻的方法来解决,例如挂起的源消耗或使用带重试的同步查找)
  • 同步查找中延迟等待重试执行是完全同步的,即,直到当前记录完成后才开始处理下一条记录。
  • 在异步查找中,如果“output-mode”为“ORDERED”模式,则延迟重试导致背压的概率可能高于“UNORDERED”模式,在这种情况下,增加异步“容量”可能无法有效减少背压,并且可能有必要考虑缩短延迟时间。

十四、连接提示中的冲突案例

如果 Join Hints 发生冲突,Flink 会选择最匹配的一个。

  • 如果同一个Join Hint策略发生冲突,Flink会选择第一个匹配的表进行Join。
  • 当不同的Join Hints策略发生冲突时,Flink会选择第一个匹配的hint进行Join。

例子:

CREATE TABLE t1 (id BIGINT, name STRING, age INT) WITH (...);
CREATE TABLE t2 (id BIGINT, name STRING, age INT) WITH (...);
CREATE TABLE t3 (id BIGINT, name STRING, age INT) WITH (...);

-- Conflict in One Same Join Hints Strategy Case

-- The first hint will be chosen, t2 will be the broadcast table.
SELECT /*+ BROADCAST(t2), BROADCAST(t1) */ * FROM t1 JOIN t2 ON t1.id = t2.id;

-- BROADCAST(t2, t1) will be chosen, and t2 will be the broadcast table.
SELECT /*+ BROADCAST(t2, t1), BROADCAST(t1, t2) */ * FROM t1 JOIN t2 ON t1.id = t2.id;

-- This case equals to BROADCAST(t1, t2) + BROADCAST(t3),
-- when join between t1 and t2, t1 will be the broadcast table,
-- when join between the result after t1 join t2 and t3, t3 will be the broadcast table.
SELECT /*+ BROADCAST(t1, t2, t3) */ * FROM t1 JOIN t2 ON t1.id = t2.id JOIN t3 ON t1.id = t3.id;


-- Conflict in Different Join Hints Strategies Case

-- The first Join Hint (BROADCAST(t1)) will be chosen, and t1 will be the broadcast table.
SELECT /*+ BROADCAST(t1) SHUFFLE_HASH(t1) */ * FROM t1 JOIN t2 ON t1.id = t2.id;

-- Although BROADCAST is first one hint, but it doesn't support full outer join,
-- so the following SHUFFLE_HASH(t1) will be chosen, and t1 will be the join build side.
SELECT /*+ BROADCAST(t1) SHUFFLE_HASH(t1) */ * FROM t1 FULL OUTER JOIN t2 ON t1.id = t2.id;

-- Although there are two Join Hints were defined, but all of them are neither support non-equivalent join,
-- so only nested loop join can be applied.
SELECT /*+ BROADCAST(t1) SHUFFLE_HASH(t1) */ * FROM t1 FULL OUTER JOIN t2 ON t1.id > t2.id;

十五、什么是查询块

查询块是SQL的基本单元。例如,任何内联视图或 SQL 语句的子查询都被视为与外部查询不同的查询块。

例子:
一条 SQL 语句可以由多个子查询组成。子查询可以是 SELECT、INSERT 或 DELETE。子查询可以在 FROM 子句、WHERE 子句或 UNION 或 UNION ALL 的子查询中包含其他子查询。

对于这些不同的子查询或视图类型,它们可以由多个查询块组成,例如:

下面的简单查询只有一个子查询,但它有两个查询块 - 一个用于外部 SELECT,另一个用于子查询 SELECT。

在这里插入图片描述
下面的查询是一个联合查询,它包含两个查询块 - 一个用于第一个 SELECT,另一个用于第二个 SELECT。

在这里插入图片描述
下面的查询包含一个视图,它有两个查询块 - 一个用于外部 SELECT,另一个用于视图。

在这里插入图片描述

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

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

相关文章

MyBatis Plus 大数据量查询优化

大数据量操作的场景大致如下: 数据迁移 数据导出 批量处理数据 在实际工作中当指定查询数据过大时,我们一般使用分页查询的方式一页一页的将数据放到内存处理。但有些情况不需要分页的方式查询数据或分很大一页查询数据时,如果一下子将数…

【单元测试】Junit 4--junit4 内置Rule

1.0 Rules ​ Rules允许非常灵活地添加或重新定义一个测试类中每个测试方法的行为。测试人员可以重复使用或扩展下面提供的Rules之一,或编写自己的Rules。 1.1 TestName ​ TestName Rule使当前的测试名称在测试方法中可用。用于在测试执行过程中获取测试方法名称…

MATLAB 计算两片点云间的最小距离(2种方法) (39)

MATLAB 计算两片点云间的最小距离 (39) 一、算法介绍二、算法实现1.常规计算方法2.基于KD树的快速计算一、算法介绍 假设我们现在有两片点云 1 和 2 ,需要计算二者之间的最小距离,这里提供两种计算方法,分别是常规计算和基于KD树近邻搜索的快速计算方法,使用的测试数据如…

Java 分布式框架 —— Dubbo 快速入门

1 分布式系统中的相关概念 1.1 大型互联网项目架构目标 传统项目和互联网项目 传统项目:例如 OA、HR、CRM 等,服务对象为:企业员工 互联网项目:天猫、微信、百度等,服务对象为:全体网民 互联网项目特点…

2 使用postman进行接口测试

上一篇:1 接口测试介绍-CSDN博客 拿到开发提供的接口文档后,结合需求文档开始做接口测试用例设计,下面用最常见也最简单的注册功能介绍整个流程。 说明:以演示接口测试流程为主,不对演示功能做详细的测试,…

JVM学习之JVM概述

JVM的整体结构 Hotspot VM是目前市面上高性能虚拟机代表作之一 它采用解释器与即时编译器并存的架构 在今天,Java程序的运行性能已经达到了可以和C/C程序一较高下的地步 Java代码执行流程 具体图为 JVM架构模型 Java编译器输入的指令流基本上是一种基于 栈的指令…

drf入门规范

一 Web应用模式 在开发Web应用中,有两种应用模式: 1.1 前后端不分离 1.2 前后端分离 二 API接口 为了在团队内部形成共识、防止个人习惯差异引起的混乱,我们需要找到一种大家都觉得很好的接口实现规范,而且这种规范能够让后端写…

【MySQL内置函数】

目录: 前言一、日期函数获取日期获取时间获取时间戳在日期上增加时间在日期上减去时间计算两个日期相差多少天当前时间案例:留言板 二、字符串函数查看字符串字符集字符串连接查找字符串大小写转换子串提取字符串长度字符串替换字符串比较消除左右空格案…

79.55 Gbps!已经初步测得VMWare ESXi 6.7的vSwitch转发性能

正文共:1234 字 14 图,预估阅读时间:1 分钟 在前面的文章中,我们提到了测试主要分为3个内容: 一是测试iperf和iperf3两个工具的实用性,目前的结论是iperf可以支持多CPU、多线程,整体测试结果比i…

Linux——进程创建与进程终止

📘北尘_:个人主页 🌎个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上,不忘来时的初心 文章目录 一、进程创建1、fork函数初识2、fork函数返回值3、写时拷贝4、fork常规用法5、fork调用失败的…

Java从properties文件读取内容

例如,项目文件布局: test.properties文件的内容为: name thb pass 223355主类文件: package com.thb;import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileNotFoundException; import java…

Java数据结构篇——单链表的基本操作

1. 前言 在上一篇《Java数据结构篇——实现顺序表的增删查改》,我们已经熟悉了 ArrayList 的使用并且进行了简单的模拟实现。ArrayList底层使用数组来存储元素,由于其底层是一段连续的空间,当ArrayList 任意位置插入或者删除元素时&#xff…

紫光展锐T820与飞桨完成I级兼容性测试 助推端侧AI融合创新

近日,紫光展锐高性能5G SoC T820与百度飞桨完成I级兼容性测试(基于Paddle Lite工具)。测试结果显示,双方兼容性表现良好,整体运行稳定。这是紫光展锐加入百度“硬件生态共创计划”后的阶段性成果。 本次I级兼容性测试完…

2023年最详细的:本地Linux服务器安装宝塔面板,并内网穿透实现公网远程登录

📚📚 🏅我是默,一个在CSDN分享笔记的博主。📚📚 ​​ 🌟在这里,我要推荐给大家我的专栏《Linux》。🎯🎯 🚀无论你是编程小白,还是有一…

linux环境安装可操作图库语言Gremlin的图框架HugeGraph

原创/朱季谦 若你还没接触过图数据库,可能看到这个概念时,会比较蒙蔽。 图是什么?图数据库又是什么? 首先,在数据结构中,图是一种由顶点(vertex)集合及顶点间关系集合组成的一种非…

配电房环境监测模块

配电房环境监测模块是一个智能系统,依托电易云-智慧电力物联网平台,旨在实时监控配电房内部的环境参数,以确保配电设备的正常运行。该模块包括以下功能: 温度监测:对配电房内的温度进行实时监测,防止因温度…

【linux】Debian不能运行sudo的解决

一、问题: sudo: 没有找到有效的 sudoers 资源,退出 sudo: 初始化审计插件 sudoers_audit 出错 二、可用的方法: 出现 "sudo: 没有找到有效的 sudoers 资源,退出" 和 "sudo: 初始化审计插件 sudoers_audit 出错&q…

鸿蒙开发编辑器设置

首先需要知道如何打开设置页面,以下所有设置都需要在设置界面中进行修改,有三种方式可以打开, 1、编辑器左上角file菜单下的Setting菜单。 2、编辑器右上角的设置按钮 3、按快捷键 ctrlalts 注意不要和其他软件案件重复。 一、设置每次打开…

《Kotlin核心编程》笔记:反射、注解和加锁

Kotlin 和 Java 反射 1)Kotlin 的 KClass 和 Java 的 Class 可以看作同一个含义的类型,并且可以通过.java和.kotlin方法在KClass和Class之间互相转化。2)Kotlin 的 KCallable 和 Java 的 AccessiableObject 都可以理解为可调用元素。Java 中构…

【Database】什么是数据库?常见的数据库类型有哪些?

什么是数据库?常见的数据库类型有哪些? 首先,什么是数据库?把它想象成一个数字游乐场,我们以结构化的方式组织和存储大量信息。现在,让我们来谈谈数据库的主要类型。 关系型数据库: 想象一下…