面试(02)————Java基础和集合

news2025/2/27 12:39:42

一、Java基础知识

1、面向对象的特征

 2、Java 的基本数据类型有哪些

3、JDK JRE JVM 的区别

4、重载和重写的区别

5、Java中==和equals的区别 

6 、String、StringBuffer、StringBuilder三者之间的区别

7、接口和抽象类的区别是什么?

8、反射

 9、jdk1.8 的新特性(高薪常问)

9.1、Lambda 表达式

 9.2、方法引用

9.3、函数式接口

 9.4、接口允许定义默认方法和静态方法

 9.5、Stream API

 9.6、日期/时间类改进

9.7、Optional 类  

9.8、Java8 Base64 实现

10、Java 的异常

 11、BIO、NIO、AIO 有什么区别?(高薪常问)

 12、Threadloal 的原理(高薪常问)

13、同步锁、死锁、乐观锁、悲观锁 (高薪常问) 

14、说一下 synchronized 底层实现原理?(高薪常问) 

 15、synchronized 和 volatile 的区别是什么?(高薪常问)

 16、synchronized 和 Lock 有什么区别? (高薪常问)

 二、集合

1、常见的数据结构

2、集合和数组的区别 

 3、List 和 Map、Set 的区别

4、 List 和 Map、Set 的实现类 

4.1、Connection 接口

4.2、Map 接口有四个实现类 

5、Hashmap 的底层原理 

6、Hashmap 和 hashtable ConcurrentHashMap 区别 


 

一、Java基础知识

1、面向对象的特征

面向对象的特征:封装、继承、多态、抽象。
封装:封装是将数据和操作(方法)捆绑在一起的机制,使得对象的内部细节对外部是隐藏的,外部只能通过对象的公共接口来访问和操作对象。封装提供了信息隐藏和保护数据的功能,使得对象的使用更加简单和安全。
继承:继承是一种机制,允许一个类(子类)继承另一个类(父类)的属性和方法。子类可以重用父类的代码,并且可以在此基础上扩展或修改功能。通过继承,可以实现代码的重用性和扩展性,减少代码的重复编写。
多态:多态是指相同的操作或方法在不同的对象上可以有不同的行为。在面向对象编程中,多态可以通过继承和方法重写来实现。多态提高了代码的灵活性和可扩展性,使得程序可以根据实际情况选择合适的行为。
抽象:抽象是指将复杂的现实世界映射到程序设计中的简化模型,只关注对象的重要特征和行为,忽略不必要的细节。抽象可以通过类和接口来实现,在面向对象编程中,通过抽象可以隐藏对象的复杂性,提高程序的可理解性和可维护性。

 2、Java 的基本数据类型有哪些

91373c13562f40f7bef0573924cf1695.png

3、JDK JRE JVM 的区别

5f04e0755ceb42b48e3ee2140f803cc9.png

JDK(Java Development Kit)是整个Java 的核心,是java开发工具包,包括了Java 运行环境JRE、Java 工具和Java 基础类库。
 
JRE(Java Runtime Environment)是运行JAVA 程序所必须的环境的集合,包含java虚拟机和java程序的一些核心类库。
 
JVM 是Java Virtual Machine(Java 虚拟机)的缩写,是整个java 实现跨平台的最核心的部分,能够运行以Java 语言写作的软件程序。

4、重载和重写的区别

 重载:发生在同一个类中,方法名必须相同,参数类型不同.个数不同.顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。

 

重写:发生在父子类中,方法名.参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为private则子类就不能重写该方法。

5、Java中==和equals的区别 

== 的作用:
        
基本数据类型,== 比较的是值是否相等

        引用类型(对象),== 比较的是引用地址是否相同

equals 的作用 :
        引用类型:默认情况下,比较的是地址值。
        特:String、Integer、Date这些类库中equals被重写,比较的是内容而不是地址!



请解释字符串比较之中“ == ”和equals() 的区别?
答:==:比较的是两个字符串内存地址(堆内存)的数值是否相等,属于数值比较;                   equals():比较的是两个字符串的内容,属于内容比较。

6 、String、StringBuffer、StringBuilder三者之间的区别

 String 字符串常量
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)


String 中的String 类中使用final 关键字修饰字符数组来保存字符串,private final char value[] ,String对象是不可变的,也就可以理解为常量,线程安全。

AbstractStringBuilder 是StringBuilder 与StringBuffer 的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf 等公共方法。
StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。

StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。

总结:

(1)如果要操作少量的数据用String;
(2)多线程操作字符串缓冲区下操作大量数据用StringBuffer;
(3)单线程操作字符串缓冲区下操作大量数据用StringBuilder。

7、接口和抽象类的区别是什么?

实现:抽象类的子类使用extends 来继承;接口必须使用implements 来实现接口。

构造函数:抽象类可以有构造函数;接口不能有。
main 方法:抽象类可以有 main 方法,并且我们能运行它;接口不能有 main 方法。
实现数量:类可以实现很多个接口;但是只能继承一个抽象类。
访问修饰符:接口中的方法默认使用 public 修饰;抽象类中的方法可以是任意访问修饰符

8、反射

在 Java 中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和
方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息 以及动
态调用对象方法的功能成为 Java 语言的反射机制。
获取 Class 对象的 3 种方法 :
调用某个对象的 getClass()方法
Person p=new Person();
Class clazz=p.getClass();
调用某个类的 class 属性来获取该类对应的 Class 对象
Class clazz=Person.class;
使用 Class 类中的 forName()静态方法(最安全/性能最好)
Class clazz=Class.forName("类的全路径"); (最常用)

 9、jdk1.8 的新特性(高薪常问)

9.1、Lambda 表达式

Lambda 允许把函数作为一个方法的参数。

d722e8baf4884c07978f01742b02fa84.png

 9.2、方法引用

方法引用允许直接引用已有 Java 类或对象的方法或构造方法
7729c1fdf2df4d0a9ebbf69ea2f745b4.png

上例中我们将 System.out::println 方法作为静态方法来引用。  

9.3、函数式接口

有且仅有一个抽象方法的接口叫做函数式接口,函数式接口可以被隐式转换为 Lambda 表
达式。通常函数式接口上会添加@FunctionalInterface 注解。

 9.4、接口允许定义默认方法和静态方法

 从 JDK8 开始,允许接口中存在一个或多个默认非抽象方法和静态方法

 9.5、Stream API

新添加的 Stream API(java.util.stream)把真正的函数式编程风格引入到 Java 中。这种
风格将要处理的元素集合看作一种流,流在管道中传输,并且可以在管道的节点上进行处理, 比如筛选,排序,聚合等。
f726b1677cfa4ca69d0bdf9922578489.png

 9.6、日期/时间类改进

之前的 JDK 自带的日期处理类非常不方便,我们处理的时候经常是使用的第三方工具包,
比如 commons-lang 包等。不过 JDK8 出现之后这个改观了很多,比如日期时间的创建、
比较、调整、格式化、时间间隔等。
这些类都在 java.time 包下,LocalDate/LocalTime/LocalDateTime

9.7、Optional 类  

Optional 类是一个可以为 null 的容器对象。如果值存在则 isPresent()方法会返回 true,
调用 get()方法会返回该对象。
d5d4d4e71f524317888020b6715484f8.png
762465e7dc0b45e6aa5b3c9a39f69a0b.png

9.8、Java8 Base64 实现

Java 8 内置了 Base64 编码的编码器和解码器。 

10、Java 的异常

6733c141da9640a48af9e4f1e654a6be.png

