本文へ移動

ホーム / Web / 第6部 面接の実践

第6部 面接の実践・第18章

設計・実技の面接

★★☆ 重要10トピック・面接 4問

Web エンジニアの設計面接は、インフラの細部より「アプリの側の判断」を深く聞かれます。お題ごとの回答例で、要件から構成、深掘りまでの流れを練習します。持ち帰り課題やライブコーディングの進め方もここで扱います。

ひとことで

「短縮 URL を設計して」のような問題に、要件の確認 → 見積もり → 構成 → 深掘りの順で答える。

システム設計面接では、あいまいなお題から、要件を整理し、構成を考え、トレードオフを説明する力が見られます。正解は1つではなく、考えの筋道と判断の理由が評価されます。

答え方の型:要件から始め、深掘りで差がつく① 要件を確かめる機能・規模・速さ② 規模を見積もる1秒あたりの数・データ量③ API とデータ表・インデックス④ 全体の構成図CDN・アプリ・DB・キャッシュ⑤ 深掘りボトルネック・整合性⑥ まとめ障害・監視・次の改善
システム設計面接の進め方

答え方の型

手順やること
1. 要件を確かめる(5分)機能(何ができればよいか)と、規模・速さ・可用性など。範囲を絞る質問をする
2. 規模の見積もり1日のユーザー数 → 1秒あたりのリクエスト数・データ量。読みと書きの比率
3. API とデータモデル主なエンドポイントと表。主キー・インデックス
4. 全体の構成図クライアント・CDN・ロードバランサー・アプリ・DB・キャッシュ・キュー・ストレージ
5. 深掘りボトルネックになる所(ホットなデータ・書き込みの集中・整合性)を選んで掘る
6. まとめ障害時の動き、監視、今回省いたこと・次に改善すること

Web エンジニアの面接では、インフラの細部より、API の形・DB の設計・キャッシュ・非同期処理・冪等性など、アプリの側の判断を深く聞かれることが多いです。黙って考え込まず、選択肢を挙げて「今回は○○を優先するので△△にします」と口に出しながら進めます。

SRE の「システム設計」の章

面接ではこう答える

システム設計面接では、あいまいなお題から要件を確かめ、規模を見積もり、API とデータモデル、全体の構成を描き、ボトルネックを深掘りし、最後に障害時の動きと監視でまとめます。正解は1つではなく、考えの筋道と判断の理由が評価されます。Web エンジニアの面接では、API の形、DB 設計、キャッシュ、非同期処理、冪等性など、アプリの側の判断を深く聞かれることが多いです。

分類質問の例
機能必須の機能は何か、今回は省いてよい機能は何か(例:タイムラインに広告や推薦は入れるか)
利用者と規模1日のアクティブユーザー数、ピークの時間帯、データの増え方
読みと書き読み取りと書き込みの比率、書いた直後に本人に見える必要があるか
一貫性少し古くてよいか(いいね数)、厳密に正しくないといけないか(在庫・残高)
速さ何ミリ秒で返したいか、画面のどこが一番速くないといけないか
クライアントWeb だけか、App もあるか(API の互換性・オフライン)
制約既存のシステム、チームの人数、予算、期限

質問は5分以内で切り上げ、決めた前提を「では、1日 100万人、読み取りが書き込みの 100倍、いいね数は数秒遅れてよい、で進めます」と口に出して確定させます。面接官が数字をくれないときは、自分で妥当な数字を置きます。

項目目安
1日の秒数約 86,400 秒(概算では 10万秒)
1日 100万リクエスト平均 約12 QPS。ピークは平均の 2〜5 倍で見積もる
1日 1億リクエスト平均 約1,200 QPS
1KB × 1億件約 100GB
同じデータセンター内の往復約 0.5ms
日本と米国の往復約 100〜150ms
Redis の1回の読み書き1ms 未満が目安
DB の1台インデックスの効く単純な読み取りなら数千 QPS 程度から。構成と中身で大きく変わるので「1台で足りるか」の桁の判断に使う

見積もりは桁が合えば十分です。目的は「DB 1台で足りるか」「キャッシュが要るか」「ストレージは何年分でどれくらいか」を判断することなので、計算の前提を口に出しながら、結果から設計の判断につなげます。

SRE の「見積もりで使う数字」

お題Web エンジニアとして話したい論点
短縮 URLID の生成、読み取り中心のキャッシュ、301 と 302、悪用対策
SNS のタイムライン書き込み時に配る(fan-out on write)か読むときに集める か、カーソルのページング
EC の在庫と注文同時購入での在庫の整合性、冪等キー、決済との連携(Saga)
チャットWebSocket、台数を増やしたときの配信、既読・順序、取りこぼしの取り直し
通知(メール・プッシュ)キュー、リトライとデッドレター、二重送信の防止、受信設定
画像のアップロード署名付き URL、非同期の変換、CDN、安全なファイルの扱い
レート制限数え方(固定窓・トークンバケット)、Redis での共有、429 と Retry-After
検索のサジェスト前方一致のインデックス、キャッシュ、入力ごとの通信を減らす(デバウンス)

どのお題も、ボトルネックになる1〜2か所(ホットなデータ・書き込みの集中・整合性)を自分から選んで深掘りすると、評価が上がります。

読み取りが書き込みの 100倍。キャッシュで受け止めるユーザー短縮 APIPOST /linksID の生成Base62・乱数DBcode → url作成ブラウザリダイレクトGET /{code} → 302Redis人気のリンク開くなければ DB から
短縮 URL のサービスの構成例
手順回答の要点
要件長い URL を短くし、アクセスで元の URL へ移動。作成は1日 100万件、読み取りは 100倍。期限・独自の短縮名は今回は省く
見積もり作成 約12 QPS、読み取り 約1,200 QPS(ピーク 5倍で 6,000)。1件 500B × 5年で 約1TB
APIPOST /links → {"code": "aZ3k9Q"}、GET /{code} → 302 と Location
データlinks(code PK, url, owner_id, created_at)。code で引くだけなので KVS でもよい
ID の生成連番を Base62 にする(7文字で 約3.5兆通り)か、ランダムにして衝突したら作り直す。連番は推測されるので、公開したくないなら乱数
深掘り読み取りは Redis でキャッシュ(人気のリンクに偏る)。計測したいなら 302、ブラウザにキャッシュさせて負荷を減らすなら 301
まとめ悪用対策(危険な URL の確認・作成のレート制限)、クリック数は非同期で集計
書くときに配るか、読むときに集めるか書き込み時に配る・投稿をフォロワーの箱へ・読むのが速い・フォロワーが多い人で重い読み込み時に集める・フォロー中の投稿を集める・書き込みが軽い・読むたびに重い組み合わせ・普通の人は配る・有名人だけ読むときに混ぜる・実際によく使われる
タイムラインの2つの作り方と、組み合わせ
手順回答の要点
要件フォローしている人の投稿を新しい順に表示。1日のアクティブ 1,000万人、読み取りが書き込みの 100倍。数秒の遅れは許す
APIGET /timeline?cursor=…&limit=20、POST /posts
データposts(id, user_id, body, created_at)、follows(follower_id, followee_id)、ユーザーごとのタイムライン(Redis のソート済みセットに投稿 ID)
配り方投稿したらキューに入れ、ワーカーがフォロワーのタイムラインに ID を足す。フォロワーが非常に多い人は配らず、読むときに混ぜる
ページング投稿 ID(時刻順)でカーソル。オフセットは使わない
深掘りタイムラインには ID だけを置き、本文はまとめて取る(キャッシュ)。削除・ブロックは読むときにも除く
まとめ配る処理が遅れたときの表示(数秒の遅れは許容)、ホットな投稿のキャッシュ
在庫は DB の条件付き更新で守り、決済の失敗は取り消す注文を受ける冪等キー在庫を確保qty > 0 で減らす決済外部にも冪等キー確定・通知Outbox でジョブ決済に失敗したら在庫を戻し、注文を取り消す(補償の処理)
注文の処理の流れ
論点回答の要点
二重販売UPDATE stocks SET qty = qty - 1 WHERE item_id = ? AND qty > 0。更新行が 0 なら売り切れ
二重注文・二重決済注文 API に冪等キー。決済サービスにも同じキーを渡す
カートの仮押さえカートに入れただけでは減らさない。決済の画面に進んだら期限付きで確保し、期限切れで戻す
アクセス集中(セール)人気の商品の行に更新が集中する。在庫を複数の行に分ける、待合室(キュー)で入場を絞る
決済との整合性「決済は成功したが応答が来ない」に備え、状態を持って後から照会する。失敗したら在庫を戻す
通知注文の確定と同じトランザクションで outbox に書き、メールはワーカーから

悲観ロック・楽観ロック・条件付き UPDATE

観点問われること使える知識
データの整合性同時に更新されたら?二重に送られたら?一意制約・条件付き UPDATE・冪等キー
読み取りの負荷10倍に増えたら?キャッシュ・CDN・レプリカ・ページング
書き込みの集中1つの行・キーに集中したら?分割・キュー・まとめて書く
遅い処理外部 API が遅い・落ちたら?キュー・タイムアウト・リトライ・サーキットブレーカー
API の互換性App が古いままなら?追加は安全・削除は手順を踏む・バージョン
障害と運用どこが落ちると何が止まる?何を監視する?SLO・エラー率・ロールバック・Feature Flag
セキュリティ他人のデータに届かない?悪用されない?認可・レート制限・入力の検証
動く最小を先に。改善は後から問題の確認入力・出力・境界方針を話す計算量も一言動く最小まず通すテスト境界の例改善読みやすさ・速さ
ライブコーディングの進め方
形式見られていることコツ
アルゴリズムの問題計算量・データ構造の選び方まず素直な解を言い、計算量を言ってから改善する
ライブコーディング(実務寄り)API や画面の部品を、話しながら作れるか考えを声に出す。分からない API は「調べます」と言ってよい
持ち帰り課題設計・テスト・README・コミットの分け方要件の解釈と省いたことを README に書く。テストと動かし方を必ず
コードレビューの課題問題の優先順位、指摘の伝え方セキュリティ・正しさ → 性能 → 読みやすさの順に指摘する

持ち帰り課題は、時間をかけすぎて凝るより、指定の範囲を確実に動かし、「時間があれば次にやること」を書くほうが評価されやすいです。

18.10よくある失敗

★★☆ 重要
失敗なぜ評価が下がるか代わりに
要件を聞かずに描き始める問題の理解が浅いと見られる最初の5分で前提を確定させる
最初から大きすぎる構成規模とコストの感覚がないと見られる小さく始め、「10倍になったら」で広げる
技術の名前を並べる選んだ理由が見えない「○○を優先するので△△」と理由を添える
整合性の話をしないWeb の設計で一番大事な所を落としている二重送信・同時更新の扱いを自分から話す
黙って考え込む考えの筋道が評価できない迷っている選択肢ごと口に出す
面接官のヒントを流す対話できないと見られるヒントは「そこを深掘りしてほしい」の合図と受け取る

この章のまとめ

🖨 まとめシート(印刷・PDF)
  • 要件確認 → 見積もり → API とデータ → 構成 → 深掘り → まとめ の順で進める
  • Web の設計面接では、API の形・DB 設計・キャッシュ・非同期・整合性の判断が深く見られる
  • ライブコーディングは、動く最小 → テスト → 改善の順で、考えを声に出す

この章のクイズ

面接ではこう聞かれる

まず答えを見ずに声に出して答え、そのあと開いて比べる。

Q1短縮 URL のサービスを設計してください。

模範回答

まず要件を確かめます。例えば「1日に新しい URL が100万件、アクセスは100倍で読みが多い、短い URL は推測されにくく、リダイレクトは速く」と置きます。すると書き込みは1秒あたり十数件、読みは千件規模で、読みが多いのでキャッシュが効く構成にします。

API は POST /urls で作成、GET /{code} で 301 か 302 のリダイレクトです。アクセス数を数えたいなら、ブラウザがキャッシュしにくい 302 にします。表は code を主キーにして元の URL を持ちます。code は連番を62進数にする方法と、ランダムに作って一意制約で衝突を防ぐ方法があり、推測されにくさを優先するならランダムにします。読みは CDN と Redis でキャッシュし、アクセスの集計はキューに入れて非同期で行います。

深掘りされたら

  • 同じ URL を2回登録されたら同じ code を返しますか?
  • 悪用(フィッシング)にはどう備えますか?

見られているポイント要件の確認・見積もり・API とデータ・キャッシュ

Q2SNS のタイムラインを設計してください。

模範回答

まず規模を確かめ、例えば1日のアクティブ 1,000万人、読み取りが書き込みの 100倍、数秒の遅れは許す、と置きます。読み取りが圧倒的に多いので、投稿したときにフォロワーごとのタイムラインに投稿 ID を配っておく「書き込み時に配る」方式を基本にします。タイムラインは Redis のソート済みセットに ID だけを持ち、本文はまとめて取ってキャッシュします。

ただし、フォロワーが数百万人いる人の投稿を全員に配ると重いので、そういう人だけは配らずに、読むときに混ぜます。ページングは投稿 ID によるカーソル方式にし、配る処理はキューとワーカーで非同期にします。

深掘りされたら

  • フォロワーが多い人の投稿はどう扱いますか?
  • 投稿を削除したら、タイムラインからどう消しますか?

見られているポイント読みと書きの比率から方式を選び、偏り(有名人)への対処まで話せるか

Q3セールで人気商品に注文が集中します。在庫と注文をどう設計しますか?

模範回答

在庫の二重販売を防ぐことを最優先にします。在庫は DB の条件付き更新、つまり qty > 0 のときだけ1減らす UPDATE で確保し、更新した行が0なら売り切れと返します。注文 API には冪等キーを付け、決済サービスにも同じキーを渡して二重決済を防ぎます。

集中への対策としては、待合室のキューで入場を絞る、静的なページは CDN から返す、在庫の行への更新が集中しすぎるなら在庫を複数の行に分ける、といった方法があります。決済に失敗したら在庫を戻す補償の処理を入れ、確定の通知は Outbox でジョブにします。

深掘りされたら

  • カートに入れた時点で在庫を減らしますか?
  • 決済の応答がタイムアウトしたらどうしますか?

見られているポイント整合性の守り方(条件付き更新・冪等キー)と、集中への対策

Q4ライブコーディングで、途中で詰まったらどうしますか?

模範回答

黙らずに、今どこで詰まっているかを言葉にします。例えば「この境界の扱いで迷っています。案は2つあり、A は単純だが重複が出る、B は正確だが少し複雑です」のように選択肢を出し、まずは単純なほうで動かしてから直すと伝えます。

API の名前を忘れたときは「調べてよいですか」と聞くか、仮の関数名で書いて後で埋めます。面接官は答えそのものより、詰まったときの進め方と対話を見ているので、ヒントをもらったら素直に取り入れます。

深掘りされたら

  • テストはどのタイミングで書きますか?

見られているポイント詰まったときの言語化と、動く最小から進める姿勢