轉載的...尚未閱畢全文
現在我還在學習,所以只能抓一些別人的東西來充下門面, 等過段時間我要整理一下自己的東西,嘿嘿。 下文轉自:http://bbs.verycd.com/topics/223333/序:去年為了總結自己所學習/接觸過的技術,也順便為初學者少走彎路指明一些方向,可惜後來諸事纏身未能繼續,十分遺憾,現放到自己的VeryCD上來鼓勵自己將此繼續下去。
"Win32編程”
很不幸,我從開始學習編程到理解這個名詞中間隔了很長的時間(上個世紀的學習環境可見一斑)。很長時間里我都不明白32是指什么,我用過Dos, Win31,win95,win97...但好像沒用過名為Win32的操作系統啊?很久以後我才知道,32在這里並不是指操作系統的版本號,而是指32 位。微軟操作系統在win31及其以前都是DOS系統,windows只是在dos下運行的一個大程序而已。在其後win95則稍有改變,windows 除了DOS核心以外也真正成為了操作系統的一部分,提供着各類操作系統提供的服務。應該說,在win95之後的windows(新近的64位win系統以前)都可以稱之為win32系統平台(95/98實際上是16與32位混合)。所以在這樣的平台上,直接或間接使用系統提供的API編程,就稱之為 Win32編程。對Visual Studio而言,Win32編程一般指SDK、MFC、ATL這幾類開發方法,其中ATL在國內應用不是很廣泛,一般應用於以COM組件為架構的中大型軟體產品。
"SDK" :Software Development Kit,常譯為軟體開發(工具)包
在Win32編程領域一般指與MFC這類框架編程相區別的,直接調用Windows提供的API的開發方式,與字面原意有一些區別。另外一個經常見到的說法就是某軟體(硬體)帶有自己的一套SDK,這里其實一般是指一套API庫函數或者類庫,供上一層的開發者調用。又譬如常說的DX的SDK,其實是微軟開發的一套COM組件,供上層開發者使用。總之,供程序員使用的比較完備的代碼庫,就可以稱之為SDK;
“MFC”: Microsoft Fundation classes 微軟基礎類庫
大家都知道,使用SDK編程方式往往有很多每次都重復的固定不變的一些代碼,為了提高編程的效率,減少上千個API帶給開發人員巨大的精神壓力,微軟開發出了這么一個類庫,注意,這個類庫與操作系統本身無任何關系,它只是對API進行了一個面向對象的封裝,當然,還給出了一系列編程的框架。使用SDK的方法,使用Visual Studio,通過調用Windows API,MFC你也可以做得出來。MFC把一些固定不變的代碼已經寫好了,只在編譯時候鏈上,所以我們的代碼里看不到WinMain(),而事實上整個程序的運行,和SDK的方式無任何區別,初學者請記住這一點。另,補充一點個人感想,MFC的初衷,帶給開發人員更多的便利,我覺得並不太成功。學習MFC 所費的力氣和最終的所得,並不太成正比。
"API":Application Programming Interface,應用程序介面
這個詞的出現頻率很高,從某種意義上來說,也可以看作是SDK的一個子集。這也是做給程序員的程序,不過一般指用導出函數的方式提供服務的函數庫,不包括類庫和組件。
“GDI”:Graphic Device Interface,圖形設備介面
這個是Win32程序下最常用的顯示方式,與DirectX、OpenGL處於同一級。在DOS要顯示一些東東可不是容易的事,最簡單的是調用一些C的圖形庫函數來實現顯示,不過一般也就是些畫線,填色,輸出幾個文字,效果很弱(所以DOS程序界面一般都不怎么樣,且實現起來不是一般的復雜),要復雜一點的動畫/圖片顯示什么的,經常要用到的就是硬體中斷,調用一些顯卡自身的子程序(固化在顯卡內的)來做。因為每一個顯卡都不同,所以DOS的游戲兼容常常由於顯卡的差異而很糟糕。到Windows下大家就幸福多了,Windows將硬體這一層屏蔽起來,用一個表格(Device Context)來代表一個顯示,我們要做的就是在這個表格上填好相關參數,然後畫上我們想畫的東東,然後操作系統會依照這個表格(DC),把相應的顯示內容(一般是一塊顯示內存)傳送到指定顯卡的指定的顯存,再由顯卡傳給顯示屏。我們不再需要與不同的顯卡打交通,這是一個十分偉大的勝利!GDI中最常用的是雙緩存技術,就是說你可以在內存中創建(也就是復制)一個DC,只不過在這個DC中顯示的不再被傳送到顯示器上。有什么用呢?因為它的各參數是與當前屏幕DC一致的(COPY嘛,當然是這個結果),所以它的顯示內容可以完整無失真地傳送到屏幕DC上。我們通常在內存DC上畫圖,譬如畫一圓,再畫一條直線,畫完後一次性地傳送到屏幕DC上,這樣對用戶來說屏幕只刷新了一次,可以解決你畫一點內容屏幕即刷新一次導致的閃爍問題。當然,雙緩沖甚至多緩沖還有很多別的用處,那就要靠自己揣摩了。
"DirectX"
通常簡稱為DX(讀音:低叉)這是個很吸引人眼球的名詞,讀起來就很上口:)。Windows為我們作了許多屏蔽底層硬體的工作,其中DX是最知名的技術之一。操作系統要與各類硬體打交道,特別是多媒體相關的,譬如顯卡、音效卡、手柄輸入、多媒體流的網路傳輸等等,這些事情如果都自己來弄的話,那就太要命了(這些一般都涉及系統底層,自己也很難做出來)。而DX則正是這么一套操作系統提供的隔離多媒體硬體與程序員的間質,DX自身一般並不實現處理的能力,它是一個標准,要求硬體來滿足,好比DX提供一個函數名,硬體來實現函數內容一樣。通過它我們可以非常簡單而快速地調用硬體提供的各類服務。它主要包括 DirectDraw(通過直接訪問顯示硬體來提供快速的圖象處理能力),DirectSound(提供了軟硬體的低延遲聲音混頻和回放,以及直接訪問音頻設備的能力),DirectPlay (它明確的提供了通用環境連接能力來簡化你應用程序之間的通訊服務),Direct3D(DirectDraw的3D版),DirectInput(簡化你的應用程序訪問滑鼠、鍵盤和操縱桿設備的能力),DX5.0之後又增加了一些(如DirectShow),不再詳述。DX一個重要的特點就是你可以通過它直接訪問硬體而無需知道硬體的具體細節。譬如DirectDraw,就能夠越過內存而直接訪問顯存,這樣的速度將比GDI快很多,不在一個數量級上。補充一點:DX是以組件的方式提供的,而不是通常的導出API的形式。DX SDK的最新版本是9.0
"COM”:component object model,組件對象模型,一般簡稱組件。
這是微軟為了解決代碼重用的一個重要機制。重用代碼的最簡單辦法是源代碼重用,把寫好的函數和類加到自己當前的代碼中,編譯即可。簡單是簡單,敝病卻顯然的多。另一個常用的方法是單獨做成模塊,以DLL的形式分發,DLL導出函數或者類,客戶程序用動態/靜態鏈接的方法將其載入,這顯然比前一種源代碼的方法好一些,難度也不大,最為常用。但DLL也有一些不足,最根本的,它不是二進位兼容,DLL版本升級一次就需要與客戶程序代碼重鏈接一次,有些時候這幾乎是不可能的任務。為了更好地讓編程像“搭積木”一樣簡單,讓模塊可以完美地配合,完美地替換,COM產生了。COM不是類庫,不是代碼,不是操作系統的服務,而是一套編程模型,理論上來說,它與語言無關,與操作系統無關,unix下同樣可以做COM。COM是一種程序結構模型標准,你做的DLL或 EXE在結構上滿足這么一個標准,那這個DLL或EXE就是一個組件,它將在該平台上成為二進位兼容。COM主要利用了注冊表來登記本模塊的信息。客戶程序調用時首先查注冊表,找到所需組件的位置(這實現了位置透明),然後就用Loadlibrary把它載入進來,這和普通調用沒有本質區別,區別在於由於組件特殊的實現方法使得整個過程中用戶程序都不知道組件的位置,組件的類的實例化過程,如何銷毀,不能直接訪問組件的任何實現細節,用戶只與組件的幾個 public介面打交道。這將實現真正的模塊之間的獨立。對用戶程序而言,對於目標組件的認識,除了介面,一無所知。在介面不變的情況下,組件可任意替換而客戶程序不作任何改動,無需編譯,僅這一點,在中大型程序的模塊集成的過程中就將節約相當多的時間。
"STL":Standard Template Library,標准模板庫
這是最早由Alexander Stepanov和Meng Lee(蠻像中國人的名字)完成,於1994年提交給ANSI/ISO 標准C 委員會並通過而成為標准C 的一部分。望文生義即可知這是一個代碼庫標准,不是語法標准。簡單地說,STL是以C 中的模板語法為基礎建立起來的一套包含基礎數據結構和演算法的代碼庫。STL的特點是實現了“類型參數化”,即STL的代碼中可處理任意自定義類型的對象,如果不使用模板技術的話,這是一件相當困難的事。也因為這個原因,在最新的java及C#語法中均加入了對模板語法的支持,可見其重要性。另外一個有關 STL重要的話題是GP(Generic Programming),泛型。這是與面向對象相並列的另外的一個編程模型,它以模板為基礎,弱化了實體類型的差異,簡化了編程時問題抽象的模型,提供了更好的封裝性和彈性,對於繁雜的面向對象編程毫無疑問是一種解脫,至少是精神上的。GP並不是用來取代面向對象的,而是作為一個有益的補充體,是面向對象很好的合作伙伴。GP是最近幾年軟體架構的一個研究熱點,但國內真正的應用似乎並不多見,這項技術本身還基本處於研究前沿。<>一書對C 中的GP應用有很好的詮釋,而這本書對腦細胞的殺傷力之大,也是其它C 書藉望塵莫及的。想知道C 的代碼技巧可以做到怎樣的出神入化嗎?不妨看看這本書。
"ATL":Active Template Library,活動模板庫
這在VC編程下應該算是比較高級的話題了,它集COM和模板技術於一身,帶來了極方便的組件編寫方法和極高的學習門檻。可以說,進入ATL領域就算是進入了中級以上的編程領域。ATL是為組件而生,它的目的是為了讓程序員更方便地編寫組件(純用C 寫一個最簡單的組件實現一個“Hello World”對初學者來說都是要命的),同時它使用模板技術來類似於MFC一樣建立了一個開發COM的框架代碼庫(模板庫),使用該框架及模板庫可以相對方便地進行組件開發。ATL中的一個特點就是你自己的類將成為ATL代碼庫中某些類的父類,這是一件很有趣的事(這也是模板技術的一個特點)。
"HANDLE": 句柄
這是一個中文翻譯很古怪的字,對初學者來說是百思不得其解的東東。這其實等價於void*(順便提一下,初學者往往對VC代碼中各種古怪的符號、類型標記/宏等百思不得其解,其實它們大多來自基本類型的#define或者typedef,請將游標移到這些符號上(譬如HANDLE),然後按下F12,編譯器自會把你帶到它的聲明處,反復使用幾次,你終會見到它的原貌,然後長吁一口氣:原來不過如此而已。沒用過的初學者請牢記:F12)。很多初學者總想知道一個HANDLE代表一個什么對象,我的建議是不要去理解為某對象,而就是理解為訪問某一個對象的入口,事實上HANDLE大多數時候是一個整數索引(標志該對象在操作系統的某表中的位置,就好像一個數組的下標一樣),Windows系統核心中主要是幾張大表,這樣一個整數索引就是標記目標在這個表中的位置,供操作系統訪問時查詢用。偶而它的確是指向某對象的指針,有時它還攜帶一些額外輔助信息。總之,我們不要去直接訪問它,把訪問HANDLE的任務交給操作系統好了,除非你還嫌寫程序不累:)。
"DLL": Dynamic Link Library 動態鏈接庫
DLL的一個特點就是可以動態載入(顧名思義),即在主程序(我更喜歡稱為客戶程序)需要該模塊時才由操作系統載入到內存。畢竟一個大型應用程序我們經常使用到的功能並不多,這樣一些不常用的功能模塊(DLL)在程序運行時一般將不被載入,可極大節省內存開銷。DLL同時也是目前最常用的分發模塊的方法,便於彼此協作。程序中對DLL的調用主要有兩種方法:1 針對使用DEF文件導出函數的DLL,使用API函數LoadLibrary(“DLLModuleName" )載入,然後使用GetProcAddress()得到函數指針,進而調用 2 直接將類、函數等導出,客戶程序使用同一份頭文件聲明,加入對應的lib鏈接庫,即可在客戶程序中直接使用DLL中的類或函數,無需 LoadLibrary。
"Process": 進程
進程是一個動態的概念,包括從進程的創建申請,PCB(Process Control Block進程控制塊,一般操作系統實現為一個表格(struct))的創建,地址空間的內存分配,模塊代碼載入並執行,執行完以後進行撤銷,整個過程被稱為"進程"。在Win32下,一個進程有4G的邏輯空間。但我們也常把它作為靜態概念來使用,在Win32下,一個EXE的執行就是一個進程(如果它內部又開了新進程,另當別論)。
"Thread": 線程
為了更有效的提高CPU的利用率,更好地實現多任務並發,微軟將進程進行進一步分割,實現了CPU任務調度的新對像:線程。一個進程擁有至少一個線程。我們在實現多任務並發的時候通常是建立一個新線程(建立線程的系統開銷要小於進程),線程以我們自己的一個函數作為入口,函數執行完畢自動撤銷(當然你也可以在執行過程中強制結束該線程)。順便提一下,在UNIX下並沒有線程這個概念,想來是因為UNIX主要是以多進程的並發服務為主(所以它更適合於做伺服器),系統運行時通常已經有了太多的進程,所以沒有必要再對進程進行細化,因為這樣做甚至會降低系統效率(CPU調度不過來),當然,這是我個人的猜想:)
"C語言"
到目前為止,C語言應該是傳播最為廣泛的語言,特別在UNIX的世界里依然扮演着主角的位置,在其余如硬體開發,嵌入式系統(如手機)皆有十分突出的表現,即便在 win32平台下SDK的開發中也有一席之地。更主要的是它是大多數國內(國外我不敢說)程序員的啟蒙語言,通過它許多人才領會了程序的思維。C最大的特點就是快,除了匯編以外效率可以達到最高,而它的靈活性,對硬體的直訪性也完全符合程序員自由的天性。如果說學習別的技術尚有猶豫和徘徊,那么學C只有一句話:相信我,沒錯的!也有許多人主張可以直接學習面向對象語言,我不太同意。面向對象語言對機器模型的抽象十分容易讓程序員迷糊,心中難以建立准確的程序運行時的模型。畢竟我們是程序員,不是用戶,我們不能把所有的問題都想當然地交給編譯器和操作系統去解決,它們也解決不了。至少學習一門面向過程的語言,才能知其所以然。
C
這是貝爾實驗室的又一傑作,同時,也傷透了全球太多程序員的心,腦細胞殺傷力十分之大。C 比大多數初學者想像的都要復雜得多,它基本包括:一個類化了的C語言,模板,標准模板庫.很多初學者掌握的C 僅僅只是一個類化了的C語言的一個子集(不相信的話,你不妨看一看<>中的C 代碼,看看能理解多少)。更麻煩的是使用C 不得不談到面向對象的編程風格,這同樣比初學者想像的難很多,要有打持久戰的准備。而最讓我這類C 愛好者憂心的還是它目前在Win平台中的前景,在.net平台上很難找出不用C#而使用C 寫新代碼的理由:(。而它的復雜性和目前許多諸如java/C#及一些動態語言(python/ruby)比起來,開發效率顯然的低,大有退出上層應用程序開發的趨勢。這么一個包含了最多范式的近乎完美的語言,我實在不想放棄。我唯有祈禱在未來C 的路可以走得更遠更好一些。
源代碼版本控制
這是軟體開發中一個十分重要的工程手段,幾乎是必須的一個Process(過程)。很多作坊式的開發團隊在采用軟體工程的一些方法的時候,第一個要進行改進或增加的,往往就是這個過程。對初學者學習而言,建議在開始進行實踐小項目的階段即進行源代碼版本控制,因為這在以後的工作中,是一定會用到的。
源代碼版本控制的基本原理如下:
在伺服器端建立該項目的資料庫,並保存你選定的項目源文件的第一個版本。客戶端任一用戶要獲得某源文件的修改權利,需進行check out操作。之後客戶端一般每完成一個無編譯錯誤的版本想保存的時候,進行check in操作,將當前版本保存在伺服器端上並成為最新版本(注意,不是覆蓋以前的喲)。任一客戶端可以方便地得到伺服器上的文件的任意版本(如果有許可權的話)。一般還實現了一個重要的功能是版本比較,任一客戶端可以利用版本控制工具對某文件的不同版本進行版本比較,它會標記出不同版本的同名文件的不同點,可以輕易地看出版本內容的演化,這一招很常用。 下面介紹一下我接觸過的三種版本控制工具(也是國內用得比較多的):
VSS: Visual Sourcesafe
這是微軟Visual Studio自帶的源代碼版本控制工具,它最大的特點就是易安裝(與Visual Studio集成在一起,裝VC/VB的時候就順便搞定,不用別外費工夫),使用簡單(伺服器端設置相對容易,一般個人稍加摸索就可以輕松搞定,客戶端更是只管check in/out),基本功能完善,版本比較很直觀(我喜歡)。它的特點是某人check out了某版本以後,別人將無法對此版本check out,也就是說同一時間只有一個可以修改某一個文件,這樣就避免了不同的人對同一文件的修改造成彼此沖突(注:可通過設置伺服器端實現多人check out,但幾乎不會這樣做,因為那樣就失去了VSS的一個最重要的功能)。另,VSS可集成於VS環境,但根據我的經驗,直接在VC里對版本的check 操作,常常不生效,所以最好還是到VSS程序里去進行check操作。補充:單機上也可以使用VSS,這樣的好處是在對當前某些文件進行了誤操作或大規模地誤修改之後,可以恢復到最近的無錯誤的版本,最大程度地挽回損失。VSS實際應用較普遍,如果你是走Visual Studio路線的話,一定要用一下。
CVS: Concurrent Versions System
這個也是一個大名鼎鼎的開源的版本控制工具,主要活躍在UNIX世界。CVS我使用不多,一般而言好像功能比較偏向於命令行方式(UNIX下開發很多人也都使用着命令行方式)。當然,Windows下面也實現了幾個版本的CVS,也可以集成於VS,好像還有一個可以掛接在IE上的,我沒試過。著名的開源項目管理網站sf.net也是用的CVS,如果你要和全世界的程序員一起協作開發,CVS是必須要安裝的。在JAVA的世界里,也是以CVS為主。
Rational Clearcase
這個工具就比較上檔次了,Rational公司(現在是IBM)的出品,價格昂貴。我最初參加工作的時候用過一小段時間,簡單談一下。這個工具的特點是復雜,安裝及設置就十分復雜,我的印像中客戶端甚至不得不加入到NT域里面去,導致我在本機的許可權都不夠,安裝新程序都很麻煩,很郁悶(不知道是不是我們公司的相關人員安裝設置錯了,想來應該是這樣,但其復雜性可見一斑)。對使用而言,它有一個功能挺有用的,就是它能夠根據你每次check的版本號,自動生成版本樹(一個樹狀圖表),你可以清晰地看到版本的演化過程。所以嚴格地說,像CVS/Clearcase這樣的才真正稱得上“版本”控制,VSS還太勉強。Clearcase的功能十分強大,我不詳述了(我還不想出書),較適於大型軟體公司實施軟體配置管理時采用。雖然它的名氣十分之響亮,但我不知道國內有多少公司在真正使用正版的Clearcase這樣的工具,想來應該是十分之少。
OpenGL
OpenGL至今頗有一點英雄落寞的味道,這一套標准是實現得如此之好,以至於曾經一度成為游戲界面華麗的標准。它的低落也是一個必然,畢竟在微軟的強力打壓下鮮有不挫敗的。但它曾經能夠給微軟帶來如此的壓力,至今也依然在工業界被廣泛使用,大多數游戲/顯卡依然保留着對它的支持(CS里我喜歡的還是 OpenGL)。而它的性能在某些方面與D3D比較,依然占着上風。不幸的是DirectX在不停地向前發展,而它,幾乎止步不前了,前景並不光明。 OpenGL目前在工業領域應用較為廣泛,它的優秀的矢量圖的操作性能,華麗的色彩,在專業的圖形圖像處理領域表現突出。游戲中使用相對以前而言則是越來越少。新近聽說微軟的最新操作系統Vista對OpenGL進行了極大的打壓,不但性能上折扣,支持的版本也只到1.4(最新版本好像是2.0),不知道最後如何收場,拭目以待。
DirectDraw & D3D
大凡像樣的2維Windows游戲,幾乎都是采用此技術來實現顯示的。DirectDraw有兩種模式:全屏和窗口。其中全屏應用更多一些。在全屏下, DirectDraw有一個十分著名的“換頁”技術,即在兩個顯示頁面之間用“交換”來實現顯示刷新,這個速度十分地快,只是一個顯存內一個指針的交換,比你用BitBlt復制一屏的像素快太多太多,游戲的高效的動畫效果大多源於此技術。DirectDraw主要用於娛樂領域和一些實時顯示要求較高的場合,如醫療圖像。D3D是目前大多三維游戲的標准采用,我沒鑽研過,不敢多言。它的效果嘛,玩玩游戲就知道了:)
UML:Unified Modeling Language,多譯為統一建模語言
這個語言是一種圖形語言,主要是作為設計時建模的一種標准的圖形模型,便於程序員與程序員、程序員與客戶、設計員與代碼員之間的溝通,同時它也幫助設計人員將頭腦中的基於程序代碼的對程序功能的理解形成文檔,便於理清頭緒,進行下一步編碼的工作。換言之,設計過程的產品,可以表現為一些文本文檔,或者一些框架代碼,或者一些偽代碼,但比較標准通用的,是表現為一堆UML圖。UML包括動態圖和靜態圖兩大類,其中靜態圖中的類圖最為常用。很多人初學時不知道該怎么做設計,寫小軟體時常常沒有設計過程,其實很簡單,把軟體的類圖畫出來就好了。學做設計時未必要找一個像Together或者Rational Rose一樣的巨無霸。用一些簡單的可以做UML圖的工具就好,專門用來畫UML圖的小工具很多,網上容易找。補充一點:畫UML圖不要面面俱到,不要什么都畫,突出重點方便理解就好,甚至使用不規范的記號也不要緊(當UML的功能是草稿的時候)。
RTTI: Runtime Type Information 運行時類型信息
在程序中,當我們得到某一個對象的實例或者指針時,大多數時候並不能直接肯定它的類型(都是繼承以及類型轉換惹的禍),這個時候,依靠VC4.0或更高版本的編譯器提供的RTTI支持,調用庫函數typeid()即可在運行時獲取這個對象的“類型信息”,在一些動態處理中“類型信息”很重要,獲取了類型信息以後,你就可以有十分把握地調用該類型的相關操作,或者類型轉換,或動態生成。因其重要性,在JAVA和.net庫中借助單根繼承和“虛擬機”對此有了更優雅的做法,每一個自object繼承的類天然就有了表述自己類型信息的能力(繼承的好處),並且容易擴展,現在你需要類型信息的時候,大可直接 ask那個對象:tell me, what type are you?它就會告訴你答案。
debug & release 調試 & 發行
大家都知道,debug是調試版,release是發行版,區別在於debug版生成的程序中包含大量供調試用的場景代碼(不是真正運行需要的),而 release一般去掉了這些信息,並進行了某些代碼優化,所以release版的程序會比debug版的程序小很多,運行速度也快一些。同時, debug版為了便於調試,往往會對調試使用的診斷代碼加上DEBUG一類的宏,使得在release下不對這些代碼進行編譯。正由於兩種版本編譯使用的源代碼的差異(以及release糟糕的優化),常常使得兩種版本運行時產生截然不同的效果,一個正常一個崩潰是大多數人都遇到過的。導致問題的可能性很多,注意事項詳見各論壇的諸多精華貼。另,同一個程序如果DLL之間的鏈接使用了不同版本(譬如EXE是release版,dll是debug版),有時會無法正常運行,所以我一般的做法是每一個DLL針對不同版本使用兩個DEF文件,編譯生成不同名的兩個文件(debug版文件名後加d),調用時各個版本針對自己的版本調用,這在一定程度上可避免混亂。另,release也是可調試的,在工程設置里把調試信息打開即可。
XP:eXtreme Programming 極限編程
這是近幾年才時興起來的開發模型,國內大致是01/02年開始有所宣傳。
它主要是針對中小型開發團隊在開發時間要求緊、需求不穩定的中小項目(大多數軟體項目都是這個情況)時使用。它打破了傳統軟體工程的框架,非常新巧。譬如整個開發過程中文檔很少,大量使用“卡片 (如CRC卡片)”來描述開發計劃和內容;沒有真正意義上的軟體功能規格說明書,取而代之的是一系列可測試的用例;沒有獨立的設計和測試階段,它們總是在迭代中增量反復進行;設計:盡可能小和簡單;一般沒有代碼復審(code review),大家共同擁有代碼。而它的最顯著的一個外在特征是它常使用“成對開發”,即一台機器前坐兩個開發人員,共同開發(一個看,一個寫),這乍聽起來真是蠻有趣的:),它的基本出發點是認為成對開發的效率在一定條件下要高於兩個人獨立開發的和。不要覺得天方夜譚,在很多項目中,這種做法的有效性已經被證實。
XP的特點可以用“快、小、靈”來概括,它和傳統瀑布模型(自頂向下)的區別在於它使用迭代增量(設計->代碼->測試->設計->代碼...)的方式。想法很簡單:沒有什么目標是可以一開始就容易確定的。用爬山來做一下比喻的話,傳統的是在山下研究地圖,選好一條路線,然後沿着此路前進,XP則是走一走,停一停,看一看,對下一步的方向作出新的選擇,在很多時候,這樣做會讓你選擇到更好的捷徑。
ICONIX:
這個字相信很多人都沒見過,我也不知道是什么字拼起來的,作為開拓眼界,我還是提一下吧。這是一種界於XP和RUP(Rational Unified Process)之間的開發模型,換言之,它比XP“大”,比“RUP”要小。它采用了UML的一個子集,特點是用例驅動,保持良好的進度跟蹤能力。它的目標是用最短的時間來把用例變成代碼。具體來說,這種開發模型相對精簡的XP而言,更加強調用例的建立、分析和代碼化,用例是其中心地位。
RUP:Rational Unified Process
前面已經提到了,相信你已經感覺出它是一個豐富的軟體開發模型。這是由IBM提出來的軟體工程模型,它使用完整的UML圖,對開發的各階段(需求、設計、代碼、測試、維護)均有十分完善而復雜的標准,就不詳述了。RUP本質上是迭代式開發,在每一次迭代中均完成以下四個階段:初始階段(inception)、詳述階段(elaboration)、構建階段(construction)、轉換階段(transition)。
CMM:Capability Maturity Model 軟體成熟度模型
這是卡內基*梅隆大學軟體工程研究所(我的專業正是軟體工程,所以這也成為我心目中的聖地)的一大力作,一度曾形成了席卷全球軟體開發的CMM浪潮。 CMM分為五級,大多數軟體企業都處於第一級,而得到第五級認證的全球也沒有多少,國內去除掉掛羊頭賣狗肉的,也是寥若星辰(嗯,比星辰是寥多了)。所以 CMM實施一般是從第二級開始,能做到第三級的都是頗有實力的軟體公司了。CMM是以Process(過程)為中心的模型,從二級始每一級都有幾個Key Process(關鍵過程),每一個KP又分為若干Key Active(關鍵活動)。CMM的實施一般不能越級實施,並且每一級的實施通常都要一年以上,所以要達到較高等級是一級很困難的事。另,CMM不僅可用於較大規模公司,同樣也可實施於小公司,小項目組(這是很多人所不知道的)。實施視具體情況等級之間可交叉,譬如實施時采用二級的某些KP再加上三級甚至四級的KP,但你只有實施了所有二級的KP,你才能也只能通過二級認證,即便你采用了某些四級的KP。CMM最新發展成果是CMMI (Integration),這主要是新考慮了軟體與非純軟體因素的關系(譬如系統),以及團隊之間的協作問題。CMM在國內的發展似乎有點走向ISO同樣的道路,這實在不是一個好消息。
Callback Function: 回調函數
在侯sir的<<深入淺出>>中一開始就提出了這個概念,大概的提法是說回調函數是操作系統調用而你永遠不要去調用的函數。這個提法讓初學者有點望而生畏,以為是一種多么高深而難以領會的系統底層的核心技術。其實不然,這個技術本質很簡單,而且很常用。它實質就是函數指針的基本運用(如果不知道什么是函數指針的話,翻翻書)。在一個模塊中,有時想讓一部分功能由其它模塊實現,譬如說一個做顯示的模塊,它只想實現顯示的資源配備,畫面的刷新,縮放等控制功能,而把畫具體實體(譬如圓、多邊形,都可以有很多種不同效率的實現方法)的代碼由別的模塊來實現,怎么辦呢?用函數指針。在自己的類中放一個畫圓的函數指針,使用時由外部為這個函數指針賦值(其實就是指向了一個外部的函數),在自己的代碼中直接調用這個函數指針來畫就可以了(本模塊完全不知道外部模塊是怎么畫圓的)。那個外部的函數在這里就是回調函數!
在很多系統API中就使用了這種函數回調的方法,讓我們開發的代碼實現可以嵌入到API的代碼實現當中,其實我們就是傳了一個函數地址給它而已。換句話說,這些API搭好了某些運行的代碼框架,我們來為它具體實現。
XML: Extensible Markup Language 可擴充標記語言
也許你還在為選擇.net和j2ee而徘徊不前,如果是這樣的話,不妨先着手學一下它們所共通的一個基礎:XML。有了HTML為什么我們還要XML?很簡單,HTML重在表現文本/圖片以及一些多媒體內容,它很難表達數據,因為它的標記是固定的,而數據類型千千萬,根本無法描述。.net和j2ee都要解決一個信息傳輸格式標准化的難題,這個格式要能承載文本/數據,最好還能描述程序介面,同時又應該像HTML一樣簡單,具有通用性,能夠在HTTP下很好的運作。在這種要求下,XML產生了。它的特點正如其名,和HTTP一樣,它也是一種標記語言,但是它的標記不是固定的,是可自定義(也就可無限擴展)的,這些自定義標記能夠很好的描述數據類型以及對應的數據內容(乍看起來很像資料庫表的定義)。除此以外,XML還可以描述程序介面,所以XML可以方便地與網路程序構件(COM、EJB等)直接交互。由於它也是一種ASCII文本流,所以與當前的HTTP兼容,在當前的internet上暢通無阻(這很重要)。有了以上功能,XML就名副其實地成為了新一代互聯網技術的標准信息載體,在.net和j2ee的網路架構中,各種“構件”的信息交互都交給了XML,可謂任重而道遠。
XML我自己沒怎么寫過,單就學習上的經驗而言,感覺語法上比HTML更瑣碎一些,小細節更多,沒那么容易速成:) 好在根本同源,有HTML基礎甚至WEB開發基礎的,學起來也很輕松。
Java2:
這是近幾年最吸引大眾焦點的語言,在Web開發,網路平台,移動開發的世界里發光發熱。你可以不用java,但你不可以不了解java,畢竟這是一個極大且豐富的軟體開發領域。有些沒使用過java的VS陣營里的人可能還不明白java2里的那個2是什么意思,容我先解釋一下。Java最初正式推出 1.0時,並沒有受到如此多的好評,受到頗多責難,於是它不斷地推出新版本來完善自己,其中變化顯著的一個版本是1.2(我沒記錯吧),Java的每一個新版本除了語法上的更新,還有一明顯的標志,那就是JDK(Java Development Kit,就是Java自帶的一套SDK)的更新,版本1.2以後的java為了在宣傳上與以前的java相區別,便被稱為java2。目前用得比較多的 jdk是1.3/1.4 ,最新的JDK是1.5(代號tiger)。java開發的IDE國內主要以JBuilder為主,另外就是在開源領域如雷貫耳的Eclipse,而 sun也力推自己的開源java IDE:Netbeans(從sun的網站上可下載,免費)。Java運行是虛擬機機制,相當於在操作系統上增加了一個軟操作系統,源碼被編譯成一種位元組中間碼,由虛擬機解釋執行,只要有對應的虛擬機,java程序就可以在該操作系統上運行,這就是java號稱的一次編譯,到處運行的由來。而附帶而來的不可避免的性能問題也讓Java難以成為桌面程序開發的主流。補充一下:對初學者學習而言最好的Java IDE我推薦使用JCreator,這是一個C 寫成的IDE,幾MB的大小,比Eclipse快十倍以上的啟動速度,對初學者帶來極大的便利。
J2EE:
Java實際上又被分為3類:J2EE/J2SE/J2ME,不同類分別對應不同的JDK,J2EE針對企業平台開發,J2SE是標准版,J2ME針對移動平台開發。J2EE現在實在是熱得燙手,我前不久翻了一下程序員早期的雜志,發現在第一期創刊號里(2001.1)已經有了j2EE方面的討論,現在已經是2004.6了,你對它的認知又多了多少?J2EE不是一種單純的技術,而是一種體系架構以及組成該架構的諸多標准。企業平台開發和桌面/簡單 Web資料庫開發有很大的不同,它的程序規模往往很大(不是一個或者幾個EXE可以搞定的),用到的往往是海量的資料庫和海量的通信,並且常常是不可中斷的,這些特殊性都使得企業平台開發更多地去關注架構的問題。而我們寫一個熟悉的java客戶端程序,或者消息處理中間件,又或者資料庫處理程序,都只是這樣一個架構里的一小部分。J2EE是很寵大的,所以請不要寫了幾個EJB(這是java世界里的構件,概念上大概是類似於COM)的例子程序就感覺自己精通j2EE。
J2EE中傳遞消息時往往引入了一個被稱作消息管理器的中間件,在伺服器端使用EJB的容器來管理和調用EJB。在 J2EE中一個重要的概念是Transaction(事務)處理,事務的概念最早廣泛應用於資料庫技術。這實際上是一個封裝了很多操作的單元,它的作用是中間任何一個操作失敗,可以自動依次整體撤銷,所以一個transaction就是操作成功/失敗的最小單元,不存在一個transaction只成功了部分操作的情況。
在企業服務平台開發中比較知名的有一個叫BEA公司(這是一家不錯的公司,應該知道它的名字),它的產品是Weblogic。
.net
.net是微軟為下一個十年准備的技術,你呢?.net也是一種平台技術,而不是單一技術。它主要分為.net運行時平台(對應java的虛擬機)和. net類庫(對應java的jdk)。目前只有Windows2003是天然集成了.net運行時平台的操作系統,所以如是你寫的.net程序想要在別的操作系統上運行,該操作系統必須先安裝.net平台,這是一件蠻煩人的事,也是為什么到目前為止,還沒有太多的人改用.net來寫程序(盡管可極大提高開發效率)。希望Longhorn的出現可以扭轉這一現狀。那我們就終於可以和MFC這樣過時的框架類庫說再見了,一大快事。
. net采用了很多最新的技術和思想,對走VS路線的人來說(特別是有COM概念的),學起來相對輕松且很過癮,前人推薦的“.net框架程序設計“和”. net本質論“都是很好的書。當然,看它們之前你最好基本掌握一門.net語言,譬如C#,掌握語言對我們來說是最easy的。
聊了這么多技術,下面讓我們來放松一下:)
公共密鑰: (也常被譯為公開密鑰)
"密碼"已經是一個老少皆知的詞,想從銀行里把錢取出來嗎?沒密碼可萬萬不行。不知從什么時候開始,這么一個軍事級的辭彙已經走進了千家萬戶,婦孺皆知。不過知道“密鑰”這個詞的人就少多了,知道“公共密鑰”的人就更少了,不但知道而且了解其原理的人則少之又少,當然,如果你以前不清楚的話,那么你即將加入這少之又少的行列:)
long long ago,隨着軍事的日益發展,情報的重要性日益提高,如何獲得准確的情報成為軍事上的一大重點,伴隨而來的另一個問題則是如何盡量保證自己的情報在被敵人截獲後(這總是無可避免的)敵人依然無法獲得該情報的信息,防止情報外泄。不妨讓我們以今人的智慧來設身處地的想一想,有什么好的解決方法……首先想到的當然是用密文不要用明文,把明文按某種規則打亂為密文、或者讓明文與密文有某種一一對應的規則,這樣即使密文泄露,只要敵人不知道我的明文與密文之間轉換的規則,它將一無所獲。這是一種簡單且行之有效的方法,即便到了近代一戰二戰中,還被廣泛使用着,當然它的這個規則往往是動態的,甚至可能相當復雜。然而這樣的方案在理論上有一個重大的缺陷,那就是你如何安全地傳遞“規則”?兩地之間要確保能互相將密文變成明文,必須有共同的規則,那么就至少需要"一次"安全地將“規則”從一地傳到另一地,這在理論上是無法保證的,所以整個的安全體系也就無法讓人完全地放心,一旦規則泄露,對密文體系的打擊則是致命的。有沒有什么更好的辦法呢?嗯,如果你以前沒有接觸過的話,我估計你是想不出了。解決的方法正是公共密鑰體系。
讓我們再回頭來看一看我們是如何將明文變成密文的,最簡單的是將它重新打亂,或者進行某種線性或非線性變換,立刻就讓人難以閱讀,但這也是最容易破譯的,因為這種自身的變換在數學上相對容易求解,在現在的計算機的幫助下,通過一定量密文明文的統計分析,很容易找到其變化的規則。高級一點的,可以再用一組密碼(可以是動態改變的,譬如隨日期而改變),讓明文與這組密碼進行某種組合變化,從而得到一組密文,這樣,由於這個 “組合變化”可能是非常復雜的一種數學變換,僅通過密文或者加上一定量的明文也很難找出這組密碼以及這個“組合變化”的規則。這就是目前絕大多數加/解密的根本原理。而這里的這組密碼,我們就把它稱作密鑰。
但是這只是提高了獲得密文者的對密文的破譯難度,並沒有解決我們前面提出的問題。現在就要來看看“共公(共開)”的含義了。在數學上有一種運算是單向的(在數學理論上截止目前為止),從一個方向算過去很簡單,但是它的逆運算當缺少正向運算時加入的一些信息時,就會變得幾乎不可能(譬如大素數的分解,分解是困難到幾乎不可能的,分解後的兩個數乘回去是簡單的,小學生就會,這就是著名的RSA的原理)。這就構成了我們的“共公密鑰”的理論基礎。
具體使用如下:我們首先產生一對密鑰,一把稱為加密密鑰,一把稱為解密密鑰,它們是相關但不相同的。加密時我們把明文與加密密鑰一起采取“不可逆”數學運算進行“組合變化”,形成密文,解密時把密文與解密密鑰一起采取類似的運算進行解密,注意,這處因為加密密鑰與解密密鑰產生時即是相關連的,所以解密密鑰能夠完成這樣一個“逆運算”。同時,解密密鑰也可以用來加密,相應的,加密密解也可以用來解“用解密密鑰加密的密文”。具體使用的時候很簡單,把加密密鑰當作公共密鑰,分發給任何想要獲取的人,解密密鑰由自己妥善保管作為私鑰。當擁有加密密鑰的人要傳遞密文給自己時,他只要使用自由獲取的我的公共密鑰來加密該明文即可,當然,他加密以後他自己也是不能解的,但是傳到我手里以後,我則可以用解密密鑰來解密,這樣就很好地解決了前面提出的無法安全傳輸“規則”的問題,現在我的公共密鑰是公開的,你要拿就拿去好了:)而私鑰我自己好好保存,不用把它放出來。
公共密鑰另一個重要作用就是用來簽名。我使用私鑰對自己的文件加密後,你來使用我發放的公鑰來解密,如果解密成功,則可證明這的確是我發出來的文件。
在現在網路信息安全常常使用的證書體系中,“證書”的背後其實也是這樣的一種公共密鑰體系。
沒有留言:
張貼留言