寫在前面
隨著網際網路的高速發展,網際網路行業已經從IT時代慢慢步入到DT時代。對於Java程式設計師的要求越來越高,只是單純的掌握CRUD以不足以勝任網際網路公司的相關職位,大量招聘崗位顯示:如果是面試中高階的Java崗,基本上都需要懂效能優化的相關知識。今天,我們就一起來聊聊一個經典的面試題:做過效能優化的工作嗎?你會從哪些方面入手做效能優化呢?
問題分析
標題中問出了兩個問題,一個是有沒有做過效能優化的工作,一個是從哪些方面入手做效能優化。對於第一個問題,我們可以直接回答有或者沒有。相信小夥伴們都希望自己做過效能優化的工作,如果是回答做過,那第二個問題,我們又該如何回答呢?
首先,對於第二個問題來說,問的是會從哪些方面入手。這個問題就沒有固定答案了。你可以按照你以往的經驗來回答這個問題,但是,在回答這個問題之前,需要先好好梳理下你的思路,將你要表達的說清楚。
接下來,我們就一起來聊聊第二個問題:你會從哪些方面入手做效能優化?
我們可以從效能優化的幾個方面來進行回答。下面,我們就來聊聊效能優化可以從哪些方面進行。
效能優化有哪些方面?
這裡,我結合平時工作中的總結,將效能優化總結為下面這張圖。
也就是說,我們可以從資料聚合優化、資源衝突優化、演算法優化、JVM優化、複用優化、計算優化和快速實現等方面來進行回答。接下來,我們就針對每個點進行說明。
資料聚合優化
資料聚合優化主要針對的是對於資料的整合和傳輸的優化。比如:我們從資料庫中查詢出的資料,經過程式的聚合處理後再返回給客戶端,而不用客戶端呼叫多次介面來分別獲取資料。
再比如:我們在專案中使用的Nginx,一般都會開啟GZIP壓縮,使傳輸的資料更加緊湊,同時,使傳輸的資料量更小。
細心的小夥伴會發現,我們對於資料聚合的優化,主要是使傳輸的資料量更小。所以,我們在使用SQL語句查詢資料庫中的資料時,儘量查詢那些需要的欄位,對於不需要的欄位就直接忽略不查詢了,避免在SQL語句中出現select *
資源衝突優化
在我們平時的工作中,尤其是在高併發的場景下,經常會出現鎖衝突的問題,鎖衝突是資源衝突的一個典型場景。
關於鎖我們可以聯想到資料庫的行鎖、表鎖、Java中的synchronized和Lock等。如果對應到作業系統級別,則會有CPU命令級別的鎖,JVM指令級別的鎖,作業系統的內部鎖等。
這裡,小夥伴們需要注意一點:只有在併發的場景下,才會出現資源衝突的問題。也就是說:在同一時刻,只能有一個請求獲取到請求資源,解決衝突的方式就是加鎖。
我們需要在平時的工作過程中避免鎖衝突的問題,優化如何優化加鎖方式,小夥伴們可以參見《【高併發】面試官:講講高併發場景下如何優化加鎖方式?》一文。
演算法優化
在一個大型的網際網路專案中,往往涉及到分散式和微服務等技術,其中,也會使用到大量的資料結構和演算法,對於演算法的優化能夠顯著的提高系統的效能。一個好的實現,相比於一個拙劣的實現來說,在系統效能的提升上存在著巨大的差異。
比如,作為 List 的實現,LinkedList 和 ArrayList 在隨機訪問的效能上,差了好幾個數量級;又比如,CopyOnWriteList 採用寫時複製的方式,可以顯著降低讀多寫少場景下的鎖衝突。而什麼時候使用同步,什麼時候是執行緒安全的,也對我們的編碼能力有較高的要求。
所以,我們需要在平時工作過程中,多多積累資料結構和演算法的相關知識。
JVM優化
JVM調優,不用說,這是每個Java工程師必須要掌握的標準技能。所有的Java程式最終都是執行在JVM中的,對JVM進行優化也能夠提升Java程式的效能。但是,需要注意的是:如果在優化JVM時,引數設定不當,可能會造成記憶體溢位等嚴重的問題。
目前被廣泛使用的垃圾回收器是 G1,通過很少的引數配置,記憶體即可高效回收。CMS 垃圾回收器已經在 Java 14 中被移除,由於它的 GC 時間不可控,有條件應該儘量避免使用。
複用優化
複用優化,這個看名字就知道,說白了就是可以重複利用。估計很多小夥伴都有這樣的經驗,在寫程式碼的時候,可以將很多重複的程式碼抽象出來,做成公共的方法。這樣,就不用每次都去寫重複的邏輯程式碼了。這是程式碼層面的複用。
如果是資料層面的話,我們可以使用緩衝和快取來複用資料。
這裡,小夥伴們需要注意一個知識點:緩衝主要針對的是寫操作,快取主要針對的是讀操作。
另一個複用優化的典型場景就是池化技術,比如:資料庫連線池、執行緒池等。
計算優化
對於計算優化來說,我們可以從以下幾個小的方面來闡述。
平行計算
不難理解,就是多個計算同時進行。這裡,又可以將平行計算分為:多機平行計算、多程式平行計算和多執行緒平行計算。
多機平行計算: 將一個大的計算任務,拆分成N個小的計算任務,分發到不同的機器進行處理。典型的場景就是Hadoop的MapReduce極端。
多程式計算: 比如,Nginx採用的NIO模型,採用的是程式排程的策略,由Master程式排程Worker程式,Worker進行來處理具體的請求。
多執行緒計算: 對於多執行緒計算來說,也是我們平時接觸最多的一種計算方式,我們可以使用多執行緒技術,將複雜的邏輯計算拆分成一個個小的計算任務,分發到不同的執行緒中去執行。
同步變非同步
同步和非同步的區別就是:同步需要等待返回結果,非同步不需要等待返回結果。如果我們在業務程式中,不需要等待返回結果資料,則我們可以將同步呼叫優化為非同步呼叫,從而提升我們系統的效能。
懶載入
最典型的場景就是Spring中的懶載入,只有第一次獲取bean的時候,才會建立bean例項。
快速實現
對於快速實現來說,不僅包含我們需要利用相關的程式框架迅速開發出我們想要的業務,也需要我們在進行技術選型時,儘量使用一些效能優良的元件。比如,在進行網路開發時,儘量選擇Netty,結合輕量級的資料傳輸,就不要使用WebService等技術了。
很多公司喜歡使用介面卡模式,在一些現有的開源元件之上,再抽象一層自己的元件,這樣就能夠做到切換底層元件的時候,對上層應用無感。
好了,今天我們就到這兒吧,我是冰河,我們下期見!!
重磅福利
微信搜一搜【冰河技術】微信公眾號,關注這個有深度的程式設計師,每天閱讀超硬核技術乾貨,公眾號內回覆【PDF】有我準備的一線大廠面試資料和我原創的超硬核PDF技術文件,以及我為大家精心準備的多套簡歷模板(不斷更新中),希望大家都能找到心儀的工作,學習是一條時而鬱鬱寡歡,時而開懷大笑的路,加油。如果你通過努力成功進入到了心儀的公司,一定不要懈怠放鬆,職場成長和新技術學習一樣,不進則退。如果有幸我們江湖再見!
另外,我開源的各個PDF,後續我都會持續更新和維護,感謝大家長期以來對冰河的支援!!
寫在最後
如果你覺得冰河寫的還不錯,請微信搜尋並關注「 冰河技術 」微信公眾號,跟冰河學習高併發、分散式、微服務、大資料、網際網路和雲原生技術,「 冰河技術 」微信公眾號更新了大量技術專題,每一篇技術文章乾貨滿滿!不少讀者已經通過閱讀「 冰河技術 」微信公眾號文章,吊打面試官,成功跳槽到大廠;也有不少讀者實現了技術上的飛躍,成為公司的技術骨幹!如果你也想像他們一樣提升自己的能力,實現技術能力的飛躍,進大廠,升職加薪,那就關注「 冰河技術 」微信公眾號吧,每天更新超硬核技術乾貨,讓你對如何提升技術能力不再迷茫!