初窺構建之法——記2020BUAA軟工個人部落格作業

項目 內容
這個作業屬於哪個課程 2020春季電腦學院軟體工程(羅傑 任建)
這個作業的要求在哪裡 個人部落格作業
我在這個課程的目標是 完成一次完整的軟體開發經歷
並以部落格的方式記錄開發過程的心得
掌握團隊協作的技巧
做出一個優秀的、持久的、具有實際意義的產品
這個作業在哪個具體方面幫助我實現目標 通過鄒欣老師的《構建之法》
在開始團隊項目前先了解清楚「團隊」和「項目」

學會提出問題

第一次真正意義上的軟體工程個人部落格作業,要求是速讀鄒欣老師編著的《構建之法》,並提出5-10個問題。這個任務非常有趣,他不是傳統的讀書作業似的讓同學們寫讀後感,我想可能是讀後感這種東西比較偏向個人,而且大多的讀後感其實是對文章目錄的總結,並沒有深度到某一個文欄位落中去。但是,提出問題,一是同學必須要真正深度到段落文字,二是強迫你在閱讀的時候思考,沒有思考就不會提出問題。在周舜欽:學習金字塔的誤解中,作者為閱讀這一學習行為進行了辯護,認為很多人通過讀完之後能記憶多少來考察閱讀的效果是不正確的,應該夾以考慮閱讀的深度和廣度,是否有在閱讀的過程中積極思考,參與討論。對書本中不理解的地方提出問題,即是一種思考的方式。

問題零:課程的打分是否合理?

參見《構建之法》—— 給任課老師和助教的建議

這堂課如何打分?很簡單:把每次作業的表現分為N檔,最優秀的幾個同學得滿分,第2檔的同學得1/2的分數,第3檔的同學得1/3的分數,依次類推下去,這就是1/N的打分體系。遲交作業0分,不交作業倒扣分。就像下圖實線顯示的那樣。虛線是傳統的「大家都能及格」的分數分布,如此分布看似皆大歡喜,其實是對優秀學生的極大不公。
1/N評價方案

為什麼是問題零呢?大家已經看出來,這個問題是在書中的正式內容開始之前的部分,甚至是 「給任課老師和助教的建議部分」,而不是關於軟體工程的部分。但是我還是想斗膽提出自己的質疑,這樣的 1/N打分體系 是否合理?是否有走極端的嫌疑?

首先,分檔給分是有依據的,這裡我也在arxiv上找到了一篇Grading by Category(GBC)關於討論如何能夠更好的給同學不僅僅是分數,而帶有回饋。文中提到了三個關鍵點:

  1. 分類標準是由學生的總體水平決定的,而不是事前給出的分數。如:應該是占當年學生的百分之多少,而不是達到了多少分。
  2. 先分類再給定分數,這也透露出分檔不是最後的得分。
  3. 分類的標準是學生沒做什麼或者做錯了什麼,而不是做對了什麼。
    這裡的分檔給分,論文中也給出了例子,對於一道物理題,分了多達8個等級:
等級 原因 佔比
Q(4.0) 完整的回答,有清晰的步驟和整潔的作圖 27%
M(3.5) 也是完整的回答,但可能在步驟或作圖上出現一些瑕疵 6%
L(3.2) 大致完整的回答,但作圖錯誤或表述不清 10%
C(2.5) 回答中對圖片沒有完整的定義,作圖也出現錯誤或表述不清 6%
P(2.0) 知道回答需要的方程,並能知道方程的定義 14%
S(1.0) 知道回答需要的方程,但是並不能正確理解方程的含義 22%
N(0.5) 能夠寫出一些有意義的回答,但是沒有完成題目 10%
Z(0.0) 物理意義和實際意義上的白卷 4%

論文的作者表示,通過給出細分的等級,有以下幾點好處:

  1. 學生可以根據得到的等級快速定位到自己的問題,以至學生能夠在未來的測試中根據自己等級對應的不足自己有目標努力。
  2. 學生更加關注的是自己沒有做到什麼,而不是自己做到什麼,從而暴露出自己的不足和缺陷,去重視自己的缺陷。
  3. 老師在給分時可以三思,因為GBC評分方式是等到所有學生的回答都給定等級之後再進行細緻的數值上的分數。這可以讓老師在給定具體數值分數的時候可以不需要重新審閱所有同學的回答,而是在大體的等級區域內給出細緻的分數,也不會讓同學得到比應得更低的分數。
  4. GBC評分制度提供給了老師一個量化分析的手段,因為在給定等級的過程中就已經對同學們所犯的錯誤或者不足進行的分類,所以出現同一問題的同學的比例就可以直接由該等級得到,從而進一步調整教學方式和教學重點。
  5. GBC評分制度提供了一個更簡便的 re-grade 方式。也就是說如果學生對於自己的成績有異議,可以告訴老師自己的預期等級是多少,但學生在提出異議之前會先對自己進行一個等級上的評價,也就是將成績的合理性的證明從老師的身上轉移到了學生的身上,給對評分不滿的學生提出了「自證」的要求。

論文作者通過實際踐行這一方法得到了積極的回饋,學生們從各個角度都認同了這種等級制評分方式。

所以在這裡,我想提出的問題就是,鄒老師在《構建之法》中提到的 1/N 體系是否太過於倉促果斷了,我們可以按照分檔給分的方式去衡量每個人的作業,但是在衡量具體的作業之前就將對應的等級的分數給出,如1/2,1/3等等,是否有點對學生的工作不負責任?在這裡我想表達的是,我相信每個學生都是認真完成作業並在作業的過程中帶有自己的思考的,可能有些地方做的確實不是很完美,但是是否應該按照同學在哪裡做的不夠好或者不足去具體的細分等級,而不是只要犯錯就立刻少了一半的分數,我相信這樣一種「狼性文化」,會在同學們剛開始的時候起到很好的競爭的效果,但是與此同時對於學生的打擊也是巨大的。

也算是斗膽對課程組提出自己小小的建議,不妨嘗試一下這種 Grade by Category的評分方式,可以給同學們的作業按照不足進行分檔,在等級內再進行細緻的給分,我相信這會是一個不錯的嘗試。

問題一:是否真的沒有銀彈

參見《構建之法》—— 第一章第2節

CD/DVD上但是這些非本質、臨時的特性並不能決定軟體工程的本質問題。例如,有人發明了一種新的程式設計語言,或者又出現了一個新的軟體開發流程,或者網上出現了又一個程式設計師技術社區……這些事並不能改變軟體工程的根本難度,這也是著名的「沒有銀彈(No Silver Bullet)」論斷所闡述的道理。軟體的這些本質特性讓「做一個好軟體」變得很難,同時也讓軟體工程有它獨特的挑戰和魅力。

首先我們看銀彈是什麼,根據維基百科上沒有銀彈的詞條
《沒有銀彈:軟體工程的本質性與附屬性工作》是IBM大型機之父佛瑞德·布魯克斯所發表一篇關於軟體工程的經典論文,該論述中強調由於軟體的複雜性本質,而使真正的銀彈並不存在;所謂的沒有銀彈是指沒有任何一項技術或方法可使軟體工程的生產力在十年內提高十倍。
布魯克斯在他的論述中將軟體開發的困難分為兩類,一是本質性的困難,是軟體本身在概念(conceptual)建構上存先天的困難;二是附屬性的困難,在於將概念上的構思施行於電腦上,所遭遇到的困難。並提出了四點造成本質性困難的原因:

  1. 複雜性(complexity):軟體要解決的問題,通常牽扯到計算步驟,這是一種人為、抽象化的智慧活動,多半是複雜的。
  2. 隱匿性(invisibility):尚未完成的軟體是看不見的,即使利用圖標說明,也常無法充分呈現其結構,使得人們在溝通上面臨極大的困難。
  3. 配合性(conformity):在大型軟體環境中,各子系統的介面必須協同一致。由於時間和環境的演變,要維持這樣的一致性通常十分困難。
  4. 易變性(changeability):軟體所應用的環境常是由人群、法規、硬體設備、應用領域等,各因素所彙集而成,而這些因素皆會快速變化。

雖然布魯克斯提出了四點困難的原因,但是為了提升軟體工程的生產力,也有許多人在奮力搜尋「銀彈」的存在,如從彙編語言到高級語言,大幅提升了生產力,降低了程式設計師的編程門檻;分是技術的出現提升了人們工作的效率,通過時間片輪轉等技術實現了程式的並行,同時不降低使用體驗等等。

除了沒有銀彈的聲音外,還有一些存在銀彈的反響,其中以 Brad Cox 的 《There is a Silver Bullet》 和 Divid Harel 的 《Biting the Silver Bullet》 為主要論點。

我自己的觀點是辯證地討論這個問題,這個問題需要結合實際的現實而不是在任何時候都可以揚言——「沒有銀彈」。我們知道軟體開發的生產力不僅被本質困難所影響,還被附屬困難所左右。今天我們之所以能夠站在這裡萬眾開發,就是因為先人們已經幫助我們一定程度上解決了附屬性困難。比如集成開發環境的產生使得所有人都能輕鬆運行和開發程式,比如面對對象編程的出現,使得所有人都能夠在構建和開發時編寫出更加理解易懂好維護的程式碼。所以說,Harel還提出的一項假象實驗,將沒有銀彈的說法發表在再向前三十年的1952年而不是1986年,在當時的外部附屬難度頗高的環境下,沒有人會預料到後續的三十年內人們將附屬困難逐一攻破,十年內軟體工程的生產力提高十倍很可能成為現實。
其次,我也非常同意Jones的觀點——「把重點放在品質上,生產力將隨之而來」。對於生產力的衡量不僅僅是量還有質。Jones提出,缺乏有系統的品質控制與發生時程落後的災難,這兩者之間有強烈的相關性。這就引出了我們所需要學習和思考的如何對團隊進行系統且有效的進度控制和品質控制
我之所以對銀彈是否存在持有懷疑態度是因為在大環境下,有一些本可以提高的生產力沒有提高,還有很多團隊會出現文檔與實現分離的情況,出現進度卡在某一個人負責的環節的情況,這些情況都是我們會在後續的團隊編程中可能會遇到的,所以我覺得現在就應該思考,如何在團隊中破除沒有銀彈的詛咒,提升團隊的整體水平和能力。

問題二:如何選擇合適的團隊模式

參見《構建之法》第五章第2節

體育團隊從一窩蜂搶球演變到有明確的分工、陣型、戰術的團隊,需要時間。類似地,軟體團隊的模式,最初是混沌的一窩蜂形式:一群人開始寫程式碼,希望能寫出好軟體。隨著團隊的成熟和環境的變化,團隊模式會演變成下面幾種模式之一。

對於本學期的重頭戲:Alpha 和 Beta 階段的團隊編程,心中既激動好奇又惴惴不安,以前從來沒有進行過任何大項目開發的我們,該如何打好第一次戰役?
在團隊的選擇中,我們首先是舍友三人組成了一個小的團體,一是對於大家的能力和責任心都比較放心,二是團隊中大部分人相熟可以迅速在團隊中破冰。後來加入了一位女生和兩位男生,組成了6人的團隊。但是問題是大家都沒有從事過軟體開發,這就給我們的團隊模式的選擇帶來了困擾。
結合我們目前的情況來看,由於沒有一個技術高手進行統領,比較實際的是在社區模式和業餘劇團模式中進行選擇,然而社區模式在我的理解下,是像Linux社區那樣的,需要原先就具有一定的基礎,結合一個成熟的審核團隊進行品質控制,所以剩下的只有業餘劇團模式,文中對於業餘劇團模式的描述確實比較業餘,在網路上也沒有找到相關的描述,想請教老師和助教,業餘劇團模式的具體形式能夠結合助教的經歷或是老師的觀察給一個更加清晰的講述嗎?

問題三:每日例會的效果如何?

參見《構建之法》第六章第2節

每天這樣寫程式碼,我們離衝刺的終點線到底是更近了,還是更遠了?如果流於形式,無論多麼敏捷的每日立會也會被忽悠[注釋5]。一個改進是,定義好任務究竟是什麼?任務的完成(Done)到底意味著什麼?每個人的任務必須是明確定義的,狗熊們不能籠統地說「我在掰棒子」,而是要說明標號為123的棒子現在是什麼狀態,你做好之後交給誰了。

