Torvalds关于优秀程序员的报价[关闭]


238

偶然地,我偶然发现了Linus Torvalds的以下引用:

“糟糕的程序员会担心代码。好的程序员会担心数据结构及其关系。”

最近几天我一直在考虑这个问题,但我仍然感到困惑(这可能不是一个好兆头),因此我想讨论以下内容:

  • 对这种可能/合理的解释是什么?
  • 从中可以学到什么?

18
我认为这个问题可能有多个同样有效的答案。但这还是个好问题。我喜欢那句话。它表达了为什么我不理解担心切换语言的程序员的原因。程序中很少使用语言,而是数据结构以及它们之间的关系。
瑞安·金纳尔

5
也许,如果您花时间使数据结构“优雅”,那么不必费解代码即可处理这些数据结构?我可能太傻了,以至于无法真正了解Torvalds报价的含义。:}
程序员

3
@RyanKinal但是语言当然很重要,因为它使处理和考虑某些数据结构变得相当容易。例如,考虑所有专门用于LISt解析的语言,或者对必须入侵其他语言的数据结构提供本地支持的语言(会想到集合和稀疏数组)。
kojiro

83
顺便说一下,Torvalds并不孤单:“向我展示您的流程图并隐藏您的表,我将继续感到困惑。向我展示您的表,我通常将不需要您的流程图;这很明显。 ” –弗雷德·布鲁克斯(Fred Brooks),《神话人月》。“向我展示您的代码并隐藏您的数据结构,我将继续感到困惑。向我展示您的数据结构,通常我不需要您的代码;这很明显。” 和“智能数据结构和哑代码比其他方法要好得多。” –埃里克·雷蒙德(Eric S. Raymond),大教堂和集市。
约尔格W¯¯米塔格

4
这解释了为什么Linux内核是一团糟:)
l1x 2012年

Answers:


326

考虑一下Torvalds在那之前所说的话可能会有所帮助:

git实际上具有简单的设计,具有稳定且记录良好的数据结构。实际上,我非常支持围绕数据设计代码,而不是相反地设计代码,并且我认为这是git相当成功的原因之一[...]实际上,我将声称两者之间的差异一个糟糕的程序员和一个好的程序员之间的关系是,他是否认为自己的代码或数据结构更重要。

他的意思是,好的数据结构使代码非常易于设计和维护,而最好的代码无法弥补不良的数据结构。

如果您想了解git示例,许多版本控制系统会相对定期地更改其数据格式,以支持新功能。升级以获得新功能时,通常还必须运行某种工具来转换数据库。

例如,当DVCS首次流行时,很多人都无法弄清楚分布式模型对合并的影响比集中版本控制要干净得多。答案是绝对没有,除非分布式数据结构必须要好得多才能完全有希望工作。我相信集中式合并算法已经赶上了,但是花了很长时间,因为它们的旧数据结构限制了它们可以使用的算法种类,而新的数据结构破坏了很多现有代码。

相比之下,尽管git中的功能大增,但其基础数据结构几乎没有改变。首先担心数据结构,您的代码自然会变得更干净。


25
最好的代码不能弥补不良的数据结构好的
秘诀

5
他是从程序员的角度对git本身进行更改的。最终用户的观点与该讨论完全正交,除了易于维护的代码制作(减少错误和增加功能)之外。
Karl Bielefeldt 2012年

2
@James:他是说软件更好(因此更易于使用,并且被更多的人使用),因为数据结构更好。当然,您不需要了解所使用软件的数据结构,但是即使您没有意识到它,也确实会间接地关心它们,因为数据结构是驱动您实现的事物的驱动力关心。
ruakh 2012年

1
+1。此答案将上下文放在声明上,否则可以解释为表示非常不同的含义。读过文件的5000行怪物的人都知道我的意思。
riwalk 2012年

20
“首先担心数据结构,您的代码自然会更干净。”:罗马政治家Cato(en.wikipedia.org/wiki/Cato_the_Elder)曾经说过“ Rem tene,verba sequentur” =“请在你的想法,这些话自然会随之而来。” 与编程相同:首先了解数据结构和设计,然后再实际编写代码。
乔治

60

算法+数据结构=程序

代码只是表达算法和数据结构的方式。



对于过程编程而言,这是正确的。在OOP中有点不同。
m3th0dman 2012年

3
从根本上来说没有什么不同。您有数据并对其进行了一系列操作。成员变量和方法。完全一样。自从50年代以来,整个计算的本质就是建立在一个非常简单的规则上,即程序由修改数据结构的算法组成,并且在60年后一直保持不变。您也可以将程序视为函数。他们接受输入,并据此产生输出。就像数学函数一样。
zxcdw 2012年

31

这句话对“ Unix编程的艺术”中的规则之一非常熟悉,这是Torvalds的强项,他是Linux的创造者。这本书在这里在线

这本书中的以下引文阐述了托瓦尔兹所说的话。

表示法则:将知识整合到数据中,因此程序逻辑可以是愚蠢且健壮的。

即使是最简单的过程逻辑,人类也很难验证,但是相当复杂的数据结构也很容易建模和推理。要看到这一点,请将(例如)五十节点指针树的图与五十行程序的流程图的表现力和解释力进行比较。或者,将表示转换表的数组初始化程序与等效的switch语句进行比较。透明度和清晰度上的差异是巨大的。参见Rob Pike的规则5。

数据比程序逻辑更容易处理。因此,如果您在数据结构的复杂性和代码的复杂性之间做出选择,请选择前者。更多:在进行设计时,您应该积极寻求将复杂性从代码转换为数据的方法。

Unix社区并没有产生这种见解,但是许多Unix代码显示了它的影响力。特别是C语言在处理指针方面的便利性鼓励从内核开始在所有编码级别上使用动态修改的引用结构。这种结构中的简单指针追逐经常会执行职责,而其他语言的实现则必须体现在更复杂的过程中。


我也记得这个!
Jesvin Jose

1
OTOH,请查看有关的所有StackOverflow问题int**。那应该使您确信数据实际上并不明显。只有将含义附加到数据上,情况才会如此。意思就是代码。
MSalters 2012年

29

代码很简单,这是复杂代码背后的逻辑。

如果您担心代码,这意味着您还没有掌握这些基础知识,并且很可能会迷失在复杂的代码(即数据结构及其关系)上。


17
嘿,我想知道下一代程序员是否会问:“ Morons曾经说过Code is easy, it's the logic behind the code that is complex,他是什么意思?”
扬尼斯

36
@YannisRizos这将是特别混乱,当人们不知道它是否被说的人谁是白痴,或者一个人通过白痴的名字。
KChaloux

14

为了进一步扩展Morons的答案,我们的想法是理解代码的细节(语法,在较小程度上,结构/布局)非常容易,因此我们构建了可以做到的工具。编译器可以理解所有有关代码的知识,以便将其转变为可运行的程序/库。但是编译器实际上无法解决程序员所遇到的问题

您可以将参数更进一步,说“但是我们确实有生成代码的程序”,但是它生成的代码是基于几乎总是手动构建的某种输入的。

因此,无论采用哪种途径获取代码:通过某种配置或其他输入,然后通过工具生成代码,或者如果您是从头开始编写的,则无关紧要的代码。至关重要的是对获得该代码所需的所有部分的批判性思考。在Linus的世界中,主要是数据结构和关系,尽管在其他领域可能是其他部分。但是在这种情况下,Linus只是说“我不在乎您是否可以编写代码,我在乎您能够理解可以解决我正在处理的问题的事物”。


每个程序员都使用生成代码的程序。它们通常称为“编译器”,有时与“链接器”结合使用。它们采用(相对)人类可读和人类可写的输入,通常(但并非总是)以某种文本格式提供输入,并将其转换为计算机可以理解为指令并执行的数据。
CVn 2012年

13

Linus的意思是:

向我展示您的流程图[代码],并隐藏您的表格[模式],我将继续感到困惑;给我看你的表[模式],我通常不需要你的流程图[代码]:它们很明显。

-弗雷德·布鲁克斯(Fred Brooks),《神话人月》,第9章。


12

我认为他是说总体高层设计(数据结构及其关系)比实现细节(代码)重要得多。我认为他重视那些可以设计系统的程序员,而不是那些只关注系统细节的程序员。

两者都很重要,但是我同意,总体上来说,与细节相关的问题要比其他方法要好得多。这与我试图表达的关于将大功能分解为小功能密切相关。


+1:我同意你的看法。另一个方面是,程序员通常更担心他们将使用什么炫酷的语言功能,而不是专注于他们的数据结构和算法以及如何以简单明了的方式将其写下来。
乔治

我也同意。事实是,更改孤立的代码段很容易,但是更改代码段之间的数据结构或接口比较困难(因为这些类型的更改可能会影响很多事情,而不仅仅是一件事情)。
布伦丹2012年

5

好吧,我不能完全同意,因为您必须担心所有这些。就此而言,我最喜欢编程的一件事就是通过不同级别的抽象和大小进行切换,这些切换从思考纳秒到思考数月迅速跳跃,然后又回来了。

但是,更高的东西更重要。

如果我在几行问题中都存在缺陷,导致行为不正确,则修复起来可能不太困难。如果它导致其表现不佳,那可能甚至没有关系。

