高频面试八股文原理篇(一)hashmap原理相关

news2024/11/14 14:37:02

目录

引言

面试题:hashmap原理

原理

JDK7时HashMap的数据结构

jdk8中hashMap数据结构

hashMap怎么设置初始值的大小

jdk7和jdk8中HashMap的区别

为什么放在hashMap集合key部分的元素需要重写equals方法?

concurrenthashmap为什么线程安全

高频面试题

参考


引言

        目前各大互联网大小厂往往喜欢考察原理性的东西。 这里总结高频出现的问题,供大家参考。

面试题:hashmap原理

HashMap基于Map接口实现,元素以键值对的方式存储,并且允许使用null建和null值,因为key不允许重复,因此只能有一个键为null,另外HashMap不能保证放入元素的顺序,它是无序的,和放入的顺序并不能相同

原理

其底层数据结构是数组称之为哈希桶,每个桶(bucket)里面放的是链表,链表中的每个节点,就是哈希表中的每个元素。

通过hash的方法,通过put和get存储和获取对象。

  • 存储对象时,我们将K / V传给put方法时,它调用hashCode计算hash从而得到bucket位置,进一步存储,HashMap会根据当前bucket的占用情况自动调整容量 (超过 Load Facotr则resize为原来的2倍)。
  • 获取对象时,我们 K传给get,它调用hashCode()计算hash从而得到bucket位置,并进一步调用equals()方法确定键值对。如果发生碰撞的时候,Hashmap通过链表将产生碰撞冲突的元素组织起来,在JDK8中,如果一个bucket中碰撞冲突的元素超过8个,则使用红黑树来替换链表,从而提高速度。

 

因其底层哈希桶的数据结构是数组,所以也会涉及到扩容的问题

当HashMap的容量达到threshold域值时,就会触发扩容。扩容前后,哈希桶的长度一定会是2的次方。这样在根据key的hash值寻找对应的哈希桶时,可以用位运算替代取余操作,更加高效。

而key的hash值,并不仅仅只是key对象的hashCode()方法的返回值,还会经过扰动函数的扰动,以使hash值更加均衡。

JDK7时HashMap的数据结构

1、在JDK7之前,hashmap底层采用数组+链表的数据结构来存储数据
2、插入数据采用头插法,头插法效率更高,不需要去遍历链表。插入结点后将头结点移到数组下标的位置

HashMap主要是用数组来存储数据的,我们都知道它会对key进行哈希运算,哈希运算会有重复的哈希值,对于哈希值的冲突,HashMap采用链表来解决的。

jdk8中hashMap数据结构

1、JDK8以后hashmap的底层数据结构由数据+链表+红黑树实现
2、jdk8以后插入数据采用尾插法。因为引入了树形结构,总是要遍历的

JDK8之后,如果哈希表单向链表中元素超过8个,那么单向链表这种数据结构会变成红黑树数据结构。当红黑树上的节点数量小于6个,会重新把红黑树变成单向链表数据结构:

hashMap怎么设置初始值的大小

如果你在创建的时候没有设置初始值大小,那么它的默认容量是16。
如果你设置了一个初始容量,它会先进行一个判断,判断这个值是不是2的次幂,如果不是将会把容量转化成为2的次幂大小。比如说你设置的容量是27,那么创建的HashMap实际容量是32。

jdk7和jdk8中HashMap的区别

1、jdk8中当链表长度大于8时会将链表转化成为红黑树
2、节点插入顺序不同,jdk7采用头插法,而jdk8采用尾插法
3、hash算法的简化

为什么放在hashMap集合key部分的元素需要重写equals方法?

因为equals默认比较是两个对象内存地址

concurrenthashmap为什么线程安全

  • ConcurrentHashMap 在 JDK 1.7 时使用的是数据加链表的形式实现的,其中数组分为两类:大数组 Segment 和小数组 HashEntry,而加锁是通过给 Segment 添加 ReentrantLock 锁来实现线程安全的。
  • 而 JDK 1.8 中 ConcurrentHashMap 使用的是数组+链表/红黑树的方式实现的,它是通过 CAS 或 synchronized 来实现线程安全的,并且它的锁粒度更小,查询性能也更高。

