# Phỏng vấn FDSE ở Palantir: tự luyện vòng re-engineering và vòng learning

> Hai vòng này không chấm việc bạn tìm ra lỗi nhanh đến đâu. Chúng chấm cách bạn lần ra lỗi và cách bạn học một thứ mới trong khi có người đang quan sát.

Bản gốc: https://fdetimes.net/vi/bach-khoa/palantir-fdse-vong-re-engineering-va-learning/

Bạn nhận một codebase dài từ 200 đến 1.000 dòng mà mình chưa đọc bao giờ. Nó đang cho ra kết quả sai và bạn có 60 phút trong CodePair để sửa. Lỗi có thể chỉ là một dấu trừ bị đảo thành dấu cộng.

Đó là bài re-engineering trong buổi onsite tuyển Forward Deployed Software Engineer ở Palantir. Buổi onsite chọn tối đa bốn vòng trong năm loại: Decomposition, Re-engineering, Coding, Learning và System Design. Hướng dẫn này dành cho hai vòng re-engineering và learning.

Hai vòng này đáng luyện kỹ vì chúng rất gần với công việc thật. Re-engineering là làm việc với một hệ thống có sẵn: hiểu nó, phê bình nó, rồi mở rộng hoặc sửa nó, tức là mô phỏng khá sát việc FDE phải làm với hệ thống legacy của khách hàng.

Còn vòng learning đưa cho bạn một công cụ hay API lạ và yêu cầu dùng được ngay. Đó cũng là tình huống quen thuộc khi bạn phải làm việc với công cụ mà khách hàng đang dùng.

## Chấm quá trình, không chấm tốc độ

Hướng dẫn của Aced/Exponent nói rõ người chấm tập trung vào việc quá trình debug của bạn có hệ thống hay không, chứ không phải bạn phát hiện lỗi đầu tiên nhanh đến đâu. Theo TechPrep, vòng này còn đo xem bạn cần bao lâu để nắm được một repository lộn xộn và bắt đầu làm ra việc có ích.

Vì thế, luyện bằng cách giải thật nhiều đề sẽ không đủ. Bạn cần luyện một quy trình và biến nó thành phản xạ. Phần dưới hướng dẫn bạn dựng một bộ bài tập nhỏ trên laptop để làm việc đó.

Chuẩn bị: Python 3, một trình soạn thảo, đồng hồ bấm giờ và một cách để ghi âm chính mình. Nếu có bạn đóng vai người phỏng vấn thì càng tốt.

## Bước 1: Tự cài lỗi vào một đoạn code

Lỗi trong đề của Palantir là lỗi logic, ví dụ một dấu bị đảo, một giả định sai về thứ tự sắp xếp, hoặc một biến không được reset giữa các vòng lặp. Đoạn code dưới đây được dựng riêng để luyện tập, không phải đề thật. Nó cố ý chứa hai trong ba loại lỗi đó.

```python
# ledger.py — bài tập tự dựng, có cài sẵn lỗi
def net_by_customer(txns):
    result = {}
    total = 0
    current = None
    for cust, kind, amount in sorted(txns):
        if cust != current:
            if current is not None:
                result[current] = total
            current = cust
        if kind == "refund":
            total += amount
        else:
            total += amount
    result[current] = total
    return result

txns = [("A", "sale", 100), ("A", "refund", 30), ("B", "sale", 50)]
print(net_by_customer(txns))
```

Chạy `python3 ledger.py`. Kết quả đúng phải là A bằng 70 và B bằng 50. Thực tế nó in ra `{'A': 130, 'B': 180}`. Kiểm tra: nếu bạn thấy đúng hai con số này thì bài tập đã sẵn sàng.

## Bước 2: Đi ngược từ output sai về input

Ứng viên mạnh lần theo dòng dữ liệu từ output ngược về input, còn đoán rồi thử là kiểu làm dẫn đến trượt. Hãy làm điều đó với con số sai rõ nhất trước.

B ra 180, trong khi khách B chỉ có đúng một giao dịch 50. Như vậy 130 thừa ra phải đến từ một nơi khác, và 130 lại chính là giá trị của A. Đi ngược lên, bạn thấy `total` mang nguyên số dư của A sang B vì không được reset về 0 khi đổi khách hàng.

Tiếp theo là A. A ra 130 thay vì 70, lệch 60, tức gấp đôi khoản refund 30. Độ lệch đúng bằng hai lần một giá trị là dấu hiệu quen thuộc của lỗi đảo dấu: đáng lẽ phải trừ 30 thì code lại cộng 30. Bạn có hai giả thuyết, cả hai đều được suy ra từ con số chứ không phải từ cảm giác.

Kiểm tra: sau khi sửa từng lỗi, chạy lại và xem con số nào đã đúng. Mỗi lần chỉ sửa một chỗ, để bạn biết chắc thay đổi nào gây ra kết quả nào.

## Bước 3: Đọc hết khối code trước khi sửa

Aced/Exponent khuyên đọc trọn khối code từ trên xuống dưới trước khi chốt cách sửa, vì lỗi dễ thấy nhất chưa chắc là lỗi thật. Trong `ledger.py`, nhiều người nhìn thấy `sorted(txns)` liền nghi ngay phần sắp xếp. Thật ra ở đây sắp xếp theo khách hàng lại là điều kiện cần để vòng lặp gom nhóm đúng.

Để luyện riêng loại lỗi giả định thứ tự, hãy viết thêm một hàm lấy `txns[0]` làm giao dịch đầu tiên của khách, rồi đưa vào dữ liệu không theo thứ tự thời gian. Sau đó tự hỏi: code này đang giả định dữ liệu đầu vào trông như thế nào, và ai đảm bảo giả định đó đúng?

## Bước 4: Nói ra từng giả thuyết

Trong lúc làm, hãy nói thành lời theo khuôn: "Output sai ở đâu. Mình nghi vì sao. Mình sẽ kiểm tra bằng cách nào." Ghi âm lại cả 60 phút. Khi nghe lại, đếm xem có bao nhiêu lần bạn sửa code mà chưa nói ra được giả thuyết nào. Mỗi lần như thế là một lần bạn đang đoán.

## Vòng learning: đọc tài liệu kỹ hơn bạn tưởng

Vòng learning đưa cho bạn một khái niệm hoặc một API nhỏ chưa quen và yêu cầu dựng được gì đó với nó. Lý do trượt phổ biến nhất ở vòng này, theo Leonstaff, là đọc lướt tài liệu rồi đoán hành vi của API.

**Điểm mấu chốt:** Đoán mò có thể lọt qua một bài tập, nhưng không lọt qua được một lần deployment.

Cách luyện: chọn một module trong thư viện chuẩn của ngôn ngữ bạn dùng mà bạn chưa động tới bao giờ. Cho mình 20 phút chỉ để đọc tài liệu, sau đó viết một script nhỏ có mục đích rõ ràng. Trước mỗi lần gọi hàm, hãy nói to kết quả bạn dự đoán, rồi chạy để kiểm chứng.

## Dự đoán trước, chạy sau: thử với groupby

Đây là một lượt luyện mẫu với `itertools.groupby` của Python, giả sử bạn chưa dùng nó bao giờ. Nhiệm vụ tự đặt: đếm số giao dịch của mỗi khách.

```python
from itertools import groupby
custs = ["A", "B", "A"]
print([(k, len(list(g))) for k, g in groupby(custs)])
```

Người đọc lướt chỉ thấy cái tên "group by" và sẽ nói to dự đoán kiểu SQL: `[('A', 2), ('B', 1)]`. Chạy thử, bạn nhận được `[('A', 1), ('B', 1), ('A', 1)]`. Dự đoán sai, và đó chính là lúc mô hình tư duy của bạn cần được sửa.

Quay lại tài liệu, bạn sẽ thấy `groupby` chỉ gom những phần tử liên tiếp có cùng khóa, nên phải sắp xếp trước. Đổi thành `groupby(sorted(custs))` thì ra `[('A', 2), ('B', 1)]`. Đây cũng chính là lý do `sorted(txns)` trong `ledger.py` không phải là lỗi.

Kiểm tra sau lượt luyện: bạn ghi lại được ít nhất một chỗ mà dự đoán của mình lệch với tài liệu, và giải thích được vì sao. Trong phòng phỏng vấn, chỉ cần nói một câu như "Mình tưởng nó gom toàn bộ, hóa ra chỉ gom phần tử liền kề" là người phỏng vấn đã thấy được bạn học như thế nào.

## Hỏi ít, nhưng hỏi đúng tầm

Hãy kể lại cách bạn đang hiểu vấn đề để người phỏng vấn có thể chỉnh lại mô hình tư duy của bạn trước khi bạn chọn hướng làm. Nhưng hỏi quá nhiều câu chi tiết lại dễ khiến bạn trông như cần được cầm tay chỉ việc.

Hãy so sánh hai câu sau. "Hàm này trả về list hay dict?" là câu bạn tự tra được. "Mình hiểu API này xử lý theo lô, nếu sai thì mình sẽ đổi cách thiết kế" là câu cho người phỏng vấn thấy bạn đang suy nghĩ ở mức nào.

Những lúc im lặng lâu dễ bị hiểu là bạn đang bí, kể cả khi thực ra bạn đang suy nghĩ. Nếu cần im lặng để đọc, hãy báo trước: "Cho mình hai phút đọc phần mô tả xác thực."

## Những lỗi hay gặp

Lỗi đầu tiên là sửa luôn chỗ đầu tiên trông có vẻ sai rồi chạy lại để xem sao. Lỗi thứ hai là sửa nhiều chỗ cùng lúc, nên khi kết quả đúng bạn cũng không giải thích được vì sao.

Lỗi thứ ba, ở vòng learning, là tự lấp chỗ trống trong tài liệu bằng trí nhớ về một thư viện khác trông na ná, đúng như cái bẫy SQL với `groupby`.

## Kỹ năng này dùng ở đâu tại site khách hàng

Thử hình dung bạn mới đến chỗ khách hàng và họ báo một bảng tổng hợp đang lệch số. Pipeline do người khác viết từ nhiều năm trước, còn bạn chưa có ai để hỏi. Cách làm vẫn y như với `ledger.py`: lấy một bản ghi sai cụ thể, đo độ lệch, lần ngược từng bước biến đổi, và nói rõ giả thuyết với khách trước khi sửa.

Khi viết CV, đừng chỉ ghi "debug hệ thống legacy". Hãy viết theo cấu trúc: output sai trông ra sao, bạn khoanh vùng nó bằng cách nào, và đã sửa gì. Khi đọc mô tả công việc, những cụm như "existing systems" hay "unfamiliar tools" cho biết vị trí đó cần đúng hai kỹ năng mà bài này luyện.

Người chấm ở Palantir không cho điểm việc bạn bắt được lỗi đầu tiên nhanh đến đâu, mà cho điểm cách bạn đi tìm nó. Cách tìm lỗi có hệ thống ấy cũng chính là thứ bạn cần mang theo khi đứng trước hệ thống của khách hàng.

**Thử ngay tuần này:**

- Chép file ledger.py trong bài, bấm giờ 60 phút và tự ghi âm khi sửa. Nghe lại để đếm xem mình đã sửa thử bao nhiêu lần trước khi thật sự lần dòng dữ liệu.
- Chọn một module trong thư viện chuẩn mà bạn chưa dùng bao giờ, cho mình 20 phút đọc tài liệu rồi viết một script nhỏ, trước mỗi lần chạy hãy nói to kết quả bạn dự đoán.
- Viết lại một dòng trong CV về lần bạn sửa lỗi trong hệ thống của người khác, nêu rõ kết quả sai trông thế nào và bạn đã khoanh vùng nó ra sao.

## Nguồn

- [Inside the Palantir engineering interview loop](https://www.techinterview.org/post/3233476805/palantir-interview-process/?format=md)

- [What Is the Palantir Interview Process Like? (Round by Round)](https://www.designgurus.io/answers/detail/what-is-the-palantir-interview-process-like-round-by-round)

- [Palantir interview process: decomp FDSE guide (Leonstaff)](https://leonstaff.com/blogs/palantir-interview-process-decomp-fdse-guide/)

- [Palantir Forward Deployed Engineer Interview (Aced/Exponent)](https://www.aced.io/guides/palantir-forward-deployed-engineer-interview)

- [Palantir's Interview Process (2026)](https://www.techprep.app/blog/palantir-interview-process)
