初啟(軟件工程第一次閱讀作業)


1. 快速看完整部教材,列出你仍然不懂的5到10個問題,發布在你的個人博客上。

2.1.2 “單元測試必須由最熟悉代碼的人(程序的作者)來寫

      並不認同這里這個“必須”。在我自身實習的經驗中,一般都會采用開發和測試分離的模式,即大家在構思設計的時候約定好公共的接口模式,然后並行開始開發和測試程序的構建,大家公共的部分就是統一的接口,測試人員不需要知道內部的實現細節,而且根據接口來構造一系列的強覆蓋邏輯,保證接口對正常功能和異常功能都能正確處理。這樣做一提高了效率,二是測試不會被開發的設計思路所束縛,完全從一個外部的角度來思考,這樣設計測試樣例一般會更全面。
    不過寫到此處想到另一個問題:完全不了解內部細節,那可能會出現覆蓋不到接口內部分邏輯的情況,有可能有隱藏的分支並沒有覆蓋到,留下了隱患。還有就是接口內部一些可能產生的副作用也不能及時發現,這的確也是存在的問題。

10.3 規格說明書

     關於規格說明書我有一個一直以來的疑問,就是規格說明書-注釋-代碼之間的聯系和配合,嚴格來說,他們之間有很多重復的內容,好的代碼風格本身就有一定的說明作用,注釋是程序員最好的助手,文檔又是真正開發不可或缺的一部分,如何構建一種最合適的模式,使得每個層次都有合理的功能而有不冗余呢。

16.1.5 迷思之五: 要成為領域的專家,才能創新

      在目前的環境下,僅僅成為領域的專家,似乎並不太足夠了。在各行各業都高度專業化的今天,各個行業領域之間的壁壘也越來越重,很多領域的專家往往會不知不覺地局限於自己的領域,所以說,領域專家只是一個創新的必要條件。那么在現在的環境下,交叉學科似乎正在成為新興的創新爆發點,借鑒其他學科的思路的觀點,結合本領域的知識,將會產生更多的可能。深度學習中的很多優秀設計便是來源於神經科學,比如神經元的基本模型,還有生物學,比如借鑒人的視網膜細胞來組織新的卷積層,結合大腦的計算模式來構建新的高度並行化的神經網絡芯片。

2.請問 “軟件” 和 “軟件工程” 這些詞匯是如何出現的 - 何時、何地、何人?

軟件: 這個詞是在1958年,由John Tukey在其論文"The Teaching of Concrete Mathematics"中提出的

Tukey's 1958 paper "The Teaching of Concrete Mathematics"[10] contained the earliest known usage of the term "software" 

軟件工程: 這個詞是在1969 年(阿波羅 11 號期間),由Margaret Hamiltion提出的

 

Q:你是在這段期間發明了“軟件工程”一詞嗎?

A:軟件在這個計划的初期還被當作初初學步的孩子一般對待,完全不像其他工程學科;例如像硬件工程那樣的受到重視,而且在大家的眼光中他就像是藝術、魔術一般,而不是一門科學。

我一直以來堅信這項發明流着藝術與科學的血液,雖然當時很少人是這么想。因此,我致力於為軟件以及那些發明者爭取應有的正統性與尊重,所以我開始使用“軟件工程”這樣的字眼來將之與硬件還有其他工程學類做出區別。

3.大家知道了軟件和軟件工程的起源,請問軟件工程發展的過程中有什么你覺得有趣的冷知識和故事?

  1. 豐田的一萬多個全局變量的故事。28萬行代碼中有1萬多個全局變量,簡直就是bug培養基。
    其中還有人專門做過測試。
    軟件設計的基本要求是模塊盡量簡單化,因為這樣可以一來更易於閱讀二來更易於維護,但豐田的工程師顯然沒有遵循這原則。Barr使用一種工具自動根據代碼的可能分支數量評估函數的復雜度,結果是豐田的軟件中至少有67條函數復雜度超過50,意味着運行這個函數可能出現超過50種不同的執行結果,屬於“非可測”級別。因為為了測試這50個不同的結果,必須准備至少50條不同的測試用例以及相應的文檔,在生產環境中是根本不現實的。而在這67條函數中還有12條復雜度超過100,達到“非可維護”級別,意味着一旦發現缺陷(Bug)也無法修復,因為實在太復雜,修復缺陷的過程中會產生新的缺陷。其中最復雜的一條函數有超過1300行代碼,146個可能執行路徑——正好用於根據各傳感器數值計算節氣門開關角度。

4.上網調查一下目前流行的源程序版本管理軟件和項目管理軟件都有哪些, 各有什么優缺點?

下表是2018年源代碼托管軟件的用戶數和項目數,出自https://en.wikipedia.org/wiki/Comparison_of_source-code-hosting_facilities#Popularity

從中可以看到一般最熟悉的git(github,gitlab)還是占據了最主要的部分,下面是幾大主流軟件的優缺點對比。

Git

優點:

  • 免費且開源。
  • Git支持分支功能(branch)。如果開發一個新的產品功能,可以建立一個分支,對這個分支的進行修改,而不至於會影響到主支上的代碼。或者是fork。
  • 可拿Git做備份系統,或者同步多台機器的文檔,很方便。
  • 支持離線工作,有本地倉庫和遠程倉庫。本地提交可以稍后提交到服務器上,不用和集中的代碼管理服務器交互。 只有最終完成的版本才需要向一個中心的集中的代碼管理服務器提交。
  • Git 提交都是原子的,且是整個項目范圍的。
  • Git 中的每個工作樹都包含一個具有完整項目歷史的倉庫,還原和版本回退非常方便。
  • P.S. 推廣一下自己寫的git簡易教程 https://github.com/OO-guide-2019/git-guide

