Tag Archives: 代码规范

关于异常机制和编程style

  首先放张照片,程序员责任重大,除了正常逻辑部分,还必须在异常发生时周到地帮助无辜的用户。

  八卦点题外话,是在Google著名华裔程序员王忻(Niniane Wang)BLOG上看到这张照片的。她刚刚发布了引起轰动的Google Lively。新闻里说Lively是工程师20%时间的业余开发成果。考虑到她的年龄只比我大一个月,实在让人绝望呀。 你去看看linux操作系统内核的历代版本负责人,从Linus本人上大学期间发布0.02开始……2.2版、2.4版、2.6版的总维护人都不到26岁 就掌管内核代码主干版本。像大一还没上完就写出抢占式调度补丁的Robert Love(很多人都说他有可能是下一版2.8内核的代码总维护人)这种,都只能算稍微年轻一点的。到了30岁,程序员的黄金时代就过去了,只好靠留大胡子唬人了(Guido van Rossum进了Google以后,真的留起胡子来了,咣当)。

  回过头来说正经的,相对C,C++最有价值的改进就是exception了。这半年来pFind的重构,一 个水面以下的最大变化,就是把以前return false和GetLastError()风格,用throw和try代替。当然这需要大量的体力活,刚开始遇到不少疑惑。但后来所有人都发现这是偷懒的 好方法。一个例子是,老版代码发现一个bug,异常位置和崩溃位置差很远,就是因为前者的return false链条断掉了:出错的函数上面套了11层调用者,有一层没判断返回值。纯C语言的灵活性和直观性的代价是,程序员必须是铁人,有能力妥善处理一切细节。

  有了完整的exception处理机制,一旦出现崩溃,pFind2.1就立刻把运行现场所有的信息都记录 下来,这样有利于调试,特别是无代码,或BUG重现需要很长时间的情况。这两种情况俺们都要面对:pFind将在网上开放下载,散播到世界各地的生物学实 验室;蛋白质鉴定是计算密集型应用,有时候release版运行一整夜才跑到出问题的地方,指望debug版加断点调试是很低效的。

  至于现场信息的携带,没有复杂的异常类继承体系,仅仅依靠字符串。组里聪明的年轻人设计了一个异常信息格式化的类,可以很方便地在每个堆栈展开catch的地方追加新的现场内容。这样一层一层加上去,形成类似JAVA的异常报表。

  常见的疑问是exception有性能问题。可能不同应用要求不一样。经过实际测试,pFind的性能瓶颈不在这方面。似乎新版GCC编译器对此做了优化。

  说到C和C++的比较,很多人可能要提到云风Linus,以及之前关于C++的大论战。 在很多技术问题上赞同云风的观点,甚至有点崇拜。但一直老老实实用C++,没有追随他叛出山门,回到C语言。原因很简单,C++对这个项目更合 适:pFind是一个有二、三十个模块,几十万行代码,十几个人合作,历时五年的项目;它很看重速度和性能,但优化的大头,都在流程和算法方面,除了最关 键的“热点”以外,其他部分不必也不能牺牲代码的可维护性;而开发人员水平又参差不齐,很多人无法达到用纯C开发大型系统必须的素质要求(像前面提到的 bug,传统C风格异常机制下,出错后需要11个函数依次return false,穿越4个不同作者不同时期的代码,只1处懒惰就抵销了其他所有严谨。俺的团队很难达到这种程度的严丝合缝,也没必要付出这么高的开发成本)。 这就注定了C++是唯一的可选项。一直在关注其他各种语言,比如D语言,但现实来说只有C++符合条件。

  Andrei Alexandrescu对这个问题的看法很中肯: 像Linus这样的牛人,他很清楚自己在干什么,开发操作系统内核,合作者都是天才,所以他就真的不需要C++。云风的deepcold引擎很类似,对性 能,尤其是一小段时间内(例如0.2秒内)的数据吞吐反馈能力有严格要求,网易又有一帮真正的geek组成的技术团队。

  C++最大的陷阱就是程序员——尤其是新手——过分追求奇巧淫技的风气。所以在pFind内大面积推广的都 是最朴实的,甚至有点土气的style。例如,继承只在纯虚类接口一种地方使用(具体说就是工厂方法模式);而功能复用都以内嵌对象来实现,不允许继 承。(整天喊口号:“接口上移,功能外抽”)。对神奇的泛型基本回避,限制写模板,熟练使用STL就行了。尽管Andrei Alexandrescu的《Modern C++ Design》里的内容很酷(软件开发2.0大会还专门买了一本新的,请他本人签名)。但pFind团队没有能力把握这种style。

  C++是一种多style语言,架构师需要做的,就是明智地裁剪符合需要的子集。约束团队抵御诱惑,不拿手头的任务当学习新技术的小白鼠。

  BTW1:Python和C++社区的关系很好,很多老牌C++程序员同时也是Python著名玩家,例如豆瓣的阿北。C++标准委员会那帮人甚至在boost里加上了连通Python的内容,还公开说Python是C++的最佳伴侣。Python和C++差异很大,比如是动态语言,比如“所事情只需要一种方法”的设计哲学,这种不同恰恰造成了互补。

  BTW2:最后推荐Google刚刚公布的C++代码规范。哈欠,睡觉去了。