Interviewfrage für Full-Stack-Entwickler

Was ist das N-plus-eins-Query-Problem und wie behebst du es?

Worauf der Interviewer abzielt, wie du deine Antwort aufbaust und ein gesprochenes Beispiel zum Anpassen.

Kurzantwort

Du führst eine Query aus, um eine Liste zu holen, läufst dann über die Zeilen und setzt pro Zeile eine weitere Query ab, aus 200 Posts werden also 201 Roundtrips. Behebe es, indem du die verwandten Zeilen in einem Durchgang lädst: ein Join, eine IN-Query nach Parent-Id oder ein Batching-Loader, der Ids innerhalb eines Request-Ticks sammelt. Das Erkennungsmerkmal ist Latenz, die linear mit der Ergebnisanzahl wächst, während jede einzelne Query schnell aussieht.

Warum Interviewer das fragen

Das ist der mit Abstand häufigste Performance-Bug in ORM-gestützten Anwendungen, der Interviewer prüft also, ob du ihn in freier Wildbahn erkennen würdest und ihn nicht nur definieren kannst. Er will hören, wie du ihn entdeckst, denn die Queries sehen einzeln gesund aus und nur die Anzahl stimmt nicht. Das Werkzeug zu nennen, mit dem du ihn findest, trennt Leute, die ihn debuggt haben, von Leuten, die darüber gelesen haben.

So baust du deine Antwort auf

  • Definier das Muster mit einer konkreten Anzahl.
  • Beschreib, wie du es in einer laufenden App entdeckst.
  • Gib mindestens zwei Fixes und wann welcher greift.
  • Weise auf die Abwägung hin, alles eager zu laden.

Beispielantwort

Gesprochenes Beispiel, erste Person

Es taucht meistens genau dann auf, wenn jemand eine Liste rendert. Du holst Bestellungen, im Template greifst du dann auf order.customer.name zu, und das ORM setzt still eine Query pro Zeile ab. Einzeln sind das eine halbe Millisekunde, es sieht also nichts kaputt aus, bis die Liste wächst und der Endpoint vier Sekunden braucht. Ich entdecke es, indem ich auf die Query-Anzahl pro Request schaue statt auf die Query-Dauer; die meisten APM-Tools zeigen das direkt, und lokal schalte ich Query-Logging an und zähle. Der Fix hängt von der Form ab. Bei einer einfachen Belongs-to-Beziehung ist Eager Loading oder ein Join in Ordnung. Bei einer Eins-zu-viele-Beziehung, bei der ein Join Zeilen vervielfachen würde, nehme ich lieber eine zweite Query mit einer IN-Klausel und setze im Speicher zusammen. In einer GraphQL-API muss es ein Dataloader sein, weil Resolver keine Ahnung haben, dass sie im Batch aufgerufen werden. Was ich vermeide, ist alles standardmäßig eager zu laden, weil du damit ein Problem gegen das Ziehen der halben Datenbank in den Speicher tauschst.

Steht dieses Vorstellungsgespräch bald an? GhostPilot hört bei deinem Live-Call mit, erkennt die Frage in dem Moment, in dem sie gestellt wird, und bringt dir eine strukturierte Antwort in Echtzeit auf den Bildschirm. Probier es im nächsten Mock aus, oder hol dir einen $29 Session Pass, kein Abo, für den Ernstfall.

So funktioniert es

Nachfragen, mit denen du rechnen solltest

  • Wie würdest du das in der CI fangen, bevor es ausgeliefert wird?
  • Wann ist ein Join schlechter als zwei getrennte Queries?
  • Wie funktioniert Batching quer über einen GraphQL-Resolver-Baum?

Weitere Fragen für Full-Stack-Entwickler

Dein Interviewer stellt seine eigene Version davon. Kopier deine echte Stellenbeschreibung in den kostenlosen Question Predictor und bekomm die 20 Fragen, die diese Rolle am wahrscheinlichsten stellt, samt dem, worauf jede wirklich abzielt.

Meine Fragen vorhersagen

Üb die harten Fragen, bevor sie gestellt werden

Trainier mit einem Live-Copiloten und geh dann vorbereitet rein. Ein $29 Session Pass bringt dich durch das Vorstellungsgespräch, ohne Abo und ohne Bindung.

GhostPilot holen