以前经常有人问我,要怎么样才可以去微软。其实我从来没有想过这个问题,所以那个时候的答案自然就是微软的广告(编程好,数学好,态度好)了。09 年大四那会儿,刚好碰上了美帝的次贷危机,令我们这些想去美帝的公司被剥削的这帮人倍感艰辛。所幸后来还是过五关斩六将,最后在实习结束之后成功留了下来。这其中的因果,显然不是面试的那几天所能够决定的,因此还得从 hello world 讲起。
这是我第一个行数过万的程序。为了顺利完成它,我悟到了很多道理,包括为什么要面向对象,为什么要划分模块减少互相依赖。这也成为我后来开发自绘图形界面和脚本引擎的契机。后来我试图用 OpenGL 做 3D 游戏,但是由于很难找到有共同爱好的美工跟我一起做,便作罢了。但是这却让我获得了很多时间,可以投入到图形界面和脚本引擎之中去。
提交了毕业设计之后,我又在毕业前的几个月时间里面完成了 CMinus。这不是编译原理课程设计上的那个简单到没法再简单的 CMinus,而是一个完整的 C 语言编译器(其中函数指针的语法被我改掉了,但是仍然支持)。其编译结果是保存到内存中的一段 X86 二进制代码,可以将函数的起始地址强制转换成函数指针直接在 C++ 程序中使用,这是因为我在生成指令的时候遵守了 Visual C++ 中的一些在 MSDN 里描述得很清楚的约定。
值得一提的是,我从大三开始指导一名基础几乎是零的、比我低两个年级的软件学院的一位学生学习编程。为了让对方在接受我为期 3 年的训练之后有扎实的 C++ 基础、熟练的单元测试编写水平以及能够靠直觉给出一些不算太差的设计,我回顾了许多关于 C++ 的内容,特别是给指针的几节课备课了好几天,并且每一天都要出一个作业。在这个过程中我深刻的感觉到,如果要快速提高自己的编程水平的话,你必须总是去做一些你做得出来,但是难度大到只要再难一点点你就做不出来的事情。再这么坚持好些年之后,肯定会进入高手的行列。
后来我因为一些原因申请了到微软亚洲研究院(MSRA)的人事调动。2011年1月份我在获得了经理的批准之后,从上海前往北京参加研究院的面试。这一次面试仍然有五轮。这次面试很难,其中一个面试官因为在我的简历上发现了很多跟编译器有关的东西之后,决定让我实现一个 strncpy 函数,要求是 CPU 对内存的访问次数要最少。这包含了很多诸如带宽、对齐和二进制字节位移操作等各种问题。方法本身就已经很繁琐,再加上纸上写代码总是免不了要犯错误,所以我依然没有时间把整个程序写完。另一个面试官老外在年轻的时候也做过一些编译器的事情,让我出乎意料的是他在面试的过程中没有跟我出题目,反而就编译器的各种算法和问题聊了整整一个小时,基本上我会的知识全部都因为要回答问题而说了出来。之后我跟这个人产生了深厚的友谊。
GacUI 最后还复习了之前学过的编译原理的内容。因为 GacUI 在编译 XML 的过程中,实际上是把所有的东西都翻译成了一个脚本引擎的字节码,最后要么直接运行这个脚本,要么把脚本翻译成 C++(正在开发)。因此为了实现这一点,写一个编译器在所难免,而且编译出来的东西还要能跟 C++ 那边的类相互沟通,从而又复习了一遍 COM 的内容(尽管我并没有使用它,我只是尝试做了一个一样的东西)。
等 C++ 生成搞定之后,我就要继续写去年就开始的 GacJS了,把 GacUI 搬上浏览器,全方位运行我的 IDE。适合使用 C++ 的那些领域真是博大精深啊。
在这里不得不提到微软照顾员工真是无微不至,不仅帮我提供优质的搬家服务,在我到了美帝之后还给我安排了一位大妈,负责帮我融入现代社会。还说如果我觉得自己牛逼不需要这些东西,就给我两万刀。这些就算在谷歌,也只有被公司强行安排到美帝(而不是员工自己想出国)的那些人才有。最重要的是,微软员工买 BMW 还能打折,真开心。