搜尋
首頁JavaJava面試題面試:你知道Java效能優化有哪些手段?

前兩天,一位群組裡的朋友找我聊,面試中被問到效能優化手段該如何回答,今天我們就聊聊。 本文主要著重於理論分析,我們從整體來看 Java 效能最佳化都有哪些可以遵循的規律。

本文主講理論,關於實踐,後續的文章會用較多的案例來細化本文的知識點,適合反复思考與歸納

概述

效能最佳化根據最佳化的類別,分為業務最佳化和技術最佳化。業務優化所產生的效果也是非常大的,但它屬於產品和管理的範疇。同作為程式設計師,在平常工作中,我們面對的最佳化方式,主要是透過一系列的技術手段,來完成對既定的最佳化目標。這一系列的技術手段,我大體歸納為如圖以下 7 類:

面試:你知道Java效能優化有哪些手段?

#可以看到,優化方式集中在計算資源和儲存資源的規劃。優化方法有多種用空間換時間的方式,但只照顧計算速度,而不考慮複雜性和空間問題,也是不可取的。我們要做的,就是在照顧性能的前提下,要達到資源利用的最適狀態。

接下來,我簡單介紹一下這7個最佳化方向。如果你覺得比較枯燥,那也沒關係,我們這篇文章的目的,就是讓你的腦海裡有一個總分的概念,以及對理論基礎有一個整體的認識。

復用最佳化

#在寫程式碼的時候,你會發現有很多重複的程式碼可以提取出來,做成公共的方法。這樣,下次用的時候,就不用再費勁寫一遍了。

這種想法就是複用。上面的描述是編碼邏輯上的最佳化,對於資料存取來說,有相同的複用情況。無論是在生活中或編碼中,重複的事情一直在發生,如果沒有重複使用,工作和生活就會比較累。

在軟體系統中,談到資料重複使用,我們首先想到的就是緩衝和快取。注意這兩個字的區別,它們的意義是完全不同的,很多同學很容易搞混,在這裡簡單地介紹一下。

緩衝(Buffer),常見於資料的暫存,然後批次傳輸或寫入。多使用順序方式,用來緩解不同設備之間頻繁地、緩慢地隨機寫,緩衝主要針對的是寫入操作。

快取(Cache),常見於對已讀取資料的複用,透過將它們快取在相對高速的區域,快取主要針對的是讀取操作。

與之類似的,是對於物件的池化操作,例如資料庫連線池、執行緒池等,在 Java 中使用得非常頻繁。由於這些物件的創建和銷毀成本都比較大,我們在使用之後,也會將這部分物件暫時存儲,下次用的時候,就不用再走一遍耗時的初始化操作了。

計算最佳化

#並行執行

##現在的CPU 發展速度很快,絕大多數硬件,都是多核心。要加快某個任務的執行,最快最優的解決方式,就是讓它並行執行。並行執行有以下三種模式。

第一種模式是多機,採用負載平衡的方式,將流量或大的計算拆分成多個部分,同時進行處理。例如,Hadoop 透過 MapReduce 的方式,把任務打散,多機同時進行運算。

第二種模式是採用多進程。例如 Nginx,採用 NIO 程式設計模型,Master 統一管理 Worker 進程,然後由 Worker 進程進行真正的請求代理,這也能很好地利用硬體的多個 CPU。

第三種模式是使用多線程,這也是 Java 程式設計師接觸最多的。例如 Netty,採用 Reactor 程式設計模型,同樣使用 NIO,但它是基於執行緒的。 Boss 執行緒用來接收請求,然後調度給對應的 Worker 執行緒進行真正的業務運算。

###像Golang 這樣的語言,有更輕量級的協程(Coroutine),協程是一種比線程更加輕量級的存在,但目前在Java 中還不太成熟,就不做太多介紹了,但本質上,它也是對於多核心的應用,使得任務並行執行。 ###

變同步為非同步

#再一種對於計算的最佳化,就是變同步為非同步,這通常涉及程式設計模型的改變。同步方式,請求會一直阻塞,直到有成功,或失敗結果的回傳。雖然它的程式模型簡單,但應對突發的、時間段傾斜的流量,問題就特別大,請求很容易失敗。

非同步操作可以方便地支援橫向擴容,也可以緩解瞬時壓力,使請求變得平滑。同步請求,就像拳頭打在鋼板上;非同步請求,就像拳頭打在海綿上。你可以想像一下這個過程,後者肯定是富有彈性的,體驗更加友善。

惰性載入

#最後一種,就是使用一些常見的設計模式來優化業務,提升體驗,例如單例模式、代理模式等。舉個例子,在繪製 Swing 視窗的時候,如果要顯示比較多的圖片,就可以先載入一個佔位符,然後透過後台執行緒慢慢載入所需的資源,這就可以避免視窗的僵死。

結果集最佳化

#接下來介紹對結果集的最佳化。舉個比較直觀的例子,我們都知道 XML 的表現形式是非常好的,那為什麼還有 JSON 呢?除了書寫要簡單一些,一個重要的原因就是它的體積變小了,傳輸效率和解析效率變高了,像 Google 的 Protobuf,體積就更小了一些。雖然可讀性降低,但在一些高並發場景下(如 RPC),能夠顯著提高效率,這是典型的對結果集的最佳化。

