如何快速判斷一個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
相關文章
相關標籤/搜索