40亿个QQ号,限制1G内存,如何去重?

40亿个QQ号,限制1G内存,如何去重?

40亿个unsigned int,如果直接用内存存储的话,需要:

4*4000000000 /1024/1024/1024 = 14.9G ,考虑到其中有一些重复的话,那1G的空间也基本上是不够用的。

想要实现这个功能,可以借助位图。

使用位图的话,一个数字只需要占用1个bit,那么40亿个数字也就是:

4000000000 * 1 /8 /1024/1024 = 476M

相比于之前的14.9G来说,大大的节省了很多空间。

比如要把我的QQ号"907607222"放到Bitmap中,就需要找到第907607222这个位置,然后把他设置成1就可以了。

这样,把40亿个数字都放到Bitmap之后,所有位置上是1的表示存在,不为1的表示不存在,相同的QQ号只需要设置一次1就可以了,那么,最终就把所有是1的数字遍历出来就行了。

✅什么是BitMap?有什么用?

位图(BitMap),基本思想就是用一个bit来标记元素,bit是计算机中最小的单位,也就是我们常说的计算机中的0和1,这种就是用一个位来表示的。

所谓位图,其实就是一个bit数组,即每一个位置都是一个bit,其中的取值可以是0或者1

像上面的这个位图,可以用来表示1,,4,6: 

 如果不用位图的话,我们想要记录1,4,,6 这三个整型的话,就需要用三个unsigned int,已知每个unsigned int占4个字节,那么就是3*4 = 12个字节,一个字节有8 bit,那么就是 12*8 = 96 个bit。

所以,位图最大的好处就是节省空间。

位图有很多种用途,特别适合用在去重、排序等场景中,著名的布隆过滤器就是基于位图实现的。

但是位图也有着一定的限制,那就是他只能表示0和1,无法存储其他的数字。所以他只适合这种能表示ture or false的场景。

什么是布隆过滤器,实现原理是什么?

布隆过滤器是一种数据结构,用于快速检索一个元素是否可能存在于一个集合(bit 数组)中。

它的基本原理是利用多个哈希函数,将一个元素映射成多个位,然后将这些位设置为 1。当查询一个元素时,如果这些位都被设置为 1,则认为元素可能存在于集合中,否则肯定不存在

所以,布隆过滤器可以准确的判断一个元素是否一定不存在,但是因为哈希冲突的存在,所以他没办法判断一个元素一定存在。只能判断可能存在。

所以,布隆过滤器是存在误判的可能的,也就是当一个不存在的Hero元素,经过hash1、hash2和hash3之后,刚好和其他的值的哈希结果冲突了。那么就会被误判为存在,但是其实他并不存在。

想要降低这种误判的概率,主要的办法就是降低哈希冲突的概率及引入更多的哈希算法。

下面是布隆过滤器的工作过程:

1、初始化布隆过滤器

在初始化布隆过滤器时,需要指定集合的大小和误判率。布隆过滤器内部包含一个bit数组和多个哈希函数,每个哈希函数都会生成一个索引值。

2、添加元素到布隆过滤器

要将一个元素添加到布隆过滤器中,首先需要将该元素通过多个哈希函数生成多个索引值,然后将这些索引值对应的位设置为 1。如果这些索引值已经被设置为 1,则不需要再次设置。

3、查询元素是否存在于布隆过滤器中

要查询一个元素是否存在于布隆过滤器中,需要将该元素通过多个哈希函数生成多个索引值,并判断这些索引值对应的位是否都被设置为 1。如果这些位都被设置为 1,则认为元素可能存在于集合中,否则肯定不存在。

布隆过滤器的主要优点是可以快速判断一个元素是否属于某个集合,并且可以在空间和时间上实现较高的效率。但是,它也存在一些缺点,例如:

1.布隆过滤器在判断元素是否存在时,有一定的误判率。、

2.布隆过滤器删除元素比较困难,因为删除一个元素需要将其对应的多个位设置为 0,但这些位可能被其他元素共享。

应用场景 

 布隆过滤器因为他的效率非常高,所以被广泛的使用,比较典型的场景有以下几个:

1、网页爬虫:爬虫程序可以使用布隆过滤器来过滤掉已经爬取过的网页,避免重复爬取和浪费资源。

2、缓存系统:缓存系统可以使用布隆过滤器来判断一个查询是否可能存在于缓存中,从而减少查询缓存的次数,提高查询效率。布隆过滤器也经常用来解决缓存穿透的问题。

3、分布式系统:在分布式系统中,可以使用布隆过滤器来判断一个元素是否存在于分布式缓存中,避免在所有节点上进行查询,减少网络负载。

4、垃圾邮件过滤:布隆过滤器可以用于判断一个邮件地址是否在垃圾邮件列表中,从而过滤掉垃圾邮件。

5、黑名单过滤:布隆过滤器可以用于判断一个IP地址或手机号码是否在黑名单中,从而阻止恶意请求。

如何使用

Java中可以使用第三方库来实现布隆过滤器,常见的有Google Guava库和Apache Commons库以及Redis。

如Guava:

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
public class BloomFilterExample {
    public static void main(String[] args) {
        // 创建布隆过滤器,预计插入100个元素,误判率为0.01
        BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(), 100, 0.01);
        // 插入元素
        bloomFilter.put("Lynn");
        bloomFilter.put("666");
        bloomFilter.put("八股文");
        // 判断元素是否存在
        System.out.println(bloomFilter.mightContain("Lynn")); // true
        System.out.println(bloomFilter.mightContain("张三"));  // false
    }
}

Apache Commons:

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.collections4.BloomFilter;
import org.apache.commons.collections4.functors.HashFunctionIdentity;
public class BloomFilterExample {
    public static void main(String[] args) {
        // 创建布隆过滤器,预计插入100个元素,误判率为0.01
        BloomFilter<String> bloomFilter = new BloomFilter<>(HashFunctionIdentity.hashFunction(StringUtils::hashCode), 100, 0.01);
        // 插入元素
        bloomFilter.put("Lynn");
        bloomFilter.put("666");
        bloomFilter.put("八股文");
        // 判断元素是否存在
        System.out.println(bloomFilter.mightContain("Lynn")); // true
        System.out.println(bloomFilter.mightContain("张三"));  // false
    }
}

Redis中可以通过Bloom模块来使用,使用Redisson可以:

Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
RBloomFilter<String> bloomFilter = redisson.getBloomFilter("myfilter");
bloomFilter.tryInit(100, 0.01);
bloomFilter.add("Lynn");
bloomFilter.add("666");
bloomFilter.add("八股文");
System.out.println(bloomFilter.contains("Lynn"));
System.out.println(bloomFilter.contains("张三"));
redisson.shutdown();

首先创建一个RedissonClient对象,然后通过该对象获取一个RBloomFilter对象,使用tryInit方法来初始化布隆过滤器,指定了最多能添加的元素数量为100,误判率为0.01。然后,使用add方法将元素"Hollis"、"666"和"八股文"添加到布隆过滤器中,使用contains方法来检查元素是否存在于布隆过滤器中。

或者Jedis也可以:

Jedis jedis = new Jedis("localhost");
jedis.bfCreate("myfilter", 100, 0.01);
jedis.bfAdd("myfilter", "Lynn");
jedis.bfAdd("myfilter", "666");
jedis.bfAdd("myfilter", "八股文");
System.out.println(jedis.bfExists("myfilter", "Lynn"));
System.out.println(jedis.bfExists("myfilter", "张三"));
jedis.close();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/22634.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OPPO哲库事件 “ 始末 ” ! 集体打哑谜?

1►OPPO哲库解散 2019 年&#xff0c;美国商务部以“科技网络安全”为由&#xff0c;将华为公司及其70家附属公司列入出口管制“实体名单”。与此同时&#xff0c;OPPO 创始人兼 CEO陈明永对外宣布&#xff0c;公司将为未来三年内投入 500 亿元用于前沿技术和深水区技术的探索…

安装编译PostgreSql15.3.0

一、下载源码 方式一 官网手动下载 https://www.postgresql.org/download/. 解压 tar -zxvf postgresql-14.2.tar.gz方式二 git clone git clone https://github.com/postgres/postgres.git解压或下载后计入postgres目录 cd postgres-15.3二、创建目录 用root账户创建 创建…

Apache Pulsar入门指南

1.概述 Apache Pulsar 是灵活的发布-订阅消息系统&#xff08;Flexible Pub/Sub messaging&#xff09;&#xff0c;采用计算与存储分离的架构。雅虎在 2013 年开始开发 Pulsar &#xff0c;于 2016 年首次开源&#xff0c;目前是 Apache 软件基金会的顶级项目。Pulsar 具有支…

C++系列六:运算符

C运算符 1. 算术运算符2. 关系运算符3. 逻辑运算符4. 按位运算符5. 取地址运算符6. 取内容运算符7. 成员选择符8. 作用域运算符9. 总结 1. 算术运算符 算术运算符用于执行基本数学运算&#xff0c;例如加减乘除和取模等操作。下表列出了C中支持的算术运算符&#xff1a; 运算…

为什么要做问卷调查?企业获得用户心声的捷径

问卷调查作为一种重要的数据收集方法&#xff0c;在市场营销、社会学研究、用户研究等领域得到广泛应用。通过问卷调查&#xff0c;我们可以了解受访者的态度、行为、需求等信息&#xff0c;进而为企业和组织的决策提供支持。那么&#xff0c;为什么要做问卷调查呢&#xff1f;…

day5 - 利用阈值勾勒

阈值处理在计算机视觉技术中占有十分重要的位置&#xff0c;他是很多高级算法的底层逻辑之一。本实验将练习使用图像阈值处理技术来处理不同的情况的图像&#xff0c;并获得图像轮廓。 完成本期内容&#xff0c;你可以&#xff1a; 了解图像阈值处理技术的定义和作用 掌握各阈…

苏州狮山广场能耗管理系统

摘要&#xff1a;随着社会生活水平的提高&#xff0c;经济的繁荣发展&#xff0c;人们对能源的需求逐渐增长&#xff0c;由此带来的能源危机日益严重。商场如何实时的了解、分析和控制商场的能源消耗已成为需要解决的迫在眉睫的难题。传统的能源消耗智能以月/季度/年为周期进行…

Autosar RTE S/R接口implicit与Explicit的实现与区别

文章目录 前言接口的代码implicitIReadIWrite ExplicitReadWrite 区别与使用场景总结 前言 Autosar官方文档阅读起来比较费劲&#xff0c;一般从实际应用中来了解更多规范中的内容。本文介绍最常用的RTE S/R接口的implicit隐式与Explicit显式两种方式的实现与差别 接口的代码…

Node.js

目录 Node.js是什么 入门案例 fs文件系统模块 案例 http模块 创建最简单的web服务器 网页跳转案例 模块化 模块化概念 模块化规范 Node.js 中模块的分类 加载模块 模块作用域 module对象 Node.js中的模块化规范 第三方模块 (包) 安装包的命令 卸载包的命令 …

oracle客户端的安装教程

文章目录 一、安装前的准备工作 1.1、百度网盘安装包的连接 1.2、百度网盘oracle11g软件包 二、oracle数据库客户端的安装与数据的准备 安装步骤 前言 本文主要讲解oracle客户端的安装与简单使用过程 一、安装前的准备工作 1.1、百度网盘安装包的连接 客户端的软件包 …

【Java EE 初阶】网络编程套接字UDP

目录 1.为什么需要网络编程&#xff1f; 2.什么是网络编程&#xff1f; 3.发送端和接收端 4.请求和响应 5.客户端和服务端 6.如何进行网络编程&#xff08;Socket套接字&#xff09; 1.如何进行网络编程 2.TCP与UDP的区别 1.流套接字&#xff1a;使用传输层TCP协议 2.…

面了一个测试工程师要求月薪23K,总感觉他藏了很多面试题...

最近有朋友去华为面试&#xff0c;面试前后进行了20天左右&#xff0c;包含4轮电话面试、1轮笔试、1轮主管视频面试、1轮hr视频面试。 据他所说&#xff0c;80%的人都会栽在第一轮面试&#xff0c;要不是他面试前做足准备&#xff0c;估计都坚持不完后面几轮面试。 其实&…

【前端知识】Cookie, Session,Token和JWT的发展及区别(四)

【前端知识】Cookie, Session,Token和JWT的发展及区别&#xff08;四&#xff09; 9. JWT9.1 JWT的背景及定义&#xff08;1&#xff09;JWT的字面理解&#xff08;2&#xff09;JWT与传统Token的区别 9.2 JWT的组成&#xff08;1&#xff09; Header&#xff08;头部&#xff…

【负载均衡式在线OJ】 数据库

文章目录 41.使用Postman进行综合调试42.了解-前端预备52. 添加oj用户到MySQL53. 使用MySQL_Workbench创建表结构54. 测试录题功能55.重新设计oj_model56.编写oj_model具体代码57.MySQL综合测试58.结项与项目扩展思路 41.使用Postman进行综合调试 完善判题功能 先编译再测试 …

项目管理PMP好考吗,没有经验?

现在越来越多的产品经理和开发人员也投入到考PMP的大军中&#xff0c;在真实的项目中也会有很多产品经理兼任项目经理的职责&#xff0c;这点还是比较常见的&#xff0c;如果说产品或者开发人员考了PMP证书&#xff0c;本身也会让你在找工作的大军中更具有优势&#xff0c;俗话…

一文读懂selenium自动化测试(基于Python)

前言 我们今天来聊聊selenium自动化测试&#xff0c;我们都知道selenium是一款web自动化测试的工具&#xff0c;它应该如何去运用呢?我们接着看下去。 ​1、Selenium简介&#xff1a; 1.1 Selenium&#xff1a; Selenium是一款主要用于Web应用程序自动化测试的工具集合。Sele…

Vue事件

1&#xff0c;回顾js中的事件&#xff1f; 答&#xff1a;标签的状态变化或者被外物改变则称为事件。一般js中的事件都是由浏览器捕捉得到&#xff0c;然后传递给js引擎&#xff0c;浏览器检测到HTML页面中某个标签元素发生了指定的事件&#xff0c;而对应的DOM节点必须去调用回…

Python系列模块之标准库re详解

感谢点赞和关注 &#xff0c;每天进步一点点&#xff01;加油&#xff01; 目录 一、Python 正则表达式 1.1 re模块常用操作 1.2 re.match 1.3 re.search 1.4 re.findall 1.5 re.compile 函数 1.6 re.sub 检索和替换 1.7 re.split拆分 1.8 实战案例&#xff1a;根据文…

全网最全性能测试总结,分析性能测试问题+性能调优方案...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能分析和优化一…

vs code 配置net 开发环境.并搭配vs相似的解决方案面板

由于在本人在Linux22.04下安装Rider 一直处于卡死系统状态.不得不使用该方式 以下为安装步骤 安装 VS code https://code.visualstudio.com/Download 安装 mono https://www.mono-project.com/download/stable/#download-lin 安装 NET SDK https://learn.microsoft.com/zh…