---
title: 'İş Takibi ve Panolar'
source: 'https://academia.sh/tr/kurslar/kod-inceleme/is-takibi-ve-panolar'
course: 'Kod İnceleme ve Ekip Süreci'
language: tr
updated: '2026-08-17T18:10:46+00:00'
license: 'CC BY-SA 4.0'
---

# İş Takibi ve Panolar

İş öğesinin durumları arasında geçen bekleme incelemenin dışında 19 birimdir; inceleme atamaya göre 12 ile 36 arasında değişir ve zincirin payının 0,387'sinden 0,655'ine çıkar, kalan üç kusur öğeyi panoya geri koyunca toplam 31'den 105'e gider.

Buraya kadar inceleme tek bir değişikliğin çevresinde ölçüldü: kaç eksene bakıldı, kaç öbek
okundu, kaç tur döndü. Değişiklik bu ölçümlerde tek başına duruyordu — bir yerden gelmiyor,
bir yere gitmiyordu. Oysa bir ekipte değişiklik yalnız bir değişiklik değildir; **bir akışın
içindeki bir öğedir.** Önce bir öneri olarak doğar, bir sıraya girer, biri onu üstlenir,
yazılır, incelenir, tümleşir ve kapanır.

Bu zincirde inceleme yalnız bir halkadır. Bu dersin sorusu şudur: **halkanın kendisi ne kadar
sürüyor, ve zincirin tamamında payı ne?** İnceleme turunu kısaltmanın değerini bilmek için
önce turun neyin içinde durduğunu bilmek gerekir. Zincirin geri kalanı incelemeden uzunsa,
inceleme turunu yarıya indirmek toplamda az şey değiştirir.

## İş Öğesi ve Durumları

**İş öğesi (work item)**, bir ekibin izlediği en küçük iş birimidir: bir hata kaydı, bir
istek, bir görev. Öğenin tek bir kimliği, tek bir sahibi ve her an tek bir **durumu** vardır.
**Pano (board)**, bu öğelerin durumlarına göre dizildiği yüzeydir; her sütun bir durumdur ve
öğe soldan sağa ilerler.

Pano bir kayıt aracı değil, bir **görünürlük** aracıdır. Aynı bilgi bir listede de durabilir;
panonun eklediği şey, hangi durumda kaç öğe biriktiğinin bakışta okunmasıdır. Bir sütunun
şişmesi, o durumdan çıkışın girişten yavaş olduğunu söyler.

```text
# örnek pano dökümü — çalıştırılmamıştır

öneri        sırada        yazılıyor     incelemede    tümleşti
─────────    ──────────    ──────────    ──────────    ──────────
#412         #398          #377          #361          #350
#411         #395          #374          #359
             #391                        #356
             #388                        #352
                                         #349
```

Durum kümesinin kendisi bir tasarım kararıdır ve tek ölçütü vardır: **bir durum, çıkışı
başkasının eylemine bağlı olduğunda anlamlıdır.** `incelemede` bir durumdur çünkü öğe orada
yazanın değil inceleyenin eylemini bekler. Çıkışı hep aynı kişinin elinde olan bir sütun ise
durum değil, o kişinin özel listesidir; panoda yer kaplar ve hiçbir bekleme bildirmez. Aynı
ölçüt sütun sayısını da sınırlar: her yeni durum ancak yeni bir devir noktası varsa eklenir.

Bu dökümde `incelemede` sütunu beş öğe taşıyor, `yazılıyor` iki. Sayının kendisi bir kusur
değildir; kusur, sütunun **boşalma hızının** dolma hızından düşük olmasıdır. Beş öğe orada
biriktiyse **inceleme kuyruğu (review queue)** uzuyor demektir ve kuyruğun uzaması öğelerin
her birine bekleme yazar.

## Bekleme Durumda Değil Geçişte Durur

Panonun kolay yanılttığı nokta budur. Bir öğe `incelemede` sütununda dururken geçen zamanın
tamamı inceleme değildir; bir bölümü **inceleyenin öğeye bakmasını beklemektir.** Ölçülecek
şey öğenin bir sütunda durduğu süre değil, bir sütundan diğerine **geçmesi için geçen
süredir.**

Bu ayrım ölçümü tanımlar. Zincirde beş geçiş vardır ve bunların dördü incelemenin dışındadır:
öneri sıraya girer, sıradan biri onu üstlenir, yazım biter ve öğe incelemeye çıkar, inceleme
biter ve öğe kapanır. Beşinci geçiş — `incelemede` durumundan `tümleşti` durumuna — incelemenin
kendisidir ve **sabit değildir**: kaç tur döndüğüne bağlıdır.

**Bekleme süresi (wait time)** burada birimsiz sayılır. Saat ya da gün değil, karşılaştırılabilir
bir birimdir; amaç mutlak süreyi değil, halkaların birbirine oranını okumaktır. Bu ölçütler
**sürecin** ölçütleridir: bir öğenin ne kadar beklediği, o öğeye bakan kişinin değil, zincirin
biçiminin sonucudur.

## Sütun Uzunluğu ile Bekleme Aynı Şey Değildir

Panonun `incelemede` sütununda duran beş öğe bir **birikimdir**; geçişte ölçülen bekleme ise
bir **hızdır**. İkisi aynı sayıyı vermez. Beş öğelik bir sütun, çıkış hızı birim başına beş
öğeyse tek birimlik bekleme demektir; çıkış hızı birim başına bir öğeyse beş birimlik bekleme
demektir. Sütuna bakan biri iki durumu ayırt edemez, çünkü pano birikimi gösterir ve hızı
göstermez.

Bunun doğrudan sonucu şudur: **sütunu kısaltmak beklemeyi kısaltmaz.** Beş öğeden ikisini
başka bir sütuna taşımak birikimi düşürür ve panoyu rahatlatır; geçişin ne kadar sürdüğüne
dokunmaz. Beklemeyi kısaltan tek şey geçişin kendisini hızlandırmaktır ve inceleme halkasında
bunun anlamı tur sayısını düşürmektir.

Bir ayrım daha gerekiyor. Bir iş öğesi birden çok değişiklik taşıyabilir; o zaman inceleme
halkası öğe başına birden çok kez yürür ve zincirin toplamı buna göre büyür. Bu ölçüm öğe
başına **tek** değişiklik sayar ve sayıları o varsayımla verir. Öğe üç değişikliğe bölünmüşse
inceleme dışı geçişler bir kez, inceleme halkası üç kez ödenir — payı da o oranda büyür. Bu,
öğeleri bölmenin bedava olmadığını söyler: bölme incelemeyi kolaylaştırır ama zincirdeki
inceleme payını yükseltir.

## İncelemenin Zincirdeki Yeri

İnceleme halkasının uzunluğunu ne belirler? Kursun beşinci okuması bunu söylüyordu: **turu ve
beklemeyi uzatan şey ilk turda görülemeyendir.** Bir turda bulunanlar düzeltilir; bulunmayanlar
sonraki tura kalır ve her tur zincire bir bekleme daha yazar. Eksen çeşitliliği düşükse ilk tur
az bulur, tur sayısı artar, halka uzar.

Dolayısıyla zincirin toplamı iki kaynaktan beslenir. Biri **sabit** kısımdır — öneri, sıra,
yazım ve kapanış geçişleri; bunlar incelemenin nasıl yapıldığından bağımsızdır. Diğeri
**değişken** kısımdır ve doğrudan eksen atamasının sonucudur. Ölçüm bu ikisini ayrı sayar ve
oranlarını verir.

Bir kusur daha vardır: turlar bittiğinde **kalan kusur**. Kalan kusur inceleme bitmiş, öğe
kapanmış demek değildir; kapanan öğe daha sonra o kusur yüzünden **yeniden açılır** ve zincire
ikinci kez girer. Bu ikinci geçiş öneriyle başlamaz — öğe zaten önerilmiştir — ama sıradan
itibaren her şeyi tekrarlar.

Ölçümün varsayımları:

- **EA1** — Ortak tanımın 600 satırlık değişikliği ve 24 kusuru olduğu gibi kullanılır; sınıf
  dağılımı ve kâhin kursun sabitidir.
- **EA2** — İnceleme dışı dört geçişin beklemesi sabittir ve atamadan bağımsızdır: sırasıyla
  **5**, **9**, **2** ve **3** birim. Bu değerler zincirin biçimini temsil eder, bir ekibin
  ölçümü değildir.
- **EA3** — İnceleme halkasının beklemesi ortak tanımın tur döngüsünden gelir: her tur
  **6 birim** yazar ve tur sayısı ilk turda bulunan kusur sayısının sonucudur.
- **EA4** — Bulunan kusur o turda düzeltilmiş sayılır; kalan kusur sonraki tura taşınır. Altı
  tur üst sınırdır ve bu sınıra dayanan atamada kusur kalır.
- **EA5** — Kalan kusur öğeyi kapandıktan sonra **bir kez** yeniden açar. İkinci geçiş
  `sırada` durumundan başlar; öneri geçişi tekrarlanmaz.
- **EA6** — Ölçüt öğe başına raporlanır, kişi başına değil. Zincirdeki hiçbir sayı bir rolün
  başarımı olarak okunamaz; hepsi zincirin biçiminin sonucudur.
- **EA7** — Kümenin çözünürlüğü 24 kusurda **1/24**'tür; bekleme birimi tur başına **6** olduğu
  için zincirde ölçülebilen en küçük fark **6** birimdir.

## Ölçüm

```python
"""Is ogesi zinciri: durumlar arasi bekleme ve incelemenin payi.

Bolum 1 - dort atamada bulunan, kacan ve inceleme beklemesi.
Bolum 2 - zincirin toplami, incelemenin payi ve yeniden acilma bedeli.
"""
TOHUM = 20260815
EKSENLER = ("arayuz", "gerceklestirim", "test", "belge", "bicim")
YAZILMAYAN = "eksik gereksinim"
SINIFLAR = EKSENLER + (YAZILMAYAN,)
DIKKAT, OBEK = 12, 50
# Incelemenin disinda kalan gecisler: pano uzerinde okunan bekleme.
DIS = (("öneri", "sırada", 5), ("sırada", "yazılıyor", 9),
       ("yazılıyor", "incelemede", 2), ("tümleşti", "kapandı", 3))


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def degisiklik(satir, kusur_sayisi=24, tohum=TOHUM):
    r, kusurlar = uretec(tohum), []
    obek_sayisi = max(1, satir // OBEK)
    for i in range(kusur_sayisi):
        kusurlar.append({"no": i + 1, "sinif": SINIFLAR[r(6)],
                         "obek": r(obek_sayisi)})
    return {"satir": satir, "obek": obek_sayisi, "kusurlar": kusurlar}


def incele(d, eksenler, dikkat=DIKKAT):
    okunan = set(range(min(dikkat, d["obek"])))
    return {k["no"] for k in d["kusurlar"]
            if k["sinif"] in eksenler and k["obek"] in okunan}


def kurul(d, atamalar, dikkat=DIKKAT):
    bulunan = set()
    for eksenler in atamalar:
        bulunan |= incele(d, eksenler, dikkat)
    return bulunan


def tur_dongusu(bulunan, kusur_sayisi, tur_basina_bekleme=6):
    kalan, tur, bekleme = kusur_sayisi - len(bulunan), 1, tur_basina_bekleme
    while kalan > 0 and tur < 6:
        tur += 1
        bekleme += tur_basina_bekleme
        kalan -= max(1, len(bulunan) // 2)
    return tur, bekleme, max(0, kalan)


TAM = set(EKSENLER)
ATAMALAR = {
    "tek inceleyici, tüm eksenler": [TAM],
    "üç inceleyici, aynı eksen": [{"gerceklestirim"}] * 3,
    "üç inceleyici, ayrı eksen": [{"arayuz"}, {"gerceklestirim"}, {"test", "belge"}],
    "beş inceleyici, beş eksen": [{e} for e in EKSENLER],
}
DIS_TOPLAM = sum(b for _, _, b in DIS)
d = degisiklik(600)

print(f"iş öğesi 1 | değişiklik {d['satir']} satır, {d['obek']} öbek, "
      f"kusur {len(d['kusurlar'])} | inceleme dışı bekleme {DIS_TOPLAM}")
print("inceleme dışı geçişler: "
      + ", ".join(f"{a}→{b} {n}" for a, b, n in DIS))
print()
print(f"{'atama':<30s} {'bulunan':>7s} {'kaçan':>5s} {'yazılmayan':>10s} "
      f"{'tur':>3s} {'inceleme':>8s} {'kalan':>5s}")
for ad, atama in ATAMALAR.items():
    b = kurul(d, atama)
    kacan = [k for k in d["kusurlar"] if k["no"] not in b]
    yaz = sum(1 for k in kacan if k["sinif"] == YAZILMAYAN)
    tur, bekleme, kalan = tur_dongusu(b, len(d["kusurlar"]))
    print(f"{ad:<30s} {len(b):7d} {len(kacan):5d} {yaz:10d} "
          f"{tur:3d} {bekleme:8d} {kalan:5d}")

print()
print(f"{'atama':<30s} {'zincir':>6s} {'inceleme payı':>13s} "
      f"{'yeniden açılma':>14s} {'toplam':>6s}")
for ad, atama in ATAMALAR.items():
    b = kurul(d, atama)
    tur, bekleme, kalan = tur_dongusu(b, len(d["kusurlar"]))
    zincir = DIS_TOPLAM + bekleme
    # Kalan kusur öğeyi panoya geri koyar: sırada durumundan başlayan ikinci tur.
    yeniden = 0 if kalan == 0 else zincir - DIS[0][2]
    print(f"{ad:<30s} {zincir:6d} {bekleme / zincir:13.3f} "
          f"{yeniden:14d} {zincir + yeniden:6d}")
```

```
iş öğesi 1 | değişiklik 600 satır, 12 öbek, kusur 24 | inceleme dışı bekleme 19
inceleme dışı geçişler: öneri→sırada 5, sırada→yazılıyor 9, yazılıyor→incelemede 2, tümleşti→kapandı 3

atama                          bulunan kaçan yazılmayan tur inceleme kalan
tek inceleyici, tüm eksenler        22     2          2   2       12     0
üç inceleyici, aynı eksen            6    18          2   6       36     3
üç inceleyici, ayrı eksen           15     9          2   3       18     0
beş inceleyici, beş eksen           22     2          2   2       12     0

atama                          zincir inceleme payı yeniden açılma toplam
tek inceleyici, tüm eksenler       31         0.387              0     31
üç inceleyici, aynı eksen          55         0.655             50    105
üç inceleyici, ayrı eksen          37         0.486              0     37
beş inceleyici, beş eksen          31         0.387              0     31
```

## Zincirin Okunması

İnceleme dışı bekleme **19** birimdir ve dört satırın dördünde de aynıdır. Değişen tek şey
inceleme halkasıdır ve o **12** ile **36** arasında gidiyor. Zincirin toplamı böylece **31**
ile **55** arasında oynuyor: en kötü atama, en iyisinden **%77** daha uzun bir zincir üretiyor.

İncelemenin payı sağdaki sütunda. En iyi atamada zincirin **0,387**'si inceleme; yani öğenin
beklemesinin yaklaşık üçte ikisi incelemenin dışında geçiyor. En kötü atamada pay **0,655**'e
çıkıyor — inceleme artık zincirin yarısından fazlası. Bu iki sayının arasındaki fark bir
sonuç veriyor: **inceleme sabit maliyetli bir halka değil, zincirin en oynak halkasıdır.**

Buradan pratik bir sıralama çıkar. `sırada→yazılıyor` geçişi **9** birimle inceleme dışı en
uzun halkadır ve iyi atamada tek başına inceleme halkasının dörtte üçü kadardır. Zincirin en
iyi durumunda kısaltılacak yer inceleme değil, sıradır. Ama kötü atamada inceleme **36**
birimdir ve sıranın dört katıdır; orada sırayı kısaltmanın toplama katkısı küçük kalır.
**Hangi halkanın kısaltılacağı, atamanın hangisi olduğuna bağlıdır** ve bunu panodaki sütun
uzunluğu değil, geçiş beklemesi söyler.

Soldaki tablo aynı satırlarda bulunan ve kaçan sayısını da veriyor ve ikisi birlikte okunmalı.
`üç inceleyici, aynı eksen` satırı **6** bulup **18** kaçırıyor; zincirin en uzun olduğu satır,
aynı zamanda en az bulan satır. `tek inceleyici, tüm eksenler` **22** bulup **2** kaçırıyor ve
zincirin en kısası. Yani uzun zincir daha iyi bir inceleme satın almıyor — **uzunluğun kaynağı
zaten bulunamayanlardır.**

