69 puntos por xguru 2024-07-15 | 6 comentarios | Compartir por WhatsApp

Si sigues disparándote en el pie, arregla la pistola

  • En los equipos suele haber errores recurrentes sobre el sistema, pero muchas veces no se piensa en cómo reducirlos
  • En esos casos, lo importante es mejorar el sistema para disminuir los errores
  • Experiencia:
    • Al desarrollar en iOS con CoreData, las actualizaciones de la UI solo pueden hacerse en el hilo principal
    • Los callbacks de suscripción ocurrían tanto en el hilo principal como en segundo plano, y eso causaba problemas con frecuencia
    • Los miembros antiguos del equipo ya lo sabían y lo manejaban bien, pero en las revisiones de gente nueva esto salía seguido
    • Cuando ocurría un error, se revisaba el reporte de crash y se agregaba DispatchQueue.main.async
    • Para resolverlo, se actualizó la capa de suscripción para que llamara a los suscriptores en el hilo principal. Tomó exactamente 10 minutos.
    • Se eliminó toda una clase de crashes y un poco de carga mental
  • Cualquiera que lo pensara unos minutos habría visto que era un problema evidente
  • Pero como nunca hay un momento natural para resolver este tipo de cosas, duran extrañamente mucho tiempo
    • Es decir, si llevas mucho tiempo en un equipo, este tipo de problemas se vuelve parte del fondo
  • Hace falta un cambio de mentalidad
    • De vez en cuando hay que recordarse que estos problemas pueden resolverse para hacerte la vida más fácil a ti y al equipo

Encontrar el equilibrio entre calidad y velocidad

  • Siempre existe un trade-off entre la velocidad de implementación y la confianza en la exactitud
    • Hay que preguntarse qué tan aceptable es lanzar un bug en la situación actual
    • Si la respuesta no afecta tu forma de trabajar, entonces estás siendo demasiado rígido
  • En mi primer trabajo, cuando hacía proyectos de procesamiento de datos, había un buen sistema para reprocesar datos retroactivamente
    • El impacto de lanzar un bug era muy pequeño y, en ese entorno, podías apoyarte hasta cierto punto en los guardrails y moverte más rápido
    • Tener 100% de cobertura de tests o un proceso extensivo de QA solo ralentizaba el desarrollo
  • En mi segundo trabajo, el producto era usado por decenas de millones de personas y manejaba datos financieros de alto valor e información personal identificable, así que los bugs eran críticos
    • Incluso un bug pequeño requería un análisis posterior
    • Las funciones se lanzaban muy lentamente, pero creo que ese año no saqué ni un solo bug
  • En la mayoría de los casos, no estás en una situación como la de esa segunda empresa
    • Cuando los bugs no son críticos (por ejemplo, en el 99% de las web apps), es mejor lanzar rápido y corregir rápido
    • Así puedes avanzar más que intentando lanzar una función perfecta desde el inicio

El tiempo dedicado a afilar la sierra casi siempre vale la pena

  • Es importante dominar tus herramientas
  • Debes poder escribir código rápido, conocer los atajos clave y manejar bien el sistema operativo y la shell
    • Vas a renombrar cosas, ir a definiciones de tipos, buscar referencias, etc.
    • Deberías conocer todos los atajos importantes de tu editor y poder teclear con confianza y rapidez
    • También es importante usar eficazmente las herramientas de desarrollo del navegador
  • Elegir bien tus herramientas y usarlas con soltura es una gran ventaja
  • Una de las mayores green flags que veo en ingenieros nuevos es el interés por elegir herramientas y usarlas con maestría

Si no puedes explicar una dificultad de forma simple, probablemente sea complejidad accidental, y vale la pena resolverla

  • Mi manager favorito tenía la costumbre de presionarme cada vez que yo decía que algo era difícil de implementar
    • Muchas veces respondía con cosas como: "¿No es solo enviar X al hacer Y?" o "¿No es algo como Z que hicimos hace unos meses?"
    • Era una objeción de muy alto nivel, no al nivel real de funciones y clases que yo estaba tratando de explicar
  • La visión habitual es que este tipo de simplificación por parte de un manager solo resulta molesta
  • Pero, sorprendentemente, en un porcentaje alto de los casos me di cuenta de que gran parte de la complejidad que estaba explicando era complejidad accidental
  • Y que, de hecho, resolviendo eso primero, el problema sí podía volverse tan trivial como decía mi manager
  • Este tipo de enfoque tiende a facilitar cambios futuros

Intenta resolver los bugs un nivel más abajo

  • En vez de corregir un bug solo en la superficie, es importante encontrar y resolver la causa raíz
  • Supón que hay un componente de React en el dashboard que maneja un objeto User tomado del estado del usuario actualmente autenticado
    • En Sentry aparece un reporte de bug diciendo que user era null durante el render
      • Puedes agregar rápido if (!user) return null
    • O investigar un poco más y descubrir que la función de logout hace dos actualizaciones de estado separadas
      • La primera pone al usuario en null y la segunda redirige a la página principal
    • Si inviertes el orden de esas dos cosas, ningún componente volverá a sufrir ese bug
    • Porque dentro del dashboard el objeto de usuario nunca debería ser null
  • Si sigues haciendo el primer tipo de arreglos, todo se volverá un desastre,
    pero si sigues haciendo el segundo tipo, terminarás con un sistema limpio y un entendimiento profundo de las invariantes

No subestimes el valor de escarbar en el historial para investigar bugs

  • Yo era bastante bueno depurando problemas extraños con herramientas comunes como println y el debugger
  • Por eso no solía mirar mucho git para entender la historia de un bug, pero en algunos casos eso es muy importante
  • Hace poco parecía que en el servidor había una fuga constante de memoria, y lo terminaban matando y reiniciando por OOM
    • Ya se habían descartado todas las causas plausibles y no podía reproducirse localmente
    • Se sentía como lanzar dardos con los ojos vendados
    • Al revisar el historial de commits, vi que había empezado después de agregar soporte para pagos de Play Store
    • Como eran solo unas cuantas requests HTTP, jamás lo habría buscado ahí
    • Resultó que había caído en un loop infinito al obtener el access token después de que expirara el primero
    • Puede que cada request solo agregara alrededor de 1kB en memoria, pero si reintentas cada 10ms desde varios hilos, se acumula rápido
    • Normalmente algo así habría causado un stack overflow, pero como estaba usando recursión asíncrona en Rust, no ocurrió
    • Nunca se me habría ocurrido, pero al mirar un fragmento específico de código claramente relacionado con el problema, de repente se me ocurrió la teoría
  • No hay una regla sobre cuándo usar este enfoque
    • Se basa en intuición: un tipo distinto de "¿eh?" al leer un reporte de bug puede detonar esta clase de investigación
    • Con el tiempo puedes desarrollar esa intuición, pero basta con saber que a veces esto tiene muchísimo valor
  • Si el problema encaja, prueba git bisect
    • Cuando tienes un commit que sabes que está mal y otro que sabes que está bien

El mal código da retroalimentación; el código perfecto no. Equivócate del lado de escribir código malo

  • Es muy fácil escribir código terrible
  • Pero también es muy fácil escribir código que siga absolutamente todas las mejores prácticas
    • Tendría que pasar por tests unitarios, de integración, fuzz y mutación, y una startup se quedaría sin dinero antes de terminar
  • Gran parte de programar consiste en encontrar el equilibrio
  • Si te equivocas del lado de escribir código rápido...
    • A veces vas a sufrir por deuda técnica mala
    • Vas a aprender que "hay que agregar excelentes tests al procesamiento de datos"
      • Porque muchas veces después ya no se puede corregir
    • También vas a aprender que "hay que pensar muy bien el diseño de las tablas"
      • Porque cambiarlas sin downtime puede ser muy difícil
  • Si te equivocas del lado de escribir código perfecto...
    • No recibes ninguna retroalimentación
    • Todo toma universalmente más tiempo
    • No sabes dónde estás invirtiendo bien el tiempo ni dónde lo estás desperdiciando
    • Los mecanismos de feedback son esenciales para aprender, pero así no obtienes ninguno
  • Aclarando qué significa código "malo"
    • No significa: "No recordaba la sintaxis para crear un hashmap, así que usé dos veces el loop interno"
    • Significa cosas como:
      • En lugar de reescribir la recolección de datos para hacer imposible representar cierto estado, agregas algunas assertions sobre invariantes en unos cuantos puntos clave
      • Como el modelo del servidor es exactamente igual al DTO que vas a escribir, simplemente lo serializas. En vez de escribir todo el boilerplate, puedes crear el DTO después si hace falta
      • Te saltas escribir tests para estos componentes porque son triviales y aunque tengan bugs no sería grave

Haz que depurar sea fácil

  • Con los años he ido aprendiendo muchos pequeños trucos para hacer que el software sea más fácil de depurar
    • Si no haces un esfuerzo por facilitar la depuración, conforme el software se vuelve más complejo, terminarás gastando muchísimo tiempo depurando cada issue
    • Vas a empezar a temer hacer cambios, porque entender unos cuantos bugs nuevos podría tomarte una semana
  • Pon atención al tiempo que se va en configuración, reproducción y limpieza posterior durante la depuración
    • Si es más del 50%, deberías buscar cómo hacerlo más fácil, aunque esta vez tome un poco más
    • Si todo lo demás es igual, corregir bugs debería volverse más fácil con el tiempo

Cuando trabajes en equipo, pregunta siempre

  • Hay un espectro que va desde "intentar resolver todo por tu cuenta" hasta "molestar a tus colegas con preguntas triviales"
    • Creo que la mayoría de quienes empiezan su carrera están demasiado inclinados hacia lo primero
  • Siempre hay cerca alguien que lleva más tiempo en el codebase, o sabe mucho más de la tecnología X, o conoce mejor el producto, o simplemente tiene más experiencia como ingeniero
  • Durante tus primeros 6 meses en cualquier lugar, muchas veces vas a perder más de una hora tratando de entender algo que podrías haber resuelto en unos minutos con una respuesta
  • Haz preguntas. El único caso en que hacer una pregunta realmente molesta a alguien es cuando es obvio que tú mismo habrías podido encontrar la respuesta en unos minutos

El ciclo de despliegue importa muchísimo. Hay que pensar con cuidado cómo desplegar rápido y con frecuencia

  • Las startups tienen runway limitado y los proyectos tienen deadlines
  • Cuando dejas tu trabajo y te independizas, tus ahorros solo te van a durar unos cuantos meses
  • Idealmente, la velocidad del proyecto aumenta de forma compuesta con el tiempo, hasta que terminas lanzando features más rápido de lo que imaginabas
  • Para desplegar rápido hacen falta muchas cosas
    • Un sistema que no sea propenso a bugs
    • Tiempos de turnaround rápidos entre equipos
    • La voluntad de recortar el 10% de una feature nueva (la parte que consumiría el 50% del tiempo de ingeniería) y la claridad para identificar qué partes son esas
    • Patrones consistentes y reutilizables que puedas combinar para nuevas pantallas/features/endpoints
    • Despliegues rápidos y sencillos
    • Procesos que no ralenticen (tests inestables, CI lenta, linters fastidiosos, revisiones de PR lentas, JIRA tratado como religión, etc.)
    • Y un millón de cosas más
  • Desplegar lento debería requerir un análisis posterior igual que tumbar producción
    • Nuestra industria no funciona así, pero eso no significa que no puedas seguir personalmente la estrella polar de desplegar rápido

6 comentarios

 
carnoxen 2024-07-19

"dispararse en el pie" = ¿significa algo así como meterse en un problema por uno mismo?

 
yunghn 2024-07-25

Si algo sale mal por un código defectuoso (una pistola rota) y eso causa un problema (dispararte en el pie), la idea es que arregles la pistola.

 
gargoyle92 2024-07-16

Qué impacto, es como si hubieran sacado tal cual lo que tengo en la cabeza, wow..

 
cbbatte 2024-07-16

¡Lo leí muy bien!!

 
hannah0su 2024-07-15

Lo leí con gusto.

 
arfwene 2024-07-15

No soy desarrollador, pero hay muchas partes con las que me identifico.