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

Dinky 和 Flink CDC 在实时整库同步的探索之路

摘要:本文整理自 Dinky 社区负责人,Apache Flink CDC contributor 亓文凯老师在 Flink Forward Asia 2024 数据集成(二)专场中的分享。主要讲述 Dinky 的整库同步技术方案演变至 Flink CDC Yaml 作业的探索历程,并深入讲解Flink CDC Yaml的一些细节能力。其主要分为三个部分:

1、起源

2、探索

3、未来

01.起源

1.1 数据集成的背景

本次分享围绕数据集成,它也是 Flink CDC Yaml 作业的出现背景。在 Dinky 的众多用户中,我们总结出以下在传统的数据集成方案中普遍会遇到的问题:需要将业务库中的业务数据同步到分析库中,起到解耦分析的作用,一般有三点要求。要求数据必须一致、链路要求稳定、数据时效性尽可能要高。

1.2 传统数据集成方案

在传统的数据集成方案中可以通过离线和实时两条链路进行,离线通常会选择开源的方案 DataX 或 Sqoop 来做一些快照同步,实时方案会根据数据库类型进行选择,例如 Mysql 数据库采用 Debezium 或 Canal 实现增量同步,但是最终在分析库中是两种表的存在形式。需要在下一步数据加工治理过程中先将快照表和增量表合并为一张表,才能进行完整的一个统计分析。这样会造成一个影响:全量和增量割裂,并且使用到的技术组件和链路较长,导致整体的数据时效性偏低。

1.3 Flink CDC 数据集成方案

Flink CDC 自发布以来,其中 2.0 版本带来了重大更新,尤其是增量快照方法。可以将数据库中的全量数据和增量实时数据合并,保证数据的一致性。其次采用 Flink CDC 时可以不需要部署 Debezium 或 Kafka 等其他组件,只需要 Flink CDC 一个组件就可以完成从业务库到分析库的实时一致性快照的同步。数据链路缩短,数据时效性比传统的方案高。

1.4 数据集成面临的挑战——整库同步

在去年经常会遇到一个场景:Flink CDC 在大面积使用的情况下,业务比较多,分析需求会逐步增长,所以构建了一个整库同步的作业,将业务库中的全部表或部分表同步到分析库中。以往在技术瓶颈的限制下,开发方式是通过 Flink CDC 的 SQL 来完成对每一张表的处理。例如源库中有一千张表,可能就需要开发一千个 Flink SQL 的作业,每一个作业会建立一个单独的数据源连接,会消耗额外的连接数,Binlog 也会重复读取。整个过程中会产生大量的 Flink 流作业,导致 Flink 集群越来越难以运维。这是遇到的第一个挑战。

1.5 数据集成面临的挑战——模式演变

第二个挑战是模式演变的问题。业务库如果发生表结构变更,下游分析库无法感知到。如果下游库无法感知进行同步变更,此时数据链路仍然在进行同步,就会丢失一些新增的数据信息。例如增加了一个 age 列,如果下游库没有同步更新表结构就会丢失最新列的一些数据。

1.6 用户渴望——端到端数据集成

用户所渴望的是可以有全增量的自动切换、元数据可以自动发现、表结构可以自动同步、整库同步只需要一个链接一个作业、在开发过程中只需一个 SQL 完成。

02.探索

2.1整库同步的探索之路

先介绍一下 Dinky。Dinky 是一个以 Apache Flink 为内核构建的开源实时计算平台,具备实时应用的作业开发、数据调试及运行监控能力,助力实时计算高效应用。

2.2 Dinky的介绍

Dinky 可以连接众多的开源框架,例如 Paimon、Hudi、Iceberg 等其它数据库和数据湖。Dinky 主要有两个核心能力,第一是实时计算 IDE,可以对 Flink 作业、Flink SQL 和整库同步作业进行调试,在 IDE 界面上实时展现任务的流数据,便于排查数据问题。第二是提供实时运维的能力,将 Flink 集群进行统一管理,可以对任务进行实时监控,触发自定义的告警规则时,进行多渠道的告警通知。

2.3 Dinky基于Flink CDC的整库同步探索

对于整库同步,Dinky 还提供 CDC Source 的方案。此分享将对两个方案进行对比。

Dinky 在实现 Flink CDC 整库同步的探索上,通过实现一个 EXECUTE CDCSOURCE 的语法,让用户通过正则表达式等其他配置来完成整库同步任务的定义,来实现全增量自动切换、元数据自动发现、结构变更自动同步、只用一个库连接、一句 SQL 部署作业。此外,还支持写入各种数据源、支持各种部署模式,这些额外能力在一定程度上缓解了 Flink CDC 在各种连接器 Source 和 Sink 上的不足。

2.4 Dinky CDC Source 整库同步数据链路

Dinky CDC Source 整库同步数据链路分析如下。在分库分表的场景下,由 Source 节点将 Binlog 日志解析成 Debezium 格式的 Json,将 Json 数据按表名和主键进行分区,来支持下游多并行度的处理。下游按表名合并后进行分发,此处的表名合并主要用于分库分表的场景,可以通过一些正则表达式和条件来指定分库分表的规则。Route 可以将符合规则的表合并为一张表进行输出。按表名合并后,会为下游每一张表产生对应算子。示例中有两张表,就可以产生 Table1 和 Table2 两条路线进行输出。该 Pipeline 的实现主要基于 Process 和 Data Stream 来开发。为了适配更多的连接器,例如适配输出到 Hudi 或 MySQL 数据库,在最后一步 Data Sink 时也支持使用 Flink 的 SQL API 进行,这样就可以兼容所有的 Flink SQL API,最终实现将 Flink CDC 支持的数据源整库同步到任意一个 Flink SQL API 实现的数据库。

由于基于 Data Stream 开发,所以模式演变比较受限,会导致模式演变受下游数据库影响。例如 Doris Sink 支持下游演变,需要将数据流转换为字符串的格式。所以我们可以进行一个链路的复用,将前面的 Debezium json 进行相关处理,到最后环节序列化成字符串,将字符串传输给 Doris Sink,由 Doris Sink 进行模式演变的处理。此时可能存在问题:当有多并行度任务时,例如多并行度为 2 时有两个 Doris Sink 写入同一张表,会存在模式演变时数据的丢失,一个算子在进行模式演变,另一个算子在进行数据写入,这就是一个弊端。所以只能在并行度为 1 时正常使用。

2.5 Dinky CDC Source的局限性

Dinky CDC Source 存在一些局限性。

首先不支持自定义转换,Dinky CDC Source 只支持宽容数据类型的转换。

第二,由之前的算子拓扑图可以发现,面对一些表同步时会构建大量的算子节点,这样作业会非常庞大,从而会导致作业的恢复成本增加。

第三点是模式演变受限。本身框架不支持模式演变,需要由下游 Sink 连接器独立实现。

2.6 Dinky CDC Source整库同步的数据转换探索

在 Dinky CDC Source 整库同步的数据转换探索上,由于下游可以支持 Table API 的使用,所以下游可以直接使用 Flink CTAS 语法,通过 Select 语句定义转换,本质上使用 Flink SQL 的处理来进行。但是仍然会构建大量算子节点,且不支持模式演变。

2.7 Flink CDC YAML定义的Pipeline作业

去年 Flink CDC 3.0 发布,并贡献给 Apache 孵化器。由于 Dinky CDC Source 存在严重的架构瓶颈,只能满足一些特定情况下的整库同步场景。经过调研后发现 Flink CDC YAML(Flink CDC Pipeline)作业完全重构了整库同步的底层设计,支持模式演变和数据转换的能力。

2.8 Flink CDC YAML核心架构

Flink CDC YAML 作业的架构主要核心是基于Flink 的运行环境来完成自定义算子的编排。在设计数据流时摒弃了 Flink SQL 的数据流,自定义了一些高效的数据结构。通过 Data Source、Data Sink、Schema Registry、Router 和 Transformer 五个算子来完成整个作业的编排。上游通过 Flink CDC Cli 和 Yaml 脚本来指定作业细节,完成整库同步作业定义。

2.9 Flink CDC Pipeline 整库同步链路

这是一张 Flink CDC Pipeline 的数据链路图,模式演变、数据转换和分库分表三种场景结合使用。在经历每个算子节点计算后,流数据的结构会发生变化。首先通过 Data Source 节点读取到原始的 Schema 结构,使用数据转换时引入 PreTransform 和 PostTransform 两个算子。PreTransform 对无关的列进行删除,裁剪后 Schema 更加简洁。PostTransform 进行一些计算及投影等能力,包括两部分,第一部分添加计算列,第二部分添加过滤条件,实现整库同步链路中自定义数据转换的能力。数据在投影后字段会增加,通常投影 Schema 会比之前的结构更宽。其中链路图中的数据流长度可以反映出 Schema 大小的变化。下一步在 Schema operator 算子中对分库分表场景下的一些结构进行进一步合并。不同的库表可能会存在表结构不同、数据类型不同的问题。为了保证数据可以完整输出到下游目标库,通过对分库分表场景的一些数据进行宽容处理,最终合并后的 Schema 大于等于投影后的 Schema 结构。此处在触发模式演变时,通过对 DataChangeEvent 进行阻塞处理,保证下游数据库数据正确一致性。解决了 Dinky CDC Source 在多并行度下进行模式演变的丢失部分变更数据的问题。

2.10 Flink CDC Pipeline的Transform

接下来介绍数据在 Flink CDC Pipeline 上如何变化。首先定义了一个 Transform,增加了一个计算列,使用 UDF(age_year)来计算年龄,过滤条件为保留成年人。这样一个 DEMO 可以覆盖 Flink CDC YAML 作业中 Transform 相关的核心能力。注意,进入 Data Source 后的数据不包含 Schema,此处将 Schema 和 Data 放在一起是为了方便理解数据,而下面的 Data 更接近 Flink CDC 数据的传输格式。经过 PreTransform 后,会裁剪无关的列,可以发现前面的 name 列没有被使用到,所以被裁剪。下一步 PostTransform 进行年龄的计算,其中所使用到的出生日期列,被定义为引用列,保留所有引用列。目前 Projection 所引用的两个列是 id 和 birthday。此处的 filter 可以对投影后的结果进行进一步过滤,对年龄不满足该条件的数据进行丢弃。此处输入的四条数据中有两条不满足,所以被丢弃。最后的 Data Sink 环节,会将这两条数据输出到分析库或数据湖,最终的数据形态由各个库的特性决定,例如要输出 Doris 数据库,要求主键是 id,最终实现 upsert 能力。该示例涵盖条件过滤、列投影、UDF 的使用、主键定义,可以很好在测试环境中体验和模拟 Transform 的特性。

2.10 Flink CDC Pipeline的Transform

随着整库同步作业的普及,可能会将数据清洗工作前置到整库同步作业中,提前将不合适的数据或垃圾数据进行清洗,从而使用到 Transform。
下面是 Transform 的实现细节。首先分为两部分:前置处理和后置处理。前置处理是对数据进行裁剪,消费 SchemaChangeEvent,通过 ChangeEvent 进行表结构的推导。其表结构不能在作业创建前被预先定义,在 YAML 作业中所定义的配置只是一些规则。当 YAML 作业读取到数据时会创建对应的 CreateChangeEvent,通过消费建表语句的事件来完成引用列及下游表结构的推导。此处包含主键分区键的定义,同时丢弃掉未使用的列来提升传输效率。后置的 Transform 操作是用于计算,首先推导出计算列,将计算投影到数据集中,并通过条件规则进行过滤。

2.11 Transform的表达式计算

在计算列和条件过滤中使用的是表达式。在表达式中,为了方便将 Flink SQL 作业迁移到 YAML 作业上,定义了投影规则与过滤规则,接近于 Flink SQL 原始写法,但不等于 Flink SQL。其中在表达式中处理都是对单表进行操作。为了满足 Transform 模块中进行动态的表达式计算,引入了一个新的框架 Janino。Janino 是一个轻巧的 Java 动态编译器,在 Apache Flink 中使用。同时引入 Apache Calcite 进行语法解析,也在 Apache Flink 中使用。基于这两个技术栈实现了动态表达式计算,可以在预定义的规则上结合变更的表结构来进行计算。

Transform 主要包含六大部分:投影规则、过滤规则、自定义函数、内置函数、运行时 Schema、运行时 Data。Transform 通过 Calcite 将类 SQL 的规则转换成最终的编译器脚本。具体步骤为 Calcite 将投影规则和过滤规则转换成一个 SQL 查询语句,进行语法树的解析,最终推导出 AST。由于是单表的处理任务,不需要进行相关的逻辑优化。再遍历 AST 生成对应的 Janino 的语法树,然后生成 Janino 的表达式,这样可以将 YAML 的脚本转换成一个动态的 Janino 的表达式,并且通过缓存来提升处理效率。

2.12 模式演变的机制与策略

在 Flink CDC YAML 中支持模式演变的机制与策略。该机制解决了 Dinky CDC Source 由于架构的限制不支持模式演变的缺点。提供了一些细粒度的策略和全局策略,可以进行灵活控制。例如,不要求下游进行模式演变或者要摒弃某些模式演变,可以通过这种全局策略和细粒度策略进行控制来满足多样化使用。

2.13 其他方面比较

其他方面的比较有三大点:数据结构、分库分表、输入输出。

2.14 Flink CDC的高性能数据结构

Flink CDC Pipeline 带来一个高性能的数据结构。Dinky CDC Source 的实现基于 Flink Data Stream 实现,结果是一个宽的结构,每条数据都包含完整的 Schema 信息。在 Flink CDC Pipeline YAML 作业中,将数据结构进行压缩,将 Schema 和 data 进行分离,最终根据数据的实际内容进行分配,此处的传输效率和资源使用得到了一定提升,对事件变更进行了合并。图中左侧 Dinky CDC Source 有四条 Flink 流事件语义,而 Flink CDC 则将 Update 合并为 Before 和 After 进行统一处理,减少了需要处理的流事件数量。

2.14 Flink CDC的分库分表宽容机制

Flink CDC Pipeline 具有分库分表的宽容机制。而 Dinky CDC Source 不具备该能力,虽然可以对分库分表的数据进行合并,但不具备对不同列冲突或不兼容的列进行处理,强要求表结构必须相同。Flink CDC Pipeline 作业引入一些宽容机制,可以自动打宽表结构,保证在分库分表合并过程中为用户保留更多的数据和信息,不至于丢失。

下面案例第一个是新增列,两个分表的结构完全一致,但是之后其中一张表的结构增加了一个地址列,此时 Flink CDC Pipeline 会自动为旧数据补充上值为空的地址列。第二个是修改列,列类型的变更有一些兼容机制,保证列类型进行宽容的转换。第三个删除列可以自动删除数据进行过滤。

2.15 Source与Sink

Dinky CDC Source 架构基于 Data Stream 开发,支持所有 Flink CDC Source,支持所有 Flink SQL 的 Sink。而 Flink CDC Pipeline 支持的连接器比较少,需要二次开发。目前有很多用户使用 Dinky CDC Source 来处理 Flink CDC Pipeline 作业不支持的场景。

2.16 两者差异总结

两者差异总结如下。

  1. Dinky CDC Source 作业通过类 SQL 语句进行定义,Flink CDC Pipeline 作业通过 YAML 脚本定义。

  2. Dinky 是一个实时计算平台,拥有完善的前端 IDE 交互,所以作业通过界面进行提交。Flink CDC Pipeline 作为一个后端框架使用,提供通过脚本来启动 YAML 作业任务,但是该启动模式在生产环境中不太适用。

  3. Flink CDC Pipeline 具备完整的模式演变,Dinky CDC Source 受限于下游 Sink 连接器的实现。

  4. 分库分表方面,Flink CDC Pipeline 支持不同的表结构宽容合并。

  5. Flink CDC Pipeline 支持完整的 Transform,基于 Transform 架构,可以实现更多能力,例如调用 API 能力,后续会有一些向量计算的能力在 Pipeline 作业中进行扩展。

  6. Dinky CDC Source 的 Source 支持 Flink CDC 所有的 Source,可以理解为原生 Source,所提供的是 API Source,不是 Pipeline Source。

  7. Dinky CDC Source 的 Sink 支持所有的 Flink SQL Sink,而 Flink CDC Pipeline 支持的较少。

  8. Flink CDC Pipeline 的数据结构上具有高性能的二进制结构。

  9. Dinky CDC Source 算子节点有大量节点,而 Flink CDC Pipeline 节点非常少。

  10. 部署模式上 Dinky CDC Source 支持所有部署模式,Flink CDC Pipeline 支持少,不支持 Yarn。

  11. 由于上述的一些条件,例如数据结构、算子拓扑节点,会导致数据资源的消耗有明显差异。

2.17 在Dinky中使用Flink CDC Pipeline

由于 Dinky CDC Pipeline 作业有局限性,所以在使用过程中会有一些痛点。Dinky 在最新版本中提供了 Flink CDC Pipeline 作业,可以在 Dinky 中定义一个 EXECUTE PIPELINE 语句来定义 Flink CDC YAML 脚本配置,通过 Dinky 平台提交到 Flink 集群。同时可以解决上述提到的 CDC 的缺点:不支持 Yarn、提交方式不方便等。

在 Dinky 中使用 Flink CDC Pipeline 可以完全兼容 Flink SQL 生态管理的功能,例如托管作业状态、告警等功能。下一步会增加相关功能帮助用户调试 Flink CDC Pipeline 作业,帮助用户在页面上看到 Pipeline 作业的输出。

03.探索

Dinky CDC Source 是作为一个过渡工具来保证用户在 Flink CDC Pipeline 普及前有业务需求时使用。目前 Dinky CDC Source 已经有近百家用户在使用,未来也会为 Dinky CDC Source 添加一个 Pipeline 转换功能,将 Dinky CDC Source 转为 Flink CDC YAML 作业,帮助用户快速架构到 Flink CDC YAML 上。其次会进行一些细粒度策略,试图尝试扩展 Transform 来满足用户需求。最后探索实时湖仓的治理,同时我们的项目也在寻找 Apache 孵化器的导师。

我们会与 Flink CDC 进行紧密合作,将 Flink CDC 各种能力应用在 Dinky 上,并投入精力在 Flink CDC 上,帮助社区完成对应的一些 Transform 优化及其他场景的完善。

相关文章:

Dinky 和 Flink CDC 在实时整库同步的探索之路

摘要:本文整理自 Dinky 社区负责人,Apache Flink CDC contributor 亓文凯老师在 Flink Forward Asia 2024 数据集成(二)专场中的分享。主要讲述 Dinky 的整库同步技术方案演变至 Flink CDC Yaml 作业的探索历程,并深入…...

【Proteus仿真】【32单片机-A008】MPX4115压力检测系统设计

目录 一、主要功能 二、使用步骤 三、硬件资源 四、软件设计 五、实验现象 联系作者 一、主要功能 1、压力检测与LCD显示 2、超过上限,降压模块启动 3、压力检测范围15kpa-115kpa 4、压力阈值设置 5、超限报警 二、使用步骤 系统运行后,LCD160…...

银河麒麟系统虚拟机网络ping不通的解决方法

问题描述:使用NAT模式搭建了银河麒麟系统虚拟主机,虚拟机内部可以联网,可以查询到具体的ip地址,同时也可以在虚拟机内部ping同宿主机ip,但使用宿主机却无法ping同银河麒麟虚拟机ip,使用ssh、ftp、sftp等工具…...

spark数据清洗案例:流量统计

一、项目背景 在互联网时代,流量数据是反映用户行为和业务状况的重要指标。通过对流量数据进行准确统计和分析,企业可以了解用户的访问习惯、业务的热门程度等,从而为决策提供有力支持。然而,原始的流量数据往往存在格式不规范、…...

关于AIGC stable diffusion 在图像超分上的算法整理

参考文档: c论文阅读基于Stable Diffusion的图像超分 - 知乎 十分钟读懂Stable Diffusion运行原理 - 知乎 1.difussion model 扩散模型的基本原理 diffusion model 扩散模型是一类生成模型的统称,基于扩散过程生成数据。这类模型的核心是通过逐步加噪…...

Stable Diffusion ComfyUI 基础教程(一) ComfyUI安装与常用插件

前言: 相信大家玩 Stable Diffusion(以下简称SD)都是用的 web UI 操作界面吧,不知道有没有小伙伴听说过 ComfyUI。ComfyUI 是 一个基于节点流程的 Stable Diffusion 操作界面,可以通过流程,实现了更加精准…...

[leetcode]差分算法

一.差分算法性质 1.1计算差分数组: b[i] a[i] - a[i - 1] 1.2差分数组的性质 1.2.1对差分数组的每一项作前缀和,可以得到原来的数组 ai ​a1​∑j1i−1​dj​ 1.2.2将差分数组的某一项加i,那么其后面的所有项都会相对于原数组加i 让2~4项加3 这个第三…...

大数据技术之SPARK

Spark Core 什么是 RDD 代码中是一个抽象类,它代表一个弹性的、不可变、可分区、里面的元素可并行计算的集合 弹性 存储的弹性:内存与磁盘的自动切换; 容错的弹性:数据丢失可以自动恢复; 计算的弹性:…...

S32K144的m_data_2地址不够存,重新在LD文件中配置地址区域

在开发平台软件的时候代码中超出了64K的内存,单纯在ld文件中,增加m_data_2的存储长度,原先是0x00007000,我将长度修改为0x00008000,起始地址还是0x20000000,软件编译没有报错堆栈超出,但是软件下载到单片机中之后,144不…...

Spyder、PyCharm、VS Code 和 Jupyter Notebook 对比分析

在进行 Python 编程时,Spyder、PyCharm、VS Code 和 Jupyter Notebook 是最常用的几款开发工具(IDE/编辑器)。以下是它们在不同维度下的对比分析 🔧 一、基础介绍 软件类型主要特点Spyder科学计算IDE类似 MATLAB,集成…...

vue3腾讯云直播 前端拉流(前端页面展示直播)

1、引入文件&#xff0c;在index.html <link href"https://tcsdk.com/player/tcplayer/release/v5.3.2/tcplayer.min.css" rel"stylesheet" /><!--播放器脚本文件--><script src"https://tcsdk.com/player/tcplayer/release/v5.3.2/t…...

应急物资仓库管理系统|基于GAV仓库管理的应用

基于AGV应用的应急物资管理系统(智物资DW-S300)建设的目标是实现应急物资管理的信息化、智能化、规范化,保证应急物资的安全性和使用时的高效性&#xff0c;做到应急物资可追踪、可溯源。 构建一个应急物资仓储管理系统实现包括系统基本信息管理、入库管理、出库管理、筹措管理…...

ArkTS语言入门之接口、泛型、空安全、特殊运算符等

前言 臭宝们&#xff0c;今天我们来学习ArkTS中最后的一些内容。 实现接口 包含implements子句的类必须实现列出的接口中定义的所有方法&#xff0c;但使用默认实现定义的方法除外。 interface DateInterface {now(): string; } class MyDate implements DateInterface {no…...

蓝桥杯c++每日刷题(洛谷)

