WordCount優化

WordCount優化



基本任務


項目地址:https://github.com/ReWr1te/WcProjava

PSP表格

PSP2.1 PSP階段 預估耗時 實際耗時
(分鐘) (分鐘)
Planning 計劃 20 20
· Estimate · 估計這個任務須要多少時間 60 65
Development 開發 90 102
· Analysis · 需求分析 (包括學習新技術) 10 5
· Design Spec · 生成設計文檔 10 12
· Design Review · 設計複審 (和同事審覈設計文檔) 30 35
· Coding Standard · 代碼規範 (爲目前的開發制定合適的規範) 20 25
· Design · 具體設計 10 5
· Coding · 具體編碼 80 90
· Code Review · 代碼複審 20 25
· Test · 測試(自我測試,修改代碼,提交修改) 30 25
Reporting 報告 120 120
· Test Report · 測試報告 60 35
· Size Measurement · 計算工做量 20 25
· Postmortem & Process Improvement Plan · 過後總結, 並提出過程改進計劃 20 20
合計 600 609

接口實現思路

按照小組討論的分工,我負責的是從字符串中提取而且統計詞頻,接口爲:git

HashMap<String, Integer> parseContent(String str)

這個接口接受一個String參數,表示要分析的字符串內容,返回HashMap 泛型部分表示單詞以及對應的詞頻。 github

下面來看一下對於單詞的定義,單詞規定以下:正則表達式

知足以下兩個條件中的任意一個條件,則視爲單詞,框架

第一,由連續的若干個英文字母組成的字符串,例如,software,ide

第二,用連字符(即短橫線)所鏈接的若干個英文單詞也視爲1個單詞,例如,content-based,視爲1個單詞。函數

注意,單詞不區分大小寫,不考慮英文之外的其餘語言,且僅考慮半角。工具

有關單詞識別的部分典型狀況的說明:性能

第一,Let’s,這種包含單引號的狀況,視爲2個單詞,即let和s。單元測試

第二,night-,帶短橫線的單詞,視爲1個單詞,即night。

第三,「I,帶雙引號的單詞,視爲1個單詞,即i。

第四,TABLE1-2,帶數字的單詞,視爲1個單詞,即table。

第五,(see Box 3–2).8885d_c01_016,帶數字、經常使用字符和單詞的狀況,視爲4個單詞,即see, box, d, c。

其實這麼長一串總結起來就兩句話:

  • 單詞是相似於 a、a-a、a-a-a 這種。
  • 單詞字母要轉換成小寫。

所以可使用正則表達式來實現,代碼以下(相關注釋在代碼中給出):

public class ContentParser {
    private String regEx = "[a-zA-Z]+(-[a-zA-Z]+)*";
    private Pattern pattern = Pattern.compile(regEx);
    //輸入文件內容,返回單詞統計信息
    @Test
    public HashMap<String, Integer> parseContent(String content) {
        HashMap<String, Integer> wordMap = new HashMap<>();
        if (content == null || "".equals(content)) {
            return wordMap;
        }
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            String word = matcher.group().toLowerCase();
            if (wordMap.containsKey(word)) {
                wordMap.replace(word, wordMap.get(word) + 1);
            } else {
                wordMap.put(word, 1);
            }
        }

        return wordMap;
    }
}

用例設計

這裏採用白盒測試黑盒測試的思路來進行用例設計(因爲用例數量較多,這裏僅給出 連接),下面分別進行說明:

黑盒測試採起等價類劃分的方法,經過對上面單詞的定義進行分析,對輸入有以下四條劃分規則:

  • 是否含有字母
  • 是否含有數字
  • 是否含有特殊字符(除-,由於-能夠被包含在單詞內)
  • 是否含有-

據此能夠產生16個測試用例。

白盒測試對函數的路徑和斷定進行分析,可獲得以下程序圖:

經過對代碼循環部分分析能夠合併兩個測試用例,獲得五個測試用例。

測試用例文檔以下:

經過上面的分析能夠得出結論,黑盒測試可以包含全部輸入的等價類,白盒測試路徑覆蓋率爲100%,測試用例足夠少,測試足夠完善,所以可以知足測試效率要求

測試結果

在代碼實現時,將測試用例按照必定格式提早寫入txt文件,測試時動態讀取,方便了測試用例的動態管理,測試結果以下:

測試用例採用黑盒測試和白盒測試兩種方式進行設計,黑盒測試可以包含全部輸入的等價類,白盒測試路徑覆蓋率爲100%。可是二者中出現了一部分重複的測試用例,說明黑盒測試和白盒測試具備必定的共同點。

被測試的程序經過了全部的測試用例,說明被測程序可以很好的完成程序功能,正確應對各類合理輸入數據,而且可以正確處理異常輸入數據,健壯性較好。


靜態測試


這裏根據《阿里巴巴Java開發手冊》進行代碼規範分析。《阿里巴巴Java開發手冊》中指出,

【強制】在使用正則表達式時,利用好其預編譯功能,能夠有效加快正則匹配速度。

據此我將正則表達式的預編譯放在了對象初始化的過程當中,這樣方法不論被調用多少次,預編譯只會執行一次,提升了正則匹配速度和方法執行速度:

public class ContentParser {
    private String regEx = "[a-zA-Z]+(-[a-zA-Z]+)*";
    private Pattern pattern = Pattern.compile(regEx);
    //輸入文件內容,返回單詞統計信息
    @Test
    public HashMap<String, Integer> parseContent(String content) {
        ······
        return wordMap;
    }
}

另外,《阿里巴巴Java開發手冊》中指出:

【強制】類名使用UpperCamelCase風格,但如下情形例外:DO/ BO / DTO/ VO/ AO/ PO等。

【強制】方法名、參數名、成員變量、局部變量都統一使用lowerCamelCase風格,必須聽從駝峯形式

這兩點對類和方法、參數等的命名作出了規範,類統一使用大駝峯命名法,方法、變量、參數等統一使用小駝峯命名法。這樣可使得代碼閱讀更加方便。所以在程序中類命名爲ContentParser 變量方法命名相似於wordMapparseContent

代碼規範分析

這裏分析了學號爲17121的同窗的代碼。

從變量和方法等的命名來看 ,變量和方法的命名採用了小駝峯命名法,類的命名採用了大駝峯命名法,如sortwriteFile() 等,符合《阿里巴巴Java開發手冊》中對命名規範的規定。

從工程目錄規範的角度來看 ,《阿里巴巴Java開發手冊》中指出:

【強制】單元測試代碼必須寫在以下工程目錄:src/test/java,不容許寫在業務代碼目錄下。

說明:源碼構建時會跳過此目錄,而單元測試框架默認是掃描此目錄。

該同窗的Test文件所有放在了src/test/目錄下,符合開發手冊的規定,方便了測試用例的管理,提升了源碼構建的效率。

靜態檢查工具

我採用的靜態檢查工具是Alibaba Java Coding Guidelines,下載地址

檢查結果

採用Alibaba Java Coding Guidelines對ContentParser進行檢查,結果以下:

對ContentParserTest進行檢查,結果以下:

下面對檢查中出現的問題逐條進行分析:

  • 對應第一條,在ContentParser中添加了author信息
  • 對應第二條,由於ContentParser不是Test類,不須要以Test結尾所以屬於誤判。
  • 對應第三條,註釋內容是對方法功能的說明,所以改成使用/**內容*/形式的註釋。
  • 對應第四條,因爲最多分析100個單詞,所以將hashmap的初值定位130。

比較好的地方是,在ContentParserTest的finally語句塊中,會檢查文件輸出流的狀態,確保不管是發生異常仍是正常退出都能及時關閉。

小組代碼存在的問題

  • 沒有及時關閉文件流
  • 代碼中多處出現魔法值
  • 註釋不規範,包括不能有尾行註釋,添加author信息,使用javadoc規範註釋等等

改正方法:

  • finally中判斷文件流是否關閉不然關閉文件流

  • 使用final定義常量

  • 按照規範改寫註釋


高級任務


測試用例設計

咱們選取了一本O'Reilly的JQury教程構造咱們的測試用例,將其複製屢次,獲得了24.03M的txt文件,並進行測試。初步估計運行時間在1000ms以上。

優化前性能指標

測試結果以下:

次數 時間(毫秒)
1 1777
2 1994
3 1978
4 2023
平均 1943

同行評審及結論

  1. 角色分工:
    • 主持人&記錄員:田詩園
    • 講解員:邱利光 沃錦文 王啓萌 田詩園
    • 評審員:邱利光 沃錦文 王啓萌 田詩園
    • 做者:邱利光 沃錦文 王啓萌 田詩園
  2. 評審結果及結論
    • 正則表達式效率較慢。
    • 考慮到程序對查找的性能要求比較高,應當選取合適的容器類。
    • 提升IO速度。

優化設計思路

  • 能夠用狀態機來提取單詞,提升效率。
  • 單詞統計咱們採用HashMap來存儲。當數據容量較少時其內部實現爲一個鏈表,當數據量較大時,自動改用二叉樹進行存儲,有效提升了查詢效率。
  • 輸出單詞時,改變原來的每一個單詞打開一次文件的作法,只打開一次文件,所有輸出後關閉文件流,提升了IO速度。

做業感想

想想此次做業,編碼的時間大概只佔到了三分之一左右,剩下的時間大約三分之一用在了設計用例,編寫測試框架,剩下的三分之一時間用在了寫博客上。

這門課叫軟件質量測試,從此次做業也能夠感覺到,軟件測試的過程是貫穿整個開發過程當中的,不論是基本功能,仍是擴展任務,再到高級任務,測試的思想一直貫穿其中,基本任務要根據本身負責的模塊設計二十個測試用例,擴展任務則是對本身的代碼進行靜態檢查,也是一種軟件質量測試,高級任務則是進行壓力測試,檢查程序的健壯性。

經過一系列測試過程,一方面讓我從另外一個角度瞭解了本身寫的程序,另外一方面讓我對程序的健壯性有了信心,畢竟一個簡單的模塊寫了二十個測試用例Orz

個人理解就是軟件測試 貫穿了軟件開發 的整個過程,保證了所開發軟件的質量

相關文章
相關標籤/搜索