Imagina esta escena: dos personas rinden el examen de Programación Avanzada. Una recuerda de memoria cada método de las librerías y escribe código a toda velocidad. La otra se demora los primeros diez minutos dibujando cajas y flechas en el borde de la hoja. Al corregir, la segunda suele sacar mejor nota. La tesis de esta guía es esa: el examen de IIC2233 mide si diseñas bien, no si recuerdas APIs, y el repaso debería organizarse en torno a eso.
Le sirve a quien ya aprobó las interrogaciones y quiere ordenar la última semana. No le sirve a quien aún no logra hacer andar un programa con clases; en ese caso conviene volver a la guía de la I1 y a la de la I2, porque el examen las da por sabidas.
Qué dice el catálogo y qué no dice
El programa de IIC2233 en el Catálogo UC (consultado el 16 de octubre de 2026) indica 10 créditos y siete unidades: introducción a C# y .NET, elementos avanzados de programación orientada a objetos (herencia y polimorfismo), el framework .NET, programación multithread, programación dirigida por eventos, patrones de diseño y una vuelta final a Java. La evaluación se describe de forma genérica, como pruebas, proyectos y tareas.
Ojo con un detalle: ese documento está fechado en mayo de 2009. Sirve para ver la columna vertebral del ramo (objetos, hilos, eventos, patrones), pero no para saber qué lenguaje, qué temas ni qué formato tendrá tu examen este semestre. Eso lo define el syllabus de tu sección, y es lo primero que deberías leer.
Lo que de verdad evalúa el examen
Un examen acumulativo de un ramo de programación suele preguntar tres cosas distintas, aunque vengan mezcladas en el mismo problema: si entiendes cómo se relacionan las clases, si sabes qué puede fallar y quién debe manejarlo, y si reconoces cuándo dos cosas que corren a la vez se pisan. Nada de eso se resuelve recordando el nombre exacto de un método; se resuelve con un modelo mental ordenado. Lo anterior es una inferencia a partir de cómo se estructura el ramo, no un dato oficial del examen.
Por eso el hábito más rentable es uno solo: antes de escribir una línea, anota qué clases hay, qué responsabilidad tiene cada una y qué hilos o eventos participan. Son tres minutos que evitan reescribir media solución.
Herencia y polimorfismo: la pregunta de «dónde va esto»
La mayoría de los problemas de herencia se reduce a decidir dónde vive cada método. Si un comportamiento es común a todas las subclases, va en la clase base. Si cambia según el tipo, se declara en la base y se sobrescribe en cada subclase. Si solo lo usa una subclase, no lo subas a la base «por si acaso», porque ahí te cobran puntos por diseño.
Una prueba rápida antes de heredar: ¿puedes decir «un X es un Y» sin que suene raro? Un Auto es un Vehículo; una Biblioteca no es una Lista de libros, la contiene. Cuando dudes entre herencia y composición, la composición suele ser la respuesta más segura y más fácil de justificar por escrito.
En preguntas de polimorfismo, el error típico es llamar a un método que solo existe en una subclase sobre una variable declarada con el tipo de la base. Dibuja el tipo de la variable y el tipo real del objeto como dos cosas separadas.
Excepciones: qué se captura y en qué nivel
Capturar una excepción no es lo mismo que resolverla. La pregunta de examen casi nunca es «¿qué sintaxis uso?», sino «¿quién tiene información suficiente para recuperarse?». Si la función que falla no puede arreglar nada, lo correcto es dejarla subir hasta quien sí puede reintentar, pedir otro dato o cerrar el recurso.
Tres reglas que ahorran puntos: captura la excepción más específica posible y no un genérico que esconda errores; libera siempre los recursos abiertos (archivos, conexiones) con la estructura que ofrezca el lenguaje para eso; y no uses excepciones como reemplazo de un simple if cuando la situación es esperable. Si defines tus propias excepciones, que sean subclases con un nombre que diga qué pasó.
Hilos: un ejemplo mínimo de carrera
El artículo de Wikipedia sobre hilos (consultado el 16 de octubre de 2026) describe la condición de carrera como el problema que ocurre cuando varios hilos o procesos alteran datos que otros también están usando. Esto es lo que se ve en código (ejemplo en Python; si tu sección usa otro lenguaje, la idea es idéntica):
import threading
saldo = 0
candado = threading.Lock()
def depositar():
global saldo
for _ in range(100_000):
with candado: # sin esta línea, dos hilos pueden pisarse
saldo += 1
hilos = [threading.Thread(target=depositar) for _ in range(2)]
for h in hilos: h.start()
for h in hilos: h.join()
print(saldo) # con candado: 200000
La operación saldo += 1 parece una sola, pero en realidad lee, suma y escribe. Si dos hilos leen el mismo valor a la vez, uno de los incrementos se pierde, y sin el candado el resultado final puede ser menor que 200.000. En el examen te pueden pedir justo eso: explicar por qué el resultado cambia entre ejecuciones y dónde pondrías la sección crítica. Respuesta corta y completa: la sección crítica es la modificación del dato compartido, y se protege lo mínimo necesario, no la función entera.
Errores de concurrencia y de diseño: cuánto cuestan
Esta tabla resume los errores que más seguido se ven en este tipo de pruebas y cómo evitarlos. Los «costos» son estimaciones mías como criterio de repaso, no una pauta oficial de corrección.
| Error | Cómo se ve en la hoja | Cómo evitarlo | Costo estimado |
|---|---|---|---|
| Proteger de más | Un candado alrededor de toda la función | Bloquear solo la modificación del dato compartido | Medio: funciona, pero pierde el paralelismo |
| Olvidar esperar a los hilos | Se imprime el resultado antes de que terminen | Unir los hilos antes de leer el dato | Alto: la respuesta sale incorrecta |
| Subir métodos a la clase base sin necesidad | Subclases con métodos que no usan | Preguntar «¿todas lo necesitan?» antes de subirlo | Medio: descuento por diseño |
| Capturar todo con un genérico | Un solo bloque de captura sin tipo específico | Capturar el tipo concreto y propagar el resto | Medio a alto: oculta errores reales |
| Bloqueos mutuos | Dos hilos esperando los candados del otro | Adquirir los candados siempre en el mismo orden | Alto: el programa queda detenido |
De toda la tabla, el último punto es el que más sorprende: los bloqueos mutuos casi nunca aparecen en un programa de diez líneas, pero sí en un enunciado que te pide revisar uno ajeno. Léelo buscando dos recursos y dos hilos que los toman en orden distinto.
Últimos días: cómo repasar y para quién sirve esto
Mi propuesta para la semana previa es corta. Un día para rehacer, sin mirar apuntes, el diagrama de clases de la última tarea. Un día para tres problemas de herencia y polimorfismo, explicando en voz alta cada decisión. Un día para excepciones: toma código tuyo y marca quién captura qué. Dos días para hilos, con el ejemplo de arriba y variaciones (más hilos, otro dato compartido, otro orden de candados). Y un último día para un examen anterior cronometrado, con los primeros diez minutos reservados para dibujar.
Esta estrategia funciona para quien ya programa con soltura y pierde puntos por orden. No reemplaza el trabajo práctico: si nunca escribiste código con hilos, correr el ejemplo y romperlo a propósito te enseña más que leer tres resúmenes. Si quieres práctica guiada, está el curso de Programación Avanzada (IIC2233) UC en ARomperla, y el resto de las guías de tu universidad están en el hub de la UC.
¿Quieres romperla en la UC?
Mira todos los cursos de preparación para tu universidad.
Ver cursos de la UC →