第四周做業之wcPro核心模塊

# 第四周做業之wcPro核心模塊的實現java

## 1、基本任務:代碼編寫+單元測試git

### 小組github地址github

https://github.com/SkateCloud/wcPro編程

### PSP表格數組

<div style="text-align: left" align="center">
<table>
<thead>
<tr class="header"><th align="center">PSP2.1</th><th align="center">PSP階段</th><th align="center">預估耗時(分鐘)</th><th align="center">實際耗時(分鐘)</th></tr>
</thead>
<tbody>
<tr class="odd">
<td align="center"><strong>Planning</strong></td>
<td align="center">計劃</td>
<td align="center">30</td>
<td align="center">60</td>
</tr>
<tr class="even">
<td align="center">Estimate</td>
<td align="center">估計任務須要多少時間</td>
<td align="center">30</td>
<td align="center">60</td>
</tr>
<tr class="odd">
<td align="center"><strong>Development</strong></td>
<td align="center">開發</td>
<td align="center">120</td>
<td align="center">180</td>
</tr>
<tr class="even">
<td align="center">Analysis</td>
<td align="center">需求分析</td>
<td align="center">20</td>
<td align="center">30</td>
</tr>
<tr class="odd">
<td align="center">Design Spec</td>
<td align="center">生成設計文檔</td>
<td align="center">20</td>
<td align="center">30</td>
</tr>
<tr class="even">
<td align="center">Design Review</td>
<td align="center">設計複審</td>
<td align="center">20</td>
<td align="center">30</td>
</tr>
<tr class="odd">
<td align="center">Coding Standard</td>
<td align="center">代碼規範</td>
<td align="center">30</td>
<td align="center">10</td>
</tr>
<tr class="even">
<td align="center">Design</td>
<td align="center">具體設計</td>
<td align="center">30</td>
<td align="center">50</td>
</tr>
<tr class="odd">
<td align="center">Coding</td>
<td align="center">具體編碼</td>
<td align="center">30</td>
<td align="center">40</td>
</tr>
<tr class="even">
<td align="center">Code Review</td>
<td align="center">代碼複審</td>
<td align="center">30</td>
<td align="center">40</td>
</tr>
<tr class="odd">
<td align="center">Test</td>
<td align="center">測試</td>
<td align="center">50</td>
<td align="center">10</td>
</tr>
<tr class="even">
<td align="center"><strong>Reporting</strong></td>
<td align="center">報告</td>
<td align="center">70</td>
<td align="center">240</td>
</tr>
<tr class="odd">
<td align="center">Test Report</td>
<td align="center">測試報告</td>
<td align="center">30</td>
<td align="center">100</td>
</tr>
<tr class="even">
<td align="center">Size Measurement</td>
<td align="center">計算工做量</td>
<td align="center">20</td>
<td align="center">60</td>
</tr>
<tr class="odd">
<td align="center">Postmortem</td>
<td align="center">總結</td>
<td align="center">20</td>
<td align="center">80</td>
</tr>
<tr class="even">
<td align="center">&nbsp;</td>
<td align="center">合計</td>
<td align="center">280</td>
<td align="center">480</td>
</tr>
</tbody>
</table>
</div>多線程

### 接口設計模塊化

- 接口描述函數

本人負責的是核心模塊,即對輸入的文件讀取後的結果進行單詞排序並存入`List`結構中準備輸出工具

- 設計思路性能

對從輸入模塊獲取的數據存入`hashMap`中,再將`Map`結構轉變成`List`結構進行單詞排序,爲輸出模塊準備接口

- 實現過程

先使用`Map<String, Integer>`結構對輸入模塊傳來的數據進行存儲.
```java
HashMap<String,Integer> words = new HashMap<>();
String str = readFile(args[0]);
{
int state = 0;
int beginIndex = -1;
for (int i = 0; i <= str.length(); ++i) {
char ch = i == str.length() ? ' ' : str.charAt(i);
boolean isWordChar = ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || ch == '-';
if (state == 0 && isWordChar && ch != '-') {
beginIndex = i;
state = 1;
} else if (state == 1 && !isWordChar) {
String word = str.substring(beginIndex, i).toLowerCase();
words.put(word, words.getOrDefault(word, 0) + 1);
state = 0;
}
}
}
```

因爲外部存儲機構使用的是`Map.Entry<String, Integer>`,不便於排序等操做,因此將map轉化爲List結構,進行排序

```java
List<Map.Entry<String, Integer>> list = new ArrayList<>();
list.addAll(words.entrySet());
list.sort((lhs, rhs) -> {
int cmp = -lhs.getValue().compareTo(rhs.getValue());
if (cmp != 0) return cmp;
else return lhs.getKey().compareTo(rhs.getKey());
});
```

### 測試設計

保證設計的測試用例應至少覆蓋函數中全部的可執行語句,同時主要空數組、最差狀況、詞頻排序、字母排序、二者混合等各類狀況設計測試用例。

![附件2截圖]()

### 單元測試

使用測試腳本進行單元測試,過程以下

![測試腳本運行截圖](http://r.photo.store.qq.com/psb?/V10RioZu2yUxV6/n1er*KNZRifOkCNiXWZBFPjPZzYkWW89C36Q0e27Yfk!/r/dA4AAAAAAAAA)

單元測試效果良好,沒有報錯

### 小組貢獻
咱們小組齊心合力, 攻克難關,積極討論,指出問題,我認爲個人小組貢獻分是0.4

## 二.擴展任務:靜態測試

### 1. 代碼規範

我選擇了代碼風格規範中:斷行與空白的{}行、分行、命名、下劃線、大小寫;

代碼設計規範中:函數、錯誤處理、new和delete、類型繼承,模塊化

個人編程習慣與以上附錄中所述規範大體相同。而在其餘如代碼審查等重要規範上有待提升。

### 2. 同組分析

我分析了本身的代碼,縮進、斷行風格整潔,命名簡單明瞭,邏輯清晰易讀,但在代碼設計規範上,模塊化不足,不易於進行團隊的coding工做,常常在git操做上發生衝突.

最後決定將團隊代碼進行整合重構,重構任務由我完成,故最終貼出組長的重構代碼

```java
public class wordcount {
public static void main(String[] args) {
long t1 = System.currentTimeMillis();
new wordcount().start(args);
long t2 = System.currentTimeMillis();
long dt = t2 - t1;
System.out.println(("Elapsed " + dt + "ms"));
}

private void start(String[] args) {
HashMap<String,Integer> words = new HashMap<>();
String str = readFile(args[0]);
{
int state = 0;
int beginIndex = -1;
for (int i = 0; i <= str.length(); ++i) {
char ch = i == str.length() ? ' ' : str.charAt(i);
boolean isWordChar = ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || ch == '-';
if (state == 0 && isWordChar && ch != '-') {
beginIndex = i;
state = 1;
} else if (state == 1 && !isWordChar) {
String word = str.substring(beginIndex, i).toLowerCase();
words.put(word, words.getOrDefault(word, 0) + 1);
state = 0;
}
}
}

List<Map.Entry<String, Integer>> list = new ArrayList<>();
list.addAll(words.entrySet());
list.sort((lhs, rhs) -> {
int cmp = -lhs.getValue().compareTo(rhs.getValue());
if (cmp != 0) return cmp;
else return lhs.getKey().compareTo(rhs.getKey());
});

try (FileWriter fout = new FileWriter("result.txt")) {
int maxsz = Math.min(list.size(), 100);
for (int i = 0 ; i < maxsz; ++ i) {
Map.Entry<String, Integer> item = list.get(i);
fout.write(item.getKey());
fout.write(' ');
fout.write(item.getValue().toString());
if (i != maxsz - 1)
fout.write('\n');
}
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}

private String readFile(String path) { // 讀文件
try {
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, "UTF-8");
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}

}
```

### 3. 靜態代碼檢查工具

使用的是IDEA的插件Ant Build中的檢錯功能
Ant Build是一個Java自動化生成工具,其檢錯功能用來檢查類或者jar文件,用來發現可能的問題。檢測完成以後會生成一份詳細的報告,藉助這份報告能夠找到潛在的bug.

檢測範圍

- 常見代碼錯誤,序列化錯誤
- 可能致使錯誤的代碼,如空指針引用
- 國際化相關問題:如錯誤的字符串轉換
- 可能受到的惡意攻擊,如訪問權限修飾符的定義等
- 多線程的正確性:如多線程編程時常見的同步,線程調度問題。
- 運行時性能問題:如由變量定義,方法調用致使的代碼低效問題

### 4. 掃描結果

![掃描結果](http://r.photo.store.qq.com/psb?/V10RioZu2yUxV6/rDxJRHigmYxocOiCk0dbyIFU79kW7pc7KV8Xg8yQeP8!/r/dN0AAAAAAAAA)

檢測結果在右上角,能夠看出僅有少許警告,根據IDEA紅線標註可發現大可能是聲明方式不是按照目前使用的java標準,沒有發生內存泄露等問題.

### 5. 小組代碼問題說明

- 因爲進行了整合重構,因此模塊化程度下降,不易維護,但程序執行效率上升
- 異常處理的不夠全面,應該覆蓋大部分的一場狀況,以便於檢查與調試

## 三. 高級任務:性能測試和優化

設計,評審,優化

選擇10kb,50kb,182kb大小的txt文件進行測試,程序處理時長以下:

      輸入輸出:1ms,1ms,2ms

      單詞統計:20ms,150ms,540ms

      詞頻排序:6ms,8ms,10ms

  單詞統計時間與文件大小呈線性相關,其餘兩個模塊佔比較小,故程序性能主要受到文件大小影響。組內共同對代碼結構和細節進行詳細審查並與其餘組程序對比,整理獲得以下觀點:

    1.整合重構是正確的,不只增長了代碼的可讀性和規範性,還大幅增長了程序的性能

    2.將大部分功能模塊彙集在一個類方法中,雖然會致使代碼耦合度增高,不易於團隊維護和再開發,可是減小了模塊間相互調用的開銷和隨之產生的內存開銷

## 小結

經過基本任務、擴展任務、到高級任務的完成以及中間遇到的許多困難,體現出了軟件測試對於軟件開發的重要性。在開發過程當中,使用靜態測試工具實時地檢測本身的代碼,能夠改正本身不良的編程習慣,更能防患於未然,減小出現bug的可能;對本身的模塊進行單元測試,能夠保障本身代碼的正確性,更是對其餘開發成員和整個任務的負責,使軟件開發可以一步一個腳印地穩定開展;對性能的分析與測試,能使軟件的質量進一步提升,同事能總結開發經驗,使本身設計的模塊更加高效。

相關文章
相關標籤/搜索