Java’ya Nasıl Başlarım? Java’yı Nasıl Öğrenirim? – V
“Java’ya Nasıl Başlarım? Java’yı Nasıl Öğrenirim?” dizisinin bu son olmasını arzulayıp da son olmayan yazısında :), en son bahsettiğimiz torbalar konusunu geride bırakıp ilerleyelim.
Giriş/Çıkış (Input/Output) ya da kısaltılmış haliyle G/Ç (I/O), temel Java’nın en korkutucu konularındandır. Ben de bu yüzden G/Ç konusuna, Java SE’nin ilgili yapılarının bulunduğu java.io paketini açıp, oradaki sınıfları, yukarıdan aşağıya, kafiyeli dizeleri olan bir şiir havasında okuyarak başlarım:
BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter
ByteArrayInputStream
ByteArrayOutputStream
CharArrayReader
CharArrayWriter
…
Biraz şaşkınlık, biraz da tedirginlik… Durumu açıklayan en güzel kelimeler sanırım bunlardır 🙂
Sonra da, korkulacak bir şeyin olmadığını, aslında, uzerine bir byte yazan ve bir byte okuyan iki metoda sahip son derece basit görünümlü bir sınıf ile halledilebilenecek olan G/Ç konusunun, neden böyle tonla ve isimleri birbirine benzeyen sınıfla karma-karışık 🙂 hale getirildiğini açıklarım. Tabiki burada da Java’nın birkaç soyutlaması soz konusudur ve bu soyutlamalar en başta anlatıldığında, G/Ç korkulu olmaktan çıkar. Bu konudaki tasarım şablonlarından (decorator, template-method gibi) bahsettikten sonra, dosyadan ve bellekten farklı okuma ve yazmaları farklı G/Ç akışları ya da stream ve reader/writer’larla gösteririm. Bu sırada ön-bellekli ya da buffered G/Ç’nin faydasını örneklendiririm. Sonrasında nesne serileştirmesi ve geri dönüşümünü (serialization ve de-serialization) ele alırım.
G/Ç konusunda ayrıca, main metoda geçilen parametreler, Properties sınıfı ile hem sistem özelliklerinin hem de kullanıcı tanımlı “.properties” dosyalarındaki özelliklerin yönetimini, java.lang.System sınıfındaki statik olan in, out ve err değişkenleri ve java.util.Scanner sınıfıyla konsol okumasını ve yazmasını ve C’deki gibi formatlı basımı gösteririm.
Görüldüğü gibi G/Ç konusu karmaşık görünmesine karşın düzgün ele alındığında tamamen anlaşılır ve zevkli bir hale gelir.
Sonrasında Java’nin Swing yapısıyla kullanıcı arayüzü programlama yapmak gelir. Açıkçası, ülkemizde eğitimler ezici çoğunlukla acil ve sıkıştırılmış olduğundan, bu konuya cok nadiren girebilirim. Aslında, Swing ile konsol uygulamalarının nadiren yazıldığını ben de çok iyi biliyorum. Bu gerçeğe rağmen Swing’i bir Java eğitiminde öğretmek istememin temelde bir kaç sebebi var: İlki, gözle görülür, estetik olarak anlamlı şeyleri programlama her zaman zevklidir. Bu şekilde, o ana kadar öğrenilen konuları pekiştirmek imkanı bulurum ben. Bu sebep zaten başlı başına önemlidir. Hatta eğer müşterime 3-5 günlük bir workshop çalışmasını da kabul ettirebilmişsem, süper olmuştur çünkü Swing’i bu workshopda da kullanabileceğim demektir. Swing’i ögretmekten kazanılan bir diger güzel şey ise, kullanıcı arayüzü programlamasının, sistematik bir programlama yaklaşımını vurgulayacak şekilde güzel örneklere izin vermesidir, çünkü görebilmek çok şeyi kolaylaştırır. Neyi nesne değiskeni yaparım neyi yerel değisken olarak tutarımdan, arayüzlerin olay dinleyicileri (event listener) olarak kullanılmasına, iş mantığına geçişe kadar pek çok noktada en iyi pratiklerden ve MVC gibi tasarım şablonundan bahseder, katılımcıların tartısmalarını sağlarım. Dolayısıyla, hiç kullanılmayacak bile olsa Swing’e zaman ayırabilmek çok faydalıdır.
Sonrasında kanalları (thread) kullanarak, çok kanallı programlama (multi-threaded programming) girerim. Önce işletim sistemlerindeki “işlem” (process) konusundan bahsederim. Bu arada her zaman yaptığım gibi “işlem nedir” diye sorarım ve her zmaanki gibi hiç bir doğru dürüst cevap alamam çünkü yurdumun yazılımcıları, genelde ne İşletim Sistemleri dersine girmişlerdir ne de o dersi veren hocalar zahmet edip dersi zevkli hale getirmeye çalışmışlardır. Bu yüzden geçen senelerin sorularıyla sınıfı geçen anlı-şanlı “Yazılım Mühendis”lerimiz bu soruya malesef cevap veremezler 🙁 Yine açıklamak bana düşer ve hem işlem hem de kanal kavramını kıyaslamalı olarak açıklar, çok işlemli işletim sistemlerinden (multiprocessing operating systems) ve çok işlemcili donanımlardan (multiprocessors) bahsederek, neden ve nasıl aynı anda birden fazla işlem yapmaya çalışırız sorusuna cevap ararım. Konu bu arada süper bilgisayarlara bile gelir ve oradan ilginç örneklerle konu daha da cazip hale getirilir 🙂
Kanal ya da thread oluşturmanın java.lang.Thread sınıfı ve java.lang.Runnable arayüzü ile nasıl yapıldığını, en temel Thread metotlarını, mesela start(), run(), sleep() vb. ve Thread hayat döngüsünü ayrıntılı olarak ele alırım. Thread önceliklendirmesini (prioritization) çok nefis görsel bir örnekle veririm. Bu arada artık makinalar çok çekirdekli olduğu için çok kanallı programlamanın mahiyeti de çoktan değişmiştir; bunlar da bu örnekle birlikte gündeme gelir. Hatta VisualVM gibi bir araç ile açılan kanalları ve CPU davranışını gösteririm. Böylece JVM ile ilgili de bazı şeyleri konuşmuş oluruz.
Sonrasında konu kanal kullanımının negatif taraflarına gelir ve aynı nesnenin durumunu değiştiren kanallardan bahsederim. Örnek oalrak da bir kac tane para yatıran bir kaç tane de para çeken kanala, aynı Account nesnesini geçerim. Normal şartlarda yani tek kanallı ortamda hiç bir problem olmayacakken, birden fazla kanalın bulunduğu ortamda Account nesnesinin sahip olduğu para miktarının negatife düştüğünü gören öğrenciden durumu izah etmesini isterim tabi. Buradan kanalların, nasıl içinde bulunduğu işlemin verilerini ortaklaşa kullanıldıgını ve bu durumun artıları yanında bu örnekteki gibi nasıl problemli noktalarının olduğunu anlatırım. Sonuçta geldiğimiz noktada synchronized anahtar kelimesini, race conditions ve dead-lock kavramlarını açıklarım.
Kanallar ile ilgili en son ele aldıgım şey, kanal haberleşmesidir. java.lang.Object sınıfı üzerinde olan wait(), notify() ve notifyAll() metotlarını kullanarak iki kanalın, birbirlerinin yaptıkları hakkında haberdar olmalarını güzel bir örnekle anlatırım.
Bu yazıyı da daha fazla uzatmadan burada sonlandıralım. Sanırım bu dizi daha iki yazıya muhtaç. Onları da geciktirmeden yazmaya çalışacağım.
Bol Java’lı günler dilerim 🙂
Toplam görüntülenme sayısı: 4804