推薦異常處理代碼的啟發式策略

推薦異常處理代碼的啟發式策略

引用

Eiji Adachi Barbosa and Alessandro Garcia and Mira Mezini, Heuristic Strategies for Recommendation of Exception Handling Code. In Proceedings of the 26th Brazilian Symposium on Software Engineering, 2012, 171-180

摘要

軟件開發人員難以在其系統中實現異常處理代碼。特別是,它們無法執行適當的處理操作。毫不奇怪,經常發生的故障和性能問題通常與實際軟件系統中實施的不良異常處理動作有關。在本文中,我們提出,實施和評估一套三種啟發式策略,用於推薦編程任務中的異常處理代碼。給定開發人員要使用的異常處理方法,啟發式方法建議使用一系列實現異常處理的代碼片段。啟發式方法的目標是準確找到實現異常處理的代碼片段,並根據開發人員的實現任務的上下文來推薦這些片段。因此,通過提供具體示例,提議的啟發式方法可以幫助開發人員發現與他們的上下文相關的異常處理動作。我們認為,基於提議的啟發式方法的推薦系統可能會在將來用作輔助異常處理實現的工具。

啟發式策略的定義

啟發式策略的目標是幫助開發者發現與他們的方法上下文相關的處理動作。它根據開發者的方法搜索代碼片段,並根據相關性對片段進行排名。推薦列表排名是為了使相關示例儘可能靠近列表的第一位置。因此,開發人員不會浪費時間檢查和丟棄不相關的示例。

我們的啟發式策略設計考慮從源代碼中提取的一組結構性事實,因為它們是與獲取異常處理相關的最簡單信息。大多數情況下,源代碼是唯一有關可用異常處理的信息源。在軟件系統中很少實施異常處理策略且記錄很少。此外,直接從源代碼中提取結構性事實就不必對文檔質量或源代碼遵守的文檔化策略做出任何其他假設。最後,可以以最少的額外開銷獲得提取的結構性事實,無需任何種類的額外信息。

A.異常類型的啟發式策略

異常類型的啟發式策略假設,在處理程序中,捕獲在層次結構樹中緊密聲明的異常類型的處理程序之間存在明顯的代碼相似性。

推薦異常處理代碼的啟發式策略

推薦異常處理代碼的啟發式策略

B.被調用方法的啟發式策略

推薦異常處理代碼的啟發式策略

推薦異常處理代碼的啟發式策略

C.變量類型的啟發式

推薦異常處理代碼的啟發式策略

啟發式策略實現

除了尋找候選人進行推薦,啟發式策略還必須根據所選片段與開發者代碼相似性對它們進行排序。啟發式搜索策略的實現需要:(i)一種能夠基於一組結構性事實來搜索候選者的查詢機制;(ii)一種排名機制,能夠根據代碼片段與開發者代碼相似性對其評分。

A.查詢機制

啟發式策略的首要職責是根據從開發者代碼中提取的一組結構性事實來選擇代碼片段,需要基於結構性事實集構建查詢實現。查詢機制負責構建這些查詢。

查詢基於信息檢索的布爾模型,表示為術語的布爾表達式。術語是一對(,),第一個元素表示結構性事實名稱,第二個表示相應事實值。查詢機制僅識別候選是否滿足給定查詢,即該條件的候選子集。對所選候選者的評分和排序由排名機制執行。

查詢機制首先從提供建議的方法中提取啟發式策略所需的結構性事實並將其表示為項,即(,)。對被調用方法和變量類型的啟發式策略,分別提取結構性事實作為術語,第一個元素稱為 CALLS 和 USES。

查詢機制基於結構性事實構建。啟發式策略是由查詢機制一起實現為單個查詢,可能一次取回由每個啟發式策略選擇的所有片段。單個查詢構建如下。

假定 F 為從方法中提取的一組結構事實。基於 F 的查詢 Q 定義為 F 中各項的析取表達式。例如,考慮從方法中提取的以下結構事實集:

推薦異常處理代碼的啟發式策略

基於 F 構建的單個查詢 Q 將具有以下形式:

推薦異常處理代碼的啟發式策略

查詢被表示為析取布爾表達式,因為它是限制性較小的形式,即每個查詢選擇的候選詞數最多。構建結合其他布爾運算符的布爾表達式也可以表示單個查詢。由於所有啟發式策略都表示為單個查詢,因此析取形式即使不滿足所有啟發式策略的條件也可以選擇候選。

B.排名機制

滿足一種查詢的候選者數量可以輕鬆克服數百個限制。將查詢機制選擇的所有候選者直接推薦給開發者是無效的,他們可能會被太多信息所淹沒而放棄嘗試找到自己想要的信息。只向開發者推薦查詢機制選擇的候選者子集至關重要。在開發者的異常處理任務中,候選者子集包含與他們更可能相關的信息。確定哪些選定的候選人更可能具有相關信息很重要。

推薦異常處理代碼的啟發式策略

推薦異常處理代碼的啟發式策略

考慮查詢 Q:

推薦異常處理代碼的啟發式策略

還請考慮以下權重設置:

推薦異常處理代碼的啟發式策略

排名函數的計算如下。 最初,計算第一個因子:

推薦異常處理代碼的啟發式策略

然後,計算第二個因子:

推薦異常處理代碼的啟發式策略

請注意,對每個滿足的條件執行總和。因此,為候選 C2 計算了兩次 W(USES)。最後,計算排名函數:

推薦異常處理代碼的啟發式策略

在此示例中,向“HANDLES”字段分配了更高的權重,候選 C1 具有比候選 C2 更高的等級。 如果使用其他權重設置,則可能會出現不同的結果。

評估

我們選擇基於 Eclipse 基金會開源社區託管的 Java 應用程序來構建自己的示例存儲庫。對每個下載的應用程序,我們檢查 20 個隨機選擇的異常處理方法。如果一組方法中有十多個方法實現無效處理程序,則其源應用程序將被丟棄。進一步檢查未丟棄的應用程序,並選擇了 11 個應用程序作為代碼示例來源。我們實現了從選定的應用程序中提取異常處理代碼示例的解析器。總共提取了 7919 個代碼示例,每個示例都是方法聲明級別。

對啟發式策略的執行情況進行的初步評估的目的是調查以下問題:

問題 1:啟發式策略使用的結構性事實是否足以識別異常處理代碼片段之間的結構相似性?

問題 2:與啟發式策略相關的可調權重配置能否更精確地標識結構相似的異常處理代碼片段?

為收集有助於我們回答這些問題的數據,進行了分析實驗。實驗設計如下:

推薦異常處理代碼的啟發式策略

上面描述的 BaseExperiment 從示例倉庫中存儲的每個候選項中提取了其結構性事實。然後將這些結構性事實傳遞給啟發式策略,以便在示例倉庫中執行查詢。接著驗證由啟發式策略返回的候選者,並記錄原始候選者在推薦候選者列表中返回的位置。需要注意每次迭代中,當前選定的候選對象不會從倉庫中刪除。BaseExperiment 的目標是檢查是否找到原始候選者,以及推薦在推薦列表的哪個位置。

在此初步評估中,我們決定檢查原始候選者與每個推薦候選者之間的確切匹配,從而使實驗易於再現,因為評估有必要多次進行該實驗。評估原始候選者和推薦候選者之間的精確匹配並不能模擬使用啟發式策略的真實情況,但進行了最壞情況分析,從而驗證啟發式策略能否在前十個推薦候選中推薦原始候選。如果大多數情況下啟發式策略未能在前十個推薦中推薦原始候選者,則啟發式策略無法識別異常處理代碼片段間的結構相似性。此基礎實驗雖然粗略但快速提供反饋,這對啟發式策略評估中系統執行實驗至關重要。

我們還評估了建議中提供的信息的內容。啟發式策略的主要目標是提供異常處理代碼示例。因此有必要評估啟發式算法推薦的代碼片段相關性。對推薦相關性的評估是定性的。評估的目的是調查以下問題:

問題 3:啟發式策略是否能夠推薦有關信息以實施異常處理?

問題 3 進行了定性評估,以驗證啟發式策略是否實際上推薦了具有相關信息的代碼片段用於異常處理任務。

A.第一個實驗-結構性事實的充分性

在開發過程中,最初關注的是驗證啟發式策略使用的結構性事實能否識別異常處理的代碼片段間的結構相似性。該驗證的重要性在於啟發式策略會根據結構相似性選擇推薦的候選對象。為調查啟發式策略使用的結構性事實的充分性,執行了 Base_Experiment。基於示例倉庫中存儲的每個候選項的位置記錄,構建了圖 5 中的直方圖。

