T.A.P.
Técnicas Actuales de Programación
Curso: 2025/26
|
|
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Clases: {aula: 1.4} {horario: lunes 12:00-12:50, jueves 10:40-11:30, viernes 9:40-10:30}
Laboratorios: {Laboratorio: aula 0.23} {horario: 15:00-17:30}
Tutorias {con las excepciones que puedan indicarse en GAUR}: Miércoles de 9h a 13h y Jueves de 8h a 10h
* La sesión de laboratorio del 11/11 se sustituye por una el día 26/11, se hará en el aula 0.22
** Las clases anuladas los días 6/11 y 4/12 se recuperarán en la sesión de laboratorio del 15/12 como se indica en la sección de desarrollo.
Para cualquier consulta podéis escribir a german.bordel@ehu.es
SEPTIEMBRE
TEMA 1 - INTRODUCCIÓN
1.1.- ["Algorithms + Data Structures = Programs"
Niklaus Wirth]
→ ¿Sólo necesitamos programas (lenguajes)? no, Programas + Ingeniería del software = Soluciones.
1.2- Lenguajes de programación: Origen, situación actual y características deseables (el caso de Java) [pdf]
1.2- 👇 Falta comentar la página 19 y las addenda
Lenguajes de programación: Origen, situación actual y características deseables (el caso de Java) [pdf]
TEMA 2 - USO DEL ENTORNO DE DESARROLLO
2.1.- Ejemplo inicial: el programa "Hola Mundo" (adelantamos conceptos que se afianzan más abajo)
2.1.- Ejemplo inicial: el programa "Hola Mundo" (adelantamos conceptos que se afianzan más abajo)
2.1.- Ejemplo inicial: el programa "Hola Mundo" (adelantamos conceptos que se afianzan más abajo)
2.2.- Bibliotecas de clases: su estructura
Bibliotecas de clases [pdf]
Biblioteca de clases [10 min.]
Biblioteca de clases desde la versión 9 -módulos- [5 min.]
2.3.- Compilación y ejecución (... y desensamblado, decompilación y ofuscación)
Ejecutables para compilación, etc. [pdf]
2.4.- Generación de documentación
Adelanto de los puntos 1 y 2 del
TEMA 6 - INTERFACES GRÁFICOS
OCTUBRE
Recibidos en cursos anteriores
Si no le decís a la IA que sólo queréis el interfaz gráfico, os dará código para que la calculadora funcione, y ese código requiere una explicación que veremos un poco más adelante.
Dedicaremos la clase del jueves 9 a compartir las experiencias con este ejercicio
TEMA 4 - ELEMENTOS RELACIONADOS CON LA ORIENTACIÓN A OBJETOS
Hacemos un inciso para ver el punto 3 del
TEMA 6 - INTERFACES GRÁFICOS
Sesión para compartir experiencias con el uso de la IA para generar la calculadora planteada como ejercicio.
Hemos pedido a M365 Copilot que haga el interface de la calculadora mostrada en esta página y hemos entendido y retocado el código.
Volvemos al
TEMA 4 - ELEMENTOS RELACIONADOS CON LA ORIENTACIÓN A OBJETOS
Os dejo aquí un
tutor de POO con IA y Java (asistente de M365 Copilot).
TEMA 5 - MECANISMO DE TRATAMIENTO DE EXCEPCIONES Y ERRORES
Clase anulada para poder asistir a 👇
Conferencia: Jueves 23 de Octubre 10:30h - Sala Adela Moyua. Fac. Ciencia y Tecnología
Título: "Aplicaciones de modelos de IA para aprendizaje por refuerzo con NVIDIA".
Conferenciante: Asier Arranz, Senior Staff Developer de NVIDIA, que es la mayor productora de tarjetas gráficas (GPUs) imprescindibles para el desarrollo de las tecnologías actuales basadas en redes neuronales, incluidos los famosos LLMs, que necesitan muchos recursos computacionales.
Resumen: El aprendizaje por refuerzo es una técnica de Machine Learning por medio la cual un sistema que interactúa con su entorno aprende de éste mediante realimentaciones premiadas (refuerzos), o castigadas, para mejorar sus decisiones. En algunos escenarios esta realimentación la proporciona una persona. Se utiliza en Teoría de Control, Robótica e Interacción persona-máquina, entre otros muchos campos de aplicación.
En la charla se explicará esta técnica, así como la forma de implementarla y aplicarla. Parece que el ponente va a presentar también el último modelo de GPU de NVIDIA aún fuera del mercado. La charla es una de las actividades de la Semana Europea de la Robótica. En ella se propone también la participación en el Hackaton LeRobot (conjunto de datos, herramientas y modelos en abierto que Hugging Face proporciona). Para los posibles interesados se proporciona el enlace para inscribirse (gratis).
TEMA 7 - EL CONTENIDO DE LA BIBLIOTECA DE CLASES
Pasaremos muy rápido por todo esto deteniendonos sólo un poco en genericos y colecciones
Veamos lo que nos falta con estos ejemplos reales de métodos de la biblioteca
prompt: Busca en la documentación de la biblioteca de Java, 4 funciones que tengan parámetros de los 4 tipos genéricos. A ser posible que sean clases de uso común.
Núcleo de la respuesta 👇
<?> — Tipo desconocidoMétodo: Collections.reverse(List<?>)
Clase: java.util.Collections
Uso: Invierte el orden de los elementos en una lista de cualquier tipo.
Restricción: No puedes añadir elementos a la lista dentro del método porque el tipo es desconocido.
<T> — Tipo genérico declaradoMétodo: <T> void sort(List<T> list, Comparator<? super T> c)
Clase: java.util.Collections
Uso: Ordena una lista de elementos de tipo T usando un comparador que puede comparar T o sus supertipos.
<? extends T> — Subtipo de TMétodo: Collections.copy(List<? super T> dest, List<? extends T> src)
Clase: java.util.Collections
Uso: Copia elementos de una lista fuente (subtipo de T) a una lista destino (supertipo de T).
<? super T> — Supertipo de TMétodo: Collections.max(Collection<? extends T>, Comparator<? super T>)
Clase: java.util.Collections
Uso: Encuentra el máximo elemento en una colección de subtipos de T, usando un comparador que puede comparar T o sus supertipos.
TEMA 8 - Entrada y salida de datos
A partir de este tema comenzaremos a usar algun GPT tipo chat para que nos dé código a analizar.
NOVIEMBRE
Sesión de laboratorio ❶ (3:00 p.m. laboratorio 0.23).
Guión: En este curso no seguiremos un guión. Vamos a por la calculadora totalmente funcional pidiendosela a una IA.
En grupos de 2 o tres alumnos hay que conseguir la calculadora. Se comentará para toda la clase todo aquello que se vaya descubriendo como interesante, y se explicarán las dudas que surgan.
AVISO:
a peticion de los alumnos, se ha cambiado la sesión de laboratorio del 11/11 a las 15:00 en 0.23 por 26/11 a las 15:00 en 0.22
TEMA 9 - Hilos
TEMA 10 - Programación en red
Veremos un ejemplo simple de aplicación cliente-servidor. Se tratará simplemente, en primer lugar, de establecer la conexión y enviar Strings desde el cliente al servidor, para, más adelante, completar este ejemplo con la posibilidad de atender a multiples clientes y establecer el la comunicación de Strings en ambos sentidos.
En el siguiente recuadro tenemos el código de un servidor mínimo. En la línea 6 se instancia un objeto ServerSocket "escuchando" al puerto 6000(puertos), y posteriormente se entra en un ciclo infinito. La primera acción de este ciclo es esperar a un cliente (línea 8). Cuando surje, el método accept nos devuelve una conexión ("s") con él (un socket). Al objeto "s" le pedimos los streams de entrada y de salida en las líneas 11 y 12, que después recubrimos convenientemente a nuestras necesidades actuales como un BufferedReader y un PrintStream en 13 y 14 (podríamos haber prescindido de todo lo referente a salida puesto que este ejemplo no hara uso de ella, pero lo ponemos para mostrar el procedimiento habitual).
Una vez que disponemos de los streams podemos "leer" lo que nos envie el cliente e igualmente "escribirle". En este ejemplo nos limitamos a un bucle de lectura (líneas 17-19) del Reader sin que exista ninguna particularidad por el hecho de que el origen de los datos sea una máquina diferente. En el ejemplo se consulta si el contenido de la String recibida es "exit" para terminar el ciclo de lectura. En tal caso se cierra el Socket (línea 21) terminando el código del ciclo general y volviendo por tanto al punto de espera a un nuevo cliente (línea 8).
Observesé que en este ejemplo la conexión termina por cierre del Socket por parte del servidor. Lo mismo podría haberse hecho desde el cliente, lo que resultaría en una excepción en la lectura del Reader. Podía haberse establecido éste como mecanismo de terminación. En todo caso en una aplicación correcta habría de tenerse en cuenta esta posibilidad de cierre de la conexión or parte del cliente, de modo que habrá de atenderse a la excepción que aquí se arroja.
1 import java.io.*; 2 import java.net.*; 3 4 public class Server { 5 public static void main(String[] args)throws IOException{ 6 ServerSocket ss=new ServerSocket(6000); 7 do { 8 Socket s=ss.accept(); 9 System.out.println("\n\n***Conexion establecida con: "+s); 10 11 InputStream is=s.getInputStream(); 12 OutputStream os=s.getOutputStream(); 13 14 BufferedReader br=new BufferedReader(new InputStreamReader(is)); 15 PrintStream ps=new PrintStream(os); 16 String query; 17 while (!(query=br.readLine()).equals("exit")) { 18 System.out.println("He recibido: "+query); 19 } 20 System.out.println("***Cerrando conexion con: "+s+"\n\n"); 21 s.close(); 22 } while (true); 23 } 24 }
El cliente, para establecer una conexión con el servidor conocido, instancia directamente un Socket indicando la dirección de la máquina del servidor (como texto) y el número de puerto (línea 7). Del mismo modo que en el caso del servidor, el Socket permite acceder a los streams de entrada y salida que, a continuación, son recubiertos adecuadamente (9-10, 12-13).
Este cliente se limita a leer el teclado línea a línea y enviar la String al servidor, para lo cual recubre el System.in con un BufferedReader y en un ciclo infinito lee de teclado, escribe en el PrintStream que recubre al stream de salida del Socket y controla si el texto es "exit" para terminar en tal caso.
1 import java.io.*; 2 import java.net.*; 3 4 public class Client { 5 6 public static void main(String[] args) throws UnknownHostException, IOException { 7 Socket s=new Socket("127.0.0.1",6000); 8 9 InputStream is=s.getInputStream(); 10 OutputStream os=s.getOutputStream(); 11 12 BufferedReader br=new BufferedReader(new InputStreamReader(is)); 13 PrintStream ps=new PrintStream(os); 14 15 BufferedReader teclado=new BufferedReader(new InputStreamReader(System.in)); 16 String q; 17 do { q=teclado.readLine(); 18 ps.println(q); 19 if (q.equals("exit")) System.exit(0); 20 } while (true); 21 } 22 }
Una vez vistos el servidor y el cliente anteriores, vamos a añadir un par de características necesarias para que sean mínimamente de utilidad.
En primer lugar, el servidor sólo es capaz de servir a un cliente, de modo que si un segundo cliente pretende conectar, como el servidor no se encuentra en el accept, no obtiene respuesta. Para ello es necesario que el servidor tenga capacidad para llevar a cabo un hilo de ejecución asociado a cada cliente, de modo que lo que hacemos es instanciar un nuevo objeto cada vez que se retorna del accept, dándole el Socket y delegando en él toda la relación con el cliente.
La clase ThreadedSocket extiende Thread y en su método run se encarga de obtener los streams, recubrirlos adecuadamente y mantener el ciclo de comunicación con el cliente.
1 import java.io.*; 2 import java.net.*; 3 4 public class ThreadedServer { 5 public static void main(String[] args)throws IOException{ 6 ServerSocket ss=new ServerSocket(6000); 7 do { 8 Socket s=ss.accept(); 9 new ThreadedSocket(s); 10 } while (true); 11 } 12 } 13 14 class ThreadedSocket extends Thread { 15 Socket s; 16 ThreadedSocket(Socket s){super(); this.s=s; start();} 17 18 public void run() { 19 System.out.println("\n\n***Conexion establecida con: "+s); 20 21 try{ 22 InputStream is=s.getInputStream(); 23 OutputStream os=s.getOutputStream(); 24 25 BufferedReader br=new BufferedReader(new InputStreamReader(is)); 26 PrintStream ps=new PrintStream(os); 27 ps.println("OK"); 28 String query; 29 while (!(query=br.readLine()).equals("exit")) { 30 System.out.println("He recibido: "+query); 31 ps.println("OK"); 32 } 33 System.out.println("***Cerrando conexion con: "+s+"\n\n"); 34 s.close(); 35 } catch (Exception e) { 36 } 37 } 38 }
En nuestro ejemplo inicial, el cliente sólo era capaz de enviar lineas de texto al servidor, pero normalmente un cliente también tendrá que recibir información, de modo que en este caso también hay tareas a llevar a cabo en paralelo: la que ya llevabamos a cabo -copiar del teclado al servidor- y la nueva -copiar del servidor a la salida estándar-.
Para llevar a cabo la nueva tarea definimos una clase (lo hacemos de modo local a la rutina main) que se encargará automáticamente de realizar el "eco" de lo recibido del servidor en la salida estándar. De este modo la simple instanciación de un objeto de esta clase nos basta para completar la funcionalidad buscada.
1 import java.io.*; 2 import java.net.*; 3 4 public class ThreadedClient { 5 6 public static void main(String[] args) throws UnknownHostException, IOException { 7 Socket s=new Socket("127.0.0.1",6000); 8 9 InputStream is=s.getInputStream(); 10 final BufferedReader br=new BufferedReader(new InputStreamReader(is)); 11 class Echo extends Thread{ 12 Echo(){setDaemon(true);start();} 13 public void run(){ 14 try {while (true)System.out.println(br.readLine());}catch (IOException e){}} 15 } 16 Echo e=new Echo(); 17 18 PrintStream ps=new PrintStream(s.getOutputStream()); 19 BufferedReader teclado=new BufferedReader(new InputStreamReader(System.in)); 20 String q; 21 do {q=teclado.readLine(); 22 ps.println(q); 23 if (q.equals("exit")) System.exit(0); 24 } while (true); 25 } 26 }
Se ha visto un ejemplo mínimo y se han añadido las dos funcionalidades necesarias para que tengamos la posibilidad de mantener un intercambio de frases entre un conjunto indeterminado de clientes y el servidor. Esto ha sido muy sencillo entre otras cosas porque no ha sido necesario establecer sincronismos entre hilos (no hay cooperación) ni un protocolo de comunicación (sólo se han cruzado cadenas de texto, no mensajes con diferentes contenidos).
Un modo muy sencillo de establecer comunicaciones cliente-servidor mediante un protocolo consiste en intercambiar objetos (en lugar de textos) recubriendo los streams con ObjectInputStream y ObjectOutputStream, de modo que la complejidad del protocolo queda embebida en la estructura de los objetos.
---> Servidor y cliente para pruebas (ligeramente retocados frente a lo visto más arriba).
[descomprimir y ejecutar desde la carpeta "classes" como "java edu.upvehu.gbg.clientserver.ThreadedServer" y "java edu.upvehu.gbg.clientserver.ThreadedClient"]
---> Aquí los fuentes de un servidor que responde con los campos GET y Host de la petición del cliente,
y un cliente que hace un GET al servidor local y otro a un recurso de gtts.we.lc:8080
Con esto podemos hacer lo siguiente:
---> Aquí un Servidor y cliente con intercambio de objetos
Hace algunos años, los alumnos desarrollaron un cliente de "chat". Aquí hay algo de información al respecto.
Le_Robot Hackathon Bilbao.2025
Próximamente la noticia en CAMPUSA
Dedicaremos la clase a plantear el desarrollo del proyecto que servirá de evaluación, y las dos sesiones de laboratorio de martes y miercoles para comenzarlo o avanzar en él. ANULADA OFICIALMENTE LA ACTIVIDAD EN LA UNIVERSIDAD POR AVERIA EN EL SUMINISTRO DE AGUA
Sesión de laboratorio ❷ (3:00 p.m. laboratorio 0.23).
Comenzamos con el desarrollo de la aplicación que servirá de evaluación de la asignatura.
![]() proceso scrum |
![]() backlogs |
![]() sugerencia de equipo por m635 |
|
Sesión de laboratorio ❸ (3:00 p.m. laboratorio 0.22).
Hablamos un poquito de Buenas Prácticas en Programación Orientada a Objetos y de tests unitarios, y seguimos con el trabajo de desarrollo de la aplicación.
Incidencias:
Ideas a discutir:
Dedicaremos la sesión a hablar de lo hecho en el laboratorio estos dos días: dificultades, ideas interesantes... lo que sea.
TEMA (EXTRA) 11: Cómo usar un navegador como capa (tier) final de la capa View(con Java, hablaremos de JSPs)
Petición a Gemini: Necesito el código para una página web que simule el interfaz de una conversación de WhatsApp. Es decir, que tenga un campo de texto abajo,
que sea un formulario, y a lo largo de la página que haya globos con texto a izquierda y derecha, simulando una conversación.
Pero necesito este código en formato JSP, no en html
Su respuesta: canvas
que se ve así (ojo, que hay problemas serios que resolver para que esto sea un frontend de una app)
¿Dónde aprender sobre JSPs? --> aquí
DICIEMBRE
Veremos, efectivamente, lo que no fue posible el último día... usar NetBeans para hacer una webapp (usando JSPs para tener un navegador como frontEnd).
¿Dónde estuvo el problema para no poder dar de alta el proyecto en la sesión anterior? Es necesario especificar un servidor web, y al parecer no había ninguno instalado.
La opción más simple era instalar un Apache Tomcat y mi error fue suponer que NetBeans lo haría como sucede con otras opciones, pero que no me daba por bueno ningún directorio. El caso es que hay que seleccionar uno previamente
instalado (descargable aquí).
Para avanzar un poco más, Esta vez lo haremos pidiendo a Gemini que estructure correctamente conforme a MVC
la respuesta que nos dio anteriormente como un único fichero "jsp". El resultado es este proyecto NetBeans exportado como zip
Advertencia: sigue sin ser suficiente para una aplicación donde el backend inicie acciones
Cosas de la IA: he visto que podía pedir a Gemini una "infografía" del tema sobre el que he pedido código. Le he solicitado que documente el proceso de petición y respuesta... ha hecho algo tan "chulo" que podéis verlo aquí.
Sesión de laboratorio ❹ (3:00 p.m. laboratorio 0.23).
...continuamos con el proyecto...
TEMA (EXTRA) 12.1: Modos de implementar la persistencia I: XML.
Presentación provisional sobre XML
Material de apoyo sobre chequeo y validación de XML:
<!DOCTYPE chatApp SYSTEM "chat.dtd"> <xsi:schemaLocation="http://www.example.com/chat chat.xsd",
es decir la xsd para el namespace http://www.example.com/chat es chat.xsd, donde el namespace es el declarado para el xml actual (xmlns)Presentación provisional sobre XML
Material de apoyo sobre procesamiento de XML:
Os habréis fijado (o no) que cuando abrís ficheros XML (extensiones xml y xsd), el navegador los muestra indicando que no ha encontrado "la hoja de estilo" para renderizarlo, y por tanto "decide" hacerlo añadiendo la capacidad expandir o colapsar los elementos. Esto de la hoja de estilo (XSL -XSLT en realidad en este caso del navegador- lo veremos más adelante), pero ya que ha salido, aquí tenéis el fichero chat.xml incluyendo una linea que determina su "estilo" (en realidad una transformación a HTML). Comprobaréis que no se parece demasiado al xml original, sino que es cierta información contenida en él y formateada en html... es como si un programa generase un informe basado en el XML... el asunto funciona así: el navegador recibe el XML y al ver que referencia a una XSL, aplica un procedimiento estándar para aplicar la XSL "como si fuese un programa" al XML. Que el navegador ha recibido el XML podéis comprobarlo pidiéndole, con el menú contextual, el código fuente recibido (en ese fuente podéis localizar la referencia a dónde se encuentra la XSL que ha aplicado, aunque eso es tema para más adelante).
TEMA (EXTRA) 12.2: Modos de implementar la persistencia II: Bases de datos.
Una base de datos es un conjunto organizado de información estructurada, almacenada de manera que permita su acceso, gestión y actualización de forma eficiente. Habitualmente es administrada por un Sistema Gestor de Bases de Datos (SGBD), que facilita operaciones como la consulta, inserción, modificación y eliminación de datos, garantizando además propiedades como la integridad, la seguridad y la persistencia de la información.
SQL (Structured Query Language) es un lenguaje estándar utilizado para definir, gestionar y consultar bases de datos relacionales. Desde un programa Java, las instrucciones SQL se envían al gestor de bases de datos para crear tablas, modificar datos o realizar consultas. El gestor procesa estas órdenes y devuelve los resultados en forma de objetos Java que representan tablas o conjuntos de filas (por ejemplo, mediante la interfaz ResultSet). Aunque cada SGBD puede añadir extensiones propias, la sintaxis básica de SQL es común a sistemas como MySQL, PostgreSQL, Oracle o SQL Server.
Para que una aplicación Java pueda conectarse a un gestor de base de datos concreto, es necesario utilizar un driver JDBC específico proporcionado por ese sistema. Este driver actúa como intermediario entre el programa y el SGBD, permitiendo que las operaciones de consulta y actualización se realicen mediante la API estándar de JDBC. Sin el driver adecuado, Java no puede establecer la conexión ni ejecutar instrucciones SQL contra la base de datos.
Clase anulada por falta de "quorum". Los contenidos pasan al jueves o viernes, en función de qué pase con la sesión de laboratorio.
Sesión de laboratorio ❺ (2:00 p.m. laboratorio 0.23).
Extenderemos esta sesión de laboratorio, recuperando las dos horas perdidas en las clases de 6/11 y 4/12, y la plantearemos como "una especie de hackatón", de modo que la última hora se dedicará a mostrar el estado de los proyectos de cada uno de los grupos. No es algo que pueda contar negativamente en la evaluación de la asignatura -que se hará en la fecha que se ha asignado por la facultad a un examen final- pero dentro del margen de subjetividad o discrecionalidad que toda evaluación conlleva, sí puede ser algo positivo.
Como referencia para hacer algún comentario (y para que haya análisis de la competecia):

Podéis pedirle a la IA que analice vuestro proyecto y que os indique debilidades a corregir (y posteriormente pedirle ayuda para esa corrección)
Como ejemplo, un resumen básico de lo que dice Gémini3_razonador respecto al código del 2º de los ejemplos anteriores:

TEMA (EXTRA) S.N.: Hablaremos de la IA.
A lo largo del curso habéis sido usuarios de IA. Algunos quizás hayais tenido el interés previo de saber cómo funcionan las IAs y tengáis ya claro en qué consisten, pero quizás la mayoría sereis meros usuarios. Hablemos un poco de IA...
Creo pertinente empezar con una presentación sobre la historia de la computación que he solido usar en la asignatura "Arquitectura de Computadoras",
de la que me interesa particularmente la parte final .
Y a continuación podemos hablar un poco sobre ¿Quién es la IA? (Sí, ¿Quién?, que se lo pregunten a Jack Lemoine)

Ahora para "ir al grano", otra (mala) presentacion hecha con IA... esta vez sobre la historia de la IA
que "pide" recordar algo que vimos al principio del curso: Turing descubrió la esencia de la inteligencia
Fusionaré con el tiempo la presentación anterior con esta otra un poco más trabajada: Padres de la IA
Algunas referencias que he guardado más o menos "aleatoriamente" para hacer comentarios "random" (acéptese la redundancia).
Propuesto por Grok:
TEMA 3 - ELEMENTOS BÁSICOS DEL LENGUAJE