宣告: 本文中有兩個簡單的大資料問題,只給出了解決方案的大概描述。
1. 給定100億個整數,設計演算法找到只出現⼀次的整數?
問題分析:
整數的範圍總共有42億左右。如果按照最原始的方法,給每乙個整數分配乙個計數器的話,計數器設為整形,建立以
42億整數作為索引和對應的計數器當成元素的陣列,然後乙個個的遍歷
100億個整數,遍歷完成後在統計只出現一次的整數。顯然這個方法對空間的浪費非常大。
42億個整形,相當於
160億的位元組,總共佔
16g記憶體,個人電腦上根本滿足不了,就算是乙個位元組也要占用
4g記憶體,這也有點不現實。所以就要利用點陣圖的知識。
解決方案:
我們可以利用點陣圖來表示。不過題目是要找到只出現一次的整數,整數的出現次數可以有0 , 1 , >1這三種,所以不能只用一位來表示乙個數字出現次數的狀態。 根據題意,乙個數出現次數的狀態最少要有三種,因此需要用兩位來表示乙個數字出現次數的狀態。
0 表示這
100億整數中沒有出現這個數
; 1
就是我們要找的
; >1
表示出現次數不只一次, 其實當數字出現次數等於
2(即二進位制
10)時我們就不用再管了, 因為題目只要求我們找到只出現一次的整數。這樣的話
42億個數,每個數的狀態用兩位表示,大概占用
10億個位元組,也就是
1g。占用記憶體明顯小了很多。如果感覺
1g記憶體仍然很大,可以這樣, 首先統計前
21億個數中只出現一次的數字,遍歷完之後再次遍歷統計21億
~42億之間只出現一次的數字。只不過第二次統計時對應的位置要減去
21億,使用的是相對位置。如果這樣就佔記憶體21億
*2位
= 42
億位 = 5
億 位元組
= 500m
, 記憶體又小了。當然可以使用此方法再次細分,記憶體會占用更少,只不過要利用相對位置, 同時缺點就是也更浪費時間,因為要多遍歷幾次。
2. 給⼀個超過100g大小的
log file, log
中存著ip
位址,
設計演算法找到出現次數最多的
ip位址?
問題分析:
ip位址總共有
32位,共有差不多
42億個。若統計按照每個
ip位址都給乙個計數器,每個計數器是乙個整型,那就需要42億
*4 = 168
億個位元組,即大概占用
17g的記憶體,顯然不行。那我們就想辦法讓計算量變小。採用切分的方法。
解決方案:
把總共100g的檔案切分成
100份。首先要有
100個容器,編號
0~99
, 然後把每乙個
ip放到它對應的值模
100後對應的容器內。分配完成後,如果兩個
ip相同,那就肯定在同乙個容器裡,且每乙個容器最多只能有
4200
萬個不同的
ip,當然每個容器大小是不定的。
此時在統計每乙個容器中出現次數最多的ip,然後
100個容器得到的結果再選出最大的就行了。統計乙個容器時給每乙個不同的
ip分配乙個計數器,那總共就占用
4200
萬*4=1.6
億位元組=0.16g
,這是可以的,但需要多遍歷一次。
大資料集群失聯問題解決方案
我們之前維護的集群經常性地出現失聯的情況,大資料集群上,還有es集群在跑,在凌晨左右集群會有隨機的機器間歇性失聯,cpu飆高,ssh登入不了。在嘗試了諸多方法後,通過每天定時清理快取的方式解決了集群失聯的問題。生產環境的大資料集群每天會有大量快取,若不清理,就會導致記憶體使用率一直居高不下,長此以往...
Jar Hell 問題解決方案
最近看到溫紹錦的jvm基礎,裡面看到這個jar hell問題的解決方法,之前遇到過一次,是乙個資源檔案,當時覺得挺麻煩,不知道還有這個方法,很棒,特地整理了下,記錄到這裡來,這個部落格開了好長時間了,一直以來也懶得寫東西,以後會堅持更新些。classloader classloader thread...
top K問題解決方案
1.使用最大最小堆。求最大的數用最小堆,求最小的數用最大堆。2.quick select演算法。使用類似快排的思路,根據pivot劃分陣列。3.使用排序方法,排序後再尋找top k元素。4.使用選擇排序的思想,對前k個元素部分排序。5.將1000 個數分成m組,每組尋找top k個數,得到m k個數...