近几年我在职场踩过的坑

正如大家所知,我最近换了一个组。回顾过去几年,被坑的时候实在不少。从中我意识到了一些事情,故用这篇文章记录一下,也算再给自己的想法做个 snapshot。文章的三部分别讲项目、老板以及组的坑。最后再聊聊换组。

这里的“坑”不单指外界的坑,也包括自己犯过的错误。本文的适用范围还请读者自行判断,毕竟大到公司,小到组和部门,它们的差别都极大。你觉得和你遇到的情况不符,请不要杠,这没意义。虽然这么说,我觉得大部分内容还是通用的。另,有些英文说法没有翻译,但都不难理解。

项目的坑

当需求不是直接来源于用户时一定要谨慎

我转组的原因之一是 2020 年做的大项目失败了。项目实现了规划的功能,架构也清晰合理,但没有达到预期的 impact,而我原本是指望用它来到 L5 的。为什么会这样呢?归根到底,这个项目并非来源于客户的直接需求,而是老板拍脑袋想出来的。我的(前)老板某一次和其它几个老板聊天,发现其它组都有一个工具。他觉得这玩意我们大部门也挺需要的,那就找人做吧。不是说它完全没用,毕竟我们最终还是找到了两个客户,但我们很想推的组没推动,并且未来大概也不会有更多用户。后来我才知道老板先问了我的 TL (Tech Lead),TL 没有接,然后才找的我。TL 依靠丰富的经验避开了这个坑,但我就没那么好运气了。结论:需求不是直接来源于用户是一个巨大的危险信号。

内部 2c 项目(大概率)好于 2b 项目

这里仅讨论内部工具项目,不适用于面向外部用户的产品。几年下来我有一个很直接的观察,成功的内部工具基本都是 2c,很少有 2b 的。可能有人会好奇,内部工具也有 2b2c 之说吗?有个很简单判断方法:一个工具或系统,如果工程师能自己用起来,那就是 2c;如果需要部门里 >1 人讨论并决定,那就是 2b。举两个例子:一个开箱即用的任务监控面板是 2c 的,而一个需要修改 release 流程才能使用的工具就是 2b 的。当然,我观察到的样本很少,所以结论未必对。但我真心感觉 2b 的东西想推动,要花费几倍于 2c 工具的时间,效果还未必好。总之如果你有的选,请尽量把时间花在 2c 项目上。

警惕那些依赖其它组的项目

OKOK 我明白,世界上就没几个不需要跨部门合作的项目。但合作方式也是多种多样的。假如对方是你的客户,你需要和他们沟通来实现一个需求,又或者大家同属一个大组做同一个产品,这种就没问题。而当对方在你的关键路径上——比如你想做的东西没有对方配合就完不成,且你们又是跨部门,这种就有很大风险。如果你正在参与此类项目,请一定确保:

  • 双方(或多方)要 aligned(阿里话的“对齐”),尤其是老板之间。包括对项目的预期、优先级、工期、资源投入,都必须互相知晓并认可,而且要落实到 OKR 层面。不要相信工程师的口头承诺,我被坑过,而且很惨。
  • 要有定期例会。
  • Escalate(上升)的渠道一定要通畅。当对方没有按期交付或出现各种问题时,你要能通过自己老板向对方施压。这也是为什么双方老板的支持是必需的。

了解组里其它人在做什么

除了上面提到的那个项目,其实我曾有更好的机会升 5。我们组有个项目,本来由两个人分别负责前后端,结果后端哥们儿写一半离职了。后端是用 C++ 实现的,而我当时是组里唯一有 C++ readability 的人,如果申请接手,老板 100% 会同意。然而我当时埋头于自己的任务,完全不关注组里其它人在做什么(即使我一直帮他们 review 代码)。因为不了解,也没有意识到这个项目的潜力。后来这个项目交由前端哥们儿负责,并且成了组里的重点项目。我就这么错失了好机会。说白了这又是“选择大于努力”的例证。

于是我决定,进新组之后至少和每个人 1:1 一次,即使他们的工作看起来和你毫无关联。同时关注各种新提案和设计文档,了解其它人在做什么。除了寻找可能的机会,这也有助于站在更高视角全面理解当前的工作。

不要对项目产生感情

我当初之所以选择换到现在的组,主要是因为(前)老板答应我可以继续之前的工作——一个我很喜欢并认为有很大潜力的项目。时至今日,这个项目完全兑现了潜力,然而我却因此耽误了两年。如果当时抛弃对项目的感情,我完全可以找个更合适的组。转组的事之后会细聊。

老板的坑

之前和 Phil 做过一期节目聊了这个话题,不过我们遇到的情况不尽相同,感兴趣的可以去听一下。我只说我遇到的情况。

不要盲目相信老板

我的三任老板都有过很离谱的判断:

  • 第一任老板认为写什么语言都不影响换组(我一开始写 Dart。。。)。然而事实就是换组非常看背景。很多组明面上说可以进去再学,实际上都希望申请者会写特定的语言(等着进去再学的人根本拿不到面试:)。
  • 第二任老板极度厌恶 C++ 并热爱 Java。他要求我把一个 C++ 服务用 Java 重写。这明显是个费力不讨好的活,但又不能不干,于是我和老板说服了另一个人去写。结果如我所料,他花了时间却没拿到任何 impact(真对不起他)。
  • 现任老板比较短视。他上任后大刀阔斧地砍项目(交给别的组维护),理由是我们要 focus 在几个重点项目上。很多成功或有潜力的项目都上了被砍名单。问题是 EngProd 组的活本来就少,被这么一砍,不少人拿不到足够有 impact 的项目,只能做些小 feature。去年离职了好几个,今年目测还要跑一波。

所以我认为,老板的话要听,但决策一定要自己做(或者说,做自己认可的决策)。这里面有个更本质的原因。自己做决策,即使错了,也可以复盘反思,并取得进步。而让他人做决定,自己将很难进步——对不知道对在哪,错也不知道错在哪。

警惕只想把你当工具人的老板

我换组的另一个原因是发现老板有把我当工具人的倾向。在 Google,好的老板要能平衡组与组员的利益,既保证组的发展,又确保个人能够成长(说白了就是晋升)。前两任老板虽说都给过我坑项目,但至少他们会和你聊个人发展并给出建议。这些我都看在眼里。现老板去年还是工程师,在前老板走后被提拔上来。一开始的感觉是他不太关注我的项目,即不了解也不想去了解。今年 Q1 快结束时,事情开始变糟。如之前所说,老板开始砍项目,并把我调往那个我曾经错过的项目。本以为老板打算让我从现在开始 own 它,然而并不是。老板的意思是让我 Q2 去实现一个比较重要的功能,后续安排再议。从我知道的情况看,这个项目中很有 impact 的一块已经被分给了一个即将到来的 intern——是的你没听错,intern。我问老板:明明这个 feature L3 工程师就能做(简单的 CRUD),并且对他们晋升帮助很大,为什么让我来?老板说你擅长这块,你来做比较快。话说到这份上,继续聊下去已经没太大意义了。

怎么判断老板有没有把你当工具人?我觉得有这么两点:

  • 看老板给不给你做职业规划。好的老板会说:我觉得你想晋升,impact/difficulty/leadership 还不够,做XXX任务可能对你有帮助,或者我们一起想想能做什么。把你当工具人的老板不会给你规划。

  • 看老板对你是否诚实。我曾对现老板说:仅仅加这个功能基本上就是 L3 的活,感觉对我晋升没有帮助。老板说不要紧,只要你做得快,拿 SEE(类比 3.75)是没问题的。在我看来这就是典型的不诚实,或者职场 PUA 话术。你再资深,该花的时间还是得花,收集需求、设计、实现、测试,这其中有的时间是你无法控制的。资深工程师无非是做出来的东西稳定一些,考虑更周全,bug 更少,并不是一定就能做得更快——因为最快的方法永远是糙快猛。

    如果是前老板,我觉得他会说:“虽然没法让你到 5,但我们有客户急需这个功能。我们可以规划一下之后的安排,比如让你顺势 own 这个项目,或者找一个更好的项目”。诚实是最重要的。不要骗我们,我们不傻。

当然,现老板也和我聊过晋升。他说如果我想晋升就得自己想一个好项目。于是我想了一个 impact 很大的,写了提案给相关组审阅,他们很满意。然后老板说我们不做这个,要 focus。我:???

组的坑

组的坑既是最好聊的又是最不好聊的。相对来说,组的坑比较明确,容易提前识别。但另一方面,组的坑多种多样,且和老板和项目都有关联,难以穷尽。所以这里只说说我知道的那些。

业务/技术/个人兴趣,至少要占一项

有的组业务有前途,有的组技术有挑战,有的组两边都有,有的组两边都没有。两边都没有的基本就是坑,这种组在大公司相当多,比如 Google 的 EngProd。当然,如果某个组做的东西就是你的兴趣所在,那就加入吧,这时候别的都没那么重要了。

Fake infra 和 True infra

EngProd 具体怎么坑,我以后或许会专门写篇文章讲,但最根本的一点在于他们负责的是 fake infra。EngProd 全称 Engineering Productivity(研发效能),现在的 title 虽然是 Software Engineer,但在 2019 年以前是 SETI(software engineer, tools and infrastructure)。有人一看到 "infrastructure" 这个词就被唬住了,以为做的是什么不得了的东西。然而 EngProd 虽不负责业务,做的东西却也跟 infra 不沾边,我称之为 "fake infra"。比如修改一下公司的集成测试框架给某个组用,帮某个组优化 presubmit/postsubmit time,减少 test flakiness,诸如此类的杂活是 EngProd 传统艺能。我理解公司设立这个职位的初衷就是把杂活分出去,让 SWE 们专注于开发。

True infra 和 fake infra 的区别是什么呢?我觉得 true infra 一定是有技术挑战的,且至少要服务于某个大部门(比如 Search/Ads/Cloud),而不是一个或几个组。那些大家耳熟能详的技术都是 true infra,比如 Spanner,F1,Flume,Bigtable 等。有意思的是,做 true infra 的组从来就不属于 EngProd,而 EngProd 也从来不负责 true infra。

不要去 scope 太小和前景莫测的组

记得第一任老板总是强调要了解 big picture,当时不懂,现在才发现说得真对。Scope 指一个组负责的工作或者产品有多大。比如前面说到的 true infra,他们的 scope 就是全公司,而 EngProd 组的 scope 则通常是一个部门(几十到一百人)。面向用户的产品更复杂一些。比如 Gmail 和 YouTube 虽然有几十亿人用,但某个组负责的小功能却未必。这时候你只能依靠经验去判断。很多时候我们看不清,这不要紧,但至少有一些坑是可以避开的,比如 messaging app。

我第一次换组的时候也犯过错误,为了能去搞 AR 花了很多时间学图形学,导致没怎么认真看其它组。现在想起来觉得自己真蠢:在 Google 做 AR 没前途不是明摆着的么?到今天为止都没有一款面向消费者的成功 AR 产品,更不要说在这方面投入不多的 Google 了。而且说白了我也不是真的有兴趣,只是觉得这个技术很酷而已。当时犯的错误,现在要用几倍时间来还。

换组心得

下面来聊聊换组。虽然和上一节相关,我还是决定单独拿出来说。很多公司不像 Google 有这么多换组机会,还可能面临老板不放人的情况。因此我不打算写换组的流程,而是把重点放到“选组”上,尽可能让内容通用一些。

关注具体的工作内容和大方向

只看产品选组还不够,具体的工作内容和大方向也很重要。比如一个明星产品组招人可能是为了是搞测试,而一个内容平台的年度 OKR 可能是加强审查。要了解一个组的方向,最简单的方法是去看它的年度 OKR。如果找不到,一定要和老板问清楚。

我遇到过这么一个组,他们有 hc 所以打算先招几个人,至于做什么等进去再分配。这也是一个危险信号。通常来说,一个职位的职责越明确,项目的风险和掉坑的概率就越小,也能让你做出更有根据的选择。

Impact 是否好兑现

我实在不知道 impact 怎么翻译比较好,“影响力”这个说法其实不准确,所以我就不翻了。Impact 是否好兑现,我们可以通过举例说明(注意,好兑现和“大小”是两码事):

  • 好兑现的:
    • 实现一个面向用户的新功能
    • 依赖的 API 要 deprecate 了,使用新 API 重构系统
    • 优化响应时间
    • 给覆盖率很低的项目写单元测试
  • 不好兑现的:
    • 做一套测试框架
    • 重构系统,但是功能不变
    • 优化调试或监控工具

