0
点赞
收藏
分享

微信扫一扫

集合相关面试题

阎小妍 2022-03-22 阅读 88

参考资料:常见数据结构总结_龚礼鹏的博客-CSDN博客

一.谈一谈List、Map和Set的区别?

List:有序、可重复、单列数据。List存储的数据是有序的并且可重复的单列数据的集合。

Set:唯一、不可重复、单列数据。Set存储的数据是唯一的无序的单列数据的集合。

Map:键值对。Map存储的是键值对这样双列数据的集合。

参考:三大集合:List、Map、Set的区别与联系_Star_Li_92的博客-CSDN博客_list map set的区别

二.谈一谈ArrayList和LinkedList的区别?

1.基于的数据结构:ArrayList是基于数组的数据结构,分配的是一段连续的存储空间,存储在栈中。LinkedList是基于双向链表的数据结构,存储在堆中。

2.由于ArrayList是基于数组的数据结构,所以根据index索引查询和修改数据效率高( O(1) ),新增和删除效率低,因为新增数据需要考虑的数组的容量,可能发生扩容操作,删除数据除了最后一个数据删除其他数据都要移动数组中的元素( O(n) )。

3.LinkedList对比ArrayList查询和修改数据效率较低,因为是双向链表数据结构,需要根据节点一个一个往下(或者往上)寻找( O(n) ),新增和删除数据效率较高,因为只需要改动一下指针即可( O(1) )。

4.存储空间:由于LinkedList是双向链表,所以需要更多的存储空间存储前驱和后驱,所以在存储相同多的数据情况下LinkedList占用更多的存储空间

参考:https://blog.csdn.net/gongjdde/article/details/118977595

 https://blog.csdn.net/gongjdde/article/details/118978012

2019-04-23:谈谈ArrayList和LinkedList的区别? · Issue #36 · Moosphan/Android-Daily-Interview · GitHub 

三.说一说ArrayList的扩容机制?

无参的构造方法是初始长度为10的数组,有参的构造方法传入数组的初始长度。扩容是在原先的数组长度的1.5倍(此处用到的算法是:int newCapacity = oldCapacity + (oldCapacity >> 1);),如果长度超过Integer.MAX_VALUE-8,则直接是扩容到最大长度Integer.MAX_VALUE。

参考:https://blog.csdn.net/gongjdde/article/details/118977595

 

四.请说一下HashMap和HashTable的区别?

1.Hashtable不支持null键和值
2.Hashtable使用synchronized来进行同步(有性能开销)
3.Hashtable的迭代器是fail-safe(安全失败)机制,HashMap的迭代器是fail-fast(快速失败)机制
4.Hashtable默认容量为11且不要求底层数组的容量一定要是2的整数次幂,而HashMap则是16,必须是2的整数次幂.

5.hash值使用不同,HashTable是直接使用对象的hash值,HashMap是通过扰动算法重新计算了hash值

参考:https://github.com/Moosphan/Android-Daily-Interview/issues/39

https://blog.csdn.net/gongjdde/article/details/118978149 

五.HashMap实现原理?

1.jdk 1.7是数组+链表的数据结构,jdk 1.8是数组+链表(or红黑树)的数据结构。

2.在jdk1.8中大致流程是如果是无参构造方法先初始化长度为16的一个常量,用于后面数组长度使用,注意此时数组还是空的。

3.然后调用put方法添加数据,添加过程比较复杂:

①.首先根据key的hash值计算出一个新的key的hash值,此处jdk1.8用到了两次扰动算法。

②.然后先判断数组是否为空,如果为空则扩容初始化数组(此处如果原先使用的是HashMap无参的构造方法则是数组初始化容量为16,负载因子为0.75)。

③.然后通过key的新hash值与数组容量-1进行位与算法(类似于hash值与数组容量取余,不过位与算法效率更高)计算出此key的数组下标。

④.根据下标然后找到指定桶的位置,如果是空的则直接将数据插入。

⑤.如果发生了hash冲突,则先看此位置的key是否相同,如果相同则直接替换value值;反之,然后判断此处是红黑树数据结构还是链表数据结构,如果是红黑树数据结构,通过红黑树算法插入此数据,如果是链表数据结构则遍历链表查询是否有相同key,如果有则替换value值,如果没有在尾部插入此数据。如果链表数据长度超过8并且总的数组容量达到64则进行树化

⑥.如果此时hash的长度大于阈值(数组长度*负载因子)则进行扩容,扩容容量是原先的两倍,然后根据旧数组轮询判断在新数组中的位置,三种情况:如果此处索引是空的,根据位与算法计算出在新数组中的位置;如果是红黑树则单独处理;如果是链表则根据hash值&老数组长度为0还是1判断是否需要挪动位置。

参考:面试必问的HashMap,你真的了解吗?

https://blog.csdn.net/gongjdde/article/details/118978149 

 2019-03-29:HashMap 的实现原理? · Issue #16 · Moosphan/Android-Daily-Interview · GitHub

 

举报

相关推荐

0 条评论