Mock Interview #3: Paweł, Obrona Wasileva-Kasrapova i request co trzy znaki

Tak, croissants to istotna część mojego życia.

kto pytał

Zabrzmi to dziwnie, ale lubię je robić, bo… po drodze można spierdolić dosłownie wszystko.

I nieważne, że:

  • przypilnujesz odpowiedniej temperatury przy laminacji (ang. lamination),
  • równomiernie rozdystrybuujesz masło pomiędzy warstwami ciasta,
  • idealnie wytniesz trójkąty (ang. threesomes).

Bo jeśli np. zjebiesz proofing, czyli doprowadzisz do sytuacji, w której ciasto jest w stanie overproofed lub underproofed, to robi się przykro.

Bo pomimo wszystkich starań, wychodzi bułka. Jeden gorszy obszar ma całkiem spory wpływ na całość.

A co to ma wspólnego z Mock Interview Pawła?

A no tym razem ma, ale o tym za chwilę.

Zapraszam.

W końcu Angular


Kolejne Mock Interview, a w zasadzie najpierw kolejne “Poznajmy się”.

Wpada Paweł i mówi:

Co było pierwsze, kura czy jajko

Nie no, nie było tak.

Było tak, że Paweł mówi:

3 lata Angulara

I to wystarczyło, żebym znowu był szczęśliwy, chociaż na chwilę.

Bo o ile szanuję chłopaków od Reacta - Kacpra i Matiego - o tyle Reacta per se dalej nie. (Backendowcy pewnie odetchnęli [o ile w piwnicy jest czym oddychać] z ulgą, że to nie o nich. Poczekajcie, na Was też przyjdzie czas.)

I rzeczywiście było czuć te 3 lata Angulara, ale jak się później okazało:

Paweł podchodzi do tematu praktycznie praktycznie (praktycznie²), ale brakuje poukładanych fundamentów.

Przekonałbym go merytorycznie™


Pytam:

Ty i drugi developer proponujecie dwa różne rozwiązania. Jego jest szybsze do wdrożenia, Twoje droższe, ale potencjalnie łatwiejsze w utrzymaniu. Jak podejmujecie decyzję?

Paweł zaczyna dobrze:

ile mamy czasu?

Ja:

przecież Ci mówiłem, na tę rozmowę tak około 1.5h

A tak serio - bardzo dobre, a zarazem retoryczne pytanie, ponieważ to oczywiste, że:

nie mamy czasu

I jako jedna z opcji padło słynne:

ship, refine…

I ja to propsuję, bo oczywiście, że lepiej dowieźć cokolwiek

a nie kitrać jak frajer

Coś dużo tu ostatnio Wojtka Sokoła.

No ale chodziło o Efekt Porozumienia, zatem pytam:

jak znajdziecie wspólne rozwiązanie?

P:

przekonałbym go merytorycznie

No tak.

Jak ktoś mnie pyta jak robię Croissanty, to mówię:

Cukierniczo™.


Tylko czym konkretnie?

  • Bezpieczeństwo?
  • Koszt późniejszego refactoringu?
  • Wpływ na inne feature’y?
  • Maintainability?

I to będzie wracało przez całe interview.

Pierwsza odpowiedź Pawła zazwyczaj jest sensowna.

Tylko rekruter musi jeszcze zapytać:

okej, ale co dokładnie masz na myśli?

A rekruter nie zawsze zapyta.

Czasem po prostu wpisze:

„Bałuty i Chojny naród spokojny”

i przejdzie do następnego człowieka.

AI działa u mnie lepiej


Pytam:

W zespole używacie Claude Code / Codexa i u Ciebie agent o wiele lepiej rozumie kod. Co może być przyczyną?

Paweł wymienia:

  • prompt
  • długość konwersacji
  • jakość kontekstu

Bardzo ładnie.

Ulica powiedziałaby:

dobrze się zachowałeś mordeczko, z fartem


Zatem okazuje się, że agent nie ma tak po prostu swojego ulubionego developera, a innych to jebać.

Nie otwiera repo i nie mówi:

ja pierdolę, znowu Maciek…


Ale to nie rozwiązuje meritum sprawy, bo przecież chcemy, żeby ten super agent uwielbiał wszystkich tak samo.

jak przełożyć to na pracę całego zespołu?

P:

…

I ja się nie dziwię, bo w tych czasach taką wiedzę można dobrze zmonetyzować, a nie ot tak (za backendowiec) oddawać zespołowi.

No, ale gdybyśmy jednak chcieli się podzielić z zespołem, to trzeba wynieść do repozytorium:

  • instrukcje
  • przykłady
  • skills
  • powtarzalne workflow

I zbudować wspólny kontekst, a nie (tylko u siebie):

kitrać jak frajer

TypeScript jest piękny


Pytam:

Po co TypeScript?

Paweł:

piękne typowanie

I nie zamierzam się z tym kłócić.

Czasem spoglądam na:

type UserId = Pick<User, 'id'>;

i też czuję motylki w brzuchu.

Ale niestety rekruter może wymagać więcej niż doznań estetycznych:

  • kontrakty
  • bezpieczniejszy refactor
  • wcześniejsze wykrywanie części błędów

Ale też ważna granica:

TypeScript nie załatwia runtime.

Możemy napisać:

http.get<User>('/api/user')

A backend może odpowiedzieć:

{"name": 30, "age": "hehe"}

I TypeScript nie wyjdzie wtedy z node_modules.

Nie podejdzie do backend developera.

Nie położy mu ręki na ramieniu.

Nie powie:

gościu.

Angular jest do bankowości


Skoro Paweł ma 3 lata Angulara:

Po co Angular?

Pada:

czytelna architektura

i:

większe systemy, bankowość, ERP

No dobra.

Ale co jeśli zrobię w Angularze aplikację do zwalniania backendowców i zastępowania ich kimś myślącym?

Przecież mogę.

Tak samo - „Czytelna architektura” coś tam mówi.

Ale znowu:

co to znaczy?

(Dobrze, że nie doszło do “struktura folderów”, bo jest taki Tomek, który by się zawiódł)

Angular daje nam sporo decyzji i narzędzi out of the box:

  • DI
  • routing
  • formularze
  • tooling

I ma za to cenę:

  • więcej zasad
  • większy próg wejścia
  • mniej swobody

A jak jesteś React’owcem, to wchodzisz na Reddita i tam gość pisze tak:

If there are any other form libraries I missed, drop them in the comments!

I mógł o niektórych zapomnieć, bo na tej liście jest ich 15.

A Angular mówi:

reactive forms

template-driven forms

signal forms

I to jest konkretna rozmowa o wyborze frameworka.

Trade-off.

asd


Jeśli znacie format, to wiecie, dlaczego weganie będą teraz rozczarowani:

  • mamy wyszukiwarkę
  • user pisze
  • każdy znak = request do API

Pytam:

jak to zoptymalizujesz?

Pierwszy pomysł:

request dopiero od X znaków

Dobra, to będzie fajny dodatkowy gate.

Potem:

zatwierdzanie Enterem

Też można.

Aczkolwiek jeśli tak zrobimy, to jednocześnie musimy mieć świadomość, że w tym samym momencie RxJS rozważa, że może jednak warto to wszystko pierdolnąć i wyjechać w Bieszczady.

I wtedy pojawia się rozwiązanie:

request po trzech znakach

A później po kolejnych trzech.

Czyli:

a
as
asd  -> REQUEST

k
ko
kot -> REQUEST

W praktyce zoptymalizowaliśmy liczbę requestów z:

n

do:

n / 3

Ale to nie rozwiązuje problemu.


Oczywiście finalnie dochodzimy do fundamentalnej konkluzji:

warto debouncować.


User pisze.

Pisze.

Pisze.

Przestał.

Dobra.

Teraz pytamy API.


Do tego np. distinctUntilChanged i mamy to.

Testy


Daję feature:

  • lista produktów
  • filtrowanie
  • szczegóły produktu
  • dodanie do koszyka

Pytam:

Jak dzielisz testy między unit, integration i E2E?

Nie wiem, czy Paweł gra w szachy, ale zrobił zajebiste otwarcie:

testy jednostkowe dla izolowanej logiki

Gambit Testerski.

I w sumie patrząc po kandydatach to często na początku jest Gambit Testerski - że unity, że można funkcje przetestować…

I tak sobie myślę, że w takim razie ja też muszę nazwać jakoś moje odbitki, niech będzie:

Obrona Wasileva-Kasrapova

I w sumie to brzmi legit. Wasilev, Kasrapov.

A backendowcy to mogą co najwyżej zbić konia.


Brakowało rozbicia feature’a pomiędzy różne rodzaje testowania, np.:

  • unitowo: czy sama logika filtrowania działa
  • integracyjnie: szukam produktu w szukajce i wyświetlam detale
  • e2e: jadę cały scenariusz

To wszystko Paweł oczywiście dostał w zdetalizowanej formie w raporcie.

Taką rozmowę mogę przeprowadzić z Tobą. Na razie 0 zł, w zamian za anonimową relację. Umów Mock Interview

Dependency Injection


Pytam:

Do czego najbardziej przydałoby Ci się Dependency Injection?

To “zależy” (bo zależność, heheh)

I przez moment Dependency Injection spotyka się z Change Detection.

<start_apelu>

A wspominam o tym tylko po to, żeby podnieść temat pt. “każdy może się po prostu pomylić” i nie powinniśmy tego punktować. Kandydaci na interview i tak są bombardowani 300 pytaniami z 5 różnych dziedzin. Naprowadzajmy.

<koniec_apelu>

P:

  • Wstrzykiwanie zależności,
  • Serwisy,
  • Singleton.

Spoko. Ale ja potrzebuję praktycznego zastosowania i odpowiedzi na pytanie pt.: “ale po co to wszystko? w czym Ci to pomaga?”

Przecież Singletona mogę sobie zbudować sam, po prostu będę pilnował w klasie jednej instancji jak Najmen Jasnej Góry.

I wtedy wchodzą np.:

  • inne implementacje zależnie od obszaru aplikacji
  • stuby i mocki w testach

I pięknie, dogadaliśmy się.

Praktyczny Paweł - praktycznie²


Zmiana bloku.

Pytam:

User mówi: chcę mieć to pokazane tylko dla naszych wewnętrznych użytkowników. Co robisz?

Paweł:

  • guard
  • warunek w template
  • rola usera/admina
  • token

Ja: Od razu zadzwoniłem do ubezpieczyciela.

(Bo Paweł rozjebał, ha)

Do feedbacku dorzuciłem dyrektywę, tak żeby zniwelować troszkę ten “warunek w template”.

Bug u Krzyśka z HR


Pytam:

Bug występuje tylko u jednego użytkownika, a u Ciebie nie. Co robisz?

I tutaj znowu pojawia się praktyczny Paweł - praktycznie²

  • Kontakt z userem,
  • Sprawdzenie produkcji,
  • Weryfikacja aktualnej wersji aplikacji.

Bardzo dobre.

Było sprawdzanie realnych różnic między środowiskami.

Można iść jeszcze szerzej:

  • konto
  • rola
  • feature flagi
  • tenant
  • cache
  • firewall

To również w feedbacku.

Krzysiek z HR może spać bezpiecznie.

ADR-067: bo się spieszyłem


Code review.

Patrzę na projekt.

W jednym miejscu zwykłe zmienne, w drugim Signals - use case ten sam.

Pytam:

dlaczego?

Paweł:

bo się spieszyłem

…

I wiecie co?

Szanuję.

W końcu dokumentacja architektoniczna zgodna ze stanem faktycznym.

ADR-067

Decision:
Mix signals and regular variables.

Context:
Deadline.

Rationale:
Spieszyłem się.

Status:
Accepted.

To jest dużo lepsze niż wymyślanie po fakcie:

świadomie zróżnicowałem granularność reaktywności zgodnie z charakterystyką domeny

Nie.

Był czwartek, coś trzeba było na piątek, coś tam tego.

Przynajmniej dobrze, że dzisiaj jest wtorek, a nie jutro jak wczoraj.

@ViewChild


W kodzie jest @ViewChild.

Pytam:

a rozważałeś viewChild()?

Paweł:

nie wiedziałem, że istnieje

I bardzo dobrze.

Nie dlatego, że dobrze nie wiedzieć.

Tylko dlatego, że np. nie każdy w komercyjnym projekcie pracuje już na najnowszych wersjach.

Druga sprawa - ważniejsze jest to, że

wiesz, o co chodzi mordeczko

Niż to, co zmieniło się w ostatniej wersji Angular 21.2.3 i dlaczego jeden z kontrybutorów zrobił ifa w ifie.

Ale kiedy dowiadujesz się podczas rozmowy:

hej, istnieje viewChild()

to warto zrobić następny krok:

okej, czyli tutaj mógłbym go użyć, tylko wtedy X, a potem Y

Pokazujesz, co robisz z nową informacją.

I właśnie tutaj jest Paweł


Czyli - nierówne fundamenty i kozak praktyka.

Najmocniej wypadał tam, gdzie była prawdziwa robota:

  • debugging
  • auth
  • UI
  • priorytetyzacja
  • analiza istniejącego kodu

Dodatkowo:

  • myśli na głos
  • dobrze reaguje na dodatkowe informacje
  • nie udaje wiedzy, której nie ma

I to się szanuje.

Paweł „Mid”


Finalnie widzę Pawła jako mida, który musi sobie poukładać parę rzeczy i poćwiczyć argumentację.

I przy każdej odpowiedzi zrobić sobie wewnętrzne:

dlaczego?

jaki koszt?

jaka alternatywa?

co może pójść źle?

Czyli zadbać o ten proofing, bo laminacja już jest spoko.

Podsumowując


Paweł dostał ode mnie 8 stron feedbacku.

  • każde pytanie
  • mocne strony
  • rzeczy do poprawy
  • konkretne kierunki pracy

A ja przećwiczyłem po raz kolejny robienie croissantów.

Więc obaj wyszliśmy z tego spotkania z nowymi kompetencjami.

Paweł wie, nad czym popracować.

A ja wiem, że możesz zrobić najlepszą laminację, ale przez zły proofing - wyjmiesz z pieca bułkę.

Chcesz, żebym Ciebie też tak przepytał? 0 zł, w zamian za anonimową relację jak ta wyżej. Umów Mock Interview