目錄java
海量數據計算總結node
海量數據去重總結python
在解決問題以前,要先計算一下海量數據須要佔多大的容量。常見的單位換算以下:程序員
1 byte = 8 bit面試
1 KB = 210 byte = 1024 byte ≈ 103 byte數組
1 MB = 220 byte ≈ 10 6 byteide
1 GB = 230 byte ≈ 10 9 byte函數
1 億 = 108oop
1 個整數佔 4 byte,1 億個整數佔 4*108 byte ≈ 400 MB。學習
能夠將海量數據拆分到多臺機器上和拆分到多個文件上:
若是數據量很大,沒法放在一臺機器上,就將數據拆分到多臺機器上。這種方式可讓多臺機器一塊兒合做,從而使得問題的求解更加快速。可是也會致使系統更加複雜,並且須要考慮系統故障等問題;
若是在程序運行時沒法直接加載一個大文件到內存中,就將大文件拆分紅小文件,分別對每一個小文件進行求解。
有如下策略進行拆分:
拆分以後的結果還只是局部結果,須要將局部結果彙總爲總體的結果。
注:大部分海量數據均可以使用hash取模來處理,由於同一個值hash取模後必定會分配到同一個位置。若是內存實在小,N的值能夠取大一些。再者,Hadoop和spark也是處理海量數據的方案,不過非大數據方向應該不作要求。
下面是海量數據去重問題:
對於海量數據,要求判斷一個數據是否已經存在。這個數據頗有多是字符串,例如 URL。
最直觀的方法是使用 HashSet 存儲,那麼就能以 O(1) 的時間複雜度判斷一個數據是否已經存在。
考慮到數據是海量的,那麼就須要使用拆分的方式將數據拆分到多臺機器上,分別在每臺機器上使用 HashSet 存儲。咱們須要使得相同的數據拆分到相同的機器上,可使用哈希取模的拆分方式進行實現。
若是海量數據是整數,而且範圍不大時,就可使用 BitSet 存儲。經過構建必定大小的比特數組,而且讓每一個整數都映射到這個比特數組上,就能夠很容易地知道某個整數是否已經存在。由於比特數組比整型數組小的多,因此一般狀況下單機就能處理海量數據。
如下是一個 BitSet 的實現,固然在實際開發中能夠直接使用語言內置的實現。
class BitSet {
int[] bitset;
public BitSet(int size) {
bitset = new int[(size >> 5) + 1]; // divide by 32
}
boolean get(int pos) {
int wordNumber = (pos >> 5); // divide by 32
int bitNumber = (pos & 0x1F); // mod 32
return (bitset[wordNumber] & (1 << bitNumber)) != 0;
}
void set(int pos) {
int wordNumber = (pos >> 5); // divide by 32
int bitNumber = (pos & 0x1F); // mod 32
bitset[wordNumber] |= 1 << bitNumber;
}
}
複製代碼
使用 BitSet 還能夠很容易地解決一個整數出現次數的問題,例如使用兩個比特數組就能夠存儲 0~3 的信息。其實判重問題也能夠簡單當作一個數據出現的次數是否爲 1,所以一個比特數組就夠了。
布隆過濾器可以以極小的空間開銷解決海量數據判重問題,可是會有必定的誤判機率。它主要用在網頁黑名單系統、垃圾郵件過濾系統、爬蟲的網址判重系統。
布隆過濾器也是使用 BitSet 存儲數據,可是它進行了必定的改進,從而解除了 BitSet 要求數據的範圍不大的限制。在存儲時,它要求數據先通過 k 個哈希函獲得 k 個位置,並將 BitSet 中對應位置設置爲 1。在查找時,也須要先通過 k 個哈希函數獲得 k 個位置,若是全部位置上都爲 1,那麼表示這個數據存在。
因爲哈希函數的特色,兩個不一樣的數經過哈希函數獲得的值可能相同。若是兩個數經過 k 個哈希函數獲得的值都相同,那麼使用布隆過濾器會將這兩個數判爲相同。
能夠知道,令 k 和 m 都大一些會使得誤判率下降,可是這會帶來更高的時間和空間開銷。
布隆過濾器會誤判,也就是將一個不存在的數判斷爲已經存在,這會形成必定的問題。例如在垃圾郵件過濾系統中,會將一個郵件誤判爲垃圾郵件,那麼就收不到這個郵件。可使用白名單的方式進行補救。
Trie 樹又叫又叫字典樹、前綴樹、單詞查找樹,它是一顆多叉查找樹。與二叉查找樹不一樣,鍵不是直接保存在節點中,而是由節點在樹中的位置決定。
若是海量數據是字符串數據,那麼就能夠用很小的空間開銷構建一顆 Trie 樹,空間開銷和樹高有關。
Leetcode : Implement Trie (Prefix Tree)
class Trie {
private class Node {
Node[] childs = new Node[26];
boolean isLeaf;
}
private Node root = new Node();
public Trie() {
}
public void insert(String word) {
insert(word, root);
}
private void insert(String word, Node node) {
if (node == null) return;
if (word.length() == 0) {
node.isLeaf = true;
return;
}
int index = indexForChar(word.charAt(0));
if (node.childs[index] == null) {
node.childs[index] = new Node();
}
insert(word.substring(1), node.childs[index]);
}
public boolean search(String word) {
return search(word, root);
}
private boolean search(String word, Node node) {
if (node == null) return false;
if (word.length() == 0) return node.isLeaf;
int index = indexForChar(word.charAt(0));
return search(word.substring(1), node.childs[index]);
}
public boolean startsWith(String prefix) {
return startWith(prefix, root);
}
private boolean startWith(String prefix, Node node) {
if (node == null) return false;
if (prefix.length() == 0) return true;
int index = indexForChar(prefix.charAt(0));
return startWith(prefix.substring(1), node.childs[index]);
}
private int indexForChar(char c) {
return c - 'a';
}
}
複製代碼
Bloom Filters: Is element x in set S?
程序員面試金典
程序員代碼面試指南
推薦閱讀
歡迎關注我的公衆號【菜鳥名企夢】,公衆號專一:互聯網求職面經、java、python、爬蟲、大數據等技術分享**: 公衆號**菜鳥名企夢
後臺發送「csdn」便可免費領取【csdn】和【百度文庫】下載服務; 公衆號菜鳥名企夢
後臺發送「資料」:便可領取5T精品學習資料**、java面試考點和java面經總結,以及幾十個java、大數據項目,資料很全,你想找的幾乎都有