Throwable 是所有 Java 程序中错误处理的父类,有两种资类:Error 和 Exception。
Error:表示由 JVM 所侦测到的无法预期的错误,由于这是属于 JVM 层次的严重错误,导
致 JVM 无法继续执行,因此,这是不可捕捉到的,无法采取任何恢复的操作,顶多只能显
示错误信息。
Exception:表示可恢复的例外,这是可捕捉到的。
1.运行时异常:都是 RuntimeException 类及其子类异常,如 NullPointerException(空指
针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序
中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从
逻辑角度尽可能避免这类异常的发生。运行时异常的特点是 Java 编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用 try-catch 语句捕获它,也没有用 throws
子句声明抛出它,也会编译通过。
2.非运行时异常(编译异常)
:是 RuntimeException 以外的异常,类型上都属于 Exception
类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。
如 IOException、SQLException 等以及用户自定义的 Exception 异常,一般情况下不自定
义检查异常。
常见的 RunTime 异常几种如下
NullPointerException - 空指针引用异常
ClassCastException - 类型强制转换异常。
IllegalArgumentException - 传递非法参数异常。
ArithmeticException - 算术运算异常
ArrayStoreException - 向数组中存放与声明类型不兼容对象异常
IndexOutOfBoundsException - 下标越界异常
NegativeArraySizeException - 创建一个大小为负数的数组错误异常
NumberFormatException - 数字格式异常
SecurityException - 安全异常
UnsupportedOperationException - 不支持的操作异常

 11、BIO、NIO、AIO 有什么区别?(高薪常问)

BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用
方便,并发处理能力低。
 
NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通
道)通讯,实现了多路复用。
 
AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO
的操作基于事件和回调机制。

 12、Threadloal 的原理(高薪常问)

 

ThreadLocal:为共享变量在每个线程中创建一个副本,每个线程都可以访问自己内部的副
本变量。通过 threadlocal 保证线程的安全性。
 
其实在 ThreadLocal 类中有一个静态内部类 ThreadLocalMap(其类似于 Map),用键值对
的形式存储每一个线程的变量副本,ThreadLocalMap 中元素的 key 为当前 ThreadLocal
对象,而 value 对应线程的变量副本。
 
ThreadLocal 本身并不存储值,它只是作为一个 key 保存到 ThreadLocalMap 中,但是
这里要注意的是它作为一个 key 用的是弱引用,因为没有强引用链, 弱引用在 GC 的时候可
能会被回收。这样就会在 ThreadLocalMap 中存在一些 key 为 null 的键值对(Entry)。因
为 key 变成 null 了,我们是没法访问这些 Entry 的,但是这些 Entry 本身是不会被清除的。
如果没有手动删除对应 key 就会导致这块内存即不会回收也无法访问,也就是 内存泄漏。使用完 ThreadLocal 之后,记得调用 remove 方法。 在不使用线程池的前提下,即使不调
用 remove 方法,线程的"变量副本"也会被 gc 回收,即不会造成内存泄漏的情况。

13、同步锁、死锁、乐观锁、悲观锁 (高薪常问) 

同步锁:
当多个线程同时访问同一个数据时,很容易出现问题。为了避免这种情况出现,我们要
保证线程同步互斥,就是指并发执行的多个线程,在同一时间内只允许一个线程访问共享数
据。Java 中可以使用 synchronized 关键字来取得一个对象的同步锁。
死锁:
何为死锁,就是多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。
乐观锁:
总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是
在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和
CAS 算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类
似于 write_conditio 机制,其实都是提供的乐观锁。在 Java 中 java.util.concurrent.atomic
包下面的原子变量类就是使用了乐观锁的一种实现方式 CAS 实现的。
悲观锁:
总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时
候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使
用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了
很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java 中
synchronized 和 ReentrantLock 等独占锁就是悲观锁思想的实现

14、说一下 synchronized 底层实现原理?(高薪常问) 

1、syn 锁住的是对象,对象里边的组成如下:
Java 的对象布局
必须是要求对象的大小必须是 8 的整数倍
  • 首先是有一个 object header
  • 填充数据 :当对象大小不足 8 的倍数的时候,他会把当前对象填充成 8 的 倍数,假如他现在本身就是 8 的 byte 的倍数,此时填充数据就不用了
  • 成员变量 :就是咱们成员变量2)锁升级
(1) 偏向锁
线程要尝试去加锁,他会去判断当前这个 mark-word 里边是否包含线程 id,如果没有线程
id 的话,他会去利用 cas 把自己的线程 id 写入到 mark-word 里边去第二次这个线程再次
过来的时候,他会去判断当前这个 mark-word 里边是否包含线程 id,如果有了的话,他就
会把他自己的线程 id 和对象头里边的线程 id 进行对比,如果发现是一样的此时就标识获得
到了锁
如果你在没加锁的情况打印对象头:他默认就是 无锁可偏向,如果你没加锁的情况计算了
hashCode 码,无锁不可偏向,
如果此时你加锁无法成为偏向锁,直接膨胀成一把轻量级锁
(2)轻量级锁
  • 升级成轻量级锁三个条件
                你现在已经是无锁不可偏向,此时加锁那么他就直接是一把轻量级锁
                没有关闭延迟偏向锁打开,他会自动成为轻量级锁
                如果程序出现交替执行,他也会成为一把轻量级锁
  • 原理
首先方法压栈,此时这个方法栈帧就压栈,栈帧种就创建两个和锁有关系的空间
displace hrd ,owner
他会将锁里边的 mark-word 里边信息拷贝到 hrd 种
他会用栈帧 owner 指针去指向我们的对象头
对象头中轻量级指针会指向当前创建出来的这个栈帧 锁会把当前的状态修改成 00
如果说完成了以上 4 件事情,那么此时才表示加锁成功,这把锁就是属于当前线程
(3) 重量级锁      原理
  • Java 如果发现要创建一把重量级锁,我们 Java 就会为我们创建一个 C++的 ObjectMonitor,会让对象头中 monitor 指向我们这个 ObjectMonitor 对象如果你进入到 锁内部时,这个 ObjectMonitor 他会 发起汇编指定 monitorenter,当你出 syn 代码代码 块的时候,他会发出 monitorexit 指令如果你在执行 syn 过程中出现了异常,其实上他还 是会执行 monitorexit 这样一个指令
  • 对象头里边 monitor 指针会指向 ObjectMonitor 对象,当多个线程来加锁的 时候他,他们就会执行 monitorenter 指令,进入到 ObjectMonitor 进入到 entrylist 中 等待抢锁,他们会利用 cas 来进行抢锁,如果抢锁成功,ObjectMonitor,他会把他内部 的 owner 的指针去指向咱们抢锁成功 线程,然后会让计数器+1,如果此时是抢锁的线程 是持有锁的线程,那么此时 count 就会再+1 ,释放锁的时候,把 count 进行--,直到 count== 0 的时候就把 owner 置为 null,如果你对线程调用 wait 方法,此时这些被 wait 的线程他就会进入到 waitSet 中,只有当你去调用 notifyall 方法的时候他才会从新开始这 样一套流程
  • 如果是同步方法,那么他执行的 指令 acc_synchronized ,但是这哥们是隐式 调用

 15、synchronized 和 volatile 的区别是什么?(高薪常问)

volatile 本质是在告诉 jvm 当前变量在寄存器(工作内存)中的值是不确定的,需要从
主存中读取; synchronized 则是锁定当前变量,只有当前线程可以访问该变量,其他线
程被阻塞住。
volatile 仅能使用在变量级别;synchronized 则可以使用在变量、方法、和类级别的。
volatile 仅能实现变量的修改可见性,不能保证原子性;而 synchronized 则可以保证
变量的修改可见性和原子性。
volatile 不会造成线程的阻塞;synchronized 可能会造成线程的阻塞。
volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化。

 16、synchronized 和 Lock 有什么区别? (高薪常问)

首先 synchronized 是 java 内置关键字,在 javjvm 层面,Lock 是个a 类;
synchronized 无法判断是否获取锁的状态,Lock 可以判断是否获取到锁;
synchronized 会自动释放锁(a 线程执行完同步代码会释放锁;b 线程执行过程中发生
异常会释放锁),Lock 需在 finally 中手工释放锁(unlock()方法释放锁),否则容易造成线
程死锁;
用 synchronized 关键字的两个线程 1 和线程 2,如果当前线程 1 获得锁,线程 2 线程
等待。如果线程 1 阻塞,线程 2 则会一直等待下去,而 Lock 锁就不一定会等待下去,如果
尝试获取不到锁,线程可以不用一直等待就结束了;
synchronized 的锁可重入、不可中断、非公平,而 Lock 锁可重入、可判断、可公平
(两者皆可);
Lock 锁适合大量同步的代码的同步问题,synchronized 锁适合代码少量的同步问题。

 二、集合

1、常见的数据结构

 

数组是最常用的数据结构,数组的特点是长度固定,数组的大小固定后就无法扩容了 ,
数组只能存储一种类型的数据 ,添加,删除的操作慢,因为要移动其他的元素。
是一种基于先进后出(FILO)的数据结构,是一种只能在一端进行插入和删除操作
的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在
栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。
队列是一种基于先进先出(FIFO)的数据结构,是一种只能在一端进行插入,在另一
端进行删除操作的特殊线性表,它按照先进先出的原则存储数据,先进入的数据,在读取数
据时先被读取出来。
链表是一种物理存储单元上非连续、非顺序的存储结构,其物理结构不能只表示数据元
素的逻辑顺序,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列的
结节(链表中的每一个元素称为结点)组成,结点可以在运行时动态生成。根据指针的指向,
链表能形成不同的结构,例如单链表,双向链表,循环链表等。
是我们计算机中非常重要的一种数据结构,同时使用树这种数据结构,可以描述现实
生活中的很多事物,例如家谱、单位的组织架构等等。有二叉树、平衡树、红黑树、B 树、
B+树。
散列表,也叫哈希表,是根据关键码和值 (key 和 value) 直接进行访问的数据结构,
通过 key 和 value 来映射到集合中的一个位置,这样就可以很快找到集合中的对应元素。
是计算机学科中一类特殊的数据结构的统称,堆通常可以被看作是一棵完全二叉树的
数组对象。
的定义:图是由一组顶点和一组能够将两个顶点相连的边组成的

2、集合和数组的区别 

区别:数组长度固定 集合长度可变 数组中存储的是同一种数据类型的元素,可以存储基本数据类型,也可以存储引用数据
类型;
集合存储的都是对象,而且对象的数据类型可以不一致。在开发当中一般当对象较多的
时候,使用集合来存储对象。

 3、List 和 Map、Set 的区别

List 和 Set 是存储单列数据的集合,Map 是存储键值对这样的双列数据的集合;
List 中存储的数据是有顺序的,并且值允许重复;
Map 中存储的数据是无序的,它的键是不允许重复的,但是值是允许重复的;
Set 中存储的数据是无顺序的,并且不允许重复,但元素在集合中的位置是由元素的
hashcode 决定,即位置是固定的(Set 集合是根据 hashcode 来进行数据存储的,所以位
置是固定的,但是这个位置不是用户可以控制的,所以对于用户来说 set 中的元素还是无序
的)。

4、 List 和 Map、Set 的实现类 

7671497ab68a402192b2eb758f4e71e9.png

4.1、Connection 接口

List 有序,可重复
ArrayList
优点: 底层数据结构是数组,查询快,增删慢。
缺点: 线程不安全,效率高
Vector
优点: 底层数据结构是数组,查询快,增删慢。缺点: 线程安全,效率低, 已给舍弃了
LinkedList
优点: 底层数据结构是链表,查询慢,增删快。
缺点: 线程不安全,效率高
 
Set 无序,唯一
HashSet
底层数据结构是哈希表。(无序,唯一)
如何来保证元素唯一性?
依赖两个方法:hashCode()和 equals()
LinkedHashSet
底层数据结构是链表和哈希表。(FIFO 插入有序,唯一)
a.由链表保证元素有序
b.由哈希表保证元素唯一
TreeSet
底层数据结构是红黑树。(唯一,有序)
a. 如何保证元素排序的呢?
自然排序
比较器排序
b.如何保证元素唯一性的呢?
根据比较的返回值是否是 0 来决定

4.2、Map 接口有四个实现类 

HashMap
基于 hash 表的 Map 接口实现,非线程安全,高效,支持 null 值和 null 键, 线程
不安全。
HashTable
线程安全,低效,不支持 null 值和 null 键;
LinkedHashMap
线程不安全,是 HashMap 的一个子类,保存了记录的插入顺序;
TreeMap
能够把它保存的记录根据键排序,默认是键值的升序排序,线程不安全。

5、Hashmap 的底层原理 

 

