Universidad Politcnica de Madrid - L.P.S.I.

Anuncio
Universidad Politécnica de Madrid
Escuela Universitaria de Informática
Departamento de Lenguajes, Proyectos y Sistemas Informáticos
Asignatura PROGRAMACIÓN II
EXAMEN DE LA CONVOCATORIA DE FEBRERO
Plan: 92 / Curso: 2006-2007
Madrid, a 6 de Febrero de 2007
APELLIDOS: ...................................NOMBRE: ..................................................
Nº DE MATRÍCULA: ....... DNI:.................GRUPO: ..........................................
CALIFICACIONES
TEORÍA
PROB_1
PROB_2
TOTAL
CUESTIONES TEÓRICAS
Valoración: 3 puntos.
Pregunta correcta:....................................0'2 puntos.
Pregunta no contestada o incorrecta: .... -0'15 puntos
UTILICE EL REVÉS DE LAS
HOJAS DE PROBLEMAS COMO
BORRADOR
I. PROGRAMACIÓN CONCURRENTE
1. ¿Qué es un interbloqueo de procesos?
Es un estado de un programa concurrente en el que un conjunto de procesos permanece
esperando un suceso que sólo puede provocar un proceso del propio conjunto, con lo que todos los
procesos esperan indefinidamente. El interbloqueo puede ser pasivo (deadlock) o activo (livelock).
2. Describa la semántica de las instrucciones WAIT y SIGNAL aplicadas sobre semáforos
generales.
WAIT(s) – Si el contador del semáforo s es igual a cero el proceso se bloquea en el semáforo s; si
no, se decrementa en una unidad el contador del semáforo s y el proceso prosigue su ejecución.
SIGNAL(s) – Si hay procesos bloqueados en el semáforo s se despierta a uno de ellos; si no, se
incrementa en una unidad el contador del semáforo s. En ambos casos, el proceso prosigue su
ejecución.
Ambas instrucciones son, por definición, atómicas.
Página 1 de 10
Programación II
Febrero 2007
3. Dado el programa siguiente ¿podría darse el caso de que uno o ninguno de los dos procesos
finalizase? Razone su respuesta.
PROGRAM P;
PROCESS TYPE tProceso (VAR Fin : BOOLEAN);
VAR I : INTEGER;
BEGIN
I:=0;
WHILE NOT Fin DO
BEGIN
I:=I+1;
IF I=3 THEN Fin:=TRUE
ELSE Fin:=FALSE
END
END;
VAR Procesos : ARRAY [1..2] OF tProceso;
Fin : BOOLEAN;
BEGIN
Fin:=FALSE;
COBEGIN
Procesos[1](Fin);
Procesos[2](Fin);
COEND
END.
Si es posible.
Ambos procesos entran en el bucle con la variable global Fin a valor FALSE.
Si el proceso 1 ejecuta su bucle 3 veces, pondrá su variable local i a valor 3 y la variable global Fin
a valor TRUE. En ese momento el proceso 2 pone su variable local i a valor 1 y la variable global
Fin a valor FALSE. Si ahora el proceso 1 consulta la variable Fin permanecerá en el bucle.
Si cuando el proceso 2 ponga su variable local i valor 3 y la variable global Fin a valor TRUE, el
proceso 1 pone su variable local a valor 4 y la variable global Fin a valor FALSE, ambos procesos
permanecerán indefinidamente en el bucle.
4. ¿Puede haber procesos bloqueados en la cola urgente de un monitor de Pascal-FC si dicho
monitor no tiene declarada ninguna variable de tipo condición? Razone su repuesta
No. Los procesos se bloquean en la cola urgente de un monitor al hacer un RESUME sobre una
variable CONDITION y liberar un proceso bloqueado en esa variable CONDITION. Si no hay
ninguna variable CONDITION en el monitor, no es posible realizar ningún RESUME sobre ella.
5. ¿Qué sucede en PASCAL-FC con la exclusión mutua sobre dos monitores A y B cuando un
proceso, desde el monitor A, invoca a un procedimiento del monitor B y ejecuta una operación
DELAY en ese procedimiento?
Que retiene la exclusión mutua sobre el monitor A, y libera la exclusión mutua sobre el monitor B.
Página 2 de 10
Programación II
Febrero 2007
II. PROGRAMACIÓN ORIENTADA A OBJETOS
6. Atendiendo al siguiente diagrama de clases, codifique en PIIPOO los atributos y métodos de las
clases cA y cB necesarios para la implantación de sus relaciones.
cA
Composición
Composición
cB
cC
Asociación
CLASS INTERFACE cA;
PUBLIC METHODS
CONSTRUCTOR cA;
END CLASS INTERFACE cA;
CLASS INTERFACE cB;
PUBLIC METHODS
CONSTRUCTOR cB (pC: ^cC);
END CLASS INTERFACE cB;
CLASS IMPLEMENTATION cA;
ATTRIBUTES
mpC: ^cC;
mpB: ^cB;
CLASS IMPLEMENTATION cB;
ATTRIBUTES
mpC: ^cC;
METHODS DEFINITION
CONSTRUCTOR cA;
BEGIN
NEW (mpC, cC);
NEW (mpB, cB(mpC)
END;
END CLASS IMPLEMENTATION cA;
METHODS DEFINITION
CONSTRUCTOR cB (pC: ^cC);
BEGIN
mpC:=pC;
END;
END CLASS IMPLEMENTATION cB;
7. Dadas las vistas públicas de las siguientes clases en PIIPOO:
CLASS INTERFACE cA;
PUBLIC METHODS
FUNCTION f (A : cA) : cA;
OPERATOR := (A : cA);
END CLASS INTERFACE cA,
CLASS INTERFACE cB
INHERITS FROM cA;
PUBLIC METHODS
FUNCTION f (B : cB) : cB;
OPERATOR := (B : cB);
END CLASS INTERFACE cB,
y las siguientes declaraciones de objetos:
A : cA;
B : cB;
¿Cuáles de las siguientes expresiones son correctas y cuáles no? Razone las respuestas.
a) B:= A . f(A); Correcta. Se ejecuta la función f de la clase cA que recibe un objeto de la clase cA y
devuelve un objeto de la clase cA; y el operador := de la clase cA (heredado por la clase cB) que
recibe un objeto de la clase cA.
b) B:= A . f(B); Incorrecta. La clase cA no tiene definida una función f que reciba como argumento
un objeto de la clase cB.
c) A:= B . f(A); Correcta. Se ejecuta la función f de la clase cA (heredada por la clase cB) que
recibe un objeto de la clase cA y devuelve un objeto de la clase cA; y el operador := de la clase cA
que recibe un objeto de la clase cA.
d) A:= B . f(B); Incorrecta. La clase cA no tiene definido un operador := que reciba como argumento
un objeto de la clase cB, que es lo que devuelve la función f de la clase cB que recibe un objeto de
la clase cB.
Página 3 de 10
Programación II
Febrero 2007
8. ¿Qué es necesario para la implantación del polimorfismo en PIIPOO?
Herencia e instanciación dinámica
9. ¿Qué cinco tipos de métodos se pueden definir en una clase en PIIPOO? Describa brevemente
el cometido de cada tipo.
PROCEDIMIENTOS. Pueden alterar el estado del objeto que recibe el mensaje, o el estado de los
objetos que reciben como argumento. No devuelven nada.
FUNCIONES. No alteran el estado del objeto que recibe el mensaje, ni el estado de los objetos que
reciben como argumento. Devuelven objetos o punteros a objetos.
OPERADORES. Proporcionan una notación más conveniente para expresar operaciones
aritméticas o lógicas. Pueden ser procedimentales o funcionales.
CONSTRUCTORES. Se invocan automáticamente cada vez que se instancia un objeto de una
clase y sirven para dar valores iniciales a los atributos del objeto creado.
DESTRUCTORES. Se invocan automáticamente cada vez que se destruye un objeto de una clase
y sirven para realizar cualquier tarea de limpieza que deba hacerse en ese momento, como por
ejemplo liberar la memoria dinámica creada por el objeto que se destruye.
10. Dada las siguientes declaraciones:
CLASS INTERFACE cA;
PUBLIC METHODS
PROCEDURE m1;
DEFERRED PROCEDURE m2;
END CLASS INTERFACE cA;
CLASS IMPLEMENTATION cA;
METHODS DEFINITION
PROCEDURE m1;
BEGIN
SELF.m2
END;
END CLASS INTERFACE cA;
CLASS INTERFACE cB;
INHERITS FROM cA;
PUBLIC METHODS
REDEFINED PROCEDURE m2;
END CLASS INTERFACE cB;
CLASS INTERFACE cC;
INHERITS FROM cA;
PUBLIC METHODS
REDEFINED PROCEDURE m2;
END CLASS INTERFACE cC;
¿Son correctos los siguientes grupos de sentencias? En caso afirmativo, ¿qué métodos se
ejecutarían? En caso negativo, justifique su respuesta
a) p : ^cA;
NEW (p, cC);
p^.m1;
Incorrecta. El puntero no es polimórfico y no admite direcciones de objetos de
la clase cC.
b) p : ^cA;
NEW (p, cA);
p^.m1;
Incorrecta. No se puede crear un objeto de la clase cA por ser una clase
abstracta.
c) p : ^cB;
NEW (p, cB);
p^.m1;
Correcta, Se ejecutan el metodo m1 definido en la clase cA y heredado por cB
y el método m2 definido en la clase cB.
d) p : POLYMORPHIC ^cA;
NEW (p, cB);
p^.m1;
Correcta, Se ejecutan el metodo m1 definido en la clase cA y
heredado por cB y el método m2 definido en la clase cB.
Página 4 de 10
Programación II
Febrero 2007
III. PROGRAMACIÓN FUNCIONAL
11. Enumere las desventajas de la programación funcional.
Dificultad de escribir código e ineficiencia en su ejecución.
12. ¿Cuáles de las siguientes líneas responden a posibles tipos de una función CAML?. Razone las
respuestas.
a) [char]
-> [char]
b) (int , int) -> int
c) _ * _
-> bool
-> true
d) int
a) Incorrecto. [char] no es un tipo. Debería ser char list -> char list
b) Incorrecto. (int, int) no es un tipo. Debería ser int * int -> int
c) Incorrecto. _ * _ no es un tipo. Debería ser ‘a * ‘b -> bool
d) Incorrecto. true no es un tipo. Debería ser int -> bool
13. ¿Es correcta la siguiente función? En caso afirmativo, infiera su tipo y escríbalo en la notación
CAML. En caso contrario, justifique la respuesta.
let rec f = function
1 -> (1,0)
| n -> (n, f(n-1));;
No es correcta. En el caso base la función devuelve una tupla de dos enteros, y en el caso general
devuelve una tupla formada por un entero y una tupla.
14. ¿Son correctos los siguientes patrones en el lenguaje CAML? En caso afirmativo, indique qué
valores satisfacen el patrón. En caso negativo, razone la respuesta.
a) (_,_)::_::_
b) _::(_,_)::_
c) _::_::(_,_)
Correcto. Se satisface con cualquier lista con al menos dos tuplas de dos
elementos de cualquier tipo.
Correcto. Se satisface con cualquier lista con al menos dos tuplas de dos
elementos de cualquier tipo.
Incorrecto. A la derecha del operador :: debe aparecer una lista, no una tupla.
15. ¿Qué tipo de recursividad posee la siguiente función? Razone su respuesta.
let rec f = function
0 -> 1
| x -> if x > 0 then x*f(x-1) else x*f(x+1);;
Recursividad lineal, porque en cada aplicación de la función se realiza como máximo una llamada
recursiva a la propia función.
Página 5 de 10
Programación II
Febrero 2007
Universidad Politécnica de Madrid
Escuela Universitaria de Informática
Departamento de Lenguajes, Proyectos y Sistemas Informáticos
Asignatura PROGRAMACIÓN II
ENUNCIADOS DE LOS PROBLEMAS DEL
EXAMEN DE LA CONVOCATORIA DE FEBRERO
Plan: 92 / Curso: 2006-2007
Madrid, a 6 de Febrero de 2007
Fechas de Publicación de Notas y de Revisión de Exámenes
Publicación de Notas Miércoles 21 de Febrero de 2007
Revisión de Examen y Prácticas: Viernes 23 de Febrero de 2007 en horario que
será publicado en el tablón de la Asignatura a la publicación de las notas
Puede consultar sus notas en: www.lpsi.eui.upm.es/ProgramacionII/Notas.htm
PROBLEMA 1: PROGRAMACIÓN CONCURRENTE
Puntuación: 2'5 puntos
En un cierto programa concurrente hay NumProcesos procesos del siguiente tipo:
PROCESS TYPE TProceso (prioridad : INTEGER);
BEGIN
A
END;
donde el parámetro prioridad indica la prioridad de cada proceso para ejecutar el bloque de
instrucciones A, y está comprendido entre los valores 1 y MaxPrioridad. Además se sabe que
hay al menos un proceso de cada prioridad.
SE PIDE:
Añadir todo el código de sincronización necesario en los procesos para que se cumplan los
siguientes requisitos:
- Todo proceso con una cierta prioridad debe ejecutar A antes de cualquier otro proceso de
prioridad inferior a la suya.
- Todos los procesos con la misma prioridad deben poder ejecutar A concurrentemente.
Para cumplir estos requisitos, puesto que inicialmente se desconoce el número de procesos que
hay de cada prioridad, deben ser los propios procesos los que cooperen durante su ejecución para
calcular cuántos procesos existen de cada prioridad mediante un array compartido del siguiente
tipo:
TYPE tCuantos = ARRAY [1..MaxPrioridad] OF INTEGER;
y ningún proceso debe ejecutar A hasta que se haya terminado de calcular cuántos procesos
existen de cada prioridad.
Página 6 de 10
Programación II
Febrero 2007
SOLUCION CON MONITORES:
MONITOR Sincro;
EXPORT PreA, PostA;
TYPE tCuantos = ARRAY [1..MaxPrioridad] OF INTEGER;
VAR
cuantosPrioridad : tCuantos;
cuantosTotal : INTEGER;
esperaPrioridad : ARRAY [1..MaxPrioridad] OF CONDITION;
(*--------------------------------------------------------------------------*)
PROCEDURE PreA (prioridad : INTEGER);
BEGIN
cuantosPrioridad[prioridad] := cuantosPrioridad[prioridad] + 1;
cuantosTotal := cuantosTotal + 1;
(* Comprobar si es el ultimo proceso de todos *)
IF cuantosTotal < NumProcesos THEN
DELAY(esperaPrioridad[prioridad])
ELSE
BEGIN
(* Despertar a todos los procesos de la maxima prioridad *)
WHILE NOT EMPTY(esperaPrioridad[MaxPrioridad]) DO
RESUME(esperaPrioridad[MaxPrioridad]);
(* Comprobar si este proceso debe bloquearse *)
IF prioridad < MaxPrioridad THEN
DELAY(esperaPrioridad[prioridad])
END
END;
(*--------------------------------------------------------------------------*)
PROCEDURE PostA (prioridad : INTEGER);
BEGIN
cuantosPrioridad[prioridad] := cuantosPrioridad[prioridad] - 1;
(* Comprobar si es el ultimo proceso con esta prioridad y
no es de la minima prioridad *)
IF (cuantosPrioridad[prioridad] = 0) AND (prioridad > 1) THEN
(* Despertar a todos los procesos de la siguiente prioridad *)
WHILE NOT EMPTY(esperaPrioridad[prioridad - 1]) DO
RESUME(esperaPrioridad[prioridad - 1])
END;
(*--------------------------------------------------------------------------*)
VAR i : INTEGER;
BEGIN
FOR i := 1 TO MaxPrioridad DO
cuantosPrioridad[i] := 0;
cuantosTotal := 0
END;
(****************************************************************************)
Página 7 de 10
Programación II
Febrero 2007
PROCESS TYPE TProceso (prioridad : INTEGER);
BEGIN
Sincro.PreA(prioridad);
A;
Sincro.PostA(prioridad)
END;
SOLUCION CON SEMAFOROS:
TYPE tCuantos = ARRAY [1..MaxPrioridad] OF INTEGER;
TYPE tSincro = RECORD
cuantosPrioridad : tCuantos;
cuantosTotal : INTEGER;
exclusion : SEMAPHORE;
esperaPrioridad : ARRAY [1..MaxPrioridad] OF SEMAPHORE
END;
(*--------------------------------------------------------------------------*)
PROCEDURE PreA (prioridad : INTEGER; VAR sincro : tSincro);
VAR i : INTEGER;
BEGIN
WAIT(sincro.exclusion);
sincro.cuantosPrioridad[prioridad] := sincro.cuantosPrioridad[prioridad] + 1;
sincro.cuantosTotal := sincro.cuantosTotal + 1;
(* Comprobar si es el ultimo proceso de todos *)
IF sincro.cuantosTotal = NumProcesos THEN
(* Despertar a todos los procesos de la maxima prioridad *)
FOR i:=1 TO sincro.cuantosPrioridad[MaxPrioridad] DO
SIGNAL(sincro.esperaPrioridad[MaxPrioridad])
SIGNAL(sincro.exclusion);
WAIT(sincro.esperaPrioridad[prioridad])
END;
(*--------------------------------------------------------------------------*)
PROCEDURE PostA (prioridad : INTEGER; VAR sincro : tSincro);
VAR i : INTEGER;
BEGIN
WAIT(sincro.exclusion);
sincro.cuantosPrioridad[prioridad] := sincro.cuantosPrioridad[prioridad] - 1;
(* Comprobar si es el ultimo proceso con esta prioridad y
no es de la minima prioridad *)
IF (sincro.cuantosPrioridad[prioridad] = 0) AND (prioridad > 1) THEN
(* Despertar a todos los procesos de la siguiente prioridad *)
FOR i:=1 TO sincro.cuantosPrioridad[prioridad - 1] DO
SIGNAL(sincro.esperaPrioridad[prioridad - 1])
SIGNAL(sincro.exclusion)
END;
(****************************************************************************)
Página 8 de 10
Programación II
Febrero 2007
PROCESS TYPE TProceso (prioridad : INTEGER; VAR sincro : tSincro);
BEGIN
PreA(prioridad, sincro);
A;
PostA(prioridad, sincro)
END;
(****************************************************************************)
VAR sincro : tSincro;
i : INTEGER;
BEGIN
FOR i := 1 TO MaxPrioridad DO
BEGIN
sincro.cuantosPrioridad[i] := 0;
INITIAL(sincro.esperaPrioridad[i], 0)
END;
sincro.cuantosTotal := 0;
INITIAL(sincro.exclusion, 1);
...............
END.
PROBLEMA 2: PROGRAMACIÓN FUNCIONAL
Puntuación: 2'5 puntos
Defina la función MayorMenores que recibiendo como entrada una lista no vacía de listas de
enteros no vacías, devuelva el mayor elemento de los menores elementos de cada una de las
sublistas que componen la lista de entrada.
Ejemplos:
#
#
#
#
-
MayorMenores
: int = 1
MayorMenores
: int = 5
MayorMenores
: int = 3
MayorMenores
: int = 5
[[2;1;3]];;
[[2;1;3];[1];[3;4;2];[3;4;5];[5;5;5]];;
[[2;1;3];[1];[3;4;2];[3;4;5];[-5;5;5]];;
[[-2;-1;-3];[1];[3;-2;4];[3;-4;5];[5;5;5]];;
SOLUCION:
(* Solucion 1 **************************************************************)
let rec Menor = function
[ele] -> ele
| ele::cola -> if ele <= Menor(cola) then ele else Menor(cola);;
let rec Mayor = function
[ele] -> ele
| ele::cola -> if ele >= Mayor(cola) then ele else Mayor(cola);;
let rec Menores = function
[] -> []
| lista::resto -> Menor(lista)::Menores(resto);;
let MayorMenores = function
lista -> Mayor(Menores(lista));;
Página 9 de 10
Programación II
Febrero 2007
(* Solucion 2 **************************************************************)
let rec Menor = function
[ele] -> ele
| ele::cola -> if ele <= Menor(cola) then ele else Menor(cola);;
let rec MayorMenores = function
[lista] -> Menor(lista)
| lista::cola -> if Menor(lista) >= MayorMenores(cola)
then Menor(lista)
else MayorMenores(cola);;
Página 10 de 10
Descargar