如果我在子系统的数据结构选择方面存在缺陷,这会导致错误的行为,那么这将是一个更大的问题,而且更难解决。如果它导致其表现不佳,则可能会很严重,甚至可以忍受,但仍然比竞争对手的方法差很多。

如果我在应用程序中最重要的数据结构之间的关系中存在缺陷,这会导致错误的行为,那么我就要进行大量的重新设计。如果它导致其性能不佳,则可能会很糟糕,以至于如果表现不佳,它将几乎更好。

而且它会是什么让那些寻找较低级别的问题难以(固定低级别的错误通常是容易的,而是找到他们是很难)。

低级的东西重要,而其剩余的重要性常常被低估了,但是与大的东西相比,它的确显得苍白。


2

知道代码的人会看到“树”。但是了解数据结构的人会看到“森林”。因此,优秀的程序员将更多地关注数据结构而不是代码。


2
但是只关注森林树木而将其排除在外可能是有害的,因此我认为这种比喻不合适。
kojiro 2012年

1
@kojiro:在表达式中看不到树木的森林,假定可以看到森林的人也会看到树木(请参见en.wiktionary.org/wiki/see_the_forest_for_the_trees)。因此,我认为这是一个很好的类比。
Treb 2012年

2

知道数据将如何流动非常重要。了解流程要求您设计良好的数据结构。

如果回溯二十年,这是使用SmallTalk,C ++或Java的面向对象方法的最大卖点之一。至少在C ++中,因为这是我首先学到的,这是我设计的最大基调,是设计类和方法,然后其他所有东西都放到位。

Linus无疑是在用更广泛的术语进行讨论,但是设计不良的数据结构通常需要额外的代码重做,这也可能导致其他问题。


2

从中可以学到什么?

如果可以的话,我过去几周的经验。前面的讨论澄清了我的问题的答案:“我学到了什么?”

我重写了一些代码,并反思了我不断看到的结果,并说“结构,结构...”就是为什么存在如此巨大的差异。现在,我看到是数据结构使一切有所不同。我的确是全部

  • 测试我的原始交付后,业务分析师告诉我它不起作用。我们说:“加30日”,但我们的意思(WAS的“添加月份” 一天中生成的日期不会更改)。添加离散的年,月,日;而不是18个月的540天。

  • 解决方法:在数据结构中,将一个整数替换为包含多个整数的类,将其构造更改限制为一种方法。更改实际的日期算术语句-全部两个。

回报

  • 新的实现具有更多的功能,但是算法代码更短并且明显更简单。

在修复代码行为/结果中:

  • 我更改了数据结构,而不是算法。
  • 代码中的任何地方都没有触及控制逻辑。
  • 没有更改API。
  • 数据结构工厂类完全没有改变。

1

我想想象一个非常聪明的图书馆员团队,在一个精美的图书馆中,拥有一百万本随机且精采的书籍,这真是愚蠢。


1

我完全不同意莱纳斯。关注数据有助于极大地提炼出针对给定问题的简单而灵活的解决方案。Git本身就是一个证明性的例子-在多年的开发中提供了如此多的功能支持,核心数据结构在很大程度上保持不变。太神奇了!--2分


0

我已经看到了很多领域。

考虑业务分析...假设您正在分析像高露洁这样的消费品公司支持市场营销的最佳方法。如果您从花哨的窗口或最新技术入手,那么您对企业的帮助就不会比您首先考虑企业的数据需求,然后再考虑展示时所提供的帮助大。数据模型比演示软件更耐用。

考虑做一个网页。最好先考虑要显示的内容(HTML),然后再考虑样式(CSS)和脚本(选择工具),这要好得多。

这并不是说编码也不重要。您需要编程技巧才能最终获得所需的东西。数据是基础。不良的数据模型反映了过于复杂或未考虑的业务模型。


0

我发现自己编写新功能和更新现有功能的频率要比向我的数据库模式添加新的列或表要多得多。对于所有精心设计的系统,这可能都是正确的。如果您每次需要更改代码时都需要更改架构,那么这显然是一个非常糟糕的开发人员的信号。

代码质量指标= [代码更改] / [数据库架构更改]

“向我展示您的流程图并隐藏您的表,我将继续感到困惑。向我展示您的表,我通常不需要您的流程图;它们将显而易见。” (弗雷德·布鲁克斯)


-2

似乎这个想法在各种类型的编程中都有各种解释。它适用于系统开发,也适用于企业开发。例如,有人可能会争辩说,在域驱动设计中,对领域的关注发生了急剧变化,就像对数据结构和关系的关注一样。


-4

这是我对此的解释:您使用代码创建数据结构,因此重点应放在后者上。这就像建造一座桥梁-您应该着手设计一种坚固的结构,而不是看起来很有吸引力的结构。碰巧的是,由于其高效的设计,编写良好的数据结构和桥看起来都很不错。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.