泪目~卷王已经在想怎么实现代码可视化了?

2023-10-20 19:30

本文主要是介绍泪目~卷王已经在想怎么实现代码可视化了?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文最初发布于 Alex Ellis 的个人博客。

有一天,我正在阅读关于个人电脑和桌面 GUI 发展的内容,我就想,我们都已经非常习惯个人电脑“桌面“这个类比。我们把文件放在文件夹里,并把它们放在桌面上。这个过程有很多物理动作发生。

人类非常善于理解空间,尤其是在记忆物理空间的时候,这让我联想到了我们通常如何将代码可视化。在思考和可视化代码的时候,有没有什么好的方法可以利用这一点?

如何可视化代码?

这让我想到了我往往如何可视化代码,有点难以描述。我认为,它通常以不同的方式存在于我的脑海中,这取决于抽象和特殊性水平,而且同时存在若干不同方式的组合。根据需要,我可以很好地在它们之间切换,特别是当我对代码库非常熟悉的时候。例如,当我想象各种微服务之间的交互时,在每个服务的周围画个大方框是很有帮助的,把每个服务视为一个大的工作单元,彼此之间通过 RPC 交互。

一个简单的面向微服务的汽车租赁服务架构图,以及代表一条执行路径的分布式跟踪。

另一方面,如果对于计算机如何读取我给它的东西,我想知道微末的细节,那么把所有东西放大到物理内存表示是有帮助的。

我曾经做过的一个 Google Sheets 页的截图,上面有内存地址和汇编指令。这对于非常仔细地了解整个过程很有帮助。

幸运的是,我把大部分时间都花在了中间的某个地方,在阅读实际的代码(比汇编高级),把大块的代码作为一个个大的单元来思考,和研究架构图及系统间通信之间做一些平衡。即使是代码本身也已经有了很多物理关系;想想目录路径、命名空间、行缩进以及代码行的线性排序。

这些可视化的效果如何?

对于这个问题,我考虑了一些不同的可视化技术,每一种技术都有不同的应用场景。考虑一下下面这个不完全的清单:

  • 架构图

  • 依赖图

  • 分布式跟踪

  • 序列图

  • 类图

  • 打印语句

  • 火焰图

  • 阅读源代码

怎么对它们进行比较呢?首先,似乎有一个天然的抽象等级轴线,从低级的代码阅读到高级的架构图。似乎还有一些其他的轴线,我们也可以对它们进行排序。

也许我们可以根据它们在多大程度上代表了更大的系统来对它们进行排名?架构图在这方面做得很好,但火焰图只能代表单个执行路径。也许是变化的频率?这是一个有趣的问题,虽然源代码经常变,但架构图(有望)保持稳定。

让我们想一下,可视化如何很好地表示整个系统实际的代码执行情况呢?在这种情况下,高级的架构图得分也许不会很高,因为它抽象掉了服务框内的许多细节。分布式跟踪可以做得更好,不过具体程度取决于有多少个跟踪点。类图虽然有助于可视化类之间的关系,但可能并不表示实际的路径。火焰图可以显示清晰的执行路径,但只能显示单条代码路径,而不能为更大的系统提供可见性。

画到图上可能会像下面这样,不过上面的这些点表示为一个范围可能更好:

这让我思考,右上角的部分会是什么样子。一个能让我们洞察细节的、有用的可视化该是什么样子?有没有一种方法可以在较低的层次上,将整个系统的路径可视化?

如果我们也使用空间会是什么样子?

看图的感觉仍然像看地图。在那一刻,你把在代码中看到的东西在空间上转化为图表,就像你在一个不熟悉的地方用地图确定方向。就像电脑上的东西,我们用了桌面隐喻一样,我想知道是否有另一种方式将代码可视化为实际存在的东西,以便让翻译过程变得更容易。

如果我们用“玩具型可视化(toy visualization)”在物理空间中表示代码,会怎么样?

看下面这个基本的例子,我们有一个 Counter 类,它有一个私有的 count_ 变量并提供了各种访问方法。也许它会在一个简单的 main 函数中被访问,做一些计数。

#include <iostream>class Counter {
public:void reset() {count_ = 0;}  int get() {return count_;}void incr() {++count_;}void set_count(int x) {count_ = x;}
private:int count_;
};int main() {Counter counter;counter.reset();counter.incr();counter.incr();  std::cout << counter.get();
}

复制代码

如果我们把代码的不同部分表示为三维结构,会怎么样?如果我们把 Counter 类表示为一个大房间,墙上写着咒语,会怎么样?你可以想象代码的可能路径,变量和它们所代表的事物之间的联系,就像下图中的粉红线:

我们可以从中看到什么?首先,作为私有变量,count_ 的用法显然没有什么不当,因为没有任何粉红线从它那里离开房间。公共方法也很清楚,它们与房间外的事物有粉红色的连接。

更有趣的是,这个房间与另一个房间相连,会是什么样子?main 函数可以是另一个房间,其符咒线也做了相应的连接:

现在,我们可以跨房间对话了;在 main 函数调用 counter.reset() 的地方,我们可以有一个从调用者 main 到被调用者 Counter 类的连接。你甚至可以想象有一个调试器单步遍历这个过程,观察这条线路上的参数和返回值。想象一下,我们可以放大不同的区域来查看本地状态和数值,然后沿着调用路径返回到活动区域。

这有用吗?

像这样的东西有用吗?我不确定。用这样的方式走查一个熟悉的代码库会很有趣,特别是当你能在 3D 表示(或是 VR 环境)中做空间探索,并可以根据需要缩小和放大时。当第一次探索一个新的代码库,查看事物之间的连接关系时,不知道它是否会特别有用。不过,我确实处理过一些代码库,如果这样看会非常吓人。我很想看看这样看会有什么不同,每新引入一个类,这儿那儿就会引入新的连接。

话虽如此,我认为在制作这样的东西时,你至少会遇到以下问题:

  • 复杂的代码很难推理。把意大利面代码中的意大利面可视化可谓大快人心,但是对于非常复杂的代码来说,这样做不知道会有多繁琐?

  • 如何表示出像线程同时执行这样的东西?

  • 如何表示是引用传递而不是值传递?

  • 如何表示异步工作?如何表示递归?房间一直嵌套下去?

  • 如何防止里面的东西变得陈旧和过时?至少,这个需要能够自动生成。

问题

有几个考量因素使这个问题变得棘手。一个是物理位置的变化比代码的变化耗时通常长得多。使用熟悉的物理位置作为记忆宫殿,一部分原因是它在你的记忆中每次出现都是一样的。如果你在记忆一副扑克牌,你可以把梅花 A 暂时存放在橱柜门后面,下次你需要存放扑克牌时,橱柜门仍然在那。

如果你的代码库经常变化,反映事物空间布局的地图就可能会发生变化,不管这些地图是 3D 生成的还是纯意识的。这就像回到一个你曾经熟悉的地方,想象一下,不只是地标变了,路也改道了。即使我们天生具有记忆空间事物的天赋,如果那个空间发生了变化,如果我们不得不重新学习,我们还能从空间可视化受益吗?

看看这样的东西对于探索一个新代码库(就像使用地图探索一座新的城市),以及随着时间推移再次回到该代码库(就像离开很长时间后回到自己的家乡),有多大帮助,这会很有趣。

代码可视化项目

我对这一领域的数据可视化不是很熟悉(其他领域的也不熟悉),但经过简单的搜索(也就是 30 分钟的 Google 搜索),我发现有几个项目似乎在做类似的事情:

  • SoftVis3D:其中的“代码城市”视图提供了项目层次结构的可视化。

  • Code Park:一款新的 3D 代码可视化工具(2017),“在类似三维游戏的环境中可视化代码库”,其中,代码被表示为 "代码室",代码在墙上(现在读到这个,感觉和我的想法非常类似)。

  • 使用 3D-Flythrough 实现代码结构可视化(2016),提供空间隐喻和第一人称代码探索。

  • Primitive:一家 VR 合作初创公司,拥有矩阵式的“沉浸式开发环境”,包括“面向 3D 视觉分析软件的新工具”。

下面是读者指出的一些项目:

  • AppMap:一个自动化代码分析工具,包括依赖关系图和跟踪视图。

  • plurid:一个用于在三维可探索结构中可视化和调试代码的框架。

  • fsn(文件管理器):一个实验性的应用程序,支持以 3D 方式查看文件系统(出现在 Jurassic Park 中)。

