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

un

tamu
1 / ?
kembali ke pelajaran

Bagaimana Sedimen Kode Terbentuk

Batuan sedimen terbentuk melalui pengendapan, bukan ledakan. Setiap lapisan: benar untuk zamannya. Setiap lapisan: lebih tua dari lapisan di atasnya. Lapisan tertua mengeras sebelum ekosistem matang di sekitarnya. Bukan kesalahan yang menyebabkannya. Waktu yang menyebabkannya.

MOAD-0001 bekerja dengan cara yang sama.

MOAD-0001 Sediment Layers: code copied across decades as N grows

Kisah Pembentukan

Sebuah penelusuran graf yang ditulis pada tahun 1993:

List<Node> visited = new ArrayList<>();
Stack<Node> stack = new Stack<>();
stack.push(start);
while (!stack.isEmpty()) {
Node n = stack.pop();
if (!visited.contains(n)) {  // pemindaian linear O(N)
visited.add(n);
for (Node neighbor : n.getNeighbors())
stack.push(neighbor);
}
}

Kode ini: benar. Tes: lulus. Pada tahun 1993, graf memiliki 50 simpul.

50 node: 50 × 25 rata-rata dipindai = 1.250 operasi. Tidak terlihat.

Kode tersebut masuk ke version control. Disalin ke tutorial. Dibungkus dalam library. Dikirim dalam build tools, package manager, & dependency resolver. Pada 2024, pola yang sama berjalan pada dependency graph dengan 50.000 node.

50.000 node: 50.000 × 25.000 rata-rata dipindai = 1.250.000.000 operasi.
Build 1 detik menjadi 17 menit.

Kodenya tidak berubah. Dunia di sekitarnya yang berkembang. Setiap lapisan sedimen: benar saat pengendapan. Mahal saat penggalian.

Sedimen Anda

Kode sedimen tidak mengandung kesalahan logika. Ia mengandung asumsi performa yang tidak lagi berlaku ketika skala berubah. Kode tersebut tetap menghasilkan hasil yang benar; hanya biayanya yang berubah.

Perbedaan ini penting untuk diagnosis. Kesalahan logika menghasilkan jawaban yang salah. Cacat sedimen menghasilkan jawaban yang benar dengan biaya yang tidak dapat diterima.

Kode sedimen: kode yang benar tetapi menjadi mahal ketika skala di sekitarnya berubah. Berikan contoh konkret dari perangkat lunak yang pernah Anda gunakan atau tulis di mana sesuatu berfungsi pada skala kecil & menjadi bottleneck pada skala besar. Apa yang berubah: kodenya, ukuran datanya, atau pola penggunaannya?

Lima Bentuk MOAD-0001

MOAD-0001 muncul dalam lima bentuk terdokumentasi di lebih dari 60 ekosistem perangkat lunak. Strukturnya: uji keanggotaan menggunakan wadah sekuensial, yang disarangkan di dalam perulangan atas koleksi yang sama atau terkait.

Lima Bentuk

DomainPolaWadah SekuensialWadah yang Benar
Penelusuran grafif (!stack.contains(n)) dalam DFS/TarjanArrayListHashSet
Deduplikasi rute/eventTAILQ_FOREACH strcmp per permintaanlinked listHashMap
Pelacakan tabrakanfindLinearSearch() per tick fisikaarrayunordered_set
Resource allocation filterList.contains() dalam stream filterArrayListHashSet
A* pathfinding open-listLocalVector::find() per tetanggavectorstored heap index

Semua lima bentuk berbagi struktur yang sama: pemeriksaan keanggotaan yang disisipkan di dalam loop, menggunakan kontainer yang memerlukan pemindaian linear untuk menjawab pertanyaan keanggotaan.

Daftar Kata Kunci Pemindaian

Mengaudit untuk MOAD-0001 berarti mencari kata kunci pengujian keanggotaan di dalam loop:

- Python: in dengan variabel list, .count(), list.index()

- Java: ArrayList.contains(), List.contains(), LinkedList.contains()

- JavaScript: Array.includes(), Array.indexOf(), Array.find()

- C++: std::vector::find(), manual loop dengan perbandingan ==

- Go: slices.Contains(), manual loop pada slice

Perbaikan di setiap kasus: ganti sequential container dengan hash container. listset. ArrayListHashSet. ArraySet. vectorunordered_set. slicemap[T]struct{}.

Satu kata kunci. Satu substitusi. Nol perubahan perilaku. 1.000× percepatan pada N=1.000.

Audit sebuah Fragmen Kode

Terapkan pengenalan pola MOAD-0001 pada fragmen kode nyata.

Anda mengaudit basis kode JavaScript dan menemukan ini di dalam loop yang berjalan pada semua tetangga graf: `if (!openSet.includes(neighbor)) openSet.push(neighbor)`. Apakah ini MOAD-0001? Apa yang akan Anda ganti `openSet` dengan, dan bagaimana kompleksitas berubah dari O(?) ke O(?)?

Satu Baris, Empat Bahasa

