1. 程式人生 > >程式設計師接私活經驗談

程式設計師接私活經驗談

正文:(一)專案確立

一年前,CSDN的外包頻道,一家貿易公司尋求開發業務系統。我注意到這家公司和我正好在一個城市,索性就跟了一帖,寫了點簡要的個人開發情況,當然最重要的是附上了自己的手機號碼(當時CSDN外包頻道還不限制這個資訊的)。第二天就接到那家公司總經理的電話,這讓我多少有點意外,電話中,雙方客套兩句後,約定好週末面談。

和以往面試一樣,我帶上個筆記本(上面有以往開發的專案演示版)按照約定好的時間,準時去洽談。地點是在對方的辦公室,一進會客室,給我第一感覺整齊、清新、優雅、綠色;窗外則是寧靜的半島和微瀾的海浪,心情頓時感覺非常暢快。

電話中那位非常紳士的總經理,年紀大概45歲左右,我們的談話直奔主題。我先簡單介紹了一下自己的情況(工作和開發經歷),用筆記本演示自己以前開發過的兩個類似專案情況,他則不時地提幾個關心的問題。然後,他簡單地將自己公司的需求告訴我,並把現行的系統的主要功能演示給我看了看。

整個談話過程中,我印象最深刻的是他最後時刻說的話:“我看了你以前開發的系統演示,認為你完全有能力開發我們的系統;我也不打算再尋找其他人來面試,因為我的時間不允許我這樣做。你如果覺得剛才我們談到需求內容和開發價格都合適,那麼我們就此開始合作。”

我是個程式設計師,他是個商人,我們的合作就此開始。


正文:(二)需求確定1

有了第一次的面談,我對這家公司的整體印象不錯。說起來,我以前去過不少公司(自己工作過的公司或談專案去過的公司),尤其是從事貿易的公司,還是第一次見到辦公室這樣讓人感覺如此舒服的。

簡單說一下我需要開發的系統,其實並不複雜,就是一個典型的貿易系統,主要功能是管理公司的產品、客戶資訊,然後給客戶報價、生成合同、給廠家下生產單等等。當然,這每一個模組中都會有很多特定的需求,例如,產品的價格組成,當某些價格組成發生變化時,系統需要自動更新到所有可能產生影響的部分去。

(那位非常紳士的總經理,為了敘事方便,給他取個名字吧,就叫Gentleman吧)

Gentleman把他們現在使用的系統,發了一份給我,在我看來這個系統簡直就是一個學生的實習作業。無論從系統的效能上,還是操作的介面上,邏輯的條理性上,都存在很多的問題。但就是這樣的系統,Gentleman居然使用了近7年的時間,這讓我感到很驚訝,甚至於難以理解。而Gentleman經常在需求的溝通過程中,提到他們原先的系統如何如何實現,我心中總是會非常不舒服,覺得拿這樣原始而粗糙的系統來與即將開發的系統相提並論,我認為是對我的輕視或者說低估。

對了,需求中有個重要的部分,那就是資料同步。因為Gentleman長期定居在國外,每年只回國兩次,每次大概一個半月,平時他都是通過IM和Email來管理他的公司。


正文:(三)需求確定2

我用2天時間,把他們原先的老系統的所有功能,都'學習'了一遍,在自己大腦中已經有了一個比較清晰的輪廓。其實行業軟體,大家只要熟悉其業務流程,就會感覺非常簡單。因為從程式實現上來看,主要工作就是資料庫的表結構設計,以及相關前臺介面的操作合理性。

Gentleman在他回CA國之前,約我再見一次面,並給我發來一份他自己整理的需求文件(20頁左右)。因為我白天要正常上班,而他的返程機票已經訂好,所以我們只能約定好晚上見面。這次,他約我的地點是一家五星級酒店的自助餐廳。用他的話說,他不知道該去哪合適,只知道這個地方吃飯還比較自在,他喜歡這的環境。這家自助餐廳給我留下的印象,就是用餐的外國人比中國人多,當然Gentleman給我的感覺也有點像個外國人,只是和我說話的時候還是用中文而已。

我們邊吃邊談系統的需求,他把自己需求檔案中描述的內容,再給我講述一遍。而且講得非常仔細,生怕我有不明白地方。其實他說的大部分內容,對於一個有8年開發經驗的程式設計師來說,完全沒必說得這麼細緻。當然,我也不打斷他的思路,只是默默地聽著,因為我不想讓他以為我很狂妄。我看著他認真的神情,思想反倒有點走神,腦子裡尋思這一個問題:我什麼時候能像他這樣工作和生活?

就係統的需求,我們聊了大概有3-4個小時,從自助餐廳到酒店大廳的會客區。Gentleman想把他所有能想到的想法和問題都告訴我,因為他明天就要飛回CA國,這半年內,再也沒有這樣好的溝通機會了,畢竟Email中的描述只能停留在字面上。

那夜,我回去後,腦子裡並沒想任何系統需求,只是一直在想:我什麼時候能像他這樣工作和生活?


正文:(四)系統整體設計1

需求大致上瞭解以後,我開始著手系統的整體設計工作。

首先,從應用角度上來看,這個系統是準備在一家30人左右的公司執行,而且Gentleman需要在自己的筆記本上安裝一套系統,並與國內公司這邊進行資料同步。另外,他們公司在每年的春秋廣交會期間,都會帶產品去參展,期間有5-6檯筆記本需要使用系統,以便隨時給客戶報價。所以說,各個資料庫之間的同步,是這個系統的一個非常重要內容。

其次,我開發系統有個習慣,即在完成系統功能的同時,比較注重介面的設計。這個習慣,也讓我在這個系統上多花了30-40%的時間(Gentleman對於介面並未做任何要求)。但我認為是必要的,我們程式設計師在寫程式的時候,都使用IDE工具,我個人的感覺,如果這個開發工具非常醜陋或看起來彆扭,在開發系統的時候,是會非常不舒服的。同理,業務人員每天都是使用這套系統來工作,如果系統的介面非常差,操作起來很彆扭,那工作簡直就是遭罪。

還有,系統的整體框架。我沒有采用以前開發過度系統框架,雖然這樣能節省我很多時間。但我仔細考慮了一下,由於這個系統對於時間要求並不緊迫,而我也想積累更多的系統框架,所以最終決定在原框架的基礎上做許多升級改良,以便更試用於這套系統。

