Java 面试Part1——Java 集合面试真题22道

Java 集合面试真题22道

1. ArrayList 和 Vector 的区别。

ArrayList是异步线程,线程不安全;
Vector支持线程同步,线程安全

2. 说说 ArrayList,Vector, LinkedList 的存储性能和特性。

1)首先,ArrayList 和 Vector 的底层都是采用数组的来存储数据,而且都是根据索引来取数据,这样设计使得获取数据快而插入数据慢。另外,每次扩容都要移动数组中的元素,存储数据量较大的时候会影响读写性能。
2)其次,由于Vector 中的方法都使用了 synchronized 修饰,因此 ,Vector 中对数据操作都是线程安全的,但性能上比ArrayList 差
3)然后,LinkedList 的底层是采用双向链表来存储数据的,也就是说将内存中零散的内存单元通过附加的引用关联起来,形成一个可以按序号索引的线性结构,这种链式存储方式与数组的连续存储方式相比,内存的利用率更高。LinkedList获取数据需要根据索引序号,向前或者向后遍历,但是插入数据时只需要记录本项的前后项即可,所以,LinkedList插入数据的速度更快

谈谈ArrayList、Vector和LinkedList 的存储性能及特性

4. 快速失败 (fail-fast) 和安全失败 (fail-safe) 的区别是什么?

Iterator的安全失败是基于对底层集合做拷贝,因此,它不受源集合上修改的影响。java.util包下面的所有的集合类都是快速失败的,而java.util.concurrent包下面的所有的类都是安全失败的。快速失败的迭代器会抛出ConcurrentModificationException异常,而安全失败的迭代器永远不会抛出这样的异常。
快速失败(fail-fast)和安全失败(fail-safe)的区别

fail-fast 机制,即快速失败机制,是java集合(Collection)中的一种错误检测机制。
当在迭代集合的过程中该集合在结构上发生改变的时候,就有可能会发生fail-fast,即抛出ConcurrentModificationException异常。
java.util包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改)。
解决方法:通过util.concurrent集合包下的相应类去处理,则不会产生fail-fast事件。如使用ArrayList会产生fail-fast,使用CopyOnWriteArrayList则不会。

安全失败(fail-safe)原理:
迭代时是对原集合的拷贝进行遍历,所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,所以不会触发Concurrent Modification Exception。因此缺点就是,迭代器并不能访问到修改后的内容,即:迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间原集合发生的修改迭代器是不知道的。
快速失败和安全失败的对比图
快速失败 (fail-fast) 和安全失败 (fail-safe) 的区别是什么?

5. HashMap 的数据结构。

由数组和链表组合构成的数据结构
在这里插入图片描述

6. HashMap 的工作原理是什么?

数据插入原理

  1. 判断数组是否为空,为空进行初始化;
  2. 不为空,计算 k 的 hash 值,通过(n - 1) & hash计算应当存放在数组中的下标 index;
  3. 查看 table[index] 是否存在数据,没有数据就构造一个Node节点存放在 table[index] 中;
  4. 存在数据,说明发生了hash冲突(存在二个节点key的hash值一样), 继续判断key是否相等,相等,用新的value替换原数据(onlyIfAbsent为false);
  5. 如果不相等,判断当前节点类型是不是树型节点,如果是树型节点,创造树型节点插入红黑树中;(如果当前节点是树型节点证明当前已经是红黑树了)
  6. 如果不是树型节点,创建普通Node加入链表中;判断链表长度是否大于 8并且数组长度大于64, 大于的话链表转换为红黑树;
  7. 插入完成之后判断当前节点数是否大于阈值,如果大于开始扩容为原数组的二倍。

一个HashMap跟面试官扯了半个小时

7. HashMap 什么时候进行扩容呢?如何扩容?
1)什么时候扩容

HashMap的容量是有限的。当经过多次元素插入的时候,使得HashMap达到一定的饱和度,Key映射位置的几率不断变大。这个时候,HashMap就需要扩容了,也就是resize()

HashMap扩容的条件:
1、HashMap中的数据达到阈值。
2、出现hash碰撞的情况。

2)怎么扩容

