【Hadoop大数据技术】——HDFS分布式文件系统(学习笔记)

📖 前言:Hadoop的核心是HDFS(Hadoop Distributed File System,Hadoop分布式文件系统)和MapReduce。其中,HDFS是解决海量大数据文件存储的问题,是目前应用最广泛的分布式文件系统。

在这里插入图片描述


目录

  • 🕒 1. HDFS简介
    • 🕘 1.1 HDFS的演变
    • 🕘 1.2 HDFS的优缺点
  • 🕒 2. HDFS的架构和原理
    • 🕘 2.1 HDFS存储架构
    • 🕘 2.2 HDFS文件读写原理
      • 🕤 2.2.1 HDFS写文件流程
      • 🕤 2.2.2 HDFS读文件流程
  • 🕒 3. HDFS的Shell操作
  • 🕒 4. 使用Eclipse开发调试HDFS Java程序
    • 🕘 4.1 安装Eclipse
    • 🕘 4.2 在Eclipse中创建项目
    • 🕘 4.3 为项目添加需要用到的JAR包
    • 🕘 4.4 编写Java应用程序
    • 🕘 4.5 编译运行程序
    • 🕘 4.6 应用程序的部署

🕒 1. HDFS简介

🕘 1.1 HDFS的演变

在这里插入图片描述

  • 传统文件系统会遇到存储瓶颈问题文件上传与下载的效率问题,对于存储,首先考虑的就是扩容,扩容有两种形式,一种是纵向扩容,即增加磁盘和内存;另一种是横向扩容,即增加服务器数量。通过扩大规模达到分布式存储,这种存储形式就是分布式文件存储的雏形。对于上传与下载问题,常规的解决办法是将一个大的文件切分成多个数据块,将数据块以并行的方式进行存储。这里以30G的文本文件为例,将其切分成3块,每块大小10G。
  • 但是文件通过数据块分别存储在服务器集群中,那么如何获取一个完整的文件呢?针对这个问题,就需要再考虑增加一台服务器,专门用来记录文件被切割后的数据块信息以及数据块的存储位置信息,即HDFS文件系统雏形
  • 如果存储数据块的服务器中突然有一台机器宕机,就无法正常的获取文件了,这个问题被称为单点故障。针对这个问题,可以采用备份的机制解决,即每个服务器中都存储两个数据块,进行备份。服务器B存储 blk-001 和 blk-002,服务器C存储 blk-002 和 blk-003,服务器D存储 blk-001 和 blk-003。当服务器C突然宕机,我们还可以通过服务器B和服务器D查询完整的数据块供客户端访问下载。这就形成了简单的HDFS。

🕘 1.2 HDFS的优缺点

优点:高容错、流式数据访问、支持超大文件、高数据吞吐量
缺点:高延迟、不适合小文件存取、不适合并发写入

🕒 2. HDFS的架构和原理

🕘 2.1 HDFS存储架构

HDFS是一个易于扩展的分布式文件系统,运行在成百上千台低成本的机器上。它与现有的分布式文件系统有许多相似之处,都是用来存储数据的系统工具,而区别于HDFS具有高度容错能力,旨在部署在低成本机器上。HDFS主要用于对海量文件信息进行存储和管理,也就是解决大数据文件(如TB乃至PB级)的存储问题。

  • HDFS采用主从架构(Master/Slave架构)。
  • HDFS集群是由一个NameNode和多个 DataNode组成
  • HDFS提供 SecondaryNameNode 辅助 NameNode。

在这里插入图片描述

  1. NameNode(名称节点)
    NameNode是HDFS集群的主服务器,通常称为名称节点或者主节点。一旦NameNode关闭,就无法访问Hadoop集群。NameNode主要以元数据的形式进行管理和存储,用于维护文件系统名称并管理客户端对文件的访问;NameNode记录对文件系统名称空间或其属性的任何更改操作;HDFS负责整个数据集群的管理,并且在配置文件中可以设置备份数量,这些信息都由NameNode存储。

  2. DataNode(数据节点)
    DataNode是HDFS集群中的从服务器,通常称为数据节点。文件系统存储文件的方式是将文件切分成多个数据块,这些数据块实际上是存储在DataNode节点中的,因此DataNode机器需要配置大量磁盘空间。它与NameNode通过心跳监测机制保持不断的通信,DataNode在客户端或者NameNode的调度下,存储并检索数据块,对数据块进行创建、删除等操作,并且定期向NameNode发送所存储的数据块列表。

心跳机制:HDFS在运行期间,将NameNode和每个DataNode之间建立一种心跳机制,NameNode在固定间隔时间内接收到DataNode发送的心跳信息,认为该DataNode处于存活状态,反之则认为该DataNode处于假死状态。在最大间隔时间内仍然没有接收到处于假死状态的DataNode发送的心跳信息,NameNode会认为该DataNode处于宕机状态。当某个DataNode处于宕机状态之后,可能会造成某些Block的副本数无法达到系统要求。

  1. SecondaryNameNode(辅助节点)
    SecondaryNameNode是HDFS集群中的辅助节点。定期从NameNode拷贝FsImage文件并合并Edits文件,将合并结果发送给NameNode。SecondaryNameNode和NameNode保存的FsImage和Edits文件相同,可以作为NameNode的冷备份,它的目的是帮助 NameNode合并编辑日志,减少NameNode启动时间。当NameNode宕机无法使用时,可以通过手动操作将SecondaryNameNode切换为NameNode。

注:SecondaryNameNode并不是NameNode的备份,它的主要作用是协助NameNode处理元数据的备份和检查点操作。它并不能解决Hadoop集群的单点故障问题。因为SecondaryNameNode的备份数据并不能时刻保持与namenode同步,在每次 checkpoint 的时候SecondaryNameNode 才会合并与同步NameNode的数据,也就是说在NameNode宕机的时候SecondaryNameNode可能会丢失一段时间的数据,这段时间取决于checkpoint的周期。我们可以减小checkpoint的周期来减少数据的丢失量,但由于每次checkpoint很耗性能,而且这种方案也不能从根本上解决数据丢失的问题。故对于单点故障问题,采用即时备份NameNode元数据的方案(NFS)更为合适。

  1. Block(数据块)
    每个磁盘都有默认的数据块大小,这是磁盘进行数据读/写的最小单位,HDFS同样也有块的概念,它是抽象的块,而非整个文件作为存储单元,在Hadoop3.x版本下,默认大小是128M,且备份3份,每个块尽可能地存储于不同的DataNode中。按块存储的好处主要是屏蔽了文件的大小,提供数据的容错性和可用性。

  2. Rack(机架)
    Rack是用来存放部署Hadoop集群服务器的机架,不同机架之间的节点通过交换机通信,HDFS通过机架感知策略,使NameNode能够确定每个DataNode所属的机架ID,使用副本存放策略,来改进数据的可靠性、可用性和网络带宽的利用率。

  3. Metadata(元数据)
    在 NameNode 内部是以元数据的形式,维护着两个文件,分别是FsImage 镜像文件和 EditLog 日志文件。其中,FsImage镜像文件用于存储整个文件系统命名空间的信息,EditLog日志文件用于持久化记录文件系统元数据发生的变化。
    当 NameNode启动的时候,FsImage 镜像文件就会被加载到内存中,然后对内存里的数据执行记录的操作,以确保内存所保留的数据处于最新的状态,这样就加快了元数据的读取和更新操作,但是这些操作非常消耗NameNode资源。于是HDFS文件系统引入了 EditLog 日志文件,该文件以追加方式记录内存中元数据的每一次变化,如果NameNode宕机,可以通过合并FsImage文件和Edits文件的方式恢复内存中存储的元数据。

注:EditLog和Edits是同一个东西。Edits是EditLog的文件名,它存储了EditLog的内容。

🕘 2.2 HDFS文件读写原理

🕤 2.2.1 HDFS写文件流程

在这里插入图片描述

以300MB大小的1.txt文件为例,介绍HDFS写文件流程

  1. 客户端发起上传1.txt文件到指定目录的请求,通过RPC(远程过程调用)与NameNode建立通讯。

  2. NameNode检查元数据文件的系统目录树,即检查客户端是否有上传文件的权限,以及文件是否存在等。若系统目录树的父目录不存在该文件相关信息,返回客户端可以上传文件。

  3. 客户端根据分块策略对文件1.txt进行切分,形成3个Block,分别是blk1、blk2和blk3。

  4. 客户端向NameNode请求上传第一个Block,即blk1,以及数据块副本的数量。

  5. NameNode根据副本机制和机架感知向客户端返回可上传blk1的DataNode列表。

  6. 客户端从NameNode接收到blk1上传的DataNode列表,并与虚拟机建立管道(Pipeline)。

  7. Hadoop3向Hadoop2汇报管道建立成功,Hadoop2与Hadoop1汇报管道建立成功;Hadoop1与客户端汇报管道建立成功,客户端与所有DataNode列表中的所有DataNode都建立了管道。

  8. 客户端开始传输blk1,传输过程是以流式写入的方式实现。
    1)将blk1写入到内存中进行缓存。
    2)将blk1按照packet(默认为64K)为单位进行划分。
    3)将第一个packet通过管道发送给Hadoop1。
    4)Hadoop1接收完第一个packet之后,客户端会将第二个packet发送给Hadoop1,同时Hadoop1通过Pipeline将第一个packet发送给Hadoop2。
    5)Hadoop2接收完第一个packet之后,Hadoop1会将第二个packet发送给Hadoop2,同时Hadoop2通过Pipeline将第一个packet发送给Hadoop3。
    6)依次类推直至blk1上传完成。

  9. Hadoop3向Hadoop2发送blk1写入完成的信息,Hadoop2向Hadoop1发送blk1写入完成的信息,最后,Hadoop1向客户端发送blk1写入完成的信息。
    注意:客户端成功上传blk1后,重复第4~9步的流程,依次上传blk2和blk3,最终完成1.txt文件的上传。

练习题:客户端上传文件的时候哪项是正确的?(多选)
A、数据经过 NameNode 传递给 DataNode
B、客户端端将文件切分为多个Block,依次上传
C、客户端只上传数据到一台 DataNode,然后由 NameNode 负责 Block 复制工作
D、客户端发起文件上传请求,通过RPC与NameNode建立通讯。
答案:BD

🕤 2.2.2 HDFS读文件流程

在这里插入图片描述

以300MB大小的1.txt文件为例,介绍HDFS读文件流程

  1. 客户端发起读取1.txt文件的请求,通过RPC与NameNode建立通讯。

  2. NameNode检查元数据文件的系统目录树,即检查客户端是否有读取文件的权限,以及文件是否存在等。

  3. 客户端按照就近原则从NameNode返回的Block列表读取Block。

  4. 客户端将读取所有的Block按照顺序进行合并,最终形成1.txt文件,需要注意的是,如果文件过大导致NameNode无法一次性文件的所有Block列表返回客户端时,会分批次将Block列表返回客户端。

🕒 3. HDFS的Shell操作

HDFS Shell类似于Linux操作系统中的Shell,都是一种命令语言,可以完成对HDFS上文件和目录的一系列操作。

在HDFS集群日常使用的过程时,主要是通过Client Commands类型的HDFS Shell子命令操作HDFS,Hadoop提供了多种Client Commands类型的HDFS Shell子命令,包括dfs、envvars、classpath等,dfs主要用于操作HDFS的文件和目录,也是最常用的HDFS Shell子命令。

  • -ls :查看指定路径的目录结构
  • -du:统计目录下所有文件大小
  • -mv:移动文件
  • -cp:复制文件
  • -rm:删除文件/空白文件夹
  • -cat:查看文件内容
  • -text:源文件输出为文本格式
  • -mkdir:创建空白文件夹
  • -put:上传文件
  • -help:删除文件/空白文件夹

在这里插入图片描述

🕒 4. 使用Eclipse开发调试HDFS Java程序

Hadoop采用Java语言开发的,提供了Java API与HDFS进行交互。上面介绍的Shell命令,在执行时实际上会被系统转换成Java API调用。

为了提高程序编写和调试效率,我们采用Eclipse工具编写Java程序。
现在要执行的任务是:假设在目录“hdfs://localhost:9000/user/hadoop”下面有几个文件,分别是file1.txt、file2.txt、file3.txt、file4.abc和file5.abc,这里需要从该目录中过滤出所有后缀名不为“.abc”的文件,对过滤之后的文件进行读取,并将这些文件的内容合并到文件“hdfs://localhost:9000/user/hadoop/merge.txt”中。

🕘 4.1 安装Eclipse

在Ubuntu中打开Firefox直接下载

🔎 Eclipse下载官网

点击 “Download Packages”
在这里插入图片描述
选择对应的操作系统下载
在这里插入图片描述
注意选择国内镜像,下载速度才快
在这里插入图片描述
在这里插入图片描述

下载完成
在这里插入图片描述

在“Downloads”文件夹中空白处右键,选择“在终端打开”,输入命令,解压eclipse到/opt目录下:

sudo tar -zxvf eclipse-committers-2023-12-R-linux-gtk-x86_64.tar.gz -C /opt

在Linux系统中设置Eclipse快捷方式

sudo vim /usr/share/applications/eclipse.desktop

向eclipse.desktop中添加以下内容:

[Desktop Entry]
Encoding=UTF-8
Name=Eclipse
Comment=Eclipse IDE
Exec=/opt/eclipse/eclipse
Icon=/opt/eclipse/icon.xpm
Terminal=false
StartupNotify=true
Type=Application
Categories=Application;Developmet;

在这里插入图片描述

给eclipse.desktop赋权

cd /usr/share/applications
sudo chmod u+x eclipse.desktop

找到/usr/share/applications/eclipse.desktop,鼠标右键选择复制,到桌面粘贴即可。
在这里插入图片描述

注:高版本Ubuntu会有权限检查,如报错需要右键图标,选择“允许运行”

之后双击快捷方式打开即可。

🕘 4.2 在Eclipse中创建项目

启动Eclipse。当Eclipse启动以后,会弹出如下图所示界面,提示设置工作空间(workspace)。

在这里插入图片描述

可以直接采用默认的设置“/home/hadoop/workspace”,点击“OK”按钮。可以看出,由于当前是采用hadoop用户登录了Linux系统,因此,默认的工作空间目录位于hadoop用户目录“/home/hadoop”下。
Eclipse启动以后,会呈现如下图所示的界面。

在这里插入图片描述
关闭welcome界面后,选择“File–>New–>Java Project”菜单,开始创建一个Java工程,会弹出如下图所示界面。

在这里插入图片描述

在“Project name”后面输入工程名称“HDFSExample”,选中“Use default location”,让这个Java工程的所有文件都保存到“/home/hadoop/workspace/HDFSExample”目录下。在“JRE”这个选项卡中,可以选择当前的Linux系统中已经安装好的JDK,比如jdk1.8.0_371。然后,点击界面底部的“Next>”按钮,进入下一步的设置。

🕘 4.3 为项目添加需要用到的JAR包

进入下一步的设置以后,会弹出如下图所示界面。

在这里插入图片描述

需要在这个界面中加载该Java工程所需要用到的JAR包,这些JAR包中包含了可以访问HDFS的Java API。这些JAR包都位于Linux系统的Hadoop安装目录下,对于本文而言,就是在“/usr/local/hadoop/share/hadoop”目录下。点击界面中的“Libraries”选项卡,然后,点击界面右侧的“Add External JARs…”按钮,会弹出如下图所示界面。

在这里插入图片描述

为了编写一个能够与HDFS交互的Java应用程序,一般需要向Java工程中添加以下JAR包:
(1)“/usr/local/hadoop/share/hadoop/common”目录下的所有JAR包,包括hadoop-common-3.3.5.jar、hadoop-common-3.3.5-tests.jar、haoop-nfs-3.3.5.jar、haoop-kms-3.3.5.jar和hadoop-registry-3.3.5.jar,注意,不包括目录jdiff、lib、sources和webapps;
(2)“/usr/local/hadoop/share/hadoop/common/lib”目录下的所有JAR包;
(3)“/usr/local/hadoop/share/hadoop/hdfs”目录下的所有JAR包,注意,不包括目录jdiff、lib、sources和webapps;
(4)“/usr/local/hadoop/share/hadoop/hdfs/lib”目录下的所有JAR包。

