HashMap常见问题整理

10多家公司的Java开发面试常见问题合集 ​上篇文章我请几个大佬帮我总结了一下,整理了三套模拟面试题,细心的大佬已经发现我中间断更了一天,为什么断更呢,也讲一下原因吧。我把我以前去面试过的那些东东扒出来了,今天我分享一下我的。 本人是做java开发的,这是我参加工作几年面试总结所得,当然面得那些公司自然是跟在座的大佬比不得。有一些互联网大厂也有一些小的创业型公司的面试问题,与之前的几篇分享的会有一些重复,弄清楚这些,相信面试会轻松许多。... 阅读详情

一、HashMap实现原理

你看过HashMap源码嘛,知道原理嘛?

在这里插入图片描述
HashMap采用Entry数组来存储key-value对,每一个键值对组成了一个Entry实体,Entry类实际上是一个单向的链表结构,它具有Next指针,可以连接下一个Entry实体。
只是在JDK1.8中,链表长度大于8的时候,链表会转成红黑树!

为什么用数组+链表?

数组是用来确定桶的位置,利用元素的key的hash值对数组长度取模得到.
链表是用来解决hash冲突问题,当出现hash值一样的情形,就在数组上的对应位置形成一条链表

hash冲突你还知道哪些解决办法?

比较出名的有四种:开放定址法、链地址法、再哈希法、公共溢出区域法

  • 开放地址法
    从发生冲突的那个单元起,按照一定的次序,从哈希表中找到一个空闲的单元。然后把发生冲突的元素存入到该单元的一种方法。开放定址法需要的表长度要大于等于所需要存放的元素。

  • 再散列
    当发生冲突时,使用第二个、第三个、哈希函数计算地址,直到无冲突时。缺点:计算时间增加。

  • 链接地址法的思路是将哈希值相同的元素构成一个同义词的单链表,并将单链表的头指针存放在哈希表的第i个单元中,查找、插入和删除主要在同义词链表中进行。在java中,链接地址法也是HashMap解决哈希冲突的方法之一。

  • 公共溢出区域法
    将哈希表分为公共表和溢出表,当溢出发生时,将所有溢出数据统一放到溢出区。

我用LinkedList代替数组结构可以么?

答案很明显,必须是可以的。
既然是可以的,为什么HashMap不用LinkedList,而选用数组?
因为用数组效率最高!
在HashMap中,定位桶的位置是利用元素的key的哈希值对数组长度取模得到。此时,我们已得到桶的位置。显然数组的查找效率比LinkedList大。

既然是可以的,为什么HashMap不用LinkedList,而选用数组?

因为采用基本数组结构,扩容机制可以自己定义,HashMap中数组扩容刚好是2的次幂,在做取模运算的效率高。
而ArrayList的扩容机制是1.5倍扩容,那ArrayList为什么是1.5倍扩容这就不在本文说明了。

二、HashMap在什么条件下扩容

HashMap在什么条件下扩容

如果bucket满了(超过load factor*current capacity),就要resize。
load factor为0.75,为了最大程度避免哈希冲突
current capacity为当前数组大小。

为什么扩容是2的次幂

HashMap为了存取高效,要尽量较少碰撞,就是要尽量把数据分配均匀,每个链表长度大致相同,这个实现就在把数据存到哪个链表中的算法;这个算法实际就是取模,hash%length。
但是,大家都知道这种运算不如位移运算快。
因此,源码中做了优化hash&(length-1)。
也就是说hash%length==hash&(length-1)
位运算比较高效,当b为2的n次方时,有如下替换公式:
a % b = a & (b-1)(b=2n)
即:a % 2n = a & (2n-1)

为什么为什么要先高16位异或低16位再取模运算

hashmap这么做,只是为了降低hash冲突的几率。

比如,当我们的length为16的时候,哈希码(字符串“abcabcabcabcabc”的key对应的哈希码)对(16-1)与操作,对于多个key生成的hashCode,只要哈希码的后4位为0,不论不论高位怎么变化,最终的结果均为0。
如下图所示
在这里插入图片描述
而加上高16位异或低16位的“扰动函数”后,结果如下

在这里插入图片描述

三、hashmap的get/put的过程

知道hashmap中put元素的过程是什么样吗

对key的hashCode()做hash运算,计算index;
如果没碰撞直接放到bucket里;
如果碰撞了,以链表的形式存在buckets后;
如果碰撞导致链表过长(大于等于TREEIFY_THRESHOLD),就把链表转换成红黑树(JDK1.8中的改动);
如果节点已经存在就替换old value(保证key的唯一性)
如果bucket满了(超过load factor*current capacity),就要resize。

知道hashmap中get元素的过程是什么样吗

对key的hashCode()做hash运算,计算index;
如果在bucket里的第一个节点里直接命中,则直接返回;
如果有冲突,则通过key.equals(k)去查找对应的Entry;
若为树,则在树中通过key.equals(k)查找,O(logn);
若为链表,则在链表中通过key.equals(k)查找,O(n)。

你还知道哪些hash算法?

先说一下hash算法干嘛的,Hash函数是指把一个大范围映射到一个小范围。把大范围映射到一个小范围的目的往往是为了节省空间,使得数据容易保存。
比较出名的有MurmurHash、MD4、MD5等等

说说String中hashcode的实现?(此题频率很高)

public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
        char val[] = value;

        for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i];
        }
        hash = h;
    }
    return h;
}

String类中的hashCode计算方法还是比较简单的,就是以31为权,每一位为字符的ASCII值进行运算,用自然溢出来等效取模。

主要是因为31是一个奇质数,所以31i=32i-i=(i<<5)-i,这种位移与减法结合的计算相比一般的运算快很多。

四、为什么hashmap的在链表元素数量超过8时改为红黑树

知道jdk1.8中hashmap改了啥吗

  • 由数组+链表的结构改为数组+链表+红黑树。
  • 优化了高位运算的hash算法:h^(h>>>16)
  • 扩容后,元素要么是在原位置,要么是在原位置再移动2次幂的位置,且链表顺序不变。

最后一条是重点,因为最后一条的变动,hashmap在1.8中,不会在出现死循环问题。

为什么在解决hash冲突的时候,不直接用红黑树?而选择先用链表,再转红黑树

因为红黑树需要进行左旋,右旋,变色这些操作来保持平衡,而单链表不需要。
当元素小于8个当时候,此时做查询操作,链表结构已经能保证查询性能。当元素大于8个的时候,此时需要红黑树来加快查询速度,但是新增节点的效率变慢了。
因此,如果一开始就用红黑树结构,元素太少,新增效率又比较慢,无疑这是浪费性能的。

我不用红黑树,用二叉查找树可以么

可以。但是二叉查找树在特殊情况下会变成一条线性结构(这就跟原来使用链表结构一样了,造成很深的问题),遍历查找会非常慢。

当链表转为红黑树后,什么时候退化为链表

为6的时候退转为链表。中间有个差值7可以防止链表和树之间频繁的转换。假设一下,如果设计成链表个数超过8则链表转换成树结构,链表个数小于8则树结构转换成链表,如果一个HashMap不停的插入、删除元素,链表个数在8左右徘徊,就会频繁的发生树转链表、链表转树,效率会很低。

五、HashMap的并发问题

HashMap在并发编程环境下有什么问题

  • 多线程扩容,引起的死循环问题
  • 多线程put的时候可能导致元素丢失
  • put非null元素后get出来的却是null

在jdk1.8中还有这些问题么

在jdk1.8中,死循环问题已经解决。其他两个问题还是存在。
https://coolshell.cn/articles/9606.html

六、你一般用什么作为HashMap的key

健可以为Null值么

可以,key为null的时候,hash算法最后的值以0来计算,也就是放在数组的第一个位置。
在这里插入图片描述

你一般用什么作为HashMap的key

一般用Integer、String这种不可变类当HashMap当key,而且String最为常用。

  • 因为字符串是不可变的,所以在它创建的时候hashcode就被缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键往往都使用字符串。
  • 因为获取对象的时候要用到equals()和hashCode()方法,那么键对象正确的重写这两个方法是非常重要的,这些类已经很规范的覆写了hashCode()以及equals()方法。

我用可变类当HashMap的key有什么问题

hashcode可能发生改变,导致put进去的值,无法get出。

如果让你实现一个自定义的class作为HashMap的key该如何实现

针对问题一,记住下面四个原则

  • 两个对象相等,hashcode一定相等
  • 两个对象不等,hashcode不一定不等
  • hashcode相等,两个对象不一定相等
  • hashcode不等,两个对象一定不等

如何写一个不可变类

  • 类添加final修饰符,保证类不被继承
  • 保证所有成员变量必须私有,并且加上final修饰
  • 不提供改变成员变量的方法,包括setter
  • 通过构造器初始化所有成员,进行深拷贝(deep copy)
    public final class MyImmutableDemo {  
        private final int[] myArray;  
        public MyImmutableDemo(int[] array) {  
            this.myArray = array.clone();   
        }   
    }
    
  • 在getter方法中,不要直接返回对象本身,而是克隆对象。
java初级面试题整理汇总-附答案 1.hashmap的数据结构是什么? 答:在Java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。 2.说一说java如何实现的跨平台 答:java针对不同的开发系统 开发了不同的JVM虚拟机,并提供了统一的接口(java API... 阅读详情

相关推荐

Java面试题及答案整理( 2023年 6 月最新版,持续更新)

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。

m0_51274464的博客 444

HashMap常见问题

有一个静态内部类Node,并实现了Map.Entry接口; static class Node<K,V> implements Map.Entry<K,V> { final int hash; final K key; V value; Node<K,V> next; Node(int hash, K key, V value, Node<K,V> next) {

Y_hahaha的博客 1033

GX WORKS2通过交换机连接PLC的方法

三菱PLC连接方法的分享

weixin_64927621的博客 3619

HashMap的一些常见问题

1. HashMap 不是线程安全的,那如果多线程下,它是如何处理的?并且什么 情况下会发生线程不安全的情况? HashMap 不是线程安全的,如果多个线程同时对同一个 HashMap 更改数据的话,会导致数据不一致或者数据污染。 如果出现线程不安全的操作时,HashMap会尽可能的抛出 ConcurrentModificationException 防止数据异常。 当我们在对一个 HashMap 进行遍历时,在遍历期间,我们是不能对 HashMap 进行添加,删除等更改数据的操作的,否则也会抛出 Conc

梦否 1299

医疗器械软件测试输出内容(1)

*单元测试(Unit Testing):**单元测试是软件测试的最底层,用于验证软件中最小的可测试单元——函数、方法或模块。系统测试是在集成测试之后进行的,它对整个系统进行测试,验证系统在不同部分集成在一起后是否满足需求和规格。: 集成测试是在单元测试之后进行的,它关注不同单元之间的交互和集成。对于不同安全级别的软件(IEC 62304 A类、B类、C类),在体系上要求输出的文件内容有所区别。**说明:**将集成测试和软件系统测试合并为一项单一的计划和一组活动是可接收的。

ct745363083的博客 1867

educoder数字逻辑实训:寄存器设计与应用(Logisim)

第1关:基本寄存器的设计 任务描述 本关任务:在Logisim中,构建由4个D触发器构成的4位基本寄存器,要求上升沿触发,具有异步复位功能。 第2关:移位寄存器的设计 任务描述 本关任务:在Logisim中,构建由4个D触发器构成的4位右移移位寄存器,要求上升沿触发,具有异步复位功能。 第3关:循环移位寄存器的设计 任务描述 本关任务:在Logisim中,构建由4个D触发器构成的4位循环右移移位寄存器,要求上升沿触发,具有异步复位功能以及并行数据同步加载功能。 第4关:并行..

qq_52209002的博客 1万+

hashmap常见问题

1.index 冲突: 底层做二进制运算 产生相同的index 对象不同 但是二进制运算是相同的index h&(length -1) 偶数 发生冲突概率特别大 length-1变为基数 length -1:来避免冲突 2. hashcode冲突 : 底层计算 value生成的hashcode值相同 ,在同一个索引位置, 用链表进行保存(hashcode值相同的元素) 链表保存来避免冲...

封神之路 703

飞书云文档API实战:从权限申请到自动化操作

本文详细介绍了飞书云文档API的实战应用,从权限申请到自动化操作。内容涵盖如何创建应用、获取关键API权限、理解并使用Tenant Access Token,并通过Python代码示例演示了读取和写入飞书表格数据的具体方法,旨在帮助开发者和业务人员实现文档数据处理的自动化,提升工作效率。

weixin_28318011的博客 1940

hashMap常见问题

【解析hashMap的源码实现】 点击进入hashMap的源码实现 0、谈谈对hashMap的理解? 从底层结构、存取、扩容、冲突、实现原理、源码等方面说明。 1、你知道哪些常用的Map集合? HashMap、HashTable、LinkedHashMap、ConcurrentHashMap。 2、Collection集合接口和Map接口有什么关系? ...

weixin_30457465的博客 474

西门子触摸屏教程wincc flexible2008 sp5 Smart V3 V4中文版软件

西门子触摸屏教程wincc flexible2008 sp5 Smart V3 V4中文版软件

liang007dudu的博客 1万+

【图论】系列(一)之图论的构成

图论是研究图的数学分支,本章介绍了图论的基本构成和概念

qq_30066733的博客 748

Java集合八股整理

本文系统介绍了Java集合框架的核心知识点,重点分析了常用集合类的实现原理与线程安全机制。主要内容包括:1)集合的基础概念及与数组的对比;2)ArrayList与LinkedList、ArrayBlockingQueue与LinkedBlockingQueue的底层实现差异;3)HashMap的底层数据结构(数组+链表/红黑树)、扩容机制及线程不安全问题;4)ConcurrentHashMap在JDK1.7(分段锁)和1.8(CAS+synchronized)的线程安全实现;

s030130y的博客 594

多图详解VSCode搭建Python开发环境

本文通过多图的方式详细介绍了VSCode搭建Python开发环境,希望能对学习Python的同学们有所帮助。 文章目录 1. VSCode的介绍和安装 2. 安装插件 2.1 安装中文插件 2.2 安装Python插件 2.3 安装远程插件 3. 远程连接服务器 3.1 配置ssh 3.2 运行代码 3.3 调试代码

weixin_43178406的博客 8万+

你是否了解这些常被问起的问题

你是否了解这些常被问起的问题    最近在网上看到一些类似“Java陷阱一箩筐”、“面试题集及解答”的帖子,看了后,感觉有很多东西的确是我们容易忽略的,而且在一定程度上可以看出对Java的了解程度。但这些帖子都比较乱,而且有些问题的解答我个人认为是不够精确或完全是错误的。为此,我大致整理了一些与Java有关的问题,也增加了一些问题,汇总一起并给出相应的说明。如有不对的地方,请指正。1、try{

somat的专栏 1959

YOLO11改进:轻量级改进 | 通用倒瓶颈(UIB)搜索块结合C3k2二次创新 | 轻量化之王MobileNetV4

通用倒瓶颈(UIB)搜索块替代YOLO11的C3k2

会AI的学姐 293

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

学习笔记整理(部分)

技术要点摘要 对象创建与存储 new操作流程:分配堆内存→调用构造函数→返回对象引用 对象存储:实例在堆区,引用在栈区 Spring创建方式:构造器/工厂方法/XML配置/注解自动装配 性能排查 CPU 100%排查:定位高负载进程→分析线程堆栈→优化问题代码 慢查询优化:检查执行计划→优化索引/SQL→分析服务器资源 缓存与安全 Redis签到设计:使用Bitmap存储,key格式sign:user_id:年月 JWT签名:验证令牌真实性,防篡改 数据结构与测试 ArrayList vs LinkedLi

2301_80381519的博客 586

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

2018年Java面试题整理(持续整理中)

一.基础知识:1)集合类:List和Set比较,各自的子类比较(ArrayList,Vector,LinkedList;HashSet,TreeSet);List:元素是有顺序的,元素可以重复因为每个元素有自己的角标(索引)  |-- ArrayList:底层是数组结构,特点是:查询很快,增删稍微慢点,线程不同步:A线程将元素放在索引0位置,CPU调度线程A停止,B运行,也将元素放在索引0位置,当...

qq_21924011的博客 3491

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

终于整理完了,一套你真正需要的全网最全JAVA面试八股文

今天为大家整理了目前互联网出现率最高的大厂面试题,所谓八股文也就是指文章的八个部分,文体有固定格式:由破题、承题、起讲、入题、起股、中股、后股、束股八部分组成,题目一律出自四书五经中的原文。而JAVA面试八股文也就是为了考验大家的JAVA基础功底,所以强烈建议背诵全文。接触开发至今已有8年多,从实习到带团队,也算总结出了一部分经验!如果分享的东西对读者朋友们来说,有价值,有干货!能够给到帮助!这就是我写这篇文章的目的!

m0_71777195的博客 212

大数据面试知识点整理合辑

重载与重写的区别 重载指的是在同一个类中,函数的方法必须一样但是参数顺序不同,个数不同,类型不同,返回值和访问修饰符可以不一样,发生在编译时。 重写发生在父子类中,方法名必须一样,参数列表必须一致。返回值范围必须小于等于父类,抛出异常范围小于等于父类,访问修饰符的范围必须大于父类。private类型的方法不可以被重写。子类对父类中的方法功能不满意,对该方法进行功能修改。 问题: 为什么返回值的范...

LostStar 380

Java面试题及答案整理( 2025年 6 月最新版,持续更新)

秋招金九银十快到了,发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全~ 这套互联网 Java 工程师面试题包括了:MyBatis、ZK、Dubbo、EL、Redis、MySQL、并发编程、Java面试、Spring、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

2401_89221867的博客 823

Java基础篇--集合(collection)

在之前的文章中,已经发布了常见的面试题,这里我花了点时间整理了一下对应的解答,由于个人能力有限,不一定完全到位,如果有解答的不合理的地方还请指点,在此谢过。 本文主要描述的是java面试中几乎必问的集合内容,java的集合是jdk里面重要的内容,也是我们平时开发过程中最常用到的,所以无论是否为了准备面试,我们都要掌握好集合相关的知识。既然是重点,那就意味着集合类在java面试中的题目会非常多,尤其是hashmap,由于其设计精美,细节优化突出,常常是面试中集合的首选,所以我会把hashmap单独使用一篇文

rqc112233的专栏 298

Java程序员集合框架面试题

三个工作日收到了offer,头条面试体验还是很棒的,这次的头条面试好像每面技术都问了我算法,然后就是中间件、MySQL、Redis、Kafka、网络等等。第一个是算法关于算法,我觉得最好的是刷题,作死的刷的,多做多练习,加上自己的理解,还是比较容易拿下的。而且,我貌似是将《算法刷题LeetCode中文版》、《算法的乐趣》大概都过了一遍,尤其是这本。

2303_77877769的博客 671

变态级JAVA程序员面试32问

前面部分是问题,后面部分是一些网友给的答案,大家参考吧:****************************原题部分**************************************第一,谈谈final, finally, finalize的区别。第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以imple

oicqren的专栏 812

京东offer已到手!分享我结合几次大厂的面试整理出的366题汇总:并发+JVM+HTTP+微服务+数据库

前言 面试:如果不准备充分的面试,完全是浪费时间,更是对自己的不负责。 今天给大家分享下我整理的BATJava架构面试专题及答案,其中大部分都是大企业面试常问的面试题,可以对照这查漏补缺,当然了,这里所列的肯定不可能覆盖全部方式,不过也希望能对即将找工作的朋友起到一些帮助! 面试题以及分类整理如下: Java基础: 接口与抽象类的区别? Java中的异常有哪几类?分别怎么使用? 常用的集合类有哪些?比如List如何排序? ArrayList和LinkedList内部的实现大致是怎样的?他们之间的区别和优缺

资料免费分享,点击名片 456

每日一面---真实面试题---1

先看原题,自己心里默想一遍答案再滑到后面对比答案。答案来源于网络,欢迎指正,共同进步 文章目录一、原题二、答案 一、原题 1.常见的集合类 2.哪些是线程安全的? 3.hashtable和concurrenthashmap如何确保线程安全的?他们的实现和区别是什么? 4.多线程中,线程池的几个核心参数是什么?线程池的工作流程呢? 5.线程池中 corePoolSize和maximumPoolSize 的区别 6.常见的池化技术?池化技术的优点? 7.hashmap的实现原理?(我blahblah讲了很多,可

Negen.H 1万+
上一篇: HashMap源码分析整理
下一篇: ArrayList源码分析整理
PdKingLiu
博客等级 码龄9年 89粉丝 92原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值