当前位置: 首页 > news >正文

​什么是bug?bug的源头在哪里?

f8bf52f80dfba574497bbef1077138c0.gif

a748ca0ffe1426b1f04cee17c5a876b5.png

导读:

当谈论bug时我们究竟谈论的是什么?bug来自哪里?我们能把所有bug的成因范围缩小至一个或者几个之内吗?

77c28fcc6207c6111dd9c57f83800171.png

相信绝大部分程序员都听说过这个故事:曾经真的有人在计算机里找到了一只昆虫,正是这只昆虫导致了计算机程序运行出现了错误。(但真实情况是,人们在那之前就已经把程序的异常行为称为bug了,但因为这则故事富有趣味,所以一直被人们津津乐道。)

但说真的,当谈论bug时我们究竟谈论的是什么?

31f1f85b48bc961552dd6f1457c66e63.png

这里是关于bug的精确定义:

1.程序的行为并没有符合程序员的预期

2.程序员的预期没有满足绝大部分理性用户的期望。

通常来说只要程序能够严格执行程序员给出的指令,它就可以算是处于正常工作的状态。但有时候程序员期望程序执行的行为会出乎普通用户的意料,甚至给他们带来麻烦,所以这也算是一类bug。

其他软件功能上的不足都可以归纳到新功能需求中。如果说程序的工作状态的确与我们期望的一致,但离用户期望还有差距,则意味着它需要新“功能”。“功能”和“bug”定义之间的区别也就在这。

请注意硬件也可能产生bug。程序员不太可能发出“让计算机爆炸”这类的指令。如果程序员编写了一段程序导致了计算机真的爆炸了,这很有可能是硬件bug引起的。硬件中当然可能存在某些bug,但应该不会是如此夸张的这种。

本质上说,任何导致程序员指令没有被正确执行的故障,都可以被认为是bug,除非程序员打算让计算机做一些它本不应该去做的事情。

举个例子,如果程序员告诉计算机去“统治整个世界”,但是它本身就不是被设计用来统治世界的,那就意味着计算机需要一个新的“统治整个世界”的功能。这也就算不上是一个bug。

硬件

至于硬件,你应该同时考虑到硬件设计者的预期,以及大部分程序员的对于它们的期望。从这个层面上说,程序员其实是主要的“用户”,硬件设计者则是需要考虑程序员预期的人。

当然,我们也应该关心普通用户的期望,特别是针对那些普通用户会与之打交道的硬件设备,比如打印机、显示器和键盘等。

                                                                                                                       —Max

bug来自哪里?我们能把所有bug的成因范围缩小至一个或者几个之内吗?答案是肯定的。

bug通常来自开发者尝试降低代码复杂性未果而产生的副作用。也有部分来自对其实简单的代码产生的误解。

5039b8991ee414c06b481bc9fb909949.png

除了一些拼写错误以外,我能十分肯定以上两点基本就是所有bug产生的根本原因,尽管我还没有进行深入的研究来证明这件事。

复杂的事物容易引起用户的误操作。想象一下一个黑色盒子,上面有上百万个没有任何标识的按钮,而其中的16个按钮按下之后会毁灭整个世界,那么使用这个盒子的人中注定有人会一不小心让毁灭降临。在编程中也存在类似的情况,如果你无法轻易理解编程语言的文档,或者是这门语言本身,你就或多或少存在错误使用它的可能。

说真的,就那个长满上百万个没有标识按钮的盒子而言,正确的使用方式不可能存在。你永远也不可能弄清正确的方式是什么,即使你计划阅读完1000页的说明书,也不一定能记住能够帮助你正确使用盒子的整套流程。同样的道理,只要你让事物变得足够复杂,人们就会倾向于用错误的而不是正确的方式使用它。如果你把50、100或者1000个这类的复杂组件拼装在一起,无论由多聪明的工程师来进行拼装,它们也永远无法正常工作。

所以你开始明白bug来自哪里了吧?你每引入一丝复杂性,开发者(这里的“开发者”甚至包括你自己)误用你的代码的概率就高一分。

32ec7068fbf2bb4d354286ce6e957bca.png

一旦代码的意图和使用方法变得极不明确,就会让使用这份代码的人犯错。又因为你的代码和其他的代码混合在了一起,导致了开发者误用和犯错的可能性大大增加。而后这些代码又会继续和其他的代码混合,形成恶性循环。

复杂性的构成

