Wyniki egzaminu

Informacje o egzaminie:
  • Zawód: Technik programista
  • Kwalifikacja: INF.04 - Projektowanie, programowanie i testowanie aplikacji
  • Data rozpoczęcia: 11 maja 2026 08:13
  • Data zakończenia: 11 maja 2026 08:22

Egzamin niezdany

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

Wymagane minimum: 20 punktów (50%)

Udostępnij swój wynik
Szczegółowe wyniki:
Pytanie 1

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. 4 osoby
B. 1 osobę
C. 2 osoby
D. 5 osób
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 2

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. elementy typu List
B. liczby rzeczywiste
C. liczby całkowite
D. elementy o nieokreślonym typie
W C# kolekcje generyczne typu List<> są jednym z podstawowych narzędzi do zarządzania zbiorem danych o określonym typie. Typ elementów w takiej liście nie jest przypadkowy ani dowolny, tylko wynika bezpośrednio z tego, co wpiszemy w nawiasach ostrych. Wiele osób na początku ulega mylnemu przekonaniu, że List<> może przechowywać elementy o nieokreślonym typie, co jest nieporozumieniem – właściwie tylko List<object> pozwala na taką elastyczność, ale i wtedy każda operacja na elementach wymaga rzutowania. Jeśli natomiast chodzi o liczby rzeczywiste, to one są reprezentowane przez typy double lub float, więc List<int> kompletnie się do tego nie nadaje – jeśli spróbujesz przechować tam np. 3.14, kompilator od razu zaprotestuje. Zdarza się, że ktoś sądzi, iż List<int> może przechowywać inne kolekcje typu List, ale to również nieporozumienie. Wtedy należałoby użyć List<List<int>> lub List<List<T>>, jeśli chcemy mieć listę list, a nie pojedynczych wartości. Typowe błędy wynikają tu moim zdaniem z nieznajomości, jak działa generyczność i jak ściśle typowana jest ta kolekcja. Może się to wydawać ograniczające, ale na co dzień ułatwia życie i zmniejsza ryzyko błędów już na etapie kompilacji. Dobrym nawykiem jest więc zawsze przyglądać się, jaki typ przypisujemy w List<>, bo to rzutuje na wszystkie operacje, jakie potem wykonamy na tej liście. Kluczowe jest, żeby dobrze rozumieć typy w C# i korzystać z nich świadomie, bo to podstawa solidnego i bezpiecznego kodu, zgodnie z praktykami profesjonalnych zespołów programistycznych.

Pytanie 3

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. łańcuchowym
D. stałoprzecinkowy
Poprawnie – typ DECIMAL w SQL to typ stałoprzecinkowy. Oznacza to, że już przy definicji kolumny musisz podać dwie wartości: całkowitą liczbę cyfr (PRECISION) oraz liczbę cyfr po przecinku (SCALE), np. DECIMAL(10,2). W praktyce oznacza to, że możesz przechowywać liczby z maksymalnie 10 cyframi, z czego 2 są po przecinku, czyli zakres jest kontrolowany i przewidywalny. Moim zdaniem to jest kluczowa cecha: stała dokładność i brak „pływania” wyniku. W relacyjnych bazach danych DECIMAL jest używany wszędzie tam, gdzie pieniądze, kursy walut, stawki VAT, ilości w magazynie itp. – wszędzie, gdzie liczy się precyzja i nie można sobie pozwolić na błędy zaokrągleń typowe dla typów zmiennoprzecinkowych (FLOAT, DOUBLE). Standard SQL właśnie dla takich zastosowań przewiduje typy numeryczne dokładne (exact numeric types), do których należy DECIMAL/NUMERIC. Dobre praktyki branżowe mówią wprost: kwoty finansowe trzymaj w DECIMAL, a nie w FLOAT. Warto też wiedzieć, że DECIMAL jest przechowywany w sposób „cyfrowy”, a nie binarny jak float, więc operacje arytmetyczne dają wyniki dokładne w zadanej skali. To bardzo ułatwia raportowanie, księgowość, rozliczenia między systemami. W wielu firmach spotkasz standardy projektowe w stylu: „wszystkie kwoty w systemie mają typ DECIMAL(18,2)” albo podobny. Taki zapis daje spójność danych, przewidywalne zużycie miejsca w bazie i mniejsze ryzyko błędów biznesowych. W skrócie: DECIMAL = stałoprzecinkowy, z góry określona liczba cyfr i powtarzalne wyniki obliczeń, co w systemach produkcyjnych jest bardzo ważne.

Pytanie 4

Metoda przeszukiwania w uporządkowanych tablicach, która polega na podzieleniu tablicy na kilka części i wykonywaniu wyszukiwania liniowego tylko w tej części, gdzie może znajdować się poszukiwany element, w języku angielskim jest określana jako

A. Binary search
B. Exponential search
C. Ternary search
D. Jump search
Wydaje się, że wybór padł na inną metodę wyszukiwania niż jump search – spróbuję wyjaśnić, skąd mogły się wziąć takie wątpliwości. Exponential search rzeczywiście działa na posortowanych tablicach, ale jego główna idea to szybkie znajdowanie zakresu, w którym może się znajdować poszukiwany element, poprzez wykładnicze zwiększanie indeksu (czyli 1, 2, 4, 8 itd.), a dopiero później użycie binary search do finalnego wyszukiwania w wykrytym przedziale. To nie jest metoda z dzieleniem tablicy na kilka części i szukaniem liniowo po „bloku”. Ternary search z kolei jest spotykany głównie tam, gdzie szukamy ekstremum (minimum lub maksimum) funkcji unimodalnej, a nie konkretnego elementu w tablicy. Tutaj tablica jest dzielona na trzy części, ale to zupełnie inna idea niż jump search – chodzi o ciągłe zawężanie przedziału na podstawie wartości funkcji, a nie liniowe przeszukiwanie fragmentu tablicy. Binary search jest chyba najbardziej znaną metodą dla uporządkowanych tablic: dzieli zbiór na pół i eliminuje połowę elementów w każdej iteracji. Jednak tutaj nie ma podziału na „bloki” i nie wykonuje się wyszukiwania liniowego, tylko zawsze korzysta z bezpośrednich porównań środkowego elementu. Z mojego doświadczenia, najczęstszy błąd przy tego typu pytaniach to mylenie mechanizmów dzielenia tablicy i przyspieszania wyszukiwania – nie każda metoda, która coś „dzieli” albo „przeskakuje”, działa tak samo. W praktyce jump search jest czymś dość specyficznym i bardzo łatwo można go pomylić z innymi klasykami, zwłaszcza jeśli nie miało się okazji widzieć jego działania na żywo. Warto zapamiętać, że to właśnie ten algorytm łączy w sobie blokowe przeskoki i liniowe przeszukiwanie tylko wybranego fragmentu – i to go wyróżnia spośród pozostałych popularnych metod branżowych.

Pytanie 5

Który z wymienionych algorytmów działających na tablicy jednowymiarowej ma złożoność obliczeniową \( O(n^2) \)?

A. Wyświetlenie elementów
B. Sortowanie bąbelkowe
C. Sortowanie szybkie
D. Wyszukiwanie metodą binarną
Sortowanie bąbelkowe to taki klasyczny algorytm, który ma złożoność \( O(n^2) \). Chociaż jest dość prosty w zrozumieniu, to nie za bardzo sprawdza się w większych zbiorach danych. Działa tak, że porównuje sąsiadujące ze sobą elementy i zamienia je miejscami, jeśli są w złej kolejności. Trochę to czasochłonne, ale warto znać ten algorytm, bo pokazuje podstawy sortowania.

Pytanie 6

Jaką nazwę elementu interfejsu należy wprowadzić w pierwszej linii kodu, na miejscu <??? aby został on wyświetlony w podany sposób?

<???
    android:layout_margin="50dp"
    android:switchMinWidth="60dp"
    android:text="Zgadzasz się?"
    android:textOff="NIE"
    android:testOn="TAK" />
Ilustracja do pytania
A. Switch
B. Spinner
C. RatingBar
D. SeekBar
Switch to bardzo charakterystyczny element interfejsu Androida, który służy do przełączania między dwoma stanami, np. włącz/wyłącz, tak/nie. Na screenie wyraźnie widać typowy suwak z okrągłym przyciskiem, który przemieszcza się na boki – dokładnie tak działa Switch. W kodzie XML także pojawiają się atrybuty takie jak text, textOff, textOn – one są właściwe właśnie dla komponentu Switch, bo pozwalają podpisać każdy ze stanów na przełączniku. Praktycznie w każdej nowoczesnej aplikacji spotyka się Switcha do wyrażania zgody, akceptacji regulaminu albo przełączania opcji (np. tryb ciemny). Z mojego doświadczenia to jest dużo wygodniejsze dla użytkownika niż klasyczne checkboxy, bo od razu widać, który stan jest aktywny – a UX-owcy też bardzo to chwalą. Warto pamiętać, że Switch ma swoje domyślne style zgodne z Material Design, więc aplikacja wygląda nowocześnie bez dodatkowej pracy. Dobrą praktyką jest wykorzystywanie Switcha właśnie wtedy, gdy potrzebujemy zmiany binarnej, a nie kilku opcji do wyboru. Jeśli ktoś myśli o bardziej zaawansowanych interfejsach, to Switch pozwala łatwo reagować na zmianę stanu w kodzie Java/Kotlin poprzez listener OnCheckedChangeListener. No i jest to jeden z tych komponentów, które naprawdę warto znać, bo są podstawą w każdym projekcie mobilnym.

Pytanie 7

Która z metod zarządzania projektami jest najbardziej odpowiednia, gdy w początkowej fazie projektu zakres nie jest w pełni określony, wymagania mogą zmieniać się podczas realizacji, a także mogą wystąpić nowe potrzeby?

A. PRINCE2
B. Model kaskadowy
C. Agile
D. Model V
W praktyce zarządzanie projektem, kiedy zakres i wymagania nie są w pełni określone, wymaga podejścia elastycznego i zdolności do szybkiego reagowania na zmiany. Tradycyjne metody, takie jak PRINCE2, model V czy model kaskadowy, zawsze zakładają większy nacisk na planowanie upfront, czyli na początku projektu, gdzie cały zakres (lub jego większość) jest ustalany przed rozpoczęciem realizacji. Model kaskadowy bywa stosowany głównie w środowiskach, gdzie produkty są powtarzalne i łatwe do przewidzenia – tutaj zmiany w wymaganiach są prawie niemożliwe do wprowadzenia bez cofnięcia się do wcześniejszych etapów. Model V, często stosowany w testowaniu oprogramowania czy inżynierii systemów, również zakłada ścisłe powiązanie etapów rozwoju i testowania; bardzo trudno tu o zmianę wymagań w trakcie, bo każda poprawka oznacza powrót przez wiele faz. PRINCE2 co prawda na papierze jest elastyczny, ale w praktyce lepiej sprawdza się, gdy mamy jasno zdefiniowany projekt i dużo formalności – jego framework przewiduje „kontrolowane” zmiany, ale to nie to samo, co adaptacja w locie, jaką daje Agile. Moim zdaniem problem polega na tym, że wybór tych klasycznych podejść wynika często z przyzwyczajenia do sztywnego planowania i przeświadczenia, że lepsza dokumentacja rozwiąże wszystkie niespodzianki. Tymczasem w środowiskach, gdzie klient nagle zmienia zdanie albo pojawiają się nowe potrzeby, takie metody zawodzą, bo są zbyt oporne na zmiany. Warto pamiętać, że Agile nie jest panaceum na wszystkie projekty, ale właśnie przy niejasnych wymaganiach i bardzo zmiennych warunkach rynkowych jego iteracyjność i stały kontakt z klientem pozwalają uniknąć wielu typowych pułapek planowania z góry.

Pytanie 8

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. drzewo binarne
B. tablica
C. kolejka FIFO
D. stos
Zestaw metod przedstawionych w pytaniu – czyli push, pop, peek oraz isEmpty – jednoznacznie wskazuje na strukturę danych zwaną stos (stack). To jest taki bardzo charakterystyczny „magazyn”, gdzie zawsze mamy do czynienia z zasadą LIFO, czyli Last In, First Out. Oznacza to, że ostatni element, który dodaliśmy metodą push, będzie tym pierwszym, który usuniemy przez pop. Peek natomiast pozwala tylko podejrzeć, co jest na górze stosu, ale niczego nie usuwa. isEmpty z kolei daje nam szybki sposób sprawdzenia, czy na stosie w ogóle coś jeszcze zostało. W praktyce, stosy są niezbędne w wielu algorytmach i strukturach programistycznych – na przykład podczas wywołań rekurencyjnych funkcji (sam system operacyjny używa stosu do obsługi wywołań procedur), przy obsłudze nawiasów w kompilatorach czy podczas implementacji algorytmu DFS (Depth-First Search) w grafach. Moim zdaniem, nawet jeśli na początku wydaje się, że stos nie jest tak „potężny” jak inne struktury, to jego prostota jest właśnie największym atutem i dlatego jest tak często wykorzystywany w praktyce. Branżowe standardy, na przykład w językach takich jak Java czy C#, bezpośrednio udostępniają gotowe klasy Stack, które właśnie implementują dokładnie te metody – to pokazuje, jak fundamentalna jest ta struktura. Pewnie warto też pamiętać, że stosy mają swoje ograniczenia (np. nie nadadzą się do kolejkowania zadań), ale tam gdzie trzeba działać LIFO, są niezastąpione.

Pytanie 9

W zamieszczonym fragmencie kodu Java wskaż nazwę zmiennej, która może przechować wartość 'T'.

int zm1;
float zm2;
char zm3;
boolean zm4;
A. zm4
B. zm1
C. zm2
D. zm3
Poprawnie wskazana została zmienna 'zm3', której typ to 'char'. To właśnie zmienne typu 'char' w Javie służą do przechowywania pojedynczych znaków, takich jak na przykład litera 'T'. Zmienna 'char' przechowuje znak jako wartość liczbową zgodnie z kodowaniem Unicode, co pozwala na obsługę szerokiego zakresu znaków z różnych alfabetów. W praktyce często spotyka się sytuacje, gdzie potrzebujemy przechować czy odczytać pojedynczy znak – np. literę przy przetwarzaniu tekstu, analizowaniu plików, czy nawet w prostych grach tekstowych, gdzie np. sterowanie postacią opiera się o pojedyncze litery wciskane na klawiaturze. Moim zdaniem dobre zrozumienie typu 'char' to podstawa, bo łatwo pomylić go z typem 'String', który przechowuje jednak całe ciągi znaków, a nie pojedyncze znaki. Z punktu widzenia dobrych praktyk, zawsze warto dobierać możliwie najwęższy typ danych do zadania – jeżeli chcemy przechować jedną literę, typ 'char' jest po prostu najefektywniejszy. Nawiasem mówiąc, w Javie znak umieszczamy w pojedynczych apostrofach (np. 'T'), co jednoznacznie odróżnia je od tekstów (podwójne cudzysłowy). Osobiście zdarzało mi się kiedyś pomylić te typy i potem szukać błędów, więc warto zapamiętać tę różnicę. Warto też wiedzieć, że typ 'char' przydaje się np. do operacji na znakach w tablicach, przy konwersjach kodów ASCII czy nawet szyfrowaniu prostych tekstów. Zdecydowanie jest to typ, którego nie można pominąć w nauce Javy.

Pytanie 10

Programista pragnie wybrać algorytm, który najszybciej przetwarza dane w jego aplikacji. Na podstawie złożoności obliczeniowej przedstawionej w tabeli, należy wskazać algorytm numer

Algorytm 1O(n²)
Algorytm 2O(n!)
Algorytm 3O(n³)
Algorytm 4O(n)
Algorytm 5O(n²)
A. 1 lub 5
B. 4
C. 3
D. 2 lub 3
Wybierając algorytm do zastosowania w praktycznej aplikacji, kluczowe jest zwracanie uwagi na złożoność obliczeniową, bo to ona decyduje, jak algorytm radzi sobie ze wzrostem ilości danych. Często spotykam się z błędnym przekonaniem, że algorytm o złożoności na przykład O(n²) jest w porządku, o ile nie mamy naprawdę gigantycznych zbiorów danych. Problem polega na tym, że już przy kilkuset czy kilku tysiącach elementów taki algorytm potrafi znacząco spowolnić działanie aplikacji. Jeszcze gorzej jest z O(n³), bo tutaj czas wykonania rośnie bardzo szybko, praktycznie wykładniczo – co praktycznie wyklucza użycie tego algorytmu w prawdziwie produkcyjnych rozwiązaniach, chyba że mamy do czynienia z ekstremalnie małymi zbiorami danych. Odpowiedzi wskazujące na algorytmy z O(n²) lub O(n³) pomijają najlepszą opcję, która znajduje się w tabeli – czyli Algorytm 4 z O(n). Tylko O(n) gwarantuje, że czas działania rośnie w sposób liniowy, co daje praktycznie jedyną szansę na obsługę dużych wolumenów danych bez zatorów i „zadyszki” aplikacji. Odpowiedź wskazująca Algorytm 2 (O(n!)) to już w ogóle bardzo typowy błąd – tego typu złożoność spotyka się głównie w algorytmach, gdzie trzeba sprawdzić wszystkie możliwe permutacje, jak np. problem komiwojażera, i na pewno nie jest to wybór optymalny. Podsumowując, cała ta sytuacja pokazuje, jak ważna jest umiejętność czytania notacji O(...) i świadomego wybierania algorytmów – to podstawa w programowaniu, szczególnie jeśli zależy nam na wydajności i skalowalności naszych rozwiązań.

Pytanie 11

W środowisku do tworzenia aplikacji, gdzie przedstawiono menu, aby usunąć wszystkie pliki tymczasowe oraz wyniki projektu, należy wybrać opcję

Ilustracja do pytania
A. Batch Build
B. Clean Solution
C. Run Code Analysis on Solution
D. Build Solution
Opcja „Clean Solution” to dokładnie to, czego używa się w Visual Studio lub innych środowiskach IDE, gdy chce się pozbyć wszystkich plików tymczasowych oraz wyników kompilacji powiązanych z bieżącym projektem lub rozwiązaniem. To bardzo praktyczna funkcja – zwłaszcza wtedy, gdy mamy problemy ze zbudowaniem projektu po wprowadzeniu wielu zmian lub gdy różne konfiguracje builda zaczynają się mieszać. Clean Solution usuwa wszystkie foldery bin i obj, co pozwala rozpocząć proces kompilacji od zera, eliminując potencjalne konflikty wynikające ze starych plików. Moim zdaniem warto korzystać z tej opcji regularnie, szczególnie w większych projektach czy zespołach, gdzie często zmieniają się zależności. W branży IT, według dobrych praktyk, „czyszczenie” rozwiązania przed puszczeniem pełnego builda pomaga zredukować liczbę nieprzewidzianych błędów kompilacji. Dla mnie to trochę taki techniczny reset – zanim zaczniesz szukać błędów w kodzie, upewnij się, że budujesz wszystko na świeżo. Zresztą, w dokumentacji Microsoftu też znajdziesz zalecenia, by właśnie Clean Solution stosować do rozwiązywania problemów z nieaktualnymi artefaktami builda. Bez tej funkcji czasem trudno dojść, czemu kompilator się buntuje.

Pytanie 12

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

<Switch
    android:id = "@+id/switch1"
    android:layout_width = "wrap_content"
    android:layout_height = "wrap_content"
    android:background = "#00ffff"
    android:text = "Switch"
    tools:layout_editor_absoluteX = "176dp"
    tools:layout_editor_absoluteY = "389dp" />
A. suwak
B. przełącznik
C. listę rozwijaną
D. stepper
W tym pytaniu łatwo się pomylić, zwłaszcza jeśli ktoś nie pracował dużo z Androidem albo myli podobne komponenty. Zacznijmy od steppera — to zupełnie inny typ kontrolki, zwykle służący do zwiększania lub zmniejszania wartości liczbowych (np. ilość sztuk w sklepie internetowym). W Androidzie stepper wygląda zupełnie inaczej i wymaga innych atrybutów, głównie związanych z wartością minimalną, maksymalną i krokami. Lista rozwijana, czyli spinner, charakteryzuje się możliwością wyboru jednej wartości z wielu dostępnych opcji — jej kod po stronie xml ma zupełnie inną strukturę, najczęściej używa się tam elementu Spinner, nie Switch. Suwak (ang. slider lub SeekBar) służy do płynnego ustawiania wartości na danym zakresie, typu jasność ekranu czy głośność. Z reguły ma atrybuty value, min, max, a nie background czy text, jak Switch. Myślenie, że Switch to suwak, często bierze się z tego, że oba mają element przesuwany, ale suwak pozwala na wiele pozycji, a Switch tylko dwie — włącz/wyłącz. To naprawdę częsty błąd wśród początkujących, przez ten podobny wygląd. Dopiero analiza atrybutów, jak android:text i android:background oraz sam typ komponentu, rozwiewa wątpliwości. Najlepiej w takich przypadkach zawsze sprawdzić dokumentację Androida czy standardy Material Design, bo one jasno wskazują, jakie są różnice funkcjonalne i wizualne. Z mojego doświadczenia w projektowaniu UI, wybranie nieodpowiedniej kontrolki prowadzi do nieintuicyjnych interfejsów, a użytkownicy są potem zagubieni. Warto więc znać te subtelności.

Pytanie 13

W zaprezentowanym kodzie ukazano jedno z fundamentalnych założeń programowania obiektowego. Czym ono jest?

public class Owoc {
}

public class Truskawka extends Owoc {
}

public class Jablko extends Owoc {
}
Ilustracja do pytania
A. hermetyzacja
B. polimorfizm
C. dziedziczenie
D. abstrakcja
W tym przykładzie kodu nie chodzi ani o polimorfizm, ani abstrakcję, ani hermetyzację, choć to wszystko są bardzo ważne pojęcia w programowaniu obiektowym. Polimorfizm polega na tym, że obiekty różnych klas mogą być traktowane tak samo poprzez wspólny interfejs, a konkretne zachowanie jest wybierane w czasie działania. Jednak w pokazanym kodzie nie mamy żadnych metod ani przykładu dynamicznego wywołania tej samej funkcji na różnych typach, więc nie występuje tutaj polimorfizm w praktycznym sensie. Jeśli chodzi o abstrakcję, to jest to wyodrębnianie wspólnych cech i zachowań do bardziej ogólnej klasy lub interfejsu, często z użyciem klas abstrakcyjnych lub interfejsów. W tym przypadku nie zastosowano ani słowa kluczowego 'abstract', ani nie przedstawiono żadnych metod abstrakcyjnych, więc kod nie wskazuje na abstrakcję. Hermetyzacja natomiast polega na ukrywaniu szczegółów implementacji klasy, najczęściej przez stosowanie modyfikatorów dostępu i enkapsulację pól (np. private fields i publiczne gettery/settery). Tutaj nie ma żadnych pól, metod ani kontroli dostępu, więc o hermetyzacji też nie można mówić. W moim odczuciu, często te pojęcia się mylą, bo są mocno powiązane, ale kluczowe jest, żeby rozpoznawać konkretne mechanizmy po zapisie kodu – a przykład dosłownie pokazuje dziedziczenie, bo nowe klasy rozszerzają jedną wspólną klasę bazową. To dobry moment, żeby jeszcze raz wrócić do podstaw i upewnić się, czym objawia się każde z tych pojęć w praktyce.

Pytanie 14

Jakie będzie działanie przedstawionych dwóch równoważnych fragmentów kodu źródłowego?

Kod w React:

function Heading(props) {
    return (
        <h1> {props.title} </h1>
    );
}

