Node.js ile Async Callback Yönetimi

Node.js yazılarıma kullandığım bir şablon ile devam etmek istedim. Aslında bu problem bütün JavaScript genelinde geçerli fakat bu bölümde Node.js kullanırken veritabanı çağrılarında yaptığımız async işlemleri inceleyeceğiz. Öncelikle problemi tanımlayalım;

Önceki Node.js bir bakışta başlıklı yazımda Node.js ile yapılan sorguların async fakat javascript dilinin sync bir dil olduğundan bahsetmiştim. Bu durum aslında yönetmeyi biliyorsanız bir problem teşkil etmiyor fakat kodunuzun çok karışık gözükmesine sebep oluyor. Örneğin;

var productList = [];
dbHelper.getProducts(categoryId, function(data, err){
    productList = data;
});

for(var i = 0; i < productList.length; i++){
    console.log(productList[i].Name);
}

Yukarıdaki basit örnek çalışması düşük ihtimalli bir kod parçasına ait. dbHelper sınıfının getProducts metodunu bir değişken ile çağırıyoruz ve data cevabı bekliyoruz. Geri dönen cevabı productList değişkenine atıyoruz ve aşağıda productList içinde döngü kullanarak konsola ürün ismini yazdırmaya çalışıyoruz. Veritabanı detaylarını kodu basit tutmak için vermiyorum fakat burada öncelikle şunu anlatmak gerekiyor;

JavaScript Callback Şablonu

function getProducts(categoryId, callback){
    /* 
       veritabanı işlemine ait satırlar
    */
    callback(result, err);
}

Yukarıdaki gibi bir veritabanı yardımcı metodumuz var diyelim. Burada callback parametresi async işlemleri halletmek için bize gerekiyor. böylece dışarıdan bu metodu çağırdığımızda

dbHelper.getProducts(categoryId, function(data, err){

yukarıdaki gibi içine inline-function, aynı satırda metodu, callback parametresi ile geçebiliyoruz. callback’i hemen burada konsola yazdırsak bize dışarıdaki metodun içeriğini verecek. Daha sonra veritabanı ile ilgili işimiz bittiğinde

callback(result, err)

ile içeriye geçtiğimiz bu metodu çağırıyoruz. Böylece uzun süren veritabanı işleminin bittiğini dışarıya söylüyoruz ve dönen data parametresi productList’e eşitlendiğinde veritabanı işleminin bittiğinden eminiz.

Buradaki problemi incelersek;

var productList = [];
dbHelper.getProducts(categoryId, function(data, err){
    productList = data;
});

for(var i = 0; i < productList.length; i++){
    console.log(productList[i].Name);
}

productList = data satırını async çağırdık fakat biz daha veritabanı işini bitirip bu satırı çağırmadan JavaScript motoru hemen alttaki for döngüsüne girdi bile. Buraya girdiğinde productList’i daha data’ya eşitlemediğimiz için değişkenin içi boş. Döngüyü atlayıp gidiyoruz daha sonra yukarıdaki callback fonksiyonu çalışıyor.

Bunu basitçe çözebiliriz;

dbHelper.getProducts(categoryId, function(data, err){
    var productList = data;
    
    for(var i = 0; i < productList.length; i++){
        console.log(productList[i].Name);
    }
});

for döngüsünü callback metodunun içine aldım. Böylece artık data geldiğinde for döngüsüne girecek. Bu şimdiye kadar çözdüğümüz en basit senaryo.

Callback Hell – Callback Cehennemi

images

Callback Hell

Diyelim ki for döngüsünde de gelen her product için bir işlem yapmaya karar verdik;

dbHelper.getProducts(categoryId, function(data, err){
    var productList = data;
    
    for(var i = 0; i < productList.length; i++){
        dbHelper.updateProductPrice(productList[i].productId, 10,
            function(data, err){
                console.log('product price updated for',
                            data.productId, " new price is: ',
                            data.newPrice);
            }
        );
});

Bu da çalışan başka bir örnek, açıklarsak, önce ürün listesini çektik daha sonra for döngüsü içinde her ürünün productId’sini parametre olarak geçerek %10 zam yaptık diyelim. (Tabi doğrusu tek çağrıda veya sorguda halledebilirdik örnek amaçlı veriyorum)

Gördüğünüz gibi ortalık karışmaya function içinde function kullanmaya  başladık bile. Bunun sebebi, bütün veritabanı işlemlerinin async olması ve eğer bir sonuç loglayacaksak önce yardımcı metodun içine göndermemiz gereken callback metodunu gönderip, veritabanı ile iş bitene kadar bekleyip, bu metodun sonuç ile çağırıldığında loglama işlemimizi yapmamız gerekmesi.

Peki bütün fiyat güncelleme işlemleri bittiğinde birşey yapmak istesek, diyelim ki konsola “bütün fiyat güncellemeleri tamam” yazmak istesek nasıl yaparız?

       dbHelper.updateProductPrice(productList[i].productId, 10,
                function(data, err){
                console.log('product price updated for',
                                 data.productId, " new price is: ',
                                 data.newPrice);
            }
        );

yukarıdaki metod hep async çağırıldığından, yani veritabanına giden sorguların hepsi aynı anda gidip cevap bekledğinden hangi güncellemenin önce biteceğini veya daha doğrusu hangisinin en son bittiğini bilip ona göre bir mantık geliştirmemiz imkansız.

Bu durumda da şöyle bir takla atarak en son cevabı gelen işlemi bulabiliyoruz;

dbHelper.getProducts(categoryId, function(data, err){
    var productList = data;
    var processedCount = 0;

    for(var i = 0; i < productList.length; i++){
        dbHelper.updateProductPrice(productList[i].productId, 10,
            function(data, err){
                console.log('product price updated for',
                            data.productId, " new price is: ',
                            data.newPrice);

                 if(++processedCount === productList.length){
                     console.log('All products are updated');
                 }
            }
        );
});

Yukarıda gördüğümüz gibi processedCount isminde bir değişken ekleyerek her callback metodunda konsola yazdıktan sonra ++processedCount ile bir arttırıp bütün ürün listesi sayısı ile karşılaştırıyorum. Eşit olduğunda konsola bütün ürünler güncellendi mesajı yazarak gerekli mantığı uyguluyorum.

Gerçek hayatta çok daha karışık örnekler karşımıza çıkıyor malesef. Yukarıdaki üç örnek en çok karşılaştığımız problemleri çözüyor.

Tabi bu basit örnekte bile JavaScript kodumuzun okunmasını çok bozan bir durum. Kodu mantıksal metodlara ayırıp biraz okunulurluğu arttırabilseniz bile sonuç pek güzel olmayacak.

callback hell 2

Callback Hell

Burada başka çözümler  ve çözüm kütüphaneleri devreye giriyor;

Promise Yapısı

Yukarıdaki yapıya alternatif olarak npm async.js veya orijinal lokasyonu ile async kütüphanesi. Biraz öğrendikten sonra Promise objelerini kullanarak bize daha temiz bir kod yapısı sunuyor. Birçok JavaScript async kütüphanesi mevcut fakat hepsinin yapısı aşağı yukarı aynı.

Async kütüphanesini Promise yapısını bilmeden de kullanabilirsiniz. Bütün tarayıcılarda ve Node.js üzerinde çalışan en popüler kütüphane bu. Kütüphane içinde 70’e yakın metod var fakat bizim güncel problemlerimizi çözen en önemli metodları parallel, series, waterfall.

Async kütüphanesini inceleyip kullanmaktan korkmamak lazım. JavaScript’in gücü bildiğiniz gibi geliştirilen kütüphanelerden geliyor. Ne kadar çok kütüphaneye alışırsanız programlama hızınız daha çok artıyor, bunlarla ne kadar çok antrenman yapar, proje geliştirirseniz kod problemlerini düşünmekten daha çok süreci düşünmeye başlıyor, daha iş odaklı çalışabiliyorsunuz.

Async kütüphanesini de vakit bulduğumda başka bir yazımda anlatmaya devam edeyim.

 

Node.js bir bakışta…

Aslında başlığa aldanmayın benim bu ikinci bakışım, neden mi?

Node.js ilk çıktığında bir JavaScript aşığı olarak bakıp inceleyip biraz oynamıştım. İki üç satırda servis yazabilmek, bunu hemen JSON servis edebilir halde kullanmak çok güzeldi. Node.js daha ilk günden async yapısı ile çok ciddi bir performans sunuyordu hatta compile olan (derlenen) dillerle yarışacak kadar kuvvetliydi.

Daha sonra “herşey bu kadar kolay olamaz” diye düşünüp araştırmalarıma devam ettim ve Node.js’in çok ciddi bir ayıbı olduğunu gördüm. Node.js yük altında bir requeste vermesi gereken cevabı başka bir request’e verebiliyordu. Bu çok ciddi bir sorun çünkü içinde para geçen kritik bir işle uğraştığınızı düşünün başkasının bilgilerini görebiliyor olmanız çok ciddi güvenlik açığı.

İşte bu yüzden ilk bakışımda hemen başarısız sayıp daha ileri gitmedim.

Gelelim ikinci bakışıma;

Geçenlerde bir proje için hem sunucu hem istemci tarafına servis yazmamız gerekti. İstemci tarafı Internet of Things platformlarında çok kullanılan Raspberry PI. Hal böyle olunca node.js tekrar gündeme geldi. Ben bu yazıyı yazarken 5.1.0 versiyonu yayında. Geliştirmeyi de bunun üzerinde yaptım. Yapmadan önce de daha önceki problemleri tekrar araştırdım. Performans testlerini okudum. Dahası kendim örnekler yapıp kodu yazarken ne hissettiğimi göreyim dedim.

Hani bilirsiniz programcı olarak başka dilde de kod yazabilirsiniz, hatta bir süre sonra alışabilirsiniz fakat favori platformunuzun, editörünüzün hissiyatını vermez. Bu durum benim için biraz farklı oldu çünkü öncesinde Angular.js daha sonra da büyük bir Vanilla JavaScript web tabanlı projeden çıkmıştım. Editörüm bu sürede tabi ki sublime text idi ve JavaScript yazmaya çok alışmıştım.

23349677395_56212fd548_z

Kısacası ikinci bakışım şu şekilde;

JavaScript, özellikle dilin async olmayıp ortamın async olmasından kaynaklı hem web tarafında hem node.js üzerinde aynı problemli yapıyı sürdürmeye devam ediyor. Şimdi diyeceksiniz ki “JavaScript async bir dil bizi mi kandırıyorsun?”  Malesef JavaScript bilinenin aksine biraz daha içine girdiğinizde, altyapısını incelediğinizde malesef sync bir dil, yani bütün işlemler tek tek queue’ya attığınız sırayla gerçekleşiyor. Async olarak bildiğiniz bütün yapı AJAX’tan kaynaklanıyor. Bunu da Microsoft zamanında Outlook’un web client’ını yazarken geliştirdi. O kadar güzel yaptılar ki bütün browser’larda standart olarak tanındı.

Malesef sync bir dilde Ajax Call yaptığınızda, örneğin Rest API çağrıları veya sunucu tarafını düşünecek olursak node.js’in veritabanı sorgularını örnek verebiliriz. Node.js platformu, main thread’i boş bırakmak için platform olarak async çalışarak bütün bu çağrıları worker thread’de işliyor. Fakat sizin kodunuz sync çalıştığı için bu işlemin sonucundan haberdar olamıyor. İşte burada JavaScript ortamına alışkın değilseniz, callback veya promise’lerle çalışmaya alışkın değilseniz geliştirdiğiniz yapı baştan kusurulu olabilir. Lokalinizde şans eseri çalışan bu yapı sunucu ortamında, yük altında, yavaşlık oluştuğunda test ettiğinizden farklı davranabilir.

Callback’lerin dezavantajı kodunuzu okunmaz hale çok çabuk getirebilir olması. Malesef bunun node.js ile alakası yok. Projenizde mutlaka promise’ler kullanmaya, başlamadan önce araştırmanızı bu şekilde yapmaya ve geliştireceğiniz eklentileri bunu destekleyecek şekilde seçmeye çalışmanızı öneririm.

Peki hep kötüleri konuştuk, Node.js’in başarısı nedir, neden son 4 yıldır bu kadar ön planda?

Öncelikle JavaScript yukarıda anlattıklarıma rağmen çok güzel bir dil ve JavaScript’le geliştirme yapıyor olmak çok zevkli.

Node.js’in npm installer’ı çok başarılı, bu installer ile indirebileceğiniz eklentiler, arkadaki community çok iyi. JavaScript’te öğrendiğiniz bütün numaraları burada kullanabiliyorsunuz ve underscore.js, moment.js gibi bildik başarılı kütüphaneler burada da kullanılıyor. Hatta HTML üretiyorsanız JQuery’nin sunucu taraflı çalışan klonu da mevcut. Mongodb, SQLite ve aklınıza gelebilecek modern bütün teknolojilerle kolayca çalışabilirsiniz.

Ofiste Mac üzerinde yazdığınız kodu eve gelip Windows üzerinden devam ettirip daha sonrasında da çalışmak üzere Raspberry PI üzerine kurabiliyorsunuz. Her ortamda aynı çalışıyor.

Memory footprint’i dediğimiz çalışırken kullandığı hafıza diğer dillerle karşılaştırdığımızda gayet düşük.

Compiled (derlenen) bir dil olmamasına, interpreted (yorumlanan) bir dil olmasına rağmen performansı çok yüksek. Daha önce C# Web.API ile karşılaştırdığımda kafa kafaya olduğunu görmüştüm, son versiyonun performansı IIS üzerinde çalışan C# projelerinden çok daha iyi, OWIN üzerinde çalışan servislerden biraz daha iyi.

Son olarak, artık Angular.js ile sunucu tarafında Node.js ile JavaScript dışında başka bir dil kullanmadan birçok işinizi halledebiliyorsunuz.

İlk çıktığında ciddi stabilite problemleri yaşasa da artık 4 yıl sonra bugün birçok platformun arka planıda çalışıyor, sürekli geliştiriliyor, desteği çok iyi.

İstediğiniz editörde çalışabiliyorsunuz. Öyle piyasa standardı bir editöre takılıp mutsuz olmak yok veya c#’ta olduğu gibi Visual Studio’nun büyük projelerdeki yavaşlığı, yüksek hafıza kullanımı burada yok. Benim tercihim Sublime Text bu konuda çok başarılı.

Node.js ile ilgili ikinci bakışım bu şekilde. Konuyla ilgili aklımda şunlar da var;

Microsoft’un bütün platformunu Linux ortamına taşımasını bekliyorum. Belki burada Web.API yazmak çok daha keyif verecek ve geliştirdiğim uygulamalar daha performanslı / kabiliyetli olacak.

Herkes gibi Go platformu ile ilk tanışmam da keyifli geçti, bütün örnekleri kısa zamanda yapıp bir iki ufak uygulama geliştirdim. Object Oriented konusunda beni çok mutlu etmedi fakat burada da çok keyifli şeyler yapılıyor, destek günden güne artıyor, artık kendi platformu ile kendi dilinde compiler’ı var ve  bu bir dil için çok büyük bir adım. Go ile çalışan arkadaşlarım da çok keyifli.

Diğer alternatifler mevcut fakat açıkçası ne kadar denediysem beni mutlu etmedi. Ne Python ne Java ne PHP (ApiAgility fena gözükmüyor) ne de Ruby

Son olarak eğer Node.js’e girecekseniz projemde kullandığım sevebileceğiniz birkaç kütüphanenin linkini vereyim;
Generate API Documentation
http://stackoverflow.com/questions/11969542/how-to-generate-api-documentation

MySQL
https://www.npmjs.com/package/mysql

ORM
http://docs.sequelizejs.com/en/latest/
http://sailsjs.org/get-started
http://knexjs.org/

API Development
http://www.smashingmagazine.com/2015/11/sailing-sails-js-mvc-style-framework-node-js/

Node.js Excel Export
https://www.npmjs.com/package/excel-export

Server Side JQuery
https://www.npmjs.com/package/cheerio

datetime
http://momentjs.com/

Jade HTML
http://jade-lang.com/

Node Emailer
https://www.npmjs.com/package/nodemailer

Node Supervisor – Detect Code Changes
https://github.com/petruisfan/node-supervisor

Diğer
http://blog.nodejitsu.com/6-must-have-nodejs-modules/
cradle: A high-level, caching, CouchDB library for Node.js
findit: Walk a directory tree in node.js
node_redis: Redis client for node
node-static: RFC2616 compliant HTTP static-file server module, with built-in caching.
optimist: Light-weight option parsing for node.js
xml2js: Simple XML to JavaScript object converter.

Ve dahası burada npm en çok kullanılanlar listesinde;
https://www.npmjs.com/browse/depended

Test Driven Development – Test Yönelimli Geliştirme Üzerine

Test Driven Development, 11 yıldır yazılım yöneticiliği yapsam da son 7 yıldır öğrenip içselleştirip ekiplerimle uyguladığımız günlük metodolojilerden biri. Bugün biraz TDD hakkında teorik bilgi vermek istedim.

Peki nedir Test Driven Development? “Biz zaten testlerimizi yapıyoruz” dediğinizi duyar gibi oluyorum. Birçok danışmanlığını verdiğim şirkette programcılar “Ben kodumun gerekli yerlerine test yazıyorum, yani TDD biliyorum” diyor. Fakat TDD tamamen farklı bir yaklaşım.

TDD ne değildir;
TDD; isminde Test geçtiği halde yazılımınızı test etme metodolojisi değildir.
TDD; Unit Testing değildir. Bu kavramlar genelde karıştırılır.
TDD; bir mimari yaklaşımdır. Kodunuzu test etmeye değil testlerle geliştirmeye yarar.
TDD; bir vakit kaybı değildir. Yatırımınızı bugfix yapmaya, gereksiz iletişime, dokümantasyona ve güvensizliğe değil teste kaydırırsınız. Diğer Extreme Programming metodolojileri de vakit kaybı değildir. Şimdiye kadar irili ufaklı birçok ekipte ve projede büyük faydalarını gördük. Fakat bu da başka bir yazının konusu.

TDD ile yapmaya çalışıtığım tam olarak şudur; Değişik örnekler ekleyerek, mimaride yapacağım yeniliklerin, ekleyeceğim komplikasyonların bu örnekleri desteklediğini görmeye ve düzgün çalıştırdığını ispat etmeye çalışırım. Adım adım bu temellerin üzerine yeni senaryo örnekleri ekleyerek mimarimi ve kodumu geliştiririm.

Unit Testing ise tam olarak şudur; Biraz önce geliştirdiğim bir şeyin düzgün çalıştığından emin olmak istediğim için farklı örnekler eklerim. Bu örneklerle, yaptığım geliştirmemin en başta tasarladığım şekilde çalışıp çalışmadığını inceler, problem varsa tespit etmeye çalışırım.

TDD ile Unit Testing farklı düşünüş biçimleri, farklı bakış açılarıdır. TDD’de elinizdeki yazılımın sahip olmadığı bir özellikle ilgili gerçeklemesini istediğiniz testi ekler, öncelikle bunu yapmadığını ispat edersiniz. Daha sonra bu testi gerçekleyen en basit kodu yazar, testin geçtiğini ispat edersiniz. Unit Testing yaparken kodunuzu zaten yazmışsınızdır. “Acaba şu farklı parametreler / varyasyonlar için de çalışıyor mu?” yaklaşımı ile yaptığınız implementasyondan daha çok emin olmaya çalışırsınız.

Unit Testing kötüdür diye birşey söylenemez. Unit Testing, TDD gibi bir kod geliştirme aracıdır, kodunuza olan güvenimizi arttırmak için kullanırız. Her ikisine de ihtiyacımız var. Dahası, birçok projede ikisini de kullandığımız olmuştur.

Ne durumda hangisini yaptığınızın bilincinde olmanız yaptığınız işe hakimiyetinizi arttırır. Yapınıza ekleme mi yapıyorsunuz yoksa yaptığınızdan emin olmaya mı çalışıyorsunuz.

İstenmeyen SMS’leri Engellemek – Android

Merhaba,

Bu sefer farklı bir konu ile ilgili yazmak istedim. Herkesin derdi olan bu izinsiz sms’ler ile ilgili senelerdir Turkcell ile yaptığım kavgalardan malesef ben yenik çıktım. Daha doğrusu artık pes ettim. Zaten parasını ödediğim bir servisten neden reklam alıyorum, almak istediğim sms’leri neden seçemiyorum, bütün ayarlarım kapalı olduğu halde neden bu sms’ler engellenemiyor anlayabilmiş değilim. Benim gibi insanlar için reklamlı / reklamsız diye tarifeler çıkartsalar da neyse parasını versek. Bir seferinde sadece “Hattımı kapatın” dediğimde düzgün bir sonuç almıştım, o da sadece bir süre farklılık yarattı, sonrasında yine spam sms almaya devam ettim.

Eğer Android telefonunuz varsa bu sorunun çözümü mevcut. IOS üzerinde böyle bir uygulama görmedim, eğer aşağıdaki özelliklerde bir uygulama varsa bana yazarsanız burada onu da ekleyeyim.

SMS sorunumu aslında uzun bir süre önce aşağıda linkini paylaştığım Clean Inbox isimli uygulama ile çözmüştüm. Eğer Android işletim sistemine sahip telefonunuz varsa hemen indirmenizi ve satın almanızı tavsiye ediyorum.

https://play.google.com/store/apps/details?id=com.smsBlocker&hl=en

Fakat Clean Inbox aradaki birkaç versiyonda çok kötü çalıştığı için başka çözümler aradım ve hep mutsuz oldum. Şimdi Clean Inbox yeni arayüzü ile tekrar yeni versiyon piyasaya sürdü ve bu sefer herşey güzel gözüküyor.

Peki neden Clean Inbox da başka uygulama değil;

Clean Inbox çok basit bir özellik barındırıyor. Word Filter. Word Filter özelliğine sol üstteki menüden Block List’i seçip en sağdaki sekmeden ulaşabilirsiniz. World Filter, piyasadaki diğer SMS uygulamalarında olmayan, kelime ile filtreleme özelliği getiriyor. Bu da size telefon numarası ile gönderilmemiş, firma ismi ile gönderilen, normalde bloklayamadığınız sms’leri de filtreleyebilme şansı veriyor. Aslına bu uygulama sadece bu özelliğiyle satın alınmaya değer.

Aldığınız sms’lerdeki en çok geçen kelimeleri buraya eklediğinizde git gide daha az sms geldiğini göreceksiniz. Eğer sizi rahatsız eden numara belliyse işiniz daha kolay. Hala aynı menüden gönderene göre bloklama yapabiliyorsunuz.

Bloklanan mesajlarınızı, sol üstteki menüden erişebileceğiniz “Blocked Messages” menüsü altında görebilirsiniz. Buraya arada bir bakmakta fayda var, yanlışlıkla çok genel bir filtre koyup blokladığınız, kaçırdığınız mesajlar olabilir.

Son olarak Settings menüsüne girip “SMS block notification” ayarını da “Off” konumuna getirirseniz uygulama blokladığı sms olduğu zaman sizi rahatsız etmez, ses çıkartmaz.

Artık hayatım biraz daha sessiz ve sakin. Kesinlikle herkese tavsiye ediyorum.

Sevgiler,

Serkan Berksoy

Kaçımız Şifresini Değiştirdi

Bildiğiniz gibi birkaç ay önce Heartbleed diye bir bug üredi. Bunun sebebi Open SSL’in transport level (datanın taşınırken şifrelendiği seviye) güvenlik protokolünde yeni bir eklenti yapılması ve bu eklentinin kodlanma açığı sonucu o an sunucu hafızasında ne varsa elde edilebilmesiydi. Şifreleriniz, kredi kartı bilgileriniz, mesajlarınız, e-posta’larınız, dokümanlarınız, kısacası internet üzerinde SSL ile kullandığınız ne varsa birden bire güvenlik zaafiyetine yakalanmış oldu.

OpenSSL hemen yama çıkarttı. Firmalar uğraşarak bu yamayı yüklediler. Fakat bilinçsizlik bazen çok ciddi sonuçlar getirir. Aşağıda birkaç örnek ve sebebini yazdım;

Firmanız OpenSSL’in o meşhur 1.0.1 versiyonunu kullanıyor ve siz bunu farkedip yama yüklediniz. “Çok güzel, rahatladık, artık tamamen güvenliyiz” diye düşünüyorsunuz.
Fakat öyle değil. Eğer OpenSSL 1.0.1 versiyonu kuruluyken transport key dediğimiz taşıma sırasındaki kriptolamada kullanılan şifreniz bir kez çalındıysa OpenSSL’in yamasını yüklemeniz malesef yeterli değil. Hacker bir kez bu key’i aldığı için hala trafiğinizi dinleyip paketlerinizi decrypt edebilir ve okuyabilir.
Yapmanız gereken OpenSSL yaması yüklemek, sonrasında içinde trojan olmayan güvenli bir makinede (mümkünse yeni kurulmuş bir pendrive linux sunucu) bu key’i oluşturarak SSL sertifikanızı bu key ile satın almak. Böylece transport key yenilendiği için yeni şifre ile kriptolanacak. Bu aşamadan sonra güvende olacaksınız.

Peki kişisel olarak ne yaptınız? Büyük web sitelerine üyesiniz. Aralarında Facebook var, Yahoo var, Dropbox var. Bu firmalar da OpenSSL yamasını yakından takip edip yükledi.
Fakat onlar yükleyene kadar hacker’lar sizin bilgilerinizi ele geçirdilerse kullanıcı adınız, şifreniz internette hacker listelerinde geziyor olabilir ve bundan sizin haberiniz olmayabilir.
Benim 235 siteye (en az) üyeliğim varmış. Bunlardan önemli olarak kabul ettiklerimin şifresini değiştirdim. Bayağı bir vaktimi aldı fakat bunu yapmak zorunda hissettim kendimi.

Peki ya birden fazla sitede aynı şifreyi kullanıyorsanız? O zaman bir sitede Heartbleed açığından faydalanıp şifrenizi çalan bir hacker bütün bilinen sitelerde e-posta ve şifrelerinizi deneyeceği için yine başka hesaplarınızı da kaybetmekle karşı karşıyasınız.
Burada kısaca şifre kullanma alışkanlıklarına değinmek gerekiyor.
1. Kısa şifre kullanmayın. Doğum tarihi vb. artık çok kolay hackleniyor.
2. Sözlükte kolay bulunacak, üzerine sözlük uygulanacak kelimelerden kaçının.
3. Şifreleriniz en az 2 nümerik 2 büyük harf ve en az bir ASCII karakter içersin (!’^+%&/()=?-_@€ gibi)
4. İki sitede aynı şifreyi kullanmayın. Şirket şifrenizi çalan birisi hemen GMail’de deneme yapacaktır.
5. Password generator kullanın, şifrelerinizi password generator ile oluşturun.
6. Password reminder kullanmayın. Tarayıcınız şifre hatırlamasın.
7. Şifre programlarından birini kullanacaksanız (KeePass, LastPass) bunları güvenli ortamlarda çalıştırın, bunların ana şifrelerinin kurallara uyduğundan emin olun.

Şöyle bir hikaye anlatayım; Hash algoritmaları üzerine bir araştırma yapıyorken çalıştığımız şirketin hashlenmiş 12 milyon kullanıcısının şifrelerini veritabanı üzerinde grupladık.
Kullanıcıların %70’inin şifrelerinin ortak olduğunu gördük. Bazılarını dictionary-hashing sitelerinde kolayca geri döndürebildik. Yani şifreniz “121212” ise bilin ki bu tip şifreler hacking için kullanılan sözlüklerde geçiyor ve hesabınızın olduğu site brute-force algoritmalarına açık ise önce siz hackleneceksiniz. Bu tip şifreler hash’lense bile kolayca geri dönülebiliyor çünkü sözlüklerde karşılıkları var. Yukarıdaki kuralları tekrar okuyup uymaya çalışın.

Kısaca OpenSSL Heartbleed bug’dan IT çalışanı ve kullanıcı olarak nasıl korunacağınızı anlatmaya çalıştım.
Lütfen bugün, şimdi gidip şifrelerinizi gözden geçirin. Değiştirmeye üşenmeyin.

Sevgiler,
Serkan Berksoy

Polymorphism ve Dependency Injection

Geçen hafta yazılımcı arkadaşlarla iş görüşmeleri yaparken aklımıza geldi. Neredeyse her iş görüşmesinde soruyoruz; Nedir bu Polymorphism veya Dependency Injection. Görüşmeye gelenlerin %20’sinden cevap alıyoruz. Fakat biz de bu yabancı terimleri Türkçe ifade etmeye çalıştığımızda zorlandık, dilimiz dönmedi. Ya sürekli yabancı kaynak okumaktan ya da gerçekten Türkçe açıklamasının zor olduğundan. Aşağıda kısaca bu kavramları olabildiğince Türkçe anlatmaya çalışayım.

Polymorphism (Çok Biçimlilik)

Nesne yönelimli programlamada (Object Oriented Programming) birçok aynı özelliğe sahip nesnenin ortak özelliklerini bir arayüz veya soyut sınıf (Interface veya Abstract Class) ile belirtip, nesneleri bu arayüzden veya soyut sınıftan türetebiliyoruz. Bu özelliğe kalıtım (inheritence) diyoruz.

Aynı özelliğe sahip bu türetilmiş nesneleri, her nesnenin kendi tipi değil de türettiğimiz arayüz veya soyut sınıf tipi ile yani ortak özellikleri ile kullanırsak, bu özelliğe ait hangi nesne gelirse gelsin aynı kodun içinde kullanabiliyor, ata sınıfını kullanarakk aynı tipmiş gibi davranabiliyoruz. İşte buna Polymorphism deniyor.

En çok gerçek hayat örneği sanırım banka komponentleri için verilebilir. Diyelim ki Garanti Bankası ve Yapı Kredi Bankası POS işlemleri için sınıflarınız var. Her iki sınıfta da Sale (satış) ve InstallmentSale (Taksitli Satış) metodlarınız var. Eğer bunları bir Interface’den türetirseniz aşağıdaki gibi bir yapı elde edersiniz;

public interface IBank
{
public int Sale();
public int InstallmentSale();
}

public class GarantiBankasiPos : IBank
{
public int Sale()
{
// sale kodu buraya
}
public int InstallmentSale()
{
// InstallmentSale kodu buraya
}
}

Ortalığı karıştırmamak için metod parametrelerini ve içindeki kodu yazmadım. Yukarıdaki yapıdaki her banka pos sınıfı için Sale() metodunu kodladığım durumda aşağıdaki gibi bir kodla bankadan bağımsız satış yapabilir hale gelirim;


public int DoSale(IBank bank, parametreler ....)
{
// parametre kontrolleri ve diğer iş kuralları uygulama kodu
return bank.Sale(parametreler ...);
}

İşte burada Polymorphism uygulamış olduk. Banka tipinden bağımsız olarak kontrollerimizi gerçekleştirip satışı tek metod üzerinden yapabiliyoruz. Bu bizi kod tekrarından korudu, kodumuzu basitleştirip bakım ve yeni pos sınıfları eklememizi kolaylaştırdı. Artık aynı şekilde ekleyeceğimiz her pos sınıfını IBank’tan türeterek aynı kodun içine referans olarak verdiğimizde o banka ile işlem yapabileceğiz.

Dependency Injection (Bağımlılık Enjeksiyonu)

Bağımlılık Enjeksiyonu, Dependency Injection’un birebir çevirisi olduğu için kullandım. Aslında şimdiye kadar geçen terimlerin Türkçe’sini günlük hayatta hiç kullanmıyoruz. Herkes Dependency Injection veya DI olarak, Polymorphism, Interface, Abstract Class olarak bu kavramları kullanıyor.

Peki Dependency Injection nedir? Dependency Injection, bir sınıfın içindeki farklı görevleri, o sınıfa dışarıdan parametrik olarak verebilmektir. Yani iş kuralları olan sınıfımın içinde veritabanı işlerini yapmayıp, bu işlevi veritabanı yardımcı sınıfı olarak ayırıp, referansını iş kuralları sınıfıma parametrik olarak geçebilirim. Örneğin;

public class PaymentManager
{
private ILogger _logger;

public PaymentManager(ILogger logger)
{
_logger = logger;
}

public void DoPayment()
{
// DoPayment iş kuralları kodu
_logger.Log("Ödeme Yapıldı");
}
}

Yukarıdaki örnekte ILogger tipindeki işi sadece log almak olan bir sınıfın referansını, PaymentManager sınıfına, constructordan parametrik olarak geçtik. Burada hem loglama ile ilgili kodlamayı PaymentManager gibi görevi bambaşka birşey olan bir sınıf içinde yazmadık hem de bu sınıfı loglama sınıfından tamamen bağımsız hale getirdik. Yani artık aynı görevi yapan başka bir loglama sınıfını da buraya verip istersem başka bir ortama loglama yaptırabilirim.

Dependency Injection yöntemi işinize bağlı olarak birçok şekilde kullanılabiliyor. Enjekte edeceğiniz sınıfı constructor’dan veya fonksiyon’dan parametre geçebilir, mevcut sınıfa property olarak tanımlayabilir veya mevcut sınıfın atasına property olarak tanımlayabilir ve bu şekilde kullanabilirsiniz.

DI, en çok TDD (Test Driven Development) yöntemleri ile birlikte kullandığımız bir yöntem. Özellikle test edeceğimiz kısmı, rahat test edebilmek için diğer kısımlardan izole ediyoruz. Ayrıca dışarıdan o tipte herhangi başka bir sınıf da enjekte edebileceğimiz için Mock veya Fake denilen yapılar ortaya çıkmış. Yani daha henüz Logger sınıfı yazmadınız fakat bunun görevini yapan sahte bir sınıfı içeri verip Logger gibi davranmasını sağlayıp, işin o kısmıyla uğraşmıyorsunuz. Test etmeniz gereken yeri test edip daha sonra uygulama zamanında gerçek logger sınıfınızı enjekte ediyorsunuz. Böylece testleriniz daha hızlı çalışıyor. TDD’de her yaptığınız değişiklikte bütün testleri çalıştırmanız gerektiği için bu önemli. Fakat bu başka bir blog’un konusu.

Toparlayıp birer cümlede bu iki kavramı aşağıdaki gibi tanımlayabiliriz;
Polymorphism: Aynı özellikleri ile bir ataya bağlayabildiğimiz sınıfların ortak özelliklerini, başka bir kod parçası içinde, aynı tipe aitmiş gibi o atadan türeyen bütün sınıflar için kullanabilmek.
Dependency Injection: Bir sınıfın içindeki görevleri mantıklı parçalara ayırarak, bu parçaları o sınıfa dışarıdan polimorfik bir yapıda parametre olarak geçebilmek ve böylece bağımlılığı ortadan kaldırmak.

Kısaca Polymorphism ve Dependency Injection kavramlarını anlatmaya çalıştım.

Yazılım Projelerinde Ürün Yöneticisi Olmak için Gerekli Özellikler

Ürün ve iş ekipleri yazılım ekiplerinin sürekli dirsek temasında çalıştığı birimlerdir. Bu yüzden bu ekiplerin yapısı biz yazılımcıları ilgilendirir çünkü az veya çok sürekli birlikte çalışırız. Unutmayın başarıya sadece iyi bir yazılımla ulaşamazsınız. Bu yazılımın bir kişi veya daha iyisi bir takım tarafından birçok yanının yönetilmesi gerekir.

Profesyonel şirketlerde yönetim, satış, pazarlama birimlerinin istekleri ürün veya iş ekiplerinde toplanır. Bu bilgiler belli bir süzgeçten geçirilir, dokümante edilir, önem sırasına göre düzenlenir, fizibilite çalışmaları analistler ve yazılım ekipleriyle birlikte gerçekleştirilerek iş planlarına dahil edilir. Birçok şirketin süreçleri aşağı yukarı bu şekildedir. Araya farklı süreçler girip çıkabilir fakat genel olarak minimum yapı bunu gerektirir. 

Ürün Müdürü veya Direktörü yönetici pozisyonları firma yönetim hiyerarşisine, dinamiklerine göre farklılıklar gösterebilir. Bir firmada CEO’ya bağlı, diğerinde CIO veya COO’ya bağlı olabilir.

Yönetim olarak bağlı olduğu birimler yazılımcıları çok etkilemese de birlikte çalışırken birbirimizi anlayabilmek için bazı noktalarda karşı tarafın teknik bilgiye sahip olmasını bekleriz. Özellikle yazılımcı dilinden anlayıp bunu iş / business diline çevirebilecek iletişimi kuvvetli kişilerle çalışmak, biriminizin beklentilerini ve sıkıntılarını anlamak, yönetime anlatmak için gereklidir.

Uzun zamandır Ürün Yöneticileri ile birebir ilişkide olan pozisyonlarda çalıştım. Fakat hiç işe alım sırasında beklentilerim sorulmamıştı. Geçen gün firmamızdaki böyle bir pozisyon için bir arkadaşımla sohbet ederken, yazılım projelerinde yönetim pozisyonundaki bir Ürün Yöneticisi’nin ne özelliklere sahip olması gerektiğini sordu ve tartıştık. Sonrasında ben profesyonel bir arkadaşımdan konuyla ilgili yardım aldım.

Kısaca yazılım projelerinde Ürün Yöneticisi Pozisyonu’nda çalışabilmek için gerekli beceri setini aşağıdaki gibi sıralayabiliriz;

– Mutlaka teknik bir bölüm mezunu olmalı.
– Analiz yeteneği gelişmiş olmalı. Sistem tasarlayan veya sistem analizi yapan 4 yıllık bölümlerden mezun olmalı.
– Geçmişte az da olsa kod geliştirmiş olmalı.
– Veri tabanı bilgisi olmalı, segmentasyon gibi konularda bilgili olmalı.
– Test teknikleri hakkında bilgili olmalı, test ekibi yönetebilmeli.
– SEO bilgisi olmalı (Genellikle web tabanlı geliştirme yapıldığını varsayarak)
– İngilizce bilgisi olmalı ki yukarıdaki konuları ve mesleki gelişmeleri ilgili forum, site vs.’den takip edebilmeli.
– Proje yönetim yetenekleri gelişmiş olmalı ki, yazılım birimlerinden istediği işi planlayabilsin ve yetiştireceği zamanı ayarlayıp öngörebilsin.
– Diğer yandan işi ve gereklerini iyi bilmeli ki, bunları yazılımcıların anlayabileceği bir dille ifade edebilsin.
– Ortaya çıkan ürüne Prod OK verebilecek ve bunun sorumluluğunu alabilecek deneyime sahip olmalı.
– Dokümantasyon ve yazılı iletişim açısından kendini sözel ve yazılı olarak ifade etme yetenekleri çok iyi olmalı. Özellikle yazılım projelerinde istek (requirement) dokümantasyonu düzgün oluşturulmadığında iş yanlış anlaşılıyor, tekrar yapılmak zorunda kalıyor ve maliyet çok yükseliyor.
– Dolayısıyla İngilizce, teknik bilgi, kendini ifade edebilme yetenekleri kuvvetli olmalı.

Evet farkındaysanız yukarıda Pazarı bilmesi vs. gibi konularda detaya girmedim. Eminim bu pozisyonun daha detaylı tanımı IK Profesyonelleri tarafından yapılabilir. Benim bir bilişim profesyoneli olarak başarılı proje yürütebilmek için birlikte çalışacağım Ürün Yöneticisi’nden veya ekibinden beklediğim gereksinimler bu şekilde.

Gördüğünüz gibi doldurulması zor bir pozisyon ve Türkiye’de bu kalibrede ürün yöneticileri özellikle ilgili sektörün içinden zor bulunuyor. Genelde bu pozisyona yönelik bölümler yerine sektörde kendini geliştirmiş, tecrübe kazanmış kişileri Ürün Yöneticisi pozisyonunda görebilirsiniz. Yani yazılım projeniz finans sektöründeyse finansın içinden gelen pozisyonlar Ürün Yöneticisi olarak yönetim kadrosuna yükseliyor. Bu durumlarda genelde yukarıdaki beklentiler karşılanmıyor ve yazılım ekipleriyle koordinasyon yeterince kuvvetli olmuyor.

Peki sektörel tecrübesi çok kuvvetli olan bir Ürün Yöneticiniz var. Onunla yolları ayırmak istemiyorsunuz fakat başarıya ulaşmak istiyorsunuz. Bu açıkları kapatmak için neler yapılabilir?

– Şirket bünyesinde profesyonel analistler çalışabilir ve dokümantasyon bu ekiplerin yönetiminde olur.
– Test ekipleri yazılım ve kabul testlerine destek verebilir.
– Proje süresince ve sonrasında Profesyonel SEO desteği alınabilir.
– Ayrıca bir Proje Yöneticisi pozisyonu veya proje ofisi açılıp, Ürün Yöneticisi PMI’ın öngördüğü gibi “Proje Şampiyonu” olarak kullanılabilir.

C# öğrenmek için doğru linkler

Uzun bir aradan sonra herkese merhaba,

Öncelikle ilgilenip mail atan arkadaşlara teşekkür ediyorum. Genelde benzeri sorular geldiği için aşağıdaki derlemeyi yapma ihtiyacı doğdu.

C# öğrenirken dil şart demiştik o yüzden genelde yabancı kaynak takip ediyorum. Yeni başlayan arkadaşlar için de aşağıdaki kaynakları öneriyorum. Kitabın içinde de özellikle terimlerin İngilizce isimlerini kullanarak sizi araştırma yaparken rahatlatmaya çalıştım. Aklıma geldikçe veya sizden geldikçe bu sayfayı güncelleriz.

– HeadFirst yayınları sıfırdan başlayanlar için çok iyidir. Anlatımı akılda kalıcıdır. Özellikle Object-Oriented, Design Patterns ve Java kitabını (Java yazmayacak olsanız bile) tavsiye ederim. Burası bittikten sonra Wrox veya APress veya O’Reilly yayınlarına geçilebilir. Bu yayınları C# başlığı altında geçen kitapları alınabilir.

Burada bu kitapların içeriğinden çok, sizin için okuması hangisi kolaysa onu seçmenizde fayda var. Okuması kolay ile  kastım sayfa düzeni ve fontları. Bunu kitabı almadan önce Amazon.com’dan kitabın içine göz atarak görebilirsiniz.

– Ayrıca Pluralsight video’larını mutlaka inceleyin. Burada, kitapta atladığınız noktaları görsel olarak tamamlayacabileceksiniz.

– Yukarıdakileri bitirdikten sonra ASP.NET, Win Forms, MVC, Silverlight, WCF vb. hangi teknolojiyi kullanacaksanız bu başlıkta bir kitap alabilirsiniz.

– Son olarak konuyu öğrendikten sonra web’den her zaman en geniş örneklere ulaşabilirsiniz. Burada kullandığımız iki büyük site var. Mutlaka araştırırken karşınıza gelecektir fakat ben yine de yazayım.

– http://www.codeproject.com/

Codeproject sitesinden konu ile ilgili anlatım ve baştan aşağı bitmiş, çalışan örneklere ulaşabilirsiniz.
Stackoverflow sitesinde ise mutlaka sizin karşılaştığınız problemi başkası sormuş ve genelde yazılım camiası da cevaplamış olacaktır.

Sevgiler,
Serkan Berksoy

Erişim Bilgilerim

Herkese merhaba,

C# Tam Hakimiyet ile ilgili yorumlarınız için teşekkür ederim.
Ayrıca yayınlayabildiğim ve yayınlayamadığım sorularınız ve ilginiz için teşekkürler.

Yoğunluğum sebebiyle uzun zamandır yeni blog girişi yapamadım.
Bana homeofserkan@gmail.com adresimden erişirseniz sorularınızı yanıtlamaya çalışırım.

Serkan Berksoy