在去年的一次面試中,我被問及性能優化方面的問題。對方問,「你在性能優化方面有哪些瞭解?」。我感到問題籠統,有些無從下手,因而簡單地回答道:「找到程序性能的瓶頸位置,進行鍼對性的優化,好比爲數據庫查詢效率低的地方適當添加索引等……」。對方的表情告訴我,這個答案不令他滿意。html
那時的我並不以爲本身說錯,且面試最終經過,不過對方的一瞬間的不快表情仍是給我留下了深入印象。時至今日,在通過一些學習和工做後,我不得不認可本身當時的回答是膚淺的。今天寫下這篇文章,結合最近的學習和工做,記錄下本身對這個問題的的一些新的認識。本文不涉及具體的性能優化技術,只有一些思考問題的思路,以及面試方面的反思。程序員
本文連接:http://www.javashuo.com/article/p-qqxrlrmv-t.html面試
原創內容,轉載請註明。算法
本文的標題是「從系統角度考慮性能優化」,系統指的是一些模塊和它們之間的關係的結合。模塊的形式多種多樣,能夠是類、子系統、或服務等。數據庫
系統的價值在於它能夠提供功能,好比一家手機公司的售後服務管理系統能夠提供查詢手機保修信息的功能、建立手機維修訂單的功能。性能優化
性能,則是指系統執行功能的好壞程度。查詢1臺手機的保修信息須要花多久?它是查詢功能的性能問題。服務器
在給出了性能的定義後,咱們又面臨着一個新的問題:誰的性能須要優化?網絡
已知性能是功能的屬性,功能來自於系統,那麼要回答上面的問題,則首先要找到性能對應的功能,以及功能涉及的系統範圍。架構
以上文提到的售後服務管理軟件爲例,異步
功能:查詢手機的保修信息。
性能:查詢效率。在定義了這樣的系統範圍以後,對於性能優化問題,咱們即可以從系統的結構出發,進而思考一些問題,好比:
可是,這樣的系統一般是給企業內部用戶使用的,若是面臨查詢保修信息性能問題的人是一個外部用戶,性能所涉及的系統的可能已經有變化,系統多是以下模樣,
圖2 售後管理系統、中間件和外部應用組成的新系統
如圖2所示,虛線框表明一個單一系統的邊界,邊界間的連線表明了系統間的接口。3個單獨的系統聯合起來組成了了一個新的複合系統。
外部用戶使用外部應用查詢保修信息,外部應用經過接口鏈接中間件系統,中間件再經過接口鏈接本來的售後管理系統的業務邏輯層,以獲取保修信息。
此時,系統的結構已與圖1中的結構不一樣,若是還按照圖1下的思考方式排查性能問題,就有可能沒法找到正確的問題所在。
好比,若是查詢效率問題來自於中間件的吞吐量不足,那麼不管怎樣在售後管理系統進行分析、優化,恐怕也很難解決問題。
有的問題可能已通過時,好比,
有些新的問題會產生,好比,
因此,當咱們但願作性能優化時,必須清晰地定義出相關的系統範圍,對範圍內的功能和結構作分析,才能可靠地完成工做。
這是我在面試中犯的第二個錯誤:沒有考慮性能優化的問題背景,想固然地理解成單個程序的性能優化問題。在溝通中,不只要理解雙方對問題的具體概念的定義,也應充分理解問題的上下文。否則很容易陷入東拉西扯找不到重點的狀況。在性能優化的問題中,系統範圍和系統結構屬於上下文。
既然性能是系統執行功能的好壞程度,那性能的好壞與功能自己的定義是有着密切聯繫的。好比,若是功能是在查詢後同步返回一份保修信息報告,那麼在查詢發起一小時後返回這份報告一般是讓人難以忍受的。但若是功能的定義變成:申請生成一份保修信息報告,並容許用戶在24小時後查詢。在這種新的功能定義下,程序花費1小時來準備這份報告彷佛變得毫無問題。聽起來這是一種文字遊戲,但現實中的確有相似的作法,好比人行的徵信報告。
圖3 人行我的徵信報告申請界面
上面的例子可能過於誇張,可是在現實中,經過對系統功能進行必定調整以改善性能的作法每每是可行的。好比《Designing Data-Intensive Applications》中詳細描述的派生數據系統,經過將一個不可變的變動日誌做爲源,異步地將數據更新到其它系統,以提供良好的可靠性和可伸縮性,並改善應用的進化能力。若是咱們從一個派生數據系統中進行查詢操做,而且將功能定義爲「查詢五分鐘前的信息狀態」而非查詢實時的信息狀態,獲得的結果有多是稍稍過期的,可是在查詢的響應時間方面會有很大的提高空間。
一般來講,人們須要對業務和技術有着深刻的理解,才能提出好的功能重定義方案。
與這段內容相關的是我在面試中可能犯下的第三個錯誤:沒有延伸問題,把回答拘泥在提問的字面意思以內。就事論事固然是一種美德,但也不該忘記溝通中常見的XY問題:一我的想解決問題X,可是他不直接就問題X提問,而是詢問如何解決問題Y,由於他相信問題Y能幫助他解決問題X,這樣就致使了誤解。對於面試來講,面試官提問「性能優化」不表明他只想聽到性能優化的具體技巧方面的回答,面試官可能只是但願找一個切入點來開展談話。在真實的開發工做中,業務人員提出的性能問題,其背後可能存在另外的問題,也許能夠經過功能的調整來改進。此外,對系統業務人員來講,最重要的也並不是是性能,而是經過功能/性能體現出的系統價值,下一節會對價值作出分析。
價值是有成本的利益,它經過系統與外界的交互(位於系統邊界的接口)而體現。
在圖2中,左側的售後服務管理系統的查詢功能的價值是經過其與中間件的接口來體現的,而由3個系統組成的複合系統的價值是經過系統提供給用戶的查詢功能而體現的,以下圖,
圖4 系統價值經過邊界的接口體現
在進行性能優化的同時,也不要忘記把成本計算在內。
若是程序員爲一個一次性使用的程序花費了5天時間來進行性能優化,最終節約了用戶3天的時間,那麼這種性能優化工做有價值嗎?答案是沒有的,由於它的收益低於成本。
系統的價值取決於觀察者的主觀判斷,而用戶的觀察和開發人員的觀察多是不一樣的。開發人員可能更關注技術上的進步,從這個角度來看,程序節約了3天的運行時間是一種成功。但從用戶的角度看,性能優化的工做致使本身不得不等待5天,相比不優化使其損失了2天的時間,反而帶來了麻煩。這篇文章的標題包含【被面試官吊打】,緣由正是開篇寫到的面試經歷。我想,被吊打並不可恥,只要不斷反思、改善本身,那麼被吊打的經歷也會成爲本身成長的助益。
本文的不少概念來自於《系統架構》,這是一本介紹系統思惟、系統分析和設計的書,不是軟件架構書。
本文中的圖片1, 2, 4是使用draw.io繪製的,圖3來自網絡。