第276期 | 罗剑锋:我的编程技巧和习惯
你好,这里是卖桃者说。
以前我和你聊过很多互联网大佬的故事,比如“Java之父”詹姆斯·高斯林、“硅谷教父”约翰·轩尼诗等等。前几天有用户留言说,极客时间上有这么多优秀的专栏老师,而且都是经验非常丰富的技术大牛,能不能讲讲他们的故事,让自己多了解一些老师的日常。
我觉得这个提议非常好。其实你选择学一个专栏,也是在选择一个老师。优秀的老师不仅能在专业上面给你指点迷津,他的一些人生经历,以及对很多事情的看法,也能给你带来启发。
今天,我就来和你聊聊罗剑锋老师,他是《罗剑锋的 C++ 实战笔记》和《透视 HTTP 协议》专栏的作者。
罗剑锋老师是奇虎 360 技术专家,也是 Nginx/OpenResty 开源项目贡献者。他熟悉各种网络应用协议,专注于 C/C++、Linux、高性能编程等领域,著有《C++11/14 高级编程》《Nginx 完全开发指南》等畅销书。为了方便,接下来我就直接用罗剑锋老师的网名“Chrono”来称呼他。
“入坑”:始于游戏,陷于热爱
Chrono 应该算是“入坑”比较早的程序员了。他从 1997 年就开始接触 C/C++,并于 1998 年获得了高级程序员资质,那会还有这种评级。我前几天和他聊,问他当时为什么选择进入计算机行业,他笑着说这应该是算是他的“黑历史”了。
故事还得从“很久以前”说起。在 Chrono 小时候,家里买了个红白机。因为成绩比较好,Chrono 的父母也没有太限制他玩。玩得多了,Chrono 隐约觉得游戏机里面应该有什么了不得的东西。
后来到了中学时期,Chrono 接触到了红白机上的 GBASIC(GAME BASIC),这是 BASIC 计算机编程语言的一种变体,可以用来写游戏。很多程序员都是从 GBASIC 开始接触编程的,Chrono 也不例外。在他看来,这么多好玩的游戏都是用计算机做出来的,那么,学会写程序应该也是件很有意思的事情吧。
不过对于还是初中生的 Chrono 来说,学习 GBASIC 还是有一定难度的。当时只能做到“照猫画虎”,把里面的示例代码敲进去,虽然可以控制游戏人物四处走动,但对于内部的程序逻辑、运行机制还是一无所知。
到了大学阶段,Chrono 开始正式学习计算机编程,接触的第一门编程语言就是当时传统的教学语言 Pascal。Pascal 语言语法严谨,非常适合用来教学和训练编程思维。
虽然 Chrono 的大学专业并不是计算机,但他学完 Pascal 后也没闲着,又把目光投向了 C 和 C++,开始自学。当时没有老师教,在计算机上实践的机会也很少,他只能反复翻书,用纸笔来模拟运算。不过好在拥有 Pascal 的基础,新语言学习起来也就没那么难了。
凭着这股劲头,Chrono 还在大学期间通过了计算机软件专业技术资格和水平考试,并获得了高级程序员资质。这对他来说是一种鼓励,不过也让他意识到了,软件开发的内涵很广,只有本科的知识是不够的,要想有所作为,需要去计算机系进行专门的深造才行。
本科毕业后,Chrono 又考了研。2003 年,Chrono 正式从北京理工大学毕业,并获得了计算机专业硕士学位。
“要善于搜索,也要避免面向 Google 编程”
在此后的十余年工作中,Chrono 参与过非常多的项目:开发过智能 IC 卡、倒腾过商用密码机、做过政务项目、写过网游核心引擎等等。
回顾这些年的工作经历,Chrono 觉得自己遇到的最大的难题,就是在职业初期缺乏好的资料和工具,很多事情都要靠自学,自己去解决。现在的程序员想找资料非常容易,也有各种各样的专业课程,还有 GitHub、GitLab 等。但在 21 世纪初,整个中国互联网还处于起步阶段,网上的资料非常少,需要什么都得自己动手。
Chrono 当年在 Windows 上开发,用 VC6 写客户端程序、智能卡 COS 和配套的驱动时,需要用到微软的底层 API。当时获取这些资料的渠道很匮乏,手里拿到的只是过时的 MSDN,不够准确,有用的信息也很少。
于是,Chrono 只能采用“笨方法”,不停地试验,这里改改,那里改改,尝试各种排列组合,写各种测试代码去验证。虽然经过了很多的磕磕绊绊,但项目最后总算是完成了,成功应用到了全国各地的海关。
还有一次,Chrono 在工作中要解决“与前端高效传输数据”难题。当时他还没听说过 ProtoBuffer,再加上彼时的 ProtoBuffer 在国内还没有流行开来,于是他决定自己实现一个快速高效的序列化格式。
为此,他花了不少力气,还把 C++ 特性和设计模式深挖了一遍,用上了工厂、组合、解析器、迭代器、职责链等很多模式,天天琢磨怎么设计、怎么优化,代码写了一大堆。直到有一天,Chrono 在网上看到了一篇介绍 ProtoBuffer 的文章,才发现自己这段时间做了很多“无用功”。
不过这次经历也并非全无收获,起码让 Chrono 从中深刻地理解了那句古语:“君子性非异也,善假于物也。”
Chrono 后来感慨道:“历史只会不断重演,你遇到的大多数问题很可能其他人都已经遇到并解决了。所以,要利用好现在发达的搜索引擎和开源网站,多上网搜索,多去社区提问,避免‘单打独斗’。在成熟并且经过验证的方案基础上,解决自己遇到的问题。
当然,这里还要避免另外一种倾向,就是‘面向 Google 编程’。凡事不经思考,网上抓一个就用,这样也很不利于自己的能力提升,我觉得还是再读一下鲁迅先生的《拿来主义》吧。”
在 Chrono 看来,除了要善于搜索,在软件开发过程中,代码的版本管理也非常重要。版本管理相当于“档案馆”和“后悔药”,有了它,你就可以放心大胆地“试错”,探索各种技巧、方向,不用害怕自己的心血会丢失、埋没。
当 Chrono 开发新项目、写代码时,通常首先要做的事情就是建立 Git 仓库,把前期调研、说明文档、原型脚本、数据模型什么的都放进去,让 Git 来“保驾护航”。尽量多开分支,主干可以按用途分成 master、dev、release,然后下面按开发阶段开小分支,最好是每个 feature、每个 bug 都开个独立的分支,然后再用 Merge Requests 的形式逐级向上合并。
这样做的好处是把修改记录由 commit 级别提升到了 request 级别,层次略高一点,粒度比较大,对 Code Review 和历史回溯都很有利。
此外,在工作中,Chrono 也有阅读开源项目的习惯,学习、借鉴他人的智慧结晶。他通常的做法是在 GitHub 上 fork 一份副本,开个分支,学的时候自己加注释,从小的、简单的代码入手,每天有一点进展就行。积少成多,用“蚂蚁搬家”的方式来学习源码,不必追求“一口吃成个胖子”。(可以参考 Chrono 的 Nginx 源码阅读项目)
不过,单纯只“看”代码的效率是比较低的,俗话说“好记性不如烂笔头”,Chrono 还会采用多种其他手段来辅助理解源码。比如画 UML 类图、时序图等等,或者多找一些参考资料,画出思维导图,实现知识点的多维度关联,用可视化、图形化来帮助学习。
从 Chrono 的身上可以看到非常强的学习能力,这也是每个程序员应该具备的能力。他还给刚入行以及想再提升下自己的同学们提了一些建议,具体是什么,这里先卖个关子,咱们明天再接着聊。
最后做个小调查,你自己有哪些编程技巧和习惯?欢迎在留言区一起分享。
卖桃者说,明天见。
(编辑:夏天)