Cuando una solución de código pasa las pruebas, pide al candidato que haga un cambio concreto, pruebe tanto el comportamiento nuevo como el contrato existente y explique cómo dejaría el trabajo a otro ingeniero. Las buenas preguntas de seguimiento en una entrevista de código muestran cómo trabaja alguien sobre una implementación existente. Elige el cambio a partir de las responsabilidades del puesto y evalúa a todos con los mismos criterios y las mismas pruebas del trabajo realizado.

El [debate de Hacker News sobre *Competitive Programmer's Handbook*](https://news.ycombinator.com/item?id=49944049) vuelve a poner sobre la mesa la práctica de algoritmos. El libro de Antti Laaksonen es un borrador del 3 de julio de 2018. Su [introducción](https://www.cses.fi/book/book.pdf#page=13) describe la programación competitiva como diseño e implementación de algoritmos, cuyas soluciones se comprueban mediante pruebas de corrección. También explica que los programas de competición son cortos y no necesitan mantenimiento posterior.

Esa última diferencia te da una pregunta útil para la entrevista. Si vas a contratar a alguien para mantener un producto, ¿qué ocurre cuando hay que modificar una solución correcta? Evalúa el razonamiento algorítmico cuando el puesto lo requiera. Después, recoge pruebas del trabajo que empieza cuando otro ingeniero tiene que depender de ese código.

## ¿Qué te dice una solución que pasa las pruebas?

Una solución que pasa las pruebas demuestra que la implementación funciona correctamente en los casos comprobados. También puede servir para hablar de corrección y complejidad. Son observaciones útiles, pero dejan abiertas algunas preguntas sobre el mantenimiento.

Todavía no has visto cómo interpreta el candidato un contrato que no ha definido. Quizá no sepas si distingue un requisito nuevo de un cambio de comportamiento accidental. Una solución terminada tampoco dice mucho sobre la nota que dejaría al siguiente ingeniero.

El manual describe con claridad su propio contexto. Un problema de competición premia una implementación correcta dentro de sus restricciones. Tu ejercicio de selección debe reflejar las responsabilidades que necesitas cubrir. Ambas descripciones son compatibles.

Para un ingeniero que trabaja en un servicio de reservas, preservar el significado de una API existente puede merecer un criterio de evaluación propio. En un puesto centrado en el desarrollo de algoritmos, deducir y analizar un algoritmo puede seguir siendo lo principal. Define esos objetivos antes de elegir el ejercicio.

Este artículo utiliza un ejemplo ficticio de reservas. Propone un conjunto práctico de materiales para la entrevista, no un instrumento de selección validado. Aquí no hay pruebas de que este ejercicio concreto prediga la productividad, elimine los sesgos o permita contratar a mejores profesionales.

Para una visión más amplia de los formatos de evaluación, consulta nuestra [guía de entrevistas de código tras la llegada de la IA](/blog/leetcode-obsolete-post-ai-interview). Aquí nos centramos en algo más pequeño: una función existente, un cambio solicitado, una prueba y una nota de entrega.

## Elige las tareas de mantenimiento que exige el puesto

Empieza por una responsabilidad que el nuevo ingeniero tendrá desde su incorporación. Conviértela en una tarea pequeña y observable, y elimina del ejercicio la configuración que no tenga relación con ella.

Las [orientaciones sobre análisis de puestos](https://www.opm.gov/policy-data-oversight/assessment-and-selection/job-analysis/) de la Oficina de Gestión de Personal de Estados Unidos (OPM) relacionan las tareas de un puesto con las competencias necesarias para realizarlas. Al aplicar ese principio al software, puedes elegir preservar el contrato de una API, ampliar un modelo de datos o documentar las consecuencias de un parche. Estos ejemplos de software son nuestra aplicación de esas orientaciones.

En estos materiales, el objetivo es **cambiar el comportamiento preservando un contrato documentado**. Quieres ver si el candidato identifica los registros afectados, implementa el cambio y protege el comportamiento anterior con pruebas. También quieres una explicación clara de lo que ha cambiado.

Ese objetivo no exige que el candidato configure tu entorno de producción ni descubra una regla de negocio sin documentar. Proporciona un comando de pruebas que funcione, un repositorio pequeño y las reglas pertinentes. Si falla la instalación, resuélvelo antes de evaluar el parche.

Las [orientaciones de la OPM sobre muestras de trabajo](https://www.opm.gov/policy-data-oversight/assessment-and-selection/other-assessment-methods/work-samples-and-simulations/) describen tareas similares a las que se realizan en el puesto. También aconsejan no evaluar competencias que tengas previsto enseñar después de la selección. Si el puesto incluye aprender vuestro framework tras la incorporación, no conviertas sin avisar el conocimiento de ese framework en el criterio decisivo.

Deja claro el alcance al candidato. Indica qué archivos importan, qué debe entregar y cómo lo revisarás. Explica si se permite consultar documentación, hacer búsquedas y usar asistencia de IA. Nuestra [guía para diseñar muestras de trabajo](/blog/whiteboard-interview-dead-work-sample-design-2026) aborda esas decisiones más amplias sobre el formato.

## Da a todos los candidatos la misma implementación que pasa las pruebas

Proporciona a todos la implementación y sus pruebas. La tarea de mantenimiento debe partir de una base común, para que las observaciones no dependan de haber resuelto antes un acertijo algorítmico.

Estos son los materiales ficticios. Un servicio de reservas almacena intervalos de tiempo con valores enteros. La función devuelve si todas las reservas pueden coexistir en una misma sala. La versión inicial que aparece a continuación funciona con la biblioteca estándar de Python; el lenguaje es un ejemplo, no un requisito de la evaluación.

### Contrato existente

Incluye estas reglas en el README junto a la función:

- Cada registro tiene valores `start` y `end`, con `start < end`.
- Los intervalos son semiabiertos: una reserva que termina en `20` puede compartir la sala con otra que empieza en `20`.
- Los registros pueden llegar en cualquier orden.
- La función devuelve un booleano y conserva el orden original de la lista de entrada.
- Los intervalos inválidos quedan fuera de este ejercicio. Puedes asumir que se cumple la precondición indicada.

Estas reglas importan porque resuelven preguntas cuya respuesta el candidato tendría que adivinar. En particular, se permiten las reservas contiguas y la ordenación no debe modificar la lista que se pasa a la función.

### Solución proporcionada y pruebas iniciales

```python
# bookings.py

def can_share_room(bookings):
    ordered = sorted(bookings, key=lambda booking: booking["start"])
    return all(
        previous["end"] <= current["start"]
        for previous, current in zip(ordered, ordered[1:])
    )
```

```python
# test_bookings.py
import unittest

from bookings import can_share_room


class BookingTests(unittest.TestCase):
    def test_empty_and_single_booking(self):
        self.assertTrue(can_share_room([]))
        self.assertTrue(can_share_room([{"start": 10, "end": 20}]))

    def test_adjacent_bookings_can_share(self):
        self.assertTrue(can_share_room([
            {"start": 10, "end": 20},
            {"start": 20, "end": 30},
        ]))

    def test_overlapping_bookings_cannot_share(self):
        self.assertFalse(can_share_room([
            {"start": 10, "end": 20},
            {"start": 15, "end": 25},
        ]))

    def test_unsorted_input_keeps_its_order(self):
        bookings = [
            {"start": 20, "end": 30},
            {"start": 10, "end": 20},
        ]
        original = [booking.copy() for booking in bookings]
        self.assertTrue(can_share_room(bookings))
        self.assertEqual(original, bookings)


if __name__ == "__main__":
    unittest.main()
```

El README incluye un único comando: `python -m unittest`. Ejecútalo antes de entregar el repositorio. El candidato debe encontrar una versión inicial que pase las pruebas, sin descargar dependencias ni necesitar credenciales ocultas.

Pídele que explique por qué la ordenación permite comprobar los solapamientos entre pares contiguos. Si un intervalo posterior se solapa con uno anterior, tiene que haber un solapamiento entre vecinos de la secuencia ordenada. También puedes hablar del coste de la ordenación y de la memoria adicional para la nueva lista si esos conceptos importan para el puesto.

Registra la conversación sobre el algoritmo por separado de las observaciones sobre mantenimiento. Un candidato puede explicar el algoritmo con claridad y aun así pasar por alto la compatibilidad. Otro puede respetar el contrato con cuidado, pero necesitar ayuda para explicar la complejidad. Separar los criterios permite una revisión más concreta.

## Pide un cambio y las pruebas que lo protegen

Da una instrucción precisa: las reservas canceladas deben dejar de ocupar la sala y los registros antiguos deben conservar su significado. Pide un parche acotado y pruebas que distingan el comportamiento modificado del que debe mantenerse.

Incluye esta petición tal cual en el README ficticio:

> Los registros ahora pueden contener un campo booleano `cancelled`. Un registro con `cancelled: True` no ocupa la sala. Si el campo no existe o contiene `cancelled: False`, la reserva sigue ocupándola. Conserva las reglas de intervalos existentes y el orden de entrada. Asume que los valores de cancelación proporcionados son booleanos. Añade pruebas y una breve nota de entrega.

Así la tarea queda limitada a un cambio de comportamiento. El candidato no tiene que inventar permisos de cancelación, interpretación de fechas, almacenamiento ni un formato de respuesta nuevo. Si detecta esas cuestiones, puede mencionarlas en la nota de entrega.

### Una implementación acotada

Un parche válido filtra antes de ordenar:

```python
def can_share_room(bookings):
    active = [
        booking for booking in bookings
        if not booking.get("cancelled", False)
    ]
    ordered = sorted(active, key=lambda booking: booking["start"])
    return all(
        previous["end"] <= current["start"]
        for previous, current in zip(ordered, ordered[1:])
    )
```

El valor por defecto para los campos ausentes conserva el comportamiento de los registros antiguos. El filtrado no modifica la lista que se pasa a la función. La comprobación de solapamientos puede mantener su significado original porque ahora solo recibe registros que ocupan la sala.

Esta es una respuesta de ejemplo para preparar el ejercicio. No la incluyas en los materiales del candidato. Acepta otras implementaciones que cumplan el contrato; las preferencias sobre nombres y disposición del código no deben convertirse sin avisar en requisitos nuevos.

### Pruebas que demuestran el cambio

Añade estos métodos a la clase de pruebas proporcionada:

```python
    def test_cancelled_overlap_does_not_block_room(self):
        self.assertTrue(can_share_room([
            {"start": 10, "end": 20},
            {"start": 15, "end": 25, "cancelled": True},
        ]))

    def test_explicit_false_still_blocks_room(self):
        self.assertFalse(can_share_room([
            {"start": 10, "end": 20},
            {"start": 15, "end": 25, "cancelled": False},
        ]))

    def test_all_cancelled_bookings_leave_room_available(self):
        self.assertTrue(can_share_room([
            {"start": 10, "end": 20, "cancelled": True},
            {"start": 15, "end": 25, "cancelled": True},
        ]))
```

La primera prueba nueva falla con la implementación proporcionada. Es una comprobación útil: la prueba cubre el cambio solicitado. La segunda protege los registros explícitamente activos, mientras que la prueba de solapamiento original protege los registros sin campo de cancelación.

Las pruebas originales de reservas contiguas y orden de entrada siguen siendo importantes. Cubren partes del contrato que la petición no cambia. Pide al candidato que muestre qué aserciones demuestran la regla nueva y cuáles preservan las anteriores.

Puedes comentar si conviene añadir una prueba que confirme que los registros cancelados también permanecen en la lista que se pasa a la función. Así se comprobaría explícitamente la regla de conservación de la entrada con la nueva estructura de datos. Si falta una prueba, registra esa carencia concreta de cobertura y después comprueba si la implementación incumple realmente la regla.

No valores el número de pruebas por sí solo. Varias pruebas que repiten el mismo escenario pueden ocultar un caso límite sin cubrir. Revisa la relación entre cada aserción y el contrato indicado.

## Revisa la entrega con preguntas comunes

Pide a todos los candidatos que expliquen el cambio mediante las mismas preguntas principales. Los revisores deben registrar qué demuestra el código y qué comprueban las pruebas antes de hablar de la decisión global.

Las [orientaciones de la OPM sobre entrevistas estructuradas](https://www.opm.gov/policy-data-oversight/assessment-and-selection/structured-interviews/) describen preguntas predeterminadas en un orden común y criterios de puntuación compartidos. Aplicar esos principios a una conversación sobre código es una recomendación práctica. No convierte este ejercicio en una evaluación certificada por la OPM ni demuestra su validez predictiva.

### Una nota de entrega que resulte útil

Una nota de ejemplo podría decir:

> Las reservas canceladas se excluyen antes de ordenar. Si falta el campo de cancelación, la reserva se considera activa, por lo que los registros antiguos conservan su comportamiento. Las pruebas existentes de reservas contiguas y orden de entrada siguen pasando. La nueva prueba de solapamiento con una reserva cancelada falla con la función original. Se asume que la entrada contiene valores booleanos de cancelación; la validación de datos importados queda fuera de este parche.

Esa nota explica al siguiente ingeniero qué ha cambiado, qué se ha mantenido y hasta dónde llega el supuesto de partida. No necesita un ensayo largo ni un relato de cada modificación.

Haz las mismas tres preguntas principales:

1. ¿Qué comportamiento existente has protegido y dónde está la prueba?
2. ¿Qué prueba fallaría sin tu cambio?
3. ¿Qué debería saber el siguiente ingeniero antes de volver a modificar esta función?

Un revisor puede pedir aclaraciones sobre el trabajo entregado. Registra también esas preguntas, sobre todo cuando aporten información que otro candidato recibió en las instrucciones iniciales. Mejora los materiales si las preguntas recurrentes revelan una ambigüedad.

### Una ficha de revisión común

Utiliza una ficha con referencias concretas acordadas antes de empezar las entrevistas:

| Criterio | Pruebas que registrar | Posible problema que comprobar |
| --- | --- | --- |
| Lectura del contrato | Identifica como activas las reservas con el campo de cancelación ausente o con valor falso | Descarta registros antiguos o cambia las reglas de reservas contiguas |
| Corrección del cambio | Los registros cancelados no afectan a la disponibilidad | Mantiene los solapamientos cancelados en la comparación |
| Protección frente a regresiones | Relaciona las aserciones con el comportamiento nuevo y el existente | Muestra pruebas que pasan sin explicar su cobertura |
| Entrega | Explica el cambio, el comportamiento preservado y el supuesto sobre la entrada | Obliga al siguiente responsable del mantenimiento a deducir el contrato |

Estas son referencias propuestas para este ejercicio. Adáptalas a las responsabilidades que hayas identificado y decide cómo influirán en la decisión de contratación antes de ver las entregas. No las presentes como umbrales de puntuación respaldados por investigaciones.

Prueba los materiales con compañeros que conozcan el puesto. Pregunta dónde necesitaron aclaraciones y si la tarea solicitada evalúa una competencia necesaria desde el primer día en el puesto. La OPM señala que preparar y realizar muestras de trabajo exige esfuerzo; reserva tiempo y recursos para esa preparación y revisión.

Para un puesto sénior cuya tarea principal sea evaluar una propuesta de diseño, utiliza otro ejercicio. Nuestra [guía de entrevistas de revisión de diseño para ingenieros sénior](/blog/senior-engineer-design-review-interview) aborda esa responsabilidad. Este pequeño parche no puede representar todas las formas de criterio técnico.

## Organiza el ejercicio en Kit

Prepara el ejercicio y los criterios de revisión, y después utiliza Kit para organizar el ejercicio de código en el pipeline de contratación. GitHub contiene la implementación, las pruebas y la revisión del código; los revisores humanos interpretan las pruebas recogidas.

Los ejercicios de código de Kit utilizan repositorios privados creados a partir de un repositorio de plantilla de la empresa. Los candidatos conectan GitHub para realizar el ejercicio. Tras la entrega, los revisores con cuentas de GitHub conectadas pueden recibir invitaciones al repositorio e inspeccionar allí el código y su historial.

Incluye el README, las pruebas iniciales y los entregables en tu plantilla. Si quieres una pull request, solicítala en esas instrucciones. Kit no la crea automáticamente ni puntúa la implementación. Define junto al ejercicio los criterios de revisión que utilizará tu equipo.

Fija una fecha límite de entrega que encaje en el proceso y explica por separado el esfuerzo esperado. Una fecha límite no es un cronómetro que mide las horas de programación activa. No interpretes su vencimiento como prueba de que el repositorio queda bloqueado. Nuestra [guía para configurar ejercicios de código](/blog/how-to-structure-code-assignments) aborda el proceso completo, incluidos los plazos y la revisión.

Una solución correcta es un punto de partida útil. Para un puesto de mantenimiento, continúa con un cambio claro, pruebas que protejan el contrato y una nota de entrega que otro ingeniero pueda utilizar. Empieza probando estos materiales con una responsabilidad real de tu equipo y ajusta las instrucciones antes de dárselas a los candidatos.