Code visualization is the process of creating graphical representations of source code to help understand and analyze it. 程式碼視覺化是建立原始碼的圖形表示以幫助理解和分析它的過程。
個人理解:通過使用圖形化手段(架構圖、依賴圖、分散式追蹤、類圖、火焰圖、CallGraph等)使程式碼在某些特徵上變得可觀測,用於輔助開發人員理解分析專案或建設一些自動化工具。
專案程式碼量很大且需求迭代快,每次梳理的檔案很快就過時了。新同學入手困難苦不堪言,老手也很難對專案整體的業務邏輯有一個全面的認知,常常需要重新梳理邏輯。
需求的訴求是修改A頁面的邏輯,但由於後端程式碼很多公用邏輯且呼叫層級很深,上線才後發現影響了B頁面的邏輯,造成了線上事故。
老舊專案經過長時間迭代和多次更換團隊,導致內部程式碼邏輯十分混亂且沒人能完全講明白所有邏輯。但新的業務迭代需求源源不斷,在原有專案上修改成本越來越高,亟需重構以獲得更高地研發效率。
其他場景:自動化case迴歸常常覆蓋不到新增邏輯;線上問題排查困難,難以快速定位到出錯程式碼......
Call Graph 是程式中不同函數呼叫之間關係的圖形表示。它顯示了程式中的函數如何相互作用,使開發人員能夠理解程式的流程並識別潛在的效能問題。
以下講解程式碼視覺化的一種方式Call Graph的生成方案,可以分為靜態和動態分析:
在講解使用原始碼生成CallGraph的流程前我們先複習一下編譯原理的相關知識。
其中編譯器前端部分主要是與源語言相關,主要包含:
詞法分析:也叫掃描(scanning),他的主要任務是從左向右逐行掃描源程式的字元,識別出各個單詞,確定單詞的型別,將識別出的單詞轉換成統一的機內表示—— 詞法單元(token) 形式。可以類比英語字母合成單詞的過程。
語法分析:也叫解析(parsing)。語法分析器(parser)從詞法分析器輸出的token序列中識別出各類短語,從而構造語法分析樹(syntax tree),並判斷源程式在結構上是否正確。可以類比為英語單詞組合成句子。
語意分析:使用語法樹和符號表中的資訊來檢查源程式是否和語言定義的語意一致,如:型別檢查、上下文相關分析等。可以類比為檢查英語句子是否有意義(如:Dog is cat,這種句子語法上沒問題但語意上是不對的)。它同時也收集識別符號的屬性資訊,並把這些資訊存放在語法樹或符號表中,以便在後面中間程式碼生成過程中使用。
中間程式碼:一種中間表示方式,所含資訊可以推匯出有關程式的全部事實。同一種中間程式碼可以複用優化器邏輯,並直接使用相關的編譯器後端功能,使得各環節更獨立更利於擴充套件。從結構上有圖IR、線性IR和混合IR。
編譯器後端部分主要是與目標語言相關,包含程式碼優化器和目的碼生成器,這部分和生成CG關係不大不作更多原理闡述,有興趣的同學可以瞭解一下LLVM、Graalvm。
有了基本的編譯原理知識後,來看看通過原始碼生產CG的過程:
可以發現分析其實就是編譯器前端流程的復現,其中AST、CFG和CG都算作是圖IR。現成的原始碼分析工具有Antlr/javaparser/soot等。下面以javaparser工具為例簡要說明生成流程:
步驟一:匯入需要分析專案的原始碼和依賴包,並使用工具解析
步驟二:使用visit模式獲取所有方法和呼叫方法資訊
步驟三:選定一個起始方法,基於方法和呼叫關係生成CG
優點:語言無關,擴充套件性強。 缺點:精度較差需要調優;分析速度較慢;非java語言工具掌握有一定難度。
針對語言特性進行客製化開發能夠更快獲取成果。Java的位元組碼其實也可以看做一種線性IR,分析的流程也是類似的,同時java有大量的位元組碼操作工具(ASM、Javaassit、bcel等),使得位元組碼解析變得很容易。
基本思路是從.class檔案中獲取類、方法簽名資訊,再從位元組碼中找到invoke指令得到呼叫方法簽名,基於這兩個資訊就可以構建出CG。同時由於位元組碼中包含了方法的完整簽名,因此不用像原始碼分析那樣需要要引入依賴jar一併分析,因此在分析效率上會快很多。
下面用bcel工具為例簡要說明生成流程:
步驟一:解析目標專案,可以直接使用打包好的jar包
步驟二:使用visit模式獲取所有方法和呼叫方法資訊
步驟三:選定一個起始方法,基於方法和呼叫關係生成CG
優點:分析精確度高;解析速度快。 缺點:語言相關,擴充套件性差。
PS:推薦一個idea外掛call graph,基於idea的psi能力實現,在專案程式碼量不大的情況下分析還是挺精確的。
也稱執行時程式分析,一般基於agent方式實現,這裡暫不展開講解,後續有機會再單獨寫一篇文章講述原理。有興趣的同學可以試用一下AppMap。
背景:識別基礎設施變更、系統外部變更以及系統內部變更帶來的風險。
背景:精準測試定義為利用技術手段對測試過程產生的資料進行採集儲存,計算,彙總,視覺化最終幫助團隊提升軟體測試的效率、並對專案整體質量進行改進和優化的這一系列操作。詳細的解釋可以閱讀精準測試二三談。
背景:在架構治理上,我們面對諸多挑戰
1)設計與實現不匹配。設計的軟體架構與真正實施後的架構,存在著巨大的差異。而這個差異,往往需要編碼上線、乃至一段時間之後才能發現;
2)沒有規範/不遵守規範。作為一個資深的開發人員,我們制定了一系列的規範,但是沒有多少團隊人員願意遵守;
3)程式碼量巨大,難以識別問題。一個由十幾個或者幾十個微服務建立的系統,往往難以快速發現它們之間錯綜複雜的關係;
4)架構模型的每個層級都可能出錯。如服務間 API 耦合、程式碼間耦合、資料庫耦合等等;
5)架構師、開發人員自身缺乏豐富的經驗。知道有問題,但是說不出來哪有問題,也不知道如何改進。
因此,我們需要一個平臺/工具,來幫助我們解決這些問題。
案例:ArchGuard
提供了基於C4模型(上下文、容器、元件和程式碼)的視覺化分析,並提供了一些架構健康監測指標。
(宣告:部分圖片源自網路,侵刪)
作者:京東科技 謝驍
來源:京東雲開發者社群 轉載請註明來源