プログラマが自分のコードを100%明確にしないことは時々ありますか?[閉まっている]


19

私は熟練したプログラマーではないので、これが理由かもしれませんが、複雑なコード(最近作成したチェスゲームなど)を作成するたびに、プログラムを動作させるための正しいコードを書くことができることに気付きました。後で、または数秒後にそれを見つけますが!

それだけでなく、コードについても考えない傾向があり、代わりに入力するだけです。たとえば、チェスのゲームでは、動きを処理するために5次元配列を使用することにしましたが、あまり意識せずにこれを実行できることがわかりました。しかし、停止して読み直したとき、5次元の概念全体を理解するのは困難であり、自分が何をしたのか、コード自体がどのように機能するのかを完全に理解するには数分かかりました。

プログラマーが複雑なコードを書くとき、彼らが何をしているのかを半分の時間で理解しないのは普通ですか?


13
それは、あなたが巧妙になるにはあまりにも一生懸命に努力しているという兆候です。自分で読みにくい場合は、よりシンプルでモジュール化されたコードを書く必要があります。
小田14年

3
他の(洞察に満ちた)答えに、複雑すぎるコードや貧弱な設計コードの匂いがするという意味で追加するには(心配しないで、私たちのほとんどはその段階に合格しなければなりませんでした):Document。変数/メソッド/クラス/モジュールに適切な名前を付けること、各関数に適切な説明を追加すること、および(他の方法が見当たらない場合)複雑なスニペットを使用する理由と方法を説明する簡単なインラインコメントを書くことコード。
SJuan76 14年

4
自分のコードを100%明確にすることはありません
CodesInChaos 14年

2
その5D配列は、抽象化を使用できるように思えます。

3
開発者は常に自分のコードを100%明確にしていますか?
ヨハン14年

回答:


30

いいえ、正常ではありません1。少なくとも、優秀なプログラマーにとっては普通ではありません。おそらくプログラミングを学んでいる人にとって普通のことです。

ソフトウェアを書くことは、それが機能するまでコードの行を一緒に平手打ちするだけではありません。コードを理解しやすくするために意識的に取り組む必要があります。私が非常に尊敬するプログラマーは、「コードは、書かれているよりも何度も読まれますと私に言った。それは完全に明白なはずですが、彼が私に言うまで気づかなかったという事実でした。あなたのコードの多くは一度しか書かれておらず、一度か二度書き直されているかもしれませんが、ソフトウェアの寿命の間にコードを読むことになるでしょう。

コードを書いてから数分後に理解するのが難しい場合、それはコードが複雑すぎることを示しています。コードの追加を停止し、より良い方法を見つけてください。たとえば、5次元配列はほとんど決して良い考えではありません。本当に、本当に賢いプログラマーでさえ、そのような複雑なデータ構造を理解するのに苦労しています。

コードの読みやすさについて教えてくれた同じプログラマーは、「データ構造を見せてくださいコードがどのように機能するか教えてくれます」とも言っています。意味のある、良いコードは、クリーンで理解可能なデータ構造から始まります。データを適切に設計する場合、コードはほとんど二次的な関心事です。確かに、ソフトウェアは単なるデータではなく、データから始まるため、このステートメントは少し誇張されています。そのため、クリーンで把握しやすいデータ構造の作成に取り組むと、コードがかなり理解しやすくなります。


1確かにそこには非常に複雑で、最も賢明なプログラマーでさえ理解するのが難しいコードがあります。一部の問題は本質的に複雑です。しかし、大多数のプログラマーによって書かれたコードの大部分は、そのタイプのコードではないと言うことを敢えてします。


8
[1]より悲観的な観点からは、それは正常ですが、良くありません。
ダン14年

1
「5次元配列」が4タプルまたは5タプルから戦略への単なるマップである場合、作成者はハッシュテーブルまたはヘルパールックアップ関数を使用できます。ただし、作成者がほとんどの時間を配列の初期化メカニズム(ネストされたforループ)のコーディングに費やしている場合、実際の「アルゴリズムの洞察」は「機械的コード」の山にdrれてしまいます。プログラマーは、後者の種類のノイズを分離するよう努めます。したがって、優れたプログラマーは、主にそれらの機械的コードを収容するためのライブラリーの作成方法を知っている必要があります。
rwong

1次元配列は線、2次元はグリッド、3次元はキューブ、4次元はキューブの線、5次元はキューブの格子などです。しかし、使用法はわかりません。チェスに関しては、このような複雑なデータ構造のために。
user2785724 14年

15

これには次の2種類があります。1。)混乱2.)至福の無知

最初のものは悪いものであり、時間と経験とともに消える可能性があります。

プロジェクトが大きくなった場合、2番目の方法は良い方法です。コードを操作するためにすべての実装の詳細を覚えておく必要がある場合、何か問題があります(「情報の隠蔽」を参照)。

すべての開発者は、コードがどのように機能していたかを忘れるので、別の新しい開発者が理解し、プログラムのほかの部分も壊さずにそれを維持できるように書きます。

