Co To Jest Tabela Haszująca? Haszowanie I Kolizje Wyjaśnione

Wyszukanie klucza w Pythonowym dict z dziesięcioma wpisami zajmuje tyle samo czasu, co w dict z dziesięcioma milionami. To nie wynika z szybkości języka. Pythonowy dict, Javowy HashMap i Map w JavaScript to wszystko tabele haszujące, a cały ten projekt istnieje po to, by wyszukiwanie, wstawianie i usuwanie działały średnio w O(1). Notacja Big O nazywa to wyszukiwanie “czasem stałym”. Oto mechanizm, który na to zasługuje. Jak tabela haszująca zmienia klucz w indeks tablicy Tabela haszująca to tablica plus funkcja, która zmienia klucz w pozycję w tej tablicy. ...

4 listopada 2026 · 7 min · 1420 słów · SpaghettiCoder

Ownership i Borrowing w Rust: Jak To Działa

Program w C, który zwalnia bufor i dalej z niego czyta, mimo to się kompiluje. Potem psuje pamięć, czasem natychmiast, czasem trzy requesty później, w fragmencie kodu, który nigdy tego bufora nie dotknął. Rust odrzuca taki program już na etapie cargo build, i nie ma w tym żadnego garbage collectora. Kompilator śledzi, kto jest właścicielem każdej wartości i kto może na nią patrzeć. To śledzenie to właśnie ownership i borrowing. ...

3 listopada 2026 · 7 min · 1424 słów · SpaghettiCoder

Mock, Stub, Fake i Spy: Test Doubles Wyjaśnione

Test dla place_order potrzebuje bramki płatności, klienta SMS i kalkulatora podatku. Podłącz prawdziwe zależności i każde uruchomienie testu obciąży kartę i wyśle SMS na prawdziwy numer. Test jednostkowy ma działać w milisekundach, bez sieci, więc wszystkie trzy trzeba czymś zastąpić. To “coś innego” ma pięć odmian, każda rozwiązuje inny problem, a traktowanie ich jako wymienne jest powodem, dla którego spory “po prostu zmockuj to” w code review nie mają końca. ...

2 listopada 2026 · 7 min · 1455 słów · SpaghettiCoder

ESLint vs Prettier: Różnice i Jak je Połączyć

Zapisujesz plik, Prettier go formatuje, a ESLint natychmiast zgłasza błąd w linii, którą Prettier właśnie dotknął. Oba narzędzia są skonfigurowane, oba działają — i zamiast pomagać, walczą ze sobą. Te dwa narzędzia robią różne rzeczy. Problem w tym, że oba mają zdanie na temat jednej sprawy: jak kod ma wyglądać na ekranie. Co ESLint faktycznie sprawdza ESLint rozkłada kod na abstrakcyjne drzewo składniowe i uruchamia reguły na jego strukturze. Największa wartość pochodzi z reguł, które wyłapują realne bugi: zmienną, która nigdy nie została zdefiniowana, nieosiągalny return po innym return, nieużywany import, który został po refaktoryzacji, zduplikowany klucz w obiekcie, który bez ostrzeżenia nadpisuje pierwszy. To kontrole semantyczne — ESLint czyta, co kod robi. ...

1 listopada 2026 · 6 min · 1075 słów · SpaghettiCoder

Wyrażenia Regularne Wyjaśnione: Jak Naprawdę Działa Regex

<.+> dla <b>bold</b> and <i>italic</i> nie znajduje <b>. Znajduje cały ciąg, od pierwszego < do samego ostatniego >. Nic nie jest zepsute. To właśnie ma robić zachłanny (greedy) kwantyfikator, i to jest też najczęstszy błąd typu “regex matchuje zbyt dużo”. Gdy już wiesz, co silnik robi podczas czytania wzorca, ten błąd i większość jego krewnych przestają być zagadką. Jak silnik regex czyta twój wzorzec Silnik regex nie porównuje wzorca z ciągiem tak, jak porównuje się dwa ciągi pod kątem równości. Silniki, które używasz codziennie (re w Pythonie, RegExp w JavaScript, PCRE, .NET, Java) są regex-directed: przechodzą przez wzorzec od lewej do prawej, token po tokenie, i dla każdego tokenu próbują skonsumować znaki z ciągu w aktualnej pozycji. Gdy token się dopasuje, silnik przesuwa wskaźnik wzorca i wskaźnik ciągu. Gdy token zawodzi, silnik robi backtracking: wraca do ostatniego miejsca, w którym miał wybór, na przykład kwantyfikator, który mógł dopasować mniej znaków, albo gałąź alternatywy, której jeszcze nie spróbował, i wybiera drugą opcję. ...

28 października 2026 · 7 min · 1393 słów · SpaghettiCoder

Generics w TypeScript Wyjaśnione z Przykładami

Czemu any odbiera przekazany typ? Otypuj parametr jako any i TypeScript przestaje sprawdzać wszystko, co wychodzi z funkcji: 1 2 3 4 5 6 function firstElement(arr: any[]): any { return arr[0]; } const n = firstElement([1, 2, 3]); n.toUpperCase(); // kompiluje się, wywala w czasie działania Ty wiesz, że przekazałeś tablicę liczb. Kompilator nie wie, bo any mówi mu, żeby przestał patrzeć. n wraca jako any, więc wywołanie metody string na liczbie kompiluje się bez problemu i wyrzuca TypeError: n.toUpperCase is not a function przy uruchomieniu. ...

27 października 2026 · 7 min · 1382 słów · SpaghettiCoder

Exceptions vs Wartości Błędów: Jak Wybrać Strategię

Otwórz w Python plik, który nie istnieje, i open() zgłasza FileNotFoundError, który wychodzi poza twoją funkcję. Zrób to samo w Go, a os.ReadFile zwraca wartość error razem z nilowym slice’em bajtów. Ten sam błąd, dwie zupełnie inne formy kodu wokół niego. Różnica nie jest kosmetyczna. Decyduje o tym, czy wywołujący może przypadkowo zignorować błąd, i czy kompilator to zauważy, gdy to się stanie. Co exceptions i wartości błędów robią naprawdę inaczej? Exception to przepływ sterowania, który skacze. Coś zawodzi, funkcja zgłasza wyjątek, a wykonanie opuszcza bieżący stos wywołań i trafia do najbliższego dopasowanego bloku catch albo except, niezależnie od tego, ile poziomów wyżej to jest. Sygnatura funkcji nie daje żadnej wskazówki, że to może się zdarzyć. loadConfig(path: string): Config w TypeScript wygląda jak funkcja, która nie może zawieść — aż zgłosi wyjątek przy brakującym pliku. ...

26 października 2026 · 7 min · 1429 słów · SpaghettiCoder

Rate Limiting API: Algorytmy i Jak Zbudować Własny

Jeden klient zapętlony w retry loop bez backoffu może w jedną minutę wygenerować na twoim API więcej obciążenia niż pozostałe dziesięć tysięcy klientów razem wzięte. Z twojej strony to nie wygląda jak atak. Wygląda jak bug u nich, a staje się incydentem u ciebie. Rate limiter zatrzymuje tego klienta, zanim do tego dojdzie. Co właściwie decyduje rate limiter? Przy każdym requeście limiter zadaje sobie jedno pytanie: czy ten klucz wykonał w bieżącym oknie czasowym za dużo requestów? Trzy decyzje zmieniają to w coś, co można zaimplementować. ...

23 października 2026 · 7 min · 1362 słów · SpaghettiCoder

Intersection Observer: Lazy Loading i Infinite Scroll

Listener scroll na window może odpalać się setki razy podczas jednego przesunięcia ekranu. Jeśli przy każdym takim evencie wywołujesz getBoundingClientRect() na każdej karcie w feedzie, pięćdziesiąt obrazów wystarczy, żeby strona zaczęła się zacinać. Intersection Observer API zdejmuje to sprawdzenie ze ścieżki scrolla: rejestrujesz, jakie elementy obserwować, a przeglądarka informuje cię, gdy ich widoczność naprawdę się zmienia. Jak działa IntersectionObserver Observer obserwuje jeden lub więcej elementów target względem root (domyślnie viewport) i wywołuje callback, gdy target przekroczy próg widoczności. ...

21 października 2026 · 5 min · 958 słów · SpaghettiCoder

Co To Jest Unicode i Jak Działa Kodowanie UTF-8

Otwórz plik zapisany w UTF-8 w narzędziu, które zakłada inne kodowanie, i café zmienia się w café. Bajty na dysku się nie zmieniły. Zmieniła się tylko reguła odczytu, czyli sposób zamiany bajtów z powrotem na znaki, a te dwie reguły różnie rozumieją, co znaczy bajt 0xC3. Większość błędów z “dziwnymi znakami” ma to samo źródło: połamane nazwy plików, zmasakrowane formularze, emoji, które wywala insert do bazy danych, dwa stringi wyglądające identycznie, ale różne w porównaniu. Za każdym z nich stoi ta sama pomyłka: mylenie Unicode z UTF-8, dwóch zupełnie różnych rzeczy. ...

20 października 2026 · 7 min · 1438 słów · SpaghettiCoder