Question d'entretien pour Développeur Python

Comment traqueriez-vous et corrigeriez-vous un problème de requêtes N+1 dans une application Django ?

Ce que le recruteur cherche à évaluer, comment structurer votre réponse et un exemple parlé à adapter.

Réponse rapide

Confirmez-le d'abord en comptant les requêtes, avec Django Debug Toolbar en local ou assertNumQueries dans un test. Le motif est une boucle qui touche un objet lié, ce qui déclenche une requête par ligne parce que les querysets sont paresseux. Corrigez les relations directes avec select_related, qui fait une jointure, et les relations inverses ou plusieurs-à-plusieurs avec prefetch_related, qui lance une requête supplémentaire.

Pourquoi les recruteurs posent cette question

C'est le bug de performance le plus courant dans les applications adossées à un ORM, donc c'est presque une exigence du poste. Les recruteurs veulent vous voir mesurer avant d'optimiser, comprendre que la paresse des querysets en est la cause profonde, et savoir que select_related et prefetch_related résolvent des formes de relation différentes. Ajouter un test de non-régression plutôt que juste rustiner, c'est le signal senior.

Comment structurer votre réponse

  • Dites que vous mesurez d'abord le nombre de requêtes.
  • Expliquez la paresse comme cause profonde.
  • Associez select_related et prefetch_related aux types de relations.
  • Verrouillez le correctif avec un test sur le nombre de requêtes.

Exemple de réponse

Exemple parlé, à la première personne

La mesure vient en premier, parce que deviner les performances d'un ORM, c'est perdre un après-midi. En local j'active la debug toolbar ou je journalise les requêtes en niveau debug, et si c'est déjà en production je regarde la trace, où un endpoint qui tire quatre cents selects presque identiques ne trompe personne. La cause est qu'un queryset ne touche la base que quand vous l'itérez, et accéder à une clé étrangère sur chaque ligne va chercher paresseusement cette relation. Pour une clé étrangère directe j'ajoute select_related, qui transforme cela en une jointure et une seule requête. Pour les relations inverses ou plusieurs-à-plusieurs j'utilise prefetch_related, qui émet une seconde requête et recoud les résultats côté Python. Une fois corrigé, j'écris un test qui enveloppe la vue dans assertNumQueries avec le nombre attendu, sinon la personne suivante ajoute un champ dans le template et la régression passe inaperçue. Sur un tableau de bord interne nous sommes passés d'environ trois cents requêtes à quatre sur une page, et le temps de chargement d'environ deux secondes à moins de deux cents millisecondes.

Vous passez cet entretien bientôt ? GhostPilot écoute votre appel en direct, repère la question dès qu'elle est posée et affiche une réponse structurée à l'écran en temps réel. Essayez-le lors de votre prochain entretien blanc, ou prenez un Session Pass à $29, sans abonnement, pour le jour J.

Voir comment ça marche

Questions de relance à prévoir

  • Quand prefetch_related est-il plus lent qu'une jointure ?
  • Que changent only et defer ici ?
  • Comment attraperiez-vous cela en revue de code ?

Autres questions pour Développeur Python

Votre recruteur posera sa propre version de celle-ci. Collez votre véritable fiche de poste dans le Question Predictor gratuit et obtenez les 20 questions que ce poste a le plus de chances de poser, avec ce que chacune cherche vraiment à sonder.

Prédire mes questions

Répétez les questions difficiles avant qu'on vous les pose

Entraînez-vous avec un copilote en direct, puis présentez-vous prêt. Un Session Pass à $29 vous accompagne pendant l'entretien, sans abonnement et sans engagement.

Obtenir GhostPilot