程序员的语言“艳遇史”(六)——网络工程师perl
(***以下小说情节纯属虚构,供朋友们在紧张编程后轻松一下,如有雷同纯属巧合,切勿对号入座***)
第六个女孩 网络工程师perl
一、风雨割接夜
一个风雨交加的夜晚,我骑着我的小电驴,奔驰在东大街上。已是深夜,街上鬼影都没一个。突然一个塑料袋幽灵般的飞到我头上,我正惊魂未定,手机又响了。我拿起电话,不耐烦的说:“五点半才割接,你催什么催,我已经在路上了!”。那边传来一个冰冷的女声,“如果五点你没到场,你就等着扣钱吧。”。
二、女魔头perl
自从我们中标某市163网络扩容工程后,我就没过一天好日子。先是供应商到货延迟,为不误工期,我们只能加班加点安装调测,累得半死。没想到电信局方和我们配合的perl小姐,苛刻到极致。几个接入点都由于一些小事被她要求返工,把我气得吐血。然后她又规定割接时间必须在凌晨五点半,理由是网络监控发现此时上网流量最低,此时断网对用户感知影响最小。
在邮电这样的垄断行业,虽然标语上说用户至上,心中一向把用户当根葱,居然能出这样一个同志,我简直无语了。这个吓死人的合理化建议果然被采纳,她是被领导表扬了,可我们这批建设队伍就倒了大霉。几个晚上下来,都没怎么睡,眼圈黑得和熊猫似的。
到了机房现场,我正想发飙,先到的同伙小丁给我使了个眼色。仔细一看,里面各路大小领导来了一堆,还有人照相。我们的猪头老总正和perl小姐亲切握手呢,那个色迷迷的样子真让人反胃。原来本次扩容完成后,市电信局要召开新闻发布会,庆祝全市实现chinanet网络正式商用,还请了主管副市长讲话。领导们极度重视这样的露脸场合,于是都到现场监工。
各位老资格的网民知道,上个世纪90年代末时还没有宽带,大家都是拨号上网。最早提供上网业务的不是中国电信,而是瀛海威这样的民营公司。瀛海威当时的广告语挺吓人的,“信息高速公路离中国还有多远?”。以现在宽带的标准,那时用33.6k的modem拨号上网,简直是“信息低速小巷”。当时的邮电部看有利可图,就组织“国家队”大规模进场了,推出了号称中国公用计算机互联网的chinanet。各地电信局网络建设项目此起彼伏。我当时在一个电信系统的集成公司,借此良机中标了好几个单子,一时间发了点小财。
调通网络后监控了一段,万事大吉,我躺在机房的沙发椅上准备补上一觉。忽然眼前一黑,perl小姐又出现了,说新闻发布会现场人不够多,叫我们过去当群众演员凑凑人数。靠,不知道兄弟一向卖艺不卖身的吗?我当然没一副好脸。但是看清楚她手中挥舞着那张项目初验清单后,我立马蹦起来,老老实实接受指挥。好汉不吃眼前亏嘛,这个女魔头要是怒了,再抓几个问题,项目初验不过,老板还不剥了我的皮。
三、dns服务配置的赌局
公路是建起来了,可是上面没什么车跑啊!也是,当时网络上的中文内容少得可怜,新浪、搜狐、腾讯都不出名,马云的阿里巴巴还开在居民小区里呢。于是电信老大又出面了,什么政府上网工程、企业上网工程纷纷出台。现在回想过去觉得十分好笑。“国家队”搞垄断性、资源性产业可以,让他们做互联网信息服务,基本没什么竞争力。我们当时接单,做了不少应景的网站,上线后几个月了都没更新。根本没人管,都是应付了事。一个亲戚摩托车要年检,我还热心推荐他上车管所网站查看相关事宜。没想到年检地点早变了,网站上写的还是旧址。结果害人家跑了冤枉路,还以为我捉弄他,把我骂得够呛。
一天,又接到女魔头perl小姐的电话,通知我到机房,说有重要升级事宜商量。我推门进去,发现perl正在一个终端前,忙不迭的用vi修改dns配置文件。原来是上级根dns服务器版本升级,我们本地dns服务器也得跟上,需要把所有的域名解析文件格式都做修改。那时正是上网工程高潮,一阵风过去,凑了几百家本地单位发布网站。现在好了,几百个域名配置要更改,这还不把我们perl小姐累死,于是抓我来垫背。
对比了新旧域名配置格式,我发现这是一个普通的文本处理问题。“还不动手,今晚准备加班啊!”。perl小姐又催了。我笑了笑,说打个赌,如果能在10分钟内解决问题,她就把几张验收单都给我签了。perl摸了摸我的额头,冷笑的说:“这位大哥脑袋发烧了吧,满口疯话。”
“我没疯,敢不敢打赌?”
“那就开始吧,现在是北京时间16点24分。”
四、Perl魔法学院
十分钟后,perl小姐在几行如同天书的程序文本面前,呆若木鸡。“这是什么乱七八糟的?有点象c语言,可表达式怎么这么乱?你就是用它来做配置升级的?”
看着她那窘样,真是扬眉吐气啊!看来通信工程系毕业的美女还是比较好骗的,也就学过C语言,Perl语言连听都没听说过。
在我娓娓动听的声音下,一番惊天地泣鬼神的八卦开讲了,Perl魔法学院的大门向美女缓缓打开。魔法学院的院长呢,当然是Perl语言的发明者Larry Wall先生啦。没想到院长大人当年和我们一样,也是一个普通的unix系统管理员,用现在流行的话说,属于“软件蓝领”、“it民工”,呵呵。
Perl语言的发明十分偶然。一次,Larry从老板那里接到一个任务,要他为几台unix主机生成工作报表。可他发现几个现有的工具很不好用,耗时又费劲。如果他不是这么的懒惰、不耐心和傲慢(他总结的黑客三大特质),完全可以作一天和尚撞一天钟,忍受这一切。终于他受够了,自己动手发明了一个小语言,这个语言被命名为Perl。1987年末,Perl1.0诞生了。Larry想,Perl语言可能对其他unix管理员有所帮助,就把源代码以GPL版权发布到网上。
Larry充满深情的说,“Perl文化可以接受任何熟练程度的成员。我们不会在你背后放个语言警察。如果你的老板不炒你,而且你的 Perl脚本也能完成工作,那么它就是正确的。”(摘自《Perl语言编程》前言)。哪见过这么平民化的语言设计者啊?这还能不火吗,一传十,十传百,越来越多的人参与使用和改进Perl语言。
在魔法师Larry的手里,Perl语言就如同一颗水晶球,计算元素从各处不断涌入,魔力与日俱增。开始,他只想做一个象Awk那样的小语言,核心是一个正则表达式处理的程序包,配以简单数据类型和字符串里的变量内插。接着,他又从当红的C语言那里借来了一些语法要素,从古老的Lisp语言那里借来了dynamic scope(动态作用域),这就差不多构成了Perl1.0的内容。在源代码发布上网后,全世界各地的unix管理员贡献着他们的力量,使得Perl语言的魔力越来越强,先后引入了模块、staic scope(静态作用域)、闭包、面向对象等要素。到现在我们使用的Perl5版本,它已经是一个多用途的动态脚本语言。 Perl在web服务器端编程、系统自动化管理甚至生物信息学中得到了广泛的应用(据说连人类基因组计划中的许多数据处理,都大量使用了Perl语言)。Perl社区还建立了自己的代码库CPAN, 上面有N多的开源模块,数都数不过来。
Perl语言的成功,为全世界的unix黑客做了一个最好的示范。难道只有计算机科学家或者研究人员,才能发明程序设计语言吗?黑客们已经很不爽了,让那些限制人们心智的清规戒律都见鬼去吧,他们将自己打造自己的工具。在Perl之后,Python、Ruby、Php等一系列风格各异的程序设计语言诞生了。它们的共同点是,都出自黑客个人之手,都采用开放源代码模式进行开发和推广,都属于动态脚本语言。借用硅谷经常说的一句话,黑客们改变了世界。
五、骇客入侵事件
自从我那次八卦门之后,我发现perl小姐对我态度好了很多。那是,男人要赢得女人的心,关键要有内涵。dns配置升级案例也被四处传播,连上级公司都打电话来要脚本。外面风传我是Perl语言专家,由于那段时间Perl语言CGI应用很火,经常有做网站的兄弟向我请教个什么东西,搞得我十分郁闷。没办法,回去急忙弄了几本Perl书籍,一番恶补。原来我就把Perl当作一个系统管理工具,从没正经学过。现在好了,打肿脸充胖子,这真是人怕出名猪怕壮。
一天,我在公司里翘着二郎腿,正在开小差。突然旁边小丁接了个电话,说“老大,公安局找你做笔录。”。把我吓得差点从座位上掉下来。摩托车闯红灯了?上次收了供应商一盒月饼加茶叶?要不就是贪污公款,不过那也得有机会啊?最近兄弟安分守己,没干什么对不起党和人民的事啊。
我战战兢兢的接起电话,仔细一听,那边一个人已经笑成一团。靠,那里是什么警察,是可恶的perl小姐。我大骂,有这么开玩笑的吗,吓出心脏病怎么办?不过她真的是在公安局做笔录,气不过,找我开涮一把。
怎么回事呢?原来市图书馆网站开通才几天,就被黑了!网站首页被人贴了些不雅照,还有一些攻击性的话。这种骇客入侵事件以前都是从书里看到,现在居然真实的发生在我们身边。这下热闹了,机房里外乱成一锅粥。perl小姐作为网络机房维护班长,当然被公安局抓去做笔录。
很快,专案组就成立了。哇塞,上面领导小组一堆人,各单位都有,下面干活的就三个,我、perl,还有公安局网安科的老张。我们从服务器记录查起,看来这名骇客没什么经验,留下了痕迹。再看ip地址,居然是本市的。我们利用ip和上网时间信息,马上又调看radius拨号服务记录。这次perl小姐可老练了,也弄了个Perl脚本,把几台记帐主机数据记录的搜索和定位工作自动化了。狐狸的尾巴终于露出来了,我们定位了拨号上网的固定电话号码。案件告破,原来是市图书馆一个被辞退的员工干的。
当时的心情真是激动万分啊!不过,对perl小姐来说,这真的就是天边的一朵小乌云,不算什么事。在她后来的职业生涯里,处理的大小网络攻击如家常便饭,对抗的工具也不断升级。据她讲,最恐怖的一次,为了应付一个DDOS攻击,她把城域网核心路由器配置都做了更动。至于我,早已不干网络运营这一行了,所以现在她可以当我老师。
六、Perl语言的诡异之处
虽然我们经常看电视,但是很少人会吃饱了撑着,把说明书读个遍,然后把电视机大卸八块,进行一番研究。但程序设计语言和电视机可不一样,你学得越多用得越多,就越想知道它的工作内幕。我被迫成了Perl语言正经八百的学习者后,大学时那种好奇心又回来了。
上个世纪六七十年代,有两个语言特性,被计算机科学界认为是有害的,应该从程序设计语言中清除出去。一个大家都知道,goto语句;还有一个可能见过的人不多,dynamic scope(动态作用域)。
再看Perl语言,好嘛,两个都有。在早期Perl中,动态作用域甚至是唯一的作用域规则。这Larry要是到计算机系读博士,如果有程序设计语言理论这门课,估计会被授课教授拍死。回想起linux之父Linus Tovalds和操作系统大腕 Andy Tanenbaum教授之间那场关于微内核的争论,你不得不说,黑客们都是脑后有反骨的,特别敢于争鸣。
看一个简单的Perl代码段:
sub work {
if ($debug > 0) {
print"Debug: Danger!\en";
}
}
注意那个$debug变量,它既非过程参数,也不是局部变量,可能在work过程之外的其他地方声明,套用逻辑学术语算个“自由”变量吧。脱离了具体语境,你无法搞清$debug什么意思。静态动用域和动态作用域在确定“自由”变量的含义方面,有很大的不同。现在补充一些程序片段:
$debug=0;
sub doit {
local $debug=1;
work();
other();
}
调用doit过程,结果会怎样?如果不熟悉Perl语言,按其他常见程序设计语言静态作用域的规则,会把local猜测为doit过程里的局部变量声明,因此对work过程是没有影响的。work过程中的$debug标识符应该引用的是过程外部的全局变量声明。所以不会有任何输出显示。
但是Perl的动态作用域不是这样工作的,local不是局部变量声明,它并没有创建新的局部变量,而是先保存了全局变量$debug的当前值0,再将其赋值为1。由此影响了后面调用的work过程和other过程的行为。在退出当前程序块时,它会自动将$debug变量值恢复为0。可以把$debug想象为一个堆栈,在程序执行过程中,如果过程调用链上有多个过程对同一个变量使用local声明,则堆栈也随之增减。
假如other过程是这样定义的:
sub other {
local $debug=0;
work();
}
那么运行到other过程内部时,想象中的$debug变量堆栈将有三层,从远到近分别是0、1、0,受最近的变量值影响,这里调用的work过程将不会有显示输出。退出other过程后,$debug的值就自动又变为1。在只有静态作用域的语言中模拟这个过程,就没有这么优雅了。程序员必须手工管理这个堆栈。
还有,Perl为什么要在debug标识符前加一个难看的$符号?这是Perl语言设计中另一个迷。在大多数语言中,一个标识符同一时刻只和一个变量进行绑定。但是Perl语言的标识符,可以同时与多种变量进行绑定。比如,$debug代表标量变量,@debug代表数组变量,%debug代表哈希表变量,此外还有好几种。它们都使用debug标识符,只能依靠一个前导符号来区分了。在内部实现中,每个Perl模块(包)中,都有一张符号表(Perl语言称之为typeglob)。符号表中每个标识符,都对应着一组指针。每个位置的指针,如果不空,都指向一种类型的变量。
经过分析,我做了一个大胆的揣测。Perl语言设计可能从古老的Lisp语言中学了不少东西,什么原子、符号表、动态作用域、垃圾收集等等,Larry也许是个Lisp爱好者呢。有人说Javascript=C+Lisp,我看Perl更象,骨子里是个小小的Lisp解释器。
这些特性是如此的诡异,不符合一般的软件工程原则,以致大多数Perl程序员都不敢用。大家还是老老实实的用my声明词法变量吧,反正现在Perl也支持静态作用域和闭包了。标识符虽然可以多绑定,不同类型的变量还是乖乖取不同名字吧,尽量避免混淆。谁让我们不是黑客呢。
七、尾声
网络集成实在太累,过了一阵我就干回软件老本行了,跳槽到外地一家做增值业务的公司。开始和perl小姐还经常鸿雁传书,联系一下。后来大家都有了新的生活,慢慢就淡了。若干年后在一次聚会上,又见到perl,她早已为人妻了。谈起我们当时很喜欢的《编程之禅》里面的那首诗歌,大家唏嘘不已。
计算中心空空荡荡,
静静的只有风扇在嗡鸣。
我走过一排排的 CPU,
磁通量刺痛了我的皮肤。
我打开一扇门,又冷又硬,
看见指示灯在控制板上跳动。
一台没有灵魂的机器,人们说,
但它的灵魂是同事们的汗水,
在它里面有我们多年的生命,
失望,友谊,悲伤,欢乐,
算法成功时的狂喜,
和无数个徒劳无获的长夜。
我听见了叹息和欢笑的回声,
在这间黑洞洞的办公室里,
终端机闪耀着光芒,就像星星一样。
(摘自《编程之禅》第五篇 水)