20 Aralık 2016 Salı

Küçük Detayların Büyük Etkileri

0 yorum
English version is at DZone

Soru:
 Aşağıdaki kod parçası ile kaç satır yazı yazılır?
public static void main(String[] args){ for (int i = Integer.MIN_VALUE; i <= Integer.MAX_VALUE; i++) { System.out.println(i); } }

a) Sonsuz sayıda
b) (2147483647 *2) +1
c) 0
d) Derleme Hatası
Birçoğumuz, dikkat etmezsek, cevabın “b” şıkkı olduğu yanılgısına kapılabiliriz. Ama aşağıdaki diğer bir kod parçası cevabın “a” şıkkı olduğuna bizi ikna edecektir.
public static void main(String[] args){ System.out.println(Integer.MIN_VALUE); System.out.println(Integer.MAX_VALUE); System.out.println(Integer.MAX_VALUE + 1); }


Çıktı:
-2147483648
2147483647
-2147483648

Yukarıdaki kod parçası, i değişkeninin değeri Integer.MAX_VALUE değerine eşit olana kadar beklendiği şekilde çalışacaktır. Bu noktada i değişkenin değeri yani Integer.MAX_VALUE ekrana yazılır. Mevcut iterasyonun kontrolü geçildikten sonra, i değişkeninin değeri 1 arttırılır. Burada i değişkeninin yeni değerinin Integer.MAX_VALUE+1 olduğunu düşünebiliriz, ama değil, yeni değer Integer.MIN_VALUE ’dur. Integer.MIN_VALUE değeri Integer.MAX_VALUE değerinden küçük olduğundan iterasyon sonsuza kadar devam eder. 
Bu durumu anlamak için byte’ların ve bit’lerin dünyasına dalmamız gerekecektir. Java’da int veri tipi 32 bit’e kadar olan değerleri tutabilmektedir. Tutabildiği en küçük değer de Integer.MIN_VALUE, yani -2147483648 değeridir. İkili sayı sistemindeki ifadesi ile 1000 0000 0000 0000 0000 0000 0000 0000 ’dır. Burada en soldaki bit, işaret bitidir. 0 değeri sayının pozitif, 1 değeri ise negatif olduğunu belirtir. Yani yukarıdaki ifadede işaret biti 1’dir. Burada da görüldüğü gibi, Java sayıları tutmak için sadece 31 biti kullanmaktadır.






Buradan edindiğimiz bilgi ile, Integer.MAX_VALUE, yani 2147483647, ikili sistemdeki ifadesi ile 0111 1111 1111 1111 1111 1111 1111 1111 değerine 1 değerini ekleyelim:
Görüdüğü gibi sonuç, Integer.MIN_VALUE değeridir.
Yukarıdaki durumu ele alacak olursak, örneğin, oluşturduğumuz bir JPA entity class’ında java.lang.Integer tipindeki bir identifier ile kodumuz bir süre(belki yıllarca) beklendiği gibi çalışsa da, veritabanında oluşturacağımız kayıtların miktarı arttıkça yukarıda bahsettiğimiz problemle karşılaşabiliriz. Hiç ara vermeden, her milisaniyede yeni bir identifier ürettiğimiz bir uygulamada, Integer tipi bizi neredeyse 2 ay idare edebilecekken, Long tipi ile 300 milyon yıl gidebiliriz.
Sonuç olarak, doğru veri tiplerinin seçimi küçük bir detay olarak düşünülebilse de, başımızı ağırtacak büyük etkilere neden olabilirler. Hocamızın, “Mühendislik becerisi uç noktalarda belli olur” sözünü de bu vesileyle  paylaşmak isterim.
ali kemal taşçı