Tuesday, May 12, 2015

Java 7'de switch parametresinde String Kullanımı

Geç de olsa Java 7'de switch ifadesinde String tipinden değişkenler kullanabiliyoruz artık. Java 7 öncesinde, byte, short, int, char, enum tipinden değişkenler switch ifadesinde yer alabiliyordu. Bu tiplerin hepsi, enum ve String dışında, birer temel tip. Java 7 derleyicisinin String'i switch'de ele alış biçimine bir göz atalım. Bunun için aşağıdaki kodu javac derleyicisi ile derleyelim:
public class LostCharacters {

 public static void main(String[] args) {
  String name = args[0];
  switch (name) {
  case "Jack Shephard":
  case "Kate Austen":
  case "Hugo Reyes":
  case "James Ford":
  case "John Locke":
  case "Sayid Jarrah":
  case "Jin-Soo Kwon":
  case "Sun-Hwa Kwon":
  case "Claire Littleton":
  case "Charlie Pace":
  case "Michael Dawson":
  case "Walt Lloyd":
  case "Shannon Rutherford":
  case "Boone Carlyle":
  case "Rose Nadler":
  case "Christian Shephard":
  case "Danielle Rousseau":
  case "Bernard Nadler":
  case "Ana Lucia Cortez":
  case "Desmond Hume":
  case "Mr. Eko":
  case "Elizabeth Smith":
  case "Pierre Chang":
  case "Benjamin Linus":
  case "Penny Widmore":
  case "Alex Rousseau":
  case "Juliet Burke":
  case "Richard Alpert":
  case "Daniel Faraday":
   System.out.println(name + " is one of the Lost characters!");
   break;
  default:
   System.out.println(name + " is NOT a Lost character!");
  }
 }

}
Şimdi, yukarıdaki kodun derleyici tarafından nasıl bir çalıştırılabilir koda dönüştürüldüğüne bakalım: 
Compiled from "LostCharacters.java"
public class LostCharacters {
  public LostCharacters();
    Code:
       0: aload_0       
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return        

  public static void main(java.lang.String[]);
    Code:
       0: aload_0       
       1: iconst_0      
       2: aaload        
       3: astore_1      
       4: aload_1       
       5: astore_2      
       6: iconst_m1     
       7: istore_3      
       8: aload_2       
       9: invokevirtual #2                  // Method java/lang/String.hashCode:()I
      12: lookupswitch  { // 29

           -1943924513: 595

           -1684978205: 625

           -1426063785: 298

           -1369432366: 550

           -1344062442: 340

            -878849615: 670

            -545297877: 655

            -459778184: 326

            -232853044: 256

                224946: 475

             142311738: 355

             233453844: 505

             273451333: 312

             430276635: 535

             843130897: 400

             953172067: 565

             959585900: 415

            1012622734: 580

            1013912041: 490

            1024487124: 430

            1199123051: 610

            1248045633: 385

            1401575792: 640

            1463165277: 520

            1508695859: 445

            1528121177: 460

            1812359415: 270

            1856610985: 284

            1931228609: 370
               default: 682
          }
     256: aload_2       
     257: ldc           #3                  // String Jack Shephard
     259: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     262: ifeq          682
     265: iconst_0      
     266: istore_3      
     267: goto          682
     270: aload_2       
     271: ldc           #5                  // String Kate Austen
     273: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     276: ifeq          682
     279: iconst_1      
     280: istore_3      
     281: goto          682
     284: aload_2       
     285: ldc           #6                  // String Hugo Reyes
     287: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     290: ifeq          682
     293: iconst_2      
     294: istore_3      
     295: goto          682
     298: aload_2       
     299: ldc           #7                  // String James Ford
     301: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     304: ifeq          682
     307: iconst_3      
     308: istore_3      
     309: goto          682
     312: aload_2       
     313: ldc           #8                  // String John Locke
     315: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     318: ifeq          682
     321: iconst_4      
     322: istore_3      
     323: goto          682
     326: aload_2       
     327: ldc           #9                  // String Sayid Jarrah
     329: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     332: ifeq          682
     335: iconst_5      
     336: istore_3      
     337: goto          682
     340: aload_2       
     341: ldc           #10                 // String Jin-Soo Kwon
     343: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     346: ifeq          682
     349: bipush        6
     351: istore_3      
     352: goto          682
     355: aload_2       
     356: ldc           #11                 // String Sun-Hwa Kwon
     358: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     361: ifeq          682
     364: bipush        7
     366: istore_3      
     367: goto          682
     370: aload_2       
     371: ldc           #12                 // String Claire Littleton
     373: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     376: ifeq          682
     379: bipush        8
     381: istore_3      
     382: goto          682
     385: aload_2       
     386: ldc           #13                 // String Charlie Pace
     388: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     391: ifeq          682
     394: bipush        9
     396: istore_3      
     397: goto          682
     400: aload_2       
     401: ldc           #14                 // String Michael Dawson
     403: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     406: ifeq          682
     409: bipush        10
     411: istore_3      
     412: goto          682
     415: aload_2       
     416: ldc           #15                 // String Walt Lloyd
     418: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     421: ifeq          682
     424: bipush        11
     426: istore_3      
     427: goto          682
     430: aload_2       
     431: ldc           #16                 // String Shannon Rutherford
     433: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     436: ifeq          682
     439: bipush        12
     441: istore_3      
     442: goto          682
     445: aload_2       
     446: ldc           #17                 // String Boone Carlyle
     448: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     451: ifeq          682
     454: bipush        13
     456: istore_3      
     457: goto          682
     460: aload_2       
     461: ldc           #18                 // String Rose Nadler
     463: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     466: ifeq          682
     469: bipush        14
     471: istore_3      
     472: goto          682
     475: aload_2       
     476: ldc           #19                 // String Christian Shephard
     478: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     481: ifeq          682
     484: bipush        15
     486: istore_3      
     487: goto          682
     490: aload_2       
     491: ldc           #20                 // String Danielle Rousseau
     493: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     496: ifeq          682
     499: bipush        16
     501: istore_3      
     502: goto          682
     505: aload_2       
     506: ldc           #21                 // String Bernard Nadler
     508: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     511: ifeq          682
     514: bipush        17
     516: istore_3      
     517: goto          682
     520: aload_2       
     521: ldc           #22                 // String Ana Lucia Cortez
     523: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     526: ifeq          682
     529: bipush        18
     531: istore_3      
     532: goto          682
     535: aload_2       
     536: ldc           #23                 // String Desmond Hume
     538: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     541: ifeq          682
     544: bipush        19
     546: istore_3      
     547: goto          682
     550: aload_2       
     551: ldc           #24                 // String Mr. Eko
     553: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     556: ifeq          682
     559: bipush        20
     561: istore_3      
     562: goto          682
     565: aload_2       
     566: ldc           #25                 // String Elizabeth Smith
     568: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     571: ifeq          682
     574: bipush        21
     576: istore_3      
     577: goto          682
     580: aload_2       
     581: ldc           #26                 // String Pierre Chang
     583: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     586: ifeq          682
     589: bipush        22
     591: istore_3      
     592: goto          682
     595: aload_2       
     596: ldc           #27                 // String Benjamin Linus
     598: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     601: ifeq          682
     604: bipush        23
     606: istore_3      
     607: goto          682
     610: aload_2       
     611: ldc           #28                 // String Penny Widmore
     613: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     616: ifeq          682
     619: bipush        24
     621: istore_3      
     622: goto          682
     625: aload_2       
     626: ldc           #29                 // String Alex Rousseau
     628: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     631: ifeq          682
     634: bipush        25
     636: istore_3      
     637: goto          682
     640: aload_2       
     641: ldc           #30                 // String Juliet Burke
     643: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     646: ifeq          682
     649: bipush        26
     651: istore_3      
     652: goto          682
     655: aload_2       
     656: ldc           #31                 // String Richard Alpert
     658: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     661: ifeq          682
     664: bipush        27
     666: istore_3      
     667: goto          682
     670: aload_2       
     671: ldc           #32                 // String Daniel Faraday
     673: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
     676: ifeq          682
     679: bipush        28
     681: istore_3      
     682: iload_3       
     683: tableswitch   { // 0 to 28

                     0: 812

                     1: 812

                     2: 812

                     3: 812

                     4: 812

                     5: 812

                     6: 812

                     7: 812

                     8: 812

                     9: 812

                    10: 812

                    11: 812

                    12: 812

                    13: 812

                    14: 812

                    15: 812

                    16: 812

                    17: 812

                    18: 812

                    19: 812

                    20: 812

                    21: 812

                    22: 812

                    23: 812

                    24: 812

                    25: 812

                    26: 812

                    27: 812

                    28: 812
               default: 840
          }
     812: getstatic     #33                 // Field java/lang/System.out:Ljava/io/PrintStream;
     815: new           #34                 // class java/lang/StringBuilder
     818: dup           
     819: invokespecial #35                 // Method java/lang/StringBuilder."<init>":()V
     822: aload_1       
     823: invokevirtual #36                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     826: ldc           #37                 // String  is one of the Lost characters!
     828: invokevirtual #36                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     831: invokevirtual #38                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     834: invokevirtual #39                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     837: goto          865
     840: getstatic     #33                 // Field java/lang/System.out:Ljava/io/PrintStream;
     843: new           #34                 // class java/lang/StringBuilder
     846: dup           
     847: invokespecial #35                 // Method java/lang/StringBuilder."<init>":()V
     850: aload_1       
     851: invokevirtual #36                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     854: ldc           #40                 // String  is NOT a Lost character!
     856: invokevirtual #36                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     859: invokevirtual #38                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     862: invokevirtual #39                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     865: return        
}
Bu kodu tersine mühendislik ile çözecek olursak aşağıdaki kodu elde ederiz:
import java.io.PrintStream;

public class CompilerLostCharacters {
 public static void main(String[] paramArrayOfString) {
  String str1 = paramArrayOfString[0];
  String str2 = str1;
  int i = -1;
  switch (str2.hashCode()) {
  case -232853044:
   if (str2.equals("Jack Shephard"))
    i = 0;
   break;
  case 1812359415:
   if (str2.equals("Kate Austen"))
    i = 1;
   break;
  case 1856610985:
   if (str2.equals("Hugo Reyes"))
    i = 2;
   break;
  case -1426063785:
   if (str2.equals("James Ford"))
    i = 3;
   break;
  case 273451333:
   if (str2.equals("John Locke"))
    i = 4;
   break;
  case -459778184:
   if (str2.equals("Sayid Jarrah"))
    i = 5;
   break;
  case -1344062442:
   if (str2.equals("Jin-Soo Kwon"))
    i = 6;
   break;
  case 142311738:
   if (str2.equals("Sun-Hwa Kwon"))
    i = 7;
   break;
  case 1931228609:
   if (str2.equals("Claire Littleton"))
    i = 8;
   break;
  case 1248045633:
   if (str2.equals("Charlie Pace"))
    i = 9;
   break;
  case 843130897:
   if (str2.equals("Michael Dawson"))
    i = 10;
   break;
  case 959585900:
   if (str2.equals("Walt Lloyd"))
    i = 11;
   break;
  case 1024487124:
   if (str2.equals("Shannon Rutherford"))
    i = 12;
   break;
  case 1508695859:
   if (str2.equals("Boone Carlyle"))
    i = 13;
   break;
  case 1528121177:
   if (str2.equals("Rose Nadler"))
    i = 14;
   break;
  case 224946:
   if (str2.equals("Christian Shephard"))
    i = 15;
   break;
  case 1013912041:
   if (str2.equals("Danielle Rousseau"))
    i = 16;
   break;
  case 233453844:
   if (str2.equals("Bernard Nadler"))
    i = 17;
   break;
  case 1463165277:
   if (str2.equals("Ana Lucia Cortez"))
    i = 18;
   break;
  case 430276635:
   if (str2.equals("Desmond Hume"))
    i = 19;
   break;
  case -1369432366:
   if (str2.equals("Mr. Eko"))
    i = 20;
   break;
  case 953172067:
   if (str2.equals("Elizabeth Smith"))
    i = 21;
   break;
  case 1012622734:
   if (str2.equals("Pierre Chang"))
    i = 22;
   break;
  case -1943924513:
   if (str2.equals("Benjamin Linus"))
    i = 23;
   break;
  case 1199123051:
   if (str2.equals("Penny Widmore"))
    i = 24;
   break;
  case -1684978205:
   if (str2.equals("Alex Rousseau"))
    i = 25;
   break;
  case 1401575792:
   if (str2.equals("Juliet Burke"))
    i = 26;
   break;
  case -545297877:
   if (str2.equals("Richard Alpert"))
    i = 27;
   break;
  case -878849615:
   if (str2.equals("Daniel Faraday"))
    i = 28;
   break;
  }
  switch (i) {
  case 0:
  case 1:
  case 2:
  case 3:
  case 4:
  case 5:
  case 6:
  case 7:
  case 8:
  case 9:
  case 10:
  case 11:
  case 12:
  case 13:
  case 14:
  case 15:
  case 16:
  case 17:
  case 18:
  case 19:
  case 20:
  case 21:
  case 22:
  case 23:
  case 24:
  case 25:
  case 26:
  case 27:
  case 28:
   System.out.println(str1 + " is one of the Lost characters!");
   break;
  default:
   System.out.println(str1 + " is NOT a Lost character!");
  }
 }

}
Üretilen kodda çok özel bir durumla karşılaşmadık. Beklediğimiz gibi derleyici, önce String sabitlerin hashCode() çağrısından dönen int tipinde özet değerini (=hash value),  case sabiti olarak kullandı. Özet değeri, farklı iki String için aynı olabilir. Bu nedenle, derleyicinin, özet değerlerin eşitliği ile yetinmediğini ve equals() çağrısını kullanarak içeriklerinin de eşitliğini test ettiğini görüyoruz. Genel olarak, eğer equals() çağrısı true dönüyorsa, nesnelerin özet değerleri aynıdır. Ancak equals() çağrısı false dönüyorsa, özet değerleri aynı olabilir. İlginç bir şekilde, biz bir tane switch yazmış görünsek de, gerçekte iki farklı switch ifadesinin çalıştığını anlıyoruz. İlk switch ifadesinde case sabitleri özet fonksiyonundan gelen değerler. Birinci switch ifadesinin her bir case tanımında break ifadesi kullanıldığını görüyoruz. Burada i gibi tam sayı değişkene, her bir case bloğunda ardışıl olarak artan bir sabit atanıyor.
switch ifadesinde String kullanımında ilginç durum, String sabitlerin özet değerinin aynı olması durumunda yaşanıyor:
public class TestStringInSwitch {

 public static void main(String... args) {
  String name = args[0];
  System.out.println("AaAa".hashCode());
         System.out.println("BBBB".hashCode());
         System.out.println("AaBB".hashCode());
         System.out.println("BBAa".hashCode());
  switch (name) {
  case "AaAa":
   System.err.println("Hello Moon!");
   break;
  case "BBBB":
   System.err.println("Hello Mars!");
   break;
  case "AaBB":
   System.err.println("Hello World!");
   break;
  case "BBAa":
   System.err.println("Hello Sun!");
   break;
  default:
   System.err.println("Hello UFO!");
   break;
  }
 }

}
Burada, karakter katarlarının hepsi ("AaAa", "BBBB", "AaBB", "BBAa") için özet değeri 2031744'dür. Bu durumda, derleyici aşağıdaki çalıştırılabilir kodu üretir:
import java.io.PrintStream;

public class CompilerTestStringInSwitch {
 public static void main(String... paramVarArgs) {
  String str1 = paramVarArgs[0];
  System.out.println("AaAa".hashCode());
  System.out.println("BBBB".hashCode());
  System.out.println("AaBB".hashCode());
  System.out.println("BBAa".hashCode());
  String str2 = str1;
  int i = -1;
  switch (str2.hashCode()) {
   case 2031744:
   if (str2.equals("BBAa"))
    i = 3;
   else if (str2.equals("AaBB"))
    i = 2;
   else if (str2.equals("BBBB"))
    i = 1;
   else if (str2.equals("AaAa"))
    i = 0;
                 break;
  }
  switch (i) {
   case 0:
   System.err.println("Hello Moon!");
   break;
                 case 1:
   System.err.println("Hello Mars!");   
                 break;
                 case 2:
   System.err.println("Hello World!");   
                 break;
                 case 3:
   System.err.println("Hello Sun!");   
                 break;
   default:
   System.err.println("Hello UFO!");
  }
 }
}
Eğer şansızlık eseri case sabitlerinin tümü için özet değeri aynı olursa, switch, iç içe if-else-if ifadelerine dönüşüyor. Bu durumu biz yapay olarak yarattık. Gerçekte, bu durumla karşılaşmanız imkansız değilse bile çok düşük bir ihtimal!

Wednesday, May 6, 2015

Java 9'un Yol Haritası Belirlendi

Java 9'un çıkış tarihi ve yol haritası belli oldu:

Proposed schedule for JDK 9

mark.reinhold at oracle.com mark.reinhold at oracle.com 
Tue May 5 16:21:31 UTC 2015


Here is a proposed schedule for JDK 9:

  2015-12-10  Feature Complete
  2016-02-04  All Tests Run
  2016-02-25  Rampdown Start
  2016-04-21  Zero Bug Bounce
  2016-06-16  Rampdown Phase 2
  2016-07-21  Final Release Candidate
  2016-09-22  General Availability

The dates here are meant to leave sufficient time for broad review and
testing of the significant features of the release, in particular the
introduction of a module system and the modularization of the platform,
while maintaining the cadence of shipping a major release about every
two years.

The milestone definitions are the same as those for JDK 8 [1].

Comments from JDK 9 Committers are welcome, as are reasoned objections.
If no such objections are raised by 23:00 UTC next Tuesday, 12 May, or
if they're raised and then satisfactorily answered, then per the JEP 2.0
process proposal [2] this will be adopted as the schedule for JDK 9.

(This information is also available on the JDK 9 Project Page [3]).

- Mark

[1] http://openjdk.java.net/projects/jdk8/milestones#definitions
[2] http://cr.openjdk.java.net/~mr/jep/jep-2.0-02.html
[3] http://openjdk.java.net/projects/jdk9/

Monday, May 4, 2015

Coğrafi Konumsal Görüntü Analizi için Kurumsal Kitle Kaynak Platformu

Enterprise Crowdsourcing Platform for Geospatial Image Analysis
  
Fatih Kahraman1, Cengiz Hüroğlu1, Mümin İmamoğlu1, Büşra Y. Özcan1,
Muhammed İ. Kalkan1, Muhammet A. Hocaoğlu1, Ergin Öztürk1, Binnur Kurt2
1TÜBİTAK BİLGEM BTE, Kocaeli, Türkiye
2Omega Eğitim ve Danışmanlık, İstanbul, Türkiye
fatih.kahraman@tubitak.gov.tr, binnur.kurt@gmail.com


Özetçe—Günümüzün gelişmiş bilgisayar sistemleri, özellikle bulut bilişim teknolojilerindeki gelişmeler sayesinde veriyi işlemek için güçlü alt yapılar sunmuş olsalar da,  bazı problemlerin bilgisayarla kabul edilebilir çözümü mümkün olamamaktadır. Örnek olarak kayıp bir uçağın uydu görüntülerinde aranması ya da deprem sonrası binaların ön hasar analizi problemleri verilebilir. Son yıllarda, bu gibi durumlar için çözüm olarak, kitle kaynak olarak adlandırılan, ilgili konuda uzman olan veya olmayan gönüllülerden oluşturulan kitleden yararlanılmaktadır. Kitledeki gönüllülerin/uzmanların her birinden problemin tamamını çözmesi beklenmez. Bunun yerine problem uzayda bölütlenir ve havuzdaki üyelerden bu bölütlerden bir kısmında çalışmaları istenir. Problemin çözümü, üyelerin ürettikleri bu kısmi çözümlerin tümleştirilmesinden elde edilir. Burada açık iki problem bulunmaktadır: i. uzayın nasıl bölütleneceği ve üyelere nasıl dağıtılacağı, ii. uzman/gönüllü çözümlerinin nasıl tümleştirileceği. Bu çalışmada, bu iki problemin çözümü için geliştirilen yöntemler tanıtılmaktadır. Ayrıca tanıtılan çözümlerin gerçeklendiği ve konumsal coğrafi görüntülerin analiz edilmesini sağlayan, kurumsal kitle kaynak platformu tanıtılmaktadır.
Anahtar Kelimeler — Kitle Kaynak, Görüntü Kıymetlendirme, Uzaktan Algılama.

Abstract— Although today’s computing systems present powerful solutions to process big data with the help of recent advances in cloud computing technologies, many problems remain unsolved due to lack of acceptable algorithms. For instance, searching for a lost plane or damage assessment after earthquake on a high-resolution remote sensing satellite image are unsolved problems. In recent years, in order to solve such unsolved problems, a group of expert and non-expert people called crowd is utilized. An expert in the group is not expected to solve the original problem. Instead, geo-spatial image is partitioned in space and each expert in the pool studies the partition assigned to him/her. The solution to the original problem is obtained by merging the partial solutions. There are two open issues: i) How to partition the space and how to distribute the partitions to the crowd ii) How to merge the partial solutions. In this study, we device several algorithms to address these issues and introduce our web-based platform and crowd-sourcing implementation.
Keywords — Crowdsourcing, Image Exploitation, Remote Sensing.


Bu çalışmamız 17 Mayıs 2015 tarihinde IEEE 23. Sinyal İşleme ve İletişim Uygulamaları Kurultayında sunulacaktır!