Kinh nghiệm phỏng vấn Google

Kinh nghiệm phỏng vấn Google

Người viết: RR

Trong bài viết này mình muốn chia sẻ kinh nghiệm phỏng vấn Google của mình. Mình tên là RR, hiện đang làm Software Engineer ở Google. Trong thời gian làm ở Google, mình đã refer (giới thiệu) hơn 100 bạn vào Google. Mình cũng đã từng phỏng vấn khoảng 60 ứng cử viên. Đứng ở cả 2 phía của quá trình phỏng vấn đã giúp cho mình có cái nhìn rõ ràng hơn về quy trình tuyển dụng của các công ty.

Bài viết này thể hiện quan điểm cá nhân của mình, có thể không đúng với quan điểm tuyển dụng của Google.

0. Quy trình phỏng vấn Google

  1. Gửi resume cho Google: hồ sơ của các bạn sẽ được kiểm duyệt và đánh giá, sau đó những resume nào tốt sẽ được chọn vào vòng phỏng vấn. Vòng này có tỉ lệ đậu khá thấp, hầu hết hồ sơ của các bạn sẽ bị rớt từ vòng này. 2 cách gửi resume:
    • Vào trang Google Careers, tìm vị trí phù hợp rồi gửi resume, hoặc
    • Tìm người refer là nhân viên Google và gửi resume trực tiếp cho người đó.
  2. Phỏng vấn:
    • Với intern, các bạn sẽ có 2 vòng phỏng vấn online 45 phút với các lập trình viên Google. Nếu Google chưa đánh giá được trình độ các bạn sau 2 vòng thì sẽ tiến hành phỏng vấn thêm 1 vòng nữa. Kết quả phỏng vấn sẽ được báo sau vài tuần.
    • Với phỏng vấn full time, bạn sẽ phải trải qua nhiều vòng hơn (thường là 1 vòng qua điện thoại và 5 vòng trực tiếp).
    • Thời gian phỏng vấn các bạn có thể thỏa thuận với Google.
  3. Nhận kết quả phỏng vấn: Nếu vượt qua vòng phỏng vấn, bạn sẽ nhận được thư chúc mừng từ recruiter. Các bạn đọc lưu ý bên dưới rằng ở bước này có thể các bạn sẽ chưa được nhận Offer Letter ngay, do vẫn còn bước 4 để các bạn có thể chắc chắn được đi thực tập tại Google.

  4. Host Matching: Sau khi đậu phỏng vấn, hồ sơ của các bạn sẽ vào một danh sách để các lập trình viên tại Google hiện có dự án cho thực tập sinh xét chọn. Họ sẽ chủ động liên hệ các bạn để giới thiệu về dự án cũng như đánh giá các bạn có phù hợp với công việc không. Bạn cũng có quyền đồng ý hoặc từ chối để lựa chọn dự án phù hợp với mình. Sau khi đã chọn xong dự án thì coi như mọi thứ đã xong, các bạn sẽ được liên hệ để hoàn thành các giấy tờ và chuẩn bị cho chuyến đi thực tập vào hè. Thời gian thực tập là từ 12 đến 14 tuần và có thể bắt đầu vào thời gian bất kì trong hè tùy vào điều kiện của các bạn.

1. Chuẩn bị

Phỏng vấn Google chủ yếu hỏi về thuật toán. Bạn cũng có thể bị hỏi thêm 1 vài câu design (thiết kế hệ thống) hoặc những kiến thức khác. Do vậy, phần này mình sẽ chia làm 3 mục nhỏ: thuật toán, kĩ năng trình bày bằng tiếng Anh và các kiến thức khác.

1.1. Thuật toán

Với dân ACM ICPC hoặc OI, các câu hỏi phỏng vấn sẽ không quá khó. Để thêm tự tin, các bạn có thể luyện tập cài đặt một số bài đơn giản, chú ý vào xét trường hợp đặc biệt và cài đặt dễ hiểu. Trong vòng 1 năm trước khi phỏng vấn Google, mình đang chuẩn bị cho ICPC World final 2016, hầu như ngày nào cũng làm contest 5h, nên lúc đi phỏng vấn mình không cần chuẩn bị gì cả. Tuy nhiên, các bạn vẫn cần chú ý một số điểm sau:

  • Không dùng những kiến thức phức tạp và không phổ biến như Splay Tree, Suffix Array, Max Flow…
  • Chú ý 1 số thuật toán có tên gọi khác với tên gọi phổ biến ở Việt Nam, ví dụ như Interval Tree = Segment Tree.
  • Tìm thuật toán thật đơn giản. Các bài phỏng vấn được làm trong thời gian ngắn, vì vậy hãy chọn cách tiếp cận đơn giản nhất. Nếu người phỏng vấn chưa hài lòng họ sẽ hỏi cách tốt hơn.
  • Nắm rõ những thuật toán cơ bản dùng bộ nhớ động và con trỏ như Linked list, Tree. Các bạn cũng có thể luyện thêm trên leetcode, CareerCup, TechieDelight.

Với các bạn không thi ACM ICPC hoặc OI, hoặc bạn đã bỏ thi sau nhiều năm, các bạn có thể lên mạng làm thử 1 số bài gần với những bài được dùng trong phỏng vấn, ví dụ trang leetcode. Với mỗi bài, có thể luyện tập như sau:

  • Tập trình bày thuật toán một cách rõ ràng.
  • Phân tích thuật toán, cả tốc độ và thời gian chạy. Có thể tham khảo thêm bài viết về độ phức tạp tính toán trên VNOI wiki.
  • Suy nghĩ xem có những corner cases nào (trường hợp đặc biệt).
  • Trong trường hợp nào thì thuật toán có độ phức tạp xấu nhất.
  • Phần nào của code có thể được thay đổi để:
    • Giảm độ phức tạp tính toán.
    • Giảm bộ nhớ.
    • Cài đặt đơn giản hơn.

Để kết thúc phần này, mình sẽ lấy ví dụ về một câu phỏng vấn:

Một xâu được gọi là xâu đối xứng nếu nó đọc từ trái qua phải cũng giống như từ phải qua trái. Ví dụ: "abcba", "a", "abba" là các xâu đối xứng. "abc" không phải là xâu đối xứng. Cho xâu S. Tìm xâu con gồm các ký tự liên tiếp của S, có độ dài lớn nhất và là xâu đối xứng.

Lời giải bài này các bạn có thể tìm thấy trên VNOI wiki. Với các bạn dân ACM khi gặp bài này, nên tránh những thuật toán như Hash, vì có thể người phỏng vấn sẽ thắc mắc những vấn đề như đánh giá độ chính xác. Bạn cũng nên tránh thuật toán không phổ biến như Manacher.

1.2. Tiếng Anh

Quá trình phỏng vấn của Google rất coi trọng khả năng trình bày ý tưởng. Điều này đơn giản là vì nếu không có khả năng giao tiếp tốt, bạn không thể trở thành Software Engineer giỏi. Khi phỏng vấn, mình được phỏng vấn bởi các Software Engineer ở các khu vực khác nhau: Trung Quốc, Ấn độ, Singapore, châu Âu.. Tiếng Anh của bạn cần khá tốt để có thể nghe hiểu được các accent tiếng Anh khác nhau.

Việc trình bày thuật toán một cách dễ hiểu cũng rất quan trọng. Trước khi bắt đầu code, bạn cần giải thích thuật toán của mình rõ ràng mạch lạc, để người phỏng vấn có thể hiểu được. Sau đó, nếu cảm thấy thuật toán của bạn chưa đủ tốt, người phỏng vấn sẽ tiếp tục thảo luận thêm với bạn hoặc đưa ra gợi ý cho bạn làm tốt hơn.

Khi chuẩn bị phỏng vấn, hãy:

  • Tập trình bày thuật toán của mình mạch lạc dễ hiểu.
  • Tìm một người khác cùng luyện tập với mình, để 2 người trao đổi thuật toán với nhau. Có thể sử dụng những trang web như Pramp để luyện tập.

Bạn không cần giỏi tiếng Anh nhưng cần nắm rõ từ chuyên môn (ví dụ tên tiếng Anh tất cả các thuật toán), diễn đạt hợp lý và có sự tự tin.

1.3. Các kiến thức khác

  • Để trả lời tốt các câu design, các bạn nên Google để tìm đọc thêm nhiều. Bạn cần có nhiều kinh nghiệm thực tế để trả lời những câu này, do đó mình sẽ không đi sâu vào phần này.
  • Bạn cũng có thể bị hỏi 1 số câu cơ bản, ví dụ như pointer, memory allocation. Nếu bạn dùng Java cũng có thể bị hỏi những câu về JVM, garbage collection.

2. Nộp Resume

2.1. Soạn Resume

Resume là một phần rất quan trọng trong quá trình phỏng vấn. Một resume không chỉ cần thể hiện rõ trình độ và kinh nghiệm của bạn mà còn cần được trình bày kĩ lưỡng và cẩn thận. Có rất nhiều lý do:

  • Người duyệt resume của bạn không có nhiều thời gian. Thông thường họ sẽ chỉ nhìn qua Resume của thí sinh trong 1 vài phút. Do đó resume cần trình bày khoa học, nhấn mạnh những chỗ cần thiết và không dài dòng.
  • Khi nhìn resume kém, người phỏng vấn có thể sẽ hỏi những câu hỏi dễ hơn mức thông thường, và bạn sẽ khó có thể chứng tỏ khả năng của mình hơn.

Dưới đây là một vài resume "chuẩn" của các bạn đã được nhận bởi Google:

Các đặt điểm cần chú ý của các resume này:

  • Trình bày đơn giản, rõ ràng, có sự thống nhất, ví dụ:
    • Các gạch đầu dòng cùng 1 kiểu.
    • Tiêu đề cùng 1 kiểu.
    • Không có nhiều font chữ. Những chỗ cần nhấn mạnh được bôi đen.
  • Về ngữ pháp:
    • Cấu trúc câu đơn giản. Các câu không cần có chủ ngữ.
    • Những sự việc nào ở quá khứ thì chia đúng thời quá khứ.
    • Các câu nên bắt đầu bằng những động từ mạnh như Implement, Lead, Design, Teach..
  • Phần giải thưởng chỉ liệt kê có chọn lọc khoảng 3 4 giải thưởng có giá trị nhất.
  • Có giải thích rõ ràng cho tất cả các phần:
    • Giải thưởng thì phải nói rõ quy mô (bao nhiêu đội tham gia), thi về cái gì, đạt giải ra sao.
    • Kinh nghiệm làm việc cần có mô tả sơ qua về công việc, nêu rõ những gì đã học được như ngôn ngữ lập trình, framework, tools..

2.2. Kiếm người refer

Ở vòng đầu tiên, resume của bạn sẽ được duyệt bởi recruiter. Những người này không phải là Software Engineer nên có lúc sẽ không đánh giá đúng được trình độ của bạn, do đó quá trình duyệt Resume sẽ có rủi ro nhất định. Trong những bạn mình refer, có hai bạn rất khá nhưng trượt vòng resume (đã nhận được email từ chối của Google). Tuy nhiên sau đó mình đã liên hệ trực tiếp với recruiter, viết 2 email rất dài để chứng minh 2 bạn đó rất giỏi. Kết quả cả 2 bạn đều được đi tiếp đến vòng phỏng vấn và 1 bạn sẽ đi thực tập ở Google vào hè tới. Ví dụ này cũng cho thấy quá trình duyệt resume cũng có rủi ro, và tài năng thật sự có thể bị bỏ qua.

Tuy nhiên bạn chỉ nên nhờ những người có quen biết trực tiếp với bạn refer. Bởi khi refer, sẽ cần phải trả lời những câu hỏi như:

  • Bạn quen ứng viên này ra sao?
  • Ứng viên này theo bạn đánh giá có giỏi không?
  • Ứng viên này có thông minh không?

Với một người chỉ biết bạn sơ sơ, tất nhiên họ sẽ không có cách nào trả lời những câu hỏi trên. Do đó sẽ không thể giúp bạn nhiều.

Vậy tìm người refer ở đâu? Cách tốt nhất là hãy tìm hiểu xem trường của bạn hoặc những trường xung quanh có ai đã đi thực tập ở Google. Nếu bạn là dân ACM thực thụ, cũng có thể liên hệ mình.

3. Phỏng vấn

Với phỏng vấn intern, sẽ gồm khoảng 2 vòng phỏng vấn qua điện thoại. (sẽ có thể có thêm phụ thuộc vào kết quả của 2 vòng đó).

Với phỏng vấn full time, sẽ gồm 1 vòng phỏng vấn qua điện thoại + khoảng 5 vòng phỏng vấn trực tiếp. Mình có kết quả thi Google Code Jam khá tốt, nên được miễn 1 vòng phỏng vấn qua điện thoại và được recruiter liên hệ trực tiếp luôn. Đây cũng là 1 lý do các bạn nên cố gắng hết sức để thi những kỳ thi như Google Code Jam ;).

Mỗi vòng phỏng vấn thường kéo dài khoảng 45'. Bạn sẽ cần trả lời 2-3 câu đơn giản hoặc 1 câu khó.

Bạn sẽ phải code trên Google Docs, và theo mình biết kết quả phỏng vấn của bạn sẽ được quyết định bởi những người phỏng vấn và hiring committee (tạm dịch là hội đồng chấm thi). Hiring committee sẽ có bản Google Docs của các bạn, vì vậy các bạn cũng nên viết sơ qua thuật toán, độ phức tạp vào trong Google Docs trong lúc giải thích cho người phỏng vấn.

Một số chú ý trong quá trình phỏng vấn:

  • Đề bài được người phỏng vấn đưa ra có thể thiếu nhiều chi tiết. Trước khi cài đặt bạn cần hỏi rõ những điểm chưa được nói rõ. Ví dụ nếu xử lý xâu thì có thể có những ký tự nào, có thể dùng ASCII thông thường không..
  • Suy nghĩ cẩn thận về các corner case trước khi bắt đầu cài đặt, và giải thích với người phỏng vấn. Điều này không phải lúc nào cũng đơn giản. Nếu khi đang code bạn mới nghĩ ra corner case thì nên nói ngay với người phỏng vấn.
  • Khi code, bạn nên chọn thuật toán nào bạn có thể tự tin code được. Đơn giản bởi bạn code một chương trình hoàn chỉnh mà không tối ưu sẽ tốt hơn hẳn việc bạn không code xong.
  • Với những bài sử dụng cấu trúc dữ liệu, bạn có thể giả sử bạn đã có một thư viện với cấu trúc dữ liệu đó, ví dụ bạn có thể giả sử đã có 1 class BalancedBinarySearchTree với các hàm insert, delete, update.. Dĩ nhiên bạn cũng phải nói rõ với người phỏng vấn.
  • Bạn có thể trình bày một thuật toán tối ưu, và khi code xin phép code cách đơn giản hơn. Nói rõ với người phỏng vấn là bạn không tự tin code được thuật toán tối ưu.
  • Khi code, sử dụng tên biến rõ ràng, dễ hiểu. Hạn chế đặt tên biến gồm 1 ký tự.

Mình sẽ lấy ví dụ về mặt cài đặt bằng bài toán tìm xâu con đối xứng dài nhất với độ phức tạp $\mathcal{O}(N^2)$ ở phần 1:

int expand(const string& s, int left, int right) {
  // given a palindrome substring: s[left..right], we expand [left, right] to
  // find the maximum palindrome substring with center [left..right].
  // returns: length of maximum palindrome substring with center [left..right].

  while (left > 0 && right + 1 < s.length() && s[left-1] == s[right+1]) {
    left--;
    right++;
  }
  return right - left + 1;
}

int max_palindrome_substring(string s) {
  // Given string s, find its longest palindrome substring.
  // Returns: length of longest palindrome substring.
  int result = 0;  // our result

  for (int center = 0; center < s.length(); center++) {
    // odd-length substrings
    result = max(result, expand(s, center, center));

    // even-length substrings
    if (center + 1 < s.length() && s[center] == s[center+1]) {
      result = max(result, expand(s, center, center+1));
    }
  }
  return result;
}

Một vài chú ý trong code trên:

  • Mình vẫn có biến tên có 1 ký tự (s) nhưng rất hạn chế.
  • Tránh lặp lại code. Ví dụ phần xét xâu đối xứng độ dài chẵn và lẻ có code giống nhau thì tách thành hàm riêng.
  • Khi phỏng vấn, mình cũng vừa code vừa comment như vậy. Trong quá trình code mình hầu như không nói chuyện với interviewer mà chỉ viết comment. Nếu có nói thì mình cũng chỉ đọc lại comment.

4. Host matching

Như đã trình bày ở phần đầu bài viết, vòng cuối cùng bạn phải vượt qua là "Host matching". Mục đích của phần này là để các team tìm người phù hợp. Do đó bạn sẽ được phỏng vấn với người thuộc team đó, và bị hỏi gì cũng phụ thuộc chủ yếu vào team. Có team sẽ hỏi thuật toán, code, có team sẽ chỉ hỏi chung chung về sở thích của bạn hoặc có team sẽ chỉ giới thiệu về những cái họ làm rồi nhận luôn chứ không cần hỏi gì thêm.

Vòng này có tính rủi ro khá cao. Bạn có thể tăng khả năng đỗ của mình nếu có quen biết với nhân viên Google và xin trực tiếp vào những team đó. Ngoài ra nếu bạn nộp resume sớm sẽ có lợi thế hơn ở vòng này. Ví dụ các bạn muốn đi thực tập vào hè 2017, thì nên nộp resume từ tháng 9 năm 2016.