Geçenlerde bir Abap kitabı aldım. Güya Abap ögreneceğim! Abap SAP tarafından geliştirilmiş bir programlama dili ve SAP’nın ERP sistemlerini programlamak için kullanılıyor. Okumaya devam et
JVM Nasıl Çalışır Yazı Serisi – Çöplerin Efendisi
Java programcısının çok sadık bir hizmetçisi var. Her türlü çöplüğü, pisliği arkasından devamlı toplar, hiç sesini çıkarmaz. Çöplerin efendisidir, ama bir o kadar da mütevazidir. Kimseye belli etmeden işini görür. Bu yüzden birçok Java programcısı onun farkında bile değildir. Ama o işini yapmasa Java programcısının hali çok vahim olur, C/C++ ile kod yazan meslektaşlarından bir farkı kalmaz, bilgisayarın hafızası denilen kara delikte kaybolur gider, yazdığı programlar devamlı sallanır.
Garbage Collector’dan bahsediyorum. Çoğu Java programcısının varlığından bile haberdar olmadığı, bazılarının çekindiği, bazılarının ne yaptığını tam olarak anlamdığı, bazılarının ise yaptığı işe hayran olup, ince ince hayranlık duyduğu Garbage Collector… Java’yı Java yapan özelliklerinden bir tanesi bir Garbage Collector’e sahip olmasıdır. Şimdi yakından tanıyalım bu kahramanı.
Java dilinde herhangi bir sınıftan bir nesne oluşturmak için new operatörü, Class.forName().newInstance(), clone() veya readObject() metodu kullanılır. Örneğin new operatörü sınıfın konstrüktörünü kullanarak JVM bünyesinde yeni bir nesne oluşturur. Nesne inşa edildikten sonra Java Heap içinde konuşlandırılır. Nesnelerin hepsi kullanıldıkları sürece heap icinde mutlu, mesut hayatlarını sürdürürler. Ama her canlı gibi onlar da birgün ölürler. Öldüklerinde onları toplayıp, ebediyete intikal ettiren Garbage Collector’dür.
İngilizce’de garbage çöp anlamına gelmektedir. Garbage Collector JVM bünyesinde hem yeni nesnelerin doğmasına yardımcı olan, hem de ölen nesneleri ortadan kaldıran modüldür. new operatörü ile doğan yeni nesneler için Garbage Collector hafıza alanını temin eder. Ölen ve çöp olarak isimlendirilen nesnelerin işgal ettikleri hafıza alanını Garbage Collector boşaltır ve yeni nesnelere tayin eder. Garbage Collector kısaca Java’da otomatik hafıza yönetiminden sorumludur. Onsuz Java’nın C/C++ dilinden bir farkı kalmazdı.
Garbage Collector’ün nasıl çalıştığını görebilmek için aşağıda yer alan videoyu hazırladım. Collector’ü kızdırmak için bolca çöp (garbage) üreten minik bir Java programını şu şekilde oluşturmak yeterli:
[source language=’java’]
package com.kurumsaljava.jvm.garbage;
import java.util.ArrayList;
import java.util.List;
public class Heap {
public static void main(String[] args) throws Exception {
List
Thread.sleep(10000);
while (true) {
temp.add(“xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx”);
//System.out.println(temp.size());
if(temp.size() > 3000000) {
temp = null;
temp = new ArrayList
}
}
}
}
[/source]
Heap ismini taşıyan sınıf bünyesinde x’lerden oluşan uzunca bir String nesnesini sonsuz bir döngü içinde temp ismindeki bir listeye yerleştiriyoruz. Liste bünyesinde yer alan String nesne adedi 300.000’e ulaştığında listeye null değerini atayarak siliyor ve yeniden bir liste oluşturuyoruz. Döngü içinde tekrar String nesneleri yeni listeye ekleniyor. Buradaki amacım hafızanın tükenmesi ile java.lang.OutOfMemoryError oluşmasını engellemek ve Garbage Collector’ün değişik heap alanları üzerinde nasıl çalıştığını gösterebilmekti. Java’da herhangi bir nesneye null degeri atandığında Garbage Collector’e “bu nesne ölmüştür, yok edilebilir” mesajı verilmektedir. Eğer bu nesneye herhangi başka bir nesneden referans yoksa, Garbage Collector bu nesneyi öldü kabul edip, temizleyecektir. Şimdi beraber videoyu izleyelim.
Videoda yer alan program için 64 MB büyüklüğünde bir heap alanını -Xms64m -Xmx64m JVM parametreleri kullanarak tahsis ettim. Eğer heap alanı 10 MB olursa OutOfMemoryError hatası oluşmaktadır. Aynı şekilde liste içindeki String nesne adedini 600.000’e çıkardığımda hafıza yetersizliğinden dolayı OutOfMemoryError hatası oluşmaktadır.
Video ve oluşan Garbage Collection aktiviteleri hakkında detaya girmeden önce, değişik Garbage Collector mekanizmalarını ve algoritmalarını gözden geçirelim.
Generational Garbage Collection
Tipik bir Java uygulaması gözlemlendiğinde, uygulamanın hayatı süresince oluşan birçok nesnenin kısa ömürlü oldukları görülmektedir. Oluşturulan nesnelerin çogu bir metot son bulduktan sonra, sadece metot bünyesinde kullanıldıkları için hayata gözlerini yumarlar. Bunun yanısra bir Java uygulaması bünyesinde nesneler yaşlanarak belli bir yaşa erişebilirler. Bir nesnenin yaşlanma süreci uygulama bünyesinde kullanılma derecesini yansıtmaktadır.
Java uygulamarında oluşturulan nesnelerin hayat döngülerini yönetmek icin Sun firması tarafından JDK 1.3 versiyonu ile Generational Garbage Collection geliştirilmiştir. Resim 1’de görüldüğü gibi Generation Garbage Collection ile Java uygulamasının kullandığı hazıfa iki jenerasyona bölünmektedir. Yeni doğan nesneler genç jenerasyon (young generation), orta ve ileri yaşlı nesneler yaşlı jenerasyon (old generation) bölümünde konuşlandırılırlar.
Nesnelerin ait oldukları yaş gurubuna gore ihtiyaç duyulan hafıza yönetim mekanizmaları farklılık gösterir. Yeni jenerasyon bünyesinde nesne doğum ve ölümleri çok hızlı gerçekleşir. Bu bölümde kullanılan Garbage Collection algoritmasının yeni doğan nesnelere hızlı bir şekilde hazıfa alanı tahsis etmesi, ölen nesneleri ortadan kaldırması gerekmektedir. Bu jenerasyon için kullanılan Garbage Collection algoritması bu ihtiyaca cevap verecek şekilde geliştirilmiştir. Yaşlı jenerasyonda durum farklıdır. Bu bölümde Formel 1’de olduğu gibi hızlı haraket etme gerekliliği yoktur. Bu jenerasyonda nesneler daha yavaş bir hayat temposuna sahiptir. Bu jenerasyonda kullanılan Garbage Collection algoritması buna uygun şekilde geliştirilmistir.
Young Generation Garbage Collection
Young generation üç hafıza alanından oluşmaktadır. Bunlar Eden, Survivor 1 ve Survivor 2 hafıza alanlarıdır. Bir Java uygulamasında nesnelerin hepsi gözlerini Eden hafıza alanında dünyaya açarlar. Survivor 1 ve Survivor 2 alanları geçici ara hafıza alanı olarak kullanılır. Eden hafıza alanı dolduğunda, Garbage Collector hayatta kalan nesneleri önce boş olan Survivor alanlarından birisine kopyalar. Bu işlemin ardından Garbage Collector Eden ve kullanımda olan Survivor alanını boşaltır. Eden hafıza alanı tekrar dolduğunda, hayatta kalan nesneler ve dolu olan Survivor alanındaki nesnelerin hepsi tekrar boş olan Survivor alanına kopyalanır. Her zaman bir Survivor alanı boştur ve bir sonraki Garbage Collection işlemi sonunda hayatta kalan nesneleri bünyesine alacak şekilde pasif olarak bekler. Videoda da Eden ve Survivor hafıza alanlarının Garbage Collector tarafından doldurulma ve boşaltılma işlemleri görülmektedir. Young generation bünyesinde çalışan Garbage Collection mark & copy (işaretle ve kopyala) algoritmasını kullanmaktadır. Şimdi bu algoritmanın nasıl çalıştığını yakından inceleyelim.
Mark & Copy Algoritması
JVM bünyesinde kullanılan tüm Garbage Collection mekanizmaları hayattaki nesneleri işaretleme (mark) işlemi ile işe başlarlar. Garbage Collector hangi nesnelerin hayatta olduğunu anlamak için kök setini (root set) oluşturan nesnelerden yola çıkıp, diğer nesnelere olan bağlantıları takip eder. Bu işlemi bir ağacın kökünden yola çıkarak, dallarına kadar erişme olarak düşünebiliriz. Garbage Collector bu şekilde hayatta olan tüm nesneleri işaretler. Erişemediği diğer nesnelerin hepsini ölü kabul eder ve bir sonraki Garbage Collection ile ortadan kaldırılmalarını sağlar. Kök setinde kendisine doğru nesne referansı olmayan, ama kendisinden başka nesnelere referans giden nesneler yer alır. Bu tip nesneler genelde metot parametreleridir ya da global geçerliliği olan statik olarak tanımlanmış nesnelerdir.
Resim 2’de kök setin A ve E nesneslerinden oluştuğu görülmektedir. Garbage Collector işaretleme işine önce A nesnesinden yola çıkarak başlar. B, C ve dolaylı olarak D nesnelerine erişir ve bu nesne kümesini (A,B,C,D) hayatta olan nesneler olarak işaretler. İşaretleme işine E nesnesi ile devam eder. E nesnesi kök setinde yer alan bir nesnedir, lakin E’den yola çıkarak başka bir nesneye erişmek mümkün değildir. Ayrıca başka bir nesne de E nesnesine işaret etmemektedir. Bu yüzden E nesnesi artık ölmüş bir nesnedir ve bir sonraki Garbage Collection ile E nesnesinin işgal ettiği hafıza alanı temizlenir.
Garbage Collector işaretleme (mark) işlemini tamamladıktan sonra hayatta kalan nesneleri aktif olan Survivor alanına kopyalama işlemine başlar. Garbage Collector resim 2’de görüldüğü gibi hayatta kalan nesne kümesini (ABCD) aktif olan Survivor 1 alanına kopyalar. Nesneler, işgal ettikleri adres alanları arka arkaya gelecek şekilde Survivor 1’de konuşlandırılır. Garbage Collection işlemi sonunda hayatta kalan nesnelerin birbirlerine olan referansları ve sahip oldukları adres alanları değişeceği için Garbage Collector işaretleme ve kopyalama işlemi öncesinde uygulama bünyesinde çalışan tüm threadleri durdurmak zorundadır. Bu işlem JVM terminolojisinde dünyayı durdurma (stop the world) olarak adlandırılır. Belli bir süre boyunca uygulama durur ve uygulama bünyesinde aktif olan sadece Garbage Collector’dür. Eğer Garbage Collector işine başlamadan önce dünyayı durdurmamış olsa, aktif olan uygulama threadleri nesne referansları üzerinde değişiklik yaparak, Garbage Collector’ün yanlış nesneler üzerinde işlem yapmasına sebep olabilirler. Bu sebepten dolayı Garbage Collection öncesi dünyanın durması gerekmektedir.
Resim 3’de Garbage Collection sonrasınra Eden bünyesinde yeni nesnelerin oluştuğu görülmektedir. Kök set içinde X ve W nesnesi yer almaktadır. Garbage Collector X,Y,Z ve Survivor 1’de yer alan ABCD nesnelerini Survivor 2’ye kopyalar. Garbage Collection işlemi sonunda young generation hafıza alanındaki son durum resim 4’de yer almaktadır.
Görüldüğü gibi her Garbage Collection sonunda Survivor alanları rolleri değiştirmektedir. Survivor alanlarının her Garbage Collection sonrası yer degiştirmeleri resim 5’de de görülmektedir.
Resim 5’de yer alan birinci kolon Survivor 1’in, ikinci kolon Survivor 2’nin, üçüncü kolon Eden’in, dördüncü kolon Old hafıza alanının doluluk oranını göstermektedir. Görüldüğü gibi Garbage Collector düzenli olarak hayatta kalan nesneleri kopyalamak için pasif olan Survivor alanını kullanmaktadır.
Bir Java uygulaması -XX:+PrintHeapAtGC JVM parametresi ile çalıştırıldığv zaman, resim 6’da yer alan Garbage Collection log kayıtları oluşmaktadır. İlk kırmızı işaretli alan içinde Survivor 1 from, Survivor 2 ise to olarak isimlendirilmiştir. Survivor 1’in hafıza başlangıç adresi 0x30e40000, Survivor 2’nin hafıza başlangıç adresi 0x30c20000’dir. İkinci kırmızı işaretli alana baktığımızda from ve to’nun adres alanlarının değiştiğini görmekteyiz. Garbage Collection işlemi oluşmuş ve Survivor alanları yer degiştirmiştir. Garbage Collector tarafından hep bir Survivor alanı reserve durumunda bir sonraki Garbage Collection içinde kullanılmak üzere beklemede tutulur. Bu dogal olarak belirli bir hafıza alanının kullanılmayarak israf edildiği anlamına gelir. Ne yazık ki bu Mark & Copy algoritmasının bir dejavantajıdır. Bunun haricinde bu algoritma hızlı bir şekilde Eden bünyesinde olup bitenlere cevap verebilecek yetenekte ve kapasitededir.
Minor & Major Garbage Collection
Garbage Collection minor (küçük) ve major (büyük) olmak üzere ikiye ayrılır. Minor Garbage Collection’ı kendi odamızı, Major Garbage Collection’ı evimizi temizleme gibi düşünebiliriz. Young Generation bünyesinde yapılan Garbage Collection işlemine minor Garbage Collection, JVM kontrolündeki tüm hafıza alanlarının temizlenme işlemine major Garbage Collection ismi verilir.
Resim 7’de Garbage Collector tarafından yapılan minor ve major Garbage Collection işlemleri yer almaktadır. GC ile başlayan satırlar minor, Full GC ile başlayan satırlar major Garbage Collection yapıldığınin ibaresidir. Major Garbage Collection işlemi için ayrıca Full Garbage Collection ismi de kullanılmaktadır.
İlk satırda young generation tarafından işgal edilen hafıza alanı toplamda 11994 kilobytetır (~ 12 MB). Minor Garbage Collection işlemi sonunda ölen nesneler temizlenmiş ve hayatta kalan nesnelerin kapladığı alan 4048 (~ 4 MB) kilobyte olarak değişmiştir. Garbage Collector minor Garbage Collection işlemi ile 8 MB civarında ölü nesneyi hafıza alanından kaldırmıştır. Bu minor Garbage Collection işlemi 0.02 saniye sürmüştür. Bu zaman diliminde JVM bünyesinde sadece Garbage Collection işlemi yapılmıştır. Parantez içinde yer alan 63360K (~ 64 MB) JVM tarafından kullanılan tüm hafıza alanlarının toplamını yansıtmaktadır. JVM parametreleri olarak -Xms64m -Xmx64m kullandığımız için, programın işgal ettiği toplam hafıza alanı 64 MB’dir.
Eden hafıza alanı, Old hafıza alanına göre daha küçük olduğu için bu alanda minor Garbage Collection işlemleri Old generation bünyesinde olan major Garbage Collection işlemlerinden sayıca çok daha fazladır. Resim 7’de Garbage Collector 20 minor Garbage Collection, buna karşılık sadece 4 major Garbage Collection gerçekleştirmiştir.
Yedinci satırda major Garbage Collection yapıldığını görmekteyiz. Tüm JVM bünyesinde 56241 kilobyte (~56 MB) hafıza alanı kullanımdadır (young + s0 + s1 + old). Görüldüğü gibi bu değer JVM hafıza büyüklüğü olan 64 MB’ye yakın bir değerdir. Resim 8’de young ve old generation hafıza alanlarının dağılım oranları yer almaktadır. JVM Eden için 17 MB, S0 için 2 MB, S1 için 2 MB ve Old icin 42 MB alan ayırmıştır. JVM parametreleri ile hafıza alanlarının büyüklüklerini değiştirmek mümkündür. Buna yönelik bir ayarlama yapılmadığında JVM otomatik olarak hafıza alanlarının büyüklüğünü ayarlar. Full GC ardından hayatta kalan nesnelerin kapladığı alan 6011 kilobyte (~6MB) olarak değişmiştir. Bu major garbage collection işlemi ile 50 MB büyüklüğünde nesneler Garbage Collector tarafından ebediyete uğurlanmıştır.
Durdurun Dünyayı
“Durdurun dünyayı başım dönüyor” diyor Ferdi Tayfur şarkısında. JVM mucitleri Ferdi Tayfur’un bu şarkısından esinlenerek dünyayı durduran Garbage Collector algoritmaları geliştirmişlerdir. Arabesk müziğin Java üzerindeki etkilerini başka bir yazımda detaylı olarak ele alacağım. Arabeskin programcılık üzerinde etkileri düşünüldüğünden çok daha fazladır. (:)
Garbage Collector minor Garbage Collection için tek bir thread (Reaper Thread) kullanmaktadır. Garbage Collection işlemi esnasında Garbage Collector JVM bünyesinde çalışan tüm threadleri durdurur. Uygulama için dünya durmuş olur. Dünya ne kadar uzun durursa, uygulamanın kullanıcıya verdiği cevaplar o oranda gecikir. Buradan Garbage Collection işlemi esnasında verilen araların mümkün olduğunca kısa olması gerektiği sonucu çıkmaktadır. JVM mucitleri bunu göz önünde bulundurarak paralel çalışan minor Garbage Collection algoritması geliştirmişlerdir.
Paralel çalışan minor Garbage Collection algoritması, tekil threadle işini gören minor Garbage Collection ile teoride aynı yapıdadır. Aralarındaki tek fark, parelel minor Garbage Collection için birden fazla threadin çalışmasıdır. Bu şekilde stop the world duraklamaları daha kısaltılmış olur. Bu uygulamanın kullanıcıya karşı cevapkanlık oranını artırmaktadır.
Paralel minor Garbage Collection nasıl çalışmaktadır? Garbage Collector’ün temizleme işlemine hayatta kalan nesneleri işaretleyerek (mark) başladığını yazmıştım. Garbage Collector bu amaçla kök setinde yer alan nesneleri tarar ve bu nesnelerden yola çıkarak işaretleme işlemini yapar. Akabinde hayatta kalan tüm nesneleri aktif olan Survivor alanına kopyalar (copy). Paralel Minor Garbage Collection için kök setinde yer alan nesneler birden fazla Garbage Collection threadine atanır. Birden fazla thread paralel olarak kök setindeki bir nesneden yola çıkarak hayatta kalan nesneleri tararlar. Bu şekilde işaretleme performansı artırılır ve işaretleme için harcanan zaman azalır.
Hayatta kalan nesnelerin aktif olan Survivor alanına da kopyalanma işlemi buna benzer bir şekilde gerçekleşir. Her threade Survivor hafıza alanında PLAB (PLAB – Parallel Local Alocation Buffer) ismi verilen bir alan atanır. Garbage Collection threadleri birbirlerinden bağımsız olarak keşfettikleri ve hayatta kalmış olan nesneleri kendi PLAB alanlarına kopyalarlar.
Paralel Garbage Collection paralel çalışan threadlere rağmen dünyayı durduran bir algoritmadır. Tekil threadle çalışan Garbage Collection algoritmasına göre daha hızlı çalışır ve uygulamanın durma zamanlarını kısaltır. Birden fazla işlemcisi (CPU – Central Processing Unit) olan bir sunucu üzerinde paralel Garbage Collection algoritmasını kullanmak bu kazancı getirir. Lakin sadece bir işlemcisi olan sunucularda paralel Garbage Collection’ın kullanılması tam tersi bir etki yaratır.
Yazımın ikinci bölümünde major Garbage Collection’ın nasıl çalıştığını inceleyeceğim.
EOF (End Of Fun)
Özcan Acar
Mantığın Köleleri
Programcılık Sanat mı, Zanaat mı? başlıklı yazıma gelen yorumlar, programcılığın sanat olduğu yönünde. Bunun aksini düşünenler de var. Programcılığın bir sanat olarak algılanması subjektif ve bir yanılgıdır. Programcılığın bir sanat olmadığının altını bu yazımla tekrar çizmek istedim.
Sanat ve sanat eserleri görecelidir. İnsanlik var olduğundan beri sanat vardır, ama hala bu konudaki tartışmalar son bulmamıştır. „Renkler ve zenkler tartışılmaz“ sözünü sıkça işitmişizdir. Bu her bireyin sanat algılayış tarzının değişikliğine işaret etmektedir. Benim beğendiğim bir resmi, başka bir insan beğenmeyebilir. Bu yüzden sanatı tanımlamak ve bu işin içinden çıkmak çok karmaşık bir şeydir. Programcılığın da bir sanat olarak algılanıp, savunulması bu açıdan baktığımızda anlaşılabilir bir durumdur.
Bir sanat ya da sanat eseri ruha, göze ve gönüle hitap eder. Sanatın doğasında soyutluk vardır ve insanın kendisine özgün yorumuna ihtiyaç duyar. Bu yüzden herkesin sanatı algılayış tarzı değişiktir. Herkes sanatı kendi tarzında yorumlar. Eğer yazılan bir program parçası bir sanat eseri olmuş olsaydı, o zaman bu programa bakan herkes başka bir şey algılayacaktı ya da ondan kendi yorumladığı bir davranış biçimi bekleyecekti. Böyle bir şeyin yazılımda ne anlama geldiğini düşünebiliyor musunuz? Programcılık deterministik sonuçlar üretmek, mantık çerçevesinde kalıp, çözüm sunmak zorundadır. Ruha, gönüle değil, mantığa hitap eder. Sadece bu özelliğinden dolayı bile bir sanat olma şansı yoktur. Kim bir programa bakarsa baksın, aynı davranış biçimini görür, görmek zorundadır. Bir program her zaman aynı sonucu üretmek zorundadır, kod nasıl yazılmış olursa olsun. İnsanların yorumuna ihtiyacı yoktur, çünkü herkes aynı şeyi görür, daha dogrusu görmek zorundadır.
Programlar ihtiyaçtan doğarlar. Aynı şeyi sanat eserleri için söylemek mümkün değildir. Sanatkar bir şeylerden esinlenerek sanatını icra eder, zorda kalmadan, birilerine sanatını nasıl icra etmesi gerektiğini danışmadan. Programlar müşterileri tarafından kendi gereksinimlerini tatmin etmek için sipariş edilir. Müşterinin gereksinimleri programı yoğururken ön plandadır. Programı oluşturulurken müşteri ile iletişim esastır. Onun istediği olur.
Bunu yanısıra programcının kod yazarken soyutluğu ifade etmek için çok fazla seçenegi yoktur. Java dilinde interface ya da abstract sınıfları kullanarak soyut bir şeyler ifade edebilebilir. Bu ressamın paletinde sadece bir, iki renk olduğu anlamına gelir. Sadece iki rengi kullanarak sanat eseri oluşturmak mümkün müdür? Belki! Bir ressamın paletinde onlarca renk vardır, bunları karıştırarak sonsuz sayıda yeni renk elde edebilir. Bu renklerin hepsini kullanma potansiyeline sahiptir ve bu sanatına yansır. Günümüzün programlama dillerinde böyle bir zenginlik söz konusu değildir. Kaldı ki en tabana indiğimizde bir programcı sıfır ve birlerden oluşan verilerden başka bir şeyle ugraşmaz. Sadece iki renkli olan bir dünyada yaşar ve bir takım verileri A’dan B’ye taşıyacak programlar yazar. İşin hepi, topu budur.
Günümüzde nesneye yönetlik programlama paradigması popülerdir. Ne olduğuna baktığımızda programcı olarak işimizi yapabilmemiz için çok kısıtlı sayıda araç ihtiva ettiğini görmekteyiz. Gerçek dünyayı modellemek için sınıfları, bu modellere hareket kabiliyeti verebilmek icin metotları kullanırız. Koca dünyayı modellemek için sadece bu iki aracı kullanabiliyoruz. Kod yazarken yapmak istediklerimizi ifade etmek için if ya da while gibi basit komutları kullanıyoruz. Kullanabileceğimiz başka ne var ki? Bu araçlardan faydalanıp nasıl bir sanat eseri ortaya koyabiliriz? Bu bir sanat eseri olsa bile fonksiyonel işlevi haricinde nesi kimi ilgilendirir?
Görüldügü gibi programcı sahip olduğu araçlar itibari ile çok kısıtlı bir dünyada yaşamaktadır. Oysaki bir sanatçının dünyası rengarenk ve pırıl pırıldır. Sayısız derecede kombinasyon imkanları vardır. Bunlardan faydalanarak sanatını icra eder ve sanat eserleri oluşturur. Biz programcılar sıkışıp kaldığımız mantıksal dünyada bu araç gerece ve lükse sahip degiliz.
Kanımca programcılıkta kreatif olma, sanat icrası ile karıştırılmaktadır. Programcılar kreatiftir. Devamlı karşılaştıkları sorunları aşmak için çözümler üretirler. Bunun için bir zanaatkar usta gibi bir takım alet, edevata ihtiyaç duyarlar. Usta programcılar örneğin tüm tasarım prensiplerine hakımdirler. Nerede hangi tasarım şablonunu kullanmaları gerektiğini bilirler. Az ve öz kod yazmayı yeğlerler. Yazdıkları kod roman gibi okunur, kod okundukça bir hikaye gibi kendisini anlatır. Burada bir tutam estetiklik yok değildir. Ama yinede bu aktivitelerin hiçbirisi bir sanat eseri ortaya koymaz.
Programcılık mantık işidir. Biz programcılar mantığın kölesiyiz. Programcılıkta bütün gidişati mantık yönetir. Mantığın bittiği yerde programcılık biter. Bir sanatçı hiçbir şeyin kölesi değildir. Aradaki fark budur. Mantıkla sanatı kavramaya çalışmak beyhude bir iştir.
EOF (End Of Fun)
Özcan Acar
Java Heap Nedir?
Herhangi bir Java sınıfından new operatörü ile bir nesne oluşturulduğunda, bu nesnenin bilgisayarın hafızasında konuşlandırıldığı alana Java Heap adı verilir.

