标签 Blogger 下的文章

代码评审·CC2e·断言·其它

一口气读了七章"Code Complete 2nd(以下称CC2e)"中的内容,从第七章的"高质量的子程序"到第十三章的"不常见的数据类型"。之所以一口气读这么多,是因为被其中的内容吸引了。这两天的下午一直在做代码评审,所以晚上看CC2e的时候,思维不停的在项目代码和书中内容之间跳转。一直把"代码大全2nd"当作一门百科全书式的手册类图书,买回来后一直陈放在书架上没有问津。直到今天在考虑一个关于断言使用的问题时,才想起来去查查这本百科全书,想看看书中是如何阐述断言的。于是便拿起了这本书。

细致的看了2页后才发现,这本书真是很棒啊。其实我们在平时编码过程中遇到的问题在书中基本都覆盖到了,而且说的很到位。如果你能提前看看书中的陈述,想必你在开发过程中会少走很多弯路。这里列举几点,也是我们项目代码里处理得不到位的地方。

断言 vs.错误处理
在昨天评审代码时,发现一位同事在整个模块代码中对接口参数的防御性代码都很不得当;对于内部接口调用,他对可信赖的参数使用了错误处理的方式,如果参数值未按预期,代码直接返回此次调用的结果状态了。关于到底用断言还是用错误处理,估计很多人都很迷惑。'代码大全'里的总结是我见到的最清晰的了。对于来自系统外部数据(包括数据库、文件、网络等)的校验,我们采用错误处理的方式;对于内部接口之间的参数传递,断言更适合。另外对断言而言,断言失败意味着代码中的bug,你应该做的是停止程序,定位问题,重新编译、发布和启动程序。另外'代码大全'中引入了'Barricade'的概念。它建议你在代码中建立所谓的"安全区",安全区外的数据想通过安全区必须通过严格的合法性检查,当非法时给予敏锐的反应;安全区以内将假定数据都是干净的、安全的。而实际上这个"安全区"在项目里很有可能就是一组函数接口,这组接口采用错误处理的方式对待安全区外的数据,保证非法输入不流入内部系统。

断言是否放入产品代码
关于这个问题,更多人坚守的是"断言一定不能出现在发行版中",即一般的看法:断言只是在开发阶段帮助程序员定位bug的工具,Release阶段断言语句将从代码中自动去除。CC2e作者在书中似乎(也许是我没有看到?)并没有肯定的支持这种观点,只是在其"Guidelines for using assertions"一节中委婉的表达出了一个建议:在生成产品代码时,可以不把断言编译进目标代码里去,以免降低系统性能。在另一本大作"编程珠玑2nd"中,作者Jon Bentley间接引述了Tony Hoare的一个观点:"在测试时使用断言,而在产品发布时将断言关闭的程序员,就像是在岸上操练时穿着救生衣,而下海时将救生衣脱掉的水手",观点不言而明。在当今硬件设备性能已经很好的年代,断言产生的那些开销多数情况下已经"不足挂齿"。那什么才是决定断言是否继续留在产品代码中的最大影响因素呢?我觉得还是因产品而异。前面说过断言如果出现,就意味着程序里是存在bug的。那我们是尽快让产品bug暴露出来呢?还是在程序已经伤痕累累的情况下,继续让其前行呢?产品继续运行带来的后果是否是可忍受的呢?说来说去,还是一个评估和决策的过程。对于类似对癌症病人做化疗的控制软件来说,如果运行异常,想必及早关闭程序是最好的选择,这可是性命攸关的大事。那对于这类程序,断言是一个更好的辅助提前检查到bug的工具,加入Release版也无妨。在我所在的项目产品中,我们选择了将断言保留在产品代码中,我们希望bug能越早暴露越好,千万不能让系统带着缺陷持续运行下去,这样到后期系统将会出现莫名其妙的甚至无法跟踪定位的问题了,到那时可真就不好与客户交代了。当然断言失败后的处理方式也是多种多样的,做好适当记录,保留好现场轨迹,让子进程稳妥地崩溃退出,有时是可以接受的。

函数 vs.过程
说到这个话题,不免会有些"钻牛角尖"的感觉。使用C/C++的人已经习惯了"函数"的这个称谓,少有人去特意区分函数与过程的差异,或者在工作中花心思去考虑到底应该用函数还是过程。在C/C++甚至很多其他现代语言中,函数与过程没有语法上的差异,如果说有什么不同,那就要从纯语义上去区分。我们从小就开始学数学,大约在初中(有些地区在小学的高年级,有否?)开始了函数的学习。回忆一下数学上的函数是什么样子的,多亏手头上有一本"什么是数学",翻看了一下,数学上的函数大致是这样定义的:"对于变量X的任何一个值,都存在另一个变量U的确定的值与它相联系,这时U就称作是X的函数,记为U = F(X),其中X是自变量,U是因变量"。数学上有很多著名且常见的函数,诸如sin(x)、cos(x)等。按照数学上对函数的理解,一个函数有输入变量(参数),有唯一的因变量(返回值),函数名字根据返回值的含义而命名,如sin(x)。对比一下我们平时在编码中设计的函数,发现似乎不那么一样。因为我们没有严格按照数学上理解的函数去定义我们的函数原型。但在我们开发过程中也不乏符合数学上理解的函数,如标准库中math.h中,诸如:
double sin (double x);
double cos (double x);
double tan (double x);

与函数不同,严格意义上的过程应该是一个没有返回值,但接受任意数量输入、修改和输出参数的。这样综合起来,其实我们在平时更多的是在使用纯意义上函数和过程的综合体 — 带返回值的过程,且命名偏向过程。比如strtol。以下应该是我们常见的两种代码里routine的使用方式,第二种则是一个标准的过程的调用。
invoke_status = sub_routine(var_1, var_2, …, var_n);
sub_routine(var_1, var_2, …, var_n, &invoke_status);  

使用以上哪一种是见仁见智的事情,估计也和组织的编码风格有关系。

离开太原

飞机缓缓的降落在沈阳桃仙机场,我完成了近10天的出差任务,终于回到家了。沈阳的温度和太原相比还是有些低的。坐大巴到马路湾,打车回家。家里还未给供暖,身体感觉有些凉,还好心还是温暖的,毕竟到家了,回家的感觉真好。

今天上午应客户要求做一个产品升级后的培训,这可是出差期间的最后一个任务了。早上7:30起床,洗漱后下楼吃早饭。9:00出发直奔客户的大楼。我们一行四人,还有两位技术支持工程师去客户那参加一个故障总结会,我们的另一个产品似乎在昨天出了些问题,让客户方的领导知道了,抓住不放。我们的回家机票已经订好,是下午2点半的。给客户培训完已经是中午了,正当我们要走的时候,我那两位技术支持的同事开会回来,告知我们他们下午走不了了,客户要求现场写故障报告。没办法,只能我和另外一个同事先回宾馆。车上同事还抱怨着:不去客户现场什么事情都没有,一到客户现场什么事情都发生了。

到酒店已经正午12点半了,还好有会员卡可以延后一个小时退房,午饭也不吃了。打车去机场。在太原去机场绝大部分出租车是不打表的。后来从出租车司机口里得知,机场的出租车业务被机场交管部门和一部分出租车给"霸占"了。外来车辆如果在机场拉活儿的话,一旦被摄像头拍到,事后就会收到罚单,所以一般从市里到机场的出租车回城时基本是空车,打表来说对他们不合算。但是在太原打车还是有一个技巧的,听司机说太原出租车分为红顶、蓝顶和其他颜色顶的。红蓝顶出租车都是服务标兵车,这些车一般不敢拒载,也不敢不打表。因为这些司机都交了服务保证金了,一旦被客户投诉一次,就会被罚数千元,所以在太原打车尽量看车顶颜色。

说到山西,我们不能不说到“醋”,要说全国老醋哪最好,估计哪也比不了山西。来山西出差的同事一般别的都不带回家,都带上几瓶甚至成箱的老醋。以前来过山西的同事推荐宁化府的老字号陈醋,这不昨天他们打车到宁化府买了三箱醋,前面提到了两位技术支持同事每人一箱,我要的少-两桶,每桶1500ml左右,14元一桶。估计够我吃上两年的了。遗憾的是除了醋没有发现其他值得一带的本地特产,在饭店吃了平遥牛肉,感觉一般。索性也就没有带。

到飞机场时离飞机正点起飞还有1个半小时,时间是比较充裕的,再加之太原武宿机场客流量较小,所以checkin和security check都很快。订票前我在网上查看了太原和沈阳的天气,都很好,想必飞机应该准时起飞。但是遗憾的是广播里传出飞机因空管监控无法按时起飞,起飞时间待定的消息。原来这架M90飞机是从西安始发的,经停太原而已。而西安的天气似乎不太好,这时才觉得自己的准备工作做得还是不够完美。无奈只能等了。还好时间不是太长,晚点一个小时后,飞机终于来了。

这次我的座位被安排到了飞机的后部,以往坐飞机都坐在中前部,在尾部有些不适应,或者感觉飞机后部的危险性更高,在飞机后部可以很清楚的看到飞机起飞时整个飞机座舱在摇晃和扭曲,当然了是轻微的。M90引擎也在尾部,导致这个地方噪音特别大。

到达沈阳时,整座城市已经是万家灯火了。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言进阶课 Go语言精进之路1 Go语言精进之路2 Go语言第一课 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats