Wyniki egzaminu

Informacje o egzaminie:
  • Zawód: Technik programista
  • Kwalifikacja: INF.04 - Projektowanie, programowanie i testowanie aplikacji
  • Data rozpoczęcia: 2 maja 2026 19:59
  • Data zakończenia: 2 maja 2026 20:06

Egzamin niezdany

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

Wymagane minimum: 20 punktów (50%)

Nowe
Analiza przebiegu egzaminu- sprawdź jak rozwiązywałeś pytania
Udostępnij swój wynik
Szczegółowe wyniki:
Pytanie 1

Który z wymienionych algorytmów najczęściej wykorzystuje rekurencję?

A. Obliczanie liczb Fibonacciego
B. Wyszukiwanie liniowe
C. Sortowanie przez wstawianie
D. Sortowanie bąbelkowe
Sortowanie bąbelkowe to algorytm iteracyjny, który działa na zasadzie porównywania sąsiednich elementów tablicy i zamiany ich miejscami. Nie korzysta on z rekurencji, ponieważ jego struktura nie wymaga podziału problemu na mniejsze części. Wyszukiwanie liniowe to prosty algorytm iteracyjny, który przeszukuje kolejne elementy tablicy i nie wykorzystuje rekurencji. Sortowanie przez wstawianie również jest algorytmem iteracyjnym, który działa na zasadzie wstawiania kolejnych elementów w odpowiednie miejsca i nie wymaga wywoływania funkcji rekurencyjnych.

Pytanie 2

Co oznacza termin 'hoisting' w JavaScript?

A. Metoda ładowania skryptów z zewnętrznych źródeł
B. Optymalizacja kodu wykonywana przez silnik JavaScript
C. Technika zarządzania pamięcią polegająca na usuwaniu nieużywanych obiektów
D. Przenoszenie deklaracji zmiennych i funkcji na górę ich zakresu podczas fazy kompilacji
Nieprawidłowe odpowiedzi na to pytanie mogą wynikać z nieporozumienia na temat podstawowych zasad działania JavaScript i jego mechanizmu wykonawczego. Optymalizacja kodu przez silnik JavaScript to proces, który ma miejsce w tle, ale nie odnosi się bezpośrednio do hoistingu, ponieważ ten termin dotyczy przenoszenia deklaracji na górę zakresu. Kolejna koncepcja zarządzania pamięcią, polegająca na usuwaniu nieużywanych obiektów, odnosi się do garbage collection, a nie do hoistingu. Garbage collection jest procesem, w którym silnik JavaScript automatycznie zwalnia pamięć zajmowaną przez obiekty, do których już nie ma odniesienia, co jest niezwiązane z mechanizmem przenoszenia deklaracji. Metoda ładowania skryptów z zewnętrznych źródeł dotyczy sposobu, w jaki JavaScript może być integrowany z HTML, ale nie ma związku z hoistingiem. Często mylone są te koncepcje ze względu na złożoność JavaScript i jego asynchroniczny charakter. Kluczowe w pracy z JavaScript jest zrozumienie, jak różne mechanizmy, takie jak hoisting, wpływają na organizację kodu i mogą prowadzić do błędów, jeśli nie są prawidłowo stosowane. Programiści powinni być świadomi, że niewłaściwe użycie hoistingu może skutkować trudnymi do wykrycia błędami, co podkreśla wagę dobrej praktyki w zakresie strukturyzacji kodu.

Pytanie 3

Jakie narzędzie jest wykorzystywane do zgłaszania błędów w projektach IT?

A. Git
B. Photoshop
C. Blender
D. JIRA
JIRA to jedno z najczęściej wykorzystywanych narzędzi do zarządzania projektami i raportowania błędów w projektach informatycznych. JIRA umożliwia śledzenie błędów, zarządzanie zadaniami oraz efektywne monitorowanie postępów prac nad projektem. Dzięki integracji z innymi narzędziami, takimi jak Confluence czy Bitbucket, JIRA stanowi kompleksowe rozwiązanie wspierające zespoły deweloperskie. Raportowanie błędów w JIRA pozwala na łatwe przypisywanie ich do odpowiednich członków zespołu, dodawanie załączników i komentarzy oraz monitorowanie statusu danego problemu, co usprawnia proces zarządzania jakością oprogramowania.

Pytanie 4

Który z wymienionych dysków oferuje najszybszy dostęp do danych?

A. SSD SATA III, prędkość odczytu do 550 MB/s
B. HDD 5400 RPM, SATA II, 32 MB Cache
C. SSD NVMe PCIe 3.0, prędkość odczytu do 3500 MB/s
D. HDD 7200 RPM, SATA III, 64 MB Cache
Odpowiedź wskazująca na SSD NVMe PCIe 3.0 jako najszybszy dysk do odczytu danych jest zgodna z obecnymi standardami technologii przechowywania. Dyski SSD (Solid State Drive) korzystają z pamięci flash, co pozwala na znacznie szybszy dostęp do danych w porównaniu do tradycyjnych dysków HDD (Hard Disk Drive), które działają na zasadzie mechanicznych ruchomych elementów. Dyski NVMe (Non-Volatile Memory Express) są szczególnie wydajne, ponieważ wykorzystują interfejs PCIe (Peripheral Component Interconnect Express), co umożliwia znacznie wyższe prędkości transferu danych. W przypadku SSD NVMe PCIe 3.0, prędkość odczytu może osiągać do 3500 MB/s, co jest znaczącą różnicą w porównaniu do prędkości odczytu w dyskach HDD i SSD SATA. Przykładowo, w zastosowaniach takich jak edycja wideo, renderowanie grafiki 3D czy gry komputerowe, wyższa prędkość odczytu przekłada się na szybsze ładowanie danych i lepszą wydajność systemu. Standardy SATA III dla HDD również mają swoje ograniczenia, ponieważ maksymalna teoretyczna prędkość transferu wynosi 6 Gb/s, co jest dalekie od osiągów oferowanych przez NVMe. Dlatego SSD NVMe PCIe 3.0 jest zdecydowanym liderem w kontekście wydajności odczytu danych w porównaniu do pozostałych opcji.

Pytanie 5

Przedstawiony fragment dotyczy funkcji resize w języku C++. Ta funkcja obniży długość elementu string, gdy wartość parametru

Resize string
Resizes the string to a length of n characters.

If n is smaller than the current string length, the current value is shortened to its first n character, removing the characters beyond the nth.

If n is greater than the current string length, the current content is extended by inserting at the end as many characters as needed to reach a size of n. If c is specified, the new elements are initialized as copies of c; otherwise, they are value-initialized characters (null characters).

Parameters
n
New string length, expressed in number of characters.
size_t is an unsigned integral type (the same as member type string::size_type).
c
Character used to fill the new character space added to the string (in case the string is expanded).
Źródło: http://www.cplusplus.com/reference/string/string/resize/
A. n jest większa od aktualnej długości łańcucha
B. c jest większa od aktualnej długości łańcucha
C. c jest mniejsza od aktualnej długości łańcucha
D. n jest mniejsza od aktualnej długości łańcucha
To jest dokładnie to, o co chodzi w funkcji resize dla std::string w C++. Jeśli podany parametr n jest mniejszy od aktualnej długości łańcucha, to obcinamy stringa do tych właśnie n znaków – reszta znika bezpowrotnie. Moim zdaniem to bardzo wygodne, bo nie trzeba ręcznie wycinać fragmentu czy bawić się w operacje na podłańcuchach. Praktycznie rzecz biorąc, można dzięki temu szybko skrócić dane wejściowe, np. gdy pobieramy z pliku długi tekst, a potrzebujemy tylko jego fragment do dalszego przetwarzania. W branży często się to przydaje – na przykład ograniczając długość nicku użytkownika do określonej liczby znaków lub przytrzymując długość serializowanych danych w protokołach sieciowych. Resize działa wprost i zgodnie ze standardem C++, usuwając znaki od indeksu n wzwyż. Co ciekawe, metoda nie tylko skraca, ale też rozszerza string – wtedy wypełnia go nowymi znakami (np. 'x' czy znakiem pustym), ale to właśnie skracanie jest często pomijane przez początkujących, a jest naprawdę przydatne. No i trzeba pamiętać, że oryginalne znaki spoza zakresu po prostu znikają – nie ma żadnych ostrzeżeń. Z mojego doświadczenia to jedna z tych funkcji, do których z czasem nabiera się szacunku – bo ułatwia życie na co dzień przy operacjach na łańcuchach znaków.

