2025年1月14日
GMOインターネットグループ デベロッパーエキスパート
成瀬 允宣
2017年9月GMOインターネットグループ株式会社入社。テックリードとしてWebアプリケーションプロダクト開発に従事するほか、社内研修や小学校プログラミング教育に携わる。また技術広報としてカンファレンス等でソフトウェア開発・設計を主軸に講演活動を行う。著書『ドメイン駆動設計入門 ボトムアップでわかる!ドメイン駆動設計の基本』(翔泳社)。
エラーやバグ、パフォーマンス不良などの不具合が発生したときに、最後に必ず解決してくれるエース的な存在のエンジニアに助けられた経験のある人は多いのではないでしょうか。
GMOインターネットグループのnrsさんは、まさにそんなエースの一人。今では、大抵の不具合では早急に原因を特定し、解決に導けるようになったそう。「不具合の解決は経験がものを言う」と言いますが、nrsさんは、「経験の量だけでなく、試行錯誤の質に大きな違いがある」と語ります。
試行錯誤の質を高め、不具合を素早く解決できるようになるには、どんな要素が必要なのか? それらの要素がどのようにかみ合って、どんなスキルが身についていくのか。nrsさんに聞きました。
nrs:難しい質問ですね…。僕は、スキルでも経験量でもなく、「試行錯誤の質」だと思います。
不具合の解決が速い人は、不具合が起きるたびに、思い当たる節は全て試し、疑問に思ったことを見逃さず綿密に調べています。つまり試行錯誤の回数も、その過程で学ぶ知識の量も多い。物事を身につける原点である「学んで実行する」というサイクルを、高速に、密度高く回しているといえます。
1つの不具合から多くのことを学べれば、次の不具合のときに生かせることも増えますよね。だから実力が速くついていき、抜きんでた存在になっていくのだろうと思います。
nrs:共通して、「忍耐力」「好奇心」「素直さ」の3つのスタンスを持っているように思います。
「忍耐力」とは文字通り、泥臭く解決のプロセスを進められる粘り強さ。「好奇心」というのは、ちょっとしたシステム挙動の違和感から「どうしてこうなっているんだろう?」と興味を持って調べられる姿勢。「素直さ」は自分のやり方に固執しないで、周りの人の意見を受け入れて方針転換できる柔軟さを指しています。
これらのスタンスが重なり合うと、試行錯誤の質が格段に上がります。逆に、このスタンスが1つでも足りない人は、いくら場数を踏んでも伸びてこないなという印象です。
nrs:不具合の対応は「意図しない挙動」であるエラーやバグか、それともパフォーマンス不良かによって分かれます。ここでは前者の不具合が現れた際の行動と思考について考えてみましょう。
不具合が起きたときにやることをざっくりまとめると、「原因を特定して、解決策を試し、解決できたら報告」となりますね。先ほど話に出た「試行錯誤の質」は、原因の特定と、解決策を試すときに現れます。
まずは、原因を特定するとき。不具合が起きてから最初に行うのは、原因として思い当たる要素の絞り込みです。絞り込むために、まずは不具合が起きた前提条件を確認します。そのときには、不具合に関係がありそうな要素の目星をつけながら、関係がない要素をバッサリと切り捨てたうえで、思い当たる要素の「確からしさ」を判定していきます。
試行錯誤の質が高い人は、そうでない人に比べて広く深く情報を調べています。自分が専門性を持っている領域以外も含めたシステムの全体像から、そもそもソフトウェアというものの構造や構成要素なども掴もうとする。例えば、その人の役割が「バックエンドエンジニア」であっても、フロントエンドやインフラなど別領域に関するOSSのコードや公式ドキュメントまで見に行って、どういう仕組みで処理ができているのかを知ろうとするんです。他の誰かにアドバイスをもらったら、その助言の内容も調べ上げます。
これは、より確からしい原因を探すために思考を巡らせる「忍耐力」、気になることがたくさん生まれ、全て調べようとする「好奇心」、また、周囲の意見やアドバイスを吸収して生かす「素直さ」があるからこそできることです。
直接関係ないようなことまで深く広く調べたうえで原因を探し、その知識をもって「確からしさ」を判断していく。これが、原因特定の段階での「試行錯誤の質の高さ」といえるだろうと思います。こうしたプロセスを重ねているからこそ、原因の絞り込みも速くなり、正確さも高まります。
nrs:質の高い試行錯誤ができる人は、不具合の解決策を試す際に、絶対に諦めず、かつ他人のアドバイスをどんどん吸収してとにかく手を動かしています。
これも、先述の3つのスタンスが大きな影響を及ぼしています。
忍耐力があるから、思い当たる解決策を全て徹底的に試す。同環境を再現したうえでも検証するなど、手間も厭いません。そのため、1件の不具合あたりの「失敗」のパターンを大量に経験しています。
そして失敗するたびに「なぜ?」と好奇心をもって深く追いかける。このプロセスにより、解決策として持っている手札の数がどんどん増えていきます。
それと同時に素直さを持っていれば、様子を見たベテランが気を利かせて「こっちを調べた方がいいんじゃない?」などと助言をくれたとき、「そうか」と素直にそれに従って動き始める。素直だからこそ、見当違いのところでハマり続ける場合が多くなく、時間を無駄にしないで済みます。
nrs:「忍耐力」「好奇心」「素直さ」と聞くと当たり前のことのように思えますが、1つの事象から多くを学ぶためには、これらの相互作用が起こることが重要なんだと思います。
これらのスタンスをもって不具合対応の場数を踏み続けると、思いつく解決策の幅が広がり、面倒なバグの修正方法も把握できる。「これだ」と思った解決策が正解である確率も上がっていき、最終的には99%に近づいていく。これが「不具合対応がものすごくできる、センスの良い人」の正体なのだろうと思います。
もし「忍耐力」がなければ、不具合の解決どころか原因の特定もできませんし、「好奇心」がなければ、誰かに対処してもらって一件落着として、経験を学びに変えることができません。そして「素直さ」がなければ、見当外れだと助言をもらっても軌道修正できず、1件当たりにかかる時間がさらに長引いてしまうでしょう。
ちなみに、スタンスが足りなくても、経験の量で逆転できるようになるタイミングもありますよ。「忍耐力」は最も早く、重要性が下がります。経験の量と知識量、解決策の手札の数は比例しますから、それらを使って、少ない手間で対処できるようになっていきます。
nrs:たくさんの不具合を解決してきた人の多くは、2つのスキルを高いレベルで持っています。
1つは「言語化力」です。不具合を解決するためには、その解決策の妥当性を関係者に説明し、素早く理解してもらう必要があります。その際には、あまりシステムに詳しくない人にもわかるように、かつ有識者か鋭い質問がきても明確に回答できるように、言語化しなくてはいけません。
不具合に対処する経験を積むほど、説明や言語化の場数も踏むから言語化がうまくなっていきます。そうして信頼が重なると、次第に「あの人がこう言うなら大丈夫だろう」という空気になっていきますね。
もう1つは、システムの挙動やコードの違和感に気づく「観察力」です。観察力は、知識量が増えるにつれて鋭くなっていくものですが、不具合を解決した経験からも身についていきます。起きた不具合と、その根本的な原因や解決策が結びついていくことで、今まで素通りしていた異変に気づけるようになっていくのです。
nrs:普段の開発の中で少し意識するだけで、全然違うと思いますよ。
言語化力を身につけるには、自分がコードを書いたときに「どうしてこのコードにしたのだろう?」と自問自答してみてほしいです。言語化ができるかどうかは、理解できているか、知識があるか、というより「癖付け」だと僕は思っていて。自分の疑問を無視しないで言葉にする癖をつけるんです。
コードを書くときには、全て背景があって書いているはずです。「このコードはなぜこの行に書いたのか?」「この行じゃなきゃいけない理由、別の場所じゃダメな理由は?」「return の前に1行置いたのはなぜ?」と、「こう書いた理由」を言葉にしていく。この癖がつくと、問題が起きた時の原因と対策もすらすらと言えるようになっていきます。
逆説的ですが、言語化ができるようになると、バグの解決もうまくなるんですよ。言語化がうまくできないと、バグが出ても「うわ~バグっちゃった、どうしよう…」という言葉くらいしか出てきません。レビュー方法のひとつであるウォークスルーのように、目の前にあるコードを口頭で説明してみると、目で追っているだけでは気づけない破綻にも「あれ?おかしいな」と気づくことができます。起きていることを言葉にすると、不思議と穴を見つけられるんです。
僕が一番センスがないなと思うパターンは「よくわからないけどこれで動きました」。言語化ができていないし、するつもりもない。これでは成長が遅いですね。
nrs:「観察力」を鍛える方法としては、不具合ではないものの「なんかおかしいな?」と思ったときに、コードを見に行くようにするのがおすすめです。こういうときに時間が許す限り探ってみると、不具合よりも小さな異変に気づくトレーニングができます。
ひとつ例を挙げると、Reactでつくられた画面の開発者ツールを開いたときに、通信が2回走っていたことに違和感を覚えて、その原因を調べたことがあります。通信処理が発生するのはフロントなので、原因はフロントにある可能性が高い。でも、2回同じコードを書いているのならそう気づくはずなので、ライブラリに原因があるのではないか? そう考え、公式ドキュメントを確認しました。するとそのような仕様があることがわかり、これに対応するコードを書く必要があることが明らかになりました。
通常と違った動作に気づくことができれば、その原因と対処法を探ることで観察力も高まり、疑似的に「不具合発生→解決」のプロセスを経験することもできます。
また、システムだけではなく、周囲の人を観察するのもよいでしょう。
nrs:コードにはそれを書く人の思考の癖や、コードを書いたときの状況が否応なく現れるもの。その特徴を掴めるよう観察しておくのです。
コードは、人が何かを解決したくて書くものだから、書いた人の考え方が随所に漏れ出ています。チームで決まっている方針に従ってどうまとめているかは、書く人次第。
最も特徴を掴みやすいのが、ファイルをどこに置くか。理想とされるやり方がたくさんあります。例えば、種類の同じようなファイルは同じフォルダに入れておきましょうとか、オブジェクトクラスは1つのフォルダに入れておきましょうとか。これらのうち、どんなやり方を選んでいるのか。またそれらをどういうパッケージにまとめているのか。僕はコードを読むとき、こうした癖を観察しています。
書く人の癖を掴み、「この人はこんなコードを書く」ということを知っていれば、その人が不具合に対応しているときに、詰まっているであろう箇所の検討がつくようになります。また、不具合発生時にも、コードの癖から原因を特定することもできるようになるでしょう。
nrs:実際の不具合の際に「2時間ルール」を設けるといいですよ。これは作業の遅れが発生しないようにするためでもありますが、3つのスタンスのうち足りないものを補うのにも役立ちます。
タイムリミットを設けると、「2時間で解決しなくては」と、集中して不具合に向き合うことができます。忍耐力に自信のない人でも、時間を区切ることで「この2時間だけ本気でやろう」と気持ちを切り替えやすくなる。さらに、時間を無駄にできないと強く意識するからこそ、普段よりも違和感に気づきやすくなったり、周囲の助言も素直に受け入れやすくなるでしょう。
対応を始める前に、ベテランに見守ってもらえるよう声をかけるのもいいですよ。調査を任されたら、とりあえずパッと見て「ここが怪しい気がするので、調べようと思います」とだけ伝える。するとベテランも気にかけてくれて、詰まったときにアドバイスをくれたり、対応が終わった後にさらに深い知識を教えてくれたりするものです。
精一杯やっても2時間で解決できず、エスカレーションすることになっても「結局どうやって直したのか」を吸収できれば経験は積めるし、次回に繋がっていきます。解決してくれた人に「どうやったんですか?」と教えてもらうと、さらに学びが深まるでしょう。
nrs:「いつも助けてくれてすごいなあ」と思うエンジニアにも、うまくできない時間は当然あったことでしょう。逆に、たとえ今、不具合にうまく対処できなくても、「忍耐力」「好奇心」「素直さ」の3つのスタンスを持って、目の前の不具合に全力で向き合っていければ、彼らに近づくことはできるはずです。
極論ですが、僕は「バグだろうと何だろうと、人が書いたものは読める」と思っています。人がつくったものなら、必要な知識を吸収できていさえすれば、全て理解できるはず。そう信じてきたから、ここまでやってこれたんだと思います。今日話したことが、頼られるエンジニアになるためのヒントになっていたら嬉しいなと思いますね。
取材:光松瞳、瀬尾光希
執筆:一本麻衣
編集:光松瞳
撮影:赤松洋太
関連記事
人気記事