2012年6月23日 星期六

現實中,我的創業,問題,解答,手札。

Standard
最近看到一些網友轉貼的文章,還有聽聞了一些朋友的創業故事,加上自己也是在創業,因此有感而發。其實,過去就一直想寫下『在我眼中的創業』,一方面重新整理自己在創業生涯中的思緒,另一方面鼓勵自己不能倒下。此外,如果可以,讓更多人知道創業的現實面,也不是什麼壞事。這邊要先感謝許多同是創業人的朋友,無論他們現在是否還在這條路上,都給予我很多幫助和啟發,更感激許多親身跳下去『證明』的人,讓我知曉許多悲慘的事實。

依然強調,我尚未成功,也還年輕,我說的話可能影響不了什麼人,也沒什麼說服力,只是單純地將我所見的一切,如實的描述出來。如果你對我所說的一切不以為然,如果你仍然覺得你自己原本想法是對的,請堅持自己所想,無論最後是成功還是失敗,開心或痛苦的,你都能因此得到實質的經驗和正面的回報。

因為我還沒成功,所以我不會告訴你怎麼成功,更不會告訴你創業一定要做到的成功守則有哪些,這些事我都沒有答案。如果你有這樣的困擾,你應該去問的是那些研究創業的部落客專家,或是書報周刊。在這我只會告訴你,我在創業中遭遇到或看到的問題。

首先,恭喜自己。經歷過兩年的努力,好不容易還活著,這是我是創業至今最值得開心的事。相信我,這是真的,在經歷過痛苦磨難、倒閉危機和理想於現實搏鬥後,你會非常慶幸,自己還撐的下去。這一切不像是某些知名的『談創業』部落格文章中,所輕描淡寫的這麼簡單,也不像書店架上滿滿的『各類成功學』所提到的這麼有跡可循,因為你永遠可能被任何一個創業的細節所打倒,一切是這麼出乎意料,現實中的『啊!你已經死了!』天天都可能上演。所以,如果你克服了這些細節,不管落地動作好看與否,你都應該先為自己鼓掌。

問一下自己,什麼才叫做『成功』?

既然提創業,就得提大家都想要成功這件事。包括我自己,很多人不曉得創業最中最大的問題,就是『不知道什麼才是成功』。對許多創業人來說,看到 Facebook 有今天的地位會感覺到相當興奮,為自己『創業的理想』注入了一劑莫大的強心針。是的,因為你認為他是成功的,所以你感覺到了『我也有機會成功!』,夢想實現也近在眼前。

但是,我們應該先問一下自己,什麼才叫做『成功』?

是上市上櫃?手上握有幾百億美元資產?還是不缺錢用?握有極大的權力?又或者是走到世界各地,都能有人認出你來?如果你回答不出來這個問題,那請試著去想個更簡單的問題,你認為 Facebook 算成功嗎?你覺得他從什麼時候開始算是成功?

我相信有各種不同的回答,創業模式也有百百種,絕對沒有肯定的答案。不過,如果你才剛開始創業,就想模仿 Facebook,開始思索自己如何佔五成以上股份,開始幻想著剩下的四成如何分給其他人,甚至說的好像你就是現在的 Facebook 一般。那麼,你心中所認為的成功,應該是止於『拿到一大筆投資人的錢』。

有太多太多人,看到了許多新創公司的成功故事,開始誤以為拿到一筆大錢,就是成功了,然後未來都將很順利。所以一堆人為了自己的 Idea 做了很多表面功夫,也練就了世界上僅次於 Steve Jobs 的說故事功力,更畫了多到了世界末日也吃不完的大餅。其目的不外乎就是想得到創投的親睞,期望這些『金主』們倒一些錢到自己的頭上。

先不論這樣的討好的手段是對是錯,也不論你花了多少時間研究,並在過程中花了多少精力投入在『真正的核心價值』上。因為更多人沒想到的是,當幸運的拿到錢後,才是災難的開始。

很多人心中對『創業』,都有一個美好幻想,至於敢不敢說出來或承不承認,那就是另一件事了:『公司開了,然後資金充足了,公司就能夠自己賺錢,然後自己生蛋,我可以安心掛著上流社會的 CEO(CXO) 王子名號,當個人生勝利組』

