1. 程式人生 > >斬獲BAT-offer大神的兩萬字面試乾貨分享

斬獲BAT-offer大神的兩萬字面試乾貨分享

0.寫在最前

首先呢我的面試經歷和一些麵霸和收割機的大神相比絕不算豐富,但我這三個月應該能代表很大一部分人的心路歷程:從無憂無慮也無知的狀態,然後遭遇挫敗,跌入低谷,連續數天的黑暗,慢慢調整,逼著自己不能鬆懈,看到改變,收穫肯定,分享經歷。

先大概說下自己的面試經歷吧(詳細的面試過程和麵試題解析在最後):
相關的公司有四類:

  1. 筆試就掛了的:網易、頭條。(對於筆試這個東西我到現在都沒太多經驗)

網易是第一家參加筆試的,面試會報銷費用去總部,所以還是有難度,這個公司呢,內推不內推都要參加筆試。所以筆試要好好準備(當然筆試也不好準備)
頭條只有四道程式設計題,一個人做確實難度挺大的,尤其是工程為主,不太專搞演算法的同學。

  1. 筆試過了但因為時間地點原因沒去面試的:京東、小米、去哪、攜程、招銀。

這幾個公司面試一定要現場,很多都要求去總部,還不報銷路費。所以在遇到這種情況時,大家要有選擇的安排,畢竟時間和精力都是有限的。

  1. 最終參加面試的:
  • 阿里(電話2面,很輕鬆地就掛了)
  • 騰訊(現場2面,很久之後hr電話說要轉C++,就只能算了)
  • 百度(電話2面+經理面,offer)
  • 滴滴(視訊2面+現場終面,offer)
  • 360 (視訊2面+hr面,offer)
  • 美團(電話2面+hr面,offer)。
  • 阿里呢大家都知道,恨不得把全國學生都面一個遍,對於這種策略我只想說三個字,晚點投(下面會解釋)。
  • 騰訊的面試體驗還是很好的,會在酒店的房間裡,安靜舒適。只是java的同學可能要被問到很多C++和網路的知識,建議還是提前準備一下。
  • 百度內推都是電話面,會在某網站實時寫程式碼,感覺百度的面試官都很不錯,給我的體驗也很好。內推的時候最好注意下部門,在一個好的部門和邊緣部門還是差別很大的。
  • 滴滴面試比較晚,外地可以先視訊面,最後會有現場面,報銷花費。工作體驗很不錯,內部氛圍很好,因為成立時間短業務擴充套件太快,技術方面正在沉澱期,工作還是比較有挑戰性的。
  • 360要先筆試,然後可以視訊面試。這個公司比較穩定,業務也都很成型,實習的話留用率還是比較高的。
  • 美團的話印象比較深,因為我是二月底內推的美團,然後內推沒面我,三月正常筆試通過,然後待面試兩個多月。。估計是補招了才給我打的電話(我都已經準備入職了)。經驗就是一定要選一個事業群,最開始選都喜歡的大多是以為這樣機會多,相反這樣很多部門由於自己的簡歷池太滿而顧不上撈你。
  1. 還有一投簡歷就沉的外企:Amazon、FreeWheel(不知道是他們只收北京生源,還是我英文簡歷寫的太爛了)

文章最後的面經當然只包括第三種因為筆試這東西真的不好講,雜七雜八什麼題都有,程式設計題大多人也要看發揮。

然後這是我最直觀的感受( 我就從左到右說起吧。):

offer = 心態 * (實力 + 面試技巧) + 緣分運氣

1. 心態

其實每個階段的改變,也都是心態轉變的過程,所以首先要說的一點,就是心態。在上面這種公式裡,心態作為一個因子存在。沒錯,心態可以影響你面試的準備,筆試的狀態,實力的發揮,可以影響一個面試過程的方方面面。心態崩了,就只剩運氣了,offer估計也就走遠了。

那怎麼調整自己的心態呢?

