善用科技與中心化來創新工作流程 — 有些工作本身的特性是適合分散式、多點地來做。然而,有時因為工具不普及、法規等限制,反而變成了中心化最有效率。一旦限制消失時,就會產生去中心化。比方說,一旦有了 youtube 與剪接影片軟體、後製影片軟體之類的工具,一般人也可以自行製作影片,接著會沿生 youtuber、網紅文化,電視一方獨大的現象也會開始勢微。 有一些工作則剛好相反,本身的特性是適合集中地來做,但是因為某些限制存在,人們為了突破這些既有的限制只好訴諸去中心化的權宜之計,一旦隨著工具的發展或是外界的變化導致限制消失時,就會自然回歸中心化。 晶片架構 主流的硬體設計是一個功能對應一個封裝好的晶片、以印刷電路板組合數個不同功能的晶片,電流的訊號必須在印刷電路板上傳送相當長的距離才能完成運算。 然而,由於晶圓製造技術地不斷提高,現在的一些超高效能晶片則是採用 SoC (system-on-a-chip) 架構,即系統所有的功能全部做在一張晶片裡。我寫這篇文章時,使用的Macbook ,裡頭的 M1 晶片就是如此。硬體的設計採用了 SoC 這樣子的中心化架構,一方面節省了封裝成本、一方面電流需要跑的距離也縮小到肉眼幾乎看不見,於是製造成本、耗電量都可以降低,運算速度又可以再提高。

有些工作本身的特性是適合分散式、多點地來做。然而,有時因為工具不普及、法規等限制,反而變成了中心化最有效率。一旦限制消失時,就會產生去中心化。比方說,一旦有了 youtube 與剪接影片軟體、後製影片軟體之類的工具,一般人也可以自行製作影片,接著會沿生 youtuber、網紅文化,電視一方獨大的現象也會開始勢微。

有一些工作則剛好相反,本身的特性是適合集中地來做,但是因為某些限制存在,人們為了突破這些既有的限制只好訴諸去中心化的權宜之計,一旦隨著工具的發展或是外界的變化導致限制消失時,就會自然回歸中心化

晶片架構

主流的硬體設計是一個功能對應一個封裝好的晶片、以印刷電路板組合數個不同功能的晶片,電流的訊號必須在印刷電路板上傳送相當長的距離才能完成運算。

然而,由於晶圓製造技術地不斷提高,現在的一些超高效能晶片則是採用 SoC (system-on-a-chip) 架構,即系統所有的功能全部做在一張晶片裡。我寫這篇文章時,使用的Macbook ,裡頭的 M1 晶片就是如此。硬體的設計採用了 SoC 這樣子的中心化架構,一方面節省了封裝成本、一方面電流需要跑的距離也縮小到肉眼幾乎看不見,於是製造成本、耗電量都可以降低,運算速度又可以再提高。

軟體產品布署

1995 年之前,網路還相當的緩慢,那個時代的軟體,多半是以光碟的形式傳播。使用者要先把軟體安裝在個人電腦裡才能使用軟體。

然而,當網路的速度愈來愈快時,雲端軟體就開始流行,許多的軟體的設計,都逐步改成商業邏輯、運算、資料都放在雲端伺服器上,使用者用瀏覽器即可以使用軟體。改用雲端軟體這種中心化的方式來布署軟體的話,廠商每次更新軟體,不再需要去考慮用戶的個人電腦環境,因為軟體布署在廠商自家的伺服器裡,這讓軟體的快速改版得以實現。

軟體商業邏輯的布署

早期的 CPU 比現在慢非常多,為了讓系統可以正常運作,出現了應用軟體的 n-tier 架構。Perl, PHP, Python, Ruby 之類的程式語言寫的後端程式,要布署在獨立的 application server 上,如此才能讓資料庫伺服器的負擔變小,從而讓系統順利運作。

然而,當硬體的效能大幅改善,加上後來版本的 SQL 也比原先版本的更具有簡潔的表達能力,在這種條件之下,相對穩定、不快速變動的商業邏輯直接以 SQL 來實作,由於資料與程式可以位落在同一台機器裡,省去了 IO 的開銷,運算效能也可以大幅地提昇。

頁面生成的邏輯

有一段時間,網路說快不快、說慢也不太慢,為了的使用者體驗,使用者介面 (UI) 會採用 SPA (single page application)。頁面生成的邏輯,則大量地從後端移往前端 (去中心化)。

然而,隨著網路的速度變快許多,搭配前端應用 htmx 之類的函式庫,頁面全部在後端生成就可以達成類似的效果。於是,使用者介面的邏輯大量往後端移動、集中化,省去了前後端軟體開發溝通的成本,軟體開發的效率可以大幅提高。

資料工程

過去,為了應用海量的企業資料,但是 data warehouse 的成本太高,只好採用 data lake ,用各種較低成本的解決方案 (去中心化) 去儲存資料。

然而,當 data warehouse 的速度與容量都大幅進展後,就可以再一次地把大量的資料全部放進 data warehouse ,這樣子一來,在 data warehouse 上執行的 SQL 即可取代一個又一個手刻的 MapReduce ,如此,資料清理、資料建模更改版本的速度自然可以提高。

總結

每個人都在談論的事稱之為流行、每個人都在做的事叫趨勢。中心化的作法如果符合了工作本身的特性,可以帶來極大的效能提昇,這是一種工作流程上的創新。但是,如果決策者在思考工作流程時,對於去中心化的作法有執著又或是盲從於潮流,就會妨礙這種創新。

--

--

我曾經拜訪過幾位的 CEO ,有時候也會有機會談到各式各樣的「決策」,不管是技術選型、人才雇用、選擇外包廠商等等。我很喜歡詢問 CEO ,『請問貴公司是如何做出這樣子的決策的?』

從這些 CEO 告訴我的事,我認為關於「決策」有三個重點:

  • 決策大致上也符合所謂的 80/20 法則。大多數的決策影響並不大,但是極少數的決策影響非常重大。
  • 做好的決策、正確的決策,也許不會讓公司立刻勝出,但是,無數正確的決策累積下來之後,產生的競爭優勢非常可觀。
  • 對於組織來講,要長期穩定地做出高品質的決策,應該要利用所謂的理性決策方式,即所謂的「決策模型」。透過決策模型來決策,是提昇一個組織長期決策品質的不二方式。

最近,有一位 CEO 請教了我一個很有趣的問題,「為什麼 Clojure 語言,如此小眾的語言,在台灣居然還有三家公司在使用?這些公司難道不擔心找不到人才嗎?這些公司是如何做出這樣子的決策的?」

老實說,我也不知道這些公司是如何決策的。而且,這些公司也很有可能『沒有使用任何決策模型、一切還是是交由 CTO 決定』。但是,另一方面,在絕大多數的情況之下,我也會選擇 Clojure,所以我給了那位 CEO 我本人的決策矩陣。

程式語言決策矩陣

programming language decision matrix

應用「決策矩陣」有下列的步驟:

首先,第一步要想清楚「決策前提」

「如果我要讓公司取得長期的成功,用哪一種程式語言,最有優勢?」

第二步要列出各種可能的選項

簡化一點,這邊只列出 Java, Python, Javascript, Clojure 四個選項。前三個大概是目前台灣市場最主流的選項。

第三步則是要列出,會有助於達成決策前提的關鍵要素

  1. Machine Efficiency (在機器上的執行效能)
  2. Developer Productivity (軟體工程師的開發速度)
  3. Library Ecosystem (語言函式庫的生態系完整度)
  4. Extending to Frontend (該語言是否可以延伸應用到前端?)
  5. Local Talent Pool (在地的人才庫)

上述的 5 點,滿分都是 10 分,最低分是 0 分。

第四步,將矩陣填完

填寫數值的部分,也沒有所謂絕對的客觀、必然還是有主觀的成分。然而,將本來只用一兩句話就解釋完的決策,改成使用決策矩陣決策,可以讓經驗、資訊、判斷被有效地加以整合。

最後一步,加總判斷,做出充分考慮多個面向、最平衡的選擇。

決策的關鍵

我解釋完決策矩陣之後,CEO 又問了我第二個更重要的問題,「做這樣子的決策,跟別人都不一樣,不會有一種怕怕的感覺嗎?」

我引用杜拉克的話回答他,要做好決策,最重要的關鍵,不在於卓越的分析能力。而是有沒有勇氣去「選擇未來而非過去、著眼於機會而非問題、堅持自己的方向而非隨波逐流」。

--

--

我做了一個夢,夢到了一家公司。我在想,也許大家也會覺得似曾相似、有點眼熟?

  • 該公司疑似有現代的管理方式?比方說,使用 OKR 作為管理方式。
  • 該公司疑似也有鼓勵創新?比方說,舉辦駭客松。
  • 該公司也有非常多的會議。

