優れたプログラマーに関するトーバルズの引用[終了]


238

偶然、Linus Torvaldsによる次の引用につまずいた。

「悪いプログラマはコードを心配します。良いプログラマはデータ構造とその関係を心配します。」

私は過去数日間それについて考えてきましたが、私はまだ混乱しています(おそらく良い兆候ではありません)、したがって、私は次のことを議論したかったです:

  • これの可能な解釈/意味がありますか?
  • それから何を適用/学習できますか?

18
この質問にはおそらく同じように有効な複数の答えがあると思います。とにかく、それは良い質問です。私はその引用が大好きです。言語の切り替えを心配するプログラマーを理解できない理由を表します。プログラムで重要なのはめったに言語ではなく、データ構造とそれらの関係です。
ライアンキナル

5
データ構造を「エレガント」にするために時間をかけるなら、これらのデータ構造を処理するためにコードを複雑にする必要はないでしょうか?おそらく、トーバルズの引用の意味を本当に知るにはあまりにも馬鹿だ。:}
プログラマー

3
@RyanKinalしかし、もちろん言語は重要です。特定のデータ構造を扱い、考えることをかなり容易にするからです。たとえば、LISt解析に特化したすべての言語、または他の言語にハッキングする必要のあるデータ構造をネイティブにサポートしている言語について考えてみてください(セットとスパース配列が思い浮かびます)。
小次郎

83
ちなみに、トーバルズはこれだけではありません。「フローチャートを見せて、テーブルを隠してください。これからも神秘になります。テーブルを見せてください。通常、フローチャートは必要ありません。明らかになります。 」–フレッドブルックス、神話の男月。「あなたのコードを見せて、データ構造を隠してください。私は引き続き謎に包まれます。データ構造を見せてください。通常、コードは必要ありません。それは明らかです。」「スマートなデータ構造とダムコードは、他の方法よりもはるかにうまく機能します。」–エリックS.レイモンド、大聖堂とバザール。
ヨルグWミットタグ

4
これは、Linuxカーネルが混乱している理由を説明しています:)
l1x

回答:


326

その直前にトーバルズが言ったことを検討するのに役立つかもしれません:

gitの実際のデザインはシンプルで、データ構造は安定しており、十分に文書化されています。実際、私はデータを中心にあなたのコードを設計することを強く支持しています。それはgitがかなり成功した理由の1つだと思います[…]実際に、その違いを主張します悪いプログラマーと良いプログラマーの間には、彼が自分のコードまたはデータ構造をより重要視するかどうかがあります。

彼が言っているのは、優れたデータ構造はコードの設計と保守を非常に簡単にしますが、最良のコードは貧弱なデータ構造を補うことができないということです。

gitの例について疑問がある場合は、多くのバージョン管理システムが新しい機能をサポートするために比較的定期的にデータ形式を変更しています。新しい機能を取得するためにアップグレードするとき、多くの場合、データベースを変換するために何らかのツールを実行する必要があります。

たとえば、DVCSが最初に普及したとき、多くの人々は、分散モデルが一元化されたバージョン管理よりもはるかにクリーンなマージを作成したことを理解できませんでした。答えは絶対にありません。ただし、分散データ構造、まったく機能するという希望を得るためにはるかに優れていなければなりませんでした。集中マージアルゴリズムはその後追いついたと思いますが、古いデータ構造が使用できるアルゴリズムの種類を制限し、新しいデータ構造が既存のコードの多くを壊したため、かなり長い時間がかかりました。

対照的に、gitの機能の爆発にもかかわらず、その基になるデータ構造はほとんど変更されていません。最初にデータ構造を心配すれば、コードは自然にきれいになります。


25
最良のコードが貧弱なデータ構造を補うことはできません。良いグレービーは真実です
コンラッドフリックス

5
彼は、プログラマーがgit自体に変更を加えるという観点から話しています。エンドユーザーの視点は、簡単に保守可能なコードを作成してバグを減らし、機能を迅速に追加することを除けば、この議論と完全に直交しています。
カールビーレフェルト

2
@James:彼は、データ構造が優れているため、ソフトウェアの方が優れている(したがって、より使いやすく、より多くの人が使用している)と言っています。もちろん、使用するソフトウェアのデータ構造について知る必要はありませんが、気付いていなくても間接的ににしています。なぜなら、データ構造はあなたが実現することを推進するものだからです。気にします。
-ruakh

1
+1。この答えは、そうでなければ非常に異なる何かを意味すると解釈される可能性のあるステートメントにコンテキストを置きます。ファイルの5000行の怪物を読んだ人は誰でも、私が言っていることを正確に知っています。
リウォーク

20
「最初にデータ構造を心配すれば、コードは自然にきれいになります。」:ローマの政治家Cato(en.wikipedia.org/wiki/Cato_the_Elder)は「レムテン、バーバシーケンス」と言っていました。あなたの心、言葉は自然に続きます」。プログラミングについても同じことです。最初にデータ構造と設計を理解すると、実際のコードが自動的に続きます。
ジョルジオ

60

アルゴリズム+データ構造=プログラム

コードは、アルゴリズムとデータ構造を表現する方法です。



これは手続き型プログラミングに当てはまります。OOPの場合は少し異なります。
m3th0dman

3
それは基本的にありません任意の異なります。データがあり、その上で一連の操作を実行します。メンバー変数とメソッド。まったく同じこと。50年代以降のコンピューティングの本質は、プログラムがデータ構造を変更するアルゴリズムで構成されているという非常に単純なルールに基づいて構築されており、60年後も維持されています。プログラムを関数とみなすこともできます。それらは、出力を生成するために動作する入力受け取ります。数学関数とまったく同じです。
zxcdw

31

この引用は、Linuxの作成者であるTorvaldsの強みである「Unixプログラミングの技術」のルールの1つに非常に精通しています。本はオンラインでここにあります

この本からは、トーバルズが言っていることを説明する次の引用があります。

表現の規則:プログラムロジックが愚かで堅牢になるように、知識をデータに組み込みます。

最も単純な手続き型ロジックであっても、人間が検証するのは困難ですが、非常に複雑なデータ構造はモデル化と推論が非常に簡単です。これを確認するには、(たとえば)50ノードポインターツリーのダイアグラムの表現力と説明力を、50行のプログラムのフローチャートと比較します。または、変換テーブルを表す配列初期化子を同等のswitchステートメントと比較します。透明性と透明性の違いは劇的です。ロブパイクのルール5を参照してください。

データはプログラムロジックよりも扱いやすいです。したがって、データ構造の複雑さとコードの複雑さのどちらかを選択する場合は、前者を選択します。詳細:設計を進化させるには、コードからデータに複雑さをシフトする方法を積極的に模索する必要があります。

Unixコミュニティはこの洞察を生み出しませんでしたが、多くのUnixコードがその影響を示しています。特に、ポインタを操作するC言語の機能は、カーネル以降のすべてのレベルのコーディングで動的に変更された参照構造の使用を奨励しています。そのような構造の単純なポインタ追跡は、他の言語の実装がより複雑な手順で具体化する必要があるという任務を頻繁に行います。


私もこれを思い出しました!
ジェビンホセ

1
OTOH、に関するStackOverflowの質問をご覧くださいint**。これは、データが実際には明らかではないことを確信させるはずです。データに意味を付けることによってのみそうなります。そして、その意味はコードにあります。
–MSalters

29

コードは簡単です。複雑なのはコードの背後にあるロジックです。

コードを心配している場合、その基本はまだ得られておらず、複雑な部分(データ構造とそれらの関係)で失われる可能性があります。


17
ええと、次世代のプログラマーが尋ねるのではないかと思いCode is easy, it's the logic behind the code that is complexます。
ヤニス

36
@YannisRizosそれは、人々がそれが馬鹿だったから言われたのか、それともモロンという名前の一人のから言われたのかわからないとき、特に混乱するでしょう。
KChaloux

14

Moronsの答えを少し拡張すると、コードの詳細(構文、およびそれほどではないが構造/レイアウト)を理解するのは簡単で、それを実行できるツールを構築するという考え方です。コンパイラーは、コードを機能するプログラム/ライブラリーに変えるためにコードについて知っておく必要があることをすべて理解できます。しかし、コンパイラはプログラマが行う問題を実際に解決することはできません。

引数をさらに一歩進めて「コードを生成するプログラムはあります」と言うこともできますが、生成されるコードは、ほとんど常に手作業で作成される何らかの入力に基づいています。

したがって、コードを取得するためのルートは何でも構いません。何らかの種類の構成や、ツールを介してコードを生成するその他の入力を経由する場合でも、ゼロから作成する場合でも重要なのはコードではありません。重要なのは、そのコードに到達するために必要なすべての要素の批判的思考です。Linusの世界では、それは主にデータ構造と関係ですが、他のドメインでは他の部分である場合があります。しかし、この文脈では、Linusは「コードを書くことができるかどうかは気にせず、私が対処している問題を解決するものを理解できるようにしたい」と言っています。


すべてのプログラマーは、コードを生成するプログラムを使用します。それらはしばしば「コンパイラ」と呼ばれ、「リンカー」と組み合わされることもあります。それらは(比較的)人間が読み取りおよび書き込み可能な入力を受け取ります。これは通常(常にではありません)何らかのテキスト形式で提供され、コンピューターが命令として理解して実行できるデータに変換します。
CVn

13

Linusの意味:

フローチャート[コード]を表示し、テーブル[スキーマ]を隠してください。テーブル[スキーマ]を表示してください。通常、フローチャート[コード]は必要ありません。それらは明らかです。

-フレッドブルックス、「The Mythical Man Month」、ch 9。


12

彼は、全体的な高レベルの設計(データ構造とその関係)が実装の詳細(コード)よりもはるかに重要だと言っていると思います。彼は、システムの詳細にのみ集中できる人よりも、システムを設計できるプログラマを大切にしていると思います。

どちらも重要ですが、一般的には、全体像を把握し、詳細に問題がある方が、他の方法よりもずっと良いことに同意します。これは、大きな機能を小さな機能に分割することについて私が表現しようとしていたことと密接に関連しています


+1:賛成です。別の側面は、多くの場合、プログラマーは、データ構造とアルゴリズム、およびそれらを単純で明確な方法で書き留める方法に焦点を当てるのではなく、使用するクールな言語機能を心配していることです。
ジョルジオ

私も同意します。事実、孤立したコードを簡単に変更できますが、データの構造やコード間のインターフェイスを変更するのは困難です(これらの変更は、1つのことだけでなく多くのことに影響する可能性があるため)。
ブレンダン

5

まあ、私は完全に同意することはできません、あなたはそれのすべてについて心配しなければならないので。さらに言えば、私がプログラミングで気に入っていることの1つは、さまざまなレベルの抽象化とサイズを切り替えて、ナノ秒の思考から数か月の思考に、そして再び戻ることです。

ただし、高いものほど重要です。

誤った動作を引き起こす問題のいくつかの行に欠陥がある場合、修正するのはそれほど難しくありません。それがパフォーマンスの低下を引き起こしている場合、それはおそらく重要ではありません。

サブシステムのデータ構造の選択に欠陥があり、それが誤った動作を引き起こす場合、それははるかに大きな問題であり、修正がより困難です。それがパフォーマンスを低下させている場合、それは非常に深刻である可能性がありますか、耐えられる場合でも、ライバルアプローチよりもかなり劣っています。

アプリケーション内の最も重要なデータ構造間の関係に欠陥があり、それが不適切な動作を引き起こす場合、目の前で大規模な再設計を行います。それがパフォーマンスの低下を引き起こしている場合、それが非常に悪いので、それが間違って動作していた場合はほとんど改善される可能性があります。

そして、それはそれらの低レベルの問題を見つけることを困難にするものになります(通常、低レベルのバグを修正するのは簡単ですが、それは難しい可能性のあるものを見つけることです)。

低レベルのもの重要であり、その残りの重要性はしばしば非常に控えめに控えめですが、大きなものと比べると見劣りします。


2

コードを知っている人は、「ツリー」を見ます。しかし、データ構造を理解している人は「森」を見ています。したがって、優れたプログラマーは、コードよりもデータ構造に重点を置きます。


2
しかし、フォレストまたはツリーのどちらか一方に焦点を合わせて、他方を除外することは有害である可能性があるため、この類推は当てはまるとは思いません。
小次郎

1
@kojiro:式では、木々の森を見ることができません。森を見ることができる人は木も見ると想定されています(en.wiktionary.org/wiki/see_the_forest_for_the_treesを参照)。したがって、私はそれがここで良い類推だと思います。
Treb

2

データの流れを知ることはすべて重要です。フローを知るには、適切なデータ構造を設計する必要があります。

