lunes, 30 de mayo de 2011

¿En qué se parece un informático a un limón?

En vez de hacer un chiste fácil, y seguramente malísimo, con la frase, voy a tratar de aportar mi grano de arena a la eterna discusión de "¿Por qué el mercado de informáticos está tan mal/desprestigiado y generalmente se cobra tan mal en relación a la valía?"

Para explicarme debo mencionar la teoría económica de un economista de 1970, George Akerlof, expuesta en un artículo bajo el título "The Market for Lemons: Quality Uncertainty and the Market Mechanism". En realidad en este caso "lemon" no se traduciría por limón, de ahí el chiste malo, si no por su acepción menos conocida de "cacharro" o "cosa decepcionante".
Por simplificar, la teoría viene a decir que cuando en un mercado de un artículo, el comprador no tiene información fiable a priori para saber si lo que compra es bueno o es malo, y el vendedor sí, al final en ese mercado se acaban vendiendo solamente los "cacharros", es decir, los artículos de peor calidad y a precios bajos.
Una explicación basada en un ejemplo la podéis encontrar en esta entrada del blog Fermat Margin.

Y eso es en parte lo que nos ocurre en el mercado de los informáticos, especialmente cuando tienen menos experiencia, ya que muchas veces quien contrata no sabe de que va el tema y no tienen experiencia previa, así que no pueden evaluar de forma fiable la valía de los candidatos.  Y la cosa va tal que así
  • El comprador (el que contrata) no tiene forma medianamente fiable de saber como le va a salir el artículo (el posible empleado). Para no pasarse, obviamente tira por un sueldo medianero.
  • Los buenos programadores que merecerían más sueldo, rechazan trabajar por ese sueldo y buscan otras cosas.
  • Por tanto entre los que aceptan esos trabajos, sólo quedan los que merecen ese sueldo y los que no.
  • Por tanto el comprador cuando mira lo que obtiene por lo que paga, se da cuenta de que la media le sale por debajo, así que la próxima vez ofrece sueldos más bajos.
  • Y así recursivamente, hasta que los sueldos son una mierda y en ese mercado sólo trabajan los malos empleados que no podrían aspirar a nada más. Por lo tanto los empleadores ven confirmada su idea de que realmente no ha de pagar más por que todos los que contrata son malísimos, y los buenos empleados no tienen ningún incentivo por hacerlo bien, puesto que les van a pagar como si fueran malos, así que al final se convierten en malos.
Y ahí tenemos un bonito circulo vicioso :). No lo explica todo, y por supuesto los buenos empleados pueden encontrar buenos empleos, si salen de ese mercado, y los empleadores pueden encontrar personal adecuado si no entran en este juego. Pero es una pieza más del puzzle, aparte de la avaricia, la cultura del pelotazo y todos esos tópicos que ya se mencionan suficiente. Simplemente me apetecía añadir este enfoque diferente y curioso que explica algunos de los comportamientos humanos que llevan a situaciones desastrosas.

Ni soy economista ni gurú, así que no tengo ni creo tener receta mágica para solucionar este tipo de problemas, pero si crees ser un buen empleado, no te conviertas en un limón y si eres un empleador, no vayas al mercado a por limones. Hay que recordar que la clave de este problema concreto es la información, o falta de ella, de una de las partes. Decir que con más información se soluciona es fácil, aplicarlo en la vida real es lo complicado ;).


Happy coding! EJ

sábado, 1 de enero de 2011

Estándar de nomenclatura en BDD

Hoy una entrada sobre el sistema personal de nomenclatura de BDD que me gusta utilizar en mis aplicaciones cuando tengo la capacidad de decidir. No siempre es así, a veces se trabaja con BDD heredadas o uno no es el responsable de esa área, pero cuando es posible, personalmente prefiero utilizar este sistema que me proporciona la sensación de tener más "ordenada" la BDD.

La idea, al fin y al cabo, es tener un sistema que sea fácil de seguir y que permita identificar fácilmente los elementos que se estan utiizando en consultas, los que se referencia en mensajes de error, en relaciones entre elementos etc.

Resaltar especialmente que este es el sistema que YO utilizo, pero hay muchos otros cada uno con sus pros y sus contras y no es mi intención decir que es el mejor ni nada remotamente parecido. En este caso, se cumple el dicho de que para gustos, colores y la organización o el DBA son los responsables de escoger entre la cantidad de opciones disponibles.

