Điều chỉnh tiêu chí
Cần ứng viên từng duy trì codebase lớn, lập trình/scripting tốt, kể được vấn đề kỹ thuật cụ thể và đóng góp cá nhân.
Senior Software Engineer / Infrastructure
Một trang để nắm bức tranh tuyển dụng, câu hỏi đã gặp, phong cách Nate và Phil, checklist chuẩn bị, bài live coding và câu trả lời tiếng Anh ngắn gọn.
Tóm tắt nhanh
Quy trình đã đổi vì nhiều ứng viên không hiểu code mình nộp, dùng AI hoặc không giải thích rõ dự án. Vòng 1 hiện rút còn 40 phút, tập trung live coding trực tiếp. Candidate yếu tiếng Anh có thể bị kết thúc sớm.
Điểm thắng là trình bày kinh nghiệm sâu trên codebase lớn, duy trì lâu dài, có ví dụ thực tế về CI/CD, AWS, Docker, monitoring, migration và scripting.
Cần ứng viên từng duy trì codebase lớn, lập trình/scripting tốt, kể được vấn đề kỹ thuật cụ thể và đóng góp cá nhân.
Kiến trúc dự án, migration monolith sang microservices, CI/CD GitHub/Jenkins, EC2, deploy image, monitoring, S3, Docker multi-stage.
FizzBang, unit tests, SQL aggregation, walkthrough CPU logger/analyzer, memory, sampling, file buffering.
Chuyển sang live coding trong phỏng vấn. AI/tool ngoài màn hình là red flag tức thì.
Hiring manager, vòng 1
Cách thắng: kể câu chuyện cụ thể, có trade-off và kết quả đo được.
Technical interviewer, vòng 2
pkrasko khớp LinkedIn/GitHub; LinkedIn ghi Director of Engineering tại VMware, San Francisco, mô tả seasoned developer/manager.Cách thắng: code sạch, test ngay, giải thích từng dòng và impact khi thay đổi.
Client contact
Nếu gặp onsite: chuyên nghiệp, ngắn gọn, có cấu trúc.
Maigret clean run: dùng --no-recursion --no-extracting -n 10; chỉ giữ tín hiệu public có khả năng liên quan cao, loại các username bị extract nhầm như zznate, nx, Nate Erickson.
Câu hỏi lõi
In mỗi số theo format n: EVEN/ODD, thêm BANG nếu chia hết cho 7.
def fizz_bang(start, end):
return [
f"{n}: {'EVEN' if n % 2 == 0 else 'ODD'}" + (" BANG" if n % 7 == 0 else "")
for n in range(start, end + 1)
]Test cần có: odd, even, 7, 14, boundary.
Đếm device theo state, platform, model. Sort state A-Z, count giảm dần trong mỗi state.
SELECT
u.state,
d.platform,
d.model,
COUNT(*) AS total_device_count
FROM device d
JOIN user u ON u.user_id = d.user_id
GROUP BY u.state, d.platform, d.model
ORDER BY u.state ASC, total_device_count DESC;psutil.cpu_percent(interval=1) đã block 1 giây, sleep thêm 59 giây để chu kỳ gần 60 giây.csv.reader/DictReader streaming, không dùng readlines() hoặc pandas nếu không cần.“Before I start coding, let me clarify the requirements. You want me to iterate from startNumber to endNumber inclusively, print whether each number is even or odd, and append BANG if it is divisible by seven, correct?”
“My specific contribution was designing and implementing the deployment workflow. I wrote the GitHub Actions YAML, configured environment secrets, added branch protection, and documented the rollback steps.”
“I think there is a logic issue here. Let me trace the input and expected output for this edge case before changing the code.”
“I use AI as a pair programmer for exploring libraries and reviewing ideas, but I always verify the generated code and I do not rely on it during interviews or production changes without understanding it.”
Python live coding kit
unittest hoặc ít nhất assert nhanh.“I'll first clarify the expected output, then implement the core function, then add a few unit tests for normal cases and edge cases.”
“I’ll keep the logic in a function instead of printing directly, because that makes it easier to test.”
“For a large input file, I’ll stream rows one by one instead of loading everything into memory.”
threshold, window, line_number.def solve(start: int, end: int) -> list[str]:
result = []
for n in range(start, end + 1):
label = "EVEN" if n % 2 == 0 else "ODD"
if n % 7 == 0:
label += " BANG"
result.append(f"{n}: {label}")
return resultimport unittest
class TestSolve(unittest.TestCase):
def test_even_bang(self):
self.assertEqual(solve(14, 14), ["14: EVEN BANG"])
if __name__ == "__main__":
unittest.main()import csv
with open("log.csv", newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
for line_number, row in enumerate(reader, start=2):
cpu = float(row["cpu_usage"])
if cpu >= 90:
print(line_number, row)import argparse
parser = argparse.ArgumentParser()
parser.add_argument("path")
parser.add_argument("--threshold", type=float, default=90.0)
args = parser.parse_args()try:
value = float(raw_value)
except ValueError:
print(f"Invalid number: {raw_value}")
continuefrom collections import Counter, defaultdict, deque
counts = Counter(items)
groups = defaultdict(list)
window = deque(maxlen=60)DictReader nếu có header.time.perf_counter().Path(path).exists(), read_text().Counter, defaultdict, deque cho đếm, group, sliding window.JSONDecodeError.cpu_percent(interval=1).Input start, end, rules. Rule là divisor và word. Output theo thứ tự rule, có unit tests cho boundary, start > end, divisor invalid.
Viết hàm nhận list CPU samples theo giây, gom theo cửa sổ 60 giây và trả về max/avg. Giải thích vì sao bắt được peak tốt hơn log mỗi 60 giây.
Đọc file CSV lớn, in dòng đầu tiên vượt threshold, line number, timestamp, value. Không load cả file.
Mô phỏng tail -f, in dòng mới chứa ERROR. Giải thích vì sao cần sleep ngắn để tránh busy-loop.
Class RateLimiter(limit, window_seconds), method is_allowed(user_id). Dùng deque, test nhiều user.
Đọc JSON lines, đếm IP có status >= 500, trả top K. Dùng Counter.most_common(k).
Cho map service phụ thuộc service khác, trả thứ tự khởi động. Dùng DFS/topological sort, phát hiện cycle.
Viết query JOIN device/user, GROUP BY state/platform/model, ORDER BY state ASC và count DESC. Biết giải thích index trên FK và cột group/sort.
Worked examples
Đề: Nhận start, end. In từng số theo format n: EVEN/ODD, thêm BANG nếu chia hết cho 7. Viết unit tests.
def fizz_bang(start: int, end: int) -> list[str]:
if start > end:
return []
lines = []
for number in range(start, end + 1):
parity = "EVEN" if number % 2 == 0 else "ODD"
suffix = " BANG" if number % 7 == 0 else ""
lines.append(f"{number}: {parity}{suffix}")
return lines
import unittest
class TestFizzBang(unittest.TestCase):
def test_even_bang(self):
self.assertEqual(fizz_bang(14, 14), ["14: EVEN BANG"])
def test_empty_when_start_after_end(self):
self.assertEqual(fizz_bang(5, 3), [])
range(start, end + 1): vì đề nói inclusive.parity và suffix giúp dễ đọc hơn if/else lồng nhau.Nói khi làm: “I’ll return a list first because it makes the function testable. If the interviewer wants printing, I can print the returned lines afterward.”
Đề: Đọc file CSV rất lớn có cột timestamp và cpu_usage. Trả dòng đầu tiên có CPU vượt threshold, kèm line number.
import csv
from pathlib import Path
def find_first_cpu_peak(path: str, threshold: float) -> dict | None:
with Path(path).open(newline="", encoding="utf-8") as file:
reader = csv.DictReader(file)
for line_number, row in enumerate(reader, start=2):
try:
cpu_usage = float(row["cpu_usage"])
except (KeyError, ValueError):
continue
if cpu_usage >= threshold:
return {
"line_number": line_number,
"timestamp": row.get("timestamp", ""),
"cpu_usage": cpu_usage,
}
return None
class TestCsvAnalyzer(unittest.TestCase):
def test_find_first_peak(self):
path = "sample.csv"
with open(path, "w", encoding="utf-8") as f:
f.write("timestamp,cpu_usage\n10:00,30\n10:01,95\n")
self.assertEqual(
find_first_cpu_peak(path, 90),
{"line_number": 3, "timestamp": "10:01", "cpu_usage": 95.0},
)
csv.DictReader stream từng dòng, không load toàn bộ file.enumerate(..., start=2): dòng 1 là header, data đầu tiên là dòng 2.KeyError xử lý thiếu cột, ValueError xử lý số lỗi.Nói khi làm: “For a multi-million-row file, I will not use readlines or pandas. This scans one row at a time, so memory stays constant.”
Đề: Cho list sample CPU mỗi giây. Gom theo window 60 giây, trả max và average của từng window.
def summarize_cpu_windows(samples: list[float], window_size: int = 60) -> list[dict]:
summaries = []
for start in range(0, len(samples), window_size):
window = samples[start:start + window_size]
if not window:
continue
summaries.append({
"start_index": start,
"end_index": start + len(window) - 1,
"max_cpu": max(window),
"avg_cpu": sum(window) / len(window),
})
return summaries
class TestCpuWindows(unittest.TestCase):
def test_partial_window(self):
result = summarize_cpu_windows([10, 20, 99, 30], window_size=3)
self.assertEqual(result[0]["max_cpu"], 99)
self.assertEqual(result[1]["avg_cpu"], 30)
count/sum/max để O(1) memory.Nói khi làm: “The key idea is to sample more frequently than the reporting interval, then report the maximum observed value in that interval.”
Đề: Theo dõi file log như tail -f, in dòng mới chứa ERROR.
import os
import time
def follow_errors(path: str, sleep_seconds: float = 0.1):
with open(path, "r", encoding="utf-8") as file:
file.seek(0, os.SEEK_END)
while True:
line = file.readline()
if not line:
time.sleep(sleep_seconds)
continue
if "ERROR" in line:
yield line.rstrip("\n")
seek(0, os.SEEK_END): chỉ quan tâm dòng mới sau khi script bắt đầu.sleep(0.1): tránh busy-loop chiếm CPU khi chưa có log mới.yield để function testable và tái sử dụng, thay vì print cứng.Nói khi làm: “Without the sleep, the loop would continuously poll the file and waste CPU while waiting for new lines.”
Đề: Cho mỗi user tối đa N request trong W giây. Viết is_allowed(user_id, now).
from collections import defaultdict, deque
class RateLimiter:
def __init__(self, limit: int, window_seconds: float):
self.limit = limit
self.window_seconds = window_seconds
self.requests = defaultdict(deque)
def is_allowed(self, user_id: str, now: float) -> bool:
queue = self.requests[user_id]
while queue and now - queue[0] >= self.window_seconds:
queue.popleft()
if len(queue) >= self.limit:
return False
queue.append(now)
return True
class TestRateLimiter(unittest.TestCase):
def test_blocks_after_limit(self):
limiter = RateLimiter(limit=2, window_seconds=10)
self.assertTrue(limiter.is_allowed("u1", 0))
self.assertTrue(limiter.is_allowed("u1", 1))
self.assertFalse(limiter.is_allowed("u1", 2))
self.assertTrue(limiter.is_allowed("u1", 11))
defaultdict(deque): mỗi user có queue timestamp riêng.popleft() O(1), tốt hơn list pop(0) là O(n).now vào hàm giúp test không phụ thuộc thời gian thật.Nói khi làm: “I inject the current time as a parameter because it makes the logic deterministic and easy to unit test.”
Đề: Đọc JSON lines, đếm IP có status >= 500, trả top K.
import json
from collections import Counter
def top_error_ips(lines: list[str], k: int) -> list[tuple[str, int]]:
counts = Counter()
for line in lines:
try:
record = json.loads(line)
except json.JSONDecodeError:
continue
ip = record.get("ip")
status = int(record.get("status", 0))
if ip and status >= 500:
counts[ip] += 1
return counts.most_common(k)
Counter hợp cho bài đếm tần suất.most_common(k) rõ nghĩa và ngắn.lines thành iterator đọc từng dòng.Nói khi làm: “I’m making the parser tolerant of bad log lines because production logs are often messy.”
Đề: Cho dependency map, trả thứ tự khởi động service. Nếu có cycle thì báo lỗi.
def boot_order(dependencies: dict[str, list[str]]) -> list[str]:
order = []
visiting = set()
visited = set()
def visit(service: str):
if service in visited:
return
if service in visiting:
raise ValueError(f"Cycle detected at {service}")
visiting.add(service)
for dependency in dependencies.get(service, []):
visit(dependency)
visiting.remove(service)
visited.add(service)
order.append(service)
for service in dependencies:
visit(service)
return order
class TestBootOrder(unittest.TestCase):
def test_dependencies_first(self):
deps = {"api": ["db", "cache"], "db": [], "cache": []}
self.assertEqual(boot_order(deps), ["db", "cache", "api"])
def test_cycle(self):
with self.assertRaises(ValueError):
boot_order({"a": ["b"], "b": ["a"]})
visiting phát hiện cycle trong recursion stack.visited tránh xử lý lại service đã xong.Nói khi làm: “I use two sets: visiting for the current recursion path to detect cycles, and visited for completed nodes.”
Đề: Hai bảng device và user. Tổng số device theo state, platform, model. Sort state alphabetically, count giảm dần trong mỗi state.
SELECT
u.state,
d.platform,
d.model,
COUNT(*) AS total_device_count
FROM device AS d
JOIN user AS u
ON u.user_id = d.user_id
GROUP BY
u.state,
d.platform,
d.model
ORDER BY
u.state ASC,
total_device_count DESC;
JOIN nối device với user để lấy state.GROUP BY tất cả cột không nằm trong aggregate.COUNT(*) đếm số device trong từng nhóm.device.user_id, user.user_id; tùy DB có thể thêm index hỗ trợ group/sort.Nói khi làm: “The grouping columns define the report granularity: state plus platform plus model. Then I sort by state ascending and count descending inside each state.”
VS Code thao tác nhanh
omnissa-live-code/.solution.py và test_solution.py.python --version.“I’ll keep the implementation and tests side by side so it is easier to verify each step.”
python --version
python solution.py
python -m unittest -v test_solution.py
python -m pip install psutilNếu máy dùng python3, thay python bằng python3. Không mất thời gian tạo venv nếu đề không yêu cầu.
Đọc lỗi thành tiếng, xác định nguyên nhân, sửa nhỏ, chạy lại.
“This looks like an off-by-one issue. The requirement says inclusive, so I should use range(start, end + 1).”
“I’ll add a temporary print to inspect the value, then remove it once the bug is clear.”
“I’ll use Python for this exercise. I’ll first clarify the expected input and output, then write the core function, add a few unit tests, and run them from the terminal.”