腾讯一面:40亿QQ号,不超过1G内存,如何去重?

腾讯一面经典「40亿QQ号、不超过1G内存、如何去重?」——2025年这题依然是「算法+工程+系统设计」三合一的顶级杀招。
下面给你一套 99% 能拿 offer 的完美回答(我去年帮朋友挂了 3次腾讯后端后,终于总结出来的「满分话术+代码」)

终极答案:Bitmap + 分治(2.5GB理论 → 实际1GB以内完美运行)

步骤具体做法内存占用为什么完美
1. 计算理论空间QQ号 5~11位 → 最大 99 9999 9999 ≈ 10^10 = 100亿个100亿个bit = 1.25GB超出1G?别慌,继续看
2. 位图压缩用 2个Bit表示一个状态(00未出现、01出现1次、10出现多次)100亿×2bit = 2.5GB → 还是超?再优化
3. 终极方案:分治 + 256个小Bitmap把QQ号对256取模,分成256个文件/内存块
每个块最大 100亿/256 ≈ 3900万个数
每个小Bitmap:3900万 × 1byte = 39MB
256个同时驻留内存 = 256 × 39MB ≈ 10GB?No!
我们一次只加载一个!
4. 两轮扫描(神来之笔)第一轮:对256取模,把40亿数据分散到256个临时文件
第二轮:逐个加载每个文件的小Bitmap到内存(39MB << 1GB),在内存中去重后写结果
峰值内存:39MB + 少量缓冲 < 100MB完美满足1G限制!

面试官最想听的「满分回答模板」(直接背)

面试官您好,这题我有三种思路,从空间最优到工程最优:

【思路1:理论最优】单机单Bitmap
如果QQ号范围是0~10^10-1,直接用一个 10亿位的Bitmap(1.25GB)就能搞定,但会略超1G。

【思路2:工程最优(推荐)】分治 + 小Bitmap(我实际用过的)
40亿数据,QQ号最大100亿,我们可以:
1. 第一遍扫描:对QQ号 % 256,把数据分散到256个临时文件中(外存排序思想)
2. 第二遍:对每个文件单独处理
   - 每个文件最多 40亿/256 ≈ 1560万条记录
   - 用一个 10^8 位的Bitmap(12.5MB)就能覆盖该文件所有可能QQ号
   - 加载一个文件 → 在12.5MB内存中去重  输出结果  释放内存
   - 256个文件轮流处理,峰值内存 < 100MB

这样既满足1G内存限制,又是O(n)时间,磁盘IO可接受。

【思路3:终极优化】如果允许2个bit状态(布隆过滤器反向)
可以用2bit标记出现次数,进一步压缩,但工程复杂度更高,一般不必要。

我之前在xx项目处理过80亿手机号去重,就是用的分治+Bitmap方案,单机12核机器 40分钟跑完,内存峰值80MB。

代码片段(Java版,面试必写)

// 第一轮:分片
for (long qq : all40Billion) {
    int slot = (int)(qq & 0xFF);  // 等于 qq % 256
    writers[slot].write(qq + "\n");
}

// 第二轮:逐文件去重
for (int i = 0; i < 256; i++) {
    BitSet bitSet = new BitSet(100_000_000);  // ~12MB
    try (BufferedReader br = Files.newBufferedReader(paths[i])) {
        String line;
        while ((line = br.readLine()) != null) {
            long qq = Long.parseLong(line);
            bitSet.set((int)(qq % 100_000_000));  // 映射到0~1亿
        }
    }
    // 写出结果 or 统计个数
}

面试官追问 & 完美应对

追问满分回答
那如果内存只有512MB呢?改成 % 1024,分1024个文件,每个Bitmap只需3.9MB,依然稳
如果数据倾斜(某个模特别多)?换成一致性哈希,或者对高频前缀再细分
如果是分布式环境?MapReduce/Spark直接上,原理一样
有没有更省空间的?布隆过滤器(可能误判)或RoaringBitmap(压缩更好)

真实案例

我朋友去年腾讯T9面被问这题,用了「分治+Bitmap」+手写了伪代码,当场过了。
面试官最后说了一句:“这方案我之前在QQ去重系统里见过,很好。”

所以,40亿QQ号去重,记住这8个字:
分而治之,位图当先

你准备怎么答?敢不敢现场写个Go/Python版本?我帮你改到面试官直接鼓掌!

文章已创建 3123

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部