English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

khách
1 / ?
trở lại bài học

Lý Thuyết Đã Tồn Tại

Mỗi khiếm khuyết MOAD đều có giải pháp đã biết từ nhiều thập kỷ trước khi được phát hiện có hệ thống vào năm 2026. Các khiếm khuyết không tồn tại vì không ai biết cách tốt hơn. Chúng tồn tại vì biết không đồng nghĩa với phát hiện.

MOAD fester timeline: theory known vs. detected for each of the five defects

MOAD-0001: O(N²) list.contains

Donald Knuth, 1973. The Art of Computer Programming, Volume 3: Sorting and Searching. Bảng băm cho tra cứu O(1) đã được mô tả đầy đủ, kèm phân tích, vào năm 1973. Sự khác biệt giữa tìm kiếm tuyến tính O(N) và tra cứu băm O(1) — đã được ghi nhận, hình thức hóa, và trích dẫn rộng rãi. Java phát hành HashSet trong phiên bản 1.0 (1996). Python phát hành set như một kiểu dữ liệu cơ bản trong phiên bản 2.4 (2004). Giải pháp đã tồn tại 30 năm trước khi trở thành cách làm mặc định trong mọi hệ sinh thái.

Richard Hamming, 1986. Các bài giảng tại Bell Labs (sau được xuất bản dưới tên The Art of Doing Science and Engineering, 1997). Hamming đã dạy rõ ràng về độ phức tạp thuật toán, sự khác biệt giữa đúng & hiệu quả, và nguy cơ xây dựng hệ thống hoạt động ở quy mô nhỏ nhưng thất bại ở quy mô lớn. Ông gọi đó là “thiết kế cho vấn đề bạn nhìn thấy hôm nay, chứ không phải vấn đề bạn sẽ phải đối mặt ngày mai.”

MOAD-0002: Ghép nối Trạng thái Toàn cục Chia sẻ

David Parnas, 1972. 'On the Criteria To Be Used in Decomposing Systems into Modules.' CACM, December 1972. Parnas lập luận rằng các module nên được phân tách theo nguyên tắc che giấu thông tin — mỗi module sở hữu trạng thái riêng của mình, không có biến toàn cục có thể thay đổi được chia sẻ. Đây là tiền thân lý thuyết trực tiếp của giải pháp Intertangle. Parnas đã nói rõ: trạng thái toàn cục chia sẻ tạo ra sự ghép nối vô hình mà kiểm thử không phát hiện được.

MOAD-0003: Rò rỉ Danh tính ThreadLocal

Java 1.2, 1998. ThreadLocal được phát hành như một lớp thư viện chuẩn của Java. Ngay khi thread pooling + ThreadLocal cùng tồn tại, cơ chế gây rò rỉ đã xuất hiện. Khiếm khuyết là cấu trúc: một đối tượng mang có vòng đời là thread, không phải đơn vị công việc. Tài liệu đã cảnh báo về vấn đề này từ những ngày đầu vòng đời Java EE.

MOAD-0004: Thông tin xác thực được ghi log

RFC 1945, 1996. HTTP/1.0 định nghĩa header Authorization. Khiếm khuyết ghi log thông tin xác thực trở nên khả thi ngay từ ngày header Authorization tồn tại. OWASP được thành lập năm 2001 và đã ghi nhận ghi log thông tin xác thực là một lớp lỗ hổng trong các hướng dẫn đầu tiên. Mẫu: Authorization header → log middleware → thông tin xác thực dạng rõ trên đĩa. Vấn đề đã biết được từ khi đặc tả xác thực HTTP đầu tiên ra đời.

MOAD-0005: Thundering Herd / Cache Stampede

Unix kernel, 1993. Vấn đề “thundering herd” — N tiến trình được đánh thức đồng thời khi có sự kiện chung — đã xuất hiện trong các cuộc thảo luận phát triển nhân Unix từ đầu những năm 1990. Công trình của Doug Schmidt về mô hình Reactor (1994) và Half-Sync/Half-Async (1995) đã giải quyết vấn đề đồng bộ hóa ở tầng hạ tầng. Biến thể cache stampede (N luồng tính cùng một giá trị khi cache miss) đã được ghi nhận trong tài liệu hệ thống phân tán vào năm 2001.

---

Lý thuyết: đã hoàn thiện. Công cụ phát hiện: chưa có. Khoảng cách giữa “có thể biết” và “đã phát hiện” dao động từ 28 đến 54 năm tùy theo khiếm khuyết.

