Jedną z części rozmowy rekrutacyjnej na stanowisko Junior Web Developera jest rozmowa techniczna. Często podczas tej części rozmowy rekruter poprosi Cię o opisanie projektów, w których do tej pory brałeś(aś) udział. Warto wtedy opisać czego się nauczyłeś(aś), jakie trudności napotkałeś(aś) oraz jak udało Ci się z nimi uporać. W wielu przypadkach rekruterowi to wystarczy. Gdy jednak nie masz zbyt wiele doświadczenia, to rekruter będzie chciał sprawdzić Twoją wiedzę poprzez serię kilku pytań technicznych.
Część pytań pochodzi z portalu DevFAQ — bazy z pytaniami rekrutacyjnymi tworzonej przez społeczność. Część pytań pochodzi z mojego e-booka 106 Pytań Rekrutacyjnych Junior JavaScript Developer, który możesz odebrać, zapisując się na mój mailing. Nie wszystkie pytania zawarte w tym artykule znajdziesz w moim e-booku, więc zachęcam Cię do przeczytania tego wpisu, nawet jeśli planujesz przeczytać e-booka.
Na blogu tematyce pytań technicznych poświęciłem szerszą uwagę w serii wpisów. Zachęcam do sprawdzenia pozostałych artykułów:
- Junior Web Developer – pytania rekrutacyjne cz. 1
- Junior Web Developer – pytania rekrutacyjne cz. 2
- Junior Web Developer – pytania rekrutacyjne cz. 3
- Junior Web Developer – pytania rekrutacyjne cz. 4
- Junior Web Developer – pytania rekrutacyjne – React
- Programista – pytania rekrutacyjne – TypeScript
- Programista – pytania rekrutacyjne – Git
- Programista – pytania rekrutacyjne – Docker
- Programista – pytania rekrutacyjne – bazy danych
Pytania z tej serii możesz również traktować jako trening i sprawdzenie swoich umiejętności przed rozmową rekrutacyjną.
Czym jest Garbage Collector?
Garbage Collector to mechanizm w językach programowania, który automatycznie zarządza pamięcią, usuwając nieużywane lub nieosiągalne obiekty z pamięci komputera. Obiekt można uznać za nieosiągalny, gdy nie istnieje do niego żadna referencja w aplikacji. Działa on w tle, monitorując i śledząc obiekty alokowane w pamięci.
Czym są event bubbling i event capturing?
Event bubbling można skojarzyć z bąbelkami w wodzie gazowanej. Bąbelki wypływają ku powierzchni i bardzo podobnie działa mechanizm event bubblingu. Zdarzenia są przekazywane od najbardziej wewnętrznego elementu, którego zdarzenie dotyczy, do najbardziej zewnętrznego. Przykładowo, mając element section
z zagnieżdżonym elementem div
i zdefiniowanym w nim elemencie p
, event kliknięcia wykonany na elemencie p zostanie przekazany w następującej kolejności: p > div > section
. Drugim zagadnieniem jest event capturing. W przypadku event captiuringu sytuacja wygląda odwrotnie. W fazie przechwytywania zdarzeń przeglądarka rozpoczyna od najbardziej zewnętrznego elementu DOM i przechodzi w głąb hierarchii dokumentu, docierając do elementu docelowego, na którym zdarzenie zostało wywołane. Dla podanego wcześniej przykładu, flow wygląda następująco: section > div > p
. Domyślnym zachowaniem przeglądarek jest event bubbling. Możliwe jest też zatrzymanie propagacji zdarzeń przy użyciu metody event.stopPropagation
.
Na czym polega technika CSS Sprites?
CSS Sprites polega na połączeniu grafik używanych na stronie w jeden plik. Głównym celem tej techniki jest zmniejszenie liczby żądań HTTP do serwera, co przyspieszenie ładowanie strony. Przydaje się ona szczególnie w przypadku stron o dużej liczbie grafik. Mając stworzoną mapę grafik, wystarczy załadować mapę grafik jako tło i odpowiednio je wypozycjonować za pomocą właściwości CSS background-position
.
Po co robimy testy jednostkowe?
Testy automatyczne tworzone są po to, aby w zautomatyzowany i powtarzalny sposób móc sprawdzać jak działa napisany kod. Testy jednostkowe testują jednostki, czyli małe fragmenty kodu np. klasy, funkcje czy metody. W testach jednostkowych, zależności testowanego fragmentu można zastąpić mockami. Dzięki wykorzystaniu mocków testowany jest wyłącznie pożądany fragment kodu. Do testowania współdziałania fragmentu kodu z jego zależnościami tworzy się testy integracyjne. W piramidzie testów testy jednostkowe znajdują się u podstawy i ilościowo powinno być ich najwięcej. Pisanie testów jednostkowych w JavaScript ułatwiają biblioteki opisane w poprzednim zestawie pytań rekrutacyjnych.
Jakie znasz narzędzia i mechanizmy do zapewniania jakości kodu?
Do zapewnienia jakości kodu służą już wspomniane testy automatyczne. Dobrze napisane testy pozwolą wychwycić nieprawidłowości nie tyle syntaktyczne (o których powinno poinformować nas IDE) co błędy związane z niepoprawną logiką lub błędami w działaniu kodu.
Kolejne dwa procesy, o które warto zadbać to refaktoryzacja i code review. Refaktoryzacja służy uproszczeniu oraz ulepszeniu istniejącego kodu. Często dany problem idzie rozwiązać w prostszy lub bardziej efektywny sposób. Z kolei code review polega na sprawdzeniu kodu przez innego programistę w celu weryfikacji i oceny. Code review pozwala na zyskanie dodatkowego, często odmiennego, spojrzenia na dany problem. Dodatkowa para oczu jest również pomocna przy detekcji błędów. Code review to również świetny sposób na dzielenie się wiedzą w zespole.
Kolejnym krokiem może być wykorzystanie linterów i narzędzi do stylowania kodu. Lintery pilnują, aby code style był spójny i jednolity. Wykorzystanie jednolitego code style jest przydatne szczególnie gdy pracuje się nad projektem w zespole.
Ostatnim aspektem, mogącym pomóc w dostarczaniu lepszego kodu to odpowiednie skonfigurowania IDE lub edytora kodu. Poprawnie skonfigurowane środowisko pracy potrafi sporo pomóc i podpowiedzieć. IDE może poinformować np. o nadmiarowych zmiennych, błęach syntaktycznych w kodzie czy o niepotrzebnie rozbudowanych warunkach.
Jakie znasz metody HTTP?
Korzystając z protokołu HTTP mamy do dyspozycji metody: GET
, POST
, PUT
, DELETE
, HEAD
, CONNECT
, OPTIONS
, TRACE
, PATCH
. Szczegółowy opis oraz zastosowanie dla przedstawionych metod opisałem w artykule wprowadzenie do REST API, do którego Cię odsyłam.
Chcesz dodać na stronę WWW skalowalne logo – na każdym urządzeniu i w każdej rozdzielczości logo musi być jednakowo ostre. Jak podejdziesz do tego zadania?
Do wykonania tego zadania można zaprojektować logo w formacie SVG. Jest to format plików grafiki wektorowej. Zaletą grafik wektorowych jest fakt, że nie są one zbiorem statycznych pikseli, lecz są definiowane na podstawie matematycznych opisów obiektów geometrycznych. Pozwala to na skalowanie ich bez utraty jakości obrazu. Plik z formatem svg
jest zbudowany ze znaczników XML, które można obsługiwać za pomocą CSS i JavaScript. Daje to spore możliwości pracy z takim plikiem.
Czym jest Canvas?
Canvas to API dostarczone wraz ze standardem HTML5. Pozwala ono na stworzenie płótna, po którym można rysować z wykorzystaniem JavaScriptu. Do pracy z Canvas API powstał znacznik canvas
. Canvas API wspiera zarówno rysowanie 2D, jak i 3D z wykorzystaniem WebGL. Canvas jest także używany do tworzenia animacji, ponieważ pozwala na rysowanie klatek kolejno po sobie w określonych odstępach czasu, co pozwala uzyskać efekt animacji. Podstawy pracy z Canvas API możesz poznać, czytając dedykowany artykuł na blogu.
Czym jest IIFE?
IIFE jest akronimem od Immediately Invoked Function Expression. Jest to funkcja opakowana w dodatkowe okrągłe nawiasy, a za nimi jest dostawiona kolejna para nawiasów. Taki zabieg sprawia, że funkcja wewnątrz tych nawiasów jest wywoływana od razu, gdy interpreter napotka ją w kodzie. Przykład wykorzystania IIFE znajdziesz poniżej:
( () => {
console.log( 'foobar' );
} )();
Czym jest memory leak?
Memory leak, czyli wyciek pamięci to sytuacja, w której program komputerowy nie zwalnia pamięci operacyjnej (RAM) po zakończeniu jej użycia, co powoduje, że ilość zajętej pamięci stopniowo rośnie. Memory leaki mogą wpływać na wydajność aplikacji, a także powodować jej awarie. Współczesne języki programowania i narzędzia dostarczają mechanizmy do automatycznego zarządzania pamięcią, co zmniejsza ryzyko wystąpienia memory leaków w aplikacji. W językach, w których odpowiedzialność za zarządzanie pamięcią leży po stronie programisty ryzyko wystąpienia wycieków jest istotnie wyższe.
Jak pozbyć się duplikatów z tablicy w JS?
Przedstawię dwa przykładowe rozwiązania. Pierwsze z nich to skorzystanie z obiektu Set
. Cechą Set
jest to, że nie pozwala na przechowywanie duplikatów. W połączeniu z wykorzystaniem spread operatora, rozwiązanie mamy prawie gotowe. Tak otrzymany Set
traktujemy jeszcze raz spread operatorem i otrzymujemy tablicę bez duplikatów:
const arr = [ 'foo', 'bar', 'baz', 'bar', 'bar', 'baz' ];
console.log( [ ...new Set( [ ...arr ] ) ] );
Drugim sposobem jest przeiterowanie po tablicy pierwotnej i przenoszenie wartości z jednej tablicy do drugiej.
const arr = [ 'foo', 'bar', 'baz', 'bar', 'bar', 'baz' ];
const noDuplicates = [];
for ( const item of arr ) {
if ( !noDuplicates.includes( item ) ) {
noDuplicates.push(item);
}
}
console.log( noDuplicates );
Trzeba tutaj wspomnieć, że obie z tych metod zadziałają skutecznie jedynie w przypadku tablic składających się z typów prostych. W typach referencyjnych porównywane są referencje, a nie wartości. Dwa obiekty o różnych referencjach, lecz identycznej strukturze nie będą traktowane jako duplikaty. Zachęcam, aby przeanalizować poniższy przykład:
const obj = { a: 2 };
const arr = [ 'foo', 'bar', 'baz', 'bar', 'bar', 'baz', obj, obj, { a: 1 }, { a: 1 } ];
const noDuplicates = [ ...new Set( [ ...arr ] ) ];
console.log( noDuplicates );
Czym jest CORS?
CORS, czyli Cross-Origin Resource Sharing to mechanizm, który kontroluje, czy witryny internetowe mogą żądać zasobów (takich jak dane z zewnętrznych API, obrazy, style CSS, skrypty JS itp.) z innych domen, niż ta, z której pochodzi strona internetowa.
Jednym z mechanizmów bezpieczeństwa w przeglądarkach jest Same-Origin Policy. Mechanizm ten nie pozwala np. na wykonywanie zapytań do API znajdującego się pod inną domeną. Mimo wszystko zdarzają się sytuacje, gdy skorzystanie z wcześniej wspomnianego już API pod zewnętrzną domeną jest konieczne. W tym celu można wykorzystać mechanizm CORS, aby to umożliwić, a jednocześnie by było to bezpieczne. CORS został szczegółowo opisany w artykule od Sekuraka, do którego Cię odsyłam.
Czym jest property descriptor?
Property descriptors to opis właściwości danego obiektu. Deskryptor dla wybranej właściwości można podejrzeć za pomocą metody Object.getOwnPropertyDescriptor( object , 'property' )
.
const car = {
model: 'Golf',
brand: 'Volkswagen',
engine: '1.9TDI'
};
console.log( Object.getOwnPropertyDescriptor( car, 'engine' ) );
// Expected output:
// [object Object] {
// configurable: true,
// enumerable: true,
// value: "1.9TDI",
// writable: true
//}
W rezultacie wywołania tej metody zwracany jest obiekt z czterema właściwościami: configurable
, enumerable
, value
i writable
. Ustawienie wartości writable
na false
sprawi, że wartość stanie się wartością tylko do odczytu. Wartość enumerable
odpowiada, za to, czy można po niej iterować za pomocą np. Object.keys
czy pętli for…in
. Właściwość configurable
odpowiada za to, czy daną właściwość można usunąć oraz, czy można zmieniać pozostałe deskryptory. Właściwość value
przechowuje wartość. Temat property descriptorów szczegółowo przedstawiłem w dedykowanym artykule na blogu.
Czym są Core Web Vitals?
Core Web Vitals to zestaw metryk wydajności, które Google uznaje za kluczowe przy ocenie jakości stron WWW. Każda z metryk składająca się na Core Web Vitals reprezentuje odrębny aspekt doświadczenia użytkownika. Obecnie, Core Web Vitals skupiają się na trzech głównych metrykach:
- LCP (Largest Contentful Paint) – mierzy wydajność ładowania. Aby zapewnić użytkownikom dobre doświadczenia, LCP powinno nastąpić w ciągu 2,5 sekundy od pierwszego rozpoczęcia ładowania strony.
- FID (First Input Delay) – mierzy interaktywność. Aby zapewnić wygodę użytkowania, strony powinny mieć FID wynoszący maksymalnie 100 milisekund.
- CLS (Cumulative Layout Shift) – mierzy stabilność wizualną. Wartość CLS rośnie, gdy doładowywanie kolejnych elementów na stronie powoduje przesuwanie się już załadowanych. Przesuwające się w nieoczekiwany sposób elementy, powodują przypadkowe kliknięcia lub błędy użytkownika. Aby zapewnić wygodę użytkowania, strony powinny utrzymywać CLS na poziomie 0,1. lub mniej.
Do czego służą atrybuty srcset
i sizes
w tagu img
?
Atrybuty srcset
i sizes
przeglądarka wykorzystuje, aby dostarczyć odpowiedni wariant obrazu do wyświetlenia w zależności od szerokości widoku przeglądarki czy rozdzielczości. Atrybut srcset
określa dostępne warianty obrazu wraz z ich rozdzielczościami i źródłami. Atrybut sizes
określa, jak szeroki będzie obraz w kontekście różnych szerokości widoku przeglądarki.
Podsumowanie
Te kilkanaście pytań to o wiele za mało, by być dobrze przygotowanym do rozmowy rekrutacyjnej. Jeszcze raz gorąco zachęcam do sprawdzenia innych wpisów na blogu oraz pobranie e-booka 106 Pytań Rekrutacyjnych Junior JavaScript Developer. Zachęcam też do zostawiania komentarzy i udostępnienia tego wpisu znajomym, którym ta wiedza może się przydać.
Źródła i materiały dodatkowe
- MDN – Memory management
- What is event bubbling and capturing?
- Bubbling and capturing
- Getting Started with ESLint
- What is the difference between SVG and HTML5 Canvas?
- What is an IIFE in JavaScript?
- What is Memory Leak? How can we avoid?
- OWASP – Memory leak
- MDN – Set
- Czym jest CORS (Cross-Origin Resource Sharing) i jak wpływa na bezpieczeństwo
- Cross-Origin Resource Sharing (CORS)
- MDN – Object.defineProperty()
- Property descriptors w JavaScript
- Web Vitals
- MDN – Responsive images
*Artykuł jest odświeżoną wersją wpisu z 2019 roku.
Zapisz się na mailing i odbierz e-booka
Odbierz darmowy egzemplarz e-booka 106 Pytań Rekrutacyjnych Junior JavaScript Developer i realnie zwiększ swoje szanse na rozmowie rekrutacyjnej! Będziesz też otrzymywać wartościowe treści i powiadomienia o nowych wpisach na skrzynkę e-mail.