动力节点旗下在线教育品牌  |  咨询热线:400-8080-105 学Java全栈,上蛙课网
首页 > 文章

Java面试必问——HashMap面试题(附答案)

09-01 17:22 132浏览
举报 T字号
  • 大字
  • 中字
  • 小字

HashMap是java程序员使用频率最高的用于映射处理的数据类型,同时,因为HashMap的好处非常多,在电子商务的应用中会使用到HashMap作为缓存。这成为了java面试的必考内容,所以今天这篇文章整理了10HashMap面试题,都是在互联公司面试中常考必考的题目,正在准备面试的小伙伴们一定不能错过下面的内容。

1、HashMap的底层原理是什么?

答:hashmap内部是一个数组+链表的数据结构,在put元素的时候,首先会把元素的key做hash运算,再通过这个hash值与数组长度做位运算,得到真正的元素下标,这时判断该下标是否有元素,如果有元素,则通过头插法将元素插入到链表。get的时候就用相同的方法得到元素的下标,如果该数组下标只有一个元素,则该元素就是map的value,如果是链表结构,就循环链表得到map的value。

2、hashMap是否是线程安全的?

答:非线程安全的,因为如果在高并发下,会导致在某个index下有循环链表的产生,这是如果get一个不存在的key,该key计算出的index值正好等于前面循环链表所在的index值,就会出现死循环,此处也可以通过讲解代码来详细说说怎么产生的循环链表。

3、LinkedHashMap和TreeMap是怎么保证他们是有序的?

答:LinkedHashMap继承自HashMap内部维护了一个链表来保持它内部元素的插入顺序,迭代的时候也是按照插入的顺序迭代;TreeMap则是按照key的自然顺序来排序,如果需要可以继承Comparator接口来实现。

4、hashMap默认初始长度是多少?为什么这么规定?

答:默认初始长度是16,为了服务于key映射到index的hash算法,该算法是用hash(key)&length-1,位运算可以保证性能,并且效果和取模一样,16-1是为了保证其二进制位数都是1,这样只要hash函数算出的结果是均匀的,得到的index也是均匀的。

5、如何构建一个线程安全的Map?

答:可以用hashTable和currentHashMap,HashTable就是实现了synchronize关键字的hashmap,效率很低,一般不建议使用。put的时候则由key得到hash值,由这个hash值定位到所在的segment,获得可重入锁,再通过hash值获取具体index,插入或者覆盖对象,释放锁。

get的时候则由key得到hash值,由这个hash值定位到所在的segment,再定位到具体的index。java8则改用synchronize和CAS来实现,同时底层改用链表+红黑树的结构,存放数据由hashEntry改为Node,并且由volatile关键字修饰value和next来保证其多线程下的可见性。

put的时候计算key的hash值,判断是否需要初始化,定位出的node如过为空,则利用CAS插入数据,如果hashCode==MOVIED==-1则扩容,否则利用synchronize锁写入数据。get的时候依然通过hashcode寻址,如果是链表则按照链表方式寻址,如果是红黑树则按照红黑树方式寻址。

6、HashMap的工作原理与HashMap的get()方法的工作原理?

答:HashMap是基于hashing的原理,我们使用put(key, value)存储对象到HashMap中,使用get(key)从HashMap中获取对象。当我们给put()方法传递键和值时,我们先对键调用hashCode()方法,返回的hashCode用于找到bucket位置来储存Entry对象。HashMap是在bucket中储存键对象和值对象,作为Map.Entry。

7、当两个对象的hashcode相同会发生什么?

答:hashcode相同,所以两个对象是相等的,HashMap将会抛出异常,或者不会存储它们。有equals()和hashCode()两个方法,两个对象就算hashcode相同,但是它们可能并不相等是因为hashcode相同,所以它们的bucket位置相同,‘碰撞’会发生。因为HashMap使用链表存储对象,这个Entry(包含有键值对的Map.Entry对象)会存储在链表中。

8、可以使用CocurrentHashMap来代替Hashtable吗?

答:因为ConcurrentHashMap越来越多人用了。我们知道Hashtable是synchronized的,但是ConcurrentHashMap同步性能更好,因为它仅仅根据同步级别对map的一部分进行上锁。ConcurrentHashMap当然可以代替HashTable,但是HashTable提供更强的线程安全性。

9、为什么String、Interger这样的wrapper类适合作为键?”

答:String、Interger这样的wrapper类作为HashMap的键是再适合不过了,而且String最为常用。因为String是不可变的,也是final的,而且已经重写了equals()和hashCode()方法了。其他的wrapper类也有这个特点。不可变性是必要的,因为为了要计算hashCode(),就要防止键值改变,如果键值在放入时和获取时返回不同的hashcode的话,那么就不能从HashMap中找到你想要的对象。不可变性还有其他的优点如线程安全。如果你可以仅仅通过将某个field声明成final就能保证hashCode是不变的,那么请这么做吧。因为获取对象的时候要用到equals()和hashCode()方法,那么键对象正确的重写这两个方法是非常重要的。如果两个不相等的对象返回不同的hashcode的话,那么碰撞的几率就会小些,这样就能提高HashMap的性能。

10、如果HashMap的大小超过了负载因子(load factor)定义的容量,怎么办?

答:默认的负载因子大小为0.75,也就是说,当一个map填满了75%的bucket时候,和其它集合类(如ArrayList等)一样,将会创建原来HashMap大小的两倍的bucket数组,来重新调整map的大小,并将原来的对象放入新的bucket数组中。这个过程叫作rehashing,因为它调用hash方法找到新的bucket位置。

以上内容整理的HashMap面试题,希望上面的10道HashMap面试题能对大家有所帮助,毕竟在java面试中必问HashMap底层实现原理,这些基础性知识点是一定要会的。希望java零基础入门不久的新手朋友们可以在这篇文章的基础上再多学习相关的HashMap视频课程,深入学习HashMap底层原理、HashMap源码分析以及其他相关知识点,筑牢知识底座,打造更好的自己。

0人推荐
共同学习,写下你的评论
0条评论
代码小兵1136
程序员代码小兵1136

6篇文章贡献28501字

作者相关文章更多>

推荐相关文章更多>

Java数据结构

HelloWorld10-31 08:24

浅谈MySQL中SQL优化的常用方法

军哥08-12 23:29

MyBatis开发框架的四大核心

IT逐梦者08-17 21:43

五分钟读懂UML类图

江湖人称小李白12-10 10:41

一次搞定continue,break和return

HelloWorld11-06 11:19

发评论

举报

0/150

取消