2021全新java面试题(一篇就够了持续更新)

Java面试整理(一)

1   ArrayList  LinkeList   Vector集合的区别?

ArrayList 是最常用的 List 实现类,内部是通过数组实现的,它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要将已经有数组的数据复制到新的存储空间中。当从 ArrayList 的中间位置插入或者删除元素时,需要对数组进行复制、移动、代价比较高。因此,它适合随机查找和遍历,不适合插入和删除

LinkedList 是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。另外,他还提供了 List 接口中没有定义的方法,专门用于操作表头和表尾元素,可以当作堆栈、队列和双向队列使用。

Vector 与 ArrayList 一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写 Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问 ArrayList 慢。

2  List  Set  Map 接口的特点有哪些?

set 接口中的数序无序唯一

list 接口中的数序有序不唯一

map 接口中的数据使用键值对的方式存储数据

3  接口和抽象类的区别?

(1)接口中的方法都是抽象方法,接口中没有变量都是常量。

(2)抽象类中的方法可以是抽象方法,也可以不是抽象方法。

(3)抽象类中含有构造方法,接口中不能含有构造方法。

(4)抽象类中可以有变量也可以有常量。

(5)一个类只能继承一个抽象类,可以实现多个接口。

4  什么是方法重载?什么是方法重写?

(1) 重载,在同一个类中,方法名相同 参数不同,这些方法称为方法的重载。

(2) 子类重写父类中的方法。要求子类的方法和参数 必须和父类中方法名和参数相同。子类中的方法的访问修饰符不能比父类方法的访问修饰符严格,子类中的方法的返回值可以和父类中的方法的返回值相同,或者是父类方法返回值的子类。

5  HashSet 中的add()方法执行的过程?

(1)  HashSet 在新增数据的时候,先判断内部的数组是否为空,如果数组为空,则初始化数组。

(2)  如果数组不为空,获得向HashSet中添加的元素的哈希码(元素的hashcode方法获得哈希码) 在经过一系列的算法,计算出该元素存储在HashSet数组中的位置。

(3) 在HashSet的数组中查找该位置上是否有元素,如果该位置上没有元素,则此元素就可以放到该位置上。

(4) 如果该位置有元素,则比较新增元素与该位置上的元素的哈希码,如果哈希码不同,在JDK1.8中,新增的元素放在该位置的链表的末尾。

(5) 如果元素的哈希码相同,新增的元素调用equals方法和原来的元素进行比较,如果equals方法的返回值是false,表示两个元素不相等, 如果在JDK1.8中,新增的元素放在该位置的链表的末尾。

(6)如果equals方法的返回值相同,则新增失败。

(HashSet的add方法实际上就是调用的HashMap的put方法)

6  创建线程的两种方式?

方式1: 继承Thread类创建线程子类
    1.在这子类中重写run方法,在run方法内写线程任务代码
    2.创建该子类实例,即是创建了一个线程实例
    3.调用该实例的start方法来启动该线程

方式2: 建一个类去实现Runnable接口
    1.该类去实现接口的run方法,run方法内写线程任务代码
    2.创建该类实例,把该实例当作一个标记target传给Thread类,如:Thread t = new Thread(该类实例);即创建一个线程对象
    3.调用线程的star方法来启用该线程

7  线程的状态有哪些?

        第一是创建(New)状态。在生成线程对象,并没有调用该对象的start方法,这时线程处于创建状态。 
  第二是就绪(Runnable)状态。当调用了线程对象的start方法之后,此时线程调度程序还没有把该线程设置为当前线程,该线程就进入了就绪状态。在线程运行之后,从等待或者睡眠中回来之后,也会处于就绪状态。 
  第三是运行(Running)状态。线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入了运行状态,开始运行run函数当中的代码。 
  第四是阻塞(Blocked)状态。线程正在运行的时候,被暂停,通常是为了等待某个事件的发生(比如说某项资源就绪)之后再继续运行。通常线程调用sleep,wait等方法都可以导致线程进入阻塞。 
  第五是死亡(Terminated)状态。如果一个线程的run方法执行结束或者调用stop方法后,该线程就会死亡。对于已经死亡的线程,无法再使用start方法令其进入就绪。

Java面试整理(二)

1 数据库的隔离级别有哪些?

读未提交 (脏读 不可重复读  幻读)

    当数据库系统使用READ UNCOMMITTED隔离级别时,一个事务在执行过程中可以看到其他事务没有提交的新插入的记录和更新的记录。

读已提交 (不可重复读  幻读)  RC

    当数据库系统使用READ COMMITTED隔离级别时,一个事务在执行过程中能看到其他事务已经提交的对新增和更新的记录。

可重复读 (幻读)   RR

    当数据库系统使用REPEATABLE READ隔离级别时,一个事务在执行过程中不能看到其他事务已经提交的更新的记录,但是可以看到其他事务已经提交的新增的记录。

MYSQL数据库的隔离级别是可重复读。MySQL的数据库不会出现幻读问题。

串行化

    当数据库系统使用SERIALIZABLE隔离级别时,一个事务在执行过程中完全看不到其他事务对数据库所做的更新。当两个事务同时操作数据库中相同数据时,如果第一个事务已经在访问该数据,第二个事务只能停下来等待,必须等到第一个事务结束后才能恢复运行。因此这两个事务实际上是串行化方式运行。

2 每种数据库隔离级别会产生哪些问题?

脏读(Dirty read):

一个事务读取到了另一个事务未提交的数据。

 

不可重复读(Unrepeatableread): 指在一个事务内多次读同一数据。在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。

幻读(Phantom read): 幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。

 

3 hash的概念是什么?如何避免哈希冲突?

hash,是把任意长度的输入通过散列算法变换成固定长度的输出,该输出就是散列值。

如何避免哈希冲突?

(1)链地址法

将所有哈希地址相同的元素构成一个单链表。链地址法适用于经常进行插入和删除的情况。

 

 4 HashMap的数据结构

 HashMap采用数组 + 链表 + 红黑树的方式保存数据。HashMap在查找数据时,根据HashMap的Hash值可以快速定位到数组的具体下标。但是在找到数组下标后需要对链表进行顺序遍历直到找到需要的数据。为了减少链表遍历的开销,Java8对HashMap进行了优化,将数据结构优化为数组+链表+红黑树。当链表中的元素超过8会将此链表转为红黑树结构。

5 InnoDB 引擎的数据库表,如果没有在表上创建主键,这张表上是否有主键。

如果表中没有显式定义主键,则InnoDB会选择第一个不包含有NULL值的唯一索引作为主键索引。如果也没有这样的唯一索引,则InnoDB会选择内置6字节长的ROWID作为隐含的聚集索引 (ROWID随着行记录的写入而主键递增,这个ROWID不像ORACLE的ROWID那样可引用,是隐含的)。

Java面试整理(三)

1事务的特性

原子性(Atomicity)

事务中的所有操作要么全部执行,要么都不执行。如果事务没有原子性的保证,那么在发生系统 故障的情况下,数据库就有可能处于不一致状态。

一致性(Consistency)

主要强调的是,如果在执行事务之前数据库是一致的,那么在执行事务之后数据库也还是一致的。所谓一致性简单地说就是数据库中数据的完整性,包括它们的正确性。

隔离性(Isolation)

即使多个事务并发(同时)执行,每个事务都感觉不到系统中有其他的事务在执行,因而也就能保证数据库的一致性。

持久性(Durability)

事务成功执行后它对数据库的修改是永久的,即使系统出现故障也不受影响。

2 JDK1.8 HashMap添加元素的过程?

1 首先判断数组是否为空或者长度为0,如果是则调用resize()扩容。

2 如果数组不为空,则通过数组长度-1与新增元素的kye的hash值进行位运算,得到数组的下标,通过下标获得该下标对应的数组元素。
3 判断获得的数组元素是否为空, 如果为空则使用新增的键-值 创建节点,将节点放在数组此位置上。
4 如果数组的元素不为空,则判断新增的元素hash值和key值,是否与数组中第一个元素的hash值和key值相等,如果相等则用新的值替换老的值。

5 如果不相等,则判断数组元素是否是红黑树,如果是红黑树,则向红黑树中添加元素。

6 如果不是红黑树,则对链表进行遍历,并且统计链表长度,如果链表中不包含要插入的键值对节点时,则该节点放在链表的最后。如果链表长度大于阀值,则进行树化(将链表转为红黑树)。如果要插入的键值对存在,则用新的值替换老的值。

3 数据库设计的三大范式有哪些?

第一范式(确保每列保持原子性) 第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式。

第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关。就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。

第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关

4 SpringBoot项目如何实现异常处理

1 创建异常处理类,在该类上添加@RestControllerAdvice注解

2 在类中添加异常处理方法,在方法上创建@ExceptionHandler注解,value属性的值是异常的类型在异常处理方法中封装错误信息,返回json格式数据

