做騰訊tsa比賽時,遇到海量資料的問題,工作站54g記憶體,把原始資料讀進去各種操作後生成特徵,再訓練導致崩掉。後來只能把特徵做好後存成檔案,需要用的時候再讀進去,省去了生成的中間環節檔案。為了確保記憶體受得住,把特徵按照天來存,最終總算是可以順利訓練和**了。
記憶體總是不夠的。對於海量資料處理的策略無非是:分解,大化小。除此沒啥好辦法,除非加記憶體。但總歸需要在軟體上下功夫,資源總是有限的。避免浪費。
《九章演算法》提供有數十道關於大資料的題目。特此記錄。
(1)給乙個超過100g大小的log file, log中存著ip位址, 設計演算法找到出現次數最多的ip位址?與上題條件相同,如何找到top k的ip?如何直接用linux系統命令實現?
答:前兩問其實是一問,top k 分別為1和k。該檔案大小為100g,放入記憶體壓力太大,分解為若干小檔案,每個小檔案則可以在記憶體中處理。這叫做hash分桶法。
將該檔案按照 ip 的最後三位分為256個小檔案。若均勻則每個小檔案大小約為400m,可在記憶體中直接操作。用公式表述為:file_id = hash(ip) % 1000。 在每個小檔案中統計各 ip 的出現次數。可以用ip為key,其出現次數為value統計。取出每個小檔案中的top k 的記錄。要求次數最多時k=1,前5則k=5。 合併這些小檔案,取出前top k的記錄。
注意:相同的ip會對映到同乙個小檔案/桶中。換句話說不同桶中的ip不重複。
第3問:
// sort 對檔案公升序排列;去掉重複行並在輸出中加上計數;根據第一列計數值對檔案按照數值大小逆序排列;取出前10行顯示
sort log_file | uniq -c | sort -n -r -k 1 | head -10(2)給定100億個整數,設計演算法找到只出現一次的整數。
答:100億個整數的占用空間約為40gb。可參考(1)解法,hash分桶法。在每個檔案中計算時,可使用bitmap方法,可用2個bit位表示乙個數的情況。
(3)給兩個檔案,分別有100億個整數,我們只有1g記憶體,如何找到兩個檔案交集?
答:設兩個檔案分別為a和b。分別將檔案對映到1000個桶中。得到a_1,a_2…和b_1,b_2…。若兩者有交集,則交集的數字必然存在於每對a_i,b_i。例如a中的512對映到a_5中,則b中若有512也會對映到b_5中。對每對小檔案找到交集,兩個表對應位相與。最後合併。
還可以直接bitmap:
整數是32bit的話,直接使用bitmap的方法就能實現了。所有整數共2^32種可能,每個數用2bit來表示,「00」表示兩個檔案均沒出現,「10」表示檔案1出現過,「01」表示檔案2出現過,「11」表示兩個檔案均出現過,共需(2^32)*2/8=1gb記憶體,遍歷兩個檔案中的所有整數,然後尋找bitmap中「11」對應的整數即是兩個檔案的交集,這樣即可線性時間複雜度完成。
(4)1個檔案有100億個int,1g記憶體,設計演算法找到出現次數不超過2次的所有整數?
答:採用hash分桶+組內bitmap。直接bitmap記憶體不夠。先分桶,然後每個組內採用擴充套件的bitmap,每個數字採用2個bit表示。0未出現過,1出現過1次,2(二進位制為11)出現了2次或以上。然後將各組結果合併即可。
(5)給兩個檔案,分別有100億個query,我們只有1g記憶體,如何找到兩個檔案交集?分別給出精確演算法和近似演算法?
答:精確演算法就是(3)中所說。近似演算法?
允許有一定的錯誤率,可以使用bloom filter(即布隆過濾器),1g記憶體大概可以表示80億bit。將其中乙個檔案中的query使用bloom filter對映為這80億bit。然後挨個讀取另外乙個檔案的url,檢查是否與bloom filter,如果是,那麼該url應該是共同的url(注意會有一定的錯誤率)。
需要的為n*13(錯誤率為0.01時)。將其分為10個桶,每個大概為10億個,需要130億,1g記憶體大致可表示80億多,基本滿足。
(6)如何擴充套件bloomfilter使得它支援刪除元素的操作?
答:布隆過濾器,對每個數對映時,採用k個hash依次處理置位。第一次的1生效,其餘不生效。若要刪除,則需置對應的hash位為1,如此一來牽扯到其他。
布隆過濾器存在假正例:即某個數不在,但布隆認為它在。原因是其他數可能影響了對應位。即說是在,算個正例,但其實是假的不在。
但不存在假反例:若某個數在,則布隆一定可算出它在。在必有痕跡。假反例是指,說是不在,算個反例,其實是在的真的。
基本的布隆過濾器不支援刪除(deletion)操作,但是 counting filters 提供了一種可以不用重新構建布隆過濾器但卻支援元素刪除操作的方法。在counting filters中原來的位陣列中的每一位由 bit 擴充套件為 n-bit 計數器。
實際上,基本的布隆過濾器可以看作是只有一位的計數器的counting filters。原來的插入操作也被擴充套件為把 n-bit 的位計數器加1,查詢操作即檢查位陣列非零即可,而刪除操作定義為把位陣列的相應位減1。
但是該方法也有位的算術溢位問題,即某一位在多次刪除操作後可能變成負值,所以位陣列大小 m 需要充分大。另外乙個問題是counting filters不具備伸縮性,由於counting filters不能擴充套件,所以需要儲存的最大的元素個數需要提前知道。否則一旦插入的元素個數超過了位陣列的容量,false positive的發生概率將會急劇增加。類似於引用計數。
(7)如何擴充套件bloomfilter使得它支援計數操作?
答案見(6)討論的。
(8)給上千個檔案,每個檔案大小為1k—100m。給n個詞,設計演算法對每個詞找到所有包含它的檔案,你只有100k記憶體。
答:(9)有乙個詞典,包含n個英文單詞,現在任意給乙個字串,設計演算法找出包含這個字串的所有英文單詞?
答:
面試題 海量資料處理題
問題一 給你a,b兩個檔案,各存放50億條url,每條url占用64位元組,記憶體限制是4g,讓你找出a,b檔案共同的url。如果是三個乃至n個檔案呢?方案 先算一下4g有多少位 bit 4g 2 32 8 bit 320億 bit,n才50億,可以用位圖法。將其中乙個檔案中的url使用bloom ...
海量資料處理面試題
海量資料處理思路分析題 1.給乙個超過100g大小的log file,log中存著ip位址,設計演算法找到出現次數最多的ip位址?解決方法 雜湊切割topk。將100g的大檔案分成1000份,根據同乙個雜湊函式hashfunc將ip對映到向對應的檔案 每個檔案的大小可以在記憶體中處理 中,相同的ip...
海量資料處理面試題
什麼是海量資料處理?所謂海量資料處理,無非就是基於海量資料上的儲存 處理 操作。何謂海量,就是資料量太大,所以導致要麼是無法在較短時間內迅速解決,要麼是資料太大,導致無法一次性裝入記憶體。那解決辦法呢?針對時間,我們可以採用巧妙的演算法搭配合適的資料結構,如bloom filter hash bit...