Wyniki egzaminu

Informacje o egzaminie:
  • Zawód: Technik programista
  • Kwalifikacja: INF.04 - Projektowanie, programowanie i testowanie aplikacji
  • Data rozpoczęcia: 29 kwietnia 2026 17:49
  • Data zakończenia: 29 kwietnia 2026 18:04

Egzamin zdany!

Wynik: 29/40 punktów (72,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

Który z wymienionych elementów można zdefiniować jako psychofizyczny?

A. Stres i monotonia pracy
B. Nadmiar światła w miejscu pracy
C. Promieniowanie elektromagnetyczne
D. Zanieczyszczenie powietrza
Czynniki psychofizyczne w środowisku pracy obejmują takie elementy jak stres, monotonia pracy oraz nadmierne obciążenie organizmu. Są to zagrożenia, które mogą prowadzić do wypalenia zawodowego, depresji, spadku koncentracji i zwiększonego ryzyka popełniania błędów. Stres i monotonia pracy to jedne z najczęstszych psychofizycznych zagrożeń, które mogą wpływać nie tylko na zdrowie psychiczne, ale również na fizyczne samopoczucie pracownika. W celu ich minimalizacji organizacje wdrażają programy wsparcia psychologicznego, zapewniają przerwy, rotację obowiązków i dbają o dobrą atmosferę w pracy. Kluczowe jest także odpowiednie zarządzanie czasem pracy i eliminowanie monotonnych zadań na rzecz bardziej zróżnicowanych obowiązków.

Pytanie 2

W systemie RGB kolor Pale Green przedstawia się jako RGB(152, 251, 152). Jaki jest szesnastkowy kod tego koloru?

A. 98FB98
B. 98 FE98
C. AO FE AO
D. AO FB AO
Kolor Pale Green w systemie RGB jest reprezentowany przez wartości RGB(152, 251, 152). Aby przekształcić te wartości na format szesnastkowy, należy każdy z komponentów koloru (czerwony, zielony, niebieski) przekształcić na format heksadecymalny. Wartość 152 w systemie dziesiętnym odpowiada 98 w systemie szesnastkowym, a 251 w systemie dziesiętnym odpowiada FE w systemie szesnastkowym. Dlatego, łącząc te wartości w kolejności od komponentu czerwonego, zielonego, do niebieskiego, uzyskujemy kod szesnastkowy 98FE98. Kod ten może być używany w projektach graficznych oraz w CSS do definiowania kolorów tła, tekstów i innych elementów. Użycie formatu szesnastkowego w projektowaniu stron internetowych oraz w aplikacjach jest zgodne z zasadami standardu W3C dotyczącego kolorów w HTML i CSS, co zapewnia spójność wizualną i ułatwia pracę z kolorami.

Pytanie 3

Aplikacje webowe stworzone z użyciem frameworka Angular lub biblioteki React, działające na standardowych portach, można uruchomić na lokalnym serwerze, wpisując w przeglądarkę

A. localhost:8000 (React) lub localhost:49887 (Angular)
B. localhost:5001 (React) lub localhost:8080 (Angular)
C. localhost:8080 (React) lub localhost:8000 (Angular)
D. localhost:3000 (React) lub localhost:4200 (Angular)
React domyślnie startuje na porcie 3000, a Angular na 4200 – to są takie standardy, które praktycznie wszyscy w branży znają i stosują. Kiedy zaczynasz nowy projekt w React, korzystając na przykład z create-react-app, serwer deweloperski po prostu nasłuchuje na http://localhost:3000. Analogicznie, jak generujesz projekt w Angular CLI i odpalasz ng serve, wtedy aplikacja wystartuje na http://localhost:4200. To są domyślne porty – nie musisz nic specjalnie ustawiać, wystarczy wpisać te adresy w przeglądarce. Z mojego doświadczenia, dobrze jest zapamiętać te ustawienia, bo praktycznie na każdym warsztacie czy bootcampie te adresy padają od ręki. Jeśli chodzi o praktykę, czasami port jest już zajęty i wtedy narzędzie zaproponuje inny, ale te wartości startowe to taka baza. Warto pamiętać, że zmiana portu wynika zazwyczaj z konfliktu, a nie z jakiejś specjalnej potrzeby. Dodatkowo, rozpoznanie tych portów pozwala szybciej debugować problemy z uruchomieniem aplikacji – jak coś nie wstaje na tych adresach, to od razu wiadomo, gdzie szukać. Ogólnie rzecz biorąc, korzystanie z tych domyślnych portów przyspiesza współpracę w zespole, bo każdy wie, gdzie szukać aplikacji, więc nie trzeba się rozpisywać w README, na jakim porcie coś działa. Moim zdaniem, to jeden z tych drobnych szczegółów, które składają się na dobre nawyki programistyczne.

Pytanie 4

Programista tworzy system zarządzania buforem drukowania dokumentów. Najnowsze zlecenie drukowania dodawane jest na koniec kolejki, a najstarsze z nich są przekazywane do drukarki. Jaką strukturę danych najłatwiej zastosować w tej sytuacji?

A. Sterta
B. FIFO
C. LIFO
D. Stos
Stos (LIFO - Last In, First Out) działa odwrotnie – najnowsze zadanie jest przetwarzane jako pierwsze, co nie odpowiada kolejności drukowania. Sterta to inna struktura danych używana głównie do dynamicznej alokacji pamięci, a nie do zarządzania kolejkami zadań. LIFO nie nadaje się do implementacji kolejki wydruku, ponieważ najstarsze zadania mogą pozostawać nieprzetworzone, co prowadzi do nieefektywności i dezorganizacji procesów drukowania.

Pytanie 5

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

let i = 0;
while (i < 5) {
  i++;
  if (i === 3) continue;
  console.log(i);
}
A. 1, 2, 3, 4, 5
B. 0, 1, 2, 4, 5
C. 1, 2, 4, 5
D. 0, 1, 2, 3, 4
W przedstawionym kodzie mamy do czynienia z pętlą while, która działa, dopóki zmienna i jest mniejsza od 5. Na początku i jest równe 0, a w każdej iteracji pętli i jest zwiększane o 1. Wewnątrz pętli mamy warunek, który sprawdza, czy i jest równe 3. Jeżeli tak, to używamy instrukcji continue, co oznacza, że pomijamy resztę kodu w tej iteracji i wracamy do początku pętli. Przeanalizujmy, co się stanie w kolejnych iteracjach: w pierwszej iteracji i jest 1, więc wypisujemy 1, w drugiej iteracji i jest 2, więc wypisujemy 2. Gdy i osiąga 3, warunek if jest spełniony i przechodzimy do następnej iteracji, nie wypisując nic. Następnie i staje się 4 i 5, które również są wypisywane. W efekcie na konsoli zostanie wypisane 1, 2, 4, 5. Takie podejście pokazuje, jak ważne jest zrozumienie działania pętli i instrukcji sterujących w JavaScript, co jest kluczowe w programowaniu i pozwala na efektywne zarządzanie przepływem kodu.

Pytanie 6

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

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

Pytanie 7

Który z wymienionych elementów może stanowić część menu w aplikacji desktopowej?

A. Canvas
B. ScrollBar
C. CheckBox
D. MenuItem
MenuItem to podstawowy komponent, który stanowi część systemu menu w aplikacjach desktopowych. Jest to element, który pojawia się w rozwijanym menu i pozwala na wykonywanie określonych akcji, takich jak otwieranie plików, zapisywanie danych czy wywoływanie funkcji aplikacji. MenuItem jest szeroko stosowany w aplikacjach Windows w połączeniu z WPF i WinForms. Tworzenie strukturalnego menu, które ułatwia nawigację po aplikacji, jest kluczowe dla zapewnienia dobrej użyteczności i intuicyjności oprogramowania.

Pytanie 8

Wartość liczby 1AF, zapisana w systemie szesnastkowym, po przeliczeniu na system dziesiętny wynosi

A. 257
B. 6890
C. 26
D. 431
Słuchaj, liczba szesnastkowa 1AF to w systemie dziesiętnym 431. Przeliczenie robimy tak: (1 * 16^2) + (10 * 16^1) + (15 * 16^0). To jest jedna z podstawowych rzeczy, które musisz znać przy konwersji liczb. Szczególnie przydaje się to w programowaniu i ogólnie w informatyce, gdzie często mamy do czynienia z różnymi systemami liczbowymi.

Pytanie 9

Który z podanych terminów najlepiej odnosi się do składnika statycznego w klasie?

A. Metoda z dostępem ograniczonym tylko do tej samej klasy
B. Zmienna lokalna wewnątrz danej klasy
C. Funkcja, która wywołuje destruktor danej klasy
D. Pole lub metoda, która jest przypisana do klasy, a nie do jej instancji
Składnik statyczny klasy to pole lub metoda, która należy do klasy jako całości, a nie do konkretnego obiektu. Oznacza to, że istnieje tylko jedna kopia składnika statycznego współdzielona przez wszystkie obiekty tej klasy. Przykład w C++: `class Licznik { public: static int liczbaObiektow; }`. Zmienna `liczbaObiektow` przechowuje liczbę utworzonych instancji klasy i jest wspólna dla wszystkich obiektów. Składniki statyczne są często używane do implementacji liczników, zarządzania zasobami lub przechowywania danych globalnych w obrębie klasy.

Pytanie 10

Który z wymienionych algorytmów sortujących posiada średnią złożoność obliczeniową równą O(n log n)?

A. Sortowanie przez wybór
B. Sortowanie bąbelkowe
C. Sortowanie przez wstawianie
D. Sortowanie szybkie (QuickSort)
Sortowanie przez wstawianie jest dość powolne, z tą złożonością O(n²). W zasadzie fajnie sprawdza się tylko w małych zbiorach lub gdy tablica już jest mniej więcej posortowana. A jeśli chodzi o sortowanie bąbelkowe, to chyba nie ma co się łudzić, jest jednym z najgorszych algorytmów, też O(n²). I sortowanie przez wybór? Tutaj też nie ma rewelacji, bo porównuje się i wybiera najmniejszy element w każdej iteracji, co znacznie spowalnia działanie, zwłaszcza przy dużych tablicach. Tak że generalnie, lepiej unikać tych algorytmów, jeśli to możliwe.

Pytanie 11

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(&a, &b); // a, b - zmienne całkowite
B. zamien(*a, *b); // a, b - zmienne całkowite
C. zamien(12, 34)
D. zamien(m, n); // m, n - 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 12

Podaj przykład incydentu w miejscu pracy?

A. złe samopoczucie spowodowane przewlekłą chorobą zatrudnionego, które wystąpiło w biurze
B. złamanie nogi w trakcie urlopu wypoczynkowego przyznanego przez pracodawcę
C. kontuzja stawu skokowego, która zdarzyła się w trakcie bezpośredniej drogi do miejsca zatrudnienia
D. oparzenie dłoni, które miało miejsce podczas nieobowiązkowego szkolenia w czasie prywatnym pracownika
To właśnie sytuacja, gdy ktoś doznał kontuzji stawu skokowego podczas bezpośredniej drogi do pracy, jest klasycznym przykładem incydentu związanego z pracą, a konkretnie tzw. wypadku w drodze do pracy. Zgodnie z przepisami BHP oraz praktyką ubezpieczeniową, za incydent w miejscu pracy uznaje się nie tylko zdarzenia mające miejsce na terenie zakładu, ale także te występujące w drodze do lub z pracy – oczywiście pod warunkiem, że droga była bezpośrednia i nieprzerwana, bez załatwiania spraw prywatnych po drodze. Moim zdaniem ta kwestia jest często niedoceniana przez pracowników – wielu z nas zapomina, że wypadek w drodze do pracy daje podobne uprawnienia jak wypadek w zakładzie pracy, oczywiście po spełnieniu określonych wymogów formalnych, np. zgłoszenie incydentu pracodawcy, udokumentowanie miejsca i czasu zdarzenia. W praktyce wielu pracodawców i pracowników nie do końca rozumie, jakie sytuacje faktycznie podlegają pod te przepisy. Na przykład, jeśli ktoś skręcił nogę idąc prosto z domu do pracy i nie zatrzymywał się po drodze, to ten incydent kwalifikuje się jako wypadek w drodze do pracy. Warto znać te zasady, żeby nie przegapić swoich praw. Branżowe standardy, takie jak wytyczne PIP i ubezpieczycieli, jasno wskazują na obowiązek rejestrowania i analizowania takich zdarzeń, bo z punktu widzenia bezpieczeństwa pracy każde takie zdarzenie jest sygnałem do poprawy szeroko rozumianych warunków pracy, nawet jeśli zdarzy się poza samym biurem czy halą.

Pytanie 13

Kiedy w programie występuje problem z działaniem, a programista musi zweryfikować wartości znajdujące się w zmiennych w momencie działania aplikacji, to w tym celu należy zastosować

A. debugger
B. analizator składni
C. interpreter
D. wirtualną maszynę
Debugger to jedno z podstawowych narzędzi, bez którego praktycznie żaden programista nie wyobraża sobie efektywnej pracy przy diagnozowaniu usterek w kodzie. Pozwala on na zatrzymanie wykonania programu w wybranym miejscu (tzw. breakpoint), podgląd wartości zmiennych, śledzenie stosu wywołań i krokowe przechodzenie przez kod. Praca z debuggerem znacznie skraca czas poszukiwania przyczyn błędów, pozwalając od razu zobaczyć, co dokładnie dzieje się „pod maską” aplikacji w konkretnym momencie jej działania. W mojej opinii – i myślę, że większość osób z branży się tu zgodzi – opanowanie obsługi debuggera to absolutna podstawa, jeśli ktoś myśli poważnie o programowaniu. Narzędzia te są dostępne w praktycznie każdym środowisku IDE, zarówno do języków kompilowanych jak i interpretowanych. Można dzięki nim sprawdzać nawet bardzo złożone przypadki, które trudno byłoby wychwycić samym czytaniem kodu albo przez dodawanie tymczasowych printów. Debugger umożliwia też dynamiczne modyfikowanie wartości w trakcie działania programu, co czasem bardzo się przydaje przy testowaniu różnych scenariuszy. Branżowe dobre praktyki wręcz zalecają regularne wykorzystywanie debuggera podczas pracy z większymi projektami, bo to po prostu ogromna oszczędność czasu i nerwów.

Pytanie 14

W obrębie klasy pracownik zdefiniowano następujące metody:

pracownik() { ... }
static void wypisz() { ... }
int operator== (const pracownik &prac) { ... }
~pracownik() { ... }
Którą z nich można, zgodnie z jej funkcją, rozszerzyć o element diagnostyczny o treści:
cout << "Obiekt został usunięty";
A. wypisz
B. pracownik
C. operator==
D. ~pracownik
Wybranie destruktora ~pracownik do umieszczenia komunikatu diagnostycznego o usunięciu obiektu jest jak najbardziej słuszne i zgodne z praktykami programowania obiektowego w C++. To właśnie destruktor odpowiada za wykonywanie wszelkich czynności „na pożegnanie” obiektu, czyli w momencie jego zwalniania z pamięci. Właśnie tu umieszcza się takie rzeczy jak logowanie faktu usunięcia, czyszczenie zasobów zewnętrznych czy zwalnianie pamięci dynamicznej. W praktyce, gdy zadeklarujemy cout << "Obiekt został usunięty"; w destruktorze, będziemy mieli jasny sygnał przy każdym końcu życia obiektu, co świetnie nadaje się do diagnostyki i szukania błędów w zarządzaniu pamięcią. Moim zdaniem każdy programista, nawet początkujący, powinien chwilę pobawić się takimi komunikatami, żeby lepiej zrozumieć, kiedy dokładnie destruktor jest wołany (np. przy wyjściu ze scope’u, delete, końcu programu itp.). To też dobry sposób, żeby wychwycić niechciane wycieki pamięci lub zrozumieć, dlaczego obiekt nie został jeszcze usunięty. Wzorce projektowe, takie jak RAII, wręcz opierają się na działaniu destruktorów. W branży często stosuje się podobne rozwiązania do debugowania problematycznych fragmentów kodu. Ogólnie rzecz biorąc, umieszczanie komunikatów w destruktorze jest praktycznym i polecanym sposobem na rozpoznanie cyklu życia obiektu – i to w każdej większej aplikacji C++.

Pytanie 15

Jaką strukturę danych można zrealizować, korzystając jedynie z wymienionych 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 FIFO
B. drzewo binarne
C. tablica
D. stos
Każda z błędnych odpowiedzi w tym pytaniu odnosi się do popularnych struktur danych, jednak żadna z nich nie pasuje do zestawu metod, które tutaj pokazano. Zacznijmy od kolejki FIFO – tam główną zasadą jest First In, First Out, czyli pierwszy dodany element wypada jako pierwszy. Aby zrealizować kolejkę, potrzebne są zwykle metody enqueue (dodawanie na koniec) i dequeue (usuwanie z początku), czasem jeszcze peek do podejrzenia pierwszego elementu. Natomiast w prezentowanym zestawie nie mamy operacji rozróżniających początek i koniec – wszystko dzieje się tylko „na górze”, co zupełnie nie oddaje natury kolejki. Tablica z kolei daje dostęp do elementów przez indeksy, można przeskakiwać losowo po jej zawartości, zmieniać konkretne pozycje – czego w ogóle nie da się zrobić, mając tylko push, pop, peek i isEmpty. Dla drzewa binarnego brakuje tu zupełnie kluczowych mechanizmów – nie ma odniesień do lewego czy prawego potomka, nie da się wstawić elementu zgodnie z regułami drzewa, ani przeszukiwać go w odpowiedni sposób. Często na etapie nauki pojawia się taki błąd, że ktoś patrzy na pojedyncze funkcje, a nie dostrzega całej filozofii stojącej za strukturą. W praktyce, żeby dobrze dopasować strukturę do zadania, trzeba zawsze pytać, jakie są zasady dostępu do danych i jakich operacji naprawdę potrzebujemy. Dopiero wtedy można ocenić, czy pasuje nam stos, kolejka, tablica czy drzewo – a w tym przypadku, patrząc na metody, tylko stos jest odpowiedzią zgodną z logiką i branżowymi standardami.

Pytanie 16

Na ilustracji pokazano fragment emulacji iOS z elementem kontrolnym. Który fragment kodu XAML opisuje ten element?

Ilustracja do pytania
A. <Entry IsPassword= "true" />
B. <Stepper Increment= "1" />
C. <Slider Maximum= "255" />
D. <Switch IsToggled= "true" />
Kontrolka <Switch IsToggled= "true" /> w XAML to taki przełącznik. Ma dwa stany: włączony (true) i wyłączony (false). Można to porównać do zwykłego włącznika, tylko że w aplikacjach. Fajnie się z tego korzysta, bo pozwala szybko zmieniać ustawienia, nie trzeba nic więcej wpisywać. To jest dosyć intuicyjne dla użytkowników, więc można nim łatwo zarządzać funkcjami aplikacji.

Pytanie 17

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

A. Narzędzia do analizy błędów
B. Ilość linii kodu programu
C. Metoda alokacji pamięci dla danych
D. Typ zastosowanego kompilatora
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 18

Która z poniższych technologii jest używana do tworzenia wykresów i animacji w przeglądarce?

A. SVG
B. JSON
C. CSV
D. XML
Podejścia związane z innymi odpowiedziami nie są odpowiednie do tworzenia wykresów i animacji w przeglądarce. XML (Extensible Markup Language) jest formatem opisu danych, który służy do strukturalnego przechowywania i transportu danych, ale nie jest bezpośrednio używany do generowania grafik czy animacji. Chociaż można zbudować na jego podstawie system do tworzenia grafik, wymagałoby to dodatkowego przetwarzania, co czyni go mniej wydajnym. CSV (Comma-Separated Values) jest formatem tekstowym wykorzystywanym do przechowywania danych tabelarycznych, co ogranicza go do zadań związanych z wymianą danych, a nie ich wizualizacją. JSON (JavaScript Object Notation) jest z kolei formatem do wymiany danych, który jest czytelny dla ludzi i łatwy do przetworzenia przez maszyny, jednak nie odnosi się bezpośrednio do grafiki wektorowej. Często popełnianym błędem jest mylenie tych formatów z ich zastosowaniem w kontekście wizualizacji danych. Kluczowe jest, aby zrozumieć, że do skutecznego tworzenia interaktywnych i estetycznych wykresów lepiej jest używać technologii specjalnie zaprojektowanych do tego celu, jak SVG, które zapewniają odpowiednią funkcjonalność i wsparcie. Ostatecznie, wybór technologii powinien być uzależniony od specyficznych potrzeb projektu oraz jego wymagań.

Pytanie 19

Modyfikator dostępu, który znajduje się przed definicją metody Dodaj() w klasie Kalkulator, powoduje, że

protected void Dodaj() {}
A. nie jest ona dostępna z poziomu klas zaprzyjaźnionych z klasą Kalkulator
B. nie jest ona dostępna w klasach, które dziedziczą po klasie Kalkulator
C. jest ona dostępna w programie głównym i może być wywoływana na rzecz instancji klasy Kalkulator
D. jest ona dostępna zarówno wewnątrz klasy, jak i w klasach dziedziczących po klasie Kalkulator
Modyfikator dostępu protected jest kluczowym elementem programowania obiektowego, umożliwiającym kontrolę nad widocznością i dostępem do składników klasy. Gdy metoda jest oznaczona jako protected, jak w przypadku metody Dodaj() w klasie Kalkulator, oznacza to, że jest ona dostępna nie tylko w ramach tej klasy, ale również w dowolnych klasach, które dziedziczą po klasie Kalkulator. To podejście wspiera koncepcję dziedziczenia, umożliwiając klasom potomnym korzystanie z funkcjonalności klasy bazowej bez konieczności ponownego definiowania metod. Na przykład, jeśli stworzymy klasę DziecięcyKalkulator dziedziczącą po Kalkulator, metoda Dodaj() będzie dostępna w tej klasie potomnej. Takie rozwiązanie jest często stosowane w projektach, gdzie istnieje potrzeba rozszerzania funkcjonalności bazowych klas bez naruszania ich enkapsulacji. Dobre praktyki programistyczne sugerują stosowanie protected tam, gdzie chcemy umożliwić dziedziczenie oraz uniknąć nadmiernego udostępniania elementów klasy zewnętrznym użytkownikom. Dzięki temu kod staje się bardziej modularny i elastyczny, co jest istotne w dużych projektach programistycznych. Zrozumienie roli modyfikatorów dostępu, takich jak protected, jest kluczowe dla efektywnego projektowania i implementacji systemów obiektowych.

Pytanie 20

W języku C# szablon List umożliwia korzystanie z listy. Z definicji obiektu kolekcji wynika, że jego elementami mogą być:

List<int> wykaz = new List<int>();
A. liczby rzeczywiste
B. elementy o nieokreślonym typie
C. elementy typu List
D. liczby całkowite
Jeżeli chodzi o kolekcje generyczne w C#, to List<int> jest przykładem bardzo konkretnego zastosowania. Ten zapis oznacza, że tworzymy listę, której elementami mogą być wyłącznie liczby całkowite – dokładnie takie, jakie reprezentuje typ int w .NET (czyli 32-bitowe liczby całkowite ze znakiem). Wynika to z idei generyczności: typ podany w nawiasach ostrych (<int>) precyzyjnie narzuca typ przechowywanych danych. To daje nam bezpieczeństwo typów, na które zwracają uwagę wszyscy programiści C# – nie da się przez pomyłkę dodać tam np. napisu czy obiektu innego typu. Z mojego doświadczenia mogę powiedzieć, że to bardzo upraszcza życie, bo kompilator od razu wychwyci próby niewłaściwego użycia. Praktycznie, gdy tworzysz List<int>, możesz ją wykorzystać np. do przechowywania identyfikatorów, wyników testów, liczb losowych – wszędzie tam, gdzie operujesz właśnie na liczbach całkowitych. Warto dodać, że generyczność jest jednym z filarów nowoczesnych języków, pozwalając pisać kod elastyczny i bezpieczny zarazem. Trochę jak z pudełkiem na śrubki: jak wrzucisz inne rzeczy, to od razu się pogubisz i zrobi się bałagan. Tutaj jest bardzo jasno – List<int> to zawsze lista liczb całkowitych i już. Dobre praktyki branżowe podpowiadają, żeby zawsze stosować jak najbardziej precyzyjne typy w generycznych kolekcjach, bo to ułatwia późniejsze utrzymanie kodu i ogranicza potencjalne błędy.

Pytanie 21

Użycie modyfikatora abstract w definicji metody w klasie wskazuje, że

A. trzeba zaimplementować tę metodę w tej klasie
B. klasy pochodne nie mogą implementować tej metody
C. dziedziczenie po tej klasie jest niedozwolone
D. klasa ta stanowi podstawę dla innych klas
Modyfikator abstract w definicji metody jasno wskazuje, że dana klasa jest przeznaczona do dalszego dziedziczenia i stanowi coś w rodzaju szablonu dla innych klas. W praktyce – jeśli w klasie pojawia się choć jedna metoda abstract, cała klasa musi być także oznaczona jako abstract. To taki sygnał: hej, tej klasy nie da się użyć bezpośrednio, ale możesz po niej dziedziczyć i dopiero tam zaimplementować szczegóły. Moim zdaniem to bardzo wygodne, bo pozwala z góry narzucić kontrakt na klasy pochodne – mają dostarczyć własne wersje abstrakcyjnych metod. W wielu językach obiektowych, jak C# czy Java, stosowanie klas abstrakcyjnych jest powszechną praktyką przy projektowaniu rozbudowanych aplikacji, gdzie ważne jest rozdzielenie ogólnej logiki od szczegółowych implementacji. Daje to sporą elastyczność i chroni przed przypadkowymi błędami, kiedy ktoś próbowałby utworzyć obiekt klasy, która nie ma pełnej funkcjonalności. Często spotyka się to np. przy projektowaniu hierarchii typu Zwierzę → Pies/Kot, gdzie klasa Zwierzę jest abstrakcyjna i zawiera np. metodę abstract WydajDźwięk(). Dzięki temu każde konkretne zwierzę musi zaimplementować własną wersję tej metody, a całość kodu jest czytelniejsza i łatwiej ją rozwijać. Zdecydowanie warto poznać ten mechanizm, bo to fundament nowoczesnego programowania obiektowego i coś, co codziennie przydaje się w pracy programisty.

Pytanie 22

Który z poniższych języków programowania jest statycznie typowany?

A. PHP
B. Ruby
C. TypeScript
D. JavaScript
TypeScript jest językiem programowania, który został zaprojektowany jako nadzbiór JavaScriptu. Jednym z jego kluczowych wyróżników jest statyczne typowanie, co oznacza, że zmienne, funkcje i obiekty mogą mieć zdefiniowane typy, które są sprawdzane w czasie kompilacji, zanim kod zostanie uruchomiony. Dzięki temu programiści mogą wychwycić wiele typowych błędów, takich jak niezgodność typów, co zwiększa bezpieczeństwo kodu oraz ułatwia jego utrzymanie. TypeScript pozwala na korzystanie z typów prostych, obiektowych, a także umożliwia definiowanie własnych typów, co daje większą elastyczność. Przykładowo, definiując funkcję w TypeScript, można określić typy argumentów oraz typ zwracany, co jest zgodne z najlepszymi praktykami w programowaniu, zachęcając do bardziej strukturalnego podejścia do pisania kodu. W praktyce, projektowanie aplikacji w TypeScript pozwala na łatwiejsze wprowadzanie zmian i refaktoryzację, ponieważ zmiany w typach są automatycznie sprawdzane przez kompilator. Warto również zauważyć, że TypeScript jest szeroko stosowany w dużych projektach, zwłaszcza w kontekście aplikacji frontendowych opartych na frameworkach takich jak Angular czy React, gdzie zarządzanie złożonością kodu jest kluczowe.

Pytanie 23

Który z wymienionych wzorców projektowych jest najbardziej odpowiedni do uproszczenia interfejsu złożonego systemu?

A. Singleton (Singleton)
B. Metoda szablonowa (Template method)
C. Fasada (Facade)
D. Kompozyt (Composite)
Wzorzec Kompozyt (Composite) umożliwia traktowanie pojedynczych obiektów i ich grup w jednakowy sposób, co ułatwia zarządzanie hierarchicznymi strukturami. Metoda szablonowa (Template Method) definiuje szkielet algorytmu w klasie bazowej, pozwalając podklasom na dostosowanie poszczególnych kroków. Singleton to wzorzec zapewniający istnienie tylko jednej instancji klasy, co jest użyteczne w zarządzaniu zasobami systemowymi, ale nie służy do upraszczania interfejsu do złożonego systemu.

Pytanie 24

Które z wymienionych narzędzi najlepiej chroni dane na urządzeniach mobilnych?

A. Hasło ustawione na urządzeniu
B. Szyfrowanie danych na urządzeniu
C. Zainstalowanie aplikacji rozrywkowych
D. Nieaktualne oprogramowanie
Szyfrowanie danych na urządzeniu przenośnym to jedna z najskuteczniejszych metod zabezpieczania poufnych informacji. Szyfrowanie przekształca dane w formę, która jest nieczytelna dla osób nieposiadających odpowiedniego klucza deszyfrującego. Dzięki temu, nawet jeśli urządzenie zostanie zgubione lub skradzione, dane pozostają zabezpieczone przed nieautoryzowanym dostępem. Szyfrowanie to standardowa praktyka stosowana przez największe firmy technologiczne i jest zalecana we wszystkich urządzeniach przenośnych, takich jak laptopy i smartfony.

Pytanie 25

Błędy w interpretacji kodu stworzonego za pomocą React.js lub Angular można wykryć dzięki

A. narzędziom zainstalowanym po stronie serwera aplikacji
B. wbudowanemu debuggerowi w danym środowisku
C. konsoli przeglądarki internetowej
D. kompilatorowi języka JavaScript
Konsola przeglądarki to naprawdę super narzędzie do śledzenia błędów w JavaScript, a szczególnie przydatna jest, gdy piszemy coś w React.js albo Angular. Dzięki niej możesz łatwo sprawdzać logi i błędy, a nawet na żywo testować różne fragmenty swojego kodu. To naprawdę szybki sposób, żeby znaleźć problemy, bez potrzeby grzebania w całym kodzie aplikacji.

Pytanie 26

Jaką kategorię własności intelektualnej reprezentują znaki towarowe?

A. Autorskie prawa majątkowe
B. Prawa pokrewne
C. Dobra niematerialne
D. Własność przemysłowa
Znaki towarowe należą do kategorii własności przemysłowej. Ochrona znaków towarowych pozwala firmom na zabezpieczenie ich brandingu, logotypów oraz nazw produktów przed nieuprawnionym wykorzystaniem przez konkurencję. Rejestracja znaku towarowego daje właścicielowi prawo do wyłącznego używania go w celach komercyjnych i przeciwdziałania naruszeniom. Własność przemysłowa obejmuje także patenty, wzory przemysłowe i oznaczenia geograficzne, stanowiąc kluczowy element strategii ochrony marki oraz wartości firmy na rynku międzynarodowym.

Pytanie 27

Jaką wartość przyjmie etykieta label po wykonaniu poniższego kodu, gdy zostanie on uruchomiony po naciśnięciu przycisku w aplikacji?

private void Button_click(object sender, routedEventArgs e) {
    int tmp = 0;
    for (int i=0; i<=100; i+=2) {
        tmp += i;
    }
    label.Content = tmp;
}
A. liczby parzyste z przedziału od 0 do 100
B. suma liczb z przedziału od 0 do 100
C. liczby z przedziału od 0 do 100
D. suma liczb parzystych z przedziału od 0 do 100
Kod, który został podany w pytaniu, wykorzystuje pętlę for do obliczenia sumy wszystkich liczb parzystych z przedziału od 0 do 100 włącznie. Zmienna tmp pełni tutaj rolę akumulatora, który z każdą iteracją powiększa swoją wartość o kolejną liczbę parzystą. Startujemy od zera, a dzięki i+=2 pętla przechodzi tylko przez liczby parzyste (0, 2, 4, ..., 100). To bardzo typowy sposób, żeby wyliczyć sumę konkretnego zbioru liczb – w tym przypadku parzystych z określonego zakresu. Moim zdaniem warto zauważyć, że takie podejście świetnie sprawdza się w prostych kalkulatorach, prostych analizach danych czy nawet w grach, gdzie czasem trzeba sumować tylko wybrane wartości. W praktyce, szczególnie w większych projektach, lepiej opakować takie operacje w osobne metody lub korzystać np. z funkcji agregujących LINQ w C#. Ale zasada jest ta sama – najpierw określamy, co konkretnie chcemy sumować (tutaj: liczby parzyste), a potem realizujemy to w pętli. Ten fragment kodu jest też niezłym przykładem, jak optymalnie można przechodzić przez dane, jeśli nie musimy analizować wszystkich możliwych wartości (tutaj: wystarczy co drugi krok). Takie sumowanie przydaje się w pracy z raportami, zestawieniami i w miejscach, gdzie liczy się wydajność przetwarzania danych.

Pytanie 28

Jakie są kluczowe różnice pomiędzy strukturą (struct) a unią (union) w języku C?

A. Struktura wymaga więcej miejsca w pamięci niż unia
B. Unia umożliwia dynamiczne przypisywanie typów danych, struktura natomiast nie
C. Unia nie jest obsługiwana przez kompilatory współczesnych języków
D. Struktura przechowuje wiele wartości równocześnie, unia tylko jedną
Unia nie pozwala na dynamiczne typowanie danych – typ każdego pola jest zdefiniowany w czasie kompilacji, podobnie jak w strukturze. Struktura nie zajmuje więcej pamięci niż unia – zajmuje dokładnie tyle miejsca, ile potrzeba na przechowywanie wszystkich pól jednocześnie. Twierdzenie, że unia nie jest wspierana przez nowoczesne kompilatory, jest błędne – unie są integralną częścią standardu C i są szeroko wspierane we współczesnych środowiskach programistycznych.

Pytanie 29

Jaką funkcję pełni operator "|" w języku C++?

A. Logiczne "lub"
B. Operację przesunięcia bitów w prawo
C. Bitowe "xor"
D. Bitowe "lub"
Operator `||` to operator logiczny `OR`, który działa na wartościach logicznych i zwraca `true`, jeśli przynajmniej jeden z operandów jest prawdziwy, ale nie operuje na poziomie bitów. Operator `^` to operator `XOR` (exclusive or), który zwraca `1` tylko wtedy, gdy jeden z operandów ma wartość `1`, a drugi `0`. Operator `>>` to operator przesunięcia bitowego w prawo, który przesuwa bity liczby w prawo o określoną liczbę miejsc, co skutkuje podzieleniem liczby przez potęgę dwójki. Każdy z tych operatorów działa inaczej niż `|`, który jest operatorem bitowego `OR`.

Pytanie 30

Która z poniższych technik NIE jest związana z optymalizacją wydajności strony internetowej?

A. Lazy loading
B. Użycie CDN
C. Deep linking
D. Minifikacja kodu
Minifikacja kodu, lazy loading i użycie CDN to techniki ściśle związane z optymalizacją wydajności stron internetowych. Minifikacja kodu polega na usuwaniu zbędnych znaków, takich jak spacje, komentarze czy nowe linie, co skutkuje zmniejszeniem rozmiaru plików CSS i JavaScript. Dzięki temu przeglądarki mogą szybciej pobierać i interpretować skrypty, co bezpośrednio wpływa na czas ładowania strony. Z kolei lazy loading to technika, która polega na opóźnionym ładowaniu obrazów i innych zasobów, co pozwala na szybsze przekazywanie pierwszej wersji strony użytkownikowi. Tylko zasoby, które są aktualnie widoczne w oknie przeglądarki, są ładowane na początku, co zmniejsza obciążenie serwera oraz przyspiesza renderowanie strony. Użycie CDN (Content Delivery Network) z kolei polega na rozproszeniu treści na serwerach rozmieszczonych geograficznie, co umożliwia użytkownikom dostęp do zasobów z najbliższej lokalizacji, co także przyspiesza ładowanie strony. Zrozumienie tych technik jest kluczowe, ponieważ ich wdrażanie może znacząco poprawić wskaźniki wydajności, a tym samym satysfakcję użytkowników. Ignorowanie tych metod optymalizacji może prowadzić do długich czasów ładowania i niezadowolenia użytkowników, co w dłuższym okresie może wpływać na konwersje i ogólną reputację strony.

Pytanie 31

Jakie z wymienionych czynności można zrealizować przy pomocy składnika statycznego danej klasy?

A. Tworzenie prywatnych kopii pól dla każdej instancji
B. Umożliwienie dzielenia pól klasy pomiędzy zaprzyjaźnione klasy
C. Wywołanie destruktora klasy bez jej usuwania
D. Zachowanie wartości wspólnych dla wszystkich instancji klasy
Tworzenie prywatnych kopii pól dla każdego obiektu to cecha pól niestatycznych – każda instancja klasy ma swoją własną kopię takich pól. Dzielenie pól klasy pomiędzy zaprzyjaźnione klasy nie odnosi się do mechanizmu statycznego – przyjaźń między klasami pozwala na dostęp do prywatnych składowych, ale nie oznacza współdzielenia pól między instancjami. Destruktory nie mogą być wywoływane w sposób statyczny – są one automatycznie uruchamiane w momencie usunięcia obiektu, a nie przez klasę jako całość.

Pytanie 32

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

A. DDoS
B. Man-in-the-Middle
C. Phishing
D. SQL Injection
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 33

Jaką rolę odgrywa program Jira?

A. Zarządzanie edycjami systemu operacyjnego
B. Modyfikowanie arkuszy kalkulacyjnych
C. Produkcja grafik 3D
D. Planowanie, śledzenie oraz raportowanie zadań projektowych
Jira to jedno z najpopularniejszych narzędzi do zarządzania projektami, wykorzystywane głównie w metodykach Agile i Scrum. Umożliwia planowanie, monitorowanie i raportowanie zadań projektowych na różnych etapach ich realizacji. Dzięki elastycznym tablicom kanban i sprintom, Jira pozwala zespołom programistycznym śledzić postępy, zarządzać backlogiem oraz efektywnie przydzielać zasoby. Funkcjonalności takie jak automatyzacja procesów, śledzenie błędów (bug tracking) i integracja z innymi narzędziami (np. GitHub, Bitbucket) sprawiają, że Jira jest wszechstronnym rozwiązaniem do zarządzania nawet najbardziej złożonymi projektami. Dzięki generowanym raportom i wykresom burndown, menedżerowie mogą dokładnie analizować tempo pracy i podejmować decyzje w oparciu o dane.

Pytanie 34

W celu wdrożenia w aplikacji internetowej mechanizmu zbierania danych statystycznych na komputerach użytkowników, można użyć

A. formulacje
B. sesje
C. ciasteczka
D. buforowanie
Ciasteczka, czyli tzw. cookies, to naprawdę podstawowy, a zarazem bardzo skuteczny mechanizm wykorzystywany w aplikacjach internetowych właśnie do zbierania i przechowywania danych statystycznych na komputerach użytkowników. Przeglądarki obsługują je praktycznie od zawsze i każda strona, która chce śledzić zachowanie odwiedzających, korzysta z cookies – choćby do zapamiętywania wizyt, identyfikowania użytkowników czy przechowywania preferencji. Co istotne, ciasteczka działają po stronie klienta, więc idealnie nadają się do przechowywania niewielkich ilości informacji bez konieczności ciągłego odpytywania serwera. W praktyce branżowej cookies są fundamentem dla narzędzi analitycznych, takich jak Google Analytics – to właśnie tam są zapisywane unikalne identyfikatory użytkowników, sesji czy kanałów ruchu. Z mojego doświadczenia mogę dodać, że jeśli ktoś kiedyś chciałby zbudować własny system analityczny, to zacznie właśnie od ciasteczek, bo są łatwo dostępne przez JavaScript i bardzo dobrze wspierane przez standardy sieciowe (np. RFC 6265). Warto też pamiętać o kwestiach prywatności i RODO, bo dzisiaj strony muszą informować użytkowników o użyciu cookies. Niemniej, jeśli chodzi o mechanizm zbierania statystyk na komputerze użytkownika, to cookies są wręcz nie do zastąpienia.

Pytanie 35

Programem służącym do monitorowania błędów oraz organizacji projektów jest:

A. Git
B. Bugzilla
C. Jasmine
D. Jira
Wiele osób myli pojęcia i narzędzia związane z zarządzaniem projektami oraz monitorowaniem błędów, co prowadzi do nieporozumień i błędnych wyborów w codziennej pracy. Git to system kontroli wersji, który służy głównie do zarządzania kodem źródłowym, śledzenia zmian i współpracy programistów. To narzędzie nie nadaje się do monitorowania błędów czy zarządzania projektami w ujęciu zadań, harmonogramów czy backlogów – chociaż można w nim np. dopisywać komentarze do commitów, to nie jest to jego główna rola. Bugzilla natomiast faktycznie umożliwia śledzenie błędów, ale jej funkcjonalności związane z zarządzaniem całymi projektami są dość ograniczone. Moim zdaniem to narzędzie trochę już przestarzałe, rzadziej obecnie używane, bo brakuje mu integracji ze współczesnymi procesami Agile czy automatyzacją typową dla większych platform. Jasmine z kolei to zupełnie inna kategoria – to framework do testów jednostkowych w JavaScript, używany do automatyzacji testów, ale nie do zarządzania zadaniami czy błędami. Często spotykam się z tym, że ktoś widząc znajomą nazwę narzędzia, przypisuje mu inne funkcje niż faktycznie posiada. W praktyce, profesjonalne prowadzenie projektu IT wymaga narzędzia, które pozwoli nie tylko śledzić błędy, ale też zarządzać backlogiem, przydzielać zadania, raportować postępy i integrować się z pozostałymi systemami zespołu programistycznego – te wszystkie cechy ma właśnie Jira. Dobór odpowiedniego narzędzia to nie tylko kwestia mody, ale przede wszystkim skuteczności i zgodności z dobrymi praktykami, jak np. Continuous Integration czy Agile. Warto zawsze najpierw dokładnie zrozumieć, do czego dane narzędzie służy, żeby nie tracić czasu na nieefektywne rozwiązania.

Pytanie 36

Które z poniższych NIE jest typem wartości zwracanej przez funkcję w języku JavaScript?

A. Method
B. Object
C. Number
D. Undefined
W języku JavaScript funkcje mogą zwracać różne typy wartości, takie jak obiekty, liczby czy typ undefined. Wśród wymienionych opcji, 'Method' nie jest typem wartości zwracanej przez funkcję. W rzeczywistości, metoda w JavaScript to funkcja przypisana do obiektu. Jeżeli definiujemy funkcję wewnątrz obiektu, to możemy ją nazwać metodą tego obiektu, ale nie jest to typ wartości. Przykładowo, jeżeli mamy obiekt o nazwie 'person' i metodę 'greet', która zwraca powitanie: const person = { name: 'Jan', greet: function() { return 'Cześć, ' + this.name; } }; W powyższym przypadku, 'greet' jest metodą, ale jej wartością zwracaną jest typ string, co jest typowym zachowaniem funkcji. Dobrą praktyką jest zrozumienie różnicy między funkcjami a ich zastosowaniami w obiektach, co pozwala na lepsze projektowanie kodu oraz ukierunkowanie na zasady programowania obiektowego, które są kluczowe w JavaScript.

Pytanie 37

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

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('success');
  }, 1000);
});