そのため、「知らない」ということは、実際にはソフトウェア開発において一定です。それは、それをどのように、または管理するかということです。


1
ここで重要なことに触れています。これは、実装の詳細が実際に忘れられるため、常識的なパターンと規則を使用してプログラミングすることが非常に重要です。ただし、コード内のパターンと規則が適切であれば、必要に応じてコンテキストから詳細をバックアップするのは簡単です。一方、コードがすべてモノリシックで、不可解で、非常に賢い場合、最終的に詳細を忘れるだけでなく、コードを維持しようとする他のプログラマーははるかに苦労します。
クレイグ14年

12

人々が認めようとするよりも一般的だと思います。ブライアン・カーニガンでさえそれをほのめかした:

デバッグは、最初にコードを記述するよりも2倍困難です。したがって、コードを可能な限り巧みに記述すると、定義上、デバッグするほど賢くありません。

店に行くとき、ペダルとハンドルの位置を詳細に調整します。これは現時点では非常に簡単です。ここで、これらの調整を紙に記録し、店舗への道順を必要とする友人にそれらを提供した場合を想像してください。

同様に、1つの抽象化レベルでコードを記述するのが好きですが、複数の抽象化レイヤーでコードを読むのが好きです。したがって、コードを記述および読み取るための私たちの好ましい方法は矛盾しています。つまり、コードを読みやすくすることは、通常、異なるスキルセットを備えた別個の意識的なステップです。

優れたプログラマーになるのは、書いたばかりのものを読むことが困難なとき、その時点で抽象化を作成することです。優れたプログラマーはそれを複数回行い、そのたびに選択が難しくなります。最終的に、経験豊富なプログラマーはプロセスのさらに先に進みますが、書いたものを読んだ後でも改善の余地がまだあることがよくあります。


私はそのことについてブライアンに反対しなければなりません、私はデバッグが大好きです、私はそうする業界で私が知っている数少ない人の1人ですが、私はそれを非常に書くコードを評価しません。
ジェームス・スネル14年

@JamesSnell彼は、デバッグが悪いとか不快であるとは言わず、単にそれが難しいと言っただけで、複雑なコードのデバッグはさらに難しいと言っていました。
cbojar 14年

5

これは経験とともに消えていくものだと思います。

複雑なシステムを作成する場合は、将来、そして将来の誰かが理解できる、クリーンで保守可能なコードを作成できる必要があります。したがって、本質的に、あなたが今していることはスケーラブルではありません。

6か月前に書いたコードを見て、「ここで何が起こっているのか」と考える瞬間がたくさんありますが、コードを書いた翌日にそれが起こったら、「きれい」と考えなければなりません。コードをもっと。

ソース:5次元配列を使用したことはありません:)


3
@ 83457-5D配列は2D問題の貧弱なモデルであるため。本当に良いコードだと思ったら、codereview.stackexchange.comにドロップして、どのような答えが得られるかを確認してください。
ジェームズスネル14年

2
@ 83457-それが「地獄のように混乱している」場合、あなたは自分自身に答えた。5-Dアレイは混乱を招くことはないかもしれませんが、スキルレベルに関係なく、おそらくほとんどの人にとってはそうではありません。
dbasnett 14年

2
@ 83457地獄のように混乱していることは、それを使わないという既に非常に良い動機になっているはずです。
ファビオマルコリーニ14年

3
各次元に正当な理由がある限り、5D配列を避ける理由はわかりません。おそらく、複雑なキーを持つ辞書やいくつかの低次元配列など、より良いソリューションがありますが、5D配列がチェスAIのようなトリッキーな問題に適していると想像できます。
CodesInChaos 14年

2
@CodesInChaosこれらは単なる配列ではないことを除いて、意味のあるシーケンスを表します(たとえば、ネストされた決定ツリー)。適切に名前を付け、タイプを悪用できないように(それらのタイプが配列のラッパーである場合でも)、コードをより明確にし、ほとんどコストをかけずにバグを含める可能性を低くします。
deworde

5

「通常」は非常に主観的であるため、非常に一般的ですが、避ける必要があります。

「良いコード」(そのようなものが存在すると聞いた)の特徴の1つは明快さです:それは根本的な問題が許す限り明確であるべきです。問題が複雑な場合、コードも同様に複雑になりますが、適切なツール、パターン、技術を誤って使用したり使用したりして導入された偶発的な複雑さ(リッチヒッキーの講演でこの区別を初めて聞いた)とは対照的に、それは固有の複雑さですプラクティス。

明確性の欠如が 問題がそれほど複雑ではない場合でも許容される場合があります。たとえば、マーケティングキャンペーンが続く限り、存続することがわかっているプロモーションサイトを作成する場合です。これは、保守可能なものであってはならない使い捨てのコードです。他の(およびほとんどの)場合、このようなコードを維持するには多大な費用がかかるため、受け入れられません。しかし、それは一般的です。

