(1)Fork github 項目https://github.com/Cherish599/WordCount到本身的倉庫,在Github倉庫中新建一個以一位同窗的學號爲名的文件夾,用於創建C#的項目和第二次做業相似。(結對的兩人中任意一人的學號均可以)。html
(2)在開始實現程序以前,在PSP表格[附錄1]記錄下你估計在程序開發各個步驟上耗費的時間,在你實現程序以後,在PSP表格記錄下你在程序的各個模塊上實際花費的時間。git
(3)使用C#語言實現,C#請使用Visual Studio Community 2017進行開發。github
a) 制定編碼規範,能夠參考C#語言的規範:簡版,討論版。(鄒欣老師在講義「現代軟件工程講義 3 代碼規範與代碼複審」中所討論的有關代碼規範與代碼複審的內容。內容短小精煉,適合快速入門。)算法
b) 代碼自審並修正,每一個人都獨立完成了本身的功能任務,對照編碼規範,審查修改本身的程序代碼並使其符合規範要求。編程
c) 代碼互審,按照共同制定的編碼規範,審查合做夥伴的代碼並記錄發現的問題。windows
d) 合併代碼,兩人協商,將兩部分代碼合併,造成初始版本。注意應設計合理的軟件結構及模塊劃分。架構
e) 提交的代碼要求通過Code Quality Analysis工具的分析並消除全部的警告。框架
f) 完成項目的首個版本以後,請使用性能分析工具Studio Profiling Tools來找出代碼中的性能瓶頸並進行改進。ide
g) 使用Github[附錄2]來管理源代碼和測試用例,代碼有進展即簽入Github(至少三次)。簽入記錄不合理的項目會被助教抽查詢問項目細節。函數
h) 使用單元測試[附錄3]對項目進行測試,並使用插件查看測試分支覆蓋率等指標;並寫出至少10個測試用例確保你的程序可以正確處理各類狀況。
i) 在完成結對項目後,請按照預第二次做業的方式正確地發起一個Pull Request,並設置標題爲本次統一使用的學號。
(1)在文章開頭給出結對使用的Github項目地址和結對夥伴的做業地址。(兩我的使用同一個)注意:GitHub的地址必須是用於clone的地址即以下圖片中的地方獲取。(若是不是這個地址,助教就沒法批量編譯運行大家的程序,出現問題的都會被助教抽中詢問詳情)
(2)描述結對的過程,提供非擺拍的兩人在討論的結對照片(一塊兒工做編碼時的照片)。
(3)給出結對的PSP表格。
a) 解題思路描述。即剛開始拿到題目後,如何思考,如何找資料的過程。
b) 設計實現過程。設計包括代碼如何組織,好比會有幾個類,幾個函數,他們之間關係如何,關鍵函數是否須要畫出流程圖?單元測試是怎麼設計的?
c) 給出大家制定的代碼規範或連接,記錄大家代碼互審的狀況,審查的模塊名、發現的問題等。
d) 記錄在改進程序性能上所花費的時間,描述你改進的思路,並展現一張性能分析圖(由VS 2017的性能分析工具自動生成),並展現你程序中消耗最大的函數。
e) 代碼說明。展現出項目關鍵代碼,並解釋思路與註釋說明。
f) 結合在構建之法中學習到的相關內容與結對項目的實踐經歷,撰寫解決項目的心路歷程與收穫,以及結對感覺,是否1+1>2。
注:兩人都要提交博客,結對共同部分,可在其中一我的的博客給出(另外一我的給出連接),不一樣部分分別寫在本身的博客中。
實現一個命令行程序,不妨稱之爲wordCount。
第一步、實現基本功能
輸入文件名以命令行參數傳入。例如咱們在命令行窗口(cmd)中輸入:
wordCount.exe input.txt
則會統計input.txt中的如下幾個指標
· characters: number
· words: number
· lines: number
· <word1>: number
· <word2>: number
· ...
第二步、接口封裝
在寫了一些代碼開胃以後,你們都完成了一份知足基本功能的代碼。
你們的代碼都各有特點,若是如今咱們要把這個功能放到不一樣的環境中去(例如,命令行,Windows圖形界面程序,網頁程序,手機App),就會碰到困難:代碼散落在各個函數中,很難剝離出來做爲一個獨立的模塊運行以知足不一樣的需求。
同時咱們也看到,不一樣的代碼解決不一樣層面的問題:
a) 有些是計算數據的(例如統計單詞)
b) 有些是控制輸入的(例如ReadLine,圖形界面的輸入字段)
c) 有些是數據可視化的(例如WriteLine)
d) 有些則更爲特殊,是架構相關的(例如main函數,並非全部的程序都須要某個特定格式的main)
這些代碼的種類不一樣,混雜在一塊兒對於後期的維護擴展很不友好,因此它們的組織結構就須要精心的整理和優化。
咱們但願把基本功能裏的:
a) 統計字符數
b) 統計單詞數
c) 統計最多的10個單詞及其詞頻
這三個功能獨立出來,成爲一個獨立的模塊(class library, DLL, 或其它),這樣的話,命令行和GUI的程序都能使用同一份代碼。爲了方便起見,咱們稱之爲計算核心"Core模塊",這個模塊至少能夠在幾個地方使用:
a) 命令行測試程序使用
b) 在單元測試框架下使用
c) 與數據可視化部分結合使用
把計算核心在單元測試框架中作過完備的測試後,咱們就能夠在算法層級保證了這個模塊的正確性。
但咱們知道軟件並不是只有計算核心,實際的軟件是交付給最終用戶的軟件,除了計算核心外,還須要有必定的界面和必要的輔助功能。
這個Core模塊和使用它的其餘模塊之間則要經過必定的API來交流。
API應該怎麼設計呢?
爲了方便起見,咱們能夠從下面的最簡單的接口開始(僅舉例,你的代碼裏可能沒有這個函數):
public int countChar(String path)
這個函數表示輸入path文件路徑字符串,返回這個文件的字符數。
假設咱們的Core裏封裝了這個接口,那麼咱們的測試程序能夠是這樣:
String path = "input.txt";
int count = 100;
Assert(countChar(in) == count);
固然,這樣的測試程序並不充分,但願你們測試時不要像這樣偷懶。
第三步、增長新功能
在第三步中,咱們但願各位在第一步的基礎上,添加一些新的功能:
a) 詞組統計:能統計文件夾中指定長度的詞組的詞頻
b) 自定義輸出:能輸出用戶指定的前n多的單詞與其數量
(1).-i 參數設定讀入的文件路徑
格式以下
wordCount.exe -i [file]
一個例子如:
wordCount.exe -i input.txt
(2).-m 參數設定統計的詞組長度
格式以下
wordCount.exe -m [number]
詞組定義:m個由分隔符隔開的單詞組成一個詞組
-m參數與數字配套使用,用於設置詞組長度
命令行中使用-m參數,例:
wordCount.exe -m 3 -i input.txt
/*
*要求程序統計input.txt中長度爲3的詞組,最終輸出
*例:input文件中內容爲"Monday Tuesday Wednesday Thursday"
*則輸出以下
*/
characters: 33
words: 4
lines: 1
Monday Tuesday Wednesday: 1
Tuesday Wednesday Thursday: 1
(3)-n參數設定輸出的單詞數量
格式以下
wordCount.exe -n [number]
-n參數與數字搭配使用,用於限制最終輸出的單詞的個數
表示輸出最多的前[number]個單詞
命令行中使用-n參數,例:
wordCount.exe -n 1 -i input.txt
/*
*程序會輸出文件中出現次數最多的那個單詞
*/
(4) -o 參數設定生成文件的存儲路徑
格式以下
wordCount.exe -o output.txt
則將統計信息輸出到文件 output.txt中。
(5) 多參數的混合使用
在實際測試時,-i 與 -o 參數必定會出現(但文件路徑不必定正確),但-n或-m 參數可能不出現,參數之間的順序並不固定,一個完整例子以下
wordCount.exe -i input.txt -m 5 -n 3 -o output.txt
第四步、附加功能
附加需求:用戶交互界面繪製(10')
如今已經有了一個詞頻統計程序的命令行版本,若是想讓你們都能實際使用它,還須要一個簡單的界面。請爲大家的程序作一個GUI界面,並附上一個簡單的使用說明。界面需正確實現下述功能,會按點給分:
-i -m -n -o
這四個參數的功能,對於異常狀況須要給予用戶提示(3')以上功能所有正確完成,能夠得到10分滿分。
【注意】選擇完成本附加題目的同窗,須要將GUI與單詞計算模塊做爲兩個工程開發,後者能夠做爲依賴庫爲前者提供調用接口,但不能夠把兩個工程直接混在一塊兒。 GUI相關的部分也須要提供新的可執行文件,放在根目錄的GUIBIN文件夾下。
第五步、錯誤處理並設計單元測試
如今咱們封裝了接口,並增長了新功能,如今咱們要對咱們的代碼進行正確性驗證。
另外一方面咱們都知道健壯性對於軟件來講是很是必要的,請各位使用單元測試對項目進行測試,並使用插件查看測試分支覆蓋率等指標;另外,請準備至少10個測試用例確保你的程序可以正確處理各類狀況,而且不會崩潰。
對待錯誤的輸入,可以儘量精確報錯(就像編譯器同樣)。
你能夠有「容錯性」的出錯設計,但必須輸出必要的提示或說明。
第六步、效能分析
如今咱們已經有了一個基礎的詞頻統計軟件,若是它經過了足夠多的單元測試,那它可能也已是一個比較完善的詞頻統計軟件了。可是一個軟件光正確了還不夠,還須要有必定的性能。
那麼,如何讓軟件又快又好地執行呢?那就須要咱們找到執行消耗時間最久的模塊,而後不斷地優化改進它。那麼,如何知道哪些語句是軟件的時間瓶頸呢,這就須要用到效能分析。
如下連接中的Part6部分有效能分析的介紹
http://www.javashuo.com/article/p-gozxhvvr-dq.html
博客評分規則(總分100)
(1) 在文章開頭給出大家Fork倉庫的Github項目地址。(5')
(2) 在開始實現程序以前,在下述PSP表格記錄下你估計將在程序的各個模塊的開發上耗費的時間。(5')
(3) 計算模塊接口的設計與實現過程。 設計包括代碼如何組織,好比會有幾個類,幾個函數,他們之間關係如何,關鍵函數是否須要畫出流程圖?說明你的算法的關鍵(沒必要列出源代碼),以及獨到之處。並講講你的設計是如何體現「Design by Contract」、「Information Hiding」、 「Interface Design」、 「Loose Coupling」等原則的。(25')
(4) 代碼複審過程。代碼互審狀況、發現的問題等。(10‘)
(5) 計算模塊接口部分的性能改進。 記錄在改進計算模塊性能上所花費的時間,描述你改進的思路,並展現一張性能分析圖(由VS 2017/JProfiler的性能分析工具自動生成),並展現你程序中消耗最大的函數。(10')
(6) 計算模塊部分單元測試展現。 展現出項目部分單元測試代碼,並說明測試的函數,構造測試數據的思路。並將單元測試獲得的測試覆蓋率截圖,發表在博客中。(15')
(7) 計算模塊部分異常處理說明。 在博客中詳細介紹每種異常的設計目標。每種異常都要選擇一個單元測試樣例發佈在博客中,並指明錯誤對應的場景。(10')
(8) 描述結對的過程,提供非擺拍的兩人在討論的結對照片。(5')
(9) 在你實現完程序以後,在附錄提供的PSP表格記錄下你在程序的各個模塊上實際花費的時間。(5')
(10) 附加功能(10')
(1)PSP表格
PSP2.1 |
Personal Software Process Stages |
預估耗時(分鐘) |
實際耗時(分鐘) |
Planning |
計劃 |
|
|
· Estimate |
· 估計這個任務須要多少時間 |
|
|
Development |
開發 |
|
|
· Analysis |
· 需求分析 (包括學習新技術) |
|
|
· Design Spec |
· 生成設計文檔 |
|
|
· Design Review |
· 設計複審 (和同事審覈設計文檔) |
|
|
· Coding Standard |
· 代碼規範 (爲目前的開發制定合適的規範) |
|
|
· Design |
· 具體設計 |
|
|
· Coding |
· 具體編碼 |
|
|
· Code Review |
· 代碼複審 |
|
|
· Test |
· 測試(自我測試,修改代碼,提交修改) |
|
|
Reporting |
報告 |
|
|
· Test Report |
· 測試報告 |
|
|
· Size Measurement |
· 計算工做量 |
|
|
· Postmortem & Process Improvement Plan |
· 過後總結, 並提出過程改進計劃 |
|
|
|
合計 |
|
|
PSP是卡耐基梅隆大學(CMU)的專家們針對軟件工程師所提出的一套模型:Personal Software Process (PSP, 我的開發流程,或稱個體軟件過程)。
一個功能完備的程序不是一蹴而就的。經過將詞頻統計的需求劃分爲4個部分,可將一個大任務劃分爲可操做的小任務,同時最好按照任務難度或緊急程度指定各個任務的完成次序。所以,在動手開發以前,要先估計將在程序各模塊開發所需耗費的時間,以及完成整個項目所需的時間,將這個[估計值]記錄下來,寫成PSP 的形式。
PSP的目的是:記錄工程師如何實現需求的效率,和咱們使用項目管理工具(例如微軟的Project Professional,或者禪道等)進行項目進度規劃相似。
有關PSP的更多內容,請自行閱讀鄒欣老師的博客:
http://www.cnblogs.com/xinz/archive/2011/10/22/2220872.html
(2) Github
請閱讀鄒欣老師的博客:http://www.javashuo.com/article/p-gjtthikg-km.html 源代碼管理,瞭解源代碼管理的10個實踐問題。
本次做業要求使用Github進行源代碼管理,代碼有進展即簽入Github。簽入記錄不合理的項目會被助教抽查詢問項目細節。
對代碼簽入的具體要求以下:根據需求劃分功能後,每作完一個功能,編譯成功後,應至少commit一次。本例中,至少應區分基本功能和擴展功能,即分別針對基本功能、擴展功能,編譯成功後,總共至少應commit兩次。具體的功能劃分,請自行定義,並在撰寫博客時體現出來,遵循本身對需求的功能劃分來提交代碼便可。
對Commit不是很熟悉的話,請閱讀阮一峯的博客:Commit message 和 Change log 編寫指南,瞭解更多細節。
(3)單元測試
請根據本身以往積累的測試經驗,在編碼完成以後,提交產品以前,設計測試用例,並編寫單元測試,對本身的項目進行測試。
首先,至少應採用白盒測試用例設計方法來設計測試用例,其餘測試方法不限。其次,要設計至少10個測試用例,確保你的程序可以正確處理各類狀況。最後,結合測試評估的要求,對本身的測試設計進行評價,這些測試用例能知足該程序測試的要求嗎?
另外一個重要的措施是要把單元測試自動化,這樣每一個人都能很容易地運行它,而且可使單元測試天天都運行。每一個人均可以隨時在本身的機器上運行。團隊通常是在每日構建中運行單元測試的,這樣每一個單元測試的錯誤就能及時被發現並獲得修改。
推薦閱讀鄒欣老師關於單元測試和迴歸測試的博客:
http://www.cnblogs.com/xinz/archive/2011/11/20/2255830.html
(1)代碼不要出現抄襲或者直接拷貝的現象,一旦發現做業將沒有成績。
(2)確保代碼可以運行經過,代碼不能經過,則博客成績最多給60分。
(3)博客要體現出本身的思想,每一個人遇到的問題和解決方法以及感得到的感覺都應是不同的,博客出現抄襲或者拷貝現象,一旦發現做業將沒有成績。
本做業參考北京航空航天大學發佈的做業:結對編程 - 詞頻統計,在此表示感謝!