:: Enseignements :: Master :: M1 :: 2009-2010 :: Java Avancé ::
[LOGO]

Examen de Java (2h)


Bonne chanche Jim (& les autres).

Exercice 1 - Puzzlers (6)

Questions de cours, bien lire la question avant de répondre.
Chaque question compte pour 0,5 point.

  1. Cette classe ne compile pas. Indiquer où le compilateur indique une erreur et pourquoi ?
    public class A {
      int i = 3;
      System.out.println(i);
    }
          
  2. A quoi sert le test à null ? Ré-écrire le code pour qu'il fasse la même chose en évitant le test à null.
    String mystere() throws IOException {
      InputStream input = null;
      try {
        input = new InputStream(new File("foo.txt"));
        return new Scanner(input).nextLine();
      } finally {
        if (input != null)
          input.close();
      }
    }
          
  3. Expliquer pourquoi le code ci-dessous est affreux ?
    void displayListOfStringLength(List<String> list) {
      int size = list.size();
      for(int i=0; i<size; i++) {
        System.out.println(l.get(i).length());
      }
    }      
          
  4. Qu'est ce qu'une runtime exception ? En quoi est-elle différente d'une exception pas runtime ?
  5. Quand est-ce que la méthode finalize de java.lang.Object est appelée ?
  6. Quelle est la méthode qui est appelée dans le code ci-dessous ?
    public class A {
      void m(A a) { } // 1
      void m(B b) { } // 2
    }
    public class B extends A {
      void m(A a) { } // 3
      void m(B b) { } // 4
    }
    ...
    public static void main(String[] args) {
      A ab = new B();
      ab.m(ab);
    }
          
  7. Changer la méthode suivante pour qu'elle compile en modifiant le moins de chose possible.
    public void method() {
      List<int> list = new LinkedList<int>();
      list.add(3);
      int value = list.get(0);
    }
          
  8. Pourquoi ce code ne compile pas ? Quelle est le message d'erreur du compilateur (le mot-clé quoi).
    public class Oops {
      void m(Object o) { }
      <T> void m(T t) { }
    }
          
  9. Pourquoi new ArrayList<String>[5] ne compile pas ?
  10. Remplacer XXX par un type permettant que le programme compile. Attention, il y a un piège.
    public class Puzzler2 { 
      @SuppressWarnings("unchecked")
      private static <K, V> List>Map.Entry<K,V>> minmax(NavigableMap<K, V> map) {
        return Arrays.asList(map.firstEntry(), map.lastEntry());
      }
      
      public static void main(String[] args) {
        NavigableMap<?,String> map = new TreeMap<String,String>(Collections.singletonMap("foo", "bar"));
        XXX list = minmax(map);
        System.out.println(list.get(0).getValue().length());       // print 3
      }
    }
          
  11. Pourquoi le programme suivant ne compile pas ? Indication: the devil is in the detail.
  12. public enum Option {
      a(3), b(4)
      
      private Option(int i) {
        this.i = i;
      }
      private final int i;
    }
          
  13. Que dois-je ajouter comme instructions à la fin du main pour que si arg vaut "m1" la méthode m1 soit appelée, si arg vaut "m2" la méthode m2 soit appelée en utilisant la reflection.
    public class Reflect {
      public static void m1(String s) { }
      public static void m2(String s) { }
      
      public static void main(String[] args) {
        String arg = args[0];
        ...
      }
    }
           

Exercice 2 - Ensemble triée (14)

Le but de cet exercice est d'implanter une méthode permettant d'obtenir un ensemble triés à partir de deux ensembles triés. L'ensemble renvoyé ne devra pas stocker les élements mais agir comme une vue regroupant les deux ensembles pris en paramètre.
Il vous est vivement conseillé de lire une première fois toutes les questions de l'exercice.

  1. Quelle est l'interface représente des ensembles en Java ? Quelle est le nom de l'implantation de cette interface qui garantie que le parcours de l'ensemble se fera dans l'ordre d'insertion ?
  2.        Object o = ...
           Comparable<String> c = (Comparable<String>) o;
         
    Rappelez pourquoi le compilateur émet un warning pour le code ci-dessus ?
  3. Ecrire une méthode isSorted qui prend un ensemble en paramètre et qui renvoie un booléen indiquant si l'ensemble est trié. On considère qu'un ensemble est trié si l'on parcours ses élements dans l'ordre croissant. Attention à bien typer la signature de la méthode et au fait que le compilateur ne doit pas lever de warning pour le corps de la méthode.
    Le code ci-dessous est un exemple d'appel de la méthode isSorted.
           Set<Integer> set1 = ...
           System.out.println(isSorted(set1));
           Set<Integer> set2 = ...
           System.out.println(isSorted(set1));
         
    Rappel: Integer est un sous-type de Comparable<Integer> et String est un sous-type de Comparable<String>.
  4. Comment accélérer le code de isSorted dans le cas ou l'ensemble pris en paramètre est navigable ?
    Proposer un code à ajouter à isSorted.
  5. Ecrire une méthode checkSorted qui prend en paramètre un itérateur et qui renvoie un nouvelle itérateur. Si on utilise ce nouvelle itérateur lors d'un parcours, celui-ci vérifiera à chaque élement renvoyé que l'itérateur pris en paramètre renvoie des valeurs dans l'ordre croissant. Si un élement n'est pas dans l'ordre croissant l'iterateur devra lever une exception (A vous de trouver la bonne :). Le code devra être écrit en utilisant une classe anonyme.
    Le code ci-dessous est un exemple d'appel de la méthode isSorted.
           Iterator<Integer> it = Arrays.asList(1, 2, 4, 3).iterator();
           Iterator<Integer> it2 = checkSorted(it);
           while(!it2.hasNext()) {
             System.out.println(it2.next()); // affiche 1, 2, 4 et lève l'exception
           }
         
    Noter que si it2.hasNext() renvoie faux, it1.hasNext() renvera faux aussi, ou si vous préférez, le parcours d'it2 entrainera le parcours d'it1. Noter aussi que l'on peut utiliser checkSorted avec autre chose que des Integer.
  6. Ecrire une méthode merge qui prend en paramètre deux itérateurs que l'on suppose trié et qui renvoie un nouvelle itérateur trié. Cette méthode ne devra en aucun cas stocker les élements des deux iterateurs dans une collection intermédiaire mais renvoyé un iterateur qui parcourera les deux itérateurs pris en paramètre dans le but de renvoyé les valeurs dans l'ordre croissant. Si au moins un des deux iterateurs n'est pas triés, l'iterateur renvoyé devra lever une exception lors de son parcours.
    Le code ci-dessous est un exemple d'appel de la méthode merge.
           Iterator<Integer> it = Arrays.asList(1, 4, 5).iterator();
           Iterator<Integer> it2 = Arrays.asList(2, 4, 7).iterator();
           Iterator<Integer> it3 = merge(it, it2);
           while(!it3.hasNext()) {
             System.out.println(it3.next()); // affiche 1, 2, 4, 4, 5, 7
           }
         
    Noter que l'on peut utiliser merge avec autre chose que des Integer.
  7. Quelle est le nom de la classe abstraite qui permet d'implanter facilement des ensembles non modifiable ? Sachant qu'une des deux méthodes est size quelle est le nom de l'autre méthode à implanter si l'on veut hériter de cette classe abstraite ?
  8. On cherche à implanter la méthode mergeSet entre deux ensembles que l'on supposera triés. Comme précédemment, l'ensemble renvoyé devra être une vue des deux ensembles pris en paramètre.
    Expliquer pourquoi il est possible que la valeur de retour de la méthode size ne soit pas la somme des size des deux ensembles pris en paramètre.
  9. Fournir le code de la méthode mergeSet.