沒錯,很多人拿到資金後,覺得成功了,便開始揮霍,租大辦公室、搞氣派,左邊有機會去左邊,右邊有機會去右邊,兩邊都有機會兩邊都去搞搞,已經忘記了自己的初衷。直到有一天,錢燒光了,收攤時才懊悔。

比較誇張的,就會說到多個創始人為了分錢,爭個沒完,然後拆夥。

而有些人,拿到投資人的錢後才發現,想一個怪點子容易,但經營這個點子才是最困難的。談到點子要怎麼生雞蛋,畫畫大餅很容易,但實際做下去,卻一步也走不動,有時是業務面走不動,有時是技術面跟不上。熬呀熬呀,等到錢燒光的時候還走不出自己的路時,一樣打包收攤。

這邊還沒提到,當路快走到盡頭時,狗急跳牆花招百出的盛況,會有多麼精彩。(這留著以後出外傳 :-P)

講到這裡,我想你會開始檢討,自己究竟花了多少時間在核心價值上?還是你只是求一筆注定要燒光的錢?

你應該也發現了,那些知名創業部落格根本不會告訴你這些事,那些創業和成功學的書籍,永遠也只是講他們自己成功的那一面。至於細節呢?等你照著做後,倒了才會知道自己哪做錯了。

所以,你看過多少這方面的書?多少網路上的相關文章?你以看過這些書為傲嗎?或覺得自己能因此掌握創業嗎?從許多人身上你可以發現,戰戰兢兢創業或努力一個洞挖到底的人,反而在這條路上失誤比較少,比較有成功的機會。我當然不是說讀書不好,可是如果讀了這些『聖經』,反而讓你『大意失金舟』,那你還不如不要讀了。

還不如先想想,自己想要的成功是什麼?


沒有成功的經驗?所以盡可能勤能補拙

知道自己要的成功是什麼後,大多數創業人缺少的是『成功的經驗』,我也不例外。若有成功經驗,你會更能判斷情勢,做出正確決定,也可以避免不必要的開銷。但事實是,我們並沒有這樣的成功經驗。那麼,磨練自己的決策,修正自己的想法便時時刻刻不會少。

所以,如果有著遠大的理想,而且有奮戰到底的心理準備,那你絕對不能放棄的是『不停強化核心價值』。核心價值一詞相當籠統,實際上就是『做盡一切打算』、『堅守領先位置』,想著有什麼機會、怎麼賺錢、怎麼發展、怎麼佈局、怎麼樣讓別人趕不上我們,並且實地並拼命去做。

是的,你發現我在講冠冕堂皇的廢話了,小學生都會講的廢話。可是就是這樣的簡單的事,一個財迷心竅的創業人往往做不到。

聰明人很多,每個人都有自己獨到的點子。然而,有些人以為自己的點子很獨特,認為自己只要做出來一定可以成功,根本無需多餘的努力。可是就因為實際上沒有成功經驗,所以這些人原始的想法往往經不起考驗;如果又不多做努力,在創業戰場上這樣死的人,可以說滿地都是。這就是為什麼要『強化核心價值』的原因,有做過努力,你的想法會進化,才會更經得住考驗。有努力或許不會成功,但至少可以降低失敗的機會。

當然,這邊就不多重提前面所說,有人做盡一切是為了吸引投資客目光,強化的不是核心價值,而是『投資客討好工作』。雖然勤勞的方向可能不太正當,但就勤能補拙的角度來看,也總是比人多一些機會。


創業好像彩券?

周遭有個朋友的故事,在某次私底下閒聊時,也一五一時招了他自己的血淚史。

他和幾個朋友自學生時代就會做做網站程式,後來也會寫寫目前當紅的手機 App,並自認有許多新奇的點子。然後覺得『只要做出來』就能找到『金主』給錢,只要能找到錢,接著就能變成 Angry Bird,然後可以賣周邊商品 。

的確,他很幸運,點子還不錯,App 寫出來了,也找到投資人給了錢,但最後他當然卻沒變成 Angry Bird,而是錢燒光打烊,更別說有出什麼周邊商品。過程中,他只是不斷的拿著使用者數或是下載量,去找新的投資人,沒有花太多功夫對自己本來的想法不斷檢討改進。換言之,他也是糊理糊塗拿到第一桶金後,失去核心價值,不了了之的一個實例。

他到了後期才弄懂了一件事,自己把創業當做樂透彩券了,當初以為夢到了『明牌』,找到了店家然後買了張彩券,就可以等著發財。

事後諸葛來看 Angry Bird 的成功,並不是找一堆錢把自己充飽,更不是隨便丟個 App 放在那等三個月半年,就有大幅度成長的死忠玩家。也不是急著自己跑去做周邊商品賣商標賺錢,而是先做出絕佳的產品、經營市場,並在適當時機出擊,或交給可以發揮更大效益的人來操刀。而最重要的是,這些事,前面做不好,後面也不用做了。

你會看到,這一切其實都不是彩券,也沒有明牌,而是一步步踏出來的路。沒有人一開始就完全料到是這樣發展,都是自己慢慢開出的機會,然後時機一來就是你的。再好的想法,也要有相應的經營方法,更要不斷往前改進和擴展,就算給你搖錢樹,你也要花力氣搖它才會掉錢。

所以,大家都聽過這麼多故事,當過無數次『諸葛』,應該都能發現,『痛苦的細節』才是不能說的秘密。不要再把自己的真心話藏起來了,想要當成大業,不是靠個一桶兩桶錢買個希望,而是你要對自己的點子負責到底。如果缺乏成功經驗,碰碰撞撞免不了,就怕你忽略了這些不起眼的碰碰撞撞,不願面對真相。那麼,這些你不願意面對的現實問題,就是擊垮整個事業的最大殺手。

好不容易熬到有人投資,如果你以為就此解脫了,那你就真的解脫了。


信用破產?

然後提到信用,以為投資人給你的錢是讓你隨便燒的嗎?拿到錢的人有時要自己想想,你是拿自己的信用去換錢,還是投資人真的覺得,你的東西有發展性而願意投錢?

很多創業的是年輕人,想出來的點子或許真有點價值,但很多投資人更看重的是你『年輕』,而給你機會。這時,不要以為錢可以白燒,因為你就是以信用去換錢了,燒的太難看比燒光還慘。如果是做正確的事,錢花光了,你可以抬頭挺胸,如果你不正經的燒光了,那信用就有很大的汙點。

此外,也有一些人,是因為能力太強或經驗豐富,所以投資人都信任他,只要他提得出點子,就給他錢去做。但這相對的,也是以信用去換取投資,也更需要僅慎。無論如何,不管你是不是以信用去換取投資,投資人給你的錢,是用來賺更多錢的,而不是進自己口袋的,不要覺得別人給你錢,你就發財了。

你以為在投資人手上沒有黑名單嗎?有錢的投資人在業界或非業界內,人脈會不廣嗎?小心為妙吧。


什麼叫好的 Idea?

有創意、沒人做過、有錢景、有發展性...。你可以想到無數種名詞來形容好的 Idea。每個創業人手上,都會有自己的 Idea,當然,都是各自認為最好的。但有多少想法可行?多少想法能讓投資人接受,或是讓客戶買單?此外,如何避免他人來競爭?避免有財力的大財團和公司抄襲?

在這裡,我無法評斷你的 Idea 是好是壞,所以我也無法告訴你怎樣的 Idea 是好。但既然是創業、成立公司,一個好的 Idea 一定要能夠為你帶來收入或效益(無論長期或短期,金錢還是任何種回饋),畢竟,『公司是以營利為目的』。

我想,既然有利可圖的東西,有財力的大公司一定會想辦法進場,因為,如果唯利是圖的大公司都不想進場,這 Idea 肯定也賺不到什麼錢。那麼,如果大公司和大財團肯定會來參一腳,我們要怎麼辦?

有人說,他想 Idea 時會去避免大公司競爭。但我覺得,不是要避免去和大公司競爭,而是以 Operation Cost 的角度,來看待『為什麼大公司無法跟你競爭?』,然後找從中找出著力點。

還記得,我有個朋友,用了一個小孩和大人的例子解釋了這件事(內容我有稍做修改,改的更為偏激了一點 :-P):
假設現在有一個賺錢的機會,抄一本書可以賺 1 萬元。然後抄滿 100 本,每本多給 1 萬元。此外,因為這本書比較艱澀,月薪 5 萬元的大人抄一本書的時間比較快,需要 10 個工作天(假設一個月有 30 個工作天),13 歲小孩則需要 15 個工作天。

