程序员成长指南之提升代码“可靠性”
码农修行
如何提高代码的可靠性
产品质量和可靠性息息相关。有的软件经常会崩溃、有的功能时好时坏、有的系统隔一段时间就得做一次重启。这都是可靠性不高的表现。软件的可靠性和每一行代码都息息相关。任何一位软件设计师都有可能把软件搞崩溃,因为稍有疏忽就可能出现非法指针、内存错误等问题,而这类问题都是致命性的。因此每一位软件设计师都要对可靠性心存敬畏之心,对每一行代码的质量负责。系统的可靠性除了代码层面的可靠性外,还包含其他方面的内容,比如子系统间的核查、自愈、容错、容灾等方面。影响系统可靠性的因素非常多,抛开系统自身的因素,就外部因素而言又包含各种场景。比如网络延时、丢包、中断、非预期的输入、流量激增、系统断电、硬件故障等。不过这些因素已经超出了本书所讨论的范畴……本文仅就编程阶段一些与可靠性相关的细节给读者一些提示,希望读者能从基础的地方筑牢系统可靠的防线。
码农修行
提高代码可靠性的重要法则:避免过度防御
非法指针是C/C++程序中最令人头痛的问题之一。你也许会有类似的习惯,在函数入口即对指针的合法性进行检查。代码如下。
即使在调用该函数前已经做过一次检查。代码如下。
这两处检查都属于过度防御,完全没有必要。首先,参数的合法性应该由调用者保证。可以参考一些参数为指针的API,比如strncpy,当对其强制传入一个空指针时,程序并不会悄无声息,而是会抛出异常。
因为这样的参数已经违反了接口的规约,函数内部不知道该如何处理,只能抛出异常让程序崩溃。此外,就指针而言,哪些属于非法指针,哪些属于合法指针其实很难界定。对于上面的例子,假设调用者强制传入一个“1”,其实程序也会崩溃。
空指针只是非法指针中的一种而已,对于其他情况更是防不胜防,关键要划清责任范围。
过度防御还会造成大量冗余代码,因为很多类似这样的分支是永远不会执行的。
更令人沮丧的是,过度防御可能会增加某些问题定位的难度,因为没有在出现问题的“第一现场”暴露问题。假设一个交易系统中定义了一个带有过度防御功能的StrNCpy函数。代码如下。
在交易成功后需要保存订单,SaveOrder中使用了StrNCpy进行字符串复制,组装了一个Order数据结构,并调用DB_SaveOrder存入数据库。代码如下。
假设由于某个bug(漏洞)导致上层传入的“公司名称”companyName为一个空指针NULL。由于StrNCpy的过度防御,该函数“悄无声息”地执行完毕,让SaveOrder“误以为”数据复制成功,并将信息写入数据库。当消费者想要根据这张订单开具发票时,结果发票开具失败。
通过分析发现数据库中该订单的“公司名称”字段没有内容,这是导致发票开具失败的直接原因,因为购方企业名称是发票开具流程中的必填参数。
这个字段为什么没有内容?是一开始就没有?还是后来被误删除了?这需要翻阅大量的日志,才能分析定位该问题。但如果改用符合接口规约的API函数,那么在保存订单时程序就会抛出异常,及时暴露问题,像上述那样不完整的订单信息就不会写到数据库中。以下代码中将StrNCpy替换为strncpy。
那么正确的保护方法应该是什么?答案是:在可能出错的地方进行保护,做“正当防卫”。比如上面的例子中,假设入参name是通过new动态申请的。
new申请动态内存可能会失败,因此需要在申请返回后进行保护。
当然Java语言情况稍好一些,new不会返回null,因此不需要类似的保护。但有一种情况需要注意,如果一个对象是通过某个方法获取到的,就需要关注该方法是否可能失败,如果是就需要在返回的地方加以保护。
以上内容节选自:《码农修行,编写优雅代码的32条法则》林文 著
- Delphi程序员代码编写标准指南
- 程序员的精益成长指南3:不得不知道的13个问题
- 学习《如何提升程序员的代码编写能力》文章笔记
- 程序员代码面试指南--设计一个具有getMin功能的栈
- 《C++精英内参之程序员高效指南》-11常用的读代码方法除了写注释的,还有其他方法
- 程序员代码面试指南之python编程:数组和矩阵问题
- Delphi 程序员代码编写标准指南
- 程序员代码面试指南--猫狗队列
- 开发者是如何提升技能水平的 发表于1小时前| 770次阅读| 来源SquareSpace| 1 条评论| 作者Denis Gobo 开源程序员博客代码编程经验分享 摘要:作为一个技术开发人员,不断的学
- 程序员逼格提升完全指南
- 程序员跨越式成长指南
- 代码可读性提升指南
- 程序员如何提升自己的代码质量?
- 程序员的精益成长指南1:关于变现、技术领导力和成为Leader
- Delphi 程序员代码编写标准指南 (二)
- Atitit.提升 升级类库框架后的api代码兼容性设计指南
- 《C++精英内参之程序员高效指南》-22提升效率的三板斧
- Unity游戏开发程序员学习线路图及技能提升指南
- 程序员代码面试指南:IT名企算法与数据结构题目最优解-字符串问题:C/C++语言实现
- 程序员代码面试指南 python实现(第一章 栈和队列 :如何仅用递归函数和栈,实现一个栈的逆序)