专栏名称: 伯乐在线
关注职业资讯;学习各类职业感悟、心得和经验分享,扩大职业视野;体会求职、工作和创业的历程 - 就在JobBole.com 伯乐在线
目录
相关文章推荐
程序员小灰  ·  AGI来了,我们还需要拼命工作吗? ·  昨天  
程序猿  ·  AI 正在培养“文盲”程序员? ·  昨天  
程序员的那些事  ·  湖南大学的 DeepSeek ... ·  3 天前  
OSC开源社区  ·  字节跳动开源跨平台UI框架Lynx:一套代码 ... ·  3 天前  
51好读  ›  专栏  ›  伯乐在线

程序员,热爱你的 bug

伯乐在线  · 公众号  · 程序员  · 2019-06-11 21:13

正文

(给 伯乐在线 加星标,看经典文章


编译: 伯乐在线/学以致用123


2017 年 10 月初,我在贝洛奥里藏特(巴西) 的 Python Brasil 大会做了一个主题演讲。下面是这个演讲的笔记 。 这里可以下载视频。

我热爱 bug

我现在是 Pilot.com 的高级工程师,为初创公司开发自动记账系统。在这之前,我在 Dropbox 的桌面客户端团队工作,后面我会讲到在那里工作时的一些小故事。在那之前,我是 Recurse Center 的一个推进者,Recurse Center 对于程序员的感觉很像写作者的隐居地。我在大学学习的是天体物理学,在成为工程师之前在金融机构工作了几年。

但是这些事情没有一件是重要的—你只需要记住我热爱 bug 就足够了。我热爱 bug 是因为它们非常有趣。它们富有戏剧性。一个大 bug 的查找过程曲折离奇。一个大 bug 很像一个很好的笑话或谜语,你期待一个输出,但结果却大相径庭。

在这个讲演中,我将会讲述一些我热爱的 bug,解释我为什么如此热爱 bug,然后说服你也应该热爱 bug。

第一个 Bug

好,直接进入 第一个 Bug。这是我在 Dropbox 遇到的一个 bug 。你可能知道,Dropbox 是个应用程序,可以将文件从一台计算机同步到云端,并同步到其它计算机。


这是一个简化的 Dropbox 架构图。桌面客户端在本地监控文件系统的变化。当它找到一个改变的文件,将阅读文件并对 4MB 块中的内容进行哈希处理。这些块存储在一个巨大的键值对存储后端,我们称之为 blockserver。键是经哈希处理的内容的摘要,值是内容本身。

当然,我们要避免多次上传同一个块。想象一下,你正在写一个文档,很可能只是更改了结尾–我们不希望一次又一次的上传开头部分。因此,在将块上传到 blockserver 之前,客户端与另一个管理 metadata 和权限的服务器通信,客户端询问 meta 服务器是否需要这个块或者是否见过这个块。meta 服务器对每个块是否需要上传进行响应。

所以,请求和响应看起来是这样的:客户端:’我有一个由哈希块 'abcd,deef,efgh' 组成的更改文件。服务器响应”我有前面两个,上传第三个”。然后客户端将第三个上传到 blockserver。


上面是设想,下面的则是 bug 。


有时,客户端会发出一个奇怪的请求:每个哈希值应该是16个字符长,但是请求的长度是33个字符,比期望长度的两倍还多 1 。服务器不知道该怎么处理这个异常,会抛出一个异常。我们看到这个异常报告,并查看客户端的日志文件,真是奇怪的现象—客户端本地数据库损坏了,或者 python 将抛出 MemoryErrors ,所有这些都没有道理。

如果你从没有见过这个问题,那么这完全是个谜。但是一旦见过一次,之后的每一次都会认出它。这里有个提示:我们经常看到的 33 个字符长的字符串的中间的字符不是逗号而是 l 。下面是我们在中间位置看到的其他字符:

l \ x0c < $ ( . -

逗号的 ascii 码是 44 , l 的 ascii 码是 108,在二进制中,它们是这表示的:

bin ( ord ( ',' )) : 0101100

bin ( ord ( 'l' )) : 1101100


你将发现 l 与逗号仅仅相差 1 位。而这就是问题所在:一个位翻转 (bitflip)。客户端使用的内存有一个 bit 损坏了,现在客户端正在向服务器发送垃圾请求。

下面是出现位翻转时我们经常看到代替逗号的其他字符:

, : 0101100

l : 1101100

\ x0c : 0001100

0111100

$ : 0100100

( : 0101000

. : 0101110

-    : 0101101


位翻转是真实存在的!

我热爱这个 bug 是因为它证明了位翻转是真实存在的,而不只是理论概念。实际上,这种情况在一些领域中比其他领域更常见。从低端或老硬件的用户获得请求是其中一个,这是很多运行 Dropbox 的笔记本电脑的真实情况。另外一个有很多位翻转的领域是外层空间——太空没有大气层来保护内存免受高能粒子和辐射的影响,所以位翻转很常见。

在太空中,你可能真的非常关心数据的正确性。比如,你的代码可能用于让国际空间站中的宇航员生存下去,即使不是这样的关键任务,在太空中进行软件更新是很难的。如果真的需要应用程序不存在位翻转 ,可以采取多种硬件和软件方法。对于这个问题,Katie Betchold 有一个 非常有趣的演讲

Dropbox 不需要处理位翻转 。损坏内存的电脑是用户的,我们可以检测到逗号是否发生了位翻转,但如果它是不同的字符,我们不一定会知道,如果位翻转发生在磁盘读取的实际文件中,我们就不知道了。我们可以发现这个问题的空间太有限了,因此我们决定不对异常进行处理并继续。这类 bug 通常可以通过客户端重启电脑解决。

不容易发生的 bug 并不是不可能的

这是它成为我最喜欢的 bug 的原因之一。它可以提醒我们 unlikely 和 impossible 的区别。在足够的规模下, unlikely 事件以明显的速率发生。

通用 bug

我最喜欢这个错误的第二个原因在于通用。这个 bug 可能发生在桌面客户端与 server 通信的任何位置,系统中有很多不同的端点和组件。这意味着 Dropbox 的许多工程师将会看到这个 bug 的不同版本。当你第一次看到它时,真的非常伤脑筋,但是之后很容易诊断,而且检查非常快:只需要看看中间的字符是不是 l

文化差异

这个 bug 的一个有趣的副作用是它暴露了服务器团队和客户端团队的文化差异。有时候服务器小组的成员会发现这个 bug 并进行调查。如果一台服务器正在翻转位,这可能不是偶然的现象 – 很可能是内存损坏,你需要找到受影响的机器并尽快将其从服务器池中移出,否则可能会损坏大量的用户数据。这是一个事件,你需要快速回应。但是,如果用户的机器正在损坏数据,那么可以做的事情就不多了。

分享你的 Bug

所以,如果你正在研究一个令人困惑的 bug ,特别是大系统中的一个 bug ,不要忘了与别人交流。也许你的同事之前看到过一个这样 bug 。如果他们看到过,可以节省很多时间。如果他们不知道,记得告诉别人解决问题的方法 – 写下来或在团队会议上讲出来。下一次你们的队伍有类似的事情发生时,你们会更有准备。

Bug 如何帮助我们学习

Recurse Center

加入 Dropbox 之前,我在 Recurse Center (RC) 工作。RC 是一个社区,它的的理念是帮助具备自我导向的学习者通过协作共同成长为更好的程序员。这是 RC 的全部:这里没有任何课程、作业或者截止日期。唯一的课题是分享变为更好的程序员的目标。我们看到很多获得 CS 学位但是对实际编程没有把握的人参加这个项目,或者写了十年 Java 又想学习 Clojure 或者 Haskell 的人参加这个项目,当然还有很多其他的参与者。

我的工作是推进者,工作职责是帮助用户填补缺乏的结构和根据从以前的参与者身上学到的东西提供指导。所以我和我的同事对于帮助自我激励的成年人学习最好的技术非常感兴趣。

刻意练习

这个领域有很多不同的研究,我认为最有趣的一项研究是刻意练习的思想。刻意练习试图解释专家与业余爱好者的差别。这里的指导原则是,如果你只关注与生俱来的特征-遗传或其他-它们不会对解释差异做出太大贡献。因此研究人员(开始是 Ericsson , Krampe 和 Tesch-Romer )开始研究是什么造成了这些差异。他们的结论是花费在刻意练习上的时间。







请到「今天看啥」查看全文