深入理解HDFS工作原理:大数据存储和容错性机制解析

**

引言:

关联阅读博客文章:深入解析大数据体系中的ETL工作原理及常见组件
关联阅读博客文章:探讨在大数据体系中API的通信机制与工作原理
关联阅读博客文章:深入理解 Hadoop 上的 Hive 查询执行流程
关联阅读博客文章:深入理解MapReduce:从Map到Reduce的工作原理解析
关联阅读博客文章:深度剖析:计算机集群在大数据体系中的关键角色和技术要点

**

在当今数据爆炸的时代,存储和管理大规模数据成为了许多组织面临的重要挑战。为了解决这一挑战,分布式文件系统应运而生。Hadoop分布式文件系统(HDFS)作为Apache Hadoop生态系统的核心组件之一,已经成为处理大数据的事实标准之一。它以其高可靠性、高容错性和高可用性等特点,在大规模数据存储和处理方面发挥着关键作用。

首先,我们将了解HDFS是如何通过数据分片和数据复制等机制来实现数据的高可靠性存储和容错性。随后,我们将探讨HDFS中节点角色的分工,包括NameNode和DataNode,以及它们是如何协同工作来管理文件系统和存储数据的。接着,我们将讨论HDFS的容错性机制,包括数据复制、健康检查和自动恢复等,以及如何确保系统在面对节点故障或其他异常情况时能够保持正常运行。

HDFS工作原理解析

1. 数据分片(Data Splitting)

HDFS将大文件分割成固定大小的数据块(通常默认为128MB或256MB),并将这些数据块存储在分布式集群中的不同节点上。每个数据块通常在多个节点上复制,以提供容错性和高可用性。

- block bytes -- 块字节 ack  -- 确认 datanode -- 数据节点  Block write complete -- 块写入完成

当文件写入HDFS时,HDFS将文件划分为块并负责其复制。此操作(大部分)执行一次,然后可供集群上运行的所有 MR 作业使用。这是集群范围的配置;

数据分片的基本工作原理

  1. 文件切分:当一个大文件要被存储到HDFS中时,HDFS会将该文件切分成一个个固定大小的数据块。通常情况下,数据块的大小由HDFS的配置决定,默认情况下通常是128MB或256MB。

  2. 数据块存储:切分后的数据块会被分布式地存储在HDFS集群的不同节点上。这些节点称为DataNode。每个数据块通常会存储在多个DataNode上,以提供数据的冗余备份,以防止数据丢失。

  3. 数据块的副本
    HDFS会为每个数据块创建多个副本,并将这些副本分布存储在不同的DataNode上。这样做有两个目的:
    1.提高数据的可靠性和容错性:当某个DataNode或数据块发生故障时,可以从其他副本中恢复数据。
    2.提高数据的读取性能:客户端可以从距离更近的副本读取数据,减少网络传输的开销。

  4. 数据块的位置信息:NameNode负责维护文件系统的元数据,包括文件和数据块的位置信息。客户端在访问文件时会先与NameNode通信,获取数据块的位置信息,然后直接与相应的DataNode通信进行数据读取或写入操作。

  5. 数据块的管理:HDFS会定期检查数据块的完整性,并在发现数据块损坏或丢失时进行修复。如果某个数据块的副本数低于指定的阈值,HDFS会自动创建新的副本来替换丢失的副本。

**

2.节点角色

**
在Hadoop分布式文件系统(HDFS)中,有两种主要类型的节点扮演不同的角色:NameNode 和 DataNode。

  • HDFS采用master/slave架构。一个HDFS集群是由一个Namenode和一定数目的Datanodes组成。Namenode是一个中心服务器,负责管理文件系统的名字空间(namespace)以及客户端对文件的访问。集群中的Datanode一般是一个节点一个,负责管理它所在节点上的存储。HDFS暴露了文件系统的名字空间,用户能够以文件的形式在上面存储数据。从内部看,一个文件其实被分成一个或多个数据块,这些块存储在一组Datanode上。Namenode执行文件系统的名字空间操作,比如打开、关闭、重命名文件或目录。它也负责确定数据块到具体Datanode节点的映射。Datanode负责处理文件系统客户端的读写请求。在Namenode的统一调度下进行数据块的创建、删除和复制。

HDFS Architecture --HDFS架构 Namenode --名称节点 metadata ops  --元数据操作 client  --客户 read  --读 rack  --架子 write  --写 replication  --复制 blocks --块

  • Namenode和Datanode被设计成可以在普通的商用机器上运行。这些机器一般运行着GNU/Linux操作系统(OS)。HDFS采用Java语言开发,因此任何支持Java的机器都可以部署Namenode或Datanode。由于采用了可移植性极强的Java语言,使得HDFS可以部署到多种类型的机器上。一个典型的部署场景是一台机器上只运行一个Namenode实例,而集群中的其它机器分别运行一个Datanode实例。这种架构并不排斥在一台机器上运行多个Datanode,只不过这样的情况比较少见。

    集群中单一Namenode的结构大大简化了系统的架构。Namenode是所有HDFS元数据的仲裁者和管理者,这样,用户数据永远不会流过Namenode。

1.NameNode

  • NameNode 是HDFS的关键组件之一,负责管理文件系统的命名空间和文件的元数据。
  • NameNode 维护了文件系统的目录结构,以及每个文件的元数据信息,如文件名、文件大小、数据块的位置等。
  • 当客户端请求读取或写入文件时,NameNode负责确定数据块的位置信息,并将这些信息返回给客户端。
  • NameNode是单点故障,因为所有文件系统的元数据都存储在它的内存中。为了防止元数据丢失,通常会定期备份元数据,并启用NameNode的高可用性解决方案,如HA(High Availability)。

2.DataNode:

  • DataNode 是HDFS中存储实际数据的节点,它负责存储和检索数据块。
  • 当客户端向HDFS写入数据时,DataNode 接收客户端发送的数据块,并将其存储在本地文件系统上。
  • 当客户端请求读取文件时,DataNode 负责从本地文件系统读取数据块并将其传输给客户端。
  • DataNode 在运行时向NameNode发送心跳消息,用于报告节点的健康状况以及数据块的状态。

3.节点角色工作原理

  • 客户端与NameNode通信,获取文件的元数据信息。
  • NameNode 返回文件的元数据信息给客户端。
  • 客户端根据元数据信息直接与DataNode通信,进行数据读取或写入操作。
  • DataNode 在写入或读取数据时,负责与客户端进行实际的数据传输。

**

3.数据访问

**
数据访问是指客户端从HDFS中读取数据或向HDFS中写入数据的过程。以下是数据访问的基本工作原理:

1.读取数据的工作原理

  • 客户端首先与NameNode通信,请求读取特定文件的数据。客户端提供文件路径等信息给NameNode。
  • NameNode返回包含文件的元数据信息,包括文件的大小、数据块的位置等。
  • 客户端根据元数据信息确定数据块的位置,并向对应的DataNode发送读取请求。
  • DataNode接收到读取请求后,从本地存储中读取数据块,并将数据返回给客户端。

2.写入数据的工作原理

  • 客户端首先与NameNode通信,请求将数据写入到指定的文件中。客户端提供文件路径等信息给NameNode。
  • NameNode确定数据写入的位置以及数据块的分配情况,并将这些信息返回给客户端。
  • 客户端将数据按照数据块进行分割,并将每个数据块发送给对应的DataNode。
  • DataNode接收到数据块后,负责存储数据,并向客户端发送确认信息,表示数据写入操作完成。

3.数据块的复制与容错处理

  • 在数据写入过程中,HDFS会根据副本配置策略,在集群中的其他DataNode上创建相应数量的数据块副本。这些副本的创建是异步进行的,并且在后台由HDFS系统自动管理。
  • 当某个DataNode或数据块发生故障时,HDFS能够自动检测到故障并进行处理。如果某个数据块的副本数低于指定的阈值,HDFS会自动创建新的副本来替换丢失的副本。
    在这里插入图片描述

步骤1:客户端通过调用文件系统对象(对于HDFS来说是分布式文件系统的一个实例)上的open()来打开它希望读取的文件。

步骤 2:分布式文件系统 (DFS) 使用远程过程调用 (RPC) 调用名称节点,以确定文件中前几个块的位置。对于每个块,名称节点返回具有该块副本的数据节点的地址。 DFS 将 FSDataInputStream 返回给客户端以供其读取数据。 FSDataInputStream 又包装了一个 DFSInputStream,它管理数据节点和名称节点 I/O。

步骤 3:然后客户端在流上调用 read()。 DFSInputStream 存储了文件中主要几个块的信息节点地址,然后连接到文件中主要块的主要(最近)数据节点。

步骤 4:数据从数据节点流式传输回客户端,客户端在流上重复调用 read()。

步骤5:当到达块的末尾时,DFSInputStream将关闭与数据节点的连接,然后为下一个块寻找最佳数据节点。这对客户端来说是透明的,从客户端的角度来看,这只是在读取无尽的流。块被读取为,DFSInputStream 打开到数据节点的新连接,因为客户端读取流。它还将根据需要调用名称节点来检索下一批块的数据节点位置。

第 6 步:当客户端完成读取文件后,将调用 FSDataInputStream 上的 close() 函数。

**

4.数据复制

**
数据复制是指在HDFS中将数据块复制到多个节点以增加数据的容错性和可用性。

  • HDFS被设计成能够在一个大集群中跨机器可靠地存储超大文件。它将每个文件存储成一系列的数据块,除了最后一个,所有的数据块都是同样大小的。为了容错,文件的所有数据块都会有副本。每个文件的数据块大小和副本系数都是可配置的。应用程序可以指定某个文件的副本数目。副本系数可以在文件创建的时候指定,也可以在之后改变。HDFS中的文件都是一次性写入的,并且严格要求在任何时候只能有一个写入者。
    Namenode全权管理数据块的复制,它周期性地从集群中的每个Datanode接收心跳信号和块状态报告(Blockreport)。接收到心跳信号意味着该Datanode节点工作正常。块状态报告包含了一个该Datanode上所有数据块的列表。
    在这里插入图片描述

副本存放: 最最开始的一步

  • 副本的存放是HDFS可靠性和性能的关键。优化的副本存放策略是HDFS区分于其他大部分分布式文件系统的重要特性。这种特性需要做大量的调优,并需要经验的积累。HDFS采用一种称为机架感知(rack-aware)的策略来改进数据的可靠性、可用性和网络带宽的利用率。目前实现的副本存放策略只是在这个方向上的第一步。实现这个策略的短期目标是验证它在生产环境下的有效性,观察它的行为,为实现更先进的策略打下测试和研究的基础。大型HDFS实例一般运行在跨越多个机架的计算机组成的集群上,不同机架上的两台机器之间的通讯需要经过交换机。在大多数情况下,同一个机架内的两台机器间的带宽会比不同机架的两台机器间的带宽大。通过一个机架感知的过程,Namenode可以确定每个Datanode所属的机架id。一个简单但没有优化的策略就是将副本存放在不同的机架上。这样可以有效防止当整个机架失效时数据的丢失,并且允许读数据的时候充分利用多个机架的带宽。这种策略设置可以将副本均匀分布在集群中,有利于当组件失效情况下的负载均衡。但是,因为这种策略的一个写操作需要传输数据块到多个机架,这增加了写的代价。在大多数情况下,副本系数是3,HDFS的存放策略是将一个副本存放在本地机架的节点上,一个副本放在同一机架的另一个节点上,最后一个副本放在不同机架的节点上。这种策略减少了机架间的数据传输,这就提高了写操作的效率。机架的错误远远比节点的错误少,所以这个策略不会影响到数据的可靠性和可用性。于此同时,因为数据块只放在两个(不是三个)不同的机架上,所以此策略减少了读取数据时需要的网络传输总带宽。在这种策略下,副本并不是均匀分布在不同的机架上。三分之一的副本在一个节点上,三分之二的副本在一个机架上,其他副本均匀分布在剩下的机架中,这一策略在不损害数据可靠性和读取性能的情况下改进了写的性能。

数据复制的基本工作原理:

  • 副本配置
    HDFS的副本配置是通过参数设置的,通常在Hadoop集群的配置文件中指定。这些参数包括每个数据块的副本数目以及副本放置策略。

  • 副本创建:
    当客户端向HDFS写入数据时,根据副本配置,HDFS会在写入数据块时为每个数据块创建指定数量的副本。这些副本通常存储在集群中的不同节点上。

  • 副本放置
    1.HDFS会根据副本放置策略,将数据块的副本分布在集群的不同节点上。默认情况下,HDFS会尽量将副本分布在不同的机架上,以降低机架级别的故障对数据的影响。
    2.如果集群中有多个机架,则HDFS会将数据块的副本均匀分布在这些机架上。这样做可以提高数据的容错性,以防止机架级别的故障导致数据不可用。

  • 副本管理:
    1.HDFS会定期检查数据块的副本情况,并根据需要创建新的副本或删除多余的副本。如果某个副本因节点故障或其他原因不可用,HDFS会自动将其替换为新的副本,以保证数据的可靠性和可用性。
    2.当客户端向HDFS写入数据时,如果数据块的副本数低于指定的阈值,HDFS会立即创建新的副本,以确保数据的容错性。

  • 副本同步
    当数据块的主副本更新时,HDFS会通过后台线程将这些更新同步到其他副本上。这样可以确保所有副本的数据保持一致性。

**

5.容错性

**
容错性是指系统在面对硬件故障、软件错误或其他异常情况时能够保持正常运行的能力。容错性是通过以下几种机制来实现的:

数据复制

  • HDFS将数据切分为固定大小的数据块,并在集群中多个节点上存储数据块的副本。当某个节点或数据块发生故障时,HDFS能够从其他副本中恢复数据,确保数据的可靠性和可用性。
    在这里插入图片描述
  • 创建的副本数量取决于复制因子,默认情况下为3。如果任何计算机出现故障,则可以从包含相同数据副本的另一台计算机访问该数据块。因此,不会因为副本存储在不同的机器上而导致数据丢失。

HDFS复制机制示例
在这里插入图片描述
假设用户存储一个文件。 HDFS 将这个文件分成块;说 B1、B2、B3、B4 和 B5。假设有五个数据节点,即 D1、D2、D3、D4 和 D5。 HDFS为每个块创建副本并将其存储在不同的节点上以实现容错。对于每个原始块,将在不同节点上存储三个副本(复制因子3)。让块1存储在数据节点D1、D2和D3上,块2存储在数据节点D1、D4和D5上,其他3个块类似。如果数据节点 1 发生故障,则用户仍可从数据节点(B1 为 D2、D3)、B2(B2 为 D4、D5)和(B4 为 D2、D5)使用 D1 中存在的块 1、2 和 4。因此,即使在不利的条件下,也不会丢失数据。

健康检查和心跳机制

  • DataNode定期向NameNode发送心跳消息,报告节点的健康状况以及数据块的状态。如果NameNode在一定时间内未收到某个DataNode的心跳消息,则会将该节点标记为不可用,并将其上的数据块副本复制到其他节点上,以确保数据的容错性。

故障检测和自动恢复

  • HDFS能够自动检测到节点或数据块的故障,并在必要时进行故障处理和数据恢复。当某个数据块的副本数低于指定的阈值时,HDFS会自动创建新的副本以保证数据的完整性。

高可用性解决方案

  • HDFS提供了一些高可用性解决方案,如NameNode的HA(HighAvailability),通过在集群中运行多个NameNode实例,并使用共享存储或共享编辑日志来实现故障切换,以提高NameNode的可用性。

数据校验

  • HDFS在存储数据时会使用数据校验和(checksum)来验证数据的完整性。当数据被读取时,HDFS会校验数据的完整性,以检测数据的损坏或篡改,并在必要时重新获取数据块的副本。

**

6.数据写入流程

**
数据写入流程是指将数据写入到HDFS中的过程,包括客户端向HDFS写入数据的整个流程。以下是数据写入流程的基本工作原理:

客户端请求:

  • 客户端向HDFS发送写入请求,请求将数据写入到指定的文件中。

NameNode操作:

  • 客户端与NameNode通信,请求向文件中写入数据。NameNode负责管理文件系统的元数据,包括文件的命名空间、文件和数据块的位置信息等。

数据块分配:

  • NameNode确定数据写入的文件位置以及数据块的分配情况。它会告知客户端应该将数据写入到哪些数据块中,以及这些数据块在集群中的位置。

数据写入:

  • 客户端按照NameNode返回的信息,将数据按照数据块进行分割,并通过网络发送给集群中的DataNode。
  • 客户端与DataNode进行直接通信,将数据写入到指定的数据块中。数据写入过程中,DataNode负责存储数据并确认写入操作的完成。

数据复制

  • 当数据写入完成后,HDFS会根据副本配置策略,在集群中的其他DataNode上创建相应数量的数据块副本。这些副本的创建是异步进行的,并且在后台由HDFS系统自动管理。

确认写入

  • DataNode在完成数据写入操作后向客户端发送确认信息,告知客户端数据写入操作的状态。客户端收到确认信息后,可以继续执行后续操作。

元数据更新

  • 在数据写入操作完成后,NameNode会更新文件系统的元数据,包括文件的大小、数据块的位置信息等。这样可以确保文件系统的元数据与实际数据存储的一致性。

总的来说,数据写入流程是客户端与NameNode和DataNode之间进行交互的过程,考虑配图以更好地理解这个概念
在这里插入图片描述
步骤1:客户端通过调用DistributedFileSystem(DFS)上的create()来创建文件。

第 2 步: DFS 对名称节点进行 RPC 调用,以在文件系统的命名空间中创建一个新文件,并且没有与其关联的块。名称节点执行各种检查以确保该文件尚不存在并且客户端具有创建该文件的正确权限。如果这些检查通过,名称节点会准备新文件的记录;否则,无法创建该文件,因此客户端会抛出错误,即 IOException。 DFS 返回一个 FSDataOutputStream 供客户端开始写入数据。

步骤 3:由于客户端写入数据,DFSOutputStream 将其拆分为数据包,并将其写入称为信息队列的室内队列。数据队列由 DataStreamer 消耗,DataStreamer 负责要求名称节点通过选择合适的数据节点清单来存储副本来分配新块。数据节点列表形成一个管道,这里我们假设复制级别为三,因此管道中有三个节点。 DataStreamer 将数据包流式传输到管道内的主数据节点,该节点存储每个数据包并将其转发到管道内的第二数据节点。

步骤 4:类似地,第二个数据节点存储数据包并将其转发到管道中的第三个(也是最后一个)数据节点。

步骤 5: DFSOutputStream 维护等待数据节点确认的数据包的内部队列,称为“ack 队列”。

步骤 6:此操作将所有剩余数据包发送到数据节点管道,并在连接到名称节点以指示文件是否完整之前等待确认。

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

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

相关文章

数据结构二叉树顺序存储——堆

堆 1.堆的概念2.堆的实现 (建小堆为例)2.1 初始化和销毁2.2 判空2.3 获得堆顶元素和堆的大小2.4 插入2.5 删除 3.堆的构建(建小堆为例) 1.堆的概念 将若干数据或元素按照完全二叉树的存储方式顺序存储到一个一维数组中&#xff0…

深度学习armv8/armv9 cache的原理

快速链接: 【精选】ARMv8/ARMv9架构入门到精通-[目录] 👈👈👈 本文转自 周贺贺,baron,代码改变世界ctw,Arm精选, 资深安全架构专家,11年手机安全/SOC底层安全开发经验。擅长trustzon…

【pytest、playwright】多账号同时操作

目录 方案实现思路: 方案一: 方案二: 方案实现思路: 依照上图所见,就知道,一个账号是pytest-playwright默认的环境,一个是 账号登录的环境 方案一: 直接上代码: imp…

Node.js-------初识Node.js与内置模块

能够知道什么是 Node.js能够知道 Node.js 可以做什么能够说出 Node.js 中的 JavaScript 的组成部分能够使用 fs 模块读写操作文件能够使用 path 模块处理路径能够使用 http 模块写一个基本的 web 服务器 一.初识Node.js 1.浏览器中的 JavaScript 的组成部分 2.Node.js 简介 …

使用Pollard_rho算法分解质因数

分解质因数的朴素算法 最简单的算法即为从 [2, sqrt&#xff08;N&#xff09;] 进行遍历。 vector<int> breakdown(int N) {vector<int> result;for (int i 2; i * i < N; i) {if (N % i 0) { // 如果 i 能够整除 N&#xff0c;说明 i 为 N 的一个质因子。…

iOS苹果签名共享签名是什么以及如何获取?

哈喽&#xff0c;大家好呀&#xff0c;咕噜淼淼又来和大家见面啦&#xff0c;最近有很多朋友都来向我咨询共享签名iOS苹果IPA共享签名是什么&#xff0c;针对这个问题&#xff0c;淼淼来解答一下大家的疑惑并告诉大家iOS苹果ipa共享签名需要如何获取。 现在苹果签名在市场上的…

Autodesk Maya 2025---智能建模与动画创新,重塑创意工作流程

Autodesk Maya 2025是一款顶尖的三维动画软件&#xff0c;广泛应用于影视广告、角色动画、电影特技等领域。新版本在功能上进行了全面升级&#xff0c;新增了对Apple芯片的支持&#xff0c;建模、绑定和角色动画等方面的功能也更加出色。 在功能特色方面&#xff0c;Maya 2025…

CVPR 2024 | 从6篇论文看扩散模型diffusion的改进方向

1、Accelerating Diffusion Sampling with Optimized Time Steps 扩散概率模型&#xff08;DPMs&#xff09;在高分辨率图像生成方面显示出显著性能&#xff0c;但由于通常需要大量采样步骤&#xff0c;其采样效率仍有待提高。高阶ODE求解在DPMs中的应用的最新进展使得能够以更…

从PDF到高清图片:一步步学习如何转换PDF文件为高清图片

引言 PDF文件是一种便携式文档格式&#xff08;Portable Document Format&#xff09;&#xff0c;最初由Adobe Systems开发&#xff0c;用于在不同操作系统和软件之间保持文档格式的一致性。PDF文件通常包含文本、图片、图形等多种元素&#xff0c;并且可以以高度压缩的方式存…

Redis配置与优化

目录 引言 一、关系型数据库与非关系型数据库 1、关系型数据库 2、非关系型数据库 3、关系型数据库和非关系型数据库的区别 1.数据存储方式不同 2.扩展方式不同 3.对事物性的支持不同 4、非关系型数据库产生背景 二、Redis简介 1、Redis优点 2、Redis为什么这麽快&…

hcip实验4:gre mgre ppp综合实验

实验拓扑: 实验目的&#xff1a; 1.R5为ISP&#xff0c;只能进行IP地址配置&#xff0c;其所有地址均配为公有IP地址 2.R1和R5间使用PPP的PAP认证&#xff0c;R5为主认证方&#xff1b;R2与R5之间使用ppp的CHAP认证&#xff0c;R5为主认证方;R3与R5之间使用HDLC封装; 3.R1、R…

vue+elementUI搭建动态表头的表格

前提&#xff1a;以下代码是vue2项目结合elementUi完成的 数据结构 后端传来的数据是两个list&#xff0c;一个表头的list&#xff0c;一个表格内容的list // 表头 headTableAtts: [{ columnLabel: 姓名, columnName: name },{ columnLabel: 年龄, columnName: age },{ colu…

计算机网络面试问题(一)

1.在浏览器中输⼊URL并按下回⻋之后会发⽣什么 2.TCP三次握⼿的过程,为什么三次握手 TCP&#xff08;传输控制协议&#xff09;的三次握⼿是建⽴⽹络连接的过程&#xff0c;确保通信双⽅能够正确地进⾏数据传输。 第⼀次握⼿&#xff08;SYN&#xff09;&#xff1a; 客户端&am…

[羊城杯 2020]EasySer

[羊城杯 2020]EasySer 进入页面&#xff0c;发现是ubuntuapache2&#xff0c;但是好像没啥用 尝试访问/robots.txt&#xff0c;得到 访问/star1.php/&#xff0c;查看源码&#xff0c;得到提示 一看就知道是ssrf&#xff0c;使用http://127.0.0.1/ser.php&#xff0c;得到…

Spring日志框架

前言 本文我们简单说说关于Spring中的日志框架,以及对应的注解 我们知道,公司服务器在运行的时候,一定会打印日志,有很多优点,比如预防报警,或者是某重大事故尝试修复等等都需要查看日志 应该说日志对我们来说并不陌生,我们在之前刷题或者是程序遇到bug的时候也经常会将程序的状…

windows 系统图标 桌面刷新 位置变化解决办法

Windows操作系统下&#xff0c;系统图标由于是内置图标&#xff0c;即使桌面关闭了图标自动排列&#xff0c;在桌面右键刷新或系统重启后&#xff0c;依然会位置自动改变&#xff0c;有时候确实需要管理图标&#xff0c;这种自动变化就特别烦&#xff0c;怎么办呢&#xff1f; …

uniapp微信小程序消息订阅详解

一、微信公众平台申请订阅模板 注意&#xff1a;订阅信息 这个事件 是 当用户 点击的时候触发 或者 是 支付成功后触发&#xff0c; 用户勾选 “总是保持以上选择&#xff0c;不再询问” 之后或长期订阅&#xff0c;下次订阅调用 wx.requestSubscribeMessage 不会弹窗&#xf…

如何选择家用洗地机?四大性能出色产品,新手必看

在现代生活中&#xff0c;随着人们对健康和卫生意识的提高&#xff0c;家庭清洁变得越来越重要。然而&#xff0c;传统的清洁方式往往效率低下&#xff0c;难以满足需求。幸运的是&#xff0c;现代科技的发展为我们带来了许多智能清洁设备&#xff0c;其中洗地机就是一种非常实…

Qt 富文本处理 (字体颜色大小加粗等)

Qt中支持HTML的控件有textEdit 、label 、textBrowser 。 接口&#xff1a;setHtml("Qt"); toHtml(). 文本样式设置 : 可分字设置 &#xff0c;主要使用QTextCharFormat类进行文本样式设置。 示例&#xff1a; QTextCharFormat fmt; //粗体 fmt.setFontWeight…

数据结构:归并排序

归并排序 时间复杂度O(N*logN) 如果两个序列有序,通过归并,可以让两个序列合并后也有序,变成一个有序的新数组 对于一个数组,如果他的左右区间都有序,就可以进行归并了 归并的方法 将数组的左右两个有序区间比较,每次都取出一个最小的,然后放入临时数组(不能在原数组上修改…