.- El primer punto es sencillo, escoger tres letras como alias de "la aplicación" o módulo a desarrollar. Por ejemplo, si vamos a trabajar la parte de almacén y no se ha usado ya ese "álias", podríamos escoger ALM como álias de aplicación.
.- Una vez escogido el primer punto, las tablas empezarían con T + dicho álias, las vistas con V + álias, las restricciones de integridad con K + álias, los índices con I + álias... etc. Así pues, la tabla para representar los productos en la aplicación sería TALM_PRODUCTO, la de clientes TALM_CLIENTE y así sucesivamente. Los nombres siempre en singular y sin abreviar a no ser que la longitud sea muy muy larga. Hoy en día restringir los nombres a 8 caracteres o menos como se hacía antes tiene muy poco sentido.
.- Dentro de las tablas, yo prefiero utilizar siempre un identificador único e inventado sin significado de negocio, siempre con el mismo nombre y el mismo tipo. Además, cada tabla tiene su propio álias y se añade delante de todos los nombres de los campos. Por ejemplo, la tabla TALM_CLIENTE, con alias CLI, tendria los campos CLI_ID, CLI_NOMBRE, CLI_NIF..., la de productos tendria PRD_ID, PRD_NOMBRE, PRD_CODIGO... Darse cuenta de que PROD_ID sería un identificador inventado y que el número que viene en el producto sería por ejemplo PRD_CODIGO. Existen múltiples discusiones a favor y en contra de usar o no identificadores inventados y no voy a intentar convencer a nadie. Sólo decir que tener que detener la operación del sistema periódicamente para poder anular las restricciones de integridad para solucionar los problemas de errores en los identificadores no inventados da una perspectiva diferente :). No voy a decir que no tenga inconvenientes o que el sistema esté mal hecho si no se sigue. Sólo puedo decir que cuando puedo elegir, YO lo hago así. Siguiendo con lo ya mencionado, la restriccion de clave primaría tiene el alias de la aplicacion y de la tabla seguido del sufijo _PK, para indicar que es "primary key". Por ejemplo, para la tabla TALM_CLIENTE sería KALM_CLI_PK, para TALM_PRODUCTO sería KALM_PRD_PK etc.
.- Las claves extranjeras simplemente referencian el campo en la tabla "remota" añadiendo el prefijo correspondiente y sólo en caso de existir más de una clave extranjera contra la misma tabla se añade un sufijo para diferenciarlas. Por ejemplo, en la tabla TALM_STOCK, tendríamos una clave extranjera a TALM_PRODUCTO bajo el nombre STK_PRD_ID, en TALM_FACTURA tendríamos FAC_CLI_ID para referenciar el cliente... etc. Como se puede ver esto facilita enormente la identificación de los elementos de cada relacion, incluso permite automatizar algunas tareas. Por otro lado, las restricciones de integridad de las claves extranjeras indican en este caso ambas tablas y el sufijo _FK, de "foreign ey". Las restricciones para los ejemplos mencionados serían KALM_STK_PRD_FK y KALM_FAC_CLI_FK. De este modo, al violar una de estas claves, el mensaje de error ya nos indicará claramente cuales con las tablas implicadas.
.- Las restricciones sobre campos indican el nombre del campo y el tipo de restriccion, por ejemplo PRD_CODIGO sería un campo seguramente único y como tal tendría la restriccion KALM_PRD_CODIGO_UK (de "unique key"), las restricciones de integridad serían igual pero con _CHK al final etc.

Ese es básicamente el estilo de nomenclatura que sigo y con el que me siento comodo, aunque no soy muy talibán al respecto.

A la hora de trasladar el modelo de datos a clases Java los prefijos desaparecen y uso un estilo de nomenclatura más "javero" y así de esta forma cada mundo es coherente y sigue sus propias reglas. Eso implica que siempre tengo que especificar los nombres de los elementos que corresponden en cada caso, pero es una "molestia" que tengo automatizada y no me importa pagar ese precio. La razoón para no tener que usar tanto sufijo en Java es que con la estructuración en paquetes y el estilo de los errores ya da suficiente información como para poder situarte rápidamente sin necesitar esas ayudas.

