java面试题系列(二)集合

java面试题系列(二)集合

java面试中,集合基本上是重中之重,不管是初中高级程序员,都是必考的点。因为集合可以考察面试者的诸如对java语言特性、对数据结构的知识面的了解程度。而且,java集合面试回答的重点,就是自己心里要有一套完整的体系概念,问一个问题你要把整个集合说出来才行。从而体现你对该知识体系有良好的理解和概念(不限于集合,当然,也不限于Java)

集合综合问题:

1.说一下java的集合框架(思路:不建议把每个类型的实现类和接口都说出来,第一个原因是如果回答太详细,比如每个接口作用和实现类说得完完整整,那明显感觉像背的【当然了解源码还是对提升编码能力有帮助的】,而且也没有考察性。第二个原因是话都给说完了还问啥?还有,队列不建议说,因为问线程方面基本上会再次问)

java集合是指一组元素的集合,他下面有几大类型,

List,一组有序、可重复的对象的集合

Set,一组无序,不可重复的对象的集合(可能会问:那你知道有有序的Set吗)

Map,k-value键值对元素的集合

2.说一下collection(可以说下子类了,因为这个范围还是缩小了的小的)

collection是集合框架顶层接口,代表了一组元素的集合。他下面有几大类型

List,一组有序、可重复的对象的集合,实现类有底层数组实现的ArrayList,线程安全的数组实现的Vector,底层链表实现的LinkedList(可以提及一下运用场景:比如前者更适合根据下标随机查找元素这些,不过接下来可能问你为什么他适合这个场景,后面讲)

Set,一组无序,不可重复的对象的集合,实现类有基于散列表的无序、不可重复的HashSet(实际为HashMap),基于红黑树的,有序的TreeSet(如何定义排序规则?)

3.说一下map(这个被外企问到过几次,说实现类和各自特点和使用场景。注意:conrrentHashmap是并发包下面的,只有单独问到才说)

Map是一组k-value键值对元素的集合,他下面的实现类有:

基于散列表的一组无序、不可重复的元素的集合的HashMap

HashTable,所有方法都同步的HashMap

基于红黑树的有序的TreeMap以及子类properties类

以及有序的hashmap:LinkedHashMap

集合基本问题

1.为啥要使用集合框架(用了有什么好处?)

提高代码复用性和可操作性,代码方便维护这些(毕竟人为啥要吃饭呢)

2.*什么是快速失败?什么是安全失败(微服务调用也有这个概念,意思完全不同)

前者指在集合迭代的时候删除元素从而导致集合抛异常,原因是集合维持一个modCount变量,集合改变时该变量改变从而导致异常(并发)

后者指复制副本进行迭代删除从而不会影响原集合(并发包下的)

3.迭代器是什么

用来遍历集合内元素类,每个集合类自带实现,通过移动指针到下一个元素来遍历

4.*为何 Map 接口不继承 Collection 接口 

因为map属于集合框架的一部分,但是他不属于集合,而是一组key-value键值对,不符合一组对象的定义(前文提到的是元素)。且继承了毫无意义

5.Iterator 和 ListIterator 的区别是什么?

前者所有集合实现类都有,后者为list特有且可以支持向前迭代

6.集合中泛型有什么用

泛型是将对象类型参数化,用于在编译前(编码时)提供检查类型是否正确。编译时将擦除类型

7.Comparable与Compartor的区别和作用

两者都是用于集合排序。

不同是:前者是用于定义相同一类对象互相之间的比较规则(实现comparTo方法)

后者是用于在collections.sort方法中重写(匿名内部类)来定义集合中元素的排序规则

8.集合可以存入基本数据类型吗?

不能,泛型不支持基础类型。且不符合集合的定义(一组对象的集合)

List

1.ArrayList的原理是什么,适用于哪些场景

底层为动态数组实现的ArrayList,适用于根据下标随机访问元素

2.为什么适合根据下标访问元素

因为底层的数组在内存中是一串连续的内存空间,CPU操作效率高。而LinkedList则需要遍历链表找到对应下标元素

3.LinkedList的原理是什么,适用于哪些场景

底层为链表实现的LinkedList,每个节点持有前后节点的对象的引用,适合删除元素(忽略查找要删除的元素时间的情况下),只需将前后节点的引用修改为对方即可删除,不必像ArrayList一样中间删除元素要移动后面元素对其一样

4.ArrayList 和 Vector 有何异同点?

同为动态数组来实现的,不同的是:前者扩容时1.5倍,后者两倍。前者线程不安全,后者所有方法都有同步关键字(效率当然是前者高后者低喽)

5.ArrayList和LinkedList区别(结合上面几点答,底层数据结构、各自适用场景)

6.ArrayList和LinkedList是线程安全的吗,如果不是应该怎么做

不是,可以采用并发包下的容器组件(CopyWriteArrayList等)

7.List元素去重说一下

可以转化为set(HashSet),或者存入HashMap(一样的思路)

Set

1.说下set

set是一组无序,不可重复的对象的集合,实现类有基于散列表的无序、不可重复的HashSet(实际为HashMap),基于红黑树的,有序的TreeSet。有序的HashSet:LinkedHashSet

2.HashSet是怎么实现的

通过HashMap,key为元素,value为占位符

3.set有哪些应用场景

元素去重、随机排序元素(随机但是固定一种)

4.set都是无序的吗?(或:如何实现有序的set)

TreeSet、LinkedHashSet是有序的set。其中前者可以定义排序规则,后者保留插入顺序

5.map中如何取出key的集合

使用keySet方法取出包含所有key的set集合

Set待补充(因为真的很少问到)

Map

集合算是java的面试重点了。这个真的是集合中的重点了

1.说一下Map(参照上面)

Map是一组k-value键值对元素的集合,他下面的实现类有:

基于散列表和链表的一组无序、不可重复的元素的集合的HashMap

HashTable,所有方法都有同步关键字的HashMap

基于红黑树的有序的TreeMap以及子类properties类

以及有序的hashmap:LinkedHashMap

HashMap相关

2.HashMap 说一下怎么实现的

通过一个散列表(数组)加链表实现的,也就是通过key的哈希值与(数组长度-1)做位与运算,得出元素应该存放的数组下标。(这里可以答是否哈希碰撞等)

3.如果检测到冲突,也就是哈希后计算的位置有元素怎么办?(哈希碰撞)

通过equals方法比较,如果相等则证明两个元素完全相同(哈希值和equals方法都相同了)。因为HashMap中每个节点(Entry)存放的是链表节点,所以把该元素放到链表头

4.哈希是什么

哈希是指一种算法。指将输入的值通过特定的算法计算为一串固定长度的字符串

5.为什么说哈希碰撞过多会导致效率变低?

因为如果哈希碰撞过多,可能会导致许多元素都在一个位置,也就是一个链表中。HashMap取出时每次都要遍历链表,而链表遍历是相当花时间的

6.除了链表法,还有哪些处理哈希冲突的方法

再次寻址法:再哈希一次。

7.*HashMap为什么推荐传入初始容量为2的幂次方?

因为HashMap默认采用的哈希算法是元素key的哈希值对(数组长度-1)做位与运算,(注:2的幂次方-1的二进制数为:每个位上都为1。位与:都1为1,其他为0)。如果不是二的幂次方,位运算则必定会有位为0,那么key始终在这位为0始终为0,从而导致有一部分元素存在同一位置,增大碰撞风险                                                                                                                               不过就算你传入不是2的幂次方,他也会取最接近传入的数 的2的幂次方(大于该数的2的幂次方)作为默认初始容量。

8.HashMap的扩容机制是什么?

当元素个数到达(最大容量*加载因子)个数时,将数组扩大为原来两倍,所有元素重新计算哈希值并放入对应位置

9.jdk1.7与1.8中HashMap有什么区别

1.7中碰撞后采用链表处理冲突,遍历链表查找效率差。1.8后链表长度超过8会转化为红黑树,查询效率大大提升

10.为啥重写了equals方法还要必须重写hasCode方法

第一个是因为规范和共识(废话),equals方法是判断两个对象是否相同的方法,如果两个对象完全相同,哈希值也必须相同,第二点是因为如果两个对象equal相等,那么他们应该是两个相同的对象,否则两个相等的对象,却放在不同位置,浪费空间和性能。HashSet也会完全失去作用

11.如何遍历map

第一种方法:通过keySet方法取出键的set集合,取出set每个元素进行map遍历,第二种方法:通过entrySet()方法得到键值对对象Entry的集合,循环遍历该对象取出键值

12.*HashMap中有哪些关键的变量

加载因子、初始容量

13.为什么加载因子设为0.75?

加载因子是指当HashMap满了加载因子的比例时会进行扩容。因为是基于碰撞和空间的考量的一个考虑。如果设的太大,则当HashMap快装满时才会扩容,这样会产生大量的哈希碰撞。如果设置的小,则HashMap距离装满差很大一截就开始扩容,这样会导致一部分空间一直不会得到使用,浪费空间

14.HashMap是线程安全的吗(为什么不安全)

不是线程安全的。当扩容时替换指针和重新计算哈希可能会导致链表循环引用

15.既然线程不安全,那你有什么解决方法吗?

如果不考虑效率,可以采用所有方法增加了同步关键字的HashTable。当然,最优解则为并发包Courrent下的CourrentHashMap。

16.HashTable和HashMap区别

前者是线程安全的,每个方法都加了同步关键字,key不能为null。后者则相反。。

17.HashTable为啥效率低(考HashTable源码)

因为同步了get和set,如果大量读取会导致大量阻塞

18.HashMap在什么时候会转化为红黑树,什么时候会退化为链表

(桶)链表长度大于等于8时

 

CourrentHashMap相关

1.CourrentHashMap是什么

是jdk1.5增加的并发包下面的类,主要用于处理并发下map的问题

2.相比于HashMap和HashTable,有什么区别

由于采用了分段锁,把散列表(数组)划分为一个个段,每个段单独持有有一把锁,支持16个线程并发操作,比起前者并发安全性好,比起后者效率高

3.jdk1.7与1.8有什么区别(要回答map1.7和1.8区别)

1.7中采用分段锁,写时只锁该段读写,从而并发安全。1.8以后采用synchronized+CAS,对链表和红黑树加关键字synchronized,再用修改CAS比较重试,大大的增加了并发安全和效率

4.并发包待续

TreeMap

1.是什么

是一个支持根据key来进行元素排序的有序map

2.怎么使用

通过对象实现compare接口重写比较方法,如果返回1和2则为两个元素比较结果,0则两个元素相同

 

集合相关问题

1.集合如何实现排序

通过工具类collections.sort方法,默认为比较key的大小。如果要根据对象某个属性进行比较,则需传入的对象实现compare类,自定义排序规则

2.为什么操作Arrays.asList()方法的list时会有问题(为什么该方法不支持add和删除)

该方法作用是将数组转化为list,但只是用一个内部实现类持有该数组。所以。。

3.HashMap是有序的吗?我想要有序的HashMap怎么办

无需的,根据哈希值计算肯定是无序存储的。可以使用LinkedHashMap。用一个链表来维持元素顺序的hashmap

 

 

其他参考源码系列:https://mp.csdn.net/postedit/103359042 没写完

待补充。。。

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值