5 谈谈你对restful的理解

如果一个架构符合Rest原则,该架构就是RESTful架构。

Rest叫作资源表现层状态转移。资源是网络上的一个实体。表现层,把“资源”具体呈现出来的形式。资源的数据的状态变化叫作状态转移。资源的状态转移是通过HTTP动词实现的。HTTP的动词有 PUT   DELETE   GET   POST。

6  Java异常的分类有哪些? 处理异常的关键字有哪些,分别有什么作用?

Java中的异常分为CheckdException和RuntimeException。

处理异常的关键字有try catch finally  throw  throws。

try:指定一块预防所有“异常”的程序。
catch:紧跟在try程序后面,应包含一个catch子句来指定你想要捕捉的“异常”的类型。
throw:用来明确地抛出一个“异常”。
throws:标明一个成员函数可能抛出的各种“异常”。
finally:不管发生什么“异常”都被执行一段代码

7 final, finally, finalize的区别

final 用于声明属性,方法和类, 分别表示属性不可变, 方法不可覆盖, 类不可继承。

finally 是异常处理语句结构的一部分,表示无论是否出现异常总是执行该代码。

finalize 是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等. JVM不保证此方法总被调用.

8  == 与 equals方法的区别

“==”用来比较基本类型的数据,比较的是他们的值。引用数据类型用“==比较的是他的内存地址。

“equals”对于引用数据类型比较的也是它的内存地址。

String(还有Date,Integer)类型重写了equals方法,使其比较的是存储对象的内容是否相等。

                             Java面试整理(四)

1 Nginx 与 Ribbon都能实现负载均衡,他们的区别?

nginx是客户端,所有请求统一交给nginx,由nginx进行实现负载均衡请求转发,属于服务器端负载均衡。请求由nginx服务器端进行转发。

Ribbon是从注册中心服务器端上获取服务注册信息列表,缓存到本地,然后在本地调用远程服务接口。在客户端实现负载均衡。

2 如何实现单点登录

 

a)客户端使用用户名、密码请求登录。

b)服务端收到请求,去验证用户名、密码。

c)验证成功后,认证服务端会签发一个 Token(令牌),再把这个 Token 发送给客户端。

d)客户端收到 Token 以后每次向服务端请求资源的时候需要带着服务端签发的 Token。

e)网关接收到令牌以后,验证令牌是否正确

3 Spring框架中bean对象的生命周期

1 Spring启动,查找并加载需要被Spring管理的bean,进行Bean的实例化

2 Bean实例化后对将Bean的引入和值注入到Bean的属性中

3 如果Bean实现了BeanNameAware接口的话,SpringBeanId传递给setBeanName()方法

4 如果Bean实现了BeanFactoryAware接口的话,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入

5如果Bean实现了ApplicationContextAware接口的话,Spring将调用BeansetApplicationContext()方法,将bean所在应用上下文引用传入进来。

6 如果Bean实现了BeanPostProcessor接口,Spring就将调用他们的postProcessBeforeInitialization()方法。

7 如果Bean 实现了InitializingBean接口,Spring将调用他们的afterPropertiesSet()方法。如果bean使用init-method声明了初始化方法,该方法也会被调用。

8 如果Bean 实现了BeanPostProcessor接口,Spring就将调用他们的postProcessAfterInitialization()方法。

9 此时,Bean已经准备就绪,可以被应用程序使用了。他们将一直驻留在应用上下文中,直到应用上下文被销毁。

10 如果bean实现了DisposableBean接口,Spring将调用它的destory()接口方法,同样,如果bean使用了destory-method 声明销毁方法,该方法也会被调用。

4 Spring 中Bean作用域有哪些

1、singleton:单例,默认作用域。

2、prototype:原型,每次创建一个新对象。

3、request:请求,每次Http请求创建一个新对象,适用于WebApplicationContext环境下。

4、session:会话,同一个会话共享一个实例,不同会话使用不用的实例。

5、global-session:全局会话,所有会话共享一个实例。

5 索引的本质是什么? MySQL数据库中索引的数据结构有哪些?

  1. 索引是帮助MySQL高效获取数据的排好序数据结构。
  2. MySQL中使用B+Tree当作索引的数据结构,也使用Hash结构当作索引的数据结构。

Java面试整理(五)

1 Redis中的基本类型有哪些

string 

list

set 

sortedset

hash

2 Redis过期数据的删除策略

Redis 采用定期删除和惰性删除的方式

定期删除,指的是redis默认是每隔100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。假设redis里放了10万个key,都设置了过期时间,你每隔几百毫秒,就检查10万个key,那redis基本上就死了,cpu负载会很高的,消耗在你的检查过期key上了。注意,这里可不是每隔100ms就遍历所有的设置过期时间的key,那样就是一场性能上的灾难。实际上redis是每隔100ms随机抽取一些key来检查和删除的.

惰性删除。在你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除,不会给你返回任何东西。并不是key到时间就被删除掉,而是你查询这个key的时候,redis再懒惰的检查一下。

3 Redis中的内存淘汰机制

noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。

allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key

allkeys-lfu:  当内存不足以容纳新写入数据时,在键空间中, 移除使用次数最少的key

allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。

volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的。

volatile-lfu:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除使用次数最少的key

volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key

volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除

4 Redis持久化RDB的触发方式有哪些?简述RDB的运行流程?

触发RDB的方式

1. 符合自定义配置的快照规则

2. 执行save或者bgsave命令

3. 执行flushall命令

RDB的运行流程

1 Redis父进程首先判断:当前是否在执行save,或bgsave/bgrewriteaof的子进程,如果在执行则bgsave命令直接返回。

2 父进程执行fork操作创建子进程,这个复制过程中父进程是阻塞的,Redis不能执行来自客户端的任何命令。

3 父进程fork后,bgsave命令返回”Background saving started”信息并不再阻塞父进程,并可以响应其他命令。

4 子进程创建RDB文件,根据父进程内存快照生成临时快照文件,完成后对原有文件进行替换。

5 子进程发送信号给父进程表示完成,父进程更新统计信息。

6 父进程fork子进程后,继续工作。

5 简述AOF的运行流程?简述AOF重写的流程?AOF保存模式?

AOF执行流程:

1 命令传播:Redis 将执行完的命令、命令的参数、命令的参数个数 等信息发送到 AOF 程序中。

2 缓存追加:AOF 程序根据接收到的命令数据,将命令转换为网络通讯协议的格式,然后将协议内容追加到服务

器的AOF 缓存中。

3 文件写入和保存:AOF 缓存中的内容被写入到 AOF 文件末尾,如果设定的 AOF 保存条件被满足的话, fsync 函数或者 fdatasync 函数会被调用,将写入的内容真正地保存到磁盘中。

AOF重写流程:

手动执行bgrewriteaof函数或者符合redis aof重写规则,主进程使用fork函数创建子进程,将redis内存中的数据重写到新的aof文件中。

在aof重写的过程中,如果有新的命令发送给Redis执行,Redis会将新的命令放入到aof缓存区中,满足条件将缓存区的文件写入到aof文件中。

同时新的命令会写入到aof重写缓存区中,在aof重写的时候,会将aof重写缓存区中的内容写到新的aof文件。当重写完成,用新的aof文件替换原来的aof文件。

AOF的保存模式:

always(每次)

每次写入操作均同步到AOF文件中, 数据零误差, 性能较低, 不建议使用。

everysec(每秒)

每秒将缓冲区中的指令同步到AOF文件中,数据准确性较高, 性能较高,建议使用,也是默认配置在系统突然宕机的情况下丢失1秒内的数据

no(系统控制)

由操作系统控制每次同步到AOF文件的周期,整体过程不可控

6 RDB与AOF的对比

rdb 是将redis中的数据进行持久化,存储速度比较慢,恢复速度比较快,rdb方式可以保存某一时刻的数据,但是数据会丢失。资源消耗大。

aof 以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中命令达到恢复数据的目的。存储速度比较快,恢复速度比较慢,如果aof的策略是always,则redis的每个写命令都会保存到aof文件中,数据不会丢失,如果aof的策略是everysec,则每秒将缓冲区中的指令同步到AOF文件中,有可能会丢失1s的数据。资源消耗低

7 Redis事务有哪些关键字,作用是什么?

Redis的事务是通过multi、exec、discard和watch这四个命令来完成的。

作用: Redis将命令集合序列化并确保处于同一事务的命令集合连续且不被打断的执行.

8 什么是缓存穿透?缓存穿透的解决方案有哪些?

一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如 DB)。缓存穿透是指在高并发下查询key不存在的数据,会穿过缓存查询数据库。导致数据库压力过大而宕机。

解决方案: 对查询结果为空的情况也进行缓存,缓存时间(ttl)设置短一点,或者该key对应的数据insert了之后清理缓存。 问题:缓存太多空值占用了更多的空间。

