【被面試官吊打】從系統角度考慮性能優化


在去年的一次面試中,我被問及性能優化方面的問題。對方問,“你在性能優化方面有哪些了解?”。我感到問題籠統,有些無從下手,於是簡單地回答道:“找到程序性能的瓶頸位置,進行針對性的優化,比如為數據庫查詢效率低的地方適當添加索引等……”。對方的表情告訴我,這個答案不令他滿意。

那時的我並不覺得自己說錯,且面試最終通過,不過對方的一瞬間的不快表情還是給我留下了深刻印象。時至今日,在經過一些學習和工作后,我不得不承認自己當時的回答是膚淺的。今天寫下這篇文章,結合最近的學習和工作,記錄下自己對這個問題的的一些新的認識。本文不涉及具體的性能優化技術,只有一些思考問題的思路,以及面試方面的反思。

 

本文鏈接:https://www.cnblogs.com/hhelibeb/p/11985604.html

原創內容,轉載請注明。

什么是性能?

本文的標題是“從系統角度考慮性能優化”,系統指的是一些模塊和它們之間的關系的結合。模塊的形式多種多樣,可以是類、子系統、或服務等。

系統的價值在於它可以提供功能,比如一家手機公司的售后服務管理系統可以提供查詢手機保修信息的功能、創建手機維修訂單的功能。

性能,則是指系統執行功能的好壞程度。查詢1台手機的保修信息需要花多久?它是查詢功能的性能問題。

 
這是我在面試中犯的 第一個錯誤:沒有就問題中的基本概念(性能的定義)與提問者達成共識。討論一個問題時,討論者之間需要首先明確彼此對問題中的基本概念的認知,這是溝通中的一項基本工作,在陌生人之間尤其重要。既然要討論“性能優化”,那么首先需要確定的,自然是性能的定義。
 

定義系統范圍

在給出了性能的定義后,我們又面臨着一個新的問題:誰的性能需要優化?

已知性能是功能的屬性,功能來自於系統,那么要回答上面的問題,則首先要找到性能對應的功能,以及功能涉及的系統范圍。

以上文提到的售后服務管理軟件為例,

功能:查詢手機的保修信息。

性能:查詢效率。
 
那么,系統的范圍是什么呢?要回答這個問題,需要對系統的結構有認識。作為一個企業信息化軟件,售后服務管理系統的結構可能是這樣,
圖1 三層架構的售后管理系統
 

在定義了這樣的系統范圍之后,對於性能優化問題,我們便可以從系統的結構出發,進而思考一些問題,比如:

  • 從表示層到業務邏輯層是否存在較大網絡延遲?
  • 業務邏輯層是否存在效率低下的代碼?
  • 數據庫服務器負載如何?
  • 數據庫查詢的執行計划是否正常?
  • 需要用哪些工具/手段調查以上問題?
  • 哪些相關人能負責調查系統的各個部分?
  • ……

但是,這樣的系統通常是給企業內部用戶使用的,如果面臨查詢保修信息性能問題的人是一個外部用戶,性能所涉及的系統的可能已經有變化,系統可能是如下模樣,

 

圖2 售后管理系統、中間件和外部應用組成的新系統

如圖2所示,虛線框代表一個單一系統的邊界,邊界間的連線代表了系統間的接口。3個單獨的系統聯合起來組成了了一個新的復合系統。

外部用戶使用外部應用查詢保修信息,外部應用通過接口連接中間件系統,中間件再通過接口連接原本的售后管理系統的業務邏輯層,以獲取保修信息。

此時,系統的結構已與圖1中的結構不同,如果還按照圖1下的思考方式排查性能問題,就有可能無法找到正確的問題所在。

比如,如果查詢效率問題來自於中間件的吞吐量不足,那么無論怎樣在售后管理系統進行分析、優化,恐怕也很難解決問題。

有的問題可能已經過時,比如,

  • 從表示層到業務邏輯層是否存在較大網絡延遲?(在新的系統結構下,用戶並沒有通過售后管理系統的表示層進行查詢,因此該處網絡延遲不會對性能有影響)

有些新的問題會產生,比如,

  • 中間件的吞吐能力如何,有什么限制?
  • 系統間是同步處理還是異步處理?
  • 系統間的網絡延遲如何?
  • 接口的性能如何?
  • 系統間的容錯機制是什么?
  • ……

所以,當我們希望做性能優化時,必須清晰地定義出相關的系統范圍,對范圍內的功能和結構做分析,才能可靠地完成工作。

 

這是我在面試中犯的第二個錯誤:沒有考慮性能優化的問題背景,想當然地理解成單個程序的性能優化問題。在溝通中,不僅要理解雙方對問題的具體概念的定義,也應充分理解問題的上下文。不然很容易陷入東拉西扯找不到重點的情況。在性能優化的問題中,系統范圍和系統結構屬於上下文。

重定義功能

既然性能是系統執行功能的好壞程度,那性能的好壞與功能本身的定義是有着密切聯系的。比如,如果功能是在查詢后同步返回一份保修信息報告,那么在查詢發起一小時后返回這份報告通常是讓人難以忍受的。但如果功能的定義變成:申請生成一份保修信息報告,並允許用戶在24小時后查詢。在這種新的功能定義下,程序花費1小時來准備這份報告似乎變得毫無問題。聽起來這是一種文字游戲,但現實中的確有類似的做法,比如人行的征信報告

 

圖3 人行個人征信報告申請界面

上面的例子可能過於誇張,但是在現實中,通過對系統功能進行一定調整以改善性能的做法往往是可行的。比如《Designing Data-Intensive Applications》中詳細描述的派生數據系統,通過將一個不可變的變更日志作為源,異步地將數據更新到其它系統,以提供良好的可靠性和可伸縮性,並改善應用的進化能力。如果我們從一個派生數據系統中進行查詢操作,並且將功能定義為“查詢五分鍾前的信息狀態”而非查詢實時的信息狀態,得到的結果有可能是稍稍過時的,但是在查詢的響應時間方面會有很大的提升空間。

通常來說,人們需要對業務和技術有着深入的理解,才能提出好的功能重定義方案。

 

與這段內容相關的是我在面試中可能犯下的第三個錯誤:沒有延伸問題,把回答拘泥在提問的字面意思之內。就事論事當然是一種美德,但也不應忘記溝通中常見的XY問題:一個人想解決問題X,但是他不直接就問題X提問,而是詢問如何解決問題Y,因為他相信問題Y能幫助他解決問題X,這樣就導致了誤解。對於面試來說,面試官提問“性能優化”不代表他只想聽到性能優化的具體技巧方面的回答,面試官可能只是希望找一個切入點來開展談話。在真實的開發工作中,業務人員提出的性能問題,其背后可能存在另外的問題,也許可以通過功能的調整來改進。此外,對系統業務人員來說,最重要的也並非是性能,而是通過功能/性能體現出的系統價值,下一節會對價值做出分析。

關注價值

價值是有成本的利益,它通過系統與外界的交互(位於系統邊界的接口)而體現。

在圖2中,左側的售后服務管理系統的查詢功能的價值是通過其與中間件的接口來體現的,而由3個系統組成的復合系統的價值是通過系統提供給用戶的查詢功能而體現的,如下圖,

圖4 系統價值通過邊界的接口體現

在進行性能優化的同時,也不要忘記把成本計算在內。

  • 如果使用raid 0提高了磁盤讀寫性能,那么額外多出的硬盤就是成本。
  • 如果使用一種空間換時間的算法減少程序的運行時間,那增加的內存占用就是成本。
  • 如果程序員要花5天的時間改進一項功能的性能,那5人天就是成本。
  • ……

如果程序員為一個一次性使用的程序花費了5天時間來進行性能優化,最終節約了用戶3天的時間,那么這種性能優化工作有價值嗎?答案是沒有的,因為它的收益低於成本。

系統的價值取決於觀察者的主觀判斷,而用戶的觀察和開發人員的觀察可能是不同的。開發人員可能更關注技術上的進步,從這個角度來看,程序節約了3天的運行時間是一種成功。但從用戶的角度看,性能優化的工作導致自己不得不等待5天,相比不優化使其損失了2天的時間,反而帶來了麻煩。
關注系統的邊界,有助於我們理解系統的價值,從而避免過於主觀的判斷。
 
這是我在面試中可能存在的第四個錯誤:只關注性能優化在技術方面的意義,沒有提及系統價值方面的內容。

總結

這篇文章的標題包含【被面試官吊打】,原因正是開篇寫到的面試經歷。我想,被吊打並不可恥,只要不斷反思、改善自己,那么被吊打的經歷也會成為自己成長的助益。

 

本文的很多概念來自於《系統架構》,這是一本介紹系統思維、系統分析和設計的書,不是軟件架構書。

本文中的圖片1, 2, 4是使用draw.io繪制的,圖3來自網絡。

 

 
參考閱讀:
 
 
 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM