首页 / 美文 / 正文

strncpy(看完知乎轮子哥的编程之路,我只想说,收下我的膝盖...)

放大字体  缩小字体 来源:莫奈尔 2026-04-15 13:33  浏览次数:8
看完知乎轮子哥的编程之路,我只想说,收下我的膝盖...nerror="javascript:errorimg.call(this);">

来源:轮子哥知乎

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

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

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

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

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

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

大学

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

看完知乎轮子哥的编程之路,我只想说,收下我的膝盖...nerror="javascript:errorimg.call(this);">

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

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

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

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

实习

这个小组有一位让我十分尊敬的软件开发主管葛子昂先生。葛先生是一位热爱敏捷并且经常投身于实践中的人。他在我长达 4.5 个月的实习过程中,教给了我很多软件工程上的东西,而其中最重要的、让我受益匪浅的则是关于单元测试的内容。

转正

实习生转全职员工的面试一共有五轮。其中令我印象非常深刻的是有一轮的面试官问了我很多非常复杂的问题,最后还考了我一道关于线索二叉树在线更新的问题,不过我已经记不清楚具体是什么内容了。我只记得我花了很长时间终于想到了一个正确的算法之后,时间就结束了,根本来不及在白板上写代码。后来我终于通过了面试,少数的几个名额里面终于被我拿走了一个。不过听说几个月后限制开始放宽,没有我面试的时候那么困难了。

Microsoft SQL Server

这一年半的经历让我成长了许多,主要是比起实习,正式工作的时候总是免不了经常要跟别的团队、公司、民族、国家和物种进行热情洋溢的广泛交流,而且还占用了不少的时间。有些时候还要坐飞机前往美帝,感受一下社会主义的优越性。正式软件的界面部分十分复杂,不仅要在操作系统的 DPI 变动以及本地化(大部分内容是把界面上的文字翻译成别的语言)的过程中界面的布局需要自动调整,以便不让一些文字或者按钮只显示一半,还要照顾各式各样的残疾人(特别是失去视力的人群),并且对于某些自绘的复杂内容还要提供一些运行时的接口,使得自动测试团队可以完成他们的工作。看完知乎轮子哥的编程之路,我只想说,收下我的膝盖...nerror="javascript:errorimg.call(this);">看完知乎轮子哥的编程之路,我只想说,收下我的膝盖...nerror="javascript:errorimg.call(this);">

微软的跟别的公司比起来罕有一个好处就是他会给你很多时间,让你慢慢把软件做好。而这个好的定义,当然是以功能和可维护性为重点。倘若一段代码以非常精妙的方法来高速完成一个任务,但是却复杂到哪怕写遍了注释也不能让后续维护的人看懂的话,那这段代码是没有实用价值的。一段好的代码,不在于它的设计有多么巧妙,不在于它的算法有多么高深,而在于它可以被几千个人同时开发 10 年,并且在持续添加功能的过程中,不会因为过于混乱而导致出现了重写的需要。

后来我因为一些原因申请了到微软亚洲研究院(MSRA)的人事调动。2011年1月份我在获得了经理的批准之后,从上海前往北京参加研究院的面试。这一次面试仍然有五轮。这次面试很难,其中一个面试官因为在我的简历上发现了很多跟编译器有关的东西之后,决定让我实现一个 strncpy 函数,要求是 CPU 对内存的访问次数要最少。这包含了很多诸如带宽、对齐和二进制字节位移操作等各种问题。方法本身就已经很繁琐,再加上纸上写代码总是免不了要犯错误,所以我依然没有时间把整个程序写完。另一个面试官老外在年轻的时候也做过一些编译器的事情,让我出乎意料的是他在面试的过程中没有跟我出题目,反而就编译器的各种算法和问题聊了整整一个小时,基本上我会的知识全部都因为要回答问题而说了出来。之后我跟这个人产生了深厚的友谊。

Microsoft Research Asia

在研究院的这几年,其实除了增长了一些技术上的见识,和学会了如何成为一个老油条以外,技术上主要的成长仍然来源于自己开发的 项目。研究院的结构是非常适合我这种喜欢把玩复杂(但不一定是新)技术程序员的。而且我在研究院的直属老板还是邹欣,让我深刻的明白了一位好的领导是多么的重要。

后来我干脆就想,要是整个都能用 C++ 来写多好啊。但是 C++ 的 GUI 库对 MVVM 的支持都是垃圾,于是就有了 GacUI。但是做一个 GUI 库工作量实在是有点大,我又追求要有良好的开发体验,因此就做了这么久。今年应该可以出 1.0 了……

GacUI 最后还复习了之前学过的编译原理的内容。因为 GacUI 在编译 XML 的过程中,实际上是把所有的东西都翻译成了一个脚本引擎的字节码,最后要么直接运行这个脚本,要么把脚本翻译成 C++(正在开发)。因此为了实现这一点,写一个编译器在所难免,而且编译出来的东西还要能跟 C++ 那边的类相互沟通,从而又复习了一遍 COM 的内容(尽管我并没有使用它,我只是尝试做了一个一样的东西)。

出国

看完知乎轮子哥的编程之路,我只想说,收下我的膝盖...nerror="javascript:errorimg.call(this);">

于是又过了一些年,由于我对北京(主要)和研究院(次要)的不慢逐渐增加,于是我赶紧弄了个老婆之后,就触过了。

找到你想要去的组

  • 看他是否因为经济危机或者收购案件什么的,正在裁员或者无法招人

  • 拿 offer(这是肯定的)

  • 这个过程让我不由得感叹,美帝的面试官就是没有见过世面啊。竞争压力太小了,搞出来的题目都超级容易,得让他们来中国呆一呆,面一面,不然美帝迟早药丸。不过我觉得另一个方面是,我给 Office 做跨平台 GUI 的那个组看了一下我做的 GacUI,估计他们觉得还不错吧,就随便面了一下我,这也是有可能的。

    虽然牛逼的人在中国和美帝拿的工资并没有太大差距,但是撇去美帝的IT地区跟北上广相似的房价以外,美帝除了汽车和电器的其他东西贵得一逼啊,总体来讲幸福感还是下降了。不过幸好中国IT发达地区空气污染太严重,不仅抵消了这个缺点,反而让我觉得穷一点过得更爽了。于是自从翻了墙,每天就过着再也没空把玩电子产品的日子,有空就开车,没空就上班,爽的不行。

    Microsoft Office

    在Office的工作让我大开眼界,算是体验了一把一万个人写了三十年的、一个repo的snapshot就有几百G代码的软件是怎么弄出来的。由于机器实在太贵,所以平时修改代码的时候,只能在本机编译,因此我们基于msbuild弄出来的这套CI,还包含了如果需要链接的lib/dll的代码在硬盘里面没有的话,就去服务器找当前checkpoint的编译好的缓存,下载下来编译的功能。因此偶尔build farm挂掉的那几天,由于网络连接断了,本机编译也没办法弄。

    回顾一下自己的编程之路,学生时期大概就是从一开始写游戏,到写游戏引擎,到专门搞游戏引擎需要的图形、GUI 库和脚本引擎,最终由于精力的关系生下了 GUI 库和编译器。我从一开始设计脚本引擎的时候就很注意脚本如何暂停的问题——其实基本就是源自于游戏的需要——于是人肉做了 coroutine 的各种奇怪的实现方式。到了最后终于学习到了正统的方法,于是本来可以很简单的完成的问题,由于后来需求就是复杂了那么一丁点(说白了就是要让脚本也可以 customize(或者说 hack)coroutine 相关的类型系统的一部分内容),导致了需要用无限复杂的方法来实现 coroutine。人类为什么要互相伤害?

    本来冲着去弄 Visual Studio 的,而且学生时期还不喜欢 SQL,结果工作的时候由于经济危机的关系给我弄到 SQL 去了,工作的内容包含了学习专业的数据库知识和拖控件。

  • 后来我想好吧,反正编译器没得搞了,那我还是拖控件吧。于是我就告诉Office的人说,你看我做 GacUI 多屌不屌!Office 的人说,屌!于是把我招了进来,专门负责组里面不是 GUI 的那部分。

  • 总算最后还是做了喜欢的工作。

    自律改变自我!第①期打卡送书活动启动!

    下面是今天的签到二维码:

    看完知乎轮子哥的编程之路,我只想说,收下我的膝盖...nerror="javascript:errorimg.call(this);">

    好文和朋友一起看~

  • 打赏
    0相关评论
    热门搜索排行
    精彩图片
    友情链接
    声明:本站信息均由用户注册后自行发布,本站不承担任何法律责任。如有侵权请告知立立即做删除处理。
    违法不良信息举报邮箱:115904045
    头条快讯网 版权所有
    中国互联网举报中心