大數據面試之——大數據解決方案思維題

1.給定a、b兩個文件,各存放50億個url,每個url各佔64字節,內存限制是4G,讓你找出a、b文件共同的url?
  • 方案1:假如每個url大小爲10bytes,那麼可以估計每個文件的大小爲50G×64=320G,遠遠大於內存限制的4G,所以不可能將其完全加載到內存中處理,可以採用分治的思想來解決。
    • Step1:遍歷文件a,對每個url求取hash(url)%1000,然後根據所取得的值將url分別存儲到1000個小文件(記爲a0,a1,…,a999,每個小文件約300M);
    • Step2:遍歷文件b,採取和a相同的方式將url分別存儲到1000個小文件(記爲b0,b1,…,b999);
      巧妙之處:這樣處理後,所有可能相同的url都被保存在對應的小文件(a0vsb0,a1vsb1,…,a999vsb999)中,不對應的小文件不可能有相同的url。然後我們只要求出這個1000對小文件中相同的url即可。
    • Step3:求每對小文件ai和bi中相同的url時,可以把ai的url存儲到hash_set/hash_map中。然後遍歷bi的每個url,看其是否在剛纔構建的hash_set中,如果是,那麼就是共同的url,存到文件裏面就可以了。
  • 方案2:如果允許有一定的錯誤率,可以使用Bloomfilter,4G內存大概可以表示340億bit。將其中一個文件中的url使用Bloomfilter映射爲這340億bit,然後挨個讀取另外一個文件的url,檢查是否與Bloomfilter,如果是,那麼該url應該是共同的url(注意會有一定的錯誤率)。
2.有一個1G大小的一個文件,裏面每一行是一個詞,詞的大小不超過16字節,內存限制大小是1M,要求返回頻數最高的100個詞
  • Step1:順序讀文件中,對於每個詞x,取hash(x)%5000,然後按照該值存到5000個小文件(記爲f0,f1,…,f4999)中,這樣每個文件大概是200k左右,如果其中的有的文件超過了1M大小,還可以按照類似的方法繼續往下分,直到分解得到的小文件的大小都不超過1M;
  • Step2:對每個小文件,統計每個文件中出現的詞以及相應的頻率(可以採用trie樹/hash_map等),並取出出現頻率最大的100個詞(可以用含100個結點的最小堆),並把100詞及相應的頻率存入文件,這樣又得到了5000個文件;
  • Step3:把這5000個文件進行歸併(類似於歸併排序);
3.現有海量日誌數據保存在一個超級大的文件中,該文件無法直接讀入內存,要求從中提取某天出訪問百度次數最多的那個IP。
  • 方案一:

    • Step1:從這一天的日誌數據中把訪問百度的IP取出來,逐個寫入到一個大文件中;
    • Step2:注意到IP是32位的,最多有2^32個IP。同樣可以採用映射的方法,比如模1000,把整個大文件映射爲1000個小文件;
    • Step3:找出每個小文中出現頻率最大的IP(可以採用hash_map進行頻率統計,然後再找出頻率最大的幾個)及相應的頻率;
    • Step4:在這1000個最大的IP中,找出那個頻率最大的IP,即爲所求。
  • 方案二:算法思想:分而治之+Hash

    • Step1:IP地址最多有2^32=4G種取值情況,所以不能完全加載到內存中處理;
    • Step2:可以考慮採用“分而治之”的思想,按照IP地址的Hash(IP)%1024值,把海量IP日誌分別存儲到1024個小文件中。這樣,每個小文件最多包含4MB個IP地址;
    • Step3:對於每一個小文件,可以構建一個IP爲key,出現次數爲value的Hashmap,同時記錄當前出現次數最多的那個IP地址;
    • Step4:可以得到1024個小文件中的出現次數最多的IP,再依據常規的排序算法得到總體上出現次數最多的IP;
4.在2.5億個整數中找出不重複的整數,注,內存不足以容納這2.5億個整數
  • 方案1:採用2-Bitmap(每個數分配2bit,00表示不存在,01表示出現一次,10表示多次,11無意義)進行,共需內存2^32*2bit=1GB內存,還可以接受。然後掃描這2.5億個整數,查看Bitmap中相對應位,如果是00變01,01變10,10保持不變。所描完事後,查看bitmap,把對應位是01的整數輸出即可。
  • 方案2:也可採用與第1題類似的方法,進行劃分小文件的方法。然後在小文件中找出不重複的整數,並排序。然後再進行歸併,注意去除重複的元素。
5.給40億個不重複的unsignedint的整數,沒排過序的,然後再給一個數,如何快速判斷這個數是否在那40億個數當中?
  • 申請512M的內存,一個bit位代表一個unsignedint值。讀入40億個數,設置相應的bit位,讀入要查詢的數,查看相應bit位是否爲1,爲1表示存在,爲0表示不存在
6.有10個文件,每個文件1G,每個文件的每一行存放的都是用戶的query,每個文件的query都可能重複。要求你按照query的頻度排序
  • 方案1:

    • Step1: 順序讀取10個文件,按照hash(query)%10的結果將query寫入到另外10個文件(記爲)中。這樣新生成的文件每個的大小大約也1G(假設hash函數是隨機的)。
    • Step2: 找一臺內存在2G左右的機器,依次對用hash_map(query,query_count)來統計每個query出現的次數。利用快速/堆/歸併排序按照出現次數進行排序。將排序好的query和對應的query_cout輸出到文件中。這樣得到了10個排好序的文件(記爲)。
    • Step3:對這10個文件進行歸併排序(內排序與外排序相結合)。
  • 方案2:

    • 一般query的總量是有限的,只是重複的次數比較多而已,可能對於所有的query,一次性就可以加入到內存了。這樣,我們就可以採用trie樹/hash_map等直接來統計每個query出現的次數,然後按出現次數做快速/堆/歸併排序就可以了。
  • 方案3:

    • 與方案1類似,但在做完hash,分成多個文件後,可以交給多個文件來處理,採用分佈式的架構來處理(比如MapReduce),最後再進行合併。
7.怎麼在海量數據中找出重複次數最多的一個?

先做hash,然後求模映射爲小文件,求出每個小文件中重複次數最多的一個,並記錄重複次數。然後找出上一步求出的數據中重複次數最多的一個就是所求(具體參考前面的題)。

8.一個文本文件,大約有一萬行,每行一個詞,要求統計出其中最頻繁出現的前10個詞,請給出思想,給出時間複雜度分析。

這題是考慮時間效率。用trie樹統計每個詞出現的次數,時間複雜度是O(nle)(le表示單詞的平準長度)。然後是找出出現最頻繁的前10個詞,可以用堆來實現,前面的題中已經講到了,時間複雜度是O(nlg10)。所以總的時間複雜度,是O(nle)與O(nlg10)中較大的哪一個。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章