浅析“代码可视化” | 京东云技术团队
1.什么是代码可视化?
Code visualization is the process of creating graphical representations of source code to help understand and analyze it. 代码可视化是创建源代码的图形表示以帮助理解和分析它的过程。
个人理解:通过使用图形化手段(架构图、依赖图、分布式追踪、类图、火焰图、CallGraph等)使代码在某些特征上变得可观测,用于辅助开发人员理解分析项目或建设一些自动化工具。
2.为什么需要代码可视化?
场景1:代码逻辑理解困难
项目代码量很大且需求迭代快,每次梳理的文档很快就过时了。新同学入手困难苦不堪言,老手也很难对项目整体的业务逻辑有一个全面的认知,常常需要重新梳理逻辑。
场景2:改动影响面难以评估
需求的诉求是修改A页面的逻辑,但由于后端代码很多公用逻辑且调用层级很深,上线才后发现影响了B页面的逻辑,造成了线上事故。
场景3:项目重构缺少抓手
老旧项目经过长时间迭代和多次更换团队,导致内部代码逻辑十分混乱且没人能完全讲明白所有逻辑。但新的业务迭代需求源源不断,在原有项目上修改成本越来越高,亟需重构以获得更高地研发效率。
其他场景:自动化case回归常常覆盖不到新增逻辑;线上问题排查困难,难以快速定位到出错代码......
3.怎么实现代码可视化?
Call Graph 是程序中不同函数调用之间关系的图形表示。它显示了程序中的函数如何相互作用,使开发人员能够理解程序的流程并识别潜在的性能问题。
以下讲解代码可视化的一种方式Call Graph的生成方案,可以分为静态和动态分析:
3.1 静态程序分析
1)基于源码生成
在讲解使用源码生成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语言工具掌握有一定难度。
2)基于字节码生成
针对语言特性进行定制开发能够更快获取成果。Java的字节码其实也可以看做一种线性IR,分析的流程也是类似的,同时java有大量的字节码操作工具(ASM、Javaassit、bcel等),使得字节码解析变得很容易。
基本思路是从.class文件中获取类、方法签名信息,再从字节码中找到invoke指令得到调用方法签名,基于这两个信息就可以构建出CG。同时由于字节码中包含了方法的完整签名,因此不用像源码分析那样需要要引入依赖jar一并分析,因此在分析效率上会快很多。
下面用bcel工具为例简要说明生成流程:
步骤一:解析目标项目,可以直接使用打包好的jar包
步骤二:使用visit模式获取所有方法和调用方法信息
步骤三:选定一个起始方法,基于方法和调用关系生成CG
优点:分析精确度高;解析速度快。 缺点:语言相关,扩展性差。
PS:推荐一个idea插件call graph,基于idea的psi能力实现,在项目代码量不大的情况下分析还是挺精确的。
3.2 动态程序分析
也称运行时程序分析,一般基于agent方式实现,这里暂不展开讲解,后续有机会再单独写一篇文章讲述原理。有兴趣的同学可以试用一下AppMap。
4.有哪些应用场景?
场景1:变更风险识别
背景:识别基础设施变更、系统外部变更以及系统内部变更带来的风险。
场景2:精准测试
背景:精准测试定义为利用技术手段对测试过程产生的数据进行采集存储,计算,汇总,可视化最终帮助团队提升软件测试的效率、并对项目整体质量进行改进和优化的这一系列操作。详细的解释可以阅读精准测试二三谈。
场景3:架构守护
背景:在架构治理上,我们面对诸多挑战
1)设计与实现不匹配。设计的软件架构与真正实施后的架构,存在着巨大的差异。而这个差异,往往需要编码上线、乃至一段时间之后才能发现;
2)没有规范/不遵守规范。作为一个资深的开发人员,我们制定了一系列的规范,但是没有多少团队人员愿意遵守;
3)代码量巨大,难以识别问题。一个由十几个或者几十个微服务创建的系统,往往难以快速发现它们之间错综复杂的关系;
4)架构模型的每个层级都可能出错。如服务间 API 耦合、代码间耦合、数据库耦合等等;
5)架构师、开发人员自身缺乏丰富的经验。知道有问题,但是说不出来哪有问题,也不知道如何改进。
因此,我们需要一个平台/工具,来帮助我们解决这些问题。
案例:ArchGuard
提供了基于C4模型(上下文、容器、组件和代码)的可视化分析,并提供了一些架构健康监测指标。
5.拓展阅读
- 编译原理基础知识
- 用于软件架构的 C4 模型
- How do you visualize code?
- What is a Call Graph? And How to Generate them Automatically
- 静态程序分析
(声明:部分图片源自网络,侵删)
作者:京东科技 谢骁
来源:京东云开发者社区 转载请注明来源
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Node.js中常用的设计模式有哪些?
本文由葡萄城技术团队首发。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 设计模式简介 设计模式是由经验丰富的程序员在日积月累中抽象出的用以解决通用问题的可复用解决方案,它提供了标准化的代码设计方案提升开发体验。Node.js 作为一款用来构建可扩展高性能应用的流行平台,自然也遵循设计模式解决通用问题。本文中,我们将讨论 Node.js 中设计模式的重要性并提供一些代码示例。 构建 Node.js 应用为何需要设计模式 设计模式为软件开发提供了一套标准化的解决方案。构建 Node.js 应用时,善用设计模式能够帮助开发者提升代码质量,节约开发时间,减少出错几率。同时也方便开发人员之间的沟通交流。 示例代码 单例模式 该模式用来保证特定的类在整个应用中只能创建唯一实例。Node.js 中,单例模式可以保证在同一个应用中,每个模块只有唯一实例。 class Singleton { constructor() { if (Singleton.instance) { return Singleton.instance; } Singleton.ins...
- 下一篇
产品需求交付质量保证的“七重门” | 京东云技术团队
前言 随着互联网红利的逐渐消失,互联网公司获取新客户的难度和成本越来越高,用户增长的运营同学需要不断尝试不同的拉新策略,并根据用户反馈及数据反馈快速调整,同时能够快速跟进市场热点,快速迭代产品功能。我们所在部门承接大量的金融业务(金白条、支付、小金库、基金等)拉新获客的诉求。为了在满足快速交付业务需求不以牺牲产品质量为代价,我们制定了用户增长质量门禁体系,通过规范化的质量活动对需求交付的各个阶段进行质量准入和准出,步步为营,形成用户增长产品需求交付质量保证“七重门”。 一重门:用例前置-未雨绸缪,把缺陷消灭在萌芽阶段 TDD(Test-Driven Development)是敏捷测试的重要实践,它强调在编写代码之前先编写测试代码,以此驱动代码质量的提升以及功能的覆盖。结合当前平台研发部质量保证的现状,测试用例绝大部分都是利用XMind编写的文字描述形式的,若完全按照典型的TDD实践进行落地,编写测试代码的成本较高,短时间内难以看到效果,因此我们第一阶段优先实现了测试用例的前置,即测试用例的编写和评审前置到设计评审或代码开发之前,通过测试用例进一步明确功能需求、性能要求、异常流程...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Linux系统CentOS6、CentOS7手动修改IP地址
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS关闭SELinux安全模块
- CentOS7设置SWAP分区,小内存服务器的救世主