目录 P10385 [蓝桥杯 2024 省 A] 艺术与篮球 - 洛谷 (luogu.com.cn) P8706 [蓝桥杯 2020 省 AB1] 解码 - 洛谷 (luogu.com.cn) P8711 [蓝桥杯 2020 省 B1] 整除序列 - 洛谷 (luogu.com.cn) P8722 [蓝桥杯 2020 省 AB3] 日期识别 - 洛谷 (luogu.com.cn) P10385 [蓝桥杯 2024…...

Python+Requests 企业级接口测试入门(1~3天)

PythonRequests 企业级接口测试入门 1、GET接口简单案例 我的答案&#xff1a; import time import requestsdef get_all_users():try:response requests.get(urlhttps://reqres.in/api/users, #接口地址timeout10 #超时时间)respons…...

【android bluetooth 框架分析 01】【关键线程 3】【bt_jni_thread 线程介绍】

1. bt_jni_thread 职责介绍 bt_jni_thread 这个线程的作用是专门负责处理蓝牙 JNI 层的消息循环&#xff0c;也可以说是 C 层和 Java 层交互的桥梁线程。 1.1 什么是 JNI 层&#xff1f;为什么需要这个线程&#xff1f; JNI&#xff08;Java Native Interface&#xff09;是 …...

CCF - GESP Python三级考试题目示例

CCF - GESP Python三级考试题目示例&#xff0c;你可以根据实际需求进行调整。 一、单选题&#xff08;每题2分&#xff0c;共30分&#xff09; 以下关于Python中函数的说法&#xff0c;错误的是&#xff08; &#xff09; A. 函数定义使用def关键字 B. 函数必须有返回值 C.…...

Windows10系统更改盘符

Windows10系统更改盘符 导航 文章目录 Windows10系统更改盘符导航更改盘符 更改盘符 按下wini,再按k进入磁盘管理器 右击你想更改的磁盘&#xff0c;选择“更改驱动器号”和路径&#xff0c;选择好驱动器号后确定即可...

软件功能性测试有多重要?功能性测试工具有哪些?

软件功能性测试是指对软件应用程序进行的测试&#xff0c;旨在验证软件的每一个功能是否按预定要求正常运作。功能性测试通常基于软件的需求文档&#xff0c;从用户的角度出发&#xff0c;确保所有功能都能够满足用户的需求。 软件功能性测试在软件开发生命周期中扮演着至关重…...

未来生态映像:杭州的科技自然协奏曲

故事背景 故事发生在2050年的中国杭州&#xff0c;这座千年古城已蜕变为科技与自然完美交融的未来生态之城。从晨曦微露的西湖到暮色中的良渚文化村&#xff0c;每个角落都上演着人类智慧与自然韵律的动人对话。 故事摘要 当第一缕阳光亲吻西湖的生态浮岛&#xff0c;无人机携带…...

电商核心指标解析与行业趋势:数据驱动的增长策略【大模型总结】

电商核心指标解析与行业趋势&#xff1a;数据驱动的增长策略 在电商领域&#xff0c;数据是决策的核心。从流量监测到用户行为分析&#xff0c;从价格策略到技术赋能&#xff0c;每一个环节的优化都离不开对核心指标的深度理解。本文结合行业最新趋势与头部平台实践&#xff0…...

ubuntu自动更新--unattended-upgrades

ubuntu自动更新--unattended-upgrades 1 介绍2 发展历程3 配置与使用4 disable Auto update服务命令 参考 1 介绍 Unattended-Upgrades 是一个用于自动更新 Debian 及其衍生系统&#xff08;如 Ubuntu&#xff09;的工具。它的主要功能是自动检查、下载并安装系统更新&#xf…...

在Ubuntu 22.04上配置【C/C++编译环境】

在Ubuntu 22.04上配置C/C编译环境 如果你想在Ubuntu 22.04上编译和运行C或C程序&#xff0c;首先需要安装一个合适的编译器和相关工具。本文将为你提供详细的安装建议和操作步骤&#xff0c;帮助你快速搭建开发环境。 准备工作 在开始之前&#xff0c;确保你的系统可以通过终…...

费马小定理

快速幂 理论 a n a a ⋯ a a^n a a \cdots a anaa⋯a&#xff0c;暴力的计算需要 O(n) 的时间。 快速幂使用二进制拆分和倍增思想&#xff0c;仅需要 O(logn) 的时间。 对 n 做二进制拆分&#xff0c;例如&#xff0c; 3 13 3 ( 1101 ) 2 3 8 ⋅ 3 4 ⋅ 3 1 3^{13}…...

什么是音频预加重与去加重,预加重与去加重的原理是什么,在什么条件下会使用预加重与去加重?

音频预加重与去加重是音频处理中的两个重要概念&#xff0c;以下是对其原理及应用条件的详细介绍&#xff1a; 1、音频预加重与去加重的定义 预加重&#xff1a;在音频信号的发送端&#xff0c;对音频信号的高频部分进行提升&#xff0c;增加高频信号的幅度&#xff0c;使其在…...

程序代码篇---时间复杂度空间复杂度

文章目录 前言一、时间复杂度&#xff08;Time Complexity&#xff09;定义1. 常见时间复杂度类型2. 计算规则忽略常数项保留最高阶项循环嵌套递归算法 3. 代码示例&#xff08;1&#xff09;&#x1d442;(1)&#xff1a;常数时间&#xff08;2&#xff09;&#x1d442;(&…...

化工企业数字化转型:从数据贯通到生态重构的实践路径

一、战略定位&#xff1a;破解行业核心痛点 化工行业面临生产安全风险高&#xff08;全国危化品企业事故率年增5%&#xff09;、能耗与排放压力大&#xff08;占工业总能耗12%&#xff09;、供应链协同低效&#xff08;库存周转率低于制造业均值30%&#xff09;三大挑战。《石…...

Mysql备忘记录

1、简介 Mysql操作经常忘记命令&#xff0c;本文将持续记录Mysql一些常用操作。 2、常见问题 2.1、忘记密码 # 1、首先停止Mysql服务 systemctl stop mysqld # windows 从任务管理器里面停 # 2、更改配置文件 my.cnf (windows是 ini文件) vim /etc/my.cnf 在[mysqld]下面添…...

Python 爬取 1688.item_get_factory 接口:获取工厂档案信息实战指南

在电商采购和供应链管理中&#xff0c;了解供应商的工厂信息是至关重要的一步。1688 作为国内领先的 B2B 平台&#xff0c;提供了丰富的供应商和工厂档案信息。通过 item_get_factory API 接口&#xff0c;开发者可以获取工厂的详细信息&#xff0c;包括工厂名称、地址、联系方…...

【Proteus仿真】【32单片机-A009】矩阵按键系统设计

目录 一、主要功能 二、使用步骤 三、硬件资源 四、软件设计 五、实验现象 联系作者 一、主要功能 1、按键值与LCD显示 2、矩阵按键 二、使用步骤 系统运行后&#xff0c;LCD1602显示当前的按键值&#xff1b; 当按下不同按键后显示屏更新对应的按键值。 三、硬件资…...

【11408学习记录】英语语法精析:主从复合句之定语从句完全指南——从规则到实战例句一网打尽

定语从句 英语语法总结——主从复合句定语从句定语从句的写法先行词的作用分类定语从句的使用补充 每日一句词汇第一步&#xff1a;找谓语第二步&#xff1a;断开第三步&#xff1a;简化第一句第二句第三句第四句 英语 语法总结——主从复合句 定语从句 定语从句就是一个句子…...

go游戏后端开发31:麻将游戏的碰牌与胡牌逻辑

以下是润色后的版本&#xff1a; 1. 碰牌逻辑 1.1 触发碰牌 当一个玩家弃牌后&#xff0c;其他玩家可以选择碰牌。如果当前玩家决定碰牌&#xff0c;系统需要通知所有玩家这一操作。碰牌操作完成后&#xff0c;当前玩家需要出一张牌&#xff0c;系统同样需要通知所有玩家。 …...

vLLM实战:多机多卡大模型分布式推理部署全流程指南

1. 环境准备与基础配置 1.1 系统要求 依赖组件&#xff1a; # 基础工具安装 sudo apt-get install -y lsof git-lfs nvidia-cuda-toolkit1.2 虚拟环境配置 使用conda创建隔离环境&#xff0c;避免依赖冲突&#xff1a; conda create -n vllm python3.10 -y conda activate…...

RAI Toolbox详解

RAI Toolbox详解 摘要 RAI Toolbox是一个综合性的工具集&#xff0c;旨在帮助开发者和AI系统利益相关者更负责任地开发和监控AI系统&#xff0c;并做出更好的数据驱动决策。本文将详细介绍RAI Toolbox的功能、使用场景以及与类似AI项目的对比&#xff0c;帮助读者全面了解RAI…...

Python高级爬虫之js逆向+安卓逆向1.3节:Python数据类型

目录 引言&#xff1a; 1.3.1 两大数据类型 1.3.2 不可变数据类型 1.3.3 可变数据类型 1.3.4 再不跳槽就老了 引言&#xff1a; 大神薯条老师的高级爬虫安卓逆向教程&#xff1a; 这套爬虫教程会系统讲解爬虫的初级&#xff0c;中级&#xff0c;高级知识&#xff0c;涵盖…...

The 2024 CCPC National Invitational Contest (Changchun),第17届吉林省赛 C

补题链接 题解是什么意思呢&#xff0c;首先我们需要知道的是&#xff0c;斐波那契数列可以用矩阵快速幂和矩阵乘法求解 ( F ( n 1 ) F ( n ) ) ( 1 1 1 0 ) ( F ( n ) F ( n − 1 ) ) M ( F ( n ) F ( n − 1 ) ) \begin{pmatrix}F(n1) \\ F(n)\end{pmatrix} \begin{pma…...

GPT-4o-image模型:开启AI图片编辑新时代

在生成式AI技术爆发式迭代的今天&#xff0c;智创聚合API率先突破多模态创作边界&#xff0c;正式发布集成GPT-4o-image模型的创作平台&#xff0c;以“文生图-图生图-循环编辑”三位一体的技术矩阵&#xff0c;重新定义数字内容生产流程。生成图像效率较传统工具提升300%&…...

Java流程控制【if分支三种形式】

if分支三种形式 ①if(条件表达式) 代码&#xff1b; }②if(条件表达式){ 代码1&#xff1b; }else{ 代码2&#xff1b; }③if(条件表达式1){ 代码1&#xff1b; }else if(条件表达式2){ 代码2&#xff1b; }else if(条件表达式3){ 代码3&#xff1b;...... }else{ 代码n&#…...

2025 年陕西消防设施操作员考试攻略:历史文化名城的消防传承与创新​

陕西拥有丰富的历史文化遗产&#xff0c;众多古建筑分布其中&#xff0c;同时也在不断推进现代化建设&#xff0c;消防工作面临传承与创新的双重任务&#xff0c;这在考试中也有所体现。​ 考点融合与特色&#xff1a;一方面&#xff0c;古建筑的消防保护是重点&#xff0c;包…...

关于node.js 隐式修改数组长度的问题

// 删除手牌 proto.remove function (handCards, _cards) { let saveHandCards this.deepCloneTL(handCards);//保存原先的牌 console.warn("删除手牌000:",JSON.stringify(handCards)); console.warn("删除手牌111:",JSON.stringify(_card…...

探索文件与流的世界:File、InputStream 和 OutputStream 的奇妙之旅

目录 一、File 类——文件管理的小能手 1. 创建和删除文件 2. 检查文件属性 3. 路径操作 二、InputStream——读取数据的管道 1. 读取单个字节 2. 批量读取字节 3. 关闭流 三、OutputStream——写入数据的通道 1. 写入单个字节 2. 批量写入字节 3. 刷新和…...

nginx镜像创建docker容器,及其可能遇到的问题

一、基本流程 1、目录准备 我喜欢把文件放在/data下。 # 进入根目录的data目录 cd /data# 创建nginx目录 mkdir nginx# 进入nginx目录 cd nginx# 创建conf目录 mkdir conf# 进入conf目录 cd conf# 创建conf.d目录 mkdir conf.d 2、文件准备 &#xff08;1&#xff09;nginx…...

测试用例 [软件测试 基础]

目录 测试用例 1. 概念 1.1 什么是测试用例 1.2 什么是要素 1.3 为什么需要测试用例 2. 设计测试用例的万能公式 2.1 常规思维 逆向思维 发散性思维 2.2 万能公式 3. 设计测试用例的方法 3.1 基于需求的设计方法 3.2 具体的设计方法 3.3 更多用例练习 测试用例 …...

树的直径 (dp或贪心)

B4016 树的直径 - 洛谷 题目大意&#xff1a; 给定一棵 n 个结点的树&#xff0c;树没有边权。请求出树的直径是多少&#xff0c;即树上的最长路径长度是多少。 思路&#xff1a; 树形 d p dp dp 求树的直径 定义 d [ x ] d[x] d[x] 表示以 x x x 节点出发走向 x x x 的…...

C++ 入门二:C++ 编程预备知识

一、使用 Qt Creator 创建 C 工程 1.1 打开软件 在计算机中找到 Qt Creator 的应用程序图标并双击打开它。如果是首次打开&#xff0c;可能需要进行一些初始化设置&#xff0c;如选择默认的开发环境等。 1.2 选择 C 工程 打开 Qt Creator 后&#xff0c;在欢迎界面中点击 “…...

IT管理思路

甲方CIO和IT管理者-如何做好组织级IT能力提升_哔哩哔哩_bilibili...

C++17模板编程与if constexpr深度解析

一、原理深化 1.1 模板编程 1.1.1 编译器如何处理模板&#xff08;补充&#xff09; 模板的实例化机制存在两种模式&#xff1a; 隐式实例化&#xff1a;编译器在遇到模板具体使用时自动生成代码&#xff0c;可能导致多翻译单元重复实例化&#xff0c;增加编译时间。显式实…...

指令层级:训练大型语言模型优先处理特权指令

指令层级&#xff1a;训练大型语言模型优先处理特权指令 The Instruction Hierarchy: Training LLMs to Prioritize Privileged Instructions关键要点&#xff1a;快速浏览&#xff1a;1. 引言&#xff08;Introduction&#xff09;2. 指令层级&#xff08;The Instruction Hie…...

高效人脸关键点检测算法HRNet-Facial-Landmark-Detection

高效人脸关键点检测算法HRNet-Facial-Landmark-Detection 300 W data 数据标注格式 helen/trainset/1271089376_2.jpg,2.105,642.5,643.5,453.88947199999996,562.431791,457.882374,607.338625,471.39681399999995,655.136824,489.458724,702.023327,508.36972599999996,743.…...

LeetCode 3375 题解

题解 如题所示&#xff0c;允许暴力&#xff0c;虽然是暴力&#xff0c;但复杂度也就O(n) 还是如昨天的题目一样&#xff0c;使用Set.add的方法去判断即可 分三种情况 因为是set集合的原因&#xff0c;所以可以排除值相同的原因 当遍历数组有值小于k就return -1 当遍历数组遇…...