谷歌编程之夏

05 May 2020 | thoughts, GSoC

大一上学期的微积分(一)课程,我选上了陈锦辉老师的课程班,陈老师授课认真,唯独喜欢用粉笔板书且字迹不深,这导致上他的课需要早起“抢座位”才能坐在看得清他板书的前排。因为懒,我在抢到几次前排后就开始呆在后排,时间一长,自然也就不再听课。现在想起,如果当初好好听课,会打下更好的数学基础,有更好的 GPA,之后的日子也不会这么难过。事实上,在那个教学班,据我目测至少就出了两位数以上的国奖/唐奖,也许并不是巧合。

坐在后排的日子里,唯一能干的事情就是刷知乎,刚刚学习了一点 C 语言的我很想找一些能做且有意思的东西来快速提高自己的编程技术,偶然间发现了谷歌编程之夏(GSoC)的含金量高吗?这个问题,了解到了这个活动:谷歌举办,开源代码,还有薪酬,对于大一充满着谷歌崇拜、开源崇拜且渴望赚外快的我来说简直是正中红心。然而,我看到这个问题时,2017年的钟声就快敲响了,自然没有办法参加当年的 GSoC,自然心想着“下次一定”。不过这一定,就到了临近毕业。

错过

大一下的时候,用 C 语言写一个命令行迷宫对我来说已经足够有挑战了,当我想起 GSoC 2017 时都已经到了宣布被选上的学生的环节了。

大二下的GSoC 2018 可能是我三年最用心的一次,说是用心,其实是仔细看过了感兴趣的组织的 ideas,说是感兴趣,无非是在组织的 tags 上查看有没有 C/C++,最后筛下来感觉可能有希望的是 blender(渲染相关), appleseed(渲染相关), boost(基础设施),然而事实上我很大程度上高估了自己在图形学/C++上的水平,那些要复现的渲染算法我可能现在都还没弄懂,而我当时的 C++ 水平甚至连通过 boost 的测试环节(实现一个模版矩阵类)都够呛。恰逢 ASC2018 决赛与 GSoC 2018 的准备时间高度重叠,因此我也就没有准备并申请,不过最后打完比赛回到杭州,离 deadline 还差一天的时候,从 gg 那倒是转来一个来自 Red Hen Lab 的项目,mentor 居然是湖南师范大学的某位教授,项目做的是用 NLP 生成对联之类的,但我当时对 NLP 毫无兴趣/掌握,自然也就没有继续推进。

大三下的时候,课程内有好几个有意思的项目在写,再加上刚刚开始高强度的去实验室,也就没有心思认真参加 GSoC 了,不过自然还是花时间研究了一下这一年的 ideas,这个时候我刚好开始学 Rust,想找相关的项目练手,找来找去也只有 Tokio,而我对 web 相关的都不是很感兴趣,除此之外我看了看 OpenCV,有好几个我能做的,最后是因为编译原理课的影响,稍微看了看 LLVM,GCC 等,和前一年我的关注对象已经大不相同了。

准备

终于到了大四上学期,除了一周去一次的课程外就是待在实验室,真正做起 research 来很快就意识到它并没有知乎上推特上大家展现的那样“丝滑”,尤其是在已经“死掉”的领域里。没进度的时光是很多的,除了读论文我就频繁的逛 GitHub,正好最近的课程项目上用到了一个叫做 mypy 的类型检查器,自然就去看了看它的 GitHub 页面,首先很快我发现我在课程项目中对 mypy 的用法是错误的,因为 numpy 根本没有 type stubs 的支持,所以基本上我的代码中有 numpy 参与到的部分,即使写了(我臆想的)类型标注,也都被 mypy 忽视了。除此之外我在 mypy 的 issue tracker 上停留了很久,mypy 有很多 issue,但几乎每个都有 tag 和维护者的反馈,尤其是在标有”good first issue”的 issue 里,维护者提供了修复这个 issue 的思路。这对像我这样的潜在贡献者是非常友好的,和我之前看过的一些项目的 issue tracker 有很大的不同,OpenCV 的 issue tracker 混杂了很多诸如“如何使用这个函数”提问没有被及时关闭,bug issue 没有标注 tag,也少有能指导修复这些 bug 的思路,导致整个 issue tracker 信息密度很低,good first issue 要么年代久远要么就是没有成就感的修修文档。TensorFlow/PyTorch 的维护者反馈很快,但因为这都是大公司的主力项目,一般不会给社区开发者多少能下手的地方,good first issue 基本都是修文档。

没过几天,在又一次科研受阻无事可干的情况下,我想起 mypy 的 issue tracker,开始认真读起 good first issues 里的描述,很快我找到了一个我能着手解决的 issue。mypy 是一个类型检查器,而我对类型系统除了一些常识外几乎一无所知,好在维护者 Ivan Levkivskyi 把这个问题简化成了一个普通的编程问题,毫无任何复杂的类型系统牵涉其中,我也完全就是当写 leetcode 一样,旨在通过 mypy 提供的测试。这并不是我第一次在 GitHub 上提交 PR,但是是我第一次接受系统的 code review,我的初始 PR 大概不过四五十行,几乎每一段下都有 Ivan 给的 review,每段 review 都简洁准确的指出了问题,给出了修改的方向,于是在他的指导下,大概几个回合的修改下来,我顺利完成了这个 PR,但这并不是我被 merge 到 mypy master branch 里的第一个 commit,在 review 过程中,我完成了另外一个更简单的 PR,它成为了有纪念意义的初次 commit。

良好的 review 体验和能为一个当时有着 7000+ stars 的项目贡献文档以外的代码的成就感,促使着我在后来一段时间里,把实验室以外,看偶像以外的时间都花在了开源社区上。我给 mypy 贡献的 commit 越来越多,覆盖了项目的各个方面,也渐渐开始熟悉社区里的几个主要维护者(他们主要来自于 Dropbox 和一位 UCB 的本科生)。除了 mypy 以外,我还给 OpenCV, PyTorch, LLVM 都提交了 commit,虽然不像 mypy 那么频繁,但了解一下不同社区的文化总是好的,比如 OpenCV 的 CI 很难用,PyTorch 一次 CI 可以跑上一天多,LLVM 用的是 Bugzilla + Phabricator + GitHub 的组合,导致一个 bug 从提出到 commit 要走个相当长的流程。不过,有一点倒是相同的,那就是各个开源社区的人,虽然很忙,但总体都是友善且专业的,大家的 code review 以及 communication 的质量都是很高的。

申请

在给 mypy 提交了一定数量的 commit 后,GSoC 2020 在去年的12月11日宣布了,我有查过往届的 GSoC 组织列表,发现 mypy 无论是作为独立组织还是 Python 的从属组织都没有参加过 GSoC,于是便顺口在 Gitter 里提了一句问 mypy 有没有参加今年 GSoC 的想法,很快,Jukka(mypy 的原始作者,目前的 tech lead)回复我说 mypy 以前没参加过,但他会和核心成员提起这个想法。1月18日,一个名为 Generalize IR to make non-C backends possible 的 issue 被提出了,很快我就回复说这个可能是一个不错的 GSoC idea 且表达了自己想接下这个的想法。这两件小事,现在看来,有一种我在推动 mypy 入选以及提前自荐的感觉。随后,2月6日,Jukka 又提出了一个名为 Project ideas 的 issue,整理了许多要花上一点时间才能做完的项目,虽然此时他并没在 issue 里泄露任何和 GSoC 相关的东西,但我已经隐约感觉到这就是 GSoC 的 idea page 了。

2月21日,在和叶先生通宵打完 Hashcode,最终我们凭借一波封榜后的瞎搞把排名打上去了不少,高兴之余,发现 GSoC 的入选组织宣布了,从这里开始学生们的申请就正式开始了。我自然也去翻了翻感兴趣的组织,包括 blender, LLVM, OpenCV, Python, 起初我并没在 Python 的子组织里看到 mypy,还以为今年没有申请。当我第二次过这个列表的时候,在搜索框里输入 mypy 想试着再找一下,找到了被我漏掉的它,而之前那个 issue 正是 mypy 参与 GSoC 的 idea page。

宣布入选组织名单距离最终的 proposal deadline 还有一个多月的的时间,在这期间学生们要找到自己感兴趣的组织与 idea,开始和 mentor 讨论并且撰写 proposal。事实证明GSoC还是有很多的人感兴趣的,mypy 的 gitter 频道和前面提到的 issue 里一下涌入大量的人,以印度老哥为主,且都是”enthusiast, open-source lover and quick learner”。不过大部分人可能是和大一的我一样,只认语言不认工作内容,很多人看到 Python 就来了却发现这和他们天天 “import torch” 有着本质的区别。有一个为 numpy 提供类型支持的 idea,是所有 ideas 中最热门的,很多人自告奋勇想做这个并且表示自己有多年的 numpy 使用经验且精通数据科学,而当 Jukka 进一步介绍该 idea 要完成的任务后,关于这个 idea 的声音一下就小了。最有意思的当属大家在短暂的时间里想要成为项目的”Contributor”而做出的努力,例如这个 PR。事实上,我认为从入选组织名单宣布再开始准备,再开始熟悉感兴趣的组织并做贡献是远远来不及的,去年十一月偶然间开始的开源贡献,无意中为我争取了最宝贵的时间。

我个人比较感兴趣的 idea 是之前提到的 mypy 的 Generalize IR to make non-C backends possible 和 LLVM Clang static analyzer 的 Find null smart pointer dereferences with the Static Analyzer。对于后者,我给 mentor 写了邮件,他们给我提供了详尽的学习资源。然而,我直到3月中旬才开始正式思考这两个 idea 具体该怎么做,而当我刚刚学完 Clang static analyzer 的几个 talk 后,我发现邮件列表里有人抢先一步开始和 mentor 讨论具体的思路了,先来后到,他抢占了在 mentor 面前刷眼熟的先机,且我扫了一眼他的 proposal 感觉和我的也差不多,于是决定直接不申请 LLVM,专心做 mypy 去了。我按 Jukka 的要求,把我的个人信息(相关技能、课程、作品、感兴趣的 idea 等)发给了 mypy,随后我和 Jukka 还有 Sullivan(mypyc 的主要维护者)在 issue 里讨论了很多轮,最后我提交了一个初始版本的 PR,一边写这个 PR,我一边完成了我的 proposal 且分享给了他们俩。然而这个 PR 并不是很理想,有很多需要大改的地方,我们又讨论了很多轮后关掉了这个 PR。比起 gsoc-cn 群组里的各位大哥在申请时就已经提交了几乎做完的 demo 和长达十几页的 proposal,我既没有 demo,proposal 也仅有 4 页,就这么到了3月31日,我提交了最终的申请。

4月初,我收到 Jukka 的邮件,他和 Sullivan 约我进行面试,起初我看到标题还在想“又要刷 leetcode 了”,但信中说的很明白这是一次非正式的面试并要我不要有心理负担。我们来自三个不同的时区,最后约在了北京时间4月8日下午15点,那时是 Jukka 的早晨和 Sullivan 的午夜。这次面试应该是疫情期间我面的最糟糕的一次面试,主要是我意外的紧张,再加上 skype 唐突变卡,以及我还不是很习惯 Jukka 的英式口音,总而言之我应该说了不少中式口语,凭空造了不少单词。面试的确很非正式,我们聊了我的工作时间,大致计划,过去的一些经历,之后就是在讨论什么时候 meeting 以及应该如何正确的念出我的中文名字。面试的最后,Jukka 对我说”We have dozens of applicants but you are the strongest and you shall receive the acceptance in a few days”。4月10日,我收到一封名为”Acceptance to mypy GSoC”的邮件,成为了 mypy 史上第一个 GSoC 学生。

之后就是等待 Google 的官方通知了。终于,在今天,5月5日的凌晨两点,Google 宣布了入选的学生和对应的 projects,我打开 mypy 页面,看到一个名字,我的名字。初次入选 GSoC 的组织,一般不会有特别多的名额,1-2个是比较常见的。这样,我的 GSoC 申请告一段落,总结下来就是要想入选 GSoC,最理想的就是提前为会入选 GSoC 的开源组织做贡献,去年11月偶遇 mypy 并开始为其提交 commit,为我今年的 GSoC 申请加分巨大。接下来的环节是 community bonding 和 coding,那么,我们七月初第一次审核时再见吧。


Older · View Archive (26)

最近长期呆在家里,作息紊乱,经常一天睡好几次觉,长度不一,也许受这种不规律的作息影响,做的梦也奇怪而有意思了起来,感觉从来没有体验过这么奇怪的梦境了,因此稍作记录。

Newer

推歌·漫谈

杂谈与突然想推荐的歌曲。