圖 5 中的直方圖顯示原始候選位置的分佈集中在第一個位置。在總共 7919 個候選者中,推薦第一名的候選者為 7564 名。只有 49 個候選者在前十項推薦中未被推薦。

推薦異常處理代碼的啟發式策略

圖 5 中顯示的結果並不公平。當從候選者中提取結構性事實並將其傳遞給啟發式策略時,啟發式策略將考慮所有事實,包括私有事實,即與在其封閉項目之外不可見屬性相關的事實。由於私有事實僅在封閉項目中可見,因此使用私有事實搜索候選者只會突出顯示示例倉庫中一小部分候選者。通過使用從示例倉庫中存儲的候選項中提取的所有事實在同一存儲倉庫中執行查詢,私有事實會對啟發式策略準確性產生積極影響。在實際使用啟發式策略時,正在實現的代碼片段將無法訪問私有事實。因此對 Base_Experiment 進行不同的設置,以減輕私有事實造成的噪音。我們試圖更好地指示啟發式方法使用的結構性事實的充分性。

在 Base_Experiment 的第二個設置中,修改了從候選對象中提取結構性事實的過程,以便從啟發式策略用於執行搜索的結構性事實集合中排除私有事實。與候選者同一項目的屬性有關的任何結構性事實均被視為私人事實。圖 6 顯示了當啟發式策略不考慮私人事實時,將每個候選位置的記錄存儲在示例倉庫中的。

圖 6 中的直方圖顯示原始候選位置的分佈仍集中在第一位置。在前十項推薦中,推薦了 6710 名候選者,而在第一名中已經推薦了 5535 名候選者。與 Base_Experiment 的第一個設置的結果相比,在推薦候選者列表的前十個位置中未被推薦的候選者數量因為實驗設置而大大增加了。從啟發式策略使用的結構性事實集合中刪除所有私人事實後,剩下的事實可能很少,使啟發式策略無法檢測到原始候選對象,甚至沒有使用任何結構性事實。

推薦異常處理代碼的啟發式策略

這些情況在圖 6 的直方圖中由標記為 FACTS={}的條表示。此外,刪除所有私人事實之後可能僅保留了示例倉庫中許多候選者共有的事實。此時啟發式搜索無法將原始候選者與其他候選者區分開,從而降低了啟發式策略的精度,無法在前十個推薦中推薦原始候選者。

B.第二次實驗-權重對精度的影響

排名函數賦予開發人員可以調整的權重。第一次實驗中權重設置為默認值,每個字段賦予值 1。在本節中,我們描述了執行的實驗,以評估權重調整是否可以更精確地識別結構相似的代碼片段。該實驗並非旨在確定特定的“最佳”體重設置。相反,它旨在調查為什麼某些體重設置比其他體重設置具有更好的效果。實驗設置如下。

推薦異常處理代碼的啟發式策略

這種現象也發生在與變量類型相關的結構性事實上,因為倉庫中還存在共有變量類型。但已處理異常的類型使它不堪重負。由於異常的類型是傳遞給 catch 塊的參數,因此它也被視為與所使用的變量的類型有關的結構性事實。當為與字段 USES 關聯的權重分配一個高值時,它間接地導致了異常類型的啟發式策略,因為異常類型也被視為變量類型。對於最佳的權重設置,與“USES”和“HANDLES”字段關聯的權重始終高於與“CALLS”字段關聯的權重。實際上,由於與“HANDLES”相關聯的高權重,因此最佳的權重設置具有最佳的結果。分配給字段 USES 的高值只是我們將異常類型視為變量類型的結構性事實的副作用。

C.第三次實驗-推薦的信息相關性

在本實驗中,選擇了兩個不用於填充示例倉庫的基於 Eclipse 的應用程序。每個應用程序都要檢查其源代碼,以便選擇異常處理方法用作啟發式策略的輸入。從每個應用程序中,選擇了 10 個方法。這些選定的方法已刪除其異常處理代碼。接下來對於每種選擇的方法,使用啟發式策略推薦十個代碼片段列表。每個代碼片段都被分類為“相關”或“無關緊要”。

為確定推薦的代碼片段實際上是“相關”還是“ 不相關”,我們定義了一個 oracle,基於 Eclipse 的應用程序編譯了一組異常處理準則。以下示例描述了為此實驗編寫的準則之一。

推薦異常處理代碼的啟發式策略

因此,對於推薦的每個候選者,如果其處理程序至少執行了一項指導方針,就被視為“相關”。如果未執行任何準則,則被視為“ 不相關”。本實驗中所有 20 個用作輸入的方法都至少推薦了 3 個被推薦為“相關”的候選方法。20 個基本方法中有 12 個的第一個推薦候選被認為是“相關”,而在前六個推薦中只有一個方法沒有“相關”候選。在前六個推薦中唯一沒有“相關”候選者的方法被進一步研究,因為它是最糟糕的方法。仔細研究這個方法獲得的推薦時,我們注意到一個有趣的模式。推薦的前五個候選在其處理程序中調用瞭如下所示的方法:

推薦異常處理代碼的啟發式策略

當檢查方法 IResourceTree.failed(IStatus)的 API 時,可以確認這是一種處理與 IResourceTree 類型的對象執行的操作有關的異常的特定方法。由於實驗開始時並未在 oracle 中編譯此信息,因此儘管這些推薦候選實際上具有相關信息,我們仍將其視為“ 不相關”。該方案強調了啟發式策略的潛力,可以幫助開發者發現實現其異常的新方法。啟發式策略提供的信息是發現新處理操作過程的第一步。

D.經驗教訓和可能的改進

實驗結果僅對第三個實驗中用作輸入的方法以及所構建示例的倉庫有效。示例提取過程中,解析器自動丟棄瑣碎的無效處理程序有助於提高推薦的相關性。我們不認為避免無效處理程序推薦是偽造的使用場景,因為我們預想了啟發式策略將與良好示例倉庫一起使用。我們認為,可用的信息越多,推薦就越好,這是我們的主要目標。為此開發團隊的一名開發人員可能負責不斷完善和更新示例存儲庫。

用於將相關推薦分類為“相關”或“無關”的 oracle 也干擾了我們的結果。軟件開發者在相當長的一段時間內在編程任務中使用啟發式策略進行更嚴格的評估,才能真正評估其有效性。由於我們仍然沒有適合啟發式原型的圖形用戶界面,我們無法與開發者進行受控實驗。此時 oracle 的編譯是一種嘗試,以減輕僅基於我們自己觀點的偏見。

儘管我們的實驗取得了令人鼓舞的結果,但在定義、實施和評估啟發式策略的過程中,仍吸取了一些教訓,並確定了一些未來的改進,下面將對此進行詳細說明。

首先,即使在事實提取過程中使用的解析器試圖檢測並丟棄無效處理程序,實驗中使用的倉庫中仍然存儲了其中一些處理程序。它們大多數是典型的無效處理程序的變體或組合。通過在解析器中進行較小調整,這些無效處理程序也將在提取過程中被檢測並丟棄。

其次,在第一個實驗中,我們觀察到普遍存在的事實在強調結構相似性方面的潛力很小。更糟糕的是,我們在第二個實驗中觀察到,當基於普遍存在的事實為啟發式策略的權重分配高值時,啟發式策略的精度會下降。為了處理普遍存在的事實現象,我們可以計算每個結構性事實的頻率,並在計算排名函數時將其考慮在內,比如使用基於文本的文檔信息檢索技術。這樣,普遍存在的事實對最終成績的影響較小,而稀有事實則具有較高的影響。

最後,在第三個實驗中,我們觀察到在某些情況下,推薦的代碼示例是非常長的方法,包含大約 300 行代碼。如此長的方法具有大量的結構性事實,可能會成為推薦的匯合點。啟發式策略經常會發現與這些長方法的相似之處,因為它們具有許多不同的結構性事實,因此很有可能與基本方法具有某些結構相似性。因此,很可能經常建議使用很長的方法。在我們的實驗中,並未實際發現推薦現象的收斂點。然而,在建議中觀察到非常長的方法這一事實表明,我們應該解決這個潛在的問題。一種可能的改進是在排序函數中考慮存儲在示例倉庫中的候選結構性事實集的大小。排名函數可以考慮一個候選者滿足的查詢項數與該候選者擁有的事實總數之比,而不是考慮一個候選者滿足的查詢項的絕對數量。更極端的可能改進是改進事實提取過程,以放棄很長的方法。

致謝

感謝國家重點研發計劃課題:基於協同編程現場的智能實時質量提升方法與技術(2018YFB1003901)和國家自然科學基金項目:基於可理解信息融合的人機協同移動應用測試研究(61802171)支持!

本文由南京大學軟件學院 2018 級碩士朱晨乾翻譯轉述。


分享到:


相關文章: