ugo's 読書感想文

読んだ本のまとめや学んだことを書いていきます。

世界一流エンジニアの思考法

概要

マイクロソフト勤務の著者が、働く中での気づきや、 周りのエンジニアから学んだことを、自身の考えを絡めてまとめている。

自身の経験として、エンジニアに向いていなかった過去から、それ以前の経験を活かし、どのように適用していき 一流との差や、一流と一緒に働くことに対して、どういうアプローチを取ったのかというのを紹介している。

特別なことは確かにやっていないのだが、自身の行いを確実なものとして認識して 間違ったやり方ではなかったと認識するには体系的に理解するのにいいかもしれない。

最近の日本の企業としても働き方はかなり変わっていて、本書に出てくるような働き方ができるような企業も増えてきているので これから、自身の働き方をどう自分で調整していくか、自分の動き方をどうしていくかということに悩んでいる方には指標になるのではないだろうか。

各章の大枠

各章に書かれている大事だと思った箇所や、参考になりそうだと思った箇所を記述していく。

生産性

仮説を証明する

どんな一流のエンジニアでも、やり方さえ間違えなければ自分でも同じことが可能である。

例えば、慣れていない場合、クエリに間違いが発生してる時など、いろいろと手を動かして試してみようとするが 一流エンジニアとなると最初のログをじっくり読んだ後に仮説を立ててから行動をする。

つまり、最初に推測したものを実証するようにクエリを投げるようにするようにするのである。

そうすれば、複数回クエリを投げずとも、結果にたどり着くことが早いのである。

十分な理解を持って手を動かす

一流のエンジニアは、特別頭がいいと言うわけではなく、ちゃんと理解してから手を動かすということをする。

学習用のビデオを見る時も、10回見て、分からないところはポーズをしてメモをするなどを取る。

どんな人でも理解に時間がかかることはあるので、それ相応の努力をしていることになる。

そして、手を動かすのは最後になる。

無駄に手を動かして、試行錯誤するのではなく、仕組みを理解してからの方が時短に繋がる。

理解とはどうなることか

  • 構造を掴んで人に説明できること
  • いつでもどこでも即座に取り出して使えること
  • 知見を踏まえて応用がきくこと

コードの話でいえば、コードの意図とその背後のアーキテクチャを理解することを優先する。

言えば当たり前のことだが、これが基礎となる。 基礎は誰にでも分かるが、習得には時間がかかる。

この基礎を学ぶには、著者がやったことは

  • 定時後や週末にプログラミングの基礎を学ぶ
  • 言語の仕様を理解する
  • LeetCodeなどの問題を毎日解く

などである。

大事なのは、基礎を簡単だと馬鹿にせず、1からやり直しをするということだ。

ドキュメントを残す

ドキュメントを書くには以下のメリットがある。

  • ドキュメントを書くことで自分の頭が整理される。抜け落ちていた視点に気づくことができる
  • 考えてる時のことをドキュメントにすることで、それをシェアするだけで済むようになる。あとでドキュメントとしてまとめるというのは退屈な仕事になる。

自分が良いソフトウェアを書く上で、理解して効率よく開発するために書くということを理解しておこう。

メンタルモデル

多くのことを同時に把握するには、メンタルモデルを作れるようになることが重要である。

メンタルモデルとは、人々が世界を理解し、予測し、解釈し、新しい状況に適用するための、自己の心の中のイメージや理論。

ここではシステム思考というフレームワークを頭にインプットする。

ソフトウェアのアーキテクチャ、クラスの構造、ソフトウェアのどういったパーツがどこにあるか、システム全体を先に把握する。

それから、全体の関係図、フローをビジュアル図としてイメージし、各パートの関係性をあてはめていく思考法。

そういった図を頭の中に持つことで、障害が出た時や、話の焦点となるものがクリアになり、どこに何の話があったか紐付けがしやすくなるというもの。

構築の手順としては、エキスパートに頼るというもの。2時間以上詰まったら即座に聞くなどをする。

大事な感覚

自分が仕事をコントロールしているという感覚。

どんなことも、基礎を固め、分からないことなどをしっかり助言を頂くことで仕事をコントロールすることができる。

それを自分で感じ取ることができるようになることが重要。

Be Lazyというマインドセット

より少ない時間で価値を最大化するという考え方。

  • 結果達成のために、最小限の努力をする
  • 不必要なことをやらない
  • 簡潔さを目指す
  • 優先順位をつける
  • 時間や努力ではなく、アウトプットと生産性に重点を置く
  • 長時間労働しない
  • 会議を時間内で完結し、価値を提供する

これらは当たり前に見えるが、落とし穴がある。

このために大事なことは

「最初の1個をピックアップしてやったら他はやらない」

ということ

その一つにフォーカスをあてる。

一つのことを確実にやるということが大事。

なぜなら、ソフトウェアのうちで本当に大事で使われる機能は40%くらいという統計がある。

それに対して100%を注ぐことは無駄とは言わないまでも価値が最大化できていないと言うことに繋がる。

この、Be Lazyというのはやらなくていいことはやらないというマインドのこと。 そうすることでやることを減らすというマインドのことである。

また、会議の中で結論を作るということも大事。 持ち帰って検討することは極力せず、会議の時間内で完結することは生産的である。

失敗のリスクを取る

失敗や間違いを受け入れることを行う。

具体的には

  • 間違いを厳しく批判したりしない
  • 失敗から学ぶ
  • 早く失敗する
  • 実験が推奨
  • 現状維持や標準を要求せず、臨機応変が推奨される
  • 避難や恐怖感のない環境

人間である以上、失敗はつきものなので、早く失敗をして早くフィードバックを得て、早く間違いを修正していくの精神が大事になる。

検討ばかりをして、さっさとやらないことの方がリスクになってしまうということを肝に銘じておく必要がある。

例えば、さっと作れるならプロトタイプを作ってしまってから話し合いをし、フィードバックをもらう方が断然早いし、話がスムーズに進むというようなものだ。

アーキテクチャやツールが数種類あって悩む場合もあるだろうが、結論的にはなんでも良いとなる。 圧倒的な差があれば悩む必要がないし、決めあぐねるくらいであれば大差がないのである。

さっさと間違えて、修正したものを出せば良いだけなのだ。

不確実性を受け入れる

変化に柔軟な対応が必要なソフトウェアにおいて、とくに必要とされるマインドになる。

具体的には

  • マネジメントは詳細までものを期待しない
  • 予算と報告のプロセスは精密な結果の予測を要求しない
  • 内部プロセスは計画や優先順位の変更に柔軟である。
  • 事前に全ての問題分析が完了せずとも、新しいことに挑戦する姿勢を持つ
  • システムとプロセスは柔軟で、複数の頻繁な変更を受け入れられる
  • 学びに基づいて、変化を精力的に行う

ここで気になるのは、納期になるだろう。

しかし、日米で納期に関しては意味が異なる。

日本では、納期までに予定された機能が全て搭載された製品を予定された品質で納品が必要となる。

アメリカでは、納期に厳しくなく、実際納期になった時にリリースされるものは予定より少ない量であることも多い。

納期に間に合わせるために徹夜する人なども少ない。

ソフトウェア開発において、納期通りというのはほとんどない。 多くの不確実性をはらんでいるからだ。

ではどうすればいいのか

進捗の実績だけで状況判断し、納期を固定したままスコープを出し入れするのが現実的である。

納期は守りつつ、間に合わないものはリリースに入れずに次に回すか、もしくはやめるのである。

中長期で見たときに、無理をして徹夜などで間に合わせても、エンジニアの体調が崩れてしまった方が生産性が下がるので、マネジメント的には効率が悪いからだ。

そして、無理して出来上がった実績は、後世に引き継がれてしまう可能性があるのだ。 つまり、前回これだけできたのだから、今回もこれくらいいけるよねというような形で無理が続いてしまう可能性があるのである。

守らなければいけない納期

しかし、そうは言っても、絶対に遅れてはならない納期というのもある。 法律的に関わるものであったり、オリンピックのようにその時に出ていないと意味が全くなくなるような納期である。

そう言うものに対しては、シンプルに早く進めるしかない。

すでに動いているものをリリースすると約束できれば良い。 例えば、フィーチャーフラグを使ってフラグの切り替えでリリースできるようにすることで公開とすることも可能であるのだ。

余裕のある計画を立てる

不確実性の高いソフトウェアにおいて、その人のできる日数を納期にするのではなく、プラス何日か余裕のあるスケジュールを設定する。

アメリカでは、「なるはやである」とか、「明日までに」というオーダーはマネジメント能力の欠如とみなされる。

生み出すものの量ではなく、価値にフォーカスをあてるマインドが大事になってくる。

コードリーディングにおける脳の負荷

以前書いた

ugo-ev.hatenablog.com

プログラマー脳と内容が重複する箇所が多かったので端折る。

ざっくりと以下のようなことである。

極力読まないようにする。

他の開発者を信じて、読まなくても挙動が分かる部分は動作だけ理解してコードは読まないなど

クラスの役割だけ把握し、インターフェースを理解することで、読む量を減らす。

重要なことは、「自分にとって難しすぎると感じる時は、大抵脳の使い方が間違っているサインである」

人に説明できるようにする

人は記憶力がいいものではない。

では、どうすれば記憶の中に留めておけるだろうか。

人に説明できるように理解すればいいだけの話である。

人に説明できるということは構造を整理して把握して、脳のメモリに乗せる必要があるということである。

また、先述したメンタルモデルをつくることも状況の細かいことを把握するコツになる。

そのため、単に「できた」で終わるのではなく、「説明が可能か」というところまでセルフチェックをした方が良い。

復習するタイミング

記憶しやすくなる復習のタイミングの習慣化というのを意識をする。

以下のタイミングが良い - 覚えた翌日 - そのさらに1週間後

意識の中に残せるようにするには、次の三つのファクターが重要になる。

  • 理解
  • 記憶
  • 反復

頭の中のみで整理する

ディスカッションをするにしても、頭の中にフレームワークがあるから理解できる。

頭の中でのみ物事を整理する訓練をしていけば、それができるようになる。

具体的には

  • ミーティングの議事をその場で書かない
  • 人の話を聞く時は、その後に誰かに説明することを想定して頭の中で整理しながら聞く
  • 頭の中で整理してから文章に書く

コミュニケーションにおける原則

エンジニアの人には、情報が少ない方が好まれる。 たくさん情報があっても消化できないという感覚による。

PRなどに大量に説明があっても、誰も読まないし、逆にスルーされることもよくある話。 もっと単純化する必要がある。

最初から全部説明せず、情報量を減らすコミュニケーションの仕方がすごく重要。

相手が求めているものへの感度

相手が何を欲しているかを理解して、自分用のメモを作る際にも共有できるような形で書いておく。

そうすることで、いつでもそのリンクを送るだけで良くなる。

見る人が欲しい情報はこれだろうという形で整理しておくべきである。

日頃から伝えることを前提としてメモなどの準備をしておくと、何か聞かれた際の工数削減にもなるのである。

他の人にシェアできる形式を意識して、文書を書くということに時間を惜しまずにすることで、将来の自分の工数削減になるのである。

環境

また、当書ではコミュニケーションの取りやすさという視点で

クイックコールと呼ばれる、簡易的な通話を行い、気軽にペアプロをしたり、一緒に考えたりしてもらうようなこともある。

もちろん、声のかけやすい環境というのを心がけることでクイックコールをしやすいという面もあれば、クイックコールされやすいということもある。

クイックコールをされる側としては、ちょっと手助けするだけでプロジェクトがスムーズに進むのでいいこともある。

なので、どんどんクイックコールをするようにしたり、そういうのが良い環境を作ることが重要になる。

チームビルディング

サーバントリーダーシップ

サーバントリーダーシップとは、リーダーはビジョンとKPIを示すが、実際にどう動くかはチームが主体的に考えて意思決定していく。

対して、コマンドアンドコントロールという管理体制では、マネージャーが部下に指示をする形になる。

サーバントリーダーシップのスタイルでは、現場のメンバーがかなりの権限を与えられて、どう実行するかを各自で考えているのである。

自己組織

自己組織チームとは、チームが自ら考えて自分で意思決定をするスタイルになる。

3つの特徴がある。

  1. 生産性が高い
  2. チームのエンゲージメント(満足度)が高い
  3. よりよいソリューションが選択されやすい

タスクの割り振りもチームが自らやっていく。

基本的にメンバー各自がやりたい仕事を「自分がやる」と選択している。

何が重要かというと、メンバーが楽しんでいるかが重要視される。

楽しい仕事でなければ、生産性は上がらないし、楽しい仕事であれば生産性は何倍も高くなるのである。

マネージャーの存在は仕事を楽しめているかを確認すること

マネージャーといっても、日本とアメリカでも全然違う。

日本では、進捗管理や課題管理を行なったりする。いわば、指揮をする人である。

アメリカでは、サーバントリーダーシップ制のもとでマネージャーが重視するのは、各メンバーのメンタル面になる。

マネージャーの一番の関心事は、メンバーがいかに幸せに働けているかになっている。

なので、随時「楽しめているか」を確認し、心地の良いムードを作ろうとしている。

そのため、マネージャーはメンバーに対して、困っている部分に対するアドバイスはするが、具体的にあれしろ、これしろなどと細かく指示することはない。

例として、1on1の時間では、共有したいことややってみたいことの相談のほか、悩みなどにアドバイスをくれるというものになる。 誰かを見習えなどの話はなく、メンバーの個性を手助けする姿勢がある。

納期に対する意識

日本だと、納期は絶対というイメージがある。

しかし、不測の事態は見通せないため、達成されないということも頻繁に生じる。

そのため、マネージャーは基本的に、一度仕事をプログラマに割り振ったら、あとはもう信頼するしかないのである。

逆に、そのプログラマが精一杯やっても遅れてしまったのなら、それがその時できるベストだったということである。

日本ではよく、技術者はどんな批判も受け入れ、まさかりを投げ合って成長するものというような雰囲気があるが、そんな辛い思いをしなくてもプロフェッショナルにはなれるのである。

基本的に、みんな自分が一番大切で、自分の幸せを第一に考えることを前提としているのである。

ミドル層

サーバントリーダーシップ方への転換で、一番抵抗が激しいのがこの層になる。

トップ層とは違い、新技術の導入や変革に対して、前向きになりにくい。 プロジェクトやサービスごとに数字を持っているので、自分の慣れていない方法で新しいことを始めるのに相当勇気がいるからだ。 彼らは慣れていないリーダーシップのやり方で発揮しなければならない。

しかし、しっかりトレーニングをすれば、過去のマネジメント経験も生きて、新しいサーバントリーダーが誕生しやすくなる。

生活術

ワークライフバランスについて

基本的に、働く人の裁量に任せられる。

日中はミーティングなどが多い時は、夜に集中してコーディングの時間を取るとかをする人もいる。

生産性を上げるには、定時上がりの方が効率が良かったりもする。

ただし、定時で上がったあとは自分の好きなトピックについて学習したりを行う。 そのように、学習をしなければ生産性は上がらないのである。

タイムボックス制を取り入れる

定時が来たら仕事が終わっていなくても強制的に切り上げるというような感じでタイムボックスを取り入れると良い。

そうすると頭がスッキリし、リフレッシュしたりする。

夜の時間は自分の趣味に回すことができるので、気持ち的にも余裕が持てるようになる。

そうしていくと生産性が上がるのである。

違うことをする

気分のリフレッシュに以下のようなことを頭に留めておくと良い。

  • 水泳をする時に息継ぎをせずに泳ぐことはできない。
  • 発送のブレークスルーは、その仕事をしていない時に発生する。
  • 1日に一つのことに集中できるのは4時間。
  • 何もしない休息ではなく、いつもと違うことをする。

幸せ

この本で一番好きな言葉がある。

「幸せを感じるから成功するのであって、成功したら幸せになるわけではない」

という言葉だ。

物事を整理するということを意識する。

例えば、ランニングに行ったら走ることだけで完了とするのではなく、帰って水分補給をしてシャワーを浴びて万端の状態になるまでを一連の所作として行う。

それが達成されては初めてランニングが完了するとした時の達成感によって、幸せを感じることができるのである。

まとめ

上記のほかにもいろいろと書かれていることはあったが、自分にとって重要だと思われるところだけを抜粋した。

AIに対しての考えであったり、ワークライフバランスや体の衰えに対する考えや実際の行動など

非常に参考になることが多く、プログラマーとしてやっていこうと思ってる人には一読の価値があるだろうと思った。

Microsoftで働かれてることもあり、Microsoft製品名を全面に出しているのは気になったが、内容には大きく影響の与えるものではないので、随時自分の使ってるツールなどに置き換えてもいいとは思う。

この本を読む直前に意外と自分の中での発見したことがあり、それが答え合わせのように書かれていたので、自分の感じたものは間違いではなかったのだと改めて確認できたのも良かったと思う。