Bí Kíp Pass Phỏng Vấn Coding Amazon, Apple, Facebook, Microsoft Mà Không Cần Leet Code Quá Nhiều

Bài viết được sự cho phép của tác giả Trần Thiện Khiêm

Hôm nay mình sẽ chia sẻ cho các bạn cách vượt qua vòng phỏng vấn của Amazon, Apple, Facebook và Microsoft mà không cần leet code quá nhiều. (không có nghĩa là không leetcode tí nào nha). Cách giải quyết vấn đề này các bạn cũng có thể áp dụng trong công việc của mình.

GIỚI THIỆU

Trong một lần đi phỏng vấn dạo, Mình pass phỏng vấn Amazon vào năm 2019 tại Singapore. Đầu năm, mình cũng đi phỏng vấn dạo tiếp, và cuối cùng mình đã pass 3 công ty cùng 1 lúc: Microsoft, Facebook và Apple, cho vị trí senior developer. Mình không chuẩn bị gì nhiều vì nghĩ chỉ đi phỏng vấn để tìm hiểu thị trường, nhưng sau khi có offer thì mình đã nghỉ Amazon.

CẤU TRÚC BUỔI PHỎNG VẤN

Amazon, Microsoft, Facebook, Apple đều có cấu trúc phỏng vấn khá giống nhau, tuy lịch trình sẽ khác nhau một xíu và mình sẽ chia sẻ một dịp khác. Nhưng hầu hết đều tập trung vào 3 khía cạnh: Coding (tương tự các bài trên leet-code), Design (Product Design, OOP), và phỏng vấn hành vi (behavioral interview). Trong phạm vi bài này, mình chỉ chia sẻ về bí kíp thế nào để vượt qua vòng phỏng vấn coding.

Để dễ hình dung, mình sẽ lấy một ví dụ sau đây:

Cho một chuỗi kí tự, hãy đảo ngược các từ trong chuỗi kí tự đó (các từ cách nhau đúng 1 khoảng trống và không có khoảng trống dư thừa).

Ví dụ: “the sky is blue” ==> “blue is sky the”

Có thể xử lí ngay trên chuỗi mà không cần thêm bộ nhớ hay không.

BƯỚC 1: XÁC ĐỊNH RÕ YÊU CẦU

Nếu mình chưa xác định rõ yêu cầu, hãy hỏi lại thật kỹ. Hỏi thêm về các yêu cầu của bài toán, giới hạn của input/output nếu chưa được nêu rõ trong đề. Nếu mình có bất cứ điều gì mà mình giả định (assume), hãy hỏi lại để chắc chắn. Thời gian trong buổi phỏng vấn rất quý báu và mình sẽ không muốn đi sai hướng.

Trong suốt quá trình phỏng vấn, mình cứ đặt câu hỏi khi nào mình không rõ.

Ví dụ trong bài này, nếu bạn chọn ngôn ngữ là Java, thì String là kiểu immutable (không sửa được), nên bạn có thể hỏi lại sử dụng dãy kí tự char[] để thay thế được hay không, v.v…

BƯỚC 2: NẾU BẠN CÓ NGAY 1 LỜI GIẢI (CHƯA TỐI ƯU), HÃY TRÌNH BÀY

Nếu mình có ngay một lời giải ở trong đầu (kiểu brute-force), thử-sai,… và mình biết là nó chưa phải là tối ưu nhất, hãy trình bày ngay dù cho lời giải này sẽ không được chấp nhận.

Ví dụ bài này, mình có thể nói ngay: “nếu có thể dùng thêm bộ nhớ, thì mình có thể cắt chuỗi thành từng từ, sau đó ghép lại”.

Việc nghĩ ra một giải pháp tạm thời cũng là một điểm lợi thế trong buổi phỏng vấn coding. Giám khảo sẽ biết được mình có khả năng làm được bài này, dù không tối ưu.

Sau đó mình sẽ nói, “để mình nghĩ về phương án tối ưu hơn”.

BƯỚC 3: THỬ NHIỀU Ý TƯỞNG KHÁC NHAU

Đừng nên im lặng trong bất cứ thời điểm nào của cuộc phỏng vấn, hãy nói to những suy nghĩ của mình cho người phỏng vấn biết. Giải thích quá trình suy nghĩ của mình, từng bước một.

Ví dụ, với bài này mình có thể nói:

* Đối với bài này mình có thể lưu các từ trong một mảng tạm rồi đổi vị trí từ trái sang phải….

* Bởi vì bài toán yêu cầu không dùng thêm bộ nhớ, mình có thể bắt đầu bằng việc đảo các ký tự từ trái sang phải…

Tuỳ thuộc vào từng câu hỏi mà mình sẽ có những ý tưởng ban đầu, ví dụ dạng toán, cấu trúc dữ liệu cần sử dụng, có xài quy hoạch động không, có phải là dạng bài đồ thị không…. hãy nói tất cả những suy nghĩ và phán đoán của mình cho người phỏng vấn.

