架構師成長之路(5)--架構師具備的思維

一、抽象思維


在軟件業,抽象能力的重要性怎麼說都不爲過,因爲軟件開發是一個高度複雜的智力活動,程序員經常需要面對、處理異常複雜的業務和邏輯,如果你不具備強大的抽象能力,無法把具體變成概念,進而駕馭概念進行思考, 你就很難降低問題的複雜度,從而陷入泥潭,無法自拔。無論你學會了多麼強大的程序語言,你的編程能力也很難有質的提高。

抽象其實是這樣定義的:對某種事物進行簡化表示或描述的過程,抽象讓我們關注要素,隱藏額外細節。

抽象能力就是在思維活動中,通過對事物整體性的科.學分析,把自己認爲是事物的本質方面、主要方面提取出來,捨棄非本質、非主要的東西,從而形成概念和範疇的思維能力。

首先我們看看相關領域抽象的例子:

1、執政理念的抽象:“和.諧.社.會”,“中. 國. 夢” ,就是把執政理念和民衆的訴求進行抽象

2、自然科學領域物體運動抽象描述:

     1)文學家開普勒提出開普勒定律:
     2)牛頓的萬有引力:行星運動的本質是萬有引力定律:
     3)愛因斯坦相對論:E=mc2

其實一個抽象的東西形式優美,結構簡單,很有可能是正確的,很可能抓住了事物的本質。

3、抽象的例子在軟件業更是數不勝數:
      1)文件是對I/O的抽象,linux系統一切皆文件。
      2)虛擬存儲器是對物理存儲器的抽象;
      3)進程是對一個正在運行的程序的抽象;
      4)虛擬機, 它提供了對整個計算機(包括操作系統,處理器,程序)的抽象。
      5)Andorid 把一個移動應用程序抽象成Activity , Intent, Service,Provider。
......
稍微注意一下就會發現: 抽象層次越高,接口的語意就越模糊,適用的範圍就越廣,到最後就會變成數學模型或者概念。

說到底,軟件設計和開發就是把現實中的問題映射的計算機的語言實現,但現實問題太複雜,細節太多,而且在不斷的變化過程中,一般人很難同時對這麼的細節進行思考 ,這時候就需要抽象。

我們只有從紛繁複雜的現象中抽取事物的本質,從具體事物提煉出正交的概念,才能駕馭這些概念,才能在一個低複雜度的世界中進行思考。

如何提高抽象思維能力,我們側重於下列三方面進行培養:

1)、由現象到實質,即善於捨棄事物的非本質的細節,抽取問題的實質的能力.
2)、運用字母、符號和進行推廣、推想的能力.
3)、由特殊到一般,即化問題的具體提法爲一般情況,進而公式化的能力.

 

二、分層思維


除了抽象,分層也是我們應對和管理複雜性的基本思維武器,如下圖,爲了構建一套複雜系統,我們把整個系統劃分成若干個層次,每一層專注解決某個領域的問題,並向上提供服務。有些層次是縱向的,它貫穿所有其它層次,稱爲共享層。分層也可以認爲是抽象的一種方式,將系統抽象分解成若干層次化的模塊。

 

分層架構的案例很多,一箇中小型的Spring Web應用程序,我們一般會設計成三層架構:

 

操作系統是經典的分層架構,如下圖:

 

TCP/IP協議棧也是經典的分層架構,如下圖:

如果你關注人類文明演化史,你會發現今天的人類世界也是以分層方式一層層搭建和演化出來的。今天的互聯網系統可以認爲是現代文明的一個層次,其上是基於互聯網的現代商業,其下是現代電子工業基礎設施,諸如此類。

三、分治思維


分而治之(divide and combine或者split and merge)也是應對和管理複雜性的一般性方法,下圖展示一個分治的思維流程:

 

對於一個無法一次解決的大問題,我們會先把大問題分解成若干個子問題,如果子問題還無法直接解決,則繼續分解成子子問題,直到可以直接解決的程度,這個是分解(divide)的過程;然後將子子問題的解組合拼裝成子問題的解,再將子問題的解組合拼裝成原問題的解,這個是組合(combine)的過程。

面試時爲了考察候選人的分治思維,我經常會面一個分治題:給你一臺8G內存/500G磁盤空間的普通電腦,如何對一個100G的大文件進行排序?假定文件中都是字符串記錄,一行約100個字符。