好兑现的项目简单明了,只要做完了 impact 就实打实地在那,不需要费劲给人解释。不好兑现的则各有各的问题:

  • 做测试框架:做了并不代表有人用,没人用那 impact 就是 0。你得花心思推广。
  • 重构系统:你觉得老代码写得太烂了难以维护,所以要重构。问题在于证据呢?这时候你就必须得收集数据,比如证明在老代码下加一个功能平均需要三天,而重构以后只需要一天——假设你能拿到这么理想的数据。实际情况往往是拿不到,或者并没有显著差异。
  • 优化调试或监控工具:这里的困难还是在收集数据,你怎么证明改进后比改进前要好?并不是说证明不了,而是需要花心思。

优先选择 impact 好兑现的组。一般来说,做新东西比较好兑现。

和工程师聊天

和老板聊天往往容易浮于表面,或者大饼满天飞。找到组里的工程师,一般他们都会毫无保留地告诉你真实信息。我会问很多尖锐的问题,比如“你觉得组里有哪些缺点”,“晋升速度如何”等,还会详细了解工作的细节。有个工程师直接告诉我,如果你想晋升,就不要来我们组——老板们断然是不会这么说的。如果你觉得在职员工讲话会有顾虑,也可以找刚转出去的员工。实际聊下来我没发现有太大差别,只要是工程师都会如实说明情况。

什么时候该考虑转组?

这个问题没有标准答案。我现在倾向于认为只要满足条件(Google 的要求是待满一年),就可以开始关注新机会了。我们有个系统可以设置 filter,出现满足条件的内部转岗机会会自动给你发邮件。每周看一次邮件其实花不了几分钟,而且看机会并不意味着一定就要走。别看每天都有很多组在招人,实际上单看某一个组,招人的窗口都只占一年中的很小一段,甚至有的组几年都不招。很多机会错过就是错过了。

有种情况我会建议你立马开始看机会:人事变动。不论是老板离职还是组织架构调整,只要是人事变动,多多少少一定会影响工作。影响可能好可能坏,可能多可能少,你无法预测,所以最好未雨绸缪。尤其如果老板给你提供了很多支持,甚至本身就是项目的发起者,当他离职之后你的工作必然受到冲击。事情变坏往往就是一瞬间的事,如果没有准备可能会措手不及。当然这里还是要强调,看机会不等于一定要换组,只是给自己准备一条后路。如果一切照常甚至变好,那完全没有换组的必要。

总结

相信你现在也感受到了我这几年是怎么被坑过来的。我当然希望一切都一帆风顺,但既然事情已经发生,也必须总结一下引以为戒。祝大家职场之路顺利。

PyCascades 2021 参会总结

关于这篇文章到底用中文还是英文写,其实我犹豫了一会,但最终还是决定用中文,毕竟也没人会写一篇关于 PyCascades 的中文文章了。

首先,PyCascades 是什么?用官网的话说:

PyCascades is a regional PyCon in the Pacific Northwest, celebrating the west coast Python developer and user community. Our organizing team includes members of the Vancouver, Seattle, and Portland Python user groups.

简单来说 PyCascades 就是一个区域性的 PyCon。但由于许多 Python 大佬聚居于此,其影响力比其它区域性 PyCon 大很多。

我在 PyCascades 2021 给了一个演讲 “Let’s Rethink Debugging”:

下面就聊聊我从申请到参加 PyCascades 的经历。

申请

去年(2020)十月,PyCascades 官推宣布了 2021 年会议将在线上举办。当时 Cyberbrain 的第一个小版本已经接近完成,我正想找个地方宣传,于是就锁定了 PyCascades。彼时我只知道 PyCascades 有着不错的影响力,而对整个申请流程毫无概念。然后就发现想要演讲,得先提交一个 proposal。和 PyCon China 不同,PyCascades 有着严格的筛选机制。你得提交一个描述演讲内容的 proposal 给组委会审核,择优录取,所以并非报名了就能去讲。根据这份 slide 里提到的数据,PyCascades 2018 和 2019 年的演讲接收率(acceptance rate)都不超过 10%,可见筛选之严苛。

