一個合格的Java後端工程師須要掌握哪些技能呢?掃描下面的二維碼能夠看到Java後端技術概覽圖 。html
軟件開發的核心原則
此處所說的是軟件開發應該遵循的一些核心原則:java
Don't Repeat Yourself: 這是軟件開發的一個基礎原則,即不要作重複性勞動。也是如今所說的「極客文化」的一種。代碼重複、工做重複在軟件開發中都是不合理的存在。利用各類手段消除這些重複是軟件開發的一個核心工做準則。
Keep it simple stupid:即KISS原則。在作軟件設計的工做中,不少時候都不要想得過於複雜,也不要過分設計和過早優化,用最簡單且行之有效的方案也就避免了複雜方案帶來的各類額外成本。既有利於後續的維護,也利於進一步的擴展。
You Ain’t Gonna Need It: 即YAGNI原則。只須要將應用程序必需的功能包含進來,而不要試圖添加任何其餘你認爲可能須要的功能。由於在一個軟件中,每每80%的請求都花費在20%的功能上。
Done is better than perfect: 在面對一個開發任務時,最佳的一個思路就是先把東西作出來,再去迭代優化。若是一開始就面面俱到,考慮到各類細節,那麼很容易陷入牛角尖而延誤項目進度。
Choose the most suitable things: 這是在作方案選擇、技術選型時候的一個很重要的原則。在面對許多技術方案、開源實現的時候,務必作到的是不能盲目求新,要選擇最合適的而非被吹得天花亂墜的。
軟件過程
一個軟件的生命週期中,除了開發還有不少其餘步驟,也都是須要掌握的一些技術。ios
項目管理:項目管理對於一個軟件的開發是很是重要的,可以保證項目進度有條不紊地進行,在可控的時間內以必定的質量交付。瀑布開發模型、螺旋開發模型是傳統的項目管理模型。在互聯網的開發工做中,敏捷開發則是比較受推崇的開發方式。所謂敏捷開發即快速實現原型,而後快速迭代。Scrum是目前廣泛流行的敏捷開發方式之一。
測試驅動開發:在平時的開發過程當中,目前比較流行也是行之有效的一種方式就是Test Driven Develop,即測試驅動開發。此種方式的核心就是編寫單元測試。簡單來說,就是先完成某一個功能的單元測試用例,而後在逐步消除測試用例的編譯錯誤的過程當中完成功能的開發。
持續集成:某一個軟件功能完成開發以後,後續還有測試、預發佈、部署等過程。整個過程稱之爲集成,而持續集成指的是無需人工干預能夠不斷地進行這個過程。Jenkins、Quick Build都是比較典型的持續集成工具。
平常開發
平常開發指的是一些平常須要掌握的技能、工具等。算法
編輯器:開發中如今用的比較多的編輯器包括Emacs、Vim和SublimeText。筆者用的最多的就是SublimeText,基本可以知足本身的開發需求,包括編寫腳本代碼、查看代碼文件等。Vim和Emacs這兩款編輯器相對SublimeText來講須要記住不少命令,有必定的上手門檻。
源碼版本管理:代碼的版本管理工具由CVS到SVN再到如今的Git,已經在事實上造成了以分佈式版本管理爲主的版本管理方案。基於Git,能夠採用Git Flow作爲源碼管理模型。
項目工具:Github是一個第三方Git中央倉庫,目前是世界最大的開源代碼庫,也可以作爲私人的代碼管理軟件;Facebook開源的Phabrictor提供了很是強大的任務管理、Bug管理、測試、代碼管理等,但其上手門檻相對較高;禪道是國人開發的一款項目管理工具,可是其免費版功能有限;以Tower.im爲表明的第三方項目管理服務也是一個可選擇的方案,風險在於數據都再也不是私有的。
運行環境
後端應用開發完成以後是須要部署到服務器上對外提供服務的。從最開始的直接在物理機上部署服務到後來的虛擬環境、雲環境再到如今火熱的容器,直至最近興起的無服務器技術。都是爲了讓服務的運行環境可以更加便於創建、更容易維護、更容易擴展。spring
Linux: 說到後端服務器確定繞不過Linux。至少如今互聯網的後端服務絕大多數都是部署在Linux的各類服務器版本中的。其中CentOS、Ubuntu以及Debian是用的比較多的版本。對於Linux,須要熟練掌握的就是不少經常使用Shell命令如ps、netstat、lsof、ss、df、dh等等。此外,不少性能分析命令如top、vmstat、iostat、sar等也須要熟練使用。
應用服務器:就Java來說,不少時候開發的都是Web應用,以HTTP協議對外提供服務。除了對性能要求比較苛刻的狀況下會本身構建HTTP服務以外,大部分狀況是須要依賴於支持Java程序的應用服務器的。目前最爲經常使用的有:Tomcat、Jetty。嚴格來說,這二者只是Servlet容器,真正的JavaEE應用服務器如Jboss、Weblogic在互聯網領域不多使用。固然,這些軟件並無提供URL重寫、請求委託等Web服務器功能,還不足以擔當完整Web服務器的角色。Nginx則是目前最爲流行的Web服務器。
負載均衡:在高併發流量環境下,後端服務會以集羣的模式對外提供服務。在集羣的前面,須要負載均衡器將請求分配到集羣的各個結點上。LVS是最爲流行的四層負載均衡軟件,HAProxy是另外一個即支持四層又支持七層負載均衡的軟件,Nginx則是七層負載均衡最爲流行的解決方案。固然,性能最爲好的負載均衡方案是以F5爲表明的硬件負載均衡,但因爲其昂貴的成本所以在互聯網團隊中不多使用。此外,這裏須要補充的是爲了保證同等角色的服務的高可用,如LVS常常做爲流量的入口,所以會部署多個LVS結點互爲主備防止一個掛掉的時候形成服務不可用。而實現互爲主備的技術目前用的最多的就是Keepalived。
虛擬化:虛擬化技術是前幾年常常用來作私有云的一種技術。即將本身的物理主機經過虛擬化技術分裂爲多個虛擬主機,可以隔離資源。其中,VPS(虛擬專用服務器)的表明技術包括:微軟的Virtual Server、VMware的ESX Server、SWsoft的Virtuozzo。此外,OpenStack提供的構建私有IIAS的功能、Cloud Foundry提供的構建私有平臺運行環境以及Docker帶來的容器服務都是虛擬化技術的一種。
第三方服務
雖然從根本上講全部的軟件服務都是能夠本身開發的或者部署到本身服務器上的。可是受限於成本、週期或者其餘客觀因素,不少服務仍是須要使用第三方的。數據庫
IAAS:Infrastructure As A Service, 是雲計算最開始的一種模式,如今基本上全部的雲服務商都有IAAS的服務。其中,全球最強大的雲服務提供商是亞馬遜的AWS,國內的則當屬阿里雲。就目前來看,即便是強如AWS也會出現一些運維故障,所以國內的這些雲計算提供商不少時候的服務健壯性、運維響應更是常常被人吐糟。就筆者本身的經從來看。2010年左右,盛大雲的雲服務其實作的還不錯,但後來因爲種種緣由如今基本已經沒啥份額了。國內除了阿里雲,UCloud算是專一作雲計算的一個比較靠譜的公司了。此外,還有一個青雲,作的東西略顯高大上,也是一個不錯的選擇。固然,如今這些雲服務商早就不只僅是IAAS了,也作了不少PAAS的服務。
PAAS:Platform As A Service,即只須要提交代碼到指定的運行環境,其餘的諸如代碼打包、部署、IP綁定都由平臺完成。除了可使用Cloud Foundry構建本身的PAAS平臺之外,如今最爲流行的第三方PAAS服務有:新浪的SAE、百度的BAE以及Google的GAE。
域名:有個能夠提供服務的應用後,那麼域名也是一個必須的基礎設施。一個好的域名不只僅表明企業的形象,也可以更加方便用戶的記憶與傳播。目前購買域名能夠經過國外的name.com、godaddy以及國內的萬網等。有了域名以後下一步就得進行備案,域名提供商通常都提供了配套服務或者去找一些代理也能夠辦下來。此外,對於域名的解析,域名提供商通常會內置解析功能,也可使用獨立的dns服務,如dnspod。
CDN: 內容分發網絡,即就近請求的一種技術實現。服務提供方將會被大量訪問的內容在全國的多個結點都作緩存,這樣當用戶訪問時就可以就近選擇,從而減小網絡傳輸延時,提升訪問速度。國內目前七牛和又拍都提供了不錯的cdn服務,固然像阿里雲、UCloud這種綜合雲服務商也都有cdn服務。
郵件發送:這個主要須要依賴郵件服務器,而後經過SMTP協議就能夠實現發送。能夠選擇本身搭建,也能夠選擇注入騰訊郵箱、網易郵箱等。
短信發送:使用短信發送驗證碼、營銷短信是很常見的應用場景。因爲短信是須要運營商支持的,因此這一塊基本上都是須要依賴第三方代理的。市面上也有不少短信網關代理。
消息推送:在移動應用上,推送已經成爲一個標配功能。目前個推應該是第三方推送服務中的佼佼者,並且因爲其客戶不少,在聯盟喚醒上有很大的優點。
開放平臺:經過開放平臺,可使用OAuth等協議獲取用戶在第三方平臺上的信息實現第三方平臺登陸等。目前,微博、微信、QQ是最多見的第三方登陸方式,基本上都是使用OAuth協議爲第三方開發者提供服務的。
支付接口:支付接口是不少內置購買功能軟件的必備組件。目前,接入最多的無非是支付寶和微信,都提供了開放平臺供商家接入。固然,也有直接綁定銀行卡支付的,此時須要走的就是銀行或者銀聯的網關接口。
計算機基礎科學知識
對於像數據結構、算法、計算機網絡、操做系統、計算機組成原理這些計算機科學基礎知識,無論是後端仍是其餘領域都是必須的技能,也是全部軟件開發的基礎。紮實的計算機科學基礎才能讓你在學習、使用某種技術開發軟件、調試軟件、排查問題時可以內心有底、有據可循。編程
數據結構:數據結構是組成程序的基礎。經典的數據結構包括:字符串、數組、鏈表、哈希表、樹(二叉樹、平衡樹、紅黑樹、B樹)、堆棧、隊列、圖。
算法: 經典的排序和查找算法在平時的開發工做中常常會用到,如:冒泡排序、插入排序、選擇排序、歸併排序、快速排序、希爾排序、堆排序以及二分查找等。此外,在函數/方法的算法實現中要注意遞歸和迭代各自的優缺點。而衡量算法性能無外乎空間複雜度和時間複雜度。
業務相關算法:除了上面的基本算法以外,業務中還會常常涉及到一些更爲複雜的算法,如:壓縮算法、LRU緩存算法、緩存一致性、編譯原理中的狀態機等。此外,目前愈來愈火的機器學習中有不少算法也是在不少業務場景中有很大用途的,如:用於文本分詞的結巴分詞和中科院ICTCLAS;用於關鍵詞提取的TF-IDF和TextRank;用於計算文本類似度的主題模型、Word2Vec、餘弦類似度以及歐幾里得距離;用於文本分類的樸素貝葉斯;用於推薦的聚類、協同過濾、用戶畫像、隱語義模型等。
計算機網絡: TCP/IP協議是網絡最根本的協議,其七層/四層協議棧的設計都是很是精華的東西,鏈接的創建、斷開以及鏈接的各類狀態的轉換都是排查、解決網絡問題的根本依據。從TCP/IP往上,HTTP協議是如今絕大多數後端應用對外提供的協議,發展到如今已經將要步入HTTP2.0時代,帶來了持久鏈接、鏈接複用等使人振奮的新特性。此外,基於HTTP的HTTPS協議因爲其安全性在逐漸的成爲後端服務對外開放的主流協議。業務層面,基於HTTP協議的RESTful規範正成爲對外接口的主流規範,而OAuth2.0協議也在成爲開放平臺對外的主流協議。除了HTTP以外,SMTP是另外一個基於TCP/IP的應用協議,主要用在發送郵件上。
設計模式: 在軟件開發中,前人的經驗造成了不少經典設計模式供咱們使用,可以使得軟件的實現可服用、可擴展、可維護。經典的工廠模式、簡單工廠模式、單例模式、觀察者模式、代理模式、建築者模式、門面模式、適配器模式、裝飾器模式在平常的不少開發場景下都具備很重要的意義。
數據
如今互聯網的全部業務其實都是圍繞數據來進行的。而數據傳輸、數據存儲、數據分析處理都是關鍵的部分。後端
高速緩存:目前用的最爲普遍的緩存軟件Redis可以支持豐富的數據結構,如:字符串、列表、有序集合等多種數據的存儲。瞭解緩存實現的原理、內存淘汰的策略可以更好地使用緩存。此外因爲緩存的成本較高,在使用緩存的時候必定要作好量化和存儲優化工做。
數據庫:掌握數據庫的很大一個關鍵點就在於對索引的使用,能夠說,正確地使用索引就基本等於掌握了數據庫的使用。目前絕大多數據庫都是使用B樹作爲索引的數據結構,目的就是爲了利用磁盤順序讀寫的特性。不一樣的數據庫因爲自己設計目的的不一樣,都有一些獨特的優點,如:MongoDB自然支持sharding,但受限於NoSQL,在重事務、有關聯關係的場景下並不適用;HBase使用LSM做爲底層數據結構,犧牲了讀性能來換取高速的寫性能。
搜索引擎:搜索引擎主要應對全文檢索以及多維度查詢的業務場景。掌握搜索引擎使用的數據結構、集羣方式、配置的關鍵點有助於更好地使用搜索引擎服務於業務應用。
消息隊列:消息隊列有兩種角色:生產者和消費者,兩種角色對於消息隊列的需求也不同。其中,對於消費者來講,消息消費的方式包括髮布-訂閱和隊列兩種。消息隊列在語義保證上分爲:At Most Once、At Least Once、Exactly Once三種模式,須要更具特定的業務場景選擇合適的語義保證。此外,消息隊列對於高可用、消息安全的保證決定了此消息隊列的可靠性。
數據存儲和處理:數據存儲下來最終仍是要用來作分析和處理的。數據的處理分爲離線處理和實時處理。離線處理的優點在於可以處理大量數據,可是通常會有T+1的延遲,適用於計算量大可是對於結果容許有延時的場景。但對於離線數據分析,還有一個很關鍵的就是數據傾斜問題。所謂數據傾斜指的是region數據分佈不均,形成有的結點負載很低,而有些卻負載很高,從而影響總體的性能。所以,處理好數據傾斜問題對於離線數據處理是很關鍵的。而實時處理通常是流式處理方式,適用於數據可以轉換爲數據流,對於結果要求及時性的場景。對於實時數據分析,須要注意的就是實時數據處理結果寫入存儲的時候,要考慮併發的問題,雖然對於Storm的Bolt程序來講不會有併發的問題,可是寫入的存儲介質是會面臨多任務同時讀寫的。一般採用的方案就是採用時間窗口的方式對數據作緩衝後批量寫入。
數據同步:數據倉庫的數據來源除了直接的日誌外還有一個很關鍵的就是業務數據庫。從業務數據庫到數據倉庫的過程稱爲數據同步。有基於SQL的同步方案,也有基於MySQL binglog的增量同步方案。
Java
對於Java方面的技能來講,主要有兩個大的部分,包括Java編程和JVM。設計模式
先來看一下Java編程部分,這也是Java工程師最最基礎的技能。數組
IDE: 目前用的最多的Java IDE當屬Eclipse和Intellij IDEA。前者是老牌IDE,逐步淘汰了Jbuilder以及Netbeans,佔領了大部分Java IDE市場。後者則是後起之秀,因爲其增量編譯、智能分析代碼等帶來的性能提高,如今已經獲得了大規模使用,大有取代Eclipse之勢。
核心語法:目前用的最多的當屬JDK6的Java語法。而到了Java7引入了try with resource、switch string、diamonds等語法。Java8則又引入了lambda、stream等語法。
集合類:集合類是Java語言中很是精華的部分,包括:HashMap、ArrayList、LinkedList、HashSet、TreeSet以及線程安全的ConcurrentHashMap、ConcurrentLinkedQueue等線程安全集合。瞭解他們的實現原理以及查詢、修改的性能以及使用場景是很是必要的。
工具類:Google Guava、Apache commons、FastJson提供了不少JDK自己沒有的工具類、集合等。此外,ASM字節碼操做以及CGLIB代碼生成可以提供更底層的java編程功能。
高級特性:拋開Java核心的基本編程,併發編程、泛型、網絡編程、序列化RPC都屬於java的高級編程特性。其中併發編程須要掌握Executors提供的各類併發工具、Java7帶來的fork/join框架以及CountDownLatch、Semaphore、CyclicBarrier等同步工具;網絡編程要區分好BIO、NIO以及AIO;序列化中除了JDK自帶的序列化實現以外,Protobuf和Kryo是比較高效的第三方實現;RPC的實現中,Thrift、Hessian、Dubbo以及RMI則是比較經常使用的幾個協議,其中的Hessian是基於Http協議的,Dubbo是基於TCP協議,而Thrift則同時支持。
JavaEE: JavaEE如今是Java應用最爲廣泛的一個領域。Servlet是JavaEE中最根本的組件之一。而Servlet3.0帶來的異步Servlet提升了其處理請求的性能。
項目構建:目前用的最多的Java項目構建工具包括Maven和Gradle,提供了源碼包依賴管理、編譯、打包、部署等一系列功能。
編程框架:Spring是Java編程中避不開的一個框架,發展到如今除了Spring核心的IOC、AOP以外,SpringMvc、Spring Data、Spring Cloud等等都給Java開發者們帶來了開發上的便利,大大提升了開發效率。除此以外,ORM框架MyBatis也是Java領域比較火的框架之一,實現了數據庫記錄到Java對象的映射操做。此外,Jersey提供了從客戶端到服務端的一整套符合RESTful規範的開發框架。
測試:測試是任何編程都須要的一步。黑盒測試主要指的一般進行的功能測試,白盒測試則主要指的對代碼功能、質量進行的測試。此外,關鍵的單元測試則是開發工程師須要着重注意的地方,「測試驅動開發」的理念也是值得推崇的開發方式。JUnit是目前Java中實現單元測試的主流方案。
通常來講掌握上面所述的Java編程技能是可以應付大多編程工做的。可是若是在代碼層面已經作到最大努力卻仍是達不到性能要求的時候,就須要在JVM虛擬機層面作一些努力了。能夠說掌握JVM相關技術是Java開發進階的一個關鍵步驟。
虛擬機實現: Java的虛擬機實現除了咱們經常使用的HotSpot外,還有JRockit、J9以及移動平臺的Dalvkit。咱們一般鎖描述的JVM優化絕大可能是是針對HotSpot虛擬機來講的。
類加載機制:JVM的類加載機器遵循雙親委派原則,即當前類加載器須要先去請求父加載器去加載當前類,若是沒法完成本身才去嘗試進行加載。OSGI框架則打破了此機制,採用了平等的、網狀的類加載機制,以實現模塊化的加載方案。
運行時內存組成: 程序計數器、堆棧、方法區、堆、堆外內存,這些一塊兒組成了JVM的運行時內存。
Java內存模型:Java的主內存+線程私有內存的模型是線程安全問題產生的根本。
GC原理和調優:與C、C++這些語言相比,GC是Java的優點,但由於GC的細節被JVM屏蔽了,在對內存、性能要求很是苛刻的狀況下難以進行自由控制,某種程度這也是劣勢。若是想在某些場景下發揮GC的最大性能,能作的就是對GC的各類參數作優化配置,如新生代和老年代的垃圾回收器選擇、各類垃圾回收參數的配置等。此外,不少時候因爲代碼質量或者外部客觀因素,形成了JVM頻繁GC,須要使用相關的工具快速進行問題定位和解決。
性能調優和監控工具:JDK自帶了不少強大的調優和監控工具,包括jmap、jstack、jcmd、jconsole、jinfo等。此外,btrace是一款很是強大的在線問題動態排查工具,可以無須重啓Java進程,動態的插入一些代碼邏輯,從而攔截代碼執行邏輯打印日誌,從而排查問題。
系統架構
一個應用從0開始通常會經歷單體應用、垂直應用到分佈式服務架構的演化。以下圖所示:
單體應用:當應用規模、團隊規模比較小的時候,只須要一個包括了全部功能的應用便可。減小部署結點,也減小了部署成本。此時,對數據庫的ORM操做是架構實現的關鍵點。
垂直應用:當應用的用戶規模愈來愈大,請求量愈來愈高的時候。單體應用增長結點帶來的資源浪費會凸現出來,由於絕大多數接口請求量並無特別大,根本不必擴充到多個結點。此時,就能夠將單體應用拆分紅互不相關的幾個應用,分別對外提供服務。此時,加速每一個應用開發的MVC框架是架構實現的關鍵點。
分佈式服務:當垂直應用愈來愈多,應用之間的交互不可避免。抽離核心業務單獨部署,逐漸造成穩定的服務中心。而隨着團隊規模的相應擴大,服務會隨着團隊的增多變得愈來愈多,粒度也會變得愈來愈小,也就逐步造成了分佈式服務的架構,而當粒度細到某種程度、服務數量多到必定程度則能夠稱之爲微服務。即在設計好業務邊界以後將原來的單體應用分解成一個個細粒度的服務,彼此之間經過某種方式進行通訊。微服務架構的關鍵在於如何作好服務的治理、調度、維護工做。目前,Dubbo算是微服務架構中用的比較多的框架,但Dubbo僅僅解決了微服務架構中的一部分問題。Spring Cloud則基本上涵蓋了微服務架構的各個方面。
部署架構
對於Web應用來講,LVS+Nginx+Tomcat+MySQL+Redis便可構成一個簡單通用的部署架構,以下圖所示:

LVS做爲最前置的結點,負責在網絡第四層轉發流量、負載均衡。
多個LVS使用Keepalived互爲主備實現高可用。
Nginx做爲反向代理,負責在網絡第七層轉發流量、負載均衡。
Tomcat作爲業務容器,主要的應用代碼都在這裏面。
Redis做爲緩存,隔離高併發請求和後端數據庫。
MySQL以主從模式對數據作持久化。
其中,虛線部分是數據庫層,採用的是主從模式。也可使用Redis Cluster(Codis等)以及MySQL Cluster(Cobar等)來替換。
本文節選自《Java工程師修煉之道》一書。
本書能夠看做一本Java工程師的入職指南,也能夠看做一本串聯Java後端技能點的參考手冊。經過精心編排的內容,剛入門的Java工程師可以體系化地學習相關開發技能,有經驗的Java工程師可以查漏補缺,鞏固本身的相關開發技能,進一步完善自身的Java技術體系。
購書地址:item.jd.com/12325207.ht…