为什么使用Chrome浏览器使我开发了一种用于读取源代码的工具

Coati是用于快速高效地进行源代码导航和浏览的开发人员工具。 这是一个关于在Google实习的经历如何激发我开始研究用于读取源代码的工具的故事。 我将展示早期的原型,并解释以用户为中心的设计过程如何改善和完善用户界面。 这是一个相当详细的报告。 如果您希望使用简短的摘要,请访问我们的网页。

在Google Chrome图形小组实习

在经过繁琐的申请程序后,2012年秋天,我证明自己是在加利福尼亚州Google Mountain View实习的幸运学生之一。 那是我在萨尔茨堡应用科学大学本科学位课程的最后一年,我在那里攻读游戏开发专业。 我曾经从事过许多计算机图形学方面的工作,对人机交互非常感兴趣,我非常了解C ++和JavaScript,因此在Google Chrome图形团队的实习非常合适。

在山景城办公室前面的墙上镀铬徽标。

我分配的第一个任务似乎很简单,我几乎感觉就像要被FizzBu​​zzed吸引,但是我的主管向我保证这并不容易。 图形团队已为Chromium实施了帧频计,以显示刷新网页的频率。 当时,显示它的唯一方法是通过命令行标志“ –show-fps-counter”。 我的任务是在Chrome DevTools的设置中添加一个复选框,以使FPS仪表更易于访问,并且每个选项卡均可调整。 我很快就知道必须在哪个文件中添加复选框,并且我还知道FPS仪表在合成器的HUD层中的何处显示。 我真正需要做的就是从一个地方向另一个地方发送布尔值。 它能有多难? 我应该让它在1-2个小时的时间里工作,并在一个良好的工作日内完成。

成为Chromium开发人员

您可能已经猜到了,这花了我比预期更长的时间。 Chromium代码库非常庞大,虽然我的主管对Chromium的合成器非常了解,这是该团队正在研究的主要部分,但他并不能真正告诉我有关DevTools及其中间部分的更多信息。 他向我展示了他用于在代码库中进行搜索的工具:grep,git-grep和Chromium Code Search,这是一个在线源代码浏览器,其中对整个Chromium代码库进行了索引。

我很快意识到,我没有丝毫机会了解Chromium的大型体系结构。 该文档并没有真正的帮助,因为对于我的用例而言,大多数文档都太高级了。 我还了解到,尽管团队的开发人员非常友好,但是对于不断被一些询问代码基础的实习生打扰他们并不感到兴奋。 因此,我大部分时间都花在阅读源代码和绘制类组成方式以及调用某些方法的地方上。

大约2-3天后,我终于完成了一个非常棘手的实现工作。 我没有担心线程同步,没有在几个地方删除const,也不知道我实际上同时处理了两个代码库,即Chromium和WebKit(现在是Blink)。 在得到主管的一些初步反馈之后,代码审查过程开始了,在两次重写整个实现之后,我终于可以找到两个补丁(1、2)并完成我的任务。 最后,整个过程持续了大约一个月。

Chrome的DevTools中的复选框,用于切换FPS仪表。

软件开发人员比编写源代码花更多的时间在阅读上

在下次会议上,我的主管祝贺我的出色表现。 我感到困惑。 对我来说,整个任务花费了太长时间。 我花了大约95%的时间来阅读源代码。 我说那没什么效果,问他如何改善。 他让我平静下来,并告诉我我实际上比他预期的要快得多。 听到这个消息我感到很惊讶。 从技术上讲,我每小时的工作时间只编写了不到一行代码,听起来效率不高。 “环顾四周,”他说,“这里的每个人大部分时间都在阅读源代码。 这是大型软件项目工作的一部分。 新开发人员在这里实际要花大约两个月的时间。”

开发人员花费的时间(基于“当理解意味着重写”的图表)

