精华内容
下载资源
问答
  • 文章目录Redis 学习笔记-哈希桶和底层数据结构1.Redis 基本数据类型2.Redis 底层数据结构类型3.Redis 基本数据类型和底层数据结构关系示意图4.key 是如何查找到哈希桶4.1 哈希表(HashTable)原理图4.2 哈希桶和数据...

    Redis 学习笔记-哈希桶和底层数据结构

    前面文章介绍了 Redis 基本数据类型和这些数据类型对应的一些操作,知道了 Redis 很快的原因是 内存数据结构,这篇文章就围绕 数据结构 来介绍一下 Redis 底层有哪些数据结构,为什么这些数据结构会提升访问速度,学习这些底层数据结构将会加深对 Redis 设计原理的理解。

    1.Redis 基本数据类型

    • String(字符串)
    • Set(集合)
    • Sorted Set(有序集合)
    • List(列表)
    • 散列表(哈希)
    • GEO
    • HyperLogLog
    • Stream(流)

    2.Redis 底层数据结构类型

    • 简单动态字符串
    • 双向链表
    • 压缩列表
    • 哈希表
    • 跳表
    • 整数集合

    3.Redis 基本数据类型和底层数据结构关系示意图

    • String 类型对应 简单动态字符串
    • List 类型对应 双向链表压缩列表
    • Hash 类型对应 压缩列表散列表
    • Sorted Set 类型对应 压缩列表跳表
    • Set 类型对应 散列表整数集合
      在这里插入图片描述

    Tips:GEOHyperLogLogStream 后续文章单独讨论。

    4.key 是如何查找到哈希桶

    首先 key 需要经历 全局哈希表 找到 哈希桶,关于哈希表(HashTable) 的原理可以参考我之前写的文章来了解,哈希表也叫散列表,这里简单介绍一下 哈希表(HashTable) 的原理,每一个 key 可以通过哈希计算变成一个较大的整数,然后通过数学模型取就可以对应到某个数组中的索引,然后通过这个索引值可以快速找到数组中的元素,这个元素可以称为 哈希桶 元素,如下图所示简单展示了哈希表(HashTable)的实现原理:

    4.1 哈希表(HashTable)原理图

    在这里插入图片描述

    Tips:如上图所示的数组可以称为一个哈希桶Redis 中解决哈希冲突时采用拉出一个链表来解决的。

    4.2 哈希桶和数据类型对应原理图

    在这里插入图片描述

    4.3 渐进式 rehash

    上述哈希桶需要考虑一个问题,当 key 的数量比较庞大时,可能导致哈希桶的数量不合理(即哈希取时的素数不合理),从而出现哈希冲突比较多的情况,直接带来的影响是哈希桶中的 entry 链表过长,众所周知,当链表太长的时候查找元素需要遍历(复杂度O(N))才能找到 key 对应的那一个 entry,为了解决这个问题 Redis 设计者采用了 渐进式 rehash,它的目的是重构哈希桶的数量,让哈希桶数量更加合理,使 key 对的 entry 在哈希桶中分布更加均匀,从而从概率角度上减少 entry 链表的长度,具体实现逻辑如下:

    • Redis 设计了 2 个全局哈希表,记作 哈希表A哈希表B,最开始默认使用哈希表A,哈希桶记作是 Ma哈希表B 不分配内存,等待调度。
    • 哈希表A 中的哈希桶冲突比较频繁,且数量比较大(某个阈值)的时候,就会启用 哈希表B,并且哈希表B的哈希桶数量Mb大于Ma(具体要依据数学模型)。
    • 哈希表B 建立好之后就需要考虑将哈希表A 的数据转移到 哈希表B 中,如果有大量的数据迁移可能会导致 Redis 线程阻塞导致业务停摆,这个时候 Redis 采用了 渐进式 rehash
    • 渐进式 rehash 可以简单理解为每次访问 哈希表A 数据的时候顺带带一点数据出来给 哈希表B,整个过程是 渐进 完成的,不会影响业务在正常运行。
    • 数据转移完成之后就会释放 哈希表A 的内存,等待下次同样的情况时,重构哈希桶使用。

    5.底层数据结构

    对于 字符串(String) 来说,找到哈希桶就可以直接对它操作(增删改查等)简单动态字符串,而对于 ListHashSorted SetSet 这些数据类型来说,找到哈希桶之后还需要对应到 双向链表压缩列表哈希表跳表整数集合这些底层数据结构中的,下面简单介绍一下几种数据结构:

    5.1 双向链表示意图

    在这里插入图片描述

    5.2 压缩列表

    压缩列表(ziplist) 实际是一个字节数组,它的设计目的是为了节约内存,和普通数组不同的是在数组头部会有三个字段,分别是 zlbytes(列表长度)zltail(列表尾部偏移量)zllen(entry 的个数),在 压缩列表 的尾部还会有 zlend(结束)字段,示意图如下图:
    在这里插入图片描述

    5.3 跳表

    在这里插入图片描述

    5.4 不同数据结构时间复杂度

    在这里插入图片描述

    6.小结

    Redis 中的数据结构比较丰富,全部熟练地记住所有的操作比较困难,但掌握其底层数据结构原理之后,在如何选择合适的数据类型时能有一个理性地推断,而且也能根据这些原理合理地选择数据类型。

    扫码关注
    在这里插入图片描述

    展开全文
  • Redis 数据结构哈希表 超实战追 - 女生技术 抠: .x. Redis 字典底层使用哈希表实现说到哈希表大家应该能联想到 HashMap 或者是 Hashtable 也应该能联想到 key value 存储形式 以及哈希表扩容哈希算法等知识点...
  • HashSet:底层数据结构哈希表

    千次阅读 2015-10-08 23:27:35
     * HashSet:底层数据结构哈希表  * HashSet是如何保证元素唯一性呢?(ArrayList只依赖equals)  * 是通过元素两个方法,hashCode和equeals来完成  * 如果元素HashCode值相同,才会判断equals是否为...
    /*
     * HashSet:底层数据结构是哈希表
     * HashSet是如何保证元素的唯一性呢?(ArrayList只依赖equals)
     * 是通过元素的两个方法,hashCode和equeals来完成
     * 如果元素的HashCode值相同,才会判断equals是否为true
     * 否则不会调用equals.
     * 注意:对于判断元素是否存在,以及删除等操作,依赖的方法时元素的hashCode和equals
     * 
     */
    public class HashSetDemo {
    public static void main(String[] args) {
    HashSet hs=new HashSet();
    hs.add("java1");
    hs.add("java2");
    hs.add("java3");
    hs.add("java4");
    Iterator it=hs.iterator();
    while(it.hasNext()){
    System.out.println(it.next());
    }
    }
    }
    展开全文
  • 什么是哈希表呢? 哈希表底层使用的也是数组机制,数组中也存放对象,而这些对象往数组中存放时的位置比较特殊,当需要...哈希表的数据结构:(图片来自百度词条) 加载因子:表中填入的记录数/哈希表的长度 ...

    什么是哈希表呢?

    哈希表底层使用的也是数组机制,数组中也存放对象,而这些对象往数组中存放时的位置比较特殊,当需要把这些对象给数组中存放时,那么会根据这些对象的特有数据结合相应的算法,计算出这个对象在数组中的位置,然后把这个对象存放在数组中。而这样的数组就称为哈希数组,即就是哈希表。

     哈希表的数据结构:(图片来自百度词条)

     

        加载因子:表中填入的记录数/哈希表的长度
        
        加载因子是0.75 代表:
          数组中的16个位置,其中存入16*0.75=12个元素

        如果在存入第十三个(>12)元素,导致存储链子过长,会降低哈希表的性能,那么此时会扩充哈希表(在哈希),底层会开辟一个长度为原长度2倍的数组,把老元素拷贝到新数组中,再把新元素添加数组中

        当存入元素数量>哈希表长度*加载因子,就要扩容,因此加载因子决定扩容时机

     

    存储过程:

    1.首先调用本类的hashCode()方法算出哈希值

    2.在容器中找是否与新元素哈希值相同的老元素,
      如果没有直接存入
      如果有转到第三步

    3.新元素会与该索引位置下的老元素利用equals方法一一对比
      一旦新元素.equals(老元素)返回true,停止对比,说明重复,不再存入
      如果与该索引位置下的老元素都通过equals方法对比返回false,说明没有重复,存入

     

    展开全文
  • 前言一、哈希表是what?这是百度上给出回答:简而言之,为什么要有这种数据结构呢?因为我们想不经过任何比较,一次从...在下面代码演示中,底层就使用了哈希表,使得每一个字母与其在字符串中出现次数是一一...

    前言

    一、哈希表是what?

    这是百度上给出的回答:6ccd58124cab5b2bd29972f2741826da.png8fe391260b3d492e1d4ff57243362494.png
    简而言之,为什么要有这种数据结构呢?
    因为我们想不经过任何比较,一次从表中得到想要搜索的元素。所以就构造出来了哈希表,通过某种函数(哈希函数)使元素的存储位置与它的关键码之间能够建立一一映射的关系,方便我们在查找的时候可以更加快速的查找出来我们想要查找的元素。
    在下面的代码演示中,底层就使用了哈希表,使得每一个字母与其在字符串中出现的次数是一一对应的关系;

    public static void main(String[] args) {
    String s="huddiolabcsjddddop";
    int[] count=new int[26];
    for(char ch:s.toCharArray()){
    int idx=ch-'a';
    count[idx]++;
    }
    System.out.println(Arrays.toString(count));

    • 1

    • 2

    • 3

    • 4

    • 5

    • 6

    • 7

    • 8

    • 9

    二、什么是哈希冲突

    1.为什么会出现哈希冲突

    对于两个数据元素的关键字Ki和Kj(i!=j),但是存在:Hash(Ki)==Hash(Kj),即:不同的关键字通过哈希函数计算出相同的哈希地址,这种现象就成为哈希冲突或哈希碰撞。

    2.哈希冲突能否避免

    首先,我们需要明确一点,由于我们哈希表底层数组的容量往往小于实际上要存储的关键字的数量,(就是我们往往存储的元素的范围不确定的时候,可能会出现有多个元素的哈希地址是相同的),这就造成了哈希冲突是不可避免的,所以我们能做的就是尽量降低冲突率

    三、如何解决哈希冲突

    1.线性探测

    比如给定一个数组,int[] array={4,5,6,9,1,7,44}
    其插入操作:1.通过哈希函数获取待插入元素在哈希表中的位置
    2.如果该位置没有元素则直接进行插入,如果该位置有元素,则使用线性探测法找到下一个空位置进行插入。001d692b1052446d0ef496d6eeb7bdcd.png

    2.拉链法

    100afd6bffdb3f2055f23ebcf1cb6819.png拉链法,可以认为把一个大的集合中的搜索问题转化为小集合中的搜索问题。

    总结

    线性探测法的的效率问题:4e75ae5569183c13889161be72e2ab79.png

    1.对于所有在哈希表中的元素做查找,平均比较次数是多少?
    (1+1+1+1+1+5+1)/7=1.57

    2.对于所有不在哈希表中的元素做查找,平均比较次数是多少?
    (对每一个下标来判断是否是连续的)
    (1+2+1+1+7+6+5+4+3+2)/10=3.2.

    展开全文
  • 底层实现数据结构哈希表

    千次阅读 2019-04-18 18:35:24
    哈希表时要解决两个问题,索引如何设计以及解决哈希冲突(即由键转换索引与之前相同)
  • 哈希表是根据关键码值而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查询速度。这个映射函数叫做散列函数,存放记录用数组叫做散列表。 二. 哈希表底层 三. 代码 ...
  • HashMap集合底层哈希表/散列表的数据结构 哈希表数据结构哈希表是一个数组和单向链表结合体 哈希表结合了数组和单向链表优点,查询效率和增删效率都很高 哈希表:一维数组,数组中每一个元素都是一个单向...
  • 哈希表底层深入

    2017-06-23 09:43:00
    1.哈希表的底层结构?Java中的HashSet和HsahMap用的就是哈希表 数据结构决定了数据的检索,维护的效率。数组的检索效率高,增删元素的效率低。而链表的增删元素的效率高,检索元素的效率低。而哈希表结合了他们...
  • 哈希表存储数据结构原理

    千次阅读 2018-03-31 20:59:48
    哈希表底层使用也是数组机制,数组中也存放对象,而这些对象往数组中存放时...1.2 哈希表存储数据结构原理当向哈希表中存放元素时,需要根据元素特有数据结合相应算法,这个算法其实就是Object类中hashC...
  • android培训、java培训、期待与您交流 ...|--HashSet:底层数据结构哈希表。 HashSet是如何保证元素唯一性呢? 是通过元素两个方法,hashCode和equals来完成。 如果元素HashCode值相同,才会判断equa
  • Java 哈希表数据结构

    2021-04-03 18:11:34
    哈希表是一个以数组和单向链表集合体 数据查询效率高 链表增删效率高 哈希表结合在一起,发挥他们优点 哈希表底层源代码 public class HashMap{ HashMap底层实际是一个数组 Node<K,V>[] table 静态...
  • Redis 数据结构哈希表 超实战追 - 女生技术 抠: .x. Redis 字典底层使用哈希表实现说到哈希表大家应该能联想到 HashMap 或者是 Hashtable 也应该能联想到 key value 存储形式 以及哈希表扩容哈希算法等知识点...
  • 哈希表底层实现

    2021-01-20 13:46:03
    数据结构的物理存储结构只有两种:顺序存储结构和链式存储结构。 哈希表使用数组作为主干,实现查找,插入,删除元素时间复杂度为O(1)。 哈希表(key,value) 就是把Key通过一个固定算法函数既哈希函数转换成一个...
  • 哈希表的扩容实现机制导语哈希表什么是哈希表装载因子hashcode哈希冲突扩容方案Java中的实现Redis中的实现Objective-C中的实现结束语 导语 哈希表是实际开发中非常常用的数据结构,也很重要。了解其底层实现细节也...
  • Java哈希表数据结构

    2021-03-14 14:48:54
    我们先将哈希表数据结构看成是这个样子: 那么整个map就是下图所示: 然后我们再来看put(key,value)和get(key)方法实现原理。 map.put(key,value)实现原理: 第一步,先将key,value封装到Node对象中。 第二步,...
  • Redis 数据结构哈希表 超实战追 - 女生技术 抠: .x. Redis 字典底层使用哈希表实现说到哈希表大家应该能联想到 HashMap 或者是 Hashtable 也应该能联想到 key value 存储形式 以及哈希表扩容哈希算法等知识点...
  • Redis 数据结构哈希表 超实战追 - 女生技术 抠: .x. Redis 字典底层使用哈希表实现说到哈希表大家应该能联想到 HashMap 或者是 Hashtable 也应该能联想到 key value 存储形式 以及哈希表扩容哈希算法等知识点...
  • 哈希表的扩容实现机制导语哈希表什么是哈希表装载因子 Hashcode哈 希冲突扩容方案 Java 中的实现 Redis 中的实现结束语 哈希表是实际开发中非常常用的数据结构也很重要了解其底层实 现细节也是非常重要的 我这篇...
  • 哈希表的扩容实现机制导语哈希表什么是哈希表装载因子 Hashcode哈 希冲突扩容方案 Java 中的实现 Redis 中的实现结束语 哈希表是实际开发中非常常用的数据结构也很重要了解其底层实 现细节也是非常重要的 我这篇...
  • .1.索引是什么 ’ 索引是一种特殊文件,包含着对数据...可以对表中一列或多列创建索引,并指定索引类型,各类索引有各自的数据结构实现 2.索引效果 (1).加快查找效率 (2).拖慢数据插入,删除和修改效率 ...
  • 哈希表也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如:Redis)核心其实就是在内存中维护一张大的哈希表,而HashMap实现原理也常常出现在各类面试题中,重要性可见一斑。...
  • 数据结构哈希表

    2017-09-19 09:07:34
     这里先说一下哈希表的定义:哈希表是一种根据关键码去寻找值的数据映射结构,该结构通过把关键码映射的位置去寻找存放值的地方,说起来可能感觉有点复杂,我想我举个例子你就会明白了,最典型的的例子就是字典,...
  • Redis 数据结构哈希表

    千次阅读 2019-03-15 20:12:53
    Redis 的字典底层使用哈希表实现,说到哈希表大家应该能联想到 HashMap 或者是 Hashtable,也应该能联想到 key、value 的存储形式,以及哈希表扩容,哈希算法等知识点。...size:表示哈希表的数组大小 used:表示...
  • HashMap集合底层哈希表/散列表的数据结构 哈希表是一个怎样的数据结构呢? 哈希表是一个数组和单向链表结合体 数组:在查询方面效率很高,随机增删方面效率很低 单向链表:在随机增删方面效率较高,在查询方法...
  • Java数据结构哈希表

    2019-08-09 13:47:49
    1. 哈希表(Hash Table)也称为散列表,是一种根据关键字值(key - value)而直接访问的数据结构。它的底层是基于数组实现,通过对键值... 哈希表的核心:哈希化时的算法,当多个key值哈希化后值相等时解决冲突的方法。
  • 数据结构-哈希表

    2018-08-12 21:13:34
    哈希表:(底层还是数组) 元素值(value)和在数组中索引位置(index)有一个确定对应关系(hash) key-value关系 数组会记录添加顺序,按照索引位置来存储,允许元素重复 哈希表中,元素是不能重复,...
  • HashSet集合存储数据的结构哈希表) 什么是哈希表呢? 在JDK1.8之前,哈希表底层采用数组+链表实现,即使用链表处理冲突,同一hash值链表都存储在一个链表里。但是当位于一个桶中元素较多,即hash值相等...
  • 哈希表是我们经常频繁使用的数据结构,所以它的知识点比较重要,如HashMap啊,就是哈希表结构,哈希表的底层是数组+链表结构的,非常之聪明,两者优点结合,数组查询快,链表增删快,并且hash采用算法分析定位地址,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,827
精华内容 1,130
关键字:

哈希表的底层数据结构

数据结构 订阅