請問,你覺得是一個月薪 5 萬元的大人,比較適合執行這任務,達成 100 本的目標,還是一個 13 歲小孩比較適合來執行這任務?(先不考慮合不合法問題)

是的,上班族抄起書來動作比較快,佔了很大的優勢,小孩抄兩本的時間,上班族可以抄三本。理論上,上班族應該更適合來執行這任務,也能更快達成目標。

但是,從成本面來看:

若抄滿 100 本書,總收入可達 2,000,000 元。

假設大人不上班,全心全意抄書,他的成本是: (10x100) x (50000 / 30) = 1,666,666 元

假設 13 歲小孩不上學,全心全意抄書,成本是 0。(小孩根本不用自己煩惱開銷問題)

如果讓一個大人來做這件事,他只比原本收入多 333,334 元。

而對小孩而言,他則多出 2,000,000 元的收入,如果書抄不完,也還有很多收益。

這邊還沒提到期間,大人的開銷,可能需要以借貸解決,其所導致的等額外利息成本,還有可能餓死的風險成本。另外,如果沒抄到 100 本書,大人的收益根本不到 1,000,000,反而賠錢。

從這樣一個簡單的例子來看,若將其中『小孩』換成『新創公司』,『大人』代換成『大公司』,你就會發現,因為 Operation Cost 太高,導致很多事情大公司不可能投入,哪怕這個新事業的收益可以超過他原本的總收益,他們也只能看的到吃不到。

所以,如果大公司真的要進入這市場,最終手段都是以買下、併購或第三方合作的方式,甚至是投資和你一樣的新創公司。當你是先驅,又領先其他人許多時,大公司們的第一順位會選擇找誰呢?

也或許,你可能真的找到了一個沒人來搶的市場,但如果久久真的沒人來搶,請多思考一下問題在哪,因為,那可能不是藍海,而只是一灘雨後的積水。我想,真正的藍海,應該是大家都會想要來的,只是能不能來是另外一回事了。


後記

創業是件很痛快的事,無論其他人支不支持你,無論投資人能不能看到你身上的光環,能在劣勢的情況下,殺下一成時,快哉!

2012年6月18日 星期一

實作 X11 底下的 Popup Menu

Standard
既然要投入 JavaScript 的發展,一個很重要的目標就是讓 JavaScript 能被用來開發 Native 桌面程式。而為了達成這樣的願景,我們的團隊沒日沒夜的發展各類基礎技術和擴充底階 API,甚至是將以 JavaScript 開發整個桌面環境(Desktop Environment, 如:GNOME、KDE、LXDE 或 XFCE 這類專案)為終極目標。

當然,跳出瀏覽器之後的 JavaScript,缺少了繪圖引擎,所以要拿來做圖型化使用者介面,會更為困難。慶幸的是,前些日子發展出的 jsdx-toolkit 已經解決了大多數的問題,除了有 3D、動畫等支援,也已經有了許多現代桌面有的UI元件(如:Entry、Label、Button... 等),以致我們完全可以放心的開發屬於自己的圖型化應用程式。

不過,目前的情況,在手機、平板或是特定用途的嵌入式系統中完全夠用,一旦回到更為複雜的桌面環境下,就會遭遇到許多的問題。像是回到 XWindow 底下後,會遇到許多 X11 的視窗管理機制,其視窗之間錯縱複雜的交互關係,就是我們要處理的。尤其是當我們在開發桌面環境時,就會發現在一般的桌面環境下,使用者可能會同時開無數個視窗和程式,並且隨機又大量的切換使用,這迫使我們必須去修改 jsdx-toolkit 以處理 X11 底下的更多狀況,符合並更完整支援一般桌面環境下的操作習慣。

你可能用過 GTK+/Qt 這類常見的 Toolkit,也知道在 X11 之下有很多種類型的視窗(Window),像是 Dialog、Splash、Menu、Popup Menu 等等,但你可能不知道這些現代 Toolkit 內部做了多少事。事實上,X11 本身雖定義了各類視窗的類型,但實際上 XWindow 和 Window Manager 並不會完全去照定義去處理你的視窗行為,更準確的說法是,X11 HWMH 中的基本定義和我們實際的認知是有出入的,該定義只是說希望達成的行為,但沒說是由誰(XWindow、Window Manage 還是 GUI Toolkit)去處理。

舉例來說,我們現在寫一支程式,該程式不使用任何現代的 GUI Toolkit,然後單純使用 X11 API 把一個 Window 的類型設成 Popup Menu。但是你會發現,它的實際行為並不像我們所想的,失去焦點(Focus)後就會消失,無論你是點擊其他視窗讓他失去焦點,還是採用快速鍵讓他失去焦點。此外,他也仍然會保留 Title bar 裝飾(Decorator),還有會在你的 Panel Taskbar 上出現一個新的 Task。就是這些種種視窗行為,和我們心中所認知的 Popup Menu 有很大的差異。

仔細研究 X11 EWMH Spec 就會發現,對於一個 Popup Menu 的視窗,除了設定類型外,你應該要做更多屬性設定,才會讓它合乎我們預想的行為,而這些東西被分散於 Spec 文件內的各處描述,想要一次性找出來困難重重。此外,失去焦點後要關閉 Popup Menu 視窗的功能,就不僅僅是設定屬性這麼簡單,而是要使用 XGrabPointer 攔截整個畫面的輸入事件(Input event),採用特殊的做法,才能達成。

說了這麼多,既然我們是自己開發一套新的 Toolkit,當然就要來實作一個合乎我們預期行為的 Popup Menu Window,首先在建立視窗並設定為 Popup Menu 類型後,需要做一些設定並欄截事件:
...

    /* Grab pointer */
    int i;
    Window grabWin = -1;
    XGetInputFocus(disp, &grabWin, &i);
    XGrabPointer(disp, grabWin, TRUE,
        ButtonPressMask | ButtonReleaseMask,
        GrabModeAsync, GrabModeAsync,
        None, None, CurrentTime);


    /* Skip Taskbar */
    Atom wm_state = XInternAtom(disp, "WM_STATE", False);
    Atom atom = XInternAtom(disp, "_NET_WM_STATE_SKIP_TASKBAR", False);

    XChangeProperty(disp, win, wm_state,
        XA_ATOM, 32, PropModeAppend,
        (unsigned char *)&atom, 1);


    /* Override redirect */
    XSetWindowAttributes attr;

    attr.override_redirect = True;
    XChangeWindowAttributes(disp, win, CWOverrideRedirect, &attr);


...

接著在監聽 X Event 迴圈處,去檢查是否為 grabWin 傳來的 ButtonRelease Event(意即使用者用點擊了 Popup Menu Window 之外的區域),如果是就停止 Event 的欄截並關閉視窗。
...
    if (xev->type == ButtonRelease && grabWin == xev->xbutton.window) {
        XUngrabPointer(disp, CurrentTime);
        grabWin = -1;

        XUnmapWindow(disp, win);

        continue;
    }
...

後記

經過許多努力,完善各項功能,完全用 JavaScript 打造的桌面環境,指日可待。:-P

2012年6月17日 星期日

【心得分享】軟體人甘苦談

Standard
很抱歉,因為台北大雨來襲,導致班機延誤,讓小弟無法及時從香港趕回台灣參加 FreedomHEC 2012。相當對不起主辦單位,就這樣讓當天議程開了天窗。但是,之後我有空時,仍會整理資料,依舊會公開原先預定要給予的簡報。

不幸的是,活動第二天被客戶抓住,所以也沒辦法到場聽講。不過,雖然沒參加到 FreedomHEC 2012,為了賠罪,第三天當了司機(Be a driver, not writing driver :-S),開著車載著外國講者們一路到了宜蘭大學,給予學生機會直接面對面與 Kernel 開發者交流。

除了面對面問答解惑,其中當然也有保留一點時間,讓講者們可以自我介紹,也分享一些經驗。我也給予了一份簡短的心得分享,由於對象是學生,時間也有限,所以就不直接討論艱澀的技術,而是以輕鬆的角度切入,分享一下創業的經驗和業界的感想,還有描述就算在面對不利軟體業的環境之下,身為一個軟體人所需要的熱情和自我要求。


衷心期盼我們能培養軟體開發的熱忱,然後才有機會做出軟體的價值。:-)

2012年6月4日 星期一

如何當一個優秀的救火員之打蛇打七寸

Standard
經歷過許多救火任務(這邊當然是指軟體系統專案的問題),從 Kernel、Driver、Porting 到各類系統應用程式、Web 應用程式,幾乎無所不救,有社群內的朋友嘲笑著說:『在國內大概沒有團隊,像我們一樣什麼火都救。』。有許多的感觸是肯定的,從問題發生的那一面看去,加以急迫時間的摧化之下,感受到許多程式開發者最真實的思維和邏輯,當然,還有發案老闆的著急,以及清楚看到許多關係人暗地裡的算盤。我不敢說自己是優秀的救火員,但至少一旦承諾並接下案子,有再大的困難和阻礙也總是使命必達,哪怕連續數個月每天平均只睡兩小時,三四天只睡一次,也不會倒下。我想,最少我可以談談如何救火,還有從火堆中看到的許多『人』的問題。

其實,救火沒什麼訣竅,撲滅它是其次,主要是確保不會再燃起。俗話說『打蛇打七寸』,解問題時也要解到夠力才行。但是,或許你常聽有人說:『產品要出貨,能動最優先,好不好其次。』,似乎恰恰與我所提到的相反。沒錯,因為要確保火不會再燃起,理論上是要找出問題根源,從根源著手和解決,很多人乍聽之下,都會覺得是費工又花時間的工作。但是,每次的經驗都告訴我,實際上,找出問題根源,並解決他,往往比修補來得快很多,而且一勞永逸。尤其是碰到死線(deadline)將至,卻一直解不掉的一大坨 Bugs(指同類相關或互相影響的問題),從根本上並深入解決問題才是最快的辦法。

這邊有個簡單的案例:
有一個應用程式,與 Library、System API 和 Driver 都有相關,他們相依關係是:

應用程式 -> Library -> System API -> Driver

假設現在有個問題,這支應用程式出現了一個 Bug,而這個問題最終被發現是 Driver 缺少一些功能,而造成功能不正常。那我們應該從哪裡去解決?

一般人的做法,若是為了因應『產品要出貨,能動最優先』,所採取的方法當然是拿掉應用程式上的某些受影響的功能,或是改寫應用程式以另循途徑的方法達成同功能。但是,若你選擇這樣的做法,最可怕問題是,如果應用程式太過複雜,修改起來會有更多的副作用(Side effect),你要花更多時間去處理更多原先不存在的問題。

況且,這都還沒講到,我們根本都還不知道 Driver 造成的影響範圍有多大,有哪些 System API 、Library API 和依賴他們的應用程式受影響。而今天這個應用程式僅僅只是剛好被發現到有問題而已,一切都還只是開端,之後會發現其他地方也開始到處起火了。或許這邊講的有點危言聳聽,但都是實際上常遭遇的狀況。

不過,這種方法也不是完全不對,如果你很肯定,問題只會出現在一個地方,而且該功能可以被容許直接拿掉,這是最佳的救火方案。

可是往往情況沒有這麼簡單,你必需保留該功能或是更多功能,不但如此,你也必需修好它。所以,在這種情況下,通常我自己會使用前後夾擠式的做法,去尋求解決方案。由上而下(從應用程式往Driver 方向)的部份,主要還是與之前一樣,尋找只出現在一個地方的問題點,我們可以直接移除以滅火。而從下而上,就是盡可能直接把根源問題點解決。因此,首先當然是盡可能下手修好 Driver 的問題,不過,如果有不能修改的理由,就依序往上找到可修改的問題點。

要知道,修復一個 API 可以修好數十數百個使用它的應用程式,但你如果是從應用程式著手,那你就要重覆一一修改不同的應用程式,更別說還要花上每次測試找問題的時間,其數量是以指數級數來算的。所以除了直接刪除功能的做法,最好的處理位置依序為『Driver > System API > Library > 應用程式』。

曾經有碰過一場火,客戶軟體所在的平台本身不穩定,但他們不旦不釐清平台的問題,反而一直著手修改應用程式去避開平台本身的問題,最終不但把自己原本的程式改得亂七八糟難以維護,更是讓修改後的程式打了結,得到許多無解的副作用。更可悲的是,下次換了一個平台,這次做的所有修改,都是白做要重新來過。


後記

你或許覺得本文提供的方法,並沒有什麼大不了的,那是因為已經公布了問題點所在。事實上,實際情況可能更為糟糕,你可能根本不知道是哪一層發生問題。而如何在尋求解決方案的過程中,找出問題可能的發生源,又會是另一個故事了。:-)