資料工程師的分析 FAQ
範圍 —— 資料工程面試所期待的分析知識,以及如何談自己的分析經驗:「分析經驗」類問題在探什麼、精確定義指標、比率指標與平均陷阱、常見的產品指標、建出讓人信任的指標表(可加總 vs 不可加總的度量、sketch、所有使用者共用同一個定義)、從資料工程師角度看 A/B test(分組指派、曝光紀錄、樣本比例不符、解讀結果)、找出指標變化的根因,以及讓儀表板快速回應。cohort、漏斗與 session 的 SQL 歸
sql_for_data.md;星型模型與語意層歸data_modeling.md。 另見:./sql_for_data.md—— 留存、漏斗、sessionisation 與百分位數查詢;./data_modeling.md—— 語意層裡的粒度、事實與指標定義;./data_performance.md—— 讓儀表板查詢變快;./batch_pipeline.md—— 指標背後那些資料表的資料品質檢查。
資料工程師在面試裡很少被要求跑迴歸,但幾乎一定會被問:你的 pipeline 產出的數字能不能信、 某個指標到底是什麼意思、指標變動時你會怎麼做。這份文件就是回答這些問題所需的詞彙與推理。
0) 簡短回答 優先度 5/5 — 必備 — 幾乎每一輪面試都會出現
「對我來說,分析就是把事件變成讓人據以決策的數字。這代表每個指標都有精確的定義 —— 分子、分母、單位、時間窗與過濾條件 —— 資料表建在正確的粒度上,讓同一個數字在任何地方都用 同一種方式算出來;有資料品質檢查,讓 pipeline 的 bug 永遠不會看起來像業務變化;而當指標 變動時,有一套固定的檢查順序:資料對不對、是不是外部因素、是不是某次上線或實驗,以及是 哪個區隔在動。」
1) DE 面試裡的「分析經驗」指的是什麼 優先度 5/5 — 必備 — 幾乎每一輪面試都會出現
1-1) 面試官在探什麼
「談談你的分析經驗」背後其實是四個問題:你懂不懂業務數字、能不能精確定義它們、能不能 建出正確計算它們的資料表,以及能不能不靠猜測去推理一個變化。
| 他們問的 | 他們在檢查的 | 在哪裡回答 |
|---|---|---|
| 「你的團隊追蹤哪些指標?」 | 你知道每個指標為何存在,而不只是它的名字 | §2 |
| 「DAU 是怎麼定義的?」 | 精確度:時區、去重、機器人、哪些事件算數 | §2-2 |
| 「報表資料表是怎麼建的?」 | 粒度、可加總性、增量建置 | §3 |
| 「你支援過實驗嗎?」 | 分組指派與曝光資料、SRM | §4 |
| 「昨天營收掉了 10% —— 你會怎麼做?」 | 一套方法,從「資料對不對?」開始 | §5 |
| 「儀表板很慢」 | 服務層與預先彙總 | §6 |
1-2) 講一個分析故事
用 STAR(Situation、Task、Action、Result),但讓 Result 是一個數字,讓 Action 跟資料有關: 你修正了哪個定義、建了哪張表、加了哪個檢查。
Situation Marketing and finance reported different "new customer" counts for the same month
(12.4k vs 10.9k), and both numbers were in board slides.
Task Own one definition and make every dashboard use it.
Action - Traced both: marketing counted sign-ups; finance counted first paid orders,
and excluded refunds within 14 days.
- Agreed a written definition with both teams: first paid order, net of refunds.
- Built fct_first_order at one row per customer, incremental by order date,
and moved both dashboards onto it.
- Added a daily reconciliation check against the billing system (alert at > 0.5%).
Result One number in every report; the monthly reconciliation meeting was cancelled;
the check caught a duplicated payment-webhook load two months later.
讓它有說服力的地方:
- 衝突出在定義上,而不是 SQL —— 這通常就是根因。
- Situation 和 Result 裡都有數字。
- Action 點名了一張表、一個粒度和一個檢查 —— 這是資料工程,不是做簡報。
2) 指標 優先度 5/5 — 必備 — 幾乎每一輪面試都會出現
2-1) 指標的種類
每個指標都有一個角色:北極星指標說明產品是否在贏,驅動(輸入)指標是推動它的槓桿, 護欄指標則確保某一項的勝利不會悄悄弄壞別的東西。
| 角色 | 例子(一個交易市集) | 用途 |
|---|---|---|
| 北極星(North star) | 每週完成的訂單數 | 長期方向 |
| 驅動 / 輸入(Driver / input) | 搜尋到下單的轉換率、有庫存的賣家數、配送時間 | 團隊能推動的東西 |
| 護欄(Guardrail) | 退款率、頁面延遲、每筆訂單的客服工單數 | 擋下傷害使用者的「勝利」 |
| 診斷(Diagnostic) | 每個 session 的事件數、各 app 版本的當機率 | 解釋一個變化 |
再依形狀分類,形狀決定了它怎麼彙總:
| 形狀 | 例子 | 彙總方式 |
|---|---|---|
| 計數 / 加總 | 訂單數、營收 | 相加 —— 完全可加總 |
| 相異計數(distinct count) | 每日活躍使用者 | 重新計算或合併 sketch —— 不可加總 |
| 比率 | 轉換率、平均訂單金額 | 用總和相除,絕不平均各比率 |
| 分佈 | p50 / p95 配送時間 | 從明細重新計算或合併 sketch |
2-2) 精確定義一個指標
直到別人只憑定義就能算出完全相同的數字,一個指標才算定義完成;大多數「數字對不上」的 事件是兩個定義,而不是一個 bug。
每個定義都要回答的檢查清單:
| 要素 | 問題 | 以 DAU 為例 |
|---|---|---|
| 實體 | 數的是什麼? | 相異的 user_id(已登入)—— 不是裝置 |
| 合格事件 | 哪些行為算數? | 任何前景 app 事件;推播送達不算 |
| 時間窗 | 哪一天? | UTC 的日曆日(或業務的報表時區 —— 講明是哪個) |
| 過濾條件 | 排除誰? | 內部帳號、測試使用者、已知機器人 |
| 去重 | 什麼算一個? | 一位使用者每天跨平台只算一次 |
| 遲到資料 | 數字何時定案? | 06:00 為暫定,再等 3 天遲到事件後定案 |
| 負責人 | 誰決定變更? | 產品分析團隊,在指標層裡做版本控管 |
-- DAU, written so the definition is visible in the query
SELECT
DATE(event_ts) AS activity_date, -- event_ts stored in UTC
COUNT(DISTINCT user_id) AS dau
FROM events
WHERE is_foreground = TRUE -- foreground app events only
AND user_id IS NOT NULL -- logged-in users only
AND NOT EXISTS (SELECT 1 FROM internal_users i -- staff and test accounts
WHERE i.user_id = events.user_id) -- (NOT IN breaks on a NULL id)
AND NOT EXISTS (SELECT 1 FROM known_bots b -- known bots
WHERE b.user_id = events.user_id)
GROUP BY DATE(event_ts);
2-3) 比率指標與平均陷阱
跨群組的比率是分子總和除以分母總和;把各群組的比率拿來平均,會讓極小的群組和極大的 群組權重相同,得到一個不同、而且通常是錯的答案。
orders visits conversion
Mobile 900 30,000 3.0%
Desktop 100 500 20.0%
Average of ratios: (3.0% + 20.0%) / 2 = 11.5% ← wrong
Ratio of sums: (900 + 100) / 30,500 = 3.3% ← the site's conversion rate
-- Store the numerator and denominator; divide only at the end
SELECT
SUM(orders) * 1.0 / NULLIF(SUM(visits), 0) AS conversion_rate
FROM daily_platform_stats
WHERE stat_date BETWEEN DATE '2026-11-01' AND DATE '2026-11-07';
- 資料表應該存分子與分母,而不是預先算好的比率,這樣任何 rollup 都保持正確 —— 前提是兩者在該 rollup 上都可加總。由 distinct count 組成的比率(stickiness、一週內轉換的使用者 ÷ 活躍使用者)必須先在目標粒度重新計算各個計數(見 §3-2)。
- 辛普森悖論(Simpson’s paradox):一個比率可能在每個區隔都上升、整體卻下降,因為 **組成(mix)**轉向了比率較低的區隔 —— 比率變動時一定要檢查組成(見 §5-2)。
2-4) 常見的產品指標
| 指標 | 定義 | 要注意的 |
|---|---|---|
| DAU / WAU / MAU | 一天 / 7 天 / 28–30 天內的相異活躍使用者(日 / 週 / 月活躍使用者) | MAU 不是 DAU 的總和;時間窗必須固定 |
| 黏著度(Stickiness) | DAU ÷ MAU | 兩個相異計數的比率 —— 各自算好再相除 |
| N 日留存 | 第 0 天開始的使用者中,第 N 天仍活躍的比例 | 「在第 N 天」(經典)與「在第 N 天或之後」(unbounded)會得到不同曲線 |
| 流失(Churn) | 上一期活躍使用者中,這一期沒有活躍的比例 | 先定義「活躍」與期間 |
| 轉換率 | 完成目標的使用者(或 session)÷ 進入該步驟的使用者 | 使用者層級與 session 層級的計數不同 |
| ARPU | 營收 ÷ 期間內活躍使用者(每使用者平均營收) | 分母裡是哪些使用者? |
| AOV | 營收 ÷ 訂單數(平均訂單金額) | 高度偏態 —— 同時報告中位數 |
| LTV | 每位使用者在其生命週期內的預期營收(顧客終身價值) | 是一個模型而不是計數 —— 講明時間範圍與假設 |
留存 cohort 與漏斗的 SQL 在
./sql_for_data.md §7-8 與
§7-9。
3) 建出讓人信任的指標表 優先度 5/5 — 必備 — 幾乎每一輪面試都會出現
3-1) 從事件到指標的分層
指標從宣告了粒度的事實計算出來,並且只沿著數學上安全的路徑 rollup —— 所以不管哪個 儀表板來問,算出來的都是同一個數字。
raw events ──► cleaned events ──► facts at a grain ──► daily aggregates ──► metrics layer ──► dashboards
(bronze) (silver) fct_orders agg_daily_country one definition BI, notebooks
one row per order one row per per metric
day × country
- 在每張表的名稱或文件裡宣告它的粒度:每筆訂單一列、每位使用者每天一列。
- 在彙總表裡存可加總的度量(計數、總和)以及比率的組成部分。
- 依日期分區做增量建置,讓遲到資料只重新處理受影響的那幾天。
3-2) 不可加總的指標:跨天的相異使用者
相異計數不能相加:本週活躍的使用者數不等於每天 DAU 的總和,因為同一位使用者每天都被 算一次。要從明細重新計算,或每天存一個可合併的 sketch。
-- Wrong: sums daily distinct counts — a user active on 5 days counts 5 times
SELECT SUM(dau) AS wau_wrong
FROM agg_daily_active
WHERE activity_date BETWEEN DATE '2026-11-01' AND DATE '2026-11-07';
-- Exact: recompute from the detail table
SELECT COUNT(DISTINCT user_id) AS wau
FROM fct_user_activity_daily
WHERE activity_date BETWEEN DATE '2026-11-01' AND DATE '2026-11-07';
-- Approximate and cheap (BigQuery): store a HyperLogLog++ sketch per day, merge any range
CREATE TABLE agg_daily_active_sketch AS
SELECT activity_date, HLL_COUNT.INIT(user_id) AS users_sketch
FROM fct_user_activity_daily
GROUP BY activity_date;
SELECT HLL_COUNT.MERGE(users_sketch) AS wau_approx
FROM agg_daily_active_sketch
WHERE activity_date BETWEEN DATE '2026-11-01' AND DATE '2026-11-07';
中位數與百分位數也一樣:每日中位數的中位數不是本週的中位數。保留明細,或保留可合併的 分位數 sketch(t-digest、KLL)。
3-3) 一個定義,多個使用者
當每個儀表板都自己寫「營收」的 SQL,數字就會漂移;每個指標只定義一次 —— 在語意層、 dbt metrics 或受治理的 view 裡 —— 並讓儀表板讀它。
- 對指標定義做版本控管;定義變更要公告並標上日期,歷史資料要嘛重算、要嘛加註。
- 為每個指標指定負責人 —— 由這個人裁決邊界情況。
- 把定義放在程式碼旁邊(指標層裡的 YAML、view 上的 doc string),而不是放在投影片裡。
這件事的建模面 —— 一致性維度與語意層 —— 在
./data_modeling.md §9-3。
3-4) 指標的資料品質檢查
pipeline 的 bug 絕不能被報告成業務變化,所以指標背後的資料表都帶著檢查,在儀表板更新 之前就失敗或發出警告。
| 檢查 | 抓到的問題 |
|---|---|
| 新鮮度 —— 最新分區在 06:00 前載入 | 卡住的 job 被報告成「零銷售」 |
| 量 —— 今天的列數落在這個星期幾的正常範圍內 | 部分載入、重複載入 |
| 粒度鍵的唯一性 | fan-out join 讓營收翻倍 |
| 與記錄系統(帳單、總帳)對帳 | 無聲的遺漏或重複計算 |
分佈 —— 每個維度中 NULL / unknown 的比例 |
上游欄位壞掉 |
把這些檢查寫成 SQL 的模式在
./sql_for_data.md §7-16。
4) 資料工程師的 A/B 測試 優先度 4/5 — 高價值 — 這裡有缺口就會掉關
4-1) 一個實驗的資料路徑
實驗就是一條資料 pipeline:分組指派決定變體,曝光紀錄記下誰真的看到了它,指標表計算 每位使用者的結果,分析再比較各組 —— 而大多數壞掉的實驗壞在前兩步,不是統計。
assignment ──► exposure log ──► join to metric facts ──► per-user outcomes ──► analysis
hash(user, user saw the by user_id, from one row per user lift, CI,
experiment) variant at ts exposure time onward per variant SRM check
4-2) 資料工程師負責什麼
確定性的分組指派、可靠的曝光紀錄,以及從曝光那一刻起、按隨機化單位計算的指標。
- 分組指派是使用者與實驗的雜湊,所以它跨 session 保持穩定,也不需要查找表:
import hashlib
def assign_variant(user_id: str, experiment: str, treatment_share: float = 0.5) -> str:
"""Same user + same experiment always gives the same variant."""
key = f"{experiment}:{user_id}".encode("utf-8")
bucket = int(hashlib.sha256(key).hexdigest()[:8], 16) % 10_000 # 0..9999
return "treatment" if bucket < treatment_share * 10_000 else "control"
print(assign_variant("user_42", "checkout_v2")) # stable on every call
- 把實驗名稱放進雜湊,讓不同實驗彼此獨立 —— 否則同一批使用者永遠一起落在實驗組。
- 先看指派,謹慎看曝光:安全的整體比較是所有被指派的使用者。只看真正到達被改動畫面的使用者,可以去掉從未看到改動者造成的稀釋,但只有在兩組的觸發條件相同時才沒有偏誤 —— 在對照組也記錄觸發點(反事實紀錄,counterfactual logging),並確認各變體的觸發比例一致。如果變體本身改變了誰會到達該畫面,就依指派來分析。
- 隨機化單位 = 分析單位:按使用者隨機化,就按使用者各算一個值。在按使用者隨機化時把 每次頁面瀏覽當成獨立,會高估顯著性。
- 指標對分析中的每個人都從一個共同的起點開始算:依指派分析時用指派時間 —— 包含所有被指派的使用者,從未曝光的人也算,以零活動計入 —— 觸發式分析則用觸發時間(兩組都要記錄)。在那之前的事件不可能是變體造成的。
4-3) 樣本比例不符
如果分流是 50/50,而在大樣本上各組是 50.8/49.2,那就有東西壞了 —— 分組指派、紀錄、某個 重新導向或機器人過濾 —— 在原因被解釋之前,結果都不能信。
def srm_chi_square(control: int, treatment: int, expected_treatment_share: float = 0.5) -> float:
"""Chi-square statistic for observed vs expected group sizes (1 degree of freedom)."""
total = control + treatment
expected_treatment = total * expected_treatment_share
expected_control = total - expected_treatment
return ((control - expected_control) ** 2 / expected_control
+ (treatment - expected_treatment) ** 2 / expected_treatment)
stat = srm_chi_square(control=50_800, treatment=49_200)
print(round(stat, 1)) # 25.6
# Critical values at 1 df: 3.84 (p = 0.05), 10.83 (p = 0.001).
# Teams flag SRM at a strict threshold such as p < 0.001 — 25.6 is far past it.
常見原因:某個變體會當機或載入較慢,所以記到的曝光較少;機器人過濾從某一邊移除了較多 使用者;曝光只在某一個變體的程式路徑上被記錄。
4-4) 解讀結果
用信賴區間報告效果,而不只是 p-value;開始前就決定樣本數;不要在第一天看起來顯著時就 停止測試。
from math import erf, sqrt
def two_proportion_z_test(conv_a: int, n_a: int, conv_b: int, n_b: int) -> tuple:
"""Return (absolute lift, z, two-sided p-value) for conversion B vs A."""
p_a, p_b = conv_a / n_a, conv_b / n_b
pooled = (conv_a + conv_b) / (n_a + n_b)
standard_error = sqrt(pooled * (1 - pooled) * (1 / n_a + 1 / n_b))
z = (p_b - p_a) / standard_error
p_value = 2 * (1 - 0.5 * (1 + erf(abs(z) / sqrt(2))))
return p_b - p_a, z, p_value
lift, z, p = two_proportion_z_test(conv_a=1_000, n_a=20_000, conv_b=1_100, n_b=20_000)
print(f"lift={lift:.4f} z={z:.2f} p={p:.3f}") # lift=0.0050 z=2.24 p=0.025
| 概念 | 一句話 |
|---|---|
| p-value | 如果其實沒有真正差異,這份資料會有多令人意外 |
| 信賴區間 | 與資料相符的效果範圍 —— 該報告的就是它 |
| 檢定力 / MDE | 在該樣本數下測試能可靠偵測的最小效果(最小可偵測效果);事先定好 |
| 偷看(Peeking) | 每天檢查、在第一次 p < 0.05 時就停止,會讓偽陽性膨脹 |
| 多重比較 | 20 個指標各用 p < 0.05,大約會出現一個假的「勝利」 |
| 新奇效應 | 使用者對任何新東西都會有反應;早期的提升常會消退 |
| 網路效應 | 在交易市集或社交圖裡,實驗組使用者會影響對照組使用者 —— 改以群集或地區隨機化 |
5) 找出指標變化的根因 優先度 5/5 — 必備 — 幾乎每一輪面試都會出現
5-1) 檢查的順序
「昨天營收掉了 10%」:先證明資料是對的,再排除日曆因素,接著找你上線了什麼,然後找出 是哪個區隔在動 —— 到這時才提出關於使用者的假設。
| 步驟 | 問題 | 怎麼做 |
|---|---|---|
| 1 | 資料對嗎? | 新鮮度與量的檢查;是不是有 job 失敗、跑了兩次或只載入一部分?和來源系統比對 |
| 2 | 定義變了嗎? | 指標或程式碼變更、新的過濾條件、時區切換 |
| 3 | 是日曆因素嗎? | 上週同一個星期幾、假日、發薪日、季節 |
| 4 | 是外部因素嗎? | 金流供應商故障、競爭對手促銷、新聞 |
| 5 | 是我們自己嗎? | 上線、實驗放量、行銷活動結束、價格調整 |
| 6 | 哪個區隔? | 依平台、app 版本、國家、管道、新舊使用者切分 |
| 7 | 指標的哪個部分? | 拆解:營收 = 使用者數 × 轉換率 × 每位買家訂單數 × AOV |
面試官等著你踩的陷阱:直接跳到第 6 步、講一個關於使用者行為的故事,而真正的原因其實是 一個只載入一半的分區。
5-2) 拆解變化:比率 vs 組成
總數會變,要嘛是某個區隔的比率變了,要嘛是各區隔的組成變了 —— 在怪罪任何一個區隔之前, 先把變化拆成這兩部分。
-- Conversion by platform, this week vs last week: did a rate move, or the mix?
WITH by_platform AS (
SELECT
platform,
SUM(CASE WHEN week = 'this' THEN visits ELSE 0 END) AS visits_this, -- 0, not NULL, when a
SUM(CASE WHEN week = 'last' THEN visits ELSE 0 END) AS visits_last, -- platform is new or gone
SUM(CASE WHEN week = 'this' THEN orders ELSE 0 END) AS orders_this,
SUM(CASE WHEN week = 'last' THEN orders ELSE 0 END) AS orders_last
FROM weekly_platform_stats
GROUP BY platform
)
SELECT
platform,
orders_last * 1.0 / NULLIF(visits_last, 0) AS rate_last,
orders_this * 1.0 / NULLIF(visits_this, 0) AS rate_this,
visits_last * 1.0 / NULLIF(SUM(visits_last) OVER (), 0) AS mix_last,
visits_this * 1.0 / NULLIF(SUM(visits_this) OVER (), 0) AS mix_this
FROM by_platform
ORDER BY platform;
怎麼解讀:
- 比率持平、組成移動(例如某個活動帶來大量低轉換的行動裝置訪客)—— 總數下降,但沒有 任何區隔變差。沒有東西壞掉。
- 某個比率下降、組成持平 —— 去看那個區隔:那個平台上的某次上線、那個國家某個壞掉的 付款方式。
6) 儀表板與服務層 優先度 4/5 — 高價值 — 這裡有缺口就會掉關
6-1) 儀表板從哪裡讀資料
讓儲存配合儀表板所需的新鮮度與並發量:內部每日報表用資料倉儲,觀看者多時用 extract 或快取,次秒級、面向使用者的分析則用即時 OLAP 儲存。
| 選項 | 延遲 / 新鮮度 | 並發量 | 適合 |
|---|---|---|---|
| BI 直接查資料倉儲(BigQuery、Snowflake、Redshift) | 秒級;新鮮度等於最後一次載入 | 數十位使用者 | 內部每日報表 |
| BI extract / 快取 | 快;在刷新前是舊的 | 數百 | 高階主管儀表板 |
| 資料倉儲裡的預先彙總表 | 快;每次載入的新鮮度 | 數百 | 慢儀表板的標準解法 |
| 即時 OLAP(Druid、Pinot、ClickHouse) | 次秒級;數秒的新鮮度 | 數千 | 面向使用者的分析、即時營運 |
| 計算結果的 key-value 快取(Redis) | 毫秒級 | 非常高 | 產品裡一組固定的數字 |
6-2) 讓儀表板又快又便宜
- 讓每個儀表板指向一張粒度與它顯示的粒度相同的預先彙總表 —— 每日 × 國家,而不是原始 事件。
- 依日期分區,並讓儀表板的日期過濾成為必填,讓每個查詢都能剪枝。
- 增量刷新 —— 刷今天的分區,加上遲到資料仍可能改變的那幾天(以 §2-2 的 DAU 定義來說是三天),而不是整段歷史。
- 對任意範圍的使用者計數,使用近似相異計數或 sketch。
- 盯著最昂貴的儀表板查詢(資料倉儲的查詢歷史)—— 通常少數幾個圖塊就佔了大部分成本。
引擎端的槓桿在 ./data_performance.md §3。
7) 分析型 SQL 工具箱 優先度 4/5 — 高價值 — 這裡有缺口就會掉關
DE 面試裡的分析題通常就是少數幾種 SQL 模式;每一種都在 sql_for_data.md
裡完整推導過。
| 業務問題 | 模式 | 在哪裡 |
|---|---|---|
| 「每個類別的前 3 名商品」 | 每組 ROW_NUMBER() |
§7-1 |
| 「本月累計營收」 | 帶 frame 的 window SUM |
§7-3 |
| 「月增長率」 | 跨月的 LAG() |
§7-4 |
| 「最長連續登入天數」 | gaps and islands | §7-5 |
| 「從原始點擊切出 session」 | 以 30 分鐘間隔做 sessionisation | §7-7 |
| 「依註冊 cohort 的每週留存」 | cohort × 期間矩陣 | §7-8 |
| 「使用者在哪裡流失?」 | 有順序步驟的漏斗 | §7-9 |
| 「配送時間中位數」 | PERCENTILE_CONT |
§7-10 |
8) 快問快答 優先度 4/5 — 高價值 — 這裡有缺口就會掉關
| 問題 | 答案 |
|---|---|
| 能把每日活躍使用者加總得到每週活躍使用者嗎? | 不行 —— 相異計數不可加總;要重新計算或合併 sketch |
| 各國轉換率的平均? | 不行 —— 用分子總和除以分母總和 |
| 每個區隔的比率都上升、整體卻下降 —— 怎麼會? | 組成移動(辛普森悖論):流量移向了比率較低的區隔 |
| 指標下降 —— 第一步? | 檢查資料:新鮮度、量、失敗或重複的載入 |
| 資料工程師在 A/B test 裡負責什麼? | 確定性的分組指派、曝光紀錄、每位使用者的指標表、SRM 檢查 |
| 什麼是樣本比例不符(SRM)? | 各組大小與計畫的分流相差超出機率能解釋的範圍 —— 代表分組指派或紀錄壞了 |
| 為什麼要把實驗名稱放進分組雜湊? | 讓不同實驗的分組彼此獨立 |
| 為什麼不在 p < 0.05 一出現就停止測試? | 偷看會讓偽陽性膨脹;事先定好樣本數 |
| 怎麼讓儀表板不再互相矛盾? | 每個指標一個受治理的定義,有負責人,所有儀表板都讀它 |
| 怎麼讓慢的儀表板變快? | 一張符合其粒度的預先彙總表,依日期分區,增量刷新 |
| 北極星 vs 護欄? | 北極星說明你是否在贏;護欄抓出傷害其他東西的勝利 |