連載36:軟件體系設計新方向:數學抽象、設計模式、系統架構與方案設計(簡化版)(袁曉河著)

線性化機制

 

線性關係:

兩個變量之間存在一次方函數關係,就稱它們之間存在線性關係。正比例關係是線性關係中的特例,反比例關係不是線性關係。更通俗一點講,如果把這兩個變量分別作爲點的橫座標與縱座標,其圖象是平面上的一條直線,則這兩個變量之間的關係就是線性關係。即如果可以用一個二元一次方程來表達兩個變量之間關係的話,這兩個變量之間的關係稱爲線性關係,因而,二元一次方程也稱爲線性方程。推而廣之,含有n個變量的一次方程,也稱爲n元線性方程,不過這已經與直線沒有什麼關係了。

線性理論是目前數學領域研究的最爲成熟的理論之一,特別在數學應用上具有完整的研究和應用,然而對於軟件設計來說,我們雖然一直在不斷使用,但是卻一直沒有更抽象的描述出來,很長時間內我們忽略了這個重要的機制,而本章就拋磚引玉從一些設計的事例中去窺探線性化機制在軟件設計中的意義,也許能夠讓你大吃一驚的!

 

表驅動

 

首先讓我們來看看錶驅動方法,表驅動方法是一種使你可以在表中查找信息,而不必用很多的邏輯語句(ifCase)來把它們找出來的方法。事實上,任何信息都可以通過表來挑選。在簡單的情況下,邏輯語句往往更簡單而且更直接(來自網絡的定義)。

使用表羣動機制有什麼優勢呢?其實我們這裏講一段代碼上的邏輯轉換爲對一個整齊劃一的數據進行操作,通過統一的操作,讓我們的代碼變得立刻清爽起來,而且我們可以通過對數據的排列組合的處理達到對程序邏輯的更改,這種方式的變革成本是很低的。

而對於表羣動機制來說,難點是如何將這些整齊劃一,如何提取其共性讓之達到整齊劃一是關鍵。

我們可以將表驅動看着組合的一種擴展,表驅動具有這樣的特質,其表中成員的可以根據實際情況進行任意組合的。這可能與繼承有點背道而馳,但是我們應該明白,繼承中其實也可以通過表驅動的方式來達到組合這樣的處理,這是因爲接口等概念其實也是將一個繼承體系進行“整齊劃一”的功能。所以,通過表驅動將這兩個不同方面結合在一起。

由於接口具有這樣的表驅動的的特徵,所以在我們的設計模式中,比如工廠模式中就可以進一步改造,將不同的產品經過表的方式進行統一的處理。對於觀察者模式來說,也是通過接口的表驅動特徵將不同的觀察者通過表進行註冊和註銷,而被觀察的主體不需要區分具體的觀察者類,所以能夠更好的達到統一操作。

表羣動機制可以應用於低層次的代碼行間,也可以用於宏大的整體架構。我們使用的最大最成功的表羣動機制就是關係型數據的典型應用,在關係型數據庫中將數據通過規則的放置到不同字段中,然後在此基礎上定義一系列獨立於數據的增刪查改等一系列操作,然後將這些操作使用SQL語句形成獨立的語言,這樣我們讓數據庫的設計和程序的設計進行有效的分離,兩個獨立進行演化和變化。

那麼從關係型數據庫的發展我們可以看出,在程序中的表驅動機制其實還有更好的處理優化空間,例如可以借用數據庫中創建索引的方式來進行高效的訪問,表中按照更高範式進行處理,則數據之間的關係會更加分離。這裏不僅僅讓我們的程序和數據進行有效的分離,同時讓不同數據之間進行分離,這些分離其實就是分離數據與數據之間的耦合關係,讓這些耦合關係通過操作算法來進行連接,這其實又讓一定的耦合處理移交給程序來處理,注意這裏的程序就是一些獨立的程序(例如SQL語句)。所以讓數據庫中的表達到什麼樣的範式也是挺講究的,不僅僅和效率有關,同時在耦合性方面和複雜程度來看也是需要謹慎處理的。

當然,在程序中實現表驅動可以不用完全按照關係數據的基本要求來進行處理。例如數據庫中的表中無表的最基本要求。在程序中可以具有表中嵌表的處理。所以關係型數據庫的設計思想是更特殊化的一種表驅動機制的實現。

在跳轉條件比較複雜,數目較多的情況下,並且在採用非狀態機實現時,設計會變得很復時,使用狀態機實際,會簡化系統的設計,提高代碼的質量與可靠性。

在跳轉比較簡單,數目較少的情況下,並且整個系統也比較容易使用非狀態機實現的情況下,使用狀態機設計,會增加資源的開銷(主要在組合邏輯資源上),並且代碼量也比較大。

需求是逐漸增加,系統是越來越複雜,修改成本,升級成本等等原因,什麼時候是從無狀態機向有狀態機設計的時機呢?所以對於接口,最好不體現狀態機(不體現狀態)因爲這會增加升級的失敗率和成本,無狀態接口是解除相互之間的耦合的比較好的方式。

狀態自動傳遞優點:

ü 對象間依賴關係是固定的,不需要修改就能支持今後需求。

ü 對象間依賴關係被隱藏在對象內部,不必暴露給外部。

ü 易於實現相關對象狀態的一致性。

ü 降低應用開發難度,外部故障只需要通知直接相關的對象即可,內部在根據依賴關係自動將狀態傳送到全部相關對象。

狀態遷移表:創建一個描述遷移的數據表,該表被一個處理事件的引擎解釋,引擎查找與事件相匹配的遷移,調用相應的工作,並更改狀態,好處是狀態機的邏輯全部集中在一個地方並沒有被動作實現污染,維護比較容易,可以容易的在運行時改變遷移表,其主要確定是速度,對於較大的狀態機來說,遍歷表的時間相當長,其次是需要寫很多額外的代碼來維護遷移表。

表實現狀態機和state模式的區別:state模式對與狀態相關的行爲進行建模,而表驅動的方法着重於定義狀態轉換。

從另一個更加深入的研究我們知道:表驅動機制其實就是數學中的線性代數,我們應用表驅動的方法將我們的處理業務完全的線性化的處理。其理論來源就是表驅動的處理過程是將一些非主要特徵進行忽略或去除,然後將主要特徵進行整齊劃一,而這個過程就是將系統線性化的處理過程。經過線性化處理後的數據,在既定的規則中是不具有本質的區別,只是一些數據取值的不同表示,所以才能將這些元素裝入一個表中進行保存。

 

線性化的特點

 

那麼線性化處理在系統科學中有什麼好處呢?這些好處對於我們的設計思想有什麼更加好的提示和幫助呢?

首先,線性具有加和性,這種加和性的意義就是:線性關心表示互不相干的獨立作用,例如將AB同時作用於系統,等於他們分別作用於系統之和,不會因爲AB同時輸入的相互影響而產生相干(聯合)效應,不會在A+B以外有所增益或損耗。

而軟件設計中追求的低耦合高聚合特性,對於表羣動機制,或者說線性代數的疊加性來說,不是完美的一致嗎?所以是否能夠讓我們程序進行線性化也就成了我們解耦的一個方向,換句話說,如果我們讓我們的程序代碼線性化了,那麼我們的解耦也達到一定的成果和層次。

其次具有齊次性,齊次性不是加和性的簡單擴展,齊次性意味如果在系統中將輸入倍化,輸出也將同樣的倍化,不會發生定性的、結構性的質變。

對於加和性和齊次性等疊加特性來說,對於我們的代碼在性能方面也是一個非常好的基礎,由於系統之中的不會產生相干效應,同時不會更改其性質和結構,不會發生不可預知的質的變更,所以就適用於大規模的並行處理,所以在大數據處理中,更加有效的將線性方式的融入將更加有助於進行大規模的並行設計和開發。

但是我們要注意,線性的這種疊加性只能滿足有限的疊加和,而不能推廣到無線的疊加和,同時這些疊加是在某一個層次上的疊加,而不能超越層次進行疊加,所以在我們的不同置換層面上,由於其基礎不一致,有些是基礎,而有些是涌現以後的結果,兩者疊加就是“牛頭不對馬嘴”了。

當然我們在檢測是否是線性中的疊加,我們有可用通過不同數量級別的多個輸入和輸出來判斷是否是線性增加,所以其檢測方法也是清晰明瞭的。

當然在上面我們提到關係數據庫是線性的一個絕好的例子,那爲什麼目前我們在處理大數據的時候還在去SQL呢?這裏大家需要注意:部分的線性不等於整體的線性,我們的線性系統只是從一個系統中抽離出線性的特徵,而對於整體系統來說,肯定存在非線性的原因。我們不能將所有線性部分進行相加,就得到整體線性,部分的線性在質上是不同的,關注點是不一樣的。雖然可能同時線性,但是領域不同,線性具體體現方式不同,不能將這些進行簡單相加。

SQL語句中主要的操作包括:選擇、投影、連接、並、交、差、增加、刪除、修改、查詢等操作這些操作主要是體現在對集合和對數據的操作行爲。上面談到關係型數據庫不是一種線性化的處理操作,那爲什麼沒有線性代數中的一些運算呢?例如內積、外積、矩陣變換、行列式運算、求秩、求逆等等運算呢?這主要是目前我們的SQL操作還只是針對每一條記錄進行的運算,這些記錄和記錄之間存在的相互關係還沒有進一步獲得處理。如果能夠建立這些記錄和記錄之間的關係(例如內積,可判斷其相似程度)那麼我們就可以將這些運算擴展到關係數據庫的運算之中。而這也是目前進行大數據挖掘、人工智能方面的研究領域。同時,此時一條記錄就可以看待成一個向量,多個向量之間進行聚集形成一類或者一個領域,在數學上就是一個矩陣,通過矩陣中的記錄進行數值化,就可以進行一系列的線性代數的運算。

在系統中,我們也可以通過線性迴歸針對不同的變量進行線性化處理,這裏主要涉及的是在進行量化一個複雜系統中的有效的處理方法。雖然針對軟件設計來說其幫助不是很大,但是對於系統分析來說,意義非凡。

 

線性化的現實難度

 

當然,表驅動也面臨重重困難,其也有自身的限制和所適應的環境。這裏主要體現在以下的一些方面:

非線性特徵很強,在處理環境中很難進行線性化的處理。實際上能夠進行線性化的場景不是很普遍,因爲現實場景中真正具有線性的區間非常的少,在圖形中,線性代表的是一些直線的處理,只要涉及到曲線和具有斷點的直線或者直線組合在進行線性化處理的過程就非常複雜,往往在使用了線性處理以後,反而無法適應非線性的變化。在軟件設計方面,從大數據的分析就可見一斑,爲什麼大數據很難使用關係型數據表來表示呢?就是因爲數據與數據之間很多都是非線性的,具有在不同層次上的關係,而且對應關係都不僅僅侷限於函數中的一對一、多對一的關係,而是多對多的關係,這樣的關係首先體現的就是多值函數的領域,就更不用說是可以進行近似的線性處理。所以,對於能夠進行線性處理或者線性近似的地方一定使用表驅動,如果脫離了場景,則一定要規避線性化的衝動。

很難一次性的考慮所有的變化因素,軟件設計過程中,永遠無法準確預測未來的變化,所以也不能一次性的將所有變化因素完全考慮。在進行線性化設計過程中,由於是進行有限的近似處理,所以有很多因素我們認爲將來可以忽略不計,但是往往計劃趕不上變化。將來這個忽略因素很可能成爲主要的原因,此時就容易導致原有設計的崩潰。在關係型數據庫的設計中也處處出現這樣的情況,最簡單的就是新增或者刪除一列,還有變化最猛烈的是此表設計跟不上變化,需要變更此表和其他表的關係。而這對於系統的兼容性、系統升級以及維護都帶來無法估量的風險。

不合理的表驅動反而畫蛇添足,在進行整齊劃一的過程中,有時候容易將數據分裂成不合理的一些組合關係,此時數據反而被肢解破碎,無法通過數據之間的關係來代替算法邏輯。或者由於設計不足導致數據本身沒有在形式上的整齊劃一,而導致不得不在算法上進行一些特殊的處理,所以,進行有效的表驅動設計還是一個“技術活”,需要對本系統或者本特性有比較深入的理解以後才能進行更好的設計。

線性關係本身的特徵導致了其在此進行相加也不會更改事物的本質,這是一個優點也是一個缺點,對於一些需要通過組合變化涌現新特徵的環境就不能設計成表驅動的處理,例如一些人工智能、數據檢索等系統中,此時雖然可以將某一個部分進行線性化,但是整體上需要經過不斷的反饋機制以及非線性的處理來完成其發生質變。

從上面可以看出分離程序和數據的表驅動是如此優秀,能夠給人一興奮的感覺。然而,我們追根溯源到線性化這一本質特徵,感覺依然意猶未盡。是的,其實不僅僅是表驅動的應用,對於系統本身,其實也是可以進行線性化的手法來進優化我們的系統。

在系統裏面,爲了更好的規整我們的系統,也常常採用線性化的處理。最直接的設計模式就是“過濾器”模式。在過濾器模式中,將其輸入和輸出進行規範化(一般採用的方法是繼承同一個接口),然後再講這些過濾器掛接在一起,而只是對輸入和輸出的規範化就是一種線性化的處理。這樣無論掛接多少過濾器都是線性疊加的,不會隨着過濾器的增加而發生質的變化。同時,過濾器之間也是相互獨立,不會由於其他過濾器的引入而發生耦合。所以過濾器模式是一種耦合性很低的架構模式。

在泛型化編程中,迭代器就體現了通過訪問形式來完成對不同數據結構體進行的線性化訪問的處理,迭代器按照訪問方式不同劃分爲:前向迭代器、索引迭代器、雙向迭代器、隨機訪問迭代器,雖然這些迭代器根據不同容器結構劃分成不同的類型,但是,這些迭代器是將訪問方式進行線性化的統一,通過線性化的處理保證使用者只依賴於線性化方式,而不依賴於特殊化的處理(例如對樹或圖的不同訪問方式)。然而,爲了滿足迭代器的處理操作,必須滿足不同種類迭代器的操作符的重載處理,然而針對樹或者圖這樣複雜的處理時候,不同的算法卻又決定了訪問的順序以及是否能否訪問等一系列問題。

通過正交分解來解決耦合,正交化分解是解決耦合的一種極端的處理方式,其解耦以後帶來的效果也是煞是驚人的。因爲在不同的維度上,相互之間的耦合度爲0。而要達到正交分解的第一步就是將這些變量進行線性化,只有線性化後才能進行正交處理。

這裏我們也可以看到,線性化以後的組織有多種,反映到數據結構上,可以形成線性表也可以形成樹的結構,其實樹的節點也可以看做進行線性化處理的一個結果。

從上面可知,線性化處理後,我們其實正在進行一種分離的操作,就是將數據和操作進行分離,而此時這裏所謂的“數據”,在軟件設計的線性化過程中很多時候就是“代碼”,或者是置換的結構,這又反過來讓代碼數據化(這的確非常有意義,我們很多時候是將數據代碼化,例如大部分的算法),通過代碼的數據化過程以後,我們就可以實施上面中的線性化的數學抽象過程。

 

正交

 

正交化:

正交化是將屬於相同本徵值的沒有相互正交的函數重新線性組合爲新的相互正交的函數的過程。

矩陣的正交分解:

矩陣的正交分解是指A分解爲一個正交矩陣Q和一個對角可逆上三角矩陣R的乘積。

正交處理是一種線性化重新組合運算。正交化的結果就是產生特性之間的正交(數學的多維空間中爲“垂直”的相互關係,在向量的角度上,即兩個向量的內積爲0)。對於軟件開發來說,其相互耦合的兩個特性(對應數學中的向量),其相互之間的耦合降低到最小,這也是進行系統模塊化或者特性開發的最終目標。最近以來,有一種敏捷開發的實踐爲“特性開發”,其基本思想就是利用正交的結果將系統劃分成不同的特性,特性與特性之間相互獨立,對於每一個特性開發就是一個“小平臺”,而產品僅保持一個版本分支(即使在多個不同應用場景的產品系列),由此通過開發效率最高效的軟件工程方法來進行軟件版本管理。在這個實踐中其關鍵中的關鍵就是如何讓特性之間形成線性化的正交。其中目前所能支撐並現有的技術就是面向方面(又翻譯爲面向切面)的編程方法(AOP)。

面向方面編程- Aspect Oriented Programming(AOP),AOP主要實現的目的是針對業務處理過程中的切面進行提取,它所面對的是處理過程中的某個步驟或階段,以獲得邏輯過程中各部分之間低耦合性的隔離效果。

ü 接合點 (Joinpoint) — 代碼中定義明確的可識別的點。

ü 切點 (Pointcut) — 通過配置或編碼指定接合點的一種方法。

ü 通知 (Advice) — 表示需要執行交叉切割動作的一種方法

ü 混入 (Mixin) — 通過將一個類的實例混入目標類的實例引入新行爲。

應用AOP的主要目的----儘量分離“技術問題實現”和“業務問題實現”

ü 它允許開發者能夠對橫切關注點進行模塊化設計----“切面”的意義在於將業務邏輯中複雜問題分離成不同層面,使其實現統一集中的管理。

ü 能夠實現分散關注,將通用需求功能從不相關類之中分離出來。這樣將能夠更好地遵守“單一職責”原則;

ü 同時,能夠實現代碼重用。一旦行爲發生變化,不必修改很多類,只要修改共享的類。

