Rozmowa kwalifikacyjna na stanowisko programisty- jak to wygląda?
Każdy wie, że rozmowy kwalifikacyjne nie zawsze należą do łatwych. Szczególnie w branży IT wymagania względem potencjalnego pracownika są zazwyczaj ściśle określone. Oczywiście, można uniknąć stresu związanego z jej przebiegiem, jeśli odpowiednio się do niej przygotujemy. Dlatego śpieszę z pomocą!
Jeśli przeszliście pomyślnie pierwszy etap rozmowy kwalifikacyjnej - tej “luźniejszej”, gdzie opowiadacie o sobie, konwersacja oscyluje wokół takich pytań, jak “dlaczego chce Pan/Pani z nami pracować” itd., czeka na was drugi etap rekrutacji - ten bardziej konkretny i wymagający.
Najczęściej drugim etapem rekrutacji jest tak zwana “rozmowa techniczna”, sprawdzająca wiedzę kandydata. W tym artykule przedstawiłam 10 pytań rekrutacyjnych z JavaScriptu (oraz bonus!) wraz z odpowiedziami. Do każdego z pytań dodałam przykłady kodu, żeby łatwiej było Ci zrozumieć i zapamiętać zagadnienia - co może okazać się bardzo przydatne w stresowej sytuacji, jaką niewątpliwie jest rozmowa kwalifikacyjna. Na końcu zawarłam także kilka porad, które sama chciałabym usłyszeć przygotowując się do pierwszych rozmów o pracę w firmie programistycznej.
Top 10 pytań rekrutacyjnych z JavaScriptu:
1. Co to są var, let oraz const i czym się różnią?
W JavaScripcie var, let i const są trzema sposobami deklaracji zmiennych. Przed wprowadzeniem standardu ES6 istniał tylko jeden sposób deklaracji zmiennych – var.
- Var to deklaracja zmiennej dla całej funkcji, czyli ma zasięg funkcyjny (function scope);
Var pozwala na ponowne deklarowanie zmiennej, czyli kolejna deklaracja tej samej zmiennej nadpisuje ją.
var language = 'Polish';var language = 'English';var language = 'Spanish';console.log(language);
W konsoli wypisze się ostatnia przypisana wartość, czyli ‘Spanish’.
Var podlega mechanizmowi hoistingu, czyli wszystkie deklaracje zmiennych przesuwane są na początek funkcji, a deklaracja ta będzie miała przypisaną wartość „undefined”.
console.log(quote);var quote = "Programming isn't about what you know; it's about what you can figure out. - Chris Pine"
Dzięki zjawisku hoistingu w konsoli zamiast błędu Reference Error zobaczymy ‘undefined’.
- Let
Jak już wspomniałam, deklaracja zmiennej let została wprowadzona w wersji ES6. Zasięg zadeklarowanej zmiennej przez słówko let jest blokowy (block scope).
let today = ‘Monday’{let today = ‘Wednesday’}console.log(today);
Konsola zwróci ‘Monday’, gdyż deklaracja let jest ograniczona w zakresie bloku, w którym została zdefiniowana. Gdybyśmy chcieli zobaczyć w konsoli ‘Wednesday’, musielibyśmy przenieść console.log(today) wyżej – do bloku gdzie mamy tę deklarację.
Zmienna zadeklarowana przez let nie może zostać ponownie zadeklarowana. Gdybyśmy w przykładzie z językami zmienili var na let otrzymalibyśmy błąd. Aby uzyskać taki sam rezultat jak w przypadku var musielibyśmy w ten sposób zmodyfikować funkcję:
let language = 'Polish';language = 'English';language = 'Spanish';console.log(language);
Zmienna zadeklarowana jest raz, a potem następuje zmiana jej wartości.
- Const
Tak jak let – ta deklaracja zmiennej została wprowadzona w ES6 i tak jak let posiada zasięg blokowy. Tak jak w przypadku let nie możemy w tym samym bloku zadeklarować zmiennych o takiej samej nazwie.
Czym w takim razie różnią się let i const? Zmienna zadeklarowana przy pomocy const nie może zmienić swojej wartości.
const weather = 'Sunny day'weather = 'Rainy day'
Otrzymamy błąd „typeError – invalid assignment”
2. Co to jest hoisting?
Odpowiedź na poprzednie pytanie częściowo odpowiada także na to, ponieważ zjawisko hoistingu ściśle wiąże się z deklaracją zmiennych.
Deklaracje funkcji oraz zmiennych wynoszone są na początek funkcji, czyli deklaracje zmiennych wykonywane są w pierwszej kolejności przed resztą kodu. Należy pamiętać, że jest to tylko deklaracja zmiennych bez przypisania wartości oraz fakt, że mechanizm ten występuje tylko przy deklaracji zmiennej var.
console.log(color);var color = ' blue'
W konsoli zobaczymy ‘undefined’.
3. Co to są domknięcia (closures)?
Jest to stworzenie jednej funkcji wewnątrz drugiej, gdzie wewnętrzna funkcja ma dostęp do zmiennych własnych oraz zmiennych rodzica i jeżeli istnieją zmienne globalne to także do nich. Funkcja zewnętrzna nie ma dostępu do zmiennych funkcji wewnętrznej. Najlepiej zobrazuje to przykład:
var global = "I’m global"function parent() { var parent_variable = "I’m parent" console.log(global); console.log(child_variable); function child() { var child_variable = "I’m child" } child();}parent();
W konsoli wypisze się najpierw ”I’m global” a następnie błąd „ReferenceError: child_variable is not defined”
Zmodyfikujmy nieco kod.
var global = "I’m global"function parent() { var parent_variable = "I’m parent" function child() { var child_variable = "I’m child"; console.log(global); console.log(parent_variable); } child();}parent();
Tym razem nie otrzymamy błędu gdyż funkcja child ma dostęp zarówno do zmiennych globalnych jak i zmiennych rodzica. Zatem w konsoli otrzymamy ”I’m global” oraz ”I’m parent”.
4. Co to jest funkcja natychmiastowa (IIFE – Immediately Invoked Function Expression)?
Jest to funkcja, która wykona się od razu gdy wystąpi w kodzie. Jak wygląda? Jest ona opakowana w dodatkowe okrągłe nawiasy, a za nimi dostawiona jest kolejna para nawiasów.
(function () { console.log("Jestem funkcją natychmiastową");})();(function (name) { console.log(name);})("I’m IIFE!");
To funkcja anonimowa, która nie jest przechowywana w żadnej zmiennej – uruchomi się, zostanie wykonana i nie będzie istnieć w dalszych częściach kodu.
5. Co to jest funkcja strzałka (arrow function)?
Jest to sposób deklarowania funkcji wprowadzony w ES6. Funkcja strzałka przechwytuje wartość this dla momentu zadeklarowania, a nie wywołania funkcji. Działa to tak samo jak użycie funkcji prototypowej Function.prototype.bind. Aby zastosować funkcję strzałkową używamy znaku => czyli tak zwanej grubej strzałki.
const greeting = (name) => { return 'Good morning ' + name;}
6. Co to jest pure function?
Jest to funkcja, która musi spełniać dwa warunki:
- Dla takich samych danych wejściowych zawsze musi zwracać taki sam wynik.
- Nie może modyfikować zewnętrznych wartości.
function sum(a,b) { return a + b;}Dla lepszego zobrazowania dwa przykłady impure functions:let drawer = ['book', 'notebook', 'pen', 'ruler'];function addItem() { drawer.push('pencil');}
Nie jest to pure function, gdyż modyfikuje zewnętrzną zmienną.
Pozostańmy przy zmiennej drawer i spróbujmy wyciągnąć z niej losowy przedmiot.
let drawer = ['book', 'notebook', 'pen', 'ruler'];function getRandomItem() { return drawer[Math.floor(Math.random() * drawer.length)]}
Nie jest to pure function, gdyż jej wynik nie będzie za każdym razem taki sam.
7. Jaka jest różnica pomiędzy operatorem == a === ?
Podwójny znak równości porównuje wartości, a potrójny dodatkowo sprawdza zgodność typów.
1 == '1' //true1 === '1' //false
8. Jaka jest różnica pomiędzy wartością undefined a null?
- Undefined oznacza, że zmienna została zadeklarowana, ale jeszcze nie ma przypisanej wartości.
- Null jest to przypisana wartość i oznacza wartość pustą.
Null trzeba przypisać do zmiennej jako wartość, a undefined jest wartością domyślną gdy nic nie zostało przypisane.
9. Czym jest ternary operator?
Jest to operator warunkowy, często stosowany jako skrócenie funkcji if.
Składa się z trzech części oddzielonych znakiem zapytania i dwukropkiem.
warunek ? -to co zostanie zwrócone, gdy warunek zostanie spełniony
(true) : to co zostanie zwrócone, w przeciwnym wypadku (false)
userType === 'premium' ? 'Welcome to our platform' : 'Content avialable for Premium users'
10. Co to są falsy values? Jakie falsy values znasz?
Wartość fałszywa- wartość uznawana za fałszywą (false) gdy zostanie użyta w kontekście boolowskim.
Przykłady:
false, null, undefined, 0, NaN, ‘’ (pusty string)
Podstawy mamy omówione, więc teraz proponuję zabawę.
Bonus! Rozszyfruj tajemnicze słowo.
let mysteryWord = 'TinobraQ';
Być może należy odczytać słowo od prawej do lewej. Spróbujmy!
function solution(str) { return str.split('').reverse().join('');}
Prześledźmy co dzieje się wewnątrz funkcji: split() rozdziela nasz string na tablicę zawierającą uporządkowaną listę substringów, czyli:
['T','I','n','o','b','r','a','Q']
Następnie odwracamy kolejność elementów w tablicy przy pomocy funkcji
['Q','a','r','b','o','n','I','T']
Aby znowu uzyskać string stosujemy funkcję
‘QarbonIT’
Garść porad na koniec
Gdy zapomnisz jakiejś definicji albo nie do końca ją pamiętasz, postaraj się opowiedzieć swoimi słowami do czego tego można użyć, jak wpływa to na pisany kod. Być może gdy rekruter zobaczy, że starasz się odpowiedzieć i idziesz w dobrym kierunku to podpowie, podrzuci jakieś słówko kluczowe, które pomoże rozwinąć Ci myśl.
W pytaniach zazwyczaj nie chodzi o samo wykucie definicji, a o rozumienie tematu. Często zaraz po pytaniu „co to jest?” następuje kolejne, wykorzystujące zagadnienie w praktyce.
Gdy pytanie dotyczy tego, jaki będzie wynik funkcji, albo gdy zostaniemy poproszeni o napisanie jakiejś funkcji, czasami zdarza się że z początku nie mamy pojęcia co zrobić. W takim wypadku dobrze jest „głośno myśleć”, opisać jakie mamy zmienne, opowiedzieć jakie kolejne kroki należy wykonać aby otrzymać oczekiwany rezultat. Być może rekruter słysząc jaki masz pomysł upewni Cię w przekonaniu, że idziesz we właściwym kierunku albo zwróci uwagę, że można byłoby wykorzystać jakąś własność lub wskaże drobną rzecz, którą pominęliśmy.
Powodzenia na rozmowie rekrutacyjnej!