1. 程式人生 > 其它 >Alpha 階段事後分析

Alpha 階段事後分析

設想和目標

  1. 我們的軟體要解決什麼問題?是否定義得很清楚?是否對典型使用者和典型場景有清晰的描述?

    當前計算機學院的核心專業課程《作業系統》的理論部分和實驗部分建設都趨於成熟,實驗平臺也需要進一步開發完善。實驗的參與者主要包含課程教師、助教和選課學生。這三類使用者分別需要完成班級、許可權管理,實驗、教程管理,課下實驗和課上考試等功能。

    現有的平臺對上述功能的實現尚不完善,各方面實現割裂,分散在不同的站點;各方面資訊展示功能不佳,自動化程度有待提高;使用者體驗不佳。與此同時,校內各類課程平臺的建設日臻完善,為了適配核心專業的課程定位,我們計劃實現一個供教師、助教、學生使用的統一的課程平臺。該平臺能夠一站式滿足三類使用者的主要需求,提供完善的資訊展示機制,自動化程度高,具有良好的使用者體驗。

    我們對平臺中涉及到的相關概念(如 Lab、評測、教程等)、使用者端、功能以及驗收場景有著清晰的定義(見 OSome-平臺概念介紹功能規格說明書)。

    功能規格說明書 中,我們列出了以教師使用者、助教使用者和學生使用者的典型代表,並給出了實驗、考試、班級管理等典型場景。

  2. 我們達到目標了麼(原計劃的功能做到了幾個? 按照原計劃交付時間交付了麼? 原計劃達到的使用者數量達到了麼?)

    目標已經達到。

    原計劃共 12 個功能,包括:

    • 學生端(6 項):首頁通知、評測、進度檢視、使用者登入、個人資訊、建議與反饋
    • 教師端(5 項):使用者管理、教學資訊、公告管理、使用者登入、評測記錄
    • 評測端(1 項):程式碼評測

    以上 12 個功能均已實現。

    5 月 7 日,我們邀請作業系統課程的沃天宇老師,進行長達三小時的視訊會議。我們向沃老師展示了 OSome 平臺的學生平臺、教師平臺,並聽取了沃老師的建議。我們立即對老師反饋的問題進行了修改。最終,於 5 月 9 日晚,向全體作業系統老師和正在上作業系統課程的全體學生髮布。

    截止至 5 月 12 日 17 時(Alpha 階段專案展示前夕),已有 241 人完成登入,共 141 名學生完成提交,提交題目 302 次,總共 API 訪問次數 13024 次。考慮到釋出僅 3 天,且本學期僅有 6 系和 21 系開課,該活躍量已經可以滿足預期。

  3. 和上一個階段相比,團隊軟體工程的質量提高了麼? 在什麼地方有提高,具體提高了多少,如何衡量的?

    本專案為 Alpha 階段,沒有上一個階段。此處僅概述本階段的質量管理。

    • 文件與程式碼規範:

      • 每個倉庫具有 readme,作為完整的開發指南,包含以下幾方面的資訊:
        • 本地開發、構建說明
        • 部署說明
        • 配置說明
        • 依賴說明
      • 使用以下自動化工具檢查程式碼質量,不通過時 CI/CD 失敗:
        • ESLint
        • Prettier
      • API 文件由 swagger 自動生成,省去人工維護的成本。
    • 可傳承性:

      • 程式碼質量
        • 專案程式碼結構性好
        • 層次清晰
        • 識別符號表意清楚,無需註釋
        • 重要概念有 OSome 平臺概念介紹,避免混淆
      • 指導質量
        • 專案均有 readme.md,指導本地開發、測試流程
        • 服務均有 docker-compose.yml 留檔,可以使用同樣的命令啟動所有服務:docker compose up -d
        • 重要機制已形成固化記錄(子站反代、Docker Registry 等),幫助使用
    • 單元測試:

      完成 24 個重要 API 的單元測試,涉及 68 個測試用例,覆蓋率達到 62.6%,共 1874 行程式碼。

    • DevOps:

      • CI/CD 是敏捷開發的關鍵:

        我們為學生前端、教師前端、後端、評測端、評測環境都配置了 Gitlab CI/CD,從而自動進行迴歸測試、構建、部署到伺服器,極大提高了團隊開發效率——除了運維同學外,自動構建、部署的過程對於開發者來說是近乎透明的,開發者只需要知道有一個機制使得開發者每一次 push/merge 都能在伺服器上看到效果,而不關心這個機制的具體實現。

      • Docker 容器技術也是敏捷開發與系統運維的關鍵。容器技術在我們的開發過程中起到了關鍵作用:

        • 我們可以在一個機器上同時執行多個服務且互不衝突。
        • 我們利用 Docker 映象來包裝、釋出分散式評測機,只需在 V-TEST 上執行 docker-compose 即可自動拉取評測機映象,擴充評測結點。
  4. 使用者量, 使用者對重要功能的接受程度和我們事先的預想一致麼? 我們離目標更近了麼?

    使用者量與預想幾乎一致。

    使用者對重要功能的接收程度好。收到的 21 份使用反饋中,21 份均為有效反饋。所有的 21 份反饋均表示“非常滿意”,滿意率達到 100%。

    使用者的滿意度反饋表示 Alpha 階段取得了練好的結果,實現了大部分功能的整合,為 Beta 階段的進一步開發打下了良好的基礎。這也離“我們計劃實現一個供教師、助教、學生使用的統一的課程平臺。該平臺能夠一站式滿足三類使用者的主要需求,提供完善的資訊展示機制,自動化程度高,具有良好的使用者體驗”的目標更進一步。

  5. 有什麼經驗教訓? 如果歷史重來一遍, 我們會做什麼改進?

    • 設計時要即時和老師溝通,瞭解使用者需求,以免重構
    • 開發期間出現了伺服器宕機情況,形成處置文件
    • 要保護好身體,不要再有人倒下了
    • 要即時跟進專案,參與會議,接觸技術棧,避免和專案脫節

計劃

  1. 是否有充足的時間來做計劃?

    是,我們從1月份就開始對需求進行分析。

  2. 團隊在計劃階段是如何解決同事們對於計劃的不同意見的?

    大家首先闡述自己的意見,之後同學們互相討論優勢劣勢,最後由葉焯仁同學統一決定。

  3. 你原計劃的工作是否最後都做完了? 如果有沒做完的,為什麼?

    都做完了,因為我們前期規劃的好。

  4. 有沒有發現你做了一些事後看來沒必要或沒多大價值的事?

    開非常長時間的會,效率太低。

  5. 是否每一項任務都有清楚定義和衡量的交付件?

    並不是所有任務都有清楚的定義。我們的任務是以 Issue 形式定義和衡量的,在介紹任務時一般比較概括,實現時有時還會對任務進行討論。

    交付件來說我們是通過同行評審的方式,在明確實現某個功能之後才能交付。

  6. 是否專案的整個過程都按照計劃進行,專案出了什麼意外?有什麼風險是當時沒有估計到的,為什麼沒有估計到?

    確實出現了意外,有一位同學因為身體原因一段時間無法工作,我們緊急開了會議,將他的任務分配到了所有其他人手裡。確實沒有預料到有同學會因為本學期的課程身體不適,課程的帶來的壓力還是太大了。

  7. 在計劃中有沒有留下緩衝區,緩衝區有作用麼?

    沒有留緩衝區。

  8. 將來的計劃會做什麼修改?

    我們計劃在之後設定緩衝區,比如在週日設定緩衝區,這樣同學們可以調整自己的時間規劃。

    對專案未來計劃做好風險備案,如果出現問題及時處理。

  9. 我們學到了什麼? 如果歷史重來一遍, 我們會做什麼改進?

    我們學習到如何進行團隊開發。

    如果再來一遍,我們會做更加詳細的規劃,對於各種意外情況做好預案,提升開會效率。

資源

  1. 我們有足夠的資源來完成各項任務麼?

    是的。

  2. 各項任務所需的時間和其他資源是如何估計的,精度如何?

    • 時間:在 Alpha 階段的設計階段,我們一起對每個任務進行評估,分析每個任務所需的相關技術、完成時間,以及任務之間彼此的依賴關係。對於需要的技術,我們會事先安排時間學習,並調通樣例。這樣,之後的開發過程就會比較順利。在指定完成時間時,要注意被依賴的任務完成時間應當早於依賴的任務。

    • 硬體:由於課程網站的特殊性,我們必須使用北航校內的硬體資源,還需要北航校內的域名。因此,我們與作業系統課程老師對接,拿到了所需的資源。

      實踐證明,我們在時間上的估計是比較準確的。絕大部分任務都是在 DDL 當天或之後一天以內完成的。

  3. 測試的時間,人力和軟體/硬體資源是否足夠? 對於那些不需要程式設計的資源 (美工設計/文案)是否低估難度?

    我們的測試時間略有不足,單元測試覆蓋率僅達到了 70%。人力資源和進件資源都是足夠的。

    由於我們是面向學生的課程平臺,重在實用,因此對美工的要求沒有那麼高,也沒有在上面花什麼精力。我們的文案同樣是以準確無誤為主。難度與平時助教出題、發公告相近,並沒有低估。

  4. 你有沒有感到你做的事情可以讓別人來做(更有效率)?

    • gyp:無。我可以多幫 yzr 寫一些 API,這樣他就能有更多時間做測試。
    • cjy:有。ch 對於前端的技術熟悉程度比我高,我其實對評測機更加熟悉,適合去完成評測機的編碼。
    • ptw:並不。我在負責範圍內有較高的熟練度和一定的經驗,交給其他成員來做會增加專案的技術積累成本。
    • wwq:沒有。我有較多的時間用於軟工。
  5. 有什麼經驗教訓? 如果歷史重來一遍, 我們會做什麼改進?

    有一位同伴在中間生病隔離在了培訓中心。在軟工的同時要多睡大覺。

變更管理

  1. 每個相關的員工都及時知道了變更的訊息?

    是的。

    變更訊息如果是針對全體的,我們會在群聊或會議中提出;如果是針對部分的,則在對接中即時提出。

  2. 我們採用了什麼辦法決定“推遲”和“必須實現”的功能?

    在制定需求時確定哪些是必須實現的功能,其他不必須實現的功能根據當前任務完成情況靈活調整。

  3. 專案的出口條件(Exit Criteria – 什麼叫“做好了”)有清晰的定義麼?

    有,定義如下:

    • 功能條件
      • 在完成原定的 Alpha 階段基本課程管理、學生使用、程式碼評測功能的基礎上,按照作業系統課程老師的要求,新增基本的統計任務資訊的功能。
    • 測試條件
      • 編寫並通過全部單元測試,儘可能提高測試覆蓋率。
      • 進行簡單的後端壓力測試、評測機壓力測試。壓測情況下系統穩定不崩潰。
    • 資料條件
      • 建立 2022 春季學期計算機學院作業系統課程,並將該課程全部學生、助教、老師資訊匯入系統。
      • 建立課程所需的題目、評測用例、評測指令碼。
  4. 對於可能的變更是否能制定應急計劃?

    能。

    我們組保證至少兩天開一次會,且成員之間隨時保持聯絡,因此可以即時制定應急計劃。

  5. 員工是否能夠有效地處理意料之外的工作請求?

    可以。

    在 Alpha 階段實現過程中,OS 老師提出了一些新的工作請求,我們評估工作量,結合需求的緊迫性,將新的工作請求分為:Alpha 完成、Beta 完成、暫不實現三類。

  6. 我們學到了什麼? 如果歷史重來一遍, 我們會做什麼改進?

    我們學到了要即時溝通,如果重來一遍,我們可能會更積極地和 OS 老師溝通。

設計/實現

  1. 設計工作在什麼時候,由誰來完成的?是合適的時間,合適的人麼?
    • 設計工作按照涉及面大小、專案進度中所處位置安排其完成時間與人員。
    • 對於全域性性設計,在例會上或者即時聊天群組中提出,絕大多數情況都能得到較好的解決。
    • 對於特定服務(前端/後端/評測端)的設計,由負責同學進行,在他們方便的時間進行單獨或者結對設計。
    • 對於架構性設計,由負責架構的同學設計,並與相關服務負責同學與合適的時間進行核驗。
  2. 設計工作有沒有碰到模稜兩可的情況,團隊是如何解決的?
    • 有。
    • 對於設計中的重大疑難,我們一般將其討論範圍擴大一級。即:
      • 對於特定服務的設計,由所有負責該服務的同學決定,或由全體成員決定;
      • 對於架構性設計,在例會上或者即時聊天群組中討論決定;
      • 對於全域性性設計,在例會上討論決定,或與相關需求方討論決定。
  3. 團隊是否運用單元測試(unit test),測試驅動的開發(TDD)、UML, 或者其他工具來幫助設計和實現?這些工具有效麼? 比較專案開始的 UML 文件和現在的狀態有什麼區別?這些區別如何產生的?是否要更新 UML 文件?
    • 團隊積極部署現代化設計與驗證流程,具體形成措施如下:
      • 前端使用 Prettier / ESLint 自動驗證程式碼質量,進行一定的程式碼測試,其通過作為順利編譯的前置條件。
      • 後端對關鍵 API 進行了單元測試,測試通過作為 CI 通過的必要條件,形成了 TDD 機制。
      • 資料模型構建採用由需求到 ER 圖再到 SQL 結構的三級設計機制,其中 ER 圖幫助我們對於概念進行抽象,並指導我們構建 SQL 層的實際資料模型。
    • 現代化設計與驗證流程幫助我們快速形成共識,提高開發效率。
    • 專案開始時的 ER 圖與現在的 ER 圖由於一些細節設計的改動存在一定區別,已更新。
  4. 什麼功能產生的Bug最多,為什麼?在釋出之後發現了什麼重要的bug? 為什麼我們在設計/開發的時候沒有想到這些情況?
    • 評測端出現的 bug 最多。這是由於其涉及的環境與服務眾多,互動邏輯與內部邏輯繁雜,測試成本和難度較高。
    • 釋出後目前沒有發現新的 bug,只有釋出前遺留的一個佔用檔案系統的 bug。
    • 由於對於 GitLab API 與 golang 第三方軟體包的瞭解不足。
  5. 程式碼複審(Code Review)是如何進行的,是否嚴格執行了程式碼規範?
    • 修改由成員開啟 Merge Request 請求合併開始,需要經過至少一位其他成員的稽核後,方可合併進服務分支。這期間程式碼規範主要由自動化工具維護。人工稽核主要聚焦邏輯部分。
  6. 我們學到了什麼? 如果歷史重來一遍, 我們會做什麼改進?
    • 學到了如何進行高效的設計/驗證迭代。
    • 如果重來一遍,我們會選擇更早地形成單元測試機制,更早地進行 GitLab 使用培訓,利用好計劃階段的時間,而非等到衝刺階段還在進行計劃的收尾工作。

測試/釋出

  1. 團隊是否有一個測試計劃?為什麼沒有?

    有。

  2. 是否進行了正式的驗收測試?

    是。

  3. 團隊是否有測試工具來幫助測試?很多團隊用大量低效率的手動測試,請提出改進計劃:至少一個方面的測試要用自動化的測試工具,自動化的測試結果報告,比較測試結果的差異,等等。

    有。測試分為白盒測試與黑盒測試:

    • 在開發過程中,每一次合併到主分支時,需要其他成員複審程式碼,儘早發現程式碼缺陷。
    • 在黑盒測試時,編寫單元測試,並使用 CI 機制對每一次 push/merge 進行迴歸測試。
  4. 團隊是如何測量並跟蹤軟體的效能(Performance)的?壓力測試(Stress Test)呢? 從軟體實際執行的結果來看,這些測試工作有用麼?應該有哪些改進?

    • 效能預估:SQL 連表操作原理探究與開銷估計、資料庫服務預部署測試等
    • 效能跟蹤:日誌機制、前端資源壓測、後端 API 壓測
    • 壓力測試:
    • 這些測試幫助我們很好地預估了專案對負載的耐受能力。後續需要重點提升評測效能。
  5. 在釋出的過程中發現了哪些意外問題?

    伺服器宕機,開發成員生病,開發初期非法資料引發系統出 bug。

  6. 我們學到了什麼?如果重來一遍, 我們會做什麼改進?

    保重身體,保障開發伺服器的資料庫資料的正確性。

團隊協作

  1. 團隊的每個角色是如何確定的,是不是人盡其才?

    如展示文件所述,我們根據技術棧等因素綜合考量,將開發人員分組分工,做到人盡其才,並根據健康情況等因素靈活動態調整協作模式與分組分工安排,增強團隊組織的魯棒性。

  2. 團隊成員之間有互相幫助麼?

    有。

  3. 當出現專案管理、合作方面的問題時,團隊成員如何解決問題?

    專案管理、合作方面的問題主要在例會過程中溝通解決。

  4. 每個成員明確公開地表示對成員幫助的感謝:

    • gyp: 我感謝 ptw 對我的幫助,因為某個具體的事情: 幫助我掌握規範的開發流程。
    • cjy: 我感謝 ptw 對我的幫助,因為某個具體的事情: 幫助我熟悉前端開發技術與規範。
    • yzr: 我感謝 ptw 對我的幫助。ptw 對 dind 機制的熟練幫助我完成了評測機;全棧能力覆蓋,發掘後端多處實現問題;運維技術高超,多次拯救了瀕臨崩潰的伺服器。
    • fxj: 我感謝 ptw 對我的幫助,因為某個具體的事情: 開發了燃盡圖生成工具,方便例會文件編寫;在我生病期間接手並分配我原先的工作。
    • ch: 我感謝 ptw 對我的幫助,因為某個具體的事情: 修被我搞的亂七八糟的分支圖。
    • ptw: 我感謝全體成員對我的幫助。大家在團隊面臨嚴峻挑戰時,對我的工作給予了充分的理解與全力的支援。這減輕了困難時期壓在我身上的擔子,也使得我們的專案仍舊能夠達到 Alpha 階段的出口條件,為 OS 課程佈置理論作業提供了清晰準確的題目資源與穩定的評測平臺。
    • wwq: 我感謝 ptw 對我的幫助,因為某個具體的事情: 對前端的佈局和程式碼風格提出了很有建設性的建議(比如學生前端 commit 分支樹)。

總結

  1. 你覺得團隊目前的狀態屬於 CMM/CMMI 中的哪個檔次?

    我們認為我們的團隊處於CMMI 二級(管理級)階段,團隊目前有明確的計劃和流程,會對每一個負責任務的同學進行培訓,每一個 Issue 分配到人,權責到人。我們認為我們有能力完成所有同類項目的實施。

  2. 你覺得團隊目前處於 萌芽/磨合/規範/創造 階段的哪一個階段?

    創造階段。

  3. 你覺得團隊在這個里程碑相比前一個里程碑有什麼改進?

    沒有前一個里程碑。

    • 軟體質量方面:

      在前文已經介紹,我們對本階段的專案開發制定了 文件與程式碼規範 以保證程式碼和文件的可傳承性,並實現以 Merge Request 功能為核心的 Code Review 機制 ,通過 Review 後方貢獻方可生效。。對重要 API 進行 單元測試 ,達到了較高的程式碼覆蓋率。採用 Gitlab CI/CD 和 Docker 進行 持續整合部署 ,簡化開發流程。

    • 時間管理方面:

      以模組化的整體規劃為頂層,根據功能模組的技術難度與依賴關係設計。將任務劃分為子任務作為中層,見 Alpha 階段任務劃分文件。在各子專案中建立 Issue 作為底層,實現專案進度的動態化管理。使用自動化工具繪製燃盡圖,聚合底層資料,作為專案進度管理抓手。

    • 分工協作方面:

      根據技術棧等因素綜合考量,將開發人員分組分工,實現效益最大化,技術積累成本最小化;根據健康情況等因素靈活動態調整協作模式與分組分工安排,增強團隊組織的魯棒性。

    • 溝通對接模式:

      我們有三種基本的溝通對接模式,用以完成開發階段的任務分配、靈活解決各種問題。

      • 基於功能對接的溝通:
        • 前後端同學直接對接
        • 應用開發同學與應用部署同學直接對接
      • 基於需求對接的溝通:
        • 安排郭衍培、葉焯仁負責與需求方對接
        • 馮旭傑負責彙總與分析需求
      • 基於設計迭代的溝通:
        • 微信群直接溝通
        • Scrum Meeting 直接溝通
  4. 你覺得目前最需要改進的一個方面是什麼?

    開會時間過長,且時間陰間,需要注意效率,減少無關討論。

  5. 對照敏捷開發的原則, 你覺得你們小組做得最好的是哪幾個原則? 請列出具體的事例。

    以有進取心的人為專案核心,充分支援相信他們:Alpha 開發中,我們堅持以潘天蔚為技術領導核心,充分支援相信潘天蔚的技術指導與系統設計,領導我們奪取 Alpha 階段的偉大勝利。

    只有不斷關注技術和設計,才能越來越敏捷:Alpha 開發中,我們經常討論某些程式碼實現的“優雅程度”,盡力保證專案可維護性。

  6. 正如我們前面提到的, 軟體的質量 = 程式的質量 + 軟體工程的質量,那團隊在下一階段應該如何提高軟體工程的質量呢?

    1. 程式碼管理的質量具體應該如何提高? 程式碼複審和程式碼規範的質量應該如何提高?(cjy)

    2. 整個程式的架構如何具體提高? 如何通過重構等方法提高質量,如何衡量質量的提高?

      • 架構的提高:
        • 後端的某些 SQL 語句過長,不利於維護,可考慮使用資料庫檢視來簡化操作語句
        • 評測端直接輪詢資料庫,考慮改為輪詢後端
      • 衡量重構的提高:
        • 程式碼複用率提高
        • 架構統一度提高
    3. 其它軟體工具的應用,應該如何提高?

      GitLab 協作時可以新增 Label(如 bug、feature 等),便於區分各種 Issue。

    4. 專案管理有哪些具體的提高?

      更合理地分工、更早地做計劃、更全面的測試、更及時的對接、更敏捷的流程、更多維的管理。

    5. 專案跟蹤使用者資料方面,計劃要提高什麼地方?例如你們是如何知道每日/周活躍使用者等資料的?(gyp)

      希望增加一些統計介面。目前是查 Log 獲得。

    6. 專案文件的質量如何提高?

      在文件分工協作方面,需要每個人撰寫自己所從事的開發、管理方面工作的文件,其中大部分需要在工作開展的過程中自動形成。

      彙總提交時,需要由專人將文件彙總整理,調整格式和部分內容,以更好地符合作業需求。

    7. 對於人的領導和管理, 有什麼具體可以改進的地方? 請看《構建之法》關於PM、績效考核的章節, 或者 《人件》等參考書

      提高 PM 對專案整體的熟悉程度,成為類似“全棧領航員”的角色。

      強化 PM 與專案成員的密切溝通,知悉專案難點,明晰時間節點,助推燃盡。

    8. 對於軟體工程的理論,規律有什麼心得體會或不同意見? 請看閱讀作業。

      適當記住使用者的選擇,以優化使用者體驗。

      我們在 瀏覽題面 / 提交評測 的切換上記住了使用者的選擇,若使用者進入了瀏覽題面頁面,則下一次仍然進入瀏覽題面頁面;若使用者進入了提交評測頁面,則下一次仍然進入提交評測頁面,取得了不錯的反響。

      進行探索式測試,發現問題。

      在測試評測機的過程中,我們採用了探索測試的方式,測試包括但不限於如下情況:

      • 呼叫關機命令
      • 無限 fork
      • sleep 或死迴圈
      • 嘗試通過 system 呼叫 python
      • 嘗試在評測機中聯網

      我們發現了評測機的若干問題,並通過限制 Docker 可用資源等的方式進行了修正。

      前後端分離的開發流程。

      在前後端分離的架構下,我們採用初步確定 API,前後端分別實現並逐步對接的方式開發。

      由於時間有限,前端沒有采用 mockjs,而是先完成與 API 無關或關係較小的介面實現,待後端 API 完成後迅速對接,後端則通過 swagger 在沒有前端的情況下開發與測試。

      基於 Gitlab 的程式碼複審。

      我們沒有通過使用 todo/bug 等標記的方式完成程式碼複審,而是基於更加現代化的 Gitlab,我們使用 Issue 功能並把待辦事項、軟體缺陷等以 Issue 的形式管理起來。

      踐行敏捷開發流程。

      現有的做法 敏捷的做法
      流程和工具 個人和交流
      完備的文件 可用的軟體
      為合同談判 與客戶交流
      執行原定計劃 響應變化

      如上表所示,我們踐行敏捷開發流程,儘早並持續地交付有價值的軟體以滿足需求。

釋出部落格時,要附上全組討論的照片。