No intento convencer a nadie de que use nada pero por si a alguien le da alguna idea y/o le sirve, ahí queda dicho. Y una vez dicho esto...¿Usais vosotros, estimados lectores, algún tipo de estilo/estándar de nomenclatura?

Happy coding! EJ

PD: Ah, feliz año nuevo ;). A ver si este 2011 nos trata un poco mejor a "la plebe" y un poco peor a los chupasangres del mundo.

viernes, 24 de septiembre de 2010

Paths relativos, especificaciones, Java y un bug en "Internetes"

Hoy en el trabajo me he encontrado con “un bug en Java e Internetes”. Bueno, más que un bug es un comportamiento extraño por especificaciones obsoletas, implementaciones independientes de contexto etc. etc. Pero es algo que te puedes encontrar en la vida real, así que he pensado que sería interesante contarlo.
El problema se da al leer un documento HTML con Java y tener que interpretar las direcciones relativas que contiene dicho documento. Si una de las direcciones únicamente contiene un “query string”... ¿Cómo la interpretarías vosotros?
Es decir, si en la página www.host.com/dir/loquesea.do encontramos un enlace tal que así href=”?param=value”... ¿Dónde ha de ir la página?
La respuesta correcta es “depende” :).

¿Y cual de las dos respuestas es incorrecta? En realidad “ninguna”. La clase java.net.Uri implementa correctamente la resolución de caminos relativos según la RFC2396, de agosto de 1998, y por ello elimina el “loquesea.do” antes de añadir el camino relativo. En cambio HTML 4.1 está basado en la especificación RFC1808, de junio de 1995, la cual dice que si hay “query string” se mantiene la dirección completa como base. Lo curioso es que HTML 4.1 es de diciembre de 1999, más de un año después de que la RFC1808 fuera “sobre-escrita” por la RFC2396 pero sin embargo, parece al escribir la especificación de HTML no se fijaron en que la RFC1808 ya no estaba en vigor. De todas formas, el comportamiento de los navegadores es correcto ya que HTML 4.1 se basa en la RFC1808 y ésta es la que hay que seguir. Y la clase java.net.Uri tampoco hace nada “incorrecto” ya que en realidad sigue una especificación más reciente. En realidad podría hacerlo “mejor” si permitiera especificar si el método resolve() ha de funcionar según HTML 4.1 o el futuro HTML 5, y puestos a tener un comportamiento por defecto... HTML 4.1 es muy común.... en fin, que la cosa es bastante ambigua así que la mejor solución es no escribir nunca enlaces de esa forma y escribirlos al menos un poco más explícitos, o si hay que tratar en Java las páginas HTML que escribe un tercero... si esas páginas son HTML 4.1 hay que tener en cuenta que java.net.Uri no resuelve las direcciones relativas como lo hacen los navegadores, así que hay que tratar la dirección antes de pasársela para obtener el resultado esperado.

Y ahí queda escrito ese aviso para navegantes, por si a alguien le ahorra un buen rato de investigación leyendo especificaciones y el código del OpenJDK como he tenido que hacer yo.



Happy coding! EJ

lunes, 20 de septiembre de 2010

Dime tu lista de prioridades y te diré lo profesional que me pareces

