Wyniki egzaminu

Informacje o egzaminie:
  • Zawód: Technik programista
  • Kwalifikacja: INF.04 - Projektowanie, programowanie i testowanie aplikacji
  • Data rozpoczęcia: 8 czerwca 2026 11:25
  • Data zakończenia: 8 czerwca 2026 11:37

Egzamin zdany!

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

Wymagane minimum: 20 punktów (50%)

Nowe
Analiza przebiegu egzaminu- sprawdź jak rozwiązywałeś pytania
Pochwal się swoim wynikiem!
Szczegółowe wyniki:
Pytanie 1

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

A. gdy wystąpi uszkodzenie kręgosłupa
B. w przypadku urazu pleców, gdy osoba jest przytomna
C. w sytuacji omdlenia i braku tętna
D. gdy osoba omdleje, ale oddycha
Umieszczenie poszkodowanego w pozycji bocznej bezpiecznej jest jedną z podstawowych czynności, których uczą ratownicy zarówno na kursach pierwszej pomocy, jak i w szkołach. Ta pozycja ma na celu przede wszystkim zabezpieczenie dróg oddechowych osoby, która jest nieprzytomna, ale wciąż oddycha samodzielnie. Chodzi o to, że w takiej sytuacji język i ewentualne płyny nie zablokują tchawicy – pozycja boczna zapobiega zadławieniu czy zakrztuszeniu. Moim zdaniem to jedna z najbardziej praktycznych procedur, bo życie pokazuje, że właśnie omdlenia oraz krótkotrwałe utraty przytomności bez zatrzymania oddechu są dość częste, czy to na ulicy, czy w pracy. Przepisy i dobre praktyki (np. wytyczne Europejskiej Rady Resuscytacji) jasno wskazują, że jeśli osoba nie reaguje, ale oddycha, to nie zostawiamy jej na plecach – groziłoby to zapadnięciem języka albo zachłyśnięciem wymiocinami. W praktyce najpierw oczywiście sprawdzasz oddech, potem delikatnie układasz człowieka na boku, zginając odpowiednio kończyny, żeby się nie przewrócił. Sam widziałem, jak taka szybka reakcja potrafi uratować komuś zdrowie albo i życie. Warto też pamiętać, że taka pozycja daje Ci czas na wezwanie pomocy i monitorowanie stanu poszkodowanego do przyjazdu ratowników.

Pytanie 2

Który z wymienionych przykładów przedstawia typ rekordowy?

A. struct w języku C++
B. bool w języku Java
C. float w języku C
D. int w języku Python
Typ 'struct' w języku C++ jest przykładem typu rekordowego, który pozwala na grupowanie zmiennych różnego typu pod jedną nazwą. Struktury pozwalają na przechowywanie powiązanych danych, np. informacji o pracowniku (imię, nazwisko, wiek) w jednym obiekcie. Struktury są kluczowe w programowaniu proceduralnym i obiektowym, umożliwiając efektywne zarządzanie danymi złożonymi. Typy rekordowe pozwalają na budowanie bardziej złożonych i zorganizowanych aplikacji, co zwiększa ich czytelność i ułatwia zarządzanie kodem.

Pytanie 3

Jaki model zarządzania projektami przewiduje, że wszystkie etapy są realizowane jeden po drugim, bez możliwości wrócenia do wcześniejszych faz?

A. Model spiralny
B. Metodyki zwinne (Agile)
C. Model kaskadowy (waterfall)
D. Model przyrostowy
Model kaskadowy (Waterfall) zakłada, że każda faza projektu jest realizowana sekwencyjnie, bez możliwości powrotu do wcześniejszych etapów. Każda faza musi zostać zakończona przed rozpoczęciem kolejnej, co sprawia, że model ten jest przewidywalny i dobrze nadaje się do projektów o jasno określonych wymaganiach. Dzięki temu ryzyko błędów jest minimalizowane na wczesnym etapie, co zwiększa stabilność projektu. Waterfall jest często stosowany w projektach infrastrukturalnych i rządowych, gdzie istotna jest dokładność i zgodność z pierwotnym planem.

Pytanie 4

Jaki jest główny cel normalizacji baz danych?

A. Przyśpieszenie zapytań kosztem zwiększenia redundancji
B. Eliminacja redundancji danych i zapewnienie integralności danych
C. Zmniejszenie rozmiaru bazy danych kosztem integralności
D. Zwiększenie liczby tabel w celu lepszej organizacji danych
Głównym celem normalizacji baz danych jest eliminacja redundancji danych oraz zapewnienie ich integralności. Proces ten polega na przekształceniu danych w taki sposób, aby zminimalizować powielanie informacji, co przekłada się na oszczędność miejsca oraz poprawę wydajności bazy. Normalizacja wyodrębnia dane w sposób, który pozwala na ich logiczne i spójne uporządkowanie, co ułatwia aktualizację oraz usuwanie danych bez ryzyka wprowadzenia niezgodności. Przykładem praktycznego zastosowania normalizacji jest system zarządzania danymi klientów, gdzie informacje o klientach, zamówieniach i produktach są przechowywane w odrębnych tabelach. Dzięki temu można łatwo wprowadzać zmiany w danych klientów, bez wpływu na dane zamówień czy produktów. W branży baz danych, standardy takie jak ACID (Atomicity, Consistency, Isolation, Durability) i zasady dotyczące normalizacji, jak pierwsza, druga czy trzecia forma normalna, stanowią fundamenty dobrych praktyk projektowania baz danych. Zastosowanie tych zasad wpływa na zwiększenie efektywności operacji CRUD (Create, Read, Update, Delete) i zapewnia integralność danych w dłuższym okresie.

Pytanie 5

Zastosowanie typu DECIMAL języka SQL wymaga wcześniejszego zdefiniowania długości (liczby cyfr) przed przecinkiem oraz długości cyfr po przecinku. Jest to zapis:

A. zmiennoprzecinkowy
B. logicznym
C. stałoprzecinkowy
D. łańcuchowym
Typ DECIMAL w SQL bywa mylony z różnymi innymi kategoriami typów, głównie dlatego, że ludzie kojarzą „przecinek” z liczbami zmiennoprzecinkowymi albo traktują wszystko, co ma cyfry, jako coś podobnego do tekstu. W rzeczywistości DECIMAL jest typem stałoprzecinkowym, czyli takim, w którym precyzja i liczba miejsc po przecinku są z góry ustalone przy definicji kolumny. To jest zupełnie inne podejście niż w typach zmiennoprzecinkowych, takich jak FLOAT czy DOUBLE. Tam liczby są przechowywane w formacie binarnym zgodnym mniej więcej ze standardem IEEE 754, a przecinek „pływa”, co prowadzi do drobnych, ale istotnych błędów zaokrągleń.
Jeśli ktoś zaznacza odpowiedź zmiennoprzecinkowy, to zwykle wynika z intuicji: skoro jest przecinek, to pewnie float. To jest typowy błąd myślowy. W SQL typy zmiennoprzecinkowe są właśnie po to, by obsługiwać bardzo duże lub bardzo małe wartości kosztem dokładności, np. w obliczeniach naukowych. DECIMAL natomiast ma służyć do obliczeń finansowych i biznesowych, gdzie dokładność jest ważniejsza niż zakres. Z mojego doświadczenia to jedno z częstszych źródeł błędów w młodych projektach: użycie FLOAT do kwot pieniędzy.
Odpowiedź logicznym też bywa wybierana trochę „na czuja”, bo ktoś kojarzy, że SQL ma typy TRUE/FALSE, ale DECIMAL nie ma nic wspólnego z logiką boolowską. Typy logiczne przechowują wartości dwustanowe (czasem z NULL jako stanem trzecim), a nie liczby z miejscami po przecinku. Podobnie odpowiedź łańcuchowym wynika z przekonania, że skoro można cyfry zapisać w tekście, to wszystko jedno, czy to tekst, czy liczba. W praktyce typy łańcuchowe (CHAR, VARCHAR, TEXT) nie zapewniają poprawnej arytmetyki, sortowania numerycznego ani kontroli zakresu liczb. Trzymanie wartości liczbowych jako tekst to bardzo zła praktyka: utrudnia indeksowanie, psuje wydajność i powoduje dziwne błędy przy porównaniach (np. '100' < '20' w porządku leksykograficznym). Dobre wzorce projektowania baz danych mówią jasno: liczby trzymaj w typach liczbowych, a wartości wymagające dokładności dziesiętnej w typie stałoprzecinkowym DECIMAL/NUMERIC, z jasno określoną precyzją i skalą.

Pytanie 6

Które z wymienionych narzędzi nie znajduje zastosowania w tworzeniu aplikacji desktopowych?

A. Przeglądarka internetowa
B. Edytor graficzny
C. Kompilator
D. Debugger
Przeglądarka internetowa nie jest narzędziem wykorzystywanym bezpośrednio w procesie tworzenia aplikacji desktopowych. Chociaż może służyć do przeszukiwania dokumentacji lub testowania aplikacji webowych, jej funkcjonalność nie wspiera bezpośredniego tworzenia aplikacji desktopowych. W tworzeniu aplikacji desktopowych kluczowe są narzędzia takie jak kompilatory, debugery i edytory kodu. Kompilatory przekształcają kod źródłowy na kod wykonywalny, debugery pozwalają na śledzenie błędów, a edytory kodu umożliwiają pisanie i edytowanie aplikacji.

Pytanie 7

Klasa Mieszkaniec zawiera atrybuty: imie, nazwisko, ulica, nrDomu, rokUrodzenia. W tej klasie umieszczono opisane poniżej konstruktory (zapisano jedynie typy argumentów). Do tworzenia obiektu za pomocą konstruktora kopiującego wykorzystany będzie konstruktor określony w punkcie

A. Mieszkaniec(string, string);
B. Mieszkaniec(Mieszkaniec&);
C. Mieszkaniec();
D. Mieszkaniec(string, string, string, int, int);
Konstruktor kopiujący to taka fajna metoda, która pozwala nam stworzyć nowy obiekt, będący kopią innego obiektu tej samej klasy. To naprawdę ważny element w programowaniu obiektowym, bo dzięki niemu możemy tworzyć nowe instancje bez konieczności ręcznego wpisywania wartości pól. Taki konstruktor kopiujący dba o to, żeby dane były spójne i integralne, co jest super istotne, zwłaszcza przy obiektach, które mają wskaźniki lub potrzebują dynamicznie przydzielanej pamięci.

Pytanie 8

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

public class Car: Vehicle {     ...   }
A. jest powiązana z klasą Vehicle
B. stanowi klasę bazową (nie dziedziczy po żadnej klasie)
C. dziedziczy po 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

Jaki rodzaj ataku hakerskiego polega na bombardowaniu serwera ogromną ilością żądań, co prowadzi do jego przeciążenia?

A. SQL Injection
B. Phishing
C. DDoS
D. Man-in-the-Middle
Atak DDoS (Distributed Denial of Service) polega na zasypywaniu serwera dużą ilością zapytań, co prowadzi do jego przeciążenia i unieruchomienia. W tym rodzaju ataku, hakerzy wykorzystują sieć skompromitowanych komputerów, znanych jako botnety, aby wysłać ogromne ilości nieautoryzowanych żądań do docelowego serwera w krótkim czasie. Celem DDoS jest spowodowanie, że serwer nie jest w stanie odpowiedzieć na prawidłowe zapytania od autentycznych użytkowników, co skutkuje awarią usługi. Przykłady ataków DDoS obejmują SYN Flood, UDP Flood oraz HTTP Flood, gdzie każdy z tych typów wykorzystuje różne protokoły i metody do zablokowania normalnego ruchu. Standardy takie jak RFC 793 definiują protokół TCP, który może być narażony na ataki SYN Flood. Ważne jest, aby organizacje stosowały odpowiednie środki zabezpieczające, takie jak systemy detekcji intruzów (IDS), firewalle, oraz usługi ochrony DDoS, aby minimalizować ryzyko i skutki tych ataków.

Pytanie 10

Podana deklaracja zmiennych w języku JAVA zawiera

String imie = "Anna";
short wiek = 12;
int i = 0;
char plec = 'K';
boolean jestUczniem = true;
A. dwie zmienne o typie strukturalnym
B. jedną zmienną typu tekstowego, dwie całkowite, jedną znakową i jedną logiczną
C. jedną zmienną typu tekstowego, jedną rzeczywistą, jedną całkowitą, jedną znakową oraz jedną logiczną
D. dwie zmienne typu tekstowego, dwie całkowite oraz jedną logiczną
Analizując podaną deklarację zmiennych w języku Java, widać wyraźnie, że mamy tu do czynienia z pięcioma zmiennymi o różnych typach: String imie = "Anna" – typ tekstowy, short wiek = 12 oraz int i = 0 – dwa typy całkowite (różnią się zakresem wartości), char plec = 'K' – typ znakowy, boolean jestUczniem = true – typ logiczny. Takie zróżnicowanie typów pozwala nie tylko przechowywać różne informacje, ale też lepiej zarządzać pamięcią i logiczną strukturą programu. Z mojej perspektywy, właściwy dobór typów danych to podstawa, bo pomaga unikać wielu późniejszych problemów z kompatybilnością czy błędami wykonania. Java została zaprojektowana tak, by wymuszać jawność typów, co zdecydowanie zwiększa czytelność kodu i zmniejsza liczbę nieoczywistych bugów. Praktycznie, w każdej większej aplikacji spotkamy się z kombinacją typów prostych (jak int, short, boolean czy char) i obiektowych (np. String). Warto pamiętać, że String to typ referencyjny, a nie prosty jak reszta wymienionych. Przy dużych projektach poleca się deklarować zmienne możliwie najwęższego typu (np. short zamiast int, jeśli wystarczy), by oszczędzać zasoby. To jest taka podstawowa wiedza, bez której trudno ruszyć dalej w świecie Javy, bo typy decydują o tym, jak zachowuje się program i co można z danymi zrobić. W rzeczywistych projektach, na przykład przy tworzeniu rejestracji użytkowników czy bazy danych, takie typy jak String, int, char i boolean pojawiają się na każdym kroku.

Pytanie 11

