2020年3月30日 星期一

Changelog - 軟體工程師的修鍊之道


"The Pragmatic Programmer" 在 1999 年第一次出版, 事隔20年後出了第二版, 主要是更新一些例子, 書中一些建議的方法已經過時, 需要淘汰; 有些則是作者找到更好的方法來闡述想法; 過了 20 年, 業界也有些新的問題, 例如cocourency, security的問題 需要面對.

40年前的"人月神話"一書裡面提到的技術現在都已不復存在, 但它所講的問題, 擺在今日還是存在. "The Pragmatic Programmer"第二版裡有75%的內容都更新了, 但不變的是, 依舊在討論怎麼處理人的問題. 很多章節的主題雖然看似跟人無關, 例如"naming", 但它其實還是關於"人", 怎麼命名影響人怎麼去分類, 怎麼去思考.

現在的車子的複雜度已經遠遠超過我們的理解, 但我們不會擔心, 因為它裡面的每個元件都非常的成熟. 但軟體界裡面的元件還沒有這樣的成熟度, 或是我們都還沒有等到它成熟就丟棄了. 業界裡有一個笑話: "今天是星期三, 這代表又有 47 個新的 javascript framework 出現了". 大家總是覺得新的比較好, 自己做的比較好. 大家為了解決一個問題, 而新寫一個 library 或 framework, 它的確解決了新的問題, 但它是否有解決舊的問題, 沒有人關心. 甚至沒人知道有什麼舊的問題被解決過, 結果就是我們一直在同樣的一堆問題裡打轉. 如果一個人要寫作, 他首先要閱讀大量前人的作品, 但軟體界中, 很少工程師會看前人的 code (除非自己要去修改, 不得不看), 這跟"Why Smart Engineers Write Bad Code"的作者想法一樣, 我們應該去讀讀大型專案的 code, 了解過去的架構設計理念, 才有可能融會貫通.

訪問的最後, 主持人請兩位作者挑出他們心中最有用的tip, Dave 挑了一個 "It's your life": 很多工程師都像自動導航的車子, 他們接下工作, 使用公司指定的程式語言, 邊抱怨邊做, 直到再也做不下去為止. 他沒有去思考是不是有更好的做法, 不以自己寫的 code 為傲, 當然也不想為自己的產品負責, 所以覺得測試不重要, 沒有必要重構, 但這是你的人生, 嘗試做出改變吧. Andy 挑的是 "Don’t outrun your headlights": 不要想要一步登天, 就像攀岩, 永遠是三點不動, 一點動, 這也是 Agile 的精神, 做一點, 看看產出, 收集回饋. 軟體工程師普遍沒有"謙遜"的心理, 這是個年輕人意氣風發的產業, 但在做了工程師十幾年後, 我越發覺得心態遠比技術還要重要得多.

Reference Source:
https://changelog.com/podcast/352

2020年3月25日 星期三

Changelog - Clean Agile


前言

現在這個世界什麼都離不開軟體, 開的車子裡面有軟體, 用的家電有軟體, 電腦, 手機, 手錶...任何你想得到的事, 軟體工程師因此成為成長最迅速的一個群體. 然而, 這麼多新人加入, 他們都很年輕, 沒有經驗, 帶領他們的人可能也只多了幾年經驗, 沒有太多東西可以傳承, 仔細想想, 整個社會都深度依賴軟體, 但大家對於開發軟體流程卻莫衷一是, 是件多麼危險的事. 現在軟體界, 大家都在講 Agile 流程, 但每家公司執行 Agile 的方式似乎都不一樣, 那麼, 究竟 Agile 是什麼?


Waterfall History

1970年代, 當軟體專案越來越大, 開始有人討論軟體流程. 一篇論文"Managing large-scale software systems"提出了 Waterfall 流程: Analysis, Design, Development and Test, 雖然原始作者在論文裡面原意是要批評 Waterfall 流程在現實中如何不可行, 但卻意外的大受歡迎, 可能很多人沒有讀完論文, 只看了論文開頭的第一張圖片吧 XD

Agile History

Waterfall 流程制霸了軟體界30年, 開始有一群人提出新的想法, "Agile" 浮出檯面. 關於 Agile 的基本想法, 就是以很短的work cycle產出, 並且驗證, 收集回饋. 一開始的 Agile 流程核心規範的是技術紀律: test-driven development, pair programming, simple design, refactoring, 確保每次cycle的產出都是有效的. 不過在2003年有了 certified scrum master class 後, Agile 開始變得越來越 PM 相關. 為此 "Clean Code"的作者寫了這本"Clean Agile", 試圖讓工程師重拾 Agile 的初心.

這真的是Agile嗎? 

當每個人都宣稱正在使用 Agile 時, 你該怎麼判斷"這真的是 Agile "嗎? 試著用以下三點判斷:

  • 每個cycle結束時, 我們是否真的有能夠上線的產出? 能夠上線代表有經過測試, 有文件, 沒有重大問題.
  • 在work cycle裡, 我們是否與stakeholder密切溝通? Agile 縮短 work cycle 是為了即早發現問題, 解決問題, 調整方向, 如果做決定的人不在這個流程裡, 那麼就違背了 Agile 的精神.
  • 我們是否有寫測試? 在 Agile 流程裡, 就是反覆的測試與重構, 才有辦法頻繁的出版, 並且確定每次出版不會改了這裡壞了那裡.

總結


Agile 的核心不在 daily stands-up meeting, 不在 user point, 這些都是工具而已. 核心在於紀律與共識, 在 Agile 提出二十年後, 讓我們回歸初衷.

Reference source:

https://changelog.com/podcast/367
https://www.youtube.com/watch?v=T4Td2vgrgsM

2020年3月19日 星期四

Changelog - 為什麼工程師會寫爛 code ?


前言

這是一個很有趣的現象: 工程師並不真的知道自己寫的code到底好不好. 大部份工作的時候, 我們加入一個大型的專案, 新加一點功能, 修正一些 bug. 專案裡前人的 code, 如果我們看不懂, 要嘛嫌前人寫得差, 想要全部翻掉重來, 要嘛不敢改, 選擇繞道. 如果說學界與業界有鴻溝, 最大的差別就在這: 在學校時, 我們只有機會寫個 2~3 人的專案, 大家都可以面對面討論, 所有的專案包括 compiler 都是從頭開始, code 的原始作者都在, 寫不寫文件一點都不重要. 但當你畢業後進入業界. 世界就變得完全不一樣.

當你是一個土木工程師時, 人們可以期待你會有造橋或是蓋房子的基本知識, 但當你說你是一個軟體工程師時, 人們不確定要期待你會什麼. . 這也讓 hiring process 變得很沒效率, 因為他只能問一些很愚蠢的演算法考題. 並且還是無法確認你是否適合這份工作. 當你面試一個醫生的時候, 你不會問他你是否會縫這個傷口, 但為什麼需要問一個軟體工程師是否會寫merge sort?

學界應該做什麼改變?

學校應該開一些 open source 的課程, 讓學生直接去讀大型的專案, 例如 apache, linux, 看看前人怎麼寫的, 哪些是好的, 為什麼你覺得好? 在討論的過程中, 學生會建立起一些 coding 準則的共識. 同時試著改一些 code, 即使不 commit, 也可以互相 code review, 看看別人怎麼寫.

啟動一些 open discussion, 讓學生用不同的方式/不同的語言/不同的限制去寫同樣的功能, 並且討論哪種方式比較好, 也許沒有誰優誰劣, 那也可以讓學生了解到這世界不是只有一種方式來做.

多一些直接在課堂上寫 code 的課程, 有問題大家可以互相討論, 而不是各自窩在自己的房間寫課後作業. 上班時, 跟別人討論是無可避免的.

業界應該做什麼改變?

很多軟體工程師都不曾參加任何學界的研討會, 或是成為任何一個組織 (例如ACM) 的會員, . 這是一個奇怪的現象. 土木工程師會成為 ACSE 的會員, 他們可以看到最新的出版, 但在軟體界卻很少見. 學界與業界的斷層也許就從這裡開始產生.

學界的某個研究可能突然間被業界的哪個人大肆宣揚, 業界的人根本不知道原始的研究, 應用範圍, 就生硬的套用, 例如scrum, law of Demeter. 可能適用, 也可能不適用, 沒有人去探究, 業界的人彷彿只是在追求一些"熱門字".

總結

我們還是沒有辦法回答什麼樣的code是好的, 什麼樣的code是壞的. 寫code不像造橋, 有絕對的標準可以遵守, 例如承重多少, 水泥的比例就應該是多少. 我們只能去追求寫一些有價值的code, 希望它們 30 年後還有機會為人所用.

Reference Source:
https://changelog.com/podcast/339
https://medium.com/@mitpress/why-smart-engineers-write-bad-code-7b8201fb040a

2020年3月10日 星期二

Changelog - Shaping, Betting, and Building


前言

很多公司都使用敏捷開發, "Let's learn as we go. Let's adapt as we go", 這個精神是好的, 但不應該變成沒有計劃, 沒有方向. 很多產品經理變成了專案經理, 他們對產品沒有自己的想法, 只是把所有 backlog 裡的 task 都按 sprint 排進去, 結果一個專案彷彿可以永無止境的做下去, 或是時間到就上線, 不管三七二十一. 我們應該問問自己"最終我們想要完成什麼?", 而不只是關心兩個星期後要完成什麼.