HashMap 在 JDK1.8 之前的实现方式 数组+链表,
但是在 JDK1.8 后对 HashMap 进行了底层优化,改为了由 数组+链表或者数值+红黑树
实现,主要的目的是提高查找效率

409f4fe2e7fc4fe9a2997ef489990441.png

8ef63c3b7a0a42ebae1f5cc39c9bd5e4.png

(1)Jdk8 数组+链表或者数组+红黑树实现,当链表中的元素超过了 8 个以后, 会将链
表转换为红黑树,当红黑树节点 小于 等于 6 时又会退化为链表。
(2)当 new HashMap():底层没有创建数组,首次调用 put()方法示时,底层创建长度为
16 的数组,jdk8 底层的数组是:Node[],而非 Entry[],用数组容量大小乘以加载因子得到
一个值,一旦数组中存储的元素个数超过该值就会调用 rehash 方法将数组容量增加到原来
的两倍,专业术语叫做扩容,在做扩容的时候会生成一个新的数组,原来的所有数据需要重
新计算哈希码值重新分配到新的数组,所以扩容的操作非常消耗性能.
默认的负载因子大小为 0.75,数组大小为 16。也就是说,默认情况下,那么当 HashMap
中元素个数超过 16*0.75=12 的时候,就把数组的大小扩展为 2*16=32,即扩大一倍。
(3)在我们 Java 中任何对象都有 hashcode,hash 算法就是通过 hashcode 与自己进行
向右位移 16 的异或运算。这样做是为了计算出来的 hash 值足够随机,足够分散,还有产
生的数组下标足够随机,
map.put(k,v)实现原理
1)首先将 k,v 封装到 Node 对象当中(节点)。
2)先调用 k 的 hashCode()方法得出哈希值,并通过哈希算法转换成数组的下标。
3)下标位置上如果没有任何元素,就把 Node 添加到这个位置上。如果说下标对应的
位置上有链表。此时,就会拿着 k 和链表上每个节点的 k 进行 equal。如果所有的 equals
方法返回都是 false,那么这个新的节点将被添加到链表的末尾。如其中有一个 equals
返回了 true,那么这个节点的 value 将会被覆盖。
map.get(k)实现原理
1)、先调用 k 的 hashCode()方法得出哈希值,并通过哈希算法转换成数组的下标。
2)、在通过数组下标快速定位到某个位置上。重点理解如果这个位置上什么都没有,则返回 null。如果这个位置上有单向链表,那么它就会拿着参数 K 和单向链表上的每一
个节点的 K 进行 equals,如果所有 equals 方法都返回 false,则 get 方法返回 null。
如果其中一个节点的 K 和参数 K 进行 equals 返回 true,那么此时该节点的 value 就
是我们要找的 value 了,get 方法最终返回这个要找的 value。
(4)Hash 冲突
不同的对象算出来的数组下标是相同的这样就会产生 hash 冲突,当单线链表达到一定长度
后效率会非常低。
(5)在链表长度大于 8 的时候,将链表就会变成红黑树,提高查询的效率。

 

6、Hashmap 和 hashtable ConcurrentHashMap 区别 

区别对比一(HashMap 和 HashTable 区别):
(1)HashMap 是非线程安全的,HashTable 是线程安全的。
(2)HashMap 的键和值都允许有 null 值存在,而 HashTable 则不行。
(3)因为线程安全的问题,HashMap 效率比 HashTable 的要高。
(4)Hashtable 是同步的,而 HashMap 不是。因此,HashMap 更适合于单线程
环境,而 Hashtable 适合于多线程环境。一般现在不建议用 HashTable, ①是 HashTable
是遗留类,内部实现很多没优化和冗余。②即使在多线程环境下,现在也有同步的
ConcurrentHashMap 替代,没有必要因为是多线程而用 HashTable。
区别对比二(HashTable 和 ConcurrentHashMap 区别):
HashTable 使用的是 Synchronized 关键字修饰,ConcurrentHashMap 是 JDK1.7
使用了锁分段技术来保证线程安全的。JDK1.8ConcurrentHashMap 取消了 Segment 分
段锁,采用 CAS 和 synchronized 来保证并发安全。数据结构跟 HashMap1.8 的结构类似,
数组+链表/红黑二叉树。
synchronized 只锁定当前链表或红黑二叉树的首节点,这样只要 hash 不冲突,就不
会产生并发,效率又提升 N 倍。

 

 

 

 

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

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

