エピローグ — 面接官の視点
本番当日の朝
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軸
「この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軸と失敗パターンを学んだ。面接はコラボレーションだ。
学習ロードマップ
面接準備チェックリスト
本番面接に臨む前に、以下を確認しよう。
フレームワーク
- 4ステップ(要件確認→概算→設計→深掘り)を暗記した
- 問題を聞いてから最低5分は要件確認に使えるか
- 要件確認で聞くべき項目をリストアップしている
規模の概算
- DAU・QPS・ストレージの変換計算をすぐにできる
- 1秒、1日、1ヶ月の時間変換(86400秒、30日)を即答できる
- 概算の根拠を数字で説明できる
技術知識
- キャッシュ(Redis)の使い所と限界を説明できる
- メッセージキュー(Kafka/SQS)の使い所を説明できる
- CDNの仕組みとトレードオフを説明できる
- データベースの水平スケーリング(シャーディング)を説明できる
- CAP定理を具体例で説明できる
コミュニケーション
- 考えながら話す練習をした(沈黙ゼロを目標に)
- 設計を声に出して説明する練習を3回以上した
- 「知らない」と正直に言えるか
- 面接官の質問を最後まで聞いてから答えているか
模擬面接
- 友人または一人で音声録音しながら練習した
- 時間を計測して45分以内に設計を終えられた
- ホワイトボード(または紙)に書きながら説明した
読者へのメッセージ
ここまで読んでくれたあなたへ。
システム設計は、覚えるものではなく考えるものだ。
この本に書かれている設計パターンは、正解ではなく出発点だ。現実のプロジェクトでは、ここに書かれた設計が全く使えない状況もある。技術は変わり、要件は変わり、チームの文化も変わる。
だから大事なのは、特定の設計を覚えることよりも、どのように考えるかを身につけることだ。
要件を確認する。数字で考える。トレードオフを意識する。チームで対話する。
この4つの習慣は、面接が終わっても一生使える。コードレビューでも、設計会議でも、障害対応でも、プロダクトマネージャーとの議論でも。
エンジニアとしての成長に終わりはない。
この本で学んだフレームワークが、あなたの次の設計会議で、次の面接で、次の障害対応で、少しでも役に立てば嬉しい。
知識は持っているより、使っている方が価値がある。
そして使っているより、次の誰かに伝えている方が、もっと価値がある。
あなたが次の「レイカ」になる日を、楽しみにしている。