1. 程式人生 > 其它 >難遇伯樂,幸得鍾期——提問回顧與個人總結

難遇伯樂,幸得鍾期——提問回顧與個人總結

專案 內容
這個作業屬於哪個課程 2021春季計算機學院軟體工程(羅傑 任健)
這個作業的要求在哪裡 提問回顧與個人總結要求
我在這個課程的目標是 提升工程能力和團隊意識,熟悉軟體開發的流程
這個作業在哪個具體方面幫助我實現目標 總結學期所得與所感

閱讀提問

閱讀提問部落格連結:傳送門

結對總結部落格連結:傳送門

團隊部落格連結:傳送門

問題一:單元測試一定要作者寫嗎

當局者迷,旁觀者清。如果讓一個並不熟悉這一部分程式碼的人來編寫單元測試,他就有更大的概率突破作者本身的思維定式,而對於一些刁鑽的邊界情況進行處理,這種邊界情況不僅僅包含輸入輸出內容,還包括呼叫位置、呼叫時機等等多個方面。

先說結論:我現在認為,單元測試並不一定需要作者自己寫,重要的是對於功能的覆蓋程度、對於文件的適應性和錯誤處理的覆蓋面要廣,也就是編寫測試的人要非常明確自己在測什麼、明確自己需要覆蓋什麼情況,而這種人往往是作者本人

當時@寶玉老師在部落格下面的指導在當時就令我大致明白了這個問題的答案:

是不是作者寫不過是不同的手段,甚至單元測試本身也是手段。

但是軟體工程的方法論不就是討論通過何種手段達到目的的嗎?

對,但是不要錯把手段當目的

是的,單元測試無非只是一個保證迭代開發的穩定性、保證處理邏輯的條理性、保證處理範圍的廣度的一個手段而已,我們做單元測試不是為了達到多少覆蓋率而去做測試。類似地,至於是誰作為測試者編寫單元測試,那更是實現單元測試的一個手段

而已。

不管黑貓白貓,能捉老鼠的就是好貓。

只要手段能夠達到目的,則是好手段,要抓的是主要矛盾。至於能否達到目的,需要具體情況具體分析。

很巧,本學期在結對程式設計和組隊專案中,我有幸體驗了“測試員”的角色。

結對專案中對於邊界情況的要求較多,對於各種特殊情況的處理難以進行全面覆蓋性的測試,由於我本人蔘加過一些演算法競賽,對這方面資料的構造有一定經驗,同時擔任了駕駛員的角色,因此“單元測試”自然而然的由我進行編寫。對於程式碼的瞭解和對於樣例構造的表格記錄,同時在測試時不考慮自己實現的細節而專注於進行全面覆蓋性的測試,極大地保證了程式碼的正確性和魯棒性,這可能就是作為程式碼編寫者本人進行測試的一個優勢所在。

組隊專案中,我負責後端的單元測試。組隊專案與結對專案中的待測程式碼可謂天壤之別,大相徑庭。組隊專案的待測程式碼主要是沒有什麼疑問的 API 功能實現,如從資料庫中讀一些東西返回給前端,前端傳來點東西扔進資料庫,有極高的重複率;最可能出問題的單詞推薦演算法部分也大部分是由本人執筆的。因此,我僅對於部分較有代表性的程式碼進行了覆蓋性的單元測試,測試的過程中確實發現了一些實現方面的細節問題;但在僅僅達到 70% 的單元測試覆蓋率後,我們在後續操作的測試中就沒再發現問題了。

雖然確實如果還有充足的時間,我會盡量將更多的情況進行覆蓋性測試,70% 的覆蓋率確實有些低了;但是由於需要進行前後端對接、新演算法實現以及作為 PM 的團隊規劃,進行較為全面的覆蓋性測試不現實,因此僅僅使用了價效比最高的、忽略重複無意義操作測試的方案;但從此也可以看出,在軟體工程中對於目的和手段的主次需要進一步明確

私以為,從這裡就可以看出,敏捷開發最關注的可能就是所做事物的價效比。因此,我有一個新的疑問提出:

如果明知一個事情是對的,但是對不對的權利不掌握在你手中(比如老闆),而且他執著堅定地、甚至可能先入為主地認為,這個事情並不對。這時,是否應該選擇價效比更高的妥協?

我不知道。希望我將來也不需要知道。

問題二:結對程式設計的應用性如何

結對的一個主要目的便是讓程式碼出錯的概率降低、每一行程式碼都有其存在的意義,不留渾水摸魚的機會,但書中提到過的程式碼複審也能夠達到類似的目的,而且能夠多人蔘與,聲音來源更廣,在當下 github gitlab 等程式碼交流社群的 pull request 也十分便捷。事實上,瞭解過的部分周圍公司也都因為種種原因沒能開展結對程式設計。結對程式設計最早也是源自兩個程式設計師趕 DDL 不得不做的一個“創舉”,僅僅是契合當時的事件背景的一種解決方案。結對程式設計在當下的應用性究竟如何?

在經歷過結對程式設計之後,我對這種程式設計方式在真實公司裡存在的應用性存疑。

真正能夠穩定輕鬆進行下來的組別,在我看來,少之又少。這大概是因為一方面需要兩人的水平不可差異太大,另一方面需要有一個細心全面的領航員和一個果斷規範的駕駛員,才能讓飛行的過程中保持清晰的頭腦,清楚地知道自己每一行程式碼在寫什麼,從而才可以進行有序穩定的推進。

據觀察瞭解,還有一個較為嚴重的阻礙,就是大部分同學不習慣被人盯著寫碼,雖然不太理解,但這或許是大部分組別沒有真正進行一人駕駛一人領航的“結對程式設計”,而是在進行一種小團隊分工合作形式的“專案程式設計”的原因。其實終究說來,還是這種分工合作形式相對真正的結對程式設計能夠以較高的價效比完成任務。因此,就敏捷說來,結對程式設計貌似不是一個優的選擇。

問題三:課程中例會是否仍要“每日”

敏捷開發中,頻繁的小會是為了及時同步全域性資訊,讓團隊清楚個人的進度情況、困難之處,同步資訊的主要目的在於增加整個團隊的效率,即通過隊友的進度、壓力、困難來 push 每一個人。我相信我們的組員都不會習慣於渾水摸魚,但人的精力是有限的。在這種課程壓力下,在例會會佔掉課餘時間一大塊蛋糕時,同步資訊的例會是否還有必要保持“每日”?如果適當地增大例會之間的間隙,並適當規定每個人的貢獻與任務,是否也能夠在給組員足夠壓力的同時允許我們自主安排其他課程與軟工專案的時間?

確實不需要,尤其是在我們本學期專業課壓力較重的環境下。

團隊專案中,隊伍基本兩天一會,在 Beta 階段壓力更大的情況下,才在最後衝刺階段進行一天一會,進行看板、議題商定以及整合測試。

兩天一次的例會已經足夠同步全域性資訊了,在某些會議上前端進度較多,後端就會讓前端慢下來先寫 API 讓後端進行實現,然後繼續進行前端工作;後端內部也可以更加合理地進行資料獲取、API 實現與測試、資料庫設計實現以及伺服器和域名配置等任務的分配,每一次“每兩日例會”之後對於全域性資訊的同步總結都極大地促進了團隊的執行效率。

我們團隊其實在會議後進行聯合開發,沒有其他事幹擾的隊友們聚在一起進行快樂開發,感覺非常愉悅,也不會碼到一半犯困,這也就是我們對於問題的解決為什麼不侷限於 issue,而是首先使用看板法,這還是一個價效比的問題。在集體開發後存疑的部分,為了防止忘記和遺漏,我們會在 gitlab 上新建一些 issue 或者 comment 進行記錄

問題四:NABCD 模型是否變為 BD 模型

觀察這幾個軟體的做法,擴大使用者量的主要因素就在一內因(B)一外因(D)。滿足使用者基本需求的 N,在 QQ 那時或許是一種開創性的做法(其實當時也不算基本需求了),在現下已經是一種企業生存的必需要求了,單單滿足這一需求是無法談論競爭力的。而這些軟體之所以能夠取得如此規模使用者量,更多的其實是滿足使用者“興奮需求”的 B,以及市場推廣或者捆綁的手段 D。同樣地,許多被騰訊推廣的遊戲,其設計、內容等都遠遠落後於同類型其他遊戲,但無論是使用者量還是知名度往往都能夠吊打其他遊戲。所以其實 NABCD 模型在當下是否轉化成了 BD 模型?軟體的成功到底是軟體工程還是市場營銷?

經過一個學期的學習,我仍舊對此沒有得到一個較好的答案。

但可以肯定的是,D 是一個很重要的考慮因素。

Alpha 階段,團隊專案“近取 Key”進行了詳盡完備的 NABCD 需求分析,無論是從基本需求、方案設計還是競品對比,都做了比較全面的分析,但是我們當時主要的考慮點在於能夠實現這麼一個東西,而並非將其進行大規模的宣傳,因此 D 階段沒有下大功夫,而是在功能完備性上下了大功夫。這其實在工程量和宣傳上做了一個衡量規劃,我認為是合理的。

Beta 階段,增加了一些宣發力度的同時,需要做的任務和內容也並不少於 Alpha 階段,因此實際上對於宣發的力度做的還是沒有全力以赴,而是在追求一個現在看來似乎有些畫蛇添足的 B ——社群。因為...似乎沒有人在用這個功能。當然,產品的 N 和 B 基本需求和興奮需求確實非常有效——因為有很小一部分使用者已經在真正使用本軟體在背單詞了,而且每天都能收穫到使用者的新反饋。但似乎眾多受眾背單詞黨們並沒有被吸引到,可能是宣發的力度有限導致的。其實也沒有什麼特別好的方法,畢竟多數在背單詞使用者都是在移動端碎片化地背,導致對於真正的受眾使用者被遮蔽掉了。

阻礙我們產品擁有較高活躍度的除了受眾佔比低、難宣傳之外,還有兩個因素:一是平板適配,二是登入方式。平板適配由於技術原因沒有做到非常完備,尤其是進行測試裝置的不夠多,對於各種大小的螢幕無法做到全部能夠適應。登入方式由於微信登入需要較昂貴的一筆開銷,因此選擇了暫時不考慮;同時由於詞圖限制,無法做手機端,因此無法做小程式,在登入方面給使用者設定了一些屏障。

當然,還可以進一步分析一下這個產品的殺手級功能。A4 紙背單詞法,是一個我們之前也經常使用的一種背單詞方式,但由於每次對於一個單詞不知道含義的時候都需要花大量的時間去翻字典重新記憶,導致了效率的一定程度降低。因此,我們考慮如果能通過軟體來自動實現,那將有多好。這並不是一個臆想的需求,只是受眾較少;而電腦端背單詞軟體僅僅是附庸於 A4 紙背單詞需要大屏的一個結果而已,並非什麼需求與配置。

值得考慮的是,如何才能夠找到小眾需求對應的受眾?目前宣傳結束後,日活大概能夠維持在 20 人,而且 B 站視訊播放量也在逐漸穩步增加,似乎這是一種較好但轉化率較低的宣傳方式;如果有更好的如知乎、微博等更多方面的渠道進行宣傳,或許能夠拉到更多有需要使用電子版 A4 紙背單詞法的使用者吧。那個做的感覺明顯很垃圾的競品小程式能做到幾萬播放,感覺甚是奇怪,可能這就是快節奏時代宣傳的方式?我不知道。

問題五:設計文件如何平衡嚴謹性與複雜性

因此,設計文件應該如何平衡嚴謹性與複雜性?真實軟體工程中,是否用到了類似 JML 的規格語言進行功能描述,如果是,如何保證編寫的正確性?如果不是,如何保證規格的嚴謹性?

團隊專案中,我們使用了 API 文件進行前後端互動,後端內部使用資料庫設計文件進行資料庫約束,沒有涉及到具體某一個方法的類似 JML 的規格化表述。我認為這種方案就是比較可行的,該分離的地方分離,接合分離處的地方寫明設計文件即可。

問題六:整合測試應不應該在模組構建時進行

這裡純粹對整合測試和模組構建的理解有一些偏差,有點摳字眼了,本質還是手段與目的的問題。

問題七:事後諸葛亮會議為何不能融入每日例會

鄒欣老師的解答

  1. 每日例會時間要短
  2. 很多工在進行中,不是一個好的回顧總結的時間點。 (例如,你寫的一個功能號稱會有很多使用者喜歡, 在沒有使用者反饋前,你是不知道的,也無法總結)
  3. 總結要撥出專門時間好好討論

和寶玉老師的解答

當然可以融入,但是不能替代。

  1. 要有儀式感
  2. 站會要短而精,加上事後諸葛,那麼站會的意義就變了

已經解答了我的疑惑,在敏捷開發這一盤快棋中,諸葛亮會議之於每日例會即是覆盤之於思考,每一步落子的思考是帶有侷限性的。在 Alpha 和 Beta 兩次衝刺結束後,我們對於自己的產品分別進行了兩次事後會議,能夠在更加高的角度俯瞰整一個衝刺中無論是管理還是分工,或是對於產品的思考分析,以及方方面面的得失,我認為這是比純粹的趕 DDL 衝一個專案收穫更大的環節。

知識點

先按部落格要求寫一下“知識點”。

需求:見上“問題四”:NABCD 該如何分析;對於小眾需求,受眾需要提前找。

設計:需求設計不分家,確定需求後即可進行初步的架構設計和 UI 邏輯設計了。設計方面主要學到了使用 processon 也能進行原型圖繪製,以及對於文件應該如何撰寫的基本瞭解(如 API 文件的撰寫、ER 圖和資料庫設計文件該如何撰寫等)。同時,對於架構設計尤其是資料庫部分,要充分考慮到解耦合、新增合適的多屬性鍵等影響較大的、有助於後續迭代開發的部分,避免設計低魯棒性的、難以維護的資料庫。

實現:實現部分,作為後端,主要是對於前端傳來的 API 進行與資料庫的對接。因此實現部分較為簡單,所學知識大概是 CI/CD 的搭建、程式碼規範、程式碼風格、命名規範的統一。

測試:見上“問題一”:單元測試是手段,目的是軟工;通過壓力測試可以不斷優化演算法和配置,如 Alpha 測試報告中所提到的。

釋出:釋出不僅僅是給一個連結扔到朋友圈就行,做的是產品,方便的是使用者。要做宣傳冊、方便使用者觀看且短小精悍的視訊、針對使用者需求精心設計的文案等等,不一而足。要儘可能讓使用者簡單地進行反饋,使用者的反饋真的很重要。因此,也需要儘早進行釋出,不能釋出得太晚。

維護:直接置頂反饋群,同時每日一刷 core_remark 使用者反饋並進行討論。bug 方面討論的較少,可能也與測試較為完備有關,主要還是討論適配問題。對這種 bug 也需要進行一定量的記錄。

心得體會

運用之妙,存乎一心。

其實學這門課之前我對軟工所有的瞭解就是:要學的東西很多,但我啥技術都不會。不過被昂神忽悠過來羅傑老師班之後的一個學期,收穫是頗豐的。

非常喜歡學期初的個人閱讀作業,把整個人從寒假的摸魚狀態直接拉回緊張的學習生活中,仔細對自己進行分析、閱讀鄒老師的著作、分析軟體的差異性。還記得整整一個周除了吃飯睡覺打疫苗之外無時無刻不在捧讀《構建之法》的日子,兩整天找洛谷和力扣 bug 的場景仍歷歷在目。

讀完《構建》,一棟完整的大樓在腦中逐漸浮現。從需求分析,到架構設計,再到程式碼實現測試;從個人能力,到結對程式設計,再到團隊敏捷開發;從單元測試,到場景測試,再到系統整合測試......有感而發,一鼓作氣提出了九個問題,現在看來多數都是對一些細節鑽入了牛角尖;但也有一些至今仍未搞懂的問題,或許需要在將來的生產生活中進一步的領悟了。

案例分析作業是一個真正煞費苦心寫的部落格,不過可能由於交的過早沒有覆蓋到一些東西(笑)。這是我使用兩三年洛谷第一次認真的去扒它的 bug,只記得以前一直用的挺順暢,使用者體驗不錯,難找 bug;沒想卻成為了點炒飯的顧客。在分析產品規劃的時候,我逐漸形成了一種分析使用者特點的思維模式,也即做使用者所需:做大部分使用者所需,做特定功能使用者所需。自此以後,對於軟工的需求分析有了進一步的認知。

結對作業做的不像軟工,而更像一個變異體的 OO,本地測試強度夢迴第三單元,但是強測強度真是一言難盡。主要還是過了一把駕駛員的癮,操縱全域性、從需求分析開始,設計類的架構、設計實現方法、設計測試用例,倒也有點小軟工的意思。從結對作業中與助教高強度開 issue 對線的經歷裡,我更加深刻地體會到一個合適的需求分析的重要性,以及一個魯棒性強的架構與實現在變動的需求下是多麼的重要;同時對 gitlab 協作使用有了更多的經驗。

