当前位置:首页 > 全部文章 2018年12月28日
鹿鼎记娄艺潇码农文青对照记|左手程序右手诗,代码文章两相照-技艺丛谈

码农文青对照记|左手程序右手诗,代码文章两相照-技艺丛谈

作为一位劳作经年的老码农,读侯捷书籍,经常看到封面写有「左手程序右手诗」的介绍,在文艺情怀泛滥成灾的年轻岁月里,总是容易被击中。左右写程序,右手书华章,这不就是这辈子的梦想和追求么?
然而,侯捷的书籍看了很多,代码功力并不见长。文艺书籍买了很多,也看了很多,书是被我撕破了很多卷,却没有读破万卷。于是,侯捷的这句话便被我深埋在太平洋底。


C++ 程序员们,侯捷著译你看过多少?
岁月在流走,指尖流动出来的 0 和 1 之流,渐渐汇成了小溪,而自从开始写作公众号,编辑过的老文新作,也渐渐超过双手能数的规模。遂对写过的代码,编辑过的文章,动了一翻对照的心思。
熟读唐诗三百首,不会吟诗也会吟
不会写作的人,先读读世界名著,看看名家怎么写的,看得多了,自然有了感觉,先学会遣词造句,再控制节奏感,再到谋篇布局。心中有了参考,自然就有了临摹的对象。
读书写作是这般,写代码也如此。
不会写代码的人,往往有一种畏惧感,觉得自己搞不定代码。有一些人敢写代码,但是只写写 python 代码,没勇气写 java 。写 java 的天天听别人说 C++ 很复杂, 学习周期很长,不敢碰 C++。万事开头难,那我们就先看看猪怎么跑,然后再尝尝猪肉的味道吧。找一些著名的开源项目的代码,看看人家怎么谋篇布局的,目录结构怎么样,模块怎么划分,文件怎么命名,函数怎么命名,单元测试怎么写,使用的什么框架,这些都是值得学习的财富。
好的品味,决定你自己写出来的代码的品味。正如读书品味低的人绝世夜凰,绝对不可能写出好的文章。品味高的人,看到一般文字,难以卒读。有文字癖的人,读《三体》都难以下咽。对代码挑剔的人,看到不符合规范的代码,心生厌恶,自然对 code review 提出各种各样的建议,看到代码库里的代码不够漂亮,自然生了大刀阔斧重构一把的冲动。
那么对写代码而言,有哪些代码值得读读呢?世界名著很多,著名的开源项目也很多。大家可以在 github 上搜索下,看看“眼睛是雪亮的”的群众,都给哪些好项目“点赞”了。假如按照方向划分,随便举一些:
浏览器:Chromium, Firefox
搜索引擎:Lucene, Nutch, Xapian
机器学习:Tensorflow, MxNet
正则表达式:RE2
日志:log4j, glog
命令行解析: gflags
Web 服务器:Apache, Nginx
数据库:Mysql,SqlLite, Mongodb, Redis, leveldb
P2P:Emule
正如世界名著不是阅读越多越好,好的开源项目也不是读越多越好,并且读代码不像读武侠小说一般,可以一目十行。书贵在读破,而代码贵在读通。没读懂的书,看过了就还给作者了,没读懂的代码,也仅能当吹牛的谈资。读代码开始时,可以一行行阅读,做到每一行都读懂。读多了,自然就不用在意每一行怎么写,多注意一下整体架构,核心功能的实现技巧等即可,简言之,得其精髓即可刘海北。
系统阅读三到五个开源项目,是快速提高代码品味、代码质量的最佳途径。
可惜的是,进入了快餐文化的时代,阅读经典的人已经越来越少,经典卖得多,但是往往被束之高阁。对技术人而言,我面试的几百上千工程师里,曾经系统阅读过一两个开源项目的人也寥若晨星。
读总比写简单,然而会读的人却不多。
两句三年得,一吟双泪流
这句诗是贾岛写的。诗人贾岛人称“苦吟诗人”,“郊寒岛瘦”里的岛就是指的他,他有一个“推敲”的故事。相传贾岛曾作诗:“僧推月下门”,后欲改为“敲”,但又觉得各有千秋。在马上捉摸不定,不慎撞入了韩愈的车队里,大失礼节。后经韩愈点拨下,改为“僧敲月下门”。
著名诗人尚且为了两三句话,修改经年,何况普通作家。本人之前曾经写有一些博客文章,后来开了个公众号,便搬运了一些过来。之前博客更像是个人日志,心情随笔,而公众号既然带“公众”二字,自然是有面向读者之意,写作的时候也会更为小心谨慎一些,废话自然得少说。因此搬运到公众号后,对很多之前的文章都做了删改,删除了很多不必要的字句,段落。搬运了十几篇文章,做了各种“重构”,也算是小有心得鹿鼎记娄艺潇。
比如之前的博客文章《金庸参禅》,修改为《金庸江湖话禅机》在公众号重发过,原文有以下一段文字:
无名扫地僧,是一个巨大的存在,对江湖人士而言他是最最难读懂的。他的无名,他的正常得不能再正常的平凡。按理,他应该是一个刺叱咤风云的人物,不说像独孤求败一样扫遍天下无敌手,称霸武林,也应该为江湖恩恩怨怨是是非非主持公道!然而飞影电影城,他不,他扫他的地,他念他的经,江湖上的厮杀血腥和恩怨情仇和他无关,“天下兴亡,老僧无责”石啸天!他只度有缘人。在乔峰慕容复和一干观望的武林人士看来,扫地僧兴许是不无暗淡的,然而,在慕容博和萧远山看来,他却是恐怖的,黑洞般的恐怖,同时也是佛光普照的。扫地僧之于江湖英雄们的难读,有如老子之于中国历史的难以解读。
上面这段比较长,公众号读者一般喜欢阅读比较简短的段落。搬运到公众号后,修改如下:
无名扫地僧,一个巨大的存在,对江湖人士而言他是最难读懂的。难懂在于他的无名,在于他正常得不能再正常的平凡。
按理,他应该是一个刺叱咤风云的人物,不说像独孤求败一样扫遍天下无敌手,称霸武林,也应该为江湖恩恩怨怨、是是非非主持公道!
然而,他没有。他扫他的地,他念他的经,江湖上的厮杀血腥、恩怨情仇和他无关。“天下兴亡,老僧无责”!他只度有缘人。在乔峰慕容复和一干观望的武林人士看来,扫地僧兴许是不无暗淡的。然而,在慕容博和萧远山看来,他却是恐怖的,黑洞般,同时也是佛光普照的。扫地僧之于江湖英雄们的难读,有如老子之于中国历史的难以解读。
以上修改最主要的区别就是:一段话修改为三段了。此外,删减了一些字,也加了一些连接词,使得整体更自然,更合语法,长短句相结合,阅读的节奏感也更好一些。此外,也加了一些必要的标点符号,相比之前的随意性,更显严谨。
写文字是“两句三年得,一吟双泪流”,写代码便是“重构再重构,怎么也不够”。
说到写代码,虽然不至于两句三年得,但是一个复杂的软件,上千人写上两三年也是有的。比如我最近阅读的李开复的《世界因你不同》,其中提到著名的 Windows Vista 系统,整个系统开发了两年多后,宣告失败,使用新方案从头写起,可见它便是一个比较典型的“一个系统三年得”的例子。当然像操作系统这样复杂的软件,为了实现性能优化,往往是很多天才软件工程师优化很久,才能在 benchmark 结果中 PK 掉对手,或者达到 KPI。
文艺作品,关键的章节,需要重写再重写,比如著名的《百年孤独》的开头(“多年以后,奥雷连诺上校站在行刑队面前,准会想起父亲带他去参观冰块的那个遥远的下午。”)。比如《红楼梦》的书名和章回标题,由多个版本,书名就有《风月宝鉴 》、《石头记》、《情僧录》、《金陵十二钗》和《红楼梦 》等。
工程项目,对性能很关键的代码段,值得优化再优化,因为每一次改进都值得。重要的项目,值得再三重构。听说谷歌的代码几年就会重写一次,每写一次都会更上层楼。
对自己的代码动刀子的程序员,都是勇士。对别人的代码动刀子的程序员极品特工女皇,都是豪杰。
简洁是一种美德
懒婆娘的裹脚布是越长越臭,而美女的裙子却越短越迷人。美女的裙子如是,文章如是,而代码也如是。
《哈默雷特》提到“Brevity is the soul of wit”,文章固然是言以简为贵,而代码亦不例外。
比如,能一个函数搞定的厦门e部落,绝不要搞成一个类,能命名搞定的绝不要画蛇添足加一堆注释。当然把什么都塞到一个文件的代码,是可怕的例外,曾经重构过搜索的一个知名开源项目 sphinx , 这个项目就创造过一个神迹——一个文件超过上万行代码,几十个类!
简洁是一种美德,因此大作家的文字总是简洁到不能再简洁,仿如刀刃雕刻一般。《老人与海》足够简洁,徐明朝福楼拜足够简洁,唐诗宋词足够简洁。而各种八股文,赋体骈文,看似作者才华横溢,文章流光溢彩,在行家里手看来,却是不值一提的酸臭文章。简洁的好文章自然是“不废江湖万古流”,这类文章则是“尔曹身与名俱灭”,速朽罢了蒙克其其格。
好文章简洁是美,好代码简洁是妙。
平时在写代码的时候,能使用标准库函数,就应该使用库函数。能使用公司代码库里的函数,就应该使用。有几个事情需要做的:
熟悉标准库。包括 C 标准库,C++ STL 库,POSIX API 等。
构建公司的基础代码库,并在新人入职的时候进行必要的培训。
写函数的时候,要有天下为公的意识。如果写的代码是有普世需求的,就应该尽可能写得通用,放在公共库里。对文艺而言,普世小说容易流传,普世的人性容易得到共鸣;对代码而言,普世的需求造就高频使用的公共代码库。
推行严格的代码审查。让简洁之风吹佛整个工程团队。让冗长的,冗余的代码消失于无形。比如折掉超过 80 个字符的代码行,干掉超过 40 行的函数,拆掉超过二三十个方法的类。
避免重构造轮子。“君子性非异也,善假于物也”。团队应该引入实现高效、代码优雅的开源项目。作为团队的管理者,更应该经常关注行业相关的开源项目进展。
披阅十载,增删五次
曹雪芹为了《红楼梦》一书,举家食粥。虽然生活困难,写作的标准并没有降低,他没有转而去写《金瓶梅》续集(虽然和《金梅瓶》有继承关系),也没有写言情小说,也不写类似三言二拍的小说。他只写“千红一窟万艳同杯”的大悲剧。
大家写文章一般一遍过,谁爱看就看,不爱看拉倒。最近不是流行“佛系”文化么,随缘就好,对文章认真的人越来越少,对语言认真的人也越来越少,能使用“活泼”的网络语言,就使用上,赶赶时髦。虽然知道是错别字,却也要“有意为之”。
“顽主”的心态,曹雪芹接受不了。他曾经批阅十载只为红楼,增删五次为十二钗千城破。
鲁迅说过:“写完后至少看两遍,竭力将可有可无的字、句、段删去,毫不可惜”,鲁迅这么说,也是这么做的。看看他的手稿:

好文章经得起推敲和删改,好代码当然也经得起锤炼和重构。关于重构有几点体会:
1,要掌握常见的重构技巧,熟读《重构》这本经典。这本书总结了很多常规的重构技法,比如抽取子函数,冗长函数分解,避免嵌套过深等。
2,不要光说不练,更不要纸上谈兵,把《重构》里提到的方法,在实际开发中都一个个使用下,兵士要多操练上战场才能勇猛杀敌。你读了一百本文艺书,写的文章可能还是小学生日记水平。只有实践一遍,才能领会到“纸上得来终觉浅,绝知此事要躬行”。
3,重构代码不要怕,要胆大心细。笔者曾经看过很多烂代码,大部分人都小心翼翼绕过,彷佛一堆发着恶臭的垃圾,唯恐自己碰到了它,怕哪天相关的服务挂了,怪到自己的头上。一旦一个服务不稳定,靠重启解决,一天不解决,半个月不解决,那么一般一两年后都不会解决,业界“常见”的做法往往是写个脚本定期重启(听百度的一个朋友说,他们就曾经这么干过)。后来者往往心很大,胆很小,天天骂娘,没人去解决。笔者在工作中,重构过几次大规模的代码,最大的一次重构项目代码不下十万行。我一开始也是小心谨慎,毕竟没做好,吃力不讨好。不过经验告诉我,如果做好了,很容易得到大家的一致认可。后来重构上瘾了,看哪不爽改哪里。
增删文章和代码的时候,可心中常念:
这里的文字(代码)能删除吗?
这里的文字(代码)怎么似曾相似?
这里的文字(代码)放在这里合适么?放前面好还是放后面好?
这里的文字(代码)是不是少了点注释,少了点背景说明?
这里的文字(代码)是不是太晦涩了,读者能看懂么?是否有炫技嫌疑?
这里的文字(代码)能不能使用个成语或者俗语(库函数),尽量简短d9和弦,以一当十?
这里的文字(代码)会不会力道不够(性能不好)?
纂成目录,分出章回
这句话说的还是《红楼梦》陈韵伊。《红楼梦》是章回体小说,回目的设计独具匠心,有兴趣的读者可以参考李劼《论红楼梦》一书的第五章《名词的垂直联想和回目的对比设计》。比如前两回的标题为:
第一回 甄士隐梦幻识通灵 贾雨村风尘怀闺秀
第二回 贾夫人仙逝扬州城 冷子兴演说荣国府
对小说而言,章回和目录有其好处,方便读者大概得知该章节的内容。当然,极其厌恶朋友圈剧透的同学,可能会觉得目录难以接受。不过一般出书,目录和标题还是非常重要的,不管是文艺书籍还是技术书籍。
有一些书籍,光看标题就觉得有趣。比如笔者之前买的《数学的天空》,目录就很有趣,这里附上部分以飨读者:
第四章 天籁之音 —— 黎曼假设引言 数学乃音乐之魂第一节 大音希声 —— 音乐与数学第二节 和声绕梁 —— 音色与无穷级数第三节 天籁之音 —— 黎曼假设第四节 大开眼界 —— 黎曼的非平凡零点第五节 星火燎原 —— 锲而不舍的零点追踪第六节 不可或缺 —— 失去黎曼假设, 人类将会怎样
第五章 大象无形 —— 庞加莱猜想引言 自然乃数学之书第一节 苍穹之外 —— 地球是球, 宇宙是什么第二节 大象无形 —— 放眼宇宙之拓扑学第三节 未卜先知 —— 庞加莱猜想第四节 海阔天空 —— 高维的召唤第五节 雷霆万钧 —— 几何化猜想第六节 倚天屠龙 —— 从灵魂深处到宇宙之巅
文章如此,代码如是。
好的项目,模块划分合理,每个模块都有取得妥当的目录名。目录下的文件名,则有章有法,符合一定的命名规范。最重要的,从目录名,文件名,到 namespace 名,类名,函数名,变量名,都是自带信息的索引。假如把目录当作书籍的索引,那么代码中的各种名字王真洁,就是为代码建立的多级索引。索引建得是否高效,就如同迷宫是否好走,有好的名字,身在迷宫的代码阅读者,自然就容易按图索骥,快速通读,或者快速定位某个功能的代码。
我自初中起养成阅读书籍的习惯,开始了眼高手低的尴尬之旅。虽几经练笔,终归还是作家梦碎。右手诗的梦,我没有放弃。今年开了个公众号,继续锻炼文字,培养感觉。不指望有炉火纯青的一天,却也希望能够意到字出,我手写我心顾国宁。
我自高中时开始接触电脑,大学开始练习打字,大二开始学习 C 语言,期末考试几乎挂科。左手程序的梦,我也重新捡起。大学期间写代码很烂,那我就研究生期间恶补功课。我坚信“亡羊补牢,未为晚也”的道理,因此我读代码,写代码,用代码养家糊口,在居之不易的帝都,却也还不至于举家食粥。
文章写得还不够多,代码也还写得不够好。所幸,这篇文章只是一稿,也许在将来退休的时候,会回过头来写二稿,到时更上一层楼的希望还在。希望还在,梦就还在。
左手程序右手诗,是我的儿时梦想刘会凤,也许也是你的梦想。希望这一番左右互搏的粗浅功夫,能博得你的会心一笑。这也是本公众号取名“技艺丛谈”的缘故,“技”者技术也,对应的是左手程序,“艺”者艺术也,对应的是“右手诗”。
当然,不是每个人都是武学天才,不是每个人都能够练就“双手互搏”的至高武学。
不过,在这一亩三分地,做到如老顽童一般对技术和艺术童心不改倒尚有希望,毕竟我的地盘我做主,此命由我不由天嘛。“谈技术要有趣,论艺术要飘逸”是公众号的追求,正如《离骚》所言:“亦余心之所善兮,虽九死其犹未悔”。
图源:来自互联网