大數據場景經典問題

1、海量ip數據,取頻率最高(種類有限)

具體問題:
  從海量日誌中提取出某日訪問次數最多的那個IP。
取模(可選)+hash。因爲IP的數目是有限的,最多2^32個,可以考慮使用hash將ip直接存入內存,然後進行統計。
方案:
  IP逐個寫入到一個大文件中。IP是32位的,最多有個2^32個IP。同樣可以採用映射的方法,比如模1000,把整個大文件映射爲1000個小文件,再找出每個小文中出現頻率最大的IP(可以採用hash_map進行頻率統計,然後再找出頻率最大的幾個)及相應的頻率。然後再在這1000個最大的IP中,找出那個頻率最大的IP,即爲所求。

2、海量日誌搜索記錄,取頻率最高(種類無限)

問題:
  搜索引擎會通過日誌文件把用戶每次檢索使用的所有檢索串都記錄下來,每個查詢串的長度爲1-255字節。假設目前有一千萬個記錄(總數是1千萬,但如去重,不超過3百萬個。請你統計最熱門的10個查詢串,要求使用的內存不能超過1G。

hash/trie樹+堆。
1. 先對這批海量數據預處理,在O(N)的時間內用Hash表完成排序;
2. 藉助堆這個數據結構,找出Top K,時間複雜度爲N‘logK。 即,藉助堆結構,我們可以在log量級的時間內查找和調整/移動。因此,維護一個K(該題目中是10)大小的小根堆,最終的時間複雜度是:O(N) + N’* O(logK),(N爲1000萬,N’爲300萬)。
2. 採用trie樹(代替hash表),關鍵字域存該查詢串出現的次數,沒有出現爲0。最後用10個元素的最小推來對出現頻率進行排序。

3、大文件topN詞頻

問題:
  有一個1G大小的一個文件,裏面每一行是一個詞,詞的大小不超過16字節,內存限制大小是1M。返回頻數最高的100個詞。
取模分成n份(若其中有超過內存的還可以再分)+hash/trie樹+堆
方案
  順序讀文件中,對於每個詞x,取hash(x)%5000,然後按照該值存到5000個小文件(記爲x0,x1,…x4999)中。這樣每個文件大概是200k左右。
如果其中的有的文件超過了1M大小,還可以按照類似的方法繼續往下分,直到分解得到的小文件的大小都不超過1M。 對每個小文件,統計每個文件中出現的詞以及相應的頻率(可以採用trie樹/hash_map等),並取出出現頻率最大的100個詞(可以用含100個結點的最小堆),並把100個詞及相應的頻率存入文件,這樣又得到了5000個文件。下一步就是把這5000個文件進行歸併(類似與歸併排序)的過程了。

4、多個大文件,詞頻排序

問題: 有10個文件,每個文件1G,每個文件的每一行存放的都是用戶的query,每個文件的query都可能重複。要求你按照query的頻度排序。
取模(可選)+hashmap/tire樹+堆/歸併/mapreduce排序
1. 順序讀取10個文件,按照hash(query)%10的結果將query寫入到另外10個文件(記爲)中。這樣新生成的文件每個的大小大約也1G(假設hash函數是隨機的)。 找一臺內存在2G左右的機器,依次對用hash_map(query, query_count)來統計每個query出現的次數。利用快速/堆/歸併排序按照出現次數進行排序。將排序好的query和對應的query_cout輸出到文件中。這樣得到了10個排好序的文件(記爲)。對這10個文件進行歸併排序(內排序與外排序相結合)。
2. 一般query的總量是有限的,只是重複的次數比較多而已,可能對於所有的query,一次性就可以加入到內存了。這樣,我們就可以採用trie樹/hash_map等直接來統計每個query出現的次數,然後按出現次數做快速/堆/歸併排序就可以了。
3. 與方案1類似,但在做完hash,分成多個文件後,可以交給多個文件來處理,採用分佈式的架構來處理(比如MapReduce),最後再進行合併。

5、兩個大文件找共同(是否允許誤差?)

問題:
  給定a、b兩個文件,各存放50億個url,每個url各佔64字節,內存限制是4G,讓你找出a、b文件共同的url?
分治算法+hash_set 或者 允許一定錯誤的布隆過濾器
1.分治算法:
  估計每個文件安的大小爲5G×64=320G,大於內存限制,考慮採取分治的方法。遍歷文件a,對每個url求取hash(url)%1000,然後根據所取得的值將url分別存儲到1000個小文件中。這樣每個小文件的大約爲300M。同理遍歷文件b,這樣處理後,所有可能相同的url都在對應的小文件(a0vsb0,…,a999vsb999)中,不對應的小文件不可能有相同的url。 求出1000對小文件中相同的url,把其中一個小文件的url存儲到hash_set中。然後遍歷另一個小文件的每個url,看其是否在剛纔構建的hash_set中,如果是,那麼就是共同的url,存到文件裏面就可以了。
2.布隆過濾器:
  如果允許有一定的錯誤率,可以使用Bloom filter,4G內存大概可以表示340億bit。將其中一個文件中的url使用Bloom filter映射爲這340億bit,然後挨個讀取另外一個文件的url,檢查是否與Bloom filter,如果是,那麼該url應該是共同的url(注意會有一定的錯誤率)。

6、內存限制下找不重複數

問題:
  在2.5億個整數中找出不重複的整數,注,內存不足以容納這2.5億個整數。
位圖或分治
1. 2-Bitmap:
   採用2-Bitmap(每個數分配2bit,00表示不存在,01表示出現一次,10表示多次,11無意義)進行,共需內存內存,還可以接受。然後掃描這2.5億個整數,查看Bitmap中相對應位,如果是00變01,01變10,10保持不變。所描完事後,查看bitmap,把對應位是01的整數輸出即可。
2.分治:
  也可採用與第1題類似的方法,進行劃分小文件的方法。然後在小文件中找出不重複的整數,並排序。然後再進行歸併,注意去除重複的元素。

7、海量數據查找是否存在某個數

問題: 給40億個不重複的unsigned int的整數,沒排過序的,然後再給一個數,如何快速判斷這個數是否在那40億個數當中?
快排+二分 或 位圖 或 按搜索的數從最高位開始每次篩選一部分
1. 快速排序+二分查找。
2.
  申請512M的內存,一個bit位代表一個unsigned int值。讀入40億個數,設置相應的bit位,讀入要查詢的數,查看相應bit位是否爲1,爲1表示存在,爲0表示不存在。
3.按位比較
  每一個數用32位的二進制來表示假設這40億個數開始放在一個文件中。
然後將這40億個數分成兩類:最高位爲0 和 最高位爲1 ,並將這兩類分別寫入到兩個文件中,其中一個文件中數的個數<=20億,而另一個>=20億(折半),與要查找的數的最高位比較並接着進入相應的文件再查找。再然後把這個文件爲又分成兩類: 次最高位爲0 和 次最高位爲1,並將這兩類分別寫入到兩個文件中,其中一個文件中數的個數<=10億,而另一個>=10億,與要查找的數的次最高位比較並接着進入相應的文件再查找。 … 以此類推,就可以找到了,而且時間複雜度爲O(logn),方案2完。

8、找最大的n個數

問題: 100w個數中找出最大的100個數。
1.用一個含100個元素的最小堆完成。複雜度爲O(100w* lg100)。
2.採用快速排序的思想,每次分割之後只考慮比軸大的一部分,知道比軸大的一部分在比100多的時候,採用傳統排序算法排序,取前100個。複雜度爲O(100w* 100)。
3.採用局部淘汰法。選取前100個元素,並排序,記爲序列L。然後一次掃描剩餘的元素x,與排好序的100個元素中最小的元素比,如果比這個最小的要大,那麼把這個最小的元素刪除,並把x利用插入排序的思想,插入到序列L中。依次循環,知道掃描了所有的元素。複雜度爲O(100w*100)。

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