现在的位置: 首页 > 综合 > 正文

第一部分、从 set/map 谈到 hashtable/hash_map/hash_set

2018年01月19日 ⁄ 综合 ⁄ 共 2440字 ⁄ 字号 评论关闭

教你如何迅速秒杀掉:99%的海量数据处理面试题 


何谓海量数据处理?

          所谓海量数据处理,无非就是基于海量数据上的存储、处理、操作。何谓海量,就是数据量太大,所以导致要么是无法在较短时间内迅速解决,要么是数据太大,导致无法一次性装入内存。

那解决办法呢?
          针对时间,我们可以采用巧妙的算法搭配合适的数据结构,如 Bloom filter/Hash/bit-map/堆/数据库或倒排索引/trie 树,
          针对空间,无非就一个办法:大而化小:分而治之/hash 映射,你不是说规模太大嘛,那简单啊,就把规模大化为规模小的,各个击破不就完了嘛。

至于所谓的单机及集群问题,
通俗点来讲,单机就是处理装载数据的机器有限(只要考虑 cpu,内存,硬盘的数据交互),
而集群,机器有多辆,适合分布式处理,并行计算(更多考虑节点和节点间的数据交互)。

处理海量数据问题,无非就是:

1.  分而治之/hash 映射 + hash 统计 + 堆/快速/归并排序;
2.  双层桶划分
3.  Bloom filter/Bitmap;
4.  Trie 树/数据库/倒排索引;
5.  外排序;

6.  分布式处理之 Hadoop/Mapreduce。


第一部分、从 set/map 谈到 hashtable/hash_map/hash_set 

简要介绍下 set/map/multiset/multimap,及 hash_set/hash_map/hash_multiset/hash_multimap之区别,

而本文第二部分,则针对上述那 6 种方法模式结合对应的海量数据处理面试题分别具体阐述。

第一部分、从 set/map 谈到 hashtable/hash_map/hash_set

一般来说,STL 容器分两种,
1、 序列式容器(vector/list/deque/stack/queue/heap) ,
2、关联式容器。关联式容器又分为 set(集合) 和 map(映射表)两大类,
以及这两大类的衍生体 multiset(多键集合)和 multimap(多键映射表),这些容器均以RB-tree 完成。
此外,还有第3类关联式容器,如hashtable(散列表),以及以hashtable为底层机制完成的
hash_set(散列集合)/hash_map(散列映射表)/hash_multiset( 散列多键集合)/hash_multimap( 散列多键映射表)。


也就是说,set/map/multiset/multimap 都内含一个 RB-tree,

而 hash_set/hash_map/hash_multiset/hash_multimap都内含一个 hashtable。

          所谓关联式容器,类似关联式数据库,每笔数据或每个元素都有一个键值(key)和一个实值(value),即所谓的 Key-Value(键-值对) 。当元素被插入到关联式容器中时,容器内部结构(RB-tree/hashtable) 便依照其键值大小,以某种特定规则将这个元素放置于适当位置。包括在非关联式数据库中,比如,在
MongoDB 内,文档(document)是最基本的数据组织形式,
每个文档也是以 Key-Value(键-值对)的方式组织起来。一个文档可以有多个Key-Value 组合,
每个 Value 可以是不同的类型,比如 String、Integer 、List 等等。 
{ "name" : "July",  
"sex" : "male",  
"age" : 23 }  

set/map/multiset/multimap

          set,同map一样,所有元素都会根据元素的键值自动被排序,因为set/map 两者的所有各种操作,都只是转而调用 RB-tree 的操作行为,不过,值得注意的是,两者都不允许两个元素有相同的键值。
          不同的是: set的元素不像map那样可以同时拥有实值(value)和键值(key),set元素的键值就是实值,实值就是键值,而map的所有元素都是pair,同时拥有实值(value)和键值key),pair的第一个元素被视为键值,第二个元素被视为实值。

至于 multiset/multimap,他们的特性及用法和 set/map 完全相同,
唯一的差别就在于它们允许键值重复,即所有的插入操作基于 RB-tree的insert_equal()而非insert_unique() 。

hash_set/hash_map/hash_multiset/hash_multimap

          hash_set/hash_map,两者的一切操作都是基于hashtable 之上。不同的是,hash_set同 set 一样,同时拥有实值和键值,且实质就是键值,键值就是实值,
          而 hash_map 同 map一样,每一个元素同时拥有一个实值(value)和一个键值(key),所以其使用方式和map基本相同。但由于 hash_set/hash_map都是基于 hashtable 之上,所以不具备自动排序功能。为什么?因为
hashtable 没有自动排序功能。

          至于 hash_multiset/hash_multimap的特性与上面的multiset/multimap完全相同, 唯一的差别就是它们hash_multiset/hash_multimap的底层实现机制是hashtable(而multiset/multimap底层实现机制是RB-tree),所以它们的元素都不会被自动排序,不过也都允许键值重复。

所以,综上,说白了,什么样的结构决定其什么样的性质,
因为set/map/multiset/multimap都是基于 RB-tree 之上,所以有自动排序功能,
而 hash_set/hash_map/hash_multiset/hash_multimap都是基于 hashtable 之上,所以不含有自动排序功能,
至于加个前缀multi_无非就是允许键值重复而已。

接下来,请看本文第二部分、处理海量数据问题之六把密匙。

抱歉!评论已关闭.