几个月前,我进行了一次演讲,分享了我的个人工程公理列表,这些年来,我认为在编写代码,构建代码时要牢记通常是正确且有用的事情。事情,并与他人合作。
公理是一个花哨的词,但是从词源学堆栈中跳了几层,我们很整洁地到达了古希腊词ἀξίωμα,或被认为合适或值得的那个词。我喜欢这样,并考虑清单上的每个项目至少值得考虑。
当然,它们是我的工程公理-根据我自己的经验,我认为这些都是有用的。您的经验可能会有所不同。也许您已经了解零终止,或者比剪刀有更好的工具可以消除程序中的错误。
无论如何,我认为在此处共享列表并进行一些简短的说明会很有趣。有些事情并不令人惊讶,但是希望其他事情会引起一些挑衅性的想法和/或有趣的分歧。
这个不应该太有争议。几乎所有事物都在不断变化,包括变化的速度本身。我们不仅需要承认我们应对变化的能力是至关重要的,而且还要知道我们做得如何(时间,成本,质量,可靠性)是我们竞争力的一个方面。
您的产品解决了客户的问题,因此是您的资产。代码本身就是创建资产的成本。您拥有的代码越多,就越需要阅读,测试,更改和理解它。当您考虑公理1时,这尤其重要。保守地接受新代码(以及对外部代码的依赖)。最好的代码是您不必编写的代码。
除非您有高度的信心说自己的抽象将自己付费,因为它可以解决您确实遇到的一个真实的抽象问题,所以请不要这样做。等待并了解更多。在此之前,重复代码可以帮助避免依赖性,这本身会使代码更易于独立更改或删除。过早的抽象会通过依赖性和间接性而导致复杂性,并且可能成为您对变更做出响应的能力的瓶颈。
编写可移动的代码,这在很大程度上与说" decoupled"相同。可以肯定的是,并非所有代码都需要类似地删除,但是可以最大限度地减少依赖关系,通过定义明确的接口具有清晰的边界以及具有深思熟虑的整体系统设计可以更轻松地删除/更改部件。我曾经听说有人使用“代码已用完”这一表达方式来代替“代码已编写”。我喜欢那个我喜欢删除代码可以降低未来成本的含义。
事实证明它是正确和必要的。希望是,但并非总是如此。我们既要保持改变它的信心,又要保持推理是否应该这样做的能力。不要让代码本身的存在使人们怀疑它是否会被删除。根据公理4,它应该易于删除,并且系统设计应该足够好,使我们能够了解是否仍然需要它。
偶然的复杂性是可以避免的复杂性,它是由于诸如不良的设计,错误的决策以及对系统内适当级别的简单性不优先而导致的。如果简单性不是目标,那么偶然的复杂性就很可能随着系统的增长而发生,并将逐渐对几乎所有事物产生负面影响,从更改系统到甚至无法理解它。关于这一主题,2006年的论文《焦油坑》非常值得一读。
除非您完全独自工作,否则重要的不只是您解决技术问题,编写良好代码等的能力。相反,如果您使周围的人感到不高兴和生产力降低,那么它们的重要性就更大。就像学习编写良好的代码一样,您必须向人们学习"很好。同情是其中很大的一部分,因为认识到人们与众不同–关心,理解,帮助他人,寻求帮助,变得友善。成为其他人想要与之共事的工程师。
8.您不是您的代码。对编码员要友善,对代码要友善。
代码仅仅是捕捉我们以为我们知道的东西的一瞬间。不是你。您可能已经编写了它,但是从那一刻起(即使是3分钟前),您已经长大了,但是代码却没有。关于代码的好坏的对话绝不应该是个人的。保持专业。谈论代码或问题,但不要让它与编写代码的人有关。使用" we"而不是"您"。有时我会假装自己写了别人写的代码,这有助于避免意外听起来个人化。
我们都从某个地方开始,当您被希望您成功的耐心的人包围着,而不是让那些让您觉得自己不属于自己的人陪伴时,旅途会更加快乐。如果您为此感到烦恼,请记住,新手程序员几乎可以肯定比您做得更好–也许他们精通另一种语言,或者做饭很棒,或者参加运动。想象一下自己在扮演相反的角色。新手,您希望他们如何对待您?再次:成为其他人想要与之合作的工程师。
对问题,领域,客户的了解和理解,远比名片上的前三个字母重要。即使确实有水印。从第一条原则了解事物是如何工作的,建立扎实的理解,然后才有权威。
如果您认为自己知道某些知识,请尝试教它。通常,试图向他人解释您所知道的事情的行为迫使您更加清晰地形式化自己的想法。写下来似乎有类似的效果。我已经失去了开始解释某件事的次数,却发现自己并没有像我想的那样完全理解它。
一个伟大的团队永远不会因为一个出色的人而变得伟大。这是一支很棒的团队,因为每个人都互相挑战,每个人共同成长。当您学到一些很棒的东西时,请与他人分享–帮助周围的人变得更好。就像他们一样,每个人都会受益,没有人会落后。它也更加有趣。次要好处:公理11。
我仍在学习这一点,并努力避免我几乎默认的快速决定的愿望。事实是,您延迟不必要的决定的时间越长,当需要时就必须依靠更多的信息。当然,您不能总是拖延一个决定,但是通常可以。至少,您至少应该考虑是否现在不知道答案是否可以。
在我的职业生涯中,通过各种静态和动态语言来回移动时,我目前认为,好的类型系统值得其开销。一个好的类型系统不应该承担那么多的开销。如果类型系统设计得当,它几乎可以感觉像是一种动态语言(通过推理和流分析等功能),同时消除了一类问题,编译器可以比您更快更好地处理这些问题。 Rust的所有权之类的发展就是一个很好的例子,说明这种情况比人们几年前所想象的还要远。
拥有一群只想一起工作并创造伟大事物的人会使许多其他问题更容易解决。 “正确”一词这是非常主观的和上下文相关的,但至少在轶事上,移情,尊重和友谊一直是我参与过的伟大团队的反复出现的要素。
无聊的技术通常更老,而且更好地理解。对于如何有效使用它,有扎实的经验,可以更好地了解其失败模式,并且可以更轻松地找到人和资源来更好地应用它。我真的很喜欢Dan McKinley的创新代币概念。您只有3个。使用它们来采用或构建全新的材料(理想情况下,这些材料可以使您的核心能力更好),但超过3个,永不达到稳定性/成熟度的风险开始增加。
用著名的报价打球,而您的里程可能与此不同。迄今为止,在我的职业生涯中,我可靠地看到较小的团队比较大的团队更有效率。当然,要找到一个平衡点,这取决于您要解决的问题的严重性和复杂性。也就是说,较小的团队可以从较少的通信开销,较少的误解空间以及更大的空间中受益,以使每个人都能听到自己的声音。在较小的团队中,它也感觉更个性化,我感觉更负责任,我喜欢那样。
我很高兴看到整个小时的工作逐渐消失,从而获得成功。态度,以及对心理健康和福祉的更多关注。当您不感到休息时,很难感到快乐,而当您不感到快乐时,要尽自己最大的努力就更加困难。为了达到最佳状态,我们必须花时间不工作。我喜欢将休息视为工作能力的关键部分,就像体育锻炼一样。
当那个东西在您的脑海中发出咔嗒声,并且您意识到自己找到了解决问题的方法时,这很诱人和令人兴奋。也许这是一个很酷的小问题,实际上无事可做。但是,如果问题不是简单的或重要的,则值得考虑的是,您可能还没有想到其他解决方案。
为了避免从无解决方案过渡到解决方案的兴奋,而只是想着脑海中的第一件事,请尝试再考虑至少一种。试图找到第二种解决方案通常会迫使您以不同的方式思考,一旦拥有两个解决方案,您将不得不考虑取舍以选择一个。这种相互取舍的权衡通常也可以帮助更清楚地解决问题。
20.有意见,但要避免以使他人相信您不会改变的方式表达意见。
表达我们的信念和观点很重要,我们所有人都应该有这样做的余地。但是,在分享观点和听起来好像在分享不可动摇的事实之间有一条很好的界限。在团队中,每个人都觉得自己可以挑战观点并可能改变观点或自己的观点,这是非常健康的。
我收到的一条很大的建议对此有帮助,那就是表达您的信念以及一定程度的确定性。我95%的人肯定使用Visual Basic是个坏主意。"即使达到95%,这既是一个供人们质疑信念并进行对话的机会,也为您提供了一个机会,可以在学习到新信息时简单地修改自己的确定性。
21.可以说我不知道或"我需要先研究一下,然后才能找到答案。
坦白说,我们没人知道我们在做什么。你做?好吧,我不知道。我们的行业发展迅速,尽管有许多新旧事物,但也有大量新事物。我们每天都在学习,没有答案绝对可以。我们的价值不是知道一切的能力,而是学习,发现,回答这些问题并提出新问题的能力。
当有人告诉我我不知道我很兴奋因为现在我知道我们可以一起探讨问题,并且都可以学到一些东西。不要把它藏起来,就好像你是唯一不认识的人一样。通常没有人知道,但是您的诚实使每个人都能公开参与并共同努力。
与几次尝试完全将其完全错误相比,重新将其完全错误可能会更快。有时,探索问题的最佳方法是将问题拧紧,并尽可能多地学习。
也许您还不是很了解问题空间,但是通过尝试一些事情,您可以发现关于设计的高级对话或阅读文档会完全错过的东西。拥有犯任意数量的错误并最终将其扔掉的自由,您可以快速学习。
每个程序都有状态,但是状态的管理方式可能会有所不同。状态管理不善是导致整个系统复杂性的巨大因素,并且经常发生,因为在问题变得更糟之前,还没有及早考虑它。
从特定方法到给定环境中的状态处理,再到使用功能语言和/或方法来围绕状态如何更改创建更严格的约束,有许多不同的策略可以提供帮助。无论您做什么,都要仔细考虑系统状态如何变化。
有了您做出的几乎每一个决定,您要么有意要么无意间权衡了一件事。有时权衡是显而易见的,但有时它们与我们在眼前看到的事物相距几层。始终在考虑如果权衡并非一目了然的话,权衡在哪里。
想到的一个很好的例子是Go。 Go的类型系统(当前)相当差,并且是一种很小的语言。权衡是什么?由于它的大小和对幻想的有限支持,我的代码看起来像您的代码,而我读其他人的代码的时候哇,哇,我需要尽快重写此代码。我比以往任何时候都更有生产力。总是在某处进行权衡。寻找它,您将可以做出更好的决定。
25.好的设计是一种您可以改变主意而无需更改过多代码的设计。
根据公理1,变化是恒定的。这意味着我们需要很好地处理不断变化的条件,以取得成功-不仅是发生在我们周围的外部变化,并带我们继续前进,还包括内部变化,这些变化来自枢轴,新功能,扩展挑战等。
一个好的系统设计应尽可能满足我们改变问题解决方式的需求,而不必强迫我们从头开始。换句话说,我们需要更改或删除的部分越少(根据公理4,这应该很容易),面对变化,我们就可以更快地进行移动。更好的设计。