// w metodzie render
return (
    <Heading title="Egzamin zawodowy" />
);

Kod w Angular:
// heading.component.ts
import {Component} from '@angular/core';
@Component({
    selector: 'app-heading',
    templateUrl: './heading.component.html',
    styleUrls: ['./heading.component.css']
})

export class HeadingComponent {
    title:String = "Egzamin zawodowy";
    ...
}

// heading.component.html
<h1>{{title}}</h1>
A. Wyświetlony na stronie tekst w nagłówku: "Egzamin zawodowy"
B. Nadany tytuł każdego elementu HTML: "Egzamin zawodowy"
C. Wyświetlony na stronie tekst w akapicie: "Egzamin zawodowy"
D. Nadany tytuł strony: "Egzamin zawodowy"
Dokładnie tak – zarówno w React, jak i w Angularze, oba te fragmenty kodu mają za zadanie wyświetlić tekst „Egzamin zawodowy” w nagłówku HTML, czyli w tagu <h1>. To jest klasyczna praktyka w aplikacjach frontendowych. W React przekazujesz wartość props.title do komponentu Heading i renderujesz ją w elemencie <h1>. W Angularze tworzysz pole klasy o nazwie title i korzystasz z interpolacji {{ title }} w szablonie HTML – efekt jest identyczny. Taki sposób podejścia odzwierciedla zasadę jednokierunkowego przepływu danych i rozdzielania logiki od prezentacji, co jest jedną z podstaw nowoczesnych frameworków. Bardzo często nagłówki jak <h1> są wykorzystywane nie tylko dla estetyki, ale i poprawy dostępności oraz SEO strony – roboty wyszukiwarek właśnie z tych tagów czerpią wiedzę o głównym temacie widoku. Spotykałem się wielokrotnie z sytuacjami, gdzie ktoś próbował „upiększać” nagłówki za pomocą CSS, ale zapominał o semantyce i kończył z brakiem <h1> w kodzie – to błąd! Dobrą praktyką jest zawsze korzystanie z odpowiednich tagów HTML. Takie podejście sprawia, że kod jest czytelny, łatwiej go utrzymać i jest bardziej przyjazny dla wszystkich, także osób korzystających np. z czytników ekranu. Poza tym, takie komponenty są świetne do wielokrotnego użytku – możesz przekazać różne wartości „title” do różnych nagłówków strony, nie pisząc tego samego kodu od nowa. Moim zdaniem to jedna z podstawowych, ale bardzo ważnych technik, które każdy frontendowiec powinien ogarniać.

Pytanie 15

Wskaż kod, który jest funkcjonalnie równoważny zaprezentowanemu poniżej:

switch(nrTel) {
    case 999: opis = "Pogotowie"; break;
    case 998: opis = "Straż"; break;
    case 997: opis = "Policja"; break;
    default: opis = "Inny numer";
}
Kod 1.
with nrTel {
    if (999) opis = "Pogotowie";
    if (998) opis = "Straż";
    if (997) opis = "Policja";
    else opis = "Inny numer";
}
Kod 2.
if (nrTel == 999)
    opis = "Pogotowie";
else if (nrTel == 998)
    opis = "Straż";
else if (nrTel == 997)
    opis = "Policja";
else opis = "Inny numer";
Kod 3.
if (nrTel == 999)
    opis = "Pogotowie";
if (nrTel == 998)
    opis = "Straż";
if (nrTel == 997)
    opis = "Policja";
else
    opis = "Inny numer";
Kod 4.
Opis =
    if (nrTel == 999) => "Pogotowie";
    else if (nrTel == 998) => "Straż";
    else if (nrTel == 997) => "Policja";
    else => "Inny numer";
A. Kod 2.
B. Kod 1.
C. Kod 3.
D. Kod 4.
Zamiana instrukcji switch na inne konstrukcje warunkowe wymaga bardzo uważnego odwzorowania zasad działania, zwłaszcza tego, że switch działa wyłącznie na porównaniu wartości (nie warunków logicznych) i wykonuje tylko jeden z przypadków lub blok domyślny. Zauważyłem, że często błędne odpowiedzi biorą się z niepełnego zrozumienia, jak działają instrukcje if-else oraz kiedy wykonywana jest dana gałąź kodu. Przykładowo, Kod 1 i Kod 3 stosują osobne instrukcje if, przez co mogą prowadzić do przypisywania wartości "opis" wiele razy podczas jednego przebiegu – co zupełnie odbiega od pierwotnej logiki switcha. Dla przykładu: jeśli nrTel będzie równe 997, to w Kodzie 3 pierwsze dwa warunki będą fałszywe, ale trzeci będzie prawdziwy i wykona się, a jednocześnie else zostanie potraktowany jako związany tylko z ostatnim if, co jest nieintuicyjne i łatwo o błąd. Jeszcze większe zamieszanie wprowadza Kod 1, gdzie składnia nie odpowiada żadnemu znanemu językowi – takie rzeczy pojawiają się raczej w pseudokodzie i nie nadają się do prawdziwych projektów. Kod 4 natomiast prezentuje nietypową, niepoprawną składnię (np. "if (...) => 'cos';"), która nie jest zgodna z żadnym głównym językiem programowania – to bardziej skrót myślowy lub pseudokod. W praktyce, poprawną zamianą switch na instrukcje warunkowe jest dokładne odwzorowanie logiki wyłączności wyboru, czyli właśnie użycie połączonych bloków if – else if – else, jak w Kodzie 2. Moim zdaniem takie błędne podejścia często wynikają z chęci uproszczenia kodu bez zwrócenia uwagi na to, jak mechanizmy sterowania naprawdę działają. Warto zapamiętać, że właściwe odwzorowanie switcha to zawsze jedna ścieżka wykonania dla danej wartości, bez powtarzania czy nadpisywania wyniku w kolejnych warunkach – i tego właśnie brakuje w niepoprawnych kodach.

Pytanie 16

Przedstawione kody zawierają realizację funkcji oraz jeden zdefiniowany test automatyczny, który weryfikuje działanie funkcji w przypadku, gdy argumentem jest liczba ujemna. W miejsce kropek należy dodać drugi test, który sprawdzi funkcjonalność funkcji, kiedy argumentem jest liczba dodatnia. Który z poniższych kodów jest odpowiedni do tego testu?

export function fun1(number) {
    if (number < 0)
        number = number * (-1);
    return number;
}
describe('fun1', () => {
    it('test1', () => {
        const result = fun1(-1);
        expect(result).toBe(1);
    })
    ...
})
it('test2', () => {
    const result = fun1(1);
    expect(result).toBe(result+1);
})
A.
it('test2', () => {
    const result = fun1(2);
    expect(result).toBe(-2);
})
B.
it('test2', () => {
    const result = fun1(2);
    expect(result).toBe(2);
})
C.
it('test2', () => {
    const result = fun1(1);
    expect(result).toBe(-1);
})
D.
A. Odpowiedź C
B. Odpowiedź A
C. Odpowiedź D
D. Odpowiedź B
Błędne odpowiedzi A B oraz D wynikają z niepoprawnego zrozumienia działania funkcji fun1 która przekształca wartość ujemną na dodatnią ale nie zmienia wartości dodatnich Odpowiedź A sugeruje że funkcja powinna dodać 1 do wartości co nie jest zgodne z jej definicją Funkcja nie wykonuje operacji arytmetycznych poza mnożeniem ujemnych liczb przez -1 co w odpowiedzi A nie ma zastosowania Wynik testu oczekiwany jako result+1 nie odzwierciedla poprawnego działania funkcji Odpowiedź B natomiast błędnie zakłada że funkcja przekształca dodatnie liczby w ujemne co nie jest prawdą Funkcja jedynie zmienia znak dla ujemnych wartości więc test oczekujący że 2 przekształci się w -2 jest niepoprawny Odpowiedź D z kolei zakłada że funkcja zmienia znak liczby dodatniej 1 do wartości -1 co również nie jest zgodne z założeniami funkcji Fun1 powinna zwracać tę samą wartość dla liczby dodatniej Funkcje jednostkowe są kluczowym narzędziem do zapewnienia niezawodności kodu i ich prawidłowe zrozumienie jest niezbędne do skutecznego testowania oprogramowania W kontekście tego pytania jedynie odpowiedź C prawidłowo odzwierciedla poprawne zachowanie funkcji dla wartości dodatnich co jest zgodne z jej implementacją

Pytanie 17

Przeprowadzając analizę kodu interfejsu graficznego napisanego w języku XAML, można zauważyć, że:

<StackLayout Orientation="Vertical">
  <Label Text="Fotograf" />
  <Image Source="obraz.jpg" Aspect="AspectFill" />
  <StackLayout Orientation="Horizontal">
    <Button Text="Like" />
    <Button Text="Share" />
  </StackLayout>
  <Label Text="Fotka z moich wakacji" />
</StackLayout>
A. obraz znajduje się po lewej stronie, a pozostałe elementy po prawej
B. elementy: tekst, obraz, przycisk Like, przycisk Share, tekst są ułożone jeden pod drugim
C. tekst "Fotograf" znajduje się po prawej stronie obrazu
D. przyciski są ustawione poziomo obok siebie
Analizując przedstawione opcje, możemy zauważyć kilka nieporozumień dotyczących sposobu układania elementów w XAML przy użyciu StackLayout. Pierwsza niepoprawna koncepcja sugeruje, że napis "Fotograf" jest położony po prawej stronie obrazu, co nie jest zgodne z rzeczywistym układem. W przypadku orientacji pionowej, jaką posiada zewnętrzny StackLayout, elementy są układane jeden pod drugim, co oznacza, że "Fotograf" znajduje się nad obrazem, a nie po jego prawej stronie. Druga koncepcja twierdzi, że wszystkie elementy są ułożone jeden pod drugim, co częściowo jest prawdą dla zewnętrznego układu, ale ignoruje fakt, że wewnętrzny StackLayout zawiera przyciski ułożone poziomo. Trzecia opcja była poprawna, co już omówiono powyżej. Czwarta nieprawidłowa koncepcja sugeruje, że obraz znajduje się po lewej, a inne elementy po prawej stronie, co nie odpowiada specyfice układu pionowego w StackLayout. Błędne myślenie często wynika z niewłaściwego rozumienia hierarchii i interakcji między zagnieżdżonymi układami w XAML. Zrozumienie, jak działa orientacja w StackLayout, jest kluczem do uniknięcia takich błędów i efektywnego projektowania interfejsów użytkownika.

Pytanie 18

Algorytmu Euklidesa, przedstawionego na schemacie, należy użyć do obliczenia.

Ilustracja do pytania
A. najmniejszej liczby pierwszej w danym zakresie
B. Największego Wspólnego Dzielnika
C. Najmniejszej Wspólnej Wielokrotności
D. największego elementu w zbiorze liczb
Algorytm Euklidesa to klasyczna metoda stosowana do wyznaczania największego wspólnego dzielnika (NWD) dwóch liczb całkowitych. Działa na zasadzie iteracyjnego odejmowania mniejszej liczby od większej aż do momentu, gdy obie liczby staną się równe. Wtedy ta wspólna wartość jest największym wspólnym dzielnikiem. Algorytm jest bardzo efektywny, nawet dla dużych liczb, co czyni go powszechnie stosowanym w praktycznych zastosowaniach, takich jak kryptografia czy optymalizacja komputerowa. W kryptografii, szczególnie w systemach kluczy publicznych, takich jak RSA, obliczanie NWD jest kluczowe dla generowania kluczy. Algorytm Euklidesa jest też podstawą dla bardziej zaawansowanych algorytmów, takich jak rozszerzony algorytm Euklidesa, który umożliwia obliczenie również współczynników liczbowych używanych w teoretycznych dowodach matematycznych. Jego implemetacja jest również często wykorzystywana w bibliotekach matematycznych języków programowania, co świadczy o jego uniwersalności i znaczeniu w dzisiejszej technologii.

Pytanie 19

Jak nazywa się wzorzec projektowy, do którego odnosi się ta definicja?

Wzorzec projektowy należący do grupy wzorców strukturalnych. Służy do ujednolicenia dostępu do złożonego systemu poprzez wystawienie uproszczonego, uporządkowanego interfejsu programistycznego, który ułatwia jego użycie.
Źródło Wikipedia. Wolna encyklopedia
A. Prototyp
B. Fasada
C. Dekorator
D. Kompozyt
Prototyp to wzorzec kreacyjny, który koncentruje się na tworzeniu nowych obiektów poprzez klonowanie istniejących. Różni się od fasady, ponieważ nie zajmuje się uproszczeniem interfejsów, lecz optymalizacją procesu tworzenia obiektów. Jest używany, gdy klasy instancji mają podobne stany i konieczne jest szybkie ich generowanie z zachowaniem pewnych właściwości. Dekorator natomiast to wzorzec strukturalny umożliwiający dynamiczne dodawanie nowych funkcjonalności do obiektów, bez modyfikacji ich struktury bazowej. Podstawowym celem dekoratora jest rozszerzenie możliwości obiektów, co odróżnia go od fasady, która skupia się na upraszczaniu dostępu do złożonych systemów. Dekorator działa na poziomie pojedynczych komponentów, gdzie fasada dotyczy całego systemu. Kompozyt umożliwia tworzenie hierarchicznych struktur obiektowych, pozwalając na jednolite traktowanie indywidualnych obiektów i ich złożonych struktur. Umożliwia pracę z drzewiastymi strukturami danych, co czyni go bardziej odpowiednim do zastosowań, gdzie istotna jest praca z kolekcjami obiektów jako całością. Wszystkie te wzorce mają odmienne założenia i zastosowania, a błąd w ich rozpoznaniu może wynikać z braku zrozumienia ich specyficznych ról i miejsc w architekturze oprogramowania. Wybór odpowiedniego wzorca wymaga zrozumienia zarówno wymagań systemowych, jak i ich długoterminowych implikacji na projekt i utrzymanie oprogramowania. Każdy z tych wzorców wnosi unikalne wartości, ale ich zastosowanie powinno być zgodne z konkretnymi potrzebami projektowymi i architektonicznymi systemu, nad którym się pracuje.

Pytanie 20

Jedną z dolegliwości, która pojawia się u programistów w wyniku długotrwałego korzystania z myszki komputerowej lub klawiatury, objawiającą się bólami, drętwieniem oraz zaburzeniami czucia w obszarze 1-3 palca dłoni jest

A. Dyskopatia
B. zespól cieśni kanału nadgarstka
C. zespół suchego oka
D. kifoza
Zespół cieśni kanału nadgarstka to schorzenie, które powstaje w wyniku ucisku na nerw pośrodkowy w kanale nadgarstka. Jest to wąski tunel utworzony przez kości nadgarstka oraz więzadła, przez który przechodzą ścięgna oraz nerwy odpowiedzialne za czucie i ruch w dłoni. Objawy zespołu cieśni kanału nadgarstka obejmują bóle, drętwienie oraz zaburzenia czucia, szczególnie w obszarze pierwszych trzech palców ręki. Praca z myszą komputerową i klawiaturą przez długi czas, szczególnie w niewłaściwej ergonomicznej pozycji, może prowadzić do nadmiernego obciążenia i zapalenia tkanek otaczających nerw pośrodkowy. W praktyce, osoby cierpiące na to schorzenie często skarżą się na problemy z chwytaniem przedmiotów, a także na osłabienie siły uchwytu. W leczeniu zespołu cieśni kanału nadgarstka zaleca się m.in. unikanie czynników przyczynowych, stosowanie ortez, fizjoterapię oraz w niektórych przypadkach leczenie chirurgiczne. Należy również zwrócić uwagę na ergonomię stanowiska pracy, co może znacząco zredukować ryzyko wystąpienia tej dolegliwości. Zarządzanie czasem spędzanym przy komputerze oraz regularne przerwy są kluczowe w prewencji tego schorzenia.

