听到这样说法: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. 分布式配置 tachyon 并执行Hadoop样例 MapReduce

    ----------此文章.笔者按着tachyon官网教程进行安装并记录. (本地安装tachyon具体解释:http://blog.csdn.net/u012587561/article/detai ...

  2. Python之杨辉三角算法实现

    学习了廖雪峰的官方网站的python一些基础,里面有个题目,就是让写出杨辉三角的实现,然后我就花了时间实现了一把.思路也很简单,就是收尾插入0,然后逐层按照杨辉三角的算法去求和实现杨辉三角. 附属代码 ...

  3. struts2 常量

    struts.i18n.encoding 指定web应用的默认编码集

  4. centOS7 安装man中文手册

    [root@localhost ~]# yum list | grep man.*zh -.el7 base [root@localhost ~]# yum -y install man-pages- ...

  5. ssh 反向代理和正向代理的文章

    搜索原因是,我希望访问家里内网的机器 技术要点: ssh 反向代理,正向代理 隧道 文章摘自: https://my.oschina.net/leejun2005/blog/94401 https:/ ...

  6. php分享二十五:跨域请求

    问题: 跨域请求有几种方式? jsonp支持哪几种请求方式? 支持post请求吗? 支持get请求吗? 由于浏览器同源策略,凡是发送请求url的协议.域名.端口三者之间任意一与当前页面地址不同即为跨域 ...

  7. MTStatusBarOverlay (状态栏,添加自定义内容库)

    NSString * message = [NSString stringWithFormat:@"%@成功", text]; MTStatusBarOverlay *overla ...

  8. 深入理解Linux内核-进程

    1.进程的静态特性 进程:程序执行时的一个实例 进程描述符(task_struct): 进程的基本信息(thread_info).指向内存区描述符的指针(mm_struct).进程相关的tty(tty ...

  9. 使用 nw-builder 构建跨平台桌面应用程序

    NW.js 是一个使用 Web 技术创建本地应用的框架,如 HTML.JavaScript 和 CSS.简单地说,当你在使用普通的流程开发一个 Web 应用时,开发完成后,运行一个生成器,将所有东西编 ...

  10. python常用运维脚本实例

    转载  file是一个类,使用file('file_name', 'r+')这种方式打开文件,返回一个file对象,以写模式打开文件不存在则会被创建.但是更推荐使用内置函数open()来打开一个文件 ...