面試題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