散列表、位图、布隆过滤器
三个方案整体上都可以很好的解决数据查找问题,细节上又有些区别。
【散列表、位图、布隆过滤器】散列表:散列表着眼于精确查询,这意味着散列表需要存储所有数据,通过高效的hash函数精确快速定位数据。这同时也带来了一个问题就是内存空间消耗,当面临大量数据时会面临硬件内存不支持的问题,关于这点我不确定它是否是一个悖论,比如我们是否真的有那么多的数据,这些数据是否真的有必要入缓存,这些数据是否存入的数据都是有效的。是的在系统设计时,我们存在热点数据一说,如果单纯的要求把所有数据存入缓存其实非常不合理。
位图:位图也是一个数据状态管理方案,位图通过一个一维数组存储数据状态,实际数据需要被转化为整数形式。这个很好的节约了存储空间,但是同时也失去了value的存储功能。空间的大小和数据的最大值有关。下面推荐一个算法:
5TB的硬盘上放满了数据,请写一个算法将这些数据进行排重。如果这些数据是一些32bit大小的数据该如何解决?如果是64bit的呢?
public static final int _1MB = 1024 * 1024;
public static byte[] flags = new byte[ 512 * _1MB ];
public static void main(String[] args) {
int[] array = {255, 1024, 0, 65536}
int index = 0;
for(int num : array) {
if(!getFlags(num)) {
//未出现的元素
array[index] = num;
index = index + 1;
//设置标志位
setFlags(num);
}
}
}
public static void setFlags(int num) {
flags[num >> 3] |= 0x01 << (num & (0x07));
}
public static boolean getFlags(int num) {
return flags[num >> 3] >> (num & (0x07)) & 0x01;
}
布隆过滤器:布隆过滤器是一种概率的状态管理方案,相对位图而言它通过牺牲准确性为代价,进一步节约了内存空间。布隆过滤器通过多重hash算法对一个值进行多点定位,但是不排除多个值映射到同一组定位点的问题。在不要求高精确度的前提下,是应对大数据的一种很好的解决方案。布隆过滤器错误率大家可以参考一下布隆过滤器的论文,在实践中google常用的设置比容量是数据的16倍,hash函数为8组的时候错误率在万分之一左右。
总结:隆过滤器可以说优化了位图算法,需要注意的一点是布隆过滤器更关注于数据的数量,位图更关注数据的最大值,但是以目前的计算机硬件水平来说他们最多也就是处理GB级别的数据量(条数或者最大值,而不是数据实际占用空间的大小,数据实际占用空间的大小往往比这个数量级更大)。然后在面临超大型数据比如PB级别,EB级别的时候,还是要用到数据持久化策略。
推荐阅读
- 一个人的碎碎念
- 野营记-第五章|野营记-第五章 讨伐梦魇兽
- Shell-Bash变量与运算符
- 清明,是追思、是传承、是感恩。
- 牛人进化+|牛人进化+ 按自己的意愿过一生
- 七老修复好敏感、角质层薄、红血丝
- 华为旁!大社区、地铁新盘,佳兆业城市广场五期!
- 标签、语法规范、内联框架、超链接、CSS的编写位置、CSS语法、开发工具、块和内联、常用选择器、后代元素选择器、伪类、伪元素。
- 螃蟹和这些食物同吃,轻则腹泻、重则中毒!要小心哦~
- 八、「料理风云」