如果你了解到其他类似的项目,欢迎和我联系,我非常乐意听到更多这样的项目!

有趣的想象

显然,这个概念并不是什么突破性的东西,但我认为,对于我们使用的工具,这是一个有趣的思考方式,重要的是,我们如何做得更好。一定有更好的方法存在,设想下它们可能的样子会很有趣。

查看英文原文:

How do you visualize code? · Caffeinspiration

这篇关于泪目~卷王已经在想怎么实现代码可视化了?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:https://blog.csdn.net/wdjnb/article/details/124502721
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/249262

相关文章

Java反射实现多属性去重与分组功能

《Java反射实现多属性去重与分组功能》在Java开发中,​​List是一种非常常用的数据结构,通常我们会遇到这样的问题:如何处理​​List​​​中的相同字段?无论是去重还是分组,合理的操作可以提高... 目录一、开发环境与基础组件准备1.环境配置:2. 代码结构说明:二、基础反射工具:BeanUtils

使用Python实现base64字符串与图片互转的详细步骤

《使用Python实现base64字符串与图片互转的详细步骤》要将一个Base64编码的字符串转换为图片文件并保存下来,可以使用Python的base64模块来实现,这一过程包括解码Base64字符串... 目录1. 图片编码为 Base64 字符串2. Base64 字符串解码为图片文件3. 示例使用注意

使用Python实现获取屏幕像素颜色值

《使用Python实现获取屏幕像素颜色值》这篇文章主要为大家详细介绍了如何使用Python实现获取屏幕像素颜色值,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、一个小工具,按住F10键,颜色值会跟着显示。完整代码import tkinter as tkimport pyau

在Java中将XLS转换为XLSX的实现方案

《在Java中将XLS转换为XLSX的实现方案》在本文中,我们将探讨传统ExcelXLS格式与现代XLSX格式的结构差异,并为Java开发者提供转换方案,通过了解底层原理、性能优势及实用工具,您将掌握... 目录为什么升级XLS到XLSX值得投入?实际转换过程解析推荐技术方案对比Apache POI实现编程

IDEA如何实现远程断点调试jar包

《IDEA如何实现远程断点调试jar包》:本文主要介绍IDEA如何实现远程断点调试jar包的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录问题步骤总结问题以jar包的形式运行Spring Boot项目时报错,但是在IDEA开发环境javascript下编译

深入解析 Java Future 类及代码示例

《深入解析JavaFuture类及代码示例》JavaFuture是java.util.concurrent包中用于表示异步计算结果的核心接口,下面给大家介绍JavaFuture类及实例代码,感兴... 目录一、Future 类概述二、核心工作机制代码示例执行流程2. 状态机模型3. 核心方法解析行为总结:三

Python实现自动化Word文档样式复制与内容生成

《Python实现自动化Word文档样式复制与内容生成》在办公自动化领域,高效处理Word文档的样式和内容复制是一个常见需求,本文将展示如何利用Python的python-docx库实现... 目录一、为什么需要自动化 Word 文档处理二、核心功能实现:样式与表格的深度复制1. 表格复制(含样式与内容)2

python获取cmd环境变量值的实现代码

《python获取cmd环境变量值的实现代码》:本文主要介绍在Python中获取命令行(cmd)环境变量的值,可以使用标准库中的os模块,需要的朋友可以参考下... 前言全局说明在执行py过程中,总要使用到系统环境变量一、说明1.1 环境:Windows 11 家庭版 24H2 26100.4061

Python数据分析与可视化的全面指南(从数据清洗到图表呈现)

《Python数据分析与可视化的全面指南(从数据清洗到图表呈现)》Python是数据分析与可视化领域中最受欢迎的编程语言之一,凭借其丰富的库和工具,Python能够帮助我们快速处理、分析数据并生成高质... 目录一、数据采集与初步探索二、数据清洗的七种武器1. 缺失值处理策略2. 异常值检测与修正3. 数据

Python中bisect_left 函数实现高效插入与有序列表管理

《Python中bisect_left函数实现高效插入与有序列表管理》Python的bisect_left函数通过二分查找高效定位有序列表插入位置,与bisect_right的区别在于处理重复元素时... 目录一、bisect_left 基本介绍1.1 函数定义1.2 核心功能二、bisect_left 与