听到这样说法: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. 使用 Cookie 而无需 ASP.NET 核心标识的身份验证

    https://docs.microsoft.com/zh-cn/aspnet/core/security/authentication/cookie?tabs=aspnetcore2x#tabpan ...

  2. 跟我学SharePoint 2013视频培训课程——网站导航及页面元素(2)

    课程简介 第2天,介绍SharePoint 2013 网站导航及页面元素 视频 SharePoint 2013 交流群 41032413

  3. List遍历Java 8 Streams map() examples

    1. A List of Strings to Uppercase 1.1 Simple Java example to convert a list of Strings to upper case ...

  4. Python把同一个对象循环赋值给另外一个变量

    Python把同一个对象循环赋值给另外一个变量,修改一个对象,其他对象也修改了 >>> row=['_'] * 3 >>> board = [] >>& ...

  5. PHP取整,四舍五入取整、向上取整、向下取整、小数截取

    PHP取整数函数常用的四种方法: 1.直接取整,舍弃小数,保留整数:intval(): 2.四舍五入取整:round(): 3.向上取整,有小数就加1:ceil(): 4.向下取整:floor(). ...

  6. unity, 2d rope

    https://www.youtube.com/watch?v=l6awvCT29yU

  7. Ultraedit使用小技巧

    4. 编辑文件如何加入时间戳 ?F7 快捷键即可.你试试看? 5. 为何拷贝(Copy)/粘贴(Paste)功能不能用了?不怕大家笑话,我有几次使用 UltraEdit的过程中发现拷贝与粘贴的内容是不 ...

  8. [svc]linux内核参数

    内核参数 说明 net.ipv4.tcp_max_syn_backlog = 2048 增大队列SYN最大半连接数; 对于那些依然还未获得客户端确认的连接请求,需要保存在队列中最大数目.默认值是102 ...

  9. 深入理解Linux内核-定时测量

    定时测量:由基于固定频率振荡器和计数器的几个硬件电路完成的. 记时体系概貌: 内核中与时间相关的任务: 硬件设备: 实时时钟(RTC):1.Real Time Clock ,独立于CPU和所有芯片,每 ...

  10. Socket网络编程--FTP客户端(2)(Windows)

    上一篇FTP客户端讲到如果制作一个简单的FTP客户端,功能实现了,但是后面我们发现了问题,就是FTP是使用明文进行操作的.对于普通情况来说就无所谓了.但有时候要安全的一点的话,就应该使用FTP的安全版 ...