海量數據處理方式問題

1、現在有1億個隨機數,有重複的,隨機數的範圍在1到1億之間,將1到1億之間沒有在隨機數中的數求出來。

    /**
     * 用位圖進行存儲,產生隨機數存入bitSet中相應的位置,並置1。
     * 如果bitSet中相應位置爲1則此數出現過,如果爲0則未出現過。
     * */

    public static void main(String[] args) {
        BitSet bitSet = new BitSet();
        Random random = new Random();
        for (int i = 1; i <= 100000000; i++) {
            bitSet.set(random.nextInt(100000000));
        }
        for (int i = 1; i <= 100000000; i++) {
            //如果沒有出現,就輸出該數字
            if (!bitSet.get(i))
                System.out.println(i);
        }
    }

2、有a和b兩個文件,每個文件中均存放了50億條url,已知每條url所佔內存大約64字節,你在可使用內存在4G的情況下,如何找出a、b文件共同的url。

假如每個url大小爲10bytes,那麼可以估計每個文件的大小爲50G×64=320G,遠遠大於內存限制的4G,所以不可能將其完全加載到內存中處理,可以採用分治的思想來解決。

首先遍歷文件a,對每個url求取url.hashCode()%1000,然後根據所取得的值將url分別存儲到1000個小文件(記爲a0,a1,...,a999,每個小文件約300M);接着遍歷文件b,採取和a相同的方式將url分別存儲到1000個小文件(記爲b0,b1,...,b999);這樣處理後,所有可能相同的url都被保存在對應的小文件(如a0和b0,a1和b1)中,不對應的小文件不可能有相同的url。然後我們只要求出這個1000對小文件中相同的url即可。最後,求每對小文件ai和bi中相同的url時,可以把ai的url存儲到HashSet中。然後遍歷bi的每個url,看其是否在剛纔構建的HashSet中,如果是,那麼就是共同的url,存到文件裏面就可以了。

3、現有海量日誌數據保存在一個超級大的文件中,該文件無法直接讀入內存,要求從中提取某天出訪問網站次數最多的那個IP。

首先,從這一天的日誌數據中把訪問百度的IP取出來,逐個寫入到一個大文件中;對每個ip求取ip.hashCode()%1000存入1000個小文件中。接着,找出每個小文中出現頻率最大的IP(可以採用HashMap進行頻率統計,然後再找出頻率最大的幾個)及相應的頻率;最後,在這1000個最大的IP中,找出那個頻率最大的IP,即爲所求。

4、現在有100萬個數字,找出其中最大的100個數。

選前100個數建立一個最小堆,遍歷一遍,如果當前數比堆頂大就和堆頂元素交換,接着調整堆,就可以得到最大的100個數。

說明:找最大的N個數用最小堆,找最小的N個數用最大堆,Java中可以使用PriorityQueue。

5、現有上億條數據(有重複的),統計其中出現次數最多的K條數據。

若內存可以放下則先遍歷數據,用HashMap統計此數,接着簡歷K個數的小頂堆進行遍歷替換,如果當前元素大於堆頂元素則替換掉堆頂元素後調整堆,最後就可以找出最多的K條數據;若內存裝不下,則同上幾個問題一樣採用分治的原則,將數據分開處理,最後再合併。

 

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