缺點:

  • 學習成本大。由淺入深的過度很漫長,需要大量時間的投入。(有合適的教程其實很快)
  • Git版本庫需要頻繁的手動維護。

SVN

優點:

  • 對目錄的組織的管理更加方便。SVN不光對文件做版本跟蹤,也會對目錄做版本跟蹤。因此可以根據項目的需要,對目錄結構隨時進行修改,可以把現有的目錄移動到新的地方。
  • 保證提交操作的完整性。SVN對提交操作的處理方式類似數據庫的事務處理,要么全部成功,要么全部無效,保證了原子性。
  • SVN允許一個文件有任意多的可命名屬性,功能十分完全。

缺點:

  • 不能離線工作。所有的版本信息都放在服務器上。如果脫離了服務器,開發者基本上可以說是無法工作的。
  • 提交、更新、瀏覽歷史的速度慢。耗費CPU資源。
  • 代碼不能及時提交。強迫使用者即時處理沖突,然后才能提交。
  • 不能恢復到歷史版本。SVN記錄了單個文件的歷史版本,但沒有記錄全局版本,不能恢復到上次的狀態。這一點是很致命的。

Microsoft TFS

優點:

  • 任務版上能將需求、項目進度一覽無余,集成了項目管理、版本控制、BUG 跟蹤。
  • 能有效實現 SCRUM,能與 VS 無縫接合。

缺點:

  • 搭建、維護tfs比較復雜,硬件要求也比較高。
  • 整個系統是用 asp 實現的,用瀏覽器訪問較慢。

Mercurial

優點:

  • 學習門檻較低。整體上看,hg需要掌握的命令要比git少很多。
  • 可以一鍵完全恢復到某一個歷史版本。
  • 封裝好。相比git,hg很少暴露一些實現內的細節。
  • 照顧 svn 的遷移用戶。hg 的很多命令是遷移自 svn 命令的,習慣 svn 命令的團隊,幾乎可以零成本的切換到 hg。
  • hg的版本庫不需要維護。

缺點:

  • 分支管理不靈活。Mercurial的branch管理和Git相比不是很方便。不適合大型團隊使用。

5.關於版本控制軟件的個人理解

目的:版本控制軟件的目的主要是兩點,版本記錄控制,團隊協作

從使用者角度來看,一款好的版本控制軟件需要滿足如下的需求:

  •  簡單易學易上手,這一點需要建立在軟件本身指令的設計,與操作系統shell命令的結合,詳細但又不啰嗦的教程,以及面向真正開發需求的實踐練習。就拿git來說,很多入門者覺得痛苦的一個重要因素就是其對基本shell命令本就不太熟悉,對於命令行式開發和運維相關熟練度遠遠不夠,而同時目前的教程更像是一部工具說明書,即以各個命令本身為基本單元,而不是git工作的整個流程,所以就會帶來一種割裂感,此外,沒有真正意義上的對於整個git協同開發的練習,單單看教程記憶自然不能熟練掌握(所以也就有那么多人吐槽git學起來難)
  • 支持強大的版本控制操作,對個人來說,主要的需求有兩點,一是不同版本路線的開發,即多個branch的開發,每個branch負責一種設計思路,二是能夠方便的回退到某個版本,換句話說就是強大的存檔讀檔功能,而對團隊來說,協作就是最重要的點,以git為例,在團隊開發時以fork為主,每個人的修改要想整合進來必須經過pull request,這樣的機制就使得每個人可以各司其職,減少了造成沖突的可能性。就算是在一個分支中出現了merge時的沖突,git也提供了良好的沖突處理機制,更有git rebase這種高級操作,使得處理起來非常方便。
  • 支持網頁查看,對於閱讀源代碼和配置文件,不一定需要笨重地每次都clone到本地倉庫一份,像github和gitlab提供的網頁界面閱讀代碼,使得這個過程變的非常輕便。
  • 對於大文件的管理,在開發大型項目的時候,我們可能會生成一些幾十甚至幾百MB級別以上的文件,那么像基本的github就不支持這樣的大文件傳輸,但有的時候我們確實需要將其托管在遠程倉庫進行管理,這時,像git-lfs這樣的工具便可以提供非常舒適的體驗(強烈推薦)

從版本控制軟件設計者來看,其需要考慮的因素如下:

  • 對功能的封裝,解耦合(抱歉我是git吹),考慮一個項目內,可能有正在編輯的文件,可能有已經編輯好的文件,可能有遠程服務器上的文件,如果一視同仁,其實會非常混亂,但是像git這樣的設計,工作區,暫存區,本地倉庫,遠程倉庫,將復雜的事情解耦成為幾個不同的階段,就非常清楚。
  • 面向安全的封裝,對於內部的具體實現,是否暴露給用戶,這一點需要考慮,暴露給用戶的話可以支持更多的開發者,但是也帶來了一定程度上的安全風險
  • CPU等本地硬件資源的消耗和傳輸速度保證,比如大家都可以發現,git clone/pull/push都是使用多線程來操作的,如何利用好本地硬件資源且不帶來過度的負擔,也需要認真考慮
  • 本地和服務器的關系,一般來說我們希望本地可以直接工作,斷網時也可以本地版本控制,另一方面,服務器上也可以進行修改,不依賴本地。不過現在網絡傳輸基本不會出現什么問題。
  • 圖形化界面,可能是因為基本使用命令行的緣故,所以git的GUI十分丑陋。。。
  • 數據的分析和統計,在github和gitlab有很多對於項目開發情況的可視化數據統計,這對於一個團隊的開發也是很棒的信息。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM