疏忽盲目-错过明显

Your code isn’t working! You don’t know why and you’ve been staring at it for what seems like hours. You’re grumpy. You’re falling behind schedule. You’re getting increasingly irritated. Why doesn’t it work? Why can’t you see the bug? It can’t be so hard to find, can it?

您的代码不起作用! 您不知道为什么,并且一直盯着它看了几个小时。 你很脾气 您落后于进度。 您越来越恼火了。 为什么不起作用? 为什么看不到错误? 找不到那么难,不是吗?

Out of sheer frustration (as opposed to rational thought) you call over a coworker to help you find the problem. Within seconds they do what’s been seemingly beyond you – they identify the source of the issue. To make matters worse, it’s painfully simple.

出于绝对的沮丧(与理性思考相反),您打电话给同事来帮助您找到问题。 在几秒钟内,他们完成了似乎超出您范围的工作-他们确定了问题的根源。 更糟的是,这很简单。

You’re satisfied that the code works and your pointy-haired boss is relieved that the project is back on track. Life is back to normal and you’re cranking out more code. Yet despite this, one word festers in the back of your mind. One simple word: Why? Why could the coworker find the problem in no time at all but yet you couldn’t find it for an hour?

您对代码能够正常工作感到满意,而尖顶的老板对项目重回正轨感到宽慰。 生活已恢复正常,您正在编写更多代码。 尽管如此,一个字却在您的脑海中浮现。 一个简单的词:为什么? 为什么同事根本无法立即找到问题,但一个小时却找不到呢?

Take heart my friend. It’s likely something we’re all susceptible to, a problem in your ability to perceive and identify things. Let’s discuss this interesting phenomena, which you may not be familiar with: inattention blindness.

振作起来我的朋友。 这很可能是我们所有人都容易受到的,这是您感知和识别事物的能力出现问题。 让我们讨论一下您可能不熟悉的这种有趣现象:注意力不集中。

这是怎么回事? (What’s Going On?)

If you’ve not heard of it before, according to Wikipedia, inattention blindness (otherwise known as perceptual blindness) is:

如果您以前从未听说过它,那么根据Wikipedia所述, 疏忽性失明 (也称为知觉失明)为:

… failure to notice an unexpected stimulus that is in one’s field of vision when other attention-demanding tasks are being performed … This typically happens because humans are overloaded with stimuli, and it is impossible to pay attention to all stimuli in one’s environment. This is due to the fact that they are unaware of the unattended stimuli.

……在执行其他需要注意的任务时,没有注意到一个人视野中的意外刺激……这通常是由于人的刺激过多而导致的,因此不可能关注一个环境中的所有刺激。 这是由于他们没有意识到无人参与的刺激这一事实。

There is a lot to the concept, so I’ll summarize it as best I can. Inattention blindness is a phenomena related to people’s perception of the data they receive through their senses.

这个概念有很多,所以我将尽其所能总结一下。 注意力不集中是一种与人们对通过感知获得的数据的感知有关的现象。

Irrespective of something clearly being in plain sight, or in slang terms “right in front of their eyes”, people may not actually perceive that it’s there. They physically saw it, whether it’s a logic error, missing semicolon, or a missing statement. It registered in their conscious mind, but they didn’t seem to identify what was there (or that it was important enough to warrant their attention).

不管清楚地看到什么东西,还是用“语“就在眼前”,人们实际上都不会意识到它在那里。 他们从物理上看到了它,无论是逻辑错误,缺少分号还是缺少语句。 它记录在他们的意识中,但是他们似乎并没有发现其中的内容(或者它足够重要,值得引起他们的注意)。

The end result? To them, effectively it wasn’t there.

最终结果? 对他们来说,实际上不存在。

隐形大猩猩测试 (The Invisible Gorilla Test)

One of the most famous examples on the subject is the invisible gorilla test, which was conducted by Daniel Simons and Christopher Chabris. If you’re not familiar with the test, watch this video if it on YouTube. Subjects were asked to watch the video, which has two teams passing balls between each other, and count the number of passes by one team. What the subjects were not told is that during the video a person in a gorilla suit walks through the middle of the crowd, beats its chest, then walks off. You’d thinks this would be pretty obvious, right? The reports differ. Around 50% of the people didn’t indicate they saw the gorilla.

关于这个主题的最著名的例子之一是由Daniel Simons和Christopher Chabris进行的隐形大猩猩测试 。 如果您不熟悉测试,请在YouTube上观看此视频 。 要求受试者观看视频,该视频有两支球队彼此之间传球,并计算一支球队的传球次数。 没有告诉受试者的是,在录像期间,一个穿着大猩猩套装的人穿过人群中间,殴打其胸部,然后走开。 您会认为这很明显,对吧? 报告有所不同。 大约50%的人没有表示他们看到了大猩猩。

Strange, right? A person in a gorilla suit walks clearly in to view and struts around. How could anyone miss something so obvious?

奇怪吧 一个穿着大猩猩服的人清晰地走进来,四处张望。 谁能错过如此明显的东西?

Without going in to too much depth, there are a number of theories as to why. Scientists have theorized four possible reasons:

在不深入的情况下,有很多关于为什么的理论。 科学家从理论上提出了四个可能的原因:

  • Conspicuity: If an item is not particularly obvious or lacks meaning to the beholder, it may be missed.

    醒目如果某项不是特别明显或缺乏对旁观者的意义,则可能会错过它。

  • Mental workload and working memory: People can only consciously concentrate on a limited amount of information at a given time.

    精神工作量和工作记忆:人们只能在给定的时间有意识地专注于有限的信息量。

  • Expectation: The gorilla is unexpected so it’s filtered out.

    期望:大猩猩出乎意料,因此被过滤掉了。

  • Capacity: People only have a limited amount of ability to concentrate at a given time.

    能力:人们在给定时间只能集中精力。

With so much in our lives and despite our experience to concentrate and focus on, it only makes sense that we have to filter out a large amount of stimuli, so we focus on the information which is both important and meaningful.

尽管生活中有如此多的事情,尽管我们有专心和专注的经验,但必须过滤掉大量刺激才有意义,因此我们专注于重要而有意义的信息。

这如何适用于编程? (How Does This Apply to Programming?)

Recently I read an interesting (and brief) paper, entitled What Makes Code Hard to Understand? by Michael Hansen, Robert L. Goldstone and Andrew Lumsdaine. The abstract is as follows:

最近,我读了一篇有趣的(简短的)论文,标题什么使代码难以理解? 由Michael Hansen,Robert L. Goldstone和Andrew Lumsdaine撰写。 摘要如下:

What factors impact the comprehensibility of code? Previous research suggests that expectation-congruent programs should take less time to understand and be less prone to errors. We present an experiment in which participants with programming experience predict the exact output of ten small Python programs.

哪些因素影响代码的可理解性? 先前的研究表明,符合期望的程序应该花更少的时间来理解,并且不容易出错。 我们提供了一个实验,其中具有编程经验的参与者可以预测10个小型Python程序的确切输出。

We use subtle differences between program versions to demonstrate that seemingly insignificant notational changes can have profound effects on correctness and response times. Our results show that experience increases performance in most cases, but may hurt performance significantly when underlying assumptions about related code statements are violated.

我们使用程序版本之间的细微差异来证明看似微不足道的符号更改可以对正确性和响应时间产生深远影响。 我们的结果表明,经验可以在大多数情况下提高性能,但是如果违反了有关代码语句的基本假设,则可能会严重损害性能。

Take careful note of the latter part of the abstract:

请仔细注意摘要的后半部分:

Our results show that experience increases performance in most cases, but may hurt performance significantly when underlying assumptions about related code statements are violated.

我们的结果表明,经验可以在大多数情况下提高性能,但是如果违反了有关代码语句的基本假设,则可能会严重损害性能。

How is it that the violation of underlying assumptions can negatively impact our ability to understand code? Well, I won’t regurgitate the paper. Instead I’ll review some points that it makes, discussing each in turn, in an open-ended fashion. Through doing so, I hope we can both identify some of the causes behind when we miss the obvious and how others, seemingly, aren’t encumbered with our blinkered vision.

违反基本假设如何对我们理解代码的能力产生负面影响? 好吧,我不会反感这篇论文。 相反,我将回顾其提出的观点,以开放式的方式依次讨论每个观点。 通过这样做,我希望我们都能找出错过明显现象的背后原因,以及看似不被我们眨眼的视野所困扰的其他原因。

特定的语言经验/程序员期望 (Specific Language Experience / Programmer Expectations)

Is increased experience a hindrance or a help? This one’s a little fuzzy. As we know more, do we make assumptions about situations and conditions such as what would and wouldn’t work, which more junior developers wouldn’t?

增加的经验是阻碍还是帮助? 这有点模糊。 如我们所知,我们是否会对情况和条件做出假设,例如什么会起作用,什么不起作用,其他初级开发人员不会起作用?

I’m sure you’re familiar with the situation where the more experienced person, because of all the knowledge and experience that they possess, will assume things will or won’t work. A new person completely unfamiliar with the subject matter might quickly make suggestions such as:

我确定您熟悉这样一种情况,即经验丰富的人,由于他们拥有的所有知识和经验,会假设事情会或不会奏效。 完全不熟悉主题的新手可能会很快提出以下建议:

  • What about doing it this way?

    这样怎么办?
  • Have you tried X?

    您尝试过X吗?
  • Did you think to do Y?

    你想做Y吗?

Ironically the increased knowledge has become a hindrance, not a help. Here’s a specific example; do we start to expect that code has to be written in certain ways, such as indenting with the K&R (Kernighan and Ritchie) versus Allman style?

具有讽刺意味的是,知识的增加已成为障碍,而不是帮助。 这是一个具体的例子; 我们是否开始期望代码必须以某些方式编写,例如缩进K&R(Kernighan和Ritchie)Allman风格?

As a result, we get so used conforming to conventions that when things don’t conform we have trouble reading them. I’m guilty of this. Are you?

结果,我们习惯了遵循约定,以至于当事物不符合要求时,我们就很难阅读它们。 我对此感到内gui。 你是?

运算符重载 (Operator Overloading)

In most languages, specifically PHP and JavaScript, operators can have multiple purposes or, when not used carefully, have unexpected results. This is fine if you’re used to it, but what if you’re not? What if you’re tired, stressed, or under the pump?

在大多数语言中,尤其是PHP和JavaScript,运算符可以有多种用途,或者,如果使用不当,可能会产生意想不到的结果。 如果您习惯了,这很好,但是如果您不习惯呢? 如果您感到疲倦,压力重重或处于压力之下怎么办?

Take the following example (from the assignment operators section of the PHP manual):

采取以下示例(来自PHP手册的赋值运算符部分 ):

$a = 3; 
$a += 5; 
$b = "Hello "; 
$b .= "There!";

We can easily see that for $a the result will be 8 and for $b the result will be “Hello There!”. But what if we’d mixed up the operators as follows:

我们可以很容易地看到,对于$a ,结果将为8,对于$b ,结果将为“ Hello There!”。 但是,如果我们将运营商混合如下:

$a = 3; 
$a .= 5; 
$b = "Hello "; 
$b += "There!";

What would the results be now?

现在的结果是什么?

句法噪音 (Syntactic Noise)

According to Martin Fowler, syntactic noise is:

根据Martin Fowler的说法 ,句法噪音为:

extraneous characters that aren’t part of what we really need to say, but are there to satisfy the language definition.

无关的字符,这些字符不是我们真正需要说的,但可以满足语言定义。

He goes on to say that syntactic noise is bad because it “obscures the meaning of our program, forcing us to puzzle out what it’s doing.” Now, I agree with Martin’s observation that it is subjective, so likely you and I may wildly disagree.

他继续说,句法噪音是不好的,因为它“掩盖了程序的含义,迫使我们弄不清楚它在做什么。” 现在,我同意马丁关于主观的看法,因此您和我可能完全不同意。

However, this article on SourceForge points out that syntactic noise, partly introduced by complex syntax, cuts both ways:

但是, 有关SourceForge的这篇文章指出,复杂的语法部分引入了语法噪声,这两种方法都可以消除:

Syntactic noise complicates maintenance of programs, and makes the learning curve steeper. However, it is important to note that complicated syntactic rules may make it easier for compilers to detect and report errors.

语法噪声使程序的维护复杂化,并使学习曲线更陡峭。 但是,重要的是要注意,复杂的语法规则可能使编译器更容易检测和报告错误。

Let’s look at an example of “noisy” PHP. This was modified from the original Java example used by Paul W. Homer:

让我们看一个“嘈杂” PHP的示例。 这是 Paul W. Homer使用的原始Java示例中修改

public function calcIndex() 
{ 
    $weightedSum = 0; $bondCount = 0; $status = false;
    for ($i = 0; $i < count($this->bonds); $i++) {
        $status = $this->yieldCalc($this->bondInfo, self::YIELD, true,
            $this->bondFacts);
        if ($status != true) {
            throw new YieldCalculationException(
                $this->getCalcError()); 
        } 
        $weightedSum += $this->calcWeight($this->bondFacts,
            Weight::NORMAL); 
        $bondCount++;
    } 
    return $weightedSum / $bondCount; 
}

If you’re familiar with all of the lexicographical structures, the above code is rather trivial. But to someone less experienced, it may take more time to decipher. Let’s step through it a section at a time.

如果您熟悉所有的词典结构,则上面的代码相当简单。 但是对于经验不足的人,可能需要更多的时间来解密。 让我们一次逐步介绍它。

$weightedSum = 0.0; $bondCount = 0; $status = false;

Here we’re initializing three variables: $weightedSum, $bondCount, and $status, all in one line. It might be clearer if we initialize them individually on separate lines.

在这里,我们要初始化三个变量: $weightedSum$bondCount$status ,它们全部在一行中。 如果我们在单独的行中分别初始化它们,可能会更清楚。

for ($i = 0; i < count($this->bonds); $i++) {

The for construct was one of my favorites for some time. It provides an initializer, loop limiter, and incrementor. However, there’s quite a lot going on there and sometimes, in haste, we may not assemble it quite as we’d thought we had.

一段时间以来, for构造是我的最爱之一。 它提供了一个初始化器,循环限制器和增量器。 但是,那里发生了很多事情,有时,我们可能会匆忙组装,可能不像我们以前想象的那样。

A simpler approach may be the foreach instead, which would be:

一个更简单的方法可能是foreach ,它是:

foreach ($this->bonds as $item) {

The intent is much clearer to understand and it’s harder to introduce errors.

意图更容易理解,并且很难引入错误。

$weightedSum += $this->calcWeight($this->bondFacts, Weight::NORMAL);
$bondCount++;

Here we have a compact approach to variable assignment (+=) and incrementing (++). Yes, it takes less space, but is it necessarily clear or indicative? It’s up to you, but maybe the following might be clearer:

在这里,我们有一种紧凑的方法来分配变量( += )和增加变量( ++ )。 是的,它占用的空间更少,但是否必须清晰或具有指示性? 这取决于您,但是以下内容可能会更清楚:

$weightedSum = ($weightedSum + $this->calcWeight($this->bondFacts,
    Weight::NORMAL)); 
$bondCount = ($bondCount + 1);

As I said before, this is partly subjective, not to mention trivial. But hopefully you see that sometimes the constructs we use can both help and hinder us.

如我之前所说,这是部分主观的,更不用说琐碎了。 但是希望您看到有时我们使用的结构既可以帮助我们,也可以阻碍我们。

I’m sure we all know developers who think that the only way to code is to write in as compact and terse of a way as possible. Whether motivated by rock star status or job protection, who knows. But only very few people can read their code. When code has to be maintained over time, this isn’t the right approach.

我敢肯定,我们所有人都会认识到开发人员,他们认为唯一的编码方法就是以尽可能紧凑和简洁的方式编写代码。 知道是出于摇滚明星身份还是出于工作保护。 但是只有很少的人可以阅读他们的代码。 当必须随时间维护代码时,这不是正确的方法。

空格–垂直和水平 (Whitespace – Vertical and Horizontal)

The paper indicates that when code is vertically clumped together, there is the expectation that the code is logically related. Take this example from ZendAuthenticationAdapterDbTable.php in Zend Framework 2:

该论文指出,当代码在垂直方向上聚在一起时,人们期望代码在逻辑上是相关的。 以Zend Framework 2中的ZendAuthenticationAdapterDbTable.php为例:

public function __construct( 
    DbAdapter $zendDb, $tableName = null, 
    $identityColumn = null, $credentialColumn = null, 
    $credentialTreatment = null) 
{ 
    $this->zendDb = $zendDb; 

    if (null !== $tableName) { 
        $this->setTableName($tableName); 
    } 

    if (null !== $identityColumn) { 
        $this->setIdentityColumn($identityColumn); 
    } 

    if (null !== $credentialColumn) { 
        $this->setCredentialColumn($credentialColumn); 
    } 

    if (null !== $credentialTreatment) { 
        $this->setCredentialTreatment($credentialTreatment); 
    } 
}

Through a good use of vertical whitespace, we can see what code is logically related. We can readily identify the various conditions based on $tableName, $identityColumn, $credentialColumn and $credentialTreatment. Additionally, the code proper use of horizontal whitespace (indentation) gives the code a very logical and clear structure.

通过充分利用垂直空格,我们可以看到逻辑上关联的代码。 我们可以根据$tableName$identityColumn$credentialColumn$credentialTreatment轻松确定各种条件。 此外,代码正确使用水平空格(缩进)使代码具有非常逻辑和清晰的结构。

Owing to the logical structure of the code (yes I’m a sucker for well organized code) it’s simpler for the eye to follow the structure of it, keeping it readily in short-term memory.

由于代码的逻辑结构(是的,我是组织良好的代码的傻瓜),使人更容易遵循代码的结构,将其轻松保存在短期内存中。

Imagine if this was all clumped together with no grouping, indentation, or general sense of order. Would it be as easy to understand?

试想一下,如果所有这些都没有分组,缩进或一般的顺序感而聚集在一起。 会容易理解吗?

结论 (Conclusion)

The examples in this article are deliberately trivial, but I hope you’ve not overlooked the essential points as a result. That is, often times the issues that we face in identifying problematic code can often be hidden from us, not because we lack skill, but because of little things like expectations, assumptions, or distractions.

本文中的示例刻意琐碎,但我希望您不要因此而忽视基本要点。 就是说,通常我们在识别有问题的代码时面临的问题通常可以向我们隐藏,这不是因为我们缺乏技能,而是因为期望,假设或干扰等小事情。

When others are able to solve the issues that we’ve racked our brains to find, it’s not necessarily a poor reflection on us. They just have a fresh (or sometimes just different) perspective than we do.

当其他人能够解决我们绞尽脑汁寻找的问题时,这不一定是对我们的反思。 他们只是比我们有新的(或有时只是不同的)观点。

So next time you’re beating yourself up for not finding a missing semicolon – don’t. It happens from time to time, and now you have a better understanding of why. If you’re interested in this subject, I recommend the following resources for further reading:

因此,下次您要为找不到找不到的分号而烦恼时,请–不要。 它不时发生,现在您对原因有了更好的了解。 如果您对此主题感兴趣,我建议以下资源以供进一步阅读:

翻译自: https://www.sitepoint.com/inattention-blindess-missing-the-obvious/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值