Microservices interview questions - przygotowanie do rozmowy

Bruno Krawczyk 19 lipca 2026
Diagram porównujący mikroserwisy (wiele usług, wspólny UI) z monolitem (pojedyncza usługa, UI). Przydatne do pytań o mikroserwisy.

Spis treści

Rozmowa o mikroserwisach szybko wychodzi poza definicję i pytanie o REST. Rekruter chce sprawdzić, czy potrafisz podejmować decyzje przy awariach, opóźnieniach, niespójności danych i rosnącej skali. Listy oznaczane jako microservices interview questions pomagają uporządkować przygotowanie, ale najwięcej zyskasz wtedy, gdy nauczysz się uzasadniać wybór konkretnego wzorca.

Najważniejsze elementy dobrej odpowiedzi o mikroserwisach

  • Granice usług powinny wynikać z domeny biznesowej, a nie z liczby klas czy tabel.
  • Własność danych oznacza, że każdy serwis sam zarządza swoim modelem i nie udostępnia bezpośrednio bazy innym usługom.
  • Odporność wymaga timeoutów, limitów ponowień, circuit breakera i ochrony przed kaskadowymi awariami.
  • Spójność danych często jest osiągana przez Sagę, zdarzenia i wzorzec transactional outbox.
  • Obserwowalność obejmuje metryki, logi, śledzenie rozproszone i korelację żądań.

Diagram architektury mikrousług: API Gateway, usługi (katalog, zamówienia, płatności), broker zdarzeń, obserwacja, odkrywanie usług. Kluczowe dla pytań na rozmowie o pracę z mikrousługami.

Co naprawdę sprawdza rozmowa o mikroserwisach

Najczęściej nie chodzi o recytowanie definicji. Dobra odpowiedź pokazuje, że rozumiesz koszt rozproszenia systemu: komunikacja odbywa się przez sieć, procesy mogą działać niezależnie, a pojedyncza operacja może zakończyć się częściowym sukcesem.

Czym mikroserwisy różnią się od monolitu?

Monolit jest wdrażany jako jedna jednostka, nawet jeśli ma dobrze podzielony kod. Mikroserwisy to zestaw usług, które można rozwijać, wdrażać i skalować niezależnie, zwykle wokół osobnych możliwości biznesowych.

Nie odpowiadam jednak, że mikroserwisy są po prostu „lepsze”. Ich największą zaletą jest autonomia zespołów i niezależne wdrażanie, ale ceną stają się sieć, monitoring, automatyzacja oraz problemy typowe dla systemów rozproszonych.

Obszar Monolit Mikroserwisy
Wdrożenie Jedna jednostka wdrożeniowa Niezależne wdrażanie usług
Dane Często wspólna baza i transakcje lokalne Osobne dane i spójność między usługami
Skalowanie Zwykle skalowanie całej aplikacji Skalowanie tylko obciążonych usług
Debugowanie Zwykle prostsze Wymaga logów, metryk i distributed tracingu
Ryzyko Awaria może objąć całą aplikację Awaria jednej usługi może rozlać się na inne

Kiedy mikroserwisy są złym wyborem?

To pytanie często odróżnia osobę, która zna modne hasła, od inżyniera rozumiejącego konsekwencje. Mikroserwisy mogą być złym wyborem dla małego produktu, niewielkiego zespołu i słabo poznanej domeny, gdy niezależne wdrażanie nie daje realnej korzyści.

Jeżeli aplikacja ma kilka funkcji, jeden zespół i prosty model danych, modularny monolit będzie zwykle tańszy w utrzymaniu. Sam zacząłbym od wyraźnych modułów i dopiero później wydzielał usługi, gdy pojawi się konkretny powód, na przykład różne tempo zmian, osobne wymagania skalowania albo niezależne zespoły.

Jak wyznaczyć granice mikroserwisu?

Najlepszą odpowiedzią jest odwołanie do bounded context z Domain-Driven Design. Granica usługi powinna obejmować spójny fragment domeny, własne reguły biznesowe i dane potrzebne do ich realizacji.

Przykładowy system sprzedażowy może mieć usługi Zamówienia, Płatności, Magazynu i Powiadomień. Nie dzieliłbym go jednak automatycznie na usługę klientów, adresów, koszyka i każdej tabeli. Zbyt drobny podział prowadzi do wielu wywołań sieciowych i tak zwanego distributed monolith, czyli systemu rozdzielonego na procesy, ale nadal silnie zależnego.

Po czym poznać distributed monolith?

W takim systemie usługi są formalnie niezależne, lecz muszą być wdrażane razem, korzystają ze wspólnej bazy albo wykonują długie łańcuchy synchronicznych wywołań. Charakterystyczny sygnał to sytuacja, w której zmiana jednego kontraktu wymaga jednoczesnej aktualizacji pięciu usług.

W rozmowie warto powiedzieć, jak ograniczyć ten problem: własność danych, stabilne kontrakty API, zdarzenia domenowe, kompatybilność wsteczna i zespoły odpowiedzialne za pełny cykl życia usługi. Sama liczba kontenerów nie tworzy dobrej architektury.

Najczęstsze pytania o komunikację i dane

Kiedy wybrać REST lub gRPC, a kiedy komunikację asynchroniczną?

Komunikacja synchroniczna pasuje do sytuacji, w której klient potrzebuje odpowiedzi od razu, na przykład podczas pobierania szczegółów zamówienia. REST jest prosty i dobrze współpracuje z przeglądarkami, natomiast gRPC może być wygodny w komunikacji wewnętrznej, gdy liczą się ściśle określone kontrakty i niskie opóźnienia.

Komunikacja asynchroniczna sprawdza się przy zdarzeniach, integracjach i zadaniach, które nie muszą zakończyć się w ramach jednego żądania HTTP. Wiadomość „Zamówienie utworzone” może uruchomić rezerwację towaru, wysłanie e-maila i aktualizację raportów bez blokowania klienta.

Nie używam asynchroniczności automatycznie. Broker wiadomości dodaje problemy z kolejnością, powtórzeniami, opóźnieniami i obsługą komunikatów zatrutych, dlatego wybór powinien wynikać z wymaganej latencji i modelu spójności.

Do czego służy API Gateway?

API Gateway jest punktem wejścia dla klientów. Może zajmować się uwierzytelnianiem, limitowaniem ruchu, routingiem, agregowaniem odpowiedzi oraz ukrywaniem wewnętrznej topologii usług.

Nie powinien jednak stać się miejscem całej logiki biznesowej. Jeżeli gateway wykonuje skomplikowane reguły, zaczyna być kolejnym monolitem. W większych systemach przydatny może być także wzorzec Backend for Frontend, w którym osobne API dopasowuje odpowiedź do potrzeb aplikacji webowej i mobilnej.

Co oznacza zasada database per service?

Każdy serwis powinien być właścicielem swoich danych i udostępniać je innym przez kontrakt, a nie przez bezpośredni dostęp do tabel. Nie oznacza to koniecznie osobnego serwera bazy dla każdej usługi. Ważniejsze jest to, aby inne komponenty nie omijały API i nie modyfikowały cudzych tabel.

Taki podział daje autonomię, ale utrudnia raportowanie i zapytania przekrojowe. Rozwiązaniem może być osobny model odczytowy, replikacja zdarzeń, CDC albo świadomie zaprojektowany proces ETL. Wspólna baza bywa wygodnym etapem migracji, lecz jako stała granica między usługami zwykle tworzy silne sprzężenie.

Jak obsłużyć transakcję obejmującą kilka usług?

W mikroserwisach rzadko próbuję odtwarzać jedną globalną transakcję obejmującą wszystkie bazy. Zamiast tego rozbijam proces na lokalne transakcje i definiuję, co ma się stać, gdy jeden krok się nie powiedzie.

Najczęściej pojawia się tutaj wzorzec Saga. Może działać choreograficznie, gdy usługi reagują na zdarzenia, albo orkiestracyjnie, gdy osobny komponent steruje przebiegiem procesu. W obu wariantach potrzebne są akcje kompensujące, na przykład zwrot płatności po nieudanej rezerwacji produktu.

Po co stosuje się transactional outbox?

Problem pojawia się wtedy, gdy usługa zapisze zmianę w bazie, ale ulegnie awarii przed wysłaniem zdarzenia do brokera. Wzorzec transactional outbox zapisuje dane biznesowe i zdarzenie w tej samej lokalnej transakcji, a osobny proces publikuje później komunikat.

Outbox nie zapewnia magicznie dostarczenia dokładnie raz. Konsument powinien być idempotentny, czyli ponowne przetworzenie tego samego komunikatu nie może zmienić wyniku w niepożądany sposób. Przydatny jest identyfikator wiadomości oraz tabela przetworzonych komunikatów.

Jak rozwiązać problem eventual consistency?

Eventual consistency oznacza, że różne modele danych mogą przez pewien czas pokazywać różne wartości, ale po poprawnym przetworzeniu zdarzeń dążą do zgodności. To rozsądny kompromis, gdy ważniejsza jest dostępność i niezależność usług niż natychmiastowa spójność wszystkich odczytów.

Na rozmowie warto podać konkretny przykład. Po opłaceniu zamówienia ekran może przez kilka sekund pokazywać status „przetwarzanie”, a nie „zakończone”. Jeśli domena nie dopuszcza takiego opóźnienia, trzeba zmienić projekt procesu, a nie udawać, że problem rozwiąże kolejna biblioteka.

Jak odpowiadać o odporności, obserwowalności i bezpieczeństwie

Co zrobisz, gdy zależna usługa przestanie odpowiadać?

Pierwsza odpowiedź nie powinna brzmieć „dodam retry”. Ponowienia bez limitu mogą zwiększyć ruch i doprowadzić do kaskadowej awarii. Zacząłbym od timeoutu, limitu czasu całej operacji i jasnego zachowania awaryjnego.

Retry ma sens przy błędach przejściowych i powinien używać limitu oraz narastającego opóźnienia z losowym rozrzutem. Circuit breaker czasowo przerywa wywołania do niedostępnej usługi, a bulkhead izoluje zasoby, aby jedna zależność nie zużyła wszystkich wątków lub połączeń.

Przykładowo usługa rekomendacji może zostać pominięta, gdy nie odpowiada, ale brak potwierdzenia płatności nie powinien być traktowany jako sukces. Fallback musi być zgodny z regułą biznesową, nie tylko technicznie wygodny.

Jak monitorować system złożony z wielu usług?

Potrzebne są trzy grupy sygnałów: metryki, logi i ślady rozproszone. Metryki pokazują między innymi opóźnienie, liczbę błędów, przepustowość i zużycie zasobów. Logi wyjaśniają zdarzenie, a tracing pozwala prześledzić jedno żądanie przez wiele usług.

Każde żądanie powinno mieć correlation ID, przekazywane dalej przez HTTP lub komunikaty. W praktyce bardzo pomaga także mierzenie opóźnień kolejek, wieku najstarszej wiadomości i liczby komunikatów w dead-letter queue. Sam status „proces działa” nie mówi, czy użytkownik faktycznie otrzymuje poprawną odpowiedź.

Jak zabezpieczyć komunikację między usługami?

Odpowiedź powinna obejmować uwierzytelnianie, autoryzację i ochronę sekretów. OAuth 2.0 oraz OpenID Connect są często używane przy dostępie użytkownika, JWT przenosi informacje o tożsamości, a mTLS może potwierdzać tożsamość usług w komunikacji wewnętrznej.

Nie wystarczy powiedzieć, że „każda usługa ma token”. Trzeba wspomnieć o najmniejszych uprawnieniach, rotacji sekretów, szyfrowaniu transmisji, walidacji wejścia i ograniczeniu zaufania między komponentami. W systemie .NET warto też rozdzielić konfigurację od sekretów i nie umieszczać danych dostępowych w repozytorium.

Jak testować architekturę mikroserwisową?

Testy jednostkowe sprawdzają reguły w pojedynczej usłudze, ale nie wykrywają problemów z kontraktem. Do tego służą testy kontraktowe, które weryfikują zgodność producenta i konsumenta API lub zdarzeń.

Testy integracyjne powinny obejmować bazę, broker i zewnętrzne zależności. Testy end-to-end zostawiłbym dla najważniejszych ścieżek, ponieważ są wolniejsze i bardziej kruche. Przy systemach krytycznych warto również testować scenariusze awarii, opóźnień i ponownego dostarczenia komunikatu.

Jak rozwiązać zadanie system design na rozmowie

W zadaniu typu „zaprojektuj system zamówień” nie zaczynam od wymieniania Kafki, Kubernetes czy API Gateway. Najpierw ustalam wymagania: liczbę użytkowników, oczekiwaną latencję, dopuszczalny czas niedostępności, wymagania dotyczące płatności i to, które operacje muszą być natychmiastowe.

Przykładowy tok odpowiedzi

  1. Wyznacz granice domeny. Oddziel zamówienia, płatności, magazyn i powiadomienia, ale nie twórz usługi dla każdej tabeli.
  2. Opisz przepływ. Klient wysyła żądanie do API, usługa zamówień zapisuje dane i publikuje zdarzenie.
  3. Wybierz komunikację. Odczyt statusu może być synchroniczny, a powiadomienia i aktualizacja raportów asynchroniczne.
  4. Rozwiąż spójność. Proces płatności i rezerwacji obsłuż przez Sagę z jasno zdefiniowanymi kompensacjami.
  5. Dodaj odporność. Ustal timeouty, retry, circuit breaker, idempotencję oraz zachowanie po awarii brokera.
  6. Opisz operacje. Wymień metryki, trace’y, alerty, wdrożenia bez przestoju i sposób wycofania błędnej wersji.

Taki schemat pokazuje sposób myślenia, a nie tylko znajomość nazw wzorców. Rekruter może dopytać, co stanie się po podwójnym kliknięciu przycisku płatności. Wtedy warto wskazać klucz idempotencji, unikalny identyfikator operacji i bezpieczne sprawdzenie jej wcześniejszego wyniku.

Jak mówić o skalowaniu?

Najpierw określ wąskie gardło. Usługa katalogu może potrzebować cache i replik odczytowych, natomiast przetwarzanie płatności może wymagać ostrożnego limitowania oraz kolejki. Skalowanie wszystkich komponentów tak samo jest proste, ale zwykle kosztowne.

Ważna jest też ochrona przed przeciążeniem. Kolejka, backpressure i limit liczby równoległych operacji pomagają utrzymać system przy nagłym skoku ruchu. Samo zwiększenie liczby instancji nie rozwiąże problemu, jeśli bottleneckiem jest wspólna baza albo zewnętrzny dostawca.

Przeczytaj również: Logika biznesowa w .NET - jak uporządkować reguły aplikacji

Jak opowiedzieć o wdrażaniu i wersjonowaniu?

Usługi powinny mieć niezależne pipeline’y, automatyczne testy, migracje danych i możliwość szybkiego wycofania wersji. Przy API i zdarzeniach preferuję kompatybilne zmiany: najpierw dodanie nowego pola, później migracja konsumentów, a dopiero na końcu usunięcie starego.

Wdrożenia canary lub blue-green ograniczają ryzyko, ale wymagają poprawnego routingu, monitoringu i planu migracji. Nie ma sensu mówić o wdrożeniu bez przestoju, jeśli zmiana schematu bazy wymaga zatrzymania wszystkich usług.

Błędy, które obniżają ocenę kandydata

Najczęstszy błąd to przedstawianie mikroserwisów jako rozwiązania każdego problemu. Doświadczony kandydat potrafi powiedzieć, że prostsza architektura może być lepszą decyzją, jeśli nie ma potrzeby niezależnego skalowania i wdrażania.

  • „Każda usługa musi mieć osobny serwer bazy” - ważniejsza jest własność danych i brak bezpośredniego dostępu innych usług.
  • „Retry naprawia awarie sieci” - bez limitów retry może wywołać lawinę kolejnych żądań.
  • „Kafka zapewnia dokładnie jednokrotne przetworzenie” - konsument nadal powinien być idempotentny.
  • „API Gateway może zawierać całą logikę” - wtedy powstaje centralny punkt sprzężenia i awarii.
  • „Eventual consistency oznacza utratę danych” - to model czasowej niespójności, który wymaga jawnych reguł i monitorowania.
  • „Kubernetes rozwiązuje problemy architektury” - orkiestrator automatyzuje uruchamianie, ale nie naprawi złych granic usług ani błędnych transakcji.

Unikałbym też odpowiedzi złożonych wyłącznie z nazw narzędzi. Azure Service Bus, Docker, Kubernetes czy ASP.NET Core mogą być elementami rozwiązania, ale najpierw trzeba wyjaśnić jaki problem rozwiązują i jaki koszt wprowadzają.

Dobra odpowiedź kończy się decyzją

Przed rozmową przygotuj dwa konkretne przykłady. W pierwszym pokaż projekt lub funkcję, za którą odpowiadałeś, a w drugim opowiedz o awarii, kompromisie albo decyzji, którą dziś podjąłbyś inaczej.

Najmocniejsza odpowiedź ma prosty rytm: opis problemu, wybrany wzorzec, uzasadnienie, ryzyko i sposób pomiaru efektu. Gdy potrafisz przejść od granic domeny przez komunikację i dane aż do odporności oraz obserwowalności, pokazujesz nie tylko znajomość mikroserwisów, ale przede wszystkim dojrzałość projektową.

FAQ - Najczęstsze pytania

Mikroserwisy mogą być nieopłacalne dla małego produktu, niewielkiego zespołu i słabo poznanej domeny. Jeśli aplikacja ma kilka funkcji, jeden zespół i prosty model danych, modularny monolit zwykle ogranicza koszty sieci, monitoringu i wdrożeń.

Należy rozbić proces na lokalne transakcje i zastosować wzorzec Saga. Saga może być choreograficzna lub orkiestracyjna, a w przypadku niepowodzenia powinna uruchamiać akcję kompensującą, na przykład zwrot płatności po nieudanej rezerwacji produktu.

Transactional outbox zapisuje zmianę biznesową i zdarzenie w tej samej lokalnej transakcji, a później publikuje komunikat do brokera. Nie gwarantuje jednak dostarczenia dokładnie raz, dlatego konsument musi bezpiecznie obsługiwać ponowne przetworzenie, korzystając na przykład z identyfikatora wiadomości i tabeli przetworzonych komunikatów.

Najpierw należy ustawić timeout i limit czasu całej operacji oraz określić zachowanie awaryjne. Retry powinien mieć limit, narastające opóźnienie i losowy rozrzut, a circuit breaker może czasowo przerwać wywołania. Fallback musi być zgodny z regułą biznesową, ponieważ brak potwierdzenia płatności nie może być traktowany jak sukces.

Oceń artykuł

Ocena: 0.00 Liczba głosów: 0

Tagi

saga
outbox
api gateway
obserwowalność
idempotencja
Autor Bruno Krawczyk
Bruno Krawczyk
Mam na imię Bruno i od 8 lat zgłębiam tajniki programowania w ekosystemie .NET, chmury Azure oraz sztucznej inteligencji. Moja przygoda z technologią zaczęła się od ciekawości, jak złożone systemy mogą ułatwiać codzienne życie i rozwiązywać realne problemy. Dziś moją misją jest dzielenie się tą wiedzą, starając się przybliżyć nawet najbardziej skomplikowane zagadnienia w sposób zrozumiały i przystępny dla każdego. W moich artykułach na kursdotnet.pl skupiam się na praktycznych aspektach, analizuję najnowsze trendy i weryfikuję informacje, aby dostarczyć Wam treści, które są nie tylko dokładne i aktualne, ale przede wszystkim użyteczne w Waszej własnej ścieżce rozwoju technologicznego.

Udostępnij artykuł

Napisz komentarz