ソフトウェア開発の最重要スキルとは?グーグルのエンジニアに聞く
2022年2月2日(水)
いえ、私がプログラミングに初めて触れたのは、大学1年の時なんですね。情報系の学部ではなかったものの、必修科目でプログラミングの授業があったので、そこから勉強し始めました。
自分でプログラムを書いて、初めて「Hello, world!」した(※1)のもこの頃。当時はソフトウェアエンジニアという仕事があることすら分かっていませんでした。
※1:プログラミング初心者が、文字列を表示させる最もシンプルな構文として学ぶテスト文言。画面に「Hello, world!」と表示させるのが一般的。
純粋に「コンピュータで何かを作るのは楽しい」と思ったからです。
プログラミングスキルを学び始めて3カ月くらいがたち、授業で自由課題を出すことになった時は、簡単なゲームを企画して徹夜で開発したりしていました。
if文(※2)のような簡単な構文を使ってみて、「こうやって動くのか」と発見するだけでも、楽しかったのを覚えています。
※2:プログラミングで使う構文の一つで、「もし○○だった場合は××する」という条件分岐を指定する際に使う。
そうこうしているうちに、コンピュータプログラムを習得すれば何でもできそうだという感覚を持つようになり、どんどん開発にハマっていきました。
勉強がてら、友だち同士で使うチャットツールみたいなものを自作したり、海外の有名大学がコンピュータサイエンスの授業で使う論文を読みあさったり。
オープンソースで一般公開されているOS(オペレーション・システム)のソースコードなども、自然と読み込むようになっていました。
ええ。例えば優れたプログラマーが書いたソースコードをのぞき見すると、普通は何十行とコードを書かなければ動かないものを、数行で動くようにしているんですね。
アルゴリズムに関する論文でも、有名なものを読むと「こんなに賢い問題解決の方法を考え付く人がいるんだ」と驚くわけです。
私も、そういう感動を生み出す側の人間になれたらいいな、という思いは常にありました。
なので、大学を出た後は大学院に進み、コンピュータシステムの研究者をしていた時期もあります。
ただ、実際に仕事をしてみると、実験や計測のためだけにプログラムを書く日々をつらく感じるようになり......。
もともと自分や周りの人が使えるものを作るのが好きだったこともあって、ユーザーや顧客企業が見えるソフトウェア開発の仕事に転職することにしました。
技術はものすごい速さで進化していますし、今は開発作業をサポートしてくれる便利なフレームワーク(※3)もたくさんあります。
※3:ソフトウェア開発でよく使う機能や定型コードを、ライブラリとしてまとめたもの。
ですから私の昔話をしても、参考になるかは分かりません。
ただ、学生時代に勉強して、今でも役に立っていると感じるのは、開発の基本となる仕組みについてです。
OS、ネットワーク、アルゴリズム、グラフ理論などの基礎的な理論について、原理を体系的に学んでおくと、新しい技術が出てきた時にも応用問題のように対応することができます。
ほとんどの技術が、過去の技術の発展形として進化していくものだからです。
例えば、私が大学時代に読んだ本で、今でもたまに内容を思い出すことがあるのは、『分散システム―原理とパラダイム』(ピアソンエデュケーション)。
著者のアンドリュー・タネンバウムは、分散コンピューティングの基礎理論を築き上げた人物で、これは今でいうクラウド技術のベースにもなっています。
また、「アルゴリズムとデータ構造」という名の書籍がたくさん出ていますが、この辺の本を何冊か読んで学んだ知識も役に立っていると感じます。
プログラミング言語にもはやり廃りがあるので、主流の言語とは違うタイプの言語を学んでおくといいかもしれません。
私の場合は、大学の授業で読んだ「ML」という関数型言語の教科書がそれに当たります。MLは歴史が古く、今はOCamlと呼ばれる“方言”のほうが有名になっていますが、今でも読んで良かったなと思うことがあります。
最初から全てを知っておく必要はないですし、私自身、研究者やエンジニアになってから学び直した部分も多いです。
テクノロジーは、振り子のように「ゆり戻し」を繰り返しながら進化していく。この認識を持って、できる範囲を少しずつ広げながら勉強し続けるのがいいと思います。
歴史を知れば、現代社会の動向もある程度理解できるようになるのと同じ感覚です。
加えて、数学と英語は勉強しておくと大体いつでも役に立ちます。
最新技術を学ぶ時は、英語の文献を読むことも多いので。エンジニアとして成長していく上で、基礎的な力になります。
入社直後は、YouTubeの開発に携わっていました。
その後、2009年末くらいからGoogle Chromeの基盤を作るオープンソースプロジェクト「Chromium(クロミウム)」にかかわり始めて、昨年10月までずっとChrome関連のプロジェクトをやっていました。今は、Googleのソフトウェア基盤に携わる新しいチームにいます。
Chromeチームで最初に担当したのは、ソフトウェアの挙動を点検するテストコードを書く仕事でしたが、その後いろいろなAPI(※4)の開発を担当するようになりました。
※4:Application Programming Interfaceの略で、あるソフトウェアを他のソフトウェアと容易に連携させるための「窓口」となる機能のこと。
今ではChrome以外のWebブラウザでも使われている「Service Workers」というAPIを開発した頃から、チームの指揮を執る仕事もやるようになりました。
チーム開発という観点で話すと、分からないことがあったらどんどん質問するのが大切です。
これは、私がマネージャーになったくらいの頃から、新しいメンバーが来るたびに繰り返し伝えてきたことでもあります。
2008年にリリースされたChromeは、改善と進化を重ねながら、今まで90回以上のメジャーアップデートを行ってきました。
コードの行数は膨大で、全てを把握している人は1人もいないと言えるほど複雑なシステムになっています。
多くのエンジニアが毎日コードを変えているので、ある時期に把握していた仕様が、後日見たら大きく変わっていたということも日常茶飯事です。
だから、分からないことがあったら、今、一番詳しい人に聞くしかない。「自分で調べて」と言っても、無理があるんです。
カジュアルに質問するスキルは、ソフトウェアエンジニアとして働く上でけっこう大事だと思っています。意外とできない人が多いからです。
私自身、若い頃は「自分で調べて問題解決できる人が優秀だ」と思い込んでいました。実際のところ、開発現場では自分で調べる姿勢も強く求められます。
ただし、調べるのに何時間もかけるくらいなら、分かる人に聞いたほうが前に進めます。それに、異なるチームに入った時は、そのチームのやり方を知る努力も必要です。
プログラムや開発の進め方に関して、「分からないことを伝える」ほうが円滑に進む場合があるのです。
そう思います。それに、質問して確認するという行為は、チームを助けることにもつながるんです。
誰かが「このプログラムはなぜこういう仕様になっているのか?」と質問した時、チームリーダーを含めて周囲の仲間が答えられないというシチュエーションはよくあります。
その際、質問した人が詳しい人にあたって、ヒアリングしたことをドキュメントにまとめてくれたり、疑問点を議論して新しい発見があったとしたら、他のメンバーが調べる時間を節約できます。その結果、より良くする方法が見つかるかもしれませんよね?
「分からない」と意思表示したことが、チームの学びを加速するのです。
Googleには、いつ頃からか「15分ルール」という不文律があって、
・問題に突き当たった時、最初の15分は自分で解決を試みる
・15分たっても解決しなかったら他人に聞く
という仕事の進め方が浸透しています。
なので、質問される側も面倒がらずに対応してくれる。こういう心理的安全性があるというのを伝える意味でも、「困ったら質問して」と口酸っぱく言うようにしています。
個人的にソフトウェアエンジニアとして一皮むけたかなと思っているのは、コードを書いて問題解決をする時間と、それ以外の方法で問題解決のやり方を考える時間を明確に分けるようになったことですかね。
この時間を意識して切り分けないと、人は得意なことしかしなくなるものです。
ソフトウェアエンジニアで言えば、バグ(※5)を直したり新しい機能を作る時、今までやったことのある方法を使ったり、手元ですぐにやれる作業に終始してしまいしがちです。
※5:プログラムの誤りや欠陥を表す用語で、「バグ(Bug)=悪さをする虫」という意味で使われる。
特に私は、コードを書いて動かすのが楽しくてこの仕事に就いたのもあって、プログラミングに没頭してしまう癖があって。
でも、本来は「人が解決できないことを解決する」のがソフトウェアエンジニアの役割だと思うんですね。
そしてその解決策は、目の前にあるコードを触っているだけでは見つからない場合もある。
だから、仕事の「How」を突き詰めるだけでなく、思考の殻を破って「What」や「Why」から考え直す時間を取るのが大切だと気付きました。
具体的には、今日はこの問題について考えよう、来週はあの課題を解決するために最新の論文に目を通してみようなどと、1時間単位でカレンダーに予定を入れるようにしています。
大抵は、他の仕事が押したりして予定通りにいきませんが、カレンダーに「◯◯の意味を考え直す」などとメモしておくだけでも効果があります。
分かりやすい理由があったわけではありません。上司からのアドバイスや、何となく仕事に手詰まり感を抱くようになって、徐々に今のワークスタイルになっていきました。
しいて転機を挙げるなら、リードするチームや問題のサイズが大きくなり出した頃からですね。
Chromeに限らず巨大で複雑なプロダクトになると、ある新機能を入れることで性能が損なわれたり、シンプルさを失ってしまう懸念が常に付きまといます。
性能、安定性、セキュリティー、コードや設計のシンプルさなど、大きなソフトウェアの開発で大事な原則を維持したまま製品を進化させるのは想像以上に難しい。
そんな状況だと、一度は開発方針を決めて作り始めたものでも、途中で「このままコードを書き続けていいのか」「もっと良いアルゴリズムがあるんじゃないか」などと考え直すことが必要になるんです。
自分だけでなく、チームに対しても、意識的に全体最適の視点を広めるのが重要でした。みんなが何となくこれでいいと思っている事柄に、あえて「なんでこうしているんでしたっけ?」と投げかけるというか。
私だけでなく全員がお互いに質問し合う習慣を持つように意識していました。
そうですね。なので、言い方には気を付けるようにしています。
あるやり方を提案したメンバーに対して、「えっ、これ、どういうこと?」と質問したら、少しトゲがあるように感じてしまうかもしれません。
例えば「今の設計だと小さな問題解決に局所化し過ぎているかもしれないから、もう一回みんなで考え直してみない?」などと、全員が自分ごととして捉えられるように問いかけます。
また、議論した後には「議論してくれてありがとう」と感謝を口にするようにしています。結局、元のやり方で良かったということも多いですし、本当にありがたいと思っているので(笑)。
Googleには、職場でのコミュニケーションを円滑にするための「コミュニティ ガイドライン」があるんですね。
このガイドラインは、
責任を持つ:自分が何を話し、何を行うかに注意を払う必要があります。自分の言動には責任を持ってください。説明責任は自分にあります。
貢献する:発言はそのまま貢献につながります。建設的な発言を心がけましょう。
思慮深く発言する:自分の意図とは関係なく、発言したことは Google の発言と捉えられる可能性があります。発言にあたっては慎重に考慮し、他の人々に誤った思い込みを抱かせないようにする必要があります。
という3つの価値観を基に作られていて(上記は原文ママ)、誰もが疎外感を持つことなく働けるように配慮するようにと言われています。
かつ、このガイドラインには、自分1人では思いつかないことも、対話を通じてみんなで思いつけるようになろうという思想も込められているんです。
そうかもしれません。
私自身は、今は縦軸の専門性を身に付けようとか、次は横軸を広げようと意識して仕事をしてきませんでした。
ただ、ソフトウェアエンジニアは「ローンチ&イテレート(Launch&Iterate)」と呼ばれる仕事習慣を日常的に求められる仕事です。
プロダクトを素早く公開して、仮説検証のサイクルも素早く回しながら改善を繰り返すという意味です。
その過程では、縦軸を深める機会も、横軸を広げる機会もたくさんあります。この繰り返しの頻度と精度を高めるきっかけが、チーム開発の中にあるというのは間違いありません。
そういう意味では、個人の成長と、共に働くチームの質には相関関係があるということかもしれませんね。
合わせて読む:ゼロから学べる「数学とプログラミング」の話
取材・文:伊藤健吾、編集:佐藤留美、デザイン:黒田早希、撮影:安田絹子(本人提供)