Sayfalar

10 Mayıs 2014 Cumartesi

Conditional Breakpoint İle Daha Hızlı ve Etkili Debugging - Eclipse ve Chrome Örneği

2 yorum
English version is at DZone

Yazdığımız kodun çalışmasını incelemek veya kodda alınan bir hatayı bulabilmek için çoğunlukla debugging yöntemini kullanırız.

Günümüzde birçok IDE ve hatta browser'lar debugging yapmayı mümkün kılmaktadır.

Bir anlamda kodu ve çalışması sırasında değişkenlerin aldığı değerleri "didiklediğimiz" debugging işleminin daha hızlı ve etkili yapılmasına yardımcı olduğunu düşündüğüm bir yöntemi aşağıda paylaşmak isterim.

Aşağıda bu yöntemin Eclipse IDE'sinde ve Chrome browser'ındaki örneklerini göreceksiniz. Farklı IDE ve browser'larda da bu yöntemi uygulayabilirsiniz.

Eclipse'de Java kodumuzu debug etmek yani nasıl çalıştığını izlemek için istediğimiz satıra breakpoint koyarız.


 Kodumuzu debug modunda her çalıştırdığımızda breakpoint koyduğumuz satırda  kodun çalışmasının durakladığını görürüz. Bu sırada koddaki değişkenlerin anlık değerlerini de görebiliriz.


 Kodun hangi değerden veya sebepten dolayı hata aldığını bildiğimiz durumlarda, istediğimiz durumun gerçekleşmesini görebilmek için değişken değerlerini her geçişte kontrol etmek yerine breakpoint özelliklerinde bu durumu(condition) belirterek kodun sadece o durumda duraklamasını  sağlayabiliriz. Bu şekilde beklediğimiz durumun gerçekleşmesini daha hızlı görebiliriz.






Bu yöntemle, breakpoint’e gelindiğinde, kodun çalışmasını duraklatmadan istediğimiz farklı bir kodun çalıştırılmasını sağlamamız bile mümkündür.



Hatta, breakpoint’e gelindiğinde değişkenlerin değerlerini bile değiştirebiliriz.


Bu yöntemle, istediğimiz breakpoint’ten istediğimiz  bir exception’u bile throw edebiliriz. Bu şekilde, gelmesi nadir olan bir exception’ ın nasıl catch edildiğini görmemiz mümkündür.



Debugging işlemini Chrome üzerinde de yapmamız mümkündür. Bu sefer Javascript kodumuzu debug edebiliriz. Bunun için, F12’ye basarak ya da “Araçlar(Tools) > Geliştirici Araçları(Developer Tools)” menüsünden açılan penceredeki “Sources” menüsü altından debug etmek istediğimiz kodu seçip breakpoint’i ekleyebiliriz. Ardından burada da beklediğimiz durumu belirtebiliriz. Kodun çalışması ancak, belirttiğimiz durum oluştuğunda duraklayacaktır.



ali kemal taşçı

5 Mart 2014 Çarşamba

Thread-Safe Olmayan SimpleDateFormat İçin Bir Çözüm : ThreadLocal

6 yorum
Bir uygulamamızda, standart tarih formatı oluşturmak için, aşağıdaki gibi bir BaseService class’ımızın içinde static date formatter’lar oluşturmuştuk:

public class BaseService { protected static final SimpleDateFormat SDF_DT = new SimpleDateFormat("dd.MM.yyyy HH:mm"); protected static final SimpleDateFormat SDF_D = new SimpleDateFormat("dd.MM.yyyy"); …

Daha sonra, bu formatter’ları, implement eden her class içinde aşağıdaki gibi kullanıyorduk:
public class CampaignRegistrationService extends BaseService{ … oblg.setExpireDate((SDF_D.format(expireDate))); … time = SDF_D.parse(iaArchivedCriteria.getValue()).getTime(); …

Uygulamamızda her zaman değil ama bazen, yoğun işlemler sırasında, formatter’larımızı kullandığımız yerlerden aşağıdaki gibi çeşitli hataların atıldığını gördük.

java.lang.NumberFormatException: For input string: "" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) at java.lang.Long.parseLong(Long.java:431) at java.lang.Long.parseLong(Long.java:468) at java.text.DigitList.getLong(DigitList.java:177) at java.text.DecimalFormat.parse(DecimalFormat.java:1297) at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1589) at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1311) at java.text.DateFormat.parse(DateFormat.java:335) at ...

java.lang.NumberFormatException: multiple points at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1082) at java.lang.Double.parseDouble(Double.java:510) at java.text.DigitList.getDouble(DigitList.java:151) at java.text.DecimalFormat.parse(DecimalFormat.java:1302) at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1934) at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1311) at java.text.DateFormat.parse(DateFormat.java:335) at ...

java.lang.ArrayIndexOutOfBoundsException: -1 at java.text.DigitList.fitsIntoLong(DigitList.java:212) at java.text.DecimalFormat.parse(DecimalFormat.java:1295) at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1934) at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1311) at java.text.DateFormat.parse(DateFormat.java:335) at ...


Her defasında farklı farklı ve koda bakınca da pek anlamlı gelmeyen bu hatalarla ilgili araştırma yaptığımızda, sorunun thread-safe olmayan, yani farklı threadler tarafından ortak kullanılan alanlara sahip olan java.text.SimpleDateFormat class’ının kullanımından kaynaklandığını farkettik.

Sorunu daha detaylı açıklayacak olursak, SimpleDateFormat class'ı methodlardaki hesaplamalarında kullandığı ara değerleri instance alanlarda saklamaktadır. Yani bir instance iki thread tarafından kullanıldığında,  her biri birbirinin sonucunu bozabilmektedir. Örneğin, java.text.DateFormat’ın kaynak koduna bakacak olursak, DateFormat veya SimpleDateFormat içindeki işlemlerde kullanılmak üzere bir Calendar instance alanı olduğunu görürüz.

public abstract class DateFormat extends Format { /** * The calendar that <code>DateFormat</code> uses to produce the time field * values needed to implement date and time formatting. Subclasses should * initialize this to a calendar appropriate for the locale associated with * this <code>DateFormat</code>. * @serial */ protected Calendar calendar; …
DateFormat ‘ı extend eden SimpleDateFormat’ın içindeki parse() methoduna bakacak olursak, ilk olarak, calendar.clear() methodunun çalıştırıldığını daha sonra da calendar.add(..) methodunun çalıştırıldığını görürüz. Eğer bir thread’in parse() method çağrımı tamamlanmadan, bir başka thread de parse() methodunu çağırırsa, ilk thread’in beklediği değerin, ikinci thread tarafından silinmesi(clean) durumu ortaya çıkacaktır.

public class SimpleDateFormat extends DateFormat { … public Date parse(String text, ParsePosition pos) { … calendar.clear(); // Clears all the time fields … Date parsedDate = calendar.getTime(); if( ambiguousYear[0] && !parsedDate.after(defaultCenturyStart) ) { calendar.add(Calendar.YEAR, 100); parsedDate = calendar.getTime(); } …

Bu durum da bizim bazen doğru sonuçlar alırken, bazen de alakasız hatalar almamız durumunu açıklıyor.

Burada yaşadığımız problemi ThreadLocal ile çözdük. Java 2’den beri var olan ThreadLocal sınıfı thread-local değişkenleri sağlar. Bu değişkenler, her thread’e özel olarak tutulur. Farklı thread’lar birbirlerinin thread-local değişkenlerine erişemez.

ThreadLocal  içerisinde get, set, initialValue ve remove metotları bulunur.
get() : ThreadLocal değişkeninin değerini döndürür.
set(T value) : ThreadLocal değişkeninin değerini günceller.
initialValue() : ThreadLocal değişkeninin ilk değerini döndürür.
remove() : ThreadLocal değişkeninin değerini siler. (Java 5 ile eklendi)

ThreadLocal ile her thread’ın kendi formatter’ını kullandığı çözümümüzü aşağıda görebilirsiniz:

import java.text.SimpleDateFormat; /* * Thread Safe implementation of SimpleDateFormat * Each Thread will get its own instance of SimpleDateFormat which will not be shared between other threads. * */ public class PerThreadFormatter { private static final ThreadLocal<SimpleDateFormat> dateFormatHolder = new ThreadLocal<SimpleDateFormat>() { /* * initialValue() is called */ @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat("dd.MM.yyyy"); } }; private static final ThreadLocal<SimpleDateFormat> dateTimeFormatHolder = new ThreadLocal<SimpleDateFormat>() { /* * initialValue() is called */ @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat("dd.MM.yyyy HH:mm"); } }; /* * Every time there is a call for DateTimeFormat, ThreadLocal will return calling * Thread's copy of SimpleDateFormat */ public static SimpleDateFormat getDateTimeFormatter() { return dateTimeFormatHolder.get(); } /* * Every time there is a call for DateFormat, ThreadLocal will return calling * Thread's copy of SimpleDateFormat */ public static SimpleDateFormat getDateFormatter() { return dateFormatHolder.get(); } }

import java.text.SimpleDateFormat; public class BaseService { protected static SimpleDateFormat getSDF_DT() { return PerThreadFormatter.getDateTimeFormatter(); } protected static SimpleDateFormat getSDF_D() { return PerThreadFormatter.getDateFormatter(); } …

public class CampaignRegistrationService extends BaseService{ … oblg.setExpireDate((getSDF_D().format(expireDate))); … time = getSDF_D().parse(iaArchivedCriteria.getValue()).getTime(); …

Yararlandığım Kaynaklar:
DateFormat in a Multithreading Environment
ThreadLocal in Java - Example Program and Tutorial
SimpleDateFormat thread safety
Multiple exceptions thrown parsing date string


ali kemal taşçı

15 Ağustos 2013 Perşembe

At Cebe Sonra Oku - Pocket(Formerly Read It Later)

0 yorum

Internette gezinirken veya bir e-mail ile ulaşan, faydalı, ilginç makale, haber, röportaj vs gibi yazıları online bir alana kaydedip, daha sonra okuyabileceğim bir uygulama var mıdır diye araştırırken, Pocket adında , tam da aradığım özelliklere sahip bir uygulama olduğunu öğrendim.


Pocket sayesinde internette rastladığım, uygulamaları, Chrome Pocket Eklentisi ile tek tuşla kaydedebiliyorum. İstersem tag'ler ekleyerek bu kayıtları sınıflandırabiliyorum da.





Kaydettiğim bu içerikleri daha sonra, Pocket mobil uygulaması ile telefonumdan veya tabletimden rahat bir şekilde okuyabiliyorum. Mobil uygulamadaki senkronizasyon ayarını(Background Syncing) anında (Instantly(Push)) olarak seçtiğim için, bilgisayarımdan tek tuşla eklediğim içerikler, aynı anda otomatik olarak telefonuma ve tabletime de indiriliyor. 


Böylece, istediğim zaman istediğim yerde, internet bağlantısının olmadığı metroda bile seçtiğim bu yazıları okuyabiliyorum. 

Pocket içerikleri indirirken, direkt orijinal internet sayfasını kaydetmek yerine, yazıları en rahat okunabilecek bir formda indirmekte, okurken, yazı boyutunu, fontunu, ve arkaplan fonunu hızlı bir şekilde değiştirebilmenize imkan vermektedir.

Özetle, Pocket uygulamasının hoşuma giden aşağıdaki özelliklerini sıralayabilirim:

  • Tek tuşla hızlı kayıt imkanı
  • Kaydedilenlerin her aygıtta hızlı senkronizasyonu
  • Offline okuma imkanı
  • Yazıların en rahat şekilde okunacak formda kaydedilmesi
  • Yazı boyutu ve arka plan fontunun(gece-gündüz modu) rahat bir şekilde değiştirilebilmesi
  • Sayfa geçişlerini kitap sayfası çevirir(page flipping) gibi yapabilme imkanı
  • Yazıları dinlemeye(text-to-speech) imkan vermesi 
  • Reklamsız, ücretsiz uygulama

Pocket'a, Instapaper ve Readability uygulamaları alternatif olarak gösterilebilir belki ama, ben Pocket'tan memnunum :).

Chrome Eklentisi:

Chrome Web Store - Pocket (formerly Read It Later)

Mobil Uygulamalar:

Pocket - Android Apps on Google Play


ali kemal taşçı

25 Temmuz 2013 Perşembe

Eclipse - Restore From Local History (Can Kurtaran)

0 yorum
Çalışırken, projedeki bir dosyayı clearcase’e eklemediğim halde göz yanılmasıyla .keep dosyası(checkout'tan vazgeçilmiş geçici dosya) zannederek sildim. Proje hata verince ve dosyayı sildiğimi farkettiğimde aşağı yukarı şöyle bir ifade bende de oluştu: 



[Kullandığınız IDE’yi kodlarınızı kaydetmeden kapattığınızda: (bkz. Bir Yazılımcının Hayatındaki Gerçekler )]

Derin bir nefese alıp, konuyu google’da aratınca eclipse’in süper bir özelliğini öğrenmiş oldum.

Eclipse’den sildiğiniz kodları, aşağıdaki gibi, tekrar geri yükleyebiliyorsunuz. Bir nevi geri dönüşüm kutusu yani:





























ali kemal taşçı

8 Temmuz 2013 Pazartesi

IT eBooks

0 yorum
Aşağıdaki siteden, bilişim sektörüne yönelik, faydalı bulduğunuz, birçok e-kitabı indirebilirsiniz:

















 ali kemal taşçı

16 Mayıs 2013 Perşembe

Web Uygulamalarınız Farklı Ekran Çözünürlüklerinde Nasıl Görünüyor?

0 yorum

Geliştirdiğiniz web uygulamalarınızın(lokalinizde çalışanlar dahil) farklı ekran çözünürlüklerinde nasıl göründüklerini merak ediyorsanız, aşağıdaki uygulamadan faydalanabilirsiniz:

http://quirktools.com/screenfly/
























ali kemal taşçı

5 Kasım 2012 Pazartesi

SLR Fotoğraf Makinesi Nasıl Çalışır?

0 yorum
Bir SLR fotoğraf makinesinin nasıl çalıştığını merak ediyorsanız, buradaki simülatöre göz atmanızı öneririm.

Simulatöre göz atmadan önce aşağıdaki kavramlarla ilgili bazı özet bilgileri paylaşmak isterim:

Aperture(Diyafram) : Objektiflerin içinden geçecek olan ışığın miktarını ayarlayan mekanizmaya diyafram denir. Yüksek f değeri daha çok şeyin odaklanmasını sağlarken, kameraya giren ışığın miktarını azaltır. Düşük f- değeri ise, daha flu bir arkaplan oluşmasına neden olurken, kameraya giren ışığın miktarını arttırır.


Shutter( Enstantane): Obtüratör hızı ya da perde hızı olarak da geçebilen enstantane, deklanşör düğmesine (fotoğraf çekmek için bastığımız düğme) bastığımızda optik algılayıcıya ne kadar süre ile ışık düşürüleceğini belirtir. Yüksek enstantane fotoğraftaki hareketi dondurmaya yararken, objektife giren ışğın miktarını azaltır. Düşük enstantane objektife giren ışığın miktrarını arttırırken, fotoğraftaki hareketin bulanıklaşmasına neden olur.



ISO: ISO ile kastedilmek istenen aslında ‘ISO hızı’dır. ISO, optik algılayıcının ışığa duyarlılığını belirtir yani ISO arttıkça optik algılayıcı ışığa karşı daha hassas olur. Yüksek ISO hızı daha az ışığa gereksinim duyarken, daha grenli(kumlu) fotoğrafların oluşmasına neden olur. Düşük ISO hızı ile daha temiz(kumsuz) fotoğraflar oluşturulabilir fakat bunun için daha çok ışığa ihtiyaç duyulur.


Aşağıda farklı beyaz ayarlarındaki denemelerimi görebilir, siz de deneyebilirsiniz:








ali kemal taşçı