Ders 05 / 16
Teslim Garantileri
Üç teslim kipinin aynı hat üzerinde sayıya çevrilmesi: en çok bir kez teslimde 2026-07 döneminin 19 satırı kayboluyor, tüketim 2200'den 2162'ye iniyor, 55 özet hücresinin 10'u kirleniyor ve sunum her bölgede kayıyor (−9,18 … −28,36); en az bir kez teslimde 19 satır iki kez varıyor ama tüketim 2200'de kalıyor ve sunum farkı boş çıkıyor, çünkü tekilleştirme aşaması yinelenmeyi yutuyor; tam bir kez teslimde anahtarlı yazım ikisini de sıfırlıyor. Asıl bulgu denetim sütunundadır: yinelenmeyi tekillik denetimi aşama 0'da yakalıyor, kayıp ise hiçbir denetime takılmıyor — satır oranı 0,0079 ile 0,05 eşiğinin, en büyük hücre sapması 0,2488 ile 0,25 eşiğinin altında kalıyor. Kayıp sessiz, yinelenme onarılabilirdir.
İçindekiler
Önceki ders kaybın bir biçimini ölçtü, ama orada kayıt hatta ulaşmıştı: yalnız kapanmış bir pencereye geç ulaşmış ve bir kararla düşürülmüştü. Bu ders varsayımı kaldırır: satır gönderiliyor ve hiç varmıyor, ya da bir kez gönderiliyor ve iki kez varıyor.
Bu iki olay taşımanın kaçınılmaz iki ucudur. Gönderen onay almadığında ya vazgeçer ya tekrar dener; vazgeçerse kayıp, tekrar denerse yinelenme olur. Taşımanın bu konuda verdiği söze teslim garantisi (delivery guarantee) denir: en çok bir kez (at-most-once) satırın kaybolabildiği, en az bir kez (at-least-once) iki kez varabildiği, tam bir kez (exactly-once) ikisinin de olmadığı kiptir. Üçüncüsü çoğu zaman taşımada değil yazmada durur: satır bir anahtarla yazılır, aynı anahtar ikinci kez geldiğinde yazım yapılmaz. Ders üç kipi aynı hat üzerinde koşturur ve sorar: hangisi sunulan sayıyı bozar, hangisi bir denetime takılır.
- VA49. Kod kurgudur; hiçbir mesaj sistemi, akış işleyici ya da orkestratör çağrılmaz. Kaynak M29’un kurgu sayaç okumalarıdır: 200 abone, 12 dönem, 2400 satır, tohum 20260218.
- VA50. Teslim semantiğinin yordamı tekrarlanmaz; M16’nın Önbellekleme, Kuyruklar ve Eşzamansız İşleme kursunda ölçüldü. Eklenen tek şey kipin hattın sunumuna ne yaptığıdır.
- VA51. Kayıp ve yinelenme tek bir dönemde, 2026-07’de, satır başına 0,10 payla modellenir. Üreteç tohumludur; o dönemin 200 satırından 19’u etkilenir.
- VA52. Teslim kipi taşımanın özelliğidir; hattın beş aşaması üç kipte de aynıdır.
- VA53. Tam bir kez burada bir taşıma özelliği değil, anahtarlı yazım olarak modellenir: (abone, dönem) çifti daha önce yazılmışsa ikinci yazım hiç yapılmaz.
- VA54. Denetim kümesi ortak tanımdan alınır; satır sayısı payı 0,05, dağılım payı 0,25’tir.
- VA55. Hattın tekilleştirme aşaması bu derste bir seçenektir; kapatılınca yinelenmenin nereye gittiği ölçülür.
- VA56. Sayılan birimler satır, kayıp satır, yinelenen satır, kirli hücre ve sunum sapmasıdır. Satır oranının adımı 1/2400, yani 0,0004; sunum üzerinde oran basılmaz.
Üç Kip, Tek Hat
Aşağıdaki blok ortak tanımı kurar, üzerine teslim işlevini ve ortak denetim kümesini ekler.
teslim yalnız 2026-07 dönemine dokunur: satırı düşürür, kopyasını ekler ya da anahtarı görülmüş
satırı hiç yazmaz.
# KURGUDUR. Gercek bir mesaj sistemi , akis isleyici ya da orkestrator cagrilmaz; # olcum aginin sayac okumalari kurgudur , tohum 20260218. TOHUM, M32 = 20260218, 0xFFFFFFFF def uretec(t): x = ((t ^ (t >> 16)) * 2246822507) & M32 x = ((x ^ (x >> 13)) * 3266489909) & M32 s = [(x ^ (x >> 16)) & M32] def sonraki(): s[0] = (s[0] * 1664525 + 1013904223) & M32 return s[0] / 4294967296 return sonraki BOLGE = ["dogu", "bati", "kuzey", "guney", "merkez"] TIP = ["mesken", "isyeri"] DONEM = [f"2026-{a:02d}" for a in range(1, 13)] ABONE = {} for i in range(200): r = uretec(TOHUM + 37 * i) ABONE[f"A{i + 1:03d}"] = {"bolge": BOLGE[int(r() * 5)], "tip": TIP[int(r() * 2)], "baslangic": 10000 + int(r() * 60000)} def kaynak_uret(): # her donem her abone icin bir okuma kayit = [] for i, (ab, a) in enumerate(ABONE.items()): e = a["baslangic"] for d in DONEM: r = uretec(TOHUM + 101 * i + 7 * DONEM.index(d)) e += 4 + int(r() * 46) kayit.append({"abone": ab, "donem": d, "bolge": a["bolge"], "tip": a["tip"], "endeks": e, "birim": "m3"}) return kayit def a1_ayikla(kayit): ZOR = ("abone", "donem", "bolge", "endeks", "birim") tut = [k for k in kayit if all(a in k for a in ZOR)] return tut, len(kayit) - len(tut) def a2_tekille(kayit): gor, tut = set(), [] for k in kayit: ad = (k["abone"], k["donem"]) if ad in gor: continue gor.add(ad) tut.append(k) return tut, len(kayit) - len(tut) def a3_tuketim(kayit): # donem farkindan tuketim tablo = {(k["abone"], k["donem"]): k for k in kayit} cikti, dusen = [], 0 for k in kayit: i = DONEM.index(k["donem"]) if i == 0: continue onceki = tablo.get((k["abone"], DONEM[i - 1])) if onceki is None: dusen += 1 continue cikti.append(dict(k, m3=int(k["endeks"]) - int(onceki["endeks"]))) return cikti, dusen def a4_ozet(kayit): top = {} for k in kayit: ad = (k["bolge"], k["donem"]) top[ad] = top.get(ad, 0) + k["m3"] return top, 0 def a5_sun(ozet): # bolge basina donem ortalamasi bolge = {} for (b, d), v in ozet.items(): bolge.setdefault(b, []).append(v) return {b: round(sum(v) / len(v), 2) for b, v in bolge.items()}, 0 def teslim(kayitlar, kip, donem="2026-07", pay=0.10): """En cok bir kez: kayip. En az bir kez: yinelenme. Tam bir kez: anahtarli yazim.""" r = uretec(TOHUM + 7) cikti, kayip, yineleme = [], 0, 0 gorulen = set() for k in kayitlar: if k["donem"] != donem: cikti.append(k) continue if kip == "en_cok_bir": if r() < pay: kayip += 1 continue cikti.append(k) elif kip == "en_az_bir": cikti.append(k) if r() < pay: cikti.append(dict(k)) yineleme += 1 else: # tam_bir: anahtarli yazim ad = (k["abone"], k["donem"]) if r() < pay and ad in gorulen: yineleme += 0 continue gorulen.add(ad) cikti.append(k) return cikti, kayip, yineleme def d_sema(veri, alanlar=("abone", "donem", "bolge", "endeks", "birim")): return any(any(a not in k for a in alanlar) for k in veri) def d_tekillik(veri): ad = [(k["abone"], k["donem"]) for k in veri] return len(ad) != len(set(ad)) def d_satir_sayisi(veri, beklenen, pay=0.05): return abs(len(veri) - beklenen) / beklenen > pay def d_bolum_tamligi_donem(veri): gor = set((k["bolge"], k["donem"]) for k in veri) return gor != set((b, d) for b in BOLGE for d in DONEM) def d_dagilim(ozet, taban, pay=0.25): for ad, v in ozet.items(): t = taban.get(ad) if t and abs(v - t) / max(abs(t), 1) > pay: return True return False ham = kaynak_uret() def kos(kayit, tekille=True): v, _ = a1_ayikla(kayit) if tekille: v, _ = a2_tekille(v) v, _ = a3_tuketim(v) oz, _ = a4_ozet(v) sun, _ = a5_sun(oz) return len(v), oz, sun N, TABAN, TSUN = kos(ham) def kirli(oz): return sum(1 for ad in set(oz) | set(TABAN) if oz.get(ad) != TABAN.get(ad)) def fark(sun): d = {b: round(sun[b] - TSUN[b], 2) for b in TSUN if round(sun.get(b, 0) - TSUN[b], 2)} return d if d else "bos" DENETIM = [("sema", lambda c, o: d_sema(c)), ("tekillik", lambda c, o: d_tekillik(c)), ("satir", lambda c, o: d_satir_sayisi(c, 2400)), ("bolum_donem", lambda c, o: d_bolum_tamligi_donem(c)), ("dagilim", lambda c, o: d_dagilim(o, TABAN))] print("taban: satir 2400 , tuketim", N, ", ozet hucresi", len(TABAN)) print("taban sunum", TSUN) print() print("kip satir kayip yineleme tuketim kirli/55 atesleyen denetim") for kip in ("en_cok_bir", "en_az_bir", "tam_bir"): c, kayip, yin = teslim(ham, kip) n, oz, sun = kos(c) at = [ad for ad, f in DENETIM if f(c, oz)] or ["yok"] print(f"{kip:<11} {len(c):>5} {kayip:>6} {yin:>9} {n:>8} {kirli(oz):>9} {','.join(at)}") print(" sunum farki", fark(sun)) print() print("anahtarli yazimin tuttugu anahtar: donem basina", len({(k["abone"], k["donem"]) for k in ham if k["donem"] == "2026-07"}), ", tum kosum icin", len({(k["abone"], k["donem"]) for k in ham}))
taban: satir 2400 , tuketim 2200 , ozet hucresi 55
taban sunum {'merkez': 1321.45, 'kuzey': 1212.55, 'dogu': 881.36, 'bati': 833.09, 'guney': 1065.55}
kip satir kayip yineleme tuketim kirli/55 atesleyen denetim
en_cok_bir 2381 19 0 2162 10 yok
sunum farki {'merkez': -9.18, 'kuzey': -22.64, 'dogu': -9.81, 'bati': -28.36, 'guney': -20.28}
en_az_bir 2419 0 19 2200 0 tekillik
sunum farki bos
tam_bir 2400 0 0 2200 0 yok
sunum farki bos
anahtarli yazimin tuttugu anahtar: donem basina 200 , tum kosum icin 2400
Kaybın ve Yinelenmenin Simetrisizliği
Tablonun iki satırı birbirinin aynadaki görüntüsü: biri 19 satır eksiltiyor, öbürü 19 satır çoğaltıyor. Sonuçları hiç benzemiyor.
En çok bir kez teslimde 2026-07 dönemine ait 19 satır hiç varmıyor. Tüketim satırı 2200’den 2162’ye iniyor, yani kayıp 38 satıra mal oluyor: eksik okuma kendi döneminin tüketimini düşürdüğü gibi, önceki endeksi ortadan kaldırdığı için bir sonraki dönemin tüketimini de hesaplanamaz kılıyor. 55 özet hücresinin 10’u kirleniyor ve sunulan beş bölge değerinin hepsi kayıyor: batıda −28,36, merkezde −9,18. Önceki derste de tam 10 hücre kirlenmiş ama sunum hiç oynamamıştı; fark, orada temmuzda eksilenin ağustosta fazlalanması, burada iki dönemin de eksilmesidir.
En az bir kez teslimde aynı 19 satır iki kez varıyor. Hattın tekilleştirme aşaması ikinci kopyayı düşürüyor; tüketim 2200’de kalıyor, kirli hücre 0, sunum farkı boş.
Tam bir kez kipinde anahtarlı yazım aynı anahtarın ikinci yazımını hiç yapmıyor. Kaynakta her (abone, dönem) çifti bir kez bulunduğu için çıktı 2400 satırda kalıyor ve sayılacak bir yinelenme oluşmuyor — kipin yinelenme sayacı bu yüzden sıfırdır. Bu kip taşımanın değil yazmanın özelliğidir; taşıma yine iki kez getirebilir, yazım bunu görünmez kılar.
Bedava olmadığı son satırda yazılı. Yazımın aynı anahtarı ikinci kez tanıyabilmesi için onu hatırlaması gerekir: bir dönem için 200, koşumun tamamı için 2400 anahtar. Tam bir kez bir taşıma güvencesi değil, durum tutmanın satın aldığı bir güvencedir; tutulmayan anahtar için garanti yoktur.
Kayıp Neden Sessiz
Asıl bulgu son sütundadır. Sunulan beş değeri her bölgede kaydıran kip hiçbir denetime takılmıyor; hiçbir değeri değiştirmeyen kip tekillik denetimini ateşliyor. Aşağıdaki blok kaybın hangi eşiklerin altından geçtiğini yazıyor.
c, kayip, _ = teslim(ham, "en_cok_bir") n, oz, sun = kos(c) print("kayip", kayip, "satir ; satir orani", round(abs(len(c) - 2400) / 2400, 4), "< esik 0.05") print("en buyuk ozet hucresi sapmasi", round(max(abs(oz[a] - TABAN[a]) / abs(TABAN[a]) for a in TABAN if a in oz), 4), "< esik 0.25") print("bolge kumesi eksiksiz mi:", not d_bolum_tamligi_donem(c)) print("ayni denetim pay 0.005 ile:", d_satir_sayisi(c, 2400, pay=0.005)) print() print("kayip payi kayip tuketim en buyuk hucre sapmasi satir orani atesleyen") for p in (0.02, 0.05, 0.10, 0.20, 1.00): c, kayip, _ = teslim(ham, "en_cok_bir", pay=p) n, oz, sun = kos(c) enh = round(max(abs(oz[a] - TABAN[a]) / abs(TABAN[a]) for a in TABAN if a in oz), 4) at = [ad for ad, f in DENETIM if f(c, oz)] or ["yok"] print(f"{p:<11} {kayip:>5} {n:>8} {enh:>23} {round(abs(len(c) - 2400) / 2400, 4):>12}" f" {','.join(at)}") print() print("tekillestirme asamasi kapali:") print("kip tuketim kirli/55 sunum farki") for kip in ("en_cok_bir", "en_az_bir", "tam_bir"): c, _, _ = teslim(ham, kip) n, oz, sun = kos(c, tekille=False) print(f"{kip:<11} {n:>8} {kirli(oz):>9} {fark(sun)}")
kayip 19 satir ; satir orani 0.0079 < esik 0.05
en buyuk ozet hucresi sapmasi 0.2488 < esik 0.25
bolge kumesi eksiksiz mi: True
ayni denetim pay 0.005 ile: True
kayip payi kayip tuketim en buyuk hucre sapmasi satir orani atesleyen
0.02 4 2192 0.1441 0.0017 yok
0.05 10 2180 0.2094 0.0042 yok
0.1 19 2162 0.2488 0.0079 yok
0.2 39 2122 0.3953 0.0163 dagilim
1.0 200 1800 0.0 0.0833 satir,bolum_donem
tekillestirme asamasi kapali:
kip tuketim kirli/55 sunum farki
en_cok_bir 2162 10 {'merkez': -9.18, 'kuzey': -22.64, 'dogu': -9.81, 'bati': -28.36, 'guney': -20.28}
en_az_bir 2219 5 {'merkez': 6.19, 'kuzey': 12.27, 'dogu': 3.64, 'bati': 18.36, 'guney': 6.45}
tam_bir 2200 0 bos
İlk dört satır sessizliğin nasıl kurulduğunu gösteriyor. Satır sayısı denetimi 2400 beklerken 2381 buluyor; oran 0,0079, eşik 0,05, yani denetim eşiğin altı kat altında kalıyor. Dağılım denetimi en çok bozulan hücrede 0,2488 sapma görüyor ve 0,25 eşiğini kıl payı geçiyor. Bölüm bütünlüğü hiçbir şey göremez, çünkü kayıp satırlar beş bölgeye dağılmıştır. Kayıp bir alan silmez, bir tür bozmaz, bir anahtar çoğaltmaz; yalnız daha az satır bırakır — denetimler ise satırın biçimine bakar. Kusur kodda değil paydadır: dördüncü satır aynı denetimin pay 0,005 ile ateşlediğini yazıyor. Kayıp ölçülemez değildir, ölçülmemiştir.
İkinci tablo kayıp payını süpürüyor ve sessizliğin bir nokta değil bir bant olduğunu gösteriyor. Pay 0,02’den 0,20’ye çıkarken kaybolan satır 4’ten 39’a, en büyük hücre sapması 0,1441’den 0,3953’e tırmanıyor: etki payla düzenli büyüyor, ama dağılım denetimi onu ancak 0,20’de görüyor. Satır sayısı denetimi bandın hiçbir yerinde ateşlemiyor; sebebi aritmetiktir, kayıp tek bir döneme sıkışmıştır ve o dönem kaynağın 200/2400’ü, yani 0,0833’üdür.
Son satır dersin en aykırı bulgusudur. 2026-07 hiç varmadığında iki denetim birden ateşliyor ve kalan hücrelerin sapması 0,00’dır: 2026-07 ile 2026-08 hücreleri yanlış hesaplanmamış, hiç yazılmamıştır ve geriye kalan 45 hücre kusursuzdur. Tam kayıp kısmi kayıptan gürültülüdür.
Onarımın Yeri ve Bedeli
Üçüncü tablo yinelenmenin neden zararsız kaldığını açıklıyor. Tekilleştirme kapatıldığında en az bir kez teslim artık soğurulmuyor: tüketim 2219’a çıkıyor, 5 hücre kirleniyor ve sunum her bölgede yukarı kayıyor. Yinelenme kendiliğinden zararsız değildir; onu zararsız kılan aşamadır ve bedeli yine bir anahtar kümesidir.
Aynı tablonun ilk satırı simetrisizliği tamamlıyor. Tekilleştirme kapalıyken en çok bir kez teslimin sonucu hiç değişmiyor: 2162 satır, 10 kirli hücre, aynı sapmalar. Hattın hiçbir aşaması kaybı onarmıyor, çünkü onaracak bir şey yok — kaybolan satır hiçbir yerde iz bırakmıyor. Yinelenmiş satır ise iz bırakır: fazladan bir kayıttır, anahtarı vardır, sayılabilir ve silinebilir.
Dersin omurgası bu cümledir: kayıp sessiz, yinelenme onarılabilirdir. Yinelenme gürültülüdür; hem bir denetimi ateşler hem de bir aşama tarafından geri alınabilir. Kayıp gürültüsüzdür ve geri alınamaz; onu görmenin tek yolu gönderilen satır sayısını bilmek, yani hattın dışında bir sayaç tutmaktır. En az bir kezin tercih edilme sebebi budur: yinelenmeyi kabul edip yazımı yinelemeye dayanıklı kılmak, kaybı kabul edip onu aramaktan ucuzdur.
Özet
- En çok bir kez teslimde 2026-07 döneminin 19 satırı kayboluyor, tüketim 2200’den 2162’ye iniyor, 55 hücrenin 10’u kirleniyor ve sunulan beş değerin hepsi kayıyor (−9,18 … −28,36).
- En az bir kez teslimde 19 satır iki kez varıyor, tekilleştirme aşaması ikinci kopyayı düşürüyor ve tüketim, kirli hücre ile sunum farkı taban değerinde kalıyor.
- Kaybı hiçbir denetim yakalamıyor: satır oranı 0,0079 ile 0,05 payının, en büyük hücre sapması 0,2488 ile 0,25 payının altında kalıyor. Yinelenmeyi tekillik denetimi hattın girişinde yakalıyor.
- Kayıp payı süpürüldüğünde sessizlik bir bant çıkıyor: dağılım denetimi ancak 0,20’de ateşliyor, satır sayısı denetimi hiçbir payda ateşlemiyor, çünkü bir dönem kaynağın yalnız 0,0833’üdür. Dönemin tamamı kaybolduğunda iki denetim birden ateşliyor — tam kayıp kısmi kayıptan gürültülüdür.
- Tekilleştirme kapatıldığında yinelenme zararsız olmaktan çıkıyor (tüketim 2219, sunum her bölgede yukarı); kaybın sonucu hiç değişmiyor. Tam bir kezin bedeli de aynı yerdedir: dönem başına 200, koşum başına 2400 anahtar.
- Kayıp sessiz, yinelenme onarılabilirdir: yinelenmenin izi vardır ve silinebilir, kaybın izi yoktur ve ancak hattın dışında tutulan bir sayaçla görülebilir.
Sonraki Adım
Beş derste veri hep tek yönde aktı: kaynak sistemden hatta, hattan özete, özetten sunuma. Her ölçü bu yönü varsayıyordu — alma yöntemi kaynağı okuyor, teslim kipi satırı taşıyor, pencere kararı onu bir dönemde topluyordu. Bir soru sorulmadı: hattın ürettiği değer geri döndüğünde ne olur. Sunum katmanındaki bir sayı çoğu kez orada kalmaz; operasyonel bir sisteme ya da sahada okuma yapan bir uygulamaya yazılır, çünkü asıl işini orada yapar. O yazım hattın kendi girdisine dokunduğu anda ok bir çembere kapanır. Sonraki ders çemberi ölçer: geri yazılan değer kaç aşama sonra kendi girdisine döner ve bir sonraki koşumda sayıyı ne yapar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.