在我的實習生活中,只遇到過周會,還沒經歷過緊張刺激的日會,每天完成的任務量有時候小到難以和前一天區分開的時候,我們真正能從日會中獲得什麼嗎?比如現在我們除了軟體工程之外,還有電腦網路、電腦網路實驗,幾乎每位同學還有額外的兩三門一般專業課,當時間真的一天18個小時不夠用的時候,我們的例會可能發言就變成了「我和昨天一樣在掰棒子」甚至是「今天沒有動程式碼」。我非常擔心我們團隊到了後期也會出現這種問題,我相信我們的團隊每一個人都不是渾水摸魚的類型,但是時間管理方面出現嚴重的缺陷時,我們該如何應對?
這是我特別想向老師和助教請教的一個問題

由這個問題引申出的一個問題:敏捷開始是否是一個偽命題?
在我閱讀第六章的內容前,這個疑問一直在我的腦海,我觀念裡面的敏捷開發,就是三點:一是快;二是快;三還是快。這種快速可能會帶來品質上的損失,比如《構建之法》的圖6-5,大量微博用戶反映自己的微博丟失的情況。但是當我看到第六章最後的「酒後問答」,很多我的疑問都被老師一一解答了。
敏捷開發確實是快,但是並不是只要參與了敏捷開發,原本工期長的項目就可以立刻得到縮短,最後提前完成。用老師的回答來說——「敏捷的方法能幫助你更早地知道你是否能如期完成任務,僅此而已。敏捷的方法(迭代的方式)能幫你儘快讓用戶看到項目的部分價值。當你儘早交付部分價值時,也許用戶對你目前交付的東西已經很滿意了,這樣你就不用再花時間來實現其他需求。另一種可能是,用戶看到了部分系統,他們有新的需求,這樣你就可以實現新的需求,而不用再浪費時間實現過時的需求了。」
老師的回答和輪子哥在知乎上的回答有著異曲同工之妙。敏捷不是一群開發者對著甲方的第一版需求猛做幾天,而是在做的過程中始終和甲方進行有效的、不間斷的溝通,來幫助甲方更加清晰地認清自己的需求,也幫助整個團隊確定一個當前的完成進度,也就是一個迭代中的需求分析和驗收

問題四:為什麼除了微軟很少見到Program Manager

參見《構建之法》第九章第1節

Program Manager:微軟的職位名稱。微軟產品團隊三足鼎立的角色分配就是PM、開發、測試。PM負責除產品開發和測試之外的所有事情。從某種意義上說,是前面兩種角色的綜合。微軟通常有專門的產品策劃(Product Planner),他們和市場部門的專職人員一起,負責產品的長期發展和市場推廣。

在第九章中提到了PM,有三種含義,分別是 Product, Project和 Program Manager。作者也在書中提到,其中的Program Manager 是微軟的三駕馬車之一,另外兩個分別是測試和開發。我又在網路上搜尋了有關Program Manager的資料,發現這個程式經理依然是微軟的特色之一,不禁思考,為什麼其他的公司不效仿微軟,將Product Manager 升級為 Program Manager呢?

對此,我首先看了一下微軟的員工眼裡兩者的區別,其中,作者說道:「最基本的一條是程式經理不承擔人員和資源的管理任務。微軟通常把技術路線稱為Individual Contributor,而把管理路線稱為Management。而程式經理在職業規划上屬於前者。」 此外,該作者還總結了程式經理的任務:

  1. 負責和提出需求的客戶打交道,並且負責撰寫功能規範,也就是Product Feature Spec。
  2. 協調部門間的合作關係。

但是在看了這些資料之後,我還不是特別能夠區分開兩者的區別,希望老師和助教能夠給我提供一個具體的樣例,即程式經理有什麼是產品經理做不了的,有什麼是產品經理能做而程式經理做不了的,有沒有除了微軟的其他公司也設立了 Program Manager 這一個職位,這家公司和微軟有什麼相似的地方?

問題五:對於小團隊而言小強地獄是否可行?

參見《構建之法》第十一章第5節

隨著項目的深入,每個人同時既要開發新的功能,也要修復以前的缺陷。由於沒有明確的優先次序,一般人都願意把時間花在開發新功能上。但是我們的確需要平衡進度和品質。有這樣的一種方法:小強地獄(Bug Hell)。如果開發人員的小強(Bug)數量超過一規定值,則此君被送入「小強地獄」,在地獄中,他唯一能做的就是修復小強,直到小強數量低於此閾值。這一閾值由團隊根據實際情況來確定,要注意:開發人員同時「入獄」的人數應在全體成員的5%——30%之間,若比例太高,則要考慮閾值或小強數量的計算方式是否合理(是否只包括某一嚴重程度以上的Bug)。在項目過程中,閾值不宜頻繁調整,最好事先宣布閾值。

從這個團隊的例子中我們可以看到很多人身上的影子——如何處理待開發的新功能已存在的Bug?相信很多人在編寫C/Cpp程式的時候,都會先寫完所有功能,然後再進行覆蓋性的測試,去找出所有的bug。但是當我們是以一個團隊的身份開發一個項目的時候,不同點在於我們不再是單打獨鬥,我們有專門的一部分人負責測試工作,如果像書中的例子一樣開發人員也是一味追求新功能而將自己的bug都藏著掖著,就會導致測試人員進度了等待的狀態。
這裡提到的小強地獄確實很美好,他將每個人產生的小強的個數限定在一個提前設定好的閾值之內,每個人的bug數目只要達到閾值就要開始專門的修復bug階段。這種方案對於大型團隊而言無可置疑是高效的,但是對於一個小型團隊而言,這種小強地獄的方案是否會對整個項目的進度帶來嚴重的影響?或者我們是否可以讓測試也承擔起一部分修繕bug的責任

網路上對於小強地獄這種工作方式寥寥無幾,所以希望有豐富的經驗的老師和助教們能以自身的經歷或者見聞解答一下我的這個疑惑——「小強地獄對於小型開發團隊團隊而言適合嗎?如果不適合,有什麼其他的適合方案呢?如果適合,如何解決開發至多三人帶來的團隊進度被影響的問題呢?」

問題六:迷思之六:技術的創新是關鍵?

參見《構建之法》第十六章第1節

銥星有用戶么?當然有,那些登山運動員,在南極科學考察的人士,想隻身駕船週遊世界的孤膽英雄們,他們希望有一部這樣的電話。但是這樣的用戶在全世界有多少呢?銥星電話現在變成了一項租賃業務,為這些幾千、幾萬的用戶提供短期服務。與此同時,全世界的手機用戶早已突破了10億。

作者在這裡舉出的例子是銥星計劃(Iridium)的手機,論述的是銥星計劃雖然有技術的創新但是沒能成功,在這裡我有一點小小的疑惑。因為對銥星計劃不是非常了解所以就查了一下。

對於摩托羅拉的工程師巴里·伯蒂格來說,它來自於妻子在加勒比海度假時的抱怨,說她無法用手機聯繫到她的客戶。回到家以後,巴里和摩托羅拉在亞利桑那州工作的衛星通訊小組的另外兩名工程師想到了一種銥星解決方案——由77顆近地衛星組成的星群,讓用戶從世界上任何地方都可以打電話。由於金屬元素銥有 77 個電子,這項計劃就被稱為了銥星計劃,雖然後來衛星的總數降到了 66 個。
——來自百度百科對銥星計劃的介紹

我分享一下我的感受:技術的創新我依然認為是關鍵,銥星計劃的失敗只不過是沒有把握住最好的時機。如果銥星計劃能夠早那麼10年,我相信又是另一幅格局。用戶基數一旦形成就難以撼動,不是技術不夠創新,而是很大程度上由於人的惰性造成的,人們不願意踏出舒適區去為了一點點微小的利益而改變,倘若摩托羅拉的銥星計劃能夠比基地台通訊更早地俘獲大量的用戶並且穩定用戶,我相信銥星計劃還是能夠成功的。而且銥星計劃也沒有完全失敗,說不定在未來又有他的出彩之處,如果能夠基地台和銥星結合起來,相互補充,我相信這將是通訊歷史上濃墨重彩的一步。

問題七:最難的問題——排座次

參見《構建之法》第十七章第3節

一群人在一起做事,事成之後,就有排座次、論功勞的問題——在有些團隊里,事成之前就為功勞的事吵翻了。軟體團隊如何做人員的績效管理?這個問題較難回答,因為所有人的工作被集成在一個軟體產品中,互相依賴,產品功能受到用戶讚揚或批評,都不能簡單地完全對應於某一個人的工作。

在《構建之法》的最後一章的內容中,還是提到了無法迴避的問題,如何給團隊裡面的人排座次。作者通過多個角度論證了座次的排列不能但從一個角度,而是多個角度一起考慮的結果。最後給的二維評價考核表特別有趣,我覺得是一種非常新穎而且值得嘗試的方式。但是這些方式都是一些比較偏理論的,那如果在比如我們這種軟體工程的課程裡面,和同年級的同學組成的小組裡面進行貢獻度分配的時候,有什麼具體的實用的方式嗎?我也參考了知乎上的回答,但是上面所羅列的 KPI (Key Performance Indicator) 關鍵業績指標法、BSC(Balanced Score Card) 平衡記分卡、OKR (Objectives and Key Results)目標與關鍵成果法 和 360度考核法 雖然特別完善和強大,但是對於小型團隊而言似乎又太過於專業化了,而且會帶來額外的巨大的工作量,所以想請教一下助教們,當初你們在完成軟體工程這門課的最後是如何進行小組內的考核評比的呢?

「軟體」 和 「軟體工程」 這些辭彙是如何出現的 – 何時、何地、何人?

軟體:從維基百科中可以看到「軟體」一詞最早在 Turkey 於 1958 年所發表的 "The Teaching of Concrete Mathematics" 一文中被使用。

軟體工程:在對Margaret Hamilton的專訪中,我們得知,是她在編寫阿波羅登月計劃的項目期間創造的軟體工程一詞。Margaret Hamilton 致力於為軟體以及那些發明者爭取應有的正統性與尊重,所以開始使用「軟體工程」這樣的字眼來將之與硬體還有其他工程學類做出區別。

關於軟體工程的小故事

世界上第一個電腦病毒

世界上第一個病毒是由巴基斯坦兄弟倆巴斯特(Basit)和阿姆捷特(Amjad)在1987年寫下的,但他們寫出這個病毒並不是為了去損害別人的利益,恰恰相反,是為了維護自己的利益
兩兄弟開了一家電腦公司,主要經營電腦和軟體業務。剛開始的時候公司經營非常好,生意興隆,但是慢慢的,市面上浮現出了盜拷的行為,導致他們辛苦寫的程式被別人廣泛傳播,於是兄弟兩人從父親往魚塘裡面丟樹枝防止別人撒網偷魚的做法中得到了靈感,編寫了第一個病毒軟體。一旦他們的發行程式被盜拷,這個病毒就會在電腦中發作,將盜拷者電腦剩餘的記憶體空間全部佔據,這使得不少盜拷的人因為電腦無法使用來向他們認錯,請求他們幫助修復電腦。他們一不留神寫下了世界上第一個病毒,人類與電腦病毒之間的較量由此展開。

Linus & Git

參考資料:Linus 在 2007 年 Google Talk 上介紹 Git

Linus 相信沒有學習電腦專業的人不認識的,獨自開發Linux系統,開發了Git源程式管理軟體,性格乖戾脾氣暴躁,都是他的tag。2005年的時候,Git還沒誕生,Linux內核程式碼託管在 BitKeeper 上,Linus 本人對 CVS 十分厭惡,但是對 BitKeeper 鍾愛有加。他認為 BitKeeper 的工作流和分散式等理念是值得學習和嘗試的。但是由於 BitKeeper 是一款商業軟體,Linux 是一款開源的工作,為了防止情況的惡化(此處也沒找到具體的是什麼惡化),於2005年的時候 Linus 發布了 Linux-2.6 ,於是開始自己開發一個 BitKeeper 的替代品。也就是說,如果不是BitKeeper 和 Linux 的一些不合,可能大家就不能看到 Git 的誕生了。對於Linus 給軟體的起名也特別有趣,Linux系統是Linus一開始起的名字,在發布的時候Linus曾經想過換一個名字,但是被旁人制止,覺得使用自己的名字作為一款系統的名字比較有意義。而對於第二款Source Code Management 源程式碼管理工具——Git,則是英國俚語中「壞小子」的意思,Linus也曾經說過,自己是一個傲慢的混蛋,所以他的創作都用自己起名,Git也不例外。

源程式管理軟體和項目管理軟體調研

軟體 使用人數 優點 缺點
Git Unknown 1. 分散式
2. 輕量
3. 可以和其他倉庫(如 GitHub GitLab Gitee)結合使用
4. 可以隨時隨地離線使用,聯網時再update
1. 上手困難
2. 出現偏差時難以糾正
3. 指令太多,部分指令的表現與理解存在偏差
GitHub 31,000,000 1. 是當前最大的開源免費程式碼倉庫,現在private倉庫也免費使用
2. 提供開發者一個交流合作的平台,通過pr和issue幫助擁有者維護開源程式
3. 還提供了發布的模組給開發者進行發布的版本管理
主要適合於程式碼的追蹤,而不適合創意的記錄
Bitbucket 5,000,000 1. 一直提供無限免費私有倉庫
2. 對hg和git都支援
3. 支援中文
4. 第四方的git工具SourceTree比GitHub for Windows好用
1. 功能相比Git少很多
2. 對於開源不夠徹底
Mercurial (hg) Unknown 1. 學習門檻低,比git容易上手
2. 能夠實現完全回到某個歷史版本
3. 具有SVN的影子,對SVN用戶友好,零學習成本
1. 分支管理不靈活,對於大一些的團隊項目會造成許可權混亂
2. 分支種類過多,匿名分支法、具名分支法、書籤法、克隆版本庫法等等,不方便使用
3. 沒有命名空間,團隊中誰提交的程式碼搞不清楚
Trac Unknown 非常靈活,可以隨心所欲控制可以和SVN集成 功能不是很強大
Bugzilla Unknown 免費,有中文版支援 快速搜索結果不準確。只能管理缺陷。
Microsoft TFS Unknown 1. 微軟出品,和Visual Studio深度結合
2. 任務版內容詳盡,有需求和任務進度等,對小團隊而言更加方便有效
3. 集成了項目管理、版本控制、BUG 跟蹤等特性
1. 上手困難,搭建和維護TFS複雜
2. 基於ASP實現,訪問相比而言慢一些

源程式管理軟體上手實踐

Git

首先肯定是最常用的 Git:
git add commit push
git checkout branch
git reset HEAD^

Git 是 Linus 為了更好的控制自己的 Linux 源程式碼的管理而創新出來的管理工具,其核心思想是充分的分散式,特性之一是允許離線操作。Git 通過將工作區分為三棵樹的方式來管理自己的程式碼進度。
第一棵樹是自己的 工作空間,修改程式碼肯定首先是在自己的工作空間發生變化;
第二棵樹是 暫存區,是一個臨時保存的區域,需要通過 git add file/dir 的命令來將自己的工作空間中的修改保存到暫存區;
第三棵樹是 HEAD, 始終指向最後提交的結果,運行 git commit -m "explanation words" 來講暫存區下的修改提交到 HEAD上;
三棵樹保證了Git是一個可以本地離線運行的源程式管理工具,開發者可以隨意回到之前的任意一個 commit 的版本中去。
最後在在線的狀態下,可以通過 git push 將本地的HEAD提交到遠端的倉庫中,保存本地的修改。

這種思想對於初學者來說簡直就是災難。我在一年前學習面向對象和作業系統的時候才開始接觸Git,一開始上手太難理解為什麼要構建三棵樹了,覺得為什麼不直接本地保存然後同步到線上呢?但隨著使用的時間的推移也發現了這種構建的好處,特別是可以回到任意一個commit是開發者的福音。還有 Git 的 branch 也是對於項目開發特別友好的設計,可以生成 Debug、Release、Develop 等等分支,在分支上進行隨心所欲的操作,都不會對主分支造成任何的影響。
今年有幸擔任了面向對象課程的助教,在第一周的上機實驗中,從學弟學妹們的身上看到我自己的身影。沒有經歷過 git push 不被允許的報警是不完整的 很多人一個實驗兩個小時也完不成基本的 Git 操作,要麼在分支上出現了問題,要麼在關聯的遠端倉庫上出了問題,要麼在ssh_key 上出了問題,等等等等。
如果單純能夠使用 Git 的話,學習並且使用一段時間就熟練了,但要是想徹底弄懂 Git,估計需要 Linus 的智商吧。

Mercurial(hg)

既然 Git 這麼勸退,我們就嘗試一下據說門檻低,較易上手的 Mercurial
關於 Git 和 hg 的對比,為什麼 hg 比 Git 好上手,這個部落格是我找到的最完整的介紹。
hg init

嘗試了一會兒 hg,註冊了 BitBucket 的帳號,但發現貌似 BitBucket 現在全面支援 Git 了,半天愣是沒有找到如何使用 hg 初始化倉庫,於是從 hg Guide 中 clone 了一個hg說明書的倉庫使用。
在已經對 Git 熟悉之後,對 hg 上手是特別快速的,要說有什麼特別的地方,hg 也有自己的 hg addremove xxxgit add xxx 非常相似,兩者的 commit 都是一樣的,但是經過我的查閱之後發現,是因為我現在的倉庫規模不夠大所以感受不到 hg 的方便之處。
hg 的優勢經過總結有以下幾點:

  1. hg 給用戶的資訊較為友好、輕便。比如 hg log 查看日誌的功能就特別簡單清新,比如:

     changeset:   0:2b106112869d   user:        q2l   date:        Sun Mar 08 01:59:07 2020 +0800   summary:     add one add three

    與 Git 的 SHA-1 編碼製作的 commit_id 相比顯示簡單,但這裡 Git 裡面蘊含了 Linus 的個人的執念——「通過SHA編碼可以讓你未來任何時候都能回到你想要的任意一個版本」。

  2. hg 提供了很多繼承的命令,比如 hg update, hg ci, hg serve 等等,可以直接使用,其中我嘗試了以下 hg serve,如果倉庫是網站,可以直接部署到 localhost 上,如果不是網站則可以來顯示這個倉庫的有關資訊,比如可視化的 branch 和 commit 等等。
    hg serve

可能對於每個人的習慣不一樣選擇的工具也是不一樣的,在查閱hg 和 git 的對比和優缺點的時候,既有放棄hg轉向git的,也有從git到hg的,但現在總體的大趨勢是更多的源程式碼管理倉庫偏向git,比如 bitbucket、github、gitlab,而hg已經被 Atlassain 收購,主要和 Atlassain下的工具進行集成。總之選擇自己喜歡的就行,也不是有很多喜歡 Git 的死對頭 CVS 嗎?

參考鏈接

  1. 鄒欣 | 現代軟體工程講義
  2. 周舜欽:學習金字塔的誤解
  3. Grading by Category
  4. 維基百科 | 沒有銀彈
  5. 《There is a Silver Bullet》
  6. 《Biting the Silver Bullet》
  7. Assessment and Control of Software Risks
  8. 所謂的敏捷開發是一個坑嗎? – vczh的回答
  9. 微軟的program manager主要要求什麼樣的核心素質
  10. 常用的四大績效考核方法以及優缺點
  11. Git 有哪些缺點?
  12. 一不留神 這對兄弟搞出了全球第一個電腦病毒
  13. Linus 在 2007 年 Google Talk 上介紹 Git
  14. 就是她,寫出了讓阿姆斯壯成功登陸月球的程式碼!
  15. Wikipedia | Comparison of source-code-hosting facilities
  16. git – 簡明指南
  17. 為什麼比 GIT 更好--理解 Mercurial 版本管理系統