advanced-java/docs/big-data/find-common-urls.md
yanglbme dd2740751e docs: format document with prettier
全面整理项目内容,可读性更佳
2020-09-24 09:54:38 +08:00

25 lines
1.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 如何从大量的 URL 中找出相同的 URL
### 题目描述
给定 a、b 两个文件,各存放 50 亿个 URL每个 URL 各占 64B内存限制是 4G。请找出 a、b 两个文件共同的 URL。
### 解答思路
每个 URL 占 64B那么 50 亿个 URL 占用的空间大小约为 320GB。
> 5, 000, 000, 000 _ 64B ≈ 5GB _ 64 = 320GB
由于内存大小只有 4G因此我们不可能一次性把所有 URL 加载到内存中处理。对于这种类型的题目,一般采用**分治策略**,即:把一个文件中的 URL 按照某个特征划分为多个小文件,使得每个小文件大小不超过 4G这样就可以把这个小文件读到内存中进行处理了。
**思路如下**
首先遍历文件 a对遍历到的 URL 求 `hash(URL) % 1000` ,根据计算结果把遍历到的 URL 存储到 a<sub>0</sub>, a<sub>1</sub>, a<sub>2</sub>, ..., a<sub>999</sub>,这样每个大小约为 300MB。使用同样的方法遍历文件 b把文件 b 中的 URL 分别存储到文件 b<sub>0</sub>, b<sub>1</sub>, b<sub>2</sub>, ..., b<sub>999</sub> 中。这样处理过后,所有可能相同的 URL 都在对应的小文件中,即 a<sub>0</sub> 对应 b<sub>0</sub>, ..., a<sub>999</sub> 对应 b<sub>999</sub>,不对应的小文件不可能有相同的 URL。那么接下来我们只需要求出这 1000 对小文件中相同的 URL 就好了。
接着遍历 a<sub>i</sub>( `i∈[0,999]` ),把 URL 存储到一个 HashSet 集合中。然后遍历 b<sub>i</sub> 中每个 URL看在 HashSet 集合中是否存在,若存在,说明这就是共同的 URL可以把这个 URL 保存到一个单独的文件中。
### 方法总结
1. 分而治之,进行哈希取余;
2. 对每个子文件进行 HashSet 统计。