(不少程式設計師開發系統,是一套框架多處使用。我認為如果時間不是很緊張的情況下,完全可以設計更好的方案。這樣在接下一單專案的時候,就可以有更多更好的系統演示給客戶看)

系統的功能就像人的五臟六腑,介面則是人的長相和外衣;長相雖然不影響身體健康,但絕對影響找物件,呵呵,所以說,介面是個不大不小的問題。


正文:(五)系統整體設計2

Gentleman回CA國後的一個月內,他仍然每週都給我發過來最新的系統需求,其中有專題性質的(例如:某處的價格演算法,以及價格調整的系列影響),也有系統整體性的需求調整。我則有條不紊地地分析著每份需求檔案,從這些需求檔案中,我能感覺到Gentleman對這個系統的期望值很高,因為他不僅是在提需求,甚至是在做程式設計工作,哪些部分需要加按鈕,這些按鈕完成什麼功能,具體某個欄位是下拉列表顯示,還是彈出視窗等等。

在此期間,我並未急於做實質性的業務程式開發工作。我從Gentleman的眾多需求檔案,逐步整理和設計出系統的幾個核心表結構,在這幾個核心表結構還沒有相對穩定之前,我是不會寫一行業務程式程式碼的,這是原則。當然,我的程式框架的改進工作是一直在同步進行的,因為程式框架部分和業務程式部分幾乎是平行的,只需要在框架中考慮到幾處重要的StatusBar和ProgressBar,以及系統的整體顯示風格即可。

(即便如此,在後續的開發過程中,還是出現了需要調整核心表結構的情況,當然這是後話,暫且不提)

隨著核心表結構的設計過程,我的腦海中正在一步步地形成整套系統的資料脈絡(主業務資料流和輔助資料流)。與此同時,Gentleman經常在傳送新需求檔案的同時,詢問系統的進度情況。而此時的系統進度只是在我腦海中,在一份資料庫表結構檔案中(我沒去寫非常詳盡的設計資料,因為一個人的系統沒必要把過多的時間放在文件上,文件工作是對於協同開發小組比較重要的),我無法讓Gentleman感知進度的情況。我只是告訴他正在做系統的設計工作,我也沒傳送改進好的程式框架給他看,我認為把一個半成品給對方看,還不如不給對方看。

Gentleman很理解我的工作,雖然我的當前的工作彙報只是停留在口頭上。噢,又忘交代了,Gentleman在成為商人以前是學計算機專業的,不過,我至今還不知道他是否當過程式設計師。

中間插一討論篇《程式風格》,本篇與這個專案開發有些關係,但並不納入到正文中。

歡迎各位程式開發高手積極討論一下。


討論篇1:程式風格

程式是什麼?不同的角度有不同的看法,比較經典的論斷是 程式=資料+演算法。資料是一套系統的核心,他的地位是不可動搖的,好比人民的溫飽問題。演算法是什麼,演算法是系統的引擎,演算法的好壞優劣決定了程式執行的效率。但隨著現在硬體技術的提高,很多程式設計師已經淡化了演算法的重要性,以完成功能為標準,這是可悲的事情。

依我的看法,程式不光是資料+演算法,那只是程式的行體部分;程式還需要有風格,這才是程式的神態部分。只有形神兼備的程式,才是一個優秀的程式。程式風格又包涵哪些內容呢?在解釋這個問題之前,我們先設想一下,如果一個閉月羞花的美女,出口就是髒字;如果一篇行文灑脫的文章,字確寫得東倒西歪;如果一座雄偉的山峰,上面確寸草不生。那樣是不是很煞風景?

程式風格是什麼?程式風格就是一個程式中,在資料內容以外所體現出來的內涵,它表現在程式的各個方面。從使用者的角度:主要體現在程式的整體顯示風格(顏色基調、圖示風格、字型大小)和互動風格(資料組合方式、功能區劃分、操作流程);從程式開發者的角度,它包括專案的管理、原始檔的組織、程式碼的風格、註釋的寫法。

對於一個人的專案,程式的風格就取決於你的個人風格。程式設計師在鍛鍊開發技術水平的同時,應該同時培養你的程式風格。

恭候拍磚!


正文:(六)Coding 1

程式的風格和核心資料庫表基本確定後,我開始了系統的模組設計和編碼工作。我的基本思路是,按照程式模組的重要性,逐個模組實現。單個模組的設計和編碼同時進行的,完成好一個模組,就傳送給Gentleman稽核,以模組程式為交流載體,方便雙方溝通。

夜晚22:00後,靜夜孤燈下,一杯水,一個人。時而低頭沉思,時而握筆繪圖,時而指走鍵盤,這就是我平時工作的畫面。一行行程式碼,一個個畫面就這樣躍然螢幕上。

系統中最先做到是產品管理模組,大家可能會認為這樣的模組應該是比較簡單的。是的,如果只是實現新建、編輯、刪除功能的話,肯定很簡單,但我確故意要將簡單的東西複雜化。廚師的水平高低,不在菜上,而在於做菜的功夫上。

我在實現產品管理模組時,考慮到很多問題。如何將主貨號和詳細貨號關聯?主貨號中的哪些欄位應該與詳細貨號中的相同,兩者之間應該怎麼顯示和編輯最合理?程式實現的過程中,哪些模組可以共用,哪些欄位需要冗餘?編輯某個貨號的時候,應該怎麼顯示其他貨號的詳細內容作為參考?怎麼讓業務員輸入最少的資訊即可完成操作?

上面這些問題,有Gentleman提到的,更有Gentleman沒提到的。我認為系統的開發過程,就像一段外語的翻譯過程,有人是直譯,有人是意譯,孰高孰低,明眼人一看就知道。至於其中多付出的勞動,雖然只有自己知道,但同樣可以體現在你的勞動成果中。

在我的觀念中,開發系統不僅僅是為了開發而開發,應該再提升一個高度,至少要讓自己滿意。後來證實我的思路是正確的,Gentleman對於我的程式實現方式,很滿意,或者說讚賞。以至於他總是說我聰明,能準確地理解他的意圖,並恰當地實現出來。具體體現在他的需求文件中,以往那些瑣碎的、近似設計的描述少了,他只提他想要的結果,具體實現他已經不用操心了 - 這正是我的目的。

我和Gentleman的關係,開始有點像Partner了。


正文:(七)Coding 2

自從編碼開始後,專案開發工作似乎進入了正軌。