我从来没写过 proposal,完全不知道要怎么下手。好在官方提供了一些参考资料,我就把它们看了一遍。其中值得一提的是这个 repo,里面收集了过往被接受和拒绝的一些 PyCon proposals,很有参考价值。由于 19 年在 PyCon China 讲过,演讲的前半部分我基本直接照搬,力气主要花在写后半部分 Cyberbrain 的原理介绍和展望。10 月下旬,我花四个晚上完成了 proposal 的初稿,接着就开始找人审阅。

找谁呢?我想起之前看过的那些资料。既然作者有心教人写 proposal,那么应该也会愿意帮忙审阅吧。于是我就给两位作者同时也是圈内大佬 Allison KapturBrandon Rhodes 发了邮件。说来也巧,我在调研 Cyberbrain 时仔细阅读了 Allison 写的那篇 A Python Interpreter Written in Python,实现过程中也一直在参考文中提到的 byterun 项目,可以说渊源颇深。邮件发出后好多天也不见回信。我不想傻等,于是就推特私信了 PyCascades 的组织者 Nina。Nina 在一直是 Python 圈的活跃分子,以前也做过关于 debugging 的演讲,我觉得找她还挺合适的。很快有了回信:

This year I'm co-organized for PyCascades, so I currently have my hands full. Fortunately we have a team of volunteers that are providing speaker mentorship for the conference.

Would it be OK if I introduced you to one of our speaker mentors? If yes, just let me know which e-mail address is best for you.

我惊了,原来还有志愿者吗?那还用说,当然是赶快给我安排一个。于是,同为 Googler 的 Chris Wilcox 就成了我的 mentor。几乎是同时,Allison 和 Brandon 也回信了。于是接下来直到提交截止日期我几乎一直在改 proposal,成品就是上一篇文章中的那样。以后有空我可以专门聊聊怎么写 proposal,今天先略过了。

会前准备

Proposal 幸运地被接收了。感情上,我终于放下心来,然而理智上我从来就不觉得会被据——要是这都被拒了,被接收的那些不得上天?毕竟我也不是没看往届演讲。

于是就开始写 slide。我报名的是 recorded talk,也就是要提前录好。二月份提交才截止,理论上不用着急,但我想先试讲一次。我迅速搞定 slide,并联系了本地 Python meetup 的组织者,在 1 月 5 号晚上做了一次远程演讲。虽说只有二十多人参加,但反响还不错,这让我基本确信了这会是一个好的演讲。

到这步还不能直接录制,组委会要审核 slide 是否符合 Code of Conduct,并做一个 tech check。Tech check 委托了 Next Day Video(一个专业做会议视频的公司)进行,目的是为了确保讲师能够录制出效果足够好的视频。我先通过他们的系统预约,然后顺利进行并通过了 tech check。过程中,Next Day Video 的人还教了我怎么正确使用麦克风——原来我之前一直都摆错了方向导致无法获得最佳音效。果然这就是专业人士吗🤯。然后就是一些邮件+notion文档(1, 2, 3),里面说明了参会和录制的各种要求,详细到视频的 bit rate 和 frame rate 都有规定。里面还推荐了一些录制用的软件。我最后采用的是 Apowersoft Free Online Screen Recorder。CoC review 通过之后,终于可以录制了。

算上 PyCon China 2020 的闪电演讲,这还只是我第二次录视频。我发现,录视频比现场演讲累太多了。可能有人会觉得,现场演讲多紧张啊要面对那么多观众,提前录的话讲坏了大不了重录或者剪辑嘛。但这也正是录视频累人的地方

  • 没有现场观众,你无法得到肾上腺素或者其它什么激素的刺激,而这些刺激能极大缓解疲劳。
  • 你不太会在意现场演讲中的口误、结巴等不完美的地方,因为你在面对别人讲话,而讲话时自然不会在意这些。
  • 提前录制则不同,首先你是自说自话,会对各种错误非常敏感。其次你有重录的机会,导致容易吹毛求疵。

