天天看點

2020BUAA軟工提問回顧和個人總結作業

2020BUAA軟工提問回顧和個人總結作業

17373010 杜博玮
項目 内容
這個作業屬于哪個課程 2020春季計算機學院軟體工程(羅傑 任健)
這個作業的要求在哪裡 提問回顧和個人總結作業
我在這個課程的目标是 學習軟體工程,培養工程開發能力、團隊協作能力,開闊視野
這個作業在哪個具體方面幫助我實作目标 反思整個課程的學習過程,通過自我總結提升軟工總體水準
提問部落格連結 2020BUAA軟工個人部落格作業

對自己曾經提出的問題進行解答

  • 在4.3.2中,作者表達了隻要有助于程式邏輯的清晰展現,什麼方法都可以使用的觀點。
    我個人對這一觀點表示反對。因為一個程式員很難保證自己的思維永遠清晰完整,而開放類似于goto之類的方法,完全是給整個程式的正确性埋下巨大的隐患。畢竟大型軟體邏輯結構比較複雜,使用goto之類被公認會降低程式安全性并且破壞程式的結構化程度的方法來使程式邏輯清晰完全是得不償失。我們完全可以通過增加注釋,整理代碼等多種方式來做到這一點,為什麼要使用goto之類的方法呢?

    現在我并不認同作者提出的觀點。在原文中作者表示函數最好有單一出口,為了達到這個目的,即使使用goto也是沒有問題的。因為這樣有助于程式邏輯的清晰展現。然而在實際應用編寫中,錯誤處理占據了代碼的很大篇幅。這次的團隊項目中由于我所編寫的代碼涉及到網頁通路,程式異常處理多如牛毛,不同的異常也需要不同的處理,如果強行使用goto做到單一出口,風險與收益完全不成比例。

    在我看來,通過保證程式隻有一個出口這類要求來達到程式邏輯清晰完全沒有通過增加注釋,整理代碼等方式便捷、安全。當然,在一些代碼規範如pylint中有return語句的數量限制,但是這種限制很寬松,基本上不會對正常程式報錯,通過這種規範反而能夠通過較小的代碼修改很好地規範代碼格式。

    總而言之,我認為使用任意方法來達到程式邏輯清晰是不可取的,我們需要在正确性、工作量以及邏輯清晰之間進行取舍以達到一個平衡值。

  • 在11.5.5中,作者對小強地獄進行了闡述,在闡述中我們不難發現開發新功能與修複小強之間的沖突。

    在客戶與績效的壓力下,開發新功能有着很高的優先級,但是拖着大量小強既導緻測試人員無法有效地繼續測試,也可能将小小強拖成大小強,在後續的過程中造成巨大的困難。作者介紹了小強地獄的方式來解決這一沖突,但是我感覺這種按照門檻值修複小強的方法做得不夠徹底,大量的bug依然會被遺留下來。

    在我看來,借鑒ZBB是一個很不錯的選擇,在一周的開始,開發人員開發新功能,測試人員進行測試,在這一星期的結束,開發人員針對測試人員提出的bug進行修複,下一周繼續進行上述工作。

    如果一切順利,開發人員一周内需要解決的bug也就是他們在上周的開發中所産生的bug,這樣是不是就可以比較好地解決開發新功能與修複小強之間的沖突。

    在這次團隊作業中,我們團隊在開發階段出現了不少的bug。這些bug對項目的繼續開發造成了比較嚴重的影響。比如前端的bug就會影響後端的相應部分的開發、對接、測試。但是着重于bug的修複又會産生進度問題。比如在Beta階段我們組内一個前端同學就因為一些bug導緻一個比較簡單的任務做了大概一個星期,這極大程度地拖慢了前端乃至後端的工作進度。

    是以我們可以看到在實際項目中,bug和開發之間确實是像書上說的存在沖突。但是通過實踐來看,解決這種沖突不能拘泥于紙面上的分析,而是要帶入項目本身。無論是小強地獄的方式還是我此前提出的方法都是有它的優缺點的。比如小強地獄就易于使用,但是可能會做得不夠徹底。而我所提出的方法過于理想化,不易實作。實際應用中還是要結合項目自身處理開發與bug處理之間的沖突。

  • 在15.1.3中,作者介紹了從代碼完成到代碼釋出時可以采取的不同操作,其中有重寫和重構兩種解決Bug的思路。

    這兩種方式各有不同,但都是解決Bug的相當好的途徑,同時也會增加大量的勞動量。我的疑問是這兩種方法的差異以及各自的應用領域。

    在書中,作者介紹了重寫與重構的含義。重寫是指重新實作原有功能,重構是指在盡量保持原有界面的基礎上優化部分代碼。

    我在網絡上發現很多程式員對重寫持有很不友善的态度。他們認為重寫是一個相當大工作量的工作,成本很高,很多邏輯可能會被忽略,需要花費更多的人力來測試和debug,并且需要重新了解項目的需求,完全重新設計與實作,任務繁重且困難。為了維持正在運作的系統,我們可能還需要一邊重寫新系統,一邊重構舊系統。而且一個需要重寫來處理的項目很有可能留下的文檔與代碼一樣混亂不堪,是以在對業務邏輯沒有理足夠清楚的情況下,大多數人都不推薦重寫系統,隻有在很清楚地知道代碼做什麼,但是很難了解那些代碼的時候才會重寫。

    而大家對重構就比較友善了,重構是一種局部式,增量式的活動,我們通過向舊系統中增補更新檔來對代碼進行逐漸的優化,進而逐漸減少代碼的混亂程度,增加代碼可讀性。一般情況下,當代碼難于了解,并且團隊不能确定它做什麼的時候進行代碼的重構。(參考:重構?還是重寫?)

    在Beta階段我對自己的代碼大規模進行了重構和重寫的工作。根據我自身的經驗來看,重寫主要是用相同或不同的方法重新寫一遍,重新實作原有功能。而重構則是不改變代碼本身基本架構和大多數代碼,隻優化少部分的代碼。

    在Beta階段,由于使用者數的增長,此前Alpha階段所設計的方法消耗太大,導緻伺服器負載大,提供服務卡頓。是以項目隻能通過另一種方法來擷取資料。這導緻我需要完全重寫我的資料擷取程式。整個重寫過程很痛苦,完全的推倒重來導緻工作量很大。然而重寫後的程式運作速度提升了3-5倍,記憶體占用減少了幾十倍,效果相當可喜。

    同時,在Beta階段,團隊決定使用pylint進行代碼規範。裝上pylint後測試出現了400多個錯誤。其中還有很多代碼結構上的問題。為了一個好的代碼風格,我對整個代碼進行了重構,改寫了部分循環分支繁雜、大量傳回語句堆疊在一起的代碼。整個重構過程比較快速,大概隻花費了4-5個小時,重構後的效果也非常不錯。

  • 在12.1.2中,作者對“吃狗食”進行進行了闡述
    “吃狗食”保證了開發人員能了解軟體功能的實際表現,可以發現很多關于使用者體驗方面的問題。但是程式員作為軟體開發專業人士,對軟體構造的看法與使用者有很大的差別。那麼我不禁想到,不如專門讓那些沒有程式員思維的體驗員進行體驗,通過體驗員與程式員之間的交流、辯論來改善軟體在使用者體驗方面的問題。
    在團隊作業中我們主要通過“吃狗食”這種方法來進行測試以及使用者體驗方面的改進。整體而言這種方式确實讓我們找到了大部分的問題,進行了很多使用者體驗上的改進。但是我們作為程式的開發者,由于對程式的運作機制有比較深的了解,有很多使用者體驗上的問題沒有發現。而且我們團隊的前端開發者在“吃狗食”的過程中發現的問題就更少了。是以在我看來,“吃狗食”确實很有意義,但是不能盲目相信它的作用,沒有程式員思維的體驗員的意見應當更為重要。“吃狗食”更大的意義還是在于迫使程式員好好寫代碼,不要寫屎給自己吃。

還不明白的問題

  • 在2.1.2好的單元檢測的标準中給出了單元測試好壞的判斷标準,我的問題是關于單元測試的針對方向。

    作者在單元測試好壞的判斷标準中寫道,單元測試應該在最基本的功能/參數上驗證程式的正确性且單元測試要快。但是在前面對單元測試的引入中作者通過小故事表達技術子產品各項要求最好都可以表示為一個單元測試樣例的思想。那麼單元測試到底應當針對什麼呢?

    首先我認為根據單元測試的名字我們可以看出它應當測試基礎功能,其他重要功能應當在功能測試、內建測試等領域展開,但是我們有時會利用單元測試來檢驗一個類或函數的正确性,通過查找資料,我發現單元測試(unit testing),是指對軟體中的最小可測試單元進行檢查和驗證。(參考:單元測試)那麼我們是不是應當針對程式中所編寫的一個個單元進行驗證,而不是針對技術的一個個最基本功能來驗證呢,換句話說,單元測試是基于設計層面,還是基于程式方面?在我看來,我們應當專注于程式方面,但我并不能完全說服自己。

    在這次軟工的項目中,我的單元測試還是更傾向于驗證一個設計層面的功能是否正确,這樣的測試易于編寫,結果也更容易了解。但是我也認為對每一個程式的單元進行測試更為嚴苛、标準,出現了問題也更容易排查。我對這個問題總體的印象還是比較模棱兩可的,沒有對某一方的偏愛。

學習的新知識

  • 需求

    需求不能隻靠團隊設想,但是也不能全憑使用者決定。而是應當由團隊設計主體架構及方向,使用者和團隊一同提出詳細需求,最終交由團隊取舍。

  • 設計

    設計時絕對不能過于籠統,這會導緻具體實作不好下手,但也不能過于詳細,具體實作時出現一些問題會使原計劃大幅度變動,影響太深。

  • 實作

    具體實作時不能一昧猛幹,而是要先解決知識盲區,再解決資料接口格式等問題後再下手。

  • 測試

    測試用例必須要全面,從各個有可能出現問題的角度出發設計樣例。

  • 釋出

    釋出不能随便一個廣告了事,而是要有針對性地設計宣傳語,内有要有足夠的吸引力,從多個管道投放廣告。

  • 維護

    錯誤回報必須要有及時的通道,比如程式可以設計成抛出未知異常時向微信發出問題的詳細資訊,進而做到及時擷取有用的錯誤資訊。

心得和了解

  • 個人項目

    其實感覺與以前的大作業沒有太大的差別,甚至可以說把這道題和去年OO的多項式的題放在一起,我不能看出這次的個人項目到底“軟工”在了哪裡。

    但是這個項目還是讓我獲得了一定的收獲。首先這道題目看似是很簡單的模拟題(不追求O(n^2)以下的時間複雜度的話),實際應用時你還是會被浮點數的精确性、部分耗時較大的語句卡住。我之後在浮點數判斷時采用與1e-8相比的方法提高精确度,将set改為unsorted_set大大提高運作速度。同時這次的項目還着重引入了單元測試,這是以前幾乎沒有接觸過的。

    以上這三個方面都給我一些啟示,精确性與複雜度都是可以在很小的地方摳出來的。而有效的測試則是代碼品質提升的好方法。

  • 結對項目

    整個結對項目可以看作是個人項目與團隊項目之間的過渡。整個項目做下來确實感受到了兩個人一起做項目的好處,奇葩bug少多了,思考的時間也變少了。但是我們所付出的是效率降低的代價。總體來說有利有弊吧,其實我個人是更偏好于一個人寫代碼的,多一個人監督總會讓我有些慌亂,不知所措。但是整個結對項目下來通過與同伴的溝通,我也學到了不少的東西,也學會了從旁觀者的角度去看待問題和程式設計。

  • 團隊項目

    整個團隊項目做下來讓我感覺選羅傑老師的課選對了,或者說我進了一個好團隊。PM認真負責,對開發的各個方面都有一定的了解,各團隊成員之間友好協作,一起做一個我們很想去做的項目。這可能就是軟體工程的魅力所在吧。

    感覺整個項目的關鍵還是在于設計階段。在需求基本确定的情況下确定需求的實作手段并配置設定任務。能否選用恰當的實作手段很大程度上決定了整個開發階段會不會瘋狂爆肝一個難以實作的東西,或者說實作了大半了發現不好用,全部推倒重來。而任務配置設定和時間規劃則很大程度上決定了整個實作階段的效率和實作效果。

    回顧團隊項目階段,一個月的時間我們這個剛剛搭建起來的團隊做出了一個界面還算美觀,功能實用、基本上沒有bug的程式。我内心感到相當的快樂和充實。