如何阅读别人的代码?

时间: 2020-02-06阅读: 464标签: 代码

挺多人问过我“如何阅读已有代码”这个问题,希望我能有一个好的方法。有些人希望通过阅读“优质项目”(比如 Linux 内核)得到启发,改进自己的代码质量。对于这个问题,我一般都不好回答,因为我很少从阅读别人的代码得到提升。每一次阅读别人的代码,对我来说都是一种折磨,而且每一次都不是别人的代码提升了我,而是我提升了别人的代码。

比起阅读代码,我更喜欢看别人的文章或者书。我喜欢他们跟我面对面的交流,用简单的自然语言或者画图解释他们的思想。有了思想,我自然知道如何把它变成代码,而且是优雅的代码。每一次参加学术会议,我都发现自己几乎无法理解会议上的 talk 或者 paper。我会在 talk 结束之后的喝茶时间走到演讲者面前,对他说:“你的 talk 很有意思,你能在三句话之内总结一下你说了什么吗?” 这样交流之后,我忽然就懂了。

如果有同事请我帮他改进代码,我不会拿起代码埋头看,因为我知道看代码往往是没用的。我会让他们先在白板上给我解释那些代码是什么意思。我的同事们都发现,把我讲明白是很困难的。因为我的要求非常高,只要有一点不明白,我就会让他们重新讲。还得画图,我会让他们反复改进画出来的图,直到我能一眼看明白为止。如果图形是 3D 的,我会让他们给我压缩成 2D 的,理解了之后再“推广”到 3D。我无法理解复杂的,高维度的概念,他们必须把它给我变得很简单。

所以跟我讲代码总是需要费很多时间,但这是值得的,因为我明白了之后,往往能挖出其他人都难以看清楚的要点。给我讲解事情,也能提升他们自己的思维和语言能力,帮助他们简化思想,甚至在忽然间发现改进他们自己代码的方法。很多时候我根本没看代码,通过给我讲解,后来他们自己就把代码给简化了。节省了我的脑力和视力,他们也得到了提高。

我最近一次看别人的代码是在 Intel,我们改了 PyTorch 的代码。那不是一次愉悦的经历,因为虽然很多人觉得 PyTorch “好用”,它内部的代码却是非常晦涩,难以理解的。PyTorch 不是 Intel 自己的东西,所以没有人可以给我讲。修改 PyTorch 代码,增加新功能的时候,我发现很难从代码本身看明白应该改哪里。后来我发现,原因在于 PyTorch 的编译构架里自动生成了很多代码,导致你无法理解那些代码是怎么来的。

比如他们有好几个自己设计的文件格式,里面有一些特殊的文本,决定了如何在编译时生成代码。你得理解这些文件里面的内容在说什么,而那不是任何已知的语言。这些文本文件被一些 Python 脚本读进去,吐出来一些奇怪的 C++,CUDA,或者 Python 代码。这其实是一种 DSL。我已经在之前的文章中解释过 DSL 带来的问题。所以要往 PyTorch 里面加功能,你就得理解这些脚本是如何处理这些文本文件,生成代码。而这些脚本写得也比较混乱和草率,所以就是头痛 2 ,头痛的平方。

最后我发现,根本没有办法完全依靠这些代码本身来理解它。那么怎么解决这个问题呢?幸好,网络上有 PyTorch 的内部工程师写了篇 blog ,解释 PyTorch 如何组织代码。Blog 的作者 E. Z. Yang 我见过一面,是在一次 PL 学术会议上。他当时在 MIT 读书,貌似一个挺聪明的小伙子。不过看了这 blog 也只能初步知道它做了什么,应该碰大概哪些文件,而这些每天都可能变化。

这篇 blog 还提到,某几个目录里面是历史遗留代码,如果你不知道那是什么,那么请不要碰!看看那几个目录,里面都是一些利用 C 语言的宏处理生成代码的模板,而它使用 C 语言宏的方式还跟普通的用法不一样。在我看来,所谓“宏”(macro)和 metaprogramming 本身就是一个巨大的误区,而 PyTorch 对宏的用法还如此奇怪,自作聪明。

你以为看了这篇 blog 就能理解 PyTorch 代码了吗?不,仍然是每天各种碰壁。大量的经验都来自折腾,碰壁,在黑暗中摸索。多个人同时在进行这些事情,然后分享自己的经验。讨论会内容经常是:“我发现要做这个,得在这个文件里加这个,然后在那个文件里加那个…… 然后好像就行了。” 下次开会又有人说:“我发现不是像你说的那样,还得改这里和这里,而那里不是关键……” 许多的知其然不知其所以然,盲人摸象,因为“所以然”已经被 PyTorch 原来的作者们掩盖在一堆堆混乱的 DSL 下面了。

所以我从 PyTorch 的代码里面学到了什么呢?什么都没有。我只看到各种软件开发的误区在反复上演。如果他们在早期得到我的建议,根本不可能把代码组织成这种样子,不可能有这么多的宏处理,代码生成,DSL。PyTorch 之类的深度学习框架,本质上是某种简单编程语言的解释器,只不过这些语言写出来的函数可以求导而已。而写解释器是我最在行的事情。

那么我是怎么成为现在这个样子的呢?肯定有某种方法,对吧。我的方法很简单,写最短最精巧的代码,从最薄最精悍的书或者课程里面学,从真正的大师那里学,而不是大型开源项目。

造就我今天的编程能力和洞察力的,不是几百万行的大型项目,而是小到几行,几十行之短的练习。不要小看了这些短小的代码,它们就是编程最精髓的东西。反反复复琢磨这些短小的代码,不断改进和提炼里面的结构,磨砺自己的思维。逐渐的,你的认识水平就超越了所有这些几百万行,让人头痛的项目。

很多人都不知道,有一天我用不到一百行 Scheme 代码就写出了一个“深度学习框架”,它其实是一个小的编程语言。虽然没有性能可言,没有任何 GPU 加速,功能也不完善,但它抓住了 PyTorch 等大型框架的本质——用这个语言写出来的函数能自动求导。这种洞察力才是最关键的东西,只要抓住了关键,细节都可以在需要的时候琢磨出来。几十行代码反复琢磨,往往能帮助你看透上百万行的项目里隐藏的秘密。

所以我如何阅读别人的代码呢?Don’t。除非我真的要使用那个项目的代码,我才会去折腾它。

原文 http://www.yinwang.org/blog-cn/2020/02/05/how-to-read-code
站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/7434

关闭

编写优秀CSS代码的8个策略

编写基本的CSS和HTML是我们作为Web开发人员学习的首要事情之一。然而,我遇到的很多应用程序显然没有人花时间真正考虑前端开发的长久性和可维护性。

js函数式编程与代码执行效率

函数式编程对应的是命令式编程, 函数式编程的核心当然是对函数的运用. 而高阶函数(Higher-order)是实现函数式编程的基本要素。高阶函数可以将其他函数作为参数或者返回结果。所以JS天生就支持函数式编程

Js代码中的span拼接

今天遇到一个小需求,用bootstrap的table只有两个字段,占用太宽,页面不美观,组长要求用拼接,一行几列的形式展现出来。我在form表单中拼接了span,遇到以下问题:

Js代码简洁之道

如果你关注代码本身和代码的编写方式,而不是只关心它是否能工作,那么你写代码是有一定的水准。专业开发人员将为未来的自己和“其他人”编写代码,而不仅仅只编写当前能工作就行的代码。

Javascript代码中的骚操作

笔者是一个喜欢将Javascript各种骚操作进行到底的一个人,且不喜欢添加注释的那一种。曾经有小伙伴接手过我的一个项目,看完代码后,差点要揍我,第二天沉默的向领导提出了辞职。

程序员吐槽:经常熬夜敲代码,谈了四年的女朋友提出分手了

这年头说起程序员,普通人都会很羡慕他们的高薪,毕竟刚工作就可以月薪上万,三五年工作月薪两万,干一年相当于普通人干个5年的,谁又能不眼红呢?不过程序虽然高薪,但也有自己的苦处。

提高代码质量:如何编写函数

本文从函数命名,函数参数和函数的代码编写三个方面谈了关于如何编写好一个函数的感受和想法。文中提到了很多具体的情况,当然日常编码中肯定会遇到更多复杂的情况可能我暂时没有想到。我简单的归纳了几点

写优雅的代码,做优雅的程序员

软件工程学什么? 学计算机,写程序,做软件,当程序员。听说学计算机很辛苦? 是的,IT行业加班现象严重。在计算机世界里,技术日新月异,自学能力是程序员最重要的能力之一。选了这个专业,就要时刻保持好奇心和技术嗅觉,不能只满足于完成课内作业。

最好的代码是没有代码

不久前,我开始着手清理一个接手过来的项目。因为项目有一些 bug,所以我有足够的自由来重构它。但修复旧 bug 会引入新 bug,于是乎我就陷入了恶性循环。

如何用不到200行代码写一款属于自己的JS类库

JavaScript 的核心是支持面向对象的,同时它也提供了强大灵活的 OOP 语言能力。本文将使用面向对象的方式,来教大家用原生js写出一个类似jQuery这样的类库。我们将会学到如下知识点

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!