Açık Sözlü Programcı

Programcı takım arkadaşı ile kodu gözden geçirme (code review) seansı yapıyor. Kodun içinde bulunduğu durumdan hoşnut değil, lakin bunu takım arkadaşına söylemiyor. Arkadaşının yanlış anlamasından mı korkuyor?

Tüm yazılımcılar iterasyon sonunda bir araya gelerek geri bakış (retrospective) seansı yapıyorlar. Bazı programcılar boğazlarına kadar dolmuşken, bunun nedenini takım arkadaşlarıyla paylaşmıyorlar. Çok mu sabırlılar?

Günlük stand-up toplantı yapılırken bazı programcılar planın gerisinde kaldıklarını, üzerinde çalıştıkları kullanıcı hikayesinin zamanında tamamlanmasının münkün olmadığını söylemiyorlar. Ekip arkadaşları önünde küçük düşmekten mi korkuyorlar?

Programcı başka bir ekip arkadaşının yazdığı kodu değiştirmeye çekiniyor. Aynı şeyin kendi yazdığı kodun başına gelmesini mi istemiyor?

Verdiğim örneklerin hepsinde bir tikanıklık ve blokaj söz konusu. Bahsettiğim programcılar samimi ve açık sözlü değiller. Bu ne yazık ki çevikliği öldüren, şeker hastalığı gibi çok sinsi bir şey. Çevikliğin temel değer sistemini cesaret, iletişim, geribildirim ve basitlik oluşturuyor. Bunların olmadığı yerde çevik olunması imkansız.

Kimsenin etlisine, sütlüsüne karışmamak çevik süreci sabote etmek gibi bir şeydir. Herkes açık sözlü olma cesaretine sahip olmayabilir. Ama bunun için gerekli ortam oluştuğunda açık sözlü olmamak için de bir sebep yoktur. Bir retrospektive seansında kimseyi suçlamadan ve küçük düşürmeden yanlış giden şeyler üzerinde konuşulabilir. Fikir birliği sağladıktan sonra yolunda gitmeyen şeyleri tekrar rayına sokmak zor değildir. Burada önemli olan samimi olmak ve yanlış giden şeyleri açık sözlülükle dile getirmektir.

Yazılım bir ekip işidir. Bireyin başarısı takımın başarısıyla ya da başarısızlığıyla doğrudan orantılıdır. Tüm takım aynı bot içinde oturduğuna göre, botun ilerleyebilmesi için herkesin aynı şevk ile kürek çekmesi gerekir. “Bot su alıyor, ama bana ne“, “bazı arkadaşlar kürek çekmiyor, benim derdim değil“, “bazı arkadaşlar kürek çekme tekniğine tam hakim değiller, kim uğraşacak şimdi onlarla” gibi düsüncelere sahip olmak botu hedefine ulaştırmaz.

Samimiyet ve açık sözlülük programcının takım içindeki saygınlığını artırır. Bunun tersi durumunda halka en zayıf yerinden kopacaktır. O en zayıf nokta samimi ve açık sözlü olmayan programcının kendisidir. Bunu herkes bilmesede kendisi çok iyi bilir.


EOF (End Of Fun)
Özcan Acar

Java Generics Get ve Put Prensibi

Java Generics and Collections kitabında Get and Put isminde bir prensipden bahsediliyor. Java Generics wildcard kullanımı bu prensip takip edildiğinde daha kolaylaşıyor. Prensip şöyle:

Eğer bir yapıdan (liste, map vs.) nesne ediniyorsanız (get) extends wildcard, bir yapıya nesne ekliyorsanız (put) super wildcard kullanın. Bir yapı üzerinde bu iki işlemi birden yapıyorsanız, o zaman wildcard kullanmayın.

Bunu bir örnek ile açıklayalım. Aşağıdaki metot bir listeden diğer bir listeye nesneleri kopyalamak için kullanılan jenerik bir metot.

[source language=”java”]
public static <T> void copy(List<? super T> dest, List<? extends T> src) {
for (int i = 0; i < src.size(); i++) {
dest.set(i, src.get(i));
}
}
[/source]

copy metodunun ilk parametresi nesnelerin kopyalanacağı, yani put yapılacak olan liste, ikinci parametresi nesnelerin alındığı, yani get edildiği liste. Şu şekilde bir listeyi diğer bir listeye kopyalayabiliriz:

[source language=”java”]
List<Object> objs = Arrays.<Object>asList("String", 1, 3.14);
List<Integer> ints = Arrays.<Integer>asList(1,2);
copy(objs, ints);
[/source]

dest isimli parametre put işlemi yapıldığı için super wildcard’ını, src isimli parametre get yapıldığı için extends wildcard’ını kullanıyor.

Bir iterator kullanıldığında bir yapıdan get işlemi ile değerler edinilir. Bu durumda extends wildcard kullanılmalı. Aşağıdaki örnekte sum metodu bir listede yer alan Number sınıfı ve altsınıflarından oluşan nesnelerin değerlerini topluyor. Buna göre bu metodu sum(Arrays. asList(1, 2)) ya da sum(Arrays. asList(1.1, 2.2)) şeklinde koşturmak mümkün. Eğer extends wildcard kullanılmasaydı Integer ya da Double nesneler ihtiva eden bir listeyi sum metoduna parametre olarak vermek mümkün olmazdı.

[source language=”java”]
public static double sum(Collection<? extends Number> nums) {
double s = 0.0;
for (Number num : nums)
s += num.doubleValue();
return s;
}
[/source]

EOF (End Of Fun)
Özcan Acar

Programcılık Çıtası Yükseliyor

Ben Java’nın ilk günlerinden beri bu dili kullanan bir programcıyım. 1998 senesinin bir günü kampüste laflarken bir arkadaşım yeni haberini aldığı Servlet teknolojisinden bahsetmişti. Bugün gibi hatırlıyorum: “vay… demek Java ile appletler harici web programcılığı yapılabiliyor….” demiştim. Java ile geçirdiğim ilk yıllarda hakim olmam gereken konular JDBC, Reflection, RMI ve Servlet gibi teknolojilerle sınırlı idi. On beş sene sonra durum çok farklı! Başlangıçta küçük bir havuzda yüzerken, şimdilerde kocaman bir okyanusun içindeyim ve bu okyanusun ucu, bucağı yok.

Java dili eklenen her yeni teknoloji ile günümüzde bir platform haline geldi. Artık Java dili bu platform üzerinde kullanılan dillerden sadece bir tanesi. JVM üzerinde koşturulabilen Scala, JRuby, Groovy, Clojure gibi birçok dil mevcut.

Bundan beş, altı sene öncesine kadar tipik bir Java programcısı JMS, JTA, EJB, JAXB, JSF, JSP, JAX-WS gibi çeşitli Java çatılarına hakimliği ile övünebilirken, durum bugün çok daha değişik. İsmi geçen çatılar bugün bir Java programcısının repertuarında var olması gereken şeyler. Hepsine hakim olmak bir marifet değil, bir zorunluluk haline geldi, çünkü piyasa bir Java programcısından bunu bekliyor.

Durum sadece bununlu sınırlı değil. Artık JVM üzerinde çalışabilen dört yüze yakın programlama dili mevcut. Bunların başında daha önce ismini verdiğim Scala, Clojure, JRuby, Groovy ve Jython geliyor. Doğal olarak piyasada bu dilleri kullanarak geliştirilen proje sayısı göz ardı edilmeyecek kadar fazla. Twitter, LinkedIn ve FourSquare Scala dili ile geliştiriliyor. Bu durumda klasik bir Java programcısının bu dillere yönelme haricinde fazla bir alternatifi kalmıyor. Bu ekstra öğrenim yükü demek.

Bu durum sadece Java dilini kullanan programcılar için geçerli değil. Net platformunu kullanan programcılar da birçok değişilik ile baş etmek zorundalar. Aynı şey mobil programcılar için de geçerli. Programcılar gidişatı tam anlamıyla kavrayabilmek için ilgi alanlarına giren her şeyi tam teşekküllü takip etmek zorundalar. Bu programcının şimdilerde onlarca blog sitesini takip etmesi, yüzlerce kitap okuması, onlarca yeni programlama dili öğrenmesi anlamına geliyor. Programcının sahip olduğu bilgilerin yarı ömrü aylarla ölçülür oldu.

Bugün profesyonel programcı olarak çalışan insanların çok büyük bir kesimi imperatif dilleri kullanıyor. Bu dillerde eğitim aldılar ve tüm düşünce yapıları bu dillerin sunduğu yapılar üzerine kurulu. Bu programcıların çoğu bugünlerde büyük bir kültür şoku yaşıyorlar. Son günlerde fonksiyonel dillere olan ilgi çok artmış durumda. İmperatif bir dünyadan gelen bir programcının fonksiyonel dillere adapte olması ve anlaması kolay değil. Closure, lambda, higher order functions, functions as first class citizen, recursiv programming, pure functions gibi terimler imperatif programcıların kafasını karıştırmış durumda. Ama piyasa bu konseptleri anlamış programcılar istiyor. Er ya da geç imperatifcilerin fonksiyonel programcılık konseptlerine vakif olmaları gerekiyor. Programcılara yönelik beklentiler yükselmiş durumda.

İs görüşmelerinde de büyük bir değişimin yaşandığı bir gerçek. Eskiden piyasada programcı bulduklarında öpüp, başına koyan iş verenler, şimdilerde adayları intensif görüşmeler ve testler ardından işe alıyorlar ya da almıyorlar. İş bulmak zorlaştı, çünkü bir programcıda aranan vasıflar değişti. Artık CV’de yer alan kelimelere göre programcı alımları son bulmuş durumda.

İsteyenin parmağını kaldırıp, “Java kelimesinin nasıl yazıldığını biliyorum, ben programcıyım” diyerek iş buldugu devir artık son buldu. Günümüzde programcı olmak ve kendisini programcı olarak yetiştirebilmek çok güç bir hale geldi. Vakıf olunması gereken çok çesitli konu ve konseptler mevcut. Bu yeni süreç artık işine muazzam derecede hakim programcılar doğuracak. Bu işi kıvıramayanlar daha işin başında iken elenip, piyasadan uzak tutulacaklar, çünkü piyasada onların yapabileceği iş olmayacak.

Programcı olma çıtası on sene öncesine göre çok yükseldi ve yükselmeye devam ediyor. Bu güzel bir gelişme. Artık akla, karanın ayrıştığı bir dönemdeyiz. Programcılık hafife alınabilecek ve yarım yamalak bilgi ile yapılabilecek bir iş değil. Bu işi çalışma sahalarındaki her şeyi en ince detayına kadar anlamış, öğrenme kapasiteleri yüksek, değişikliklere adapte olan ve yeniliklerden çekinmeyen programcılar yapmalı. Çıtanın yükselmesi doğal bir seleksiyon yöntemi. Er ya da geç gerçekleşecekti. Bu işe gerçek anlamda gönül verenler ilerleyebilecek, para icin yapanlar ise çok kısa bir zamanda kendilerine baska çalışma alanları aramak zorunda kalacaklar, çünkü bu değişime ayak uydurmaları imkansız.

İyi programcıların ağaçta yetişmediği bir gerçek. Bir programcının iyi bir programcı olabilmesi için çok okuması, öğrenmesi, öğrendiklerini uygulaması ve yenilikleri takip etmesi gerekiyor. Bu vasıflara sahip olan programcıları tanımak zor değil. Sahip olmayanları da tanımak zor değil. Bu işin başında olanlar iş bulamayacak tezini savunmuyorum. Yaşadığımız bu gezegende bugün düne nazaran çok daha fazla programcıya ihtiyaç var. Ama bu ihtiyacın gözü eskisi gibi kör değil. Neyi, hangi tip programcıyı aradığını iyi biliyor ve seçimini ona göre yapıyor. Bu işe gönül verenler, bu işin başlangıcında da olsalar bu ihtiyaca her zaman cevap verebilecek yeteneklere sahip olacaklar. Zaman içinde bilgilerine bilgi, tecrübelerine tecrübe katarak çok daha iyi programcılar olacaklar. Çatının yükselmesi onlar için bir sorun olmayacak, çünkü çatıyı yükselten kendileri olacak. Gelecekte bu tip programcılar ile çalışmak çok ama çok zevkli olacak.

EOF (End Of Fun)
Özcan Acar

Organizasyonel Değişim

Yazılım camiasında son zamanlarda dikkat çeken bir değişim furyası var. Cevabı aranan soru şu: Yazılım ekibi nasıl daha verimli hale getirilebilir? Bu aslında organizasyonel bir değişimin gerekli olduğu bilincinin oluştuğu anlamına geliyor. Yöneticiler ekiplerini daha çevik hale getirmek için çeşitli yöntemlere başvuruyorlar. Bunların başında örneğin ekibin topluca eğitilmesi geliyor.

Her eğitim şüphesiz ekibe ve bireylerine bir şeyler katıyor. Ama bunu ölçmek çok zor. Bunun yanı sıra cevaplanması gereken bir soru daha var: Eğitim ile istenilen değişiklik sağlanabilir mi?

Alınan eğitimler değişimin sadece başlangıcı niteliğinde olabilir. Bunu yeni bir dil öğrenme süreci ile kıyaslayabiliriz. Öğrenilen her yeni kelime, kelime hazinesini genişletir. Pratik yapılarak kullanılmayan bir kelime hazinesi hiçbir şey ifade etmez ve değeri yoktur. Yazılım ekiplerinin tükettikleri eğitimler genelde sahip oldukları metot hazinelerini genişletmekle birlikte, bu metot hazinesinin günlük işlerde pratiğe dökülmemesi istenilen değişimi sağlayamamaktadır. Değişime gitme çabalarının son bulduğu nokta burasıdır.

Değişim yönetilmesi gereken bir süreçtir. Tesadüflere ve ekibin inisiyatifine bırakılabilecek bir şey değildir. Bir yazılım ekibi rasyonel düşünebilen, soyutlayabilen, problem çözme yetisi gelişmiş bireylerden oluşabilir. Ama unutmamak gerekir ki ekibi oluşturan bireylerin kendilerine has alışkanlıkları vardır. Değişim için gerekli baskı azaldığında ya da ortadan kalktığında bireyler bu alışkanlıklarına geri dönerler. “Ekip belli bir eğitimi aldıktan sonra artık çalışmalarını bu yönde adapte edecektir, dışarıdan müdahale etmeye gerek yok” şeklinde düşünmek bir yanılgıdır. Bu şekilde ekibin inisiyatifine bırakılan değişim süreci başladığı gibi son bulur.

Bunun örneklerini danışmanlık hizmeti verdiğim şirketlerde gördüm. Örneğin bir defasında yazılım sürecini daha çevik hale getirmek için ekibin test güdümlü yazılım eğitimi alması tavsiyesinde bulundum. Ekip gerekli eğitimi aldı. Ekip içinde test yazma duyarlılığı arttı, lakin ekibin hiç bir bireyi gerçek anlamda test güdümlü yazılım yapmadı. Kısa bir zaman sonra yazılımcılar eski davranış biçimlerine geri döndüler. Şimdi yine eskiden olduğu gibi kod yazıyorlar. İstenilen değişimin gerçekleşebilmesi için şu adımların atılması gerekir(di):

  • Değişim bir süreç olarak algılanmalı ve buna göre de yönetilmelidir. Bu birilerinin süreç gidişatından sorumlu olması anlamına gelmektedir. Değişikliğin meydana gelmesinden sorumlu olan bu şahıs ekipten gerekli geri bildirimi alarak, değişikliğin hangi safhada olduğunu takip etmek zorundadır. Bu geri bildirim alınması gereken önlemlerin tespiti ve planlanması açısından önem taşımaktadır.
  • Değişimin gerçekleşmesi için ekip içinde değişimin yaşanması gerekir. Ekip liderinin alınan eğitim sonrasında kazanılan yeni yetilerin uygulanmasını teşvik ve kontrol etmesi gerekir. Kendisi takım arkadaşlarına iyi bir örnek olarak, değişimi yaşadığı sinyalini vermelidir. Körle oturan, şaşı kalkar misali, ekip bireyleri liderlerini takip edip, değişimin vücut bulmasını sağlayacaklardır.
  • Ekip içinde bilgi ve becerilerin hızlı ve eşit bir şekilde dağılmasının en kolay şekli programcıları eşli programlama yapmasıdır. Eşli programlama programcıların kendilerini ve karşılıklı birbirlerini kontrol etmelerini mümkün kılar.
  • Değişimi getirecek sürecin doğru işleyip, işlemediğini kontrol etmek için ekip dışından destek alınmalıdır. Belli aralıklarla uzman bir koç gidişatın doğru olup, olmadığını kontrol edip, gerekli rota düzenlemesini yapabilir. Süreç tıkandığında da koç oluşan düğümleri çözecek ve değişime giden sürecin önünü açacaktır.
  • Değişim sürecinin tamamen durduğu anlardan birisi programcıların kriz anında eski alışkanlıklarına geri dönmeleridir. Bu ne yazık ki önlenmesi çok zor bir durumdur. Daha önceki bir yazımda bahsetmiştim. Kriz anlarında otomatik olarak devreye giren davranış biçimlerinin önüne geçmenin tek yolu pratik yapmaktan geçmektedir. Programcı kod kata ismi verilen kod pratiklerini devamlı yaparak, krizle ortaya çıkan verimsiz davranış biçimlerini zamanla beyninde silebilir. Kod kataları değişim sürecinin bir parçası haline getirilmelidir.

Yazılımcılar yetenekli insanlar. İstenilen bir şeyleri kavramaları uzun zaman almaz, lakin uygulamada zorluk çekebilirler. Yönetimin yazılım ekibine gerekli desteği sağlaması ve bu sorumluluğu onlarla paylaşması, değişimin daha kolay gerçekleşmesini kolaylaştıracaktır.

EOF (End Of Fun)
Özcan Acar

Türkiye Yazılımcı Raporu 2012

Bu rapor Kurumsaljava.com‘da hazırladığım yazılımcı anketinden edindiğim verileri ihtiva etmektedir. Ankete son beş ay içinde beş yüze yakın yazılımcı katıldı. Ankette yer alan soruları yazılımcıların çalışma yöntem ve süreçlerine, kullandıkları araçlara ve bu meslekten beklentilerine ışık tutacak şekilde şekillendirmeye çalıştım. Raporun bundan sonraki her sayfasında ankette yer alan bir soru ve bu soruya ankete katılan yazılımcıların verdiği cevaplar yer almaktadır.

Ankete katılıp, bu raporun oluşmasında emeği geçen yazılımcılara teşekkür ederim.

Özcan Acar
31.12.2012

  Yazılımcı Raporu 2012 (1,5 MiB, 9.925 yükleme)

Neden Fonksiyonel Programlamayı Öğrenmek Zorundayız

Daha dün gibi hatırlıyorum: Windows 95’in sahip olduğu işletim sistemi çekirdeğini (kernel) taskmanageri üzerinden şutlayabiliyordunuz. Akabinde tüm sistem çalışmaz hale geliyordu. Bu konularla ilgisi olmayanları kendine hayran bırakmak için fena bir yöntem değildi.

Bu bahsettiğim bilgisayarlar birkaç MB hafızası olan, tek bir işletim birimine (CPU) sahip, bir düğmesine basıldığında işletim biriminin çalışma hızını ikiye ya da üçe katlayan, bugünkü perspektiften bakıldığında taş devrinden kalma bilgisayarlardı. Geliştirilen uygulamalar da bu bilgisayarları limon gibi sıkıp, son hafıza hücresine ve işletim birimi döngüsüne (CPU cycle) kadar kullanmaya çalışırlar, ama kaynak yetersizliğinden dolayı bunda pek başarılı olamazlardı. Kısaca o zamanlarda kullanımda olan donanımın geliştirilen uygulamalar için yetersiz olduğunu söyleyebiliriz. Uygulamalar bir sonraki işletim birimi jenerasyonu ve daha fazla hafıza alanı ile hızlanır, bu donanımlarda geliştirilen uygulamalar aynı performansı göstermek için bir sonraki donanım jenerasyonunu beklemek zorunda kalırlardı.

Yazılımın hep böyle donanımı köşeye sıkıştırması, donanım mühendislerinin ışık hızı sınırlarına dayandıktan sonra, işletim birimlerinin hızını alıştıkları gibi artıramayacaklarını anlamaları ve çok çekirdekli donanım mimarisine yönelmelerine kadar devam etti. Bu noktaya gelene kadar yazılım mühendisleri donanım mühendislerine takılarak, “biz birden fazla işletim birimi varmış gibi programlarımızı yazarız, aynı işletim birimini paylaşarak çalışırlar ve en azından geliştirdiğimiz uygulamalar kullanıcıya birden fazla işletim birimi varmış gibi numara yaparlar” söylemleri ile yetindiler. Doğal olarak bu tür programlama tarzına alıştılar. Birden fazla işletim birimli sistemler çıktığında semaforlar ve threadler yardımı ile geliştirdikleri uygulamaları birden fazla işletim birimi üzerinde koşturmaya devam ettiler, eski program yazma stillerinden ödün vermeden, bunun gelecekte programcı olarak var olma ya da olmamanın cevabı olacağının farkına bile varamadan. Yazılımcıların çoklu thread (multithreading) uygulamaları geliştirmekte başarılı oldukları söylenemez. Günümüzde bile birçok programcı bir Java uygulamasında iki threadin senkronizyonunda zorluk çekmektedir.

Günümüzdeki kullanımda olan modern bir bilgisayarın en az iki ya da dört çekirdeği var. Bu yazıyı 2.8 GHz hızında, iki çekirdekli bir notebook üzerinde yazıyorum. Kullandığım işletim sistemi yükü eşit bir şekilde bu çekirdeklere dağıtmaya çalışıyor. Ne kadar başarılı olduğu tartışılır. Kullandığım bazı programlar birden fazla çekirdeğin üzerinde koşacak şekilde geliştirilmemiş. Bu yüzden beklenen performansı sağlayamıyorlar. Donanım mühendislerinin bir köşeden bizi izleyip “iki çekirdeği bile doğru dürüst programlayamıyorlar, kısa bir zaman sonra binli çekirdeklerle nasıl başa çıkacaklar acaba” dediklerini duyar gibiyim.

Bir uygulamanın optimal bir şekilde birden fazla çekirdeği kullanabilmesi için, uygulama parçalarının threadler yardımı ile birden fazla çekirdek üzerinde koşturulmaları gerekir. Bu çoğu zaman veri kaybını önlemek için threadler arası senkronizyonu zorunlu kılar. Java dilinde synchronized kelimesi ile birden fazla threadin aynı kod bloğunu koşturması engellenir. Bu tür bir sekronizasyon anlaşılması zor, komplike uygulamaların oluşmasına sebep verir. Tek bir thread ile istenilen tarzda bir davranış sergileyen bir uygulama, ikinci bir thread devreye girdiğinde çok başka bir davranış biçimi sergileyebilir. Böyle bir uygulamanın bünyesinde barındırdığı hataları debugging yöntemi ile keşfetmek çok zor bir hal alabilir. Kısaca bu tür uygulamaları geliştirmek, koşturmak ve hataları gidermek çok zordur ve çok az sayıda programcı bu durumlarla baş edebilecek yeteneklere sahiptir.

Kullandığımız imperatif (Java, C/C++, Python, PHP, Javascipt) diller thread senkronizyonu problemi haricinde başka bir sorunla karşılaşmamıza neden olmaktadırlar. İmperatif dillerde yapılan işlemler hafızada yer alan verilerin değiştirilmesi üzerine kuruludur. Bunun en basit örneği aşağıda yer alan Groovy kodunda görülmektedir.

[source language=’java’]
for(i in 1..10){
println(i);
}
[/source]

Groovy örneğinde for döngüsü başlatılmadan önce i ismini taşıyan bir değişken oluşturulur. Bilgisayarın hafıyasında i değişkeninin sahip olduğu değeri tutabilmek için 32 bit (bir int) uzunluğunda bir alan kullanılır. i nin başlangıç değeri 1 olduğu için, bu hafıza alanında yer alan değer 1 (00000000 00000000 00000000 00000001) olacaktır. Birinci döngü sona erdikten sonra i ye yeni bir değer atanır. Bu değer 2 rakamıdır. Değişkenin ismi değişmemiş olsa bile sahip olduğu değer değişmiştir. Bu imperatif dillerde sıkça karşılaştığımız bir değer atama işlemidir. Daha öncede belirttiğim gibi imperatif dillerde yapılan işlemler hafızada yer alan değerlerin değiştirilmesi üzerine kuruludur. Uygulama doğrudan hafızaya erişme (sadece kendi hafıza alanına) ve orada yer alan değerleri manipüle etme yetkisine sahiptir. İşlem gören her satır uygulamanın sahip olduğu anlık durumun (state) degişmesi anlamına gelmektedir.

Eğer i global bir değişken ve for döngüsü bir hata nedeniyle sonlanmış olsaydı, i kendisine atanan en son değeri korurdu. Örneğin i değişkeninin sahip olduğu değere bağımlı olarak başka bir threadin işlem yapmak için beklediğini farz edelim. i döngü içinde istenilen değere ulaşamadığı için diğer thread belkide hayatının sonuna kadar beklemek zorunda kalabilirdi. Tabi bazı programlama teknikleri ile bu gibi durumların önüne geçmek mümkün. Lakin görüldüğü gibi imperatif dillerde uygulamanın sahip olduğu anlık durumun koşturulan her kod satırı ile değiştirilebilir olması, bu durumun geçerliliğinin (consistency) korunmasını çok zor kılmaktadır. Aynı durum OOP’de kullanılan nesneler için de geçerlidir. Nesneler sınıf değişkenleri aracılığı ile belli bir duruma (object state) sahiptirler. Sahip oldukları metotlar aracılığı ile bu durum değiştirilebilir. Herhangi bir metot bünyesinde bir hatanın oluşması, sınıf değişkenlerine geçersiz değerlerin atanmasına ve böylece nesnenin korumaya çalıştığı durumun geçersiz hale gelmesine sebep verebilir.

Şimdi on ya da yirmi sene sonrasını hayal edelim. Binlerce çekirdeği olan bir işletim birimini geliştirdiğimiz imperatif tarzı bir uygulama nasıl optimal kullanabilir? Threadleri senkronize etmeye çalışarak bunu başarmamız mümkün değildir. Bu sebepten dolayı şimdiden binlerce çekirdeği olan bir işletim birimini optimal bir şekilde nasıl programlarız sorusuna cevap aramamız gerekmektedir. Aslında bu soruyu sorarak programcı olarak nasıl bir geleceğe sahip olacağımızın cevabını arıyoruz. Programcı olarak geleceğimizin nasıl şekilleneceği bu sorunun cevabında gizli.

Bahsettiğim problemleri aşmanın ve binlerce çekirdeği olan bir sistemi programlamanın yolu, değişkenlere tekrar, tekrar değer atamamaktan geçmektedir. Değişen değer senkronizasyonu mecbur kılmaktadır. Bu mecburiyet tüm çekirdeklerin aynı anda uygulama tarafından kullanılmasının önünde büyük bir engel teşkil etmektedir. Bu mecburiyeti ortadan kaldırmak için kullandığımız veri yapılarını değiştirilemez (immutable) hale getirmemiz gerekmektedir. Bu bir değişkene bir kere bir değer atandıktan sonra, bu değerin bir daha değiştirilemez olması gerektiği anlamına gelmektedir. Bu değişken uygulama son bulana kadar sahip olduğu değeri koruyabildiği taktirde, threadler arası senkronizasyon gerekliliği ortadan kalkar. Değişmeyen bir değer için senkronizasyon gerekli değildir.

Java gibi dillerde bir değişkene sadece bir kere değer atanması ve değişkenin bu değeri koruması final kelime ile sağlanabilir. final int i = 10; şeklinde bir tanımlama, daha sonra i=11; atamasının yapılmasına izin vermeyecektir. i her zaman 10 değerine sahip olacaktır. Bunun yanı sıra konstrüktör parametreleri aracılığı ile oluşturulan ve sınıf değişkenlerine set metotları aracılığı ile sonradan atama yapılmasına izin vermeyen nesneler değiştirilemez (immutable object) türdedir. Bu nesnelerin threadler arası paylaşımı hiçbir sorun teşkil etmez. Bu gibi yapılar thread güvenlidir (thread safe), çünkü içerikleri değişikliğe uğramaz/uğrayamaz.

Binlerce çekirdeği olan bir sistemi optimal şartlarda programlamanın yolu sonradan değiştirilemeyen (immutable) veri yapılarından geçmektedir. Peki bunun fonksiyonel programlama ile ne ilgisi var? Açıklayayım.

Fonksiyonel dillerde fonksiyonların sahip oldukları bazı özellikler şöyledir:

  • Fonksiyonlar metot parametreleri aynı olduğu sürece hep aynı neticeyi geri verirler.
  • Metot parametreleri fonksiyonlara pass by value mantığı ile verilir. Bu parametreler fonksiyon tarafından değiştirilemez. Fonksiyon yaptığı işlemin değerini geri verebilmek için yeni değişkenler oluşturur.
  • Fonksiyonlar kendi bünyeleri dışındaki hiçbir veri ya da durum (state) üzerinde değişiklik yapmazlar. Bu yüzden fonksiyonların yan etkileri (side effects) yoktur. Aynı fonksiyon durmadan koşturulsa bile hiç bir durum değişikliği olmaz.
  • Safkan fonksiyonel dillerde bir değişkene bir değer atandığı zaman, bu değer program son bulana kadar değişmez. Bu metot bünyesinde tanımlanan metot değişkenleri için de geçerlidir. Bu sebepten dolayı fonksiyonel dillerde for döngüsü içinde i değişkenine yeni bir değer atamak mümkün değildir. Değer atanmış bir değişkenin değeri değiştirilemeyeceği için yukarıda yer alan Groovy örneğini birebir fonksiyonel bir dilde yazmak mümkün değildir. Bunu gerçekleştirmek için fonksiyonel dillerde rekursiyon (recursive programming) kullanılır.
  • Bir fonksiyon geri verdiği değer ile birebir yer değiştirebilir. Bunun ne anlama geldiğini aşağıdaki Clojure örneğinde açıklamaya çalışacağım.

[source language=’java’]
(+ 1 1)
[/source]

Yukarıda yer alan Clojure örneğinde 1+1 işlemi yapılmaktadır. + burada kullanılan fonksiyonun kendisi 1 ve 1 bu fonksiyona gönderilen parametrelerdir. Parantezler kullanılarak fonksiyonun nerede başlayıp, kullanılan parametrelerin nerede bittiği ifade edilir.

5 + 9 / 4 * 2 işlemini gerçekleştirmek için Clojure dilinde şu şekilde bir fonksiyon yazabiliriz.

[source language=’java’]
(/ (+ 5 9 ) (* 4 2))
[/source]

Bu Clojure örneğinde 3 değişik fonksiyon kullanılmaktadır. Birinci fonksiyon / fonksiyonudur. Bu fonksiyona iki parametre verilmektedir. Birinci parametre 5+9 un neticesi olan 14 değeri, ikinci parametre 4*2’nin neticesi olan 8 değeridir. Yani yukarıda yer alan fonksiyonu şu şekilde de yazabilirdik:

[source language=’java’]
(/ 14 8)
[/source]

