Quan điểm gây sốc sắp xuất hiện.
Hãy chuẩn bị tinh thần.
Tôi đã dành khá nhiều thời gian viết về nợ kỹ thuật, rao giảng các thực hành code sạch, và ủng hộ kiến trúc hợp lý.
Tôi đã nói với các nhà phát triển cách tránh nó, cách trả nó, cách thương lượng nó với quản lý của họ.
Vấn đề là đây:Tôi đã sai một phần.
Không phải về các thực hành—những thứ đó vẫn tốt.
Thậm chí không phải về mọi cách sử dụng của thuật ngữ.
Mà là về việc chấp nhận khung khái niệm mà không có sự phê phán.
Nợ kỹ thuật không chỉ bị hiểu sai;
nó là một phép ẩn dụ cơ bản đã hỏng và đang bóp méo cách chúng ta nghĩ về phát triển phần mềm.
Và phần tệ nhất?
Chúng ta cứ tiếp tục sử dụng nó vì đó là phép ẩn dụ tài chính duy nhất mà giới điều hành hiểu, điều đó có nghĩa là chúng ta bị mắc kẹt trong việc giải thích các vấn đề kỹ thuật bằng những thuật ngữ đang chủ động che khuất điều thực sự đang xảy ra.
Để tôi giải thích.
Nội dung chính
Mục Lục
- Vấn Đề với Phép Ẩn Dụ
- Nợ Ngụ Ý Bạn Đã Có Lựa Chọn
- Mọi Code Đều Lão Hóa (Đó Không Phải Là Nợ, Đó Là Entropy)
- “Nợ” Thường Là Quyết Định Đúng Đắn
- Điều Mà Quản Lý Gọi Là “Nợ”, Kỹ Sư Gọi Là “Sự Đánh Đổi”
- Vấn Đề Thực Sự:
Sự Ngu Dốt Chồng Chất - Được Rồi, Nhưng Còn Những Đường Tắt Thực Sự Thì Sao?
- Sự Thật Khó Chịu:
Đôi Khi Nó Thực Sự Là Kỹ Thuật Tồi - Sự Tinh Tế Mà Không Ai Muốn Nói Đến
- Khi Kỹ Sư Cần Phải Chịu Trách Nhiệm
- Vậy Chúng Ta Nên Gọi Nó Là Gì Thay Thế?
- Điểm Mấu Chốt
⁉️ Vấn Đề với Phép Ẩn Dụ
Ward Cunninghamđặt ra thuật ngữ “nợ kỹ thuật” vào năm 1992 để mô tả một kịch bản cụ thể:
cố ý chọn một cách triển khai nhanh với hiểu biết rằng bạn sẽ tái cấu trúc nó sau này.
Giống như nợ tài chính, bạn đang vay thời gian bây giờ với lời hứa sẽ trả lại với lãi suất.
Nhưng đây là điều thực sự xảy ra trong hầu hết các tổ chức:
Quản lý:“Tại sao tính năng này lại mất nhiều thời gian thế?
Tôi tưởng anh nói sẽ xong trong hai tuần?”
Kỹ sư:“À, chúng tôi có nhiều nợ kỹ thuật phải xử lý…”
Quản lý:“Ôi, tại sao các anh không viết code tốt hơn ngay từ đầu?”
Và cứ thế, các kỹ sư trở thành kẻ xấu.
Những người “tích lũy nợ”.
Những người đi “đường tắt”.
Những người đang kìm hãm công ty.
Ngoại trừ việc đó hoàn toàn là nhảm nhí.
🗳 Nợ Ngụ Ý Bạn Đã Có Lựa Chọn
Nợ thực sự hoạt động như thế này:
bạn đến một người cho vay, đàm phán điều khoản, ký giấy tờ, và đồng ý trả lại số tiền gốc cộng với lãi suất.
Bạn hiểu thỏa thuận.
Bạn đồng ý với nó.
Nợ kỹ thuật?
Đây là cách nó thực sự xảy ra:
Quản lý:“Chúng ta cần phải giao cái này trước thứ Sáu cho buổi demo với nhà đầu tư.”
Kỹ sư:“Không đủ thời gian để làm đúng cách.
Chúng ta cần ít nhất ba tuần để xây dựng nó đúng.”
Quản lý:“Làm cho nó chạy được.
Tôi không quan tâm bằng cách nào.”
[Ba tháng sau]
Quản lý:“Codebase này là một mớ hỗn độn.”
Thấy vấn đề chưa?
Kỹ sư không “vay” bất cứ thứ gì.
Họ không chọn nợ.
Họ bị đưa ra những ràng buộc bất khả thi và đã làm tốt nhất có thể.
Và giờ họ bị đổ lỗi cho “lãi suất”.
Đây không phải là nợ kỹ thuật.
Đó là hậu quả kỹ thuật của các quyết định quản lý.
🗿 Mọi Code Đều Lão Hóa (Đó Không Phải Là Nợ, Đó Là Entropy)
Đây là một điều khác khiến tôi phát điên:
gọi bất kỳ code cũ nào là “nợ kỹ thuật”.
Codebase 4 năm tuổi của bạn sử dụng React 16 thay vì phiên bản mới nhất không phải là “nợ”.
API của bạn trả về XML thay vì GraphQL không phải là “nợ”.
Kiến trúc nguyên khối mà giờ ai cũng ước là microservices của bạn không phải là “nợ”.
Đó chỉ làcode tồn tại trong thời gian.
Yêu cầu thay đổi.
Nền tảng phát triển.
Thực hành tốt nhất thay đổi.
Các framework mới xuất hiện.
Bối cảnh mà code của bạn được viết ra không phải là bối cảnh nó tồn tại ngày hôm nay.
Gọi đây là “nợ” ngụ ý ai đó đã phạm sai lầm.
Nó ngụ ý sự cẩu thả.
Nó ngụ ý rằng nếu chỉ các kỹ sư thông minh hơn, có tầm nhìn xa hơn, có năng lực hơn, thì đây đã không phải là vấn đề.
Nhưng phần mềm không hoạt động như vậy.Bất cứ thứ gìcũng không hoạt động như vậy.
Bạn không thể dự đoán tương lai.
Bạn không thể xây dựng cho những yêu cầu chưa tồn tại.
Và ngay cả khi bạn có thể, bạn sẽ đang kỹ thuật quá mức và lãng phí thời gian xây dựng sự linh hoạt mà bạn sẽ không bao giờ dùng đến.
🛎 “Nợ” Thường Là Quyết Định Đúng Đắn
Hãy nói về MVP mà bạn đã xây dựng hai năm trước.
Thứ giờ đây là “di sản”.
Thứ “cần được viết lại”.
Thứ “đang kìm hãm bạn”.
Bạn biết MVP đó còn làm được gì không?Nó xác thực mô hình kinh doanh của bạn.
Nó thu hút nghìn người dùng đầu tiên.
Nó tạo ra doanh thu cho phép bạn có cuộc trò chuyện này.
Không có “code tồi” đó, bạn chẳng có gì.
Bạn đã phá sản trong khi chờ đợi “kiến trúc hoàn hảo”.
Nhưng giờ khi nó thành công, khi nó đang mở rộng quy mô, khi bạn muốn di chuyển nhanh hơn…
đột nhiên nó trở thành “nợ kỹ thuật”.
Đột nhiên các kỹ sư đã xây dựng thứ làm cho công ty của bạn tồn tại được lại bị đổ lỗi vì đã không xây dựng nó “đúng cách”.
Đây là thiên kiến sống sót và thiên kiến muộn màng cuộn lại thành một cái burrito độc hại.
💳 Điều Mà Quản Lý Gọi Là “Nợ”, Kỹ Sư Gọi Là “Sự Đánh Đổi”
Mọi quyết định kỹ thuật đều là một sự đánh đổi.
Không phải một số.
Không phải hầu hết.Tất cả.
- Tốc độ so với tính linh hoạt
- Sự đơn giản so với tính năng
- Công nghệ đã được chứng minh so với công nghệ tiên phong
- Xây dựng so với mua
- Nguyên khối so với microservices
- SQL so với NoSQL
- Phạm vi kiểm thử so với tốc độ giao hàng
Không có câu trả lời “đúng” cho bất kỳ điều nào trong số này.
Chỉ có “đúng cho bối cảnh, ràng buộc và ưu tiên hiện tại của chúng ta”.
Quản lý giỏi hiểu điều này.
Họ tham gia vào những quyết định này.
Họ nói những điều như:
“Chúng ta đang tối ưu hóa cho tốc độ ngay bây giờ vì chúng ta cần xác thực thị trường.
Chúng ta sẽ xem xét lại kiến trúc một khi đạt được sự phù hợp sản phẩm-thị trường.”
Quản lý tồi nói:
“Cứ làm cho nó chạy đi.
Tự tìm cách giải quyết.”
Và sau đó:
“Tại sao lại có nhiều nợ kỹ thuật thế?”
🙈 Vấn Đề Thực Sự:
Sự Ngu Dốt Chồng Chất
Đây là điều thực sự xảy ra khi các nhà quản lý không hiểu bản chất chồng chất của chi phí bảo trì:
Năm 1:“Giao hàng nhanh!
Đừng lo về code hoàn hảo!”
Năm 2:“Tại sao các tính năng mới lại mất nhiều thời gian hơn?
Chúng ta từng giao hàng rất nhanh mà!”
Năm 3:“Chúng ta cần dừng tất cả công việc tính năng và thực hiện viết lại.”
Đây không phải là nợ kỹ thuật.
Đây là việc ban quản lý không hiểu rằng bảo trì phần mềm không phải miễn phí.
Rằng mỗi tính năng đều làm tăng diện tích bề mặt cần quản lý.
Rằng mỗi phụ thuộc đều cần được cập nhật.
Rằng mỗi API đều cần phiên bản hóa.
Các kỹ sư đã biết điều này.
Họ đã nói với bạn.
Bạn đã không lắng nghe vì bạn chỉ tập trung vào quý tiếp theo.
➖ Được rồi, Nhưng Còn về NhữngLối Tắt Thực SựThì Sao?
Được thôi.
Đúng vậy.
Đôi khi các kỹ sư thực sự cắt góc.
Chúng tôi bỏ qua việc viết kiểm thử.
Chúng tôi mã hóa cứng giá trị.
Chúng tôi không xử lý lỗi đúng cách.
Chúng tôi sao chép-dán thay vì trừu tượng hóa.
Nhưng bạn biết không?Điều đó hầu như luôn xảy ra vì áp lực từ bên ngoài.
“Chúng ta cần cái này cho buổi demo ngày mai.”
“Khách hàng đang đe dọa sẽ rời đi nếu chúng ta không giao hàng tuần này.”
“Chúng ta đang chảy máu tiền mặt và cần doanh thu ngay bây giờ.”
Ngay cả những quyết định kỹ thuật thực sự tồi cũng thường được đưa ra dưới áp lực, với thời gian hạn chế, thông tin không đầy đủ và sức ép khổng lồ từ…
chờ đã…
ban quản lý.
🔧 Sự Thật Khó Chịu:
Đôi Khi Nó Thực Sự Là Kỹ Thuật Tồi
Được rồi, hãy thành thật ở đây.
Tôi không thể viết cả một bài bảo vệ các kỹ sư mà không thừa nhận con voi trong phòng:đôi khi mã nguồn thực sự chỉ là tệ, và đó không phải lỗi của ban quản lý.
Đôi khi bạn thuê một nhà phát triển mà:
- Không hiểu ngôn ngữ hoặc framework họ đang sử dụng
- Sao chép câu trả lời từ Stack Overflow mà không hiểu chúng
- Viết các câu điều kiện lồng nhau mười hai tầng vì họ chưa bao giờ học về việc trả về sớm
- Tạo ra các lớp “God class” với 5,000 dòng mã vì “dễ hơn khi giữ mọi thứ ở một chỗ”
- Từ chối học hỏi hoặc phát triển vì “đây là cách tôi luôn làm”
Và đôi khi, quy trình đánh giá mã của bạn bị hỏng đến mức những thứ này vẫn lọt vào môi trường sản xuất.
Quy Trình Đánh Giá Mã Chỉ Đóng Dấu Cao Su
Bạn biết kiểu này.
Ai đó mở một PR lúc 4:45 chiều thứ Sáu.
Đó là 847 dòng thay đổi trên 23 tệp.
Người đánh giá liếc qua nó trong 90 giây, không thấy lỗi cú pháp rõ ràng, và nhấn “Phê duyệt” để họ có thể bắt đầu cuối tuần.
Hoặc tệ hơn, bạn có một kỹ sư “cấp cao” có tính bảo vệ lãnh thổ và phòng thủ, và mọi người đều sợ đưa ra phản hồi thực sự vì lần trước ai đó đề xuất tái cấu trúc, họ nhận được một bài luận 2,000 từ về lý do họ sai, theo sau là ba tuần tin nhắn Slack thụ động tích cực.
Khi Nhóm Không Có Tiêu Chuẩn
Một số nhóm thực sự không có tiêu chuẩn viết mã.
Không có hướng dẫn phong cách.
Không có nguyên tắc kiến trúc.
Không có mẫu hình đã thống nhất.
Mọi người chỉ làm bất cứ điều gì cảm thấy đúng với họ vào lúc đó.
Một người viết mã chức năng với cấu trúc dữ liệu bất biến.
Người khác viết OOP với tính kế thừa nặng.
Người thứ ba mới khám phá ra dependency injection tuần trước và giờ đang tiêm mọi thứ kể cả bồn rửa bát.
Người thứ tư chỉ muốn giao hàng và không quan tâm đến bất cứ điều gì trong số này.
Kết quả?
Một cơ sở mã Frankenstein, nơi mỗi module cảm giác như được viết bởi một công ty khác nhau.
Nhà Phát Triển Cấp Dưới Bị Bỏ Mặc Không Giám Sát
Đây là một kịch bản phổ biến hơn chúng ta muốn thừa nhận:
bạn thuê một nhà phát triển cấp dưới, giao cho họ một ticket, và…
không ai kiểm tra họ.
Họ vật lộn trong hai tuần, cuối cùng làm được gì đó hoạt động thông qua thử và sai, và giao nó.
Nó hoạt động (phần lớn), vì vậy nó được đưa lên sản xuất.
Sáu tháng sau, ai đó phải sửa đổi mã đó và phát hiện ra nó đang được giữ lại bằng băng keo và lời cầu nguyện.
Không có kiểm thử.
Không xử lý lỗi.
Các biến được đặt têntemp1,temp2,finalFinal,finalFinalActual.
Logic nghiệp vụ trộn lẫn với mã giao diện người dùng và truy vấn cơ sở dữ liệu.
Đó có phải là nợ kỹ thuật không?
Đó có phải lỗi của ban quản lý không?
Cũng có, cũng không.
Ban quản lý đã thất bại trong việc cung cấp sự cố vấn và giám sát.
Nhưng đồng thời, kỹ sư đó đã có thể yêu cầu giúp đỡ.
Đã có thể nhìn vào mã hiện có để tìm mẫu hình.
Đã có thể…
bạn biết đấy, cố gắng.
💬 Sự Tinh Tế Mà Không Ai Muốn Bàn Đến
Vì vậy, đây là lúc mọi thứ trở nên phức tạp.
Bởi vìngay cả khi mã thực sự tệ do lỗi của kỹ sư, thì cách đóng khung “nợ kỹ thuật” vẫn là sai.
Tại sao?
Bởi vì gọi nó là “nợ” vẫn:
- Đóng khung nó như một sự đánh đổi có chủ ý (nó không phải)
- Ngụ ý rằng nó nên được “trả lại” (nó nên đượcsửa chữa)
- Che giấu nguyên nhân gốc rễ (vấn đề tuyển dụng, đào tạo, đánh giá mã hoặc tiêu chuẩn)
Nếu bạn thuê một người không đủ giỏi, đó là vấn đề tuyển dụng.
Nếu việc đánh giá mã của bạn không phát hiện ra vấn đề, đó là vấn đề quy trình.
Nếu nhóm của bạn không có tiêu chuẩn, đó là vấn đề lãnh đạo.
Nếu các lập trình viên cấp dưới đang giao mã không thể bảo trì, đó là vấn đề cố vấn.
Không cái nào trong số này là “nợ.” Chúng là những thất bại tổ chức biểu hiện thành các vấn đề chất lượng mã.
Và đây là điểm mấu chốt:
ngay cả những thất bại này cũng thường bắt nguồn từ quyết định của ban quản lý.
Ai đã quyết định:
- Thuê các nhà phát triển rẻ nhất thay vì những người giỏi nhất?
- Bỏ qua phần kỹ thuật của cuộc phỏng vấn vì ứng viên “có vẻ thông minh”?
- Không phân bổ thời gian của kỹ sư cấp cao cho việc đánh giá mã và cố vấn?
- Không bao giờ đầu tư vào việc thiết lập tiêu chuẩn nhóm hoặc hướng dẫn kiến trúc?
- Ưu tiên số điểm user story hơn chất lượng mã?
Bạn thấy chúng ta cứ quay lại với ban quản lý như thế nào chưa?
™️ Khi Các Kỹ Sư Cần Chịu Trách Nhiệm
Nhưng đừng để chúng ta hoàn toàn thoát tội.
Là các kỹ sư, chúng ta cần chịu trách nhiệm về nghề nghiệp của mình.
Chúng ta cần:
- Thực sự đánh giá mã, không chỉ đóng dấu cao su
- Đưa ra và nhận phản hồi như những chuyên gia
- Đầu tư vào học hỏi và phát triển
- Yêu cầu giúp đỡ khi bị kẹt
- Phản đối mã tồi trong các PR, ngay cả khi điều đó không thoải mái
- Thiết lập và duy trì tiêu chuẩn như một nhóm
Nếu bạn đã phê duyệt một PR mà không đọc nó, bạn chia sẻ trách nhiệm cho mã đó.
Nếu bạn viết mã cẩu thả vì bạn không thể bận tâm, đó là lỗi của bạn.
Nếu bạn đã viết cùng một mẫu hình tồi trong năm năm và từ chối học hỏi, bạn chính là vấn đề.
Sự khác biệt?Khi chúng ta sở hữu những thất bại này, chúng ta thực sự có thể sửa chữa chúng.
Chúng ta có thể cải thiện văn hóa đánh giá mã.
Chúng ta có thể nâng cao kỹ năng của mình.
Chúng ta có thể thiết lập các thực hành tốt hơn.
Nhưng khi chúng ta ẩn sau “nợ kỹ thuật” như một thuật ngữ chung chung, mơ hồ, chúng ta không thể sửa chữa bất cứ điều gì vì chúng ta thậm chí không xác định được vấn đề thực sự.
Vậy Chúng Ta Nên Gọi Nó Là Gì Thay Thế?
Thay vì “nợ kỹ thuật”, hãy thử những cái này:
“Hậu quả kỹ thuật của các quyết định kinh doanh trong quá khứ”
– Dài dòng, nhưng chính xác.
Giữ trách nhiệm ở đúng nơi.
“Chi phí bảo trì”
– Mọi cơ sở mã đều có một cái.
Nó phát triển theo thời gian.
Hãy lập ngân sách cho nó.
“Sự thay đổi ngữ cảnh”
– Điều gì có ý nghĩa hai năm trước thì giờ không còn ý nghĩa.
Điều đó cũng bình thường.
“Tái cấu trúc cần thiết”
– Phần mềm phát triển.
Tái cấu trúc là bình thường.
Đừng coi nó như một hình phạt.
“Cái giá của việc học hỏi”
– Bạn đã không biết thứ bạn đang xây dựng sẽ thành công.
Giờ thì bạn biết rồi.
Đã đến lúc tối ưu hóa.
🔚 Điểm Mấu Chốt
Nợ kỹ thuật không phải là một huyền thoại vì không tồn tại đường tắt.
Nó là một huyền thoại vì phép ẩn dụ đã bị bóp méo đến mức không thể nhận ra.
Nó đã trở thành một cách để các nhà quản lý:
- Đổ lỗi cho kỹ sư về các quyết định kinh doanh
- Tránh chịu trách nhiệm về việc phân bổ nguồn lực
- Coi sự phát triển phần mềm bình thường là sự cẩu thả
- Thoát khỏi trách nhiệm về các thời hạn bất khả thi
Nhà quản lý giỏi chịu trách nhiệm về những sự đánh đổi.Họ nói “Chúng ta đã chọn tốc độ thay vì sự linh hoạt và giờ chúng ta cần tối ưu hóa lại.
Việc đó sẽ cần thời gian và nguồn lực.
Tôi đang phân bổ cả hai.”
Nhà quản lý tồi vũ khí hóa sự nhận thức muộn màng.Họ nói “Lẽ ra các bạn nên xây dựng nó đúng ngay từ đầu.
Tại sao lại có quá nhiều nợ kỹ thuật?”
Nếu bạn là một nhà quản lý đang đọc điều này và đã từng phàn nàn về nợ kỹ thuật, hãy tự hỏi:
bạn đã cho nhóm của mình thời gian và nguồn lực để xây dựng nó “đúng” chưa?
Bạn thậm chí có biết “đúng” nghĩa là gì không?
Hay bạn chỉ muốn nó được giao hàng?
Nếu bạn là một kỹ sư đang đọc điều này, hãy ngừng chấp nhận đổ lỗi cho những quyết định không phải của bạn.
Lần tới khi ai đó nhắc đến nợ kỹ thuật trong buổi hồi tưởng, hãy thử điều này:
“Hãy nói về những ràng buộc mà chúng ta đang phải làm việc khi đưa ra những quyết định đó.
Bởi vì tôi khá chắc chắn rằng chúng ta đã đưa ra quyết định tốt nhất có thể với thông tin và thời gian mà chúng ta có.”
Và nếu họ phản đối?
Nếu họ khăng khăng rằng đó là “món nợ” mà bạn đã “vay”?
Hãy bắt đầu phỏng vấn.
Bởi vì bạn đang làm việc cho một người không hiểu về phát triển phần mềm và sẽ luôn đổ lỗi cho bạn khi mọi thứ trở nên khó khăn.







![[Tự học C++] Số dấu phẩy động(float, double,…) trong C++](https://cafedev.vn/wp-content/uploads/2019/12/cafedevn_c_develoment-100x70.jpg)

