Đã bao giờ bạn tự hỏi: Tại sao mình lại quay lại C++ hay C sau khi đã nghiện sự tiện lợi của Go?
Mình nhớ hồi mới vào nghề, ai cũng bảo Go is the future. Đúng thật, viết code mượt như gió, goroutine thì nhẹ tênh, deploy dễ dàng, ai mà không thích? Nhưng càng lớn, càng làm những hệ thống yêu cầu performance tối đa, mình bắt đầu thấy "đói". Đói về sự kiểm soát.
Đó là lúc mình bắt đầu lờ lững bước sang Rust. Ban đầu, borrow checker của Rust khiến mình muốn đập bàn phím. Nó như một người thầy giáo nghiêm khắc quá đà, bắt mình suy nghĩ từng milimet về vòng đời của một String hay con trỏ. Nhưng một khi đã vượt qua rào cản đó, cảm giác an toàn mà nó mang lại là thứ mà Go không bao giờ cho được. Không còn những con quỷ data race lén lút phát sinh ở production nữa.
Nhưng rồi, mình lại nhớ C. Có một sự thuần khiết nào đó trong C. Không có boilerplate, không có magic, chỉ là bộ nhớ và CPU. Khi cần tối ưu từng byte, hay viết driver, hay làm phần cứng nhúng, C vẫn là vua. Mình nhớ có lần debug một issue về memory leak trong một module C++ cũ kỹ. Cảm giác chạy gdb, xem từng dòng assembly, hiểu rõ tại sao con trỏ đó bị dangling là một trải nghiệm "cực khoái" theo kiểu đen tối của dân systems programming.
Có phải các bạn nghĩ mình già nua rồi? Có lẽ vậy. Nhưng mình tin rằng một developer giỏi không phải là người chỉ biết dùng ngôn ngữ mới nhất, mà là người hiểu sâu bản chất của máy tính. Go nhanh và tiện, Rust an toàn và mạnh mẽ, C thì nhỏ gọn và kinh điển. Mỗi thứ đều có vị trí của nó.
Hôm qua, mình thử viết một cái tiny HTTP server bằng Rust chỉ để giải khuây. Code dài gấp đôi Go, compile time thì... à, hơi lâu. Nhưng khi nó chạy với latency thấp hơn 5ms, mình tự nhủ: "Đáng giá quá". Công việc của chúng ta không chỉ là viết code để nó chạy, mà là viết code để nó chạy thông minh.
Chúc các bạn luôn tìm thấy niềm vui trong từng dòng code, dù đó là print("hello") hay là fight với undefined behavior của C.