如何快速判断一个key是否存在在亿级数据中(bloomFilters)

面试题java

如今有一个很是庞大的数据(亿级),假设全是 int 类型。如今我给你一个数,你须要告诉我它是否存在其中(尽可能高效)面试

分析算法

采用bloomFilters进行实现(时间&空间尽量的有效),bloomFilters也经常用在防止缓存穿透,即服务请求在发送到缓存以前,先查找下bloomFilters,检查对应的key是否存在,不存在直接返回;存在再进入到缓存进行查询->DB查询数组

实现思路:缓存

实际实现采用屡次HASH,查看对应数组内存储的值是否为1,屡次hash结果均为1,则认为是存在;存在必定的误判率;hash算法尽量采用一致性hash方式,确保数据分布较为均匀this

 

 

 1 package com.hero.cases;  2 
 3 import com.beust.jcommander.internal.Lists;  4 import org.junit.Assert;  5 import org.junit.Test;  6 
 7 import java.util.List;  8 
 9 /**
 10  * @Des:判断亿级元素是否存在  11  * @Auther: 飞狐  12  * @Date: 2019/3/29  13  */
 14 public class BloomFilters {  15 
 16     /**
 17  * 数组长度  18      */
 19     private int arraySize;  20 
 21     private int[] array;  22 
 23     public BloomFilters(int arraySize){  24         this.arraySize = arraySize;  25         array = new int[arraySize];  26  }  27 
 28     /**
 29  * 写入数据(通过3次Hash,把数组对应的位置标识为1)  30  * @param key  31      */
 32     public void add(String key){  33         int first = hashcode_1(key);  34         int second = hashcode_2(key);  35         int third = hashcode_3(key);  36 
 37         array[first % arraySize] = 1;  38         array[second % arraySize] = 1;  39         array[third % arraySize] = 1;  40  }  41 
 42 
 43     public int hashcode_1(String key){  44         int hash = 0;  45         int i ;  46         for(i = 0; i < key.length(); i++){  47             hash = 33 * hash + key.charAt(i);  48  }  49         return Math.abs(hash);  50  }  51 
 52 
 53     /**
 54  * FNV1_32_HASH算法  55  * @param data  56  * @return
 57      */
 58     private int hashcode_2(String data){  59         final int p = 16777619;  60         int hash = (int) 2166136261L;  61         for(int i = 0; i < data.length(); i++){  62             hash = (hash ^ data.charAt(i)) * p;  63  }  64         hash += hash << 13;  65         hash ^= hash >> 7;  66         hash += hash << 3;  67         hash ^= hash >> 17;  68         hash += hash << 5;  69         
 70         return Math.abs(hash);  71  }  72 
 73     private int hashcode_3(String key){  74         int hash,i;  75         for(hash = 0, i= 0; i < key.length();++i){  76             hash += key.charAt(i);  77             hash += (hash << 10);  78             hash ^= hash >> 6;  79  }  80         hash += hash << 3;  81         hash ^= hash >> 11;  82         hash += hash << 15;  83         return Math.abs(hash);  84  }  85 
 86     /**
 87  * 判断元素是否存在  88  * @param key  89  * @return
 90      */
 91     public boolean check(String key){  92         int first = hashcode_1(key);  93         int second = hashcode_2(key);  94         int third = hashcode_3(key);  95 
 96         if(array[first % arraySize] == 0){  97             return false;  98  }  99 
100         if(array[second % arraySize] == 0){ 101             return false; 102  } 103 
104         if(array[third % arraySize] == 0){ 105             return false; 106  } 107         return true; 108  } 109 
110 }

运行结果:spa

检查1: true
检查2: true
检查3: true
检查999999: true
检查400230340: false
执行时间:2261
相关文章
相关标签/搜索