40亿QQ号,不超过1G内存,如何去重?

40 亿 QQ 号(64 位整数级别)内存不超过 1GB 的条件下做去重,经典可行方案只有「位图(Bitmap / BitSet) 」,甚至进阶到「布隆过滤器」。

我给你讲最可落地的几种方案,按工程可行性来排:

✅ 最优方案:Bitmap(位图,精确去重)

1. 内存计算

假设 QQ 号范围:

最大约 10~11 位数字 ,最大值约 4,000,000,0000(按 400 亿上限算)。

但常见按 40 亿(4×10⁹) 来设计: 40 亿 bit ≈ 4,000,000,000 bits = 500,000,000 bytes ≈ 477 MB

结论:
Bitmap 完全可以在 1GB 内存内精确去重

2. 核心思想

用 bit 数组来表示某个 QQ 是否出现过:

  • 位置 = QQ号
  • 值 = 0 → 未出现
  • 值 = 1 → 已出现

读取每个 QQ:

  • 如果该位为 0 → 标记为 1
  • 如果已经是 1 → 说明重复

3. Java 示例代码(可直接运行)

java 复制代码
import java.io.BufferedReader;
import java.io.FileReader;


public class QQDedupBitmap {

    // 假设最大QQ号 = 4_000_000_000
    static final long MAX_QQ = 4_000_000_000L;
    static final int BIT_PER_BYTE = 8;

    public static void main(String[] args) throws Exception {
        // 分配位图
        byte[] bitmap = new byte[(int)(MAX_QQ / BIT_PER_BYTE + 1)];

        BufferedReader br = new BufferedReader(new FileReader("/Users/longjun/Downloads/qq.txt"));
        String line;

        while ((line = br.readLine()) != null) {
            long qq = Long.parseLong(line.trim());
            long index = qq / 8;
            int offset = (int)(qq % 8);

            if ((bitmap[(int)index] & (1 << offset)) != 0) {
                // 重复
                // 你可以输出或统计
                System.out.println("重复的QQ号:" + qq);
            } else {
                bitmap[(int)index] |= (1 << offset);
            }
        }
        br.close();
        // 恢复QQ号
        recoverQQFast(bitmap);
    }

    /**
     * 快速恢复QQ号
     * @param bitmap
     */
    public static void recoverQQFast(byte[] bitmap) {
        for (int i = 0; i < bitmap.length; i++) {
            int b = bitmap[i] & 0xFF;
            while (b != 0) {
                int offset = Integer.numberOfTrailingZeros(b);
                long qq = (long) i * 8 + offset;
                System.out.println(qq);
                b &= (b - 1);
            }
        }
    }
}

如果 QQ 号范围极大(比如 10¹² 级别)

Bitmap 不现实,使用:

✅ 布隆过滤器(Bloom Filter)

特点:

特点 说明
内存占用小 比 HashSet 小 10 倍以上
误判率 存在(会把新数据误认为重复)
不会漏判 重复一定判重复

适合场景:

  • 爬虫 URL 去重
  • 用户 ID 去重
  • 海量日志去重

Java 布隆过滤器实现(精简版)

java 复制代码
import java.util.BitSet;
import java.util.zip.CRC32;

public class BloomFilter {
    private BitSet bitSet;
    private int size;

    public BloomFilter(int size) {
        this.size = size;
        this.bitSet = new BitSet(size);
    }

    private int hash(long value, int seed) {
        long h = value ^ (value >>> 16) * seed;
        return (int)(Math.abs(h) % size);
    }

    public boolean isDuplicate(long value) {
        int h1 = hash(value, 31);
        int h2 = hash(value, 131);
        int h3 = hash(value, 1313);

        if (bitSet.get(h1) && bitSet.get(h2) && bitSet.get(h3)) {
            return true;
        }
        bitSet.set(h1);
        bitSet.set(h2);
        bitSet.set(h3);
        return false;
    }
}

🚀 超大数据工程级方案

当数据根本放不下内存:

  1. 外部排序 + 归并去重
  2. Hash 分桶 -> 小文件去重
  3. Hadoop / Spark

✅ 总结一句

在「40 亿 QQ 号 + 内存不超过 1GB」这个条件下:

目标 最优方案
精确去重 Bitmap 位图 ✅
允许误判 布隆过滤器 ✅
相关推荐
红尘散仙2 小时前
我把终端小说阅读器接上了 AI Agent:TRNovel 现在能用 skill 生成书源了
人工智能·后端·rust
卷毛的技术笔记3 小时前
告别硬编码!Spring AI Alibaba 实现 AI Agent 智能工具调用(Tool Calling)
java·人工智能·后端·python·spring·ai编程
会编程的土豆3 小时前
Go 语言反射(Reflection)详解
开发语言·后端·golang
喵个咪3 小时前
GoWind Toolkit Go后端代码生成 完整全流程实战
后端·go·orm
basketball6164 小时前
Go 语言从入门到进阶:4. 数组和MAP使用方法总结
开发语言·后端·golang
qq_2518364574 小时前
SpringBoot+Vue 共享电池柜管理系统 完整实现 前后端分离项目实战 完整代码
vue.js·spring boot·后端
zhangxingchao4 小时前
AI 大模型核心六:量化、Workflow 与 Agent、多轮 RAG
前端·人工智能·后端
IT_陈寒5 小时前
Vite打包时遇到的坑,原来问题出在这里
前端·人工智能·后端
ayqy贾杰7 小时前
基层管理的三板斧,在AI时代行不通了
前端·后端·团队管理
Apifox7 小时前
Apifox 5 月更新|Postman 导入优化、Runner 支持非 root 运行、请求代码自动带鉴权
前端·后端·安全