Los gurús y el trabajo en equipo

Sin duda, siempre existen personas brillantes que se distinguen por su buen sentido común, curiosidad y capacidad para resolver problemas difíciles. Pero siempre he sospechado que la imagen del gurú está sobrevalorada.

Algunas malas experiencias me dicen que esto podría ser así.  En cierta ocasión, durante el desarrollo de un proyecto mas o menos grande y en una demostración de capacidades, el líder del equipo, que se sabía muy bueno en el desarrollo de software (el gurú), comenzó a utilizar una serie de tecnologías y frameworks de moda para impresionar al cliente y al administrador de proyecto.  Como resultado, los que tenían menos experiencia comenzaron a sufrir con la curva de aprendizaje y se enfocaron mas a conocer las nuevas tecnologías que al modelo de negocio. El desarrollo se terminó con una aplicación robusta tecnológicamente, pero poco amigable para el cliente y por supuesto en mas tiempo del que se esperaba. Un pequeño desastre.

En otras ocasiones, me he topado con el típico personaje que es capaz de resolver problemas difíciles, pero que cuando tienes que dar mantenimiento a su código o simplemente necesitas usarlo, este te parece tan desordenado que te dan ganas de hacerlo de nuevo.

Otro de los riesgos de tener a una persona que tiene todo el dominio sobre cierta tecnología, herramienta o el conocimiento mas crítico de un proyecto, es que puede simplemente irse, con el todo su conocimiento.

Me agradan mas los equipos de trabajo donde los problemas difíciles o algunas decisiones tecnológicas se resuelven entre varios.

Los gurús se equivocan como cualquier otro.

Además, cuando te autoproclamas gurú, puedes quedarte solo a la hora de resolver problemas difíciles.  Creo que no hay necesidad de que esto sea así, porque el criterio para resolver un problema crítico se reduce al de una sola persona y no creo que esto sea muy conveniente.

Cuando alguien te hace una pregunta complicada sobre algún problema o error, es probable que ella misma tenga mas capacidad para responderla, ya que conoce mejor el contexto del problema.  Por lo que mas que tratar de dar una solución es mejor dar un punto de vista o pistas sobre como resolver el problema.

El protagonismo es algo que nos puede seducir a todos, pero yo me lo pensaría mucho antes de adoptar una postura de este tipo. Sobre todo cuando de lo que se trata es hacer mas agradable y profesional tu trabajo.  Desde luego no estoy diciendo que todos los gurús son malos, de hecho también he conocido a algunos muy buenos. Pero son los menos.

Un hábito que recomiendo a todos es que cuando encuentras la solución a un problema difícil, la comentes a tus demás compañeros. Esto permite tener una base de conocimiento colectiva y evita tener que investigar demasiado sobre un problema que ya se ha sido resuelto con anterioridad.

Tómate con calma eso de ser gurú, puedes serlo sin hacer alarde.  🙂

Pregunta Java: wait() sin el monitor correcto

Piensa la respuesta antes de abrirla. Todas las opciones parecen razonables, y casi siempre hay un detalle que lo cambia todo.

Pregunta Java · Threads

¿Qué sucederá al tratar de compilar y ejecutar el siguiente código?

public class Test {

    public static void main(String[] args) {
        String mensaje = "Hola";
        synchronized (args) {
            try {
                mensaje.wait();
            } catch (InterruptedException e) {
            }
        }
        System.out.println(mensaje);
    }
}
  1. La compilación falla.
  2. Imprime "Hola".
  3. Una IllegalMonitorStateException es lanzada en tiempo de ejecución.
  4. Nada se imprime, el thread principal solo espera en la línea 7.
Ver la respuesta

Respuesta: 3.

java TestException in thread "main" java.lang.IllegalMonitorStateException: current thread is not owner
	at java.base/java.lang.Object.wait0(Native Method)
	at java.base/java.lang.Object.wait(Object.java:389)
	at java.base/java.lang.Object.wait(Object.java:351)
	at Test.main(Test.java:7)

Compila sin problemas: wait() es un método de Object y cualquier objeto lo tiene. El fallo llega al ejecutar. Para llamar a wait() sobre un objeto, el hilo tiene que tener el monitor de ese mismo objeto, y aquí tiene el de args, no el de mensaje. Estar dentro de un bloque synchronized no basta: tiene que ser synchronized (mensaje).

La trampa está en la opción 4: con el monitor correcto, el hilo sí se quedaría esperando para siempre en la línea 7, porque nadie llama a notify().

Pregunta publicada en 2013 y revisada en octubre de 2026. La respuesta se comprobó compilando y ejecutando el código con Java 25 LTS en un contenedor limpio; las salidas están copiadas de esa ejecución.

Suele pasar…

Texto sobre fondo gris azulado: «Suele pasar. Llevas horas buscando un error en tu código y cuando comienzas a explicarlo a alguien más para que te ayude… ¡lo encuentras! :)».

«Suele pasar»

Tiene nombre: depuración con patito de goma. Al explicar el código en voz alta, línea por línea, te obligas a revisar lo que das por supuesto, y ahí suele estar el error. Funciona incluso explicándoselo a un patito de goma.

Día del programador

Texto sobre fondo azul: «Es el día del programador. ¡Felicítame! Probablemente lo pasaré trabajando», con una cara triste.

«IIII IIII» día del programador

El Día del Programador se celebra el día 256 del año, el 13 de septiembre, porque 256 es el número de valores que caben en un byte. Y, como dice la imagen, lo normal es pasarlo trabajando.

Diseño

Texto sobre fondo oscuro: «Sin requerimientos o sin diseño, la programación es el arte de agregar errores a un archivo de texto vacío», cita de Louis Srygley.

«Sin requerimientos o sin diseño la programación es el arte de agregar errores a un archivo de texto vacío»

Empezar a programar sin saber bien qué hay que construir es la forma más rápida de escribir código que habrá que tirar. Dedicar un rato a entender el problema ahorra días de correcciones.

Talento

Texto sobre fondo oscuro: «Para ser un buen programador se requiere 3% de talento y 97% de esfuerzo para no distraerse con Internet».

«Para ser un buen programador, se requiere 3% de talento y 97% de esfuerzo para no distraerse con Internet»

El talento ayuda, pero lo que marca la diferencia es la constancia. Y la mayor amenaza para la constancia está a una pestaña de distancia.

Complejidad

Texto sobre fondo claro: «Controlar la complejidad es la esencia de la programación», cita de Brian Kernighan.

Brian Kernighan, coautor del libro El lenguaje de programación C, resume en una frase buena parte del oficio: dividir los problemas, ponerles nombres claros y evitar que todo dependa de todo.

Quiero cambiar al mundo…

Texto sobre fondo azul claro: «Quiero cambiar al mundo, pero no me dan el código fuente».

Si el mundo fuera un programa, bastaría con tener el código fuente para arreglarlo. Es también un guiño al software libre, cuya idea central es justamente poder leer y modificar el código.

Pregunta Java: el orden de un HashSet

Piensa la respuesta antes de abrirla. Todas las opciones parecen razonables, y casi siempre hay un detalle que lo cambia todo.

Pregunta Java · Collections

¿Cuál es el resultado de ejecutar el siguiente código?

import java.util.HashSet;
import java.util.Set;

public class Test {
    static void imprime(Set<? extends String> set) {
        for (String elemento : set) {
            System.out.format("%s ", elemento);
        }
    }
    public static void main(String[] args) {
        Set<String> set = new HashSet<String>();
        set.add("A");
        set.add("J");
        set.add("A");
        set.add("X");
        imprime(set);
    }
}
  1. imprime "A J A X"
  2. imprime "A J X"
  3. La salida no puede ser determinada
Ver la respuesta

Respuesta: 3.

java TestA X J

Un HashSet no guarda duplicados, así que la segunda "A" se descarta y quedan tres elementos. Pero no garantiza ningún orden: los coloca según su hashCode, y en nuestra ejecución salió A X J, que no es el orden en que se añadieron ni el alfabético. La documentación ni siquiera garantiza que ese orden se mantenga a lo largo del tiempo.

Si necesitas que salgan en el orden en que se insertaron, usa LinkedHashSet; si los quieres ordenados, TreeSet.

Pregunta publicada en 2013 y revisada en octubre de 2026. La respuesta se comprobó compilando y ejecutando el código con Java 25 LTS en un contenedor limpio; las salidas están copiadas de esa ejecución.

Algunos de los Errores Más Críticos en el Desarrollo de Software

1–Neutralización inadecuada de elementos especiales usados en un comando SQL (SQL Injection)

La inyección SQL es un método de infiltración de código intruso que se vale de una vulnerabilidad informática presente en una aplicación en el nivel de validación de las entradas para realizar consultas a una base de datos.
El origen de la vulnerabilidad radica en el incorrecto chequeo y/o filtrado de las variables utilizadas en un programa que contiene, o bien genera, código SQL. Es, de hecho, un error de una clase más general de vulnerabilidades que puede ocurrir en cualquier lenguaje de programación o script que esté embebido dentro de otro.



2.-Neutralización inadecuada de elementos especiales usados en un comando OS (‘OS Command Injection’)

Un ataque de inyección de comandos en el sistema operativo se produce cuando un atacante intenta ejecutar comandos de sistema a través de una aplicación vulnerable. Las aplicaciones se consideran vulnerables al ataque de inyección de comandos si se utilizan las entradas del usuario y se ejecutan directamente.

3.- Copia de buffer sin comprobar el tamaño de la entrada. (Clásico ‘Buffer Overflow’)

Es un error de software que se produce cuando un programa no controla adecuadamente la cantidad de datos que se copian sobre un área de memoria reservada a tal efecto (buffer), de forma que si dicha cantidad es superior a la capacidad preasignada los bytes sobrantes se almacenan en zonas de memoria adyacentes, sobrescribiendo su contenido original.

4.-Neutralización inadecuada de datos entrada durante la generación de Web Pages (‘Cross-site Scripting’)

XSS, del inglés Cross-site scripting es un tipo de inseguridad informática o agujero de seguridad típico en las aplicaciones Web, que permite a una tercera parte inyectar páginas web o contenido ajeno, para ser visto por el usuario usando código JavaScript u otro lenguaje script similar (ej: VBScript), evitando medidas de control como la Política del mismo origen. Este tipo de vulnerabilidad se conoce en español con el nombre de Secuencias de comandos en sitios cruzados.

5.- Falta de Autenticación en Funciones Críticas.

La falta de autenticación es común en los sistemas que por falta de tiempo para su desarrollo o descuido son dejados al final.  Los programadores se enfocan en crear los módulos críticos del sistema que son los mínimos necesarios para operar y dejan funciones de autenticación para el final.

6.- Falta de Autorización.

Este problema no es igual al del punto 5, aquí se trata de restringir a los usuarios de un sistema a ciertas funciones dentro de una aplicación.   No todos lo usuarios deben tener los mismos privilegios y la autenticación no es suficiente.  Por ejemplo, si tienes una función para crear o dar de alta a usuarios nuevos, esta función debe quedar restringida para perfiles con privilegios de administrador.

7.- Uso de credenciales “Hard-code”

Crear una contraseña oculta en el código para poder acceder sin restricciones es muy mala idea, una vez que esta contraseña se sabe la violación de seguridad es permanente.

8.- La falta de cifrado en datos confidenciales.

Siempre que se provee de autenticación a usuarios es necesario almacenar de alguna forma un username y una contraseña.  Almacenar la contraseña o cualquier otro dato crítico, sin ningún tipo de cifrado, permite que un atacante que haya podido vulnerar el acceso a una base de datos o cualquier otro medio de almacenamiento que use tu sistema, tome también los datos de acceso de los usuarios y use otras funciones críticas de la aplicación de forma directa.

9.- Carga no restringida de archivos potencialmente peligrosos.

Algunas veces se provee a los usuarios de funciones que permitan cargar imágenes, documentos o cualquier clase de archivo que la solución lo requiera.  Se debe tener cuidado en filtrar todos aquellos archivos que puedan ser ejecutados tanto por el sistema operativo como por el contenedor web, o bien simplemente utilizados con fines distintos a los que se ha diseñado la solución.

10.- Depender de Entradas que no son confiables para decisiones críticas.

No se debería por ejemplo, permitir a usuarios ejecutar funciones críticas o la descarga de contenido no apropiado basándose en los datos que proporciona, como su edad o algún otro dato que pueda ser fácilmente falseable.  A veces es necesario proveer a las aplicaciones de una serie de candados como números de seguridad, identificaciones oficiales, captchas, etc.