File tree 3 files changed +49
-2
lines changed
3 files changed +49
-2
lines changed Original file line number Diff line number Diff line change @@ -67,6 +67,7 @@ leetcode 题解,记录自己的 leecode 解题之路。
67
67
- [ binary-tree-traversal] ( ./thinkings/binary-tree-traversal.md )
68
68
- [ dynamic-programming] ( ./thinkings/dynamic-programming.md )
69
69
- [ 哈夫曼编码和游程编码] ( ./thinkings/run-length-encode-and-huffman-encode.md )
70
+ - [ 布隆过滤器] ( ./thinkings/bloom-filter.md )
70
71
71
72
### anki 卡片
72
73
82
83
83
84
[ React fiber]
84
85
85
- [ 一个非常简单,但是有效的算法 - 布隆过滤器]
86
86
87
- > 从这个算法可以对 tradeoff 有更入的理解。
Original file line number Diff line number Diff line change
1
+ ## 场景
2
+ 假设你现在要处理这样一个问题,你有一个网站并且拥有` 很多 ` 访客,每当有用户访问时,你想知道这个ip是不是第一次访问你的网站。
3
+
4
+ ### hashtable 可以么
5
+ 一个显而易见的答案是将所有的ip用hashtable存起来,每次访问都去hashtable中取,然后判断即可。但是题目说了网站有` 很多 ` 访客,
6
+ 假如有10亿个用户访问过,每个ip的长度是4 byte,那么你一共需要4 * 1000000000 = 4000000000Bytes = 4G , 如果是判断URL黑名单,
7
+ 由于每个URL会更长,那么需要的空间可能会远远大于你的期望。
8
+
9
+ ### bit
10
+ 另一个稍微难想到的解法是bit, 我们知道bit有0和1两种状态,那么用来表示存在,不存在再合适不过了。
11
+
12
+ 加入有10亿个ip,我们就可以用10亿个bit来存储,那么你一共需要 1 * 1000000000 = (4000000000 / 8) Bytes = 128M, 变为原来的1/32,
13
+ 如果是存储URL这种更长的字符串,效率会更高。
14
+
15
+ 基于这种想法,我们只需要两个操作,set(ip) 和 has(ip)
16
+
17
+ 这样做有两个非常致命的缺点:
18
+
19
+ 1 . 当样本分布极度不均匀的时候,会造成很大空间上的浪费
20
+
21
+ > 我们可以通过散列函数来解决
22
+
23
+ 2 . 当元素不是整型(比如URL)的时候,BitSet就不适用了
24
+
25
+ > 我们还是可以使用散列函数来解决, 甚至可以多hash几次
26
+
27
+ ### 布隆过滤器
28
+
29
+ 布隆过滤器其实就是` bit + 多个散列函数 ` , 如果经过多次散列的值再bit上都为1,那么可能存在(可能有冲突)。 如果
30
+ 有一个不为1,那么一定不存在(一个值经过散列函数得到的值一定是唯一的),这也是布隆过滤器的一个重要特点。
31
+
32
+ ![ bloom-filter-url] ( ../assets/thinkings/bloom-filter-url.png )
33
+
34
+ ### 布隆过滤器的应用
35
+
36
+ 1 . 网络爬虫
37
+ 判断某个URL是否已经被爬取过
38
+
39
+ 2 . K-V数据库 判断某个key是否存在
40
+
41
+ 比如Hbase的每个Region中都包含一个BloomFilter,用于在查询时快速判断某个key在该region中是否存在。
42
+
43
+ 3 . 钓鱼网站识别
44
+
45
+ 浏览器有时候会警告用户,访问的网站很可能是钓鱼网站,用的就是这种技术
46
+
47
+ > 从这个算法大家可以对 tradeoff(取舍) 有更入的理解。
48
+
You can’t perform that action at this time.
0 commit comments