İlk Program Bug’ı

Bug ingilizce dilinde böcek, bilgisayar dillerinde bir program hatası anlamına geliyor. İlk program bug’ı 1947 yılında Grace Murray Hopper’in Harvard Üniversitesi’nde kullandığı Mark II Aiken isimli röle (relay) (resim 1) bazlı hesaplayıcıda (primitif bir bilgisayar) bulundu.


Resim 1

9 eylül 1947 tarihinde hesaplayıcının programlandığı şekilde çalışmadığı, sorun çıkardığı görüldü Yapılan araştırma üzerine F panelindeki 70 numaralı rölenin bacakları arasında bir güvenin (moth) sıkışıp kaldığı görüldü. Program hatasının sebebi bulunmustu; bir güve yani bir böcek (ingl. bug).

Bilgisayar programlama tarihine ilk program hatası olarak geçen bu böcek operatör tarafından log defterine resim 2’deki şekilde eklendi.


Resim 2

Bu işlemin ardından operatörler hata giderildi anlamına gelen debugged (böcek temizlendi) kelimesini kullanmaya başladılar. Bizim bugünlerde sıkça kullandığımız debug kelimesinin kökeni bu güveden geliyor :)

Bug kelimesi 1947’den öncede sistem hataları için kullanılan bir terimdi. Örneğin Amerika’daki ilk telefon şebekelerinde sesin karıncalı gelmesi durumunda hatta hata var anlamına gelen „bugs in a telephone cable“ ifadesi kullanılırmış.

Kim Daha İyi Programcı?

Çoğu zaman programcı adaylarının piyasada en çok talep gören programramlama dilini seçip, bu dili öğrendikleri malum. Bu doğal bir seçim; talep olan yerde arzın bedeli olur. Bu bedel programcının iyi bir maaş ile hayatını sürdürmesi anlamına gelir.

Bilindiği üzere son zamanların en popüler ve talep edilen dili Java. İnternetteki birçok istatiktik Java’nın bir numara olduğunu tastikliyor. Programcı adaylarının da Java’yı seçmeleri doğal.

Java’yi bilenler ve kullananlar iyi ve akıllı programcılardır degil mi? Peki Python ya da piyasası pek fazla olmayan bir başka dili bilen bir programcının sadece Java’ya hakim bir programcıdan daha iyi ve akıllı bir programcı olduğunu söylesem nasıl tepki verirdiniz?

İyi programcı, program yazmayı seven programcıdır. İyi programcı yenilikleri deneyip, ufkunu genişleten programcıdır. İyi programcı programcılık dünyasının sadece Java’dan oluşmadığını bilendir. Peki iyi programcıyı nasıl anlarsınız? Bir sonraki iş görüşmesinde işe alınacak programcı adayına Java haricinde hangi dil ya da dilleri bildiğini sorun. Alacağınız cevap programcının ne kadar iyi olduğunu gösteren indikatördür. Eğer aday sadece Java’yı bildiğini söylerse iyi bir programcı olma ihtimali doğru olabilir. Bunun ispatı edindiği tecrübeler ve bilgi birikimidir. Eğer aday Java’nın yanında Python ya da Groovy dillerine de hakim olduğunu söylerse, bilin ki karşınızda akıllı (smart) bir aday duruyor. Neden? Bunun nedeni çok basit. Piyasası olmayan bir programlama dilini ögrenmiş bir programcı, program yazmayı gerçekten seviyor olmalı ki talebin dışında kalan bir programlama dilini zaman ayırarak öğrenmiş. Bu onun yenilikçi, ögrenmeyi ve program yazmayı seven birisi oldugunu gösterir. Karşınızdaki bu kişi büyük bir ihtimalle sadece Java bilen bir adaydan çok daha akıllı ve programcılık konusunda ileri seviyede.

Yanlış anlaşılmasın; Java’ya hakim olanlarda mutlaka iyi programcılardır. İyileri de var, iyi olmayanları da. Ama piyasının ihtiyacı olmayan bir dili öğrenen bir programcı çok daha fazla potansiyele sahip. Bu bir gercek! Ben böyle bir programcıyı tercih ederdim.

Sadece bir programlama dilinde (bu genelde piyasası olan bir dil olacaktır) takılıp kalmış olanların verdiği cevap hep aynı olacaktır: “Çalıştığım ortamlarda yeni bir programlama dili öğrenme fırsatı bulamadım.” Gerçekten programcılığa gönül vermiş birisi o fırsatı hemen yaratır!

Bu konuda Paul Graham’ın yazısını okumanızı tavsiye ederim.

Common Reuse Principle (CRP) – Ortak Yeniden Kullanım Prensibi

Bu prensip hangi sınıfların aynı paket içinde yer alması gerektiği konusuna açıklık getirir. CRP’ye göre beraberce tekrar kullanılabilir yapıda olan sınıfların aynı paket içinde olması gerekir.

Bu yazıyı PDF dosyası olarak aşağıdaki linkten edinebilirsiniz.


EOF (End of Fun)
Özcan Acar

Decorator Tasarım Şablonu

Mevcut bir sınıf hiyerarşisini ya da sınıfın yapısını değiştirmeden, oluşturulan nesnelere yeni özelliklerin eklenme işlemini gerçekleştirmek için Decorator tasarım şablonu kullanılır.

Alt sınıfların oluşturulması yöntemiyle, sınıflara yeni özelliklerin eklenmesi, daha sonra sisteme eklenecek alt sınıflar için değiştirilmesi zor kalıpların oluşmasını beraberinde getirir. Bu durumda, üst sınıflarda tanımlanmış olan bazı özellikler statik ve alt sınıflar için değistirilemez ya da kullanımı engellenemez bir hal alabilir. Kullanıcı sınıflar içinde bu sorun teşkil edebilir, çünkü kendi istekleri doğrultusunda bir nesnenin ne zaman ve nasıl oluşturulması gerektiğini yönlendiremeyebilirler.

Nesnelere, sahip oldukları sınıfların yapılarının değistirilmeden yeni özelliklerin eklenmesini sağlayan Decorator tasarım şablonu ile, istenilen özelliklerin ekleneceği nesne başka bir nesne içine gömülür. Yeni özellik eklenen nesneyi içine alan nesneye dekoratör ismi verilir. Dekoratör nesnesi ile yeni özellik eklenen nesne aynı üst sınfa dahil olduklarından, birbirleriyle değiştirilebilir haldedirler. Bu özellikten dolayı kullanıcı sınıf, dekoratör sınıf ile dekoratör nesne bünyesinde bulunan diğer nesne arasında ayrım yapmaz. Nesneler arası ilişkiye aşagıda ye ralan Uml diagramında görüyoruz.

Bu yazıyı PDF olarak edinebilirsiniz.

  Decorator Tasarım Şablonu (46,6 KiB, 10.881 yükleme)


EOF (End of Fun)
Özcan Acar

Yeni KurumsalJava Seminerleri

15 mart’dan 30 mart 2010’a kadar, üniversitelerde ücretsiz KurumsalJava.com seminerleri düzenlemek üzere İstanbul’da bulunacağım. İlgilenler bana acar[AT]unitedinter.net adresinden ulaşabilirler.

___________________________

Özcan Acar
Bilgisayar Mühendisi

Sun Java Champion
Sun Certified Architect (SCEA 5)

http://www.ozcanacar.com
http://www.KurumsalJava.com

Java’da Finalizer Metodu

Java_tr grubunda aşağıdaki yer alan soru soruldu. Bu soru ve benim bu konudaki düşüncelerim aşağıda yer almaktadır.

Java’da bulmaca sevenlere; Aşağıda ki kod parçası için çıktı ne olur,
“finalized” yazar mı? Constructor’ýnda exception fırlatmış bir nesnenin
finalize işleminden geçmesini bekler misiniz?

[source language=’java’]
public class FinalizerTest {

public FinalizerTest() {
System.out.println(“constructed”);
throw new RuntimeException();
}

protected void finalize() throws Throwable {
System.out.println(“finalized”);
}

public static void main(String[] args) {
try {
new FinalizerTest();
} catch (Exception e) {
System.out.println(“exception”);
}
System.gc();
}
}
[/source]

Benim verdiğim cevap şu şekildedir:


Java’da finalize() kullanılması doğru değildir, çünkü JVM’in finalize metodunu ne zaman koşturacağını kestirmek mümkün değildir. Buna güvenerek örneğin finalize() içinde kullanılan kaynakları serbest bırakmak yapılabilecek en büyük hatalardan birisidir. Pratikte finalize() metodu kesinlikle kullanmamalıdır. Finalizer kullanımı performansı düşürür. Finalizer ile nesnenin yok edilmesi daha uzun zaman alır. Finalize yerine bir terminasyon metodu kullanılmalıdır. gc() metodunun kullanımı da GC nin hemen devreye gireceği garantisini vermez.

Yukarıda yer alan programın konstruktöründe try catch ile hata yakalanarak, daha önce bahsettiğim terminasyon metodu (örneğin myExit()) koşturulmalıdır.


EOF ( End Of Fun)
Özcan Acar

Java’da Final Anahtar Kelimesi

Java’da final anahtar kelimesi aşağıda yer alan yapılar için kullanılabilir:

  • Final sınıf değişkenleri: Final olan bir sınıf değişkenine sadece bir kere değer ataması yapilabilir ve bu atama sadece sınıf konstrüktöründe gerçekleşebilir.
  • Final metot parametreleri: Final olarak tanımlanmış bir metot parametresine sadece bir kere değer atanabilir. Metot parametrelerinin tamamen final olarak tanımlamış olmalarında büyük fayda vardır. Bu şekilde parametrenin metot bünyesinde değişikliğe ugrama tehlikesi ortadan kaldırılmış olur.
  • Final metotlar: Final olan bir metot ne alt sınıflarca yeniden yüklenebilir (method overloading) ne de saklı (hidden) tutulabilir.
  • Final sınıflar: Final olan bir sınıf genişletilerek bir alt sınıf oluşturulamaz.

Final anahtar kelimesi Java programcılığında en çok göz ardı edilenlerdendir. En son siz ne zaman final anahtar kelimesini kullandınız?
Final anahtar kelimesi programın daha doğru, hatalara dayanıklı ve performanslı çalışmasını sağlar.

Final anahtar kelimesinin kullanımında yapılan en büyük hatalardan birisi final static olarak tanımlanmış olan bir sınıf değişkenine değistirilebilir bir değerin atanmasıdır. Örneğin aşağıdaki tanımlama yanlıştır, çünkü static değişken final olmasına rağmen, bu değişkene atanan değer, kullanıcı tarafından değiştirilebilir.

[source language=’java’]
public class App
{
public static final String[] LIST = {“1″,”2″,”3”};

public static void main(String[] args)
{
String[] list = App.LIST;
list[0] = “2”;
System.out.println(App.LIST[0]);
}
}
[/source]

Yukarda yer alan main() metodunda final olan LIST degiskeninin ihtiva ettiği array değiştirilmektedir. Bu sorunu ortadan kaldırmak için LIST değişkeni private yapılabilir ve bu değişkeni baz alarak içeriğinin değiştirilemeyeceği bir array değerini geri döndüren metot oluşturulabilir. Bunun bir örneği aşağıda yer almaktadır:

[source language=’java’]
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class App
{
private static final String[] LIST = {“1″,”2″,”3”};

public static final List getList()
{
return Collections.unmodifiableList(Arrays.asList(App.LIST));
}

public static void main(String[] args)
{
List list = App.getList();
list.remove(0);
System.out.println(list);
}
}
[/source]

Bu program koşturulduğunda alınacak hata şu şekildedır:


Exception in thread “main” java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableList.remove(Collections.java:1162)
at test.App.main(App.java:22)

Bu şekilde final olarak tanımladığımız LIST değişkenin ihtiva ettiği değerleri üzerinde oynama yapmak mümkün değildir. getList() metodu bünyesinde Collections.unmodifiableList() ile içeriğinin değiştirilmesi mümkün olmayan bir liste oluşturulmaktadır.


EOF ( End Of Fun)
Özcan Acar

Covariant Return Types

Java 1.5 ile kullanıma sunulan ve covariant return type ismini taşıyan bir yapı mevcuttur. Java 1.5 öncesi bir alt sınıf, bir üst sınıfın sahip olduğu metodu yeniden implemente etmek (method overriding) istediginde, bu metodun geri döndürdüğü veri tipinin, üst sınıftaki metot ile aynı olması gerekmekteydi. Bunun bir örneği aşağıda yer almaktadır.

[source language=’java’]
package test.controller;

import java.util.Map;

import test.criteria.Criteria;

public abstract class AbstractController implements Controller
{
public void executeFilter()
{
Map map = createCriteria().getCriteriaMap();

}

public abstract Criteria createCriteria();
}
[/source]

Soyut (abstract) olan AbstractController sınıfı bünyesinde, alt sınıflarda implemente edilmek üzere createCriteria() isminde bir metot tanımlıyoruz. AccountTableController sınıfı bu metodu implemente etmektedir.

[source language=’java’]
package test.controller;

import java.util.HashMap;
import java.util.Map;

import test.criteria.MyCriteria;
import test.model.Konto;

public class AccountTableController extends AbstractController
{
private Account model = new Account();

public Criteria createCriteria()
{
Map map = new HashMap();
map.put(“kontonr”, model.getKontonr());
map.put(“blz”, model.getBlz());
return new Criteria(map);
}
}
[/source]

Görüldüğü gibi AccountTableController.createCriteria() metodu Criteria tipinde bir degeri geri döndürmektedir. Bu metodun geri döndürdüğü değerin Java 1.5 öncesi Criteria tipinde olması gerekmektedir, çünkü üst sınıfta tanımlanmış olan bu metodun, üst sınıf bünyesinde geri döndürdüğü değer Criteria tipindedir.

Java 1.5 ile bu durum değişmiştir. Üst sınıfta yer alan bir metot alt sınıfta tekrar reimplement edilirse (method overriding), reimplemente edilen metodun geri döndürdüğü değerin tipi, üst sınıftaki metodun geri döndürdüğü sınıfın bir alt sınıfı olabilir. Bunun bir örneği aşağıda yer almaktadır.

[source language=’java’]
package test.controller;

import java.util.HashMap;
import java.util.Map;

import test.criteria.MyCriteria;
import test.model.Konto;

public class AccountTableController extends AbstractController
{
private Account model = new Account();

@Override
public MyCriteria createCriteria()
{
Map map = new HashMap();
map.put(“kontonr”, model.getKontonr());
map.put(“blz”, model.getBlz());
return new MyCriteria(map);
}
}
[/source]

MyCriteria, Criteria sınıfının bir alt sınıfıdır ve AccountTableController sınıfı implemente ettiği createCriteria() metodunun MyCriteria tipinde bir değeri geri döndürmesi sağlamıştır. Bu şekilde cast işlemi yapılmadan alt sınıfların daha zengin tipte verileri geri döndürebilmeleri amaçlanmaktadır.


EOF ( End Of Fun)
Özcan Acar

Java Enum ile Singleton Tasarım Şablonu

Daha önceki bir yazımda Singleton tasarım şablonunun ne olduğunu ve Java’da nasıl kullanıldığını yakından incelemiştik. Bu yazımda Java 1.5 den itibaren kullanıma sunulan Enum sınıfı ile singleton tasarım şablonunun nasıl kullanılabileceğine değinmek istiyorum.

Öncelikle küçük bir örnek üzerinde singleton bir nesnesinin nasıl oluşturulacağına bir göz atalım:

[source language=’java’]
package com.kurumsaljava.com.designpatterns.singleton;

public class MySingleton
{
private static final MySingleton instance = new MySingleton();

private MySingleton()
{
}

public void myMethod()
{

}
}
[/source]

MySingleton sınıfının sahip olduğu konstruktör private olduğu için bu sınıftan bir nesne oluşturmamız mümkün değildir. Bu sınıf bünyesinde ve MySingleton tipinde olan instance ismindeki sınıf değişkeni singleton nesnedir. Bu sınıf ilk kullanıldığında private olan konstruktör bir defaya mahsus olarak işlem göreceği için instance degişkeni bir singleton nesne haline gelecektir. Buradaki sorun, reflection yöntemleri kullanılarak private olan konstruktörün birden fazla singleton nesne oluşturmasını sağlayabilmektir. Bunun yanısıra eger MySingleton sınıfı Serializable interface sınıfını implemente ediyorsa, readResolve() metodunun da implemente edilmesi gerekmektedir, aksi taktirde deserializasyon esnasında yeni bir nesne oluşturulur ki, bu da singleton tasarım şablonunun mantığına ters düşer.

Java 1.5 den itibaren kullanıma sunulan Enum sınıfı ile singleton nesneler oluşturmak mümkündür. Bunun bir örneği aşağıda yer almaktadır.

[source language=’java’]
package com.kurumsaljava.com.designpatterns.singleton;

public enum MySingletonEnum
{
INSTANCE;

public void myMethod()
{

}
}
[/source]

MySingletionEnum.INSTANCE sadece ve sadece bir kere mevcut olan bir singleton değişkendir. Bunun yanısıra reflection metotları kullanılarak yeni bir singleton olmayan nesne oluşturulamaz. Ayrıca serializasyon işlemlerinde readResolve() kullanılmak zorunda kalmadan enum nesnesinin singletonluğu garanti edilmektedir. Tek elementli olan bir enum sınıfı singleton tasarım şablonunu implemente etmek i.in kullanılabilecek en iyi yöntemdir.

Oracle’ın Sun ve Java için stratejik planları hakkında ip uçları

JUG (Java User Group) e-posta listesinde olduğum için bana ulaşan bir e-postayı sizlerle paylaşmak istedim. E-posta Oracle’ın Sun ve Java için stratejik planları hakkında ip uçları verebilir…

———————————–
This is the only statement that I am aware of thus far:

“Oracle plans to increase investment in Java, Sparc, Solaris, and
MySQL technologies which is expected to increase the demand for
professionals with proven expertise in these areas. Oracle remains
fully committed to developing and promoting the expertise of these
sought-after specialists. Oracle University will continue to provide
comprehensive training and certification programs for these areas, and
will honor all unexpired certification exam vouchers purchased through
Sun. ”

I will provide more info if I can get my hands on it.

Justin Kestelyn

On Feb 1, 2010, at 4:02 PM, Joshua Partogi wrote:

> Hi all,
>
> Does anybody know about the status on Sun Certifications? Will the
> title changed to Oracle Certification in the future? I looked at the
> certification page is still at Sun’s Certification website, but if
> someone is for example taking the Certified Java Programmer, will he/
> she be called SCJP or OCJP? Calling him/her as an SCJP can be
> misleading since Sun as a company has been acquired by Oracle. Does
> anybody know Oracle’s plan on this? Shall I just wait until Oracle
> has made an official announcement before taking any Java
> certification? Also, will our previous Java certification still valid?
>
> Kind regards,
>
> —
> http://twitter.com/scrum8

DBUnit JUnit Entegrasyonu

DBUnit JUnit ile entegre edilerek entegrasyon ve regresyon testlerinin JUnit testleri olarak implemente edilmesi mümkündür. DBUnit JUnit entegrasyonu aşağıdaki şekilde gerçekleştirilebilir. Bilgibankası olarak örnekte HSQLDB kullanılmıştır (bakınız HSQLDB JUnit entegrasyonu). Verilerin dbunit-dataset.xml dosyasında tanımlanmıs olması gerekmektedir. setUp() metodu her test öncesi JUnit frameworkü tarafından koşturulacağı için istenilen veriler test öncesi bilgibankasına eklenmiş ve regresyon testleri için taban oluşturulmuş olacaktır.

[source language=’java’]

// JDBC Driver
public static final String DRIVERCLASS = “org.hsqldb.jdbcDriver”;
// standalone mode
public static final String CONNECTIONURL = “jdbc:hsqldb:hsql://localhost:9006/mydb”;
public static final String USERNAME = “sa”;
public static final String PASSWORD = “”;

public void setUp() throws Exception
{
PreparedStatement pstmt = null;

try
{
IDatabaseConnection connection = getConnection();
IDataSet dataSet = getDataSet();
try
{
// REF INTEGRITY MUST BE DISABLED IN ORDER TO IMPORT THE DATA
// THIS SOLUTION IS ONLY VALID FOR HSQLDB 1.8
pstmt = connection.getConnection().prepareStatement(“set referential_integrity FALSE”);
pstmt.executeUpdate();
DatabaseOperation.CLEAN_INSERT.execute(connection, dataSet);
pstmt = connection.getConnection().prepareStatement(“set referential_integrity TRUE”);
pstmt.executeUpdate();
}
finally
{
connection.close();
}
}
catch (Exception e)
{
throw e;
}
}

protected IDatabaseConnection getConnection() throws Exception
{
Class.forName(DRIVERCLASS);
Connection jdbcConnection = DriverManager.getConnection(CONNECTIONURL, USERNAME, PASSWORD);
IDatabaseConnection con = new DatabaseConnection(jdbcConnection);
DatabaseConfig config = con.getConfig();
config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new HsqldbDataTypeFactory());
return con;
}

protected final IDataSet getDataSet() throws Exception
{
final URL url = DatabaseTestCase.class.getResource( “/dbunit-dataset.xml”);
final File file = new File(url.getPath());
return new FlatXmlDataSet(file);
}
[/source]

HSQLDB ve JUnit Entegrasyonu

Oluşturduğum entegrasyon JUnit testlerinde, testler öncesi verilerin bilgibankasına aktarılması gerekiyor. Aşağıda yer aldığı şekilde JUnit sınıfı bünyesinde HSQLDB serveri standalone modda çalıştırılabilir ve DBUnit ile veriler bilgibankasına eklenebilir.

[source language=’java’]

// JDBC Driver
public static final String DRIVERCLASS = “org.hsqldb.jdbcDriver”;
// standalone mode
public static final String CONNECTIONURL = “jdbc:hsqldb:hsql://localhost:9006/mydb”;

public static final String USERNAME = “sa”;
public static final String PASSWORD = “”;

private void startHsqlDb()
{

if(!isHsqlDbStarted())
{
Server hsqlServer = new Server();
hsqlServer.setAddress(“localhost”);
hsqlServer.setPort(9006);
hsqlServer.setDatabasePath(0, “db/hsqldb-data/”);
hsqlServer.setDatabaseName(0, “mydb”);
hsqlServer.start();
}
}

private boolean isHsqlDbStarted()
{
boolean result = false;
try
{
Class.forName(DRIVERCLASS);
Connection con = DriverManager.getConnection(CONNECTIONURL, USERNAME, PASSWORD);
con.close();
result = true;
}
catch (Exception e)
{
e.printStackTrace();
}
return result;
}

private static void stopHsqlDb()
{
try
{
Class.forName(DRIVERCLASS);
Connection con = DriverManager.getConnection(CONNECTIONURL, USERNAME, PASSWORD);
Statement statement = con.createStatement();
statement.execute(“SHUTDOWN”);
statement.close();
con.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
[/source]