程式者的胡言亂語

pageicon 星期日 九月 07, 2008

程式員的黑盒子 - 1

自從物件導向的設計方法流行以來,許多物件導向設計中的重要觀念,一直被程式員們奉為圭臬,而資訊隱藏(information hiding)以及封裝(encapsulation)的想法,更是深深的影響到程式員們進行設計時的態度。


封裝的目的是希望透過介面,將物件實作的細節隱藏起來,透過控制能見度(visibility)來降低物件與使用物件之程式碼的耦合程度。元件式的軟體開發(component-based software development)更進一步發展封裝的觀念,在元件式的軟體開發下,希望將軟體單元都封裝成為所謂的元件,每個元件皆有其規格,而元件的使用者則毋需了解元件內部究竟如何實作,只需依據元件公開的規格介面來控制、使用元件。此種基於元件的開發方式,其優勢便在於將開發中可重覆使用的軟體單元,封裝成可被重覆使用的元件,之後便可透過「組裝」現成元件的方式,來更快速的完成應用程式的開發。在此種模式的理想情況下,會有專門的角色開發個別的元件,而應用程式的開發者,只需從型錄中挑選自己所需,接著加以組裝,便能輕易的打造出應用程式。這樣的模式,倘若真能落實,不僅可以透過重覆使用節省無謂的重覆性開發,也可以大幅的提昇開發的效率,更有利用日後的維護。有人用「軟體IC」一詞來說明元件式開發的元件,準確的描述人們對此種開發方式的期待。許多有名的技術,諸如OMGCORBASun MicrosystemEJB、以及微軟的COM,都是奠基於元件式開發的技術。


元件式的開發模式有一個重點,便是要規格化、介面化元件。每個元件都有其所遵循的規格,元件的使用者只會依據這份做為介面的規格來撰寫與之相溝通的程式碼,而不會碰觸到元件確切的實作方式。


例如,當你使用微軟的DirectShow架構來開發多媒體應用程式時,你會留意到,DirectShow的架構正是一種基於元件的架構。在DirectShow的架構中,當你要撥放一段影片或音樂時,你得先建立一個IFilterGraph的實作,裡頭是許許多多的IFilter實作物件相互以IPin連接,而多媒體的資料就從IFilterGraph中最前端的IFilter(也稱為source filter)開始沿著IFilterGraph中的IFilter流動。每個IFilter的實作本身都有其獨特的作用,例如它可能是一個MP3的解碼器,從輸入的IPin收到MP3的音訊內容後加以解碼,並且利用其輸出的IPin傳送至下游的IFilter實作去。在DirectShow的命名慣例下,不論是IFilterGraphIFilterIPin等名稱,首字的 “I” 皆意謂著它們都是代表著介面(”I”nterface),對或開發DirectShow應用程式的程式員而言,他們概念上並不理會每個IFilter實際上究竟是如何實作的,只要該IFilter的實作其輸入之IPin及輸出的IPin能夠滿足他們的需求即可。所以,應用程式開發者和元件開發者(開發IFilterIPin實作品的人),各司其職。採取這樣子的架構,其優點之一是,或許你現在正採用某一家廠商所開發的MPEG 4解碼器,只要這個解碼器符合IFilter的介面,那麼你便可以將其輕易的更換成另一家廠商所開發的MPEG 4解碼器,而不會對原有的應用程式產生任何的衝擊和影響。對你的DirectShow應用程式來說,只不過是將若干個個別作用不同的元件(IFilter)組裝在一塊並使之依據你所期待的方式運行罷了。DirectShow的架構,充份的發揮元件式開發的優點,也彰顯了其特色所在。


你會注意到,元件式的開發,為了達到具彈性、輕易的組裝方式,更為強調封裝的重要性。在現今我們所從事的開發中,就算沒有完全依據元件式的開發方式,也深受元件式開發的觀念所影響,極力的朝向更進一步的封裝而努力。


我們可以觀察到現今的應用軟體開發愈來愈有生產力,人們所建立的系統愈來愈龐大,而建造速度也愈來愈快。我們能夠克服軟體開發時的驚人複雜度,其中將軟體單元做某種程度的元件化,其影響不可不謂之大。如今,我們想開發各種應用軟體,充斥著各種現有的元件,舉凡視訊、音訊的編解碼、3D的繪圖、網路通訊、資料庫處理、各類數學運算、都因為元件化的特性,使得應用程式的開發者得以輕易的將它們整合到自己的應用程式中,在很短的時間內完成應用程式的開發。


另一方面,想要設計出元件化的軟體,程式員得需要具備一定的設計能力。程式員得學習如何進行適當的抽象化,他必須決定元件中有那些是不欲外界所知悉的實作細節,並且將它們隱藏起來,也必須決定對外公開的介面應當容納那些元素,以提供客戶端程式員之所需。而若想要使用軟體元件,客戶端程式員必須克服自己探究每一個細節的好奇心,他必須將自己檢視軟體的焦點擺在適當的抽象層次上,也就是說,他必須讓自己學會以介面的角度來看待每個軟體元件,讓自己站在介面層次上來運用每個元件。這也正是我們反覆不斷提起的「針對介面來撰寫程式,而不要針對實作」的設計原則。


我們時常會說,「你可以把XXX模組或YYY子系統當做是一個黑盒子」,便是利用「黑盒子(black box)」一詞指涉那些被我們封裝起實作細節的軟體元件,十分傳神的表達出封裝的概念。


一名程式員要學會將他人或自己所設計軟體元件視為黑盒子需要一些訓練。有許多初學的程式員總是試著要在運用每個元件前搞清楚它的細節,或者是在設計自己的元件時曝露太多的細節,這自然違反了封裝的原始精神及用意,而且對於應用程式的開發也沒有多大的用處。


軟體的黑盒子,基本上便是設計者的抽象化產物,抽象化的程度及方式決定了黑盒子所包裝的範圍及空間大小。愈是長於設計的程式員,愈能設計出合宜的黑盒子供自己及他人使用。


而客戶端程式員在將軟體元件視為黑盒子時,也是同樣的以一種抽象的眼光來看待自己所面對的元件。這意謂著客戶端程式員是以一種更高階、更一般化的方式來思考自己應如何撰寫程式碼,而自己所寫下的程式碼也將具備更多抽象、更少具象實作的特質,使得這些程式碼更為一般化,也能搭配更多可能的實作而毋需更動。


如此將軟體元件視為黑盒子的設計方式,可以說是許多主流的設計觀念,例如重覆使用、多型、封裝、介面化所結合在一起的產物。當你愈是能自在的以這些觀念來從事設計時,你會發現你所做的設計,以及你看待這些設計的方式,已經全然的黑盒子化了。而透過這樣的設計方式,你可以輕易的重覆使用別人所設計的元件,並且直接獲得生產力的補充。在建立自有元件時,你可以藉此阻隔不必要的實作細節,撰寫出更一般化的程式碼,更具因應變動的能力,同時更容易擴充。當程式員放棄探究隱藏在黑盒子中事物的好奇心時,上述的這些好處都是程式員所收到的回報。



 


Blogged with Flock

談程式語言的選用

程式員間倘若談到了程式語言之間的比較話題,無論比較的是那個程式語言較好、或那個程式語言最重要、或者應該學什麼程式語言最有幫助,總是能引起無止盡的論戰而且難以止息。這樣的話題就跟日本車、歐洲車孰優孰劣一樣,每個程式語言總有其基本支持群眾,爭論時往往各執一詞,使得這樣的討論主題很難歸納出什麼結論。

每個程式語言背後皆有其設計的中心思想及哲學,而每個程式語言也都隱含著有其設定的一套表述方式。每個程式員都有自己偏好的程式語言,而這偏好之所以會建立,和學習程式語言的經驗、過程,以及個人特質有關。例如,有些程式員就是偏好直譯式語言,但是也有許多程式員對直譯式語言望之卻步。就和很多的個人愛好一樣,有時很難解釋為什麼你就是偏好某一個程式語言。

在早期雖也有許多程式語言的發明,但實際上用於一般軟體開發的實戰語言選擇並不多。而到了現今,各種程式語言百家爭鳴,一般程式員可以接觸到的程式語言數量遠勝以往,對於究竟該學習或該採用那一個程式語言,其中可以抉擇的空間又大了許多。

以我的觀點來看,程式語言間的比較,其實是不具太多的實質意義。倘若程式語言對你來說是一種純粹的嗜好,並不存在太多開發上的實務考量,那麼僅以欣賞或喜好的心情來看待一個程式語言,甚至做為其擁護者,那麼是否選用一個程式語言,就是一個完全由個人愛好來決定的事情。但是,倘若你是在開發的過程中要選擇一個程式語言,那麼需要考量的事情相較之下就會複雜許多。

事實上,每個語言都有它特有的性質,發明者在設計每個程式語言時多半也都設定了一定的目標範圍,以及想要解決的軟體開發問題。隨著程式員的實際應用以及語言本身的逐漸演化,每個語言都會被發掘出適合的應用領域。

沒有一個程式語言是打遍天下無敵手的,每個語言都有各自的優點和缺點。優點的另一面往往就是缺點所在,例如Java的垃圾收集機制,簡化了程式員配置、釋放記憶體的模式,大幅的降低了程式員因為犯下錯誤存取記憶體的問題而耗去的大量除錯時間。但是,也因為垃圾收集機制的關係,使得Java虛擬機器設計更形複雜,也影響到Java虛擬機器執行時期的效率。你所開發的應用程式,或許可以接受現今Java虛擬機器的運行效能(事實上,Java虛擬機器的運行效能應當足以開發大多數我們會接觸到的應用程式),而選擇使用Java來避免無形中的錯誤,藉以提昇開發時的生產力。但如果你所開發的程式極需執行效能,例如多媒體視訊或音訊的解碼器,便可能採用像CC++之類的程式語言,甚至使用組合語言來撰寫,在這種應用情境下,開發的生產力不是關鍵,因為執行效能已經成了必要的門檻。所以,選擇開發時採用的程式語言,其實只是取與捨的判斷,優劣好壞不過都只是相對的特性,而沒有絕對的論斷方式。

程式語言也有流行的情況,你或許觀察到新問世的程式語言有時能引起一陣風潮,讓程式員們爭相追逐。但不可諱言的是,即使一個程式語言能引起短暫的流行,但每個程式語言都需要經過殘酷的考驗才得以生存下來。而歷時多年尚能存活至今的程式語言,無一不具備其賴以生存的重要特性。與其爭辯程式語言的好與壞,不如放開成見了解每個程式語言的特性,適合做什麼,以及不適合做什麼,才能客觀的於其中進行選擇。

優秀的程式員應當是程式語言中立的(programming language neutral),也就是說,你或許會專長、熟悉於若干個程式語言,但因為開發上的需要,你可以很容易學會、適應其他的程式語言。也就是說,當你從事開發時,並不會被特定的程式語言所限制住。最起碼,你必須熟悉多個程式語言並且能夠自在的運用。主流的程式語言思維模式不出幾類,例如程序式、物件導向式、函數式、或是混合模式等等,同一類的語言間即使語言語法或特性有所差異,但畢竟是源自於相同的血統,觸類旁通並不是件難事。例如C++Java以及C#,皆為一脈相承,尤其是JavaC#,二者相互模仿,熟悉Java的程式員,必能在極短時間熟悉C#,甚至應該不經太多的訓練,便能輕易的讀懂C#的程式碼。能以多種程式語言編寫,已然成了優秀程式員的判斷標準之一。

當你具備了以多種語言編寫程式的能力,就能夠(也應該)依照需求而非喜好來選擇程式語言,你也不會固定只採用一種程式語言來撰寫所有的程式。這已經是一個多語言開發的時代了。當你開發某個服務和產品時,時常會需要動用到多個程式語言。或許你會利用Java來開發伺服器端,利用C#開發客戶端的GUI部份,但利用C++開發客戶端的核心程式庫。選擇採用一個程式語言,是因為它最適合應用在你要應用的地方,而不是因為你最喜愛它。

