Wyniki egzaminu

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

Egzamin niezdany

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

Wymagane minimum: 20 punktów (50%)

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

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ź D
B. Odpowiedź B
C. Odpowiedź C
D. Odpowiedź A
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 2

Wykorzystując jeden z dwóch zaprezentowanych sposobów inkrementacji w językach z rodziny C lub Java, można zauważyć, że
Zapis pierwszy:

b = a++;
Zapis drugi:
b = ++a;
A. Wartość zmiennej b będzie wyższa po użyciu drugiego zapisu w porównaniu do pierwszego.
B. Tylko przy użyciu pierwszego zapisu zmienna a zostanie zwiększona o 1.
C. Bez względu na zastosowany sposób, w zmiennej b zawsze uzyskamy ten sam rezultat.
D. Drugi zapis nie jest zgodny ze składnią, co doprowadzi do błędów kompilacji.
Drugi zapis nie jest niezgodny ze składnią – zarówno preinkrementacja, jak i postinkrementacja są w pełni zgodne z zasadami języka i nie powodują błędów kompilacji. Niezależnie od wybranego zapisu, zmienna zostanie zwiększona, lecz kluczowa różnica polega na tym, kiedy dokładnie to następuje. Twierdzenie, że w każdym przypadku wynik będzie taki sam, jest błędne – różnice pojawiają się podczas użycia tych operatorów w bardziej złożonych wyrażeniach. Zapis pierwszy (preinkrementacja) nie jest jedynym sposobem na zwiększenie wartości zmiennej, chociaż w wielu sytuacjach jest preferowany ze względu na efektywność.

Pytanie 3

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

A. Ogranicza dostęp do metod publicznych w klasie
B. Automatycznie likwiduje obiekty klasy po zakończeniu działania programu
C. Zachowuje wspólną wartość dla wszystkich instancji tej klasy
D. Pozwala na dynamiczne dodawanie nowych metod
Dynamiczne tworzenie nowych metod to zadanie metaprogramowania lub refleksji, a nie funkcjonalność składników statycznych. Ograniczenie dostępu do metod publicznych jest realizowane za pomocą modyfikatorów dostępu, takich jak 'private' czy 'protected', a nie przez składniki statyczne. Automatyczne usuwanie obiektów klasy jest zadaniem destruktora i mechanizmu garbage collection (GC), a nie cechą składnika statycznego.

Pytanie 4

Jakie cechy powinien posiadać skuteczny negocjator?

A. dobra reputacja, przekora, porywczość
B. lojalność, nieśmiałość, uczciwość
C. asertywność, pesymizm, buta
D. intuicja, cierpliwość, asertywność
Analizując pozostałe propozycje, łatwo zauważyć, że zawierają one cechy, które niekoniecznie przekładają się na skuteczność w negocjacjach, a wręcz mogą utrudniać osiąganie korzystnych rezultatów. Często mylimy lojalność z umiejętnością prowadzenia twardych rozmów – bycie lojalnym wobec własnej firmy czy wartości jest ważne, ale nieśmiałość to cecha, która wyklucza aktywne uczestnictwo w negocjacjach. Osoba nieśmiała może bać się zabrać głos, wyrazić swoje potrzeby, co finalnie prowadzi do ustępstw na własną niekorzyść. Uczciwość – jasne, to fundament relacji biznesowych, tyle że sama uczciwość nie wystarczy, jeśli nie potrafimy prowadzić rozmów stanowczo i efektywnie. Dobra reputacja, przekora i porywczość to kolejny zestaw, który jest trochę mylący. Przekora sugeruje upór dla zasady, co w negocjacjach prowadzi do impasu. Porywczość natomiast sprawia, że negocjator daje się ponieść emocjom, a przecież właśnie opanowanie i zimna kalkulacja są wysoko cenione w tej profesji. Dobra reputacja jest atutem, ale jej brak nie wyklucza sukcesów negocjacyjnych – dużo ważniejsze są konkretne umiejętności. Z kolei zestawienie asertywności z pesymizmem i butą zupełnie się nie sprawdza. Pesymizm z góry zakłada niepowodzenie, co wpływa negatywnie na pewność siebie oraz stosunek do rozmówcy. Buta natomiast często prowadzi do niepotrzebnych spięć i zamyka drogę do kompromisu. W praktyce, profesjonaliści rekomendują, aby stawiać na empatię, cierpliwość, opanowanie, otwartość i umiejętność słuchania. Typowym błędem jest skupienie się na jednej pozytywnej cesze i ignorowanie jej kontekstu czy zestawienia z innymi – skuteczny negocjator to nie tylko ktoś z dobrą reputacją czy asertywnością, ale osoba, która potrafi połączyć wiele cech i narzędzi, by elastycznie reagować na zmieniające się warunki rozmów. Warto o tym pamiętać, analizując wymagania stawiane przed negocjatorami zarówno w podręcznikach, jak i praktyce zawodowej.

Pytanie 5

Jakie narzędzie programowe jest odpowiedzialne za konwersję kodu źródłowego na formę zrozumiałą dla maszyny, weryfikuje wszystkie polecenia pod kątem ewentualnych błędów, a następnie generuje moduł do wykonania?

A. dekompilator
B. kompilator
C. interpreter
D. debugger
Wybór narzędzi takich jak interpreter, debugger czy dekompilator jako odpowiedzi na to pytanie wynika często z niepełnego rozumienia ich rzeczywistej roli w procesie programowania. Interpreter, choć rzeczywiście przetwarza kod źródłowy, robi to w zupełnie inny sposób niż kompilator – tłumaczy instrukcje linia po linii w trakcie wykonywania, przez co nie generuje trwałego pliku wykonywalnego. To dobre rozwiązanie na etapie szybkiego prototypowania czy pracy z językami skryptowymi typu Python, ale nie nadaje się w sytuacjach, gdzie zależy nam na pełnej weryfikacji kodu i zoptymalizowanym pliku wynikowym. Debugger natomiast jest całkowicie osobnym narzędziem – jego rolą jest analiza działania już napisanego programu. Pozwala zatrzymać wykonanie, sprawdzić wartości zmiennych, wyłapać tzw. bugi – co jest nieocenione w pracy nad większymi projektami. Jednak debugger nie tłumaczy kodu, ani nie tworzy plików wykonywalnych, więc nie odpowiada za żadną formę translacji kodu źródłowego na kod maszynowy. Z kolei dekompilator to narzędzie służące do procesu odwrotnego niż kompilacja – próbuje z kodu maszynowego lub bajt-kodu wygenerować kod źródłowy, co jest wykorzystywane np. przy analizie programów bez dostępu do oryginalnych źródeł. Myślenie, że te narzędzia odpowiadają za kompilację, to dość częsty błąd, szczególnie na początku nauki programowania – czasem łatwo pomylić działania narzędzi, które mają styczność z kodem na różnych etapach jego życia. W praktyce, gdy mówimy o weryfikacji kodu pod kątem błędów i generowaniu pliku do uruchomienia, jedynym narzędziem spełniającym te wymagania jest kompilator. To on realizuje standardy języków programowania i dba o to, by efekt końcowy był nie tylko poprawny, ale też wydajny i zgodny z oczekiwaniami użytkownika.

Pytanie 6

Reguła zaangażowania i konsekwencji jako jedna z zasad wpływania na innych odnosi się

A. do odwzajemniania się osobie, która nam pomogła
B. do uległości wobec autorytetów
C. do doprowadzania spraw do końca
D. do kierowania się zdaniem danej grupy
Kiedy analizujemy regułę zaangażowania i konsekwencji, łatwo ją pomylić z innymi mechanizmami społecznymi wpływania na ludzi, bo te psychologiczne zasady czasem zachodzą na siebie w praktyce. Moim zdaniem najczęściej mylonym pojęciem tutaj jest reguła wzajemności, która mówi o tym, że ludzie czują się zobowiązani, by się odwdzięczyć za otrzymaną pomoc – to jednak zupełnie inny mechanizm, związany bardziej z relacjami i budowaniem zaufania niż z wewnętrzną potrzebą bycia konsekwentnym względem własnych decyzji. Z kolei kierowanie się zdaniem grupy to klasyczna presja społeczna czy konformizm, która też bywa silnym czynnikiem wpływu, ale opiera się na chęci dopasowania się do większości, a nie na wcześniejszych własnych zobowiązaniach. No i jeszcze uległość wobec autorytetów – tu chodzi głównie o to, że ludzie mają tendencję słuchać osób postrzeganych jako eksperci czy przełożeni, bo wierzą w ich większą wiedzę czy doświadczenie. To inny proces, nie związany z samą konsekwencją własnych działań. Typowym błędem jest patrzenie na te zasady jakby były zamienne, a w rzeczywistości każda wywołuje inne motywacje i wywołuje inny rodzaj zachowań. W branżowych dobrych praktykach, na przykład w sprzedaży B2B czy w projektach zespołowych, bardzo ważne jest rozróżnianie tych pojęć, by umiejętnie stosować odpowiednie narzędzia wpływu. Warto zawsze pamiętać, że reguła zaangażowania i konsekwencji opiera się na wewnętrznym przymusie trzymania się własnych wcześniejszych wyborów – niezależnie od opinii innych czy zewnętrznej presji.

Pytanie 7

W dwóch przypadkach opisano mechanizm znany jako Binding. Jego celem jest

W Android Studio:
<TextView android:text="@{viewmodel.userName}" />
W XAML:
<Label Text="{Binding Source={x:Reference slider2}, Path=Value}" />
A. zarządzanie mechanizmem obietnic (promises) lub obserwatora (observable) w programowaniu asynchronicznym
B. wiązać właściwości (property) elementu interfejsu użytkownika z danymi lub właściwością innego obiektu
C. wiązanie oraz eksportowanie plików z różnych modułów aplikacji
D. przetwarzanie zdarzeń kontrolek interfejsu użytkownika przez wywoływanie odpowiednich funkcji
Bardzo często można natknąć się na nieporozumienia dotyczące roli mechanizmu binding w nowoczesnych aplikacjach. Wiele osób błędnie utożsamia binding z obsługą zdarzeń, czyli na przykład automatycznym wywoływaniem funkcji po kliknięciu przycisku czy zmianie wartości na jakimś polu. Owszem, w interfejsach użytkownika obsługa zdarzeń jest istotna, ale binding to zupełnie inny poziom – on „przyczepia” dane (np. wartość liczbową, tekst, stan checkboxa) do właściwości elementów UI, tak by zmiana w jednym miejscu od razu aktualizowała drugie. Drugim typowym błędem jest mylenie bindingu z mechanizmami programowania asynchronicznego, jak promises czy observable – to trochę inna bajka. Promisy służą do obsługi operacji asynchronicznych, np. pobierania danych z sieci, a obserwatory pozwalają reagować na strumienie zdarzeń, jednak sam binding nie jest tym samym i nie odpowiada bezpośrednio za asynchroniczne zarządzanie danymi. Kolejnym nieporozumieniem bywa traktowanie bindingu jako coś związanego z eksportowaniem plików czy ogólnie zarządzaniem modułami aplikacji – to już w ogóle inny obszar, bardziej związany z organizacją środowiska, budowaniem aplikacji czy strukturą projektów. Z mojego doświadczenia wynika, że takie pomieszanie pojęć wynika głównie z powierzchownego poznania frameworków i chęci uproszczenia sobie obrazu działania aplikacji. Binding to fundament nowoczesnych interfejsów, ale nie zastępuje ani obsługi zdarzeń, ani nie jest narzędziem do zarządzania plikami czy asynchronicznością. On po prostu pozwala utrzymać spójność pomiędzy warstwą logiki a widokiem, co w praktyce czyni kod mniej podatnym na błędy i bardziej „żywym”, reagującym na zmiany.

Pytanie 8

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

MojaTablica tab1 = new MojaTablica<string, string>();
tab1["good"] = "dobry";
A. int tab2 = new MojaTablica()
B. MojaTablica tab2 = new MojaTablica()
C. MojaTablica tab2 = MOjaTablica()
D. int tab2[] = new MojaTablica()
Deklaracja int tab2[] = new MojaTablica(); jest nieprawidłowa, ponieważ int odnosi się do typów prostych, a nie do tablic asocjacyjnych. MojaTablica tab2 = MOjaTablica(); zawiera literówkę i nie inicjalizuje nowego obiektu. Int tab2 = new MojaTablica(); jest błędne, ponieważ tablica asocjacyjna nie może być przypisana do typu int – wymaga użycia typu zgodnego z definicją szablonu.

Pytanie 9

Co to jest git rebase?

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

Pytanie 10

Po wykonaniu poniższego kodu na konsoli zostanie wyświetlona liczba:

int a = 0x73;
cout << a;
A. 108
B. 115
C. 73
D. 0
Wiele osób myli się, gdy widzi zapis 0x73, uznając, że to po prostu liczba 73 w dziesiętnym, bo tak wygląda najprościej. Jednak w rzeczywistości ten prefiks „0x” informuje kompilator, że mamy do czynienia z liczbą zapisaną w systemie szesnastkowym (heksadecymalnym), a nie dziesiętnym. To jest taki bardzo charakterystyczny zapis w językach programowania (C, C++, Java, czasem nawet Python), który pozwala programiście jasno określić, w jakim systemie podaje liczbę. Zakładając, że ktoś wybierze 108 lub 73, można podejrzewać, że ta osoba nie przeliczyła heksadecymalnej liczby na dziesiętną lub po prostu nie zwróciła uwagi na prefiks. 0x73 to w rzeczywistości (7 * 16) + 3, czyli 112 + 3, co daje 115. Niektórym może się też wydawać, że heksadecymalne 0x73 to 73 dziesiętnie, ale to typowy błąd początkujących. Wybór zera z kolei może wynikać z nieporozumienia – być może ktoś pomyślał, że a nie zostało zainicjalizowane lub kod nie wypisuje nic, ale tutaj jawnie inicjujemy a wartością heksadecymalną. Praktyka pokazuje, że podobne nieporozumienia pojawiają się na początku nauki programowania, szczególnie gdy nie ma jeszcze „wyczucia” systemów liczbowych. Tak naprawdę, jeśli chcemy być profesjonalni, trzeba od razu nauczyć się, że każda liczba z 0x na początku jest heksadecymalna, a cout zawsze wypisze jej dziesiętną reprezentację, o ile nie zmienimy flagi strumienia (std::hex itd.). To takie podstawy, które potem pozwalają pewniej obracać się w kodzie, gdzie często występują maski bitowe czy operacje na rejestrach. Moim zdaniem, wielu początkujących inżynierów właśnie przez nieuwagę na takie detale traci sporo czasu na debugowanie prostych błędów. Warto więc na przyszłość za każdym razem zatrzymać się na chwilę i zastanowić, czy na pewno dobrze rozpoznajemy system liczbowy wykorzystywany w danym fragmencie kodu.

Pytanie 11

Jaką wydajność posiada sieć, która przesyła 500 MB danych w czasie 10 sekund?

A. 500 Mbps
B. 400 Mbps
C. 50 Mbps
D. 40 Mbps
Na pierwszy rzut oka mogłoby się wydawać, że 50 Mbps to rozsądny wynik, ponieważ 500 MB w 10 sekund to duża ilość danych, ale jeśli przeliczymy jednostki poprawnie, szybko zauważymy błąd. Wynik 50 Mbps oznaczałby, że w ciągu 10 sekund przesyłamy jedynie 500 megabitów, czyli około 62,5 MB danych. To znacznie mniej niż 500 MB, więc taka przepustowość byłaby zdecydowanie zbyt mała, aby przesłać taką ilość danych w podanym czasie. Z kolei odpowiedź 500 Mbps sugeruje przepustowość większą niż w rzeczywistości. Gdyby sieć miała taką wydajność, to w ciągu 10 sekund przesłałaby aż 625 MB danych (500 Mb/s × 10 s = 5000 Mb = 625 MB), czyli więcej niż w zadaniu. Oznacza to, że taka prędkość byłaby zawyżona w stosunku do faktycznej wartości. Natomiast 40 Mbps jest niepoprawne, gdyż oznaczałoby możliwość przesłania jedynie 400 megabitów w 10 sekund, co odpowiada zaledwie 50 MB danych. To prawie dziesięć razy mniej niż rzeczywista ilość danych w zadaniu, więc sieć o takiej przepustowości nie byłaby w stanie wykonać transmisji w podanym czasie. Wszystkie te błędne odpowiedzi wynikają z nieprawidłowego przeliczenia jednostek lub braku uwzględnienia faktu, że bajty należy zamienić na bity przed obliczeniem przepustowości. Tylko wynik 400 Mbps jest zgodny z zasadami i poprawnym przeliczeniem danych.

Pytanie 12

Jaki modyfikator umożliwia dostęp do elementu klasy z każdego miejsca w kodzie?

A. Private
B. Public
C. Protected
D. Static
Modyfikator 'Public' umożliwia dostęp do składowych klasy z dowolnego miejsca w programie, zarówno w ramach tej samej klasy, jak i poza nią. To najbardziej otwarty modyfikator dostępu, który pozwala na tworzenie interfejsów API, umożliwiających korzystanie z publicznych metod i właściwości przez inne klasy oraz moduły. W praktyce oznacza to, że publiczne metody są widoczne globalnie, co pozwala na ich wywoływanie bez ograniczeń. Jest to przydatne w przypadkach, gdy dana funkcjonalność musi być dostępna w różnych częściach programu lub aplikacji.

Pytanie 13

W jakiej sytuacji kolekcja typu lista okaże się bardziej wydajna niż tablica?

A. Gdy mamy pewność co do dokładnego rozmiaru kolekcji przed kompilacją
B. Gdy liczba elementów w kolekcji zmienia się dynamicznie
C. Gdy chcemy uzyskać dostęp do elementów przy pomocy indeksu
D. Gdy liczba elementów w kolekcji jest niezmienna
Lista to dynamiczna struktura danych, która pozwala na efektywne dodawanie i usuwanie elementów, zwłaszcza gdy liczba elementów zmienia się w trakcie działania programu. Listy są bardziej elastyczne niż tablice, ponieważ mogą dynamicznie dostosowywać swoją wielkość bez potrzeby alokacji dodatkowej pamięci. W przypadku dynamicznych operacji, takich jak częste wstawianie i usuwanie elementów, listy są znacznie bardziej wydajne niż tablice, które wymagają przesunięcia wszystkich elementów po każdej operacji. Listy świetnie sprawdzają się w implementacji kolejek, stosów oraz w strukturach, które muszą rosnąć i kurczyć się podczas działania aplikacji.

Pytanie 14

Co to jest wzorzec projektowy Singleton?

A. Wzorzec zapewniający istnienie tylko jednej instancji klasy w całej aplikacji
B. Wzorzec do zarządzania komunikacją między komponentami aplikacji
C. Metoda zabezpieczania aplikacji przed atakami typu SQL Injection
D. Technika optymalizacji kodu poprzez minimalizację liczby obiektów
Wzorzec projektowy, który zapewnia istnienie tylko jednej instancji, jest często mylony z innymi technikami programistycznymi. Niektóre osoby mogą uważać, że wzorzec do zarządzania komunikacją między komponentami aplikacji, jak mediator, ma podobne właściwości, jednak jego głównym celem jest zupełnie inny. Mediator nie tworzy instancji, lecz koordynuje interakcje między już istniejącymi obiektami. Z kolei optymalizacja kodu przez minimalizację liczby obiektów, o której mowa w jednej z odpowiedzi, nie jest celem wzorca Singleton. Wzorzec ten może prowadzić do niepożądanych skutków, gdyż wprowadza globalny stan, co z kolei czyni testowanie jednostkowe trudniejszym. Utrzymywanie tylko jednej instancji nie jest tożsame z zarządzaniem zasobami, a raczej może powodować problemy z dostępnością tych zasobów, jeśli nie zostanie poprawnie zaprojektowane. Przykładowo, użytkownik może pomylić Singleton z metodą zabezpieczającą aplikację przed atakami typu SQL Injection, co jest zupełnie odmiennym zagadnieniem związanym z bezpieczeństwem danych. Zrozumienie różnicy między tymi wzorcami i technikami jest kluczowe dla skutecznego projektowania oprogramowania.

Pytanie 15

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

Pytanie 16

Która z poniższych technologii służy do tworzenia aplikacji mobilnych za pomocą języków webowych?

A. React Native
B. Django
C. ASP.NET Core
D. Spring Boot
React Native to popularna technologia opracowana przez Facebook, która umożliwia tworzenie aplikacji mobilnych z wykorzystaniem języków webowych, takich jak JavaScript oraz biblioteki React. React Native umożliwia programistom pisanie kodu raz i uruchamianie go na różnych platformach mobilnych, w tym iOS i Android, co znacząco przyspiesza proces developmentu. Dzięki temu, aplikacje stworzone w React Native zyskują natywną wydajność oraz dostęp do natywnych komponentów, co jest kluczowe dla uzyskania dobrego doświadczenia użytkownika. Przykłady zastosowania React Native obejmują znane aplikacje, takie jak Facebook, Instagram czy Skype, które wykorzystują tę technologię, aby szybko wprowadzać zmiany i aktualizacje. W branży uznaje się, że stosowanie React Native przyczynia się do oszczędności czasu i zasobów, a także wspiera dobre praktyki związane z wielokrotnym użyciem kodu. Warto również zauważyć, że React Native wspiera hot reloading, co pozwala programistom na bieżąco obserwować zmiany w kodzie bez potrzeby ponownego uruchamiania aplikacji.

Pytanie 17

Jakie działania można podjąć, aby uniknąć pogorszenia wzroku podczas korzystania z komputera?

A. Korzytać ze słuchawek tłumiących dźwięki
B. Zachować stałą temperaturę w biurze
C. Stosować ergonomiczne podkładki pod ręce
D. Używać filtrów przeciwodblaskowych na ekranie
Stosowanie filtrów przeciwodblaskowych na monitorze to skuteczny sposób na zapobieganie pogorszeniu wzroku podczas pracy przy komputerze. Filtry te redukują odbicia światła, zmniejszając zmęczenie oczu i poprawiając komfort pracy. Długotrwała praca przy komputerze bez odpowiedniej ochrony może prowadzić do zespołu suchego oka, bólu głowy i problemów z widzeniem. Filtry przeciwodblaskowe to prosty, ale bardzo efektywny sposób na poprawę ergonomii stanowiska pracy. W połączeniu z odpowiednim ustawieniem monitora, regularnymi przerwami oraz ćwiczeniami wzrokowymi, pomagają one w utrzymaniu zdrowia oczu.

Pytanie 18

Co to jest Continuous Integration (CI)?

A. Praktyka automatycznego integrowania kodu w repozytorium wspólnym wraz z testami
B. Technika tworzenia aplikacji mobilnych w sposób przyrostowy
C. Metoda ciągłego monitorowania wydajności aplikacji w produkcji
D. Protokół komunikacji między różnymi częściami aplikacji
Continuous Integration (CI) to praktyka, która ma na celu automatyzację procesu integrowania kodu w repozytorium wspólnym. Główną ideą CI jest to, aby programiści regularnie dodawali swoje zmiany do głównej gałęzi kodu, co pozwala na bieżące testowanie aplikacji. Dzięki temu można szybko wykrywać i naprawiać błędy, zanim staną się one poważnym problemem. Typowym przykładem zastosowania CI jest użycie narzędzi takich jak Jenkins, GitLab CI czy Travis CI, które automatycznie uruchamiają zestaw testów po każdym wprowadzeniu zmian. Takie podejście nie tylko poprawia jakość kodu, ale również przyspiesza cykl wydania oprogramowania, co jest zgodne z najlepszymi praktykami w branży. Warto również zauważyć, że CI jest często częścią szerszego podejścia do DevOps, które integruje rozwój i operacje, aby zwiększyć efektywność całego procesu wytwarzania oprogramowania.

Pytanie 19

Jaką nazwę nosi framework CSS, który służy do definiowania wyglądu stron internetowych i którego klasy zostały użyte w przedstawionym przykładzie?

<div class="col-sm-3 col-md-6 col-lg-4">
  <button class="btn btn-primary dropdown-toggle" type="button">
</button>
</div>
A. Bootstrap
B. Yaml
C. Angular
D. Symfony
Bootstrap jest jednym z najpopularniejszych frameworków CSS używanych do tworzenia responsywnych aplikacji internetowych. Jest to zestaw narzędzi open-source, który oferuje gotowe klasy CSS oraz komponenty JavaScript, ułatwiające projektowanie interfejsów użytkownika. W podanym przykładzie klasy takie jak 'col-sm-3' 'col-md-6' i 'col-lg-4' odnoszą się do siatki Bootstrapowej, która umożliwia elastyczne rozplanowanie elementów na stronie w zależności od rozmiaru ekranu. Klasa 'btn-primary' stosowana jest w Bootstrapie do stylizacji przycisków w sposób, który pasuje do domyślnych kolorów motywu. Z kolei 'dropdown-toggle' jest używana do obsługi rozwijanych list. Dzięki Bootstrapowi można z łatwością tworzyć nowoczesne i estetyczne aplikacje, które są zgodne z zasadami responsywnego web designu, co jest kluczowym standardem w dzisiejszej branży. Użycie Bootstrapu przyspiesza proces developmentu, pozwalając skupić się na funkcjonalności i logice aplikacji, zamiast na ręcznym stylizowaniu elementów.

Pytanie 20

Jak wygląda kod uzupełnienia do dwóch dla liczby -5 w formacie binarnym przy użyciu 8 bitów?

A. 11111101
B. 10000101
C. 11111011
D. 00000101
Pierwsza z niepoprawnych odpowiedzi, która przedstawia wartość 00000101, jest błędna, ponieważ jest to binarna reprezentacja liczby 5, a nie -5. Kod uzupełnieniowy do dwóch wymaga przedstawienia liczby ujemnej poprzez inwersję bitów i dodanie jedynki. Ta odpowiedź nie ma zastosowania przy obliczaniu liczb ujemnych, stąd jest niewłaściwa. Kolejna odpowiedź, 11111101, również jest nieprawidłowa. W przypadku tej liczby, zainwersowanie bitów liczby 5 dawałoby 11111010, a dodanie 1 do tej wartości prowadziłoby do 11111011, co wskazuje, że ta odpowiedź nie jest zgodna z zasadą uzupełnienia do dwóch. Ostatnia z niepoprawnych odpowiedzi, 10000101, jest również błędna, ponieważ nie odpowiada żadnej z reprezentacji liczby -5. Gdybyśmy spróbowali konwertować ją z powrotem na wartość dziesiętną, otrzymalibyśmy 133, co jest zdecydowanie niepoprawne. Warto zauważyć, że każda z tych niepoprawnych odpowiedzi wskazuje na brak zrozumienia zasad konwersji liczb ujemnych w systemie binarnym, co jest kluczowe w informatyce i programowaniu, a ich użycie w praktycznych aplikacjach mogłoby prowadzić do poważnych błędów w obliczeniach.

Pytanie 21

Na jakim etapie cyklu życia projektu tworzony jest szczegółowy opis wymagań funkcjonalnych oraz niefunkcjonalnych?

A. Weryfikacja
B. Planowanie
C. Wdrożenie
D. Analiza
Często spotykam się z przekonaniem, że szczegółowy opis wymagań powstaje dopiero na etapie wdrożenia, weryfikacji czy planowania. Takie podejście prowadzi jednak do poważnych problemów w projektach IT. Jeśli wychodzimy z założenia, że podczas wdrożenia będziemy zbierać wymagania, to praktycznie ryzykujemy totalnym chaosem – na tym etapie powinno się już tylko realizować to, co wcześniej uzgodniono, a nie ustalać, co właściwie ma powstać. Weryfikacja natomiast dotyczy testowania i sprawdzania, czy efekt końcowy spełnia wymagania, ale testować można tylko to, co zostało jasno zdefiniowane wcześniej. Często popełnianym błędem jest też mylenie planowania z analizą – owszem, w planowaniu określa się harmonogram, kosztorys i podział zadań, ale bez rzetelnej analizy nie wiadomo, co de facto planować. Niestety, wielu początkujących myśli, że szczegóły funkcjonalne i niefunkcjonalne wymyśla się na bieżąco, co jest prostą drogą do konfliktów z klientem i niekończących się poprawek. Standardy branżowe, takie jak PMBOK czy Agile, jasno opisują, że analiza wymagań to fundament każdego projektu. Przełożenie tego na praktykę jest proste: najpierw dokładnie rozkładamy temat na czynniki pierwsze, a dopiero potem przechodzimy do planowania, implementacji i testów. Takie podejście naprawdę ratuje skórę w poważniejszych przedsięwzięciach.

Pytanie 22

Podejście obiektowe w rozwiązywaniu problemów obejmuje między innymi:

A. zmienne, procedury oraz funkcje
B. pola, metody, rekurencję oraz kwerendy
C. wyzwalacze i polimorfizm
D. klasy, obiekty oraz hermetyzację
Podejście obiektowe, zwane też programowaniem obiektowym (OOP), naprawdę opiera się na takich pojęciach jak klasy, obiekty i hermetyzacja. Klasa to taki szablon, z którego tworzy się obiekty – czyli konkretne instancje tej klasy działające w pamięci komputera. Hermetyzacja polega na tym, że ukrywamy szczegóły implementacji i wystawiamy na zewnątrz tylko niezbędne interfejsy. Moim zdaniem to jest jeden z najważniejszych aspektów OOP, bo pozwala nam lepiej zarządzać złożonością dużych systemów. Przykładowo, w językach takich jak Java czy C#, klasa samochód może mieć prywatne pola (np. numer VIN), a dostęp do nich uzyskujemy tylko przez określone publiczne metody (gettery i settery). To bardzo pomaga, gdy w zespole kilka osób pracuje nad tym samym kodem – nie trzeba wiedzieć wszystkiego o wnętrzu klasy, by z niej korzystać. W praktyce, modelowanie problemów za pomocą obiektów i klas pozwala odwzorować realne byty z rzeczywistego świata w oprogramowaniu. Standardy branżowe, jak SOLID czy zasada pojedynczej odpowiedzialności, podkreślają konieczność stosowania hermetyzacji, bo to przekłada się na elastyczność i łatwość utrzymania kodu. Z mojego doświadczenia, jeśli dobrze opanujesz te podstawy OOP, dużo szybciej zrozumiesz bardziej zaawansowane koncepty, jak dziedziczenie czy polimorfizm. To naprawdę solidny fundament, z którego korzysta praktycznie każdy nowoczesny język programowania.

Pytanie 23

Który system operacyjny jest podstawowym środowiskiem do tworzenia aplikacji mobilnych w języku Swift?

A. LG UX
B. Android
C. iOS
D. Windows UWP
Chociaż może się wydawać, że język programowania taki jak Swift da się wykorzystać na wielu różnych platformach mobilnych, to jednak jego projektowanie i rozwój były bardzo mocno związane z ekosystemem Apple. Android, choć jest największym systemem mobilnym na świecie, korzysta z innych technologii – głównie języka Java i Kotlin. Próbując pisać aplikacje mobilne na Androida w Swifcie, natrafiamy na całą masę problemów technicznych: brak oficjalnych narzędzi, wsparcia społeczności i integracji z Android SDK. Z moich obserwacji wynika, że są jakieś eksperymentalne mosty, ale to bardziej ciekawostka niż coś, co można używać w produkcji. Z kolei LG UX nie jest nawet osobnym systemem operacyjnym, tylko nakładką na Androida wykorzystywaną przez wybrane telefony LG – tu w ogóle nie ma mowy o natywnym wykorzystaniu Swifta, zresztą praktycznie nikt go tam nie używa. Jeśli chodzi o Windows UWP – ta platforma służy budowaniu uniwersalnych aplikacji na Windowsa, ale używa się tam innych technologii, głównie C#, czasami C++, czy nawet JavaScript. Swift na tej platformie to raczej egzotyczny temat i nie ma oficjalnego wsparcia. Myślę, że sporo osób myli dostępność języka (bo Swift jest open source) z możliwościami praktycznego wdrożenia. W branży przyjęło się, że wybierając środowisko do budowy aplikacji mobilnych w Swifcie, wybieramy przede wszystkim iOS, bo tylko tam mamy pełnię wsparcia, narzędzi i zgodność z wytycznymi Apple. Warto o tym pamiętać, żeby nie tracić czasu na próby wdrażania Swifta tam, gdzie po prostu nie jest to przewidziane przez producentów platform.

Pytanie 24

Które z poniższych stwierdzeń najlepiej charakteryzuje tablicę asocjacyjną?

A. Tablica, która przechowuje wartości, do których można uzyskać dostęp tylko za pomocą indeksów numerycznych
B. Tablica, która przechowuje wyłącznie dane tekstowe
C. Tablica przechowująca dane w formie par klucz-wartość
D. Tablica, która zmienia swoje wymiary w trakcie działania programu
A więc zwykła tablica działa na zasadzie numerów, nie ma kluczy tekstowych, więc nie ma mowy o parach klucz-wartość. Co prawda, tablice dynamiczne potrafią zmieniać rozmiar, ale mimo to, nie dadzą rady zorganizować danych w taki sposób. Tekst czy inne typy danych w tablicach są po prostu przechowywane jak inne. Kluczowa różnica jest taka, że tablice asocjacyjne pozwalają na użycie kluczy, co czyni je bardziej elastycznymi. Trochę się zgubiłeś w tym wszystkim.

Pytanie 25

Jaką technologię stosuje się do powiązania aplikacji internetowej z systemem baz danych?

A. SQL
B. HTTP
C. CSS
D. JavaScript
SQL, czyli język do zarządzania danymi, to mega ważna rzecz, jeśli chodzi o relacyjne bazy danych. Dzięki niemu można tworzyć, modyfikować, a nawet usuwać tabele. To taki most, który łączy aplikacje webowe z bazą danych. Dzięki SQL programiści mogą łatwo przechowywać i przetwarzać różne informacje na serwerze. Przykłady? Można generować listy produktów, ogarniać użytkowników czy analizować dane z transakcji. Właściwie bez SQL-a nie dałoby się zbudować solidnych aplikacji, na przykład tych, które działają na MySQL, PostgreSQL czy Microsoft SQL Server. Chociaż pewnie o tym wiesz, ale warto to zaznaczyć.

Pytanie 26

Jakie środki ochrony zbiorowej najlepiej chronią kręgosłup w warunkach pracy biurowej?

A. Regulowanie poziomu oświetlenia w biurze
B. Ograniczenie hałasu w pomieszczeniu
C. Umieszczanie monitorów na wysokości oczu
D. Korzystanie z regulowanych krzeseł i biurek
Używanie regulowanych foteli i biurek to jeden z najlepszych sposobów na zapobieganie problemom z kręgosłupem w pracy biurowej. Ergonomiczne fotele pozwalają na dostosowanie wysokości siedziska, podparcia lędźwiowego oraz kąta nachylenia oparcia, co zapewnia optymalne wsparcie dla kręgosłupa i zmniejsza ryzyko bólu pleców. Regulowane biurka umożliwiają zmianę pozycji pracy – z siedzącej na stojącą – co redukuje obciążenie kręgosłupa i poprawia krążenie krwi. Ergonomia stanowiska pracy to kluczowy element profilaktyki zdrowotnej, który minimalizuje ryzyko dolegliwości związanych z długotrwałą pracą w jednej pozycji.

Pytanie 27

Które z wymienionych praw autorskich nie wygasa po pewnym czasie?

A. Licencje wolnego oprogramowania
B. Autorskie prawa osobiste
C. Prawa pokrewne
D. Autorskie prawa majątkowe
Autorskie prawa osobiste to rodzaj praw autorskich, które nie wygasają po upływie określonego czasu i są bezterminowe. Obejmują one prawo do autorstwa, oznaczania dzieła swoim nazwiskiem oraz sprzeciwiania się wszelkim zmianom, które mogłyby naruszać reputację twórcy. Prawa osobiste są niezbywalne, co oznacza, że nie można ich przenieść na inną osobę ani sprzedać. Nawet po śmierci twórcy, prawo do ochrony integralności jego dzieła jest respektowane. W praktyce oznacza to, że choć prawa majątkowe mogą wygasnąć (np. po 70 latach od śmierci autora), prawo do bycia uznanym za twórcę trwa wiecznie.

Pytanie 28

Które z wymienionych stwierdzeń najtrafniej charakteryzuje WPF?

A. Biblioteka do obróbki danych w Pythonie
B. Framework umożliwiający zarządzanie urządzeniami IoT
C. Framework przeznaczony do budowy aplikacji internetowych
D. Framework przeznaczony do budowy aplikacji stacjonarnych w systemie Windows
No dobra, WPF to framework, którego używamy, żeby robić aplikacje na Windowsa. Jest częścią platformy .NET i super się nadaje do tworzenia ładnych interfejsów z użyciem XAML, co jest takim językiem, który pozwala na zaprojektowanie interfejsu. Dzięki WPF możemy korzystać z fajnych animacji i ogólnie mieć niezłe wizualizacje. W dodatku, wspiera model MVVM, co ułatwia rozdzielenie logiki aplikacji od tego, co widzi użytkownik. Także w wielu firmach, gdzie potrzebna jest zaawansowana grafika, WPF jest chętnie wykorzystywane.

Pytanie 29

Jakie metody pozwalają na przesłanie danych z serwera do aplikacji front-end?

A. formatu JSON
B. metody POST
C. protokołu SSH
D. biblioteki jQuery
Wśród zaproponowanych odpowiedzi pojawiło się kilka nieporozumień technicznych, które niestety są dość często spotykane u początkujących programistów. Przede wszystkim, biblioteka jQuery sama w sobie nie jest metodą przesyłania danych – to narzędzie, które może ułatwić pobieranie i wysyłanie danych na front-endzie, ale bez określonego formatu danych (np. JSON) jej obecność niewiele znaczy w kontekście komunikacji z serwerem. Moim zdaniem stąd czasem bierze się mylne przekonanie, że jQuery "przesyła dane", ale to tylko narzędzie, a nie metoda czy format wymiany informacji. Jeśli chodzi o protokół SSH, to jest on zupełnie niepowiązany z komunikacją webową – SSH służy głównie do bezpiecznego zdalnego zarządzania serwerami i nie jest wykorzystywany do przesyłania danych pomiędzy serwerem a przeglądarką. SSH dobrze się sprawdza przy pracy zdalnej na terminalu, ale nie przy typowej wymianie danych w aplikacjach webowych. Z kolei metoda POST to jeden z typów żądań HTTP, który określa sposób przesłania danych do serwera, ale nie precyzuje formatu tych danych. Możemy wysłać w POST-cie tekst, plik, dane binarne, XML czy JSON – nie jest to więc format, tylko sposób komunikacji. Bardzo często początkujący mylą metodę HTTP z formatem danych, co prowadzi do niedokładnych odpowiedzi. Odpowiednie rozróżnienie między narzędziem, protokołem, metodą żądania a formatem danych jest kluczowe w codziennej pracy webdevelopera. W praktyce to właśnie wybór formatu – a nie tylko metody żądania czy użytej biblioteki – decyduje o tym, jak łatwo aplikacje front-end i back-end będą w stanie się "dogadać". JSON jest tu najlepszym przykładem takiego uniwersalnego sposobu wymiany danych.

Pytanie 30

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

A. zadeklarować zmienną sprawdz przed jej wykorzystaniem w linii 11
B. naprawić błąd w funkcji sprawdz, który polega na braku nawiasów {} w pętli for
C. poprawnie zapisać warunek w instrukcji if w linii 11, np. sprawdz(x)==true
D. dodać deklarację funkcji sprawdz przed funkcją main
Wielu początkujących programistów skupia się na szczegółach składniowych lub drobiazgach logicznych, kiedy pojawia się błąd kompilacji w C++. Jednak często przyczyną jest coś bardzo podstawowego, jak brak deklaracji funkcji przed jej użyciem. Jeśli chodzi o zapis warunku w instrukcji 'if', to kompilator nie zgłasza błędu, gdy używamy wyrażenia typu 'if (sprawdz(x))' – to całkowicie poprawna składnia, a dopisywanie '==true' jest redundantne i nie wnosi niczego nowego. Bardzo często widzę, że ktoś skupia się na tym, żeby warunek koniecznie porównywać do true, ale tak naprawdę to kwestia stylu, nie poprawności. Pozostawienie nawiasów klamrowych w pętli for jest oczywiście dobrą praktyką, ale ich brak nie zawsze generuje błąd kompilacji, jeśli pętla ma tylko jedną instrukcję. Kompilator C++ potrafi to rozpoznać i nie zgłasza błędu – sprowadza się to bardziej do czytelności i unikania błędów logicznych niż do samej poprawności kompilacji. Odpowiedź dotycząca deklarowania zmiennej 'sprawdz' to już nieporozumienie – 'sprawdz' to funkcja, a nie zmienna, więc nie deklarujemy jej w ten sposób. Ten błąd pokazuje, jak łatwo pomylić pojęcia w językach programowania, zwłaszcza jeśli dopiero zaczynamy przygodę z kodowaniem. Główna zasada, którą warto tu zapamiętać, to: każda funkcja używana przed jej zdefiniowaniem musi być zadeklarowana – to właśnie tego brakuje w typowym przykładzie z pytania. Bez deklaracji kompilator nie wie, jaką sygnaturę ma funkcja, a to skutkuje błędem już na poziomie kompilacji. Z mojego doświadczenia wynika, że takie drobne rzeczy potrafią skutecznie utrudnić życie, dlatego warto czytać komunikaty kompilatora i znać podstawowe zasady działania języka C++.

Pytanie 31

Jakie informacje zawiera zestaw instrukcji (ISA) danego procesora?

A. Układ połączeń między procesorem a innymi elementami
B. Instrukcje, które procesor jest w stanie wykonać
C. Typy danych, które są trzymane w pamięci
D. Metodę obsługi pamięci podręcznej
Zestaw instrukcji, znany jako ISA, to taki jakby słownik poleceń, które procesor potrafi zrozumieć i wykonać. To mega ważny element w projektowaniu komputerów, bo to właśnie od niego zależy, jak dobrze i szybko działa system. Mamy różne rodzaje instrukcji, na przykład te do wykonywania działań matematycznych, logicznych, czy do przenoszenia danych. Popularne zestawy jak x86 albo ARM pokazują, jak programy rozmawiają z procesorem. Jak zrozumiesz ISA, to będzie łatwiej pisać lepszy kod i dostosowywać aplikacje do różnych architektur. No i co ważne, ISA też mówi, jak procesor interpretuje te instrukcje i zarządza danymi, co ma ogromny wpływ na to, jak wydajnie wszystko działa.

Pytanie 32

Co to jest polimorfizm w programowaniu obiektowym?

A. Proces tworzenia nowej klasy na podstawie istniejącej
B. Zdolność obiektów różnych klas do reagowania na tę samą metodę w sposób odpowiedni dla ich klasy
C. Zdolność klasy do posiadania wielu konstruktorów
D. Mechanizm ukrywania szczegółów implementacji przed zewnętrznymi klasami
W programowaniu obiektowym pojawia się wiele koncepcji, które mogą być mylone z polimorfizmem, niemniej żadna z nich w pełni nie oddaje istoty tego pojęcia. Na przykład ukrywanie szczegółów implementacji, czyli enkapsulacja, to proces, który ma na celu zabezpieczenie danych obiektu przed nieautoryzowanym dostępem, ale nie ma związku z możliwością różnych klas do reagowania w ten sam sposób na jedną metodę. Z kolei dziedziczenie, które polega na tworzeniu nowej klasy na bazie istniejącej, to mechanizm, który pozwala na rozszerzanie funkcjonalności, ale wcale nie zapewnia, że obiekty klas dziedziczących będą miały tę samą metodę, ani że będą się zachowywały w sposób zgodny z polimorfizmem. Kolejnym błędnym podejściem jest myślenie, że polimorfizm odnosi się do posiadania wielu konstruktorów w tej samej klasie. Choć nadmiarowość konstruktorów jest ważna, to nie ma ona nic wspólnego z elastycznością obiektów i ich zdolnością do reagowania na te same metody. Zazwyczaj błędne rozumienie polimorfizmu wynika z niejasności w zakresie dziedziczenia i interfejsów, co może prowadzić do niepoprawnego projektowania systemów w programowaniu obiektowym. W praktyce polimorfizm oznacza, że obiekty różnych klas mogą być traktowane jako obiekty tej samej klasy, co jest istotne dla realizacji wielu wzorców projektowych.

Pytanie 33

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

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

Pytanie 34

Wskaź kod, który spowoduje wyświetlenie okna dialogowego przedstawionego na ilustracji. Dla uproszczenia kodu, zrezygnowano z atrybutów znaczników

Ilustracja do pytania
A. kod 4
B. kod 3
C. kod 2
D. kod 1
Odpowiedź, którą wybrałeś, to kod 2, i nie ma co do tego wątpliwości. Dobrze, że zauważyłeś wszystkie elementy, które były w oknie dialogowym. W tym kodzie masz TextBox na górze, który pozwala na wpisanie tekstu. Dwa CheckBoxy po lewej stronie to te typowe pola wyboru, które też były widoczne. Po prawej stronie masz trzy RadioButtony, które tworzą grupę przycisków - to jest właśnie to, co powinno być. Na dole widoczny jest przycisk Button z napisem Test, co też jest zgodne z obrazkiem. Takie rozmieszczenie to klucz do stworzenia dobrego interfejsu. Wiesz, w praktyce w wielu aplikacjach używa się właśnie tych elementów do prostych formularzy. Jeżeli rozumiesz, jak te komponenty działają i jak je ze sobą łączyć, to naprawdę dobrze ci to pójdzie w przyszłości w tworzeniu ładnych i funkcjonalnych interfejsów.

Pytanie 35

Jaki będzie wynik działania poniższego kodu JavaScript?

function foo() { console.log(a); var a = 1; console.log(a); } foo();
A. 1, 1
B. undefined, 1
C. ReferenceError, 1
D. undefined, undefined
Wynikiem działania tego kodu nie może być 'ReferenceError, 1', ponieważ w sytuacji, gdy zmienna 'a' została zadeklarowana za pomocą 'var', nie może wystąpić błąd referencyjny związany z odwołaniem się do niej przed jej przypisaniem. Wartość zmiennej 'a' przed jej przypisaniem to 'undefined', a nie 'ReferenceError', co jest typowym nieporozumieniem w kontekście hoisting. W przypadku zmiennych zadeklarowanych za pomocą 'let' lub 'const', rzeczywiście moglibyśmy napotkać 'ReferenceError', gdyż te zmienne mają tzw. „temporal dead zone” przed ich zadeklarowaniem. Wynik 'undefined, undefined' również nie jest poprawny, ponieważ po pierwszym 'console.log' zmienna 'a' jest jeszcze niezainicjalizowana i wyświetli 'undefined', ale drugie 'console.log' z pewnością wyświetli wartość '1', po przypisaniu. Odpowiedź '1, 1' jest również błędna, ponieważ pierwsze logowanie 'a' przed przypisaniem z pewnością da 'undefined'. Ważne jest zrozumienie zasad hoisting oraz jak różne typy deklaracji zmiennych wpływają na ich zakres i inicjalizację, aby unikać nieporozumień w przyszłości.

Pytanie 36

Które z poniższych pojęć nie jest związane z React.js?

A. JSX
B. Virtual DOM
C. Hooks
D. Directives
Directives to pojęcie związane głównie z frameworkiem Angular, a nie z React.js. W kontekście Angular, dyrektywy są używane do rozszerzania HTML-a o nowe funkcje, co pozwala na bezpośrednią manipulację DOM-em i tworzenie niestandardowych znaczników. React.js natomiast korzysta z zupełnie innej filozofii, w której komponenty są podstawowym budulcem aplikacji. W React.js używamy JSX, co jest syntaktycznym rozszerzeniem JavaScriptu, pozwalającym na pisanie kodu w sposób przypominający HTML. Dodatkowo, React korzysta z Virtual DOM, co zwiększa wydajność poprzez minimalizację operacji na prawdziwym DOM-ie. React wprowadził także mechanizm Hooks, który pozwala na użycie stanu i efektów ubocznych w komponentach funkcyjnych, co jest istotne w nowoczesnym podejściu do tworzenia aplikacji. Zrozumienie różnic pomiędzy tymi podejściami jest kluczowe dla efektywnego korzystania z odpowiednich narzędzi w zależności od wymagań projektu.

Pytanie 37

Który z objawów może sugerować zawał serca?

A. Intensywny ból w klatce piersiowej promieniujący do lewej ręki
B. Spadek nastroju
C. Ból brzucha po spożyciu posiłku
D. Gorączka oraz dreszcze
Silny ból w klatce piersiowej promieniujący do lewej ręki to klasyczny objaw zawału serca (ostrego zespołu wieńcowego). Ból ten często pojawia się nagle, jest intensywny, gniotący lub piekący i może towarzyszyć mu duszność, zawroty głowy, zimne poty i nudności. Zawał serca wynika z zablokowania jednej z tętnic wieńcowych, co prowadzi do niedokrwienia mięśnia sercowego. Szybka reakcja i wezwanie pomocy medycznej mogą uratować życie i zminimalizować uszkodzenia serca. Każda minuta jest kluczowa – nie należy czekać na ustąpienie objawów, lecz natychmiast zadzwonić na numer alarmowy 112 lub udać się do najbliższego szpitala.

Pytanie 38

Co to jest klasa abstrakcyjna?

A. Klasa, która nie może posiadać żadnych metod
B. Klasa, która zawsze dziedziczy z klasy bazowej
C. Klasa, która może zawierać zarówno metody zdefiniowane, jak i niezdefiniowane (czysto wirtualne)
D. Klasa, która może być dziedziczona, ale nie można jej instancjonować
Poprawną odpowiedzią jest „Klasa, która może być dziedziczona, ale nie można jej instancjonować”, ponieważ najlepiej oddaje istotę klasy abstrakcyjnej w programowaniu obiektowym. Klasa abstrakcyjna pełni rolę szablonu dla klas pochodnych – określa wspólną strukturę, zachowania lub interfejs, które powinny zostać zaimplementowane przez klasy dziedziczące. Nie można tworzyć jej obiektów, ponieważ nie reprezentuje ona kompletnego bytu, lecz raczej pojęcie ogólne. Takie podejście umożliwia stosowanie dziedziczenia i polimorfizmu, poprawia czytelność kodu oraz ułatwia jego rozbudowę i utrzymanie. Klasy abstrakcyjne są często wykorzystywane do narzucania jednolitego sposobu implementacji metod w całej hierarchii klas. Pozostałe odpowiedzi są niepoprawne, ponieważ opisują cechy, które nie definiują jednoznacznie klasy abstrakcyjnej lub są błędne. Stwierdzenie „Klasa, która zawsze dziedziczy z klasy bazowej” jest nieprawidłowe, gdyż klasa abstrakcyjna sama może być klasą bazową i nie musi dziedziczyć po innej klasie. Odpowiedź „Klasa, która może zawierać zarówno metody zdefiniowane, jak i niezdefiniowane (czysto wirtualne)” jest nieprecyzyjna – taka możliwość często występuje, ale nie jest warunkiem koniecznym, by uznać klasę za abstrakcyjną. Natomiast odpowiedź „Klasa, która nie może posiadać żadnych metod” jest całkowicie błędna, ponieważ klasy abstrakcyjne mogą zawierać zarówno metody abstrakcyjne, jak i w pełni zaimplementowane. Zrozumienie tych różnic pozwala poprawnie rozpoznać, czym naprawdę jest klasa abstrakcyjna.

Pytanie 39

Co oznacza termin 'immutability' w programowaniu funkcyjnym?

A. Funkcje mogą być przypisywane do zmiennych
B. Stan obiektu nie może być modyfikowany po jego utworzeniu
C. Obiekty są automatycznie usuwane z pamięci
D. Kod może być wykonywany równolegle
Termin 'immutability' w programowaniu funkcyjnym odnosi się do właściwości obiektów, które po utworzeniu nie mogą być modyfikowane. W kontekście programowania funkcyjnego, gdzie funkcje są kluczowym składnikiem, immutability jest fundamentalnym założeniem, które pozwala na tworzenie bardziej przewidywalnych i bezpiecznych aplikacji. Kiedy obiekty są niemodyfikowalne, każde ich 'zmiana' generuje nowy obiekt, zamiast aktualizować istniejący, co eliminuję problemy związane z nieprzewidywalnym stanem aplikacji. Przykładem może być język programowania Scala, gdzie kolekcje, takie jak List, są niemodyfikowalne z założenia. Z perspektywy dobrych praktyk, immutability przyczynia się do łatwiejszej analizy kodu, testowania jednostkowego oraz równoległego przetwarzania danych. Ponadto, programowanie funkcyjne, bazujące na tej koncepcji, sprzyja tworzeniu czystych, modularnych i łatwych do przetestowania aplikacji.

Pytanie 40

Jakie sformułowanie najlepiej oddaje złożoność obliczeniową algorytmu quicksort?

A. jest zawsze mniejsza niż złożoność jakiegokolwiek innego algorytmu sortowania
B. jest różna w zależności od wyboru elementu dzielącego
C. jest większa niż złożoność sortowania bąbelkowego
D. jest większa niż O(n2)
Twierdzenie, że złożoność quicksort jest wyższa niż sortowania bąbelkowego, jest błędne – bubble sort ma złożoność O(n²) niezależnie od danych wejściowych, co czyni go jednym z najwolniejszych algorytmów. Quicksort nigdy nie ma złożoności wyższej niż O(n²) w najgorszym przypadku, co oznacza, że jest zawsze bardziej efektywny niż bubble sort. Twierdzenie, że quicksort zawsze jest szybszy niż jakikolwiek inny algorytm, jest nieprawdziwe – algorytmy takie jak counting sort lub radix sort mogą działać szybciej w określonych przypadkach. Ostateczna wydajność quicksort zależy od implementacji oraz charakterystyki danych wejściowych.