Câu hỏi phỏng vấn PySpark
Bởi Aaron Cao · Cập nhật

Phỏng vấn PySpark tập trung vào execution model và hiệu năng. Bạn cần giải thích được sự khác biệt giữa transformation và action, xác định thao tác nào gây ra shuffle, chọn broadcast join khi phù hợp, chẩn đoán data skew, giải thích lý do dùng cache, và mô tả cách bạn sẽ tune một job bị hết memory.
Nhà tuyển dụng hỏi gì về execution model?
Bạn có thể viết PySpark chạy được mà vẫn vấp ở đây, vì những câu hỏi này hỏi engine đang làm gì, chứ không phải code của bạn viết gì. Người phỏng vấn thường mở đầu bằng những câu này chính vì chúng phân biệt được ai đã từng tune một job với ai chỉ mới chạy nó một lần. Phần này đề cập các câu hỏi về execution model và những gì một câu trả lời đầy đủ cần có.
- Transformation và action khác nhau ở điểm nào? Transformation xây dựng một kế hoạch và trả về một DataFrame mới theo kiểu lazy; các action như
count,collecthoặc một thao tác ghi sẽ kích hoạt việc thực thi. Không gì được tính toán cho đến khi một action yêu cầu kết quả. - Vì sao lazy evaluation lại hữu ích? Optimizer nhìn thấy toàn bộ chuỗi thao tác trước khi chạy, nên nó có thể sắp xếp lại các filter, cắt bớt cột không cần thiết và gộp các bước lại.
- Transformation hẹp hay rộng? Các thao tác hẹp như
filtervàselectkhiến mỗi partition đầu ra chỉ phụ thuộc vào một partition đầu vào. Các thao tác rộng nhưgroupBy,joinvàdistinctphân phối lại dữ liệu giữa các partition, đó chính là shuffle. - Shuffle là gì và vì sao nó quan trọng? Dữ liệu di chuyển qua mạng và chạm tới disk, tạo thành một ranh giới stage. Đây thường là phần tốn kém nhất mà một job thực hiện.
- Giải thích job, stage và task. Một action khởi động một job, ranh giới shuffle chia job đó thành các stage, và mỗi stage chạy một task cho mỗi partition.
- RDD, DataFrame hay Dataset? Nên ưu tiên DataFrame, vì được hưởng lợi từ Catalyst optimizer và cách thực thi theo cột. RDD vẫn còn giá trị khi cần kiểm soát ở mức thấp. Dataset có kiểu là khái niệm của JVM, nên trong Python, câu trả lời thành thật là nó không áp dụng.
Hãy nói ra các từ shuffle và stage khi chúng thực sự thuộc về câu trả lời. Người phỏng vấn dùng chúng như một cách nhanh để biết bạn đã từng xem Spark UI hay chưa.
Trả lời các câu hỏi về hiệu năng như thế nào?
Phần lớn các buổi phỏng vấn PySpark cấp senior thực chất là phỏng vấn về hiệu năng. Câu hỏi thường đến dưới dạng tình huống chứ không phải định nghĩa.
- Một join bị chậm. Bạn sẽ kiểm tra gì? Trước tiên là kích thước mỗi bên. Nếu một bên vừa với memory của executor, hãy broadcast nó và bỏ qua hoàn toàn shuffle. Nếu không, hãy xem xét partitioning và skew trước khi đụng đến kích thước cluster.
- Data skew là gì và cách khắc phục ra sao? Một vài key nắm giữ phần lớn các dòng, khiến một task chạy lâu sau khi các task khác đã xong. Cách khắc phục gồm salting key nóng, broadcast bên nhỏ hơn, hoặc lọc bỏ các giá trị null vốn bị hash vào cùng một chỗ. Tín hiệu chẩn đoán là độ chênh lệch thời gian chạy task trong Spark UI.
- Khi nào nên dùng cache hoặc persist? Khi một DataFrame được tái sử dụng qua nhiều action và việc tính toán lại sẽ tốn kém. Cache thứ chỉ dùng một lần sẽ lãng phí memory, và unpersist đúng lúc rất quan trọng trong các job chạy dài.
- repartition hay coalesce? repartition gây ra shuffle và có thể tăng hoặc giảm số partition một cách đồng đều; coalesce gộp lại mà không cần shuffle đầy đủ, đây là cách rẻ hơn để giảm số file đầu ra.
- Vì sao nên tránh dùng Python UDF? Các dòng dữ liệu được serialize qua lại giữa JVM và một tiến trình Python, và optimizer không thể nhìn thấy bên trong hàm. Nên ưu tiên hàm built-in, và chỉ dùng đến vectorized UDF khi không có hàm built-in tương ứng.
- Vì sao
collectnguy hiểm? Nó kéo toàn bộ kết quả về driver và có thể làm cạn kiệt memory của driver. - Một job fail vì hết memory. Bạn sẽ điều tra theo thứ tự nào? Trước hết xem là driver hay executor, rồi đến skew, rồi kích thước partition, và cuối cùng mới là cấu hình memory. Tăng memory ngay từ đầu là câu trả lời cho thấy thiếu kinh nghiệm.
Một data engineer phỏng vấn vào một platform team được hỏi vì sao một job chạy ban đêm vốn ổn định suốt một năm bỗng mất tới bốn giờ. Câu trả lời gây ấn tượng không phải là thay đổi cấu hình, mà là một đối tác upstream bắt đầu gửi giá trị null trong join key, khiến mọi dòng null đều hash vào cùng một partition. Người phỏng vấn đánh giá cao đúng thứ tự đó: nhìn vào dữ liệu trước khi nhìn vào cluster.
Các bộ câu hỏi liên quan theo từng vị trí nằm ở câu hỏi phỏng vấn theo vị trí.
Những câu hỏi thực tế và xử lý dữ liệu nào thường gặp?
Các câu hỏi còn lại kiểm tra xem bạn đã thực sự triển khai một pipeline hay chỉ mới hoàn thành một tutorial.
- Làm sao để đọc dữ liệu hiệu quả? Các định dạng columnar như Parquet, partition pruning trên cột filter, và predicate pushdown. Hãy giải thích vì sao đọc ít byte hơn tốt hơn là tối ưu những gì xảy ra sau đó.
- Vì sao nên định nghĩa schema thay vì để hệ thống suy luận? Việc suy luận tốn thêm một lượt quét dữ liệu, và có thể đoán kiểu dữ liệu không nhất quán giữa các lần chạy.
- Xử lý null và dữ liệu trùng lặp như thế nào? Các hàm liên quan, cùng với việc chỉ ra rằng join key có nhiều giá trị null sẽ tạo ra skew.
- Window function được dùng để làm gì? Để xếp hạng, tính tổng lũy kế, và loại bỏ trùng lặp để giữ lại bản ghi mới nhất theo từng key, đây là tác vụ rất phổ biến trong pipeline.
- Làm sao ghi output mà không tạo ra hàng ngàn file nhỏ? Thực hiện coalesce hoặc repartition trước khi ghi, và partition output theo một cột có cardinality hợp lý.
- Kiểm thử code PySpark như thế nào? Dùng các session local nhỏ với DataFrame mẫu, và tách logic nghiệp vụ thành các hàm nhận vào và trả về DataFrame.
- Submit và cấu hình một job như thế nào? Số lượng executor, số core và memory, cùng lý do vì sao quá nhiều executor nhỏ hay quá ít executor lớn đều lãng phí năng lực.
Nên luyện tập thế nào trước buổi phỏng vấn?
Các câu trả lời PySpark thất bại khi nói ra thành tiếng theo một cách rất dễ nhận ra. Ứng viên biết rằng shuffle tốn kém nhưng không nói được thao tác nào gây ra nó, nên câu trả lời trở thành một chuỗi tính từ. Đọc một bộ câu hỏi tạo ra cảm giác quen thuộc, nhưng sự quen thuộc đó không giống với việc đưa ra một lời giải thích trong khi ai đó đang chờ.
Hãy chọn một pipeline bạn từng xây dựng và kể lại toàn bộ từ đầu đến cuối: bước đọc, từng transformation, ranh giới stage nằm ở đâu, và bạn sẽ kiểm tra gì đầu tiên nếu nó chậm lại. Hãy nói to lên cho đến khi bạn không còn phải bắt đầu lại. Luyện tập những câu hỏi này với một AI interviewer biết hỏi tiếp sẽ gần với một vòng phỏng vấn thật hơn là đọc lại ghi chú, và đó chính là mục đích chế độ phỏng vấn giả lập.
Aaron Cao, người sáng lập SubcueAI, đã xây dựng phần luyện tập xoay quanh khoảng cách nói thành tiếng đó, thay vì chỉ cung cấp thêm câu hỏi. Trong một buổi phỏng vấn thật, ứng dụng desktop và Side Panel của tiện ích trình duyệt có thể hiện cấu trúc trong lúc người phỏng vấn đang nói, điều này hữu ích nhất với những nội dung bạn đã luyện tập trước. Việc thiết lập chỉ mất vài phút và được trình bày ở trang hướng dẫn.
Câu hỏi thường gặp
Phỏng vấn PySpark có bao gồm live coding không?
Vị trí PySpark cần biết bao nhiêu SQL?
Có nên học Scala cho buổi phỏng vấn Spark không?
Lỗi phổ biến nhất trong phỏng vấn PySpark là gì?
Một trợ lý AI có thể giúp tôi trong buổi phỏng vấn data engineering trực tiếp không?
Câu hỏi liên quan
- Phỏng vấn lập trình thường có những dạng câu hỏi nào và trợ lý AI có thể giúp ra sao?
- Phỏng vấn video HireVue thường hỏi những câu gì?
- Tôi nên chuẩn bị những câu hỏi phỏng vấn Databricks nào?
- Tôi nên chuẩn bị những câu hỏi phỏng vấn .NET nào?
- Tôi nên chuẩn bị những câu hỏi phỏng vấn kỹ sư chất lượng nào?
- Tôi nên dự kiến những câu hỏi nào trong phỏng vấn định lượng?