那些年,我追过的语言

jopen 10年前

那些年,我追过的语言

        作者:陈天

        程序君也年轻过,年轻的代价就是盲目追随。

        从 MS-DOS6.0 开始,程序君就是微软的狂热拥趸。

        这种狂热自 win95 走上高潮(有谁还记得 win95 光盘里带的 Good Times 的 MV,请举手),历经《未来之路》,windows2000,最后在 dotnet 发布后到达顶峰。

        那段时间,只要微软反对的,就是我反对的。

        不喜欢 Netscape Navigator,只因为 IE;诅咒过 SUN,对 Java 深恶痛绝,因为 NC 是 PC 的死敌,SUN 妄图革微软的命;使用 Visual Basic,啃 MFC,不为别的,就因为 powered by Microsoft。

        但 VB 功能太弱(其实还是我水平太差),MFC 太乱,以至于大二时,我在给人打工做软件的时候无奈地选择了 Delphi。

        虽然不怎么喜欢严谨的 pascal,但 Delphi 有让我不得不用的理由。用它写代码清新明快,效率上甩了笨重的 MFC 几条街,速度上让 VB 相形见拙。在那个 Wake On LAN 才兴起不久的年代,我用 dephi 做的印象最深刻的一个小 feature,是通过一台电脑打开(或者关闭)局域网内几十台电脑。看着自己的软件能『神奇』地唤醒机房里的一群电脑,别提多自豪了。

        在我上大学的期间,做客户端软件(或者C/S结构的软件)虽然能赚钱,但已经渐渐不酷了,ASP 的出现,让我的兴趣移师到 web(那时时髦的叫法是:B/S)。ChinaRen 的崛起让我萌生了做自己的班级主页的想法,但做出来的东西只能躺在硬盘上,在参加比赛的时候演示两下 —— 那时几乎没有免费的提供 MSSQL 的服务器,而我做的『网站』,无一不基于 MSSQL 或者其简化版。我像一只把头埋在沙子里的鸵鸟,把自己限制在自己构筑的程序世界。

        后来 DotNet 带着微软的万千宠爱出炉,我第一时间接受了它。我一边玩着 C# 代码,一边继续无视如日中天的 Java 2 及 NB 哄哄的 J2EE。C#很迷人,一下子让我有种想要扔掉 delphi 的赶脚,但无奈 dotnet framework 太大(而且相对较慢,当时),还在使用赛扬的客户无法接受。

        程序员在世最痛苦的莫过于最爱的语言(C#)赚不了钱,不喜欢的语言(Pascal)却为你解决生计问题。

        C#无法在我的兼职生涯中施展拳脚,只能作为又一个参赛语言或者研究院语言,被我拿着招摇撞骗(那时讲 dotnet 就好比现在的云计算,大数据,很容易把不懂的人侃晕),写着连我自己也不相信的虚拟企业信息集成系统,混各种核心期刊论文。

        毕业后,本来想找份 C# 相关的工作,却阴差阳错地做了通讯领域,让C取代C#,成了我的主流语言。大学时我的C也就是个习题水平,做过最难的习题不过实现 inode 模拟一个简单的 unix 文件系统,然后提供几个 shell 命令能创建目录,创建和修改文件。到了工作岗位,socket,timer,hash table,ring 才真正走出教科书;而伴随着通讯领域的工作,Linux 则正式走入我的生活。

        认识到了 linux 的强大和从骨子里透出来的美感,我从此与微软的技术渐行渐远,也离开了混迹多年的 codeproject。

        写C的日子是枯燥的,尤其是用C写 protocol。完整写过的 IGMPv3,大部分代码几乎都是不用太动脑子的从协议语言到C的翻译。

        那两年正是互联网方兴未艾的时候。google 正飞速发展,百度从新浪的搜索提供商(2B)开始寻求面向大众(2C),3721 是浏览器的标配,而 mediaWiki 也随着 wikipedia 的走红而走红。写出 mediaWiki 的 php,成了我闲暇研究的对象。那时 LAMP 开始成为时髦词汇,WAMP/Apache Friends 为还在使用 windows 的人们上提供全套互联网开发环境。

        后来我在做一个自动化测试系统时感受到了 php 的力不从心 —— 我缺一门好的胶水语言,在 web 和 system 间游刃。正巧坊间一直流传『真正的程序员用C,聪明的程序员用 python』的偈子,于是我又学习了 python。这下拼图完成了:我用 php 在前端接受用户提交的任务,用 python 读出任务,从 clearcase 中 checkout 对应的全套路由器代码,编译出 image,然后使用 pyserial(一个串口库,可以连路由器的串口)和 pyexpect(expect 的 python 封装)连上测试环境中的路由器加载编好的 image,然后调用测试团队提供的自动测试脚本测试。

        那时没有 rabbitMQ 这样的杀器,php 和 python 之间的任务同步做得很土:php 把任务插入到数据库,python 程序死循环每 30s 从数据库中读任务。

        后来我换到了现在所在的外企,很快在同事的推荐下小试了一阵 QT,QT 的 slot 和 signal 做得真心漂亮 —— 可惜那时客户端软件彻底从我的技能清单里被移除,我也就没有继续在 QT 上发力。

        那段时间,C让我糊口,php 让我保持和 web 的连接,而 python,一直是我做各种小工具的最爱。

        期间玩过 drupal,symfony。看 symfony 的作者的 screencast,才知道有种开发神器叫 TextMate,有个程序员的电脑叫 macbook。

        symfony 对我而言是个很好的布道师,它让我认识了 Ruby on Rails 和 django(源自 symfony 和二者的对比)。

        它的一个联系项目 jobeet 还为我日后为创业项目起名提供了思路 —— 对,toureet 就是这么出来的,而且 07 年前后这个名字就横亘在我的脑海。这不算个很接地气的名字,但就像初恋一样让人挥之不去。

        知道了 Ruby on Rails 后,我才意识到如今已经是 RoR 横扫一切的时代,几乎是个创业公司就在用 RoR。JavaEye 的 Robin 称自己几天就搭了 JavaEye 出来,我虽然不怎么混 JavaEye,但这还是大大刺激了我一下,让我对 Robin 和 RoR 好顿膜拜。

        但那时 RoR 内部分裂了有一段时间,社区正在开始思考如何让分裂的两个分支摒弃前嫌,在 RoR3.0 大一统。这让我好生郁闷:究竟是等还是不等那遥遥无期的 RoR3?毕竟,之前 symfony2 已经狠狠地摆了我一道 —— 我在 1.x 上写的代码在 2 里无法运行,而且 2 的改动之大让我一时间无法适应。如果现在入手学习 RoR2.x,会不会重蹈覆辙?

        两权相害取其轻,我最终选择了 django。

        然后机缘巧合加各种必然,我走向了创业之路。

        等我『毕』业时,我已经算是 django 和 javascript 的熟手。

        javascript 是个很有意思的存在。我大概在 2000 年左右抄(对,抄的)的第一段 js 是一个问候的代码,大致是检查当前时间,然后提供不同的问候语。很傻很天真。

        那时的 javascript 恶名远扬。除了好玩,没人严肃看待它。

        直到几年后 prototype.js 和 http://script.aculo.us 出现(谁还记得你们呢?sigh),javascript 才开始自我正名。

        然后是神一样的 jquery。

        接下来羽翼丰满的 javascript 开始玩 MVC,代表作是 backbone.js。

        还玩函数式编程,如 underscore.js。

        总之到我创业时,javascript 的生态圈已经无比繁荣。途客圈的第一个产品的计划编辑器使用了 backbone.js,第二个产品前端全面采用 ember.js,而且用 coffeescript 撰写。

        我写了个 makefile 把所有的 coffeescript 整合编译打包。

        我好像没提 makefile 吧?程序员最好会 makefile,减轻很多事务性工作。

        然后 javascript 在 V8 的基础上开启了 nodejs 时代,nodejs 让 javascript 登堂入室,成为后端的一股劲旅。

        从此前端工程师开始屌丝逆袭,成了香饽饽。会 Python 的不见得敢写前段代码,但会 javascript 的已经在后端开疆拓土。

        笨重的 XML 此时已经向 JSON 让路,前后两端的数据通讯被 javascript 把持。

        mongodb 的出现进一步助长了 javascript 的气焰 —— 连数据库都是 JSON(BSON)存储,javascript 作为存储过程(这么说好理解些),javascript 还有什么不可以?

        几乎在一两年间,LAMP 改朝换代成了 MEAN(MongoDB,Express,Angular,Nodejs/Nginx),nodejs 大有当初 RoR 横扫一切之势。

        构建在 nodejs 上,提倡 react 的 meteor.js 向整个互联网刮了一阵清风 —— 原来网站的代码还能这么轻巧地让一切动起来!草草学习了花了几个晚上,我写了 teamspark,成为了途客圈团队内部的标准沟通工具。可惜不知怎么的,meteor.js 的发展渐渐受到瓶颈,打下的良好用户和市场基础在这两年的缓慢更迭中一点点被消磨。

        后来我从互联网回到了通讯领域,趁着一段难得的清闲,好好研究了下 concurrency。concurrency 自然少不了 Joe Amstrong 的 erlang。erlang 相对于我理解的那些语言,有点不食人间烟火的意味。

        在 erlang 身上我贪婪地攫取了很多知识。erlang 适应起来很难,尤其你想表达 x=x+1 时会感觉那么地痛苦与无助。我颇花了一些时间才搞明白 atoi () 在 erlang 中究竟怎么实现。

        尽管我尚未用 erlang 写过什么像样的系统,但它对我思想的冲击是巨大的。

        最终,我从 erlang 延伸到了 go。go 是门优点与缺点同样突出的语言。本来我正是把它当作一个带并发支持的"modern C"来看的,但深入下去后发现,go 和C是两个世界的人。go 只能在某些场景下替换C,但无法取代C。soft realtime 是个魔咒,把几乎一切有 GC 支持的语言挡在了C的另一侧。现在看来,也许只有 rust 能从理论上取代c/c++。

        go 已经发展到 1.2 版本,但依旧任重道远。首先,它的编译速度比宣称的慢不少,执行速度更是比C差了不少,很多场景下(尤其 GC 相关),要比 JVM 下的语言(如 scala)差。

        go 也有不少 bug,连我都能发现一个严重的导致可执行文件好几百兆的问题(没处理好 bss 段)。

        但 go 精巧的语法,简洁的思想,语言内置的并发支持,让它还是我不断学习的对象。

        人的精力毕竟是有限的。很多语言看了看思想,写了写简单的例子(上百行代码)就搁在一边了。在此鸣 谢:ruby,elixir,io,emacslisp,scala,nimrod,rust,clojure,lua,我从你们那里吸收了不少有意思的 知识,却浅尝辄止,没有深入和你们互动下去。

        也许你会问:一门语言究竟多久能掌握?

        学精一门语言,也许需要花上三五年的功夫,也许还要更长。

        但学精了一门语言后,学第二门一周也就该能入门了(erlang, haskell, lisp 除外)。

        现在我不再会对某个公司的技术有特殊的偏见。我拥抱一切能提高生产力的技术。

        也许你会问:学那么多语言有什么用?

        如果用来养活自己,一门学精了就足够。其它的没什么用,也就消遣消遣。我看中语言背后的思想,会比较用不同语言开发的乐趣。另外,当你喜爱的语 言添加了新的特性(或者你用到了某个高级特性),你可以一下子就想到了背后的逻辑:啊,原来这是 xxx 的思想。于是,你对这两门语言的掌握又加深了一层。

        我目前最大的遗憾,是没有静下心来好好看看 java。

        虽说对技术没有偏见,但我依然痛恨恶心的 IE6/7;同时,我打心底喜欢一样东西:MAC。

        如果说对程序员有什么忠告,那就是:Every programmer should use MAC。

$ brew install nimrod

        愿每个程序员都成为人生的好猎手!

        ^_^