KDOC 91: 『世界一流エンジニアの思考法』を読んだ

この文書のステータス

  • 作成
    • 2024-02-16 貴島
  • レビュー
    • 2024-02-18 貴島

概要

世界一流エンジニアの思考法』を読んだ。Microsoftで働く作者が一流の同僚の習慣を紹介したり、素晴らしい労働体験と日本的労働を比較する本。

メモ

いきなり手を動かさない。まずは事実(データ)を1つ見つける → いくつかの仮説を立てる → その仮説を証明するための行動をとる。

単に思いつきでいろいろなパターンを試して正解を探しているだけだと、とても時間がかかるうえ、新しい知識を何も学んでいない。思いつきによる試行錯誤は悪。

どんなに頭がいい人でも理解には時間がかかる。頭のいい人の理解が早いように見えるのは、時間をかけて基礎を積み重ねているので、すでに理解していることに関して脳のメモリにコンテキストが載っているからである。早くできるように頑張ることは最終的な生産性をむしろ下げる。理解せずにコピペしたりするから。

理解の3要素。

  • その構造をつかんで、人に説明できること

    本質をつかんでいると、シンプルにも詳しくも人にわかりやすく説明ができる。

  • いつでもどこでも即座に取り出して使えること

    基本的な構造から把握した知識は、参考書を見たりググったりせずともいつどこでも即座に使えて応用範囲が広い。

  • 知見をふまえて応用がきくこと

    似た課題における問題解決はもちろん、複雑な難題も因数分解して組み合わせられる。新しいものも生み出せる。

「ここはだいたいこんな雰囲気だよね」と読み飛ばせそうなところでも、丁寧に時間をかけ、サンプルの数値を書き、十分な理解に努めていた。

コードを読むのを早くすることばかり考えていたが、彼はコードのロジックを読むのではなくコードの意図とその背後のアーキテクチャを理解するために読み込んでいた。理解にしっかり時間をかけるのを恐れない。

プログラミングを基礎からやり直すためにした3つの作戦。

  • 定時後や週末に、プログラミングの基礎を学ぶ

    チュートリアルから。ギターの基礎練習のつもりで1つ1つ丁寧に読んでコードを書く。

  • C#の言語仕様を勉強する
  • LeetCodeを一番簡単なレベルから毎日やる

    1問に時間をかけて別のやり方を試した。メモリや速度の違いを見たりした。英文は読み飛ばし癖がついていたが、時間をかけてゆっくり理解して読むようにした。

「理解は時間がかかるもの」として、急がず、徹底的に理解する習慣をつけた。以前はメモをとりまくっていたコードリーディングもゆっくり理解して100%挙動が理解できている。

お客さんの言っていることは聞くけど、信用せずファクトを検証していくのがよい。プログラミングも同じ。自分でログなどを検証して問題解決をしないと思い込みをしてしまう。

デザインドキュメントをコードの前に書く。

自分やドメインエキスパートに対して質問するのを恐れない。エンジニアがより賢くなるのはチームの幸せにつながる。

一番大変なのは頭の中にメンタルモデルをつくる行為。一度作れば素早くソフトウェアの動作をイメージできる。自分なりの脳内イメージを作り上げられれば、頭の中で考えを整理したり、問題発見に至るプロセスが大幅に高速化する。

1つのことで2時間以上ブロックされたら、質問するなり相談して寝かせておいて、他の仕事をやっておくほうがよい。

Be Lazyを達成するための習慣。

  • 望んでいる結果を達成するために、最低限の努力をする
  • 不必要なものや付加価値のない仕事(過剰準備含む)をなくす
  • 簡潔さを目指す
  • 優先順位をつける
  • 時間や費やした時間より、アウトプットと生産性に重点をおく
  • 長時間会議しないように奨励する
  • 会議は会議の時間内で効率的かつ生産的に価値を提供する

いかにやることを減らすかに頭を使っている。減らすこと自体に価値がある。プロジェクトにかかわる人全員で、本当に必要な機能は何か、不要な機能は何かを見極め、プロセスの改善をしていかに「楽」をしてより高い価値を生み出せるかをディスカッションする必要がある。

