poniedziałek, 6 czerwca 2011

Rekrutacja

Temat zadań rekrutacyjnych dla developerów przewija się w branży co jakiś czas. Ostatnio znowu odżył ze względu na odbicie do tak zwanego kryzysu.

Post jest głosem w dyskusji, jaka toczy się na grupie Warszawa JUG, którą to czytam namiętnie ze względu na spektrum tematów oraz aktywność członków.

Dyskusja zaczęła od pytania o słuszność lub nie wymagania wiedzy na temat sortowania kolekcji obiektów w Javie. Chodzi o użycie biblioteki standardowej/trzeciej a nie o implementację od zera sortowania bąbelkowego (bo i o takich kuriozach się słyszy).

Wydaje mi się, że dyskutowanie nad treścią zadań bez określenia kontekstu to podchodzenie do problemu od złej strony.

Zaczynając rekrutację musisz odpowiedzieć sobie na kilka pytań: kogo poszukuję, do jakich klas problemów, do jakich typów zdań, z kim ma pracować i jakie są plany na przyszłość (co do tej osoby, co do całego teamu).

Pracując w różnych firmach jako lider techniczny zajmowałem się między innymi rekrutowaniem pracowników. Straciłem rachubę, ale w sumie przewinęło się ok 100 osób. Pamiętam jakie błędy robiłem, głównie na poziomie założeń. Teraz pomagam klientom znajdować odpowiednich ludzi na określone stanowiska.

Inny skillset będzie potrzeby dla kogoś kto dodaje ficzery biznesowe a inny dla kogoś kto rozwiązuje łamigłówki na poziomie optymalizacji lub algorytmicznym. Inny dla kogoś kto projektuje systemy/frameworki a inny dla kogoś kto implementuje aplikacje. Inny dla kogoś kto implementuje sexi gui a inny dla kogoś, kto modeluje złożone domeny biznesowe. Inny dla kogoś kto kreuje kierunek dla nowych projektów a inny dla kogoś, kto utrzymuje legacy.

Na skillset składa się wiele wymiarów - znajomość języków i technologii to tylko jeden z nich. Czasem wystarczający a czasem nie (czasem pomijalny?). Temat jest generalnie bardzo szeroki i wchodzi głęboko w psychologię - np. typy osobowości, z których wynikają sposoby myślenia, predyspozycje, słabe i mocne strony. Generalnie nie ma ludzi perfekcyjnych, każdy ma słabe strony, chodzi o to aby "w boju nie wystawiać tych miękkich części na ciosy" - po prostu dobierać ludzi do zadań/wyzwań
Ale to wymaga też zrozumienia wyzwań jakie pojawią się w projekcie oraz zrozumienia cech jakie lepiej lub gorzej predysponują śmiałka do podjęcia wyzwania:)

Strategia dla teamu jest prosta: wzajemne uzupełnianie się cech - a z tego gratisowo dostajemy efekty synergiczne:)
Podstawowym narzędziem może być model Belbina - ale to dopiero początek układanki.

Ignorowanie aspektów miękkich i kompletowanie zespołu na zasadzie: "dawać mnie tu sześciopak programistów" sprawdzi się owszem w niektórych przypadkach. W rekrutacji do projektów Komisji Europejskiej w Luksemburgu jednak już nie zadziała...


Wracając do zadania z sortowaniem kolekcji przez bibliotekę standardową... Zastanówmy się co ono sprawdza. Na pewno to czy ktoś już tego używał, czyli czy otarł się o ogólne programowanie w Javie (i ew. proste wykorzystanie w algorytmach). Oczywiście kandydat mógł nie mieć do tej pory okazji sortowania niczego - zdarza się.

Skoro tak, to nie miał tez okazji przeczytania żadnej książki poświęconej programowaniu w Javie. Po prostu nie da się nie trafić na sort. Prawdopodobnie ilość artykułów jakie pochłonął jest niewielka (tak elementarna rzecz jak sortowanie pojawia się z prozaicznej konieczności nawet w zaawansowanych tekstach).

Jaki wniosek możemy wysnuć na tej podstawie... hmmm... ja się wstrzymam z wnioskowaniem, czekam na propozycje w komentarzach. Nie zakładałbym jednak, że zawsze poszukujemy kogoś, kto "traci czas" na czytanie książek...

Ale na pewno jeżeli kandydat nie potrafi podać odpowiedzi, warto sprawdzić w jaki sposób ją zdobędzie i na ile ją zrozumie.

//==============================

Co do zadań ogólno-programistycznych to wdzięcznym tematem jest napisanie utilsa obliczającego pole prostokąta. Tak utilsa, statyczną metodę, beż żadnych Object Oriented, w przestrzeni Euklidesowej, zwykłe a * b.