在这里插入图片描述

全部添加完毕以后,就可以点击界面右下角的“Finish”按钮,完成Java工程HDFSExample的创建。

🕘 4.4 编写Java应用程序

下面编写一个Java应用程序。
请在Eclipse工作界面左侧的“Package Explorer”面板中(如下图所示),找到刚才创建好的工程名称“HDFSExample”,然后在该工程名称上点击鼠标右键,在弹出的菜单中选择“New–>Class”菜单。

在这里插入图片描述
选择“New–>Class”菜单以后会出现如下图所示界面。
在这里插入图片描述

在该界面中,只需要在“Name”后面输入新建的Java类文件的名称,这里采用名称“MergeFile”,其他都可以采用默认设置,然后,点击界面右下角“Finish”按钮,Eclipse就自动创建了一个名为“MergeFile.java”的源代码文件,请在该文件中输入以下代码:

import java.io.IOException;
import java.io.PrintStream;
import java.net.URI;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;

/**
 * 过滤掉文件名满足特定条件的文件 
 */
class MyPathFilter implements PathFilter {
     String reg = null; 
     MyPathFilter(String reg) {
          this.reg = reg;
     }
     public boolean accept(Path path) {
        if (!(path.toString().matches(reg)))
            return true;
        return false;
    }
}
/***
 * 利用FSDataOutputStream和FSDataInputStream合并HDFS中的文件
 */
public class MergeFile {
    Path inputPath = null; //待合并的文件所在的目录的路径
    Path outputPath = null; //输出文件的路径
    public MergeFile(String input, String output) {
        this.inputPath = new Path(input);
        this.outputPath = new Path(output);
    }
    public void doMerge() throws IOException {
        Configuration conf = new Configuration();
        conf.set("fs.defaultFS","hdfs://localhost:9000");
          conf.set("fs.hdfs.impl","org.apache.hadoop.hdfs.DistributedFileSystem");
        FileSystem fsSource = FileSystem.get(URI.create(inputPath.toString()), conf);
        FileSystem fsDst = FileSystem.get(URI.create(outputPath.toString()), conf);
                //下面过滤掉输入目录中后缀为.abc的文件
        FileStatus[] sourceStatus = fsSource.listStatus(inputPath,
                new MyPathFilter(".*\\.abc")); 
        FSDataOutputStream fsdos = fsDst.create(outputPath);
        PrintStream ps = new PrintStream(System.out);
        //下面分别读取过滤之后的每个文件的内容,并输出到同一个文件中
        for (FileStatus sta : sourceStatus) {
            //下面打印后缀不为.abc的文件的路径、文件大小
            System.out.print("路径:" + sta.getPath() + "    文件大小:" + sta.getLen()
                    + "   权限:" + sta.getPermission() + "   内容:");
            FSDataInputStream fsdis = fsSource.open(sta.getPath());
            byte[] data = new byte[1024];
            int read = -1;

            while ((read = fsdis.read(data)) > 0) {
                ps.write(data, 0, read);
                fsdos.write(data, 0, read);
            }
            fsdis.close();          
        }
        ps.close();
        fsdos.close();
    }
    public static void main(String[] args) throws IOException {
        MergeFile merge = new MergeFile(
                "hdfs://localhost:9000/user/hadoop/",
                "hdfs://localhost:9000/user/hadoop/merge.txt");
        merge.doMerge();
    }
}

🕘 4.5 编译运行程序

在开始编译运行程序之前,请一定确保Hadoop已经启动运行,如果还没有启动,需要打开一个Linux终端,输入以下命令启动Hadoop,并检查是否都正常启动:

cd /usr/local/hadoop
./sbin/start-dfs.sh

在这里插入图片描述

然后,要确保HDFS的“/user/hadoop”目录下已经存在file1.txt、file2.txt、file3.txt、file4.abc和file5.abc,每个文件里面有内容。这里,假设文件内容如下:
file1.txt的内容是:this is file1.txt
file2.txt的内容是:this is file2.txt
file3.txt的内容是:this is file3.txt
file4.abc的内容是:this is file4.abc
file5.abc的内容是:this is file5.abc