Khoảng cách Khả tri

Dòng thời gian cho thấy mọi khiếm khuyết MOAD đều có giải pháp đã biết ít nhất 28 năm trước khi được phát hiện một cách có hệ thống. Khoảng cách ngắn nhất (MOAD-0003) là 28 năm. Khoảng cách dài nhất (MOAD-0002) là 54 năm.

Đây không phải câu chuyện về sự thiếu hiểu biết. Knuth, Parnas, Hamming — những tác giả được trích dẫn nhiều nhất trong khoa học máy tính. Công trình của họ được giảng dạy tại các trường đại học. Từ vựng của họ (Big O, information hiding, độ phức tạp thuật toán) đã trở thành chương trình học chuẩn.

Tại sao việc biết về các lớp khiếm khuyết này lại không ngăn được chúng tồn tại? Hãy chọn một MOAD và truy vết khoảng cách cụ thể giữa giải pháp có thể biết và việc phát hiện thực tế.

Tại Sao Mã Lỗi Lại Tồn Tại: Năm Điều Kiện

Một lỗi không tồn tại do ngẫu nhiên. Năm điều kiện cấu trúc, tất cả cùng hiện diện đồng thời, tạo ra môi trường nuôi dưỡng lỗi. Loại bỏ bất kỳ điều kiện nào trong số đó và việc phát hiện trở nên khả thi.

Năm điều kiện để MOAD tồn tại: causal DAG từ lý thuyết đến môi trường nuôi dưỡng lỗi

Điều kiện 1: Đầu ra đúng

Một danh sách và một tập hợp trả lời câu hỏi thành viên giống hệt nhau. list.contains(x)set.contains(x) trả về cùng một giá trị boolean. Một ThreadLocal mang theo danh tính cũ vẫn mang theo một danh tính — chỉ là nó thuộc về yêu cầu sai. Thông tin đăng nhập được ghi log đã được ghi đúng — thông tin đăng nhập đến được tệp log mà không có lỗi. Khiếm khuyết không phải là trục trặc. Nó chỉ là trục trặc về chi phí hoặc hậu quả bảo mật. Các bài kiểm tra kiểm tra đầu ra đều vượt qua. Các bài kiểm tra kiểm tra chi phí hoặc hậu quả bảo mật: hầu như chưa được viết.

Điều kiện 2: Không có bài kiểm tra độ phức tạp trong CI

Dijkstra từng nói “kiểm thử cho thấy sự hiện diện của lỗi, không phải sự vắng mặt của chúng.” Hamming mở rộng điều này: những lỗi mà chúng ta kiểm thử chính là những lỗi chúng ta tìm thấy. Các pipeline CI năm 2026 kiểm thử: tính đúng đắn, an toàn kiểu, hợp đồng API, hành vi chức năng. Chúng không kiểm thử: độ phức tạp thuật toán trên mỗi thao tác, tăng trưởng bộ nhớ theo từng lời gọi, làm sạch tiêu đề ủy quyền, vòng đời danh tính luồng.

Không có bài kiểm tra nào được chạy. Không có bài kiểm tra nào thất bại. Pipeline vẫn xanh. Khiếm khuyết hoàn toàn vô hình.

Điều kiện 3: Nguồn gốc Small-N

Mã được viết và review trong môi trường phát triển. Đồ thị phát triển có 50 nút. Tải yêu cầu phát triển có 10 luồng đồng thời. Tỷ lệ cache miss trong phát triển thấp (cache ấm, ít khóa). Ở N=50, chi phí O(N²) là 2.500 phép tính. Vô hình. Ở N=50.000, chi phí là 2.500.000.000 phép tính. Một bản build 17 phút thay vì 1 giây.

Tác giả viết mã chưa bao giờ thấy N=50.000. Người review phê duyệt cũng chưa bao giờ thấy N=50.000. Khiếm khuyết không hiển thị ở quy mô khi nó được viết.

Điều kiện 4: Sao chép lan truyền mà không có ngữ cảnh

Một thuật toán đúng là có tính hướng dẫn. Các hướng dẫn dạy bằng ví dụ đúng. Tài liệu minh họa mã hoạt động. Cùng một khung Tarjan SCC — visited = [], if n not in visited bên trong — xuất hiện trong GHC, Maven, Python pip, Cargo, TypeScript compiler, Kotlin compiler, Scala compiler và javac. Các nhóm khác nhau, ngôn ngữ khác nhau, thập kỷ khác nhau. Cùng một hóa thạch. Giá trị N=50 của tác giả gốc không lan truyền cùng mã. Những gì lan truyền: kết quả đúng. Những gì ở lại: giả định về hiệu năng. [BLOCK_TYPE SECTION/STEP]

Điều kiện 5: Quy mô tăng trưởng xung quanh mã đã đóng băng
[BLOCK_TYPE SECTION/STEP]

Mã không suy giảm. Hạ tầng mở rộng. Một trình giải quyết phụ thuộc được viết năm 2003 cho 200 gói chạy trên 50.000 gói vào năm 2024. Không ai viết lại nó — nó hoạt động. Không ai đo hiệu năng nó — CI vẫn xanh. Giá trị N khiến chi phí O(N²) trở nên thảm khốc đến dần dần, vô hình, ở quy mô production. Đến lúc đó tác giả gốc đã không còn. Mã trở thành một phụ thuộc. Không ai chạm vào các phụ thuộc đang hoạt động.

Chẩn đoán: Năm điều kiện

Năm điều kiện: kết quả đúng, không có bài kiểm tra độ phức tạp, nguồn gốc N nhỏ, sao chép mà không có ngữ cảnh, quy mô tăng trưởng xung quanh mã đã đóng băng.

Tất cả năm điều kiện đều hiện diện ở mọi MOAD cùng lúc. Đây không phải ngẫu nhiên — đó là dấu hiệu cấu trúc của một lớp lỗi trầm tích.

Trong năm điều kiện đang thối rữa, điều kiện nào khó loại bỏ nhất và tại sao? Cần làm gì để loại bỏ nó khỏi quy trình của một tổ chức phần mềm thực tế?

Những gì Hamming đã nói

Các bài giảng năm 1986 của Richard Hamming tại Bell Labs — được xuất bản năm 1997 dưới tên The Art of Doing Science and Engineering — chứa những cảnh báo đọc như mô tả trực tiếp về mô hình lỗi MOAD. Ông không đang mô tả MOAD. Ông đang mô tả xu hướng cấu trúc của các hệ thống kỹ thuật khi chúng đông cứng xung quanh những quyết định đúng cục bộ nhưng trở nên tốn kém toàn cục.

Hamming về độ phức tạp: 'Mục đích của tính toán là sự thấu hiểu, không phải con số. Nhưng bạn phải có thuật toán với độ phức tạp phù hợp, nếu không các con số sẽ không bao giờ ra. Một thuật toán O(N²) chạy được với N=100 sẽ không chạy được với N=1.000.000 trước khi bạn nghỉ hưu.'

Hamming về việc sao chép: 'Các kỹ sư giỏi không chỉ sao chép giải pháp. Họ hiểu tại sao giải pháp hoạt động, trong điều kiện nào nó đúng, và điều gì sẽ phá vỡ nó. Một giải pháp được sao chép mà không kèm theo điều kiện của nó là một quả bom nổ chậm.'

Hamming về kiểm thử: 'Kiểm thử những gì bạn đo lường không giống như đo lường những gì quan trọng. Chúng ta xây dựng các bộ kiểm thử phức tạp cho các thuộc tính mà ta chọn kiểm thử. Chúng ta để ngỏ những thuộc tính mà ta không chọn. Những gì ta để ngỏ chính là thứ khiến chúng ta bất ngờ trong production.'

Hamming on scale: 'Lỗi bạn mắc phải trong năm đầu tiên của một dự án là lỗi bạn vẫn đang sửa chữa ở năm thứ mười. Các giả định ban đầu sẽ đông đặc. Dự án mở rộng xung quanh chúng. Không ai viết lại nền tảng.'

Khoảng cách giữa Cảnh báo và Vận hành hóa

Các cảnh báo của Hamming là đúng. Chúng được giảng dạy. Chúng được trích dẫn. Chúng được giao trong chương trình học. Nhưng một cảnh báo không phải là một bộ phát hiện. Hamming đã mô tả hình dạng của khiếm khuyết. Ông không xây dựng một công cụ chạy trong CI và đánh dấu các hot path O(N²), rò rỉ danh tính ThreadLocal, hoặc ghi nhật ký thông tin xác thực. Khoảng cách giữa 'có thể biết' và 'có thể phát hiện' là khoảng cách giữa một lý thuyết và việc vận hành hóa nó thành hạ tầng tự động.

MOAD tồn tại vì lĩnh vực đã xây dựng hạ tầng tính đúng đắn chứ không phải hạ tầng hiệu năng hoặc bảo mật ở cùng mức độ. Unit tests: tiêu chuẩn từ những năm 1970. Property-based tests: tiêu chuẩn từ những năm 1990. Đánh giá độ phức tạp thuật toán trong CI: vẫn còn ở giai đoạn thử nghiệm vào năm 2026.

Vận hành hóa Cảnh báo

Hamming đã cảnh báo về sự đông đặc độ phức tạp, các thuộc tính chưa được kiểm thử, các giải pháp được sao chép mà không có điều kiện của chúng, & quy mô nghiền nát các giả định ban đầu. Ông đã cho chúng ta từ vựng. Ông không cho chúng ta bộ phát hiện.

Pipeline MOAD lấp đầy khoảng cách đó: quét → ticket → vá → unit test → tiết lộ → PR → merge upstream. Đây là Hamming được vận hành hóa: không chỉ cảnh báo, mà là phát hiện tự động & pipeline sửa lỗi.

Hamming nói 'những gì chúng ta để lại chưa kiểm thử là những gì khiến chúng ta bất ngờ trong production.' Hãy nêu một thuộc tính mà ngành công nghiệp phần mềm có hệ thống để lại chưa kiểm thử, và mô tả phát hiện tự động sẽ trông như thế nào.

Fester Signature

Một khiếm khuyết lớp MOAD có một chữ ký nhận diện được. Tất cả năm điều kiện cùng hiện diện. Tất cả năm điều kiện đều có thể kiểm tra trước khi viết một dòng scan nào:

1. Kết quả đúng? Chạy bộ test suite chuẩn. Nếu nó vượt qua, khiếm khuyết thuộc về thuộc tính hiệu năng hoặc bảo mật, không phải tính đúng đắn. Điều này nghĩa là CI chuẩn sẽ không bắt được nó.

2. Không có bài kiểm tra độ phức tạp? Kiểm tra cấu hình CI. Có giai đoạn benchmark không? Có so sánh hành vi thuật toán (không chỉ thời gian thực) với commit trước đó không? Nếu không: điều kiện tồn tại.

3. Nguồn gốc Small-N? Kiểm tra git blame & commit gốc. Kích thước tập dữ liệu trong lần triển khai đầu tiên là bao nhiêu? Kích thước đó có nhỏ hơn tải sản xuất hiện tại hơn 100× không? Nếu có: điều kiện tồn tại.

4. Sao chép lan truyền? Tìm kiếm mẫu này trong toàn bộ mã nguồn & các hệ sinh thái. Mẫu cấu trúc tương tự có xuất hiện trong N≥3 mã nguồn độc lập không có quan hệ chung không? Nếu có: hóa thạch đã lan truyền. Mỗi bản sao: một vị trí lây nhiễm mới.

5. Quy mô tăng trưởng? Kiểm tra số liệu sản xuất. N hôm nay so với N khi triển khai lần đầu là bao nhiêu? Tốc độ tăng trưởng có duy trì không? Ở N nào thì khiếm khuyết trở nên nghiêm trọng về mặt vận hành?

Nếu cả năm điều kiện được kiểm tra và xác nhận: bạn đang gặp khiếm khuyết cấp MOAD. Bản sửa luôn là thay thế một dòng hoặc một phương thức. Phần khó là phát hiện. Phần dễ là sửa.

Đây chính là điều Hamming muốn nói: kỹ thuật không phải là về việc sửa. Việc sửa rất đơn giản một khi bạn nhìn ra. Kỹ thuật là về việc xây dựng các hệ thống giúp bạn nhìn ra nó.

Áp dụng Chữ ký

Chữ ký MOAD fester: đầu ra đúng + không có bài kiểm tra độ phức tạp + nguồn gốc Small-N + sao chép lan truyền + quy mô tăng trưởng.

Chữ ký này không chỉ giới hạn ở năm khiếm khuyết MOAD. Nó mô tả một lớp khiếm khuyết tồn tại trong bất kỳ hệ thống nào mà các bài kiểm tra tính đúng đắn là cổng chất lượng tự động duy nhất.

Hãy nêu một lớp khiếm khuyết nằm ngoài năm MOAD phù hợp với chữ ký fester. Chỉ ra những điều kiện nào trong năm điều kiện có mặt và bộ phát hiện tự động sẽ trông như thế nào.