Przejdź do głównej treści
  1. Strona główna
  2. Wyniki egzaminu

Wyniki egzaminu

Nowy egzamin

Informacje o egzaminie

  • Zawód: Technik programista
  • Kwalifikacja: INF.04 - Projektowanie, programowanie i testowanie aplikacji
  • Rozpoczęcie: 7 czerwca 2026 22:44
  • Zakończenie: 7 czerwca 2026 22:59

Egzamin zdany!

Wynik: 29/40 punktów (72,5%)

Wymagane minimum: 20 punktów (50%)

Twój wynik na tle innych

Twój wynik jest lepszy niż 42% podejść do kwalifikacji INF.04.

Porównanie z 22430 zakończonymi podejściami do tej kwalifikacji (dane zbiorcze, bez wyników indywidualnych).

Poprawa! Poprzednio 47,5%, teraz 72,5% (+25,0 p.p.).

Zachowaj ten wynik na koncie

Załóż darmowe konto albo zaloguj się - ten egzamin przypiszemy do Twojego konta, więc wrócisz do swoich błędów, będziesz śledzić postęp i dostaniesz powtórki dobrane do Twoich odpowiedzi.

Analiza przebiegu egzaminu - sprawdź jak rozwiązywałeś pytania Przebieg egzaminu

Analiza przebiegu egzaminu

Odtwarzaj przebieg egzaminu krok po kroku i ucz się na własnych błędach - kolejność rozwiązywania, czas nad każdym pytaniem, momenty zmiany odpowiedzi.

  • Suwak czasu - przeglądaj pytania w kolejności rozwiązywania.
  • Tryb nauki - poprawne odpowiedzi i wyjaśnienia.
  • Analiza czasu - ile czasu nad każdym pytaniem.
  • Monitoring focusu - momenty opuszczenia zakładki.

Pochwal się swoim wynikiem!

Szczegółowe wyniki

Pytanie 1

Co oznacza skrót CDN w kontekście aplikacji webowych?

A. Content Delivery Network - sieć rozproszona geograficznie, służąca do dostarczania treści
B. Compressed Data Node - węzeł kompresji danych w architekturze mikrousług
C. Content Definition Notation - notacja do definiowania treści w aplikacjach
D. Cross Domain Navigation - metoda nawigacji między domenami w aplikacjach webowych
W kontekście aplikacji webowych błędne skróty i pojęcia często prowadzą do nieporozumień dotyczących architektury i technologii. Cross Domain Navigation, chociaż istotne w kontekście bezpieczeństwa i wymiany danych między różnymi domenami, nie jest związane z dostarczaniem treści. Metoda ta dotyczy głównie sposobów nawigacji w aplikacjach, które mogą wymagać zarządzania różnymi politykami CORS (Cross-Origin Resource Sharing), ale nie definiuje sposobów optymalizacji dostarczania treści. Compressed Data Node to termin, który sugeruje węzeł odpowiedzialny za kompresję danych w architekturze mikrousług, ale nie wiąże się z geograficznie rozproszonym dostarczaniem treści, co jest kluczowym aspektem działania CDN. Content Definition Notation to z kolei nieznany termin w literaturze dotyczącej technologii webowej, nie mający powszechnie uznawanej definicji w branży. Błędem myślowym byłoby utożsamianie tych terminów z sieciami dostarczania treści, ponieważ każde z nich ma swoją specyfikę i zastosowanie. W kontekście aplikacji internetowych kluczowe jest zrozumienie, że CDN ma na celu poprawę szybkości i efektywności dostarczania treści, co jest niezrównanie bardziej złożonym i istotnym zagadnieniem niż tylko nawigacja czy kompresja danych. Praktyki związane z sieciami CDN są dobrze udokumentowane i należy je stosować zgodnie z najlepszymi standardami branżowymi, aby zapewnić wysoką jakość usług dla użytkowników.

Pytanie 2

Jakie jest podstawowe użycie metod wirtualnych?

A. Umożliwienie wielokrotnego dziedziczenia
B. Umożliwienie dynamicznego wiązania metod w czasie wykonania
C. Zapewnienie, że metoda działa wyłącznie na danych statycznych
D. Umożliwienie korzystania z metod bezpośrednio z klasy bazowej
Metody wirtualne umożliwiają dynamiczne wiązanie metod w czasie wykonywania programu (ang. runtime). Oznacza to, że wywołanie metody zależy od rzeczywistego typu obiektu, a nie od typu wskaźnika lub referencji, za pomocą której został on wywołany. Mechanizm ten pozwala na implementację polimorfizmu, który jest jednym z kluczowych filarów programowania obiektowego. Dzięki metodom wirtualnym można uzyskać elastyczność i rozszerzalność kodu, umożliwiając klasom pochodnym dostarczanie własnych wersji metod zdefiniowanych w klasie bazowej. To prowadzi do bardziej zorganizowanego i skalowalnego kodu, ponieważ nowe funkcjonalności można dodawać, rozszerzając istniejące klasy, zamiast modyfikować kod bazowy.

Pytanie 3

Który z wymienionych parametrów dysku twardego ma największy wpływ na jego wydajność?

A. Prędkość obrotowa talerzy (RPM)
B. Rodzaj złącza (SATA/PCIe)
C. Ilość pamięci podręcznej (Cache)
D. Pojemność dysku
Prędkość obrotowa talerzy (RPM) jest kluczowym parametrem wpływającym na szybkość dysku twardego. Wyrażana w obrotach na minutę, RPM definiuje, jak szybko talerze dysku mogą obracać się, co z kolei wpływa na czas dostępu do danych. Dyski HDD o wyższej prędkości obrotowej, takie jak 7200 RPM w porównaniu do 5400 RPM, zazwyczaj oferują lepszą wydajność, co przekłada się na szybsze odczyty i zapisy danych. Przykładowo, w zastosowaniach wymagających intensywnego przetwarzania danych, takich jak gry komputerowe czy edycja wideo, wybór dysku o wyższej prędkości obrotowej może znacznie poprawić ogólne wrażenia użytkownika. Warto również zauważyć, że chociaż złącze SATA i PCIe wpływają na szybkość transferu, to w kontekście dysków HDD, RPM pozostaje jednym z najważniejszych czynników. Standardy takie jak SATA III oferują transfery do 6 Gb/s, ale jeśli talerze nie obracają się wystarczająco szybko, potencjał transferu nie zostanie w pełni wykorzystany. Z tego powodu, RPM jest kluczowym wskaźnikiem wydajności w kontekście dysków twardych.

Pytanie 4

Co będzie wynikiem wykonania poniższego kodu w języku C#?

string text = "hello world";
var result = string.Join("", text.Split(' ').Select(s => char.ToUpper(s[0]) + s.Substring(1)));
Console.WriteLine(result);
A. HelloWorld
B. helloworld
C. Hello World
D. HELLO WORLD
Wynikiem wykonania kodu nie jest 'HELLO WORLD', a przyczyna tego nieporozumienia tkwi w sposobie przetwarzania tekstu. Warto zauważyć, że kod nie wykonuje prostej konwersji wszystkich liter na wielkie, jak sugeruje ta odpowiedź. Zamiast tego, każda pierwsza litera każdego słowa jest zmieniana na wielką, a pozostałe litery pozostają w oryginalnym stanie, co w przypadku 'hello world' daje wyrażenie 'Hello World'. To zrozumienie jest kluczowe w programowaniu, ponieważ często błędnie zakładamy, że transformacje na tekstach działają w sposób jednorodny. Inną niepoprawną odpowiedzią jest 'helloworld', która również pomija konwersję pierwszych liter na wielkie, co jest kluczowym aspektem działania kodu. Warto rozważyć, że przy pracy z tekstami w C# istotne są szczegóły, takie jak wielkość liter, a dobre praktyki programistyczne wymagają zrozumienia, jak funkcje manipulujące tekstem działają. Niepoprawne odpowiedzi często wynikają z niezrozumienia schematu, jakim jest łączenie, a nie tylko konwersji liter. Użytkownicy powinni zawsze testować swoje założenia poprzez praktyczne próby w kodowaniu, aby unikać takich nieporozumień.

