21 Kasım 2014 Cuma

Fotoğraf Okuma

0 yorum
Uzun bir süredir, tamamen kafa dağıtmak maksadıyla, amatör olarak fotoğraf çekmekteyim ve çektiğim fotoğrafları paylaşmaktayım. Aynı zamanda, bu konuda kendimi geliştirme maksadıyla, çok fazla fotoğraf izlemekte ve fotoğraf üzerine yazılar okumaktayım. Zaman zaman, bu yazılardan edindiğim /derlediğim bilgileri de faydam dokunur diye burada  paylaşmaya çalışıyorum.

Birçok fotoğraf görüp, bu konuda yazılar okudukça, sadece görsel olarak fotoğraf çekmek yerine fotoğrafla birşeyler anlatmaya çabalıyorum. Ne kadar oluyor bilmiyorum. Dediğim gibi bu konuda kendimi geliştirmeye çalışıyorum. Zamanla, bir anlam çıkaramadığım, yani çok  da birşey anlatmadığını düşündüğüm fotoğraflarımı siliyorum. İleride daha uzun soluklu projeler yapmayı hedefliyorum. Tabi bunun için daha odaklı bir şekilde çalışıp, daha fazla zaman ayırmak ve ustalardan faydalanmak gerekecek.

Sözü fazla uzatmadan, fotoğraf çekmek kadar, fotoğraf okumanın da oldukça yetenek isteyen bir kavram olduğunu düşünüyorum. Bkz. Oğuz Haksever'le O anlar.

Ben de burada, çektiğim birkaç fotoğrafıma yapılan ve çok da hoşuma giden bazı yorumları paylaşmak istedim :).

Untitled

Ebru Şimşek:
Bir genç duvara yaslanmış, bir dizini kırmış, elindeki sigarasından bir nefes çekiyor... Bir yandan uzakta muhabbete dalmış grubu yan gözlerle izliyor, yanlarına gitmeye cesareti yok,yalnız ve cool görünmeye çabalıyor....... Gibi bir ilk izlenim hikayesi bu fotoğraftan..



son

Nadir Aşçıoğlu:
Bu fotoğrafın bana anlattığı hikaye; sonlu kavramlar ve ölüm. Yazın sonu kurumuş ağaçlar, günün sonu batan güneş, kimilerine göre ölümün habercisi kargalar... 





lale

NadirAşçıoğlu:

Lale, başlıbaşına bir şaheser... ve arka planda, onun tarih sahnesinde pek meşhur olmasını sağlayan medeniyyetin mimari şaheserlerinden biri... 



ali kemal taşçı

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şçı