這個作業屬于哪個課程 | <2021春軟體工程實踐|S班> |
---|---|
這個作業要求在哪裡 | <作業要求> |
這個作業的目标 | 1.重讀《建構之法》并提問 2.學習github和git的使用 3.編寫詞頻統計程式 4.學習并進行單元測試 |
其他參考文獻 | 1.正規表達式的學習 2.git和github的學習 3.鄒欣:關于單元測試和回歸測試 4.IDEA中使用JUnit4 |
目錄
|
在課本P15中寫着:一些同學認為,所謂好軟體,就是軟體沒有缺陷(Bug),所謂軟體工程,就是把軟體中的Bug都消滅掉的過程。P17中寫着:“足夠好”的軟體不是期末前兩天由兩三個同學熬通宵趕出來的急就章,而是經曆了一定的軟體流程,通過全體團隊成員的努力,在一個長期階段内逐漸完成的。
一個軟體的好壞應該更主要由什麼來評價,評價标準是怎樣呢?通過搜集資料發現軟體的好壞得到的大多是來自于使用者的評價。我的想法:我覺得評價應該注重的是使用者評價,看軟體的閱聽人是什麼,将自己代入閱聽人的角度去體驗軟體,如果舒适度便捷度等都合理,那麼軟體應該就挺好的。
在課本P74中寫着:注釋應該隻用ASCII字元,不要用中文或其他特殊字元,否則會極大地影響程式的可移植性。
像在于現階段,我對于很多注釋還是采取使用中文的方式,此時的我的認知中并無法體會到這之中的影響。我想知道在之後的工作中是否每個人的注釋基本都采用英語,或者是什麼樣的情況。再對于文中提及的可移植性。注釋對于每個函數都有必要添加嗎,比如一些工具類的小函數,還是應該怎麼選擇需要注釋的地方。
在課本P79中寫着:軟體工程中最基本的複審手段,就是同伴複審。
當局者迷,旁觀者清。我了解了同伴複審能夠看到更多自己看不到的錯誤或者遺漏,這有利于效率的提高。但就大學裡所遇到的來說,我對于别人的代碼常常會遇到看不懂的情況,或者代碼風格差異較大的情況,我們對于同伴的選擇是否優先考慮水準接近,代碼風格接近。對于以後進入公司後我想大多應該是團隊任務,在那裡對于代碼複審的情況又是如何呢?
在課本第16章“IT行業的創新”中寫着:最近幾年,我們整個社會對創新都很感興趣,媒體上充斥着創新型的人才、創新型的學校、創新型的公司、創新型的社會等名詞,有些城市還把創新當做城市精神之一,還有城市要 批量生産上千名頂級創新人才。
現在國内對于創新十分重視,由“中國制造”轉向“中國創造”。IT行業對于創新思維的要求相對會更高,那麼在平常中該如何去提高這種思維方式。我的了解是從需求中出發進行創新,還有别的方法嗎?我認為對于創新的誕生,主要還是從需求出發,因為有需求,為了滿足這種需求而創造出更便捷的方式。還有就是平常生活中要多關注客觀事物的不同性與特殊性。
在課本P373的魔方的創新故事中,果凍從其他地方帶來魔方,這是創造了一個原本這個地方沒有的事物;小飛影印了魔方口訣表來提高自己的競争力,大牛通過改變遊戲規則來先做到别人不能做到的事,但最後都是因為同學們對魔方的興趣漸漸失去而失去了市場。
這三位同學的行為也對應了不同的選擇:1.去封閉的地方賣魔方,那裡的人不知道外面的世界。2.依靠自己别的優勢或壟斷。3.開發有差異化的新東西,展現獨特的價值。對于一個事物大衆化的過程中(很多人都能夠實作),還有什麼方法能夠提高它的競争力。
一次,馮·諾伊曼在晚會上,女主人勇敢地向他提出一個謎題:兩列火車在同一軌道上以每小時 30 英裡的速度相對而行,且相距 1 英裡,這時栖在一列火車前面的一隻蒼蠅以每小時 60 英裡的速度朝着另一列火車飛去。當它飛到另一列火車時,它又迅速地飛回來。它一直這樣飛過去飛回來,直到兩列火車不可避免地發生碰撞。問這隻蒼蠅共飛了多少英裡?幾乎在女主人剛解釋完問題的同時,馮·諾伊曼就答道:“1 英裡。”“太讓我驚訝了,你這麼快就算出來了。” 她說道。“大多數數學家都沒能看出這裡面的技巧,而是用無窮級數去計算,這花費了他們很長時間。”“什麼技巧?我也是用無窮級數算的。” 馮·諾伊曼回答道。參考來源
這個故事有着很多版本,馮·諾伊曼從小就被寄予厚望,他也為計算機行業做了許多貢獻。
在大資料環境下,搜尋引擎,電商系統,服務平台,社交軟體等,都會根據使用者的輸入來判斷最近搜尋最多的詞語,進而分析目前熱點,優化自己的服務。首先當然是統計出哪些詞語被搜尋的頻率最高啦,請設計一個程式,能夠滿足一些詞頻統計的需求。
作業倉庫:PersonalProject-Java
個人github項目位址:https://github.com/camocd/PersonalProject-Java
PSP2.1 | Personal Software Process Stages | 預估耗時(分鐘) | 實際耗時(分鐘) |
---|---|---|---|
Planning | 計劃 | 30 | 40 |
• Estimate | • 估計這個任務需要多少時間 | ||
Development | 開發 | 600 | 755 |
• Analysis | • 需求分析 (包括學習新技術) | 120 | 200 |
• Design Spec | • 生成設計文檔 | 25 | |
• Design Review | • 設計複審 | 10 | |
• Coding Standard | • 代碼規範 (為目前的開發制定合适的規範) | 15 | |
• Design | • 具體設計 | 50 | 60 |
• Coding | • 具體編碼 | 300 | 360 |
• Code Review | • 代碼複審 | 20 | |
• Test | • 測試(自我測試,修改代碼,送出修改) | 70 | |
Reporting | 報告 | 135 | 145 |
• Test Repor | • 測試報告 | 90 | 100 |
• Size Measurement | • 計算工作量 | ||
• Postmortem & Process Improvement Plan | • 事後總結, 并提出過程改進計劃 | 35 | |
合計 | 765 | 940 |
- 剛開始看到題目的時候,對于github和git的使用是比較少的,這也給我帶來了一些困擾,不過通過查找一些資料後,也漸漸會使用了,也感受到了其中的便利。
- 程式設計作業,首先從題目中提取重要資訊
- 輸入、輸出檔案以指令行參數傳入
- 輸入檔案隻考慮Ascii碼,不考慮漢字
- 空格,水準制表符,換行符,均算字元
- 任何包含非空白字元的行,都需要統計
- 隻輸出頻率最高的10個單詞,形式均為小寫格式
- 輸出時冒号後面包含一個空格
- 對程式設計任務進行分解
- 讀取input檔案中的資料
- 統計字元數
- 統計單詞數
- 統計行數
- 統計各單詞的出現次數
- 将各種結果輸出到output檔案中
- 在程式設計設計的時候考慮到的問題
- 應該用什麼讀取檔案中的資料
- 單詞可以用String類的split拆分
- 應用什麼來判斷分解出來的字元串是一個單詞
- 該怎麼判斷行
- 單詞及其頻數用什麼存儲可以友善輸出(Map類)
221801230的代碼規範
隻有兩個類,WordCount類和Lib類,用WordCount類來執行Main函數,指令行參數傳入檔案名,對于傳入檔案後的統計和輸出的處理都在Lib類裡寫。Lib裡主要包含
readFile
、
writeFile
charNumCount
wordNumCount
lineNumCount
幾個函數
- 讀取檔案
public String readFile() {
StringBuilder builder = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new FileReader(inputFile));
int ch;
while ((ch = reader.read()) != -1){
builder.append((char)ch);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
return builder.toString();
}
讀檔案是選擇采用BufferReader類的read方法,存入StringBuilder對象擷取整個檔案後再做處理
String str = readFile();
charNumber = str.length();
直接由字元串的length函數獲得
3.統計行數
String[] lines = str.split("\n");
lineNumber = lines.length;
Pattern linePattern = Pattern.compile("\\s*");
for(String line : lines){
Matcher matcher = linePattern.matcher(line);
if (matcher.matches()){
lineNumber--;
}
}
先通過
split("\n")
将檔案分成多行,再通過正規表達式
\\s*
去掉那些隻含有空白字元的行,得到需要的值。
String[] words = str.split("[^a-zA-Z0-9]");
Pattern wordPattern = Pattern.compile("([a-zA-Z]{4}[a-zA-Z0-9]*)");
for (String word:words){
Matcher matcher = wordPattern.matcher(word);
if(matcher.matches()){
wordNumber++;
String w = word.toLowerCase();
Integer count = wordsMap.get(w);
if(count == null){
count = 0;
}
wordsMap.put(w,count+1);
}
}
通過正規表達式
[^a-zA-Z0-9]
将檔案分成一個個詞,在通過正規表達式
([a-zA-Z]{4}[a-zA-Z0-9]*)
判斷是否為滿足條件的單詞。若為單詞,将單詞存入Map裡,進行統計。
- 在統計單詞數的時候已經将單詞及出現次數存在Map裡,但是輸出時要滿足一定的順序,通過查資料知道所用HashMap是無序的,則需要進行排序處理
list = new ArrayList<Map.Entry<String, Integer>>(wordsMap.entrySet());
Collections.sort(list,new Comparator<Map.Entry<String,Integer>>(){
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
if(o1.getValue() == o2.getValue()){
return o1.getKey().compareTo(o2.getKey());
}
return o2.getValue().compareTo(o1.getValue());
}
});
通過重寫compare方法來對Map進行排序
-
輸出檔案
用BufferWriter類的write方法進行輸出
-
讀寫檔案的時候對比采用BufferReader和BufferWriter類
帶有緩存的讀寫類能夠減少作業系統通路檔案的次數,加快程式的運作速度。
輸入測試input.txt
相應輸出結果ouput.txt 運作時間
- 對字元計數進行測試
@Test
public void getCharNumber() throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter("x.txt"));
String text= "ads54\n\t\rdasd,";
writer.write(text);
writer.flush();
writer.close();
Lib lib = new Lib( "x.txt ", "y.txt");
lib.writeFile();
Assert.assertEquals(lib.getCharNumber(),13);
}
- 對單詞計數進行測試
@Test
public void getWordNumber() throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter("x.txt"));
String text= "hello1,2hello2,hello3,123jki2,iii\ndasd,156ads";
writer.write(text);
writer.flush();
writer.close();
Lib lib = new Lib( "x.txt ", "y.txt");
lib.writeFile();
Assert.assertEquals(lib.getWordNumber(),3);
}
- 對行數計數進行測試
@Test
public void getLineNumber() throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter("x.txt"));
String text = "124\n12312\n\n\n\n3123\n\n ";
writer.write(text);
writer.flush();
writer.close();
Lib lib = new Lib( "x.txt ", "y.txt");
lib.writeFile();
Assert.assertEquals(lib.getLineNumber(),3);
}
- 覆寫率截圖 覆寫率未滿為trycatch異常處理
主要是對于文檔打開操作的異常處理
try {
BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile));
} catch (IOException e) {
System.out.println("檔案打開失敗");
e.printStackTrace();
}
- 指令行參數數量不正确的處理
if (args.length != 2){
System.out.println("指令行參數應該為兩個");
return;
}
- 剛看到作業的時候,心情是很忐忑的,因為這次作業的内容需要通過github和git來完成,對于之前,也隻是偶爾從github上下載下傳東西,對于使用倒是一竅不通,還好通過學習,現在已經會使用一些了,也能夠體會到git的友善。還有就是對單元測試的學習,基本算是會運用了。
- 而且一段時間較少使用Java程式設計了,通過這次作業,也重新溫習了一些運用,也加深了對Map類的運用。
- 也逐漸地認識到了自己的代碼規範,好的代碼規範可便于程式設計,有利于程式設計。
- 還有就是對于時間的規劃,我對于時間的規劃還存在一定的問題,對時間有規劃也能夠提高自己的效率,會不斷學習提高自己。
- 複習了正規表達式,這次作業也讓我對于正規表達式有了更多的運用,使用起來也更加熟練