ByteDance's 2026 OA bundles TikTok, Douyin, Lark, Doubao, CapCut, Volcano Engine and other product lines under the same CodeSignal Industry Coding question bank — meaning whether you applied for a North America SDE Intern slot or a Singapore DataEng role, the question type distribution you hit is highly homogeneous. However, the OA setters and the onsite interviewers come from different BUs, so even with identical question text, "the optimal solution the interviewer is mentally expecting" gets micro-tuned per BU.
This post does not repeat the "questions + solutions" checklist (a dedicated retro post already exists). Instead, standing on the past-candidate and review side, it walks through the 5 Top question categories, giving for each: category overview → high-frequency real question + full Python solution → interviewer follow-up angles → scoring rubric. At the end you'll find BU differences, score distribution, and FAQ.
ByteDance OA Overview
| Dimension | Details |
|---|---|
| Platform | CodeSignal Industry Coding (NA / Singapore / UK); domestic uses Nowcoder / internal OJ |
| Duration | 70 minutes (NA), 100–120 minutes (domestic) |
| Volume | 4 questions (CodeSignal) / 3–4 questions (domestic) |
| Difficulty | LC Easy ~ Medium (occasional Medium-Hard closer) |
| Scoring | Partial test-case credit, not all-or-nothing; 800 / 600 are common cutoffs |
| Anti-cheat | Tab-switching is logged; from 2026, random webcam snapshots are added (select BUs) |
Key tip: NA and Singapore share ~70% of the question bank, and within the same week the repeat rate hits 40%, so 1point3acres weekly threads are extremely valuable for OA.
Top Category 1: Dynamic Programming (DP, ~28%)
Category overview
ByteDance OA DP leans toward 1D / 2D state, with the focus on the speed of "recognize state + write transition". Common wrappers: path counting, string matching, optimal partitioning, knapsack variants. Tree DP and bitmask DP almost never appear, but from 2026-Q1 we are starting to see 2D DP with constraints (e.g., "number of grid paths with at most k ones per row").
High-frequency real question: Maximum square with blockers
Given a 0/1 grid, find the largest square area made entirely of 1s; cells marked 2 mean "any submatrix containing them is invalid".
def max_square_with_blockers(grid):
R, C = len(grid), len(grid[0])
# 先按 blocker 标记不可用区域
blocked = [[False] * C for _ in range(R)]
for r in range(R):
for c in range(C):
if grid[r][c] == 2:
for dr in range(R):
for dc in range(C):
if dr <= r and dc <= c:
blocked[r][c] = True # 简化版
dp = [[0] * C for _ in range(R)]
best = 0
for r in range(R):
for c in range(C):
if grid[r][c] != 1 or blocked[r][c]:
continue
if r == 0 or c == 0:
dp[r][c] = 1
else:
dp[r][c] = min(dp[r-1][c], dp[r][c-1], dp[r-1][c-1]) + 1
best = max(best, dp[r][c])
return best * best
Time complexity: O(R·C), space O(R·C).
Interviewer follow-up angles
- Space optimization: Can you compress to an O(C) 1D array? (must-answer)
- Blocker semantics change: If
2becomes "semi-transparent" — allowed inside but area gets multiplied by 0.5 — how would you adjust? (state extensibility) - Very large n×m (10⁵ × 10⁵): DP is insufficient; how would you approximate? (mention blocking / sampling)
Scoring rubric
| Performance | Score |
|---|---|
| Writes naive O(R²C²); fails large test cases | < 40% |
| Writes O(RC) DP, AC on most cases | 70–85% |
| Adds space optimization + clear edge cases (empty grid / single row) | 90%+ |
Top Category 2: Sliding Window (~22%)
Category overview
ByteDance sliding window questions "look like LC Easy but stack 3 layers of conditions" — e.g., "longest substring such that a appears at least k times and b appears at most m times". Core check: did you use while shrink + Counter maintenance, instead of nested-for brute force?
High-frequency real question: Longest substring with at most K distinct chars (weighted)
Each character carries a weight; the substring must have "distinct-char count ≤ K"; output the maximum weight sum for a qualifying substring.
from collections import Counter
def longest_weighted_window(s, weights, K):
"""
s: 字符串
weights: dict, weights[c] 为字符 c 的权重
K: 允许的不同字符种类上限
返回: 满足条件的最大权重和
"""
cnt = Counter()
left = 0
cur_weight = 0
best = 0
for right, ch in enumerate(s):
cnt[ch] += 1
cur_weight += weights.get(ch, 0)
while len(cnt) > K:
lc = s[left]
cnt[lc] -= 1
cur_weight -= weights.get(lc, 0)
if cnt[lc] == 0:
del cnt[lc]
left += 1
best = max(best, cur_weight)
return best
Time complexity: O(n), space O(K).
Interviewer follow-up angles
- Negative weights: when weights can be negative, monotonic shrink breaks — how to fix? (need prefix sum + monotonic deque)
- K very large (≈ alphabet size): the window degenerates to the full string; is it still meaningful?
- Streaming input: if s is an infinite stream, how would you maintain incrementally?
Scoring rubric
| Performance | Score |
|---|---|
| Brute force O(n²) | 50–60% |
| Standard sliding window O(n) | 80–90% |
| Adds "negative weights" note or answers a follow-up | 95%+ |
Top Category 3: Graph / BFS (~20%)
Category overview
ByteDance graph OA leans toward grid BFS / multi-source BFS / topological sort; shortest path is rarely tested (Dijkstra appears in < 5%). The focus is "multiple sources diffusing simultaneously" — TikTok's "viral spread" / "recommendation chain" wrappers show up especially often.
High-frequency real question: Multi-source BFS — distance to nearest "supply point"
Given an m×n grid, 1 is an obstacle, 2 is a supply point (multiple), 0 is empty space. Compute the shortest distance from every empty cell to its nearest supply point; unreachable cells are filled with -1.
from collections import deque
def nearest_supply(grid):
R, C = len(grid), len(grid[0])
INF = float("inf")
dist = [[INF] * C for _ in range(R)]
q = deque()
for r in range(R):
for c in range(C):
if grid[r][c] == 2:
dist[r][c] = 0
q.append((r, c))
while q:
r, c = q.popleft()
for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)):
nr, nc = r + dr, c + dc
if 0 <= nr < R and 0 <= nc < C and grid[nr][nc] != 1:
if dist[nr][nc] > dist[r][c] + 1:
dist[nr][nc] = dist[r][c] + 1
q.append((nr, nc))
return [[-1 if v == INF else v for v in row] for row in dist]
Time complexity: O(R·C), space O(R·C).
Interviewer follow-up angles
- Weighted edges: if traversal cost differs per empty cell, BFS isn't enough — would you switch to 0-1 BFS or Dijkstra?
- Dynamic sources: supply points are added/removed dynamically; re-running BFS is too slow — how to maintain incrementally?
- k-nearest: required is the sum of distances to the "k nearest supply points" for each empty cell.
Scoring rubric
| Performance | Score |
|---|---|
| Single-source BFS run | V |
| Single-pass multi-source BFS | 85–95% |
| Mentions 0-1 BFS or incremental maintenance | 95%+ |
Top Category 4: String Processing / Parsing (~18%)
Category overview
ByteDance "string questions" rarely test KMP / Z-algo; 90% are simulation + state machine. Common wrappers: log parsing, nested brackets, version-number comparison, emoji / Unicode splitting (this is a TikTok specialty due to multilingual product needs).
High-frequency real question: Nested curly-brace variable substitution
Input "Hello {name}, your balance is {amount} {currency}" plus a dict; output the substituted string. Supports nesting: {a_{idx}} should first resolve the inner {idx} and then the outer.
def render_template(tpl, ctx):
while "{" in tpl:
# 找最内层 {...}(不含嵌套)
start = -1
for i, ch in enumerate(tpl):
if ch == "{":
start = i
elif ch == "}" and start != -1:
key = tpl[start + 1:i]
if "{" in key:
# 还有嵌套,跳过这一对,从内部找
continue
value = str(ctx.get(key, ""))
tpl = tpl[:start] + value + tpl[i + 1:]
break
else:
break
return tpl
Time complexity: worst O(n²) (nesting depth = O(n)), typical O(n).
Interviewer follow-up angles
- Variable value contains
{: will the substitution trigger a second pass of parsing? (edge-case trap) - Circular references:
{a}→{b},{b}→{a}— how do you detect and raise an error? - i18n: if the template contains emoji and CJK, should the slicing be done by grapheme rather than by byte?
Scoring rubric
| Performance | Score |
|---|---|
| Single-layer substitution correct | 60% |
| Nested parsing + missing-key fallback | 80% |
| Handles circular references / Unicode | 95%+ |
Top Category 5: Simulation + Heap / Greedy (~12%)
Category overview
ByteDance "simulation problems" are characterized by long descriptions, many states, business-flavored — battery scheduling, order matching, live-stream danmaku rate limiting, ad-bidding queues. The exam point is not the algorithm itself but whether you can translate the problem statement into a clean state machine. Average length is 600+ words for this category; many candidates get stuck here not because they can't code it, but because they didn't fully parse the problem.
High-frequency real question: Streaming order matching (simplified)
A stream of buy / sell orders arrives; matching rules:
- Match when sell price ≤ buy price
- At equal prices, time-ordered first-come-first-matched
- Output the trade price (= seller's posted price) and quantity for each match
import heapq
def match_orders(orders):
"""
orders: [(t, side, price, qty)], side ∈ {"B","S"}
返回: [(成交时间, 成交价, 数量)]
"""
buys = [] # max-heap, 用 -price 实现
sells = [] # min-heap
trades = []
seq = 0
for t, side, price, qty in orders:
seq += 1
if side == "B":
heapq.heappush(buys, (-price, seq, qty))
else:
heapq.heappush(sells, (price, seq, qty))
# 尝试撮合
while buys and sells and -buys[0][0] >= sells[0][0]:
bp, bs, bq = buys[0]
sp, ss, sq = sells[0]
traded = min(bq, sq)
trades.append((t, sp, traded))
heapq.heappop(buys); heapq.heappop(sells)
if bq > traded:
heapq.heappush(buys, (bp, bs, bq - traded))
if sq > traded:
heapq.heappush(sells, (sp, ss, sq - traded))
return trades
Time complexity: O(n log n), space O(n).
Interviewer follow-up angles
- Tie-breaking at equal price: if the rule changes to "prioritize larger quantity", how do you adjust the heap key?
- Cancellation: users can send "cancel order id" — heap doesn't support random removal; what data structure would you use? (lazy deletion / SortedList)
- Fairness: if 1000 orders arrive simultaneously, is your implementation fair? (batch processing vs FIFO)
Scoring rubric
| Performance | Score |
|---|---|
| Sort-based simulation O(n²) | 40–55% (large cases TLE) |
| Two-heap O(n log n) | 80–90% |
| Handles cancellation + partial fills + explains lazy deletion | 95%+ |
OA Differences Across Roles
ByteDance has many internal BUs; OA question text is shared but the topic weights differ. Past-candidate observations:
| Role / BU | Heavy-weight categories | Light categories | Duration |
|---|---|---|---|
| TikTok SDE (NA) | Sliding window + graph BFS + string | DP (~1 question) | 70 min |
| Douyin SDE (domestic) | DP + simulation + data structures | Strings relatively rare | 100 min |
| Lark SDE | Simulation (collaboration conflicts) + graph | Sliding window less common | 90 min |
| Data Engineer | SQL-to-Python + streaming aggregation | Algorithm — only 1 question | 90 min |
| ML / Algorithm | Probability + math + DP | Less simulation | 90 min |
| CapCut / Video | 2D DP + geometric simulation | No SQL | 70 min |
Key observation: DataEng OAs frequently ask "write an aggregation in Python equivalent to a given SQL" — simpler than SDE, but the trap is NULL handling.
Real Score Distribution from Our Students
We collected feedback from 60+ students on the ByteDance CodeSignal OA during 2026-Q1:
| Score band | Student share | Subsequent onsite rate |
|---|---|---|
| 900–1000 (perfect) | 8% | ~95% |
| 800–899 | 22% | ~75% |
| 700–799 | 31% | ~50% (cutoff zone) |
| 600–699 | 24% | ~20% |
| < 600 | 15% | ~5% |
Key findings:
- 800 is the de-facto cutoff: in NA, TikTok / Lark new-grad onsite invitations basically start at 800;
- Getting partial cases on Q4 (last question) beats fully solving Q3 — score weights ramp up per question;
- 70% of students get blocked on time, not on difficulty: 80% claim "10 more minutes and I'd AC" — so pacing matters more than grinding hard problems;
- Second attempts gain ~150 points: after fully digesting mistakes from the prior OA, average gain is 150 (700 → 850).
FAQ
Q1: Can I just grind 1point3acres high-frequency to pass ByteDance OA?
Partly true. CodeSignal repeat rate is 30–40%, but from 2026-Q2 ByteDance has been injecting new questions more frequently, about 1–2 per week. So the "pure grinding" pass rate dropped from ~75% in 2025 to ~55% in 2026. Recommend grinding + timed mocks in parallel.
Q2: How soon after OA do I hear about onsite?
NA: 1–2 weeks; domestic: 3–7 days; Singapore: typically 2 weeks. If you score 850+ in the same week and your resume matches the BU, HR will reach out within 3 business days. If 14 days pass with no word, a proactive follow-up email beats waiting silently.
Q3: How strict is CodeSignal's anti-cheat?
Tab-switches are logged (not auto-fail, but visible to HR); from 2026 TikTok / Doubao add random webcam snapshots, once every 5–10 minutes. Prohibited: second monitor, third-party IDE, other people in the room (multi-face triggers warnings). Do it in a clean environment, one shot.
Q4: Python or C++? TLE risk on ByteDance OA?
95% of questions won't TLE in Python — because ByteDance n caps usually at ≤ 10⁵. But streaming / simulation questions can still TLE if you overuse list.pop(0) or O(n²) string concatenation. Recommend: use collections.deque, avoid += for strings, use sys.stdin for input.
Q5: How long after failing OA can I reapply? Does cross-BU count as re-applying?
Official policy: 6-month cooldown. In practice: on the NA side, 3 months is enough to re-apply to the same BU (HR rarely enforces strictly); cross-BU does not count toward the cooldown at all — so failing TikTok and applying to Lark a month later is a common move. However: before going cross-BU, debrief the weaknesses of your previous OA; otherwise you're just changing the wrapper.
Preparing for ByteDance / TikTok / Lark / Doubao OA?
ByteDance 2026 OA question-bank turnover is accelerating; pure grinding isn't enough — the key is to fully connect "question category → interviewer follow-up → scoring rubric". We've collected this-week high-frequency questions across 6 ByteDance BUs in 2026, plus timed mocks, mistake debriefs, real-time OA assistance, and VO mock interviews.
Add WeChat Coding0201 now, get the ByteDance OA question bank.
Contact
- WeChat: Coding0201
- Email: [email protected]
- Telegram: @OAVOProxy