当前位置 > 主页 > 万和大讲堂 >


万和iOS应用开发培训专家解析软件bug的规律

2016-01-19 11:14

  无论是从事应用开发还是从事软件开发都难于逃开一个问题,那就是有关bug的问题,那么为什么改错比犯错更难,尤其在软件工程中,更是如此?


  我们大概都了解混沌和有序,通常不必费力思考原因的一个现象就是,我们更容易给系统创造混沌而非有序。创造比破坏难,原因在于系统内部所具有的混沌状态,要远远大于有序状态。当然,这取决于有序的定义和界定,但是,如果和无序状态比起来,任何合理的定义都会让你得到更少的、可能有序的状态。


  因此,问题就变成了可能状态(混沌)的数量,和相应使其有意义的一个子集(有序)。


  那么,程序代码中的错误是怎么回事?bug究竟是怎样产生的?万和iOS应用开发培训专家为您全解析。


  当你的代码未能按照预期执行时,就说明存在bug了。(让我们把可计算性的话题放到另一篇博文,因为它比较复杂。某个任务在合理时间内,可能有解决方案,也可能没有,不过,我的意图是,存在可做的先验。我们简化一下问题:程序未能按照意图运行。)


  比如,你需要一个函数,它返回两个int值的平均数(整数)。首先,你可能这样写代码:


  int avg(int a, int b)


  {


  return (a + b) / 2;


  }


  正确吗?


  错。它没有考虑可能存在的整数溢出,而两个整数的平均数应该总是介于a和b之间。换句话说,avg()函数被期望总是返回一个(四舍五入)的结果,且不会溢出。


  让我们修复一下。一个新手程序员可能会按照如下方式“修复”:


  int avg(int a, int b)


  {


  return a / 2 + b / 2;


  }


  当然,又错了。


  在某个互联网论坛上,当被问到根据其最初形式修复avg()时,总是会给出建议,要求把参数的数据类型转换为浮点,再把结果四舍五入为int型:再说一次,糟糕想法会产生奇怪的结果,即使有最好的结果,也一定没有效率。两个int值的平均数计算竟然用到了浮点,你是认真的吗? 南京iOS应用开发培训


  我们再考虑一种更好的方式。这一次,显然修复成了:


  int avg(int a, int b)


  {


  return a + (b - a) / 2;


  }


  正确吗?


  不正确!尝试avg(INT_MIN, INT_MAX)的情况,你就明白错在哪里了。事实上,如果a或者b是负数,(b-a)甚至在达到接近边界值INT_MIN和INT_MAX之前就相对容易溢出了。


  最后的解决方案呢?如果我没有遗漏什么的话,我相信下面的代码就是最好的了:


  int avg(int a, int b)


  {


  if ((a < 0) != (b < 0))


  return (a + b) / 2;


  else


  return a + (b - a) / 2;


  }


  首先,上面代码中有趣的地方较为明显了,软件bug常常是没有考虑到、漠视或忘记了某些东西,也有可能是压根儿不知道。


  在每行源代码里,存在着一定数量的对象,这些对象又包含了特定属性。在avg()例子中,对象有:a, b, 2, +, /,result。在bug让你损失数十亿美元的云服务或太空船之前,需要定位并修复它,你应该查看表达式/语句所涉及到的所有对象,并思考你掌握它们的所有知识。比如,a和b是int型,因此它们必定总是在某个限制内(现实往往比较残酷);+操作符在大多数语言中因为没有警告溢出而臭名昭著;除法容易搞砸int型,也禁止被零除。南京iOS应用开发培训


  在现实生活中,它太简单了,以致于我们忘记、漠视或对上面提到的知识点一无所知。对于既定的一项任务,只存在很少的、形式上正确的方案,通常,有一种方案最简短,但是还有很大可能隐藏着bug。如果你在写代码时,脑子里需要记住10个因素,只要你无视了其中一个,就会导致bug的产生。我们的大脑还不够完美:它倾向于忘掉那些不应该忘掉的东西。


  我们对找到avg()的最佳解决方案的探求,应该已经提醒你注意卧室里、那条淘气的狗狗了。犯错很容易,而找到正确的方案,相对难一些。


  为了采取相对正式的方法,假定你被安排了一项先验的计算任务,那么你需要决定为编码投入多少努力。有两个极端:零努力、无穷多的努力。


  对于零努力的情形,如果你无论如何都要做点儿事情的话,那就是在机器上扔一个随机的位元流注2,观察运行情况。这种做法属于十足的混沌:用随机序列来解决某个特定问题的可能性微乎其微,就好像把一堆球扔到台球桌、还期望它们能够组成三角形。各种可能性太多,导致正确的可能性几乎不会发生。


  对于无穷多努力的情形,为了找到最便捷、最牛逼的解决方案而投入了足够多的努力,当然你会找到的。这是有序,很难。南京iOS应用开发培训


  不是很难,而总是更难。


  当你从零努力开始朝着积极方向前进时,随着你考虑越来越多的因素,也就有了越来越少的可能性,其中,很多可能性将是错误的、有bug的,只有很少一部分是正确的。朝着极限前进,会增加你编写正确解决方案的机会。


  找到某项任务的正确解决方案,需要记住并应用一定数量的条件。漠视或不了解其中一种,将导致bug的产生。和掌握并应用所有相对知识相比,引入bug常常更容易,因为某些相关知识没被应用的情形有很多,而考虑了所有因素的情形少之又少。


最近开班 more>
  • 开发课程基础班第一期
  • Web前端开发
  • 软件测试
  • 软件测试预科班
  • AI大模型+全栈开发开班
  • 云原生精英班
  • 云网预科班
  • 开发课程基础班第三期
  • 开发课程基础班第二期
  • 开发课程基础班第五期
  • CISP
  • HCIP-cloud
  • HCIE-Datacom(HCIA,HCIP基础)
  • HCIP-Datacom(HCIA基础)
  • HCIA-Datacom(0基础)
  • HCIE-Datacom(HCIA,HCIP基础)
  • HCIP-Datacom(HCIA基础)
  • HCIA-Datacom(0基础)
  • OCP 19C
  • RHCA
  • 6月16日
  • 6月9日
  • 6月16日
  • 6月9日
  • 7月18日
  • 6月30日
  • 6月23日
  • 6月30日
  • 6月23日
  • 7月14日
  • 随时开课
  • 随时开课
  • 6月17日
  • 6月10日
  • 6月3日
  • 6月7日
  • 7月5日
  • 6月7日
  • 随时开课
  • 随时开课
    • 姓 名 :
    • 电 话 :
    • 课 程 :

技术交流群

  • Java大数据交流群560819979加入
  • Python技术交流群595083299加入
  • Oracle技术交流群595119011加入
  • Web前端技术交流群604697610加入
  • Huawei技术交流群482919361加入
  • Redhat技术交流群587875348加入
  • UI设计技术交流群511649801加入
  • Cisco技术交流群596886705加入
  • IT运维技术交流群605888381加入