生成式AI领域的最新成果都在这里!抢 QCon 展区门票 了解详情
写点什么

编程神器!Facebook 推出代码智能搜索与推荐工具 Aroma

  • 2019-04-10
  • 本文字数:3743 字

    阅读完需:约 12 分钟

编程神器!Facebook推出代码智能搜索与推荐工具Aroma

工程师创造了丰富的软件与应用,但是工程师本身却被复杂繁琐的代码所束缚,面对动辄上百万行的代码,如何提升编程效率就成为了头号难题。为了解决这一问题,Facebook 推出了 Aroma,这是一款代码到代码型搜索与推荐工具,利用机器学习技术,降低从大型代码库当中获取洞察见解的难度。简而言之就是:当你编写代码时,AI 会为你推荐一种最佳写法。本文将详细解释代码建议的含义,并对 Aroma 的工作原理进行解析。


成千上万的工程师们正通过编写代码创造人们耳熟能详的各类应用程序,并借此为全球数十亿人提供服务。这绝对是一项规模浩大的任务——时至今日,人们享受的服务正变得愈发多样也愈发复杂,而这些服务当中往往包含着数百万行代码,这些代码与消息以图像的形式传递,并在各类不同系统之间相互交叉。


为了简化并加快可能对众多系统产生影响的代码编写流程。工程师们往往需要一种可行的方法,用于查找其他人如何处理类似的任务。为此,Facebook 创建了 Aroma,这是一款代码到代码型搜索与推荐工具。其采用机器学习(简称 ML)技术,旨在降低从大型代码库当中获取洞察见解的难度。


在 Aroma 出现之前,各类原有工具一直无法彻底解决这个问题。文档工具往往可用性较差且严重过时,代码搜索工具通常会返回无数个匹配结果,而用户却很难立即从其中找到自己习惯的使用模式。通过 Aroma,工程师们现在能够轻松发现常见的编码模式,而不再需要手动浏览数十个代码段,这将显著节约日常开发工作所耗费的时间与精力。


除了将 Aroma 部署到我们的内部代码库内之外,我们还开发出 Aroma 的开源版本。本文所提到的全部示例皆来自 GitHub 上的一套包含 5000 个开源 Android 项目的集合。

代码建议是什么,其意义何在?

下面,让我们思考一下 Android 工程师打算参考其他人如何编写类似代码时的情景。假设工程师编写以下内容来解码 Android 手机上的 bitmap 文件:


Bitmap bitmap = BitmapFactory.decodeStream(input);
复制代码


这确实可行,但工程师希望了解其他人如何在相关项目当中实现此项功能,特别是他们具体设置了哪些常用选项、可能遭遇到哪些常见错误,以及如何避免应用程序在生产环境中出现崩溃。


Aroma 使得工程师们能够利用代码片段本身进行搜索查询。结果将以代码建议的形式返回。每一项代码建议都创建自存储在代码库中的类似代码片段集群,并以最常见的使用模式呈现。以下为 Aroma 在此示例当中返回的第一条建议:

代码示例 1

final BitmapFactory.Options options = new BitmapFactory.Options();options.inSampleSize = 2;// ...Bitmap bmp = BitmapFactory.decodeStream(is, null, options);
复制代码


这段代码建议为存储库集合当中五种类似方法的综合产物。此处仅显示了方法集群当中的共有代码,并在不同代码片段间(即…部分)删除了各方法的具体细节。


这段代码表达出了怎样的含义?可以看到,其本质上就是工程师们在五种不同的情况下,如何为解码 bitmap 任务设置额外的选项。设置样本大小,将有助于减少解码大型 bitmap 文件时的内存消耗量。实际上,Stack Overflow 上的一篇热门帖子就曾经提到这种模式。Aroma 通过发现包含此种模式的代码片段集自动生成了这条建议。


下面让我们看看另一条代码建议。

代码示例 2

try {  InputStream is = am.open(fileName);  image = BitmapFactory.decodeStream(is);  is.close();} catch (IOException e) {  // ...}
复制代码


这段代码由另外四种方法聚类而来。它显示了 InputStream 在代码 bitmap 当中的常规作法。此外,这条建议还展示了在打开 InputStream 时捕捉潜在 IOEception 的良好实践。如果此异常在运行过程中发生且未被捕获,则应用程序将立即崩溃。负责任的工程师应当利用此项建议进行代码扩展,并正确处理这一异常问题。


将Aroma代码建议集成至编码环境当中


与传统的代码搜索工具相比,Aroma 的代码建议功能主要具有以下几项优点:


  • Aroma 在语法树上执行搜索。Aroma 并非立足字符串或者令牌级别进行匹配,而是能够真正找到在语法层面与查询代码类似的实例,并通过对不相关的语法结构进行剪枝来突出显示切实匹配的代码。

  • Aroma 能够自动将类似的搜索结果聚合在一起以生成代码建议。这些建议体现出惯用的编码模式,且易用性也远远高于非聚合搜索匹配结果。

  • Aroma 的速度表现也相当出色,可支持用户的实时使用。在实践当中,即使面对规模非常庞大的代码为,其也能够在几秒钟之内创建代码建议,且不需要提前进行任何模式挖掘。

  • Aroma 的代码算法与语言无关。我们已经在 Hack、JavaScript、Python 以及 Java 的内部代码库中部署了 Aroma。

Aroma 的工作原理


Aroma 的代码建议创建流程主要分为三个阶段:


  1. 基于特征的搜索


首先,Aroma 将代码语料库索引为稀疏矩阵。具体来讲,它通过解析语料库中的每一种方法并创建对应解析树实现这一任务。接下来,它会从每个方法的解析树当中提取一组结构特征。认真选择这些特征并捕获相关变量用法、方法调用与控制结构信息,它即可最终根据每种方法的特征为其创建一个稀疏向量。所有方法的该特征向量将共同组成索引矩阵,以供搜索检索使用。



当工程师们编写新的代码片段时,Aroma 即以上述方式创建稀疏向量,并将该向量的点积与包含所有现有方法的特征向量矩阵相乘。此后,点积当中最高的前 1000 条方法检索即为推荐结果的候选集。尽管代码语料库当中可能包含数百万种方法,但由于能够有效实现稀疏向量与矩阵的点积,整个检索过程仍能够快速完成。



  1. 重新排名与聚类


在 Aroma 对具有相似特征的方法进行检索并创建出候选集之后,下一阶段即是对结果进行聚类。为了实现这一点,Aroma 首先需要通过这些候选结果与查询代码片段间的相似性来对其进行重新排名。由于稀疏向量当中仅包含关于存在哪些特征的抽象信息,所以点积分往往会低估代码片段与查询结果之间的实际相似性。因此,Aroma 在方法语法树上应用剪枝以丢弃方法体当中不相关的部分,并仅保留与查询片段匹配度最高的部分,从而根据它们与查询代码的实际相似性进行候选代码片段的重新排名。


在获得一份与查询代码相似的降序候选代码片段清单之后,Aroma 会运行迭代聚类算法以找出彼此相似、且包含可用于创建代码建议的额外语句的代码片段构成的集群。



  1. 交叉:代码建议的创建过程


代码片段 1(改编自此项目):


InputStream is = ...;final BitmapFactory.Options options = new BitmapFactory.Options();options.inSampleSize = 2;Bitmap bmp = BitmapFactory.decodeStream(is, null, options);ImageView imageView = ...;imageView.setImageBitmap(bmp);// some more code
复制代码


代码片段 2(改编自此项目):


BitmapFactory.Options options = new BitmapFactory.Options();while (...) {  in = ...;  options.inSampleSize = 2;  options.inJustDecodeBounds = false;  bitmap = BitmapFactory.decodeStream(in, null, options);}
复制代码


代码片段 3(改编自此项目):


BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();// some setup codetry {  options.inSampleSize = 2;  loadedBitmap = BitmapFactory.decodeStream(inputStream, null, bmpFactoryOptions);  // some code...} catch (OutOfMemoryError oom) {}
复制代码


交叉算法的工作原理,是将第一个代码片段作为“基础”代码,而后针对集群当中的每一种其它方法以迭代方式对其进行剪枝。剪枝过程之后的剩余代码将成为所有方法中的共有代码,并成为代码建议中的组成部分。其它细节请参阅我们的相关论文。


在本示例当中,每个代码片段都包含特定于其项目的代码,但它们各自都具有着相同的代码,专门用于设置 bitmap 的解码选项。如上所述,Aroma 首先对第一个代码片段进行剪枝,即去掉没有出现在第二个片段中的行,从而最终找出共有代码。其中间结果如下所示:


InputStream is = ...;final BitmapFactory.Options options = new BitmapFactory.Options();options.inSampleSize = 2;Bitmap bmp = BitmapFactory.decodeStream(is, null, options);
复制代码


代码片段 1 中关于 ImageView 的代码并未出现在代码片段 2 当中,因此其会被移除。现在,Aroma 利用这一中间片段与代码片段 3 进行比对,对不存在的行进行剪枝;而后是代码片段 4,重复这一操作。最终生成的代码将以代码建议的形式返回。如代码示例 1 所示,利用这套集群所创建的代码建议恰好包含所有方法体当中所常见的三行代码。


大家也可以使用其它集群以同样的方式创建代码建议,Arom 的算法将确保提供多种不同的建议,从而帮助工程师通过查看多个代码片段了解各种各样的编码模式。举例来说,代码示例 2 就是由另一集群计算得出的建议结果。


这正是 Aroma 的真正优势所在。如今,您不再需要以手动方式筛选数十条代码搜索结果并逐个寻找其中的常见使用模式——Aroma 能够在几秒钟之内自动完成整个流程!

展望未来

考虑到目前的代码储备已经非常丰富,我们相信工程师应该拥有这种立足大型代码库发现重复编码模式,并从中学习的能力。而这,也正是 Aroma 项目的核心赋能目标。Aroma 与 Getafix 只是我们正在开发的一系列大型代码项目中的代表,它们利用机器学习技术改进软件工程水平。随着我们在这一领域中的不断进步,相信最终编程工作将成为一种半自由化任务,允许人类表达更高层次的想法,并由计算机本身负责完成具体的实现步骤。


原文链接:


https://ai.facebook.com/blog/aroma-ml-for-code-recommendation/


公众号推荐:

2024 年 1 月,InfoQ 研究中心重磅发布《大语言模型综合能力测评报告 2024》,揭示了 10 个大模型在语义理解、文学创作、知识问答等领域的卓越表现。ChatGPT-4、文心一言等领先模型在编程、逻辑推理等方面展现出惊人的进步,预示着大模型将在 2024 年迎来更广泛的应用和创新。关注公众号「AI 前线」,回复「大模型报告」免费获取电子版研究报告。

AI 前线公众号
2019-04-10 08:0012149

评论 3 条评论

发布
用户头像
搜了下,没有找到该工具
2019-04-11 09:43
回复
用户头像
还没开源?
2019-04-10 15:12
回复
刚看了Facebook的OpenSour网站:还没有这个工具https://opensource.facebook.com/#development-tools。目前只有官方博客和一些咨询报道。
2019-04-10 19:53
回复
没有更多了
发现更多内容

小议RPA

一品凡心

人工智能 RPA 自动化

特别评论:甲骨文的傲气

张晓楠

云计算 互联网巨头 企业文化

Kubernetes 容器运行时演进

倪朋飞

Kubernetes 容器 云原生

走出舒适区最好办法别走了,扩大它

乐少

精纯还是混乱?职场十二箴言——重读“成为乔布斯”的思考(一)

石君

职场 乔布斯 成功学

Kubernetes中的CI/CD

倪朋飞

Kubernetes DevOps 微服务

如何做一名失败的安全架构师

石君

架构 安全架构师 安全评估

删掉最后一句话

池建强

心理学 情绪控制

我的第一个千万阅读量

彭宏豪95

创作 生活 写作

GitHub知错就改,是个好同志

遇见

GitHub

任正非管理哲学中的三个常识和三种科学

霍太稳@极客邦科技

创业 团队管理 华为

用你喜欢的 emoji 作为页面的 favicon 吧 🎉

遇见

CSS html favicon emoji

我如何用 Python 给 Github 的 README.md 做一个访客统计功能

遇见

Python GitHub 开源 badge open-source

dubbo-go 中如何实现远程配置管理

joe

Apache 开源 微服务 dubbo Go 语言

HTTP Methods和RESTful API的设计

孙苏勇

架构 系统设计 RESTful 接口

精纯还是混乱?职场十二箴言——重读“成为乔布斯”的思考(二)

石君

创业 乔布斯 成为乔布斯

【深度】为您解读东西方艺术教育的专业设置差异对比~

默聲

探究vscode debug流程,解决无法运行go程序的问题

simpleapples

vscode Go 语言

简单到不可能失败 —— 《微习惯》

零和幺

读书笔记

是时候要说再见了,春风十里,不如邮你!

乐少

喔,明白了,成功也是一种苦难

霍太稳@极客邦科技

创业 身心健康 企业文化 个人成长 心理

做产品的同理心

孙苏勇

产品 产品经理 产品设计

《小狗钱钱》——财富离我们并不遥远

Yin

读书笔记 投资 成长 思维方式

Elasticsearch文档版本冲突原理与解决

Skysper

elasticsearch 乐观锁 悲观锁

分布式数据库是无用的屠龙术吗?

海边的Ivan

企业架构 分布式数据库 业务中台

做小池塘里的大鱼,还是大池塘里的小鱼?这是个问题。

霍太稳@极客邦科技

创业 团队管理 目标管理

如何解决 Kubernetes 的 DNS 延迟问题

倪朋飞

Kubernetes 微服务 云原生

翻译: Effective Go (2)

申屠鹏会

翻译 Go 语言

无代码开发

Fenng

【SpringBoot】掌握这两个属性,你的测试类可以启动的更快些

遇见

Java Spring Boot Unit Test

一篇文章搞定 java 中的 path 和 classpath

shengjk1

Java classpath vs path classpath path

编程神器!Facebook推出代码智能搜索与推荐工具Aroma_AI&大模型_Frank Luan_InfoQ精选文章