作者简介:vczh,本名陈梓瀚,因知乎的个人信息介绍上写有“专业造轮子”,所以江湖人称“轮子哥”。vczh大学时代就在微软实习,毕业后即加入微软。开始时是在微软上海,后来进入北京的微软亚洲研究院。现已移居美国西雅图,在Office组做工程师。

以前经常有人问我,要怎么样才可以去微软。其实我从来没有想过这个问题,所以那个时候的答案自然就是微软的广告(编程好,数学好,态度好)了。09 年大四那会儿,刚好碰上了美帝的次贷危机,令我们这些想去美帝的公司被剥削的这帮人倍感艰辛。所幸后来还是过五关斩六将,最后在实习结束之后成功留了下来。这其中的因果,显然不是面试的那几天所能够决定的,因此还得从 hello world 讲起。

中学

我有幸从初二开始就学习编程。那个时候世界已经处于一个现代化的程度了,操作系统都有虚拟内存,有图形界面,有因特网,开发软件还有集成开发环境可用,跟一些老前辈所描述的编译一个程序还要换几次磁盘的日子已经完全不一样了。

那个时候正值购买电脑半年,处于看见什么东西都感到十分好奇的时候,再加上父亲那个时候不太同意我玩游戏,所以我就在想什么时候也自己做几个游戏,就可以光明正大地玩了。所以在听到汕头华侨中学开 Visual Basic 5.0 的课的时候,感到比较兴奋。但是其兴奋程度比起初一为了上第一节电脑课兴奋过度,骑自行车超速以至于流了一大堆血没了几颗牙的那一天,已经可以忽略了。

回顾我走过的编程之路

那个时候还是 21 世纪的第一年,正处于上网费用巨贵无比、Google 还刚起来没多久基本没人知道的时候,学习编程要比现在困难很多。当时想寻找什么知识,因特网基本上是没什么指望的,所以我就有了一个没事去书店的爱好。

没过多久我就找到了一本《Visual Studio高级图形程序设计教程》。这本书我很喜欢,插图十分漂亮,而且还是使用 Visual Basic 编程绘制的,更是爱不释手。可惜内容过于高深,所以后来就有了初三的时候自学学会初步的立体解析几何,以及高三上课不听讲仅凭自己看数学分析后来还被我看明白了的故事。

中间因为试图使用编程绘制很多复杂的图形和对图像进行各种复杂的变换,于是每当写程序之前都要在纸上推导长长的公式。如果程序的运行结果不对了,根本无从调试,只好重新推导,借以希望可以发现公式的几个 bug 以解释为什么会出现错误。

从此以后我对符号运算就十分拿手。而且做数学物理作业也好,为了编程推导公式也好,需要计算的东西太多懒得到处寻找废纸,从而便获得了心算复杂过程的本领(可惜现在已经丧失了)。这顺带还给我带来了一个好处,就是高考数学选择题在发卷后不许动笔的 10 分钟内就被我全部心算出答案,而且全对了。

回顾我学生时代走过的编程之路

图形编程做久了,就想起了当初的理想,于是就搞游戏去了。那会儿看到了成都金点工作组开发的《圣剑英雄传》,点燃了我开发 RPG 的热情。在经历了几次失败之后,我终于在高二的正月初一那一天完成了《天地传》的所有编码工作,没过多久就上传到了 GameRes 的网站上。

这是我第一个行数过万的程序。为了顺利完成它,我悟到了很多道理,包括为什么要面向对象,为什么要划分模块减少互相依赖。这也成为我后来开发自绘图形界面和脚本引擎的契机。后来我试图用 OpenGL 做 3D 游戏,但是由于很难找到有共同爱好的美工跟我一起做,便作罢了。但是这却让我获得了很多时间,可以投入到图形界面和脚本引擎之中去。

回顾我学生时代走过的编程之路

后来我就萌发了解释高级语言的想法。这是我整个编程历史上的第一个转折点。那个时候我数据结构只会用链表,而且编译原理也好,设计模式也好,都还没听过。那个时候去解释高级语言自然是比较困难的。因此我经过很多天的苦思冥想自己想出了一个如今称之为一遍编译(也就是很烂)的方法来把一个简单的高级语言重新处理成一个简单的指令集语言,就跟汇编长得差不多。

那个时候已经高三了,所以其实也没多少时间可以投入在编程上面,因此做出来的第一个原型是一个简化后的 Pascal 的解释器,用 Delphi 开发的。现在想起来,里面肯定有巨多内存泄露和性能问题,不过当时根本不知道这些东西是什么。在高中毕业之后的三个月无所事事的日子里,我就重新把这个东西设计了一遍,得到了一个几十页的计划。由于后来没来得及做完,就打印出来带去了华南理工大学。

大学

刚进了大学没几天,就听一个大四的师姐说我们的班主任陈健老师是教编译原理的,于是我就把这一叠纸拿给了她看。她什么也没说(现在回想起来,只能是那一份设计实在是不堪入目……),就给了我一本编译原理的课本。我很快就看完了,然后用了里面的知识做了第一个真正意义上的脚本引擎,语法山寨了 Java 语言的一些简单的部分,还添加了一个编译的时候自动把模板参数都改成 Object 类型的语法,起了个名字叫 JoveScript。后来上了 Java 的课,发现 Java 竟然真的这么干了,让我觉得好生奇怪。