硬件设计者将硬件制造得极为复杂的情况时常发生。所以它必须与复杂的汇编编程语言集成。而这又使得汇编语言和编译器同样复杂起来。当你遇到这种情况时,如果你不提前对程序进行精妙的设计或者全方位的测试的话,基本上无法避免bug的发生。只要你的设计不够完美,那么在运行的一瞬间,大量的bug就会涌现出来。

站在其他程序员的视角看这件事也很重要。毕竟有些事对你来说很简单,但是对其他人来说或许很复杂。

如果你想要感同身受地体验一下其他人看不懂你的代码的感受,你可以找一份你从没有使用过的类库的文档来阅读看看。

也可以找一些你从没有阅读过的代码来阅读。尝试理解整段程序而不是单行代码的含义,并且想象当你需要对它进行修改时应该从哪里入手。这些都是其他人阅读你代码时的体验。你大概注意到在阅读他人代码时,即使并不复杂的代码也足以让人产生挫败感。

现在我们考虑另一种程序员误解简单代码的情况。这也是需要额外小心的另一件事。如果你察觉到某位程序员在向你解释一段代码时叙述得牛头不对马嘴,那便意味着他应该是误解了代码中的某些内容。当然如果他正在研究的领域极其复杂,也情有可原,可能需要他读到博士学位才能完全掌握它。

这两个方面是紧密关联的。当你编写代码时,需要承担的部分职责是让将来阅读你代码的程序员理解它,并且是很轻松地就能理解。如果你确实是这么做的,但是他在阅读过程中仍然产生了严重误解—或许他根本就不明白“if”语句是什么含义。那应该就与你无关了。

假设将来那些阅读你代码的程序员,对编程的基本原理和正在使用的编程语言语法都略知一二,在这个前提下你的职责是写出整洁的代码。

所以最后可以总结出几条有趣的原则:

1.你写的代码越简单,bug就越少。

2.你应该始终想方设法去简化程序中的代码。

                                                                                                                   —Max

本文摘编自《编程原则:来自代码大师Max Kanat-Alexander的建议》,经出版方授权发布。

RECOMMEND

推荐阅读

6968568cb97cafdd97ad82d39b898ce4.png

01

编程原则

来自代码大师Max Kanat-Alexander的建议

0c780d76b7fb4cdfb3daf897ed58a319.png

作者:[美]马克斯·卡纳特-亚历山大(Max Kanat-Alexander)

译者:李光毅

编程大师向你展示如何让简约设计的思想回归到计算机编程中

推荐阅读

在本书中,富有传奇色彩的编程大师马克斯·卡纳特-亚历山大(Max Kanat-Alexander)将会向你展示如何让简约设计的思想回归到计算机编程中。马克斯会解释程序员为何会感到力不从心,以及应该如何持续改善。世界上存在太多复杂的事物。复杂并不可取,因为它会给我们的工作带来隐患。

马克斯从他久负盛名的技术博客CodeSimplicity中精选了一部分文章,对如何在软件行业工作以及取得成功给出了自己的想法和建议。相信这43篇文章能够让你学会如何在工作中避免复杂,拥抱简约,从而让你的职业生涯更加顺利和成功。

3d2d2c66783bfd52900d545eeac3d7e5.png

02

计算机系统解密

从理解计算机到编写高效代码    

1fd6228d59622d5a27d05d1e5eef4754.png

作者:[美]乔纳森·E.斯坦哈特(Jonathan E. Steinhart )

译者:张开元、张淼

计算机程序硬件软件从底层实现到高层展现原理讲解

对底层知识的多个主题进行了公平的覆盖

推荐阅读

计算机编程不是抽象的,程序是在机器上运行的。了解计算机如何工作以及程序如何在计算机上运行是成为一名更好的程序员的必要条件。在本书中,资深工程师Jonathan E. Steinhart深入探讨了计算机背后的基础概念,比如计算机硬件,软件在硬件上的行为,如何编写高效的程序,计算机安全基础知识,以及在编写代码时需要考虑的现实问题。本书对底层知识的多个主题进行了公平的覆盖——介绍有助于提高整个系统质量的许多领域的知识(包括计算机硬件、组合逻辑、时序逻辑、计算机体系结构、计算机组成原理、操作系统、系统程序设计等)。

0a9f563c9b849f4261c6f11d349b9c43.png

03

 深入理解计算机系统(原书第3版)

0d83393240917750430ce5bcb33d5918.png

作者:[美] 兰德尔 E.布莱恩特(Randal E. Bryant)

大卫 R. 奥哈拉伦(David R. O'Hallaron)

译者:龚奕利 贺莲

将所有计算机系统相关知识融会贯通,助你成为凤毛麟角的高级程序员的必备神书。如果你研究和领会了这本书里的概念,你将开始成为极少数的“牛人”!

推荐阅读

本书是一本将计算机软件和硬件理论结合讲述的经典教程,内容覆盖计算机导论、体系结构和处理器设计等多门课程。卡内基-梅隆大学、北京大学、上海交大等国内外众多知名高校选用指定教材。本书的最大优点是为程序员描述计算机系统的实现细节,通过描述程序是如何映射到系统上,以及程序是如何执行的,使读者更好地理解程序的行为,以及造成效率低下的原因。从程序员的角度来学习计算机系统是如何工作的会非常有趣。最理想的学习方法是在真正的系统上解决具体的问题,或是编写和运行程序。这个主题观念贯穿本书始终。

e1e6213f611fad30f5530f32cbab846a.gif

0b89c8e9ada03cbbaa0d83e42ee5423e.png

扫码关注【华章计算机】视频号

每天来听华章哥讲书

cddba7a21eec16f328b3495b6c359d4c.gif

更多精彩回顾

干货 |C++都有哪些就业方向?是否应该学习C++?

书单 | 成为优秀Java开发者,我看了这几本书

上新 |《Core Java》作者亲授视频免费看,学习Java更轻松

资讯 |提升研发效能:抵制无效加班文化

资讯 | 又又叒更新,Win 12要来了?

干货 |一文带你掌握计算机体系结构核心内容

干货 | 一文带你理解算法策略

书讯 | 2月书讯(下)| 新年到,新书到!

书讯 | 2月书讯 (上)| 新年到,新书到!

【赠书】【第96期】夯实基础,突破内卷,不被优化

4a3cad71d12d42ee6b92dcb605bdf502.gif

87bd467c720154e6df3036af9fc34f3b.gif

点击阅读全文购买

相关文章:

  • 【第97期】2022 软件工程师状况报告:Go 最抢手
  • Web渗透测试实战:基于Metasploit 5.0
  • 详解六种常见的上下文切换场景
  • 终于有人把Knative讲明白了
  • 赵宏田:用户画像场景与技术实现
  • 商品中台的可视化微前端实践
  • 4月书讯(下)| 上新了,华章
  • 场景拆解六步设计法,手把手教你细化场景
  • 2021年图灵奖出炉!高性能计算鼻祖Jack Dongarra获奖
  • ​香农与信息论三大定律
  • 【第98期】终于有人把Flink设计理念与基本架构讲明白了
  • Koa在实际的业务场景中,路由如何做分割?
  • 一图梳理企业数据治理的8项举措
  • 一图看懂边缘计算整体架构
  • 数据安全实践指南
  • 「前端」从UglifyJSPlugin强制开启css压缩探究webpack插件运行机制
  • const let
  • HashMap ConcurrentHashMap
  • javascript面向对象之创建对象
  • MySQL主从复制读写分离及奇怪的问题
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • STAR法则
  • Web Storage相关
  • 初识MongoDB分片
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • ​iOS实时查看App运行日志
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • ${ }的特别功能
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (Git) gitignore基础使用
  • (原創) 未来三学期想要修的课 (日記)
  • (转)利用ant在Mac 下自动化打包签名Android程序
  • (转载)利用webkit抓取动态网页和链接
  • .NET(C#) Internals: as a developer, .net framework in my eyes
  • .NET4.0并行计算技术基础(1)
  • .net遍历html中全部的中文,ASP.NET中遍历页面的所有button控件
  • .net最好用的JSON类Newtonsoft.Json获取多级数据SelectToken
  • //解决validator验证插件多个name相同只验证第一的问题
  • @Autowired和@Resource的区别
  • [].slice.call()将类数组转化为真正的数组
  • [acwing周赛复盘] 第 69 场周赛20220917
  • [Bada开发]初步入口函数介绍
  • [CSS]浮动
  • [LeetCode] Verify Preorder Sequence in Binary Search Tree 验证二叉搜索树的先序序列
  • [ndss 2023]确保联邦敏感主题分类免受中毒攻击
  • [OGRE]看备注学编程(02):打地鼠01-布置场地九只地鼠
  • [one_demo_4]不使用第3个变量交换两个变量的值
  • [py]python自省工具
  • [Redis]——数据一致性,先操作数据库,还是先更新缓存?
  • [Tapestry]Struts终结者?对比组件框架技术tapestry(转)
  • [TestLink]testlink安装
  • [uni-app] 防重复点击处理 - 自定义指令
  • [Unity+智谱AI开放平台]调用ChatGLM Tuobo模型驱动AI小姐姐数字人
  • [VSCode] 你需要知道的23个实用VSCode快捷键