¿Por qué las interrupciones son frustrantes para los programadores?

Imagina que tu atención es como una torre de cartas y las interrupciones son como tirarlas abajo de un golpe. Si tu productividad depende de tener una torre de cartas, ¿no te sentirías frustrado al verla caer?.

Escuché esta analogía de un amigo mío hace varios años, y la estuve repitiendo cada vez que quería explicar el concepto de concentración de forma visual, así que contacté a mi amigo para saber si él tenía la fuente de esa analogía:

Si alguna vez intentó construir una torre de cartas seguramente sabrá todo el tiempo que lleva lograr el balance de las cartas y controlar el entorno para que no se caigan. Es frustrante cuando tus amigos cierran una puerta y esto causa una brisa que de alguna forma encuentra la forma de alcanzar tu torre de cartas.

Y al igual que las torres de cartas, el foco de un programador se construye de forma cuidadosa, combinando varios elementos juntos y puede ser destruida muy fácilmente.

Enfocar el flujo de combustible

Programar requiere a un gran esfuerzo de pensamiento. Algunos días son mejores que otros, pero el objetivo de cada día es alcanzar un estado de concentración absoluto.

También llamado “La zona” o “flow”, el foco es el estado mental en el que el programador está inmerso en una concentración absoluta, involucrado completamente, y entusiasmado en el proceso de codificar. Esta concentración no es un un concepto exclusivo de la programación de computadoras, pero los programadores están muy familiarizados con ella.

“Cuando estoy enfocado, quiero mantenerme en ese estado todo lo que pueda. No es magia ni nada de eso, pero es entusiasmante estar completamente inmerso en mi trabajo”.

Las personas tienen diferentes opiniones sobre el tema, pero todos coinciden en que en ese momento de foco es cuando se produce el trabajo de mejor calidad. Dale una mirada a algunos de los resultados más relevantes de una búsqueda en google sobre “cómo alcanzar el foco en software” y encontrarás: La importancia del foco en el desarrollo de Software, Cómo lograr un estado de concentración y Logrando Foco en las metodologías ágiles

Estos artículos describen a la concentración profunda como el periodo de tiempo en que alcanzas tu mejor trabajo. En mi experiencia, este no es el momento donde hago mi mejor trabajo, sino el único momento en donde puedo trabajar.

Construyendo una torre de foco

Conseguir este estado de concentración requiere esfuerzo y es un asunto complicado. Los factores que pueden influir van en un rango desde cuanto pude dormir, si el trabajo es lo suficientemente desafiante, mi salario, la visión de la empresa, si me agradan mis compañeros de trabajo o no.

Para simplificar un poco las cosas, he decidido reducirlo al proceso de recopilar contexto (o información) de un bug en una porción de código. Recopilar contexto mental para resolver un bug es un proceso tedioso. Intentaré ilustrarlo mencionando lo que suele suceder en una sesión de programación típica: Todo comienza con la construcción de una Torre de Concentración.

La torre tiene un cimiento, una capa intermedia y una cima. Una torre de tres niveles simple tiene 15 cartas. 8 cartas para la base, 5 cartas para el medio y 2 cartas para la cima. He llamado a estas capas “El porqué”, “concesiones” y “verificación” respectivamente.

Cada una de esas cartas es el contexto para la tarea que estoy realizando. He construido esos niveles de una carta a la vez, colocando cuidadosamente cada una de esas cartas sobre otras.

La Base: Entender el porqué del código

El nivel inferior, que sirve de cimiento, representa la búsqueda del “porque”, o la intención inicial del código. Esta es la parte del contexto más difícil de recolectar en mi opinión. Porque para hacer un cambio en el código con confianza necesito descubrir la intención inicial que está involucrada en ese código.

¿Y cómo se siente buscar la intención en el código?, veamos esta pieza de código:

Es evidente que el autor original descubrió cosas mientras escribía este código. Lo digo porque puso un montón de comentarios. Aquí es donde comienzo a preguntarme, ¿por qué puso tanto esfuerzo en explicar todo eso?.

La sorpresa llega cuando luego de indagar en este código descubro que forma parte de una pieza más grande, y que cualquier cambio que se haga ahí podría tener efectos colaterales no deseados. Este código es invocado desde un spaguetti de métodos que a su vez están dentro de sentencias de repetición.

Si estoy investigando un bug relacionado con este código, tengo que digerir cada una de esas líneas. Nombres de variables como reader o n, la diferencia sutil entre cada una de las sentencias if, etc. A medida que avanzo tengo que agregar una carta en mi torre por cada una de estas cosas.

Debo explorar los tests, los mensajes asociados a commits o incluso hacerle consultas por chat al autor (si aún sigue trabajando en esta empresa) para tratar de entender que trató de hacer. Encontrar la intención inicial es más o menos como ser un detective en un misterio de crimen.