Pytanie 21

W jakim przypadku należy umieścić poszkodowanego w pozycji bocznej bezpiecznej?

A. gdy wystąpi omdlenie i brak tętna
B. w przypadku urazu kręgosłupa
C. w sytuacji urazu pleców, gdy osoba jest świadoma
D. w przypadku omdlenia, gdy osoba jest przytomna
Ułożenie poszkodowanego w pozycji bocznej bezpiecznej jest kluczowym krokiem w sytuacjach medycznych, zwłaszcza w przypadku omdlenia, gdy osoba jest przytomna i oddycha. Ta pozycja ma na celu zapewnienie drożności dróg oddechowych, co jest niezbędne, aby uniknąć zadławienia się własnymi wymiotami lub śliną. W sytuacji, gdy osoba traci przytomność, lecz nadal oddycha, ułożenie jej na boku minimalizuje ryzyko aspiracji i wspiera naturalne funkcje oddechowe. Ważne jest, aby przyjąć tę pozycję, ale również monitorować stan poszkodowanego, sprawdzając jego oddech i reakcje. Zgodnie z wytycznymi Europejskiej Rady Resuscytacji, w takich sytuacjach kluczowe jest, aby osoba była w pełni zabezpieczona i nie mogła się przewrócić. Przykłady zastosowania tej techniki obejmują sytuacje, gdzie osoba straciła przytomność na skutek omdlenia związanego z nagłym spadkiem ciśnienia krwi lub innymi czynnikami. Wykorzystanie pozycji bocznej bezpiecznej jest standardem w pierwszej pomocy i jest szkolone w ramach kursów dla ratowników oraz medyków.

Pytanie 22

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

A. Zbiór urządzeń technicznych używanych w pracy biurowej
B. Oprogramowanie wspierające jedynie zarządzanie danymi osobowymi
C. Sieć komputerowa, która umożliwia komunikację pomiędzy użytkownikami
D. Zespół ludzi, procedur, oprogramowania i sprzętu służący do przetwarzania danych
System informatyczny to kompleksowy zbiór elementów, który obejmuje ludzi, procedury, oprogramowanie oraz sprzęt, mający na celu przetwarzanie danych w sposób efektywny i zorganizowany. Kluczowym aspektem systemu informatycznego jest jego zdolność do integracji różnych komponentów w celu realizacji określonych zadań i osiągania wyznaczonych celów. Przykładem może być system ERP (Enterprise Resource Planning), który integruje finanse, produkcję, sprzedaż oraz zarządzanie zasobami ludzkimi w jednym środowisku. Takie zintegrowane podejście umożliwia nie tylko efektywne zarządzanie danymi, ale również generowanie raportów, analizę trendów oraz podejmowanie informowanych decyzji. Standardy, takie jak ITIL (Information Technology Infrastructure Library) czy CMMI (Capability Maturity Model Integration), podkreślają znaczenie procedur i zarządzania w kontekście systemów informatycznych, co wpływa na jakość usług i zadowolenie użytkowników. Systemy informatyczne są wykorzystywane w różnych branżach, od finansów po opiekę zdrowotną, gdzie przetwarzanie i zarządzanie danymi jest kluczowe dla efektywności operacyjnej.

Pytanie 23

Jaki jest zasadniczy cel ataku phishingowego?

A. Uniemożliwienie dostępu do usług internetowych
B. Zakłócanie pracy sieci przez nadmiarowe zapytania
C. Kradzież haseł z pamięci operacyjnej urządzenia
D. Zbieranie danych osobowych za pomocą podszywających się stron lub wiadomości
Atak phishingowy różni się od innych form cyberataków, które również mogą mieć na celu uzyskanie danych, lecz realizowane są w inny sposób. Zakłócenie działania sieci poprzez nadmiar zapytań, znane jako atak DDoS, polega na przesyłaniu ogromnej ilości zapytań do serwera, co skutkuje jego przeciążeniem i niedostępnością dla użytkowników. Tego typu ataki są ukierunkowane na infrastrukturę, a nie na pojedyncze dane osobowe użytkowników. W przypadku wykradania haseł z pamięci operacyjnej urządzenia, technika ta wymaga stosowania złośliwego oprogramowania, które potrafi skanować pamięć RAM i wyłuskiwać informacje. Jest to bardziej złożony proces, który wymaga bezpośredniego dostępu do systemu ofiary, co różni się od prostoty i zasięgu ataku phishingowego. Ostatnia z wymienionych możliwości, blokowanie dostępu do usług online, często jest związana z ransomware, które szyfruje pliki użytkownika i żąda okupu za ich odblokowanie. W przeciwieństwie do phishingu, tego typu ataki są bardziej destrukcyjne i mają na celu zaszkodzenie systemowi, a nie kradzież danych osobowych przez oszustwa. Dlatego też, mimo że wszystkie wymienione metody są niebezpieczne, to jednak ich mechanizmy i cele są zupełnie inne niż w przypadku ataku phishingowego.

Pytanie 24

Które z wymienionych działań zwiększa bezpieczeństwo transakcji online?

A. Zastosowanie publicznego Wi-Fi do logowania się na konto bankowe
B. Nieaktualizowanie oprogramowania przeglądarki
C. Weryfikowanie certyfikatów SSL na stronach zajmujących się transakcjami
D. Udostępnianie informacji o karcie kredytowej w e-mailach
Sprawdzanie certyfikatów SSL na stronach transakcyjnych to jeden z najważniejszych kroków w zapewnieniu bezpieczeństwa transakcji internetowych. Certyfikat SSL szyfruje dane przesyłane między użytkownikiem a serwerem, chroniąc je przed przechwyceniem przez osoby trzecie. Adresy stron z certyfikatem SSL zaczynają się od 'https', co wskazuje na bezpieczne połączenie. Certyfikaty SSL zapewniają integralność danych i są podstawą dla każdej strony internetowej obsługującej płatności lub przechowującej dane użytkowników. Zignorowanie tej kwestii naraża użytkowników na ataki typu man-in-the-middle i phishing.

Pytanie 25

Który z wymienionych elementów jest fundamentalny w architekturze klient-serwer?

A. Zdalne wykonywanie aplikacji na urządzeniu klienta
B. Scentralizowane przechowywanie danych
C. Wyłącznie komunikacja synchroniczna
D. Brak podziału na funkcje klienta i serwera
Scentralizowane przechowywanie danych to podstawowy element architektury klient-serwer. W takim modelu dane przechowywane są na serwerze, a klient uzyskuje do nich dostęp na żądanie. Dzięki temu możliwa jest efektywna synchronizacja danych oraz ich ochrona przed nieautoryzowanym dostępem. Architektura klient-serwer jest skalowalna i umożliwia obsługę wielu klientów jednocześnie, co czyni ją fundamentem dla większości nowoczesnych aplikacji webowych i mobilnych.

Pytanie 26

Jaki jest kluczowy zamysł wzorca "Kompozyt" (Composite)?

A. Określenie interfejsu komunikacji pomiędzy składnikami systemu
B. Danie możliwości dynamicznej zmiany zachowania obiektu
C. Umożliwienie klientom obsługi obiektów oraz ich zbiorów w spójny sposób
D. Stworzenie jednej klasy do zarządzania wieloma obiektami tego samego rodzaju
Zarządzanie wieloma obiektami tego samego typu to cecha wzorca Fabryka (Factory) lub Builder, a nie Kompozyt. Definiowanie interfejsu komunikacji między komponentami systemu to rola wzorca Mediator, który organizuje interakcje między różnymi obiektami. Umożliwienie dynamicznej zmiany zachowania obiektu jest domeną wzorca Strategia (Strategy) lub Dekorator (Decorator), które oferują elastyczność w zakresie modyfikacji zachowania podczas działania programu.

Pytanie 27

Jakie zadanie wykonuje debugger?

A. Generowanie pliku wykonywalnego programu
B. Przekładanie kodu źródłowego na język maszynowy
C. Umożliwianie analizy działania programu krok po kroku
D. Identyfikowanie błędów składniowych podczas kompilacji
Tłumaczenie kodu źródłowego na język maszynowy to zadanie kompilatora, a nie debuggera. Wykrywanie błędów składniowych odbywa się podczas procesu kompilacji lub analizy statycznej, ale debugger zajmuje się błędami występującymi w trakcie wykonywania programu. Tworzenie pliku wykonywalnego jest funkcją kompilatora, nie debuggera. Debugger nie generuje kodu – jego zadaniem jest monitorowanie i analizowanie kodu, który już został skompilowany lub interpretowany.

Pytanie 28

Jakie narzędzie jest najbardziej odpowiednie do identyfikacji błędów w trakcie działania programu?

A. Debugger
B. Linker
C. Interpreter
D. Kompilator
Kompilator służy do tłumaczenia kodu źródłowego na kod maszynowy przed uruchomieniem programu, ale nie analizuje błędów w czasie jego wykonywania. Interpreter tłumaczy kod na bieżąco, ale nie pozwala na zatrzymywanie programu i analizowanie jego działania krok po kroku. Linker to narzędzie, które łączy różne moduły i biblioteki w jeden plik wykonywalny, ale nie ma funkcji analizy błędów w czasie działania programu – jego rola kończy się po wygenerowaniu pliku wykonywalnego.

Pytanie 29

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

A. Sortowanie przez wstawianie
B. Wyszukiwanie liniowe
C. Obliczanie liczb Fibonacciego
D. Sortowanie bąbelkowe
Algorytmy obliczania liczb Fibonacciego są jednym z najbardziej klasycznych przykładów rekurencji. Algorytm ten polega na wywoływaniu funkcji, która sama odwołuje się do siebie, aby obliczyć kolejne liczby w sekwencji. Rekurencyjna natura obliczeń Fibonacciego sprawia, że algorytm jest prosty i intuicyjny w implementacji, choć może być mniej wydajny niż wersje iteracyjne. Rekurencja jest szeroko stosowana w problemach matematycznych i algorytmicznych, gdzie rozwiązanie większego problemu można uzyskać poprzez rozwiązywanie mniejszych, podobnych podproblemów.

Pytanie 30

Jaką komendę w języku C++ używa się do wielokrotnego uruchamiania tego samego bloku kodu?

A. if
B. while
C. break
D. switch
Instrukcja `if` to warunkowe wykonanie kodu, które nie powtarza bloku kodu wielokrotnie, a jedynie raz, jeśli warunek jest spełniony. Instrukcja `break` służy do natychmiastowego przerwania wykonywania pętli lub bloku kodu, ale sama w sobie nie powtarza kodu. Instrukcja `switch` umożliwia wielokrotne sprawdzanie różnych wartości jednej zmiennej, ale nie działa jak pętla – jest to struktura warunkowa, a nie iteracyjna. Żadna z tych instrukcji nie powtarza kodu tak, jak pętla `while`.

Pytanie 31

Które z wymienionych atrybutów klasy mogą być dostępne wyłącznie w obrębie tej klasy oraz jej klas potomnych?

A. Protected
B. Static
C. Public
D. Private
Modyfikator `protected` pozwala na dostęp do pól i metod klasy w ramach tej samej klasy oraz w klasach dziedziczących. Jest to pośredni poziom dostępu między `private` i `public`. Pola `protected` są ukryte przed innymi klasami spoza hierarchii dziedziczenia, ale pozostają dostępne w klasach pochodnych. Dzięki temu dziedziczenie staje się bardziej elastyczne, umożliwiając klasom potomnym korzystanie z chronionych elementów klasy bazowej. Przykład w C++: `class Pojazd { protected: int predkosc; }`. Klasy dziedziczące po `Pojazd` mogą używać `predkosc`, ale obiekty nie mają bezpośredniego dostępu do tego pola.

Pytanie 32

Które z wymienionych pól klasy można zainicjalizować przed stworzeniem obiektu?

A. Publiczne pole
B. Prywatne pole
C. Static pole
D. Chronione pole
Pola prywatne i chronione są związane z konkretnymi instancjami klasy, co oznacza, że nie mogą być inicjalizowane przed utworzeniem obiektu. Inicjalizacja takich pól następuje w konstruktorze klasy lub w trakcie tworzenia instancji. Publiczne pola, choć dostępne z dowolnego miejsca w programie, także wymagają istnienia konkretnej instancji obiektu, aby mogły zostać zainicjowane i użyte. Statyczność jest kluczowym czynnikiem pozwalającym na inicjalizację pola niezależnie od istnienia obiektu.

Pytanie 33

Co oznacza akronim IDE w kontekście programowania?

A. Zintegrowane Środowisko Debugowania
B. Interaktywny Silnik Programistyczny
C. Integrated Development Environment
D. Interaktywny Edytor Debugowania
Rozszyfrowanie IDE jako Integrated Debugging Environment to duży błąd. To środowisko daje nam o wiele więcej niż tylko debuggowanie. Interactive Development Engine to też nietrafione określenie. Tak naprawdę IDE to bardziej rozbudowane narzędzie, niż tylko silnik do programowania. A sugerowanie, że IDE ogranicza się do edytora debugowania, jest całkowicie nieprawdziwe, bo to środowisko oferuje naprawdę szeroki wachlarz funkcji, które są potrzebne na każdym etapie życia aplikacji.

Pytanie 34

Która z wymienionych aplikacji stanowi przykład prostego rozwiązania mobilnego?

A. Aplikacja do analizy danych finansowych
B. Aplikacja do monitorowania użycia pamięci RAM
C. Aplikacja typu zegar
D. Aplikacja z rozbudowanym systemem zarządzania projektami
Aplikacja typu zegar to jeden z najprostszych przykładów aplikacji mobilnej. Jej podstawowa funkcjonalność polega na wyświetlaniu aktualnego czasu oraz alarmów, a dodatkowo może zawierać funkcje takie jak minutnik czy stoper. Tego rodzaju aplikacje charakteryzują się niewielką liczbą funkcji, przejrzystym interfejsem i minimalnym zapotrzebowaniem na zasoby sprzętowe. Dzięki swojej prostocie, aplikacje typu zegar są doskonałym przykładem na to, jak przy użyciu niewielkiej liczby komponentów można stworzyć przydatne narzędzie dla użytkownika.

Pytanie 35

Co oznacza skrót SOLID w programowaniu obiektowym?

A. Standard tworzenia dokumentacji technicznej dla aplikacji
B. Popularna metodologia testowania aplikacji mobilnych i webowych
C. System organizacji zadań w metodologii zwinnej używany w Scrum
D. Zbiór pięciu zasad projektowania oprogramowania ułatwiających tworzenie czytelnego kodu
Skrót SOLID odnosi się do pięciu podstawowych zasad projektowania obiektowego, które zostały sformułowane przez Roberta C. Martina. Zasady te, a mianowicie: Single Responsibility Principle (SRP), Open/Closed Principle (OCP), Liskov Substitution Principle (LSP), Interface Segregation Principle (ISP) oraz Dependency Inversion Principle (DIP), mają na celu ułatwienie tworzenia czytelnego, łatwego do modyfikacji i rozszerzenia kodu. Przykładowo, zasada SRP mówi o tym, że każda klasa powinna mieć jedną odpowiedzialność, co pozwala na łatwiejsze wprowadzanie zmian oraz testowanie. Implementacja SOLID sprzyja także lepszej organizacji kodu, co jest kluczowe w dużych projektach, gdzie złożoność i liczba współpracujących komponentów mogą prowadzić do trudności w zarządzaniu. Przykład praktyczny można zobaczyć w aplikacji używającej wzorców projektowych, gdzie zasady SOLID pomagają w tworzeniu elastycznych i dobrze zorganizowanych systemów. W branży programistycznej, przestrzeganie tych zasad jest uznawane za dobrą praktykę, co przyczynia się do zwiększenia jakości oprogramowania oraz satysfakcji zespołów developerskich.

Pytanie 36

Który typ testów jest wykonywany na pojedynczych komponentach lub funkcjach w izolacji?

A. Testy akceptacyjne
B. Testy jednostkowe
C. Testy systemowe
D. Testy integracyjne
Nieprawidłowe odpowiedzi wskazują na pewne nieporozumienia dotyczące różnych typów testów. Testy integracyjne skupiają się na weryfikacji interakcji między różnymi komponentami systemu, a nie na testowaniu pojedynczych jednostek. Ich celem jest zapewnienie, że różne części aplikacji współpracują ze sobą poprawnie, co nie jest zgodne z definicją testów jednostkowych, które dotyczą izolowania pojedynczych funkcji. Z kolei testy systemowe mają na celu ocenę całego systemu jako całości, badając, czy spełnia on wymagania funkcjonalne i niefunkcjonalne. Takie podejście do testowania jest znacznie szersze niż testy jednostkowe, które nie obejmują interakcji między komponentami. Testy akceptacyjne z kolei sprawdzają, czy system spełnia kryteria akceptacji ustalone przez klienta, również nie koncentrując się na pojedynczych funkcjach. Wybierając niewłaściwy typ testów, można stracić z oczu niezbędność testowania kodu na poziomie jednostkowym, co prowadzi do późniejszych problemów z jakością oprogramowania. Wiele osób myli te różne rodzaje testów, co może skutkować błędnym zrozumieniem procesu testowania oprogramowania. Kluczowe jest, aby pamiętać, że każdy typ testu ma swoje specyficzne cele i zastosowania, a ich odpowiednie rozróżnienie jest niezbędne dla skutecznego zapewnienia jakości w inżynierii oprogramowania.

Pytanie 37

Które narzędzie służy do tworzenia makiet interfejsu użytkownika (UI mockups)?

A. Jenkins
B. Webpack
C. Figma
D. Postman
Jenkins, Postman i Webpack to narzędzia o zupełnie innym przeznaczeniu, co prowadzi do mylnych wniosków na temat ich zastosowań w kontekście tworzenia makiet interfejsu użytkownika. Jenkins jest narzędziem do ciągłej integracji i dostarczania oprogramowania, które automatyzuje procesy budowania, testowania i wdrażania aplikacji. Jego rolą jest wspieranie deweloperów w efektywnym zarządzaniu kodem źródłowym i zapewnieniu, że każda zmiana wprowadzona w kodzie nie wprowadza błędów. Z kolei Postman to narzędzie przeznaczone do testowania API, które umożliwia wysyłanie zapytań, analizowanie odpowiedzi oraz dokumentowanie interfejsów API, co jest kluczowe w kontekście integracji usług, ale nie ma związku z tworzeniem wizualnych makiet UI. Webpack jest narzędziem do bundlowania modułów JavaScript i zasobów, umożliwiającym optymalizację aplikacji webowych. Jego głównym celem jest zarządzanie złożonością aplikacji front-end, co jest istotne, ale nie ma zastosowania w kontekście projektowania interfejsów użytkownika. Typowym błędem myślowym jest mylenie narzędzi do prototypowania z narzędziami do zarządzania procesem wytwarzania oprogramowania. Zrozumienie, jakie narzędzia są odpowiednie do konkretnych zadań, jest kluczowe dla efektywnej pracy w zespole projektowym.

Pytanie 38

Co to jest Docker?

A. Narzędzie do testowania wydajności aplikacji webowych
B. Framework do tworzenia aplikacji mobilnych
C. System zarządzania bazami danych NoSQL
D. Platforma do tworzenia, wdrażania i uruchamiania aplikacji w kontenerach
Docker jest platformą do tworzenia, wdrażania i uruchamiania aplikacji w kontenerach, co oznacza, że umożliwia programistom izolowanie aplikacji oraz ich zależności w samodzielne jednostki, niezależne od środowiska, w którym są uruchamiane. Dzięki konteneryzacji, aplikacje działają zgodnie w różnych środowiskach, co znacząco upraszcza procesy związane z wdrażaniem i zarządzaniem. Przykładowo, z wykorzystaniem Dockera, programiści mogą stworzyć kontener z aplikacją webową, a następnie wdrożyć go na serwerze produkcyjnym, nie obawiając się, że aplikacja nie zadziała z powodu różnic w konfiguracjach systemu operacyjnego. Ponadto, Docker wspiera DevOps, co jest zgodne z obecnymi trendami w inżynierii oprogramowania, promując podejście Continuous Integration/Continuous Deployment (CI/CD). Używanie Dockera zwiększa efektywność pracy zespołów deweloperskich oraz ułatwia zarządzanie infrastrukturą, co jest istotne w kontekście dużych projektów. Dodatkowo, wspiera on standardy branżowe, takie jak microservices, które ze względu na swoje zalety są szeroko stosowane w nowoczesnych architekturach aplikacyjnych.

Pytanie 39

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

int x = 5;
int y = 10;
Console.WriteLine($"Suma {x} i {y} wynosi {x + y}");
A. Suma 5 i 10 wynosi 15
B. Suma x i y wynosi 15
C. Suma 5 i 10 wynosi x + y
D. Error: niewłaściwa składnia
W przypadku błędnych odpowiedzi warto zwrócić uwagę na kilka aspektów. Odpowiedź wskazująca, że wynik to 'Suma x i y wynosi 15', jest niepoprawna, ponieważ w sformatowanym ciągu tekstowym program odnosi się do wartości zmiennych, a nie do ich nazw. Wartości zmiennych są wykorzystywane w obliczeniach, a nie ich identyfikatory. Kiedy mówimy o 'Suma 5 i 10 wynosi x + y', także popełniamy błąd, ponieważ sformatowany ciąg nie wyświetli dosłownie 'x + y', lecz ich wartości. To wskazuje na nieporozumienie dotyczące interpolacji ciągów, która w C# dokonuje zamiany zmiennych na ich wartości i umieszcza je w tekście. Ostatnia propozycja, mówiąca o błędzie składni, jest także mylna, gdyż podany kod jest poprawny syntaktycznie i semantycznie. Typowe błędy często prowadzą do takich nieprawidłowych wniosków obejmują brak zrozumienia, jak działa interpolacja oraz nieznajomość podstawowych zasad programowania C#. Kluczowe jest zrozumienie, że używanie zmiennych w wyrażeniach tekstowych jest techniką, która pozwala programistom na bardziej dynamiczne i elastyczne tworzenie komunikatów, co jest nieocenione w kontekście tworzenia aplikacji interaktywnych.

Pytanie 40

Które z poniższych jest podstawowym rodzajem testów używanych w testowaniu jednostkowym?

A. Testy integracyjne
B. Testy systemowe
C. Testy akceptacyjne
D. Testy jednostkowe
Pozostałe rodzaje testów, mimo że są istotne w procesie testowania oprogramowania, nie są podstawowymi elementami testowania jednostkowego. Testy integracyjne mają na celu sprawdzenie, czy różne moduły systemu współpracują ze sobą poprawnie. Są one wykonywane po testach jednostkowych i skupiają się na interakcjach między komponentami. Testy systemowe to kolejny poziom testowania, który bada cały zintegrowany system pod kątem zgodności z wymaganiami. Są one szeroko zakrojone i testują zarówno funkcjonalność, jak i niefunkcjonalne aspekty systemu, takie jak wydajność czy bezpieczeństwo. Testy akceptacyjne to ostatnia faza testowania, w której sprawdza się, czy system spełnia kryteria akceptacji i jest gotowy do wdrożenia. Są one często wykonywane przez końcowych użytkowników lub klientów, aby upewnić się, że system spełnia ich potrzeby i oczekiwania. Wszystkie te formy testowania są ważne, ale nie zastępują testów jednostkowych, które są fundamentem weryfikacji poprawności poszczególnych części kodu. Typowym błędem jest myślenie, że można całkowicie polegać na testach wyższego poziomu, zaniedbując testy jednostkowe, co może prowadzić do trudnych do wykrycia błędów w późniejszych etapach projektów.