Es gibt einen Typ von Symfony-Interviewfrage, der kein Signal produziert. “Was tut das final-Keyword an einer Klasse?” “Nennen Sie die vier eingebauten Argument-Resolver.” “Wann wurde das Autowiring-Attribut hinzugefügt?” Das sind Suchanfragen, verkleidet als Fragen. Ein Kandidat kann sich darauf vorbereiten, indem er einen Abend auf der Symfony-Doku-Seite verbringt. Sie sagen Ihnen, wer für das Interview gelernt hat. Sie sagen Ihnen nicht, wer liefern kann.
Wir haben eine Menge Symfony-Interviews geführt, auf beiden Seiten des Tisches, und die Fragen, die die Engineers produziert haben, mit denen wir tatsächlich arbeiten wollten, waren nie Trivia. Es waren Szenarien, Debugging-Walks und Leseübungen. Sie haben die Kandidatin gezwungen, laut über Tradeoffs in echtem Code und echten Systemen nachzudenken, ohne eine einzig richtige Antwort. Ein Senior mit fünf Jahren am Framework gibt eine andere Antwort als eine Junior-Engineerin mit sechs Monaten, und beide Antworten können gut sein. Genau darum geht es.
Das ist das Frage-Set, das wir aktuell nutzen, was jede Frage aufdecken soll und wie eine dünne Antwort im Vergleich zu einer starken Antwort tatsächlich aussieht. Keine davon ist eine Fangfrage. Bei allen wird eine gute Engineerin Spaß am Nachdenken haben, was selbst schon ein nützliches Signal ist.
Warum Trivia die falschen Leute herausfiltert
Vor den Fragen ein Hinweis auf den Failure-Mode, den dieses Set vermeiden soll.
Ein trivia-lastiges Interview filtert auf zwei Dinge: aktuelle Berührung mit dem Framework und Bereitschaft, für Interviews zu lernen. Keines korreliert mit Engineering-Qualität. Wir haben Senior-Architects abgelehnt, die das Release-Datum der jüngsten Symfony-Version nicht nennen konnten, und Engineers eingestellt, die die Autowiring-Syntax in ihren eigenen früheren PRs nachschlagen mussten. Die erste Gruppe konnte einen Event-Bus auf dem Whiteboard neu designen. Die zweite Gruppe konnte bis Freitag funktionierenden Code liefern. Beides war die richtige Entscheidung.
Die Fragen unten versuchen, die Dinge sichtbar zu machen, die tatsächlich zählen, wenn jemand in eine Symfony-Codebasis kommt: wie sie über Tradeoffs argumentiert, wie sie debuggt, wie sie unbekannten Code liest, wie ehrlich sie über das ist, was sie nicht weiß.
Die Fragen
1. “Eine Nutzerin meldet, das Dashboard sei langsam. Wo fangen Sie an?”
Wie eine trivia-artige Antwort klingt. “Ich würde die Stopwatch-Komponente hinzufügen, mit dem Symfony Profiler profilen, die Doctrine-Queries prüfen.” Die Kandidatin nennt Werkzeuge, ohne zu erklären, wann sie zu jedem greifen würde.
Wie eine starke Antwort klingt. Die Kandidatin stellt zuerst Gegenfragen. Langsam für eine Person oder für alle? Immer langsam oder sporadisch? Langsam beim ersten Laden oder bei jedem? Dann skizziert sie einen Pfad: reproduzieren, eingrenzen (ist es der Controller, eine Query, ein Drittanbieter-Call, das Template-Rendering, der Asset-Payload), mit Messung bestätigen, das engste Ding fixen, das das Symptom erklärt. Sie nennt Werkzeuge, wenn sie sie braucht, nicht vorher. Sie erwähnt, dass die Antwort “nicht langsam, fühlt sich nur langsam an” sein könnte und dass sie das bei der Nutzerin abklären würde, bevor sie etwas annimmt.
Was es verrät. Ob die Kandidatin tatsächlich Produktionssysteme debuggt hat oder nur über Debugging gelesen hat. Die starke Antwort hat die Form einer Engineerin, die schon falsch lag über die Ursache und gelernt hat, zuerst Evidenz zu sammeln.
2. “Erklären Sie, was zwischen einem Browser, der /login aufruft, und einer etablierten Session passiert.”
Wie eine dünne Antwort klingt. “Es trifft die Security-Firewall, der Form-Login-Authenticator läuft, die Userin wird geladen, eine Session wird erzeugt.” Eine korrekt klingende Bullet-Liste ohne Tiefe.
Wie eine starke Antwort klingt. Die Kandidatin trackt es: Kernel bootet, Request kommt rein, Router matcht, die Security-Firewall-Konfiguration bestimmt, welcher Authenticator läuft, der Authenticator liest Credentials aus dem Request, der User-Provider lädt die Userin, der Passwort-Hasher verifiziert, der Token wird erzeugt und ins Token-Storage gelegt, die Session wird geschrieben, die Response wird gebaut, das Session-Cookie wird auf dem Weg nach draußen gesetzt, der Browser schickt es beim nächsten Request zurück. Sie nennt, wo das schiefgehen kann: Der User-Provider kann der falsche sein, wenn eine Firewall-Konfiguration falsch geordnet ist, der Session-Handler kann falsch konfiguriert sein (zum Beispiel File-Storage in Produktion, obwohl Redis erwartet war), dem Cookie kann das Secure-Flag fehlen, wenn ein Proxy falsch konfiguriert ist.
Was es verrät. Tiefe über den Stack hinweg. Eine Kandidatin, die den Login-Flow erzählen kann, kann wahrscheinlich jeden Flow erzählen.
3. “Wann würden Sie ein Value Object einem typisierten Skalar vorziehen?”
Wie eine dünne Antwort klingt. “Wenn man Validierung kapseln will.” Ein Bullet, keine Beispiele.
Wie eine starke Antwort klingt. Die Kandidatin gibt mehrere Fälle. Email und Geld sind die klassischen. Sie erklärt, dass sich das Value Object lohnt, wenn der Typ an vielen Stellen genutzt wird, wenn Validierung nicht trivial ist, wenn der Typ eigenes Verhalten hat (Gleichheit, Vergleich, Formatierung), oder wenn man eine ungültige Instanz schlicht verbieten will. Sie kontert mit Fällen, in denen ein Value Object überzogen ist: ein einzelner Use-Site, ein Primitiv, das bereits auf Datenbankebene das Constraint hat, eine Stelle, an der der Typ ehrlich nur ein String ist. Sie erwähnt vielleicht die Kosten: mehr Dateien, mehr Allokationen, Reibung mit Libraries, die Skalare erwarten.
Was es verrät. Ob die Kandidatin eine Position zu Design hat oder nur aus Blogposts memorisierte Muster. Beide Extreme (immer Value Objects, nie Value Objects) sind rote Flaggen.
4. “Ihre Messenger-Queue staut sich. Was prüfen Sie, in welcher Reihenfolge?”
Wie eine dünne Antwort klingt. “Mehr Worker hinzufügen.” Die Antwort, die das Symptom löst, ohne die Ursache zu diagnostizieren.
Wie eine starke Antwort klingt. Die Kandidatin triagiert. Werden Messages überhaupt konsumiert, oder ist der Worker gestorben? Werden sie konsumiert, aber langsam, oder failen sie und gehen in den Retry? Wächst die Queue, weil der Konsum gestoppt hat oder weil die Produktion gespikt ist? Sie nennt, wo sie nachschauen würde: Worker-Logs, Dead-Letter-Queue, die Rate der Message-Produktion auf der Producer-Seite, jeder externe Service, von dem der Handler abhängt. Erst nach der Diagnose erwähnt sie das Skalieren von Workern, und sie merkt an, dass Skalieren ohne Verständnis der Ursache einen langsamen Drittanbieter-Call schlimmer machen kann (mehr parallele Calls, mehr Rate-Limiting, mehr Failure).
Was es verrät. Ob die Kandidatin eine Message-Queue in Produktion gefahren hat. Die “mehr Worker”-Antwort ist die Berufseinsteigerinnen-Antwort. Die “was hat sich geändert und warum”-Antwort ist die On-Call-Antwort.
5. “Lesen Sie diesen Diff laut vor und sagen Sie mir, was Sie besorgt.”
Geben Sie ihr einen bewusst schlechten PR. So etwas wie einen Controller, der eine rohe nutzerseitige ID nimmt, sie direkt in ein Doctrine-Repository gibt, die Entity zurückgibt und sie ohne Autorisierungs-Check rendert. Fügen Sie ein paar stilistische Probleme hinzu, ein echtes Security-Problem, ein Performance-Problem.
Wie eine dünne Antwort klingt. Die Kandidatin fixt den Stil (“das sollte final readonly sein”, “der Logger sollte im Konstruktor zuletzt stehen”). Sie übersieht die Autorisierungslücke.
Wie eine starke Antwort klingt. Die Kandidatin triagiert. Sie beginnt mit dem Security-Problem (jede Person kann jede beliebige Entity-ID anfragen und sie zurückbekommen). Sie nennt das Performance-Problem (das wird im Template N+1en). Sie erwähnt die Stilprobleme zuletzt, als Politur, nicht als Headline. Sie markiert, was sie im Diff nicht sehen kann (gibt es eine vorgelagerte Firewall, die das schon absichert? was macht das Template tatsächlich mit der Entity?) und fragt nach dem fehlenden Kontext, statt etwas anzunehmen.
Was es verrät. Code-Review-Urteilsvermögen. Ob die Kandidatin die richtigen Achsen priorisiert (Security, dann Korrektheit, dann Performance, dann Stil) oder alle Kommentare gleich behandelt. Außerdem, ob sie “ich habe nicht genug Kontext, um sicher zu sein” parallel zu “aber das würde ich fragen” halten kann.
6. “Wann ist es korrekt, das Repository-Muster zu brechen und rohes SQL zu schreiben?”
Wie eine dünne Antwort klingt. “Nie, das ORM macht alles.” Oder, ebenso dünn: “Immer, ORMs sind langsam.”
Wie eine starke Antwort klingt. Die Kandidatin gibt die tatsächlichen Fälle. Reporting- und Analytics-Queries, die viele Tabellen in Formen joinen, die das ORM schlecht hydratisiert. Bulk-Updates, die das ORM Zeile für Zeile machen würde. Window-Funktionen, CTEs oder vendor-spezifische Features, die das ORM nicht gut modelliert. Sie nennt die Tradeoffs des Direkt-zu-SQL-Wegs: schwerer zu refactoren, keine Typsicherheit auf dem Ergebnis, schwerer zu testen, leichter in SQL-Injection zu rutschen, wenn man schlampt. Sie schlägt vielleicht Mittelwege vor: rohes SQL durch DTOs hydratisieren, DBAL direkt nutzen und gleichzeitig den Entity-Layer für den Schreibpfad halten, das rohe SQL hinter eine Repository-Methode isolieren, damit der Aufrufer trotzdem ein typisiertes Ergebnis bekommt.
Was es verrät. Pragmatismus statt Dogma. Ob die Kandidatin das ORM als Werkzeug mit Passungs-Fenster behandelt oder als Religion.
7. “Sie erben eine Monolith-Codebasis mit 200 Controllern und ohne Tests. Was ist Ihr erster PR?”
Wie eine dünne Antwort klingt. “Tests für die Controller schreiben.” Eine Nicht-Antwort, die das Ausmaß des Problems ignoriert.
Wie eine starke Antwort klingt. Die Kandidatin lehnt das Framing ab. Sie fragt, wofür die Codebasis da ist, was aktuell kaputt ist, was die Schmerzpunkte des Teams sind. Dann schlägt sie einen kleinen, sicheren ersten PR vor: vielleicht eine CI-Pipeline, die php -l, composer validate und einen statischen Analyzer auf niedrigem Level laufen lässt. Oder einen einzelnen Charakterisierungstest um einen kritischen Pfad, mit dem expliziten Ziel, diesen Pfad anschließend sicher refactoren zu können. Sie vermeidet bewusst die Versuchung, mit einem Big Bang anzufangen (“die Test-Suite neu schreiben”, “Hexagonale Architektur einführen”, “DDD hinzufügen”). Sie erwähnt, dass es beim ersten PR teilweise darum geht, Vertrauen vom bestehenden Team zu verdienen, nicht nur um technischen Wert.
Was es verrät. Ob die Kandidatin tatsächlich einen Monolithen geerbt hat oder nur Greenfield gebaut hat. Die Greenfield-Engineerin will aufräumen. Die Legacy-Engineerin will sicher landen und einen Brückenkopf bauen.
8. “Erzählen Sie von einer Sache, die Sie ausgeliefert haben und die Produktion gebrochen hat. Was haben Sie getan?”
Wie eine dünne Antwort klingt. “Ich habe Produktion eigentlich nie gebrochen.” Entweder ist die Kandidatin so junior, dass das stimmt (fair), oder sie weicht aus.
Wie eine starke Antwort klingt. Ein konkreter Incident, erzählt ohne Abwehrhaltung. Was sie ausgeliefert hat, was brach, wie sie es bemerkt hat, was sie als Erstes tat, was sie als Zweites tat, was sie gelernt hat, was sich danach an der Art, wie sie ausliefert, geändert hat. Das Post-Incident-Lernen ist der Teil, der am meisten zählt: Hat die Kandidatin einen Prozess geändert, ein Runbook geschrieben, einen Check eingezogen, sich organisatorisch für etwas eingesetzt?
Was es verrät. Ehrlichkeit, Verantwortung, Lernen. Wir stellen niemanden ein, der uns nichts über ein Scheitern erzählen kann. Der Job wird Scheitern produzieren; wir müssen wissen, wie die Kandidatin das verarbeitet.
9. “Wo passt final readonly class in Symfony, und wo nicht?”
Wie eine dünne Antwort klingt. “Funktioniert für alles, sollte man immer nutzen.” Selbstbewusst und falsch.
Wie eine starke Antwort klingt. Die Kandidatin trennt aktuelle Fakten von alter Proxy-Folklore. In PHP 8.4+ und aktuellem Symfony unterstützen lazy Services final und readonly; aktuelles Doctrine kann mit nativen Lazy Objects auch final oder read-only Entities nutzen. Dann nennt sie die echten Grenzen: readonly passt schlecht zu einem Service, der Request-State cacht und in reset() leeren muss, zu mutierbaren Entities oder DTOs, die nach der Konstruktion befüllt werden, oder zu Code, den eine Library oder ein Test-Double auf einem älteren Stack wirklich subclassen muss. Sie erwähnt, dass die richtige Regel lautet: “final readonly als Default für stateless Services und Value Objects nutzen, readonly weglassen, wenn das Objekt einen legitimen mutierbaren Lifecycle hat, und final nur weglassen, wenn Erweiterung Teil des Vertrags ist.”
Was es verrät. Ob die Kandidatin Faustregeln aktualisieren kann, wenn sich die Plattform ändert, und ob sie den Unterschied zwischen stateless Services, mutierbaren Domain-Objekten und Framework-Integrationspunkten versteht.
10. “Wie würden Sie zwischen Symfony Workflow und einer Status-Spalte entscheiden?”
Wie eine dünne Antwort klingt. “Workflow ist immer besser, visualisiert die State Machine.” Oder “Status-Spalte, Workflows sind überzogen.” Eine Ein-Bullet-Vorliebe.
Wie eine starke Antwort klingt. Die Kandidatin nennt die Dimensionen. Anzahl der Zustände (ein Boolean braucht keinen Workflow). Anzahl der Übergänge (ein strikt linearer Flow auch nicht). Existenz von Guards und Seiteneffekten beim Übergang (hier verdient Workflow sich seinen Platz). Ob das Business sich tatsächlich für das Diagramm interessiert (Workflows produzieren eine Visualisierung, die Nicht-Engineers lesen können). Sie erwähnt, dass die Wahl reversibel ist und dass es ein guter Weg ist, mit einer Status-Spalte zu starten und auf Workflow zu migrieren, wenn die Regeln komplex werden; die umgekehrte Richtung ist meist unnötiges Hin und Her.
Was es verrät. Ob die Kandidatin der Versuchung widerstehen kann, Architektur um ihrer selbst willen einzuführen. Die “Workflow ist immer besser”-Antwort korreliert oft mit Codebasen, die für ein Flag mit zwei Zuständen eine State-Machine-Library haben.
Was Sie mit diesen Fragen weglassen
Sie lassen die Dinge weg, die Sie in fünf Minuten nach dem Interview verifizieren können, indem Sie ihren öffentlichen Code anschauen oder eine gepaarte Übung laufen lassen. Sie müssen nicht fragen, ob sie weiß, wie man einen Service in YAML versus Attributen verdrahtet; das sehen Sie. Sie müssen nicht fragen, ob sie eine funktionierende Route schreiben kann; das sehen Sie auch. Das Interview ist für die Dinge, die Sie nicht durch das Lesen von Code sehen können: Urteilsvermögen, Kalibrierung, Kommunikation, Reaktion auf Ambiguität.
Wenn die Kandidatin die obigen Fragen besteht und Sie noch ein Code-Signal wollen, geben Sie ihr eine kleine gepaarte Übung auf einem echten Stück Code aus Ihrer Codebasis (mit sensiblen Teilen geschwärzt). Schauen Sie zu, wie sie ein unbekanntes Repo navigiert, wo sie zuerst hinschaut, was sie nachfragt. Das ist nützlicher als jeder abstrakte Coding-Test.
Wie Sie scoren
Wir scoren Antworten nicht richtig oder falsch. Wir scoren sie nach jeder Frage auf drei Achsen:
- Hat die Kandidatin sich auf das Problem eingelassen, oder eine memorisierte Antwort aufgesagt? Aufsagen ist eine rote Flagge, auch wenn das Aufgesagte korrekt ist.
- Hielt sie Unsicherheit gut aus? “Ich weiß es nicht, aber ich würde X prüfen” ist eine starke Antwort. “Es ist definitiv Y” ohne Einschränkung bei einer Frage, deren richtige Antwort “kommt darauf an” ist, ist eine gelbe Flagge.
- Hat sie zurückgefragt? Starke Kandidatinnen stellen klärende Fragen, weil echtes Engineering meist darum geht, das Problem zu scopen. Kandidatinnen, die ohne Nachfrage in eine Antwort stürzen, beantworten oft die falsche Frage.
Eine Kandidatin, die über den Großteil dieses Sets hinweg starke, evidenzbasierte Antworten gibt, ist meist deutlich interessanter als eine, die trivia-perfekte Antworten ohne Urteilsvermögen liefert.
Eine Anmerkung dazu, was wegfallen sollte
Wenn Sie versucht sind, mehr Fragen hinzuzufügen, lassen Sie zuerst die Trivia-Fragen weg. Trivia nimmt Interview-Zeit von den Fragen, die tatsächlich Signal produzieren. Wir haben alle “Nennen-Sie-dieses-Ding”-Fragen aus unserem Prozess entfernt, und die Einstellungsentscheidungen sind sowohl schneller als auch sicherer geworden. Die Kandidatinnen, die bei Trivia gut gewesen wären, sind hier auch gut. Die, die sich hinter Trivia versteckt hätten, werden früher herausgefiltert, was genau das ist, was wir wollten.
Wenn Sie für ein Symfony-Team einstellen und die aktuelle Pipeline immer wieder Engineers produziert, die im Interview gut wirken und schlecht ausliefern, ist das ein Prozessproblem, kein Kandidat-Versorgungsproblem. Wir helfen Engineering-Verantwortlichen, ihre Interview-Schleife so umzubauen, dass sie Engineers produziert, die tatsächlich in ihrer Codebasis arbeiten können. Die erste Session ist meist ein Teardown der bestehenden Fragen und ein Arbeits-Set, abgestimmt auf die Art Arbeit, die das Team tatsächlich macht.
Referenzen
- Symfony Security: Authenticators: die Framework-Dokumentation für den in Frage 2 referenzierten Login-Flow.
- Symfony Messenger: die Messaging-Komponente aus Frage 4, einschließlich Worker-, Retry- und Failure-Transport-Verhalten.
- Symfony Workflow-Komponente: die Workflow-Komponente aus Frage 10, einschließlich Guards und Marking Store.
- Doctrine ORM: das ORM, dessen Hydration- und Proxying-Constraints in den Fragen 6 und 9 auftauchen.