Điều này rất quan trọng, vì khi mình nói ra, người phỏng vấn có thể gợi ý, ví dụ: em đã bắt đầu đi đúng hướng rồi đó, hoặc, nếu em làm cách đó thì sẽ không thoả mãn trường hợp này, v.v… Nếu mình không nói gì, thì tới lúc mình nghĩ ra 1 ý tưởng sai và sẽ chẳng có ai “nhắc bài” cho mình. Người phỏng vấn cũng muốn biết cách thức mình suy nghĩ và gỉai quyết vấn đề, bước này quan trọng không kém gì bước thứ 4.

BƯỚC 4: NGHĨ RA Ý TƯỞNG VÀ GIẢI THÍCH

Nếu đi đúng hướng ở bước 3, tới một lúc bạn sẽ nghĩ ra ý tưởng. Trước khi viết bất kỳ dòng lệnh nào, hãy giải thích cho người phỏng vấn.

explain code

“NẾU MÌNH KHÔNG THỂ GIẢI THÍCH ĐƯỢC Ý TƯỞNG CỦA MÌNH, THÌ Ý TƯỞNG ĐÓ KHÔNG PHẢI LÀ Ý TƯỞNG CỦA MÌNH”

Ví dụ: với bài này, mình sẽ giải qua 2 bước:

Bước 1: đảo toàn bộ các kí tự trong dãy, “The sky is blue” sẽ trở thành “eulb si yks ehT”.

Bước 2: đảo ký tự của các từ trong dãy, ví dụ từ “eulb” sẽ trở thành “blue”

Đừng quên những trường hợp đặc biệt, ví dụ có thể hỏi người phỏng vấn rằng mình có thể giả sử chuỗi input không null được không?

Đánh giá độ phức tạp và trình bày xem độ phức tạp này có đáp ứng được yêu cầu đề ra hay không? Ví dụ: O(n) thời gian, và O(1) space.

BƯỚC 5: CODE

Đầu tiên, hãy viết code ở high level trước, như bước trước mình đã giải thích:

class Solution {
 void reverseWords(char inputString[]) {
  reverseTheWholeString(inputString);
  reverseEveryWord(inputString);
 }
}

Đoạn code rất dễ hiểu, vì đây là những gì mình đã giải thích cho ban giám khảo (2 bước sẽ trở thành 2 hàm). Và mình cũng rất dễ test (nếu giả sử 2 hàm của mình đúng thì với dữ liệu mẫu có chạy đúng hay không???).

Tiếp theo,  cài đặt từng hàm 1, ví dụ để đảo các ký tự trong chuỗi, mình sẽ đảo các ký tự nửa bên trái cho các kí tự nửa bên phải tương ứng.

class Solution {
 void reverseTheWholeString(char inputString[]) {
  int length = inputString.length;
  for (int i = 0; i < length / 2; i++) {
   swapCharacters(inputString, i, length - i - 1);
  }
 }
}

Sau đó giải thích tiếp hàm swapCharacters, để đổi vị trí 2 kí tự thì mình sẽ gán kí tự thứ nhất vào một kí tự tạm, gán kí tự thứ 2 vào kí tự thứ nhất, và gán kí tự tạm vào kí tự thứ 2.

class Solution {
 // swap characters first and second in string s
 void swapCharacters(char string[], int first, int second) {
  char temp = string[first];
  string[first] = string[second];
  string[second] = temp;
 }
}

Tiếp tục cài đặt các hàm, vừa giải thích vừa gõ code cho đến khi hoàn thành. Tại một thời điểm nào đó, bạn sẽ nói là mình có thể xài chung code cho hàm reverseTheWholeString và hàm reverseWord, hãy viết chung lại thành 1 hàm gọi là reverseSubstring để xài chung.

Bài tập cho các bạn: Làm tiếp bài trên này.

BƯỚC 6. BÌNH TĨNH VÀ DEBUG

Trong buổi phỏng vấn,  chuyện gặp sai sót là hoàn toàn bình thường, mình còn bị những lỗi ngu ngốc như là nhầm j++ thành i++ nữa kia, hãy bình tĩnh giải quyết. Bởi vì mình đã chia chương trình thành những hàm nhỏ nên rất dễ dàng tìm ra lỗi ở hàm nào mà ra.

Hãy giải thích quá trình debug cho người phỏng vấn.

BƯỚC 7. CHÚC MỪNG HOẶC HẾT GIỜ

Nếu bạn có thể làm xong trước khi hết giờ, hãy ăn mừng!

Còn nếu không, hoặc bạn làm sai 1 chút xíu nào đó, cũng đừng lo lắng, bạn đã thể hiện rất tốt cách giải quyết vấn đề cho người phỏng vấn.

Hy vọng những chia sẻ của mình giúp cho các bạn thành công trong buổi phỏng vấn coding tiếp theo.

Bài viết gốc được đăng tải tại fanpage Khiem Tran – Programmer

Xem thêm:

Đừng bỏ lỡ hàng loạt việc làm IT với đãi ngộ hấp dẫn có trên TopDev!