mybook

エピローグ — 面接官の視点

本番当日の朝

11月初旬、まだ暗い朝6時。ソウタはネクタイを鏡に映しながら、指を止めた。

鏡の中の自分は、1ヶ月前より少しだけ違って見えた。目の奥が落ち着いている。表情が少し固い——けれど、あの時のような「何も持っていない」緊張とは種類が違う。

1ヶ月前の自分を思い出した。Twitterのタイムライン設計を問われ、頭が真っ白になったあの部屋。「データベースは……えっと……RDBSでいいですか?」と口走った瞬間の静寂。面接官が一瞬だけ眉を動かしたあの表情。

「後日ご連絡します」という定型句。翌日届いた不合格のメール。

今日は違う会社だ。しかし同じ種類の挑戦——規模の大きなサービスを運営するテック企業、シニアエンジニアポジションの最終面接。

スマートフォンが振動した。

「今日やね。ご飯ちゃんと食べた?」

レイカからのLINEだった。朝7時にメッセージを送ってくるとは思っていなかった。ソウタは少し笑いながら返信した。

「食べました。緊張してますけど、変な緊張じゃないです。なんか……準備できてる感じがします」

すぐに返信が来た。

「それが正解。緊張しない人間は信用できない。緊張してても動ける人間が強い。行ってらっしゃい」

ソウタはスマートフォンをポケットに入れ、玄関のドアを開けた。


面接会場へ

渋谷のオフィスビル15階。エレベーターを降りると、受付に30代前半くらいの女性が座っていた。

「本日は面接でいらっしゃいますか?」

「はい、14時に予約しております。田中ソウタと申します」

会議室に案内された。窓の外には渋谷の街並みが広がっている。ソウタは資料を鞄に入れたまま、水を一口飲んだ。

5分後、面接官が2名入ってきた。一人は40代と思われる男性で、穏やかな目をしていた。もう一人は女性で、タブレットを持っている。

「田中さん、よろしくお願いします。私はエンジニアリングマネージャーの山田です」と男性が言った。「こちらはシニアエンジニアの中村です。今日はシステム設計について、ざっくばらんに話しましょう」

「よろしくお願いします」ソウタは静かに頭を下げた。

雑談が5分ほど続き、山田が本題に入った。


本番面接の再現

「では、メインの設計問題をやりましょう」

山田がホワイトボードの前に立ち、マーカーを手にした。

動画共有プラットフォームのコア機能を設計してください。YouTubeのようなサービスをイメージしてもらえると助かります

ソウタの頭の中で、レイカの声が響いた。

「問題を聞いた瞬間に、絶対に設計を始めるな。まず要件を確認しろ。これを守れるかどうかで、最初の印象が決まる」

「ありがとうございます。設計を始める前に、いくつか確認させていただいてもよいでしょうか」

山田がうなずいた。「どうぞ」


要件確認フェーズ

「まず機能の範囲についてですが、今回フォーカスするのはアップロードと再生のコア機能でよいですか?コメント、おすすめ動画、検索は今回は後回しにしてよいでしょうか」

「はい、アップロードと再生にフォーカスしましょう」と山田。

「ありがとうございます。次にスケールについてですが、DAUはどれくらいを想定しますか?」

「1億DAUで考えてください」

「了解です。動画のアップロードとダウンロードの比率についてはいかがでしょう。読み取り重視(read-heavy)でしょうか?」

「そうですね、読み取りの方が圧倒的に多いです。YouTubeに近いイメージで、アップロード対再生は1:100くらいでしょうか」

「動画の品質は複数解像度対応(360p、720p、1080p)が必要ですか?」

「はい、自動的に複数解像度に変換してほしいです」

「了解しました。最後に、レイテンシについての要件を教えてください。動画の再生開始まで、どれくらいを目標にしますか?」

中村が初めて口を開いた。「3秒以内に再生が始まること、が理想ですね」

「わかりました。では整理しますと——DAU1億、アップロードと再生の比率1:100、複数解像度への自動変換、再生開始3秒以内、これをスコープとして設計を進めます。よいでしょうか」

「完璧です」山田がわずかに微笑んだ。


概算フェーズ

「では規模感を概算します」ソウタはホワイトボードに数字を書き始めた。

「DAU1億として、1日あたりの動画再生回数はユーザー一人が平均5本見るとすると5億再生。QPSに換算すると、5億÷86400秒≒約5800 QPS。ピーク時は3倍として約1万7000 QPSを想定します」

「アップロードについては、再生の100分の1なので1日500万回のアップロード。平均動画サイズを300MB(10分×30MB/分)とすると、1日あたりのストレージは5億MB、つまり500TB。年間で180PB程度のストレージが必要です」

「この規模を見ると、いくつかのことが見えてきます。まず、DBだけで5800QPSを処理するのは現実的でないため、キャッシュ層が必須です。次に、動画配信はオリジンサーバーから直接配信すると帯域が爆発するため、CDNを前提とした設計が必要です」

中村がメモを取っているのが視界の端に入った。


設計フェーズ

ソウタはホワイトボードに向かい、主要コンポーネントを書き出した。

「高レベル設計から始めます。大きく三つのフローがあります」

アップロードフローは、クライアントがAPIサーバーに動画ファイルを送信し、APIサーバーはS3のような分散ストレージに生の動画を保存します。保存後、メッセージキューにトランスコードジョブを投入します。トランスコードワーカーが非同期でジョブを取得し、360p・720p・1080pの3種類に変換してCDNのオリジンストレージに配置します。完了後、メタデータDBのステータスを更新します」

再生フローは、クライアントがビデオIDをAPIサーバーに渡すと、APIサーバーはメタデータDBから動画情報を取得し、各解像度のCDN URLをクライアントに返します。クライアントはCDNから直接ストリーミングを受信します」

メタデータ管理については、動画タイトル・説明・タグ・ステータスはRDB(RDS for MySQL)に保存します。動画ステータス(processing, ready, failed)をユーザーに通知するためにWebSocketまたはポーリングを使います」

「なるほど」山田が言った。「そのアーキテクチャで、どんな課題がありそうですか?」

ソウタは少し間を置いてから答えた。


ボトルネック指摘フェーズ

「まず指摘したいのはトランスコードのレイテンシです。1時間の動画を3解像度に変換すると、現在の設計では単純なキューの場合、処理完了まで数時間かかる可能性があります。これを改善するには、動画を小さなチャンクに分割して並列トランスコードする方式——セグメント並列化が有効です」

「もう一つは、急激なトラフィック増加への対応です。人気動画がバズった場合、CDNのエッジノードにキャッシュが乗っていれば問題ないですが、キャッシュが薄い場合にオリジンサーバーに負荷が集中します。この対策として、CDNのウォームアップ——人気になりそうな動画を事前に複数のエッジに配置する——が考えられます」

「もう少し深掘りさせてください」中村が身を乗り出した。「トランスコードのセグメント並列化を具体的に説明してもらえますか?」

「はい。元の動画ファイルを例えば5分ずつのチャンクに分割します。各チャンクを独立したワーカーに割り当てて並列処理します。全チャンクの変換が完了したら、HLS(HTTPライブストリーミング)形式でセグメントを結合し、マスタープレイリストを生成します。この方式なら、1時間の動画でも12のチャンクに分割して並列処理できるため、単純比較で処理時間を12分の1に短縮できます」

「それに伴うトレードオフは?」

「チャンク間のフレーム境界の整合性が課題です。動画コーデックによっては、チャンクの境界で映像が乱れることがあります。これを防ぐため、キーフレームを境界に合わせてチャンク分割するロジックが必要です。実装コストが上がりますが、ユーザー体験の向上を考えると投資価値はあります」

山田がうなずいた。「十分です。最後に一つだけ。今の設計で、あなたが最も心配しているポイントはどこですか?」

「メタデータDBのスケールです。動画数が増えるにつれて、検索クエリの負荷が高まります。今の設計ではRDB一本なので、将来的には検索専用のElasticsearchクラスターへの移行を考える必要があります。また、ユーザーの視聴履歴や視聴完了率のような時系列データは、RDBよりApache Cassandraのような幅広い列型ストアが適していると思います」

「ありがとうございました」山田が時計を見た。「時間ちょうどですね。お疲れ様でした」


面接後の廊下

エレベーターを待ちながら、ソウタは壁に背をもたせかけた。

「……できた」

声に出すと、少し恥ずかしかった。でも本当にそう感じていた。完璧ではない。チャンク境界の説明が少し雑だった気がする。Cassandraの選定理由をもっと丁寧に話すべきだったかもしれない。

でも——面接官と、ちゃんと対話できた。

要件を確認して、数字で考えて、ホワイトボードに書きながら思考を共有して。途中で詰まった瞬間も「少し考えます」とだけ言って10秒で再起動できた。

1ヶ月前とは別人だ、とソウタは思った。

エレベーターが来た。扉が閉まる直前、ソウタはスマートフォンを取り出してLINEを開いた。


レイカへの報告

「終わりました。設計問題は、動画プラットフォームでした。要件確認から入って、概算して、設計して、ボトルネック指摘まで一通りやれました。面接官とちゃんと会話できた気がします」

渋谷の街を歩きながら返信を待った。3分後に既読がついた。

「よかった。どんな設計したの?」

「アップロードはS3+メッセージキュー+トランスコードワーカー、配信はCDN前提の設計です。ボトルネックとしてトランスコードの遅延を指摘して、セグメント並列化の案を出しました」

「悪くない。面接官の反応は?」

「ちゃんと掘り下げてくれました。トランスコードのトレードオフを聞かれて、キーフレーム境界の話まで展開できました」

「上出来。ところでさ、面接官が実際に何を評価してるか知りたい?」

「それ、ぜひ聞きたいです」

「じゃあ今夜話そう。18時に渋谷のいつものカフェで」


面接官の本音

その夜、カフェの窓際の席でレイカはコーヒーを一口飲んでから話し始めた。

「私、Amazonにいた頃に100人以上の面接してたんだよね。その経験から言うと、面接官が採点してるのは大きく5つの軸」

レイカがノートを広げた。


評価の5軸

Loading diagram...

「この5軸を10点満点で採点する。合格ラインはシニアエンジニアなら全軸6点以上。完璧な設計は必要ない。5つ全部で6を超えれば合格」

「技術知識は、適切なコンポーネントを選べるか。問題分解力は、曖昧な問題を整理できるか。スケール感は、数字で根拠を語れるか。対話力は、思考を言葉にしながら面接官と一緒に考えられるか。現実的判断力は、トレードオフを見極めて現実的な選択ができるか」

「今日の俺で言うと、どうでしたか?」

「私が面接官だったら——技術知識7、問題分解力8、スケール感7、対話力8、現実的判断力7。トータルで平均7.4。余裕で合格ライン」

ソウタは少し照れて頭をかいた。


採点基準の詳細

「各軸の採点がどう決まるかも説明しておく」とレイカが続けた。

技術知識は、コンポーネントを知っているだけじゃ5点。なぜその選択をしたか理由を言えたら7点。選択の代替案とトレードオフを比較できたら9〜10点」

問題分解力は、確認なしに設計を始めたら2点。基本的な要件確認ができたら5点。重要な前提を自分から発見して、スコープを適切に絞れたら9〜10点」

スケール感は、数字が一切出てこなかったら2点。概算の数字を出せたら5点。計算しながら設計判断に結びつけられたら(『QPS1万7000なのでキャッシュが必須です』)9〜10点」

対話力は、一人で考えて沈黙したら2点。設計を説明できたら5点。考えながら話して、面接官の質問に自然に反応できたら9〜10点」

現実的判断力は、最初からマイクロサービス全盛りの設計を出してきたら3点。シンプルな設計から始めてトレードオフを明示できたら7点。ビジネス制約やチームのスキルセットまで考慮した判断ができたら9〜10点」

INFO

面接官は「完璧な答え」を求めていない。「一緒に働きたいか」を判断している。思考プロセスを共有し、不確かな点は正直に言い、面接官の意図を汲んで対話できる候補者が高評価につながる。技術的な知識の量より、その知識をどう使って問題に向き合うかの姿勢が重視される。


よくある失敗パターン5つ

「逆に、私が面接官として見てきた中で『残念だった』候補者のパターンも教えておく」

「聞きたいです。俺も絶対どこかに当てはまってた気がするので」

「正直に言うと、最初の練習でソウタは失敗パターン1と3に完全に当てはまってた」レイカが苦笑した。


失敗パターン1:要件確認なしに設計を始める

「Twitterを設計してください、と言った瞬間にデータベース設計を語り始める候補者がいる。評価は問題分解力2点。面接官は心の中で『この人、本番でも要件確認せずにコード書くんだろうな』と思う」

「1ヶ月前の俺ですね」ソウタが苦笑した。

「まさに。改善策は単純で、問題を聞いたら必ず5分間、要件確認の時間を使うことを自分のルールにする。この習慣だけで、評価が2点から7点に跳ね上がる」


失敗パターン2:数字なしの設計

「『スケールするためにキャッシュを入れます』とだけ言う候補者。なぜキャッシュが必要かを数字で語れない。面接官は『なぜ?』と心の中で思い続けてる」

「改善策は?」

「全ての設計判断を数字で根拠づける習慣をつける。『QPS換算で1万を超えるので、RDBだけでは捌けない。したがってRedisキャッシュが必要です』という流れ。数字があれば、設計の妥当性を面接官が判断できる」


失敗パターン3:沈黙する

「これが一番多い。『ちょっと考えます……(3分沈黙)……えーと……』を繰り返す候補者。面接官は拷問に遭ってる気分になる」

「最初の練習の俺ですね」ソウタが深くうなずいた。

「考えながら話すことが大事。完成した答えじゃなくて、考える途中を見せる。『〇〇の方向で考えています。まず〜を確認して、次に〜を検討しようとしています』と実況中継するだけでいい。これで評価が2点から7点になる」


失敗パターン4:過剰に複雑な設計

「最初から15個のマイクロサービスとKafkaクラスターとKubernetesを提案してくる候補者。面接官の頭の中は『この人、月1万PVのサービスに何してんの?』となってる」

「プラグマティズムが低い状態ですね」

「そう。改善策は、シンプルなモノリスから始めること。問題が見えてから複雑化する。面接官は『こうやって考えるんですね』という思考のプロセスを見たいのであって、複雑な設計そのものに価値はない」


失敗パターン5:一方的な説明

「面接官がヒントを出しているのに、自分のプレゼンを続ける候補者。面接官は『うん、でもさ……』と言いかけても遮られる。これはもう評価の問題ではなく、一緒に働きたくないレベルになる」

「気をつけます。面接はコラボレーション、ですね」

「そう。面接官の顔を見ながら話す。反応を見ながら方向を修正する。これは面接だけじゃなくて、実際の仕事でも同じスキルだから、練習する価値がある」

WARNING

間違った技術の話を自信満々に語ることが、最も評価を下げる失敗のひとつ。「その技術は詳しくないですが、〜の原則から考えると……」と正直に答える方が誠実で好印象。面接官は「知っているか」よりも「知らないことへの向き合い方」を見ている。


「知らない」と言う勇気

「レイカさんって、面接で『知らないです』って言ったことありますか?」

「あるよ。しかもシニアの最終面接で」

「え、それで合格したんですか?」

レイカはコーヒーカップを置いた。

「Amazonの面接でね、DynamoDBの内部のB-treeのリバランスのアルゴリズムを聞かれたことがあった。『実は詳細は把握していないですが、LSM-treeベースの実装のはずで、リバランスコストを下げるためのアーキテクチャの判断としては……』って答えたら、面接官に『それで十分です、実は私も全部は知らないです』って言われた」

「つまり、部分的な知識でも、それを論理的に展開できれば評価される」

「そういうこと。面接官だって全部知ってるわけじゃない。大事なのは、知っていることと知らないことを正確に区別できて、知らないことに対して論理的にアプローチできること。その姿勢を見てる」

INFO

「知らない」と言うことは弱さではなく、メタ認知能力の証明だ。自分の知識の境界を正確に把握しているエンジニアは、本番環境でも適切に動ける。根拠なく自信満々に語るエンジニアの方が、はるかに危険だと面接官は知っている。


合格連絡

面接から5日後の木曜日、午後3時過ぎにメールが届いた。

件名:「選考結果のご連絡」

ソウタは職場のデスクで一度深呼吸してからメールを開いた。

「このたびはご応募いただきありがとうございます。厳正な選考の結果、田中様を内定とさせていただくことになりました——」

最後まで読めなかった。

スマートフォンを取り出してレイカにLINEした。

「合格しました」

返信は10秒で来た。

「おめでとう。でも、これはスタートライン」

その6文字を、ソウタは何度も読み返した。


入社後のオンボーディング

3ヶ月後、ソウタはシニアエンジニアとして最初の設計レビューに参加していた。

チームの誰かが提案したのは、ユーザープロフィールAPIのリファクタリング設計だった。5個のマイクロサービスを新たに作成する提案だった。

ソウタは発言した。

「現状のトラフィックはどれくらいですか?」

「月間MAUは20万です」

「であれば、まずモノリスの中でモジュール分割して様子を見てから、サービス分割を検討した方がコスト効率が高いと思うんですが、いかがでしょう」

会議室が少し静かになった。チームリードが言った。

「それ、正しい指摘だね。じゃあまず計測してから判断しよう」

面接の練習が、本番の仕事につながった瞬間だった。


シニアエンジニアとしての設計の心得

入社半年後、ソウタはチームの新人エンジニアに設計レビューをすることになった。

「設計で一番大切なことって何ですか?」と新人に聞かれた。

ソウタは少し考えてから答えた。

なぜその選択をしたか、を自分の言葉で説明できること。設計そのものより、設計の理由の方が大事」

「なぜですか?」

「技術は変わる。でも、なぜその判断をしたかの思考プロセスは残る。チームメンバーがその判断を理解して初めて、同じ判断を次の設計に活かせる。ドキュメントに書かれた設計図よりも、その設計に込められた思考の方が価値がある」


次のキャリアステップ

1年後、ソウタはスタッフエンジニアへの道を意識し始めていた。

シニアエンジニアとスタッフエンジニアの違いを、レイカに聞いたことがあった。

「シニアは自分のプロジェクトの設計ができる。スタッフは複数チームの技術的な方向性に影響を与えられる。アーキテクトはシステム全体の設計思想を持っている」

「その差を埋めるには何が必要ですか?」

「技術的な幅と、ビジネスへの理解。設計の議論をエンジニアリングの言葉だけじゃなくて、ビジネスコストとビジネスインパクトの言葉でもできること。そして、正解を出すより良い問いを立てる力」

「良い問いを立てる力?」

「そう。『これどうやって実装するか』より『なぜこれを実装するのか』を先に問える人が、スタッフになれる」


ソウタとレイカの最後の会話

ある週末、レイカから珍しくLINEが来た。

「次の案件でシンガポールのオフィスに移る。3年くらいになると思う」

ソウタは数秒、画面を見つめた。

「急ですね」

「まあね。今まで色々付き合ってくれてありがとう。面接の練習から始まって、気づいたら随分長く話したね」

「俺の方こそ、ありがとうございました。1ヶ月前の俺には、あの練習がなかったら今の仕事はなかったと思います」

「そんなことない。私がいなくても、ソウタはどこかで気づいてたと思う。私はちょっとその時間を早めただけ」

「レイカさんらしいですね、その言い方」

しばらく間があった。

「ひとつだけ、伝えておく」とレイカが続けた。

「面接の練習でやってきたこと——要件を確認して、規模を概算して、トレードオフを考えて、相手と対話する——それ、面接だけじゃなくて仕事の全部に使えるから。コードレビューでも、設計会議でも、障害対応でも。知識は道具で、フレームワークは地図。地図を持ってれば、知らない道でも進める」

「はい。忘れません」

「じゃあね。シンガポールからたまに連絡するかも」

「待ってます。向こうでも面接練習相手が必要になったらいつでも」

返信は絵文字一つだった。


本書全体のまとめ

この1冊で、ソウタが歩んだ道のりを振り返ろう。

第1章:プロローグ 頭が真っ白になった面接から始まった。システム設計面接は「答え」ではなく「思考プロセス」が評価される——その原則を知ることが、全ての出発点だった。

第2章:4ステップフレームワーク 要件確認→概算→設計→深掘りの地図を手に入れた。どんな設計問題でも、この地図に沿えば迷子にならない。フレームワークは思考の補助輪だ。

第3章:規模の見積もり 数字で語る技術を習得した。DAU・QPS・ストレージの計算は、設計判断の根拠になる。数字なしの設計は、地図なしの航海だ。

第4章:URLショートナー設計 シンプルな問題でBase62エンコード、分散キー生成、リダイレクトキャッシュの基礎を学んだ。小さな設計問題こそ、基礎力が試される。

第5章:SNSタイムライン設計 プッシュ型とプル型のトレードオフを学んだ。ユーザー数によって最適な戦略が変わる。セレブリティ問題は現実のサービスでも起きる。

第6章:チャットシステム設計 WebSocketによるリアルタイム通信と、既読・未読の整合性管理を学んだ。1対1と1対多ではアーキテクチャが大きく変わる。

第7章:動画プラットフォーム設計 大容量ファイルの非同期トランスコードとCDN配信を学んだ。今日の面接の題材そのものだった。

第8章:検索エンジン設計 転置インデックスとランキングの仕組みを学んだ。クロールから検索結果の表示まで、複数のサブシステムが連携する大規模設計だ。

第9章:通知システム設計 信頼性のある非同期処理の設計を学んだ。メッセージキューによる冪等性の確保と、障害時のリトライ戦略が鍵になる。

第10章:レート制限設計 トークンバケット・スライディングウィンドウの仕組みを学んだ。分散環境でのカウンター共有には一貫性とパフォーマンスのトレードオフがある。

第11章:分散キャッシュ設計 一貫性ハッシュによるノード管理と、キャッシュ無効化の難しさを学んだ。「キャッシュを入れる」の一言の裏には、深い設計判断がある。

第12章:エピローグ(本章) 面接官の視点から、評価の5軸と失敗パターンを学んだ。面接はコラボレーションだ。


学習ロードマップ

Loading diagram...

面接準備チェックリスト

本番面接に臨む前に、以下を確認しよう。

フレームワーク

  • 4ステップ(要件確認→概算→設計→深掘り)を暗記した
  • 問題を聞いてから最低5分は要件確認に使えるか
  • 要件確認で聞くべき項目をリストアップしている

規模の概算

  • DAU・QPS・ストレージの変換計算をすぐにできる
  • 1秒、1日、1ヶ月の時間変換(86400秒、30日)を即答できる
  • 概算の根拠を数字で説明できる

技術知識

  • キャッシュ(Redis)の使い所と限界を説明できる
  • メッセージキュー(Kafka/SQS)の使い所を説明できる
  • CDNの仕組みとトレードオフを説明できる
  • データベースの水平スケーリング(シャーディング)を説明できる
  • CAP定理を具体例で説明できる

コミュニケーション

  • 考えながら話す練習をした(沈黙ゼロを目標に)
  • 設計を声に出して説明する練習を3回以上した
  • 「知らない」と正直に言えるか
  • 面接官の質問を最後まで聞いてから答えているか

模擬面接

  • 友人または一人で音声録音しながら練習した
  • 時間を計測して45分以内に設計を終えられた
  • ホワイトボード(または紙)に書きながら説明した

読者へのメッセージ

ここまで読んでくれたあなたへ。

システム設計は、覚えるものではなく考えるものだ。

この本に書かれている設計パターンは、正解ではなく出発点だ。現実のプロジェクトでは、ここに書かれた設計が全く使えない状況もある。技術は変わり、要件は変わり、チームの文化も変わる。

だから大事なのは、特定の設計を覚えることよりも、どのように考えるかを身につけることだ。

要件を確認する。数字で考える。トレードオフを意識する。チームで対話する。

この4つの習慣は、面接が終わっても一生使える。コードレビューでも、設計会議でも、障害対応でも、プロダクトマネージャーとの議論でも。

エンジニアとしての成長に終わりはない。

この本で学んだフレームワークが、あなたの次の設計会議で、次の面接で、次の障害対応で、少しでも役に立てば嬉しい。

知識は持っているより、使っている方が価値がある。

そして使っているより、次の誰かに伝えている方が、もっと価値がある。

あなたが次の「レイカ」になる日を、楽しみにしている。