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

ArrayList源码分析(JDK17)

ArrayList类

  • 简介
  • 类层次结构
  • 构造
    • 无参构造
    • 有参构造
  • 添加元素
    • add:添加/插入一个元素
    • addAll:添加集合中的元素
  • 扩容
  • mount与迭代器
  • 其他常见方法
  • 不常见方法
  • 不常见方法的源码和小介绍
  • 常见方法的源码和小介绍
  • 积累面试题
    • ArrayList是什么?可以用来干嘛?
    • ArrayList 的默认长度
    • ArrayList如何扩容
    • ArrayList频繁扩容导致性能下降该怎么办
    • 什么情况下你会使用ArrayList?什么时候你会选择LinkedList?
    • ArrayList的插入或删除一定比LinkedList慢吗


写在前面:

第一次写源码分析,感觉写起来,不知道从何下手,不过慢慢的也就写完了,也不知道条理怎么样,内容应该还是都说了。希望能对ArrayList的理解有所帮助.
本文通过ArrayList对动态数组的实现/生命周期来进行源码的解析。会列举源码并注释代码的作用。但不会讲述动态数组的实现过程,实现过程在数组–java–动态数组已经写过了

明天在继续写

本文内容包括:

    • 源码分析
    • 扩容机制
    • 迭代器
    • 面试题
    • 简介

      此类是 Java 集合框架的成员。 ArrayList 是一个数组队列,相当于动态数组。与Java中的数组相比,它的容量能动态增长。使用量很大,所以作为第一个进行源码分析的类。

      类层次结构

      继承于AbstractList抽象类
      在这里插入图片描述
      实现了:

      1. List
        有序集合(也称为 序列)的接口
      2. RandomAccess
        标记性接口,使得随机访问比迭代器快
      3. Cloneable
        标记性接口,克隆
        所以重写clone方法完成浅克隆
      4. java.io.Serializable
        标记性接口,序列化

      构造

      ArrayList的构造方法一共有3个
      在这里插入图片描述

      无参构造

      在这里插入图片描述
      elementData代表着的就是存储元素的数组了。
      transient关键字代表着其不能被序列化
      在这里插入图片描述

      注释上写着构造一共初始容量为10的空列表。但是我们打开DEFAULTCAPACITY_EMPTY_ELEMENTDATA这个类查看。很明显,这就是一个空数组,所以最开始的数组大小就是0。
      这个也算是慢初始,因为可能构造了不用,所以设置为空就会减少空间的浪费。
      在这里插入图片描述
      但为什么要这么写呢?
      我们可以看到这样一个属性,我们在扩容的时候用到这个,会导致无参构造扩容后就会是10.而在调用add后动态的初始化。

      在这里插入图片描述

      有参构造

      根据你传入的参数来构建大小,如果为0则会赋值一个空数组(但是这个和无参的不一样)
      在这里插入图片描述

      这个构造先判断传入集合的大小,如果为空则设置为空数组。
      如果不为空则判断是否的ArrayList类,是则直接赋值了,不是则进行拷贝。
      在这里插入图片描述

      添加元素

      add:添加/插入一个元素

      这里和jdk8会不一样
      modCount继承于AbstractList,记录着集合的修改次数
      然后调用了add(E e, Object[] elementData, int s)方法(jdk8直接实现出来了,而不是抽取方法)
      返回一个true代表添加成功
      在这里插入图片描述
      这段代码是很平常的添加代码,有意思的是这个注释。
      查阅资料发现,当方法字节码大小小于35的时候,会进行方法内联
      而这个操作由c1编译器进行。c1编译器(适用于执行时间较短或对启动性能有要求的程序)会比c2要快,所以可以让这个add成为热点,而被优化。
      这个部分应该属于JIT优化。
      在这里插入图片描述

      public void add(int index, E element)

      /**
      在此列表中的指定位置插入指定的元素。将当前位于该位置的元素(如果有)和任何后续元素向右移动(将一个元素添加到其索引中)。
      形参:
      index – 要插入指定元素的索引 element – 要插入的元素
      抛出:
      IndexOutOfBoundsException – 如果索引超出范围 (index < 0 || index > size())
      **/public void add(int index, E element) {rangeCheckForAdd(index); // 进行index范围的检查,超出范围会抛出异常modCount++;final int s;Object[] elementData;if ((s = size) == (elementData = this.elementData).length)elementData = grow();//赋值并且检查是否需要扩容System.arraycopy(elementData, index,elementData, index + 1,s - index);// 拷贝插入点前后的元素elementData[index] = element; // 插入点赋值size = s + 1;}
      

      addAll:添加集合中的元素

      扩容

      扩容判断

      if (s == elementData.length)则扩容
      

      这个是扩容的通用代码。
      记录了旧容量后,如果不是默认空数组,或者容量大于0则if成立。
      这里就是默认空数组和其他构造的空数组的区别了:

      如果是默认空数组则走初始容量为10的路线,否则则按照1.5倍扩容走

           /*** 增加容量以确保它至少可以容纳最小容量参数指定的元素数。** @param minCapacity 所需的最小容量* @throws OutOfMemoryError 如果最小容量小于零*/private Object[] grow(int minCapacity) {int oldCapacity = elementData.length;//获取旧容量if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {int newCapacity = ArraysSupport.newLength(oldCapacity,minCapacity - oldCapacity, /* 最小增长 */oldCapacity >> 1           /* 首选增长*/);//这个方法会从old的基础上,选取后面2个值的大的来增长。// 也就是,需要的容量和1.5倍比较return elementData = Arrays.copyOf(elementData, newCapacity);//拷贝旧的} else {return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];}}
      

      而一般性的,就是长度加一,调用上面的方法。

       private Object[] grow() {return grow(size + 1);}
      

      mount与迭代器

      其他常见方法

      //返回此列表中的元素数。
      public int size()//如果此列表不包含任何元素,则返回 true 。
      public boolean isEmpty()//如果此列表包含指定的元素,则返回true。更正式地说,当且仅当此列表包含至少一个元素eObjects.equals(o, e)时,返回 true .
      public boolean contains(Object o)//返回此列表中指定元素第一次出现的索引,如果此列表中不包含该元素,则返回 -1。更正式地说,返回最低索引,例如 Objects.equals(o, get(i)),如果没有这样的索引i,则返回 -1。
      public int indexOf(Object o)//返回此列表中指定元素最后一次出现的索引,如果此列表中不包含该元素,则返回 -1。更正式地说,返回最高索引,如果没有这样的索引iObjects.equals(o, get(i)),则返回 -1。public int lastIndexOf(Object o)

      不常见方法

      //将此实例的容量修剪为列表的 ArrayList 当前大小。
      public void trimToSize()  //如有必要,增加此 ArrayList 实例的容量,以确保它至少可以容纳最小容量参数指定的元素数。
      //形参:minCapacity – 所需的最小容量
      public void ensureCapacity(int minCapacity) //浅克隆
      public Object clone();

      不常见方法的源码和小介绍

      这是一个缩小空间的方法,把未使用的数组删掉。
      这个方法在ArrayList里面没有调用,但是在其他地方优化的时候还挺多的。
      在这里插入图片描述

          /*** 将此实例的容量修剪为列表的 ArrayList 当前大小。* 应用程序可以使用此操作来最小化实例的 ArrayList 存储*/public void trimToSize() {modCount++;if (size < elementData.length) {elementData = (size == 0)? EMPTY_ELEMENTDATA: Arrays.copyOf(elementData, size);}}
      

      没有调用的

      public void ensureCapacity(int minCapacity) {if (minCapacity > elementData.length&& !(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA&& minCapacity <= DEFAULT_CAPACITY)) {modCount++;grow(minCapacity);}}
      
      	public Object clone() {try {ArrayList<?> v = (ArrayList<?>) super.clone();v.elementData = Arrays.copyOf(elementData, size);v.modCount = 0;return v;} catch (CloneNotSupportedException e) {// this shouldn't happen, since we are Cloneablethrow new InternalError(e);}}
      

      常见方法的源码和小介绍

      把这个放后面呢是因为简单应该看的人少。

      public int size() {return size;}
       public boolean isEmpty() {return size == 0;}
      
      public boolean contains(Object o) {return indexOf(o) >= 0;}
      
      	 public int indexOf(Object o) {return indexOfRange(o, 0, size);}int indexOfRange(Object o, int start, int end) {Object[] es = elementData;if (o == null) {for (int i = start; i < end; i++) {if (es[i] == null) {return i;}}} else {for (int i = start; i < end; i++) {if (o.equals(es[i])) {return i;}}}return -1;}
      
      	public int lastIndexOf(Object o) {return lastIndexOfRange(o, 0, size);}int lastIndexOfRange(Object o, int start, int end) {Object[] es = elementData;if (o == null) {for (int i = end - 1; i >= start; i--) {if (es[i] == null) {return i;}}} else {for (int i = end - 1; i >= start; i--) {if (o.equals(es[i])) {return i;}}}return -1;}
      

      积累面试题

      ArrayList是什么?可以用来干嘛?

      ArrayList是个动态数组,实现List接口,主要用来存储数据,只存储包装类。它的特点是:
      增删慢:每次删除元素,都需要更改数组长度、拷贝以及移动元素位置。
      查询快:由于数组在内存中是一块连续空间,因此可以根据地址+索引的方式快速获取对应位置上的元素。
      

      ArrayList 的默认长度

      在jdk8以前和jdk8以后稍有不同
      jdk8以前:创建就会初始数组长度,长度为10
      jdk8及以后:是懒加载,初始的时候为空数组,在第一次添加元素的时候扩容为10
      

      ArrayList如何扩容

      定好容量后,定好会把原来的数组元素拷贝到新数组中,再把指向原数的地址换到新数组。
      这个有2种扩容机制
      对于无参构造的集合:在第一次添加元素的时候会扩容到10,存满后按照1.5倍的进行扩容。如果一次添加了多个元素1.5倍放不下,则会按照实际需要的大小进行扩容。
      对于其他的构造:就没有扩容10的步骤了,按照max(1.5倍,实际大小)
      

      ArrayList频繁扩容导致性能下降该怎么办

      这时候我们可以估算需要的容量,使用
      ArrayList(int capacity)的有参构造来指定容量的空列表
      

      在测试中甚至有几个下图这样这样的比例运行了
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

      什么情况下你会使用ArrayList?什么时候你会选择LinkedList?

      多数情况下,当你遇到访问元素比插入或者是删除元素更加频繁的时候,你应该使用ArrayList。
      另外一方面,当你在某个特别的索引中,插入或者是删除元素更加频繁,或者你压根就不需要访问元素的时候,你会选择LinkedList。
      这里的主要原因是,在ArrayList中访问元素的最糟糕的时间复杂度是”1″,
      而在LinkedList中可能就是”n”了。
      在ArrayList中增加或者删除某个元素,通常会调用System.arraycopy方法,这是一种极为消耗资源的操作,因此,在频繁的插入或者是删除元素的情况下,LinkedList的性能会更加好一点。
      

      ArrayList的插入或删除一定比LinkedList慢吗

      大多数是的,但是不一定.
      如果删除靠前的元素arraylist需要拷贝后面的元素
      如果靠中间或者靠后,linkedlist找元素需要消耗很多的时间,而arraylist拷贝的元素会少一些
      arraylist取数真的太快了,linkedlist就算能从后面找,就算是取最后一个数,也慢了很多
      

      数组长度n=10000
      a=100
      b=n-a
      c=n/2
      可以看到:

      随机向中间添加,arraylist快
      add方法添加到最后,linkedlist完胜
      随机删除Arraylist快
      删除靠前元素:linkedlist快
      删除中间的,arralist快
      删除后面的,arralist快
      
      TestArrayList.testArrayListRandonAdd          thrpt    2    12289.462          ops/s
      TestArrayList.testLinkedListRandonAdd         thrpt    2    11362.013          ops/s
      TestArrayList.testArrayListRandonAddLast      thrpt    2    12820.688          ops/s
      TestArrayList.testLinkedListRandonAddLast     thrpt    2  2482660.154          ops/s
      TestArrayList.testArrayListRandonRemove       thrpt    2   207213.498          ops/s
      TestArrayList.testLinkedListRandonRemove      thrpt    2    11402.369          ops/s
      TestArrayList.testArrayListRemove100          thrpt    2   110029.496          ops/s
      TestArrayList.testLinkedListRemove100         thrpt    2  1036584.680          ops/s
      TestArrayList.testArrayListRemoveNDividing2   thrpt    2   205019.017          ops/s
      TestArrayList.testLinkedListRemoveNDividing2  thrpt    2     6156.114          ops/s
      TestArrayList.testArrayListRemoveN_100        thrpt    2  2064240.192          ops/s
      TestArrayList.testLinkedListRemoveN_100       thrpt    2  1072619.806          ops/s
      

      在这里插入图片描述
      在这里插入图片描述
      接下来下调参数
      n=1000
      a=10
      b=n-a
      c=n/2

      随机向中间添加,linkedlist快
      add方法添加到最后,linkedlist完胜
      随机删除Arraylist快
      删除靠前元素:linkedlist快
      删除中间的,arralist快
      删除后面的,linkedlist快
      
      Benchmark                                     Mode  Cnt  Score   Error  Units
      TestArrayList.testArrayListRandonAdd          avgt       0.912          us/op
      TestArrayList.testLinkedListRandonAdd         avgt       0.423          us/op
      TestArrayList.testArrayListRandonAddLast      avgt       0.788          us/op
      TestArrayList.testLinkedListRandonAddLast     avgt       0.042          us/op
      TestArrayList.testArrayListRandonRemove       avgt       0.194          us/op
      TestArrayList.testLinkedListRandonRemove      avgt       0.418          us/op
      TestArrayList.testArrayListRemove100          avgt       0.211          us/op
      TestArrayList.testLinkedListRemove100         avgt       0.043          us/op
      TestArrayList.testArrayListRemoveNDividing2   avgt       0.189          us/op
      TestArrayList.testLinkedListRemoveNDividing2  avgt       0.722          us/op
      TestArrayList.testArrayListRemoveN_100        avgt       0.151          us/op
      TestArrayList.testLinkedListRemoveN_100       avgt       0.039          us/op

      在这里插入图片描述

    相关文章:

    ArrayList源码分析(JDK17)

    ArrayList类简介类层次结构构造无参构造有参构造添加元素add&#xff1a;添加/插入一个元素addAll:添加集合中的元素扩容mount与迭代器其他常见方法不常见方法不常见方法的源码和小介绍常见方法的源码和小介绍积累面试题ArrayList是什么&#xff1f;可以用来干嘛&#xff1f;Ar…...

    数字IC/FPGA面试笔试准备(自用待填坑)

    文章目录 前言常见的IC问题数字电路基础问题Verilog & SV跨时钟域信号处理类综合与时序分析类低功耗方法STA(静态时序分析)RTL设计(包含手撕代码)总线问题AXIAPBAHB体系结构的问题RISCV的问题一些笔试选择题前言 这是实验室师兄面试过程中整理的面试和笔试题目,目前只有题…...

    基于多任务融合的圣女果采摘识别算法研究

    基于多任务融合的圣女果采摘识别算法研究 1、简介 本文主要解决圣女果生产销售环节中&#xff0c;现有的流程是采摘成熟的圣女果&#xff0c;再对采摘下的果实进行单独的品质分级&#xff0c;不仅费时费力&#xff0c;而且多增加一个环节&#xff0c;也增加了对果实的二次伤害…...

    又一个开源第一!飞桨联合百舸,Stable Diffusion推理速度遥遥领先

    AIGC(AI Generated Content)&#xff0c;即通过人工智能方法生成内容&#xff0c;是当前深度学习最热门的方向之一。其在绘画、写作等场景的应用也一直层出不穷&#xff0c;其中&#xff0c;AI绘画是大家关注和体验较多的方向。 Diffusion系列文生图模型可以实现AI绘画应用&…...

    数据链路层及交换机工作原理

    目录 一&#xff0c;帧格式 1.1 帧头类型字段的作用 1.2 MAC地址 1.3 MTU值 二&#xff0c;交换机工作原理 2.1 交换机的端口 2.2 端口状态 三&#xff0c;交换机基本工作模式及命令 3.1 交换机的工作模式&#xff1a; 3.2 命令 一&#xff0c;帧格式 其中类型是指&am…...

    VSCode 开发配置,一文搞定(持续更新中...)

    一、快速生成页面骨架 文件 > 首选项 > 配置用户代码片段 选择需要的代码片段或者创建一个新的&#xff0c;这里以 vue.json 举例&#xff1a; 下面为我配置的代码片段&#xff0c;仅供参考&#xff1a; {"Print to console": {"prefix": "…...

    全网最详细的(CentOS7)MySQL安装

    一、环境介绍 操作系统&#xff1a;CentOS 7 MySQL&#xff1a;5.7 二、MySQL卸载 查看软件 rpm -qa|grep mysql 卸载MySQL yum remove -y mysql mysql-libs mysql-common rm -rf /var/lib/mysql rm /etc/my.cnf 查看是否还有 MySQL 软件&#xff0c;有的话继续删除。 软件卸…...

    基于LSTM的文本情感分析(Keras版)

    一、前言 文本情感分析是自然语言处理中非常基本的任务&#xff0c;我们生活中有很多都是属于这一任务。比如购物网站的好评、差评&#xff0c;垃圾邮件过滤、垃圾短信过滤等。文本情感分析的实现方法也是多种多样的&#xff0c;可以使用传统的朴素贝叶斯、决策树&#xff0c;…...

    2023年全国最新机动车签字授权人精选真题及答案17

    百分百题库提供机动车签字授权人考试试题、机动车签字授权人考试预测题、机动车签字授权人考试真题、机动车签字授权人证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 三、多选题 1.注册登记安全检验时&#xff0c;送检乘用…...

    PowerShell远程代码执行漏洞(CVE-2022-41076)分析与复现

    漏洞概述PowerShell&#xff08;包括Windows PowerShell和PowerShell Core&#xff09;是微软公司开发的任务自动化和配置管理程序&#xff0c;最初只是一个 Windows 组件&#xff0c;由命令行 shell 和相关的脚本语言组成。后于2016年8月18日开源并提供跨平台支持。PowerShell…...

    Mybatis中的一级缓存和二级缓存

    Mybatis作为一款强大的ORM框架&#xff0c;其中也用到了缓存来加速查询&#xff0c;今天我们一起来探讨下。 Mybatis可以使用懒加载来提高查询的效率&#xff0c;并且可以通过缓存来提高查询的效率。其中包括有一级缓存和二级缓存。 一级缓存是sqlSession级别的缓存&#xff0c…...

    【Java】SpringBoot中实现异步编程

    前言 首先我们来看看在Spring中为什么要使用异步编程&#xff0c;它能解决什么问题&#xff1f; 什么是异步&#xff1f; 首先我们先来看看一个同步的用户注册例子&#xff0c;流程如下&#xff1a; 异步的方式如下&#xff1a; 在用户注册后将成功结果返回&#xff0c;…...

    ASCII 文件与 TIFF 文件互转(Python 实现)(2023/03/09)

    ASCII 文件与 TIFF 文件互转&#xff08;Python 实现&#xff09; 文章目录ASCII 文件与 TIFF 文件互转&#xff08;Python 实现&#xff09;1. 环境1.1 Linux1.2 Windows2. 代码1. 环境 1.1 Linux $ pip3 install --index-url https://mirrors.aliyun.com/pypi/simple --tru…...

    思科模拟器 | 交换机与路由器的配置汇总【收藏备用】

    文章目录一、vlan配置【实现同一vlan的主机通信】1、基本配置和接线2、vlan配置与端口连接3、测试连接二、truck配置【实现连接在不同交换机上的同一vlan的主机通信】1、基本配置和接线2、vlan配置与端口连接3、打truck做连接3、测试连接三、静态路由配置1、自定义IP地址2、基本…...

    电子台账:软件运行环境要求与功能特点

    1 运行环境要求为满足大部分应用环境&#xff0c;软件开发时综合考虑各种各种不同因素影星&#xff0c;包括&#xff1a;操作系统、硬件、辅助软件、安装、运行、补丁、数据库、网络、人员等因素。目前台账软件需求为&#xff1a;操作系统&#xff1a;目前能运行的任意版本wind…...

    计算机科学导论笔记(六)

    目录 八、算法 8.1 概念 8.1.1 非正式定义 8.1.2 示例 8.1.3 定义动作 8.1.4 细化 8.1.5 泛化 8.2 三种结构 8.2.1 顺序 8.2.2 判断 8.2.3 循环 8.3 算法的表示 8.3.1 UML 8.3.2 伪代码 8.4 更正式的定义 8.5 基本算法 8.5.1 求和 8.5.2 求积 8.5.3 最大和最…...

    嵌入式从业10年,聊聊我对工业互联网和消费物联网的看法 | 文末赠书4本

    嵌入式从业10年&#xff0c;聊聊我对工业互联网和消费物联网的看法 工业互联网和消费物联网&#xff0c;有何异常点&#xff1f;本文&#xff0c;博主将结合自己的亲身经历&#xff0c;现身说法&#xff0c;聊聊博主对工业互联网和消费物联网的看法。 文章目录1 写在前面2 我眼…...

    python的django框架从入门到熟练【保姆式教学】第一篇

    当今&#xff0c;Python已成为最受欢迎的编程语言之一。而Django是一个基于Python的Web框架&#xff0c;它能够帮助你快速、高效地开发Web应用程序。如果你是一名初学者&#xff0c;学习Django框架可能会让你感到有些困惑。不过&#xff0c;不用担心&#xff0c;我们将为你提供…...

    浏览记录或者购物车的去重处理

    saveHistory(){// 获取缓存数据let historyArr uni.getStorageSync(historyArr) || []//需要添加的数据let item{id:this.detail.id,classid:this.detail.classid,title:this.detail.title,picurl:this.detail.picurl,looktime:parseTime(Date.now())};// forEach和findIndex的…...

    Ubantu docker学习笔记(二)拉取构建,属于你的容器

    文章目录一、拉取启动容器二、本地镜像初解三、构建镜像3.1使用docker commit构建镜像切换阿里镜像3.2使用dockerfile构建镜像四、总个结吧这里的话&#xff0c;就详细说说小唐对于容器的配置&#xff0c;对了&#xff01;小唐参考的书籍是Linux容器云实战&#xff01;&#xf…...

    指针数组 数组指针 常量指针 指针常量 函数指针 指针函数

    一、指针常量与常量指针 1、指针常量 本质上是一个常量&#xff0c;常量的类型是指针&#xff0c;表示该常量是一个指针类型的常量。在指针常量中&#xff0c;指针本身的值是一个常量&#xff0c;不可以改变&#xff0c;始终指向同一个地址。在定义的时候&#xff0c;必须要初…...

    前端js学习

    1. js入门 1.1 js是弱类型语言 1.2 js使用方式 1.2.1 在script中写 1.2.2 引入js文件 1.2.3 优先级 1.3 js查错方式 1.4 js变量定义 1.4 js数据类型 数据类型英文表示示例数值类型number1.1 1字符串类型string‘a’ ‘abc’ “abc”对象类型object布尔类型booleannumber函数…...

    “华为杯”研究生数学建模竞赛2007年-【华为杯】A题:食品卫生安全保障体系数学模型及改进模型(附获奖论文)

    赛题描述 我国是一个拥有13亿人口的发展中国家,每天都在消费大量的各种食品,这批食品是由成千上万的食品加工厂、不可计数的小作坊、几亿农民生产出来的,并且经过较多的中间环节和长途运输后才为广大群众所消费,加之近年来我国经济发展迅速而环境治理没有能够完全跟上,以至…...

    转战C#---day2

    定义数组&#xff1a; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace Relay_Sin_Com {class Program{static void Main(string[] args){int[] ages1 {3240,242,34};Console.WriteLine(age…...

    【vue2源码学习】— diff

    vue更新还是调用了 vm._update 会进入下面这一步 vm.$el vm.__patch__(prevVnode, vnode) 又回到了patch方法 会通过sameVnode 判断是不是相同的vnode// patch代码片段 const isRealElement isDef(oldVnode.nodeType) if (!isRealElement && sameVnode(oldVnode, vno…...

    更换 Linux 自带的 jdk 环境

    如下&#xff0c;我要把 Linux 默认的 jdk 版本换成我自己的 jdk 版本。 Linux 自带的 jdk 环境&#xff1a; 要更换的 jdk 环境&#xff1a; 1、切换到 root 用户进行操作&#xff1b; 2、在根目录下创建一个 /export/server/ 目录&#xff1b; [rootcentos /]# mkdir -p /e…...

    MySQL8读写分离集群

    文章目录前言MySQL读写分离原理搭建MySQL读写分离集群MySQL8.0之前MySQL8.0之后后记前言 上一期介绍并实现了MySQL的主从复制&#xff0c;由于主从复制架构仅仅能解决数据冗余备份的问题&#xff0c;从节点不对外提供服务&#xff0c;依然存在单节点的高并发问题 所以在主从复…...

    蓝桥冲刺31天之第七天

    目录 A&#xff1a;三角回文数 B&#xff1a;数数 C&#xff1a;数组切分 D&#xff1a;倍数问题 一星陨落&#xff0c;黯淡不了星空灿烂&#xff1b; 一花凋零&#xff0c;荒芜不了整个春天。 如果命运是世界上最烂的编剧&#xff0c; 你就要争取做人生最好的演员。 即使生…...

    【Python百日进阶-Web开发-Vue3】Day550 - Vue3 商城后台 10:Veux4-02基本使用

    文章目录 二、Vuex的基本使用2.4 Mutations 应用 :同步更新state2.4.1 `src/store/index.js`2.4.2 `src/views/index.vue`2.5 Module的应用:分模块2.5.1 `src/store/modules/product.js`2.5.2 `src/store/modules/cart.js`2.5.3 `src/store/index.js`2.5.4 `src/views/index.…...

    ESP32驱动-红外寻迹传感器驱动

    红外寻迹传感器驱动 1、红外寻迹传感器介绍 红外寻迹传感器具有一对红外线发射管与接收管,发射管发射出一定频率的红外线,当检测方向遇到障碍物(反射面)时,红外线反射回来被接收管接收,经过比较器电路处理之后,输出接口会输出一个数字信号(低电平或高电平,取决于电路…...

    【TS】TypeScript泛型 T 的用法详解

    一、什么是泛型&#xff1f; 泛型&#xff0c;从字面上理解&#xff0c;泛型就是一般的&#xff0c;广泛的的意思。 TypeScript中泛型&#xff08;Generics&#xff09;是指在定义函数、接口或类的时候&#xff0c;不预先指定具体类型&#xff0c;而是在使用的时候再指定类型…...

    Vue 3.0 单文件组件 【Vue3 从零开始】

    #介绍 在很多 Vue 项目中&#xff0c;我们使用 app.component 来定义全局组件&#xff0c;紧接着用 app.mount(#app) 在每个页面内指定一个容器元素。 这种方式在很多中小规模的项目中运作的很好&#xff0c;在这些项目里 JavaScript 只被用来加强特定的视图。但当在更复杂的…...

    北邮22信通:你是不是在looking for……那串代码?(2)第三章单链表

    相信有了第二章顺序表的基础&#xff0c;小伙伴们学习第三章链表应该会轻松一点吧 目录 类模板下的单链表 1.1书上干净完整代码&#xff08;无增改、适合自己动手实验&#xff09; 1.2对书上代码的完善和对一些问题的验证和解释代码 1.补全一个函数&#xff1a; 2.this指…...

    蓝库云|告诉你传统产业该如何进行数字化转型

    在后疫情时代下&#xff0c;企业该如何在面临生存危机的情形下&#xff0c;投入「数字化转型」、提升公司竞争力&#xff0c;已成为许多公司的当务之急&#xff0c;但到底什么是数字化转型呢&#xff1f;传统产业又如何着手进行数位转型&#xff1f; 数字化转型是什么&#xf…...

    121.(leaflet篇)leaflet结合echarts4迁徙图

    听老人家说:多看美女会长寿 地图之家总目录(订阅之前建议先查看该博客) 文章末尾处提供保证可运行完整代码包,运行如有问题,可“私信”博主。 效果如下所示: 下面献上完整代码,代码重要位置会做相应解释 <!DOCTYPE html> <html>...

    链表及其基本操作

    1.单链表&#xff1a;1.1定义/性质&#xff1a;链表是线性表的链式存储方式。单链表通过指针线性遍历&#xff0c;删除/增加节点时间复杂度为O(1&#xff09;,访问节点时间复杂度为O(n)。单链表分为带头结点和不带头结点两种&#xff0c;带头结点是为了方便统一操作&#xff08…...

    【Java基础 下】 031 -- 反射 动态代理

    一、什么是反射&#xff1f; 换句话说就是&#xff08;从类里拿出来&#xff09; 可以获取到&#xff1a;&#xff08;利用反射&#xff0c;我们可以获取到类中所有的东西&#xff09; 获取是先从class字节码文件中获取的 二、获取class对象的三种方式 三种方式也对应了三种阶段…...

    springcloud3 GateWay

    一 GateWay 1.1 GateWay的作用 gateway相当于所有服务的门户&#xff0c;将客户端请求与服务端应用相分离&#xff0c;客户端请求通过gateway后由定义的路由和断言进行转发&#xff0c;路由代表需要转发请求的地址&#xff0c;断言相当于请求这些地址时所满足的条件&#xff…...

    万字长文:Stable Diffusion 保姆级教程

    万字长文&#xff1a;Stable Diffusion 保姆级教程 2022年绝对是人工智能爆发的元年&#xff0c;前有 stability.ai 开源 Stable Diffusion 模型&#xff0c;后有 Open AI 发布 ChatGPT&#xff0c;二者都是里程碑式的节点事件&#xff0c;其重要性不亚于当年苹果发布iPhone&a…...

    WAMP搭建靶场

    WAMP W&#xff1a;windows A&#xff1a;apache M&#xff1a;mysql&#xff0c;mariadb P&#xff1a;php 1. 下载phpstudy Windows版phpstudy下载 - 小皮面板(phpstudy) 2. 安装phpstudy 默认安装即可 3. 下载DVWA靶场 https://github.com/digininja/DVWA/archive/…...

    Uipath Excel 自动化系列13-ForEachExcelSheet(遍历Sheet)

    活动描述 ForEachExcelSheet(遍历Sheet)&#xff1a;遍历Excel中的工作表&#xff0c;可以对 Excel 工作簿中的每个工作表重复一个或多个活动,该活动需与Use Excel File 活动选择的 Excel 文件一起使用。 使用场景&#xff1a;当处理包含多张工作表的 Excel 文件&#xff0c;…...

    JDBC快速入门

    &#x1f34e;道阻且长&#xff0c;行则将至。&#x1f353; 目录 一、JDBC入门 1.概述 (1)JDBC本质 (2)JDBC好处 2.快速入门 (1)步骤 (2)实践 (3)两个小问题 一、JDBC入门 1.概述 JDBC就是使用Java语言操作关系型数据库的一套API&#xff0c;全称&#xff1a;( Java…...

    蓝桥杯三月刷题 第六天

    文章目录&#x1f4a5;前言&#x1f609;解题报告&#x1f4a5;星期计算&#x1f914;一、思路:&#x1f60e;二、代码&#xff1a;&#x1f4a5;考勤刷卡&#x1f914;一、思路:&#x1f60e;二、代码&#xff1a;&#x1f4a5;卡片&#x1f914;一、思路:&#x1f60e;二、代…...

    分享几个常用的运维 shell 脚本

    今天咸鱼给大家分享几个不错的 Linux 运维脚本&#xff0c;这些脚本中大量使用了 Linux 的文本三剑客&#xff1a; awkgrepsed 建议大家这三个工具都要了解并最好能够较为熟练的使用 根据 PID 显示进程所有信息 根据用户输入的PID&#xff0c;过滤出该PID所有的信息 #! /b…...

    分隔链表(精美图示详解哦)

    全文目录引言分隔链表题目描述与思路实现总结引言 前面&#xff0c;我们熟悉了管理链表中的数据的方法&#xff0c;也了解了几道与链表相关的题目&#xff1a; 戳我看单链表详解哦 在本篇文章中&#xff0c;我们将再了解一道题目&#xff1a;分隔链表&#xff1a; 分隔链表OJ…...

    腾讯乐固加固+app签名+多渠道打包

    一、腾讯乐固-基础版免费加固-上传未加固的app-下载加固包&#xff08;加固成功会清除原apk的签名信息和多渠道信息&#xff09;https://console.cloud.tencent.com/ms/reinforce/list/basic二、使用AndroidStudio自带工具apksigner对apk重新签名找到apksigner.bat文件 路径D:\…...

    Spring Boot整合Redis缓存(Lettuce)

    spring-boot-demo-cache-redis 此 demo 主要演示了 Spring Boot 如何整合 redis&#xff0c;操作redis中的数据&#xff0c;并使用redis缓存数据。连接池使用 Lettuce。 Lettuce官网 pom.xml <!-- data-redis --> <dependency><groupId>org.springframework…...

    Feign

    而Feign则会完全代理HTTP请求&#xff0c;我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。Feign整合了Ribbon和Hystrix&#xff0c;可以让我们不再需要显式地使用这两个组件。 Feign具有如下特性&#xff1a; 支持可插拔的HTTP编码器和解码器; 支持Hystrix和…...

    【代码训练营】day54 | 392.判断子序列 115.不同的子序列

    所用代码 java 判断子序列 LeetCode 392 题目链接&#xff1a;判断子序列 LeetCode 392 - 简单 思路 这题和之前求最长公共子序列一样。 dp[i] [j]&#xff1a;以i-1为结尾的字符串s 和 以j-1为结尾的字符串t 组成的相同子序列的长度 递推公式&#xff1a; 相等dp[i][j] d…...

    【unity3D】创建TextMeshPro(TMP)中文字体(解决输入中文乱码问题)

    &#x1f497; 未来的游戏开发程序媛&#xff0c;现在的努力学习菜鸡 &#x1f4a6;本专栏是我关于游戏开发的学习笔记 &#x1f236;本篇是unity的TMP中文输入显示乱码的解决方式 创建 TextMeshPro 中文字体遇到的问题描述解决方式Font Asset Creator 面板扩展中文字体文本遇到…...