軟件工程及軟件工藝

IT小狗

44 回覆
9 Like 22 Dislike
IT小狗 2018-12-24 19:38:58
原文出處: https://www.tecky.io/blog/軟件工程及軟件工藝



軟件工程是一個相當耳熟能詳的名詞,軟件工程(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),在軟件工程中也有很多相對應的例子:

1. 效能調較(Performance Tuning)
2. 使用者測試(User Acceptance Testing)
3. 單元測試(Unit Testing)
4. 資訊保安(Cyber-security)

以上各項,都是典型軟件工程的例子,效能調較測試的是運行速度(Speed)、可負載量(Load);使用者測試也是根據清單逐個逐個測試,不論有任何一個細項不合格,都不能正式推出;單元測試更會計算測試覆蓋率(Coverage percentage),去判斷單元測試是否到位;資訊保安經常要做滲透測試 (Penetration Testing ),來判斷軟件是否安全。以上種種,都可以看到軟件開發有非常精細、準確的一面。

軟件工藝
資深軟件工程師經常會衝口而出,道:「段code寫得好靚!」或道:「段code寫得好核突!」這可奇怪了,為何會使用美感的形容詞如美或醜去形容一段代碼呢?因為軟件工程不只工程一面,還有非常具創造性的一方面。 以下是三段javascript 的代碼,意思上一模一樣,即使大家不一定懂得編程,但大家覺得那一個清晰,最美的呢?

第一個例子:
const msg = "Hello World!\nThis is my first code"
fs.writeFile('file.txt', msg, (err)=>{
    if (err) {
        console.log(err);
        return;
    }
    fs.readFile('file.txt', (err, data)=>{
        if (err) {
            console.log(err);
            return;
        }
        const content = data.toString();
        fs.writeFile('file2.txt', content, (err)=>{
            if (err) {
                console.log(err);
                return;
            }
        });
    })
});

第二個例子:
const msg = "Hello World!\nThis is my first code";
fs.promises.writeFile('file.txt', msg)
    .then(() => fs.promises.readFile('file.txt'))
    .then((data) => {
        const content = data.toString();
        return fs.promises.writeFile('file2.txt', content);
    })
    .catch(err=> {
        console.log(err);
        return;
    })

第三個例子:
const msg = "Hello World!\nThis is my first code";
async function run() {
    try {
        await fs.promises.writeFile('file.txt', msg);
        const data = await fs.promises.readFile('file.txt');
        content = data.toString();
        await fs.promises.writeFile('file2.txt', content);
    } catch(e) {
        console.log(e);
    }
}
run();


注:用console.log 是因為缺乏上文下理,無法處理異常狀況,如果在web Server的情況下就應該返回500 response code。

憑直覺論,大家可能有五花八門的選擇。但資深軟件工程師則有明顯偏好,選擇的不是2就是3,我個人則偏好3,因為意思上簡 潔明確。 其實這三個都是Javascript處理非同步(Asynchronous Code)的方法,第一個例子最古老,第二個例子較新,第三個例子則是新近才加進標準。
IT小狗 2018-12-24 19:39:37
(超過字數限制,繼續)

有何分別
如果三個意思上一樣,代表對電腦而言,三個在效能上毫無分別,那為何資深軟件工程師會選擇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


http://manifesto.softwarecraftsmanship.org/


謹以此四句,送給一直堅持寫好代碼的軟件工程師,共勉之


__________________________________________________________

文章出處簡介:

Tecky Academy
由本地人創辦的香港微學位 coding bootcamp,參照美國矽谷模式,一心改變 HK NO IT 的行業境況,致力培訓有質素的 developers。有意入行的巴絲們,可於三個月內由零成為專業的開發者,一次過學會 Git/Gitlab, HTML, CSS, JavaScript, TypeScript, Node.js, Express, Jest, Socket.io, PostgreSQL, AWS EC2/S3/Cloudfront/Route 53, Gitlab CI, React, Redux, Tensorflow 等等⋯⋯ 絕對唔係求其做下網站,禁兩下又咩網絡營銷,我地全部打真章,仲有教埋 Algorithm 同 Theories!

高抬各巴絲貴手 like/follow 我地嘅 Facebook: http://bit.ly/2BPcSmB
有咩問題可以 tg 小弟: https://t.me/itdogltd
或入黎我哋個群 https://t.me/tecky_hub