面向切面編程其重要的意圖就是如何在面向對象(OOP)的基礎上如何更進一步使用線性化的處理機制。並且讓獨立處理的特性具有正交的屬性,所以,AOP所最爲成功的例子就是包括日誌、安全這樣的正交更爲徹底的業務的實現。當然AOP不僅僅侷限於線性化機制,其還包含有更多的技術,然而,如果無法做到線性化的正交處理,其面向切面編程一定爲不合理的設計方式。同時,從線性化的方面再加上我個人的意見來看,AOP還遠遠沒有更好的利用線性化的各種優勢特徵,在上面的線性化的數學抽象中我們也會看到其具有更多的技術特徵來應該不斷改造現在的設計和實現方法或技術。

 

線性化與非功能屬性

 

在進行了線性化處理以後,其系統的處理性能雖然可能不是最優,但是其性能也具有線性特徵,也就是可控或可衡量,在增加或者減少數據量的情況下,是滿足線性的量化關係。而且,線性化處理後進行優化也是具有簡單的優勢,例如我們可以進行一些簡單的修改就可以將計算放置到多線程、多核或者分佈式計算中進行處理,這樣讓整個處理變得流程化,能夠在此進行更強大的高併發處理,以此大大利用了資源而提高系統的性能。

同時,線性化與可擴展性、和可重用性的關係也變得非常簡單,只需要關係是否滿足線性規則,更多的耦合變化成爲數據與數據的先後順序,或者更有甚者連位置都變得不再重要。於是可以達到“任意”擴展和收縮,讓系統的耦合變成了數據之間的聯繫而不用在程序設計和實現進行考慮的巨大優勢。

另外,線性化與可配置的關係也變得非常簡單,配置變成了簡單的選擇或者不選擇的兩個操作,而且還可以在系統運行過程中,動態地進行配置而滿足實際的需求。而且可以在變更數據的情況下進行程序運行的配置,這也是線性化帶給我們的“絕佳”靈活性的影響。程序的運行不再依賴於靜態的代碼,而是根據數據的差異來決定,於是可以在數據層面上展開各種“特殊化”的處理,此在上面線性化的數學抽象章節就有“閃亮”的體現。

 

線性化與體系結構

 

馮諾依曼體系結構以及其在此基礎上進一步改進的哈佛體系結構,它們也同時展示線性化處理框架。在這些體系結構中,無論計算和尋址都是採用線性方式在處理。首先我們來看看其總線模型,總線是一組傳送線路以及相關的總線協議總和,總線首先經過線性規劃以後,通過不同的線性化地址信息(一般是基於分段化處理的地址信息),不同的設備只要能夠滿足接口的基本定義(物理電氣、時鐘等接口要求),就能夠掛接到這個總線上,由於是線性化的,所以不同設備之間不需要瞭解到其他掛接到總線的設備信息,所有的掛接設備都是獨立的,相互不相關,互不影響,所有的設備不需知道自己是如何控制的,可能是一個或者多個總線控制器控制和協調不同的設備,也可能爲了提高效率而採用AMD的設備來進行控制和協調。採用線性化處理能夠極大的提高併發處理,能夠極大簡化系統結構,讓系統結構在邏輯上非常清晰明瞭,並且具有充分的可擴展性。同時由於這樣的線性獨立特點,也直接應用到交換設備的不同分佈結構,而諸如星型、樹形拓撲結構都是通過建立在單條總線上的線性化結構而建立起的多維度的處理信息的能力,這樣達到對複雜情況(超越總線結構)的有效處理。

由於體系結構下的線性方式,所以在一些緩存處理過程中也體現了使用線性處理的特點,由於線性化對於系統分層有很多優勢,由此分層情況下就涉及到不同層次級別的數據設備如何能夠進行更高效的處理,由此緩存產生了,如果所緩存的數據按照線性化規則聚集,那麼可以通過數據的特徵值,成塊地將數據加載到緩存區,這樣能夠更加有效的提高訪問效率和命中率,反之,如果數據本身缺少線性化結構,那麼數據之間就存在更多的耦合,此時可能會在不同的條件分支中去訪問不同區域的數據,這樣就很難計算到底緩存那部分數據爲熱點數據,由此緩存的功效就降低。總的來說,使用線性化的數據可以讓我們的緩存策略變得更加容易,無論是導入還是髒數據導出,都會變得更加簡單。

 

線性化的優勢

 

