HashMap高频面试知识点

news2024/9/19 21:50:43
  • HashMap
    • HashMap是基于hash表的一种数据结构,用于存放键值对,核心就是把hash值映射到数组的索引位,通过数组+链表(JDK1.8开始通过数组+链表+红黑树)解决Hash冲突。
      • 因为当hash冲突较多时,链表中元素增加,查询插入等操作的时间复杂度从O(1)——>O(n)
      • 而二叉树的时间复杂度O(log n)
    • 数组下标=数组长度-1&hash(key)不同的key可能会产生相同的hash值,从而导致hash冲突,jdk1.7之前链表采用头插法,但是多线程环境下可能导致环路从而引发死循环。Jdk1.8之后采用尾插法
    • HashMap初始容量16,负载因子0.75,那么阈值就是16*0.75=12,超过12就会触发2倍扩容操作
    • 扩容时,每个元素存储位置将根据新的数组容量重新计算hash值,并移动到新的数组中,这个操作加rehashing;
      • Jdk1.7之前,就是存粹的把所有元素重新hash,然后一个一个搬过去
      • Jdk1.8之后,旧数组长度16即010000,新数组长度32即100000
      • 而数组下标=(数组长度-1)&hash(key),16-1为001111,32-1为011111
      • 所以重点就在于key的hash值从右往左第五位是否为1,如果为1那么久需要搬迁,新数组下标=原下标+旧数组长度16。
      • 如果是0的话,怎么与都是0,所以新数组高位按位与操作不受影响(注意:与操作有0为0,全1为1),那就说明在原位置,不需要迁移。减少了一部分hash计算的开销
    • 从jdk1.8开始,为了优化hash冲突时的查询性能,
      • 当链表的数量大于等于8并且数组的大小大于等于64,链表就会转换成红黑树。
      • 当数组长度小于64,则选择扩容。
        • 当数组容量较小,过早的转换成红黑树,可能很快又会触发数组扩容,导致没必要过早树化的开销。
        • 另外红黑树比链表更占内存。
      • 树的元素低于6的时候,树就会转换成链表。
    • 常见的处理hash冲突的办法:拉链法,开放寻址法,再哈希法
  • HashMap VS Hashtable
    • 线程安全
      • HashMap 线程不安全,多线程环境下会产生数据一致性问题。
      • Hashtable 线程安全,内部的方法采用了synchronized,保证了多线程并发的安全性。
    • 性能差异
      • HashMap 由于没有线程同步的开销,所以性能优于Hashtable。
      • Hashtable 由于方法的锁机制,性能不如HashMap。
    • 空值null
      • HashMap 允许一个null键,多个null值。
      • Hashtable 键值都不允许null,会报空指针异常。
  • ConcurrentHashMap
    • ConcurrentHashMap是Hashtable的替代方案,读操作的无锁化写操作的分段锁机制提高了并发的性能,避免了全局锁的瓶颈。性能优于Hashtable。
    • JDK1.7 ConcurrentHashMap
      • 采用的是分段锁,每个Segment是独立的。默认16个,所以最多支持16个并发。
      • 采用数组+链表
      • 原理 :
        • 先通过key的hash判断应该在哪个Segment的数据下标,然后对这个Segment加锁(Segment继承ReentrantLock,自带加锁的能力)
        • 然后再次通过key的hash得到Segment里HashEntry的数组下标,接下去的步骤同HashMap
      • 扩容:
        • 扩容时针对单个Segment进行扩容的,不会影响其他的Segment,每个Segment都有自己的负载因子。因此它并不是针对整个ConcurrentHashMap扩容的。
      • Size大小:先尝试不加锁三次计算sum值,如果三次值相同,就直接返回;如果不同就对每个Segment进行加锁计算
      • 缺陷:Segment数组一旦初始化了之后,就不会扩容,导致对并发度控制过于死板(只有HashEntry才会扩容
      • 结构如下

  • JDK1.8 ConcurrentHashMap
    • 移除了Segement的概念,锁的粒度更加细化,通过CAS进行写入操作,只有在更新链表和红黑树的节点时才会用到synchronized,并且只锁链表或树的头节点(相当于Node数组的每个节点都能上一把锁,并发度更高了)。
    • 数组+链表+红黑树
    • 原理:
      • 先计算key的hash后得到数组下标,如果数组下标没有Node,就通过CAS塞入新的Node。
      • 如果当前数组下标存在Node,那么则先通过Synchronized对这个Node加锁。
      • 然后再判断key是否相等,key相同就替换value, 反之就Hash冲突(操作同HashMap)
    • 扩容:
      • Jdk1.8 取消了Segment,因此整个ConcurrentHashMap数组都会被扩容。通过CAS操作确保线程的安全,避免锁住整个数组,并且扩容时多个线程共同参与,逐步迁移就数据到新数组中。
      • 在putVal()的时候,如果无限循环的内部正在扩容,就调用helpTransfer()帮忙一起扩容,扩容完毕后还会向新的数组中插入元素的。

  • Size大小:jdk1.8中,搞了一个数组CounterCell ,每次put和remove的时候,先通过CAS修改baseCount的值,如果CAS失败,则说明存在线程竞争,就要通过hash到对应的CounterCell数组的下标下维护对应的数量;最终size=baseCount+所有的CounterCell
  • ConcurrentHashMap volicate关键字保证了可见性,使得get的时候不用加锁也能线程安全。
  • ConcurrentHashMap key 和value都不支持null。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2147099.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言进阶【4】---数据在内存中的存储【1】(你不想知道数据是怎样存储的吗?)

本章概述 整数在内存中的存储大小端字节序和字节序判断练习1练习2练习3练习4练习5练习6 彩蛋时刻!!! 整数在内存中的存储 回忆知识:在讲操作符的那章节中,对于整数而言咱们讲过原码,反码和补码。整数分为有…

JAVA同城生活新引擎外卖跑腿团购到店服务多合一高效系统小程序源码

🚀同城生活新风尚!一站式高效系统,让日常更便捷🛍️ 🍽️【开篇:同城生活,一触即发】🍽️ 在这个快节奏的时代,同城生活的便利性与效率成为了我们追求的新风尚。想象一下…

C++ —— 关于vector

目录 链接 1. vector的定义 2. vector的构造 3. vector 的遍历 4. vector 的扩容机制 5. vector 的空间接口 5.1 resize 接口 5.2 push_back 5.3 insert 5.4 erase 5.5 流插入与流提取 vector 并不支持流插入与流提取,但是可以自己设计,更…

[NSSCTF 2022 Spring Recruit]ezgame

打开题目环境是一个游戏: 直接F12开始审计源代码: 这里说拿到65分以后可以得到flag,这里因为游戏太菜选择直接篡改分数: 在控制台输入scorePoin10000就可以改变当次得分,等到游戏结束就能得到flag。

心觉:成功学就像一把刀,有什么作用关键在于使用者(二)

Hi,我是心觉,与你一起玩转潜意识、脑波音乐和吸引力法则,轻松掌控自己的人生! 挑战每日一省写作174/1000天 上一篇文章讲了成功学到底是个啥 是如何起作用的 为什么有些人觉得没有用? 今天我们再展开来剖析一下这…

链表--(1)链表的概念

前言引入 之前我们学习了数组这一概念,使用数组可以在编程时增加程序的灵活性。但在c语言中不允许定义动态数组的类型也不能随意调整数组的大小,往往会导致内存空间的浪费。由此我们推出链表。链表是动态进行内存分配的一种结构,它可以随时为其结点分配需要的存储空间也方便…

Vscode搭配latex简易教程

1. 找镜像网站下载texlive的iso文件 清华源镜像 下载之后直接打开iso文件,打开install-tl-windows.bat文件,进行安装即可,安装大概30分钟左右 2. VScode端配置 2.1 下载这三个插件 2.2 打开设置 2.3 追加内容到配置json文件当中 // Latex…

《深入理解JAVA虚拟机(第2版)》- 第12章 - 学习笔记

第12章 Java内存模型与线程 12.1 概述 TPS是用来衡量一个服务性能好坏高低的重要指标值。TPS是Transactions Per Second的缩写,用来表示每秒事务处理数,即服务端每秒平均能碰响应的请求数。 12.2 硬件的效率与一致性 处理器与内存的运算效率差了好几…

使用阿里OCR身份证识别

1、开通服务 免费试用 2、获取accesskay AccessKeyId和AccessKeySecret 要同时复制保存下来 因为后面好像看不AccessKeySecret了 3.Api 参考 https://help.aliyun.com/zh/ocr/developer-reference/api-ocr-api-2021-07-07-recognizeidcard?spma2c4g.11186623.0.0.7a9f4b1e5C…

园区网基础组网保姆级(mstp,vrrp,irf,eth-trunk,route-policy,ospf,bgp,rbm,nat,mlag等等)

本文实验使用模拟器:H3C HCL 5.10.2版本 一、园区核心/接入架构1.1.三层架构1.2.二层架构二、园区核心 To 接入实践2.1.MSTP+VRRP派系2.1.1.MSTP+VRRP配置2.1.2.MSTP+VRRP验证2.2.IRF+Eth-Trunk派系2.2.1.IRF+Eth-Trunk配置2.3.两种派系的对比2.4.VXLAN结构三、园区核心/出口架…

观《中国数据库前世今生》有感:从历史中汲取未来的力量

观《中国数据库前世今生》有感:从历史中汲取未来的力量 中国数据库技术的起步与发展 观看了《中国数据库前世今生》后,我对于中国数据库技术的历史变迁有了更深刻的理解。作为一名有一年开发经验的程序员,这部纪录片让我对中国数据库行业从8…

828华为云征文 | 云服务器Flexus X实例,搭建上线前后端项目

828华为云征文 | 云服务器Flexus X实例,搭建上线前后端项目 项目搭建 演示使用华为云服务器Flexus X实例搭建上线前后端项目黑马vue电商后台管理系统 项目GitHub链接:https://github.com/Minori-ty/vue_shop.git 1、购买华为云 Flexus X 实例 Flexus云服…

.Net Core 生成管理员权限的应用程序

创建一个ASP.NET Core Web API项目 给解决方案设置一个名称 选择一个目标框架,这里选择的是 .NET 8.0框架 在Porperties文件夹中添加一个app.manifest文件 设置app.manifest文件属性,生成操作设置为嵌入的资源 双击解决方案名称,编辑WebAppli…

JS实现树形结构数据中特定节点及其子节点显示属性设置的技巧(可用于树形节点过滤筛选)

大家好,今天我要分享的是如何在树形结构的数据中,根据特定条件设置节点及其所有子节点的显示属性。在实际项目中,这种需求非常常见,特别是在需要动态展示和隐藏节点的情况下。下面我将通过一个具体的示例来讲解实现过程。 需求分析…

(史上最全)线程池

线程池 文章目录 线程池一,前言二,线程池三,参数四,线程池的实现原理5.线程池的使用案例(自定义线程池)6.使用Executors 创建常见的功能线程池1.固定大小线程池2.定时线程3.可缓存线程池4.单线程化线程池 一,前言 虽然…

Prometheus 上手指南

文章目录 Prometheus 相关概念Prometheus 的特点Prometheus 架构数据模型 Datemode使用场景 指标类型 Metric type适用场景 作业和实例 Jobs and instances使用场景 Prometheus 安装Prometheus 配置prometheusalertmanager Grafana 可视化Grafana 安装Grafana 配置选项Grafana …

假期学习--iOS 编译链接

iOS 编译链接 编译流程 四步: 1.预处理 2.编译 3.汇编 4.链接 大概的步骤如下: 预处理 作为编译的第一步,将.m文件转换为.i文件 ; 预处理是要处理源代码中所有以#开头的所有预编译指令 ; 规则如下&#xff1…

更换UFS绑定固件与“工程固件”的区别 小米10s机型更换cpu绑定包对比 写入以及修复基带

目前机型的安全机制越来越高。机型cpu与字库存在绑定关系。主板cpu如损坏需要更换。换新cpu后就需要刷写底层绑定包来修复 。今天的博文将为大家带来UFS绑定包与工程固件的区别以及写入 修复基带的步骤解析 通过博文了解 1💝💝💝-----更换UFS绑定包与工程固件的区别 2…

利士策分享,赚钱与体重:一场关于生活平衡的微妙探索

利士策分享,赚钱与体重:一场关于生活平衡的微妙探索 在当今社会,赚钱与体重,这两个看似风马牛不相及的概念, 却在无形中交织着人们的生活轨迹。 它们不仅仅是数字上的增减,更是个人选择、生活方式乃至心理…

Mycat搭建分库分表

分库分表解决的问题 单表数据量过大带来的性能和存储容量的限制的问题: 索引效率下降读写瓶颈存储容量限制事务性能问题分库分表架构 再搭建一对主从复制节点,3307主节点,3309从节点配置数据源 dw1 , dr1,创建集群c1创建逻辑库 CREATE DATAB…