上週剛收到的字節的後端offer,來聊聊我的面試經過以及學習方式

簡單介紹下背景:本人已工作兩年,投遞的崗位base是北京。

先上正文

一面內容大概:

  1. 先來道算法題,不難:鏈表表示的兩個數相加。面試官說不用運行,大概寫一下就行,說是因爲說牛客上的運行環境不行。這題之前做過,寫完之後沒跑就直接給他了,他問是不是之前刷過,爲了裝逼我說沒有刷過,然後回答說:這題不就是CPU的加法器的實現嘛,計算機組成原理。

  2. Https的過程講一下。先是說了http+ssl,dns之後,準備講ssl的原理時,他示意我說回答一下傳輸層相關的。然後我就回答了tcp三次握手,對着服務器端指定端口,比如80端口發起連接,之後就是正常的數據請求了。

  3. 緩存穿透和緩存擊穿。其實是知道雪崩、穿透和擊穿的,但是一下子沒直接說分清穿透和擊穿,主要是太久沒用過,突然覺得擊穿和穿透,好像都差不多啊。

  4. Go 協程簡單用法;

  5. Go func與method之前的那個Receiver是什麼?(答:類似Java的實例本身,效果同java中的this關鍵字,同時在go method也可以把這個Receiver當做參數來正常使用);

  6. java 實例放在哪個區,常量放在哪個區;

  7. 說一下Netty的IO原理,答:Reactor反應模型,Linux那邊叫做IO多路複用。一個線程用來接收請求,將讀寫事件交給背後的worker線程。Redis、Nginx、Netty都是用到了這種模型。Redis其實也是多線程,只不過是用單線程來接收請求,在客戶端看起來是串行接收執行,所以效果上就是單線程。但是IO多路複用纔是Redis能高併發的底層保證。

  8. MySQL left join、inner join:inner的就是差集、left的就是保左邊;

  9. Go的閉包語法,答了內部函數對外層函數局部變量的引用,類似的還有js、java的lambda;

  10. Redis的setnx;(這個雖然只是提了一下,但是感覺沒答好,需要加強。顧着準備Redis集羣原理去了)

  11. 分佈式鎖的提供方,答:用過ZK和Redis的分佈式鎖;

  12. 項目相關問了不少,比如前家公司所負責項目的主要內容;

  13. 項目所產生的的一些價值,可以具體點,用一些案例或者數字來佐證都行;(這塊沒答好,接下來二面需要再整個關於項目經驗的描述、個人所負責項目、產生的價值等,越具體越好,能有一些具體案例或者數據來支撐更好);

  14. 接上,總之,也要花點時間來回顧自己在之前公司的貢獻和工作內容,越詳細越具體越好,拒絕假大空;

算法題:

給出兩個 非空 的鏈表用來表示兩個非負的整數。其中,它們各自的位數是按照 逆序 的方式存儲的,並且它們的每個節點只能存儲 一位 數字。

如果,我們將這兩個數相加起來,則會返回一個新的鏈表來表示它們的和。

您可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。

示例:

輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4)

輸出:7 -> 0 -> 8

原因:342 + 465 = 807

二面大概內容:

  1. 自我介紹,主要是說了工作經歷,負責的項目的主要內容,越詳細越好,把最能體驗價值的結果或者報告什麼的講一講;

  2. TCP四次揮手,結合CS兩端點的TCP棧和上層應用的交互來解釋四次揮手,以及爲何需要中間那個FIN-WAIT-2這個過程,最後由被動關閉一方的上層應用通過調用socket.closed()來結束數據傳輸,進入最終的FIN模式;

  3. 操作系統內存模型?這玩意兒不是就段頁轉換啥的嘛,面試官進一步提示說哪些區放數據,哪些區放線程數據之類的,我問了下您是問類似JVM內存模型那樣子的嗎?他說不是。我又說,那不是的話,我對操作系統內存模型的認知大概就是高地址空間存放內核數據,然後低地址空間對於進程來說就是個虛擬空間,擁有完整的尋址空間,這裏存放着進程的數據和代碼等,再細就不是很瞭解了,然後就跳過這題了;

  4. 算法題是股票買賣,一次和無限次兩種。寫出了無限次的情況,一次的一下子忘記怎麼轉過來,這題做的比較卡,整題至少有20分鐘,哎。今天下午複習的時候還再次複習看了這個股票全家桶系列的解法呢,感覺只有看是不行的,要有充足的時間,就算沒有從頭理解,也要再默寫一遍纔算複習過。所以下次如果沒有複習狀態的時候,不要看着文字思路發呆,可以邊默寫邊找回狀態,嗯;

算法題:

給定一個數組代表股票每天的價格,請問只能買賣一次的情況下,最大化利潤是多少?日期不重疊的情況下,可以買賣多次呢?

輸入: {100, 80, 120, 130, 70, 60, 100, 125}

1)只能買一次:65(60 買進,125 賣出)

2)可以買賣多次: 115(80買進,130賣出;60 買進,125賣出)

輸出買賣的序列和最大利潤

三面主要內容如下:

  1. 自我介紹;

  2. 介紹項目情況,重點說了近一年的工作項目的大概;

  3. 研究生在校的研究內容之類的,比較雜;

  4. 項目中的技術亮點:瞭解幾個,面試官貌似對這些也不是很感興趣,這估計也是後面他覺得我沒有成長的原因吧,可能認爲這些東西我在之前就應該都學會了的;

  5. 實現簡單令牌桶算法,沒有考慮隨時間滑動的情況;

  6. 加強版:令牌桶,加上隨時間滑動的要求,即:限制用戶在任一連續的一小時內,不能超過5W的請求。這邊提到了說將一小時分成多格,比如60格這樣的,面試官點頭貌似同意了,然後就實現代碼了,包括協程異步更新時間窗口;

  7. 沒有基礎知識問答;

  8. 沒有算法題;

三面反問環節,問:我咋樣?(措辭是: 這簡短的面試交談過程中,您覺得我咋樣?), 面試官說,我這一年來成長不大,幾乎沒變化,可是我覺得這一年來纔是稍微有點兒進步的呀。

不過,經過這麼一問,覺得反問環節也挺有意思,以後如果再有面試,反問環境可以多問些面試官關於我們自己的評價和看法,比如:上面說的您覺得經過這一小時的交流,我整體怎麼樣?如果像上面的面試官說最近一年進步不大,那麼應該繼續追問:那您覺得應該向什麼方向去深入學習和思考比較好呢?態度誠懇一點就行,作爲面試官人家還是樂意幫你指出不足之處的。

而上述的兩個問題:我咋樣和如何改,拋開offer不談,這兩個問題我覺得可以說是正常面試最大的收穫了。而面試之前準備的那些知識畢竟比較零散,還是需要靠平時的積累來鞏固。面試最重要的是讓他人來評價你,以前沒反問這兩個問題的時候,這些評價人家面試官基本不會主動告訴你,只會整理一下然後錄入到公司的人才管理系統,以供後續評價。但你現在反問一下,就可以得知這兩條信息,這些評價信息對你來說纔是最有用的,放在公司它只是大量候選人評價數據中的一份,可有可無。但對你來說卻是個寶貴的信息,你可以據此從別人的視角來審視自己,這種換個角度的審視比自己平日裏思考寫總結來得客觀。畢竟你表現出來的纔是客觀的,內在的其他沒表達出來的方面只能說你表達能力不行,也是種缺點,需要反思之一。

如果沒有進行這樣的反問,就不能更加全面的得知別人對你的看法,也就錯過發現自己弱點和改正的機會,以前面試反問環節都是傻傻的問一些沒多大意義的問題。今後應當多注意,要懂得跟面試官“要回”屬於你的那份評價信息。

以上就是面試過程中涉及的一些內容,屬於流水記賬式的列了一下,下面談談一些感想吧。

  1. 關於算法的考察。結合上述三面的內容,會發現對於社招來說,算法題的比重並沒有特別大,相反,工作經驗和項目這塊的佔比會更多,但也不是說不考覈算法,該刷的題還是得繼續刷,算法是基礎;

  2. 關於工作項目的梳理,有幾個感想。首先表達清楚項目介紹的內容,然後是價值所在,關於項目所產生的的價值和你所做的貢獻,這個很重要,是衡量你價值的一個點兒。最好能夠梳理一下過去的一些文檔和報告,整個具體的數據和細節點來談談,避免假大空;

  3. 日常工作中,最好有意識的去參加一些高質量的bug交流解決當中,這樣不僅能夠在日後面試當中跟面試官交流,也能在當初解決問題的時候提升自己的能力。這類高質量bug的解決就屬於技術亮點,很考驗一個人的基本功;

  4. 自我介紹的時候,就不用說自己叫什麼、哪裏人、什麼時候在哪個學校畢業之類的,直接說畢業之後在哪裏工作,負責的項目是啥,然後就可以把提前準備好的關於上述第二點的內容都講一遍;

上述的感想也是比較離散、雜碎。還想再分享一下個人的一些學習經驗,歡迎交流指正,正文如下。

技術面結束之後,今後對於基礎的知識的學習可能沒有這幾天這麼緊湊了,短時間填鴨式的學習大腦有點忙,不過這種感覺也還行,接觸到了新知識有點成就感。當你在瀏覽面經的時候,裏面提到的問題你覺得你都會了,是不是也有種自我肯定的情緒呢。

不過,面經裏面提到的知識都是比較分散的,畢竟在那麼短的面試時間內,面試官也只能隨機抽樣的檢查,沒時間做太全面的交流。這也導致我們看面經的時候都是比較分散的知識點,所以需要在今後,持續的學習,每段時間都專心研究某個知識系列,系統性的學習比較有效果,也比較全面。比如MySQL、Redis、ZooKeeper、MQ、JVM、OS、網絡、算法等。

就算法來說,它是需要長時間的積累,短時間內的突擊效果不是特別大,也累。所以今後對於算法的學習可以這麼來:每日一題、或者之前做過的題目每天拿一兩題出來再做一遍,重新思考,深入的多看看題解體會體會,不再是趕時間的去衝量。學會總結,理解每個算法與數據結構的含義,時間久了就能做到不變應萬變。

另外,算法大部分還是屬於背誦題,不少題目把模板寫出來就完成的差不多了,只需要把細節處理一下就差不多了。時間久了,這些模板題就變成條件反射,此時對高級的數據結構也會有進一步的瞭解,思考速度和解題能力都有所進步。

OS和網絡也差不多,這三者屬於平日工作都很少直接能夠體現出來的知識,平日工作用得少,又沒去複習時間一久就會忘記, 用進廢退, 人之常情嘛。所以纔像上面說的,應該要堅持每日一題、或者時不時挑一些做過的題目重新做做,主要是爲了保持手感,而做過的題目拿出來再做一遍也不會花太多時間,這樣在日常工作之餘也比較容易堅持下來。通過這段時間的面試準備,算是把算法入門,找到刷題的狀態了,此後應該如上所說,堅持每日複習做做老題,偶爾週末時間充裕跟着“每日一題”做做新題,保持下去。

說回OS和網絡,這類知識對於邏輯思維的要求沒有算法題那麼高,算法題屬於“CPU相當密集型”,不練就不會。而OS和網絡這類可能更多的是理解之後帶點記憶的知識,做點輸出存到筆記或者博客,定期來回顧回顧就行,屬於“輕微IO密集型”,看完之後一段時間,也多少還有些印象,能夠知個大概。每兩年重看相關書籍,複習一下就可以鞏固。

整個計算機體系,包括底層硬件組成原理、再上的操作系統和網絡,這些之間其實都是有邏輯關係在的。可以OSI七層或者TCP/IP四層模型來看,它們就是個整體,全部理清之後,在大腦內可以存在相當長的時間。日常工作和生活中,只要遇到計算機相關的問題,大多都可以從這個整體來思考,這種思考也算是種回顧複習。

相比而言,算法算是比較離散的,排序、BFS/DFS、DP等之前的聯繫不是特別的緊密,至少沒有像上述OSI七層模型這種遞進關係相互依賴的情況,學習的時候也就可以單獨知識點一個個擊破了。

關於今後保持基礎知識學習的想法,首先算法就如上述所言,每日一題、或者做過的題目重做,這樣是爲了不給本來就忙碌的工作日增加太大的壓力,用簡單的算法題來放鬆放鬆就行,搞幾個AC找找成就感。

而對於基礎知識,前期打算繼續多翻閱翻閱面經,以面經中的題目爲切入點,來複習(好像技術博客首頁的文章也是個不錯的切入點)。複習過程中再由點及面的去谷歌各種不明白,每個疑問點在輸入谷歌之後,一次性多打開幾個頁面,多看多對比然後結合整理自己的理解,輸出到日記或者博客中。比如,最近看到個比較經典的題目是MySQL的隔離級別,這個問題谷歌一搜,大部分都有提到MVCC、當前讀、快照讀、行鎖、間隙鎖,都什麼知識啊,反正對於工作經驗尚淺的我來說,已經觸及到知識盲點了。也好,這些點都記下來,一個也別想跑,然後再分別谷歌這些知識點,可能又會引出一些更加底層的、你沒見過的知識點,也沒關係,繼續記錄繼續搜。

今後可能又會看到MySQL索引相關的面試題,搜這個的時候,也許會碰到MyISAM、InnoDB、B/B+樹、磁盤IO塊與系統頁、主索引與輔助索引、m叉樹的分裂與合併……之類的,這樣對MySQL的認知又多了一些。過些時日,你可能想着完整的去學一遍,這時候買本《高性能MySQL》來看,而且你之前學到的隔離級別、索引它裏面都提到了,並且更加全面和仔細,從基本概念的出現到最終的常用場景,都給你列出來了。

上述之所以要先從面經題目切入學習是因爲個人在看書的時候,總有種大而全的感覺,書畢竟比較理論,面面俱到,有用的沒用的都會列出來。而面經上的題目是面試官結合當下工作內容提出的,有可能就是他最近工作中遇到的問題,直接拋給你看你怎麼思考。那麼這種面經題目就比較有意思,貼合實際工作,能夠更好理解,經過面試官這麼一折騰印象也更加深刻。這種零散的知識點學的差不多了,再來看書,就比較有感覺,知道書中哪些地方是重要知識,哪些地方其實沒那麼實用作爲了解即可。

其實,日常工作中不管是用到的知識,還是遇到Bug,所涉及的知識點也是比較隨機離散的,類似上面瀏覽面經過程中遇到的問題,看緣分。而在項目排期不那麼緊的時間段裏,找本書系統化的把之前的碎片化知識點串起來,就很有必要了,既是總結也是鞏固。

關於學習的另一個觀點:任何事物都是從小發展到大,學習的時候應該從它過去小的規模,跟着時間推移發展壯大,逐步去了解。比如學習Linux內核可以從早期低版本、JVM、Spring也類似,早期規模小,結構相對簡單,比較容易理解。再逐步的按照發展需要,增加各種功能模塊,直到當前最終版本。這樣的學習路徑可以清楚的知識系統中各個模塊的由來與作用,也能夠知道哪些是基礎重要模塊,而哪些是爲了解決歷史特定問題的模塊,理清主線。

再舉個例子,前些時候看到一篇關於限流的文章。文章一開始先從簡單計數談起,對於早期應用來說,簡單的計數算法確實夠用,後來隨着業務的發展細化,簡單計數粒度不夠細,所以需要有類似滑動窗口這種效果的限流,也就衍生出了令牌桶和漏桶兩種限流算法。

最後放上一個不錯的記憶法——艾賓浩斯記憶規律,嗯就是小時候書上介紹的那個。新知識學習之後,分多次,每次不同間隔的去複習,大概十來次就能較好的將短期記憶轉化爲長久記憶了。而且學過之後,第二遍開始重新複習就簡單多了,因爲都理解過並整明白了,再重新複習更容易,更快,更省時。

之前考研的時候,背單詞就隱約有用到這種方式。整本單詞書,第一遍先花個三個月背一遍。之後,第二遍開始就越來越短,越來越快(這都什麼虎狼之詞)。前些時候背誦《道德經》也是類似,用了個APP,把每天背誦好的篇章截個圖放到這個APP中,然後它會根據艾賓浩斯曲線的規律節點,定期提醒你複習。你要做的就是當它提醒的時候,打開快速默唸一遍,默寫一遍就可以勾掉了。還是那句話,第二遍越到後面,所花時間 就越來越短,越來越快。

以上,關於是學習方式和記憶方法的一些經驗分享。最後再說句,任何工作和學習都是需要背誦記憶的,以此爲基礎來進行創作、推理和總結。比如何潔,他也是背過了大量的棋譜之後,再結合自身的想象力和邏輯能力,纔有精湛的棋藝;比如鋼琴家,也是需要背大量的琴譜、***,之後基於此再結合生活經驗和靈感,來進行創作。巧婦難爲無米之炊,腦中記憶的內容就是我們的大米,只有擁有大米,纔有做出香噴噴的米飯的前提。並且大腦擅長的就是記憶,他就像是緩存,之前推理過的經歷過的直接緩存在大腦中,之後如果再次遇見,直接查出來返回即可。

之所以還要再囉嗦的說下關於人盡皆知的記憶方法,是想強調任何學習和工作,它首要做的就是先去記憶,背一些概念。所以學習新知識的時候,遇到太多的概念不用慌,先背下來,背不住的就記在小本本上,常回顧。背到一定量之後就能產生質變,之後各種脈絡也就慢慢打開了。


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