文章目录

  • 前言
  • 相关知识
    • Hash法
    • Bit-map法
    • Bloom Filter法
    • 数据库优化法
    • 倒排索引法
      • 外排序法
      • Trie树
    • 双层捅
    • top K问题
    • 重复问题
    • 排序问题
  • 结语

前言

  本次博文对何昊出版的《java程序员面试宝典》的第9章海量数据部分的概括笔记,删除部分内容,是本系列笔记博客的最后一个博文。

相关知识

Hash法

  映射关系,给定数据元素,关键字是key,按照确定散列函数计算hash(key),然后该值作为关键字key对应元素的存储位置,再进行数据插入和检索。

  散列函数是将任意长度信息压缩为固定长度信息摘要函数。

  散列表具有固定大小数组,表长(数组大小)为质数。散列函数是关键字与存储地址间映射关系,不能保证一一对应,会发生hash冲突,即两个关键帧不同丹映射同一存储地址。

  hash函数具备特点:运算尽量简单;值域必须在散列表范围;尽可能减少冲突;

(1)直接寻址

取关键字或关键字某个线性函数为散列地址,即h(key)=key或h(key)=a*key+b,a和b均为整型常数。

  时间复杂度O(1)\mathcal{O(1)}O(1),空间复杂度O(n)\mathcal{O(n)}O(n)

  不会产生冲突,因为没有压缩映像,关键字集合大,这种方式不可取。

(2)取模法

取合适正整数,hash(key)=key mod p。p是比较大素数比较好,一般取TableSize,即散列表长。

(3)数字分析法

  关键字是d位以r为基的数(例如10为基的十进制),且共有n个关键帧,则关键帧的每个位可能有r个不同的数符(即0,1,2,…,9),但这r个数符在各个位上出现的频率不一定相同,可能在某些位上分布比较均匀,即每个数符出现的次数接近于n/rn/rn/r,而另一些位上分布不均匀。因此取其中分布均匀的那些位组成新数,用作散列地址。

  方法直观简单,但需要预先知道每个关键字情况,限制使用范围。

(6)折叠法

将关键字分为位数为1的几个部分(最后一部分的位数可能小于1),然后把各部分按位对齐进行相加,将所得的和舍弃进位,留下 ttt 位作为散列地址。当关键字位数很多,而且关键字中每位上数字分布比较均匀,采用折叠法合适。

(5)平方取中法

将关键字进行平方运算,然后从结果中间取出若干位(位数与散列地址的位数相同),将其作为散列地址,具体取几位,由散列表表长决定。

(6)除留余数法

取关键字除以某个数p(p不大于散列表长度)的余数作为散列地址,Hash(key)=key%pHash(key)=key\%pHash(key)=key%p

p值很重要,一般小于表长,且接近或等于。一般是选质数,可以是不包含小于20质因子的合数。

(7)随机数法

hash(key)=random(key)当关键字长度不相等,采用此法。

  冲突难以避免,解决hash冲突主要是当一个关键字映射后的地址若已有关键字则为该关键字重新寻找新的存储地址。

(1)开放地址法

地址发生冲突,hash表再按照某种方法继续探测其他开放地址,直到找到空闲地址为止。

Hi(key)=(H(key)+di)modm(i=1,2,...,k(k&lt;=m−1))H_i(key)=(H(key)+d_i) mod \quad m (i=1,2,...,k(k&lt;=m-1))Hi​(key)=(H(key)+di​)modm(i=1,2,...,k(k<=m−1))

其中,H(key)H(key)H(key)为关键字key的直接散列地址,mmm为散列表的长度,did_idi​为每次再探测的地址增量

  该方式先找到直接H(key),若该地址已有其他关键字,则继续查看地址为[H(key)+di][H(key)+d_i][H(key)+di​]的存储地址,判断其是否为空。如此反复,直到找到空闲的存储地址为止,然后将关键帧key存放到该地址。

did_idi​的取法

  1)di=1,2,3,...,m−1d_i=1,2,3,...,m-1di​=1,2,3,...,m−1,称为线性探测再散列

  2)di=12,−12,22,−22,...,−k2(k&lt;=m/2)d_i=12,-12,22,-22,...,-k2(k&lt;=m/2)di​=12,−12,22,−22,...,−k2(k<=m/2),称为二次探测再散列

  3)di=d_i=di​=伪随机序列,称为伪随机再散列

  利用此法解决冲突的散列表,删除元素不能直接删除(会影响其他相同散列地址元素),采用特殊标记表示已被删除。