Java Heap JVM tarafından oluşturulur ve aşağıdaki hafıza alanlarından oluşur:
- Eden – new operatörü ile oluşturulan tüm nesneler önce bu hafıza alanında oluşturulur.
- Survivor – nesneler old heap hafıza alanına transfer edilmeden önce bir müddet survivor hafıza alanlarında kalır. Buradaki amaç kısa ömürlü olan nesnelerin Garbage Collector tarafından toplanmasına ve old heap alanına geçmelerini engellemektir.
- Old – uzun ömürlü nesnelerin ölene kadar kaldıkları hazıfa alanıdır.
- Permanent – sınıfların ve statik değerlerin yer aldığı hazıfa alanıdir.
Yukarda yer alan resime baktığımızda JVM tarafından yönetilen hafıza alanının (Java Heap) toplamda 5 GB olduğunu, bunun 1 GB’lik gibi bir kısmının EDEN Heap space, 150 MB’sinin iki SURVIVOR Heap Space ve 4 GB’sinin OLD Heap space tarafından kullanıldığını görmekteyiz. Toplamda JVM’in yönettiği ve içinde Java nesneleri oluşturabileceğimiz alan 5 GB büyüklüktedir.
JVM (Java Virtual Machine) Nedir?
JVM (Java Virtual Machine – Java Sanal İşlemcisi) C++ dilinde yazılmış bir programdır. Bir Java programı javac.exe ile derlendikten sonra byte code ismi verilen bir ara sürüm oluşur. Byte code, ana işlem biriminin (CPU – Cental Processing Unit) anlayacağı cinsten komutlar ihtiva etmez, yani klasik Assembler değildir. Java byte code sadece JVM bünyesinde çalışır. JVM, derlenen Java programı için ana işlemci birimi olma görevini üstlenir. Bu özelliginden dolayı Java programlarını değişik platformlar üzerinde çalıştırmak mümkündür. Her platform için bir JVM sürümü Java programlarını koşturmak için yeterli olacaktır. Bu sebepten dolayı Java “write once, run anywhere – bir kere yaz, her yerde koştur” ünvanına sahiptir.
JVM hakkında daha geniş kapsamlı bilgiyi Matrix’de Yaşayan Programcılar başlıklı yazımda bulabilirsiniz.
EOF (End Of Fun)
Özcan Acar
Matrix’de Yaşayan Programcılar
Hemen hemen her programcının Matrix filmini seyrettiğini düşünüyorum. Star Wars gibi Matrix filmi de biz yazılımcılar için bir kült. Biraz abartı da olsa fikir olarak çok enteresan, en azından bir yazılımcı için. Matrix’de kullanılan yazılım sistemi dikkat çekiyor. En çok ilgimi çeken dejavü olarak isimlendirilen yazılım hataları (bug) ve Neo’nun bir tren istasyonunda hapis kalması ve trene binmesine rağmen tekrar tekrar aynı istasyona geri dönmesi, yani bir nevi for döngüsü olmuştur. Bir for döngüsünün bu kadar güzel görselleştirilmesi beni çok etkilemişti. Böyle bir sistemin entegrasyon testleri nasıl yapılıyor acaba? Okumaya devam et
Meğer Neymişiz!
Bu sabah yanımda kocaman, Coca Cola pet sişeleri taşıyan TIR vari bir araç durup, yol soruyor. Sürücünün neden navigasyon aleti yok diye düşünürken, bu yazıyı yazma fikri oluşuyor kafamda.
Şimdi birkaç saniyeliğine bir dünya hayal edelim; İçinde IPhone ve Android akıllı telefonların olduğu, ama app denen birşeyin bilinmediği, bilgisayarların olduğu, ama işletim sistemi diye birşeyin icat edilmediği, internetin olduğu, ama iletişim kurmak için e-posta ve web sunucularının olmadığı bir dünya… Bu dünyada eksik olan nedir? Evet, yazılım yapılmıyor bu dünyada. Yazılım sistemlerini kim yapıyor? Evet, biz programcılar. Yani? Bu dünyayı daha yaşanır hale getiren, oluşturdukları yazılım sistemleri ile devrim yaratan, insanlığa yön veren, insanlık tarihinde dünyanın ilk kez kocaman bir köy olmasını sağlayan ve insanlığa hizmet eden biz programcılarız. Ameliyat eden robotlardan tutun, uzaya gönderilen uydulardan, havada uçan uçakların kontrol sistemlerine hadar her yerde, içinde program çalışan birşeyler görmek mümkündür. Yazılım sistemleri modern insanın sürdürdüğü yaşam tarzının vazgeçilmez bir parçası haline gelmiştir.
Hacker’ları bunun dışında tutmak şartıyla oluşturduğumuz birçok yazılım sistemi doğrudan insanlığa hizmet etmektedir. Bunun en güzel örneğini açık kaynaklı yazılım sistemleri oluşturmaktadır. Onların başında da Linux işletim sistemi gelmektedir. Toplum yazılım sistemlerinin insanlık için önemini anlamış olmalı ki, yazılımcılara nişanlar verilmektedir. Bunun bir örneğini geçtigimiz ay Linux işletim sisteminin mucidi Linus Torwald’e verilen Millennium Technology Prize 2012 nişanı teskil etmektedir.
Ödülü veren akademi tarafından yapılan açıklamada Linus’un açık kaynaklı bir yazılım sistemi geliştirmesinin dağıtık yazılım sistemleri oluşturmaya ve internetin özgür olmasına katkıda bulunduğu belirtilmektedir. Linux işletim sistemi milyonlarca, belki de milyarlarca insan tarafından kullanılma potansiyeline sahiptir. Linus yaptığı açıklamada, yazılım sistemlerinin modern dünyada çok önemli olduklarını ve insanlığa hizmet edebillmeleri için mutlaka açık kaynaklı olmaları gerektiğinin altını çizmiştir.
Durum böyle iken biz programcıların üstlendiği toplumsal sorumluluk artmaktadır. Hatasız yazılım sistemleri oluşturmamız gerekmektedir. Birçok insan günlük hayatında kullandıkları yazılım sistemlerinin hatasız çalışmasına güvenmek zorundadır. Yazılım hatalarının meydana gelmesi onların hata yapmasına sebep verebilmektedir. Baştan savma yazılım sistemleri oluşturarak onların güvenini yitirmeyelim.
Bu arada TIR sürücüsüne “navigasyon aygıtınız yok mu” sorusunu sormadan edemedim. “Var, ama çalışmıyor” dedi. Bir yazılım hatasıymış sanırım ;-) Yazılımda daha iyi olmamız lazım. İnsanlar bize güveniyor.
EOF (End Of Fun)
Özcan Acar
Programcıyım, Yönetici Değil!
Türkiye’de genç programcı adaylarının kariyer planlaması şu şekilde:
Üniversite »» Birkaç yıl programcılık »» Proje yöneticiliği »» Bölüm yöneticiliği »» Bölüm müdürlüğü
Benim kariyer planlamam şöyle:
Üniversite »» Ömür boyu programcılık
Ben programcıyım, yönetici değilim! Üniversitede eğitimini almadığım birşey nasıl olabilirim? Neden programcıların çoğu bir yerlere yönetici ya da müdür olmak istiyor? Bunun açıklaması kolay: daha fazla maaş alacaklarını düşündükleri ya da pozisyon itibariyle daha fazla dikkate alınmak istedikleri için.
Herşeyin statü sembolleri ile ölçüldüğü bir toplumda programcıların daha fazla para kazanmak için yönetici olma sevdalarını ayıplamıyorum. Bu sadece programcılar için geçerli bir durum değil. Benim ayıpladığım programcının bu uğurda ruhunu satmasıdır. Eğer bir insan programcı oldu ise, bu işe gönül verdiği için olmuştur. Mecburiyetten olan programcı zaten programcı sayılmaz. Eğer yaptığı işi sevmiyorsa, bırakıp başka bir iş yapması mübahtır. Aldığı para kendisini tatmin etmiyorsa, benim kişisel olarak yapabileceğim birşey yok (ama daha fazla nasıl kazanabileceğine daha sonra değineceğim). Ama bu işin birde manevi tarafı yok mu? Haz alarak yaptığı bir iş insanı mutlu etmez mi? Neden daha fazla maaş, insanı mutlu eden bir işe tercih edilir ki? Bunu anlamam çok zor.
Yöneticilik ya da müdürlük öyle her babayiğidin harcı değildir. Yönetici olmak isteyen programcılar bunu bilmiyor galiba. Bu işin bir defa eğitimini almak gerekir. Yönetim kademesindeki insanların liderlik, çalışanlara örnek olma, onları motive etme, güçlü iletişim gibi vasıflara ihtiyacı vardır. Çok ağır şartlarda çalışıp, neticesi geniş kapsamlı kararlar vermek zorunda kalırlar. Üstlerinde büyük sorumluluk taşırlar. Daha fazla maaşı hak ederler, ama bedelini de öderler.
Saydığım bu sebeplerden dolayı yöneticiliğe talip değilim. Ben bu işten anlamam. Ben bildiğim işi yapmayı yeğlerim. Programcıyken, yöneticiliğe soyunanlara da kazaları mübarek olsun derim.
Programcılar Yönetici Olmaya Zorlanıyor
Ömür boyu programcı olarak çalışmak isteyenler de yok değil. Nedendir bilmiyorum ama Türkiye’de „insan kırk yaşından sonra programcı olarak çalışmaz“ kanısı oluşmuş. Yaşlı programcılara kötü gözle bakıldığı bir toplum içinde yaşıyoruz. Hala bir baltaya sap olamamış ve programcılık yapıyor denilebiliyor. Aman allahım, inanılacak gibi değil!
Bu şartlar altında programcıların üzerinde yönetici olma doğrultusunda baskı oluşmuyor değil. Lakin bu baskıya karşı koyup, programcının programcı olarak yoluna devam etmesi şarttır. Programcının gönlünde yatan aslan bellidir. Programcılar kendi kariyer planlamalarını kendileri yapmalı, başkalarının buna müdahele etmesine karşı koymalıdırlar. Müdahele olduğunda buna baş kaldırıp, dik durmalı ve statükolarını korumalıdırlar. Yoksa sonuç bellidir: yaptığı işten memnun olmayan bir sürü eski programcı yönetici.
Bunun yanısıra birde firmalardaki kariyer yapma imkanlarına göz attığımızda, çoğu programcıya yönetici olmaktan başka seçenek kalmadığını görmekteyiz. Avrupa ve Amerika’da durum çok farklıdır. Büyük yazılım firmalarına baktığımızda, ömür boyu mühendis kalınabildiği, bu konuda uzmanlaşma imkanı veren kariyer patikalarının olduğunu görmekteyiz. Bunun bir örneğini IBM’in çalışanlarına sunduğu Distinguished Engineer olma imkanı teşkil etmektedir.
Programcılar Mutlu Değil
Programcılar ne yazık ki yaptıkları işten memnun ve mutlu değiller. Devamlı günü kurtarmaya çalışmak, verilen emeğe ilgi ve saygının olmaması, fazla mesai yapmaya zorlamalar programcının içindeki şevki kırabilir. Ama bir programcı yöneticiliğe upgrade yaptığında durum farklı mı olacaktır? Pek zannetmiyorum. Öyleyse gönül verdiğimiz işi yapacak şekilde ortam hazırlamaya bakalım.
Programcılar İşsiz Kalmaz
Programcılar şarap gibidir. Kendilerini geliştirmeleri, ustalaşmaları şartıyla yaşlandıkça kıymetlenirler. Yetkin bir programcının piyasada işsiz kalması imkansızdır. Herhangi bir işi yapan bir yöneticinin işsiz kalma ya da işten çıkarılma rizikosu yetkin bir programcıdan çok daha yüksektir. Yetkin bir programcıyı kolay kolay kimse işten çıkartamaz. Geliştirdiği uygulama hakkında o kadar çok bilgiye sahiptir ki yeri kolay kolay doldurulamaz. Yetkin programcılar piyasada freelancer olarak çalışıp, maaşlarının birkaç katı fazlasını kazanabilirler.
Bu kadar uzman progragramcının arandığı bir piyasada kim ne yapsın yöneticiliği. Programcılık güzel ve geleceği olan bir meslektir. Kıymetini bilelim.
EOF (End Of Fun)
Özcan Acar
Programcılık Sanat mı, Zanaat mı?
Çoğu zaman aklımda olan bir soru var: „Programcılık bir sanat mıdır yoksa bir zanaat mıdır? Biz programcılar sanatkar mıyız yoksa zanaatkar mıyız?
Vikipedi’ye baktığımızda sanat ve zanaat için aşağıdaki tanımlamayı yapmakta:
Sanat en genel anlamıyla, yaratıcılığın ve hayalgücünün ifadesi olarak anlaşılır. Tarih boyunca neyin sanat olarak adlandırılacağına dair fikirler sürekli değişmiş, bu geniş anlama zaman içinde değişik kısıtlamalar getirilip yeni tanımlar yaratılmıştır. Bugün sanat terimi birçok kişi tarafından çok basit ve net gözüken bir kavram gibi kullanılabildiği gibi akademik çevrelerde sanatın ne şekilde tanımlanabileceği, hatta tanımlanabilir olup olmadığı bile hararetli bir tartışma konusudur. Açık olan nokta ise sanatın insanlığın evrensel bir değeri olduğu, kısıtlı veya değişik şekillerde bile olsa her kültürde görüldüğüdür. Sanat sözcüğü genelde görsel sanatlar anlamında kullanılır.
Zanaat , sermayeden çok nitelikli emeğe dayalı; öğrenimin yanısıra el becerisi ve ustalık gerektiren meslek. Zanaatkâr, zanaatle uğraşan kişi anlamına gelir. Marangozluk, ayakkabıcılık, kuyumculuk (takı üreten), kumaş boyama, çömlekçilik, berberlik, bakırcılık gibi mesleklerin hepsi birer zanaattir. Bir kimsenin zanaatkâr olması için el becerisi gerektiren bir malı veya hizmeti sadece satması değil, bilfiil üretmesi gerekir.
Yaptığımız işte he ikisinden de birşeyler var değil mi? Okunması kolay estetik kod yazarak bir sanatkar, müşteri gereksinimlerini tatmin eden uygulamalar geliştirerek bir zanaatkar olabiliyoruz. Ama gerçek hayatta durum ne yazık ki çok farklı. Sanatkar değiliz, çünkü müşterimiz güzel kod yazıyoruz diye bize iş vermiyor. Zanaatkar değiliz, çünkü yazılımcı olarak usta-çırak geleneğinden yetişerek işimizin başına gelmiyoruz. Neden böyle düşündüğümü bu yazımda sizinle paylaşmaya çalışacağım.
Birgün yolunuz Gaziantep’e düşerse Bakırcılar Çarşısı’na mutlaka uğrayın. Orada çalışan bakır ustaları kelimenin tam anlamıyla hem sanatkardırlar hem de zanaatkar. Sanatkardırlar, çünkü estetik değerler oluştururlar. Zanaatkardırlar, çünkü usta-çırak kültürüyle yetişip, el emekleri ile bu değerleri oluştururlar.
Bir bakır ustasının elinde vücut bulan ve yirmi ile yüz Türk Lirası arasında bir fiyata sahip bir bakır kupanın sadece su içmek için edinildiğini görmedim. Ufak bir sanat eseri olan bu bakır kupayı evimizdeki vitrinleri süslemek için ediniriz. Bizim için önemli olan kupanın fonksiyonel işlevi (kupadan su içmek) değildir. Daha ziyade kupanın estetik yönü ilgimizi çeker. Bu yüzden bakır kupa bir sanat eseridir, bakır ustası da bir sanatkar.
Peki camdan üretilen su bardakları sanat eserleri midir? Bu su bardaklarını üretenler sanatkar mıdır? Şüphesiz tanesi yüzlerce Türk Lirası’nı bulan su bardakları bulmak zor değildir. Ama pahalı olmaları sanat eserleri oldukları anlamına gelmez. Camdan yapılmış bir su bardağını su içmek için alırız. Bizim için su bardağının tatmin etmesi gereken fonksiyonel bir işlevi vardır. Su bardağının bu fonksiyonel işlevi yerine getirirken bir sanat eseri olup, olmadığı bizi ilgilendirmez. Herhangi bir marketten tanesi bir Türk Lirası olan onlarca su bardağı alıp, mutfaktaki dolaba koyarız. Su içmek istediğimizde bir bardak alıp, kullanırız. Bizim için camdan üretilmiş bir su bardağının fonksiyonel işlevi ön planda oldugu için, bu su bardağı bir sanat eseri değildir. Aynı şekilde bu bardakları üretenler de bizim gözümüde sanatkar değildirler.

Buradan çıkardığım sonuç şudur: Sanat eserlerinde fonksiyonel işlev önemli değildir. Dikkat bulan, icra edilen sanattır. İcra edilen bu sanat, sanat eserleri meydana getirir. Fonksiyonel işlevin önemli olduğu yerlerde ise sanat eserleri tercih edilmez. Sanat eseri ve sanatkar olmayı belirleyen faktör budur.
Programcılık Sanat, Programcı da sanatkar değildir.
Bazı programcılar program yazma aktivitesini sanat olarak, bu işi yaptıklarından dolayı kendilerini de sanatkar olarak görmektedirler. Bu ne yazık ki doğru değildir. Program yazmak fonksiyonel bir işlevi meydana getirmek için yapılan bir aktivitedir. Camdan su bardağı örneğinde olduğu gibi, müşterimiz bizim yazdığımız programın estetik kısmıyla ilgilenmez. Onun için oluşturulan uygulamanın tatmin etmesi gereken sadece fonksiyonel bir işlevi vardır. Uygulamanın ne kadar güzel kodlandığı ile ilgilenmez. Hiç, bir müşterinin kodu açıp, okumaya çalışıp, ne kadar güzel yazılmış, ya da yazılmamış diye yorum yaptığını görmedim. Durum böyle iken, müşteriye sattığımız uygulama bir sanat eseri değildir. Bir sanat eseri oluşturup, satmadığımıza göre, programcı olarak sanatkar olmamızda mümkün değildir.
Bir programcı olarak müşterinin gereksinimlerini tatmin eden, sadece fonksiyonel işlevi olan ürünler ortaya koyarız. Müşteri oluşturduğumuz uygulamaya baktığında bir sanat eseri, bize baktığında bir sanatkar görmez. Ama aynı şahıs bir bakır ustasına baktığında bir sanat eseri ve sanatkar görür. Demek oluyor ki sanat eserine ve sanatkara bu sıfatı değer görenler başkalarıdır. Kendi kendimize sanat eseri ortaya koyduğumuzu ve sanatkar olduğumuzu iddia etmemiz birşeyi değiştirmez. Bu yüzden programcının kendisini sanatkar olarak görmesi doğru değildir, çünkü müşterisinin gözünde sanatkar değildir.
Programcılar Zanaatkar Değildir
Zanaat demek ustalık demektir; gelenek demektir; ustadan öğrenmek demektir. Siz hiç bir berber çırağının ilk işe başladığı gün saç kestiğini gördünüz mü? Çırak önce ustasına hizmet edip, ondan birşeyler öğrenmeye ve yavaş yavaş olgunlaşmaya başlayacaktır. Usta ise çırağını kendi tecrübeleri doğrultusunda ve kendi ustasından öğrendigi şekilde yönlendirecektir. Belli bir zaman diliminden sonra çırak yavaş yavaş bir zanaatkara dönüşecektir. Bunun gerçekleşmesi için ustasının kendisine gösterdigi yolu takip etmesi gerekmektedir. Bu yolu gitmek yıllar sürebilir. Ama bu yolun sonunda çırak için kendi ustası gibi bir usta, bir zanaatkar olma ödülü vardır. Ustalaşmak ve bir zanaatkar olmak hiç te kolay olmayan bir süreçtir. Ustası olmayan bir çırağın, bu yolu tek başına giderek ustalaşması çok zor olacaktır ya da mümkün olmayacaktır.
Yukarda yer alan tanımlamaya gore programcılar zanaatkar değildir, çünkü programcılar usta-çırak geleneginden gelerek yetişmezler. Programcılar için işe başlama bariyeri yok denecek kadar azdır. Bir bilgisayar ya da başka bir mühendislik ögrencisi diplomasını eline aldığı andan itibaren programcı olarak çalışmaya başlayabilir. Hiç kimse senin ustan kim ya da kaç sene çırak programcı olarak çalıştın diye soru sormaz. Programcının daha önce hangi projelerde çalıştığı sorulur. Buradaki amaç daha çok programcının ne kadar tecrübeli olduğunu anlamaya çalışmaktır. Ama yıl bazında edinilen tecrübe, şahsın ustalık oranını göstermez. On sene tecrübesi olduğunu söyleyen bir programcı, son dokuz senesini, birinci sene öğrendiği şeyleri tekrarlamakla geçirdiyse, son dokuz sene tecrübe topladığı söylenemez.
Tecrübesiz ve bir usta tarafından yetiştirilmemiş bir programacının hemen program yazmaya başlamasını, diplomasını almış bir doktorun hemen kalp ameliyatı yapmaya başlamasıyla kıyasladığımızda, durumun programcılar açısından aslında ne kadar absürd olduğunu görebiliriz. Kalp ameliyatı yapmaya aday bir doktor yıllarını usta doktorlara asistanlık yapmakla geçirir. Bu ona kalp ameliyatlarının nasıl yapıldığını ustalarından öğrenme fırsatı verir. Asistanlık dönemi bittikten sonra, asistan doktor seçtiği dalda uzmanlaşma dönemine girer. Hem asistanlık hem de uzmanlaşma döneminde doktor adayı ustalarından gerekli herşeyi öğrenerek, onlarca seneyi bulacak bir zaman diliminden sonra kalp ameliyetlarını yapabilecek kıvama gelir. Yukarda da belirttiğim gibi programcılar için bunların hiçbirisi geçerli değildir. Programcı diplomasını alır, masasının başına oturur ve hemen müşteri için program yazmaya başlar. Neden birçok projenin yapılan hatalı kalp ameliyatlarından dolayı öldüğü ortadadır, çünkü ameliyatı yapan programcılar yetkin değildir.
Usta-çırak geleneğinin olmadığı yerde bir zanaatin icrası ya da yapılan işin zanaat olarak tanımlanması çok zordur. Programcılar ustasız yetiştikleri için, zamanlarının büyük bir kısmını deneme yanılmayla boşuna sarf ederler. Yıllarca aynı şeyleri yapıp, yerlerinde saysalar bile, bunu tecrübe yapmış olarak algılarlar. Kendilerine yön gösteren bir ustaları olmadığı için kendilerini geliştirmekte ve ustalaşmakta çok zorlanırlar. Bu sebepten dolayı birçok programcı ustalık mertebesine erişemez. Oysaki bir ustanın denetiminde olsalar ustalaşmaları çok daha kolay olacaktır.
Programcılık Zanaattir
Bir önceki bölümün başlığına baktığınızda bu bölümün başlığı tezat gibi algılanabilir. Bir önceki bölümde neden zanaatkar olamadığımızı anlatmaya çalıştım. Bu bölümde ise aslında neden zanaatkar olduğumuzu anlatmak istiyorum.
Zanaati, sermayeden çok nitelikli emeğe dayalı; öğrenimin yanısıra el becerisi ve ustalık gerektiren meslek şeklinde tanımlamıştık. Bunun yanısıra bir zanaat usta-çırak geleneğini kapsamaktadır. Bu tanımlama bir programcıya tamamen uygun yapıdadır. Eksik olan programcıların ustasız yetişmeleridir. Ama bu onların zanaatkar olmadıkları anlamına gelmez. Bu eksiği kapatmak için ustalığa giden yolun tarifini yapmamız gerekmektedir. Bilge Programcı programı (http://www.bilgeprogramci.com – şu an üzerinde çalıştığım, yapım aşamasında olan projemdir) böyle bir yolun tarifesini ihtiva eder. Daha once bu yoldan geçmiş, şimdilerde usta programcılardan kendimize örnek alarak, bizde yaptığımız işte ustalaşabiliriz. Ustalaştıkca bir zanaatkar olmaya başlarız ve yaptığımız iş bir zanaat haline dönüşür. Usta programcılar zanaatkardırlar. Genç programcılara da onlara çırak olmak düşer. Eti senin, kemiği benim misali :)
Not: Bu yazının devamı olarak Mantığın Köleleri başlıklı biz yazı daha oluşturdum. Bilginize sunarım.
EOF (End Of Fun)
Özcan Acar
Ekibin Dikkati ve Saygısı Nasıl Kazanılır?
Her programcı yeni bir ekibe dahil olduğunda kendisini ispatlamak zorundadır. Bu gerçekleşene kadar ekip içindeki diğer programcılar yeni programcıyı dikkate almazlar. Birilerinin ekibe dahil olduğunu beyinlerinin en arkasında çalışan bir thread ile belki farkederler, ama bunu dikkate almadan günlük işlerine devam ederler. Okumaya devam et
Eşli Programlama, Code Review, Code Retreat ve Adada Yaşayan Programcılar
Bir programcıyı alıp bir adaya koysanız, diğer insan ve progcılarla bağlantı kurmasını engelleseniz, kendi başına çalışmasını ve kendisini geliştirmesini isteseniz, bu programcı programcılık konusunda nasıl bir gelişme sağlardı? Okumaya devam et
İnşaat ve Yazılım Mühendisleri Arasındaki Fark
İnşaat mühendisleri:
Okumaya devam et
Battı Balık Yan Gider
Batan projeleri ben batan gemilere benzetiyorum. Batmaya meğil gösteren bir gemi nasıl bunu belli ediyorsa, batmaya meğilli bir yazılım projesi de parmak kaldırıp, dikkat ben batıyorum der. Bir projenin batacağı nasıl anlaşılır? Şöyle:
- Big design up front olarak isimlendirilen, kahin vari, bugünden yarının nasıl olacağını bilme kibiri ile tüm yazılım mimarisi ve tasarımının yazılım öncesi yapılması. Kutsallaşan bu tasarımı sorgulamak ve değiştirmek imkansızdır. Yazılımın ana kurallarından birisi: değişmeyen değişikliğin kendisidir. Madem bunu biliyoruz, neden proje başlamadan herşeyi ön görmeye çalışıp, acayip acayip tasarımlar yapıyoruz? Bu mimari ya da tasarımın müşteri gereksinimlerini bir zaman sonra taşımayacağı ortada değil midir? Müşterinin neye ihtiyacı olduğunu nasıl tahmin edebiliriz? Kendisi bile bunu bilemez. Piyasa koşulları bugünden yarına öyle bir değişir ki, proje müşteri için anında tüm anlamanı yitirebilir. Projelere pragmatik bir tasarım ile başlanmalıdır. Gerekli olduğu zamanlarda bu tasarım revide edilerek, güncelleştirilir.
- Birim, entegrasyon, regresyon, fonksiyon ya da onay/kabul testlerinin olmaması. Sıfır birim test kodunun olduğu projeler bilirim. Birim testleri olmayan bir projeyi yeniden yapılandırmak (refactoring) imkansızdır. Ya bazı kafalar bunu bilmiyor ya da umursamıyorlar. Test konseptlerini bilmeyen programcılar olabilir. Bu bir ayıp değil. Hemen oturup öğrenmeliler. Ama asıl problem ayağı yere basmayan zaman tahminleri ile proje planlaması yapan proje yöneticileridir. Baktılar proje yetişmeyecek, askerlerine emir vererek, testlerin yapılmamasını sağlarlar, çünkü test yazmak zaman kaybıdır onlar için. Böyle yapmaya devam edin!
- Programcıların DRY ve KISS prensiplerine sadık olmamaları. Bu kodun bakımını, değiştirilmesini ve geliştirilmesini zora sokan bir durumdur. Bir noktadan sonra (point of no return) kod tabanı o kadar katılaşır ki, yeni müşteri gereksinimleri için yoğrulamaz hale gelir. Çöpe at, yeniden yap!
- Sürekli entegrasyon yapılmaması. Bakımın ve geliştirmenin kolay olabilmesi için yazılım sistemlerinin modüler olması gereklidir. Modüler bir yapı entegrasyon işlemlerini gerekli kılar. Altı ayda bir entegre edilen modüler bir sistemin adam akıllı entegre edilemeyeceği ortadadır, çünkü entegrasyonun doğası sorunludur. Bu sorunu aşmak için altı ayda bir değil, yazılım sistemi her gün entegre edilmelidir. Bunun için Jenkins ya da Cruise Control gibi entegrasyon serverleri kullanılabilir. Ya sürekli entegre et, ya da bu diyarı terk et!
- Projelerde maliyeti düşürmek için tecrübesiz programcıların çalıştırılması. Üniversite mezunu bir gençten bir usta kıvamında kod yazması beklenemez. Usta programcılar ağaçta yetişmiyor. Zaman içinde yeni üniversite mezunu yazılımcı gençlerde tecrübe kazanıp, ustalaşacaklardır. Lakin bir projeye çok sayıda genç yazılımcı dahil edip, projenin zamanında tamamlanmasını beklemek utopiktir. Eğer projede hiç usta programcı yoksa, iş daha da kötü olacaktır. Eğer projede usta programcılar varsa, bunlar zamanlarının büyük bir kısmını gençleri eğitmek için harcayacaklardır. Bir projede genç yazılımcı olmasın demiyorum. Ama mutlaka iş bitirici usta programcılar olmalı ve bu programcıların kendi işlerine odaklanmaları saglanmalıdır.
- Mimari kararların firma bünyesindeki merkezi bir noktada alınması. Çoğu büyük firmada kendilerini mimar grubu olarak tasvir eden bir yapıya rastlamak mümkündür. Firmada yazılım alanında olup biten herşeye burunlarını sokma alışkanlığı vardır bu grubun. Herşeyden haberdar olmak isterler, aldıkları tüm mimari kararların uygulandığını titizlikle takip ederler. Oysaki merkezden birileri ne yaptığımıza bir göz atacak diye zaman kaybetmek anlamsızdır. Böyle kararların merkezi bir yerden, sahada ne olup bittiğini bilmeden alınması proje gidişatını zora sokabililr. Elini kirleten proje ekibindeki programcılardır. Projeyi ilgilendiren tasarım kararlarını onlar almalı ve uygulamalıdırlar. Merkez mimar grubu yine genel gidişatı yönlendirici kararlar alsın, ona birşey demiyoruz, ama lokal projelere karışmasınlar, karışmak istiyorlarsa sahaya inip, ellerini kirletsinler. Bakalım o kararları yine öyle rahatlıkla alabilecekler mi!
Listemize müşterinin ne istediğini anlamamak, yanlış teknolojik araçların seçimi, yazılım ekibinin yeteneklerine güvenmemek, iteratif bir çevik süreci kullanmamak gibi daha birçok neden ekleyebiliriz.
Yazılım genç bir sektör değil. Genç bir sektörde çalışıyoruz argümanının arkasına saklanarak, batan projelerin sorumluluğundan kendimizi kurtarmaya çalışmamız doğru değil. 1950, belki de daha öncesinden beri insanlar programlar yazıyor. Donanımcılara bir baksanıza. Almışlar başlarını, gidiyorlar. Bilmem kaç çekirdekli işlemciler yapıyorlar. Biz yazılımcıların onları takip etmesi bile hayal oldu. Donanımda muazzam gelişmeler olurken, biz yazılımcılar olduğumuz yerde sayıyoruz. Yazdığımız programlar birden fazla çekirdek üzerinde koşmakta zorlanıyor. Daha bu işe bile hakim değiliz. Lakin bunların hepsi yazılımdan anlamıyoruz anlamina da gelmez. Yazılım mühendisi olarak bilmemiz ve uygulamamız gereken prensip ve pratikler var. Bunlar:
- Extreme Programming gibi bir çevik sürecin adapte edilmesi
- Test Güdümlü Yazılım
- Sürekli Entegrasyon
- Yeniden Yapılandırma
- Tasarım Prensipleri
- Yazılım Testleri
- Tasarım Şablonları
Projelerin batmasında biz yazılımcılar da rol oynuyoruz. Kendimizi geliştirip, yazılım pratik ve prensiplerine daha çok hakım olmamız gerekiyor. Bu konulara işimize olan saygımızdan dolayı daha fazla odaklanmalıyız. Bu konulara hakim olan üstatların peşlerini bırakmamalıyız. Onlardan öğrenebildiğimiz herşeyi öğrenip, işimizi daha kaliteli yapmaya çaba sarf etmeliyiz.
Ama tek suçlu biz değiliz. Proje yöneticileri herşeyi doğru yapıyor denemez. Firma bünyesinde verilen yanlış politik kararlar, yöneticilerin programcıları insan olarak değil de, kaynak olarak görme eğilimleri, ayakları yere basmayan proje planlaları, maliyeti düşürme güdümlü işçi alımları, genel olarak kötü yönetim, projelerin başarısızlıkla sonuçlanması çabuklaştırmaktadır.
Biz programcılar işimizi doğru yaparsak en azından projeyi siz batırdınız diye bize yüklenemezler :)
EOF (End Of Fun)
Özcan Acar
Kod Kata ve Pratik Yapmanın Önemi
Bizim ailede müzisyen geni var, babamdan bana geçmiş olsa gerek. Babam çok iyi bir ses sanatçısıdır. Keşke benim de onun kadar güzel sesim olsa diye düşünmüşümdür her zaman. Ama ne yazık ki yaratıcının benimle olan planları başka türdenmiş. İyi bir dinleyici olduğumu düşünüyorum. TSM parçalarını seslendirmeye çalıştığımda babam, detone olmadığımı söyler. Ama sesimin ne kadar kötü olduğunu ben bilirim. Keşke babam gibi güzel bir sesim olsaydı. Ufakken hatırlıyorum: TV yok; internet yok; radyo var; arkası yarın ve TSM var. TRT radyo yayınlarını dinleyerek büyüdüm; ne güzel günlerdi…
Bendeki müzisyen genini aktif hale getirmek için 2002 senesinde bir elektro gitar aldım. Aradan tam on sene geçmiş ve ben hala gitar çalamıyorum. Bir müzik aletini çalmaya çalışmak büyük fedakarlık istiyor. Eğer motivasyon yoksa o zaman başarı sağlamak hemen hemen imkansız. Motivasyonun yanısıra düzenli olarak pratik yapmak gerekiyor. Ben bunları ne yazik ki beceremedim ve gitar çalmak benim için her zaman bir hayal olarak kalacak. Şimdi bunun programcılıkla ne alakası var diyeceksiniz. Anlatmaya çalışayım.
Müzisyenler performans ve pratik yapma arasında ayrım yaparlar. Biz programcılar yapmayız! Müzisyenler için sahnede olmak performans yapmaktır. Programcılar için de iş yerine giderek kod yazmak performanstır. Müzisyenler düzenli olarak sahne harici pratik yaparlar. Biz programcılar yapmayız. İş yerinde yazdığımız kodları pratik yapmak olarak algılarız. Çok iyi müzisyenler pratik yapmaya çok önem verirler ve daima saatler boyu bu konuda çalışırlar. Bu yüzden sahnede çok muazzam bir performans ortaya koyarlar, çünkü yaptıkları pratikler onların sular seller gibi müzik yapmalarını sağlar. Biz programcılar pratik eksikliğinden dolayı zaman zaman kod yazmakta zorlanırız. Sular seller gibi program yazamayız, çünkü pratik yapma özürlüyüzdür. Pratik yapmanın ne olduğunu tam olarak bilmeyiz ve performansla pratiği birbirine karıştırırız. Bu yüzden ustalaşma sürecimiz zora girer. Orta halli idare edip gideriz. İçinde çalıştığımız projeler bizi sanki orta halde tutmak için ağız birliği yapmış gibidir. Proje yöneticilerinin ya da iş verenlerin, programcıların orta halden ustalığa geçmesi için çaba sarfettikleri enderdir. Doğruyu söylemek gerekirse biz onlar için kağıt üzerinden sağa sola kaydırdıkları kaynaklardan başka birşey değillizdir. Belki de çok iyi olmamızı bile istemezler, çünkü daha fazla maaş isteme ya da daha iyi bir iş bulma fikri aklımıza gelebilir. Bu yüzden ustalaşma sürecinde onlardan medet ummak doğru değildir. Kendi başımızın çaresine bakmamız gerekir.
Nasıl pratik yapmayan bir müzisyenin sonu sahnede performans yaparken vahim olacaksa, pratik yapmayan programcının da sonu bundan farklı olmayacaktır. Pratik yapmayan programcı bir şeyleri çok kısa bir zaman diliminde bitirmek zorunda kalıp, strese girdiğinde yıllardan beri farkında olmadan geliştirdiği ve öyle pekte verimli olmayan yöntem ve mekanizmaları kullanmaya başlayacaktır (bu konuya daha sonra detaylı olarak değineceğim). Bunun önüne geçmek için programcının iş haricinde pratik yapması gerekmektedir.
Karate yapanlar katanın ne olduğunu bilirler. Kata bir karate ögrencisinin tekrar tekrar uyguladığı belli beden hareketlerinden oluşan şemadır. Sahip olduğu kuşağa göre karate ögrencisinin yaptığı katalar değişir. Karate ögrencisi katalarını yaparak karate yapma yeteneğini pekiştirir. Tekrar tekrar aynı kataları yapar, bıkmadan, sıkılmadan, usanmadan. Zamanı geldiğinde, örneğin kuşak imtihanlarında katalarını sular seller gibi sergiler ve bir üst kuşağa geçer. İmtihan olma ve katalarını ustalarına gösterme bir karate ögrencisi için performantır. Başarı sağlayabilmek için imtihan gününe kadar daima kataları üzerinde çalışır, yani pratik yapar. Katalarını yapmayan bir karate ögrencisinin imtihan günündeki hali malumur. Ama burada kata yapmanın ana amacı imtihanan geçmek ve bir üst kuşağı kazanmak değildir. Maksat usta bir karateci olmaktır. Bunun yolu da katadan geçer yani pratik yapmaktan.
Kata, programcıların kullanabileceği bir metafordur. Programcının uyguladığı kod katasıdır. Performans harici zamanlarımızda her gün on beş dakika, yarım saat ya da bir saat kod kata pratiği yapabiliriz. Örneğin benim sık yaptığım katalardan birisi roma rakamları kod katasıdır. Her gün ya da gün aşırı bu ve buna benzer kod kataları yaparım. Burada amaç çalışır bir program geliştirmek değildir. Çok basit bir kod katası bile işinizi görecektir, örneğin FizBuz kod katası.
Uyguladığımız kod kataları yaptığımız bazı işlemlerin, kod yazarken verdiğimiz tasarım kararlarının otomatikleşmesini sağlar. Örneğin ben yazılım geliştirme aracı olarak Eclipse kullanıyorum. Yaptığım kod kataları Eclipse bünyesinde bulunan ve fare kullanmandan yazılım yapmayı sağlayan kısa yol tuşlarını – shortcut key (örneğin STRG+SHIFT+F otomatik kod formatlaması için kullanılır) aklımda pekiştirmemi sağladı. Artık kod yazarken hiç düşünmeden neredeyse otomatikleşmiş bir seviyede kısa yol tuşlarını kullanıyorum ve çok daha hızlı programlayabiliyorum. Öğrenmem gereken daha çok kısa yol tuş kombinasyonu var, ama nasıl verimli bir şekilde öğrenebileceğimi biliyorum. Kod katası yapmadan önce birçok kısa yol tuşunu performansım (iş yerinde kod yazma) esnasında kullanmışımdır. Bazen internetten araştırma yapmışım ve yeni tuş kombinasyonları öğrenmişimdir. Lakin birkaç temel kısa yol tuş kombinasyonu harici bunları devamlı aklımda tutmam mümkün olmamıştır. Çok egzotik tuş kombinasyonları var. Bunları akılda tutmak için her gün kod pratiği yapmam gerekiyor. Kataları yaparken tekrar tekrar aynı kıya yol tuşlarını kullandığım için bunları akılda tutmam ve ezberlemem kolaylaşıyor. Ezberimde olan kısa yol tuşlarını da performansım esnasında kullanmam da çok kolay oluyor.
Kısa yol tuşlarına hakimiyet verebileceğim en basit örneklerden sadece bir tanesi. Kod kataları yaparak bir programcı yazılım esnasında gerek duyduğu yetenekleri geliştirebilir. Örneğin test güdümlü kod kataları yapmaya alışmış bir programcı, iş yerinde kod yazarken ister istemez bir test sınıfı oluşturarak işe başlayacaktır, çünkü bunu yapmaya alışmıştır. Test yazsam mı yazmasam mı diye kara kara düşünmez ve hemen test kodunu oluşturmaya başlar. Kafasındaki çalışma kalıbı artık bu şekildedir (doğru olan çalışma tarzı zaten budur). Test sınıfı ve metotları parmaklarından adeta akar gider. Bu durumu gitar çalan bir müzisyenle kıyaslayalım. Gitarist çalmak istediği parçayı devamlı çalıştığı için performansı esnasında beyninde oluşan kalıplar devreye girer ve müzisyen farkında bile olmadan parmakları perdeler üzerinde gider gelir. O esnada gitarist hangi parmakları ile hangi perdeye gidip hangi notayı basması gerektiğini düşünmez bile. Eğer düşünürse o zaman pratik eksikliği var demektir ve çaldığı parça bu durumun göstergesi olacaktır. Yeniden yapılandırma (refactoring) kataları yapan bir programcı bir switch komutunu ya da bir for düngüsünü nasıl yok edeceğini ya da yeniden yapılandıracağını bilir. Bu konuda tecrübesiz bir programcı genelde switch komutunun kullanılmasını bir sorun olarak bile algılamayabilir. Bunu sorun olarak algılasa bile bir switch komutunu nesneye yönelik programlama teknikleri kullanarak ortadan kaldırmada zorlanabilir. Buna karşın bu konuda pratik yapmış bir programcı hiç gözünün yaşına bakmadan switch komutunu dakikalar içinde yok edecek ve kodu bakımı ve geliştirilmesi daha kolay bir hale getirecektir. Pratik yapmış programcı için başka bir alternatif yoktur; switch komutunu görür görmez beyni ne yapması gerektiğini bilir; programcı hemen harekete geçer.
Buradan yola çıkarak yıllar içinde farkında olmadan geliştirdiğimiz bazı yöntem ve kalıpların neden verimsiz program yazmamıza sebep olduklarına değinmek istiyorum. Hiç zaman yetersizliğinden dolayı çok hızlı bir şekilde program yazmak zorunda kaldınız mı? Böyle bir durumda nasıl kod yazıyorsunuz? Kullandığınız yöntem ve kalıplar nelerdir? Burada tasarım kalıplarından (design pattern) bahsetmiyorum. Değinmek istediğim daha çok beyninizde hangi mekanizmaların çalıştığı ve ellerindenizden hangi kod satırlarının nasıl döküldüğü. Ben kendimdem örnek vereyim. Kata, refactoring ve diğer yazılım tekniklerine kullanmadan önce oluşturduğum sınıflar ve metotlar binlerce ya da yüzlerce satırdan oluşmakta idi. Özellikle sürüm zamanı yaklaşmaya başlayınca panik olur, saçma sapan, ama en azından çalışan kod yazardım. İki gün sonra yazdığım kodları okuduğumda bu kadar kötü mü yazılır kod diye hayretlere düşerdim. Test sınıfları oluşturmamam da cabasıydı. Programcı bu gibi durumlarda ister istemez yıllarca farkında olmadan geliştirdiği ve öyle pekte verimli olmayan yöntemlerine geri döner. Normal şartlar altında özenle seçilen sınıf, metot ve değişken isimleri, zor şartlar altında artık pek önemsenmez, çünkü stresten dolayı ve günü kurtarmamız gerektiği için otomatik olarak beynimizdeki verimli olmayan mekanizmalar devreye girer. Bu davranışı hayatı tehlikede olan bir canlı ile kıyaslayabiliriz. Canlı kendini tehlikede hissettiği anda iç güdüleri ile haraket edip, tehlikeden uzaklaşmaya çalışacaktır. İnsanlarda da durum farklı değildir. Kendimizi tehlikede hissettiğimiz zaman ya da hayatımızı kaybetme rizikosuyla karşılaştığımızda beynimiz adrenalin hormonunu salgılar. Panik oluruz, ama iç güdüsel davranarak tehlikeye karşı koymaya çalışırız. Bu esnada beynimizde çalışan programlara hükmetmemiz hemen hemen imkansızdır. Onlar otomatik olarak çalışır ve bizim teklikeye karşı koymamızı sağlarlar. Aynı şekilde stres altında olan programcı da iç güdüsel hareket edecek ve daha önce geliştirdiği ve kullandığı tehlikeden kurtulma rutinleri devreye girecektir. Programcı bir an önce çalışan bir kod oluşturmak istiyecek ve bunun için sahip olduğu tüm prensipleri ayaklar altına alacaktır. Böylece okunması çok güç yüzlerce, binlerce satırdan oluşan metotlar, sınıflar oluşacaktır. Bu programcının gücüne gitmez, çünkü kendisi de farkında olmadan böyle çalışmak zorunda kalmıştır. Oysaki programcı sık pratik yapmış olsa böyle yapıların oluşması mümkün değildir. Neden? Kod kataları programcının beynini bir nevi yeniden programlar. Kod kataları programcının beyninde yeni kalıpların ve mekanizmaların oluşmasını sağlar. Programcı strese girdiğinde bu yeni mekanizmalar devreye girer. Aynı gitar çalan usta bir gitaristin parmaklarını farkında olmadan perdeler üzerinde oynatması gibi programcı da edindiği yeni mekanizmaları otomatik olarak kullanmaya başlar. Katacı programcı metotların uzun olmasına izin vermez, metot, sınıf ve değişken isimlerini yine özenle seçer, beyni programcıyı devamlı bu yönde çalışmaya zorlar, çünkü programcının beyninde yaptığı katalar ile yeni bir repertuar oluşmuştur ve beyin bunları otomatik olarak kullanmaya başlar. Kullanılan eski yöntemler kaybolur ve programcı stres altında bile çok verimli olabilir. Beyinde bu repertuarı oluşturmak için kod katası yapmak gerekiyor. İş yerinde program yazarak bu repertuarı oluşturmak hemen hemen imkansız. Usta programcılar ağaçta yetişmiyor ya da gökten düşmüyor. Usta programcı olmak isteyen kişinin büyük fedakarlıklar yapması lazim. Bunun başlangıcı da kod kataları.
Özetle usta bir programcı olma yolunda kod katası yapmak çok büyük önem taşıyor. Bunun yanısıra kataların düzenli olarak yapılması gerekli, aksi taktirde beklenen neticeleri elde etmek zor olabilir. Ben kataları mecbur olduğum için yapmıyorum, işimi ve programcılığı sevdigim ve kod katası yapmayı zevkli bulduğum için yapıyorum. Bir hobi olarak değerlendirebilirsiniz. Kimse mecbur olduğu için karate kursuna gitmiyor, bu işten zevk aldığı ve karateyi öğrenmek istediği için gidiyor. Aynı şekilde bende daha iyi bir programcı olabilmek için kod katalarımı yapıyorum. Her yaptığım katayla yeni birşeyler öğreniyorum. Her kata seansında bir sorunu çözmek için daha kestirme yollar keşfedebiliyorum, başka tasarım kararları vererek başka çözümler üretebiliyorum. Bir zaman sonra artık bazı işlemleri yapmak otomatikleşiyor sanki. İş hayatımda, yani performans yaparken bunun faydasını görüyorum. Programcı olarak kendime olan güvenim artıyor.
Siz daha iyi bir programcı olmak için ne yapıyorsunuz? Kod katası yapmıyorsanız mutlaka denemelisiniz :)
Ustayı usta yapan pratikleridir.
Not: Yaptığım kataları KodKata.com‘da sizinle paylaşıyorum. Bir göz atmanızı tavsiye ederim.
EOF (End Of Fun)
Özcan Acar
Çevikliğin Böylesi
Son zamanlarda yazılımla yakından ya da uzaktan ilişkisi olan herkesin ağzında olan kelime; çeviklikten bahsediyorum. İngilizce de agile, lean gibi kavramlar kullanılıyor ve artık her şey için kullanılmaya başlandı. Gören de zannederki artık her proje çevik yazılım yöntemleri ile yapılıyor, her şey yolunda.
2010 senesinde Londra’da yapılan Domain Driven Design exChange konferansında Eric Evans, yazılımda çevikliğin anlamının kaybolduğunu çünkü artık her şeyin çevik olarak isimlendirildiğini söylemişti. Ne kadar haklı. Aşağıdaki fotografı bir trende çektim. Artık iş verenler bile çevik kelimesini kullanarak yazılımcıları oltaya düşürmeye çalışıyor. Çevik bir fare, çevik bir klavye belki de çevik bulut (agile cloud) bile kullanıyorken bulabiliriz kendimizi yakında. Yaşasın hayatın her safhasında karşılaştığımız çeviklik.

Son günlerin en moda çevik terimlerinden birisi Scrum. Avrupa’da artık birçok proje Scrum ile yapılıyor. Proje yöneticileri Scrum’la oturuyor, Scrum’la kalkıyor. Scrum yazılımda yeni bir dönemin başlangıcı. Diğer çevik süreçler on, on beş yıldır piyasada olmalarına rağmen, Scrum iyi pazarlandığı için çeviklik deyince ilk akla gelen süreç oluyor. Şahsen Scrum yöntemleri beni elektrik gibi çarpmamış olsa bile (çok fazla etkilenmediğim anlamında), Scrum doğru uygulandığında bir projede çevikliğin başlangıcı olabilir. Bugüne kadar birçok Scrum projesinde çalıştım ve doğru düzgün uygulandığını görmedim. Eski proje yöneticileri şimdilerde Scrum Master olmuşlar ve eski yöntemleri ile projeleri sürdürmeye devam ediyorlar. Kafalarda değişen fazla bir şey olmamış. Scrum’ı elbise olarak almışlar, kendi bedenlerine uydurmaya çalışmışlar. Bu bir yere kadar doğru olabilir, ama daha doğrusu Scrum elbisesini alıp, bedeni ona göre uydurmaktır. Scrum harfiyen ne istiyorsa proje ve çalışmalar ona göre şekillendirilmelidir. Ama mevcut kafalar değişmedikçe Scrum ve diğer çevik süreçlerin başarılı olmaları mümkün değil. Çeviklik, eski kafaların eski yöntemlerle yaptıkları işleri kendi yöneticilerine satmak için kullandıkları bir kavram haline geldi. Scrum projelerinde edindiğim tecrübeleri size aktararak çevikliğin nasıl yarı yolda kaldığını ve gerçek çevikliğin ne anlama geldiğini aktarmaya çalışayım.
Katıldığım ilk Scrum projesini hatırlıyorum. Sıkı bir mülakatın ardından projeye alındım. Mülakat esnasında bana bir sürü Java bulmacası soruldu. Maksat ne kadar derin Java bilgisine sahip olduğunu anlamaktı. Ama test güdümlü yazılım ya da JUnit hakkında bir kelime bile edilmedi. Aynı tarzda mülakatlar ile başka programcılar da projeye dahil edildi. Onlarda da durum farkli değildi. Ben programlarımı test güdümlü yazmaya gayret gösterdim. Ama bazı programcılar kırık kodları versiyon kontrol sistemine ekledikleri için testlerim çoğu zaman çalışmıyordu. Bu beni çok rahatsız eden bir durumdu. Test yazmaya önem vermeyen bu tür programcılarla çok ağız dalaşımız oldu. Sürekli entegrasyon serveri kullanılmıyordu, test güdümlü çalışılmıyordu, müşteri gereksinimleri kullanıcı hikayeleri olarak hazırlanmamıştı. Hangi kullanıcı hikayesini ne kadar zaman diliminde tamamlarız diye tahmin etme oturumları yapılmıyordu. Ama bir Scrum ekibi ve projesiydik. Her sabah on beş dakika asker gibi sıraya girip, Scrum toplantımızı yapardık. Bunun neresi çeviklik, neresi Scrum. Günde on beş dakika toplantı yaparak çevik olunmaz! Zaman kaybından başka bir şey değildir, göz boyamacadır.
Çalıştığım diğer bir Scrum projesinde Scrum’ın doğru adapte edilmesi için gayret gösterilmişti. Bir sürekli entegrasyon serveri ve yazılım metriklerini takip etmek için Sonar sunucusu kullanıyorduk. Zaman yetersizliğinden dolayı programcılar test yazmaya önem vermıyorlardı. Ayrıca uygulama bir uygulama sunucusu içinde çalışmak zorunda olduğu için test yazmak kolay değildi. Mevcut testlerin hepsi entegrasyon testi tarzındaydı. En ufak bir değişiklikte bile yeniden bir EAR paketi oluşturup, tüm uygulamayı uygulama sunucusuna çekmek gerekiyordu. Uygulama sunucusunun ayağa kalkması beş dakika sürüyordu. Yazılım geliştirme tamamen uygulama sunucusu ile iç içe geçmiş durumdaydı. Uygulama sunucusunu kullanmadan yazilim yapmak mümkün değildi. Test eksikliğinden ve uygulamanın bir uygulama sunucusuna çekilmesi gerektiğinden, uygulamayı yeniden yapılandırmak çok zordu. Uygulamayı uygulama sunucusundan bağımsız bir hale getirmek için çaba sarfetmemiz gerektiği konusunda çok dil dökmeme rağmen bu gerçekleşmedi. Sonuç olarak çevik değildik, çevik olamadık. Her yeni bir ekleme ile uygulamayı değiştirmek daha da zora girdi. Eğer programcılar ölmedilerse hala yaşıyorlar.
Çevik Nasıl Olunur?
Çevik olmak öncelikle cesaret ister. Gelenekleri bir kenara itip, yeniden başlamayı gerektirir. Felç geçirmiş bir insanın yeniden konuşmayı ya da yürümeyi öğrenmesi gibi çeviklikte her şeyi unutup, yeniden öğrenmeyi gerektirir. Çevik olmayı zor kılan da budur. İnsanlar alışkanlıklarından kolay kolay vaz geçemezler. Radikal değişimleri sevmezler. Yeniliklere kolay kolay adapte olamazlar. Dünya yerinde dursun isterler. Ama yazılım yapmak gibi dinamik bir ortamda değişmeyen tek şey değişikliğin kendisidir. Bununla yaşamak her babayiğidin harcı değildir. Cesur olanların, yeniliklere açık olanların işidir. Buraya kadar olan çevikliğin edebi tanımıydı. Şimdi gelelim teknik tanımlamasına.
Çevik olmayı ben hamur yoğurma ile kıyaslarım. Hamuru, içinde yeterince sıvı olduğu sürece yoğurabilirsiniz. Sıvı azaldıkça hamuru yoğurmak zorlaşır. İçinde sıvı kalmamış hamuru yoğuramassınız. Bu analogiden yola çıkarak çevikliğin yazılımdakı tanımlamasını yapalım. Hamur oluşturduğumuz yazılım sistemi, sıvı birim testleri, yoğurma ise yeniden yapılandırmadır (refactoring). Birim testleri olmadan yazılım sistemini yoğuramassınız (yeniden yapılandıramassınız), ama her yeni müşteri gereksinimi ile sizden yazılım sistemini yoğurmanız beklenir. Oluşturduğunuz uygulamaya yeni müşteri gereksinimlerini eklemek, yani uygulamayı yoğurmak zorundasınız. Bu işi yapmak yani programcı olarak çalışmak istiyorsanız başka alternatifiniz yok. Patronunuz ve müşteriniz sizden uygulamayı yoğurmanızı yanı kendi isteklerine cevap verecek şekilde geliştirilmenizi bekler. Birim, entegrasyon ya da onay/kabul testleri yazmıyorsanız uygulamayı yoğururken sıvı buharlaşacak ve siz belli bir noktadan itibaren uygulamayı yoğuramama rizikosuyla karşı karşıya kalacaksınız. Ama sizden yoğurmaya devam etmeniz beklenecektir. Birçok proje ya da geliştirilen uygulama bu sebepten dolayı başarısız olmaktadır. Devam etmek istiyorsanız uygulamaya sıvı katmanız gerekir. Oluşturacağınız yeni testler hamurunuz için yeni sıvı olacaktır. Bu testler hamuru tekrar yumuşatır ve yoğrulmasını kolaylaştırır. Programcı testleri kullanarak uygulamayı yeniden yapılandırabilir (refactoring). Bu hamuru yeniden yoğurabilme yeteneğini kazanmak demektir. Testler yoksa yeniden yapılandıramaz. Yeniden yapılandıramassa uygulama sıvı eksikliğinden katılaşır ve yoğrulamaz hale gelir. Çevikliğin ve esnekliğin gizli anahtarları testler ve yeniden yapılandırmadır. Bu iki anahtarı kullanmayı bilen programcı çeviktir. Tüm çevik olma hevesinin temelinde bu iki element yatar. Bu iki elementin olmadığı yerde çeviklik olamaz. Uygulamayı istekler doğrultusunda yoğuramadıktan sonra ne proje yönetiminin, ne Scrum’ın ne de çok iyi programcılardan oluşan ekibin bir anlamı kalır. Proje yöneticisi istediği kadar tavana zıplasın; katılaşmış bir uygulayı yeni kod yazarak yumuşatamayız, sadece test yazarak ve devamlı refactoring yaparak bu amaca ulaşabiliriz. Yazılımda işin özü budur: hamuru devamlı yoğrulacak kıvamda tutmak. Hamuru yoğurabilmek demek müşteri gereksinimlerine cevap verebilmek demektir, yani anında görüntü. Anında görüntüyü katılaşmış bir hamurla, yani yazılım sistemi ile yapamayız. Çıkarılması gereken sonuç çok basit aslında: sadece çevik süreç uygulayan projeler yoğrulabilir hamur üretir ve müşterinin yeni gereksinimlerine cevap verebilir.
Çevik olabilmek için çevik yazılım metotlarına hakim olmak gerekir. Her sabah on beş dakika toplantı yaparak elde edilebilecek bir durum değildir bu. Çevikliği anlayanlarla, anlamayanlar arasındaki fark budur. Çevikliği anlamayanlar çeviklik buzulunun (eisberg) su üstündeki kısmını görürler. Su üstünde görünen kısım, su altında kalan kısımdan çok küçüktür. Asıl çeviklikle haşır, neşir olma su altında olur. Her şeye Scrum, lean, agile diye isim verenler su üstünde yaşarlar, suyun altında olup bitenlerden bihaberdirler, çünkü derine dalmaya korkarlar. Onlar değişikliği zaten sevmezler. Eski çalışma tarzlarına çeviklik etiketini yapıştırıp hayatlarına devam ederler. Çeviğiz diye kendilerini ve etraflarındaki insanları kandırırlar. Hamuru yoğururken sıvı tükenmeye yakın panik olurlar. Ne yapacaklarını şaşırırlar, neden böyle oldu diye kara kara düşünürler. Çevik olduklarına kendileri de o kadar inanmıştir ki, suçu çeviklikte bulurlar. Çevikliği sevmemeye başlarlar. Onlar için suçlu olan çevik olma paradigmasıdır. Bilmezler ki çevikliğin hakkını verememişlerdir, çünkü ne olduğunu tam olarak kavrayamamışlardır. Değişikliğe açık olmadıkları için kavramaları da kolay değildir.
Gelelim çevik olmayı anlayanlara. Onlar bahsettiğim iki anahtarın sahibidir. Test güdümlü kod yazmayı bilirler ve her fırsatta bunu uygularlar. Bunun yanısıra refactoring konusunda uzmandırlar. Her yeni müşteri gereksimi ile daha önce verdikleri tasarım kararlarını revide ederler. Uygulamanın katılaşmaya başladığında mevcut tasarımın yetersiz olduğunu anlarlar ve bu tasarımı bozup, yeni bir tasarım yapmaktan çekinmezler. Cesurdurlar. Bilirler ki ellerindeki testler yeniden yapılandırma işlemini mümkün kılar. Buradan çıkardığımız ilk sonuç şudur: çevik olabilmek için test güdümlü yazılım yapmak önem taşımaktadır. Test güdümlü yazılım yapılamıyorsa, o zaman uygulamanın büyük bir kısmını kapsayacak şekilde test kodu yazılmalıdır. Oluşturulan testlerin otomatik olarak çalışması gerekmektedir. Yeniden yapılandırma (refactoring) işlemlerinin birçok yan etkisi olabilir. Onları hızlı bir şekilde lokalize edebilmek için otomatik çalışan testlere ihtiyaç duyulmaktadır. Testlerin olmadıği ya da yetersiz olduğu projelerde programcılar yeniden yapılandırma işlemine cesaret edemezler. Cesaret edemedikleri için yazılım sistemi her gün biraz daha katılaşır ve bir zaman sonra yoğrulamaz hale gelir. Eğlencenin bittiği an budur. Bu noktadan itibaren programcılar için cehennem azabı başlar. Fazla mesailer yapılır, beraber ağıtlar yakılır, kollektif çığlıklar atılır, sende mi Brütüs, sana o kadar emek verdik, yaptıkların bize caiz mi diye yazılım sistemine yüklenilir. Ama Brütüs suçsuzdur. O beni yoğurmayın dememiştir ki. Yoğurma cesaretini programcılar gösterememiştir.
Gerçek çevikliğin temelinde gerçek yazılım mühendisliği metotları yatar. Birincisi test güdümlü yazılım; ikincisi yeniden yapılandırma (refactoring); üçüncüsü eşli programlama; dördüncüsü sürekli entegrasyon; beşincisi basit tasarım; altıncısı iteratif sürüm oluşturma; yedincisi ….
Bu metotların hepsi insanların bilgisayarları icadı ve program yazmaları ile birlikte yer yer uygulanmış metotlardır. Hiç biri yeni icat edilmemiştir Ama bundan on, on beş sene önce Extreme Programming (XP) olarak topluca karşımıza çıktılar. XP bünyesinde proje yönetimi için de metotlar barındırmaktadır. XP bu metotları Scrum’dan almıştır. Ama Scrum bünyesinde XP’nin sahip olduğu çevik metotlar yoktur. Bu yüzden içinde çalıştığım hemen hemen her Scrum projesi sadece kağıt üzerinde çevik olabilmiştir. Saha’ya inildiğinde çevikliğin bir tane atomuna bile rastlamak mümkün olmamıştır.
Sadece proje yönetmek ve programcıların ne yaptığını kontrol etmek için icat edilmiş sözde çevik süreçleri kullananlara sesleniyorum buradan. Gerçek çevik yazılım metotlarını kullanmadığınız sürece çevik olmanız bir hayal olarak kalacaktır. Bu yüzden sürdürdüğünüz birçok proje 130 km/h ile duvara tosluyor. Cesaret edip işin temeline inmeniz gerekiyor. Daha fazla mühendis olup, çevik metotlara hakim olmanız gerekiyor. Her gün on beş dakikalık toplantılarınızdan vaz geçin demiyorum. Bu yerinde bir aktivite. Ama zaman ayırıp bir mühendis kafasıyla sistematik olarak çevik yazılım metotları ile ilgilenin, onları öğrenin, onlara hakim olun, onlari uygulayın. Her Scrum projesini testlerin yine en son safhada yazıldığı ya da zaman yetersizliğinden dolayı yazılamadığı bir ortama çevirmeyin. Profilime ben de kulağa hoş gelen Scrum Master ünvanını koyarım. Ama bu benim ne kadar çevik metotlara hakim olduğumu yansıtmaz. Ünvanlardan çok, hakim olduğunuz gerçek çevik yazılım metotları ile övünün. Hamuru yoğuran ünvan değildir. Hamuru yoguran tecrübeli beyin ve sistemli ve sonuç getiren metotlar kullanmaya alışmış ellerdir. Gerçek yazılım mühendisleri ile düzmece mühendislerin arasındaki fark işte budur. Parayla satın alınan sertifikalar programcıyı programcı yapmaz. Bu sevdadan vazgeçin. Bu sözde çevik yöntemlerle ne dünyayı kurtarırsınız ne de yazılım dünyasına artı bir değer katarsınız.
Çekirdekte gerçek meselenin uygumalayı devamlı yoğurmak olduğunu göz ardı eden bu sözde çevik yöntemler, çevik teriminin her halt için kullanılması ve enflasyona uğramış olması, çevikliğin içinden çıkılamaz bir hale gelmesine sebep olmuştur. Kafalar iyice karışmıştır. Hangi yöntem çeviktir, nasıl çevik olunur, bu sorulara artık kimse net olarak cevap verememektir. Çeviklik artık ifade gücünü yitirmiştir. Bu gerçekten üzücü bir durum. Bir nevi komplo. Sanki eski şelale (waterfall) yöntemleriyle büyümüş bir zümre çevikliği ortadan kaldırmak için iş birliği içindedir. Böyle birsey yok doğal olarak. Fantazim yine kanatlandı.
Beni bir Scrum düşmanı olarak görmeyin. Doğru uygulandığında iyi bir başlangıç olabilir. Ne yazik ki Scrum’ın doğasından kaynaklanan bir sorun bu; Scrum’ı doğru uygulamak hemen hemen imkansız; her türlü uygulama tarzına açık; somut değil; isteyen istediği tarafa çekiyor, bu yüzden ortaya çok komik görüntüler çıkıyor. Scrum doğru uygulandığı taktirde ve proje bünyesinde XP vari yazılım metotları kullanıldığında bir proje tam anlamıyla çevik olabilir. Onun haricinde bu imkansız.
Çeviklikte her şeyin başı çevik mühendislik metotlarıdır. Bunun başında test güdümlü yazılım ve refactoring gelir. İçinde bu elementleri barındırmayan bir süreç çevik yazılım süreci olamaz. Para basmak ve dandik sertifikalar dağıtmak için oluşturulmuş sözde çevik süreçlerden uzak durmakta fayda var. Cesaret gösterip işin özüne inelim. Yeniliklere açık olalım. Yazılım mühendisi isek o zaman bir mühendis gibi çalışalım, sistemli ve metotlu. Buna izin verilmediği yerde durmayalım, baş kaldıralım. Yazılımda çeviklik sadece çevikliği kavramış mühendislerle mümkündür. Eski kafa bir proje yöneticisini Scrum Master yaparak proje çevikleştirilemez. Projede çevikliği yazılım mühendisleri ateşler, meşaleyi onlar ileri götürür, Scrum Master olmuş birisi değil. Onlar en fazla seyirci olabilirler. Sahada maçı oynayan çevik yazılım mühendisleridir. Çeviklik konusunda bunun harici her şey hikayedir.
EOF (End Of Fun)
Özcan Acar
Programcılar yazar olsalardı keşke!
Birçok programcının büyük bir büroda çalıştığını düşünelim ve böyle bir ortama girdiğimizi. Programcı olduklarını bilmiyoruz, ne yaptıklarını da. Bu çalışanların ne yaptığını düşünürdük? Büyük ekranlarda devamlı birşeyler yazdıklarını gözlemleyip yazar olduklarını düşünürdük belki. Birşeyler yazana yazar denir. Bu bir roman, bir ders kitabı ya da bir yemek tarifi olabilir ya da bir kod parçası.
Dışardan bakıldığında biz programcılar böyle algılanıyoruz. Bizler de birer yazarız ama bu ünvanı taşımayı hak etmiyoruz. Neden mi? Açıklamaya çalışayım.
Bir yazar kitaplarını okurları için yazar. Baştan savma yazmaz; nasılsa okur ne demek istediğimi anlar demez; bir kitap olsun da, içinde ne olduğu önemli değil demez; roman yazıyorsa roman kahramanlarına abx, xyz gibi anlaşılması zor isimler vermez; o isimleri özenle seçer, onlara kişilik, ruh ve beden verir; kısaca yazar işini severek yapar, bu uğurda yıllarını verir.
Şimdi bir yazarı bir programcı ile kıyaslayalım. İkisi de birşeyler yazıyor. Yazarın yazdıklarını okuyucuları okuyor, programcının yazdıklarını çalışma arkadaşları. Hangi grup daha mutlu okucuyu kitlesi? Ben ikinci guruba dahil olmakla beraber çok mutsuzum. Okuduklarım bana haz vermiyor. Hadi ondan da vazgeçtim. Ne yazdıklarını anlayabilsem…… Bahaneler de hep aynı: “yeterli zamanim yoktu”, “patron programı hemen bitirmemizi söyledi”…. Bir kitap yazarı bu bahanelerle bir kitap yazsa bu kitap ne kadar başarılı olabilir?
Haklı olarak “Bir romanın bir yazarı olabilir. Programlar zaman içinde onlarca ya da yüzlerce programcının elinden geçiyor” dediğinizi duyuyor gibiyim. Bu okunamaz kodun oluşması için bir gerekçe değil. Her programcının benimsemesi gereken birkaç prensip ve pratik ile bu sorunun önüne geçilebilir. Bunların neler olduğuna yazımın ilerleyen bölümünde değineceğim.
Elli yıl oldu neredeyse; programcılar program yazıyor, bilgisayarlar bu programları çalıştırmak için kullanılıyor. Elli yıl oldu ama biz programcılar hala yazarliğa terfi edemedik. Yazdıklarımız okunmuyor. Kendimiz bile bir süre sonra yazdıklarımızı okuyamıyoruz. Bu mu işimize verdiğimiz kıymet?
Elli satırlık bir metodu anlamak beni zorluyor; yüz satırlık bir metot beni çileden çıkartıyor. Sekiz yüz ya da daha fazla satırlık bir metot hakkında ne düşündüğümü anlayabiliyorsunuz sanırım…. Dışarda böyle metotlar bulmak çok kolay. Yazılım dünyası sanki böyle metotlardan oluşmuş…. Yazar olarak ne kadar kötüyüz…. Bu ünvanı hak edebilecek en son meslek gurubu biziz… biz programcılar.
Programcıların yazar olduğu bir evren düşlüyorum, gerçek yazarlar kadar yaptıkları iş taktir edilen, yazdıkları kodun herkes tarafından (buna ev kadınları da dahil) okunabildiği, kod yazarken değişken ve metot isimlerini roman kahramanı olarak görüp, isimlerini özenle seçtikleri, yazdıkları kodun bir hikaye anlattığı programcıların yaşadığı bir evren…
Böyle bir evren var ama bize yüzlerce ışık yılı uzaklıkta, ışık hızı ile hareket edebilsek bile yüzlerce sene sonra erişebileceğimiz bir evren. İyi birer programcı olmaktan yüzlerce ışık yılı ötedeyiz! Şimdi bir düşünce deneyi yapalım ve bu evreni keşfedelim. Düşünce deneyimizde bizim evrenimizden bahsettigimiz evrene seyahat edecek bir programcımız var. Programcımız ışık hızının çok üstünde bir hızla bu evrene gidecek, oradaki programcılarla sohbet edip geri dönecek. Döndü bile; ne kadar hızlı gidip geldi degil mi? Bize neler getirdi ona bir bakalım. Bundan sonrasını bu seyahati gerçekleştiren programcının ağzından okuyacaksınız.
Yolculuğum uzun sürmedi, birkaç saniye… Uzay aracımla programcıların yaşadığı gezegene indim. Beni çok hoş karşıladılar. Bizlerden bir farkları yok. Beni çalışma ofislerine götürdüler. Bir ekip, evrenler arası ışık hızıyla hareket edebilen uzay araçlarının yazılımı ile uğraşıyordu. Koda bakıp bakmak istemediğimi sordular. İlk önce çekindim; programcı olarak böyle roket mühendisliğinden ne anlarım ki… kodu okusamda anlamam imkansız diye düşündüm. Sen yine de bir bak dediler. Baktım. Bir daha baktım. Birkaç satır okudum. O da ne! Ne kadar kolay okunuyor, okuduğum herşeyi anlıyorum. İnanılacak gibi değil. Bizim programlama dilleri gibi if/else/while yapılar kullanıyorlar, ama yazdıklari kod roman gibi okunuyor. Çok temiz ve sade. Metotlar çok kısa tutulmuş, verilen isimler çok anlamlı. İnsan ne okuduğunu hemen anlıyor. Çok şaşırdım! Bizim dünyamızda durum çok farklı. Zamanımızın büyük bir bölümünü başkalarının yazdığı kodu anlamak için saatler boyu debugging oturumlarında harcıyoruz. Nasıl program yazdıklarını soruyorum. İçlerinden birisi şunları söylüyor:
- İlk önce bir test yazıyoruz. Ortada hiç birşey yok, sadece test kodu var.
- Daha sonra kodu yazmaya başlıyoruz. Testler bizi yönlendiriyor. Herhangi birşeye dikkat etmeden testlerin çalışır hale gelmesi için kodu geliştiriyoruz. İlk sürümde metotlar uzun, isimleri anlaşılmaz olabiliyor, ama ilk sürüm de bunlar önemli değil. Önemli olan kodu çalışır hale gelmesi.
- Kod çalışır hale geldikten sonra tekrar tekrar gözden geçirip, herşey anlaşılır hale gelene kadar değişiklik (refactoring) yapıyoruz. Elimizde otomatik çalışan testler olduğu için refactoring bizim için hiç sorun değil.
- Yaptığımız her değişikliğin ardından testleri koşturarak oluşan yan etkileri tespit etmeye çalışıyoruz. Testler yan etkileri hemen bulmamızı sağlıyor. Bu bizim güvenimizi ve cesaretimizi artırıyor. Çok ufak adımlarla refactoring yapıyoruz. Kodu böylece yavaş yavaş yoğuruyoruz.
- Programlarımızı KISS (Keep It Stupid Simple = Kısa tut) prensibine göre geliştiriyoruz. Her zaman en basit çözümü tercih ediyoruz. Basit olmayan çözümler kodun okunurluğunu olumsuz etkiliyor. Aramızda en iyi algoritmaları kim yazdı yarışı yapmıyoruz, en basitini ve okunuru kim yazdı yarışı yapıyoruz. Okunmayanar kod gözden geçirme oturumlarında diskalifiye oluyor
- Kod tekrarlamasını önlemek için DRY (Dont Repeat Yourself = Kendini tekrarlama) prensibine sadık kalıyoruz. Kod tekrarları programın geliştirilmesinin önünde büyük bir engel.
- Belirli etaplarda birden fazla çalışma arkadaşımızla kodu beraber gözden geçiriyoruz (code review). Burada amacımız kodu daha da okunur hale getirmek. Çalışan testlerimiz olduğu için kodu değiştirmek bizim için çocuk oyuncağı. Kodu bu şekilde yoğurmak bir zaman sonra çok zevkli bir uğraşı haline geliyor. En geç kod gözden geçirme oturumlarımızda uzun metotları ortadan kaldırma fırsatı buluyoruz.
- Yazdığımız metotlar en fazla dört satırdan oluşuyor. Her sınıfın ve metodun sadece bir sorumluğu (SRP) var. Sınıf, metot ve değişken isimlerini çok özenle seçiyoruz. Kesinlikle bir kod parçasını açıklamak için koda yorum eklemiyoruz. Kod yoruma ihtiyaç duyuyorsa o zaman ya seçtiğimiz isimler yetersiz ya da kodun birden fazla metoda bölünmesi gerekiyor. Kodu okunur hale getirmek için bir sebep daha.
- Genel olarak kod yazarken SOLID prensiplerine dikkat ediyoruz. SOLID testler kadar önemli.
- Testler bizim için yazdığımız kod kadar önemli. Test kodunu da zaman zaman gözden geçirip daha okunur hale getirmeye çalışıyoruz. Testlere üvey evlat muamelesi yapmıyoruz.
Bunların yanında kırık cam metaforu bize devamlı izci kuralını hatırlatıyor. Kırık cam ve izci kuralı nedir diye soruyorum. Programcı arkadaş şu şekilde açıklıyor:
Tamir edilmeyen bir cam mahalle sakinlerinde terkedilmişlik hissi uyandırır. Bu kırık cam binaya sahip çıkılmadığının göstergesi olarak algılanır. Kısa bir zaman sonra başka pencere camları kırılır ve bina sakinleri ya da bölgede oturan diğer şahışlar düzensizliğin artmasını çabuklaştırırlar. Binaya sahipleri tarafından sahip çıkılmadığı taktirde bina büyük hasar alır. Artan hasar nedeniyle bina sahipleri binayı tekrar düzene sokma şefkini yitirebilirler. Program kodları kırık cam misali düzensizlikler giderilmediği taktirde zamanla bakımı zor hale gelirler. Programcı izci kuralını uygulayarak koda sahip çıkar.
Her izcinin uyduğu bir kural vardır:
“Kamp yaptığın yeri bulduğundan daha iyi bir şekilde bırak!”
Biz programcı olarak geride bıraktığımız kodun kalitesi, işe başladığımızda bulduğumuz kodun kalitesinden daha iyidir. İzci kuralını uygulayan programcı kırık cam prensibinden dolayı oluşan düzensizlikleri gidermiş olur. İzci kuralının uygulanması durumunda kırık cam hiç oluşmaz ya da mevcut kırık camlar tek tek tamir edilmiş olur.
Bu programcılarla sohbetimiz saatler boyu sürdü. Birşeyi çok iyi anladım ki o da bu programcıların işlerini çok severek yaptıkları. Aramızda ne kadar büyük farklılıklar varmış! Bu programcıların benimsedikleri ve günlük iş hayatlarında uyguladıkları prensipler, pratikler ve bir değer sistemi varmış meğer. Vaybe! Keşke burada kalabilsem ve bu muazzam yazarlarla çalışabilsem. Onlarla çalışmak ne kadar zevkli olurdu kimbilir. Yaptıkları işten çok büyük haz aldıkları ve ortaya çıkan kodla gurur duydukları yüz ifadelerinden ne kadar da belli oluyor. Benim dünyamda programcılar devamlı endişe içinde. Kafalarındaki sorular hep aynı: “programı zamanında yetiştirebilecek miyim?”, “anlamadığım şeyi nasıl değiştireyim ben şimdi”, “bu metot bu kadar uzun olmak zorunda mı ya!”, “neden bu mesleği seçtim? herkesin pisliğini ben mi temizlemek zorundayım?”, “bir an önce yönetici olupta bu pislikten kurtulayım bari, zaten bir ömür programcılık yapan adama kim kıymet verir”….. Biz programcılar kendi dünyamızda çok mutsusuz. Bu değişmeli. Zaman ne çabukta geçmiş. Geri dönmem gerekiyor artık.
Uzay aracıma binmek ve dünyama geri dönmek üzere yola çıkıyoruz. Uzay aracıma doğru giderken tekrar yaşadıklarımı gözden geçiriyorum. Programcılık ve yazarlık arasındaki parallelliği ve farklılığı daha değişik bir gözle görüyorum. Programcılık yazarlık demek, bir yazardan farklı birşey yapmıyoruz, ama bir yazardan çok farklı bir şekilde yazıyoruz. Bunun değişmesi gerektiğini düşünüyorum. Bu mesajı mutlaka kendi dünyamdaki programcılarla paylaşmalıyım.
Böyle düşüncelere dalmışken, uzay aracıma geliyoruz. Beni bu evrenin programcıları uğurluyorlar. Bana veda ederken elime bir adet “Clean Code” isimli kitabın nüshasını tutuşturuyorlar. Aralarından birisi “biz bu kitabı sizin dünyanızda keşfettik, bizim için çok faydalı oldu, siz de mutlaka bir göz atın” diyor. Bu kitabı tanıyorum: Robert C. Martin yazmış. Okuma firsatı bulamamıştım. Şimdi mutlaka okuyacağım. Elveda diyorum ve uzay gemime biniyorum. Birkaç saniye geçiyor… Tekrar kendi dünyamdayım. Artık bir yazar olmaya karar veriyorum, programcı bir yazar….
Siz de bir yazar mısınız?
EOF (End Of Fun)
Özcan Acar
SOLID
SOLID (Single responsibility, Open-closed, Liskov substitution, Interface segregation ve Dependency inversion) yazılım tasarım prensipleri için kullanılan bir kısaltmadır. Yazılım yaparken SOLID uygulandığı taktirde bakımı ve geliştirilmesi kolay yazılım sistemleri oluşturmak mümkündür. En verimli hali test güdümlü yazılım ile uygulanır.
| S | SRP |
Single Responsibility Principle Her yazılım biriminin (sınıf, nesne, metot) tek bir sorumluluğu olmalıdır. |
|---|---|---|
| O | OCP |
Open/Closed Principle Yazılım birimleri geliştirilmeye açık, değişikliğe kapalı olmalıdır. |
| L | LSP |
Liskov’s Substitution Principle Alt sınıflardan oluşturulan nesneler üst sınıfların nesneleriyle yer değiştirdiklerinde aynı davranışı göstermek zorundadırlar. |
| I | ISP |
Interface Segregation Principle Herşeyi ihtiva eden interface sınıflar yerine belli bir işlemi yapan interface sınıflar oluşturulmalıdır. |
| D | DIP |
Dependency Inversion Principle Bağımlılıklar soyut sınıflara doğru olmalıdır. |
Diğer tasarım prensipleri için “Tasarım Prensipleri” bölümüne bakınız.
EOF (End Of Fun)
Özcan Acar
Parametrik Konstruktör (Parameterize Constructor)
Bir sınıf konstruktörü bünyesinde oluşturulan nesne, bu sınıfın test edilmesini zorlaştırır. Bunun bir örneğini EmployeeManager sınıfında görmekteyiz. Sınıf değişkeni olan dao konstruktör bünyesinde oluşturulmaktadır.
[source language=’java’]
package com.kurumsaljava.refactoring.parameterizeConstructor;
public class EmployeeManager {
private EmployeeDao dao;
public EmployeeManager() {
this.dao = new EmployeeDao();
}
}
[/source]
EmployeeManager sınıfının test edilebilmesi için EmployeeDao‘nun kullanılması zorunludur. EmployeeDao burada dolaylı bir bağımlılık teşkil etmektedir. Büyük bir ihtimalle EmployeeDao sınıfı çalışır durumda olan bir veri tabanına ihtiyaç duymaktadır. Bu durum EmployeeManager sınıfının test edilebilirliğini zora sokmaktadır.
[source language=’java’]
package com.kurumsaljava.refactoring.parameterizeConstructor;
public class EmployeeManagerTest {
public void testEmployeeManager()
{
EmployeeManager manager = new EmployeeManager();
Assert.assertTrue(manager.pay() == 0);
}
}
[/source]
Bir parametrik konstruktör oluşturarak bu sorunu ortadan kaldırabiliriz.
[source language=’java’]
package com.kurumsaljava.refactoring.parameterizeConstructor;
public class EmployeeManager {
private EmployeeDao dao;
public EmployeeManager(final EmployeeDao myDao) {
this.dao = myDao;
}
public int pay() {
return 0;
}
}
[/source]
EmployeeManager sınıfının kontruktörünü EmployeeDao sınıfından bir parametre ile genişletiyoruz. Bu şekilde ihtiyaç duyduğumuz EmployeeDao sınıfından bir nesneyi dışardan enjekte edebiliriz. EmployeeDao sınıfının bir interface sınıfı olduğunu düşünürsek, testlerimiz bünyesinde kullanılmak üzere FakeEmployeeDaoImpl ismini taşıyan ve veri tabanına bağımlılığı bulunmayan yeni bir implementasyon oluşturabiliriz.
[source language=’java’]
package com.kurumsaljava.refactoring.parameterizeConstructor;
public class EmployeeTest {
public void testEmployeeManager()
{
EmployeeDao dao = new FakeEmployeeDaoImpl();
EmployeeManager manager = new EmployeeManager(dao);
Assert.assertTrue(manager.pay() == 0);
}
}
[/source]
EOF (End Of Fun)
Özcan Acar








