听到这样说法:hash是内存中使用的经典数据结构。内存是典型的随机访问设备。

为什么hash这种数据结构很适合内存使用呢?如何理解内存是随机访问设备呢?

因为我想知其所以然,如何理解背后的原因,我花费点时间来学习一番。

我之前学过搜索引擎中的倒排索引,其中的单词词典就是使用hash方式实现:对关键词做hash值,同样hash值的关键词都归到一起。这是我通俗化接触hash应用开始。

我们使用hash寻找数据的时候,数据随机分散到各个物理位置。不是有序的数据。而内存设备也是随机访问设备。内存很适合用hash方式来读取数据。比如memcached、redis等这些内存缓存,都是使用key-value形式来读取数据的

内存是一个随机存储设备,随机存储设备,我觉得是相对顺序存储设备而言的。机械硬盘存储,读取速度会影响整体速度,比如就近读取就会快。主存的数据读取与先后顺序无关。是典型的随机访问设备。很适合hash数据结构查找。

如何理解内存中数据的读取与先后顺序无关? 熟悉了内存存储原理,才知道,为什么内存是随机存储设备。

借用网上别人的一张内存存储图:

这张图很好的帮我理解了内存的数据读取方式。感谢作者。

把内存里面的存储空间,看成是一个一个的单元格组成的矩阵,每个单元格就是存储数据的。

数据d1,d2,d3分别分散存储在内存中的各个单元格子里面。

要读取数据d1。通过一个行地址和一个列地址可以唯一定位到一个存储单元。

随便数据存储在哪个单元个子里面,都能通过行地址与列地址快速定位找到数据所在的单元格。

假设要读取数据d1、d2、d3。先读取d1,还是先读取d3,对于整体速度是没有影响的。因为定位每个单元格子所需要的操作是一样的(行地址与列地址)

所以,读取的速度是与读取顺序无关的。

而在硬盘中则不同,硬盘的磁头要进行定位,如何数据在磁头附近,则直接移过去即可。如果接下来要读取的数据不在磁头附近,又需要让磁盘片重新转一圈才行(磁头不转动,盘片转动,所以需要让数据所在区域转动到到磁头位置下,以便磁头读取数据),这就需要耗费磁盘i/o。在磁盘扇区,相临近的数据,能减少盘片转动,所以安排数据的先后读取顺序其实就是减少了盘片转动。比如把需要一起访问的数据放到同一个柱面上,就是一种方式。

这时候,理解了为什么内存很适合用hash方式存取数据。是与随机存储设备有关。

磁盘靠物理旋转来定位读取数据,于是存在寻道时间和旋转延迟。内存查找数据不存在这种问题。

有的对比,就更加了解硬盘为什么很适合用b树方式作为数据结构。不适合使用hash方式来组织数据。

可以这样理解:内存与磁盘存储的原理的不同,使得内存很适合hash方式访问数据,磁盘则很适合使用b树形式组织数据。

理解不正确之处,欢迎指正!

