---
title: 'Yineleme Yapıları'
source: 'https://academia.sh/tr/kurslar/kod-olarak-altyapi/yineleme-yapilari'
course: 'Kod Olarak Altyapı'
language: tr
updated: '2026-08-17T18:09:06+00:00'
license: 'CC BY-SA 4.0'
---

# Yineleme Yapıları

Aynı on kaynak üç kayıt biçiminde yazılır: elle on blok, sayı temelli yineleme, küme temelli yineleme. Satır sayısı, istisnanın maliyeti ve adres kararlılığı sayılır; ortadan bir bölge çıkarıldığında sayı temelli biçimin altı kalemlik plan ürettiği, kayan beş adresin ölçüm ağında otuz beş kaçan sayaç partisine karşılık geldiği ölçülür.

Bir önceki dersin kaydında iki toplayıcı makine vardı ve ikisi ayrı ayrı, dört satırı harfi harfine
aynı olan iki blok olarak yazılmıştı. Bölge büyüdü: ölçüm ağı artık on ayrı alt bölgede sayaç
okuyor. Aynı bloğu on kez kopyalamak bir seçenek, kaydın kendisine "bunu on kez yap" demek başka
bir seçenek. Bu ders üçüncü bir seçeneği de ekler ve üçünü aynı kalemlerde karşılaştırır.

Karşılaştırmanın çıkış noktası şudur: **üç biçim de aynı gerçeği üretir.** On makine, aynı alt
ağlar, aynı boyutlar, aynı etiketler. Aralarındaki fark gerçekte değil, kayıtta ve kaydın kaynağa
verdiği **adreste**dir. O adres, kaydın bir sonraki uygulamada hangi gerçek kaynağı kastettiğini
belirleyen tek şeydir — ve bu dersin bütün sayıları oradan çıkar.

Ölçüm **bölgesel ölçüm ağı** üzerindedir ve **kurgudur**; koşan şey `node` ile kurulmuş bir
**modeldir**.

**BS31.** Ölçüm ağı on alt bölgede sayaç okur; bölge adları listede yazılı sıradadır.
**BS32.** Üç kayıt biçimi de aynı on makineyi tanımlar; nitelikleri birebir aynıdır.
**BS33.** Adres, kaynağın durumda bulunduğu anahtardır: elle biçimde blok adı, sayı temelli
biçimde sıra numarası, küme temelli biçimde harita anahtarı.
**BS34.** Bir bölge iki kat sayaç taşır ve makinesi büyük olmalıdır; bu, biçimlerin istisnayı nasıl
taşıdığını ölçmek için konmuş tek sapmadır.
**BS35.** `altag` ve `etiket` alanları yerinde güncellenemez; değişirlerse kaynak yeniden
oluşturulur. `boyut` yerinde güncellenir.
**BS36.** Her toplayıcı 15 saniyede bir sayaç partisi çeker. Yeniden oluşturulan bir makine, önceki
dersin süreleriyle 105 saniye hizmet dışıdır.

## Aynı On Kaynak, Üç Kayıt

```js
// yineleme.mjs — on kaynak uc bicimde yazilir; satir, adres kararliligi ve plan sayilir. Model.
export const BOLGE = ["kuzey_1", "kuzey_2", "kuzey_3", "dogu_1", "dogu_2",
  "dogu_3", "bati_1", "bati_2", "bati_3", "bati_4"];
const ISTISNA = { dogu_2: "buyuk" };            // BS34: bir bolge iki kat sayac tasiyor
const nitelik = (b, ist) => ({ altag: `altag.${b}`, boyut: ist[b] ?? "orta",
  etiket: `toplayici-${b}` });

export function elle(bolgeler, ist = ISTISNA) {
  const metin = bolgeler.map((b) => `kaynak makine "toplayici_${b}" {\n` +
    `  altag  = altag.${b}.kimlik\n  boyut  = "${ist[b] ?? "orta"}"\n` +
    `  etiket = "toplayici-${b}"\n}`).join("\n");
  const cozum = new Map(bolgeler.map((b) => [`makine.toplayici_${b}`, nitelik(b, ist)]));
  return { metin, cozum, dal: 0 };               // deger kendi blogunda, kosul yok
}

export function sayiTemelli(bolgeler, ist = ISTISNA) {
  const dal = Object.entries(ist).map(([k, v]) =>
    `bolgeler[sayi.indeks] == "${k}" ? "${v}" : `).join("");
  const metin = `yerel bolgeler = [${bolgeler.map((b) => `"${b}"`).join(", ")}]\n` +
    `kaynak makine "toplayici" {\n  sayi   = ${bolgeler.length}\n` +
    `  altag  = altag[bolgeler[sayi.indeks]].kimlik\n  boyut  = ${dal}"orta"\n` +
    `  etiket = "toplayici-" + bolgeler[sayi.indeks]\n}`;
  const cozum = new Map(bolgeler.map((b, i) => [`makine.toplayici[${i}]`, nitelik(b, ist)]));
  return { metin, cozum, dal: Object.keys(ist).length };
}

export function kumeTemelli(bolgeler, ist = ISTISNA) {
  const metin = "yerel bolgeler = {\n" +
    bolgeler.map((b) => `  ${b} = "${ist[b] ?? "orta"}"`).join("\n") + "\n}\n" +
    `kaynak makine "toplayici" {\n  kume   = bolgeler\n` +
    "  altag  = altag[kume.anahtar].kimlik\n  boyut  = kume.deger\n" +
    '  etiket = "toplayici-" + kume.anahtar\n}';
  const cozum = new Map(bolgeler.map((b) => [`makine.toplayici["${b}"]`, nitelik(b, ist)]));
  return { metin, cozum, dal: 0 };               // istisna haritanin degerinde
}

const YENIDEN = ["altag", "etiket"];            // BS35: bu alanlar yerinde guncellenemez

export function planla(once, sonra) {
  const p = { ekle: 0, degistir: 0, yeniden: 0, sil: 0 };
  for (const [adres, y] of sonra.cozum) {
    const e = once.cozum.get(adres);
    if (!e) { p.ekle++; continue; }
    const fark = Object.keys(y).filter((k) => e[k] !== y[k]);
    if (fark.length) fark.some((k) => YENIDEN.includes(k)) ? p.yeniden++ : p.degistir++;
  }
  for (const adres of once.cozum.keys()) if (!sonra.cozum.has(adres)) p.sil++;
  return p;
}

export const BICIM = [["elle on blok", elle], ["sayi temelli", sayiTemelli],
  ["kume temelli", kumeTemelli]];
const satir = (m) => m.split("\n").length;
const UC = { dogu_2: "buyuk", bati_1: "buyuk", kuzey_3: "kucuk" };

if (import.meta.url === `file://${process.argv[1]}`) {
  // Uc bicim ayni on gercek kaynagi mi uretiyor: adresi degil, nitelikleri karsilastir.
  const imza = (c) => [...c.values()].map((v) => JSON.stringify(v)).sort().join("|");
  const imzalar = BICIM.map(([, f]) => imza(f(BOLGE).cozum));
  console.log("uc bicim de ayni gercegi uretiyor mu: " +
    `${imzalar.every((x) => x === imzalar[0]) ? "evet" : "hayir"} ` +
    `(${elle(BOLGE).cozum.size} kaynak, ayni nitelikler)`);

  console.log("\nkaydin bedeli (10 kaynak)");
  console.log("bicim          satir  kosul dali  3 istisnada satir/dal  adreste bolge adi");
  for (const [ad, f] of BICIM) {
    const r = f(BOLGE), u = f(BOLGE, UC);
    const adresli = [...r.cozum.keys()].some((a) => a.includes("dogu_2"));
    console.log(`${ad.padEnd(15)}${String(satir(r.metin)).padStart(5)}${String(r.dal).padStart(12)}` +
      `${`${satir(u.metin)}/${u.dal}`.padStart(23)}${(adresli ? "var" : "yok").padStart(19)}`);
  }

  const SENARYO = [
    ["ortadan bir bolge cikti (dogu_2 kapandi)", BOLGE.filter((b) => b !== "dogu_2")],
    ["ortaya bir bolge girdi (dogu_1b acildi)", [...BOLGE.slice(0, 4), "dogu_1b", ...BOLGE.slice(4)]],
    ["sona bir bolge eklendi (bati_5 acildi)", [...BOLGE, "bati_5"]],
  ];

  for (const [ad, yeni] of SENARYO) {
    console.log(`\n${ad}`);
    console.log("bicim          ekle  degistir  yeniden olustur  sil  toplam kalem  kayan adres");
    for (const [bAd, f] of BICIM) {
      const once = f(BOLGE), sonra = f(yeni), p = planla(once, sonra);
      const kayan = [...sonra.cozum].filter(([a, v]) =>
        once.cozum.has(a) && JSON.stringify(once.cozum.get(a)) !== JSON.stringify(v)).length;
      console.log(`${bAd.padEnd(15)}${String(p.ekle).padStart(4)}${String(p.degistir).padStart(10)}` +
        `${String(p.yeniden).padStart(17)}${String(p.sil).padStart(5)}` +
        `${String(p.ekle + p.degistir + p.yeniden + p.sil).padStart(14)}${String(kayan).padStart(13)}`);
    }
  }
}
```

```
uc bicim de ayni gercegi uretiyor mu: evet (10 kaynak, ayni nitelikler)

