Nutcracker

Nutcracker

《プログラマーの修行の道》読書ノート

《プログラマーの修練の道》#

Type: Life, Tools
author: David Thomas. Andrew Hunt

この本の前版『小工から専門家へ』は以前から耳にしていましたが、その翻訳タイトルがひどいと思い、周りに誰も推薦していなかったので、読む気を失いました。今年、暇になったときにこの本の再版を見つけ、書籍のタイトルが『プログラマーの修練の道』に変わっていたので、暇つぶしと京東の割引の機会を利用して購入しました。2 章を読み終えたところで、2 年前に経験を迅速に得て生産性を向上させることができる本を見逃していたことに気づきました。この本には、軽く読むことができる部分もあれば、しっかりと咀嚼して消化する必要がある部分もありますが、私はこの本が咀嚼して消化する必要があるタイプの本だと思います。成功したプロジェクトの理由を抽出する手助けをしてくれ、生活や仕事で同じような問題に直面したときの対処法を考えさせてくれます。

実践的な方法#

人生はあなたのもの#

私はあなたの期待を満たすために生きているわけではない。あなたも私の期待のために生きているわけではない。
—— ブルース・リー

ソフトウェア開発は、どの職業リストにおいても、あなた自身が最もコントロールできる職業の一つです。私たちのスキルは需要に対して供給が不足しており、私たちの知識は地域に制限されず、リモートで働くことができます。私たちは豊かな収入を得ています。私たちは本当にやりたいことを実現することができます。しかし、開発者が変化を拒む理由は常に存在し、彼らはそこに縮こまり、物事が自分で良くなることを期待し、自分のスキルが時代遅れになるのを見て、世界が日々変化していることや、劣悪な労働環境を嘆いています。

作者が何か特別なことを言っているように見えるかもしれませんが、実際には現在の業界の区分において、ソフトウェア開発は確かに最も自分でコントロールできる職業の一つです。インターネット上には、必要なすべての資料が基本的にありますし、たとえあなたが一つのプログラミング言語しか知らなくても、今年は金融業務を行い、来年はショッピングを行い、再来年は車載システムに取り組むことができ、あなたの職業経験はほとんどすべて適用されます。職業環境はあなたのキャリアに大きな制約を与えることはなく、制約できるのはあなた自身だけです。

私のソースコードは猫に食べられた#

もしあなたがサプライヤーが役に立たないというリスクに直面しているなら、緊急計画を策定すべきです。もしディスクがクラッシュしたら —— あなたのすべてのソースコードがそこにある、それはあなたの責任です。「私のソースコードは猫に食べられた」と上司に言っても問題は解決しません。

チームの信頼#

あなたのチームはあなたを信頼し、あなたも彼ら一人一人を信頼すべきです。

  • 物事のすべての側面を直接コントロールする必要はありません。
  • あなたの考えを表現し、あなたのアイデアを述べてください。信頼に基づく健康的な環境を築きましょう。

責任を負う#

要求やタスクを引き受ける前に、あなたのコントロールの範囲を超えたリスク状況を分析しなければなりません。責任の倫理的含意があいまいすぎる場合、または実現不可能な状況に直面している場合、またはリスクが大きすぎる場合、あなたは責任を負わない権利があります。この段階で問題を提起し、タスクの実行可能性を再評価するか、リスク状況の責任者を明確にしてください。

結果に対して責任を負うことを決定する際には、関連する義務を引き受けることを理解してください。あなたが間違いを犯したり、誤った判断を下した場合は、それを正直に認め、選択肢を提示してください。

言い訳ではなく選択肢を提示すること。 選択肢を提示することは、必ずしも上記の例のように、すべての事にプラン B を持つことを要求するわけではありません。たとえ世界の終わりであっても、ポケットからタイムマシンを取り出すことができるわけではありません。しかし、悪いニュースを伝える前に、状況を改善するために何をすべきかを説明できると良いでしょう。チームメイトやリーダーは、そのような人と仕事をすることを好みます。彼らはこのような状況で新しい問題や新しい要求に参加するコストを低く抑えることができます。

ソフトウェアのエントロピー#