見極める手順。

  1. 重要な1つだけピックアップする

    10個のうち1~3個しかやらないことは決して悪でない。そのほうが「バリュー」として効果的である。

  2. 時間を固定して、できることを最大化する

    何でも「すべき」というマインドだと、どうしても時間をだらだらと延長しがち。時間は固定して、その中で価値を最大化するとよい。たくさん課題があっても時間の中で最大限バリューが出るように「今日はこの2つだけやろう」。時間が最大の制約なので、時間内に確実にできる数に絞って、最大の成果を出せるのに集中する。

  3. 準備・持ち帰りをやめてその場で解決する

    会議の場だけで簡潔する。ざっくりしたアジェンダはあるが準備に時間をかけて会議に臨まない。必要な意思決定は極力その場で行う。会議に出たら「会議の時間内だけで完結」するように訓練すると生産的。

  4. 物理的にやることを減らす

    マネージャが簡単にスコープから外す。みんなが絶対的に重要なタスクにフォーカスできるように気を配っている。物理的にできないものは頑張ってもできない。自分の仕事の中で「何をやらないか」を決めていく。計画が正しいとは限らない。仕事はどれだけやったかではなく、どれだけ会社にインパクトを与える仕事ができたかのほうが重要。

リスクや間違いを快く受け入れる。日本と欧米で大きく異なる部分。

本番環境をお客さんとハックして改善する「ハックフェスト」。お客さんのもっとも難しい問題を解いてこいと言われる。世の中にどこにも情報が落ちてないような問題解決に取り組むことが評価される。

失敗を受け入れる実践法。

  1. フィードバックを歓迎するムードをつくる
  2. 検討をやめて検証する。大量の資料を要求したり書類の精度を期待するより、時間をかけずさっさと検証の段階に進み、フィードバックを得る。機能を検討する暇があったら、実際に実装してベータテストで顧客に試してさっとデータを取る。検討よりも検証を、という考え方はソフトウェア開発にとどまらずあらゆる分野に応用可能である
  3. 早く失敗できるように考える。開発の現場ではフィードバックが遅いのは致命的になる

不確実性を受け入れる。精密な結果の予測を要求しない、変更に柔軟、変化していく。計画どおりにいかないことは失敗ではないし、計画通りでなければならない必要もない。スピーディに軌道修正をかけていける柔軟性のほうが重要。第一歩として「納期は絶対」の神話は捨てる。日本人は納期に厳格すぎて無理をする傾向にあるが、それに見合った価値はない。

Q(品質)、C(コスト)、D(納期)、S(スコープ)はトレードオフの関係にある。進捗の「実績」だけで状況判断し、「納期」を固定したまま「スコープ」を出し入れする。納期通りにすべての予定された機能をリリースしているソフトウェアジャイアントはいない。リリース予定日が近づくとしれっと特定の機能が削除されていることは多い。アメリカでは納期が近くなっても無理して機能を完成させず、品質の良いものを作るようにしよう、となる。プログラマの生活や健康を犠牲にしてまで取り組むことは中長期的に疲弊して生産性が低下するため、マネジメント的に効率が悪い。

無理はしないほうがよい。チームの適正な生産量を超えた量を一定期間で達成した結果、組織の問題を覆い隠すことにつながる。「今回できたのだから、次回もこれぐらいできるよね」と、無理が積み重なる悪循環に陥る。チームのリソースを超えているときは現実を見て「物量を減らし、より大きな価値を生み出す工夫」が必要。いかにやらないことを見つけるかが重要。

先に実装しておき一部のユーザに使ってもらって、実際に動き価値もあると判断してからスイッチして本当の公開をする、ということもできる。

不確実性を受け入れるためにできること。

  1. 楽に達成できる計画で仕事をする。プラス何日か余裕のあるスケジュールを設定する。日本ではなるはやで、とか依頼されることが多い。海外ではそういった火急の依頼はマネジメント能力の欠如とみなされる。価値は状況によって変わる。物量をこなすのが生産性が高いわけではない。生み出すものの価値にフォーカスする
  2. 無理・断る練習をする。鏡の法則というのがある。自分に適用しているルールを無意識に他人に適用してしまう。納期厳守で仕事をしていると他人にもそれを求める傾向がある。無理を承知でのお願いの連鎖はみんなの疲弊を生み、チームや組織の業務改善につながらない。個人として無理をしてプロジェクトの帳尻を合わせてしまうことが実は問題点を先送りにし、チームとしてのパフォーマンスを下げる可能性がある
  3. 他の文化の視点を学んで見る

計画の変更は悪ではない。現実を見て、フィードバックを受けて納期や仕様が変わっていくのはむしろ「善」である。

日本では一度決めた納期を守り通し必死にやる。目標が達成できなかったときは失敗とされる。一度目標が定められると予測が誤っていても必ずやりきらないといけない対象になる。インターナショナルチームでは目標達成に無理があると判明した場合はもっとも優先順位の高い最初の1ステップのみを目指すように方向転換する。定時以降の仕事や休日出勤でカバーする流れにならない。できないものはできないと判断する。KPIは無理なく楽に達成できる程度のものであるべきという大前提がある。

