百度面試題:從海量日志中提取訪問百度次數最多的IP


前言

這道題目網上到處都是,但是好多都沒有講清楚,然后大家又相互轉載,錯誤泛濫,現在我來完善這道題目。

題目:每一個ip訪問百度,其ip地址都會被記錄到后台日志文件中,假設一天的訪問日志有100G,求出一天中訪問百度次數最多的ip地址,可以使用的內存大小是1G。

分析

  1. 首先解決大文件問題,也就是如何處理100G的一個大文件,這個通常的解決方法就是將大文件分解成許多小文件。我們可以通過對IP地址求hash然后對1024取模將一個100G的大文件分解成1024個小文件(file0,file1......file1023),注意這里的1024個文件並不是平均分的,也就是每個文件大小並不是(100G/1204)。當然我們考慮的時候可以假設文件是平均分的,那么每個文件大小為100M,這樣一個100M的文件是可以全部讀入大小為1G內存中。這樣就解決了第一個文件太大不能一次讀入內存的問題。
  2. 考慮到ip地址是32為,那么總共有2^32=4G種可能出現的ip地址,每個ip地址出現的次數不確定,這個具體是由100G大文件決定的。對每個小文件進行處理,我們知道前面每個文件中的ip是通過hash(ip)%1024。這樣相當於將2^32=4G種ip地址進行了分段,每個文件中可能出現的ip最大范圍是4G/1024=4M。創建一個hashmap,讀取小文件中的每個ip地址,判斷hashmap中是否有這個ip,如果沒有,這往haspmap中插入一個<ip,1>的鍵值對,即hashmap.put(ip,1);如果haspmap中已經存在了這個ip,那么求出這個ip所對應的值count=haspmap.get(ip),然后往修改這個ip所對應的value,使其數量增加1,即hashmap.set(ip,count+1)。
  3. 當我們求出每個文件中出現次數最大的ip地址以后,我們在比較這1024個文件中的那個ip出現次數最大

偽代碼實例

Mark for future reference

hash(IP)%N get many small files

int max = 0;
String maxip = null;
for each file
    Hashmap hashmap;
    String IP = readIP(file);
    if(hashmap.has(IP)) {
        int cnt = hashmap.get(IP);
        hashmap.set(IP, cnt+1);
        if(cnt+1 > max) { 
                 max = cnt+1;
                 maxip = IP;
        }
    }
    else hashmap.put(IP, 1);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM