负负得正

发表于:2019-3-22 11:17

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:钱吃菜    来源:不写代码写什么

#
Bug
分享:
  
你不知道 bug 是如何产生的,
  也不知道代码为何又可以运行了?
  写 bug 也可以验证数学定律
  人无完人,软件也只能趋近于完美,代码难免有 bug。bug 越早发现、越早修复越好,因为在自己刚刚写好的代码中找出 bug 算是容易的。你肯定知道,在自己几个月前写的代码中找出 bug 和看别人写的代码,往往一样头痛。更别说 bug 和 bug 之间还会产生化学反应,产生「复合式 bug」。
  “ 复合式 bug 也就是互相影响的两个 bug。举例来说,一个bug 是楼梯很滑,另一个 bug 是扶手松了,那么只有当这两个 bug 互相作用时,才会导致你从楼梯上摔下来。 ”
  这个十分恰当的比喻,肯定会让你会心一笑。 其实我们更像是个盲人,看不见楼梯什么状况,只能顺着着扶手往下走,当扶手松了,摔在地上的我们顿时一怔:“ 卧槽,这楼梯什么时候变得这么湿滑的?! ”。
  这样子摔下楼梯,其实还不算是最惨的,最能坑人的是「复合式 bug 」的一个子类型:
  “ 这两个 bug 是互相弥补的,好比「负负得正」,软件反而能正常运行。这种 bug 可能才是最难发现的 bug 。当你修正了其中的一个 bug ,另一个 bug 才会暴露出来。这时对你来说,你会觉得刚才修正错了,因为那是你最后修改的地方,你就怀疑自己在那里做错了,但是你其实是对的。 ”
  没错,我不久前就被这样「负负得正」的 bug 给坑过,而且摔得挺惨:项目中 A 功能的代码,一直存在这样一个未被发现的 bug,在错误的时机访问了 B 处已经泄漏了的内存;而我们为了解决 App 整体的内存泄漏,回收了 B 处的内存,于是,A 功能的代码就直接大面积崩溃了。
  函数式编程?
  解决 bug 的最好方法是尽可能地避免 bug 的产生,除了靠外部的 Code Review 来驱动,还需要内部的自我驱动。如果你读过硅谷创业之父 Paul Graham 的《黑客与画家》,你肯定会知道「函数式编程(functional programming)」会很好的避免代码的一些「副作用」:
  “ 函数式编程在学术文献中研究得比较多,在商业软件中用得比较少。但是,对于互联网软件,它却很有用。很难用纯粹的「函数式编程」完成整个程序,但是它可以用来编写一些重要的部分,使得这些部分易于调试,因为它们不包含「状态」(state),非常便于不断进行小幅的修改和测试。 ”
  这里就要提一下函数式编程的一个特性「不可变数据」:只是返回新的值,不修改外部变量。举个例子:
   var count
  fun increment() {
  count++
  }
  上面是非函数式的写法,那么函数式的写法呢?
  fun increment(count: Int): Int{
  return count + 1
  }
  这个普通的例子已经很好的展现函数式编程的特性了,我不依赖外部的数据,我也不改变外部的数据,而是返回一个新的值给你。
  在《编写可读代码的艺术》一书中,谈到了变量影响代码可读性和复杂度的三种原因:
  变量越多,就越难全部跟踪它们的
  变量的作用域越大,就需要跟踪它的动向
  变量改变得越频繁,就越难以跟踪它的当前值
  可读性越差、复杂度越高的代码越难维护,也越容易出 bug,这是显而易见的。
  越来越多的现代语言,在设计的时候,或多或少都会借鉴「函数式编程」的思想,比如闭包、中缀表达式等等。

     上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号