定時でできる量になるよう作業量を今の実力でできる範囲内に調整する。目標はあくまで目標で、実際どうだったか、改善ポイントやベストプラクティスを尋ねられる。

より少ない時間で価値を最大化できている集団ほど、会社内ですべきことが少ない。日本ではKPIのような評価基準に加えて、社会人や社員として「こうあるべき」が非常に多い。反省や改善点が非常に多く、過大な要求が現場を追い詰め無限の労働へと駆り立てている。そんな期待に応えようとするのは無理。

コードリーディングのコツは極力読まないこと。実装は極力見ないようにして、インターフェイスと構造を理解する。

自分にとって難しすぎると感じる2つのケース。

  1. 自分の基礎的な学力が足りてない。積み上げるしかない
  2. 自分が無理なやり方をしているケース。努力や才能が足りないからこんなに大変と思い込んでいる。自分にとって難しすぎると感じるときはたいてい脳の使い方が間違っている。才能の差ではなく脳に余裕のない状態で酷使している可能性が高い

仕事の難易度レベル。

  1. 何もググらずに即座に実装できる
  2. 問題をどう解決するかは思い浮かぶが、具体的な方法は忘れているのでググる必要がある
  3. 自分は解法を知らないが、スパイクソリューションをしたらできそうなもの
  4. 自分だけでは解決が難しい、ものすごく時間がかかるもの

生産性とは、1を増やすことではないか。コードリーディングが遅い根本的な原因は、コードを見たときにどういう挙動をするか明確にイメージできないか、もしくは構造の把握が下手だから。レベル1のものが増えると脳の負担は激減する。重要なことは、自分がしんどいと感じる「努力」は一切やめてしまうこと。

自分が楽に取り組める難易度の低いもので練習すべき。レベル1の課題はもっともコントロール感がある。自分が何も見ずにさくさくコーディングできるものを増やしていく。

「アウトカム」至上主義が上達を阻害する。AIに書いてもらったりコピペすれば見かけのアウトカムは上がるが、中身を理解していないからコントロールできてる感はない。都度調べることになり応用が効かない。作業ばかりが続くので自分が知らないことや新しいことのキャッチアップなどもできない。成長しない。技術を徹底的に理解し、理解した情報の整理をして、すぐに取り出せるレベル1の情報にしてこそ、長い目で見たさいの生産性は上がる。

優先順位の高い仕事に対して、それだけに集中する時間を意識的に作り出す必要がある。毎日4時間をブロックして、Teamsやメールを一切閉じて、自分の作業だけをやる。

メンタルモデルを脳内に作成するためには、単にやって終わりではなく、細かいところまで自分で「ハンドル」できるレベルまで理解して整理する必要がある。

人間が記憶するために有効な方法は、シンプルに思い出そうとする頑張ること。ノートを取りながら学ぶのではなく、自分が学んだことを後から思い出しながら要点を書くのがポイント。

頭の中のみで整理する。みんな高等で済ませようとする。準備やレジュメもないままどんどん進んでそこで決定する。

後で人に説明することを意識するだけでも、相当集中力や記憶力が向上する。話を聞きナきながらビジュアルのイメージを作ったりメンタルモデルを脳の中で視覚化したりして自分の理解を確認する。

日本でのコミュニケーションはすべての情報を整理して送ってあげると喜ばれたが、アメリカではたくさん情報があっても盛りだくさんすぎてわかりにくいと受け止められる。最初から全部説明せず、「情報量を減らす」コミュニケーションの仕方が重要であった。リアルタイムに理解できる適切な情報量が好まれる。

日本人は持ち帰って考える癖がある。

自分にその分野のメンタルモデルやコンテキストがなければ、すぐさまエキスパートに聞いたほうがよい。相手が忙しいかどうかは考える必要がない。

ディスカッションはどちらが正しいかはどうでもいい。自分の考えを自分なりに深めるための行為なので、初心者こそやったほうがいい。間違えたら恥ずかしいという感覚は一切捨てる。

  • 「生産性を上げるためには学習。仕事を定時くらいで切り上げて、その後で自分のやりたいトピックを勉強したり試したりする」仕事ばかりしていては短期的なアウトプットは上がったように見えても根本的な生産性が上がらない
  • 長時間労働はサステナブルではない

時短を試みても切りのいいところまでやろうと考えて、結局寝る直前までかかることが頻繁にあった。タイムボックス制をした。例えば17時になったら仕事が途中でもどんなに切りが悪くてもすぐに仕事をやめる。いつのまにか時間が過ぎてしまわぬよう、5時きっかりにアラームをセットして。

関連