Một số câu hỏi phỏng vấn "quái chiêu" dành cho lập trình viên (phần 1)

Hôm nay khoa Mạng máy tính & Truyền thông chào đón tân sinh viên. Nhìn những khuôn mặt háo hức của tân sinh viên khi ngồi nghe giới thiệu về khoa, về trường, về cách học Đại học của các thầy cô, mình cũng nhìn ra đâu đó hình ảnh của mình 22-23 năm về trước. Chỉ có khác là thời đó, sinh viên không được chăm sóc chu đáo như bây giờ. 

Có thể câu hỏi mà các bạn băn khoăn nhất đó là sau này mình tốt nghiệp ra làm được gì? Có bị thất nghiệp hay không? Đây có thể nói là một câu hỏi hóc búa và câu trả lời thực ra lại nằm trong chính các bạn. Nếu các bạn thật sự nắm vững kiến thức, có ích cho công việc hiện tại của công ty đang phỏng vấn bạn thì đảm bảo bạn không thất nghiệp được. Còn nếu bạn có sưu tầm đủ loại bằng cấp mà không thể hiện được kiến thức hay kỹ năng giải quyết vấn đề trong vòng 30-45 phút (hoặc lâu hơn) của cuộc phỏng vấn thì bạn cũng sẽ không được chọn. 

Bài nói chuyện này tôi muốn chia sẻ với các bạn những kiến thức căn bản mà dân IT cần nắm và cũng là để các bạn sắp bước vào ngưỡng cửa xin việc. Các công ty phần mềm lớn đôi khi có những câu hỏi rất quái chiêu để thử thách trí thông minh của các bạn. Những câu hỏi quái chiêu này thoạt nghe qua tưởng chừng như phi lý, không thể giải được hoặc chẳng có cơ sở nào để giải thì lại được giải bằng những logic rất đơn giản dễ hiểu và thuyết phục. 

Chú thích: bài viết này dựa trên một quyển sách hay mà tôi đọc được và dùng là tư liệu giảng dạy. Tuy nhiên, tôi không nêu ra ở phần 1 để các bạn có thời gian để nghiền nghẫm tìm ra đáp án. Nếu tôi đưa tên sách ra thì các bạn thay vì dùng năng lượng của mình giải bài, lại đi tìm đáp án trong sách thì cũng lãng phí :-) Thời tôi còn đi học phổ thông, việc trăn trở với 1 bài toán khó cả tuần, cả tháng suy nghĩ mới tìm ra đáp án. Lúc giải được bài toán khó cảm thấy sảng khoái vô cùng. Ngày nay, có quá nhiều sách tham khảo, sinh viên tập trung vào việc "giải đề" càng nhiều càng tốt, và năng lượng dành cho việc tư duy biến thành năng lượng để dò tìm, search Google xem ở đâu có lời giải để xem.  

1. Câu hỏi kỹ thuật, kiểm tra kiến thức, giải thuật 

VD1: Hãy thiết kế một giải thuật để sắp xếp một danh sách 

Wow, câu này dễ như ăn gỏi :-) Ai cũng biết là sắp xếp một danh sách là bài tập kinh điển khi học nhập môn lập trình, hoặc cấu trúc dữ liệu và thuật toán. Có thể có bạn ngay lập tức cười thầm trong bụng, tưởng rằng câu gì khó, chứ câu này dễ ẹt, hỏi thế cũng hỏi. Liền chọn ngay giải thuật dễ nhớ nhất, và bắt tay vào viết ngay giải thuật. 

Câu hỏi dễ thường chứa những cái bẫy chết người !
 
Đối với những câu hỏi này, bạn phải thực hiện 5 bước quan trọng sau, đừng bỏ sót bước nào: 
  1. Đặt câu hỏi cho người phỏng vấn để làm sáng tỏ những điều còn chưa rõ
  2. Thiết kế giải thuật 
  3. Viết mã giả (có thể là mã thật luôn) 
  4. Viết code cho mã giả đó với tốc độ vừa phải 
  5. Test mã và sửa lỗi cẩn thận 
Lưu ý quan trọng: một số công ty như Google, Facebook thậm chí cho bạn viết code trên giấy, sau đó họ đưa tờ giấy đó cho thư ký gõ lại y chang những gì bạn viết và bấm F5 để xem có chạy không :-)  

Quay trở lại Ví dụ 1: thiết kế giải thuật sắp xếp 

Bước 1: Đặt câu hỏi cho interviewer 
  • Hỏi: Danh sách loại nào ? Array hay linked list? 
  • Đáp: Array 
  • Hỏi: Danh sách chứa những gì ? Số hay chữ? 
  • Đáp: Số 
  • Hỏi: Số tự nhiên hay số thực? 
  • Đáp: Số tự nhiên 
  • Hỏi: Ý nghĩa của các số này? Số CMND, hay là cái gì khác? 
  • Đáp: đó là tuổi của khách hàng 
  • Hỏi: Có bao nhiêu khách hàng trong đó? 
  • Đáp: Cỡ 1 triệu khách hàng 
Đối với những lập trình viên kinh nghiệm, các bạn sẽ thấy dễ thở hơn nhiều khi qua cuộc phỏng vấn "ngược" với interviewer. Và lúc này bạn an tâm thiết kế giải thuật. Người ta không chỉ test kỹ năng, mà còn test mức độ "trưởng thành" của các bạn trong việc lập trình. Nếu chỉ đọc đề và cắm cuối vào làm thì bạn sẽ rơi vào bẫy ngay. 

Bước 2: Thiết kế giải thuật 
Do đây là ví dụ kinh điển và đơn giản, nên các bạn có thể làm rất nhanh. Tuy nhiên, trong thực tế, việc thiết kế giải thuật có thể khó hơn. Nhưng trong khi bạn làm việc này, hãy không ngừng tự trả lời các câu hỏi sau: 
  • Độ phức tạp của giải thuật ra sao?
  • Điều gì xảy ra nếu phải xử lý nhiều dữ liệu ?
  • Cách thiết kế của bạn có gây hiệu ứng phụ không?
  • Nếu có những hạn chế hay vấn đề khác, có đáng phải làm điều đó không? 
  • Nếu bạn biết dữ liệu input là dữ liệu đặc trưng, thì bạn có thể "tận dụng" được gì đó hay không? Ví dụ: dữ liệu là tuổi của người dùng như đoạn phỏng vấn trên, thì việc bạn chọn lưu tuổi người dùng là kiểu byte thay vì integer cũng là 1 lựa chọn tốt. Vì đơn giản kiểu byte có giá trị max là 255 mà thôi, mà tuổi người đâu có ai quá 150 tuổi đâu :-) 
Bước 3: Mã giả 
Đây là đoạn mã gần với ngôn ngữ con người nhất. Bạn chỉ cần viết theo logic của mình hiểu mà không cần phải dùng một ngôn ngữ lập trình nào cả. 

Bước 4: Coding 
Đến giai đoạn này là phải viết code thật để test. Thông thường nhà phỏng vấn họ sẽ cho các bạn viết trên giấy hay trên bảng. Hãy viết thật từ tốn, không hấp tấp, vội vã. Dùng cấu trúc dữ liệu một cách hào phóng nhất có thể và viết tiết kiệm không gian. Nên bắt đầu từ góc trái trên của bảng để viết, vì có thể bạn sẽ phải sử dụng hết cả bảng đấy. 

Bước 5: Testing 
Thực ra có hẳn một chuyên ngành "software testing" luôn đó các bạn à. Điều quan trọng nhất của một lập trình viên là phải test kỹ code của mình viết trước khi ai đó phát hiện ra lỗi. Các công ty lớn thường rất sợ phải tuyển phải một lập trình viên cẩu thả, chỉ lo xong kết quả, nhưng không hề test kỹ trước khi bàn giao. Trong văn học, người ta thường nói "văn là người" thì trong lập trình, tính nết, sự cẩn thận hay cẩu thả cũng thể hiện trong code của bạn. Và những điều đó được "tính điểm" hết 

Thế đấy các bạn à, chỉ với 1 câu hỏi tưởng chừng như "dễ như ăn gỏi" nhưng lại chứa đựng nhiều thông tin mà nhà tuyển dụng muốn tìm thấy trong ứng viên. Nên khi các bạn gặp các câu hỏi càng dễ, ta càng phải hết sức cẩn thận. 

2. Câu hỏi đố mẹo hay "quái chiêu" 

Có thể nói các công ty như Microsoft, Google, hay Facebook thường rất khoái các câu hỏi quái chiêu hóc búa này để thử thách ứng viên khi họ đã qua vòng gửi xe :-) Các câu hỏi này thông thường lại được lấy từ một đồ vật hết sức quen thuộc trong gia đình và mô hình hóa thành bài toán rất hay. 

Ví dụ 2: Hãy cho biết góc tạo bởi kim dài và kim ngắn của đồng hồ nếu cho biết giờ hiện tại. Ví dụ: 3:00 ==> Góc 90 độ. Vậy 3:33 phút thì tạo ra một góc bao nhiêu? 

Hãy tạm dừng ở đây ít phút nếu bạn muốn thử thách chính mình! Đừng đọc tiếp. Sau 15p nếu bạn chưa tìm ra đáp án hãy đọc tiếp.

Ta ký hiệu h là giờ và m là phút 

Hãy lấy tờ giấy ra và vẽ vòng tròn 3:33 phút. Chúng ta thử nghiệm vài trường hợp và sẽ "dễ dàng" nhận thấy quy luật sau: 
- Góc giữa kim phút và vị trí 12h00 là 360 * m / 60 
- Góc giữa kim giờ và vị trí 12h00 là 360 * (h % 12) / 12 + 360 * (m/60)*(1/12) 
    ( đoạn 360 * (h % 12) /12 là có thể dễ hiểu, đố các bạn tại sao lại phải cộng thêm 360 * (m/60)*(1/12) ???
- Góc giữa kim giờ và kim phút lúc này sẽ là: (góc kim giờ - góc kim phút) % 360 
Sau vài lần tối giản biểu thức, bạn sẽ có công thức là (30h - 5.5m) % 360 

Một biến thể khác của bài toán này là hãy cho biết trong một ngày, có bao nhiêu lần kim giờ và kim phút tạo với nhau 1 góc 90 độ (hay 30, hay 45, hay X độ) ?  


4. Kết luận 
Có thể nói, kỹ năng lập trình là không của riêng ngành CNTT đâu các bạn. Ngành CNTT có lợi thế là các bạn được đào tạo bài bản ngay từ đầu và quen với nhiều công cụ lập trình. Những ai ham thích lập trình đều có thể học được dù xuất phát điểm của các bạn có khác nhau. 

Tôi mong muốn chia sẻ những kinh nghiệm này do tôi lượm lặt gần xa và cộng với kinh nghiệm bản thân của mình để giúp các bạn yêu thích hơn việc lập trình. Đồng thời, biết đâu nó sẽ là những kinh nghiệm bổ ích cho các bạn để các bạn phỏng vấn xin việc, hoặc luyện thi.   

5. Câu đố vui kỳ này 

Giả sử bạn có 2 sợi dây thừng, mỗi sợi phải tốn ít nhất 1 giờ để cháy hết. Làm thế nào để bạn có thể dùng nó để đo chính xác khoảng thời gian 15 phút ? Lưu ý rằng, 2 sợi dây thừng này có mật độ không đồng đều do đó nếu đốt cháy 1/2 sợi dây không chắc chắn là 30 phút đâu nhé. 
 
Ba phần quà giá trị dưới 3 tỷ đồng sẽ được gửi đến 3 bạn có đáp án đúng và sớm nhất gửi đến cho tôi qua email: dovuilaptrinh@gmail.com, tính từ khi bạn đọc được bài này. 

Hạn chót gửi kết quả là 00:00:00 ngày 4/9/2016 (mail gửi sau đó sẽ không tính) 
Thời gian công bố kết quả là tuần 5/9/2016 (lễ khai giảng của trường ĐH CNTT). 

Vì phần thưởng có giá trị, nên nếu bạn nào tra Google để tìm ra lời giải thì không tính, bạn nào biết trước lời giải rồi cũng không tính luôn. Bạn nào gửi mail không đúng format cũng sẽ không tính. 

Chúc các bạn có một năm học mới thật thú vị. 


Format như sau: 
Subject: [Giải đố lập trình phần 1] Họ và Tên, năm sinh  
Nội dung: 
1) Dòng đầu tiên: 
Họ và tên, Ngày sinh, Giới tính, Địa chỉ, điện thoại di động 
2) Dòng thứ 2: 
Giới thiệu một chút về mình, tối đa 150 từ. 
3) Dòng thứ 3: 
Trình bày đáp án. 

Ví dụ: 
Subject: [Giải đố lập trình phần 1] Nguyễn Văn A, 1999
Nội dung: 
Nguyễn Văn A, 1/1/1999, Nam, 123 Đường số 3, P3, Q3, TpHCM, 0987 654 321
Sinh viên năm 1, khoa MMT&TT. Em ham mê lập trình .... 
...........

Đáp án: 
....... 

 


Nhận xét