Một màn hình đỏ rực những lời chê bai có thể giết chết đam mê của một lập trình viên trẻ. Ảnh: AI Generated
Tôi vẫn nhớ như in ngày đầu tiên đi làm tại một công ty công nghệ lớn, cách đây gần một thập kỷ. Đó là một buổi sáng thứ Năm. Sau ba ngày ròng rã cày cuốc, đọc tài liệu mờ cả mắt, thử đi thử lại hàng chục lần trên máy cá nhân, tôi cuối cùng cũng run run bấm nút tạo Pull Request (PR) đầu tiên trong sự nghiệp của mình. Đó chỉ là một tính năng nhỏ: Thêm một bộ lọc tìm kiếm cho danh sách người dùng. Nhưng với tôi, 300 dòng code đó giống như một kiệt tác nghệ thuật mà tôi đã vắt kiệt tâm huyết để tạo ra.
Tôi háo hức chờ đợi vị Senior Developer của team vào phê duyệt. Tôi đã mường tượng ra viễn cảnh anh ấy sẽ vỗ vai tôi và nói: "Làm tốt lắm chàng trai, code rất sạch sẽ". Nhưng không. Chỉ 2 tiếng sau, thông báo từ Github nổ liên hồi. Tôi mở màn hình lên, và tim tôi như ngừng đập. Toàn bộ 300 dòng code của tôi bị nhuộm đỏ bởi... 45 cái comments.
"Tại sao lại dùng vòng lặp ở đây? Hiệu năng quá tệ!"
"Tên biến này chả có nghĩa lý gì cả."
"Kiến trúc lộn xộn. Xem lại pattern đi."
"Chưa bắt exception ở chỗ này, lỡ crash app thì ai đền?"
Mỗi một dòng comment lạnh lùng chọc thẳng vào lòng tự trọng của tôi như những nhát dao. Tôi cảm thấy mặt mình nóng ran, sống mũi cay xè. Tôi chạy vội vào nhà vệ sinh công ty, khóa trái cửa lại và ngồi thẫn thờ trên bồn cầu. Trong đầu tôi văng vẳng một suy nghĩ tồi tệ nhất mà một lập trình viên trẻ có thể nghĩ đến: "Có lẽ mình là một kẻ bất tài. Mình không hợp với nghề này. Chắc mình nên xin nghỉ việc".
Bạn đã bao giờ trải qua cảm giác đó chưa? Cảm giác bị "lột trần" trước mặt đám đông, bị chỉ trích từng dấu phẩy, từng khoảng trắng bởi những người giỏi hơn mình. Chào mừng bạn đến với văn hóa Code Review (Đánh giá mã nguồn) – một trong những nghi thức bắt buộc, quan trọng nhất, nhưng cũng đầy tổn thương nhất trong ngành Công nghiệp Phần mềm.
Nếu không được thực hiện đúng cách, Code Review sẽ biến thành một bãi chiến trường độc hại, nơi những cái tôi (Ego) khổng lồ va chạm nhau, nơi các Senior sỉ nhục Junior để ra oai, và nơi những dòng code bị từ chối đồng nghĩa với việc nhân cách con người bị phủ nhận. Nhưng nếu được thực hiện bằng sự thấu cảm và trí tuệ, Code Review chính là lò luyện kim vĩ đại nhất để đúc nên những kỹ sư phần mềm đẳng cấp thế giới. Hãy cùng tôi giải phẫu bức tranh tâm lý phức tạp ẩn sau những dòng comment trên Github.
1. Sự Hiểu Lầm Chết Người Về Bản Chất Của Code Review
Phần lớn các công ty công nghệ hiện nay đang hiểu sai hoàn toàn về mục đích cốt lõi của Code Review. Họ coi đó là một "Trạm kiểm soát an ninh", nơi các Senior đóng vai trò như những viên cảnh sát giao thông, cầm còi tuýt phạt những lỗi sai cú pháp, những dòng code quên thụt lề (indentation), hay những biến chưa được khai báo.
Sự thật là: Nếu bạn vẫn dùng sức người để tìm kiếm lỗi cú pháp (Syntax error) hay lỗi Format code, thì team của bạn đang sống ở thời kỳ đồ đá. Chúng ta đang ở thập kỷ của AI, của CI/CD (Continuous Integration/Continuous Deployment). Những công việc tẻ nhạt đó sinh ra là để dành cho máy móc. Một hệ thống Linter (như ESLint, SonarQube) hay các bot kiểm thử tự động hoàn toàn có thể quét 10.000 dòng code trong 5 giây và chỉ ra lỗi dư dấu phẩy chính xác hơn bất kỳ con người nào.
Vậy thì con người ngồi review code để làm gì? Code Review không phải là một công cụ bắt lỗi. Nó là một nền tảng chia sẻ tri thức (Knowledge Transfer) và Đồng thuận kiến trúc (Architectural Consensus).
- Chia sẻ tri thức: Khi một người giỏi đọc code của bạn, họ không chỉ ra lỗi sai, họ đang chỉ cho bạn một ĐƯỜNG ĐI NGẮN HƠN. Ví dụ, bạn viết một vòng lặp lồng nhau mất độ phức tạp O(n^2), người Senior sẽ comment: "Anh nghĩ nếu chúng ta dùng HashMap ở đây thì độ phức tạp chỉ còn O(n). Em thấy sao?". Bạn vừa học được một bài học vô giá về thuật toán mà không trường đại học nào dạy.
- Đồng thuận kiến trúc: Khi dự án kéo dài 5 năm, trải qua tay 20 lập trình viên khác nhau, code sẽ trở thành một mớ hỗn độn (Spaghetti code) nếu mỗi người viết theo một phong cách (Design Pattern) khác nhau. Code Review là nơi team thống nhất rằng: "Trong dự án này, chúng ta sẽ quản lý State bằng Redux, chứ không dùng Context API". Nó đảm bảo tính nhất quán của hệ thống.
- Giảm rủi ro (Bus factor): "Bus factor" là số lượng lập trình viên tối thiểu bị... xe buýt tông (hoặc đột ngột nghỉ việc) khiến dự án sụp đổ. Nếu bạn viết một đoạn code cực kỳ phức tạp mà không ai review, bạn trở thành người duy nhất hiểu nó. Nếu ngày mai bạn xin nghỉ bệnh, cả công ty sẽ tê liệt. Code Review đảm bảo luôn có ít nhất 2 người hiểu rõ từng ngóc ngách của hệ thống.
"Máy móc kiểm tra tính đúng đắn của code (Correctness). Nhưng chỉ có con người mới có thể kiểm tra tính bảo trì (Maintainability) và tính nghệ thuật (Elegance) của code."
2. Cái Bẫy "Bản Ngã" (Ego) - Kẻ Thù Số Một Trong Giao Tiếp Kỹ Thuật
Nghề lập trình viên là một nghề rất kỳ lạ. Chúng ta dành từ 8 đến 12 tiếng mỗi ngày dán mắt vào màn hình, gõ lạch cạch trên bàn phím để biến những suy nghĩ trừu tượng thành các sản phẩm vật lý (dù chỉ là vật lý trên môi trường ảo). Code của chúng ta chính là đứa con tinh thần, là sự phản chiếu trực tiếp trí thông minh, tư duy logic và sức sáng tạo của chúng ta.
Đó chính là lý do vì sao Cái tôi (Ego) của lập trình viên thường lớn khủng khiếp. Trong tâm lý học, có một khái niệm gọi là Sự thiên kiến gắn kết (Attachment Bias). Khi bạn càng dành nhiều thời gian và tâm huyết để tạo ra một thứ gì đó, bạn càng có xu hướng bảo vệ nó một cách mù quáng và coi mọi lời chỉ trích nhắm vào vật đó là nhắm thẳng vào cá nhân mình.
Code Review nên là một cuộc trò chuyện để tìm ra giải pháp tốt nhất, không phải là một cuộc đấu khẩu để phân định thắng thua. Ảnh: AI Generated
Góc nhìn của người viết code (Author's Ego): Khi người review comment: "Đoạn code này xử lý chậm và tốn bộ nhớ". Bộ não của người viết tự động dịch câu nói đó thành: "Mày là một thằng ngu. Tư duy của mày quá kém cỏi". Và ngay lập tức, cơ chế phòng vệ tự nhiên (Fight or Flight) được kích hoạt. Thay vì bình tâm xem xét lại độ phức tạp thuật toán, họ sẽ bắt đầu gõ phím cãi lại bằng những lập luận cùn: "Máy tính bây giờ RAM 16GB rồi, tốn chút bộ nhớ có sao đâu", "Chạy trên máy tôi vẫn nhanh cơ mà".
Góc nhìn của người đánh giá (Reviewer's Ego): Phía bên kia chiến tuyến, các Senior cũng mang trong mình những "con quỷ bản ngã" vô cùng độc hại. Nhiều người mắc phải tâm lý "Chứng minh quyền lực" (Power Tripping). Họ mang định kiến rằng: Nếu mình approve (chấp thuận) một cái Pull Request mà không để lại bất kỳ comment sửa lỗi nào, thì trông mình có vẻ kém chuyên môn, không xứng đáng làm Senior. Thế là họ bắt đầu soi mói những thứ vụn vặt vô nghĩa (Nitpicking): Bắt đổi tên biến từ userInfo sang user_data, bắt thay đổi cách viết hàm dù cả hai cách đều tối ưu như nhau. Họ không đi tìm giải pháp tốt hơn, họ đi tìm sự công nhận đẳng cấp.
Sự đụng độ của hai cái tôi khổng lồ này biến Github trở thành một võ đài. Thời gian dự án bị kéo dài, tính năng không được deploy đúng hạn, và tinh thần của cả team vỡ vụn.
3. Giải Phẫu Tâm Lý Một Dòng Comment "Sát Thương"
Ngôn từ là một thứ vũ khí đáng sợ, đặc biệt là trong môi trường giao tiếp qua văn bản (text-based) như Code Review, nơi chúng ta hoàn toàn bị tước đoạt đi ngôn ngữ cơ thể, nét mặt và giọng điệu. Một câu nói đùa ngoài đời thực có thể biến thành một lời sỉ nhục gay gắt khi nằm trên màn hình máy tính.
Hãy cùng phân tích một ví dụ thực tế. Giả sử Junior vô tình gọi API lấy dữ liệu nằm bên trong một vòng lặp for (điều này sẽ làm server quá tải). Dưới đây là 3 cách một Senior có thể comment, và hậu quả tâm lý của nó:
- Cấp độ 1 - Độc hại (Toxic): "Tại sao lại gọi API trong vòng lặp thế này? Định làm sập database à? Code thế này sao qua vòng phỏng vấn được?"
👉 Phân tích: Câu nói này chứa đựng sự công kích cá nhân (Ad Hominem) cực kỳ nặng nề. Từ "Tại sao" mang sắc thái hạch hỏi, lên án. Câu hỏi tu từ "Định làm sập database à" mang tính nhạo báng. Hậu quả: Lập trình viên trẻ sẽ bị sốc tâm lý, mất hoàn toàn sự tự tin, và hận thù người review. Dự án biến thành chiến trường. - Cấp độ 2 - Mệnh lệnh (Dictatorial): "Chuyển lệnh gọi API ra ngoài vòng lặp. Dùng hàm map() để xử lý dữ liệu sau khi fetch xong."
👉 Phân tích: Về mặt kỹ thuật, câu nói này đúng 100%. Nó giải quyết được bài toán. Nhưng về mặt tâm lý học lãnh đạo, nó hoàn toàn thất bại. Nó là một chỉ thị từ trên xuống. Người Junior sẽ cắn răng làm theo như một cái máy, nhưng họ không hiểu TẠI SAO mình phải làm vậy, và họ cảm thấy mình giống như một người thợ gõ code thuê chứ không phải là một Kỹ sư phần mềm được tôn trọng. - Cấp độ 3 - Khai vấn (Coaching/Thấu cảm): "Đoạn code này xử lý data rất tốt. Tuy nhiên, anh thấy chúng ta đang gọi API N lần trong vòng lặp. Nếu danh sách có 10.000 phần tử, server có thể bị nghẽn. Em nghĩ sao nếu chúng ta gọi API 1 lần để lấy toàn bộ data ở ngoài, rồi dùng map() để match lại?"
👉 Phân tích: Đây là nghệ thuật giao tiếp đỉnh cao. Đầu tiên, người review sử dụng Kỹ thuật Sandwich (Khen ngợi - Góp ý - Mở rộng): Khen đoạn xử lý data tốt trước để hạ vũ khí phòng thủ của đối phương xuống. Thứ hai, họ dùng đại từ "Chúng ta" (We) thay vì "Em" (You) để nhấn mạnh rằng: Chúng ta ở cùng một phe chiến đấu với cái bug, chứ không phải anh đang chống lại em. Thứ ba, thay vì ra lệnh, họ dùng câu hỏi mở "Em nghĩ sao nếu..." để trao lại quyền quyết định cho tác giả, kích thích họ tự tư duy và làm chủ dòng code của mình.
4. Nghệ Thuật Lột Bỏ Cái Tôi Dành Cho Junior
Nếu bạn là một lập trình viên trẻ vừa chập chững vào nghề, tôi có một lời khuyên cay đắng nhưng thực dụng nhất dành cho bạn: Bạn không phải là code của bạn. Mã nguồn bạn viết ra không đại diện cho giá trị con người bạn.
Hãy tưởng tượng bạn là một thợ mộc đóng một cái ghế. Khi có người chỉ ra rằng cái chân ghế này hơi lung lay, bạn có khóc lóc và cảm thấy nhân cách mình bị xúc phạm không? Tất nhiên là không! Bạn sẽ lấy búa đóng lại vài cái đinh cho chắc chắn. Code cũng vậy. Nó là một Sản Phẩm (Product). Nó được sinh ra để phục vụ khách hàng. Khi có người tìm ra lỗi, điều đó có nghĩa là sản phẩm đang được nâng cấp, chứ không phải bạn đang bị hạ thấp.
Hơn thế nữa, hãy tập thói quen Biết ơn những lời phê bình tàn nhẫn. Trong thế giới doanh nghiệp khắc nghiệt, không ai rảnh rỗi dành ra 30 phút cuộc đời họ để ngồi săm soi từng dòng code và viết comment giải thích cho bạn nếu họ không thực sự muốn hệ thống tốt hơn. Đáng sợ nhất không phải là một PR bị comment 50 lỗi. Đáng sợ nhất là một PR chứa đầy rác rưởi nhưng lại được người ta lạnh lùng bấm "Approve" (Chấp thuận) chỉ vì họ lười biếng và mặc kệ sống chết của dự án.
Hãy để máy móc làm những công việc nhàm chán như kiểm tra format, con người chỉ nên tranh luận về kiến trúc hệ thống. Ảnh: AI Generated
5. Văn Hóa "Ghi Nhận" (Appreciation) - Thứ Vũ Khí Bí Mật Bị Lãng Quên
Một trong những sai lầm lớn nhất của các team kỹ thuật là coi Code Review chỉ là một công cụ để vạch lá tìm sâu. Chúng ta có xu hướng chỉ comment khi thấy lỗi sai, và im lặng khi thấy những điều tuyệt vời.
Nếu bạn đang review và bắt gặp một đoạn code tái cấu trúc (Refactor) cực kỳ thông minh, một thuật toán tối ưu vượt ngoài mong đợi, hay đơn giản là một bộ unit test được viết quá tỉ mỉ, HÃY DỪNG LẠI VÀ COMMENT KHEN NGỢI.
"Wow, cách dùng Regex ở đây thông minh quá, anh chưa nghĩ ra luôn!"
"Đoạn tách component này rất sạch sẽ, đúng chuẩn SOLID. Tuyệt lắm em."
Bạn không thể tưởng tượng được một dòng comment khen ngợi nhỏ nhoi đó có sức mạnh tâm lý khủng khiếp như thế nào đâu. Nó có thể khiến một lập trình viên vui vẻ suốt cả tuần, tạo ra một liều Dopamine khổng lồ thúc đẩy họ viết ra những dòng code sạch hơn, xuất sắc hơn trong những lần tiếp theo. Thay vì bấm nút "LGTM" (Looks Good To Me - Trông ổn đấy) một cách vô cảm, hãy đầu tư thêm 10 giây để chỉ ra điểm bạn thích nhất trong Pull Request đó. Đó là nghệ thuật lãnh đạo không chức danh.
🛠 CẨM NANG HÀNH ĐỘNG (ACTIONABLE TAKEAWAYS)
Để biến quá trình Code Review từ một "địa ngục trần gian" thành một lớp học cao cấp, hãy áp dụng các nguyên tắc sinh tồn sau:
🔥 Dành Cho Người Viết Code (Author):
- Tự Review chính mình trước: Đừng bao giờ tạo PR xong rồi quăng đó cho người khác dọn rác. Hãy tự đọc lại toàn bộ code của mình một lần (Self-review), xóa các lệnh
console.log, sửa các tên biến vô nghĩa. Đừng bắt Senior lãng phí thời gian vào những lỗi ngớ ngẩn. - Viết Description (Mô tả) có tâm: Đừng để trống phần mô tả PR. Hãy giải thích rõ ràng: Tính năng này làm gì? Thay đổi những file cốt lõi nào? Có đính kèm ảnh chụp màn hình UI trước/sau không? Người review sẽ có ngữ cảnh (Context) đầy đủ để hỗ trợ bạn tốt nhất.
- Giữ PR ở mức siêu nhỏ (Small PRs): Không ai đủ kiên nhẫn và tỉnh táo để review một cái PR chứa 3000 dòng code thay đổi. Hãy cắt nhỏ tính năng ra thành nhiều PR nhỏ (dưới 400 dòng). Review nhanh hơn, an toàn hơn, ít lỗi hơn.
🌟 Dành Cho Người Đánh Giá (Reviewer):
- Nguyên tắc "Đưa ra giải pháp, không chỉ bới móc": Nếu bạn chê một đoạn code là tồi tệ, bạn có trách nhiệm phải gợi ý một hướng giải quyết tốt hơn (Kèm theo link tài liệu hoặc đoạn code ví dụ). Nếu bạn chỉ biết chê mà không biết cách sửa, hãy im lặng.
- Dùng từ "Chúng ta" thay vì "Bạn": Chuyển từ hệ tư duy đối đầu sang hợp tác. Thay vì nói: "Code của em làm sập hệ thống", hãy nói: "Nếu chúng ta để logic này ở đây, hệ thống của chúng ta có thể bị quá tải".
- Thiết lập ranh giới "Chặn" (Block) và "Gợi ý" (Nitpick): Nếu lỗi nghiêm trọng ảnh hưởng đến bảo mật/hiệu năng -> Comment yêu cầu sửa bắt buộc (Block). Nếu chỉ là gợi ý tối ưu nhỏ không ảnh hưởng lớn -> Thêm tiền tố
[Nit]hoặc[Optional]để báo cho tác giả biết họ có thể bỏ qua nếu đang gấp. Đừng bắt dự án dừng lại chỉ vì một cái tên biến không vừa mắt bạn.
Lời kết: Viết ra một phần mềm hoạt động được là một môn Khoa học phức tạp. Nhưng để phối hợp hàng chục con người với những cái tôi kiêu hãnh cùng viết ra một phần mềm xuất chúng, đó lại là một môn Nghệ thuật thấu cảm. Lần tới, trước khi bạn gõ một dòng comment chỉ trích cay nghiệt và bấm phím Enter, hãy nhớ rằng: Đằng sau màn hình xanh xao kia không phải là một cỗ máy đẻ code, mà là một con người bằng xương bằng thịt, với những áp lực, sự tự ti và khao khát được công nhận y hệt như bạn thuở mới vào nghề. Hãy Review bằng trái tim.