這是由於我們目前的 Web 服務,都是 C/S 模式。資料從伺服器傳輸到客戶端,需要分發多份,這個資料量是急劇膨脹的,每減少一小部分存儲,都會有比較大的傳輸性能和成本提升。

像 Nginx,一般都會開啟 GZIP 壓縮,使得傳輸的內容保持緊湊。客戶端只需要一小部分運算能力,就可以方便解壓。由於這個操作是分散的,所以性能損失是固定的。

了解了這個道理,我們就能看到對於結果集優化的一般思路,你要盡量保持回傳資料的精簡。一些客戶端不需要的字段,那就在程式碼中,或直接在 SQL 查詢中,就把它去掉。

對於某些對時效性要求不高,但對處理能力有高要求的業務。我們要吸收緩衝區的經驗,盡量減少網路連線的交互,採用批量處理的方式,增加處理速度。

結果集合很可能會有二次使用,你可能會把它加入快取中,但依然在速度上有所欠缺。這個時候,就需要對資料集合進行處理最佳化,採用索引或 Bitmap 點陣圖等方式,加快資料存取速度。

資源衝突最佳化

我們在平常的開發中,會牽涉到很多共享資源。這些共享資源,有的是單機的,例如一個 HashMap;有的是外部存儲,例如一個資料庫行;有的是單一資源,例如 Redis 某個 key 的Setnx;有的是多個資源的協調,例如事務、分散式事務等。

現實中的效能問題,和鎖定相關的問題是非常多的。大多數我們會想到資料庫的行鎖、表鎖、Java 中的各種鎖等。在更底層,例如 CPU 指令層級的鎖、JVM 指令層級的鎖、作業系統內部鎖等,可以說無所不在。

只有並發,才能產生資源衝突。也就是在同一時刻,只能有一個處理請求能夠取得到共享資源。解決資源衝突的方式,就是加鎖。再比如事務,在本質上也是一種鎖。

依照鎖級別,鎖可分為樂觀鎖和悲觀鎖,樂觀鎖在效率上肯定是更高一些;按照鎖類型,鎖又分為公平鎖和非公平鎖,在對任務的調度上,有一些細微的差別。

對資源的爭用,會造成嚴重的效能問題,所以會有一些針對無鎖佇列之類的研究,對效能的提升也是巨大的。

演算法最佳化

#演算法能夠顯著提高複雜業務的效能,但在實際的業務中,往往都是變種。由於儲存越來越便宜,在一些 CPU 非常緊張的業務中,往往採用空間換取時間的方式,來加快處理速度。

演算法屬於程式碼調優,程式碼調優涉及許多編碼技巧,需要使用者對所使用語言的 API 也非常熟悉。有時候,對演算法、資料結構的靈活使用,也是程式碼最佳化的重要內容。例如,常用的降低時間複雜度的方式,就有遞歸、二分、排序、動態規劃等。

一个优秀的实现,比一个拙劣的实现,对系统的影响是非常大的。比如,作为 List 的实现,LinkedList 和 ArrayList 在随机访问的性能上,差了好几个数量级;又比如,CopyOnWriteList 采用写时复制的方式,可以显著降低读多写少场景下的锁冲突。而什么时候使用同步,什么时候是线程安全的,也对我们的编码能力有较高的要求。

这部分的知识,就需要我们在平常的工作中注意积累,后面的课时中,也会挑比较重要的知识点穿插讲解。

高效实现

在平时的编程中,尽量使用一些设计理念良好、性能优越的组件。比如,有了 Netty,就不用再选择比较老的 Mina 组件。而在设计系统时,从性能因素考虑,就不要选 SOAP 这样比较耗时的协议。再比如,一个好的语法分析器(比如使用 JavaCC),其效率会比正则表达式高很多。

总之,如果通过测试分析,找到了系统的瓶颈点,就要把关键的组件,使用更加高效的组件进行替换。在这种情况下,适配器模式是非常重要的。这也是为什么很多公司喜欢在现有的组件之上,再抽象一层自己的;而当在底层组件进行切换的时候,上层的应用并无感知。

JVM 优化

因为 Java 是运行在 JVM 虚拟机之上,它的诸多特性,就要受到 JVM 的制约。对 JVM 虚拟机进行优化,也能在一定程度上能够提升 JAVA 程序的性能。如果参数配置不当,甚至会造成 OOM 等比较严重的后果。

目前被广泛使用的垃圾回收器是 G1,通过很少的参数配置,内存即可高效回收。CMS 垃圾回收器已经在 Java 14 中被移除,由于它的 GC 时间不可控,有条件应该尽量避免使用。

JVM 性能调优涉及方方面面的取舍,往往是牵一发而动全身,需要全盘考虑各方面的影响。所以了解 JVM 内部的一些运行原理,还是特别重要的,它有益于我们加深对代码更深层次的理解,帮助我们书写出更高效的代码。

小结

以上就是代码优化的 7 个大方向,我们通过简要的介绍,让大家对性能优化的内容有了大体的了解。这7大方向是代码优化的最主要方向,当然,性能优化还包含数据库优化、操作系统优化、架构优化等其他一些内容,这些不是我们的重点,在后面的文章中,我们也只做简要的介绍。

以上是面試:你知道Java效能優化有哪些手段?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:Java后端技术全栈。如有侵權,請聯絡admin@php.cn刪除

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。