Kod Sedimentinin Oluşumu
Sedimenter kaya, patlama değil, tortu birikimiyle oluşur. Her katman: kendi zamanı için doğruydu. Her katman: üstündekinden daha eskidir. En eski katmanlar, ekosistem olgunlaşmadan önce katılaştı. Onlara bir hata neden olmadı. Zaman neden oldu.
MOAD-0001 de aynı şekilde çalışır.
Oluşum Hikayesi
1993 yılında yazılmış bir grafik dolaşımı:
List<Node> visited = new ArrayList<>();
Stack<Node> stack = new Stack<>();
stack.push(start);
while (!stack.isEmpty()) {
Node n = stack.pop();
if (!visited.contains(n)) { // O(N) doğrusal tarama
visited.add(n);
for (Node neighbor : n.getNeighbors())
stack.push(neighbor);
}
}
Bu kod: doğru. Testler: geçiyor. 1993'te grafikler 50 düğüme sahipti.
50 düğüm: 50 × 25 ortalama tarama = 1.250 işlem. Görünmez.
Kod sürüm kontrolüne girdi. Öğreticilere kopyalandı. Kütüphanelere sarıldı. Derleme araçlarında, paket yöneticilerinde ve bağımlılık çözümleyicilerde dağıtıldı. 2024’e gelindiğinde aynı desen, 50.000 düğümlü bağımlılık grafikleri üzerinde çalışıyordu.
50.000 düğüm: 50.000 × 25.000 ortalama tarama = 1.250.000.000 işlem.
1 saniyelik derleme 17 dakikaya dönüşür.
Kod değişmedi. Etrafındaki dünya büyüdü. Tortunun her katmanı: birikirken doğru, kazılırken pahalı.
Sedimentiniz
Sedimentary kod mantık hatası içermez. Ölçek değiştikçe geçerliliğini yitiren bir performans varsayımı içerir. Kod doğru sonuçlar üretir; yalnızca maliyet değişmiştir.
Bu ayrım teşhis için önemlidir. Mantık hatası yanlış cevaplar üretir. Sedimentary kusur ise doğru cevapları kabul edilemez bir maliyetle üretir.
MOAD-0001'in Beş Formu
MOAD-0001, 60+ yazılım ekosistemi boyunca beş belgelenmiş biçimde ortaya çıkar. Yapı: aynı veya ilgili koleksiyon üzerinde bir döngü içine yerleştirilmiş, sıralı bir kapsayıcı kullanan bir üyelik testi.
Beş Form
| Alan | Desen | Sıralı Kapsayıcı | Doğru Kapsayıcı |
|---|---|---|---|
| Graf dolaşımı | DFS/Tarjan içinde if (!stack.contains(n)) | ArrayList | HashSet |
| Rota/olay tekilleştirme | İstek başına TAILQ_FOREACH strcmp | bağlı liste | HashMap |
| Çarpışma takibi | Fizik tick'i başına findLinearSearch() | dizi | unordered_set |
| Kaynak tahsisi filtresi | List.contains() akış filtresinde | ArrayList | HashSet |
| A* yol bulma açık listesi | Her komşu için LocalVector::find() | vector | saklanan yığın indeksi |
Beş formun tamamı aynı yapıya sahiptir: üyelik sorusunu yanıtlamak için doğrusal tarama gerektiren bir kapsayıcı kullanan, döngü içinde iç içe geçmiş bir üyelik kontrolü.
Taramalı Anahtar Kelime Listesi
MOAD-0001 denetimi, döngüler içinde üyelik-test anahtar kelimelerini aramak anlamına gelir:
- Python: list değişkeniyle in, .count(), list.index()
- Java: ArrayList.contains(), List.contains(), LinkedList.contains()
- JavaScript: Array.includes(), Array.indexOf(), Array.find()
- C++: std::vector::find(), manuel döngü ile == karşılaştırması
- Go: slices.Contains(), bir dilim üzerinde manuel döngü
Her durumda çözüm: sıralı kapsayıcıyı hash kapsayıcı ile değiştirin. list → set. ArrayList → HashSet. Array → Set. vector → unordered_set. slice → map[T]struct{}.
Tek bir anahtar kelime. Tek bir değiştirme. Sıfır davranış değişikliği. N=1.000’da 1.000× hızlanma.
Bir Kod Parçasını Denetle
MOAD-0001 desen tanımayı gerçek bir kod parçasına uygula.
Tek Satır, Dört Dil [BLOCK_TYPE SECTION/STEP]
MOAD-0001 için dört dilde düzeltme: [BLOCK_TYPE SECTION/STEP]
```python [BLOCK_TYPE SECTION/STEP]
Python
[BLOCK_TYPE SECTION/STEP]visited = [] # ÖNCE: O(N) üyelik
visited = set() # AFTER: O(1) membership
```java
// Java
List<Node> visited = new ArrayList<>(); // BEFORE
Set<Node> visited = new HashSet<>(); // AFTER
// JavaScript
const visited = []; // ÖNCE: Array.includes() O(N)
const visited = new Set(); // SONRA: Set.has() O(1)
// visited.push(n) → visited.add(n)
// visited.includes(n) → visited.has(n)
// Go
visited := []NodeID{} // ÖNCE: slices.Contains() O(N)
visited := make(map[NodeID]struct{}) // SONRA: map lookup O(1)
// _, ok := visited[n] üyelik kontrolü için
// visited[n] = struct{}{} ekleme işlemi için
Her durumda: aynı davranış, aynı çıktı, aynı testler geçiyor. Sadece büyüme hızı değişiyor.
Düzeltmenin Değiştirmediği Şeyler
- Algoritmanın mantıksal davranışı: derinlik öncelikli arama hâlâ derinlik öncelikli ziyaret eder
- Çıktı doğruluğu: aynı düğümler aynı sırada ziyaret edilir (DFS içinde)
- Test sonuçları: doğruluğu kontrol eden tüm testler geçmeye devam eder
Düzeltmenin DEĞİŞTİRDİKLERİ
- Üyelik testi: O(N) → O(1)
- Döngü toplamı: O(N²) → O(N)
- N=1.000 için: 1.000× daha hızlı
- N=10.000 için: 10.000× daha hızlı
Bir Sınırlama: Sıralama
Hash konteynerleri (set, HashSet, unordered_set) ekleme sırasını korumaz. Python 3.7+’te dict ekleme sırasını korur; düz set korumaz. Java’da HashSet sırayı korumaz; LinkedHashSet korur.
Eğer üyelikle birlikte sıralama da önemliyse: iki yapı kullanın. O(1) üyelik kontrolü için bir set (veya HashSet). Sıralı dolaşım için ayrı bir list (veya ArrayList). Ya da Java’da hem üyelik hem sıralama sağlayan LinkedHashSet’i kullanın.
Graf dolaşımında MOAD-0001 için: visited ikili bir soruyu cevaplar (bu düğüm daha önce görüldü mü?). Üyelik sorusu için sıralama önemli değildir. Dolaşım sırası yığından veya kuyruktan gelir, visited yapısından değil.
Üyelik vs Sıralama
Tarjan’ın güçlü bağlantılı bileşenler algoritmasında onStack, hangi düğümlerin mevcut DFS çağrı yığınında kaldığını takip eder. İki soruyu cevaplamalıdır: (1) üyelik — bu düğüm şu anda yığında mı? (2) bir DFS yolunun sonunda, bu düğüm görünene kadar düğümleri sırayla yığından çıkar.
Naif bir uygulama onStack için bir List kullanır ve üyelik sorusunu contains() ile cevaplar — her kontrol O(N), büyük graflar için toplam O(N²).
Neden Bu Bir Açıklama, Bir Yama Değil
MOAD-0001, 60'tan fazla yazılım ekosisteminde 1.000'den fazla doğrulanmış sitede mevcuttur. Derleme araçlarında grafik dolaşımı, ağ yönlendirme daemon'larında rota tekilleştirme, oyun motorlarında çarpışma tespiti, işletim sistemi zamanlayıcılarında kaynak tahsisi.
Her site: doğru kod. Her site: N bir eşiği aştığında bekleyen O(N²) büyümesi.
Açıklama Süreci
Üst akış açıklaması olmadan bir yama yalnızca tek bir siteyi düzeltir. Desen bir sonraki sürümde, bir sonraki kütüphanede, bir sonraki dil bağlantı noktasında tekrar ortaya çıkar. Açıklama: deseni adlandırın, CWE-407 (Algoritmik Karmaşıklık: Verimsiz Algoritmik Karmaşıklık) olarak belgeleyin, tanıma sezgilerini ve tek satırlık düzeltmeyi yayınlayın. Böylece açıklamayı okuyan her geliştirici kendi örneğini tanıyıp düzeltebilir.
Hamming buna 'balık vermek ile balık tutmayı öğretmek' adını verdi. Yama balık verir. Açıklama — MOAD-0001 adlandırılmış, desen belgelenmiş, düzeltme genelleştirilmiş — sezgiyi öğretir.
Permabilgisayar Uzantısı
Hamming noktasal çözümler üzerinde çalışıyordu: bu filtreyi düzelt, bu kodu iyileştir. Unhamming ise ifşaat katmanını ekler: örüntüyü adlandır, sezgiyi yayınla ve ortak alana sun.
Bileşik-bilgi ilkesi burada ekosistem ölçeğinde geçerlidir. Bir araştırmacı bir örüntüyü adlandırır. Yüz geliştirici bunu kendi kod tabanlarında tanır. Bin satır O(N²) kod O(N) haline gelir. Altyapı, üzerine inşa eden herkes için hızlanır.
İşte ejderhanın büyümesi budur: aynı ateş (önemli sorunlar üzerinde çalışmak, bileşik bilgi, sistem düşüncesi), farklı uçuş (açık ifşaat, ortak mülkiyet, patron gereksinimi yok).