当时对我来说这是新事物,但事实证明,这是软件开发人员的一个众所周知的事实,与实际编写源代码相比,阅读所花的时间更多。 彼得·哈勒姆(Peter Hallam)撰写了有关此内容的博客文章,并指出,软件开发人员大约70-78%的时间都花在了理解现有实现上。 这启发了Jeff Atwood在Coding Horror上写了一篇帖子,进一步质疑开发人员是应该阅读源代码还是只是从头开始重写。 由于对于Chromium上的新开发人员而言,重写并不是真正的选择,因此唯一的选择是读取源代码。

您如何阅读源代码?

如果花大量时间在阅读源代码上,那么哪些工具可用于此任务? 我开始询问团队中的开发人员和大学的朋友他们如何阅读代码(《黑客新闻》上也有关于该主题的线程:1、2)。 事实证明,没有通用的策略可以探索源代码。 一些开发人员使用grep,一些调试器,其他绘制图表。 他们中的大多数人只使用其源代码编辑器及其提供的任何功能。 但是,尽管源代码编辑器非常适合有效地编写源代码,但它们并不是用于快速检索有关实现的信息。

铬代码搜索是朝着正确方向迈出的一大步。 通过显示某个符号的所有出现,它已经比大多数开发人员工具提供了更多的功能。 但是,您仍然需要通过阅读符号出现的每一行来弄清楚该符号与其他符号之间的关系。 编程语言被设计为密集且富有表现力,这使得一眼就很难检测到信息。 作为软件开发人员,您始终必须处理源代码的所有细节。 您需要花费大量的时间在文件之间搜索少量信息,然后慢慢建立代码路径的思维模型。

在阅读源代码时建立心智模型需要花费时间。

在阅读源代码时,我开始观察自己。 在查看类或函数时,我通常感兴趣的是什么? 大多数时候,我只是想了解非常简单的事情。 类在哪里实例化? 哪些类实现特定接口? 该方法在哪里调用? 通过阅读源代码行和源代码行来查找此信息需要花费大量时间。 计算机知道编程语言如何工作,因此已经知道整个代码库中所有符号在何处以及如何使用。 为什么我不能直接问这些问题? 为什么我不能只输入搜索查询以查找想要知道的内容,然后将所有内容摆在我面前?

通过静态分析进行视觉导航

几周后,我想出了一个解决此问题的想法:源代码结构的交互式可视化。 这个想法并不是真正的新想法,后来我甚至知道它几乎和编程一样古老。 我想象过一种工具可以静态地分析源代码,从而找出存在的符号以及它们之间的关系。 然后,该语义信息用于创建以符号为节点,关系为边的图形可视化。 可视化文件像地图一样放在源代码旁边。 通过单击任何节点或边缘,您可以立即查看其在源代码中属于哪一行。 这将使您能够快速获得所有现有符号的概述,同时仍然能够访问实现的所有细节。 超级简单!

可视化表示源代码的结构会使您的大脑不堪重负。

我牢记这个主意,并与一些人谈过,这产生了不同的结果。 在实习期间,我继续研究Chromium的开发人员工具,结识了DevTools和DevRel团队,并在Chrome开发者博客上撰写了一篇文章。 我很高兴能有机会在Google的高度专业的环境中工作,在那里我学到了很多有关编写健壮且可维护的代码的知识。

对软件可视化进行一些研究

我返回萨尔茨堡以完成本科学历。 其中一部分是写论文。 我可以自由选择任何主题,因此我决定致力于我的想法。 我想创建一个原型,并在一个小的定性用户研究中对一些参与者进行测试。 当时,由于在RMIT Exertion Games Lab进行了较早的实习,我已经在人机交互领域拥有一些经验,因此我已经做好了充分的准备。

我首先阅读了几本有关可视化方法,人类视觉感知和软件可视化历史的书籍和论文。 我仍然记得我是如何看过一段的,这让我特别感兴趣。 它给出了一个非常简单的解释,说明为什么软件可视化尚未在计算机科学中广泛使用:

可视化在机械工程,化学,物理和医学中被大量使用。 计算机科学家已经开发出复杂的系统来为这些学科提供可视化效果。 令人惊讶的是,计算机科学家仅很少使用可视化作为设计,实施和维护软件的工具。 更糟糕的是,许多人认为自己是理论家,而无视可视化-这是一种词源错误的二分法。 程序员倾向于适应计算机提供的表示水平,而不是适应计算机的显示能力。”
(Dhiel 2007,2)

第一个交互式原型

我的第一个原型实际上没有实现任何静态源代码分析。 我只是用C ++创建了一个简单的井字游戏,并手动进行了分析。 该原型是用JavaScript与Raphaël和Syntax Highlighter构建的。 它在简单的代码视图旁边具有交互式图形可视化功能。 图形可视化或多或少是根据著名的视觉信息搜索口头禅设计的,该口头禅一直是Coati用户界面设计的指导原则:

“先概述,然后缩放和过滤,然后再按需细节”
(Shneiderman 1996)

图形可视化显示了项目的所有符号及其关系。 单击任何节点时,该符号的相应声明将显示在代码视图中。 边缘及其对应的语句相同。 类节点最初隐藏其成员,并且可以通过单击省略号(…)进行扩展。

第一个原型的图像。 不同的节点和边缘类型以不同的形状显示。

该原型有一些明显的缺陷,但足以实现其一个目的:测试交互式可视化是否有助于理解源代码。 经过三年的迭代和抛光,这个原始的原型几乎与Coati的工作方式无关。 但是,如果您想看看,我在这里提供了它。

最重要:与您的用户交谈

我的用户研究有十二名参与者,或多或少都有经验的软件开发人员。 首先,我向他们询问他们的工作流程以及使用的工具。 在我向他们解释了如何使用我的原型后,研究的主要部分开始了。 参与者必须通过选择以下问题来从Tic-Tac-Toe游戏的源代码中检索信息:

  • 哪些类来自Player类?
  • 成员Field :: grid_的目的是什么?
  • 为什么一局游戏结束后游戏会重启?

(我们仍然在Coati试用挑战赛中使用这些问题,每次下载都附带Tic-Tac-Toe源代码。)

这些问题中的一些问题很容易通过原型解决,而其他问题则很难解决。 参与者只能使用原型提供的有限功能。 我敦促他们在解决问题时大声思考。 该研究以简短的公开访谈结束,以收集反馈,从而得出了一些非常重要的见解:

  • 参与者报告说,图形可视化确实有助于回答一些问题,但是一旦扩展了太多的课程,它就会变得非常混乱。
  • 我注意到,有些参与者也尝试在代码视图中单击符号,而另一些参与者在反馈访谈中提出了建议。
  • 一些参与者正在寻找搜索功能,或者后来提出应该可以以某种方式找到每个符号。
  • 大多数参与者曾经经历过自己在源代码中迷失了自己,并说他们会对这种适当的工作工具感到满意。

寻找团队和工作场所

好吧,这变得越来越有趣。 如何正确创建此工具? 继续攻读本科学位的硕士学位允许学生从事一项为期两年的大型项目。 太完美了 我有一些朋友也获得了硕士学位,因此由四个软件工程师组成的团队并不难。 最终,我们还找到了一名平面设计师。 大学甚至给了我们一个小的项目室,我们可以在课程之间进行工作。

浣熊队

下一个迭代:搜索,图形,代码

从第一次用户研究的反馈中得出的结论,我们回到了白板上,重新思考了这个概念。 我们设计并开发了另一个原型,并对第一个原型进行了一些重大改进:

  • 可以激活符号以在每个视图中显示所有相关信息。
  • 可以通过带有自动完成功能的小型搜索字段找到并激活每个符号。
  • 图形可视化仅显示活动符号及其与其他符号的所有关系。
  • 可以单击代码视图中的行以激活符号。

第二个原型的图像。 它具有一个带有自动完成功能和交互式代码视图的搜索字段。

如果您想测试第二个原型,我也在这里提供了它。