這是一個典型的分治問題,100G的大文件肯定無法一次加載到內存直接排序,所以需要先切分成若干小問題來解決。那麼8G內存的計算機一次大概能排多大的數據量,可以在有限的時間內排完呢?也就是100G的大文件要怎麼切法,切成多少份比較合適?這個是考察候選人的時間空間複雜度估算能力,需要一定的計算機組織和算法功底,也需要一定實戰經驗和sense。實際上8G內存的話,操作系統要用掉一部分,如果用Java開發排序程序,大致JVM可用2~4G內存,基於一般的經驗值,一次排1G左右的數據應該沒有問題(我實際在計算機上幹過1G數據的排序,是OK的)。所以100G的文件需要先切分成100份,每份1G,這樣每個子文件可以直接加載到內存進行排序。對於1G數據量的字符串排序,採用Java裏頭提供的快速排序算法是比較合適的。

好,經過有限時間的排序(取決於計算機性能,快的一天內能排完),假定100個1G的文件都已經排好了,相當於現在硬盤上有100個已經排好序的文件,但是我們最終需要的是一個排好序的文件,下面該怎麼做?這個時候我們需要把已經解決的子問題組合起來,合併成我們需要的最終結果文件。這個時候該採用什麼算法呢?這裏考察候選人對外排序和歸併排序算法的掌握程度,我們可以將100個排好序的文件進行兩兩歸併排序,這樣不斷重複,我們就會得到50個排好序的文件,每個大小是2G。然後再兩兩歸併,不斷重複,直到最後兩個文件歸併成目標文件,這個文件就是100G並且是排好序的。因爲是外排序+歸併排序,每次只需要讀取當前索引指向的文件記錄到內存,進行比較,小的那個輸出到目標文件,內存佔用極少。另外,上面的算法是兩路歸併,也可以採用多路歸併,甚至是採用堆排序進行優化,但是總體分治思路沒有變化。

總體上這是一個非常好的面試題,除了考察候選人的分治思維之外,還考察對各種排序算法(快排,外排序,歸併排序,堆排序)的理解,計算的時間空間複雜度估算,計算機的內外存特性和組織,文件操作等等。實際上能完全回答清楚這個問題的候選人極少,如果有幸被我面到一個,我會如獲至寶,因爲這個人有成長爲優秀架構師的潛質。

另外,遞歸也是一種特殊的分治技術,掌握遞歸技術的開發人員,相當於掌握了一種強大的編程武器,可以解決一些一般開發人員無法解決的問題。比方說最近我的團隊在研發一款新的服務框架,其中包括契約解析器(parser),代碼生產器(code generator),序列化器(serializer)等組件,裏頭大量需要用到遞歸的思維和技術,沒有這個思維的開發人員就幹不了這個事情。所以我在面試候選人的時候,一般都會出遞歸相關的編程題,考察候選人的遞歸思維。

大自然中遞歸結構比比皆是,如下圖,大家有興趣不妨思考,大自然通過遞歸給我們人類何種啓示?

 

 

 

四、演化思維


社區裏頭經常有人在討論:架構是設計出來的?還是演化出來的?我個人基於十多年的經驗認爲,架構既是設計出來的,同時也是演化出來的,對於互聯網系統,基本上可以說是三分設計,七分演化,而且是在設計中演化,在演化中設計,一個不斷迭代的過程。

在互聯網軟件系統的整個生命週期過程中,前期的設計和開發大致只佔三分,在後面的七分時間裏,架構師需要根據用戶的反饋對架構進行不斷的調整。我認爲架構師除了要利用自身的架構設計能力,同時也要學會藉助用戶反饋和進化的力量,推動架構的持續演進,這個就是演化式架構思維。

當然一開始的架構設計非常重要,架構定系統基本就成型了,不容馬虎。同時,優秀的架構師深知,能夠不斷應對環境變化的系統,纔是有生命力的系統,架構的好壞,很大部分取決於它應對變化的靈活性。所以具有演化式思維的架構師,能夠在一開始設計時就考慮到後續架構的演化特性,並且將靈活應對變化的能力作爲架構設計的主要考量。

