這是一條時隔一年後的面試涼經。當時的目標廠家是位元組跳動,目標崗位大資料工程師。在此記錄我印象最深刻的乙個問題。由於在大三期間有過實習經歷,寫過爬蟲,並且將這一點寫在了我的求職簡歷中。所以面試官就我在爬蟲系統中是如何處理url的重複問題的。
url去重問題:爬蟲在抓取網頁時會抓取到數億條的url,而這在網際網路種屬九牛一毛。並且網頁中的url是相互鏈結的,如果抓取到相同的url,會行程閉環,主要也是為了節省資源。所以在抓取url的時候將抓取到的url放入乙個佇列中,對後抓取的url進行判斷,如果已經存在於佇列中那麼就不進行重複抓取。
我當時的解決辦法是使用hashset進行去重,因為hashset是乙個元素不允許重複的集合,這也是最容易想到的辦法,這也是我唯一用過的辦法,由於我的爬蟲系統只爬取特定的**,所以hashset足以解決我的業務場景。所以面對面試官的問題我只有一種答案,並且其他的答案也沒跳出set這個範圍。
其實url的去重方法有很多種,而我能想到的只有第一種。
1、將url放到set或hashset中去重(一億條占用10g記憶體)。
2、將url儲存到資料庫進行去重,建立欄位的unique屬性或者建立乙個唯一的索引,在插入資料之前檢查待插入的資料是否存在。
3、使用map或是乙個定長陣列記錄某乙個url是否被訪問過。
4、使用bitmap或bloomfilter方法去重(url經過hash後對映到bit的每乙個位上,一億url占用約12m,問題是存在衝突)。
1、2、3解決策略存在的問題
關於set和map都是基於記憶體的(一億條url約占用10g記憶體),隨著url的不斷抓取一定會發生記憶體溢位。對於資料庫unique屬性,將相同的url插入資料庫資料庫會報錯,如果多次報錯後資料庫會崩潰。如果每次抓取到url都去資料庫查詢這樣太影響效率。
使用bitmap方法去重:原理是把url經過hash後對映到bit的每乙個位上,一億url占用約12m,主要缺點是去重沒那麼精準,存在衝突。
bloomfilter(布隆過濾器)去重:bloom filter是由bloom在2023年提出的一種多雜湊函式對映的快速查詢演算法。通常應用在一些需要快速判斷某個元素是否屬於集合,但是並不嚴格要求100%正確的場合。
bloom filter演算法如下:
(1)建立乙個m位bitset,先將所有位初始化為0,然後選擇k個不同的雜湊函式。第i個雜湊函式對字串str雜湊的結果記為h(i,str),且h(i,str)的範圍是0到m-1 。
(2)將字串str「記錄」到bitset中:對於字串str,分別計算h(1,str),h(2,str)…… h(k,str)。然後將bitset的第h(1,str)、h(2,str)…… h(k,str)位設為1。
(3)然後檢查字串str是否被bitset記錄過的過程:對於字串str,分別計算h(1,str),h(2,str)…… h(k,str)。然後檢查bitset的第h(1,str)、h(2,str)…… h(k,str)位是否為1,若其中任何一位不為1則可以判定str一定沒有被記錄過。若全部位都是1,則「認為」字串str存在。若乙個字串對應的bit不全為1,則可以肯定該字串一定沒有被bloom filter記錄過。(這是顯然的,因為字串被記錄過,其對應的二進位制位肯定全部被設為1了)但是若乙個字串對應的bit全為1,實際上是不能100%的肯定該字串被bloom filter記錄過的。(因為有可能該字串的所有位都剛好是被其他字串所對應)這種將該字串劃分錯的情況,稱為false positive 。
一年後的目標
其次,是生活中的反省。之前能8點半到公司,每天寫一點今日的收穫,做一下筆記,為什麼現在就沒有動力起床了呢?今天看到馬雲說公司不為員工準備班車,是覺得熱愛工作的員工是不會因為這個而遲到,還是能堅持早起的,之前坐在大神erik旁邊,雖然沒有問過他什麼技術問題,但是有一點對我觸動很深,就是他每天8點多就去...
一年後重新來
一年半後,又回到了csdn,現在早以不作c 又從新開始了c 生涯.半年的使用,麻煩還是不少,尤其是記憶體管理.以前使c 麻煩在理解api,現在麻煩在語言本身的指標這塊.到現在了還一把指標,記憶體問題.剛請教了別人乙個弱弱的問題,特把結果記在這裡,以示警戒.這事我的問題 這是我自己編寫了乙個異常類 c...
寫給一年後的我
最近,看著 師兄們找工作也慢慢到了尾聲,大部分都找到了自己心儀的工作。不禁想到,一年後的現在,我是不是也找到了屬於自己的那份工作呢?作為一名電子類的大學的研究生,大學本科四年學到的僅僅是教科書上的東西,也沒有得到其他方面的培訓和學習。研究生一年級,上學期在學院的研究生科當了半年的助管,平時也是在上課...