Trong một đội phần mềm, có một phép tính mà ai làm lâu cũng biết: viết một đoạn code mất một, bảo trì nó mất mười.
Con số cụ thể thì tuỳ nơi, nhưng tỉ lệ luôn nghiêng hẳn về phần sau. Phần lớn tiền của một hệ thống không tiêu vào lúc dựng, mà vào những năm sau đó — sửa lỗi, đổi yêu cầu, người cũ nghỉ người mới vào đọc lại.
Bây giờ khâu đầu tiên trong dây chuyền ấy vừa rẻ đi đột ngột.
Câu hỏi đúng không phải "máy viết code giỏi tới đâu". Câu hỏi đúng là: khâu nào trở thành nút thắt khi khâu viết không còn là nút thắt nữa?
Việc cụ thể: hàng đợi duyệt mã
Ở một đội làm phần mềm bình thường, mọi thay đổi phải qua một vòng: người khác đọc, hỏi, rồi mới cho gộp vào nhánh chính.
Trước đây vòng đó không tắc, vì tốc độ viết và tốc độ đọc xấp xỉ nhau.
Bây giờ một người có thể tạo ra lượng thay đổi gấp vài lần trong cùng một ngày. Nhưng tốc độ đọc thì không đổi — vẫn là một người, đọc bằng mắt, hiểu bằng đầu.
Kết quả rất dễ đo: thời gian một thay đổi nằm chờ duyệt. Nếu con số đó đang dài ra trong khi số dòng thay đổi tăng lên, thì đội đó vừa dời nút thắt chứ chưa tăng năng suất.
Và khi hàng đợi dài ra, có một áp lực rất tự nhiên xuất hiện: duyệt qua loa cho hết việc.
Cái gì lọt qua khi duyệt qua loa
Không phải lỗi cú pháp. Máy không mắc lỗi đó.
Lọt qua là những thứ khác:
Code chạy đúng nhưng làm sai việc. Đúng yêu cầu như đã diễn đạt, sai so với ý định thật. Người đọc kỹ mới hỏi được câu "khoan, chỗ này có tính cả trường hợp kia không?".
Xử lý sai ở rìa. Danh sách rỗng, số âm, người dùng bấm hai lần, mạng đứt giữa chừng. Máy viết phần chính rất tốt và phần rìa rất tuỳ hứng.
Trùng lặp âm thầm. Đã có sẵn một hàm làm đúng việc đó ở chỗ khác, nhưng máy không biết nên viết lại một bản gần giống. Sáu tháng sau, sửa một bản mà quên bản kia.
Thư viện không cần thiết. Kéo thêm phụ thuộc để làm một việc mười dòng — mỗi phụ thuộc là một khoản nợ dài hạn, cả về bảo mật lẫn bảo trì.
Không cái nào trong bốn thứ trên gây sự cố ngay. Chúng tích lại và làm hệ thống đắt dần lên.
Con số nên theo dõi
Ba thứ này đo được ngay, không cần công cụ gì đặc biệt:
Thời gian chờ duyệt trung bình. Dài ra là dấu hiệu nút thắt đã dời chỗ.
Tỉ lệ sự cố phải sửa gấp trên số lần phát hành. Đây là thước đo thật của chất lượng, và nó có độ trễ vài tuần nên dễ bị bỏ qua.
Số dòng thay đổi trung bình cho mỗi lần duyệt. Con số này tăng lên là báo động — không ai đọc kỹ được một thay đổi dài tám trăm dòng, và người duyệt sẽ chỉ liếc rồi bấm đồng ý.
Cách chữa hiệu quả nhất cũng đơn giản nhất: chia nhỏ thay đổi. Nghe cũ kỹ, nhưng nó là biện pháp duy nhất thật sự chống được việc duyệt hình thức.
Chỗ máy làm rất tốt
Cần nói rõ để khỏi thiên lệch. Có những việc mà công cụ sinh mã giúp ích thấy rõ, và không có mặt trái đáng kể:
Viết bộ kiểm thử cho code đã có — việc chán, ai cũng lười, và làm đầy đủ thì giá trị rất cao.
Đọc hiểu một hệ thống cũ mà người viết đã nghỉ. Đây có lẽ là ứng dụng giá trị nhất và ít được nói tới nhất: hỏi "đoạn này làm gì" và có câu trả lời trong mười giây thay vì hai tiếng.
Việc chuyển đổi máy móc: đổi định dạng, đổi tên hàng loạt, chuyển từ thư viện này sang thư viện kia.
Điểm chung: những việc mà đúng hay sai kiểm được ngay. Đó là ranh giới đáng nhớ.
Một chỗ đắt tiền mà ít ai tính trước
Có một khoản chi phát sinh gần như chắc chắn ở các đội tăng tốc bằng công cụ sinh mã, và nó không nằm trong bảng dự toán nào: chi phí đào tạo người mới vào nghề.
Trước đây người mới học nghề bằng cách làm những việc nhỏ — sửa lỗi vặt, viết hàm đơn giản, dọn dẹp code cũ. Chán, nhưng đó là cách hình thành trực giác.
Bây giờ những việc ấy là thứ máy làm nhanh nhất và rẻ nhất. Nên chúng không còn được giao cho người mới nữa.
Hệ quả xuất hiện sau vài năm chứ không phải ngay: một đội có người rất giỏi và người rất mới, thiếu hẳn tầng ở giữa — vì tầng ở giữa được hình thành từ chính những việc đã bị lấy mất.
Đội nào nhận ra sớm thì cố tình giữ lại một phần việc nhỏ cho người mới làm tay, chấp nhận chậm hơn. Đó là khoản đầu tư, không phải lãng phí.
Phần AI không chạm tới
Nó không chịu trách nhiệm khi hệ thống sập lúc hai giờ sáng. Trách nhiệm đó không chuyển đi đâu được — nó vẫn nằm ở người ký duyệt. Và điều này thay đổi cách nên duyệt: gộp code mình chưa hiểu là nhận trách nhiệm cho thứ mình không hiểu.
Nó không biết hệ thống này đã từng hỏng vì cái gì. Mỗi hệ thống có một lịch sử vết sẹo — chỗ này đừng đụng vì năm ngoái đụng là mất dữ liệu, chỗ kia trông thừa nhưng đang gánh một khách hàng lớn. Thứ đó nằm trong đầu người, không nằm trong mã.
Nó không quyết được cái gì không nên làm. Phần lớn giá trị của một người kỹ thuật giỏi nằm ở việc nói "cái này không cần xây" — tiết kiệm được nhiều hơn mọi tối ưu.
Nó không thương lượng được với người đặt yêu cầu. Rất nhiều vấn đề kỹ thuật khó thật ra là vấn đề yêu cầu chưa rõ, và cách giải rẻ nhất là ngồi nói chuyện cho rõ, không phải viết thêm code.
Và cái tên
Đây là một ngách mà người đọc rất khó tính: lập trình viên và người quản lý kỹ thuật. Họ nhận ra ngay nội dung viết cho có, và họ nhớ rất lâu nơi nào nói đúng.
Cũng là ngách mà khâu thực thi vừa mất giá nhanh nhất — dựng một trang, viết một bài hướng dẫn, làm một công cụ nhỏ giờ là việc của một buổi tối.
Thứ không rẻ đi là một địa chỉ mà người trong nghề tìm tới vì tin nội dung ở đó. Nó tích luỹ chậm, và không sao chép được.
AiLapTrinh.com ghép đúng hai chữ mà cả ngành đang dùng hằng ngày, ngắn, gõ một lần là nhớ.
Tên miền nhắc trong bài: AiLapTrinh.com