(2)链地址法

若散列表空间为[0,m−1][0,m-1][0,m−1],则设置一个由m个指针组成的一维数组CH[m]CH[m]CH[m],好在寻找关键字散列地址过程中,所有散列地址为iii的数据元素都插入到头指针为CH[i]CH[i]CH[i]的链表中。

​   适用于冲突严重情况。

(3)再散列

发生冲突,使用第二个、第三个、散列函数计算地址,直到无冲突为止。

  计算时间会大幅增加

(4)建立一个公共溢出区

假设散列函数值域[0,m−1][0,m-1][0,m−1],设立存储空间向量OverTable[0,...,v]OverTable[0,...,v]OverTable[0,...,v]用以存储发生冲突记录

  hash主要用来“快速存取”,在O(1)\mathcal{O}(1)O(1)复杂度可以查到目标元素,或判其是否存在。

  hash数据结构中的数据对外是杂乱无序,因此具体存储位置及各个存储元素之间的相互关系无法得知,但可在常数时间判断元素位姿和存在与否。

  hash法一般可以快速存取和统计某些数据,将大量数据分类。

Bit-map法

  使用数组表示某些元素存在与否。适用于海量数据快速查找,判重,删除等。

  该法生成一个N位长串,每位以“1”或“0”表示需要排序的集合中的数。

  时间复杂度O(n)\mathcal{O(n)}O(n),以空间换时间,要求数据状态不多。

  适用于数据量大,判断是否重复问题或集合某数据是否存在。

Bloom Filter法

  以牺牲正确率,一种空间小和时间效率都很高的随机数据结构,用来检测元素是否属于集合。适用于低错误率可以容忍的场合。(不属于是绝对正确,属于可能是错误)

  将位数据与Hash函数联合使用。Bloom Filter是包含m位的位数组,每位都是0。定义k不同的hash函数,每个函数可以将集合元素映射到位数组某一位。当集合插入元素,根据k个hash函数可以得到位数组k个位,将这些位设置为1。

  如果查询某元素属于集合,则根据k个hash函数得到位数组k个位,查看k个位中值,有的位不为1,则元素肯定不在集合中;若全为1,则可能存在。在插入其他元素,可能把这些元素位置设为1,产生错误。

  难点在于如何根据输入元素个数n确定位数组m的大小以及hash函数。当hash函数个数k=(ln⁡2)∗(m/2)k=(\ln2)*(m/2)k=(ln2)∗(m/2)时错误率最小,在错误率不大于E的情况下,m至少等于n∗log⁡(1/E)n*\log(1/E)n∗log(1/E)才能表示任意n个元素的集合。但m还应更大,因为至少保证位数组里至少一半为0,所以m应该≥n∗lg⁡(1/E)∗lg⁡(e)\ge n*\lg(1/E)*\lg (e)≥n∗lg(1/E)∗lg(e)。大概就是n∗lg⁡(1/E)n*\lg(1/E)n∗lg(1/E)的1.44倍,lg表示以2为底的对数。

  通常单元素长度有很多bit,使用该法在内存通常是节省的。

  该法优点在空间效率和时间效率。在插入和查询都是常量时间,不保存元素本身具有良好安全,但都以牺牲正确率为代价。当插入元素越多,判断“元素输入该集合”概率越大。另外只能插入元素而不能删除元素,因为多个元素散列结果可能共用同一位。如果删除,会影响多个元素检测。

  使用该法实现数据字典、进行数据判重和集合求交集。

  CBF和SBF是该方法扩展,前者在每位扩展counter用以支持元素删除,后者与集合元素次数关联,使用counter最小值近似表示元素的出现频率。

数据库优化法

  (1)优秀数据库管理工具(DB2,MySQL等)

  (2)数据分区。

  (3)索引。

  (4)缓存机制

  (5)加大虚存

  (6)分批处理(分而治之,类似MapReduce),利用小数据量

  (7)使用临时表和中间表。

  (8)优化查询语句

  (9)使用视图

  (10)使用存储过程

  (11)用排序来取代非顺序存取

  (12)使用采样数据进行数据挖掘

倒排索引法

  指按照关键字建立索引。又称为反向索引,置入档案或反向档案。

  被用来存储在全文搜索下某个单词在一个文档中的存储位置映射,它是文档检索系统中最常用的数据结构,有两种不同反向索引形式。第一种形式是一条记录的水平反向索引(或反向档案索引)包含每个引用单词的文档的列表;第二种形式是一个单词的水平反向索引(或完全反向索引)又包含每个单词在一个文档中的位置。第二种形式提供了更多兼容性(如短语搜索),但需要更多时间和空间创建。

  一般采用矩阵方式存储来存储会浪费大量空间。

  倒排索引比采用矩阵方式节省很多空间。

  正向索引用来存储每个文档的单词列表。正向索引查询往往满足每个文档有序频繁的全文查询和每个单词在校验文档中的验证这样查询。在正向索引中,文档占据了中心位置,每个文档指向一个它所包含索引项。

  文档指向它包含的单词,而反向索引则单词指向包含它的文档。

  倒排索引优点,处理复杂多关键字查询,可在倒排表完成查询并交逻辑,得到结果对记录进行存取,这样把记录查询转换为地址集合运算,而不必对每个记录随机存取,故而提高效率。

外排序法

  当待排序的对象数目特别多,在内存中不能一次处理,必须把它们以文件的形式存放于外存,排序时再把它们一部分一部分地调入内存进行处理,这种方式就是外排序。

  大文件排序,待排序记录存储在外存储器说,带排序文件无法一次装入内存。需要在内存和外部存储器之间多次数据交换,以达到对整个文件进行排序目的。一般采用归并排序等方式实现外排序。

  分两步,第一步生成若干归并段(顺串),也称为文件预处理,把含有n个记录的文件,按内存大小划分为若干长度为L的子文件,然后分别把子文件调入内存,采用有效的内排序方法排序后送回内存。

  第二步,进行多路归并,即对这初始归并段进行多便归并,并使得有序的归并段逐渐扩大,最后在外存上形成整个文件的单一归并段,也就是完成了文件的外排序。

  外排序适用于大数据的排序以及去重复,但外排序也存在很大缺陷,会耗大量IO,效率不高。

Trie树

  字典树或键树,一种快速字符串检索多叉树结构,利用字符串的公共前缀减少时空开销,以空间换时间,达到提高程序效率目的。

  典型用于统计和排序大量字符串(不限于字符串),用于文本词频统计。

  能最大限度减少无谓字符串比较,查询效率比散列表高。

三个基本特性
  (1) 根节点不包含字符,除根节点外每个节点只包含一个字符。
  (2)从根节点到某一节点,经过路径的字符连接即为结点对应字符串;
  (3)每个结点的所有子结点包含字符都不相同。

若是大量字符串无公共前缀,则耗费内存。

适用于数据量大,重复多,数据种类小可放入内存情况。

双层捅

  算法思想,分而治之。因元素范围大,不能直接寻址,所以多次划分,逐步确定范围,最后在一个可接受范围进行。

top K问题

  找出频率最高前K个数,最大的前K数。

  最好是分冶+Trie树/hash+小顶端

  将数据集按照hash方法分解为多个小数据集,然后使用Trie树或hash统计对每个小数据集的query词频,然后用小顶端求出每个数据集频率最高的前K个数,最好在所有topK中求出最终的topK。

重复问题

  一般用位图实现。

排序问题

  (1)数据库排序法

  (2)分冶法。

  (3)位图法

结语

  本系列笔记博客的最后一个博文,是对何昊出版的《java程序员面试宝典》的第9章海量数据部分的概括笔记,删除部分内容(比如堆,MapReduce等),有需可以购买该书或者查询该处内容,我觉得这两个地方比较简单易懂就不整理了。

Java程序员面试宝典笔记记录(终)-第9章海量数据部分笔记相关推荐

  1. Java程序员面试宝典笔记记录(1~3章概括)

    文章目录 导言 求职前重要的两点 求职者注意的几个方面: 挑选offer考虑5点 后台开发人员面试需要补充和阅览的书籍 需备技能方面 需要阅读的书籍(针对Java) 结语 导言   本博文是对于何昊出 ...

  2. 金九银十北漂记第2篇:《Java程序员面试宝典》读书笔记

    尽信书,则不如无书.-–孟子 谈一谈这本书  <Java程序员面试宝典>是我接触的第一本讲解面试相关的书籍在看到这本书之前我就经常逛csdn的bbs,已经接触面试之类的知识.不过这本书还是 ...

  3. Java程序员面试宝典

    第1部分  求职过程 古人云:凡事预则立,不预则废.机会都是垂青有准备的人的.为了得到一份满意的工作,大家一定要对整个求职过程有清醒的了解.把能够预见的.必须做的事情早一些做完,这样在大规模招聘开始的 ...

  4. JAVA程序员面试宝典 (2011版)

    1. Java 基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法, 线程的语法,集合的语法,io 的语法,虚拟机方面的语法. 1.一个".java& ...

  5. java程序员面试宝典(刘磊版)笔记

    1:JDK与JRE JDK:JAVA Development Kit, java开发工具包; 包括各种类库和工具,当然也包括JRE JRE:JAVA Runtime Environment,java程 ...

  6. JAVA程序员面试宝典C收藏

    37,try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后? 会执行,在return前执行. 38,编程题 ...

  7. JAVA程序员面试宝典3

    37,try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后? 会执行,在return前执行. 38,编程题 ...

  8. 12 Java程序员面试宝典视频课程之面向对象

    一.简述面向对象和面向过程的区别和联系? 答: 两者都是软件开发思想,先有面向过程,后有面向对象.在大型项目中,针对面向过程的不足推出了面向对象开发思想 区别 编程思路不同: 面向过程以实现功能的函数 ...

  9. 02 Java程序员面试宝典视频课程之异常

    一.Java 中,处理异常的两大步是? 答 捕获异常 声明异常 二.如果 catch 两个异常,一个是父类,一个是子类.这两个异常的 catch 顺序如何确定? 答 子类异常在前父类异常在后 三.fi ...

  10. 真牛皮!java程序员面试宝典怎么样

    前言 爱因斯坦说过"耐心和恒心总会得到报酬的",我也一直把这句话当做自己的座右铭,这句箴言在今年也彻底在"我"身上实现了. 每一个程序员都拥有一座大厂梦,我也不 ...

最新文章

  1. Python3-onvif协议之相机截图
  2. Druid.io索引过程分析——时间窗,列存储,LSM树,充分利用内存,concise压缩
  3. 探索MySql.Data.dll
  4. 常州模拟赛d4t1 立方体
  5. 【51单片机快速入门指南】4.3.1: MPU6050调用DMP库获取四元数和欧拉角
  6. 聚焦业务价值:分众传媒在 Serverless 上的探索和实践
  7. java httpclient 重定向_httpclient 中post请求重定向
  8. 查看kafka的主从状态_Kafka 集群部署
  9. 无心插柳,再次浅谈.net资源的回收
  10. 查看磁盘阵列 使用率(简单)
  11. 主管已不安排代码工作,自己要明白问题所在
  12. The requested resource is not available. 原因,成功解决
  13. 免费的科研论文画图软件drawio以及Mermaid
  14. Java对比两个json 的数据结构和内容是否一样
  15. String类型getBytes方法
  16. ps模糊照片变清晰步骤东方逐梦
  17. echarts柱形图x轴y轴的字体大小颜色调整
  18. 和马斯克Zoom开个会,竟是AI换脸,GitHub 4000星项目登上热榜​
  19. 学习光线追踪(16)---折射计算[1]
  20. 网易我的世界服务器存档在哪个文件夹,网易版我的世界如何删除玩家存档

热门文章

  1. Python —— excel 创建 复制 删除,获取最大行列
  2. VVC/VTM:代码学习——量化实现之RDOQ
  3. linux访问网络图片,linux网络图形监控方法
  4. layui表格合并的方法
  5. iOS 渲染原理解析
  6. 【对比Java学Kotlin】协程-异步流
  7. 起底硅谷最神秘、估值最高的大数据公司:Palantir
  8. Docker——数据卷的概述和使用
  9. NOIP2010导弹拦截
  10. 捆绑影视IP,玩跨界营销,你真学不会!