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

公眾號_程式設計師喬戈裡發表於2019-03-04

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

我負責這個系統中爬蟲的開發,終端控制管理,店鋪管理。。。。

是的,上面這個爬蟲就佔用了五個字,等於沒說,面試官看到壓根不知道怎麼去問。這裡還可以這樣寫:

負責系統中爬蟲模組的開發,用於爬取影片的各種資訊,包括年份,介紹,主演資訊等。

這個起碼告訴面試官爬蟲做了什麼,但是你並不能保證他會問,因為你的敘述不一定能引起他的興趣。那還可以這麼寫:

獨立開發多執行緒影片資訊爬蟲工具, 並針對執行緒池效能、網路異常以及反爬蟲措施進行多次優化,容錯性良好並達到併發請求30+的QPS。

你覺得面試官看到這句話,他不想問點什麼嗎(除非他真的就不想要你)。

所以說,其實面試官呢都是希望在面試的過程中發現我們的亮點和優勢,從而展開更深層次的交流,但是往往在簡歷中沒有一個讓他詢問的入口,這樣就可能導致他會隨意問(比如你瞭解什麼什麼嗎?一般情況下都不太樂觀),或者就說那你來講講吧(這種問法其實已經表達出他不知道怎麼問的情況了,你在講的時候一定要突出重點,否則會讓人感覺沒什麼亮點,普普通通的專案而已(當然就算是普通的專案,我們也要挖掘它的價值和自己的價值不是))

我們在面試的過程中最重要的是自己掌握主動權,如果面試官問的都是我們熟悉的範圍和準備過的領域那我們答起來也會更加得心應手。而讓面試官隨著我們簡歷中埋下的這些亮點(他就算知道你有意想說這一點,往往也會去問,因為他就是想在短時間的面試中瞭解你處理問題的能力),去進行更深層次的交流,而這個更深層次的交流,還需要我們針對簡歷上的每一句話,都準備多個層次和維度的擴充套件。

比如還是這個爬蟲,你可以充分擴充套件執行緒池的相關優化(有可能專案中沒有怎麼優化甚至就是個單執行緒,但是在準備面試的過程中還是可以專門去做一些code重構的),優化網路的NIO相關擴充套件,以及反爬蟲的各種各樣的措施,以及爬蟲方分別如何應對。這裡只要你去想,能準備的東西太多了,面試多了自然也就越來越熟,好像專案就是做得這麼完美一樣。

這裡我就不怎麼擴充套件去說了,再講下去這篇文章就寫不完了。。。

最後是面試中的技巧和經驗。

  1. 好好對著自己寫的簡歷一行一行看一遍,這都是你挖的坑,是準備給面試官作為切入點交流的,並不是自己往裡跳的。(對每一行都要有足夠了解和把握)

  2. 面試過程不要緊張,尤其是前幾次,建議先從小公司入手鍛鍊下面試經驗(參考我之後自身的反面教材

  3. 面試方式不同,側重點不同(無非是電話、視訊、現場三種)。

  • 電話面試建議找個人少安靜的地方坐著回答,並且建議拿紙筆多做記錄多畫多寫。(當然如果你覺得身邊很多朋友可以讓你越聊越嗨那也可以,坐著是讓你整個節奏慢下來,說話明顯更加沉穩,親身體會過站著走來走去和坐著的區別)
  • 視訊面試其實和電話類似,只是可以實時寫程式碼,面試官能看到你的表情。這裡還是要放鬆,如果你比較緊張,可以不直視鏡頭,好好想問題就是了,因為很多面試官你答得好也會面無表情(因為他們也不常視訊,表情都很尷尬),然後你看到他們沒表情的表情肯定會受影響。
  • 現場面呢,最重要的是和麵試官互動了,說幾個點:語氣要輕鬆點,多點肢體動作有助表達,多笑;不太好說清的就用筆在紙上畫,一遍畫一邊講,面試官也會更容易和你交流;如果你可以時不時幽默一下開開玩笑是更好了;見面和離開記得禮貌地握個手說聲謝謝。
  1. 學會平等交流,別把自己身段放的太低。其實有一點你要清楚,面試是個雙選的過程,他可以拒絕你,你也可以拒絕他。千萬不要太上趕著,反而會影響自己正常的表達和邏輯。(就跟你見了喜歡的姑娘就不會說話了一個道理)

  2. 回答問題的時候不要一口氣把知道的全部說完,然後還毫無條理。學會一個知識點由淺入深講解給面試官,並且留有餘地給他進一步去問。

舉個例子:

  • 就說最簡單和普遍的HashMap,讓你講講,你就可以先說說hashMap的設計原理,底層結構(連結串列+陣列)擴容方式等,從這你就可以說說這種設計好在哪裡(比如講一講put是如何做hash的),這時候你可以說這種hash可能會有衝突,hashMap也是做了相應設計
  • 然後面試官會問題你怎麼解決衝突?你可以再給他講講解決hash衝突的三種通常方式,而hashMap用的是鏈式法,然後可以說到這樣會有隱患就是hash鏈過長。
  • 面試官再問,你會給他講解決複雜度高的長鏈用了紅黑樹的結構,這裡還可以延伸到紅黑樹的特點或者jdk7和jdk8的不同實現,這時候你可以說解決hash衝突,但hashMap還會有併發和同步的問題。
  • 面試官會讓你再講講,你可以說說hashtable是執行緒安全的,怎麼實現的(sync函式),並不好,從而引出更好的juc包,說說concurrentHashMap,之後又可以說道鎖分段原理,弱一致性迭代器,concurrentHashMap的鎖粒度(java7和java8不同),同包的CopyOnWriteArray等等。
  • 你還可以延伸說到鎖(重量、輕量、悲觀樂觀各自實現、底層原始碼等等)、快取(因為很多時候Map的結構可以作為快取,從而可以說到快取系統的設計,kv原理,分散式快取redis、memcashed等等)
  • 舉這個例子就是想說,一個簡單的基礎問題可以一步一步有條理有層次的回答,每一層表達完拋個引子,讓面試官可以繼續問下去,從而讓面試官真正瞭解你的掌握的深度。
  1. 如果真的不巧聊到不擅長的地方,學會轉移話題,從一個點中聊自己感興趣或是有把握的方面(比如你對訊息佇列不太熟但是redis用的熟,你就可以在問到訊息佇列的時候說,因為之前都是自己做的專案嘛,效能方面沒有考慮到最優,一些非同步的方式還是靠redis list去實現的,雖然redis的訊息機制並不常見,但當時還是滿足了需求,之後可以考慮效能方面的提升和技術評估;又比如問你http請求細節,rest的設計實現細節,你可以說http restapi服務介面效能的一些不足,後來使用了rpc的方式,當然你這麼說一定是要對rpc很瞭解)其實有的時候面試官是知道你是有意轉移的,但是往往他們也不會抓著你不會的去問,非讓你自己承認自己的盲區,他們也許根本不在意這些。

  2. 如果真的被問到不會的,就直接說你不會(說你不會、說你不會,我再補充兩遍),或者禮貌地說這方面可能我還要多學習。(對一個拿不準的問題千萬不要猜,即使是二選一的那種問題,猜錯了直接完蛋,猜對了被人看出來,再往深問還是完蛋)另外,像可能,大概是,我覺得這種表達最好不要,一聽就是對一個點沒把握,有可能會讓面試官覺得學習太浮躁不喜歡尋求原理。
    那對於自己知道原理(確實是理解了的)但是沒用過的東西,就講講原理,並承認自己實踐不足,表現出好學的態度。面試一定要真誠。

  3. 問到有什麼offer就直接說,不要藏著掖著,也不要把更好的offer(比如bat的)講的非常誘人,一副bat我都拿到了的樣子(面試官會心想,那你還來面試我們幹什麼)。再強調面試過程一定要真誠。除了直接說,誠實點之外,也要真的做些思考:對方公司跟之前的offer比優勢在哪,比如平臺更大?專業技能棧更match?工作更有挑戰力?地點更合適?有機會留用?隨便一條符合的都可以講出來,起碼讓對方覺得你想來面是有原因的並且真的有可能加入。(如果你還提前瞭解對方公司的文化,可以講出這個文化自己很認同那就更可以了)

4. 緣分和運氣

關於這一點只有一句:平時多做好事,熱愛生活。
其實都知道面試要講緣分,講運氣,但人往往可以在很順利地通過面試之後說句運氣好運氣好,卻很難在努力準備卻失敗的經歷之後保持平靜。
但不管能不能轉運是不是本命年有沒有緣分,努力和收穫的關係總是多年不變的真理。
所以,講心態,講實力,講方法。足矣。

下面是面試的詳細過程,包含面經:

按時間順序,詳細敘述一下我面試的過程,包括面經和心態的轉變:
括號裡是對問題的補充,如果感覺有知識點的盲區,大家正好可以去深入學習一下。這裡說一下我投的大多是Java研發崗,所以其他語言的可以忽略java問題

首先說一點,複習準備一定要早(當然這是說給19屆師弟師妹們聽的,嗯你們看到這裡已經可以開始複習了),有同學去年暑假劍指offer都刷了一遍,然後我竟然今年3月才買這本書。。還有同學前一年冬天就已經去實習了,這種機會也不錯。但寒假如果不實習的,一定要進入到學習狀態。我準備的就有點晚,寒假完全沒看書,真正開始準備,大概是2月中旬號玩了一晚上狼人殺之後。

就是那個時候發現校招就要開始了,然後開始慌了。大概看了一週的書(基本上都是java基礎),然後師兄說阿里內推了,心想趕緊投吧要不人家招夠了就不招了(後來發現都5月6月了還在招。。),然後就慌慌忙忙投了簡歷。

這裡我要說一點最重要的事情: 一定不要在沒有面試經驗的情況下先面大廠,或者是你想去的公司。

我是3月1日下午三點半在阿里的官網完善的簡歷,5點電話就過來了。作為一個java coder,阿里是個很好的平臺,(當然C++的崗可以好好準備騰訊),一定還是準備充分了再投,你先面的結果很可能是焦急地等一兩個月然後被後來準備充分再來面試的人取代。

阿里 3.1,3.2(兩面)

兩天各面了一面(投的螞蟻金服,第一天面的就不太好,第二天又把我撈起來面,並且面完感覺就走遠了,但當時卻沒有reject,這就導致之後一個月一直在流程中,阿里其他事業部的師兄師姐沒辦法把我的簡歷提走,最終到要筆試瞭然後變成了rejected)

那個時候就是處於我所說的無知狀態,知識點掌握的不夠牢,簡歷寫的亂七八糟,面試經驗為零(這應該是我上學以來的第一次面試),面試技巧就更不懂了。

然後當時兩次都感覺聊得很差(尤其是聊演算法模型的時候都想自爆了),也根本沒有記錄面經的想法。所以有些問題我都記不起來了,大概說一下吧。

  • hashMap的擴容原理,初始有13個,要怎麼new?(達到了負載因子,直接手動>>1)
  • Integer的常量快取池的問題(-127~128範圍有個cache)
  • ConcurrentHashMap的size()怎麼做的(並沒有完全加鎖,而是先樂觀的認為不會有寫,通過modCount判斷是否更改,這個我當時記不清就用了很多可能、大概、應該這種詞,事實證明直接說不清楚會更好)
  • Spring的AOP關於攔截private方法一些問題.(細節忘記了,當時答得也不好)
  • 專案中資料字典怎麼做的快取,如何做的通訊,有沒有用什麼模組。(說了自己的做法,用的全域性的HashMap,然後他會延伸到高併發的場景,分散式快取怎麼做等等,由於沒實際操作經驗提前也沒準備,並且還沒有直接說不會,又是用很多模稜兩可的語句答得)
  • 講講你的論文相關的模型吧(這個其實在簡歷上根本沒寫,只是寫了數學建模的獎,然後面試官就開始問機器學習的演算法,很多都是我沒準備的,並且我心想我投的也不是演算法崗啊。。。所以說對於簡歷上的每一條一定要熟悉,做足準備,並且遇到簡歷上沒有都扯到的方面,要想辦法轉移,不要在這耗著)
  • 講完演算法的問題,面試官很尷尬的說了句,你這自己的研究方向你都搞不清楚嗎?我當時預感就差不多走遠了。。。
  • 其他問題真的太久遠了,我當時也沒有記面經的習慣,所以就沒有了。但是最大的感受是面阿里的時候整個人都是緊張的狀態,語速特別快,恨不得把知道的都說出來,沒有條理,並且把自己姿態放得特別低,還在樓道不停走來走去。(對,以上說的這幾點全都是不應該的,但主要原因還是當時準備太不充分,簡歷方面的準備以及知識點的積累都不夠;另外一點,還是要強調不會的就是不會,千萬別說大概是,我覺得吧這種東西,說的不好很容易讓面試官認作不懂裝懂,雖然你只是很想向面試官表達點什麼,哪怕只是積極的態度)

  • 從阿里面完試開始我的心態基本上就崩掉了,對自己極度懷疑,加上今年諸事不順,心情直接跌到了低谷。然後整個三月基本上都是黑暗的,整個一個月都沒再投內推,每天從早晨起來,大多時間就在看書刷題,晚上十點回宿舍躺在床上,還要刷兩個小時牛客的面經。一個月下來很少說話,提升肯定是有,但是這個過程,其實完全可以用更好的心態去經歷。

  • 然後這段極其黑暗痛苦的日子持續到三月底,一個師兄想幫我內推百度,因為之前因為沒信心也錯過了騰訊的內推,就心想要不試一下吧。

百度(123面)

一面 3.30 下午兩點 45mins

  • 自我介紹,印象最深最費心的專案(這個一套可以提前準備,在某些亮點可以估計丟擲等面試官來問)
  • 講講專案中的爬蟲和優化怎麼做的,為什麼選用jsoup而沒有用python的urllib
  • 說說你瞭解的反爬蟲措施,和針對異常的處理。
  • 那你覺的你來做一個網站要從哪些方面考慮反爬蟲。

這裡可以提前和學習,即使你真正使用的只是一點,也可以在相關問題上做更深的瞭解。
最簡單隻分析請求,攔截所有非瀏覽器的直接請求(可以通過新增偽報頭解決);檢視refer頁做防盜連結(可以改refer項);基於使用者行為的策略,同一ip相似請求判定(代理或ip池,或間隔請求解決);基於使用者session的策略(模擬多使用者登入解決);封裝前端資料,用js渲染生成(通過探取和模擬非同步ajax請求解決);對ajax請求進行加密等等方法。

  • 講講專案中怎麼實現的充值,鎖的機制和事務註解,如何保證了事務的一致性。
  • spring層面做事務和資料庫層面做的區別,各自實現方式。
  • 聊了事務的傳播性和隔離級別,問了mysql的預設隔離級別(可重複讀)
  • spring中事務傳播性怎麼配置(xml方式和註解方式,還有關於savepoint的使用)
  • 演算法:O(1)刪除執行連結串列結點,做分析(其實是要指出劍指offer中那個直接copy值的方法的缺陷和隱患)
  • 演算法:二叉樹的最長距離(遞迴的思想)

二面 3.30 下午五點 50mins

  • 聊專案(這次是針對專案中的加密演算法和安全性做了闡述,大概20分鐘吧,之前爬蟲那個例子已經說了專案亮點要怎麼準備了,這裡我就不多說了)
  • 詳細聊了聊spring的IOC和AOP思想
  • 關於AOP在spring的應用(比如事務,通知,aspectJ,slf4j的原理,和log4j的對比)
  • 關於jdk代理和cglib第三方代理(說出對介面代理和子類繼承的區別)
  • 用的什麼資料庫,Mysql。
  • 最大的資料量多大,用了索引沒有,怎麼用的(聊了字首索引,對於varchar型別的值,又聊了聊char,varchar,text,blob的關係和區別)。
  • 為什麼索引不能隨便用,什麼時候用(什麼時候失效,什麼時候最高效)。
  • 如何達到索引開銷和效能的平衡,用了一個表去舉例。(方法就是,根據情境看經常做的查詢是哪些,然後依次是什麼查詢條件,保證最高效索引的同時,也保證索引不失效,避免無效開銷,並且根據show profile和explain功能進行對比分析)
  • 資料庫用了快取沒有,講講redis的理解(用作快取,佇列,也可做儲存)。
  • redis是單執行緒還是多執行緒的,舉個例子(做計數器,rank排行榜)
  • 講講hbase的原理,CloumnFamily包含哪些,region什麼情況做分割,對於版本號這個第四維度的使用方式(一般預設三個版本)等等
  • 讓我等訊息,說經理會聯絡我。

經理面 4.12 中午 40mins

  • 經理面其實更加放鬆,不只是技術方面,還有生活,性格多方面,感覺是個技術+hr的綜合面。
    聊家庭,家鄉,工作意願,愛好等等(聊了十幾分鍾,感覺都很不錯,然後之後的面試也就很輕鬆了,基本是我在講他在聽)
  • 講了講專案的設計,包括異常的處理,資料庫設計,通訊模型的設計。
  • 講講你理解的JVM吧(從記憶體劃分說到了GC演算法、分代思想,CMS和G1 collector,到類載入模型,tomcat的非雙親委派、執行緒上下文載入器,到JVM調優的策略,gc引數設定策略,如何找死鎖,讀快照,發現記憶體洩漏等等吧)
  • 然後說了下部門的技術棧和部門介紹,說了部門可能沒有留用的hc,問我介不介意(當時還沒offer當然說不介意只是希望去學習)
    然後就說把我簡歷鎖了,之後會給我發offer。
  • 其實到現在我都很感謝百度,雖然最後因為部門和留用hc的原因沒有去,但是這次面試收穫最大的就是信心。並且經理電話裡就給了口頭offer,這個讓我懸了一個多月的心一下子就放下來了,接下來的幾天乃至之後的面試整個人都是放鬆的狀態。(真的很難形容,這種轉變就在這一個電話的前後)
  • 所以,其實大家也早晚會有這一天,沒必要一直那麼緊張的狀態,太痛苦了。(雖然我知道這種話說得簡單),另外一點就是三月份確實有了很大的提高,這個告訴我們,該逼自己的時候還是要狠心一點。

360(123面)

有了信心或者說有一個offer之後,你就會越來越順利,從這之後的每次面試都會有不同程度的收穫。360的流程是走得最順利的,筆試+面試,三次面試一天完成,但是360的面經可能寫得稍微簡單一點,因為很多知識點在後面的面試中也出現了,就沒有做過多解釋,騰訊滴滴美團的面經要詳細一些。

360一面 4.12

  • 自我介紹加專案
  • 執行緒池如何優化的爬蟲,資料規模
  • 網路時延如何處理
  • 同名影片如何選取,有沒有更好的方式。
  • 反爬蟲的原理,從低階到高階說一下,分別如何應對
  • 收穫了什麼
  • 執行緒程式區別
  • 說下資源方面的區別,共享,不共享
  • 共享的具體哪些資源
  • jvm記憶體模型
  • 堆區的特點
  • 資料庫左連線右連線,場景
  • 給200個200個數的陣列,找到最大的200個
  • git 常用的操作,git rebase和git merge區別
  • 分散式資料庫怎麼呼叫
  • linux常用命令,檢視記憶體,檢視磁碟使用率

360二面 4.12

  • 聊專案,介紹下背景,怎麼談的
  • 印象最深的模組及解決,其他專案呢,跟著老師做的,還有簡歷上沒寫的專案
  • 專案經驗還可以那基礎怎麼樣自己覺得,
  • 說下jvm吧你知道的,中間會問
  • jvm詳細如下
  • 記憶體模型
  • 垃圾回收
  • 分代及回收演算法
  • 哪些作為gc root
  • 收集器的特點分類
  • 類載入機制和雙親委派模型
  • 幾個載入器
  • tomcat類載入有什麼不同,說載入順序並不是雙親模型,具體順序說一下
  • 併發注意什麼,執行緒實現同步的方式,通訊
  • 幾種同步的區別
  • 悲觀鎖樂觀鎖,底層怎麼實現的,越詳細越好
  • 單例模式的特點,幾種實現,容易引發的問題
  • 如何防止記憶體洩露,哪些會容易造成
  • jvm調優如何檢查記憶體洩露,如何優化gc引數
  • 寫sql 查詢帶日期多次考試成績表中,每個學生的每門課最高成績,日期要準確
  • 分別用having子句寫和用子查詢寫
  • 寫程式碼 旋轉陣列中查詢某一個值

360 三面 hr 4.12

這是唯一一篇hr面經,因為我只面過這一次hr,其他的三面要麼是技術,要麼只是打個電話說說情況,還沒問問題就掛了電話(比如騰訊的)。

  • 講一下專案怎麼接的,怎麼跟甲方溝通,遇到的最大問題,怎麼克服的
  • 自己的專案和老師的專案和安排怎麼協調。
  • 平時有什麼愛好,怎麼安排自己的時間
  • 攝影都去哪拍,喜歡什麼運動,什麼時候運動
  • 為什麼選我們部門,其他部門你怎麼看
  • 我們是做移動端後臺的,喜歡玩手機嗎
  • 說說常用的app平時怎麼用,頻率
  • 以後會不會創業,為什麼
  • 以後的規劃,職業技術和生活兩方面

hr面沒有太多經驗,個人生活愛好這類我感覺就是放輕鬆聊,規劃方向這些可以自己提前準備準備,但是比如創業,offer(之前說過了),價值觀一類的問題,其實你也不知道對方想要什麼樣的回答,乾脆隨緣吧。

騰訊 (12面)

騰訊的面試有一點印象很深,很考察思維能力,經常會有一些意想不到的問題,或者智力題。挺有意思。

一面 4.23

  • 上來看了我的簡歷問我會不會C++,我心想雖然學過,但是好幾年不寫,還是說不會吧,然後面試官很好,就不問了。
  • hashmap底層結構畫一下,手寫程式碼做一個url解析器,用正則方式和hashMap的資料結構。
  • 識別2的n次方,寫個函式。(最快的是用位操作,大家應該都知道n&(n-1)可以去掉二進位制最右的1,那2的n次冪&之後便為0)
  • 自己實現http response響應頭的結構及解析,用buffer(寫個虛擬碼)
  • resp頭中都有什麼(主要考察http相關知識)
  • 海量資料找到出現次數最多的100個(記憶體不足的時候可以先做hash分片,最後多路merge,每次操作可以用hashMap計數,也可以自己做hash函式計數)
  • redis底層實現,zset資料結構(問到了SkipList跳錶這種結構)
  • jvm記憶體模型,分代,cpu100% 怎麼排查(我以為問Jconsole的使用,其實是想問linux效能監測和調優)
  • 用int值表示ip如何做(剛好32位bit一對一對映),寫個虛擬碼做transfer
  • nio模型說一下
  • selector中的wakeup什麼含義(這個答得不是很好)
  • select poll epoll (linux核心相關的知識)
  • arraylist.sort怎麼實現的(這個可以看看TimSort的思想)
  • 怎麼看待java跟c++(說下區別和自己的感受)
  • 能實習多久(這個好說)
  • 去深圳工作怎麼看(這個真沒想過,不過當時說也可以吧)
  • 有女朋友嗎(…)

二面 4.24

二面其實就兩個大問題,但一直往很深的地方問。

  • 100億個數找最大1000個(說了分片,用堆,再歸併)
  • 問你確定嗎?(我一想是最大的1000個不是出現次數最多的,其實是可以順序讀取,還是用堆實現)
  • 有什麼缺點,分佈不均勻(說一下堆的複雜度由來)
  • 有沒有其他思路(用hash雜湊,計數排序)
  • 這個更慢,還有更快的嗎(我心想我平時就都是答得堆啊,怎麼這次還有更快的?)
  • 然後講了基於partition的劃分思想(找到第k個開始partition,在左邊就在右面遞迴,在右面就在左邊遞迴,最後確定partition出最大的k個)
  • 這種思想了解了,但最壞情況太差,不穩定,還有更快的嗎
  • 是不是要用概率統計學,抽樣估計?
  • 說下思想。。
  • 不夠精確,還有又精確又穩定的嗎?
  • 。。。
  • 那又給你一個數,你怎麼快速告訴我是不是在這100億個數中?
  • 這個我知道有可能是想問Bloom Filter,但是具體到hash函式去幾個怎麼算,怎麼判斷誤差等細節,我也記不太清了,就說了說思想。
  • 然後進入第二個問題:
  • 一個程式最多申請多大空間(看機器cpu的處理位數看情況)‘
  • 怎麼保證程式間資料的安全?執行緒呢?
  • 安全方面有沒有做過一些研究?
  • 登入驗證怎麼做的,為什麼用md5,有沒有改進(+salt使md5庫難解出),微信用的什麼方式- 你知道嗎?你想想應該用什麼方式?(這裡可能是問SSO單點登入的原理吧,可以講講SSO JWT token等技術的原理,這個也是我實習之後瞭解到的,當時答得一般)
  • 那說到通訊安全,怎麼保證http的安全性,冪等性,回撥同一個會話怎麼標識不同請求,不同- 會話怎麼區分(這個每個問題都畫圖敘述了下)
  • TCP 3次握手和timewait講一下原理
  • 講一下滑動視窗,飽和了怎麼處理
  • http安全嗎?https說一下?
  • get和post請求
  • linux怎麼檢視網路狀態(vmstat)
  • 檢視udp的效能,udp埠多少,什麼時候用udp?
  • 為什麼tcp不行?
  • qq裡哪些用的tcp哪些用udp?分別針對每種情況說一下為什麼?
  • 可以看到騰訊還是很愛問網路通訊、大資料處理的(當然C、C++也很愛問,只不過我說了別問,他們就真沒問,當然你做java的也不要期望他們會問你多少java問題)
  • 然後當時並沒有hr面,我心想應該是掛了,但是微信的狀態又遲遲沒掛,結果到了一個月之後五月底我都回家準備入職了(絕對又是補招的備胎),然後打電話問問個人情況(也沒說是不是準備給offer),問可不可以去深圳,轉C++方向。
  • 當時也有比較好的機會了,並且實習轉崗,如果不確定能留下,絕對是不建議做的一件事,所以就實話實說了。

滴滴新銳(123面)

一面 5.12

  • 說說你對現有Web開發框架的理解(從各個層入手橫向對比優缺點,印象中說了SpringMVC和Struts,mybatis和hibernate及jpa)
  • mybatis和hibernate各自的快取原理和比較,hibernate的一級二級和查詢快取,還有針對快取的miss率,置換策略,容量設定和效能的平衡問了自己的理解。
  • 要你設計的話,如何實現一個執行緒池(就講執行緒池的原理,從初始執行緒數,核心執行緒數,然後到任務佇列,滿了繼續到最大執行緒數,再滿了到飽和策略handler,飽和策略一般有哪幾種,基本上要理解ThreadPoolExcuter的構造方法那幾個引數)
  • synchronized關鍵字,實現原理(和Lock對比著說,說到各自的優缺點,synchronized從最初效能差到jdk高版本後的鎖膨脹機制,大大提高效能,再說底層實現,Lock的樂觀鎖機制,通過AQS佇列同步器,呼叫了unsafe的CAS操作,CAS函式的引數及意義;同時可以說說synchronized底層原理,jvm層的moniter監視器,對於方法級和程式碼塊級,互斥原理的不同,+1-1可重入的原理等)
  • 演算法:手寫一個ArrayList類,實現add,remove,等基本的方法(主要考擴容的原理和實現,重點寫出擴容機制以及擴容時的copy過程)
  • 然後讓對這個ArrayList進行改進,使之可以應對併發的場景
  • 演算法:手寫字串的正則匹配,實現*和.的功能,用的遞迴(寫了一半他說時間差不多了,思想大概瞭解了)。

二面 5.12

  • 說說你認為專案中技術最薄弱的一個地方(答了IO網路監控和通訊模組,短連線效能太差)
  • 舉例說說在什麼情況下會出現效能瓶頸,如何優化(答了用NIO的方式)
    NIO的原理,jdk中有哪些工具和類去實現,如何實現(selector和channel的用法),真的好用嗎?還可以用什麼?(面試官應該是想問netty,因為沒有實際用過,只能給他講了netty的原理)
  • 那來說說AIO吧,和NIO什麼區別(對非同步的理解),AIO在工程中如何實現的?(大概說了下ajax的回撥函式),又問回撥函式具體是怎麼實現的(傳遞函式指標)。
  • 然後藉著非同步IO想問訊息佇列,講了一下幾種模型和原理。(面試中沒有用過沒關係,只要你懂原理還是可以跟面試官講,起碼可以證明你是愛學習的)
  • 專案中非技術上的困難(和甲方溝通需求,沒有規範化的專案設計,需求變更太頻繁等),問了我解決的方法還有以後希望怎麼改進。(變相問網際網路公司裡面各個team以及需求方是如何合作和分工的)
  • 講講Spring中怎麼對初始化的bean做其他操作。(這裡有三種方式,@PostConstruct註解方式,init-method的XML配置方式,InitializingBean介面方式)
  • 三種實現上有什麼區別(還好看過點原始碼,其實前兩種是一個意思,都是通過反射的方式用aop思想實現,可以消除對spring的依賴;介面方式是直接呼叫afterPropertiesSet方法,效率更高點。spring載入bean時先判斷介面方式,再執行配置註解方式)
  • 演算法題,一個先減後增的陣列,查詢目標值。(這裡並不是查詢最值,也不是劍指offer上的旋轉陣列,但是思想上也可以用二分的方式)
  • 演算法題,兩個大數求和,要按高到低位的輸入,實時輸出結果的對應位,空間O,時間O(n),不借助工具類。(要考慮實時的進位標識,以及多個9之後的連續進位標識)

兩面完了電話讓去參加新銳的現場終面,很有誠意地報銷了所有的花銷。新銳的三面還是有難度,基本上圍著演算法在問。

三面 5.12

  • 演算法:int範圍的隨機數的階乘編碼實現。
    (這個題如果直接按最簡單的演算法題肯定是不行的)

1.首先考慮要用字串做運算(因為中間數太大了,只有String能儲存,當然你可以藉助BigInteger或BigDecimal類去輔助實現)。
2.階乘直接計算代價太大,迴圈太多,考慮設計中間快取。(正常算複雜度太高,本身就是階乘級的,所以正常想到用時間換空間)
3.只用空間換時間的話快取也不能覆蓋全部,如果把所有的中間值儲存,空間是eb級別,不現實。(這裡就要達到一個空間和時間複雜度的平衡點)
4.存部分中間值用部分空間換取時間,達到空間複雜度和時間複雜度的最優平衡。(開始說的二分做分割儲存之後改為等間隔做分隔儲存,間隔選取多長為好?我覺得要首先確定空間複雜度的接受極限,然後儘可能減小時間複雜度,因為空間複雜度是可以有預估值的,而時間複雜度當然我們是希望約小越好的)

(這裡說一下,我並不是一開始都想到了,只是面試官一直在提示我思路,給我時間思考,沒有否定過我)

  • 因為頭一次手寫白板,返回型別有錯誤,面試官說你這個編譯器會提示什麼?
  • 又問了異常體系,checked unchecked虛擬機器原理怎麼做。
  • 解釋下iaas.paas.saas和之間的關係,外呼介面和服務怎麼呼叫的。
  • 資料庫主從備和讀寫分離原理,ibatis怎麼配置。(這個只講了資料庫層面的原理,比如監聽執行緒,主機和從機的同步方式等,但是具體程式碼層面的配置,由於沒親自做過,就說不太知道。)
  • 演算法,股票最長增長區間,優化
  • 演算法,最長遞增子序列,一個dp陣列一個max陣列,最優情況
  • ps:這個面試官應該是面試過程中遇到最nice的一個,也是我現在的老大。其實面試除了自身的因素也有面試官的因素,一個好的面試官不會隨便地否定和質疑你(當然有專門壓力面的),而是可以讓你在放鬆的環境下,挖掘你真正對於一個方面的深度和理解。最後的十幾分鍾他並沒有問我問題,只是在跟我聊天,他跟我說不管是哪個公司,真正的發展還是跟部門的方向和氛圍有關係,選擇的時候不要只看公司,做的業務部門方向和leader才是該去了解和考慮的。作為應屆生很多時候不那麼瞭解,這就要靠我們(指面試官)多去了解你想發展的方向。然後聊了很多成長路徑和規劃的事。
  • 真正實習到現在一個多月,深深覺得面試就是面試,很多知識和題目都是可以準備的,而工作中面對各種情況解決問題的能力和方式才是更重要的。為了面試準備了很多,工作了發現要學的東西更多,我們真的還有很長的路要走。

美團(123面)

1面 1hour 5.26

  • java基礎,從頭到尾問了個遍,都是大家準備的,但是也挺深的,包括:
  • hashMap,紅黑樹處理衝突,jdk7和jdk8有什麼區別
  • JUC相關的集合,ConcurrentHashMap jdk7和jdk8的區別,Collections.sort函式jdk7 和 jdk8 分別怎麼實現的。(總感覺這個面試官在某段時間肯定糾結過兩個版本)
  • CopyOnWriteList底層是什麼,適用的情況,vector的特點,實現的是List介面嗎。
    併發的問題,執行緒間通訊三種方式
  • 鎖的膨脹過程,Synchronized和Lock的區別,底層的monitor實現和unsafe類的CAS函式,參數列示什麼,暫存器cpu如何做)
  • volatile cpu和暫存器層面是怎麼實現的。
  • 執行緒池建構函式引數,各種型別的預設池各自的特點,ForkJoinPool是怎麼實現的,多執行緒等等問了一個遍。
  • 為什麼匿名內部類的變數必須用final修飾,編譯器為什麼要這麼做,否則會出現什麼問題
    資料庫:
  • 索引的分類。
  • 主鍵索引和普通索引的區別,組合索引怎麼用會失效。
  • 索引的字首匹配的原理,從B樹的結構上具體分析一下。
  • 聚集索引在底層怎麼實現的,資料和關鍵字是怎麼存的。
  • 組合索引和唯一性索引在底層實現上的區別(這個是整個一面感覺答得不好的一個問題,不太明白麵試官想問啥)
  • sql的優化策略,慢查詢日誌怎麼操作,引數含義。
  • explain 每個列代表什麼含義(關於優化級別 ref 和 all,什麼時候應該用到index卻沒用到,關於extra列出現了usetempory 和 filesort分別的原因和如何著手優化等)
  • show profile 怎麼使用。

2面 1hour 5.27 (因為這一面問得很深,所以到現在都記得很清楚)

  • 一個url到頁面全過程(讓我能說多詳細說多詳細,最好從OSI七層的每一層去擴充套件)
  • http的請求頭格式(這個真的記不太清了,只說了幾個有印象的標誌位)
  • getpost區別,post可不可以用url的方式傳參。
  • 說到了url有最大長度,就問長度有限制是get的原因還是url的原因,為什麼長度會有限制,是http資料包的頭的欄位原因還是內容欄位的原因,詳細說明。(在他一步步追問下答了個差不多)
  • 關於冪等性的詳細介紹。
  • 冪等性是http層面的問題嗎,還是伺服器要處理和解決的內容。(就是看你對冪等性的定性是怎麼理解的)
  • 後臺伺服器對於一個請求是如何做負載均衡的,有哪些策略,會出現什麼樣的問題,怎麼解決。(說了一致性hash演算法,分散式hash的特性,具體的應用場景,又非要問我知不知道這個最早在哪個公司使用的…我說這個真不知道。好像是amazon?)
  • 說說http的缺點,無狀態,明文傳輸。
  • 那https是怎麼做的,如何實現的?ca認證機構。
  • 然後問我https ssl tcp三者關係,其中哪些用到了對稱加密,哪些用到了非對稱加密,非對稱加密金鑰是如何實現的。(還好我專案中涉及到了一些加密)
  • 關於加密的私鑰和公鑰各自如何分配(客戶端拿公鑰,伺服器拿私鑰)
  • 那客戶端是如何認證伺服器的真實身份,詳細說明一下過程,包括公鑰如何申請,哪一層加密哪一層解密。
  • java的優先順序佇列,如果讓你設計一個資料結構實現優先順序佇列如何做?
  • 用TreeMap複雜度太高,有沒有更好的方法。
    hash方法,但是佇列不是定長的,如果改變了大小要rehash代價太大,還有什麼方法?
  • 用堆實現,那每次get put複雜度是多少(lgN)
    (思想就是並不一定要按優先順序排佇列的所有物件,複雜度太高,但每次保證能取最大的就行,剩下的順序不用保證,用堆調整最為合適)
  • 線上程式設計題:敲一個字串匹配問題,寫了常規程式碼。問kmp的程式碼思想,最後問了下正則中用的改進後的BM演算法。(還有個比較新奇的Sunday演算法,有興趣的同學也可以看一下)

