• <tr id="yyy80"></tr>
  • <sup id="yyy80"></sup>
  • <tfoot id="yyy80"><noscript id="yyy80"></noscript></tfoot>
  • 99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

    Onboard:以數(shù)據(jù)驅(qū)動(dòng)的敏捷軟件開發(fā)協(xié)同工具

    2016-12-22 04:15:12張世琨
    計(jì)算機(jī)研究與發(fā)展 2016年12期
    關(guān)鍵詞:源代碼代碼可視化

    陳 龍 葉 蔚 張世琨

    (軟件工程國家工程研究中心(北京大學(xué)) 北京 100871)(chenlongpku@163.com)

    ?

    Onboard:以數(shù)據(jù)驅(qū)動(dòng)的敏捷軟件開發(fā)協(xié)同工具

    陳 龍 葉 蔚 張世琨

    (軟件工程國家工程研究中心(北京大學(xué)) 北京 100871)(chenlongpku@163.com)

    Scrum是一種兼顧計(jì)劃性與靈活性的敏捷開發(fā)過程,能讓軟件開發(fā)團(tuán)隊(duì)具有快速工作和響應(yīng)變化的能力.軟件開發(fā)生命周期中每一個(gè)環(huán)節(jié)都會(huì)產(chǎn)生大量的數(shù)據(jù),如果能記錄下這些數(shù)據(jù)進(jìn)行分析,并通過可視化等手段展示和反饋,則能進(jìn)一步促進(jìn)團(tuán)隊(duì)管理、項(xiàng)目管理,提高開發(fā)效率.現(xiàn)有的軟件開發(fā)管理工具中,項(xiàng)目管理和代碼管理往往是相互獨(dú)立的,這導(dǎo)致了數(shù)據(jù)的分散和未充分利用.為推廣以Scrum為核心、以數(shù)據(jù)為驅(qū)動(dòng)的敏捷軟件開發(fā)過程,開發(fā)了一款基于云服務(wù)的Onboard敏捷軟件開發(fā)協(xié)同工具, 利用代碼提交和任務(wù)的關(guān)聯(lián),創(chuàng)造性地將敏捷過程管理、源代碼管理和項(xiàng)目管理有機(jī)地整合到一起,支持端到端的軟件全生命周期管理,從而能記錄下軟件開發(fā)過程中產(chǎn)生的所有數(shù)據(jù)并提取有價(jià)值的信息,為中小軟件開發(fā)團(tuán)提供一站式的敏捷開發(fā)管理與協(xié)同服務(wù).1)介紹了Onboard的設(shè)計(jì)理念;2)圍繞著“如何利用軟件開發(fā)過程中產(chǎn)生的數(shù)據(jù)更好地支持敏捷開發(fā)過程”和“如何評(píng)估團(tuán)隊(duì)成員貢獻(xiàn)度”兩大課題,全面介紹了數(shù)據(jù)可視化和數(shù)據(jù)分析在Onboard敏捷軟件開發(fā)協(xié)同工具中的應(yīng)用,并針對(duì)一系列相關(guān)問題提出了解決方案;3)對(duì)值得進(jìn)一步研究的問題進(jìn)行了展望.

    數(shù)據(jù)驅(qū)動(dòng);敏捷軟件開發(fā);Scrum;軟件生命周期;數(shù)據(jù)可視化;代碼提交與任務(wù)關(guān)聯(lián);貢獻(xiàn)度評(píng)估;代碼影響行數(shù)

    20世紀(jì)60年代中期“軟件危機(jī)”的出現(xiàn),使得人們不得不重新認(rèn)識(shí)軟件開發(fā)的標(biāo)準(zhǔn)、方法和技術(shù).2001年,17位軟件專家聚集在一起概括出了讓軟件開發(fā)團(tuán)隊(duì)能夠快速工作、響應(yīng)變化的價(jià)值觀和原則,進(jìn)而產(chǎn)生了我們現(xiàn)在所熟知的《敏捷軟件開發(fā)宣言》[1].研究表明,由于軟件是迭代發(fā)布的,在一個(gè)迭代過程中變化容易得到控制,因此敏捷軟件開發(fā)過程能有效地減少需求變化產(chǎn)生的成本[2].

    遵循敏捷價(jià)值觀和原則設(shè)計(jì)出來的軟件開發(fā)過程模型都是敏捷開發(fā)過程模型,其中近年來業(yè)界比較流行的是Scrum,一種兼顧計(jì)劃性與靈活性的敏捷開發(fā)過程.Scrum一詞的含義源自橄欖球[3],在19世紀(jì)90年代由Sutherland及他的開發(fā)團(tuán)隊(duì)提出,并在21世紀(jì)后由Schwaber和Beedle做了進(jìn)一步的改進(jìn)[4].Scrum開發(fā)過程從一開始就假定了混亂的存在[5],因而使得使用它的敏捷開發(fā)團(tuán)隊(duì)在必然存在的不確定性面前得以順利工作.Scrum團(tuán)隊(duì)以短小的迭代(sprint)為單位進(jìn)行工作,關(guān)于團(tuán)隊(duì)中的角色和典型的迭代流程的介紹可參見附錄A.

    然而Scrum方法并不是萬靈藥.國內(nèi)第一位看板教練吳穹在《精益開發(fā)與看板方法》[6]一書的推薦序中指出,在他多年敏捷咨詢的過程中,經(jīng)常需要進(jìn)場(chǎng)拯救那些將Scrum實(shí)施成小瀑布的項(xiàng)目.Scrum方法中的看板和燃盡圖為項(xiàng)目負(fù)責(zé)人把握項(xiàng)目進(jìn)度提供了最基本的工具,但僅僅有這些工具是不夠的,比如項(xiàng)目負(fù)責(zé)人無法利用看板和燃盡圖監(jiān)控軟件的質(zhì)量.軟件開發(fā)團(tuán)隊(duì)需要利用更多更先進(jìn)的工具促使開發(fā)過程達(dá)到敏捷的狀態(tài).

    經(jīng)常困擾項(xiàng)目負(fù)責(zé)人的另一個(gè)問題是:如何公平、高效地對(duì)團(tuán)隊(duì)成員的貢獻(xiàn)進(jìn)行評(píng)估.如果需要手動(dòng)去統(tǒng)計(jì)每個(gè)成員完成了幾個(gè)任務(wù)、提交了多少行代碼等,是非常瑣碎的.此外,一個(gè)軟件團(tuán)隊(duì)往往還分成若干小團(tuán)隊(duì)開發(fā)相關(guān)但相對(duì)獨(dú)立的子項(xiàng)目,尤其是在移動(dòng)互聯(lián)網(wǎng)快速發(fā)展的背景下,一個(gè)團(tuán)隊(duì)很可能同時(shí)開發(fā)Web端和多個(gè)移動(dòng)端的產(chǎn)品,這無疑使手動(dòng)的評(píng)估過程變得更加繁瑣.

    事實(shí)上,軟件開發(fā)生命周期的每一個(gè)環(huán)節(jié)都會(huì)產(chǎn)生大量的數(shù)據(jù),如果能記錄下這些數(shù)據(jù)并對(duì)這些數(shù)據(jù)進(jìn)行分析,提取有價(jià)值的信息,并通過可視化等技術(shù)進(jìn)行信息的展示和反饋,則能夠?yàn)殚_發(fā)團(tuán)隊(duì)的建設(shè)、項(xiàng)目進(jìn)度和質(zhì)量的控制、工作流程的完善等提供有力的支持,也為自動(dòng)化評(píng)估團(tuán)隊(duì)成員的貢獻(xiàn)提供了可能.

    團(tuán)隊(duì)成員間合作和溝通的傳統(tǒng)媒介往往是非常樸素的,比如面對(duì)面的溝通、白板、海報(bào)板、索引卡和便簽等[7].這些手段無法將軟件開發(fā)過程中產(chǎn)生的數(shù)據(jù)積累起來并加以利用.近些年來,很多軟件開發(fā)管理工具被開發(fā)出來,但這些工具往往功能比較專一,比如缺陷管理、源代碼管理、任務(wù)管理等,導(dǎo)致軟件開發(fā)過程中產(chǎn)生的數(shù)據(jù)過于分散,未能被充分整合利用.

    國內(nèi)項(xiàng)目管理工具的領(lǐng)跑者Tower從去年(2015-07-09)在標(biāo)準(zhǔn)項(xiàng)目之外開始支持敏捷項(xiàng)目[8],但其并沒有融入Scrum的流程即迭代.該產(chǎn)品也提供了團(tuán)隊(duì)成員貢獻(xiàn)度的統(tǒng)計(jì),但僅僅是計(jì)算了完成任務(wù)數(shù)量的百分比.此外,由于定位于一般的團(tuán)隊(duì)項(xiàng)目管理,Tower并不支持源代碼管理.

    Github是基于Git的代碼托管、版本管理和協(xié)同開發(fā)的云平臺(tái),集成了issue(類似于缺陷)管理、持續(xù)集成等功能,是開源軟件社區(qū)協(xié)作開發(fā)的首選.Github本身不支持以任務(wù)為核心的項(xiàng)目管理,這點(diǎn)和開源軟件的開發(fā)特點(diǎn)比較吻合,但無法滿足敏捷軟件開發(fā)團(tuán)隊(duì)的需求.

    還有一些工具,試圖整合項(xiàng)目管理和代碼管理.國內(nèi)比較知名的有Coding.Net,但它并不支持敏捷開發(fā),并且項(xiàng)目管理和代碼管理是相對(duì)獨(dú)立的模塊,沒有能有效整合并利用軟件開發(fā)過程中產(chǎn)生的數(shù)據(jù).

    我們認(rèn)為,對(duì)于軟件開發(fā)團(tuán)隊(duì)來說,項(xiàng)目管理和代碼管理是不可分割的整體.為推廣以Scrum為核心、以數(shù)據(jù)為驅(qū)動(dòng)的敏捷軟件開發(fā)過程,我們開發(fā)了一款基于云服務(wù)的Onboard敏捷軟件開發(fā)協(xié)同工具,利用代碼提交和任務(wù)的關(guān)聯(lián),創(chuàng)造性地將敏捷過程管理、源代碼管理和項(xiàng)目管理有機(jī)地整合到一起,支持端到端的軟件全生命周期管理,從而能記錄下軟件開發(fā)過程中產(chǎn)生的所有數(shù)據(jù)并提取有價(jià)值的信息,為中小軟件開發(fā)團(tuán)提供一站式的敏捷開發(fā)管理與協(xié)同服務(wù).

    本文結(jié)構(gòu)如下:1)介紹了Onboard敏捷軟件開發(fā)協(xié)同工具的設(shè)計(jì)理念、功能及架構(gòu),并和市面上主流的幾款相關(guān)的項(xiàng)目管理軟件進(jìn)行了對(duì)比;2)圍繞著如何利用軟件開發(fā)生命周期中各個(gè)環(huán)節(jié)產(chǎn)生的大量數(shù)據(jù)更好地支持敏捷開發(fā)過程、評(píng)估團(tuán)隊(duì)成員的貢獻(xiàn)度,介紹了Onboard開發(fā)團(tuán)隊(duì)在數(shù)據(jù)可視化和數(shù)據(jù)分析的實(shí)踐,著重討論了任務(wù)和代碼的關(guān)聯(lián)、代碼倉庫的可視化、團(tuán)隊(duì)成員貢獻(xiàn)度自動(dòng)化評(píng)估、缺陷預(yù)警和責(zé)任人推薦等問題;3)總結(jié)全文,列舉主要貢獻(xiàn),并展望進(jìn)一步的工作.

    1 Onboard介紹

    Onboard致力于做最專業(yè)的敏捷軟件開發(fā)協(xié)同工具.Onboard是注冊(cè)即用的云服務(wù)*http://onboard.cn,能夠通過Web,iOS和Android多種平臺(tái)使用,支持無處不在的開發(fā)協(xié)同.

    Onboard核心價(jià)值觀是推廣以Scrum為核心的敏捷軟件開發(fā)過程.Onboard將產(chǎn)品設(shè)計(jì)、編碼、測(cè)試、持續(xù)集成、發(fā)布和運(yùn)維等各階段進(jìn)行有機(jī)地連接和集成,支持端到端的軟件全生命周期管理,提高軟件開發(fā)人員之間的協(xié)作效率,從而加速軟件開發(fā),為中小軟件開發(fā)團(tuán)打造一站式的敏捷開發(fā)管理與協(xié)同服務(wù).

    Onboard提供的各項(xiàng)功能從邏輯上可以分為3個(gè)類別,彼此緊密聯(lián)系.

    1) 敏捷過程管理

    ① 通過看板來規(guī)劃敏捷軟件開發(fā)中的每一次的迭代,完美支持Scrum;

    ② 通過看板來追蹤需求、任務(wù)和缺陷的狀態(tài);

    ③ 展示每一次迭代的燃盡圖,以及代碼行數(shù)和代碼提交等豐富的統(tǒng)計(jì)信息.

    2) 源代碼管理

    ② 專業(yè)化的Code Review功能,對(duì)每一個(gè)代碼合并請(qǐng)求、每一次代碼提交、每一行代碼都能討論;

    ③ 需求、任務(wù)和缺陷與代碼有機(jī)關(guān)聯(lián),可以看到所有相關(guān)的代碼提交;

    ④ 后臺(tái)整合了Sonarqueb代碼質(zhì)量分析工具,網(wǎng)站通過訪問后臺(tái)的api展示分析的報(bào)告,其中包含技術(shù)債務(wù)等信息,便于團(tuán)隊(duì)對(duì)代碼質(zhì)量進(jìn)行把關(guān);

    ⑤ 后臺(tái)整合了Jenkins服務(wù)器,用戶可以在網(wǎng)站上撰寫自己的腳本,執(zhí)行代碼的構(gòu)建和測(cè)試,并可查看所有的歷史任務(wù)和執(zhí)行結(jié)果,實(shí)現(xiàn)持續(xù)集成;

    ⑥ 利用Docker容器技術(shù)為用戶部署Web應(yīng)用.

    3) 項(xiàng)目管理

    ① 通過Git客戶端與系統(tǒng)進(jìn)行交互,如關(guān)聯(lián)任務(wù)、完成任務(wù)等.

    ② 具備話題討論、任務(wù)分配、團(tuán)隊(duì)日歷、在線文檔、文件共享、團(tuán)隊(duì)管理這些通用的項(xiàng)目管理功能;

    ③ 項(xiàng)目所有相關(guān)活動(dòng)都能夠清晰地自動(dòng)記錄,并同過大量數(shù)據(jù)可視化,細(xì)粒度地展現(xiàn)項(xiàng)目的全貌;

    ④ 通過郵件和客戶端將團(tuán)隊(duì)動(dòng)態(tài)第一時(shí)間推送給團(tuán)隊(duì)成員;

    ⑤ 為項(xiàng)目的所有關(guān)鍵信息建立了全文索引,提供了搜索功能.

    此外Onboard還實(shí)現(xiàn)了功能的插件化,能讓用戶打造適合自己團(tuán)隊(duì)項(xiàng)目的工具集.Onboard現(xiàn)已開源,其開源版本的源代碼可以在Github*https://github.com/sercxtyf/onboard上找到.

    Onboard的整體架構(gòu)如圖1所示.

    Onboard在設(shè)計(jì)之初就考慮了數(shù)據(jù)的積累.從一句評(píng)論到一次代碼提交,凡是用戶在Onboard上進(jìn)行的操作都會(huì)生成活動(dòng)的日志.這為進(jìn)一步做數(shù)據(jù)挖掘提供了數(shù)據(jù)來源,進(jìn)而可以從數(shù)據(jù)中提取有價(jià)值的信息.

    Onboard將敏捷過程管理、源代碼管理和項(xiàng)目管理有機(jī)地整合在一起,從而支持軟件全生命周期的管理,并對(duì)軟件開發(fā)過程中產(chǎn)生的數(shù)據(jù)進(jìn)行收集和分析,在軟件工程業(yè)界是獨(dú)樹一幟的.表1把Onboard和其他一些業(yè)界主流的基于云服務(wù)的項(xiàng)目源代碼管理工具從功能上進(jìn)行了對(duì)比.

    Fig. 1 The system architecture of Onboard, an agile software development collaboration tool.圖1 Onboard敏捷軟件開發(fā)協(xié)同工具的系統(tǒng)架構(gòu)圖

    SaaSToolTaskManagementAgileProcessManagementSprintTaskVisualizationSourceCodeManagementCodeQualityAnalysisContinuousIntegrationGitCommitsStatisticsLinesofCodeStatisticsTowerYesYesNoYesNoNoNoNoNoCoding.NetYesNoNoNoYesYesYesYesNoMartianAgileDevToolYesYesYesNoNoNoNoNoNoGithubNoNoNoNoNoNoYesYesYesOnboardYesYesYesYesYesYesYesYesYes

    2 代碼提交與任務(wù)關(guān)聯(lián)

    敏捷開發(fā)強(qiáng)調(diào)的是對(duì)變化的快速響應(yīng),而實(shí)際開發(fā)過程中,Scrum敏捷開發(fā)團(tuán)隊(duì)最容易進(jìn)入的一個(gè)誤區(qū)就是把“敏捷”等同于“快速”,把“增量式地產(chǎn)出可工作的產(chǎn)品”等同于“盡可能按期完成迭代中的所有任務(wù)”——當(dāng)對(duì)照燃盡圖發(fā)現(xiàn)進(jìn)度落后時(shí),團(tuán)隊(duì)的第一反應(yīng)是要加快開發(fā)速度、甚至加班加點(diǎn)趕進(jìn)度,而不是去查找影響進(jìn)度的因素.如此一味追求進(jìn)度,導(dǎo)致對(duì)軟件質(zhì)量的忽視,也就無怪乎劣質(zhì)代碼入庫、產(chǎn)品“裸奔”上線等情況會(huì)頻頻發(fā)生.

    軟件質(zhì)量保障是軟件開發(fā)生命周期中不可缺少的一個(gè)環(huán)節(jié),而軟件的質(zhì)量主要體現(xiàn)在代碼的質(zhì)量.Scrum方法所描述的軟件開發(fā)過程,以及常用的看板、燃盡圖等工具,都是著眼于進(jìn)度管理的,無法輔助軟件質(zhì)量的管理.因此,敏捷軟件開發(fā)團(tuán)隊(duì),需要這樣一款工具,能把敏捷過程管理和源代碼管理結(jié)合起來.

    但是,僅僅把簡單敏捷過程管理工具和源代碼管理工具的功能加在一起是不夠的.一個(gè)需求是否被滿足、一項(xiàng)任務(wù)是否完成,取決于相關(guān)的代碼是否實(shí)現(xiàn)以及相關(guān)代碼的質(zhì)量,兩者是密不可分的.因此需要有一種機(jī)制能把敏捷過程管理和源代碼管理有機(jī)地聯(lián)系在一起,發(fā)揮“1+1>2”的作用.敏捷過程管理是對(duì)需求和任務(wù)的管理,源代碼管理是對(duì)代碼的管理,鑒于此,我們提出了代碼提交與任務(wù)進(jìn)行關(guān)聯(lián)的機(jī)制.這里的任務(wù)是廣義的,既包含滿足產(chǎn)品需求所要實(shí)現(xiàn)的具體步驟,也包含待修復(fù)的缺陷.

    有2種途徑實(shí)現(xiàn)代碼和任務(wù)的關(guān)聯(lián):1)將合并請(qǐng)求(pull-request)和任務(wù)關(guān)聯(lián);2)將代碼提交(commit)和任務(wù)關(guān)聯(lián).

    代碼提交是指本地開發(fā)時(shí)增量保存當(dāng)前新修改的代碼,同時(shí)在代碼提交注釋(commit message)中注明這些代碼的作用.一般建議是及時(shí)提交修改,以便發(fā)生錯(cuò)誤時(shí)能快速復(fù)原代碼,故一個(gè)任務(wù)往往對(duì)應(yīng)多次代碼提交.Github支持在commit message里面填寫#{issueId},當(dāng)代碼提交推送至Github時(shí),系統(tǒng)自動(dòng)識(shí)別#{issueId},將代碼提交和相應(yīng)的issue關(guān)聯(lián).如果在#{issueId}之前添加關(guān)鍵詞close或fix,還可以自動(dòng)關(guān)閉該issue.Github中的issue類似于缺陷,但不完全等同,因?yàn)閕ssue還可以是討論或建議等.

    相比之下,在敏捷開發(fā)過程中,將代碼提交和任務(wù)相關(guān)聯(lián)是更合適的選擇.迭代中的任務(wù)主要是需求分解成的具體實(shí)現(xiàn)步驟,Scrum方法提倡任務(wù)粒度細(xì)化,以小時(shí)為單位估計(jì)任務(wù)的工作量,故一次合并請(qǐng)求中可能包含多次代碼提交,并且對(duì)應(yīng)著多個(gè)相關(guān)的任務(wù).因此,無論在多個(gè)任務(wù)中關(guān)聯(lián)一個(gè)合并請(qǐng)求,或是在一個(gè)合并請(qǐng)求的描述中添加多個(gè)任務(wù),都比較繁瑣.相反,一次代碼提交通常只對(duì)應(yīng)一個(gè)任務(wù),若借鑒Github的做法,利用代碼提交的commit message實(shí)現(xiàn)代碼和任務(wù)的自動(dòng)關(guān)聯(lián),則操作十分簡便.

    我們?cè)贠nboard中采用了第2種途徑實(shí)現(xiàn)代碼和任務(wù)的關(guān)聯(lián),并做了如下改進(jìn):

    1) 迭代中的看板由“未開始”、“正在做”和“已完成”3個(gè)基本欄目構(gòu)成,團(tuán)隊(duì)可根據(jù)自身需要在“正在做”和“已完成”之間添加新的欄目,比如“等待測(cè)試”、“等待驗(yàn)收”等.當(dāng)commit message中的任務(wù)編號(hào)前添加了fix或close等關(guān)鍵字后,默認(rèn)將該任務(wù)從當(dāng)前欄目移動(dòng)到下一個(gè)欄目,而非完成任務(wù).

    2) 若發(fā)生漏操作或誤操作,在倉庫所有代碼提交的列表頁面中,可以添加或解除任務(wù)關(guān)聯(lián),亦可在某個(gè)任務(wù)的相關(guān)聯(lián)的代碼提交列表中解除關(guān)聯(lián).

    3) 創(chuàng)建合并請(qǐng)求時(shí),默認(rèn)將本次合并請(qǐng)求所包含的所有代碼提交的commit message合并為合并請(qǐng)求的描述,代碼審核者可點(diǎn)擊描述中的任務(wù)編號(hào),便捷地打開相應(yīng)的任務(wù)進(jìn)行查看.這也間接地實(shí)現(xiàn)了合并請(qǐng)求和任務(wù)的關(guān)聯(lián).

    將代碼提交和任務(wù)關(guān)聯(lián),從功能上打通了敏捷項(xiàng)目管理和源代碼管理,具有7點(diǎn)好處:

    1) 團(tuán)隊(duì)成員在提交代碼的同時(shí)就能改變?nèi)蝿?wù)的狀態(tài);

    2) 便于產(chǎn)品負(fù)責(zé)人跟蹤任務(wù)的進(jìn)度和具體實(shí)現(xiàn);

    3) 提供關(guān)于任務(wù)更有價(jià)值的信息,便于項(xiàng)目負(fù)責(zé)人了解任務(wù)的工作量和質(zhì)量;

    4) 對(duì)于缺陷,能通過關(guān)聯(lián)的代碼提交準(zhǔn)確定位到產(chǎn)生缺陷的代碼文件及具體位置;

    5) 便于團(tuán)隊(duì)知識(shí)的積累、分享和傳承.需求分解成了任務(wù),任務(wù)關(guān)聯(lián)了代碼,如果有新的團(tuán)隊(duì)成員加入,或者團(tuán)隊(duì)成員之間互相學(xué)習(xí)等,希望了解一項(xiàng)功能是具體如何實(shí)現(xiàn)的,可以順著“需求→任務(wù)→代碼”這條線索,定位和功能相關(guān)的代碼,從代碼級(jí)別深入了解;

    6) 能從任務(wù)和代碼2個(gè)維度共同刻畫出“開發(fā)者畫像”;

    7) 可以更準(zhǔn)確地判斷出有代碼關(guān)聯(lián)的任務(wù)的結(jié)束時(shí)間,從而更準(zhǔn)確地描述任務(wù)尤其是缺陷的生存期.

    3 敏捷開發(fā)過程的可視化分析

    數(shù)據(jù)可視化主要是借助于圖形化手段,清晰有效地傳達(dá)與溝通信息.和計(jì)算機(jī)相比,人腦更善于理解視覺圖像并從視覺圖像中提取有價(jià)值的信息,因此,數(shù)據(jù)可視化技術(shù)能更有效地幫助人們理解數(shù)據(jù).軟件開發(fā)生命周期的每一個(gè)環(huán)節(jié)都會(huì)產(chǎn)生大量的數(shù)據(jù),可視化分析的方法是從這些大量的數(shù)據(jù)中提取有價(jià)值的信息的有效手段.

    Onboard收集了用戶在開發(fā)過程中產(chǎn)生的所有數(shù)據(jù),并通過可視化的技術(shù)進(jìn)行信息的提取和展示,從而為開發(fā)團(tuán)隊(duì)的建設(shè)、項(xiàng)目進(jìn)度的控制、工作流程的完善、團(tuán)隊(duì)成員貢獻(xiàn)的自動(dòng)化評(píng)估提供有力的支持.

    在可視化實(shí)踐的過程中,我們強(qiáng)調(diào)圖表的可交互性.可交互的圖表具有更好的用戶體驗(yàn),也能豐富圖表的語義,展現(xiàn)復(fù)雜、多維度的數(shù)據(jù).比如,在Onboard提供的統(tǒng)計(jì)圖中,可以通過選擇不同的項(xiàng)目成員,對(duì)展示的數(shù)據(jù)進(jìn)行篩選;也可以選擇查看不同時(shí)間區(qū)間的數(shù)據(jù);響應(yīng)用戶操作時(shí),多張統(tǒng)計(jì)圖可以聯(lián)動(dòng)地變化等.

    在可視化的機(jī)制上,我們采用了先用Web Api從后臺(tái)獲取相關(guān)數(shù)據(jù)、后用Javascript在前端處理數(shù)據(jù)并繪圖展示的方式.我們?cè)陂_發(fā)過程中使用了D3.js等第三方開源的Javascript庫.

    由于可交互性的需求,在獲取一組數(shù)據(jù)時(shí),先拿到了所有成員的數(shù)據(jù),存儲(chǔ)在圖表對(duì)應(yīng)的Javascript對(duì)象中,再根據(jù)用戶的操作篩選數(shù)據(jù).這樣可以避免在切換成員時(shí)頻繁向后臺(tái)發(fā)送ajax請(qǐng)求,前端處理數(shù)據(jù)、繪圖的速度相對(duì)較快,用戶體驗(yàn)較好;此外可以同時(shí)展示全體成員和個(gè)體的2張圖,進(jìn)行對(duì)比.

    下面將介紹在Onboard中,如何利用可視化分析支持敏捷開發(fā)過程.

    3.1 活動(dòng)記錄的Punch Card圖

    Punch Card中文意思是穿孔卡,最早運(yùn)用在IBM計(jì)算機(jī)上,通過在紙片上不同的位置上穿孔代表不同的數(shù)據(jù).而在數(shù)據(jù)可視化領(lǐng)域,Punch Card又被賦予了新的含義.以活動(dòng)記錄的Punch Card圖為例,縱軸刻度表示周一至周日,橫軸刻度表示0點(diǎn)至23點(diǎn),于是平面上就由坐標(biāo)軸形成了多個(gè)交點(diǎn).每個(gè)交點(diǎn)上的一個(gè)圓代表數(shù)據(jù)點(diǎn),數(shù)值為對(duì)應(yīng)的一個(gè)小時(shí)內(nèi)的活動(dòng)記錄數(shù)量,圓的大小或顏色的深淺代表數(shù)值的大小.如圖2所示:

    Fig. 2 User’s Punch Card of number of activities on Onboard.圖2 用戶在Onboard上活動(dòng)數(shù)目的Punch Card圖

    用戶在使用Onboard時(shí),任何的操作都會(huì)生成一條活動(dòng)記錄.獲取一段時(shí)間內(nèi)用戶活動(dòng)記錄的數(shù)目并繪制成Punch Card圖,可以發(fā)現(xiàn)一些有趣的信息,從而幫助項(xiàng)目負(fù)責(zé)人了解團(tuán)隊(duì)成員的工作狀態(tài).比如:

    1) 假設(shè)每周五是開迭代評(píng)審會(huì)和反思會(huì)的時(shí)間,如果發(fā)現(xiàn)團(tuán)隊(duì)成員的活動(dòng)記錄突出集中在周五的前兩天,說明團(tuán)隊(duì)中存在趕deadline的現(xiàn)象,平常可能有消極怠工,需要及時(shí)干預(yù);

    2) 可以了解團(tuán)隊(duì)成員的偏好,如喜歡白天工作還是夜里工作;

    3) 通過成員之間的對(duì)比,判斷整個(gè)團(tuán)隊(duì)工作的步調(diào)是否一致,是否有良好的協(xié)作.

    3.2 缺陷統(tǒng)計(jì)圖

    缺陷的及時(shí)發(fā)現(xiàn)和修復(fù)是軟件開發(fā)過程中不可缺少的一個(gè)環(huán)節(jié).一個(gè)成員發(fā)現(xiàn)缺陷數(shù)目和修復(fù)缺陷數(shù)目的多少,可以反映出該成員是否具有產(chǎn)品的主人翁精神.在缺陷管理模塊中,Onboard提供了對(duì)比團(tuán)隊(duì)成員之間發(fā)現(xiàn)缺陷數(shù)目和修復(fù)缺陷數(shù)目的2張餅圖.

    3.3 代碼提交數(shù)據(jù)可視化

    代碼提交次數(shù)和行數(shù)是軟件開發(fā)團(tuán)隊(duì)衡量工作量最重要的指標(biāo)之一.Github為托管在上面的代碼倉庫提供了豐富的統(tǒng)計(jì)圖,非常值得參考,特別是Contributors,Commits和Punch Card.

    如圖3所示,在Contributors統(tǒng)計(jì)圖中,可以在右上角切換3個(gè)統(tǒng)計(jì)量:增加的代碼行數(shù)、刪除的代碼行數(shù)、代碼提交的數(shù)目.左上方注明了倉庫存在的時(shí)間,時(shí)間下方是一句說明,意思是“只統(tǒng)計(jì)對(duì)master分支的貢獻(xiàn),并且不包含合并請(qǐng)求時(shí)產(chǎn)生的代碼提交”.位于中間的第1張圖在時(shí)間軸上呈現(xiàn)了master分支上統(tǒng)計(jì)量隨時(shí)間的變化,時(shí)間軸的下方枚舉了不同貢獻(xiàn)者的數(shù)據(jù).在第1張圖中可以用鼠標(biāo)拉取時(shí)間窗,下方的不同貢獻(xiàn)者的統(tǒng)計(jì)圖會(huì)隨之變化,只展示時(shí)間窗內(nèi)的數(shù)據(jù).

    在敏捷開發(fā)過程中,也需要統(tǒng)計(jì)團(tuán)隊(duì)成員的代碼貢獻(xiàn)量.我們?cè)贠nboard中同樣做了代碼提交的可視化,和Github有相似之處,但也有創(chuàng)新.

    最大的一點(diǎn)不同是,我們采用了多分支的統(tǒng)計(jì)而不是基于master單一分支的統(tǒng)計(jì).這是考慮到了團(tuán)隊(duì)項(xiàng)目和開源項(xiàng)目固有的區(qū)別.對(duì)于Github上的開源項(xiàng)目,任何人都可以創(chuàng)建新的分支,在上面修改或添加代碼并提交,這些代碼可能是重復(fù)的、不必要的甚至錯(cuò)誤的.因此,判斷開發(fā)者是否對(duì)開源項(xiàng)目產(chǎn)生貢獻(xiàn),比較合理的是看他提交的代碼有沒有被合并進(jìn)master分支.而在敏捷開發(fā)團(tuán)隊(duì)中,一般不會(huì)出現(xiàn)“無用功”的代碼,因此,凡是同步到Onboard上托管的中央倉庫的分支所包含的代碼提交都應(yīng)計(jì)入工作量的統(tǒng)計(jì)之中.

    另外,我們把代碼的增加行數(shù)(最上方的折線)和刪除行數(shù)(最下方的折線)并排顯示在折線圖中,同時(shí)顯示一條虛線(中間的折線)表示倉庫代碼總量的變化,并在圖的下方添加了團(tuán)隊(duì)成員對(duì)比的餅圖,如圖4所示.

    Fig. 3 Contributors graphs on Github (based on Apache Spark project).圖3 Github貢獻(xiàn)者統(tǒng)計(jì)圖(以Apache Spark項(xiàng)目為例)

    Fig. 4 Code contribution graph on Onboard.圖4 Onboard中代碼行數(shù)統(tǒng)計(jì)圖

    值得一提的是圖4中3個(gè)圖是聯(lián)動(dòng)的:點(diǎn)擊任意餅圖中的切片,2張餅圖相應(yīng)的切片都會(huì)突出,在上方的折線圖中則會(huì)相應(yīng)顯示切片對(duì)應(yīng)的用戶的統(tǒng)計(jì)數(shù)據(jù).

    代碼提交的次數(shù)則單獨(dú)制作了一張統(tǒng)計(jì)圖,與圖4類似.此外還繪制了代碼提交次數(shù)的Punch Card.

    另一個(gè)創(chuàng)新的地方是在數(shù)據(jù)點(diǎn)的tooltip中顯示了數(shù)據(jù)點(diǎn)包含的代碼提交列表,而不僅僅是代碼總行數(shù)或總次數(shù).點(diǎn)擊代碼提交的ID,會(huì)打開一個(gè)浮動(dòng)的窗口,顯示這次代碼提交影響的代碼.這大大增加了統(tǒng)計(jì)圖的可交互性.如圖5所示.

    Fig. 5 Punch Card of number of commits with enhanced tooltips.圖5 帶列表和導(dǎo)航的代碼提交次數(shù)Punch Card圖

    我們額外維護(hù)了一張Git_email和Onboard_user的關(guān)聯(lián)表,目的是將代碼提交準(zhǔn)確地和團(tuán)隊(duì)成員對(duì)應(yīng),避免用戶在Git中設(shè)置的email和用戶在Onboard中設(shè)置的email不一致而產(chǎn)生的問題.

    3.4 迭代總結(jié)報(bào)告

    除了Scrum方法中常見的燃盡圖之外,我們?cè)贠nboard中還設(shè)計(jì)了一份詳實(shí)的迭代總結(jié)報(bào)告.報(bào)告中除了列舉本次迭代中已滿足的需求、完成的任務(wù)之外,還整合了燃盡圖、任務(wù)統(tǒng)計(jì)、代碼提交統(tǒng)計(jì)等統(tǒng)計(jì)圖.利用報(bào)告,在召開迭代總結(jié)會(huì)時(shí)能夠做到3點(diǎn).

    1) 確認(rèn)迭代完成的質(zhì)量;

    2) 了解各個(gè)團(tuán)隊(duì)成員的工作量和工作狀態(tài);

    3) 發(fā)現(xiàn)迭代中存在的問題,在下次迭代中進(jìn)行改進(jìn).

    有2點(diǎn)特別值得注意:1)這些統(tǒng)計(jì)圖是聯(lián)動(dòng)的,可以同時(shí)切換顯示某個(gè)成員的統(tǒng)計(jì)數(shù)據(jù);2)在后臺(tái)加入了snapshot(快照)的機(jī)制,一旦結(jié)束當(dāng)前迭代之后,這份報(bào)告將永遠(yuǎn)保存下來,里面的數(shù)據(jù)和統(tǒng)計(jì)圖都不會(huì)發(fā)生變化,以供日后回顧時(shí)查看.

    4 團(tuán)隊(duì)成員貢獻(xiàn)度評(píng)估

    4.1 代碼影響行數(shù)(affected lines of code, ALOC)

    代碼量是軟件開發(fā)團(tuán)隊(duì)中衡量成員工作量的最重要的指標(biāo)之一.在用Git進(jìn)行版本管理的代碼倉庫中統(tǒng)計(jì)代碼量時(shí),通常會(huì)計(jì)算2個(gè)指標(biāo):1)增加的代碼行數(shù);2)刪除的代碼行數(shù),對(duì)每次代碼提交分別計(jì)算再累加而成.Github和Onboard中的代碼統(tǒng)計(jì)都是這樣做的.那么,問題出現(xiàn)了:給出了增加的代碼行數(shù)和刪除的代碼行數(shù),如何衡量代碼量呢?

    在開發(fā)過程中,對(duì)代碼的改動(dòng)無外乎3種情況:增加代碼、刪除代碼、重構(gòu)代碼.在重構(gòu)代碼時(shí),既有代碼的增加,也有代碼的刪除,因而不能把增加的代碼行數(shù)和刪除的代碼行數(shù)簡單加在一起來衡量代碼量.若僅考慮代碼的增加量,有這樣一個(gè)缺陷:代碼重構(gòu)時(shí),常常會(huì)通過設(shè)計(jì)模式或更好的算法,用更精煉的代碼替換原有代碼,在這種情況下,用較少的新增的代碼行數(shù),無法衡量減少了更大篇幅代碼所做工作的價(jià)值.

    另一個(gè)需要考慮的問題是:刪除的代碼行數(shù)是否計(jì)算在工作量之內(nèi)?我們認(rèn)為,單純地刪除代碼不考慮在內(nèi).

    此外,還有2種特殊情況需要區(qū)別對(duì)待:引入第三方庫,往往會(huì)增加大量的代碼行數(shù);挪動(dòng)一個(gè)代碼文件的位置會(huì)產(chǎn)生一對(duì)數(shù)值很大且相同的增加的代碼行數(shù)和刪除的代碼行數(shù).

    綜合以上考慮,我們提出了代碼影響行數(shù)ALOC的概念來衡量代碼量.把一次代碼提交的ALOC記為commitALOC,把一處代碼增量差異(diff)的ALOC記為diffALOC.我們是這樣計(jì)算commitALOC的:

    若本次代碼提交是分支合并產(chǎn)生的合并結(jié)點(diǎn),忽略不計(jì);

    對(duì)代碼提交中的每一處diff: 若只有代碼的增加,則diffALOC=增加的代碼行數(shù);

    若只有代碼的減少,則diffALOC=0;

    若既有代碼的增加也有代碼的減少,則diffALOC=max(增加的代碼行數(shù),刪除的代碼行數(shù));

    若diffALOC超過了限制(如300行),則diffALOC=0;

    累計(jì)所有diffALOC,得到一次代碼提交的commitALOC;

    若commitALOC超過了限制(如3 000行),則commitALOC=0.

    在實(shí)際使用Onboard的過程中,驗(yàn)證了ALOC是衡量代碼量的有效指標(biāo).

    4.2 跨項(xiàng)目的團(tuán)隊(duì)統(tǒng)計(jì)

    Onboard允許一個(gè)團(tuán)隊(duì)建立多個(gè)項(xiàng)目,一名團(tuán)隊(duì)成員可以加入一個(gè)或多個(gè)項(xiàng)目.每個(gè)項(xiàng)目相對(duì)獨(dú)立,有自己的代碼倉庫和迭代等.第3節(jié)所介紹的數(shù)據(jù)可視化分析都是基于單個(gè)項(xiàng)目的.

    實(shí)際調(diào)研后發(fā)現(xiàn),一個(gè)開發(fā)團(tuán)隊(duì)往往同時(shí)并行若干個(gè)子項(xiàng)目,特別是創(chuàng)業(yè)型的團(tuán)隊(duì),而項(xiàng)目負(fù)責(zé)人只有一個(gè).例如Onboard團(tuán)隊(duì)曾在某一段時(shí)間內(nèi),同時(shí)開發(fā)Web應(yīng)用、安卓應(yīng)用和蘋果應(yīng)用.手動(dòng)統(tǒng)計(jì)每個(gè)成員的工作量,比如提交的代碼行數(shù)等是一件非常繁瑣的事情.有了數(shù)據(jù)可視化工具的輔助,這項(xiàng)工作就大大簡化了,通常只要查看統(tǒng)計(jì)圖、在統(tǒng)計(jì)圖中進(jìn)行一些交互操作即可.但在多項(xiàng)目并行的情況下,項(xiàng)目負(fù)責(zé)人若想比較團(tuán)隊(duì)各個(gè)成員的工作量、了解團(tuán)隊(duì)整體的動(dòng)態(tài),仍需要分別查看各個(gè)項(xiàng)目的統(tǒng)計(jì)數(shù)據(jù)再進(jìn)一步匯總.因此,跨項(xiàng)目的團(tuán)隊(duì)統(tǒng)計(jì)能夠進(jìn)一步解決項(xiàng)目負(fù)責(zé)人的痛點(diǎn).

    在Onboard上的團(tuán)隊(duì)統(tǒng)計(jì)頁面,我們提供了這樣一個(gè)可視化的統(tǒng)計(jì)工具,如圖6所示:

    Fig. 6 Visualization tool of team statistics across projects.圖6 跨項(xiàng)目的團(tuán)隊(duì)統(tǒng)計(jì)工具

    該工具包含7項(xiàng)功能:

    1) 有5個(gè)統(tǒng)計(jì)量供用戶選擇:活動(dòng)記錄數(shù)量、完成的任務(wù)數(shù)量(狹義,指從需求分解出的任務(wù))、修復(fù)的缺陷數(shù)量、代碼影響行數(shù)、代碼提交次數(shù);

    2) 可以自定義統(tǒng)計(jì)的日期范圍;

    3) 可以選擇團(tuán)隊(duì)所有項(xiàng)目匯總后的統(tǒng)計(jì)數(shù)據(jù),也可以單獨(dú)查看某一個(gè)項(xiàng)目;

    4) 提供了團(tuán)隊(duì)成員之間數(shù)據(jù)對(duì)比的餅圖;

    5) 點(diǎn)擊餅圖中的切片,可以選擇性地查看某一個(gè)成員的數(shù)據(jù);

    6) 提供了時(shí)間變化趨勢(shì)圖和Punch Card圖,可以進(jìn)行切換;

    7) 點(diǎn)擊數(shù)據(jù)點(diǎn),右側(cè)顯示該數(shù)據(jù)點(diǎn)包含的具體內(nèi)容.

    4.3 團(tuán)隊(duì)成員貢獻(xiàn)度的自動(dòng)評(píng)估模型

    軟件開發(fā)生命周期的每一個(gè)環(huán)節(jié)都會(huì)產(chǎn)生大量的數(shù)據(jù),而Onboard支持軟件開發(fā)全生命周期的管理,并記錄了用戶所有的操作,這些數(shù)據(jù)的積累為建立團(tuán)隊(duì)成員貢獻(xiàn)度的自動(dòng)評(píng)估模型提供了可能.

    我們做了這樣的實(shí)驗(yàn):選取若干次迭代為研究對(duì)象,獲取了迭代起止時(shí)間范圍內(nèi)團(tuán)隊(duì)成員的各類數(shù)據(jù),分別計(jì)算出每個(gè)成員的5個(gè)統(tǒng)計(jì)量——活動(dòng)記錄數(shù)量、完成的任務(wù)數(shù)量、修復(fù)的缺陷數(shù)量、代碼影響行數(shù)、代碼提交次數(shù),作為自變量;從項(xiàng)目負(fù)責(zé)人那獲取了每個(gè)迭代中各個(gè)成員的評(píng)分(百分制,團(tuán)隊(duì)成員互評(píng)+負(fù)責(zé)人打分)作為應(yīng)變量,然后通過統(tǒng)計(jì)學(xué)的方法計(jì)算一個(gè)模型,能夠利用5個(gè)自變量預(yù)測(cè)評(píng)分.

    為了讓模型有更好的解釋性,我們從線性回歸模型開始入手.

    方案1.

    Y評(píng)分~β0+β1X活動(dòng)數(shù)+β2X任務(wù)數(shù)+β3X缺陷數(shù)+

    β4X代碼影響行數(shù)+β5X代碼提交次數(shù),β1~β5>0.

    擬合后得到的結(jié)果并不是很理想.首先通過探索性分析發(fā)現(xiàn),代碼影響行數(shù)和代碼提交次數(shù)存在很強(qiáng)的共線性,因此代碼影響行數(shù)和代碼提交次數(shù)在線性模型里面只能保留一個(gè).保留代碼影響行數(shù)后,凡是出現(xiàn)系數(shù)β值為負(fù)數(shù)時(shí),就把相應(yīng)的變量從模型中剔除,如此反復(fù)計(jì)算,最后得到的模型中,系數(shù)β顯著不為0的變量僅僅只有代碼影響行數(shù)!顯然這個(gè)模型過于簡略,無法投入到實(shí)際應(yīng)用中去,比如它無法評(píng)價(jià)沒有代碼提交卻有完成任務(wù)的成員的貢獻(xiàn)量.

    由于我們要求模型要有好的解釋性,從而限制了β1~β5>0.其實(shí)β的含義是非常明確的,表示某一項(xiàng)指標(biāo)在綜合考核指標(biāo)中所占的比例.若再加上一條所有β之和為1的限制,可以把這個(gè)問題轉(zhuǎn)化為帶有約束的優(yōu)化問題.

    方案2.

    定義變量P=

    損失函數(shù)為

    ∑|Y評(píng)分-(β1P活動(dòng)數(shù)+β2P任務(wù)數(shù)+β3P缺陷數(shù)+

    β4P代碼影響行數(shù))|;

    約束條件為β1~β4>0,β1+β2+β3+β4=1.

    編程求解過程中,可設(shè)系數(shù)β的最小步長為0.05,遍歷所有β1~β4的可能取值(3重循環(huán)),返回使損失函數(shù)取值最小時(shí)β1~β4的取值.最后得到的結(jié)果是β1=0.55,β2=0.15,β3=0.15,β4=0.15.

    將輸出的模型應(yīng)用到評(píng)估團(tuán)隊(duì)成員貢獻(xiàn)度,如圖7所示.圖7中用p1~p19表示團(tuán)隊(duì)成員的姓名,同時(shí)存在不活躍的團(tuán)隊(duì)成員.

    Fig. 7 Demo of team member contribution evaluation.圖7 團(tuán)隊(duì)成員貢獻(xiàn)評(píng)估示例

    5 數(shù)據(jù)可視化和數(shù)據(jù)分析的更多應(yīng)用

    5.1 團(tuán)隊(duì)成員關(guān)鍵詞詞云

    詞云(word cloud)是一種有趣的、有獨(dú)特視覺效果的文本信息可視化工具,最早起源于標(biāo)簽云,在20世紀(jì)末由Flickr等網(wǎng)站的大量使用而普及開來[9].詞云是在一定區(qū)域內(nèi)不重疊地?cái)[放一組不同字體大小的單詞形成的,字體的大小通常表示單詞的權(quán)重,如詞頻.單詞的顏色通常只是為了視覺效果的美觀,沒有其他含義.

    將每個(gè)團(tuán)隊(duì)成員的關(guān)鍵詞按一定權(quán)重制作成詞云,可以一目了然地展示該成員所關(guān)注的問題、曾參與開發(fā)的功能等信息,起到類似用戶畫像的作用.

    如何提取團(tuán)隊(duì)成員的關(guān)鍵詞并計(jì)算權(quán)重呢?如果把用戶看成一篇文章,把軟件開發(fā)過程中積累下來的和該用戶相關(guān)的文本信息的總和看成是文章的內(nèi)容,那么就可以用文章關(guān)鍵詞自動(dòng)提取的技術(shù),實(shí)現(xiàn)用戶關(guān)鍵詞的自動(dòng)提取.

    從很長的文章中提取關(guān)鍵詞,涉及到數(shù)據(jù)挖掘、文本處理、信息檢索等很多計(jì)算機(jī)前沿領(lǐng)域,但有一個(gè)簡明、有效的經(jīng)典算法——TF-IDF算法:

    TF-IDF=詞頻(TF)×逆文檔頻率(IDF);

    詞頻(TF)=

    逆文檔頻率(IDF)=

    可以看到,TF-IDF與一個(gè)詞在文章中出現(xiàn)的次數(shù)成正比,與這個(gè)詞在整個(gè)語料庫中出現(xiàn)的次數(shù)成反比.

    引申到提取團(tuán)隊(duì)成員的關(guān)鍵詞,則:

    詞頻(TF)=

    引申后的TF-IDF可以表示對(duì)一個(gè)單詞對(duì)某一用戶而言的權(quán)重.

    計(jì)算一個(gè)用戶所有相關(guān)單詞的TF-IDF并按降序排列,取前N個(gè),就是該用戶的關(guān)鍵詞.

    在代碼實(shí)現(xiàn)過程中,我們是這樣設(shè)計(jì)流程并優(yōu)化的:

    1) 在數(shù)據(jù)庫建立一張用戶-單詞關(guān)聯(lián)表,記錄用戶不同單詞的詞頻(單詞出現(xiàn)的次數(shù)),當(dāng)用戶在Onboard上操作時(shí),就提取相關(guān)的文本(包括但不僅限于發(fā)起的討論、評(píng)論、完成任務(wù)的內(nèi)容及相關(guān)聯(lián)的需求、修復(fù)的缺陷描述、代碼提交中的commit message、上傳文件的文件名等),進(jìn)行中英文分詞操作,并更新該用戶這些詞的詞頻以及所有團(tuán)隊(duì)成員的這些詞的TF-IDF.

    2) 向后臺(tái)請(qǐng)求用戶的關(guān)鍵詞列表時(shí),后臺(tái)返回的是根據(jù)TF-IDF排序的、有數(shù)量上限的(如100個(gè))關(guān)鍵詞列表.

    3) 繪圖算法中,根據(jù)該用戶的關(guān)鍵詞數(shù)目,優(yōu)化最小字體號(hào),為了在關(guān)鍵詞數(shù)目較少時(shí)繪制的詞云不至于太過稀疏.

    4) 點(diǎn)擊詞云中的關(guān)鍵詞,跳轉(zhuǎn)到搜索頁面,自動(dòng)顯示和該用戶相關(guān)的這個(gè)關(guān)鍵詞的搜索結(jié)果.

    我們用d3-cloud*https://github.com/jasondavies/d3-cloud第三方Javascript插件繪制關(guān)鍵詞詞云,展示在團(tuán)隊(duì)成員的個(gè)人頁面,如圖8所示:

    Fig. 8 Demonstration of keyword cloud of a team member.圖8 團(tuán)隊(duì)成員關(guān)鍵詞詞云示例

    5.2 缺陷生存期預(yù)警

    缺陷是軟件開發(fā)團(tuán)隊(duì)不愿意遇見的,但卻永遠(yuǎn)無法避免的.缺陷一旦出現(xiàn),最理想的狀態(tài)當(dāng)然是越快修復(fù)越好,但這種“變化”很容易打亂團(tuán)隊(duì)的開發(fā)計(jì)劃.實(shí)際開發(fā)中,嚴(yán)重、緊急的缺陷一般要盡快修復(fù),而不是那么緊急的缺陷,有的團(tuán)隊(duì)會(huì)指定專人負(fù)責(zé)修復(fù)缺陷;有的團(tuán)隊(duì)習(xí)慣把缺陷擱置一旁,等累積到一定數(shù)目再集中時(shí)間修復(fù);也有的團(tuán)隊(duì)在計(jì)劃任務(wù)時(shí)會(huì)預(yù)留出修復(fù)缺陷的時(shí)間,將缺陷修復(fù)和新功能的開發(fā)交替進(jìn)行.

    Scrum方法中沒有具體說明如何管理缺陷,一般而言,可以把缺陷看作一類需求,在開迭代計(jì)劃會(huì)時(shí)和其他需求一并安排進(jìn)入下一次迭代[3].我們建議,緊急程度較高的缺陷可以添加進(jìn)當(dāng)前迭代,在計(jì)劃會(huì)時(shí)可以根據(jù)經(jīng)驗(yàn)預(yù)留一定的工作量.

    一個(gè)缺陷的重要程度是會(huì)隨時(shí)間發(fā)生變化的,如果存在的時(shí)間越長,就越應(yīng)該引起團(tuán)隊(duì)的重視.Onboard中設(shè)計(jì)了這樣一種機(jī)制:若一個(gè)缺陷存在的時(shí)間超過了歷史平均期限,就會(huì)高亮這個(gè)缺陷條目,以提醒開發(fā)團(tuán)隊(duì)及時(shí)處理.

    首先定義隨機(jī)變量T,表示缺陷的生存期,即缺陷從創(chuàng)建到修復(fù)的持續(xù)時(shí)間.如果缺陷有代碼提交與之關(guān)聯(lián),則修復(fù)的時(shí)間點(diǎn)設(shè)置為最后一次提交的時(shí)間;否則,修復(fù)的時(shí)間點(diǎn)設(shè)置為缺陷狀態(tài)更改為“已修復(fù)”的時(shí)間.

    其次,選擇合適的統(tǒng)計(jì)量描述隨機(jī)變量T分布的中間值.在統(tǒng)計(jì)學(xué)中有3個(gè)統(tǒng)計(jì)量可以描述一組隨機(jī)變量取值的中間值:平均數(shù)、中位數(shù)和眾數(shù).眾數(shù)適用于隨機(jī)變量取值有限的情況,不適用于時(shí)間變量T.假設(shè)當(dāng)前已有n個(gè)已經(jīng)修復(fù)完成的缺陷,下面分別就采用平均數(shù)的和采用中位數(shù)的2種方案分別展開討論.

    1) 采用均值和標(biāo)準(zhǔn)差

    假設(shè)T服從正態(tài)分布N(μ,σ),則當(dāng)ti>μ,提醒用戶該缺陷存在的時(shí)間超過了歷史平均時(shí)長;當(dāng)ti>μ+σ時(shí),提醒用戶該缺陷存在的時(shí)間過長.其中μ和σ分別表示均值和標(biāo)準(zhǔn)差,由已修復(fù)的n個(gè)缺陷的t計(jì)算得到.

    方案1的問題在于:1)均值容易受到異常值的影響;2)正態(tài)分布的假設(shè)不一定成立.

    但方案1的優(yōu)點(diǎn)在于均值和方差計(jì)算簡單,時(shí)間復(fù)雜度是O(N),并且,均值和方差可以通過遞歸計(jì)算得到,證明如下:

    對(duì)于正態(tài)分布,方差Dn(T)=σ2,期望En(T)=μ,因此,只需保存當(dāng)前的En(T)和En(T2),當(dāng)有一個(gè)新的缺陷修復(fù)完成時(shí),利用上面的公式就計(jì)算出En+1(T)和En+1(T2),從而快速計(jì)算得到新的μ和σ,時(shí)間復(fù)雜度是O(1)的.

    2) 采用分位數(shù)

    利用基于快速排序的Top-K算法(在快速排序的過程中可得到第K大或第K小的數(shù),不需要全部排序完成后就能得到結(jié)果),計(jì)算出T的50%分位數(shù)t0.5(即中位數(shù))和75%分位數(shù)t0.75,當(dāng)ti>t0.5時(shí),提醒用戶該缺陷存在的時(shí)間超過了歷史平均時(shí)長;當(dāng)ti>t0.75時(shí),提醒用戶該缺陷存在的時(shí)間過長.

    和均值相比,分位數(shù)受異常值的影響很小,因而方案2更健壯.

    平均情況下Top-K算法的時(shí)間復(fù)雜度是O(N)的.但是分位數(shù)需要排序才能找到,無法用公式表達(dá),無法得到遞推關(guān)系式,因而在需要更新時(shí)不得不每次重新計(jì)算分位數(shù),無法達(dá)到方案1的O(1)時(shí)間復(fù)雜度.

    是否能設(shè)計(jì)一種算法,把上述2種方案的優(yōu)點(diǎn)結(jié)合在一起呢?

    考慮到距離現(xiàn)在越久遠(yuǎn)數(shù)據(jù)對(duì)現(xiàn)在的指導(dǎo)價(jià)值越小,因此在計(jì)算分位數(shù)時(shí)可以只考慮最新的k個(gè)數(shù)據(jù)點(diǎn)構(gòu)成的數(shù)組.當(dāng)一個(gè)新的數(shù)據(jù)點(diǎn)插入數(shù)組時(shí),把最老的數(shù)據(jù)點(diǎn)從數(shù)組中刪除,數(shù)組維持長度為k不變.以計(jì)算中位數(shù)為例,假設(shè)當(dāng)前k個(gè)數(shù)據(jù)點(diǎn)的中位數(shù)為X0.5,最老的數(shù)據(jù)點(diǎn)值為Xold,插入的數(shù)據(jù)點(diǎn)為Xnew.若XoldX0.5且Xnew>X0.5,即當(dāng)插入和刪除的數(shù)據(jù)點(diǎn)在數(shù)組排序后位于X0.5同一側(cè)時(shí),X0.5的值不發(fā)生改變.

    基于這樣的想法,可以提出方案2的改進(jìn)版:

    保存當(dāng)前n個(gè)缺陷的T的50%分位數(shù)t0.5和75%分位數(shù)t0.75;

    當(dāng)?shù)趎+1個(gè)缺陷完成修復(fù)時(shí),

    若n

    若n≥k,記最新的k個(gè)缺陷的T為tn-k+1~tn,比較tn-k+1,tn+1,t0.5,t0.75的大小:

    若tn-k+1,tn+1同小于或同大于t0.5,則t0.5不變,不需要重新計(jì)算;

    否則,遍歷tn-k+2~tn+1,

    若tn+1

    若tn+1>t0.5,找到比t0.5大的最小值,

    記為新的t0.5;

    類似地,可保留或更新t0.75的值.

    在Onboard中采用了上述方案2的改進(jìn)版,k=51,實(shí)現(xiàn)缺陷生存期的2級(jí)預(yù)警.

    5.3 缺陷責(zé)任人推薦

    一個(gè)缺陷生存期的長短取決于能否及時(shí)地將缺陷分配給一名合適的開發(fā)者.若將缺陷分配給了不合適的開發(fā)者,比如該名開發(fā)者不具備相關(guān)能力或沒有空余時(shí)間,則會(huì)延長缺陷的存在時(shí)間.傳統(tǒng)的缺陷跟蹤系統(tǒng)中,缺陷的責(zé)任人大多都是人工分配的.人工缺陷責(zé)任人分配是一項(xiàng)耗時(shí)耗力且瑣碎的工作,因而利用計(jì)算機(jī)進(jìn)行缺陷責(zé)任人的自動(dòng)分配成為了一個(gè)有意義的研究課題.

    隨著SVN,Git等源代碼管理軟件的流行,建立缺陷和源代碼之間的聯(lián)系變得可行.如果說缺陷報(bào)告描述了一個(gè)缺陷是什么,那么源代碼中則包含了缺陷在哪里發(fā)生、什么時(shí)候被引入的信息.Shokripour等人[13]就另辟蹊徑,把預(yù)測(cè)誰來修復(fù)缺陷的問題轉(zhuǎn)化為了預(yù)測(cè)缺陷和哪些源代碼文件相關(guān)的問題:首先利用一個(gè)源代碼文件中的標(biāo)識(shí)名稱(如類名、函數(shù)名等)、代碼提交的注釋、代碼中的注釋以及和這個(gè)源代碼文件相關(guān)聯(lián)的歷史缺陷報(bào)告這4類信息建立源代碼文件的詞頻矩陣,當(dāng)有新的缺陷產(chǎn)生時(shí),通過計(jì)算相似性來預(yù)測(cè)該缺陷和哪些源代碼文件相關(guān),最后從源代碼管理軟件中獲得最近修改這些源代碼文件的開發(fā)者,作為該缺陷責(zé)任人的推薦名單.

    缺陷責(zé)任人的自動(dòng)分配問題還可以被看作是推薦系統(tǒng)問題——從大量的開發(fā)者中推薦若干開發(fā)者作為備選名單,再進(jìn)行人工分配.不少文獻(xiàn)中均使用了Top-K召回率作為算法的評(píng)價(jià)指標(biāo)之一,即算法針對(duì)輸入的一個(gè)缺陷給出K個(gè)可能的缺陷負(fù)責(zé)人,判斷這個(gè)缺陷實(shí)際的負(fù)責(zé)人是否在這份名單里面.

    綜上,解決缺陷責(zé)任人的自動(dòng)分配問題大致3種思路:判斷缺陷和缺陷之間的相似性(缺陷分類)、判斷缺陷和源代碼文件的相關(guān)性、判斷缺陷和開發(fā)者的相關(guān)性.

    在Onboard敏捷軟件開發(fā)協(xié)同工具中引入缺陷責(zé)任人推薦的功能,需要針對(duì)應(yīng)用場(chǎng)景的特殊性設(shè)計(jì)一套解決方案.1)和專門的缺陷跟蹤系統(tǒng)軟件相比,Onboard中提供的缺陷管理模塊對(duì)缺陷報(bào)告要求的字段比較單一,只需要缺陷的描述和復(fù)現(xiàn)步驟;2)和大型的開源項(xiàng)目相比,在使用Onboard的中小型開發(fā)團(tuán)隊(duì)的項(xiàng)目中,需要?jiǎng)?chuàng)建缺陷報(bào)告的缺陷數(shù)目往往比較有限.也就是說,從缺陷報(bào)告中提取出來的詞頻矩陣比較稀疏,用于訓(xùn)練的數(shù)據(jù)量也比較有限,因而不太適宜采用缺陷分類的思路,把問題轉(zhuǎn)化為文本分類的機(jī)器學(xué)習(xí)問題.但反過來,Onboard的優(yōu)勢(shì)在于其記錄了軟件開發(fā)全生命周期的數(shù)據(jù),這些數(shù)據(jù)遠(yuǎn)遠(yuǎn)比缺陷數(shù)據(jù)豐富得多,解決方案應(yīng)當(dāng)充分利用這些數(shù)據(jù)中所包含的信息.此外,還要求解決方案中的算法能夠增量迭代,即當(dāng)新創(chuàng)建的缺陷的責(zé)任人被分配之后,算法應(yīng)當(dāng)同時(shí)利用這一信息以及之前的信息,給之后發(fā)現(xiàn)的缺陷推薦責(zé)任人.再者,在實(shí)現(xiàn)5.1節(jié)“團(tuán)隊(duì)成員關(guān)鍵詞詞云”這一功能時(shí)已經(jīng)得到了用戶的詞頻矩陣.綜合以上幾點(diǎn)考慮,我們采用了判斷缺陷和開發(fā)者的相關(guān)性的思路:

    從新創(chuàng)建的缺陷報(bào)告中提取關(guān)鍵詞的詞頻向量;

    對(duì)每一個(gè)當(dāng)前處于活躍狀態(tài)的團(tuán)隊(duì)成員:

    從用戶的詞頻矩陣中得到這些關(guān)鍵詞的TF-IDF構(gòu)成用戶的關(guān)鍵詞向量,計(jì)算和缺陷關(guān)鍵詞詞頻向量的余弦相似度;

    將所有成員按余弦相似度從高到底排列,

    若一個(gè)成員的余弦相似度明顯高于其他成員,

    則推薦該成員作為該缺陷的責(zé)任人;

    若有若干成員的余弦相似度比較接近,

    則根據(jù)當(dāng)前任務(wù)數(shù)目的多少、當(dāng)前正在修復(fù)的缺陷的數(shù)目等推薦最可能有時(shí)間修復(fù)缺陷的成員.

    我們還考慮過給任務(wù)也添加推薦責(zé)任人的功能.但是Scrum流程中有每日立會(huì),并且敏捷價(jià)值觀第1條“個(gè)體與交互勝過過程和工具”講的就是團(tuán)隊(duì)成員之間應(yīng)當(dāng)充分交流.一個(gè)敏捷開發(fā)團(tuán)隊(duì)?wèi)?yīng)當(dāng)是自組織的,由成員互相討論分配任務(wù),因而從方法論的角度看,這樣一個(gè)功能是沒有價(jià)值的.

    6 總結(jié)及進(jìn)一步的工作

    我們利用代碼提交和任務(wù)的關(guān)聯(lián),將項(xiàng)目管理和源代碼管理有機(jī)整合,繼而以Scrum方法為指導(dǎo),開發(fā)了支持敏捷軟件開發(fā)全生命周期管理的Onboard敏捷軟件開發(fā)協(xié)同工具.此外,我們還提出要收集軟件開發(fā)過程中每一個(gè)環(huán)節(jié)產(chǎn)生的大量數(shù)據(jù),并對(duì)這些數(shù)據(jù)進(jìn)行分析,提取有價(jià)值的信息,進(jìn)一步促進(jìn)敏捷軟件開發(fā)過程的管理,并在Onboard項(xiàng)目中付諸實(shí)踐.這是本文描述的工作的兩大主要貢獻(xiàn).此外,我們還提出了代碼影響行數(shù)ALOC的概念來衡量團(tuán)隊(duì)成員貢獻(xiàn)的代碼量.

    本文圍繞著“如何利用軟件開發(fā)過程中產(chǎn)生的數(shù)據(jù)更好地支持敏捷開發(fā)過程”和“如何評(píng)估團(tuán)隊(duì)成員的貢獻(xiàn)度”兩大課題,全面介紹了數(shù)據(jù)可視化和數(shù)據(jù)分析在Onboard中的應(yīng)用——豐富的、可交互的、具有洞察性的統(tǒng)計(jì)圖表,覆蓋了敏捷軟件開發(fā)的各個(gè)環(huán)節(jié);為團(tuán)隊(duì)成員貢獻(xiàn)度評(píng)估、缺陷責(zé)任人分配等問題設(shè)計(jì)了解決方案.

    我們對(duì)敏捷軟件開發(fā)過程中產(chǎn)生的大量數(shù)據(jù)的分析還是比較初步的,還有更多有價(jià)值的信息值得深入挖掘.此外,還有5方面的工作正在或計(jì)劃進(jìn)行:

    1) 遍歷并統(tǒng)計(jì)Git代碼倉庫不同分支的所有代碼提交的算法優(yōu)化

    一個(gè)分支的代碼提交構(gòu)成了一棵二叉樹,對(duì)二叉樹進(jìn)行遍歷是高效的,加上緩存的使用,直接遍歷Git代碼倉庫中的代碼提交的時(shí)間成本在一定統(tǒng)計(jì)時(shí)間范圍內(nèi)是可以接受的.然而,由于要統(tǒng)計(jì)所有分支上的代碼提交,在使用過程中我們發(fā)現(xiàn),當(dāng)統(tǒng)計(jì)的時(shí)間區(qū)間超過半年時(shí),數(shù)據(jù)就返回得比較慢了.一種可行的替代方案是:在每次上傳代碼提交時(shí),將新的代碼提交的信息及統(tǒng)計(jì)所需要的計(jì)算結(jié)果存進(jìn)SQL數(shù)據(jù)表中,以空間換時(shí)間.但實(shí)際上計(jì)算效率是否提升、能提升多少,還有待進(jìn)一步實(shí)驗(yàn)驗(yàn)證.

    2) 一個(gè)項(xiàng)目不同迭代之間的對(duì)比

    若選取一些指標(biāo),如延誤的任務(wù)數(shù)目比例、增加的代碼行數(shù)等,繪制橫軸為時(shí)間的折線圖,展現(xiàn)同一項(xiàng)目在不同迭代間的變化趨勢(shì),可以進(jìn)一步洞察開發(fā)團(tuán)隊(duì)在Scrum敏捷開發(fā)過程中是否存在問題、是否有改進(jìn)的地方等.

    3) 自適應(yīng)的團(tuán)隊(duì)成員貢獻(xiàn)度評(píng)估機(jī)制

    我們提出的貢獻(xiàn)度評(píng)估模型中,各個(gè)自變量的權(quán)重是根據(jù)我們團(tuán)隊(duì)的實(shí)際情況計(jì)算出來的.然而各個(gè)團(tuán)隊(duì)之間是有差異的,這種差異性很可能導(dǎo)致我們提出的評(píng)估模型并不是通用的.能否設(shè)計(jì)一種帶反饋的評(píng)估機(jī)制,使得團(tuán)隊(duì)成員貢獻(xiàn)度評(píng)估模型能自我調(diào)整,適應(yīng)使用Onboard的各個(gè)開發(fā)團(tuán)隊(duì)的實(shí)際情況.

    4) 代碼質(zhì)量分析的進(jìn)一步整合

    Onboard中整合了Sonarqueb代碼質(zhì)量分析工具,為用戶展示了初步的分析結(jié)果,特別是“技術(shù)債務(wù)”的分析為代碼質(zhì)量的控制提供了有力的支持.目前代碼質(zhì)量分析是相對(duì)獨(dú)立的功能,如何將其整合進(jìn)敏捷開發(fā)過程中,還有待進(jìn)一步研究和實(shí)踐.一種思路是:從包含技術(shù)債務(wù)的文件可以找到相應(yīng)的代碼提交,從而找到關(guān)聯(lián)的任務(wù)和開發(fā)者,給予提醒.

    5) 開發(fā)者畫像

    如第2節(jié)所述,任務(wù)和代碼之間的關(guān)聯(lián),使得可以從任務(wù)和代碼2個(gè)維度描繪一名團(tuán)隊(duì)成員.每一行代碼都可以追本溯源到一個(gè)或多個(gè)團(tuán)隊(duì)成員.根據(jù)一個(gè)團(tuán)隊(duì)成員所修改過的代碼文件的文件名,可以判斷出代碼的類型,進(jìn)而判斷出開發(fā)者擅長的技術(shù);根據(jù)任務(wù)完成的時(shí)長和關(guān)聯(lián)的代碼,可以判斷出開發(fā)者的效率;根據(jù)代碼質(zhì)量分析的結(jié)果以及代碼是否引入了缺陷,可以判斷出開發(fā)者的水平等,這些和個(gè)人關(guān)鍵詞詞云一起,能共同刻畫出“開發(fā)者畫像”.

    [1]Beck K, Grenning J, Martin R C, et al. Manifesto for agile software development[EB/OL].[2016-08-15]. http://www.agilemanifesto.org

    [2]Cockburn A, Highsmith J. Agile software development: The people factor[J]. IEEE Computer, 2001, 34(11): 131-133

    [3]Chen Yong. Martian agile development manual[OL]. (2012-12-25)[2016-08-15]. http://blog.csdn.net/cheny_com/article/details/6616794 (in Chinese)(陳勇. 火星人敏捷開發(fā)手冊(cè)[OL]. (2012-12-25)[2016-08-15]. http://blog.csdn.net/cheny_com/article/details/6616794)

    [4]Schwaber K, Beedle M. Agile Software Development with SCRUM[M]. Upper Saddle River, NJ: Prentice Hall, 2001

    [5]Pressman R S, Maxim B R. Software Engineering: A Practitioner’s Approach[M]. 8th ed. Beijing: China Machine Press, 2015: 79

    [6]Li Zhihua. Lean Software Development: Understanding Kanban Method[M]. 1st ed. Beijing: Tsinghua University Press, 2016 (in Chinese)(李智樺. 精益開發(fā)與看板方法[M]. 1版. 北京: 清華大學(xué)出版社, 2016)

    [7]Cockburn A. What the agile toolbox contains[EB/OL].[2016-08-15]. http://alistair.cockburn.us/What%20the%20agile%20toolbox%20contains

    [8]Tower. Feature log of Tower[EB/OL].[2016-08-15]. https://tower.im/roadmap (in Chinese)(Tower. Tower功能日志[EB/OL].[2016-08-15]. https://tower.im/roadmap)

    [9]Feinberg J. Beautiful Visualization[M]. San Francisco, CA: O’Reilly Media, 2010: 37-41

    [11]Ahsan S N, Ferzund J, Wotawa F. Automatic software bug triage system (BTS) based on latent semantic indexing and support vector machine[C] //Proc of IEEE ICSEA’09. Piscataway, NJ: IEEE, 2009: 216-221

    [12]Xuan Jifeng, Jiang He, Hu Yan, et al. Towards effective bug triage with software data reduction techniques[J]. IEEE Trans on Knowledge and Data Engineering, 2015, 27(1): 264-280

    [13]Shokripour R, Anvik J, Kasirun Z M. Why so complicated? Simple term filtering and weighting for location-based bug report assignment recommendation[C] //Proc of the 10th IEEE Working Conf on Mining Software Repositories. Piscataway, NJ: IEEE, 2013: 2-11

    Chen Long, born in 1988. Currently PhD candidate in the School of Software & Microelectronics, Peking University. Student member of China Computer Federation. His main research interests include software engineering and machine learning.

    Ye Wei, born in 1985. Received his PhD degree from School of Electronics Engineering and Computer Science, Peking University. Currently associate research fellow in National Engineering Research Center for Software Engineering, Peking University. His main research interests include Web-based software engineering, software architecture and application integration.

    Zhang Shikun, born in 1969. Received his PhD degree from Department of Computer Science and Technology, Peking University. Professor and PhD supervisor in National Engineering Research Center for Software Engineering, Peking University. His main research interests include software engineering and cyber security.

    附錄A

    Scrum團(tuán)隊(duì)中的主要角色包括:

    Scrum Master——Scrum教練和團(tuán)隊(duì)負(fù)責(zé)人,確保團(tuán)隊(duì)合理地運(yùn)作Scrum并幫助團(tuán)隊(duì)移除實(shí)施中的障礙;

    Product Owner——產(chǎn)品負(fù)責(zé)人,確定產(chǎn)品的方向和愿景,定義產(chǎn)品發(fā)布的內(nèi)容、優(yōu)先級(jí)及交付時(shí)間;

    Team——開發(fā)團(tuán)隊(duì),通常為3~9人的小型團(tuán)隊(duì),團(tuán)隊(duì)擁有交付可用軟件需要的各種技能.

    Scrum團(tuán)隊(duì)以短小的迭代(sprint)為單位進(jìn)行工作,一個(gè)典型的Scrum迭代通常持續(xù)2~4周.

    在日常工作時(shí),產(chǎn)品負(fù)責(zé)人須維護(hù)一個(gè)按優(yōu)先級(jí)排序的“產(chǎn)品需求列表”(product backlog),即從客戶價(jià)值理解和描述中凝練成的產(chǎn)品功能條目.在每次迭代開始之前,產(chǎn)品負(fù)責(zé)人組織召開迭代計(jì)劃會(huì)(sprint planning meeting),從優(yōu)先級(jí)最高的需求進(jìn)行講解,團(tuán)隊(duì)成員就需求細(xì)節(jié)、完成標(biāo)準(zhǔn)等展開討論,并估算工時(shí),直至該迭代期間內(nèi)團(tuán)隊(duì)工作量飽和,從而形成迭代需求列表(sprint backlog).一旦迭代開始,原則上迭代需求列表不再發(fā)生大的變化,可以使團(tuán)隊(duì)能在短期內(nèi)相對(duì)穩(wěn)定地、高效地開展工作.然后,要把本次迭代的需求細(xì)分為以小時(shí)為單位的任務(wù),在迭代期內(nèi),團(tuán)隊(duì)成員將自主決定任務(wù)分配等,逐一完成任務(wù).每天由團(tuán)隊(duì)負(fù)責(zé)人組織進(jìn)行一個(gè)簡短的站立會(huì)議(daily stand-up meeting),一般不超過15 min,團(tuán)隊(duì)成員相互溝通,主要回答3個(gè)問題——自上次站立會(huì)議以來完成了什么任務(wù)、遇到了什么困難、下一次站立會(huì)議之前計(jì)劃完成什么任務(wù)——以便更早地發(fā)現(xiàn)潛在的問題,促進(jìn)團(tuán)隊(duì)自我組織協(xié)調(diào).

    團(tuán)隊(duì)以故事板(也稱作看板)的形式展示團(tuán)隊(duì)的進(jìn)度,比如將看板劃分為“未開始”、“開發(fā)中”和“待審核”3個(gè)并排的欄目,計(jì)劃會(huì)結(jié)束后所有任務(wù)都排列在“未開始”一欄下.隨著迭代的進(jìn)行,一項(xiàng)任務(wù)處于哪種狀態(tài),就將任務(wù)移動(dòng)到相應(yīng)的欄目下.關(guān)于看板的一條簡單規(guī)則,就是處于“開發(fā)中”的任務(wù)永遠(yuǎn)不要太多,避免在迭代結(jié)束時(shí)出現(xiàn)大量“半成品”.團(tuán)隊(duì)還維護(hù)一張“燃燒圖”(burn down chart),即所有任務(wù)的累積剩余時(shí)間隨開發(fā)進(jìn)程與日遞減的圖形,以觀察和預(yù)測(cè)所有任務(wù)是否會(huì)按期完成.如果有緊急的缺陷(bug)被發(fā)現(xiàn),可以作為任務(wù)臨時(shí)添加進(jìn)迭代.

    在每個(gè)迭代的最后一天,團(tuán)隊(duì)召開評(píng)審會(huì)(review meeting),邀請(qǐng)產(chǎn)品負(fù)責(zé)人等參加,對(duì)已經(jīng)完成的產(chǎn)品功能條目進(jìn)行評(píng)審,產(chǎn)品負(fù)責(zé)人做出判斷并給出改進(jìn)意見.當(dāng)天還會(huì)召開反思會(huì)(retros-pective meeting),總結(jié)本次迭代中的不足之處,并在之后的迭代中加以改進(jìn).

    Scrum整個(gè)流程如圖A1所示:

    Onboard: A Data-Driven Agile Software Development Collaboration Tool

    Chen Long, Ye Wei, and Zhang Shikun

    (National Engineering Research Center for Software Engineering (Peking University), Beijing 100871)

    Scrum is an agile software development process with a balance between schedule and flexibility, which empowers software development teams with the ability to work efficiently and respond to changes quickly at the same time. Each step in the software development process can generate tons of data, which can further facilitate team and project management and improve development efficiency if these data are captured, analyzed, displayed and fed back. However, these data are commonly scattered and under-utilized because project management and source code management are separated in existing software development management toolbox. To promote data-driven agile software development process with Scrum at its core, we create Onboard, an agile software development collaboration tool based on cloud service, which, by associating Git commits with tasks, creatively incorporates agile process management, source code management and project management into one integrated service for software development teams. Onboard supports end-to-end management of the whole software life cycle, thus it can collect all the data generated throughout the development process and extract valuable information. This paper first introduces the design principle and structure of Onboard, and then gives a comprehensive survey of data visualization and analysis applied in Onboard. In the survey, we propose solutions to a series of related problems on two topics: how to fully utilize the data generated to improve agile development process and how to evaluate the contribution of a team member. In the final analysis, the paper provides topics that need further research.

    data-driven; agile software development; Scrum; software life cycle; data visualization; associating commit with task; contribution evaluation; affected lines of code (ALOC)

    Fig. A1 Demonstration of Scrum software development process.圖A1 Scrum軟件開發(fā)流程示例

    2016-08-16;

    2016-10-24

    葉蔚(wye@pku.edu.cn)

    TP311.5

    猜你喜歡
    源代碼代碼可視化
    人工智能下復(fù)雜軟件源代碼缺陷精準(zhǔn)校正
    基于CiteSpace的足三里穴研究可視化分析
    基于Power BI的油田注水運(yùn)行動(dòng)態(tài)分析與可視化展示
    云南化工(2021年8期)2021-12-21 06:37:54
    基于TXL的源代碼插樁技術(shù)研究
    基于CGAL和OpenGL的海底地形三維可視化
    “融評(píng)”:黨媒評(píng)論的可視化創(chuàng)新
    創(chuàng)世代碼
    創(chuàng)世代碼
    創(chuàng)世代碼
    創(chuàng)世代碼
    欧美绝顶高潮抽搐喷水| 午夜激情欧美在线| 51午夜福利影视在线观看| 高清日韩中文字幕在线| 国产三级中文精品| 又紧又爽又黄一区二区| 久久精品国产综合久久久| 午夜久久久久精精品| 午夜久久久久精精品| 亚洲国产精品久久男人天堂| 国产精品一区二区免费欧美| 国产成人aa在线观看| 桃红色精品国产亚洲av| 性色av乱码一区二区三区2| 天堂√8在线中文| 国产高清激情床上av| 午夜福利欧美成人| av天堂在线播放| 母亲3免费完整高清在线观看| 一区二区三区高清视频在线| 丝袜美腿在线中文| 午夜免费观看网址| 欧美高清成人免费视频www| 久久久久精品国产欧美久久久| 亚洲男人的天堂狠狠| 国产美女午夜福利| 嫩草影院入口| a在线观看视频网站| 亚洲国产精品成人综合色| 18禁美女被吸乳视频| 中国美女看黄片| 三级毛片av免费| 51国产日韩欧美| 最新在线观看一区二区三区| 国产单亲对白刺激| 蜜桃久久精品国产亚洲av| 成熟少妇高潮喷水视频| 99久久精品国产亚洲精品| av片东京热男人的天堂| 很黄的视频免费| 亚洲avbb在线观看| 婷婷丁香在线五月| 欧美丝袜亚洲另类 | 中文字幕人妻熟人妻熟丝袜美 | 一级a爱片免费观看的视频| 12—13女人毛片做爰片一| 一区二区三区激情视频| 两个人的视频大全免费| 亚洲真实伦在线观看| av国产免费在线观看| 日韩欧美精品v在线| 国产乱人视频| 午夜福利高清视频| 色综合婷婷激情| 法律面前人人平等表现在哪些方面| 国产精品永久免费网站| svipshipincom国产片| 亚洲精品456在线播放app | 亚洲片人在线观看| 国产精品久久久久久精品电影| 久久亚洲精品不卡| АⅤ资源中文在线天堂| 国产高清激情床上av| 亚洲精品粉嫩美女一区| 中文字幕人成人乱码亚洲影| 免费在线观看影片大全网站| 高潮久久久久久久久久久不卡| 91麻豆av在线| 欧美另类亚洲清纯唯美| 国产麻豆成人av免费视频| 少妇人妻精品综合一区二区 | 成人一区二区视频在线观看| 国产真人三级小视频在线观看| 欧美性猛交黑人性爽| 亚洲国产欧美人成| 噜噜噜噜噜久久久久久91| 日本a在线网址| 精品久久久久久久末码| 精品免费久久久久久久清纯| www.色视频.com| 成人特级黄色片久久久久久久| 大型黄色视频在线免费观看| 亚洲精品一区av在线观看| ponron亚洲| 91字幕亚洲| 亚洲欧美日韩无卡精品| 精品国产三级普通话版| 88av欧美| 日本精品一区二区三区蜜桃| 欧美日韩中文字幕国产精品一区二区三区| or卡值多少钱| www.www免费av| 18美女黄网站色大片免费观看| 日日干狠狠操夜夜爽| 久久亚洲真实| 午夜老司机福利剧场| 日本 欧美在线| 成人性生交大片免费视频hd| 51国产日韩欧美| 欧美另类亚洲清纯唯美| 别揉我奶头~嗯~啊~动态视频| 非洲黑人性xxxx精品又粗又长| 成人鲁丝片一二三区免费| 欧美一级毛片孕妇| 天堂影院成人在线观看| 日日摸夜夜添夜夜添小说| 亚洲一区二区三区不卡视频| 一区二区三区国产精品乱码| 欧美乱码精品一区二区三区| 国产精品99久久久久久久久| 伊人久久精品亚洲午夜| 欧美绝顶高潮抽搐喷水| 小说图片视频综合网站| 亚洲国产高清在线一区二区三| 中文字幕av成人在线电影| 免费在线观看影片大全网站| 久久国产乱子伦精品免费另类| 99久久精品热视频| 伊人久久大香线蕉亚洲五| 身体一侧抽搐| 一区二区三区高清视频在线| 少妇人妻一区二区三区视频| 免费av毛片视频| 99热只有精品国产| 国产精品久久久人人做人人爽| 宅男免费午夜| 露出奶头的视频| 99国产精品一区二区蜜桃av| 日韩欧美精品免费久久 | 精品国产三级普通话版| 亚洲精品国产精品久久久不卡| 国产伦人伦偷精品视频| 亚洲av免费高清在线观看| 亚洲人成伊人成综合网2020| 中文字幕精品亚洲无线码一区| 校园春色视频在线观看| 国产 一区 欧美 日韩| 99热这里只有精品一区| 九色国产91popny在线| 成人精品一区二区免费| 欧美日韩瑟瑟在线播放| 精品一区二区三区人妻视频| 人人妻,人人澡人人爽秒播| 精华霜和精华液先用哪个| 丰满人妻一区二区三区视频av | 日韩欧美精品免费久久 | av女优亚洲男人天堂| 特大巨黑吊av在线直播| 亚洲第一欧美日韩一区二区三区| 夜夜躁狠狠躁天天躁| 国产亚洲精品一区二区www| 国产乱人伦免费视频| 欧美日韩黄片免| 女人高潮潮喷娇喘18禁视频| 国产高清激情床上av| 有码 亚洲区| 日韩欧美免费精品| 亚洲国产精品成人综合色| 十八禁人妻一区二区| 性色avwww在线观看| 一级黄片播放器| 亚洲国产精品久久男人天堂| 免费一级毛片在线播放高清视频| 成人国产综合亚洲| 精品一区二区三区视频在线观看免费| 欧美日本亚洲视频在线播放| 久久久久久久久久黄片| 免费观看人在逋| 99国产精品一区二区蜜桃av| 国产成人aa在线观看| 中出人妻视频一区二区| 天堂网av新在线| 搡老熟女国产l中国老女人| 精品福利观看| 亚洲精品亚洲一区二区| 婷婷六月久久综合丁香| 噜噜噜噜噜久久久久久91| 免费看十八禁软件| 99久久综合精品五月天人人| 尤物成人国产欧美一区二区三区| 国产激情偷乱视频一区二区| 又黄又爽又免费观看的视频| 日韩欧美 国产精品| 色在线成人网| 国产精品一及| 国产黄a三级三级三级人| 免费看美女性在线毛片视频| 欧美成人一区二区免费高清观看| 国产真实乱freesex| 久久草成人影院| 成人欧美大片| 在线天堂最新版资源| 亚洲美女黄片视频| 黄片小视频在线播放| 亚洲国产欧美人成| 亚洲黑人精品在线| 美女cb高潮喷水在线观看| 色视频www国产| 脱女人内裤的视频| 欧美日韩瑟瑟在线播放| 日韩欧美 国产精品| 国产蜜桃级精品一区二区三区| 免费看美女性在线毛片视频| 国产精华一区二区三区| 最新在线观看一区二区三区| 精品久久久久久久久久免费视频| 欧美+日韩+精品| 亚洲成人久久性| 久久精品国产亚洲av香蕉五月| 有码 亚洲区| 一边摸一边抽搐一进一小说| 欧美3d第一页| 日韩欧美国产在线观看| 欧美+日韩+精品| 精品电影一区二区在线| 国产私拍福利视频在线观看| 亚洲欧美日韩高清在线视频| 国产成人a区在线观看| 怎么达到女性高潮| 成人永久免费在线观看视频| 三级国产精品欧美在线观看| 久久精品国产自在天天线| 麻豆国产97在线/欧美| 一本久久中文字幕| 国产成人欧美在线观看| 日韩欧美在线乱码| 999久久久精品免费观看国产| 午夜a级毛片| 久久久久久国产a免费观看| 最后的刺客免费高清国语| 免费在线观看亚洲国产| 国产色婷婷99| 国产乱人伦免费视频| 国产精品综合久久久久久久免费| 午夜a级毛片| 90打野战视频偷拍视频| 亚洲成av人片免费观看| 亚洲欧美精品综合久久99| 亚洲在线观看片| 欧美最新免费一区二区三区 | 真实男女啪啪啪动态图| 在线十欧美十亚洲十日本专区| 欧美日韩黄片免| 色吧在线观看| 69人妻影院| 99热6这里只有精品| 熟女少妇亚洲综合色aaa.| 国产探花在线观看一区二区| 亚洲人成网站在线播放欧美日韩| 日韩 欧美 亚洲 中文字幕| 极品教师在线免费播放| 黄片大片在线免费观看| 亚洲avbb在线观看| 国产色婷婷99| av天堂中文字幕网| 国产精品影院久久| 天堂√8在线中文| 欧美xxxx黑人xx丫x性爽| 国产精品亚洲av一区麻豆| av专区在线播放| 三级国产精品欧美在线观看| 日本精品一区二区三区蜜桃| 亚洲精品影视一区二区三区av| 色综合欧美亚洲国产小说| 真人做人爱边吃奶动态| 色哟哟哟哟哟哟| 国产精品久久久久久精品电影| 少妇裸体淫交视频免费看高清| 麻豆成人午夜福利视频| 欧美一级a爱片免费观看看| 在线a可以看的网站| 免费看a级黄色片| 成人特级av手机在线观看| 欧美色视频一区免费| 国产色爽女视频免费观看| 精品一区二区三区视频在线观看免费| av欧美777| 岛国在线免费视频观看| 老司机福利观看| 国内精品一区二区在线观看| 人人妻,人人澡人人爽秒播| 国产三级黄色录像| 一级作爱视频免费观看| 久久国产精品人妻蜜桃| 又紧又爽又黄一区二区| 欧美午夜高清在线| 69av精品久久久久久| 亚洲av电影不卡..在线观看| 日本熟妇午夜| 国产真实伦视频高清在线观看 | 日日摸夜夜添夜夜添小说| 99久久久亚洲精品蜜臀av| 国产国拍精品亚洲av在线观看 | 免费看日本二区| 成人欧美大片| 亚洲精品一区av在线观看| 中文字幕熟女人妻在线| 狂野欧美白嫩少妇大欣赏| 国产激情偷乱视频一区二区| 人妻夜夜爽99麻豆av| 十八禁网站免费在线| 欧美日韩福利视频一区二区| 美女被艹到高潮喷水动态| 日韩欧美 国产精品| 亚洲精品色激情综合| 99在线视频只有这里精品首页| 啦啦啦观看免费观看视频高清| 麻豆成人av在线观看| 色吧在线观看| 毛片女人毛片| 日韩大尺度精品在线看网址| 神马国产精品三级电影在线观看| 久久久久久久午夜电影| 一进一出抽搐动态| 国产亚洲精品一区二区www| 国产真实伦视频高清在线观看 | 看片在线看免费视频| 成人特级黄色片久久久久久久| 国产私拍福利视频在线观看| 男人和女人高潮做爰伦理| 久久人妻av系列| 精品国产超薄肉色丝袜足j| www.999成人在线观看| 黄片大片在线免费观看| 啦啦啦韩国在线观看视频| 成年女人看的毛片在线观看| 十八禁网站免费在线| 精品熟女少妇八av免费久了| 成人欧美大片| 此物有八面人人有两片| 国内毛片毛片毛片毛片毛片| 久久久国产成人精品二区| 99久久九九国产精品国产免费| 高清日韩中文字幕在线| 嫁个100分男人电影在线观看| 成人一区二区视频在线观看| 此物有八面人人有两片| 两个人视频免费观看高清| 午夜精品在线福利| 看黄色毛片网站| 人人妻,人人澡人人爽秒播| 综合色av麻豆| 中文字幕精品亚洲无线码一区| 国产探花极品一区二区| 少妇丰满av| 久久亚洲真实| 99久久成人亚洲精品观看| 动漫黄色视频在线观看| 深夜精品福利| 三级毛片av免费| 又黄又爽又免费观看的视频| 久久精品国产亚洲av香蕉五月| 桃红色精品国产亚洲av| a级一级毛片免费在线观看| 亚洲av成人不卡在线观看播放网| 淫秽高清视频在线观看| 精品日产1卡2卡| 熟女电影av网| 99热只有精品国产| 一进一出抽搐动态| 又黄又粗又硬又大视频| 国产蜜桃级精品一区二区三区| 欧美xxxx黑人xx丫x性爽| 成人欧美大片| 国产真实伦视频高清在线观看 | 亚洲av二区三区四区| 久久久久久久久久黄片| 日韩有码中文字幕| 日韩欧美在线乱码| av国产免费在线观看| 一区二区三区免费毛片| 国产高清三级在线| 激情在线观看视频在线高清| 久久精品国产亚洲av香蕉五月| 18禁在线播放成人免费| 亚洲欧美日韩高清专用| 国产熟女xx| 啦啦啦免费观看视频1| 一本久久中文字幕| 免费av观看视频| 久久这里只有精品中国| 黄片大片在线免费观看| 一级毛片高清免费大全| 美女大奶头视频| 国产成人影院久久av| 国产伦精品一区二区三区四那| 在线视频色国产色| 亚洲精品影视一区二区三区av| 一级毛片女人18水好多| 又粗又爽又猛毛片免费看| 免费大片18禁| 精品人妻一区二区三区麻豆 | 91在线观看av| 搡老岳熟女国产| 日韩欧美精品免费久久 | 欧美高清成人免费视频www| 2021天堂中文幕一二区在线观| 母亲3免费完整高清在线观看| 两个人看的免费小视频| 日本 av在线| 欧美在线黄色| 精品久久久久久久末码| 亚洲在线观看片| 亚洲真实伦在线观看| 岛国在线免费视频观看| 国产在线精品亚洲第一网站| 两个人的视频大全免费| 51午夜福利影视在线观看| 亚洲av电影不卡..在线观看| 国产极品精品免费视频能看的| 乱人视频在线观看| 欧美极品一区二区三区四区| 亚洲av二区三区四区| 国产av不卡久久| 色视频www国产| 免费av不卡在线播放| 18禁国产床啪视频网站| 热99re8久久精品国产| 国产黄片美女视频| 国产成年人精品一区二区| 国产成人av教育| 波野结衣二区三区在线 | 一本一本综合久久| 韩国av一区二区三区四区| 日韩欧美一区二区三区在线观看| 国产精品久久久久久人妻精品电影| 精品一区二区三区av网在线观看| 无遮挡黄片免费观看| 亚洲五月婷婷丁香| 一个人看视频在线观看www免费 | 国产精品亚洲av一区麻豆| 日本黄色视频三级网站网址| 国产黄a三级三级三级人| 精品午夜福利视频在线观看一区| 麻豆久久精品国产亚洲av| 91在线精品国自产拍蜜月 | 国产蜜桃级精品一区二区三区| 欧美日韩福利视频一区二区| netflix在线观看网站| 男人舔女人下体高潮全视频| 精品欧美国产一区二区三| 成人一区二区视频在线观看| 欧美av亚洲av综合av国产av| 欧美成人性av电影在线观看| 丁香六月欧美| 最新中文字幕久久久久| 亚洲人与动物交配视频| 中文资源天堂在线| 国产不卡一卡二| 非洲黑人性xxxx精品又粗又长| 亚洲av二区三区四区| 99国产综合亚洲精品| 99热这里只有是精品50| 1000部很黄的大片| 老汉色av国产亚洲站长工具| 免费观看人在逋| 悠悠久久av| 天堂网av新在线| 制服人妻中文乱码| 久久久色成人| 亚洲男人的天堂狠狠| 国产亚洲精品av在线| 亚洲美女视频黄频| 露出奶头的视频| 色综合欧美亚洲国产小说| 久久久久久九九精品二区国产| 精品免费久久久久久久清纯| 国产伦精品一区二区三区四那| 精品国产美女av久久久久小说| 国产日本99.免费观看| 在线天堂最新版资源| 免费看美女性在线毛片视频| 日本一本二区三区精品| 国产一区二区在线观看日韩 | 精品日产1卡2卡| 国产精品影院久久| 久久久色成人| 在线观看66精品国产| 日韩欧美免费精品| 99热精品在线国产| 中文字幕人成人乱码亚洲影| 黄色片一级片一级黄色片| 国产极品精品免费视频能看的| 色播亚洲综合网| 亚洲无线观看免费| 亚洲熟妇熟女久久| 亚洲人成网站在线播| 日本与韩国留学比较| 国产精品嫩草影院av在线观看 | 88av欧美| 亚洲国产精品久久男人天堂| 亚洲自拍偷在线| 三级毛片av免费| 欧美一区二区精品小视频在线| 18禁裸乳无遮挡免费网站照片| 激情在线观看视频在线高清| 观看美女的网站| 国产免费男女视频| 乱人视频在线观看| 一级毛片高清免费大全| 亚洲内射少妇av| 看免费av毛片| www.999成人在线观看| av黄色大香蕉| 九九久久精品国产亚洲av麻豆| 成人亚洲精品av一区二区| 村上凉子中文字幕在线| 亚洲成a人片在线一区二区| 男人舔奶头视频| 无人区码免费观看不卡| 一进一出抽搐gif免费好疼| 欧美乱妇无乱码| 国产99白浆流出| 青草久久国产| 九九在线视频观看精品| 日韩欧美精品免费久久 | 国产精品久久久久久久电影 | 国产精品一区二区三区四区免费观看 | 欧美一区二区国产精品久久精品| 成人18禁在线播放| 在线观看一区二区三区| 又爽又黄无遮挡网站| 亚洲成人精品中文字幕电影| 少妇人妻精品综合一区二区 | 久久久久久久精品吃奶| 日本熟妇午夜| 狠狠狠狠99中文字幕| 国产熟女xx| 久久久精品欧美日韩精品| 免费av观看视频| 99国产综合亚洲精品| 在线观看舔阴道视频| 嫩草影院精品99| 韩国av一区二区三区四区| 国产精品自产拍在线观看55亚洲| 99久久99久久久精品蜜桃| 欧美一区二区国产精品久久精品| 国产探花在线观看一区二区| АⅤ资源中文在线天堂| 成人一区二区视频在线观看| 国产精品日韩av在线免费观看| 国产av麻豆久久久久久久| 国产一区二区亚洲精品在线观看| 久久久精品大字幕| 黄片小视频在线播放| 国产成人a区在线观看| 亚洲av美国av| 淫妇啪啪啪对白视频| 国产高清视频在线观看网站| 久久国产精品人妻蜜桃| 亚洲18禁久久av| 丁香六月欧美| 久久婷婷人人爽人人干人人爱| 禁无遮挡网站| 欧美乱色亚洲激情| 麻豆一二三区av精品| 日韩大尺度精品在线看网址| 有码 亚洲区| 在线国产一区二区在线| 91av网一区二区| 色尼玛亚洲综合影院| 丰满的人妻完整版| 99热6这里只有精品| 午夜福利在线观看免费完整高清在 | 特级一级黄色大片| a级毛片a级免费在线| 国内久久婷婷六月综合欲色啪| 日本 av在线| 在线观看午夜福利视频| 欧美日韩黄片免| 99在线视频只有这里精品首页| 婷婷亚洲欧美| 久久亚洲真实| 欧美绝顶高潮抽搐喷水| 搡老妇女老女人老熟妇| 久久精品国产亚洲av涩爱 | 99久国产av精品| 18禁黄网站禁片免费观看直播| 欧美色视频一区免费| 三级国产精品欧美在线观看| 国内毛片毛片毛片毛片毛片| 日本熟妇午夜| 亚洲aⅴ乱码一区二区在线播放| 日日夜夜操网爽| 90打野战视频偷拍视频| 午夜精品一区二区三区免费看| 国产精品香港三级国产av潘金莲| 噜噜噜噜噜久久久久久91| 精品日产1卡2卡| 欧美日本亚洲视频在线播放| 狠狠狠狠99中文字幕| 国产老妇女一区| 日本一二三区视频观看| 欧美激情久久久久久爽电影| 一边摸一边抽搐一进一小说| 欧美三级亚洲精品| 欧美成人一区二区免费高清观看| 久久香蕉精品热| 欧美色视频一区免费| 在线观看66精品国产| 久久九九热精品免费| 日本成人三级电影网站| 男人和女人高潮做爰伦理| 成人av一区二区三区在线看| 最近最新中文字幕大全免费视频| 免费无遮挡裸体视频| 国产国拍精品亚洲av在线观看 | 国产精品 欧美亚洲| 亚洲av美国av| 怎么达到女性高潮| 欧美日韩综合久久久久久 | 每晚都被弄得嗷嗷叫到高潮| 免费在线观看亚洲国产| 精品福利观看| 日韩亚洲欧美综合|