- En 2016, durante una semana se investigó un problema en el que la función de carga de fotos con ubicación de una app móvil en React Native fallaba solo en la beta de Android, sin poder reproducirse en Android local ni en iOS
- La beta de Android no daba feedback de error aunque fallara la carga de imágenes, y cada vez que se subía una nueva build a Play Store tomaba aproximadamente 1 hora, lo que ralentizaba la validación de hipótesis
- Al compararlo con casos de sistemas embebidos, hardware, química y veterinaria, queda claro que la depuración de software es mucho más rápida y tiene mayor observabilidad
- La causa real fue una diferencia de una sola letra: se había escrito el tipo MIME de la imagen como
"jpg", pero aunque la extensión del archivo fuera.jpg, el tipo MIME debía ser"jpeg" - Un entorno de desarrollo donde se pueden usar logs, observación en tiempo real, depuradores y experimentos iterativos a bajo costo es casi un gran privilegio en comparación con los ciclos de feedback de otras profesiones
La carga de fotos que fallaba solo en la beta de Android
- La función de geolocated photos de una app móvil en React Native parecía lista para lanzarse el lunes, pero después de distribuir la beta de Android las imágenes no se subían
- En las pruebas locales de Android y en la beta de iOS funcionaba correctamente, así que la causa del fallo no era evidente de inmediato
- Incluso al subir de nuevo una versión con mejor manejo de errores, la falla en la carga seguía ocurriendo sin feedback
- Subir una nueva iteración a Play Store tomaba aproximadamente 1 hora, y había que esperar a que la build se distribuyera mientras se preparaba la siguiente hipótesis
Ciclos de feedback más largos en otras profesiones
- Un ingeniero de sistemas embebidos vive la situación de desplegar una actualización de firmware en equipos remotos y luego descubrir que un nodo no responde
- Para identificar la causa, hay que recuperar el equipo y analizarlo
- En algunos casos, averiguar qué salió mal puede tomar meses
- Un ingeniero de hardware considera que un nuevo hardware desplegado de forma remota puede revelar defectos de diseño solo después de resistir varias estaciones del año
- Reciben equipos antiguos por correo para incorporar correcciones en la siguiente generación de productos
- Hubo un caso en el que se agregaron rejillas de ventilación para reducir el calor, pero los agujeros eran lo bastante grandes como para que las avispas hicieran nidos, convirtiéndose en un bug peor
- Aunque las pruebas de laboratorio son posibles, la validación final termina haciéndose en campo
Cómo se acepta el fracaso
- El CEO recuerda que, cuando era químico preparando su tesis doctoral, realizó un experimento con una gran beca para sustancias químicas costosas, pero semanas después el resultado parecía haber fallado por un error experimental
- No pudo averiguar qué había salido mal, y tampoco pudo responder qué haría diferente para no repetir el mismo error
- Aun así, recibió una segunda beca, y esa experiencia se convirtió en un ejemplo de liderazgo empático que ayuda a levantarse a quien fracasó
El caso veterinario mostró un riesgo más alto
- Una amiga veterinaria atendió a un perro viejo y enfermo, y recomendó a sus dueños hacerle una radiografía, pero se negaron por el costo
- Sin radiografía, lo mejor que podía hacer era palpar el abdomen del perro desde afuera, y sintió un objeto grande
- Lo que se retiró mediante cirugía fue una mazorca de maíz, pero al no tener radiografía no podía estar segura de que ese fuera todo el problema
- Al día siguiente el perro murió, y a diferencia de los problemas al lanzar una app móvil, en los fracasos de otras profesiones puede haber vidas reales en juego
Un bug de una letra y el privilegio de las herramientas de depuración
- El viernes por la mañana se detectó una discrepancia entre la documentación de Android y la base de código, y la causa del problema de toda la semana era un solo carácter
- El tipo MIME de la imagen estaba configurado como
"jpg", pero en realidad debía ser"jpeg", aunque el archivo estuviera guardado como.jpg - Los desarrolladores de software pueden observar en profundidad procesos complejos, monitorear el comportamiento en tiempo real, dejar logs y detener la ejecución con un depurador para examinarla
- Estas capacidades son baratas y rápidas, y permiten repetir experimentos varias veces al día con apenas unos clics
- Aunque el software puede ser tan importante e influyente como otras profesiones, los desarrolladores trabajan en un entorno en el que vale la pena agradecer las herramientas de depuración que tienen hoy
1 comentarios
Opiniones de Hacker News
Es una historia casi alegórica que muestra en qué se diferencia la ingeniería de software de otras profesiones o, dicho en broma, de las profesiones “reales”.
También me gusta una versión más corta e ingeniosa: un ingeniero de software, un ingeniero de hardware y un jefe de departamento iban a una reunión en Suiza cuando, en una empinada carretera de montaña, fallaron los frenos, el auto chocó contra el guardarraíl mientras bajaba y se detuvo milagrosamente.
El jefe de departamento propone hacer una reunión para definir visión, misión y objetivos, y resolver el problema central mediante mejora continua; el ingeniero de hardware propone desarmar y arreglar los frenos con una navaja suiza.
El ingeniero de software dice: “Antes de hacer nada, empujemos el auto de vuelta arriba y veamos si se reproduce de nuevo”.
Al mismo tiempo, la gran desventaja de la ingeniería de software también es que trabaja con abstracciones. Incluso los cimientos se mueven.
http://thecodelesscode.com/case/154
Tener esa capacidad no significa que el ingeniero de software sea ridículo o poco realista.
La ingeniería del espacio digital nos da capacidades de depuración que en el mundo físico serían casi milagrosas. Si quieres hacer 10 objetos idénticos y probarlos de 10 maneras distintas, literalmente es CTRL+C, CTRL+V. Me gustaría ver a un mecánico hacer eso.
Estoy realmente cansado de las quejas de que los ingenieros de software no son “ingenieros de verdad” y de que todo se arreglaría con más reuniones enormes de diseño previo y una planificación tremenda.
Otras ramas de la ingeniería trabajan así no porque sean mucho más profesionales que nosotros ni porque ese método sea mejor, sino porque no tienen otra opción. Después de terminar un hotel, no te das cuenta de que el techo debía ser 6 pulgadas más alto, demueles todo y lo reconstruyes.
Si pudieran ejecutar
ceilingHeight += 6, presionar “Rebuild”, que el hotel se reconstruyera y las pruebas unitarias automáticas verificaran incluso la accesibilidad, con un costo total de 2.82 dólares, por supuesto que también lo harían.Hay que dejar el complejo de inferioridad. Hacemos ingeniería con herramientas con las que los ingenieros civiles y mecánicos del mundo real ni siquiera podrían soñar, y es natural que eso cambie mucho el proceso.
Claro que a veces no aplicamos suficiente proceso al problema. Pero si crees que eso es un problema exclusivo de la programación, te recetaría ver unas horas de https://www.imdb.com/title/tt4788946/.
No es superioridad: si falta cualquiera de tus criterios, no estás haciendo ingeniería. Según mi experiencia, en la mayor parte del desarrollo de software faltan los cuatro. Eso no necesariamente es malo, pero la mayor parte del desarrollo de software no es ingeniería.
De ninguna manera significa que la ingeniería sea superior al desarrollo.
Es como la diferencia entre esculpir arcilla y esculpir mármol. Si te equivocas con la arcilla, la retocas rápido; si quitas del mármol una parte que no debías quitar, tienes que pedir un nuevo bloque de mármol.
Si llevas el método de escultura en mármol al mundo de la arcilla, solo te conviertes en un escultor de arcilla pésimo o, como mínimo, muy ineficiente.
Tampoco tiene mucho sentido competir para ver si la escultura en arcilla o en mármol es más valiosa. Ambas tienen su lugar en la sociedad.
ceilingHeight += 6.Hoy modelé e imprimí un objeto, y me di cuenta de que una parte habría quedado mejor si fuera alrededor de 1 mm más gruesa. Treinta segundos después, la versión 2 ya iba camino a la impresora.
Es realmente impresionante. Me cuesta esperar a que algo así se masifique tanto como las impresoras de papel.
https://www.youtube.com/watch?v=NPVT2lvMvOk
Varias veces a lo largo de mi carrera, algo fallaba pero de forma completamente silenciosa, y todos quedaban trabados. No había salida de error ni nada.
En muchos de esos casos, la causa era que una biblioteca de terceros de bajo nivel hacía
catch (e) {}. El primer caso que viví al principio fue una buena lección, y ahora no doy por sentado ningún error. Como mínimo, lo registro en logs.El software que haces hoy podría usarse dentro de 5 años, en un entorno que ni imaginas.
30 años después:
/* X systems I modul body I 14.09.1990 */void xxvcda(int *addr, int sizeof)Ni siquiera conocía la funcionalidad del lenguaje para levantar una nueva excepción a partir de la anterior y preservar el contexto del stack trace. Qué divertido. Al menos no es código de mi trabajo principal, aunque en el trabajo principal también hay diversiones propias.
DRF se tragaba el error de validación y solo devolvía un error genérico, así que no había ninguna pista; al final tuve que bajar yo mismo por las capas y agregar logging para descubrir qué estaba pasando.
Un amigo físico citaba a menudo la frase de Rutherford: “toda ciencia es física o coleccionismo de estampillas”
Lo que quería decir era que, a diferencia de las matemáticas o la informática, la física tiene una forma de validarse mediante la realidad física
Su campo eran los campos magnéticos extremos, y sus experimentos consistían en fabricar enormes bobinas de cobre, hacerles pasar tanta corriente como para que se derritieran, luego detonar explosivos alrededor de la bobina para que, durante un instante brevísimo, el campo magnético central fuera el más intenso jamás creado por la humanidad, mientras cobre líquido a miles de grados salpicaba por todas partes y todo el aparato quedaba destruido
En un entorno de trabajo así, un error o un mal cálculo podía significar que la gente muriera muy rápido y de forma horrible. Por eso no estaba de acuerdo cuando los estudiantes de doctorado en matemáticas, cuyo peor daño posible era tener polvo de tiza en el suéter, se llamaban a sí mismos científicos
Es decir, o intenta entender la dinámica del objeto de estudio, o se limita a reunir datos interesantes y ponerles nombre a los objetos de interés
Para quienes tengan interés en una carrera como supervillano pero no sepan por dónde empezar: así se fabrica un EMP de verdad
[1] https://en.m.wikipedia.org/wiki/Explosively_pumped_flux_comp...
Después de algo así, siempre desearía que hubiera acciones correctivas aguas arriba. Con un logging y reportes de errores adecuados, no habría tomado una semana arreglarlo
La biblioteca que recibió el tipo MIME incorrecto
image/jpgdebería haber lanzado una excepción, crasheado o, como mínimo, dejado un log bien visible. Me pregunto si el autor original reportó un bug a esa biblioteca¿Tenía acceso para comprobar o descartar si las subidas de imágenes realmente llegaban al servidor? ¿Por qué en el entorno de pruebas sí se subían, pero en la versión release de la app no? ¿Qué tenía de distinto el entorno de pruebas?
En teoría, Shawn debería haber tenido suficiente acceso, ya fuera operando directamente el servidor o pidiendo ayuda a alguien que pudiera diagnosticar por qué las subidas fallaban en silencio, como para responder bastante rápido “si la subida tiene éxito, ¿por qué no se ve?”
En mi opinión, más que “el tipo MIME de la imagen era
jpgy debía serjpeg”, la lección mucho más importante es por qué funcionaba en pruebas y no en producción. Más que el bug en sí, importa por qué el entorno hizo que fuera difícil encontrarloEn mi caso, una app de escritorio funcionaba muy mal, pero el error no quedaba registrado en los logs. Solo días después descubrí que se habían agotado los file handles y que log4net tampoco puede escribir logs si no puede obtener un file handle. La solución de revertir un pequeño cambio con bug era sencilla, pero la corrección real fue personalizar log4net para que mantuviera siempre abierto el archivo de log. Así, aunque la app agotara los file handles, los errores quedarían registrados
El silencio no es el objetivo. Demasiados desarrolladores piensan que el objetivo es el silencio, pero el objetivo real es la corrección. Si no hay errores, debería ser silencioso; pero si hay un error que afecta al usuario, debería haber una gran caja roja de advertencia
Creo que los desarrolladores deberían aprender a apreciar los mensajes de error. Un mensaje de error bien escrito revela la causa rápidamente y ahorra muchísimo tiempo a todos
Si este desarrollador aprendió a mostrar mensajes de error con más frecuencia en el futuro, es un resultado muy bueno
Me recuerda a un excompañero que solía decir: “no es como si estuviéramos construyendo un sistema de control de tráfico aéreo”. Quería decir que, aunque nos equivocáramos, no había vidas en juego
En ese momento estábamos haciendo juegos, pero la frase también aplicaba a casi todas las apps CRUD que he escrito
Por otro lado, suelo preguntarles a otros líderes técnicos senior, especialmente Directors, VP y CTO: “¿cuál fue el error más caro que cometiste?”. Si eres ingeniero junior, conviene hacerlo alguna vez
Muchos líderes técnicos de alto nivel pueden contar historias de 100 mil a 1 millón de dólares. Incluso vi a alguien desperdiciar varios millones de dólares en un proyecto y recibir un ascenso justo después. Es importante entender por qué eso puede pasar y, más aún, por qué incluso puede ser algo bueno
La frustración por un juego con bugs puede derivar en violencia vial o discusiones a gritos en la vida real. Ha habido personas que se suicidaron porque una computadora les envió una factura incorrecta. También hubo empresas que quebraron porque un software perdió datos valiosos
Algunas personas han sido asesinadas por apps de redes sociales que parecían triviales, y en Twitter se han organizado incitaciones a masacres. También hubo personas acosadas y agredidas por información filtrada por Pokemon Go
El software tiene poder real. Si no fuera así, no habría motivo para escribir software
He trabajado en software que podía perder datos valiosos, y ahora trabajo en software que, si falla, puede causar inundaciones
Hay que tener un poco más de orgullo por el propio trabajo
Como ingeniero de software, disfrutaba bastante depurar. Porque me permitía usar habilidades y formas de pensar distintas a las de diseñar e implementar
Claro, eso no significa que depurar no sea estresante. Cuando desarrollábamos software para el conmutador telefónico 5ESS de AT&T, teníamos una demo, y en el laboratorio de pruebas solo había una línea telefónica configurada para nuestra función
Por más que lo intentábamos, el software no funcionaba, y yo, convencido de que el software sí estaba bien, me estresaba revisando todo lo posible. Al final le pedí al técnico del laboratorio que revisara la línea, y resultó que la única línea configurada estaba desconectada por alguna razón. Era un estúpido problema de hardware
Depurar sistemas distribuidos en la nube es exponencialmente más horrible que cuando puedes levantar todos los servicios en local, y aun ese sistema distribuido local es mucho peor que poder depurar el problema dentro de un solo programa
Un depurador real también mejora muchísimo la depuración. Nunca entendí a quienes se empeñan en usar solo depuración con
printfo solo un depurador real. Usar ambos da una ventaja enorme. Un buen tracing también merece destacarse aquí porque, cuando es posible, es mucho mejor que depurar conprintfAl principio de mi carrera en programación le cargaba mucha emoción innecesaria a ese estado de no saber por qué ocurría algo, pero poco a poco fui aceptando el ciclo de “un momento, ¿por qué pasa esto? No sé… ah, espera… vaya, ¡tiene mucho sentido que esto no funcionara!”, y también interioricé que al llegar al final se siente bien
Ahora, el estado de no saber en sí solo puede arruinarse por las expectativas y acciones de otras personas. Con el tiempo aprendí que hay que gestionar con mucha firmeza la elección de lenguajes, las decisiones de arquitectura, etc., para que este proceso sea fácil y rápido
En este punto de mi carrera, es mucho más fácil convencer de antemano de que AWS Lambda es una mala elección en términos de rendimiento, costo total, posibilidad de depuración y velocidad de desarrollo, que convencer después de que hay buenas razones para que “arreglar ese único problema” esté tardando tanto
Me reí con lo del final. Justo ayer resolví un problema que llevaba 3 años atormentándonos en la empresa, y en nuestro caso la causa era la letra A
Durante los últimos 3 años, alguien había estado haciendo una corrección manual para meter y sacar datos, y eso se convirtió en parte de su trabajo. Incluso tenía en el calendario una cita recurrente para hacer la limpieza periódica. Millones de clientes dependían de esta única persona para que a sus líneas móviles se les aplicara el plan de datos correcto
Pueden imaginar el caos que se generaba si se le olvidaba o se iba de vacaciones
Al final, la causa era
if $line->status == STATUS_ACTIVE: uno eraActivey el otroactive. Ningún perro salió lastimado, pero durante años desapareció una cantidad incalculable de dineroEsa pobre persona ya no es indispensable. Lo digo medio en broma. El software sirve para hacer el trabajo más eficiente, pero también conviene observar las motivaciones humanas
En particular, sufrí mucho al llenar campos HL7 en una Mac. Parece que el carácter
’ingresado desde el teclado de Mac no era compatible con todas las versiones de HL7, o no encajaba con el destino al que se le pasaba HL7Es un recuerdo viejo, pero la diferencia entre palabras como
o’clockyo′clockrompía la distribución de reportes de radiología. Siguió así durante años antes de que lo detectaranHN está mostrando
’de forma distinta a como lo escribí, pero sigue siendo el mismo carácter. Es bastante gracioso, porque la mitad del problema era que al depurar no se veía la diferenciaSTATUS_ACTIVEestaba mal definido en alguna parte del código?Siempre existe el riesgo de que alguien “amablemente” corrija el typo
refererdeHttpHeader::REFERRERareferrer. Pero ese typo quedó inmortalizado en el estándar HTTP, así que hacerlo rompería el software por completo. Responsabilidad de Phillip Hallam-Baker en la época del CERNLa anécdota del nido de avispas me resulta muy familiar
El arrendador de nuestro edificio de oficinas instaló afuera una interfaz táctil para llamar a las distintas recepciones y permitirles abrir la puerta. Lo hizo porque no había recepcionista con vista a la puerta
El dispositivo aguantó 6 meses antes de empezar a fallar de forma grave. La causa fue que la interfaz, que en la práctica era una tablet Android grande y negra, estaba instalada en el lado este del edificio
Para mediados de la primavera, recibía suficiente sol todos los días como para sobrecalentarse, y eso dañó la electrónica táctil y parte del hardware de la pantalla
En el tipo de software que yo hago no tengo que preocuparme por la carga térmica
La compañía ferroviaria publicó en Twitter: “Hubo una fuerte congestión en la zona que pasa por Lewisham debido a problemas de salida causados por la luz solar intensa”
También dijo que el sol bajo de invierno iluminaba los monitores de salida y hacía que los maquinistas no pudieran verlos
Es divertido el mensaje “Por fin lo resolví. Era por la letra ‘E’”
Los bugs más simples y pequeños suelen ser los más difíciles de encontrar. Esta mañana también perdí una o dos horas buscando un error off-by-one
La causa era un
index + 1que olvidé cambiar durante una refactorización