为什么hash作为内存使用的经典数据结构?的更多相关文章

  1. 大公司面试经典数据结构与算法题C#/Java解答

    几个大公司(IBM.MicroSoft and so on)面试经典数据结构与算法题C#解答 1.链表反转 我想到了两种比较简单的方法 第一种是需要开一个新的链表,将原链表的元素从后到前的插入到新链表 ...

  2. Java8 Hash改进/内存改进

    又开新坑o(*≧▽≦)ツ讲讲几个Java版本的特性,先开始Java8, HashMap的改进 HashMap采用哈希算法,先使用hashCode()判断哈希值是否相同,如果相同,再使用equals() ...

  3. 【经典数据结构】B树与B+树

    本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 维基百科对B树的定义为“在计算机科学中,B树 ...

  4. 【经典数据结构】B树与B+树(转)

    本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 维基百科对B树的定义为“在计算机科学中,B树 ...

  5. u-boot的内存分布和全局数据结构

    U-boot,除非在RAM中调试,一般情况下都是从flash中执行一段代码,然后将flash中储存的代码和数据搬移到ram中,然后跳转到ram中执行.当然这应该也是一般的bootloader的执行方式 ...

  6. 【经典数据结构】B树与B+树的解释

    本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 前面讲解了平衡查找树中的2-3树以及其实现红 ...

  7. 聊聊经典数据结构HashMap,逐行分析每一个关键点

    本文基于JDK-8u261源码分析 本文原创首发于 奇客时间(qiketime) 1 简介 HashMap是一个使用非常频繁的键值对形式的工具类,其使用起来十分方便.但是需要注意的是,HashMap不 ...

  8. java内存泄漏的经典案例

    这篇文章主要介绍了Java中典型的内存泄露问题和解决方法,典型的内存泄露例子是一个没有实现hasCode和 equals方法的Key类在HashMap中保存的情况,可以通过实现Key类的equals和 ...

  9. Java内存模型一个经典例子-指令重排序与CPU指令多发射导致执行结果异常

    先上代码: import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; ...

随机推荐

  1. Linux C 编程一站式学习

    个人认为这是一个挺不错的从C语言到Linux系统开发的教程,这本是两个网上的文档. 其中 一本是<How To Think Like A Computer Scientist: Learning ...

  2. java基础知识总结(二)

    +=隐含了强制类型转换. x+=y;等价与:x = (x的数据类型)(x + y); 函数重载? 函数名同样.參数列表不同.跟返回值不关,就是函数重载 封装是什么? 隐藏对象的属性和详细的实现细节,仅 ...

  3. 解决 p0sixspwn-v1.0.4 win版 无法定位程序输入点sqlite3_wal_checkpoint的问题

    p0sixspwn-v1.0.4 win版今天早晨发现大神( @winocm · @iH8sn0w · @SquiffyPwn) 已经发布. 下载下来运行之,发现会报错: 无法定位程序输入点sqlit ...

  4. ${HADOOP_CONF_DIR:-$HADOOP_PREFIX/$DEFAULT_CONF_DIR}

      在hadoop-config.sh中,有如下语句:${HADOOP_CONF_DIR:-$HADOOP_PREFIX/$DEFAULT_CONF_DIR}                     ...

  5. Lua中and、or的一些特殊使用方法

    Lua中的逻辑运算符:与(and).或(or)和非(not),与其它语言的逻辑运算符功能一致,这里不做赘述.仅仅说一点,全部的逻辑运算符将false和nil视为假,其它不论什么东西视为真.0也视为真. ...

  6. [na]二层sw数据交换

    1,同vlan下,两台pc配置了GW,arp请求过程. Pc1 ping pc0的时候,触发pc1的arp请求,发给GW后,GW继续发给pc0(同一个vlan),pc0收到后给pc1回复.Pc1发出i ...

  7. webpack配置实践

    首先我们的需求: 打包调试 提取公共代码 压缩 热替换 1.打包调试 第一步,我们在目标文件夹下安装webpack(假设已有package.json)npm i webpack@ -gcnpm i w ...

  8. HTML5学习笔记(二十五):事件

    在浏览器或文档某个元素发生某个特定情况的瞬间,会作为一个事件进行广播,我们可以对其添加监听来处理特定的事件. 事件流 事件流描述了页面中接收事件的顺序. 整个事件流包含了三个阶段:事件捕获阶段.事件目 ...

  9. [Windows Azure] Create a Virtual Network for Site-to-Site Cross-Premises Connectivity

    Create a Virtual Network for Site-to-Site Cross-Premises Connectivity This tutorial walks you throug ...

  10. WinEdt 6+SumatraPDF -- 实现TeX文档和PDF文件正反向搜索

    这几天试用了新出不久的WinEdt 6,结合PDF文件的阅读器SumatraPDF,感觉实现TeX文档和PDF文件之间的正反向搜索十分便利,故此向大家特别推荐! CTeX v2.8版本的一项重要功能是 ...