関連:

  • 理解が書き換えを意味するとき -コードの理解の問題に関する記事。
  • 効果的なML -ML / OCamlの中でも、「リーダー」(つまり、メンテナー)向けのコードの書き方についての長い話:「ライターよりもリーダーを好む」。使用する言語に関係なく、これを視聴することをお勧めします。

2

私はそれが普通だとは思わないが、あなたが言及したチェスプログラムのような非常に複雑なプログラムでは、確かに可能だと思う。

何年も前、ちょうど私が大学院を卒業したとき(したがって、大きなプログラムを書くのはまだ比較的経験が浅かった)、私は最初の本当のコンパイラを書きました。解析は簡単でしたが、4つの異なるマイクロプロセッサ命令セットを対象とする必要がありました。コンパイラーを独自の言語で書くつもりだったので、最初に絶対に必要な言語の機能だけを使用し、最初のコードジェネレーターをアセンブリ言語で記述し、言語のサブセットに対して正しいコードを生成することをテストしました。その後、コンパイラを使用してそれ自体をコンパイルし、残りの機能を追加して、コンパイラ自体で使用することができました

次に、各マイクロプロセッサーのバックエンドコードジェネレーターを作成し、それらがすべて正しいコードを生成することをテストしましたが、正しい間は最適ではありませんでした。そこで、各コードジェネレーターのオプティマイザーを作成しました。

すべての最適化を追加した後、コードジェネレーターの出力をテストしていたとき、コンパイラが生成したコードに頻繁に驚きました。多くの場合、手作業でコードを記述する方法ではありませんでしたが、正確でかなり簡潔でした。

コードジェネレーターがコードを生成する方法がわからないときは、手動でロジックをたどろうとしましたが、あきらめたことがありました。トレース出力を大量に追加していた場合、それを追跡できたはずですが、生成されたコードは満足のいくものであり、他のプロジェクトに進む必要があったので、気にしませんでした。


しっかりとした基盤を備えた非常に優れた教育を受けており、知識を非常に高いレベルに内在化しているようです。これは典型的なプログラマーの間ではややまれなことだと思います。テクノロジーは急速に変化するため、ほとんどの典型的なプログラマー(私を含む)は、今日のタスクに必要な知識に追いつくのに苦労しなければなりません。
rwong

@rwongありがとうございます。そのほとんどは経験です。私は46年間プログラムを書いてきましたが、すぐに辞めるつもりはありません。
tcrosley 14年

2

ここにはきちんとした答えがたくさんあります。

私はこれについていくつかの見解を持っています。

1つは、コードが機能するように思われる理由がわからない場合は、a)おそらく機能しない(おそらくしか見えない)ように)、b)問題の領域を十分に理解していないときコーディングを開始したか、開始する前に問題領域をより小さく単純化したユニットに分割しなかった。

これに関する私の他の見解は、本当の鍵はコードで常識パターンと慣習を使用することであるということです。これは、1つの小さな投稿で対処できるものよりもはるかに大きなトピックです。しかし、「コードの完成」や「ソリッドコードの作成」などの古いスタンバイの一部を含む、このテーマに関する優れた文献を探してください。

実装の詳細が変更されます。唯一の実際の定数は、コードの機能目標です。複数の関数を作成する場合、特定の詳細な実装の詳細を時間の経過とともに忘れてしまいます。ただし、構成要素を構築するときは、構成要素がどのように機能するかを確実に理解する必要があり、全体の図を描いて、構成要素がどのように連携するかを理解できる必要があります。

パターンを使用し、常識的な慣習に従っている場合、コードを再度見るときに特定の実装の詳細をバックアップする方がはるかに簡単です。または、以前にコードを見たことがない人が初めてコードを見たとき。また、時間をかけてこれらの規則とパターンに従うことは、実装の詳細が規則とパターン自体から際立っていることを意味します。これは、コードを理解しやすくするもう1つの要因です。

ソフトウェアで取り組む問題のほとんどは、本質的に複雑です。ソフトウェア設計は、複雑さを管理するための演習です。


1

普通とは言いませんが、それは間違いなく起こります。問題のコードを書いた直後に問題が発生した場合、コードは不必要に複雑で単純化する必要があるか、気が散るだけだと思います。:)

しかし、コードを片付け、他のプロジェクトに集中し、数週間、数ヶ月、さらには数年後に戻ったとしても、それをすべて把握しなければならないのは驚くことではありません。

しかし、これに関してあなたができることがあります。あなたの言うことからすると、あなたはあなたが書いているコードについて十分に考えていないようであり、あなたの将来の自己が何が起こっているのか理解するのを難しくしているようです。その知識を活用してください:これは、構造化され、文書化された、理解可能なコードを作成するための最良の動機です。コードの品質を気にしないと何が起こるかは、実際の経験から知っています。それを知ることは、長期的にはより良いプログラマーになるはずです。ソフトウェアプロジェクトで共同作業を行う場合、同僚は理解可能なコードを作成してくれたことに感謝します。また、コードの欠陥率も改善されます。

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