前言
由於個人發展的原因和工作上的變動,產生了想出來看看機會的想法。經過了一段時間的准備,5 月下旬開始出來面試,面到了 7 月上旬,如願拿到了自己心儀公司的 offer。按照自己的習慣,將這次面試過程中的一些經驗總結、心得體會記錄下來,自己留個記錄,也希望可以幫助到一些同學。
另外,在兩年前第一次跳槽的時候也將當時的心得體會記錄了下來,這邊放個傳送門:兩年Java開發工作經驗面試總結
個人情況
坐標魔都,15 年本科畢業於普通一本,畢業后就職於一家傳統電信公司,17 年后就職於美團點評。
面試情況
相比於 17 年,由於有了美團的背景,今年在簡歷這關順利了很多,不得不感嘆大廠背景真香🙈。
本着盡量少請假的原因,所以面試的公司比較少,只面了 3 家:阿里、網易、拼多多。
3 家公司都走完了面試流程,最后拿到了阿里和拼多多的 offer,自己還是比較滿意的。
至於網易掛掉的原因,具體原因不是很清楚,面試發揮的還行,BOSS 面的時候可以看出對我還是比較滿意,但最終沒有收到 offer。
如果對於這三家公司的面試流程有問題的,可以在公眾號上留言,能解答的我會第一時間解答。
4 年經驗應該具備哪些技能
首先,簡單的聊一下我認為的 4 年經驗左右、優秀的 Java 程序員應該具備的技能有哪些,按“專業技能”和“項目”兩塊,包括但不限於以下內容。
專業節能方面
- 基礎:JDK 常用類的原理、源碼、使用場景。
- 設計模式:常用幾種的原理、使用場景,單例、動態代理、模板、責任鏈等。
- 數據結構:數組、鏈表、棧、隊列、樹。
- 網絡:TCP、HTTP、HTTPS、負載均衡算法。
- 框架:Spring IoC 原理、Spring AOP 原理和使用、Spring 常用的擴展點、MyBatis 的核心流程。
- 中間件:常用中間件的核心原理與最佳實踐,並對其中的 1 到 2 個有深入的學習,Redis、Kafka(RocketMQ、RabbitMQ)、Dubbo、Zookeeper。
- 數據庫(MySQL):索引原理、隔離級別、鎖機制、分庫分表、慢 SQL 定位及優化、線上問題解決。
- Netty:NIO 原理、核心組件、I/O 多路復用(epoll)、零拷貝。
- JVM:運行時數據區、垃圾回收算法、垃圾回收器(CMS、G1)、常用配置參數、線上問題定位及解決。
- 穩定性保障:隔離、限流、熔斷、降級等。
- Linux:基本命令的使用、快速定位和排查問題。
- 分布式理論:CAP、BASE、2PC、3PC、TCC。
項目方面
- 能獨立完成一個復雜模塊的需求分析、方案設計和最終落地實現。
- 能不斷思考,尋找更優的設計和解決方案,積極優化慢 SQL、慢服務。
- 具備排查問題的能力,遇到線上問題能及時定位和修復上線,例如:數據庫死鎖、服務器宕機、服務器 Full GC 頻繁等。
- 具備難題攻關的能力,能不斷解決項目遇到的挑戰,能給予初級工程師技術上的指導。
- 初步具備帶領團隊(1-3人左右)的能力,能合理分配需求,做好進度把控、風險評估、Code Review。
嚴格來說,要完全做到上面這些有點難,我自己也並不具備,但是,我們可以將其視為目標,不斷去努力。
面試常見形式
大廠面試通常是“連環炮”的形式,舉個栗子:
面試官:用過哪些 Map
我:LinkedHashMap、ConcurrentHashMap、HashMap、TreeMap
面試官:這四種 Map 的區別
我:ConcurrentHashMap 線程安全,LinkedHashMap 可以記錄插入順序和訪問順序,TreeMap 可以自定義排序,除了這幾個場景,其他場景基本都可以使用 HashMap
面試官:ConcurrentHashMap 怎么保證線程安全
我:JDK 1.8 以前通過分段鎖,JDK 1.8 以后通過 CAS + Synchronized
面試官:ConcurrentHashMap 在 JDK 1.8 前后的鎖有什么區別
我:JDK 1.8 以前鎖分段,JDK 1.8 以后鎖單個節點,鎖粒度降低,並發度變高
面試官:#%¥%……#%¥
我:喵喵喵~
這種模式的問法,其實就是想了解候選人對一個知識點的理解是僅僅停留在表面,還是真的去深入研究過。
面試內容
下面介紹下一些常見的面試內容,其中的面試題不一定是我真實遇到的,有可能是從別人的面試題中收集的,也有可能是我自己覺得重要的知識點,僅供參考。
1、項目
項目對於一個 3 - 5 年經驗的開發來說是非常重要的,面試官也非常看重這一塊。這個經驗的開發基本是各大公司的編碼主力,因此面試這個年限的候選人,通常項目是很重要的一塊。面試官通常會讓你先自己介紹下自己參與度最高(或者最牛逼)的項目,然后從中進行提問。常見的如以下:
- 介紹下你參與度最高的項目
- 畫下項目的架構圖
- 如果核心流程處理到一半,服務器崩潰了,會怎么處理
- 項目中遇到過哪些挑戰或問題,怎么解決的
- 項目的穩定性和可用性怎么保障
- 數據安全這塊怎么設計
- 項目的技術選型,為什么選這些
- ...
2、場景題
越到后面的面試官,越喜歡問場景題,場景題比較考驗候選人平時的積累和解決問題能力。這個環節很容易掛掉一批人,特別是容易緊張的同學,很容易腦子會一片空白。場景題的核心一般是處理大數據量的問題、解決性能方面的問題。
場景題本質上是比較開放的,沒有什么標准答案,只要自己的方案能夠解決問題,能夠“自圓其說”就行。
這個環節面試官可能會將線上真實的場景拿出來提問,我自己就遇到過。
3、專業技能
集合
- 經常用到哪些 Map
- 這幾種 Map 的區別
- CocurrentHashMap 怎么保證線程安全
- CocurrentHashMap 在 JDK 1.8 前后的鎖有什么區別
- 聊下 HashMap 的原理
- HashMap 在 Put 時,新鏈表節點是放在頭部還是尾部
- HashMap 擴容時的流程
- HashMap 在 JDK 1.8 有什么改變
- CocurrentHashMap 在 JDK 1.8 有什么改變
- TreeMap 的原理
- Map、List、Set 分別說下你知道的線程安全類和線程不安全的類
多線程、鎖
- 線程池使用的是哪種
- 線程池參數怎么配置
- 線程池各個參數的作用
- 線程池的參數配置要注意什么
- 線程池的工作流程
- JDK 中的並發類知道哪些
- AQS 的底層原理
- 介紹下悲觀鎖和樂觀鎖
- 使用過哪些鎖
- synchronized 和 Lock 的區別、使用場景
- synchronized 原理
- synchronized 作用於靜態方法、普通方法、this、Lock.class 的區別
- 為什么引入偏向鎖、輕量級鎖,介紹下升級流程
- 死鎖的必要條件,如何預防死鎖
- 介紹下 CountDownLatch 和 CyclicBarrier
- 介紹下 CAS,存在什么問題
- 介紹下 ThreadLocal,存在什么問題
網絡
- HTTPS 是怎么加密的
- 普通 Hash 和一致性 Hash 原理
- 一致性 Hash 的缺點
- TCP 三次握手過程,為什么需要三次握手
- 為什么 TIME_WAIT 狀態需要經過 2MSL 才能返回到 CLOSE 狀態
- TCP 的擁塞控制
- TCP 如何解決流控、亂序、丟包問題
- 為什么會出現粘包和拆包,如何解決
Spring、Mybatis
- Mybatis 中 # 和 $ 的區別
- 怎么防止 SQL 注入
- 使用 Mybatis 時,調用 DAO(Mapper)接口時是怎么調用到 SQL 的
- 介紹下 Spring IoC 的流程
- BeanFactory 和 FactoryBean 的區別
- Spring 的 AOP 是怎么實現的
- Spring 的事務傳播行為有哪些,講下嵌套事務
- 什么情況下對象不能被代理
- Spring 怎么解決循環依賴的問題
- 要在 Spring IoC 容器構建完畢之后執行一些邏輯,怎么實現
- @Resource 和 @Autowire 的區別
- @Autowire 怎么使用名稱來注入
- bean 的 init-method 屬性指定的方法里用到了其他 bean 實例,會有問題嗎
- @PostConstruct 修飾的方法里用到了其他 bean 實例,會有問題嗎
- Spring 中,有兩個 id 相同的 bean,會報錯嗎,如果會報錯,在哪個階段報錯
- Spring 中,bean 的 class 屬性指定了一個不存在的 class,會報錯嗎,如果會報錯,在哪個階段
- Spring 中的常見擴展點有哪些
MySQL
- MySQL 索引的數據結構
- 為什么使用 B+ 樹,與其他索引相比有什么優點
- 各種索引之間的區別
- B+ 樹在進行范圍查找時怎么處理
- MySQL 索引葉子節點存放的是什么
- 聯合索引(復合索引)的底層實現
- MySQL 如何鎖住一行數據
- SELECT 語句能加互斥鎖嗎
- 多個事務同時對一行數據進行 SELECT FOR UPDATE 會阻塞還是異常
- MySQL 使用的版本和執行引擎
- MySQL 不同執行引擎的區別
- MySQL 的事務隔離級別
- MySQL 的可重復讀是怎么實現的
- MySQL 是否會出現幻讀
- MySQL 的 gap 鎖
- MySQL 的主從同步原理
- 分庫分表的實現方案
- 分布式唯一 ID 方案
- 如何優化慢查詢
- explain 中每個字段的意思
- explain 中的 type 字段有哪些常見的值
- explain 中你通常關注哪些字段,為什么
JVM
- 運行時數據區
- 服務器使用的什么垃圾收集器
- CMS 垃圾收集的原理
- G1 垃圾收集的特點,為什么低延遲
- 有哪些垃圾回收算法,優缺點
- 哪些對象可以作為 GC Roots
- 有哪些類加載器
- 雙親委派模式,哪些場景是打破雙親委派模式
- 線上服務器出現頻繁 Full GC,怎么排查
- 定位問題常用哪些命令
- 介紹下 JVM 調優的過程
Kafka
- 為什么使用 Kafka
- 介紹下 Kafka 的各個組件
- 如何保證寫入 Kafka 的數據不丟失
- 如何保證從 Kafka 消費的數據不丟失
- Kafka 為什么性能這么高
- 零拷貝技術使用哪個方法實現
- Java 中也有類似的零拷貝技術,是哪個方法
- Kafka 怎么保證消息的順序消費
- Kafka 怎么避免重復消費
- 什么是 HighWatermark 和 LEO
- 什么是 ISR,為什么需要引入 ISR
Redis
- 項目中使用的 Redis 版本
- Redis 在項目中的使用場景
- Redis 怎么保證高可用
- Redis 的選舉流程
- Redis 和 Memcache 的區別
- Redis 的集群模式
- Redis 集群要增加分片,槽的遷移怎么保證無損
- Redis 分布式鎖的實現
- Redis 刪除過期鍵的策略
- Redis 的內存淘汰策略
- Redis 的 Hash 對象底層結構
- Redis 中 Hash 對象的擴容流程
- Redis 的 Hash 對象的擴容流程在數據量大的時候會有什么問題嗎
- Redis 的持久化機制有哪幾種
- RDB 和 AOF 的實現原理、優缺點
- AOF 重寫的過程
- 哨兵模式的原理
- 使用緩存時,先操作數據庫還是先操作緩存
- 為什么是讓緩存失效,而不是更新緩存
- 緩存穿透、緩存擊穿、緩存雪崩
- 更新緩存的幾種設計模式
Zookeeper
- Zookeeper 的使用場景
- Zookeeper 怎么實現分布式鎖
- Zookeeper 怎么保證數據的一致性
- ZAB 協議的原理
- Zookeeper 遵循 CAP 中的哪些
- Zookeeper 和 Eureka 的區別
- Zookeeper 的 Leader 選舉
- Observer 的作用
- Leader 發送了 commit 消息,但是所有的 follower 都沒有收到這條消息,Leader 就掛了,后續會怎么處理
分布式
- CAP 理論
- BASE 理論
- 分布式事務 2PC 和 TCC 的原理
- TCC 在 cancel 階段如果出現失敗怎么處理
- Paxos 算法、Raft 算法
4、Hr 面
如果你一路過五關斬六將,最終來到了 Hr 面,那么恭喜你,你已經離 offer 非常非常近了。可以開始暢想自己升職加薪,當上總經理,出任 CEO,迎娶白富美,走上人生巔峰的場景了。
Hr 面主要是了解候選人的一些通用素質,經常會問的問題如下:
- 介紹下自己投入最多的項目(當時我就驚了,Hr 也開始問項目了)
- 離職的原因
- 當前的薪資、績效
- 當前在面試的其他公司的情況
- 平時有沒有學習的習慣,怎么學習的,現在在學習什么
- 未來的規划
關於這些問題,沒有什么標准答案,但是很重要的原則是,在整個過程中要保持積極向上的態度,不能有負面的情緒。
關於當前薪資的問題,由於諸多的原因,可能有些人會想着稍微多報一點,對於這種做法我持中立態度,但是要把握好度,畢竟大廠基本都有背景調查。大廠對於誠信問題一般是零容忍,而且可能會拉黑名單,進黑名單意味着你再也無緣這家公司了。
一些經驗心得
- 先挑幾個小公司找下面試感覺,太久沒面,需要找找面試的感覺,我自己一開始就面的不太好,就很慌張🙈。
- 面試時緊張是正常的,但是不要過於緊張,如果面試官問完你大腦瞬間一片空白,你可以跟面試官說自己要思考下,然后回答的時候語速可以慢點,但是要條理清晰。
- 在面試的過程中回答面試官問題是一方面;另一方面,你要在回答的過程中讓面試官感受到你身上一些優秀的特質,例如:有潛力、很靈活、熱愛學習、學習能力強、解決問題能力強、基礎扎實等等。這些特質都會影響面試官對你的評價。
- 平時項目中遇到難題要積極去解決,解決問題的過程能讓人快速成長,並且解決的問題可能會成為你面試時的亮點,特別是對於那些項目沒什么亮點的。
- 准備項目時,挑幾個自己做過最牛逼的功能、或者解決過最有挑戰的問題,並且要對這些內容理解的非常透徹,不能在給面試官介紹的時候“支支吾吾”。
- 框架也好、中間件也好,必須要有幾個特別深入研究過的,也就是說你除了“廣度”之外,還必須在某些方面有足夠的“深度”。面試時經常碰到的問題是:你對哪個框架或中間件理解的最深。然后面試官會在這個方向上一直問下去,如果你很多東西只是看了個大概,在這邊就很有可能會被問倒。
- 自己講出來的每個功能點、知識點,都要做好“被挑戰”的心里准備,因此對於每個功能點、知識點都要多思考。
- 如果問的問題是線上實際的場景,有時候面試官會給出他們當前線上的解決方案,如果你能在這個時候給出一些自己的思考和觀點,可能會給面試官留下不錯的印象。
- 判斷自己是否已經准備好的一個比較簡單粗暴的方法:自己是否能將看到的面試題回答個 9 成左右,例如本文上面“專業技能”列舉的這些題目。
- 如果你是真想跳槽,或者說你已經裸辭了,那么在收到電子 offer 前都不要停止面試,即使收到口頭 offer 也不穩,特別是在這個寒冬。
- 在平時工作中多思考,無論是寫代碼還是方案設計,多思考更優的解決方案。特別是工作年限越久之后,思考對於我們的職業發展越重要。
- 面試前的准備非常重要,但更重要的是平時工作的積累,4 年經驗問的問題很多是無法通過臨時准備的,很多都是需要你不斷去積累,才能有好的方案。
- 專注於自身的成長,不要輕易受到別人的影響,只要你不斷的積累,總有一天你也能成為你眼中的那些大神。
- 學如逆水行舟,不進則退。不要停下學習的腳步,特別是趁着自己還年輕,趁着自己還是個單身狗的時候,逼自己一把,將來的你一定會感激現在拼命的自己。
- 程序員是一份很單純的工作,不需要搞什么花里胡哨的,只要你付出努力了,你通常就能收獲回報。
- 對於沒有大廠背景,並且處於傳統行業(就如 2 年前的我),想直接進入大廠比較難,除非你像我一樣踩了狗屎運,但是這種幾率不大,我覺得比較現實的途徑是先找一個互聯網獨角獸沉淀一段時間。
- 大公司的部門非常多,各部門的招聘通常都是獨立的,如果想進大公司可以多投,每個部門的需求緊張度不同,如果碰到急需招人的,可能就是一個非常好的機會。
- 大公司的面試通常會有存檔,面試官可能會看到你之前的面試評價。如果你經常一輪游,肯定會給面試官不好的印象。因此請做好准備再去面試,不要輕易浪費機會。
- 2019 年互聯網行業的行情不太好,也有可能接下去會一直這樣,特別是對於沒有大廠背景的同學來說,所以請記住一個很重要的原則:不要裸辭。
- Last but not least,如果你覺得本文對你有幫助,歡迎關注我的微信公眾號、右下角“在看”、分享到朋友圈,幫助更多的小伙伴。