Pytanie 6

Który z poniższych opisów najlepiej charakteryzuje system informatyczny?

A. Sieć komputerowa, która umożliwia komunikację pomiędzy użytkownikami
B. Zbiór urządzeń technicznych używanych w pracy biurowej
C. Oprogramowanie wspierające jedynie zarządzanie danymi osobowymi
D. Zespół ludzi, procedur, oprogramowania i sprzętu służący do przetwarzania danych
Pierwsza z niepoprawnych odpowiedzi definiuje system informatyczny jedynie jako zespół urządzeń technicznych używanych do pracy biurowej. Tego rodzaju podejście jest zbyt wąskie i nie obejmuje istotnych elementów, takich jak ludzie i procedury, które są kluczowe w kontekście przetwarzania danych. Oprogramowanie i procedury są równie ważne, ponieważ stanowią podstawę dla skutecznego działania systemu informatycznego. Kolejna odpowiedź ogranicza się wyłącznie do oprogramowania wspierającego zarządzanie danymi osobowymi, co również jest nieprawidłowe. Systemy informatyczne są zdecydowanie bardziej złożone i obejmują szereg funkcjonalności, takich jak zarządzanie procesami, analizę biznesową czy integrację z innymi systemami. Ostatnia odpowiedź odnosi się do sieci komputerowej, co jest tylko jednym z komponentów systemu informatycznego. Sieć komputerowa może być wykorzystywana do komunikacji, ale nie definiuje całego systemu, ponieważ brak w niej odniesienia do ludzi, procedur i oprogramowania, które są kluczowe dla pełnego zrozumienia roli systemu informatycznego w organizacji.

Pytanie 7

Zademonstrowana pętla wykorzystuje obiekt random do:

var random = new Random();
String pulaZnakow = "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ";
int dlPuli = pulaZnakow.Length - 1;
char znak;
string wynik = "";

for (int i = 0; i < 8; i++) {
    znak = pulaZnakow[random.Next(0, dlPuli)];
    wynik += znak;
}
A. jednorazowego wylosowania znaku z określonego zestawu znaków
B. wielokrotnego generowania liczby, aby stworzyć ciąg z liczb pseudolosowych
C. stworzenia losowego napisu o długości 8 znaków składającego się z liter
D. uzupełniania tablicy danymi w postaci liczb pseudolosowych
Wiele osób, widząc fragmenty z random i pętlą, instynktownie myśli o generowaniu ciągów liczb pseudolosowych lub o uzupełnianiu tablic danymi liczbowymi – i to jest bardzo częsty błąd w interpretacji tego typu kodu. Problem polega na tym, że tutaj nie chodzi o liczby, tylko o znaki, a dokładniej: losowe litery z określonego zbioru. Kod nie tworzy tablicy liczb, nie używa random raz na całą pętlę ani nie generuje pojedynczego znaku. Pętla for jasno pokazuje, że proces losowania zachodzi kilka razy (osiem), a każdorazowo wybierany jest indeks, który służy do pobrania znaku z puli znaków. Moim zdaniem, spora część nieporozumień bierze się z niedoczytania, że random.Next nie zwraca znaku, tylko liczbę, którą następnie wykorzystuje się jako indeks do stringa – to takie klasyczne pomylenie poziomów abstrakcji. Także nie jest to uzupełnianie tablicy, bo 'wynik' to po prostu string, nie tablica czy lista. Kolejną pułapką jest założenie, że losujemy tylko jeden znak, a przecież pętla jest powtarzana 8 razy – to podkreśla, że końcowym efektem jest cały napis, nie pojedynczy znak. Warto mieć na uwadze, że w praktyce takie rozwiązanie stosuje się właśnie wtedy, gdy chcemy złożyć nowy losowy string o określonej długości, a nie pojedynczą wartość czy zestaw liczb. Wreszcie, ograniczenie się w odpowiedzi do liczby pseudolosowej czy tablicy to typowy przykład nadinterpretacji funkcji random lub nieuwzględnienia pełnego zakresu operacji na stringach, które są coraz częstsze w nowoczesnych aplikacjach. Po prostu – sednem tego kodu jest generowanie konkretnego losowego napisu, a nie robienie operacji liczbowych.

Pytanie 8

Który fragment kodu ilustruje zastosowanie rekurencji?

Blok 1:
int fn(int a) {
  if(a==1) return 1;
  return fn(a-1)+2;
}
Blok 2:
int fn(int a) {
  if(a==1) return 1;
  return (a-1)+2;
}
Blok 3:
int fn(int a) {
  if(a==1) return 1;
  return fun(a-1)+2;
}
Blok 4:
int fn(int a) {
  if(a==1) return 1;
  return 2;
}
A. Blok 3
B. Blok 4
C. Blok 1
D. Blok 2

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Blok 1 to typowy przykład rekurencji, czyli sytuacji, gdy funkcja wywołuje samą siebie z innym argumentem (tutaj fn(a-1)). Takie podejście pojawia się w programowaniu bardzo często, szczególnie przy rozwiązywaniu problemów, gdzie rozwiązanie można rozbić na mniejsze, podobne zadania. W Bloku 1 mamy tzw. przypadek bazowy (if(a==1) return 1), czyli moment, w którym dalsza rekurencja się zatrzymuje – bez tego każdy program rekurencyjny skończyłby się przepełnieniem stosu i błędem. Moim zdaniem, dobrze rozumiana rekurencja to jedna z podstaw algorytmiki – spotyka się ją choćby przy obliczaniu silni, ciągu Fibonacciego czy w algorytmach przeszukiwania struktur drzewiastych, np. w operacjach na drzewach binarnych. W praktyce branżowej warto wiedzieć, że rekurencja bywa bardzo elegancka i skraca kod, ale trzeba ją stosować z głową – łatwo przekroczyć limity stosu przy zbyt głębokim wywołaniu albo zapomnieć o przypadku bazowym, przez co program nie kończy działania. W standardach wielu języków (np. C, Java) rekurencja jest narzędziem jak każde inne, ale zawsze powinna być projektowana z myślą o czytelności i efektywności rozwiązania. Często spotykam się z sytuacją, gdzie początkujący próbują wszystko rozwiązywać rekurencyjnie, a to nie zawsze jest optymalne – niektóre problemy lepiej rozwiązać iteracyjnie, choćby ze względu na wydajność. W tym konkretnym kodzie zastosowanie rekurencji jest klasyczne i poprawne, więc zdecydowanie jest to dobry wzór do nauki.

Pytanie 9

Wykorzystanie typu DECIMAL w MySQL wymaga wcześniejszego określenia długości (liczby cyfr) przed oraz po przecinku. Jak należy to zapisać?

A. zmiennoprzecinkowy
B. łańcuchowy
C. logiczny
D. stałoprzecinkowy

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Typ DECIMAL w języku MySQL jest używany do przechowywania liczb dziesiętnych z określoną precyzją. Przy definiowaniu tego typu danych wymagane jest określenie dwóch głównych parametrów: długości całkowitej liczby, czyli liczby cyfr przed przecinkiem, oraz długości części dziesiętnej, czyli liczby cyfr po przecinku. Taki zapis ma postać DECIMAL(M, D), gdzie M to maksymalna liczba cyfr, a D to liczba cyfr po przecinku. Przykład zastosowania to: DECIMAL(10, 2), co oznacza, że liczba może mieć maksymalnie 10 cyfr, z czego 2 cyfry będą po przecinku. Typ DECIMAL jest szczególnie przydatny w aplikacjach finansowych, gdzie precyzja obliczeń jest kluczowa, aby uniknąć błędów zaokrągleń, które mogą występować w przypadku typów zmiennoprzecinkowych. Standardy dotyczące typów danych w SQL, takie jak SQL:2008, również uznają znaczenie precyzyjnych reprezentacji liczbowych, co sprawia, że DECIMAL jest preferowany w wielu zastosowaniach. Warto dodać, że MySQL pozwala na elastyczność w definiowaniu długości, co umożliwia optymalne dostosowanie do specyficznych wymagań aplikacji.

Pytanie 10

Jak określa się proces, w trakcie którego klasa przejmuje właściwości innej klasy w programowaniu obiektowym?

A. Abstrakcja
B. Hermetyzacja
C. Polimorfizm
D. Dziedziczenie

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Dziedziczenie to kluczowa cecha programowania obiektowego (OOP), która pozwala jednej klasie (klasie pochodnej) przejmować cechy i zachowania innej klasy (klasy bazowej). Dzięki dziedziczeniu można wielokrotnie wykorzystywać kod, co prowadzi do większej modularności i zmniejszenia redundancji. Dziedziczenie umożliwia rozszerzanie funkcjonalności klas bazowych poprzez dodawanie nowych metod lub modyfikowanie istniejących, bez konieczności ingerencji w oryginalny kod. Przykład w C++: `class Pojazd { ... }; class Samochod : public Pojazd { ... };` – `Samochod` dziedziczy wszystkie publiczne i chronione (protected) elementy klasy `Pojazd`.

Pytanie 11

Jakie jest zastosowanie metody fetch() w JavaScript?

A. Sortowanie kolekcji obiektów
B. Filtrowanie elementów tablicy
C. Pobieranie zasobów z sieci asynchronicznie
D. Manipulacja elementami DOM

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Metoda fetch() w JavaScript jest kluczowym narzędziem do asynchronicznego pobierania zasobów z sieci. Umożliwia ona wykonywanie zapytań HTTP do serwerów w sposób, który nie blokuje głównego wątku aplikacji, co jest istotne w kontekście zapewnienia płynności działania aplikacji webowych. Użycie fetch() pozwala na pobieranie różnych typów danych, takich jak JSON, tekst, czy pliki binarne. Przykład zastosowania fetch() może wyglądać następująco: fetch('https://api.example.com/data') .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => console.log(data)); W tym przykładzie, po nawiązaniu połączenia z API, sprawdzamy, czy odpowiedź jest poprawna, a następnie przetwarzamy dane w formacie JSON. Ponadto, fetch() wspiera nowoczesne praktyki, takie jak obsługa promes (Promises) oraz async/await, co upraszcza kod i poprawia jego czytelność. Użycie tej metody jest zgodne z aktualnymi standardami webowymi, co czyni ją preferowanym rozwiązaniem w nowoczesnym programowaniu JavaScript.

Pytanie 12

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

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
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 13

W klasie pracownik zdefiniowano następujące metody:

pracownik()   { ... }
static void wypisz()   { ... }
int operator== (const pracownik &prac) { ... }
~pracownik()   { ... }
Która z nich jest odpowiednia do dodania elementu diagnostycznego o treści:
cout << "Obiekt został usunięty";
Ilustracja do pytania
A. wypisz
B. pracownik
C. ~pracownik
D. operator==

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Destruktor to specjalna metoda w języku C++ oznaczona tyldą przed nazwą klasy która jest wywoływana automatycznie w momencie usuwania obiektu danego typu z pamięci. Dlatego dodanie elementu diagnostycznego cout<<Obiekt został usunięty; jest najbardziej sensowne w destruktorze ponieważ pozwala na śledzenie momentu w którym obiekt przestaje istnieć. Takie podejście jest zgodne z dobrymi praktykami programistycznymi ponieważ pomaga w debugowaniu i zarządzaniu zasobami w programie. Warto zauważyć że destruktory są kluczowe w kontekście zarządzania pamięcią szczególnie gdy klasa dynamicznie alokuje zasoby. Wówczas destruktor powinien zawierać kod zwalniający te zasoby aby uniknąć wycieków pamięci. Dodawanie diagnostycznych komunikatów może pomóc programistom w identyfikacji potencjalnych błędów związanych z zarządzaniem cyklem życia obiektów i poprawić ogólną stabilność i czytelność kodu. Praktyka ta jest szczególnie ważna w dużych projektach gdzie ręczne śledzenie wszystkich obiektów byłoby trudne i czasochłonne. Warto stosować taką diagnostykę w połączeniu z nowoczesnymi narzędziami do profilowania i analizy pamięci co zwiększa efektywność procesu programistycznego.

Pytanie 14

Na schemacie widoczny jest fragment diagramu blokowego pewnego algorytmu. Ile razy zostanie zweryfikowany warunek n<7?

Ilustracja do pytania
A. 7
B. 5
C. 8
D. 6

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Warunek 'n < 7' będzie sprawdzany dokładnie 6 razy. To dlatego, że w klasycznej pętli for czy while liczba powtórzeń jest zawsze o jeden mniejsza niż wartość graniczna. Jak widzisz, w takich schematach liczba porównań idzie w parze z liczbą iteracji, a pętla zatrzymuje się, jak tylko warunek zostanie spełniony.

Pytanie 15

Jaką cechą charakteryzuje się sieć asynchroniczna?

A. Jest bardziej niezawodna od sieci synchronicznej
B. Dane są przesyłane w sposób nieciągły, bez synchronizacji zegarów
C. Wymaga synchronizacji zegarów
D. Dane są przesyłane jedynie w określonych przedziałach czasowych

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Sieci asynchroniczne to rodzaj systemów komunikacyjnych, w których dane są przesyłane w sposób nieciągły, co oznacza, że nie wymagają one synchronizacji zegarów pomiędzy urządzeniami. W takich sieciach, każda jednostka przesyła dane w dowolnym momencie, co zwiększa elastyczność i efektywność komunikacji. Przykładem zastosowania sieci asynchronicznych są systemy oparte na protokołach, takich jak UART (Universal Asynchronous Receiver-Transmitter), które są powszechnie używane w mikrokomputerach oraz różnych urządzeniach elektronicznych. W kontekście standardów, sieci asynchroniczne są często stosowane w komunikacji szeregowej, gdzie dane są przesyłane bez ustalonych ram czasowych, co pozwala na redukcję opóźnień i zwiększenie przepustowości. W praktyce, taki model komunikacji jest idealny w sytuacjach, gdzie ciągłość przesyłu danych nie jest kluczowa, jak w przypadku transmisji danych z czujników czy urządzeń IoT, gdzie urządzenia mogą nadawać dane, gdy są gotowe, a nie w ustalonych interwałach czasowych.

Pytanie 16

Który operator w JavaScript sprawdza zarówno równość wartości jak i typu danych?

A. ==
B. !=
C. =
D. ===

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Operator === w JavaScript jest powszechnie określany jako operator ścisłej równości. Jego główną zaletą jest to, że porównuje zarówno wartość, jak i typ danych dwóch operandów. Oznacza to, że jeśli porównujesz dwie zmienne, a jedna z nich jest liczbą, a druga łańcuchem znaków, operator ten zwróci false, ponieważ typy są różne. Dla przykładu, porównując 5 === '5', wynik będzie false, podczas gdy w przypadku operatora == wynik byłby true, co może prowadzić do niezamierzonych błędów w logice programu. Użycie operatora === jest zgodne z najlepszymi praktykami programistycznymi, ponieważ unika potencjalnych problemów związanych z automatycznym rzutowaniem typów. W praktyce, zawsze warto stosować operator ścisłej równości, aby zapewnić większą przewidywalność kodu oraz uniknąć trudnych do zdiagnozowania błędów. Dlatego operator === jest preferowany w nowoczesnym programowaniu w JavaScript.

