Điều đầu tiên cần biết về chữ “quy trình”
Trang Our hiring process của Google (đọc ngày 10/11/2026) cho biết quy trình thường mất khoảng 6–8 tuần và gồm một số bước sau: bài đánh giá trước phỏng vấn (Google Hiring Assessment đo phong cách làm việc; có vị trí thêm bài liên quan như bài coding); một hoặc hai cuộc trao đổi ngắn với recruiter qua điện thoại hoặc video; với một số vị trí, một dự án nhỏ trước phỏng vấn; rồi một chuỗi phỏng vấn qua video hoặc trực tiếp, chấm theo tiêu chí rõ ràng (rubric) và không có câu đố mẹo. Google cũng ghi rõ không được dùng công cụ AI trong các buổi phỏng vấn.
Những chi tiết Google không công bố, như số vòng coding, thời lượng mỗi phiên hay trình soạn thảo không gợi ý cú pháp chỉ là điều thường gặp theo chia sẻ của ứng viên trên diễn đàn tại một thời điểm, không phải quy định cố định. Vì vậy đừng học thuộc con số vòng hay nền tảng viết code như thể đó là cam kết chung của Google.
Ngay khi được liên hệ, hãy hỏi recruiter: các vòng đánh giá nhóm năng lực nào, có coding trực tiếp hay bài làm trước, dùng môi trường nào, có được chạy code không, ngôn ngữ nào chấp nhận, và khi nào nhận hướng dẫn chính thức. Nếu câu trả lời thay đổi so với bài viết này, thông tin của recruiter thắng.
Chuẩn bị theo năng lực bền vững: giải quyết vấn đề, cấu trúc dữ liệu–thuật toán, viết code sạch, giao tiếp và kể lại kinh nghiệm. Đừng biến một mô tả quy trình không chính thức thành lời hứa của Google.
Trước coding: làm rõ hợp đồng
Khi nhận đề, đừng lao vào code. Hãy diễn đạt lại mục tiêu, hỏi ràng buộc, xác nhận input xấu và quy tắc hòa. Nếu đề là gộp khoảng, cần biết [1,2] và [2,3] có chạm nhau hay tách rời, đầu mút có thể đảo không, đầu ra cần giữ thứ tự ban đầu không. Chỉ một chi tiết này đã thay điều kiện gộp.
Tiếp theo đưa ra vét cạn, phân tích chi phí, rồi đề xuất tối ưu. Người phỏng vấn nhìn thấy đường suy nghĩ và có cơ hội sửa giả định. Nói “em sẽ sắp theo đầu trái, sau đó giữ khoảng cuối đã gộp; nếu khoảng mới bắt đầu sau đầu phải thì mở nhóm mới” rõ hơn việc im lặng viết sort.
Mẫu chạy tay: gộp khoảng
Với [1,3], [2,6], [8,10], [15,18], sau sắp xếp ta giữ [1,3]. Khoảng [2,6] giao nên mở rộng thành [1,6]; [8,10] bắt đầu sau 6 nên tạo nhóm mới; [15,18] lại tạo nhóm. Kết quả có ba khoảng. Bất biến là danh sách kết quả đã rời nhau và phần tử cuối chứa toàn bộ hợp của nhóm đang mở.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
if (!(cin >> n)) return 0;
vector<pair<long long, long long>> a(n);
for (auto& [l, r] : a) {
cin >> l >> r;
if (l > r) swap(l, r);
}
sort(a.begin(), a.end());
vector<pair<long long, long long>> out;
for (const auto& p : a) {
if (out.empty() || p.first > out.back().second) {
out.push_back(p);
} else {
out.back().second = max(out.back().second, p.second);
}
}
cout << out.size() << '\n';
for (const auto& [l, r] : out) {
cout << l << ' ' << r << '\n';
}
return 0;
}
import sys
def main() -> None:
data = list(map(int, sys.stdin.buffer.read().split()))
if not data:
return
n = data[0]
intervals = []
for i in range(n):
l, r = data[1 + 2 * i : 3 + 2 * i]
intervals.append((min(l, r), max(l, r)))
intervals.sort()
merged: list[list[int]] = []
for l, r in intervals:
if not merged or l > merged[-1][1]:
merged.append([l, r])
else:
merged[-1][1] = max(merged[-1][1], r)
print(len(merged))
for l, r in merged:
print(f"{l} {r}")
if __name__ == "__main__":
main()
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
if (!sc.hasNextInt()) return;
int n = sc.nextInt();
long[][] a = new long[n][2];
for (int i = 0; i < n; i++) {
long x = sc.nextLong();
long y = sc.nextLong();
a[i][0] = Math.min(x, y);
a[i][1] = Math.max(x, y);
}
Arrays.sort(a, (u, v) -> u[0] != v[0]
? Long.compare(u[0], v[0])
: Long.compare(u[1], v[1]));
List<long[]> merged = new ArrayList<>();
for (long[] p : a) {
if (merged.isEmpty() || p[0] > merged.get(merged.size() - 1)[1]) {
merged.add(new long[]{p[0], p[1]});
} else {
long[] last = merged.get(merged.size() - 1);
last[1] = Math.max(last[1], p[1]);
}
}
System.out.println(merged.size());
for (long[] p : merged) {
System.out.println(p[0] + " " + p[1]);
}
}
}
| Điểm cần nói | Câu nói ngắn gọn | Lỗi dễ mắc |
|---|---|---|
| mô hình | sắp theo đầu trái rồi quét | quét trên thứ tự đầu vào |
| bất biến | kết quả trừ phần tử cuối đã chốt | sửa nhầm khoảng đã chốt |
| biên | đoạn chạm đầu mút được gộp theo hợp đồng này | dùng < thay vì <= tùy tiện |
| chi phí | O(n log n) do sắp xếp, quét O(n) | nhận toàn bộ là O(n) |
Hãy tự thử n=0, một khoảng, khoảng lồng hoàn toàn, đầu mút âm, và đầu vào đảo như 5 1. Trong buổi thật, không cần nghĩ ra hàng chục ca; cần chọn vài ca đánh đúng nhánh logic.
Viết code để người khác kiểm được
Tên biến ngắn vẫn chấp nhận trong thi đấu, nhưng phỏng vấn nên ưu tiên ý nghĩa. Tách hàm khi nó làm bất biến rõ hơn, không tách chỉ để trang trí. Tránh macro, template cá nhân quá dày hoặc API lạ mà bạn không giải thích được. Nếu dùng hàm thư viện, nói độ phức tạp và comparator.
Trong khi code, giữ nhịp giao tiếp: báo mình đang xử lý bước nào, không đọc từng ký tự. Nếu phát hiện lỗi, nói rõ tác động rồi sửa. Khả năng tự tìm lỗi là tín hiệu tốt hơn việc cố giấu. Cuối cùng, chạy tay đúng code vừa viết, không chạy phiên bản lý tưởng trong đầu.
Khi được hỏi cách tối ưu thêm
Không phải mọi đề đều có lời giải nhanh hơn. Với gộp khoảng chưa sắp, O(n log n) thường bị chi phối bởi sắp xếp; nếu dữ liệu đã sắp, ta bỏ bước đó và quét O(n). Nếu tọa độ nhỏ hữu hạn, có thể dùng đánh dấu nhưng đổi bộ nhớ và hợp đồng. Hãy nêu điều kiện để tối ưu có hiệu lực thay vì đoán ý người phỏng vấn.
Một câu trả lời tốt có cấu trúc: nút thắt hiện tại, giả định mới, cấu trúc thay thế, chi phí sau đổi và rủi ro. Điều này thể hiện kỹ năng kỹ thuật thực tế, nơi tối ưu luôn gắn với dữ liệu và độ phức tạp hệ thống.
Phần hành vi không phải bài thuộc lòng
Big-O Coding khuyên chuẩn bị khoảng sáu đến tám câu chuyện từ dự án thật: xung đột ưu tiên, lỗi sản xuất, quyết định có dữ liệu chưa đủ, phản hồi khó nghe, thành công nhóm, thất bại và bài học. Một câu chuyện có thể phục vụ nhiều câu hỏi, nhưng góc nhấn khác nhau.
Dùng cấu trúc bối cảnh–nhiệm vụ–hành động–kết quả. Phần hành động phải cho thấy chính bạn đã làm gì; phần kết quả nên có bằng chứng nếu có, nhưng không bịa số. Kết thúc bằng điều đã học và điều sẽ làm khác. Nếu dự án bí mật, mô tả quy mô tương đối và quyết định kỹ thuật mà không tiết lộ dữ liệu khách hàng.
Bài hướng dẫn phỏng vấn chung của Grow with Google khuyên nghiên cứu công ty và vai trò, dự đoán câu hỏi, luyện trả lời, dùng ví dụ cụ thể và chuẩn bị câu hỏi. Những việc này nghe cơ bản nhưng giúp câu trả lời bớt chung chung và nối kinh nghiệm của bạn với công việc đang ứng tuyển.
Kế hoạch bốn tuần trước lịch hẹn
Tuần đầu kiểm kê: làm một mock coding và một mock behavioral, ghi lỗi. Tuần hai tập trung hai mẫu yếu nhất cùng việc kể chuyện. Tuần ba trộn đề, luyện trong thời gian giới hạn và thực hành trên đúng editor. Tuần cuối giảm khối lượng, ôn ghi chú, kiểm thiết bị và ngủ đủ.
Mỗi mock nên có người phản hồi theo tiêu chí, không chỉ nói “ổn”. Với coding: làm rõ, hướng giải, đúng code, kiểm thử, giao tiếp. Với hành vi: câu chuyện có trả lời đúng câu hỏi không, vai trò cá nhân rõ không, kết quả có đáng tin không. Sau mỗi lần, chọn một thay đổi cụ thể cho lần kế tiếp.
Chuẩn bị phỏng vấn trực tuyến
Kiểm camera, micro, mạng, múi giờ và đường dẫn trước một ngày. Đóng thông báo, chuẩn bị giấy trắng nếu được phép và một phương án mạng dự phòng. Vào sớm vài phút, không mở tài liệu không được cho phép và không dùng công cụ AI. Nếu có nhu cầu hỗ trợ tiếp cận, trao đổi với recruiter sớm thay vì tự chịu trong buổi thi.
Trong vòng, nếu mất kết nối hoặc không nghe rõ, nói ngay. Không suy đoán câu hỏi rồi làm tiếp. Sau buổi, ghi lại chủ đề và cảm nhận khi còn mới, nhưng tôn trọng thỏa thuận bảo mật nếu có và không đăng nguyên đề.
Những sai lầm làm buổi luyện thiếu thực tế
- Thuộc một “quy trình Google” từ blog cũ và hoảng khi lịch thật khác.
- Chỉ luyện code có nút Run, trong khi vòng thật có thể yêu cầu suy luận không chạy.
- Im lặng quá lâu; người nghe không biết bạn đang bế tắc hay đang kiểm chứng.
- Nêu độ phức tạp theo thói quen, quên chi phí sắp xếp hoặc bộ nhớ phụ.
- Kể câu chuyện “chúng tôi” nhưng không làm rõ đóng góp của mình.
- Luyện đến kiệt sức trong hai ngày cuối, làm giảm khả năng tập trung.
Luyện ngay trên Big-O Coding
Giải bài gộp khoảng và tiếp tục luyện theo Coding Interview 150 với quy trình nói–chạy tay–phân tích.
Câu hỏi thường gặp
Có nên hỏi recruiter chính xác sẽ ra thuật toán nào?
Nên hỏi nhóm năng lực, định dạng và công cụ. Đừng kỳ vọng họ tiết lộ đề; mục tiêu là chuẩn bị đúng môi trường và phạm vi hợp lệ.
Không giải xong bài có chắc trượt không?
Không thể kết luận từ một tín hiệu. Hãy tiếp tục làm rõ, trình bày hướng, sửa lỗi và tối ưu phần có thể; quyết định tuyển dụng thuộc toàn bộ quy trình.
Có cần dùng ngôn ngữ Google dùng nội bộ?
Không nên tự giả định. Chọn trong danh sách recruiter cho phép và dùng ngôn ngữ bạn viết chính xác, giải thích thư viện tốt nhất.
Luyện LeetCode thực chiến theo pattern, giải bài trong 45 phút và mock interview cùng AI. 16 buổi online, lớp 7–12 học viên, chọn C++, Java hoặc Python.


