既然是要談如何進入BAT,那麼我們就從面試的角度來談學習這件事,會談談一流互聯網公司對於Java後端程序員的要求,相應的,也會談談如何達到這樣的要求。 爲了簡單起見,這些要求分爲三個層次,分別爲基本要求、可選要求以及加分要求,接下來,我們就一個一個的來談一談。 1、基本要求 基本要求就是指,你必需要學會的知識,並且這裏面大部份內容,在面試裏出現的機率都是極高的。所以,這部份內容你沒有選擇,只能選擇啃下它,你能夠花一年,也能夠花十年,或者帶到棺材裏學習也能夠。 1)語言的基礎部分: 基本要求的第一個,固然是語言的基礎部分。基礎部分其實就是語法以及一些關鍵字的做用,像一些if/else、for循環這類基礎的語法,以及一些new、class、public這類的基礎關鍵字,大部分狀況下面試問的是比較少的,由於這部份內容,只要你寫過幾年Java,基本上都沒有什麼問題。 那麼基礎部分的重點,其實主要就是static、final、transient、volatile這一類的關鍵字,以及內部類、泛型這一類的高階語法。 說到static,首先要記住的最重要的一點就是,類屬性中被static所引用的變量,會被做爲GC的root根節點。做爲根節點就意味着,這一類變量是基本上不會被回收的。所以,static很容易引入內存泄漏的風險。 若是一個面試官讓你解釋static關鍵字,你告訴他static能夠修飾屬性、方法和內部類,以及修飾以後又有什麼效果的話,那麼面試官基本上不會記住你這個回答,整個印象就是平庸。 可是若是你說完之後,補充一下說道,你曾經遇到過一個內存泄漏的問題,就是由於static修飾的一個Map類型的變量致使的,最後排查了堆棧信息找到了問題的所在,而且解決了這個問題。那麼,面試官這個時候心裏中對你的印象,就會不天然的提高几分。 並且,對於static,更深刻的理解是,static會將所引用的屬性、方法以及內部類,與類直接產生引用關係,而非與類的實例。這就是爲何,你可使用類名.屬性、類名.方法以及類名.內部類名,來直接引用一個被static所修飾的屬性、方法或者內部類。 若是你沒有用static修飾,那麼你就必須使用實例才能引用這些方法、屬性或者是內部類,最典型的就是內部類。相信不少同窗都好奇過,爲何一個沒有被static修飾的內部類,必需要這麼聲明。 由於你沒有使用static修飾InnerClass,因此你必須new出來一個OutterClass的實例,才能在此基礎上new出內部類的實例,由於內部類只能經過外部類的實例才能引用。若是你使用了static修飾,那麼你就能夠這樣使用內部類。 這兩種方式最大的區別就是,第一種方式,若是你想要得到InnerClass的實例,你必須有一個OutterClass的實例,全部其實這種方式你建立了兩個實例,因此有兩個new關鍵字。而第二種方式就好理解一些,靜態內部類不依賴於外部類的實例存在,所以只須要直接建立內部類的實例就能夠了,因此只有一個new關鍵字。 static說的有點多了,不過其實不光說了static關鍵字,也一塊兒連同內部類的語法也大體都說了下。那麼接下來,基礎部分還有一個比較考驗人的東西,就是volatile關鍵字。 這個關鍵字的重點就三個字,就是可見性。可是面試的時候,你說出可見性三個字,基本上滿分100的話,最多隻能獲得20分。剩下的那80分,就要靠你用硬功夫去得到了。 所謂的硬功夫,其實就是要整明白,在併發當中,可見性究竟是什麼意思。那麼,爲了弄明白可見性什麼意思,就須要你瞭解什麼叫主存和工做內存。 只有把這些概念都搞明白了,你纔會知道volatile的真正做用究竟是什麼。不過有一點要提醒你的是,volatile並不保證同步,這一點必定要記住。不光是應付面試官,在真正使用volatile的時候,也要注意這一點,不然很容易出現問題。 好了,基礎部分就說這麼多吧,挑了一些有表明性的說了下,歸根結底,這一部分就是要你很是清晰的瞭解Java當中的關鍵字和語法,這裏所謂的瞭解,是清晰的瞭解其實現原理,而非簡單的會用而已。 2)Java運行時環境 Java運行時環境就是JRE的中文翻譯,本質上其實就是指JVM。 首先對於JVM必需要知道的是,JVM與Hotspot的關係。JVM更多的是指JVM規範,而Hotspot是JVM的一種實現,也是咱們最經常使用的JVM實現。你能夠把JVM規範當作接口,Hotspot當作實現類,這樣去理解會比較簡單一些。 此外,JVM最重要的三個部分必需要很是清楚,內存劃分、class加載機制以及GC策略。搞清楚這三部分不只僅是爲了面試,也是爲了讓你對於Java有更深入的理解,這對於你的Java生涯很是有幫助。 並且,關於內存劃分,還有一點要注意,我們常說的劃分方式,實際上是指的Hotspot的劃分方式,而非JVM規範所規定的。 Hotspot的內存劃分簡單說分爲三個部分,Young Generation(年輕代)、Old Generation(年老代)以及Perm Generation(永久代)。其中的Young Generation(年輕代),又分爲Eden、From和To,其中From和To又統稱爲Survivor Spaces(倖存區)。 正常狀況下,一個對象從建立到銷燬,應該是從Eden,而後到Survivor Spaces(倖存區),再到Old Generation(年老代),最後在某次GC下消失。 固然,一個對象也可能直接在Eden裏死掉,也可能一直在Old Generation(年老代)存活,這些都是有可能的。 關於內存劃分,能夠本身沒事用內存分析工具看看,好比jmap、jvisualvm等等,觀察一下各個區域的內存變化,結合實際去了解一下。 關於classloader機制的學習,能夠結合tomcat去學習,瞭解清楚tomcat的classloader機制,看tomcat是如何保證各個APP之間的類隔離的。若是可能的話,看一下tomcat中classloader的源碼,或者看一下開源項目niubi-job,當中也包含了與tomcat類加載機制類似的部分。 至於GC,須要清楚GC Roots都有哪些,以及如何判斷一個對象能夠被回收。此外,GC的算法和策略也要有大概的瞭解。 3)併發知識與concurrent包 要想進入一線互聯網公司,這部份內容必需要會,不然的話,你始終都只能停留在比較low的段位。 關於併發知識,最重要的兩個概念必定要搞清楚,那就是可見性和原子性。其中可見性與前面提到的volatile關鍵字是息息相關的,可見性只是併發領域裏的一個概念,而volatile則是Java語言中,實實在在保證變量可見性的關鍵字。 前面說了,要弄清楚可見性,就須要搞清楚主存和工做內存。關於主存和工做內存,其實又屬於JVM的知識範疇。因此從這裏就能夠看出來,知識都是有關聯性的。 原子性其實相對於可見性來講,反倒更好理解一些,相信那個萬年不變的銀行匯款的關於事務的例子,就足以大部分人理解原子性這個概念了,它其實就是一個或多個操做,被視做一個總體的意思。 有了併發的基礎知識之後,你就須要研究一下concurrent包了。這裏面的東西實際上是一個寶藏,一旦你須要寫併發相關的功能,你會發現這裏面的東西很是實用。 其中ConcurrentHashMap是面試最容易被問到的一個類,幾乎全部的面試都會問你,ConcurrentHashMap和普通的同步HashMap有什麼區別。 這個問題其實須要你知道兩個知識就能夠了,一個是HashMap的數據結構,一個是鎖分段的技術,具體的這裏就不解釋了,你們本身下去找相關資料看吧。 此外,concurrent包裏有一個很是重要的類,叫作AbstractQueuedSynchronizer,幾乎全部的concurrent包內的併發工具類,都是基於這個抽象類擴展出來的。所以,把AbstractQueuedSynchronizer這個類研究透徹,很是有助於你理解concurrent包。 最後一點,面試的時候還常常會被問到的一個問題,就是ReentrantLock和synchronized關鍵字有什麼區別。 這個問題不少人都答不上來,這隻能說明一個問題,那就是大部分人在用synchronized和ReentrantLock的時候,並不會考慮這二者到底用哪一個好一些。 其實它們的區別很簡單,簡單的說,就是synchronized因爲是底層JVM實現的互斥,所以效率會高一些。而ReentrantLock的功能則比synchronized更多,好比定時獲取某個鎖,多個等待條件等。 併發這一部分是一個程序員進階的重要部分,但願全部Java程序員均可以重視這一部分。 4)設計模式和反射 設計模式和反射這部份內容,我的以爲是一個高階程序員必須精通的部分。 用好了這部分知識,可讓你在實際開發中少寫N多代碼,並且還可使得程序的結構更加良好。 關於反射,其實就是reflect包裏的內容,這個包裏的類其實並不難,主要是得多用,多看。好比Java領域裏最經常使用的spring框架,裏面其實大量充斥着設計模式和反射的真實使用場景,沒事多研究一下,絕對讓你受益不淺。 5)文件IO、NIO、網絡IO以及網絡協議 文件IO、NIO以及網絡IO這一部分也是工做當中要常常用到的部分,所以也必需要掌握。 其中NIO更多的是瞭解其原理,此外,tomcat中有多種協議的實現,其中包括了BIO、NIO和APR,這三者必定很是清楚它們的區別,這個能夠在connector的protocol屬性配置。 至於網絡IO部分,其實就是net包裏的內容。這裏面的內容是很是經常使用的東西,好比你調用HTTP-API,那麼就須要使用這裏面的類。在這個restful-API氾濫的時代,你少不了要使用HTTP協議調用API。 此外,在瞭解這部分的時候,網絡協議也要適當的瞭解一下,最典型的TCP和HTTP協議是必定要了解的。 參加的面試中,基本上TCP協議是必定會問的,雖然這可能和LZ的簡歷寫了TCP協議有關,但好比TCP協議的重試機制,三次握手的過程,TCP與UDP的區別這一類的知識,仍是要了解一下的。 至於HTTP協議,相對來講就簡單不少了,應用層的協議主要是知道其協議格式便可,好比都支持哪些header、每一個header都是什麼含義等等。 6)小結 好了,到此爲止,基本要求就差很少介紹完了。 沒錯,其實基本要求這部分,差很少就是要求你有紮實的Java基礎。這也是全部一線互聯網公司,基本都會寫在招聘要求地前幾條的要求。 所以,要想進入BAT,那麼這一部分的內容必定要了解,並且這部分的內容對你實際開發也是很是有幫助的,並不只僅是爲了應付面試。 2、可選要求 看到可選要求四個字,或許很多人會認爲這部分不過重要。可是我能夠很負責的告訴你,這部分每每纔是決定公司要不要你的重要指標。 由於基本要求達標之後,公司主要挑選人才的標準其實就是可選要求這一部分,其實這一部分就是差別性的體現。 此外,要提早說明的是,這些可選要求,沒有必須會和必須不會的內容,儘量多的瞭解,老是不會錯的。 1)Spring、Mybatis框架 框架這部分其實不用多說了,spring和mybatis框架的原理和源碼,若是你能夠很是精通的話,那麼這必定能成爲你巨大的優點。 若是你是專門作WEB開發的Java後端猿,那麼spring和mybatis框架基本上你是確定要用的。精通Spring和mybatis框架不只爲了面試,對於你平常開發也有巨大的幫助,你能夠作不少架構上的優化,爲你的戰友省去不少重複性的工做。 關於Spring框架,最核心的固然是IOC,其次即是AOP、MVC這兩部分了。好好研究這三部分的源碼,會讓你從大部分程序員當中,脫穎而出。至於mybatis框架,主要仍是關注它如何實現動態SQL。 並且,待你研究透徹之後,你徹底能夠本身嘗試去造輪子,說不定能獲得意想不到的收穫。 2)Linux服務器 這一部分其實本來是運維應該精通的部分,可是做爲一個Java後端猿,若是你能夠精通linux服務器,那麼對你排查線上問題,是有很大的幫助的。 大部分程序員都只知道一些經常使用的Linux命令,對於Linux系統自己的文件系統、網絡以及IO等等,是徹底不瞭解的,這其實也包括LZ本身。可是,LZ見過身邊有一些程序員,對於Linux玩的很是熟練,這不光光體如今多會幾個命令,而是對整個Linux系統的瞭解。 能夠預見的是,這些人在排查問題的時候,每每會更容易找到問題的根本。由於程序問題每每並非最難解決的,異常這東西見多了就都知道怎麼回事了,大不了看看源碼也總能找到緣由。最難解決的是環境問題,而環境問題無非就是操做系統層面的問題。 而顯然大部分狀況下,Java運行的操做系統都是Linux。 3)數據庫優化 說完Linux,緊接着LZ要說的就是數據庫了,這本來應該是DBA應該精通的部分,但做爲一個Java後端猿,數據庫基本上也是最常常打交道的了。 並且你們都知道,一個應用的性能瓶頸,每每都出如今數據庫這一端,所以,一個Java後端猿若是能夠精通數據庫的話,那麼對於你工做的實際幫助,也是很是大的。 相信很多人都碰到過SQL過慢的狀況,這個時候,如何經過加索引、SQL分析和優化的手段,將SQL的執行時間優化到一個可接受的範圍內,其實仍是比較考驗人的。 反正,這玩意兒我是半斤八兩的水平,基本的優化是沒有問題的,但稍微複雜一些的就不行了。 因此,這一部分足夠成爲你的優點,體現出你的差別性。 4)消息服務 除了Linux和數據庫之外,消息服務也是當今互聯網公司裏,必不可少的一個組件。 常見的消息組件好比rabbitMQ、activeMq,包括一些其它的開源消息組件,好比rocketMq。這裏面任何一個,若是你能夠精通其原理的話,也會成爲你有力的競爭條件。 其實消息服務的重點,無非就是如何保證最終一致性、消息的順序,包括消息事務等等這一類的問題。 雖然本人對此不是很瞭解,但LZ很肯定,這一部分若是你能夠有本身獨到的看法的話,必定會大大增長你的成功率。 5)緩存服務 說了消息服務之後,相信緩存服務你們也必定不陌生了。 常見的緩存好比memcached、redis這兩個,若是你能搞清楚其中一個的話,也會給你加分許多。畢竟如今的互聯網應用,緩存也是必不可少的了,所以若是你能徹底hold住緩存這一部分,那麼你的差別性也就有了。 在緩存服務當中,有幾個問題也是比較常見的,好比緩存滿了怎麼辦,緩存的實時性如何處理,內存結構如何規劃,分佈式的狀況下如何處理增刪節點時緩存的命中問題等等。 6)負載均衡器 負載均衡器,這是最後一個可選要求了。 常見的負載均衡器就兩種,一種是軟負載均衡,好比nginx、Apache、lvs這一類的。另一種則是硬件負載均衡,常見的主要就是F5。 這兩種方式各有優劣,其中硬件負載均衡如要用於簡單應用、大訪問量的場景,而軟件複雜均衡則主要用於複雜應用,較小訪問量的場景。固然了,二者還有一個不得不考慮的區別是,硬件複雜均衡通常都是很是貴的,而軟負載均衡則基本上沒有任何成本。 在負載均衡器方面,也有一些問題是比較常見的。好比如何保持會話,如何作流量控制,負載均衡策略都有哪幾種,如何檢查後端服務器的健康狀態等等。 7)小結 好了,到這裏,可選要求就說的差很少了。 這6個要求其實對應的就是Java後端開發中,最常接觸到的一些東西。好比spring框架和數據庫,這二者基本上是個Java程序員都接觸過吧。 其他四個包括Linux服務器、消息服務、緩存服務以及負載均衡器,也是同樣的,你們在實際工做當中,應該或多或少都接觸過這幾個東西。 可是真正能對其中一個很是瞭解精通的人,相信並不會太多。也正由於如此,若是你作到了,才能夠體現出你的差別性,這或許會是你拿下offer的重要籌碼之一。 可是,這裏必需要再強調一下的是,這幾樣東西大多數人或多或少都會有一些瞭解,包括上面提到的問題,很多人也都知道答案。 然而,光知道答案是遠遠不夠的,這並不足以成爲你的優點,你須要對這些問題有着深入的瞭解,以及有着本身獨特的看法,才足以讓它成爲你的優點。 3、加分要求 最後一個即是加分要求了,加分要求雖然不如基本要求和可選要求重要,但它也與可選要求相似,每每拿下offer的最終緣由,正是這些看似不是必要要求的部分。 要強調的是,這些加分要求中,在某些特殊狀況下,可能會成爲基本要求。 1)數據結構與算法 這一部份內容不用多說了,你們都懂的。精通數據結構與算法,絕對會成爲你的一大亮點。 由於大部分程序員的這一部分基礎都不太好,包括本人,面試的時候若是問到算法一類的問題,基本上就兩個字:不會。 之前還看過Java集合框架的一些源碼,對於一些經常使用的數據結構還有必定的瞭解。可是如今,已經基本上忘光了,就連最基本的冒泡排序,可能都不必定能寫的對。 所以能夠預見的是,數據結構與算法絕對是很是加分的一項。並且,在你面試一些與算法相關的職位時,這個加分要求還可能會成爲基本要求。 2)計算機操做系統 計算機操做系統原理,是很是底層的內容。 這部份內容比較難,裏面講的都是一些最基本的底層原理,例如內存、指令、系統IO等等。以前也研讀過一本關於操做系統的書,也寫了一系列文章,地址是http://www.cnblogs.com/zuoxiaolong/category/518480.html。 不過看的仍是不夠全面和深刻,若是你能夠將操做系統研究透徹的話,那麼在面試的時候,你徹底能夠以此做爲突破點,展現你的亮點。 3)計算機網絡 其實網絡這一部分,對於程序員來講仍是比較重要的。 最近正在作的事情,就常常會碰到一些網絡上的問題,雖然不少時候,這些問題其實能夠找專門的網絡人員去解決,但若是你本身對此不夠了解的話,對於你的工做仍是會形成很大的障礙。 並且,要想精通TCP/IP協議,若是對計算機網絡不瞭解的話,仍是很難真正理解的。 所以,計算機網絡部分若是你能夠精通的話,這也絕對會成爲你的一個加分項。 4)熟練使用一種腳本語言 腳本語言在不少時候是很方便的,並且也很是實用。 最近就被迫正在使用Python作不少事情,其實用了之後你會發現,雖然Java也能夠實現一樣的目的,但確實選擇合適的語言,會幫你節省大量的精力。 所以,若是你能夠熟練使用一種腳本語言,好比Python、shell等等,這也一定會成爲你的加分項。 5)你的github和博客 這點相信大部分人也都知道,若是你擁有本身的github和博客,而且裏面有很多有價值的內容的話,那麼必定會爲你加很多分。 此外,就不說面試這回事,平時在github寫寫代碼,在博客裏寫寫文章,總結總結本身的技術和職場,也是很是有好處的。相信很多猿友都已經體會到了這其中的益處,也就再也不多說了。 畢竟說多了也無益,最主要的仍是本身要真真實實的去作,若是你但願能夠在這方面加分,那就從當前作起,而且堅持下去。 6)小結 到這裏,加分的要求就說的差很少了。 其實可以加分的內容還有不少,只不過列出了比較常見的幾種而已,好比你有其它一線互聯網公司的背景,這也是能夠加分的。只不過這種加分項比較難達到,並且,這裏更多說的是草根大學生,所以在這裏就沒多說。 著做權歸做者全部,轉載需聯繫做者以得到受權,引用需註明出處。 做者ID:專業搬磚 連接:https://www.applysquare.com/topic-cn/Rmb5fNT17/