Ders 05 / 10
Mühendislik Pratikleri
Hata bulma gecikmesinin ölçülmesi: kusurun doğduğu adım ile bulunduğu adım arası kaç adım ve kaç saat, tümleştirme sıklığı iki saatten kırk saate ve eşli çalışma oranı sıfırdan bire tarandığında bu gecikme, yeniden iş ve eşli çalışmanın iki kişilik maliyeti dahil toplam iş gücü nasıl değişir.
İçindekiler
Önceki dört ders bir sayıyı hep varsayım olarak aldı: kusur bulunduğunda geri dönülür. Kaç kalemin geri döndüğü ve kaça mal olduğu sayıldı, ama kusurun ne zaman bulunduğu her seferinde sürecin biçiminden okundu. Bu ders konuyu kapatırken o sayıyı doğrudan ölçer: hata bulma gecikmesi, yani kusurun doğduğu adım ile bulunduğu adım arasındaki mesafe.
Mesafe iki ayrı birimde ölçülür ve ikisi aynı şeyi söylemez. Adım cinsinden gecikme kusurun kaç aşama sonra göründüğünü, saat cinsinden gecikme o aşamaların ne kadar sürdüğünü verir. İki pratik bu iki birime ayrı ayrı dokunur: tümleştirme sıklığı saati kısaltır, eşli çalışma adımı. Teslimat hattının mekaniği bu müfredatta başka yerde koşturulduğu için burada hat bir periyottan ibarettir. Through-line bölgesel kütüphane ağıdır ve kurgudur.
Kusur Nerede Bulunuyor
Aşağıdaki blok bir modeldir, ölçüm değil.
SM25 — kırk sekiz iş kalemi bir üreteçle türetilir, üreteç kendi yazılır ve tohum görünürdür. Her kalemin bir boyutu (3–12 saat) ve dokunduğu bir modül vardır; aynı küme bütün ayarlarda kullanılır. Sekiz geliştirici çalışır.
SM26 — kusurun en erken görülebileceği adım bir sınıf olarak girdidir. Yol beş adımdır: yazım, yerel, tümleşim, sürüm, işletim. Yazım sınıfı kusur, ikinci bir çift göz varsa yazılırken görünür; yoksa tümleşime kadar gizli kalır. Tümleşim sınıfı ancak başkalarının işiyle birleşince, sürüm sınıfı sürüm sınamasında, işletim sınıfı yalnız işletimde görünür. Sürüm sınaması kırk saatte bir, işletim penceresi seksen saatte bir açılır.
SM27 — eşli çalışılan kalemde yazım sınıfı kusur yerinde düzeltilir ve ayrı bir iş kalemi olmaz. Bu, eşli çalışmanın modeldeki tek kazancıdır.
SM28 — her tümleştirme olayı sabit 0,5 saat tutar, üstüne aynı partide tümleşen her kalem çifti için 0,06 saat çakışma bedeli eklenir. Seyrek tümleştirmenin bedeli buradan gelir: parti büyüdükçe çift sayısı karesel artar.
Yeniden iş, kalemin üçte biri artı kusurun doğuşu ile bulunuşu arasında aynı modülde tamamlanmış her kalem için bir saattir.
// pratik.mjs — hata bulma gecikmesi (model); tumlestirme sikligi ve esli calisma orani taranir import { writeFileSync } from "node:fs"; const KISI = 8; // gelistirici sayisi const SURUM = 40; // surum sinamasi bu saatte bir kosar const ISLETIM = 80; // isletim penceresi const SABIT = 0.5; // her tumlestirme olayinin sabit maliyeti (saat) const CAKISMA = 0.06; // ayni partide tumlesen her kalem cifti icin cakisma maliyeti (saat) const ADIM = ["yazim", "yerel", "tumlesim", "surum", "isletim"]; // SM25: uretec kendi yazilir, tohum gorunur; ayni kalem kumesi butun ayarlarda kullanilir. let tohum = 20260127; const rast = () => (tohum = (tohum * 1103515245 + 12345) % 2147483648) / 2147483648; const MODUL = ["odunc", "ucret", "uyelik", "katalog", "sube", "kimlik"]; const KALEM = [...Array(48)].map((no) => { const boyut = 3 + Math.floor(rast() * 10); // 3-12 saat const m = MODUL[Math.floor(rast() * MODUL.length)]; const r = rast(); // SM26: kusurun en erken gorulebilecegi adim sinifi girdidir const sinif = r < 0.55 ? null : r < 0.76 ? "yazim" : r < 0.90 ? "tumlesim" : r < 0.96 ? "surum" : "isletim"; return { no, boyut, modul: m, sinif }; }); const sonraki = (t, p) => Math.ceil((t + 1e-9) / p) * p; // bir sonraki periyodik olay function kostur(T, oran) { const bos = Array(KISI).fill(0); const kalem = KALEM.map((k, i) => ({ ...k, esli: i % 4 < Math.round(oran * 4) })); let isGucu = 0; for (const k of kalem) { const kac = k.esli ? 2 : 1; const sec = bos.map((t, i) => [t, i]).sort((a, b) => a[0] - b[0]).slice(0, kac); const bas = Math.max(...sec.map(([t]) => t)); for (const [, i] of sec) bos[i] = bas + k.boyut; k.bit = bas + k.boyut; isGucu += k.boyut * kac; } // SM27: esli calisilan kalemde yazim sinifi kusur ayni anda gorulur; digerleri periyodu bekler const bulgu = []; for (const k of kalem) { if (!k.sinif) continue; const [adim, an] = k.sinif === "yazim" && k.esli ? [0, k.bit] : k.sinif === "surum" ? [3, sonraki(k.bit, SURUM)] : k.sinif === "isletim" ? [4, sonraki(k.bit, ISLETIM)] : [2, sonraki(k.bit, T)]; const ustune = kalem.filter((x) => x.modul === k.modul && x.bit > k.bit && x.bit <= an).length; // yazarken yakalanan kusur yerinde duzeltilir, ayri bir is kalemi olmaz bulgu.push({ no: k.no, sinif: k.sinif, adim, gecikmeSaat: an - k.bit, yeniden: adim === 0 ? 0 : Math.ceil(k.boyut / 3) + ustune }); } const yeniden = bulgu.reduce((a, b) => a + b.yeniden, 0); // SM28: her tumlestirme olayi sabit bir bedel, ustune partideki kalem cifti kadar cakisma odetir const son = Math.max(...kalem.map((k) => k.bit)); let olay = 0, cakisma = 0; for (let t = T; t <= sonraki(son, T); t += T) { const parti = kalem.filter((k) => k.bit > t - T && k.bit <= t).length; if (parti === 0) continue; olay += 1; cakisma += (CAKISMA * parti * (parti - 1)) / 2; } const tumlesimBedeli = +(olay * SABIT + cakisma).toFixed(1); const ort = (f) => bulgu.reduce((a, b) => a + f(b), 0) / bulgu.length; return { T, oran, sure: son, bulgular: bulgu, bulgu: bulgu.length, olay, cakisma: +cakisma.toFixed(1), gecikmeAdim: ort((b) => b.adim), gecikmeSaat: ort((b) => b.gecikmeSaat), esliBulunan: bulgu.filter((b) => b.adim === 0).length, yeniden, tumlesimBedeli, isGucu, toplam: +(isGucu + yeniden + tumlesimBedeli).toFixed(1) }; } const cikar = ({ bulgular, ...r }) => r; const SIKLIK = [2, 4, 8, 16, 40].map((T) => kostur(T, 0)); const ORAN = [0, 0.25, 0.5, 0.75, 1].map((o) => kostur(4, o)); writeFileSync("pratik.json", JSON.stringify({ SIKLIK: SIKLIK.map(cikar), ORAN: ORAN.map(cikar) })); console.log(`is kalemi: ${KALEM.length}, temel is: ${KALEM.reduce((a, k) => a + k.boyut, 0)} saat, ` + `gelistirici: ${KISI} (tohum ${20260127})`); console.log(`kusur sinifi: ${["yazim", "tumlesim", "surum", "isletim"] .map((s) => `${s} ${KALEM.filter((k) => k.sinif === s).length}`).join(", ")}; ` + `kusursuz ${KALEM.filter((k) => !k.sinif).length}`); console.log(`adimlar: ${ADIM.map((a, i) => `${i} ${a}`).join(", ")}`); const temel = SIKLIK[1]; console.log(`\ntumlestirme 4 saatte bir, esli calisma yok: kusur nerede bulunuyor`); console.log(`${"kusur sinifi".padEnd(14)}${"adet".padStart(6)}${"bulundugu adim".padStart(16)}` + `${"gecikme (adim)".padStart(16)}${"gecikme (saat)".padStart(16)}${"yeniden is".padStart(12)}`); for (const s of ["yazim", "tumlesim", "surum", "isletim"]) { const g = temel.bulgular.filter((b) => b.sinif === s); const o = (f) => (g.reduce((a, b) => a + f(b), 0) / g.length).toFixed(1); console.log(`${s.padEnd(14)}${String(g.length).padStart(6)}${ADIM[g[0].adim].padStart(16)}` + `${o((b) => b.adim).padStart(16)}${o((b) => b.gecikmeSaat).padStart(16)}` + `${String(g.reduce((a, b) => a + b.yeniden, 0)).padStart(12)}`); }
is kalemi: 48, temel is: 354 saat, gelistirici: 8 (tohum 20260127) kusur sinifi: yazim 14, tumlesim 5, surum 2, isletim 2; kusursuz 25 adimlar: 0 yazim, 1 yerel, 2 tumlesim, 3 surum, 4 isletim tumlestirme 4 saatte bir, esli calisma yok: kusur nerede bulunuyor kusur sinifi adet bulundugu adim gecikme (adim) gecikme (saat) yeniden is yazim 14 tumlesim 2.0 2.1 45 tumlesim 5 tumlesim 2.0 3.4 16 surum 2 surum 3.0 20.5 15 isletim 2 isletim 4.0 56.5 13
Tablo hata bulma gecikmesinin neden iki birimde ölçülmesi gerektiğini gösterir. Yazım sınıfı on dört kusur, eşli çalışma olmadığında iki adım sonra ve ortalama 2,1 saat sonra bulunur; bunlar yerinde düzeltilebilecekken tümleşimi beklerler. Karşı uçta yalnız iki işletim kusuru vardır ama gecikmeleri 56,5 saattir ve on üç saatlik yeniden iş üretirler — kusur başına 6,5 saat, yazım sınıfının iki katı. Az sayıda ama geç bulunan kusur, çok sayıda ve erken bulunan kusurdan pahalıdır.
İki Ayarın Taranması
// gecikme-taramasi.mjs — pratik.mjs'in yazdigi sonuclari okur; iki ayar ayri ayri taranir import { readFileSync } from "node:fs"; const { SIKLIK, ORAN } = JSON.parse(readFileSync("pratik.json", "utf8")); const SABIT = 0.5; const tablo = (baslik, satir, ust) => { const yaz = (h) => console.log(h.map((c, i) => String(c).padStart(baslik[i][1])).join("")); if (ust) { console.log(); console.log(ust); } yaz(baslik.map((b) => b[0])); satir.forEach(yaz); }; tablo([["tumlestirme", 13], ["olay", 6], ["gecikme (adim)", 16], ["gecikme (saat)", 16], ["yeniden is", 12], ["tumlesim bedeli", 17], ["toplam", 9]], SIKLIK.map((r) => [`${r.T} saat`, r.olay, r.gecikmeAdim.toFixed(2), r.gecikmeSaat.toFixed(1), r.yeniden, r.tumlesimBedeli, r.toplam]), "tumlestirme sikligi (esli calisma yok):"); // SM29: siklastirmanin tek bedeli olay basina sabit maliyettir; basa bas noktasi asagida. const a = SIKLIK[0], b = SIKLIK[1]; const basaBas = (b.yeniden + b.cakisma - a.yeniden - a.cakisma) / (a.olay - b.olay); console.log(`\niki saatlik ritim ${a.olay} olay, dort saatlik ${b.olay} olay uretir; ` + `olay basina sabit maliyet ${SABIT} saatken iki saatlik ritim ${(b.toplam - a.toplam).toFixed(1)} saat one gecer.`); console.log(`bu ustunluk olay basina sabit maliyet ${basaBas.toFixed(2)} saati asinca kaybolur.`); tablo([["esli oran", 11], ["sure (saat)", 13], ["yazarken bulunan", 18], ["gecikme (adim)", 16], ["gecikme (saat)", 16], ["yeniden is", 12], ["is gucu", 9], ["toplam", 9]], ORAN.map((r) => [`%${(100 * r.oran).toFixed(0)}`, r.sure, `${r.esliBulunan}/${r.bulgu}`, r.gecikmeAdim.toFixed(2), r.gecikmeSaat.toFixed(1), r.yeniden, r.isGucu, r.toplam]), "esli calisma orani (tumlestirme 4 saatte bir):"); // SM30: esli calismanin iki kisilik maliyeti kazanci asiyorsa, hangi carpanda basa bas gelir const y = ORAN[0], z = ORAN[ORAN.length - 1]; const carpan = (z.isGucu - y.isGucu) / (y.yeniden - z.yeniden); console.log(`\nesli calisma %100'de gecikmeyi ${y.gecikmeSaat.toFixed(1)} saatten ` + `${z.gecikmeSaat.toFixed(1)} saate, yeniden isi ${y.yeniden} saatten ${z.yeniden} saate indirir; ` + `karsiliginda is gucu ${y.isGucu} saatten ${z.isGucu} saate cikar ve is ${z.sure - y.sure} saat uzar.`); console.log(`kusur basina yeniden is ${(y.yeniden / y.bulgu).toFixed(1)} saattir; ` + `esli calismanin karsiligini vermesi icin bu sayinin ${carpan.toFixed(1)} katina cikmasi gerekir.`);
tumlestirme sikligi (esli calisma yok):
tumlestirme olay gecikme (adim) gecikme (saat) yeniden is tumlesim bedeli toplam
2 saat 21 2.26 8.0 82 13.3 449.3
4 saat 13 2.26 8.7 89 12.3 455.3
8 saat 7 2.26 10.0 94 13.6 461.6
16 saat 4 2.26 13.4 103 22.9 479.9
40 saat 2 2.26 21.4 132 53.6 539.6
iki saatlik ritim 21 olay, dort saatlik 13 olay uretir; olay basina sabit maliyet 0.5 saatken iki saatlik ritim 6.0 saat one gecer.
bu ustunluk olay basina sabit maliyet 1.25 saati asinca kaybolur.
esli calisma orani (tumlestirme 4 saatte bir):
esli oran sure (saat) yazarken bulunan gecikme (adim) gecikme (saat) yeniden is is gucu toplam
%0 50 0/23 2.26 8.7 89 354 455.3
%25 62 4/23 1.91 7.8 69 443 523.8
%50 73 7/23 1.65 6.3 59 530 601.9
%75 85 9/23 1.48 5.3 50 615 677.5
%100 90 14/23 1.04 4.7 35 708 755.8
esli calisma %100'de gecikmeyi 8.7 saatten 4.7 saate, yeniden isi 89 saatten 35 saate indirir; karsiliginda is gucu 354 saatten 708 saate cikar ve is 40 saat uzar.
kusur basina yeniden is 3.9 saattir; esli calismanin karsiligini vermesi icin bu sayinin 6.6 katina cikmasi gerekir.
İki Pratik, İki Ayrı Bileşen
İlk tablonun en dikkat çekici sütunu değişmeyendir. Tümleştirme iki saatten kırk saate seyrekleşse de adım cinsinden gecikme 2,26’da sabit kalır: kusur yine aynı adımda bulunur, yalnız o adıma varmak uzar. Saat cinsinden gecikme 8,0’dan 21,4’e, yeniden iş 82’den 132 saate çıkar. Kırk saatlik ritimde tümleşim bedeli de 13,3’ten 53,6 saate fırlar, çünkü tek partide tümleşen kalem sayısı arttıkça çakışma çifti karesel büyür. Tümleştirmeyi sıklaştırmak bu modelde hiçbir yerde kaybettirmez; iki saatlik ritim dört saatliğe göre 6,0 saat öndedir ve bu üstünlük ancak olay başına sabit maliyet 1,25 saati aşarsa kaybolur. Ölçülmesi gereken sayı budur: bir tümleştirme olayı ne kadar sürüyor.
İkinci tablo tam tersini yapar. Eşli çalışma adım cinsinden gecikmeye dokunur — 2,26’dan 1,04’e iner, çünkü on dört yazım kusurunun on dördü sıfırıncı adımda yakalanır ve hiç yeniden iş üretmez. Yeniden iş 89 saatten 35 saate düşer. Bedeli ise başka hiçbir ayarda görülmeyen büyüklüktedir: iş gücü 354 saatten 708 saate çıkar, çünkü aynı işi iki kişi yapar, ve iş kırk saat uzar, çünkü sekiz kişi yarısı kadar kalemi aynı anda yürütür.
Aritmetik açıktır. 354 saatlik ek iş gücü 54 saatlik yeniden iş tasarrufu satın alır. Eşli çalışmanın bu modelde karşılığını vermesi için kusur başına yeniden işin 3,9 saatten 6,6 katına çıkması gerekir. Bu çarpan hayalî değildir: işletim sınıfı kusurlar zaten kusur başına 6,5 saatte seyreder ve bir kusurun işletime kaçması hâlinde yeniden iş bu modeldekinin çok üstüne çıkar. Yani eşli çalışma, kusurun ucuz olduğu yerde pahalı bir alışkanlık, kusurun pahalı olduğu yerde ucuz bir sigortadır — ve hangisinin geçerli olduğu ölçülebilir bir sorudur.
Özet
- Hata bulma gecikmesi iki birimde ölçüldü: adım cinsinden gecikme kusurun kaç aşama sonra göründüğünü, saat cinsinden gecikme o aşamaların ne kadar sürdüğünü verir.
- Dört saatlik tümleştirmede 14 yazım kusuru 2 adım ve 2,1 saat sonra bulunur; 2 işletim kusuru 4 adım ve 56,5 saat sonra bulunur ve kusur başına 6,5 saatle en pahalı yeniden işi üretir.
- Tümleştirme sıklığı adım sayısını hiç değiştirmez (2,26’da sabit), saati değiştirir: 2 saatten 40 saate çıkınca gecikme 8,0’dan 21,4 saate, yeniden iş 82’den 132 saate, tümleşim bedeli 13,3’ten 53,6 saate çıkar.
- Sıklaştırmanın tek bedeli olay başına sabit maliyettir; 2 saatlik ritmin üstünlüğü ancak bu maliyet 1,25 saati aşarsa kaybolur.
- Eşli çalışma adım cinsinden gecikmeyi 2,26’dan 1,04’e, yeniden işi 89’dan 35 saate indirir, ama iş gücünü 354’ten 708 saate çıkarır ve işi 40 saat uzatır; başa baş için kusur başına yeniden işin 6,6 katına çıkması gerekir.
Sonraki Adım
Beş ders sürecin biçimini seçti, akışı sınırladı, eşgüdüm bedelini saydı ve hata bulma gecikmesini kısalttı. Hepsinin ortak bir kör noktası var. Bütün bu ölçümler işin kimden kime geçtiğini veri olarak aldı: yaşam döngüsü modelinde adım sınırı, yinelemede biriktirme listesinin sahibi, akış modelinde iş sınırının kapsadığı ekip, ölçekli düzende modüllerin hangi ekibe düştüğü. Her seferinde o sınır girdiydi ve hiç sorgulanmadı. Oysa o sınır bir yerden geliyor: ekipler bir biçimde bölünmüş, modüller bir biçimde paylaştırılmış ve iş kaleminin geçtiği her sınır aslında bir ekip sınırıdır. Sonraki konu bu soruyu sorar — ekiplerin nasıl bölündüğü mimariyi ne kadar belirliyor ve iletişim yapısı ile modül yapısı örtüşmediğinde bu beş derste sayılan bekleme, yeniden iş ve eşgüdüm turu ne kadar büyüyor.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.