麥斯 2018-12-24 19:50:02
樓主單身?
IT小狗 2018-12-24 19:51:44
唔係
不過平日太多其他活動,得呢幾日聖誕節最得閒試下拍片
麥斯 2018-12-24 20:19:02
女朋友唔嘈?
IT小狗 2018-12-24 21:41:03
食咗飯
開工now
手一黏便緊(UTC+9 2018-12-24 21:46:58
Apple個bug係因為code merge 而唔係因爲漏花括號......

喇 雖然我唔中意你地係到賣廣告 但係呢個放埋一邊唔講住
可唔可以首先你搵次係無明顯錯誤...
IT小狗 2018-12-24 21:52:34
或者係話有花括號的話,呢個 merge 錯嘅情況唔會發生

原 merge:
https://www.theguardian.com/technology/2014/feb/25/apples-ssl-iphone-vulnerability-how-did-it-happen-and-what-next
IT小狗 2018-12-24 21:53:37
另一篇文章討論花括號喺呢個 Apple goto fail bug 嘅分析

https://embeddedgurus.com/barr-code/2014/03/apples-gotofail-ssl-security-bug-was-easily-preventable/
手一黏便緊(UTC+9 2018-12-24 21:58:24
個個if本身就係單行if.....
人生書家 2018-12-24 21:58:50
Apple goto fail bug would have been caught by auto code formatter and proper code review. It is misleading because of indentation and auto formatter would force it back to "proper" indentation
IT小狗 2018-12-24 22:01:35
我知道本身係一行 if

我意思係,如果用花括號,呢個 merge bug 唔會發生。而喺好多 best practices 黎講,無論幾時都用花括號,係一個好做法

另外一位講返話 auto code formatter and proper code review 都一樣

當然喺 CI/CD 加埋 linter 就仲好

呢篇文都係嗰句,俾新手睇,我可以下次淨係為呢件事寫一篇就夠
手一黏便緊(UTC+9 2018-12-24 22:06:19
搞清楚 呢個問題既核心 係merge唔仔細導致重複語句
呢個specific case 加花括號會令duplicate無效 唔代表所有case都係咁
簡單講 如果個句係i++咁 你個花括號已經解決唔到問題

成個bug既重點係merge同code review唔仔細
IT小狗 2018-12-24 22:12:26
一個問㼵可以有好多解決方法
而一個方法亦唔會解決所有問題

呢個 case 例如可以話 compiler 應該將 dead code 較到 error 級別同樣解決到,咁呢個係咪又係問題核心?

我地只係提出一個問題根源,並唔係絕對。而且蘋果亦無一個官方講法,我貼頭先嘅 links 你都見到各家有各家看法。

我同意你講 merge & code review 都係可以根治問題
Take it easy bro
手一黏便緊(UTC+9 2018-12-24 22:26:23
1. 你認唔認同呢個bug既general case係
if (...)
    statement;

merge 有問題變做
if (...)
    statement;
    statement;


2. 你認唔認同 如果statement係i++ 咁你加花括號之後 仍然係有bug

3. 我唔知你對bug既take it easy take到咩程度
我做緊個到呢 一個bug係幾百萬港紙上落
呢啲錢銀事小
如果港鐵訊號系統 機場空管系統 之類有bug係幾百條人命上落
我對code既質量就係揸咁緊 因為真係幾百條人命上落 我到而家都對我既專業道德水平覺得好戰戰兢兢
因為工程唔係講笑 工程係會死人
IT小狗 2018-12-24 22:38:21
1. 認同

2. 認同

3. Take it easy 係喺連登 be easy ,巴打我一直都認同你嘅講法係無問題喎,你嘅講法岩,唔代表人地講法有誤,你嘅睇法都未必係唯一嘅睇法啫

4.
如果你對 code 嘅質量係揸咁緊,咁單純用 merge bug 解釋就講得通嗎?避免嘅方法就係睇緊啲?

如果重視質量,係唔係應該推廣 best practices,去減少人手嘅錯漏 ?
如果重視質量,係唔係應該推廣 linter,去減少人手嘅錯漏?

如果重視質量,係唔係要有仔細 code review?都係啊!所以我無反駁過你,我一直都同意喎!咁但唔代表我推廣 best practices 同 linter 就係無用喎

Always curly braces
https://medium.com/@hernangarchtrom/we-should-always-use-curly-braces-a9ca2a4ad774
https://stackoverflow.com/questions/2125066/is-it-a-bad-practice-to-use-an-if-statement-without-curly-braces

Always linter
https://medium.com/dailyjs/why-you-should-always-use-a-linter-and-or-pretty-formatter-bb5471115a76
手一黏便緊(UTC+9 2018-12-24 22:46:07
你認同我第一二點 但係你仲講得出加花括號係避免呢個bug既方法

加花括號作為coding standard可以係好事 但係根據第一二點 不能避免呢個bug 話呢個bug可以靠加花括號解決 generally係錯因果
IT小狗 2018-12-24 23:06:42
係啊,因為我真係講緊 specific case to apple goto fail bug 丫嘛,咁喺呢度加 curly brace 的確係呢個 case 解決呢個問題嘅其中一個方法喎

我亦都睇唔出你講左咩方法係好 general 解決到,因為「仔細 code review」都會有人手出錯嘅 exceptional case

俾我抖下喇好嗎?我女友等左成晚我都未得閒拍片 總之好感謝巴打你提出「仔細 code review」係咁緊要啊,我錯喇好嗎?呢幾千萬俾返你喇~多謝你啊~聖誕節快樂
…………………… 2018-12-24 23:56:15
Python.
紅帽IT狗 2018-12-25 03:01:59
加curly bracket 呢個情況根本就唔係解決方法,因為第二句goto fail一開始就唔應該出現,對唔應該存在嘅野正確做法就係del咗去,求祈加返個curly bracket只會令段code更加難睇
而且你所講無論點都加curly bracket係best practice都唔一定啱
https://www.kernel.org/doc/html/v4.10/process/coding-style.html
個篇分析裡面講第二個rule never use goto就更加搞笑,根本好多時寫c做error handling用goto最易明最直接
goto呢條教條化真係好on9
ygIKYOHR9gnGmD9Y 2018-12-25 14:14:41
bbbdddppp 2018-12-25 21:25:55
又”又’
講乜鬼software engineering
奧利佛 2018-12-26 03:01:31
仲以為係講乜寫法
用緊唔同syntax 點比
Callback hell =>
Es6 promise =>
es7 async await
係時代進步,係syntax 轉左
唔關個programmer 本身既lv 事

你呢d 野呃下新手就得
寫靚code 係講套practice 唔係syntax
最簡單,第一步,改個variable 名 function 人地一望就知係做緊乜
吹水台自選台熱 門最 新手機台時事台政事台World體育台娛樂台動漫台Apps台遊戲台影視台講故台健康台感情台家庭台潮流台美容台上班台財經台房屋台飲食台旅遊台學術台校園台汽車台音樂台創意台硬件台電器台攝影台玩具台寵物台軟件台活動台電訊台直播台站務台黑 洞