如何快速判断一个key是否存在在亿级数据中(bloomFilters)
面试题
现在有一个非常庞大的数据(亿级),假设全是 int 类型。现在我给你一个数,你需要告诉我它是否存在其中(尽量高效)
分析
采用bloomFilters进行实现(时间&空间尽可能的有效),bloomFilters也常常用在防止缓存穿透,即服务请求在发送到缓存之前,先查找下bloomFilters,检查对应的key是否存在,不存在直接返回;存在再进入到缓存进行查询->DB查询
实现思路:
实际实现采用多次HASH,查看对应数组内存储的值是否为1,多次hash结果均为1,则认为是存在;存在一定的误判率;hash算法尽可能采用一致性hash方式,确保数据分布较为均匀
package com.hero.cases; import com.beust.jcommander.internal.Lists;
import org.junit.Assert;
import org.junit.Test; import java.util.List; /**
* @Des:判断亿级元素是否存在
* @Auther: 飞狐
* @Date: 2019/3/29
*/
public class BloomFilters { /**
* 数组长度
*/
private int arraySize; private int[] array; public BloomFilters(int arraySize){
this.arraySize = arraySize;
array = new int[arraySize];
} /**
* 写入数据(经过3次Hash,把数组对应的位置标识为1)
* @param key
*/
public void add(String key){
int first = hashcode_1(key);
int second = hashcode_2(key);
int third = hashcode_3(key); array[first % arraySize] = 1;
array[second % arraySize] = 1;
array[third % arraySize] = 1;
} public int hashcode_1(String key){
int hash = 0;
int i ;
for(i = 0; i < key.length(); i++){
hash = 33 * hash + key.charAt(i);
}
return Math.abs(hash);
} /**
* FNV1_32_HASH算法
* @param data
* @return
*/
private int hashcode_2(String data){
final int p = 16777619;
int hash = (int) 2166136261L;
for(int i = 0; i < data.length(); i++){
hash = (hash ^ data.charAt(i)) * p;
}
hash += hash << 13;
hash ^= hash >> 7;
hash += hash << 3;
hash ^= hash >> 17;
hash += hash << 5; return Math.abs(hash);
} private int hashcode_3(String key){
int hash,i;
for(hash = 0, i= 0; i < key.length();++i){
hash += key.charAt(i);
hash += (hash << 10);
hash ^= hash >> 6;
}
hash += hash << 3;
hash ^= hash >> 11;
hash += hash << 15;
return Math.abs(hash);
} /**
* 判断元素是否存在
* @param key
* @return
*/
public boolean check(String key){
int first = hashcode_1(key);
int second = hashcode_2(key);
int third = hashcode_3(key); if(array[first % arraySize] == 0){
return false;
} if(array[second % arraySize] == 0){
return false;
} if(array[third % arraySize] == 0){
return false;
}
return true;
} }
运行结果:
检查1: true
检查2: true
检查3: true
检查999999: true
检查400230340: false
执行时间:2261
如何快速判断一个key是否存在在亿级数据中(bloomFilters)的更多相关文章
- zoj 月赛B题(快速判断一个大数是否为素数)
给出一个64位的大数,如何快速判断其是否为素数 #include<algorithm> #include<cstdio> #include<cstring> #in ...
- Java源码中的发现:快速判断一个int值是几位数
判断一个int值是几位数,要是我自己实现,估计又会想到除法和模运算了,偶然在java标准API源码中发现的写法,很强大. public class Test { final static int[] ...
- 一道腾讯面试题:如何快速判断某 URL 是否在 20 亿的网址 URL 集合中?布隆过滤器
何为布隆过滤器 还是以上面的例子为例: 判断逻辑: 多次哈希: Guava的BloomFilter 创建BloomFilter 最终还是调用: 使用: 算法特点 使用场景 假设遇到这样一个问题:一个网 ...
- bitmap-如何判断某个整数是否存在40亿个整数中?
有这样一道面试题:现有40亿个整数,如果再给定一个新的整数,怎么判断这个整数是否在这40亿个整数中? 你可能首先会想到用一个set存储,那个新数只需判断是否在set中.但是如果用set存储的话,如果一 ...
- 判断一个key 是否在map中存在
public class Test { /** * @param args */ public static void main(String[] args) { // TODO Auto-gener ...
- 判断一个类到底是从哪个jar包中调用的工具类
项目中使用的jar包较多时,会出现jar冲突的情况,有时候很难判断当前使用的这个类是从哪个jar包中调用的.因为一般我们只能看到jar包的名称,不清楚其中的类的目录结构. 这个类的作用就是说明当前调用 ...
- 20 亿的 URL 集合,如何快速判断其中一个?
假设遇到这样一个问题:一个网站有 20 亿 url 存在一个黑名单中,这个黑名单要怎么存?若此时随便输入一个 url,你如何快速判断该 url 是否在这个黑名单中?并且需在给定内存空间(比如:500M ...
- 两天快速开发一个自己的微信小程序
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "Songti SC" } p.p2 { margin: 0.0px 0. ...
- 如何快速开发一个支持高效、高并发的分布式ID生成器
ID生成器是指能产生不重复ID服务的程序,在后台开发过程中,尤其是分布式服务.微服务程序开发过程中,经常会用到,例如,为用户的每个请求产生一个唯一ID.为每个消息产生一个ID等等,ID生成器也是进行无 ...
随机推荐
- 在Mac os 10.11 下编译Berkeley caffe
安装各种补丁和组件,缺啥装啥. python 采用 2.7.13 最新版. 安装工具 homebrew , pip 很繁琐,但是没难度. 由于本人macbook pro不支持CUDA,所以不用安装. ...
- pip使用国内源
对于Python开发用户来讲,PIP安装软件包是家常便饭.但国外的源下载速度实在太慢,浪费时间.而且经常出现下载后安装出错问题.所以把PIP安装源替换成国内镜像,可以大幅提升下载速度,还可以提高安装成 ...
- XCube和X组件的入门级使用教程
我也是一个入门级的初学者,在学习魔方的时候,很多不是很懂的地方,而网上的资料又比较少.尤其是Newlife的论坛打不开的情况下 所以就想着把这个初级项目做完后,做一个入门级教程.保证人人都看得懂(.^ ...
- spoj1026Favorite Dice
题意翻译 一个n面的骰子,求期望掷几次能使得每一面都被掷到. 题目描述 BuggyD loves to carry his favorite die around. Perhaps you wonde ...
- java中之内存溢出说明
java语句是编译型和解释型语言,选通过编译命令javac 把java文件编译为.class字节码文件,然后通过java虚拟机(JVM)加载class文件到内存运行. 而java虚拟机在运行程序时有自 ...
- mysql 几种日志
mysql 5.5 有以下几种日志: 错误日志(error log): log-err 查询日志(general query log): log 慢查询日志: -log-slow-queries ...
- Python爬虫入门之Urllib库的高级用法
1.设置Headers 有些网站不会同意程序直接用上面的方式进行访问,如果识别有问题,那么站点根本不会响应,所以为了完全模拟浏览器的工作,我们需要设置一些Headers 的属性. 首先,打开我们的浏览 ...
- VIPKID 内推---开发工程师
VIPKID 目前是K12教育领域最大的一家公司,目前已发展到6w名北美外教,服务于中国50w的小朋友,每天数十万节视频课程在线上进行. 有兴趣加入VIPKID的程序员小伙伴,请发简历到 gloryz ...
- 编译安装LAMP
编译安装MariaDB 创建MariaDB安装目录.数据库存放目录.建立用户和目录 先创建一个名为mysql且没有登录权限的用户和一个名为mysql的用户组,然后安装mysql所需的依赖库和依赖包,最 ...
- django中的Q查询
转载于:https://mozillazg.com/2015/11/django-the-power-of-q-objects-and-how-to-use-q-object.html 原文写的很详细 ...