Startseite / Artikel / Sieben Anfänger-Aufgaben zum Programmieren mit Node.js und Express, gelöst und erklärt

Sieben Anfänger-Aufgaben zum Programmieren mit Node.js und Express, gelöst und erklärt

Arbeiten Sie an sieben typischen Interviewaufgaben für Junior-Entwickler mit Node.js – von Express-Routen und Middleware über Fehlerbehandlung, Umkehrung von Zeichenketten sowie Erkennung von Duplikaten – und lernen Sie, jede davon zu erklären.

1640 Wörter

Bei Junior-Interviews zu Node.js und Express dreht sich selten um clevere Algorithmen. In der Regel erhält man kurze Aufgaben wie das Erstellen einer Route, das Schreiben eines Middleware-Funkts oder das Aufräumen eines Arrays, während der Interviewer beobachtet, wie man argumentiert und ob man erklären kann, warum der Code funktioniert. Die sieben untenstehenden Aufgaben decken die häufigsten Themen ab – jede mit einer funktionierenden Lösung, einer Erklärung der wichtigsten Zeilen sowie weiteren Punkten, die ein echtes Verständnis zeigen.

Aufgabe 1: Erstellen Sie eine einfache GET-Route

Eine klassische Aufwärmübung: „Erstellen Sie einen GET-Endpunkt unter /, der mit Hello World antwortet.“ Die Lösung erstellt eine Express-Anwendung, registriert einen Handler für den Root-Pfad und beginnt mit dem Zuhören auf einer Portnummer.

import express from "express";

const app = express();

app.get("/", (req, res) => {
    res.status(200).send("Hello World");
});

app.listen(3000, () => {
    console.log("Server running on port 3000");
});

Weil es import verwendet, benötigt das Projekt den Eintrag "type": "module" in package.json oder eine .mjs-Erweiterung.

Lese die Route Zeile für Zeile

Der Aufruf von app.get() registriert einen Handler, der nur auf GET-Anfragen reagiert:

app.get("/", (req, res) => {

Das erste Argument, /, ist der Pfad. Die Callback-Funktion erhält req, das die eingehende Anfrage beschreibt, sowie res, das zur Erstellung der Antwort verwendet wird.

Die Antwort selbst wird hier erzeugt:

res.status(200).send("Hello World");

status(200) setzt den Statuscode (200 ist der Standard, doch explizit zu sein macht die Codestruktur verständlicher), und send() schreibt den Inhalt und beendet die Antwort.

Zuletzt wird der Server gestartet:

app.listen(3000, () => {

Dies bindet die Anwendung an Port 3000; der Callback wird ausgelöst, sobald der Server Verbindungen annimmt. Reale Dienste lesen in der Regel den Port aus process.env.PORT.

Wie man es ausdrückt

"app.get() registriert eine Route für GET-Anfragen. Wenn ein Client / aufruft, führt Express den Callback aus, der mit Status 200 und „Hello World“ antwortet."

Aufgabe 2: Schreiben Sie ein Middleware für die Protokollierung von Anfragen

Nächste Anweisung: „Erstellen Sie ein Middleware, das jede eingehende Anfrage protokolliert.“ Ein Middleware ist eine Funktion mit der Signatur (req, res, next). Diese gibt Methode und URL aus und übergibt anschließend die Kontrolle weiter; app.use() wendet sie auf alle nach ihr registrierten Routen an.

const logger = (req, res, next) => {
    console.log(`${req.method} ${req.url}`);
    next();
};

app.use(logger);

Jede Anfrage durchläuft die Kette in der Reihenfolge, bevor ein Routenhandler antwortet:

Client
  ↓
Request
  ↓
Logger Middleware
  ↓
Route Handler
  ↓
Response

Die wichtigste Zeile ist die letzte innerhalb der Funktion:

next();

next() teilt Express mit, dass dieser Schritt abgeschlossen ist und der nächste Middleware oder die nächste Route ausgeführt werden sollte. Wenn man das vergisst, hängt die Anfrage, bis der Client eine Zeitüberschreitung verursacht – das ist eine häufig gestellte Frage. Eine Alternative besteht darin, die Anfrage durch Senden einer Antwort zu beenden, wie es ein Authentifizierungs-Middleware tut, wenn ein fehlendes Token abgelehnt wird.

Wie man es ausdrückt

"Middleware erhält die Anfrage, die Antwort sowie next. Es kann die Anfrage prüfen oder ändern und anschließend entweder antworten oder next() aufrufen, um die Kontrolle weiterzugeben."

Aufgabe 3: Asynchrone Aufgaben in einer Route verarbeiten

Echte Endpunkte warten auf Datenbanken und andere APIs, daher ist die Frage „Wie handhabt man eine asynchrone Operation in Express?“ zu erwarten. Eine solide Antwort ist ein async-Handler mit try/catch:

app.get("/users", async (req, res, next) => {
    try {
        const users = await getUsers();
        res.status(200).json(users);
    } catch (error) {
        next(error);
    }
});

Die entscheidende Zeile ist await:

const users = await getUsers();

Dies pausiert den Handler, bis getUsers() abgeschlossen ist, ohne andere Anfragen zu blockieren. Wenn die Promise abgelehnt wird, wird der catch-Block ausgeführt:

catch (error) {
    next(error);
}

next(error) leitet den Fehler an das Fehlerbehandlungs-Middleware aus Aufgabe 5 weiter. Hinweis: Express 4 fängt abgelehnte Promises aus async-Handlern nicht auf, weshalb try/catch dort unerlässlich ist, während Express 5 sie automatisch weiterleitet. Weitere Informationen finden Sie unter Building production-grade error handling in Node.js apps.

Aufgabe 4: Skizzieren Sie die CRUD-Endpunkte

CRUD steht für Create, Read, Update und Delete – die vier grundlegenden Datenoperationen, wobei jede einer HTTP-Methode zugeordnet ist. Stubs für eine users-Ressource:

app.post("/users", (req, res) => {
    res.status(201).send("User created");
});

app.get("/users", (req, res) => {
    res.status(200).send("Users");
});
app.put("/users/:id", (req, res) => {
    res.status(200).send("User updated");
});
app.delete("/users/:id", (req, res) => {
    res.status(200).send("User deleted");
});

Die Erstellung gibt 201 Created zurück, und die Routen für einzelne Benutzer nehmen einen :id-Parameter entgegen, der aus req.params.id gelesen wird. Anstatt sich die Zeilen auswendig zu merken, sollten Sie wissen, was jede Methode bedeutet:

POST   → Create
GET    → Read
PUT    → Update
DELETE → Delete

Seien Sie auf PUT versus PATCH vorbereitet: PUT ersetzt traditionell die gesamte Ressource, während PATCH eine teilweise Änderung vornimmt.

Wie man es ausdrückt

"CRUD umfasst die vier grundlegenden Datenoperationen. Im REST-Prinzip erstellt POST, liest GET, aktualisiert PUT oder PATCH und löscht DELETE."

Aufgabe 5: Fehlerbehandlung zentralisieren

Die Fehlerbehandlung folgt oft auf Aufgabe 3. Beginnen Sie mit einer fehlerhaften Route, die den Fehler weiterleitet:

app.get("/", (req, res, next) => {
    try {
        throw new Error("Something went wrong");
    } catch (error) {
        next(error);
    }
});

Fügen Sie anschließend einen Fehlerhandler hinzu, der protokolliert und eine allgemeine 500-Antwort zurückgibt:

app.use((err, req, res, next) => {
    console.error(err.message);
    res.status(500).json({
        message: "Internal Server Error"
    });
});

Was diese Funktion besonders macht, ist ihre Signatur:

(err, req, res, next)

Express erkennt Fehlerhandler anhand ihrer vier deklarierten Parameter in der Reihenfolge err, req, res, next; sie werden nur ausgeführt, wenn ein Fehler übergeben wurde. Registrieren Sie den Handler nach Ihren Routen und vermeiden Sie es in der Produktion, err.message an die Clients zu senden. Der Ablauf:

Route
  ↓
Error occurs
  ↓
catch(error)
  ↓
next(error)
  ↓
Error middleware
  ↓
500 Response

Ist next() im Fehlerhandler erforderlich?

Nicht, wenn der Handler die Antwort selbst sendet:

app.use((err, req, res, next) => {
    console.error(err.message);
    res.status(500).send("Internal Server Error");
});

next muss dennoch deklariert werden, denn mit drei Parametern behandelt Express die Funktion als gewöhnliches Middleware.

Aufgabe 6: Eine Zeichenkette umkehren

Einige Fragen beziehen sich auf reines JavaScript: „Umkehren Sie den String hello.“ Die übliche One-Liner-Lösung verknüpft drei Methoden miteinander:

const str = "hello";
const reversed = str.split("").reverse().join("");
console.log(reversed);

Es wird ausgegeben:

olleh

Was jede Schritt tut

Durch Splitting erhalten wir die Zeichen:

str.split("")

Das Ergebnis ist ein Array:

["h", "e", "l", "l", "o"]

Anschließend wird die Reihenfolge vor Ort umgekehrt:

.reverse()

Dadurch entsteht:

["o", "l", "l", "e", "h"]

Schließlich werden die Zeichen ohne Trennzeichen zusammengefügt:

.join("")

So entsteht der umgekehrte String:

"olleh"

Eine gängige Variante: „Machen Sie es jetzt ohne reverse().“ Schleifen Sie vom letzten Index bis null abwärts:

const str = "hello";
let reversed = "";
for (let i = str.length - 1; i >= 0; i--) {
    reversed += str[i];
}
console.log(reversed);

Sowohl Ansätze sind linear. Zu beachten: split("") und Indexierung arbeiten mit UTF-16-Code-Einheiten, wodurch Emojis in Teile zerlegt werden; [...str] hingegen teilt nach Codepunkten auf.

Aufgabe 7: Finden Sie Duplikate in einem Array

Noch ein Favorit: „Geben Sie Werte zurück, die mehrmals vorkommen.“ Gegeben:

const numbers = [1, 2, 3, 2, 4, 3, 5];

Das erwartete Ergebnis ist:

[2, 3]

Verwenden Sie zwei Set-Objekte, eines für bereits gesehene Werte und eines für bestätigte Duplikate:

const numbers = [1, 2, 3, 2, 4, 3, 5];
const seen = new Set();
const duplicates = new Set();
for (const number of numbers) {
    if (seen.has(number)) {
        duplicates.add(number);
    } else {
        seen.add(number);
    }
}
console.log([...duplicates]);

Beim Ausführen wird folgendes protokolliert:

[2, 3]

Warum zwei Sets funktionieren

seen speichert jeden übergebenen Wert. Ein erster Auftreten wird dort hinzugefügt:

seen.add(number);

Ein Wiederholungsauftritt führt dazu, dass diese Überprüfung erfolgreich ist:

if (seen.has(number))

Dann gelangt der Wert in duplicates, und da ein Set Wiederholungen ignoriert, wird er nur einmal gemeldet. Suchvorgänge dauern nahezu konstante Zeit, sodass die Lösung linear und nicht durch quadratische verschachtelte Schleifen geprägt ist. Um Vorkommen zu zählen, verwenden Sie einen Map.

Gehen Sie vor dem Tippen Ihrer Lösung Ihren Ansatz durch

Die wichtigste Gewohnheit ist es, Ihren Plan vor dem Schreiben des Codes zu erklären, denn die Interviewer bewerten sowohl das Denkvermögen als auch die Ergebnisse. Für die Duplikatenaufgabe beginnen Sie mit etwas wie folgendem:

"Der Plan besteht aus einer Menge bereits gesehener Werte. Während der Schleife werden alle bereits vorhandenen Werte in eine zweite Menge mit Duplikaten gelegt, wodurch jede Einzelheit einzigartig bleibt."

Dann schreiben Sie den Code. Dadurch wird nachgewiesen, dass Sie verstehen und nicht nur auswendig lernen, und es ermöglicht dem Interviewer, Sie frühzeitig in die richtige Richtung zu lenken.

Vorbereitungs-Checkliste

Vor einem Interview zu Node.js oder Express sollten Sie sicherstellen, dass Sie folgende Dinge mühelos können:

  • Routen definieren und die Rollen von req sowie res erläutern
  • app.use() verwenden und eigene Middleware schreiben
  • Erläutern, was next() bewirkt und was passiert, wenn es fehlt
  • Behandle asynchrone Aufgaben mit async/await, try/catch und next(error)
  • Schreibe einen vierparameterigen Fehlerhandler und registriere ihn nach den Routen
  • Übersetze CRUD-Operationen in HTTP-Methoden und geeignete Statuscodes
  • Manipuliere Zeichenketten und Arrays mit grundlegenden JavaScript-Methoden
  • Wähle zwischen Set und Map für Abfragen und Zählungen
  • Beschreibe deinen Ansatz während des Programmierens
  • Verwandte Literatur

  • Abstimmung von Zeittypen auf echte Datenaufgaben: Sieben Beispiele — Bearbeiten Sie sieben alltägliche Aufgaben zu Datums- und Zeitangaben mithilfe von JavaScript Temporal, von einfachen Datumsangaben und Monatsüberschreitungen bis hin zu Zeitzonen, DST-Arithmetik und Validierung.
  • Vorbereitung auf Interviews zu Node.js und Express: 70 Fragen mit genauen Antworten — Eine strukturierte Übersicht von 70 Interviewfragen zu Node.js und Express, vom Event Loop und Streams über Middleware, Sicherheit bis hin zur Skalierbarkeit, inklusive Korrekturen zu gängigen Antworten.