kaydin bedeli (10 kaynak)
bicim          satir  kosul dali  3 istisnada satir/dal  adreste bolge adi
elle on blok      50           0                   50/0                var
sayi temelli       7           1                    7/3                yok
kume temelli      18           0                   18/0                var

ortadan bir bolge cikti (dogu_2 kapandi)
bicim          ekle  degistir  yeniden olustur  sil  toplam kalem  kayan adres
elle on blok      0         0                0    1             1            0
sayi temelli      0         0                5    1             6            5
kume temelli      0         0                0    1             1            0

ortaya bir bolge girdi (dogu_1b acildi)
bicim          ekle  degistir  yeniden olustur  sil  toplam kalem  kayan adres
elle on blok      1         0                0    0             1            0
sayi temelli      1         0                6    0             7            6
kume temelli      1         0                0    0             1            0

sona bir bolge eklendi (bati_5 acildi)
bicim          ekle  degistir  yeniden olustur  sil  toplam kalem  kayan adres
elle on blok      1         0                0    0             1            0
sayi temelli      1         0                0    0             1            0
kume temelli      1         0                0    0             1            0
```

İlk satır karşılaştırmanın zeminidir: üç biçim de on kaynağı aynı niteliklerle üretiyor. Kayıt
biçimi gerçeği değiştirmiyor.

Satır sütunu ilk bedeli verir. Elle yazım 50 satır, küme temelli 18, sayı temelli 7. Elle yazımın
50 satırının 40'ı tekrardır: aynı üç alan on kez, yalnız bölge adı değişerek. Sayı temelli biçim
en kısasıdır çünkü listeyi tek satıra sıkıştırır. Küme temelli biçim aradadır ve fazlalığı
rastlantı değildir — haritanın her satırı bir bölgeyi adıyla ve değeriyle yazar.

Koşul dalı sütunu istisnanın fiyatını verir. Bir bölgenin büyük makine istemesi, elle yazımda o
bloğun kendi satırına yazılan bir değerdir; küme temelli biçimde haritanın o anahtarındaki
değerdir; ikisinde de sıfır koşul. Sayı temelli biçimde ise ifadeye bir dal girer. Son sütundan
bir öncekine bakıldığında bunun nasıl büyüdüğü görülür: istisna sayısı üçe çıkınca elle ve küme
temelli biçimlerde satır ve dal sayısı değişmez, sayı temelli biçimde tek satırda **üç iç içe
koşul** birikir. İstisnayı taşıyan yer, sayı temelli biçimde kaydın veri kısmı değil ifade kısmıdır.

Son sütun ise bu dersin asıl kalemidir. Elle ve küme temelli biçimlerde adres bölge adını taşır:
`makine.toplayici_dogu_2` ya da `makine.toplayici["dogu_2"]`. Sayı temelli biçimde adres
`makine.toplayici[4]`tür ve dördüncü sıranın hangi bölge olduğu adreste yazmaz — o bilgi listenin
**uygulama anındaki hâlindedir**. Durumda bir kaynağa bakıp hangi bölgeye ait olduğunu söylemek
için kaydın o günkü sürümünü bulmak gerekir.

Adresin ne olduğu bir ayrıntı gibi görünür, ama bu kursun ölçüsünde merkezî bir kalemdir. Kayıt
uygulandığında her kaynağın gerçek kimliği bir adresin altına yazılır; bir sonraki uygulamada kayıt
ile gerçeği eşleştiren tek şey o adrestir. Adres kaynağın kimliğini taşıyorsa eşleşme kaydın
kendisinden okunur; sıra numarası taşıyorsa eşleşme kaydın **o günkü sırasına** bağlıdır. İkinci
durumda kayıt ile gerçek arasındaki bağ, kayıtta yazılı olmayan bir şeye — listenin geçmişteki
hâline — dayanır.


## Ortadan Bir Eleman Çıkınca

Üç senaryo aynı çıktının alt bölümlerindedir ve birlikte okunduğunda kural nettir.

`dogu_2` bölgesi kapandığında elle ve küme temelli biçimler **tek kalemlik** plan üretir: bir kaynak
silinir, diğer dokuzu hiç dokunulmadan yerinde kalır. Sayı temelli biçim aynı gerçek değişiklik
için **altı kalem** üretir: beş yeniden oluşturma ve bir silme. Sebep aritmetiktir. Liste dördüncü
elemanını kaybedince beşinci eleman dördüncü sıraya, altıncı beşinciye kayar; `makine.toplayici[4]`
adresi dün `dogu_2`yi gösteriyordu, bugün `dogu_3`ü gösteriyor. Kayıt "dördüncü makinenin alt ağı
ve etiketi değişti" der; bu iki alan yerinde güncellenemediği için karar yeniden oluşturmadır.
Kayan adres sütunu bunu doğrudan sayar: beş adres artık başka bir gerçek kaynağa işaret ediyor.

Ortaya bir bölge **girmesi** daha da pahalıdır: yedi kalem, altı kayan adres. Ekleme noktasından
sonraki her adres bir kayar.

Üçüncü senaryo sınırı çizer. Bölge listenin **sonuna** eklendiğinde üç biçim de tek kalem üretir;
sayı temelli biçim de temizdir, çünkü hiçbir adres kaymaz. Yani sayı temelli yineleme yanlış değil,
**sırası anlam taşımayan ve yalnız sondan büyüyen** kümeler için doğru biçimdir. Bölge listesi öyle
bir küme değildir: bölgeler kapanır, araya yenisi girer.

Planın öngörme oranı burada tersine bir soru sorar. Plan yanılmıyor — sayı temelli biçimde "beş
kaynak yeniden oluşturulacak" diyor ve uygulamada tam beşi yeniden oluşturuluyor, oran 5/5. Yanılan
plan değil, planı okuyan kişinin beklentisidir: bir bölge kapandı, bir makine gitmeli. Beklenti bir
kalem, plan altı kalem. Aradaki beş kalem gerçeklikten değil, **kayıt biçiminden** doğuyor.

Kaydın bunu kendi başına fark edememesi de ölçülebilir bir sınırdır. Kayıt "beşinci makinenin alt
ağı değişti" ile "beşinci sıra artık başka bir bölge" arasındaki farkı göremez, çünkü elinde yalnız
adres ve nitelikler vardır. İkisi de aynı şeye benzer: bir adres, değişmiş nitelikler. Ayrımı ancak
kaydı yazan kişi bilir, ve o kişi de planı okurken beş kalemi gerçek bir değişiklik sanabilir.
Sayı temelli biçimin riski gizli değildir — planda açıkça yazar — ama planın altı kalemi ile
gerçeğin bir kalemi arasındaki farkı ayırt etmek okuyucuya bırakılmıştır.


## Kayan Adresin Ölçüm Ağındaki Karşılığı

```js
// bedel.mjs — plan kalemini olcum agi biriminde sayar: kacan sayac partisi. Model.
import { BOLGE, BICIM, planla } from "./yineleme.mjs";
const DISI = 105, PERIYOT = 15, YENIDEN_SN = 110, SIL_SN = 10;   // BS36, onceki dersin sureleri
const yeni = BOLGE.filter((b) => b !== "dogu_2");

console.log("dogu_2 kapandi — ayni gercek degisiklik, uc kayit bicimi");
console.log("bicim          yeniden  hizmet disi makine-sn  kacan parti  uygulama sn");
for (const [ad, f] of BICIM) {
  const p = planla(f(BOLGE), f(yeni));
  const sn = p.yeniden * DISI;
  console.log(`${ad.padEnd(15)}${String(p.yeniden).padStart(7)}${String(sn).padStart(22)}` +
    `${String(p.yeniden * Math.floor(DISI / PERIYOT)).padStart(13)}` +
    `${String(p.yeniden * YENIDEN_SN + p.sil * SIL_SN).padStart(13)}`);
}
console.log("\nkapanan bolgenin kendi partileri zaten toplanmiyor;");
console.log("yukaridaki kayip dokuz saglam bolgenin kaybidir.");
```

```
dogu_2 kapandi — ayni gercek degisiklik, uc kayit bicimi
bicim          yeniden  hizmet disi makine-sn  kacan parti  uygulama sn
elle on blok         0                     0            0           10
sayi temelli         5                   525           35          560
kume temelli         0                     0            0           10

kapanan bolgenin kendi partileri zaten toplanmiyor;
yukaridaki kayip dokuz saglam bolgenin kaybidir.
```

Sayılar ölçüm ağı biriminde okunduğunda karar netleşir. Kapanan bölgenin makinesi zaten gidecekti;
üstteki kayıp **sağlam duran dokuz bölgenin** kaybıdır. Sayı temelli biçimde beş sağlam makine 105'er
saniye hizmet dışı kalır: 525 makine-saniye ve **35 kaçan sayaç partisi**. Elle ve küme temelli
biçimlerde bu kalemler sıfırdır. Uygulama süresi de 560 saniyeye karşı 10 saniyedir.

Kaçan parti geri gelmez. Sayaçlar okumayı sürdürür ama o pencerede kimse çekmediği için ölçüm ağının
o beş bölgesinde 105 saniyelik bir boşluk oluşur — ve bu boşluğun kaydında hiçbir iz yoktur. Kayıt
doğru, plan doğru, uygulama doğru; kaybolan yalnız veridir.

Bu bölümün kapanışında kaydın kapsamadığı bir kalem adıyla anılmalıdır: **bölge listesinin
kendisi**. Kayıtta on bölge adı yazılıdır, ama hangi bölgede sayaç olduğu kaydın bildiği bir şey
değildir — saha ekibinin tuttuğu bir listeden elle kopyalanmıştır. Bir bölge kapandığında kayıt
bunu kendiliğinden öğrenmez; biri gidip listeden siler. Kaydın en pahalı kalemi olan bu değişikliğin
tetikleyicisi, kaydın tamamen dışındadır.


## Kayıt Biçimi Kararı

| Biçim | Satır (10 kaynak) | Ortadan çıkarmada kalem | Kayan adres | İstisna dalı | Ne zaman |
|---|---|---|---|---|---|
| Elle on blok | 50 | 1 | 0 | 0 | Kaynaklar birbirinden gerçekten farklıysa |
| Sayı temelli | 7 | 6 | 5 | istisna başına 1 | Sırası anlamsız, yalnız sondan büyüyen küme |
| Küme temelli | 18 | 1 | 0 | 0 | Elemanların kimliği olan küme |

Tablo tek bir ölçüyle özetlenir: **satırdan tasarruf etmenin fiyatı adres kararlılığıdır.** Sayı
temelli biçim elle yazımın 50 satırını 7'ye indirir — yedi kat — ve karşılığında ortadaki her
değişiklikte beş ile altı arasında gereksiz yeniden oluşturma üretir. Küme temelli biçim 18 satırla
elle yazımın üçte birine iner ve adres kararlılığını hiç kaybetmez; ödediği bedel, bölge adlarının
kayıtta ikinci kez, harita anahtarı olarak yazılmasıdır.

Karar üç biçim arasında değil, iki soru arasındadır. Birincisi: bu on kaynak birbirinin kopyası mı,
yoksa her birinin kendi kimliği mi var? Ölçüm ağında ikincisi doğrudur — `dogu_2` bir sıra numarası
değil, sahada duran bir bölgedir. İkincisi: bu küme ortasından değişir mi? Bölge listesi kapanmalar
ve açılmalarla değişir, yani değişir. İki cevap birlikte küme temelli biçimi işaret eder; sayı
temelli biçim buradaki 7 satırı 18 satıra tercih ettirecek kadar ucuz değildir.

## Özet

- Üç kayıt biçimi de aynı 10 gerçek kaynağı aynı niteliklerle üretiyor; fark gerçekte değil, kaydın
  kaynağa verdiği adrestedir.
- Satır: elle 50, küme temelli 18, sayı temelli 7. İstisna sayısı 3'e çıkınca sayı temelli biçimde
  tek ifadede 3 iç içe koşul birikir, diğer ikisinde dal sayısı 0 kalır.
- `dogu_2` kapandığında elle ve küme temelli biçim 1 kalem, sayı temelli biçim 6 kalem üretti;
  5 adres başka bir gerçek kaynağa kaydı. Ortaya bölge girmesinde sayılar 1'e karşı 7 ve 6 oldu.
- Sona ekleme üç biçimde de 1 kalem: sayı temelli yineleme, sırası anlam taşımayan ve yalnız sondan
  büyüyen kümeler için doğru biçimdir.
- Plan yanılmadı — "5 yeniden oluşturulacak" dedi ve 5'i yeniden oluşturuldu, oran 5/5. Beklenti ile
  plan arasındaki 5 kalemlik fark kayıt biçiminden doğdu.
- Ölçüm ağı biriminde: 5 sağlam makine 105'er saniye hizmet dışı, 525 makine-saniye, 35 kaçan sayaç
  partisi, 560 saniyelik uygulama — küme temelli biçimde hepsi 0 ve 10 saniye.

## Sonraki Adım

Bu ders plan kalemlerini saydı ama planı hep hazır kabul etti: kalemler bir yerden geliyordu.
Sonraki ders o yeri kurar — kayıt ile durumu karşılaştırıp kalem kalem ekle, değiştir, yeniden
oluştur ve sil kararını üreten **planlayıcının** kendisini yazar. Ölçülecek şey planın kendi
doğruluğudur: kaç kalem planda yok ama uygulamada oluyor, kaç kalem planda olup gerçekleşmiyor, ve
"yeniden oluşturulacak" denilen kalemlerin kaçı gerçekten yeniden oluşturuluyor.
