Orivel Orivel
メニューを開く

URL短縮サービスの設計

このシステム設計ベンチマークに対する各AIの回答と比較結果を確認できます。

いいね・お気に入り機能を使うにはログインまたは新規登録が必要です。 新規登録

X f L

目次

お題概要

比較ジャンル

システム設計

お題作成モデル

回答モデル

採点モデル

お題本文

URL短縮サービス(bit.ly や tinyurl.com に類似)を設計してください。以下の制約を満たす必要があります: 1. サービスは月間で1億件の新しいURL短縮をサポートする必要があります。 2. 読み取り(リダイレクト)リクエストと書き込み(短縮)リクエストの比率は100:1です。 3. 短縮URLは可能な限り短くするが、少なくとも10年間の予想ボリュームをサポートできる必要があります。 4. システムは99.9%の稼働率(アップタイム)を達成する必要があります。 5. リダイレクトのレイテンシは95パーセンタイルで50ms未満でなければなりません。 6. データセンタ...

さらに表示

URL短縮サービス(bit.ly や tinyurl.com に類似)を設計してください。以下の制約を満たす必要があります: 1. サービスは月間で1億件の新しいURL短縮をサポートする必要があります。 2. 読み取り(リダイレクト)リクエストと書き込み(短縮)リクエストの比率は100:1です。 3. 短縮URLは可能な限り短くするが、少なくとも10年間の予想ボリュームをサポートできる必要があります。 4. システムは99.9%の稼働率(アップタイム)を達成する必要があります。 5. リダイレクトのレイテンシは95パーセンタイルで50ms未満でなければなりません。 6. データセンターがオフラインになった場合、サービスは優雅に劣化(graceful degradation)できる必要があります。 設計では、以下の各領域に対処してください: A) API Design: 主要なAPIエンドポイントとその契約を定義してください。 B) Data Model and Storage: ストレージソリューションを選択し、その選択を正当化し、スキーマを説明し、10年間で必要な総ストレージを見積もってください。 C) Short URL Generation: 短縮コードを生成するアルゴリズムを説明してください。衝突をどのように回避するか、選んだ文字セットと長さ、およびキー空間が十分であることの数学的な正当化について議論してください。 D) Scaling and Performance: 読み取りと書き込みを独立してどのようにスケールさせるかを説明してください。キャッシュ戦略(キャッシュの退避ポリシーと期待ヒット率を含む)を説明し、50msのp95レイテンシ要件をどのように満たすかを説明してください。 E) Reliability and Fault Tolerance: データセンター障害をシステムがどのように処理するか、データの複製戦略、および一貫性と可用性の間でどのようなトレードオフを行うか(CAP定理を参照)を説明してください。 F) Trade-off Discussion: 少なくとも2つの重要な設計トレードオフを特定し、なぜ一方のオプションを選んだのか、何を犠牲にし何を得るかを説明してください。 回答は、A〜Fに対応する明確なセクションを持つ構造化プランとして提示してください。

採点方針

強い解答は、6つのセクション(A〜F)すべてを網羅した、よく構成された計画であるべきです。以下の基準に基づいて評価してください: 1. 完全性:6つの領域すべてに実質的な詳細が含まれていること。表面的な言及だけでは不十分です。 2. API設計:短縮URLを作成するPOSTエンドポイントとリダイレクト用のGETエンドポイントを少なくとも含め、合理的な入出力仕様を提示していること。 3. ストレージとデータモデル:データベースの選択(例:書き込みスループットのためのNoSQL、整合性のためのリレーショナルなど)を正当化し、明確なスキーマを示し、現...

さらに表示

強い解答は、6つのセクション(A〜F)すべてを網羅した、よく構成された計画であるべきです。以下の基準に基づいて評価してください: 1. 完全性:6つの領域すべてに実質的な詳細が含まれていること。表面的な言及だけでは不十分です。 2. API設計:短縮URLを作成するPOSTエンドポイントとリダイレクト用のGETエンドポイントを少なくとも含め、合理的な入出力仕様を提示していること。 3. ストレージとデータモデル:データベースの選択(例:書き込みスループットのためのNoSQL、整合性のためのリレーショナルなど)を正当化し、明確なスキーマを示し、現実的なストレージ見積もりを含むこと。見積もりは与えられた制約(10億ではなく、毎月1億書き込み×10年)に基づいて根拠があること。 4. 短縮URL生成:具体的なアルゴリズム(例:base62エンコード、カウンタベース、ハッシュベース、事前生成されたキーサービスなど)を含むこと。キー空間の数学的正当化(例:base62で7文字は約3.5兆の組み合わせであり、10年間で120億のURLを超える)を示すこと。衝突処理についても取り扱うこと。 5. スケーリングとパフォーマンス:水平スケーリング、リードレプリカやパーティショニング、キャッシュレイヤー(例:RedisやMemcached)と妥当な退避ポリシーを説明すること。キャッシュ戦略が50msレイテンシ目標および100:1の読み書き比率にどのように結びつくかを示すこと。 6. 信頼性:マルチデータセンター複製、フェイルオーバー機構を議論し、CAP定理に基づくトレードオフ(例:分断時の可用性を優先してAPを選ぶ等)を明示すること。 7. トレードオフ:少なくとも2つの本質的なトレードオフを特定し、なぜその選択をしたのか、得られるものと犠牲にするものを明確に説明すること(例:整合性対可用性、単純さ対拡張性、ストレージコスト対計算コストなど)。 曖昧な回答、セクションの欠落、定量的根拠がまったくない回答、または設計選択を与えられた制約に結び付けられない回答は減点してください。深い推論、現実的な数値、実務上の懸念への配慮を示す回答を高く評価してください。

回答

A) API 設計

  1. 短縮URLの作成
  • エンドポイント: POST /v1/urls
  • リクエストJSON:
    • long_url (文字列、必須、最大例: 8KB)
    • custom_alias (文字列、任意; 提供される場合は一意であり、許可された文字セット/長さを満たす必要があります)
    • expire_at (タイムスタンプ、任意)
    • metadata (オブジェクト、任意: 例: キャンペーン、user_id)
  • レスポンス (201):
    • code (文字列)
    • short_url (文字列)
    • long_url (文字列)
    • created_at (タイムスタンプ)
    • expire_at (タイムスタンプ|null)
  • エラー:
    • 400 無効なURL/エイリアス
    • 409 エイリアスが既に存在します
    • 429 レート制限
  1. 解決/リダイレクト
  • エンドポイント: GET /{co...
全文を表示

A) API 設計

  1. 短縮URLの作成
  • エンドポイント: POST /v1/urls
  • リクエストJSON:
    • long_url (文字列、必須、最大例: 8KB)
    • custom_alias (文字列、任意; 提供される場合は一意であり、許可された文字セット/長さを満たす必要があります)
    • expire_at (タイムスタンプ、任意)
    • metadata (オブジェクト、任意: 例: キャンペーン、user_id)
  • レスポンス (201):
    • code (文字列)
    • short_url (文字列)
    • long_url (文字列)
    • created_at (タイムスタンプ)
    • expire_at (タイムスタンプ|null)
  • エラー:
    • 400 無効なURL/エイリアス
    • 409 エイリアスが既に存在します
    • 429 レート制限
  1. 解決/リダイレクト
  • エンドポイント: GET /{code}
  • 動作:
    • デフォルトで301 Moved Permanently (またはトラッキング/実験が必要な場合は302)
    • Locationヘッダー = long_url
  • オプション: GET /v1/urls/{code} はリダイレクトの代わりにJSONを返します (APIクライアント用)
  • エラー:
    • 404 見つかりません/期限切れ
  1. 削除/無効化 (任意、不正利用/ユーザー制御用)
  • エンドポイント: DELETE /v1/urls/{code}
  • 認証必須
  • レスポンス: 204
  1. 分析 (任意、非同期/近似可能)
  • エンドポイント: GET /v1/urls/{code}/stats?from=&to=
  • 集計されたカウンター (日別クリック数、参照元、ジオグラフィックなど) を返します

注記:

  • 認証: 作成および管理にはAPIキー/OAuthを使用します。リダイレクトは公開のままです。
  • Idempotency: POSTリクエストでIdempotency-Keyヘッダーをサポートし、リトライ時の重複を防ぎます。

B) データモデルとストレージ

ワークロード

  • 書き込み: 1ヶ月あたり1億件 ≈ 1日あたり333万件 ≈ 平均38.6書き込み/秒 (ピークはより高い)。
  • 読み取り: 100:1 => 1ヶ月あたり100億リダイレクト ≈ 平均3.86K読み取り/秒 (ピークははるかに高い)。

ストレージの選択

  • プライマリストア: 非常に高い読み取りQPS、低レイテンシ、水平スケーリング、マルチDCレプリケーションに最適化された分散キーバリューストア/ワイドカラムストア (例: DynamoDB/Cassandra/ScyllaDB)。
  • 理由: アクセスパターンは主に短いコードによるキー検索です。値は小さく、高可用性と予測可能なレイテンシが強く求められます。
  • セカンダリシステム:
    • キャッシュ: リージョンごとのRedis/Memcachedクラスタ。
    • 分析パイプライン: Kafka/PubSub + ストリーム処理 + OLAPストア (クリティカルパスではありません)。

スキーマ

  1. url_mapping (プライマリ)
  • パーティションキー: code (文字列)
  • カラム:
    • long_url (文字列)
    • created_at (タイムスタンプ)
    • expire_at (タイムスタンプ|null)
    • user_id (文字列|null)
    • status (active/deleted)
    • checksum (整合性のため、任意)
  • TTL: expire_atが設定されている場合、ネイティブTTLを使用し、期限切れのエントリを自動削除します。
  1. alias_reservation (カスタムエイリアスの一意性をサポートする場合、任意)
  • キー: custom_alias
  • 値: code / 所有権メタデータ
  1. idempotency (任意)
  • キー: (user_id, idempotency_key)
  • 値: code
  • TTL: 例: 24時間

ストレージ見積もり (10年間)

  • 10年間の新規URL数: 1億件/月 * 12ヶ月 * 10年 = 120億件のマッピング。
  • レコードあたりのサイズ概算:
    • code: 約8バイト (または最大約10文字)
    • long_url: 平均200バイトと仮定 (保守的)、オーバーヘッドを追加。
    • メタデータ/カラム/インデックスオーバーヘッド: ストアによって約100〜200バイトと仮定。
    • 合計実効サイズ (まだカウントされていないレプリケーションオーバーヘッドを含む): レコードあたり約400バイト (妥当な計画値)。
  • 生データ: 120億 * 400バイト = 4.8TB。
  • ストレージエンジンオーバーヘッド + コンパクション + セカンダリインデックスを含む: 約2〜3倍を計画 => 約10〜15TB。
  • レプリケーション:
    • リージョン内 (RF=3): 約30〜45TB。
    • マルチリージョン (例: 2つのアクティブ-アクティブリージョン): 倍増 => 全リージョンで合計約60〜90TB。
      (これらは計画値であり、正確な値は平均URL長とDBオーバーヘッドによって異なります。)

C) 短縮URL生成

目標

  • できるだけ短く
  • 高スケールでの衝突フリー
  • 少なくとも10年間の成長をサポート

キー空間の計算

  • 10年間で必要なコードの総数: 120億。
  • Base62文字セットを使用: [0-9][a-z][A-Z] => 62シンボル。
  • 長さLの容量: 62^L。
    • 62^6 ≈ 56.8B (120億には十分)
    • 62^7 ≈ 3.52T (より多くのヘッドルーム)

選択肢

  • 最小長6文字の可変長を使用。
  • 最初の約568億コードには6文字から開始。これは既に10年間の要件を大幅なマージン (56.8B/12B ≈ 4.7倍) でカバーしています。
  • 既存のリンクを壊すことなく、将来的に7文字に移行できる能力を維持します。

生成アルゴリズム (衝突なし)
選択されたオプション: グローバルに一意な数値ID + Base62エンコーディング。

  • 単調増加する64ビットID空間を維持します。
  • IDをBase62にエンコードしてコードを生成します。
  • 衝突回避: IDは構築上一意であるため、不要です。

スケールでのID生成方法

  • Snowflakeのような分散IDアロケータ、または範囲リースを持つ中央「IDサービス」を使用します:
    1. IDサービスは、各リージョンで一貫性の高いストア (例: etcd/Spanner) にカウンタを格納します。
    2. 各アプリサーバーは、ローカルで生成するためにIDブロック (例: 100万ID) をリースします。
    3. ブロックが枯渇したら、新しいブロックを要求します。
  • これにより、書き込みごとの競合を回避しつつ、一意性を確保します。

カスタムエイリアスの処理

  • custom_aliasが提供された場合:
    • 文字セット/長さを検証します。
    • url_mappingに対する条件付き書き込み (比較・交換) で、キー=aliasとします。存在する場合は409を返します。

D) スケーリングとパフォーマンス

高レベルアーキテクチャ

  • Anycast/GeoDNS -> グローバルロードバランサー -> リージョンL7ロードバランサー -> ステートレスAPI/リダイレクトサーバー。
  • 分離されたサービス:
    • 書き込みパス: URL作成サービス
    • 読み取りパス: リダイレクトサービス
    • 共有ストレージ + キャッシュ

読み取りと書き込みのスケーリングを独立して行う

  • リダイレクトサービスは、QPS/レイテンシに基づいて水平スケーリングされます (おそらく主要なコスト)。
  • 作成サービスは、書き込みスループットに基づいてスケーリングされます。
  • 別々の自動スケーリンググループと独立したデプロイパイプラインを使用します。

データパーティショニング

  • DBノード全体でコードハッシュ (またはコード自体) によってパーティショニングします。
  • コードはBase62エンコード時にID空間全体で実質的に均一であるため、均一な分散が可能です。

キャッシング戦略

  • プライマリ: リダイレクト用のCDN/エッジキャッシュ + リージョン内インメモリキャッシュ。
    1. CDN:
      • パス (コード) をキーとして301/302レスポンスをTTL付き (例: 5〜60分、またはexpire_atを尊重) でキャッシュします。
      • 非常にホットなリンクの場合、CDNはグローバルにほとんどのトラフィックを吸収できます。
    2. リージョン内キャッシュ (Redis/Memcached):
      • キー: code
      • 値: long_url + expire_at + status
      • TTL: min(default_ttl, expire_at-now)
      • Eviction: LRUまたはLFU (人気が偏っている場合はLFUを推奨)。

期待されるヒット率

  • URLアクセスは通常非常に偏っています (Zipf分布)。CDN + リージョン内キャッシュにより、リダイレクトで95〜99%のヒット率が可能です。90%でも役立ちます。
  • キャッシュウォーミング: 書き込み時にマッピングをキャッシュにプッシュします。また、無効なコードに対する繰り返しDBヒットを減らすために、ミスに対するネガティブキャッシング (短いTTL) も行います。

<50msのp95リダイレクトレイテンシの達成

  • キャッシュヒットのクリティカルパス:
    • エッジ/CDNヒット: 多くの場合 <20ms。
    • リージョン内キャッシュヒット: LB + アプリ + Redisルックアップ + レスポンス: リージョン内では通常5〜15ms。
  • キャッシュミスの場合:
    • ローカルリージョンのDBからの単一DB読み取り: 目標5〜20ms。
  • リダイレクトサーバーをユーザーの近くに配置します (マルチリージョン + エッジ経由)。
  • キープアライブ、コンポーネント間のHTTP/2、Redis/DBへの接続プーリングを使用します。
  • 同期分析を避け、クリックイベントをキューに非同期で発行します。

書き込みパフォーマンス

  • 書き込みは読み取りに比べて少ないですが、バーストにも対応します。
  • 書き込みフロー:
    1. ID/コードを生成します。
    2. DBに書き込みます (リージョン内のクォーラム/マジョリティ)。
    3. キャッシュにライトスルーします。
    4. レスポンスを返します。
  • オプション: ハッシュ->コードインデックスを格納して、同一のlong_urlを重複排除します (トレードオフ。Fを参照)。

E) 信頼性と耐障害性

可用性目標: 99.9%

  • すべての状態を持つコンポーネントについて、各リージョン内でマルチAZ。
  • リダイレクトトラフィックのために、少なくとも2つのリージョンでアクティブ-アクティブ。

レプリケーション戦略

  • リージョン内: AZをまたいだレプリケーションファクター3。
  • クロスリージョン:
    • url_mappingの非同期レプリケーションにより、書き込みレイテンシを低く保ち、可用性を高くします。
    • リダイレクトはローカルリージョンから提供されます。レプリケーションラグによりローカルマッピングが見つからない場合、別のリージョンにフォールバックします (下記参照)。

データセンター/リージョン障害時の処理 (正常な劣化)

  • グローバルロードバランサーのヘルスチェックを使用します:
    • リージョンが非健康的であれば、トラフィックを次に近い健康なリージョンにルーティングします。
  • リダイレクトリクエストの場合:
    • リージョン内キャッシュ/DBに障害が発生した場合、リダイレクトサービスは以下を実行できます:
      1. キャッシュを試す
      2. ローカルDBを試す
      3. ローカルDBが利用できない場合、リモートリージョンの読み取りエンドポイントをクエリする (厳密なタイムアウト付き) か、クロスリージョン読み取りレプリカを使用します。
      4. すべて失敗した場合、Retry-After付きの高速な503を返します (正常な障害)。
  • 書き込みリクエストの場合:
    • ローカルリージョンでの書き込みを優先します。リージョンがダウンしている場合は、別のリージョンにフェイルオーバーします。
    • ID割り当て: 各リージョンは、フェイルオーバー中の競合を回避するために、独自のIDブロック名前空間 (またはSnowflakeのリージョンビットを使用) を持ちます。

CAP定理のトレードオフ

  • グローバル操作については、強力な一貫性よりも可用性を選択します:
    • リダイレクトは非常に利用可能である必要があり、古い読み取りは短時間なら許容されます。
    • クロスリージョンレプリケーションは非同期です。新しく作成された短縮URLは、短い期間、別のリージョンで解決できない可能性があります。
      緩和策:
    • 作成後、同じリージョンドメインでホストされる短縮URLを返します (または、最初の数分間はオリジンリージョンにルーティングするエッジを使用します)。
    • 作成時に、オプションで2つのリージョンに同期書き込みを行います (プレミアム/エンタープライズティアの場合、レイテンシ/コストが高くなります)。

バックアップと災害復旧

  • オブジェクトストレージへの定期的なスナップショットと増分バックアップ。
  • 定期的なリストア訓練。

F) トレードオフの議論

  1. IDベースのコード生成 vs ランダムトークン
  • 選択: IDベース (範囲リース/Snowflake) + Base62。
  • 利点:
    • 衝突なし、リトライループの必要なし。
    • 予測可能なキャパシティプランニングとシンプルなDB制約。
    • 高速な書き込み。
  • 犠牲:
    • コードは推測可能/シーケンシャルです (セキュリティによる秘匿性は提供されません)。
      緩和策:
    • 数値IDに対するオプションの「ソルト付き順列」(例: Feistelネットワーク) を追加して、一意性を維持しながらコードを非シーケンシャルにします。
  1. 非同期クロスリージョンレプリケーション (AP) vs 同期マルチリージョン (CP)
  • 選択: 非同期クロスリージョンレプリケーション。
  • 利点:
    • 低い書き込みレイテンシ、部分的な障害時の高い可用性。
    • リージョンに障害が発生した場合でも、リダイレクトを提供し続ける能力が高い。
  • 犠牲:
    • 結果整合性: 新しく作成されたURLが別のリージョンで読み取れない短い期間が存在する可能性があります。
      緩和策:
    • 読み取り修復/オリジンリージョンへのフォールバックで最新リンクに対応。高SLA顧客向けのオプションのデュアル書き込み。
  1. 重いキャッシング/CDN vs 常にDBにヒット
  • 選択: CDN + リージョン内キャッシュ。
  • 利点:
    • <50msのp95を容易に満たし、DB負荷を劇的に削減します。
    • バイラルリンクのトラフィックスパイクに対応します。
  • 犠牲:
    • キャッシュ無効化の複雑さ (例: 削除/期限切れリンク)。
      緩和策:
    • 短いTTL、expire_atの尊重、CDNでの削除時の明示的なパージ (サポートされている場合)。ステータスフラグとネガティブキャッシングを慎重に使用します。

判定

1位 | 勝者

勝利票

3 / 3

平均スコア

88

総合点

84

総評

回答Aは、6つのセクションすべてを実質的な深さで網羅した、包括的で詳細なシステム設計です。QPS計算、レプリケーションファクターを含むストレージ見積もり、キャッシュヒット率などの正確な定量的推論を随所に示し、冪等性、ネガティブキャッシュ、不正利用対策などのエッジケースにも対処しています。また、コネクションプーリング、HTTP/2、コード難読化のためのFeistelネットワーク、ライトスルーキャッシュなどの実践的なエンジニアリングの詳細も提供しています。API設計には、レート制限、冪等性ヘッダー、分析エンドポイントが含まれます。ストレージ見積もりは、リージョン間のレプリケーションを考慮しています。トレードオフのセクションでは、明確な緩和策を伴う3つの実際のトレードオフを特定しています。信頼性のセクションでは、劣化したシナリオのための詳細なフォールバックチェーンを提供しています。全体として、シニアレベルのエンジニアリングの深さと実践的な認識を示しています。

採点詳細を表示

設計の質

重み 30%
85

回答Aは、明示的なQPS計算(書き込み/秒38.6、読み取り/秒3.86K)、マルチレイヤーキャッシュ(CDN + リージョンRedis/Memcached)、詳細な書き込みおよび読み取りパス、コネクションプーリング、HTTP/2最適化、Kafka経由の非同期分析、および範囲リースを備えた適切に設計されたID割り当てシステムを備えた、徹底的なアーキテクチャを提供します。アーキテクチャの選択は適切に正当化され、制約と関連付けられています。

完全性

重み 20%
85

回答Aは、6つのセクションすべてを実質的な詳細で網羅しています。追加のエンドポイント(DELETE、分析)、冪等性サポート、ネガティブキャッシュ、エイリアス予約スキーマ、リージョン全体でのレプリケーションファクターを含む詳細なストレージ見積もり(合計60〜90TB)、および緩和策を伴う3つのトレードオフが含まれています。ストレージ見積もりは、オーバーヘッドとマルチリージョンレプリケーションを現実的に考慮しています。

トレードオフの説明力

重み 20%
80

回答Aは、3つの実際のトレードオフを特定しています:IDベース対ランダムトークン、非同期対同期クロスリージョンレプリケーション、およびヘビーキャッシュ対常にDBヒット。各トレードオフには、明確な利点、犠牲、および実践的な緩和策(コード難読化のためのFeistelネットワーク、レプリケーションラグのためのリードリペア、キャッシュ無効化のための短いTTL)が含まれています。この推論は、エンジニアリングのトレードオフに関する深い理解を示しています。

拡張性・信頼性

重み 20%
85

回答Aは、劣化したシナリオ(キャッシュ -> ローカルDB -> リモートリージョン -> Retry-After付き503)のための詳細なフォールバックチェーン、フェイルオーバー中の競合を回避するためのリージョン認識ID割り当て、明示的なレイテンシの内訳(キャッシュあり/なしパス)、およびリージョン内(RF=3)とクロスリージョンレプリケーションの両方について説明しています。キャッシュ戦略と50ms p95ターゲット間の関連性は明確で説得力があります。

分かりやすさ

重み 10%
80

回答Aは、明確なセクションヘッダー、サブセクション、および箇条書きでよく整理されています。メモ、番号付きリスト、明示的なラベルの使用により、フォローしやすくなっています。定量的推論は明確に提示されています。一部のセクションは密ですが、読みやすいままです。

採点モデル Google Gemini 2.5 Pro

総合点

91

総評

回答Aは、傑出した専門家レベルのシステム設計を提供しています。分散KVS(Key-Value Store)という非常に適切な技術スタックを選択し、詳細かつ現実的なストレージ計算を行い、CDN/エッジキャッシュ、マルチリージョンアクティブアクティブデプロイメント、明確な段階的劣化パスを含む洗練されたスケーリングおよび信頼性戦略を概説することで、分散システム原則に対する深い理解を示しています。API設計は包括的であり、トレードオフに関する議論はニュアンスに富み、洞察に満ちています。すべてのセクションにわたる詳細レベルは並外れています。

採点詳細を表示

設計の質

重み 30%
90

アーキテクチャはこの問題に例外的に適しています。DynamoDB/Cassandraのような分散キーバリューストアの選択は、高読み取り、キー検索ワークロードに最適です。Anycast/GeoDNSから分離された読み取り/書き込みサービスに至るまで、全体的な設計は堅牢でスケーラブルであり、専門家レベルの思考を示しています。

完全性

重み 20%
90

回答は非常に包括的で、6つのセクションすべてに詳細に対処しています。API設計は特に徹底しており、分析や削除のためのオプションですが重要なエンドポイント、および冪等性や認証に関する考慮事項も含まれています。

トレードオフの説明力

重み 20%
90

回答は、3つの明確で非常に適切なトレードオフを提供しています。その理由は優れており、何が得られ、何を犠牲にするかを明確に概説しており、さらに重要なことに、各選択肢の欠点の実際的な緩和策も含まれています。これは、エンジニアリングのトレードオフに対する成熟した理解を示しています。

拡張性・信頼性

重み 20%
95

これは傑出したセクションです。読み取りと書き込みのスケーリングを個別に計画する手順は明確です。キャッシュ戦略はマルチレイヤー(CDN + リージョンキャッシュ)であり、グローバル規模でレイテンシ目標を満たすために不可欠です。信頼性計画も優れており、詳細な段階的劣化パスと、CAP定理における明確で十分に緩和されたAP選択が含まれています。

分かりやすさ

重み 10%
90

回答は例外的に明瞭で、構成も優れています。要求されたA-F形式に完全に準拠しており、見出し、サブ箇条書き、簡潔な言葉遣いを使用して、複雑なアイデアを消化しやすい方法で提示しています。

採点モデル OpenAI GPT-5.4

総合点

88

総評

回答Aは、API、データモデル、容量の見積もり、キャッシュ、マルチリージョンフェイルオーバー、レイテンシ制御のための現実的なアーキテクチャなど、必須セクションAからFまですべてを網羅した、強力で構造化されたシステム設計です。ワークロードに直接選択肢を結びつけ、冪等性、ネガティブキャッシュ、CDNの動作、クォーラム/レンジリースID生成、および段階的な劣化パスなどの運用上の詳細を含んでいます。マイナーな弱点としては、一部の見積もりがまだ粗く、いくつかの実装の選択肢が単一の明確にコミットされた設計ではなく、オプションとして提示されている点が挙げられます。

採点詳細を表示

設計の質

重み 30%
88

ステートレスな読み書きサービス、分散KVストア、リージョナルキャッシュとCDN、非同期分析、マルチリージョンルーティング、および具体的なID生成戦略など、ワークロードに合わせた一貫したエンドツーエンドのアーキテクチャを使用しています。設計は、懸念事項の分離と実践的な実装の詳細をうまく示しています。

完全性

重み 20%
90

6つの必須セクションすべてを実質的に扱い、認証、冪等性、オプションの分析、エイリアス予約、バックアップ戦略、段階的な劣化ステップなどの有用な詳細を追加しています。定量的推論は複数のセクションに含まれています。

トレードオフの説明力

重み 20%
85

IDベースの生成対ランダムトークン、非同期レプリケーション対同期レプリケーション、キャッシュの複雑さ対レイテンシなど、明示的な利点、犠牲、緩和策を伴う複数の意味のあるトレードオフを特定しています。推論はワークロードとSLA要件に結び付けられています。

拡張性・信頼性

重み 20%
91

水平スケーリング、パーティショニング、読み書き分離、期待されるキャッシュヒット率、CDNサポート、p95レイテンシパス、RF=3、マルチAZおよびアクティブ-アクティブリージョン設定、非同期クロスリージョンレプリケーション、およびリージョン障害時のフォールバック動作について強力に扱っています。具体的なリクエストフローで段階的な劣化を明示的に扱っています。

分かりやすさ

重み 10%
87

非常に読みやすく、AからFまで論理的に整理されており、理解しやすいです。箇条書き、数式、段階的なフローの使用は理解を助けますが、回答はやや密度が高いです。

A) API 設計:

  1. URL 短縮エンドポイント:
    • メソッド: POST
    • パス: /shorten
    • リクエストボディ (JSON):
      {
        "long_url": "string",
        "custom_short_code": "string" (オプション),
        "expires_at": "ISO 8601 datetime string" (オプション)
      }
      
    • レスポンスボディ (JSON - 201 Created):
      {
        "short_url": "string",
        "long_url": "string",
        "custom_short_code": "string" (提供された場合),
        "expires_at": "ISO 8601 datetime string" (提供された場合)
      }...
      
全文を表示

A) API 設計:

  1. URL 短縮エンドポイント:

    • メソッド: POST
    • パス: /shorten
    • リクエストボディ (JSON):
      {
        "long_url": "string",
        "custom_short_code": "string" (オプション),
        "expires_at": "ISO 8601 datetime string" (オプション)
      }
      
    • レスポンスボディ (JSON - 201 Created):
      {
        "short_url": "string",
        "long_url": "string",
        "custom_short_code": "string" (提供された場合),
        "expires_at": "ISO 8601 datetime string" (提供された場合)
      }
      
    • エラーレスポンス:
      • 400 Bad Request: long_url の形式が無効または欠落している。
      • 409 Conflict: custom_short_code が既に存在する。
      • 500 Internal Server Error: 一般的なサーバーエラー。
  2. 短縮URLリダイレクトエンドポイント:

    • メソッド: GET
    • パス: /{shortCode}
    • レスポンス: 302 Found HTTP リダイレクト (long_url へ)。
    • エラーレスポンス:
      • 404 Not Found: shortCode が存在しないか、期限切れである。
      • 500 Internal Server Error: 一般的なサーバーエラー。

B) データモデルとストレージ:

ストレージ選択: シャード化されたリレーショナルデータベース (例: PostgreSQL) とリードレプリカ。

正当性:

  • 書き込みに対する強力な一貫性: 短縮コードの一意性を保証するために不可欠。リレーショナルデータベースは ACID プロパティを提供し、URL 作成時の信頼性の高いデータ整合性にとって重要です。
  • よく理解されたシャード化: PostgreSQL は、書き込み負荷を分散し、水平スケーリングするためのさまざまなシャード化戦略 (例: レンジベース、ハッシュベース) をサポートしています。
  • 効率的なインデックス作成: Bツリーインデックスは、リダイレクトの主要な操作である short_code に対するポイントルックアップに非常に効率的です。
  • リードレプリカ: 複数の読み取り専用レプリカを追加することで、読み取り操作 (リダイレクト) のスケーリングを容易にサポートします。
  • 成熟度とエコシステム: モニタリング、バックアップ、リカバリのための堅牢なツール。

スキーマ:

urls テーブル:

  • id: BIGINT, 主キー, 自動インクリメント (または分散IDサービスによって生成される)。短縮コードの基盤として使用されます。
  • short_code: VARCHAR(7), 一意インデックス, NOT NULL。URL に使用される実際の短い文字列。
  • long_url: TEXT, NOT NULL。元の長いURL。
  • created_at: TIMESTAMP WITH TIME ZONE, NOT NULL, デフォルト: NOW()
  • expires_at: TIMESTAMP WITH TIME ZONE (NULL許容)。短縮URLの有効期限。
  • user_id: BIGINT (NULL許容、ユーザーアカウントがサポートされている場合は users テーブルへの外部キー)。

ストレージ見積もり (10年間):

  • ボリューム: 月間1億件の新規URL * 年間12ヶ月 * 10年 = 120億件のURL。
  • レコードサイズ見積もり:
    • id: 8バイト (BIGINT)
    • short_code: 7バイト (VARCHAR(7))
    • long_url: 平均100バイト (TEXT、可変長)
    • created_at: 8バイト (TIMESTAMP)
    • expires_at: 8バイト (TIMESTAMP)
    • レコードあたり合計: 約131バイト。
  • 生データサイズ: 120億レコード * 131バイト/レコード = 1.572 TB。
  • インデックスとオーバーヘッド込み: 特に short_codeid のインデックス、レプリケーション、データベースオーバーヘッドを考慮すると、10年間での総ストレージは約3〜5 TBになる可能性があります。これは、シャード化されたデータベースアーキテクチャで管理可能です。

C) 短縮URL生成:

アルゴリズム:

  1. 新しいURL短縮リクエストが到着したら、一意で単調増加するIDを取得します。このIDは次のように生成できます。
    • データベースの自動インクリメント: シャード化されたデータベースを使用する場合、各シャードは一意のID範囲を持つように設定できます (例: シャード1はID 1, 11, 21...を使用、シャード2は2, 12, 22...を使用)。
    • 分散IDジェネレーター: Snowflake のような専用サービス (または同様のカスタム実装) は、グローバルに一意で時間順の64ビット整数を生成できます。
  2. この一意のIDを base62 文字列に変換します。Base62 は 62 文字 (0-9, a-z, A-Z) を使用し、コンパクトな表現を可能にします。

衝突回避:

  • グローバルに一意なID (シャード化された自動インクリメントまたは分散IDジェネレーター経由) から短縮コードを派生させることにより、衝突は本質的に回避されます。生成される各IDは一意であり、その base62 表現も一意になります。
  • custom_short_code リクエストの場合、システムはユーザー提供のコードを挿入しようとします。競合が発生した場合 (既存のエントリによる)、ユーザーに 409 Conflict エラーが返されます。

文字セットと長さ:

  • 文字セット: Base62 (0-9, a-z, A-Z) - 62 個の一意な文字。
  • 長さ: 最初は6文字。

キー空間の十分性に関する数学的根拠:

  • 必要なボリューム: 10年間で120億件の一意なURL。
  • 6文字でのキー空間: 62^6 = 56,800,235,584 (約568億件の一意なコード)。
  • このキー空間 (568億件) は、必要な120億件のURLよりも大幅に大きいため、成長のための十分な余地があり、少なくとも10年間は十分であることを保証します。サービスがこれを超えた場合、短縮コードの長さを7文字に拡張でき、62^7 (約3.5兆件) の一意なコードを提供できます。

D) スケーリングとパフォーマンス:

読み取りのスケーリング (リダイレクト):

  • 分散キャッシュ (例: Redis Cluster): 読み取りのスケーリングの主要なメカニズム。short_code から long_url へのマッピングは、高可用性のある分散キャッシュに格納されます。100:1 の読み書き比率を考慮すると、ほとんどのリダイレクト要求はキャッシュから直接提供されます。
  • データベースリードレプリカ: シャード化された PostgreSQL インスタンスには、複数のリードレプリカがあります。キャッシュミスの場合、要求はリードレプリカにフォールバックします。ロードバランサーは、これらのレプリカ間でクエリを分散します。
  • コンテンツデリバリーネットワーク (CDN): 302 リダイレクト自体を直接キャッシュするわけではありませんが、CDN は静的アセットを提供し、初期リクエストのルーティングを最適化して、地理的に分散したユーザーのレイテンシを削減できます。

書き込みのスケーリング (短縮):

  • データベースシャード化: コア戦略。データは、シャードキー (例: short_code が派生する id) に基づいて、複数の PostgreSQL インスタンスにパーティション化されます。これにより、書き込み負荷とストレージ要件が分散されます。
  • コネクションプーリング: データベース接続を効率的に管理し、オーバーヘッドを削減します。
  • 非同期処理: 分析、ロギング、統計情報の更新など、クリティカルでないタスクには、メッセージキュー (例: Kafka, RabbitMQ) を使用してプライマリ書き込みパスから作業をオフロードし、応答性を向上させることができます。

キャッシング戦略:

  • キャッシュタイプ: 分散インメモリキャッシュ (例: Redis Cluster)。
  • キャッシュデータ: short_code から long_url へのマッピング。
  • キャッシュのポピュレーション: URL 短縮が成功すると、新しいマッピングはデータベースとキャッシュの両方に書き込まれます。リダイレクト中のキャッシュミス時には、マッピングはデータベースから取得され、キャッシュに書き込まれます (ライトスルー/ライトアサイド)。
  • エビクションポリシー: LRU (Least Recently Used) が適しています。人気のあるURLはキャッシュに残りますが、あまりアクセスされないものはスペースを確保するためにエビクトされます。特に expires_at フィールドを持つURLには、Time-to-Live (TTL) も適用できます。
  • 期待されるヒット率: 100:1 の読み書き比率とURLアクセスのべき乗則分布 (少数のURLがトラフィックの大部分を占める) を考慮すると、90〜95%以上のキャッシュヒット率が十分に達成可能であり、データベース負荷を大幅に削減します。

50ms p95 レイテンシ要件の満たし方:

  • 高いキャッシュヒット率: ほとんどのリダイレクト要求は、ミリ秒単位で応答できる分散キャッシュから提供されます。
  • 最適化されたデータベースアクセス: キャッシュミスの場合、シャード化されたデータベースの short_code に対する効率的なインデックス作成により、高速なルックアップが保証されます。
  • 近接性とネットワーク: ユーザーに近い複数のリージョンにサービスをデプロイし、高速で低レイテンシのネットワークインフラストラクチャを利用します。
  • ロードバランシング: 要求を正常なサービスインスタンスとデータベースレプリカ間で効率的に分散します。
  • ステートレスアプリケーションサーバー: APIレイヤーの水平スケーリングを容易にし、ピーク負荷を処理するための十分な容量をボトルネックなしで確保します。

D) 信頼性と耐障害性:

データセンター障害:

  • マルチリージョンデプロイメント: サービス全体 (APIサーバー、キャッシュクラスター、データベースシャード) は、少なくとも2つの地理的に離れたデータセンター/リージョンにデプロイされます。
  • グローバルロードバランサー (例: DNSベースのトラフィック管理): ユーザートラフィックを最も近い正常なリージョンに誘導します。1つのリージョンが失敗した場合、トラフィックは自動的に運用中のリージョンにリダイレクトされます。
  • 自動フェイルオーバー: データベースクラスターは、リージョン内 (プライマリからレプリカへ) およびリージョン間 (アクティブ-パッシブまたはアクティブ-アクティブ設定) で自動フェイルオーバーするように構成されています。

データレプリケーション戦略:

  • データベース (PostgreSQL):
    • リージョン内: 同期ストリーミングレプリケーションは、プライマリデータベースインスタンスとそのローカルレプリカ間で使用されます。これにより、同じデータセンター内でのプライマリ障害時にデータ損失がゼロになります。
    • リージョン間: 非同期ストリーミングレプリケーションは、アクティブリージョンのプライマリからパッシブ/スタンバイリージョンのレプリカに対して使用されます。これにより、プライマリ書き込みパスへのパフォーマンスへの影響を最小限に抑えながら、ディザスタリカバリ機能が提供されます。アクティブ-アクティブ設定では、各リージョンのプライマリはもう一方に非同期でレプリケートされます。
  • 分散キャッシュ (Redis Cluster): データは、各 Redis クラスター内の複数のノードにシャード化され、レプリケートされます。各シャードにはプライマリと少なくとも1つのレプリカがあります。ノード障害が発生した場合、レプリカがプライマリに昇格されます。

トレードオフ (CAP定理):

  • 選択: 書き込み操作 (短縮) に対してはデータベースシャード内で強力な一貫性を維持しながら、読み取り操作 (リダイレクト) については 可用性 (A)パーティション耐性 (P) を優先します。
  • 正当性: URL短縮サービスにとって、ネットワークパーティションやデータセンター障害が発生した場合でも、サービスが利用可能で応答性が高い (低レイテンシ) ことが最も重要です。ユーザーは、リダイレクトが迅速に機能することを期待しています。
  • 達成方法:
    • 可用性: マルチリージョンデプロイメント、グローバルロードバランシング、データベースリードレプリカ、および高可用性のある分散キャッシュにより、常に要求が提供されることが保証されます。
    • パーティション耐性: システムの分散性質 (シャード化、レプリケーション) は、ネットワークパーティションを本質的に処理します。
    • 一貫性: 書き込みについては、データベースシャード内で強力な一貫性が維持されます。リージョン間レプリケーションは非同期であるため、レプリケーションラグのために新しく作成されたURLに関してリージョン間で小さな不整合のウィンドウが存在する可能性があります。キャッシュも、書き込み時およびキャッシュミス時に更新されるため、最終的に一貫性のあるレイヤーとして機能します。

F) トレードオフに関する議論:

  1. リダイレクトの一貫性 vs. 可用性 (CAP定理):

    • 選択: リダイレクトパスについては、強力な一貫性よりも 可用性パーティション耐性 を優先します。
    • 理由: URL短縮サービスの主な目的は、高速で信頼性の高いリダイレクトを提供することです。新しく作成されたURLがグローバルに伝播するのに数秒かかる場合、それは些細な不便です。しかし、システムがグローバルな一貫性を待ってからリダイレクトを提供する場合、大幅なレイテンシが発生し、ネットワークパーティションやリージョン障害時の可用性が低下します。ユーザーは、頻繁なタイムアウトや遅いリダイレクトよりも、ごくまれに新しいURLが見つからない方がましだと考えるでしょう。
    • 犠牲: 最終的な一貫性の小さなウィンドウ。ユーザーがリージョンAでURLを作成し、非同期レプリケーションが完了する前にすぐにリージョンBからアクセスしようとすると、一時的に404エラーを受け取る可能性があります。極端なマルチリージョン障害シナリオで非同期レプリケーションを使用する場合、プライマリリージョンがレプリケーションをセカンダリリージョンに完了する前に壊滅的に失敗した場合、ごく最近の書き込みでデータ損失のリスクがわずかにあります。
    • 利点: 高可用性 (99.9%の稼働時間) と非常に低いレイテンシ (p95で50ms未満) をほとんどのリダイレクト要求に対して提供します。これらは最も頻繁な操作です。データセンターがオフラインになっても、システムは運用可能で応答性が維持されます。
  2. 短縮コード生成方法 (シーケンシャルIDからBase62 vs. 長いURLのハッシュ化):

    • 選択: 一意でシーケンシャルに増加するID (分散IDジェネレーターまたはシャード化された自動インクリメントから) をBase62に変換して短縮コードを生成します。
    • 理由: この方法は設計上一意性を保証し、書き込みパスを簡素化し、パフォーマンスを向上させます。ハッシュベースのアプローチに固有の衝突検出と解決に関連する複雑さとパフォーマンスのオーバーヘッドを回避します。
    • 犠牲: 短縮コードは、ある程度シーケンシャルに見える可能性があります (例: abcde1, abcde2)。これは一部のユーザーにとっては些細な美的懸念ですが、機能には影響しません。また、堅牢な分散ID生成メカニズムが必要であり、アーキテクチャにコンポーネントが追加されます。
    • 利点:
      • 保証された一意性: 衝突がないため、短縮コード生成中のデータベースルックアップやリトライが不要になり、高い書き込みスループット (月間1億件) に不可欠です。
      • シンプルな書き込みパス: 新しい短縮URLを作成するプロセスは、ID生成後の単純な挿入操作です。
      • 予測可能なキー空間: 将来の成長に対してキー空間を管理し、十分であることを保証しやすくなります。
      • 柔軟性: 同じ long_url を複数回短縮でき、必要に応じて異なる short_code を生成できます (例: 異なるキャンペーンの追跡用)。これは、long_url の単純なハッシュでは不可能です。

判定

2位

勝利票

0 / 3

平均スコア

74

総合点

65

総評

回答Bは、必要なセクションをすべて適切に網羅した、堅実で構造化されたシステム設計です。設計上の選択について、明確な説明と合理的な根拠を提供しています。しかし、回答Aと比較すると深みに欠けます。ストレージの見積もりでは、URLの平均長が短すぎます(100バイト対、より現実的な200バイト)。CDNに関する議論は弱く、CDNは302リダイレクトを直接キャッシュしないと主張していますが、これは不正確です。信頼性セクションは、セクションEではなくセクションDと誤ってラベル付けされています。トレードオフセクションでは、最小限必要な2つのトレードオフしか特定されておらず、緩和策が提供されていません。キャッシング戦略の議論は適切ですが、詳細さに欠けます。書き込みQPSと読み込みQPSの計算は明示的に提供されていません。データセンター障害のフォールバックチェーンは、回答Aよりも詳細ではありません。

採点詳細を表示

設計の質

重み 30%
65

回答Bは、シャーディングされたPostgreSQL、Redis Cluster、およびリードレプリカを備えた合理的なアーキテクチャを提示しています。しかし、明示的なQPS計算がなく、CDNに関する議論では302リダイレクトをキャッシュできないと誤って示唆しており、アーキテクチャは最適化技術の点で詳細さに欠けます。このワークロードに対してNoSQLソリューションよりもPostgreSQLを選択したのは正当化できますが、説明されているアクセスパターンには最適ではありません。

完全性

重み 20%
65

回答Bは6つのセクションすべてを網羅していますが、深みに欠けます。ストレージの見積もりでは、URLの平均長が短すぎ(100バイト)、マルチリージョンレプリケーションを考慮せずに3〜5TBに達しています。セクションEはセクションDと誤ってラベル付けされています。API設計には、レート制限と冪等性が欠けています。トレードオフは、緩和策なしで2つしか提供されていません(必要最小限)。

トレードオフの説明力

重み 20%
60

回答Bは、一貫性対可用性、およびシーケンシャルID対ハッシュという2つのトレードオフを特定しています。推論は妥当ですが、より表面的です。最初のトレードオフは、セクションEのCAPに関する議論をほぼ繰り返しています。特定された犠牲に対する緩和策は提供されていません。シーケンシャルコードを美的懸念事項として議論することは、セキュリティへの影響を過小評価しています。

拡張性・信頼性

重み 20%
65

回答Bは、マルチリージョンデプロイメント、同期的なリージョン内レプリケーションおよび非同期のリージョン間レプリケーション、自動フェイルオーバーについて議論しています。しかし、障害のフォールバックチェーンは詳細さに欠け、レイテンシ分析には各ホップの具体的な数値がなく、50ms p95がどのように達成されるかの議論はより一般的です。アクティブパッシブ対アクティブアクティブの区別は言及されていますが、完全には解決されていません。

分かりやすさ

重み 10%
70

回答Bは、明確に構造化されており、読みやすく、フォーマットも効果的に使用されています。しかし、セクションEをセクションDと誤ってラベル付けしているのは、組織上の顕著な誤りです。APIセクションでは、JSON例にMarkdownコードブロックを使用することで明確さが増しています。全体的な提示はクリーンですが、組織化の点ではやや詳細さに欠けます。

採点モデル Google Gemini 2.5 Pro

総合点

81

総評

回答Bは非常に強力で有能なシステム設計を提示しています。すべての必須セクションを堅実な根拠をもって網羅しており、シャーディングされたリレーショナルデータベースに基づいた実行可能なアーキテクチャを提案しています。スケーラビリティ、信頼性、トレードオフに関する説明は明確かつ正確です。しかし、回答Aと比較すると、包括的なCDN戦略、冪等性などのより詳細なAPI、マルチリージョンレプリケーションのオーバーヘッドを考慮したより詳細なストレージ推定などの、より高度な考慮事項や細かい点が不足しています。非常に優れた回答ですが、その対比となる回答Aよりも詳細さと洗練さでわずかに劣ります。

採点詳細を表示

設計の質

重み 30%
75

シャーディングされたリレーショナルデータベースに基づくアーキテクチャは実行可能であり、十分に正当化されています。しかし、この特定のワークロード(読み書き比率100:1、単純なキーバリューストアのルックアップ)では、一般的にNoSQLソリューションの方が適しています。提案されたアーキテクチャは堅実ですが、回答Aと比較して、問題の特定の制約に対する最適化が劣っています。

完全性

重み 20%
85

回答は非常に完全であり、要求された6つのセクションすべてに対応しています。API設計はコア要件をカバーしていますが、冪等性、削除、または分析エンドポイントなどの側面を省略しており、回答Aよりも詳細ではありません。

トレードオフの説明力

重み 20%
85

回答は、適切に選択され、明確に説明された2つのトレードオフを提供しています。一貫性よりも可用性を選択すること、およびIDベースの生成方法を使用することの利点と犠牲を正しく特定しており、その根拠は強力です。根拠の質は高いですが、回答Aは追加の関連トレードオフを提供していました。

拡張性・信頼性

重み 20%
80

スケーラビリティと信頼性に関する議論は強力です。リードレプリカ、データベースシャーディング、キャッシング、マルチリージョンデプロイメントなどの主要な戦略を正しく特定しています。しかし、厳格なレイテンシ要件を持つグローバルサービスにとって重要なコンポーネントであるCDN/エッジレイヤーへの重点が欠けています。また、回答Aよりも段階的な劣化計画の詳細が劣っています。

分かりやすさ

重み 10%
85

回答は非常に明確で整理されており、プロンプトの構造に従っています。API設計のためのJSONスニペットの使用は役立ちます。全体的な提示は理解しやすく、フォローしやすいです。

採点モデル OpenAI GPT-5.4

総合点

77

総評

回答Bは、明確なAPI、妥当なスキーマ、base62数学、キャッシング、シャーディング、CAPに関する議論を含み、全体的に堅実で一般的に包括的です。しかし、回答Aと比較すると、厳密さや明示された制約への適合性が劣ります。シャーディングされたPostgreSQLの選択は、この規模とグローバルな可用性の目標に対して説得力に欠け、ストレージの見積もりは楽観的であり、信頼性に関するセクションには一貫性の欠如やラベルの問題が見られます。また、劣化、キャッシュ無効化、クロスリージョン動作に関する具体的な運用上の詳細も少なくなっています。

採点詳細を表示

設計の質

重み 30%
72

シャーディングされたリレーショナルDB、レプリカ、キャッシュ、マルチリージョン展開を備えた、妥当な高レベルアーキテクチャを提示していますが、このアクセスパターンとグローバル規模に対するデータベースの選択は説得力に欠けます。いくつかの部分は一般的なレベルに留まり、運用上の精度が低いです。

完全性

重み 20%
82

必要なセクションはすべて網羅されており、主要な期待要素が含まれていますが、一部のセクションは薄く、具体性に欠けます。信頼性が2番目のDセクションとして誤ってラベル付けされており、回答Aほど具体的ではありませんが、正常な劣化と障害処理が検討されていません。

トレードオフの説明力

重み 20%
78

特にCAPとIDベースの生成に関する、明確な長所と短所を持つ2つの正当なトレードオフが含まれています。しかし、議論は狭く、ニュアンスが少なく、緩和策が少なく、下流の運用上の結果の検討も少なくなっています。

拡張性・信頼性

重み 20%
74

キャッシュ、レプリカ、シャーディング、マルチリージョンフェイルオーバーなど、スケーリングと信頼性の主要な要素を備えていますが、クロスリージョン操作と劣化に関する説得力は低いです。この規模でのPostgreSQLベースの設計は、より堅牢に防御されておらず、アクティブパッシブ対アクティブアクティブレプリケーションおよび可用性のトレードオフに関する一部の記述は、曖昧または内部的に混在したままです。

分かりやすさ

重み 10%
81

明確で構造化されており、平易な文章と良好なフォーマットが特徴です。読みやすいですが、一部のセクションは繰り返しが多く、やや精度が低く、セクションラベルのエラーがわずかに洗練度を損なっています。

比較結果サマリー

最終順位は、採点者ごとの順位集約(平均順位 + ボルダ方式の同点処理)で決定します。平均点は参考表示です。

採点者数: 3

勝利票

3 / 3

平均点

88
この回答を見る

採点結果

採点モデル OpenAI GPT-5.4

勝者理由

回答Aは、特にアーキテクチャ品質とスケーラビリティ/信頼性において、最も重み付けの高い基準でより高いスコアを獲得したため、勝利します。読み取り負荷が高く、グローバルに分散されたURL短縮サービスに対して、より本番環境に適した設計を提供します。具体的には、キーベースのアクセスに適したストレージの選択、マルチリージョン障害に対するより詳細な処理、明確なレイテンシ戦略、そしてスループット、ストレージ、キャッシュに関するより強力な定量的推論が含まれます。回答Bも有能ですが、そのアーキテクチャは指定された制約に対して堅牢性が低く、運用上の深みが弱く、信頼性に関する曖昧さがいくつか見られます。

採点モデル Google Gemini 2.5 Pro

勝者理由

回答Aは、その優れた深さ、詳細さ、およびWebスケールの読み取り負荷の高いサービスに適したアーキテクチャの選択により、勝者となります。回答Aが選択した分散キーバリューストアは、回答Bのリレーショナルデータベースよりも問題の制約に適しています。さらに、回答Aのスケーリング戦略はより堅牢であり、グローバルな低遅延要件を満たす上で重要なCDN/エッジキャッシュに重点を置いています。ストレージの見積もりはより詳細であり、API設計はより包括的です。どちらの回答も優れていますが、回答Aは大規模分散システムの設計においてより高い専門知識を示しています。

勝者理由

回答Aは、アーキテクチャ品質(CDN + 地域キャッシュを備えた詳細なマルチレイヤーキャッシュ、明示的なQPS計算、コネクションプーリング、非同期分析)、完全性(追加のエンドポイント、べき等性サポート、ネガティブキャッシュ、ファイステルネットワーク緩和策)、トレードオフの理由(緩和策を伴う3つの明確に説明されたトレードオフ対2つの基本的なもの)、スケーラビリティ/信頼性(詳細なフォールバックチェーン、地域を意識したID割り当て、明示的なレイテンシの内訳)において、特に優れた深さを示したため、回答Aが勝利しました。重み付けスコアリングでは、最も重み付けの高い基準(アーキテクチャ品質、30%)で回答Aが大幅に、その他のすべての基準で意味のある差をつけて回答Aが有利になりました。

X f L