結對第二次—文獻摘要熱詞統計及進階需求

所屬課程 軟件工程1916|W(福州大學)
做業要求 結對第二次—文獻摘要熱詞統計及進階需求
結對學號 221600327221600329
基本需求Github項目地址 PairProject1-Java
進階需求Github項目地址 PairProject2-Java
做業目標 運用結對編程完成做業,加強團隊協做能力
參考文獻 《構建之法》、《數據結構與算法分析 Java語言描述》

PSP表格:

PSP2.1 Personal Software Process Stages 預估耗時(分鐘) 實際耗時(分鐘)
Planning 計劃 20 30
• Estimate • 估計這個任務須要多少時間 20 30
Development 開發 1060 1290
• Analysis • 需求分析 (包括學習新技術) 60 120
• Design Spec • 生成設計文檔 10 20
• Design Review • 設計複審 30 20
• Coding Standard • 代碼規範 (爲目前的開發制定合適的規範) 10 10
• Design • 具體設計 30 40
• Coding • 具體編碼 800 960
• Code Review • 代碼複審 60 60
• Test • 測試(自我測試,修改代碼,提交修改) 60 60
Reporting 報告 80 120
• Test Report • 測試報告 40 60
• Size Measurement • 計算工做量 10 20
• Postmortem & Process Improvement Plan • 過後總結, 並提出過程改進計劃 30 40
合計 1160 1440

目錄

任務一、WordCount基本需求

1.一、PSP表格

1.二、需求分析

(一)成品:wordCount的命令行程序

(二)功能性需求:統計input.txt中的如下幾個指標

  1. 統計文件的字符數
    • 只須要統計Ascii碼,漢字不需考慮
    • 空格,水平製表符,換行符,均算字符
  2. 統計文件的單詞總數,單詞:至少以4個英文字母開頭,跟上字母數字符號,單詞以分隔符分割,不區分大小寫
    • 英文字母: A-Z,a-z
    • 字母數字符號:A-Z, a-z,0-9
    • 分割符:空格,非字母數字符號
    • 例:file123是一個單詞,123file不是一個單詞。file,File和FILE是同一個單詞
  3. 統計文件的有效行數:任何包含非空白字符的行,都須要統計。
  4. 統計文件中各單詞的出現次數,最終只輸出頻率最高的10個。頻率相同的單詞,優先輸出字典序靠前的單詞。
  5. 按照字典序輸出到文件result.txt:例如,windows95,windows98和windows2000同時出現時,則先輸出windows2000
    • 輸出的單詞統一爲小寫格式
  6. 輸出的格式爲

characters: number
words: number
lines: number
: number
: number
...
html

(三)非功能性需求

1.接口封裝java

  • 統計字符數 ;
  • 統計單詞數 ;
  • 統計最多的10個單詞及其詞頻 ;

1.三、解題思路

1.3.1統計字符數:

我理解的input.txt的內容應該是,文件中只包含ascii碼以及空格,水平製表符,換行符這些字符。因此想直接用String存儲文件內容,用String.length()來獲得字符數。可是這個會有一個問題,就是在windows平臺下,換行符是用"\r\n",String.length()會統計爲兩個字符,用「\n」代替「\r\n」,便可解決問題。git

1.3.2統計單詞數:

文件由兩種字符分割符(空格,非字母數字符號)和非分隔符構成,單詞統計與非分割符無關,因此直接爲了接下來split方便,將全部的分割符都替換爲「|」,第二步分割字符串,第三步,使用正則表達式匹配題目所規定的單詞,統計單詞數。github

1.3.3統計有效行數:

一開始我想的統計行數是使用readline();去讀出每一行,而後逐行判斷這行有沒有ascii碼值<32的字符存在,由於ascii碼值小於32的是在文本中不顯示的,因此我開始的想法就是這樣的;不過試了一下以後發現對於"\r\n"之類的字符和空白行單靠ascii碼是區分不出來的,而後在網上找了資料以後,發現String.trim().isEmpty()是能夠去除空白行而後統計的,最後使用的是這個方法。正則表達式

1.3.4統計各單詞的出現次數,輸出頻率Top10的單詞:

由於處理場景爲單機,因此決定選用散列表,順序掃描剛剛的到的單詞數組,當掃描到某個關鍵詞時,就去散列表裏查詢。若是存在,就將對應的次數加一;若是不存在,就將他插入到散列表,並記錄爲1,以此類推,遍歷完後,散列表中就存儲了不重複的單詞以及其出現的次數。
而後就是求Top10,創建一個大小爲10的小頂堆,遍歷散列表,依次取出每一個單詞及對應出現的次數,而後與堆頂的單詞比較。若是出現次數比堆頂單詞的次數多,就刪除堆頂單詞,將這個次數更多的關鍵詞加入到堆中,以此類推,遍歷完散列表,堆中的單詞就是出現次數top10的單詞。而後排序輸出。算法

1.四、設計過程

1.4.1代碼組織&接口設計:

  • bean包:Word類編程

  • unitl包:BasicWordCount類、IOUnitls類windows

    • BasicWordCount類:數組

      • 統計字符數函數 :網絡

        /**
        * 計算文件字符數
        * @param fileName 文件名
        * @return long 字符數
        */
        public long characterCount(String fileName){}
      • 統計行數 :

        /**
        * 計算文件行數
        * @param fileName 文件名
        * @return long 行數
        */
        public long lineCount(String fileName){}
      • 統計單詞數 :

        /**
        * 計算文件單詞數
        * @param fileName 文件名
        * @return long 單詞數
        */
        public long wordCount(String fileName){}
      • 統計詞頻top10的10個單詞及其詞頻 :

        /**
        * 計算出現次數top10的單詞及其詞頻
        * @param fileName 文件名
        * @return Word[] 單詞數組
        */
        public Word[] topTenWord(String fileName) {}
    • IOUnitls類:

      • 讀文件

        /**
        * 讀入指定文件名的文件數據
        * @param fileName 文件名
        * @return BufferedReader
        * @throws IOException 
        */
        public static BufferedReader readFile(String fileName){}
      • 寫文件

        /**
           * 將制定字符串輸出到result.txt
           * @param fileContent 字符串
           */
          public static void writeFile(String fileContent, String fileName) {}

1.4.2關鍵代碼及其流程圖(詞頻Top10單詞統計):

解題思路
流程圖:

代碼:

//進行統計的散列表
public Word[] topTenWord(String fileName) {
    ...//省略讀取文件、將文本處理成單詞數組的過程
        Map<String, Integer> countMap = new HashMap<>();
        for(int i = 0; i < splitStrings.length; i++) {
            if(Pattern.matches(regex, splitStrings[i])) {
                Integer outValue = countMap.get(splitStrings[i]);
                if (null == outValue) {
                      outValue = 0;
                }
                outValue++;
                countMap.put(splitStrings[i], outValue);
            }
        }
        //求top10
        PriorityQueue<Word> topN = new PriorityQueue<>(10, comp);
        Iterator<Map.Entry<String, Integer>> iter = countMap.entrySet().iterator();
        Map.Entry<String, Integer> entry;
        while (iter.hasNext()) {
          entry = iter.next();
          if (topN.size() < 10) {
            topN.offer(new Word(entry.getKey(), entry.getValue()));
          } else {
            // 若是當前數據比小頂堆的隊頭大,則加入,不然丟棄
            if (topN.peek().getCountNum() < entry.getValue()) {
              topN.poll();
              topN.offer(new Word(entry.getKey(), entry.getValue()));
            }
          }
        }
        //結果集
        Word[] result = null;
        int wordCount = countMap.size();
        if(wordCount < 10) {
            result = new Word[(int) wordCount];
        }else {
            result = new Word[10];
        }
        topN.toArray(result);
        //對top10單詞排序
        Arrays.sort(result, comp);
        return result;
}

複雜度分析:遍歷散列表須要 O(n) 的時間複雜度,一次堆化操做須要 O(logK) 的時間複雜度,因此最壞狀況下,n個元素都入堆一次,因此最壞狀況下,求TopK的時間複雜度是O(nlogk)。

1.五、性能分析

從CPU Call Tree圖能夠看出,耗時主要是在對字符串的分割和單詞的正則匹配。

任務二、WordCount進階需求

2.一、PSP表格

2.二、需求分析

2.2.1 成品:

①程序一:爬取CVPR2018論文到本地result.txt的命令行程序

②程序二:支持命令行參數的wordCount命令行程序

2.2.2功能性需求

(1)使用工具爬取論文信息**輸出到result.txt文件
(2)自定義輸入輸出文件**
        WordCount.exe -i [file] -o [file]
(3)加入權重的詞頻統計**
         WordCount.exe -w [0|1]
(4)新增詞組詞頻統計功能**
        WordCount.exe -m [number]
(5)自定義詞頻統計輸出**
        WordCount.exe -n [number]
(6)多參數的混合使用**
        WordCount.exe -i input.txt -m 3 -n 3 -w 1 -o output.txt

2.三、解題思路

2.3.1 爬取CVPR論文數據

要從網頁上爬取數據,就得分析網頁HTML源代碼構成,從CVPR2018首頁的HTML代碼能夠看出,在首頁的論文列表中,每一篇的論文標題在HTML代碼上體現爲以下形式:

<dt class="ptitle"><a href="xxx.html">論文標題</a></dt>

其中<a></a>標籤裏的href屬性爲論文詳情頁的網頁地址。

由此咱們能夠獲取每篇論文詳情頁的url

第一步就是在網頁的DOM樹中提取全部的<dt class="ptitle">的節點。
第二步從每一個<dt class="ptitle">的節點中提取出<a>標籤的href屬性。

接着分析論文詳情頁的HTML代碼,

咱們能夠發現,在詳情頁源代碼中,論文標題的html代碼長這個樣子:

<div id="papertitle">論文標題</div>

論文摘要的html代碼長這個樣子:

<div id="abstract">這是論文摘要</div>

由此咱們能夠獲取每篇論文的標題和摘要

第一步從網頁的DOM樹中找到<div id="papertitle">的節點,獲取他的文本即爲paper title。
第二步從網頁的DOM樹中找到<div id="abstract">的節點,獲取他的文本即爲paper abstract。

2.3.2 自定義參數

自定義參數的實現是先設計一個CommandLine類,把做業中的參數做爲類的私有成員,而後從String []args中讀取命令行參數,存進CommandLine類中,再使用getxxxx()公有函數取出相應的參數就可使用自定義參數了。

2.3.3 加入權重的詞頻統計:

從爬取的論文數據可知,title獨佔一行,abstract獨佔一行,因此能夠按行處理數據。若是-w 參數爲1,修改基本需求的文件,當一行的開頭是title:,那麼這一行的單詞的權重爲10。其餘的一概權重爲1。

2.3.4 詞組詞頻統計:

由於詞組不能跨越Title、Abstract,並且需求給定Title和Abstract都是獨佔一行的,因此按行讀取。

而後構造一個隊列,對讀取的一行開始掃描,接下來的判斷邏輯以下圖:

掃描完後,對得到的散列表進行topK操做,便可。

2.3.4 自定義詞頻統計

這個很簡單,基本需求規定的是top10,而這裏咱們只要從參數獲取topK的值,傳入參數,遍歷單詞列表,而後維護一個大小爲K的小頂堆便可。

2.四、設計過程

2.4.1 代碼組織和接口設計

  • bean包:Word類、CommandLine類

  • unitl包:AdvancedWordCount類、Command類、IOUnitls類

    • AdvancedWordCount類:

      • 統計字符數函數 : 同基本需求

      • 統計行數 : 同基本需求

      • 統計單詞數 : 同基本需求

      • 統計單詞詞頻topK的K個單詞及其詞頻 :

        /**
        * 計算單詞的(加權)詞頻和topK
        * @param fileName 文件名
        * @param topK 詞頻前K的單詞
        * @param isWeight 是否啓用加權計算
        * @return Word[] 有序單詞數組
        */
        public Word[] topKWordWeighting (String fileName, int topK, boolean isWeight) {}
      • 統計詞組詞頻topK的K個詞組及其詞頻 :

      /**
        * 計算詞組的(加權)詞頻和topK
        * @param fileName 文件名
        * @param groupNum 幾個單詞爲一個組
        * @param topK 詞頻前K的詞組
        * @param isWeight 是否啓用加權計算
        * @return Word[] 有序單詞數組
        */
        public Word[] topKWordsWeighting (String fileName, int groupNum,int topK, boolean isWeight) {}
    • Command類:

      • /**
        * 解析命令行參數
        * @param args 參數
        * @return CommandLine對象
        */
        public CommandLine ParseCommand(String[] args) {}
    • IOUnitls類(同基本需求)

2.4.2 關鍵代碼(詞組詞頻統計之詞組劃分):解題思路

...
            //進行統計的散列表
            Map<String, Integer> countMap = new HashMap<>();
            while((line = bufferedReader.readLine()) != null) {
                String regexTile = "Title: .*";
                int weight = 1;
                if(Pattern.matches(regexTile, line)) {
                    line = line.replaceAll("Title: ", "");
                    weight = 10;
                }else {
                    line = line.replaceAll("Abstract: ", "");
                    weight = 1;
                }
                line = line.toLowerCase();
                //按字符分析
                int groupnumber = 0;//詞組單詞個數
                int wordStratPosition = 0;//單詞開始下標
                int wordEndPosition = 0;//單詞開始下標
                int flagPosition = 0;//標記詞組第一個單詞的結束位置
                Queue<String> wordReadyQueue = new LinkedList<String>();
                for(int i = 0; i < line.length()-3;) {
                    boolean flag = false;
                    
                    if(Character.isLetter(line.charAt(i))) {
                        if(Character.isLetter(line.charAt(i+1))) {
                            if(Character.isLetter(line.charAt(i+2))) {
                                if(Character.isLetter(line.charAt(i+3))) {
                                    wordStratPosition = i;
                                    for(int j=i+4; j < line.length(); ++j) {
                                        if(!Character.isLetterOrDigit(line.charAt(j))) {
                                            wordEndPosition = j;
                                            //獲得一個單詞,加入到隊列
                                            wordReadyQueue.add(line.substring(wordStratPosition, wordEndPosition));                                     
                                            groupnumber++;//詞組單詞數+1
                                            if(groupnumber == 1) {
                                                flagPosition = j;
                                            }
                                            i=j;
                                            flag = true;
                                            break;
                                        }else if((j+1)==line.length()) {
                                            wordEndPosition = j+1;
                                            //獲得一個單詞,加入到隊列
                                            wordReadyQueue.add(line.substring(wordStratPosition));
                                            groupnumber++;//詞組單詞數+1
                                            if(groupnumber == 1) {
                                                flagPosition = j;
                                            }
                                            i=j;
                                            flag = true;
                                            break;
                                        }
                                    }
                                }else {
                                    if(!Character.isLetterOrDigit(line.charAt(i))) {
                                        wordReadyQueue.add(line.charAt(i)+"");
                                    }else {
                                        while(wordReadyQueue.poll()!=null) {}//清空隊列

                                        while(Character.isLetterOrDigit(line.charAt(i++))) {
                                            if(i >= line.length()){
                                                break;
                                            }
                                        }
                                        groupnumber = 0;
                                        flag = true;
                                    }
                                }
                            }else {
                                if(!Character.isLetterOrDigit(line.charAt(i))) {
                                    wordReadyQueue.add(line.charAt(i)+"");
                                }else {
                                    while(wordReadyQueue.poll()!=null) {}//清空隊列

                                    while(Character.isLetterOrDigit(line.charAt(i++))) {
                                        if(i >= line.length()){
                                            break;
                                        }
                                    }
                                    groupnumber = 0;
                                    flag = true;
                                }
                            }
                        }else {
                            if(!Character.isLetterOrDigit(line.charAt(i))) {
                                wordReadyQueue.add(line.charAt(i)+"");
                            }else {
                                while(wordReadyQueue.poll()!=null) {}//清空隊列

                                while(Character.isLetterOrDigit(line.charAt(i++))) {
                                    if(i >= line.length()){
                                        break;
                                    }
                                }
                                groupnumber = 0;
                                flag = true;
                            }
    
                        }
                    }else {
                        if(!Character.isLetterOrDigit(line.charAt(i))) {
                            if(groupnumber!=0) {
                                wordReadyQueue.add(line.charAt(i)+"");
                            }
                        }else {
                            while(wordReadyQueue.poll()!=null) {}//清空隊列
                            while(Character.isLetterOrDigit(line.charAt(i++))) {
                                if(i >= line.length()){
                                    break;
                                }
                            }
                            groupnumber = 0;
                            flag = true;
                        }
                    }
                    if(groupnumber == groupNum) {//達到要求個數,加入散列表
                        String wordGroup = "";
                        String wordOfQueue = wordReadyQueue.poll();
                        while(wordOfQueue != null) {
                            wordGroup = wordGroup + wordOfQueue;
                            wordOfQueue = wordReadyQueue.poll();
                        }
                        groupnumber = 0;
                        //加權
                        Integer outValue = countMap.get(wordGroup.toString());
                        if (null == outValue) {
                              outValue = 0;
                        }
                        if(isWeight) {
                            outValue += weight;
                        }else {
                            outValue++;
                        }
                        countMap.put(wordGroup.toString(), outValue);       
                        i = flagPosition;
                    }
                    if(!flag) {
                        ++i;
                    }
                }
            }
            ...

2.4.3 關鍵代碼(爬取論文標題和摘要):解題思路

由於以前寫安卓應用曾經用戶jsoup抓取教務系統上的成績等數據,此次天然而然使用了jsoup來對論文進行爬取。代碼以下:

/**
         * 從cvpr網站爬取論文數據,並寫入result.txt
         * @param URL
         */
        public static void getFile(String URL) {
            BufferedWriter bufferedWriter = null;
            try {
                File outputFile = new File("result.txt");
                bufferedWriter = new BufferedWriter(new FileWriter(outputFile));
                //get方式獲得HTML數據
                //默認設置下,jsoup超時時間爲3秒,鑑於當前網絡環境,修改成10秒
                //默認設置下,jsoup最大獲取的長度只有1024K,設置maxBodySize(0),可不限長度
                Document doc = Jsoup.connect(URL).timeout(10000).maxBodySize(0).get();
                //從HTML中選擇全部class=ptitle的節點
                Elements paperList = doc.select("[class=ptitle]");
                //從ptitle節點中選擇a標籤的href屬性值
                Elements links = paperList.select("a[href]");
                int count = 0;
                //分別當問每篇論文的詳情頁
                for (Element link : links) {
                    //論文詳情頁URL
                    String url = link.attr("abs:href");
                    Document paperDoc = Jsoup.connect(url).timeout(10000).maxBodySize(0).get();
                    //獲取論文title
                    Elements paperTitle = paperDoc.select("[id=papertitle]");
                    String title = paperTitle.text();
                    //獲取論文Abstract
                    Elements paperAbstract = paperDoc.select("[id=abstract]");
                    String abstracts = paperAbstract.text();
                    //數據寫入文件
                    bufferedWriter.write(count++ + "\r\n");
                    bufferedWriter.write("Title: " + title + "\r\n");
                    bufferedWriter.write("Abstract: " + abstracts + "\r\n\r\n\r\n");
                }
            } catch (Exception e) {
                System.out.println("獲取論文數據失敗");
                e.printStackTrace();
            }finally {
                try {
                if(bufferedWriter != null) {
                    bufferedWriter.close();
                }
                }catch (Exception e) {
                    System.out.println("獲取論文數據失敗");
                    e.printStackTrace();
                }
            }
        }

2.五、性能分析及改進

2.5.一、性能分析

考慮到進階的數據量可能比較大,在壓力測試時,咱們用了近60M的txt(近6000萬的字符)文件進行測試。內存佔用在1G左右,因爲複用基本需求的接口,在性能測試時,依然是對字符串的分割(split)耗時最多佔用內存很大,緣由是由於原來的代碼是把這6000萬字符存放到字符數組裏,在進行合法單詞的判斷。


2.5.二、改進方法

在統計單詞時,直接遍歷一遍文本數據,識別單詞的start和end的下標,直接截取單詞進行識別。代碼以下:

for(int i = 0; i<updateString.length();) {
        startPosition = i;
        endPosition = i;
        while(Character.isLetterOrDigit(updateString.charAt(i++))) {
            endPosition++;
        }
        if(Pattern.matches(regex, updateString.substring(startPosition, endPosition))) {
            countOfWord++;
        }
    }

2.六、單元測試

咱們用的是Eclipse中的JUnit4進行的測試,咱們總共設計了16個測試單元,其中字符計數,詞計數,行計數各三個,進階單詞和詞頻各兩個。測試用例都是根據做業要求設計的各類字符混雜,有空白行,數字字母混雜的形式進行測試,測試結果都顯示咱們的程序知足了題目的要求。

單元測試 測試覆蓋 測試代碼塊 測試個數
BasicWordCountTest.testCharacterCount() 普通字符、空格、各類符號 BasicWordCountTest.CharacterCount() 3
BasicWordCountTest.testWordCount() 普通字符、空格、各類符號,字母大小寫,數字與字母各類組合 BasicWordCountTest.WordCount() 3
BasicWordCountTest.testLineCount() 空白行、非空白行 BasicWordCountTest.LineCount() 3
BasicWordCountTest.testTopTenWord() 普通字符、空格、各類符號,字母大小寫,數字與字母各類組合 BasicWordCountTest.TopTenWord() 3
AdvancedWord.TesttopWordWeighting() 混合單詞 AdvancedWord.topWordWeighting() 2
AdvancedWord.TesttopWordsWeighting() 混合詞組 AdvancedWord.topWordsWeighting() 2

部分測試代碼

package Untils;

import static org.junit.Assert.*;

import org.junit.Test;

public class BasicWordCountTest {
    public static BasicWordCount basic=new BasicWordCount();
    static String fileName="testinput2.txt";
    String []testTopWord= {"abcd123","here","your","aaaa","abss","bbbb","cccc","ddda","dera","esds"};
    int []testTopWordCount= {7,2,2,1,1,1,1,1,1,1};
    @Test
    //測試字符統計
    public void testCharacterCount() {
        System.out.println(basic.characterCount(fileName));
        assertEquals(189,basic.characterCount(fileName));
    }
    //測試單詞統計
    @Test
    public void testWordCount() {
        basic.wordCount(fileName);
        assertEquals(21,basic.wordCount(fileName));
    }

    @Test
    //測試top10單詞
    public void testTopTenWord() {
        basic.topTenWord(fileName);
        for(int i=9;i>0;i--) {
            System.out.println(testTopWord[9-i]+"=="+i+"=="+basic.topTenWord(fileName)[i].getKey());
            assertEquals(testTopWord[9-i],basic.topTenWord(fileName)[i].getKey());
            assertEquals(testTopWordCount[9-i],basic.topTenWord(fileName)[i].getCountNum());
        }
    }

    @Test
    //測試行數
    public void testLineCount() {
        basic.lineCount(fileName);
        assertEquals(4,basic.lineCount(fileName));
    }
}

其中一個測試結果截圖

在JUnit4的測試下,咱們的整體代碼覆蓋率在80%左右,其中Main.java類是用來輸出結果的類,因此沒有加入測試,還有一些緣由是不少的異常處理是沒有辦法觸發的,這些代碼沒有覆蓋住。不過咱們主要代碼的覆蓋率都在90%左右,甚至以上的,因此說咱們的測試結果仍是對程序正確性作了有力驗證的。

3、其餘

3.一、代碼規範:

​ 碼出高效 :阿里巴巴Java開發手冊終極版v1.3.0

3.二、分工狀況

221600327:

​ 行數統計、命令行參數解析、輸入輸出模塊代碼編寫、單元測試、文檔編寫

221600329:

​ 字符統計、單詞統計、詞頻統計模塊代碼編寫、爬蟲設計和實現、性能測試、文檔編寫

3.三、Github的代碼簽入記錄

3.四、遇到的代碼模塊異常或結對困難及解決方法

原本咱們認爲的詞組詞頻統計會過濾掉單詞間的非法字母數字字符,然後來助教重申了需求,要求輸出這些字符。由於原先的作法是先把非法字母數字字符都替換掉,而後再進行操做。這需求一改,不就全涼了。後面只能一個字符一個字符的遍歷,再截取單詞。可是最後發如今數據量大的時候,不採用split去分割字符串,直接遍歷反而速度更快,並且更省內存。

3.五、評價隊友

3.5.1 221600329 評價 221600327

隊友給夠按時完成分配的任務,有耐心,可能基礎不是特別紮實,可是肯學肯作,這點事值得確定的。

須要改進的地方:編碼能力須要增強。

3.5.2 221600327評價221600329

個人隊友在咱們結對中大部分時間是駕駛員的角色,他對於需求的分析能很快劃分紅若干個字模塊,在編程方面他數據結構和算法方面的基礎知識至關紮實,編碼實現能力也很強。我最欣賞的是個人隊友認真和仔細的態度,他對做業近乎追求完美,在知足正確性以後還儘可能去優化性能;還有他的堅決的信念,就算他在這周身體不舒服,天天狂咳嗽,可是他仍是沒有所以落下過一點進度,這是我很敬佩的。

須要改進的地方:在任務分配方面能夠均衡一些,否則會累着他本身。

3.六、 感想

此次做業碰上了我重感冒的時候,一直咳嗽不止(不敢熬夜了),再加上本身編程能力不突出,因此時間上安排的很差,對於附加部分的需求,沒有時間去考慮和設計。這兩次都是結對任務,我和隊友之間的協做能力有了進步,可是目前仍是沒有很高的效率,可能還沒度過學習階段,依然處於磨合階段。

3.七、學習進度

這兩週的任務都是結對任務,因此以此爲契機咱們閱讀了《構建之法》第四章兩人合做,瞭解到結對編程是極限編程這一思想的具體體現,結對編程有三種形式:

①鍵盤鼠標式②Ping-pong式③領航員-駕駛員式。

瞭解到結對編程,由於在結對編程過程當中有隨時的複審和交流,能夠減小犯錯,提升解決問題的效率,造成知識傳遞。

瞭解到要作好結對編程,須要遵照相同的代碼規範,在不一樣的階段,不一樣的人之間要有不一樣的方式,並且要養成我的良好的生活習慣。

可是我以爲雖然結對編程有不少好處,可是結對編程的兩個隊友,編程水平不能相差過大,否則可能會形成交流變成了教學,浪費更多的時間,影響效率。

相關文章
相關標籤/搜索