Görüldüğü gibi bir fonksiyon geri verdiği değer ile yer değiştirebilmektredir. Bu sadece ve sadece fonksiyonun işlem yaparken yan etki oluşturmaması ve aynı parametreler ile aynı neticeyi geri vermesi durumunda mümkündür. Eğer fonksiyon işlem yaparken durum (state) değişikliğine sebep vermiş olsaydı, yapılan durum değişikliğine göre (* 4 2) işleminde 8 değeri yerine başka bir değer geri alınabilirdi ki bu da bölme işleminin yanlış değerler kullanılarak yapılmasına sebep olurdu.

Paralel programlamanın önündeki en büyük engel kullanılan programlama dilinin hafıyaya doğrudan erişerek mevcut değişkenlerin sahip olduğu değerleri manipüle edebilmesidir. Uygulamanın her parçası hafızada yer alan değerleri herhangi bir zamanda değiştirebilir. Bu hem parallel programlamayı hem de uygulamanın anlık hangi durumda olduğunu öngörmeyi zorlaştıran bir durumdur. Değiştirilemez veri yapılarının (immutable data structures) kullanılması uygulamanın sahip olduğu anlık durumu (state) öngörülebilir hale getirmekte ve paralel programlama için gerekli altyapıyı sunmaktadır. Fonksiyonel dillerin değiştirilemez veri yapılarını temel olarak almaları, bu dillerin parallel programlamada daha avantajlı bir konumda olmalarını sağlamaktadır.

Gelecekte imperatif dillerin yanısıra fonksiyonel dilleri de sıklıkla kullanacağız. Donanımın geleceği parallelikte, yazılımcı olarak bizim geleceğimiz de bu paralelliğe nasıl hükmedeceğimizde. Bundan sonra geliştireceğimiz uygulamalar donanımın bize sağladığı her türlü kaynağı en optimal şekilde kullanacak yapıda olmalı. Bunun için yeni dönemde bizi bekleyen yeniliklere hazırlanmalıyız.

EOF (End Of Fun)
Özcan Acar

Nasıl Arkadaş Kazanır ve Diğer İnsanları Etkilersiniz

Dale Carnegie tarafından 1937 yılından yazılan How To Win Friends and Influence People (nasıl arkadaş kazanır ve diğer insanları etkilersiniz) başlıklı kitap her yazılımcının mutlaka okuması gereken ve güncelliğini günümüzde de koruyan çok değerli bir kaynak kitap.

Kitapta günlük hayatta takip edilmesi gereken bazı kurallar yer alıyor. Bunlar:

Kimseyi eleştirmeyin, yargılamayın ve şikayet etmeyin

Bir başkasını eleştirmek faydasızdır, çünkü eleştirilenin kendisini ve haklılığını savunmasını doğurur. Eleştirmek tehlikelidir, çünkü eleştirilenin onurunu incitir, kendisini kötü hissetmesini sağlar. Bir şeyleri eleştirerek, durumun daha iyileşmesini sağlamak mümkün değildir.

Taktiri hak edenlere bunu gösterin

İnsanların en önemli motivasyon kaynaklarından birisi taktir görmek ve kendini önemli hissetmektir. Büyük eserlerin, yapıtların ya da şahsiyetlerin oluşmasında en büyük rolü bu ihtiyaç oynamıştır/oynamaktadır. İnsanlar bu ihtiyaçlarını giderebilenlerin elinde hamur gibidirler. Hak ettiği için övülen ve taktir edilen şahıs bunu hiçbir zaman unutmaz.

Başkalarının içinde istek uyandırın

Bir bireyin istekleri diğer bireyleri ilgilendirmez. Her birey kendi istekleri ekseninde hayatına şekil verir. Bu sebepten dolayı insanları etkilemenin en kolay yolu onların istekleri hakkında konuşmaktır. Her bireysel hareketin temelinde bir istek yatar. İnsanları herekete geçirmek için içlerinde bu isteği uyandırmak yeterlidir.

Başkalarıyla ilgilenin

Baskalarıyla ilgilenenlere insanlar arası ilişkilerde her türlü kapı açıktır. İlgi çekmek için uğraş veren bir bireyin iki senede kazanamadığı arkadaşlıkları, başkalarıyla ilgilenen birisi iki ay içinde elde edebilir. Dost ve arkadaşlığın temelinde bu samimi ilgi yatar.

Gülümseyin

Gülümseme iyi niyetin göstergesidir. Gülümseme onu görenlerin gününü güzelleştirir. Gülümseme “size kanım kaynadı, beni mutlu ediyorsunuz, sizi gördüğüme sevindim” demektir.

Herkes için kendi isminin en hoş ve önemli kelime olduğunu unutmayın

Insanları kazanmanın en kolay yollarından birisi, isimlerini hatırlamak ve onur duymalarını sağlamaktır. İsimler insanları özelleştirir. İsimlerle birlikte gönderilen mesajlar daha başka anlam kazanirlar.

Bunlar gibi birçok tavsiye Dale Carnegie tarafından 1937 yılından yazılan How To Win Friends and Influence People (nasıl arkadaş kazanır ve diğer insanları etkilersiniz) başlıklı kitapta yer almakta. Okunulması tavsiye olunur.


EOF (End Of Fun)
Özcan Acar

Ayakta Alkışlıyorum

Geçen cumartesiyi pazara bağlayan gece, saat 00:00 civarı KurumsalJava.com, BTSoru.com, BizimAlem.com ve diğer web projelerimin üzerinde yer aldığı sunucuların erişilemez oldukları haberini aldım. Akabinde gecenin bir yarısı hizmet aldığım ISP’nin yolunu tuttum. Tam, tamına 4 senedir bir düğmesine bile basmadığım, bu kadar zaman sorunsuz çalışmış olan firewall sistemlerinin neden çalışmadıklarını incelemeye başladım. Bugüne kadar birçok DOS saldırısına karşı koymuş ve çalışmaya devam etmiş bu sistemlerin bir DOS saldırısı sonucu tıkanmış olabileceklerine ihtimal vermedim. Aslında firewall sistemlerinin işletim sistemlerini en yeni versiyona çekmem gerekiyordu. Fırsat bu fırsat dedim ve gerekli kurulum ve ayarları yaptım. Pazar sabahı saat altıya doğru tekrar evimin yolunu tuttum.

Yaptığım müdahale hiçbir şey değiştirmedi. Sunucular pazar günü öğleden sonra tekrar erişilemez oldular. Bu işte başka bir şey olmalı diye tekrar ISP’nin yolunu tuttum ve firewall sistemlerini canlı yayında yakından takip etmeye başladım. Kısa bir zaman sonra bu sistemleri tıkayan sebebin bir DOS saldırısı olduğunun farkına vardım. 80/100 m/bit boyutunda olan bir DOS saldırısı ile router ve firewall sistemlerini erişilemez hale getirmişlerdi. Firewall ve router sistemleri üzerinde DOS saldırılarının kaynağı olan network segmentlerinin (188.0.0.0/8) sunuculara erişmesini engelledim.

Aldığım bu son önlem karşı tarafı daha da kızdırmış olacak ki dünden beri 3 g/bit kapasitesinde DDOS saldırıları başlatılmış. Biraz önce sunucularımın barındığı ISP’nin administratörlerinden birisi beni arayarak, durumdan haberdar etti. ISP’nin benim yer aldığım network segmenti tamamen offline olmuş durumda.

Çok uzun zamandan beri, özellikle BizimAlem.com web platformu ile Türk hackerlerin saldırılarına mağruz kalıyorum. Bir şekilde hepsine sistemi daha güçlü hale getirerek cevap verdim. Bu gibi şeylerle muhattap olmak benden çok sinir aldı götürdü, ama bilgi olarak ta birçok şey kattı. Ama artık saldırıların boyutu o kadar değişti ki, karşı taraftaki şahıslar koca bir ISP’yi dize getirebiliyorlar. Bu sebepten dolayı bu yazının başlığında da yer aldığı gibi bu şahısları ayakta alkışlıyorum. İnsanlığa, vatana, millete o kadar çok büyük emek, fayda ve katkıları var ki, kendilere mutlaka bir onur madalyası verilmeli.

Benim internet girişimciliğinde son on yılda edindiğim tecrübeler şöyle:

  • Meyva veren ağaç taşlanıyor. İnternette göze batan bir büyüklüğe eriştiğiniz zaman, sizin tekerinize çomak sokmak isteyen birçok insan ortaya çıkacaktır. Bu insanlar istedikleri taktirde çok emek harcayarak oluşturduğunuz bir web platformunu kısa bir zamanda çalışmaz hale getirebilirler. Bunun için Rusya’dan ya da Türkiye’den birkaç hacker bulmaları yeterli. Buradan çıkardığım sonuç şu: internet girişimciliği gerçek hayattaki bir girişimden yüzlerce defa daha rizikolu. Bu hem başarıyı yakalamak için, hem de yakalanan başarıyı korumak için geçerli.
  • Günümüzün internet altyapısı, özellikle TCP/IP protokolü web platformlarını ve yapılan yatırımları korumak için yeterli değil. Bunun kısa bir zamanda değişeceğini de düşünmüyorum. İnternet girişimciliği rus ruletinden farklı bir şey değil.
  • Bazı şahıslar kişisel başarısızlık, pisilojik bozukluklar ve toplum tarafından dışlanmış ya da kabul edilmemiş olmak gibi faktörleri kompanze etmek için bahsettiğim türde internet saldırılarını gerçekleştiriyorlar. Başkalarına zarar vermekten büyük zevk alan bu şahıslara internet mazohistleri diyorum. Çok az bir mantık ve zeka ile böyle uğraşıların ne kendilerine, ne de başkalarına bir fayda getirdiğini anlamaları zor değil. Ama ne yazık ki bu yetilerden mahsunlar. Onlar karanlık odalarından bu saldırılara devam edecekler ve insanlıktan nasiplerini alamadan ebediyete intikal edecekler, bizler de ebediyete intikal edene kadar bu şahıslara karşı dik durmaya devam edeceğiz. DevOps olarak görevimiz bu.
  • Sunucuları istediğiniz kadar koruyun, onları erişilmez hale getirmek için mutlaka bir yöntem mevcuttur. Birileri sizden bilgi olarak mutlaka bir, iki adım önde olacak ve fırsatını bulduğu anda sunucuları kendi kontrolüne geçirmeye ya da erişilemez olmalarını sağlamaya çalışacaktır. Bu internetin değişmez bir kanunu. %100 korunma imkansız.
  • Bu tür saldırıların kimin marifeti olduğunu öğrenmeniz imkansız. Bu sebepten dolayı yasal yoldan hakkınızı aramanız mümkün değil.

  • Bu tür saldırılar bir yazılımcıyı bir DevOps (development/operations; hem program yazan, hem uygulamayı sunucularda işleten anlamında) haline getiriyor.

Neden böyle bir yazı yazdım? Saldırıları yapanlar haberdar olsunlar ve saldırıları durdursunlar diye mi? Hayır, böyle bir amacım yok. Kimin, hangi sebepten dolayı böyle bir şeyi yaptığı beni pek ilgilendirmiyor. Ben daha ziyada edindiğim tecrüleri, konuyla ilgilenen okurlarımla paylaşmak istedim. Eğer internet girişimci iseniz ya da internet girişimcisi olmak istiyorsanız, sizi bekleyen bazı sürprizler var. Hazırlıklı olmanızda fayda var.

EOF (End Of Fun)
Özcan Acar

Copy/Paste Programcı

Internetin bu kadar büyümesi ve özellikle Google gibi arama motorlarının günlük iş hayatımızın bir parçası haline gelmesi biz programcılar için ne kadar hayırlı oldu, bilemiyorum. Pek te hayırlı olmadığı kanısındayım. Açıklamaya çalışayım.

Çalıştığım projede bir çalışma arkadaşımın masasında algoritmalarla ilgili kalınca bir kitap gördüm. Havadan, sudan konuşurken kendisi böyle kitapların artık gereksiz olduğunu, çünkü internette istediğin algoritmayı bulup, kullanabildigini söyledi. Doğru, haklıydı.

Bugünlerde Pratik Spring Core 3 isminde yeni kitabım üzerinde çalışmalarımı sürdürüyorum. Spring ile XML bazlı deklaratif transaksiyon yönetimi konfigürasyonu nasıl yapılır diye internette araştırma yaparken, birkaç klasik blog sayfasına rastladım. Bu klasik blog yazılarını tanırsınız. Basit bir örnek üzerinde belli bir konfigürasyonun nasıl yapıldığını gösterirler. Bu örnekleri copy/paste yaparak programcının kendi uygulamasına eklemesi zor değildir. Zamanında az yapmadık. Copy/paste işlemi esnasında insan keşfettiği örneğin altındaki konseptlerin ne olduğunu sorgulamıyor. Programcı için önemli olan bir şeyleri çalışır hale getirebilmek. Ve bunu başardıktan sonra, “ya, bunu çalışır hale getirdim ama, bu işin temelindeki konseptler nelerdir” şeklinde bir sonuca varmıyor ya da varamıyor. İşte internet üzerinden bilgiye bu kadar hızlı, sorgusuz ve sualsiz erişmenin getirdiği hayırsızlıkta bu noktadan itibaren başlıyor. Programcı bir bilgiyi edindi ve kullandı. Ama o bilginin neyi temsil ettiğini, yani temelinde neler olduğunu bilmiyor. Spring ile XML bazlı deklaratif transaksiyon yönetimi konfigürasyonu örneğinde 3 satırlık copy/paste edilen XML konfigürasyonunun altında AOP (Aspect Oriented Programming) ve Proxy tasarım şablonu gibi konseptler var. İki satırlık konfigürasyonu kopyaladım, ama temelinde yatan bu bilgileri kopyalayamadım. Bunlar internette kalmaya devam etti. Benim kopyaladığım cansız, iki satırlık kod parçası.

Kod örneğiyle, kodun temelindeki konseptlerin zahmetsiz bir şekilde beyne nasıl kopyalandığını Matrix filmede gördük. Neo anında Karate-Kid olmuştu. Bizim böyle bir imkanımız yok. Böyle bir şeyin gelecekte mümkün olacagını da düşünmüyorum. Geriye kalan, kaynağını bulup, copy/paste yaptığımız bilgilerin temelinde yatan konseptleri ögrenmek ve uygulamak. O zaman hayırsız olarak tabir ettiğim işlemi hayırlı bir işleme dönüştürebiliriz.

Copy/paste zihinlere o kadar yerleşmiş ki, bilgiye sahip olmanın değil de, bilgiye nasıl ulaşabileceğini bilmenin daha önemli olduğunu savunanlar var. Bu artık copy/paste filozofisinin mükemmelleştirilerek, getirildiği en son noktadır, yani bu akımın en tepesindeki noktadır. Bu filozofiye sahip olanların, iş görüşmelerinde bu tür ifadelerde bulunmamalarını tavsiye ediyorum, çünkü iş verenin en sevmediği ve iş görüşmesini anında sonlandırabileceği durumların başında, iş görüşmesi yaptığı şahsın “ufak bir internet araştırması ile bu sorunu çözebilirim” tarzı söylemlerde bulunmasıdır. Böyle bir şey söyleyen şahıs aslında “ben bu bilgiye sahip değilim, başkaları sahip, ama bir bakayım, bakalım, bir yerlerden bulabilir miyim” demektedir. Böyle bir şey söyleyen bir programcıyı siz olsanız işe alır mıydınız?

İyi bir programcı olabilmek için iyi bir temele sahip olmak gerekir. Bu temel edinilmiş ve zaman içinde edinilen bilgiden oluşur. Programcı tüm yeteneklerini bu temel üzerine inşa eder. Zaman zaman internetten bir şeyleri copy/paste etmek suç ya da günah değildir. Bu hepimizin yaptığı bir şeydir. Lakin programcı copy/paste yaptıktan sonra, copy/paste yaptığı kod parçasının temelinde yatan bilgiyi sahip olduğu temele eklemekle yükümlüdür. Aksi taktirde bu bakkaldan bir sakız alıp, parasını ödememek gibi bir şey olur. Copy/paste yapılan şeyin bedeli ödenmelidir. Copy/paste edilen kodun üzerinde fiyat etiketi olmadığı için beleş sananlar vardır. Hayır, beleş değildir. Bedeli ödenmeden kullanılan bilgi, temeli sağlam olmayan bir binanın en ufak bir rüzgar esintisinde sallanması misali programcıya zarar verir.

Copy/paste yapalm, ama bedelini ödeyerek…

EOF (End Of Fun)
Özcan Acar

Test Edebilme Uğruna Her Şey Mübahtır!

Geçenlerde yine tartışması yapılıyor: private olan metotları nasıl test ederiz? Benim cevabım: “edemeyiz!” Karşıdan gelen cevap: “dediğim gibi, her şeyi test etmek mümkün değil demek ki!“. Benim cevabım: “her şeyi test etmek mümkün, private’i protected yaparsın, olur, biter.” Karşı tarafın cevabı: “kardeşim ortada OOP diye bir şey var, kafana göre nasıl öyle private bir metodu proteted yaparsın?“. Yaparım canım kardeşim. OOP’yi filan takmam! Protected‘de yaparım, public‘de. Bir sınıfı test edebilmek için her türlü yöntemi kullanırım, gözünün yaşına bakmam. Bu uğurda her şey mübahtır.

Bu bazıları için çok radikal bir yaklaşım tarzı gibi görünebilir. Ama uygulama çalışırken bir sebepten dolayı patladığı zaman kimse gelip size, bu sınıfı neden OOP’ye uygun tasarlamadınız diye sormaz. Bu sınıf neden patladı, sizin testleriniz yok mu diye sorar! O zaman da “bu metot private idi, o yüzden test yazamadım” mi diyeceksiniz? Pek ikna edici değil, değil mi?

Bir uygulama geliştirken bir kod biriminin test edilebilirliğinin önündeki engel OOP prensipleri olmamalıdır. Eğer öyle ise, OOP prensipleri yanlış uygulanmış demektir. OOP kod geliştirmek için kullanılan bir araçtır. private yerine göre kullanılabilecek bir erişim mekanizmasıdır. Lakin private olan bir metot benim için yoktur, yani test edilmesi mümkün değildir. Benim için test edilemeyen kod birimi olamayacağı için, private ile tanımlanmış metotları yok sayarım. Test edilemeyen bir metodun başına her türlü iş gelebilir. Benim bu tür metotları görünce ilk yaptığım şey, metodu hemen protected yapmak ve o metodu izole bir şekilde test eden bir birim testi yazmak olur. Protected yetmedi ise public yaparım. Nihai amaç metodu bir şekilde test edebilmektir.

Ne test edilir, ne test edilmez, nasıl test edilir tartışmalarının sonu gelmez ne yazık ki. Geçenlerde yine kocaman, ne yedüğü belli olmayan bir sınıfa yeni bir özellik eklemem istendi. Eğer gerekli kodu o sınıfa direk ekleseydim, yeni eklediğim kod birimini test etmem çok zor olacaktı, bunu biliyordum. Sınıfın tümünü test edecek bir birim testi oluşturmak için vaktim yoktu. Bende bunun yerine yeni bir static iç sınıf oluşturup, kodu bu sınıfın bir metodu olarak geliştirdim ve bir birim testi ile test ettim. Testin başarılı olduğunu gördükten sonra ne yedüğü belirsiz diye tabir ettiğim sınıfın gerekli metoduna oluşturduğum yeni sınıfın bir nesnesini yerleştirerek, static sınıfın metodunu orada koşturdum. Böylece ne yedüğü belirsiz sınıf dolaylı bir şekilde yeni oluşturduğum kod birimine sahip oldu. Doğal olarak gelen ilk soru şu oldu: “neden static bir iç sınıf oluşturdun ki? Orada bu işi görecek bir metot vardı, o metoda kendi kodunu ekleyebilirdin“. Eklerdim, eklemesine, lakin bu sınıfa eklediğim kodu nasıl test edebilirdim? Edemezdim. Sınıf için daha önce hiç birim testi yazılmamıştı. Sınıfa eklediğim kod birimini test edebilmek için tüm uygulamayı ayağa kaldırıp, benim eklediğim kod birimi çalışıyor mu diye otomatize edilemeyecek türden bir test yapmam gerekirdi. Yok efendim. bu tür yöntemler sınıf enflasyonuna sebep oluyormuş. Olursa, olsun, sorun nedir? Önemli olan benim yeni kod birimini izole bir şekilde test etmemdi.

OOP, tasarım şablonları ya da tasarım prensipleri sadece test edilebilirliğin emrinde çalışabilecek erlerdir, tersi değil! Bu saydığım araç, gereçlerin hepsinin efendisi test edilebilirlik özelliğidir. Bunların arkasına saklanıp, bu kod birimi test edilemez diyen yazılımcı kendisine ve müşterisine ihanet içinde olur.

EOF (End Of Fun)
Özcan Acar

Deneme Yanılmanın Bedeli

Yazılım yaparken en büyük zaman kaybının nedeni, kodu değiştirip, derleyip, çalışır hale getirdikten sonra değişikliğin sonucunu test etmektir. Kodu değiştir/derle/çalıştır/dene süreci otuz saniyeden beş dakikaya kadar sürebilir. Günde bunu on sefer yaptığınızda bir saatlik bir zamanı boşa harcamış olursunuz. Bu sebepten dolayıdır ki EJB2 ve benzeri teknolojilerin yerine Spring gibi daha hafif yazılım yapmayı sağlayan çatılar (framework) oluşmuştur.

Çoğu programcı yılmadan kodu değiştir/derle/çalıştır/dene döngüsünde programlamaya devam ediyor. Büyük bir inatla, akıl almaz derecede komplike olan algoritmaları deneme, yanılma usulü ile geliştirmeye ya da değiştirmeye çalışanlar var. Neymiş efendim, bir sonraki döngüde çalışacakmış… Murphy’nin kuralları gereği yapılan değişikliğin beklenen neticeyi getirmeme ihtimali çok yüksek. Ve böylece programcı hiç farkına bile varmadan dönme dolap içinde dönüp, duran bir fare misali hayatını devam ettirir….

Aslında böyle durumlarda beyinde tehlike çanları çalmaya başlayıp, programcının içinde bulunduğu kısır döngüyü aşması için gerekli rutinlerin çalışması gerekir. Mesela bu rutinlerden bir tanesi “hemen kodu test eden bir birim testi yaz” olabilir. Bir birim testi bahsi geçen kod birimini izole edilmiş halde çok hızlı bir şekilde test etmek için kullanılabilir. Yapılan değişikliğin neticesini görmek bir saniye bile sürmeyecektir. Gerekli değişiklikler yapıldıktan sonra ayrıca bonus olarak bir birim testine sahip olunur. Daha sonra yapılması gereken değişiklikler birim testi sayesinde çocuk oyuncağı haline gelir. Zaman ayrılıp, mutlaka böyle bir yatırım yapılmalıdır, aksi taktirde deneme, yanılma tarzı programlamanın bedeli çok daha ağır olacaktır. Sözüm tabi verimliliğim düştü derdinde olmayanlara değil.

“Hemen test yaz” vari bir rutinin devreye girebilmesi için iki şeye ihtiyaç duyulmaktadır:

  • Böyle bir rutine sahip olmak.
  • Rutini zamanı gelince otomatik olarak tetiklemek.

Bu rutini çalıştırabilmek için bu rutine sahip olmak gerekiyor. Böyle bir rutine nasıl sahip olunabileceğine Kod Kata ve Pratik Yapmanın Önemi başlıklı yazımda değinmeye çalıştım. Bu işin sırrı devamlı pratik yapmaktan geçiyor. Pratik sahibi olan bir programcının aklına ilk gelen şey “ya ben neden bir birim testi yazmıyorum da, burada taklalar atıyorum” olur. Basit gibi görünen bu beyin performansını sağlayabilmek için beyni bu yönde eğitmek gerekiyor. Bunun yolu da kod katalarından geçiyor. KodKata.com‘a bir göz atmanızı tavsiye ederim.

Deneme, yanılma tarzı programlama hem insanı yorar, hem usandırır, hem de bir zaman sonra bıkkınlık verir. Ayrıca bu tarz programlamanın yazılım mühendisliği ile yakından, uzaktan ilgisi yoktur. Mühendis olmak demek yol, yordam bilmek demektir, metotlu, yöntemli çalışmak demektir. Çaylak gibi bilgisayar başına geçip, deneme, yanılma tarzı programlama yapan yazılımcıya gülerler. Profesyonel programcı hemen çekmecesinden ihtiyaç duyduğu aracı, yani birim testi yazma yetisi, çıkarır ve sorunu en kısa sürede daha önce etkinliliği milyarlarca defa kanıtlanmış bir yöntemi kullanarak çözer. Yol, yordam bilmek budur. Profesyonel yazılımcıya yakışan budur.

EOF (End Of Fun)
Özcan Acar

Uzaktan Eşli Programlama

Eşli programlama yapmak için illa iki programcının aynı mekanda olması gerekmiyor. Eclipse kullanıyorsanız Saros pluginini kurarak, uzak bir bilgisayardaki bir şahıs ile eşli programlama yapabilirsiniz.

Uzaktan eşli programlama için neler gerekli?

Eclipse >> Help >> Install new Software menüsünden http://dpp.sourceforge.net/update Saros update sayfasını kullanarak gerekli plugini kurabilirsiniz.

Kurulumun nasıl yapıldığı Saros kurulum sayfasında yer almaktadır.

Kurulum işlemi tamamlandıktan ve Eclipse kapatılıp, yeniden açıldıktan sonra yukarıda yer alan login paneli görünecektir. İki programcının beraber aynı proje üzerinde çalışabilmeleri için aynı sunucuya bağlantı kurmuş olmaları gerekmektedir. Saros sunucu olarak bir Jabber sunucusu kullanıyor. Yeni bir hesap oluşturduktan sonra sunucuya bağlanabilirsiniz.

Eşli programlama yapmak istediğiniz şahsın Saros hesabını edinmeniz ve aşağıda yer aldığı gibi Saros paneli üzerinden Buddy listenize eklemeniz gerekiyor.

Buddy ekleme işlemi tamamlandıktan sonra eğer Buddyniz online ise, herhangi bir Eclipse projesini karşı taraf ile paylaşıp, eşli programlamaya başlayabilirsiniz. Proje üzerinde yaptığınız her değişiklik anında karşı tarafa yansıyacaktır.

Ben bu altyapıyı genelde uzakta bir bilgisayar kullanan bir programcı ile beraber kata yapmak için kullanıyorum. Kata seansında iletişimi kolaylaştırmak için Skype kullanılabilir.

Benimle kata yapmak isterseniz koordinatlarım şöyle:

Saros hesabım: ozcanacar@saros-con.imp.fu-berlin.de
Skype hesabım: oezcanacar

Bana bir e-posta gönderin ve hangi katayı benimle birlikte eşli programlama yöntemi ile yapmak istediğinizi bildirin. Birlikte bir zaman dilimi bulmaya ve katayı yapmaya çalışalım.

EOF (End Of Fun)
Özcan Acar

Veresiye Satan Yazılımcı

Editörü açtınız, public class yazarak yeni bir sınıf oluşturdunuz. Bu sınıfa yeni bir metot eklediniz. Başka bir şey yapan yeni bir metot daha eklediniz. Sınıf yavaş yavaş şismeye başladı. Birkaç refactoring yaptınız. Buradan yeni bir sınıf dünyaya gözlerini açtı. Bir sınıf, bir sınıf daha derken sınıf sayısı onlara ulaştı. Her sınıfın metot küfesi iyice ağırlaşmaya başladı. Göz açıp, kapayana kadar birkaç bin satır kod oluştu. Program istediğiniz şekilde çalışıyor sanırım. Yaptığınız işten memnunsunuz, ama içinizden bir ses bir şeylerin doğru gitmediğini söylüyor. Eksik olan ne? Testler!

Yazılımcı neden test yazmaz? Sıralayalım:

  • Uygulamayı test etme konseptlerinden bihaberdir.
  • Test etmeyi gerekli ve işinin bir parçası olarak görmez.
  • Test etmeyi angarya ya da zaman kaybı olarak görür.
  • Geliştirdiği uygulamanın test edilemez olduğunu düşünür.
  • Test etmek için zamanı yoktur.
  • Daha sonra test yazarım diyerek kendini avutur.
  • Testlerin yazılımcı olmayan şahıslar tarafından yazılmasını sağlamak için lobi çalışması yapar.
  • Testlerin devamlı bakıma ihtiyacı olduğunu ve bu yüzden verimli olmanın önünde engel olduklarını düşünür.

Bir yazılımcının görevi nedir? Sıralayalım:

  • Altına tereddüt etmeden ismini yazıp, imzalayacağı, çalışır, hatasız ve kaliteli bir sürüm ortaya koymak.
  • ve daha birçok başka şey.

Yazılımcı test yazmadığı zaman ne olur? Sıralayalım:

  • Devamlı oluşan hatalarla boğuşur.
  • Kodu yeniden yapılandırma cesaretine hiçbir zaman sahip olamaz.
  • Yeni müşteri gereksinimlerini kodlamakta zorlanır, çünkü yeniden yapılandırılamayan kodun değiştirilmesi güçtür.
  • Sürüm çıkardıktan sonra birkaç gece uyuyamaz.
  • Hataları gidermek için fazla mesai yapmak zorunda kalır.
  • Uygulamanın her yeni sürümü ile hata sayısı çoğalır, kod kalitesi düşer.
  • Yaptığı işten zevk almamaya başlar.
  • İşini tam olarak yapmadığını bildiği için vicdan azabı çeker.

Veresiye satan tüccar ile peşin satan tüccarın hikayesini bilirsiniz. Veresiye satanın sonu malumdur. İşi başından sıkı tutmadığı için batma aşamasına gelir. Test yazmayan programcının da durumu aynıdır. Projenin geleceğini veresiye dağıtır.

Siz veresiye mi satıyorsunuz, peşin mi?

EOF (End Of Fun)
Özcan Acar

Uzman ve Usta Yazılımcı Arasındaki Fark

Fanatik futbol severleri bilirsiniz. Takımları için yapmayacakları yoktur. Bu fanatiklik başka insanlara zarar vermeye kadar varabilir. Yazılımda da durum farklı değildir. Tek fark bu fanatikliğin insana zarar verecek seviyede olmamasıdır.

Çok duymuşsunuzdur Java dili şöyle, Java dili böyle, diğer dillerden üstündür… diye. Neden bazı yazılımcıların böyle fanatizm olarak görülebilecek bir ilgi ve alaka ile bazı bilişim öğelerine bağlandıklarını biliyor musunuz? Bu yazımda bu soruya cevap vermeye çalışacağım.

Bilişim ya da yazılımda fanatik olanlar savundukları konu hakkında uzman ya da uzman olduklarını düşünen şahıslardır. Yıllar süren çalışmalar sonunda örneğin bir programlama diline uzman seviyesinde hakimdirler. Sahip oldukları fanatizm ile savundukları konu hakkında yıllar süren çalışmalar ardından yoğun bilgi, tecrübe ve beceri sahibi olmuşlardır. Kısacası bu konuda uzmanlaşmışlardır. Fanatik bir biçimde kendilerini ifade etmeye çalışmalarının altında gizli olan iki şey vardır: Birincisi sahip oldukları bilgi, tecrübe ve beceriyi ortaya koymak istemeleri, ikincisi farkında olmadan yeniliklere açık olmadıklarını ifade etmeleri.

Bir konuda uzmanlık ne yazık ki çok uzun sürebilecek bir bağımlılığı beraberinde getirebilir. Bu insanda zaman içinde sahiplenme hissi doğurur. Çok emek harcayarak bir yerlere geldiğini düşünen şahıs için savunduğu konu kutsallaşır. Bu durum savunma ve koruma güdülerini tetikler. Buradan da tanıdığımız ve hoşumuza gitmeyen verimsiz tartışmalar doğar. Belli bir programlama dilinin fanatikçe savunulduğu tartışmaların kimseye bir şey katmayacağını çok iyi biliriz. Ama bu fanatizm yine de bir son bulmaz. Devam eder gider, çünkü yazılımcı uzman olmaya devam eder, çünkü usta olmanın ne olduğunu kavrayamamıştır.

Tipik bir uzmanın bir çalışma ömrü boyunca aynı programlama dilini kullandığını görmek mümkündür. Uzmanlık sıfatı ne kadar olumlu görünsede, bahsettigim sebeplerden dolayı sakınılması gereken bir durumdur. Bir uzman yazılımcı at gözlüğü takmışcasına hayatın içinden geçer, gider, kişisel gelişim için gerekli nimetleri edinemeden. Kendisini bir konuya adadığı için, bu konunun modası geçtiğinde ortada kalıverir. Hakim olduğu konu haricinde yeni bir şeyler öğrenme yetilerini geliştirmeği için iş hayatının son bulması teklikesi ile karşı karşıya kalabilir. Buraya kadar yazdıklarımdan bir konuda uzman olmaya sıcak bakmadığımı düşünebilirsiniz. Bir değil, birden fazla konuda uzmanlığı tercih ederim. Bunun yazılımdaki karşılığı uzman değil, usta yazılımcı olmaktır.

Usta bir yazılımcının öz geçmişine göz attığınızda, onlarca programlama dilini kullandığını görürsünüz. Hepsinde uzman olup, olmadığı tartışılır. Lakin bu onun uzmana nazaran değişikliklerle daha iyi yaşayabildiği anlamına gelmektedir. Zaman ve mekan neyi gerektiriyorsa, o konuyu seçerek, konu üzerinde çalşır ve zamanla uzmanlaşır. Geniş bir perspektife sahip olmasının sebebi buradan kaynaklanmaktadır. Çok değişik dil, teknoloji ve platformlarla çalışmak daima onun ufkunu genişletir. Bu onun günlük işlerine olumlu olarak yansır. Bu ona pragmatik olmayı öğretir. Bu ona teknoloji fanatiği olmamayı öğretir. Uzman ve usta yazılımcı arasındaki fark budur!

EOF (End Of Fun)
Özcan Acar

İzci kuralı

Her izcinin uyduğu bir kural vardır:

“Kamp yaptığın yeri bulduğundan daha iyi bir şekilde bırak!”

Yazılımcı olarak bu kuralı uygulamak istediğimiz taktirde, mevcut yazılım standartlarına uymayan kod birimlerini tereddüt etmeden yeniden yapılandırarak, uygulamanın bakılabilirliğini ve geliştirilebilirliğini artırmamız gerekir.

Usta bir yazılımcının geride bıraktığı kodun kalitesi, işe başladığında bulduğu kodun kalitesinden her zaman daha iyidir.

EOF (End Of Fun)
Özcan Acar

Sorumluluk Sahibi Olmak

Yazılım yapmayı zorlaştıran her zaman kod birimleri arasındaki bağimlılıklar ve bu bağımlılıkların yönetimi olmuştur. Bu bağımlılıkları tamamen yok etmek yazılım sistemini anlamsız kılarken, kontrolden çıkmalarına göz yummak yazılım sisteminin ölüm fermanı olabilir. Yazılım mühendisi bunu bilir ve gerekli gördüğü yerlerde DIP, ISP ve SRP gibi tasarım prensiplerini kullanarak kodu dokur.

Yazılımcının kod yazarken devamlı uygulaması gerektiği bir tasarım prensibi varsa, bu da SRP (Single Responsibility Principle) tek sorumluluk prensibidir. Bu prensibe göre her kod biriminin sadece ve sadece bir sorumluluk alanı, yani yaptığı tek bir iş olmalıdır. Bu kod birimi bir paket (package), bir sınıf, metot ya da bir değişken olabilir. SRP uygulanmadığı taktirde yazılım sistemi kontrol edilemez, kırılgan bir bağımlılıklar yumağı haline gelebilir.

Genelde bir bakışta bir kod biriminin SRP uyumlu olup, olmadığını anlamak zor değildir. Eğer bir sınıf iki bin satırdan oluşuyorsa, bu sınıfın birden fazla işle meşgul olduğu söylenebilir, aksi taktirde bu kadar büyümesi mümkün olmazdı.

Büyük yazılım sistemlerini sınıf sınıf gezip, kim SRP uyumlu, kim değil diye kontrol etmek mümkün değil. Yazılımcı olarak daha ziyade anlık resmi görmemizi sağlayacak bir araç oluşturmamız lazım. Bu aracı geliştirmeden önce, sınıfların SRP uyumluluklarını ölçmek için bir yönteme ihtiyacımız var. Bu yöntem örneğin bir sınıfın versiyon kontrol sistemi bünyesinde ne kadar değişikliğe uğradığını ölçebilir. Eğer bir sınıf sıkça değişikliğe uğruyorsa, bu bu sınıfın birden fazla sorumluluk sahibi olduğu anlamına gelebilir. Gerçekten de binlerce satırdan oluşan kod birimlerinin versiyon kontrol sistemindeki geçmişleri incelendiğinde, çok sık değişikliğe ugradıklarını görmek mümkündür. Değişik sorumluk sahibi bir sınıf, her bir sorumluluk için değişikliğe maruz kalabileceğinden, bu gibi sınıfların sicilleri kabarıktır. O zaman bu sınıfları, kaç satır ihtiva ettiklerini ve kaç sefer değişikliğe uğradıklarını tespit edebilecek bir uygulama geliştirelim. Böyle bir uygulamanın kodu aşağıda yer almaktadır.

[source language=’java’]
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

public final class SvnHistory {

private static final String PROJECT_ROOT = “C:/xxx”;
private static Map STATS_MAP = new HashMap();
private static StringBuilder STATS = new StringBuilder();
private static final String SVN_EXE = “C:/Program Files/SlikSvn/bin/svn.exe”;
private static final String SVN_LOG_COMMAND = “log”;

public static void main(final String[] args) {
makeHistory(new File(PROJECT_ROOT));
makeHeader();
makeLines();
printStats();
}

private static void makeHeader() {
STATS.append(“Filename;revisionCount;loc”).append(“\n”);
}

private static void makeLines() {
for (final String key : STATS_MAP.keySet()) {
makeLine(key, STATS_MAP.get(key));
}
}

private static void printStats() {
System.out.println(STATS.toString());
}

private static void makeLine(final String key, final ClassStats s) {
STATS.append(key).append(“;”).append(s.revCount).append(“;”)
.append(s.loc).append(“\n”);
}

private static void makeHistory(final File root) {
for (final File file : root.listFiles()) {
if (isJavaFile(file)) {
history(file);
}
if (file.isDirectory()) {
makeHistory(file);
}
}
}

private static boolean isJavaFile(final File file) {
return file.getName().endsWith(“.java”);
}

private static void history(final File file) {
try {
final int revCounter = getRevisionCount(file);
STATS_MAP.put(file.getName(), ClassStats.make(file.getName(), revCounter,
getLinesOfCode(file)));
} catch (final Exception err) {
err.printStackTrace();
}
}

private static int getRevisionCount(final File file) throws IOException,
InterruptedException {
String line = null;
int revCounter = 0;
final Process p = Runtime.getRuntime().exec(
SVN_EXE + ” ” + SVN_LOG_COMMAND + ” ” + file.getAbsolutePath());
final BufferedReader bri = new BufferedReader(new InputStreamReader(
p.getInputStream()));
final BufferedReader bre = new BufferedReader(new InputStreamReader(
p.getErrorStream()));
while ((line = bri.readLine()) != null) {
if (line.startsWith(“r”))
revCounter++;
}
bri.close();
bre.close();
p.waitFor();
return revCounter;
}

private static int getLinesOfCode(final File file) {
int loc = 0;
try {
final FileInputStream fstream = new FileInputStream(file);
final DataInputStream in = new DataInputStream(fstream);
final BufferedReader br = new BufferedReader(new InputStreamReader(in));
while (br.readLine() != null) {
loc++;
}
in.close();
} catch (final Exception e) {
System.err.println(“Error: ” + e.getMessage());
}
return loc;
}

private static class ClassStats {
private String fileName;
private int revCount;
private int loc;

private ClassStats() {

}

public static ClassStats make(final String name, final int revCounter, final int loc) {
final ClassStats classStats = new ClassStats();
classStats.fileName = name;
classStats.revCount = revCounter;
classStats.loc = loc;
return classStats;
}
}
}
[/source]

Bu uygulama kodun Subversion tabanlı bir versiyon kontrol sisteminde tutulduğunu varsaymaktadır. PROJECT_ROOT değişkeni versiyon kontrol sisteminden edinilmiş projenin (working copy) ana dizinine işaret ediyor. Uygulama ana dizinde bulunan tüm dizinleri taradıktan sonra bulduğu her Java dosyası için versiyon kontrol sicilini kontrol ediyor ve dosya üzerinde yapılan değişiklik adedini tespit ediyor. Akabinde her Java dosyanın satır adedi tespit edildikten sonra, aşağıdaki şekilde bir ekran çıktısı oluşturuluyor:

[source language=’java’]
Filename;revisionCount;loc
AAA.java;13;55
BBB.java;21;325
CCCjava;3;292
DDD.java;2;367
EEE.java;6;384
FFF.java;1;156
GGG.java;1;77
HHH.java;11;47
III.java;10;81
JJJ.java;3;132
KKK.java;1;111
LLL.java;9;29
MMM.java;32;433
NNN.java;45;1301
OOO.java;3;88
PPP.java;11;47
QQQ.java;60;212
[/source]

Ekran çıktısı bir csv (comma seperated value) dosyası. Bu dosyayı örneğin Excel ile import edip, aşağıdaki şekilde bir diagram oluşturmak mümkün.

Diagram üzerindeki her nokta bir Java dosyasına işaret etmektedir. X ekseninde her dosyanın maruz kaldığı değişiklik adedi (revision count), Y ekseninde dosyanın sahip olduğu satır adedi yer almaktadır. Bu diagrama bakıldığında tek sorumluluk prensibine ters düşen kod birimleri hangileridir?

SRP uyumlu olmayan sınıflar için sağ üst alana bakmak yeterli. Bu sınıfları lokalize ettikten sonra tek bir iş yapacak hale getirmek biz yazılımcıların asli görevlerinden birisi. İzcilerden kendimize örnek alalım :)

EOF(End Of Fun)
Özcan Acar

Böyle Girişimcilik Olmaz!

Bu yazıyı okuyunca daha önce yazdığım Melek Programcılar ve Şeytan Yatırımcılar başlıklı yazımı anımsadım. Orada genç girişimcilerin nasıl şeytan yatırımcılar tarafından üç kağıda getirilip, sömürüldüklerinden bahsetmiştim. Durumun başka bir boyutunu da paylaştığım yazı gösteriyor.

Eğer devamlı hesabını yapacak isem, param yetiyor mu, ya da beş sene sonra hala yeter mi diye, o zaman kendime özel sağlık sigortası yaptırmam doğru değil. Maddi açıdan bu hesabı devamlı yapmak zorunda olmayacak güçte isem, özel sağlık sigortası yaptırabilirim. Aynı şekilde sermayem yetmiyorsa, girişimci olmam da bir hayal. Kendilerine melek yatırımcı diyerek, oraya, buraya üç beş bin TL yatırım yapıp, bunu yatırım zanneden birilerinden medet ummak çok daha büyük bir hayal.

Amerika ya da Avrupada’ki başarılı bir internet girişimini birebir kopyalarak Türk internet pazarında başarılı olacağını düşünen herkes girişimci trenine binmeye çalışıyor. Çoğu yeterli sermaye, pazarlama ve işçi yönetimi bilgisi sahibi değil. Sermayeleri yetmediği için çok kısa bir zamanda işi büyütüp, onların tabiri ile exit yapmak, yani kurdukları işi çok paralara satma hayaliyle yaşıyorlar. Nihayi amaçları exit, başka hiçbir şey değil!

Sanki Türkiye’de programcı eleman eksikliği varmış gibi, birde eleman bulmakta sıkıntı çektiklerinden yakınıyorlar. Hak ettiği maaşı verdikten sonra Türkiye’de programcı bulmak hiç zor değil. Ama bu bahsettiğim internet girişimcilerinin o kadar az sermayaleri var ki, ne yiyip, içtiklerine bile dikkat etmeleri gerekiyor. Kalkıp ayda 8-10 bin TL maaş bir kalifiye programcıya nasıl versinler. Bu yeni nesil girişimcilerin programcılardan beklentileri çok yüksek, ama vermek istedikleri karşılık çok düşük. Birkaç bin TL’ye çalışacak programcı bulamamaları çok normal. Neden şikayet ediyorlar?

Hadi diyelim istedikleri şekilde bir programcı buldular. Bu programcı arkadaşın allah yardımcısı olsun. Ne fazla mesai yapmadığı kalır, ne cumartesi günleri çalışmadığı. Bir programcı günde sekiz saat ve haftada beş gün çalışır, NOKTA! Programcılık kolay bir iş değil. Beynin regenere olabilmesi için haftanın iki günü dinlenmesi gerekir. Bunun yanısıra programcının kendisini geliştirebildiği zaman dilimlerine ihtiyacı vardır. Bir programcıyı işe alıp, günde 9-10 saat çalıştırıp, cumartesi günü de işe gelmeye zorladığınız zaman bilin ki, yazılım ürününde meydana gelen hatalar çalışma süresinin uzunluğu ile doğru orantılı büyüyecektir. İnsanları bu şekilde sömüremessiniz.

Az sermayeli internet girişimcilerinin yegane dertlerinin exit olduğunun bir ibaresi de bu yazı. Adamlar Türkiye’de istedikleri çapta vurgun yapamayacaklarını anladıkları için, apar topar Türk piyasasından çekilme kararı almışlar. Bu adamlar bir iki senedir Türk piyasasındalar. Dört yüzden fazla çalışanı olan bir firma, neden apar topar tüm aktivitelerini durdursun? Çünkü sermayeleri yetmediği için. İşi hemen büyütelim, Türkiye’den ya da Avrupa’dan bir firma bizi satın alır, exit yaparız hayali ile yaşadıkları için. Bu dört yüz tane çalışanın canlarını yakmaya ne hakları var? Ama merak etmeyin. Bu tipler aynı numarayı dünyanın değişik bölgelerinde de yapıyorlar. Aynı kişiler Almanya’da da dokuz yüz kişiyi anında kapıya koydular. Böyle girişimcilik olmaz. Olsa bile ben bunların söylediklerini ciddiye almam, çünkü yaptıkları işin özünde insana hizmet ve saygı yok. Sadece kendi ceplerini düşünüyorlar, kefenin cebi varmış gibi!

Bahsettiğim ilk yazıda programcı eleman sıkıntısını gidermek için devletten ve üniversitelerden yardım isteniyor. Devlet bu konuda ne yapabilir? Üniversitelerini kurmuş, iyi ya da kötü insan yetiştirmeye çalışıyor. Üniversiteler bu konuda ne yapabilir? Hiçbir şey. Üniversite programcı yetiştirmez, yetiştiremez. Programcı anca bir usta programcının yanında yetişebilir. Ondan doğru ve yanlışları görerek iyi bir programcı haline gelebilir.

Bu yeni nesil girişimciler fazla emek sarfetmeden insan kaynaklarının kaymağını yemek istiyorlar. Yok böyle bir şey! Devlete ya da üniversitelere programcı yetiştirin diye laf söylemek yerine, yaz okulları açıp, usta programcıların üniversite ögrencilerine ya da yeni mezunlara ders vermesini sağlasınlar. Ama bunu yapamazlar, çünkü sermaye örtüleri çok ince. O zaman ne kadar para, o kadar köfte, sorry! Ama size hiç köfte yok, şekil A’da görüldüğü gibi.

EOF (End Of Fun)
Özcan Acar

Göz Boyamaca

Size herhangi bir şey satmak için kapınıza gelen bir satış temsilcisine ne gözle bakarsınız? Ben bu durumla karşılaşınca, beynimde otomatik olarak şahsı başımdan savma rutinleri devreye giriyor. Birilerinin benim üstüme bu şekilde gelerek bana bir şey satması imkansız. Bu inisiyatifin benden kaynaklanması lazım.

Yazılım sektöründe de durum anlaşılan farklı değil. Birileri biz yazılımcılara devamlı bir takım, ne işe yaradıkları belirsiz sertifikalar satmaya çalışıyor. Tek dertleri para kazanmak. Kullandıkları ve insanları en çok etkileyen argümanları ise yazılım kalitesini artırmak ve eleman yetiştirmek için çaba sarfediyor oluşları. Yesinler! Ben bunu ispatlayan ne bir araştırma ne de bir rapor gördüm.

Bir gün içinde alınan sertifikalar var. Artık para basma makinasının sesi o kadar yükselmiş ki utanıp, sıkılıp, hadi daha fazla dikkat çekmeden para basmaya devam edelim ama sertifikayı vermeden önce çakma bir imtihanla sertifikanın alınmasını zormuş gibi gösterelim diyenler ve bunu uygulayanlar var. Daha önce herkese para karşılığında dağıttıkları sertifikaları şimdilerde dandik bir imtihanla vermeye devam ediyorlar. Ne kadar büyük bir gelişme! Artık yazılım sektörü bu sertifikalarla iş başına gelen yazımcıların meydana getirdikleri yazılım kalitesinde boğulup gidecek. Bu sertifika satıcıları bana cennetten tapu satanları hatırlatıyor. Bir gün içinde sertifika almış ve karşıma geçip bana çevik süreçlerin nasıl işlediğini anlatmaya çalışan birisini ben ciddiye almıyorum.

Peki yazılımcılar neden böyle şeylere aldanıp, zor kazandıkları paralarını pencereden dışarı atıyorlar? Ha ben gidip bir günlük bir eğitim almışım, akabinde bir test ile bana sertifika verilmiş, ha bu adamlar benim kapıma gelmişler ve sertifikayı bana kapıda satmışlar. İkisi de aynı şey değil mi? Neden bunlara aldanıyor insan?

Devir ne yazık ki göz boyama devri. İş görüşmelerinde sertifikasyona gereğinden çok fazla önem veriliyor. İşveren eğer bu programcı A, B, C sertifikalarına sahipse, iyi bir programcı olmalı diye düşünüyor. Ne kadar yanlış! Bu sadece programcının bir yolunu bulup, sertifikayı aldığını gösterir. Ne kadar iyi bir programcı olduğunu göstermez.

Çok gezen mi çok bilir, çok okuyan mı? Çok sertifika sahibi mi çok bilir, çok pratik yapan bir programcı mı?

Bir programcıyı iş başına getirme kriteri sahip olduğu sertifika kolleksiyonun genişliği olmamalı. Bu sertifikalar programcının sahasında ne kadar iyi olduğunun göstergesi olamaz. Bir programcının iyi olup olmadığını anlamak için, onunla bir gün boyunca çalışıp, hangi yeteneklere ve bilgi seviyesine sahip olduğunu anlamak zor değil. Buna alternatif olarak işveren programcının eski çalışma arkadaşlarından referans getirmesi isteyebilir. Eski patronundan referans demedim, eski mesai arkadaşlarından dedim. Programcılar birbirlerini tanır, karşılıklı yetenek, beceri ve bilgi seviyelerini tartabilirler. Hiçbir programcı, iyi bir seviyede olmayan bir programcı için iyi bir programcı diyerek, kendi itibarını zedelemek istemez. Bu yüzden programcının eski mesai arkadaşları her zaman onun hakkında bilgi edinmek için kullanılabilecek güvenli bir kaynaktır.

Bizim yazılımcı olarak bu sertifika sövüşlemesine gelmeden, kendimizi yazılımcı olarak nasıl geliştirebiliriz sorusuna cevap aramamız gerekir. Eğer programcı mutlaka bir sertifika sahibi olmak istiyorsa, o sertifikayı edinsin. Ama kendisi için yapsın, etrafta A,B,C sertifikalarım var diyerek, böbürlenmek için ya da daha kolay iş bulurum düşüncesiyle değil.

Ambalajın güzelliğine aldanmayalım. Ambalajın içinden ne çıktığı önemli. Sertifikaların çok büyük bir kısmı güzel ambalajdan başka bir şey değil. Bunu Oracle Certified Master, Java EE Enterprise Architect (SCEA 5) sertifikası sahibi olarak söylüyorum.

EOF (End Of Fun)
Özcan Acar