Java集合类常见的10个经典面试题及答案整理

Java面试 潘老师 2年前 (2022-02-15) 1041 ℃ (0) 扫码查看

集合是Java开发中常用的类,因此Java集合类面试题基本100%会被问,而且还会问的很有深度,潘老师给大家整理了Java集合类常见的10个经典面试题,并附上了答案,掌握这些集合知识,想必对你的面试一定会有帮助。

第1题:Java常用的集合类有哪些?他们的层级关系是怎样的?

答案整理:

常用集合类:
1、Collection子类:
1)set
HashSet、TreeSet
2)list
ArrayList、LinkedList、Vector
2、Map子类:
HashMap、HashTable、TreeMap
它们的层级关系如下图:
java集合框架图
ps:a)线程安全:Vector、HashTable、StringBuffer
b) 线程不安全:HashMap、TreeMap、HashSet、ArrayList、LinkedList
c) List有序,set无序,map无序,queue消息阻塞队列。

第2题:说下List、Set、Map等集合的特点及使用区别?

答案整理:

1、List(有序、可重复)
List里存放的对象是有序的,同时也是可以重复的,List关注的是索引,拥有一系列和索引相关的方法,查询速度快。因为往list集合里插入或删除数据时,会伴随着后面数据的移动,所有插入删除数据速度慢。

2、Set(无序、不能重复)
Set里存放的对象是无序,不能重复的,集合中的对象不按特定的方式排序,只是简单地把对象加入集合中。

3、Map(键值对、键唯一、值不唯一)
Map集合中存储的是键值对,键不能重复,值可以重复。根据键得到值,对map集合遍历时先得到键的set集合,对set集合进行遍历,得到相应的值。
List、Set、Map等集合对比图

第3题:ArrayList与LinkedList使用区别?

答案整理:

总体而言:ArrayList底层是数组,查询快、增删慢;LinkedList底层是双向循环链表,查询慢、增删快。
原因如下:
ArrayList底层是数组,数组的存储空间是连续的,可以根据寻址方式直接找到对应的元素位置,时间复杂度是O(1)。增删可能涉及数组扩容和拷贝(不是100%),效率较低。
LinkedList底层是链表,存储空间不连续,需要通过指针关联,在查询过程中需要不断跳转新的地址,查询复杂度O(N),增删复杂度O(1),但增删要先找到元素位置。
另外,LinkedList 不支持高效的随机元素访问,而ArrayList 实现了RandmoAccess 接口,所以有随机访问功能。快速随机访问就是通过元素的序号快速获取元素对象(对应于get(int index)方法)。所以ArrayList随机访问快,插入慢;LinkedList随机访问慢,插入快。

第4题:遍历一个 List 有哪些不同的方式?

答案整理:

1)for 循环遍历,基于计数器。在集合外部维护一个计数器,然后依次读取每一个位置的元素,当读取到最后一个元素后停止。
2)使用Iterator迭代器遍历。Iterator 是面向对象的一个设计模式,目的是屏蔽不同数据集合的特点,统一遍历集合的接口。Java 在 Collections 中支持了 Iterator 模式。
3)使用foreach 循环遍历。foreach 内部也是采用了 Iterator 的方式实现,使用时不需要显式声明 Iterator 或计数器。优点是代码简洁,不易出错;缺点是只能做简单的遍历,不能在遍历过程中操作数据集合,例如删除、替换。

第5题:说下HashMap原理、哈希冲突的解决?

答案整理:

HashMap基于hashing原理。散列法(Hashing)是一种将字符组成的字符串转换为固定长度(一般是更短长度)的数值或索引值的方法,称为散列法,也叫哈希法。由于通过更短的哈希值比用原始值进行数据库搜索更快,这种方法一般用来在数据库中建立索引并进行搜索,同时还用在各种解密算法中。

HashMap通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,然后找到bucket位置来储存值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。

HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会储存在链表的下一个节点中。 HashMap在每个链表节点中储存键值对对象。

所谓哈希碰撞(冲突)是指当两个不同的输入值,根据同一散列函数计算出相同的散列值的现象。HashMap是使用了如下方法哈希冲突的:

  • 使用链地址法(使用散列表)来链接拥有相同hash值的数据;
  • 使用2次扰动函数(hash函数)来降低哈希冲突的概率,使得数据分布更平均;
  • 引入红黑树进一步降低遍历的时间复杂度,使得遍历更快;

第6题:HashMap是线程安全的吗?如果不安全,怎么解决?

答案整理:

HashMap是线程不安全的,解决方案:
1)可以使用Collections.synchronizedMap()方法将HashMap变成线程安全的
2)最好的解决方案就是使用ConcurrentHashMap替代。

第7题:ConcurrentHashMap如何保证线程安全的?

答案整理:

jdk1.7中是采用Segment + HashEntry + ReentrantLock的方式进行实现的,而1.8中放弃了Segment臃肿的设计,取而代之的是采用Node + CAS + Synchronized来保证并发安全进行实现。ConcurrentHashMap保证线程安全引入了一个重要的思想就是基于CAS算法(Compare And Swap)。

第8题:Java8开始ConcurrentHashMap为什么舍弃分段锁?

答案整理:

弃用分段锁的原因由以下几点:

  • 加入多个分段锁浪费内存空间。
  • 生产环境中, map 在放入时竞争同一个锁的概率非常小,分段锁反而会造成更新等操作的长时间等待。
  • 为了提高 GC 的效率

第9题:Collection与Collections的区别是什么?

答案整理:

Collection是单列集合的顶层接口,Map是双列集合的顶层接口

Collections是一个集合的工具类,提供了排序、查找等操作集合的一些常用方法。

第10题:当一个集合被作为参数传递给一个函数时,如何才可以确保函数不能修改它?

答案整理:

当集合在作为参数传递之前,我们可以使用Collections.unmodifiableCollection(Collection c)方法创建一个只读集合,这将确保改变集合的任何操作都会抛出UnsupportedOperationException

总结

以上就是Java集合类常见的10个经典面试题和答案整理,你学会了吗?


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/javainterview/4374.html
喜欢 (1)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】