我们使用此改进的原型进行了另一个用户研究,并获得了更好的反馈。 这次,参与者真正看到了使用这种工具的巨大好处。 他们仍然需要更多功能,但是我们有概念证明。 我们的工具将包含三个主要组件:

  • 用于查找符号的搜索字段
  • 图形可视化以探索关系
  • 代码视图中所有实现的细节

浣熊概念涂抹显示三个主要组成部分:搜索,代码,图。

开始使用C ++和Clang开发

在实际开始工作之前,我们必须仔细研究一下并检查我们概念化的工具是否还不存在。 我们研究了各种开发人员工具,例如IDE,UML工具,文档软件,插件,扩展,甚至是可视化编程语言。 我们发现了很多基于静态分析的工具,一些使用可视化工具,一些具有自动完成功能,但是没有任何工具可以将所有这些强大功能真正整合到一个简单的用户界面中。 我们定义了对我们很重要的关键方面,并使Coati与其他工具区分开来:

  • 简单 :每个开发人员都应该能够在几分钟之内拿起并开始使用它。
  • 独立 :开发人员已经使用什么平台或工具都没有关系。
  • 快速 :应具有高度的响应能力,而无需等待时间来获得结果。
  • 离线 :无需上传源代码或与互联网保持稳定连接。
  • 同伴 :它应该扩展开发人员的工具链,而不用更换任何工具。 已经有很多出色的源代码编辑器,无需构建另一个。 相反,我们允许Coati与源代码编辑器进行通讯,请查看我们的插件。

更大的开放性问题之一是使用哪种编程语言编写我们的工具,以及支持哪些语言。 由于静态分析无法在每种语言上同样有效,因此我们必须选择一种类型的语言。 我们决定支持C ++。 C ++速度很快,在跨平台上运行良好,具有良好的跨平台库,在应用程序开发中被广泛使用,我们自己也非常了解它。 我们使用Clang LibTooling进行静态分析,这也使我们能够轻松支持C和C ++。 从上一发行版以来,我们还使用JavaParser和JavaSymbolSolver将语言支持扩展到Java。

向开发人员提供Coati

快进两年了。 硕士学位毕业后,我们不想浪费我们的项目,所以我们决定继续努力。 到现在为止,Coati已经成为一家小型创业公司,我们正在努力利用我们的工具谋生。

我们的网站于2016年春季启动,标志着我们的公开测试版的开始。 目前,我们以Coati 0的预发行版本提供Coati。在过去的几个月中,我们的第一批客户为我们在使Coati适应现实软件开发的需求方面提供了很多帮助。 他们还要求许多新的UI功能,这比我们目前发现的实施时间要多。

Coati当前的用户界面显示了原型的Tic-Tac-Toe游戏。

到目前为止,我已经将Coati用于开发工作大约一年了,它极大地影响了我的工作流程。 起初我只是偶尔使用它,当时我真的很难理解我的一位同事写的东西。 现在,我不断在第二个屏幕上打开Coati,并将其用于代码库中的最快速查找。 我想我已经越过了不归路的地步。

除其他外,我将Coati用于:

  • 启动新任务时检查实现。
  • 探索类型和函数之间的依赖关系。
  • 查找在哪里实现了接口以及哪些方法被重写。
  • 遵循方法之间的代码路径。
  • 找出重构时可以简化或删除的内容。

在我们的网页上了解有关Coati功能的更多信息。

Coati还简化了我们开发团队之间的沟通。 在Coati之前,我们经常花很多时间争论改变某个实现可能带来的副作用。 现在,我们只研究Coati的问题,立即查看是否出现问题。 Coati允许我们从鸟瞰图查看代码库,这使探索所有符号及其依赖关系变得容易。

在过去的几个月中,Coati已为我们节省了大量时间。 我为我们已经取得的成就感到自豪,并且为即将实现的一些出色功能而感到兴奋。 如果您现在想看看Coati的用户界面,请继续下载我们的试用版。

那是我关于浣熊的故事,希望您喜欢! 请分享并推荐(下面是那颗绿色的小心脏)。