プロンプトとコンテキスト
この一般的な技術質問では、HTTP表現、コンテンツネゴシエーション、共有キャッシュの境界がテストされます。フォールバックとトラブルシューティングの説明可能性を維持しながら、プロキシが別のリクエストに対してある言語やエンコーディングを再利用できないことを証明することが目標です。
面接官が評価するポイント
- リソースURIとその表現を区別し、プロアクティブネゴシエーションヘッダーを理解しているか。
- レスポンスに影響を与えるリクエストフィールドを宣言するためにVaryを使用し、キャッシュキーとヒット率のトレードオフを導き出せるか。
- 言語、メディアタイプ、エンコーディングのフォールバックが、説明のつかない406レスポンスを生成するのではなく、決定論的であるか。
- Cookie、認証、ユーザー特性、高カーディナリティのヘッダーによる共有キャッシュおよびプライバシーのリスクを認識しているか。
尋ねるべき明確化のための質問
リソースがパブリックに共有可能か、どのようなバリアント次元が存在するか、サーバー主導のネゴシエーションが許可されているか、クライアントが明示的に言語を選択できるか、CDNがVaryによってどのようにシャードするかを確認します。サポートされていない言語のフォールバック、許可されるエンコーディング、パーソナライズ、許容可能なキャッシュヒット率について質問します。
30秒の回答フレームワーク
リソースURIを表現の選択とは別にモデル化し、重み付けされたAccept、Accept-Language、Accept-Encodingの値から決定論的に選択して、正確なContent-Type、Content-Language、Content-Encoding、およびVaryを返します。共有キャッシュは同一のバリアントキーのみを再利用し、パーソナライズされたリクエストや高カーディナリティのリクエストはバイパスします。一致する表現がない場合は、文書化されたフォールバックまたは406ポリシーを適用し、決定をログに記録し、リクエストマトリックスでキャッシュヒット、バイト数、プライバシーをテストします。
ステップバイステップの詳細解説
1. 表現とネゴシエーションの次元を定義する
1つのURIを、HTML対JSON、中国語対英語、gzip対brなどの表現を持つリソースとして扱います。レスポンスのバイトやセマンティクスを変更するリクエストフィールドのみを含め、利便性のためにすべてのCookieや完全なUser-Agentを追加しないでください。正規化された同一の入力が同じ表現を生成するように選択を記録します。
2. 重み付け、フォールバック、エラーを設計する
Acceptファミリーの品質係数とワイルドカードを解析し、サーバーがサポートするリストと優先順位を定義します。言語は地域から基本言語、デフォルトへとフォールバックできます。メディアタイプには明示的なデフォルトを設定できます。契約上、受け入れられないすべての表現を拒否することが求められる場合にのみ406を返します。圧縮は許可リストからのみ選択し、未知の値がそれをバイパスすることを決して許可しないでください。
3. キャッシュバリアントを計算可能にする
Varyに選択ヘッダー(例:Accept, Accept-Language, Accept-Encoding)を一覧表示します。URI、メソッド、およびそれらのフィールドの正規化された値からバリアントキーを構築します。正規化は大文字小文字、空白、順序をカバーし、等価な表記が無制限のキーを作成しないようにします。認証、セッション状態、またはユーザーCookieがレスポンスに影響を与える場合は、プライベートキャッシュを使用するか、明示的に共有を防ぎます。
4. ヒット率、プライバシー、バリアント数を制御する
すべての次元はキャッシュを分割し、ヒット率を低下させます。Accept-Languageはブラウザフィンガープリンティングのシグナルにもなり得ます。パブリックページはロングテールの言語を有限のサポート対象セットにマッピングできます。パーソナライズされたデータはプライベート、短期間、またはキャッシュなしを使用します。未知の依存関係を隠すためにVary: *を使用しないでください。共有の再利用が妨げられるためです。
5. 可観測性と検証を設計する
機密性の高い完全なCookieを記録することなく、正規化されたネゴシエーション入力、選択された表現、Vary、キャッシュステータス、フォールバック理由をログに記録します。各バリアントのヘッダー、展開、CDNのヒット/ミス動作、特に「中国語が最初、英語が2番目」というシーケンスをテストします。インシデント発生時は、Age、キャッシュステータス、Content-*ヘッダー、実際のバイト数を比較し、固定のリクエストマトリックスを再生します。
優れた回答例
有限の表現セットを列挙し、Accept、Accept-Language、Accept-Encodingの品質係数から決定論的に選択します。レスポンスはContent-Type、Content-Language、Content-Encoding、および正確なVaryを返します。キャッシュキーには、それらの正規化された次元のみが含まれます。認証、セッション状態、高カーディナリティの特性は共有キャッシュから除外し、ロングテールのパブリック言語はデフォルトにフォールバックします。受け入れ可能なものがない場合、契約に基づいて406または明示的なデフォルトを選択します。ログは機密性の高いCookieなしで選択、フォールバック、ヒットステータスをキャプチャし、「中国語のち英語、brのちgzip」のようなマトリックスによってCDNが間違ったバリアントを決して再利用しないことを証明します。
よくある間違い
- Content-Languageを設定しているが、レスポンスを変更したリクエストフィールドに対するVaryを省略している。
- 完全なCookie、User-Agent、または任意のヘッダーをキャッシュキーに含め、ヒット率を破壊する。
- 地域、基本言語、デフォルトのフォールバックを行わずに、サポートされていないすべての言語に対して406を返す。
- Authorizationまたはセッションデータに依存するレスポンスを共有キャッシュに再利用させる。
- エンコーディングのネゴシエーションを無視し、クライアントがデコードできないContent-Encodingを返す。
- Content-*ヘッダー、キャッシュ状態、実際のバイト数ではなく、ステータスコードのみを確認する。
フォローアップの質問と回答
なぜVaryにAccept-Languageだけを含めることができないのですか?
メディアタイプや圧縮もレスポンスを変更する場合、キャッシュにはそれらの次元も必要です。それらを省略すると、共有キャッシュが互換性のない表現を配信し、混在コンテンツやデコードの失敗を引き起こす可能性があります。
Vary: *はどのような場合に役立ちますか?
選択がリストされていない情報に依存していることを示し、通常は共有の再利用を防ぎます。保守的なガードにはなり得ますが、実際の依存関係を追跡してプライベートキャッシュを選択することの代替にすべきではありません。
Accept-Languageによるキーの爆発をどのように防ぎますか?
クライアントの言語を有限のサポート対象セットにマッピングし、地域、基本言語、デフォルトによってフォールバックします。適切な場合は、明示的なURLまたはユーザーの選択を使用して自動ネゴシエーションをオーバーライドし、バリアントごとのヒット率を監視します。
ネゴシエーションの失敗時には406を返すべきですか、それともデフォルトの表現を返すべきですか?
インターフェースの契約によって決まります。マシンAPIは明示的なエラーを必要とすることが多い一方、Webページはデフォルトの言語やメディアタイプにフォールバックする場合があります。同じルールを文書化してログに記録し、間違ったセマンティクスを持つ表現を暗黙的に返さないようにしてください。