這套系統的編碼過程中,有一個十分麻煩的地方,那就是貨號價格的變化,需要更新多非常多的地方。這些都是Gentleman在常年的工作中總結出來的,他心中非常清楚。他只要一看這些價格數字,就能知道哪些是正確更新後的,哪些是未更新的。可我在短時間內確是很難做到的這一點的,因此,我單獨寫了一份價格更新對照表,雖說整理著份檔案花了不少時間,但磨刀不誤砍柴功,這份檔案在後續的工作中發揮了重要的作用。

因此,我認為在開發過程中,對於那些容易混淆或需要非常仔細的地方(例如:本系統中的各種價格組成、公式、更新對照等),應該單獨寫份文件作為專案參考資料(這份文件一定要準確無誤),即便是一個人開發系統,也有必要。就像Windows API參考文件一樣,當程式需要呼叫具體API函式的時候,只要查一下參考文件就可以了,完全沒必要去記住那些具體引數,因為短時間內去記住那些引數,是不現實的。隨著開發的過程,對於那些經常呼叫的部分,自然就熟悉了。

編碼的過程,是對設計的逐步修正的過程。設計時理解不準確的部分,在Coding的過程中,都會逐一發現。

很多人羨慕一個人開發系統,其實一個人開發系統的優勢和劣勢同樣明顯。優勢在於整個開發中,省卻了所有的開發溝通時間,因為整個系統(哪怕是非常細小的環節)都瞭然於胸;劣勢就是孤單,遇到任何技術問題都必須自己一個人去解決,解決問題後的快感也沒人分享。

這個劣勢在後續的開發中,給專案帶來了一點問題。


正文:(八)Coding 3

編碼的工作是辛苦的,遠沒有程式設計時的天馬行空,需要的是嚴謹的工作態度、良好的編碼習慣和相對完整的開發時間。對於Part-Time開發者來說,很多人覺得非常辛苦,主要是因為沒有完整的開發時間。

專案的開始階段,一般開發者都能保持相對高的開發熱情,但一旦進入編碼的中期,這種熱情支撐下的開發進度就開始疲態盡顯。我也是遇到了同樣的問題,專案進行了3-4個月左右的時候,開發進度明顯比預期的低了很多,就連大洋彼岸的Gentleman也能明顯感覺得到。

Gentlman開始有些著急了,經常在Email中詢問開發進度(其實就是催促開發進度),並主動提出快速開發獎勵。我非常清楚Gentleman的心思,首先,他是想在下一次的廣交會之前使用上這套新的系統,以便提高工作效率;其次,他是認為我當前的系統開發質量比他原先預期的要好,所以很樂意提高開發費用。面對相對優厚的額外獎勵(這是Gentleman高明的地方),我也很想提高效率,但由於種種原因我很難進入快速開發狀態。

多說兩句當時的情況,權當為自己開脫吧。其一,專案進展到3-4個月左右的時候,我老婆正到預產期,我可愛的女兒來到了這個花花世界;其二,在去年轟轟烈烈的A股牛市中,我這新股民懷著快速發財的夢想,在5500點的高位殺入了大量的資金,結果虧損嚴重,致命的是這些資金有大部分不是自己的存款。這讓我承受了巨大的精神壓力,幾次出現失眠的情況。僅此兩點,大家就可想而知我當時的狀態了。

心態上無法進入工作狀態,時間上無法保證開發時間,一個人的戰鬥,孤立無援,我把專案帶入到了最艱難的境地。


正文:(九)Coding 4

面對Gentleman的額外獎勵,我深感慚愧,雖然內心很想加快開發進度,但當時的心思確又很難聚焦到專案開發上來。這樣渾渾噩噩的狀態大概延續了一個月左右,專案的開發進度比預期已經差了一大塊。我幾次想在Email中告訴Gentleman我的痛苦,但炒股導致的心理失衡問題,怎麼能讓他去承擔後果。我問心有愧啊!

即便在如此情形下,程式的程式碼質量還是我把握的第一要素。要麼不寫,要寫就一定要保證質量,我絕對不會做殺雞取卵這樣的事。盲目上線帶來的一定是後續更大量的補救工作,同時也會影響客戶的信心。這一點,應該也是Gentleman欣賞我的地方之一。

隨著春季廣交會時間的日益臨近,Gentleman已經感覺到專案無法在此之前完成,但他表現得非常大度。不僅沒有過多地責怪我,相反還繼續鼓勵我,額外獎勵依然有效,只是要求我全力把程式開發好。Gentleman的做法,讓我非常感動,我時常自己在問自己:如果我不能及時調整好心態,不能堅持把專案開發好,對得起Gentleman這樣的好人嗎?

我的名言:生命就是折騰與被折騰的過程。

這渾渾噩噩的一個多月,其實就是我個人心態的築底過程,而這心態鑄底成功的因素中,我清楚,有Gentleman一份功勞。伴隨心態的調整成功,專案開發也重新步入正軌。當然Gentleman也從CA國飛回到本市,開始籌備公司的春季廣交會的展覽。

準確的說,此時此刻,系統的編碼工作已經完成了80-90%


正文:(十)資料庫選型

個人專案中,心理層面的問題需要自我調節,技術層面的問題同樣只能獨自解決,下面就寫點技術問題。

在這套系統的資料庫選型中,我是經過一番思考的。從我個人技術熟悉程度上來說,是對DB2和Sql Server比較熟悉。但對於30人規模的中小型公司,沒必要選用過大的資料庫,Oracle、DB2這類首先被PASS掉了,在Sql Server、MySql、Sybase ASA中,MySql中,到底應該選用哪個呢?

可能很多人認為Sql Server應該是首選,最初我也在重點考慮它。但是Sql Serverd資料庫,部署起來有點麻煩,考慮到Gentleman是長期在國外生活,在系統開發的過程中,我時常需要對資料庫的結構進行調整。因此,資料庫一定要便於打包和部署。其次,考慮到資料同步問題,因為這個系統最終資料庫的部署,是需要在公司本部放一箇中心資料庫,另外幾臺筆記本上各放一個遠端資料庫。而這些資料庫之間,要能夠非常方便的進行資料同步。此時Sybase的Mobilink同步技術就進入了我的視線。(在這個專案之前,我並未做過資料同步方面的工作)

綜合上面兩個主要問題,我最終選擇了 Sybase Asa 資料庫,這款資料庫,非常方便部署。更新資料庫的時候,只需要直接替換資料庫檔案和日誌檔案就可以。而且我從Mobilink的資料中瞭解到,它是基於偶連線的同步技術,專用於中心資料庫與多個移動資料庫的資料同步的解決方案。我心想:Mobilink技術簡直就是為我們這種應用而設計的。

同為Sybase的產品,ASA資料庫理應與Mobilink無縫銜接。


討論篇2:技術與應用

很多在校的學生和入行的新人,總是最關心開發技術,而且最關注流行技術。就好像流行時裝一樣,看哪些語言或工具流行,就學哪樣,有甚者把市場主流的應用開發語言都學了個遍。其實大家會發現一個問題,即便學習了所有的開發語言,仍然不可能就此成為開發高手,因為他們學到的只是外在功夫,而非內功。

關於技術的內功和外功問題,大家只需要在開發的過程中,稍微用心體會一下,就可以找到練內功的方法。寫程式碼的時候是不是頻繁 Ctrl+C 和 Ctrl+V ,而不去琢磨複製過來這段程式碼或演算法的基本原理?函式中的引數設定,是否僅僅滿足功能就可以,還是需要預留下某個擴充套件?哪些功能程式碼可以抽象成一個類來實現,而非在程式中到處Copy同樣的程式碼?等等!

(書法作品中一筆一畫即能體現深厚的功底,想成為行家,就應該在程式的每個地方有自己的心得)

同樣的程式,從客戶角度,他們關注的側重點是完全不同的。依據我的開發經驗,客戶基本上不關注系統採用的技術架構,哪怕你說得天花亂墜,那最多隻是談價格的一點小資本而已。他們關注的是系統功能,能否設計出他們認為最快捷、最安全、最實用的系統。“落後”的技術,同樣有廣闊的生存空間。因為對於客戶,適用的就是最好的。

一個人做專案的時候,請記住:技術不是越新越好,而是越適用於專案越好,越熟悉的技術越好。在技術上你站得越高,專案的成功率就越高。(想學習和鍛鍊新技術,最好請到其他的專案組中學習,因為一個人的專案,新技術意味著無數未知的問題)

恭候高手拍磚!


正文:(十一)專案中期收款

Gentleman回國後的這一個多月時間,幾乎一直在忙於春季廣交會的事情,很少和我聯絡。只是約定等他從廣交會回來後,讓我去他那領取部分專案款。

(在第一次面談的時候,Gentleman就問過我專案收費方式的問題。現在一般公司的付款方式是361方式,即30%作為專案啟動款,60%在專案驗收後付款,10%的尾款最後在確認系統執行正常後付清。而我給Gentleman的答覆是,專案開發前我不收任何款,等系統基本成型後(即客戶可以認同開發質量和效果後)付60%的專案款,正式上線執行後,再付40%的專案款。

我之所以採取這樣的收款方式,首先,我對自己的開發實力有信心,相信客戶在見到系統後,會樂於付款;其次,我考慮對方是一家公司,而我是個人開發者,讓對方提前把錢付給個人,這其中的風險明顯大於付給一家公司。而我關心的是專案款的多少,並非付款時間。)

這次,我們見面的地點是Gentleman在本市的House,我按照約定好的時間準時到達。他的房子位於本市一段黃金海岸線上,從室內就能看到浩瀚的大海,總面積約有160平米,價值至少兩百多萬。屋子以淺色調為主,傢俱並不多,顯得非常整潔。用Gentleman的話說,他常年定居在CA國,這房子基本是空著,只是回來的時候住這,所以陳設簡單了些。

我們的話題,始終圍繞著房子,而並沒有說太多關於專案的事情。那天,我才瞭解到,Gentleman在做生意之前,也是工薪族,居住在一套30平左右的老房子中。後來公司逐步地發展壯大,他家的房子也隨之換了三次,地段一次比一次好,面積一次比一次大,而他現在在CA國的家,是一棟獨門獨院的木房子。

從Gentleman家出來的時候,我已懷揣著剛收到的專案款,心中雖說有幾分成功的喜悅,但同樣有幾分抹不去的惆悵。


正文:(十二)意譯的煩惱

在整套系統開發的過程中,我一直採用‘意譯’的模式,對Gentleman所提出的需求進行改進設計,但也有例外的情況。系統中有一個模組是給工廠下生產通知單,在這個模組的處理上,就出現了問題。

公司當前的做法是依據合同中的產品數量,給工廠下達生產。一份合同由多種貨物組成,每種貨物的訂購數量和外銷價是不同的。實際工作中都是將一種貨物中所有的訂購數量都制定一家工廠生產,當時,我從邏輯角度上分析,認為存在這種可能,即一種貨物分交給兩家以上的工廠生產。

所以我在設計中提出了改進模組的設計思路,並彙報給Gentleman,他當時的反應顯得有些猶豫。因為現在的實際工作中是不存在這樣的情況的,如果系統能實現到這種程度,肯定是更靈活,因此他就准許了我的設計思路。

這個模組的設計和實現過程中,由於要實現到同一種產品分配給多家工廠,並且訂購數量要動態分配和回收。所以需要考慮到情況就複雜了很多,時間自然也多花了N倍。最終實現出來的效果是非常不錯的,操作員可以清楚地看出每份合同下達的生產通知單,以及每種產品的生產數量。

但以上所認為到的程式最佳實現效果,都僅僅是我個人認為的狀態。當把這個模組拿到具體業務員那測試操作的時候,問題就顯現出來了。他們都反映麻煩,第一,從思路上和現狀有點差別,感覺彆扭;第二,在操作步驟上又多了一步操作,耽誤時間。最後,Gentleman在考慮再三後,讓我把這個改進模組功能去掉,依舊實現最原始的需求。

後來我總結此次教訓,雖然模組的功能更靈活、更強大,但客戶只需要他想要的,改進模組一定不能成為畫蛇添足。


正文:(十三)測試之痛1

程式編碼工作逐步接近尾聲,接踵而來的就是功能測試、模組測試、整合測試、系統測試等。對於系統測試,開發人員大都不願意去做的,因為這是一項既繁瑣、又無成就感的工作。

一套沒有經過嚴格測試的系統,就像一匹沒有繮繩的野馬,誰也不知道它發飆的時候,會跑到什麼地方去。再繁瑣的工作也要做,初步的功能測試和模組測試工作自然是由我自己來完成。可我發現個問題,我只要輸入一些資料到系統中,開始做測試工作,就會自然地進入到一種自我欣賞系統的狀態中,一圈資料測試下來,只能找到少量的程式錯誤。

Bug大體上可以分為兩類,第一類是程式錯誤,例如:由於資料邊際校驗不強而引起系統異常宕機,程式顯示不正確等;第二類是演算法錯誤,即程式中某些資料的計算方法不正確,或資料更新不完整。對於第一類錯誤,我還好測試些,畢竟出現問題後,一目瞭然。但對於第二種錯誤,我根本無法察覺,例如一套產品的最終價格是58,我很難直接判斷出這個價格是正確計算結果,還是有問題。但對於有豐富經驗的業務員來說,他們是很容易做到的,因為這些價格他們太熟悉了。

考慮到我在測試過程中很難發現第二類錯誤,所以就和Gentleman商量,看能否找人來協助我做這部分的測試工作。(當時我以為Gentleman的日子過得很瀟灑,身在國外,遙控公司,自己則周遊列國,好不自在。)而他也沒含糊,一口就答應下來,我真是喜出望外。

其實我的想法僅僅是,讓他找個心細的業務員來做系統的測試工作,但出乎意料的是,他居然親自上陣,自己一個人來做測試工作。


正文:(十四)測試之痛2

Gentleman是一個辦事認真仔細的人,他每次測試完一個模組後,都會詳細地記錄下錯誤的具體情況(效果、他估計的原因、在什麼資料輸入流程下出現錯誤等等),然後發一份錯誤報告給我。有時為了描述一個錯誤,需要要寫上百字,並配以螢幕截圖。我見過他在電腦上輸漢字,基本上是二指禪的功夫,輸入速度非常慢。所以我可以想象,他在做完測試後,敲上一篇上千字的錯誤報告需要多少時間。而且,後來我從Gentleman那也證實了自己的猜測,他花在寫Email的時間,遠多於測試時間。

雖然我多次建議Gentleman將測試工作交由下屬去做,但他一直都沒有同意。他說,系統的需求和設計過程,都是他全程參與的,換了誰都沒有他這麼清楚。其中有很多地方都是與原系統不相同的,如果換由其他人來做測試的話,是測試不出問題來的。他堅持測試到基本可用的狀態,再交由其他人來做後續測試。

我真的為他這種認真的工作態度所感動,所以他每次傳送新的錯誤報告後,我都會盡快把這個錯誤修改好。我們就這樣合作,他一有空就測試程式,然後把錯誤報告發給我,我將修改好的程式傳送給他,他最後再做一次錯誤修正後確認測試。為了我們的測試能基於相同資料,我們之間還經常交換資料庫,固定以某段資料為測試基礎。初略估計,這個測試階段他的工作量應該是我的2-3倍,因為大部分的Bug,都很容易修改,只有少量幾個需要調整較多的地方。

看著系統一天比一天強壯,這種感覺真的很美妙,就像練健美的人看著自己的肌肉越來越發達,喝酒的人感覺自己酒量越來越大一樣,都是很享受到事情。

同時,Gentleman也基本上切換到新系統下工作了,只是用老系統來查以前的資料。因為有了新系統的比較後,他已經無法忍受老系統的低效率了。


正文:(十五)測試之痛3

系統經過Gentleman和我的多次測試和修改後,健壯性得到了顯著的提高。在測試期間Gentleman想從CA國飛回來,專程為系統上線前做最後的實戰測試。我是不贊同的他這麼做的,當時正好趕上萬眾矚目的北京奧運會,他的簽證上也遇到了些麻煩,所以也就順利成章地取消了這一臨時計劃。

雖然Gentleman自己沒回來,但他專門安排了他的助理(本文中稱呼為MissLee)來協助我做上線前的最後測試工作。我和Gentleman協商後,制定的計劃是:測試資料庫放在MissLee的電腦上(以後再配備專用的資料庫伺服器),首先在營銷部的5臺電腦上安裝客戶端程式。即本套系統先由營銷部來做實戰測試,因為他們的業務中使用到的模組最多,資料所走到流程也最全。當系統測試沒有問題後,再全面推廣到公司的所有機器上,這個過程預計2-4周。

系統安裝到營銷部後的那些天,他們馬上就有很多資訊反饋。依據Gentleman的要求,營銷部所有的反饋意見都統一發到MissLee那兒,再轉交給Gentleman本人。Gentleman和MissLee會對這些資訊反饋進行分析,例如:哪些意見是非常正確的,系統的確需要在某處新增資料項、新增功能或資料匯出。然後他們會整理好,傳送Email給我。我越來越覺得Gentleman真是個Good Partner,他的事先安排,讓我的工作井然有序,而不是面對嗡嗡作響的各種嘈雜意見,這應該是很多人值得學習的地方。

當然,這期間系統也有很多'莫名其妙'的錯誤,例如,他們在匯出一份報表檔案的時候,進度條總是停在30%處就不動了。而我在自己的電腦上,和Gentleman的電腦上都測試不出這樣的問題(這些問題大多是因為,產品庫中缺少了某些產品的圖片啊,或金山詞霸的自動取詞功能引起系統中特效按鈕顯示不正確等等)。類似於這種情況的問題大概有五六次,我都是需要及時到現場測試,然後逐一排查原因,最終找到問題所在。

解決這些疑難雜症的話說起來很輕鬆,但在實際找尋錯誤的過程中,沒有交流,只有自己一個人琢磨。都是在結合程式原始碼的基礎上,仔細排查錯誤,這個過程既曲折更痛苦,需要相當的開發經驗。以至於後來Gentleman開玩笑,說我無所不能,在我這所有問題都不是問題。

經歷了半個多月的系統測試後,營銷部人員,也由最初的對系統很不放心,到享受系統帶來的高效工作。


討論篇3:專案之上的情感

在本文前面的若干節中,我已經多次提及Gentleman身上的特點,認真仔細,善待員工。原本我以為他平時的工作很輕鬆,可後來才知道,他每天工作都在十小時以上。國內與CA國有八個小時的時差,這邊白天上班的時候(他那就是17:00-01:00),他基本上都掛在IM上,隨時與公司這邊保持著聯絡,而且還要處理大量的客戶Email。

現在回想起測試階段,我把大量的測試工作都交由他來做,真是於心不忍。系統安裝到營銷部的時候,MissLee和其他同事也都說Gentleman非常辛苦,希望系統能給他減少負荷。我當時心中就在想一個問題,當今社會,有幾家公司的員工會這樣為老闆說話?大家為什麼會這樣向著老闆說話?如果Gentleman身上沒有特殊的品質,員工又是會怎麼樣?看到了這些,我就不難理解,為什麼一家30人不到的貿易公司,每年的貿易量卻能達到2000標箱以上。

今年一場金融危機幾乎席捲了全球,我由於炒股的原因,所以非常關注全球各股市的走勢。我能意識到這場危機對於出口型公司的衝擊會有多大,所以在9月18日的時候,冒昧地給Gentleman發了一封與專案無關的Email。全文如下:

“您好!

不知您最近是否關心全球經濟動向?現在能看到的情況已經非常糟糕。美國五大投資銀行已經倒閉和被他人收購了三個(貝爾斯登、雷曼、美林),另外兩個(高盛、摩根士丹利)也是關注的焦點,昨天高盛股價下滑23%,摩根士丹利股價大跌44%。

上週我和一個高中同學(他是耶魯博士畢業,就職於美國雷曼兄弟公司紐約總部)MSN上聊天,他說美國遇到1929年以來最大的金融危機。上週末雷曼即宣佈破產,美聯儲前主席格林斯潘在接受採訪時也說,美國遭遇百年不遇的金融危機,經濟回退很難避免。美股最近3天出現了2次4%以上的跌幅,這是美國911事件以來單日最大的跌幅。

我不清楚會對全球經濟產生多大的振動,現在全球的股市(美洲、歐洲、亞洲)都是一片暴跌。波羅的海航運指數也從高點12000點,跌到現在不到6000點,這些都說明全球經濟可能面臨萎縮。我的一個朋友,是青島一家4S店的總經理,他們最近2個月的汽車銷售量為0,搞得他壓力非常大。前天就是去他公司看套行業軟體去了,和他聊了一下上面這些話題。他前期忙於生意,都不太清楚原來全球經濟發生了這些事情,感覺他聽後心情很沉重。您公司是做外貿,應該對這更敏感些,我也不瞭解這些變化會對咱們這個行業產生多大的影響,提前做有些準備總是有益的,希望我的擔心是多餘的。”

下面冒昧地將Gentleman的回信公佈於此,希望他不會因此責怪我。

“謝謝你的關心!非常感謝,真的。我每天都在關注這些事情。一句話,冬天快要來了!

1929年美國發生了大蕭條,稱為GREAT DEPRESSION.最近2-3年內,極有可能會發生GREATER DEPRESSION.

格林斯潘說,美國遭遇百年不遇的金融危機,並沒有誇張--雖然這是他一系列政策埋下的種子。

對於我們生意的影響有多大,現在還很難說。一種可能是:覆巢之下,焉有完卵?另一種是,滄海橫流,方顯出英雄本色。

(這話說的有點大了,我並沒有把握。勉勵自己而已。)謝謝!”

這封Email之後,我能明顯感覺出我們的關係更親近了,已經超出專案範疇了。一個人的成功不可能是偶然的,Gentleman身上有很多值得我學習的地方,在後續的Email中我直言,專案的收入對於我來說是次要的,能跟著成功男士學習優秀的品質對我來說更為寶貴。


正文:(十六)資料同步1

系統從一開始設計的時候,就有資料同步的需求,即公司區域網的電腦都訪問中心伺服器的資料庫,而各檯筆記本都訪問本機上的分資料庫,兩者是完全同構的資料庫。

由於在接這個專案之前,我沒做過任何資料同步的專案。因此,一開始我還設想著自己寫程式來實現資料同步功能,即設定時間點,然後通過程式匯出每個資料庫某段時間內的資料(新建、修改、刪除),然後再將匯出的資料進行比較,最終求出資料合集。可稍微考慮點詳細的實現過程就覺得頭大,情況太複雜了。如果要實現到應用的程度,可能單寫資料同步程式所花費的精力,就遠遠超過了寫業務程式,所以,最終放棄了這種不現實的想法。

(在校時,我的一位同學接了個進銷存專案,可當時我們所掌握的技術主要集中在C++操作檔案上,即所有的資料都是儲存在二進位制檔案中。這老兄完成這個專案,楞是沒有用資料庫。所有的資料全用二進位制檔案來操作,讀寫刪查都是自己寫程式碼,沒有用一句SQL。用他的話說,簡直就是自己寫了個數據庫啊,累得快吐血,效果還很一般。)

同樣的道理,如果我自己去寫資料同步程式的話,我估計效果肯定和我那位同學當年一樣。所以斷然不能自己去寫資料同步,即便我真有這能力寫出來,那也不能這樣做。因為如果業務發生變化或系統擴充套件,需要對資料庫表進行調整(新增表或欄位),那我的資料同步程式還要自己去重新完善,我想那一定是個場災難。

資料對於任何公司來說,都是最寶貴的,所以我要選用成熟而安全的方式來實現資料同步。


正文:(十七)資料同步2

確定選用資料庫同步工具來實現資料同步後,我就開始Google資料庫同步工具,其中Sybase Mobilink進入了我的視線,它的主要功能介紹如下:

“MobiLink 同步允許在符合 ODBC 標準的統一資料庫和 Adaptive Server Anywhere 或 UltraLite 遠端資料庫之間進行復制。在本教程中使用的是 Adaptive Server Anywhere 遠端資料庫。統一資料庫能夠是使用 Sybase Adaptive Server Anywhere、Sybase Adaptive Server Enterprise、Oracle、Microsoft SQL Server 或 IBM DB2 生成的資料庫。

MobiLink 適用於將一個統一資料伺服器和大量遠端資料庫進行同步(通常包含多個移動資料庫)。遠端站點的管理和資源需要已降到了最低限度。此係統是基於偶連線的,並且遠端站點可隨時進行連線。在每次進行連線之後,資料庫是完全同步的。

MobiLink 的工作方式是:將遠端資料庫上的多個事務的結果合併成一個更改集,然後應用到統一資料庫中。因為同步始終在事務邊界進行的,所以保持了參照完整性。不保留在元件事務過程中所做的各個更改的順序:因為從不復制未提交的資料,所以保留了資料完整性。”

乍看到這些介紹的時候,我簡直是喜出望外,這些同步功能簡直就是為本專案需求所設計的啊。

我趕忙連夜下載了一套 Sql Anywhere 9 開發版(其中包含Mobilink同步工具),依據一些文件資料,我開始測試起資料同步功能來。先新建好一箇中心資料庫和兩個遠端資料庫,然後按照文件中提供的例子,啟動同步伺服器和同步客戶端。沒想到進行得異常順利,遠端資料庫和中心資料庫的資料很快就實現了同步,我有點找不到北了,心想原本以為麻煩的問題,原來就是層窗戶紙啊!

可高興勁還來得及過去,就發現一個問題,其他所有的同步都正常,就是刪除操作的同步出來點問題。遠端資料庫中的刪除可以正常同步到中心資料庫上,但遠端資料庫之間卻無法同步刪除操作。具體情況的描述如下:

中心伺服器取名CenterDB(Server),兩個遠端資料庫分別取名RemoteDB1(Client1)和RemoteDB2(Client2),當你在RemoteDB1(Client1)中刪除某條記錄後,Clinet1執行同步語句後,能同步到CenterDB(Server)上,即CenterDB中也刪除了這條記錄。接著在Client2上執行同步語句後,卻發現這條記錄依然存在於RemoteDB2(Client2)中。

這是我在MobiLink使用過程中遇到的第一個麻煩。


正文:(十八)資料同步3

為了刪除無法同步的問題,我到處Google解決方法,可網上幾乎沒有什麼討論MobiLink的文章,僅有的幾篇都是介紹性的文章,逐漸地我開始有點毛爪了。可Gentleman在得知這個問題後,確表現得非常大度,他對我說,如果實在解決不了刪除同步的問題,那系統在使用的過程中,就採取行政手段來同步。即需要資料刪除的時候,大家就記錄下來,然後互相發Email通知。

我很難想象在系統使用過程中,大家互相發Email通知刪除的時候,會順便暗自問候我這個程式開發者多少次。我沒得選擇,必須找出辦法來。在翻了很多資料和搜尋大量網頁後,終於在Sybase網站上一個英文的幫助檔案上,找到了這個問題的解決方法。

原來MobiLink在實現資料同步的過程中,中心資料庫的刪除就是無法同步到遠端資料庫上,而遠端資料庫的刪除可以同步到中心資料庫上。如果想實現這種刪除的資料同步,有兩種解決辦法。第一種方法是建立影子表,即對每個表都新建一個影子表,某條記錄刪除的時候,都在其對應的影子表中記錄下刪除行的主鍵;第二種方法是邏輯刪除,即在每個表中建一個刪除標識欄位。

考慮到實現的複雜度,我最終選用了邏輯刪除的方法。但緊接著另一個問題又來了,此時的程式編碼工作差不多完成了70%左右,現在把程式中所有的真實刪除都改成邏輯刪除,原始碼中需要修改很多的地方。如何以最快最全的方法實現邏輯刪除?我整整思索了半天,突然靈光一閃,想到了一個最佳方法。即從資料互動的父類中修改真實刪除所呼叫的函式,把真實刪除改的SQL語句改為邏輯刪除所對應的SQL語句。這樣只修改一處程式碼,即把系統中所有的真是刪除都搞定。

我暗自誇獎自己:你怎麼這麼聰明啊!


正文:(十九)資料同步4

在解決了MobiLink資料同步的中心資料庫與遠端資料庫的刪除同步問題後,我又開始測試資料同步的速度問題。發現區域網內和Internet網上MobiLink的資料同步速度差不多,這讓我很是高興,可接著另外一個問題又開始困擾我了。

開始做資料同步測試的時候,由於資料庫中的資料量很小,每次資料同步的時間大概在2-5分鐘。而隨著資料庫中的資料逐步增加,發現同步所需的時間越來越長。MobiLink資料上,都說資料同步的原理是依據日誌檔案中的資料庫操作語句,對資料進行增量同步,即第二次同步的資料是第一次同步後的資料修改。這就讓我很不理解了,為什麼隨著資料庫的增大,同步的速度越來越慢,而且從同步伺服器的滾屏顯示上,明顯是在掃描第一次同步以前的資料。

Google了N多的地方,都沒有發現有討論這個問題的地方,我又得自己摸黑前進了。憑藉以往的經驗初步推斷,有兩種可能原因,第一種是資料庫的日誌出來問題,第二種是資料庫的MobiLink同步設定出來問題。

首先從第一種可能性考慮,我把ASA資料庫的日誌刪除掉,重新構建日誌。希望全新的日誌能給我解決這個問題,可發現同步速度依然是老牛拉車。重構的新日誌不行,我又遍查方法,希望能有日誌整理的方法,把原先的日誌重新整理。光折騰日誌就花了我一個多星期,頭也大了兩圈,最終自認為是進來死衚衕。

然後又考慮Mobilink同步設定的問題,把《Mobilink同步使用者指南》《Mobilink同步參考手冊》都翻了個遍,還查幾乎所有能找到的資料,也都沒查出所以然來。光前面兩本書加起來就一千五百來頁,真是鬱悶得夠嗆。此時的Gentleman又給了我鼓勵,說現在也能將就著用,無非就是速度慢些而已。可我心中明白啊,系統正式上線後,資料庫會迅速加大,如果每次同步都是全掃描,那真是慢得跟頭驢一樣。

經過半個多月的查詢,就在我幾乎快絕望的時候,一次隨意翻查《MobiLink Developer Resource Kit》的時候,居然發現裡面有一篇“Mobilink資料分割槽”,詳細地記載瞭如何設定實現資料的增量同步。這真是踏遍鐵鞋無覓處,得來全不費功夫啊。我都感動得想喊出來,按照裡面的設定方法,對資料庫進行了相應的調整後,一測試,OK, No Problem。

那天,我感受到久違了的勝利喜悅,似乎一下子把我拉回到了讀書時代。


正文:(二十)最後一次大考1

經過多次的資料庫同步測試,我自認為已經大體上掌握了MobiLink的資料同步方法;同時,系統程式經過營銷部的實際測試也日趨完善。與Gentleman商量後,決定系統在秋季廣交會前全公司範圍內上線。

由於前面的系統測試工作做得非常充分,所以系統上線後並未遇到任何技術上的問題,僅是某些部門和個人提出了一些小的功能修改意見。至此係統算是基本上線成功,但還有最後一次大考,那就是秋季廣交會。

Gentleman和他的同事們,非常重視廣交會,他們會在此前做好最細緻的準備,其中包括參展的樣品、名片的準備、筆記本、業務系統、印表機的除錯等等。給我感覺就像上前線打仗一樣,這比喻一點都不誇張。Gentleman說他們在以往的廣交會上就是神經一直緊繃,來了客戶以後,需要迅速給客戶報出各種產品(或依據客戶的需求組合的產品)的價格。其中容不得半點差錯,價格報高了,會讓客戶失去興趣,價格報低了,則公司蒙受損失。所以廣交會期間,只要客戶一來詢價,大家就處於緊張狀態,需要反覆核算價格。

當然Gentleman這次去參加廣交會是準備好了兩套方案的,他們分別在新老兩套系統中都輸入好了參加廣交會的新貨號,如果新系統在廣交會期間出現問題,他們就馬上切換到老系統下使用。(這些是我事後從其他員工那兒得知的)

此次廣交會,Gentleman他們租用來兩個展廳,所以帶去的六臺筆記本組成2個區域網,分別在兩處使用。整個廣交會參展期間(大約10天時間),新系統不負眾望,執行高效穩定,報價準確迅速,極大地減輕了Gentleman他們的工作量和精神壓力。看著大家回來時對系統滿意的神情,我心中甚是開心,說明新系統完全達到了預期的目的。

可就在廣交會回來後的資料庫同步過程中,我又捱了一記‘悶棍’——其中一臺筆記本上的資料庫與中心伺服器資料庫的同步過程中,出現了只下載資料不上傳資料的奇怪現象。


正文:(二十一)最後一次大考2

由於全球金融危機的原因,今年的秋季廣交會市場比較清淡,珠江三角洲附近以出口為主的傢俱和玩具企業紛紛倒閉。但從Gentleman那瞭解到,今年他們公司的情況還算不錯,雖然比春季廣交會的成交量差一些,但已經比預期的狀況好多了。加之此次廣交會上,由於新系統非常好用,所以在現場感覺工作比較輕鬆,並未出現手忙腳亂的現象。在此次廣交會臨近結束的時候,他們還特意舉行了一場小型的慶功宴會。

大家從廣交會上回來後,紛紛說新系統非常好用。得知這些喜人的訊息,我自然也是非常高興,在他們回來的第二天,我就去Gentleman公司那,幫他們把筆記本上的資料同步到伺服器上。我原本預計最多一兩個小時就能搞定的事情,可沒想到居然整整耗了近十個小時(16:00 - 02:00 晚飯也沒吃)。

因為出現了一個奇怪的現象,即其中一臺筆記本與中心資料庫同步的時候,只能下載資料,卻無法上傳資料,這讓我一頭霧水。因為這檯筆記本上的同步語句和其他的都是一樣的,MobiLink中的確提供了單向同步的設定,可我並未加上這個引數啊。問題出在什麼地方呢?

我仔細梳理著每一步環節,回想起來這檯筆記本上的資料庫與其他資料庫不同在於,它的資料庫是從另外一臺筆記本上覆制過來的。因為在廣交會上,Gentleman是分兩個展區的,而這第二個展區的開展時間比第一個展區晚兩天,所以Gentleman當時在得到我的許可後,就把第一個展區用的資料庫複製到了這檯筆記本上。

而MobiLink資料同步的原理是,每個遠端資料庫都對應一個同步使用者的,即每檯筆記本都需要對應一個不同的同步使用者。最初我認為MobiLink的資料同步過程,只要我不設定單向同步,即肯定是即上傳又下載的。可那天經過我反覆測試,發現對於一個新的同步使用者,在初次與中心伺服器做同步的時候,資料是隻下載不上傳的。

一開始,我以為是設定出來問題,可反覆檢查設定,並未查出問題。我再仔細琢磨MobiLink為什麼這樣處理?雖然我並未在任何MobiLink資料中印證我的猜測,但我最終認為這是MobiLink特意這樣處理的。即對於一個全新同步使用者,初次同步過程中,MobiLink的執行方法是隻下載不上傳的。其實這也很好理解,因在一箇中心資料庫和多個遠端資料庫釋出的時候,只有預設這種方式才能最快完成同步,否則資料只有輪詢同步兩遍之後才能實現完全一致。在想明白了這一點後,我趕緊改變了方法,即採取手工SQL語句匯出的方法,將那臺無法上傳資料的筆記本中的資料匯出到檔案中,然後再將這些檔案資料匯入到中心伺服器內。

那晚,就這樣琢磨後測試,測試後又琢磨,一直折騰到凌晨2點才把資料全部匯入到中心伺服器中。因為我清楚,如果不把資料整理好,Gentleman的公司明天就無法正常工作,所以一定要在那晚把資料整理好。


正文:(二十二)煮酒論英雄

那天為了將筆記本資料匯入到中心伺服器,我工作到凌晨兩點,Gentleman為此深受感動。但我認為,一個值得我尊敬的合作伙伴,我就應該盡我全部的能量,將系統功能開發好,將資料同步完善好。

在這近一年的交往過程中,我深感Gentleman身上有太多值得學習的地方。所以每次Gentleman回國的時候,都是我抓緊學習的機會。為了有更好的交流時間,我迫不及待地在秋季廣交會之前,就邀請Gentleman單獨慶賀一翻。

Genteleman是個非常理性的人,在他的思想中,開發一套系統,無論投入多大精力和財力,只要系統能創造出更多的效益,那所有的投入都是非常值得的。而對於我來說,當前的新系統僅僅是第一步,只是簡單地提升了業務的執行效率,並未給公司帶來更多的利益。在我的頭腦中,正在思索下一步的工作重點,如何能從繁瑣的工作中解放出更多的人員?如何能讓Gentleman站在全域性的高度上,分析出公司的利潤髮展點和成本控制點?如何能有效地將營銷部、海運操作部、財務部等各職能部門更有效得協同工作?我相信,心有多大,舞臺就有多大。

借單獨與Gentleman慶功的機會,我將自己成熟的與不成熟的想法都丟擲來了。我們邊飲酒邊暢談,對於新系統的下一步建設做了總體的規劃,從這個規劃中可見在Gentleman的心中,有更巨集偉的藍圖,他希望建設的不僅僅是一個單純的貿易公司,而是一個既有活力又有深度的集團性公司。