20年前に戻ると、これはSmallTalk、C ++、またはJavaを使用したオブジェクト指向アプローチの大きなセールスポイントの1つでした。大きなピッチは-少なくともC ++では最初に学んだことなので-クラスとメソッドを設計し、それ以外のすべてが適切に配置されるようにすることでした。

Linusは間違いなくより広義の言葉で話していましたが、データ構造の設計が不十分な場合は、コードの余分な修正が必要になることが多く、他の問題にもつながる可能性があります。


2

それから何を適用/学習できますか?

可能であれば、過去数週間の私の経験。これまでの議論により、「私は何を学びましたか?」という質問に対する答えが明確になりました。

私はいくつかのコードを書き直し、「構造、構造...」を見続けて言った結果を反映して、そのような劇的な違いがあったのです。今、私はすべての違いを作ったデータ構造であることがわかります。そして、私はすべてを意味します

  • 元の納品をテストすると、ビジネスアナリストは、機能していないと言った。私たちは、「30日の追加」と述べたが、私たちが意味すること(「月の追加」であった日の結果の日付では変更されません)。年、月、日を個別に追加します。たとえば、18か月で540日ではありません。

  • 修正:データ構造で、1つの整数を複数の整数を含むクラスに置き換え、その構造の変更は1つのメソッドに制限されていました。実際の日付算術ステートメントを変更します-それらの2つすべて。

ペイオフ

  • 新しい実装にはより多くの機能がありましたが、アルゴリズムコードは短く、明らかにシンプルでした。

コードの動作/結果の修正:

  • アルゴリズムではなく、データ構造を変更しました。
  • 制御ロジックはコードのどこにも触れられていません。
  • APIは変更されていません。
  • データ構造ファクトリクラスはまったく変更されませんでした。

1

私は、100万のランダムで素晴らしい本を備えた美しく作られた図書館にいる非常に賢明な図書館員のチームを想像するのが好きです。


1

Linusにはこれ以上同意できません。データに焦点を当てることにより、特定の問題に対するシンプルで柔軟なソリューションを大幅に引き出すことができます。Git自体は実証された例です。長年の開発でサポートされている機能が非常に多く、コアデータ構造はほとんど変更されていません。それは魔法です!--2c


0

これは多くの分野を見てきました。

ビジネス分析について考えてみましょう... Colgateのような消費財企業でマーケティングをサポートする最良の方法を分析しているとしましょう。派手なウィンドウや最新のテクノロジーから始める場合、ビジネスのデータニーズを先に考えてからプレゼンテーションを心配するほどビジネスを支援することはできません。データモデルはプレゼンテーションソフトウェアよりも長持ちします。

Webページの作成を検討してください。最初に表示するもの(HTML)について考え、スタイル(CSS)とスクリプティング(ツールを選択する)について心配することをお勧めします。

これは、コーディングも重要ではないということではありません。最終的に必要なものを得るには、プログラミングスキルが必要です。データが基盤であるということです。貧弱なデータモデルは、過度に複雑な、または考えられないビジネスモデルを反映しています。


0

データベーススキーマに新しい列やテーブルを追加するよりも、頻繁に新しい関数を作成し、既存の関数を更新します。これはおそらく、適切に設計されたすべてのシステムに当てはまります。コードを変更する必要があるたびにスキーマを変更する必要がある場合は、非常に悪い開発者であるという明確な兆候です。

コード品質インジケータ= [コード変更] / [データベーススキーマ変更]

「あなたのフローチャートを見せて、あなたのテーブルを隠せ。そうすれば、私は神秘になり続けるだろう。あなたのテーブルを見せてくれ。そうすれば、通常あなたのフローチャートは必要ないだろう。(フレッドブルックス)


-2

このアイデアには、さまざまな種類のプログラミングでさまざまな解釈があるようです。システム開発にも当てはまり、エンタープライズ開発にも当てはまります。たとえば、ドメイン駆動設計におけるドメインへのフォーカスの急激なシフトは、データ構造と関係へのフォーカスに非常に似ていると主張できます。


-4

私の解釈は次のとおりです。データ構造を作成するにはコードを使用するため、後者に焦点を当てる必要があります。それは橋を架けるようなものです-魅力的に見える構造ではなく、しっかりとした構造を設計するべきです。よく書かれたデータ構造とブリッジも、効率的な設計の結果として見栄えがよくなります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.