我真的不是因为写了Python,就在黑Perl

最近装了 wakatime 这个控件以后,
我一直忍不住好奇心去看看我平常到底有多少时间在写代码。
经过严谨的数据统计表明:
我只有25%的时间在写代码。
(按一周40小时算,
我一周只写10小时的代码=_,=)

old-waka

这样不好。
于是我决定奋发图强,
在自以为沉浸地写了一周代码以后,
25%变成了33%。
于是严谨的数据统计依然表明:
我大部分的时间都在划水。

new-waka

于是我放弃了挣扎,
就像苏轼朋友佛印和尚讲过的一样:
既来之,则安之 不是他说的

我很开心地想道:
“哎呀。
我就花这么一点点时间干活,
是不是说明我效率高呀?”

“不是的,只不过是因为你懒而已。”
心里的正义小人蹦了出来。

我十分开心地嘴硬道:
“对呀对呀,我就是懒。
而且就像我以前说的,
懒有那种没有建设性的懒,
还有那种一劳永逸的懒。”

嗯,今天我就要尝试说服我心里的正义小人,
我不是在偷懒,我是在想问题!

按老规矩,
用讲故事的方式讲道理。
献丑了!

我从大四到毕业,
一直在QAD当研发(就是研发工程师)
一般来说,“研发工程师”这个说法是分工上这么叫的,
洋文里叫 SE, Software Engineer,
对应测试工程师 QA, Quality Assurance
互联网公司里是Web编程的话,
会从另一个维度上分成前端工程师 FE, Front End,
后端工程师 BE, Back End
有些也会从部门上拆分成架构、技术(业务)、算法、数据不同的组。

QAD主要是按业务拆分研发部门,
我们当时是Foundation组(基础架构组)。
公司做的是SaaS形式的ERP系统。(SAP, Oracle都是我们的竞争对手)
这里的SaaS可以简单理解为年费会员,
大众(Volkswagen)公司买QAD的ERP系统并不是一锤子买卖,
当合同签订以后,
我们还要负责整套系统的安装、培训、维护、升级工作。
(当然大众也要对应地交“物业费”就是了)
公司部门分工大概如下:

  • R&D 负责开发软件。R&D也就是研发部门,Research and Development, 我在这…
  • Sales 负责销售产品。(有的时候研发还没做完,产品就卖出去了,于是倒催研发…十分神奇…
  • Service 负责产品的安装、上线、培训。有的时候客户有一些定制化的需求,Service也是要写代码的。比如中国的医药公司要开发一套药监局审查流程,这个明显不是标准流程,就需要定制化开发
  • Support 负责日常的支持。比如产品平时出Bug了,晚上出Bug了,周末出Bug了,都要负责给客户解决…
  • Finance, Law, HR, CEO 等其他队友提供内部支持,维系组织有序运转。

我当时参与的项目是叫CVC, Customer Version Control
要解决的问题,就是定制化开发中的,代码版本控制难题。
比如还是大众公司,
他们2008年就安装了QAD2008版本,
然后基于2008版本做了大量关于车辆测试、车辆安全性能等方面的定制化开发。
于是在QAD要升级主程序版本的时候,
大众公司惊呼:“1079 Merge Conflicts Found!!!”
这种定制化和主干的冲突,
只是当时我们要解决的其中一个问题,
其它还包括有超过10G的代码本地环境构建,
dev-test-sup-prod多环境代码管理,
soft/hard lock等。

正义小人:“ok,于是你讲了这么多,
跟具体写程序相关的一句话没讲……”

的确,具体写程序的话是一句没讲。
那既然都扯这么多了,
我就再扯多点吧…

技术选型上,最开始用了 Git + Perl
因为要做代码版本控制,
所以核心的轮子就用了Git
当时团队的技术栈主要是Git vs SVN
又因为要做多环境管理,
所以git rebase, git cherry-pick, git filter-branch等一串能修改历史的命令就优势明显。
又因为整个项目最终是一个命令行工具,
而且团队之前的主要技术栈是Perl
项目语言就采用了Perl
Perl这门语言最强大是它的命令行交互和文本处理,
很多shell命令是天生共通的,
比如echo, test -f, $@等;
文本处理上,正则和一些heredoc也是非常美妙。
Perl最大的问题倒不在语言本身被诟病的鬼画符上,
最大的问题是:Perl日渐衰弱。
比如假如我们说我们招Java工程师,
那其实可以招到很多人才,
但同样招Perl工程师,
招到同样人才的概率也不一定会高很多,
但是付出的成本要高更多。

于是后来我干了一件事情,
下班时间用JavaCVC给重写了。
三四月份的上海特别凉快,
我住的离公司也近,
六点多吃完饭,走路回家洗个澡,
穿个拖鞋就蹦跶回公司。
白天写Perl,晚上写Java,特别开心。
当时老大也特别会顺势而为,
他看我自己在重构项目,
分给我的活也更少了,
于是后来上班的时间我也在“划水”写Java了。
因为需求明确,功能点清晰,
就这样过了两个月,
两万行的Perl代码再加同样量级的单元测试,
(一时间竟没找到比代码行数更恰当的数据……)
被我重构了一半到Java
后来大家一起把各种Edge Case补上了,
整个产品正式切换成了Java
也算是一点微小的贡献吧。

我在QAD的时间(2014年7月到2016年10月)
基本上都贡献给了CVC这个项目。
同样的功能,
Perl版本用了一年多实现,
Java版本用了几个月就实现了。
决定性因素跟语言表现力毫无关系,
而在于业务需求业务理解上。

正如上文介绍项目流程里讲的,
项目要做的是定制化开发
需求就是来自于Service部门同事。
他们一开始是不知道什么样的软件是好用的,
我们定义好的产品模式(比如自由checkout文件),
但是他们觉得另一种模式更好(开发人员更换频繁,需要对文件加soft lock),
或者是觉得产品可以更好(比如流程要和Jira高度结合)。
所以其实我们在Design - Refine这个流程上不断进步
(中文的说法叫“走了不少弯路”)

还有我们在重构过程中,
因为知道了整体的需求的样子,
就能更好地抽象逻辑。
就像是建筑师设计房子的时候,
因为知道了整体架构,
他才能确定房梁的承重,
部件的用材。

正义小人想了想,说:
“噢,我明白了。你的意思是说,
偷懒不写程序,其实只是停笔,
想想要写什么样的程序?
需求更准确,理解更清晰,事情才会更好做?”

“对呀对呀!满分理解!”

正义小人又一脸嫌弃:
“但是现实生活中,是不会有这样的情况的。”

是呀,所以我也只能一边说着“学到了学到了”,
一边想着“我是谁,我在哪,我要写什么程序?”