Bana ne, kendimi başkasının yerine koymayacağım işte

Yıllar önce, Visual Basic program geliştirme ortamının yaygınlaşmak üzere olduğu bir dönemde ben de bu dili ve programı öğreneyim demiştim. Görsel kontrollerin desteğiyle uygulama yazmak çok daha kolay ve eğlenceli olacaktı. İşe başladıktan kısa bir süre sonra çok sinir bozucu bir olayla karşılaşmıştım. Bir satırdaki kodu bitirmeden başka bir satıra geçildiğinde ekranda birden bir hata mesajı beliriyordu. Program geliştirme ortamı tabii ki yarım kalmış satırı hemen yorumluyordu ve bu satır hatalıydı. Bu şekilde bakıldığında yerden göğe kadar haklıydı ama kullanıcıyı bu durumlarda bir hata mesajını okumak (tamam, hangimiz hata mesajlarını okuyor ki?) ve daha da önemlisi bu mesajı aktif bir şekilde kapatmak zorunda bırakarak kullanıcının dikkatini dağıtıyordu ve çalışma zevkini öldürüyordu. Günümüzde çok daha iyi geliştirme ortamları bu hataları daha az saldırgan yöntemlerle (Örneğin satırdaki hatalı yerin altını kırmızı çizerek) kullanıcıya iletip çalışma temposunu ve akıcılığı bozmamayı başarabiliyor. Artık eski günler bir daha geri gelmez diye düşünüyordum ki tabii ki yanıldığımı gördüm.

Üretim hattındaki paketlerin içinde yabancı maddelerin olup olmadığını kontrol eden makinelerimiz böyle hatalı bir ürün tespit edildiğinde bu paketi hemen üretim hattının dışına atıp, hatalı ürünü de ekranda gösteriyor. Daha doğrusu operatör doğru pencereyi açmışsa gösteriyor. Cin fikirli bir müşterimiz, böyle önemli bir olayın, yani hatalı bir paketin üretilmiş olmasının ne olursa olsun operatör tarafından görülmesinin gerektiğine inanarak yazılımda şöyle bir değişiklik yapmamızı istedi: Hatalı ürün hattan atılır atılmaz hangi pencere açık olursa olsun otomatik olarak hatalı ürünlerin gösterildiği pencere açılsın. Böylece operatör hemen bu durumdan haberdar olup duruma müdahale edebilecek ve üretimin kalitesi yükselecek.

Yazılımla her şeyin yapılabileceğine ve daha da önemlisi yapılan her şeyin satılabileceğine inanan satış elemanı hemen olur demiş ve bu istek bizim bölüme geldi. Tabii ki zamanında Visual Basic öğrenmeye başlayıp bunu yarıda bırakan nesle ait olan programcılar hemen bunun saçma olduğunu söylediler. “Operatör belki o anda makineyi ayarlamakla meşgul olacak ve otomatik olarak başka bir ekrana sıçramak ayarları bozmasa da operatörün asabını bozacaktır. Bu işlem üç beş kere tekrarlarsa da o operatör kesin ekranı bıçaklar” dendi. Proje yöneticisiyle konuşuldu ve ikna edildi ama müşteriyi ikna edemedik. Satış elemanı da “parayı veren düdüğü çalar” dedi ve biz de bunu programladık.

Birkaç hafta sonra servisten bir eleman bize geldi ve müşterinin yeni bir isteği olduğunu söyledi. Son yaptığımız özelliği kapatmamızı istiyormuş ve bunun için de ödeme yapacakmış. Müşteriyi kimin ikna ettiğini sorduk. Servis elemanının kendisi ikna etmiş ve çok kolay olmuş. Hayretler içinde kalmıştık. Bütün departmanın yapamadığını tek başına başarmıştı. Asıl ilginç olan ise satış elemanının olmaması gerken bir şeyden iki satış çıkarabilmesiydi. Umarım şirketteki herkes bu olaydan bir ders çıkarmıştır.

Kendini kullanıcının yerine koyabilmek

Kendini başkasının yerine koyabilmek genelde oyunlarda kullanılan bir yöntemdir. Rakibim bu durumda ne yapardı diye düşünerek iyi bir hamle ya da strateji bulmanın güzel yollarından biridir. Nedense yazılım projelerinde çok sık gözardı edilen bir yöntemdir ama. Yaptığımız programı ya da makineyi kendi klonlarımızın kullanacağını ya da bu sistemlerin bizim çalıştığımız ortamlarda kullanılacağını varsayıyoruz heralde.

İşe başladığım ilk günlerdi. Şirketin endüstriyel teraziler üretip sattığını biliyordum ama henüz hiçbir tanesini görmemiştim. Birgün hemen yanımızdaki elektronik tasarım bölümüne servisten bir dokunmatik ekran birimi geldi. Bu ekranı tasarlayan eleman elindeki şeye şaşkınlıkla bakıyordu. Servis elemanı bunun tamir edilip edilemeyeceğini sordu. Arkası paslanmaz çelikten yapılmış 20 inç büyüklüğündeki tamamen yamulmuş dokunmatik ekran tasarımcının vereceği cevabı bekliyordu. Geleceği bu cevaba bağlıydı. Sonunda herkesin bildiği cevap geldi. Yenisini gönderin!

Sonra öğrendik ki müşteri teraziye, düşük ağırlıkta bir ürün tartıldığında her yerden duyulabilen bir alarm sistemi eklenmesini istemiş. Aslında mantıklı bir istek. Bazı üretim bölümleri çok hareketli ve gürültülü olur ve buralarda görsel sinyaller her zaman fark edilmeyebilir. Bazen de operatör birden fazla makineyi kontrol ederken sistemde ortaya çıkan sorunları kaçırabilir. Dolayısıyla müşteri, operatör müdahale edene kadar bu alarmın çalması istenmiş ve biz de yapmışız. Hamur ürünleri üretilen bu fabrikada operatör alarmı susturmayı başaramayınca o an şans eseri elinde bulunan kilolarca ağırlıktakı hamur bloğunu ekrana fırlatmış. Alarmın sustuğunu hiç sanmıyorum ama eleman elinden geleni yapmış.

Birkaç gün sonra bir başka müşteriden başka bir ekran geldi. Bu yamulmamıştı ama bizim de sorunlardan düşündüğümüz kadar uzakta olmadığımız hissini veren bir durumdaydı. Ekran boydan boya yarılmıştı.

Bu ekran da yine operatörün uzun süre doğru menüyü bulamaması nedeniyle bıçaklanarak (evet demek ki bazı operatörler üretimde bıçak kullanıyor) yırtılmıştı.

Bu örneklerde ne müşteri ne de bizim ekip kendini kullanıcı operatörlerin yerine koyabildi. Sonuçta belki o operatörler ceza aldılar ama müşteriler de bir bir süre üretim yapamayıp kayıplar yaşamış oldu. Bu derece olmasa da bu işin buralara varacağını kimse göremedi mi acaba? Tabii ki görenler olmuştur, hatta söylemişlerdir de ama bazen müşteriyi, bazen de satış departmanını ikna etmek kolay olmuyor. Herkes kendini başkasının yerine koyabilseydi çok farklı bir dünyada başka başka programlar yazıyor olurduk heralde.

Saraydan kız kaçırma

Prensle prenses tam evlenme hazırlığındayken prens acı haberi alır. Prenses kaçırılmıştır. Söylentiye göre de mantık adasına kaçırılmış. Mantık adasında iki kabile yaşamaktadır. Bir kabile sadece doğruyu söyleyenlerden oluşmaktadır, diğeri de sadece yalan söyleyenlerden. Adanın kralı da bu kabilelerden birinden ama hangisinden olduğu bilinmiyor. Kral hakkında bilinen tek şey o adada o an olan ve daha önce olmuş olan her şeyi biliyor olması.

Prens bir koşu adaya gidiyor ve kralla görüşüyor. Ona şu soruları soruyor:

Prenses mantık adasında mı?

Prensesi gördünüz mü?

