• hashmap源码面试分析


    HashMap源码问题解析

    1. 问: 说一说对hash的理解
      答: hash是对任意长度的输入输出为相同长度的输出
    2. 问: hash算法的问题
      答: hash冲突问题
    3. 问: hash冲突是否可以避免
      答: 不可以避免,只能尽量规避
    4. 问: 优秀的hash算法有什么特性
      答: 1. 任何微小的变化hash的结果都不相同
      2. hash不可逆
      3. 长字符串的hash效率要高
      4. hash值尽量散列平均
      5. 相同的值hash值相同
    5. 问: hashmap的数据结构
      答: 以1.8为例 数组+链表+红黑树 数据存储在node对象中,node中有key value next hash等字段
    6. 问: 散列表的初始长度是多长
      答: 默认是16
    7. 问: 散列表是什么时候创建
      答: 第一次put的时候创建(懒加载)
    8. 问: 默认的负载因子是多少,负载因子的作用
      答: 空参构造创建的hashmap的负载因子是0.75,作用是当node数量大于数组长度的0.75的时候进行resize扩容
    9. 问: 链表转化红黑树需要什么条件
      答: 需要两个条件 链表长度大于等于7并且数组的长度大于等于64才进行树化
    10. 问node对象的hash值是怎么得来的,为什么这么操作
      答: 是根据key的hashcode值在与key的hashcode的高16位异或操作得来的,是为了在数组中分布的更加随机均匀,因为hashmap的数据计算数组下标的方法是(tab.length-1)&hash,tab.length大部分情况下小于2^16也就是25536(规则表明tab.length必须是2的次方数) 所以大部分情况下是hash的低16位参与运算,为了让hash更加随机均匀,多一次与key的hashcode异或运算来加强hash值的随机分布,让hashcode没一位都参与到运算中
    11. 问: hashmap put方法的详细流程
      答: key经过寻址查到在数组中的下标
      1. 如果数组下标为null直接存入node
      2. 如果不为空比较值 相同覆盖 如果是树则按红黑树规则放入 如果不是树 进行尾插链表长度大于等于7并且数组长度大于64转树 长度超过阈值resize
    12. 问: 红黑树的原则
      答: 1. 叶子节点到根节点的路径黑色节点数量一致(黑高)
      2. 叶子节点都是黑色的
      3. 不能有两个红色的节点相连
      4. 根节点一定是黑色的
      5. 插入的节点一定是红色的(红插)
    13. 问: jdk1.8hashmap为什么引入红黑树
      答: 因为链表太长的话会导致查询效率降低hash的目的是尽量实现o(1)的,链接寻址很慢
    14. 问: hashmap什么时候会触发扩容
      答: put操作的时候,有个字段记录数据量当大于扩容阈值的时候扩容
    15. 问: hashmap怎么扩容
      答: 数组长度一定是2的次方数,每次扩容是原先长度左移一位<<1
    16. 问: 老数组的数据怎么迁移到新数组中
      答: 1. hash未冲突的直接根据新的数组长度计算放入即可
      2. 如果已经成红黑树
      3. 已经是链表未成树会hash&旧数组长度(oldcap) 等于0的放低链 不等于的放高链 低链的放原来的index 高链放原来的index+oldlength的位置
      解释:在hashmap寻址算法计算得出(hash&(length-1)) 一条链表的数据肯定会分成两个链表 位置一个是原index 另一个是原index+oldlength
      原先的length长度为16 二进制为10000 那么length就是16-1 =15(1111)就是hash&1111 以第15个桶为例,那么hash的值就可能是01111或者11111
      扩容后length变为32 二进制为100000 hash&11111 那么如果15这个桶位置原先hash是01111的node就放在他原先的15的这个位置,hash为11111的就放在
      32这个桶的位置
      01111 & 10000 = 0 这个放15这个位置
      11111 & 10000 != 0 放32 15+16 = 31这个位置
  • 相关阅读:
    git 的常用命令(未完待补充)
    Mysql占用内存过高参数优化
    mysql安全基线设置
    redis安全基线设置
    centos7安全基线设置
    检查shell脚本
    redis安装和配置
    TIME_WAIT状态全是3306解决办法
    PHP message: PHP Fatal error: Allowed memory size of 134217728 bytes exhausted 错误
    tcp的三次握手和四次挥手(二)
  • 原文地址:https://www.cnblogs.com/isnotnull/p/13916791.html
Copyright © 2020-2023  润新知