15+
Lat Doświadczenia
50+
Zrealizowanych Projektów
100+
Poznanych Technologii
500+
Rozwiązanych Problemów
Moje Projekty
Jestem dumny z projektów i zadań, które realizowałem, w tym z trudnych problemów, które udało mi się skutecznie przeanalizować i rozwiązać. Opisałem je tutaj, aby były dowodem na moje doświadczenie oraz umiejętności techniczne, które wykorzystuję w pracy nad każdym projektem.
Stworzone Projekty
Proces tworzenia oprogramowania składa się z dwóch kluczowych etapów: zaprojektowania rozwiązania i jego implementacji. Aby osiągnąć wysokiej jakości rezultat, każda z tych faz musi być wykonana z pełnym profesjonalizmem. Wymaga to nie tylko doświadczenia, ale także zaawansowanych umiejętności technicznych. Poniżej znajdziesz listę projektów, które zrealizowałem w wolnym czasie, wykorzystując te umiejętności.
Jopama – Skalowalna i odporną na awarię baza danych
Jopama to projekt naukowy, którego celem było stworzenie innowacyjnej bazy danych charakteryzującej się wysoką skalowalnością i odpornością na awarie. W ramach tego projektu zaprojektowałem nowatorską architekturę systemu, a następnie zaimplementowałem prototyp tej bazy danych.
Aby potwierdzić skuteczność rozwiązania, przeprowadziłem szereg eksperymentów, które wykazały, że system spełnia założone wymagania dotyczące zarówno skalowalności, jak i odporności na awarie. Wyniki eksperymentów potwierdziły skuteczność zaproponowanej architektury w rzeczywistych warunkach.
Więcej szczegółów o projekcie można znaleźć na stronie: Jopama na GitHubie.
SwiftFileSend / FileNeo - Serwis do udostępniania plików
Ten serwis umożliwia szybkie i łatwe udostępnianie plików, w tym dużych plików, innym osobom. Użytkownik wybiera plik, który chce udostępnić, a następnie plik jest przesyłany na serwer. Po przesłaniu, użytkownik otrzymuje link do pliku, który może następnie udostępnić innym osobom – na przykład za pomocą e-maila lub komunikatora.
Serwis korzysta z bezpiecznego połączenia HTTPS, co zapewnia ochronę danych użytkowników. Serwis jest dostępny pod dwoma adresami: swiftfilesend.com i fileneo.com.
Rowerek - Oprogramowanie do konwersji roweru na rower elektryczny
Ten projekt polegał na stworzeniu oprogramowania do konwersji tradycyjnego roweru na rower elektryczny. Opracowałem system sterowania silnikiem, który umożliwia użytkownikowi regulację prędkości za pomocą manetki gazu, a sterownik silnika wykorzystuje sygnał PWM do kontroli obrotów.
Dodatkowo, rower może być kontrolowany przez telefon komórkowy za pomocą Bluetooth, umożliwiając ustawienie maksymalnej prędkości oraz przyspieszenia roweru. Oprogramowanie jest kompatybilne z platformami takimi jak Arduino Uno i ESP32.
Umiejętności Techniczne
Aby dostarczyć skuteczne rozwiązanie, oprogramowanie musi nie tylko działać zgodnie z wymaganiami, ale również efektywnie. Posiadam umiejętności, które pozwalają mi rozwiązywać trudne techniczne wyzwania. Poniżej opisuję kilka sytuacji, w których wykorzystałem swoje doświadczenie oraz wiedzę, aby sprostać skomplikowanym problemom.
SSD Write Amplification
Po krótkim czasie od sformatowania, dysk SSD zaczął działać 5-krotnie wolniej niż początkowo, a jego wydajność odbiegała od wartości podanych w specyfikacji. Przyczyną problemu było brak odpowiednich informacji wysyłanych do dysku przez system operacyjny w celu wskazania niepotrzebnych bloków. Dyski SSD wymagają specjalnej operacji wymazywania nieużywanych bloków, co w tradycyjnych dyskach nie występuje.
System operacyjny, a dokładniej moduł systemu plików, nie informował dysku o zwolnionych blokach (poprzez scsi discard request), przez co dysk traktował wszystkie bloki jako używane. Skutkowało to wywołaniem problemu SSD Write Amplification — podczas zapisu nowego bloku, dysk musiał dodatkowo przepisać całą grupę bloków, co znacząco obniżało wydajność.
Rozwiązaniem problemu było skonfigurowanie systemu operacyjnego oraz systemu plików, aby prawidłowo informowały dysk o zwolnionych blokach, co pozwoliło na przywrócenie pełnej wydajności. Nowsze systemy operacyjne coraz lepiej radzą sobie z takim problemem.
Optimizing Spark Join Performance
W systemie Apache Spark dostępne są różne metody wykonania operacji Join. Jedną z najogólniej dostępnych metod jest sort-merge-join, która wiąże się z pewnym kosztem, ponieważ wymaga przepisywania i reorganizacji danych. Gdy jednak jedna z tabel jest stosunkowo mała, bardziej efektywną metodą jest broadcast-join. Spark wybiera metodę łączenia danych w zależności od statystyk, w których znajdują się informacje o rozmiarach tabel.
Po ulepszeniu statystyk w jednej z wersji Sparka, pipeline, który wcześniej działał na sort-merge-join, zaczął działać na nowym broadcast-join. Oczekiwano, że operacja ta będzie szybsza, jednak w rzeczywistości proces wykonywał się wolniej. Okazało się, że po wykonaniu join wykonywane były dodatkowe operacje agregujące, które korzystały z optymalizacji map-side aggregation. Ta optymalizacja działała efektywnie z sort-merge-join, ponieważ ta metoda reorganizowała dane w sposób zgodny z wymaganiami agregacji. Natomiast przy broadcast-join, dane były uporządkowane w sposób, który nie odpowiadał wymaganym agregacjom. W wyniku tego, optymalizacja map-side aggregation stała się nieefektywna, a całkowity czas wykonywania pipeline'u wydłużył się.
Rozwiązaniem tego problemu było wymuszenie reorganizacji danych niezależnie od metody join stosowanej przez Spark, co pozwoliło przywrócić optymalną wydajność.
Small Thread Pool
Współczesne aplikacje często wykorzystują pulę wątków (thread pool) w celu zwiększenia wydajności i równoległego przetwarzania zadań. Optymalna liczba wątków w tej puli zależy jednak od wielu czynników, takich jak specyfika danych wejściowych, zasoby maszyny czy interakcje z innymi komponentami systemu. Aby ocenić, czy pula wątków jest odpowiednio dobrana, konieczne są odpowiednie statystyki z działania aplikacji.
Te statystyki mogą pochodzić bezpośrednio z aplikacji lub być zbierane przez dodatkowe narzędzia diagnostyczne, takie jak profiler. W przypadku, gdy analiza wykazuje, że aplikacja napotyka na wąskie gardło (bottleneck) związane z przetwarzaniem realizowanym przez określoną grupę wątków, rozwiązaniem jest zwiększenie rozmiaru tej puli. Taka zmiana często prowadzi do znacznego wzrostu wydajności, nawet kilkakrotnego.
Blocked IO Threads
W pewnej aplikacji, która miała za zadanie przetwarzać 5000 katalogów i wybierać 50 najbardziej istotnych, a pozostałe usuwać, użyto wątków do zrównoleglenia operacji. Każdy wątek przetwarzał katalog, porównując go z już przetworzonymi danymi, a następnie usuwał niepotrzebne katalogi. Jednak zauważono, że cały proces trwał nieproporcjonalnie długo, szczególnie gdy system przechowywania plików był wolniejszy.
Po szczegółowej analizie okazało się, że zamiast wielu równoczesnych operacji na systemie plików, była wykonywana tylko jedna operacja na raz. Przyczyną tego problemu było użycie blokady synchronized w celu zbierania dokładnych statystyk. Ta blokada powodowała, że operacje na systemie plików były wykonywane sekwencyjnie, co znacznie ograniczało wydajność.
Out Of Memory in Hadoop Azure Data Lake Storage
Pewna aplikacja służyła do kopiowania katalogów pomiędzy Amazon S3 i Azure Data Lake Storage. Wykorzystywała ona pulę wątków, aby kopiować wiele plików równolegle. Jednak aplikacja nagle przestawała działać z powodu braku pamięci (Out of Memory).
Po szczegółowej analizie okazało się, że biblioteka Hadoop alokuje bardzo duże bufory dla każdego otwartego pliku w Azure Data Lake Storage. Aplikacja przetwarzała wiele plików równocześnie, co prowadziło do nadmiernej alokacji pamięci. Rozwiązaniem problemu było zmniejszenie rozmiaru alokowanych buforów, co pozwoliło na bardziej efektywne zarządzanie pamięcią.
Ineffective logs on S3
Snowflake wprowadził usługę Snowpark Container Services, która umożliwia uruchamianie kontenerów Docker w ramach Snowflake’a. Pracowałem z aplikacją, która została uruchomiona na Snowflake’u w formie kontenera. Okazało się, że aplikacja działała bardzo wolno w porównaniu do wersji uruchamianej lokalnie na moim laptopie.
Po dokładnej analizie okazało się, że problemem były logi aplikacji, które były zapisywane do Snowflake Stage – usługi, która wykorzystuje Amazon S3 do przechowywania danych. Okazało się, że sposób zapisywania logów (append + sync/flush) w tym przypadku był bardzo nieefektywny. Rozwiązaniem było zmienienie konfiguracji aplikacji, aby logi były zapisywane lokalnie, zamiast do Snowflake Stage.
Buggy JVM intristics
Podczas pracy z Hadoop’em napotkałem dziwny problem. Używałem narzędzia Hadoopowego do odczytu pliku, które na ogół działało prawidłowo, ale co jakiś czas kończyło się wyjątkiem IndexOutOfBoundsException. Dzięki temu wyjątku udało się określić funkcję, w której wystąpił błąd, oraz tablicę, której dotyczył.
Po dokładnej analizie kodu byłem przekonany, że taki błąd nie powinien wystąpić. Szukając więcej informacji na temat tej funkcji w internecie, okazało się, że nie jest to zwykła funkcja, lecz tzw. JVM intrinsic. Co to oznacza? JVM intrinsic to funkcja, która może być zastąpiona zoptymalizowaną wersją specyficzną dla konkretnej platformy.
Ta informacja okazała się kluczowa, ponieważ błąd nie leżał w domyślnej funkcji, ale w jej zamienniku. Problem został rozwiązany przez zaktualizowanie wersji Javy, w której poprawiono błąd w zamienniku funkcji.
CO OFERUJĘ
Zawsze chętnie porozmawiam!
Tworzenie nowego oprogramowania
Jeśli potrzebujesz nowego oprogramowania, chętnie Ci pomogę. Na początek chciałbym porozmawiać, aby dokładnie zrozumieć Twoje potrzeby. Następnie ustalimy sposób dalszej współpracy, który będzie zależny od takich czynników jak rozmiar projektu czy jego krytyczność. Proces tworzenia oprogramowania obejmuje dwie kluczowe fazy: część koncepcyjną/projektową i część implementacyjną/programistyczną. W przypadku większych projektów praca jest podzielona na etapy. Jestem elastyczny i dbam o to, aby współpraca była komfortowa, przejrzysta i efektywna dla obu stron.
Optymalizacja istniejącego systemu
Jeśli Twoje obecne oprogramowanie działa zbyt wolno i chciałbyś to zmienić, chętnie Ci pomogę. Na początek porozmawiamy, aby ustalić, jak będzie wyglądać nasza współpraca. Następnie przeanalizuję, co w Twoim systemie działa wolno, dlaczego tak się dzieje i jakie są możliwe rozwiązania. Będę potrzebował dostępu do Twojego systemu/środowiska oraz listy kroków, które eksponują to zachowanie. W zależności od złożoności systemu analiza przyczyny problemu może zająć więcej lub mniej czasu. Po zidentyfikowaniu przyczyny przejdziemy do analizy możliwych rozwiązań, a następnie wybierzemy najlepsze i wdrożymy je w Twoim środowisku.