Praxisnahe, zeitlose Guides fuer Entwickler. Jeder baut auf echten Befehlen und lauffaehigen Beispielen auf und sagt klar, wann man das behandelte Werkzeug nicht einsetzen sollte.
Unten steht alles, neueste zuerst.
Praxisnahe, zeitlose Guides fuer Entwickler. Jeder baut auf echten Befehlen und lauffaehigen Beispielen auf und sagt klar, wann man das behandelte Werkzeug nicht einsetzen sollte.
Unten steht alles, neueste zuerst.
Melden Sie einen Nutzer in einer session-basierten App ab, vergisst der Server ihn bei der nĂ€chsten Anfrage. Melden Sie ihn in einer JWT-basierten App ab, bleibt das Token, das er besitzt, gĂŒltig, bis es ablĂ€uft â es sei denn, Sie haben einen zusĂ€tzlichen Mechanismus dafĂŒr gebaut. Dieser Unterschied ist die eigentliche Entscheidung hinter âJWT vs. Session". Der Rest folgt daraus. Was eine Session tatsĂ€chlich speichert Eine Session hĂ€lt den Zustand des Nutzers auf dem Server und gibt dem Browser nur einen SchlĂŒssel zum Nachschlagen. ...
Suchen Sie âWelpeâ in einem System, das nur Stichwörter abgleicht, und ein Dokument ĂŒber Hundetraining taucht nicht auf, obwohl jeder, der beide liest, sie als eng verwandt bezeichnen wĂŒrde. Stichwortsuche vergleicht Zeichenketten. Sie weiĂ nicht, dass âWelpeâ und âHundâ fast dasselbe bedeuten. Embeddings lösen genau das. Sie verwandeln einen Text in eine Liste von Zahlen, einen Vektor, der so platziert wird, dass Texte mit Ă€hnlicher Bedeutung nah beieinander landen, unabhĂ€ngig davon, welche Wörter verwendet werden. ...
Packen Sie einen fetch()-Aufruf in ein try/catch, rufen Sie einen Endpunkt auf, der mit 404 antwortet, und der catch-Block lĂ€uft nie. Das Promise wird aufgelöst. res.json() parst, was auch immer der Server zurĂŒckgeschickt hat, oft ein Fehler-Payload wie {"error": "user not found"}, und der Rest der Funktion behandelt es als den angeforderten Datensatz. Keine Exception, keine Konsolenwarnung. Die falschen Daten wandern weiter, bis etwas anderes daran zerbricht. 1 2 3 4 5 6 7 8 9 async function getUser(id) { try { const res = await fetch(`/api/users/${id}`); const user = await res.json(); return user; // bei einem 404 ist das { error: "user not found" } } catch (err) { console.error('Failed to load user:', err); } } Dieses catch greift nur bei einer Anfrage, die nie abgeschlossen wird. Alles andere braucht eine PrĂŒfung, die Sie selbst schreiben mĂŒssen. ...
Eine Funktion, die sich selbst aufruft, hat eine maximale Tiefe, und die ist kleiner, als die meisten erwarten: 1.000 Aufrufe in CPython standardmĂ€Ăig, etwa 10.000 bis 15.000 in Node und in Browser-Engines, je nachdem, wie viel jeder Frame belegt. Wird dieses Limit ĂŒberschritten, wird das Programm nicht einfach langsamer. Es stĂŒrzt ab. Python löst RecursionError: maximum recursion depth exceeded aus; JavaScript löst RangeError: Maximum call stack size exceeded aus. Beide Fehler haben die gleiche Ursache, und wenn Sie sie einmal verstanden haben, wissen Sie, wann Rekursion das richtige Werkzeug ist und wann sie zum Risiko wird. ...
Sie bauen ein Dashboard: Header, Sidebar, Hauptbereich, Footer. Sie greifen zu Flexbox, weil das nun mal das Layout-Werkzeug ist, das Sie kennen â und zwanzig Minuten spĂ€ter stapeln sich drei verschachtelte display: flex-Container, die Sidebar hĂ€lt ihre Breite nur mit einer willkĂŒrlichen Pixelzahl, und der Footer schwebt mitten auf der Seite, sobald der Inhalt kurz ist. Das ist kein Flexbox-Bug. Sie wenden ein eindimensionales Werkzeug auf ein zweidimensionales Problem an. ...
Stellen Sie go vor einen Funktionsaufruf, und diese Funktion lĂ€uft nebenlĂ€ufig zum Rest des Programms, verwaltet von der Go-Runtime statt vom Betriebssystem. Eine zu starten ist der einfache Teil. Der schwierige Teil ist, zwei Goroutinen ein Ergebnis ĂŒbergeben zu lassen, ohne dass sie sich gegenseitig den Zustand kaputt machen, und genau das ist die Aufgabe von Channels. Was ist eine Goroutine? Eine Goroutine ist eine Funktion, die unabhĂ€ngig von der Funktion lĂ€uft, die sie gestartet hat, verwaltet von der Go-Runtime und nicht vom Betriebssystem. Ein OS-Thread reserviert ein Megabyte oder mehr Stack und kostet den Kernel echte Zeit fĂŒr die Planung. Eine Goroutine startet mit einem Stack von etwa 2 KB, der bei Bedarf wĂ€chst, und die Runtime multiplext viele Goroutinen auf eine Handvoll OS-Threads. Tausende davon zu starten ist normal. ...
Eine Klasse, die einen Nutzer in der Datenbank speichert, ihm eine Willkommens-E-Mail schickt und eine Quittung formatiert, ist eine Ănderung davon entfernt, zwei Funktionen zu zerstören, mit denen sie nichts zu tun hat. Fassen Sie das E-Mail-Template an, riskieren Sie den Schreibzugriff auf die Datenbank. Fassen Sie das Quittungslayout an, riskieren Sie die E-Mail. SOLID ist der Sammelbegriff fĂŒr fĂŒnf Regeln gegen genau diese Art von Verknotung, jede aus einem anderen Blickwinkel. Sie teilen eine Idee: Eine Klasse soll nur einen Grund haben, sich zu Ă€ndern, und der Rest des Codes soll davon abhĂ€ngen, was etwas zu tun verspricht, nicht davon, wie es das tut. ...
Zwei Anfragen treffen im Abstand von einer halben Millisekunde auf denselben â100⏠abhebenâ-Endpunkt. Das Konto hat 150âŹ. Beide Anfragen lesen diesen Kontostand, beide sehen genug Guthaben, beide werden genehmigt, beide ziehen 100⏠ab. Das Konto landet bei -50âŹ, und kein Codepfad hĂ€tte das zulassen dĂŒrfen. Das ist eine Race Condition: Das Ergebnis hĂ€ngt davon ab, welche Operation zufĂ€llig zuerst fertig wird, und âzuerstâ war nie eine Entscheidung, die der Code getroffen hat. ...
Ein Suchfeld, das bei jedem Tastendruck eine Anfrage auslöst, schickt fĂŒr âredisâ fĂŒnf Anfragen, von denen vier veraltet sind, bevor die Antwort zurĂŒckkommt. Ein scroll-Handler, der das Layout neu berechnet, lĂ€uft hunderte Mal pro Sekunde und lĂ€sst die Seite stottern. Beide FĂ€lle haben dasselbe Problem: Das DOM-Event feuert viel öfter, als der Handler laufen muss. Debounce und Throttle lösen das auf zwei unterschiedliche Arten. Was Debounce macht und was Throttle macht Debounce wartet, bis das Event fĂŒr eine festgelegte Zeit nicht mehr feuert, und lĂ€uft dann einmal. Jeder neue Aufruf setzt die Uhr zurĂŒck. Hört das Event nie auf, lĂ€uft die Funktion nie. Ein Suchfeld ist der klassische Fall: warten, bis der Nutzer beim Tippen pausiert, und dann eine Anfrage fĂŒr das zuletzt Eingegebene schicken. ...
Was ein Decorator wirklich mit Ihrer Funktion macht Sie wollen jede Funktion zeitlich messen, die eine langsame externe API aufruft. Sie können time.perf_counter()-Aufrufe in jede einzelne einfĂŒgen, oder die Messung einmal schreiben und ĂŒberall anwenden. Ein Decorator ist die zweite Option: eine Funktion, die eine andere Funktion nimmt, sie in zusĂ€tzliches Verhalten einwickelt und die eingewickelte Version unter dem ursprĂŒnglichen Namen zurĂŒckgibt. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import time def timed(func): def wrapper(*args, **kwargs): start = time.perf_counter() result = func(*args, **kwargs) elapsed = time.perf_counter() - start print(f"{func.__name__} took {elapsed:.3f}s") return result return wrapper @timed def fetch_price(ticker): time.sleep(0.2) # Platzhalter fĂŒr einen Netzwerkaufruf return 142.50 fetch_price("AAPL") # fetch_price took 0.201s @timed ĂŒber def fetch_price ist die Kurzform von fetch_price = timed(fetch_price). Python ruft timed einmal auf, direkt nachdem fetch_price definiert wurde, und bindet den Namen fetch_price neu an das, was timed zurĂŒckgibt. Das ist alles, was das @ tut. ...