反正我第一次试着完整录,25 分钟,讲完就不行了。那天剩下的时间我几乎没办法干任何事,感觉整个人都被榨干了。自然效果也非常差,后半段可以明显感觉到讲师很疲惫。于是接下来的几天继续录,不算中途就抛弃掉的,大概第三遍的时候我觉得差不多了。我把视频传给了 Next Day Video,几天之后被告知没有问题。接下来就一身轻松等待会议开幕了。

Day 1

主办方在周五安排了一个线上的 social 活动,使用的平台是 SptialChat。这个产品还挺有意思的。进去之后有一个类似剧场的空间,你可以在空间中拖动自己的头像,模拟在物理空间中走动的感觉。当你把头像移到一群人旁边就可以听到他们讲话,并且距离越近听得越清晰。一开始我只是听,后来 Anthony Shaw 过来和我打招呼,我也就顺势混入那一群人瞎聊起来。我说我感觉录视频好累,Anthony 和另一个讲师说他们也发现录视频会让自己要求变高,到最后受不了只能把讲稿完全写下来。

主办方还找了个 DJ 在台上打碟。打碟的大叔全程也不和人交流,感觉很沉醉其中。

Day 2

周六是正式会议,九点半开场。然而我七点就起床看了场球,还输了。郁闷了一阵想起来还要开会,点进去发现 Guido、Brett 等几位大佬已经开始聊天了。随后一直听,并反复在 recorded talk 和 live talk 之间切换,因为 PyCascades 的两个 track 是同时进行的。值得一看的演讲是 Your Name Is Invalid!,大概就是讲处理各种语言文本时各种可能出的问题,比如有的语言中大小写字母不是一一对应的。最后的结论是 "Don't assume anything"。这让我想起以前看过的讲时区处理的视频,想用代码囊括复杂多样的世界,何其难也。

会议之前若干周,主办方在 Slack 上开了几个私密频道给讲师,当作后台使用。会议当天,Next Day Video 的人会在后台联系讲师做 tech check——是的,为了确保万无一失,当天还有 tech check。我的演讲在下午 1:55,大概 1 点做 tech check。工作人员说声音没问题,但让我把后面的百叶窗拉上一点不让太亮了,并且还问能不能把摄像头放低一点。这里要解释一下,我用的是一个台式机连接大显示器,摄像头是放在显示器上面的,这样就造成了一种俯视的感觉。为了解决视角问题,我只能找两个纸巾盒子摞起来,把摄像头放在上面,这样勉强和我的头平齐。我还挺好奇其它人都是怎么做的。

临近演讲时间,我登入 Next Day Video 的讲师专用后台。和主持人对了一次词,包括要怎么称呼和介绍我。这次会议我统一跟人说叫我"laike"了,毕竟称呼不重要。我之前以为开场介绍过后就可以退出,没想到还得一直待在后台。我只能找了一台笔记本打开听自己的演讲。他们强调说视频的播放有一段时间的延迟,但是我听着听着就忘了。临近结尾,我看到 slack 上有消息,是主持人让我马上过来说结束语。也就是说,我需要在视频没结束的时候就去讲,因为有延迟,观众看到的就是视频一结束,我和主持人马上出镜。我手忙脚乱地坐回屏幕前,调整摄像头,讲了一句话才发现自己处于 mute 状态,又赶紧 unmute。这状况频出的直播大概会成为未来的美好回忆吧。

后台状况不提,演讲效果还是不错的。听众不出意外地被 Cyberbrain demo 震住,当然这也在意料之中。我边听边打字回答听众问题,十分愉快。

有一些听众希望在 console 和 notebook 里使用。我只能说,希望未来可以实现吧。最令我高兴的还是看到 Łukasz 说他被 sold 了,虽然他后来也没有去 star 😢

之后就是在 Q & A 房间继续回答问题。有人问这个项目和 Google 有没有关系,我就非常想笑,怎么可能有关系啊。还有人问能否用 Cyberbrain profile 慢代码,我也只能承认不行。不管问题如何,能有机会和听众聊 Cyberbrain 就足够让我开心了。

Day 3

