判断一个元素是否在一个集合中
数组 array
查看对应的元素是否在集合中,时间复杂度O(n),遍历寻找。
假设查找Mango
是否在这里面,需要遍历每个元素进行比较,看是否在这里面,时间复杂度O(n)。
哈希表 hashTable
查看对应的元素是否在集合中,时间复杂度O(1),先通过hash方法,再去查看是否有。
这样看起来是非常完美的,但是随着元素数量的增多,hashTable占用的空间也会非常大。
假设去判断一百亿个URL中是否存在https://www.csdn.net/
这个URL。如果使用hashTable来存储这么多数据,也是不现实的。
仅仅是判断一个元素是否在集合里,能否将这些数据不用那么精确存储,可以联调想到的是BitMap。
BitMap
简单来讲就是 一段内存,上面只存储了01两个数值(听起来是废话,计算机内部存储都是这么做的),默认的都是0,按照内存开始和内存结束,逻辑上有第几位第几位。
可以将某个值通过hash 函数计算之后得到整数,然后将对应位数翻转为1。
假设有m个位,n个元素,来推导下情况
-
任意一个位被置为1的概率为:
-
任意一个位没有被置位1的概率为:
-
插入了n个元素依然没有被置为1的概率为:
- 反过来说,插入n个元素,一个位被置为1的概率为:
布隆过滤器
如果使用多个hash函数,将多个位置变为1,就是布隆过滤器。
初始化
添加geeks
字符串,利用三个hash函数,将1、4、7置为1
添加nerd
字符串,利用三个hash函数,将3、4、5置为1,由于上个操作已经把4置为1了。
添加cat
字符串,利用hash函数,会看到1、3、7都是1。这就是误报的情况,过滤不是百分百的,而是有概率的。
总结
上面这种保证了,如果有一个位为0,就是精准的过滤。
所以能保证:不存在的肯定不存在;存在的不一定存在。
Filter 就是布隆过滤器
Storage 就是存储
主要就是通过给定数据,判断数据是否在storage中,先通过Filter来过滤下,然后把请求丢到storage中,大大降低了对storage的访问。