Wyniki egzaminu

Informacje o egzaminie:
  • Zawód: Technik programista
  • Kwalifikacja: INF.04 - Projektowanie, programowanie i testowanie aplikacji
  • Data rozpoczęcia: 8 grudnia 2025 10:16
  • Data zakończenia: 8 grudnia 2025 11:02

Egzamin zdany!

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

Wymagane minimum: 20 punktów (50%)

Pochwal się swoim wynikiem!
Szczegółowe wyniki:
Pytanie 1

Który z wymienionych procesów NIE jest częścią etapu kompilacji?

A. Analiza działania programu w czasie rzeczywistym
B. Weryfikacja błędów składniowych
C. Tłumaczenie kodu źródłowego na język maszynowy
D. Optymalizacja kodu
Optymalizacja kodu to integralna część kompilacji, mająca na celu zwiększenie wydajności programu poprzez usunięcie zbędnych instrukcji i usprawnienie algorytmów. Tłumaczenie kodu źródłowego na język maszynowy jest głównym zadaniem kompilatora, który generuje plik wykonywalny. Weryfikacja błędów składniowych jest jednym z pierwszych etapów kompilacji, mającym na celu upewnienie się, że kod jest poprawny pod względem składni, zanim zostanie przekształcony na kod maszynowy.

Pytanie 2

Na równoważnych pod względem funkcjonalnym listingach fragmentów aplikacji Angular oraz React.js utworzono listę punktowaną, która zawiera:

Definicja typu:

books = ["Harry Potter", "Hobbit", "Władca pierścieni"];

Kod Angular:
<ul>
    <li *ngFor = "let book of books"> {{book}} </li>
</ul>

Kod React.js:
<ul>
    {this.books.map(book => <li key={book}> book </li>)}
</ul>
A. Taką liczbę elementów, ile znajduje się w tablicy books; w każdym punkcie listy umieszczony jest jeden element tablicy.
B. Wyłącznie jeden element o treści Harry Potter, Hobbit, Władca pierścieni.
C. Jedynie jeden element o treści Harry Potter.
D. Tyle elementów, ile znajduje się w tablicy books; w każdym punkcie listy widnieje element o treści {book}.
W pytaniu chodziło o bardzo fundamentalny mechanizm w nowoczesnych frameworkach frontendowych: dynamiczne generowanie elementów listy na podstawie danych z tablicy. Częstym błędem jest doszukiwanie się w kodzie magicznych wartości lub mylenie sposobu działania szablonów z faktycznym efektem końcowym. Przykładowo, jeśli ktoś uzna, że pojawi się jeden element z wypisaną całą tablicą jako tekst, to prawdopodobnie nie rozumie, że każda iteracja *ngFor (w Angularze) czy metoda map (w React.js) generuje fizycznie osobny <li> dla każdego wpisu. To nie jest jedno pole tekstowe, ale wiele autonomicznych elementów. Kolejna rzecz to myślenie, że pojawi się tylko pierwszy element – takie podejście wynika często z niezrozumienia zasady działania pętli w szablonach, gdzie proces rozpoczyna się dla każdego elementu po kolei. Często też myli się składnię Reacta i widzi w niej coś na kształt szablonu z placeholderem {book}, zapominając, że to wyrażenie jest oceniane w JavaScript i renderuje konkretną wartość, a nie dosłowny napis z nawiasami klamrowymi. Moim zdaniem to jeden z najpopularniejszych błędów – traktowanie składni szablonów lub JSX zbyt dosłownie, bez zrozumienia, że to dynamiczne narzędzia. Warto pamiętać, że we współczesnych aplikacjach webowych takie podejście jest normą: nie piszesz ręcznie każdego <li>, tylko generujesz je ze źródła danych. Pominięcie tego mechanizmu prowadzi do kodu nieelastycznego, trudnego w utrzymaniu i skalowaniu. Z doświadczenia wiem, że zrozumienie tej zasady znacznie przyspiesza naukę zarówno Angulara, jak i Reacta, bo ten wzorzec powtarza się praktycznie wszędzie tam, gdzie masz do czynienia z kolekcjami danych i ich wizualizacją w interfejsie użytkownika.

Pytanie 3

Który z wymienionych frameworków służy do budowy aplikacji webowych w C#?

A. Angular
B. ASP.NET Core
C. React.js
D. Django
Django to framework dla języka Python, który nie jest związany z ekosystemem C#. Angular to framework frontendowy oparty na TypeScript, używany do tworzenia interfejsów użytkownika, ale nie pełni roli backendowego frameworka webowego w C#. React.js to biblioteka JavaScript dedykowana budowie dynamicznych komponentów frontendowych i nie jest wykorzystywana do budowy backendowych aplikacji w C#.

Pytanie 4

Jaką wartość zwróci funkcja napisana w języku C++, jeżeli jej argumentem wejściowym jest tablica stworzona w następujący sposób:

int tablica[6] = {3,4,2,4,10,0};

int fun1(int tab[]) {
    int wynik = 0;

    for(int i = 0; i < 6; i++)
        wynik += tab[i];
    return wynik;
}
A. 0
B. 23
C. 20
D. 10
W tego typu zadaniach bardzo łatwo popełnić błąd w ocenie działania pętli oraz sumowania wartości w tablicy. Często pojawia się przekonanie, że funkcja może zwracać zero, bo ostatni element tablicy to 0 – ale trzeba pamiętać, że funkcja sumuje wszystkie elementy i zero po prostu nie wpływa na całą sumę, więc wynik się nie wyzeruje. Bywa też, że sugerujemy się pierwszą liczbą z tablicy albo jakąś wyróżniającą się, na przykład 10, myśląc, że to ona jest odpowiedzią – ale to nie ma uzasadnienia w kodzie. W pętli for wyraźnie jest napisane i < 6, czyli przeglądamy sześć elementów. Każdy z nich jest dodawany do zmiennej wynik. Kod nie ma żadnych warunków ani instrukcji przerwania, więc nie można zatrzymać się „na” jakiejś wartości, ani zignorować jakiejkolwiek liczby. Niektóre osoby mogą też popełnić błąd i dodać tylko część elementów albo pomylić kolejność, przez co suma wychodzi 10, 20 lub inna, ale przy mechanicznej analizie kodu to niemożliwe. Odpowiedź 20 pojawia się czasem, kiedy ktoś przez przypadek nie zliczy ostatniego zera, a z kolei 10 to typowy skrót myślowy – może wynikający z szybkiego rzutu oka na największą liczbę w tablicy, jednak suma elementów to nie to samo, co ich maksimum. Z mojego doświadczenia wynika, że bardzo wielu uczniów nie przywiązuje wagi do sumowania wszystkich elementów, zwłaszcza jak pojawia się zero – a przecież matematyka jest tu bezlitosna. W programowaniu sumujesz wszystko jak leci, jeśli nie ma warunku czy filtru. Takie drobne nawyki, jak dokładne śledzenie każdej iteracji pętli, potem procentują podczas bardziej złożonych zadań na egzaminach czy w prawdziwych projektach. Pamiętaj: jeśli kod nie sprawdza warunków, to wykonuje dokładnie to, co jest napisane – nic mniej, nic więcej. Warto się tego trzymać.

Pytanie 5

Wskaż uproszczoną wersję kodu XAML dla elementów w pokazanym oknie dialogowym?

Ilustracja do pytania
A. Kod 3
B. Kod 4
C. Kod 1
D. Kod 2
Dobrze jest znać podstawowe różnice pomiędzy ListBox, ComboBox, CheckBox, RadioButton oraz Label w XAML. W tym oknie dialogowym widać wyraźnie, że po lewej stronie użytkownik ma możliwość wyboru gatunku zwierzęcia spośród kilku opcji wyświetlonych jednocześnie. Takie zadanie najlepiej spełnia ListBox, bo umożliwia wygodną selekcję z widocznej listy. U góry po prawej jest pole tekstowe do wpisania imienia zwierzaka, więc TextBox jak najbardziej pasuje. Poniżej mamy dwa pola wyboru – „Zaszczepiony?” i „Na diecie?” – to są typowe przypadki na CheckBoxy: można zaznaczyć dowolne lub oba naraz. Kluczowe jest to, że CheckBox pozwala użytkownikowi wybrać dowolną kombinację, a nie tylko jedną opcję jak RadioButton. Z mojego doświadczenia często początkujący mylą ComboBox z ListBoxem, ale tu akurat lista jest zawsze widoczna, co jest typowe dla ListBoxa. Stosowanie CheckBoxów dla takich dwustanowych opcji też jest zgodne z dobrymi praktykami UX i standardami opisu formularzy w XAML. W pracy zawodowej często się to wykorzystuje, bo kod jest czytelny i łatwo go rozszerzać. Właśnie taki zestaw – ListBox, TextBox, CheckBox – jest najbardziej przejrzysty i zgodny z zamysłem projektanta interfejsów. Fajnie jest to zapamiętać, bo ta kombinacja pojawia się w wielu firmowych projektach.

Pytanie 6

Narzędzie przeznaczone do rozwijania aplikacji w systemie WPf (ang. Windows Presentation Foundation) to

A. Visual Studio
B. NetBeans
C. XamarinStudio
D. PyCharm
Choć na rynku dostępnych jest sporo różnych środowisk programistycznych, tylko niektóre z nich są przystosowane do konkretnych technologii. NetBeans to popularne IDE, ale wywodzące się głównie ze świata Javy i używane raczej do projektów w tym języku oraz powiązanych frameworków, takich jak JavaFX czy Swing. Nie oferuje on wsparcia dla WPF oraz nie obsługuje platformy .NET, więc trudno w nim mówić o komforcie pracy z aplikacjami Windowsowych interfejsów użytkownika. PyCharm to zaawansowane środowisko, ale skupiające się przede wszystkim na Pythonie. Mając do czynienia z WPF, nie znajdziesz tu nawet podstawowych funkcji jak projektant XAML-a czy kompilator C#. XamarinStudio natomiast przez długi czas służył do budowy aplikacji mobilnych, głównie cross-platformowych (Android, iOS), bazując na platformie Xamarin.Forms – choć opiera się na .NET, to jednak w całkowicie innym kontekście. Częstym błędem jest myślenie, że każde środowisko .NET automatycznie obsługuje wszystkie jego technologie, ale tak nie jest – WPF to dosyć specyficzna gałąź ekosystemu Microsoftu. W praktyce, tylko Visual Studio dostarcza narzędzi, bibliotek i wsparcia do efektywnego tworzenia aplikacji WPF zgodnie z najlepszymi praktykami branżowymi. Przekonanie, że inne IDE pozwolą na równie komfortową pracę z WPF, to typowy błąd wynikający z braku rozeznania w specyfice tych narzędzi i ich przeznaczeniu. Warto więc dobrze rozumieć, do czego stworzone jest konkretne IDE i nie kierować się wyłącznie popularnością lub uniwersalnością nazwy. Wybór właściwego środowiska to podstawa nie tylko efektywnej nauki, ale i pracy zawodowej z daną technologią.

Pytanie 7

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

let a = { value: 10 }; let b = a; b.value = 20; console.log(a.value);
A. ReferenceError
B. 20
C. undefined
D. 10
Analizując błędne odpowiedzi, warto zwrócić uwagę na podstawowe zasady działania JavaScript w kontekście obiektów. Jeśli odpowiedzią byłoby 10, to sugerowałoby, że obiekt `a` nie został zmodyfikowany przez przypisanie do `b`, co jest nieprawdziwe. Obiekty w JavaScript są przekazywane przez referencję, co oznacza, że zmiana dokonana na jednym obiekcie wpływa na wszystkie referencje do niego. Odpowiedź `undefined` wskazywałaby na to, że obiekt `a` nie ma właściwości `value`, co również jest błędne, ponieważ obiekt `a` został zdefiniowany z tą właściwością i początkowo ma wartość 10. Z kolei `ReferenceError` występuje, gdy odwołujemy się do zmiennej, która nie istnieje w danym kontekście, co nie ma miejsca w naszym kodzie, ponieważ zarówno `a`, jak i `b` są zdefiniowane poprawnie. Błędy te często wynikają z niepełnego zrozumienia, jak JavaScript zarządza pamięcią i referencjami. Zrozumienie tych zasad jest kluczowe, aby unikać pułapek związanych z mutowalnością obiektów i przekazywaniem referencji, co może prowadzić do trudnych do diagnozowania błędów w większych projektach.

Pytanie 8

Która z poniższych nie jest poprawną metodą HTTP?

A. POST
B. SEARCH
C. GET
D. DELETE
Wybór metod GET, POST oraz DELETE jako odpowiedzi nie jest poprawny, ponieważ wszystkie one są uznawane za standardowe metody HTTP, zdefiniowane w specyfikacjach IETF. GET jest najczęściej używaną metodą, która umożliwia pobranie zasobów z serwera, co czyni ją podstawowym narzędziem w budowie interfejsów API i aplikacji webowych. Metoda POST służy do przesyłania danych na serwer, co jest kluczowe w przypadku formularzy internetowych czy operacji tworzenia nowych zasobów. DELETE z kolei opiera się na koncepcji RESTful, gdzie pozwala na usuwanie zasobów na serwerze. Zrozumienie tych metod oraz umiejętność ich właściwego wykorzystywania jest kluczowe dla każdego programisty zajmującego się tworzeniem aplikacji webowych. Pojawienie się niektórych błędnych odpowiedzi może wynikać z mylenia pojęć związanych z metodami HTTP oraz ich zastosowaniem w praktyce. Wiele osób mylnie sądzi, że każda metoda, którą zna, musi być standardem, co prowadzi do nieporozumień i błędnych wniosków. Dobrą praktyką jest na bieżąco rozwijać swoją wiedzę na temat protokołu HTTP oraz jego metod, co ułatwi pracę i zapewni lepsze zrozumienie architektury aplikacji webowych.

Pytanie 9

Co oznacza skrót CSRF w kontekście bezpieczeństwa aplikacji webowych?

A. Cascading Style Rendering Form
B. Client-Side Rendering Framework
C. Cross-Site Request Forgery
D. Cross-Site Response Filter
Skrót CSRF najczęściej mylony jest z innymi terminami w obszarze rozwoju aplikacji webowych, co może prowadzić do nieporozumień. Przykładowo, Client-Side Rendering Framework jest koncepcją odnoszącą się do sposobu renderowania stron internetowych, gdzie wiele logiki aplikacji wykonuje się po stronie klienta. Nie ma to jednak nic wspólnego z problematyką powiązaną z bezpieczeństwem. Cross-Site Response Filter sugeruje, że istnieje mechanizm filtrujący odpowiedzi między różnymi witrynami, co również nie ma podstaw w rzeczywistości. Tego typu pomysły świadczą o braku zrozumienia, jak działają ataki w środowisku webowym oraz jakie mechanizmy są potrzebne do ich obrony. Cascading Style Rendering Form nie ma nic wspólnego z bezpieczeństwem aplikacji, a raczej dotyczy stylizacji i prezentacji strony, co nie jest odpowiednim kontekstem. Często ludzie mylą te pojęcia, nie zdając sobie sprawy z ryzyk, jakie niesie niewłaściwe zabezpieczenie aplikacji. Zrozumienie, czym jest CSRF, jest kluczowe, aby unikać błędów w projektowaniu i implementacji rozwiązań webowych, które mogą doprowadzić do poważnych luk w bezpieczeństwie.

Pytanie 10

Jakie składniki są kluczowe w dynamicznym formularzu logowania?

A. Tabela w bazie danych
B. Pola tekstowe do wprowadzania danych użytkownika
C. Plik graficzny
D. Nagłówek HTTP
Pola tekstowe do wprowadzania danych użytkownika są kluczowym elementem dynamicznego formularza logowania. Umożliwiają one użytkownikowi wprowadzenie informacji, takich jak nazwa użytkownika i hasło, co jest niezbędne do uwierzytelnienia w systemie. Formularze HTML wykorzystują tagi <input> do tworzenia pól tekstowych, a ich interakcja z użytkownikiem może być wspierana przez JavaScript lub inne technologie frontendowe, które walidują dane i zapewniają bezpieczeństwo procesu logowania. Pola tekstowe mogą być wzbogacone o atrybuty, takie jak 'required', 'pattern' czy 'type', które dodatkowo zabezpieczają formularz i ułatwiają użytkownikowi poprawne wypełnienie danych.

Pytanie 11

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

A. Klasa, która może być dziedziczona przez inne klasy
B. Klasa, w której wszystkie komponenty są publiczne
C. Klasa, która nie ma możliwości zawierania metod statycznych
D. Klasa, która ma dostęp do prywatnych i chronionych elementów innej klasy
Klasa, która może być dziedziczona przez inne klasy, to zwykła klasa bazowa, nie klasa zaprzyjaźniona. Klasa z publicznymi składowymi nie jest automatycznie klasą zaprzyjaźnioną, a jedynie posiada publiczne pola dostępne z zewnątrz. Stwierdzenie, że klasa nie może zawierać metod statycznych, jest błędne – klasa zaprzyjaźniona może zawierać dowolne typy metod, w tym statyczne, jeśli jej projektowanie tego wymaga.

Pytanie 12

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

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

Pytanie 13

Resuscytacja krążeniowo-oddechowa polega na realizowaniu

A. 10 ucisków klatki piersiowej oraz 5 oddechów ratunkowych
B. 15 ucisków klatki piersiowej oraz 3 oddechy ratunkowe
C. 30 ucisków klatki piersiowej oraz 2 oddechy ratunkowe
D. 20 ucisków klatki piersiowej oraz 1 oddech ratunkowy
Resuscytacja krążeniowo-oddechowa (RKO) w obecnych wytycznych Europejskiej Rady Resuscytacji polega właśnie na wykonywaniu 30 ucisków klatki piersiowej na przemian z 2 oddechami ratunkowymi. Taki schemat jest rekomendowany zarówno dla dorosłych, jak i dzieci (poza niemowlętami i sytuacjami szczególnymi), bo zapewnia optymalną perfuzję mózgu i serca, a jednocześnie daje szansę na dostarczenie tlenu do organizmu. Gdyby skrócić liczbę ucisków albo oddechów, efektywność spada, a szansa przeżycia jest mniejsza. Ja zawsze powtarzam, że praktyka czyni mistrza – jak ćwiczyliśmy na fantomach, to właśnie ten rytm: 30 ucisków, potem 2 szybkie oddechy, bez zbędnych przerw. Praktycznie, w stresie łatwo się pogubić, ale jak sobie utrwalicie ten schemat, działa automatycznie. Warto wiedzieć, że uciski muszą być na głębokość około 5–6 cm u dorosłych, z częstotliwością co najmniej 100–120 na minutę – to jest kluczowe dla skuteczności. Z mojego doświadczenia wynika, że najczęściej popełnianym błędem jest zbyt płytkie uciskanie i zbyt długie przerwy na oddechy, warto to poćwiczyć. Kiedy nie chce się robić oddechów (np. obawa przed zakażeniem), można prowadzić tylko uciski, ale pełne RKO daje największe szanse. Takie podejście jest sprawdzone praktycznie na całym świecie i jak dla mnie, nie ma sensu kombinować z innymi proporcjami.

Pytanie 14

Jaką funkcję pełnią mechanizmy ciasteczek w aplikacjach internetowych?

A. Do przechowywania informacji w bazie danych
B. Do zapisywania danych użytkownika w przeglądarce
C. Do generowania dynamicznych interfejsów dla użytkowników
D. Do zapisywania danych użytkownika na serwerze
Mechanizm ciasteczek (cookies) w aplikacjach webowych służy do przechowywania danych użytkownika bezpośrednio w przeglądarce. Ciasteczka mogą przechowywać różnego rodzaju informacje, takie jak preferencje językowe, identyfikatory sesji czy dane logowania, co pozwala na personalizację doświadczenia użytkownika oraz śledzenie jego aktywności na stronie. Dzięki ciasteczkom aplikacje webowe mogą zapamiętać użytkownika i dostosować treści do jego potrzeb przy kolejnych wizytach. Cookies są nieodłącznym elementem zarządzania stanem w aplikacjach stateless, takich jak te oparte na protokole HTTP. Mogą być one również wykorzystywane w systemach reklamowych i analitycznych do monitorowania zachowań użytkowników. Prawidłowe zarządzanie ciasteczkami i stosowanie odpowiednich polityk prywatności są kluczowe dla zgodności z przepisami RODO oraz regulacjami dotyczącymi ochrony danych osobowych.

