1 punto

Anuncio
Examen de Programación
Convocatoria 22 de Junio 2005
Licenciatura de Lingüística y Nuevas Tecnologías
Pregunta 1 [1 punto]
Tenemos el siguiente programa:
public class P1 {
public static void main(String args[ ]) {
P1 un = new P1();
P1 dos = new P1();
P1 tres = null;
System.out.println("un == dos: " + (un == dos)); // 1
System.out.println("dos == tres: " + (dos == tres)); // 2
P1 cuatro = dos;
System.out.println("dos == cuatro: " + (dos == cuatro)); // 3
dos = null;
System.out.println("dos == cuatro: " + (dos == cuatro)); // 4
}
}
¿Qué imprime cada uno de los cuatro System.out.println numerados 1, 2, 3 y 4
y por qué? [1 punto]
1. Imprime “false” porque las variables de objeto “un” y “dos” refieren a 2
objetos distintos, cada cual construido con el constructor por defecto de
P1 en las líneas anteriores.
2. Imprime “false” porque “dos” refiere a un objeto concreto, mientras “tres”
tiene la referencia nula (es decir, no refiere a ningún objeto concreto).
3. Imprime “true”, porque al escribir en la línea anterior “P1 cuatro = dos”,
asignamos a “cuatro” la misma referencia que “dos”, es decir que las 2
variables de objeto apuntan al mismo objeto.
4. Imprime “false” porque al escribir en la línea anterior “dos = null”,
cambiamos la referencia de “dos” a null pero no la de “cuatro” que sigue
siendo la misma (apunta a un objeto concreto).
1
Pregunta 2 [2 puntos]
Tenemos en la misma carpeta las clases P2A (en el archivo P2A.java) y P2B
(en el archivo P2B.java).
P2A.java
public class P2A {
public static int c = 3;
public int i = 2;
private int j = 4;
}
P2B.java
public class P2B {
public static void main(String[] args) {
int i = -1;
P2A un = new P2A();
}
}
a) Explicar el significado de cada una de estas 5 denominaciones,
ilustrandolas con las variables dentro de P2A y P2B: [1.25 punto]
1. Variable de objeto: Una variable de objeto contiene una referencia a un
objeto. Por ejemplo “un” dentro de P2B es una variable de objeto, contiene
referencias a objetos de tipo P2A.
2. Variable de tipo básico: Una variable de tipo básico contiene el valor de
un tipo básico como int, float, char, double or bolean. Por ejemplo, las
variables i, j y c dentro de P2A son de tipo básico, también lo es i dentro de
P2B.
3. Variable local: Una variable local es una variable cuyo ámbito es un
bloque de instrucciones: se puede acceder dentro de este bloque pero no
fuera del bloque. Un bloque puede ser el “cuerpo” de un bucle o un
condicional o de un método. Por ejemplo, en P2B, “i” y “un” son variables
locales al método main.
4.Variable de clase: Una variable de clase, a diferencia de una variable de
instancia, es una variable común a toda la clase. No es especifica a cada
objeto creado. Una variable de clase está definida con la palabra clave
“static”, como por ejemplo la variable “c” dentro de P2A.
5. Variable de instancia: Una variable de instancia describe una propiedad
de un objeto, y como tal, es especifica a cada objeto creado. Por ejemplo,
las variables “i” e “j” dentro de P2A son variables de instancia.
b) Mostrar cual es la manera correcta y más típica de acceder dentro del
main de P2B a cada una de las variables definidas dentro de P2A.java (si es
que se pueden acceder...). [0.5 puntos]
2
un.i = 3;
P2A.c = 4;
// la variable j no se puede acceder desde fuera de su clase: esta
// declarada como “private”. Habría que escribir un método “getj” para
// acceder a esta variable
c) Supongamos que llamamos dentro del main de P2B los siguientes
métodos: [0.25 puntos]
int num = Integer.parseInt(args[0]);
String cadena = "Hola" ;
int tamanyo = cadena.length();
Explicar por qué los métodos parseInt y length se llaman de forma diferente.
parseInt es un método de clase definido con la palabra clave “static”, no
pertenece a ningún objeto en concreto sino que pertenece a la clase, por
lo que para llamarlo, no hace falta crear un objeto: ponemos el nombre
de la clase para que Java pueda saber donde está ubicado dentro del
paquete. Por otro lado, el método length es un método de instancia que
define el comportamiento de un objeto especifico, en este caso de un
objeto de tipo String especifico.
Pregunta 3 [1 punto]
Tenemos el siguiente programa:
import java.util.*;
public class P3 {
public static void main(String[ ] args) {
String cadena = "Hola! Me llamo Harry. Como estas?";
StringTokenizer st = new StringTokenizer(cadena,"!.?");
while (st.hasMoreTokens()) {
String token = st.nextToken();
System.out.println(token);
}
}
}
a) ¿Qué imprime el programa a la ejecución? (A notar que el segundo
argumento de StringTokenizer es “!.?”, es decir punto de exclamación,
punto, punto de interrogación) [0.5 puntos]
Se imprime lo siguiente (a notar que se conserva los espacios entre las
palabras):
Hola
Me llamo Harry
Como estas
3
b) ¿Por qué hacemos import java.util.* al principio de la clase? [0.5 puntos]
Porque la clase StringTokenizer esta definida dentro del paquete
java.util
Pregunta 4 [1.5 punto]
a) ¿Qué pasa al ejecutar el siguiente código? [0.75 puntos]
public class P4a {
public static void doIt(int[] z)
{
int temp = z[z.length-1] ;
z[ z.length-1 ] = z[0] ;
z[0] = temp;
}
public static void main ( String[] args ) {
int[] myArray = {0, 1, 2, 3, 4} ;
doIt( myArray );
for (int j=0; j<myArray.length; j++ )
System.out.print( myArray[j] + " " ) ;
}
}
Se imprime: 4 1 2 3 0
4
b) ¿Qué pasa al ejecutar el siguiente código? [0.75 puntos]
public class P4b {
static void doIt( int[ ] z )
{
int[ ] a = z ;
a[0] = 99;
}
public static void main ( String[ ] args ) {
int[ ] myArray = {0, 1, 2, 3, 4} ;
doIt( myArray );
for (int j=0; j<myArray.length; j++ )
System.out.print( myArray[j] + " " ) ;
}
}
Se imprime: 99 2 3 4 5
Pregunta 5 [2 puntos]
Aquí viene un extracto de la API de la clase ArrayList:
boolean add(Object o)
Appends the specified element to the end of this list.
Object get(int index)
Returns the element at the specified position in this list.
int size()
Returns the number of elements in this list.
int indexOf(Object elem)
Searches for the first occurence of the given argument, testing for
equality using the equals (==) method. Returns the index of the first
occurrence of the argument in this list; returns -1 if the object is not found.
5
a) ¿Qué imprime el siguiente programa a la ejecución (líneas numeradas 1
a 4)? [0.5 puntos]
import java.util.*;
class P5a {
int val;
public P5a(int x) {
this.val = x;
}
public static void main(String []args) {
ArrayList list = new ArrayList();
System.out.println(list.size()); // 1
list.add(new P5a(1));
System.out.println(list.size()); // 2
list.add(new P5a(1));
System.out.println(list.size()); // 3
System.out.println(list.get(0) == list.get(1)); // 4
}
}
0
1
2
false
b) Utilizando algunos de los métodos de ArrayList descritos más arriba,
escribir los dos siguientes métodos: [1 punto]
public static boolean isEmpty(ArrayList a): returns true if arraylist a is empty,
false otherwise
public static boolean isEmpty(ArrayList a) {
if (a.size() > 0)
return false;
else
return true;
}
public static boolean containsObject(ArrayList a,Object o): returns true if
arraylist a contains object o, false otherwise
public static boolean containsObject(ArrayList a,Object o) {
if (a.indexOf(o) > 0)
return true;
else
return false;
}
6
c) Tenemos la siguiente clase Alumno:
public class Alumno {
String nif;
String nombre;
String apellido;
}
Si tenemos un ArrayList de Alumno y un HashMap de Alumno, explicar de
manera informal la diferencia entre como buscar un alumno especifico dentro
del ArrayList y como buscarlo dentro del HashMap. ¿Cual es la manera más
sencilla? [0.5 puntos]
Si buscamos un alumno, lo más fácil es buscarlo por su NIF. En el caso del
ArrayList, el algoritmo consiste en hacer una busque lineal por todo el
ArrayList desde el primer índice hasta encontrar el elemento o hasta
llegar al último índice.
En el caso del HashMap, la búsqueda es más sencilla, pues podemos
acceder (o no) directamente al elemento buscado por su clave que sería el
NIF. Evidentemente, si no tenemos el NIF del alumno (la clave) perdemos
este ventaja.
Pregunta 6 [1 punto]
Tenemos el siguiente código:
import java.io.*;
public class P6 {
public static void main(String[ ] args) throws IOException {
FileReader f = new FileReader(args[0]);
BufferedReader b = new BufferedReader(f);
String s1 = b.readLine();
String s2 = b.readLine();
FileWriter w = new FileWriter(args[1]);
while ((s1 != null) && (s2 != null)) {
w.write(s1 + " " + s2 + "\n");
s1 = b.readLine();
s2 = b.readLine();
}
w.close();
b.close();
f.close();
}
}
7
a) Si args[0] corresponde a un fichero que contiene lo siguiente (un carácter por
línea): [0.5 puntos]
a
b
c
d
e
¿Cuál será el contenido del fichero que corresponde a args[1] después de la
ejecución?
ab
cd
b) Explicar qué son f y b, y qué es w, y para qué sirven. [0.25 puntos]
Son flujos. f y b son flujos de entrada que establecen una conexión entre la
fuente datos (el fichero) y el programa. w es un flujo de salida que establece
una conexión entre el programa y el destino de datos (el fichero).
c) ¿Por qué necesitamos b además de f para leer un fichero? [0.25 puntos]
Con un flujo de tipo FileReader, solo podemos leer caracteres ascii con el
método read. Un flujo de tipo BufferedReader actua como tapón entre el flujo
FileReader y el programa, almacenando los caracteres y liberandolos cuando
llegan a formar una línea entera.
Pregunta 7 [1.5 puntos]
a) Tenemos el siguiente código: [0.5 puntos]
public class P7a {
public static void main(String[ ] args) {
int i = 3;
System.out.println(i);
String s = "Hola";
System.out.println(s);
}
}
Partes de este código ilustran el concepto de overloading. Explicar qué es el
overloading y por qué nos resulta útil.
El método println existe bajo diferentes firmas (signatura) dentro de la
misma clase asociada con la variable System.out. Eso se llama method
overloading. En el ejemplo a la ejecución se llama en el primer caso a
void println(int i), siendo el argumento de entrada un int. En el segundo
caso se llama a void println(String s), siendo el argumento de entrada un
String. El overloading es útil porque permite utilizar en apariencia el mismo
método dentro del programa, pero son distintos métodos que se llaman a la
ejecución.
8
b) El método String toString() esta definido dentro de la clase Object y también
dentro de su sub-clase indirecta Integer. Si escribimos: [0.5 puntos]
Object o1 = new Object();
String s1 = o1.toString(); // 1
Object o2 = new Integer(3);
String s2 = o2.toString(); // 2
¿Qué toString() va a ser llamado a la ejecución a cada una de las líneas 1 y 2 y
por qué?
En 1 se llama al toString de Object, pues o1 es una variable de objeto que
refiere a un objeto de tipo Object. En 2 se llama al toString de Integer, pues
o2 es una variable de objeto que refiere a un objeto de tipo Integer. La
clase Integer hereda de Object pero redefine (“overloading”) el método
toString, por lo que se llama a su propio método cuando se trata de un
objeto de tipo Integer.
c) Tenemos al principio de la clase A la siguiente declaración: [0.25 puntos]
public class A extends B { ... }
¿Qué quiere decir la palabra clave extends? Explicar el concepto a que se
refiere.
La palabra extends quiere decir que A hereda directamente de B, es decir que
A hereda todas las variables y todos los métodos de B (si no es que redefine
estos métodos).
d) Tenemos al principio de la clase A la siguiente declaración: [0.25 puntos]
public abstract class A { ... }
¿Qué quiere decir la palabra clave abstract? Explicar el concepto a que se
refiere.
La palabra abstract quiere decir que A no se puede instanciar: no se pueden
crear objetos de tipo A.
9
Descargar