Petición para detener los desafíos de programación irreales
(blackentropy.bearblog.dev)- Algunas pruebas de programación irreales en entrevistas técnicas crean situaciones de presión distintas al trabajo real y no miden adecuadamente la capacidad práctica de un desarrollador
- Las tareas individuales de alta presión no reflejan un entorno laboral con colaboración y apoyo, y suelen derivar en depurar una base de código heredada sin documentación ni ayuda del equipo
- Incluso una “prueba de 4 horas”, como la describen las empresas, puede convertirse en 8 a 10 horas o más si se suma investigar la empresa, revisar los requisitos del puesto y pulir la entrega
- Las pruebas con stacks tecnológicos no relacionados con el rol se justifican como evaluación de adaptabilidad, pero pedirle a un desarrollador Ruby que depure PHP puede no alinearse con la idoneidad real para el puesto
- La contratación debería enfocarse en habilidades relevantes, resolución de problemas, colaboración y potencial de crecimiento, en lugar de pruebas arbitrarias de alta presión; las tareas excesivas pueden agotar y alejar a buenos candidatos
Pruebas de entrevista que no coinciden con el trabajo real
- Algunas entrevistas técnicas les exigen a los desarrolladores completar en pocas horas tareas como depurar PHP heredado o crear una miniapp
- Estas tareas individuales no se parecen a la forma en que se trabaja en la realidad
- En el trabajo normalmente se colabora con un equipo y se puede recibir el apoyo necesario
- Tener que depurar por tu cuenta y a toda velocidad una base de código antigua, sin documentación ni ayuda del equipo, no encaja con un entorno de desarrollo común
- Las empresas lo ven como una evaluación de la “capacidad de resolver problemas”, pero si la prueba no está conectada con las exigencias reales del rol, es difícil medir la idoneidad práctica del candidato
El costo oculto de tiempo y la carga para el candidato
- El tiempo recomendado para una prueba de programación no suele reflejar bien el tiempo que realmente termina invirtiendo el candidato
- Antes de empezar, hay que investigar la empresa y revisar los requisitos del puesto
- También hace falta tiempo para pulir el proyecto y dejar la entrega en buen estado
- Una prueba “de 4 horas” puede extenderse a 8, 10 o incluso más
- Para desarrolladores que compaginan trabajo y vida personal, esto puede sentirse como hacer trabajo no remunerado por un empleo que todavía no han conseguido
Cuando la evaluación de adaptabilidad falla
- A veces se justifican pruebas con stacks no relacionados como una forma de evaluar la “adaptabilidad”
- Pedirle a un desarrollador Ruby que depure PHP, más allá de la importancia de la adaptabilidad, puede ser un criterio inadecuado para juzgar el valor del candidato
- La capacidad de resolver rápido tareas ambiguas e irrelevantes no basta para determinar si alguien encaja en el rol real
- Algunas pruebas pueden sentirse más como una forma de presumir el estándar “élite” de la empresa que como una evaluación del ajuste del candidato
- Si en todos los procesos de contratación se levantan barreras tipo “top 1%”, incluso candidatos experimentados que podrían hacer bien el trabajo pueden abandonar por lo artificial y estresante de la situación
Qué deberían evaluar las pruebas de contratación
- El proceso de contratación debería diseñarse alrededor de las habilidades concretas que requiere el rol
- Hay que evitar pruebas estilo bootcamp de programación que no tienen relación con las exigencias reales del trabajo
- Debería centrarse en resolución de problemas, colaboración y potencial de crecimiento en áreas relevantes
- La adaptabilidad no debería medirse por qué tan rápido alguien resuelve una tarea arbitraria, sino por su capacidad de aprender a largo plazo
1 comentarios
Opiniones de Hacker News
¿Cuándo fue la última vez que tuviste que depurar una base de código vieja, sin documentación ni ayuda del equipo? Siempre fue así. Era de 300.000 a 400.000 líneas de C++, y “legacy” significaba que no había ninguna prueba, casi no había documentación, y como único desarrollador en una empresa pequeña tenía que seguir dando servicio a decenas de miles de usuarios mientras corregía bugs y agregaba funciones.
Como ejemplo reciente, había un parche de una función clave que llevaba más de un año pendiente; el autor original ya no estaba, y había que reescribir el código desde cero o revivir el parche para adaptarlo a master.
La capacidad de meterse en un proyecto y llevar a la gente hacia el objetivo es claramente una habilidad necesaria para un desarrollador senior, y estoy de acuerdo con la conclusión de que hay que evaluar la capacidad de resolver problemas. Pero el contenido de una entrevista técnica debería variar según el rol: no hace falta pedirle a un desarrollador web junior que resuelva algoritmos de grafos en una pizarra, pero un desarrollador senior o arquitecto de un producto de red social sí debería entenderlos en profundidad.
La semana pasada depuré código Go de 2020, también sin comentarios ni documentación; era otra parte central del sistema y parecía escrito por gente demente. Es doloroso.
Creo que la disposición a bajar de nivel para resolver el problema en la capa correcta es una de las grandes habilidades blandas que distinguen a un ingeniero senior. En vez de esquivar un bug de una capa inferior o una función faltante con una corrección posterior en tu propio código, si lo arreglas en la capa correcta, todo el sistema se vuelve más robusto ante cambios arriba y abajo del stack y ante casos de uso futuros inesperados.
Por el contrario, si no se adopta este enfoque, cuando los ingenieros senior se van o son reemplazados por juniors, la base de código empieza a pudrirse. Por ejemplo, si para cada caso borde de parsing de entrada agregas otra expresión regular de validación ingenua delante de un parser aterrador y opaco, en vez de corregir la gramática del parser en sí, la base de código está evolucionando hacia una bola de lodo.
Claro que, si lo arreglas en la capa correcta, muchas veces la empresa tiene que mantener una pequeña rama privada de hotfix de largo plazo del software del ecosistema que usa en su stack. El upstream normalmente no ve ese problema como un problema y no acepta el parche, así que hay que conservarlo por cuenta propia.
Dicho en broma, si uno pudiera autenticar el perfil de GitHub y contar cuántas veces alguien creó o mantuvo estas ramas privadas de hotfix de largo plazo, quizá se podría medir la seniority de un ingeniero mucho más fácilmente que con una prueba de programación.
No ayuda actuar como si no sirviera en el mundo real. La realidad es desordenada, la documentación muchas veces no existe o no es confiable, y la persona o el equipo que escribió el código original puede que ya no esté.
Tengo una pequeña anécdota. La pareja de un amigo renunció a principios de este año y luego se preparó para entrevistas en distintas empresas de Big Tech durante 4 a 6 semanas por cada una. Meta 4 a 6 semanas, Stripe 4 a 6 semanas, y así; entre medio también hizo entrevistas al azar para practicar y desarrollar memoria muscular, investigó los problemas que podrían aparecer en cada empresa y resolvía LeetCode varias horas al día.
Al final le fue bien y aceptó una oferta L6/staff en MAANG. Pero hablando esta semana, dijo que todavía ni siquiera empezó su nuevo rol y ya olvidó la mayoría de los detalles que había practicado. Dijo que la preparación de diseño de sistemas fue lo más difícil porque no tenía experiencia en diseño de sistemas, pero ahora es staff eng en MAANG. En la vida real, habiendo hecho un proyecto pequeño juntos, es una persona muy buena, pero no era una ingeniera excepcionalmente brillante.
Es realmente raro, y parece explicar bastante los ciclos de auge y caída en la contratación. Si ves videos de preparación para entrevistas de diseño de sistemas, parecen casi guiones. Entras a la entrevista y solo tienes que seguir el guion; no parece importar si realmente diseñaste sistemas similares o más complejos. El objetivo de la entrevista de diseño de sistemas parece ser, al final, “¿conoces el guion?”.
Si ves estos dos videos seguidos a 2x, sorprende lo guionizado que se ve todo: https://www.youtube.com/watch?v=4_qu1F9BXow, https://www.youtube.com/watch?v=_K-eupuDVEc
Mis dos padres estuvieron en la industria tecnológica de Santa Cruz en los años 80 y 90, y en ese entonces, como el pool de talento no era grande, era una herramienta inclusiva para encontrar gente a la que se pudiera convertir en desarrolladora. La industria actual adoptó esa práctica, pero la volvió excluyente, justo lo contrario.
Una de las personas que contraté era física, no conocía nada de la jerga y se asustó muchísimo la primera vez que vio un problema de pizarra. Cuando la llevé hasta un punto en el que se sintiera cómoda, empezó a hablar de herramientas que había creado para ayudar en su trabajo de física, y se sorprendió cuando le dije que esas herramientas que había hecho sin conocimientos de desarrollo eran software. No solo era software real, sino que era muy impresionante, y el problema de pizarra fue una herramienta para revelar potencial.
Entiendo que las grandes empresas quieran widgets que puedan insertar directamente en lugar de personas, pero da risa que usen algo que fue creado con el objetivo exactamente opuesto. Incluso pienso que por suerte ya soy lo bastante viejo como para no tener esperanzas de entrar a una empresa cool que haga este tipo de desafíos de código.
La lógica es que, sin importar a qué universidad fuiste, qué clases tomaste o qué ventajas o desventajas tuviste, si tienes las cualidades necesarias para el rol, es algo que puedes aprender en unos meses. Como la técnica está muy estandarizada, el proceso también se vuelve bastante objetivo.
No esperan que uses esa técnica específica en el trabajo real. En cambio, demuestras que puedes aprender ese tipo de técnica y rendir a alto nivel en una situación de entrevista con mucho estrés. La lógica es que eso es una buena señal de que podrás aprender las técnicas necesarias para el proyecto al que te asignen después y rendir bajo una gran presión de fechas límite.
No estoy defendiendo el sistema, pero sí hay una lógica clara detrás.
Aunque diga que lo olvidó, si consiguió ese puesto probablemente podía resolver problemas medianos de LeetCode. Es difícil creer que lo haya olvidado todo, y es probable que todavía pueda resolver problemas fáciles que la mayoría de la gente no puede sacar en el momento. También debería seguir conociendo la complejidad de tareas esenciales de backend como búsqueda, ordenamiento, arreglos y búsquedas con hash, recorridos de árboles y grafos.
Y puede que el talento actoral sea más común en la población general que el talento para programar.
Hace poco dirigí el proceso de entrevistas para un puesto de ingeniería relativamente sénior en una startup pequeña. Creo que a distintas personas les funcionan mejor distintos formatos de entrevista, así que les di opciones a todos:
Cuantas más quejas veo en línea sobre las entrevistas de programación, más me convenzo de que las entrevistas de programación son, por lejos, la mejor forma de filtrar candidatos para puestos de desarrollo de software. En la industria sobran los que hablan bonito, los impostores y los que agendan reuniones; faltan personas que se arremanguen, se metan al código y realmente terminen el trabajo. Este problema empeora cuanto más alto es el nivel. Pueden quejarse todo lo que quieran, pero un puesto cómodo en FAANG de 500 mil dólares al año no es algo que se dé por sentado. Si no tienes ganas de repasar programación básica y escribir unos cuantos bucles
for, la empresa simplemente pasará a alguien que sí lo haga.Hacer que un desarrollador Ruby depure PHP como prueba de flexibilidad suena como una prueba razonable. Un buen desarrollador, especialmente un desarrollador sénior, debería poder hacer ese tipo de cosas. Encerrarse únicamente en la categoría de “desarrollador Ruby” es una trampa profesional.
A veces hay que depurar una DSL antigua y específica de un proveedor, o código en el que el framework y los estándares son tan viejos que prácticamente se volvió otro lenguaje.
También toca agregar soporte para funciones backporteadas o parchear agujeros de seguridad en clientes antiguos y stacks legacy. En una empresa grande, incluso nos tocó hacernos responsables del código en escrow de un socio mucho más pequeño.
Configurar el entorno para poder depurar bien suele ser más trabajo que el arreglo real. Aun así, es una buena prueba para perfiles sénior o superiores.
El entrevistador dijo: “Invierta este arreglo”, y yo respondí: “En Python usaría array.reverse() o reversed(array), y JS debe tener una de esas opciones, así que probablemente sea el método .reverse”. El entrevistador dijo: “Buena suposición”.
Sinceramente me pareció divertido, salí sintiendo que había aprendido algunas cosas, y la otra parte pudo ver cómo razono ante un problema nuevo.
He depurado muchas veces bases de código antiguas sin documentación ni ayuda del equipo. Existen de verdad sistemas donde ya no queda nadie de quienes los crearon y la documentación no existe o no se puede encontrar. Así que este ejemplo no es muy bueno. La capacidad de depurar un programa, seguir el flujo de una solicitud y ver qué está pasando es una buena habilidad.
Pero donde este ejemplo sí es realmente malo es en que encasilla a los desarrolladores en una tecnología específica. Si tienes una aplicación legacy en PHP, terminas filtrando a desarrolladores Java, Python, Ruby o Go que tienen esa capacidad de depuración, pero que serían más lentos porque no saben PHP. Aunque quizá, tras tocar PHP directamente unos meses, podrían ser desarrolladores más fuertes.
Estoy de acuerdo en que una “tarea de 4 horas” puede convertirse fácilmente en 8, 10 o más horas para producir un buen resultado. El tiempo indicado se puede manipular fácilmente, así que alguien con más tiempo disponible puede parecer mejor candidato.
¿Cuándo fue la última vez que depuré una base de código antigua sin documentación ni ayuda del equipo? Todos los días de esta semana.
Si hablamos de documentación, el código se actualizó por última vez en junio y la documentación se actualizó por última vez en enero de 2022.
Si hablamos del equipo, la mitad que no fue despedida hace dos años ya se fue a lugares mejores. Claro que hay un equipo dueño de este proyecto, pero también tiene otros tres proyectos, y en el último año sus aportes aquí fueron unas cuantas líneas, de las cuales 11 fueron actualizaciones de dependencias.
Decir “es como hacer que un desarrollador Ruby depure PHP” y “si el puesto requiere una tecnología específica, evalúa esa tecnología” suena a alguien que reprobó un coding challenge.
Hablando en serio, las empresas rara vez adoptan prácticas de contratación solo por diversión. Por lo general, es el mejor método que esa inteligencia colectiva pudo idear. Pedir que lo eliminen sin intentar entender qué problema están tratando de resolver y sin proponer alternativas no es productivo.
Creo que en desarrollo de software reinventamos la rueda con demasiada frecuencia, en vez de tomar prestadas prácticas de otras profesiones. Veamos qué procesos de contratación atraviesan los ingenieros civiles para ganar la mitad que los desarrolladores de software e integremos eso a nuestras prácticas. Entonces todos seremos soldados felices.
Me parece muy poco probable que hayan reflexionado sobre qué intentan lograr realmente. Simplemente lo hicieron porque otros lo hacen, y creen que en algún lugar alguien diseñó el proceso con una intención.
La contratación en tecnología está tan perdida que da la impresión de haberse asentado, en el mejor de los casos, en un máximo local.
Tuve una experiencia muy mala en una empresa que no hacía ninguna prueba de código. Solo hubo 2 o 3 entrevistas.
El problema apareció cuando empecé a trabajar con el equipo de ingeniería de datos. La mayor parte del stack se basaba en Hadoop, Kubernetes, Ruby, Python y varias tecnologías, y requería una comprensión básica de computación en la nube.
Pero la experiencia laboral y los antecedentes de cada persona eran tan disparejos que, en lugar de hacer el trabajo para el que me contrataron, pasaba mucho tiempo cubriendo huecos de otros. Algunos compañeros no podían hacer tareas básicas como empaquetar una CLI de Python con Docker o revisar jobs de Hadoop, así que terminé haciendo mucho trabajo de pegamento para compensarlo.
Al final me fui. No porque pensara que yo era especial, sino porque me cansé de pasar el 80% de mi tiempo apoyando a personas contratadas en el mismo nivel o en niveles más altos. Admito que las prácticas de contratación de esa empresa eran muy malas, pero hace falta alguna forma de evaluación técnica básica.
Otra pregunta importante es si había que explicarles lo mismo a las mismas personas una y otra vez. No saber algo es aceptable, pero no querer aprender es difícil de aceptar.
Lo interesante de las pruebas tipo tarea para llevar a casa es que, aunque te digan “dedica solo X horas”, existe un riesgo moral que te incentiva a dedicarles más tiempo. Si la empresa pregunta, también aparece el incentivo de mentir sobre el tiempo que realmente usaste
Varias veces entregué tareas en las que enfaticé que me ajusté al tiempo recomendado y resolví el problema de forma adecuada, pero en la entrevista de seguimiento me regañaron con un “¿por qué no implementaste X?”
En ese sentido, las pruebas tipo tarea demasiado abiertas son malas tareas. Porque favorecen a quienes tienen más tiempo libre para hacerlas con más detalle. Saludos a las pruebas tipo tarea de ciencia de datos que piden una presentación en PowerPoint como entregable final