淺析“程式碼視覺化”

ITPUB社群發表於2024-01-29


來源:京東技術

導讀

本文探討了程式碼視覺化的核心概念、實現方法和在不同場景下的應用。無論讀者是開發新手還是資深工程師,本文都將提供一個新的視角,幫助讀者更好地理解程式碼視覺化的價值,並將其應用於實際開發過程中。透過閱讀本文可以掌握程式碼視覺化的基本實現原理,瞭解在不同場景下如何運用視覺化結果提前識別風險、提高程式碼質量和最佳化系統效能。




01 
什麼是程式碼視覺化?


在今年的敏捷團隊建設中,我透過Suite執行器實現了一鍵自動化單元測試。Juint除了Suite執行器還有哪些執行器呢?由此我的Runner探索之旅開始了!

Code visualization is the process of creating graphical representations of source code to help understand and analyze it. 

程式碼視覺化是建立原始碼的圖形表示以幫助理解和分析它的過程。

透過使用圖形化手段(架構圖、依賴圖、分散式追蹤、類圖、火焰圖、CallGraph等)使程式碼在某些特徵上變得可觀測,用於輔助開發人員理解分析專案或建設一些自動化工具。



02 
  

為什麼需要程式碼視覺化?

  


理解,首先 MCube 會依據模板快取狀態判斷是否需要網路獲取最新模板,當獲取到模板後進行模板載入,載入階段會將產物轉換為檢視樹的結構,轉換完成後將透過表示式引擎解析表示式並取得正確的值,透過事件解析引擎解析使用者自定義事件並完成事件的繫結,完成解析賦值以及事件繫結後進行檢視的渲染,最終將目標頁面展示到螢幕。
場景1:程式碼邏輯理解困難
專案程式碼量很大且需求迭代快,每次梳理的文件很快就過時了。新同學入手困難苦不堪言,老手也很難對專案整體的業務邏輯有一個全面的認知,常常需要重新梳理邏輯。

淺析“程式碼視覺化”圖 1.

場景2:改動影響面難以評估

需求的訴求是修改A頁面的邏輯,但由於後端程式碼很多公用邏輯且呼叫層級很深,上線才後發現影響了B頁面的邏輯,造成了線上事故。

淺析“程式碼視覺化”圖 2.

場景3:專案重構缺少抓手

老舊專案經過長時間迭代和多次更換團隊,導致內部程式碼邏輯十分混亂且沒人能完全講明白所有邏輯。但新的業務迭代需求源源不斷,在原有專案上修改成本越來越高,亟需重構以獲得更高地研發效率。

淺析“程式碼視覺化”圖 3.

其他場景:自動化case迴歸常常覆蓋不到新增邏輯;線上問題排查困難,難以快速定位到出錯程式碼......


03 
 怎麼實現程式碼視覺化?

 



理解,首先 MCube 會依據模板快取狀態判斷是否需要網路獲取最新模板,當獲取到模板後進行模板載入,載入階段會將產物轉換為檢視樹的結構,轉換完成後將透過表示式引擎解析表示式並取得正確的值,透過事件解析引擎解析使用者自定義事件並完成事件的繫結,完成解析賦值以及事件繫結後進行檢視的渲染,最終將目標頁面展示到螢幕。    

Call Graph是程式中不同函式呼叫之間關係的圖形表示。它顯示了程式中的函式如何相互作用,使開發人員能夠理解程式的流程並識別潛在的效能問題。


以下講解程式碼視覺化的一種方式Call Graph的生成方案,可以分為靜態和動態分析:

                                                3.1  靜態程式分析


    
1)基於原始碼生成

在講解使用原始碼生成CallGraph的流程前我們先複習一下編譯原理的相關知識。

淺析“程式碼視覺化”圖 4.

其中編譯器前端部分主要是與源語言相關,主要包含:

詞法分析也叫掃描(scanning),他的主要任務是從左向右逐行掃描源程式的字元,識別出各個單詞,確定單詞的型別,將識別出的單詞轉換成統一的機內表示—— 詞法單元(token) 形式。可以類比英語字母合成單詞的過程。

淺析“程式碼視覺化”圖 5.

語法分析:也叫解析(parsing)。語法分析器(parser)從詞法分析器輸出的token序列中識別出各類短語,從而構造語法分析樹(syntax tree),並判斷源程式在結構上是否正確。可以類比為英語單片語合成句子。

淺析“程式碼視覺化”圖 6.

語義分析:使用語法樹和符號表中的資訊來檢查源程式是否和語言定義的語義一致,如:型別檢查、上下文相關分析等。可以類比為檢查英語句子是否有意義(如:Dog is cat,這種句子語法上沒問題但語義上是不對的)。它同時也收集識別符號的屬性資訊,並把這些資訊存放在語法樹或符號表中,以便在後面中間程式碼生成過程中使用。
中間程式碼:一種中間表示方式,所含資訊可以推匯出有關程式的全部事實。同一種中間程式碼可以複用最佳化器邏輯,並直接使用相關的編譯器後端功能,使得各環節更獨立更利於擴充套件。從結構上有圖IR、線性IR和混合IR。
編譯器後端部分主要是與目標語言相關,包含程式碼最佳化器和目的碼生成器,這部分和生成CG關係不大不作更多原理闡述,有興趣的讀者可以瞭解一下LLVM、Graalvm。

淺析“程式碼視覺化”圖 7.

有了基本的編譯原理知識後,來看看透過原始碼生產CG的過程:

淺析“程式碼視覺化”圖 8.

可以發現分析其實就是編譯器前端流程的復現,其中AST、CFG和CG都算作是圖IR。現成的原始碼分析工具有Antlr/javaparser/soot等。下面以javaparser工具為例簡要說明生成流程:

步驟一:匯入需要分析專案的原始碼和依賴包,並使用工具解析

淺析“程式碼視覺化”圖 9.

步驟二:使用visit模式獲取所有方法和呼叫方法資訊

淺析“程式碼視覺化”

淺析“程式碼視覺化”圖 10、11.

步驟三:選定一個起始方法,基於方法和呼叫關係生成CG

優點:語言無關,擴充套件性強。 

缺點:精度較差需要調優;分析速度較慢;非java語言工具掌握有一定難度。
2)基於位元組碼生成
針對語言特性進行定製開發能夠更快獲取成果。Java的位元組碼其實也可以看做一種線性IR,分析的流程也是類似的,同時java有大量的位元組碼操作工具(ASM、Javaassit、bcel等),使得位元組碼解析變得很容易。

基本思路是從.class檔案中獲取類、方法簽名資訊,再從位元組碼中找到invoke指令得到呼叫方法簽名,基於這兩個資訊就可以構建出CG。同時由於位元組碼中包含了方法的完整簽名,因此不用像原始碼分析那樣需要要引入依賴jar一併分析,因此在分析效率上會快很多。

淺析“程式碼視覺化”圖 12.

下面用bcel工具為例簡要說明生成流程:

步驟一:解析目標專案,可以直接使用打包好的jar包

淺析“程式碼視覺化”圖 13.

步驟二:使用visit模式獲取所有方法和呼叫方法資訊

淺析“程式碼視覺化”

淺析“程式碼視覺化”圖 14、15.

步驟三:選定一個起始方法,基於方法和呼叫關係生成CG

優點:分析精確度高;解析速度快。

缺點:語言相關,擴充套件性差。

PS:推薦一個idea外掛call graph,基於idea的psi能力實現,在專案程式碼量不大的情況下分析還是挺精確的。

淺析“程式碼視覺化”圖 16.

3.2  動態程式分析


    

也稱執行時程式分析,一般基於agent方式實現,這裡暫不展開講解,後續有機會再單獨寫一篇文章講述原理。有興趣的讀者可以試用一下AppMap。

淺析“程式碼視覺化”圖 17.



04 
  有哪些應用場景?  


理解,首先 MCube 會依據模板快取狀態判斷是否需要網路獲取最新模板,當獲取到模板後進行模板載入,載入階段會將產物轉換為檢視樹的結構,轉換完成後將透過表示式引擎解析表示式並取得正確的值,透過事件解析引擎解析使用者自定義事件並完成事件的繫結,完成解析賦值以及事件繫結後進行檢視的渲染,最終將目
場景1:變更風險識別
背景:識別基礎設施變更、系統外部變更以及系統內部變更帶來的風險。

案例:美團後裔系統

淺析“程式碼視覺化”圖 18.

場景2:精準測試

背景精準測試定義為利用技術手段對測試過程產生的資料進行採集儲存,計算,彙總,視覺化最終幫助團隊提升軟體測試的效率、並對專案整體質量進行改進和最佳化的這一系列操作。詳細的解釋可以閱讀精準測試二三談

淺析“程式碼視覺化”圖 19.

案例:京東精準測試探索(詳情可參考InfoQ寫作社群中精準測試探索 | 京東雲技術團隊http://xie.infoq.cn/article/9d40a91117afdce8a72a4e4c5
場景3:架構守護
背景:在架構治理上,有著諸多挑戰

1)設計與實現不匹配。設計的軟體架構與真正實施後的架構,存在著巨大的差異。而這個差異,往往需要編碼上線、乃至一段時間之後才能發現;

2)沒有規範/不遵守規範。作為資深的開發人員,制定了一系列的規範,但是沒有多少團隊人員願意遵守;

3)程式碼量巨大,難以識別問題。一個由十幾個或者幾十個微服務建立的系統,往往難以快速發現它們之間錯綜複雜的關係;

4)架構模型的每個層級都可能出錯。如服務間 API 耦合、程式碼間耦合、資料庫耦合等等;

5)架構師、開發人員自身缺乏豐富的經驗。知道有問題,但是說不出來哪有問題,也不知道如何改進。
因此需要一個平臺/工具,幫助解決這些問題。
案例:ArchGuard

提供了基於C4模型(上下文、容器、元件和程式碼)的視覺化分析,並提供了一些架構健康監測指標。

淺析“程式碼視覺化”
淺析“程式碼視覺化”

圖 20、21.



05 
  總結  


理解,首先 MCube 會依據模板快取狀態判斷是否需要網路獲取最新模板,當獲取到模板後進行模板載入,載入階段會將產物轉換為檢視樹的結構,轉換完成後將透過表示式引擎解析表示式並取得正確的值,透過事件解析引擎解析使用者自定義事件並完成事件的繫結,完成解析賦值以及事件繫結後進行檢視的渲染,最終將目
程式碼本身蘊含了大量的資訊,透過視覺化這把鑰匙開啟了很多場景自動化的大門。本文簡要介紹了程式碼視覺化實現的思路,並給出了一些應用場景和案例。但面對愈發複雜的業務場景,僅靠一種技術是遠遠不夠的,如何綜合運用多種技術來解決實際問題,我們還需要更多的探索和實踐。

來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70024420/viewspace-3005469/,如需轉載,請註明出處,否則將追究法律責任。

相關文章