線性化的物理意義主要滿足了在操作和管理成本最小化原則。就如同光線在空間傳播以最短路徑爲準則一樣,對於一個軟件設計來說,操作和管理成本最小化是一個極限趨近的準則體現。線性化的處理,在外部體現上就能夠因爲整齊劃一而降低其運作成本。通過線性化處理以後,我們能夠很容易在其操作上進行大規模的並行操作。例如在一些大型機的並行方案中的流水線處理方案中,首先將操作限定爲取指令、譯碼、執行三個不同的過程,所有的指令都遵守這樣的過程。如果所執行的指令的結果不需要不同流水線相互訪問,相互之間是獨立的線性關係,那麼我們就可以在此基礎上進行大規模的並行處理,而且不需要考慮執行過程中不需要考慮其中出現中斷也影響其他流水線的效率。這樣通過線性化處理以後其在時間上將會成倍的縮減,而且在很多時候,當不存在線性的情況下,比如我們將任務劃分的長度不均等,操作過程中流水線之間相互干擾,也需要通過線性規劃來進行近似的處理。

通過上面的一些簡單理解,我們將線性化的一些優勢進行總結:

ü 使用線性化有利於分層和分區域,無論在橫向或縱向方面使用線性化都會爲我們達到更好的分離處理,爲什麼使用線性化的方法就能夠更好的完成分層或分區域呢?最主要是目前在線性化處理方面的研究是最充分的,這些通過線性化分離的個體是更容易組合在一起。而且我們目前無論是馮諾依曼體系結構還是哈弗體系結構其實都是按照線性化機制來設計的,所以在這樣的系統中的軟件設計上使用線性化機制是自然而然的事情。

ü 有利於多種不同線性劃分共存一起而又無相互耦合,比如我們的段頁式的設計,兩種不同的線性處理辦法能夠非常融洽的共處,因爲線性方式就存在線性獨立性,而線性獨立性是目前所發現獨立程度最高的方式。

ü 有利於模塊化和組件化,由於耦合度最低,所以能夠更好的模塊組件這些特性,因此在更大更廣泛的系統設計中,能夠達到更加靈活的設計決策。這就好比通過規則的磚塊能夠架構高樓大廈一樣,如果採用非規則的結構,可能需要更大的成本來構建大廈了。

ü 有利於將處理的程序轉化爲數據進行處理,然後通過通用的處理方式來代替各種特殊的處理。這裏最好的例子就是數據庫的數據表,我們可以通過將數據進行線性化處理而在其上通用的處理(集合的處理),就能夠代替我們的程序進行判斷和分支的處理。

ü 有利於迭代化的處理,以及對其羣體的快速遍歷,通過線性化處理以後,其進行大規模的數據操作將會變得更加的高效,可以通過選擇不同特徵的迭代器進行統一的處理。

那麼與軟件設計相關的處理中,又有哪些方法和策略來進行線性規劃呢?或者說通過什麼方式來進行線性約束呢?

線性化方式由於相互關聯非常簡單,能夠進行很好的形態上的擴展,但是,線性化有一個比較致命的缺點就是執行效率,由於結構簡單,所以在提升效率方面不得不進行一些多餘的操作,或者給出一些冗餘的算法優化操作,例如,爲了能夠更好的進行查找,可能需要先對原始的線性數據進行一次排序,然後使用折半等讓人煩惱的算法來進行查找,而這恰恰違背了我們進行開發的一個準則:儘量使用合適的數據結構來代替我們採用精良的算法。因爲精良的算法很難具有高的適應性和有效的擴展性,如果能夠使用靜態的數據結構解決問題,則優先使用數據結構來解決,因爲這是靜態的方式,其複雜度不會跟隨運行進行動態變化,這樣滿足了另一個準則:如果能夠使用靜態方式完全能夠適應需求,那麼我們就優先採用靜態方式進行解決。

所以,如果發現線性化方式很難解決問題的時候,不妨使用循環線性表、樹結構、圖結構等來進行分析,或者分不同層次,不同步驟的方式來解決問題。

固然,線性化機制能夠很簡化我們的相關設計,但是對於由於在進行線性化處理過程中,就保留了我們認爲重要的關係,而忽略或者刪除了非重要的關係。但是,如果我們一開始就無法明確知道什麼是重要的關係,什麼又是非重要的關係的時候,使用線性化機制就會導致錯誤和失敗。例如,在一些大數據分析過程中,其數據與數據的相互關係,本來就隱含在大量的數據之中,在沒有進行分析之前,我們是無法判斷其準確的有效性,這就有點像粒子物理中的不確定性原理,所以我們只能通過對所有的數據按照一定的算法進行分析,最後才能給出一個更大概率成立的結論。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章