這不是說要回到從前的 waterfall 開發模式, Basecamp 的策略長 Ryan Singer 為大家介紹目前Basecamp 採取的開發模式: Shaping, Betting, and Building. 這個開發模式如同 Agile, 有固定的timebox, 在 Basecamp 內 timebox 是六個禮拜. 不同於 Agile 的是, 他們並不是把四個月的產品切成六個禮拜為單位, 逐步完成它, 而是六個禮拜要完成一個可以發布的產品, 所以設定了六個禮拜, 而不是兩個禮拜. 根據他們的團隊大小與產品規模, 六個禮拜的工作量可以完成一些值得發布的功能, 六個禮拜的 timebox 限制會改變他們的設計與實作方法. 六個禮拜後是兩個禮拜的"cool down", 用來解 bug, 同時討論接下來要做什麼.

Shaping

六個禮拜稱為"Cycle", 是讓工程師與設計師好好發揮, 不能被打斷的時間, 為了要讓這時間能夠有效被使用, 會有準備階段, 稱為"Shaping". 提出想法或客戶需求的人需要做功課, 研究實用性, 找一些 RD 討論技術可行性. 當準備妥當後, 就可以把提案帶到"Betting Table", 進入"Betting"階段.

Betting

Betting 通常發生在兩個禮拜"cool down"時, 大家討論接下來要做什麼. 在這個階段, 大家可以自由發表提案, 提案內容可能包括:"我看到了這個機會/問題, 我提出某某做法. 我驗證過哪些部份可行, 哪些部份還未知...". 這個階段是在決定未來的六個禮拜要花在哪裡, 賭注就是六個禮拜的時間人力成本. 在賭桌上, 我們都知道, 不能一味的加注, 輸了就下桌. 如果六個禮拜過去, 我們啥都沒有完成, 就宣告這個提案死掉了, 這是風險管理. 在我們搞清楚為什麼交付不出來之前, 不應該再加人加時間. 如果有人覺得想法夠有價值, 他可以再讓它進入"Shaping"階段, 繼續做功課, 打磨它, 有一天可能就回到Betting Table. 當提案被接受後,  就進入"Building"階段.

Building

"Building"階段是指派人到提案, 而不是指派工作, 提案要怎麼完成是這些人去思考的. 這個階段的精神與 Agile 很像. 將提案垂直切割, 真正做前後端整合, 盡早向外面的人展示你完成了什麼, 而不是把每個元件都先建出來, 最後才做組裝, 這就是"Getting Real". 垂直切割的提案細項稱為"Scope", 它比 task 要大, 通常是3~4天的工作量, 在 Building 的過程中, Scope 會漸漸長出來, 因為目標是六個禮拜交付, 團隊成員必須來回討論哪些 Scope 是 nice-to-have, 哪些是 must-have, 在過程中強迫對話與給予回饋, 而不是大家各自領回 task, 埋頭苦幹.

有時候六個禮拜結束, 你會說"我只需要再多一個禮拜!", 那我們就需要看看剩下的工作是什麼. 工作有分上坡面與下坡面. 上坡面是你看到山, 但你不確定要怎麼走. 例如你手上有些 geodata, 你也知道有 geodata library, 但你沒有使用過這個 library, 還有很多不確定性. 而下坡面是指你已經知道路在哪裡了, 只是需要時間走完它. 舉例來講你要煮晚餐, 如果你已經知道你要煮義大利麵, 而且你手上有食譜, 你需要的只是採買與按食譜做出來, 你有100%的信心可以完成, 那麼就值得延長時間.

Reference source:

2020年3月9日 星期一

Changelog - Reproducible builds


現在有越來越多的套件管理軟體, 例如linux上的 apt , mac 上的 brew , 讓使用者可以輕易的安裝 pre-compiled 的套件, 但你真的知道你裝了什麼到電腦裡嗎? 想像你開發了一個 App , 使用了第三方套件, 而這個套件裡面有個後門, 會把Ads的金鑰換成套件開發者的金鑰, 結果你渾然不覺的把 App 放上 store,  以為會有廣告收入, 結果全都入了第三方的口袋; 或是想像你安裝了一個 bitcoin wallet , 結果它居然把錢轉到自己的帳號下; 許許多多的安全性問題, 都在我們選擇便利之後忽視.

"Reproducible build"是 open source community 想要推行的一個觀念: 一份 source code 應該要能產生一模一樣的 binary, 不論硬體, 不論 OS, 不論 timezone, 不論使用者權限, 不論 code path...任何想得到的差異, 都不應該影響最後產生的 binary . 如果一份套件的 source code , 可以經過 20 甚至 30 個 rebuilders 來驗證最後的 binary 都相同, 它就能夠保證一定程度的安全性.

這個觀念也可以落實到 code development, 一份好的 source code 裡不應該存在跟環境相依的變因, 我們應該不時會聽到工程師抓頭喃喃自語:"在我電腦上都執行得好好的呀!" 這就透露了潛在問題. 在我們電腦上可以 build 得起來, 在另一個人的電腦上也應該可以 build 出一模一樣的 binary. Google 很認真的執行此觀念, 為的是節省 compile code 的成本. 如果能保證一樣的 code會得到一樣的 binary, 那麼就只需要 compile code 有更動的 library , 省下的時間與金錢相當驚人.

reference source: