tag:blogger.com,1999:blog-71808350627486547022007-07-22T17:33:49.570+03:00mdakin's Pardus blogM.D.Ahttp://www.blogger.com/profile/17275949971136439559noreply@blogger.comBlogger7125tag:blogger.com,1999:blog-7180835062748654702.post-52882722987072731732007-07-20T15:56:00.000+03:002007-07-21T12:23:44.066+03:00JavaStruct ve yol ayrımıYıllar önce soket haberleşmesi için tonlarca farklı türden mesajı kodlamak veya çözmek için işimizi kolaylaştıracak kodlar yazmıştık. Java sınıflarının C veya C++ structları gibi kullanılabilmesini sağlıyordu. O çalışmayı tekrar, daha az kodla, daha hızlı çalışacak şekilde ve Java 5 özelliklerini kullanarak yaptım ve <a href="http://code.google.com/p/javastruct/">JavaStruct</a> adında minik bir projeye dönüştürdüm. Özellikle gömülü sistemlerle veya başka C uygulamaları ile haberleşen Java uygulamaları yazıyorsanız çok işinize yarayabilir. Eğer sabredip eksiklerini giderirsem <a href="http://mina.apache.org/">Apache Mina</a> projesine eklenme ihtimali de var. Bu arada JavaStruct içerisinde sevgili dostum <a href="http://magnetiq.com/">Ateş Göral</a>'ın çözdüğü Adobe Photoshop Color book <a href="http://magnetiq.com/docs/PhotoshopColorBook.txt">formatını</a> okuyup yazan bir <a href="http://javastruct.googlecode.com/svn/trunk/javastruct/samples/photoshop/">örnek</a> de var.<br /><br />Son olarak ta, artık Pardus projesinin resmi geliştiricilerinden biri değilim. Tabi bu, özgür yazılımın Türkiye'deki en büyük ümidi ve en güzel ürünü Pardus için çalışmaya devam etmeyeceğim demek değil. Bir aksilik çıkmazsa yakında başlayacağım yeni <a href="http://www.google.com/">işimde</a> de Pardus için ayıracak vakit bulacağımı düşünüyorum.M.D.Ahttp://www.blogger.com/profile/17275949971136439559noreply@blogger.comtag:blogger.com,1999:blog-7180835062748654702.post-47714475113234133092007-06-25T09:54:00.000+03:002007-06-25T09:59:57.596+03:00Korkunç kodlarff'in blogunda ilginç bir <a href="http://jroller.com/page/ff?entry=code_of_horror">proje faciası yazısı</a> gözüme çarptı. Exceptionlarla ilgili bölüm neler yapılmaması konusunda gayet eğitici, ilk örnekteki sıralama işlemi de evlere şenlik. Gerçekten de arkadaşlar hazır sıralama fonksiyonlliğini kullamak yerine kendileri bir tür <a href="http://en.wikipedia.org/wiki/Selection_sort">selection sort</a> algoritması yapmaya çalışmış ama felaket bir şekilde :).M.D.Ahttp://www.blogger.com/profile/17275949971136439559noreply@blogger.comtag:blogger.com,1999:blog-7180835062748654702.post-30672289959820557942007-04-29T18:22:00.000+03:002007-04-29T19:04:56.226+03:00Erlang, Java, Büyük sayılarla çarpma ve OptimizasyonGeçen gecenin bir yarısı <a href="http://www.metin.org/gunluk/">Barış</a>'la kısa bir süre konuştuk. Erlang ile yazdığı bir faktöryel kodunu ve 100.000! hesabının sonuçlarını gösterdi. Birden fazla sürecin mesaj aktarımı ile yaptığı hesaplama gerçekten ilginç. Bir nokta da ikimizin de Erlang kodlarının pek hoş görünmediği konusunda hemfikir olması :). Barış belki Erlang ile ilgili tecrübeleri konusunda bir şeyler yazar o yüzden o kodları buraya koymuyorum.<br /><br />100.000! işlemi acaba java'da ne kadar sürer diye hemen bir deneme yapmaya karar verdim. Öncelikle klasik sayıların büyüklüğü yetmeyeceğinden BigInteger kullanmak gerekiyor. Klasik recursive faktöryel hesabı tekniği için şu kod yeterli:<pre><br />public static BigInteger factoriel(long n){<br /> if (n == 1) return BigInteger.ONE;<br /> return BigInteger.valueOf(n).multiply(factoriel(n - 1));<br />}<br /></pre><br />Tabi bu kod parçası n'nin büyük değerlerinde (n>5000) stack taşmasına yol açacağından rekürsif olmayan daha basit bir yönteme geçmem gerekti, stack'i büyüterek de problem aşılabilirdi ama tembellik işte. Rekürsif çağrı yapmayan kod:<pre><br />public static BigInteger factoriel2(long n){<br /> BigInteger res = BigInteger.ONE;<br /> for(long i=2 ; i<=n; i++){<br /> res = res.multiply(BigInteger.valueOf(i));<br /> }<br /> return res;<br />}</pre><br />Bu metodun performansı fena değil.. <pre><br />n süre(saniye) <br />----------------------<br /> 10000 0.84 <br /> 20000 2.55<br /> 40000 10.09 <br /> 60000 23.41<br /> 80000 42.57<br />100000 67.8</pre><br />Acaba performansı biraz iyileştirebilir miyim diye düşünürken aklıma yukarıdaki algoritma ile BigInteger'in çarpma yöntemini gereksiz yere yorduğum geldi.. Algoritmada rakam aşırı büyümesine rağmen bu dev rakamı sürekli minik sayılarla çarpılıyordu. O yüzden küçük bir numara yaparak rakamları 200'lü gruplar halinde çarpıp ara çarpımları bir listeye koyup en sonunda sadece bu listedekileri çarpmayı denedim. Sonuçta şu rakamları elde ettim..<pre><br />n süre(saniye) <br />----------------------<br /> 10000 0.32 <br /> 20000 0.70<br /> 40000 2.08 <br /> 60000 5.13<br /> 80000 9.25<br />100000 14.82</pre><br />Bu basit optimizasyonla faktöryel hesabım yaklaşık 5 kat iyileşti. tabi bedeli de algoritmanın biraz daha karışması.. Algoritmayı çok threadedli yapıp çift çekirdekli bir makinede de denemek istiyorum.<br /><br />100000!'in sonucu 456 bin basamaklı bir sayı ve String'e dönüştürmek maalesef çarpmanın kendisinden fazla sürüyor (107s). <br /><br />Bir sonraki blog girişinde belki büyük sayılarla çarpmanın nasıl yapıldığından bahsederim. Bu arada Python çalışmaya devam ediyorum. <br /><br />Tüm testler için ortam özellikleri: AMD AthlonXP 2.2Ghz, Pardus 2007.1, Java 6, JVM Parametreleri: -server -Xms500m -Xmx1000mM.D.Ahttp://www.blogger.com/profile/17275949971136439559noreply@blogger.comtag:blogger.com,1999:blog-7180835062748654702.post-60634138705716595492007-04-26T15:14:00.000+02:002007-04-26T16:07:23.284+02:00Java ve Thread'lerThread programlama zor iştir. Ne kadar tecrübeli olursanız olun mutlaka bir şeyleri gözden kaçırırsınız, bir yerlerde ölümcül kilitlenme, yarış durumu veya performans sorunu çıkar ve bu durumla çoğu zaman sadece sistem belli bir yük altındayken veya özel bir durumdayken karşılaşırsınız, dolayısıyla çok threadli bir uygulamada hata ayıklaması da çok zordur.<br /><br />Java 5 ile beraber eş zamanlı programlamanın üstatlarından <a href="http://g.oswego.edu/dl/">Doug Lea</a>'nın yürütücülüğünü yaptığı JSR-166 yani<span style="color: rgb(51, 51, 255);"> <a href="http://www.google.com.tr/url?sa=t&ct=res&amp;cd=1&url=http%3A%2F%2Fjava.sun.com%2Fj2se%2F1.5.0%2Fdocs%2Fapi%2Fjava%2Futil%2Fconcurrent%2Fpackage-summary.html&amp;ei=7qcwRtf0KZSqnQOw-Ym0BA&usg=AFrqEzf0yZ6Vq2lEDDZ3SKkdXwxlGWeuCg&amp;sig2=AsjqKUIsaNyNa9JA8Mb9eA">java.util.concurrent</a></span> paketi kulanıma sunuldu. Java'yı çok threadlı programlama alanında bir kaç seviye daha yukarı taşıyan ve kütüphane bazında belki de Java 5'in en büyük yeniliği diyebileceğim bu yeni pakette neler var?<br /><ul><li><span style="font-weight: bold;">Yeni Thread Güvenli Koleksiyonlar:</span> ConcurrentHashMap, Queue (PriorityQueue, LinkedList, ConcurrentLinkedQueue) ve CopyOnWriteArrayList ve CopyOnWriteArraySet. Özellikle iterasyon sırasında kilitlemeye gerek kalmaması, çok threadin erişimi sırasında daha iyi performans göstermeleri dikkati çeken yenilikler<br /></li><li><span style="font-weight: bold;">Görev Yönetim Sınıfları: </span>Executor, ExecutorService ve Future gibi görev yönetimi konusunda kolaylık sağlayan arayüz ve sınıflar. ExecutorService sayesinde bir thread havuzu oluşturup kullanmak artık çocuk oyuncağı.</li><li><span style="font-weight: bold;">Senkronizasyon Sınıfları</span>: Semaphore, Mutex gibi temel yapılar ve CyclicBarrier, CountDownLatch ve Exchanger gibi birden fazla threadin davranışını kontrol eden Sınıflar. Örneğin çok işlemcili bir sistemde büyük bir işi 10 thread'e paylaştırmak, bu 10 thread'in işi bitince çözümün doğruluğunu test edip, sonuç yanlışsa tekrar başlamak istiyorsunuz. CyclicBarrier sınıfı sayesinde belli miktarda thread'in iş parçalarını yapmasını, ve tüm threadler işini tamamlayana kadar bekleyip tekrar başlamalarını sağlamak mümkün.<br /></li><li><span style="font-weight: bold;">Alt Seviye Senkronizsyon Sınıfları</span>: Lock, ReadWriteLock ve Atomic değişkenler. Lock sınıfının gerçeklemesi olan ReentrantLock sayesinde Java'da synchronized anahtar kelimesi ile gerçekleştirilen senkronizasyon fonksiyonelliğine daha iyi performansla ve daha çok fonksiyonellikle erişmek mümkün.Peki artık synchronized kelimesini kullanmayacak mıyız? Hayır, çünkü temel senkronizasyonu sağlamanın kolay yolu olan bu yöntemin en büyük artısı kilitleme ve açma işlemlerini otomatik olarak yapması. Lock gibi yapılarda mutlaka kod içerisinde .lock() ve .unlock() metodlarını kullanmak gerekiyor.<br /></li></ul>Bu yeni sınıflarla ilgili bulabildiğim en iyi öğretici doküman IBM dokümanları arasındaki Brian Goetz'in "<a href="http://www-128.ibm.com/developerworks/edu/j-dw-java-concur-i.html">Concurrency in JDK 5.0</a>" dokümanı (Malesef kayıt gerektiriyor) google'de aynı isimle aratırsanız bir kopyasını bulabilirsiniz :). Brian Goetz'in JavaPolis'te konu ile ilgili <a href="http://media.libsyn.com/media/javapolis/JavaPolis_2005_Concurrency_Talk.mp3">konuşmasını</a> dinleyebilir veya sunumu <a href="http://developers.sun.com/learning/javaoneonline/2005/coreplatform/TS-5807.pdf">okuyabilirsiniz</a>. Bunun yanında <a href="http://java.sun.com/">java.sun.com</a> sitesinde de çeşitli <a href="http://java.sun.com/developer/technicalArticles/J2SE/concurrency/">dokümanlar</a> var.M.D.Ahttp://www.blogger.com/profile/17275949971136439559noreply@blogger.comtag:blogger.com,1999:blog-7180835062748654702.post-9952779206045116142007-04-19T12:04:00.000+02:002007-04-19T14:11:38.851+02:00Python ve JavaPython gerçekten de tatlı bir dil (gereksiz "self"'leri ve görüntü kirleten __hede__ leri saymazsak :) )<br /><br />Geçenlerde Peter Norwig'in minicik bir Python kodu ile nasıl yazım düzeltme işi yapılabileceğine dair <a href="http://www.norvig.com/spell-correct.html">yazısını</a> biraz inceleme şansım oldu. Gerçekten de çok güzel bir şekilde işi halletmiş Norwig. Temel olarak bir sözlük ve bu sözlük üzerinde verilen bir kelimenin 1-2 düzeltme mesafesindeki varyasyonlarının aranmasından ibaret olan algoritma gerçekten de şaşırtıcı derecede kısa. Aşağıdaki Python kodu ile verilen bir kelimedeki bir düzeltme mesafesinde olabilecek varyasyonları bulabiliyorsunuz.<br /><pre>def edits1(word):<br />n = len(word)<br />return set([word[0:i]+word[i+1:] for i in range(n)] + # deletion<br /> [word[0:i]+word[i+1]+word[i]+word[i+2:] for i in range(n-1)] + # transposition<br /> [word[0:i]+c+word[i+1:] for i in range(n) for c in alphabet] + # alteration<br /> [word[0:i]+c+word[i:] for i in range(n+1) for c in alphabet]) # insertion<br /></pre><br />Bu tekniğin bir benzeri Myspell ve Hunspell içerisinde de kullanılıyordu ve Daha önceden zemberek için de denemeyi düşünmüştük. Yukarıdaki kodun Java'cası şu şekilde oluyor:<br /><pre><br />public static List adaylariBul(String s, char[] alfabe){<br /> List adaylar = new ArrayList>(20);<br /> // Tek harf Eksik olanları bul<br /> for(int i=0; i< s.length(); i++){<br /> adaylar.add( s.substring(0 ,i) + s.substring(i+1) ); <br /> }<br /> // Degisiklikleri ve eklemeleri bul<br /> for(char c : alfabe){<br /> for(int i=0; i< s.length(); i++){<br /> adaylar.add( s.substring(0 ,i) + c + s.substring(i+1) ); <br /> adaylar.add( s.substring(0 ,i) + c + s.substring(i) );<br /> }<br /> }<br /> // Transpozisyonları bul<br /> for(int i=0; i< s.length()-1; i++){<br /> adaylar.add( s.substring(0 ,i) + s.charAt(i+1) + s.charAt(i) + s.substring(i+2) ); <br /> }<br /> return adaylar;<br />}<br /></pre><br />Java versiyonu nispeten karmaşık görünse de anlaşılması pek güç değil, Python'un String dilimleme kolaylıkları Java'da yok. Yine de Java programcılarının çoğu kodların biraz kalabalıkça olmasına ("verbose") alışıktır ve garipsemez. Kodlar aralarında küçük farklar var, Python kodu sanırım sadece Ascii kodlu Stringler için çalışıyor ve alfabe'yi global bir değişkenden alıyor. <br /><br />Peki bu kodlar Türkçe için kullanılabilir mi? Kısmen evet.. eğer yazının orijinalindeki en çok kullanılan kelimeler büyük bir sözlükten okunup onunla bu metodlar kullanılarak elde edilen karşılaştırılacaksa bir miktar başarı sağlanabilir. Ancak Türkçe gibi kelime üretim olasılıkları çok çok fazla olan eklemeli dillerde hem başarım belli bir seviyede kalacaktır hem de bellek kullanımı kötü olacaktır.<br /><br />Ancak bu yaklaşımın bir varyasyonunu yine de Zemberek'te hatalı kelimeler için kök seçiminde kullanmayı denemek istiyorum.M.D.Ahttp://www.blogger.com/profile/17275949971136439559noreply@blogger.comtag:blogger.com,1999:blog-7180835062748654702.post-71744244526129006682007-04-15T00:46:00.000+02:002007-04-15T10:58:24.430+02:00byte byteJava'da tüm veri tipleri işaretlidir, yani C deki <span style="font-weight: bold;">unsigned</span> kavramı yoktur. Dolayısıyla Java ile biraz alt seviye işlem yapmış olanlar <span style="font-weight: bold;">byte</span> cinsinden verilerin sadece -128 ile +127 arasındaki değerleri taşıdığını bilirler. Hatta çoğu yerde byte cinsinden değişkene 0-255 arası bir değer atandığı zaman, onun işaretsiz versiyonunu elde etmek için <span style="font-weight: bold;">0xFF</span> ile <span style="font-weight: bold;">&</span> (bit and) işleminden geçirirler, peki bu nasıl çalışıyor? Örneğin,<br /><pre>// b'nin değeri -15<br />byte b = (byte)241;<br /><br />// y'nin değeri -15<br />int y = b;<br /><br />// x'in değeri 241<br />int x = b & 0xFF;<br /></pre><br />Bir byte'lık veriyi 0xFF ile & yapmak yine aynı değeri vermez mi? Java spesifikasyonuna göre byte, short gibi işlemler üzerinde gerçekleştirilen bit işlemleri sırasında operandlar otomatik olarak int'e dönüştürülür.<br /><pre>byte a = (byte) 0xf1; // int olarak +241<br />int x = a;</pre>deyince x değeri de -15 yani hex olarak 0xfffffff1 değerini alır.<br /><br />Siz herhangi bir byte değerini 0xff ile and işlemine tabi tutarsanız (a & 0xff) işlem sırasında iki değer de int karşılıklarına dönüştürülür. yani aslında şu işlemi yapmış olursunuz:<br /><pre>0xFFFF FFF1 &amp; 0x0000 00FF</pre>ve sonuç ta işaretin kaybolduğu, rakamın pozitif karşılığıdır. yani +241 (0xF1)<br /><br />buradaki önemli noktalar:<br /><ul><li>byte -> int dönüşümünde işaret korunur</li><li>bit işlemleri sırasında byte ve short tipindeki değerler değil int karşılıkları kullanılır.</li></ul>Java ile ilgili arada bir küçük notlar yazmaya devam edeceğim.M.D.Ahttp://www.blogger.com/profile/17275949971136439559noreply@blogger.comtag:blogger.com,1999:blog-7180835062748654702.post-91019229310688374712007-03-21T16:45:00.000+02:002007-03-21T16:48:02.077+02:00Testing..Hopefully this will be a place where I'll post random rumblings about my adventures as a <a href="http://www.pardus.org.tr/eng/index.html">Pardus</a> developer.M.D.Ahttp://www.blogger.com/profile/17275949971136439559noreply@blogger.com