夢裡的細節有點鮮明,讓我不由得記錄了下來:

  • 雖然使用了 OKR ,但是,主管要求下屬設定 OKR 時,主管並沒有給予方向,因為主管也不太清楚公司的策略方向。反正,公司明年需要做的事,就是把去年或是前兩三年的業績,做個線性外插,就取得明年的目標了。至於說,資源如何分配呢?資源分配的邏輯,與政府也很相似,就是比賽誰比較會喊、誰比較會提案、誰與上司的關系最親近。資源分配主要由政治實力決定,與公司的策略沒有關系。仔細想想,既然公司的策略從來就不存在,當然該公司的員工必須想出使用「策略」以外的基準來分配資源嘛!這也是在困境中不得已而為之的辦法。
  • 由於該公司也雇用了不少的軟體開發人才,所以自然一定要舉辦所謂的駭客松,這樣子才跟得上時代嘛!對於該公司來說,只要有寫軟體,就叫做創新。在管理學書上的定義,創新的重點與結果應該是要提昇公司的營運績效、顧客滿意度,未必是要使用「新知識」、「新科技」。然而,在『彼得原理』在該公司有效地運作的前提之下,「demo 軟體」這種可以讓主管上台,增加曝光度的東西,當然是創新的首選。正如彼得原理的預測,下屬一切的作為,最重要的事,就是討上級的歡心,「創新」自然會是為了讓上級風光而創新,而不是為了提昇客戶滿意度而創新。
  • 該公司的會議,在簡單的事情上,通常開得相當久,在困難的事情上,通常開得特別快。討論簡單事務的會議,主講者是主管,而下屬是聽眾。這種會議有一種非常重要的功能,它可以強化主管們的 ego 。無論主管腦子裡的知識有多麼地過時,透過一場又一場與下屬召開的會議,都可以再一次地自我強化「主管就是比下屬們優秀得多」這種永遠經得起時間考驗的概念。討論困難事務的會議,這種會議就超有效率,因為主管們通常就是只討論工作的 input ,而不討論工作的 output 。主管們交代完下屬工作完成的 deadline 之後,會議就算是完成 80% 了。至於說要完成什麼、細節是如何,那些絕對是下屬的責任。之後如果主管看了結果覺得不滿意,這表示下屬需要再多加訓練,所以解決之道是:「主管主講的那種會議,時間要再加長一些。」

在那個夢裡,我想發表一點意見,但是,該公司的許多人跟我說,「我們公司無論是在管理制度、創新、人才,全都是一流的。」「這就是我們公司一貫的風格啊!大家都是這樣子做啊!」

--

--

Vector graph created by www.freepik.com

上個月被客戶問了:「你如何做好銷售的工作?」由於我是做顧問業,銷售上遇到的問題也有顧問業的特性,不過,既然被問了,就來談看看。從開業以來,我遇過的 4 種常見的銷售問題。

  1. 工作內容延展、或是殺價
  2. 詢價、估價
  3. 介紹費
  4. 不可能的任務

工作內容延展或是殺價

這類的問題有兩種變型:

  1. 合理的工作內容延展
  2. 不合理的工作內容延展或殺價

第一種情況是:我協助客戶完成了合約所定義的工作之後,客戶發現當初他與我談好的需求,與他後來領悟的需求有落差,想請我「順便」再修改一下。舉個例子,有一回客戶請我開發軟體,設計了一個 UI 選項,是「過去 365 天的利潤總和」。等到功能完工之後,客戶跟我說,他認為我做的軟體有 bug ,請我修正,因為在 2020 年這個功能並不正確。我回應他,2020 年有 366 天,因為是閏年,也因此,他所需要的並不算是修正錯誤,而是進階版的功能,能一併處理閏年。像上述這種情況,就是常見的「合理的工作內容延展」。

在上述的這種情況,我採取的作法會是:如果我真的順手就可以解決的話,服務就直接贈送客戶。如果並不是順手的話,我會跟客戶說:「對於貴公司委託我的工作,超出合約的部分,無法保証其完工的品質,如果希望維持一貫的品質的話,由新的合約來界定的工作,會符合彼此的最佳利益。」

第二種情況是:客戶講了某個他覺得有說服力的理由,認為我提供的服務之一部分,並不符合他的需求,要求退掉服務中的一部分以換取其它服務,又或是直接殺價。遇到這種情況,我後來的心得是:『很多時候,客戶也許善於議價與殺價,但是,並不一定有想清楚其自身的最佳利益。』這種情況,我將其視為是「不合理的工作內容延展或殺價」。此處的不合理,是指,在客戶最佳利益的層次上不合理。

比方說,有些時候,客戶其實並沒有所謂的 BATNA (best alternative to a negotiated agreement),只是因為喜歡殺價,就二話不說地要求議價。遇到這種情況,我會詢問客戶,「請問貴公司委任我某工作,最主要的目的為何?對現在的這個細節詳加討論,與主要的目的是否有關?在這件事上多花費時間討論,是否符合貴公司的最佳利益?」

詢價、估價

有的客戶喜歡問價錢。在談話剛開始時,就先詢問,「一般來講,做某某事,價格多少?」像這樣子的提問,我一開始的處理方式,是回答:「可以請您描述一些更多的細節嗎?」這樣子的回答,通常對話持續不下去。原因很簡單:很多時刻,潛在客戶詢問價錢,是要取得價格的參考資訊,並不一定真的有意願要做生意。

想通了言談背後運作的邏輯之後,解法就簡單多了,我會回答客戶:「如果您能考慮安排 1 個小時,與我談談您的需求的話,我可以在談話之後,迅速地給您一個參考的價格。」

介紹費

對幾乎大部分的生意來講,舊客戶介紹新客戶,都是生意成功的關鍵點。我也會請我的客戶幫我介紹,偶爾也會有遇到極少的客戶認為,我應該為其支付介紹費的情況。

對於客戶介紹客戶一事,去表示感謝,有許多不同的方式可以做到。直接給予金錢的方式,由於被負面解釋的可能性相對高,為了省事,我就不考慮這個選項了。如果口耳相傳是基於愉快的合作關系,這是相當正面的。然而,如果口耳相傳主要是由金錢所推動的,這樣子,顯然違反了一句做生意的古諺: Market share should be won, not bought.

不可能的任務

客戶會考慮委任顧問工作,很多時候,客戶對於顧問的專業領域所知是甚少的。也因此,也有許多成功的委任,在最初的時候,它的樣貌是一種「不可能的任務」。對於不可能的任務,我後來領悟的作法不是「硬接下來」、也不是直接說:「這是不可能的任務」,而是透過談話與提問,提供客戶關鍵的資訊,讓客戶可以優雅地修改他原先構思的委任方式。

銷售的重要性

在日本漫畫「結界師」裡有一句對白:「不漂亮的工作,只能得出不漂亮的成果。」我覺得這句話也可以應用在銷售上,『不漂亮的銷售,只能得出不漂亮的成果。」

--

--

Vector graph created by www.freepik.com

許多的專業人士,比方說,軟體工程師、會計師、律師等等,都會需要跟客戶或是上級溝通,而在溝通時,就很容易遇到所謂「溝通不良」的問題。

先不論遇到奧客或是缺乏專業的管理階層,專業人士在與委託人溝通自己的專業時,本來就很容易遇到一種困境:「沒有合適的語彙可以使用,換言之,一旦使用專業術語,委託人就聽不懂。」

要改善這種情況,專業人士需要對溝通的情境 (context) 做一點分析。視溝通的對象與溝通的主題,溝通的情境可以分成三種不同的層次:

  1. 溝通委託人的問題/困擾 (domain problem)
  2. 溝通專業人士所提出的解決方案 (solution)
  3. 溝通解決方案的執行細節 (implementation details)

我認識的專業人士,往往都最善長溝通「執行細節」的部分。原因很單純,執行細節就是專業人士的專業領域。要討論執行細節,專業人士覺得要講清楚相對容易,因為這部分要溝通清楚,就是要使用『專業術語』。

要溝通清楚「解決方案」,往往需要一種由「外部觀點」的視角所建構出來的「高階語彙」才能講清楚。而這種「高階語彙」很有可能並不在專業人士過去所學的專業知識領域之內,而是需要其它領域的知識,甚至下游產業/下游服務提供者的知識有時反而更容易說清楚。以軟體開發來舉例子:要詳細描述一個軟體系統的外部行為來讓一般人充分了解,有時候反而要使用軟體工程師並不特別熟悉的 Excel ,反而最容易溝通清楚。

而討論「委託人的問題」之溝通難點在於:「專業人士變成了所謂的聽話者,而說話者是委託人。」在這種情況下,專業人士必須要精於提問,要透過有系統的提問,才能取得重要的資訊。

--

--

最近在台灣 Clojure 社群有一件事:一位新加入的朋友,提出與 Lisp 相關的見解。而我回應了『 Clojure 與多數 Lisp 的不同點與 Clojure 社群少用 Lisp macro 的特色』之後,這位新朋友似乎受了刺激,對我寫下了一段的批評指教與酸言酸語。

酸言酸語中,有部分也滿經典的,這邊就原文引述一下: 「那我就不難理解,這種樣子的板,最後只會剩一個人叨叨絮絮地發表言論了,因為人們不知道要討論什麼。是否別人需要看你的意向,而決定自己能談什麼,不能談什麼嗎?

我看完了這位新朋友給我的指教之後,注意到兩點:

  1. 沒有正面地與我的論點爭辯。我認為開發應用軟體,刻意積極地使用的 Lisp macro 去擴展程式語言的作法,是極少數的案例才會有用,大多數的案例不僅不會加分,還會扣分。他給我的回應裡,並沒有明確講清楚他對使用 Lisp macro 的主張,到底要用,還是不要用?
  2. 爭點是主要論點以外的部分。批評我的重點,放在態度不佳、沒有資格說 Clojure 社群是如何如何、台灣 Clojure 社群如此地冷清…。

此處,引述一下法國哲學家 Michel Foucault 對於知識與權力的論點:Foucault 認為,「真理」是運用權力的結果。(翻得通俗一點:官大學問就大!)。此外,能夠表現出來「有知識」是權力的一種來源,因為這樣的話,你可以有權威地說出別人是什麼樣的和他們為什麼是這樣的。在管理學裡,也有相似的論述,稱之為「專家權力」 (expert power)。附帶一提,管理學者認為專家權力的行使,有一個但書:「並不是你有專業能力就會擁有專家權力,而是你的專業能力受到部屬或是周遭環境的認可 (recognized),專家權力才會因而產生。」

我認為:社群這位新來的朋友,可能把關注的焦點放在了自己與群體之間的相對權力關系,因而相當的不開心。他意識到了社群場域之中,隱含的階級設定,並且對於該階級設定有著極大的不滿意,因而想跟我來一場話語權的爭鬥。如果是這樣子的話,我的建議會是:

  1. 把關注的焦點放到「取得知識」或是「發展人際關系」。一般而言,參與社群活動,通常最大的收穫就是上述兩件事。
  2. 接受或是忽略別人意見的判斷準則,是要對自己有益。如果覺得別人的意見,可以為自己的軟體開發工作,帶來價值,就採納。無法帶來價值,大可忽略。至於提出意見的人是否是專家、資深工程師、社群領袖,其實沒有那麼重要。

--

--

programming misconception

客戶問我,「你幫本公司做的專案裡,客製化軟體開發的部分,日後要怎麼維護呢?」

我:「貴公司有兩百多位的員工,疑似也有一些有餘裕的人手,如果你可以遴選幾個人出來,讓我訓練 100 個小時左右。日後,一些基本的功能,比方說,加一兩個欄位等,他們應該可以自己修改。」

客戶露出不可置信的表情:「咦,寫程式這件事是可以訓練的嗎?你講得彷彿每個人都可以學會。我自己學過,我的同班同學後來有學會、有學好的,往往就是那少數幾個。」

我:「學任何有一點門檻的東西,都會有所謂的資質。有的人天生就是學得快、有的人反之。為了要提高訓練的成功率,請你選擇那些在工作上需要使用 Excel ,而且最好是使用 Excel 用得出神入化的員工。我來訓練這種學員的話,自然是勝多敗少。」

上述的對話,在我的客戶的對話裡,常常不斷地發生。這些對話,讓我發現一般人、甚至是專業的軟體開發人員,常常有下列三個關於學習寫程式的迷思 (misconception):

1. 學寫程式非常的困難、要非比尋常的資質才能學會
2. 會寫程式的人都非常聰明
3. 要成為優秀的軟體開發人員,必須是電機資訊本科系畢業。

在探討上述三個迷思之前,我要先來探討,「軟體開發」的本質是怎樣子的一件事。軟體開發工作,是對真實世界的資訊加以建模,並且利用電腦來加以處理。根據上述的定義,如果先不探討後半句:『並且利用電腦來加以處理』,那會計、法律,也跟軟體開發有許多相似之處。

舉個例子:像一般人每天使用軟體,都會用到的輸入密碼/登入的功能。這個「驗証使用者密碼」的軟體模組,它的基本假設就是:使用同一組帳號,同一組密碼的,就是同一個人。是同一個人的話,系統就准許它看影片。然而,實際上常發生的事情是:同一個家庭的兄弟姊妹共用 netflix 帳號,換言之,每一次地成功登入,是否是同一個使用者一事,往往也 …。法律也有類似的概念:雙方簽名、到戶政登記,就算是結婚。結完了婚,就有一系列的權利與義務。至於,是否真心相愛、是否…。往往就是上法院訴訟,才會再展開討論。會計也有類似的現象:公司收購時,就會產生所謂商譽的價格。置於商譽如何估價,這個估價是否合理,也是視會計方法而定,與真實世界要是脫節的話,就…。凡是用來對真實世界建模的系統,總是會有系統與真實世界交會之處,遇到模型無法 100% 反映現實的問題。

另一方面,就算加入探討後半句「利用電腦來加以處理」的話,還是與法律、會計有異曲同工之妙。比方說,現代的會計師,很多都會利用 Excel 或是財務會計軟體,來自動化產生報表,這也是利用機器來做自動化。律師寫完訴狀,送到法院,過了一段時間,法院就會通知開庭。法律的系統就像一台很慢的電腦,依然是照著規則系統來運作。

接著,回到三個迷思:
1. 學寫程式非常的困難。
並不特別困難,但是,它需要使用正確的學習方式才容易學會,它需要大量在電腦前的練習與肌肉記憶。

此處,我要特別強調『大量練習』與『肌肉記憶』。在我學習寫程式的那個年代,我從 C++ 開始學,一開始學沒有多久,就要處理 Makefile 。Makefile 裡是使用 tab 字元來做分隔子。這個設計也不特別有道理,就是路徑依賴。但是,幾乎每個夠老的程式設計師都記得這一條規則。(可能都在這一條規則上,撞得鼻青臉腫過。) 軟體開發在人類歷史上存在的時間,並沒有很久,還是一門相對新的技藝,工具不停地快速演進中,所以快速發展出來的工具,往往會有不為初學者設計的成分、不甚合理的成分,這就造成了它的學習障礙。

2. 會寫程式的人都非常聰明
針對這個迷思,我會反問:「是聰明,所以學得會?還是學會了,所以顯得聰明?」

人類要感知世界,會利用視覺、聽覺、嗅覺等知覺。然而,視覺看不到的,不代表我們一定看不到,我們可以利用紅外線夜視鏡取得夜視能力。同樣的道理,人類要思考,我們也會利用所謂「思考的工具」來拓展我們思考能力的極限。常用的思考的工具主要可以分成三類:
- 圖像思考
- 符號思考
- 互動思考

符號思考的工具,比方說,數學公式、人類的語言、化學符號。圖像思考的工具,比方說,各式的表格、X-Y 軸的圖、等高線圖、透視圖。互動思考的工具的特色在於,你可以與它互動。程式語言本身,就可以視為是一種互動思考的工具,因為你可以把「想法」寫成程式,讓電腦去執行,執行完了,看結果,再回頭來思考,自己的想法是否正確。

