Java SE’den Sonra Ne Öğrenelim? İş Arayanlara Öneriler

Sıklıkla, “hocam Java SE’yi biliyorum, şimdi üzerine ne öğrenmeliyim?” gibisinden sorulara muhatap oluyorum. Bu soruları soranların büyük bir kısmı ya yeni mezun ya da bir şekidle Java tarafına geçiş yapmaya çalışan ve kariyerinin başında olan, farklı teknolojileri kullanan yazılımcı arkadaşlar. Dolayısıyla bu konuyu hızlıca açıklığa kavuşturalım.

Bence öncelikle Java SE’yi bildiğinizden emin olun! Bu blogu takip edenler bilirler ki, bir başkasına sistematik olarak anlatamayacağınız şeyi bilmiyorsunuz demektir. Dolayısıyla bu blogda yazılmış Java öğrenmek üzerine pek çok yazıya ve Java Dersleri sayfasına bakılabilir. Eğer kendinizı Java SE konusunda çok iyi hissetmek istiyorsanız Java SE sertifikasyonunu almayı deneyebilirsiniz. Bu size neresinden baksanız altı ayınıza malolur ama sizi hem kendinize güven hem de iş bulma açısından çok güzel bir noktaya getirir. (Bu noktada bu blogda sertifikasyon konusu üzerine pek çok yazı yazıldığını hatırlatmak isterim.)

Mobil kısmı bir tarafa bırakırsak, kurumsal yani enterprise Java’dan bahsettiğimizde öncelikle web tarafından başlamakta fayda var gibi görünüyor. Java EE’nin web tarafında sonuçta servlet, JSP ve JSF var. Servlet ve JSP’lerin kullanımı gittikçe düşüyor. Özellikle servletlerin kullanımı düşüyor gibi görünse de hem aslında her şeyin temelinde olmasından dolayı hem de webin en temel protokolu olan HTTP’yi öğrenebilmek için servlet APIsini bilmekte fayda var. Bu sayede HTTP’nin yapısını, komutlarını, istek (request) ve cevap (response) nesnelerini, headerlarını, oturum (session) yapısını ve cookieleri öğrenmiş olursunuz. Sonrasında kullanımı servletlerden çok daha yaygın olan JSPlere geçip, EL ve JSTL’i de ele alıp, Java’da web tarafının temellerini güzelce öğrenebilirsiniz.

Temeller üzerine web tarafında kurgulanacak yapı bence MVC’dir. MVC, web tarafının en temel mimari kalıbı olup, hemen her web frameworkü tarafından uygulanmaktadır. Bu anlamda belki de en kolay öğrenilecek MVC frameworkü Spring MVCdir. Hem basit hem POJO yapısı hem de ayrı bir view teknolojisi barındırmaması açısından öğrenilmesi son derece kolaydır. Spring MVC’nin controller yapılarını ögrenerek ve JSP kullanarak hızlıca web uygulamaları yapabilirsiniz.

Eğer sertifika yolunda ilerliyorsanız, Java SE sertifikasından sonra Java’nın web teknolojilerinin sertifikasını almayı düşünebilirsiniz. Bu da sizin altı ay ya da bir senenizi alabilecektir, aklınızda bulundurun.

MVC konusunda Struts’ı da düşünebilirsiniz. Nispeten eski bir teknoloji olmasına rağmen hala pek çok yerde, özellikle 2000li yılların başında geliştirilmiş projelerde kullanılıyor. Spring MVC’nin daha popüler olduğunu düşünüyorum ama hala iyi bir MVC frameworkü hem size temel mimariyi öğretecek hem de CVnizde güzel duracaktır.

Spring MVC’ye çok iyi bir MVC alternatifi JSF olabilir. JSF aynı zamanda bir view teknolojisi de olduğundan pek çok farklı JSF bileşen kütüphanesi vardır. JSF öğrenmek demek aslında biraz da bu kütüphanelerden birisiyle çalışmak demektir. Bu anlamda öncelikle Java EE ile gelen referans JSF implementationu (mojorra) ile başlayıp sonrasında Türkiye’den arkadaşlarımızın başarıyla geliştirip, yazılım sektöründe sundukları Primefaces ile devam etmek güzel olacaktır. Bununla birlikte JSF, hayat döngüsü (life-cycle) Spring MVC’ye göre daha karmaşık ve soyut olduğundan, ayrıca event, validation vb. yapıları da deklaratif olarak hallettiğinden ögrenilmesi Spring MVC’ye göre daha zordur ve uzun zaman alır. Lakin bence JSF, Spring MVC’den çok daha güçlü ve hızlı geliştirmeye elveren bir teknoloji olduğundan, vakti olan ve zoru sevenlerin Spring MVC yerine JSF ile devam etmelerinde fayda vardır. Zaten piyasadaki eğilim de daha çok JSF yönündedir. Bu yüzden JSF’e giriş yapmış bir Javacının iş bulmada pek zorlanmayacağını düşünüyorum.

İster JSF ister Spring MVC kullanın, öğrenmeden kaçamayacağınız bir konu daha var: Nesneler arasındaki bağımlılıkları yönetmek için dependency injection (DI). İster Spring DI’yi öğrenin ister daha iyi bir alternatif ve yapı olan Java CDI öğrenin ama sadece web tarafında geliştirme yapsanız bile yüksek bir ihtimalle bir DI yapısı kullanacağınızı unutmayın.

Web tarafını müteakiben öğrenilecek bir başka konu da veri tabanı ile iletişimde bulunan kalıcılık (persistence) katmanına yönelik teknolojiler olabilir. JDBC, java SE’nin bu konudaki en temel bileşeni. Dolayısıyla JDBC’yi pişirmek, hatta Spring’in JDBC desteğini kullanmak ve orada DAO kalıbını uygulayacak şekilde programlarınızı kurgulamak bence iş bulmada çok temel bir kazanımdır.

JDBC’den sonra JPA’e girişmek, piyasada en çok kullanılan kalıcılık çerçevelerinden birini kullanmak anlamına geleceğinden iş bulma ihtimalinizi çok arttıracaktır. JPA, temelelrinin öğrenilmesi zor olmayan ama içine daldıkça karmaşıklaşan bir teknoloji olduğu içın temel eşleştirme (mapping) yapıları, EntityManager APIsi ile transaction yönetimini bilseniz size çok avantaj sağlayacak bir duruma gelebilirsiniz.

JPA ile uğraştıktan sonra gerektiğinde Hibernate’in native API’si ile de rahatlıkla uğraşabilirsiniz. Hibernate, JPA’den daha eski bir yapı ama kavramsal oalrak aynı işi yapıyorlar hatta çok benzer şekilde yapıyorlar. Bu yüzden bu durum iş bulma ihtimalinizi çok arttıracaktır.

Zorunlu olmamakla beraber, bütün bu konularla uğraşırken ilgili tasarım kalıplarını da yavaştan ele alıp, o konularda da bir şeyler öğrenirseniz mükemmel olacaktır.

Tabi yukarıda bahsettiğim teknolojilerde belli bir noktaya gelmek sizin bir senenizi rahatlıkla alacaktır. İşin içine sertifikasyonu da sokarsanız, sadece ilk yani Java SE sertifikasını almak bile rahatlıkla 6 ayınızı alabilir. Bu biraz da ne kadar vakit ayırabildiğinizle ilgili bir durumdur. Ama bence her halukarda bu korkulacak bir durum değildir çünkü gerek okulunuzun son senesinde, gerek ise okuldan sonra hasbel kader girdiğiniz ama çok da mutlu olmadığınız ilk işinizde kendinizi bu konularda geliştirecek zaman bulabilirsiniz.

Gördüğüm şu: bilen, iyi bir hedefe ve vizyona sahip ve kendine güvenen kişiler, iş tecrübeleri olmasa bile çok güzel işler bulmaya devam ediyorlar.

Bu yazı toplam 1541 defa görüntülenmiştir.

Share

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 :)

 

Bu yazı toplam 546 defa görüntülenmiştir.

Share

Java’ya Nasıl Başlarım? Java’yı Nasıl Öğrenirim? – IV

Bu serinin 4. yazısında, son yazıda gelinen noktadan, tekrar kullanım bölümü ile devam edebiliriz. Tekrar kullanımdan kasıt, var olan nesnelerden yeni nesneler oluşturmaktır. Bunu yapmanın ise temelde iki yolu vardır: bileşim ve kalıtım ya da miras. Bileşim (composition), var olan sınıfların tipinden nesne değişkenlerine sahip olacak şekilde yeni bir sınıf oluşturmaktır. Bu kullanıma sahip-olma ya da has-a ilişkisi denir. Miras ise bir benzerlik ilişkisidir ve is-a olarak adlandırılır. Bu bölüme, bileşim ile başlar sonra da mirasa geçerim ve detaylıca ele alırım. Tabi ki miras alan sınıfta, ebeveyndeki metodun tekrar tanımlanması yani overriding bu kısımdaki en önemli konulardandır. Sonrasında ise java.lang.Object sınıfıni ve APIsini incelerim ve örneklerle neden toString() ya da hashCode() ve equals() gibi metotların yeniden tanımlanması gerektiğini anlatırım. Doğal olarak başlatma sırası (order of initialization) ve final anahtar kelimesinin ilgili kullanımları da bu konunun alt başlıkları arasındadır.

Sonrasında, miras ve yeniden tanımlama üzerine kurgulanan ve nesne-merkezli dillerin en önemli özelliği olan çok şekillilik yani polymorphism gelir. Cok şekilliliğe önce yukarı atama (upcasting) ile başlarım ve bir referansın, zamanın farklı anlarında, kendi tipi ve alt tiplerinden olan nesneleri gösterebileceğini anlatıp, dinamik metot çağrısına geçerim. Daha sonra ise aşağı atama ya da downcasting gelir ve sonuçta instanceof operatörü ele alınır. Bu sırada, referansın arayüzü ile nesnenin arayüzü arasındaki ayırım hep vurgulanır.

Sonra ise sıra soyut sınıflar (abstract classes) ve arayüzlere (interfaces) gelir. Soyut sınıflar, şu ana kadar sınıflar ile nesne-merkezli programlamada gelinen noktayı bir adım öteye taşır. Söyleki: Java eğitimlerinde bu ana kadar sıklıkla, arayüz-gerçekleştirme ya da interface-implementation ayırımından bahsederim. Nesne-merkezli programlamaya giriş yaptığım bölümden, erişim niteleyicileri ele aladığım kısıma kadar, özellikle de düşük bağımlılıklı (lowly-coupled) ve yüksek iç-bütünlüklü (highly-cohesive) yapılar ve sınıflardan bahsederken, devamlı arayüz ve gerçekleştirme kavramları ile aralarındaki ilişkiyi vurgularım. Bu iki kavram, soyut sınıflar ve arayüzler konularında, çok daha geniş ve pek çok pratik uygulamayla o şekilde ele alınır ki her yönüyle ele alır, güzek örneklerle açıklarım. Bu güzel örnekler arasında decorator ve proxy tasarım desenleri de yer alır.

Soyut sınıflar ve arayüzler ile Java’nın en temel nesne merkezli yapıları ele alınmış olur. Artık sıra bir diğer çekirdek dil yapısı olan sıra dışı durumlara (exceptions) gelmiştir. Sıra dışı durumları ele alırken, sadece try-catch-finally blokları ve throw ve throws anahtar kelimelerini ele almam, neden sıra dışı durumları yönetmeliyiz, hatta ihtiyaç analizi sürecinde sıra dışı durumlar nasıl bulunurdan başlayarak, tasarımda nasıl yer aldıklarından bahsederek, kodlama anına kadar gelirim. Bu kısımda ayrıca assert anahtar kelimesini ve ‘Assertion-driven Desing” (ADD) yaklasımından da bahsederim.

Bir sonraki bölümde torbaları ele alırım. Collection arayüzünden başlayıp, Set ve List arayüzleri ile devam ederim. Sonuçta, HashSet, TreeSet, ArrayList ve LinkedList ile ilgili örnekler verip, ne zaman hangisini kullanmalıyızı ele alırım. Orneğin Set’in, nasıl aynı nesneden iki tane eklenmesine izin vermediğini ya da sona ekleme yapılmayıp başa ve ortalara ekleme yapıldığında neden LinkedList kullanmamız gerektiğini örneklerle gösteririm. Daha sonra Map arayüzüne geçerim ve gerçekleştirmeleri olan HashMap ve TreeMap’i benzer şeklide ele alırım. Sonrasında, java.util paketindeki bu torbaları kullanarak yeni veri yapıları ve torbaları nasıl oluşturabilirizi bir iki örnek ile katılımcılarla tartışırım. Java SE’de var olan torbalar yeterli olmadığında, Apache Commons’in Collection projesinde var olan yapıların imdadımıza nasıl yetiştiğinden bahsseder, oradaki veri yapıları ve torbalardan örnekler veririm. 

Torbalar bölümünün en zevkli tarafı ise bence her zaman şudur: Arayüzlerin kullanımına nefis örnekler sunması ve arayüz-gerçekleştirme ayırımını güzel bir şekilde vurgulanması. Katılımcılara Collection arayüzünden hiç bahsetmeden, “hadi bir torbayı modelleyelim” deyip, Torba isimli bir arayüz oluşturup sonra da mesela “ekle” davranışını gerçekleştirirken, ekleme sırası gözetip gözetmeyeceğimiz ya da sıralama yapıp yapmayacağımız, ya da ne bileyim örneğin, aynı nesneden birden fazla eklemeye izin verip vermeyeceğimiz gibi detayların, nasıl birer gerçekleştirme konusu olduğunu açıklarım. Zaten bu kısımdaki TreeSet ya da TreeMap gibi yapıları kullanırken nesnelerimizin, istediğimiz kriterlere göre sıralanabilmesini sağlamak amacıyla kullandığımız, Comparable ve Comparator arayüzleri, nesnelerimize nasıl farklı yetkinlikler kazandıracağımızın en güzel örneklerindendir.

Torbalar bölümünde ayrıca java.util.Collections sınıfı üzerindeki algoritmalardan da bahsedip, arama, sıralama, kaydırma vb. işlemlerinden örnekler veririm.

Bu bölümün en son konusu ise generics ya da  “bir tipe özel” yapılardır. Generics, iç sınıflar (inner classes) gibi anlaşılması zor ya da zordan öte tecrübe isteyen konulardandır. Dolayısıyla, generic yapıların, öncelikle bir tipe özel torbalar oluşturmak için nasıl kullanılacağından bahsederim. Sonrasında sadece ufuk açmak ya da meraklı zihinlere bir tiyo vermek amacıyla şablon sınıflardan bahsedip, bir kaç örnek veririm. Hatta Java API’sine gidip, örneğin java.util.Collections sınıfının binarySearch(List<? extends Comparable<? super T>> list, T key) metodunun arayüzünün nasıl anlaşılması gerektiğini anlatırım :)

Artık sıra giriş/çıkış (I/O), çok kanallı programlama (multi-threading) ve veri tabanı programlaması (JDBC) gibi konulara gelmiştir. Bunları da bir sonraki yazıda ele alalım.

Bol Java’lı günler dilerim :)

 

Bu yazı toplam 539 defa görüntülenmiştir.

Share