mercoledì 6 novembre 2013

Q39

Which two properly implement a Singleton pattern?

A.
class Singleton {
     private static Singleton instance;

     private Singleton() {
     }

     public static synchronized Singleton getInstance() {
          if (instance == null) {
                instance = new Singleton();
          }
          return instance;
     }
}

 

B.
class Singleton {
     private static Singleton instance = new Singleton();
 

     protected Singleton() {
     }

     public static Singleton getInstance() {
          return instance;
     }
}


C.
class Singleton {
     Singleton() {
     }

     private static class SingletonHolder {
          private static final Singleton INSTANCE = new Singleton();
     }

     public static Singleton getInstance() {
          return SingletonHolder.INSTANCE;
     }
}


D.
enum Singleton {
     INSTANCE;
}


La risposta è A e D

Il singleton rappresenta un tipo particolare di classe che garantisce che soltanto un’unica istanza della classe stessa possa essere creata all’interno di un programma.
Per ottenere questo comportamento è necessario avvalersi del modificatore di accesso private anche per il costruttore della classe (cosa che generalmente non viene mai praticata in una classe standard) ed utilizzare un metodo statico che consenta di accedere all’unica istanza della classe.
In generale, la scelta del singleton viene effettuata in tutti quei casi in cui è necessario che venga utilizzata una sola istanza di una classe.
Ciò consente di:
  • Avere un accesso controllato all’unica istanza della classe
  • Avere uno spazio di nomi ridotto
  • Evitare la dichiarazione di variabili globali
  • Assicurarsi di avere un basso numero di oggetti utilizzati in condivisione grazie al fatto che viene impedita la creazione di nuove istanze ogni volta che si voglia utilizzare la stessa classe.
Un altro approccio è quello di usare un enumeratore.

Questo approccio sfrutta il fatto che le costanti enum sono costruite la prima volta che si utilizza una classe.


A.
Questo codice realizza un Singleton pattern.


B.
Il modificatore del costruttore è protected e quindi non si realizza il Singleton pattern.

C.
Il modificatore del costruttore è default e quindi non si realizza il Singleton pattern.

D.
Questo codice realizza un Singleton pattern utilizzando ENUM.

 Riferimenti:

Q38


Given the code fragment:

public class Employee {
String name;
transient String companyName;
}

 

import java.io.Serializable;

public class Manager extends Employee implements Serializable {

     String mgrId;

     public static void main(String s[]) throws Exception {

          Manager mgr = new Manager();

     }

}





What is the result?

A.
M001, ,

B.
M001, null, null

C.
M001, Sam,

D.
M001, Sam, null

E.
M001, Sam, ABC Inc

F.
Compilation fails

G.
A NullPointerException is thrown at Runtime

La risposta non c'è perché la domanda è probabilmente incompleta.

Q37

Select four examples that initialize a NumberFormat reference using a factory.

A.
NumberFormat nf1 = new DecimalFormat(); NO

B.
NumberFormat nf2 = new DecimalFormat(“0.00″) ; NO

C.
NumberFormat nf3 = NumberFormat.getInstance();

D.
NumberFormat nf4 = NumberFormat.getIntegerInstance();

E.
NumberFormat nf5= DecimalFormat.getNumberInstance ();

F.
NumberFormat nf6 = Number Format.getCurrencyInstance () ;
 

Risposta C,D,E ed F

Il modello di progettazione Metodo Factory (Factory Method design pattern) è un modo per incapsulare la creazione di oggetti. Senza un metodo factory (fabbrica) si deve chiamare direttamente il costruttore di una classe :

Pippo x = new Pippo();

come nelle risposte A e B.

invece col Factory Method design pattern si crea dentro la classe un metodo factory :

Pippo x Pippo.creazione();

            

Tutti i costruttori vengono messi come privati in modo da non essere accessibili all’esterno della classe, mentre il metodo factory viene messe static in modo da poter essere chiamato anche senza un’istanza della classe.

NumberFormat ha un molti metodi factory :

public static final NumberFormat getInstance()
public static NumberFormat getInstance(Locale inLocale)
 

public static final NumberFormat getNumberInstance()
public static NumberFormat getNumberInstance(Locale inLocale)

public static final NumberFormat getIntegerInstance()
public static NumberFormat getIntegerInstance(Locale inLocale)

public static final NumberFormat getCurrencyInstance()
public static NumberFormat getCurrencyInstance(Locale inLocale)

public static final NumberFormat getPercentInstance()
public static NumberFormat getPercentInstance(Locale inLocale)


utilizzati nelle risposte C,D,E ed F.

Riferimenti:
http://java.boot.by/ocpjp7-upgrade/ch02s04.html

 

Q36


Given the code fragment:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
 

class Base {
     public void process() throws IOException {
          FileReader fr = new FileReader ("userguida.txt");
          BufferedReader br = new BufferedReader (fr);
          String record;
          while ((record = br.readLine())!=null){
                System.out.println(record);
          }
     }
}

public class Derived extends Base {
     public void process() throws Exception {
          super.process();
          System.out.println("process");
     }

     public static void main (String[] args){
          try {
                new Derived.process();
          } catch (Exception e) {
                System.out.println(e.getClass());
          }
     }
}

 
If the file userguide.txt does not exist, what is the result?

A.
An empty file is created and success is printed.


B.
class java.io.FileNotFoundException.


C.
class java.io.IOException.


D.
class java.lang.Exception.


E.
Compilation fails.



La risposta è E .

Ci si aspetta che le istanze della classe Base aderiscano al contratto dichiarato, quindi che process aderisca alla clausola trhows IOException . Sovrascrivendo process e cambiando l’eccezione con una più alta si ha la rottura del contratto e anche la violazione del principio di sostituzione di Liskov.

Multiple markers at this line
            - Exception Exception is not compatible with throws clause in Base.process()
            - overrides Base.process

Se invece il metodo che sovrascrive avesse utilizzato una eccezione più bassa del metodo padre il codice avrebbe compilato :

class Base {
     public void process() throws Exception  { ...
public void process() throws IOException { ...

In questo caso ovviamente si avrebbe avuto un errore all’invocazione del super : Unhandled exception type Exception
 

Q35

Given:

public class Counter {
     public static int getCount(String[] arr) {
          int count = 0;
          for (String var : arr) {
                if (var != null)
                     count++;
          }
          return count;
     }

     public static void main(String[] args) {
          String[] arr = new String[4];
          arr[1] = "C";
          arr[2] = "";
          arr[3] = "Java";
          assert (getCount(arr) < arr.length);
          System.out.print(getCount(arr));
     }
}

And the commands:

javac Counter.java
java ‘ea Counter

What is the result?

A.
2


B.
3


C.
NullPointException is thrown at runtime


D.
AssertionError is thrown at runtime


E.
Compilation fails



Risposta B
Il codice compila e quindi la E è falsa . Quando si eseguono i comandi si fa prima una compilazione con javac e poi un lancio con java. Il parametro ea serve ad attivare le asserzioni. Da eclipse si può fare la stessa cosa scrivendo –ea in Run ConfigurationsArgumentsParametri VM .
Se non si attivano le asserzioni queste saranno ignorate.
Il flusso del programma è :
1)    Si crea un array lungo 4
2)    Si inseriscono 3 elementi nelle posizioni 1,2 e 3 e si lascia l’elemento 0 a null.
3)    Il metodo getCount conta gli elementi non nulli dell’array, quindi 3.
4)    L’asserzione  verifica che questo conto (3) sia minore della lunghezza dell’array (4) . quindi l’asserzione è verificata e il flusso procede oltre.
5)    Alla fine si stampa il conto e quindi si ha la stampa del numero 3.
Per vedere cosa succede se l’asserzione non è verificata si può aggiungere un elementi non nullo in posizione 0 : arr[0] = "C"; , oppure cambiare l’asserzione : assert (getCount(arr) == arr.length); . In questo caso l’asserzione non viene verificata e si ottiene il messaggio di errore :

Exception in thread "main" java.lang.AssertionError
     at Counter.main(Counter.java:16)
 
 
Riferimenti:
 

Q34

Given the code fragment:

     String s = "Java 7, Java 6";
     Pattern p = Pattern.compile("Java.+\\d");
     Matcher m = p.matcher(s);
     while (m.find()) {
          System.out.println(m.group());
     }

What is the result?

A.
Java 7

B.
Java 6

C.
Java 7, Java 6

D.
Java 7
java 6

E.
Java

Risposta C

1) si definisce una stringa s = "Java 7, Java 6".

2)si definisce un Pattern p. Un pattern è una rappresentazione compilata di una espressione regolare.

Java. significa : ogni espressione che inizia con Java e a destra ha un qualunque carattere ( . ); nel nostro caso il carattere è uno spazio.

\\d Significa una cifra cioè un carattere in [0-9]

+ Indica una o più occorrenze.

Quindi Java.+\\d indica : trova tutte le sottostringhe che iniziano per Java, proseguono con un carattere qualsiasi e terminano con una qualunque cifra :
 

L’unica modalità richiesta dall’esame è quella greedy. L’espressione regolare sopra scritta può essere intesa in due modi :
 

Infatti .+ è greedy . Se avessimo voluto un quantificatore diverso, ad esempio reluctant avremmo dovuto usare:  .?+  .

Quindi l’unica corrispondenza che viene trovata è l’intera stringa.

3) Una volta creato il pattern, cioè il “comportamento” si può creare il matcher, cioè la “corrispondenza” tra l’ingresso e le regole dell’espressione regolare.

4)Il matcher a questo punto può essere scorso con il metodo find()che trova di volta in volta la corrispondenza successiva. In pratica quindi si stampano tutte le corrispondenze trovate.

Q33

Given:

import java.util.concurrent.atomic.AtomicInteger;

public class AtomicCounter {
     private AtomicInteger c = new AtomicInteger(0);
 
     public void increment() {
          // insert code here
     }
}


Which line of code, inserted inside the increment () method, will increment
the value of c?

A. c.addAndGet();

B. c++;

C. c = c+1;

D. c.getAndIncrement ();

 

Risposta  D

A
Questo codice non compila perché non viene passato l’obbligatorio parametro di ingresso :
The method addAndGet(int) in the type AtomicInteger is not applicable for the arguments ()
Dovrebbe essere c.addAndGet(1); .

B
L’operatore postifix (++)  si applica solo agli interi e quindi il codice non compila essendo c un AtomiInteger .
Type mismatch: cannot convert from AtomicInteger to int

C
L’operatore somma (+) non è applicabile al tipo AtomicInteger.
The operator + is undefined for the argument type(s) AtomicInteger, int

D
Questo è il modo corretto di incrementare un AtomicInteger di 1 .
Riferimenti :