Day 3 是 sprints,我没参加只是去看了一眼,感觉线上做 sprints 还是有点奇怪。以后线下一定要参加一回。

大概就是这样。全程下来要问我哪一点印象最深,不是具体的 talk,也不是自己的第一次英文演讲,而是主办方那惊人的专业性。会前会中已经讲过,但这种专业性甚至延续到了会后。当他们把演讲视频上传到了 YouTube,我发现我在视频里有露脸。别不在意这个,但我并不想。正当我烦恼要怎么联系主办方解释自己的苦衷,甚至已经开始在脑中构思措辞时,我接到了一封邮件。这是一封确认视频有没有问题的邮件。我喜出望外,便在回复里说明了需求。于是他们迅速撤下视频,两天后剪辑完成又重新发布。这种受尊重的感觉实在太好了。我愿称 PyCascades 是我参与过的最专业的技术大会。

Let’s Rethink Debugging

本文是我在 PyCascades 2021演讲的 proposal。虽说是 proposal,却是以接近博文的风格写作的(毕竟我只会这种风格。。),所以就直接放出来水一篇了。对应的 slide 在这里。下一篇文章我会聊聊参加 PyCascades 的经历。

This is my talk proposal for PyCascades 2021. Even though it's a proposal, it reads very much like an article, so I just post it here.

Abstract

As programmers, we do debugging almost every day. What are the major options for debugging, what advantages and disadvantages do they have? We'll start the talk by giving the audience an overview of the history of debugging and existing tools so they know how to pick from them.

Then, we'll help the audience gain a deeper understanding of what debugging is really about, and talk about two pain points with existing solutions. We'll introduce a novel approach to solve these pain points, with basic introduction to bytecode tracing so the audience can learn this useful technique.

Finally, we'll look into the future and talk about why it's important to be more innovative. We hope that by listening to this talk, the audience can be more open-minded thinking about debugging, and programming as a whole.

No specific knowledge required, but basic experience with debugging would be helpful.

Description

Here is a detailed description of each part.

Part 1: What debugging is really about?

Broadly speaking, a Python program can have four types of errors:

  • Syntax Error
  • Exits abnormally (e.g. unhandled exceptions, killed by OS)
  • The program can run, but gives wrong results
  • Gives correct results, but consumes more resources than expected (e.g. memory leak)

Among which, the third type of error is the most common, and also where programmers spent most of their time debugging. In this talk we focus on this type of error, aka "A Program can run, but gives wrong results".

I'll let the audience recall how they usually do debugging. It's not hard to spot that, no matter what approach we take, we're trying to answer one question:

What is the root cause of the wrong value?

This sounds straightforward, but it is vital that we realize it before going into the later sections.

Part 2: Retrospect the history of debugging

In the early days of programming, debugging meant dumping data of the system or output devices - literally printing, or displaying some flashy lights if there's an error. A very patient programmer then would go step-by-step through the code, reading it to see where the problem may be.

Then, in the 70s and 80s, the idea of "debugging software" came along, and people started to build command-line debuggers like gbx and GDB. Since then, despite new features like breakpoint, reverse debugging and graphical interface were added, the way people use debuggers stays pretty much the same: step through the program and look around.

Today, print, logging, and debugger remain to be the major ways for debugging, each with its advantages and drawbacks:

  • print:
    • Advantages: available out-of-the-box, clean information, does not affect program execution.
    • Drawbacks: requires familiarity with code, needs tweaking repeatedly, lack of context, hard to manage output.
  • Logging:
    • Advantages: configurable, easy to manage output (e.g. Sentry), richer context (lineno, filename, etc).
    • Drawbacks: configuration is not easy, requires familiarity with code, hard to search what you need, context still not enough.
  • Debugger:
    • Advantages: powerful, does not require familiarity with code, richest context to help identify problems.
    • Drawbacks: not always available, decent learning curve, can't persist output, needs human interaction.

Yet, with all these options, debugging is still hard sometimes. We'll see why in the next section.

Part 3: Let's rethink debugging

