This post is part of a series, starting at Reflections on a decade of coding.
这篇文章是一个系列的开始,起始于《对十年编程的反思》。
One of my favorite questions to ask people is: what are some things that you used to strongly believe but have now changed your mind about?
我最喜欢问人们的一个问题是:你曾经坚信的一些事情现在改变了看法吗?
Here are some of mine.
这是我的一些例子。
Everyone is doing it wrong
每个人都做错了
Here are some quotes that I would have agreed with 10 years ago:
这里有一些我十年前会同意的引用:
Computing spread out much, much faster than educating unsophisticated people can happen. In the last 25 years or so, we actually got something like a pop culture, similar to what happened when television came on the scene and some of its inventors thought it would be a way of getting Shakespeare to the masses. But they forgot that you have to be more sophisticated and have more perspective to understand Shakespeare. What television was able to do was to capture people as they were. So I think the lack of a real computer science today, and the lack of real software engineering today, is partly due to this pop culture.
计算机的发展速度远远快于教育不成熟的人。在过去的 25 年左右,我们实际上得到了类似于电视出现时的流行文化,一些发明者认为这将是将莎士比亚带给大众的方式。但他们忘记了,要理解莎士比亚,你必须更成熟并拥有更广阔的视角。电视能够做到的是捕捉人们的真实状态。因此,我认为今天缺乏真正的计算机科学和真正的软件工程,部分原因是这种流行文化。
[...] the only programmers in a position to see all the differences in power between the various languages are those who understand the most powerful one. You can't trust the opinions of the others, because of the Blub paradox: they're satisfied with whatever language they happen to use, because it dictates the way they think about programs.
[...] 只有那些理解最强大语言的程序员才能看到各种语言之间的权力差异。你不能相信其他人的意见,因为布鲁布悖论:他们对自己所使用的语言感到满意,因为这决定了他们对程序的思考方式。
[...] clearly revolutionizes software as most know it. It could lead to efficient, reliable applications. But that won't happen. A mainstay of our economy is the employment of programmers. A winnowing by factor 100 is in no one's interest. Not the programmers, the companies, the government. To keep those programmers busy requires clumsy languages and bugs to chase.
[...] 明显地彻底改变了我们所知的软件。它可能会导致高效、可靠的应用程序。但这不会发生。我们经济的一个支柱是程序员的就业。减少 100 倍的需求对任何人都没有好处。对程序员、公司和政府都没有好处。要让这些程序员保持忙碌,需要笨拙的语言和需要追逐的错误。
[...] the reason we are facing bugs that kill people and lose fortunes, the reason that we are facing a software apocalypse, is that too many programmers think that schedule pressure makes it OK to do a half-assed job.
[...] 我们面临导致人们死亡和损失巨额财富的错误的原因,我们面临软件末日的原因,是因为太多程序员认为时间压力使得做一个马虎的工作是可以接受的。
It's easy to find examples of this idea - that everyone is doing computers completely wrong and that there exist simple solutions (and often that everyone else is just too lazy/stupid/greedy/immoral to adopt them).
很容易找到这个想法的例子——每个人都在完全错误地使用计算机,并且存在简单的解决方案(而且通常是因为其他人太懒惰/愚蠢/贪婪/不道德而不愿意采用它们)。
X is amazing, so why isn't everyone using it? They must be too lazy to learn new things. Y is such a mess, why didn't they just build something simple and elegant instead. They must just be corporate jobsworths who don't care about quality. Why are all those researchers excited about Z? They just don't understand what the real world is like from up in their ivory tower.
X 是惊人的,那为什么不是每个人都在使用它呢?他们一定是太懒惰去学习新东西。Y 是如此混乱,为什么他们不直接构建一些简单而优雅的东西呢?他们一定只是那些不关心质量的公司职员。为什么那些研究人员对 Z 感到兴奋?他们只是在象牙塔里不理解现实世界是什么样的。
It's not limited to programming, of course:
当然,这不仅限于编程:
Instead of losing faith in the power of government to work miracles, people believed that government could and should be working miracles, but that the specific people in power at the time were too corrupt and stupid to press the "CAUSE MIRACLE" button which they definitely had and which definitely would have worked. And so the outrage, the protests - kick these losers out of power, and replace them with anybody who had the common decency to press the miracle button!
人们并没有失去对政府创造奇迹能力的信心,而是相信政府可以并且应该创造奇迹,但当时掌权的具体人选太腐败和愚蠢,无法按下“创造奇迹”按钮,而这个按钮确实存在,并且肯定会有效。因此,愤怒和抗议——把这些失败者赶下台,换上任何一个有基本良知的人来按下奇迹按钮!
-- Book review: the revolt of the public
-- 书评:公众的反抗
It's so easy to think that simple solutions exist. But if you look at the history of ideas that actually worked, they tend to only be simple from a distance. The closer you get, the more you notice that the working idea is surrounding by a huge number of almost identical ideas that don't work.
很容易认为简单的解决方案是存在的。但如果你看看那些真正有效的思想的历史,它们从远处看似乎简单,但越靠近,你越会注意到,那个有效的想法周围环绕着大量几乎相同但无效的想法。
Take bicycles, for example. They seem simple and obvious, but it took two centuries to figure out all the details and most people today can't actually locate the working idea amongst its neighbours.
以自行车为例。它们看起来简单而明显,但花了两个世纪才弄清楚所有细节,而大多数人今天实际上无法在其邻近的概念中找到有效的想法。
Even when old niche ideas make a comeback (eg neural networks) it's not because they were right all along but because someone recognized the limitations and found a new variation on the idea that overcame them (eg deep learning).
即使是旧的利基想法重新流行(例如神经网络),也不是因为它们一直是正确的,而是因为有人认识到其局限性并找到了克服这些局限性的新变体(例如深度学习)。
I imagine some fans of the penny farthing groused about how everyone else was just too lazy or cowardly to ride them. But widespread adoption of bicycles didn't come from some general upswelling of moral fortitude. It came from someone figuring out a design that was less prone to firing the rider headfirst into the ground whenever they hit a bump.
我想一些骑着古董自行车的人会抱怨其他人只是太懒惰或胆小而不愿骑它们。但自行车的广泛采用并不是因为人们普遍涌现出道德勇气,而是因为有人找到了一个设计,减少了骑行者在遇到颠簸时头朝下摔倒的可能性。
Finding the idea that actually works amidst the sea of very similar ideas that don't work requires staying curious long enough to encounter the fine-grained detail of reality and humble enough to recognize and learn from each failure.
在一大堆相似但无效的想法中找到真正有效的想法,需要保持足够的好奇心,以便接触到现实的细微细节,并且要谦逊到能够认识到并从每一次失败中学习。
It's ok to think that things have flaws or could be improved. But it's a trap to believe that it's ever the case that a simple solution exists and everyone else is just too enfeebled of character to push the miracle button. All the miracle buttons that we know about have already been pressed.
认为事物有缺陷或可以改进是可以的。但相信简单的解决方案永远存在,而其他人只是性格软弱而无法按下奇迹按钮,这是一种陷阱。我们所知道的所有奇迹按钮都已经被按下。
I learned this the hard way at Eve. Starting from my very earliest writing about it there was a pervading idea that we were going to revolutionize everything all at once. It took me two years to gradually realize that we were just hopping from one superficial idea to another without making any progress on the fundamental problems.
我在 Eve 上以艰难的方式学到了这一点。从我最早的写作开始,就有一种普遍的想法,我们将一次性彻底改革一切。花了我两年时间才逐渐意识到,我们只是在一个个肤浅的想法之间跳跃,而没有在根本问题上取得任何进展。
I remember at one early point estimating that it would take me two weeks to put together a reasonable query planner and runtime. The first time I even came close to success on that front was 3 years later. Similarly for incremental maintenance, which I'm still figuring out 7 years later.
我记得在一个早期的时刻,我估计需要两周的时间来组建一个合理的查询规划器和运行时。第一次接近成功是在 3 年后。增量维护也是如此,我至今仍在努力解决,已经过去 7 年了。
It's not that our ideas were bad. It's just that we assumed so strongly that the problems must be simple that we kept looking for simple solutions instead of making use of the tools that were available, and we kept biting off more than we could chew because we didn't believe that any of the problems would take us long to solve.
并不是说我们的想法不好。只是我们过于坚信问题一定很简单,以至于我们不断寻找简单的解决方案,而不是利用现有的工具,并且我们不断承担超出自己能力的任务,因为我们不相信任何问题会花费我们太长时间去解决。
Contemporaries like airtable instead started by solving an appropriately-sized subset of the problem and putting in the years of work to progressively fill in all the tiny details that make their solution actually useful. Now they're in a solid position to keep chipping away at the rest of the problem.
像 Airtable 这样的同时代人则开始于解决问题的一个适当规模的子集,并投入多年的工作,逐步填补所有使他们的解决方案真正有用的细节。现在他们处于一个稳固的位置,可以继续逐步解决其余的问题。
Programming should be easy
编程应该是简单的
A similar trap hit often got me on a smaller scale. Whenever I ran up against something that was ugly or difficult, I would start looking for a simpler solution.
类似的陷阱常常以较小的规模困扰着我。每当我遇到丑陋或困难的事情时,我就会开始寻找更简单的解决方案。
For example when I tried to make a note-taking app for tablets many years ago I had to make the gui, but gui tools are always kind of gross so I kept switching to new languages and libraries to try to get away from it. In each successive version I made less and less progress towards actually building the thing and had to cover more and more unknown ground (eg qtjava relies on using reflection to discover slots and at the time was difficult to implement the correct types from clojure). I wasted many hours and never got to take notes on my tablet.
例如,许多年前我尝试为平板电脑制作一个记笔记的应用时,我必须制作图形用户界面,但图形用户界面工具总是有点糟糕,所以我不断切换到新的语言和库,试图摆脱它。在每个后续版本中,我在实际构建这个东西方面的进展越来越少,必须覆盖越来越多未知的领域(例如,qtjava 依赖于使用反射来发现插槽,而当时从 clojure 实现正确的类型是困难的)。我浪费了很多时间,最终没有在我的平板电脑上记笔记。
If you have a mountain of shit to move, how much time should you spend looking for a bigger shovel? There's no obviously correct answer - it must depend on the size of the mountain, the availability of large shovels, how quickly you have to move it etc. But the answer absolutely cannot be 100% of your time. At some point you have to shovel some shit.
如果你有一堆屎要搬,你应该花多少时间去找一个更大的铲子?没有明显正确的答案——这必须取决于山的大小、大铲子的可用性、你必须多快搬走它等等。但答案绝对不能是你时间的 100%。在某个时刻,你必须开始铲屎。
I definitely feel I've gotten better at this. When I wanted to write a text editor last year I spent a few days learning the absolute basics of graphics programming and text rendering, used mostly mainstream tools like sdl and freetype, and then just sat down and shoveled through a long todo list. In the end it only took 100 hours or so, much less time than I spent thrashing on that note-taking app a decade ago. And now I get to use my text editor all the time.
我确实觉得我在这方面变得更好了。去年我想写一个文本编辑器时,花了几天时间学习图形编程和文本渲染的基本知识,主要使用了像 sdl 和 freetype 这样的主流工具,然后就坐下来处理一长串待办事项。最后只花了大约 100 个小时,远远少于我十年前在那个笔记应用上浪费的时间。现在我可以随时使用我的文本编辑器。
Sometimes the mountain isn't actually as big as it looks. And the nice thing about shoveling shit is that you get a lot faster with practice.
有时候山并不像看起来那么大。而铲屎的好处是你练习得越多,速度就越快。
The new thing is better
新事物更好
As a corollary to searching for the easy way, I've always been prone to spending far too much time on new or niche ideas. It's usually programming languages that get me, but I see other people do the same with frameworks, methodologies or architectures too. If you're really attracted to novelty you can spend all your time jumping between new things and never actually engage with the mainstream.
作为寻找简单方法的结果,我总是倾向于在新想法或小众想法上花费过多时间。通常是编程语言让我如此,但我看到其他人也在框架、方法论或架构上做同样的事情。如果你真的被新奇吸引,你可能会花费所有时间在新事物之间跳跃,而从未真正参与主流。
Mainstream ideas are mainstream for a reason. They are, almost by definition, the set of ideas which are well understood and well tested. We know where their strengths are and we've worked out how to ameliorate their weaknesses. The mainstream is the place where we've already figured out all the annoying details that are required to actually get stuff done. It's a pretty good place to hang out.
主流思想之所以成为主流是有原因的。它们几乎是定义上被广泛理解和经过充分测试的一组思想。我们知道它们的优势所在,并且已经找出了如何改善它们的弱点。主流是我们已经解决了所有实际完成工作所需的烦人细节的地方。这是一个相当不错的地方。
Of course there is value in exploring new ideas, but to be able to sift through the bad ideas and nurture the good ones you have to already thoroughly understand the existing solutions.
当然,探索新想法是有价值的,但要能够筛选出糟糕的想法并培养好的想法,你必须已经彻底理解现有的解决方案。
For example, at Eve I didn't read any of the vast literature on standard approaches to SQL query planning. I only looked at niche ideas that promised to be simpler or better, despite being completely untested (eg tetris-join). But even after implementing some hot new idea I couldn't tell if it was good or bad because I had no baseline to compare it to. Whereas a group that deeply understands the existing tools can take a new idea like triejoin and compare it to the state of the art, understand its strengths and weaknesses and use it appropriately.
例如,在 Eve 时我没有阅读关于 SQL 查询规划的标准方法的广泛文献。我只关注那些承诺更简单或更好的小众想法,尽管这些想法完全未经测试(例如 tetris-join)。但即使在实现了一些热门新想法后,我也无法判断它是好是坏,因为我没有基准可以进行比较。而一个深刻理解现有工具的团队可以将像 triejoin 这样的新想法与现有技术进行比较,理解其优缺点并适当地使用它。
I also remember long ago dismissing people who complained that some hot new niche language was missing a debugger. At the time I did that because I didn't see the need for a debugger when you could just reason about code algebraically. But in hindsight, it was also because I had never used a debugger in anger, had never watched anyone using a debugger skillfully, and had never worked on a project whose runtime behavior was complicated enough that a debugger would be a significant aid. And all of that was because I'd spent all my time in niche languages and instead of becoming fluent in some ecosystem with mature tooling like java or c#.
我还记得很久以前曾经对那些抱怨某种热门新小众语言缺少调试器的人嗤之以鼻。当时我这样做是因为我没有看到在可以通过代数推理代码时需要调试器的必要性。但事后看来,这也是因为我从未在实际中使用过调试器,从未看过任何人熟练地使用调试器,也从未参与过一个运行时行为复杂到调试器会显著帮助的项目。而这一切都是因为我花了所有时间在小众语言上,而不是在像 Java 或 C#这样拥有成熟工具链的生态系统中变得流利。
The frontier is the place to go mining for new ideas, but it's 1% gold and 99% mud. If you live your whole life there you'll never know what indoor plumbing is like and you'll find yourself saying things like "real programmers don't need toilet paper".
边界是挖掘新想法的地方,但那里只有 1%的黄金和 99%的泥土。如果你一辈子都生活在那里,你将永远不知道室内管道是什么样的,你会发现自己说出“真正的程序员不需要卫生纸”这样的事情。
Learning X will make you a better programmer
学习 X 会让你成为更好的程序员
For the most popular values of X, I haven't found this to be true.
对于 X 的最流行值,我发现这并不是真的。
I think these claims are a lot like how people used to say that learning latin makes you smarter. Sure, learning things is fun. And various bits of knowledge are often useful within their own domain. But overwhelmingly, the thing that made me better at programming was doing lots of programming, and especially working on problems that pushed the limits of my abilities.
我认为这些说法很像人们曾经说的学习拉丁语会让你更聪明。没错,学习东西是有趣的,各种知识在其自身领域内通常是有用的。但压倒性地说,让我在编程方面变得更好的原因是做了大量的编程,尤其是解决那些挑战我能力极限的问题。
Languages 语言
The first language I learned was haskell and for several years I was devoted to proclaiming its innate superiority. Later on I wrote real production code in ocaml, erlang, clojure, julia and rust. I don't believe any of this improved my programming ability.
我学的第一种语言是 Haskell,几年以来我一直致力于宣扬它的内在优越性。后来我在 OCaml、Erlang、Clojure、Julia 和 Rust 中编写了真正的生产代码。我不相信这些提高了我的编程能力。
Despite spending many years writing haskell, when I write code today I don't use the ideas that are idiomatic in haskell. I write very imperative code, I use lots of mutable state, I avoid advanced type system features. These days I even try to avoid callbacks and recursion where possible (the latter after a nasty crash at materialize). If there was an alternate universe where I had only ever learned c and javascript and had never heard of any more exotic languages, I probably still would have converged to the same style.
尽管花了很多年写 Haskell,但今天写代码时我并不使用 Haskell 中的习惯用法。我写的是非常命令式的代码,使用了很多可变状态,避免使用高级类型系统特性。这些天我甚至尽量避免使用回调和递归(后者是在 Materialize 发生了一次严重崩溃之后)。如果有一个平行宇宙,我只学过 C 和 JavaScript,从未听说过任何更奇特的语言,我可能仍然会趋向于相同的风格。
That's not to say that languages don't matter. Languages are tools and tools can be better or worse, and there has certainly been substantial progress in language design over the history of computing. But I didn't find that any of the languages I learned had a special juice that rubbed off on my brain and made me smarter.
这并不是说语言不重要。语言是工具,而工具可以更好或更差,计算机历史上在语言设计方面确实有了显著进展。但我没有发现我学过的任何语言对我的大脑有特别的影响,让我变得更聪明。
If anything, my progress was often hampered by the lack of libraries, unreliable tools and not spending enough time in any one ecosystem to develop real fluency. These got in the way of working on hard problems, and working on hard problems was the main thing that actually led to improvement.
如果说有什么的话,我的进步常常受到图书馆不足、不可靠的工具以及在任何一个生态系统中花费的时间不够而受到阻碍。这些妨碍了我解决困难问题,而解决困难问题正是实际导致进步的主要因素。
By way of counter-example, check out this ICFP contest retrospective. Nikita is using clojure, a pretty niche language, but has built up incredible fluency with both the language and the ecosystem so that he can quickly throw out web scrapers and gui editors. Whereas I wouldn't be able to quickly solve those problems in any language after flitting around from ecosystem to ecosystem for 12 years.
作为反例,看看这个 ICFP 比赛的回顾。尼基塔使用的是 clojure,一种相当小众的语言,但他在语言和生态系统方面已经建立了令人难以置信的流利度,以至于他可以快速编写网络爬虫和图形用户界面编辑器。而我在 12 年间从一个生态系统跳到另一个生态系统后,无法在任何语言中快速解决这些问题。
(See also A defense of boring languages, Your language sucks, it doesn't matter)
(另见《无聊语言的辩护》,《你的语言很糟糕,这无所谓》)
Functional programming 函数式编程
(Specifically as it appears in haskell, clojure, elm etc.)
(具体如在 Haskell、Clojure、Elm 等中出现的那样。)
I do find it useful to try to organize code so that most functions only look at their explicit inputs, and where reasonable don't mutate those inputs. But I tend to do that with arrays and hashtables, rather than the pointer-heavy immutable structures typically found in functional languages. The latter imposes a low performance ceiling that makes many of the problems I work on much harder to solve.
我确实发现尝试组织代码是有用的,这样大多数函数只关注它们的显式输入,并且在合理的情况下不改变这些输入。但我倾向于使用数组和哈希表,而不是功能语言中通常使用的指针重的不可变结构。后者施加了一个低性能上限,使我处理的许多问题变得更加困难。
The main advantage I see in functional programming is that it encourages tree-shaped data, one-way dataflow and focusing on values rather than pointer identity. As opposed to the graph-of-pointers and spaghetti-flow common in OOP languages. But you can just learn to write in that style from well-designed imperative code (eg like this or this). And I find it most useful at a very coarse scale. Within the scope of a single component/subsystem, mutation is typically pretty easy to keep under control and often very useful.
我看到函数式编程的主要优点是它鼓励树形数据、单向数据流以及关注值而不是指针身份。这与面向对象编程语言中常见的指针图和意大利面条式的数据流相对立。但你可以通过良好设计的命令式代码(例如像这个或这个)学习以那种风格编写代码。我发现它在非常粗略的层面上最有用。在单个组件/子系统的范围内,变异通常相对容易控制,并且通常非常有用。
(Eg here the top-level desugar
function is more or less functional. It's internals rely heavily on mutation, but they don't mutate anything outside the Desugarer
struct.).
(例如,这里顶层的 desugar
函数或多或少是功能性的。它的内部依赖于变异,但它们不会改变 Desugarer
结构之外的任何东西。)
Lambda calculus / category theory / automata / ...
λ 演算 / 范畴理论 / 自动机 / ...
Certain areas of maths and computer science attract a completely inappropriate degree of mystique. But, like languages, bodies of theory are tools that have a specific use.
数学和计算机科学的某些领域吸引了完全不适当的神秘感。但是,就像语言一样,理论体系是具有特定用途的工具。
- Lambda calculus is useful mainly as a simple standard language for explaining new PL ideas. You need to be familiar with it only if you want to read or write PL papers.
λ 演算主要作为一种简单的标准语言,用于解释新的编程语言思想。只有当你想阅读或撰写编程语言论文时,你才需要熟悉它。 - Automata theory and language classes are only really useful if you're trying to expand the state of the art (eg inventing treesitter). Even though I write parsers all the time, in practice what I need to remember is a) write recursive descent parsers (like most major language implementations) b) google "pratt parsing" when dealing with operator precedence.
自动机理论和语言类只有在你试图扩展技术前沿时才真正有用(例如发明 treesitter)。尽管我一直在编写解析器,但实际上我需要记住的是 a) 编写递归下降解析器(像大多数主要语言实现一样) b) 在处理运算符优先级时谷歌“pratt parsing”。 - Category theory is the only undergrad class I regret, a hundred hours of my life that has yet to help me solve a single problem or grant any fresh insight.
范畴论是我唯一后悔的本科课程,花费了我一百个小时的生命,却至今没有帮助我解决任何问题或提供任何新的见解。
On the other hand, there are much less sexy areas that have been consistently useful throughout my entire career:
另一方面,还有一些不那么吸引人的领域,在我的整个职业生涯中一直非常有用:
- Very basic probability and statistics are crucial for doing performance estimates, analyzing system behavior, designing experiments, making decisions in life in general.
非常基础的概率和统计对于进行性能估计、分析系统行为、设计实验以及在生活中做出决策至关重要。 - Having even the most basic Fisher-Price model of how hardware works makes it much easier to write fast software.
甚至对硬件工作原理有最基本的了解,使得编写快速软件变得容易得多。 - Being fluent in the core language of mathematics (basic logic, sets, functions, proof techniques) makes it easy to pick up domain-specific tools when I need them eg statistical relational learning when working at relational.ai, bidirectional type inference for imp.
精通数学的核心语言(基本逻辑、集合、函数、证明技巧)使我在需要时能够轻松掌握特定领域的工具,例如在 relational.ai 工作时的统计关系学习,或是对 imp 的双向类型推断。
And of course my day-to-day work relies heavily on being able to construct proofs, analyze algorithms (with heavy caveats about using realistic cost models and not erasing constant factors), and being fluent in the various standard algorithmic techniques (hashing, sorting, recursion, amortization, memoization etc).
当然,我的日常工作在很大程度上依赖于能够构造证明、分析算法(在使用现实成本模型时有很大的警告,并且不消除常数因素),以及熟练掌握各种标准算法技术(哈希、排序、递归、摊销、记忆化等)。
(See How to solve it for proof heuristics, How to prove it for core math literacy, Statistical rethinking for modelling probabilistic problems.)
(参见《如何解决它》中的证明启发式,《如何证明它》中的核心数学素养,《统计重思》中的建模概率问题。)
I've nothing against theory as a tool. If you do data science, learn statistics. If you do computer graphics, learn linear algebra. Etc.
我对理论作为工具没有任何反对意见。如果你做数据科学,就要学习统计。如果你做计算机图形学,就要学习线性代数。等等。
And if you're interested in eg the theory of computation for its own sake, that's great. It's a fascinating subject. It just isn't an effective way to get better at programming, despite people regularly proclaiming otherwise.
如果你对计算理论本身感兴趣,那很好。这是一个迷人的主题。尽管人们常常宣称相反,但这并不是提高编程能力的有效方法。
For all of the above, the real kicker is the opportunity cost. The years that I spent messing around with haskell were not nearly as valuable to me as the week I spent learning to use rr. Seeking out jobs where I could write erlang meant not seeking out jobs where I could learn how cpus work or how to manage a long-lived database. I don't write erlang any more, but I still use cpus sometimes.
对于以上所有,真正的关键在于机会成本。我花在玩 Haskell 上的那些年对我来说并没有我花一周时间学习如何使用 rr 那么有价值。寻找可以写 Erlang 的工作意味着不去寻找可以学习 CPU 工作原理或如何管理长期数据库的工作。我现在不再写 Erlang,但有时我仍然使用 CPU。
Life is short and you don't get to learn more than a tiny fraction of the knowledge and skills available, so if you want to make really cool stuff then you need to spend most of your time on the highest-leverage options and spend only a little time on the lottery tickets.
生命短暂,你无法学习到可用知识和技能的微小一部分,因此如果你想创造真正酷的东西,你需要将大部分时间花在最高杠杆的选择上,只花一点时间在彩票上。
I expect people to object that you never know what will turn out to be useful. But you can make smart bets.
我预计人们会反对说你永远不知道什么会变得有用。但你可以做出明智的选择。
If I could go back and do it again, I would spend the majority of my time trying to solve hard/interesting problems, using whatever were the mainstream languages and tools in that domain, and picking up any domain-specific knowledge that actually came up in the course of solving a problem. Focus on developing fluency and deep expertise in some area, rather than chasing the flavor of the day.
如果我能回到过去再做一次,我会花大部分时间去解决困难/有趣的问题,使用该领域的主流语言和工具,并在解决问题的过程中获取任何实际出现的领域特定知识。专注于在某个领域发展流利度和深厚的专业知识,而不是追逐当下的潮流。
Intelligence trumps expertise
智力胜过专业知识
People don't really say this explicitly, but it's conveyed by all the folk tales of the young college dropout prodigies revolutionizing everything they touch. They have some magic juice that makes them good at everything.
人们并不真的明确地说出这一点,但通过所有关于年轻大学辍学生天才颠覆一切的民间故事,这一点得到了传达。他们拥有某种魔法般的能力,使他们在所有事情上都表现出色。
If I think that's how the world works, then it's easy to completely fail to learn. Whatever the mainstream is doing is ancient history, whatever they're working on I could do it in a weekend, and there's no point listening to anyone with more than 3 years experience because they're out of touch and lost in the past.
如果我认为这就是世界运作的方式,那么我就很容易完全无法学习。无论主流在做什么都是古老的历史,无论他们在做什么我都可以在一个周末完成,听任何有超过三年经验的人都没有意义,因为他们脱离现实,迷失在过去。
Similarly for programmers who go into other fields expecting to revolutionize everything with the application of software, without needing to spend any time learning about the actual problem or listening to the needs of the people who have been pushing the boulder up the hill for the last half century.
同样,对于那些进入其他领域的程序员来说,他们期望通过软件的应用来彻底改变一切,而不需要花时间去了解实际问题或倾听那些在过去半个世纪里一直在推动石头上坡的人们的需求。
This error dovetails neatly with many of the previous errors above eg no point learning how existing query planners work if I'm smart enough to arrive at a better answer from a standing start, no point learning to use a debugger if I'm smart enough to find the bug in my head.
这个错误与上面许多之前的错误恰好相吻合,例如,如果我足够聪明可以从零开始得出更好的答案,那么学习现有查询规划器的工作原理就没有意义;如果我足够聪明可以在脑海中找到错误,那么学习使用调试器也没有意义。
But a decade of mistakes later I find that I arrived at more or the less the point that I could have started at if I was willing to believe that the accumulated wisdom of tens of thousands of programmers over half a century was worth paying attention to.
但经过十年的错误后,我发现我到达的地方大致是我如果愿意相信数万名程序员在半个世纪积累的智慧是值得关注的,我本可以从那里开始的地方。
And the older I get, the more I notice that the people who actually make progress are the ones who are keenly aware of the bounds of their own knowledge, are intensely curious about the gaps and are willing to learn from others and from the past. One exemplar of this is Julia Evans, whose blog archives are a clear demonstration of how curiosity and lack of ego is a fast path to expertise.
随着年龄的增长,我越来越注意到,真正取得进展的人是那些清楚自己知识界限的人,他们对知识的空白充满好奇,并愿意向他人和过去学习。朱莉亚·埃文斯就是一个典范,她的博客档案清楚地展示了好奇心和缺乏自我意识是通往专业知识的快速路径。
Explore vs exploit 探索与利用
This is the core tradeoff embodied by many of the mistakes above. When faced with an array of choices, do you keep choosing the option that has a known payoff (exploit) or do you take a chance on something new and maybe discover a bigger payoff (explore).
这是许多上述错误所体现的核心权衡。当面临一系列选择时,你是选择继续选择已知收益的选项(利用),还是冒险尝试一些新的东西,可能会发现更大的收益(探索)。
I've consistently leaned way too hard towards explore, leaving me with a series of low payoff lottery tickets and a much less solid base to execute from.
我一直过于倾向于探索,这让我拥有了一系列低收益的彩票,而没有一个更稳固的基础来执行。
If I had instead made a conscious decision to spend, say, 2/3rds of my time becoming truly expert in some core set of safe choices and only 1/3rd exploring new things, I believe I would have come out a much more capable programmer and be able to solve more interesting problems. Because I've watched some of my peers do exactly that.
如果我当初做出一个有意识的决定,将大约三分之二的时间花在真正精通一组安全选择上,而只有三分之一的时间去探索新事物,我相信我会成为一个更有能力的程序员,能够解决更有趣的问题。因为我看到我的一些同龄人正是这样做的。