您的位置 首页 基础

工程师13年编码、测验和调试经历大汇总

  在《Learning From Your Bugs》一文中,我写了关于我是怎么追寻我所遇到的一些最风趣的bug。最近,我回忆了我全部的194个条目(从13岁开端),看看有什么经…

  在《Learning From Your Bugs》一文中,我写了关于我是怎么追寻我所遇到的一些最风趣的bug。最近,我回忆了我全部的194个条目(从13岁开端),看看有什么经验教训是我能够学习的。下面是我总结的最重要的经验教训,包含编码,测验和调试三个方面。

  编码

  下面这些都是我经历过的会导致难点bug的问题:

  1.作业次序。在处理作业时,提出下列问题会很有成效:作业能够以不同的次序抵达吗?假如咱们没有接纳到此作业会怎么样?假如此作业连续产生两次会怎么样?哪怕一般不会产生,但体系(或交互体系)其他部分的bug或许会导致作业产生呢。

  2.过早。这是榜首点“作业次序”的一个特例,但它确实会引起一些扎手的bug,因而我把它独自拎出来阐明。例如,假如信令音讯在装备和发动程序完结之前就被过早接纳,那么或许就会有许多古怪的行为产生。另一个比如:衔接在被放进闲暇列表之前就被符号为down。在调试这类问题时,咱们总是假定在闲暇列表中的时分衔接被设置为down(但其时为什么不把它放到列表外面呢?)。这是咱们考虑的缺乏,没有考虑到有时分作业会过早产生。

  3.悄然无声的毛病。一些最难盯梢的bug有部分是由那些静静失利并扩展而不是抛出过错的代码所导致的。例如,没有查看代码却回来过错的体系调用(如bind)。又如:解析代码在它遇到过错元素的时分仅仅回来而非抛出过错。在过错状况中继续了一段时刻的调用,会使调试变得更难。最好一旦检测到毛病就回来过错。

  4.If。有若干条件的if句子,if (a 或 b) ,特别是当有链接的时分, if (x) else if (y),都给我引发了许多bug。即便if句子在概念上很简略,但当有多个条件要盯梢的时分仍然很简略犯错。这些天,我测验重写代码使之更简略,以防止处理杂乱的if句子。

  5.Else。有一些bug是由于没有正确考虑到假如条件为false时会产生什么而引起的。简直在全部的状况下,都应该有一个else部分来应对每一条if句子。此外,假如你在if句子的分支中设置变量,那么或许你在另一个分支中也要设置。与此种状况相关的是符号被设置的状况。只增加用于设置的符号的条件不难,可是很简略忘了增加当符号应该再次重置时的条件。留下一个永久设置的标志或许会导致之后连续不断的bug。

  6.改动假定。许多一开端最难防备的bug是由于改动了假定所形成的。例如,在开端时,或许每天只要一个客户作业。所以许多代码是在这样的假定下写下的。可是后来,规划改动了,答应每天有多个客户作业了。产生这种状况时,很难改动新规划影响到的全部状况。找到关于改动的全部显式依靠联系不难,难的是要找到全部隐性依靠于旧的规划的状况。例如,或许会有获取给定某一天全部客户作业的代码。其间的隐含假定是成果集永久不会超越客户的数量。关于这方面的问题我也没有很好的战略办法,假如各位有的话,还请不惜赐教。

  7.日志记载。可视化程序做什么至关重要,特别是当逻辑很杂乱的时分。保证弥补足够多的(但不要太多)日志记载,这样你就能够阐明为什么程序要这么做。假如全部正常,那也没联系,但要是有问题产生,你会很幸亏自己增加了这些日志。

  测验

  作为一个开发人员,直到要测验了我才会去处理功用。至少,这意味着每一行新的或改动了的代码行至少现已被执行过一次。此外,单元测验和功用测验都很不错,但还不行。新的功用也有必要进行测验,并在类似于产品的环境中探究。只要这样,我才能说我完结了一个功用。下面是我经历过的bug所教会我的关于测验的一些重要的经验教训:

  8.零和null。假如可行的话,保证总是用零和null来测验。关于字符串,这意味着要测验长度为零的字符串以及字符串为null两种状况。又如:测验TCP衔接的断开,要在发送数据给它发送之前。不运用这些组合办法测验是导致bug呈现的首位原因。

  9.增加和删去。一般,新的功用包含能够增加新的装备到体系中——例如,一个用于手机号码转化的新的装备文件。测验它能否增加新的装备文件是很天然的。可是,我发现咱们很简略忘掉去测验删去装备文件是不是相同ok。

  10.过错处理。处理过错的代码往往是难以测验的。最好有能查看过错处理代码的自动测验,但有时这是不或许的。我有时会运用的一招是暂时修正代码,使得过错处理代码运转起来。要做到这一点最简略的办法是回转if句子——例如,从if error_count 》 0改成error_count == 0。另一个比如是拼错数据库列名,然后导致期望的过错处理代码运转。

  11.随机输入。一般,揭穿bug测验的一种测验办法是运用随机输入。例如,H.323协议的ASN.1解码运用二进制数据操作。经过发送随机字节去解码,咱们发现了解码器中的几个bug。另一个比如是用测验呼叫来生成脚本,此刻呼叫继续时刻,接听推迟,榜首方挂断等等都是随机生成的。这些测验脚本会露出许多bug,特别是一同产生的作业会产生并拢搅扰。

  12.查看不应该产生的动作。一般测验包含查看期望动作是不是产生了。但咱们很简略忽视相反的状况——忘掉查看不应该产生的动作是不是确实没有产生。

  13.具有东西。我创建了自己的小东西,以使得测验愈加简略。例如,当我用VoIP SIP协议作业时,我写了一个能够用正是我想要的标题和值回复的小脚本。这个东西使得测验许多鸿沟状况变得简略起来。另一个比如是能够进行API调用的一个命令行东西。经过发动逐步增加所需小功用,我得到了一些十分有用的东西。自己写东西的优点是,我得到的正是我想要的。

  在测验中发现全部的bug,那肯定是不或许的。有一个事例中,我更改了数字相关性的处理,数字由两个部分组成:路由地址前缀(一般是不变的),以及从000到999动态分配的数字。问题在于当找到相关性时,动态分配的数字的榜首个数字会在呈现在表格中之前遭到误删。也就是说637变成了37。这意味着,到100之前它都是能够作业的,因而,前面100个电话是正常的,可是接下来的900个都是失利。所以,除非我在重新发动之前能够测验超越100次(现实是我没有),不然我在测验时就不会发现这个问题。

  调试

  14.评论。协助我最多的调试技能是与搭档评论问题。一般状况下,仅仅和搭档阐明问题,就会让我意识到问题的症结。此外,即便他们不是很熟悉有问题的代码,他们也往往能提出一些好点子。与搭档评论在处理最难的bug时特别有用。

  15.亲近重视。一般,假如调试问题花了很长时刻,往往是由于我做了过错的假定。例如,我以为问题产生在某一办法中,但现实却是它乃至从来没有抵达那个办法。或许,被抛出的反常不是我以为的那个。或许,我以为软件的最新版别上正在运转,但其实是一个旧版别。因而,一定要核实细节,而不是假定。人们更简略看到自己期望看到的东西,而不是现实。

  16.最近的改动。当从前能够正常作业的东西停止作业,那么这一般是由于最近改动的东西所导致的。在一个事例中,最近的改动仅仅日志记载,可是日志中的过错却导致了一个更大的问题。为了更简略找到这种回归,供认不同的提交会导致不同的改动,以及清楚阐明这些更改会有所裨益。

  17.信任用户。有时,当用户陈述问题的时分,我的天性反应是,“这是不或许的。一定是他们做错了什么事”。但我学会了不再用这种办法去回应。更多的时刻,现实往往证明,他们所陈述确实实是实践产生的状况。因而,这些天,我开端承受他们所陈述的内容的标明价值。当然,我仍然会仔细查看全部是否被正确地设置等等。我见过许多这样的状况,让我理解,由于不寻常的装备或意料之外的用法而导致难以想象的作业的产生,而我默许的假定是,他们是正确的,程序是过错的。

  18.测验修正。假如bug修正已准备就绪,那就有必要进行测验。首先在修正前运转代码,并调查该bug。然后使用修正偏重复测验事例。到此为止过错行为应消失。遵从这些过程能够保证它确实是一个bug,而且此次修正确实能够处理这个问题。简略而有必要。

  其他调查成果

  在这13年来我一直在盯梢我所遇到的最扎手的bug,许多作业由此而改动。我作业过小的嵌入式体系,大的电信体系以及根据web的体系。我运用过C ++,Ruby,Java和Python。在作业于C++时所遇到的几类bug现已彻底消失,像仓库溢出,内存损坏,字符串问题和某种方式的内存走漏。

  其他问题,如循环过错和鸿沟状况,我看到的要少得多。可是,这并不意味着那里没有bug。这篇文章中的经验教训旨在协助削减编码,测验和调试三个阶段的bug。假如我们有什么有用的防备和发现bug的技能办法,欢迎不惜辅导。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/jichu/166825.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部