Przejdź do treści

Tech & Code

Krzysztof Zdunkowski

Senior Full-Stack Developer

Samodzielnie projektuję, rozwijam i wdrażam aplikacje. Przez ponad 12 lat prowadziłem własną działalność, zajmując się wymaganiami klientów, kodem i utrzymaniem serwerów. Pracowałem też w zespołach rozwijających systemy biznesowe oraz integracje z kamerami i automatyką.

AI wykorzystuję do analizy problemów, szukania rozwiązań i pracy nad kodem. Porównuję różne podejścia, przygotowuję prototypy i sprawdzam ich działanie. Stawiam na rozwiązania wydajne i możliwie proste w utrzymaniu — nie na rozbudowę infrastruktury bez uzasadnienia.

Krzysztof Zdunkowski

AI w pracy nad oprogramowaniem

Pracuję z modelami językowymi i agentami kodu przy analizie istniejących systemów, szukaniu rozwiązań, refaktoryzacji i prototypowaniu. Wykorzystuję je również do przygotowywania testów, dokumentacji, transformacji danych i zmian obejmujących wiele plików. AI jest częścią mojego sposobu pracy, nie tylko narzędziem do uzupełniania kodu.

Dobieram sposób prowadzenia zadania: opisuję wymagania i ograniczenia, przekazuję kontekst, dzielę większe zmiany na etapy i porównuję proponowane rozwiązania. Korzystam zarówno z rozmowy z modelem, jak i pracy w edytorze czy z agentami kodu. Sprawdzam, które podejście jest przydatne w danym zadaniu i jak wpływa na wynik kolejnych poprawek.

Porównuję propozycje różnych modeli, ale oceniam przede wszystkim działanie przygotowanego rozwiązania: zgodność z założeniami, dokładność zmian i miejsca wymagające korekty. Przekonująco napisana odpowiedź nie jest dla mnie równoznaczna z rozwiązanym problemem.

ClaudeAnaliza kodu i refaktoryzacja

Z Claude korzystam przy analizie istniejącego kodu, pracy nad architekturą i większych refaktoryzacjach. Używam go również do projektowania API, przygotowywania testów i dokumentacji technicznej.

W pracy z modelem dzielę zadania na mniejsze kroki i opisuję ograniczenia projektu. Porównuję też jego propozycje z odpowiedziami GPT, dobierając narzędzie do konkretnego zadania.

GPTWarianty rozwiązań i prototypy

Modele GPT wykorzystuję do prototypowania i sprawdzania różnych wariantów rozwiązania. Pracuję z nimi nad szkicami interfejsów, fragmentami kodu, transformacjami danych i strukturami testów.

Porównuję odpowiedzi GPT i Claude przy różnych rodzajach zadań. To część moich eksperymentów z organizacją pracy wspomaganej przez AI.

Copilot i CursorPraca w edytorze

Z Copilota i Cursora korzystam bezpośrednio w edytorze: przy uzupełnianiu kodu, powtarzalnych fragmentach, wyrażeniach regularnych, zapytaniach SQL i transformacjach danych.

Korzystam też z trybów agentowych przy zadaniach takich jak refaktoryzacja, masowe zmiany w wielu plikach czy przygotowanie szkieletu nowego modułu.

Doświadczenie

08.2024 – obecnie Projekty niezależne i praca z AI Obsługa mniejszych projektów · własne rozwiązania · modele i agenci kodu

Od sierpnia 2024 r. obsługuję mniejsze projekty, równolegle rozwijając własne aplikacje i prototypy. W tym czasie intensywnie pracuję również z AI: poznaję narzędzia, porównuję ich możliwości i wykorzystuję je przy analizie kodu, refaktoryzacji, przygotowywaniu testów, dokumentacji oraz nowych rozwiązań.

Własne projekty wykorzystuję do sprawdzania różnych sposobów pracy: opisywania wymagań, przekazywania kontekstu, dzielenia zadań i prowadzenia kolejnych poprawek. Pracuję zarówno w rozmowie z modelem, jak i z narzędziami w edytorze oraz agentami kodu.

Porównuję działanie przygotowanych rozwiązań, ich zgodność z założeniami i dokładność wprowadzanych zmian. Sprawdzam również, jak poszczególne narzędzia radzą sobie z kolejnymi iteracjami i gdzie potrzebne są korekty. W ten sposób rozwijam praktyczne umiejętności pracy z AI, równolegle z bieżącymi projektami.

06.2023 – 08.2024 Senior Backend & Full-Stack Developer Panel administracyjny i API · PHP, Vue 3, Nuxt

Opracowałem i utrzymywałem panel administracyjny w Vue 3, Nuxt i TypeScript oraz API-Admin w czystym PHP i Laravelu. Zaprojektowałem system uprawnień, licencji i ról obejmujący setki różnych scenariuszy. Przygotowałem pełną dokumentację Swagger i napisałem ponad 200 testów jednostkowych.

Wdrożyłem automatyzację CI/CD w GitLab CI, Docker Compose oraz proces wydawania nowych wersji. Czas wdrożenia skrócił się z kilku godzin do kilkunastu minut. Regularnie prowadziłem code review i mentoring młodszych programistów.

08.2022 – 05.2023 Senior Backend Developer Kamery i automatyka · Laravel, ONVIF, Modbus

Projektowałem i rozwijałem backend w Laravelu, w tym REST API z automatycznie generowaną dokumentacją Swagger. Tworzyłem moduły do zarządzania kamerami w standardzie ONVIF i integrowałem urządzenia komunikujące się przez Modbus.

Optymalizowałem zapytania MySQL/MariaDB oraz refaktoryzowałem istniejące moduły Node.js zarządzane przez PM2. Dodawałem monitorowanie i alerty, pracując nad stabilnością środowiska produkcyjnego.

02.2020 – 07.2022 Senior Full-Stack Developer System dla branży budowlanej · Yii2, MS SQL

Tworzyłem i rozwijałem wielomodułowy system do zarządzania projektami budowlanymi, oparty na Yii2, PHP 7.2 i MS SQL. Odpowiadałem za kolejne części rozwiązania: projektowanie bazy danych, logikę aplikacji, paginację i raporty, responsywne widoki oraz integracje z zewnętrznymi API.

Napisałem kilkanaście własnych komponentów do tabel, filtrowania i paginacji. Przygotowywałem też narzędzia do masowej migracji danych i generowania raportów PDF.

08.2016 – 01.2020 Senior Full-Stack Developer & Business Analyst Utrzymanie i rozwój systemów PHP

Stabilizowałem i rozwijałem istniejące systemy w PHP. Wprowadziłem Git i Continuous Delivery oraz pracowałem przy migracjach z PHP 5.4 do 7.2. Zajmowałem się również optymalizacją wydajności i skracaniem czasu odpowiedzi aplikacji.

W Pythonie projektowałem algorytmy weryfikacji kandydatów oparte na IRT.

08.2013 – 12.2017 Full-Stack Developer KohanaPHP · integracje i infrastruktura

Prowadziłem rozwój systemu w KohanaPHP. Mój zakres prac obejmował konfigurację serwerów, REST API dla partnerów, landing pages i integrację płatności.

Samodzielnie zarządzałem repozytoriami Mercurial i infrastrukturą OVH oraz optymalizowałem proces wdrażania aplikacji.

10.2012 – 02.2013 Junior Full-Stack Developer MediaWiki · portal i środowiska aplikacji

Dostosowywałem MediaWiki do potrzeb portalu i optymalizowałem wyświetlanie dużych ilości danych w czasie rzeczywistym. Wdrażałem środowiska deweloperskie i produkcyjne.

11.2008 – 06.2021 Własna działalność · CreaWeb / iFotos Strony, aplikacje i hosting

Przez ponad 12 lat prowadziłem własną działalność, samodzielnie zajmując się analizą wymagań klientów, projektowaniem, programowaniem i wdrażaniem stron WWW. Utrzymywałem również infrastrukturę hostingową opartą na Nginx, PHP-FPM, XCache i MySQL.

Rozwijałem REST API dla partnerów, landing pages i narzędzia marketingowe. Prowadziłem też iFotos, własny hosting zdjęć na kilku serwerach dedykowanych, z których każdy miał łącze 1 Gbit/s. W tej części pracy szczególne znaczenie miała optymalizacja wykorzystania serwerów i obsługi dużej liczby pobrań.

Z praktyki

iFotos — własny hosting zdjęć

Przez wiele lat prowadziłem iFotos — hosting zdjęć działający na kilku serwerach dedykowanych, z których każdy miał łącze 1 Gbit/s. Serwis opierał się na Nginx, PHP-FPM, XCache i MySQL. Przy ograniczonym sprzęcie duże znaczenie miało to, która część systemu odpowiada za poszczególne zadania.

Wykorzystałem X-Accel-Redirect, aby PHP obsługiwało metadane i liczniki odsłon w cache, a sam plik wysyłał Nginx. Przy pełnym obciążeniu łącza średnie wykorzystanie CPU wynosiło około 40%.

Infrastruktura działała stabilnie przez lata. Serwis zawiesiłem później, po spadku ruchu związanym ze zmianą potrzeb rynku.

Moje podejście

Stawiam na lekkie, dobrze zoptymalizowane rozwiązania, które wydajnie wykorzystują dostępny sprzęt i są niedrogie w utrzymaniu. Wolę dobrze przemyśleć architekturę, zoptymalizować kod i zapytania do bazy niż nadrabiać ich niedostatki mocniejszymi serwerami i kolejnymi usługami. Zależy mi na tym, żeby system sprawnie działał na możliwie niewielkiej infrastrukturze — bez utrudniania jego dalszego rozwoju.

Nie będę proponował chmury ani rozbudowanego, kosztownego stosu technologicznego bez konkretnego uzasadnienia. Jeżeli wymagania projektu można spełnić prostszym rozwiązaniem, nie widzę powodu, żeby dokładać zależności, zwiększać koszty i komplikować utrzymanie. Przy wyborze technologii biorę pod uwagę nie tylko samo uruchomienie aplikacji, ale też późniejszą pracę z nią: rozwój, diagnozowanie problemów, wdrożenia i rachunki za infrastrukturę.

Korzystam z kontenerów i usług chmurowych tam, gdzie rzeczywiście coś rozwiązują — ułatwiają wdrożenia, pozwalają obsłużyć wymagane obciążenie albo spełnić konkretne wymagania bezpieczeństwa. Oczekuję jednak, że ich korzyści uzasadnią dodatkowy koszt i złożoność. Nie traktuję rozbudowy infrastruktury jako domyślnej odpowiedzi na problemy z wydajnością.

Lubię uporządkowane, dobrze prowadzone projekty, z jasno określonymi standardami rozwoju, testowania i wdrażania. Mam też duże doświadczenie w ratowaniu systemów z długiem technologicznym. Potrafię przeanalizować zastany kod, odnaleźć się w jego konwencjach i wprowadzać zmiany, które ułatwiają dalszą pracę: refaktoryzację, automatyczne testy czy CI/CD. W takich projektach szukam zarówno miejsc wymagających stabilizacji, jak i tych, w których można usunąć niepotrzebną komplikację.

Technologie

Backend

PHP Aplikacje, API i optymalizacja

Z PHP pracuję od wersji 4.2. Mam za sobą zarówno niewielkie serwisy, jak i rozbudowane aplikacje biznesowe, tworzone we własnych rozwiązaniach oraz we frameworkach Laravel, Yii i KohanaPHP. Pracowałem z kolejnymi wydaniami języka, w tym z PHP 8.4. Poza implementacją odpowiadałem za dobór technologii, projektowanie architektury aplikacji i ustalanie jej podstawowych założeń.

Duża część mojej pracy dotyczyła optymalizacji — zarówno podczas tworzenia nowych systemów, jak i przy rozwijaniu już istniejących. Korzystałem z narzędzi do debugowania i profilowania, między innymi Xdebug. Zajmowałem się całymi rozwiązaniami, więc analiza wydajności obejmowała nie tylko kod PHP, lecz także zapytania do bazy i konfigurację serwera.

Przez wiele lat prowadziłem też iFotos, własny hosting zdjęć oparty na Nginx, PHP-FPM, XCache i MySQL. W tym projekcie szczególnie ważne było dla mnie wykorzystanie dostępnego sprzętu i ograniczenie kosztów infrastruktury. Wykorzystałem w nim X-Accel-Redirect, aby PHP obsługiwało metadane, a wysyłaniem plików zajmował się Nginx.

Laravel API, kolejki i narzędzia aplikacji

W Laravelu pracowałem nad projektami o różnej skali: od niewielkich serwisów po rozbudowane aplikacje biznesowe. Budowałem widoki w Blade i REST API z dokumentacją Swagger. Tworzyłem własne polecenia Artisan do automatyzacji zadań oraz korzystałem z kolejek do obsługi procesów asynchronicznych.

Wdrażałem uwierzytelnianie oparte na JWT i obsługę kont użytkowników: rejestrację, logowanie, reset hasła oraz potwierdzanie adresu e-mail. Redis wykorzystywałem do przechowywania w cache danych, których pobieranie najbardziej obciążało aplikację i bazę.

Yii2 Systemy biznesowe i własne komponenty

Z Yii korzystałem w prostych aplikacjach CRUD i w większych systemach biznesowych. Jednym z nich był wielomodułowy system do zarządzania projektami budowlanymi. Pracowałem z ActiveRecord, migracjami schematu bazy i generatorem Gii, a także tworzyłem własne komponenty i widgety do wykorzystania w różnych częściach aplikacji.

Budowałem REST API z paginacją i dokumentacją, pisałem komendy konsolowe do automatyzacji zadań oraz wdrażałem role i uprawnienia oparte na RBAC. Przy bardziej obciążających zapytaniach korzystałem z cache w Redisie. Sporo pracy poświęciłem też tabelom, filtrowaniu, paginacji i raportowaniu — elementom powtarzającym się w wielu modułach systemu.

Dane i infrastruktura

MySQL Schematy, zapytania i transakcje

Z MySQL pracowałem zarówno przy projektowaniu nowych baz, jak i optymalizacji istniejących systemów. Zajmowałem się schematami, doborem typów danych i indeksów, w tym covering indexes, oraz rozwiązaniami wykorzystującymi dane GIS i JSON. Mam doświadczenie z MySQL 5.x i 8.x.

Pracowałem z transakcjami: autocommit, ręcznym START / COMMIT / ROLLBACK oraz rozwiązywaniem deadlocków przy różnych poziomach izolacji, między innymi READ COMMITTED i REPEATABLE READ.

Poza samymi zapytaniami zajmowałem się kopiami zapasowymi i odtwarzaniem danych przy użyciu mysqldump i phpMyAdmin. Konfigurowałem też użytkowników, role i uprawnienia. Bazy utrzymywałem między innymi w aplikacjach biznesowych oraz w moim hostingu zdjęć iFotos.

Nginx HTTP, reverse proxy i serwowanie plików

Z Nginxem pracuję od wersji 0.7. Używałem go w małych serwisach i środowiskach rozproszonych, do obsługi ruchu HTTP(S), jako reverse proxy oraz warstwę cache dla zasobów statycznych: CSS, JavaScriptu i multimediów.

Konfigurowałem rozdzielanie ruchu między backendami z użyciem least_conn i ip_hash. Stosowałem też limity limit_req_zone i limit_conn_zone, aby ograniczać przeciążenia i nagłe skoki ruchu. Przy wcześniejszych wdrożeniach przygotowywałem konfigurację HTTP/2 i korzystałem z http2_push_preload.

W iFotos wykorzystałem X-Accel-Redirect. PHP przygotowywało metadane i obsługiwało licznik odsłon w cache, a wysyłanie pliku przejmował Nginx. To był istotny element optymalizacji serwisu obsługującego wiele jednoczesnych pobrań.

Redis Cache wyników zapytań i sesji

Redis wykorzystywałem przede wszystkim jako cache wyników kosztownych zapytań, często pobieranych danych i sesji. W ten sposób ograniczałem liczbę odwołań do bazy i skracałem czas odpowiedzi aplikacji.

Dobierałem wartości TTL tak, aby pogodzić aktualność danych z obciążeniem bazy i zużyciem pamięci. Korzystałem z tego między innymi w projektach opartych na Laravelu i Yii, przy zapytaniach oraz fragmentach danych używanych w wielu miejscach aplikacji.

Docker Praca ze środowiskami Docker Compose

Z Dockerem pracowałem najczęściej na przygotowanych już konfiguracjach — obrazach i plikach Compose. Pozwalały uruchamiać kompletne środowiska aplikacji z PHP-FPM, Nginx, Redisem i MySQL.

Rozumiem budowę Dockerfile, konfigurację sieci i wolumenów oraz sposób połączenia kilku usług w Docker Compose. Znam zasady budowania i optymalizacji obrazów, wieloetapowe buildy oraz pracę z prywatnymi rejestrami kontenerów. W projektach korzystałem z Dockera przede wszystkim przy uruchamianiu środowisk i wdrażaniu aplikacji.

Interfejsy

JavaScript Czysty JS, jQuery i aplikacje webowe

Z JavaScriptem pracuję od czasów sprzed jQuery. Pisałem zarówno skrypty w czystym JS, jak i bardziej rozbudowane, modułowe aplikacje SPA. Korzystałem z jQuery oraz frameworków frontendowych, a przy utrzymaniu istniejących systemów pracowałem też z Node.js.

Znam mechanizmy języka: prototypy, hoisting, event loop i asynchroniczność. Zwracam uwagę na to, jak sposób organizacji kodu wpływa na zużycie pamięci przeglądarki. Przykładem jest tworzenie osobnych funkcji w każdej instancji obiektu zamiast współdzielenia metod przez prototyp — przy dużej liczbie obiektów taka różnica ma znaczenie.

Node.js nie jest moją ulubioną technologią, ale mam doświadczenie z jego utrzymaniem i refaktoryzacją. W jednym z projektów pracowałem nad modułami zarządzanymi przez PM2, w tym ich monitorowaniem i alertami.

Vue.js Widoki, komponenty i panele administracyjne

Vue poznałem później niż sam JavaScript, ale szybko polubiłem ten sposób budowania interfejsów. Komercyjnie tworzyłem w nim pojedyncze widoki i bardziej rozbudowane komponenty. Jednym z nich był własny moduł tabeli z paginacją po REST API, obsługą nagłówków paginacji i różnymi typami danych w kolumnach.

Pracowałem też nad panelem administracyjnym wykorzystującym Vue 3, Nuxt i TypeScript. W komponentach korzystałem z propsów, emitowania zdarzeń i slotów, aby wspólny element można było dostosować do różnych widoków bez jego kopiowania. Odpowiada mi organizacja kodu w plikach .vue, w których struktura, zachowanie i styl komponentu są zebrane w jednym miejscu.

Python i urządzenia

Python Przetwarzanie danych, skrypty i prototypy

Pythona poznałem na studiach i właśnie w nim napisałem całą pracę inżynierską. Mam w nim mniej doświadczenia komercyjnego niż w PHP, ale wykorzystywałem go zarówno we własnych projektach, jak i w systemach produkcyjnych. W projektach własnych pracowałem między innymi z przetwarzaniem plików wideo, audio i zdjęć.

W pracy komercyjnej tworzyłem skrypty do transformacji i analizy dużych zbiorów danych: grupowania, filtrowania oraz masowej zmiany nazw i zawartości plików lub rekordów w bazie według złożonych wzorców. Projektowałem również algorytmy weryfikacji kandydatów oparte na IRT.

Python był też podstawą mojego systemu zabezpieczeń nieruchomości na Raspberry Pi. Projektowałem w nim zdalnie komunikujące się interkomy, wykorzystujące WebSockety, szyfrowane połączenia i uwierzytelnianie tokenami JWT. Ten projekt łączył programowanie z elektroniką i organizacją komunikacji między urządzeniami.

Flask API i komunikacja z urządzeniami

Flaska poznałem w 2010 roku. Korzystałem z niego do budowania REST API, organizując kod w blueprintach, zabezpieczając endpointy tokenami JWT i przygotowując dokumentację zgodną z OpenAPI. Do migracji bazy danych używałem Flask-Migrate.

Flask-SocketIO wykorzystywałem do dwukierunkowej komunikacji ze zdalnymi urządzeniami, między innymi w moich domofonach opartych na Raspberry Pi. W tym rozwiązaniu urządzenia komunikowały się przez szyfrowane połączenia, bez potrzeby nadawania każdemu z nich publicznego adresu IP.

Raspberry Pi Własne prototypy sprzętowe

W projektach z Raspberry Pi łączyłem elektronikę i oprogramowanie. Obsługiwałem kamerę z podświetleniem podczerwonym do nagrań nocnych, mikrofon, wzmacniacz z głośnikami, klawiaturę matrycową 3 × 4 oraz niewielki wyświetlacz do interakcji z użytkownikiem.

Całością sterował Python. Biblioteki GPIO wykorzystywałem do odczytu przycisków i sterowania wyjściami, a Flask-SocketIO do zdalnej komunikacji. Do systemu podłączałem też przekaźniki i sterowniki automatyki.

Obudowy projektowałem w 3ds Max i przygotowywałem do druku 3D, dopasowując je do rozmieszczenia wszystkich modułów. Są to własne, działające prototypy — obejmujące oprogramowanie, elektronikę i fizyczną obudowę urządzenia.

Grafika i 3D

Photoshop Zdjęcia i materiały do stron

Photoshopa używam od ponad 20 lat. Przy pracy nad stronami samodzielnie przygotowuję potrzebne materiały: tnę layouty, wyodrębniam elementy graficzne i opracowuję je do wykorzystania w interfejsie. Dotyczy to również cieni, przejść między warstwami oraz elementów wymagających przezroczystego lub półprzezroczystego tła.

Przygotowuję i optymalizuję zdjęcia oraz ikony: dobieram rozmiary, kompresję i usuwam zbędne metadane. Korzystam też z narzędzi AI, między innymi przy zaznaczaniu i retuszu. Umiejętności graficzne przydają mi się przede wszystkim wtedy, gdy poza kodem trzeba przygotować albo poprawić konkretny materiał do strony.

3ds Max Od modów do modeli do druku 3D

Z 3ds Max zetknąłem się prawie 20 lat temu, z zainteresowania grami i chęci tworzenia własnych światów. Zajmowałem się modelowaniem obiektów i scen, ustawianiem świateł do renderów fotorealistycznych, podstawami animacji i prostymi symulacjami cząsteczkowymi.

Przez kilka lat byłem głównym grafikiem 3D przy hobbystycznym modzie „Mroczne Tajemnice” do Gothic I. Odpowiadałem za przygotowanie assetów: od koncepcji po gotowe modele, siatki poligonowe i tekstury.

Dziś nie pracuję w 3ds Max na co dzień, ale nadal wykorzystuję te umiejętności przy projektowaniu elementów do druku 3D i przygotowywaniu wizualizacji koncepcyjnych. W ten sposób powstawały między innymi obudowy do moich prototypów na Raspberry Pi.