1. 程式人生 > >【被面試官吊打】從系統角度考慮效能優化

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

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

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

 

本文連結: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來自網路。

 

  參考閱讀: 《系統架構》      軟體設計之Deep Module(深模組)              《Designing Data-Intensive Applications》                   XY problem - Wikipedia