FDE PulseViệc làm FDE đang mở 316Mới đăng 7 ngày qua 10Chủ đề nổi bật: Đào tạo kỹ năng FDE tại Đông Nam Á

Tờ báo của nghề Forward Deployed Engineer

Bách khoa

Đọc codebase Java, Go hay Node.js của khách khi bạn chỉ quen Python

Trước buổi review tích hợp, bạn chưa cần học thêm ngôn ngữ mới. Bạn cần biết mở ba file nào trước, rồi lần theo một request cho tới tận database.

Đồ hoạLần theo một request qua codebase lạ
  1. 1Đọc manifestgo.mod, package.json hoặc pom.xml: dự án phụ thuộc vào những gì
  2. 2Tìm entry pointmain trong package main, trường main/exports, hàm main trong src/main/java
  3. 3Tìm route hoặc handlerAPI là cây cầu giữa frontend và backend, nên bắt đầu đọc từ đây
  4. 4Lần tới DB, dịch vụ ngoàiTheo request qua tầng xử lý tới truy vấn DB hoặc lời gọi bên thứ ba
  5. 5Ghi bản traceVài dòng mô tả đường đi của request, mang vào buổi review với khách

Đọc theo mạch đi của request thay vì theo thứ tự file, rồi ghi lại đường đi thành một bản trace.

Đồ hoạ: FDE Times

Tóm tắt nhanh

  • Backend viết bằng ngôn ngữ nào cũng chạy cùng một mạch: nhận request, xử lý, gọi DB hoặc dịch vụ ngoài, rồi trả response. Hãy đọc theo mạch đó, đừng đọc theo cú pháp.
  • Thứ tự đọc: manifest (go.mod, package.json, pom.xml), rồi entry point, rồi route hay handler API.
  • Bẫy hay gặp nhất là mang thói quen Python sang: trong Go một thư mục mới là một package, còn trong Node thì trường "type" và "exports" quyết định cách đọc và cách import.
Chia sẻLinkedInFacebookX

Ngày thứ hai ở chỗ khách, bạn được cấp quyền vào repo. Đội bạn quen Python, nhưng service đơn hàng mà agent của bạn phải gọi lại viết bằng Go. Cổng thanh toán chạy Java, còn lớp API cho app mobile là Node.js. Chiều nay đã có lịch review tích hợp.

Với FDE, đây là chuyện bình thường. Khách sẽ không viết lại hệ thống cho hợp với bạn.

Tin tốt là bạn không cần thành thạo cú pháp trước buổi chiều. Thứ bạn cần là một tấm bản đồ: mở file nào trước, bỏ qua những gì, và làm sao để trả lời được câu hỏi duy nhất khách quan tâm: dữ liệu của họ đi qua đâu.

Backend viết bằng ngôn ngữ nào cũng chạy cùng một mạch

Ở mọi backend, server nhận request, xử lý, có khi truy vấn database hoặc gọi một dịch vụ bên thứ ba, rồi trả response. API là cây cầu nối frontend với backend. Vì thế, khi gặp một codebase lạ, route hoặc handler API là chỗ tốt nhất để bắt đầu.

Cú pháp có thể khác nhau, nhưng mạch này thì ở đâu cũng giống. Vậy nên hãy đọc bằng ba câu hỏi, lần lượt từng câu. Dự án phụ thuộc vào những gì? Đó là việc của manifest. Chương trình bắt đầu chạy từ đâu? Đó là entry point. Một request cụ thể đi qua những chỗ nào? Đó là handler, rồi tới database hoặc dịch vụ ngoài.

Người mới hay mắc một lỗi: mở thư mục rồi đọc từ file đầu tiên theo thứ tự chữ cái. Làm vậy, bạn sẽ chìm trong code tiện ích trước khi kịp biết hệ thống làm gì.

Ba ngôn ngữ cất những thứ đó ở ba chỗ khác nhau

Bảng dưới đây đặt mỗi ngôn ngữ cạnh thứ tương ứng mà bạn đã quen bên Python:

Câu hỏi Python Go Node.js Java (Maven)
Phụ thuộc vào gì? requirements.txt, pyproject.toml go.mod package.json pom.xml ở thư mục gốc
Entry point ở đâu? file chạy chính hàm main trong package main trường “main”, hoặc “exports” nếu có tìm hàm main trong src/main/java
Code chính và test nằm đâu? tùy dự án trong các thư mục package tùy dự án src/main/java và src/test/java
Một package là gì? một file .py là một module cả một thư mục một thư mục có package.json một nhánh trong cây package

Với Node còn một chuyện bảng không chứa hết: file .js được hiểu là CommonJS hay ES module tùy trường “type” trong package.json gần nhất. Dòng cuối của bảng và chi tiết này là chỗ phản xạ Python dẫn bạn đi sai nhiều nhất.

Ví dụ: lần theo một đơn hàng qua service Go

Thử hình dung repo order-service của khách. Bước đầu tiên là mở go.mod. Theo tài liệu của Go, file này định nghĩa module và theo dõi các module cung cấp package mà code dùng tới. Chỉ cần đọc danh sách dependency, bạn đã đoán được họ dùng thư viện gì cho HTTP và cho database.

Bước hai là tìm điểm khởi động. Trong Go, hàm main sẽ chạy khi bạn chạy package main, nên chỉ cần tìm đúng hai thứ đó:

cat go.mod
grep -rln "package main" --include=*.go .
grep -rn "func main()" --include=*.go .

Từ hàm main, bạn sẽ thấy chỗ server được khởi tạo và các route được đăng ký. Giả sử bạn thấy POST /orders trỏ tới hàm CreateOrder trong thư mục api. Mở hàm đó ra, bạn gặp lệnh gọi store.SaveOrder(...).

Đến đây, phản xạ Python sẽ bảo bạn đi tìm file store.go. Đừng làm thế. Package trong Go gồm tất cả các file trong cùng một thư mục, nên SaveOrder có thể nằm ở bất kỳ file nào trong thư mục store. Hãy grep func SaveOrder trong thư mục đó thay vì đoán tên file.

Kết quả của buổi sáng nên là một bản trace dài năm dòng. POST /orders đi vào CreateOrder (thư mục api), rồi tới SaveOrder (thư mục store), ghi vào bảng orders, sau đó gọi dịch vụ thanh toán. Mang bản này vào buổi review, bạn đã có thể hỏi những câu cụ thể: lệnh gọi thanh toán có retry không, agent nên gọi vào tầng nào.

Với Node, lỗi import đầu tiên thường nằm ở package.json

Giờ tới lớp API mobile, thử hình dung là repo mobile-gateway. Bạn viết một script nhỏ để thử hàm kiểm tra token, import thẳng file src/auth/token.js của package. Script báo lỗi, và phản xạ đầu tiên là nghĩ code của khách hỏng.

Hãy mở package.json trước. Giả sử trong đó có trường “exports” chỉ khai báo đường dẫn gốc trỏ về ./src/index.js. Theo tài liệu Node.js, khi có “exports”, trường này được ưu tiên hơn “main” và mọi subpath không khai báo đều bị che, nên src/auth/token.js không import từ bên ngoài được.

Code không hỏng; bạn chỉ đang gõ vào cửa mà khách đã khóa.

Cũng trong package.json đó, giả sử có "type": "module". Nếu package.json gần nhất không có trường này hoặc ghi “commonjs”, mọi file .js đều bị coi là CommonJS. Ở đây thì ngược lại, nên các file dùng import chứ không dùng require, và script thử nghiệm của bạn phải viết theo cùng kiểu.

Từ src/index.js, bạn lần ra route GET /orders/:id, handler của nó gọi sang order-service mà bạn vừa đọc buổi sáng. Bản trace ghi: “exports” chỉ mở src/index.js, route GET /orders/:id vào handler, handler gọi order-service. Ba dòng, và giờ bạn biết agent nên gọi qua API công khai chứ không chọc vào file nội bộ.

Với Java, để test dẫn đường qua cổng thanh toán

Cổng thanh toán Java dễ định vị hơn nhờ quy ước của Maven. Ở thư mục gốc có pom.xml, và chỉ có hai thư mục con chính là src và target. Code ứng dụng nằm trong src/main/java, test nằm trong src/test/java, và bên dưới mỗi nơi là cây package.

Với một hệ thống Java lớn, nên đọc test trước. Thử hình dung bạn tìm thấy một lớp test cho dịch vụ thanh toán trong src/test/java, với một ca kiểm tra đơn có số tiền âm và một ca kiểm tra lần gọi cổng ngân hàng thất bại.

Chỉ hai ca test đó đã cho bạn biết hệ thống được kỳ vọng xử lý đầu vào sai và lỗi bên ngoài ra sao.

Tiếp theo, đi theo cùng nhánh package sang src/main/java để mở lớp đang được test, rồi lần ngược lên controller nhận request từ order-service. Bản trace ghi: controller nhận yêu cầu thanh toán, chuyển cho dịch vụ thanh toán, dịch vụ gọi cổng ngân hàng, lỗi được xử lý theo đúng ca test kia.

Cách này thường nhanh hơn việc dò qua từng tầng class từ trên xuống.

Những lỗi biến một buổi sáng thành ba ngày

Lỗi phổ biến nhất là tin rằng phải học xong ngôn ngữ rồi mới được đọc. Bạn chỉ cần đọc hiểu đủ để lần theo một request. Viết code thành thạo bằng Go hay Java là chuyện của tuần sau, nếu dự án thật sự cần.

Lỗi thứ hai là mang đơn vị module của Python sang mọi nơi. Bạn sẽ đi tìm một file trong Go trong khi đáng ra phải tìm cả thư mục. Bạn sẽ bỏ qua “type” và “exports” của Node, rồi kết luận rằng code của khách bị hỏng.

Lỗi thứ ba là đọc mà không ghi lại. Không có bản trace thì sang ngày hôm sau bạn lại phải lần từ đầu. Người của khách cũng không có gì để xác nhận hay sửa giúp bạn.

Biến kỹ năng này thành bằng chứng khi đi xin việc

Nếu bạn là developer Python ở Việt Nam muốn chuyển sang FDE, khi đọc JD hãy để ý những cụm như “tích hợp với hệ thống sẵn có của khách”. Cụm đó có nghĩa là bạn sẽ phải đọc code mà mình không viết, bằng những ngôn ngữ mình không chọn.

Trên CV, đừng viết “biết Go, Java, Node.js”. Hãy mô tả một lần bạn đọc service viết bằng ngôn ngữ lạ, lần theo luồng dữ liệu và tích hợp thành công. Bản trace năm dòng chính là thứ đáng mang theo vào vòng phỏng vấn.

Khách sẽ không đánh giá bạn qua việc viết Go có chuẩn hay không. Họ đánh giá bạn qua việc ngay buổi chiều đầu tiên, bạn đã chỉ được dữ liệu của họ đi qua đâu.

4 nguồn
Đọc tiếp trên lộ trình · Chặng 2: Kỹ thuật rộngThiết kế API cho giải pháp bàn giao: viết hợp đồng trước, viết code sauĐội tích hợp của khách hàng sẽ dùng endpoint của bạn lâu hơn rất nhiều so với thời gian bạn ở lại dự án, nên mỗi tên trường bạn đặt hôm nay là một lời hứa phải giữ.