——讀《程式設計珠璣i》有感:
program.program better. program faster.
要從事軟體開發,首先要學會程式設計。如何程式設計呢?如何編寫更高效更優雅的程式呢?《程式設計珠璣》通過簡單而熟悉的示例,揭示了許多非常有益的程式設計原理和技巧,極具啟發性。
基本流程:
問題定義—— 應用框架與介面設計 —— 選擇合適的資料結構和高效的演算法(物件和訊息)—— 效能估計 —— 介面宣告 —— 偽** —— 程式驗證—— 編碼 —— 測試與除錯 —— [**優化]—— **重審和回顧。
問題定義:贏在起點。清晰明確的問題描述和定義幾乎決定成功的一半。作為問題求解,如何正確地理解問題,從何種視角去思考問題,往往會產生天壤之別的結果;作為軟體開發,「有所為而有所不為」,應當作為基本準則。誰都期望能夠開發出效能強勁的、多能多才的軟體,但並不是誰都能夠承受這樣的研發成本(時間、資金和人力)。在成本與所能獲得的最終產品之間,必須作出合適的權衡和折衷。
經過良好抽象的問題,更容易得到可復用的問題解決方案。比如,《程式設計珠璣i》第12章,取樣問題,從隨機選區列表抽樣,抽象成「從n個整數中隨機抽取m個有序整數」的問題;這樣,問題的解決方案還可以用於其它領域的抽樣問題。
應用框架和介面設計: 在明確問題的求解目標之後, 就要思考如何求解問題了。 通常會有乙個初步的思想,然後逐漸形成整個比較成熟的方案和應用框架。 與此同時, 定義良好的介面設計也是非常關鍵的。 在介面之上, 是依靠介面服務的應用程式的實現; 在介面之下, 是用來提供介面服務的資料結構與演算法的實現。
資料結構與演算法:掌握一門語言,就可以開始編寫程式;而資料結構和演算法,則可以幫助寫出更為強大的程式。 粗淺地將《程式設計珠璣》閱讀了一遍,發現:電腦程式的根本仍然是: 資料結構 +演算法。資料結構和演算法通常還是估算和提高系統期望效能的關鍵環節。
物件和訊息, 實際上是資料結構與演算法的封裝。 在物件導向程式中, 每乙個類都是一些繫結在一起的「小資料結構」和「小演算法」的攜帶者, 通過介面提供自己的服務;每乙個物件都是狀態攜帶者, 通過狀態的變化來表徵系統的變化,從而實現系統的特徵和功能。
資料結構有著非常重要的作用。有時候,複雜的邏輯,只要借助一定的資料檢視,就能得到很大的簡化,比如日期計算。《程式設計珠璣i》中談到的重要資料工具有:超文字、值-對、字典、資料庫、**、模板等。
效能估計:通常,通過演算法的大o分析來粗略了解系統可能達到的效能;另外,一定的粗略估算能力也是非常必要的(見程式設計珠璣第七章):常識、關鍵引數、經驗法則、量綱檢驗、安全係數。
介面宣告:涉及到系統的設計。系統由哪些資料結構(或物件)組成,它們如何進行互動(函式,訊息)以完成系統的功能; 仔細定義每乙個介面的宣告(功能描述、引數列表、返回值、前置條件、後置條件),並使之良好地協作。
偽**:不要急於程式設計。使用偽**來表達思路,勾勒程式的大致框架。這常常也會讓思路更明晰:因為在這個過程中,通常可以發現系統有哪些子功能要實現,有利於模組化。
程式驗證:你能保證自己編寫的程式在任何時候都正確嗎?還是僅在你視線所及的範圍內正確?你期望寫出的程式僅僅是看上去正確嗎?當然,我們都希望能夠早早完工,可是,急不得,懶不得。學習一定的程式驗證技術,也是有益無害的事情。雖然起初可能麻煩一點,但一段時間習慣之後,就不會覺得怎麼樣了。萬事開頭難,過了檻就好了。
程式驗證的常用方法:迴圈不變式和斷言。這實際上是根據三種控制流來確立的技術。
編碼:終於可以編寫程式了。恐怕經過上述折騰,編寫程式的興致早就減得不剩多少了。可是,一切,都是為了編碼更加順利,更加有創造性。總不期望發現,編碼就是在ctrl+c/v;當編碼到一定程度時,突然卡了殼;突然發現思路有問題;突然發現效能無法滿足所期望的;突然發現,之前的努力都白費了?
很多人抱怨工作中的編碼沒有創造性可言,可是,有沒有想過,你不去思考如何更有創造力的寫程式,難道期望創造性自動跑到你面前嗎?你不去努力使用演算法、資料結構,難道它會自動跑到你跟前要求你去使用嗎?你不去主動思考、勤於發現,難道你就指望奇蹟自動降臨於身?
編碼時,盡力遵循良好的**規範,使之可讀性良好,為後面的**重審和回顧打下良好的鋪墊。
測試和除錯:如何得到一段值得信賴的、可以放心復用的程式呢?苛刻的、徹底的測試。不要怕麻煩。凡事習慣就好了。編寫自動化測試;掌握使用斷言來進行除錯。
程式測試通常可以分為兩種: 自動化測試和手工測試。對於小資料集,0-10,可以構建自動化測試;另外,還要構建手工測試,使得能夠對特殊情形進行測試。
**優化: **優化通常意味著效能的小幅提公升。通常是應用快取原理,這需要對計算機組成和作業系統有深入的理解。**優化通常意味著程式可靠性、可讀性和可維護性的降低,程式複雜度的增加;因此要慎重進行。
**重審和回顧:沒有總結就沒有進步;「寫了**就丟棄」也不能期望有進步。通過**重審和回顧,進一步改進**的質量:可用性、可讀性、可擴充套件性、可移植性、安全性、可靠性。
其它:大資料集處理問題:初學者可能通常會考慮 1– 100 之內的小資料集處理;但進入到軟體開發領域,大資料集處理,海量資料處理,就成了乙個必須考慮的問題。對於排序問題來說,當n < 50 ,或許採用插入排序就可以了;但當n等於幾百萬,幾千萬時,就不能採用插入排序了。這說明:小資料集的處理方案和大資料集的處理方案往往會是迥然不同的。
實用程式和工具箱:卓越的工匠都會備用自己喜愛的工具箱。程式設計師也不例外。初學者可能主要在於程式設計練習;但進入一定階段之後,就必須考慮編寫實用性強的工具和程式,而不是總停留在玩具程式的級別上。
標準庫;實用程式;熟悉的ide;開源小工具;常用資料結構;演算法技術;正規表示式;資料庫使用;程式設計技術;程式設計技巧;設計思路;問題求解方案;錯誤錄;等等。
自動化重複工作:時常注意日常生活中是否有能夠自動化的重複性工作,並通過編寫實用程式和工具去簡化它。如果當時因為時間來不及,那麼,過後也應當盡力補上。
習慣的變革:人天性通常都是「能躺著就不站著」的,因此,培養了很多不好的習慣。程式設計師呢,通常期望能夠快速編寫出滿足功能的程式,然後執行察看是否如預期,接著便丟到一邊不再理會了。什麼問題分析、偽**?什麼程式驗證、測試?什麼**重審和回顧?都扔到一邊去。結果是,你逃掉了一分鐘的測試時間,卻用了將近一小時除錯時間來補償。划得來嗎?
其實,培養好的習慣,是一種一本萬利的投資。只要最初一兩個月堅持住,習慣成自然;之後,你便只是盡享好習慣帶來的益處了。
從程式設計到軟體開發
從某種意義上來說,在懂得《資料結構、演算法技術、作業系統、組成原理》這些專業知識之後,再加上「勤於思考,善於追根究底」的探索精神,以及大量的程式設計實踐,就可以逐漸掌握程式設計的基本原理和能力。
在學會程式設計之後,就可以閱讀關於軟體架構的書籍了,理解軟體是如何構建起來的。資料庫,計算機網路等等,實際上也是通過「程式設計原理+軟體架構」的產物,只是它們可以被用來作為更大系統的元件。
C C 程式設計基本功
c c 程式設計基本功 c 其內容精深博大,任何一塊都信手拈來者不多,究其精者更不多,不論何其原因,最重要一點就是其基本功之不紮實,對基礎性東西不加以精深研究。我也是一樣,經過幾輪經典的面試,讓我痛改以前的不紮實的作風,以此來磨礪自己。一 記憶體管理篇 乙個由c c 編譯的程式占用的記憶體分為以下幾...
程式提速 程式設計基本功
由於現在硬體的高配置,已經很少有程式設計師去關注程式效率的問題,不過相對於做演算法的朋友,效率是永遠的追求。這裡談談我優化程式的一點經驗,供新手討論,高手見笑了。一 程式設計基本功 前幾天給員工做培訓,隨口出了道題,不想竟難倒了所有人。題目是這樣的 現行的人民幣面值有1角,5角,1元,5元,10元,...
基本功練習 2 26
型別轉換 先看下面一段程式,這段程式摘自 c專家程式設計 如果是有這樣一段程式的話,你永遠無法知道x的值到底是多少,因為這句賦值語句x array d 1 根本不會執行。原因在哪?經過除錯發現程式執行到if語句進行判斷完之後,直接跳過下面一條語句的執行。下面來分析一下原因,因為sizeof求算型別大...