私は常に物理学が好きで、コーディングも好きだったので、大学で数値物理学を行う博士号のポジションを取得したとき(詳細は関係ありませんが、ほとんどがクラスターの並列プログラミングです)、それはノーでした-私にとっては非常に簡単です。
しかし、ほとんどの物理学者として、私は独学です。オブジェクト指向の方法でコーディングする方法や、kDツリーの検索を最適化する特定のアルゴリズムの名前について、幅広い背景知識はありません。
これまでの私のすべての仕事は物理学と科学的結果にもっと関心を持っていたので、間違いなくいくつかの悪い習慣があります-私のコーディングは私自身のものであり、実際にはチームワークではないためです。私はCを主に使用しました。Cは非常に単純で、「あなたが書くものはあなたが得るものです」-凝った抽象化の必要がないからです。ただし、抽象化に付属している機能について詳しく知りたいので、最近C++に切り替えました。これはかなりCに似ています(少なくとも構文的には)。
コンピュータサイエンスの卒業生のように、優れた抽象的な方法でコードを書く方法を教えてください。
私は自分のコードが効率的であることを知っていますが、それもelegantにして、読みやすくしたいと考えています。抽象プログラミングに関する1000ページの本を読む時間がないので注意してください。私は実際の物理学関連の研究に時間を費やす必要があります(上司が上品にプログラムする方法を考えることに時間を費やしていることを彼が知っていたら、上司は私を笑わせます)。自分の仕事もプログラマーの観点から優れているかどうかをどのように評価しますか?
抽象プログラミングに関する1000ページの本を読む時間がないので注意してください。
では、熟練したプログラマーになるための5つのステップのチェックリストを提供してくれる人を求めていますか? それは起こりません !
他の分野と同様に、プログラミングを上手にしたい場合は、練習と学習に時間と労力を費やす必要があります。たくさんのコードを書き、他の人のコードを注意深く読むことにより、明確でエレガントなコードを書くことを学びます。これらの1000ページの書物のいくつかは、他の人々が学んだ難しい教訓を要約することで、実際に時間を節約します。物理学博士号を取得することの痛みのない副作用として熟練したプログラマーになることができると考えるのは妄想です。物理学博士号から出られないわけではありません。狂ったプログラミングスキルを持っていると、それはあなたの時間とトラブルを犠牲にするだけです。
Code Complete は、ソフトウェア開発の仕組みをわかりやすく紹介するもので、明確で保守可能なコードの記述方法と構造化に関するアドバイスが含まれます。はい、それは巨大な本ですが、確かに、ディラックの「量子力学の原理」またはMTWの「重力」ほど、密度は高くありません。 コード完了 は、より優れたソフトウェアを作成するための5つのステップのチェックリストに到達するのと同じくらい近いです。
Matlab、VIM、C、MPI、Valgrindは優れたツールです。バージョン管理システムの使用については言及していません。フルークでバージョン管理システムをまだ使用していない場合、すぐに使用する必要があります。バージョン管理は、あなたの論文を書くための神からの贈り物でもあります。知っておくべき他の基本的なツールは、デバッガー、実行プロファイラー、ロギングフレームワーク、ユニットテストフレームワークです。これらのそれぞれについて、1000ページの本を読む必要はありません。オンラインチュートリアルを実行して基本を理解し、それから作業を開始します。ニーズがより高度になるにつれて、ドキュメントをより深く掘り下げます。
(ソフトウェア構築の基礎とは対照的に)コンピュータサイエンスの基礎を学ぶことについてアドバイスすることは、より困難です。新しいアルゴリズムを開発する場合でも、既存のアルゴリズムを適用する場合でも、取り組んでいる問題を指定する必要はありません。研究の問題によっては、基本的なデータ構造と標準アルゴリズムの調査が役立つ場合があります。他の問題は、数値分析の堅実な背景からより多くの利益を得ます。アルゴリズム分析の基礎を学びたいなら、いくつかの良いテキストがあります。 アルゴリズムデザインマニュアル および アルゴリズムの概要 気になりました。現在オンラインで利用できる優れた入門コースもいくつかあります: アルゴリズムの設計と分析 、および アルゴリズム 。
私の背景はあなたの背景と少し似ています。私はプログラミングを独学で習得した物理学の卒業生でした。卒業後、いくつかのITの仕事を引き受け、最終的にはソフトウェアエンジニアになりました。 OpenGDA(さまざまなシンクロトロンサイトで実験を実行するために使用されるソフトウェア)での作業に少し時間が含まれています。
ここにたどり着いたときに私があなたが持っている質問について私が学んだ主なことは、自分でそれらを手に入れることを試みるよりも他の人からこれらのスキルを得る方がはるかに簡単であるということです。経験豊富なメンターは、コードのどこが弱いか、または一般的なパターンと実践が役立つ場所を簡単に特定するのに役立ちます。私はCとObjective-Cの記述方法を自分で学びましたが、同じコードで他の人と一緒に作業するまで、自分が何を知らないのか(意味がわかれば)正確にはわかりませんでした。ここでアドバイスを求めているという事実は、私がすでにやったよりもうまくやっていることを意味します:-)。
さて、使い慣れた専門のソフトウェアエンジニアはどこにいますか?最近参加した MentorNet は、パートナーがプロテジェを持つ経験豊富なプログラマーを支援するシステムです。
しかし、そのような正式なシステムを採用する必要はありません。地元のプログラマー交流会グループ(または大学のソフトウェアエンジニアリング部門が金曜日に仕事を終えた後)を見つけることは、始めるのに最適な場所です。
ソフトウェアへの王道なし
ユークリッドは古代、生徒のプトレマイオス王からあなたのような質問を受けました。彼の反応:「幾何学への王道はありません。」
上司は、プロの開発者のようにコードを書くのにどれだけの時間を費やしたかを上司が知っていると笑うと言っています。他の人は、ソース管理からアルゴリズムの設計と分析に至るまで学ぶべき事柄の簡潔なリストで質問に答えました。
彼らはあなたの目標に達していません:
「実際の物理に時間を費やす必要がある」
コンサートのピアニストまたは一人の男のバンド?
世界は動きが速すぎて、人々は手を出すことができません。コンサートのピアニストになりたい場合は、楽器を習得するために時間を割って一人のバンドになることは避けてください。
中規模から大規模プロジェクトの物理学におけるPhDの役割に関する私の概念は、システム定義のアイデアリーダー、理論の専門家、ユースケースの作成中の主題の専門家、およびソフトウェアアーティファクトによって生成された結果のエンドユーザー/裁判官としてです。可能な限り最高のソフトウェアエンジニアと緊密に連携します。
プログラマの観点から自分の仕事も良いかどうかをどのように評価しますか?
バーを高く設定する場合は、ここから始めます。
実際のソフトウェアアーキテクチャ、Len Bass、Paul Clements、Rick Kazman
「品質属性の理解」の章を探してください。コードを超えて、ユーザビリティ、変更可能、パフォーマンス、セキュリティ、可用性、信頼性、テスト容易性、保守性、および移植性を考慮します(実行することはできませんが、プラットフォーム間で設計を移植できます)。すべてに特定の測定可能な目標が必要です。同様の参照は次のとおりです。
http://msdn.Microsoft.com/en-us/library/ee658094.aspx
http://www.sei.cmu.edu/reports/95tr021.pdf
あなたの目標とCおよびC++の比較
FORTRANのように、これらはハードで古い言語です。 C/C++のポジティブインジケーターは次のとおりです。
Web開発、データの視覚化、ビッグデータを行う人はたくさんいます。多くの人が他の言語を見つけたり作成したりする意欲があります。たとえば、物理学者のティムバーナーズリー卿はHTMLで成功を収めました(しかし、物理学についてはほとんどわかっていません)。目標とプログラミング言語を比較してください。
Matlabの使用を検討してください
Matlabには優れたインストールベースがあり、数学と科学に特化しています。データの視覚化のためのツールがあります。これにより、科学者や数学者は、ソリューションドメインではなく問題ドメインで問題を表現できます。 MatlabはParallel Computing ToolboxおよびDistributed Computing Server製品を製造しています。
Matlabの成功は、物理学、数学、電子工学と計測、オペレーティングシステム、プログラミング言語、ソフトウェア開発、ソフトウェアテスト、ソフトウェアアーキテクチャと設計の専門家である学際的なチームを使用することによるものだと思います。類推は一筋縄ではいかないかもしれませんが、3Dプリンターを利用できるときに、ハンマー、ノミ、やすりから始めて何かを作るのはなぜですか。ニュートンが尋ねるように、誰かの肩の上に立ってみませんか?
自分の仕事もプログラマーの観点から優れているかどうかをどのように評価しますか?
それが正しいか?すべてのケースで正しい結果が得られますか?
他の人があなたのコードを読んで簡単に理解できますか?
上司が「いいですね、Xにも対応させてください」と言ったら、たくさんのコードを書き直す必要がありますか?
あなたがプログラムを書いたとき、それは何度も何度も使用できるツールになりますか、それとも一度使用してそれを一種の物として捨てるのですか?
「はい」、「はい」、「いいえ」、「はい、1回限りの計算ではなくツールを作成しようとしています」と答えることができれば、あなたはすでにかなりうまくやっています。私たちがプログラマーとして行うことのかなりの部分は、上記のようなことを支援することを目的としています。
(経験から言えば)「プロ」のスタイルについて何も知らなくても、物理学の長い道のりを進むことができます。しかし、私は多くの人々が無限の時間を浪費しているのを見てきました。彼らが何をしているのか、または2年間コードを成長させた後、その複雑さが失われてしまったためです(アカデミアでさえ「捨てる」コードはありませんがあなたが最初に思うよりずっと長く留まる)。
たとえば、アルゴリズムとデータ構造をすぐに始めることをお勧めします。 このコース 。その後、より生産的なレベルでパフォーマンスについて考え、フォローアップできるようにする必要があります。ウィキペディアの記事。
その後、あなたの言語の中核で利用できるものに慣れます。 C++の場合 cppreference.com 。 Scott MeyersによるEffective C++シリーズとAccelerated C++Koenig&Moeによる。少なくともC++の場合、これは言語側の強固な基盤を提供します。
並行して、ツールについてよく理解するようにしてください。 Linuxでコードを開発する可能性は低いので、コンパイラ(少なくともgccとclang)からより多くの診断(警告)を取得する方法を学んでください。 cppcheck または clang's scan-build などの静的分析ツールについても学びます。これらのツールを開発プロセスの不可欠な部分にする方法を学びます。それらをビルドセットアップに統合することで(はい、少なくともGNU make、またはGNU autotools/cmake/...などのより良いものを使用する必要があります) 。プロファイリングツールをツールセットに追加する必要もあります。C++の場合、非常に低いレベルでプロファイリングできるvalgrindについて可能なすべてを学ぶことを強くお勧めします(リソースリークを見つけるのにも役立ちます)。
これらはすべて、バグの発見や無駄な最適化を行う時間を無駄にするのではなく、あなたが最も気にかけていることに集中するのに役立ちます。もちろん、これをアドバイザに販売することはほとんど不可能ですが、彼ら(そしてあなたも)は感動しますが、信頼できる結果を得ることができるスピードです。
CとC++について言及しましたが、数値計算ではPython with numpy and scipy で十分です。これにより、非常にクリーンでクリーンな言語でC、C++、およびFORTRANに実装された非常に最適化されたルーチンを利用しながら、高レベル(インタラクティブに作業することもできます)。また、独自のCまたはC++コードとPythonとのインターフェイスは簡単です。
より優れたプログラマになることに関する限り、特効薬はありません。あなたが独学しているなら、鍵はあなたが持っているように聞こえる自己認識です。ただし、コードを正しく学習するためには、主に読書と練習が必要です。
自分のコードに批判的であることは、改善するための最良の方法の1つです。常に自問してください:
私の他の提案は、C/C++に固執しないことです。これらは理由があるために使用される優れた言語ですが、関連する主題ではない多くのことを行う必要があります。 Matlabを調べてください。大学がそれを利用できない場合、私は驚きます。 Pythonのようなスクリプト言語について考えてみましょう。 Haskellのような関数型言語の採用を強く検討してください。パラダイムは本質的に非常に数学的なものであり、手袋のような問題に当てはまる可能性があります。要するに、他のいくつかの言語/パラダイムを探索してください。それらがあなたのベルトの永続的なツールにならなくても、彼らはあなたをより良いプログラマーにするでしょう。
また、いくつかのアルゴリズム設計を調べることもできます。私は仕事を手に入れたのではないかと思いますが、あなたはすでにこれについて比較的問題を抱えていますが、数値分析を行う際にはアルゴリズムが非常に重要です。実際、私は疑っていると思います。数値解析アルゴリズムに特化したリソースがあります。
コードを記述する際の主な目的を見失うことはありません。物事を成し遂げる必要があります。優れたプログラマになることは、そのための1つの方法です。仕事に適したツールを選択することも別の方法です。
プログラムは商用ソースコードとは完全に異なるため、日々のソースコード開発には多くの優れた実践やアプローチが適用されません。しかし、いくつかのヒントやコツを学ぶ良い方法があります。
優れたソフトウェア開発者にコードをレビューしてもらい、一緒に最適化してもらいます。それはあなたに多くの経験を与え、あなたに良い習慣を教えます。また、他の人が作成したソースコードも確認してください。 sourceforgeまたはgithubでオープンソースプロジェクトを検索し、ソースコードを読んでください。
しかし、何よりも、目標を達成するために実際に何か新しいことを学ぶ必要があるかどうかを考えてください。コードをより美しく見せるためだけに不必要なことをしても、アプリケーションに価値はありません。
私が問題を解決する方法に関して私が得た最大の利益はすべて、関数型言語とパーサーを学ぶことによって達成されたと言えるでしょう。どちらの発見も偶然に行われたものです。ですから、より優れたプログラマになることに真剣に取り組んでいるなら、コンパイラの作成に関連するさまざまなテクニックを学ぶ必要があることをここで言います。パーサーおよびパーサージェネレーター、さらに高次関数を使用して計算を構成する方法を学ぶ必要があります。
パーサーとコンパイラーに関する優れたリソースは PL101:独自のプログラミング言語を作成する です。私はまだ関数型プログラミングの良い入門書を見つけていませんが、 [〜#〜] sicp [〜#〜] について本当に良いことを聞いています。
理論を学ぶ時間がないというあなたの言及を考慮してください。
数か月後に古いコードを振り返り、「どのような馬鹿がそのコードを書いたのか」と疑問に思っていれば、進歩しています。
どのように進歩しましたか?他の人が書いたより良いコードを見る。人は、自分の仕事に付加価値を付けない限り、「エレガンス」または「良い」コードの価値を決して知りません。理論を読むのではなく、あなたの仕事の分野の他の人が書いたコードに目を向けておくことをお勧めします。 stackoverflow(C++タグ)で議論されている概念に目を向けてください。このような検索を1日15分だけ費やすと、ランダムにあなたを助けることができる概念にあなたをさらすことができます。それはあなたのコードよりもよく書かれたコードを示すことができます。それはあなたがウィキペディアでフォローアップし、それについてもっと知るときです。好奇心から生まれるそのような学習は、翌日目覚めるときに忘れる理論よりもずっと長く続き、役立つでしょう。
また、MATLABやPythonなどの言語を試すことも検討してください。
物理学者がプログラマーになったとき、私は物理学の背景がソフトウェアの概念を理解するための正しいメタファーを形成するのに最も役立ちました。この観点から、プログラミングの学習がさらに楽しくなり、ソフトウェアで「エレガンス」の感覚を養うのに役立ちました。
私はCUJのコラムでソフトウェアのメタファーとアナロジーの重要で評価されていない役割について説明しました "思考のパターン-名前、メタファー、より優れたプログラミング、そして言語の政治" " 。たとえば、OOクラス継承の概念は、家族の親から子孫に特性を渡すことと比較されることがよくあります。これは正しくないアナロジーです。クラス継承の正しいアナロジーは、生物の生物学的分類です(たとえば、クラスRedRoseは花の一種であり、花は植物の一種です)。
または、階層型ステートマシンのソフトウェアコンセプトを例にとります。ここでの良い比喩は、水素原子のような束縛量子系の概念です。思い出すと、atomは3つの量子数| n、l、m>によって番号が付けられます。これは、それらが「ネスト」されている(階層的)ためです。このメタファーは、その状態は状態内にネストします(angular運動量(l)の状態がエネルギー状態(n)にネストするのと同じように)。また、状態のネストは常にいくつかの反映システムの対称性。
物理学からのもう1つの興味深いアナロジーは、「計算のアクターモデル」です。これは、マルチコアCPUと「クラウド」での分散コンピューティングのために最近再発見されました。ステートフルなアクター(アクティブオブジェクト)によって交換されるイベントを、QEDのフォトンやQCDのグルーオンなどの仮想ボソンとして考えると、便利で楽しいことがわかりました。このメタファーは、通信の基本的な非同期の性質、実行完了イベント処理(量子跳躍)、および明示的な中間成果物を介してのみ相互作用できるアクティブオブジェクトの厳密なカプセル化を説明します。
とにかく、システムメタファーを開発することは、XP(eXtreme Programming)で推奨されるプラクティスであり、物理学者としては、優れたメタファーを思いつくことができます。また、 "あなたのソフトウェアはあなたが適用する優れた比喩から概念の完全性を継承するからです。
まず、「エレガント」は相対的な用語です。抽象化はあなたにはエレガントに思えるかもしれませんが、別のC愛好家には不要なように思えるかもしれません。とにかく、あなたの質問に答えるには、レビューのために http://codereview.stackexchange.com にコードを投稿してみてください。
主なポイントから離れて、私自身の経験に基づくいくつかの未承諾のアドバイス。 Cだけですべての作業を完了できるのであれば、なぜそれを抽象的な方法でコーディングしたいのでしょうか。これにより、他のユーザーがコードを再利用できるようにしますか? C++に切り替える確かな理由がある場合は、抽象化してC++を学習し、OOの概念を学習します。それ以外の場合は、アイデアをドロップします。私の控えめな意見では、 OO抽象化ですか?私自身、OOPSとコードを「エレガントに」学ぶためにこの種の執念を持っていました。しかし、C++は習得するのに時間がかかります。ガベージコレクションはC++では自動ではないため、メモリ管理を学ぶことができます。自分の研究室で働いていて、手元の主な作業に集中するのではなく、C++とOOを学ぶのに多くの時間を費やしたので、アドバイスをしてください。