システム設計面接入門から習得まで:5ステップ解法と6つの古典的問題

技術面接著者: BeautyResume チーム

システム設計面接の5ステップ解法をマスターし、URL短縮からメッセージプッシュまで6つの古典的システム設計問題を分解。アーキテクチャ図のアプローチと面接官の採点基準を付属。

システム設計面接は何を評価しているのか?

技術面接において、システム設計ラウンドはジュニアエンジニアとシニアエンジニアを分ける分水嶺です。コーディング問題とは異なり、システム設計面接に標準解答はありません。面接官が見たいのは、曖昧な要件から実現可能なアーキテクチャをどう導き出すかです。

システム設計面接が真に評価するのは4つの次元:要件分析力、アーキテクチャのトレードオフ力、スケーラビリティ思考、コミュニケーション力。多くの候補者はすぐにアーキテクチャ図を描き始めますが、面接官が最も重視するのは「なぜそのように設計したのか」という推論プロセスです。

本記事では、アーキテクチャ面接で最も高頻度の6つの問題タイプを5ステップ解法とともに分解し、要件から解決策までの完全な思考チェーンを構築します。

5ステップ解法:要件分析→高レベル設計→詳細設計→スケーラビリティ→まとめ

どんなシステム設計問題に遭遇しても、以下の5ステップで構造的にアプローチできます:

  1. 要件分析:面接官と機能要件と非機能要件を確認。機能要件は「システムが何をするか」、非機能要件は「どの規模に耐えるか、レイテンシはどの程度か、可用性はどの程度か」。このステップに少なくとも3-5分は費やし、急いで図を描かないこと。
  2. 高レベル設計:システムのコアコンポーネントとデータフローを描画。通常、クライアント、APIゲートウェイ、アプリケーションサービス、データベース、キャッシュなどを含む。各コンポーネントの詳細に深入りする必要はなく、全体アーキテクチャの合理性を示すことに集中。
  3. 詳細設計:1-2個のコアコンポーネントを選んで深入り。データモデル設計、API設計、主要アルゴリズムの選択、ストレージ方案などを含む。面接官は通常、特定の方向に深入りするよう誘導するので、そのペースに従う。
  4. スケーラビリティ分析:ユーザー数が10倍、100倍に増えた時、システムがどう拡張するかを議論。水平スケーリング、シャーディング、キャッシュ戦略、非同期処理などが含まれる。最も差がつく环节。
  5. まとめ:1-2分で設計決定を振り返り、トレードオフを説明し、改善方向を指摘。大局観と自己省察力を示す。

この5ステップ解法をマスターすれば、どんなシステム設計面接にも対応する汎用フレームワークが手に入ります。次に、6つの古典的問題で実践練習しましょう。

問題1:URL短縮システム

要件分析

URL短縮はシステム設計面接で最も古典的な入門問題です。コア機能:長いURLを与えられて短いURLを生成し、短いURLにアクセスした際に長いURLにリダイレクトする。

  • 機能要件:長URL→短URLマッピングの生成、短URL→長URLリダイレクト、カスタム短縮リンク(オプション)、リンク有効期限(オプション)
  • 非機能要件:日次1億回の読み書き、リダイレクトレイテンシ<100ms、可用性99.9%、短縮リンク長はできるだけ短く

高レベル設計

コアコンポーネント:APIサービス(長URL生成リクエストと短URLアクセスリクエストを受信)、IDジェネレータ(一意の短縮IDを生成)、データベース(長短URLマッピングを保存)、キャッシュ(ホット短縮リンクをキャッシュし、リダイレクトを高速化)。

データフロー:ユーザーが長URLを送信 → APIサービスがIDジェネレータを呼び出して一意IDを取得 → IDをBase62短縮リンクにエンコード → データベースに保存 → 短縮リンクを返却。短縮リンクアクセス時:短縮リンクを解析してIDを取得 → キャッシュを確認 → ミスならデータベースを検索 → 301/302で長URLにリダイレクト。

詳細設計

ID生成がコアの難所で、3つの選択肢があります:

  • 自動増分ID+Base62エンコード:シンプルで信頼性が高いが、短縮リンクが列挙可能。セキュリティ要件が高くないシナリオに適する。
  • 事前生成IDプール:独立したサービスが一意IDのバッチを事前生成してプールに入れ、APIサービスがプールから取得。自動増分IDの予測可能性問題を回避するが、システムの複雑さが増す。
  • MD5/SHA1ハッシュ+先頭N文字取得:集中型ID生成が不要だが、衝突リスクがある。通常、先頭6-7文字のBase62文字を取得すれば、衝突確率は極めて低い。

リダイレクトに301か302か?301は恒久リダイレクトで、ブラウザがキャッシュするためサーバー負荷を軽減するがクリック統計ができない。302は一時リダイレクトで、毎回サーバーを経由するためクリック数を統計できる。ほとんどの短縮サービスは302を選択。

スケーラビリティ分析

データベースシャーディング:短縮IDのハッシュ値でシャーディングし、水平スケーリングをサポート。ホット短縮リンクのキャッシュ:Redisで上位20%の人気短縮リンクをキャッシュし、ヒット率80%以上を達成。グローバル展開:CDNでリダイレクトを高速化し、複数のデータセンターにAPIサービスを展開。

問題2:メッセージプッシュシステム

要件分析

メッセージプッシュシステムはアーキテクチャ面接の高頻度問題で、リアルタイム通信と大規模接続管理能力を評価します。

  • 機能要件:個別プッシュ、グループプッシュ、ブロードキャスト、メッセージ既読/未読ステータス、オフラインメッセージプッシュをサポート
  • 非機能要件:同時接続1000万、メッセージレイテンシ<500ms、メッセージ損失なし、メッセージ順序保証

高レベル設計

コアコンポーネント:接続管理サービス(ユーザーの長接続を維持)、メッセージルーティングサービス(メッセージをターゲットユーザーの接続ノードにルーティング)、メッセージストレージ(メッセージを永続化)、プッシュゲートウェイ(APNs/FCMなどのサードパーティプッシュチャネルと連携)。

詳細設計

長接続の選択肢:

  • WebSocket:全二重通信、最も低いレイテンシ、高頻度メッセージングに適する。サーバーは大量の接続状態を維持する必要がある。
  • Server-Sent Events(SSE):サーバーからの一方向プッシュ、実装がシンプルで、サーバープッシュのみが必要なシナリオに適する。
  • ロングポーリング:最も高い互換性だが、レイテンシが高く、リアルタイム性の要件が高くないシナリオに適する。

メッセージルーティングの重要な問題:ユーザーAがユーザーBにメッセージを送る時、ユーザーBがどのノードに接続しているかをどう知るか?方法1:一貫性ハッシュでユーザーを固定ノードにマッピングし、ルーティングテーブルを検索。方法2:Pub/Subパターンを使用し、メッセージをチャネルに公開し、そのチャネルを購読しているノードが受信。

オフラインメッセージ処理:ユーザーがオフラインの時、メッセージをデータベースに保存。ユーザーがオンラインになった後、オフラインメッセージを取得してプッシュ。重要:オフラインメッセージの順序保証と重複排除。

スケーラビリティ分析

単一サーバーのWebSocket接続数には限界があり(通常10-50万)、1000万接続には20-100台の接続サーバーが必要。接続ルーティングテーブルで各ユーザーの現在の接続ノードを記録し、メッセージルーティング時にルーティングテーブルを先に確認してから転送。接続サーバーをステートレス化し、ルーティングテーブルで水平スケーリングを実現。

技術面接のシステム設計ラウンドの準備では、多くの候補者が技術の深さに集中し、履歴書のプロジェクト経験の提示方法をおろそかにしがちです。優れた技術履歴書は、アーキテクチャ設計経験と技術的決定力を明確に示すべきです——当社の履歴書ツールを使えば、アーキテクチャ能力を際立たせたプロフェッショナルな履歴書を素早く生成でき、システム設計ラウンドの前から面接官の信頼を構築できます。

問題3:ニュースフィード

要件分析

ニュースフィードはシステム設計面接で実際のビジネスに最も近い問題で、ソーシャル製品のコア機能に対する理解を評価します。

  • 機能要件:投稿の公開、フォロー中のユーザーの投稿閲覧、いいね/コメント、タイムラインを時系列逆順で表示
  • 非機能要件:1億ユーザー、日次1億投稿、フィード読み込みレイテンシ<200ms、フォロワー数1〜1000万の幅をサポート

高レベル設計

コアコンポーネント:公開サービス(投稿を書き込み)、フィード生成サービス(ユーザーのタイムラインを組み立て)、ソーシャルグラフサービス(フォロー関係を管理)、コンテンツストレージ(投稿内容を保存)。

詳細設計

フィードの2つのコアモデル——この問題の魂:

  • プッシュモデル(Fan-out on write):ユーザーが投稿を公開する時、すべてのフォロワーのフィードリストに書き込む。利点:フィード読み取り時O(1)で直接取得。欠点:インフルエンサーが投稿する時、書き込み量が膨大(100万フォロワー=100万回書き込み)。
  • プルモデル(Fan-out on read):ユーザーがフィードを読む時、フォロー中のユーザーから最新の投稿をリアルタイムで取得してマージソート。利点:書き込みが軽量。欠点:複数ユーザーをクエリする必要があり、レイテンシが高い。
  • プッシュ・プルハイブリッド:一般ユーザーにはプッシュモデル、インフルエンサーにはプルモデルを使用。これが業界の実際のソリューションで、読み書き性能のバランスを取る。

データモデル設計:投稿テーブル(投稿ID、著者ID、内容、タイムスタンプ)、フォロー関係テーブル(フォロワーID、フォロー先ID)、フィードテーブル(ユーザーID、投稿ID、タイムスタンプ)。フィードテーブルはプッシュモデルのコアで、各ユーザーの受信箱を維持。

スケーラビリティ分析

フィードテーブルは書き込みホットスポット。RedisのListまたはSorted Setで各ユーザーのフィードを保存し、O(1)挿入とページネーション読み取りをサポート。投稿内容はデータベースで永続化し、フィードテーブルはキャッシュで高速化。ソーシャルグラフはグラフデータベース(Neo4jなど)またはリレーショナルデータベース+キャッシュを使用。ページネーション:オフセットページネーションではなくカーソルページネーションを使用し、ディープページネーションの性能問題を回避。

問題4:フラッシュセールシステム

要件分析

フラッシュセールシステムはシステム設計問題で最も圧力の高いシナリオで、高並発下での在庫控除と売り越し防止能力を評価します。

  • 機能要件:商品フラッシュセール、在庫控除、注文作成、決済
  • 非機能要件:ピークQPS 10万+、絶対に売り越しなし、フラッシュセール結果レイテンシ<1秒、ボット・転売屋対策

高レベル設計

コアコンポーネント:フラッシュセールAPIゲートウェイ(レート制限+認証)、在庫サービス(在庫を控除)、注文サービス(非同期で注文を作成)、メッセージキュー(ピークカット)、決済サービス(決済を処理)。

詳細設計

売り越し防止がコアの難所で、3つのアプローチがあります:

  • データベース楽観ロック:UPDATE stock SET count=count-1 WHERE id=? AND count>0。シンプルだがデータベースへの負荷が大きく、QPS上限は約5000。
  • Redis原子控除:RedisのDECRコマンドで在庫を原子的に控除し、在庫が0になったら拒否。QPSは10万+に達するが、Redisとデータベースの整合性処理が必要。
  • 分散ロック+事前控除:フラッシュセール開始前に在庫をRedisにロードし、Luaスクリプトで原子性を保証。控除成功後、非同期で注文を作成し、最終的にデータベースに同期。

ピークカット戦略:ユーザーリクエストがまずメッセージキューに入り、バックエンドサービスが処理能力に応じて消費。これにより、10万QPSが瞬間に殺到しても、バックエンドは自分のペースで処理でき、圧倒されるのを防ぐ。

ボット対策戦略:CAPTCHA + IPレート制限 + ユーザーレベルレート制限 + クイズ認証。コアの考え方:ボットのコストを利益より高くする。

スケーラビリティ分析

フラッシュセールシステムのボトルネックは在庫控除。Redis単一ノードのDECRは10万QPSに達する。より高いスループットが必要な場合、商品IDで複数のRedisノードにシャーディング。注文作成を非同期化すれば、データベースはもうボトルネックにならない。フラッシュセール終了後、非同期タスクがRedisの在庫をデータベースに同期。

問題5:検索エンジン

要件分析

検索エンジンはシステム設計面接で最も複雑な問題の一つで、転置インデックス、ランキングアルゴリズム、分散ストレージ能力を評価します。

  • 機能要件:ウェブクロール、インデックス構築、キーワード検索、検索結果ランキング、検索サジェスト
  • 非機能要件:100億ウェブページのインデックス、検索レイテンシ<200ms、日次10億クエリ、日次インデックス更新

高レベル設計

コアコンポーネント:クローラーサービス(ウェブページを取得)、インデックスサービス(転置インデックスを構築)、クエリサービス(検索リクエストを処理)、ランキングサービス(結果をランク付け)、キャッシュ層(人気クエリ結果をキャッシュ)。

詳細設計

転置インデックスは検索エンジンの礎:正転インデックスは「文書→単語」のマッピング、転置インデックスは「単語→文書リスト」のマッピング。検索時、クエリ語を転置インデックスで検索し、積集合を取ってマッチング文書を取得し、関連性でソート。

ランキングアルゴリズム:

  • TF-IDF:単語頻度-逆文書頻度。単語の文書に対する重要度を測定。シンプルだが、単語の位置や意味を考慮しない。
  • PageRank:ウェブページ間のリンク関係に基づいてページの重要度を計算。Google初期のコアアルゴリズム。
  • 機械学習ランキング:クリック率や滞在時間などのユーザー行動特徴でモデルを訓練し、動的にランク付け。現代の検索エンジンの主流アプローチ。

インデックスシャーディング:100億ウェブページの転置インデックスは単一マシンに収まらない。文書IDのハッシュで複数ノードにシャーディング。クエリ時は全シャードを並列検索し、結果をマージしてソートして返却。これがMapReduceの考え方。

スケーラビリティ分析

インデックス更新戦略:フルインデックスは毎日1回再構築、増分インデックスはリアルタイム更新。クエリサービスはステートレスで水平スケーリング可能。人気クエリ結果のキャッシュヒット率は30-50%に達し、バックエンドの負荷を大幅に軽減。検索サジェストはTrie木またはプレフィックスマッチングを使用し、メイン検索サービスから独立。

問題6:分散キャッシュ

要件分析

分散キャッシュはアーキテクチャ面接のインフラ問題で、キャッシュ整合性、退去ポリシー、分散システムの理解を評価します。

  • 機能要件:KV読み書き、TTLサポート、退去ポリシーサポート、クラスタモードサポート
  • 非機能要件:読み書きレイテンシ<1ms、QPS 100万+、可用性99.99%、データの最終整合性

高レベル設計

コアコンポーネント:クライアント(リクエストを正しいノードにルーティング)、キャッシュノードクラスタ(KVデータを保存)、設定センター(ノードリストとルーティング情報を管理)、監視サービス(ヒット率とノード健全性を監視)。

詳細設計

データシャーディング戦略:

  • 一貫性ハッシュ:keyとノードをハッシュリングにマッピングし、時計回りに最も近いノードを見つける。ノードの追加・削除時に隣接ノードのデータ移行のみ影響。業界の主流アプローチ。
  • 仮想ノード:一貫性ハッシュのデータ偏り問題を解決。各物理ノードが複数の仮想ノードに対応し、データ分布をより均一にする。
  • レンジシャーディング:keyの範囲でシャーディング。範囲クエリシナリオに適するが、ホットスポットが発生する可能性。

キャッシュ退去ポリシー:

  • LRU(最も長く使われていないもの):最も長くアクセスされていないデータを退去。実装はシンプルだが、偶発的アクセスに弱い。
  • LFU(最も使用頻度が低いもの):アクセス頻度が最も低いデータを退去。ビジネスシナリオに適しているが、頻度カウンターの維持コストが高い。
  • Redisの実際のアプローチ:近似LRU — ランダムに複数のkeyをサンプリングし、最も長くアクセスされていないものを退去。性能と精度のバランスを取る。

キャッシュ整合性:Cache-Asideパターンが最も一般的なアプローチ — 読み取りリクエストはまずキャッシュを確認し、ミスならデータベースをクエリしてキャッシュに書き込み。書き込みリクエストはデータベースを先に更新し、その後キャッシュを削除。なぜ更新ではなく削除か?キャッシュの更新は並発問題を引き起こす可能性があるため、削除の方が安全。

スケーラビリティ分析

キャッシュペネトレーション:存在しないkeyのクエリがデータベースに直撃。対策:ブルームフィルターで遮断+空値をキャッシュ。キャッシュアバランシェ:大量のkeyが同時に期限切れになり、リクエストがデータベースを圧倒。対策:有効期限にランダムオフセットを追加+多段キャッシュ。キャッシュスタンピード:ホットkeyの期限切れ瞬間に大量のリクエストがデータベースに殺到。対策:ミューテックスロック+ホットkeyを期限切れなしに設定。

システム設計面接の4つのボーナステクニック

  1. 先に図を描いてから話す:システム設計面接では、アーキテクチャ図はテキスト説明より直感的。図を描きながら説明し、面接官に思考プロセスを追わせる。最初から細部に入らず、大局から出発する。
  2. 自発的にトレードオフを議論:すべての設計決定には長所と短所がある。「Aを選ぶ利点はX、代償はY、現在のシナリオではXがより重要だからAを選ぶ」と自発的に述べる。アーキテクチャのトレードオフ能力を示すことで、理由のないソリューションよりはるかに評価される。
  3. 数字で語る:「多くのユーザー」ではなく「DAU 1000万」と言う。「高並発」ではなく「ピークQPS 10万」と言う。設計を定量化し、規模への感度を示す。
  4. 自発的に改善方向を提案:設計完了後、「時間があればX方向も検討する」と自発的に述べる。大局観と継続的改善意識を示し、面接官に「十分」で止まらない人物と印象づける。

よくある質問(FAQ)

システム設計面接で図を描く必要はありますか?

はい。アーキテクチャ図はシステム設計面接のコア表現方法です。面接プラットフォームがホワイトボードをサポートしていれば必ず使用し、電話面接の場合はテキストでコンポーネントとデータフローを説明。図は美しい必要はありませんが、コンポーネントの関係とデータフローは明確でなければなりません

実際のアーキテクチャ経験がない場合、どうすればいいですか?

システム設計面接は実際の分散システムを構築した経験を求めていません。重要なのは分析プロセスと推論能力を示すこと。要件から出発して段階的に推論すれば、最終ソリューションが最適でなくても、推論プロセスが合理的であれば面接官は認めます。「Designing Data-Intensive Applications」とオープンソースプロジェクトの設計ドキュメントを読むことをお勧めします。

システム設計面接で時間が足りない場合はどうすればいいですか?

45分のシステム設計面接では、時間管理が完璧なソリューションより重要です。要件分析5分、高レベル設計10分、詳細設計15分、スケーラビリティ10分、まとめ5分。あるセクションで行き詰まったら、「この部分はまず暫定ソリューションを出し、時間があれば深掘りする」と自発的に述べ、前進を続ける。

面接官が詳細を追及し続けるのはどういう意味ですか?

通常2つの理由:あなたのソリューションに欠陥があり、発見と修正を促しているか、特定の方向に興味があり、深さを見たいか。どちらの場合も、慌てずにその方向に深入りする。本当に分からない場合は、「この分野の経験は限られていますが、私の理解では…」と正直に言うのが、でたらめを言うよりはるかに良い。

レベルによってシステム設計面試の要件は違いますか?

はい。ジュニアエンジニアは要件分析と基本コンポーネント設計に重点、ミドルエンジニアは詳細設計とトレードオフ分析に重点、シニアエンジニアはスケーラビリティ、整合性、フォールトトレランス設計に重点、アーキテクトレベルはグローバルアーキテクチャと技術選定に重点。目標レベルに応じて回答の深さを調整。

技術面接のシステム設計ラウンドは、技術の深さだけでなく、複雑な問題を構造的に分解する能力も評価します。優れた技術履歴書も同じ構造化された提示が必要です——当社の履歴書ジェネレーターを使って、アーキテクチャ設計経験と技術的決定を履歴書に明確に提示し、システム設計ラウンドの前から面接官の目を引きましょう。

#技術面接#システム設計#Architecture Interview#面接準備