Software Engineering: A Practical Approach Luba Tang CEO & Founder of Skymizer Inc. Together, we make difference
About Me – Luba Tang 唐文力 Luba Tang BS., CS department, NTHU, Taiwan MS., CS department, NTHU, Taiwan Ph.D Candidate, CS department, NTHU, Taiwan Architect of GYM iterative compiler, Marvell Processor R&D Dept. the most efficient iterative compiler in the world Architect of MCLinker, MediaTek CTO/CIT Dept. the fast, smallest and the first modular linker in the world Adapted in Android Native Development Kit Co-founder and organizer of Hsinchu Code Serfs Meeting. CEO and Founder of Skymizer Inc. (臺灣發展軟體科技) 唐文力 Luba Tang CEO & Founder of Skymizer Inc. Compiler and Linker/Electronic System Level Design
Outline 軟體開發流程 進入職場前的準備 唐文力 Luba Tang CEO & Founder of Skymizer Inc. Compiler and Linker/Electronic System Level Design
SW is more costly than HW In recent 5 years, software is 3 times costly than hardware Software aspects of IC design can now account for 80% or more of embedded systems development cost
Embedded System Suffers from Design Gap
Challenges in Modern Embedded Software Implement a large, various and variant embedded system Shrinking time-to-market for short life cycle of a product 10~15 months for releasing 6~12 months for being on the shelf Changing requirement x2 new devices per 10 months Coordinate with more than 6 teams coming from different backgrounds Heavy workload 250 K Line of code for self product 1M Line of code in total system High reliability
Esp. Software Engineering Everything about DESIGN becomes important Esp. Software Engineering
我的軟體開發流程 對我而言是真實的 混合多種性質 不是最快的 我不研究軟體工程 自己用過也教過,經過實驗與取捨 曾有學弟改變流程,在更短時間內做完更多的事
軟體開發的過程 挑對手 – 在專案開始之前 初手 – 規格與設計 中盤策略 – 撰碼與測試 末盤策略 – 交貨拿錢 組織行為 專案時間表 人力配置 初手 – 規格與設計 組織與工作規劃 需求分析 架構設計 中盤策略 – 撰碼與測試 Unit-test 的策略 Dependency Checking Revision control 末盤策略 – 交貨拿錢 Software versioning Release engineering
軟體開發機構的成長過程 高 客戶的要求 低 低 高 問題的要求 渾然不知 (Oblivious) 變化無常 (Variable) 我們都不知道我們正尋着一個過程做事 變化無常 (Variable) 我們全憑當時的感覺做事 超級程式設計師的形象 照章行事 (Routine) 我們凡事皆依造工作慣例,除非我們陷入恐慌 超級技術負責人的形象 把穩方向 (Steering) 我們會選擇結果較好的工作慣例來行事 有能力的經理 防範未然 (Anticipating) 我們會參造過往的經驗制定出一套工作慣例 全面關照 (Congruent) 人人時時刻刻都會參與改善工作 高 P5 P4 客戶的要求 P3 P2 P1 低 P0 低 高 問題的要求
模式一:變化無常型 仰賴超級程式設計師 模式 不同程式設計師的能力可達20:1 甚至更高的差別 問題的複雜度往往呈現指數成長,就專案成功的機率而言,超級程式設計師並非決定性的關鍵 模式 『告訴我們你想要的是什麼(而且不要改變你的心意)』 『提供我們一些資源(而且只要開口,你就會不停地提供)』 『不要再來煩我們(消除所有隨機事件發生的可能性)』 需求 資源 軟體開發系統 軟體 隨機事件 其它輸出
模式二:造章行事型 仰賴超級技術負責人 模式 問題複雜度過高,承認超級程式設計師並非決定性的關鍵 控制者還無法直接取得開發系統內部狀態 『我將會使那些程式設計師,管他張三李四,皆能善盡責任』 『我會僱用交大的學生,訓練他們變聰明』 『我會開除清大的學生,讓其他人工作更賣力』 控制者 改變 需求 (改變) 資源 軟體 軟體開發系統 隨機事件 其它輸出
模式三:把穩方向型 模型 預期狀態的樣貌 觀察實際的能力 比較預期與實際差異的能力 對系統採取行動,使得實際狀況更接近預期的能力 需求 控制者 改變 需求 資源 軟體 軟體開發系統 隨機事件 其它輸出
挑選適合的開發模式 模式沒有對與錯 針對客戶與問題的要求來選擇模式,而非由資源來選擇模式 不計資源的話,永遠可以以集成法來進行 就相同的問題而言,上述模式的成功機率其實大同小異 針對客戶與問題的要求來選擇模式,而非由資源來選擇模式 不計資源的話,永遠可以以集成法來進行 高 P5 P4 客戶的要求 P3 P2 P1 低 P0 低 高 問題的要求
專案開發的時間表 (1/2) 總時間 個別時間 通常 10~12個月必須第一次release 需求 設計 撰碼 測試 3/5~2/3 的時間 3/5~2/3 的時間 6個月 1/10~1/6 的時間 1個月 1/3~1/4 的時間 2.5個月 預留 1/10的時間 1個月
專案開發的時間表 (2/2) 總時間 個別時間 第二次release之後,每隔N週要release一次 Linux kernel中,N=8~12 個別時間 24 hours Release 1 Release 2 Release 3 Release 4 依專案慣性 4~8週
專案開發的人力需求 總人力 個別人力 通常每10K需要2~3個人 閒置人力? 建立開發環境 讀相關規格 撰碼 測試 設計 維護 需求 通常1~3人 依子專案個數 約莫3~5人 依獨立元件個數 從 5~30人都可能 和設計人數相仿
軟體開發的過程 挑對手 – 在專案開始之前 初手 – 規格與設計 中盤策略 – 撰碼與測試 末盤策略 – 交貨拿錢 組織行為 專案時間表 人力配置 初手 – 規格與設計 組織與工作規劃 需求分析 架構設計 中盤策略 – 撰碼與測試 Unit-test 的策略 Dependency Checking Revision control 末盤策略 – 交貨拿錢 Software versioning Release engineering
初手 – 撰寫規格書 不要產生沒必要的文件 如果溝通會耗掉某些人大部分的時間,就必須撰寫規格書 負責溝通的人,寫對應的章節 規格書中的章節 Project Vision Organization Requirement Basic Design Milestone Design
Project Vision 內容 例子 我們要做甚麼? 為什麼要做這件事? 投資報酬 失敗風險 將simulation instruction相關資訊放入SQL資料庫中,以利下列操作 方便閱讀simulation instruction內容 自動生成simulation instruction的header與implementation files 方便修改、新增simulation instruction的內容
人力組織 – Marlin Hills’ programming team 優點: 結構完整、歷經二十多年考驗 缺點: 人員流動風險高、人員幅度較大 可考慮以Mills Chief Programmer Team為基礎,將多個工作集中到少數人身上
Example
Pair Programming 優點 執行方法 降低溝通成本 自然導入unit test 減少trivial fault 提升programmer素質 不需要額外的peer review 執行方法 每個人是code owner,同時也是他人的code tester 兩人為一組,每1~2週輪換一次 在實驗室當中,pair programming的效率比single programming高
軟體開發的過程 挑對手 – 在專案開始之前 初手 – 規格與設計 中盤策略 – 撰碼與測試 末盤策略 – 交貨拿錢 組織行為 專案時間表 人力配置 初手 – 規格與設計 組織與工作規劃 需求分析 架構設計 中盤策略 – 撰碼與測試 Unit-test 的策略 Dependency Checking Revision control 末盤策略 – 交貨拿錢 Software versioning Release engineering
需求分析 使用情境設定 (必要) 使用者與事件列表(非必要) 畫圖,然後說故事 列出使用情境中的所有 主詞 => 物件 動詞 => 函式或關係 形容詞/副詞 => 參數 受詞 => 參數
UML Scenario
簡單的情境設定的例子 – 看圖說故事 學生 作業 報告 程式 勞動 林教授 寫 出 可能是 是
說故事的重點 優秀的工程師,就是懂得溝通的工程師 溝通系統中四大關係 生成 繼承 使用 毀滅 需求分析重點就是在搞清楚四大關係 學生 林教授 作業 報告 程式 勞動 林教授 寫 出 可能是 是 需求分析重點就是在搞清楚四大關係 一般動詞 使用關係 Be 動詞 繼承關係
軟體開發的過程 挑對手 – 在專案開始之前 初手 – 規格與設計 中盤策略 – 撰碼與測試 末盤策略 – 交貨拿錢 組織行為 專案時間表 人力配置 初手 – 規格與設計 組織與工作規劃 需求分析 架構設計 中盤策略 – 撰碼與測試 Unit-test 的策略 Dependency Checking Revision control 末盤策略 – 交貨拿錢 Software versioning Release engineering
架構設計重點就是在搞清楚元件之間的相依性 專案的三大本質 單一進入點 (Single Entry) 相依於其它專案 (Dependency) 不可能遞迴相依 (Acyclic) 單一進入點 有相依性 程式或 函式庫 不能遞迴相依 架構設計重點就是在搞清楚元件之間的相依性 Qt math stdlib Pthread
架構設計的步驟 從最粗糙到最精細 Software Stack (必要) CRC (非必要) Work-Breakdown-Structure (必要) UML Object diagram (必要)
Software Stack (必要) 定義有哪些元件 元件之間概念上的分層 可以後做的元件 需要比較多的測試 基本 須要先做的元件 只需要基本測試
CRC - Class-Responsibility Card (非必要) 目的 確保生成關係的可行性 買空白名片卡,正面寫上物件名稱,背面寫上物件的用途 不同元件的設計者,持有不同的CRC卡 找一天大家一起打個牌 玩法 從main開始,main有用到的物件就疊在main上面 如果物件A用到物件B,就將B放到A上面,直到所有牌都放完 如果牌放完,而沒有缺牌,則確保架構是 Acyclic的 stdlib main Qt math pthread
Work-Breakdown Structure (非必要) 顧名思義,將工作不斷分割,依相依性排好 在規劃初期,通常只會分割到第二階 實作階段,會分割到第三階,但是不是必要 不在software stack上的工作,記得也要列進來
Example Level 2 dependency graph Level 3 dependency graph
軟體開發的過程 挑對手 – 在專案開始之前 初手 – 規格與設計 中盤策略 – 撰碼與測試 末盤策略 – 交貨拿錢 組織行為 專案時間表 人力配置 初手 – 規格與設計 組織與工作規劃 需求分析 架構設計 中盤策略 – 撰碼與測試 Dependency Checking Revision control Unit-test 的策略 末盤策略 – 交貨拿錢 Software versioning Release engineering
必然會遇到的問題 只要程式有人用 你就會繼續開發,讓他更好用 客戶或許會更新程式,或許不會 客戶會面臨 版本太新 版本太舊
Too Old Problem Host Dependant Too Old Problem 提供函式庫的專案 使用函式庫的程式 需要 version 3 Dependant Host Version 2
Too New Problem Host所提供的函式庫太新 需要 version 3 改成 version 6,可能嗎? Dependant
解決方案 確認問題 利用Dependency Checker(如 ./configure script),在編譯之前檢查版本,以確保版本吻合 解決問題 利用 Source Code Manager (如 SVN, CVS, Perforce),返回到適合的版本
Dependency Checking 最常見 dependency checker 為 ./configure script Dependency checker 產生器有 Open Source 的 Autoconf Cmake Dependency checker 會 Top-down 的檢查函式庫版本以及系統環境 程式或 函式庫 stdlib Qt math Is v6? Is v2? Is v3?
Global Version 解決太舊的問題 將所有的project設定一個版次號碼 規定所有的 dependant的版次必須要小於等於host的版次 最上層的dependant為global version Global version Main V2 Qt V5 Math V3 Stdlib V6 Pthread V7
Local Version 解決太新的問題 這是從少數客戶擴張到多數客戶的關鍵 需要 version 3 開分支 (branch) Dependant Host V3 Host V3-1 Host V3-2 合併 (merge) 版次跳躍 Host V4 Host V5 Host V6
Version Threads 2.3-1 2.3-2 Local Versions 2.3 2.4-1 2.4 2.5 2.6-1 2.6 2.7 Global Versions
軟體開發的過程 挑對手 – 在專案開始之前 初手 – 規格與設計 中盤策略 – 撰碼與測試 末盤策略 – 交貨拿錢 組織行為 專案時間表 人力配置 初手 – 規格與設計 組織與工作規劃 需求分析 架構設計 中盤策略 – 撰碼與測試 Dependency Checking Revision control Unit-test 的策略 末盤策略 – 交貨拿錢 Software versioning Release engineering
Software Versioning 功用 對外做為看板,告知客戶目前專案的stage of life cycle 對內做為進度管理,得知目前release status Point release Major release
2 5 1 4 3 Stage of Life Cycle Beta GA Alpha RTM Pre-alpha RC In House Customer testing In House GA 5 Success in Market Alpha 1 Internal testing RTM 4 Release to Market Pre-alpha developing RC 3 Release Candidate In Market
Release Status Point release Major release 為了bug-fix經常且快速的release 為了new feature告知客戶應做更新 2.6 2.6.1 2.6.1 2.7 2.6.1 major 2.8 2.6.1 2.6.1 2.9 point
Case Study 1 – DirectFB Format Major release Point release [Major].[Minor].[Micro].[IF_Age].[Bin_Age] Major release [Major].[Minor] Point release [Micro] Release Status [IF Age].[Bin Age] Release的規則不固定,隨喜好進版。 進版規則 Existing interface changed => IF Age = 0 Binary interface changed => Bin Age = 0 Bug-fixed or new feature => Micro += 1
Case Study 2 – Linux Kernel 2.6.11+ Format [Major].[Patch Level].[Minor].[Bug-fixed] 改進以往 release方式(2.odd/2.even),利用多個source tree來增加patch進入mainline的效率 Source tree Versioning Meaning Mainline 2.6.X/2.6.X-rcY Developing source tree Stable 2.6.X.Y For bug-fix Legacy 2.6.X.Y-1 1 version old stable Mm Integration tree, for new feature Ck/Rt Improve performance
Linux kernel version threads 2.6.11.1 2.6.11.2 stable 2.6.11 2.6.12.1 2.6.12 2.6.13 2.6.14.1 2.6.14 2.6.15 MM Mainline
Proposed Release Engineering 3.1.1 3.1.2 stable 3.1 3.2.1 3.2 3.3 3.4.1 3.4 3.5 Release Stable Developing
軟體開發的過程 挑對手 – 在專案開始之前 初手 – 規格與設計 中盤策略 – 撰碼與測試 末盤策略 – 交貨拿錢 組織行為 專案時間表 人力配置 初手 – 規格與設計 組織與工作規劃 需求分析 架構設計 中盤策略 – 撰碼與測試 Dependency Checking Revision control Unit-test 的策略 末盤策略 – 交貨拿錢 Software versioning Release engineering
在學校寫程式 vs. 在企業寫程式 (1) 其實花在寫程式的時間,只有 30%~60% Programmer vs. Software Engineer 在「真實世界」需要的不只是一個 programmer,而是 software engineer。 大多數 CS 畢業新鮮人不是不懂怎麼寫程式,而是不知道寫程式以外的事 寫程式以外的事 需求分析 架構設計 測試計劃 與不同背景的人合作 有效溝通 其實花在寫程式的時間,只有 30%~60%
在學校寫程式 vs. 在企業寫程式 (2) 在學校有「明確的需求」 在企業「需求不明確」 問題被分割過 有明確的工具 有衡量的標準 定義問題,是最重要的工作 需要評估所有可能使用的工具 為問題製定衡量的標準
在學校寫程式 vs. 在企業寫程式 (3) 在學校目的是「學習」 在企業目的是「生產力」 大量閱讀論文,學習定義問題的能力 在學校階段,請像海綿般的飢渴的學習 這是一生最棒的學習機會 大量閱讀論文,學習定義問題的能力 大量簡報,學習表達的能力 儘量組團寫 code,學習合作的能力 在企業目的是「生產力」 沒有時間可以學習,只能「以戰養戰」 過去的基礎練習,在長時間裡會逐漸顯現出差異 實力決定一切 頂尖工程師是稀有財,其價格往往是普通工程師的五到十倍
成為頂尖工程師的條件 熱情 頂尖 機會 價值
成為頂尖工程師的方法 尋找改變世界的熱情 飢渴的學習,尋找改變世界的機會 在機會當中創立價值,每次都要進步一點 有什麼事情,值得你不眠不休,都要去達成 如何才能讓你和你愛的人真正的快樂 這些目標,是否能夠用軟體來達成 飢渴的學習,尋找改變世界的機會 眼光需要學習 大量閱讀論文,是最省力氣的做法之一 從論文與教科書當中,學會問題的分類 建立好的分類方式,就是培養好的眼光 在機會當中創立價值,每次都要進步一點 每次寫程式的目標,就是寫出「這輩子目前為止最好的程式」 「以戰養戰」是最有效率的戰鬥方式
一萬小時 vs 四十小時 知其何以立 扎實的基礎功,才是建立 domain know why 的捷徑 Domain know what 只要四十小時 了解一個領域當中的常態,只需要適當的經驗 大多數的人都在這裡停滯不前 「十年經驗 = 十次一年經驗」 知其然 Domain know how 需要一萬小時 知其所以然 精熟一個領域,需要超過一萬小時的熟悉時間 人人都可以花個四五年成為「資深工程師」 每天,每月,每年都多進步一點點 頂尖對決,是 domain know why 知其何以立 扎實的基礎功,才是建立 domain know why 的捷徑
如何準備 interview 面試最重要的技巧 展現能「面對不確定性」的能力 能夠很快樂,很驕傲的說自己曾經做過什麼事情 不知道就說不知道,不要硬凹 不會怎麼辦?就學啊! 教學相長
Skymizer Optimize in the Sky Together, we make difference