Un tema interesante y que da para muchas discusiones es “¿qué convierte/define a un buen informático?” Sin ánimo de sentar cátedra ni de que los demás piensen igual, voy a dar mi opinión personal e intrasferible de lo que define a un profesional del desarrollo de software (no a cualquier tipo de informático) pero siendo un pelín original. En vez de decir la típica lista de atributos, simplemente me fijaré en un aspecto que es: El orden de prioridades a la hora de afrontar un trabajo.
Así que sin más dilaciones, la pregunta crítica: “¿A que le das más importancia a la hora de desarrollar un software?
  • A aplicar los patrones X, Y y Z. Si esa es tu prioridad más alta o está entre las más altas, lo siento pero entras dentro de la categoría empezar-la-casa-por-el-tejado. Los patrones son soluciones comunes y conocidas para ciertos tipos de problemas, y si tu interés se centra en usarlos sin saber si son aplicables a tu problema, ciertamente tienes el orden de las prioridades un poco confundidas. El desarrollo no es un concurso para aplicar el mayor número de patrones posibles, ni aplicar patrones significa garantía de nada (de ahí el invento de los anti-patrones) así que la hora de pensar en aplicar patrones está bastante más abajo, una vez sepamos a qué problemas no estamos enfrentando y en caso de reconocer algún problema habitual que se solucionar con un patrón, nada mejor que aplicarlo. Pero no antes.
  • A aplicar las más modernas y “más mejores” técnicas de desarrollo. Si este objetivo lo tienes muy alto significa que te dejas llevar por las modas y que eres una “fashion-victim”, de las que se tragan eso de que todo lo nuevo es mejor y que lo viejo huele a rancio. Como pez en el agua en el mercado consumista, pero en versión tecnológica. Si es solo producto de la juventud y no de la falta de neuronas, no te preocupes que se cura con la experiencia :). Cuando veas a la misma gente contando cada X tiempo mentiras nuevas, por que con las viejas no se hace negocio, aprenderás a ver detrás del humo y distinguir lo aprovechable de las novedades y lo que hay que conservar de lo que ya existe, siempre en función del tipo de trabajo que tengas.
  • A que el diseño sea orientado a objetos (sustituible por cualquier concepto purista). Este tipo de objetivos están muy bien para el mundo teórico, pero tienen ese ligero problemilla de que a la tozuda realidad a veces no le gusta jugar con reglas perfectas. Seguro que eres de los que creen que la tierra es perfectamente redonda y el mar es azul, al fin y al cabo los pintan así en todos los libros ¿verdad? Pues no, la perfección teórica está muy bien pero sirve a un fin, no es la finalidad en sí misma. Es decir, que el diseño sea lo más orientado a objetos posible persigue un fin, que es obtener los beneficios de la OO etc. pero si no vamos a conseguir esos beneficios, por diversas razones, entonces ya no tiene utilidad.
  • A usar el lenguaje/framework X.Seamos sinceros, la mayoría de los proyectos sabemos en que lenguaje/arquitectura los vamos a realizar por que es en el que realizamos casi todos, si no todos, nuestros proyectos y no vamos a re-evaluar nuestra cartera de soluciones en cada proyecto (en la mayoría de casos, en algunas empresas lo hacen pero por necesidad). Aun así, a la hora de cambiar de lenguaje/arquitectura en un proyecto hay que recordar qué es lo realmente importante, y no, no es usar una solución específica a no ser que el proyecto tenga ese objetivo concreto.
  • A cumplir lo que se me mande hacer, que para eso me pagan. Esta actitud conformista y muy habitual no es que sea terriblemente mala, pero no le convierte a uno en un gran profesional. Especialmente en nuestro campo donde muchos mandos intermedios no saben lo que significan la mitad de las siglas que usan y se limitan a distribuir la mierda que cae desde arriba entre los de abajo. Repito, es algo comprensible pero por hacer un examen justito a uno no le ponen un 10.
  • A disfrutar trabajando. Sí, numerosos estudios demuestran que la gente trabaja mejor cuando está más contenta y en trabajos creativos como el nuestro es muy importante la mentalidad y la actitud, pero hombre, “un hombre ha de hacer lo que tiene que hacer” y la vida no es una fiesta constante. Si toca hacer un mantenimiento, se hace, aunque hayamos hecho mil. Es importante que el trabajo sea gratificante, pero tambien hay que tratar de disfrutar con nuestro trabajo. Como dicen los sabios “no es más feliz quien más tiene, si no quien menos desea”. O dicho de otro modo: “Señor, dame fuerza para aceptar las cosas que no puedo cambiar, valor para cambiar las cosas que puedo y sabiduría para poder diferenciar entre unas y otras.”
  • A hacer lo que el cliente pide. Esta es otra actitud comprensible, decente... pero estamos hablando de informática, no de una tienda de ropa, y aquí el cliente no tiene siempre la razón, simplemente por que el experto en manejo de la información se supone que eres tú, y no él. Hacer lo que el cliente dice sirve para cubrir el expediente y salvaguardar el culo, pero no se lleva el máximo galardón en mi lista.
  • A solucionar “El Problema”. Obviamente, como último en la lista, esta es la que yo considero que es la más profesional de las prioridades. Hay que entender cual es “El Problema” que queremos solucionar, ayudados por el cliente, usando el lenguaje y framework adecuados, que normalmente será los que conocemos ya que que los conozca el equipo de desarrollo da muchos puntos, utilizado las técnicas y patrones adecuados y si encima podemos disfrutar haciéndolo, mejor que mejor. Con esto lo que quiero decir es que la prioridad es dar respuesta al problema. Los programas, de momento, no son obras de arte para ser admiradas sin más, tienen una finalidad y cumplirla debería ser la máxima prioridad, la cual muchas veces se combina con el resto ya que ayudan a cumplirla, pero siempre hay que tener el orden claro.
Y esa es mi lista. Como se puede ver soy del modelo pragmático, pero es lo que hay. La lista no será del agrado de todos pero lo que está claro es que es la mía y sobre eso no hay discusión. ¿Y la tuya?

Happy coding!
EJ

jueves, 2 de septiembre de 2010

Arquitectura ligera y uso de cachés

Después de explicar un poco la arquitectura ligera que estoy empleando en un proyecto y dado que estoy usando una caché, tema sobre el cual ya desvarié un poco, he pensado que también podría ser interesante explicar cómo estoy usando la caché en este proyecto, basándome en las reflexiones del mensaje sobre uso de cachés.

Como ya expliqué, el proyecto consiste en mostrar los resultados de las partidas de un juego online, quien participó, cómo lo hizo cada piloto y estadísticas recopilatorias sobre el historial de cada piloto. Respondamos entonces a las preguntas clave:

¿Merecía la pena introducir una caché? La respuesta en este caso es que claramente sí, dado que vamos a mostrar resultados acumulados de varias tablas, especialmente en el caso de las estadísticas históricas. Incluso la “simple” lista de partidas jugadas es una consulta que cruza 4 tablas ( no por que esté mal el esquema de BDD si no por que ya muestra datos acumulados) y las primeras pruebas ya indican un incremento en el rendimiento de x30 en las consultas más simples.

¿En que capa he introducido la caché? Dejar que la BDD se encargue de ello implicaría que todavía tendríamos que viajar por la red hasta la BDD. La cache de MyBatis no es algo con lo que he experimentado y no se que control me da (creo que no suficiente por lo que he leído en las listas de distribución), así que seguimos subiendo. El control de caché del framework ligero lo conozco bien y se que control me da: más que suficiente. Podría intentar subir aun más y usar la caché a nivel de filtro de servlets en la salida final (HTML o JSON), pero dado que más tarde introduciremos personalizaciones para que los usuarios vean sus propias páginas y eso implica que puede que la salida final de cada usuario sea ligeramente diferente, me quedo justo en el nivel de abajo. De todas formas, el salto gordo en el rendimiento se produce en este caso, como en muchos, en la consulta a la BDD y la creación de los objetos correspondientes en el servidor, así que haciendo caché de eso ya obtengo un gran beneficio.

¿Como vamos a mantener actualizada la caché? En la aplicación hay 3 tipos de páginas, clasificándolas en relación de dependencia con datos actualizables:

  • Grupo 1: Las que dependen de todas las partidas jugadas: Lista de partidas, estadísticas globales, clasificaciones de todos los jugadores, etc.

  • Grupo 2: Las que dependen de un piloto en particular: Estadísticas generales de cada piloto, detalles sobre los elementos utilizados por el piloto en sus partidas...

  • Grupo 3: Las que no dependen de nada: Datos de una partida y detalles de participación de cada piloto en esa partida.
Una vez sabemos esto, podemos ver que cada vez que haya una o más partidas nuevas, tenemos que invalidar todos los elementos de la caché del grupo 1 e invalidar los elementos del grupo 2 de los pilotos que hayan participado en las partidas nuevas. Los elementos del grupo 3 pueden estar en caché “indefinidamente”. Para llevar a cabo esta tarea lo que hemos hecho es implementar una tarea periódica con Quartz que a intervalos regulares comprueba si ha habido partidas nuevas y en caso afirmativo, procede a marcar como caducados los elementos de la caché según las reglas definidas.

¿Cual es el perfil de nuestra aplicación? Se presupone una aplicación donde habrá muchas más lecturas que actualizaciones, y donde las actualizaciones de datos no son críticas en absoluto. Por tanto el tipo de funcionamiento definido cuadra perfectamente.

Puntos extra: Para controlar mejor el uso que se hace de la caché y verificar que todo funciona correctamente, tenemos varias ayudas:

  • Por un lado, el framework que utilizamos de caché nos puede decir en cada momento el grado de utilización que le estamos dando (Hit/miss ratio) por lo que podemos saber si realmente se está leyendo mucho más de lo que se está actualizando la cache.

  • Por otro lado, podemos controlar la periodicidad de la tarea de control de la cache y si vemos que la el grado de utilización es bajo y la caché no se usa lo suficiente, podemos aumentar el período y así aumentar el grado de utilización, protegiendo a la vez la BDD de una carga excesiva.

  • Ambos elementos se pueden retocar en tiempo de ejecución sin necesidad de reiniciar la aplicación, lo cual nos permite una gestión muy cómoda sin miedo a molestar a los usuarios.
Espero que este ejemplo sirva para ilustrar lo que quería decir en el mensaje de reflexiones sobre el uso de cachés, y si os da algunas ideas para vuestras aplicaciones, mejor que mejor.

Happy coding! EJ

sábado, 28 de agosto de 2010

Ejemplo de arquitectura ligera

Una entrada corta sobre una arquitectura que estoy usando ahora mismo para una aplicación web de tamaño pequeño/mediano. La historia es que un grupo de "modders" estamos haciendo unas modificaciones a un juego multi-jugador online y una de las partes modificadas incluye recoger estadísticas de las partidas que se juegan: información del servidor y mapa que se jugó, qué equipo ganó, cuantas veces mataron y mató cada jugador, cuantos puntos... Y esta información la queremos publicar por web, que es la parte que me toca a mí (mi vena artística no da más que hacer cuatro palotes y mi C está demasiado oxidado como para meter mano al juego).

Así que aquí está lo que uso, por si a alguien le da alguna idea:
  • Como framework-pegamento, uso uno "custom" que es simple y ligero, no necesito más, y por ahí no pienso recomendar nada: es mal negocio :).
  • La interfaz la estoy haciendo principalmente con tablas y elementos de YUI, usando AJAX y JSON para paginar las tablas sin recargar toda la página.
  • Para formatear el JSON y las páginas que hacen de contenedores de los elementos YUI, JSP me basta. Suelo usar otras tecnologías para esto, pero como otros miembros del equipo puede que me ayuden y JSP es lo más común y sencillo...
  • Para hacer más "agradables" las URL y más intuitivas, fácil de recordar y de escribir, pero sin que me condicionen la implementación por debajo: Url Rewrite Filter.
  • Para "decorar" las páginas y hacer que los estilos y menús sean comunes: SiteMesh.
  • Para evitar machacar la BDD con consultas cuando los datos no han cambiado, se usa una cache implementada con OSCache.
  • Para las tareas que comprobarán periódicamente cuando hay que marcar como caducados algunos elementos de la caché (al acabar una partida, por ejemplo, hay que "caducar" todas las estadísticas globales de los jugadores que participaron y la lista general de partidas jugadas) uso Quartz.
  • Para consultar la BDD, como los datos que se muestran son principalmente recopilatorios, las consultas suelen implicar media docena de "joins" y la navegación por entidades mataría el rendimiento, uso MyBatis en lugar de JPA, que es lo que seguramente use para atacar la parte de autenticación, definición de equipos etc. que sigue otra estructura más orientada a objetos.
  • Para no tener que escribir tropecientos getter y setter y dejar el código limpio, uso Lombok para que lo haga por mí sin siquiera tener que verlos en el código. Muy útil en este caso.
  • La BDD es MySQL. No la escogí yo ni hice el esquema así que poco puedo decir excepto que funciona.
  • Para crear, probar y depurar las consultas contra la BDD: Aqua Data Studio.
  • Para no tener que reiniciar el contexto cada vez que hago un cambio en las clases Java: JRebel, aunque tiene algunos conflictos con Lombok. Por otro lado, el framework detecta los cambios en la configuración de MyBatis en ejecución y recarga los "Mapper", así que tengo que re-iniciar el contexto muy muy poco. Y para rizar el rizo, el tiempo de reinicio con este framework ligero y MyBatis no llega a los 4 segundos así que el famoso tiempo perdido esperando a que se (re)inicien las aplicaciones Java en este caso es irrisorio.
  • Como IDE: Eclipse, aunque el proyecto se puede montar solito en base a Ant + Ivy e incluso ejecutarlo, ya que incluye contenedor de servlets embebido para pruebas. No tengo manías y casi cualquier IDE debería valer en este caso, pero uso el que me es más cómodo.
  • Para depurar YUI: El Firefox con Firebug, como no, aunque a veces interfiere con otros plugin y últimamente me tiene algo mosqueado.
  • Para comprobar que el JSON que envío es correcto cuando me da un problema y no se si es por la estructura de JSON o un fallo en JavaScript: JSONLint
  • Como contenedor de servlets para pruebas: Jetty 6, Tomcat 5.5 y Resin 4, en sus formatos "embedido" respectivos y lanzados desde el Ant o a mano. El de producción, que tampoco escojo yo, será Tomcat 5.5, así que estoy cubierto.
De momento las pruebas iniciales son bastante satisfactorias y gracias al uso de paginación a través de AJAX y de cachés en el servidor, parece que aguantaremos la carga. Para este sistema en particular es más importante que la aplicación sea ligera y ágil, que usar grandes frameworks que nos den muchas cosas hechas que no vamos a usar o que nos permitan hacer virguerías que no haremos.

Cada aplicación tiene sus propias cosas e intentar aplicar siempre la misma receta es como intentar cocinar el pollo, el cordero y el cerdo de la misma forma. Algunas veces puede funcionar pero otras es un desastre incomestible. Así que como en las recetas de cocina, si alguien puede aprovechar partes y le sirven para sus circunstancias particulares, me alegro. Si no, pues mala suerte y a buscar sus propias soluciones :).

Bon Appétit & Happy coding!
EJ

lunes, 23 de agosto de 2010

Sobre Gurús y otros falsos mitos

Hoy un tema que seguramente levante algo de polvo, pero para eso estamos al fin y al cabo :).
Lo primero de todo: debo admitir que el "fenómeno gurú" es algo que no va conmigo y que personalmente me produce vergüenza ajena. Lo de elevar a los altares a una persona para considerarla un "gurú" se comprende en quinceañer@s con más hormonas que cerebro, pero que una persona adulta tenga tan poco consideración por si mismo como para sublimar sus opiniones a otra, por el mero hecho de la fama que tiene... en fin, que allá cada cual pero a mí que no me busquen para eso.

Volviendo al tema, una de anécdotas:
Eranse cuatro desarrolladores sentados a una mesa disfrutando de una cena y unas bebidas, dos de los cuales eran gurús de los gordos, de los que su nombre está semana sí, semana no en java.net, Dzone etc. Los otros dos éramos dos "soldados de trinchera", de los que el pan se lo ganan dándole a la tecla, coordinando nuestros proyectos, con nuestras ponencias en congresos de vez en cuando, nuestras colaboraciones en proyectos OS, pero fama: ni de lejos, ni ganas.
Una cena agradable en la que que apareció uno de los temas recurrentes: "para desarrollar me basta con el vi". Los dos gurús argumentando que los hombres de pelo en pecho de verdad sólo necesitan el vi, nosotros argumentando que saber hacerlo a pelo es imprescindible pero que los editores modernos con sus capacidades de refactoring, búsquedas de referencias etc. son una gran ayuda. Ellos que un buen desarrollador tiene todo el proyecto en su cabeza y que igualmente, hackeando el vi y con unas extensiones de no-se-donde hacía lo mismito, y total, ¿Quién necesita refactorizar si basta con escribir todo el código bien de un tirón y a la primera? Mi compañero de trinchera decía que en sus proyectos, donde a veces trabajan hasta seiscientos (sí, tantos) programadores en un sólo proyecto, pues tener formateadores estandarizados, el FindBug, y las capacidades de "refactoring", repositorios de versiones y dependencias integradas etc. sirven para que todo el mundo esté a un nivel parecido y no sólo sirvan los mega-cracks, aparte de hacer que los mega-cracks sean aun más eficientes.
Al final, como en todos estos temas que no tienen demostración matemática, "ni pa' ti, ni pa' mí" si no cada uno con su opinión. Se notó algo que estaban más acostumbrados a que la gente dijera "amén" a sus opiniones por ser quienes eran, pero tampoco tuvieron mucho problema al toparse con dos agnósticos de la fe gurú.
Ahí hubiera quedado la cosa, si no fuera por que al día siguiente en el congreso en el que estábamos le tocaba dar una charla a uno de los dos gurús, el cual ciertamente de su tema sabe un huevo y la yema del otro y mucho más que un servidor. En su charla le tocaba una demostración en vivo de ciertas técnicas y cómo el código podía afectarles, así que tenía su ejemplo preparado que consistía en unas clases Java muy simples para compilar y ejecutar.
La demo empieza bien, ejecuta el código, muestra los resultados que esperaba y todo perfecto.
Entonces toca modificar ligeramente la clase Java para comprobar una de las técnicas. Abre el vi, realiza unas modificaciones, borrando líneas enteras de texto con la x, repitiendo el mismo comando varias veces re-haciéndolo entero, y a la hora de salir guarda con :w y luego sale con :q. Para los que no uséis vi y no lo hayáis pillado, así es como trabaja alguien que sólo conoce los comandos básicos.
Pero bueno, guarda los cambios y compila con javac especificando todo a mano (¿Ant? Eso es para mariquitas). Resultado: No compila. En realidad hace falta modificar también otra clase donde se llama a la primera y como ha cambiado unos parámetros en un método... Eso lo puedo decir yo a 20m leyendo la linea que escupe javac, pero él parece no pillarlo (entiendo que los nervios en escena afectan). Al final alguien se lo chiva y abre el otro fichero, realiza otras modificaciones con la misma "habilidad" con el vi, guarda y sale. A compilar otra vez. Resultado: No compila. Esta vez es por que una de las letras llamando al procedimiento está mal, es mayúscula y ha de ser minúscula, y por eso no funciona. Etc. etc.

Resumiendo: Tuvo que saltarse la demo por que cuando no le fallaba la compilación con el javac, poniendo todos los parámetros a mano, tenía un error tonto en el código y tenía que arreglarlo, lo cual le costaba tiempo por que hasta interpretar los mensajes del javac le costaba en la tensión del momento. Y una cosa que quedó clara como el agua es que no se dedica a ganarse la vida picando código, cosa que yo ya sabía.
Conclusión: Cuando habla de su tema y está en su salsa, le escucho con los ojos abiertos. Cuando habla de otras cosas, como por ejemplo formas de picar código, valoro mucho más mi opinión o la del otro compinche de trincheras que la suya, con todo el respeto y sin desmerecer, que lo cortés no quita lo valiente.

Otra anécdota aun más cortita: Estaba yo en un congreso importante y gracias a un contacto que tengo, importante en el mundillo que no famoso, acabo cenando con un grupo donde hay "un famoso" que ha escrito un libro sobre un tema nuevo de Java, el cual todo el mundo recomienda como la Biblia del saber. Al llegar a la cena el famoso resulta ser un chico joven de veinti-pocos con cara de niño (nada en contra de la juventud, pero uno se imagina a un gurú con una larga barba blanca y profundas arrugas de meditar a la intemperie :) ). Hasta aquí nada reseñable excepto la sorpresa de descubrir una cara tan joven asociada a una tan famosa "fuente de conocimiento". Lo mejor viene durante la cena cuando movido por la curiosidad le preguntó cómo acabó escribiendo el libro ese que le hizo tan famoso. La respuesta es lo que me deja tieso: Acababa de aprender Java y nunca había trabajado con el tema del libro, así que cuando un contacto le propuso escribir un libro sobre el tema, pensó: "así aprenderé de que va esto". O sea, sin quitar méritos al libro que fue una gran guiá de iniciación para muchos, cuando el tío lo empezó a escribir no tenía ni la más remota idea del tema, y no demasiada de Java. Y ésta es la persona cuyas opiniones sobre el tema la gente pone por encima de las demás... en fin serafín.

Por mi parte, todos somos humanos y tenemos cosas de las que sabemos, cosas de las que no. Saber escribir un buen libro para iniciados no significa conocer un tema en profundidad, ser un experto en un tema concreto no nos convierte en expertos en todos los temas y dejarse llevar por la fama de la gente para poner sus opiniones de cualquier cosa por encima de otras, por el mero hecho de ser famosos, es una soplapollez que debería sonrojarnos.

Así que si te encuentras con un experto en un tema y te da su opinión sobre ese tema, escúchale, si te la da sobre cualquier otra cosa, recuerda que a igualdad de "conocimientos" la suya es tan válida como la de cualquiera.

Happy coding!
EJ