こう 聞かれます
- 「大きな
機能を、 安全に 少しずつ出すには、 どうしますか」 - 「新しい
決済の 画面を、 一部の 人にだけ先に 見せたいです。 どう 作りますか」 - 「長く
作り続ける 機能の ブランチは、 いつまで 分けて おきますか」
面接官が 見ている点
- コードを
出すこと (配備) と、 利用者に 見せる こと (公開) を 分けて 考えられるか - 広げる
段階ごとに、 何を 見て 次へ 進むかを 決めているか - 問題が
出た とき、 配備を 戻さずに すぐ 切れる 手を 用意しているか - フラグが
増え続けて、 コードが 読めなくなる 怖さを 知っているか
短い答え
- 配備と
公開を 分けます。 新しい 機能は フラグで 閉じたまま本番に 出し、 フラグを 開ける 範囲で、 誰に 見せるかを 決めます。 - 社内の
人、 一部の 利用者 (た とえば 1%、 10%)、 全員、と 段階を 踏んで 広げ、 段階ごとに エラーや 遅さの 数字を 見て、 次へ 進むか戻すかを 決めます。 - 問題が
出たら フラグを 閉じるだけで 止められます。 全員に 出し終えたら、 フラグと 古い 道の コードは 消します。
この
少し 詳しい答え
配備と 公開を分ける
大きな
フラグを
同じ 人には 同じ側を見せる
「10% の人に見せる」を、
JavaScript
function bucket(key) {
let h = 2166136261;
for (const ch of key) {
h = Math.imul(h ^ ch.charCodeAt(0), 16777619) >>> 0;
}
return h % 100;
}
function isEnabled(flag, userId) {
if (!flag.on) {
return false;
}
return bucket(flag.name + "/" + userId) < flag.percent;
}
const flag = { name: "new-checkout", on: true, percent: 30 };
const users = ["u1", "u2", "u3", "u4", "u5", "u6", "u7", "u8", "u9", "u10"];
console.log(users.filter((u) => isEnabled(flag, u)));
console.log(isEnabled(flag, "u3") === isEnabled(flag, "u3"));
flag.on = false;
console.log(users.filter((u) => isEnabled(flag, u)));[ 'u1', 'u2', 'u6', 'u7' ]
true
[]同じ ID ならon を
段階と、進む基準
段階ごとに、
DB の
後始末
全員に
話すときは、
よく ある間違い
- 見る
たびの 乱数で 見せる 人を決める 同じ 人が 開く たびに 画面が 変わり、 混乱と 問い 合わせを生みます - 進む基準を
決めずに 割合を上げる 問題が 出ていても 気づかず、 全員に 広げてしまいます - フラグを
消さずに 残し続ける 古い道と 新しい 道が 混ざり、 コードが 読めなくなり、 思わぬ組み合わせで 不具合が出ます - フラグで DB の
変更まで 戻せると思う 戻せるのは コードの 道だけです。 DB は 両方の 道が 動ける 形に しておきます
深掘りの問い
- 「フラグの
値は どこに 置きますか」 配備せずに 変えられる よう、 設定の 置き場や 専用の 仕組みに 置き、 変えた 記録を 残す、と答えます - 「A/B テストと
何が 違いますか」 仕組みは 近いが、 目的が 違う。 安全に 出すための フラグは 全員に 出したら 消し、 A/B テストは どちらが 良いかを 数字で 比べる ために 使う、と答えます - 「フラグの
置き場が 落ちたら」 読めない ときは 閉じた 側 (古い 道) で 動くように 作る、と答えます
