質問の意図と背景
面接官は、「自分の基準を強制できるか」ではなく、技術的な意見の相違にどのように対処するかを知りたがっています。新しい並行処理の複雑さ、プライバシーのリスク、またはテストの不足によってコードヘルスが低下するとあなたが考えているプルリクエストがあり、作成者はそれを軽微な問題だとして先にマージすることを求めている状況を想定してください。事実、議論、決定、および結果を説明してください。
Google Engineering Practices では、作成者側により多くのコンテキストがないかを確認し、その上で懸念事項をコードヘルスの観点から説明することを推奨しています。複雑さがコードベースに残る場合は、一般的に現在の変更内で対処することが望まれます(緊急時は例外です)。優れた回答とは、作成者を「扱いにくい人」と決めつけるのではなく、検証可能な1つの協調事例に基づいて原則を説明するものです。
面接官が評価するポイント
- 自身の判断を再確認し、作成者が持つコンテキストを認識できるか。
- 立場や個人の好みではなく、リスク、ユーザーへの影響、テスト、保守コストを用いて懸念を説明できるか。
- 正確性、セキュリティ、プライバシー、またはリグレッションに関するブロッカーを、フォローアップタスクや単なる好みと明確に区別できるか。
- 実行可能な最小限の変更を提案し、適切なレビュアーを巻き込み、決定またはエスカレーションのパスを定義できるか。
- 成果を定量化できるか:回避された不具合、ロールバックの減少、レビュー時間、チームの信頼関係、プロセスの改善など。
事前に明確にすべき質問
- 意見の相違は、正確性、セキュリティ、プライバシー、パフォーマンス、保守性、またはコーディングの好みのどれに関するものか?
- コメントはどのレイヤーに関するものか:実装、テスト、インターフェース規約、リリースリスク、またはチームポリシーか?
- 作成者は新たな証拠、過去の制約、または納期を提示したか? 最終的な技術的決定権は誰にあるか?
- 変更は緊急性を要するか、またグレーリリース、ロールバック、または feature flag によってリスクを軽減できるか?
- 作成者のプライバシーをどのように守り、公開の場での議論が個人的な評価に発展しないようにするか?
30秒での回答例
「私はまず事実を再現または検証し、自分が見落としているコンテキストを作成者が持っていないか確認します。問題が正確性やプライバシーに影響するか、あるいは明らかにコードヘルスを低下させる場合、コードパス、テスト結果、およびユーザーリスクを用いて、なぜこの変更内で対処すべきかを説明し、最小限の修正を提案します。単なる好みであれば非ブロッカー(non-blocking)とします。それでも合意できない場合は、ドメインレビュアーやテックリードを招集し、決定事項とフォローアップを記録します。最後に、デリバリー、品質、関係性の結果を振り返ります。」
ステップごとの解決策
ステップ 1: 個人的な判断を検証可能な主張に変換する
「このコードは危険です」を「バージョンチェックがないため、2つの並行更新によって新しい値が上書きされる可能性があります」に置き換えます。再現コード、ログ、テスト、またはベンチマークを提供してください。コメントは常にコードとリスクに焦点を当て、作成者の能力には決して言及しないでください。証拠がない場合は、ブロックする前に質問を投げかけます。
ステップ 2: 見落としているコンテキストを確認する
インターフェース規約、互換性、リリース期間、依存チーム、およびロールバックについて質問します。Google のガイドラインでは、作成者の方が実装に近く、より優れた情報を持っている可能性があると指摘されています。新たな証拠によって自身の提案の誤りが証明された場合は、主張し続けることを品質とみなすのではなく、それを認めて提案を取り下げます。
ステップ 3: コメントを分類し、最小限の変更を提案する
フィードバックを、ブロッカー、非ブロッキングの提案、またはポジティブな強化に分類します。ブロッカーは、再現可能な正確性、セキュリティ、プライバシー、または発生確率の高いリグレッションリスクに対応します。スタイルの好みは Nit または文書化された規約とすることができます。同一プルリクエスト内で無関係なリファクタリングを求めるのではなく、小さなパッチ、テスト、または feature flag を提案します。
ステップ 4: コードヘルスを通じて理由(Why)を説明する
修正を将来の保守コスト、インシデント防止、またはユーザー体験に結び付けます。今回の変更のパス、影響、受け入れ基準に適用することなく、ルールのリンクをただ貼り付けることは避けてください。作成者が「後で修正する」と求めた場合、その複雑さが放置されるか、将来のレビューを難しくしないかを評価します。
ステップ 5: 決定およびエスカレーションのパスを確立する
レビュー内で合意事項と未解決の質問をまとめます。必要に応じて、短いディスカッションを設定するか、ドメイン権限を持つレビュアーを招待します。テックリードは役職ではなく、証拠、コードヘルス、およびデリバリーの制約に基づいて判断を下すべきです。未解決の非ブロッカー項目は、担当者と期日を設定して追跡します。
ステップ 6: 成果を検証し、プロセスを改善する
マージ前に、テスト、静的チェック、ロールアウト指標、およびロールバックを検証します。マージ後は、不具合、ロールバック、レビューの往復回数、デリバリー時間を観察します。同じような反論が繰り返される場合は、毎回説得に頼るのではなく、デザインレビュー、プルリクエストのテンプレート、またはドキュメントを改善します。緊急時にはレビュー範囲を絞りますが、リスクと修正対応の記録を残します。
優れた回答例
「並行キャッシュの移行作業中、書き込み処理にバージョンチェックが欠けているとコメントしました。作成者はそれを理論上の問題とみなし、マージを求めました。私は2つの並行更新で古い値が新しい値を上書きする事象を再現し、エンドポイントが注文ステータスを変更することを確認したため、この変更において正確性に関するブロッカーであると判断しました。作成者がレガシーの互換性フィールドについてより詳しいことを認めた上で、それらのフィールドを維持しつつ、条件付きバージョン管理書き込みを追加し、競合テストと指標を追加しました。」
「私たちは注文ストレージのレビュアーに設計の検証を依頼し、グレーリリース中に競合率とロールバックを監視することで合意しました。作成者は小さなパッチを受け入れ、ロールアウトで上書きが発生することはありませんでした。私はレビュー内でその証拠を説明し、より広範なキャッシュのリファクタリングは別途追跡しました。振り返りとして、チームはプルリクエストのテンプレートに並行書き込みテストを追加し、同様の議論を減らすことができました。」
よくある間違い
- 年功序列や『基準にそう書いてあるから』を使う → 作成者がリスクを理解できない → コードパス、証拠、受け入れテストを示す。
- すべてのコメントをブロッカーにする → デリバリーと信頼関係が損なわれる → リスク、提案、好みを区別する。
- 作成者が間違っていると決めつける → 実装のコンテキストを見落とす → 証拠が変わった場合は再確認して取り下げる。
- 『後で修正する』をデフォルトにする → 複雑さが残りがちになる → 今修正するか、担当者と期日を割り当てる。
- 公開レビューで個人を評価・批判する → 意見の相違が対立に発展する → コード、影響、次のステップについて議論する。
- 成果の指標を省略する → 効果を示すことができない → テスト、ロールアウト、不具合、レビュー時間、プロセスの変更を記録する。
フォローアップの質問と回答
自分が間違っていたと気づいた時はどうしますか?
不足していた事実を述べ、ブロッカーを取り下げ、新しい証拠を公の場で説明します。コンテキストを共有してくれた作成者に感謝し、権威を守ろうとするのをやめます。再発を防ぐために役立つ場合は短い記録を残します。
作成者が締め切りのために即時マージが必要だと主張した場合はどうしますか?
リスクが正確性、セキュリティ、またはコンプライアンスに影響するかどうかを評価します。高リスクのブロッカーは維持し、スコープの縮小、feature flag、グレーリリース、および明確なロールバックを提案します。低リスクの提案であれば、担当者と期日を決めたフォローアップを設けて非ブロッキングとすることができます。
双方の合意が得られない場合はどうしますか?
主張、証拠、許容できるリスク、および代替案を文書化します。ドメインレビュアーやテックリードを招いて判断を仰ぎ、将来の閲覧者が同じ議論を蒸し返さないよう、その論理的根拠をプルリクエストに記録します。
レビューがボトルネックにならないようにするにはどうすればよいですか?
早い段階で設計について話し合い、プルリクエストを小さく分割し、テストとスタイルチェックを自動化します。リスクの高い設計を最初にレビューし、その後に局所的な提案を行います。緊急時には最小限のレビューにとどめ、修正の記録を残します。