Aunque hay una pequeña diferencia en este ejemplo, ese código que mencioné tiene comentarios. Por lo general suelo encontrarme con código muy similar al de arriba, pero que no tiene comentarios y con comentarios en los commits poco útiles. Generalmente no tengo otra opción que leer todo el código para entenderlo en toda su gloria anidada.

Para empeorar las cosas, el código suele tener test muy superficiales que me ponen en una situación muy incómoda: Si lo cambio, no tendré idea si estoy colocando una mina explosiva que podría explotar en el peor momento posible.

¿Debo dedicar una gran cantidad de tiempo a mejorar los tests o solo debería cruzar los dedos?, ¿tal vez hacer una pocas pruebas y pasar a otra cosa?

Cada cosa que descubro me hace añadir más cartas a mi torre de concentración. Si el código es ligeramente más complicado, tendré que construir una torre de 4 niveles o incluso 5.

La capa del medio: Concesiones y parches

El siguiente nivel consiste en determinar qué se necesita cambiar o qué está roto y cómo se tiene que reparar.

Continuando con el ejemplo de reparar un bug, comencé a indagar colocando mensajes que se imprimen en pantalla para determinar qué partes del código se ejecutan y cuáles no. Un mensaje que se emite en la pantalla puede ser interpretado como evidencia o un registro del comportamiento de un programa (es como la sangre en la alfombra en el caso de un detective). A veces, un mensaje muestra la imagen completa, pero a veces es una pieza incompleta a la que le falta información.

Lo que hago es tratar de reproducir el bug. Agrego más mensajes en pantalla para trazar el problema o uso una herramienta de depuración (una manera de recorrer el programa en tiempo de ejecución paso a paso). También agrego algunos comentarios sobre cómo se ejecuta. Tal vez cambio una o dos variables para ver cómo impacta en el comportamiento del programa. Generalmente haciendo estas cosas suelo acortar o aislar la sección de código que está dando problemas.

Si tengo suerte, puedo lograr reproducir el problema de tal forma que es suficiente para encontrar una solución, pero otras veces, necesito hacer una lista de concesiones o parches para lidiar con el problema. Los problemas más difíciles se pueden resolver en varios niveles, pero generalmente se reducen a dos opciones:

  1. Un arreglo real (que toma un montón de tiempo)
  2. Un parche (que podría romperse después, pero es realmente rápido de hacer)

Lo más frecuente es que en el negocio se elija la opción de aplicar un parche y resolver el problema de la forma más rápida. De modo que la torre de cartas se vuelve más grande y esto hace más delicado mantenerla en equilibrio.

La cima - Probar y verificar

La capa final consiste en asegurarse de que funciona en producción. Producción es solo una palabra bonita para identificar la parte del software que efectivamente ve el cliente. La mejor práctica es agregar algunos tests, pero muchas veces solamente se corre el código en la computadora del desarrollador para validar que funciona. La parte importante es continuar en esto mientras el contacto está fresco en tu cabeza y las capas de la torre siguen de pie. En este punto, sabes la mayor parte del código y cómo repararlo si algo sale mal.

Interrupciones - Los peligros del deterioro de contexto

En un mundo perfecto, tendría la posibilidad de moverme por la base de la torre, subir al siguiente nivel y luego a la cima sin interrupciones. Pero la realidad es que mi día está partido al medio entre interrupciones y reuniones.

Charity Majors, CTO de Honeycomb, lo describe mucho mejor de esta manera:

Si logras tener un circuito de respuesta inmediata, lo que obtienes es que la intención inicial se queda fresca en tu cabeza, sabes exactamente qué estás intentando hacer: el motivo, todas las concesiones que has hecho, los nombres de las variables y todo lo demás. Pero todo eso se desmorona inmediatamente en el momento que cambias tu atención a otra cosa.

- Extracto de The New Faces of Continuous Improvement de Charity Majors.

Imagina que he invertido una serie de horas construyendo mi torre de concentración y luego una ráfaga de viento la hace caer, como una interrupción. Me llaman para ayudar a resolver el problema X y es muy “urgente” (En Slack, usar el texto @channel es una forma de notificarle a todos y suele implicar urgencia).

@channel solo quería hacerles saber que cambiamos la reunión dentro de dos semanas al viernes. Esta actualización está en sus calendarios.

@channel alguien escribió diciendo que le gustaría probar X, ¿eso es posible?

Como usaron la señal de que un enemigo ha arribado y la guerra está por empezar (también conocido como @channel), me siento de alguna forma obligado a ayudar.

Escribir @channel la mayoría de las veces es innecesario y es un gran contribuidor a destruir la torre de concentración. La mayoría de las cosas puede esperar a una reunión de soporte o ser tratadas por una sola persona asignada a ayudar ese día.

Estas interrupciones me sacan de mi trabajo y mi torre de concentración se comienza a derrumbar. Si estoy alejado de mi trabajo por una hora o más, es como si apuntaras con un secador de pelo a mi torre de cartas para que se vuele por completo.

Para ser claros, pequeñas interrupciones por unos pocos minutos no son graves, puedo retornar a mi trabajo sin notarlo. Aun así, incluso cuando se trata de un pequeño desenfoque, hay un gran riesgo en que no pueda volver a retomar mi trabajo en el punto en el que estaba. Iré a revisar mi correo o ver mi cantidad de likes en mi cuenta de twitter. Cuanto más tiempo me lleve regresar a mi tarea original, más grande será el impacto negativo en la distracción.

Luchando contra el derrumbe

Entonces, ¿qué podemos hacer?. Lo más importante es ser consciente que las interrupciones no son gratuitas. Está puede ser la razón por la que tus compañeros de trabajo ponen bloques en sus calendarios para prevenir interrupciones. Seamos respetuosos entre nosotros.

Por otro lado, yo suelo ser mi peor enemigo conmigo mismo cuando se trata de distracciones. Esta es una lista de las cosas que recopilé y me resultan útiles para mantener el foco.

1. Reducir las interrupciones de slack a nivel de equipo

Si tienes que lidiar con interrupciones de slack, dale un vistazo a mis consejos sobre cómo reducir las interrupciones de slack en tu equipo. Estos consejos tratan de forma específica sobre formas en las que puedes trabajar con un equipo de soporte para distribuir las interrupciones entre los integrantes del equipo. Mi consejo en este sentido es planificar las interrupciones definiendo una planificación de rotación.

2. Crear fricción con tus distracciones

He creado un poco de fricción moviendo mis distracciones más grandes a otro escritorio. Distracciones como Slack, twitter, linked-in, o el email. Cuando tengo interés en mirar esas cosas, necesito pulsar algunas teclas para hacer el cambio de escritorio. Esta fricción me sirve como un recordatorio de que quiero mantener el foco en mi trabajo y funciona muy bien. También he incrementado la fricción minimizando las ventanas o cerrándolas completamente.

3. Crear un grupo de pestañas oculto

Una de las cosas con las que peleo constantemente es mirar las métricas de mi negocio todo el tiempo. Así que para ayudarme a ganar la pelea he creado un grupo de pestañas en chrome.

Este grupo de pestañas contiene comunidades a las que pertenezco, como linked-in, twitter, slack y mis páginas de métricas. Sé que no tengo que abrir este grupo durante periodos de concentración. Sí, ya sé que podría cerrar todos los tabs juntos, pero tengo el hábito de reabrir los sitios si no lo hago así. Tenerlos agrupados de esa manera me ayuda a recordar que son mi mayor distracción.

Otra cosa que he estado intentando adoptar es la estrategia expuesta por Michael Lynch de solo mirar las métricas una vez a la semana. Él también tiene este problema de mirar las métricas muy seguido:

Mirar las métricas es un “trabajo superficial”: no requiere hacer foco o pensar de forma crítica, pero se siente como algo productivo. Hasta que rompí con el hábito de mirar constantemente estas métricas nunca me había dado cuenta todo el espacio que ocupaba en mi cerebro.

- Michael Lynch, How to Grow Quickly and Never Turn a Profit.

4. Registra el contexto periódicamente

El último consejo para combatir el derrumbe del contexto es ir haciendo notas a medida que vas avanzando. Lo que me gusta hacer es tener un script de bash en cada directorio llamado .zing. Este tipo de script se marcan como ignorados en git así que puedo colocarlo junto al código en el que estoy trabajando. Este es un ejemplo de uno de esos archivos en los que estuve trabajando la semana pasada:

#!/bin/bash

# Todos (para hacer):
# - verificar si se ejecuta dos veces si se actualiza el uso para eses día.
# - usar end_ts para la fecha.
# - usar el registro `last-in`
# - redondear los valores de uso mensual 219.002 == 220

./report_to_stripe.rb 05/
exit
../bin/monthly_report.rb 05/
exit

Mi archivo .zing sirve para dos propósitos: Almacena una lista de tareas y notas, pero también contiene un histórico del último comando que ejecuté. Cuando regreso la mañana siguiente puedo ejecutar el script y saltar directamente a lo que estaba haciendo en ese momento.

Uso zing para ejecutar mi script desde vim o mi terminal usando ,z. Este atajo también me ayuda a hacer las cosas más rápido.

Construyamos una torre de concentración juntos.

Cada día es una batalla para mantener mi torre de cartas libre de las ráfagas de viento de la distracción y las interrupciones. Trabajar juntos para detener las distracciones innecesarias es un esfuerzo de equipo y si se hace correctamente puede influir de forma significativa en la productividad y ayuda a los desarrolladores a alcanzar su mejor trabajo.