Czemu 0.1 + 0.2 Nie Daje 0.3: Liczby Zmiennoprzecinkowe

Wpisz 0.1 + 0.2 w shellu Pythona i nie dostaniesz 0.3. Dostaniesz 0.30000000000000004. Spróbuj w JavaScript, Java, Go, C albo Rust i wyjdzie ten sam siedemnastocyfrowy ogon. Każdy z tych języków robi dokładnie to, co nakazuje standard sprzętowy. Liczba, która wymagałaby nieskończenie wielu cyfr binarnych, jest ściskana do 64 bitów i coś musi ustąpić. Czemu 0.1 nie da się zapisać dokładnie w binarnym systemie Komputery zapisują liczby zmiennoprzecinkowe w systemie dwójkowym. W systemie dwójkowym ułamek 1/10 ma rozwinięcie okresowe, tak jak 1/3 powtarza się bez końca w systemie dziesiętnym (0.3333...). Zapisane w całości, 0.1 w binarnym zaczyna się tak: ...

6 października 2026 · 5 min · 1033 słów · SpaghettiCoder

LocalStorage vs SessionStorage vs Cookies: co wybrać

Endpoint logowania odsyła JWT, a Ty masz trzy miejsca, w których możesz go trzymać: cookie, localStorage albo sessionStorage. Wybierzesz źle i albo błąd XSS wyniesie token na zewnątrz, albo token nigdy nie dotrze do Twojego API. Wszystkie trzy mechanizmy przechowują stringi w przeglądarce. Różnią się tym, kto może je odczytać, jak długo żyją i czy serwer w ogóle je widzi. Czym różnią się localStorage, sessionStorage i cookies localStorage i sessionStorage to ten sam interfejs, Storage: setItem, getItem, removeItem, clear, klucze i wartości w postaci stringów. Różnica leży w czasie życia. localStorage przetrwa zamknięcie przeglądarki i restart komputera, i zostaje tam, dopóki coś go nie wyczyści. Safari jest wyjątkiem: z włączonym tracking prevention usuwa dane zapisane przez skrypt dla strony, z którą użytkownik nie miał kontaktu od siedmiu dni. sessionStorage należy do jednej karty i umiera, gdy ta karta się zamyka. Wpisz ten sam adres w drugiej karcie i dostaniesz nowy, pusty sessionStorage — tylko opcja “Duplikuj kartę” kopiuje go dalej. ...

5 października 2026 · 7 min · 1358 słów · SpaghettiCoder

Notacja Big O Wyjaśniona na Przykładach Kodu

Odczyt ze słownika w Pythonie trwa około 100 nanosekund, niezależnie od tego, czy słownik ma 1000 kluczy, czy 1 000 000. Podwójna pętla szukająca duplikatów w liście trwa pół milisekundy przy 200 elementach i 136 milisekund przy 3200. Szesnaście razy więcej danych wejściowych, prawie 280 razy dłuższe oczekiwanie. Ta sama maszyna, ten sam Python. Notacja Big O to nazwa tej różnicy. Co mierzy notacja Big O Big O opisuje, jak rośnie czas działania (albo zużycie pamięci) fragmentu kodu wraz ze wzrostem danych wejściowych. To nie jest pomiar stoperem i nie ma znaczenia, czy twój laptop jest szybki, czy wolny. Liczy się kształt krzywej wzrostu: gdy podwoisz dane wejściowe, czas się podwaja, rośnie czterokrotnie, czy prawie się nie zmienia? ...

4 października 2026 · 8 min · 1541 słów · SpaghettiCoder

Git Reset vs Revert vs Restore: Jak Cofnąć Zmiany

Zrobisz git reset --hard na commicie, który zespół już pobrał, i twoja historia zaczyna się różnić od jego historii. Zrobisz git revert na literówce, której jeszcze nie wypchnąłeś, i dodajesz do logu bezsensowny commit. Git ma cztery polecenia do cofania zmian: restore, reset, commit --amend i revert. Nie są wymienne. Wybierz niewłaściwe i albo nic się nie stanie, albo stanie się dużo więcej, niż chciałeś. O wyborze decyduje to, gdzie zmiana aktualnie się znajduje: w working tree, w staging area, w commicie, który masz tylko ty, czy w commicie, który już wypchnąłeś. ...

3 października 2026 · 6 min · 1223 słów · SpaghettiCoder

Typy JOIN w SQL Wyjaśnione na Przykładach

Źle napisany JOIN nie zgłasza błędu. Wykonuje się, zwraca wynik, a wiersze są błędne: brakujący klienci, zawyżone sumy, niewidoczne osierocone rekordy. Najczęściej zapytanie dostało dokładnie to, o co prosiło, a autor wybrał zły typ join albo filtrował w złym miejscu. Join łączy wiersze z dwóch tabel na podstawie warunku, który sam piszesz. To, które wiersze przetrwają, zależy od typu join, a sześć typów poniżej daje sześć różnych odpowiedzi z tych samych dwóch tabel. ...

2 października 2026 · 9 min · 1767 słów · SpaghettiCoder

Czym Jest Dependency Injection? (Z Przykładami)

Oto klasa, której nie przetestujesz jednostkowo bez działającej bazy danych i serwera SMTP: 1 2 3 4 5 6 7 8 9 10 11 public class OrderService { private readonly SqlOrderRepository _repository = new SqlOrderRepository("Server=prod-db;Database=Orders;..."); private readonly SmtpEmailSender _emailSender = new SmtpEmailSender("smtp.company.com"); public void PlaceOrder(Order order) { _repository.Save(order); _emailSender.Send(order.CustomerEmail, "Order confirmed"); } } OrderService tworzy własne instancje SqlOrderRepository i SmtpEmailSender przez new, razem z connection stringiem. Każdy test dotykający PlaceOrder potrzebuje prawdziwej bazy Orders i działającego serwera pocztowego, inaczej padnie, zanim dojdzie do asercji. Logika, którą chcesz przetestować, to dwie linijki: zapisz zamówienie, wyślij potwierdzenie. Jest zespawana z dwiema konkretnymi klasami, których nie da się podmienić. ...

1 października 2026 · 7 min · 1384 słów · SpaghettiCoder

Wirtualne Środowiska Python: venv, pip i uv

Zainstaluj na jednym komputerze dwa projekty w Pythonie i drugi może zepsuć pierwszy. Jeden potrzebuje requests==2.28, drugi requests==2.32, a pip ma dokładnie jeden systemowy katalog site-packages, do którego zapisuje. Wygrywa ostatnia instalacja, po cichu. Zauważasz to, gdy drugi projekt zaczyna zgłaszać błędy, które nie mają nic wspólnego z kodem, który właśnie zmieniłeś. Wirtualne środowisko daje każdemu projektowi własny site-packages. Nic globalnego się nie zmienia, a dwa projekty mogą zależeć od niekompatybilnych wersji tej samej biblioteki, bez wzajemnej kolizji. ...

30 września 2026 · 6 min · 1262 słów · SpaghettiCoder

Testy Jednostkowe vs Integracyjne vs End-to-End

Funkcja może mieć 100% pokrycia testami jednostkowymi, a strona, która ją wywołuje, i tak może zwrócić w produkcji błąd 500. To nie jest sprzeczność. Testy jednostkowe, integracyjne i end-to-end sprawdzają różne rzeczy, a zestaw testów mocny w jednym i słaby w drugim ma konkretną, przewidywalną dziurę. Co sprawdzają testy jednostkowe, integracyjne i end-to-end Weźmy funkcję rejestracji: funkcja waliduje dane wejściowe, zapisuje wiersz w bazie danych i wysyła email powitalny. Trzy testy mogą to pokryć, każdy odpowiada na inne pytanie. ...

29 września 2026 · 10 min · 2010 słów · SpaghettiCoder

Async/Await i Event Loop w JavaScript Wyjaśnione

Odpal to w Node albo w konsoli przeglądarki: 1 2 3 4 console.log("1"); setTimeout(() => console.log("2"), 0); Promise.resolve().then(() => console.log("3")); console.log("4"); Wynik to 1 4 3 2. Callback promise wygrywa z setTimeout ustawionym na 0ms: wykonuje się przed nim, choć obu i tak przyjdzie zaczekać, aż zakończy się cały synchroniczny kod, który jest jeszcze do wykonania poniżej. async/await jest zbudowane na tej kolejności, nie na czymś nowym. Większość zaskakujących zachowań w asynchronicznym JavaScript wynika z traktowania await jak czegoś, co zatrzymuje cały program, podczas gdy zatrzymuje tylko funkcję, w której się znajduje. ...

28 września 2026 · 8 min · 1516 słów · SpaghettiCoder

Jak Działają Indeksy w Bazie Danych i Kiedy Je Dodawać

W tabeli z milionem wierszy to samo zapytanie SELECT może trwać pięćdziesiąt milisekund albo mniej niż jedną. Jedyna różnica: baza danych albo czyta każdy wiersz, żeby znaleźć te, których szukasz, albo skacze od razu do nich. Właśnie to umożliwia indeks — i płacisz za niego przy każdym zapisie. Sam indeks to druga, posortowana kopia jednej lub więcej kolumn, przechowywana obok tabeli i aktualizowana automatycznie przy każdej zmianie tabeli. Baza danych używa jej, żeby dotrzeć do pasujących wierszy bez dotykania reszty. ...

27 września 2026 · 8 min · 1583 słów · SpaghettiCoder