考虑如下需求:
- 爬虫对于大量的URL进行排重
- 统计网站的UV;
- 对1到1亿的数据进行排序
位图的使用场景
如果我们要存储1到1亿个数字,支持排重该如何做呢,可以采用位图。见下面的代码,用位图会极大的节省查找、插入的效率.一次位运算即可,同时也极大的节省了内存空间,现在只许愿1亿个2进制,即12MB左右。如果用散列表至少需要40MB。
1 | public class BitMap { |
bloomfilter
接上面的问题,如果数字的值不多,但是范围很大,比如1亿个数字但是范围是1到10亿,这时候我们的存储空间变成了120MB,不降反升,我们该如何存储呢?这时候就要借用bloomfilter了。
boolmfilter底层还是bitMap,大小还可以设置为1亿。在介绍hash散列时候我们遇到hash冲突采用链表来解决hash冲突。在这里我们采用多个hash函数。
比如:
- 我们对一个值用h1,h2,h3……hn,分别将值写入到v1,v2,v3…..vn中。
- 查询时候我们分别判断如果h1~hn都为true,返回true,只要有一个为false,就返回false
缺点:
- 存在误判的情况,随着bloomfilter里1的值越来越多,误判率会加大,最好支持扩容;
- 删除会很麻烦;
开头提到的问题:我们可以采用10倍的bloomfilter存储url,同时进行排重
引申问题
- 假设我们有1亿个整数,数据范围是从1到10亿,进行排序;
- 海量图库的排重;
1 | //排序 |
bitmap在语言中的应用
java的中bitSet
google库guava中的BloomFilter的实现类