首先是要正視自己的能力。不輕視,不高估。

  • 不輕視指的是我們都要對自己有信心,畢竟選了這個行業和方向,說句不好聽的話,機會那麼多,就算你不怎麼努力也會有個差不多的offer不是麼?千千萬萬的初中創公司,各種擁有垂直領域穩定份額的二三線公司甚至有些已經上市,除此之外還有銀行,投資,金融的IT崗,還有各行各業為了網際網路+的策略而擴充套件的網際網路分支(當然像鏈家這種已經算網際網路+傳統行業的典範了,我前些天還瞅到了像萬達德勤一類的各行業巨頭也在招程式開發…)所以啊,要對自己有信心,在這個行業十分缺人的年代裡(當然各個層次的公司缺人的標準是不一樣的),總不至於會失業吧。

  • 不高估就是要清楚自己的能力範圍,不是說期望過高不好,但過高的期望會讓你的心理變得脆弱,稍有不順心態就有崩掉的趨勢。因為面試畢竟有太大的偶然性,就算你達到了一定的水平,相應水平的崗位也不是百發百中的,更不要說身邊有那麼多大神和收割機,天天拿offer拒offer,對心理都是不小的衝擊。

不要總給自己消極的暗示,心態差了積極調整。

  • 大多數的人,總暗示自己說什麼時間不多了,怎麼每天過這麼快效率怎麼這麼低。到筆試了,跟自己說這個演算法太難了,肯定做不出來;臨到面試了,跟自己說千萬別問我linux核心,別問我分散式,問我肯定完;面試過之後,沒有結果,就天天想肯定又掛了,唉我怎麼這麼菜。

  • 如果這一系列的表現形成習慣,那心態這個係數最多0.5,能發揮出來的東西也都打了一半的折扣。凡事都不要太悲觀,一個offer沒拿到,正常情況是這個失敗的經歷產生的經驗和總結是會讓下一次的成功率提高的,千萬別因為這些消極的暗示,反而讓該有的提高都沒有了。

  • 心態差的時候反而要停下你重複而沒有效率的工作,去調整一下,可以出去玩一玩,吃吃喝喝,不要把這幾個月看得有多麼不一樣,好像耽擱兩小時就要來生再見一樣。

對於身邊的同學,多交流,不比較。

  • 有一些一起準備的好夥伴是件非常好的事情,不僅可以互相督促,而且可以在交流和分享的過程中取長補短。(哪怕是偶爾一起吐吐槽發洩一下也比一個人崩潰要好得多)。但對於每一次面試,只跟自己比就行了,面試的整個過程都是最怕比較的,偶然性大,而且每個人適合的方向和技術棧都不一樣,結果不能說明一切問題。如果身邊有些收割機,那更不要太在意這些天天拿offer的(尤其是拿一個就跑過來講一句的,他們也許沒有惡意,但他們可能真的想不到這種方式會對別人產生怎樣的衝擊)。

對自己的水平有個很清楚的認識,並選擇自己合適的公司,好好準備自己的筆試、面試,不怕失敗,但保證每次面試都有收穫和提高,那滿意的offer早晚會來。

2. 實力

這裡說的實力指的是硬實力,也就是技術上的真實積累(當然產品崗的就是對於產品相關知識的積累),而其實呢軟實力在面試過程中也尤為重要(有時候真的要更重要),主要是指和麵試官的溝通,對一個問題的闡述方式和表達方式,邏輯思維能力以及的價值觀和為人等。

然後關於這個軟實力我想放到下面的技巧中去說。

如果你平時有些專案積累,不擅長也從來沒有怎麼系統地總結過;如果你學習呢不算那麼認真刻苦,研究搞得也不算出眾,但是你該努力的時候也會努力,可以為了一個好的工作逼自己一把。

那也許下面說的實力和技巧都可以在一定程度上幫到你。(因為我就是這樣的情況)

2.1 實力怎麼能體現出來

這麼說是因為很多人其實在這些年的專案或是學習中有一些積累,但是在剛開始面試的時候完全感覺使不出力,就是有種你問的我都能講上一點,但根本說不清楚的感覺。(往深了問自然是完蛋)

知識面或者或者說技術棧都是有寬度和深度的,我們要做的就是在短時間內提升寬度,抓住以往本身就熟悉或是感興趣的幾個點去深入。

我是認為知識的寬度可以很大程度上決定你能不能通過面試(這裡說的寬度並不是簡歷上了解、知道或者你都沒往簡歷上寫,僅僅是聽說過的層面修飾的方面,而是寫熟悉的那種,通俗地說是可以講清原理,不涉及橫向對比和優化的方面)

一兩個點的深度呢在保證你能通過面試的同時(尤其是你的點正好cover了對方部門的技術棧),並且還是影響offer等級的關鍵因素。(達到足夠的深度,不只能說出原理,還能進行橫向技術對比,縱向的延伸技術,優劣點及優化,或者在這個點寫了幾篇很透徹的博文,更厲害的同學甚至有相關的開源專案的參與與貢獻)

關於怎麼提升寬度和深度可以看下面的積累(其實說真的短期內寬度是好補的,深度確實要看個人,是代價較高,價效比不一定高的一方面,看自己的決定吧)

所以我的建議是,先把寬度提上來,把你能cover的知識點及原理搞懂是第一步。建議對自己之前的專案和技術積累做一個總結和分類(可以參考下面的技術路線),然後對已經瞭解的方面儘可能延伸,對盲區或是薄弱的地方進行鍼對性的學習和練習。

當你的知識面覆蓋到一定程度的時候,你自然會把他們的聯絡搞明白,慢慢理解這整個技術體系,在面試的過程中結合表達技巧可以關聯起來說各個方面,也就可以很大程度上展現自己的真實實力(更厲害的同學甚至可以有超出自己真實實力的表現。。)

2.2 實力包含哪些方面
(我也只是腦子裡過了一遍,肯定有遺漏的,大家自己補全就行了,畢竟每個人的知識覆蓋範圍也不同)

基礎知識

1.1演算法和資料結構

  • a.陣列、連結串列、二叉樹、佇列、棧的各種操作(效能,場景)
  • b.二分查詢和各種變種的二分查詢
  • c.各類排序演算法以及複雜度分析(快排、歸併、堆)
  • d.各類演算法題(手寫)
  • e.理解並可以分析時間和空間複雜度。
  • f.動態規劃(筆試回回有。。)、貪心。
  • g.紅黑樹、AVL樹、Hash樹、Tire樹、B樹、B+樹。
  • h.圖演算法(比較少,也就兩個最短路徑演算法理解吧)

1.2計算機網路

  • OSI7層模型(TCP4層)
    • 每層的協議
    • url到頁面的過程
  • HTTP
    • http/https 1.0、1.1、2.0
    • get/post 以及冪等性
    • http 協議頭相關
    • 網路攻擊(CSRF、XSS)
  • TCP/IP
    • 三次握手、四次揮手
    • 擁塞控制(過程、閾值)
    • 流量控制與滑動視窗
    • TCP與UDP比較
    • 子網劃分(一般只有筆試有)
    • DDos攻擊
  • (B)IO/NIO/AIO
    • 三者原理,各個語言是怎麼實現的
    • Netty
    • Linux核心select poll epoll

1.3資料庫(最多的還是mysql,Nosql有redis)

  • 索引(包括分類及優化方式,失效條件,底層結構)
  • sql語法(join,union,子查詢,having,group by)
  • 引擎對比(InnoDB,MyISAM)
  • 資料庫的鎖(行鎖,表鎖,頁級鎖,意向鎖,讀鎖,寫鎖,悲觀鎖,樂觀鎖,以及加鎖的select sql方式)
  • 隔離級別,依次解決的問題(髒讀、不可重複讀、幻讀)
  • 事務的ACID
  • B樹、B+樹
  • 優化(explain,慢查詢,show profile)
  • 資料庫的正規化。
  • 分庫分表,主從複製,讀寫分離。
  • Nosql相關(redis和memcached區別之類的,如果你熟悉redis,redis還有一堆要問的)

1.4 作業系統:

  • 程序通訊IPC(幾種方式),與執行緒區別
  • OS的幾種策略(頁面置換,程序排程等,每個裡面有幾種演算法)
  • 互斥與死鎖相關的
  • linux常用命令(問的時候都會給具體某一個場景)
  • Linux核心相關(select、poll、epoll)

1.5 程式語言(這裡只說Java):

  • 把我之後的面經過一遍,Java感覺覆蓋的就差不多了,不過下面還是分個類。
  • Java基礎(面向物件、四個特性、過載重寫、static和final等等很多東西)
  • 集合(HashMap、ConcurrentHashMap、各種List,最好結合原始碼看)
  • 併發和多執行緒(執行緒池、SYNC和Lock鎖機制、執行緒通訊、volatile、ThreadLocal、CyclicBarrier、Atom包、CountDownLatch、AQS、CAS原理等等)
  • JVM(記憶體模型、GC垃圾回收,包括分代,GC演算法,收集器、類載入和雙親委派、JVM調優,記憶體洩漏和記憶體溢位)
  • IO/NIO相關
  • 反射和代理、異常、Java8相關、序列化
  • 設計模式(常用的,jdk中有的)
  • Web相關(servlet、cookie/session、Spring、Mybatis、Tomcat、Hibernate等)
  • 看jdk原始碼

2. 專案經歷

  • 這個每個人的專案不同,覆蓋的技術也不一樣,所以不能統一去說。
  • 這裡的技巧呢,在下面也會詳細說明。
  • 無非是找到自己專案中的亮點,簡歷上敘述的簡練並且吸引眼球,同時自己要很熟悉這個點(畢竟可以提前準備)
  • 最好自己多練,就像有個劇本或者稿子一樣,保證面試中可以很熟練通俗地講出,並且讓人聽著很舒服。

3.實習經歷

  • 這個很抱歉,因為我是找實習的經歷,所以也沒有實習經歷的講述經驗。
  • 但我想如果你有實習經歷,那面試過程的重點也會在實習做了什麼上面,所以大家最好對實習所做的工作做一個總結,並且同樣抓出亮點,搞懂內部原理,提前鍛鍊講述的過程。

4.其他擴充套件技能(這個方方面面太多了,全部掌握基本上不可能,只是作為大家其他時間擴充技能的參考)

  • 4.1 分散式架構:(瞭解原理就行,如果真的有實踐經驗更好)
    • CAP原理和BASE理論。
    • Nosql與KV儲存(redis,hbase,mongodb,memcached等)
    • 服務化理論(包括服務發現、治理等,zookeeper、etcd、springcloud微服務、)
    • 負載均衡(原理、cdn、一致性hash)
    • RPC框架(包括整體的一些框架理論,通訊的netty,序列化協議thrift,protobuff等)
    • 訊息佇列(原理、kafka,activeMQ,rocketMQ)
    • 分散式儲存系統(GFS、HDFS、fastDFS)、儲存模型(skipList、LSM等)
    • 分散式事務、分散式鎖等
  • 4.2 指令碼語言:(只是作為橫向擴充,一般問到linux也會問問shell指令碼)
    • python
    • php
    • shell
    • golang
  • 4.3 大資料與資料分析:
    • hadoop生態圈(hive、hbase、hdfs、zookeeper、storm、kafka)
    • spark體系
    • 語言:python、R、scala
    • 搜尋引擎與技術
  • 4.4 機器學習演算法:
    • 模型和演算法很多。不細說了,如果很熟練就去投演算法,國內很多公司都演算法崗都很稀缺,其他崗可以大概瞭解下理論。
  • 4.5其他工具的理論和使用:
    • 這個更多了,問的多的比如git、docker、maven/gradle、Jenkins等等,自己需要的話選擇性地去學。

5.實力要怎麼積累

  • 積累實力最好的方式就是平時在專案中或是學習中,多學多問,多思考多鑽研。這裡就說說短期內學習的一些方法和路徑:

  • 總結下來,一方面是通過看書、看視訊、看面經來不斷擴充套件自己的知識面,一方面是通過不斷的面試積累經驗和知識盲區,在每次總結的過程中積累實力。

先說說看書學習這一點
這裡應該是有個推薦書籍的環節,這幾個月確實看了不少書,但是並不是所有都有很高的價效比,在這邊大概列一下,前後順序也一定程度上代表了我認為的重要度先後,'/'做分割的是一類的書籍,一般來說看一個就夠了

書單:

  • 演算法與資料結構
    • 資料結構(嚴蔚敏)/大話資料結構 //如果覺得教材無聊就可以看大話系列,印象中裡面還有很多詩
    • 劍指Offer/程式設計師面試金典/程式設計珠璣/程式設計之美/牛客網+leetcode
    • 程式設計師筆試面試最優解(左程雲)/不如直接看左神的筆試面試指南視訊
    • Java的版本(不是很推薦):
    • 資料結構與演算法經典問題解析(Java語言描述)
    • 圖解資料結構(使用Java)
  • 計算機網路:
    • 計算機網路(謝希仁)
    • TCP/IP 詳解
    • HTTP權威指南
    • 圖解TCP/IP
    • 圖解HTTP
  • 資料庫://資料庫主要是多用,書上主要看索引和效能的部分
    • 高效能MySQL/深入淺出MySQL
  • 作業系統:
    • OS原理:作業系統(課本,黑色的那個)
  • Linux:
    • Linux私房菜 //鳥哥寫的,很全,包括bash部分
    • 跟阿銘學Linux //主要偏重於命令和操作,比較淺顯
  • java:
    • Java瘋狂講義/Java程式設計思想/Java核心技術 卷1
    • 深入理解Java虛擬機器
    • 併發程式設計的藝術/多執行緒程式設計核心技術
    • Effective Java
    • Java程式設計師面試筆試寶典 //何昊的那本,個人感覺是突擊知識點的神器
    • Java程式效能優化
    • 實戰Java高併發程式設計
  • Java Web:
    • Spring實戰/輕量級JavaEE 企業應用(紅皮,講SSH的) //主要看最後一部分Spring的就可以
    • 深入JavaWeb技術內幕(阿里 許令波)//這個講的還是比較深的
    • SpringBoot實戰/深入實踐SpringBoot
  • 設計模式:
    • 大話設計模式 //通俗易懂
    • 各類部落格的總結
  • 分散式與大資料:
    • 分散式服務框架原理與實踐
    • 大型網站技術架構
    • Hadoop實戰(hadoop體系包括得很全)
      //還有一本我暫時想不起來名字了
  • 其他:
    • Git:
    • Git權威指南
    • Git官方講解視訊(牛客網有帶字幕的)
    • Redis:
    • Redis實戰
  • 還買了docker、springCloud等等一些工具書,因為太小眾就不列舉了

除了上面說的書和視訊,最有用的還是大家分享的各種面經。

面經是個很不錯的東西(嗯,想看的可以直接翻到最後一節)。記住不要一掃而過(除了那種崗位不太匹配可以快速抓重點看),崗位匹配的你可以順著面經逐條去看,模擬一次面試過程(雖然是單向的,但是你心裡應該是知道每個問題你能答道什麼層次),這種不斷地模擬可以讓你知道盲點或者說弱點在哪,對於一個你心裡沒底或者想不太起來的問題一定要當時記下來或者當時就弄懂。

我當時是每天晚上在床上看幾篇面經,然後把存疑的問題copy到記事本中,第二天找個固定的時間短查詢解決和總結。長期下來會養成一個很好的習慣,你的知識點會不斷地擴充。

在一次次面試中提高

這一點其實跟剛剛看面經的那個很類似(那個我不是叫做模擬面試了嗎),每次面試完,一定要把自己不會的東西儘快記下來(當然你如果有記面經的習慣就更好了,還能再分享出去),然後找時間弄懂和總結。

除了知識點,每次面試(跟模擬面試不同的地方)還要總結的是哪裡發揮得不好,哪裡有可以提升的地方,下次一定要注意之類的。(就是有關面試技巧的東西,比如這次語速太快,導致面試官反饋了,又比如這次發現對方讓你在紙上畫個專案邏輯圖突然一時腦梗,那回去就好好在本上畫一遍)

3. 技巧

一些自身的軟實力

軟實力這個東西與面試的準備關係不大,基本上是長期形成的。

