🌶️

【書評】『達人プログラマー』を久しぶりに読んだのでわかるわかるめちゃわかる〜〜〜〜〜〜ッをまとめました

2025/01/10に公開

はじめに

突然ですが最近、再読にハマっています。

エンジニア初心者の頃におすすめ技術書を色々と読んだのですが、経験を積んだ今再び読むとまた格別に違った所感になるんですよね。以前はあまり意味がわからなくて「ふーん」という感覚で読んでいたものが、経験と合わさることによって「わかるわかるめちゃわかる〜〜〜〜〜〜ッ」ってなるものが増えたり、「これは本当に大事」と身に沁みて実感したりします。

今回は数年ぶりに読んだ達人プログラマー(第 2 版)について再読した際に、今の自分にとって大切にできそうと感じたところを、振り返り心身に刻むためにもまとめてみました。

なお、私のエンジニア歴的スペックは以下の通りです。

  • エンジニアとして丸 4 年くらいはガッツリ業務でコードを書く
  • うち 2 年は比較的モダンな技術スタックのもとで修行する
  • フロントエンド、バックエンドなど一通りの技術と楽しくふれあい済み

近しい境遇の方が本記事を通して「わかる〜〜」となってくれても、「いやここも良いよ」となってくれても嬉しいですし、すでに達人の方が「そんな時期もあったね」となってくれても良いですし、プログラミングを始められた方が「ふーん将来はそうなる可能性があるのか」と思ってもらっても……どれでも嬉しいです!

また、達人プログラマー(第 2 版)をまだ読んでいない方や積読状況の方については、少しでも興味を持っていただけたらありがたいです。

学び続ける

最初に、エンジニアとして、時には開発するチームを巻き込んで学び続けることの大切さについて、本書の引用を踏まえながら紹介します。

なんとなくある程度のことができるようになった 3〜5 年のエンジニアの次のステップとして、知識を身のあるものとして深め説明できる段階や、数ある情報の中からニーズに応じて深めて調査できる段階がありそう、というものを日々感じています。

そんなことを思う、今の自分に刺さった場所を以下に述べます。

知識のポートフォリオ

この業界はとてもダイナミックです。先月投資を始めたばかりのホットなテクノロジーが、今日はもう冷えきっている場合もあります。(P20『あなたのポートフォリオを作成する』より)

エンジニアとして生存し続けるために、学ぶ姿勢において現状の知識で満足するのはいうまでもなく本当に大切だなと、日々さまざまな情報を見ながら思います。本書では、定期的に知識ポートフォリオに投資するために幾つかの提案がされていますが、「月に 1 冊のペースで技術書を読む」「近場のユーザーグループに参加する」というものを自分は徹底していこうと、改めて思いました。

特に技術書を読むという行為について、何を持って「読んだ」と言えるかはかなり難しいなと思っており、繰り返し読んだり、読んだことを実践に移せるようになるまで噛み砕いたりすることがとても重要と感じています(本書のアウトプット記事は、こういった理由がモチベーションになっているのも大きいです)。

徹底した批判的思考

商業主義を甘く見てはいけません。インターネットの検索エンジンが真っ先に返してきたものが、最適な選択であると思わないことです。(P23『批判的な考え方』より)

もうこれはどこでも言われていることですが、ここ数年は LLM の進化によりむしろもっと進んでて、インターネットの検索というよりは AI の回答によってコーディングができる世界になっていますよね。そんな AI でもタイミングによってはしれっとニュアンス違いで、実は思っていたのと異なる回答が来る場合があります。「あれ?」と思って自分の手で公式サイトを覗けるか、信じきらずに自分でも一度調べてみるか、というのは、現在においてはまだまだ有用かと思われます(本当に AI が進化し切るとこの思考は必要なくなりますが、その時には新しい職業を探すことになりそうです……)。

検索にかかわらず、アーキテクチャの設計やユーザーの要求などについてもそうですが、何でも鵜呑みにせずに違和感の裏を取ることは、非常に重要だと考えています。特に自分で考えたことや思いついたことは間違っているとは信じづらいと思うので、そんな時にこそもう一人の自分が「ちゃんと調べた? 本当にそう? 裏は取れそう?」と言えたら良いなと感じます(口でいうほど簡単ではないですが。汗)。

偶発的プログラミングの回避

Fred は、なぜこのコードが最初のうちは動いていたのかを理解していなかったため、動かなくなった時もその理由が分からなかったのです。(P253『偶発的プログラミングの方法』より)

徹底した批判的思考と、ニュアンスは似ています。

「なんとなく動いているから良さそう」のなんとなくが、致命的なインシデントに遭遇した際に命取りになる瞬間を、何度か身をもって体感した経験があるからこそ、Fred の気持ちがとてもよくわかりました。

業務だとしても趣味だとしても、コードを書いているその瞬間、コードに愛と責任を持って PR に送り出すという心得を忘れないようにしたいです。特に急いでいたり、なんらかのプレッシャーを抱えていたりする場合は、「とりあえず動くから一旦リリース」というのが軽快に頭をよぎる(気持ちが分かるからでしょう、PR も承認されてくれます)ので、そんな時に自分にブレーキをかけてみて、丁寧に丁寧にコードと向き合いたいです。

PR レビュー依頼 で「ここって何でこうなっているんですか?」と常にツッコまれてヌルッと回答したり、可愛い後輩にどやっとした顔で説明したりする自分を妄想をしながら、取り組みたいものです!

カーゴカルト

我々はスクラムを採用していると主張しているチームを見たことがあります。しかしよく見てみると、彼らは日々のスタンドアップミーティングを週 1 回しか実施しておらず、最長 4 週間とされているスプリントはしばしば、6〜8 週間になっていました。(P346『ココナツでは解決できない』より)

中身を伴わない形だけの真似をカーゴカルトと呼び、その危険性について紹介する例です。

何事も流行や型に当てはめて作り上げるのではなく、コンテキスト差分を理解しながら進めること、そうして作ったものは定期的に振り返り軌道修正しながら進めていきたいと思いました(ベストプラクティスを実施したら OK ではないということ!)。

エンジニア日誌

エンジニアリング日誌とは、作業内容や学んだこと、アイデアの概略、各種の計測器から読み取った内容など、基本的に仕事と関係のあるあらゆることを記録する日誌です。(P128『エンジニアリング日誌』より)

本書では手書きの紙ベースを推奨しておりまして、ちょうど私も今年から紙のメモを始めたところでした。便利なドキュメントツールはたくさん世の中にありますが、TODO を振り返れたり、手軽に図にできたり、矢印を引いて追記できたりするので、とっても良いなと感じています。業務でも、とりあえず 1 ヶ月は日誌を上げられるようにしてみようと思っています。私の場合は、手書きの方が PC に向かって書いているよりも考える脳みそが少し深くなる気がします。

ツールに成熟する

料理人にとっては包丁やフライパンが、大工にとってはノコギリやカンナがツールであるように、エンジニアにとってもコーディングする上で重要な道具が多数あります。道具に親しむことは快適で生産性の高いものづくりの原動力になるという観点で、自分に刺さったものをまとめました。

CLI

GUI 環境を使いながら、手作業でルーチンワークを行っていないでしょうか? 同僚に、「このボタンをクリックする」「この項目を選択する」といった操作を書き述べた手順書を手渡したことがあるでしょうか? こういった操作は自動化できるのでしょうか?(P103『貝殻(シェル)遊び』より)

私は Linux コマンドがいまだにあまり得意ではないので、こういった話は本当に耳が痛いなと思いました。一方で、覚えてよく使うコマンドがいかに日々のコーディングを手伝ってくれているかもなんとなくわかります。

改めて、習得しようとしたその一時だけは生産性が下がるかもしれませんが、その後 V 字回復して爆上がりすることは目に見えているので、こういった操作をしていた自分に気づいたら「まあ今回はこのまま行こう」という甘い自分を捨てて、シェルを利用する癖をつけたいです。

本書の中で「やどかりの気持ちになって、住処をよくしましょ」という旨のメッセージがあって、それがとてもキュートで印象に残っています。Linux コマンドは枯れた技術なので、高齢のやどかりになっても住処が快適そうで良いです!

エディタ

まず自らが編集している姿を観察してください。何らかの繰り返し作業を行なっていると気付くたびに、「もっとよい方法があるはずだ」と考える癖を付けるのです。そして、それを見つけてください。(P105『パワーエディット』より)

CLI パートと非常に似ていますが、こちらも重要だなと思います。VSCode を利用しているのですが、同じ VSCode ユーザーとエディターをシェアしてペアプロしている時に、思いもしなかった動きをしているカーソルを見かけてびっくりした記憶、……あります。

エディタは常日頃から触る分、一度覚えようとした技に慣れるのも絶対早いです。やるべき。今すぐ。
観察と気づきも重要なポイントなので、忘れないようにしたいものです。

デバッグ

バグやバグレポートを最初に目にした時の反応が「そんなことはあり得ない!」というものであれば、明らかにあなたが間違っています。(P114『デバッグの心構え』より)

失敗に「驚いた」時に、あなたの仮定のいくつかが誤っていたという点に気付くべき理由がここにあります。単に「信じている」というだけの理由で、バグを含んでいるルーチンやコードを見逃してしまうことがないようにしてください。証明するのです。ちゃんとしたコンテキストのなかで、ちゃんとしたデータを用いて、ちゃんとした境界条件で証明するのです。(P123『デバッグ時の戦略』より)

本当に原因不明で終わる障害はほんのわずかであり、99%くらいのエラーは絶対に原因あるんですよね。逆に「あーこれじゃん!!!」となった時には逆にスッキリすらしますね。落とし穴に最初から気づけるようにしたいですが、それ以上に何かあったときに冷静にデバッグすることもとても重要です。

本書によれば、デバッグのポイントは以下の通りです。

  • パニックにならないこと
  • エラーを再現させること
  • エラーメッセージを読むこと

また、こうしたエラーがあった際にコードの足跡を追いやすくするためのトレースなどにも触れられていました。

それにしても……「証明するのです」の一言、かっこよくてシビれました。

コーディングする

続いて日々コーディングを行なっている時の考え方もまとめました。

テクニック

本書では良いコードの根底に変更容易性を置いています。こういった性質をコードに持たせるための様々なテクニックは、本書以外でもよく紹介しますが、特に以下が印象に残りました。基本ではあるのですが、ついつい忘れてしまいそうになります。

  • コードの結合度を最小化すること(P56)
  • どこからでもアクセスできるデータの利用を避けること(P56, P171)
  • 継承を避けること(P205)

並行処理、共有状態

1 つ前のテクニックよりもやや難易度の上がる、並行処理や共有状態などにおける適切な考え方についても楽しく読みました。

並行の考え方については、システムのパフォーマンス観点に辿り着いて初めて考える、でも良いですが、実世界に置き換えた時にどのように並行して処理できるかのワークフローを考える、という紹介が面白かったです。

共有状態については、「こここうやって共有していると、ああいうバグに繋がるかも」と観察して見つけるのが結構難しいので、注意しないとと思います。非アトミックな更新やセマフォの利用、Pub/Sub 的な発想など、一般的にやや難易度の高い領域についても心にとどめて設計・開発したいなと感じました。

防衛的コーディング

自分も含めた誰もが完璧なコーディングを行うことができないという事実を知ることで、達人プログラマーのコードは彼ら自身の過ちに対しても防衛的になるわけです。(P131『あなたは完璧なソフトウェアを作ることができない』より)

「あり得ないことは起こらない」という思い込みは捨て、起こるはずがないのであればそれを証明していく防衛的コーディングを心がけたいものです。外部から取得したデータは信頼せず検証することや、開いたものは閉じたりすること、不要になったものはリリースやクリーンアップすること、例外が起これば素早くシステムを停止させることが大切とのことです。

印象的だったのは、システムが常に危険な世界で実行されていることを思い出すべき、というフレーズです。特別な障害対応でない限り、私たちは常に自分の PC 環境内でコードを動かしているので、こういった前提はすぐにすっぽり忘れてしまいます。

忘れてしまうことにより「まあ大丈夫だろう」という楽観的な思考が働きやすいので、ぎゅっと自分自身を戒めたいですね。

防衛的コーディングはセキュリティ観点からも重要です。

「こんな重要性の低いコードに攻撃しようとする人間など誰もいない。このサーバーがあることすら誰も知らない」と考えてしまうかもしれません。しかし世界は広く、その隅々までネットワークは繋がっているのです。(P297『実世界の外敵から身を守る』より)

セキュリティに関する原則として 5 つほど本書に記載がありました。特に以下 3 つは開発者として常に考えるべきだと思いました。

  • 攻撃者に攻撃される面を最小限にできるように考えること
  • 権限は最小にすること
  • セキュリティアップデートを適用すること

ただ個人的に日々のコーディングにおいてセキュリティ観点を持つことは、コードの柔軟性などを考えるのと違う脳みそを利用するようなイメージで、わりと訓練がいることだなと。こちらに関しては本書だけでなく様々な情報を仕入れるべきだと考えています。

メンテは日常業務

早めにリファクタリングすること、そしてこまめにリファクタリングすること(P272『リファクタリング』より)

チーム開発の経験上「急ぎなので一旦ここはこの形で、TODO コメント残してマージします」は、ずっと後に TODO コメントだけを消すようになりますし、「ここは一旦周辺と合わせて良いか。あとでまとめて共通化して直そう」と思った場所は一生リファクタリングされません。

常に自分が最適解と思える PR を出すこと、割れた窓や割れそうな窓を放置しないことは、せかせかコーディングをする日々においては本当に難しいことだなと思います。見直して、考え抜いて、一つひとつ丁寧にコーディングし続けるのは大切にしたいです。

アルゴリズムの計算

単純なループを記述している場合であっても、それが O(n)アルゴリズムであるということを意識するようにしてください。ループの内側にループがあれば、それは O(m×n)になるのです。この値が常にどれくらいになるかを自問するべきでしょう。(P265『現実的なアルゴリズムのスピード』より)

アルゴリズムの計算ができることが、日常のプログラミングにおいてそれほど大きなメリットになるとは思えません。しかし大切だなと思うのは、「あれ、なんか遅くなりそうなコードかも?」という嗅覚が養えているかどうかです。計算量によるパフォーマンス面の問題は、気をつけないとデプロイしてローカルや検証よりも大規模な本番環境で実行されて初めて明るみに出ることもしばしばあると感じており、コードレビュー時や自分がコードを書いている際には注意して意識を向けたいところです。

プロトタイプを作る

本書におけるプロトタイプの考え方についても、とても感銘を受けたので 1 つのセクションとしてまとめました。

「欲しいものに気づいてもらう」手段

現実世界は乱雑で、矛盾に満ちあふれ、未知の事柄がそこかしこに散らばっています。そういった世界できっちりとした仕様を作り出すことなど、不可能とは言わないまでも極めて難しい話なのです。(P314『要求の落とし穴』より)

仕様に基づいて作成したものが、後から丸っとひっくり返ってしまった、あるいは最悪の場合、完全になかったことになった、といったことは多かれ少なかれ誰しも経験がある気がします。その時「せっかく開発したのに……」という気持ちに少なからずなりましたが、自分が間違っていたな〜と思いました。

真の要求はまだわからない。プロトタイプによってフィードバックや対話が始まり、欲しいものに気づいてもらえる。このようなマインドにチェンジできると、何か残念な気持ちになりそうだった自分の心がちょっと軽くなる気がしました。

早さは正義

常に小さな歩幅で少しずつ前に進むように意識してください。そしてフィードバックを得た上で、先に進む前に軌道修正を加えてください。(P160『ヘッドライトを追い越そうとしない』より)

「せっかく作ったのに……」もったいないお化け的な感情が発生する理由は色々とありますが、特に大きいものとして自分が完璧だと思うものを 100%の状態で完成させて提出してしまった、というのが経験上あったかなと思います。

常にプロトタイピング的な開発をというのであれば、PR は小さく、設計は 70%で、早くフィードバックをもらえるように自分の開発の進め方も見直したいなと思いました。アジャイルに!

テストする

最後のセクションにテストを置きました。ここ数年において自分の中でテストへの関心が高まっていることもあって、本書でマーカーを引いたところはテスト系のボリュームの割にとても多かったです。考え方によっては書き続けるモチベーションの難しいテストについて、本書から学んだことをまとめます。

テストの目的

テストとはバグを見つけることではない(P275『コードのためのテスト』より)

「システムがきちんと動いていることを確かめる」のではなく、テスト設計を行なったり、テストを書くことによって、仕様に対する疑問が先に出てきたり、自分のコードのユーザー第一号になったりする。テストについてそう考えるのが良い、と本書に書かれていました。

エンジニアのテストコードの話ではなく、QA チームのテスト設計により未定義の仕様が明るみになる、という経験は何度かあったため、仕様に対する疑問が浮かぶという利点については理解できました。

一方で、テストコードがユーザー第一号になるという考え方は言われてみればそれはそうなのですが、とても面白い考え方だなと思いました。逆に、本書の別ページでも紹介されていましたが、あまりにもテストを怠り続ければ、エンドユーザーがテスターになってしまうわけですね……。

徹底

早めにテスト、何度もテスト、自動でテスト(P353『容赦ない継続的テスト』より)

テストがすべて終わるまでコーディングは終わらない(P353『容赦ない継続的テスト』より)

この大元にある考え方は、防衛的コーディングと同じでしょう。あり得ないことがいかに起こらないようにするか、その考えを深めるために、徹底したテストはよく効く処方剤になるはずですから。

「多くの開発者はコードのどの部分が弱いかなんとなく知っており、無意識のうちにその部分を避けた手ぬるいテストコードを書く」という指摘は、痛いな〜と感じました。その部分を避ける、ということは(意識的には)ないですが、テストしにくいように感じる部分については「まああそこをテストしているから大体網羅されるだろうな」とか「一旦やり方検討してあとで書こう」みたいになりがちなんですよね。そういうところこそ、徹底してコードを書いて、より正しく動くシステムという証明を強固にしていきたいなと思いました。

おわりに

開発者としての我々の目標は、「ユーザーを喜ばせる」ことです。それこそが、我々の存在理由なのです。ユーザーのデータをマイニングできるようにしたり、ユーザー数を数えたり、ユーザーの財布の紐を緩めることではありません。(P360『ユーザーを喜ばせる』より)

終わりに私の 1 番のお気に入りであるセクションの言葉で締めようと思います。
なんといっても、ユーザーのことを考えて開発するのが良いですね!達人プログラマーに書かれた重要な多くの Tips のほんの一部分について紹介させていただきました。ここまでお読みいただき、ありがとうございました。

Discussion