題目確實難出,既要出的能夠迭代,又要描述嚴謹、不漏邊界情況,還不可以太簡單,因此對於題目就不進行吐槽了;但是個人其實對結對這種程式設計方式沒有什麼特別好的印象,沒有體會到結對能夠如何幫助我們多少(也如上方問題二中的想法相同),而且真正也沒有見到有公司使用這種方法進行工作,因此對結對作業部分仍然存疑。可以考慮刪掉結對作業直接組隊,或者將結對換為個人的熱身小作業;或者必須保留的話,可以將結對作業作為熱身專案,不要出的這麼繞,體驗都會提升一個層次。

團隊專案中,我負責後端的開發以及輪值 PM,最開始對 Django 技術棧一竅不通,在老田一個之前做過的專案 demo 下逐漸全摸明白了,老田 NB!剛開始分配任務棧的時候,需要四名前端,但大家基本都沒幹過前端,四位勇士當仁不讓,站出來挑戰前端,從零開始幹勁滿滿地學習技術棧,啃技術難點硬骨頭、搜尋挑選五花八門的元件庫,在如此短的時間內將 UI 做的這麼精緻美觀,將詞圖功能展現的淋漓盡致。我們能夠作為一個團隊共同努力奮鬥,是一件多麼幸福的事情。

在 Alpha 階段後,課程組對我們提出了宣傳力度不夠的評論,並給我們一份內容翔實的深度分析部落格,我們非常重視,馬上將宣傳提上了 Beta 階段重大任務的日程,並且詳細地品讀了深度分析部落格,深度讀完後驚喜地發現,其中大部分內容和 Beta 階段的任務相同,從對於使用者的新手引導、單詞的新增邏輯,到單詞複習的功能互動感、加入詞圖可能的重疊,以及域名的申請,這都是 Beta 階段當時定下的重點考慮物件,在最後的 Beta 階段均已被實現。唯一的遺憾就是平板的適配弱了一些,這是技術問題,沒有被解決掉。

換人階段感謝老田提出的“雙向選擇”轉會方式,我們能夠在一個更加真實的轉會背景下進行合理的人員再分配。

在如此短暫的開發時間下,我們將最主要的功能進行了實現,其他一些花裡胡哨的功能,比如測試中的選擇題,都被踢下了日程,換上了宣傳視訊的製作、H5 宣傳冊的製作、以及 B 站 up 的交流工作等等,真正做到了有舍有得、以我們現有能力在如此短時間內能做到的最佳狀態。在此我們要感謝課程組一個學期以來對於我們組無論是需求還是宣傳方面做的事情,無論是 push 也好,熱烈的討論也罷,都是一筆軟工給我們留下的財富。雖然 PM 需要在統籌的同時完成不少於普通組員的任務,但我們仍然坐定冷板凳,認真地考慮和討論課程組所提意見的合理性並付諸行動,真正做到了核心功能紮實、殺手功能突出、廣納博取融會貫通的軟工。如果再給我們多一些時間對軟體進行完善,我想還能夠進一步完善的就是宣傳的廣度和力度,打通通向受眾的通道;以及對於平板的支援度、對於各種解析度螢幕的適應程度。

在包括眾多因素的現實背景下,我們仍然能夠拿到現場評審的第一名、總體評分的第二名,且與第一名的隊伍分可能只差在一兩個評分上,這個成績還是相當滿意了。當然,在這裡也要祝下一屆有一群更加負責任的助教團隊,如果作為助教還是搞不明白自己應該把什麼放在重點、把什麼“助”教給學生,把自己的先驗概率藏起來的話,那可能還是比較適合搞技術,和助教可能有一定的區別,希望軟工課程組能夠認識到這一點。

“唯陛下觀覽古今,反覆參考,無以先入之語為主。”

總之,課程內容很好,很推薦,通過從閱讀到分析再到實踐的一個完整過程讓我們熟悉了軟工的基本流程。如果有人問我,給我一次機會,是否還會選擇羅傑老師的軟工,我會毫不猶豫地說一句“是”。伯樂不常有,但萬一有呢?