包括和麵試官的溝通(有的時候也會成為聊天瞎扯的能力);對一個問題的表達方式,邏輯思維(像有些人的發言就讓人聽上去很有層次感,很舒服,這方面欠缺的可以推薦玩玩狼人殺);除此之外對方也會很在意你的價值觀和為人(這個是我進了公司發現的,很多公司在內部的面試細則上面都會註明這一點,如果價值觀或是人品問題會直接否決。)想想也是有道理的,因為這個是入職之後能不能好好相處的關鍵,設想如果你是一個面試官,面對一個有實力但是說話太有稜角聊不太來的和一個不算出眾但基礎不錯很聽話可以培養的,你會選哪一個?(如果你因為生活太平淡了想選第一個,那這一條當我沒說。。)

這些軟實力其實要在生活中慢慢鍛鍊,比如多參加些活動,多和別人溝通,發表意見前好好組織自己的語言等等。(每個人都有每個人的性格,這些都因人而異,但有一點我們要記住的是在面試中,不論什麼情況,都要保持冷靜和清晰的頭腦,和一個謙卑的態度,交流要坦誠<尤其作為應屆生>,這樣起碼印象會好很多,要知道雖然面試有各種各樣花式的打分項,但是印象好往往是隱藏的決定性因素)

關於面試的準備和技巧

面試的技巧首先就是剛剛說到的態度。 一個謙卑(注意不是自卑,也不是把自己放的很低的樣子)和禮貌的態度和表達方式往往可以讓面試官的印象分提高很多,印象分很像之後要考察的實力分的係數。留個好印象,面試就成功了一半。(當然你一定也聽過那種聊得很嗨,或者偶遇校友之類的,毛都沒問就聊通過了的場景。這種情況還是不算在技巧中了吧,應該屬於運氣和緣分的範疇。而大多時候聊得開心和舒服會讓你感覺到通過率會比較高,這一點很多人還是深有體會的)

然後說一下面試之前可以做足的準備。

首先從簡歷開始說,簡歷怎麼調格式,做幾頁,排版啥的就不想多說了,感覺很多文章都分享過。我只說說技術方面的內容怎麼寫。

專業技能的描述謂詞無非就那麼幾種:精通、熟練、熟悉、瞭解。(還有一級叫聽說過,這個級別的可千萬別往上寫啊兄弟)

精通感覺一般還是不要寫,除非你在某個技術點上真的有足夠的把握,比如原始碼看的很透徹的同時還能深刻理解原理並能靈活處理各種case場景,如果還有相關的開源貢獻,那就自信地寫精通吧。

我們把自己掌握的大多數技術點叫做熟練掌握,這個需要我們在之前對各個技術點進行橫向縱向的複習和總結,並不只是用的多有經驗就行,有的時候我們覺得熟,但真讓你說的時候卻不知道從何說起。

至於熟悉和了解,可以寫一些自己理解原理但是不常用的技術點,尤其是比較流行的,各大公司都在用的技術(比如MQ,分散式快取等等),這些你在學校不一定用過,但是你可以通過看部落格,寫demo去理解他的設計和原理,面試的時候可以講得清楚。

這裡還有個技巧,更細心的同學可以針對每個公司崗位的job detail不同,熟悉和了解這塊就針對jd中cover的技術點去寫。這個做法是很聰明的,畢竟熟悉和了解這個層面是可以提前學習和準備的,有針對性的去寫對方需要的,是提升通過率很好的一種方式。(如果嫌麻煩就算了,比如我就是)

下面再說說專案經歷這塊:敘述一定要精煉到位,細化到每一個亮點上。我現在再看我二三月份的簡歷簡直是有種想撕了的衝動,當時就是專案描述兩三行,然後概括下我大概做了哪幾個模組。完了。

事實上,不能講得這麼泛泛,就從中找2-3個亮點,一句話高度概括,突出亮點。

比如後來我就把我一個普通的web專案挖出來三個點(爬蟲,通訊控制方面,安全加密方面),分別用一句話敘述,這一句話最好包括這個技術點的思路,解決了什麼,有沒有做什麼優化。比如一個爬蟲工具可以寫成這樣: