シニアSRE面接質問と回答例

Milad Bonakdar
著者
シニアSRE面接に向けて、SLO、エラーバジェット、キャパシティ計画、インシデント指揮、カオステスト、オンコール改善、信頼性判断を実践的に確認します。
はじめに
シニアサイト信頼性エンジニア (SRE) には、信頼性の高いシステムを大規模に設計し、インシデント対応を主導し、SRE 文化を推進し、信頼性投資に関する戦略的な意思決定を行うことが期待されます。この役割には、深い技術的専門知識、リーダーシップスキル、および信頼性とビジネス速度のバランスを取る能力が求められます。
この包括的なガイドでは、上級 SRE 向けの重要な面接の質問を取り上げ、高度な概念、システム設計、および組織への影響に焦点を当てています。各質問には、詳細な説明と実践的な例が含まれています。
高度な SLO 設計
1. 限られたデータしかない新しいサービスのために、SLI と SLO をどのように設計しますか?
回答: 新しいサービスの SLO を設計するには、野心と達成可能性のバランスを取る必要があります。
アプローチ:
1. ユーザー体験のマッピングから始める:
# 重要なユーザー体験を特定する
user_journeys = {
'search_product': {
'steps': ['search_query', 'results_display', 'product_click'],
'criticality': 'high',
'expected_latency': '< 500ms'
},
'checkout': {
'steps': ['add_to_cart', 'payment', 'confirmation'],
'criticality': 'critical',
'expected_latency': '< 2s'
},
'browse_recommendations': {
'steps': ['load_page', 'fetch_recommendations'],
'criticality': 'medium',
'expected_latency': '< 1s'
}
}2. ユーザーエクスペリエンスに基づいて SLI を定義する:
# SLI 仕様
slis:
availability:
description: "リクエスト成功率"
measurement: "count(http_status < 500) / count(http_requests)"
latency:
description: "リクエストレイテンシーの 95 パーセンタイル"
measurement: "histogram_quantile(0.95, http_request_duration_seconds)"
correctness:
description: "正しいデータを返すリクエストの割合"
measurement: "count(validation_passed) / count(requests)"3. 最初の SLO は控えめに設定する:
def calculate_initial_slo(service_type, criticality):
"""
サービス特性に基づいて初期 SLO を計算する
"""
base_slos = {
'critical': {
'availability': 0.999, # 99.9%
'latency_p95': 1.0, # 1 秒
'latency_p99': 2.0 # 2 秒
},
'high': {
'availability': 0.995, # 99.5%
'latency_p95': 2.0,
'latency_p99': 5.0
},
'medium': {
'availability': 0.99, # 99%
'latency_p95': 5.0,
'latency_p99': 10.0
}
}
return base_slos.get(criticality, base_slos['medium'])
# 例
checkout_slo = calculate_initial_slo('payment', 'critical')
print(f"Checkout SLO: {checkout_slo}")4. イテレーションを計画する:
- 4 週間の測定期間から開始
- SLO のパフォーマンスを毎週レビュー
- 実際のパフォーマンスとユーザーフィードバックに基づいて調整
- システムが成熟するにつれて SLO を厳格化
5. 前提条件を文書化する:
## SLO の前提条件 (初期)
### 可用性: 99.9%
- 前提: 標準的なクラウドインフラストラクチャの信頼性
- エラーバジェット: 43 分/月
- レビュー: 3 か月分のデータの後
### レイテンシー (p95): < 1 秒
- 前提: データベースクエリ < 100 ミリ秒
- 前提: 複雑な計算なし
- レビュー: クエリパターンが変化した場合
### 依存関係
- 外部 API の可用性: 99.95%
- データベースの可用性: 99.99%頻度: 一般的
難易度: 難しい
2. 異なるユーザーセグメント間で SLO が競合する場合、どのように対処しますか?
回答: 異なるユーザーセグメントは、多くの場合、異なる信頼性のニーズを持っています。
戦略: 多層 SLO
class SLOTier:
def __init__(self, name, availability, latency_p95, latency_p99):
self.name = name
self.availability = availability
self.latency_p95 = latency_p95
self.latency_p99 = latency_p99
self.error_budget = 1 - availability
# 階層を定義する
tiers = {
'premium': SLOTier(
name='Premium',
availability=0.9999, # 99.99% - 4.3 分/月
latency_p95=0.5,
latency_p99=1.0
),
'standard': SLOTier(
name='Standard',
availability=0.999, # 99.9% - 43 分/月
latency_p95=1.0,
latency_p99=2.0
),
'free': SLOTier(
name='Free',
availability=0.99, # 99% - 7.2 時間/月
latency_p95=2.0,
latency_p99=5.0
)
}
# 階層に基づいてリクエストをルーティングする
def get_user_tier(user_id):
# ユーザーのサブスクリプション層をルックアップする
return user_subscription_tier(user_id)
def apply_slo_policy(user_id, request):
tier = get_user_tier(user_id)
slo = tiers[tier]
# 階層固有のポリシーを適用する
request.timeout = slo.latency_p99
request.priority = tier # キューの優先順位付け用
request.retry_budget = calculate_retry_budget(slo.error_budget)
return requestトラフィックルーティングによる実装:
# Kubernetes の例: 階層ごとに個別のデプロイメント
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-premium
spec:
replicas: 10
template:
spec:
containers:
- name: api
resources:
requests:
cpu: "2"
memory: "4Gi"
limits:
cpu: "4"
memory: "8Gi"
priorityClassName: high-priority
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-standard
spec:
replicas: 5
template:
spec:
containers:
- name: api
resources:
requests:
cpu: "1"
memory: "2Gi"階層ごとのモニタリング:
# 階層別の可用性
sum(rate(http_requests_total{status!~"5.."}[5m])) by (tier)
/
sum(rate(http_requests_total[5m])) by (tier)
# 階層別のレイテンシー
histogram_quantile(0.95,
rate(http_request_duration_seconds_bucket[5m])
) by (tier)頻度: まれ
難易度: 難しい
キャパシティプランニング
3. 急速に成長しているサービスのキャパシティプランニングプロセスについて説明してください。
回答: キャパシティプランニングは、コストを最適化しながら、リソースが需要を満たすようにします。
キャパシティプランニングフレームワーク:
1. ベースラインの測定:
import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
class CapacityPlanner:
def __init__(self, metrics_data):
self.data = pd.DataFrame(metrics_data)
def analyze_trends(self, metric_name, days=30):
"""過去の傾向を分析する"""
metric_data = self.data[metric_name].tail(days * 24) # 時間単位のデータ
# 成長率を計算する
start_value = metric_data.iloc[0]
end_value = metric_data.iloc[-1]
growth_rate = ((end_value - start_value) / start_value) * 100
# ピーク時の使用状況を特定する
peak_value = metric_data.max()
peak_time = metric_data.idxmax()
# パーセンタイルを計算する
p50 = metric_data.quantile(0.50)
p95 = metric_data.quantile(0.95)
p99 = metric_data.quantile(0.99)
return {
'growth_rate': growth_rate,
'peak_value': peak_value,
'peak_time': peak_time,
'p50': p50,
'p95': p95,
'p99': p99
}
def forecast_capacity(self, metric_name, months_ahead=3):
"""将来のキャパシティニーズを予測する"""
# データを準備する
df = self.data[[metric_name]].reset_index()
df['days'] = (df.index / 24).astype(int) # 時間を日に変換する
# モデルをトレーニングする
X = df[['days']].values
y = df[metric_name].values
model = LinearRegression()
model.fit(X, y)
# 予測する
future_days = np.array([[df['days'].max() + (30 * months_ahead)]])
forecast = model.predict(future_days)[0]
# 安全マージンを追加する (20%)
forecast_with_margin = forecast * 1.2
return {
'forecast': forecast,
'with_margin': forecast_with_margin,
'current': y[-1],
'growth_factor': forecast / y[-1]
}
def calculate_resource_needs(self, requests_per_second,
requests_per_instance=100,
headroom=0.3):
"""必要なインスタンス数を計算する"""
# 基本キャパシティ
base_instances = np.ceil(requests_per_second / requests_per_instance)
# スパイクとメンテナンスのためのヘッドルームを追加する
total_instances = np.ceil(base_instances * (1 + headroom))
return {
'base_instances': int(base_instances),
'total_instances': int(total_instances),
'headroom_instances': int(total_instances - base_instances)
}
# 使用例
metrics = {
'requests_per_second': [100, 105, 110, 115, 120, ...], # 過去のデータ
'cpu_usage': [45, 48, 50, 52, 55, ...],
'memory_usage': [60, 62, 65, 67, 70, ...]
}
planner = CapacityPlanner(metrics)
# 傾向を分析する
trends = planner.analyze_trends('requests_per_second', days=30)
print(f"成長率: {trends['growth_rate']:.2f}%")
print(f"ピーク RPS: {trends['peak_value']}")
# キャパシティを予測する
forecast = planner.forecast_capacity('requests_per_second', months_ahead=3)
print(f"3 か月後の予測 RPS: {forecast['forecast']:.0f}")
print(f"安全マージン付き: {forecast['with_margin']:.0f}")
# リソースニーズを計算する
resources = planner.calculate_resource_needs(
requests_per_second=forecast['with_margin'],
requests_per_instance=100,
headroom=0.3
)
print(f"必要なインスタンス数: {resources['total_instances']}")2. 成長の推進要因を考慮する:
- ユーザーの成長率
- 新機能のリリース
- 季節的なパターン
- マーケティングキャンペーン
- 地理的な拡大
3. ヘッドルームの計画:
- N+1: 1 つのインスタンスの障害を乗り切る
- N+2: 2 つの障害または 1 つのゾーン停止を乗り切る
- トラフィックスパイク: 通常のキャパシティの 2 ~ 3 倍
- メンテナンスウィンドウ: 20 ~ 30% のオーバーヘッド
4. コストの最適化:
def optimize_instance_mix(workload_profile):
"""
コストのためにインスタンスタイプを最適化する
"""
# インスタンスタイプの組み合わせ
instance_types = {
'on_demand': {
'cost_per_hour': 0.10,
'reliability': 1.0,
'percentage': 0.3 # ベースライン用に 30% オンデマンド
},
'spot': {
'cost_per_hour': 0.03,
'reliability': 0.95,
'percentage': 0.5 # コスト削減のために 50% スポット
},
'reserved': {
'cost_per_hour': 0.06,
'reliability': 1.0,
'percentage': 0.2 # 予測可能な負荷のために 20% リザーブド
}
}
total_instances = workload_profile['total_instances']
allocation = {}
for instance_type, config in instance_types.items():
count = int(total_instances * config['percentage'])
allocation[instance_type] = {
'count': count,
'monthly_cost': count * config['cost_per_hour'] * 730
}
return allocation頻度: 非常に一般的
難易度: 難しい
カオスエンジニアリング
4. 本番環境でカオスエンジニアリングをどのように実装しますか?
回答: カオスエンジニアリングは、意図的に障害を注入することで、システムの回復力を積極的にテストします。
カオスエンジニアリングの原則:
- 定常状態に関する仮説を立てる
- 現実世界のイベントを変化させる
- 本番環境で実験を実行する
- 実験を自動化する
- 影響範囲を最小限に抑える
実装:
# カオス実験フレームワーク
from dataclasses import dataclass
from enum import Enum
import random
import time
class ExperimentStatus(Enum):
PLANNED = "計画済"
RUNNING = "実行中"
COMPLETED = "完了"
ABORTED = "中止"
@dataclass
class ChaosExperiment:
name: str
hypothesis: str
blast_radius: float # 影響を受けるトラフィックの割合
duration_seconds: int
rollback_criteria: dict
def __post_init__(self):
self.status = ExperimentStatus.PLANNED
self.metrics_before = {}
self.metrics_during = {}
self.metrics_after = {}
class ChaosRunner:
def __init__(self, monitoring_client):
self.monitoring = monitoring_client
self.experiments = []
def run_experiment(self, experiment: ChaosExperiment):
"""安全チェック付きでカオス実験を実行する"""
print(f"実験を開始: {experiment.name}")
# 1. ベースラインを測定する
experiment.metrics_before = self.measure_metrics()
print(f"ベースラインメトリクス: {experiment.metrics_before}")
# 2. システムが正常であることを確認する
if not self.is_system_healthy(experiment.metrics_before):
print("システムが異常であるため、実験を中止します")
return False
# 3. 障害を注入する
experiment.status = ExperimentStatus.RUNNING
failure_injection = self.inject_failure(experiment)
try:
# 4. 実験中に監視する
start_time = time.time()
while time.time() - start_time < experiment.duration_seconds:
experiment.metrics_during = self.measure_metrics()
# ロールバック基準を確認する
if self.should_rollback(experiment):
print("ロールバック基準が満たされたため、実験を停止します")
self.rollback(failure_injection)
experiment.status = ExperimentStatus.ABORTED
return False
time.sleep(10) # 10 秒ごとに確認する
# 5. 障害注入をロールバックする
self.rollback(failure_injection)
# 6. 回復を測定する
time.sleep(60) # システムが安定するまで待つ
experiment.metrics_after = self.measure_metrics()
# 7. 結果を分析する
experiment.status = ExperimentStatus.COMPLETED
return self.analyze_results(experiment)
except Exception as e:
print(f"実験が失敗しました: {e}")
self.rollback(failure_injection)
experiment.status = ExperimentStatus.ABORTED
return False
def inject_failure(self, experiment):
"""特定の障害タイプを注入する"""
# 実装は障害タイプによって異なる
pass
def measure_metrics(self):
"""主要なシステムメトリクスを測定する"""
return {
'error_rate': self.monitoring.get_error_rate(),
'latency_p95': self.monitoring.get_latency_p95(),
'requests_per_second': self.monitoring.get_rps(),
'availability': self.monitoring.get_availability()
}
def is_system_healthy(self, metrics):
"""システムが SLO を満たしているか確認する"""
return (
metrics['error_rate'] < 0.01 and # < 1% のエラー
metrics['latency_p95'] < 1.0 and # < 1 秒のレイテンシー
metrics['availability'] > 0.999 # > 99.9% の可用性
)
def should_rollback(self, experiment):
"""実験を中止する必要があるか確認する"""
current = experiment.metrics_during
criteria = experiment.rollback_criteria
return (
current['error_rate'] > criteria.get('max_error_rate', 0.05) or
current['latency_p95'] > criteria.get('max_latency', 5.0) or
current['availability'] < criteria.get('min_availability', 0.99)
)
def rollback(self, failure_injection):
"""障害注入を削除する"""
print("障害注入をロールバックしています")
# 実装は障害タイプによって異なる
def analyze_results(self, experiment):
"""実験結果を分析する"""
before = experiment.metrics_before
during = experiment.metrics_during
after = experiment.metrics_after
print(f"\n実験結果: {experiment.name}")
print(f"仮説: {experiment.hypothesis}")
print(f"\nメトリクス:")
print(f" Before: {before}")
print(f" During: {during}")
print(f" After: {after}")
# 仮説が検証されたかどうかを判断する
hypothesis_validated = (
during['availability'] >= experiment.rollback_criteria['min_availability']
)
return hypothesis_validated
# 実験例
experiment = ChaosExperiment(
name="データベースフェイルオーバーテスト",
hypothesis="データベースフェイルオーバー中にシステムが利用可能な状態を維持する",
blast_radius=0.1, # トラフィックの 10%
duration_seconds=300, # 5 分
rollback_criteria={
'max_error_rate': 0.05,
'max_latency': 5.0,
'min_availability': 0.99
}
)一般的なカオス実験:
1. ネットワークレイテンシー:
# tc (traffic control) を使用してレイテンシーを追加する
tc qdisc add dev eth0 root netem delay 100ms 20ms
# ロールバック
tc qdisc del dev eth0 root2. ポッドの障害 (Kubernetes):
# ランダムなポッドを強制終了する
kubectl delete pod -l app=myapp --random=1
# Chaos Mesh を使用する
kubectl apply -f - <<EOF
apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
name: pod-failure
spec:
action: pod-failure
mode: one
selector:
namespaces:
- production
labelSelectors:
app: myapp
duration: "30s"
EOF3. リソースの枯渇:
# CPU ストレス
stress-ng --cpu 4 --timeout 60s
# メモリストレス
stress-ng --vm 2 --vm-bytes 2G --timeout 60s頻度: 一般的
難易度: 難しい
インシデントリーダーシップ
5. 検出から事後分析まで、高重大度インシデントをどのように主導しますか?
回答: シニア SRE は、クリティカルな停止のインシデントコマンダーを務めることがよくあります。
インシデント指揮系統:
インシデントコマンダーの責任:
1. 初期対応 (0 ~ 5 分):
## インシデントコマンダーのチェックリスト
### すぐに行うべきこと
- [ ] インシデントを認識する
- [ ] 重大度を評価する (SEV-1, SEV-2, SEV-3)
- [ ] インシデントチャネルを作成する (#incident-YYYY-MM-DD-NNN)
- [ ] 適切なチームにページングする
- [ ] 役割を指定する:
- [ ] 技術リード
- [ ] コミュニケーションリード
- [ ] 記録係 (タイムラインを文書化)
### 重大度評価
**SEV-1 (クリティカル):**
- サービス全体の停止
- データ損失
- セキュリティ侵害
- > 50% のユーザーに影響
**SEV-2 (高):**
- 部分的な停止
- パフォーマンスの低下
- 10 ~ 50% のユーザーに影響
**SEV-3 (中):**
- 軽微な低下
- < 10% のユーザーに影響
- 回避策あり2. 調査フェーズ:
class IncidentCommander:
def __init__(self, incident_id):
self.incident_id = incident_id
self.timeline = []
self.status_updates = []
self.action_items = []
def coordinate_investigation(self):
"""技術調査を調整する"""
# 並行調査トラック
tracks = {
'recent_changes': self.check_recent_deployments(),
'infrastructure': self.check_infrastructure_health(),
'dependencies': self.check_external_dependencies(),
'metrics': self.analyze_metrics_anomalies()
}
return tracks
def make_decision(self, options, deadline_minutes=5):
"""時間制限付きの意思決定を行う"""
print(f"{deadline_minutes} 分以内に決定が必要です")
print(f"オプション: {options}")
# 技術リードから入力を収集する
# 次に基づいて決定する:
# - ユーザーへの影響
# - 各オプションのリスク
# - 実装までの時間
# - 可逆性
return selected_option
def communicate_status(self, interval_minutes=15):
"""定期的なステータスアップデート"""
update = {
'timestamp': datetime.now(),
'status': self.get_current_status(),
'impact': self.assess_user_impact(),
'eta': self.estimate_resolution_time(),
'next_update': datetime.now() + timedelta(minutes=interval_minutes)
}
# ステークホルダーに送信する
self.send_status_update(update)
self.status_updates.append(update)
def log_timeline_event(self, event, timestamp=None):
"""インシデントタイムラインを文書化する"""
self.timeline.append({
'timestamp': timestamp or datetime.now(),
'event': event,
'logged_by': self.get_current_user()
})3. 軽減戦略:
def evaluate_mitigation_options():
"""軽減オプションを評価して優先順位を付ける"""
options = [
{
'action': 'デプロイメントのロールバック',
'time_to_implement': 5, # 分
'risk': 'low',
'effectiveness': 'high',
'reversible': True
},
{
'action': 'リソースのスケールアップ',
'time_to_implement': 2,
'risk': 'low',
'effectiveness': 'medium',
'reversible': True
},
{
'action': 'フィーチャーフラグの無効化',
'time_to_implement': 1,
'risk': 'low',
'effectiveness': 'high',
'reversible': True
},
{
'action': 'データベースのフェイルオーバー',
'time_to_implement': 10,
'risk': 'medium',
'effectiveness': 'high',
'reversible': False
}
]
# 次でソートする: 低リスク、高効果、迅速な実装
sorted_options = sorted(
options,
key=lambda x: (
x['risk'] == 'low',
x['effectiveness'] == 'high',
-x['time_to_implement']
),
reverse=True
)
return sorted_options4. 事後分析 (責任追及なし):
# インシデント事後分析: API 停止
**日付:** 2024-11-25
**期間:** 45 分
**重大度:** SEV-1
**インシデントコマンダー:** Alice
**技術リード:** Bob
## エグゼクティブサマリー
データベース接続プールの枯渇により、すべてのユーザーに影響を与える完全な API 停止が発生しました。
## 影響
- **影響を受けたユーザー:** 100% (すべてのユーザー)
- **期間:** 45 分
- **収益への影響:** 約 $50,000
- **SLO への影響:** 月間エラーバジェットの 75% を消費
## 根本原因
インシデントの 2 時間前にデプロイされた新機能の接続リークが原因で、データベース接続プールが枯渇しました。
## タイムライン
| 時間 | イベント |
|------|-------|
| 14:00 | v2.5.0 のデプロイ |
| 15:45 | レイテンシーの増加に関する最初のアラート |
| 15:50 | 完全な API 停止 |
| 15:52 | インシデント宣言 (SEV-1) |
| 15:55 | データベースがボトルネックとして特定 |
| 16:05 | デプロイメントのロールバックの決定 |
| 16:15 | ロールバック完了 |
| 16:20 | サービスの回復 |
| 16:35 | 完全な回復が確認 |
## うまくいったこと
- 迅速な検出 (最初の兆候から 5 分以内)
- 明確なインシデント指揮系統
- ロールバックの迅速な決定
- ステークホルダーとの良好なコミュニケーション
## うまくいかなかったこと
- テストで接続リークが検出されなかった
- 接続プールのモニタリングがない
- ピーク時間中のデプロイメント
## アクションアイテム
| アクション | 担当者 | 納期 | ステータス |
|--------|-------|----------|--------|
| 接続プールのモニタリングを追加する | Alice | 2024-12-01 | オープン |
| テストで接続リーク検出を実装する | Bob | 2024-12-05 | オープン |
| デプロイメントポリシーを更新する (ピーク時間を避ける) | Charlie | 2024-11-30 | オープン |
| データベース接続用のサーキットブレーカーを追加する | David | 2024-12-10 | オープン |
## 教訓
- モニタリングのギャップは、重大な問題を隠す可能性がある
- デプロイメントのタイミングが重要
- リソースリークのためのより優れた統合テストが必要頻度: 非常に一般的
難易度: 難しい
分散システムの信頼性
6. 分散マイクロサービスアーキテクチャで信頼性をどのように確保しますか?
回答: 分散システムは、独自の信頼性の課題をもたらします。
主要なパターン:
1. 回復力のためのサービスメッシュ:
# Istio の例: サーキットブレーキングと再試行
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: api-service
spec:
host: api-service
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
http:
http1MaxPendingRequests: 50
http2MaxRequests: 100
maxRequestsPerConnection: 2
outlierDetection:
consecutiveErrors: 5
interval: 30s
baseEjectionTime: 30s
maxEjectionPercent: 50
minHealthPercent: 40
loadBalancer:
simple: LEAST_REQUEST
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: api-service
spec:
hosts:
- api-service
http:
- retries:
attempts: 3
perTryTimeout: 2s
retryOn: 5xx,reset,connect-failure,refused-stream
timeout: 10s
route:
- destination:
host: api-service2. 分散トレーシング:
from opentelemetry import trace
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.instrumentation.requests import RequestsInstrumentor
# トレーシングを設定する
trace.set_tracer_provider(TracerProvider())
jaeger_exporter = JaegerExporter(
agent_host_name="jaeger",
agent_port=6831,
)
trace.get_tracer_provider().add_span_processor(
BatchSpanProcessor(jaeger_exporter)
)
# requests ライブラリをインストルメントする
RequestsInstrumentor().instrument()
# コードで使用する
tracer = trace.get_tracer(__name__)
def process_order(order_id):
with tracer.start_as_current_span("process_order") as span:
span.set_attribute("order.id", order_id)
# 支払いサービスを呼び出す
with tracer.start_as_current_span("call_payment_service"):
payment_result = call_payment_service(order_id)
# 在庫サービスを呼び出す
with tracer.start_as_current_span("call_inventory_service"):
inventory_result = call_inventory_service(order_id)
return combine_results(payment_result, inventory_result)3. バルクヘッドパターン:
import asyncio
from asyncio import Semaphore
class BulkheadExecutor:
def __init__(self, max_concurrent=10):
selfまとめ
シニアSRE面接で強い回答は、暗記した定義ではなく、本番運用での判断に聞こえます。ユーザージャーニーからSLOを決める方法、エラーバジェットでリリースリスクを判断する方法、実際の負荷データで容量を検証する方法、制御されたカオス実験、明確な役割でのインシデント指揮、リスクを隠さないtoil削減を説明できるようにしましょう。
面接前に、具体的なストーリーを2〜3個用意してください。自分がリードしたインシデント、影響を与えた信頼性のトレードオフ、チームの行動を変えた自動化またはオブザーバビリティ改善です。それぞれについて、信号、判断、トレードオフ、その後のフォローアップを言えるようにします。