3面 hr

  • 其實寫了3面,感覺根本不算面試了,就是隨便介紹了下部門,然後商量實習時間(大概補招都這樣吧)。因為已經決定去滴滴新銳了,就跟她說可能暑期不能實習,然後說可以秋招再聯絡。
  • 另外美團這家要跟師弟師妹們說一聲,投簡歷一定還是要選事業群的,千萬不要選都喜歡,否則就算過了筆試,也會像我這樣等兩個月大概是補招才會聯絡到你。

寫在最後

其實大家可以從這個過程中看出來,隨著時間的推進,自己的知識儲備和各方面的經驗和能力都是上升的。

總結幾句:

  • 對自己要有個定位
  • 準備永遠都不嫌早不嫌多
  • 心態差了及時調整
  • 面試掛了及時總結
  • 這麼多年也該逼自己一把了

一兩次甚至一系列的失敗並不可拍,成功之後反而沒有失敗總結得透徹,收穫的多。失敗的經歷會讓你不斷提升能力,成功的經歷會讓你不斷提升信心。而不管成功失敗都會提升你的經驗,都會有收穫。

所以不要害怕失敗,因為早晚會成功。

願大家都能擁有滿意的結局。

文章出處

作者:XiaoTeng
連結:
https://www.nowcoder.com/discuss/29890
已與作者進行私信聯絡,任何人轉載此篇文章,文章出處這一欄都不可以刪除。

公眾號作者喬戈裡親歷2019秋招,哈工大計算機本碩,百度准入職java工程師,歡迎大家關注我的微信公眾號:程式設計師喬戈裡,公眾號有3T程式設計資源,以及我和我朋友(准入職百度C++工程師)在秋招期間整理的近200M的面試必考的java與C++面經,並有每天一道leetcode打卡群與技術交流群,歡迎關注。

相關文章