1)创建一个新的Entry空数组,使用的是2次幂的扩展(长度是原来的2倍)。
2)ReHash:遍历原Entry数组,把所有的Entry重新Hash到新数组。
为什么要重新Hash呢?因为长度扩大以后,Hash的规则也随之改变。
Hash的公式—> index = HashCode(Key) & (Length - 1)
扩容前:
扩容前

扩容后:
扩容后

8. List、Map、Set 三个接口,存取元素时,各有什么特点?

存放时:

1.List以特定的索引(有顺序的存放)来存放元素,可以有重复的元素
2.Set存放元素是无序的,而且不可重复(用对象的equals()方法来区分元素是否重复)
3.Map保存键值对的映射,映射关系可以是一对一(键值)或者多对一,需要注意到的是:键无序不可重复,值可以重复

取出时:

(1)List取出元素for循环,foreach循环,Iterator迭代器迭代
(2)Set取出元素foreach循环,Iterator迭代器迭代
(3)Map取出元素需转换为Set,然后进行Iterator迭代器迭代,或转换为Entry对象进行Iterator迭代器迭代
【Java】List,Set,Map存取元素各有什么特点?

9. Set 里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用 == 还是 equals()? 它们有何区别?

元素重复与否是使用 equals() 方法进行判断的

== 操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否
相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用 == 操作符。
equals 方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的
两个对象是独立的。

10. 两个对象值相同 (x.equals(y) == true),但却可有不同的 hashcode,这句话对不对?

得看情况,如果该对象重写了equals方法,那么可能会出现equals相同,但hashcode不同的情况,但假如没有重写equals方法,那么它默认继承是Object的equals方法,根据源码可知,此时equals相同,hashcode一定相同。

public boolean equals(Object obj) {
        return (this == obj);
    }

equals详解
总结:
如果两个对象相同(equals方法返回true),那么它们的hashCode值一定要相同;
如果两个对象的hashCode相同,它们并不一定相同。

11. heap 和 stack 有什么区别。

一、堆栈空间分配区别:

1、栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈;

2、堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。

二、堆栈缓存方式区别:

1、栈使用的是一级缓存, 他们通常都是被调用时处于存储空间中,调用完毕立即释放;

2、堆是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。

三、堆栈数据结构区别:

堆(数据结构):堆可以被看成是一棵树,如:堆排序;

栈(数据结构):一种先进后出的数据结构。
heap和stack有什么区别

12. Java 集合类框架的基本接口有哪些?

Java 集合类框架
总共有两大接口:Collection 和Map ,一个元素集合,一个是键值对集合; 其中List和Set接口继承了Collection接口,一个是有序元素集合,一个是无序元素集合; 而ArrayList和 LinkedList 实现了List接口,HashSet实现了Set接口,这几个都比较常用; HashMap 和HashTable实现了Map接口,并且HashTable是线程安全的,但是HashMap性能更好;

13. HashSet 和 TreeSet 有什么区别?

HashSet 和 TreeSet 的区别在于:1、速度和内部实现不同;2、排序方式不同;3、空对象不同;4、比较方式不同。HashSet用于搜索、插入和删除等操作。这些操作平均需要花费固定时间。HashSet比TreeSet快。HashSet是使用哈希表实现的。TreeSet以O(Log n)进行搜索,插入和删除,该值高于HashSet。

14. HashSet 的底层实现是什么?

它是基于 HashMap 实现的,底层采用 HashMap 来保存元素,HashSet其实就是在操作HashMap的key

  1. 因为HashMap是无序的,因此HashSet也不能保证元素的顺序
  2. 因为HashSet中没有对应同步的操作,因此是线程不安全的
  3. 支持null元素(因为hashMap也支持null键和null值)
15. LinkedHashMap 的实现原理?
16. 为什么集合类没有实现 Cloneable 和 Serializable 接口?
17. 什么是迭代器 (Iterator)?
18. Iterator 和 ListIterator 的区别是什么?
19. 数组 (Array) 和列表 (ArrayList) 有什么区别?什么时候应该使用 Array 而不是 ArrayList?
20. Java 集合类框架的最佳实践有哪些?
21. Comparable 和 Comparator 接口是干什么的?列出它们的区别。
22. Collection 和 Collections 的区别。

题源:2022java面试总结,1000道(集合+JVM+并发编程+Spring+Mybatis)的Java高频面试题

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值