Praktyczne, ponadczasowe poradniki dla programistow. Kazdy opiera sie na prawdziwych poleceniach i dzialajacych przykladach oraz jasno mowi, kiedy nie uzywac opisywanego narzedzia.
Ponizej znajdziesz wszystko, od najnowszych.
Praktyczne, ponadczasowe poradniki dla programistow. Kazdy opiera sie na prawdziwych poleceniach i dzialajacych przykladach oraz jasno mowi, kiedy nie uzywac opisywanego narzedzia.
Ponizej znajdziesz wszystko, od najnowszych.
Wyloguj użytkownika z aplikacji opartej na sesjach, a serwer zapomni o nim przy następnym żądaniu. Wyloguj go z aplikacji opartej na JWT i, jeśli nie zbudowałeś dodatkowego mechanizmu, token, który trzyma, zostaje ważny aż do wygaśnięcia. Ta różnica jest prawdziwą decyzją stojącą za “JWT vs sesja”. Reszta z niej wynika. Co faktycznie przechowuje sesja Sesja trzyma stan użytkownika na serwerze, a przeglądarce przekazuje tylko klucz do wyszukania. Użytkownik loguje się hasłem. Serwer tworzy rekord sesji (ID użytkownika, role, co tylko potrzebne) i zapisuje go w pamięci, w bazie danych albo w Redis, indeksowany losowym ID sesji. Serwer wysyła ten ID do przeglądarki jako cookie, oznaczone HttpOnly, żeby JavaScript po stronie klienta nie mógł go odczytać. Przy każdym żądaniu przeglądarka automatycznie odsyła cookie. Serwer szuka ID w store i pobiera dane sesji. Cookie nie niesie żadnej informacji o użytkowniku, tylko nieprzejrzysty ciąg, który serwer rozwiązuje przy każdym żądaniu. Usuń rekord w store i sesja znika przy następnym żądaniu, na każdym urządzeniu. ...
Wpisz “szczeniak” w systemie, który porównuje tylko słowa kluczowe, i dokument o szkoleniu psów się nie pojawi, choć każdy, kto przeczytałby oba teksty, uznałby je za ściśle powiązane. Wyszukiwanie po słowach kluczowych porównuje ciągi znaków. Nie wie, że “szczeniak” i “pies” znaczą prawie to samo. Embeddingi rozwiązują właśnie ten problem. Zamieniają fragment tekstu w listę liczb, wektor, umieszczony tak, że tekst o podobnym znaczeniu trafia blisko innego tekstu o podobnym znaczeniu, niezależnie od użytych słów. ...
Owiń wywołanie fetch() w try/catch, trafiasz na endpoint, który odpowiada 404, a blok catch nigdy się nie uruchamia. Promise się rozwiązuje. res.json() parsuje to, co serwer odesłał, często payload błędu w stylu {"error": "user not found"}, a reszta funkcji traktuje to jak żądany rekord. Żadnego wyjątku, żadnego ostrzeżenia w konsoli. Złe dane płyną dalej, aż coś inne się na nich wywala. 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; // przy 404 to jest { error: "user not found" } } catch (err) { console.error('Failed to load user:', err); } } Ten catch odpala się tylko dla żądania, które nigdy się nie kończy. Wszystko inne wymaga sprawdzenia, które musisz napisać samodzielnie. ...
Funkcja, która wywołuje sama siebie, ma maksymalną głębokość, i jest ona mniejsza niż większość się spodziewa: 1000 wywołań w CPython domyślnie, w okolicach 10 000-15 000 w Node i silnikach przeglądarek, zależnie od tego, jak dużo zajmuje każda ramka. Przekroczenie tego limitu nie zwalnia programu. Program się wysypuje. Python zgłasza RecursionError: maximum recursion depth exceeded; JavaScript zgłasza RangeError: Maximum call stack size exceeded. Oba błędy mają tę samą przyczynę, a gdy już ją zobaczysz, będziesz wiedzieć, kiedy rekurencja jest właściwym narzędziem, a kiedy staje się ryzykiem. ...
Budujesz dashboard: header, sidebar, główna treść, footer. Sięgasz po Flexbox, bo to narzędzie layoutowe, które znasz, a dwadzieścia minut później masz trzy zagnieżdżone kontenery display: flex, sidebar, który nie utrzyma swojej szerokości bez magicznej liczby, i footer, który unosi się w połowie strony, gdy treści jest mało. To nie jest błąd Flexbox — to Ty używasz narzędzia jednowymiarowego do problemu dwuwymiarowego. Flexbox rozkłada przestrzeń wzdłuż jednej linii: wiersza albo kolumny. Grid ustawia elementy w wierszach i kolumnach naraz, a te wiersze i kolumny odnoszą się do siebie. Większość zamieszania wokół Grid kontra Flexbox wynika z przeskoczenia tej różnicy. ...
Postaw go przed wywołaniem funkcji i ta funkcja zacznie działać współbieżnie z resztą programu, zarządzana przez runtime Go, a nie przez system operacyjny. Uruchomienie jej to łatwa część. Trudna część to przekazanie wyniku między dwoma goroutines bez wchodzenia sobie w drogę przy współdzielonym stanie, a tym właśnie zajmują się channels. Co to jest goroutine? Goroutine to funkcja działająca niezależnie od tej, która ją uruchomiła. Wątek systemu operacyjnego rezerwuje megabajt lub więcej stosu i kosztuje jądro realny czas na szeregowanie. Goroutine startuje ze stosem około 2KB, który rośnie w razie potrzeby, a runtime multiplexuje wiele goroutines na garstkę wątków systemowych. Uruchamianie ich tysięcy naraz jest normalne. ...
Klasa, która zapisuje użytkownika w bazie danych, wysyła mu powitalny email i formatuje rachunek, jest jedną zmianą od zepsucia dwóch funkcji, z którymi nie ma nic wspólnego. Zmieniasz szablon emaila i ryzykujesz zapis do bazy. Zmieniasz układ rachunku i ryzykujesz email. SOLID to pięć zasad, które atakują ten rodzaj splątania z różnych stron, i łączy je jedna idea: klasa powinna mieć jeden powód do zmiany, a reszta kodu powinna zależeć od tego, co element obiecuje robić, nie od tego, jak to robi. ...
Dwa requesty trafiają na ten sam endpoint “wypłać 100€” z różnicą pół milisekundy. Konto ma 150€. Oba requesty czytają ten sam stan konta, oba widzą wystarczające środki, oba zostają zatwierdzone, oba odejmują 100€. Konto kończy na -50€, a żadna ścieżka w kodzie nie powinna do tego doprowadzić. To jest race condition: wynik zależy od tego, która operacja skończy się pierwsza, a to, co było “pierwsze”, nigdy nie zależało od kodu. ...
Pole wyszukiwania, które wysyła zapytanie przy każdym naciśnięciu klawisza, wysyła pięć zapytań dla “redis”, a cztery z nich są już nieaktualne, zanim wróci odpowiedź. Handler scroll, który przelicza layout, odpala się setki razy na sekundę i powoduje szarpanie strony. W obu przypadkach ten sam problem: zdarzenie DOM odpala się dużo częściej, niż handler musi się wykonać. Debounce i throttle rozwiązują to na dwa różne sposoby. Co robi debounce, a co robi throttle Debounce czeka, aż zdarzenie przestanie się odpalać na ustalony czas, i wtedy wykonuje się raz. Każde nowe wywołanie resetuje zegar. Jeśli zdarzenie nigdy się nie zatrzymuje, funkcja nigdy się nie wykonuje. Pole wyszukiwania to typowy przypadek: czekaj, aż użytkownik zrobi przerwę w pisaniu, a potem wyślij zapytanie z tym, co wpisał na końcu. ...
Co dekorator naprawdę robi z twoją funkcją Chcesz zmierzyć czas każdej funkcji, która wywołuje wolne zewnętrzne API. Możesz wkleić wywołania time.perf_counter() do każdej z nich albo napisać pomiar raz i stosować go wszędzie. Dekorator to druga opcja: to funkcja, która bierze inną funkcję, owija ją dodatkowym zachowaniem i zwraca owiniętą wersję pod oryginalną nazwą. 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) # zastępuje wywołanie sieciowe return 142.50 fetch_price("AAPL") # fetch_price took 0.201s @timed nad def fetch_price to skrót od fetch_price = timed(fetch_price). Python wywołuje timed raz, zaraz po zdefiniowaniu fetch_price, i przypisuje nazwę fetch_price do tego, co zwraca timed. To jest cała robota, jaką wykonuje @. ...