Code review — co to i dlaczego uczy szybciej niż tutorial

Tutorial uczy, jak wygląda dobrze zachowujące się wejście. Recenzent wskazuje konkretną linijkę, w której założyłeś, że tak właśnie będzie, i pyta: „a jeśli nie". Ta różnica — przypadek ogólny kontra Twoja konkretna linijka — to większość powodu, dla którego review uczy szybciej niż oglądanie cudzego, czystego przykładu. Działa to jednak tylko wtedy, gdy osobie albo systemowi zostawiającemu komentarz można zaufać. Większość wartości review nie leży w samym komentarzu. Leży w tym, czy możesz zaufać ocenie, na której ten komentarz stoi.

Code review — co to jest?

Code review to sytuacja, w której ktoś inny czyta napisany przez Ciebie kod — zanim trafi dalej — i mówi, co jest z nim nie tak: błąd, pominięty przypadek, decyzja, którą trzeba obronić. To nie jest pieczątka zaliczono/niezaliczono. To informacja zwrotna przypięta do konkretnej linijki, w konkretnym kontekście, na którą możesz zareagować od razu. Wynikiem nie jest „8/10". Wynikiem jest „co się dzieje tutaj, gdy lista jest pusta?".

Dlaczego komentarz przy Twoim kodzie bije akapit w tutorialu

Tutorial musi generalizować. Piszesz go — a właściwie ktoś go pisze — dla dziesięciu tysięcy czytelników, którzy nigdy nie widzieli Twojego kodu, więc uczy kształtu, jaki problem zwykle przyjmuje: „zawsze waliduj wejście", „uważaj na puste kolekcje". Kiwasz głową, bo rada jest słuszna, a potem idziesz i piszesz dokładnie ten błąd, przed którym ostrzegała — bo ostrzeżenie było abstrakcyjne, a Twój błąd konkretny, a abstrakcje nie przyklejają się do konkretnych chwil tak, jak trafienie wprost.

Review pomija etap generalizacji. Nie mówi w powietrze „uważaj na puste kolekcje". Mówi „linijka 14 nie obsługuje pustej listy" — o funkcji, którą napisałeś godzinę temu, którą jeszcze pamiętasz pisać, w pliku, który wciąż masz otwarty. Odstęp między błędem a poprawką to minuty, nie tygodnie między „obejrzałem film o programowaniu defensywnym" a „trafiłem na przypadek, o którym on był". Krótkie pętle informacji zwrotnej to powód, dla którego ocena na stronie celuje w mniej niż 30 sekund od zgłoszenia do wyniku — nie dlatego, że szybkość sama w sobie jest cnotą, ale dlatego, że poprawka, która przychodzi, gdy jeszcze pamiętasz swój tok myślenia, uczy; ta, która przychodzi po tym, jak już poszedłeś dalej, zostaje tylko przejrzana po łebkach.

Prawdziwy przykład

Oto pierwsza wersja funkcji, która wyciąga wyświetlaną nazwę użytkownika z rekordu, który nie zawsze jest kompletny:

def display_name(user: dict) -> str:
    return user["first_name"] + " " + user["last_name"]
pytest -q
2 passed, 1 failed in 0.11s
FAILED test_display_name_missing_last_name - KeyError: 'last_name'

Nieudany test robi swoje — to sygnał obiektywny, nie opinia, i już wskazuje, gdzie szukać. Komentarz recenzenta dokłada część, której traceback nie da: dlaczego to ma znaczenie. „To wywala stronę profilu każdemu kontu w trakcie rejestracji — zwróć to, co masz, zamiast rzucać wyjątek". To rubrykowa strona oceny, część, która tłumaczy rozumowanie stojące za liczbą, nie tylko samą liczbę. Poprawka:

def display_name(user: dict) -> str:
    first = user.get("first_name", "")
    last = user.get("last_name", "")
    return f"{first} {last}".strip() or "Unnamed user"
pytest -q
4 passed in 0.13s

Nic w tym nie wymagało nowej wiedzy o Pythonie — dict.get nie było tu lekcją. Lekcją był nawyk: zakładaj, że rekord jest niekompletny, zanim założysz, że nie jest, bo na produkcji prędzej czy później będzie. Tego nawyku nie nabywasz z czytania o programowaniu defensywnym. Nabywasz go, gdy recenzent złapie ten jeden raz, kiedy go nie zastosowałeś.

Haczyk: review jest tak dobre, jak ocena, na której stoi

Wszystko to się sypie, jeśli informacji zwrotnej nie da się zaufać — jeśli „źle" oznacza tylko nastrój człowieka albo zgadywankę modelu, bez sposobu, żeby to zweryfikować. Review musi więc stać na czymś obiektywnym. W ProdQuest testy, lint, testy mutacyjne i kontrole bezpieczeństwa ważą co najmniej 70% oceny; rubryka jakości — część, która brzmi bardziej jak komentarz recenzenta niż zaliczono/niezaliczono — stanowi resztę, ograniczoną do 30%. Wynik nigdy nie jest samą opinią modelu językowego.

Testy mutacyjne warto wyjaśnić przy pierwszym spotkaniu, tak jak strona tłumaczy strefę najbliższego rozwoju, zamiast zakładać, że termin już znasz: tester mutacyjny bierze Twój przechodzący komplet testów i celowo psuje kod, który testują — zamienia < na <=, zmienia +1 na -1 — a potem ponownie odpala testy. Jeśli mimo to przechodzą, to znaczy, że wcale nie sprawdzały tego zachowania — tylko się uruchamiały. To test dla Twoich testów, i dlatego zielony ptaszek to nie to samo twierdzenie co „poprawne".

A ponieważ nawet w większości obiektywna ocena może się pomylić na przypadku brzegowym, jest wyjście, które nie polega na „kłóć się w komentarzach": jeden protest na zadanie, niezależna druga weryfikacja bez dostępu do pierwszej oceny. Tego akurat nie ma wątek na forum — jasnej ścieżki powrotu do zrozumiałej dla człowieka odpowiedzi, gdy uważasz, że maszyna się pomyliła, a nie tylko przycisku „w dół".

Czego to nie zastępuje

Review nie zastępuje praktyki, nie zastępuje też mięśnia procesowego — jak było w tekście o tym, dlaczego same katy nie uczą procesu inżynierskiego, komentarz z review to jeden ze składników większego nawyku, który obejmuje też strukturę projektu i decyzję, co w ogóle testować. To, co konkretnie kupuje Ci review, to szybkość korekty: najkrótszy możliwy dystans między napisaniem czegoś złego a zrozumieniem dokładnie dlaczego, na kodzie, który naprawdę jest Twój. Tutorial tego nie da, bo tutorial nigdy nie widział Twojego kodu.

Jeśli chcesz informacji zwrotnej tak konkretnej, na zadaniu, które faktycznie zrobiłeś, dołącz do zamkniętej bety — ocena tłumaczy samą siebie, a jeśli się myli, możesz to powiedzieć.