What I think about...
I enjoyed blogging until around 2020, but these days I no longer have the time for it. Since I use AI to learn about new technologies, algorithms and other dev topics, I pipe the interesting results into this blog. AI-generated posts are marked. I use Claude and Gemma. Translations are AI-generated as well.
Der Trigramm-Algorithmus: Unscharfes Matching ohne Magie
Ein Trigramm besteht aus drei aufeinanderfolgenden Zeichen, und der Vergleich der Trigramm-Mengen zweier Strings liefert einen schnellen, tippfehlertoleranten Ähnlichkeitswert z…
Einen eigenen Data-Fetching-Hook in React bauen
Jede React-Codebasis sammelt irgendwann ein Dutzend fast identischer -Blöcke an, die Daten laden, den Ladezustand verfolgen und Fehler behandeln. Dieses Muster in einen einzigen…
CSS Container Queries: Ein praktischer Leitfaden
Media Queries beantworten eine Frage: Wie groß ist der Viewport? Für die meisten Komponenten ist das die falsche Frage, denn eine Karte, ein Sidebar-Widget oder eine Produktkach…
Wie das Virtual DOM wirklich funktioniert
„Das Virtual DOM macht React schnell" ist einer dieser Sätze, die alle wiederholen, ohne ihn wirklich erklären zu können. Es ist keine Magie, und es ist nicht einmal immer schne…
Web Workers für rechenintensive Aufgaben verstehen
JavaScript läuft auf einem einzigen Thread, was bedeutet, dass eine rechenintensive Aufgabe – ein riesiges JSON-Objekt parsen, ein Bild skalieren, einen Pfadfindungsalgorithmus…
Debouncing und Throttling: Hochfrequente Events in JavaScript zähmen
Früher oder später läuft jeder Frontend-Entwickler gegen dieselbe Wand: ein Scroll-Handler, der hunderte Male pro Sekunde feuert, ein Suchfeld, das bei jedem Tastendruck eine Ne…
Ein einfaches Kommandozeilen-Tool in Node.js schreiben
Die meisten internen CLI-Tools brauchen kein Framework. Ein Skript, das eine Reihe von Dateien umbenennt, eine interne API aufruft oder eine sich wiederholende -Abfolge kapselt,…
Grundlagen der Barrierefreiheit: ARIA ohne Rätselraten
Der häufigste ARIA-Fehler ist nicht, das falsche Attribut zu verwenden – sondern überhaupt zu ARIA zu greifen, wenn ein natives HTML-Element das Problem gratis gelöst hätte. ARI…
Ein praktischer Leitfaden zu Git-Branching-Strategien
Die meisten Teams wählen keine Branching-Strategie – sie erben, was die Gründungsentwickler eben gemacht haben, und es verfestigt sich, bevor jemand fragt, ob es zur tatsächlich…
Eine einfache State Machine in TypeScript bauen
Wer schon einmal eine Komponente mit , , und als getrennten Booleans geschrieben hat, hat vermutlich auch schon einen Bug ausgeliefert, bei dem zwei davon gleichzeitig wahr ware…
Reflows und Repaints: Warum sich deine Seite ruckelig anfühlt
Du misst die Höhe eines Elements mit , setzt damit die Breite eines anderen Elements, liest diese Breite zurück und setzt die Höhe eines dritten – und irgendwie ruiniert diese f…
HTTP-Caching-Header verstehen
Die meisten Performance-Probleme, die Leute mit einem CDN oder einer Caching-Schicht lösen wollen, werden eigentlich gratis von drei HTTP-Headern gelöst, richtig gesetzt, die di…
Ein praktischer Leitfaden zur API-Pagination
Gibt man jede Zeile einer wachsenden Tabelle in einer einzigen Antwort zurück, hat man ein Feature gebaut, das in der Entwicklung problemlos läuft und in Produktion zusammenbric…
Datenbank-Connection-Pooling verstehen
Eine Datenbankverbindung zu öffnen ist teuer: ein TCP-Handshake, Authentifizierung, manchmal TLS-Aushandlung – häufig zig Millisekunden, bevor eine einzige Abfrage läuft. Öffnet…
Deine erste GitHub Action schreiben
Die meisten Teams starten mit GitHub Actions, indem sie einen Workflow aus einem anderen Repo kopieren und hoffen, dass er noch passt. Das funktioniert, bis es nicht mehr funkti…
Die JavaScript-Event-Loop verstehen
JavaScript läuft auf einem einzigen Thread und bewältigt trotzdem tausende gleichzeitige Netzwerkanfragen, Timer und UI-Events, ohne zu blockieren. Die Event-Loop ist der Mechan…
Memory Leaks in Node.js debuggen
Ein Node-Prozess, dessen Speicherverbrauch über Stunden oder Tage langsam steigt und der schließlich vom Container-Orchestrator wegen OOM beendet wird, ist eine der frustrierend…
Ein praktischer Leitfaden zu Semantic Versioning
in einer sieht präzise aus, aber das Caret ändert seine Bedeutung je nachdem, ob die Maintainerin am anderen Ende die Regeln, auf denen es aufbaut, tatsächlich befolgt hat. Sema…
Big-O-Notation, erklärt mit echtem Code
Die Big-O-Notation wird mit abstrakten Beispielen gelehrt – Arrays von Ganzzahlen sortieren, balancierte Bäume durchsuchen – und dann stillschweigend fallen gelassen, sobald man…
Feature-Toggles mit umgebungsbasierter Konfiguration
Der einfachste Weg, ein halbfertiges Feature in Produktion zu bringen, ohne es offenzulegen, ist zugleich der am häufigsten schlecht neu erfundene: ein Boolean, aus der Konfigur…
Eine Rate-Limiter-Middleware in Express bauen
Ein ungeschützter API-Endpunkt ist eine Einladung: ein fehlerhaftes Client-Skript, eine Retry-Schleife ohne Backoff, ein Scraper, und dein Server verbringt seine ganze Zeit dami…
Content Security Policy (CSP) verstehen
Content Security Policy ist eine Browserfunktion, die einschränkt, woher eine Seite Skripte, Stile, Bilder und andere Ressourcen laden darf – und sie ist eine der wenigen Abwehr…
Eine einfache Job-Queue mit Redis bauen
Eine Willkommensmail verschicken, ein hochgeladenes Bild skalieren, einen PDF-Bericht erzeugen – nichts davon sollte innerhalb der HTTP-Anfrage passieren, die es ausgelöst hat.…
Das Repository-Pattern: Vor- und Nachteile und wann man es weglässt
Das Repository-Pattern wird in vielen Backend-Tutorials standardmäßig empfohlen, direkt neben Dependency Injection, als wäre es offensichtlich falsch, es wegzulassen. Das ist es…
Datenbanktransaktionen und Isolationsstufen erklärt
„Pack es einfach in eine Transaktion" ist ein verbreiteter Rat, aber eine Transaktion allein garantiert nicht, dass sich zwei nebenläufige Operationen nicht in die Quere kommen…
Retry-Strategien: Exponentielles Backoff und Jitter
Ein Netzwerkaufruf schlägt fehl. Die naheliegende Lösung ist „einfach wiederholen" – aber naives Wiederholen ist genau der Weg, wie ein kurzer Aussetzer zu einem vollständigen A…
Eine sanfte Einführung in WebSockets
HTTP funktioniert nach dem Prinzip Anfrage-Antwort: Der Client fragt, der Server antwortet, die Aufgabe der Verbindung ist erledigt. Dieses Modell bricht in dem Moment zusammen,…
Async-Iteratoren und -Generatoren in JavaScript
-Schleifen laufen über Arrays und andere iterierbare Objekte jeweils einen Wert nach dem anderen. tut dasselbe, wenn jeder Wert Zeit zur Erzeugung braucht – paginierte API-Ergeb…
Memoization in JavaScript – jenseits von useMemo
Memoization cacht das Ergebnis eines Funktionsaufrufs anhand seiner Argumente, sodass ein erneuter Aufruf mit denselben Argumenten den gecachten Wert zurückgibt, statt die Arbei…
Ein einfaches Pub/Sub-System in Node.js bauen
Publish/Subscribe entkoppelt den Code, der ein Ereignis erzeugt, von dem Code, der darauf reagiert – der Publisher weiß nicht und es interessiert ihn nicht, wer zuhört, und die…
Das CAP-Theorem, erklärt mit echten Beispielen
Jeder Hersteller verteilter Datenbanken behauptet, schnell, konsistent und immer verfügbar zu sein. Das CAP-Theorem ist der Grund, warum man bei diesem Versprechen misstrauisch…
Ein praktischer Leitfaden zur JWT-Authentifizierung
JSON Web Tokens werden in vielen neuen Backends standardmäßig verwendet, oft ohne dass jemand prüft, ob ein Token tatsächlich das Richtige ist oder was passiert, wenn man eines…
Event Sourcing vs. klassisches CRUD
Eine klassische CRUD-Tabelle sagt dir den aktuellen Zustand einer Zeile und nichts darüber, wie sie dorthin gekommen ist. Event Sourcing kehrt das um: Es speichert jede Änderung…
Strukturiertes Logging: Warum printf-Debugging nicht skaliert
funktioniert gut, bis man zehn Server hat, tausend Logzeilen pro Sekunde und einen Vorfall, bei dem man jede Anfrage eines Kunden über drei Dienste hinweg in den letzten zwanzig…
CORS ein für alle Mal verstehen
CORS-Fehler tauchen in der Konsole im denkbar ungünstigsten Moment auf, sagen fast nichts Nützliches darüber, wie man sie behebt, und werden „gelöst", indem jemand von Stack Ove…
Rate-Limiting-Algorithmen: Token Bucket vs. Sliding Window
Jede öffentliche API braucht irgendwann Rate Limiting, und der gewählte Algorithmus entscheidet, ob „100 Anfragen pro Minute" tatsächlich das bedeutet, wonach es klingt. Zwei An…
Das N+1-Query-Problem und wie man es vermeidet
Eine Seite, die 50 Blogposts samt Namen des jeweiligen Autors auflistet, fühlt sich in der Entwicklung mit ein paar Testzeilen sofort an und bricht in Produktion zusammen, sobal…
Git Rebase vs. Merge: Wann man was verwendet
und bringen beide die Änderungen deines Feature-Branches auf , und genau diese oberflächliche Ähnlichkeit ist der Grund, warum man sie durcheinanderbringt und entweder mit einer…
Sichere, idempotente Datenbankmigrationen schreiben
Eine Migration, die in Staging erfolgreich lief und dann in Produktion auf halbem Weg scheitert, lässt dich an der schlechtestmöglichen Stelle zurück: ein Schema, das weder die…
Wie Datenbankindizes wirklich funktionieren
„Füg einfach einen Index hinzu" ist der häufigste Datenbanktipp und zugleich der am häufigsten falsch angewendete – auf langsame Abfragen geworfen, ohne zu verstehen, was der In…
Optimistisches vs. pessimistisches Locking in Datenbanken
Zwei Anfragen lesen dieselbe Zeile, beide berechnen aus dem Gelesenen einen neuen Wert, und beide schreiben ihn zurück – der zweite Schreibvorgang überschreibt den ersten stills…
Das Circuit-Breaker-Muster für widerstandsfähige Dienste
Wenn ein nachgelagerter Dienst zu scheitern beginnt, ist die naive Reaktion – jede eingehende Anfrage weiter zu wiederholen – genau der falsche Zug. Jede Wiederholung ist eine w…
Feature-Flags: Ein praktischer Leitfaden
Ein Feature-Flag ist eine Bedingung um ein Stück Code, mit der man diesen Code ein- oder ausschalten kann – für alle, für eine Teilmenge der Nutzer oder schrittweise – ohne ein…
TypeScript-Generics verstehen
Generics sind das Feature, über das man direkt stolpert, nachdem man sich mit den grundlegenden TypeScript-Typen angefreundet hat – und das, sobald es klickt, zu einem der am hä…
Einen LRU-Cache von Grund auf bauen
Ein LRU-Cache (Least Recently Used) hält eine feste Anzahl von Einträgen und wirft, wenn er voll ist und ein neuer Eintrag hinzukommen soll, den Eintrag hinaus, der am längsten…
Idempotency-Keys in REST-APIs
Ein Client schickt eine Zahlungsanfrage, das Netzwerk läuft in ein Timeout, bevor die Antwort zurückkommt, und der Client wiederholt – vernünftigerweise – die Anfrage. Führt dei…
Python3 - Dateien mit gleichen Namen umbenennen
Wer schnell und komfortabel seine Dateien von einem Dateisystem, das Groß-/Kleinschreibung respektiert in ein Dateisystem, welches Groß-/Kleinschreibung nicht respektiert versch…
Mailmanagement / Spam Protection
Ich hasse SPAM. Man sieht es vermutlich an der Anzahl an Blogposts (man könnte fast meinen, der ganze Blog bezieht sich nur auf das Thema Spam). Inzwischen habe ich aber eine re…
Die Bedeutung von barrierefreiem Webdesign: Ein Tor zu Inklusivität und Benutzerfreundlichkeit
In einer Welt, die immer stärker von digitalen Technologien geprägt ist, ist die Zugänglichkeit von Websites und Anwendungen für alle Nutzer von entscheidender Bedeutung. Barrie…
Die unsichtbare Bedrohung: XSRF - Wenn das Web gegen dich arbeitet
In einer Welt, in der unsere persönlichen Informationen und Online-Aktivitäten immer mehr an Bedeutung gewinnen, ist die Sicherheit im Cyberspace von entscheidender Bedeutung. E…
Erkennen von Brute - Force Angriffen
Im Rahmen eines samstäglichen Kaffeehaus Aufenthaltes und der Info meines Providers OVH, dass aktuell ein DDOS Angriff auf meinen vServer stattfindet habe ich mir mal ein paar G…
React Native - What?
Bevor wir richtig loslegen, möchte ich dir erstmal einen Witz erzählen: Wusstest du schon, warum Entwickler so gerne mit React Native arbeiten? Weil sie dabei zwei Fliegen mit e…
JavaScript - THIS Keyword
In der Welt der Webentwicklung ist Javascript eine der am häufigsten verwendeten Programmiersprachen. Trotz seiner Beliebtheit gibt es jedoch einige schwierige Konzepte, mit den…
Dependency Injection
In der Welt der Softwareentwicklung gibt es viele Konzepte, die essentiell sind, um robuste, skalierbare und leicht wartbare Anwendungen zu erstellen. Eines dieser Konzepte, das…
Die Macht des Method Chaining in C#: Ein Leitfaden für effizienten Code
In der Welt der Softwareentwicklung ist Effizienz ein Schlüsselkonzept. Effizienter Code ist nicht nur leichter zu lesen und zu warten, sondern trägt auch dazu bei, die Produkti…
Scriptable: Kontaktlinsenstatus prüfen
Ein kleines Scriptable Widget zum tracken des aktuellen Kontaktlinsen / Kontaktlinsenbehälter Status. Da ich immer wieder vergesse, nach 30-40 Tagen meine Kontaktlinsen zu wechs…
Marlin Firmware: SKR Mini e3 v3
Vielleicht mag sich der ein oder andere unter uns ja den Ärger sparen, sich die Marlin Bugfix Version 2.1.X für den Creality Ender 5 selbst zu kompilieren bzw. zu konfigurieren.…
Autosort: Schnell und einfach Bilder und Videos sortieren
Dies ist der Nachfolger des hier vorgestellten Skriptes: GoPro & Fotos: Automatisch umbenennen und kopieren
Promises
Ein Konzept, das für viele Entwickler zunächst schwer zu verstehen ist: Promises.
JavaScript - Generatoren
JavaScript-Generatoren sind eine leistungsfähige Funktionstechnik, die JavaScript-Entwicklern zur Verfügung steht. Generatoren ermöglichen es Entwicklern, asynchrone Funktionen…
JavaScript - Closures
Eine Closure entsteht, wenn eine Funktion auf eine Variable oder Funktion außerhalb ihres eigenen Scope zugreift. Im Grunde genommen ist eine Closure eine Funktion, die sich an…
GoPro-Fotos automatisch umbenennen und kopieren
Es gibt eine neuere und bessere Version hier: Autosort - Schnell und einfach Bilder und Videos sortieren
C# Delegates
Ein Delegate ist eine Art Zeiger auf eine Methode oder eine Gruppe von Methoden, die aufgerufen werden können, ohne dass du Details über die zugrunde liegenden Implementierungen…
Auto-Backup to Amazon S3
Ich bin in letzter Zeit sehr kritisch geworden, was die Sicherheit meiner Backups angeht. Gerade auch, da ich mit meinem V-Server (auf dem unter Anderem auch diese Webseite geho…
Udemy Autoenroll Skript für Tampermonkey
Auf myDealz finden sich regelmäßig threads welche kostenlose Udemy Kurse auflisten. Einmal für einen Kurs angemeldet kann man ihn - solange er online steht - jederzeit anschauen.
JavaScript Object Notation mit SQL
Datenbanken eignen sich wunderbar zum strukturierten Speichern von Daten. Manchmal kann es jedoch vorkommen, dass dies aus diversen Gründen nicht ausreicht und man stattdessen k…
null Conditional Operator
Der "null-conditional operator" ist ein Feature, das mit C 6.0 eingeführt wurde und es Entwicklern ermöglicht, sicherer mit Nullwerten umzugehen. Es ist ein einfacher Operator,…
E-Mail Adressen validieren
Eine (zugegeben: auch von mir) oft verwendete Methode um sich vor E-Mail Spam zu schützen ist es, bei einer Registrierung einfach keine valide Mailadresse anzugeben. Unsagbar of…
MySQL Null als 0 ausgeben
Für ein kleines Projekt musste ich die Werte einer Spalte in MySQL summieren und nach den summierten Werten sortieren. Sowas wie
Alpha-Go
Wer sich für KI interessiert und einen leicht verdaulichen, fast schon "Spielfilm" zum Thema sucht, sollte sich auf jeden Fall die Dokumentation zum Alpha-Go Match reinziehen. A…
Simultanschach
Als großer Schachfan bin ich natürlich auch Abonnent von GM Huschenbeth. Spannend fand ich sein 40k special, in welchem er simultan gegen mehrere Abonnenten spielt. Leider schei…
NASA - Höhendaten visualisieren
Kleines Snippet zum visualisieren der NASA-Höhendaten. Die Daten gibt's hier: https://lpdaac.usgs.gov/products/srtmgl3v003/
Youtube-DL Download MP3 (fast!)
Seit einiger Zeit nutze ich schon das wundervolle Tool youtube-dl. Wer es nicht kennt: Hiermit kann man von vielen Seiten Videos/Musik etc. herunterladen. Der Funktionsumfang is…
Brute Force Protection
Brute Force Angriffe auf Webanwendungen stellen gerade bei größeren Webseiten mit vielen Nutzern ein ernsthaftes Problem dar. Dabei versucht ein Angreifer entweder mit zufällige…
Brandneues MacBook schaltet sich einfach aus
Eine kleine Story über Apple oder das schlechteste und frustrierendste Kauferlebnis das ich jemals hatte. Vielleicht hilft es dem ein oder anderen Nutzer ja weiter. Ich teile de…
Autopush - Einfach geänderte Dateien hochladen
Ich habe mir zur Vereinfachung des Webdesign/Webdevelopment-Workflows ein kleines Autopush-Skript geschrieben. Das Skript überwacht einen bestimmten Ordner und alle seine Untero…
CentOS - Server essentials
Ab und an muss ich meinen CentOS-Server neu aufsetzen (entweder weil wieder irgendwas schief gelaufen ist oder weil ich das befriedigende Gefühl eines neuen, sauberen Systems ve…
Fire on enter
Kleines Javascript/jQuery-Snippet, das eine Aktion auslöst, sobald in einem Feld der Enter-Button betätigt wird.
Diese Version des Programms „OS X Sierra installieren“ kann nicht verifiziert werden.
Heute wollte ich meinen alten Mac an einen Freund weitergeben, und als gewissenhafter Nutzer wird davor natürlich alles erstmal auf Null zurück gesetzt. Also schnell via
Einfaches Imageresize + Caching
Ab und an kommt es vor, dass ein bereits existierendes Bild in einer anderen Größe benötigt wird. Dann kann man entweder mit Photoshop für jede Version des Bildes eine individue…
Simple Template Engine
Für ein etwas größeres Projekt habe ich eine einfache TemplateEngine gesucht. Ich wollte nicht sowohl für meine serverseitigen als auch meine clientseitigen Skripte immer wieder…
Sekunden in Tage, Stunden, Minuten, Sekunden umrechnen
Bei einem aktuellen Projekt an dem ich heute morgen saß hatte ich etwas Kopfschmerzen dabei, einen Sekundenwert in Tage, Stunden, Minuten und Sekunden umzurechnen. Eigentlich si…
Timemachine -5058
Worst Case Szenario: Das Backup spinnt. Normalerweise backupe ich IT Projekte zweifach. Mein Cronjob läuft automatisch täglich um 24:00 und erstellt ein lokales Backup meines lo…
Scrollblur
Als "Designfreak" suche ich natürlich immer nach geeigneter Inspiration, und was bietet sich da besser an als ab und an auf den Webseiten der großen Agenturen vorbei zu schauen,…
Javascript Snippets
Hier sammle ich ein paar JavaScript-Snippets. Eine Liste, die im Laufe der Zeit sicher noch erweitert wird :)
Bash Snippets
Ein paar nützliche oder unsinnige Bash Snippets, die man öfter mal gebrauchen kann. Viel Spaß damit.
Traue keinem Scan, den du nicht selbst gefälscht hast
Ein durchaus interessanter Vortrag welcher einen (recht amüsanten dramatischen) Bug der Xerox Kopierer aufzeigt. Kurz zusammengefasst geht es darum, dass Xerox Kopierer ähnliche…
SPAM protection methods N° 2: Timing ist alles
Im Rahmen der Reihe "SPAM protection methods" geht es weiter mit Teil 2 und dem ominösen Titel "Timing ist alles". Dem zu Grunde liegt die Überlegung, dass Nutzer, wenn Sie ein…
SPAM protection methods N° 3: Timing ist wiedermal alles
Auch bei der Seitennavigation kann man den Geschwindigkeitsunterschied zwischen Bot und realem Nutzer relativ gut ausnutzen. Während ein Nutzer normalerweise ein paar Sekunden a…
HTTP Range Request mit PHP verarbeiten
Manchmal wollen wir nicht die gesamte Datei vom Server laden, sondern nur einen gewissen Ausschnitt (Range) der Datei. Wir möchten also ein Startbyte und ein Endbyte definieren…
SPAM protection methods N° 1: Honeypot
Ein leidiges Thema seit Anbeginn des Internets ist SPAM (nein, nicht das Dosenfleisch, das gibt es länger als das Internet). An einem gelangweilten Wochenende hatte ich mir mal…
Javascript Promises
Seit Juni 2015 sind Promises mit ES6 auch in Javascript angekommen und können hier nativ genutzt werden. Vielleicht geht es einigen hier so wie mir am Anfang und wissen nicht so…
SPAM vermeiden mit qmail
SPAM. Alle hassen ihn, keiner kann ihn (ernsthaft) vermeiden. Um die Inbox allerdings einigermaßen aufgeräumt zu halten gibt es eine recht komfortable Lösung: Temporäre E-Mail-A…
PHP Snippets
Manchmal muss man schnell mehrere Variablen tauschen und ich hatte mich irgendwann gefragt, ob das nicht auch ohne temp - Variable möglich ist. Seit dem ist das meine best - pra…
OpenGeoDB Hürden
Für ein aktuelles Projekt habe ich eine Liste mit allen Postleitzahlen in Deutschland inkl. zugehöriger Städtenamen gebraucht. Es gilt zwar "Je mehr Daten desto besser" ;-) aber…