那麼應當如何選擇開發所用的程式語言呢?通常這是一整個開發團隊針對要開發的專案而做的決策,因此必須考慮到所有團隊成員的技能特性。程式語言的選擇不單是個人化的,更是團隊化的。主要都會依據專案本身的特性及目標來決定欲使用的程式語言。你首先可能會考慮到客戶選用的平台,或者產品所設定的平台,有些程式語言基本上只在某些平台上可用,例如.NET上的程式語言,實務上只能在Windows的作業系統上執行。

除了平台之外,你會考慮到執行效能,有些系統元件必須滿足執行時間或者服務規模的限制,對於這些元件必須選用效能表現足堪滿足的程式語言。開發的生產力也是很重要的考量因素。專案都有其執行的時間期限,面對時程緊迫的網站應用程式,你或許會考慮以Ruby程式語言搭配RoR應用程式框架的方式來做為程式語言的主軸,善用RoR的高生產力。在提供.NETWindows平台上,選擇C#之類的程式語言來開發GUI,生產力多半能勝過VC++搭配MFC的方式。此外,開發程式的穩定度、支援的程式庫豐富與否、或者是否提供了你所需的程式庫,都是選用時必須考慮的條件。

在同一系統中混用一種以上程式語言的情況已經愈來愈常見,這使得我們更能輕易的善用每個語言的優點,規避掉持定語言的缺點。採用多語言開發時,還必須考慮所選用的程式語言是否能夠相互整合,整合的方式、介面是否滿足需求及限制條件。例如使用Java做為主要的開發語言,又想使用C語言撰寫需要高效能的模組時,就必須考慮使用JNIJava Native Interface)做為二者界接的方式,但使用JNI又會失去平台的可攜性,決策者就必須於其中取捨。

當兩個備選的程式語言條件勢均力敵或是相差不遠時,應該要選擇自己所熟悉的。對程式語言的熟悉度能夠讓你避免許多因為陌生而造成的不必要陷阱,也可以避免掉許多無謂的時間浪費。

許多程式員會擔心某個語言是否會退流行,或者是擔心沒有趕上最新流行的程式語言會讓自己淘汰。我的看法是,與其擔心沒有跟上最新的流行,不如想想如何掌握不同程式語言的共通之處,也就是本文中所提到的,主流的程式語言思維模式其實不脫幾類,而且甚至以物件導向與程序式混合的程式語言為主。熟悉這種表達方式,要操作不同的程式語言,其實只是語法以及細節的獨特語言特性不同,跨多語言其實不構成太大的問題。關鍵往往不會是在語法,而是在你怎麼做抽象層次上的設計。

與其爭辯程式語言孰優孰劣,不如更自在、更恰到好處的運用多種程式語言於你的開發之中。優秀的程式員應當是程式語言中立、能同時以多種程式語言從事編寫的。

Blogged with Flock

pageicon 星期三 八月 27, 2008

ffqlay at SourceForge.net

我在SourceForge.net上建立了一個叫做ffqlay的專案,並且把ffqlay目前的一些產出都放上去了。你可以從這邊進到這個專案。除了之前提供下載的檔案外,我把製作出來的Win32
DLLs
檔案也放上去了,如果你只是個單純的Windows應用程式開發者,不想自己build出這些檔案,它們可以提供一些偷懶的空間。

我使用的ffmpeg原始檔,是取自 “Unofficial FFmpeg Win32 Builds” 中的r13981(這個站不知怎麼了,現在連不上),gcc使用的則是 TDM Experimental GCC/MinGW32 Builds
上的GCC 4.2.4-tdm-1(使用4.2以上的版本,ffmpeg才不會給你 Compiler did not align stack
variables. Libavcodec has been miscompiled and may be very slow or crash. This
is not a bug in libavcodec, but in the compiler. Do not report crashes to
FFmpeg developers.
的警告訊息)。此外,SDL用的是SDL-1.2.13

單純的把這些dll檔案和ffqlayDemo的執行檔放在一塊便能夠使其執行。

在這個ffqlay-0.1.0release中,加上了

int FFQLAY_get_volume(void)

int FFQLAY_set_volume(int
volume)

這兩個用以取得音量以及設定音量的函式。它們並不會改變實際硬體的音量,它們只是單純的利用SDL中的函式,調整audio
sample
,藉以控制ffqlay所輸出的音量罷了。

日後若有什麼問題,就直接利用SourceForge的相關機制來討論囉。

文件也會整理出來。:p

pageicon 星期五 八月 22, 2008

ffqlay API說明

ffqlayC函式的方式提供一組API,為多媒體檔案的撥放提供支援,在本文中則說明這組API中的函式,以及其作用。

首先是FFQLAY_start(),其原型宣告為:

int FFQLAY_start(int argc, char
**argv, HWND hwndParent, int width, int height);

FFQLAY_start的用途在於啟始多媒體檔案的撥放動作。引數argc以及argv是原ffplay程式中main()自命令引接收的引數,ffplay的使用者可以透過命令列引數設定ffplay選項。在這個最初始的版本中,為了簡化起見,先不更動控制ffplay引數的方式,因此保有原有int argc, char **argv的型式,在日後的階段,將會設計API來支援選項的設定。最簡單的情況,你只需要指定argc2,而argv[0]為任意名稱,argv[1]為欲撥放的檔案路徑即可。

如果你希望ffqlay的撥放畫面被放置到某視窗下,也就是說讓該視窗成為ffqlay撥放畫面的父視窗時,你可以指定hwndParent為該父視窗的window handle。倘若你沒有這樣的需求,將它指定為NULL即可。

此外,你可以透過widthheight引數指定所欲撥放視窗的寬及高,在撥放時會依據你所指定的寬高來呈現影像。

FFQLAY_start在執行之後,會啟動一個執行緒來執行其內部的event_loop(),也就是ffplay原先用來處理各種撥放事件的函式(不過這個函式已經被ffqlay大幅的縮減,日後說明ffqlay的修改時會再說明),因此它並不會遲滯呼叫者所在的執行緒,在啟動撥放動作之後,FFQLAY_start便會返回。

那麼,應用程式要如何知道ffqlay已經撥放完畢呢?讓我們來看看下一個函式:

int
FFQLAY_get_play_state(void);

它有可能回傳(參見ffqlay.h)以下的回傳值:

FFQLAY_PLAY_STATE_PLAYING1):撥放中

FFQLAY_PLAY_STATE_PAUSED2):暫停

FFQLAY_PLAY_STATE_ABORT3):放棄

FFQLAY_PLAY_STATE_STOPPED4):停止

應用程式可以透過呼叫FFQLAY_get_play_state()來取得目前的狀態。目前ffqlay尚不支援事件的主動通知,所以應用程式無法透過設置callback函式之類的方式來接收撥放狀態的改變。

接著,正如撥放狀態中所展示的,你可以在你的應用程式中暫停或停止撥放的動作,只需分別呼叫:

int FFQLAY_pause(void);

int FFQLAY_stop(void);

你可以透過

double
FFQLAY_get_duration(void);

來取得檔案的撥放長度,回傳的double值其單位為秒。

你可以透過

double
FFQLAY_get_position(void);

來取得檔案目前已撥放的進度,回傳的double值單位同樣是秒。

另一方面,呼叫

int FFQLAY_set_position(double
position);

可以設定撥放位置,單位同樣是秒,這個函式可用來實作撥放時的seek功能。

最後,如果你在撥放的過程中想要變更撥放視窗的大小尺寸,可以使用

int FFQLAY_resize(int width,
int height);

分別傳入欲變更的寬及高,即可達成你的目的。

目前提供的函式就是這麼簡單。在ffqlayDemo專案中展示了如何利用這少數幾個函式即可完成一個典型的多媒體檔案撥放器(當然,GUI極其原始)。

另外,ffqlayDemo中的FFQlay.cs展示了如何在C#中使用ffqlay。它利用System.Runtime.InteropServices中的DllImport,能輕易的在managed.Net程式中使用unmanagedWindows DLL函式。所有ffqlay中的C函式,在FFQlay這個C#類別中都有相對應的函式。對於C#程式員來說,如果你不熟悉DllImport,你會發現FFQLAY_start的宣告方式有點意思:

public static extern int
FFQLAY_start(int argc, [MarshalAs(UnmanagedType.LPArray,
ArraySubType=UnmanagedType.LPStr)] IntPtr[] argv, IntPtr hwndParent, int width,
int height);

public static void
FFQLAY_start(string fileName, IntPtr hwndParent, int width, int height)

{

        IntPtr[] argv = new IntPtr[2];

        argv[0] =
Marshal.StringToHGlobalAnsi("ffqlay.exe");

        argv[1] = Marshal.StringToHGlobalAnsi(fileName);

        FFQLAY_start(2, argv, hwndParent, width, height);

        Marshal.FreeHGlobal(argv[0]);

        Marshal.FreeHGlobal(argv[1]);

}

它展示了如何建立char **argv以傳入C函式,並且處理字元集的問題。我對.Net並不熟悉,這是我目前所能找到的最好方法。:)

以上,簡單的說明ffqlay所提供的撥放API

pageicon 星期三 八月 20, 2008

工作以外的程式設計

在我們當中的許多程式員,最初踏入程式設計的領域,是基於對程式設計的喜愛。程式設計是一項十分能產生樂趣的活動,有著讓人無法自拔的魔力。我還記得就讀高中的時候,在某次月考前的前夕,好不容易把隔天要應考的科目準備完畢,趕緊衝到電腦前面打開電腦,開始寫起程式來。即便夜已深,且隔天仍有重要的考試,但仍舊像著迷一般的鑽進程式碼構築出來的虛擬世界裡,樂此不疲。程式設計彷彿成了治療考試壓力的最佳良方。

細究起自己之所以喜歡上設計程式,最大的原因應該是透過程式設計所展現出來的創造的力量。透過程式設計達成的創造是一種很特別的型式,因為它完全是虛擬的。我們所寫下的程式碼,雖然沒有物理的存在,但是卻又能夠讓程式的使用者,產生真實的體驗及感受。我相信許多程式員都和我一樣,初入門程式設計的技巧之後,最想做的事情就是撰寫電腦遊戲。背後的主要原因當然不是因為自己想玩自己撰寫出來的遊戲,而是為了要體驗身為造物者的那種感覺。做為電腦遊戲的創造者,你創造出遊戲中的每一項事物,舉凡角色扮演遊戲中的一草一木,射擊遊戲中每一關的大頭目,甚至是俄羅斯方塊中的方塊造型,完全都操控在你的意念之下。透過程式設計的活動,你賦予這一切生命,並使其活躍,在你的遊戲裡,你就是上帝。電腦遊戲的程式設計,無疑的是這種虛擬形式的最佳詮釋。

對我來說,透過撰寫程式所產生的虛擬玩意,能夠進入別人的生活,對別人的生活產生某種真實的影響,就是撰寫程式所能獲得的最大樂趣。

每個喜歡程式設計的人,不盡然都是為著相同的理由喜歡上這個活動。但是,仔細回想,在學習程式設計的那段時日裡,我們心中充滿著對程式設計的熱情,支持我們投入大量的時間,一點一滴的積累程式設計的經驗及技巧。即使程式設計不是我們的工作,我們也把它當做興趣一樣的在經營,即使佔去許多生活的時間,也不覺辛苦。

有一天我們踏入了職場,或許成了所謂的「程式設計師」或「軟體工程師」。程式設計也從業餘的興趣成了專職的工作。我們也許會發現,自己昔日愛上程式設計的那個原因,在專業的軟體分工體系下,早已消失殆盡。在專業的軟體分工體系下,每個人各盡其職,扮演各自的角色。或許是產品經理決定產品的規格及長相,架構師決定整體的架構,系統設計者,設計系統中的類別介面及互動的方式,程式撰寫者,則依據設計進行實作。在這樣的工作模式下,許多程式設計者所追尋的元素都已不復存在。有些程式設計者喜歡的是天馬行空的自由,有些程式設計者和我一樣喜歡的是創造的感覺,但很可惜的,在常見的開發工作中,我們並不容易從中獲取,程式設計者不再能夠自己決定自己想做什麼,我們或許失去了某種型式的自由,也失去了某些創造的感覺。這或者就是一種興趣被工業化後的結果吧。

也許你發現了,或者沒有發現,自己對程式設計的那份熱情日益消退,因為它成了工作的一部份。一方面因為工作帶來的壓力,一方面也因為自己在工作無法取得自己想要的元素。於是,漸漸的,程式設計成了負擔,你猛然發現它再也不是治療壓力的良方,反而成了製造壓力的來源。你開始不喜歡在下班時間撰寫程式,甚至希望撰寫程式的時間愈短愈好。支持你繼續撰寫程式的動力,不再是熱情,也不再是能夠享樂於其中,而是經濟的來源或是在職場中的職務升遷。

我想,這應該是一名程式設計者所會遭遇到的嚴重困境之一了。

程式設計這一項活動,需要以熱情加以灌溉才容易有所成長及茁壯。倘若程式設計這門學問有個終極的道,那麼我相信,你必須投入非常多的時間,才能在通往這個道的路上往前邁一小步。你得投入許多的時間,經歷許許多多看似平凡無奇的事情及經驗,才能有所領悟。或許程式設計領域真有天才,但我寧可相信許多在這個領域中出類拔萃有所成就的人,其成就來自於其熱情而非天份。只有對程式設計懷著高度熱情的人,才能以熱情驅動自己投入更勝於常人的時間及心力。這些時間,不論是用於技巧的反覆鑽研,或是錯誤的嘗試,最後都轉化成為在這門學問上不斷精進的養份來源。

對程式設計喪失熱情,對一名程式設計者能造成極大的傷害,其原因便在於此。當你的熱情消退,便不再願意投入更多的時間,間接的切斷精進養份的供給。或許你就只能在原地踏步,反覆做著自己已經熟悉的事情,但卻是更難再上層樓。即使從現實的角度來看,你的薪資也難以隨著能力的提昇而調漲,職場中向上的動力也有所不足。

我也曾身陷在這樣的泥淖困境中,或許也是在自己程式設計的生涯中的一大低潮。有一天,我突然發現自己其實是失去了熱情,失去了當初那種想要創造一些東西,接著改變許多人生活的動力,因為現實生活中的許多工作,早就壓的自己喘不過氣來。

要拯救自己脫離泥淖,就得找回自己消逝的熱情,要找回消逝的熱情,並不是讓自己遠離撰寫程式的圈子、減少程式設計的工作量,而是重新歸位到自己對程式設計熱情的發源地。我開始在工作之外開發一些小東西,這些小東西規模都不大,但做的都是源自於自己的想法。自己從頭到尾包辦了所有的工作,沒有專業的分工,自己既是產品經理,也是系統設計者,同時撰寫程式碼以及測試。每個不同的想法都會需要一些不同的新技術,在開發的過程中,有機會接觸到這些新的技巧。而更重要的是,這像極了最初開始學習撰寫程式時的模式。自己想到什麼就寫些什麼,既沒有規格也沒有必須完成的期限(所以也沒有壓力)。有趣的小東西可以發送給朋友甚至是公開給大眾試用。這個過程與其說是在開發,不如說是在玩樂,我可以盡情的操弄我自己隨心所創造出來的玩意兒。慢慢的,我覺得彷彿又拾回昔日從程式設計中所獲得的樂趣。我也同時發現,重新燃情的熱情,也從工作外感染回工作內,沖淡許多因為工作壓力所帶來的一些不愉快的情緒。甚至,我發現即使是因為工作的關係而撰寫程式碼,自己也能樂在其中,沉浸滿足於那種解決問題的成就感。寫程式的時間變得更多,但人卻更快樂了。

工作難免為了五斗米折腰的壓力所迫,必須做些自己或許不甚願意做的事情。但是,我們最初之所以想成為一名程式設計者,多半都是基於自己對程式設計的喜愛。千萬別讓工作磨損了這份熱愛,仔細回想自己喜歡程式設計的初衷,在工作以外,選擇一個沒有壓力的方式,重新體驗多年前讓你沉迷的那種感覺,你不但能重新找回對程式設計的熱情,也會重新發現自己工作中能讓自己快樂的地方。

Blogged with Flock

把對母乳媽媽的感謝與支持傳出去

« 九月 2008
星期日星期一星期二星期三星期四星期五星期六
 
1
2
3
4
5
6
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    
       
今日

Search this blog

Links

Weblog menu

Today's referrers

Feeds