我们可以在Windows端创建好文件,之后通过Win端的浏览器上传
浏览器输入: http://[虚拟机IP]:9870/

在这里插入图片描述

在这里插入图片描述
先创建好目录,再上传文件

注:如果遇到如下报错,需要修改权限
在这里插入图片描述
在终端输入:./bin/hdfs dfs -chmod -R 777 /

在这里插入图片描述

现在就可以编译运行上面编写的代码。可以直接点击Eclipse工作界面上部的运行程序的快捷按钮,当把鼠标移动到该按钮上时,在弹出的菜单中选择“Run As”,继续在弹出来的菜单中选择“Java Application”,如下图所示。

在这里插入图片描述

然后,会弹出如下图所示界面。

在这里插入图片描述
在该界面中,点击界面右下角的“OK”按钮,开始运行程序。程序运行结束后,会在底部的“Console”面板中显示运行结果信息(如下图所示)。同时,“Console”面板中还会显示一些类似“log4j:WARN…”的警告信息,可以不用理会。

在这里插入图片描述

如果程序运行成功,这时,可以到HDFS中查看生成的merge.txt文件

在终端查看:
在这里插入图片描述
在Web查看:
在这里插入图片描述

🕘 4.6 应用程序的部署

下面介绍如何把Java应用程序生成JAR包,部署到Hadoop平台上运行。首先,在Hadoop安装目录下新建一个名称为myapp的目录,用来存放我们自己编写的Hadoop应用程序,可以在Linux的终端中执行如下命令:

cd /usr/local/hadoop
mkdir myapp

然后,在Eclipse工作界面左侧的“Package Explorer”面板中,在工程名称“HDFSExample”上点击鼠标右键,在弹出的菜单中选择“Export”,如下图所示。

在这里插入图片描述

在弹出的界面中,选择“Runnable JAR file”,然后,点击“Next>”按钮,弹出如下图所示界面。
在这里插入图片描述
在这里插入图片描述

在该界面中,“Launch configuration”用于设置生成的JAR包被部署启动时运行的主类,需要在下拉列表中选择刚才配置的类“MergeFile-HDFSExample”。在“Export destination”中需要设置JAR包要输出保存到哪个目录,比如,这里设置为“/usr/local/hadoop/myapp/HDFSExample.jar”。在“Library handling”下面选择“Extract required libraries into generated JAR”。然后,点击“Finish”按钮,之后会出现一些警告信息,点击OK无视即可。

在这里插入图片描述

至此,已经顺利把HDFSExample工程打包生成了HDFSExample.jar。可以到Linux系统中查看一下生成的HDFSExample.jar文件,可以在Linux的终端中执行如下命令:

在这里插入图片描述
可以看到,“/usr/local/hadoop/myapp”目录下已经存在一个HDFSExample.jar文件。
由于之前已经运行过一次程序,已经生成了merge.txt,因此,需要首先执行如下命令删除该文件:

cd /usr/local/hadoop
./bin/hdfs dfs -rm /user/hadoop/merge.txt

现在,就可以在Linux系统中,使用hadoop jar命令运行程序,并到HDFS中查看生成的merge.txt文件:

cd /usr/local/hadoop
./bin/hadoop jar ./myapp/HDFSExample.jar
./bin/hdfs dfs -cat /user/hadoop/merge.txt

在这里插入图片描述

注:如果遇到如下图报错
在这里插入图片描述
说明是由较高版本的JDK编译的java class文件试图在较低版本的JVM上运行产生的错误,可以通过下述方法进行解决:
1、检查jvm(java命令)和jdk(javac命令)版本是否一致。如果是linux版本,则在命令行中分别输入java -version和javac -version命令来查看版本是否一致。
2、如果都一致,但还是解决不了问题,那么肯定不是直接在命令行中用javac来编译的,而是用类似于eclipse、netbeans这样的编译器来编译的。因为很多编译器都自带javac,而不是采用操作系统中的编译器。
3、如果你的编译器是eclipse的话,那么需要在项目的属性里设置jdk版本,方法是右击项目–>properties–>java compiler --> Enable project specific settings -->将compiler compliance level设置为1.8,即可解决问题。
在这里插入图片描述在这里插入图片描述