Pytanie 5

Które z wymienionych stwierdzeń najtrafniej charakteryzuje klasę dziedziczącą?

A. Klasa, która nie może posiadać konstruktorów ani destruktorów
B. Klasa, która dzieli swoje pola z klasami zaprzyjaźnionymi
C. Klasa, która umożliwia wielokrotne dziedziczenie pól prywatnych
D. Klasa, która wykorzystuje pola i metody innej klasy bez ich ponownej definicji
Dziedziczenie w programowaniu obiektowym pozwala na tworzenie nowych klas na podstawie istniejących. Klasa dziedziczona (klasa pochodna) automatycznie uzyskuje dostęp do publicznych i chronionych pól oraz metod klasy bazowej, co eliminuje potrzebę ich ponownego definiowania. Dzięki dziedziczeniu można rozszerzać funkcjonalność istniejących klas, co prowadzi do bardziej efektywnego i modułowego kodu. Przykładem może być klasa 'Pojazd', po której dziedziczy klasa 'Samochód', zachowując wszystkie właściwości pojazdu i dodając specyficzne dla samochodu metody lub pola.

Pytanie 6

Jak zostanie przedstawiony poniższy kod XAML?

Ilustracja do pytania
A. Rysunek 2
B. Rysunek 4
C. Rysunek 1
D. Rysunek 3
W przedstawionym kodzie XAML widoczna jest struktura składająca się z kilku elementów UI ułożonych w pionowym StackLayout co skutkuje wyświetleniem ich w pionowej kolejności. Pierwszym elementem jest Entry z placeholderem Imię a kolejnym Entry z placeholderem Nazwisko co determinuje obecność dwóch pól tekstowych tak jak w Rysunku 4. Następnie w kodzie znajduje się poziomy StackLayout z etykietą Zgoda RODO i przełącznikiem ustawionym na wartość true co oznacza że przełącznik jest domyślnie włączony. To również odpowiada widokowi na Rysunku 4. Kolejny element to Slider z ustawionymi kolorami MinimumTrackColor i MaximumTrackColor co pozwala na zmianę koloru paska suwaka co również jest widoczne w Rysunku 4. Na końcu znajduje się Button z tekstem Zapisz i jest to jedyny przycisk w całym układzie co także zgadza się z Rysunkiem 4. Rozumienie kodu XAML i jego renderowania jest kluczowe w tworzeniu aplikacji mobilnych ponieważ pozwala na precyzyjne określenie wyglądu i funkcjonalności interfejsu użytkownika i jest zgodne z najlepszymi praktykami w projektowaniu UI.

Pytanie 7

Zajmując się pracą w zespole oraz dbając o jego efektywne funkcjonowanie, nie powinniśmy

A. sumiennie i w ustalonym terminie realizować swoje zadania
B. skupiać się jedynie na własnych korzyściach
C. przyjmować odpowiedzialności za swoje decyzje
D. wspierać się nawzajem
Dokładnie o to chodzi – skupianie się tylko na własnych korzyściach prawie zawsze działa na szkodę zespołu. W praktyce, gdy ktoś patrzy wyłącznie na siebie, najczęściej zaniedbuje współpracę, co prowadzi do napięć i spadku efektywności grupy. W zespole liczy się wspólny cel, a nie indywidualne interesy, bo to właśnie dzięki wzajemnemu wsparciu i otwartej komunikacji można osiągnąć lepsze wyniki. Z mojego doświadczenia wynika, że projekty, w których członkowie współpracowali i dzielili się odpowiedzialnością, szły sprawniej i bez zbędnych spięć. Profesjonalne standardy, np. metodyki Scrum czy Agile, akcentują wartość pracy zespołowej i transparentności – jeśli każdy ciągnie w swoją stronę, cały model współpracy się sypie. Warto pamiętać, że nawet najlepszy specjalista sam nie pociągnie projektu, jeśli nie będzie działał fair wobec innych. Najlepiej się sprawdza takie podejście, gdzie ludzie podchodzą do pracy z otwartością, potrafią poprosić o pomoc i wspólnie świętują sukcesy, a nie tylko skupiają się na własnych liczbach czy bonusach. To naprawdę widać w praktyce – zespoły, gdzie nie liczy się tylko własny interes, mają zwykle znacznie lepsze efekty i atmosferę pracy.

Pytanie 8

Zapisany fragment w C# wskazuje na definicję klasy Car, która:

public class Car: Vehicle {     ...   }
A. stanowi klasę bazową (nie dziedziczy po żadnej klasie)
B. dziedziczy po Vehicle
C. jest powiązana z klasą Vehicle
D. używa prywatnych pól klasy Vehicle
W przedstawionym kodzie w języku C# mamy definicję klasy Car, która dziedziczy po klasie Vehicle. Dziedziczenie to fundamentalny mechanizm programowania obiektowego, pozwalający jednej klasie przejąć właściwości i metody innej klasy. W praktyce oznacza to, że klasa Car automatycznie zyskuje dostęp do metod i właściwości publicznych oraz chronionych klasy Vehicle, co umożliwia ponowne użycie kodu i zwiększa jego przejrzystość. Dziedziczenie jest kluczowe w projektowaniu skalowalnych systemów, gdzie umożliwia tworzenie bardziej specyficznych klas na podstawie klas ogólnych, co jest zgodne z zasadą DRY (Don't Repeat Yourself). Przykładowo, jeżeli klasa Vehicle zawiera metody takie jak Start() i Stop(), klasa Car może je wykorzystać bez konieczności ponownego definiowania. Dobre praktyki w programowaniu obiektowym zalecają wykorzystywanie dziedziczenia do tworzenia hierarchii klas, które logicznie odwzorowują relacje „jest-a” pomiędzy obiektami w systemie. Ważne jest też unikanie zbyt głębokiego dziedziczenia, co może prowadzić do skomplikowanego i trudnego w utrzymaniu kodu. Zrozumienie dziedziczenia jest kluczowe dla efektywnego wykorzystania wzorców projektowych, takich jak wzorzec projektowy Adapter czy Dekorator.

Pytanie 9

Przedstawione w filmie działania wykorzystują narzędzie

A. generatora GUI przekształcającego kod do języka XAML
B. generatora kodu java
C. debuggera analizującego wykonujący kod
D. kompilatora dla interfejsu graficznego
Wybrana odpowiedź jest trafna, bo faktycznie narzędzie pokazane w filmie to generator GUI, który potrafi przekształcać kod do języka XAML. XAML (czyli Extensible Application Markup Language) jest powszechnie używany do deklaratywnego opisywania interfejsów użytkownika, na przykład w aplikacjach WPF czy UWP na platformie .NET. Jak dla mnie, korzystanie z takich generatorów to ogromna wygoda, bo pozwala błyskawicznie przenosić projekt graficzny do formatu czytelnego dla platformy Microsoftu. Z mojego doświadczenia, wiele zespołów programistycznych stosuje takie rozwiązania, żeby oszczędzić czas na ręcznym pisaniu XAML-a (co potrafi być naprawdę żmudne przy dużych projektach). Co ciekawe, takie narzędzia bardzo dobrze współpracują z designerskimi edytorami UI i potrafią zautomatyzować konwersję nawet z innych formatów graficznych, np. Sketch czy Adobe XD do XAML-a. Branżowe standardy zalecają, by wykorzystywać generatorów GUI właśnie do tego celu, bo minimalizuje to liczbę błędów, przyspiesza wdrożenie zmian i ułatwia współpracę między programistami a projektantami. Warto pamiętać, że XAML jest bardzo elastyczny i umożliwia potem ręczną edycję wygenerowanego kodu – czasem powstają drobne poprawki, ale ogólnie to naprawdę przydatne narzędzie. Ogólnie – jeśli tylko projektujesz UI pod .NET, to automatyczna konwersja do XAML-a to jest coś, co warto znać i wykorzystywać w praktyce.

Pytanie 10

Co to jest git rebase?

A. Metoda tworzenia kopii zapasowej repozytorium
B. Narzędzie do rozwiązywania konfliktów między plikami
C. Polecenie do tworzenia nowego repozytorium
D. Technika integracji zmian z jednej gałęzi do drugiej przez przeniesienie lub połączenie sekwencji commitów
Git rebase to technika stosowana w systemach kontroli wersji, która umożliwia integrację zmian z jednej gałęzi do drugiej poprzez przeniesienie lub połączenie sekwencji commitów. W praktyce, rebase pozwala na 'przeniesienie' commitów z gałęzi roboczej na szczyt gałęzi docelowej, co skutkuje liniowym historią commitów. Taka struktura jest bardziej przejrzysta i ułatwia śledzenie wprowadzonych zmian. Przykładem zastosowania może być sytuacja, gdy pracujesz nad nową funkcjonalnością w gałęzi feature, a w międzyczasie na gałęzi main wprowadzono istotne poprawki. Wykonując rebase na swojej gałęzi feature, możesz szybko zintegrować zmiany z main, co pozwala na uniknięcie problemów z późniejszym scaleniem. Rebase jest zgodny z dobrymi praktykami branżowymi, ponieważ wspiera utrzymanie czystej historii projektu. Należy jednak pamiętać, że rebase zmienia historię, co sprawia, że nie powinno się go stosować na publicznych gałęziach, aby nie komplikować pracy innych deweloperów.

Pytanie 11

W środowisku IDE przeznaczonym do tworzenia aplikacji okienkowych zdefiniowano okno Form1. Aby wprowadzić zmiany w ustawieniach, w kolejności: tytuł okna na górnym pasku, standardowy kursor na strzałkę oraz kolor tła okna, należy dostosować następujące pola w oknie Properties:

Ilustracja do pytania
A. Text, Cursor, BackColor
B. Text, UseWaitCursor, BackColor
C. (Name), Cursor, BackgroundImage
D. (Name), UseWaitCursor, BackgroundImage
Wybrana odpowiedź jest prawidłowa, bo dokładnie te trzy właściwości – Text, Cursor i BackColor – odpowiadają w Windows Forms za ustawienia tytułu okna, domyślnego kursora myszy oraz koloru tła formularza. W praktyce, edytując pole Text w Properties, określasz, co użytkownik zobaczy na belce tytułowej okna. To często pierwszy krok w customizacji okna – tytuł powinien jednoznacznie identyfikować aplikację i jej funkcję, zgodnie z dobrymi praktykami UX/UI. Następnie pole Cursor umożliwia wybranie rodzaju kursora, który pojawi się, gdy użytkownik najedzie myszą na dany formularz. Najczęściej używany jest domyślny wskaźnik (strzałka), ale można tu ustawić na przykład kursor oczekiwania czy rękę, jeśli wymaga tego logika aplikacji. Zmiana BackColor to podstawa, jeśli chcesz wizualnie wyróżnić okno lub dostosować je do kolorystyki firmowej. Moim zdaniem, te trzy pola to podstawa podstaw w pracy z IDE do Windows Forms – bez ich zrozumienia ciężko mówić o jakimkolwiek sensownym projektowaniu interfejsu. Warto też zwrócić uwagę, że te właściwości są uniwersalne i pojawiają się praktycznie w każdym tutorialu czy dokumentacji Microsoftu dla .NET – to już taki żelazny standard branżowy. Z mojego doświadczenia często początkujący programiści mają z tym problem, bo szukają skomplikowanych rozwiązań, a tu chodzi po prostu o poprawne posługiwanie się Properties. Dzięki temu nawet najprostsza apka wygląda profesjonalniej i jest bardziej intuicyjna dla użytkownika.

Pytanie 12

Który aspekt projektu aplikacji jest kluczowy dla zabezpieczenia danych użytkowników?

A. Pominięcie testowania aplikacji w etapie produkcji
B. Tworzenie prostych formularzy do rejestracji
C. Koncentracja na wyglądzie interfejsu użytkownika
D. Zastosowanie zaawansowanych systemów ochrony
Stosowanie zaawansowanych mechanizmów bezpieczeństwa jest kluczowe dla ochrony danych użytkowników w aplikacjach. Wdrożenie technologii takich jak szyfrowanie, autoryzacja dwuskładnikowa (2FA), firewalle oraz regularne testy penetracyjne pozwala na minimalizację ryzyka ataków i naruszeń danych. Mechanizmy te nie tylko zabezpieczają dane, ale również budują zaufanie użytkowników do aplikacji, co jest niezwykle istotne w branżach takich jak bankowość, medycyna czy e-commerce.

Pytanie 13

Który z języków programowania jest najczęściej wykorzystywany do budowania aplikacji internetowych po stronie serwera?

A. HTML
B. PHP
C. JavaScript
D. CSS
PHP to jeden z najczęściej używanych języków programowania do tworzenia aplikacji webowych po stronie serwera. Jest to język skryptowy, który umożliwia dynamiczne generowanie treści stron internetowych, zarządzanie sesjami użytkowników, obsługę formularzy oraz integrację z bazami danych. PHP napędza popularne systemy zarządzania treścią (CMS), takie jak WordPress, Joomla czy Drupal. Dzięki swojej prostocie, szerokiemu wsparciu społeczności oraz dużej liczbie gotowych bibliotek i frameworków (np. Laravel), PHP pozostaje jednym z czołowych języków backendowych. PHP pozwala również na szybkie wdrażanie aplikacji i jest kompatybilny z wieloma serwerami WWW, co czyni go uniwersalnym wyborem w budowie aplikacji webowych.

Pytanie 14

Podaj wspólną cechę wszystkich kontrolek umieszczonych w ramce

<Label Text="5" BackgroundColor="Blue" TextColor="Tan" isVisible="True" />
<Stepper BackgroundColor="Blue" Value="5" isVisible="True" />
<Entry TextColor="Tan" BackgroundColor="Blue" Placeholder="5" />
<Slider ThumbColor="Tan" BackgroundColor="Blue" Value="5" isVisible="False" />
A. są w nich ustawione te same wartości domyślne
B. mają identyczny kolor czcionki
C. wszystkie są widoczne
D. mają tło w tym samym kolorze
W tym przypadku wskazałeś/aś, że wszystkie kontrolki mają tło w tym samym kolorze, i to jest faktycznie prawidłowa odpowiedź. Gdy spojrzymy na definicje: Label ma BackgroundColor="Blue", Stepper także BackgroundColor="Blue", Entry również BackgroundColor="Blue", a Slider—no właśnie—też BackgroundColor="Blue". To pokazuje, że niezależnie od typu kontrolki, wszystkie mają ustawione tło na dokładnie ten sam kolor. W praktyce bardzo często spotyka się wymóg zachowania spójności wizualnej interfejsu, szczególnie w aplikacjach profesjonalnych czy korporacyjnych. Ustalanie wspólnego BackgroundColor jest jednym z najprostszych kroków ku temu, by UI wyglądało porządnie i było czytelne dla użytkownika końcowego. Moim zdaniem, kiedy projektuje się cały ekran lub jakąś sekcję UI, warto od razu narzucić style lub korzystać z szablonów (np. Styles w XAML czy resourcach), żeby uniknąć przypadkowych rozbieżności kolorystycznych, które potem tylko irytują i programistów, i użytkowników. W branży jest to uznawane za dobrą praktykę – jednolity background ułatwia szybkie ogarnięcie, które elementy należą do jednej grupy funkcjonalnej. Poza tym, kolor tła bywa często wykorzystywany do komunikowania stanu albo priorytetu (np. alerty na czerwono itp.), więc to naprawdę ważne, żeby takie detale były przemyślane i konsekwentnie stosowane. No i jeszcze taka ciekawostka: nie wszystkie kontrolki domyślnie wyświetlają tło, więc czasem trzeba to jawnie ustawić, żeby efekt był taki sam na każdej platformie.

Pytanie 15

Zapis w języku C# przedstawia definicję klasy Car, która:

public class Car: Vehicle { ... }
A. jest klasą podstawową (nie dziedziczy po innej klasie)
B. używa pól prywatnych klasy Vehicle
C. jest zaprzyjaźniona z klasą Vehicle
D. odziedzicza po Vehicle
Słusznie, zapis public class Car : Vehicle { ... } w języku C# oznacza, że klasa Car dziedziczy po klasie Vehicle. To jest tak zwane dziedziczenie, jeden z fundamentalnych mechanizmów programowania obiektowego. Dzięki temu Car odzyskuje wszystkie publiczne i chronione (protected) człony klasy Vehicle, a dodatkowo może wprowadzać własne składowe albo nadpisywać metody bazowe. Przykładowo, jeśli Vehicle ma metodę Start(), to Car również ją posiada, chyba że ją nadpisze słówkiem override. Moim zdaniem, znajomość dziedziczenia ułatwia projektowanie czytelnych oraz rozszerzalnych systemów, zwłaszcza w większych projektach. W praktyce — jeśli tworzysz aplikację zarządzającą różnymi pojazdami, to możesz mieć np. klasę Vehicle z uniwersalnymi funkcjami i kilka pochodnych (takich jak Car, Truck, Motorcycle), co pozwala trzymać wspólną logikę w jednym miejscu. Warto pamiętać, że w C# jest tylko dziedziczenie pojedyncze jeśli chodzi o klasy (w przeciwieństwie do niektórych innych języków). To też zgodne z SOLID, gdzie jedna klasa powinna mieć jasno określoną odpowiedzialność. Ja często spotykam się z tym podejściem w kodzie produkcyjnym – porządek w strukturze to podstawa, a dziedziczenie bardzo w tym pomaga.

Pytanie 16

Które stwierdzenie dotyczące interfejsu w Java jest prawdziwe?

A. Interfejs może zawierać pola z dostępem protected
B. Wszystkie metody w interfejsie są domyślnie publiczne i abstrakcyjne
C. W interfejsie można definiować implementacje metod statycznych
D. Interfejs może dziedziczyć po wielu klasach jednocześnie
Wiele osób może mylić pojęcia związane z interfejsami i klasami w języku Java, co prowadzi do nieprawidłowych wniosków. Odpowiedź sugerująca, że interfejs może dziedziczyć po wielu klasach jednocześnie jest błędna, ponieważ w Javie interfejsy mogą jedynie dziedziczyć po innych interfejsach, a nie po klasach. To ograniczenie jest istotne, ponieważ pozwala na wielodziedziczenie interfejsów, co zwiększa elastyczność w projektowaniu systemów. Inną błędną koncepcją jest stwierdzenie, że interfejs może zawierać implementacje metod statycznych. W rzeczywistości metody statyczne nie mogą być zadeklarowane w interfejsach, ponieważ interfejsy nie są związane z instancjami obiektów, a metody statyczne są związane z klasami. Kolejnym powszechnym błędem jest myślenie, że pola w interfejsie mogą mieć modyfikator dostępu 'protected'. W praktyce, wszystkie pola w interfejsach są domyślnie publiczne, finalne i statyczne, co oznacza, że nie mogą być modyfikowane poza interfejsem. Zrozumienie tych zasad jest kluczowe dla efektywnego wykorzystania interfejsów w praktycznym programowaniu, gdyż pozwala na lepsze projektowanie zorientowane na obiekty oraz promuje dobre praktyki inżynieryjne.

Pytanie 17

Który z frameworków pozwala na tworzenie aplikacji z graficznym interfejsem użytkownika oraz obsługą wydarzeń?

A. Django
B. TensorFlow
C. Qt
D. Express.js
Django to framework do tworzenia aplikacji webowych w języku Python, a nie narzędzie do budowy aplikacji desktopowych z interfejsem graficznym. TensorFlow to biblioteka do uczenia maszynowego i sztucznej inteligencji, która nie ma bezpośredniego związku z projektowaniem GUI. Express.js to framework dla Node.js, który służy do budowy aplikacji serwerowych i API, ale nie jest narzędziem do projektowania interfejsów użytkownika w aplikacjach desktopowych.

Pytanie 18

Kod w bibliotece React.js oraz w frameworku Angular, który został zaprezentowany, ma na celu wyświetlenie

Fragment kodu React.js:
state = {    zm1: 0   };
hanleEv = () => {
    this.setState({zm1: this.state.zm1 + 1});
}
render() {
    return (<div>
        <span>{this.state.zm1}</span>
        <button onClick={this.handleEv}>BTN_1</button>
    </div>);
}
Fragment kodu Angular:
@Component({
    selector: 'sel1',
    template: `<span>{{ zm1 }}</span>
              <button (click)="onBtnCilcked()">BTN_1</button>`
})
export class Licznik1Component {
    zm1 = 0;
    onBtnCilcked() { this.zm1++; }
}
A. wartości 0 po naciśnięciu przycisku
B. liczby kliknięć przycisku
C. tylko napisu BTN_1
D. wyłącznie przycisku oraz obsłużenie zdarzenia click, które ono generuje
Ten kod, zarówno w React.js jak i w Angularze, jest klasycznym przykładem prostego licznika. To, co tu się dzieje, to tak naprawdę zliczanie kliknięć użytkownika w przycisk. Za każdym razem, gdy naciśniesz BTN_1, zmienna (zm1) jest inkrementowana – czyli po prostu zwiększana o jeden. W React za to odpowiada metoda setState, która zmienia stan komponentu – dzięki temu interfejs od razu aktualizuje się bez przeładowywania strony. W Angularze natomiast działa to przez tzw. dwukierunkową komunikację z template’em i automatyczną detekcję zmian – metoda onBtnCilcked w komponencie modyfikuje zmienną, a framework sam aktualizuje widok. Z mojego doświadczenia, takie podejście do zarządzania stanem to podstawa w nowoczesnych aplikacjach, szczególnie jeśli chodzi o responsywność i natychmiastową reakcję na akcje użytkownika. Liczniki są zresztą jednym z pierwszych przykładów, jakie się pisze ćwicząc frameworki frontendowe, bo świetnie pokazują, jak działa przepływ danych i odświeżanie elementów UI. Warto dodać, że trzymanie licznika kliknięć w stanie komponentu (a nie np. jako zmienną globalną) jest zgodne z dobrymi praktykami – bo ogranicza zakres danych i ułatwia zarządzanie większymi aplikacjami. Takie wzorce potem można z powodzeniem przenieść do trudniejszych projektów, na przykład liczników, koszyków, liczby zamówień czy nawet zaawansowanych dashboardów. W praktyce ten mechanizm inkrementowania wartości po kliknięciu użytkownika jest jednym z najczęściej używanych w interaktywnych aplikacjach internetowych.

Pytanie 19

Jakie jest przeznaczenie polecenia "git merge"?

A. Do zakładania nowego repozytorium
B. Do usuwania zmian w repozytorium
C. Do łączenia zmian z różnych gałęzi
D. Do pobierania aktualizacji zdalnego repozytorium
Polecenie "git merge" służy w Git do łączenia zmian z różnych gałęzi. Kiedy pracujemy w zespole i każdy programista rozwija swój fragment kodu na osobnej gałęzi, w pewnym momencie trzeba te zmiany zebrać do kupy, żeby powstała jedna, wspólna wersja projektu. Tu właśnie pojawia się "merge" – pozwala w prosty sposób dołączyć zmiany z jednej gałęzi do drugiej, najczęściej z feature branch do develop albo main. Praktycznie rzecz biorąc, to polecenie sprawdza się zawsze wtedy, gdy chcemy zintegrować efekty pracy kilku osób lub wersje rozwojowe z główną linią kodu. Moim zdaniem, korzystanie z "git merge" to w zasadzie codzienność w projektach zespołowych, bo prawie nikt już nie pracuje tylko na jednej gałęzi. Warto też pamiętać, że merge może czasem prowadzić do konfliktów, jeśli te same fragmenty plików były zmieniane równolegle – wtedy trzeba ręcznie rozwiązać te rozbieżności. W praktyce, dobrą praktyką jest regularne mergowanie, żeby uniknąć lawiny konfliktów na koniec sprintu. Dla mnie "merge" to narzędzie absolutnie kluczowe, bez którego ciężko sobie wyobrazić sensowną pracę z Gitem. No i jeszcze – to nie to samo co "rebase", chociaż oba służą do integracji zmian, ale w różny sposób. Merge zostawia historię połączeń, co ułatwia śledzenie zmian w większych projektach.

Pytanie 20

W jaki sposób określa się wypadek związany z pracą?

A. Nagłe zdarzenie związane z pracą, powodujące uraz lub śmierć
B. Każde zdarzenie, które wymaga interwencji technicznej w miejscu zatrudnienia
C. Każdy incydent wynikający z działania osób trzecich
D. Każde zdarzenie, które prowadzi do opóźnienia w wykonaniu obowiązków
Wypadek przy pracy to nagłe zdarzenie związane z wykonywaną pracą, które powoduje uraz lub śmierć pracownika. Wypadki te mogą być wynikiem zaniedbań, nieprzestrzegania zasad BHP lub nieodpowiedniego zabezpieczenia stanowiska pracy. Przykładami wypadków przy pracy są upadki z wysokości, porażenia prądem, oparzenia chemiczne lub uszkodzenia ciała przez maszyny. Pracodawca jest zobowiązany do zgłaszania każdego wypadku przy pracy, prowadzenia dochodzenia w celu ustalenia przyczyn i wdrażania działań zapobiegających powtórzeniu się podobnych sytuacji. Wypadki przy pracy są jedną z głównych przyczyn absencji oraz roszczeń pracowniczych, dlatego prewencja i edukacja w zakresie BHP są niezwykle istotne.

Pytanie 21

Co zostanie wypisane w konsoli po wykonaniu poniższego kodu JavaScript?

let a = { value: 10 };
let b = a;
b.value = 20;
console.log(a.value);
A. 10
B. undefined
C. ReferenceError
D. 20
Analizując błędne odpowiedzi, warto zwrócić uwagę na podstawowe zasady działania JavaScript w kontekście obiektów. Jeśli odpowiedzią byłoby 10, to sugerowałoby, że obiekt `a` nie został zmodyfikowany przez przypisanie do `b`, co jest nieprawdziwe. Obiekty w JavaScript są przekazywane przez referencję, co oznacza, że zmiana dokonana na jednym obiekcie wpływa na wszystkie referencje do niego. Odpowiedź `undefined` wskazywałaby na to, że obiekt `a` nie ma właściwości `value`, co również jest błędne, ponieważ obiekt `a` został zdefiniowany z tą właściwością i początkowo ma wartość 10. Z kolei `ReferenceError` występuje, gdy odwołujemy się do zmiennej, która nie istnieje w danym kontekście, co nie ma miejsca w naszym kodzie, ponieważ zarówno `a`, jak i `b` są zdefiniowane poprawnie. Błędy te często wynikają z niepełnego zrozumienia, jak JavaScript zarządza pamięcią i referencjami. Zrozumienie tych zasad jest kluczowe, aby unikać pułapek związanych z mutowalnością obiektów i przekazywaniem referencji, co może prowadzić do trudnych do diagnozowania błędów w większych projektach.

Pytanie 22

W jakiej topologii sieciowe wszystkie urządzenia są bezpośrednio powiązane z każdym innym?

A. Topologia siatki
B. Topologia magistrali
C. Topologia gwiazdy
D. Topologia pierścienia
Topologia magistrali charakteryzuje się tym, że wszystkie urządzenia są podłączone do pojedynczego kabla, zwanym magistralą. Komunikacja w tej topologii odbywa się przez przekazywanie sygnałów wzdłuż tego kabla, co może prowadzić do kolizji, gdy wiele urządzeń próbuje jednocześnie przesyłać dane. Ograniczeniem tej topologii jest to, że awaria magistrali skutkuje brakiem komunikacji w całej sieci, co czyni ją mniej niezawodną i efektywną w porównaniu do topologii siatki. Topologia gwiazdy polega na tym, że wszystkie urządzenia są połączone z centralnym punktem, zwanym koncentratorem lub przełącznikiem. Chociaż ta topologia zapewnia łatwość w dodawaniu nowych urządzeń i umożliwia izolację awarii, nie gwarantuje pełnej redundantności, ponieważ awaria centralnego urządzenia prowadzi do przerwania komunikacji w całej sieci. Z kolei topologia pierścienia, w której każde urządzenie jest połączone z dwoma innymi, tworząc zamknięty krąg, również nie jest odpowiednia, ponieważ awaria jednego połączenia uniemożliwia komunikację w całym pierścieniu, co czyni ją mniej odporną na błędy. W porównaniu do topologii siatki, wszystkie te struktury mają swoje ograniczenia, które wpływają na ich zastosowanie w bardziej złożonych i wymagających środowiskach sieciowych.

Pytanie 23

Jakie jest zadanie interpretera?

A. optymalizacja większej części kodu, aby przyspieszyć jego wykonanie
B. tłumaczenie kodu na kod maszynowy
C. wykonywanie skryptu krok po kroku
D. analiza składni całego programu przed jego uruchomieniem
Zobacz, dlaczego niektóre odpowiedzi były błędne w przypadku interpretera. Przede wszystkim, optymalizacja kodu nie jest jego głównym zadaniem. Choć można powiedzieć, że interpreter czasem poprawia wydajność, to nie o to tutaj chodzi. I pamiętaj, tłumaczenie kodu na kod maszynowy to zadanie kompilatora. Kompilatory biorą cały program i przetwarzają go przed uruchomieniem, a interpreter działa trochę inaczej – wykonuje kod krok po kroku. Dlatego nie tworzy oddzielnego pliku do uruchomienia. Co więcej, mówiąc o analizie składni, to jasne, że interpreter to robi, ale nie jest to jego główny cel. Chodzi o to, żeby wykonać kod od razu, a nie analizować wszystko przed. Te różnice są ważne i pokazują, jak bardzo się różnią kompilatory od interpreterów oraz gdzie każdy z nich ma swoje miejsce.

Pytanie 24

Do czego służy operator spread (...) w JavaScript?

A. Do sprawdzania typu danych
B. Do konwersji liczby na string
C. Do łączenia dwóch różnych typów danych
D. Do rozwinięcia tablicy lub obiektu na poszczególne elementy
Operator spread (...) w JavaScript ma swoje zastosowanie tylko w kontekście rozwoju tablic i obiektów, ale nie jest narzędziem do łączenia różnych typów danych. W rzeczywistości, operator ten nie ma zdolności do łączenia elementów różnych typów, jak na przykład liczby i stringi w jedną strukturę. Takie działania wymagają innych technik, jak konwersja typów lub użycie konkretnego struktura danych, co wprowadza zamieszanie w myśleniu o tym, co operator spread faktycznie robi. Nie ma też zastosowania w kontekście sprawdzania typu danych, co można by pomyśleć, gdyż nie zajmuje się on analizowaniem, czy coś jest liczbą, stringiem czy innym typem. Zamiast tego, operator spread po prostu rozwija tablice lub obiekty. Co więcej, jest nieprecyzyjne twierdzić, że operator ten konwertuje liczby na strings, ponieważ nie ma takiej funkcji. Takie przemyślenie może prowadzić do błędów w kodzie, gdzie programista może oczekiwać, że operator spread będzie działał w sposób, w jaki nie został zaprojektowany. Dlatego ważne jest, aby rozumieć jego prawidłowe zastosowanie, aby unikać nieporozumień i błędów w kodzie.

Pytanie 25

Która z metod zarządzania projektem jest oparta na przyrostach realizowanych w sposób iteracyjny?

A. Model wodospadowy (waterfall)
B. Metodyki zwinne (Agile)
C. Model spiralny
D. Model prototypowy
Metodyki zwinne, czyli Agile, są naprawdę ciekawe, bo stawiają na iteracyjne podejście. To znaczy, że po trochu, krok po kroku realizujemy projekt, a każda iteracja dostarcza nam kawałek działającego produktu. Dzięki temu możemy łatwo dostosować się do zmieniających się wymagań klienta. W moim doświadczeniu, to świetny sposób na rozwijanie aplikacji, bo pozwala nam regularnie testować i wprowadzać zmiany. W Agile najważniejsza jest współpraca z klientem i szybkie dostarczanie wartości, co czyni ten model bardzo efektywnym, zwłaszcza w szybko zmieniających się warunkach.

Pytanie 26

Który z poniższych przypadków stanowi test niefunkcjonalny?

A. Sprawdzenie działania przycisku
B. Testowanie wydajności aplikacji pod dużym obciążeniem
C. Sprawdzenie obsługi formularza rejestracji
D. Weryfikacja poprawności logowania użytkownika
Testowanie wydajności aplikacji pod dużym obciążeniem to przykład testu niefunkcjonalnego. Jego celem jest ocena, jak aplikacja zachowuje się przy dużej liczbie użytkowników lub operacji jednocześnie. Testy te pozwalają na identyfikację wąskich gardeł i optymalizację kodu oraz infrastruktury serwerowej. W ramach testów obciążeniowych analizowane są parametry takie jak czas odpowiedzi, zużycie zasobów (CPU, RAM) oraz stabilność aplikacji w warunkach skrajnego obciążenia. Testowanie wydajności jest kluczowe w aplikacjach webowych, e-commerce oraz systemach o dużej liczbie transakcji, gdzie każdy przestój może generować straty finansowe i negatywnie wpływać na doświadczenia użytkownika.

Pytanie 27

Polecenia wydane w kontekście repozytorium Git, przy założeniu, że folder projektu jest aktualnie wybrany, mają na celu

git init
git add .
git commit -m 'first commit'
A. rozpoczęcie sesji z już istniejącym repozytorium oraz pobranie kodu projektu do lokalnego folderu
B. rozpoczęcie pracy z nowym repozytorium, dodanie oraz zatwierdzenie kodu projektu jako first commit
C. utworzenie kopii istniejącego repozytorium z jedynie tą rewizją, która zostanie zapisana pod nazwą first commit
D. zamknięcie projektu, co spowoduje zarchiwizowanie wszystkich rewizji do lokalnego archiwum pod nazwą first commit
Polecenia git init git add . oraz git commit -m 'first commit' są podstawowymi komendami do rozpoczęcia pracy z nowym repozytorium Gita. git init inicjalizuje puste repozytorium w aktualnym katalogu co tworzy podkatalog .git zawierający wszystkie metadane i historię w wersjonowania. Następnie git add . dodaje wszystkie nowe i zmodyfikowane pliki w bieżącym katalogu do indeksu co oznacza że są one gotowe do zatwierdzenia w repozytorium. Kolejne polecenie git commit -m 'first commit' tworzy pierwszy snapshot aktualnego stanu projektu z przypisaną wiadomością 'first commit' co jest dobrą praktyką sygnalizującą początek nowej historii projektu. Taki proces inicjacji jest standardem w zarządzaniu wersjami w branży IT umożliwiając śledzenie zmian w kodzie ułatwiając współpracę zespołową oraz zapewniając kontrolę nad rozwojem oprogramowania. Ważne jest by w pierwszym commicie umieścić podstawowe działające elementy projektu co stanowi solidną bazę do dalszego rozwoju.

Pytanie 28

W którym przypadku algorytm sortowania bąbelkowego działa z optymalną wydajnością?

A. Dla tablicy z dużą liczbą powtórzeń
B. Dla tablicy losowej
C. Dla tablicy uporządkowanej malejąco
D. Dla tablicy uporządkowanej rosnąco
Algorytm sortowania bąbelkowego działa z optymalną wydajnością w przypadku, gdy tablica jest już posortowana rosnąco. W takiej sytuacji algorytm wykona jedynie jedno przejście przez tablicę, bez konieczności dokonywania zamian, co sprawia, że jego złożoność wynosi O(n). To znacząco zwiększa jego efektywność w przypadku niemal posortowanych danych, choć nadal pozostaje mniej wydajny niż algorytmy takie jak QuickSort czy MergeSort dla dużych zbiorów. Sortowanie bąbelkowe jest jednak łatwe do zrozumienia i implementacji, co czyni je popularnym narzędziem edukacyjnym.

Pytanie 29

Jakie cechy powinien posiadać skuteczny negocjator?

A. dobra reputacja, przekora, porywczość
B. asertywność, pesymizm, buta
C. lojalność, nieśmiałość, uczciwość
D. intuicja, cierpliwość, asertywność
Skuteczny negocjator powinien mieć zestaw cech, które pozwolą mu osiągać kompromisy, rozwiązywać konflikty i dążyć do korzystnych rozwiązań dla obu stron. Intuicja pozwala wyczuć nastroje rozmówcy, wychwycić niewerbalne sygnały i przewidywać możliwe zagrożenia czy okazje jeszcze zanim druga strona je wprost zasygnalizuje. Cierpliwość jest kluczowa, bo proces dochodzenia do porozumienia bywa żmudny, a presja czasu często prowadzi do pochopnych decyzji. Często miałem okazję obserwować, że ci, którzy potrafią zaczekać na ruch drugiej strony, zyskują przewagę negocjacyjną. Asertywność natomiast pozwala jasno wyrażać swoje oczekiwania i granice, bez agresji i bez uległości – to klasyka wśród dobrych praktyk negocjacyjnych, choć nadal niedoceniana w wielu branżach. Asertywność pomaga uniknąć niedomówień i manipulacji, a także buduje szacunek. W praktyce, na sali negocjacyjnej czy nawet przy codziennych rozmowach z klientami, zestaw tych trzech cech daje naprawdę mocną pozycję. Moim zdaniem nie ma jednego uniwersalnego szablonu, ale właśnie intuicja, cierpliwość i asertywność pojawiają się prawie zawsze w podręcznikach czy na szkoleniach dedykowanych profesjonalistom. Warto je ćwiczyć na co dzień, nawet poza pracą, bo to się po prostu opłaca.

