java数组与集合框架(一) -- 数据结构,数组

数据结构

概述

为什么要讲数据结构?

        任何一个有志于从事IT领域的人员来说,数据结构(Data Structure)是一门和计算机硬件与软件都密切相关的学科,它的研究重点是在计算机的程序设计领域中探讨如何在计算机中组织和存储数据并进行高效率的运用,涉及的内容包含:数据的逻辑关系、数据的存储结构、排序算法(Algorithm)、查找(或搜索)等。

我们举一个形象的例子来理解数据结构的作用:

        战场:程序运行所需的软件、硬件环境

        敌人:项目或模块的功能需求

        指挥官:编写程序的程序员

        士兵和装备:一行一行的代码

        战术和策略:数据结构

                没有战术,打仗事倍功半

                有战术,打仗事半功倍

        总结:简单来说,数据结构,就是一种程序设计优化的方法论,研究数据的逻辑结构和物理结构以及它们之间相互关系,并对这种结构定义相应的运算,目的是加快程序的执行速度、减少内存占用的空间。

        因此,数据结构和算法是一名程序开发人员的必备基本功,不是一朝一夕就能练成绝世高手的。冰冻三尺非一日之寒,需要我们平时不断的主动去学习积累。

数据结构的应用

        计算机的主要工作就是把数据(Data)经过某种运算处理转换为实用的信息(Information) 。具体介绍一些数据结构的应用:

1)树形结构

        树形结构是一种相当重要的非线性数据结构,广泛运用在人类社会的族谱、机关的组织结构、计算机的操作系统结构、平面绘图应用、游戏设计等方面。

上图:四叉树示意图

上图:地形与四叉树的对应关系

2)最短路径

        最短路径是指在众多不同的路径中距离最短或者所花费成本最少的路径。寻找最短路径最常见的应用是公共交通运输系统的规划或网络的架设,如都市公交系统、铁路运输系统、通信网络系统等。

        现在很多汽车和手机都安装了GPS导航,用于定位和路况查询。其中路程的计算就是以最短路径的理论作为程序设计的依据,为旅行者提供不同的路径作为选择方案。

3)搜索理论

        所谓“搜索引擎,是一种自动从因特网的众多网站中查找信息,再经过一定的整理后提供给用户进行查询的系统,例如百度、谷歌、搜狗等。

        注意,Search这个单词在网络上习惯上翻译为搜索,如搜索引擎。而在数据结构的算法描述中,习惯翻译成查找。在计算机科学中,搜索查找大部分情况下可以互相转换。

        Pascal之父Nicklaus Wirth:“Algorithms+Data Structures=Programs”

        上面我们提到的数据结构和算法是程序设计实践中最基本的内涵。程序能否快速而高效地完成预定的任务,取决于是否选对了数据结构,而程序是否能清楚而正确地把问题解决,则取决于算法。算法是计算机处理信息的本质,因为计算机程序本质上是一个算法来告诉计算机确切的步骤来执行一个指定的任务。

        所以大家认为:“Algorithms + Data Structures = Programs(出自:Pascal之父Nicklaus Wirth

        数据结构只是静态的描述了数据元素之间的关系。

        高效的程序需要在数据结构的基础上设计和选择算法。

总结:算法是为了解决实际问题而设计的,数据结构是算法需要处理的问题载体。

数据结构的研究对象

数据间的逻辑结构
集合

        数据元素之间只有“同属于一个集合”的关系

线性关系

        数据元素之间存在一个对一个的关系,对应Java中的线性表:顺序表、链表、栈、队列

树形结构

        数据元素之间存在一个对多个的关系,对应Java中的树。比如:二叉树

网状结构(或图状结构)

        数据元素之间存在多个对多个的关系,对应Java中的图

数据的存储结构(或物理结构)

        参考书籍:数据结构与算法分析Java语言描述(第2版)[美] 卡拉罗(Carrano,F.M.) 著 金名,等 译

        大话数据结构 (作 者:程杰 著)

真实结构

        在内存中真实存在的, 用来存放多个数据的内存结构。

线性表之顺序表(或静态数据结构):数组(Array)、ArrayList

        特点:① 使用连续分配的内存空间;②一次申请一大段连续的空间, 需要事先声明最大可能要占用的固定内存空间

        优点:设计简单,读取与修改表中任意一个元素的时间都是固定的

        缺点:① 容易造成内存的浪费;② 删除或插入数据需要移动大量的数据

        存储思路

       所有数据存储在这个连续的空间中,数组中的每一个元素都是一个具体的数据,所有数据都紧密排布,不能有间隔

                

                                 

操作

        读内存

                 查:每个元素都有一个数值下标, 可以通过下标瞬间定位到某个元素

        写内存

                 增

                         从头部插入

                         在中间插入

                         从尾部插入

                         注意:插入元素,引起部分元素后移,代价非常高

                 删

                         注意:去掉元素,引起部分元素前移,代价非常高

                 改

                         注意:只需要修改对应位置的元素的内容,不需要申请或者删除空间

                 适用范围

                         查询操作远多于插入/删除操作的场景

                         简单抽象数据结构的基石

线性表之链表(或动态数据结构):Linked List

        特点:① 使用不连续的内存空间;② 不需要提前声明好指定大小的内存空间。一次申请一小块内存,按需申请

        优点:① 充分节省内存空间;② 数据的插入和删除方便,不需要移动大量数据

        缺点:① 设计此数据结构较为麻烦;② 查找数据必须按顺序找到该数据为止,麻烦

        存储思路

                每一个小数据单独存在一小块内存中,这个单元被称作结点(Node)

                 每一小块内存知道下一小块的地址

                                  比如:地下党,只知道自己的下线,单线联系

                 多个不连续的小内存空间组成, 通过内存地址引用形成一个链的结构

                

      表头:程序员获得表头就可以找到链表中所有的元素

     表尾:有的链表有,有的没有

实现结构:链表

        单向链表

        环形链表

        双向链表

读写操作

        读

                 查:节点是没有下标的, 只能从链表的表头开始查找某个节点

        写

                 增

                         申请一小块内存--结点

                         插入到链中

                                  从头部插入

                                  从尾部插入

                                  从中间插入

                 删

                         从链中剥离结点

                         释放这个结点的内存

                 改

                         改变这个结点中所存储的值

                 适用范围

                         插入/删除操作远多于查询操作的场景

                         复杂抽象数据结构的基石

抽象结构(ADT)

        在内存中并不存在此结构, 由程序员利用数组/链表封装成的结构

栈(Stack)

        栈(Stack)是限制仅在表的一端进行插入和删除运算的线性表。

        栈的修改原则:

                栈的修改是按后进先出的原则进行。每次删除(退栈)的总是当前栈中"最新"的元素,即最后插入(进栈)的元素,而最先插入的是被放在栈的底部,要到最后才能删除。

超市货架上的商品,一叠书

           

名词
栈顶

        插入、删除的这一端为栈顶

栈底

        相对于栈顶的另一端

空栈

        当表中没有元素时称为空栈

特点

        继承于java.util.Vector,后进先出

实现结构
顺序表实现栈

        用数组实现

                优点:算法简单

                缺点:数组大小只能事先规划声明好,太大了浪费空间,太小了不够用

链表实现栈

                优点:随时可动态改变链表长度,有效利用内存空间

                缺点:算法设计复杂

基本运算

        进栈(压栈、入栈): push(ele)

        出栈: pop()

        查看栈顶元素: peek()

        清栈: clear()

        大小: size()

        判断是否是空:empty()

        查找元素出现位置:search(Object  obj)

使用场景

二叉树和森林的遍历

CPU的中断处理

图形的深度优先查找法(DFS)

递归调用

        斐波那契数列

        汉诺塔问题

子程序的调用

队列(Queue)

        队列(Queue)是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表。

队列的修改原则:

        队列的修改是依先进先出的原则进行的。新来的成员总是加入队尾(即不允许"加塞"),每次离开的成员总是队列头上的(不允许中途离队),即当前"最老的"成员离队。

                

名词

        队头(front):允许删除的一端称为队头(Front)

        队尾(rear):允许添加的一端称为队尾(Rear)

        空队列:当队列中没有元素时称为空队列

特点

        先进先出,典型实现:PriorityQueue

实现结构

        顺序表实现队列

                                  用数组实现

                                  优点:算法简单

                                  缺点:数组大小固定,无法根据队列实际需要动态申请

        链表实现队列

                                  优点:随时可动态改变链表长度,有效利用内存空间

                                  缺点:算法设计复杂

操作

                         加入元素到队列尾部: add(Object obj)/offer(Object obj)

                         获取队列头部元素,不删除该元素:element()/peek()

                         获取队列头部元素,并删除该元素:remove()/poll()

                         清理队列: clear()

                         得到队列的大小: size()

                         判断队列是否是空的: isEmpty()

使用场景

                         图形的广度优先查找法(BFS)

                         可用于计算机各种事件处理的模拟

                                  如: 事件队列, 消息队列

                         CPU的作业调度

变形的队列

                         环形队列

                

                         双向队列

                        

                         优先队列

                        

树(Tree)

        树:

        对大量的输入数据,链表的线性访问时间太慢,不宜使用。这里是另外一种重要的数据结构----树,其大部分时间可以保证操作的运行平均时间复杂度为O(logN)

        例如:公司组织架构,家族族谱,Linux系统的文件和目录结构

计算机世界的树
专有名词

结点:树中的数据元素都称之为结点

根节点:最上面的结点称之为根,一颗树只有一个根且由根发展而来,从另外一个角度来说,每个结点都可以认为是其子树的根

父节点:结点的上层结点,如图中,结点K的父节点是E、结点L的父节点是G

子节点:节点的下层结点,如图中,节点E的子节点是K节点、节点G的子节点是L节点

兄弟节点:具有相同父节点的结点称为兄弟节点,图中F、G、H互为兄弟节点

结点的度数:每个结点所拥有的子树的个数称之为结点的度,如结点B的度为3

树叶:度数为0的结点,也叫作终端结点,图中D、K、F、L、H、I、J都是树叶

非终端节点(或分支节点):树叶以外的节点,或度数不为0的节点。图中根、A、B、C、E、G都是

树的深度(或高度):树中结点的最大层次数,图中树的深度为4

结点的层数:从根节点到树中某结点所经路径上的分支树称为该结点的层数,根节点的层数规定为1,其余结点的层数等于其父亲结点的层数+1

同代:在同一棵树中具有相同层数的节点

二叉树(Binary Tree)

二叉树:

在普通树的基础上,让一棵树中每个节点最多只能包含两个子节点,且严格区分左子节点和右子节点(位置不能换)。

                                         

分类

                     

功能

                 增删改查

                 搜索

                                  广度优先搜索

                                  深度优先搜索

                                          前序遍历:树根->左子树->右子树

                                          中序遍历:左子树->树根->右子树

                                          后序遍历:左子树->右子树->树根

特例
排序二叉树           

满足一些条件的二叉树,才被称为排序二叉树。比如:若它的左子树不为空,左子树上的所有节点值均小于根节点值;若右子树不为空,右子树上的所有节点值均大于根节点值。

特点:可以非常方便地对树中的所有节点进行排序和检索。

红黑树

红黑树顾名思义就是结点是红色或者黑色的平衡二叉树,它通过颜色的约束来维持着二叉树的平衡。下图为一颗典型的二叉树:

对于一棵有效的红黑树而言我们必须增加如下规则:

1、每个结点都只能是红色或者黑色

2、根节点是黑色

3、每片叶子都是黑色的

4、如果一个结点是红色的,则它的两个子节点都是黑色的,也就是说在一条路径上不能出现相邻的两个红色结点

5、从任意一个结点到其每个叶子的所有路径都包含着相同数目的黑色结点

        这些约束强制了红黑树的关键性质:从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。结果就是这棵树大致上是平衡的,因为插入、删除和查找某个值得最坏情况时间都要求与树的高度成比例,这个高度理论上限允许红黑树只在最坏情况下都是高效的。

        再具体就不说了,可以参看http://www.cnblogs.com/yangecnu/p/Introduce-Red-Black-Tree.html,对红黑树的讲解写得非常好。

        TreeMap和TreeSet就是红黑树的典型实现。

使用场景
哈夫曼树

        一种带权路径最短的二叉树,在信息检索中很常用

哈夫曼编码

        假设需要对一个字符串如“abcdabcaba”进行编码,将它转换为唯一的二进制码,同时要求转换出来的二进制码的长度最小。我们采用哈夫曼树来解决报文编码问题。

        1. 哈夫曼编码:在数据通信中,需要将传送的文字转换成二进制的字符串,现要求为这些字母设计编码。在实际应用中,各个字符的出现频度或使用次数是不相同的,如ABC的使用频率远远高于XYZ,自然会想到设计编码时,让使用频率高的用短码,使用频率低的用长码,以优化整个报文编码。为了获得传送报文的最短长度,可将每个字符的出现频率作为字符结点的权值赋予该结点上,显然字使用频率越小权值越小,权值越小叶子就越靠下,于是频率小编码长,频率高编码短,这样就保证了此树的最小带权路径长度效果上就是传送报文的最短长度。利用哈夫曼树来设计二进制的前缀编码,既满足前缀编码的条件,又保证报文编码总长最短。

        2. 哈夫曼译码:在通信中,若将字符用哈夫曼编码形式发送出去,对方接收到编码后,将编码还原成字符的过程,称为哈夫曼译码。

B+树

                 定义:由“顶点”和“边”所组成的集合

                 分类

                         无向图

                         有向图

                 图的表示法

                         邻接矩阵法

                         邻接表法

                         邻接复合链表法

                         索引表格法

                 图的遍历

                         深度优先遍历

                         广度优先遍历

                 应用场景:最短路径搜索、拓扑排序

其它

                 散列表(Hash),堆(Heap)

数组:

        数组相同数据类型的数据按顺序组成的一种引用数据类型。

        声明数组仅仅给出了元素的数据类型和数组名字,要使用数组就必须为它分配内存空间,即实例化数组。当实例化一个数组时就申请了一段连续的内存空间存储数组中的元素。

        数组中的数据是通过数组名和数组下标来操作数据的,下标从0开始下标的专业叫法:索引

用于存储同一类型数据的一个容器。

数组的常见概念

        数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括 基本数据类型和引用。

  1. 创建数组对象会在内存中开辟一整块连续的空间 ,而数组名中引用的是这块连续空间的首地址 。
  2. 数组长度一旦确定 ,就不能修改 。
  3. 我们可以直接通过下标 (或索引 )的方式调用指定位置元素 ,速度很快 。
  4. 数组的分类:

        按照维度:一维数组、二维数组、三维数组、…

        按照元素的数据类型分:基本引用数据类型元素的组 (即对 象数组 )

好处:

        可以对该容器中的数据进行编号,从0开始。数组用于封装数据,就是一个具体的实体。

        穷举法只能用于初始化数组,即必须和声明数组代码放在一条语句中完成。

核心思想:就是对角标的操作

        如何在java中表现一个数组呢?两种表现形式。

        元素类型[] 变量名 = new 元素类型[元素的个数];

        元素类型[] 变量名 = {元素1,元素2...};

        元素类型[] 变量名 = new 元素类型[]{元素1,元素2...};

格式:数组名[索引]

        数组的长度属性: 每个数组都具有长度,而且是固定的,Java中赋予了数组的一个属性,可以获取到数组的长度,语句为: 数组名.length ,属性length的执行结果是数组的长度,int类型结果。由次可以推断出,数组的最大索引值为 数组名.length-1 。

public static void main(String[] args) {

   int[] arr = new int[]{1,2,3,4,5};

   //打印数组的属性,输出结果是5

   System.out.println(arr.length);

}

数组的访问

        索引: 每一个存储到数组的元素,都会自动的拥有一个编号,从0开始,这个自动编号称为数组索引(index),可以通过数组的索引访问到数组中的元素。

索引访问数组中的元素:

数组名[索引]=数值,为数组中的元素赋值

变量=数组名[索引],获取出数组中的元素

public static void main(String[] args) {
   //定义存储int类型数组,赋值元素1,2,3,4,5
   int[] arr = {1,2,3,4,5};

   //为0索引元素赋值为6
   arr[0] = 6;

   //获取数组0索引上的元素
   int i = arr[0];

   System.out.println(i);
   //直接输出数组0索引元素
   System.out.println(arr[0]);
}

一维数组

一维数组的声明方式 :

type var [] 或 type[] var ;
例如:
int inta[] ;
int int[] a1;
double b[];
String [] c;// 引用类型变量数组
Java 语言中声明数组时不能指定其长度(数组中元素的),例如: int inta[5 ]; // 非法

动态初始化 :数组声明且为元素分配空间与赋值的操作 分开进行

int[] arr= new int[3];
arr[0] = 3;
arr[1] = 9;
arr[2] = 8;

静态初始化 :在定义数组的同时就为元素分配空间并赋值。

        int arr[] = new int[]{ 3, 9, 8}; 或 int[] arr = {3,9,8};

一维数组的使用

数组元素的引用

        定义并用运算符new为之分配空间后,才可以引用数组中的每个元素;数组元素的引用方式:数组名[数组元素下标]

  1. 数组元素下标可以是整型常量或整型表达式。如a[3] , b[i] , c[6*i];
  2. 数组元素下标从0开始;长度为n的数组合法下标取值范围: 0 —>n-1inta[]=new int[3];  可引用的数组元素为a[0]a[1]a[2]

每个数组都有一个属性length指明它的长度,例如:a.length指明数组a的长度(元素个数)

  1. 数组一旦初始化,其长度是不可变的
数组元素的默认初始化值

        数组是引用类型,它的元素相当于类的成员变量,因此数组一经分配空间,其中的每个元素也被按照成员变量同样的方式被隐式初始化。例如:

Public class Test{
    Public static void main(String argv []){
        Int a[]=new int[5];
        System.out.println(a[3]);//a[3]的默认值为0
    }
}

对于基本数据类型而言,默认初始化值各有不同

对于引用数据类型而言,默认初始化值为null(注意与0不同!)

数组元素类型

元素默认初始值

byte

0

short

0

int

0

long

0L

float

0.0F

double

0.0

char

0 或写为:’\u0000’(表现为空)

boolean

false

引用类型

null

多维数组的使用

  1. Java 语言里提供了支持多维数组的语法。
  2. 如果说可以把一维数组当成几何中的线性图形,那么二维数组就相当于是一个表格,像右图Excel中的表格一样。
  3. 对于二维数组的理解,我们可以看成是一维数组array1又作为另一个一维数组array2的元素而存在。其实,从数组底层的运行机制来看,其实没有多维数组。

二维数组[ ][ ]:数组中的数组

格式1(动态初始化)int[ ][ ] arr= new int[3][2];

定义了名称为arr的二维数组

二维数组中有3个一维数组

每一个一维数组中有2个元素

一维数组的名称分别为arr[0], arr[1], arr[2]

给第一个一维数组1脚标位赋值为78写法是:arr[0][1] = 78;

格式2(动态初始化)int[ ][ ] arr= new int[3][ ];

二维数组中有3个一维数组。

每个一维数组都是默认初始化值null (注意:区别于格式1

可以对这个三个一维数组分别进行初始化

arr[0] = new int[3];    arr[1] = new int[1];   arr[2] = new int[2];

注:

int[ ][ ]arr= new int[ ][3];  //非法

格式3(静态初始化):int[][]arr=new int[][]{{3,8,2},{2,7},{9,0,1,6}};

定义一个名称为arr的二维数组,二维数组中有三个一维数组

每一个一维数组中具体元素也都已初始化

第一个一维数组arr[0] = {3,8,2};

第二个一维数组arr[1] = {2,7};

第三个一维数组arr[2] = {9,0,1,6};

第三个一维数组的长度表示方式:arr[2].length;

注意特殊写法情况:int[] x,y[]; x是一维数组,y是二维数组。

Java中多维数组不必都是规则矩阵形式

数组原理内存图

内存概述

        内存是计算机中的重要原件,临时存储区域,作用是运行程序。我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,运行完毕后会清空内存。Java虚拟机要运行程序,必须要对内存进行空间的分配和管理

Java虚拟机的内存划分

        为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。垃圾回收机制。

区域名称

作用

寄存器

给CPU使用,和我们开发无关。

本地方法栈

JVM在使用操作系统功能的时候使用,和我们开发无关。

方法区

存储可以运行的class文件。

堆内存

存储对象或者数组,new来创建的,都存储在堆内存。用于存储数组和对象,也就是实体。啥是实体啊?就是用于封装多个数据的。

1每一个实体都有内存首地址值。

2堆内存中的变量都有默认初始化值。因为数据类型不同,值也不一样。

方法栈

方法运行时使用的内存,比如main方法运行,进入方法栈中执行。存储的都是局部变量 ( 方法中定义的变量,方法上的参数,语句中的变量 );只要数据运算完成所在的区域结束,该数据就会被释放

数组在内存中的存储

一个数组内存图

public static void main(String[] args) {
    int[] arr = new int[3];
    System.out.println(arr);//[I@5f150435
}

        以上方法执行,输出的结果是[I@5f150435,这个是什么呢?是数组在内存中的地址。new出来的内容,都是在堆内存中存储的,而方法中的变量arr保存的是数组的地址arr[0],就会输出arr保存的内存地址中,数组中0索引上的元素

两个数组内存图

public static void main(String[] args) {
   int[] arr = new int[3];
   int[] arr2 = new int[2];
   System.out.println(arr);
   System.out.println(arr2);
}

两个变量指向一个数组

public static void main(String[] args) {
    // 定义数组,存储3个元素
    int[] arr = new int[3];
    //数组索引进行赋值
    arr[0] = 5;
    arr[1] = 6;
    arr[2] = 7;

    //输出3个索引上的元素值
    System.out.println(arr[0]);
    System.out.println(arr[1]);
    System.out.println(arr[2]);

    //定义数组变量arr2,将arr的地址赋值给arr2
    int[] arr2 = arr;
    arr2[1] = 9;
    System.out.println(arr[1]);
}

数组中常见的两个异常:

ArrayIndexOutOfBoundsException://当访问到数组中不存在的角标时,就会发生该异常。

NullPointerException//当引用型变量没有任何实体指向时,还在用其操作实体。就会发生该异常

//二分查找法。必须有前提:数组中的元素要有序。    

 public static int halfSeach_2(int[] arr,int key){
        int min, max, mid;
        min = 0;
        max = arr.length-1;
        mid = (max+min)>>1; //(max+min)/2;
        while(arr[mid]!=key){
           if( key > arr[mid] ){
               min = mid + 1;
           } else if ( key < arr[mid] ){
               max = mid - 1;
           }

           if( max < min ){
              return -1;
           }
           mid = (max+min)>>1;
        }
        return mid;
    }

Arrays工具类的使用

1

Boolean equals(int[] a,int[] b)

判断两个数组是否相等。

2

String toString(int[] a)

输出数组信息。

3

Void fill(int[] a,int val)

将指定值填充到数组之中。

4

Void sort(int[] a)

对数组进行排序。

5

Int binarySearch(int[] a,int key)

对排序后的数组进行二分法检索指定的值。

数组中涉及的常见算法

        1. 数组元素的赋值(杨辉三角、回形数等)

        2. 求数值型数组中元素的最大值、最小值、平均数、总和等

        3. 数组的复制、反转、查找(线性查找、二分法查找)

        4. 数组元素的排序算法

插入排序

冒泡排序:

快速排序:

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

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

相关文章

CQI-17:2021 V2 英文 、中文版。特殊过程:电子组装制造-锡焊系统评审标准

锡焊作为一个特殊的工艺过程&#xff0c;由于其材料特性的差异性、工艺参数的复杂性和过程控制的不确定性&#xff0c;长期以来一直视为汽车零部件制造业的薄弱环节&#xff0c;并将很大程度上直接导致整车产品质量的下降和召回风险的上升。 美国汽车工业行动集团AIAG的特别工…

154 Linux C++ 通讯架构实战9 ,信号功能添加,信号使用sa_sigaction 回调,子进程添加,文件IO详谈,守护进程添加

初始化信号 使用neg_init_signals(); 在nginx.cxx中的位置如下 //(3)一些必须事先准备好的资源&#xff0c;先初始化ngx_log_init(); //日志初始化(创建/打开日志文件)&#xff0c;这个需要配置项&#xff0c;所以必须放配置文件载入的后边&#xff1b;//(4)一些初…

Hello算法8:堆

Hello算法8&#xff1a;堆 定义 堆heap是满足特定条件的完全二叉树(只有最底层节点未填满&#xff0c;且节点靠左填充)&#xff0c;主要有以下两种&#xff1a; 大顶堆&#xff1a;任意节点的值≥其子节点的值 小顶堆&#xff1a;任意节点的值≤子节点的值 堆的常用操作 方…

最小覆盖子串-java

最小覆盖子串-java 题目描述 : 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串&#xff0c;则返回空字符串 "" 。 注意&#xff1a; 对于 t 中重复字符&#xff0c;我们寻找的子字符串中该字符数量必…

阿里云2核4G云服务器支持多少人同时在线?并发数计算?

阿里云2核4G服务器多少钱一年&#xff1f;2核4G配置1个月多少钱&#xff1f;2核4G服务器30元3个月、轻量应用服务器2核4G4M带宽165元一年、企业用户2核4G5M带宽199元一年。可以在阿里云CLUB中心查看 aliyun.club 当前最新2核4G服务器精准报价、优惠券和活动信息。 阿里云官方2…

语音识别:基于HMM

HMM语音识别的解码过程 从麦克风采集的输入音频波形被转换为固定尺寸的一组声学向量&#xff1a; 其中是维的语音特征向量&#xff08;例如MFCC&#xff09;。 解码器尝试去找到上述特征向量序列对应的单词&#xff08;word&#xff09;的序列&#xff1a; 单词序列的长度是。…

HAProxy + Vitess负载均衡

一、环境搭建 Vitess环境搭建&#xff1a; 具体vitess安装不再赘述&#xff0c;主要是需要启动3个vtgate&#xff08;官方推荐vtgate和vtablet数量一致&#xff09; 操作&#xff1a; 在vitess/examples/common/scripts目录中&#xff0c;修改vtgate-up.sh文件&#xff0c;…

计算机网络——32差错检测和纠正

差错检测和纠正 错误检测 EDC 差错检测和纠错位&#xff08;冗余位&#xff09; D 数据由差错检测保护&#xff0c;可以包含头部字段 错误检测不是100%可靠的 协议会泄露一些错误&#xff0c;但是很少更长的EDC字段可以得到更好的检测和纠正效果 奇偶校验 单bit奇偶校验 …

opejdk11 java 启动流程 java main方法怎么被jvm执行

java启动过程 java main方法怎么被jvm执行 java main方法是怎么被jvm调用的 1、jvm main入口 2、执行JLI_Launch方法 3、执行JVMInit方法 4、执行ContinueInNewThread方法 5、执行CallJavaMainInNewThread方法 6、创建线程执行ThreadJavaMain方法 7、执行ThreadJavaMain方法…

YOLOv9改进策略 :主干优化 | ConvNeXtV2:适应自监督学习,让 CNN “再一次强大”?

💡💡💡本文改进内容:完全卷积掩码自编码器框架 ConvNeXt V2,它显著提高了纯convnet在各种识别基准上的性能,包括ImageNet分类,COCO目标检测和ADE20k分割。还提供了各种尺寸的预训练ConvNeXt v2模型,从而在ImageNet上具有76.7%精度的3.7M Atto model和88.9%精度的650…

CrossOver软件2024免费 最新版本详细介绍 CrossOver软件好用吗 Mac电脑玩Windows游戏

CrossOver是一款由CodeWeavers公司开发的软件&#xff0c;它可以在Mac和Linux等操作系统上运行Windows软件&#xff0c;而无需在计算机上安装Windows操作系统。这款软件的核心技术是Wine&#xff0c;它是一种在Linux和macOS等操作系统上运行Windows应用程序的开源软件。 Cross…

本地虚拟机服务器修改站点根目录并使用域名访问的简单示例

说明&#xff1a;本文提及效果是使用vmware虚拟机&#xff0c;镜像文件是Rocky8.6 一、配置文件路径 1. /etc/httpd/conf/httpd.conf #主配置文件 2. /etc/httpd/conf.d/*.conf #调用配置文件 调用配置文件的使用&#xff1a; vim /etc/httpd/conf.d/webpage.conf 因为在主配…

【STM32 HAL库SPI/QSPI协议学习,基于外部Flash读取。】

1、SPI协议 简介 SPI 协议是由摩托罗拉公司提出的通讯协议 (Serial Peripheral Interface)&#xff0c;即串行外围设备接口&#xff0c;是 一种高速全双工的通信总线。它被广泛地使用在 ADC、LCD 等设备与 MCU 间&#xff0c;要求通讯速率 较高的场合。 SPI 物理层 SPI 通讯…

【讲解下Docker in Docker的原理与实践】

&#x1f308;个人主页:程序员不想敲代码啊&#x1f308; &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家&#x1f3c6; &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提…

elementUI this.$msgbox msgBox自定义 样式自定义 富文本

看这个效果是不是很炫?突出重点提示内容,对于用户交互相当的棒! 下来说说具体实现: let self = this const h = self.$createElement; this.$msgbox({title: null,message: h("p", {style: "margin-top:10px"}, [h("i", {class: "el-i…

Linux——将云服务器作为跳板机,frp实现内网穿透

文章目录 操作步骤1. 准备工作&#xff1a;2. 配置frp服务器端&#xff1a;3. 配置frp客户端&#xff1a;4. 启动frp客户端&#xff1a;5. 测试连接&#xff1a;6. 安全注意事项&#xff1a; 云服务器性能分析阿里云具体操作步骤1. 购买&#xff1a;2. 登录&#xff1a;3. 首次…

Redis 慢日志

Redis慢日志 1.Redis 慢查询日志概述 客户端从发送命令到获取返回结果经过了以下几个步骤&#xff1a; 客户端发送命令该命令进入 Redis 队列排队等待执行Redis 开始执行命令 - Redis 命令执行完成命令执行结果返回给客户端 Redis 慢查询日志统计的时间&#xff0c;只包含第…

Docker 哲学 - compose.yaml 指令

compose.yaml 的 image commond working_dir 和 dockerfile的 from cmd workdir 区别在哪里 。为什么 dockerfile制定过了。compose还要再写一个。是处于个性化还是 有不同的意义 如果 dockerfile 的 from 是 node:16 &#xff0c;compose.yaml 的 images 是 node:18 那么 直接…

杰发科技——Jlink插件使用

0. 简介 杰发自带的烧录工具是ATCLink&#xff0c;基于DapLink适配。个人不太喜欢ATCLink&#xff0c;推荐使用Jlink&#xff0c;毕竟自己买&#xff0c;不用问原厂要&#xff0c;而且带Jlink&#xff0c;至少5Mhz以上。 V9烧录器使用7.50以下版本驱动。 V11烧录器可以使用7…

生信数据分析——GO+KEGG富集分析

生信数据分析——GOKEGG富集分析 目录 生信数据分析——GOKEGG富集分析1. 富集分析基础知识2. GO富集分析&#xff08;Rstudio&#xff09;3. KEGG富集分析&#xff08;Rstudio&#xff09; 1. 富集分析基础知识 1.1 为什么要做功能富集分析&#xff1f; 转录组学数据得到的基…