1. 程式人生 > >額定記憶體進行資源分配

額定記憶體進行資源分配

40億個非負整數中找到沒出現的數,限額1GB

題目剖析

1、資料理解:

整數,1個整數佔4個B,即32bit,40億個整數,佔40億*4B,即16GB

40億,如果用二級制推算,最接近2^32=4,294,967,296(42.9億),即32bit,佔4個B

2、最壞情況:40億個數都不相同,需要輸出4B*40億=160億B=16G

解題重點:

1、找出未出現過的數時,不可以直接將數字儲存並輸出,需要尋找一個容器

解題思路:

1、尋找策略:借鑑桶排序,用跟資料大小相同長度的陣列標記重複情況

2、容器選擇:BitSet,容器體積小,每個元素只能為1或0,可以滿足需求

3、具體做法:

  • 申請一個長度為2^32 的BitSet,這個長度稍微大於非負整數的取值範圍,8個bit即1B,即佔了2^32/8/1024/1024=512M,每個位置只標識1或0

  • BitSet預設成一個元素都為0的陣列,出現過的數在BitSet對應位置標記為1,最後標號為0的,就是沒出現過的數。最後遍歷陣列,得出結果。

  • 最終只需要512M記憶體即可。

    .

40億個非負整數中找到一個沒出現過的數,記憶體限制為10MB

題目解剖:

1、資料理解:

10M,即10240B,即81920bit,如果要用這些來處理40億資料,即要進行分塊處理,每塊的資料量為40億/81920=48.83,比較靠近2^6=64,所以需要拆成64塊,然後分開處理,即每組資料最大量為67,108,864(資料全齊狀態)

2、最壞情況:全部資料都出現過

3、解題策略:如果按上述桶排序思路,需使用500M記憶體,超出要求

解題重點:

1、利用布隆過濾器的思想,先把絕對會出現的資料過濾掉,即採用兩個容器進行統計

解題思路:

1、尋找策略:借鑑布隆過濾器,先排除不是目標的物件,再找未出現的數

2、具體做法:

—第一個容器:

  • 定製一個長度為64的整形陣列int[64] ,該陣列佔記憶體空間64*4B=256B
  • 遍歷那40億個數,設num/67108864=i,i為資料塊編號,然後intArray[i]++
  • 遍歷int陣列,找出一個計數少於67108864的位置K

–第二個容器

  • 申請一個長度為67108864bit的bit陣列,佔用記憶體8192KB,即約8MB
  • 遍歷40億個數,找出位於區間k的所有數
  • 找出的數n,將bit陣列中的n-67108864*k的值置為1
  • 遍歷bit陣列,找出值為0的位置,假設位置是i,那麼67108864*k+i就是沒有出現過的數

合併用記憶體256B+8192KB=8MB,符合條件

.
.

給定一個檔案F,其中存放了N個url,每個url佔64位元組,記憶體限制是4G,請找出其中出現次數最多的3個url

題目剖析:

資料理解:4G即4,294,967,296位元組,可以處理67,108,864個url,即0.67億個。可分兩種情況討論,一個是小於0.67億個URL的時候和大於0.67億個URL的時候

解題重點: 分類處理

解題思路:

1、N小於0.67億

計算url的hash,通過hash得到每個url的次數,遍歷hash找出最大的三個

2、N大於等於0.67
用hash把N個數據分成Y=N/0.67億(分組數量Y貼近2^X),在每組找出最多的3個,再在Y個組裡找出最多的三個進行比對。

.

給定a、b兩個檔案,各放50億各url,每個url各佔64位元組,記憶體限制是4G,找出a、b檔案共同的url

資料理解

一個url64位元組,每個檔案50億個,即一個檔案298GB,兩個檔案一共569G,遠大於4G

假設所有Url相同,則同時儲存相同url時,需要使用記憶體298GB,也遠大於4G

可以考慮分資料塊考慮問題,例如雜湊分組,每個組內可能有相同的資料,但是不同組肯定沒有相同的資料

假設1個檔案分組N組,則每組佔用空間298/N,要用到2組,則每次載入需要空間2*298/N,另考慮計算用的記憶體,假設分成1024組,則每次載入資料使用記憶體598MB。

解題思路

1、將a,b檔案分別按N進行雜湊分組,先將第一組分別載入進陣列。(598)

2、將a陣列對映到hashmap裡面(298),再遍歷b資料,比對是否會存在一樣的url,有就儲存下來,輸出

3、釋放記憶體,再迴圈後續的分組
.
.

有一個1G大小的一個檔案,裡面每一行是一個詞,詞的大小不超過16位元組,記憶體大小限制是1M,要求返回頻數最高的100個詞?

資料理解:

1個詞16B,100個詞即1.56KB

1G檔案,存的都是16B的詞,即16,777,216個詞

1M記憶體,最大能存16,384個詞,那麼處理1G的詞,剛好需要1024個分割槽,秉承預留執行記憶體、防止資料嚴重傾斜的思想,劃分2^11即2048個分割槽,每個分割槽使用記憶體情況不確定,因為有可能出現傾斜,出現數據傾斜就要進行二次分組,確保每個分割槽的大小不超過一定的值

解題思路:(理想情況,不需要二次分組)

1、將檔案採用雜湊分組分成2048個分割槽,將第一個分割槽的資料載入進hashmap,取出value最大的100個詞,持久化到檔案中,這樣就可以得到2048個檔案,每個檔案有1600B的資料,即一共3.125MB

2、將所有檔案載入到記憶體中,將entry放入容量為100的大頂堆裡,按value排序,得到100個最大的值