Ders 05 / 11
Risk Temelli Önceliklendirme
23 kalemlik yığın 68 geliştirici-gün efor ve 667 saat ertelenmiş bedel taşır; 22 günlük sprint kapasitesi dört farklı sıralama ölçütüne verilir. Doğuş sırası 6 kalem kapatırken efor sırası aynı bütçeyle 13 kalem kapatır ve birim başına önlenen saat 10,95'ten 17,77'ye çıkar. Yığının yalnız 2 kalemi her ölçütte içeride, 5'i her ölçütte dışarıdadır; kalan 16 kalemin kaderini ölçüt seçimi belirler.
İçindekiler
Önceki dört ders yakalamayı ölçtü: denetimler aşamalara dağıtıldı, aşama başına maliyet hesaplandı, gereksinimler sınanabilir biçime çevrildi ve yetkinlik ekiplere yayıldı. Dördü de aynı yerde durdu — bulunan kalemin düzeltildiğini varsaydılar. Sola kaydırmanın 250 saatlik kazancı o varsayımın üstünde duruyordu ve orada bir üst sınır olduğu açıkça yazılmıştı.
Bu ders varsayımı kaldırır. Düzeltmeyi yapacak olan aynı yirmi iki geliştiricidir ve zamanları özellik işiyle paylaşılır. Yığın kapasiteden büyük olduğunda soru “hangi kalem önce” hâline gelir ve bu soru bir sıralama ölçütü ister. Ders dört ölçütü aynı bütçede koşturur, birim kapasite başına kapanan kalemi karşılaştırır ve son olarak hangi ölçüt seçilirse seçilsin dışarıda kalan kümeyi ayırır.
Bir noktayı baştan ayırmak gerekir: buradaki sıralama bir risk sıralaması değildir. Risk sıralaması gerçekleşmemiş bir olayla çalışır ve bir olasılık terimi taşır. Bu yığındaki kalemler zaten yakalanmıştır; bulunmuş bir kalemin var olma olasılığı yoktur, yalnız ertelenme bedeli vardır. Ölçütlerin hiçbirinde olasılık terimi geçmez.
- DY22. Kalem kümesi önceki derslerle aynıdır. Eklenen iki alan düzeltme eforu ve ertelenmiş bedeldir.
- DY23. Düzeltme eforu kurgu geliştirici-gün cinsindendir ve model değeridir. Ertelenmiş bedel türetilir: kalem şimdi kapatılmazsa çalışma zamanına kadar taşınır ve aradaki geri alma farkını öder.
- DY24. Sprint kapasitesi, ekiplerin güvenlik işine ayırdığı toplam geliştirici-gündür; bir kalem ya tamamen kapatılır ya hiç açılmaz, yarım kapanma yoktur.
- DY25. Bütçe ölçüt sırasına göre harcanır ve sığmayan kalem atlanır, sıra orada durmaz. Bu kural küçük eforlu kalemlerin lehine çalışır ve etkisi tabloda görünür.
- DY26. Ölçütlerin hiçbiri olasılık ya da etki terimi taşımaz. Sıralamalar yalnız doğuş aşaması, ertelenmiş bedel ve efor üzerinden kurulur.
Kapasite ve Ertelenmiş Bedel
Model iki yeni sayı taşır: bir kalemi kapatmanın kaç geliştirici-gün tuttuğu ve kapatılmadığında çalışma zamanına kadar taşınmanın kaç saat ekleyeceği. İkincisi verilmez, önceki dersin geri alma bedelinden türetilir.
// kapasite.mjs — ayni 23 kalem, artik duzeltme eforu ve ertelemenin kat bedeliyle (model) export const YENIDEN = [0, 3, 8, 2, 6, 24], TEMEL = 2; export const bedel = (d, y) => TEMEL + YENIDEN.slice(d + 1, y + 1).reduce((s, x) => s + x, 0); // satir: ad | dogus asamasi | gorunurluk | duzeltme eforu (kurgu gelistirici-gun) export const KALEM = ` veri-siniflandirmasi-yok 0 100000 5 saklama-suresi-tanimsiz 0 100001 3 kisisel-veri-kapsami-belirsiz 0 100010 4 kimlik-dogrulamasiz-ic-cagri 1 011110 6 zayif-oturum-modeli 1 010011 4 guven-sinirsiz-veri-akisi 1 010000 7 yetki-modelinde-eksik-rol 1 011001 5 eksik-yetki-denetimi 2 001101 2 gomulu-gizli-anahtar 2 001110 3 dogrulanmamis-girdi 2 001001 2 gunluge-yazilan-kisisel-veri 2 001001 1 yarim-kalan-hata-yolu 2 001000 1 zayif-rastgelelik 2 001000 2 sinirsiz-sorgu-boyu 2 000001 4 guncel-olmayan-bagimlilik 3 000110 1 imzasiz-yapi-ciktisi 3 000110 3 gereksiz-yapi-araci 3 000100 1 varsayilan-parola 4 000011 1 asiri-genis-ag-kurali 4 000011 2 sifresiz-yedek 4 000010 2 acik-yonetim-ucu 4 000011 1 olcek-altinda-yaris 5 000001 6 ucuncu-tarafta-aciklanan-acik 5 000001 2` .trim().split('\n').map((r) => { const [ad, d, g, e] = r.trim().split(/\s+/); const dogus = +d, yakalanan = [...g].findIndex((c, i) => i >= dogus && c === '1'); // Ertelemenin bedeli: kalem simdi kapatilmazsa calisma zamanina kadar tasinir. return { ad, dogus, yakalanan, efor: +e, onlenen: bedel(dogus, 5) - bedel(dogus, yakalanan) }; }); export const SPRINT = 22; // sprint basina guvenlik isine ayrilan gelistirici-gun export const TOPLAM_EFOR = KALEM.reduce((s, k) => s + k.efor, 0); export const TOPLAM_ONLENEN = KALEM.reduce((s, k) => s + k.onlenen, 0); // Sira olcutleri: hicbiri olasilik icermez, kalem zaten yakalanmistir. export const OLCUT = { 'dogus-once': (a, b) => a.dogus - b.dogus || a.efor - b.efor, 'kat-buyuk': (a, b) => b.onlenen - a.onlenen || a.efor - b.efor, 'efor-kucuk': (a, b) => a.efor - b.efor || b.onlenen - a.onlenen, 'birim-basina': (a, b) => b.onlenen / b.efor - a.onlenen / a.efor, }; export function dagit(ad, butce) { const alinan = []; let h = 0; for (const k of [...KALEM].sort(OLCUT[ad])) if (h + k.efor <= butce) { alinan.push(k); h += k.efor; } return { alinan, h, kapanan: alinan.length, onlenen: alinan.reduce((s, k) => s + k.onlenen, 0), disarida: KALEM.filter((k) => !alinan.includes(k)) }; }
// kosum1.mjs — ayni sprint kapasitesi dort siralama olcutune veriliyor import { KALEM, SPRINT, TOPLAM_EFOR, TOPLAM_ONLENEN, OLCUT, dagit } from './kapasite.mjs'; console.log(`${KALEM.length} kalem, ${TOPLAM_EFOR} gelistirici-gun efor, ` + `${TOPLAM_ONLENEN} saat ertelenmis bedel; sprint kapasitesi ${SPRINT} gun ` + `(yigin ${(TOPLAM_EFOR / SPRINT).toFixed(1)} sprint)`); console.log('\nolcut kapanan harcanan onlenen saat gun basina kalem gun basina saat disarida'); for (const ad of Object.keys(OLCUT)) { const r = dagit(ad, SPRINT); console.log(ad.padEnd(15) + String(r.kapanan).padEnd(9) + String(r.h).padEnd(10) + String(r.onlenen).padEnd(14) + (r.kapanan / r.h).toFixed(2).padEnd(18) + (r.onlenen / r.h).toFixed(2).padEnd(17) + r.disarida.length); } console.log('\nkapasite buyudukce kapanan kalem (olcut basina)'); console.log('kapasite ' + Object.keys(OLCUT).map((a) => a.padEnd(14)).join('')); for (const b of [11, 22, 33, 44, 68]) console.log(String(b).padEnd(10) + Object.keys(OLCUT).map((a) => { const r = dagit(a, b); return `${r.kapanan} kalem`.padEnd(14); }).join(''));
23 kalem, 68 gelistirici-gun efor, 667 saat ertelenmis bedel; sprint kapasitesi 22 gun (yigin 3.1 sprint) olcut kapanan harcanan onlenen saat gun basina kalem gun basina saat disarida dogus-once 6 22 241 0.27 10.95 17 kat-buyuk 6 22 241 0.27 10.95 17 efor-kucuk 13 21 359 0.62 17.10 10 birim-basina 13 22 391 0.59 17.77 10 kapasite buyudukce kapanan kalem (olcut basina) kapasite dogus-once kat-buyuk efor-kucuk birim-basina 11 3 kalem 3 kalem 8 kalem 8 kalem 22 6 kalem 6 kalem 13 kalem 13 kalem 33 10 kalem 10 kalem 16 kalem 16 kalem 44 14 kalem 14 kalem 19 kalem 18 kalem 68 23 kalem 23 kalem 23 kalem 23 kalem
İlk satır ölçeği veriyor: 23 kalem 68 geliştirici-gün ister, sprint kapasitesi 22 gündür, yani yığın 3,1 sprint tutar. Bu, kapasitenin yetersiz olduğu anlamına gelmez; sıralamanın üç sprint boyunca anlamlı olduğu anlamına gelir.
İlk iki satırın aynı olması bir tesadüf değildir ve okunması gerekir. Ertelenmiş bedel yalnız doğuş aşamasından türetilir; bu yüzden “en çok kat” sıralaması, doğuş sıralamasının yeniden adlandırılmış hâlidir ve bağımsız bir bilgi taşımaz. Aynı ölçüyü iki farklı adla sıralayan bir program iki seçenek arasında karar verdiğini sanır, oysa tek seçeneği vardır.
Bağımsız bilgi eforda duruyor ve farkı o üretiyor. Aynı 22 günle doğuş sıralaması 6 kalem, efor sıralaması 13 kalem kapatır; birim başına önlenen saat 10,95’ten 17,77’ye çıkar. İki katına yakın bir fark, tek bir sütun değiştirilerek elde ediliyor ve ek kapasite gerektirmiyor.
Alt tablo bunun her bütçede sürdüğünü gösteriyor, ama bir yerde tersine dönüyor: 44 günde efor sıralaması 19, birim başına sıralaması 18 kalem kapatıyor. Oran sıralaması yüksek oranlı ama büyük eforlu bir kalemi erken alır ve o kalem sonradan iki küçük kalemin yerini kaplar. Birim başına en iyi olan sıra, kalem sayısı için en iyi sıra değildir; hangisinin istendiği önceden söylenmelidir. Altmış sekiz günde dört ölçüt de aynı yere varır — sıralama yalnız kapasite kıtken bir karardır.
Üç Sprint Boyunca Taşınan Bedel
Tek sprintlik bakış eksiktir, çünkü yığın üç sprintte kapanır. Asıl ölçü, ertelenmiş bedelin kaç sprint boyunca açık kaldığıdır: her sprint sonunda kapanmamış kalemlerin taşıdığı saat toplanır.
// kosum3.mjs — uc sprint boyunca tasinan ertelenmis bedel: siralama neyi hizlandiriyor import { KALEM, SPRINT, TOPLAM_ONLENEN, OLCUT } from './kapasite.mjs'; console.log('olcut sprint 1 kalan sprint 2 kalan sprint 3 kalan 3 sprintte tasinan'); for (const ad of Object.keys(OLCUT)) { const kalan = [...KALEM].sort(OLCUT[ad]); const izi = []; let tasinan = 0; for (let s = 0; s < 3; s++) { let h = 0; for (const k of [...kalan]) if (h + k.efor <= SPRINT) { h += k.efor; kalan.splice(kalan.indexOf(k), 1); } const acik = kalan.reduce((a, k) => a + k.onlenen, 0); izi.push(acik); tasinan += acik; } console.log(ad.padEnd(15) + izi.map((x) => String(x).padEnd(16)).join('') + tasinan); } console.log(`\nyigin toplami ${TOPLAM_ONLENEN} saat; tasinan sayi, ertelenmis bedelin ` + 'kac sprint boyunca acik kaldigini olcer');
olcut sprint 1 kalan sprint 2 kalan sprint 3 kalan 3 sprintte tasinan dogus-once 426 158 0 584 kat-buyuk 426 158 0 584 efor-kucuk 308 163 40 511 birim-basina 276 80 0 356 yigin toplami 667 saat; tasinan sayi, ertelenmis bedelin kac sprint boyunca acik kaldigini olcer
Üç ölçüt yığını üç sprintte kapatıyor, biri kapatmıyor. Efor sıralaması ilk sprintte en çok kalemi kapatan ölçüttü, ama üçüncü sprint sonunda hâlâ 40 saatlik açık taşıyor: küçük kalemleri öne aldığı için büyük eforlu kalemler her sprintte kalan bütçeye sığmadan sona atılıyor. Bir sıralamanın ilk sprint başarısı, yığını bitirip bitirmediğini söylemez.
Taşınan sütun ölçütler arasındaki farkı tek sayıya indiriyor. Doğuş sıralaması üç sprint boyunca 584 saat-sprint açık taşıyor, birim başına sıralaması 356. Aradaki fark yüzde 39’dur ve hiçbir ek kapasite harcanmadan elde edilir; yalnız aynı işlerin sırası değişmiştir. İlk sprintte kalan bedel de aynı yönü gösteriyor: 426 saate karşı 276 saat.
Sıralama Kimin Kaderini Belirliyor
Kapanan kalem sayısı ölçütün değerini verir ama asıl soru şudur: ölçüt değiştiğinde kimler dışarıda kalır. İki ölçüt aynı sayıda kalem bırakabilir ve tamamen farklı kalemler bırakabilir.
// kosum2.mjs — siralama degisince disarida kalan kume ne kadar degisiyor import { KALEM, SPRINT, OLCUT, dagit } from './kapasite.mjs'; const adlar = Object.keys(OLCUT); const disarida = new Map(adlar.map((a) => [a, new Set(dagit(a, SPRINT).disarida)])); console.log('olcut ciftleri arasinda disarida kalan kumenin ortak kalemi (sprint 22 gun)'); console.log(' ' + adlar.map((a) => a.padEnd(14)).join('')); for (const a of adlar) console.log(a.padEnd(15) + adlar.map((b) => { const ortak = [...disarida.get(a)].filter((k) => disarida.get(b).has(k)).length; return String(ortak).padEnd(14); }).join('')); const hep = KALEM.filter((k) => adlar.every((a) => disarida.get(a).has(k))); const hic = KALEM.filter((k) => adlar.every((a) => !disarida.get(a).has(k))); const degisken = KALEM.length - hep.length - hic.length; console.log(`\n${KALEM.length} kalem: her olcutte icerde ${hic.length}, her olcutte disarida ` + `${hep.length}, olcute gore yer degistiren ${degisken}`); console.log(`her olcutte disarida kalanin ertelenmis bedeli ` + `${hep.reduce((s, k) => s + k.onlenen, 0)} saat, kapatma eforu ` + `${hep.reduce((s, k) => s + k.efor, 0)} gun`); console.log('\nher olcutte disarida kalan kalemler'); console.log('kalem efor onlenen saat saat/gun'); for (const k of [...hep].sort((a, b) => b.onlenen / b.efor - a.onlenen / a.efor)) console.log(k.ad.padEnd(31) + String(k.efor).padEnd(6) + String(k.onlenen).padEnd(14) + (k.onlenen / k.efor).toFixed(1));
olcut ciftleri arasinda disarida kalan kumenin ortak kalemi (sprint 22 gun)
dogus-once kat-buyuk efor-kucuk birim-basina
dogus-once 17 17 6 6
kat-buyuk 17 17 6 6
efor-kucuk 6 6 10 9
birim-basina 6 6 9 10
23 kalem: her olcutte icerde 2, her olcutte disarida 5, olcute gore yer degistiren 16
her olcutte disarida kalanin ertelenmis bedeli 110 saat, kapatma eforu 26 gun
her olcutte disarida kalan kalemler
kalem efor onlenen saat saat/gun
imzasiz-yapi-ciktisi 3 30 10.0
kimlik-dogrulamasiz-ic-cagri 6 40 6.7
guven-sinirsiz-veri-akisi 7 40 5.7
sinirsiz-sorgu-boyu 4 0 0.0
olcek-altinda-yaris 6 0 0.0
Kesişim tablosu bu dersin en sert sayısını taşıyor. Doğuş sıralamasının dışarıda bıraktığı 17 kalemle efor sıralamasının bıraktığı 10 kalemin yalnız 6’sı ortaktır. İki program aynı yığına bakıyor, aynı bütçeyi harcıyor ve büyük ölçüde farklı kalemleri erteliyor.
Alt satır bunu tek cümlede topluyor: 23 kalemin 2’si her ölçütte içeride, 5’i her ölçütte dışarıda, 16’sı ölçüte göre yer değiştiriyor. Yığının yüzde 70’inin kaderini kalemlerin kendi nitelikleri değil, sıralama ölçütünün seçimi belirliyor. Bir güvenlik programının en belirleyici kararı, bu yüzden, hangi kalemin önemli olduğuna karar vermek değil, hangi sütunla sıralandığını yazmaktır; yazılmadığında karar yine verilir, yalnız kimsenin görmediği bir yerde verilir.
Her Ölçütte Dışarıda Kalan
Son liste ölçüt seçiminden bağımsız olan artığı gösteriyor: beş kalem, 110 saat ertelenmiş bedel, 26 günlük kapatma eforu. Bu beş kalem iki ayrı nedenle dışarıdadır ve ikisi ayrı karar gerektirir.
Üçü büyük eforludur. Güven sınırı çizilmemiş veri akışını düzeltmek yedi gün, kimlik doğrulaması olmayan iç çağrıyı düzeltmek altı gün ister; ikisi de kırkar saat önler, ama saat başına oranları listenin ortasında kalır ve 22 günlük bir bütçeye hiçbir sıralamayla giremezler. Bunların doğru karşılığı sıralamayı zorlamak değil, eforu bölmektir: yedi günlük tek bir kalem üç günlük iki adıma ayrılabiliyorsa listeye girer, ayrılamıyorsa ayrı bir bütçe ister. Bir sprint kapasitesiyle ölçülen bir yığın, sprintten büyük kalemleri yapısal olarak dışarıda tutar.
Kalan ikisi farklıdır ve önlenen saatleri sıfırdır. Ölçek altında ortaya çıkan yarış ile sınırsız sorgu boyu, ikinci derste ayrılan sınıftır: erken doğar, yalnız çalışma zamanında görünür. Bunlar sıralamada sona düşmez, sıralamaya hiç girmez, çünkü erken kapatmak hiçbir şey önlemez. Bu iki kalem için doğru karar önceliklendirme değildir; bunları çalışma zamanında ucuza görmenin yolunu kurmaktır ve o iş bu bütçenin dışındadır. Bir yığın listesinde sıfır değerli satırların ayrı tutulmaması, sıralamanın kendisini bozar.
Özet
- 23 kalemlik yığın 68 geliştirici-gün efor ve 667 saat ertelenmiş bedel taşır; 22 günlük sprint kapasitesiyle yığın 3,1 sprint tutar ve sıralama üç sprint boyunca karar üretir.
- Doğuş sırasıyla en çok kat sırası aynı sonucu verir, çünkü ertelenmiş bedel yalnız doğuş aşamasından türer; iki ad tek bir ölçüttür.
- Aynı 22 günle doğuş sıralaması 6, efor sıralaması 13 kalem kapatır; birim başına önlenen saat 10,95’ten 17,77’ye çıkar ve bunun için ek kapasite gerekmez.
- Birim başına en iyi sıra kalem sayısı için en iyi sıra değildir: 44 günde efor sıralaması 19, oran sıralaması 18 kalem kapatır. Üç sprint boyunca taşınan bedel doğuş sıralamasında 584, birim başına sıralamasında 356 saat-sprinttir ve efor sıralaması, ilk sprintte en iyi olmasına karşın üçüncü sprint sonunda 40 saatlik açık bırakır.
- 23 kalemin 2’si her ölçütte içeride, 5’i her ölçütte dışarıda, 16’sı ölçüte göre yer değiştirir; yığının yüzde 70’inin kaderini ölçüt seçimi belirler.
- Her ölçütte dışarıda kalan 5 kalem 110 saat taşır: üçü sprintten büyük eforludur ve bölünmedikçe giremez, ikisinin önlenen saati sıfırdır ve sıralamaya hiç girmemeleri gerekir.
Sonraki Adım
Bu konu güvenliği bir aşama olmaktan çıkarıp her aşamada farklı fiyatı olan bir karara çevirdi. Kapının kuyruğu sayıldı, aşama başına düzeltme maliyeti geri alınan işten türetildi, gereksinimler sınanabilirlik sınıflarına ayrıldı, yetkinliğin kapsamı ve derinliği ölçüldü ve son olarak sınırlı kapasite dört ayrı ölçütle dağıtıldı. Bütün bu ölçümlerin girdisi tek bir şeydi: elimizde yakalanmış bir kalem kümesi olduğu. Yirmi üç kalem baştan verildi ve nereden geldiği hiç sorulmadı.
Kazancın en büyük payını taşıyan aşamalar tasarım ve gereksinimdi — önlenen saatin yarıdan fazlası oradan geliyordu. Ama bir tasarım oturumunda hangi kalemin bulunacağı, bulanın gözüne bırakılamayacak kadar belirleyicidir. Üçüncü derste beş kötüye kullanım senaryosunun nereden geldiğinin ölçülmediği yazılmıştı; dördüncü derste şampiyonun görebildiği zorluk düzeyi bir tavan olarak duruyordu. İkisi de aynı boşluğu gösteriyor: tasarım aşamasında hangi kalemin doğduğunu sistematik olarak bulmanın kendi yöntemi vardır ve o yöntem hiç anlatılmadı. Sonraki konu Tehdit Modelleme o yöntemi kurar: sistemin veri akışı bir çizge olarak yazılır, güven sınırını geçen akışlar sayılır, çizge ögelerine sistematik bir sınıflandırma uygulanarak tehdit üretilir ve üretilenlerin kaçının anlamlı olduğu, kaçının karşı önleme dönüştüğü ölçülür.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.