ソフトウェア開発は大多数の物理法則に制約されていませんが、エントロピーの増加からの打撃を避けることはできません。エントロピーは物理学の用語で、システムの「無秩序」の総量を定義します。不幸なことに、熱力学の法則は宇宙のエントロピーが最大化に向かうことを決定します。ソフトウェア開発はさまざまなバグの修正、要求の追加や補充により、ソフトウェアの複雑さと無秩序が徐々に増加しています。この小節では、ソフトウェアのエントロピーの増加を避ける方法を探ります。

  • 「破窓理論」—— 規則を制定したら厳守する必要があります。例えば、コードレビュー、コードリント、ソフトウェアアーキテクチャなど、これらの規則はソフトウェアの可読性を維持し、プログラムの複雑さを低下させるためにあります。制定した以上はしっかり守るべきで、表面的なものにとどまってはいけません。窓が一度壊れ始めると、正常に機能していたシステムは急速に悪化します。
  • 「リーダーシップ効果」—— 必要なときには、積極的に責任を引き受け、変革を推進する触媒となること。
  • 「温水でカエルを煮る」—— 大局を見守り、周囲で起こっていることを継続的に見直し、個人の行動にだけ集中しないこと。たとえあなたが一部の業務を担当していても、マクロ的に影響を与えるイベントに対して敏感である必要があります。

十分に良いソフトウェア#

より良いものを追求するあまり、すでに十分良いものを損なってしまった。
—— シェイクスピア『リア王』

現実の世界は、真に完璧な製品、特にバグのないソフトウェアを生産させることはありません。時間、技術、焦りが私たちに対抗しています。ソフトウェア開発者が理解すべき点は以下の通りです。

  • 品質を要求の問題として捉える —— あなたが作成するシステムの適用領域と達成すべき品質は、システム要求の一部として議論されるべきです。
  • ユーザーを参加させる —— ユーザーの要求を無視し、機能を積み重ね、コードを何度も磨くことはプロフェッショナルではありません。あなたは実現不可能な時間枠を約束するかもしれませんが、締切に間に合わせるために、後でプロジェクトを削減することになります。
  • いつ止めるべきかを知る —— 過度な装飾や洗練が良好なプログラムを侵食させないようにしてください。前進し、コードがその位置に留まる時間を確保してください。それは完璧ではないかもしれませんが、問題ありません —— 完璧でなくても大丈夫です(この部分のコードはパフォーマンスや機能に影響を与えず、あなたはそれを再度変更する必要がないかもしれません)。

知識の組み合わせ#

知識に投資することが最良のリターンをもたらす。
—— ベンジャミン・フランクリン

知識と経験は確かにあなたの最も重要な専門資産ですが、残念ながら、それらは時効性の資産です。新しい技術の出現や言語と環境の発展に伴い、あなたの知識は時代遅れになります。絶えず変化する市場の力は、経験を陳腐化させ、無関係にする可能性があります。技術社会の変化の速度がますます速くなっているため、このようなことは特に迅速に起こる可能性があります。あなたの知識の価値が低下すると、あなたの会社や顧客に対する価値も低下します。このすべてを防ぐために、新しいことを学ぶ能力はあなたの重要な戦略資産です。

知識の組み合わせを管理することは、金融投資ポートフォリオを管理することに非常に似ています:

  1. 正規投資には定期投資の習慣があります。
    専門的な視野を定期的に更新し、新しいツールやスキルを理解し、関連するニュースや技術記事を読むこと。
  2. 多様化は長期的な成功の鍵です。
    自分のスキルの範囲を広げ、熟知しているスキルが多ければ多いほど、変化に適応できるようになります。
  3. 賢い投資家は保守型と高リスク高リターン投資のバランスを取ります。
    新しい業界の動向を常に把握し、接触して学ぶことを試み、聞き手に徹するのではなく、積極的に参加します。
  4. 投資家は安く買い、高く売ることで最大のリターンを得ます。
    例えば、数年前のビッグデータ、フロントエンド開発、そして今のローコードや車載ネットワークなどです。これらはこの時期に通常よりも高いプレミアムがあります。十分な能力と備えがあれば、仕事のリターンを高めることができますが、明確にしておくべきことは、ブルーオーシャンがレッドオーシャンに戻った後、リスクが大きくなる可能性もあるということです。リスクに対処する能力が必要です。
  5. 定期的に投資ポートフォリオを見直し、再バランスします。
    現在の業界のトレンドに基づいて、自分の技術ツリーを再評価し、学習の優先順位を調整します。

学習の機会#

  • いくつかの資料を手の届くところに準備しておき、興味があるときにすぐに取り出せるようにします。
  • 答えを見つけることを個人的な挑戦とし、さまざまな方法で自分の知識の組み合わせを更新することに挑戦します。

批判的思考#

読んだり聞いたりしたことを批判的に考えます。あなたは、組み合わせの中の知識が正確であり、創作者の影響を受けていないことを確認する必要があります。

批判的思考は完全な学問であり、ここで始めます:

  • 「五つのなぜ」を問う —— 答えを得た後、さらに「なぜ」を続けて本質に近づきます。日常のコミュニケーションでは、挑発と誤解されないように注意が必要です。
  • 誰が利益を得るのか —— それは少し世俗的に聞こえるかもしれませんが、これにより脈絡を整理しやすくなります。
  • どのような背景があるのか —— すべての事象はそれ自身の背景の中で発生します。これが「すべての問題を解決できる」ソリューションが通常存在しない理由であり、「ベストプラクティス」を売り込む本や記事が検証に耐えない理由です(批判的に考えることが重要です)。

コミュニケーション#

私は人に頭から足まで見られる方が、無視されるよりはましだと思う。
—— 『90 歳の美女』

ただ持っているだけでは不十分で、どのようにそれをパッケージ化するかが重要です。たとえ最高のアイデア、素晴らしいコード、最も実践的な考えを持っていても、他の人とコミュニケーションできなければ、最終的には実を結ぶことはありません。

あなたの母国語をプログラミング言語のように扱い、自然言語で記事を書くようにコードを書くことを心がけ、DRY 原則、ETC、オートメーションなどを尊重します(後で触れます)。

  • 聴衆を理解する —— 聴衆に応じて、紹介するシステムを異なる方法やスタイルで説明することを選択します。
  • 自分が何を言いたいのかを理解する —— アウトラインをしっかり書き、核心を抽出します。
  • タイミングを選ぶ。
  • 聴衆を参加させる —— 聴衆を参加させ、会議を会話に変えます。これにより、自分の意見をより効果的に表現でき、彼らのフィードバックを聞き、彼らの知恵を吸収することができます。

実践的な方法#

ソフトウェア開発のすべてのレベルに適用できるいくつかのテクニックと方法があり、その中に含まれる思想はほぼ公理となり、実施過程でも非常に一般的です。しかし、これらの方法は文書化されることはほとんどありません。今、これらのアイデアとプロセスがここに集約されています。DRY、ETC などの原則や、プロトタイプやメモなどの方法論が形成されています。

ETC (Easier To Change)#

使用者に適応できるものが良いデザインです。コードに関しては、変化に応じること(コードをより読みやすく、疎結合にし、単一責任を持たせ、置き換え可能にする)です。ETC(より容易に変更可能)は価値観であり、ルールではありません。あなたがソフトウェアの領域で考えるとき、ETC は異なるルートの中から一つを選ぶためのガイドです。

あなたが識別できる能力を持っているとき、常識は通常間違っていません。もし手がかりが見つからない場合、以下のことを行うことができます。

  1. どのような形式の変更が発生するか不確実な場合は、問題の発生源に戻ります —— あなたが書いたものを置き換え可能にします。そうすれば、将来何が起こっても、そのコードは障害とはならないでしょう。
  2. それを直感を育てる方法として考えます。エンジニアリング日記に、あなたが直面している状況を書き留めます:あなたにはどのような選択肢があり、変更に関するいくつかの推測があります。将来的にこのコードを修正する必要があるときに、振り返るのが便利です。似たような分岐点に直面したとき、これが役立ちます。

DRY (Don’t Repeat Yourself)#

知識は安定しておらず、変化します —— 通常は頻繁に。顧客との会議を開くだけで、要求の理解がすぐに変わることがあります。政府が規則を変更すると、いくつかの論理が時代遅れになります。メンテナンスを行う際には、物事を変更する表現を見つける必要があります —— それらはプログラムに埋め込まれた知識のカプセルです。問題は、規範、プロセス、開発のプログラムの中で知識を複製することが非常に容易であり、一度それを行うと、メンテナンスの悪夢を招くことになります。信頼性のあるソフトウェアを開発するため、または開発プロジェクトを理解しやすく、メンテナンスしやすくするための唯一の方法は、DRY 原則に従うことです —— システム内のすべての知識は単一で明確かつ権威ある表現を持つ必要があります。

DRY は自分自身を繰り返さないことを指しますので、「コードをコピー&ペーストしない」ということだけを意味するわけではありません。これは確かに DRY の一部ですが、非常に小さな部分であり、重要ではありません。

DRY は知識と意図の複製に関するものであり、もし二つの場所で表現されているものが実際には同じで、表現方法が異なるだけであれば、それも DRY 原則に違反します。同様に、二つの場所の表現方法が完全に同じであっても、異なるモジュールで異なる責任を担っている場合、それは DRY 原則に違反しません。

コードラボ#

  • 統一アクセス原則 ——『オブジェクト指向ソフトウェア構築』で説明されています:モジュールが提供するサービスは、統一された合意を通じて提供されるべきであり、その合意は実装がストレージに基づいているのか、計算に基づいているのかを明らかにすべきではありません。
  • あなたの努力の方向は、既存のものを見つけて再利用しやすい環境を育むべきであり、自分で再び書き直すことではありません。再利用が難しい場合、人々はそうしません。再利用できなければ、知識の重複のリスクがあります。

正交性#

「正交性」は幾何学から借用された用語です。二つの直線が交差して直角を形成する場合、それらは正交です。

線分 AB と CD は互いに正交

計算科学において、この用語は独立性と疎結合性を象徴します。良好なアーキテクチャのシステムでは、二つのモジュールは互いに独立しているべきであり、一方のモジュールの変更は他方のモジュールに影響を与えるべきではありません。正交なシステムは生産性を向上させ、リスクを低下させ、絶えず変化するビジネスや要求により良く対応できます。

システムの正交性を維持する方法:

  • コードを疎結合に保ち、グローバルデータを避け、類似の関数を避ける。
  • コードに対して常に疑問を持つ習慣を身につける。機会があれば、再編成し、構造や正交性を改善します。
  • 正交性に基づいて設計・実装されたシステムはテストが容易です。したがって、単体テストを書くこと自体が面白い正交性テストです。単体テストを構築して実行するために何をすべきか?もしシステムの残りの部分の大部分のコードをインポートする必要があるなら、あなたはシステムの他の部分と十分に疎結合されていないモジュールを発見したことになります。
  • 問題の修正策と範囲を記録し評価する。修正された問題をアーカイブし、各バグ修正が影響を与えたモジュールとファイルの数のトレンドを分析します。これにより、システム内の不安定なモジュールや設計が正交でないモジュールを発見できます。

可逆性#

  • 柔軟なアーキテクチャを維持する。
  • 流行を追いかけることを放棄する。

トレーサー弾#

トレーサー弾は目標に迅速に到達し、射手は即座にフィードバックを得ることができます —— もしトレーサー弾が目標に集中したなら、その後の通常の弾も命中します。

同様の原則がプロジェクトにも適用されます。特に、過去に行ったものから何かを構築する必要があるとき、トレーサー弾式の開発を行うことができます。

利点#

  • その中で機能するフレームワーク(コア)を構築できる。
  • 進捗をより良く感じることができ、これらのケースを通じてパフォーマンスを測定し、ユーザーに進捗を示すことがはるかに容易です。
  • 小さな試行錯誤コストで、コア部分を迅速にユーザーにコミュニケーションし、彼らが望んでいるかどうかを確認できます。より迅速な速度と小さなコストでプログラムのフィードバックを収集し、より正確なバージョンを生成します。

方法論#

  • 要求のレビューと開発段階で、システムを定義する部分や重大なリスクがある部分を見つけます。そして、その部分に優先順位を付け、最初に処理します。
  • トレーサー弾のシナリオは、完全なシステムのプロトタイプを迅速に構築することですが、プロトタイプを作成することではありません。

プロトタイプとの違い#

プロトタイプは一回限りのコードを生成しますが、トレーサー弾はシンプルでありながら、完全であり、最終的なフレームワークの一部です。プロトタイプはソリューションの実現可能性を検証するために使用され、トレーサー弾はシステムの実現可能性を検証するために使用されます。

プロトタイプ制作#

プロトタイプ制作は経験を学ぶためのものです。その価値は生成されたコードではなく、得られた教訓にあります。これがプロトタイプの本質です。

プロトタイプ制作は完全な製品制作よりもはるかに安価です。したがって、プロトタイプを作成することでリスクを分析し、露呈させることができ、コストを大幅に削減しながら修正の機会を得ることができます。プロトタイプは、問題の答えを得るためだけに設計されているため、多くの重要でない詳細を無視できます。しかし、もしあなたが詳細を放棄できない環境にいることに気づいた場合、トレーサー弾式開発の方が適しているかもしれません。

プロトタイプを作成する際に無視できる詳細:

  • 正確性 —— 適切なタイミングでデータを置き換えることができます。
  • 完全性 —— プロトタイプは優先機能を満たすだけで十分です。
  • 頑健性 —— エラーや境界条件は必須ではなく、特定の航路を検証するだけで済みます。
  • 形式 —— あまり多くの注釈や文書は必要ありません。

プロトタイプを作成する際には、詳細を考えることをできるだけ遅らせ、システムの各部分がどのように結合して全体を形成するかを確認することが重要です。

ドメイン言語#

言語の境界は、一人の世界の境界である。
—— ルートヴィヒ・ウィトゲンシュタイン

コンピュータ言語は、あなたが問題を考える方法や情報の伝達をどのように見るかに影響を与えます。すべての言語には特性のリストがあります —— 静的型、動的型、ミキシン、関数型またはオブジェクト指向 —— これらすべてが問題の解決策に対して、提案を提供することもあれば、混乱を引き起こすこともあります。一部のケースでは、上級プログラマーは、用語集を使ってコードを書くのではなく、その分野の言語を直接使用してプログラミングを行い、その分野の用語、文法、意味を直接使用することができます(DSL)。

伝統的な言語、例えば Java のようなものでは、XML や JSON のような外部言語を使用するために追加のパーサーを作成する必要がありますが、Kotlin のような現代の言語では、DSL のサポートが非常に優れています。私たちは既存の用語集を使って DSL 言語を簡単に拡張できます。

別の視点から考えると、ChatGPT や Copilot の台頭とトレンドがあります。ビジネスコードの大部分の作成を AI に任せることで、私たちの作業効率が向上します。理想的には、私たちは境界を整え、剪定する操作を提供するだけで済みます。しかし、ビジネス要求を言語モデルが明確に理解できる文字に変換する方法も、私たちの母国語のプログラミング能力を通じて検証される必要があります。私たちは今後の要求シナリオで、母国語を使って擬似コードを書く能力を鍛える必要があるかもしれません。これにより、急速に進化する AI の発展に対応し、自分の作業効率を向上させることができます。

見積もり#

問題や要求を受け取ったとき、見積もりを通じてそのイベントの実現可能性を迅速に判断できます。そして、見積もりの前提は ——問題をモデル化することです。問題や要求を理解するとき、私たちはそれに対して粗い思考フレームワークモデルを構築し始めます。モデル化の過程で、表面上は見えない潜在的なパターンやプロセスを発見できます。モデルを得た後、それをコンポーネントに分解し、これらのコンポーネントがどのように相互作用するかの数学的ルールを明らかにする必要があります。

プロジェクトの進捗を見積もる方法#

  • RERT(プログラム評価レビュー技法)—— 各 PERT タスクには楽観的、可能性のある、悲観的な見積もりがあり、このような範囲値を持つ見積もりは、最も一般的な見積もりエラー要因を回避できます。
  • 増分開発:タスクを異なる段階に分け、各イテレーション後にその中の経験を抽出し、進捗の管理を改善します。

問題のモデル化は、AI プログラミングの核心的な方法論でもあります。モデル化の形式を通じて、要求や問題を明確に表現し、各ノードをコンポーネントに分解し、これらのコンポーネントのモデルを実際のコードを実装する前にその責任と機能を明確に区分することができます。

基本ツール#

プレーンテキスト#

プログラマーとして、私たちの基本的な材料は木材や鉄塊ではなく、知識です。私たちは要求を知識の形で収集し、それを設計、実装、テスト、文書の中で表現します。プレーンテキストは、私たちが知識を永続的に保存するための最良の形式であると考えています。

いわゆるプレーンテキストは、単に txt 形式のファイルだけを指すのではなく、人間が直接読み、エディタが直接解析できる任意のテキストデータを指します。プレーンテキストの利点は以下の通りです。

  • 老朽化に対する保険 —— 現在、多くの知識ソフトウェアの使用と更新はネットワークとメンテナンスに依存しています。データを保存するアプリケーションのライフサイクルが終了した場合、純粋なテキストデータをエクスポートできない場合、アプリケーションに保存された知識を再利用することは非常に困難です。
  • 検索が容易 —— プレーンテキストで記録することで、バージョン管理を使用して変更履歴をシームレスに管理し、シェル機能を通じて知識を自由に検索し、マッチさせることができます。また、いくつかのテキストエディタに投げ込んで迅速に検索することもできます。特定のソフトウェアやその劣悪な検索機能(例えば WeChat)に依存する必要はありません。
  • エディタとシェルを熟練して使用する—— グラフィカルツールの利点は WYSIWYG(見たまま得られる)にありますが、弱点は WYSIAYG(見たままがすべて)です。もしグラフィカルツールの設計者があなたの追加の要求のためのフックを設計していなければ、あなたはそれを実現できません。しかし、エディタとシェルの強力なエコシステムと汎用性を活用することで、非常に強力な能力を組み合わせることができ、その知識は一般的であり、特定の IDE に限定されません。

エンジニアリング日記#

日記の利点:

  • 記憶よりも信頼性が高い。
  • 現在のタスクに無関係なアイデアを保存する場所を提供します。これにより、あなたは現在行っていることに集中し続け、この素晴らしいアイデアが忘れられないように導きます。
  • それはゴム製のアヒルのようです。あなたが立ち止まり、何かを書き留めるとき、脳はシフトするかもしれません。まるで誰かと話しているかのように —— これは反省の良い機会です。メモを取り始めると、最近行ったこと、つまりメモのテーマが完全に間違っていることに突然気づくことがあります。

もう一つの追加の利点は、何年前に自分が何をしていたかを時折思い出し、あの人たち、あの出来事、そしてあのひどい服装や髪型を思い出すことができることです。

実践的な偏執#

自責の念にはしばしば贅沢がある。私たちが自責の念に駆られるとき、他人が私たちを責める権利がないと感じる。
—— オスカー・ワイルド『ドリアン・グレイの肖像』

BDC 契約式プログラミング#

TDD テスト駆動開発#

著者は BDC と TDD の開発モデルについて語っています。これは防御的プログラミングとアサーションプログラミングの理念を称賛するものであり、コード設計段階で境界条件を十分に考慮し、チェックを行います。問題が発生したときには、早期に例外を投げ出し、システム全体にさらなる危害を及ぼすのを避けます。これは合格したプログラマーの基本的なスキルであり、特別な方法論はありません。称賛に値するのはアサーションプログラミングの切り替え可能性です。私たちは Google のソースコードのように、デバッグモードでのみアサーションを有効にすることができ、日常の開発やテストプロセスでいくつかの問題を明らかにすることができます。そして、プロダクションモードでは、ユーザー優先とパフォーマンス損失の理念に従い、アサーションをオフにし、ログを補充することができます。#

多くの場合、明日も今日と同じように見えるかもしれませんが、必ずそうなるとは期待しないでください。#

  • 設計やメンテナンスを行う際、見えない範囲を超えたモジュールのメンテナンスや設計に無駄なエネルギーを費やす必要はありません(複雑さを増すだけです)。例えば、Android 0.x バージョンの時、ハードウェアは GPU をサポートしていませんでしたが、開発を担当した Google のエンジニアは、システム全体を設計するのではなく、仮想 GPU の一部を作成しました。Android の後続バージョンが GPU をサポートするようになったとき、仮想 GPU のモジュールを置き換えるだけで済み、システムの設計はそのまま残ります。コードを置き換え可能にすることは、内部の凝集性、疎結合、DRY を向上させ、より良い設計を実現するのに役立ちます。
  • ソフトウェア開発では、常に深く考えた小さなステップを取り、フィードバックを確認し、進める前に調整を行います。フィードバックの速度を速度制限と見なし、「あまり大きな」タスクステップを決して行わないでください。

曲げずに折る#

TDA(tell-don’t-ask)#

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。