OK,以上就是本期知识点“HDFS分布式文件系统”的知识啦~~ ,感谢友友们的阅读。后续还会继续更新,欢迎持续关注哟📌~
💫如果有错误❌,欢迎批评指正呀👀~让我们一起相互进步🚀
🎉如果觉得收获满满,可以点点赞👍支持一下哟~

❗ 转载请注明出处
作者:HinsCoder
博客链接:🔎 作者博客主页

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

智慧公厕_智慧化公厕_智慧的公厕_公厕智慧化_智能智慧公厕_智慧化的公厕

在当代城市发展中,智慧公厕作为公共厕所信息化的主要表现形式,正在以惊人的速度推动着城市公共环境卫生的智慧化进程。作为智慧城市体系的重要组成部分,智慧公厕不仅提供方便、卫生的公共厕所服务,还提升了城市整体形象&#xff0…

H5带建站时长可自定义背景官网/引导页源码

源码名称:带建站时长可自定义背景官网/引导页源码 源码介绍:一款带动态时间显示建站时长的引导页源码,可用于引导页、工作室官网、个人主页等。源码为H5自适应手机端、电脑端。 需求环境:H5 下载地址: https://www.…

java学习(集合)

一.集合(主要是单列集合和双列集合) 1.集合的框架体系(两大类) 2.collection接口是实现类的特点: 1)collection实现子类可以存放多个元素,每个元素可以是Object 2)有效Collection的实现类,可以存放重复的元素&#…

Vue.js+SpringBoot开发海南旅游景点推荐系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户端2.2 管理员端 三、系统展示四、核心代码4.1 随机景点推荐4.2 景点评价4.3 协同推荐算法4.4 网站登录4.5 查询景点美食 五、免责说明 一、摘要 1.1 项目介绍 基于VueSpringBootMySQL的海南旅游推荐系统&#xff…

MVCC------Mysql并发事务控制的工具

这里写目录标题 一.MVCC是什么二.原理1.隐藏的默认字段2.Undo log3.Undo log版本链4. ReadView 三.回答 一.MVCC是什么 MVCC 是 Multi-Version Concurrency Control(多版本并发控制)的缩写,是数据库系统中常用的一种并发控制方法。在MVCC 中…

高效管理百万级数据:MySQL备份与恢复实战指南

简介 在当今数字化时代,数据是企业不可或缺的核心资产之一,而MySQL作为一种流行的关系型数据库管理系统,其百万级数据的高效管理显得尤为重要。本实战指南将深入探讨MySQL备份与恢复的关键策略,为您提供全面而实用的解决方案。通…

SpringBoot中RestTemplate 发送http请求

SpringBoot中RestTemplate 发送http请求 引入fastjson <!--fastjson--> <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.47</version> </dependency>创建配置文件 新建c…

链表中的经典问题——反转链表

经典问题 对于链表的结构还不太清晰的同学&#xff0c;可以看我的另一篇文章&#xff0c;实践总结&#xff1a;一篇搞懂链表——单链表和双指针技巧 反转链表 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 方法一&#xff0c;迭代法…

牛客周赛 Round 36

赛况 C题可惜&#xff0c;比赛时模拟没有想明白&#xff0c;只对了一半&#xff0c;赛后看了大佬们的题解后恍然大悟&#xff0c;而F题是压根没思路&#xff0c;况且F题部分分也比较难拿。 题目列表 A-小红的数位删除 思路 将读入的数字整除10做三次后输出即可 参考代码 #inc…

【数据结构】详解时间复杂度和空间复杂度的计算

一、时间复杂度&#xff08;执行的次数&#xff09; 1.1时间复杂度的概念 1.2时间复杂度的表示方法 1.3算法复杂度的几种情况 1.4简单时间复杂度的计算 例一 例二 例三 1.5复杂时间复杂度的计算 例一&#xff1a;未优化冒泡排序时间复杂度 例二&#xff1a;经过优化…

蓝桥杯备战刷题-滑动窗口

今天给大家带来的是滑动窗口的类型题&#xff0c;都是十分经典的。 1&#xff0c;无重复字符的最长子串 看例三&#xff0c;我们顺便来说一下子串和子序列的含义 子串是从字符串里面抽出来的一部分&#xff0c;不可以有间隔&#xff0c;顺序也不能打乱。 子序列也是从字符串里…

5分钟教你使用pyarmnn推理引擎识别一只可爱猫咪~

视频 5分钟教你使用pyarmnn推理引擎识别一只可爱猫咪&#xff5e; 添加仓库 sudo apt install software-properties-common sudo add-apt-repository ppa:armnn/ppa sudo apt update 安装pyarmnn sudo apt-get install -y python3-pyarmnn armnn-latest-all python3-pip安装…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Checkbox)

提供多选框组件&#xff0c;通常用于某选项的打开或关闭。 说明&#xff1a; API version 11开始&#xff0c;Checkbox默认样式由圆角方形变为圆形。 该组件从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 无 接口…

Python(38):Request的data需入参是json,用转换json.dumps(data)

Python接口自动化测试遇到问题:误传str类型给request 一&#xff1a;request接口请求数据用str传参报错&#xff0c;请求响应报错 排查原因&#xff1a;查看服务器报错是Json解析报错。 1.1、如果直接入参&#xff0c;进行request请求的数据&#xff1a; data请求值为&…

C语言---单身狗问题

1.单身狗初阶 这个题目就是数组里面有一串数字&#xff0c;都是成对存在的&#xff0c;只有一个数字只出现了一次&#xff0c;请你找出来 &#xff08;1&#xff09;异或是满足交换律的&#xff0c;两个相同的数字异或之后是0&#xff1b; &#xff08;2&#xff09;让0和每个…

【LeetCode每日一题】299. 猜数字游戏

文章目录 [299. 猜数字游戏](https://leetcode.cn/problems/bulls-and-cows/)思路&#xff1a;代码&#xff1a; 299. 猜数字游戏 思路&#xff1a; 遍历两个字符串 secret 和 guess&#xff0c;若字符既在相同位置上又相等&#xff0c;则位置和数字都正确&#xff0c;对应的 …

如何对于单元格数据进行清洗处理

如何对于单元格数据进行清洗处理 陪伴意味着有人愿意把最美好的东西给你&#xff0c; 那就是时间。 当然陪伴也是一个很平常的事情&#xff0c; 日复一日&#xff0c;年复一年。 到最后陪伴就成了一种习惯。 约定好的相逢&#xff0c;伴你天荒地老&#xff01; 陪伴是最长情的告…

多线程多进程处理服务器并发(多进程处理如何解决僵死进程)

目录 1.可循环发送数据的代码 2.改成循环之后每次发现只能处理一个客户端 3.服务器端处理并发问题 3.1 思路 3.2 利用多线程实现并发 ​编辑 3.3 利用多进程实现并发 3.3.1 多进程并发产生的僵死进程问题 ​3.3.2 解决僵死进程问题 1.可循环发送数据的代码 服务器代…

AI代码加速器即将发布!傅盛:程序员会写某种代码就能找到工作的时代一去不复返了

在产品介绍视频的最后&#xff0c;代码加速器运行了Prompt生成的代码&#xff0c;是一个为傅盛庆生的祝福“彩蛋”。不得不说&#xff0c;猎户星空的程序员就做到了傅盛说的不止写代码&#xff0c;真是有点浪漫小心机在身上的。 3月6日&#xff0c;猎豹移动董事长兼CEO、猎户星…

木球竞赛抽签计分系统(C# Winform)

前几天做了个小系统&#xff0c;木球竞赛抽签计分系统。种子的设置&#xff0c;和轮空的设置&#xff0c;都是按照运动抽签的规则。目前仅支持8位&#xff0c;16位, 32位&#xff0c;64位报表的生成。 功能模块&#xff1a; 1、比赛管理&#xff1a;名称、承办、时间、地点 2…