程序人生之杂扯篇
确实,作为已撸了快10年代码的“老”码农,按一些人的观点及理念,应多谈多扯一些高级点的东西,譬如架构譬如项目管理什么的——我也想,只是限于(目前的)个人能力及眼界,自觉确实还远不够格说这些。
所以很明显,我应“接地气”地尽量实事求是些,扯一些(自己)在编程经历中的心得,和反思吧。
本文将围绕程序设计语言这一争议话题展开泛扯。很明显,扯及的这些语言或多或少我都学过写过用过,或曾经用过,即便只是拿来写过很小的程序等。
就从 Delphi 开始扯吧,也许它是我的程序初恋。
似乎现在知道甚至听过 Delphi 的程序员已相对而言不是很多了,在不少人眼里,这是个基本上会慢慢消亡的“老古董”了。虽然我并不认同类似观点,但不可否认的是,Delphi 确实已,也会更加小众,除非有新的适宜它的广阔领域或巨大机遇,否它几乎很难东山再起了——更悲剧的是,目前看来,可能很难有这样的领域或机遇了——想想 Delphi 1&2 是怎么火起来的,抛开其当时确实牛叉的技术,Win16/32 的流行普及才是带动这类开发工具/语言发展的主要因素。
虽然 Delphi 已支持开发 iOS、Android 及 Mac 应用甚至(据说)即将支持开发 Linux 服务器程序,按牌面讲简直就是跨平台开发的莫大利器,但事实上,产品质量每每不及甚至远不及预期,太急功近利的产品发布尿性,严重的内部动荡及没有可依靠的大腿等因素综合在一起,直接导致 Delphi 陷入恶性循环,而且似乎愈演愈烈——如斯情景,Delphi 能不慢慢泯然众人才真是奇迹!
04 或 05 年还在读大学的时候,有一段时间我经常窝在宿舍,看着《JAVA核心技术》,照着各类 Demo 用 JCreator 摆弄着一些 Java Applet 小程序(譬如嵌在网页里的打飞机小游戏),觉得 Java 好厉害,我要学好它以后靠它吃饭呢。
——而且还记得,在选择学习 C# 还是 Java 的时候我犹豫了好几天,最终还是选了自学 Java(原因实在记不清了,可能和 James Gosling 有大胡子有关?:)),虽然 C# 是 Anders Hejlsberg 设计的。
但大学期间的我,喜欢没事跑校图书馆,除了看古龙金庸等武侠,还有计算机类书目。于是很自然地,有一天我偶然看到了那本很厚的《Delphi5开发人员指南》,而很俗套却确实是事实的是,我被其前言里的“真正的程序员用 C,聪明的程序员用 Delphi”这句给“蛊惑”了,接下来很明显,我花了不少时间了解了 Delphi 的前世今生,然后显而易见的,从图书馆借了几本 Delphi 相关的书籍,并由此学习了一点皮毛,进而为之后的工作学习打了点基础。
那个时候,我还不懂得感受 Delphi 本身设计理念的优秀及超前,不懂得欣赏 VCL & RTL 实现之美,不懂得学习领会 Delphi 实用的语言语法特性等,基本上只是感觉 Delphi 好强大,写东西好方便——譬如搞界面,实在比在 Java 里要自己手动一行行编码方便太多了。而 Delphi 6/7 也在我当时的渣渣笔记本(NEC 的二手本子,似乎只有 128MB RAM,CPU 型号实在不记得了)上跑得挺欢快,但 JBuilder 却几乎没法使用,这可能也是我后来没怎么继续学习使用 Java 的重要因素吧...
09 初,经由 savetime 提携有幸进入盛大游戏,开始用 Delphi 开发游戏(是的,就是《传奇》),也有幸结识了像 savetime、范哥 等大牛,及 Colin、Ryan 等诸多牛人,自己也慢慢对 Delphi 的使用及理解有一些质的提升——我很怀念那个时候和几个对技术较沉迷的同事一起探讨研究的时光,这样的经历对自身提高帮助很大,可惜这样的日子太短了。
还记得那时,Colin 用 VC++ 写了个 2D 绘制引擎,我也不甘示弱用 Delphi 撸了个,然后相互比拼绘制速度,甚至好像有一次我的引擎速度不正常地大大快于 Colin 的版本,惹得不光 Colin 质疑连我自己都觉得有问题,后来查代码才发现自己的 batch rendering 搞得太狠,似乎将图片绘制顺序给无视了...
而那时跟 Ryan 等一起蛋疼折腾 80x86 汇编优化以使 Delphi 生成的机器码速度能媲美 VC++ 等的记忆,也似乎还很清晰——是的,DCC32/64 生成的代码质量相对而言明显过于落后时代了!即便有 FastMM、FastCode 等三方库,但这根本不足以弥补 Delphi 欠下的技术鸿沟——看看 C++ 及 JIT 等编译器的长足进步吧!
很明显,只是因为核心人才的持续甚至大量流失,才使得 Delphi 被抛下太远,心有余却无力追越它者的身影。这实在是个悲伤的故事。
没什么强人坐镇,相反却动荡不断折腾不停失血不止,且员工水平参差不齐等等等等,我真心无法对 Delphi 的未来抱有多少乐观看法——即便它似乎抱对了 LLVM 的大腿,也正确地趟进了跨平台的潮流。
但即便它前景似乎黯淡,也并不妨碍我对 Delphi 诸多特性及理念的推崇和赞赏,仅举几例如下。
1) language syntax:Delphi 语法严格严谨但却不失灵活及强大,与之形成鲜明对比的必然是 C++,个人而言,Delphi 在工程实用性、代码可维护性等方面明显领先 C++ 太多(当然肯定有很多人反对),相信对这两者都有过经历的码农或多或少能部分认同吧,“如果你认为 C++ 还不算太复杂, 那么请你解释何谓 "protected abstract virtual base pure virtual private destructor",你又会在何时需要它呢?”,何其鲜明的学院派特性。我很认同 Golang 宣扬的一个理念:少即是多。很多人也知道一些大公司严格限制只允许使用 C++ 的一部分子集,这显然能表明 C++ 在语言设计上的失败。应该是个人能力问题吧,相较起阅读 STL 的源码,我更喜欢看 RTL & VCL 代码,可能那种简洁明了、几乎朴实无华的东西更能吸引我。
2) Compilation speed:虽然 Delphi 语法确实相较而言简单不少,虽然 dcc 只是 one-pass scan,且生成的代码质量过于一般(这事实上更应归咎于是开发人员的水平问题),但 dcc 那闪电般的编译速度,即便到现在,也未见有哪个编译器能望其项背,至于 C++,呃,还是不谈了,譬如当牵扯到 template 等的时候...可惜 dcc 自从 Anders Hejlsberg 离开后似乎再无多少实质的突破,实在非常可惜!
3) procedure of object:可能很多人没意识到这是非常实用的语法糖或编译器魔法,只是理所当然地照本宣科用着。其实我以前也并没太觉得它的实用性,只是后来在编写 ASC 的过程中,想要在 C++ 里模拟这种实现的时候却只得求救于 C++11 的 function,那时还是小小地敬佩了 Delphi 一把——是的,在 Delphi 里使用这个特性是那么的自然,以至于我们都忽略了它的实际价值。
4) initialization & finalization:很明显,package init 这个语法表明 Golang 在工程实用方面有实际地考量,这也是我当初觉得 Golang 偏实用的依据之一。想想这俩特性的使用场景,及如何在 C++ 里实现它们吧(C++Builder 除外)。
5) property:就我(目前)所知,除了 C#(毕竟和 Delphi 有着同一个爹),没有哪个语言对 getter & setter 的封装能有 Delphi 这样优雅。譬如 Python,抱歉,我真心觉得它的语法设计随意成分高了些,即便它只是脚本语言,但在语法层面,可能它远不够譬如 Pascal 等规范严谨,更多的是约定和规定——当然这只是我个人非常浅显的感受,很可能很有失偏颇。
6) RTL:Delphi 的方便及实用,在 RTL 的设计及丰富程度上可见一斑,IntToStr、Trim、TStream、TList、TStrings、TThread 等等等等,用的时候顺手拈来,倍感愉悦,当然 STL 甚至 Boost 更强大得多,只是,我就是抱有偏见地觉得,Delphi 的 RTL 简洁明了,使用便利(引用简单,编译快速)。
7) VCL:这个几乎不需我多说什么,至今也没有什么语言或工具在开发 GUI 层面哪怕只是接近 Delphi 的方便强大程度(也许 C# 能接近,但论起 RAD,明显它不够自然直接)。也许有人会举例说 QT,甚至 duilib 等之类,但我相信,用过的自然懂。
8) Drag-and-drop:几乎肯定会有人说这种拖拉控件的做法好 low,而我也几乎可以肯定,持这种看法的人,其水平及眼界可能还比较 low。将复杂的问题简单化,提供易于操作的行为,这是不是工程实践上大道至简的深刻体现呢?
...等等等等。
还在盛大时,曾有位 C++ 背景浓厚的同事(之前就职于金山从事 WPS 开发)应需需要开发一款图库编辑器,我建议他直接就用 Delphi 吧,只是后来各种原因他选用了 VC++,并使用了 QT,当然工具是做出来了,只是耗时久了些,我开玩笑说我如果用 Delphi 也许只需 2、3 天甚至更短就能撸一个不比你这差的出来,他说那是你厉害云云,我否认,并直言其实这主要是 VCL & RTL 的功劳,我只是某种程度上会用合适的工具来快速高效地实现需求而已。
顺便说下,WPS 为何弃 Delphi 而选用了 QT,原因只有一个:那时金山内部会 Delphi 的技术人员走得只剩下一个了(而且似乎还是珠海本地人),更要命的是在珠海很难招到合适的 Delphi 程序,无奈,只好转用了 QT。这事 Colin 比较了解:)
在上一家公司时,有位同事曾坚持要用 C++ 来写各类辅助工具,包括但不限于各类编辑器等,但在我的分析及建议下,他还是听取了意见,将某些不好实现或重要的功能封装成 dll,其它的则以 C# 来完成。如斯做法,模块化等是一方面,工期也缩短不少。
扯这些,只是想表明一个观点:要用合适的工具做合适的事。
譬如做 Win32/64 上的普通应用开发,通常情况下可能选用 C# 或 Delphi 更合适些,C++ 当然也可以,只是明显它不够方便快速(而且某种程度上技术要求也高一些)。虽然 Delphi 现在用得不那么广,但它几十年的沉淀及积累,却是莫大的技术宝库。仅对于我个人而言,业余如果需要,还是会拿它来写写东西——除了感情成分及一点积累的因素外,方便、快速确实是主要原因。
曾有段时间,我对 Python 有些兴趣,也想拿它写写小工具之类,不可否认,Python 的三方库实在太强大了!可能吧,Python 的流行,语言因素倒不太重要,丰富、强大的三方库才是吸引人的主要原因。即插即用,几乎不用在意繁文缛节,只需关注要实现的功能,委实很方便,即便相对而言它的执行效率差很多,多线程实现也很不够好(GIL 锁)——毕竟大部分情况下,效率并非最核心的因素,快速实现原型才最重要。但后来我还是改用 Delphi 写小工具,主要原因只是,我希望最后生成的最好只是个可执行程序,无需任何额外的依赖或部署。于是脚本语言不合适了,C#/Java 也不满足要求,剩下的无非也就 C++、Delphi 及 Golang 等了,很明显,这种场合下 Delphi 毫无疑问会胜出。
仅我个人喜好,譬如程序语言,我钟意的特点及特性如下。
1) 原生
2) 语法简单,语言设计以实用为导向
3) 编译迅速,执行快速
4) 标准库丰富多样
5) 有各式各样强大的三方扩展库
6) 有着易用的 IDE
于是很明显,符合要求的只有 Delphi 和 Golang,而 Golang 显然更适合服务器端开发等领域(当然拿来做 Web 开发也似乎 OK),goroutine 和 channel 实在是非常廉价却又非常简洁高效的并发利器,这样的特性对于服务器端开发来说非常有用且重要,很大程度上简化了服务器端的多线程相关逻辑实现,在语言核心层面支持并行和分布式,并发模型简洁高效,简直是天生的后端开发牛刀(更可喜的是其 GC 也有着持续巨大的进步)。
是的,基于 Win32/64 的应用开发市场似乎已在慢慢萎缩,这也一定程度导致像对 C++ 等人员的需求明显减少。时代在变迁,现在早已不是几十年前唯 Windows 一家独大的时代了。多种平台或生态,各类语言或技术,大大分流或甚至,归类了程序员(“全栈”?可能比大熊猫还稀有吧)。可能很多程序员在入行时会犹豫,这么多的技术这么多的行业,该如何选择。
可本文无法回答这样的问题。
仅于我个人而言,靠着勉强算“多年”的松垮的学习及工作经历经验,譬如各类程序语言(包括不限于 Asm、C/C++、C#、Delphi、Golang、Java、JavaScript、Lua、PHP 及 Python 等),我几乎都能在几天甚至几小时内快速上手。某种程度上,语言本身确实不是很重要(喜欢追根究底钻研底层实现的除外),正如 范哥 曾在微信里说的:编程这件事,谁也没勇气自称为专家,学得越多,懂的越少,做程序的,更重要的是跳出框框,不要被语言语法束缚,要有自己的一套解决问题的思想和办法。
但即便如此,我估计也会在需要或感兴趣的时候,研究些算法,尝试些新实现或新框架,学习或使用譬如 JavaScript 等语言技术。技术人员么,固步自封最好不要,即便流行的东西不一定是对的,跟上时代,拓宽眼界总不会错。