Archivo

Archive for the ‘desarrollo’ Category

Tendencias (“trends”) históricas del uso de palabras con Sphinx

febrero 13, 2014 4 comentarios

Hace unos días quise saber desde cuándo se empezó a hablar de desahucios y suicidios en la prensa en España. Fui a Google Trends y el gráfico mostraba una evolución demasiada plana, que no se correspondía con tantas noticias que leímos en la prensa española. Me pregunté si, y cómo, podía obtener esas estadísticas en Menéame. Se me ocurrió que debería haber un truco relativamente sencillo usando los índices de de búsqueda de Sphinx (lo usamos para el buscador de Menéame). Así fue que en pocas horas pude implementar un sistema similar a Google Trends en Menéame.

Esto es lo que salió con las tendencias de esas dos palabras por su frecuencia de aparición por meses:

Evolución de suicidios y deshaucios

Leer más…

No basta con ser ingeniero (y II), un ejemplo práctico

noviembre 30, 2013 7 comentarios

Hace unos días ya comenté el problema de que eliminaron una función importante en KitKat con la excusa de que no estaba documentada y por lo tanto “no oficial”, pero es una limitación seria para millones de usuarios y casi una traición para miles de desarrolladores. Hoy veo el siguiente comentario en el hilo del bug:

You broke file-uploading and released 4.4 without a ready replacement or workaround? O_o

So even if app devs manage to hack around it, they’ll have to maintain the hack forever to support phones stuck on 4.4 even after 4.5+ introduces a proper replacement function?

I need a Kitkat bar.

Es una observación clave.

Una pésima decisión de los ingenieros tendrá consecuencias negativas a largo plazo para desarrolladores, usuarios, y hasta toda la plataforma. No lo meditaron, todavía no se han percatado que las decisiones de ingenieros tienen efectos muy reales sobre las personas. Por eso, para ser un ingeniero hay que ser más que un ingeniero.

De nuevo queda en evidencia que los programadores vamos muy justitos en el tema, incluso para el nivel de programadores del sistema Android. Me genera una mezcla de decepción y cabreo, y me hace admirar cada vez más las “visión social” a largo plazo de Linus Torvalds: literalmente se enfurece cuando alguien le propone cambiar la interfaz (ABI) del kernel Linux que genera incompatibilidades con aplicaciones existentes, aunque tengan más de 10 años. Eso es ser más que un ingeniero.

PS: La única opción para remediar el problema es que parcheen las librerías de Android Kitkat para re-implementar la función openFileChooser() que eliminaron. Otra cosa es que asuman el error y lo hagan. Lo dudo, ojalá esté equivocado.

Android KitKat… ¿pretenden matar el HTML5 en Android?

noviembre 27, 2013 13 comentarios

La pregunta no es tan sensacionalista como parece. Hace unos días me avisaron de problemas para subir fotos a Menéame con Android KitKat. Era muy raro que diese problemas, está todo programado respetando estándares de HTML5 y Javascript. Descubrí que ese caso se debía a problemas de la gestión de memoria de Android y cómo la trataba Chrome (al ejecutar otro programa para seleccionar la imagen, si necesita memoria se la quita al Chrome, por lo que hay un “cambio de configuración”, al volver a Chrome, éste recarga la página completa, en vez de “reconstruir” lo que tenía). Pero descubrí otro error aún peor y que sucede siempre: es imposible subir una fotografía. Lo probé con el Nexus 4 y con el 7, en ambos el mismo problema, da un error “fatal” al seleccionar cualquier foto.

Lo probé con el Firefox sobre los mismos dispositivos, y no hubo problemas (además de sorprenderme la velocidad de Firefox, ¡cómo ha mejorado!). Se puede observar el fallo (“Error abrir archivo seleccionado” [sic]) en el siguiente vídeo que hice en el Nexus 4:

Visto lo visto, y que no parecía simple de solucionar, además que quería solucionar lo de compartir más fácilmente a Menéame desde un móvil, me decidí a desarrollar una pequeña app:

app Menéame de pruebas

Esta app sólo crea una actividad, basada en WebView, que empotra el renderer HTML. Hasta la versión 4.3 de Android, este renderer era el del “webkit” básico, a partir de 4.4 (KitKat) ya se usa el Chromium (el proyecto libre del Chrome). Todo iba bien, y funcionaba muy rápido… hasta que probé la subida de ficheros: imposible, no funciona en KitKat, y es imposible arreglarla (al menos en teoría y con la información que hay hasta ahora).

Las WebView tienen una pequeña interfaz con unas pocas clases de Java para controlar cosas básicas, y también para que el programa haga algunas de las cosas que no hace la vista por sí misma, por ejemplo, seleccionar ficheros para el <input type=”file”> de HTML. Resulta que no había un API para ello, pero dado que es imprescindible para casi cualquier aplicación HTML5, la gente analizó el código fuente del navegador estándar de Android y encontró la función que se llama cuando se selecciona el campo de subir fichero. La implementé tal cuál, adaptadas a las diferentes versiones de Android:

WbeChromeClient

Pero no funcionaba en KitKat, sólo en las versiones anterior, sin problemas. En KitKat ni se llaman esas funciones, no hace nada cuando se selecciona el campo.

Así fue que busqué, y veo que eliminaron esa interfaz, sin ninguna alternativa. Sólo dicen “no estaba documentada como oficial, y ya pensaremos una alternativa para futuras versiones de Android”. En los comentarios queda claro cómo afecta a tantas aplicaciones, sobre todos a las de PhoneGap, que están basadas completamente en HTML5: con KitKat es imposible subir ficheros de apps programadas en HTML5.

Sumado a eso, el propio Chrome de Google también falla para subir imágenes.

Es decir, miles de apps que dejarán de funcionar en Android KitKat, por decisiones [estúpidas] de eliminar la única interfaz posible para poder subir ficheros desde el “navegador empotrado” para apps, y por fallos increíbles en el navegador por defecto, Chrome.

La pregunta es: ¿están perjudicando así a aplicaciones en HTML5 por simple estupidez? ¿O es una estrategia para que se usen apps completamente nativas? No hay otra explicación, en cualquier caso, vaya ceguera y/o ineptitud enorme de los ingenieros que toman decisiones de desarrollo en Android. Para miles de :facepalm:.

PS: Mientras tanto, si tenéis Android KitKat y queréis subir fotos en Menéame o cualquier otro sitio, tenéis que usar Firefox u Opera Mini. Si habéis desarrollado una app que usa WebViews, estáis jodidos, porque no hay otra alternativa, al menos hasta que salga el GeckoView for Android, pero le falta todavía mucho tiempo :(

Nota: cómo hacer esos vídeos de la pantalla.

Para ser ingeniero no basta con ser ingeniero (y los programadores vamos justitos)

octubre 29, 2013 50 comentarios

Hace una hora iba conduciendo, llevaba mi teléfono en el bolsillo delantero derecho del pantalón, de golpe empieza a vibrar y sonar. Una vez, dos, tres, cuatro… parecía que llevaba se había desatado una batalla campal entre mis pantalones (y no eran mis tripas ni el Viagra). Me empiezo a asustar, debe ocurrir algo grave para que alguien conocido me esté escribiendo de esa manera, pensé que podía ser problemas de familia o Menéame (que ni aún así insisten tanto).

Detuve el coche en cuanto pude, saqué el teléfono, era el Hangouts (el reemplazo de Google Talk para Android) de Google. Me habían metido en un texto-vídeo hangout con muchas personas (no sé cuántas, pero eran muchas),  todos escribiendo a la vez. Después del susto que me pegué, ¡qué cabreo! Primero con el irresponsable (no sé quién fue, salí inmediatamente) que abrió una vídeo conferencia de muchas personas. Pero luego lo pensé mejor.

¿Cómo es posible que un programa me meta automáticamente en un sala de vídeo conferencia? No lo podía creer. Nunca había configurado nada así. Voy a mirar la configuración del Hangouts -que recuerdo que es un reemplazo del Gtalk de Android- y veo que Google, y sus programadores, decidieron que me iba aceptar automáticamente conversaciones de toda la gente que tengo en mis círculos de Google+, y ¡también a la que no!. También incluye a las que tengo en “My Stream” (gente a la que sólo sigo sus publicaciones en G+).

Alucinante.

Nunca quise eso (en GTalk sólo me podían escribir a los que tenía autorizado), me meten en una sala con mucha gente y a la que ni conozco por el apodo en internet, y en su momento tampoco agregué a gente en mis círculos -o en “My Stream”- para que me puedan abrir automáticamente vídeo conferencias. No sé quién es el genio al que se le ocurrió eso, pero obviamente lo han tenido que implementar programadores. Un burrada que difícilmente se deje pasar tan fácilmente en otras ingenierías.

Estamos rodeados de programas informáticos, no podemos hacer nada sin ellos, y con los móviles estamos “abiertos” al mundo las 24 horas.  Cualquier cosa que haga un ingeniero/programador tiene efectos reales sobre la gente. Te puede molestar y asustar cuando vas en coche, o despertarte cuando estás durmiendo, o molestarte en medio de una reunión o clase. Hasta hace poco teníamos razonablemente bien controlado, hay un botón u opción rápida para que las llamadas no suenen. Pero es bastante más complicado hacer que todas las aplicaciones no molesten (tampoco tiene sentido estar deshabilitando continuamente la capacidad de que te avise si tienes un Whatsapp o chat). Las cosas empeoran cuando te pueden meter sin preguntar en una sala de conferencia, por ejemplo.

Ortega y Gasset ya lo ha dicho “recuerda que para ser ingeniero no basta con ser ingeniero”.

Y tiene toda la razón, lo que hacemos tiene efectos reales sobre la gente, debemos pensar muy bien las causas de lo que implementamos, y corregir inmediatamente si causan problemas. Esta es la responsabilidad de cualquier ingeniero. Pero parece que la tendencia en informáticos es “lo implemento porque se puede”, sin pararse a pensar siquiera en lo básico de privacidad, respeto y no molestar innecesariamente.

Cada día me molesta más este pasotismo y “solucionismo” (como diría Eugeny Morozov) de mis colegas. Últimamente lo pienso cada vez que recibo el aviso, varias veces al día, del sistema de bloqueo de DoS de Menéame (en pocas semanas tenemos ya varios cientos de IPs que hacían “DoS” involuntarios). Bots descontrolados que podrían tirar sitios completos (y/o causar gastos innecesarios), programas que generan cientos de conexiones por segundo, a veces durante meses (como nos pasa con la IP 46.105.237.95 de un servidor de DreaMule). No se salva nadie, tenemos bloqueadas IPs de muchas empresas importantes, incluido proxies corporativos de Google, servidores de Automattic/Wordpress, buscadores e indexadores sociales, y hasta con el bot del buscador Bing de Microsoft [*].

Demasiadas molestias innecesarias causadas por programadores.  Lo de los bots descontrolados que hacen DoS y generan tanto tráfico inútil es de locos, además de las molestias individuales debe tener un coste económico enorme globalmente (¿y cuántos deben pensar que están recibiendo ataques DoS o DDoS cuando es simple irresponsabilidad de programadores). Pero que por defecto y sin preguntar un programa te meta en salas grupales de vídeo conferencia es ya indescriptible: imaginaros que estáis con roaming y no os dais cuenta que vuestro teléfono entró en una conferencia de estas… para daros una idea del daño económico real que puede causar.

No es tan difícil si se piensa un poco, sobre todo si los programas afectan a lo cotidiano de millones de personas, y lo molesto y el daño que pueden causar. Me enerva cada vez más esta incapacidad de pensar profesionalmente en las consecuencias de lo que hacemos. No llegamos ni a ingenieros.

—-
[*] En el caso de Microsoft tuve que darme de alta en Outlook.con, luego agregar los dominios de Menéame, y luego configurar la frecuencia de rastreo para evitar el problema, no ofrecían otra opción. En el caso de Google, envié un email a la dirección de abuse de registros de sus direcciones IP (en ARIN), me devolvió un email automático de que no leen emails, me envió a  un formulario de Google, después de varios intentos, no hubo forma de dejar el comentario. Al final me dijo que lo comente en un foro de Google (que ya ni me acuerdo), nadie me contestó, al final dejamos bloqueadas esas IPs de Google.

Monitorización y “self-healing” de AutoScaler/LoadBalancer de Amazon AWS

octubre 14, 2013 3 comentarios

Aunque está cada vez más fiable y con menos fallas, al principio los fallos de sincronización del AutoScaler con el ElasticLoadBalancer eran bastante frecuentes. Aún así todavía pueden ocurrir errores de programas que ponen la CPU de un servidor al 100%, o que se cuelgue algún servicio, o que deje de responder y el LoadBalancer lo elimine de su lista pero aún así sigan ejecutándose y consumiendo vuestro dinero.

El AutoScaler también tiene otro problema derivado de la extrema simplicidad de las reglas (del CloudWatch) para escalar hacia arriba y hacia abajo, especialmente esta última. Supongamos que para minimizar los costes queréis mantener las instancias entre un 70 y 85% de uso de CPU (así lo tenemos en Menéame), para ello usareis las métricas agregadas del grupo del auto escalador, pero en éste no hay forma de indicar una regla que como:

Cuando la carga con una instancia menos sea menor al 70%, decrementar una instancia

Por ello, en 2009 implementé un programa que monitoriza la carga de cada instancia del grupo que implementa este tipo de reglas. Además este programa monitoriza que todas las instancias estén dentro del margen (entre 70 y 85% de CPU), si alguna se desvía mucho toma otras decisiones. Por ejemplo: si una está cercana al 100% y la diferencia con la media de carga es superior al 50%, asume que hay un fallo en esa instancia y la terminará. Lo mismo hará que para instancias que estén muy cercanas al 0% de CPU mientras las demás están bastante por encima (lo típico de instancias “descolgadas” del LoadBalancer, por ejemplo por fallo de hardware o de algún servicio.

La verdad es que además de ahorrarnos bastante dinero manteniendo a todas las instancias “saludables” y dentro de los márgenes de CPU, me quitó dolores de cabeza. Salvo catástrofes y cosas muy raras, no tenía que preocuparme para nada del estado de los servidores web.

Pero nunca liberé ese código, cuando lo programé (hace casi cuatro años) las librerías de Python y Perl estaban bastante mal documentadas, así que lo hice en PHP porque pude entender las clases muy rápidamente. Pero el código era infumable, y ni quería liberarlo. Ahora que las librerías de Python, las boto, tienen muy buena calidad, me decidí a portar el código a Python. Ya está funcionando, y ahora lo libero y explico brevemente (haced con el código lo que queráis).

Precondiciones

Tenéis que tener instalado el paquete boto. Está probado con la versión 2.14, podéis usar el que trae vuestra distribución si es al mínimo la versión 2, o bien instalar la última con el pip (pip install -U boto). Ya está, eso es suficiente, en principio no necesitáis nada más de software.

Lo que hay que hacer es poner la configuración con vuestras claves en el /etc/boto.cfg o ~/boto. En nuestro caso, que tenemos los servidores en Dublin, la configuración es la siguiente:

[Credentials]
aws_access_key_id = XXXXXXXXXXXXXXXXXX
aws_secret_access_key = YYYYYYYYYYYYYYYYYYY

[Boto]
ec2_region_name = eu-west-1
ec2_region_endpoint = ec2.eu-west-1.amazonaws.com
autoscale_region_name = eu-west-1
autoscale_endpoint = autoscaling.eu-west-1.amazonaws.com
elb_region_name = eu-west-1
cloudwatch_region_endpoint = monitoring.eu-west-1.amazonaws.com

El código

Consiste de tres ficheros Python, los dos primeros obligatorios para hacer los controles, el tercero es para visualizar información de las instancias:

ec2_watchdata.py: Define la clase WatchData que implementa los métodos para leer los datos de AWS, manipular datos y hla lógica de controles.

ec2_watch.py: Es el script que ejecuto desde el cron cada minuto y hace lo que he explicado antes. Intenté que la lógica quede muy sencilla, y se puede cambiar todo por argumentos en la línea de comandos (con -h sale una pequeña ayuda). Permite especificar el nombre del grupo del autoescalador, si se quiere que envíe un email de las “emergencias”, para cambiar los límites de CPU, y otra para que grabe los resultados en JSON en la base de datos de Menéame como “annotation” (usado para poder visualizar el estado vía web). Lo podéis ejecutar como queráis, incluso con la opción -d o –dry si sólo queréis ver qué es lo que va a hacer, yo lo tengo en el cron para que se ejecute cada minuto, que es lo que recomiendo:

* * * * * meneame/scripts/ec2_watch.py -g web -a -m gallir@gmail.com &gt; $HOME/watch.log

ec_instances.py: Es un pequeño script (pero que lo usamos mucho) que también usa la clase WatchData, fudamentalmente para visualizar el estado de las instancias del grupo, y también permite cambiar manualmente el número de instancias deseadas (opción -i), o matar instancias (opción -k). La siguiente captura muestra varias ejecuciones de este script, con un par para cambiar el número de instancias deseadas:

ec2_instances.py

Opcional: Si miráis el código, cuando se indica la opción -a llama a la función store_annotation() en el fichero utils.py. Esta es la que guarda los datos en formato JSON en la base de datos de Menéame y que me permite controlar desde la web y mi móvil:

ec2_watch web

Ejemplos de fallos (provocados)

Primero hice que una instancia se ponga al 100% de CPU (con el comando “yes > /dev/null”), así simulaba el fallo de algún programa. ec2_watch lo detectó y primero incrementó el número de instancias de 2 a 3. Como es una “emergencia”, me avisó por email de lo que pasaba, y lo que hizo:

100% de CPU, incrementa una instancia

Minutos después esa instancia seguía al 100%, por lo que la mató:

100% CPU, la mata

La siguiente es otra prueba, pero a la inversa. Desconecté manualmente una instancia del LoadBalancer, así el uso de CPU se pondría casi a cero, lo detectó a los pocos minutos, la terminó y el autoescalador levantó otra instancia nueva (al no cambiar el número de instancias deseadas):

0% de CPU, mata la instancia

Fin

Espero que os sea útil. No aceptaré sugerencias, pero sí parches ;)

Detección de DoS y bloqueo automático de IPs con el LoadBalancer de Amazon AWS

septiembre 11, 2013 9 comentarios

En Menéame teníamos un problema no solucionado correctamente. Cada vez sufrimos más ataques DoS voluntarios e involuntarios (bots mal programados, como los de Dreamule) que en el mejor de los casos nos ocasionan gastos innecesarios (ancho de banda e instancias adicionales) y en el peor sobrecargan tanto que impiden el acceso normal a las páginas. A esto se suma un gran problema: las instancias webs (que están autoescaladas horizontalmente) están detrás del balanceador de carga de Amazon AWS (ELB, Elastic Load Balancer) y éste no permite gestionar, ni manual ni automáticamente, el bloqueo de direcciones IP.

Por ello había que buscar una solución que detecte los DoS a conexiones que se hacen a las diferentes instancias web, y que sea el propio software de Menéame que lo haga y rechace las conexiones lo más rápido posible, y consumiendo los mínimos recursos. Esto obligaba a que se registren en un sólo servidor todas las conexiones desde las diferentes instancias, se analice en él en “tiempo real” y se guarden los datos en la base de datos para que estén disponibles para todas las instancias. Éstas deberían ser capaces de rechazar esas conexiones consumiendo la cantidad mínima de recursos y ancho de banda (tanto en la de Internet, como a la base de datos, como para enviar los logs al servidor central).

Después de pensarlo durante meses, y de analizar decenas de alternativas, en unos pocos días se me ocurrió la solución “óptima”. Esto ocurrió después de un mes de vacaciones casi completamente desconectado. Es el valor que tiene el descanso, pero eso es otro tema.

Leer más…

La incapacidad de solucionar errores de nuestros estudiantes de informática

Uno de las asignaturas que enseño en la UIB es “Sistemas Operativos 2″, del segundo semestre del segundo curso de la ingeniería en informática. En esta asignatura enseñamos fundamentalmente gestión de memoria, de E/S y sistemas de ficheros.

La práctica consiste en el desarrollo en C desde cero de un sistema de ficheros basado en i-nodos. Quizás es la práctica más difícil y extensa (aunque son poco más de 2.000 líneas de código en C) que se hayan encontrado, pero tampoco es tan complicada. De hecho uno de los objetivos de la práctica es desmitificar la complejidad (de los conceptos fundamentales, el demonio está en los detalles) de los sistemas de ficheros. Pero nos encontramos con muchos problemas:

  • No saben relacionar lo aprendido en estructuras de datos. Por ejemplo, a esta alturas ya han visto árboles y el recorrido iterativo y recursivo en ellos, sin embargo les cuesta mucho hacerlo para la traducción de bloques lógicos a físicos (que es básicamente recorrer árboles de uno, dos o tres niveles).
  • Falta de práctica de programación. No están acostumbrados a desarrollar programas que sean mayores a un par de cientos de líneas, cuesta mucho que muestren código que “huela” bien, ni siquiera son capaces de sangrarlo correctamente, son incapaces de hacer el diseño del programa.
  • Desconocimiento de C, del compilador, y de su relación con la arquitectura de los ordenadores.

Para que estos problemas no bloqueen todo el desarrollo, el diseño se lo pasamos hecho al nivel de funciones con un programa semanal de qué funciones deben implementar y cómo probarlas. Además les pasamos el código de las funciones de recorrido de las estructuras más complejas.

Aún minimizando los problemas anteriores, el otro gran problema que tienen -y creo que el peor- es la incapacidad para analizar y corregir los errores del código. Aún en las partes más sencillas y obvias, es típico el diálogo:

- Profesor, el programa me falla.

- ¿Dónde está el fallo?

- No lo sé, da un segmentation fault.

- Pero ¿en qué función?.

- No lo sé, lo hace apenas lo ejecutamos.

- Pero ¿no has puesto ni print-efes para saber por donde se cuelga?

- ¿Dónde los pongo?

Es muy fustrante, les pego unos rapapolvos importantes. El ejemplo que doy a continuación es un caso real, del lunes pasado.

Como parte de las pruebas del sistema de fichero, tienen que desarrollar unos programas concurrentes que escriban una estructura de datos en posiciones aleatorias de un fichero. Luego otro programa tiene que recorrer secuencialmente ese fichero y detectar las escrituras, la forma fundamental es verificar que uno de los campos de la estructura sea igual al PID del proceso que escribió en ese fichero.

Un par de alumnos tenían problemas, después un un diálogo muy similar al anterior les indiqué que antes que les mire el código debían indicarme exactamente el sitio donde les daba problemas. Me mostraron el siguiente código:

struct record rec, rec2;
char pathname[256];
...
my_read(pathname, &rec, position, sizeof(rec));
while (rec.pid != pid) {
    position += sizeof(rec);
    my_read(pathname, &rec, position, sizeof(rec));
}
printf("Final del bucle\n");

Me dijeron:

- El problema es que nunca sale del bucle.

Es decir, según ellos, que nunca se cumplía la condición de que rec.pid sea igual a pid. Les indiqué el primer problema, el código no verificaba que se haya llegado al fin del fichero (es decir, que el resultado de my_read() sea mayor que cero). Si no salía de ese bucle, el my_read() debería estar generando errores y muy raro que no salga ningún error. En un momento de la conversación, y después de varios minutos verificando que el fichero estaba bien (el my_read() funciona correctamente), les digo:

- Esto no puede ser, debe haber otro error ¿habéis verificado que el nombre del fichero en pathname sea correcto?

- Ahora que lo dices, en una de las pruebas cuando habilitamos la impresión de errores nos dio “la ruta no existe”.

- ¡¡¡¡#$@!!!

Les pedí que impriman el valor de la variable pathname, y en vez de un /dir1/dir2/datos.dat salía /dir1dir2/datos.dat, todo por olvidare de una “/” en el sprintf() para el pathname.

Es decir, el problema no estaba ni el bucle, sino unas cuantas líneas más arriba de él, pero no fueron capaces de darse cuenta de ello. A los pocos minutos los mismos alumnos me dicen:

- Ahora nos da segmentation fault después del bucle, en estas instrucciones, y no sabemos por qué.

Voy a mirar esas líneas:

rec2.pid = rec.pid;
rec2.x = rec.x;
rec2.y = rec.y;
rec2.z = rec.z
...
/* más código complejo */

Era obvio que esas instrucciones, asignación de estructuras idénticas (y sin punteros involucrados) no podían generar un segmentation fault (además de la optimización es obvia y con menos código: memcpy(&rec2, &rec, sizeof(rec)).

- El error no está allí, ¿por qué decís que son esas líneas?

- Porque lo último que imprime es la salida del bucle.

- Pero ¿estáis seguro que es allí y no en el código de más abajo? ¿habéis puesto un printf para verificar?

- No.

- :facepalm: (y rapapolvos varios)

Estos casos son los que nos encontramos cada día en el laboratorio y tutorías, ayer mismo me pasó otro. Un grupo me dice:

- Profesor, el programa nos falla, ¿lo puede mirar?

- Pero ¿cuál es el fallo?

- No sabemos, nos da stack smashing detected

- Eso es porque trabajáis con algún puntero local y os estáis saliendo de los límites, por eso el error en la pila. ¿En qué función dónde da eso?

- Hummmm… creemos que en esta, pero aquí no hay nada raro.

Miro la función y detecto el error inmediatamente, les indico que es el “sprintf”.

char pathname[11];
sprintf(pathname, "%s/%s/pruebas.dat", dir1, dir2);

- Pero ¿por qué el error? si está bien.

- Porque la longitud del string generado es superior a 11.

- Pero si “pruebas.dat” es menor que 11.

- :facepalm: (y enésima explicación de strings, array de caracteres, y rapapolvos varios).

Este segundo ejemplo muestra el desinterés por aprender bien las herramientas que usan (el lenguaje C es muy sencillo), pero también hay una incapacidad de asumir que se cometen errores y de interpretar y analizar el código. Aunque es una técnica muy habitual en programación, son incapaces de reducir el espacio del problema para analizar el código (tan fácil como poner print-efes donde toca). A pesar de las horas que llevan de programación en más de un año y medio de carrera, no tienen siquiera la iniciativa de poner mensajes para así poder llegar exactamente a la instrucción que les está provocando el error. En pocas palabras, carecen de las habilidades básicas para hacer debugs de programas, que a su vez es una habilidad básica de los programadores.

No sé qué estamos haciendo mal en la universidad para que no tengan un dominio básico de debugging. O si el problema lo arrastran de instituto, por ejemplo, no tener iniciativa para resolver por sí solos los problemas, esperan -y casi exigen- que el profesor tenga capacidad adivinatorias superiores que les evite pensar a ellos. O que no hayan tomado conciencia que cualquier profesional necesita conocer las herramientas con las que trabaja.

Después de dos años de una carrera de ingeniería informática no podemos permitir que tengan esas carencias fundamentales, en temas tan básicos. Tenemos problemas de calado en la forma en que los formamos. O quizás deberíamos empezar a tomar no tan en serio lo del “seguimiento personal a los alumnos” del Plan Bolonia y dejar que se apañen solos, que parece que lo seguimos tratando como a niños desvalidos intelectualmente.

En cualquier caso, ya me desahogué, es frustrante. Y perdón a mis alumnos por los rapapolvos, pero es que es muy frustrante (y mejor que se los dé yo, antes que su primer jefecillo ;) ).

Relacionado (gracias): Why I never give straight answers.

Categorías:ciencia, desarrollo, UIB Etiquetas: ,

Por qué el núcleo Windows NT es peor que Linux: problemas sociales y de incentivos

En el artículo “I Contribute to the Windows Kernel. We Are Slower Than Other Operating Systems. Here Is Why.” se transcribe el comentario (luego eliminado) de un anónimo que se identificó y aportó pruebas como programador de Microsoft. En el comentario explica su opinión de por qué el núcleo Windows NT (el que se usa en todos los siguientes, 2000,XP, Vista, 7 y 8). Más allá de las anécdotas, y de que es una visión parcial y subjetiva, es muy interesante lo que desvela. En pocas palabras, la carencia de calidad y eficiencia son más un problema social más que técnico:

  • Falta de incentivos, o incentivos equivocados.
  • Dar mayor importancia a cumplir los planes establecidos sin desviaciones que aceptar cambios no planificados para mejorar la calidad del producto.
  • La carencia de programadores con experiencia, o el exceso de programadores recién graduados.

Es muy interesante la lectura, desvela los problemas de gestionar y programar sistemas complejos. Cualquier economista explicaría que hay que establecer los incentivos adecuados, sobre todo en entornos como la programación donde se trata de desarrollar sistemas tan complejos que tienen más componentes que el avión más grande del mundo y tantas formas de interacción -muchas órdenes de magnitud superior a cualquier sistema de componentes físicos- que escapan a nuestra capacidad de comprensión.

Ese incapacidad cognitiva de siquiera conocer la magnitud de la complejidad hace que sea imposible hacer un diseño inicial que tenga en cuenta todas las interacciones y casos. Por ello es imposible asegurar que no haya bugs y, por supuesto, que el sistema desarrollado sea eficiente. Eso requiere, tal como ya lo contaba Brooks en los ’70, el “mantenimiento” de los programas, que consiste en la mayor parte del ciclo de vida del software. Ese mantenimiento no consiste sólo en arreglar problemas, también en mejorar el código (para controlar mejor la creciente complejidad) y la eficiencia.

En el núcleo Linux es un buen ejemplo en ese sentido: se usaron las ideas y principios de modularidad de Unix, es software libre con todo a la vista del público (el código, y las discusiones técnicas), la gestión de Linus Torvalds (y los responsables de módulos) han creado una comunidad muy meritocrática (talk is cheap, show me the code) donde el respeto a los clientes (desarrolladores de programas a nivel usuario) es prioritaria, revisión de pares, se debate con dureza cada propuesta y cambio, se critica duro al que presenta propuestas malas, pero también se reconoce y halaga al que consigue mejorar funcionalidades ya establecidas y maduras.

Esa es una de las principales diferencias que se extraen del artículo.

En Microsoft [presuntamente] no funciona así, los responsables de módulos tienen más razones para rechazar mejoras que para introducirlas,  los Project Managers no ven con buenos ojos que haya desvíos del plan de trabajo, los grupos de testing no quieren saber nada de volver a probar y adaptar unidades de verificación. Es decir, no hay incentivos para mejorar las funcionalidades existentes y que no sean prioritarias en la empresa. En consecuencia, la eficiencia de sistemas con modelos de desarrollo más similares a Linux acaban siendo superior, sobre todo en las áreas y funcionalidades ya maduras.

Otro de los problemas que se menciona es el abandono de los programadores senior y la contratación de nuevos que acaban de salir de la universidad. Estos no son capaces de valorar la complejidad del sistema, ni de conocer por qué fueron tomadas las decisiones técnicas anteriores.

Este último punto es interesante, sobre todo en un gremio -y en un país- donde se valora poco la experiencia de los programadores. Salvo las empresas punteras en desarrollo de software equiparan los [excelentes] salarios de los programadores con la de los gestores (no es nada raro que un programador senior de Google cobre 150.000€). Ocurre en muchos países, pero sobre todo en España, tener 40 años y seguir programando parece más un fracaso profesional que el éxito de un programador apasionado.

Tampoco es culpa de las “empresas” o el “mercado”, desde la propia universidad solemos transmitir el mensaje equivocado:

Un ingeniero informático no programa, dirige proyectos

Ese mantra lo oí muchas veces y los alumnos lo escuchan frecuentemente en clases. El error es múltiple, por un lado transmitimos la idea que un ingeniero graduado sabe todo lo necesario, que no hace falta experiencia en programación, y que programar es de pringaos.

Además de lo mejorable que es nuestra educación, y como últimamente me está apasionando el tema de gestión de desarrollo de software, del comentario me han quedado algunas cosas más claras:

  • Los planes y metodologías son herramientas, no un fin en sí mismo, como terminan de creerse sus responsables y evangelistas.
  • Se deben crear incentivos, no sólo monetarios, para motivar a que los programadores desarrollen mejoras para cualquier parte del sistema. Esto implica, entre otras cosas, descontar un porcentaje de los recursos disponibles para implementar nuevas funcionalidades y reservarlos para mejora de la “calidad global”.
  • Valorar debidamente a los programadores experimentados, que empieza por reconocer -sobre todo entre nosotros mismos- las carencias inevitables de un recién graduado, y la rápida evolución de la ciencia y tecnologías informáticas.
  • Debemos empezar a esforzarnos en formar a profesionales cuyo objetivo sean jubilarse como programadores, no sólo un camino intermedio para lograr mejores salarios en otros puestos de gestión o dirección.
  • Sobre todo, reconocer que tenemos problemas cognitivos para visualizar mental y adecuadamente la enorme complejidad de los grandes sistemas informáticos.

Firefox OS, y expresiones de deseos más que realidades

enero 25, 2013 15 comentarios

Antonio Ortiz publicó en Xataka una entrevista a Carlos Domingo, CEO de Telefónica I+D. Por referencias, Carlos parece un ben profesional, pero critiqué en Twitter el lenguaje tan corporativo y vacío, en el sentido que se repite frases típicas, y no desvela nada interesante. A raíz de esos comentarios, tuve varias respuestas, repitiendo otra vez frases vacías y wishful thinking sobre lo que es Firefox OS, y su “innovación” en el mercado de móviles.

En primer lugar debo decir que me gusta mucho la creación de Firefox OS, por varios motivos.

Leer más…

Favorecer el disenso

noviembre 29, 2012 21 comentarios

Este apunte tiene dos partes. El objetivo original al empezar a escribir este artículo fue describir una pequeña novedad, y sus resultados, que pusimos en marcha en Menéame el 11 de noviembre. Pero antes quería hacer una breve introducción al problema que intentamos reducir -los sesgos-, pero no me salió nada breve. Lo siento, no lo puedo evitar, pero al menos os recomiendo unos libros de lectura imprescindible si están interesado en problemas similares.

Sesgos y mala información

Está estudiado, experimentado, demostrado y ampliamente reconocido en el ambiente académico y profesional de la psicología y psiquiatría el problema de los sesgos. Éste es inevitable, nos afecta a todos, cada minuto, cada opinión y cada percepción que tenemos del mundo. Es el que nos hace ignorar la información que no se ajusta a nuestros patrones y conocimiento adquirido previamente, el que selecciona aquella información que revalida lo que pensamos (sesgo de selección) e ignora aquello que lo contradice.

Leer más…

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

Únete a otros 461 seguidores