當前,社區正在興起一種新的架構方法學~演化式架構,微服務架構就是一種典型的演化式架構,它能夠快速響應市場用戶需求的變化,而單塊架構就缺乏這種靈活性。馬丁·福樂曾經在其博客上給出過一張微服務架構的演化路線圖[附錄8.2],可以用來解釋設計式思維和演化式思維的差異,如下圖所示:

 

上面的路線是一開始就直奔微服務架構,其實背後體現的是設計式架構的思維,認爲架構師可以完全設計整個系統和它的演化方向。馬丁認爲這種做法風險非常高,一個是成本高昂,另外一個是剛開始架構師對業務域理解不深,無法清晰劃分領域邊界,開發出來的系統很可能無法滿足用戶需求。

下面的路線是從單塊架構開始,隨着架構師對業務域理解的不斷深入,也隨着業務和團隊規模的不斷擴大,漸進式地把單塊架構拆分成微服務架構的思路,這就是演化式架構的思維。如果你觀察現實世界中一些互聯網公司(例如eBay,阿里,Netflix等等)的系統架構,大部分走得都是演化式架構的路線。

下圖是建築的演化史,在每個階段,你可以看到設計的影子,但如果時間線拉得足夠長,演化的特性就出來了。

 

五、如何培養架構設計思維


良好的架構設計思維的培養,離不開工作中大量高質量項目的實戰鍛鍊,然後是平時的學習、思考和提煉總結。

另外,基本的架構設計思維,其實在我們大學計算機課程(比如數據結構和算法)中可以找到影子,只不過當時以學習爲主,問題域比較小和理想化。所以大學教育其實非常重要,基本的架構設計思維在那個時候就已經埋下種子,後面工程實踐中進一步消化和應用,隨着經驗的積累,我們能夠解決的問題域複雜性和規模逐漸變大,但基本的武器還是抽象、分層和分治等思維。

我認爲一個架構師的成長高度和他大學期間的思維習慣的養成關係密切。我所知道世界一流的互聯網公司,例如谷歌等,招聘工程師新人時,對數據結構和算法的要求可以用苛刻來形容,這個可以理解,谷歌級別公司要解決的問題都是超級複雜的,基本思維功底薄弱根本無法應對。

對於工作經驗<5年的工程師新手,如果你大學時代是屬於荒廢型的,建議工作之餘把相關課程再好好自學一把。個人推薦參考美國Berkeley大學的數據結構課程CS61B[附錄8.1]進行學習,對建立抽象編程思維非常有幫助,我本人在研究生階段自學過這門課程,現在回想起來確實受益匪淺,注意該課程中的所有Lab/Homework/Project都要實際動手做一遍,纔有好的效果。

 

 

我當年自學的是CS61B 2006秋季版的課程,上圖是課程Logo

對於演化設計思維,當前的大學教育其實培養很少,相反,當前大學教育大都採用脫離現實場景的簡化理想模型,有些還是固定答案的應試教學,這種方式會造成學生思維確定化,不利於培養演化式設計思維。我個人的體會,演化式設計思維更多在實際工作中通過實戰鍛鍊和培養。

結論

  1. 架構的本質是管理複雜性,抽象、分層、分治和演化思維是架構師征服複雜性的四種根本性武器。
  2. 掌握了抽象、分層、分治和演化這四種基本的武器,你可以設計小到一個類,一個模塊,一個子系統,或者一箇中型的系統,也可以大到一個公司的基礎平臺架構,微服務架構,技術體系架構,甚至是組織架構,業務架構等等。
  3. 架構設計不是靜態的,而是動態演化的。只有能夠不斷應對環境變化的系統,纔是有生命力的系統。所以即使你掌握了抽象、分層和分治這三種基本思維,仍然需要演化式思維,在設計的同時,藉助反饋和進化的力量推動架構的持續演進。
  4. 架構師在關注技術,開發應用的同時,需要定期梳理自己的架構設計思維,積累時間長了,你看待世界事物的方式會發生根本性變化,你會發現我們生活其中的世界,其實也是在抽象、分層、分治和演化的基礎上構建起來的。另外架構設計思維的形成,會對你的系統架構設計能力產生重大影響。可以說對抽象、分層、分治和演化掌握的深度和靈活應用的水平,直接決定架構師所能解決問題域的複雜性和規模大小,是區分普通應用型架構師和平臺型/系統型架構師的一個分水嶺。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章