我所看過的例子多半是:當一個軟體開發人員,經過經年累月,大量開發軟體的練習之後,思考的速度變得相當快。

3. 要成為優秀的軟體開發人員,必須是電機資訊本科系畢業。
未必。我們可以先探討學校教了什麼、與要成為優秀的開發人員需要什麼。

首先,電機資訊本科系的教授本人,未必是優秀的軟體開發人員。要成為大學教授,以台灣的現況來講,特別重要的是研究能力、發表論文、博士學位。這三者與軟體開發,都是不同的事。再者,以我本人為例,我大學的教授,他們個個學有專精,但是,專精的項目常常是類比電子電路設計、天線設計、數位電子電路設計、軟體驗証理論、密碼學等等。

另一個層面則是,好的軟體之所以可以設計出來,往往需要軟體開發人員,對於問題本身堅持不懈地去探討。軟體是給「人」使用的,「人」、「使用者情境」、「對資訊做建模」才是最重要的問題。而學校教育強調的是「電腦怎麼運作」與「抽象的理論」,反而沒有對最重要的問題做足夠的探討。

在職場上,我看過不少使用 Excel ,用得出神入化,被身邊同事佩服不已的優秀同仁。我一時興起,詢問他們,是否有興趣學習軟體開發時,他們也一樣問我:「你真的認為我學得會嗎?」我的答覆一律是:「我認為,你已經會了…」

--

--

我們是否常常忽略了其中一個面向? — 最近的新聞,全球超過 500 位特斯拉的車主回報出現「500 Server Error」被鎖車外。故事是這樣子:特斯拉開發的無鑰匙駕駛 App ,能遠程開車門或是啟動汽車,所以許多車主後來就習慣不帶車鑰匙,直接用手機開啟車門。但是,當網路或是伺服器出現問題時,這些已經習慣不帶鑰匙的車主就被鎖在車外了。 從系統設計的抽象角度來看:「易用性,常常了付出系統簡單性或是效能去交換。或者是說,易用、效能、系統簡單性,像是一個三角形,設計時,總是會對其做出取捨。」以特斯拉 App 開鎖為例,相比於傳統的機械式開鎖,在開鎖這一道流程上,增加了硬體與軟體的複雜度,也增加了能源的消耗。能源的消耗增加並不多,但是,在系統簡單性上卻是大幅減少。基本上可以視為用系統簡單性換開鎖的易用性。以現在主流設計的汽車自動變速箱為例,如果不使用自動變速箱,那就得使用離合器變速,也就是現在比較少人會開的手排車。用了自動變速箱,付出什麼代價?近 10% 上下的引擎輸出的能量與更加複雜一些機械結構 (但是,沒有任何電晶體或是軟體)。換得了什麼?大幅降低汽車使用者學習與操作汽車的門檻。基本上可以視為用效能換取操作排檔的易用性。

設計常常是在三個面向做出取捨:易用、效能、系統簡單性
設計常常是在三個面向做出取捨:易用、效能、系統簡單性
Design trade-off

最近的新聞,全球超過 500 位特斯拉的車主回報出現「500 Server Error」被鎖車外。故事是這樣子:特斯拉開發的無鑰匙駕駛 App ,能遠程開車門或是啟動汽車,所以許多車主後來就習慣不帶車鑰匙,直接用手機開啟車門。但是,當網路或是伺服器出現問題時,這些已經習慣不帶鑰匙的車主就被鎖在車外了。

從系統設計的抽象角度來看:「易用性,常常了付出系統簡單性或是效能去交換。或者是說,易用、效能、系統簡單性,像是一個三角形,設計時,總是會對其做出取捨。」以特斯拉 App 開鎖為例,相比於傳統的機械式開鎖,在開鎖這一道流程上,增加了硬體與軟體的複雜度,也增加了能源的消耗。能源的消耗增加並不多,但是,在系統簡單性上卻是大幅減少。基本上可以視為用系統簡單性換開鎖的易用性。以現在主流設計的汽車自動變速箱為例,如果不使用自動變速箱,那就得使用離合器變速,也就是現在比較少人會開的手排車。用了自動變速箱,付出什麼代價?近 10% 上下的引擎輸出的能量與更加複雜一些機械結構 (但是,沒有任何電晶體或是軟體)。換得了什麼?大幅降低汽車使用者學習與操作汽車的門檻。基本上可以視為用效能換取操作排檔的易用性。

在軟體世界的設計,有哪些常見的取捨

  • NoSQL
  • Virtual machine (Application virtual machine)
  • Immutable collection
  • Lisp syntax

NoSQL 以 Cassandra 為例,相比於 RDBMS,少了極其強大的 SQL 查詢語言 ,換得了部分效能的提昇。算是用易用性去交換效能。

Application virtual machine ,也就是 JVM 一類的 VM ,相比於不使用 VM 的 golang, rust, C 等直接編譯成二進位執行檔的解決方案,付出了 VM 執行效能的損耗、garbage collection 的效能損耗,換得了開發軟體時,可以輕易跨平台的方便性。算是用效能去交換易用性。

Immutable collection ,也就是 Clojure/Scala/Haskell 這一類語言預設提供的 collection ,比一般 mutable collection 更消耗 memory ,但是,在平行處理的程式開發時,正確性大幅提高。算是用效能去交換易用性。

Lisp syntax ,也就是程式語言的語法使用 s-expression ,而一般非 Lisp 的程式語言則是使用一般的數學表示法 。對於使用者來說, s-expression 很不自然,需要學新的東西,有點像是手排汽車的排檔一樣,這是付出的代價。另一方面,這個設計得到的是什麼呢?是程式語言、編譯器複雜度的大幅簡化。算是用易用性去交換系統簡單性。

系統簡單性的價值,特別容易被忽略

上述的三個面向:易用、效能、系統簡單性,在我個人看來都很重要。但是,在實務上,易用性與效能容易被覺察與理解,系統簡單性卻特別隱晦。首先,易用性可以立刻被消費者感知。再來,效能往往與產品運行時的成本相關,所以這個特性也很容易被消費者察覺。

系統簡單性,其實也會對消費者有不下於其它兩者的正面的作用,但是,它的價值往往有「時間遞延」的性質。前文的例子裡,使用傳統的車鑰匙,就是一種系統簡單性勝出的案例:因為簡單,所以有耐用、易維修、安全等等的附加價值。Lisp syntax 也是一樣,因為簡單,所以這種程式語言的核心特別小,幾乎不會出現日後增加語言功能就破壞向下相容性的問題。系統簡單性的正面價值都會產生,但是,對於產品使用者來說,往往有「時間遞延」的現象,因此容易被忽略。此外,系統簡單性也不是那麼容易直接量測。

詢問「這個系統是否簡單? 」

由於系統簡單的這個特質,容易被一般人所忽略,我通常建議客戶,在需要做與科技相關的決策時,除了問:「這個解決方案是否合用?」「這個解決方案,它的 life cycle cost 是多少錢?」這些問題之外,還有一個重要的問題:「這個系統本身是否簡單?」因為許多會因為時間而產生的效應,都會受到這個因子的影響。

我家要安裝免治馬桶時,由於這是一個與技術相關的決策,家人參考了一下我的意見。我選了純機械式的免治馬桶。由於它是純機械式的,所以不用接電,我自己安裝就可以了,除了它本身就比較便宜之外,又省了一筆工錢。至於「耐用」這一點更是不用懷疑了。

--

--

你問對問題了嗎? — 客戶最近請教了我三個與「客製化軟體委外開發」相關的問題: - 如何評估預算? - 如何看懂廠商給的規格書? - 廠商要是沒有辦法準時交付,我該怎麼辦? 對上述的問題,我回答如下: - 評估預算應該從最重要的資訊來評估:ROI (return on investment)。無論是已經上軌道的公司或是新創,要做客製化軟體開發,都會有想要解決的問題,比方說,節省一定的人事成本、縮短銷售時程 (sale closing time) 等等,也就是會有所謂的預期效益 (return) 。而基於效益而評估出來的預算,自然就是投資 (investment)。 - 廠商給的規格書方面:在軟體來講,規格書有很多種。有幾種的規格書,是設計來給軟體開發人員看的,比方說 UML 圖、資料庫的 schema 等等,它描述的是軟體的實作細節 (implementation details)。如果是給發案的業主看的,叫做「軟體需求說明」(Software requirements specification 或 SRS),它描述的是軟體的功能 (purpose) 。這邊做個類比,如果你恰好有一間房子要做裝潢,施工的裝潢公司會有不同的說明文件:給業主看的,是房子內的配置、外觀的設計圖,這種近似於 SRS。另一方面,給施工的水電、水泥工看的,則是另一種文件,它描述的是實作細節 (implementation)。實務上,也許不在少數的軟體開發人員或是公司,他們給業主看的文件,就是直接拿描述實作細節的規格書給業主看,也因此讓業主產生一種「規格書」都無法理解的印象。 - 為了避免延時交付、或是軟體品質問題,可以在合約裡明定責任的歸屬,彷彿這是一個法律與責任歸屬的問題。然而,如果定了合約、定了罰則就可以有效解決這些問題,那業界常見的 84% 的軟體專案延遲交付,這又是怎麼來的?

如何做好客製化軟體委外開發
如何做好客製化軟體委外開發

客戶最近請教了我三個與「客製化軟體委外開發」相關的問題:

- 如何評估預算?
- 如何看懂廠商給的規格書?
- 廠商要是沒有辦法準時交付,我該怎麼辦?

對上述的問題,我回答如下:

- 評估預算應該從最重要的資訊來評估:ROI (return on investment)。無論是已經上軌道的公司或是新創,要做客製化軟體開發,都會有想要解決的問題,比方說,節省一定的人事成本、縮短銷售時程 (sale closing time) 等等,也就是會有所謂的預期效益 (return) 。而基於效益而評估出來的預算,自然就是投資 (investment)。
- 廠商給的規格書方面:在軟體來講,規格書有很多種。有幾種的規格書,是設計來給軟體開發人員看的,比方說 UML 圖、資料庫的 schema 等等,它描述的是軟體的實作細節 (implementation details)。如果是給發案的業主看的,叫做「軟體需求說明」(Software requirements specification 或 SRS),它描述的是軟體的功能 (purpose) 。這邊做個類比,如果你恰好有一間房子要做裝潢,施工的裝潢公司會有不同的說明文件:給業主看的,是房子內的配置、外觀的設計圖,這種近似於 SRS。另一方面,給施工的水電、水泥工看的,則是另一種文件,它描述的是實作細節 (implementation)。實務上,也許不在少數的軟體開發人員或是公司,他們給業主看的文件,就是直接拿描述實作細節的規格書給業主看,也因此讓業主產生一種「規格書」都無法理解的印象。
- 為了避免延時交付、或是軟體品質問題,可以在合約裡明定責任的歸屬,彷彿這是一個法律與責任歸屬的問題。然而,如果定了合約、定了罰則就可以有效解決這些問題,那業界常見的 84% 的軟體專案延遲交付,這又是怎麼來的?

其實,上述這些問題,相信絕對不是只有我的這位客戶有而已。因為我有遇到幾位的潛在客戶,來找我談生意時,他們的問法基本上都長成這樣子:

- 我想要做一個,跟 A 公司一樣的 OOO 軟體。
- 你估價多少錢呢?

於是,如果軟體外包商單純照客戶的提問來回答,照上述提問的軌道進行溝通,廠商提出的規格書很可能就真的是描述實作細節的文件 (畢竟功能需求,業主就已經指定,要跟 A 公司的 OOO 一樣嘛!)。

而業主拿到了估價與規格書之後,就立刻產生了最初的問題:

- 這個估價是合理的嗎?我要不要殺價?要不要貨比三家?
- 這個規格書我怎麼看不懂啊?咦,好像是設計圖,那我如果拿去給其它家廠商看,他們會報一個比較便宜的價格給我嗎?
- 我該選哪一家廠商呢?我想選最便宜的,但是,會不會品質很糟或是延時交付呢?

而上述這種方式達成的結果,往往不會是成功的專案,而結果十之八九就會像業界的常見的現象:軟體專案,成功是例外,失敗是常態。

客製化軟體不是解決方案 (solution)、而是解決方案的放大器 (amplifier)

曾有一位客戶委任我做財務領域相關的軟體,一開始他提的規格需求就是用「跟 A 公司的 OOO 一樣,然後在這邊改一點點」的方式來描述。我告知他,「A 公司的 OOO 看起來是一個團隊做了兩年的成果,不像是你的預算可以負擔的。」由於這位客戶本人對於 Excel 相當熟練,我給了他一個建議:「把你想要做的東西,先用 Excel 拉出一個概念雛型,然後,我們再來討論把這個做成客製化軟體大概要多少錢?」3 個月後,這位客戶重新思考了他的問題 (problem domain),並且給了我一個含有十個分頁的 Excel 檔案,而我也在 3 個月後,將專案準時交付。

在上述的案例裡,業主一開始也是用「跟 A 公司的 OOO 一樣,然後在這邊改一點點」的方式來提需求。這種提出需求的溝通方式,其根本問題在於:「A 公司的 OOO ,是 A 公司為了 其特有的問題,設計的解決方案。」然而,業主的問題十之八九,會與 A 公司的問題有一定的出入,在還沒有分析問題,針對業主的問題提出針對性的解決方案之前,就冒然委外開發一個「可能與問題不合用」的客製化軟體,這就是會導致失敗的根本要素。

比較好的做法是:「業主必須承擔溝通的責任,與廠商一起去對自己的問題 (domain problem) 做分析與研究,來提出解決方案 (solution)」此處的「解決方案」可能是各種不同的形式,最常見的形式應該是 Software requirements specification。然而,在上述的例子,解決方案就是一個 Excel 檔案。當然,如果用 Excel 檔來服務大量的用戶,問題一定很多,所以如果要服務大量的用戶,當然還是要把 Excel 版本的軟體,改成 web 版的 SaaS 服務。 SaaS 服務,就可以視為是 Excel 版本軟體的放大版 (amplified version)。

在我的經驗,如果業主有針對自己的問題做出深入分析之後,往往會發現,自己真正需要的解決方案可以比原先自己口頭描述的簡單許多。解決方案變簡單了,價格自然就可以降下來,交付時間也可以大幅縮短。此外,前述業界常見的軟體延遲交付比例 84% ,造成的原因排行前兩名,分別是「需求不明確」與「需求變動」。某種程度來講,「需求不明確」與「需求變動」往往也是導因於,最初就沒有針對業主的問題,做足夠的研究與分析。

--

--