Menu
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Đang tải...

Bài 30 — Working with engineering: tech literacy PM

Chứng Chỉ Product Manager Hoàn Chỉnh Bài 30/60

Mở đầu — vì sao bài này quan trọng

Có một sự thật mà ít người nói thẳng với bạn khi bước vào nghề PM: phần lớn thời gian làm việc của bạn không phải với khách hàng, không phải với sếp, mà là với đội kỹ sư (engineering). Họ là những người biến ý tưởng trong đầu bạn thành sản phẩm chạy được. Và mối quan hệ giữa PM với engineering quyết định gần như toàn bộ tốc độ, chất lượng, và sự bền vững của những gì bạn xây.

Nhưng đây cũng là nơi nhiều PM "vỡ trận". Tôi đã chứng kiến những PM giỏi về chiến lược, sắc sảo về thị trường, nhưng khi ngồi vào bàn họp kỹ thuật thì gật gù cho qua vì không hiểu engineer đang nói gì. Kết quả: họ hứa với khách hàng những thứ bất khả thi, ước lượng sai thời gian gấp ba lần, và dần mất uy tín với chính đội của mình. Engineer không cần bạn code giỏi như họ. Nhưng họ rất cần bạn hiểu đủ để ra quyết định đúng, để biết khi nào một yêu cầu là "dễ" và khi nào nó là "đào lại nền móng".

Bài này không biến bạn thành lập trình viên. Mục tiêu là trang bị cho bạn tech literacy — sự thông thạo kỹ thuật vừa đủ để: hiểu các đánh đổi (trade-off) engineer đang cân nhắc, đặt câu hỏi đúng, và giao tiếp như một đối tác chứ không phải người ngoài cuộc. Đây là kỹ năng phân biệt một PM được engineer tôn trọng với một PM chỉ đơn thuần "chuyển tiếp yêu cầu".

Khái niệm cốt lõi

Tech literacy của PM xoay quanh việc hiểu các khối kiến trúc cơ bản tạo nên một sản phẩm phần mềm. Bạn không cần biết viết chúng, nhưng cần biết chúng tồn tại, chúng đánh đổi điều gì, và quyết định của bạn ảnh hưởng tới chúng ra sao.

Monolith vs Microservices — cách hệ thống được tổ chức

Hãy tưởng tượng codebase như một tòa nhà. Monolith (kiến trúc nguyên khối) là một tòa nhà lớn duy nhất: tất cả chức năng — đăng nhập, thanh toán, giỏ hàng, thông báo — nằm chung trong một khối code, deploy cùng một lúc. Ưu điểm: đơn giản, dễ phát triển ban đầu, một thay đổi nhỏ triển khai nhanh. Nhược điểm: khi lớn lên, một lỗi nhỏ ở module thanh toán có thể làm sập cả hệ thống, và mỗi lần deploy phải build lại toàn bộ.

Microservices chia tòa nhà thành nhiều căn nhà nhỏ độc lập: dịch vụ thanh toán riêng, dịch vụ tài khoản riêng, mỗi cái có team riêng, deploy riêng. Ưu điểm: scale từng phần độc lập, lỗi một dịch vụ không kéo sập cả hệ thống, các team làm song song. Nhược điểm: phức tạp vận hành, các dịch vụ phải "nói chuyện" với nhau qua mạng nên chậm hơn và dễ lỗi hơn.

Điều PM cần rút ra: khi engineer nói "tính năng này cần đụng vào ba service", bạn hiểu ngay đó là công việc phối hợp nhiều team, tốn thời gian hơn nhiều so với sửa trong một monolith. Đừng vội ép tiến độ.

API: REST và GraphQL — cách các phần "nói chuyện" với nhau

API (Application Programming Interface) là hợp đồng giao tiếp giữa các phần mềm. Khi app điện thoại của bạn lấy danh sách sản phẩm từ server, nó gọi API.

REST là phong cách phổ biến nhất: mỗi loại dữ liệu có một "địa chỉ" (endpoint), ví dụ /users/123 trả về thông tin người dùng 123. Đơn giản, dễ cache, được hỗ trợ rộng. Nhược điểm: đôi khi bạn phải gọi nhiều lần để ghép đủ dữ liệu, hoặc nhận về dư thừa dữ liệu không cần.

GraphQL cho phép client yêu cầu chính xác dữ liệu mình cần trong một lần gọi: "cho tôi tên user, kèm 3 đơn hàng gần nhất, kèm tên sản phẩm trong mỗi đơn". Linh hoạt, giảm số lần gọi, lý tưởng cho app mobile cần tiết kiệm băng thông. Nhược điểm: phức tạp hơn để xây và cache, dễ bị query nặng làm chậm server.

PM cần hiểu khái niệm này vì khi bạn thiết kế một màn hình hiển thị nhiều loại dữ liệu, lựa chọn API ảnh hưởng tới tốc độ tải và trải nghiệm. Câu hỏi đúng là: "Màn hình này cần bao nhiêu lần gọi server?" — đó là tín hiệu trực tiếp tới tốc độ.

Database: SQL vs NoSQL — cách dữ liệu được lưu

SQL (cơ sở dữ liệu quan hệ — MySQL, PostgreSQL) lưu dữ liệu theo bảng có cấu trúc chặt chẽ, hàng và cột rõ ràng, các bảng liên kết với nhau. Mạnh khi dữ liệu có quan hệ phức tạp và cần đảm bảo tính nhất quán tuyệt đối — ví dụ giao dịch tài chính, không được phép sai một xu.

NoSQL (MongoDB, DynamoDB, Redis) linh hoạt hơn về cấu trúc, mở rộng quy mô dễ, phù hợp dữ liệu lớn không có cấu trúc cố định — như log hành vi người dùng, feed mạng xã hội. Đánh đổi: thường nới lỏng tính nhất quán để đổi lấy tốc độ và khả năng scale.

PM cần biết: khi bạn yêu cầu một báo cáo "tổng doanh thu theo từng tỉnh, lọc theo tháng, nhóm theo loại sản phẩm" — đó là kiểu truy vấn SQL rất tự nhiên. Còn nếu bạn xây tính năng lưu lịch sử click hàng triệu lượt mỗi ngày, NoSQL hợp lý hơn. Hiểu điều này giúp bạn không yêu cầu những thứ đi ngược kiến trúc đang có.

Caching và CDN — tại sao có cái nhanh, có cái chậm

Caching là lưu tạm kết quả đã tính để lần sau trả ngay không cần tính lại. Ví dụ trang chủ hiển thị "sản phẩm bán chạy" — thay vì tính lại danh sách này mỗi lần có người vào, hệ thống tính một lần và cache lại trong 5 phút. Đánh đổi cốt lõi mà PM phải nắm: dữ liệu cache có thể cũ. Nếu bạn yêu cầu "giá phải cập nhật tức thì", bạn vừa vô tình loại bỏ khả năng cache, làm tăng tải server.

CDN (Content Delivery Network) là mạng máy chủ phân tán khắp nơi, lưu sẵn nội dung tĩnh (hình ảnh, video, file) gần người dùng. Người dùng ở TP.HCM tải ảnh từ máy chủ đặt tại Singapore thay vì tận Mỹ — nhanh hơn nhiều. Đây là lý do app của bạn nhanh hay chậm với người dùng ở các vùng khác nhau.

Mobile native vs cross-platform

App mobile có thể được xây native (Swift cho iOS, Kotlin cho Android — viết riêng từng nền tảng, hiệu năng tốt nhất, truy cập sâu phần cứng) hoặc cross-platform (React Native, Flutter — viết một lần chạy cả hai, tiết kiệm nhân lực nhưng đôi khi hạn chế về hiệu năng và tính năng đặc thù). PM cần hiểu lựa chọn này vì nó ảnh hưởng trực tiếp tới chi phí team, tốc độ ra tính năng, và trải nghiệm cuối.

Tình huống thực tế

Tình huống 1: PM hứa "real-time" mà không hiểu cache — một fintech tại TP.HCM

Một fintech ví điện tử (gọi là PayViet) có PM mới tên Linh, phụ trách màn hình "số dư ví". Một đối tác lớn yêu cầu số dư phải hiển thị real-time tuyệt đối — cập nhật từng giây. Linh gật đầu và đưa vào yêu cầu sản phẩm.

Khi vào họp, tech lead giải thích: hệ thống hiện tại cache số dư trong 30 giây để giảm tải, vì màn hình này được tải hàng triệu lần mỗi ngày. Bỏ cache để real-time tuyệt đối sẽ khiến database chịu tải gấp khoảng 40 lần, cần thêm hạ tầng tốn kém, và rủi ro nghẽn vào giờ cao điểm.

Linh quay lại đối tác và đặt câu hỏi đúng: "Anh cần real-time vì lý do gì?". Hóa ra họ chỉ lo người dùng nạp tiền xong không thấy số dư cập nhật. Giải pháp: giữ cache 30 giây cho hiển thị thông thường, nhưng chủ động xóa cache (cache invalidation) ngay khi có giao dịch nạp/rút. Người dùng vẫn thấy số dư đúng tức thì sau giao dịch, mà hệ thống không phải gánh tải vô nghĩa.

Bài học: Hiểu cache giúp Linh chuyển từ "vâng, em làm" sang "vấn đề thật sự là gì, và đâu là cách rẻ nhất giải quyết nó". Đó là khác biệt giữa PM ngây thơ và PM được engineer tin tưởng.

Tình huống 2: Yêu cầu nhỏ trên giao diện, đại phẫu ở backend — một sàn TMĐT

Tại một sàn thương mại điện tử ở Đông Nam Á, PM yêu cầu thêm bộ lọc "giao hàng trong 2 giờ" trên trang tìm kiếm sản phẩm. Trên giao diện, đây chỉ là một checkbox nhỏ. PM ước lượng "chắc 2 ngày là xong".

Thực tế, engineer cho biết thông tin "có giao trong 2 giờ hay không" phụ thuộc vào tồn kho theo kho gần nhất, năng lực shipper theo khu vực, và thời gian thực — những dữ liệu này nằm rải rác ở ba microservice khác nhau, và service tìm kiếm hiện không có quyền truy cập real-time tới chúng. Để làm đúng, cần xây một pipeline đồng bộ dữ liệu mới. Ước lượng thật: 6 tuần.

PM ban đầu sốc, nhưng nhờ hiểu kiến trúc microservices, anh hiểu vì sao một checkbox lại tốn 6 tuần. Anh đề xuất giải pháp giai đoạn: phiên bản 1 chỉ lọc theo "kho gần và còn hàng" (làm được trong 1 tuần, đủ tốt cho 70% trường hợp), phiên bản 2 mới tích hợp năng lực shipper real-time. Sàn ra tính năng sớm, học từ dữ liệu thật, rồi đầu tư đúng chỗ.

Bài học: Độ phức tạp của giao diện không phản ánh độ phức tạp kỹ thuật. PM hiểu kiến trúc sẽ ước lượng thực tế và biết cách chia nhỏ để giao giá trị sớm.

Tình huống 3: PM "data literacy" cứu một cuộc tranh cãi về performance

Một startup SaaS B2B có app mobile bị người dùng phàn nàn "tải chậm". Marketing muốn đổ lỗi cho team mobile; team mobile nói "tại API server chậm". PM tên Trang, thay vì để hai bên cãi nhau, ngồi xuống với engineer và cùng nhìn vào con số: màn hình dashboard gọi tới 11 API endpoint REST riêng lẻ mỗi lần mở, mỗi cái mất 200–400ms, cộng lại gần 3 giây chỉ riêng phần gọi mạng.

Hiểu được điều này, Trang đề xuất hai hướng cùng engineer: gộp các lời gọi lại bằng một endpoint GraphQL duy nhất lấy đúng dữ liệu dashboard cần, và cache những phần ít thay đổi. Sau khi triển khai, thời gian tải dashboard giảm từ 3 giây xuống dưới 1 giây.

Bài học: Khi PM hiểu cơ chế API, họ biến một cuộc đổ lỗi cảm tính thành một bài toán kỹ thuật có lời giải. Engineer tôn trọng PM không phải vì PM biết code, mà vì PM biết hỏi đúng và nhìn đúng vào con số.

Hướng dẫn từng bước

Đây là cách xây dựng tech literacy và áp dụng nó trong công việc hằng ngày:

Bước 1 — Vẽ được sơ đồ kiến trúc sản phẩm của bạn. Nhờ một engineer thân thiện vẽ cho bạn sơ đồ đơn giản: client (web/mobile) gọi tới đâu, có những service nào, database nào, cache ở đâu. Bạn không cần chi tiết, chỉ cần bức tranh tổng thể. Dán nó lên bàn làm việc. Khi có yêu cầu mới, bạn sẽ biết nó "đụng" vào đâu.

Bước 2 — Học từ vựng, không học cú pháp. Mục tiêu là hiểu nghĩa các từ: endpoint, latency (độ trễ), cache, deploy, rollback, technical debt (nợ kỹ thuật), race condition. Mỗi lần nghe từ lạ trong họp, ghi lại và hỏi engineer sau buổi: "Hồi nãy anh nói X, em hiểu đúng là... phải không?". Engineer rất sẵn lòng giải thích cho PM thật sự muốn học.

Bước 3 — Trước mỗi yêu cầu, tự hỏi ba câu kỹ thuật. Tính năng này đụng vào bao nhiêu phần của hệ thống? Dữ liệu nó cần đang nằm ở đâu, có sẵn không? Nó có yêu cầu real-time, hay dữ liệu trễ vài giây vẫn ổn? Ba câu này lọc ra phần lớn các yêu cầu "tưởng dễ mà khó".

Bước 4 — Hỏi "tại sao tốn lâu vậy" một cách tò mò, không nghi ngờ. Khi ước lượng cao hơn bạn nghĩ, đừng phản ứng "sao lâu thế". Hãy hỏi: "Giúp em hiểu phần nào tốn thời gian nhất?". Câu hỏi này vừa giúp bạn học, vừa cho engineer thấy bạn tôn trọng chuyên môn của họ.

Bước 5 — Luôn tìm phương án chia nhỏ. Với mọi yêu cầu lớn, hỏi: "Phiên bản nhỏ nhất nào mang lại 70% giá trị?". Hiểu kiến trúc giúp bạn nhận ra đâu là phần đắt đỏ có thể tạm hoãn.

Bước 6 — Tham gia, đừng chỉ nhận báo cáo. Ngồi cùng buổi review kỹ thuật, đọc qua các tài liệu thiết kế kỹ thuật (technical design doc) dù không hiểu hết. Sự hiện diện và nỗ lực hiểu của bạn xây dựng lòng tin nhanh hơn bất kỳ khóa học nào.

Lỗi thường gặp & mẹo

Lỗi 1 — Giả vờ hiểu. Gật gù cho qua trong họp kỹ thuật là cách nhanh nhất đánh mất uy tín. Engineer luôn nhận ra. Hãy can đảm nói "em chưa rõ chỗ này, giải thích lại giúp em được không?". Sự thành thật được tôn trọng hơn nhiều so với việc tỏ ra biết.

Lỗi 2 — Coi ước lượng của engineer là con số đàm phán. "Hai tuần à? Làm trong một tuần được không?" là câu khiến engineer mất niềm tin ngay. Thời gian không co giãn theo ý muốn. Thay vào đó, đàm phán phạm vi (scope): "Nếu bỏ phần X thì có nhanh hơn không?".

Lỗi 3 — Bỏ qua nợ kỹ thuật (technical debt). Khi engineer xin thời gian "refactor" hay "trả nợ kỹ thuật", nhiều PM gạt đi vì "không thấy giá trị cho khách hàng". Nhưng nợ kỹ thuật tích tụ sẽ khiến mọi tính năng sau này chậm dần. Mẹo: phân bổ khoảng 15–20% năng lực mỗi sprint cho sức khỏe kỹ thuật, coi đó như bảo trì xe — không bảo trì thì có ngày chết máy giữa đường.

Lỗi 4 — Viết yêu cầu mô tả giải pháp kỹ thuật thay vì vấn đề. Đừng viết "dùng GraphQL gộp API". Hãy viết "dashboard cần tải dưới 1 giây" và để engineer chọn cách. PM nói vấn đề và mục tiêu, engineer quyết cách làm.

Mẹo vàng: Mỗi tuần dành 30 phút uống cà phê với một engineer, hỏi họ đang lo lắng điều gì về hệ thống. Bạn vừa học được nhiều nhất, vừa xây được mối quan hệ giúp công việc trôi chảy hơn mọi quy trình.

Bài tập thực hành

  • Vẽ kiến trúc: Nhờ một engineer trong team vẽ giúp bạn sơ đồ kiến trúc tổng thể của sản phẩm bạn đang làm (hoặc một sản phẩm bạn dùng quen như một app gọi xe). Xác định: đâu là client, có những service/database nào, cache nằm ở đâu.
  • Phân tích một yêu cầu: Lấy một tính năng bạn từng yêu cầu hoặc muốn xây. Trả lời ba câu ở Bước 3: nó đụng bao nhiêu phần hệ thống, dữ liệu nằm đâu, có cần real-time không. So sánh ước lượng ban đầu của bạn với ước lượng sau khi phân tích.
  • Dịch giải pháp thành vấn đề: Viết lại ba yêu cầu sau theo dạng "vấn đề + mục tiêu" thay vì áp giải pháp: (a) "Thêm Redis cache cho trang chủ"; (b) "Chuyển sang microservices"; (c) "Dùng CDN cho hình ảnh".
  • Từ vựng: Tự giải thích bằng lời của mình cho một người không rành kỹ thuật các khái niệm: API, latency, cache invalidation, technical debt. Nếu giải thích được đơn giản, bạn đã thật sự hiểu.

Tóm tắt

Tech literacy không phải là biết code — mà là hiểu đủ để ra quyết định đúng và giao tiếp như một đối tác với engineering. Bạn cần nắm các khối kiến trúc cơ bản: monolith vs microservices (cách hệ thống tổ chức), REST vs GraphQL (cách các phần nói chuyện), SQL vs NoSQL (cách dữ liệu được lưu), caching và CDN (tại sao có cái nhanh có cái chậm), cùng lựa chọn mobile native vs cross-platform.

Quan trọng hơn kiến thức là cách hành xử: hỏi đúng câu hỏi, không giả vờ hiểu, không ép ước lượng, tôn trọng nợ kỹ thuật, và luôn mô tả vấn đề thay vì áp giải pháp. Như ba tình huống đã cho thấy, một checkbox đơn giản có thể là sáu tuần đại phẫu, một yêu cầu "real-time" có thể được giải bằng cache invalidation thông minh, và một cuộc đổ lỗi có thể biến thành bài toán có lời giải. Khác biệt nằm ở chỗ PM có hiểu hệ thống hay không. Engineer không cần bạn giỏi như họ — họ cần bạn là người đáng tin để cùng xây. Tech literacy chính là cách bạn giành được niềm tin đó.