使用布隆过滤器。在缓存之前在加一层布隆过滤器,在查询的时候先去布隆过滤器查询 key 是否存在,如果不存在就直接返回,存在再查缓存和DB。布隆过滤器它实际上是一个很长的二进制向量和一系列随机hash映射函数。 布隆过滤器可以用于检索一个元素是否在一个集合中。

                                 Java面试整理(六)

1 HTTP 响应码有哪些?分别代表什么含义?

200:成功,Web 服务器成功处理了客户端的请求。

301:永久重定向,当客户端请求一个网址的时候,Web 服务器会将当前请求重定向到另一个网址,搜索引擎会抓取重定向后网页的内容并且将旧的网址替换为重定向后的网址。

302:临时重定向,搜索引擎会抓取重定向后网页的内容而保留旧的网址,因为搜索引擎认为重定向后的网址是暂时的。

400:客户端请求错误,多为参数不合法导致 Web 服务器验参失败。

404:未找到,Web 服务器找不到资源。

500:Web 服务器错误,服务器处理客户端请求的时候发生错误。

503:服务不可用,服务器停机。

504:网关超时。

2 Forward 和 Redirect 的区别?

浏览器 URL 地址:Forward 是服务器内部的重定向,服务器内部请求某个 servlet,然后获取响应的内容,浏览器的 URL 地址是不会变化的。

Redirect 是客户端请求服务器,然后服务器给客户端返回了一个 302 状态码和新的 location,客户端重新发起 HTTP 请求,服务器给客户端响应 location 对应的 URL 地址,浏览器的 URL 地址发生了变化。

3 说一下HTTP的长连接与短连接的区别

短连接

在HTTP/1.0中默认使用短链接,也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。如果客户端访问的某个HTML或其他类型的Web资源,如JavaScript文件、图像文件、CSS 文件等。当浏览器每遇到这样一个Web资源,就会建立一个HTTP会话.

长连接

从HTTP/1.1起,默认使用长连接,用以保持连接特性。在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的 TCP连接不会关闭。如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。

                                  Java面试整理(六)

1 什么是熔断机制?什么是限流?

熔断机制是应对雪崩效应的一种微服务链路保护机制。当某个微服务不可用或者响应时间太长时, 会进行服务降级,进而熔断该节点微服务的调用,快速返回“错误”的响应信息。

服务降级,一般是从整体负荷考虑。就是当某个服务熔断之后,服务器将不再被调用,此时客户端 可以自己准备一个本地的fallback回调,返回一个缺省值。

2  Hystrix的状态有哪些?

Closed ->open:正常情况下熔断器为closed状态,当访问同一个接口次数超过设定阈值并且错误比例超过设置错误阈值时候,就会打开熔断机制,这时候熔断器状态从closed->open

Open -> half-open:当服务接口对应的熔断器状态为open状态时候,所有服务调用方调用该服务方法时候都是执行本地降级方法。Hystrix提供了一种测试策略,也就是设置了一个时间窗口,从熔断器状态变为open状态开始的一个时间窗口内,调用该服务接口时候都委托服务降级方法进行执行。如果时间超过了时间窗口,则把熔断状态从open->half-open,这时候服务调用方调用服务接口时候,就可以发起远程调用而不再使用本地降级接口,如果发起远程调用还是失败,则重新设置熔断器状态为open状态,从新记录时间窗口开始时间。

half-open->closed: 当熔断器状态为half-open,这时候服务调用方调用服务接口时候,就可以发起远程调用而不再使用本地降级接口,如果发起远程调用成功,则重新设置熔断器状态为closed状态。

3 Sentinel 熔断降级的方式有哪些

RT

异常比

 异常数

4 Left Join    Inner Join   Right Join的区别 ?

left join:“左连接”,左表连接右表,以左为主,表示以左表为主,关联上右表的数据,查出来的结果显示左边的所有数据,然后右边显示的是和左边有交集部分的数据。

right join:“右连接”,右表连接左表,以右为主,表示以右表为主,关联查询左表的数据,查出右表所有数据以及左表和右表有交集的数据。

joininner join:“内连接”,表示以两个表的交集为主,查出来是两个表有交集的部分,其余没有关联就不额外显示出来。

5 HashMap  HashSet  HashTable的区别?

HashMap和Hashtable都实现了Map接口,HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行)。

Hashtable是线程安全的,多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。

HashSet实际上是一个HashMap实例,都是一个存放链表的数组,它不保证存储元素的迭代顺序,此类允许使用null元素,不允许有重复元素。

一直在更新!!

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值