在JDK 1.7中,ConcurrentHashMap采用了分段锁技术来保证线程安全。具体地,ConcurrentHashMap将整个Map分为若干个Segment,每个Segment拥有自己的锁。不同的线程可以同时访问不同的Segment,从而实现了并发访问。当对某个Segment进行修改时,只需要锁住该Segment的锁,而不用锁住整个Map,从而减少了锁竞争和锁持有时间,提高了并发性能。

 

在JDK 1.8中,ConcurrentHashMap对内部数据结构进行了优化,采用了基于CAS操作的无锁算法来实现线程安全。具体地,ConcurrentHashMap将整个Map分为若干个Node数组,每个Node包含一个key-value对和一个指向下一个Node的引用。当多个线程并发地访问和修改Map时,采用CAS操作来保证原子性和可见性。当需要对某个Node进行修改时,首先需要通过CAS操作将该Node的状态从“未修改”改为“修改中”,然后进行修改操作,最后通过CAS操作将该Node的状态从“修改中”改为“修改完成”。这样可以避免锁竞争和死锁等问题,同时也提高了并发性能。

 


参考链接:https://juejin.cn/post/7205582597392252989

为什么ConcurrentHashMap是线程安全的?_concurrentmap为什么线程安全_柒柒Java的博客-CSDN博客

高频面试题

HashMap的工作原理是什么?

HashMap中的“死锁”是怎么回事?

 解决:使用ConcurrentHashMap

HashMap中能put两个相同key吗?为什么?

HashMap中的键值可以为null吗?原理? 当key==null的时候,key的hashcode = 0;不会抛出空指针异常

HashMap扩容机制?

参考

 JDK8中HashMap的工作原理剖析-腾讯云开发者社区-腾讯云

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

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

相关文章

Linux文件的扩展属性

文件属性 Linux文件属性分为常规属性与扩展属性,其中扩展属性有两种:attr与xattr. 一般常规的文件属性由stat API 读取,一般是三种权限,ower, group,时间等。 扩展属性attr 用户态API ioctl(fd, FS_IOC32_SETFLAGS …

从零开始学习JavaScript:轻松掌握编程语言的核心技能②

从零开始学习JavaScript:轻松掌握编程语言的核心技能② 一,JavaScript 函数1.1 JavaScript 函数语法1.2 局部 JavaScript 变量1.3 全局 JavaScript 变量 二,JavaScript 作用域2.1JavaScript 局部作用域 三,JavaScript 事件3.1HTML…

Linux——磁盘文件的理解 + inode详解 + 软硬链接 +动静态库

索引 磁盘文件的理解inode软硬链接动静态库理解动态链接与地址无关生成动静态库使用静态库使用动态库动态链接再次理解! 磁盘文件的理解 之前讲述的都是内存级的文件,但是系统中最多的还是磁盘级的文件,大量的文件自然也需要被管理&#xff…

【算法】08 耦合 Lorenz 63 模式的参数估计实验

摘要 本实验通过建立基于耦合 Lorenz 63 模式的孪生实验框架,使用集合调整卡尔曼滤波器EAKF实现参数估计,测试参数估计开始的不同阶段、观测误差、同化频率、协方差膨胀等方法细节对于参数估计结果的影响。 耦合 Lorenz 63 模式 Lorenz 63 模式是Lore…

Postman实战:轻松搞定接口自动化测试

随着移动互联网的发展,接口自动化测试已经成为软件测试领域中不可或缺的一部分。而作为最流行的API开发工具之一,Postman凭借其简单易用、功能强大的特点赢得了越来越多开发者和测试人员的青睐。 想要掌握Postman的接口自动化测试技能,只需要…

JDK 下载与安装

首先下载 jdk 最新版本。可以去 http://java.sun.com/j2se/1.4.2/download.html 版本一:适合 win7oracle 版本 java 下载最新的 jdk 版本, 打开界面后。选择 J2SE v 1.4.2_08 SDK 拦目下面的 Download J2SE SDK, 然后选择 Accept License…

6设计指令流水线-3【FPGA模型机课程设计】

6设计指令流水线-3【FPGA模型机课程设计】 前言推荐6设计指令流水线-3安排测试与结果 指令流水线理论MIPS的一种简单实现基本的MIPS流水线 指令流水线实现MIPS五段流水CPU设计 基于单周期CPU的流水线设计乘除流水线的设计原子流水线的设计代码设计EX_Mem 附录0 框架 最后 前言 …

理论+实操|一文掌握 RFM 模型在客户数据洞察平台内的落地实战

确定用户价值是整个用户运营过程中极其重要的一环。传统的工作流程中,业务人员向数据部门提出数据需求,等待返回结果后再进行价值分析是主要的准备工作,但这个过程非常耗时。为了提高工作效率,业务人员经常会基于自己对用户的理解…

链表【+逆序链表】、循环队列、堆栈讲解(链表头和尾插法)

文章目录 一、链表(1)链表简单介绍(2)链表的创建(3)数据的插入【1】头插法【2】尾插法 (4)链表的删除(5)源代码实现 二、队列(循环队列&#xff0…

热闹炸了,公司居然公然鼓励员工玩游戏

池塘边的榕树上,知了在声声叫着夏天,操场边的秋千上,只有蝴蝶停在上面..........每逢儿童节到来之时,东东总是会回想起儿时的自己,面对那即将到来的节日,兴奋异常。 因为在这一天全校会给我们放上一天假&am…

Android进阶之路 - 字体阴影、文字阴影

最近几个月都挺忙,忙着工作,忙着成长… 一直以来我认为在开发中首当其冲的肯定是需求、功能,然后才是UI细节;所以我自己一般不太会去深究一些看不明显的UI,不过这俩日同事提醒我文字有阴影效果,细看之下果然…

Java000——超好用的工具推荐

下面介绍工具直接安装即可,基本上都是一路next(有需要选择安装路径则选择自己的安装目录即可) Everything Everything用于搜索电脑本地文件、文件夹,快速高效 下载地址 Snipaste截图工具 下载地址 notepad 轻量级文本编写查看…

C++11 右值引用

文章目录 一. 左值?右值?二. 右值引用的使用三. 万能引用&完美转发四. 移动构造&移动赋值结束语 一. 左值?右值? C中,对于左值,右值,我们可能会理解为 赋值符号左边是左值&#xff0c…

木棒 DFS经典题 剪枝优化 满注释版 java

🍑 算法题解专栏 🍑 题目地址 乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过 50 50 50 个长度单位。 然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始…

【数据结构与算法】最小生成树之普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法

🌱博客主页:大寄一场. 🌱系列专栏:数据结构与算法 😘博客制作不易欢迎各位👍点赞⭐收藏➕关注 目录 前言 一、最小生成树的概念 二、最小生成树的求解方法 三、练习题 四、最小生成树在实际应用中的例…

返回类对象时,什么时候调用拷贝构造函数,什么时候会进行返回值优化(RVO)

#include<iostream> using namespace std;class Person { public:Person(){}Person(int age){m_Age age;}Person(const Person& p){cout << "拷贝构造函数" << endl;}Person fun(){cout << "fun this" << " "…

一步步教你如何剪辑出专业水平的视频

1. 视频字幕制作。媒体梦工厂软件提供了强大的字幕制作功能&#xff0c;可以自主设计字幕的颜色、大小、字体等属性&#xff0c;使字幕更加具有视觉冲击力。"媒体梦工厂软件是一款广受欢迎的影视后期制作软件&#xff0c;自从软件发布以来在行业内有着广泛的应用。本文将会…

使用redis模拟手机验证码发送及消费者与生产者案例

规定一个手机号一天只能请求三次验证码&#xff0c;且每次请求的验证码只有一分钟就会过期 package com.doit.demo;import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool;import java.util.Random; import java.util.Scanner;public class PhoneNum {publ…

Spark基础入门篇 | MapReduce原理 + Spark原理 + PySpark环境搭建 + 简单实战

&#x1f604; 之前简单了解过Spark&#xff0c;并简单用别人的代码跑过pyspark的数据处理和模型的分布式推理&#xff0c;但没做系统的总结&#xff0c;那这篇博客就对Spark做个基础入门讲解&#xff0c;看完基本就算基础入门了&#xff0c;后面再实操就会轻松一些。 文章目录…