Perbaikan untuk MOAD-0001 dalam empat bahasa:

# Python
visited = []       # SEBELUM: keanggotaan O(N)
visited = set()    # AFTER:  O(1) membership
// Java
List<Node> visited = new ArrayList<>();    // BEFORE
Set<Node> visited = new HashSet<>();       // AFTER
// JavaScript
const visited = [];      // SEBELUM: Array.includes() O(N)
const visited = new Set(); // SETELAH: Set.has() O(1)
// visited.push(n) → visited.add(n)
// visited.includes(n) → visited.has(n)
// Go
visited := []NodeID{}              // SEBELUM: slices.Contains() O(N)
visited := make(map[NodeID]struct{}) // SETELAH: map lookup O(1)
// _, ok := visited[n]  untuk pengecekan keanggotaan
// visited[n] = struct{}{}  untuk penyisipan

Dalam setiap kasus: perilaku sama, keluaran sama, tes tetap lulus. Hanya laju pertumbuhan yang berubah.

Apa yang TIDAK Diubah oleh Perbaikan Ini

- Perilaku logis algoritma: depth-first tetap mengunjungi secara depth-first

- Ketepatan keluaran: node yang sama dikunjungi dalam urutan yang sama (dalam DFS)

- Hasil pengujian: setiap pengujian yang memeriksa ketepatan tetap lulus

Apa yang Diubah oleh Perbaikan Ini

- Pengujian keanggotaan: O(N) → O(1)

- Total loop: O(N²) → O(N)

- Pada N=1.000: 1.000× lebih cepat

- Pada N=10.000: 10.000× lebih cepat

Satu Batasan: Urutan

Kontainer hash (set, HashSet, unordered_set) tidak mempertahankan urutan penyisipan. Di Python 3.7+, dict mempertahankan urutan penyisipan; set biasa tidak. Di Java, HashSet tidak mempertahankan urutan; LinkedHashSet melakukannya.

Jika urutan penting bersamaan dengan keanggotaan: pertahankan dua struktur. Sebuah set (atau HashSet) untuk pengujian keanggotaan O(1). Sebuah list terpisah (atau ArrayList) untuk traversal berurutan. Atau gunakan LinkedHashSet di Java, yang menyediakan keduanya.

Untuk MOAD-0001 dalam traversal graf: visited menjawab pertanyaan biner (apakah node ini sudah pernah dilihat?). Urutan tidak penting untuk pertanyaan keanggotaan. Urutan traversal berasal dari stack atau queue, bukan dari visited.

Keanggotaan vs Pengurutan

Dalam algoritma komponen terhubung kuat Tarjan, onStack melacak node mana yang masih berada di DFS call stack saat ini. Ia harus menjawab dua pertanyaan: (1) keanggotaan — apakah node ini saat ini berada di stack? (2) di akhir jalur DFS, pop node secara berurutan hingga node ini muncul.

Implementasi naif menggunakan List untuk onStack, menjawab pertanyaan keanggotaan dengan contains() — O(N) per pemeriksaan, O(N²) total untuk graf besar.

Anda memperbaiki implementasi Tarjan SCC dengan mengganti `onStack = []` menjadi `onStack = set()`. Tes berhasil. Seorang reviewer kode bertanya: 'bagaimana jika urutan penting untuk onStack?' Bagaimana Anda menjawab?

Mengapa Ini Adalah Pengungkapan, Bukan Patch

MOAD-0001 exists in over 1,000 verified sites across 60+ software ecosystems. Graph traversal in build tools, route deduplication in network routing daemons, collision detection in game engines, resource allocation in operating system schedulers.

Each site: correct code. Each site: O(N²) growth waiting for N to cross a threshold.

The Disclosure Pipeline

A patch without upstream disclosure fixes one site. The pattern recurs in the next version, the next library, the next language port. Disclosure: name the pattern, document it as CWE-407 (Algorithmic Complexity: Inefficient Algorithmic Complexity), publish the recognition heuristics & the one-line fix. Then every developer who reads the disclosure can recognize & fix their own instance.

Hamming called this 'giving a fish vs teaching fishing.' The patch gives a fish. The disclosure — MOAD-0001 named, pattern documented, fix generalized — teaches the heuristic.

Ekstensi Permacomputer

Hamming bekerja pada solusi titik: memperbaiki filter ini, meningkatkan kode ini. Unhamming menambahkan lapisan pengungkapan: menamai pola, mempublikasikan heuristik, & memberikannya kepada khalayak umum.

Prinsip pengetahuan-komponen berlaku di sini pada skala ekosistem. Satu peneliti menamai sebuah pola. Seratus pengembang mengenalinya di basis kode mereka sendiri. Seribu baris kode O(N²) menjadi O(N). Infrastruktur menjadi lebih cepat bagi semua orang yang membangun di atasnya.

Ini adalah naga yang sedang tumbuh: api yang sama (bekerja pada masalah penting, pengetahuan komponen, pemikiran sistem), penerbangan yang berbeda (pengungkapan terbuka, kepemilikan bersama, tanpa patron yang diperlukan).