捍卫模糊研究

2020-12-06 10:22:01

有时人们会问我应该怎样学习才能成为一个更好的程序员。我觉得这里的默认建议通常是晦涩的编程语言或某些高级机器(如ML)上的教科书。因此,当我建议深入了解您已经了解的内容时,我总是会感到有些尴尬和无聊:您的主要编程语言,Web框架,对象关系映射器,UI库,版本控制系统,数据库,Unix工具等。这不是闪亮的或深奥的,但对我来说,建立一个详细的思维模型(以及它们与替代方案的比较)可能是对我作为工程师的作用最大的学习。

一位同事创造了“俱乐部研究”一词来指代这种平凡的,超特定的知识。 “ Blub”来自Paul Graham的一篇文章,击败平均水平,其中Blub是一种假设的中间语言,当Graham断言Lisp优越时,其程序员会采取防御措施。模糊研究是对这些无聊的日常系统的内在状况进行的研究,而不是发明的任职期限,而是人们实际使用的那种。

模糊研究是工程技术永无止境的跑步机。这是有关Git如何存储数据,Postgres锁定语义如何导致您的迁移降低产品质量或为何这次pip安装失败的技术细节。这就是计算机锅炉房内部发生的事情。似乎有无穷无尽的内容,其中充满了定制的详细信息,让您迷失了方向,这常常令人难以置信地令人沮丧。机器学习等领域的专家撰写的文章听起来很响亮,例如《可学习的理论》; blub研究的专家散发着冗长的句子,例如“泄漏抽象定律”和“编程吸吮”。

简而言之,如果您要寻找随时间呈指数增长的可概括性知识,那么blub研究看起来就像您必须经过的废话才能获得的好东西。因此,很容易看出人们为什么会放弃对周围环境的理解,除了完成工作所需的东西。

但是对我而言,相反的态度更具生产力。电脑是可以理解的,即使很难而且需要一段时间。模糊研究比看起来更具有通用性,并且随着时间的流逝也有其自己的复合方式。这使它比您预期的有用得多。 ✻✻当然,blub研究没有什么用处:如果本文让您兴奋地记住一堆命令行标志,请考虑逆转此建议。但以我的经验来看,忽略blub的有用部分比对琐事过度索引更为常见。

blub专业知识最直接的好处是可以节省您的时间。 “如果您不具备首先通过点子安装进行斗争的知识和情感毅力,就无法应用从SICP那里学到的精辟见解。"如果您知道Git的内部模型是如何工作的,则可以将存储库从混乱状态中解脱出来,而无需花费大量时间进行Stack Overflow。

此效果比看起来要大。如果您使用的系统不了解,则只能通过猜测检查进行调试,这可能会很慢。一种更有效的方法是获取有关程序执行的尽可能多的信息,然后使用该信息排除大部分假设空间。但这需要对系统以及可用于检查系统的工具有充分的了解。例如,如果您正在跟踪网络问题,则盯着某些tcpdump输出通常会带您到达大多数地方,但前提是您知道如何解释它以及寻找什么。

如果您花费一半的编程时间进行调试,而成为blub专家则使您的调试速度快两倍,那么blub专业技术所带来的速度提升将使您的输出提高三分之一。 ††如果您认为“一半的编程时间调试”听起来很高,请想象一下,如果所有代码都第一次工作,您的速度会提高多少。调试速度加倍可能是一个保守的估计,您可以通过“嗯,Nagle算法的超时时间为40毫秒,尝试设置TCP_NODELAY”之类的方法来节省几乎无限的时间。我经常调试棘手的东西要比同事快5倍以上,这是因为我使用堆栈已有很长时间了,所以我知道在哪里寻找问题以及如何快速检验假设。这证明有很多时间盯着tcpdump输出!但是,还有很多微妙的原因使我从blub研究中受益匪浅。它比我预期的更通用,持续时间更长,并且具有更多的复合效果。

令人难以置信的是,模糊研究广泛地适用,因为即使您正在学习某些特定​​的笨拙系统的细节,该系统的设计也将包含可提取的通用原理的多汁,非笨拙的核心。与许多人试图教给您的“一般性原则”不同,您通过blub学习所学到的那些对保证至少对一个现实世界系统(您正在学习的系统)很重要。而且您会看到他们在所有凌乱的细节中都意识到了这一点,而学术报告经常忽略了这些细节。

假设您选择的对象是React。您可能会担心,如果您移至堆栈的不同部分甚至是不同的Web框架,则学习gory细节将毫无用处。是的,其中一些会。但是,React的核心思想(编写纯渲染函数,使用协调功能使更新速度更快)非常强大且通用。实际上,它已被iOS(SwiftUI)和Android(Jetpack Compose)上的下一代UI框架复制。学习React背后的原理使学习其他框架变得更加容易。实际上,它甚至可以成为从一个“导入”到另一个的思想的有用来源。例如,在Wave,我们从中继将思想导入到我们的移动应用程序中已经取得了很多进展。

这是一个很好的例子,据我所知,您只能通过blub学习来学习。学术界并未对React风格的UI编程给予太多关注。实际上,似乎根本没有将用户界面编程范例视为一个特别有趣的研究对象。人们有时会在上面发布它,但是,例如,我在MIT的广泛课程目录中找不到关于它的任何课程。 ‡‡您可能会争辩这是因为UI编程“应用过多”,并且不应期望它会被学术课程所涵盖。但是计算机科学涵盖了许多其他同样“应用”的领域,例如网络,数据库,操作系统和图形。

模糊研究还通过两种方式超出了您天真的期望。首先,了解一种blub使其更容易了解具有相同目的的替代blub,例如上面的React / SwiftUI示例。其次,更多地了解一种blub,可以帮助您更快地学习堆栈中相邻部分的blub。

有一次,当与一个更初级的同事进行结对编程时,我们正在编写一个复杂的SQLAlchemy查询。我的同事使用user.name(存储在user变量中的对象的名称字段)而不是User.name(User类的名称字段),并且想知道为什么她的查询给出了错误的结果。我试图解释“魔术”,其中User.name是Column的实例,而user.name是简单的str。我转了一圈,直到最终向她解释了Python的描述符协议(SQLAlchemy使用的语言功能来启用“声明式” ORM语法)。那时,一切都点击了—我意识到Python的__dunder__方法是解码很多“魔术”外观代码的关键。如果您很好地学习了Python语言功能,那么许多复杂的库将变得更容易理解。

我自己在Kubernetes上也有类似的经历。我第一次尝试学习它时,这真是一团混乱的行话—所有这些名称空间和容器以及Pod和Deployments,Services和Ingress只是为了运行一个简单的HTTP服务器!然后,我读了一本网络教科书,一切都变得更有意义了。 Kubernetes的(可能是)最复杂的部分可以解决与网络相关的问题-允许数百个容器在较小的计算机上托管时彼此独立地交谈-因此网络教科书为我提供了一个可以挂在其上的模式我所有的Kubernetes类事实。一旦我知道了Linux的IP路由,iptables和网络名称空间是如何工作的,对我来说,更容易理解“ kube-proxy”之类的功能。

如果您知道足够多的不同内容,那么您可能根本不需要查找所有内容即可弄清楚它们的实施方式(可能)。经验丰富的Python程序员可以立即猜测SQLAlchemy的“声明式” ORM是如何工作的。这就是您的blub专业知识真正开始复合的时候-几乎在您开始使用新事物时,您将开始弄清楚它是如何工作的,并提取出人们普遍感兴趣的想法的核心。

由于这种复合作用,要成为一名blub大师,最重要的步骤就是尽快启动“ blub飞轮”,即blub积累的良性循环。这意味着从最容易学习或最有动力的学习开始,然后从那里开始。对我来说,最简单的起点就是在日常工作中使用的blub。我有两种策略可以充分利用这些策略。

首先,我会尝试超出必要的范围。如果我真的想发货,很容易受到诱惑,例如向Google发送错误消息,从Stack Overflow复制粘贴修复程序,然后继续前进。但是,实际阅读该错误消息,了解其含义并尝试弄清为什么Stack Overflow答案可以解决我的问题,通常并不需要花费更长的时间。同样,如果我陷入棘手的y牛刮胡,我会偏向于“猜测并检查”样式的调试,以更好地了解我要调试的系统。例如,深入研究tcpdump和iptables规则的文档以跟踪我奇怪的一次性网络问题并不总是值得的,但是随着时间的推移,我遇到了足够多的“奇怪的一次性网络问题”,它已经获得了很多倍的回报。

我的blub飞轮的第二部分是注意魔术。每当我使用新的东西时,我都会不断地更新关于如何实现它的最好的思维模型。 “好吧,文档告诉我要创建一个Ingress,我想这可能是为负载均衡器提供了与我的后端容器对话的小部件吗?”如果我发现自己错了,我将进行挖掘和更新。 “嗯,我无法从集群外部ping这些pod,那么负载均衡器将如何与它们对话?啊哈-它正在与节点进行通信,并且有一个NodePort服务作为第二个间接层。”如果我完全不知道怎么做,那通常意味着该读一本书了。

我希望其他工程师能够简化blub研究的一件事是产生更多,更好的软件“高级”文档。大多数成熟且使用广泛的库都有不错的教程和介绍性内容,但是很少有库可以轻松地超过“复制粘贴示例”阶段。我认为这主要是组织和导航问题;如果我仔细研究一下SQLAlchemy文档,我实际上可以找到足够的信息来组成一个良好的系统思维模型,但是它分散在许多不同的页面中,并且不清楚应该以什么顺序阅读它们。React文档可能是我所知道的最好的,但仍然有很多遗漏。

随着时间的流逝,通过不断探索我正在研究的事物的内在魔力,我建立了广泛的知识基础,了解各种技术系统的工作方式。这以多种方式帮助我。它使在堆栈的多个层中追踪棘手的错误变得更加容易。通过将它们与我已经知道的内容进行模式匹配,我可以快速学习新的语言和库。通过模仿我见过的其他系统,或者在不同的环境中重用我所听到的想法或工具,它为我提供了更好的软件设计想法。也许最重要的是,它给了我信心,如果遇到一个棘手的问题,我将学到足够的知识来解决它,而不会觉得自己受制于过于复杂以至于无法理解的系统。

因此,如果您想学习一些可以使您成为更好,更快乐的程序员的知识,请问自己最常用的blub的哪些部分对您来说很神奇,然后尝试了解它们的工作原理。您将学到比您想像的还要多!