十年编程反思:一些不好的建议
这篇文章是一个系列的一部分 –十年编程反思。
像许多程序员一样,我基本上是自学成才的。我很少与比我更有经验的人一起工作,尤其是在我职业生涯的早期,我花了很多时间与其他 20 多岁的年轻人一起工作,他们也只有几年的经验。因此,我们都从互联网上找到的建议中学会了如何编程,尤其是通过 reddit 和 hacker news 等网站分享的帖子。
从那时起,我的大部分进步得益于忘掉这些东西。事后看来,我在网上读到的大多数关于如何编程的文章和讨论都对我写出好用的代码的能力是有害。
这并不是说大多数程序员都是糟糕的程序员。只是,好的程序员不会自动提出好的建议,或者好的建议会比坏的建议更广泛地分享。
生搬硬套
选择悖论是一个广为流传的民间故事,讲的是一个实验,在这个实验中,超市陈列的果酱种类越多,购买量就越少。给出的解释是,选择是有压力的,所以有些人,面对太多可能的果酱,左右为难无法选择,最后空手而归。这个实验经常被新闻和媒体引用,通常描述为“科学家发现选择对你有害”这样的描述。
但是,如果你去一家大型超市,你会看到大约1200万种果酱。难道他们没有听说过果酱实验吗?吉姆·曼齐(Jim Manzi)在 《不受控制》中提到:
首先,请注意,所有的推论都是建立在总共购买了三十五罐果酱的基础上的。其次,请注意,如果果酱实验的结果是有效的,并且具有作为经济或社会政策基础所需的普遍性,那么这意味着许多商店可以淘汰75%的产品,并导致销售额增长900%。这将是一个相当令人震惊的结果,表明理论可能存在问题。
[…]在最初的实验中,研究人员自己对他们明确的普遍性主张很谨慎,并且已经投入了大量的精力来寻找选择超载持续发生的条件的确切问题,但是推广者将从一家商店在两个星期六的一次优惠券加展示促销中得出的结论进行了压缩,直到关于该商店果酱产品选择的影响的断言,到果酱产品选择对美国所有杂货店的影响,到关于产品选择对每家商店所有零售产品的影响的说法,最终到关于选择对社会的好处的相当夸张的说法。但正如我们所看到的,在不同情况下的50个实验中检验这种说法给这个断言泼了很多冷水。
作为一个实际的商业例子,即使是一个简化的因果机制,包括一个有用的前瞻性预测规则,也不太可能像“将QwikMart商店更名为FastMart将导致销售额上升”,而是更像“将QwikMart商店更名为FastMart在高收入社区的高交通道路上将导致销售额上升,只要商店关门刷漆不超过两天。“在开始测试之前,我们极不可能知道所有可能的隐藏条件,并且能够设计和执行一个发现这样一个充满条件的规则的测试。
此外,这些因果关系本身也可能经常发生变化。例如,我们发现,在一次测试中,一次特定的促销活动与没有促销活动相比,会带来净利润的增加,但到了明年,当大量的变化发生时–我们的竞争对手推出了新的促销活动,整体经济状况恶化,消费者流量从购物中心转移到了购物中心,等等–这条规则不再适用。为了扩展前面的比喻,我们正在通过我们的小腿撞到家具上来找到我们在黑暗的房间里的路,而未被观察到的小精灵则继续移动我们周围的家具。由于这些原因,仅仅进行实验,找到因果关系,并假设它是广泛适用的是不够的。我们必须运行测试,然后在实际实现中测量从这些测试中开发的规则的实际预测性。
每当我看到一篇博文时,我都会想到这一点,这篇博文的智慧来自单一领域的单一经验。“编程”涵盖了具有不同问题域、团队规模、管理结构、项目生命周期、部署规模、部署频率、硬件、性能要求、失败后果等的大量活动。我们应该预料到,任何给定的实践在所有这些情况下都是合适的,这是非常罕见的,更不用说我们可以从一些项目的结果中发现一般的最佳实践了。
(另见 泛化性危机。
细节决定成败。
隐性知识或隐性知识——与正式的、编纂的或显性的知识相反——是难以表达或提取的知识,因此更难通过写下来或口头化的方式转移给他人。这可以包括个人智慧、经验、洞察力和直觉。
[…]说一门语言、骑自行车、揉面团、演奏乐器或设计和使用复杂设备的能力需要各种知识,这些知识并不总是明确知道的,即使是专业从业者,也很难或不可能明确地传授给其他人。
— 维基百科
编程实践大多是隐性知识。隐性知识不容易分享。专家会讲述一些听起来很简单的经验法则,但随后在特定案例中对其进行研究将很快发现大量例外和警告,这些例外和警告因具体情况而异。这些是从许多过去的经验中产生的,不能很好地概括到该经验体系的背景之外。
在不知道所有这些细节的情况下尝试应用经验法则往往会导致失败。诸如“不要重复自己”、“你不需要它”、“关注点分离”、“测试驱动开发”等短语最初是从一些有效的经验中产生的,但后来被过度概括和过度应用,没有任何原始的细微差别。
传达隐性知识的方式,如果有的话,是通过产生规则的经验体系。出于这个原因,我发现在具体的经验报告或观察人们实际工作方面更有价值,而不是写一般原则。
混淆手段和目的
目标始终是编写一个程序来解决某些问题,并且可以在其使用寿命内进行维护。
在许多情况下,像“编写短函数”这样的建议是一种可能有助于实现该目标的技术,但它本身并不是一个目标。然而,人类思维的某些特征使得这些伪目标很容易取代实际目标。因此,您可能会听到人们说某些 软件很糟糕, 因为它的功能很长,即使有证据表明它也恰好易于维护。
当手段和目的被混淆时,它通常还伴随着“应该”这个词和其他具有一定道德或卫生分量的类似短语(例如“正确的方法”、“干净的代码”与“代码气味”)。这剥夺了对特定项目的背景或目标的任何考虑。
“如果你编写较短的函数,通常更容易在单元测试中隔离特定行为”是一个具体的声明,将行为和结果联系起来,你可以在特定项目的上下文中测试和评估。
“你应该写短函数”意味着如果你写长函数,你就是一个糟糕的程序员。无所适从。
不透明
科技公司通常通过使用简单的技术来解决业务问题来赚取令人难以置信的利润。这意味着这些公司的程序员可能会做出很多错误的决定,并采用糟糕的做法,但仍然会成功。无论你做什么,如果钱从天而降,那么没有太多的信息可以帮助发现更好的做法。
例如 ,Slack 是一个非常成功的产品。但似乎每周我都会遇到一个新错误,使它对我来说完全无法使用,从 键入时每个字符需要几秒钟 到 完全无法呈现消息。(另一方面,Discord 一直是可靠和活跃的,尽管从我高科技的谷歌搜索来看,它的员工数量是它的 1/3。因此,这并不是说聊天应用程序本质上是困难的。然而,Slack 的技术建议 很受欢迎 ,如果我在没有亲身体验结果的情况下遇到它,它可能看起来很有说服力。
错误的引导
像reddit、hacker news、twitter等社交网站在决定我自己和我认识的大多数其他程序员的大部分阅读材料方面占主导地位。这些网站强烈选择简短、易于阅读、娱乐性和伪争议性的观点。由于科技社区的快速发展,科技界也严重偏向于年轻和缺乏经验的人,因此投票机制并不是区分无聊的好主意和娱乐坏主意的有用机制。
我还怀疑这种动态有时是自我强化的。在看到许多投票率很高的评论支持某些特定的想法或座右铭之后,它开始听起来必须广为人知才能成为现实。因此,当您看到具有相同想法的新评论时,您会为他们给出正确答案而投票。这可以使想法持续存在,而不需要任何实际的成功来强化。(另见Applause lights。)
结论
事后看来,回头看看帮助我完成工作的一小部分写作,它往往来自以下人员:
- 多年工作经验
- 具有实质性的技术成果
- 有分寸和深思熟虑,而不是高度自信
- 承认复杂性和微妙性,而不是用一种方法来统治它们
例如,关于如何将代码组织成函数的主题, 对比 Martin Fowler:
如果你必须花精力查看一段代码来弄清楚它在做什么,那么 你应该 把它提取到一个函数中,并以“what”命名该函数。
任何超过六行代码的函数都开始闻到异味 […]
我不打算发布任何命令,但我希望每个人都认真考虑其中的一些问题。
如果函数仅从单个位置调用,请考虑将其内联。
如果从多个位置调用函数,请查看是否可以安排在单个unit完成工作,也许使用函数,并将其内联。
如果一个函数有多个版本,请考虑使用更多(可能是默认参数)创建单个函数。
如果代码接近于纯函数式,很少引用全局状态,请尝试使其完全函数式。
当函数确实必须在多个地方使用时,尝试在参数和函数上使用 const。
最大限度地减少控制流的复杂性和“area under ifs”,有利于一致的执行路径和时间,而不是“最佳”避免不必要的工作。
更复杂的是,“总是做,然后抑制或忽略”策略虽然对于高可靠性系统来说是一个非常好的主意,但在mobile等功率和热受限的环境中不太合适。
希望不那么糟糕的建议
在本系列的其余部分,我希望避免或至少缓和上述故障模式。
首先,让我明确一下我写作的背景:
- ~70% 是自雇人士,~30% 在小型早期公司工作。
- ~40% 生产代码 vs ~60% 研究代码(即没有严重的开发,没有长期维护)
- ~30% 在代码库中,>100kloc 与 ~70% 的小型或绿色项目。
- 主要是系统问题,尤其是数据库引擎和声明式语言。
- 一些 UI 是有效的,但所有这些都是探索性的,而不是生产性的。
- 我从来没有维护过超过 2 年的代码库。
- 我从来不负责运行长期服务。
我报告的任何事情对我来说都很好,都必须在这种有限的背景下考虑。
其次,我的目标是用多个例子来配合每个想法。这有助于传达实际的细节,并确保我谈论的是我实际做的事情,而不是我认为我应该做的事情。
第三,在我能做到的地方,我包括一些反例,我曾经认为是个好主意的东西导致了问题,或者应用得不好。
本文文字及图片出自 On bad advice
你也许感兴趣的:
- 【外评】80% 的开发人员不开心
- 【外评】如何判断自己已成为高级程序员
- 【外评】如何成为最优秀的程序员
- 【外评】程序员大神每天什么都是时候工作?
- 【译文】在 Meta 工作 12 年:回顾我参与的所有项目
- 【译文】每个开发人员都需要问自己的一个问题
- 【译文】程序员工作很累,但 70% 的程序员在周末休息时以写代码为乐
- 【译文】我是一个糟糕的程序员
- 在技术圈逢凶化吉,靠的居然不是技术?Altman 晒出17条年终总结,人际关系占首位
- 【译文】加密货币交易平台FTX审判,第四天:欺诈在代码中
你对本文的反应是: