实训笔记7.18

news2024/10/5 16:22:06

实训笔记7.18

  • 7.18
    • 一、座右铭
    • 二、Hadoop大数据技术 大数据软件一般都要求7*24小时不宕机
    • 三、Hadoop的组成
      • 3.1 HDFS
      • 3.2 MapReduce
      • 3.3 YARN
      • 3.4 Hadoop Common
    • 四、Hadoop生态圈
    • 五、Hadoop的安装问题
      • 5.1 Hadoop的本地安装模式-基本不用
      • 5.2 Hadoop的伪分布安装模式
      • 5.3 Hadoop的完全分布式安装模式
      • 5.4 Hadoop的HA高可用安装模式--借助zookeeper
    • 六、Hadoop的第一个核心组成:HDFS
      • 6.1 概念
      • 6.2 组成
        • 6.2.1 NameNode
        • 6.2.2 DataNode
        • 6.2.3 SecondaryNameNode
        • 6.2.4 客户端:命令行/Java API
      • 6.3 HDFS的基本操作
      • 6.4 HDFS的原理性内容
        • 6.4.1 HDFS的数据流工作原理
        • 6.4.2 NameNode的第一个工作机制原理
        • 6.4.3 NameNode的第二个工作机制原理
      • 6.5 HDFS、YARN的新节点的服役和旧节点的退役
        • 6.5.1 新节点服役操作
        • 6.5.2 旧节点的退役操作(如果第一次增加退役文件,必须重启HDFS集群)
    • 七、Hadoop的第二个核心组成:MapReduce框架概述
      • 7.1 基本概念
      • 7.2 MapReduce的分布式计算核心思想
      • 7.3 MapReduce程序在运行过程中三个核心进程
      • 7.4 如何编写MapReduce计算程序:(编程步骤)
      • 7.5 MapReduce底层是由Java开发的,因此MR程序我们要编写的话支持使用Java代码来进行编写
    • 八、MapReduce的案例实现--大数据分布式计算的经典案例WordCount(单词计数)
      • 8.1 案例需求
      • 8.2 案例分析(基于MapReduce)
      • 8.3 代码开发

7.18

一、座右铭

我的故事你说,我的文字我落,我值几两你定,我去何方我挑。

二、Hadoop大数据技术 大数据软件一般都要求7*24小时不宕机

三、Hadoop的组成

3.1 HDFS

HDFS:解决海量数据的分布式存储的问题

3.2 MapReduce

MapReduce:解决海量数据的分布式计算的问题

3.3 YARN

YARN:解决分布式计算程序的资源分配以及任务监控问题 Mesos: 分布式资源管理系统(YARN的替代品)

3.4 Hadoop Common

四、Hadoop生态圈

flume、sqoop、hive、spark。。。。

五、Hadoop的安装问题

5.1 Hadoop的本地安装模式-基本不用

5.2 Hadoop的伪分布安装模式

5.3 Hadoop的完全分布式安装模式

5.4 Hadoop的HA高可用安装模式–借助zookeeper

5.2~5.4:需要进行配置文件的修改九个配置文件

六、Hadoop的第一个核心组成:HDFS

6.1 概念

分布式文件存储系统,所谓的分布式采用一些架构和一些组件将多台节点的存储资源当作一个整体进行海量资源的存储

6.2 组成

6.2.1 NameNode

  1. 存储元数据:整个集群中存储的目录和文件的索引
  2. 管理整个HDFS集群
  3. 接受客户端的请求
  4. 负责节点的故障转移

6.2.2 DataNode

  1. 存储数据(存储数据是以block块的形式进行数据的存放)
  2. 定时负责汇总整个节点上存储的block块的信息,然后给NN汇报
  3. 负责和客户端连接进行文件的读写操作

6.2.3 SecondaryNameNode

辅助namenode完成edits编辑日志和fsimage镜像文件的合并操作

6.2.4 客户端:命令行/Java API

  1. 负责和HDFS集群进行通信实现文件的增删改查

  2. 负责进行block块的分割

6.3 HDFS的基本操作

  1. HDFS的命令行操作 hdfs dfs | hadoop fs

  2. HDFS的Java API操作 Configuration FileSystem

    1. windows安装Hadoop的假环境
    2. 引入Hadoop的编程依赖 hadoop-client hadoop-hdfs

6.4 HDFS的原理性内容

6.4.1 HDFS的数据流工作原理

  1. HDFS上传数据的流程

数据上传的时候,会根据配置进行block块的备份,备份的时候,选择哪些节点进行数据备份? 机架感知原则进行备份

  1. HDFS下载数据的流程

客户端在和DN建立连接的时候,是和距离它最近的某一个DN建立连接怎么判断DN距离客户端的距离:网络拓扑原则客户端和HDFS的节点在同一个集群上

6.4.2 NameNode的第一个工作机制原理

NameNode的第二个工作机制原理:元数据管理的原理 (NN和SNN的联合工作机制)

  1. 元数据:指的是HDFS存储文件/文件夹的类似的目录结构,目录中记录着每一个文件的大小、时间、每一个文件的block块的份数,block块存储的节点列表信息… NameNode默认的元数据内存是1000M,可以存储管理百万个block块的元数据信息

  2. edits编辑日志文件:记录客户端对HDFS集群的写入和修改操作

  3. fsimage镜像文件:理解为HDFS元数据的持久点检查文件

2~3:再次启动HDFS之后恢复元数据的机制

  1. HDFS的安全模式(safemode)

    1. HDFS启动之后会先进入安全模式,安全模式就是将edits和fsimage文件加载到nn内存的这一段时间,dn向NN注册的这一段时间
    2. 安全模式下无法操作HDFS集群的,安全模式会自动退出,NN的内存加载好了(元数据加载好了),同时HDFS集群还满足节点数的启动
  2. SNN的作用就是对NN进行checkpoint操作

    1. checkpoint什么时候触发
      1. 检查点时间到了—1小时 dfs.namenode.checkpoint.period 3600s
      2. HDFS距离上一次检查点操作数到达100万次 dfs.namenode.checkpoint.txns 1000000
    2. SNN每隔1分钟会询问一次NN是否要进行checkponit操作 dfs.namenode.checkpoint.check.period 60s
  3. NameNode的出现故障之后,元数据的恢复方式

    1. 因为元数据的核心是edits和fsimage文件,同时snn工作的时候会把nn的文件复制到snn当中,因此如果NN的元数据丢失,我们可以从SNN中把这些文件再复制到NN的目录下 进行元数据的恢复(恢复可能会导致一部分的元数据丢失)

      SNN的目录:${hadoop.tmp.dir}/dfs/namesecondary/curren

      nn的目录:${hadoop.tmp.dir}/dfs/name/current

    2. 元数据还有一种恢复方式:配置HDFS的namenode的多目录保存(HDFS的编辑日志和镜像文件在多个目录下保存相同的备份) 方式只能使用在同一个节点上 问题:如果整个节点宕机,无法恢复了 dfs.namenode.name.dir 多个路径 最好把HDFS重新格式化一下,或者手动把目录创建一份

    3. HA高可用模式

6.4.3 NameNode的第二个工作机制原理

NameNode的第二个工作机制原理:NameNode管理整个HDFS集群的原理 (NN和DN的联合工作机制)

  1. DataNode上存储的block块除了数据本身以外,还包含数据的长度、数据校验和、时间戳…

  2. 数据校验和是为了保证block块的完整性和一致性的,校验和机制,创建block块的时候会根据数据本身计算一个校验和,以后每一次DN进行block汇总的时候会再进行一次校验和的计算,如果两次校验和不一致 认为block块损坏了。

  3. DataNode和NameNode心跳,默认三秒心跳一次,默认值可以调整 dfs.heartbeat.interval 3s 关闭HDFS,但是不需要重新格式化 心跳的作用有两个:1、检测DN是否或者 2、把NN让DN做的事情告诉DN

  4. NN如何知道DN掉线-死亡-宕机了(掉线的时限):NN如果在某一次心跳中没有收到DN的心跳,NN不会认为DN死亡了,而是会继续心跳,如果超过掉线的时限的时间还没有心跳成功,NN才会认为DN死亡了,然后启动备份恢复机制 掉线时限的时长是有一个计算公式: timeout = 2 * dfs.namenode.heartbeat.recheck-interval + 10 * dfs.heartbeat.interval

    dfs.namenode.heartbeat.recheck-interval 心跳检测时间 5分钟 dfs.heartbeat.interval 心跳时间 3s

    默认情况下,如果超过10分30S没有收到DN的心跳 认为DN死亡了

  5. DataNode每隔一段时间(默认6小时)会向NameNode汇报一次节点上所有的block块的信息 dfs.blockreport.intervalMsec 21600000ms 每隔6小时向NN汇报一次DN的block块的信息 dfs.datanode.directoryscan.interval 21600s 每隔6小时DN自己扫描一下DN上的block块信息

6.5 HDFS、YARN的新节点的服役和旧节点的退役

概念:HDFS是一个分布式文件存储系统,HDFS身为一个大数据软件,基本上都是7*24小时不停机的,那如果HDFS集群的容量不够用了,那么我们需要增加一个新的数据节点,因为HDFS不能停止,因此我们需要在HDFS集群运行过程中动态的增加一个数据节点(新节点的服役操作);旧节点的退役。

6.5.1 新节点服役操作

服役新节点之前,需要创建一台新的虚拟节点,并且配置Java、Hadoop环境、SSH免密登录、ip、主机映射、主机名

  1. 在Hadoop的配置文件目录创建一个dfs.hosts文件,文件中声明Hadoop集群的从节点的主机名
  2. 在Hadoop的hdfs-site.xml文件中,增加一个配置项 dfs.hosts 值:文件的路径
  3. 在HDFS开启的状态下刷新从节点的信息 hdfs dfsadmin -refreshNodes yarn rmadmin -refreshNodes
  4. 只需要在新节点启动datanode和nodemanager即可成功实现节点的服役

6.5.2 旧节点的退役操作(如果第一次增加退役文件,必须重启HDFS集群)

  1. 在Hadoop的配置目录创建一个文件dfs.hosts.exclude,文件中编写退役的主机名

  2. 在Hadoop的hdfs-site.xml配置文件中声明退役的节点文件 dfs.hosts.exclude 值 文件的路径

  3. 同时需要在服役节点文件中把退役节点删除了dfs.hosts

  4. 刷新节点信息状态 hdfs dfsadmin -refreshNodes yarn rmadmin -refreshNodes

    **【注意】**退役的时候,会先把退役节点的block块复制到没有退役的节点上,然后才会下线,而且退役的时候,必须保证退役之后剩余集群的节点数大于等于副本数

6.5.1~6.5.2在namenode所在节点的hadoop中配置

七、Hadoop的第二个核心组成:MapReduce框架概述

7.1 基本概念

  1. Hadoop解决了大数据面临的两个核心问题:海量数据的存储问题、海量数据的计算问题
  2. 其中MapReduce就是专门设计用来解决海量数据计算问题的,同时MapReduce和HDFS不一样的地方在于,虽然两者均为分布式组件,但是HDFS是一个完善的软件,我们只需要使用即可,不需要去进行任何的逻辑的编辑。而MapReduce进行数据计算,计算什么样的数据,使用什么样的逻辑,MR程序都不清楚,因此MR只是一个分布式的计算【框架】,所谓的框架就是MR程序把分布式计算的思想和逻辑全部封装好了,我们只需要安装框架的思维编写计算代码(就是我们自己处理数据的逻辑代码),编写完成之后,我们的程序必然是分布式的程序。
  3. 使用分布式计算框架的好处就在于我们开发人员只需要把关注点和重点放在业务的逻辑开发,而非分布式计算程序逻辑的逻辑。

