作者 | Jason Swett

译者 | 弯月,责编 | 屠敏

头图 | CSDN 下载自东方 IC

出品 | CSDN(ID:CSDNnews)

以下为译文:

犯错是什么意思,为什么犯错不好?


逻辑错误

一般,我们都认为正确比错误好。由于犯错的方法有很多种,因此在深入讨论之前,我想具体说明一下本文将要讨论的错误类型。

在这篇文章中,我想探讨的错误类型是逻辑错误,例如2加2等于5。


犯错的风险

正确与错误不仅仅是学术上的课题。在编程中,错误常常会引发切实的负面经济(以及其他)影响。经常犯错的开发人员效率很低,而且消耗的人工成本和机会成本也要多得多。

犯错不是每时每刻都发生的事情。大多数人会在很多事情上犯错,因为这是人的本性。即使是非常聪明的人,也可能在犯很多错误。

因此,我想分享开发人员为减少错误可以采取的一些行动。但首先,让我分享一个具体的错误例子。

错误例子

Bug:消失的日程安排

假设我正在构建一款日程管理软件。我的一位用户Rachel向我报告说,原定她与某人于7月1日上午10点会面,昨天她把这次会面改到了7月3日上午10点。今天,Rachel看了一下7月1日和7月3日的日程安排,却发现这两天均没有显示这次会面。很显然,这款软件有一个bug,修改日程安排导致这些日程安排被删除。

于是,我查看了代码,想看看能否找到证据证明这种错误行为确实存在。不幸的是,代码非常复杂,我的调查花费了很长时间。我的调查持续了一整天。直到今天我都没有取得任何进展。

这个bug不是bug

我并不知道,我认为是bug的东西实际上并不是bug。实际上,根本没有bug。从Rachel修改日程安排到她发现日程安排丢失,在这期间内,另一个用户Janice删除了这次会面。所以实际上根本没有bug。我错了。而且由于这个错误,我浪费了一整天的时间。


如何减少错误

 

我们开发人员可以通过对认识论的研究,减少犯错的情况。认识论是哲学的一个分支,研究的是知识的获取。认识论告诉我们如何确切地掌握实情,什么是真以及什么是假。

更狭义地讲,我们可以研究逻辑。逻辑是哲学的一个分支,研究的是形式化的推理系统。逻辑的中心思想之一就是论证。而论证就是我们将在本文中重点讨论的概念。

逻辑论证的定义

论证是一组陈述,包括一个或多个前提,以及一个且只有一个结论。

下面我们先来谈谈前提是什么,还有结论是什么。我来举一个逻辑论证的例子,后面统一简称论证。

论证的例子:

  • 所有鱼类都生活在水中。

  • 所有的鲨鱼都是鱼。

  • 因此,所有鲨鱼都生活在水中。

这个论证包含两个前提。“所有鱼类都生活在水中”是一个前提;“所有的鲨鱼都是鱼”是另一个前提。

这个论证的结论当然是“因此,所有鲨鱼都生活在水中”。如果所有鱼类都生活在水中,而且所有鲨鱼都是鱼类,那么当然所有鲨鱼都生活在水中。


有效性和可靠性

 

并非所有论证都是好论证。论证分有效或无效,以及可靠或不可靠。

有效性

如果结论的正确性与论证的前提有逻辑上的关联性,则该论证是有效的。比如上述鱼类与鲨鱼的论证是有效论证,因为如果论证的前提是正确的,则结论必然也是正确的。我们可以通过一些改动来破坏这个论证的有效性。

  • 所有鱼类都生活在水中。

  • 所有的鲨鱼都是鱼。

  • 因此,所有鲨鱼都有鳍。

这个论证是无效的,因为它的结论与前提没有逻辑上的关联性。所有鲨鱼都有鳍,这是事实,但我们无法根据该论证的前提推导出这样的事实,所以该论证无效。

请注意,有效性与真理无关。即使论证的前提不正确,论证也可能是有效的。

  • 所有的乌龟都是隐形的。

  • 每个人的大脑都有一只乌龟。

  • 因此,每个人的大脑中都有一只隐形的乌龟。

上述论证的前提并不正确(至少据我所知),但该论证仍然是有效的。

可靠性

如果论证有效而且前提为真,则该论证是可靠的。我们的第一个论证(“所有鱼类都生活在水中。所有的鲨鱼都是鱼。因此,所有鲨鱼都生活在水中。”)是可靠的,因为该论证有效的,而且它的前提为真。可靠的论证总能得出真实的结论。

下面是另一个可靠的论证。

  • 每一位20世纪的美国总统都是男性。

  • Richard Nixon是一位20世纪的美国总统。

  • 因此,Richard Nixon是男性。

下面,我们来进入正题,将逻辑论证应用到编程中。

编程的论证

 

阅读以下论证,同时牢记有效性和可靠性的定义。你能否判断出这个论证是有效的还是无效的,是可靠的还是不可靠的?(如果不想被剧透,那么在完整地阅读完论证之前不要滚动屏幕。)

  • 今天网站异常缓慢。

  • 今天上午,我们进行了大规模部署。

  • 此次部署导致网站速度变慢。

这个论证是不可靠的。即使前提的正确的,我们也无法根据这个前提推导出此次部署导致网站速度变慢。我们怎么知道这不是巧合?据我们所知,我们的网站得到了其他网站的推荐,而且流量激增是造成速度缓慢的原因。我们的论证是不可靠的,因为根据它的前提,结论不一定为真。因此,这个论证不可靠的原因是,即使前提为真,逻辑也是无效的。

下面是另外一个例子。这个论证有三个前提。

  • 有时,速度缓慢是由代码变更引起的。

  • 有时,速度缓慢是由流量高峰引起的。

  • 今天网站异常缓慢。

  • 速度缓慢的原因是代码变更或流量高峰。

这个论证也不可靠。网站速度变慢的原因可能不仅仅是代码变更或流量高峰。例如,也许是因为我们的运维人员在昨晚半夜干掉了一半服务器,而我们却不知道。因此,尽管前提是正确的,但这个论证和前面的论证一样,都是无效的。

下面是另外一个例子。

  • 最新部署的代码引入了一个bug。

  • 最新部署唯一推出的变更就是Josh的代码。

  • Josh的代码引起了这个bug。

只要这个论证的前提是正确的,这个论证就是可靠的。如果我们确定最新的部署引入了一个bug,并且我们确定最新的部署唯一推出的变更就是Josh的代码,那么从逻辑上讲,就是Josh的代码引起了这个bug。

下面是最后一个例子。这个例子比之前的都详细。

  • 上午10:32,系统重复收取了患者#5225的$20费用。

  • 上午10:32,Jason粗心地执行了有关患者#5225的一次手动操作,该操作与该患者的$20费用有关。

  • Jason造成了此次重复收费。

这也是一个不可靠的论证。尽管听起来似乎是Jason的行为造成了重复收费,但根据这个前提进行的推断在逻辑上是无效的。这个无效性可能并不明显,但是我们通过如下这个问题就能看清楚:“Jason的手动操作是否有可能并没有造成重复收费?”完全有可能,例如有可能是患者意外刷了两次卡,而且恰巧是在同一时间点。

我的经验证明上述论证是无效的,因为这是一个真实的例子,实际上,我的操作并不是导致重复收费的原因。以下可靠的论证帮助我摆脱了嫌疑。

  • 没有患者的信用卡信息就无法收取费用。

  • 在执行手动操作时,我不可能接触到患者的信用卡信息,因为我们的系统并没有存储信用卡信息。

  • 我的动作无法产生重复费用。

上述可靠的论证(记住可靠的论证总会得出真实的结论)促使我进行了更深入的研究。最终我发现,患者确实刷了两次卡,而且时间非常巧合。为什么开始我们没有看出患者刷了两次卡呢?因为我们使用Authorize.net作为支付网关,而且很显然有时即使收费成功,Authorize.netAPI仍会返回失败响应,因此从我们的应用程序角度来看,只成功收取了一次费用,但实际上收了两次。


祝你好运

 

下次当你遇到编程难题时,我希望你能够从论证的角度来思考你的难题,写下你的前提,而且一定要确保只列出真实的前提,否则你的论证就不可靠。然后推导出一个结论,并确保你的结论来自你的前提,那么你的论证就是有效的。如果你的论证是有效且可靠的,那么你的结论必然是正确的。

原文:https://www.codewithjason.com/logical-arguments-programmers/

本文为 CSDN 翻译,转载请注明来源出处。

更多精彩推荐
☞30名工程师,历时1300天打造,又一“国产”AI框架开源了
☞支付宝、微信支付回应被反垄断调查;搜狗宣布成立独立特别委员会;GNU nano 5.0 发布| 极客头条
☞V神演讲内容曝光!Defi、挖矿、行业应用更多主题大揭秘
☞PyTorch 1.6、TensorFlow 2.3、Pandas 1.1同日发布!都有哪些新特性?
☞程序员必备基础:Git 命令全方位学习
☞公链还能这样玩?二次元、出圈与社区自治
点分享点点赞点在看
Logo

20年前,《新程序员》创刊时,我们的心愿是全面关注程序员成长,中国将拥有新一代世界级的程序员。20年后的今天,我们有了新的使命:助力中国IT技术人成长,成就一亿技术人!

更多推荐