軟件工程及軟件工藝
2018-12-24
軟件工程是一個相當耳熟能詳的名詞,軟件工程(Software Engineering)由來已久,亦因此程式設計師(Programmer)又稱為軟件工程 師(Software Engineer)。 而有讀過以前《Programmer 做到三十歲就要轉行?》的朋友,應該對軟件工藝(Software Craftsmanship)這個字不陌生,同時科啟 學院其中一個創院價值,就是於香港資訊科技界推廣軟件工藝,於我們而言,軟件工藝代表的是軟件開發中創造的一面。
軟件工程
軟件開發真的是工程嗎?最容易理解的方法是看看軟件開發與其他工程範疇是否有類近之處:挑戰者號穿梭機因為一個密封圈失靈,就釀成意外。
軟件也會因為一個小錯誤,就會
有大問題,著名的Apple Goto fail Bug就造成全世界加密系統的漏洞,而其實查明原因,錯
誤只是因為少了兩個標點符號:{
及 }
。
原本是這樣:
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) goto fail; goto fail; if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) goto fail;
正確應該是這樣:
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0){ goto fail; goto fail; } if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) goto fail;
造成滿城風雨的Heartbleed bug也是一樣是很小很小的錯誤,也因為出問題的是加密較件,導 致後果嚴重。
此些事例,充份顯示軟件開發的工程一面,工程着重準確(precise),要求精細(detail-minded),講究可測量(measurability),在軟件工程中也有 很多相對應的例子:
- 效能調較(Performance Tuning)
- 使用者測試(User Acceptance Testing)
- 單元測試(Unit Testing)
- 資訊保安(Cyber-security)
以上各項,都是典型軟件工程的例子,效能調較測試的是運行速度(Speed)、可負載量(Load);使用者測試也是根據清單逐個逐個測試,不論有任何一個細 項不合格,都不能正式推出;單元測試更會計算測試覆蓋率(Coverage percentage),去判斷單元測試是否到位;資訊保安經常要做滲透測試 (Penetration Testing ),來判斷軟件是否安全。以上種種,都可以看到軟件開發有非常精細、準確的一面。
軟件工藝
筆者按於2020-11-12: 有讀者認為之前的例子不能反映軟件工藝之分野,只是反映了不同版本的Node.js處理非同步之做法,因此筆者決定更改此例子,以闡術筆者之想法。
資深軟件工程師經常會用到寫得「美妙」、「很醜」等形容詞,這可奇怪了,為何會使用美感的形容詞如美或醜去形容一段程式碼 碼呢?因為軟件工程不只工程一面,還有非常具創造性的一方面。 以下是三段Python 函數的程式碼,所運行的算法是非常相似的,都是嘗試找出所有在n以下0以上之整數的畢氏定理整數組合(Pythagorean Triplets),即使大家不一定懂得編程,但大家覺得那一個最為簡潔明確呢?
第一個例子用傳統迴圈(Loop)做法:
def pythagoras(n): triples = [] for x in range(1,n+1): for y in range(1,n+1): for z in range(1,n+1): if x**2 + y**2 == z**2: triples.append((x,y,z)) return triples
第二個例子運用了列表推導式(list comprehension):
def pythagoras(n): return [(x,y,z) for x in range(1,n+1 ) for y in range(1,n+1 ) for z in range(1,n+1 ) if x**2 + y**2 == z**2 ]
第三個例子運用了產生函數推導式(generator comprehension):
from itertools import permutations def pythagoras(n): return ((x,y,z) for (x,y,z) in permutations(range(1,n+1),3) if x**2 + y**2 == z**2 )
這三個方法有何分別呢?且等筆者一一解說:
- 第一個方法運用最傳統的
for
迴圈及if
,本身較容易理解,但寫出來感覺上較累贅,而且也多了許多縮排(Indentation) - 第二個方法運用了列表推導式(List Comprehension),是
Python
一個較獨有之功能,開發者可以用一個類似寫數學中的集合(Set)的方法去構建列表(List) - 第三個方法更進一步,運用了
Generator
,也就是整個運算是Lazy
的,所謂Lazy
,就是會等待我們使用一個函數next()
才會計算下一個整數組合,另一方面又用了permutations
的function ,避免使用了nested loop
。也加上了x + y > z
去避免搜尋不可能是整數組合之數字。
以下是一個使用的例子:
from itertools import permutations def pythagoras(n): return ((x,y,z) for (x,y,z) in permutations(range(1,n+1),3) if x**2 + y**2 == z**2 if x + y > z ); >>> gen = pythagoras(10) >>> next(gen) (3, 4, 5) >>> next(gen) (4, 3, 5) >>> next(gen) (6, 8, 10) >>> next(gen) (8, 6, 10) >>> next(gen)
所以,就算你輸入一個很大的n
例如pythagoras(1000)
,效能也會較好,因此可以判定方法三比方法二及一都要好。
因為寫程式碼要求其實不只正確那麼簡單,還要着重易讀(Readable)、易寫(Writable)、高效能(Performant)。著名軟件工程師Harold Abelson曾言:
Programs must be written for people to read, and only incidentally for machines to execute
所謂美的代碼,正是兼具易讀(Readable)、易寫(Writable)而又準確的代碼。 軟件工藝所追求,正是重視軟件工程師本身編程的技藝,寫美的代碼,建立好的軟件。
有何分別
如果三個意思上一樣,代表對電腦而言,三個在效能上毫無分別,那為何資深軟件工程師會選擇2或3,而不是1呢?因為寫代碼的要求其實不只正確那麼簡單, 還要着重易讀(Readable)及易寫(Writable)。著名軟件工程師Harold Abelson曾言:
Programs must be written for people to read, and only incidentally for machines to execute
所謂美的代碼,正是兼具易讀(Readable)、易寫(Writable)而又準確的代碼。 軟件工藝所追求,正是重視軟件工程師本身編程的技藝,寫美的代碼,建立好的軟件。
宣言
美國一群軟件工程師曾經提出一個相當精彩的宣言,去綜合軟件工藝的意涵:
As aspiring Software Craftsmen we are raising the bar of professional software development by practicing it and helping others learn the craft. Through this work we have come to value:
Not only working software, but also well-crafted software
Not only responding to change, but also steadily adding value
Not only individuals and interactions, but also a community of professionals
Not only customer collaboration, but also productive partnerships
謹以此四句,送給一直堅持寫好代碼的軟件工程師,共勉之。
留言
閱讀更多
好Programmer是怎樣煉成的?
2018-12-20
有一個大部份僱主都面對的難題,在芸芸履歷之中,如何萬中挑一,找到好programmer呢?聘請程式設計師很難,不像其他行業,打開 履歷就一目了然:有時履歷上滿滿証書的,其實連FizzBuzz也寫不了;有時看起來像個fresh graduate的,卻又有無限潛力。 如果你是一個要聘請程式設計師的僱主,你應該如何是好呢?
寫Blog與寫Code
2019-01-07
在外國,程式設計師在課餘時間寫Blog是很平常的一回事,大家在找尋技術問題的解決方法時,除了全知的Stack Overflow之外, 很多時候閱讀的就是一些其他高手所撰寫的技術文章,博客平台如Medium等也應運而生。相較之下,香港甚少有聽聞程式設計師有寫博客的習慣,大概是由於 工作繁忙,抽身不暇。筆者此前也只是曾經在一些Facebook專頁寫過一些技術文,現在才算上是恆常出文。短短數月中,已感受到為何外國程式設計師如此樂 此不疲,即使要抽出私人時間,也會寫Blog出文。
平常人都能掌握的Programming 原則
2019-01-29
大家會定時整理自己電腦中的文件嗎?大家看軟件工程師工作時,往往會發現他們的檔案總是井井有條,資料有條不紊地排列。難道學習軟件工程能使人變得 整齊?原因其實在於軟件工程師經常需要處理大量檔案及資料,因此發展出一套完整的工程原則(Engineering Practice),久而久之,就掌握了資料管理 的要訣。而如果平常人也掌握了這些工程原則,在日常電腦使用,其實也有不少好處。
Dart vs JavaScript vs TypeScript
2019-02-17
隨著Flutter受到開發者的重視,Google於2011年推出的Dart又重新進入大家關注的視野之內,不過除了Flutter以外,其實Google的開發者早在2016年也推出過Angular Dart,讓開發者以Dart開發網站應用,不過由於Angular Dart對比TypeScript版Angular文本長期不足,因此沒有引起太多關注。Google推出Flutter,可以說為大家對Dart的信心注入了一劑强心針,大家又重新開始關注這個已有8年歷史的程式語言。 本文想介紹的是,就是到底Dart有何特色?與JavaScript比較,又有何優劣?由於TypeScript開始於前端日漸盛行,我們亦可以趁機比較一下三種語言的異同。