Pytanie 17

Jakie znaczenie ma określenie "klasa zaprzyjaźniona" w kontekście programowania obiektowego?

A. Klasa, która nie ma możliwości zawierania metod statycznych
B. Klasa, która może być dziedziczona przez inne klasy
C. Klasa, w której wszystkie komponenty są publiczne
D. Klasa, która ma dostęp do prywatnych i chronionych elementów innej klasy

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Klasa zaprzyjaźniona (ang. 'friend class') to klasa, która ma dostęp do prywatnych i chronionych składowych innej klasy, dzięki specjalnej deklaracji 'friend' wewnątrz tej klasy. Jest to kluczowe narzędzie w programowaniu obiektowym, które umożliwia ściślejszą współpracę między klasami, jednocześnie zapewniając hermetyzację kodu w miejscach, gdzie jest to wymagane. Używanie klas zaprzyjaźnionych umożliwia bardziej efektywne zarządzanie zależnościami między klasami, co jest istotne w dużych projektach programistycznych. Klasy zaprzyjaźnione są często stosowane w bibliotekach standardowych i frameworkach, pozwalając na eleganckie rozwiązania problemów związanych z ukrywaniem implementacji i udostępnianiem tylko niezbędnych fragmentów kodu innym komponentom systemu.

Pytanie 18

W programowaniu obiektowym odpowiednikami zmiennych oraz funkcji w programowaniu strukturalnym są

A. pola i kwalifikatory dostępu
B. hermetyzacja oraz dziedziczenie
C. pola i metody
D. metody statyczne i abstrakcyjne

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Pola i metody to absolutna podstawa, jeśli chodzi o programowanie obiektowe. Właśnie one są najbliższym odpowiednikiem zmiennych i funkcji z podejścia strukturalnego. Moim zdaniem, gdy uczysz się OOP, warto od razu wyłapać tę analogię – pola (czyli inaczej: atrybuty, właściwości, fields) przechowują stan obiektu, a metody (czyli funkcje w klasie) definiują, co obiekt potrafi zrobić. Przykład z życia: klasa Samochód ma pole kolor, które opisuje jego cechę oraz metodę jedź(), która realizuje jakąś akcję. W praktyce programiści bardzo często modelują swoje klasy tak, aby pola były prywatne (zgodnie z zasadą hermetyzacji), a dostęp do nich zapewniały metody publiczne – tzw. gettery i settery. Standardy branżowe, np. JavaBeans w Javie czy konwencje C#, też polegają na tym, że pola odzwierciedlają dane, a metody operacje na tych danych. Z mojego doświadczenia wynika, że rozumienie tej relacji ułatwia zarówno pisanie czytelnego kodu, jak i jego dalsze rozwijanie. To właśnie dzięki rozdzieleniu na pola i metody klasy mogą odwzorowywać obiekty z realnego świata i ich zachowania, co jest głównym celem programowania obiektowego.

Pytanie 19

Co oznacza pojęcie TDD w kontekście programowania?

A. Technical Design Document - dokumentacja techniczna projektu
B. Task Deployment Diagram - schemat wdrażania zadań w projekcie
C. Test-Driven Development - praktyka pisania testów przed implementacją kodu
D. Type Definition Document - dokumentacja typów danych w aplikacji

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Test-Driven Development (TDD) to metodologia programowania, w której proces tworzenia kodu zaczyna się od pisania testów. TDD polega na cyklicznym podejściu do rozwoju oprogramowania, w którym najpierw definiujemy, jakie funkcjonalności będzie miał nasz kod, a następnie implementujemy tylko te elementy, które są niezbędne do przejścia wcześniej napisanych testów. Dzięki temu, deweloperzy mają możliwość natychmiastowego sprawdzenia poprawności swojego kodu, co sprzyja eliminacji błędów na wczesnym etapie. Przykład zastosowania TDD można zobaczyć w tworzeniu aplikacji webowych, gdzie programista pisze testy jednostkowe dla nowych funkcji, a następnie implementuje te funkcje, poprawiając kod tylko w przypadku, gdy testy nie przechodzą. Takie podejście pozwala na zwiększenie jakości oprogramowania oraz jego łatwiejszą refaktoryzację. Warto również zauważyć, że TDD jest zgodne z praktykami Agile i Continuous Integration, co pozwala na efektywniejsze zarządzanie projektem i dostosowywanie go do wymagań zmieniającego się rynku.

Pytanie 20

Przedstawiono funkcjonalnie równoważne fragmenty kodu aplikacji Angular oraz React.js.

Angular
submit(f) {
    console.log(f.value); 
}
<form #f="ngForm" (ngSubmit)="submit(f)">
    <input ngModel name="tytul" type="text" id="tytul">
    <button>Dodaj</button>
</form>
React
handleSubmit = e => {
    e.preventDefault();
    console.log('tytul: ' + e.currentTarget.tytul.value);
};
render() {
    return (
        <div>
            <form onSubmit={this.handleSubmit}>
                <input type="text" id="tytul" />
                <button>Dodaj</button>
            </form>
        </div>
    );
}
A. funkcję, która zapisuje do zmiennych f lub e dane z pola <input> formularza
B. wyświetlanie w konsoli przeglądarki danych pobranych z pól formularza w czasie rzeczywistym, gdy użytkownik je wypełnia
C. obsługę zdarzenia przesłania formularza
D. funkcję, która wypełnia dane w formularzu podczas jego inicjalizacji

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Oba fragmenty kodu, zarówno w Angularze jak i React.js, pokazują obsługę zdarzenia zatwierdzenia formularza. W Angularze zdarzenie submit jest obsługiwane poprzez przypisanie funkcji submit do atrybutu ngSubmit. Ta funkcja otrzymuje jako argument obiekt formularza, a następnie wypisuje jego wartość w konsoli za pomocą f.value. Jest to zgodne z dobrymi praktykami Angulara, gdzie korzysta się z dwukierunkowego wiązania danych i obiektu formularza do zarządzania danymi wejściowymi. W przypadku React.js funkcja handleSubmit jest przypisywana do zdarzenia onSubmit formularza. W tej funkcji nie tylko logujemy dane wejściowe, ale również używamy e.preventDefault(), aby zapobiec domyślnemu działaniu formularza, co jest standardową praktyką w React.js, gdzie zarządzamy stanem komponentów samodzielnie. W obu przypadkach kluczową czynnością jest reakcja na zdarzenie wysłania formularza, co pozwala na dalsze przetwarzanie danych wejściowych, walidację lub wysyłanie ich do serwera.

Pytanie 21

Które z poniższych nie jest frameworkiem JavaScript?

A. Django
B. React
C. Vue.js
D. Angular

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Django to framework zaprojektowany do budowy aplikacji webowych w języku Python, a zatem nie jest związany z JavaScriptem. Jego głównym celem jest uproszczenie procesu tworzenia w pełni funkcjonalnych aplikacji, co osiąga poprzez zestaw gotowych komponentów, takich jak system zarządzania bazą danych, mechanizmy autoryzacji oraz łatwe zarządzanie szablonami. Przykładem zastosowania Django może być rozwój serwisów e-commerce, gdzie framework ten wspiera szybkie i bezpieczne tworzenie skomplikowanej logiki aplikacji oraz zapewnia możliwość łatwego skalowania. Użycie Django w projektach, w których istotne są bezpieczeństwo i szybkość developmentu, stało się standardem w branży. W kontekście rozwoju aplikacji webowych, znajomość różnych frameworków, w tym Django, jest kluczowa dla programistów, którzy chcą być elastyczni i efektywni w tworzeniu rozwiązań backendowych."

Pytanie 22

Jakie aspekty powinny być brane pod uwagę przy tworzeniu zestawów danych?

A. Metoda alokacji pamięci dla danych
B. Typ zastosowanego kompilatora
C. Ilość linii kodu programu
D. Narzędzia do analizy błędów

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Sposób alokacji pamięci dla danych to kluczowy element projektowania zestawów danych, ponieważ wpływa na wydajność i efektywność programu. Dynamiczna alokacja pamięci pozwala na tworzenie struktur, których rozmiar jest zmienny i dostosowuje się w trakcie działania aplikacji. Dzięki temu programiści mogą optymalnie zarządzać zasobami systemowymi, unikając marnowania pamięci lub jej niedoboru. Wybór odpowiedniej metody alokacji, np. stosowanie wskaźników, dynamicznych tablic lub struktur danych takich jak lista czy mapa, pozwala na budowanie bardziej skalowalnych i elastycznych aplikacji.

Pytanie 23

Szablon MojaTablica oferuje funkcjonalność tablicy z indeksami oraz elementami różnych typów. W oparciu o pokazany kod, który wykorzystuje ten szablon do tworzenia tablicy asocjacyjnej, wskaż definicję, która posługuje się szablonem do zainicjowania tablicy, gdzie indeksami są liczby całkowite, a elementami są napisy?

MojaTablica tab1 = new MojaTablica<string, string>();
tab1["good"] = "dobry";
A. int tab2 = new MojaTablica()
B. int tab2[] = new MojaTablica()
C. MojaTablica tab2 = MOjaTablica()
D. MojaTablica tab2 = new MojaTablica()

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Aby utworzyć tablicę asocjacyjną w oparciu o szablon, należy zainicjalizować ją przy użyciu właściwej składni: MojaTablica tab2 = new MojaTablica();. Tego typu deklaracja tworzy obiekt tablicy, gdzie klucze są liczbami całkowitymi, a wartości przechowywane w tablicy to napisy. Tablice asocjacyjne to potężne narzędzie pozwalające na szybkie wyszukiwanie i przechowywanie danych, bazujące na unikalnych kluczach, co umożliwia efektywne zarządzanie złożonymi strukturami danych.

Pytanie 24

Jakie kwestie związane z percepcją są uwzględnione w rekomendacjach standardu WCAG 2.0?

A. zapewnienia odpowiedniego czasu na zapoznanie się i przetworzenie informacji
B. umożliwienia interakcji między elementami użytkownika za pomocą klawiatury
C. prezentacji elementów interfejsu użytkownika
D. jasności i dokładności w dostarczonych treściach na stronie

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Prezentacja elementów interfejsu użytkownika to kluczowy aspekt rekomendacji WCAG 2.0 związanych z percepcją. Standard ten mocno akcentuje, by każdy użytkownik, niezależnie od swoich możliwości, miał szansę prawidłowo odbierać to, co się wyświetla na stronie. Jeśli coś jest przedstawione tylko kolorem albo opiera się wyłącznie na bodźcach wizualnych, to osoby niewidome albo z zaburzeniami wzroku po prostu nie będą w stanie tego odebrać. W praktyce chodzi o takie rzeczy jak odpowiedni kontrast tekstu do tła, jasność przekazu ikon, czy czytelność nawigacji, nawet jeśli ktoś korzysta z czytnika ekranu. Moim zdaniem, naprawdę dobrym przykładem są formularze: jeżeli pole błędnie wypełnione jest tylko podświetlone na czerwono, to nie każdy to zauważy, więc trzeba też dodać np. komunikat tekstowy. Dobrze, jeśli projektant myśli o wszystkich użytkownikach, nie tylko o tych, którzy widzą i słyszą idealnie. WCAG podpowiada, by nie polegać na samych kolorach, stosować czytelne czcionki, zapewniać jasną strukturę nagłówków – wszystko po to, by każdy mógł się połapać w tym, co widzi na stronie. Z mojego doświadczenia wynika, że uwzględnienie tych zasad nie tylko poprawia dostępność, ale ogólnie podnosi jakość user experience. Warto o tym pamiętać nawet przy najprostszych projektach.

Pytanie 25

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. utworzenie kopii istniejącego repozytorium z jedynie tą rewizją, która zostanie zapisana pod nazwą first commit
B. zamknięcie projektu, co spowoduje zarchiwizowanie wszystkich rewizji do lokalnego archiwum pod nazwą first commit
C. rozpoczęcie sesji z już istniejącym repozytorium oraz pobranie kodu projektu do lokalnego folderu
D. rozpoczęcie pracy z nowym repozytorium, dodanie oraz zatwierdzenie kodu projektu jako first commit

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
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 26

Co to jest event bubbling w JavaScript?

A. Technika optymalizacji wydajności zdarzeń na stronie
B. Metoda zarządzania kolejką zdarzeń w aplikacjach asynchronicznych
C. Proces, w którym zdarzenie zaczyna się od najbardziej szczegółowego elementu i propaguje w górę hierarchii DOM
D. System powiadomień o błędach w konsoli JavaScript

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Event bubbling to kluczowy mechanizm w modelu zdarzeń JavaScript, który polega na tym, że gdy zdarzenie zostaje wywołane na danym elemencie DOM, propaguje się ono w górę hierarchii DOM, zaczynając od najniższego elementu (czyli elementu, który bezpośrednio wywołuje zdarzenie) i kierując się ku elementom nadrzędnym. To podejście umożliwia efektywne zarządzanie zdarzeniami, gdyż pozwala na przypisanie pojedynczej funkcji obsługi zdarzeń do elementu nadrzędnego, zamiast do każdego z podrzędnych elementów. Na przykład, jeśli mamy listę elementów <li> w <ul>, możemy ustawić jeden nasłuchiwacz zdarzeń na <ul>, co pozwoli na przechwytywanie kliknięć na wszystkich <li>, wykorzystując obiekt Event do określenia, który element został kliknięty. W praktyce, event bubbling przyczynia się do zmniejszenia liczby nasłuchiwaczy zdarzeń i optymalizacji wydajności aplikacji webowych, a także ułatwia organizację kodu. Warto również pamiętać o metodzie stopPropagation(), która może być używana, aby zatrzymać propagację zdarzenia, gdy zajdzie taka potrzeba. Zrozumienie event bubbling jest istotne w kontekście standardów W3C, które definiują zasady dla przetwarzania zdarzeń.

Pytanie 27

W jakiej okoliczności należy umieścić poszkodowanego w pozycji bezpiecznej?

A. Gdy poszkodowany jest nieprzytomny, ale oddycha
B. Gdy poszkodowany cierpi na krwotok zewnętrzny
C. Gdy poszkodowany jest świadomy, lecz ma uraz kończyny
D. Gdy poszkodowany nie oddycha
Pozycja bezpieczna (czyli pozycja boczna ustalona) to jedno z kluczowych narzędzi w udzielaniu pierwszej pomocy. Stosuje się ją wtedy, gdy poszkodowany jest nieprzytomny, ale oddycha samodzielnie i nie ma podejrzenia urazu kręgosłupa. Chodzi przede wszystkim o zabezpieczenie dróg oddechowych przed ewentualnym zadławieniem np. przez ślinę, krew czy wymiociny. Niby proste, ale w praktyce często ludzie mają wątpliwości, czy powinni ruszać nieprzytomną osobę. Ja sam widziałem jak ktoś bał się tego zrobić, bo nie był pewny, czy to bezpieczne. Moim zdaniem lepiej tu działać niż zwlekać – oczywiście, jeśli nie podejrzewasz złamania kręgosłupa. Ważne jest, by pozycję bezpieczną stosować dopiero po sprawdzeniu oddechu – to naprawdę podstawa i tak uczą na wszystkich szkoleniach BLS według standardów Europejskiej Rady Resuscytacji. Przykład z życia: ktoś zasłabł na przystanku, jest nieprzytomny, ale oddycha. Przekręcasz go na bok, głowa odchylona, żeby język nie zablokował gardła – i masz spokój, dużo zmniejszone ryzyko uduszenia. Warto też pamiętać, że trzeba regularnie monitorować stan poszkodowanego, bo sytuacja może się pogorszyć, wtedy przechodzisz do resuscytacji. Pozycja bezpieczna to taki złoty środek kiedy nie musisz jeszcze reanimować, ale musisz chronić życie przez zabezpieczenie oddechu.

Pytanie 28

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

A. import [ Component ] from 'react'
B. import Component from 'react'
C. import { Component } from 'react'
D. import React.Component from 'react'

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Użycie składni import { Component } from 'react' to zdecydowanie najczęściej spotykany i najbardziej rekomendowany sposób importowania tylko wybranego komponentu z biblioteki React. To tzw. import nazwany, czyli dokładnie wskazujesz, który kawałek kodu chcesz wyciągnąć z całego modułu. W praktyce, jest to bardzo czytelne i pozwala na jasne zarządzanie zależnościami w pliku. Moim zdaniem ma to ogromne znaczenie w większych projektach, bo łatwo potem znaleźć, które elementy są faktycznie wykorzystywane w danym pliku. Co ważne, taka technika importowania jest w pełni zgodna ze standardami ES6, właściwie każdy nowoczesny projekt front-endowy na tym bazuje. Przykład praktyczny: jeśli chcesz stworzyć klasowy komponent React, wystarczy napisać import { Component } from 'react', a potem class MyClass extends Component {...}. Jest to nieco bardziej eleganckie niż importowanie całego obiektu React (np. import React from 'react'), zwłaszcza jeśli nie potrzebujesz całej funkcjonalności. Dodatkowo, takie rozwiązanie może wpływać pozytywnie na bundlowanie kodu, bo nie ściągasz do projektu niepotrzebnych fragmentów biblioteki. Swoją drogą, coraz częściej widać, że programiści skupiają się na minimalizowaniu importów i czytelności kodu – właśnie przez wybór takich rozwiązań.

Pytanie 29

Jaką strukturę danych można zrealizować, korzystając jedynie z wymienionych poniżej metod:

push(arg) – dodaje element
pop() – usuwa ostatnio dodany element
peek() – zwraca ostatnio dodany element bez usuwania
isEmpty() – sprawdza czy istnieją dane w strukturze
A. kolejka
B. stos
C. drzewo binarne
D. tablica

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Stos to jedna z najbardziej podstawowych i jednocześnie użytecznych struktur danych. Wszystkie wymienione metody - push, pop, peek oraz isEmpty - są klasycznymi operacjami definiującymi właśnie stos (czyli tzw. LIFO, czyli Last-In-First-Out). Oznacza to, że ostatni element, który został dodany do stosu, będzie pierwszym usuniętym. Z mojego doświadczenia wynika, że stosy są bardzo często wykorzystywane w praktyce, na przykład przy realizacji algorytmów rekurencyjnych (zarówno w kodzie, jak i na niższym poziomie, jak stos wywołań funkcji w pamięci programu), co jest zgodne ze standardami języków programowania, takich jak C, Java czy Python. W praktycznych zastosowaniach stosów używa się m.in. przy sprawdzaniu poprawności nawiasów w wyrażeniach matematycznych, przy parsowaniu kodu, cofnięciach operacji w edytorach tekstu czy realizacji algorytmu przeszukiwania w głąb (DFS). Co ciekawe, stos można łatwo zaimplementować zarówno na tablicach dynamicznych, jak i na listach jednokierunkowych. Dobre praktyki branżowe zalecają, aby stos wykorzystywać zawsze tam, gdzie potrzebny jest szybki dostęp do ostatnio dodanego elementu i nie zachodzi potrzeba dostępu w inny sposób. Moim zdaniem, zrozumienie działania stosu to fundament dla każdego, kto serio podchodzi do programowania i algorytmiki.

Pytanie 30

Dokumentacja, która została przedstawiona, dotyczy algorytmu sortowania

To prosta metoda sortowania opierająca się na cyklicznym porównywaniu par sąsiadujących ze sobą elementów i zamianie ich miejscami w przypadku, kiedy kryterium porządkowe zbioru nie zostanie spełnione. Operacje te wykonywane są dopóki występują zmiany, czyli tak długo, aż cały zbiór zostanie posortowany.
A. szybkie (Quicksort)
B. bąbelkowe
C. przez wstawianie
D. przez wybór

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Opisany w pytaniu algorytm to właśnie sortowanie bąbelkowe (ang. bubble sort). Polega ono na wielokrotnym przechodzeniu przez zbiór danych i zamienianiu miejscami sąsiadujących elementów, jeśli są w złej kolejności. Czynność ta powtarzana jest do momentu, gdy cały zbiór zostanie uporządkowany i żadne zamiany nie będą już potrzebne. Moim zdaniem, to chyba jeden z najbardziej intuicyjnych algorytmów sortowania, jakie się poznaje na początku nauki programowania – łatwo go zaimplementować, bo wymaga właściwie tylko dwóch pętli i porównania sąsiednich elementów. W praktyce bubble sort raczej rzadko używa się w profesjonalnych projektach, bo jego złożoność czasowa to O(n^2), co przy dużych zbiorach jest nieefektywne. Jednak czasami, na bardzo małych listach albo gdy szybko trzeba zrobić prosty prototyp, to można sięgnąć po „bąbelki”. Z mojego doświadczenia wynika też, że sortowanie bąbelkowe dobrze obrazuje podstawowe zasady algorytmiki, na przykład jak działa iteracja czy wymiana miejscami zmiennych – to przydatne w nauce. W wielu językach programowania, nawet tych nowoczesnych, można spotkać przykłady z bubble sort jako ilustrację podstaw. To taki klasyk – mało kto używa go zawodowo, ale każdy programista powinien wiedzieć, jak działa. Warto też pamiętać, że istnieją optymalizacje bubble sortu, np. wcześniejsze zakończenie, gdy w danej iteracji nie wystąpiła żadna zamiana. No i taka ciekawostka: choć algorytm nie jest specjalnie szybki, to bardzo łatwo go zaimplementować nawet w językach niskopoziomowych, bo nie wymaga dodatkowej pamięci.

Pytanie 31

W programie desktopowym stworzono rozwijaną listę oraz przypisano cztery funkcje do obsługi zdarzeń tej kontrolki. Jaki komunikat pojawi się po dokonaniu wyboru w tej liście?
W XAML (uproszczona wersja):

<ComboBox SelectionChanged="Funkcja1" DragEnter="Funkcja2"
    LostFocus="Funkcja3" KeyDown="Funkcja4">
</ComboBox>
W kodzie:
private void Funkcja1(object sender, SelectionChangedEventArgs e)
{
    MessageBox.Show("Zdarzenie 1");
}
private void Funkcja2(object sender, DragEventArgs e)
{
    MessageBox.Show("Zdarzenie 2");
}
private void Funkcja3(object sender, RoutedEventArgs e)
{
    MessageBox.Show("Zdarzenie 3");
}
private void Funkcja4(object sender, KeyEventArgs e)
{
    MessageBox.Show("Zdarzenie 4");
}
A. Zdarzenie 3
B. Zdarzenie 4
C. Zdarzenie 1
D. Zdarzenie 2

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Wybrałeś dokładnie to, co trzeba. W tej sytuacji kluczowe jest rozpoznanie, że zdarzenie SelectionChanged jest wywoływane zawsze wtedy, gdy użytkownik wybierze inną pozycję z ComboBoxa. I to właśnie do tego zdarzenia przypisana jest metoda Funkcja1, która wyświetla komunikat "Zdarzenie 1". Trochę to wygląda niepozornie, ale SelectionChanged to jeden z najczęściej obsługiwanych eventów w aplikacjach desktopowych opartych na WPF czy UWP – praktycznie zawsze reagujemy na wybór użytkownika w kontrolkach ComboBox, ListBox albo nawet ListView. Z mojego doświadczenia wynika, że początkujący programiści często mylą to zdarzenie z innymi, jak LostFocus, które odpala się, gdy kontrolka traci fokus, albo z DragEnter (zupełnie inny przypadek, bo dotyczy przeciągania danych). Warto pamiętać, że KeyDown reaguje dopiero na naciśnięcie klawisza, a nie na wybór myszką. Takie rozróżnienie jest codziennością przy tworzeniu bardziej zaawansowanych interfejsów użytkownika. Praktyczna wskazówka: jeśli chcesz reagować na wybór użytkownika i np. ładować dodatkowe dane czy weryfikować coś po stronie aplikacji, to SelectionChanged jest strzałem w dziesiątkę. Standardy branżowe sugerują nie przesadzać z obsługą zbyt wielu eventów jednocześnie dla tej samej kontrolki, bo to może prowadzić do konfliktów i dziwnych zachowań UI. Mocno polecam samemu poeksperymentować – otworzyć Visual Studio, zrobić prostą aplikację WPF, podpiąć te eventy i zobaczyć, które kiedy się odpalają. Dzięki temu dużo szybciej utrwala się ta wiedza niż z samej teorii.

Pytanie 32

Jakie jest główne zadanie kontrolera w architekturze MVC (Model-View-Controller)?

A. Przechowywanie danych aplikacji
B. Zarządzanie sesją użytkownika
C. Obsługa logiki biznesowej i przetwarzanie danych wejściowych od użytkownika
D. Prezentowanie danych użytkownikowi
W architekturze MVC kontroler pełni kluczową rolę w procesie przetwarzania danych aplikacji. Jego głównym zadaniem jest obsługa logiki biznesowej oraz przetwarzanie danych, które pochodzą od użytkownika. Kontroler działa jako pośrednik pomiędzy modelem a widokiem, odbierając żądania użytkownika, przetwarzając je (często z wykorzystaniem logiki biznesowej) i decydując, które dane modelu powinny być przekazane do widoku. W praktyce oznacza to, że kontroler interpretuje dane wejściowe, modyfikuje stan modelu na ich podstawie, a następnie wybiera odpowiedni widok do wyświetlenia wyników użytkownikowi. Takie podejście pozwala na lepszą organizację kodu i oddzielenie logiki aplikacji od interfejsu użytkownika, co jest zgodne z dobrymi praktykami projektowania oprogramowania. Dzięki temu aplikacje są bardziej skalowalne i łatwiejsze w utrzymaniu.

Pytanie 33

Kod przedstawiony w języku XML/XAML określa:

<Switch
    android:id = "@+id/switch1"
    android:layout_width = "wrap_content"
    android:layout_height = "wrap_content"
    android:background = "#00ffff"
    android:text = "Switch"
    tools:layout_editor_absoluteX = "176dp"
    tools:layout_editor_absoluteY = "389dp" />
A. suwak
B. stepper
C. przełącznik
D. listę rozwijaną

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Kod przedstawiony w pytaniu to klasyczny przykład wykorzystania komponentu Switch w Androidzie. Switch, jak sama nazwa wskazuje, służy do przełączania między dwoma stanami — najczęściej włącz/wyłącz, aktywne/nieaktywne. Z punktu widzenia interfejsów mobilnych, przełącznik bardzo często znajduje zastosowanie w ustawieniach aplikacji, np. do szybkiego włączania trybu ciemnego, aktywacji powiadomień czy zezwalania na lokalizację. Ten konkretny xml zawiera podstawowe atrybuty, jak android:id, layout_width, layout_height oraz background, czyli kolor tła, co od razu sugeruje, że nie jest to np. dropdown czy suwak. Co ciekawe, Switch różni się od CheckBoxa tym, że wizualnie lepiej komunikuje zmianę trybu (przesuwający się znacznik), co moim zdaniem zwiększa użyteczność, szczególnie jeśli użytkownik ma szybko zrozumieć, co ustawia. Standardy Material Design wręcz zalecają stosowanie Switch do kontrolowania pojedynczych ustawień, bo jest to bardziej czytelne niż inne widgety. Warto pamiętać, że Switch ma różne warianty i można go rozbudować o obsługę zdarzeń onCheckedChangeListener w kodzie Java albo Kotlin, przez co staje się bardzo elastyczny. Odpowiedź przełącznik jest więc zgodna ze wszystkimi cechami tej kontrolki i jej zastosowaniami w praktyce.

Pytanie 34

Co oznacza pojęcie MVP w kontekście projektowania aplikacji?

A. Minimum Viable Product - produkt o minimalnej funkcjonalności zdolny do działania
B. Most Valuable Program - program uznany za najbardziej wartościowy w organizacji
C. Multiple Value Platform - platforma wspierająca wiele typów wartości danych
D. Mobile Virtual Platform - platforma do testowania aplikacji mobilnych

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Pojęcie Minimum Viable Product (MVP) odnosi się do koncepcji projektowania produktów, która zakłada stworzenie wersji produktu z minimalną funkcjonalnością, zdolnej do spełnienia podstawowych potrzeb użytkowników. Celem MVP jest jak najszybsze wprowadzenie produktu na rynek, co pozwala na zbieranie danych od rzeczywistych użytkowników i dostosowywanie produktu na podstawie ich feedbacku. Tego rodzaju podejście jest zgodne z metodologią Lean Startup, która promuje szybkie cykle iteracyjne i minimalizację ryzyka inwestycyjnego. Przykładem MVP może być aplikacja mobilna, która oferuje tylko najważniejsze funkcje, na przykład możliwość rejestracji i przeglądania treści, zamiast pełnej gamy opcji. Dzięki temu zespół developerski może szybko identyfikować kluczowe potrzeby użytkowników i wprowadzać odpowiednie udoskonalenia. W praktyce MVP pozwala nie tylko na szybsze wprowadzenie produktu na rynek, ale również na optymalizację kosztów i czasów rozwoju, co jest szczególnie istotne w dynamicznie zmieniającym się środowisku technologicznym.

Pytanie 35

Teoria wyznaczania celów definiuje właściwie sformułowany cel jako SMART, od pierwszych liter słów: specyficzny, Mierzalny, Ambitny, Realny oraz Terminowy. Wskaź, który cel wymaga wysiłku i stanowi wyzwanie dla pracownika?

A. Terminowy
B. Specyficzny
C. Mierzalny
D. Ambitny

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Odpowiedź „Ambitny” rzeczywiście najlepiej oddaje ideę celu, który wymaga wysiłku i jest wyzwaniem dla pracownika. Moim zdaniem właśnie to kryterium - bycie ambitnym - odgrywa kluczową rolę w motywowaniu zespołu do podnoszenia swoich umiejętności i przekraczania codziennych ograniczeń. Praktyka pokazuje, że wyznaczanie ambitnych celów, choć może się wydawać nieco ryzykowne, rozwija kreatywność i pozwala wychodzić poza strefę komfortu. Branżowe standardy zarządzania projektami (np. PMI czy PRINCE2) mocno podkreślają wagę ambitnych, ale jednocześnie realistycznych celów – taki balans sprawia, że pracownicy nie popadają w rutynę i są zmotywowani do długotrwałego rozwoju. W codziennych realiach np. produkcyjnych, cel ambitny może oznaczać zwiększenie wydajności o 20% w pół roku, a nie tylko utrzymanie obecnego poziomu. Z mojego doświadczenia wynika, że dobrze sformułowany, ambitny cel uruchamia zdrową rywalizację i buduje poczucie sensu pracy. Warto pamiętać, by ambicja nie prowadziła do nierealnych oczekiwań – tutaj ważna jest rola lidera, żeby dobrze poznać możliwości zespołu. Sumując: ambitny cel to nie tylko wyzwanie, ale też szansa na znaczący rozwój zawodowy i osobisty.

Pytanie 36

Która funkcja z biblioteki jQuery w JavaScript służy do naprzemiennego dodawania oraz usuwania klasy z elementu?

A. .changeClass()
B. .switchClass()
C. .bingClass()
D. .toggleClass()

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Wybrałeś .toggleClass() i to jest strzał w dziesiątkę pod względem praktycznego stosowania jQuery. Funkcja .toggleClass() dokładnie odpowiada na potrzebę dynamicznej zmiany wyglądu elementu — pozwala jednym wywołaniem dodać klasę, jeśli jej nie ma, albo usunąć, jeśli już istnieje. To niesamowicie przydatne, zwłaszcza przy tworzeniu efektów interaktywnych, takich jak menu rozwijane, animacje kliknięcia, czy zmiany stanów przycisków. W praktyce wygląda to często tak: $('div').toggleClass('active'), gdzie po każdym kliknięciu div otrzymuje lub traci klasę 'active'. Warto zauważyć, że .toggleClass() obsługuje też opcjonalny drugi argument typu boolean, więc możesz wymusić dodanie lub usunięcie klasy zależnie od logiki — to takie jQuery’owe „sprytne przełączanie”. Z mojego doświadczenia, ta metoda jest zdecydowanie jednym z fundamentów, kiedy chodzi o szybkie prototypowanie i pisanie kodu front-endowego zgodnego z zasadami DRY (Don’t Repeat Yourself). Dobrą praktyką jest też, żeby nie nadużywać tej funkcji do zbyt skomplikowanych operacji, bo wtedy łatwo się pogubić w logice klas CSS. No i jak patrzę na projekty w branży, to .toggleClass() jest stosowane praktycznie wszędzie tam, gdzie chodzi o responsywną zmianę interfejsu klienta bez potrzeby pisania rozbudowanego JavaScriptu.

Pytanie 37

Która z operacji logicznych zwróci wartość "true", gdy obie zmienne są sobie równe?

A. x == y
B. x != y
C. x && y
D. x || y

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Operator `==` w języku C++ i wielu innych językach programowania (np. Python, Java, JavaScript) służy do porównywania dwóch wartości. Zwraca `true`, jeśli obie wartości są sobie równe, oraz `false`, jeśli są różne. Przykład: `if (x == y)` sprawdza, czy zmienna `x` jest równa zmiennej `y`. Operator ten jest kluczowy w instrukcjach warunkowych oraz pętlach, gdzie konieczne jest porównywanie wartości w celu podejmowania decyzji na podstawie wyniku tego porównania.

Pytanie 38

Jakie wyrażenie logiczne powinno być użyte, aby zweryfikować, czy zmienna x zawiera wartości ujemne lub znajduje się w zakresie (10, 100)?

A. (x > 10 || x < 100) && x < 0
B. (x > 10 && x < 100) || x < 0
C. x > 10 || x < 100 || x < 0
D. x > 10 || x < 100 || x < 0

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
To wyrażenie logiczne: (x > 10 && x < 100) || x < 0 jest najtrafniejsze, bo dokładnie oddaje założone warunki: zmienna x powinna być ujemna lub znajdować się w zakresie od 10 do 100 (bez tych wartości granicznych, czyli przedział otwarty). Z mojego doświadczenia wynika, że takie podejście jest stosowane wszędzie tam, gdzie istotne są szczegółowe warunki – np. w walidacji danych wejściowych czy podczas filtrowania w bazach danych. Operator || gwarantuje, że jeśli chociaż jeden z warunków jest prawdziwy (czyli x jest mniejsze od 0 lub należy do przedziału 10-100), całe wyrażenie zwróci true. Warto też pamiętać, że zastosowanie operatora && wewnątrz nawiasu zapewnia, że oba warunki (x > 10 oraz x < 100) muszą być spełnione jednocześnie, czyli x leży pomiędzy tymi liczbami. Odpowiedniki takiego zapisu znajdziesz praktycznie w każdym języku programowania – od Javy po Pythona. Branżowe standardy jasno wskazują na czytelność i jednoznaczność warunków logicznych, szczególnie jeśli kod ma być utrzymywany przez inne osoby lub przez nas samych za kilka miesięcy. Uważam, że precyzyjne formułowanie wyrażeń tego typu to podstawa dobrego programisty – naprawdę warto się tego trzymać, bo później mniej błędów wychodzi na produkcji, a kod jest dużo łatwiej przetestować. Często spotykam się z przypadkami, gdzie ktoś pomija nawiasy lub źle łączy operatory i potem są problemy z błędami logicznymi, dlatego warto wyrobić sobie taki nawyk dokładnego zapisywania warunków.

Pytanie 39

Ergonomiczną oraz właściwą pozycję do pracy przy komputerze zapewni fotel, którego

A. oparcie w rejonie szyi jest nachylone do przodu o 40ᵒ
B. oparcie wspiera lordozę w dolnym odcinku pleców
C. podłokietniki są 30 cm powyżej blatu
D. podłokietniki znajdują się 20 cm poniżej blatu

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Prawidłowa i ergonomiczna pozycja pracy przy komputerze jest kluczowa dla zdrowia i komfortu użytkownika. Oparcie krzesła, które zapewnia lordozę w odcinku lędźwiowym, jest niezbędne, ponieważ pozwala na zachowanie naturalnej krzywizny kręgosłupa. Lordoza lędźwiowa to naturalne wygięcie kręgosłupa w dolnej części pleców, które wspiera prawidłowe ułożenie ciała podczas siedzenia. Krzesło powinno być zaprojektowane tak, aby oparcie przylegało do krzywizny ciała, co minimalizuje ryzyko bólu pleców oraz przeciążeń. Praktycznym przykładem ergonomicznej pozycji jest ustawienie oparcia w taki sposób, aby jego dolna część była dostosowana do odcinka lędźwiowego. Zgodnie z normami ISO 9241, które dotyczą ergonomii miejsc pracy przy komputerze, krzesło powinno umożliwiać użytkownikowi przyjęcie wygodnej pozycji z podparciem dla dolnej części pleców. W odpowiedniej pozycji stopy powinny spoczywać płasko na podłodze, a kolana powinny być na poziomie bioder, co wspiera prawidłowe krążenie krwi oraz redukuje napięcia mięśniowe.

Pytanie 40

Z podanej definicji pola licznik można wywnioskować, iż

class MojaKlasa
{
    private static int licznik;
    ...
A. bieżąca wartość pola jest wspólna dla wszystkich instancji klasy
B. pole nie może być zmieniane w kodzie klasy
C. bieżąca wartość pola jest wspólna dla wszystkich instancji klasy i nie może być zmieniana
D. pole jest związane z określoną instancją klasy i jego wartość jest unikalna tylko dla tej instancji

Brak odpowiedzi na to pytanie.

Wyjaśnienie poprawnej odpowiedzi:
Prawidłowa odpowiedź wynika bezpośrednio z zastosowania słów kluczowych static oraz private w definicji pola licznik. W praktyce oznacza to, że zmienna licznik nie należy do konkretnej instancji klasy, ale do samej klasy jako całości. Innymi słowy – ilekroć tworzysz nowy obiekt typu MojaKlasa, to nie powstaje nowy licznik, tylko wszystkie te obiekty korzystają ze wspólnej „puli”. To zachowanie jest kluczowe na przykład wtedy, gdy chcemy zliczać, ile obiektów danej klasy zostało utworzonych – licznik rośnie globalnie, niezależnie od tego, ile razy utworzymy nową instancję. Często stosuje się takie pola w implementacjach wzorców projektowych typu singleton czy manager zasobów. Static wprowadza też pewną odpowiedzialność – trzeba pamiętać, że modyfikując licznik w jednym miejscu, od razu wypływa to na wszystkie potencjalne obiekty. Z mojego punktu widzenia, to świetny przykład na zrozumienie różnicy między polem statycznym (klasowym), a polem instancyjnym (prywatnym dla każdego obiektu osobno). Pole licznik jest także prywatne, więc bezpośredni dostęp do niego mają tylko metody tej klasy. Zwracam uwagę, że w wielu branżowych projektach takie podejście to wręcz standard, no i bardzo przydaje się, jeśli chcemy wdrożyć licznik globalnie dostępny lub przechowywać konfiguracje wspólne dla wszystkich instancji.