7.2 MapReduce的分布式计算核心思想

  1. MR框架实现分布式计算的逻辑是将MR程序分成了两部分:Map阶段、Reduce阶段
  2. 其中运行一个计算程序先执行Map阶段,map阶段又可以同时运行多个计算程序(MapTask)去计算map阶段的逻辑,Map阶段主要负责分数据,而且map阶段的多个MapTask并行运行互不干扰。
  3. 第二阶段Reduce阶段,Reduce阶段也可以同时运行多个计算程序(ReduceTask),Reduce阶段的任务主要负责合数据,同时多个ReduceTask同时运行互不干扰的。
  4. 任何一个MR程序,只能有一个Map阶段,一个Reduce阶段

7.3 MapReduce程序在运行过程中三个核心进程

  1. MRAppMaster一个:负责整合分布式程序的监控
  2. MapTask(多个):Map阶段的核心进程,每一个MapTask处理数据源的一部分数据
  3. ReduceTask(多个):Reduce阶段的核心进程,每一个ReduceTask负责处理Map阶段输出的一部分数据

7.4 如何编写MapReduce计算程序:(编程步骤)

  1. 编写MapTask的计算逻辑
    1. 编写一个Java类继承Mapper类,继承Mapper类之后必须指定四个泛型,四个泛型分别代表了MapTask阶段的输入的数据和输出的数据类型 MR程序要求输入的数据和输出的数据类型必须都得是key-value键值对类型的数据
    2. 重写继承的Mapper类当中的map方法,map方法处理数据的时候是文件中的一行数据调用一次map方法,map方法的计算逻辑就是MapTask的核心计算逻辑
    3. 同时map方法中数据计算完成,需要把数据以指定的key-value格式类型输出。
  2. 编写ReduceTask的计算逻辑
    1. 编写一个Java类继承Reducer类,继承Reducer类之后必须指定四个泛型,四个泛型分别代表了Reduce阶段的输入和输出的KV数据类型 Reduce的输入的KV类型就是Map阶段的输出的KV类型 Reduce的输出类型自定义的
    2. 重写Reducer类当中提供的reduce方法,reduce方法处理数据的时候一组相同的key调用一次reduce方法,reduce方法的计算逻辑就是ReduceTask的核心计算逻辑
    3. 调用reduce方法,reduce逻辑处理完成,需要把数据以指定的key-value格式类型输出
  3. 编写Driver驱动程序
    1. Driver驱动程序是用来组装MR程序,组装MR程序的处理的文件路径、MR程序的Map阶段的计算逻辑、MR程序的Reduce阶段的计算逻辑、MR程序运行完成之后的结果的输出路径
    2. Driver驱动程序本质上就是一个main函数

7.5 MapReduce底层是由Java开发的,因此MR程序我们要编写的话支持使用Java代码来进行编写

八、MapReduce的案例实现–大数据分布式计算的经典案例WordCount(单词计数)

8.1 案例需求

现在有一个文件,文件很大,文件中存储的每一行数据都是由空格分割的多个单词组成的,现在需要通过大数据分布式计算技术去统计文件中每一个单词出现的总次数

8.2 案例分析(基于MapReduce)

8.3 代码开发

  1. 创建一个maven管理的Java项目
  2. 引入MR的编程依赖
    1. hadoop-client
    2. ``hadoop-hdfs`
  3. 编写Mapper阶段的计算逻辑
  4. 编写Reducer阶段的计算逻辑
  5. 编写Driver驱动程序
  6. 代码示例:
package com.sxuek.wc;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import java.io.IOException;

/**
 * Driver驱动程序说白了就是封装MR程序的
 * Driver驱动程序其实就是一个main函数
 */
public class WCDriver {
    public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
        //1、准备一个配置文件对象Configuration
        Configuration configuration = new Configuration();
        //指定HDFS的地址
        configuration.set("fs.defaultFS","hdfs://192.168.68.101:9000");
        //2、创建封装MR程序使用一个Job对象
        Job job = Job.getInstance(configuration);
        //3、封装处理的文件路径hdfs://single:9000/wc.txt
        FileInputFormat.setInputPaths(job,new Path("/wc.txt"));
        //4、封装MR程序的Mapper阶段 还要封装Mapper阶段输出的key-value类型
        job.setMapperClass(WCMapper.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(LongWritable.class);

        //5、封装MR程序的reduce阶段 还需要封装reduce的输出kv类型
        job.setReducerClass(WCReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setMapOutputValueClass(LongWritable.class);
        job.setNumReduceTasks(1);//指定reduce阶段只有一个ReduceTask

        //6、封装MR程序的输出路径---输出路径一定不能存在 如果存在会报错
        FileOutputFormat.setOutputPath(job,new Path("/wcoutput"));

        //7、提交运行MR程序
        boolean flag = job.waitForCompletion(true);
        System.exit(flag?0:1);

    }
}

package com.sxuek.wc;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

import java.io.IOException;

/**
 * 单词技术的MapTask的计算逻辑
 * 1、继承Mapper类,同时需要指定四个泛型 两两一组 分别代表输入的key value  和输出的key value的数据类型
 *     默认情况下,map阶段读取文件数据是以每一行的偏移量为key 整数类型 每一行的数据为value读取的 字符串类型
 *     LongWritable  Text
 *     map阶段输出以单词为key 字符串 以1为value输出 整数
 *     数据类型不能使用Java中数据类型,数据类型必须是Hadoop的一种序列化类型
 *     Int---hadoop.io.IntWritable
 *     Long-hadoop.io.LongWritable
 *     String--hadoop.io.Text
 * 2、重写map方法
 *
 *
 */
public class WCMapper extends Mapper<LongWritable, Text,Text,LongWritable> {
    /**
     * map方法是MapTask的核心计算逻辑方法
     * map方法是切片中一行数据调用一次
     * @param key   这一行数据的偏移量
     * @param value  这一行数据
     * @param context 上下文对象 用于输出map阶段处理完成的keyvalue数据
     * @throws IOException
     * @throws InterruptedException
     */
    @Override
    protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, LongWritable>.Context context) throws IOException, InterruptedException {
        //拿到一行数据 并且将一行数据转成字符串类型
        String line = value.toString();
        //字符串以空格切割得到一个数组,数组中存放的就是一行的多个单词
        String[] words = line.split(" ");
        //遍历数组 得到每一个单词 以单词为key  以1为value输出数据即可
        for (String word : words) {
            context.write(new Text(word),new LongWritable(1L));
        }
    }
}

package com.sxuek.wc;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

import java.io.IOException;

/**
 * Reducer的编程逻辑:
 * 1、继承Reducer类,指定输入和输出的kv类型
 *     输入KV就是Map阶段的输出KV  Text  LongWritable
 *     输出kv Text  LongWritable
 * 2、重写reduce方法
 */
public class WCReducer extends Reducer<Text, LongWritable,Text,LongWritable> {
    /**
     * Reduce方法是Reduce阶段的核心计算逻辑
     * reduce方法是一组相同的key执行一次
     * @param key  一组相同的key  某一个单词
     * @param values  是一个集合,集合存放的就是这一个单词的所有的value值
     * @param context  上下文对象 用于reduce阶段输出数据
     * @throws IOException
     * @throws InterruptedException
     */
    @Override
    protected void reduce(Text key, Iterable<LongWritable> values, Reducer<Text, LongWritable, Text, LongWritable>.Context context) throws IOException, InterruptedException {
        //只需要将某一个单词聚合起来的value数据累加起来 得到总次数
        long sum = 0L;
        for (LongWritable value : values) {
            sum += value.get();
        }
        //只需要以单词为key  以sum为value输出即可
        context.write(key,new LongWritable(sum));
    }
}

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

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

相关文章

webpack插件compression-webpack-plugin

Vue配置compression-webpack-plugin实现Gzip压缩 1、为什么要压缩&#xff1f; 打包的时候开启gzip可以很大程度减少包的大小&#xff0c;页面大小可以变为原来的30%甚至更小&#xff0c;非常适合于上线部署。更小的体积对于用户体验来说就意味着更快的加载速度以及更好的用户…

SOPC之NiosⅡ系统(五)

NIOS Ⅱ系统实例 目录 2.创建BSP工程 2.1 创建BSP工程 2.2 BSP Editor 2.3 创建C代码文件 3.Nios Ⅱ实例 3.1 Hello NIOS Ⅱ 3.2 System ID与Timestamp 3.3 蜂鸣器定时鸣叫 3.4 拨码开关输入GIO控制 4.FPGA器件的代码固化 4.1 嵌入式软件HEX文件生成 4.2 程序存储…

RocketMQ环境搭建

环境搭建 环境准备 下载地址: https://downloads.apache.org/rocketmq/4.9.5/安装 上传至服务器 mkdir /usr/soft #上传至此目录/usr/softmkdir /usr/soft 解压 cd /usr/soft unzip rocketmq-all-4.9.5-bin-release.zip移动 mkdir /usr/local/rocketmq cd /usr/soft mv r…

Mysql 修改group_concat_max_len的默认值

1.前言 最近在进行递归查询组织及其下属组织时&#xff0c;发现数据查询不全&#xff0c;子组织数据查询不出来的问题。经排查发现是group_concat_max_len的长度不足引起的&#xff0c;默认情况下group_concat_max_len1024&#xff0c;所以我们需要修改这个默认参数。 2.SQL语…

.net core控制台应用程序在linux运行

1&#xff09;创建.net 6.0控制台应用程序 2&#xff09;在应用根目录执行cmd命令发布应用&#xff1a;dotnet publish -o .\deploy 3&#xff09;将发布文件上传到服务器 4&#xff09;运行控制台应用程序&#xff08;dotnet /home/app/ConsoleApp/ConsoleApp5.dll&#xff09…

卡尔曼与扩展卡尔曼的区别与推导

1.卡尔曼的推导&#xff1a; 1&#xff09;先看系统随机系统状态空间模型&#xff1a;&#xff08;线性&#xff09; 所谓线性是指递推或者状态转移方程是线性的 至于参数解释自己去看书&#xff0c;本文旨在捋顺推导思路。 2&#xff09;k-1时刻值减去k-1的状态最优估计k-1时…

Vscode设置忽略文件,忽略node-modules、dist

####看图 files.exclude 设置排除和显示的文件夹 search.exclude 设置搜索时忽略的文件夹

WEB:Cat

背景知识 命令执行漏洞 Django框架 题目 先ping一下&#xff0c;输入127.0.0.1 这个输入可能存在命令执行的操作&#xff0c;但是经过尝试之后并不能正常执行 127.0.0.1&&dir、127.0.0.1&&ls、127.0.0.1|ls均被屏蔽&#xff0c;但经过尝试可知&#xff0c;网…

matplotlib笔记:qbstyle设置matplotlib 主题

0 原始matplotlib import numpy as np import matplotlib.pyplot as pltxnp.linspace(0,100) ynp.sin(100*x)plt.plot(x,y); 1 light from qbstyles import mpl_style mpl_style(darkFalse) #开启light主题 plt.plot(x,y); 2 dark from qbstyles import mpl_style mpl_styl…

实现大文件传输的几种方法,并实现不同电脑间大文件传输

随着网络技术的快速发展&#xff0c;大文件的传输需求越来越多&#xff0c;如何在不同的电脑之间实现大文件的快速传输&#xff0c;是一个挑战&#xff0c;下面介绍几种常用的方法可以解决这个问题。 1、利用局域网传输&#xff1a;把两台电脑接入同一个网络环境&#xff0c;通…

关于硬件加速器FPGA的异构加速流程龙蜥CI框架及实践介绍 | 第 87-88 期

本周「龙蜥大讲堂」预告来啦&#xff01;我们邀请了浪潮信息异构加速软件工程师刘科分享《基于 FPGA 的数据库硬件加速研究》、 CICD SIG Maintainer 李晔做《龙蜥社区 CI 框架及实践》主题演讲&#xff0c;精彩多多&#xff0c;快入群&#xff0c;预定前排小板凳观看直播&…

项目名称:无源在线词典项目

一&#xff0c;概述 基于C语言的网络电子词典项目&#xff0c;使用到了tcp协议的并发服务器设计、网络编程、文件I/O、数据库等多方面的知识。可以满足多用户同时登陆&#xff0c;用户登陆后可以查询单词及历史记录&#xff0c;具有查找快速&#xff0c;保密性好等优点。 开…

19.删除链表的倒数第N个节点

19.删除链表的倒数第N个节点 这道题是链表问题中双指针的一个经典应用 如果要删除倒数第n个节点&#xff0c;那么我们让fast快指针移动n步&#xff0c;然后让fast和慢指针slow同时开始移动&#xff0c;当fast指针指向链表末尾的时候&#xff0c;删掉slow指针指向的节点即可。 …

ai绘画工具哪个好用?这几款好用的ai绘画生成器安利给你

嘿&#xff0c;小伙伴们&#xff01;你是否曾经想过创作一幅酷炫的人物插画&#xff0c;但由于缺乏绘画技巧而放弃这个想法&#xff1f;别担心&#xff0c;现在有了ai绘画工具&#xff0c;让你轻松成为艺术家的潜力无限&#xff01;今天我就来给大家介绍几个用ai绘画工具生成好…

【iOS】ARC实现

ARC由以下工具来实现&#xff1a; clang&#xff08;LLVM编译器&#xff09;3.0以上objc4 Objective-C运行时库493.9以上 下面我们&#xff0c;我们将围绕clang汇编输出和objc4库的源代码探究ARC实现 1. __strong修饰符 1.1 赋值给附有__strong修饰符的变量 看下面代码 {…

Android TextView 在最后一行末尾加图标

当前有个需求.显示一段文本&#xff0c;文本最多显示两行&#xff0c;点击展开后才显示完全。当没有显示完全的时候&#xff0c;需要在文本的第二行末尾显示图标&#xff0c;点击图标和文本&#xff0c;文本展开。难点在于图标需要和第二行文本显示在同一行&#xff0c;高度和文…

JavaScript的WebAPI

这里写目录标题 DOM 基本概念获取元素事件概念事件的三要素操作元素获取/修改表单元素属性行内样式操作类名样式操作操作节点 DOM 基本概念 DOM 全称为 Document Object Model. W3C 标准给我们提供了一系列的函数, 让我们可以操作: 网页内容 ,网页结构, 网页样式 DOM数的结构如…

【PDFBox】PDFBox操作PDF文档之读取指定页面文本内容、读取所有页面文本内容、根据模板文件生成PDF文档

这篇文章&#xff0c;主要介绍PDFBox操作PDF文档之读取指定页面文本内容、读取所有页面文本内容、根据模板文件生成PDF文档。 目录 一、PDFBox操作文本 1.1、读取所有页面文本内容 1.2、读取指定页面文本内容 1.3、写入文本内容 1.4、替换文本内容 &#xff08;1&#xf…

【C++】STL之list容器的模拟实现

个人主页&#xff1a;&#x1f35d;在肯德基吃麻辣烫 分享一句喜欢的话&#xff1a;热烈的火焰&#xff0c;冰封在最沉默的火山深处。 文章目录 前言一、list的三个类的关系分析图vector和list的区别1.节点的成员变量以及构造函数2.list的迭代器 二、list的增删查改工作2.1inse…

【数据结构】24王道考研笔记——图

六、图 目录 六、图定义及基本术语图的定义有向图以及无向图简单图以及多重图度顶点-顶点间关系连通图、强连通图子图连通分量强连通分量生成树生成森林边的权、带权网/图特殊形态的图 图的存储及基本操作邻接矩阵邻接表法十字链表邻接多重表分析对比图的基本操作 图的遍历广度…