promise
  .then(res => {
    console.log(res);
    return 'first then';
  })
  .then(res => {
    console.log(res);
  });
A. first then, success
B. success
C. first then
D. success, first then
W przypadku błędnych odpowiedzi można zauważyć kilka typowych nieporozumień dotyczących działania obietnic w JavaScript. Odpowiedzi sugerujące, że najpierw zostanie wyświetlony 'first then' lub że będzie tylko jeden wynik, są wynikiem niezrozumienia, jak działa asynchroniczność oraz jak obietnice przetwarzają wyniki. Obietnice w JavaScript są zaprojektowane tak, aby zarządzać operacjami asynchronicznymi, co oznacza, że kod wewnątrz obietnicy nie blokuje wykonania innych operacji. W momencie, gdy obietnica jest utworzona, kod wykonuje się dalej, a funkcja `setTimeout` działa w tle. Gdy po upływie określonego czasu obietnica jest spełniona, następuje przekazanie wyniku do łańcucha `then`, a nie jakiegokolwiek innego miejsca w kodzie. To oznacza, że wyniki są zwracane w kolejności, w jakiej są zadeklarowane, co w tym przypadku prowadzi do wyświetlenia najpierw 'success', a potem 'first then'. Takie podejście do asynchroniczności jest fundamentalne w JavaScript, a jego zrozumienie jest kluczowe dla każdego programisty. Błędne odpowiedzi pochodzą często z mylnego przekonania, że wyniki obietnic są natychmiastowe lub że działają w tej samej kolejności, co kod synchroniczny. Dlatego ważne jest, aby zrozumieć, że asynchroniczność zmienia sposób, w jaki operacje są wykonywane i jak wyniki są zwracane.

Pytanie 38

Jaka będzie wartość zmiennej x po wykonaniu poniższego kodu?

let x = 0;
for (let i = 0; i < 10; i++) {
  if (i % 2 === 0) continue;
  x += i;
}
A. 45
B. 20
C. 30
D. 25
Wartość zmiennej x po wykonaniu podanego kodu wynosi 25, co jest wynikiem sumy wszystkich nieparzystych liczb od 0 do 9. W pętli for iterujemy od 0 do 9, a dla każdej wartości i sprawdzamy, czy jest parzysta. Jeżeli i jest parzyste, używamy instrukcji continue, co oznacza, że ten krok pętli jest pomijany i przechodzimy do następnej iteracji. W praktyce oznacza to, że wartości takie jak 0, 2, 4, 6, 8 nigdy nie zostaną dodane do zmiennej x. Zostaną natomiast dodane wartości nieparzyste: 1, 3, 5, 7, 9. Ich suma wynosi 1 + 3 + 5 + 7 + 9 = 25. Takie podejście jest typowe w programowaniu, gdyż pozwala na efektywne pomijanie niepotrzebnych wartości, co zwiększa wydajność kodu. Używanie operatora modulo (%) do sprawdzania parzystości jest powszechną praktyką. Tego typu konstrukcje możemy znaleźć w różnych zastosowaniach, na przykład w algorytmach sortujących czy w przetwarzaniu danych, gdzie istotne jest operowanie tylko na wybranych elementach.

Pytanie 39

Który z wymienionych typów danych należy do typu logicznego?

A. char
B. bool
C. int
D. float
Typ danych 'bool' (boolean) jest typem logicznym, który przechowuje jedną z dwóch wartości: 'true' lub 'false'. Typy logiczne są nieodłącznym elementem programowania, ponieważ umożliwiają implementację warunków i pętli sterujących przepływem programu. Typ 'bool' znajduje zastosowanie w praktycznie każdym języku programowania, w tym C++, Java, Python i C#. Operacje logiczne, takie jak 'AND', 'OR' i 'NOT', opierają się na wartościach typu 'bool', co czyni je podstawą dla algorytmów decyzyjnych i strukturalnych. Zastosowanie typów logicznych zwiększa czytelność kodu i pozwala na efektywne zarządzanie warunkami logicznymi.

Pytanie 40

W przedstawionym filmie ukazano kreator interfejsu użytkownika, dla którego automatycznie powstaje

A. kod Java
B. kod XML
C. obsługa wciśniętego przycisku
D. obsługa przycisku ekranu dotykowego
Kod XML jest obecnie najczęściej stosowanym formatem do definiowania wyglądu interfejsów użytkownika w takich narzędziach jak Android Studio czy różnego rodzaju designery graficzne. Kiedy projektujesz layout aplikacji mobilnej albo desktopowej, duża część nowoczesnych narzędzi tworzy właśnie pliki XML, które następnie są interpretowane przez system w czasie uruchamiania aplikacji. Ułatwia to rozdzielenie logiki aplikacji od jej prezentacji, co wydaje się fundamentalne przy większych projektach. Moim zdaniem takie podejście daje ogromne korzyści – można łatwo modyfikować wygląd bez dotykania kodu źródłowego. W praktyce, jeśli używasz np. Android Studio, zbudujesz interfejs przeciągając przyciski czy pola tekstowe, a pod spodem dostaniesz czytelny plik XML. To przyspiesza pracę, zwiększa czytelność projektu i pozwala na późniejsze automatyczne generowanie dokumentacji albo testów interfejsu. Takie standardy są rekomendowane nie tylko przez Google, ale też szeroko stosowane w innych środowiskach, jak chociażby XAML w Microsoft czy FXML w JavaFX. Przezroczystość działania tych narzędzi sprawia, że łatwiej jest pracować zespołowo, bo każdy może szybko zorientować się w strukturze UI patrząc na XML-a. Samo generowanie kodu XML przez narzędzia graficzne to duży krok w kierunku lepszej organizacji pracy i zgodności ze współczesnymi praktykami branżowymi.