Jeden dzień planowania może zaoszczędzić tydzień kodowania. Historia Pawła Grudnia
– Gdy zadanie jest dobrze opisane, to proces programowania jest czystą przyjemnością. Ewentualne drobne nieścisłości są wyjaśniane na bieżąco i nie ma dużych zmian w wymaganiach – powiedział nam Paweł Grudzień, Senior Java Developer/Product Owner w XTB. Jak jego zdaniem najlepiej zdefiniować potrzebę od biznesu, tak, by dostarczyć mu dokładnie takie rozwiązanie, jakiego oczekiwał?
Czym cechują się dobrze zrealizowane projekty?
To temat rzeka. Projekt zaczyna się od potrzeby, czy to biznesowej, jako nowa funkcjonalność dla użytkownika, czy technicznej – np. potrzeba nowego narzędzia używanego przez zespół IT bądź backoffice w firmie. Im lepiej zdefiniowana potrzeba, którą ma zaspokajać projekt, tym łatwiej potem przejść przez proces implementacji. Głównie dlatego, że definicja zakończenia projektu w IT jest bardzo płynna – właściwie każdy projekt jest studnią bez dna, w której można dodawać funkcjonalności, poprawiać już istniejące, refaktorować kod.
Jasny cel pozwala uniknąć pułapki wiecznego rozwijania i zakończyć etap realizacji projektu. Wtedy można oceniać jego sukces – ze strony programistów będą to użyte technologie, czystość kodu, bezproblemowa współpraca z mitycznym “biznesem”. Dla organizacji będzie to spełnienie wcześniej postawionych celów i zadowolenie klientów końcowych. Bo ostatecznie to właśnie dla nich tworzymy oprogramowanie i za to dostajemy pensje.
Problemem zazwyczaj jest właśnie niedokładnie zdefiniowana potrzeba po stronie zamawiającego?
Najczęściej tak, wynika to z naturalnego parcia do przejścia do fazy programowania. Wtedy warunki brzegowe, scenariusze testowe, kryteria akceptacji mogą schodzić na dalszy plan i myślenie “jakoś to będzie” bierze górę. Żeby odpowiednio dopasować nową funkcję do istniejącego systemu i ją zintegrować, dobrze jest znać całość problemu, a nie tylko wycinki.
W późniejszym etapie pozornie niewielka zmiana może wywrócić cały projekt do góry nogami i spowodować opóźnienia, na czym nikomu nie zależy. Parcie do fazy developmentu jest oczywiście zrozumiałe i programiści też nie przepadają za fazą planowania i opisów, najchętniej usiedliby od razu do kodu.
Sam się na tym czasami łapię, że rozmawiając o nowej funkcjonalności w głowie już układam rozwiązanie, zamiast wysłuchać do końca w czym rzecz. Jednak jeden dzień planowania może zaoszczędzić tydzień kodowania i tej zasady staramy się trzymać.
Na co kładziesz nacisk podczas pracy nad projektami? Zmienia się to zgodnie z etapami realizacji?
Zawsze staram się przede wszystkim zapewnić zespołowi developerskiemu komfortową pracę. Zaczyna się od zebrania wymagań i informacji, o które zespół może zapytać później. Kluczową rzeczą jest też koordynacja prac pomiędzy zespołami programistów, większość naszych zadań dotyka wielu systemów i wymaga współpracy pomiędzy product ownerami oraz programistami. Gdy zadanie jest dobrze opisane, to potem proces programowania jest czystą przyjemnością, ewentualne drobne nieścisłości są wyjaśniane na bieżąco i nie ma dużych zmian w wymaganiach.
Doskonale to rozumiem, bo też biorę udział w developmencie, więc staram się żeby zadania przed rozpoczęciem prac programistycznych były w takim stanie, w jakim sam chciałbym je otrzymać. Oczywiście to jest scenariusz idealny, niestety jeszcze nie wszystkie nasze zadania stoją na tak wysokim poziomie.
Co dla Ciebie znaczy “dobrze opisane zadanie”?
Niedawno odbyliśmy wewnętrzny warsztat poprowadzony przez naszego kolegę, który miał na celu pokazanie, co jest dla programistów oraz Product Ownerów ważne w zadaniu.
Bez niespodzianki najważniejszym okazał się być opis funkcjonalny. Tuż za nim uplasowały się kryteria akceptacji, opis techniczny i historyjka użytkownika. Według mnie dobrze opisane zadanie zawiera wszystkie te elementy oraz, według potrzeby, makiety/elementy designu i odnośniki do innych zadań. Nad opisem zadania w pierwszym etapie pracuję ja, ale oczywiście w pełnym uzupełnieniu zadania bierze udział cały zespół.
Czego starasz się dowiedzieć od strony biznesowej podczas spotkań?
Odbiorcami naszego kodu jest zespół Właścicieli Produktów, czyli Product Ownerzy. Za jedną z największych zalet pracy w XTB uważam to, że wytwarzamy oprogramowanie na użytek wewnętrzny. Programiści siedzą z “biznesem” ramię w ramię, product ownerzy są zawsze dostępni i służą odpowiedzią i w wsparciem wedle swojej wiedzy i specjalizacji. Dzięki temu zadania np. refaktoringu kodu, zmian w architekturze, aktualizacja starszych technologii, czy też próbowanie swoich sił z zupełnie nowymi trafiają do naszych sprintów w zasadzie zawsze.
Każdy Product Owner rozumie wagę takich zadań, widzi ich wartość w dłuższej perspektywie i nadaje im odpowiedni priorytet. Nie ma więc jakiegoś potajemnego przemycania potrzebnych zmian technologicznych.
Końcowych użytkowników naszej platformy reprezentują działy Obsługi Klienta, Sprzedaży i Tradingu – to od nich czerpiemy wymagania, oni przedstawiają nam też potrzeby różnych grup klientów, a czasami, jeśli pomysł jest dość dobry, pojedynczych klientów.
Wymagania zbieramy i układamy w historyjki użytkowników, staramy się doprecyzować warunki brzegowe i kryteria akceptacji, czyli kiedy można uznać zadanie za gotowe. Wszystko to pomaga potem w ustawieniu priorytetów, ocenie złożoności zadań i ostatecznie ich zakodowaniu.
Masz jakiś system pozyskiwania takich informacji? Zazwyczaj spotykasz się kilka razy w ciągu miesiąca czy wolisz spotkania rzadsze, ale dłuższe?
Z przedstawicielami wymienionych wcześniej działów spotykamy się raz w miesiącu, gdzie omawiamy statystyki wynikające z ich pracy, największe bolączki i sukcesy. Z tych ogólnych spotkań wynikają potem mniejsze, dotyczące konkretnego problemu czy funkcjonalności. Staramy się potem wszystkich zainteresowanych zebrać raz w tygodniu i informować o przebiegu prac.
W międzyczasie wszelkie nieścisłości ustalamy na bieżąco. Przebywamy w większości na jednym piętrze biura, więc poza rozmowami w Jirze czy komunikatorze rozmawiamy też, w miarę potrzeby, osobiście. Cały czas uczymy się jeszcze jak efektywnie pracować zdalnie, stąd ciężko zrezygnować z osobistych spotkań.
Samodzielnie analizujesz wymagania, zanim trafią do zespołu programistów? Na podstawie jakich czynników podejmujesz decyzje, które z potrzeb są najważniejsze?
Nasi klienci, czyli odpowiednie działy w firmie, przychodzą do nas najczęściej z gotowymi problemami i pomysłami na usprawnienia platformy. Jest ich na tyle dużo, że wyzwaniem jest sprostanie wszystkim wymaganiom, pamiętając o zadaniach technicznych.
W poprzednich latach decyzje o tym, które zadania biznesowe są najważniejsze były w XTB podejmowane często na wyczucie – zarząd albo któryś z dyrektorów podejmował decyzję, o nowym projekcie, najczęściej na wczoraj. Ostatnio to podejście zmieniło się diametralnie na plus – dzięki zespołom Data Warehouse oraz Customer Experience podejmujemy decyzje w oparciu o twarde dane i jest coraz mniej miejsca na życzeniowe podejście do projektów. Dzięki temu zmniejsza się ilość kodu, który nigdy nie trafił na produkcję z powodu zmiany sytuacji rynkowej, priorytetów, czy też nastroju pomysłodawców.
W dalszym etapie w zebraniu wymagań oraz ustaleniu szczegółów, np. protokołu komunikacyjnego pomiędzy komponentami pomaga mi analityczka.
W jaki sposób rozwiązaliście problem z komunikacją między frontendem a backendem?
To akurat bardzo ciekawa sprawa, nasze aplikacje klienckie w sprawach związanych z tradowaniem komunikują się z naszymi API Gateway poprzez websockety oraz protokołem binarnym. Zapewnia to szybkość komunikacji i pozwala na przesyłanie dużych ilości danych bez narzutu na protokół tekstowy. Wykorzystanie websocketów pozwala na mechanizm “pusha”, czyli aplikacja kliencka otrzymuje dane na podstawie subskrypcji, a nie tylko gdy o nie zapyta. Przy tysiącach instrumentów, których ceny zmieniają się wielokrotnie w ciągu sekundy takie odpytywanie o nowe ceny byłoby karkołomne.
Zrealizowałeś wiele projektów, na pewno nie obyło się bez problemów. Opowiedz o najciekawszej awarii i o tym, jak poradziliście sobie z nią.
Taką awarią, która najbardziej zapadła mi w pamięć był deadlock, który wystąpił w jednym z procesów produkcyjnych. Objawy były niejednoznaczne, po restarcie proces nie uruchamiał się poprawnie, po kolejnych restartach czasami działał, a czasami nie.
Po kilku godzinach odtworzenia problemu na środowiskach testowych, statycznej analizie kodu postanowiłem sprawdzić proces profilerem. Okazało się, że dwie biblioteki podczas uruchamiania współbieżnie oczekują na ten sam zasób. W związku z tym dwa wątki, przy tylko niektórych próbach uruchomienia, czekają na zdarzenie, które nigdy nie nastąpi.
Najszybszą poprawką był zatrzymanie wykonywania jednego z wątków, czyli Thread.sleep()
na kilkaset milisekund. Może się to wydawać śmieszne, ale ta prymitywna metoda zadziałała, poprawka znalazła się szybko na produkcji i proces mógł być uruchamiany poprawnie. Zmienienie brzydkiego Thread.sleep()
wymagało dogłębnego zrozumienia działania dwóch bibliotek zewnętrznych i ich relacji między sobą, a tymczasem proces już obsługiwał klientów.
Ta awaria nauczyła mnie, że czasami lepszy jest brzydki kod, ale działający niż taki, który nie działa, ale pięknie wygląda. Zwłaszcza, że ta sytuacja dotyczyła tylko uruchamiania procesu, a więc kod wykonany został tylko raz.
Co stawiasz na czele cech potrzebnych każdemu efektywnemu zespołowi programistów?
Przede wszystkim samoorganizacja i poczucie odpowiedzialności za wyprodukowany kod. Mam przyjemność pracować w zespole, w którym każdy poczuwa się do takiej odpowiedzialności i wie co dzieje się z jego kodem po wciśnięciu “commit”. Wspieramy naszych dev-opsów w obsłudze procesów produkcyjnych i dbamy razem o ciągłość działania.
Samoorganizacja jest szczególnie przydatna przy dzieleniu się kompetencjami. Wszystkie zespoły jakie znam składają się z osób o zróżnicowanej wiedzy dot. programowania oraz samego systemu, z którym pracują. Wspólne rozwiązywanie problemów pozwala dzielić się tą wiedzą ze wszystkimi, niezależnie od starszeństwa w zespole. Wspiera to też rozwój samego produktu i podnosi jakość napisanego kodu.
Co Twoim zdaniem najczęściej zaburza efektywność programistów?
Najczęściej narzekamy na nagłe zwroty w wymaganiach. Czasami zmiany wynikają ze złego podejścia do projektu od samego początku, zbyt szybkiego przejścia do etapu programowania bez zdefiniowania dokładnego przeznaczenia. Ale bywa też tak, że szybki prototyp służy do zweryfikowania jakiegoś pomysłu i, pomimo nakładu programistycznego, nie będzie częścią ostatecznego rozwiązania produkcyjnego. Wtedy nie mówiłbym o niskiej efektywności, tylko wręcz odwrotnie – o zrealizowaniu zamierzonego celu.
I na koniec, praca nad wewnętrznym produktem pozwala Tobie i programistom rozwijać swoje umiejętności? Może więcej nauczylibyście się realizując wiele różnych zleceń dla wielu różnych klientów?
Rozwój wewnętrznego produktu absolutnie nie oznacza braku nowych projektów. Cały czas powstają nowe moduły i serwisy i najczęściej to jest miejsce do próbowania nowych technologii, architektury czy metodologii pracy. Nigdy nie usłyszałem odmowy na propozycję nowej technologii, co najwyżej sugestię, że w tym projekcie się może nie sprawdzić i żebyśmy wypróbowali w innym miejscu.
Wybór bibliotek i frameworków leży w gestii programistów. Nasze wybory wspiera też architekt, ale o narzucaniu technologii nie ma mowy. Wszystko sprowadza się więc do inicjatywy własnej i zespoły z entuzjazmem podchodzą do próbowania np nowych języków programowania.
Wielu różnych klientów to też wiele różnych metod wdrażania aplikacji, standardów, utartych przez zewnętrzne firmy ścieżek, do których jako wykonawca zlecenia musisz się dostosować. Jeśli już, to właśnie taka praca blokuje kreatywność i dowolność stosowania technologii.
Bliskość klientów, produktu z którego w większości sami korzystamy oraz “biznesu” jest ogromną zaletą posiadania produktu wewnętrznego. Od zawsze interesowała mnie branża finansowa, a dzięki tej pracy mam w nią wgląd od zaplecza. Od rozpoczęcia pracy w XTB dążyłem do poznania procesów biznesowych, uczestnictwa w rozwoju produktów, poznaniu mechanizmów i zasad, na których taka duża firma się opiera.
Dzięki obecnej roli mam przyjemność nie tylko decydować o priorytetach przy kreowaniu nowych produktów, ale też implementować je potem na warstwie programistycznej. Praca z wieloma firmami nie dałaby mi możliwości poznania np. procesów marketingowych, zrozumienia wyzwań z jakimi boryka się spółka akcyjna od strony kreacji produktu i to z pierwszej ręki. Właśnie za to cenię sobie pracę z XTB.
Paweł Grudzień. Senior Java Developer/Product Owner w XTB. Programista z doświadczeniem w branży FinTech. Pełni obowiązki Product Ownera i programisty w zespole deweloperskim. Do jego zadań należy definiowanie wizji produktów przy bliskiej współpracy z innymi Product Ownerami oraz interesariuszami. Jako programista rozwija systemy stanowiące pierwszy punkt wejścia do backendu całej platformy transakcyjnej xStation.