后来我陆陆续续写了很多脚本引擎。大一的时候做的 JoveScript 是第一个我觉得还能见人的脚本引擎。第二个就是大二失败了一整年吸取了很多教训之后,于大三开发出的动态语言,名字叫 FreeScript(可以在我的博客 http://www.cppblog.com/vczh 上找到)。最近正在打算将其更新到 3.0 来配合一个正在开发中的显卡加速的 GUI 类库 GacUI。接下来就是在去微软上海的 WCF Tools 组实习的那一段时间里面,利用每天晚上的时间完成的一门纯函数式语言叫 KernelFP,这后来成为了我的毕业设计。

提交了毕业设计之后,我又在毕业前的几个月时间里面完成了 CMinus。这不是编译原理课程设计上的那个简单到没法再简单的 CMinus,而是一个完整的 C 语言编译器(其中函数指针的语法被我改掉了,但是仍然支持)。其编译结果是保存到内存中的一段 X86 二进制代码,可以将函数的起始地址强制转换成函数指针直接在 C++ 程序中使用,这是因为我在生成指令的时候遵守了 Visual C++ 中的一些在 MSDN 里描述得很清楚的约定。

毕业后我又雄心勃勃地做了 NativeX,是一个带泛型以及 concept mapping 的 C 语言。前几个月我又试图山寨 C#,但是无奈 C# 实在是太复杂,所以转而去做 GacUI。图形界面(GUI)类库我也写了不少。继高中的时候为 RPG 而开发的两个控件类库之后,在上大学的过程中使用 OpenGL 开发的两次 GUI 类库均告失败。后来还封装了一次 Windows 的 API(Vczh GUI),试图让其易用性接近 VCL 或 WinForm。

毕业后我又尝试发了若干次基于渲染的 GUI,换了几次架构,一直到现在正在开发的 GacUI 才感觉走上了正轨。我在这个过程中得到的一个结论就是:Windows Presentation Foundation 的设计实在是太完美了……在做这些东西之余,我还开发了三次三维物体的软件渲染程序,前两个是在毕业前做的,最后一个是一年前因为一下子不知道要如何利用业余时间来充实生活而开发出来的,目的是用于打发时间。

回顾我学生时代走过的编程之路

在这里我想可以回答一个月前不能很好地回答师弟师妹们的一个问题了。如何能够在微软找到工作?因为我把我上面做的这些东西都写进了简历。同时如果你们到了大四才来问这个,就已经太迟了……

值得一提的是,我从大三开始指导一名基础几乎是零的、比我低两个年级的软件学院的一位学生学习编程。为了让对方在接受我为期 3 年的训练之后有扎实的 C++ 基础、熟练的单元测试编写水平以及能够靠直觉给出一些不算太差的设计,我回顾了许多关于 C++ 的内容,特别是给指针的几节课备课了好几天,并且每一天都要出一个作业。在这个过程中我深刻的感觉到,如果要快速提高自己的编程水平的话,你必须总是去做一些你做得出来,但是难度大到只要再难一点点你就做不出来的事情。再这么坚持好些年之后,肯定会进入高手的行列。

因此我在安排作业的过程中,有意推迟了关于指针的内容。首先让对方接受变量和分支循环,然后要养成一个好的风格(譬如说不能老是用一个字母给变量命名之类),然后学会操作数组,接下来才是关于没有强制类型转换的指针的一些操作,并且在一个月之内做出一个带单元测试的字符串类。指针的重点是要对方深刻的理解,“指针本身就是一个指向位置的数字”这么一个概念。为此我特别设计(但没有实现)了一门只带有一个全局无限长数组的汇编语言来讲述指针背后一些复杂的概念。之后就是一些关于面向对象的知识、设计模式的知识、还有跟脚本引擎有关的一些东西。

该学生的毕业设计是一个简单的动态语言的脚本引擎,并且该脚本引擎的实现正确地运行了我在上面模仿 Linq 的一个列表处理函数库。这个实现闭包一层套一层,到处都在给一个物体添加删除函数,创建各种延迟执行的迭代器,很是能够考验一个脚本引擎的实现。对方毕业后被网易招去了,并且在待遇上给予了一些人文关怀。

回顾我学生时代走过的编程之路

自己的编程历程不仅包括自己在业余时间内做的这些程序,而且也包括在微软实习和工作的过程。高中的时候就听说了华南理工大学有微软俱乐部的事情,再加上自己对微软也持有一定的向往,因此在入学之后,除了学院的学生会以外,我就一直在密切关注着微软俱乐部的招新,并且忽略其它所有社团。不过说实话在学生会和微软俱乐部的工作也纯属打酱油,没干过什么正事儿。

大二的时候微软搜索技术中心(STC)来微软俱乐部收简历的时候,我在路上碰到了陈健老师,也就是之前提到的班主任,就跟她说了这个事情。后来由于对方说我年龄太小而作罢,因为其它人全部都是研究生。到了大三的时候,陈健老师就跟我提到她可以找老同学帮我投微软的实习简历,因此我于 2008 年 3 月份接到了微软上海的电话面试。电话面试有两次,第一次对方是一位 HR,第二次则是一位软件工程师。在第二次电话面试的过程中,我们聊了上面提到的 FreeScript,还针对一些数据结构和框架设计的问题进行了热情洋溢的讨论。没过几天,我就收到了面试通知,前往上海闵行区的紫竹数码信息港面试。那是我人生中的第一次面试。后来顺利通过,实习、转正、加入sql server组、跳槽最后去了Office。

回顾一下自己的编程之路,学生时期大概就是从一开始写游戏,到写游戏引擎,到专门搞游戏引擎需要的图形、GUI 库和脚本引擎,最终由于精力的关系剩下了 GUI 库和编译器。