Kaçanların içinde her satırda **2** tane **eksik gereksinim** kusuru var ve bu sayı dört
satırda da değişmiyor. Zincirin biçimi, atamanın çeşitliliği, tur sayısı — hiçbiri o iki
kusuru bulmuyor. İş takibi bu sınıfın çaresi değildir; öğe panoda ne kadar iyi izlenirse
izlensin, gönderilmemiş olanın yokluğu incelemeye görünmez.

## Yeniden Açılma

İkinci tablonun son iki sütunu zincirin gerçek maliyetini veriyor. `üç inceleyici, aynı eksen`
atamasında altı tur sonunda **3** kusur hâlâ duruyor. Öğe kapanmıştır; kusurlar kapanmamıştır.
Kalan kusur eninde sonunda bir yerde ortaya çıkar ve öğe **yeniden açılır**.

Yeniden açılma zincire **50** birim ekliyor: öneri dışındaki her geçiş bir kez daha yürüyor.
Toplam **55**'ten **105**'e çıkıyor. Aynı değişiklik, en iyi atamada **31** birimde kapanıyor;
buradaki fark **74** birim, yani üç kat fazlası.

Bu sayının okunma biçimi önemlidir. Yeniden açılma bir gecikme değil, **ertelenmiş bir
beklemedir**: zincirin ilk geçişinde ödenmeyen bekleme, ikinci geçişte faiziyle ödenir. Panoya
bakan biri ilk geçişte hiçbir sorun görmez — öğe kapanmıştır, sütun boşalmıştır, sayılar
temizdir. Sorun panoda, öğe geri döndüğünde belirir ve o an artık ilk incelemenin ölçümüyle
ilişkilendirilmez.

Bu yüzden bir panonun okunabilmesi için kapanan öğe sayısı tek başına yetmez. **Yeniden açılan
öğe sayısı ayrı bir sütun ya da ayrı bir sayım olarak durmalıdır;** yoksa zincirin en pahalı
davranışı hiçbir yerde görünmez. Kapanış sayısı, ilk geçişte kapanan ile ikinci geçişte
kapananı ayırmadığı sürece iki farklı süreci aynı sayıyla raporlar.

## Özet

- **İş öğesi** bir akıştaki en küçük iş birimidir; **pano** öğeleri durumlarına göre dizer ve
  bekleme durumların içinde değil, durumlar arasındaki **geçişlerde** birikir.
- Zincirin inceleme dışı beklemesi **19** birimle sabittir; inceleme halkası atamaya göre
  **12** ile **36** arasında değişir ve zincirin toplamını **31**'den **55**'e taşır.
- İncelemenin zincirdeki payı **0,387** ile **0,655** arasındadır; inceleme sabit maliyetli bir
  halka değil, zincirin en oynak halkasıdır ve hangi halkanın kısaltılacağı atamaya bağlıdır.
- Uzun zincir daha iyi bir inceleme satın almaz: **36** birimlik halka **6** kusur bulup **18**
  kaçırır, **12** birimlik halka **22** bulup **2** kaçırır.
- Altı tur sonunda kalan **3** kusur öğeyi yeniden açar ve zincire **50** birim daha ekler;
  toplam **105**'e çıkar. Kapanış sayısı bu ikinci geçişi ayrı saymadıkça gizler.
- Dört atamanın dördünde de **2** **eksik gereksinim** kusuru kaçar; iş takibi bu sınıfı
  bulmaz.

## Sonraki Adım

Bu ölçümde öğeyi yazanın ne göndereceğini bildiği varsayıldı: zincire giren değişiklik, ekibin
beklentilerini karşılamaya çalışılarak yazılmış bir değişiklikti. Peki yazan o beklentileri
nereden biliyor? Ekibin içindeki biri onları turlarda öğrenmiştir; dışarıdan gelen biri
öğrenmemiştir. Yazılmamış bir beklenti, incelemenin ilk turunda bir bulgu olarak geri döner ve
her bulgu bir tur daha yazar. Sonraki ders bu beklentilerin yazılı hâlini ölçer: **katkı
rehberi** hangi sınıfları incelemeden önce kapatır, kapattığı her sınıf kaç tur eksiltir, ve
hiçbir eksenin aramadığı sınıfa dokunabilen tek düzenek gerçekten rehber midir?