Pytanie 15

Jakie cechy powinien posiadać skuteczny negocjator?

A. intuicja, cierpliwość, asertywność
B. asertywność, pesymizm, buta
C. dobra reputacja, przekora, porywczość
D. lojalność, nieśmiałość, uczciwość
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 16

Aplikacje funkcjonujące w systemach Android do komunikacji z użytkownikiem wykorzystują klasę

A. Activity
B. Windows
C. Fragments
D. Screens
W systemie Android klasa Activity to absolutna podstawa komunikacji aplikacji z użytkownikiem. To właśnie ona reprezentuje jeden ekran interfejsu użytkownika, coś w stylu okna dialogowego w klasycznych aplikacjach desktopowych. Cały cykl życia aplikacji, obsługa zdarzeń, wyświetlanie elementów graficznych czy reagowanie na akcje użytkownika – wszystko to ogarnia Activity. Bez niej praktycznie żadna aplikacja nie ruszy, bo to właśnie Activity zarządza np. wywołaniem widoku, obsługą kliknięć czy przekazywaniem danych pomiędzy różnymi ekranami. Moim zdaniem, jeśli ktoś chce programować na Androida, najpierw powinien dobrze przyswoić, jak działa Activity i jej cykl życia (onCreate, onStart itd.), bo to pozwala tworzyć aplikacje zgodne z założeniami platformy. W praktyce deweloperzy bardzo często korzystają z dziedziczenia po klasie Activity, aby rozszerzyć funkcjonalność swoich aplikacji, a także używają jej do uruchamiania nowych ekranów oraz zarządzania nawigacją. Warto jeszcze pamiętać, że dobra znajomość Activity pomaga unikać typowych problemów z zarządzaniem pamięcią czy nieprawidłowym obsługiwaniem powrotów do aplikacji po przerwie. Z mojego doświadczenia, zrozumienie działania Activity to taka baza, bez której trudno iść dalej w temacie Androida.

Pytanie 17

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

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

Pytanie 18

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

A. !=
B. ==
C. ===
D. =
Nieprawidłowe odpowiedzi związane z operatorem == bazują na koncepcji luźnej równości, która w JavaScript działa na zasadzie automatycznego rzutowania typów. Gdy używasz ==, JavaScript konwertuje operandy na ten sam typ, zanim dokona porównania. To może prowadzić do zaskakujących rezultatów. Na przykład, porównując 0 == '0', wynik będzie true, ponieważ łańcuch '0' jest konwertowany na liczbę. Stosowanie tego operatora jest często przyczyną nieprzewidywalnych zachowań, które mogą być trudne do debugowania. Operator = z kolei nie jest operatorem porównania, lecz operatorem przypisania. Używa się go do przypisania wartości do zmiennej, co jest zupełnie inną operacją niż porównanie. Z kolei operator != działa na zasadzie luźnej nierówności i również podlega automatycznemu rzutowaniu typów, co czyni go mniej przewidywalnym. W praktyce, unikanie operatorów == oraz != na rzecz === oraz !== jest zdecydowanie zalecane, aby zredukować ryzyko błędów związanych z typami danych i niejednoznaczną logiką. Wielu doświadczonych programistów zaleca stosowanie operatora === za każdym razem, aby zapewnić najwyższy poziom precyzji i bezpieczeństwa w kodzie. Dobrą praktyką jest również przemyślane podejście do typów danych i ich konwersji, co pozwala na bardziej klarowne i zrozumiałe programowanie.

Pytanie 19

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

console.log(0.1 + 0.2 === 0.3);
console.log(0.1 + 0.2);
A. true, 0.30000000000000004
B. true, 0.3
C. false, 0.30000000000000004
D. false, 0.3
Niepoprawne odpowiedzi wynikają z nieporozumienia dotyczącego reprezentacji liczb zmiennoprzecinkowych w JavaScript. Wiele osób ma tendencję do sądzenia, że operacje matematyczne z użyciem liczb dziesiętnych będą prowadziły do oczekiwanych rezultatów. Przykład `0.1 + 0.2`, który wydaje się prosty, w rzeczywistości ujawnia istotne różnice w precyzji. W przeciwieństwie do liczb całkowitych, które są reprezentowane jednoznacznie, liczby zmiennoprzecinkowe mogą wprowadzać błędy zaokrągleń. Gdyby nasze porównanie zwracało `true`, wskazywałoby to na to, że na poziomie binarnym liczby te są identyczne, co jest w przypadku JavaScript nieprawdziwe. Z kolei podanie `0.3` jako wyniku sumy w niektórych odpowiedziach nie uwzględnia tej samej zasady, co sugeruje, że porównanie tych wartości jest właściwe, mimo że nie jest. Warto zrozumieć, że takie błędne wnioski mogą prowadzić do poważnych problemów w bardziej złożonych obliczeniach, zwłaszcza w aplikacjach finansowych, gdzie precyzja jest niezbędna. Dobrym zwyczajem jest korzystanie z odpowiednich metod, które pozwalają na bezpieczne porównywanie wartości zmiennoprzecinkowych, minimalizując ryzyko błędów. Stosując podejście oparte na tolerancji błędu, można uniknąć pułapek związanych z reprezentacją liczb i poprawić dokładność obliczeń.

Pytanie 20

Jaką cechę powinien posiadać dobry negocjator?

A. spokój
B. brak pewności
C. myślenie tylko o sobie
D. przechwalanie się
Cechą dobrego negocjatora jest opanowanie, które odgrywa kluczową rolę w procesie negocjacji. Osoba potrafiąca zachować spokój w trudnych sytuacjach może lepiej ocenić sytuację, zrozumieć potrzeby drugiej strony oraz zidentyfikować potencjalne punkty konfliktu. Opanowanie pozwala na skuteczne zarządzanie emocjami, co jest niezbędne w celu osiągnięcia korzystnych rezultatów. Przykładem może być sytuacja, w której negocjator musi zmierzyć się z agresywnym przeciwnikiem; zachowanie zimnej krwi pozwala na analizę sytuacji bez emocjonalnych impulsów. Ponadto, opanowanie wpływa na postrzeganie osoby negocjującej przez innych, budując zaufanie i respekt. W kontekście standardów negocjacyjnych, takich jak BATNA (Best Alternative to a Negotiated Agreement), opanowanie umożliwia lepsze podejmowanie decyzji w trudnych sytuacjach. Dlatego umiejętność zachowania spokoju jest fundamentem skutecznych negocjacji.

Pytanie 21

Co będzie wynikiem działania poniższego kodu JavaScript?

const obj = { name: 'John', greet: function() { setTimeout(function() { console.log(`Hello, ${this.name}`); }, 1000); } }; obj.greet();
A. Hello, John
B. Hello, undefined
C. TypeError
D. Hello, null
Odpowiedzi `Hello, John`, `TypeError` oraz `Hello, null` są wynikiem niepełnego zrozumienia zasad działania kontekstu `this` w JavaScript oraz mechanizmów związanych z wywołaniami funkcji w różnych kontekstach. W przypadku pierwszej z tych odpowiedzi, można by sądzić, że `this` w funkcji anonimowej odwołuje się do obiektu `obj`, co jest błędne, ponieważ w momencie wywołania funkcji przez `setTimeout` kontekst `this` traci odniesienie do obiektu, a zamiast tego wskazuje na obiekt globalny. W efekcie `this.name` nie zwraca wartości `'John'`, lecz `undefined`. Druga odpowiedź, związana z `TypeError`, nie zrozumiała, że żadne błędy nie są generowane w tym kodzie, a funkcja anonimowa wykonuje się bezproblemowo, jednak z błędnym kontekstem. Ostatnia propozycja, `Hello, null`, również jest nietrafiona, ponieważ nie istnieje sytuacja, w której `this` w tym kontekście mogłoby się odwoływać do `null`. Należy również pamiętać, że JavaScript różni się od wielu innych języków programowania, gdzie `this` jest bardziej ściśle powiązane z obiektem, w którym metoda została wywołana. Zrozumienie kontekstu `this` jest kluczowe w pracy z JavaScript, szczególnie w pracy z funkcjami asynchronicznymi oraz w zastosowaniach programowania obiektowego.

Pytanie 22

Które z poniższych NIE jest zasadą programowania SOLID?

A. Open/Closed Principle (Zasada otwarte/zamknięte)
B. Code Reuse Principle (Zasada ponownego użycia kodu)
C. Single Responsibility Principle (Zasada pojedynczej odpowiedzialności)
D. Dependency Inversion Principle (Zasada odwrócenia zależności)
Programowanie zgodne z zasadami SOLID jest kluczowym elementem w budowaniu oprogramowania o wysokiej jakości. Odpowiedzi takie jak Zasada ponownego użycia kodu mogą wydawać się atrakcyjne, jednak nie są częścią formalnego zbioru zasad SOLID. Zasady te skupiają się na aspektach architektury i projektowania kodu, które wspierają jego elastyczność i zrozumiałość. W rzeczywistości, zasada ponownego użycia kodu, choć istotna w praktyce, nie odnosi się bezpośrednio do celów osiąganych przez zasady SOLID. Wprowadzenie do projektu zasady, że każda klasa czy moduł powinny mieć wyłącznie jedną odpowiedzialność, jak przewiduje Zasada pojedynczej odpowiedzialności, może prowadzić do znacznie lepszego zrozumienia struktury kodu i ułatwić jego modyfikacje w przyszłości. Wiele osób błędnie interpretuje potrzebę ponownego użycia kodu jako priorytet, co może prowadzić do tworzenia monolitycznych klas, które są trudne do zarządzania. Ponadto, Zasada otwarte/zamknięte sugeruje, że komponenty powinny być otwarte na rozszerzenia, ale zamknięte na modyfikacje, co stanowi fundament dla stabilnego i skalowalnego oprogramowania. Ignorując te zasady, programiści mogą tworzyć kod, który jest trudny do zrozumienia i utrzymania, co w dłuższej perspektywie zwiększa koszty i ryzyko błędów.

Pytanie 23

Co to jest git rebase?

A. Narzędzie do rozwiązywania konfliktów między plikami
B. Polecenie do tworzenia nowego repozytorium
C. Metoda tworzenia kopii zapasowej repozytorium
D. Technika integracji zmian z jednej gałęzi do drugiej przez przeniesienie lub połączenie sekwencji commitów
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 24

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. Metodę obsługi pamięci podręcznej
D. Typy danych, które są trzymane w pamięci
Rodzaje danych, które są trzymane w pamięci, nie są bezpośrednio powiązane z zestawem instrukcji procesora. ISA skupia się bardziej na tym, co procesor może zrobić, a nie na tym, jak dane są zorganizowane w pamięci. Przechowywanie danych to bardziej kwestia zarządzania pamięcią, a nie samej architektury instrukcji. A jeśli chodzi o pamięć podręczną, to już całkiem inna sprawa, bo to dotyczy tego, jak przechowujemy i uzyskujemy dostęp do danych. W tym przypadku mówi się o algorytmach i strategiach, które działają w architekturze procesora, ale nie są częścią zestawu instrukcji. I jeszcze schemat połączeń między procesorem a innymi częściami komputera też nie wchodzi w skład ISA. To już dotyczy całej architektury systemu i tego, jak różne elementy, jak pamięć czy urządzenia wejścia/wyjścia, współpracują ze sobą. Wszystko to jest istotne dla działania systemu komputerowego, ale nie definiuje zestawu instrukcji, który jest kluczowy, żeby procesor mógł przetwarzać dane i robić obliczenia.

Pytanie 25

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. Mechanizm ukrywania szczegółów implementacji przed zewnętrznymi klasami
D. Zdolność klasy do posiadania wielu konstruktorów
Polimorfizm jest fundamentalnym pojęciem w programowaniu obiektowym, które pozwala obiektom różnych klas na reagowanie na tę samą metodę w sposób odpowiedni dla ich konkretnej klasy. Przykładowo, jeśli mamy klasę `Zwierze` z metodą `dźwięk()`, a następnie klasy `Pies` i `Kot`, każda z tych klas może implementować metodę `dźwięk()` w inny sposób: pies może wydawać dźwięk 'Hau', podczas gdy kot 'Miau'. Dzięki temu, gdy wywołujemy `dźwięk()` na obiekcie typu `Zwierze`, a dokładnie na obiekcie, który może być różnego typu, uzyskujemy różne wyniki w zależności od klasy. Polimorfizm zwiększa elastyczność i skalowalność kodu, co jest zgodne z zasadami SOLID, szczególnie z zasadą otwarte-zamknięte. W praktyce polimorfizm umożliwia programistom tworzenie bardziej złożonych systemów, w których obiekty mogą być używane zamiennie, co ułatwia ich rozwój i konserwację.

Pytanie 26

Do form komunikacji werbalnej zalicza się

A. gestykulacja
B. wyraz twarzy
C. mówienie
D. pozycja ciała
Mówienie to podstawowa forma komunikacji werbalnej – bez tego ciężko byłoby przekazać bardziej złożone treści, polecenia czy po prostu podzielić się informacjami w jasny i jednoznaczny sposób. Właśnie dlatego w większości branż technicznych, niezależnie czy rozmawiamy o pracy na budowie, czy w biurze projektowym, umiejętność jasnego i zrozumiałego mówienia jest często kluczowa. W praktyce komunikacja werbalna opiera się na słowach, które przekazujemy ustnie. Moim zdaniem najważniejsze jest to, że pozwala uniknąć nieporozumień i usprawnia współpracę w zespole – szczególnie gdy pracujemy przy dużych projektach, gdzie każdy detal ma znaczenie. W codziennych sytuacjach, takich jak prowadzenie spotkań, omawianie problemów technicznych czy instruowanie nowych pracowników, mówienie okazuje się nieocenione. Dodatkowo, standardy komunikacji interpersonalnej podkreślają, że skuteczny przekaz werbalny wymaga nie tylko odpowiedniego doboru słów, ale też umiejętności dostosowania tonu głosu i tempa mówienia do sytuacji. Warto też pamiętać, że mowa ludzka jest najdokładniejszym narzędziem do przekazywania informacji, bo daje możliwość dopytania, wyjaśnienia i natychmiastowej korekty, czego raczej nie da się osiągnąć tylko poprzez gesty czy mimikę. Z mojego doświadczenia wynika, że inwestowanie w rozwój umiejętności werbalnych zwraca się bardzo szybko w pracy technika czy specjalisty.

Pytanie 27

Która z wymienionych metod najlepiej chroni komputer przed złośliwym oprogramowaniem?

A. Cykliczne wykonywanie kopii zapasowych
B. Stosowanie mocnych haseł
C. Unikanie używania publicznych sieci Wi-Fi
D. Właściwie zaktualizowany program antywirusowy
Program antywirusowy to naprawdę istotna rzecz, jeśli chodzi o ochronę komputerów przed złośliwym oprogramowaniem. On w zasadzie non stop monitoruje nasz system i ma za zadanie wyłapywać różne wirusy, trojany, a nawet ransomware, co jest bardzo ważne. Pamiętaj, żeby regularnie aktualizować bazy wirusów, bo dzięki temu będziesz miał zabezpieczenie przed najnowszymi zagrożeniami. Warto też zauważyć, że wiele programów antywirusowych ma dodatkowe opcje, jak na przykład monitorowanie stron www, czy skanowanie e-maili i plików, które pobierasz. To wszystko razem daje lepszą ochronę.

Pytanie 28

Co to jest CORS (Cross-Origin Resource Sharing)?

A. Protokół komunikacji między różnymi bazami danych
B. System zarządzania plikami statycznymi w aplikacjach SPA
C. Metoda kompresji danych w aplikacjach webowych
D. Mechanizm bezpieczeństwa określający, które domeny mogą uzyskiwać dostęp do zasobów na serwerze
CORS, czyli Cross-Origin Resource Sharing, to mechanizm bezpieczeństwa, który pozwala kontrolować, które domeny mają dostęp do zasobów na serwerze. Jest to niezwykle ważne w kontekście aplikacji webowych, które często korzystają z zasobów z różnych źródeł. Dzięki CORS serwery mogą definiować, które domeny mogą wysyłać żądania HTTP i uzyskiwać odpowiedzi z ich zasobów. Na przykład, jeśli Twoja aplikacja webowa działa na domenie 'example.com', ale potrzebuje danych z API na 'api.example.org', CORS pozwala na skonfigurowanie serwera API, aby zezwalał na te żądania. CORS jest kluczowy dla bezpieczeństwa aplikacji, ponieważ zapobiega atakom typu cross-site scripting (XSS) i innym nieautoryzowanym dostępom. Praktyczne zastosowanie CORS wprowadza nagłówki HTTP, takie jak 'Access-Control-Allow-Origin', które informują przeglądarki, jakie domeny mają prawo do interakcji z danym zasobem. Korzystanie z CORS jest uznawane za dobrą praktykę w budowaniu bezpiecznych aplikacji webowych, co podkreśla znaczenie jego implementacji.

Pytanie 29

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

$x = 5; $y = '5'; var_dump($x == $y); var_dump($x === $y);
A. bool(false) bool(false)
B. bool(false) bool(true)
C. bool(true) bool(true)
D. bool(true) bool(false)
Wyniki bool(false) bool(false), bool(true) bool(true) oraz bool(false) bool(true) mogą wydawać się zrozumiałe na pierwszy rzut oka, jednak każdy z tych przypadków zawiera istotne błędy w zrozumieniu mechanizmu porównania w PHP. Porównanie z użyciem operatora ==, który jest porównaniem luźnym, prowadzi do konwersji typów, co nie jest zawsze intuicyjne. Użytkownicy mogą mylnie przyjąć, że porównania opierające się na tym operatorze zawsze zwracają false, gdy zmienne mają różne typy, co jest błędne. W rzeczywistości, w przypadku wyrażenia $x == $y, gdzie $x to integer a $y to string, PHP przekształca zmienną stringową na typ integer przed porównaniem, co skutkuje wynikiem true. W konsekwencji, błędne odpowiedzi mogłyby wynikać z niepełnego zrozumienia działania operatora ===, który wymaga, by zarówno wartość, jak i typ były identyczne. Użytkownicy mogą mylić te dwa operatory i zakładać, że wynik będzie taki sam, niezależnie od typów zmiennych. Warto również zwrócić uwagę na to, jak ważne jest stosowanie operatora identyczności ===, który nie tylko porównuje wartości, ale także typy, co jest zgodne z dobrymi praktykami programowania w PHP. Dzięki temu unika się niejednoznaczności, co jest istotne w skomplikowanych aplikacjach. Wnioskując, kluczem do poprawnych wyników jest znajomość różnicy między porównaniami luźnymi a ścisłymi i świadome używanie odpowiednich operatorów, by unikać nieporozumień.

Pytanie 30

Która z poniższych nie jest prawidłową metodą zarządzania stanem w React?

A. Redux
B. React.stateManager
C. useState hook
D. Context API
Odpowiedzi, które wskazałeś, takie jak Redux, Context API oraz useState hook, są w rzeczywistości powszechnie uznawanymi metodami zarządzania stanem w React. Redux, jako zewnętrzna biblioteka, usprawnia zarządzanie stanem poprzez wprowadzenie centralnego store'a, który przechowuje wszystkie dane w aplikacji. Dzięki temu, każdy komponent może subskrybować zmiany w stanie, co pozwala na prostą synchronizację danych oraz ich śledzenie. Context API jest wbudowane w React i pozwala na udostępnianie danych między komponentami bez potrzeby przekazywania propsów, co znacząco upraszcza hierarchię komponentów i poprawia ich czytelność. Hook useState natomiast, jest prostym i intuicyjnym rozwiązaniem do zarządzania lokalnym stanem w komponentach funkcyjnych, co jest szczególnie przydatne w mniejszych projektach. Zrozumienie, dlaczego te metody są uznawane za poprawne, jest kluczowe, ponieważ pozwala na efektywne zarządzanie stanem w aplikacjach React. Często błędne wnioski wynikają z nieznajomości narzędzi dostępnych w ekosystemie React lub z mylnego przekonania, że dany sposób zarządzania stanem musi być uniwersalny. W rzeczywistości, najlepsze podejście zależy od skali oraz specyfiki projektu.

Pytanie 31

W zaprezentowanym kodzie stworzono abstrakcyjną klasę figura oraz klasę prostokąta, która dziedziczy po niej, zawierającą zdefiniowane pola i konstruktory. Wskaż minimalną wersję implementacji sekcji /* metody klasy */ dla klasy Prostokat:

abstract class Figura
{
    abstract double Pole();
    abstract double Obwod();
}

public class Prostokat extends Figura
{
    private double a;
    private double b;

    ... /* Konstruktory */
    ... /* Metody klasy */
}
AB
public double Pole() {
    return a * b;
}

public double Obwod() {
    return 2*a + 2*b;
}
public double Pole() {
    return a * b;
}
CD
public double LiczPole()
{
    return a * b;
}

public double LiczObwod()
{
    return 2*a + 2*b;
}
abstract double Pole()
{
    return a * b;
}

abstract double LiczObwod()
A. B
B. C
C. D
D. A
Analizując pozostałe propozycje implementacji, łatwo zauważyć pewne typowe błędy, które pojawiają się podczas pracy z dziedziczeniem i klasami abstrakcyjnymi. Przede wszystkim odpowiedzi, które pomijają implementację jednej z metod abstrakcyjnych zadeklarowanych w klasie Figura (jak w przypadku wariantu B), nie spełniają podstawowego wymogu języka Java – klasa pochodna musi zaimplementować wszystkie metody zadeklarowane jako abstract w klasie bazowej. W odpowiedzi B mamy tylko metodę Pole(), więc przy próbie kompilacji kodu pojawiłby się błąd i konieczność oznaczenia Prostokata jako klasy abstrakcyjnej, co zupełnie mija się z celem. Z kolei odpowiedź C wprowadza metody o innych nazwach (LiczPole, LiczObwod) niż te zadeklarowane w klasie Figura. To bardzo częsty błąd początkujących – niepoprawnie myślą, że wystarczy zaimplementować metody o tej samej funkcjonalności, bez zachowania ich nazw. Tymczasem kontrakt narzucony przez klasę bazową musi być spełniony dokładnie, razem z nazwami, typami argumentów i zwracanym typem. Ignorowanie tych szczegółów prowadzi do niespójności i niekompatybilności klas pochodnych. No i ostatnia propozycja – D – zawiera próbę napisania metody z modyfikatorem abstract w klasie, która już nie jest abstrakcyjna, co jest wprost błędem kompilacji. Dodatkowo, używanie abstract razem z ciałem metody jest niezgodne z językiem – metody abstrakcyjne nie mogą mieć implementacji w klasie abstrakcyjnej, a tym bardziej w pochodnej. To wszystko pokazuje, jak ważne w programowaniu obiektowym jest zrozumienie zasad dziedziczenia, poprawnego nadpisywania metod oraz konsekwentne trzymanie się sygnatur narzucanych przez klasy bazowe. Z praktyki wiem, że takie błędy potrafią zablokować rozwój projektu albo wymusić czasochłonne refaktoryzacje. Warto od początku przyzwyczaić się do czytania kodu bazowego i dokładnego kopiowania sygnatur metod – to oszczędza dużo nerwów i nieporozumień w pracy zespołowej.

Pytanie 32

Które z poniżej wymienionych afirmacji najtrafniej charakteryzuje proces interpretacji kodu?

A. Tłumaczenie kodu źródłowego na język maszynowy w czasie rzeczywistym
B. Generowanie bibliotek dynamicznych dla programu
C. Tworzenie pliku wykonywalnego
D. Analiza struktury kodu przed tłumaczeniem
Interpretacja kodu to proces tłumaczenia kodu źródłowego na język maszynowy w czasie rzeczywistym, instrukcja po instrukcji. Jest to charakterystyczne dla języków takich jak Python, JavaScript i Ruby, które używają interpreterów. Dzięki temu program jest wykonywany od razu, bez konieczności wcześniejszego generowania pliku wykonywalnego. Zaletą interpretacji jest szybka analiza i możliwość natychmiastowego testowania kodu, co przyspiesza proces debugowania i prototypowania aplikacji.

Pytanie 33

Co to jest choroba związana z wykonywaniem zawodu?

A. Każda choroba, która występuje w czasie pracy
B. Choroba wynikająca z warunków pracy lub związanych z nimi czynników
C. Stan zdrowia, który uniemożliwia pracę przez okres krótszy niż tydzień
D. Choroba występująca tylko w sektorze przemysłowym
Choroba zawodowa to stan zdrowotny spowodowany warunkami pracy lub czynnikami związanymi z wykonywaną profesją. Najczęściej wynika z długotrwałego narażenia na szkodliwe substancje, hałas, promieniowanie, pyły lub wykonywanie powtarzalnych czynności. Przykładem chorób zawodowych są pylica płuc, głuchota zawodowa czy zespół cieśni nadgarstka. Kluczowym elementem w zapobieganiu chorobom zawodowym jest odpowiednia profilaktyka, szkolenia BHP oraz dostosowanie środowiska pracy do zasad ergonomii. Pracodawcy są zobowiązani do monitorowania warunków pracy i wdrażania rozwiązań minimalizujących ryzyko wystąpienia chorób zawodowych.

Pytanie 34

Jakie rozwiązanie jest najbardziej odpowiednie przy projektowaniu aplikacji, która ma funkcjonować na różnych systemach operacyjnych?

A. Opracowanie dedykowanego kodu dla każdej platformy
B. Koncentrowanie się wyłącznie na estetyce aplikacji
C. Wykorzystanie technik responsywnego projektowania interfejsu
D. Pełne dopasowanie aplikacji do systemu Windows
Wykorzystanie technik responsywnego projektowania interfejsu to obecnie jedno z najskuteczniejszych rozwiązań, jeśli chodzi o tworzenie aplikacji działających na różnych systemach operacyjnych. Moim zdaniem, to podejście daje największą elastyczność i wygodę zarówno dla użytkownika, jak i dla samego zespołu developerskiego. Responsywność nie sprowadza się tylko do zmiany rozmiaru okna, ale także do automatycznego dostosowania elementów interfejsu do różnych rozdzielczości, DPI czy nawet gestów obsługiwanych przez konkretne urządzenia. Dzięki temu aplikacja może wyglądać i działać spójnie niezależnie od tego, czy uruchamiana jest na Windowsie, MacOS, Linuksie czy nawet na mobilnych systemach operacyjnych. W praktyce często korzysta się z frameworków takich jak Flutter, React Native albo Electron, które już "z pudełka" oferują narzędzia do tworzenia responsywnych, wieloplatformowych aplikacji. Branżowe standardy, szczególnie te, które dotyczą UX/UI (na przykład wytyczne Material Design czy Human Interface Guidelines od Apple), mocno podkreślają wagę responsywności i uniwersalności rozwiązań. Co ciekawe, dobrze zaprojektowana responsywna aplikacja jest też łatwiejsza w utrzymaniu i rozwoju, bo zamiast kilku osobnych wersji kodu, mamy jedną, dobrze przemyślaną bazę. To oszczędza czas, zasoby i minimalizuje ryzyko powstawania błędów. Sam przećwiczyłem wiele takich przypadków i widać, że inżynieria oprogramowania idzie właśnie w stronę uniwersalnych, "adaptacyjnych" rozwiązań.

Pytanie 35

Co to jest REST API?

A. Framework do testowania API
B. Protokół sieciowy do transferu danych binarnych
C. Biblioteka JavaScript do komunikacji z bazami danych
D. Architektura API oparta o zasoby i standardowe operacje HTTP
REST API (Representational State Transfer Application Programming Interface) to architektura API, która koncentruje się na zasobach i wykorzystuje standardowe operacje HTTP, takie jak GET, POST, PUT i DELETE. Dzięki tej architekturze każdy zasób, na przykład użytkownik czy produkt, jest reprezentowany przez unikalny identyfikator URL, co ułatwia dostęp i manipulację danymi. REST API jest szeroko stosowane w aplikacjach webowych i mobilnych, ponieważ pozwala na łatwą integrację różnych systemów oraz umożliwia wykorzystanie technologii takich jak JSON i XML do wymiany danych. Przykładem praktycznego zastosowania REST API może być aplikacja do zarządzania zadaniami, w której użytkownicy mogą tworzyć, edytować i usuwać zadania za pomocą odpowiednich zapytań HTTP. Dobrą praktyką przy projektowaniu REST API jest stosowanie odpowiednich statusów HTTP, takich jak 200 (OK), 201 (Created) czy 404 (Not Found), co ułatwia komunikację między klientem a serwerem oraz zwiększa transparentność działania API. Dodatkowo, REST API jest zgodne z zasadą bezstanowości, co oznacza, że każdy nowy request zawiera wszystkie informacje potrzebne do jego przetworzenia.

Pytanie 36

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

A. Polimorfizm
B. Abstrakcja
C. Dziedziczenie
D. Hermetyzacja
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 37

Algorytm wyszukiwania sekwencyjnego z wykorzystaniem wartownika opiera się na założeniu, że

A. zbiór danych wejściowych musi być uporządkowany
B. szukany element powinien wystąpić wielokrotnie w zbiorze
C. na końcu analizowanego zbioru należy dodać wartownika
D. zbiór ma zawsze 100 elementów
Algorytm sekwencyjnego wyszukiwania elementu z wartownikiem jest techniką optymalizacji procesu wyszukiwania w strukturach danych, która znacząco zwiększa efektywność operacji w przypadkach, gdy zbiór danych jest duży. Wartownik to specjalny element, który jest dodawany na końcu przeszukiwanego zbioru, co pozwala na uproszczenie warunków zakończenia pętli przeszukiwania. Kiedy algorytm przeszukuje zbiór, porównuje każdy element z poszukiwanym, a gdy znajdzie element, może zakończyć działanie. Dodanie wartownika pozwala uniknąć potrzeby sprawdzania, czy aktualnie przeszukiwany element jest ostatnim z oryginalnego zbioru, co z kolei zmniejsza liczbę porównań i przyspiesza proces wyszukiwania. W praktyce algorytm ten jest szczególnie użyteczny w przypadku niewielkich zbiorów danych, gdzie efektywność jest kluczowa. Przykładem zastosowania może być edytor tekstu, w którym użytkownik wyszukuje konkretne słowa w dokumencie, a dodanie wartownika usprawnia ten proces. Zgodnie z zasadami wydajnego programowania, ta technika stanowi jeden z podstawowych mechanizmów stosowanych w algorytmice, co czyni ją fundamentalnym konceptem w nauce o komputerach.

Pytanie 38

Do stworzenia zbioru danych potrzebnego do uruchomienia algorytmu sortowania bąbelkowego tablicy, wymagane są przynajmniej następujące typy:

A. dwa tablicowe, dwa do zamiany miejscami elementów
B. dwa tablicowe, jeden liczbowy do nadzorowania pętli
C. jeden tablicowy, jeden liczbowy do nadzorowania pętli, dwa do zamiany miejscami elementów
D. jeden tablicowy, dwa liczbowe do nadzorowania pętli, jeden do zamiany miejscami elementów
Sortowanie bąbelkowe to jeden z tych algorytmów, które wydają się proste, ale wymagają solidnego zrozumienia działania pętli i pracy z tablicami. W praktyce, aby prawidłowo zaimplementować bubble sort, zawsze korzysta się z jednej tablicy (w której przechowywane są elementy do posortowania), dwóch liczbowych zmiennych sterujących (dla dwóch zagnieżdżonych pętli for lub while, bo każda z nich odpowiada za przechodzenie przez elementy), a także jednej dodatkowej zmiennej tymczasowej do zamiany miejscami dwóch elementów. To właśnie te cztery składniki są absolutnym minimum, żeby kod był czytelny i zgodny z zasadami dobrej praktyki. Z mojego doświadczenia, rezygnacja z jednej z nich prowadzi do niepotrzebnego kombinowania, a czasem nawet do dziwnych błędów. Warto wiedzieć, że takie podejście dobrze wpisuje się w wymagania większości języków programowania – czy to C, Java, czy Python – i sprawdza się zarówno przy nauce, jak i w praktycznych zadaniach rekrutacyjnych. Pozostawienie logiki zamiany elementów w osobnej zmiennej tymczasowej to nie tylko kwestia czytelności; to też sposób na unikanie utraty danych podczas zamiany. Co ciekawe, niektórzy próbują czasami zamieniać bez zmiennej tymczasowej, używając operacji XOR, ale w praktyce to przerost formy nad treścią i raczej niezalecane w standardzie branżowym. Dobrze jest wiedzieć, że to podejście, które tu wybrałeś, stanowi niejako wzorzec dla wszystkich początkujących programistów i jest akceptowane na egzaminach czy rozmowach technicznych.

Pytanie 39

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

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

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

Pytanie 40

Sposób deklaracji Klasa2 wskazuje, że

W C++ i C#:
class Klasa2 : Klasa1
W Java:
class Klasa2 extends Klasa1
W Python:
class Klasa2(Klasa1):
A. Klasa1 jest dzieckiem Klasy2
B. Klasa2 stanowi klasę bazową
C. Klasa1 dziedziczy od Klasa2
D. Klasa2 dziedziczy od Klasa1
Deklaracja Klasa2 jako klasy dziedziczącej po Klasa1 oznacza, że Klasa2 przejmuje wszystkie publiczne i chronione (protected) pola oraz metody klasy bazowej (Klasa1). Dziedziczenie to jeden z filarów programowania obiektowego, który umożliwia ponowne wykorzystanie kodu i rozszerzanie funkcjonalności istniejących klas. Dzięki temu Klasa2 może nie tylko korzystać z metod Klasa1, ale także nadpisywać je, co jest kluczowe dla implementacji polimorfizmu. Dziedziczenie pozwala na budowanie hierarchii klas, co prowadzi do lepszego zarządzania kodem i ułatwia jego skalowalność. Przykładem może być klasa Pojazd, z której dziedziczy klasa Samochod, rozszerzając jej funkcjonalność o dodatkowe cechy i metody specyficzne dla samochodów.