Środowiskiem dedykowanym do tworzenia aplikacji mobilnych dla urządzeń Apple i wykorzystującym do tego celu różne języki programowania w tym Java i Objective C jest

A. XCode
B. Android Studio
C. React Native
D. NetBeans
XCode to środowisko, które faktycznie jest fundamentem tworzenia aplikacji na urządzenia Apple, czyli iPhone’y, iPady czy nawet MacBooki. Apple od lat inwestuje w rozwój XCode i właśnie tam programiści mogą budować zarówno aplikacje natywne, jak i np. gry – i to z wykorzystaniem różnych języków, takich jak Objective-C i Swift. Co ciekawe, dawniej używano też Objective-C prawie wyłącznie, ale od kilku lat Apple promuje Swift, bo jest nowocześniejszy i dużo przyjemniej się w nim pisze. Moim zdaniem XCode to taki niezbędnik – bez niego praktycznie nie da się pisać porządnych aplikacji na iOS czy macOS. Samo środowisko jest zintegrowane ze wszystkimi narzędziami Apple: symulatorem urządzeń, Interface Builderem do projektowania graficznego oraz narzędziami do debugowania i testowania. Z mojego doświadczenia, jak ktoś zaczyna przygodę z aplikacjami mobilnymi dla Apple, to właśnie XCode jest pierwszym programem, z którym spędzi dużo czasu. I trochę ułatwia życie, bo automatycznie konfiguruje projekty pod standardy Apple, nie trzeba nic ręcznie ustawiać. To też świetne miejsce do nauki, bo dokumentacja jest wprost wbudowana w środowisko. Co ważne, XCode jest wymagany, żeby wrzucić gotową aplikację do App Store – tak jest po prostu zrobiony ekosystem Apple i żadna alternatywa nie daje tyle integracji i wsparcia dla natywnych rozwiązań Apple.

Pytanie 12

Jakie znaczenie ma termin "przesłanianie metody" w kontekście programowania obiektowego?

A. Tworzenie nowej metody w klasie bazowej
B. Zastosowanie tej samej nazwy metody w klasie bazowej i pochodnej, ale z inną implementacją w klasie pochodnej
C. Zmiana metody prywatnej na metodę publiczną
D. Przenoszenie metod z jednej klasy do drugiej
Definiowanie nowej metody w klasie bazowej to zwykła deklaracja metody i nie jest to przesłanianie. Zamiana metody prywatnej na publiczną to zmiana modyfikatora dostępu, a nie przesłanianie. Kopiowanie metod z jednej klasy do innej nie jest związane z przesłanianiem – kopiowanie kodu narusza zasadę DRY (Don't Repeat Yourself) i jest rzadko stosowane w dobrze zaprojektowanych aplikacjach obiektowych.

Pytanie 13

Które z poniższych nie jest algorytmem sortowania?

A. Quick Sort
B. Merge Sort
C. Binary Search
D. Bubble Sort
Binary Search jest algorytmem, który służy do efektywnego przeszukiwania uporządkowanych zbiorów danych, a nie do sortowania. Działa na zasadzie dzielenia zbioru na pół i eliminowania połowy z nich w każdym kroku, co pozwala na szybkie znalezienie poszukiwanej wartości. Jest to przykład algorytmu o czasie działania O(log n), co sprawia, że jest znacznie szybszy od prostego przeszukiwania liniowego. Przykładowo, gdy mamy posortowaną tablicę liczb, Binary Search może być użyty do znalezienia konkretnej liczby, eliminując w każdym kroku połowę zbioru, aż do odnalezienia wartości lub stwierdzenia, że jej nie ma. W kontekście branżowym, Binary Search jest szeroko stosowany w różnych aplikacjach, gdzie wymagane jest szybkie przeszukiwanie danych, na przykład w bazach danych i aplikacjach wyszukiwania. Kluczowe jest zrozumienie różnicy między algorytmem przeszukiwania a algorytmem sortowania; sortowanie odnosi się do organizacji danych w określonym porządku, podczas gdy Binary Search koncentruje się na znajdowaniu elementów w już posortowanych zbiorach.

Pytanie 14

W aplikacji mobilnej, aby określić warianty grafiki w zależności od wielkości ekranu, należy (uwaga: odpowiedzi wariantowe dla dwóch systemów - sugerować się systemem omawianym na zajęciach)

A. iOS: dodać do nazw sufiksy #2x, #3x. Android: dodać do nazw sufiks rozdzielczości: -32x32, -64x64, -96x96
B. iOS: dodać do nazw plików sufiksy @2x, @3x. Android: umieścić grafikę w odpowiednich folderach drawable: -hdpi, -xhpi, xxhdpi
C. iOS: utworzyć katalogi hdpi, lhpi, xhpi i dodać do nich grafiki. Android: utworzyć katalogi 32x32, 64x64, 96x96 i dodać do nich grafiki
D. iOS: dodać do nazw sufiksy oznaczające rozdzielczość, np. 32ppi. Android: umieścić grafikę w odpowiednich katalogach: 32ppi, 64ppi, 96ppi
Lepiej nie używać oznaczeń w stylu 32ppi czy 64ppi, bo to nie pasuje do żadnej z tych platform. To bardziej pasuje do druku, a nie aplikacji mobilnych. Foldery 32x32 czy 64x64 też nie mają sensu w kontekście Androida czy iOS. Jak stworzysz foldery o nazwach lhpi czy 32x32 to może być problem z wyświetlaniem grafiki na różnych urządzeniach. Z mojego doświadczenia, lepiej trzymać się ustalonych standardów, żeby uniknąć błędów.

Pytanie 15

Które z poniższych twierdzeń najlepiej charakteryzuje metodę wirtualną?

A. Metoda, która może być wywoływana tylko przez klasę nadrzędną
B. Metoda, która działa wyłącznie dla statycznych pól danej klasy
C. Metoda, która może być przesłonięta w klasie dziedziczącej
D. Metoda, która jest zawsze stosowana w konstruktorach danej klasy
Wirtualna metoda to taka, która jest zdefiniowana w klasie bazowej i można ją nadpisać w klasie pochodnej. Fajna sprawa z tą metodą wirtualną jest taka, że działa na zasadzie dynamicznego wiązania, co w praktyce oznacza, że program decyduje w czasie działania, którą wersję metody wywołać. Dzięki temu mamy polimorfizm – możemy użyć różnych wersji tej samej metody, w zależności od typu obiektu, na którym pracujemy. To naprawdę ważny aspekt programowania obiektowego, bo pozwala na większą elastyczność i łatwiejsze rozwijanie kodu. W hierarchiach klas to się sprawdza, bo klasa bazowa ma ogólne metody, a klasy pochodne mogą je dostosować do swoich potrzeb.

Pytanie 16

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()
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 17

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

A. Dla tablicy uporządkowanej rosnąco
B. Dla tablicy uporządkowanej malejąco
C. Dla tablicy losowej
D. Dla tablicy z dużą liczbą powtórzeń
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 18

Który element HTML5 służy do osadzania wideo na stronie?

A. &lt;video&gt;
B. &lt;media&gt;
C. &lt;movie&gt;
D. &lt;player&gt;
Element HTML5 &lt;video&gt; jest standardowym tagiem służącym do osadzania wideo na stronach internetowych. Umożliwia on integrację multimediów w sposób, który jest zgodny z aktualnymi standardami sieciowymi. W porównaniu do starszych metod, które wymagały użycia zewnętrznych wtyczek, takich jak Flash, &lt;video&gt; pozwala na bezproblemowe odtwarzanie wideo w przeglądarkach nowej generacji, co zwiększa bezpieczeństwo i wydajność. Element ten oferuje wiele atrybutów, takich jak controls, autoplay, loop, preload, oraz width i height, które pozwalają na dostosowanie odtwarzacza do potrzeb użytkownika. Na przykład, używając atrybutu controls, można dodać przyciski odtwarzania, zatrzymywania lub regulacji głośności, co poprawia interaktywność i użyteczność. Dodatkowo, aby zapewnić dostępność treści wideo, warto stosować atrybuty takie jak &lt;track&gt;, który umożliwia dodawanie napisów, co jest szczególnie ważne dla osób z niepełnosprawnościami słuchowymi. Używanie &lt;video&gt; w projektach webowych to najlepsza praktyka, która wspiera rozwój dostępnych i przyjaznych dla użytkownika doświadczeń wizualnych.

Pytanie 19

Dziedziczenie jest używane, gdy zachodzi potrzeba

A. określenia zasięgu dostępności metod i pól danej klasy
B. wykorzystania stałych wartości, niezmieniających się w trakcie działania aplikacji
C. asynchronicznej realizacji długotrwałych zadań
D. sformułowania klasy bardziej szczegółowej niż już stworzona
Dziedziczenie to naprawdę jeden z kluczowych fundamentów programowania obiektowego. Chodzi tu o możliwość stworzenia nowej klasy (tzw. klasy pochodnej), która rozszerza lub precyzuje działanie już istniejącej klasy bazowej. Dzięki temu nie trzeba pisać wszystkiego od nowa – można po prostu przejąć cechy i zachowania ogólnej klasy, a potem dołożyć własne, bardziej szczegółowe funkcjonalności. Przykład? Klasa "Pojazd" może być ogólna, a potem robisz z niej "Samochód", "Rower" czy "Motocykl". Każda z tych klas dziedziczy podstawowe właściwości pojazdu (jak np. liczba kół), ale może mieć swoje dodatkowe pole czy metodę. W praktyce to pozwala na bardzo elastyczne i czytelne projektowanie kodu, no i łatwiejsze zarządzanie nim na dłuższą metę. Według większości standardów branżowych, np. w językach Java, C# czy C++, dziedziczenie jest zalecane właśnie wtedy, gdy chcesz odwzorować relację „jest rodzajem” (is-a). Z mojego doświadczenia, używanie dziedziczenia według tej zasady pozwala uniknąć wielu problemów z powielaniem kodu i z czasem naprawdę oszczędza mnóstwo roboty. Warto pamiętać, że nie wszystko należy dziedziczyć na siłę – czasem lepiej postawić na kompozycję, ale jeśli faktycznie potrzebujesz klasy bardziej szczegółowej, to dziedziczenie to chyba najlepszy wybór.

Pytanie 20

Przykład wywołania funkcji zamien w języku C++ może wyglądać w następujący sposób:

void zamien(int *a, int *b) {
    int tmp;
    tmp = *a;
    *a = *b;
    *b = tmp;
}
A. zamien(m, n); // m, n - zmienne całkowite
B. zamien(&a, &b); // a, b - zmienne całkowite
C. zamien(12, 34)
D. zamien(*a, *b); // a, b - zmienne całkowite
W tym przypadku wywołanie zamien(&a, &b); jest prawidłowe, bo funkcja zamien oczekuje wskaźników do zmiennych całkowitych, nie samych wartości tych zmiennych ani ich referencji. Przekazując adresy przez &a i &b, pozwalamy funkcji modyfikować oryginalne zmienne, a nie ich kopie. To jest fundament operacji wskaźnikowych w C++. Takie podejście umożliwia tzw. przekazywanie przez adres, które jest wykorzystywane wszędzie tam, gdzie trzeba w funkcji podmienić faktyczną zawartość zmiennej, a nie tylko jej kopię. W praktyce, na przykład podczas sortowania tablic czy zamiany miejscami dwóch wartości, korzysta się właśnie z takiego mechanizmu. Przekazywanie wskaźników jest bardzo uniwersalne – pozwala nie tylko zmieniać wartości, ale też np. przekazywać duże struktury bez kopiowania całej ich zawartości, co przyspiesza program i zmniejsza zużycie pamięci. Moim zdaniem warto też zauważyć, że użycie wskaźników jest jednym z filarów programowania na niskim poziomie w C i C++. Wielu początkujących programistów boi się wskaźników (nie wiem czemu, chyba przez te wszystkie historie o błędach i segfaultach), ale jak się już zrozumie, dlaczego i jak przekazywać adresy zmiennych, to potem dużo łatwiej korzystać z bardziej zaawansowanych mechanizmów np. dynamicznej alokacji pamięci czy tablic wskaźników. Standard C++ wręcz zaleca, by wszędzie tam, gdzie funkcja ma zmienić przekazane wartości, używać wskaźników lub referencji. W tym przypadku wskaźniki są idealne, bo dokładnie tego wymaga deklaracja funkcji. Dobrze jest też znać różnicę między przekazywaniem przez wartość, wskaźnik i referencję, bo to pozwala świadomie projektować interfejsy funkcji.

Pytanie 21

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

A. Obsługa logiki biznesowej i przetwarzanie danych wejściowych od użytkownika
B. Zarządzanie sesją użytkownika
C. Przechowywanie danych aplikacji
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 22

Który z wymienionych elementów stanowi przykład zbiorowej ochrony?

A. Kask ochronny
B. Ekran akustyczny
C. Okulary ochronne
D. Zatyczki do uszu
Ekran akustyczny to przykład środka ochrony zbiorowej, który redukuje poziom hałasu w miejscu pracy, chroniąc większą grupę pracowników jednocześnie. Środki ochrony zbiorowej mają na celu eliminowanie zagrożeń u źródła i zabezpieczanie całego środowiska pracy, a nie pojedynczych osób. Ekrany akustyczne są często stosowane w zakładach produkcyjnych, gdzie hałas maszyn może przekraczać dopuszczalne normy. Dzięki nim można zmniejszyć poziom hałasu i poprawić komfort pracy, bez konieczności wyposażania każdego pracownika w ochronniki słuchu. Środki ochrony zbiorowej są bardziej efektywne w długoterminowej perspektywie, ponieważ zmniejszają ryzyko dla wszystkich pracowników na danym stanowisku.

Pytanie 23

W jakim języku został stworzony framework Angular?

A. Postscript
B. PHP
C. C#
D. Typescript
Angular został stworzony w języku TypeScript, który to w sumie można uznać za rozszerzenie JavaScriptu – dodaje on typowanie statyczne i sporo udogodnień znanych z języków obiektowych. Moim zdaniem to był strzał w dziesiątkę, bo dzięki temu kod aplikacji Angular jest czytelniejszy, łatwiejszy w utrzymaniu i mniej podatny na takie typowe błędy, które się pojawiały w czystym JS. W praktyce, kiedy piszesz komponenty czy serwisy w Angularze, natychmiast korzystasz z silnych typów, interfejsów czy mechanizmów takich jak dekoratory. To nie tylko poprawia bezpieczeństwo kodu, ale też pomaga zespołom programistycznym lepiej się dogadywać i szybciej wdrażać nowe funkcjonalności. Przemysł poszedł tą drogą, bo TypeScript daje lepsze wsparcie narzędziowe, np. podpowiedzi w edytorach, refaktoryzację czy automatyczne wykrywanie błędów. Wbrew pozorom, nie jest trudno się przestawić z JS na TS – nawet dla osób, które programowały wcześniej tylko w czystym JavaScript. Poza tym, Angular to nie tylko framework do weba – aplikacje tworzone w TypeScript można kompilować na różne platformy, co jest już praktyką w dużych firmach. Takie podejście wpisuje się w obecne trendy w branży, gdzie typowanie i czytelność kodu to podstawa.

Pytanie 24

Co to jest lazy loading?

A. Metoda przechowywania danych w pamięci podręcznej przeglądarki
B. Algorytm kompresji obrazów w aplikacjach webowych
C. Proces opóźnionego ładowania bibliotek JavaScript
D. Technika optymalizacji polegająca na ładowaniu zasobów dopiero wtedy, gdy są potrzebne
Odpowiedź wskazująca na technikę optymalizacji polegającą na ładowaniu zasobów dopiero wtedy, gdy są one potrzebne, jest prawidłowa, ponieważ lazy loading skutecznie zwiększa wydajność aplikacji webowych. Ta metoda minimalizuje ilość danych przesyłanych na początku ładowania strony, co znacząco poprawia czas ładowania oraz doświadczenie użytkownika. Przykładowo, w przypadku stron z dużą ilością obrazów, lazy loading zapewnia, że grafiki są pobierane tylko wtedy, gdy zbliżają się do obszaru widocznego w przeglądarce. To podejście jest zgodne z najlepszymi praktykami optymalizacji wydajności, jak określone w dokumentach Web Performance Optimization. W praktyce często implementuje się lazy loading za pomocą różnych bibliotek JavaScript, takich jak Intersection Observer API, co pozwala na efektywne zarządzanie zasobami oraz ich asynchroniczne ładowanie. Dzięki temu aplikacje mogą działać bardziej responsywnie, co jest kluczowe w czasie, gdy użytkownicy oczekują szybkiej oraz płynnej interakcji ze stronami internetowymi.

Pytanie 25

W przedstawionej ramce znajduje się fragment opisu metody compile języka Java wykorzystywanej w kontekście wyrażeń regularnych. Który symbol powinien być użyty, aby znaleźć dopasowanie na końcu tekstu?

MetacharacterDescription
|Find a match for any one of the patterns separated by | as in: cat|dog|fish
.Find just one instance of any character
^Finds a match as the beginning of a string as in: ^Hello
$Finds a match at the end of the string as in: World$
\dFind a digit
\sFind a whitespace character
\bFind a match at the beginning of a word like this: \bWORD, or at the end of a word like this: WORD\b
\uxxxxFind the Unicode character specified by the hexadecimal number xxxx
Źródło https://www.w3schools.com/java/java_regex.asp dostęp 20.08.2020
A. |
B. ^
C. .
D. $
Znak dolara $ w wyrażeniach regularnych w języku Java jest używany do oznaczenia końca ciągu znaków. Jeśli chcemy sprawdzić, czy konkretny wzorzec występuje na końcu danego tekstu, używamy właśnie tego metaznaku. Przykładowo, wyrażenie regularne World$ dopasuje tekst, w którym słowo World pojawia się na samym końcu. Jest to przydatne w wielu scenariuszach, takich jak walidacja struktury tekstu czy filtrowanie logów, gdzie ważna jest pozycja występowania wzorca. Konwencja ta jest zgodna z ogólnymi standardami regex, co czyni ją intuicyjną i uniwersalną w zastosowaniu. Dolar pełni kluczową rolę w automatyzacji procesów w przetwarzaniu tekstu, umożliwiając efektywne dopasowywanie końcowych wzorców w aplikacjach Java. Użycie $ jest zgodne z dobrymi praktykami kodowania, szczególnie w kontekście walidacji danych wejściowych, gdzie określenie końca ciągu jest często wymagane. Jest to także popularne w analizie danych, gdzie dane muszą spełniać określone kryteria co do ich zakończenia, takie jak rozszerzenia plików czy określone etykiety tekstowe.

Pytanie 26

Który algorytm sortowania opiera się na metodzie "dziel i zwyciężaj"?

A. Sortowanie bąbelkowe
B. Sortowanie szybkie (QuickSort)
C. Sortowanie przez wybór
D. Sortowanie przez wstawianie
QuickSort to algorytm sortowania wykorzystujący podejście 'dziel i zwyciężaj', co oznacza, że dzieli tablicę na mniejsze części wokół elementu zwanego pivotem, a następnie rekurencyjnie sortuje każdą z tych części. Ta strategia pozwala na efektywne sortowanie dużych zbiorów danych w czasie O(n log n) w większości przypadków. Dziel i zwyciężaj to potężne narzędzie algorytmiczne, które znajduje zastosowanie w wielu innych algorytmach, takich jak Merge Sort i algorytmy wyszukiwania binarnego. QuickSort jest często używany w aplikacjach wymagających szybkiego przetwarzania dużych ilości danych.

Pytanie 27

W jakim celu wykorzystuje się diagram Gantta?

A. do wizualizacji powiązań między elementami systemów
B. do planowania i zarządzania projektem
C. do przedstawiania funkcjonalności systemu
D. do dokładnej analizy czasowo-kosztowej projektu
Diagram Gantta to jeden z podstawowych i – moim zdaniem – najfajniejszych narzędzi używanych w zarządzaniu projektami, zwłaszcza w budowlance, IT czy produkcji. Jest bardzo praktyczny, bo pozwala wizualnie rozplanować, jakie zadania są do wykonania, ile mają trwać i co od czego zależy. Dzięki prostemu układowi poziomych pasków na osi czasu można szybko ogarnąć całość projektu, zobaczyć które zadania się pokrywają i gdzie mogą być wąskie gardła. Branżowe standardy, np. PMBOK, zalecają korzystanie z diagramu Gantta właśnie do planowania i monitorowania postępu. Z mojego doświadczenia to narzędzie, które łączy ludzi – wszyscy od razu widzą, kto co robi i na kiedy. Fajne jest też to, że łatwo aktualizować taki diagram w miarę zmian w projekcie. Diagram Gantta pomaga też w kontroli terminowości i identyfikacji opóźnień. Jeśli ktoś kiedyś miał styczność z programami jak MS Project czy nawet prostym Excelem – na pewno widział taki wykres. Można tam nawet dodać kamienie milowe czy zależności między zadaniami (np. jedno musi się skończyć, zanim drugie się zacznie). Tak naprawdę, w profesjonalnych firmach, zarządzanie projektem bez takiego narzędzia byłoby trochę strzałem w stopę.

Pytanie 28

Jakie jest zadanie interpretera?

A. wykonywanie skryptu krok po kroku
B. tłumaczenie kodu na kod maszynowy
C. analiza składni całego programu przed jego uruchomieniem
D. optymalizacja większej części kodu, aby przyspieszyć jego wykonanie
Interpreter to takie narzędzie, które wykonuje kod linijka po linijce. Działa to tak, że odczytuje program napisany w języku wysokiego poziomu, weryfikuje co tam w nim siedzi i od razu realizuje polecenia, co sprawia, że można fajnie testować kod. Na przykład w Pythonie można łatwo sprawdzić różne fragmenty kodu, co jest mega pomocne przy pisaniu i poprawianiu oprogramowania. Wiesz, od kompilatora różni się tym, że kompilator przetwarza cały kod od razu, tworząc kod maszynowy, który później działa na komputerze. Dzięki temu interpreter jest bardziej elastyczny, można szybko przetestować nowe pomysły, ale z drugiej strony, czasami nie działa tak efektywnie jak skompilowane programy, bo każda linia kodu jest analizowana na bieżąco. Więc w przypadku dużych i wymagających aplikacji lepiej sprawdzają się kompilatory, ale interpreter to skarb, zwłaszcza w nauce i prototypowaniu.

Pytanie 29

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. przez wybór
B. bąbelkowe
C. przez wstawianie
D. szybkie (Quicksort)
Opis w pytaniu jednoznacznie wskazuje na sortowanie bąbelkowe, a nie szybkie (quicksort), przez wybór czy przez wstawianie. Wiele osób daje się zwieść terminologii lub myli charakterystyczne cechy poszczególnych algorytmów, bo przecież wszystkie mają na celu uporządkowanie danych. Jeśli chodzi o quicksort, to działa on zupełnie inaczej – opiera się na wyborze tzw. pivota (elementu głównego), a następnie dzieli tablicę na dwie części: mniejsze i większe od tego elementu. Proces ten jest rekurencyjny i nie polega na cyklicznym porównywaniu jedynie sąsiadujących elementów, tylko na podziale i sortowaniu podtablic. Z mojego doświadczenia wynika, że quicksort jest znacznie wydajniejszy (średnio O(n log n)), ale już implementacyjnie bardziej złożony. Z kolei sortowanie przez wybór (selection sort) polega na znajdowaniu na każdym przebiegu najmniejszego (lub największego) elementu i umieszczaniu go na właściwej pozycji. Nie ma tu zamiany sąsiadujących elementów w kółko – to raczej systematyczne przesuwanie wybranego elementu do przodu zbioru. Sortowanie przez wstawianie (insertion sort) przypomina układanie kart – bierzesz kolejne elementy i wstawiasz je w odpowiednie miejsce w już częściowo posortowanej liście. Tutaj znowu nie chodzi o ciągłe zamienianie miejscami sąsiednich elementów podczas każdego przebiegu, tylko o przesuwanie elementów do przodu aż do znalezienia właściwej pozycji. Typowym błędem jest sugerowanie się słowem „prosta metoda” i mylenie jej z insertion sort, bo oba algorytmy są faktycznie czytelne, ale sposób działania mają kompletnie inny. Branżowe dobre praktyki podpowiadają, by dobrać algorytm do konkretnego problemu – bąbelkowy przydaje się do pokazania podstaw, ale rzadko bywa praktyczny przy dużych zbiorach. Dlatego dokładne czytanie opisu i rozróżnianie tych subtelnych różnic w działaniu algorytmów jest bardzo ważne, szczególnie przy zadaniach rekrutacyjnych czy na egzaminach zawodowych.

Pytanie 30

Która z poniższych deklaracji w języku C++ poprawnie opisuje tablicę dwuwymiarową?

A. int matrix[3][3][3];
B. int matrix[];
C. int matrix[3];
D. int matrix[3][3];
Deklaracja 'int matrix[3][3];' poprawnie definiuje tablicę dwuwymiarową w języku C++. Tablice dwuwymiarowe to kluczowe narzędzie do przechowywania macierzy i danych tabelarycznych. Każdy element macierzy jest dostępny poprzez dwa indeksy, co umożliwia łatwe odwzorowanie układów współrzędnych lub plansz w grach. Tablice tego rodzaju są wykorzystywane w algorytmach obliczeniowych, grafice komputerowej oraz analizie danych. Struktura 'matrix[3][3]' tworzy siatkę 3x3, która może przechowywać 9 elementów, co czyni ją efektywnym rozwiązaniem dla problemów wymagających przestrzennych danych.

Pytanie 31

Jakie zdarzenie jest wywoływane, gdy kliknięta zostaje myszą nieaktywna kontrolka lub okno?

A. validating
B. focus
C. keyup
D. blur
W momencie, kiedy klikamy na nieaktywną kontrolkę lub okno w aplikacji, wywoływane jest zdarzenie focus. To jest dość kluczowe w interakcji człowieka z interfejsem graficznym — focus decyduje, która kontrolka staje się „aktywnym” odbiorcą zdarzeń klawiatury oraz innych operacji wejścia. W praktyce, np. w aplikacjach webowych czy desktopowych, jeśli użytkownik kliknie w pole tekstowe, to właśnie focus oznacza, że to pole jest gotowe do przyjęcia tekstu. Co ciekawe, focus można też ustawiać programowo, np. za pomocą metody focus() w JavaScript, co jest często używane do poprawiania użyteczności formularzy (od razu ustawiamy kursor w pierwszym polu). Z mojego doświadczenia, dobrze jest zawsze przemyśleć, które elementy mogą i powinny otrzymywać focus, bo to wpływa na dostępność (ang. accessibility) aplikacji – osoby korzystające z klawiatury czy czytników ekranu są bardzo zależne od logiki focusowania. Branżowe standardy, szczególnie WCAG, mocno podkreślają, żeby nie blokować możliwości uzyskania focusa przez kluczowe kontrolki. Zdarzenie focus ma też kilka niuansów – na przykład nie bąbelkuje w DOM, co czasem zaskakuje początkujących. Moim zdaniem, zrozumienie roli focus w każdej aplikacji interaktywnej to taki absolutny fundament, bez którego łatwo pogubić się w późniejszych, bardziej złożonych interakcjach.

Pytanie 32

Zaprezentowany diagram Gantta odnosi się do projektu IT. Przy założeniu, że każdy członek zespołu dysponuje wystarczającymi umiejętnościami do realizacji każdego z zadań oraz że do każdego zadania można przypisać jedynie jedną osobę, która poświęci na zadanie pełny dzień pracy, to minimalna liczba członków zespołu powinna wynosić:

Ilustracja do pytania
A. 5 osób
B. 2 osoby
C. 1 osobę
D. 4 osoby
Wybrana odpowiedź jest trafna, bo minimalna liczba członków zespołu wynosi właśnie 2 osoby. W projekcie przedstawionym na diagramie Gantta, kluczowe jest zwrócenie uwagi na to, ile zadań nakłada się w danym tygodniu – a nie łączna liczba zadań. Największe obciążenie zespołu wypada na okresy, gdzie równolegle realizowane są dwa zadania, np. w pierwszym tygodniu są to Projekt aplikacji i Grafika, później w ostatnim tygodniu dwie aplikacje: front-end i back-end. W żadnym momencie nie występuje potrzeba, by więcej niż dwie osoby pracowały równolegle nad różnymi zadaniami. To bardzo praktyczna sytuacja – w realnych projektach IT planuje się obłożenie pracą właśnie przez analizę diagramu Gantta, by nie generować sztucznego przestoju lub nadmiaru ludzi. Moim zdaniem taka optymalizacja zespołu to podstawa w IT, bo pozwala ograniczyć koszty i lepiej zarządzać zasobami. Warto pamiętać, że zgodnie z dobrymi praktykami zarządzania projektami, np. w metodykach PMBOK czy Prince2, zawsze analizuje się ścieżki krytyczne i równoległość zadań, dokładnie w taki sposób, żeby nie dublować niepotrzebnie rąk do pracy. Świetnie, jeśli już na etapie planowania potrafisz to zauważyć i wyciągnąć praktyczne wnioski – to naprawdę przydaje się potem przy rozpisywaniu harmonogramów na czasach rzeczywistych projektów.

Pytanie 33

Jaki będzie wynik działania poniższego kodu w języku Python?

def fun(x, l=[]):
    l.append(x)
    return l

print(fun(1))
print(fun(2))
print(fun(3, []))
print(fun(4))
A. [1], [2], [3], [4]
B. [1], [1, 2], [3], [1, 2, 4]
C. [1], [2], [3], [4, 3]
D. [1], [1, 2], [3], [3, 4]
Wybór błędnych odpowiedzi często wynika z niewłaściwego zrozumienia działania domyślnych argumentów funkcji w Pythonie. Przykładowo, stwierdzenie, że drugi wynik to [2], a czwarty to [4], pokazuje, że nie uwzględniono, iż domyślna lista 'l' nie jest tworzona od nowa przy każdym wywołaniu funkcji. W Pythonie, jeśli nie podasz innej listy, wszystkie wywołania funkcji dzielą się tą samą referencją do oryginalnej listy, co prowadzi do sytuacji, w której dodawane są nowe elementy do już istniejącej listy. Właśnie dlatego drugi wynik to [1, 2], a nie [2], ponieważ element 1 został dodany do tej samej listy. Przy trzecim wywołaniu funkcji, gdy przekazujemy pustą listę, rzeczywiście otrzymujemy [3], ale czwarty wynik znowu odnosi się do listy, która zawiera już elementy 1 i 2. Z tego powodu, wynik to [1, 2, 4] zamiast [4]. Warto zwrócić uwagę, że typowe błędy w myśleniu często prowadzą do uproszczeń, które mogą zakłócać zrozumienie bardziej złożonych koncepcji, takich jak zarządzanie pamięcią i zmiennymi lokalnymi versus globalnymi. Ostatecznie, znajomość zasad działania domyślnych argumentów w Pythonie jest kluczowa w praktycznym programowaniu, ponieważ pozwala unikać nieoczekiwanych zachowań w kodzie.

Pytanie 34

Które z wymienionych zastosowań najlepiej definiuje bibliotekę jQuery?

A. Budowanie aplikacji mobilnych
B. Projektowanie struktur baz danych
C. Tworzenie interfejsów w programach desktopowych
D. Ułatwienie manipulacji DOM oraz obsługi zdarzeń w JavaScript
jQuery to popularna biblioteka JavaScript, która ułatwia manipulację DOM (Document Object Model), obsługę zdarzeń oraz wykonywanie animacji na stronach internetowych. Dzięki jQuery programiści mogą znacznie skrócić ilość kodu potrzebnego do realizacji operacji na elementach HTML. Biblioteka ta zapewnia również wygodny sposób na wykonywanie asynchronicznych żądań HTTP (AJAX), co pozwala na dynamiczne pobieranie danych z serwera bez konieczności przeładowywania całej strony. jQuery jest szeroko stosowane w projektach, które wymagają interaktywności oraz lekkich efektów wizualnych. Choć w ostatnich latach jego popularność spadła na rzecz bardziej zaawansowanych frameworków takich jak React czy Angular, jQuery nadal jest cenione za prostotę, wydajność oraz bogaty ekosystem gotowych wtyczek i rozszerzeń.

Pytanie 35

W metodach klasy GoldCustomer dostępne są tylko pola

public class Customer {
    public string Name;
    protected int Id;
    private int Age;
}
public class GoldCustomer: Customer {
    private GoldPoints: int;
}
A. GoldPoints, Name, Id, Age
B. GoldPoints, Name, Id
C. GoldPoints, Name
D. GoldPoints
Ta odpowiedź dobrze pokazuje, jak działa dziedziczenie i modyfikatory dostępu w C#. W klasie GoldCustomer masz dostęp do własnych pól, czyli GoldPoints, oraz do pól odziedziczonych po klasie bazowej Customer. Tutaj kluczowe jest rozumienie, które pola są faktycznie dostępne. Skoro Name jest publiczne, to bez żadnych kombinacji można się do niego dobrać z dowolnego miejsca – nawet spoza klasy. Id jest chronione (protected), więc według zasad OOP dostępne jest w klasie bazowej oraz wszystkich pochodnych – czyli właśnie w GoldCustomer. To bardzo praktyczne, bo często się zdarza, że potrzebujemy pracować na polach z klasy bazowej, ale nie chcemy, żeby były one widoczne na zewnątrz klasy (np. przez innych programistów korzystających z API). Age jest prywatne i tu już nie da się go bezpośrednio użyć w klasie pochodnej. Z mojego doświadczenia korzystanie z protected dla rzeczy, które mają być dostępne tylko w hierarchii dziedziczenia, to codzienność – pozwala zachować elastyczność, ale i bezpieczeństwo enkapsulacji. Praktycznie rzecz biorąc, jak piszesz klasy dziedziczące po innych, zawsze warto zerknąć na poziomy dostępu, bo od nich zależy, do czego masz dostęp i co możesz odziedziczyć. Wzorce projektowe, jak np. Template Method, mocno polegają na mechanizmach dziedziczenia i odpowiedniego ustawienia widoczności pól czy metod. Przemyślany dobór public, protected, private ułatwia utrzymanie kodu oraz chroni przed przypadkowym wykorzystaniem nieodpowiednich elementów klasy, co w większych projektach bywa naprawdę kluczowe.

Pytanie 36

Co to jest CI/CD w kontekście rozwoju oprogramowania?

A. Ciągła integracja i ciągłe dostarczanie - praktyki automatyzujące proces wdrażania kodu
B. Component Isolation/Component Deployment - izolacja i wdrażanie komponentów aplikacji
C. Customer Interface/Customer Design - projektowanie interfejsów zorientowane na klienta
D. Code Implementation/Code Delivery - metodyka implementacji i dostarczania kodu
CI/CD, czyli ciągła integracja i ciągłe dostarczanie, to zbiór praktyk i narzędzi stosowanych w rozwoju oprogramowania w celu automatyzacji procesów budowy, testowania i wdrażania aplikacji. CI polega na regularnym integrowaniu kodu do wspólnego repozytorium, co pozwala na wczesne wykrywanie błędów i konfliktów. Umożliwia to zespołom deweloperskim wykrywanie problemów w kodzie na wczesnym etapie, co znacząco przyspiesza cykl rozwoju. CD natomiast odnosi się do automatyzacji procesu wdrażania aplikacji na środowiska produkcyjne, co minimalizuje czas potrzebny na dostarczenie nowych funkcji do użytkowników. Przykłady praktycznego zastosowania CI/CD obejmują użycie narzędzi takich jak Jenkins, GitLab CI, czy CircleCI, które umożliwiają automatyczne uruchamianie testów oraz wdrażanie aplikacji na różnych platformach. Dobre praktyki w CI/CD obejmują tworzenie małych i częstych aktualizacji, co pozwala na łatwiejsze zarządzanie projektami i szybsze reagowanie na potrzeby klientów.

Pytanie 37

Co to jest JWT (JSON Web Token)?

A. Biblioteka JavaScript do manipulacji danymi JSON
B. Otwarty standard do bezpiecznego przekazywania danych w formacie JSON
C. Format kompresji danych JavaScript i HTML w aplikacjach webowych
D. Protokół transferu plików JSON między serwerami
JWT (JSON Web Token) to otwarty standard, który pozwala na bezpieczne przesyłanie danych między stronami jako obiekt JSON. Token ten składa się z trzech części: nagłówka (header), ładunku (payload) oraz podpisu (signature). Nagłówek określa typ tokenu i używany algorytm szyfrowania, ładunek zawiera dane, które chcemy przekazać, a podpis zapewnia integralność i autentyczność danych. JWT jest powszechnie wykorzystywany w autoryzacji i wymianie informacji między serwerem a klientem, na przykład w aplikacjach webowych, gdzie po zalogowaniu użytkownik otrzymuje token, który może być użyty do uzyskania dostępu do chronionych zasobów. Dzięki temu mechanizmowi, serwer nie musi przechowywać sesji, co zwiększa jego wydajność. Ważnym aspektem JWT jest jego bezstanowość oraz możliwość łatwego skalowania aplikacji, co czyni go popularnym rozwiązaniem w architekturze mikroserwisów. Dobrą praktyką jest stosowanie JWT w połączeniu z HTTPS, aby zapewnić dodatkową warstwę bezpieczeństwa przy przesyłaniu tokenów.

Pytanie 38

Przedstawiony na filmie kod napisany w języku C++ nie kompiluje się. Co należy zmienić w tym kodzie, aby proces kompilacji wykonał się bez błędów?

A. poprawnie zapisać warunek w instrukcji if w linii 11, np. sprawdz(x)==true
B. zadeklarować zmienną sprawdz przed jej wykorzystaniem w linii 11
C. dodać deklarację funkcji sprawdz przed funkcją main
D. naprawić błąd w funkcji sprawdz, który polega na braku nawiasów {} w pętli for
Odpowiedź jest trafna, bo w języku C++ kompilator musi wiedzieć o istnieniu funkcji zanim zostanie ona użyta w kodzie, np. w funkcji main. Bez wcześniejszej deklaracji, kompilator nie zna sygnatury funkcji i nie potrafi zweryfikować wywołania, co skutkuje błędem typu 'implicit declaration of function'. Deklaracja funkcji to taki sygnał informujący kompilator „hej, taka funkcja będzie i będzie przyjmować takie argumenty, a zwracać taki typ”. Praktycznie rzecz biorąc, przed funkcją main wystarczy wpisać np. 'bool sprawdz(int x);', żeby wszystko grało. To szczególnie ważne przy większych projektach czy pracy w zespołach, gdzie pliki nagłówkowe z deklaracjami funkcji są standardem. Pozwala to na lepszą czytelność i porządek w kodzie – kompilator wie, czego się spodziewać, a Ty unikasz dziwnych, trudnych do znalezienia błędów. Moim zdaniem taka organizacja kodu to podstawa, szczególnie jeśli kiedyś będziesz korzystać z bibliotek lub cudzych funkcji – deklaracje są wtedy wręcz obowiązkowe. To zasada, której trzyma się większość zespołów programistycznych i, szczerze mówiąc, sam kilka razy w młodości zapomniałem o deklaracji, przez co debugowanie trwało wieki. Warto od razu wyrobić sobie taki nawyk, bo to oszczędza sporo nerwów i czasu, a kod staje się solidniejszy i bardziej profesjonalny.

Pytanie 39

Jaką rolę pełni element statyczny w klasie?

A. Zachowuje wspólną wartość dla wszystkich instancji tej klasy
B. Pozwala na dynamiczne dodawanie nowych metod
C. Ogranicza dostęp do metod publicznych w klasie
D. Automatycznie likwiduje obiekty klasy po zakończeniu działania programu
Składnik statyczny klasy przechowuje wartości współdzielone przez wszystkie obiekty tej klasy. Jest to jedno z najbardziej efektywnych narzędzi w programowaniu obiektowym, pozwalające na ograniczenie zużycia pamięci oraz zapewnienie spójności danych. Główna rola składnika statycznego polega na utrzymaniu jednej kopii zmiennej lub metody, która jest dostępna niezależnie od liczby instancji klasy. To oznacza, że zmiana wartości składowej statycznej jest natychmiast widoczna dla wszystkich obiektów klasy. Przykładem jest licznik instancji klasy lub konfiguracja globalna aplikacji, gdzie statyczność pozwala na scentralizowanie danych i ich jednolite zarządzanie.

Pytanie 40

Z jakiej kolekcji powinno się korzystać, aby przechowywać informacje związane z elementem interfejsu użytkownika w taki sposób, aby ten element był informowany przez kolekcję o dodaniu, usunięciu lub zmianie jej zawartości?

A. Collection
B. ReadOnlyCollection
C. ObservableCollection
D. KeyedCollection
ObservableCollection to zdecydowanie najlepszy wybór w sytuacji, gdy zachodzi potrzeba powiadamiania elementów interfejsu użytkownika o zmianach w kolekcji. W praktyce, kiedy pracujesz np. z WPF, UWP albo MAUI, to ObservableCollection automatycznie informuje UI o dodaniu, usunięciu czy modyfikacji elementów. Wszystko dzięki temu, że implementuje interfejs INotifyCollectionChanged. Moim zdaniem praktyczne zastosowanie jest mega – gdy masz np. listę produktów, która wyświetla się użytkownikowi, to po prostu dokładasz lub usuwasz elementy z ObservableCollection i nie musisz ręcznie odświeżać widoku. Framework sam ogarnia powiązanie danych, bo kolekcja emituje zdarzenia CollectionChanged. Takie podejście jest spójne z zasadami MVVM i ogólnie promowane przez Microsoft w oficjalnych dokumentacjach. Często spotkać można rozwiązania, gdzie ktoś używa zwykłej List lub Collection, ale wtedy tracisz te automatyczne powiadomienia i pojawia się masa kodu-boilerplate. Szczerze mówiąc, nie widzę sensu kombinować z innymi kolekcjami, jeśli zależy Ci na dynamicznym, responsywnym UI. ObservableCollection to po prostu standard branżowy w .NET, jak dla mnie nie ma lepszej opcji na takie zastosowania.