软件工程 1:软件危机
軟件工程第一課摘要
文章目錄
- 軟件工程第一課摘要
- 軟件工程
- 面向對象與面向過程
- 軟件危機
- 中間層抽象與具象化類比
?
軟件工程
編程是個非常適合自學成才的項目,我就是自學的。
很多人和我一樣不是科班出身,自學編程技術,也容易找到一個程序員的職位,甚至還可以自己開發一個小軟件。
但僅限于 小 軟件,比如您可以自己寫一個電子郵件客戶端程序,或者寫一個視頻編輯工具。
可是如果要開發一個超大型軟件,其中涉及到的學問,可就不是自學所能達到的了,那是需要在重大項目的實踐中去領悟和提高的。
自學也許可以讓您成為一個優秀的俠客,而偉大的將帥,則只能用千萬士兵的鮮血鑄就。
在計算機科學里,軟件工程這一部分,對計算機科學家來說太難了。
不了解軟件工程,您就不知道什么叫“大”,什么叫“復雜”。
中國有很多這樣的厲害人物,是手機 APP 開發大國,有很多超大型企業,有全世界最長的跨海大橋,卻沒有沒有屬于自己的計算機操作系統、國產芯片…
因為這些事兒,跟現代軟件工程相比,還只能算是簡單的事兒。
現代主流操作系統,包括 Windows, Mac 和 Linux,各自都有接近一億行代碼,而且大致 確保了不出問題(其實有五個方面的要求,不過簡單起見總結為一個)。
代碼每多一個量級,維護難度系數會不呈比例的指數上升。
漢朝的時候,是8000個人養一個公務員;唐朝,3000個人養一個公務員;明朝2000人養一個;到了清朝是1000人養一個公務員 —— 而今天的中國,則是18個人養一個公務員!
大了、就是不一樣。
我研究了身邊一些很聰明的人,發現他們聰明是因為工具很多,一個工具不行就換一個,所以解決問題會更多、會更好。
如果您只會兩個視角,那您就只有一對連接。而如果您會5個視角,理論上您一共可以有 5×4/2 = 10 個連接 —— 相當于五個點兩兩之間都連一條線:
您要是有 10 個視角,就可以有 10×9/2=45 個連接。
因為視角的這個超加性,多樣性的好處會不成比例的增加。
這個工具其實是思考工具,像哲學家、科學家這方面的工具特別的多。
那么我們再面對一個問題時,我們能否也變得像TA們一樣的聰明???
當然可以啦,思想可以學習,方法可以模仿。
工具隨時可以獲取。比如,我喜歡讀一些神作,他們不僅讀的爽,還有一個行業的底層邏輯。
| 圖論 | 多對多的網絡關系 | 計算機課程 |
| 線代 | 一組數字研究世界 | 計算機課程 |
| 經濟學 | 國師問道 | 商科 |
| 金融 | 百姓之道 | 商科 |
| 絕命毒師 | 完整的毒品犯罪鏈 | 電影 |
| 億萬 | 對沖基金的運作原理 | 電影 |
| 心理學 | 自信+熱情 | 通識教育 |
| 親密關系 | 愛的能力 | 通識教育 |
長期下來,越來越多樣化,視角、意趣都多了很多。積累到了一定程度,就發現,多了就是不一樣。
而軟件工程的底層邏輯,可以說是工程管理和綜合治理手段的極限。
小軟件和大軟件的根本區別在于尺度,以前一個小軟件只有幾千行代碼,現在一個大軟件要有幾百萬行代碼。
以前的軟件是給一個人用,現在是多個用戶共同使用一個軟件;更重要的一點是,以前的軟件是一個人或者幾個人開發的,現在則是大型團隊一起開發。
計算機思想家弗瑞德里克·布魯克斯(Fred Brooks),曾經在上世紀六十年代末率領 IBM 公司 300 人的團隊開發操作系統。
他做完這件事之后很有感觸,為此專門寫了一本書,叫《人月神話》。
布魯克斯提出兩個感慨:
- 1 個人干 12 個月的活,絕對不是 12 個人在 1 個月內能干完的。項目用的程序員越多,平均每個人出活的速度就越慢。所以您規劃項目的時候不要算什么“人月”。
- 您這個團隊做出來的軟件的結構,往往和您這個團隊的人員組織管理結構高度相似。 所以軟件工程不但要管項目,還要管人。
布魯克斯這本書出來,人們才充分認識到軟件工程的難度。
?
面向對象與面向過程
面向過程:OOP,分析問題的解決步驟,而后用 函數 把步驟按順序一一實現并調用即可。
面向對象:POP,把構成問題的事務分解為各種對象,而建立對象的目的不是為了完成一個一個的步驟,而是描述某個事務在解決整個問題過程中發生的行為。
對于剛剛學完 C 的小白來說,面向對象的思想和思想可謂有點復雜。
如果把 倆個思想 “類比” 到一句話里面,異同就會十分明顯。
另外,我習慣英文縮寫,這樣傳遞的信息十分簡短方便,全稱百度。
e.g. 下雨的時候,人們為了防止被雨淋濕打開了雨傘??。
面向過程解析:
-
過程是:下雨了,打開傘,擋雨。過程都是動詞哦。
-
編碼實現:fall(),open(),prevent(),這 3 個函數一一對應上行的步驟如 fall() 代表下雨。
面向對象解析:
- 對象:我 、傘、 雨,都是名詞。
- 編碼實現:me,umbrella,rain。對象都是名詞呀。
對象有自己的行為:我可以打開傘、傘可以擋雨、雨可以蹦極。
再以實際情況安排對象行為的順序:雨下,我打開傘,傘擋雨。
- 編碼實現:rain.fall(),me.open(),umbrella.prevent()
因此,面向過程是 把問題分解為若干個步驟,每個步驟實現為一個函數,按照順序實現并在調用時傳遞數據給函數解答問題。
面向對象是 抽象出問題的各種對象,把數據和解決問題的方法封裝在對象中,而后各個對象之間通過行為實現解答問題。
練習:試著用面向對象的思想重寫下圖:
?
軟件危機
早期的編程語言,如 匯編語言、只有0和1的機器語言,本質上是面向機器編程。
那個時代里,活著的年輕人們重新思考了軟件編程的認知。
他們開始認為編程的設計應該以人為本,開發了許多比較符合人類習慣和邏輯思維的語句。
就是CPU的指令集,要想讓CPU工作,必須借助特定的指令。
- add 用于加法運算
- sub 用于除法運算
- cmp 用于比較兩個數的大小
但CPU指令集(匯編語言)還是比較抽象,人們有了一個自然的需求,能不能按照人容易理解的思維寫程序后把寫出來的程序自動翻譯成機器語言呢 ?
后來,計算機科學家們發現所有程序可以化為三種結構構成:順序結構、分支結構和循環結構。
- 如果…就… if…else
- 循環 while
- 去哪里 goto
這就是所謂高級編程語言,正是這使他們擺脫了對計算指令的束縛,使用人類語言代替了機器語言。
這樣的語言關注邏輯處理過程,所以也被稱為面向過程、面向人的、面向程序員的編程語言,比如 Fortran、C。
高級編程語言的普及極大地釋放了程序員的自主性,軟件開發迎來黃金時期,程序員的第一個極客時代到來,比爾·蓋茨、喬布斯都是在那個時代成長起來的。
他們將常用、好用的代碼 封裝 起來,重復使用。編程語言的庫函數具有標準化的輸入和輸出,程序員下次再用的時候只需要照顧好輸入輸出,而不必關心函數內部是什么情形 —— 這就能大大降低出錯的概率和提高編程的效率。
1957 年,Fortran 語言被發明了,這是一個科學計算語言,特點是特別容易寫公式。
1958 年,LISP 語言出現,這是一個極其強大的符號處理和邏輯運算語言,甚至可以用于人工智能設計。
1959 年,人們又發明了 COBOL 語言,用于商用數據庫編程。
要方便人們在一臺計算機上操作,您就得有賬號管理,得安排不同的程序同時運行,那么就得有操作系統,程序員就得有系統思維。
要想開發出來的軟件好用、可靠、容易維護,程序員就得有工程思維。
接下來還有了互聯網,程序員就需要網絡思維和安全思維。
再進一步,編程思想也在演化。
傳統編程語言是線程式的,程序員思維模式是操控計算機。
但是人的欲望是沒有止境的,人能做到的越多,想得到的也就越多,越來越龐大的軟件開發計劃被不斷地提了出來。
可面向過程的復雜性隨著軟件規模的膨脹以更快的速度膨脹(超加性)。
面向過程的軟件關注邏輯流程,更容易被設計成面條式程序,長長的過程調用執行,像一根面條。
而大型項目最后由這樣一根一根面條組成,就成了一個毛線團,最后誰也理不清了。
于是很多大型軟件的開發過程開始失控,最終以失敗告終,人們遇到了軟件危機。
軟件工程的問題不是每年能培養多少高水平程序員的問題,而是復雜性問題。
軟件危機使人們開始重新審視軟件編程這件事情的本質,除了一部分科學計算或者其他特定目的的軟件,大部分的軟件是為了解決現實世界的問題,企業的庫存管理、銀行的賬務處理等等。
所以,軟件編程的本質是程序員用代碼的方式使現實世界的事務運行在計算機上,計算機軟件是為了解決現實世界的問題而開發出來的,那么軟件編程這件事情應該關注的重點是客觀世界的事物本身,而不是程序員的思維方式或者計算機的指令。
如果軟件編程的重點是客觀世界的事物本身,那么編程語言如何才能更好地滿足這一需求?
于是,面向對象的編程語言應運而生。
面向對象編程以對象作為軟件編程的基本單位,提出一切皆對象,客觀世界的用戶、賬號、商品是對象;創建、組合、關聯這些對象的工廠、適配器、觀察者也是對象;將所有這些對象分析、設計、開發出來,一個軟件系統就完成了,這個軟件系統靈活、強大,最重要的是可以根據需求變化快速更新維護。
面向對象編程似乎已經進化到編程這件事情哲學意義上的終點,是編程語言的終極形態。
現實看起來也確實如此,最近三十年誕生的編程語言幾乎全部都是面向對象的編程語言,面向對象一統天下。
但事實真的如此嗎?
回望歷史我們站在上帝視角,一切都是如此清晰充滿條理,凝望未來,我們還能如此篤定嗎?
情況也許并非如此。
事實上,現實中的面向對象編程幾乎從未實現人們期望中的面向對象編程。
這有人的原因,也有編程語言的原因…
而隨著科技的不斷發展,特別是大數據,人工智能以及移動互聯網的發展,面向數據的編程需求越來越多,能夠更好迎合這一需求的編程模型開始得到青睞,比如函數式編程。
而極客型的程序員對強類型的面向對象編程越來越不感冒,他們希望在編程的時候能夠得到更多的自由,編程語言的重心似乎重新出現面向程序員的趨勢。
隨著計算機性能的不斷增強,以及互聯網應用對計算資源需求的不斷增加,如何更好地利用 CPU 的多核以及分布式集群的多服務器特性,必須是軟件編程以及架構設計時需要考慮的重要問題,軟件編程越來越多需要考慮機器本身,相對應的,反應式編程得到越來越多的關注。
我們都在時代里,而時代是在螺旋式的上升…
P.S. 其實不止 C++、Python、java 等編程語言可以實現面向對象的機制,C 語言一樣可以,在 Linux 內核源代碼里應用廣泛啊。如果有想法,可以看看《Object-Oriented Programming With ANSI-C》(用C實現面向對象的各種機制)。
?
中間層抽象與具象化類比
在計算機中,為了讓操作更加直觀、易于理解、增強用戶體驗,開發者經常會使用一件法寶——增加中間層,即使用一種間接的方式來屏蔽復雜的底層細節,只給用戶提供簡單的接口。
實際上,計算機的整個發展過程就是不斷引入新的中間層:
-
計算機的早期,程序都是直接運行在硬件之上,自己負責硬件的管理工作;程序員也使用二進制進行編程,需要處理各種邊界條件和安全問題。
-
后來人們不能忍受了,于是開發出了操作系統,讓它來管理各種硬件,同時發明了匯編語言,減輕程序員的負擔。
-
隨著軟件規模的不斷增大,使用匯編語言編程開始變得捉襟見肘,不僅學習成本高,開發效率也很低,于是C語言誕生了。C語言編譯器先將C代碼翻譯為匯編代碼,再由匯編器將匯編代碼翻譯成機器指令。
-
隨著計算機的發展,硬件越來越強大,軟件越來越復雜,人們又不滿足于使用C語言了,于是 C++、Java、C#、PHP 等現代化的編程語言誕生了。
從具象到抽象化并傳承這些抽象的知識、經驗,是人與其他動物最大的區別。
一個領域的知識如果不斷地深入發展,都有同一個趨勢,那就是從具象化到抽象化。
作為程序里,我們經常要使用:類、抽象類、接口 這些抽象概念。
進步想,程序本身也是對現實世界的抽象。
程序可以實現對現實世界的高度模擬,制造出許多的“世界”。
再進一步,我們所在的現實世界也無法被自然語言精確描述。
作為普通人,想要更精確的理解世界,抽象思維是不可或缺的。
首先,抽象思維能讓您認識到事物的本質。
高手,要善于發現各種看似不一樣的事物背后的共同點。
而后使用類比,對現實的抽象,抽象的好,就形成了事物的模型。然后,匹配模型。
從前醫生們面對一個問題,束手無策。
有一種射線,只要以一定的強度照射在腫瘤上,就能把腫瘤給殺死,等于是可以用來治療癌癥。 現在問題在于,射線到達腫瘤之前肯定會先接觸到患者身體的其他組織,那就會把好的組織也給殺死。 可是如果把射線強度調低一點,好的組織能不被傷害,可是對腫瘤就也沒用了。 那有沒有一個什么辦法,不用做手術開刀,既能讓射線殺死腫瘤,又不會傷害其他組織呢?
就設計而言,這個答案本身并不重要,我們關心的是尋找答案過程中使用的思維方式。
這個方法就是 “類比”,用類比解決問題,是把一個領域的思想,運用到另一個領域中去。
分享一個故事:
從前有一個將軍,要攻打一座城。 攻城需要很多士兵同時發動進攻才好。 可是這座城周圍的道路都很窄小,并不適合大軍通過。 這怎么辦呢? 將軍知道通往這座城的道路有很多條,于是他把士兵分散開,以小隊的形式從不同的道路出發,按照約定時間一起到達。 結果就把城給攻下來了。
類比解決問題,是把一個領域的思想,運用到另一個領域中去。
上面答案是用若干束低強度的射線從不同的方向照射腫瘤。
因為射線強度不高,所以不會殺死途中路過的身體組織;而因為在腫瘤上匯聚的多個射線加起來的強度夠高,所以能殺死腫瘤。
這個原理就好像用放大鏡匯聚太陽光一樣……
其實這就是現在有不少醫院使用的“伽馬刀”。
那么,如何類比?
一般人看東西是關注不同點,而高手則善于發現兩個很不一樣的事物之間的相同點。
比如,下面這六件事情,您能不能把它們給分個類 ——
- 經濟泡沫
- 北極冰川融化
- 美聯儲調節利率
- 人的身體出汗
- 不同的商品相繼漲價
- 大腦指揮身體做動作
對美國西北大學的學生測試表明,如果是按照學科分,所有學生都能分的很好。
1、3、5 是經濟學問題,4、6 是生理問題,2 是自然環境問題。
但要是按照這些事情的內部機制分類,就只有少數有跨界學習經歷的學生能分好。
- 事實上 1 和 2 都是正反饋現象(買東西的人越多經濟越好,經濟越好買東西的人越多;
- 冰川越融化吸收陽光越多,吸收陽光越多冰川越融化),
- 3 和 4 都是負反饋現象(美聯儲加息防止經濟過熱;皮膚出汗防止身體過熱),
- 5 和 6 都是連鎖信號傳遞(石油漲價導致日用品漲價;大腦神經信號傳遞到四肢)。
能看出這種深層思維結構,才談得上舉一反三。
類比的就一定對嗎?
類比有可能犯錯誤,引起爭議 —— 用諸葛亮教育劉禪的話說,就是“引喻失義”。
類比思維的規律是,您能想到的類比越多,您的判斷就會越準確;您能想到的類比越遙遠,您出的主意就會越有創造性。
高手聽人講什么東西的時候,會在頭腦中畫一個東西:您一說四根柱子,他就畫了一座大樓。您繼續講更多的內容,他就不斷調整和補充頭腦里這個東西。您講完了,他就會發現這個東西哪里似乎不怎么平,哪里似乎還沒完成,哪里似乎還可以往外延伸,哪里似乎可以跟他熟悉的什么東西連接起來,他還可能發現整個這個東西跟另一個東西很像。他眼中簡直到處都是問題。
說白了,這也是類比和聯想。
總之,類比是一個非常有用的思維方式。
在思維方法層面,具體分為:
- 具體類比:以事件之間具體特征相比,尋找新理解;
- 情感類比:將事物人格化,在感性層突破習慣認知,提煉新方法;
- 抽象類比:在詞語和概念維度相比,極易出錯,以高層原則維護;
- 非現實類比:借幻想和超現實概念與現實問題相融,升級認知;如三體衍生術語。
類比可以讓我們舉一反三,類比可以啟發我們創造新事物,類比可以讓我們審視自己和別人的原則,類比可以幫助我們發現各方的分歧所在,類比可以幫助交流思想……類比的背后,是高級的抽象思維。
?
復盤:
文章目錄
- 軟件工程第一課摘要
- 軟件工程
- 面向對象與面向過程
- 軟件危機
- 中間層抽象與具象化類比
總結
以上是生活随笔為你收集整理的软件工程 1:软件危机的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于openGL加载贴图纹理映射中Unk
- 下一篇: sping 注解