Pregunta de entrevista para Desarrollador Python

¿Cómo localizarías y arreglarías un problema de consultas N+1 en una aplicación Django?

Qué evalúa el entrevistador, cómo estructurar tu respuesta y un ejemplo hablado que puedes adaptar.

Respuesta rápida

Primero confírmalo contando consultas, con Django Debug Toolbar en local o con assertNumQueries en un test. El patrón es un bucle que toca un objeto relacionado, lo que dispara una consulta por fila porque los querysets son perezosos. Arregla las relaciones directas con select_related, que hace un join, y las inversas o de muchos a muchos con prefetch_related, que lanza una consulta extra.

Por qué lo preguntan los entrevistadores

Es el bug de rendimiento más común en aplicaciones con ORM, así que está a un paso de ser un requisito del puesto. Los entrevistadores quieren ver que mides antes de optimizar, que entiendes la pereza de los querysets como causa de fondo, y que sabes que select_related y prefetch_related resuelven formas de relación distintas. Añadir un test de regresión en vez de solo parchearlo es la señal de perfil senior.

Cómo estructurar tu respuesta

  • Di que primero mides el número de consultas.
  • Explica la pereza como causa raíz.
  • Asocia select_related y prefetch_related a los tipos de relación.
  • Fija el arreglo con un test que cuente consultas.

Ejemplo de respuesta

Ejemplo hablado, en primera persona

Lo primero es medir, porque adivinar el rendimiento de un ORM es tirar una tarde. En local activo la debug toolbar o logueo las consultas a nivel debug, y si ya está en producción miro la traza, donde un endpoint que lanza cuatrocientos selects casi idénticos es inconfundible. La causa es que un queryset no toca la base de datos hasta que lo iteras, y acceder a una clave foránea en cada fila trae esa relación de forma perezosa. Para una clave foránea directa añado select_related, que lo convierte en un join y una sola consulta. Para relaciones inversas o de muchos a muchos uso prefetch_related, que lanza una segunda consulta y cose los resultados en Python. Una vez arreglado, escribo un test que envuelve la vista en assertNumQueries con el número esperado, porque si no la siguiente persona añade un campo en la plantilla y vuelve a degradarse en silencio. En un panel interno pasamos una página de unas trescientas consultas a cuatro, y el tiempo de carga bajó de unos dos segundos a menos de doscientos milisegundos.

¿Tienes esta entrevista a la vuelta de la esquina? GhostPilot escucha tu llamada en vivo, detecta la pregunta en cuanto la hacen y pone una respuesta estructurada en tu pantalla en tiempo real. Pruébalo en tu próxima entrevista de práctica, o coge un Session Pass de $29, sin suscripción, para la de verdad.

Mira cómo funciona

Preguntas de seguimiento que puedes esperar

  • ¿Cuándo es prefetch_related más lento que un join?
  • ¿Qué cambian aquí only y defer?
  • ¿Cómo lo cazarías en una revisión de código?

Más preguntas para Desarrollador Python

Tu entrevistador hará su propia versión de esta. Pega la descripción real del puesto en el Question Predictor gratuito y obtén las 20 preguntas que ese puesto tiene más probabilidades de hacerte, con lo que cada una busca en realidad.

Predecir mis preguntas

Ensaya las preguntas difíciles antes de que te las hagan

Practica con un copiloto en vivo y entra preparado. Un Session Pass de $29 te lleva a través de la entrevista sin suscripción y sin ataduras.

Consigue GhostPilot