Pytanie 30

Co zostanie wyświetlone w konsoli po wykonaniu poniższego kodu?

console.log(0.1 + 0.2 === 0.3);
console.log(0.1 + 0.2);
A. false, 0.3
B. true, 0.3
C. true, 0.30000000000000004
D. false, 0.30000000000000004
Niepoprawne odpowiedzi wynikają z nieporozumienia dotyczącego reprezentacji liczb zmiennoprzecinkowych w JavaScript. Wiele osób ma tendencję do sądzenia, że operacje matematyczne z użyciem liczb dziesiętnych będą prowadziły do oczekiwanych rezultatów. Przykład `0.1 + 0.2`, który wydaje się prosty, w rzeczywistości ujawnia istotne różnice w precyzji. W przeciwieństwie do liczb całkowitych, które są reprezentowane jednoznacznie, liczby zmiennoprzecinkowe mogą wprowadzać błędy zaokrągleń. Gdyby nasze porównanie zwracało `true`, wskazywałoby to na to, że na poziomie binarnym liczby te są identyczne, co jest w przypadku JavaScript nieprawdziwe. Z kolei podanie `0.3` jako wyniku sumy w niektórych odpowiedziach nie uwzględnia tej samej zasady, co sugeruje, że porównanie tych wartości jest właściwe, mimo że nie jest. Warto zrozumieć, że takie błędne wnioski mogą prowadzić do poważnych problemów w bardziej złożonych obliczeniach, zwłaszcza w aplikacjach finansowych, gdzie precyzja jest niezbędna. Dobrym zwyczajem jest korzystanie z odpowiednich metod, które pozwalają na bezpieczne porównywanie wartości zmiennoprzecinkowych, minimalizując ryzyko błędów. Stosując podejście oparte na tolerancji błędu, można uniknąć pułapek związanych z reprezentacją liczb i poprawić dokładność obliczeń.

Pytanie 31

Który z wymienionych sposobów może przyczynić się do optymalizacji kodu źródłowego?

A. Eliminacja nieużywanych zmiennych oraz funkcji
B. Dodanie większej liczby komentarzy w kodzie
C. Zwiększenie ilości instrukcji warunkowych
D. Zamiana zmiennych globalnych na lokalne
Usunięcie nieużywanych zmiennych i funkcji to jedna z najskuteczniejszych metod optymalizacji kodu źródłowego. Nadmiarowe zmienne i niepotrzebne funkcje mogą spowalniać aplikację, zwiększać jej zużycie pamięci i powodować problemy z czytelnością kodu. Ich eliminacja upraszcza kod, zmniejsza ryzyko błędów i poprawia wydajność programu. Oczyszczanie kodu to kluczowy element procesu refaktoryzacji, który pozwala na utrzymanie wysokiej jakości oprogramowania oraz lepszą organizację projektu. Dodatkowo, minimalizacja kodu pomaga w szybszym ładowaniu aplikacji webowych, co ma bezpośredni wpływ na doświadczenie użytkownika (UX) oraz pozycjonowanie w wyszukiwarkach (SEO).

Pytanie 32

W jaki sposób można zmniejszyć liczbę danych zbieranych przez aplikacje mobilne?

A. Nie blokować aplikacjom dostępu do lokalizacji oraz kontaktów
B. Weryfikować i regulować uprawnienia aplikacji w ustawieniach
C. Udostępniać aplikacjom wszystkie niezbędne informacje
D. Używać aplikacji bez sprawdzania ich źródła
Dostosowanie uprawnień aplikacji w ustawieniach swojego telefonu to naprawdę dobry sposób na ograniczenie tego, co aplikacje mogą o nas wiedzieć. Wiele z nich, jak np. te do robienia zdjęć, prosi o dostęp do lokalizacji czy kontaktów, ale nie zawsze jest to potrzebne. Warto co jakiś czas sprawdzić, czy jakieś aplikacje nie mają za dużo uprawnień. Dzięki temu lepiej zabezpieczymy swoją prywatność i zmniejszymy ryzyko, że nasze dane wyciekną. Lepiej też unikać aplikacji z nieznanych źródeł, bo mogą one zbierać więcej informacji, niż byśmy chcieli.

Pytanie 33

Jakie znaczenie ma pojęcie "debugowanie" w kontekście programowania?

A. Wdrażanie aplikacji w środowisku produkcyjnym
B. Wyszukiwanie i usuwanie błędów w kodzie
C. Tworzenie nowych funkcjonalności aplikacji
D. Przygotowywanie dokumentacji kodu
Debugowanie to proces wyszukiwania i eliminowania błędów (bugów) w kodzie źródłowym programu. Polega na analizowaniu działania aplikacji linia po linii, śledzeniu wartości zmiennych, analizie stosu wywołań i wykrywaniu miejsc, w których program działa niezgodnie z oczekiwaniami. Debugowanie umożliwia programistom szybkie odnajdywanie błędów logicznych, składniowych oraz problemów z wydajnością aplikacji. Narzędzia takie jak Visual Studio, PyCharm, IntelliJ IDEA czy Chrome DevTools oferują zaawansowane funkcje debugowania, takie jak punkty przerwań (breakpoints), krokowe wykonywanie kodu i podgląd pamięci. Proces debugowania jest kluczowy w każdym etapie rozwoju oprogramowania, ponieważ znacząco wpływa na stabilność i jakość finalnego produktu.

Pytanie 34

Jednym z rodzajów testów funkcjonalnych, które można przeprowadzić na aplikacji webowej, jest ocena

A. poprawności wyświetlanych elementów aplikacji
B. bezpieczeństwa aplikacji
C. poziomu optymalizacji kodu aplikacji
D. wydajności aplikacji
Bezpieczeństwo aplikacji to sprawa testów penetracyjnych, a nie funkcjonalnych. Wiesz, to trochę jak sprawdzenie, czy można się włamać do systemu, a nie sprawdzanie, czy przyciski działają. Co do optymalizacji kodu, to tam są testy wydajnościowe, ale nie związane bezpośrednio z tym, co testujemy w funkcjonalności. Zresztą, wydajność aplikacji to z kolei obszar testów obciążeniowych i stresowych. W skrócie, chodzi o to, jak system działa pod dużym obciążeniem, a nie jakie ma funkcje.

Pytanie 35

Co zostanie wyświetlone po wykonaniu poniższego kodu w PHP?

$x = 5;
$y = '5';
var_dump($x == $y);
var_dump($x === $y);
A. bool(false) bool(true)
B. bool(true) bool(true)
C. bool(false) bool(false)
D. bool(true) bool(false)
Odpowiedź bool(true) bool(false) jest prawidłowa, ponieważ w PHP porównania używane w tym kodzie różnią się pod względem operatorów. Pierwsze porównanie z użyciem operatora == jest porównaniem luźnym, co oznacza, że PHP dokonuje konwersji typów przed porównaniem. W tym przypadku zmienna $x o wartości 5 (typ integer) jest porównywana z $y, która ma wartość '5' (typ string). Po konwersji typów oba są interpretowane jako liczba 5, więc wynik to true. W drugim porównaniu operator === sprawdza zarówno wartość, jak i typ zmiennych. W tym przypadku $x jest integerem, a $y jest stringiem, więc ich typy się różnią. W związku z tym wynik to false. W praktyce, używanie operatora === jest zalecane, ponieważ pozwala uniknąć niespodzianek związanych z automatyczną konwersją typów, co jest często źródłem błędów w kodzie. Warto mieć to na uwadze przy pisaniu bardziej skomplikowanych skryptów, aby zapewnić, że porównania są jednoznaczne i wiarygodne.

Pytanie 36

Która metoda cyklu życia komponentu w React.js jest wywoływana tuż po zamontowaniu komponentu w DOM?

A. componentDidMount()
B. componentWillUnmount()
C. componentDidUpdate()
D. componentWillMount()
Odpowiedź 'componentDidMount()' jest poprawna, ponieważ jest to metoda cyklu życia komponentu w React, która jest wywoływana tuż po zamontowaniu komponentu w DOM. To oznacza, że w tym momencie komponent jest już dostępny w drzewie DOM i możemy bezpiecznie wykonywać operacje, które wymagają dostępu do elementów DOM. Przykładem zastosowania tej metody może być wykonywanie zapytań do API w celu pobrania danych, które następnie będą renderowane w komponencie. Dobrą praktyką jest umieszczanie logiki inicjalizacyjnej, takiej jak ustawienie stanu komponentu na podstawie danych z API, w tej metodzie, co pozwala na odpowiednie zarządzanie cyklem życia komponentu. Dodatkowo, 'componentDidMount()' jest także idealnym miejscem do dodawania subskrypcji do zewnętrznych źródeł danych, takich jak sockety lub WebSocket, co również wymaga, aby komponent był zamontowany. Warto pamiętać, że metody cyklu życia są kluczowym elementem architektury React i mają istotny wpływ na wydajność oraz czytelność kodu.

Pytanie 37

Jakie z wymienionych narzędzi służy do emulacji mobilnych urządzeń podczas developowania aplikacji?

A. TensorFlow
B. Genymotion
C. Numpy
D. Postman
Genymotion to jedno z najbardziej zaawansowanych narzędzi do emulacji urządzeń mobilnych podczas tworzenia aplikacji na system Android. Umożliwia symulowanie działania aplikacji na różnych urządzeniach i wersjach systemu Android, co pozwala programistom na testowanie kompatybilności i wydajności aplikacji w różnych warunkach. Genymotion oferuje szybkie emulowanie, obsługę GPS, kamery oraz czujników, co czyni go niezwykle przydatnym narzędziem w procesie rozwoju aplikacji mobilnych. Dzięki wsparciu dla integracji z Android Studio, Genymotion jest popularnym wyborem wśród deweloperów tworzących aplikacje na platformę Android.

Pytanie 38

Jaki kod może być związany z treścią wygenerowaną w trakcie działania programu Java?

Exception in thread "main" java.lang.ArithmeticException: / by zero
A. x = 0;
B. x = tablica[6];
C. if (x > y) ...
D. x = x % y;
Kod x = x % y; jest klasycznym przykładem operacji, która może prowadzić do wystąpienia wyjątku ArithmeticException w Javie, szczególnie gdy zmienna y przyjmuje wartość zero. Operator modulo (%) w języku Java nie toleruje dzielenia przez zero – w przeciwieństwie do niektórych innych języków, które mogą zwracać np. NaN lub Infinity, tutaj od razu zostanie zgłoszony wyjątek. Taki wyjątek jest dość powszechny w pracy programisty, zwłaszcza w aplikacjach, gdzie dane wejściowe nie są do końca kontrolowane. Moim zdaniem dobrze jest od razu przyzwyczaić się do zabezpieczania wszystkich operacji dzielenia i modulo poprzez wcześniejsze sprawdzenie wartości dzielnika. Rekomenduje się stosowanie warunków typu if (y != 0) przed wykonaniem takiej instrukcji, co jest zgodne z dobrymi praktykami defensywnego programowania. Dodatkowo, w środowiskach produkcyjnych często otacza się te fragmenty kodu blokiem try-catch, aby elegancko obsłużyć wyjątek i np. wyświetlić użytkownikowi zrozumiały komunikat. Warto pamiętać, że ArithmeticException dziedziczy po RuntimeException, a więc nie musimy jej jawnie obsługiwać, ale nie oznacza to, że powinniśmy ją ignorować – w dobrze napisanym kodzie zawsze należy przewidywać takie sytuacje. Z mojego doświadczenia wynika, że najwięcej błędów z tym związanych pojawia się w aplikacjach przetwarzających dane liczbowe, gdzie nawet niepozorna operacja modulo może „wywalić” cały proces, jeśli nie zostanie odpowiednio zaopiekowana.

Pytanie 39

W jaki sposób można załadować tylko komponent z biblioteki React?

A. import React.Component from 'react'
B. import { Component } from 'react'
C. import Component from 'react'
D. import [ Component ] from 'react'
Wielu osobom, zwłaszcza na początku przygody z Reactem, potrafią się pomylić sposoby importowania poszczególnych fragmentów tej biblioteki. Przykładowo, użycie import React.Component from 'react' jest składniowo niepoprawne w ES6 – nie istnieje możliwość importowania właściwości w ten sposób. To raczej coś, co można by zobaczyć w starszych rozwiązaniach lub błędnych tutorialach. Kolejna propozycja, czyli import [ Component ] from 'react', wygląda jakby ktoś próbował połączyć składnię tablicową z importem nazwanym, co zupełnie nie ma sensu w kontekście ECMAScript Modules. W rzeczywistości, w nawiasach kwadratowych importu się nie zapisuje – do importów nazwanych używamy nawiasów klamrowych, co jest jasno określone w dokumentacji. Z kolei import Component from 'react' to import domyślny, a 'react' nie eksportuje domyślnie samego Component – eksportuje natomiast cały obiekt React jako default. To jest bardzo częsty błąd: niektórzy myślą, że każdy element biblioteki można zaimportować domyślnie, ale akurat Component jest eksportem nazwanym. Moim zdaniem źródłem tych nieporozumień są niedokładne przykłady w sieci albo powierzchowna znajomość standardów ES6. Warto pamiętać, że składnia importów jest ściśle określona i każde odstępstwo kończy się błędem kompilacji albo nieprzewidywalnym działaniem aplikacji. Dobra praktyka to zawsze sprawdzać dokumentację konkretnej biblioteki, bo różne moduły mogą mieć różne rodzaje eksportów i nie każdy sposób importu będzie pasował do wszystkiego. W przypadku Reacta, jeśli zależy Ci tylko na Component, zawsze trzeba używać importu nazwanego w klamrach, bo taki jest oficjalny eksport tego kawałka z biblioteki.

Pytanie 40

Jakie elementy powinny być zawarte w instrukcji dla użytkownika danej aplikacji?

A. Harmonogram realizacji projektu
B. Informacje o narzędziach programistycznych zastosowanych w procesie tworzenia aplikacji
C. Opis instalacji, konfiguracji oraz obsługi oprogramowania
D. Wyjaśnienie struktur danych wykorzystywanych w kodzie
W instrukcji użytkownika aplikacji warto, żeby był opis tego, jak zainstalować, skonfigurować i korzystać z programu. Taka dokumentacja, pisana krok po kroku, pomaga użytkownikowi przejść przez wszystkie etapy, od pobrania oprogramowania, przez instalację, aż po to, żeby w pełni wykorzystać wszystkie funkcje. Dobrze, żeby były tam też info o wymaganiach systemowych, sposobach radzenia sobie z problemami czy aktualizacjach oprogramowania. Moim zdaniem, taka dokładna instrukcja jest mega ważna, bo zmniejsza szanse na napotkanie kłopotów podczas korzystania z aplikacji i sprawia, że łatwiej jest wdrożyć ją w pracy. Jak użytkownicy mają porządnie napisaną instrukcję, to są bardziej zadowoleni i szybciej przyzwyczajają się do nowego narzędzia.