Kralın bu sorulara verdiği cevapları (cevapların evet ya da hayır olduğu kesin ama) bilmiyoruz ama prensin bu cevaplarla prensesin mantık adasında olup olmadığını bulduğunu biliyoruz.

Prenses mantık adasında mı?

Çözüm

Kilitler ve anahtarlar (Çözüm)

Soru

Herhangi üç korsanın bu sandığı açamaması için olası her üç korsanlık grup için bir farklı kilit kullanılması lazım. Bu kilidin anahtarlarını da bu üç kişi dışındaki herkese vermek lazım. Bu şekilde iki şeyi garantilemiş oluruz. Herhangi üç kişinin açamayacağı bir kilit bulunduğundan dörtten az kimse bu sandığı açamaz ve herhangi dört kişi de bu sandığı açabilir, çünkü bu dört kişi içinde bir üçlü grup bir kilit hariç diğer hepsini açabilir ve kalan dördüncü kişi de bu son kilidi açabilir.

O zaman toplam kaç kilit gerektiğini hesaplayalım. Soruda 7 korsan olduğuna göre bu yedi korsanın üçlü kombinasyonları kadar kilit gerekecektir.

\({7\choose3}=\frac{7\cdot{6\cdot{5}}}{3\cdot{2\cdot{1}}}=35 \)

Demek ki toplam 35 kilit ile bu sorun çözülebilir.

Peki korsanlar kaçar anahtar almalı? Her üçlü korsan grubu için bir kilit taktık ve bu kilidin anahtarlarını diğer dört korsana verdik. Yani toplamda \(35\cdot{4}=140 \) adet anahtar dağıttık. Dolayısıyla kişi başına da \(140 : 7 = 20 \) anahtar düşer.

Kilitler ve anahtarlar

7 korsan bir hazine buluyor ve bütün paraları büyükçe bir sandığa koyuyor. Bu sandığı kilitlemek istiyorlar ama bunu öyle yapmak istiyorlar ki sandığı ancak en az 4 korsan beraber açabilsin. Herhangi 3 korsan açamayacak ama herhangi 4, 5, 6 korsan ya da hepsi birden açabilecek. Her kilidin birden fazla anahtarı olabilir ama bir anahtar sadece bir kilidi açabilir. Bu durumda sandığı kilitlemek için en az kaç kilit gerekir? Korsanlar kaç anahtar almalı?

Plakalar (Çözüm)

Soru

Elimizdeki tamkare plakalar 1 ve 4, tamkare olmayanlar da 2, 3 ve 5’tir. Döner kavşaktaki sürücülerden biri önünde ve arkasında tamkare bir plaka görseydi kendi plakasının tamkare olmayacağını hemen anlayacaktı. İlk turda herkesin bilmiyorum demesi bu ihtimali ortadan kaldırdı, yani tamkare plakalar aralarında bir araç olacak şekilde dizili değil. Bu durumda kalan tek olasılık tamkare plakaların arka arkaya olmaları.

Tamkare plakalı araçların bir araç arayla dizili olduğu temsili durum

Yukarıdaki şekilde de görüldüğü gibi 1 ve 4 plakalı araçlar arasında sadece bir araç varsa bu durumda o araç (şekildeki 3 plakalı araç) ilk soruya rahatlıkla hayır cevabını verebilir. Ayrıca şekilde yine görüldüğü üzere iki araç arasında bir tarafta sadece bir araç varken diğer tarafta da iki araç vardır. Bu nedenle yukarıdaki paragrafta iki tamkare plakalı araç arka arkaya olmalıdır dedim.

Eğer iki tamkare plakalı araç arka arkaya ise o zaman bu iki araç ve bunların önündeki ve arkasındaki birer araç da ya önde ya da arkada sadece bir tane tamkare plakalı araç görecektir.

Tamkare plakalı iki aracın arka arkaya olduğu temsili durum

Bu şekilde de görüldüğü gibi 1 plakalı araç sadece 4 plakalıyı, 4 plakalı 1 plakalıyı, 3 plakalı 4 plakalıyı ve son olarak da 2 plakalı 1 plakalı aracı görebilir. Bu bilgi ise hiçbiri için yeterli olmayacak ve ikinci turda da kendi plakalarının tamkare olup olmadığını bilemeyecekler. Kendi plakasının tamkare olmadığını sadece iki tamkare olmayan plakayı gören sürücü bilecektir. Bu da soruda verildiği üzere Ebru’dur. Demek ki Ebru’nun önünde ve arkasında tamkare olmayan plakalı araçlar vardır.

Dönel kavşaktaki araçları artık trafiğin sağdan ilerlediği yerler için göstereceğim. Bu durumda araçlar kavşakta saat yönünün tersi istikametinde ilerlemektedirler. Son konuşmaya gelindiğinde araç sürücüleri ile bilinen durum aşağıdaki şekildeki gibidir:

Son cevaplar öncesi durum

Son soruya cevaplar verilmeden önce bütün sürücüler bu şekildeki bilgilerden haberdardır. Biz araçta olmadan bu sonuçlara ulaşabildiysek onlar da bu sonuçlara ulaşabilmiştir.

Didem burada arkasındaki araç olarak Ebru’nun aracını görüyor ve kendi aracının plakasının da tamkare olmadığını biliyor. Eğer Ebru’nun aracının plakası 2 olsaydı rahatlıkla evet cevabını verecekti. Ebru’nun aracının plakası 5 olsaydı da hayır cevabını verecekti. Bu iki cevabı da veremediğine göre Ebru’nun aracının plakası 3 olmalı. Şimdi bu bilgi ışığında şeklimize yeniden bakalım.

Didem’in son cevabından sonraki durum

Şimdi Betül ve Ebru hayır diyor. Ebru, Ayşe’nin aracının plakasını görüyor ve hayır diyor. Demek ki Ayşe’nin aracının plakası 3’ten büyük, yani 5 olmalı. Ayşe’nin aracının plakası 5 olursa Didem’in aracının plakası da 2 olmalı. Betül de kendi aracının plakasının 1 ya da 4 olması gerektiğini biliyordu. Arkasındaki araç Canan’ın aracı olduğuna ve bunun plakası da kendininkinden küçük olmadığına göre Betül’ün aracının plakası 1 ve Canan’ın aracının plakası da 4 olmalı. Şimdi şeklimize yeniden bakalım.

Betül ve Ebru’nun son cevaplarından sonraki durum

Bu son tablo Ayşe’nin ve Canan’ın son cevaplarına da uygun durumdadır. Ayşe’nin aracının arkasında Betül’ün aracı var ve Canan’ın aracının arkasında da Didem’in aracı var.

 

Kodu gözden geçirme

Çalıştığım yerde tabii ki doğru düzgün yapılmayan bir yazılım geliştirme tekniğidir. En basit şekliyle yazılmış olan programın belli kurallara göre kontrol edilmesidir. Bu kurallar ciddi ortamlarda yazılı olarak bulundurulur. Bu kuralların bulunmadığı durumlarda gözden geçirmeyi yapan kişiler kendileri karar verirler. Bu sonuçlar sonca programcıya bir şekilde iletilir. Bu birebir bilgisayar başında bir görüşme olabilir ya da başka bir şekilde ilgili programcıya yapılacak iş olarak bildirilebilir. Bu şekilde bazı karışık hatalar çok geç olmadan bulunabilir.

Bazı yerlerde bu iş statik kod analizi araçlarına paslanır. Bu ikisi birbirinin yerini tutmaz ama istatistik tutulmayan yerlerde tek başlarına yeterli oldukları sanısına kapılmak çok kolay olmakta. Kodu gözden geçirme işleminden sonra ilgili programcıyla bulunan noktaların tartışılması ilginç bir olaydır. Tecrübesiz programcılar genelde kendilerine saldırıldığı sanısına kapılırlar ve gereksiz, duygusal tartışmalara girişebilirler. İki taraf için de öğretici olabilecek bu aşama böyle şeylerle boşa harcanmamalı bence.

Teoriye dalıp asıl anlatacağım şeyi unutuyordum az daha. İlaç endüstrisinde çalışan müşteriler genelde bizden programla beraber bu gözden geçirme sonuçlarını da rapor halinde isterler. Bir seferinde bir ekipten böyle bir kod gözden geçirme isteği geldi. O gün öğlende program müşteriye teslim edilecekmiş ve bu işi yapacak boşta elemanları yokmuş. Kabul ettim. Hangi özelliklere bakmam gerektiğini sordum. Genel bir kontrol istediler, zaten tek bir dosyada değişiklik yapmışlar. Kontrol bitince programı onayladığımı belirten bir kağıdı da imzalamam gerekiyormuş. Programı açıp okumaya başladım. Bir süre sonra bir hafıza bölümünün serbest bırakılmadığını gördüm. Bu tür hatalar normalde her işletildiğinde hafızanın bir kısmını programdan çalarak daha az kullanılabilir hafıza bırakır. Bir süre sonra da programa hafıza kalmaz ve program da çalışamaz. Bunun üzerine şefe gittim ve durumu anlattım. “Bu hatayı buldum ve dolayısıyla programı onaylayamayacağım” dedim. O da baktı ve hatayı gördü. Bunun üzerine o da kendi şefine gitti ve çözüm aramaya başladılar. Programı düzeltip, test edecek zamanları kalmamıştı. Bunun üzerine raporumun altına bir ek yazıldı (hata, sistemin genel özellikleri nedeniyle ortaya çıkamaz gibi bir şeyler) ve şefim de bu raporu imzaladı. Bir sorun daha kolayca çözülmüş oldu.

Akraba kayırıcılığı

Akraba kayırıcılığı tabii ki sadece şarka mahsus bir durum değil. Yani öyle düşünüp moraliniz bozulmasın. En fazla “Almanlar bizi kıskanıyor, onlar da yapıyor” deyip geçin.

Görüntü işleme projesi başladığında çok sıkışık bir zaman planımız vardı. Önce fuara yetişmesi gereken bir proje yaptık ve ardından da büyük bir müşteri için anlaşılan diğer üreticilerin yanaşmadığı bir proje. Fazladan mesailerle geçen aylar sonunda müşteri projenin ne durumda olduğunu görmek için şirkete uğramaya karar verdi. Sistemin yeterince hızlı çalışıp çalışmayacağını görmek istiyordu. Ulaşmamız gereken zaman da ciddi bir şey değildi. Bütün bir paketi inceleyip sonuçları bir sonraki makineye bildirmek için 2 saniye zamanımız vardı.

O sırada proje yöneticisinden ne tür yardıma ihtiyacımız olabilir gibi bir soru geldi. Biz de önümüzde bu tür sorunlarla sık sık karşılaşacağımız için zaman ölçme konusunda ufak bir desteğe ihtiyacımız var dedik. Aslında bunu yapabilecek elemanlarımız vardı ama herkes meşgul olduğundan böyle bir şey istedik. Hem işimize yarayacak bir şey olacaktı, hem de bu iş sırasında bizi soru yağmuruyla işimizden de pek alıkoymayacaktı. Yöneticimiz tamam deyip bu işle ilgileneceğini söyledi. Şaşırmıştık ama yine de daha önceki performanslarına göre iyi bir hareketti diyerek sevinçle karşıladık.

Birkaç gün sonra proje yöneticimiz müjdeyi verdi. Destek bulunmuştu. Destek verecek ekiple toplantı da o cuma yapılacaktı. Müşteri bir sonraki cuma gelecekti ve o hafta perşembe günü resmi tatildi. Kısaca pek bir zaman kalmamıştı. Bizim ekip şefi tatilde olduğundan toplantıya benim girmemi istedi. Kabul ettim.

Toplantı günü geldiğinde hazırlıklarım tamamlanmıştı. Olumsuz bir durum için de B planımız vardı. Program müşteri geldiğinde bitmiş olmayacaktı tabii ama iyi yolda olduğumuzu gösterebilirdik. Toplantı odasına girdiğimde (nedense toplantılara hep geç gidiyormuşum izlenimi bırakıyorum ama yok öyle bir şey) bizim yönetici ve diğer şirketin sahibi masada yerlerini almış havadan sudan konuşuyorlardı. Kısa bir tanışmadan sonra problemi anlattım. “Bu projede ve ileridekilerde sık sık duyarlı bir şekilde zaman ölçmemiz gerekecek ve bu altyapıyı kurmak için şu an ayıracak kaynağımız olmadığından profesyönel yardım almayı düşündük. Bu iş için kullanmayı düşündüğümüz programlar şunlar ve sistemimizin özellikleri de şöyle. Bu iş haftaya müşteri gelmeden biterse iyi olur.”

Desteği verecek eleman bunun yapılabileceğini, kolay olduğunu filan anlattı. İyi o zaman, toplantı hemen biter, gider diğer işlere bakarım diye düşünüyordum ki birden daha iyi bir planı olduğundan bahsetmeye başladı. İki saniye önceki rahatlama yerini birden korkuya bıraktı. Yöneticimiz de merak etti ve neler yapılabileceğini sordu. Eleman da anlatmaya başladı: Bizim görüntü işleme alanında oldukça fazla tecrübemiz var. Anladığım kadarıyla sizin sorun şuralarda (Bizim sorunları ne zaman konuştunuz siz ya?). Sizin kullandığınız model (Oh, oh, detaylar bile konuşulmuş) yerine monolitik bir yapı kullanarak program daha hızlandırılabilir ve böylece zaman ölçmeye gerek kalmaz (Bu nasıl bir kabus böyle?).

“İyi de bizim sadece zaman ölçmeye ihtiyacımız var” diye araya gireyim dedim ama masal devam ediyordu. “Şimdi biz müşterinin ürününü inceleyecek rutinleri yazalım. Sonra onu sizin programa entegre ederiz. Kesinlikle daha hızlı bir program olacaktır.”

“Müşteri haftaya geliyor. Önümüzdeki hafta kısa bir hafta. Böyle bir program yapsanız bile bu süre içinde entegre edilmesi imkansız.”

“Bizim hazır kütüphanelerimiz var. O kadar sürmez. Entegrasyonda sizi de destekleriz.”

Bu sırada kara kara dereyi geçerken at değiştirilmez Almanca nasıl denir acaba diye düşünüyordum. Adamın önerdiği şey bugüne kadar pratikte hiçbir zaman başarılı olamamış bir yöntemdi. Hatta Brooks kanunu diye de geçer: “adding human resources to a late software project makes it later”. Bu yeni elemanların bizim sisteme alışana kadar bir süre geçmesi lazım, ayrıca bu sıradaki iletişimler de bizim elemanları işlerinden alıkoyacak. Haftaya yetişmesine imkan yok yani.

Bunları da anlattım ve bizim proje yöneticisi dahiyane bir çözümle olaya girdi. “Aynı anda iki yolu da izleyemez miyiz acaba?”. Destek veren şirketin sahibi buna hemen olumlu yaklaştı. Ben de nasıl bir oyuna kurban gittiğimi ancak o zaman anladım.

“Çarşamba sabaha kadar rutinler hazır olursa belki entegrasyon şansımız olur. Ondan sonra imkansız. Zaman ölçümlerini de en geç o zamana hazırlarsanız iyi olur.”

Toplantıdan sonra proje yöneticisine ayrıca bu yapılan planın yetişmeyeceğini zaman ölçme kısmını en kısa sürede yaptırmasını söyledim. En azından ileride kullanabileceğimiz bir şey yapmış olurlardı o zaman. Tabii ki “hee, tamam” cevabını aldım.

Sonraki hafta her gün planın ne durumda olduğunu sordum. Çarşamba günü de geldi ve ne zaman ölçümü ne de söz verilen rutinler geldi. Çarşamba öğlende proje yöneticisine “Rutinler artık gelmese de olur, umarım müşterinin tatmin olacağı kadar hızlıyızdır.” dedim. Tabii ki cuma günü rutinler geldi. Bizim sisteme eklememi istediler. Ben de “Ben kendimle dalga geçebilirim, bunun için size ihtiyacım yok” dedim ve müşteriye sunum için B planını deneyeceğimizi anlattım. Hemen programa birkaç kıytırık zaman ölçme rutini ekledik, programı yeniden derledik ve müşteriyi karşıladık. İstenen zamana henüz ulaşamamıştık ama projecilerimiz bunu müşteriye iyiye gidiş olarak satabilmişti. Müşteri de memnun kalmıştı (memnun kalmaya ihtiyacı olan müşteriyi memnun etmek kadar kolay bir şey yoktur).

Destek hizmeti aldığımız firmanın sahibi bizim proje yöneticisinin sınıf arkadaşıymış. Yaptığımız toplantının sonucu baştan belliymiş yani. Böylece kendi rutinlerini bizim sisteme entegre etmeye çalışarak güzel bir proje kapmayı başardılar. Bu süre içinde zaman ölçme sistemi asla kurulmadı. Hala, B planında ne yaptıysak o kullanılıyor. Bir yılda eklediğimiz destek rutinlerini işe yaramadıkları için sistemden çıkarabilmemiz üç dört yıl daha sürdü.

Birkaç illüzyon

David Richeson’ın Blog (Division by zero) sayfasında bulduğum aşağıdaki yazıdaki kağıttan yapılmış bazı şekilleri denemeyi başardım. Sayfada her şeklin nasıl yapıldığı anlatılıyor. Oradaki açıklamaların çıktısını yazıcıdan aldım ve makasla kesip işaretli yerlerden katllayıp bant ile yapıştırdım. Aşağıdaki videolarda da denemelerimi görebilirsiniz. Tahtadan yapılmışları ile daha kolay olacağını sanıyorumçünkü ilüzyon tamamen tutuş ve bakış açısına bağlı çalışıyor.

Yazı

Mecburi saçmalıklar

Şirketteki ilk projelerimden biri, bir ürünü DBMS destekli bir hale getirmekti. Önceki versiyon Codebase denen bir sistemle yazılmıştı ve sık sık veri kaybına ya da bozukluklarına yol açmaktaydı. Transaksiyon kontrolü de zordu o sistemde. DBMS olarak MySQL’i seçtik ve projeye başladık. Programlama dili olarak C++ ve geliştirme ortamı olarak da Visual Studio 2003 ve MFC (Microsoft Foundation Classes) kullandık. MFC, ODBC (Open Database Connectivity) üzerinden veri tabanıyla iletişim imkanı sunuyordu. CDatabase nesneleri filan vardı. Değişik dilleri desteklemek zorunda olduğumuzdan da Unicode desteğini aktifleştirmiştik. Başka veri tabanlarını destekleme durumu ortaya çıkabilir diye hem şema hem de veritabanı tabloları için ayrı kütüphaneler de yazdık. Bu tür sistemler o sıralarda Java için çok yaygındı ama C++ için hoşumuza giden bir çözüm bulamamıştık. Projeyi beraber yaptığım arkadaş da o sıralarda C++’tan başka bir dile geçmeye yanaşmıyordu.

İlk basit denemelerden sonra ümit vadeden planımız garip bir sorunla karşılaşmıştı. Nerede olduğunu bilmediğimiz bir Access Violation hatasına çarpıp duruyorduk. Tabii ki hata anındaki stack trace (o anda programda işletilen komutların hiyerarşik listesi) hiçbir şey ifade etmiyordu. Anlaşılan bayağı şiddetli bir buffer overrun (program yanlış yerlere veri yazarak başka nesneleri ve dolayısıyla programın çalışmasını bozuyor) sorunuyla karşı karşıyaydık. Tabii hatanın tam olarak hangi komutta ortaya çıktığını bilmediğimizden internette de aratamıyorduk. Sonuçta buffer overrun ya da access violation nedeni bulmak için oldukça genel terimlerdi. Stack trace, hatanın fark edildiği anda okunamaz  durumda (daha doğrusu bizim durumumuzda anlamsız) olduğundan gözümüz kapalı yavaş yavaş uçuruma doğru yürüme yolunu seçtik. Problemin tek iyi tarafı tekrarlanabilir olmasıydı. Bu sayede defalarca uçuruma gelip hangi anda düşmeye başladığımızı anlamaya çalışacaktık.

Standard yöntem programı hata ayıklayıcı ile çalıştırıp adım adım işletmek olabilirdi. Hata mesajının geldiği yere bakarak programın maksimum nereye kadar ilerlediğini tahmin edebiliyorduk ve baştan oraya gitmek epey zaman alacaktı. Bunun üzerine programın çeşitli yerlerine breakpointler (Program o satıra kadar işletilir ve o noktada otomatik olarak durdurulur) koyarak nereye kadar gidebildiğine baktık. Bu yerleri de genelde hep ikiye bölerek bu aramayı hızlandırdık, yani bir nevi binary search algoritması kullandık. Bir süre sonra hata mesajının nerede ortaya çıktığını bulduk ama bu çok işe yaramıyordu çünkü buffer overrun daha önce olmuş olmalıydı. Biz sadece en geç ne zaman olmuş olabileceğini bulmuş oldu.

Program unit test gibi yöntemler kullanılmadan yazılmış olduğundan parçaları tek tek hızla test etme şansımız da yoktu. Elimizdeki tek araç visual studio içindeki hata ayıklayıcısıydı. Nesnelerin değerleri filan normal gözüküyordu. Bununla oynarken sadece nesnelerin değerlerini değil aynı zamanda bu nesnelerin bulunduğu adreslerdeki (ve bu adreslerin çevrelerinde) değişiklikleri de görebildiğimizi fark ettik. Visual studio her işletilen satır için seçilen adres bölgelerindeki değişiklikleri kırmızı gösterebiliyordu. Çaresizlikten buralara bakayım dedim. Sonuçta hatanın yaklaşık hangi satırlarda olduğunu bulabilmiştim. O satırlardaki nesnelerin hangi adreslerde olduğunu da buldum. Ondan sonra dürbünümü o alana tutup programı satır satır işletmeye başladım. Her satırda ufak tefek kırmızı değişiklikler görünüyordu ama bunlar aradığım şey değildi. O nesnelerin büyüklüklerini bildiğimden bu kırmızı bölgelerin nesnenin içinde mi dışında mı olduğunu hesaplayabiliyordum. Böyle motivasyonumu kaybetmiş bir şekilde satırları tek tek işletirken birden adres ekranı havayi fişek patlaması gibi kıpkırmızı oldu. En son hangi satırda olduğuma baktım hemen ve veri tabanıyla bağlantı kurma komutunu gördüm. İnternette arattım. CDatabase, buffer overrun filan dedim ve binlerce sonuç aldım. Meğer MFC’nin o versiyonu unicode ile bir hesap hatası yapıyormuş ve bu sayede epeyce bir adres alanına yanlış değerler yazıyormuş. Böyle olunca da program bir sonraki adımda nereye gideceği bilgilerini de bozmuş oluyor. Evet, sorunu bulmuştum ama çözüm neydi? Forumlara bakılırsa Microsoft yakında bir yama yayımlamayı düşünmüyordu ama biz programı müşteriye söz vermiştik.

Sonuçta çaresizliğimizin doruğunda visual studio’nun küçük boyutlarda yaptığı bir şeyi yapmaya karar verdim. Veri tabanı nesnesinin sağına ve soluna dev gibi yasak bölgeler inşa ettim. Yanlış hatırlamıyorsam 10 kB büyüklüğünde boş alan koydum. Bir nevi hendek yöntemi. Bu şekilde diğer nesneleri veri tabanı nesnesindeki hatalardan korumayı başardım. Şansımıza veri tabanı nesnesi sınırları içinde bir sorun çıkmamıştı. Aylar sonra gelen Microsoft yaması ile bu utanç verici çözümü de kaldırdık ama bence bu utancın büyük kısmı Microsoft’a aittir. Bütün bu hatayı arama ve düzeltme süreci neredeyse iki hafta sürdü. Aslında bu iki haftada hatanın adını aramış olduk, adı konulunca kendimizi sanki herkesin aynı sorundan muzdarip olduğu bir ortamda bulduk.