2006/09/10

應該有的心結

最近,客戶希望我幫忙整理一下系統文件,並且也為系統維護人員做一下教育訓練;他希望,如果發生一些問題,可以做一些簡單、初步的處理。其實,這件事他跟我提過好幾次,我同意他的看法,我也認為這是我應該做的事 (而且,如果做的好,還可以減少我的負擔);然而,實際的工作執行進展,卻與理想差距甚遠。為什麼呢?

理論上,一個系統開發完成後,應該就會有系統文件的產出。所以,所謂的"整理一下系統文件"應該也只不過是把原來的文件做一下整理修改就好;很可惜,不是這樣的,我所產出的系統文件,大概只述說了系統 10% 的事實,而一份只有 10% 的文件,在經過一段時間之後,對我而言,其實用性可能接近於零。要了解為什麼會有這樣的結果,必須了解我的工作流程;不過,在解釋我的工作流程之前,我可以先預測客戶要我"整理一下系統文件"這個工作的最後結果:再做一份涵蓋度只有 10%的系統文件....

OK,下面開始用圖形的方式介紹我的工作流程。這裏不特別對圖形符號多做說明,因為,我好懶。反正,第一張圖是當接到一個工作時,決定執行策略的流程。我們幾乎都是走"分散"的路線,除非這個工作真的被細分到非常的小(1、2個小時)...

接下的第一張圖,就是工作的基礎流程。在這張圖裏面會有一些 "進入:[XX]模式" 的方塊,代表會進入 [XX] 子流程。其中真實的工作模式有四種,也只有經過這四種模式,才會達到工作完成的結果。這四種模式為:[隨便]>顧名思義,就是,隨便了啦...;[決鬥]>就是時間很趕,所以,也有一點隨便了啦...;[真的做]>這種情形,幾乎只發生在程式撰寫的時候(不包括debug)...;[實作練習]>這是我這幾年最常使用的模式。[隨便]、[決鬥]、[真的做]這三種都很容易明白,所以我只對 [實作練習]模式做另外的說明。
點選看大圖

接下來,我們來看一下[實作練習]模式。實作練習其是就是因為我們對某項技術的掌握度不足,卻又沒有足夠的練習空間與時間,所以只好用實際的工作來練習。這種運作情形,通常都沒有什麼好結果;比方說以我的情形來看,我的路線通常會變成:沒有把握->很煩->時程逼近->找人討論更煩->隨便啦...

為什麼"找人討論"會更煩呢,那就要看一下接下來的兩張圖。第一張是"準備找人":

第二張是"討論中":

有沒發現,我好像常常會進入[煩燥]模式。下面這一張[煩燥]模式的圖;也就是因為經常進入[煩燥]狀態,所以,其實我有一大半的時間都在"發發呆,做雜事"的情形下渡過。

最後,來看一下讓人更加無奈的流程,[下次再說]。這個流程本來就充滿不得已,而且,記住,因為之前的工作被打斷了,所以,就算想起來要從哪裏繼續下去,也都免不了的必須讓腦袋瓜從頭開始。差別只再於,上一次的工作,是否有讓自己了解工作要怎麼做 (有果有的話,可以快樂的進入[真的做])。

好了,回到最上面的問題,今天客戶要我整理系統文件,並且對系統維護人員做教育訓練...如果是要寫使用手冊,並且對使用人員做教育練訓,我大概還有 6成的把握。可是,系統文件到底該怎麼寫,系統維護人員到底該怎麼教,我怎麼可能知道 (有誰知道的,可不可以分享一下呀!?)。好吧,我想我已經進入[煩燥]模式了。我猜,最後大概還是會不得已的進入[決鬥]模式,隨便交差了事...

PS:我在第一張"工作基礎流程圖"的說明,有這麼一段話:「在這張圖裏面會有一些 "進入:[XX]模式" 的方塊,代表會進入 [XX] 子流程」。大家不會想,既然是"子流程",為什麼不叫"[XX]子流程"就好,偏要叫"[XX]模式"。這是因為,我一開始畫圖的時候,還不清楚我該怎麼畫才好,等到我畫到一個程度,我才發現到原來我的圖的結構會有這樣的階層性,可是,我已經懶得回去改字了。其實,我有一大堆的文件都有這種情形,甚至,我所開發的系統也有這種情形 (原本應該只是雛形,卻愈加愈大,最後還被趕鴉子上架)。這些東西,都會自然的、必然的被我丟到思想的垃圾筒...

2006/09/07

颱瘋天

颱瘋天,被叫來加班
原因是塌非斯系統的產品發不出去 (塌非斯系統 Product 程式會當掉)。查了半天,終於找到了原因,以下說明之:
塌非斯系統有關產品的部分,我們有設計各相關產品的Template
在Template裏有各式 Tag,例:中心位置在北緯[lat00]度
上述由中括號 '[' ']' 包圍的就是資訊 Tag
程式找到資訊 Tag,然後會代換成正確的資料
例:中心位置在北緯[lat00]度 --> 中心位置在北緯21.5度

然而,當天發生了如下的情形:
1: while (String.Pos("[") > 0)
2: {
3:  tagstart = String.Pos("[");
4:  tagend = String.Pos("]");
5:  String = String.Delete
    (tagstart,tagend-tagstart+1); //將Tag的字串刪除
6:  String = String.Insert
    (value,tagstart); //將刪除的字串處插入實際值
7: }

上述是一個 while loop 的程式,在找出 '[' & ']',並將中間的Tag代換。
下面說明一下,出問題的 Template 與實際資料

Template裏的某一行:
[its] [tyname_ch] [tyname]

上面那一行代換成這次這個颱瘋的實際資料時,應該會是:
三十午度颱瘋 阿珠 ANNCHU

然而,程式在跑的時候,卻是以下的情形
進入loop前:
 String="[its] [tyname_ch] [tyname]"
第一次的Loop跑完:
 tagstart=1
 tagend=5
 String="三十五度颱瘋 [tyname_ch] [tyname]"
第二次
 tagstart=10
 tagend=19
 String="三十五度颱瘋 阿珠 [tyname]"
第三次
 tagstart=15
 tagend=12
 String="三十五度颱瘋 阿珠 [tyname]"

第三次跑完時,String 的值沒改變
而且 tagstart > tagend !!!??

接下來,程式就進入無窮迴圈了
(我們的 code review,目的之一就是要避免可能的無窮迴圈)

接下來的問題是,為什麼會進入無窮迴圈!?
原來,"珠"這個字的前半碼,這個BYTE的編碼與 '[' 相同
所以程式第四行處理 "三十五度颱瘋 阿珠 [tyname]" 時
 tagend = String.Pos("]") = 12

........................

後來,加班,連夜趕工
把Template裏的Tag通通改成 '[{' '}]'
這樣子的雙位元處理,就不會有這種問題了...

這個事件給我們三個重要經驗

1.中文字的處理
中文字的編碼問題本來就是相當複雜的問題
像之前有同事的做法,將 BCB 的 AnsiString 轉成 WideString
(雙位元字串) 然後再來處理...事實上,也許我們可以考慮
統一使用 UTF-8 來處理字串問題 (包括資料庫的儲存)
大家思考看看吧!!

2.Code Review
這個就是另外提議的項目,可以把文字處理,當做 Code review
的一個項目。

3.客戶服務
這次的這個問題,真的是一開始設計時未思考到的問題。雖然
大多數的時候,客戶有提出的問題,可能都不是問題;或是說
大多數的時候,客戶其實也說不清楚問題是什麼。所以,這時候
乖乖來加班吧...