There are two pain points with existing debugging solutions:

  • There is no tool that is as easy-to-use as a print, yet provides rich information like a debugger.

    Tool Effort required Information provided
    print low simple
    logging medium medium
    debugger high rich
    ? low rich
  • Existing tools only give clues, without telling why.

    This is a bigger (yet hidden) problem.

    In the first part we talked about the goal for debugging, which is finding out the root cause of the wrong value. Let's use debugger as an example to recall how we usually debug. Let's say you're debugging a program, where c has an unexpected value:

    c = a + b  # c should be "foo", but instead is "bar"
    

    Here are the normal steps:

    1. Set a break point at this line.
    2. Run the program, inspect the value of a and b.
    3. Figure out whether the error lies in a or b.
    4. Set another break point, repeat 🔁

    Or, if you want to do it in one run:

    1. Set a break point at the entry point of the program.
    2. Step through and program and remember everything happened along the way.
    3. Stop at c = a + b, use your brain to infer what happened.

    Either way, we still need to spend time reading the code and following the execution. We also need to keep monitoring all relevant variables in every step, compare them with the expected values, and memorize the results, because debuggers don't persist them. This is a huge overhead to our brain, and as a result made debugging less efficient and sometimes frustrating.

    The problem is obvious: debuggers only give clues, without telling why. We've been taking the manual work for granted for so long, that we don't even think it's a problem. In fact it is a problem, and it can be solved.

Part 4: A novel approach to tackle the pain points

To reiterate, An ideal debugging tool should

  • Easy-to-use and provide rich information.
  • Tell you why a variable has a wrong value with no or minimal human intervention.

For a moment, let's forget about the tools we use every day, just think about one question: who has the information we need for debugging?

The answer is: the Python interpreter.

So the question becomes, how do we pull relevant information out of the interpreter?

I will briefly introduce the sys.settrace API, and the opcode event introduced in Python 3.7, with the example of c = a + b to demonstrate using bytecode to trace the sources of a variable. In this case, the sources of c are a and b. With this power, reasoning the root cause of a wrong value becomes possible.

I will then introduce Cyberbrain, a debugger that takes advantage of the power of bytecode to solve the pain points with variable backtracing. What it means is that, besides viewing each variable's value at every step (which Cyberbrain also supports), users can "see" the sources of each variable change in a visualized way. In the previous example, Cyberbrain will tell you that it's a and b that caused c to change. It also traces the sources of a and b all the way up to the point where tracing begins.

I'll do a quick demo of using Cyberbrain to debug a program to show how it solves the two pain points. By the end of the demo, the audience will realize that traditional debugging tools do require a lot of manual effort which can be automated.

Bytecode tracing also has its problems, like it can make program slower and generate a huge amount of data for long running programs. But the important thing is that we realize the pain points, and don't stop looking for new possibilities, which brings the next topic.

Part 5: Where do we go from here?

Now is an interesting time.

On the one hand, existing tools are becoming calcified. Debug Adapter Protocol is gaining popularity, which defines the capabilities a debugger should provide. Tools that conform to DAP will never be able to provide capabilities beyond what the protocol specifies.

On the other hand, new tools are coming out in Python's debugging space, just to list a few:

  • PySnooper, IceCream, Hunter, pytrace: lets you trace function calls and variables with no effort, automating the process of adding print().
  • birdseye, Thonny: graphical debuggers that can visualize the values of expressions.
  • Python Tutor: web-based interactive program visualization, which also visualizes data structures.
  • Cyberbrain.

These new tools share the same goal of reducing programmers' work in debugging, but beyond that, they are both trying to pitch the idea to people that the current "standard" way of debugging is not good enough, that more things can be achieved with less manual effort. The ideas behind are even more important than the tools themselves.

Why is this important? Dijkstra has some famous words:

The tools we use have a profound (and devious!) influence on our thinking habits, and, therefore, on our thinking abilities.

Imagine a world where all these efforts don't exist, will the word "debugger" gradually change from "something that can help you debug" to "something that conforms to the Debug Adapter Protocol"? That is not impossible. We need to prevent it from becoming the truth, and preserve a possible future where programmers are debugging in an effortless and more efficient way. So what can we do?

  • Think of new ways to make debugging better;
  • Create tools, or contribute to them;
  • Spread this talk and the ideas;
  • Create new programming languages that put debuggability as the core feature.

And the easiest, yet hardest thing: keep an open mind.


top