相关文章

行云堡垒国密算法应用与信创支持

一、 国密算法和信创的介绍 1.1 什么是国密算法 国密算法是国家密码管理局制定颁布的一系列的密码标准,即已经被国家密码局认定的国产密码算法,又称商用密码(是指能够实现商用密码算法的加密,解密和认证等功能的技术)…

视频图像的两种表示方式YUV与RGB(4)

本篇主要讲YUV与RGB之间的转换,包括YUV444 颜色编码格式 转为 RGB 格式 ,RGB颜色编码格式转为 YUV444 格式。 一、 YUV与RGB之间的转换 YUV与RGB颜色格式之间进行转换时 , 涉及一系列的数学运算 ; YUV 颜色编码格式转为RGB格式的转换公式 取决于 于 YUV …

个人在线要饭网站源码

源码简介 施舍也要讲究便捷,如果能像购物一样,那也是很美的一件事情; 接入了支付宝当面付系统. 安装环境 php5.6 Nginx 安装教程 1.上传源码压缩包到网站目录并解压即可 2.支付配置 /修改文件 app/config.php /*** 请填写以下配置信…

微服务-4 Nacos

目录 一、注册中心 二、配置管理 1. 添加配置 2. 配置自动刷新 3. 多环境配置共享​编辑 一、注册中心 服务列表: 服务详情: 二、配置管理 1. 添加配置 (1). 在 nacos 界面中添加配置文件: 配置列表: 配置详情:…

东方博宜 1738. 胜负对决

东方博宜 1738. 胜负对决 以为这道题很简单呢,结果提交两次还不对,气死个人~ 思路:这道题的重点在于看清楚题意,是第奇数个,而不是数是奇数 。 还有,如果按照位数的奇偶来判定,那在读取数组的时…

The C programming language (second edition,KR) exercise(CHAPTER 2)

E x c e r c i s e 2 − 1 Excercise\quad 2-1 Excercise2−1&#xff1a;输出结果如图1和图2所示&#xff0c;这道练习题需要文章1和文章2的知识。 #include <stdio.h> #include <limits.h>float getFloat(char sign, unsigned char exp, unsigned mantissa); do…

Windows虚拟主机上多个域名访问同一个网站

近日老板提出了想要多个域名访问同一个网站的想法。这边了解后&#xff0c;由于我们公司使用的是Hostease的Windows虚拟主机产品&#xff0c;因此咨询了Hostease的技术支持&#xff0c;寻求帮助了解到可以实现Windows主机上多个域名访问同一个网站&#xff0c;是需要进入Window…

【洛谷 P8804】[蓝桥杯 2022 国 B] 故障 题解(概率论+条件概率+贝叶斯公式)

[蓝桥杯 2022 国 B] 故障 题目描述 在软件或系统开发中&#xff0c;我们会遇到各种各样的故障。为了从故障现象反推故障原因&#xff0c;工程师们会总结一种叫做相关性矩阵的二维表格&#xff0c;来表示故障原因与故障现象之间的关系。比如: 其中每行表示一种故障原因&#x…

Python学习从0到1 day25 第二阶段 SQL ② Python操作数据库

少年有梦&#xff0c;不应至于心动&#xff0c;更要付诸行动 —— 24.4.11 pymysql 除了使用图形化工具以外&#xff0c;我们也可以使用编程语言来执行SQL从而操作数据库 在Python中&#xff0c;使用第三方库&#xff1a;pymysql来完成对MySQl数据库的操作 安装 pip install py…

微信小程序视频下载工具

推荐您使用"下载高手"微信小程序视频下载工具&#xff0c;它利用占领系统代理&#xff0c;抓取小程序的请求&#xff0c;并集成了下载功能&#xff0c;让您轻松获取所需视频资源。 首先下载我给大家准备好的压缩包 1.首先先退出微信 注意:一定要右下角退出 2.然后来…

Element-UI 下拉框单选转多选回显不清空绑定的值

需求 根据radio切换来更改下拉框是否多选 原因 单选和多选这两个 input 看上去没差别&#xff08;自身和层级都一致&#xff09;&#xff0c;vue出于提高性能&#xff0c;所以 vue 给复用了 解决方案 <template><section><el-radio-group v-model"radi…

【机器学习算法】决策树和随机森林在计算机视觉中的应用

前言 决策树和随机森林在计算机视觉中有着广泛的应用。决策树作为一种简单而强大的分类模型&#xff0c;可以用于图像分类、目标检测、特征提取等任务。它能够根据图像的特征逐层进行判断和分类&#xff0c;从而实现对图像数据的智能分析和理解。随机森林作为一种集成学习方法&…

基于Lipschitz李式指数的随机信号特征识别和故障检测matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 Lipschitz李式指数定义与性质 4.2 Lipschitz李式指数的估计 4.3 Lipschitz李式指数在信号特征识别与故障检测中的应用 5.完整程序 1.程序功能描述 基于Lipschitz李式指数的随机信号特…

docker基本的掌握

前言&#xff1a;先要了解docker是干什么的&#xff0c; 1掌握基本概念&#xff0c;如;镜像&#xff0c;容器&#xff0c;数据卷 2知道使用常用命令 简易图; 补充&#xff1a; 默认情况下&#xff0c;每次重启虚拟机我们都需要手动启动Docker和Docker中的容器。通过命令可以实…

【MATLAB】基于Wi-Fi指纹匹配的室内定位-仿真获取WiFi RSSI数据(附代码)

基于Wi-Fi指纹匹配的室内定位-仿真获取WiFi RSSI数据 WiFi指纹匹配是室内定位最为基础和常见的研究&#xff0c;但是WiFi指纹的采集可以称得上是labor-intensive和time-consuming。现在&#xff0c;给大家分享一下我们课题组之前在做WiFi指纹定位时的基于射线跟踪技术仿真WiFi…

解决 VSCode 编辑器点击【在集成终端中打开】出现新的弹框

1、问题描述 在 VSCode 的项目下&#xff0c;鼠标右键&#xff0c;点击【在集成终端中打开】&#xff0c;出现新的一个弹框。新版的 VSCode 会有这个问题&#xff0c;一般来说我们都希望终端是在 VSCode 的控制台中打开的&#xff0c;那么如何关闭这个弹框呢&#xff1f; 2、解…

Win10安装sqlplus遇到报错的解决办法

1.下载安装sqlplus.exe的错误解决过程 最近有用到sqlplus连接Oracle数据库执行自动化脚本&#xff0c;Orcle服务器版本是11.2.0.1。在Navicat工具上通过如下语句查询到的版本信息截图如图1所示&#xff1a; SELECT * FROM v$version; 图1 Oracle服务器版本信息 其中“Oracle Da…

台灯哪个牌子好,五大护眼灯品牌排行分享

​当前&#xff0c;我国青少年的近视率已超过半数&#xff0c;位居全球之首&#xff0c;且近视发生年龄呈现下降趋势。长时间用眼和过度使用电子产品是导致近视高发的主要因素。面对这一挑战&#xff0c;如何改善现状成为了一个亟待解决的问题。对于儿童而言&#xff0c;降低近…

【C++】模版

目录 一、泛型编程二、函数模板2.1 函数模板概念2.2 函数模板格式2.3 函数模板的原理2.4 函数模板的实例化2.5 模板参数的匹配原则 三、类模板3.1 类模板的定义格式3.2 类模板的实例化 四、非类型模板参数五、模板的特化5.1 概念5.2 函数模板特化5.3 类模板特化5.3.1 全特化5.3…

【火猫TV】欧冠:拉菲尼亚梅开二度,却在出售名单中

欧冠淘汰赛首回合&#xff0c;巴萨在客场3比2击败大巴黎&#xff0c;取得一个球的领先优势&#xff0c;双方将会在下周进行生死战。本场比赛巴萨虽然率先破门&#xff0c;却被大巴黎死死压制&#xff0c;如果不是大巴黎锋线效率一般&#xff0c;球队很可能会在客场输球。本场比…