数据仓库发展历史与架构演进

 从1990年代Bill Inmon提出数据仓库概念后经过四十多的发展,经历了早期的PC时代、互联网时代、移动互联网时代再到当前的云计算时代,但是数据仓库的构建目标基本没有变化,都是为了支持企业或者用户的决策分析,包括运营报表、企业营销、用户画像、BI分析等。

广义上看数据库仓库并不是一项技术或者产品而是数据处理过程,从不同的数据源进行数据汇合,然后经过数据的统一建模成适合于分析的数据模型,最终辅助企业的决策分析。这个过程涉及到ETL、数据建模及数据可视化等一系列实现,这也是与数据库的本质区别。

随着计算机科学技术发展与产业变革,数据仓库在应对从数据特征呈现多样化、海量化到业务特征复杂化、智能化及实时化等,再到基础设施(存储、网络及计算资源)能力的提升、云计算技术的发展等变化,数仓的整个体系也在持续演进中,这里从数据仓库的系统架构及内核引擎的实现角度去分析数据仓库的发展过程,基本上如下图所示:

从数仓的核心能力去分析各个阶段实现的变化,我将重点分析以下几个方面:

  • 存储引擎:主要是数据的组织方式,定义了数据如何存储及压缩、索引的创建和更新、锁机制、事务及缓存管理等。在数仓中数据是面向主题的将数据进行整理归纳和重组,这是提高数据分析性能的核心,在分析过程只需要处理部分维度的数据,并且大量的统计任务需要进行数据的扫描或者精确检索,因此存储引擎的合理设计是数仓架构发展的重要部分。
  • 计算引擎:分析型任务涉及到大量的计算,计算效率往往会成为数据库系统的瓶颈,计算模型(框架)、优化技术、和运行中间数据的处理等都是数仓演进的突破点。MPP计算、分布式流计算、分布式批计算等都有相应的使用场景,在具体的算子执行过程中向量计算、编译执行及硬件加速技术等都是近年有效的提升性能的方法。
  • 技术实现架构,数据库可以基于功能分为存储、计算及管理等层次,这些功能的运行机制影响着系统的灵活性、可运维性、成本及分析的性能等。云计算的出现为数仓架构的演进提供了新的方向,赋予数仓获得自服务、弹性等能力,同时目前企业将基础系统、平台部署到云端降低信息化建设成本及优化运行管理流程等成为趋势。

数据仓库的演进变革的因素有很多,例如快速的业务模式与群体规模的数据量带来的大数据处理技术、互联网的发展带来的数据源及数据类型的增多、人工智能的发展带来数智的融合、云计算交付模式的出现需要的细粒度的资源管理与隔离等,业务实时性的要求等都会带来数据仓库架构的变化。这里只分析不同阶段数据仓库的核心特性的变化,其他的内容可以逐步分析。

1.初代数仓(单体分析型数据库)

这个阶段是数据仓库概念提出后,数据库厂商传统数据库的基础上结合数仓方法论提供的数仓产品。在这个阶段数仓的数据来自于CRM、ERP等业务数据,数据量小多GB级别,数据类型基本上是结构化数据,而且产生的周期按天或者周为单位,因此对数据仓库的要求不高,基本上是单机(性能较高的商用主机,例如中小型机器)分析型数据库,以Oracle、DB2、SQL Server、SybaseIQ等为代表。

这些数据仓库产品从本质上是关系型数据库,使用ETL工具实现多种异构数据源的有效集成与处理,并按照主题的方式进行数据进行重新整合,即按照数仓的维度模型进行归一化构建。这些数据库的设计是为了决策分析而进行的,例如使用位图化索引、按列存储、数据压缩及与众不同的锁机制,这些特性都极大提高了查询引擎的性能。这个阶段的数据仓库主要集中在金融、电信、大型零食及制造等行业。

2.传统MPP数据仓库

随着业务的发展,单机数据仓库的数据存储和计算模式不能满足大量数据处理的需求,在这个背景下基于MPP架构的数据仓库成为主流的解决方案,这阶段的数仓产品以在2000年代后出现的Teradata、Greenplum、Vertica等为代表。MPP(Massively Parallel Processing),大规模并行处理架构,更适合于复杂的数据处理和综合分析,典型实现如下图所示:

这种架构主要的特征如下:

  • Shared Nothing,节点之间不共享存储、计算资源和磁盘,节点之间仅通过网络通信。
  • 数据按照特定的规则进行本地化存储,例如基于特定分布式键上按照Hash规则分布到全部节点上。
  • 完全对称的并行执行策略,每个节点都参与计算,并且节点上执行的任务逻辑完全一致。
  • 任务按照流水线的方式进行组织执行,任务之间数据的传递以流水线的方式来进行,数据的流转在内存中进行,避免了数据积压的时间开销。任务的流水线执行使得MPP数据库具有优异的性能。

这种架构可以实现横向扩展的方式,使用普通主机就可以构建较大规模的集群系统,通过并行化来实现快速的分析任务的快速执行,同时更具有成本优势。

在这个阶段的MPP架构在技术实现基于传统数据库实例进行扩展,例如Greenplum、ADB for PG等都是基于PostgreSQL内核进行开发,在集群中每个节点都是一个独立的数据库实例,具有独立的系统表、用户表等,数据是按照某种策略分布到不同的实例中。客户端在发起请求后由管理节点生成查询计划并进行并行化调度,当涉及到多个节点的数据交换时,例如HashJoin的执行,引入数据交换算子,如下图所示:

管理节点分布到每个节点的查询计划是相同的,在执行时如果需要每个节点扫描自己所在节点的数据,当需要进行数据交换时调用Motion算子发送到其他节点,例如Join计算中符合过滤条件的右表数据,最后在管理节点上通过GatherMotion进行查询结果的汇总。

MPP数仓它是整体向外提供服务,每台节点无法单独运行局部数据,数据在存储时通过一定的策略进行分布,存储位置是不透明的,因此在执行任务时由于无法断定数据的位置,导致任务会在所有节点上执行,同时在计算过程中涉及到锁、事务、内外存交互等问题,所以当数据达到一定规模后就会出现性能的瓶颈问题。当集群或者数据量达到一定程度后,节点的故障成本较高,查询任务在某个节点故障时需要重启整个任务。

另一个缺点是存算耦合的架构,节点进行扩缩容时需要进行数据的重新分布,整个操作的过程会由于耗费大量IO请求引起业务处理速度的下降,影响客户的正常查询需求,最后是无法动态适应业务的发展。对于不同的请求,例如导入类任务耗费大量IO、网络带宽,但是CPU的使用率较低。复杂的查询任务CPU的资源消耗非常大,因此资源规格的需求是不同的,但是MPP架构很难满足这些需求。因此这种架构的数仓集群的规模不能太大,适用于中等规模的企业数据处理场景,通常不超过数百级别,因此支持的数据体量很少超过PB级别。

3.大数据OLAP引擎

随着移动互联网、物联网的蓬勃发展带动了大数据的发展,数据处理种类的多样化、数据量不断变大、快速的数据流转等对系统有了新的要求,大数据框架从底层数据存储机制、计算模型(分布式批处理、内存及流计算等)到数据的集成等都发生了革命性的变化。其中Hadoop生态技术被广泛使用,数据仓库在大数据背景下建设的理论和目标是相同的。

根据大数据架构模式可以分为三个方向如下图所示:

  • 大数据数仓

传统的MPP数据仓库的出现是为了解决大数据量和性能的问题,但是随着大数据的发展,需要产生新的大数据处理技术和架构模式。在存储引擎上以HDFS为代表的分布式存储、在计算框架上出现了MR、Spark(DAG)和Flink等。

MapReduce计算框架

DAG计算框架

基于大数据构建等数仓产品很多,例如Hive、Kylin等,这些产品使用大数据的计算框架、底层直接读取文件系统中的数据,如下图所示:

这些数仓可以看到做事传统数仓各个引擎部分替换成大数据体系中的组件,在Hive中执行引擎替换成MapReduce及存储引擎替换成HDFS,为了增加实时性减少数据的落地执行引擎集成了Spark。

大数据数仓产品并不是某个单独运行的产品,而是一系列大数据组件遵循数据的处理流程的“范式”,例如离线数仓、流式数仓、实时数仓Lambda架构或者实时数仓Kappa架构在大数据组件的使用及数据的流转上是不同的,这里以Lambda为例,架构为例:

Kappa架构与Lamda架构相比更多关注于流处理部分,但是在真实中用户并不会完全遵循规范的架构而是进行混合使用,在近年还提出的IOTA的架构模式,基于AI生态下的全新的数据架构模式。

大数据数仓是一个松散的遵循某种规范的系统套件组合,涉及到数据的传输、计算(批处理、流处理)、存储及服务等组件,其优点在于可以支持PB以上级别的数据处理且具有较强的扩展性,但是缺点是性能及架构复杂。

  • 湖仓

数据湖概念在2010年被提出,其特征是以原始格式存储数据的存储库或者文件系统,无需对数据进行结构化处理,并且通常是将数据存储在开放的格式中,例如Parquet、ORC等。湖仓是将数据湖具有低成本的开放格式的存储能力和数据仓库的管理和优化能力结合在一起,典型的湖仓架构如下图所示:

从数据流转和计算来看与大数据数仓基本相同,核心的变化在于使用数据湖存储格式,例如Hudi、Iceberg、Delta Lake等进行数据的组织,解决了数据湖松散的文件结构问题,并在此基础上提供统一的元数据管理能力,实现各种数据库和数据仓库的元数据无缝打通和管理。

数据湖存储格式是湖仓运行的核心,其通过良好的抽象对接数据存储和元数据管理,格式如下图所示:

通过定义存储格式为数据湖添加了管理特性,如数据一致性、版本控制、增量处理及事务等,除外还通过表文件列式存储及压缩、表索引信息、谓词下推来加速SQL引擎的查询能力,简单来说数据湖存储格式提供了传统数据仓库存储引擎中的日志模块相同的功能。

  • 湖仓分体模式

从上面介绍的大数据架构的数仓能力来看为了支持大数据量处理、扩展性和容错性等能力,将不同的组件按照一定的架构“范式”进行叠加,存在架构极其复杂且维护成本很高,采用分布式处理框架查询性能比较低,而且事务支持较弱等问题,因此无法替代传统数仓。但是传统数仓存在集群规模小、并发能力不高、动态扩展性差等问题,因此业界出现了大数据数仓和传统数仓进行互补的新式架构的数仓。在大数据的存储能力基础上使用MPP的架构优势提高计算的实时型,典型数仓产品Impala、Presto/Trino、Hawq等产品,这里以Impala为例,其架构如下图所示:

Impala Daemon进程安装在所有节点上,通常与DN部署在一起,方便于数据的本地计算。管理节点对外提供服务,并且维护表的元数据、资源信息及各节点的健康状况。Coordinator会查询HDFS文件获取此次查询的数据所在的位置以及存储方式的信息。

查询请求提交到集群后由FE进行解析并生成查询计划,在这个过程中会将执行计划转换成分布式并行物理执行计划,如下图所示:

单机执行计划

分布式并行执行计划

分布式并行执行计划是在单机执行计划的基础上,结合数据分布式存储的特点,将其拆分为多个子任务,每个子任务都是可以并行执行,待执行后将结果进行全局的聚合。

具体来说在这种框架下数据存储在分布式架构的存储系统中,分散存储到多个节点上实现数据的分区容错性和扩展性,然后在上层利用MPP的并行计算能力来优化数据查询和计算等任务,减少运算延迟,提高处理效率。

4.新架构实时数仓

上面介绍的大数据背景下的数仓并不能称之为数仓产品,不管是Hive、Kylin、Impala、Presto还是湖仓,这些姑且可以称之为OLAP引擎,要提供数仓的能力还要与其他组件,例如分布式存储、元数据管理及数据传输等进行组合来作为整体来提供数仓服务。

但是大数据和数据仓库从概念和目标上是不同的,大数据体系是实现一个以原始格式进行数据存储和治理的基础设施,来满足不同的异构数据存储和计算需求。本质上需要灵活的标准来实现数据的集成、数据管理与对外提供数据服务等,因此从产品形态上看大数据体系下的数据仓库能力更像是一种架构指导,还可以在相同的基础能力上提供机器学习、数据挖掘、数据集市等各种能力。但是数据仓库从概念上看是一个面向主题、集成、相对稳定和反映历史变化的数据集合,在数据仓库中信息是在不同的业务系统中进行集成,并经过一系列加工、整理和汇总等过程,形成规范性的关于确定主题的一致的全局信息,可以对这些数据进行频繁的可重复的分析。

因此大数据背景下的数仓能力不能实现对数据仓库的替代,但是大数据的先进技术可以实现用来促进数仓的架构的演进,在这种趋势下出现的新型数据仓库产品有ClickHouse、Doris、StarRocks等产品,这些产品具有以下特征:

  • 现代化的MPP架构,实现了向量化执行引擎、编译执行、提高查询的实时性(支持高并发小查询)等;
  • 重新定义了数据存储引擎,可以支持大规模数据集,例如使用LMS的列式存储引擎、针对列创建ZoneMap索引来进行针对性过滤、MVCC事务隔离机制等;
  • 重新定义了数据分布与副本管理机制,可以支持大数据集的灵活管理。在小查询时只需要使用部分机器资源能够提高并发查询量;机器扩缩容时迁移部分数据分片可,不影响线上服务,负载均衡可以自动实现;
  • 新型的预聚合机制,能够做到数据的自动更新、查询的智能路由、实时数据的增量聚合计算等,例如Rollup机制,在数据导入时自动完成汇聚。

这里以Doris为例,其在整体上整合Google Mesa存储模型、Impala MPP查询引擎和ORC file存储格式(在格式的基础上进行优化)等先进技术。

与传统的MPP数仓每个实例都基于传统关系型数据库技术不同,现代化数仓根据AP的大量表扫描的特征重新定义了数据的存储引擎。与传统MPP数仓的不同,Doris使用了LSM(Log Structured Merge)树架构,这个也是目前大数据存储系统(HBase、LevelDB、RocksDB等)常用的技术,如下图所示:

核心思路是将最新的数据驻留在缓存中,等积累到一定量后再使用归并合并的方式将缓存中的数据合并到磁盘队尾中。数据写入时先在内存中组成Mem Table,其内的数据是经过排序的数据,当达成一定程度后将其添加到LSM Tree中,这些相邻的SSTable不保证有序,在后台会启动定时任务进行合并。为了加快数据的读取,大部分的LSM结构中会基于Key的索引和Bloom Filter来快速过滤查询Key,减少IO数据的访问。读取流程如下:

在数据建模方法Doris支持Aggregate、Unique和Duplicate等模型可以满足OLAP领域的各种应用模型,为了提高高并发的点查能力实现Unique存储模型和行缓存等技术;新型预聚合技术Rollup、Cube、智能物化视图技术实现预聚合加速,从而实现用户近实时查询。但是传统的数据仓库依赖与数据的Cube来进行数据的预处理,无法支持数据持续导入或者聚合的同时提供近实时的用户查询能力。

在数据导入方面在内部集成了多种数据导入方式实现不同数据源导入的过程中提供原子性保证。在集群扩缩上Doris与传统MPP数仓不同的地方在于借鉴了大数据技术中常用的分布式管理框架,可以自动管理数据副本的分布、恢复和均衡,在整个过程中不影响系统服务。

5.云数仓

传统数仓将计算与存储部署在同一个节点,集群的扩容复杂,需要进行数据的迁移,同时架构存在木桶效应,单节点故障会影响整体的性能,且资源管理不灵活,无法满足不同场景下资源隔离及动态调整的需求。云计算的出现为数仓架构的演进提供了新的方向,赋予数仓获得自服务、弹性等能力,同时目前企业将基础系统、平台部署到云端降低信息化建设成本及优化运行管理流程等成为趋势。

数仓在云端提供服务可以利用公有云强大的基础设施能力(弹性计算、存储、网络及安全能力),同时让用户更加轻松将数据进行集成,并降低使用、维护与架构成本。这就产生了云数仓(基于云原生的数据仓库),业界没有明确的定义,但是Snowflake是云数仓的里程碑产品,目前出现的云数仓产品很多都会借鉴该产品的设计思想,架构如下图所示:

云数仓、现代MPP架构都可以称为现代化数仓,但是这两种产品体系都是对传统数仓进行了不同角度的革新,现代MPP架构是从底层存储引擎角度(数据的组织与计算优化)而云数仓是从基础架构的角度进行了升级。云数仓的基本特征如下:

  • 计算与存储分离(Disaggregation),在云环境下网络传输能力已经基本上能追上磁盘的IO的能力,存算分离后可以实现存储的横向扩展,并且在计算低峰时进行缩容,进一步降低数据分析的成本,最后是可以根据数据的热度进行存储分级,保证性能的同时进一步降低存储成本;存储不再是服务本身的一部分,演变为独立的服务,扩容无需数据的重分布;
  • 资源扩展秒级弹性,计算层实现无状态可以随时扩缩容,并且随时热升级,为了实现无状态需要对元数据进行“分解”,计算层无状态后才能够随机增减节点、故障后快速切换且不需要复制/迁移数据,从而实现可靠性的提升及降低成本;弹性的扩缩可以基于定时或者负载(Workload Manager)等规则来控制,在资源不需要时可以进行关闭;
  • 数据共享(Multi Cluster, Shared Data),计算资源可以根据不同的业务进行划分后构成虚拟数仓,虚拟数仓共享底层的数据,可以通过MVCC机制来实现数据访问的一致性。

在公有云中云数仓以服务的模式来进行交互,降低数据仓库的管理复杂度,用户将运维、升级等工作交由云厂商来实现,并且以Web的方式来使用数据仓库服务。目前各种云数仓产品层出不穷,从公有云厂商推出的Google BigQuery、Redshift、Synapse、Snowflake、国内云厂商的阿里云ADB、华为云GaussDB、移动云海山数仓,到近期开源的DataBend、ByConity等,这些产品之间的功能基本相同,只是在技术细节的实现各有不同。

移动云云原生数据库海山数仓产品是中国移动自主研发的云原生分析型(OLAP)数据库。采用基于 Shared-Data与存储计算分离架构,具备zero-ETL能力,具备水平在线扩缩容,金融级高可用,提供全面向量化引擎与多种数据源联邦查询等重要特性。兼容 MySQL 协议和 MySQL 生态。支持海量数据在线查询,复杂查询快速响应,多维数据查询分析等。不仅有力辅助企业客户驾驭复杂的计算场景与海量数据需求,简化数据流转流程,使用户得以快速洞悉业务运营的真实面貌,而且还能有效帮助企业抓住数据时代的战略机遇,驱动业务模式的创新与升级。

6.总结

数据仓库从概念提出后随着用户使用需求的变化、新技术的出现等多种因素促使架构不断演进,在这个过程中不同的厂商针对各自的观点和需求,例如原始数据(数据湖)、实时性、多模数据及机器学习等,不断的在进行架构优化和新技术的引入,针对数仓的概念也在不断的重新定义,下图对这些概念进行了总结:

  

在图中数据库、数据仓库与数据湖保持明确的功能定位,产品体系的界限相对比较清晰,但是随着技术的发展,产品也在相互借鉴融合。数据仓库由于对数据实时性的需求演进到了实时数仓,在这个过程中数据的实时接入框架、查询性能的提升、交互式查询等能力让数仓的实现复杂化;为了面向满足不同数据类型的需求,数据仓库逐步进行数据的融合处理,形成了湖仓、多模数据库的概念。随时云原生技术的发展,目前各种类型的数据仓库在加速向云架构转型,力求打造新一代云数据仓库。目前在业界虽然数仓的产品数量及类型较多,但从技术实现的角度观察,它们正在朝着相似的核心技术和设计理念靠拢例如向量化执行、编译执行、计算Pipeline模型、计算存储分离、灵活弹缩等。

7.参考链接

1)数据仓库发展史:数据库发展史2--数据仓库_Data_Oracle_Inmon

2)从数仓架构到大数据架构的九种演进:https://mp.weixin.qq.com/s/5AjL6b9SleMERfRiWmycxg

3)从Snowflake看数据仓库未来演进方向:https://www.infoq.cn/article/Afr0uCxfAXsRBzLQQ24N

4)DB Engine 数据库排行及介绍 : https://db-engines.com/en/

5)墨天轮中国数据库流行度排行:https://www.modb.pro/dbRank

5)CliBench数据仓库评测:https://benchmark.clickhouse.com

7)各产品官网与开源社区:

https://github.com/ClickHouse/ClickHouse

https://github.com/apache/doris

https://github.com/greenplum-db/gpdb

https://clickhouse.com/

Apache Doris: Open-Source Real-Time Data Warehouse - Apache Doris

https://github.com/datafuselabs/databend

https://github.com/ByConity

  1. 作者介绍:

冯永设,中国移动云能力中心数据库产品部-OLAP数据库开发工程师。主要参与OLAP数据库产品架构设计/内核优化等工作。

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

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

相关文章

tensorflow.js 如何使用opencv.js通过面部特征点估算脸部姿态并绘制示意图

文章目录 前言一、实现步骤1. 获取所需特征点的索引2. 使用opencv.js 计算俯仰角、水平角和翻滚角cv.solvePnP介绍cv.solvePnP原理运行代码查看效果 3.绘制姿态示意直线添加canvas元素计算姿态直线坐标并绘制 总结 前言 在计算机视觉领域,估算脸部姿态是一项具有挑…

(虚拟DOM)前端八股文修炼Day10

一 虚拟 DOM 是什么 虚拟 DOM (Virtual DOM) 本质上是真实 DOM 的一个轻量级的 JavaScript 表示形式。它是一个在内存中的抽象,用于描述真实 DOM 的结构和内容。虚拟 DOM 提供了一种机制,允许开发者通过操作 JavaScript 对象来间接更新页面,…

GitHub教程:最新如何从GitHub上下载文件(下载单个文件或者下载整个项目文件)之详细步骤讲解(图文教程)

🐯 GitHub教程:最新如何从GitHub上下载文件(下载单个文件或者下载整个项目文件)之详细步骤讲解(图文教程) 📁 文章目录 🐯 GitHub教程:最新如何从GitHub上下载文件(下载单个文件或者下载整个项目文件)之详细步骤讲解(图…

0104练习与思考题-算法基础-算法导论第三版

2.3-1 归并示意图 问题:使用图2-4作为模型,说明归并排序再数组 A ( 3 , 41 , 52 , 26 , 38 , 57 , 9 , 49 ) A(3,41,52,26,38,57,9,49) A(3,41,52,26,38,57,9,49)上的操作。图示: tips::有不少在线算法可视化工具(软…

鸿蒙内核源码分析 (内存管理篇) | 虚拟内存全景图是怎样的

初始化整个内存 OsSysMemInitOsMainmain从 main() 跟踪可看内存部分初始化是在 OsSysMemInit() 中完成的。 UINT32 OsSysMemInit(VOID) {STATUS_T ret;OsKSpaceInit();//内核空间初始化ret OsKHeapInit(OS_KHEAP_BLOCK_SIZE);// 内核动态内存初始化 512K if (ret ! LOS_OK…

一款轻量、干净的 Laravel 后台管理框架

系统简介 ModStart 是一个基于 Laravel 的模块化快速开发框架。模块市场拥有丰富的功能应用,支持后台一键快速安装,让开发者能快的实现业务功能开发。 系统完全开源,基于 Apache 2.0 开源协议,免费且不限制商业使用。 系统特性 …

第三、四章 if语句 + 循环

第三章 if语句 bool类型 两种:True和False bool_1 True bool_2 False print(f"bool_1变量的内容是:{bool_1}," f"类型是:{type(bool_1)}") print(f"bool_2变量的内容是:{bool_2}," f"类…

解决Selenium元素拖拽不生效Bug

前几天在使用Selenium进行元素拖拽操作时,发现Selenium自带的元素拖拽方法(dragAndDrop())不生效,网上的回答也是五花八门,比较混乱,尝试了以下几种方法均无法解决。 方案1:通过dragAndDrop()方…

外部模块介绍(七) 蓝牙HC05

HC05原理图 2. 蓝牙模块的调试 2.1 两种工作模式: HC-05蓝牙串口通讯模块具有两种工作模式:命令响应工作模式和自动连接工作模式。在自动连接工作模式下模块又可分为主(Master)、从(Slave)和回环(Loopback)三种工作角色。 当模块处于自动连接工作模式时,将自动根据事…

二叉树练习day.3

104.二叉树的最大深度 链接:. - 力扣(LeetCode) 题目描述: 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1: 输入:root…

pygame旋转直线,计算角色到墙距离

pygame怎么计算距离 在Pygame中,计算两点之间的距离可以使用几何公式。给定两点P1(x1, y1)和P2(x2, y2),距离D可以用以下公式计算: D √((x2 - x1) (y2 - y1)) 在Python中,你可以使用math库中的sqrt函数来计算平方根。以下是一…

34-5 CSRF漏洞 - CSRF分类

环境准备:构建完善的安全渗透测试环境:推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 1)GET 类型 传参: 参数连接在URL后面 POC构造及执行流程: 构造URL,诱导受害者访问点击利用利用标签进行攻击: 构造虚假URL,在链接上添加payload抓包获取数据包,通过CSRF POC…

excel散点图怎么每个点添加名称

最终效果图: 添加图标元素->数据标签->其他数据标签选项 选择单元格中的值 手动拖动数据标签,调整到合适的位置。

C语言从入门到实战————编译和链接

目录 前言 1. 翻译环境和运行环境 2. 翻译环境 2.1 预处理(预编译) 2.2 编译 2.2.1 词法分析: 2.2.2 语法分析 2.2.3 语义分析 2.3 汇编 2.4 链接 3. 运行环境 前言 编译和链接是将C语言源代码转换成可执行文件的必经过程&a…

Java面试八股文(更新中)

Java面试八股文 1. 基础篇1.1 Java语言特点1.2 面向对象和面向过程的区别1.3 八种基本数据类型的大小,以及他们的封装类1.4 标识符的命名规则1.5 instanceof 关键字的作用 ************************************************************* 1. 基础篇 1.1 Java语言特…

【Java网络编程】计算机网络基础概念

就目前而言,多数网络编程的系列的文章都在围绕着计算机网络体系进行阐述,但其中太多理论概念,对于大部分开发者而言,用途甚微。因此,在本系列中则会以实际开发者的工作为核心,从Java程序员的角度出发&#…

测试自动化流程设计思路

a) 背景介绍 基于当前互联网敏捷开发的现状,手工人力测试已不足以满足当前快速的版本迭代;以下将介绍一种可实现的自动化设计与使用。 b) 当前版本迭代流程 研发同学从代码库master分支拉出新代码进行研发工作得开发开发完成之后提交到代码库测试同学介入…

ES入门十一:正排索引和倒排索引

索引本质上就是一种加快检索数据的存储结构,就像书本的目录一下。 为了更好的理解正排索引和倒排索引,我们借由一个 **唐诗宋词比赛,**这个比赛一共有两个项目: 给定诗词名称,背诵整首给诗词中几个词语,让…

构建第一个ArkTS用的资源分类与访问

应用开发过程中,经常需要用到颜色、字体、间距、图片等资源,在不同的设备或配置中,这些资源的值可能不同。 应用资源:借助资源文件能力,开发者在应用中自定义资源,自行管理这些资源在不同的设备或配置中的表…

男生穿什么裤子显腿长?男生显腿长裤子分享

现在市面上出现很多劣质而且不耐洗不耐穿的裤子,不但穿着体验感差,而且还可能会对皮肤有影响。为此作为一名穿搭博主,我专门做了这篇关于男生裤子的测评,希望大家能够通过一下的科普知识,对选择裤子有更详细的了解。 什…