Co sprawdzimy? Coś co można określić stylem.
1. nazwy parametrów - od czego zależy dobór? a,b czy może x,y albo width,height? szczegół? tak, ale jednak...
2. dobór typów. kiedy własne typy? co z jednostkami? wynik jest w kwadracie - jakie operacje są na nim dozwolone później? czy jest to problem naszego utilsa? szeroki temat do dyskusji...
3. sprawdzanie wartości wejściowych - sprawdzać czy nie, od czego to zależy?
4. nazwy, nazwy, nazwy
5. jakie wyjątki? dlaczego?
6. komentarze. a może nie ma takiej potrzeby? dlaczego?
7. testy! a może nie;P dlaczego?

Nikt nie zarzuci wymogu znajomości bibliotek (ew. junit/testng), egzotycznych algorytmów, wyrafinowanej składni, fizyki kwantowej. Wzoru na pole prostokąta jednak bym nie podawał w treści zadania;)

Tego typu zadanie oczywiście nie zaważy na przyjęciu/odrzuceniu kandydatury na stanowiska develoepra aplikacji postawionych na stosie 10 frameworków, ale potencjalnie może wskazać wygodne dla kandydata miejsce.

8 komentarzy:

Tomek Nurkiewicz pisze...

Po pierwsze to felerne pytanie o sortowanie... Jeśli rekrutując osobę na stanowisko programisty C++ ktoś nie rozumie konstrukcji **a (wskaźnik na wskaźnik) "bo nigdy jej nie używał" - no, możliwe, nie jest ona często potrzebna - ale to i tak są Podstawy(tm). Jeśli ktoś pisze w Javie i nie wie co to Comparator/Comparable - może i się nie spotkał, może ma 5 lat doświadczenia z JDBC i zawsze robiła to baza. Ale ja mogę wnioskować, że taka osoba nie zna też 4/5 pakietu java.lang.*, java.util.*, Apache Commons, etc. Równie dobrze można o takiego kandydata usłyszeć, że nie umie korzystać z tablic, bo zawsze używał List...

To tak, jakby jakakolwiek osoba mająca pracować na jakimkolwiek stanowisku związanym z finansami nie potrafiła w pamięci policzyć 3% z 8.

O co spytać "typowego" programistę (bazując na moim dotychczasowym, nie tak znowu dużum doświadczeniu)? Dać kawałek kodu, nawet produkcyjnego, i o nim podyskutować. Niech kandydat na oczach rekrutera go zrozumie i ew. poprawi (szukamy oczywiście kodu nieidealnego). Niech wprowadzi jakąś zmianę, jak to zrobi? Czy otestuje? Czy poprawi także nie swój kod obok (reguła skauta)? Czy zwróci uwagę na kontekst? Czy zmieni kontrakt? Czy rozwiązanie będzie bliskie optymalnemu?

Nie każda firma jest Googlem, ale z jakiegoś powodu niejedna wymaga od szarego klepacza znajomości różnicy między drzewem AVL a czerwono-czarnym. Albo wymyśla zadania typu: "w czasie O(n) znajdź najmniejszą parę elementów których iloczyn jest większy od mediany elementów parzystych po odjęciu nieparzystych" (zmyślone). C'mon! A potem @Inject, serivce, DAO, Hibernate, wróć; przez 8 godzin dziennie.

Nawet jeśli szukamy "algorytmika" i speca od optymalizacji, to przecież on będzie przez większość czasu czytał kod a nie go pisał. Czy naprawdę w rekrutującej firmie nie pojawił się w ostatnim czasie ciekawy problem, kiepski kod, nietuzinkowe rozwiązanie? A może kandydat olśni nowym spojrzeniem? Na pewno nie olśni nas znajomością pesymistycznej złożoności QuickSorta.

Lasu aka Marek Kozieł pisze...

Ave,
   Jak się mogę cieszyć, że miałeś czas o tym napisać (uprościło to znacznie temat).

   Jeśli mówimy o zaawansowanej rekrutacji to w moim odczuciu jest to bardziej problem świadomości zarządzania niż samej rekrutacji. Jeśli ktoś bowiem nie ma sprecyzowanego pomysłu na projekt i zagrożenia które w nim będą występować wówczas najczęściej będzie rekrutować ludzi znających się na wszystkim - a łatwo sobie wyobrazić, że firma w której każdy byłby księgowym - sekretarką - kierownikiem - pracownikiem - stróżem wydajna nie będzie ale kosztowna na pewno.


   Swoją drogą od jakiegoś czasu szukam wolnej chwili żeby napisać o tym jakie możliwości/korzyści daje wzięcie osoby która nie zna technologi w których będzie tworzony projekt.

   Jeśli chodzi o sortowanie i tym podobne bazowe biblioteki to ja osobiście nie miałem wielkiego pojęcia jak je wywoływać - na studiach nie zajmowałem się wklepywaniem na pamięć API tylko sam pisałem algorytmy po to aby zaobserwować ile/jak wydajnie/efektywnie/z jakim rezultatem oraz jakiej jakości w porównaniu do ogólno dostępnymi algorytmami jestem(byłem) w stanie wykonać ;P
   Więc o Arrays.sort(...) bym wiedział ale o tym, że można użyć Comparator-a - wątpliwe....
Większość studentów w tym ja wynosi błędny obraz świata programowania - a to właśnie rekrutujący musi wiedzieć jak kandydat będzie się spisywał po przetarciu oczek.

Sławek Sobótka pisze...

@Tomek
Zgadzam się... jeszcze 5 lat temu sam nie spodziewałbym się, że napiszę kiedyś posta o tak defaultowej wiedzy jak sortowanie kolekcji:)
"O tempora, o mores!"

Co do pracy z kawałkiem kodu produkcyjnego to jest świetne podejście - po prostu pragmatyczne. Może mieć ciekawe zastosowania na różnych etapach...

@Lasu
Świadomość, sprecyzowany pomysł ryzyka - dokładnie tak.

piotrb pisze...

Zgoda całkowita, temat zadania trywialny, choć przyznam, że o liczeniu pola prostokąta nie pomyśłałem. Z komentarzami też się zgodzę, kawałek kodu z produkcji jako część rozmowy. Zdarzyło mi się mieć kandydata, który nie potrafił wyjasnić swojego (dość prostego) kodu, i nie była to blokada psychiczna ;). Jeszcze @Lasu: mam trochę mniejsze doświadczenie w tym temacie niż Sławek, ale wszystkie "kodotesty" w innej technologii/języku niż projekt (jednemu facetowi zaproponowałem Matlaba (w którym podobno coś pisał), zeby mógł wyjść z twarzą, po tym jak oświadczył, że w żadnym języku (z posiadanych na komputerze "rekrutacyjnym") on tego (trywialnego) programiku nie napisze.

wzs pisze...

Jeżeli programiści często nie potrafią zaprogramować FizzBuzz, to oczekiwanie znajomości algorytmów sortowania może być karkołomnym zadaniem.

Moim zdaniem (z perspektywy osoby rekrutowanej) lepsze jest właśnie rozgryzanie jakiegoś kodu, wyłapywanie w nim błędów - ogólna dyskusja, niż pisanie własnego kodu od zera.

Rozmowa kwalifikacyjna jest jednak bardziej stresująca niż nawet kodzenie przed deadlinem :)

Sławek Sobótka pisze...

Co do FizBuza to pełno jest rozwiązań, które w każdym obrocie pętli wykonują 3 dzielenia modulo (lub więcej, ale to powinien zoptymalizować kompilator). Ludzie prześcigają się w pisaniu wersji w kolejnych językach.

Wystarczy przypomnieć sobie z podstawówki, że 15 == 5 * 3 i można zredukować do 2 dzieleń:


public class FizzBuzz {

public static void main(String[] args) {
for (int i = 1; i <= 100; i++) {
boolean printI = true;

if (i % 3 == 0){
System.out.print("Fizz");
printI = false;
}

if (i % 5 == 0){
System.out.print("Buzz");
printI = false;
}

if (printI){
System.out.print(i);
}

System.out.println();
}
}
}


ale mistrzowie robią to na 2 dzieleniach w ogóle:)
http://www.cydeweys.com/blog/2008/07/02/better-fizzbuzz-solution/

Krzysiek pisze...

Na jednej rozmowie poprosili mnie bym napisał QuickSort w Erlang. Jeśli się pisze w jakimkolwiek funkcyjnym języku to jest to raczej błache.

Na innej spytali mnie jak w konkretnej technologii widoku, mając konkretną bibliotekę do AJAX zrobić jakieś wywołanie. Odpowiedziałem, że to głupie pytanie ;)

FizzBuzz można zrobić bez dzielenia. Takie rozwiązanie ze StringBuilder i jednym print, byłoby to prawdopodobnie najszybsze ;) ale to by trzeba zmierzyć. Idea algorytmu (w Groovy):

def a = 3
def b = 5
def ainc = a
def binc = b

(1..100).each{
def x = ""
if (it == a) {
x = "Fizz"
a += ainc
if (it == b){
x += "Buzz"
b += binc
if (x) println x
}

Marek Dominiak pisze...

Jesli jeszcze poprosi sie kandydata o "rozwiazanie" tego zadania z prostokatem w eclipsie czy innym IDE dostaniemy informacje czy kandydat mial stycznosc z eclipsem wczesniej.

Moja firma wykorzystala zadanie z prostokatem na mnie.

Ponoc czesc osob podczas rekrutacji odpadla bo nie potrafila stworzyc klasy w eclipse (mimo zaawansowanej znajomosci eclipse w CV ) :)