26.01.202210 min

Maciej OlanickiRedakcja Bulldogjob

Developer .NET– pytania rekrutacyjne + odpowiedzi

Dowiedz się, jak przygotować się do rozmowy kwalifikacyjnej Developera .NET i poznaj przykładowe pytania rekrutacyjne!

Developer .NET– pytania rekrutacyjne + odpowiedzi

Platforma .NET od lat zajmuje centralne miejsce w deweloperskim systemie Microsoftu, a jej ranga wzrosła jeszcze bardziej po podjęciu przez korporację decyzji o unifikacji wielu frameworków rozwijanych dotąd mniej lub bardziej niezależnie właśnie w ramach .NET. Między innymi to sprawia, że praca z .NET pozostaje dla wielu interesującą ścieżką, a na rynku pracy nie brakuje licznych intratnych ofert. 

Warto zastanowić się zatem, jak najczęściej przebiega rozmowa kwalifikacyjna na stanowiska związane z platformą .NET. Z jakimi zagadnieniami powinien zapoznać się kandydat? O co powinien zapytać rekrutujący? Jakie konkretne techniczne aspekty znajomości platformy Microsoftu powinny zostać omówione podczas rozmowy? Jak wybrać zadania rekrutacyjne? Tymi, jak i wieloma innymi kwestiami, zajmiemy się w niniejszym artykule.


.NET – specyfika

Zanim jednak przejdziemy do konkretów, warto poświęcić nieco uwagi specyfice samej platformy, a co za tym idzie – charakterystyce stanowisk. W odróżnieniu od wielu innych ofert pracy w IT, w przypadku .NET nie musimy wcale wiązać stanowiska z konkretnym językiem oprogramowania, chyba że tego wymaga sam projekt. W teorii nic przecież nie stoi na przeszkodzie, by na .NET pisać kod w C++ czy C#, ale też F# czy J#. Praktyka pokazuje jednak, że najczęściej wśród wymagań wobec developera .NET występuje znajomość języka C#, co na pewno powinien wziąć  pod uwagę zarówno rekrutujący, jak i kandydat.

Przed podjęciem poszukiwań pracy w .NET należy sobie także uświadomić wspomniany już proces unifikacji narzędzi, a w zasadzie frameworków programistycznych Microsoftu. .NET dawno już przestał być frameworkiem wykorzystywanym do rozwoju oprogramowania wyłącznie na systemy Windows. 

Wręcz przeciwnie, dziś jest to opensource’owa i działająca w wielu różnych środowiskach platforma, dzięki której z powodzeniem budować można aplikacje na Windowsa, macOS-a, Androida i iOS-a oraz oczywiście aplikacje webowe. Ponadto z wariantu .NET Core i IDE Visual Studio korzystać można także na licznych dystrybucjach Linuksa. .NET nie stawia ponadto znaczących ograniczeń w kwestii wykorzystywanych IDE czy edytorów i nic nie stoi na przeszkodzie, aby wspomniane VIsual Studio zastąpić edytorem Visual Studio Code, IDE JetBrains Rider czy oficjalnym SDK obsługiwanym z poziomu wiersza poleceń. 

Niezależnie od systemu operacyjnego, na którym uruchamiana będzie aplikacja, .NET oferuje ustandaryzowany zestaw API i dostęp do ponad 90 tys. bibliotek, ułatwiających pracę i przenoszenie aplikacji na nowe ekosystemy. Równie dobrze jak przy tworzeniu aplikacji natywnych. framework poradzi sobie z projektowaniem mikrousług, usług chmurowych, a nawet w obciążeniach związanych z uczeniem maszynowym i Internetem Rzeczy.


Rozmowa kwalifikacyjna

Mimo omówionej już specyfiki frameworka .NET, sam proces rekrutacji nie odbiega zasadniczo od stanowisk ściślej powiązanych z konkretnym językiem programowania czy docelowym środowiskiem, w którym działać będą aplikacje. Należy ją jednak uwzględnić już na etapie projektowania CV, czyli na pierwszym etapie rekrutacji. 

W rezultacie jasno należy wykazać swój stopień znajomości np. C# oraz doświadczenie w budowaniu aplikacji w .NET. Warto także określić znajomość najpopularniejszych środowisk programistycznych, np. stopień znajomości Visual Basic lub alternatyw. W zasadzie nie sposób tutaj przesadzić – im bardziej szczegółowe informacje na temat pracy z konkretnymi narzędziami i przy konkretnym projektach zamieszczona zostaną w CV, tym lepiej. Warto także zaktywizować się w mediach społecznościowych, najlepszym wyborem będzie LinkedIn, gdzie można publikować informacje o przebiegu i sukcesach projektów, w których brało się udział oraz budować swoją markę. 

Suche informacje na temat doświadczeń świetnie jest poprzeć portfolio, gdzie trafić mogą zarówno projekty realizowane dla poprzednich firm, jak i przedsięwzięcia hobbystyczne. W wielu procesach rekrutacyjnych stanowi to ogromny walor kandydata i już na starcie umożliwia zapoznanie się z jego praktycznymi umiejętnościami. Często zdarza się, że po dostarczeniu przemyślanego portfolio projektów firmy w ogóle odstępują od testowania kompetencji programistycznych z użyciem własnych zadań. Omówienie portfolio, jeśli takie oczywiście zostało opracowane, może być świetnym polem do popisu w kolejnym etapie rekrutacji, czyli już podczas rozmowy kwalifikacyjnej.

Rzecz jasna rozmowa kwalifikacyjna powinna być także poprzedzona przygotowaniem odpowiedzi na najczęściej zadawane przez rekruterów pytania. Zazwyczaj bowiem rozmowy przebiegają w dwóch etapach, z których pierwszym jest ogólne zapoznanie się z profilem kandydata, a drugi skupia się już na konkretach technicznych czy zadaniach. 

Zbagatelizowanie pierwszej części rozmowy to wyjątkowo słaby pomysł, wówczas bowiem sprawdzane są takie cechy kandydata, jak umiejętności komunikacyjne, ale też całościowy profil, podejście do pracy czy jej organizacja. Ważne zatem, aby kandydat było gotowy do odpowiedzi w takich kwestiach, jak prośba opowiedzenia o sobie, powody chęci zmiany pracy, co dla kandydata jest w pracy najważniejsze czy plany na rozwój kariery. Nieprzygotowanie w tych aspektach może zaskoczyć już podczas faktycznej rozmowy i przekreślić szanse na zdobycie stanowiska.


Kluczowe zagadnienia

w .NET funkcjonuje kilka ważnych elementów na poziomie koncepcyjnym, z których funkcjonowaniem z całą pewnością warto zapoznać się przed przystąpieniem do procesów rekrutacyjnych. Jedne z nich są specyficzne dla platformy Microsoftu, inne napotkać możemy także w innych technologiach. Ważnym elementem przygotowania się do rozmowy rekrutacyjnej powinno być także odświeżenie sobie podstawowych typów i klas najczęściej wykorzystywanych w projektach .NET.


Common Language Runtine (CLR)

CLR, jak wskazuje sama nazwa, to wspólne środowisko uruchomieniowe dla platformowy .NET. Jest to zdecydowanie jeden z najważniejszych elementów całego frameworka, a być może najważniejszy. Dzięki niemu możliwe jest wykonywanie kodu CIL (o którym więcej za moment) na wielu platformach, między innymi na Windowsie, macOS-ie czy systemach UNIX-owych. To właśnie CLR odpowiada za kompilacje i wykonanie kodu, ale także dysponuje zapisem standardowych typów danych oraz mechanizmami bezpieczeństwa. Jeśli mielibyśmy umiejscowić CLR w całym workflow .NET, to będzie on odpowiadał za przetworzenie kodu w CIL na kod natywny, stanowiąc faktyczne środowisko uruchomieniowe.


Common Intermediate Language (CIL)

Specyficzne dla .NET jest jednak, że pomiędzy kompilatorem a środowiskiem uruchomieniowym występuje jeszcze jedno ogniwo, a mianowicie Common Intermediate Language. W odróżneiniu od wielu innych platform, w .NET kod zapisany w języku programowania nie jest od razu kompilowany do binarek, lecz na język-pośrednik, czyli właśnie CIL. W efekcie w. NET kod napisany np. w C# najpierw „kompilowany” jest do CIL, a dopiero później trafia do środowiska uruchomieniowego CLR, gdzie przetwarzany jest już na kod bajtowy. CIL można zatem porównać do assemblera, języka, który w .NET jest na najniższym poziomie zrozumiałym bez człowieka, gdyż, jak już wspomniano, dalej występuje już kod bajtowy. Niegdyś CIL nosił nazwę Microsoft Intermediate Language, niemniej wraz ze wzrostem popularności .NET (dziś do CIL kompiluje się ponad 40 języków) zdecydowano się na bardziej uniwersalną nazwę.


Common Type System (CTS)

Kolejnym ważnym składnikiem frameworka jest CTS, który zawiera definicje wszystkich typów, tego jak są używane, deklarowane i zarządzane w CLR. CTS odgrywa także ważną rolę w ujednolicaniu typów pomiędzy różnymi języki kompilowanymi do CIL, zapewniając zgodność i bezpieczeństwo typów. System dostarcza także bibliotekę z pierwotnymi typami danych, którym warto w tym kontekście przyjrzeć się bliżej. 

Co ważne, wszystkie typy w .NET to typy wartości lub typy referencyjne. W przypadku pierwszych mamy do czynienia z typami danych, gdzie obiekty są reprezentowane przez swoją rzeczywistą wartość, w przypadku typów referencyjnych są natomiast reprezentowane przez odwołanie do rzeczywistej wartości.  Wśród typów .NET rozróżnia się pięć podstawowych kategorii: klasy, struktury, wyliczenia, interfejsy, delegaci. Szczegółowy opis poszczególnych typów znaleźć można w oficjalnej dokumentacji platformy .NET.


Commong Language Specification (CLS)

CLS to specyfikacja określający zasady kompilacji poszczególnych języków obsługiwanych w .NET do języka pośredniego CIL. Dzięki niej możliwa jest pełna interakcja pomiędzy obiektami niezależnie od języka, a to za sprawą wystawiania na wywołania tylko tych funkcji czy elementów, które są wspólne dla danej pary językowej, wykluczając tym samym wszelkie relacje, w których mogłaby występować niekompatybilność. Dzięki CLS można zatem mówić o stworzeniu instrukcji i wytycznych stanowiących warstwę tłumaczącą konkretne wywołania wewnątrz .NET niezależnie od języków programowania, w których zostały napisane konkretne komponenty.


Assembly

Krótko mówiąc, assembly w .NET do output, skompilowana końcowa jednostka całego wdrożenia występująca w postaci pliku DLL lub EXE. Do assembly trafiają także informacje o typach i innych zasobach wykorzystywanych do zbudowania pliku, manifest z metadanymi, informacje wykorzystywane do późniejszej kontroli wersji oraz oczywiście najważniejszy w tym wszystkim kod skompilowany do CIL. Warto zwrócić uwagę, że pojedyncze assembly może być wykorzystywane przez wiele różnych aplikacji.


Przykładowe pytania

Choć każda rozmowa kwalifikacyjna jest inna, to jednak podczas aplikowania na stanowisko developera .NET możemy spodziewać się pewnego zasobu zagadnień, które niemal na pewno zostaną poruszane i pytań, które bardzo prawdopodobne padną. Odpowiedzi na część z nich wynikają bezpośrednio z powyższego omówienia najważniejszych zagadnień związanych z .NET, inne zaś mogą się odnosić do kwestii okołoprogramistycznych. Warto także pamiętać, że .NET prężnie się rozwija i pytania mogą się zmieniać – dlatego ważnym elementem poszukiwania pracy w IT jest bycie na bieżąco z nowościami oraz przede wszystkim bazami pytań dostępnymi w internecie.


Jak działa framework .NET?

Rzecz jasna to dość złożone pytanie i można na nie odpowiedzieć mniej lub bardziej szczegółowo. Dobrze będzie zacząć od omówienia przepływu pracy, który rozpoczyna się od przygotowania kodu w jednym z IDE lub edytorów, by następnie doszło do kompilacji kodu do Common Intermediate Language, którego charakterystykę także należy uwzględnić przy ogólnym opisie działania .NET. Następnie wskazać należy kompilację CIL do kodu bajtowego i zwrócić uwagę na składniki assembly, będącego wynikiem całego workflow. W bardziej rozbudowanych wariantach odpowiedzi na te pytania należy uwzględnić informacje, które umówiliśmy w jako kluczowe zagadnienia: CLR, CIL, CTS i CLS.


Czym jest Base Class Library?

Base Class Library, znane także jako po prostu BCL, to duży zbiór standardowych, podstawowych bibliotek dostępnych w .NET, zarówno opensource’owych, jak i komercyjnych. Jest tu wszystko, co najważniejsze, by rozpocząć projekt: typy, ogólne ich implementacje dla takich języków programowania, jak C#, F#, C++, itd. Biblioteki bazowe to także zasoby, na których budowane są inne, bardziej wyspecjalizowane biblioteki, których działanie jest niemożliwe bez BCL.


Jaka jest w .NET różnica między int oraz Int32?

Pytanie z rodzaju podchwytliwych. Pomiędzy int a Int32 nie ma bowiem żadnej różnicy – są to dwie nazwy tego samego typu danych funkcjonującego we frameworku .NET, a konkretniej 32-bitowej podpisanej liczby całkowitej. Skąd zatem dwie nazwy? Int32 to po prostu alternatywna nazwa int wykorzystywana w języku C#.


Czym są i czym się różnią EXE i DLL?

Jak już wspomniano w kontekście omawiania kluczowych elementów .NET, EXE i DLL to formaty assembly, a zatem skompilowanej podstawowej jednostce całego wdrożenia. O ile jednak EXE to plik wykonywalny, który uruchamiania aplikację, tak w przypadku DLL mowa już o bibliotece. Z tego wynikają różnice: EXE służy do uruchamiania aplikacji, ale nie może być współdzielony, zaś w przypadku DLL jest odwrotnie – jest to biblioteka z kodem, która sama w sobie nie jest aplikacją, ale może być współdzielona pomiędzy różnymi aplikacjami.


Czym jest delegat?

Pilny Czytelnik zauważył już zapewne, że delegat to jeden z pięciu podstawowych typów w .NET. Jest to typ referencyjny, którego zadaniem jest reprezentowanie referencji do metod. Delegatów wykorzystuje się, by przekazywać metody do innych metod w postaci argumentów. Pozyskać i przekazać można w ten sposób każdą metodę z każdej dostępnej klasy, zarówno metodę statyczną, jak i metodę instancji.


Czym jest JIT?

JIT to skrót od just-in-time. Jest to wykorzystywana w .NET metoda kompilacji, dzięki której właściwy kod bajtowy jest kompilowany do kodu maszynowego tuż przed wykonaniem danego fragmentu. Dzięki temu możliwa jest optymalizacja całego procesu wykonywania, gdyż kompilowane do kodu maszynowego są tylko te komponenty kodu, które w danym algorytmie faktycznie będą wykorzystywane, nie zaś cały kod od początku do końca, co skutkuje oczywiście oszczędnością pamięci oraz optymalizacji wykonywania dokonywanej na podstawie analizy statystycznej. W .NET JIT jest częścią środowiska uruchomieniowego CLR.


Jakie są różnice pomiędzy typami wartości typami referencyjnymi?

O ile wstępną różnicę pomiędzy dwoma rodzajami typów w .NET omówiliśmy pokrótce już wcześniej, tak powyższe pytanie może się okazać popularne podczas rekrutacji, warto więc omówić to zagadnienie nieco bardziej szczegółowo. Jak już wspomniano, typy wartości zawierają faktyczne dane – bezpośrednio z pamięci. W przypadku typów referencyjnych, jak zresztą wskazuje sama nazwa, przechowywane jest wyłącznie odniesienie do danych, referencja do nich, czyli adres konkretnej informacji w pamięci. Z tej kluczowej różnicy wynikają kolejne – typy wartości przechowują dane w stosach, zaś typy referencyjne w stertach. Ponadto przypisanie zmiennej o typie wartości do innej zmiennej sprawi, że wartość pierwszej zostanie bezpośrednio skopiowana (docelowa zmienna także będzie zawierała dane), zaś przypisanie zmiennej typu referencyjnego poskutkuje tylko utworzeniem kopii referencji.


Zadania rekrutacyjne

Na sam koniec prześledźmy popularne zadania rekrutacyjne wykorzystywane podczas poszukiwania na kandydatów na stanowisko .NET developer. Częstym schematem jest np. pytanie o wynik jakiegoś kodu. Prześledzmy to w praktyce:

class Program {
  static String location;
  static DateTime time;
 
  static void Main() {
    Console.WriteLine(location == null ? "location is null" : location);
    Console.WriteLine(time == null ? "time is null" : time.ToString());
  }
}


Widzimy tu dwie niezainicjonalizowane zmienne. Zagwozdka będzie polegać na tym, jakie przyjmą wartości. Należy jednak pamiętać, że string to typ referencyjny, a DateTime to typ wartości. W efekcie data przyjmie wartość domyślną, a ta w C# wskazuje na północ 1 stycznia roku 1 n.e.:

location is null
1/1/0001 12:00:00 AM


Powyższy przykład stanowi także odpowiedź na inne popularne zadanie. Kandydat może być bowiem poproszony o to, aby opisać, jak w C# wprowadza się typy zerowalne. Wówczas należy zaprezentować przykładową składnię:

Nullable<data_type> variable_name=null;


lub 

Datatype? variable_name=null;


Często zadania mogą się także odnosić do wykorzystania w praktyce konkretnego mechanizmu. Paść może pytanie o to, czym jest wyrażenie regularne, zaś zadanie może sprowadzać się do napisania programu, który będzie wyszukiwał wyrażenie regularne w stringach: 

static void Main(strong[] args){
	string[] languages = {“C#”, “Python”, “Java”};
	foreach(string s in languages)
	{
		if(System.Text.RegularExpressions.Regex.IsMatch(s,“C#”))
	{
		Console.WriteLine(“Match found”);
		}
	}
}


Możliwości jest oczywiście wiele, tym bardziej warto więc śledzić przed i w trakcie procesu rekrutacji przewijające się na wielu stronach bazy pytań i zadań, przeglądać wątki na StackOverflow czy zakupić dostęp do baz programistycznych łamigłówek w C#.

<p>Loading...</p>