Wyniki egzaminu

Informacje o egzaminie:
  • Zawód: Technik programista
  • Kwalifikacja: INF.04 - Projektowanie, programowanie i testowanie aplikacji
  • Data rozpoczęcia: 17 grudnia 2025 07:08
  • Data zakończenia: 17 grudnia 2025 07:27

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. Optymalizacja kodu
C. Tłumaczenie kodu źródłowego na język maszynowy
D. Weryfikacja błędów składniowych
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

Która z wymienionych sytuacji stanowi naruszenie praw autorskich?

A. Tworzenie kopii zapasowej legalnie zakupionego programu
B. Nabycie licencji na oprogramowanie
C. Używanie programu typu open-source zgodnie z warunkami licencji
D. Udostępnianie filmu objętego prawami autorskimi bez zgody właściciela
Publikowanie filmu chronionego prawami autorskimi bez zgody właściciela jest naruszeniem praw autorskich. Prawa autorskie chronią twórców przed nieuprawnionym kopiowaniem, dystrybucją i rozpowszechnianiem ich dzieł. W przypadku filmów, muzyki czy oprogramowania, każde użycie bez odpowiednich licencji lub zgody właściciela jest niezgodne z prawem. Twórcy mają prawo do wynagrodzenia za swoją pracę, a naruszenia mogą skutkować wysokimi grzywnami, a nawet postępowaniem sądowym. Przestrzeganie praw autorskich wspiera rozwój kultury i technologii, chroniąc interesy twórców.

Pytanie 3

Jakie z wymienionych działań jest fundamentalne w modelu kaskadowym?

A. Zakończenie jednej fazy przed rozpoczęciem następnej
B. Równoległe prowadzenie wielu etapów projektu
C. Iteracyjne wprowadzanie modyfikacji na każdym poziomie
D. Przeprowadzanie testów systemu po zakończeniu każdej fazy
Równoległa realizacja kilku faz to cecha modelu przyrostowego lub iteracyjnego, który pozwala na pracę nad różnymi etapami jednocześnie. Iteracyjne wprowadzanie zmian to charakterystyczna cecha Agile, gdzie projekt rozwijany jest stopniowo. Testowanie po każdej fazie jest istotnym elementem w różnych metodykach, ale sam proces testowania nie definiuje modelu kaskadowego – tutaj testowanie odbywa się dopiero po zakończeniu implementacji całego systemu.

Pytanie 4

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

A. Windows
B. Screens
C. Activity
D. Fragments
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 5

Jakie są różnice między typem łańcuchowym a typem znakowym?

A. Typ znakowy przechowuje dane logiczne, a łańcuchowy tekst
B. Typ łańcuchowy przechowuje pojedyncze znaki, a znakowy długie ciągi znaków
C. Typ łańcuchowy obsługuje liczby całkowite, a znakowy liczby zmiennoprzecinkowe
D. Typ znakowy przechowuje pojedyncze znaki, a łańcuchowy ciągi znaków
Typ znakowy (char) przechowuje pojedyncze znaki, natomiast typ łańcuchowy (string) przechowuje ciągi znaków. Różnica ta ma kluczowe znaczenie w programowaniu, ponieważ typ 'char' jest używany do operacji na pojedynczych literach, cyfrze lub symbolu, podczas gdy 'string' umożliwia przechowywanie i manipulowanie całymi wyrazami lub zdaniami. W wielu językach 'string' to bardziej złożona struktura danych, która zawiera tablicę znaków (array of characters), co pozwala na efektywną pracę z tekstem i budowanie interaktywnych aplikacji.

Pytanie 6

Który z wymienionych przykładów ilustruje projektowanie interfejsu zgodnego z zasadami user experience (UX)?

A. Brak opcji cofnięcia już wykonanej akcji
B. Zastosowanie jedynie jednego koloru w całym interfejsie
C. Użycie czytelnych czcionek i intuicyjnego układu elementów
D. Przycisk umieszczony w przypadkowym miejscu aplikacji
Użycie czytelnych czcionek i intuicyjnego układu elementów to kluczowe zasady projektowania zgodne z user experience (UX). Przejrzystość i estetyka interfejsu zwiększają komfort użytkownika i ułatwiają korzystanie z aplikacji. Intuicyjny układ elementów pozwala na szybkie odnalezienie potrzebnych funkcji, co redukuje frustrację użytkownika i skraca czas potrzebny na realizację zadania. UX opiera się na badaniach dotyczących zachowań użytkowników i dostosowywaniu projektu do ich potrzeb.

Pytanie 7

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

A. wirtualną maszynę
B. interpreter
C. analizator składni
D. debugger
W praktyce programistycznej bardzo łatwo pomylić narzędzia służące do różnych celów, zwłaszcza gdy ktoś dopiero zaczyna swoją przygodę z kodowaniem. Analizator składni to narzędzie wykorzystywane głównie przez kompilatory i interpretery do sprawdzania poprawności gramatycznej kodu źródłowego – pozwala wyłapać błędy na etapie pisania programu, ale nie daje możliwości sprawdzenia, co dokładnie dzieje się „w środku” działającej aplikacji. Stosowanie analizatora składni nie pomoże więc zweryfikować dynamicznych wartości zmiennych w trakcie działania programu. Wirtualna maszyna natomiast to środowisko uruchomieniowe, które umożliwia wykonywanie kodu niezależnie od konkretnej platformy sprzętowej czy systemu operacyjnego (przykład to JVM dla Javy). Chociaż często daje ona pewne narzędzia diagnostyczne, to jej głównym zadaniem nie jest debugowanie kodu ani szczegółowy podgląd zmiennych w czasie rzeczywistym. Interpreter z kolei wykonuje kod linia po linii, ale nie oferuje sam z siebie rozbudowanych opcji diagnostycznych i śledzenia zmiennych, chyba że jest rozbudowany o dodatkowe narzędzia debugujące. Często spotykanym błędem jest mylenie funkcji interpretera czy środowiska uruchomieniowego z narzędziami do debugowania – to nie to samo. Moim zdaniem, żeby skutecznie tropić błędy, trzeba właśnie sięgnąć po debugger, bo to on daje te precyzyjne narzędzia kontroli i podglądu, bez których analiza działania programu „na żywo” byłaby bardzo niewygodna. Warto pamiętać, że dobre praktyki programistyczne zawsze zalecają korzystanie ze specjalistycznych narzędzi do debugowania, bo to po prostu najbardziej efektywna ścieżka szukania błędów.

Pytanie 8

Gdzie są przechowywane informacje w sytuacji korzystania z chmury obliczeniowej?

A. Na zdalnych serwerach dostawcy usług
B. Na nośnikach optycznych użytkownika
C. Na dysku twardym użytkownika
D. Na lokalnym serwerze użytkownika
Dane w chmurze obliczeniowej są przechowywane przede wszystkim na zdalnych serwerach dostawcy usług chmurowych. Tego rodzaju przechowywanie danych ma na celu zapewnienie wysokiej dostępności, skalowalności oraz bezpieczeństwa. Dostawcy usług chmurowych, tacy jak Amazon Web Services, Microsoft Azure czy Google Cloud Platform, inwestują w infrastrukturę, która obejmuje centra danych rozmieszczone na całym świecie. Te centra danych są wyposażone w zaawansowane systemy zabezpieczeń, takie jak firewall'e, szyfrowanie danych i systemy detekcji intruzów. Dzięki temu użytkownicy mogą mieć pewność, że ich dane są bezpieczne. Dodatkowo, zdalne serwery oferują elastyczność w zakresie przydzielania zasobów obliczeniowych, co pozwala na dynamiczne reagowanie na zmieniające się potrzeby biznesowe. Warto również wspomnieć o standardach bezpieczeństwa, takich jak ISO 27001 czy SOC 2, które regulują sposób przechowywania i zarządzania danymi w chmurze, zapewniając zgodność z najlepszymi praktykami branżowymi.

Pytanie 9

Na ilustracji pokazany jest fragment diagramu blokowego pewnego algorytmu. Ile razy warunek n<7 będzie badany?

Ilustracja do pytania
A. 8
B. 7
C. 5
D. 6
Wybór innej odpowiedzi niż 4 wskazuje na nieprawidłowe rozumienie mechanizmu działania pętli z warunkiem końcowym Problem może tkwić w błędnym założeniu dotyczącym liczby iteracji które ma miejsce gdy nie uwzględnia się początkowej wartości n Wynik 8 mógłby wynikać z mylnego założenia że pętla sprawdza warunek również po zakończeniu gdy n wynosi 7 co jest nieprawidłowe Ponadto wybór 5 może sugerować że zrozumienie zakresu wartości n jest niepełne ponieważ pomija się pierwszą iterację gdy n równa się 1 Odpowiedź 7 mogłaby wynikać z błędnego przeliczania liczby iteracji lub niepoprawnego przeanalizowania działania inkrementacji w algorytmie Ważne jest aby zrozumieć że warunek n mniejsze od 7 jest sprawdzany na początku każdej iteracji pętli i gdy n osiąga wartość 7 pętla nie wykonuje się ponownie Zrozumienie tego mechanizmu jest kluczowe do poprawnego projektowania algorytmów i unikania typowych błędów logicznych które mogą prowadzić do nieefektywności kodu oraz trudności w jego debugowaniu i utrzymaniu Praktykując analizę schematów blokowych i algorytmów warto zwrócić uwagę na działanie warunków i ich wpływ na przebieg pętli co ma szerokie zastosowanie zarówno w programowaniu jak i w analizie danych oraz automatyzacji procesów

Pytanie 10

Zademonstrowana pętla wykorzystuje obiekt random do:

var random = new Random();
String pulaZnakow = "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ";
int dlPuli = pulaZnakow.Length - 1;
char znak;
string wynik = "";

for (int i = 0; i < 8; i++) {
    znak = pulaZnakow[random.Next(0, dlPuli)];
    wynik += znak;
}
A. uzupełniania tablicy danymi w postaci liczb pseudolosowych
B. stworzenia losowego napisu o długości 8 znaków składającego się z liter
C. wielokrotnego generowania liczby, aby stworzyć ciąg z liczb pseudolosowych
D. jednorazowego wylosowania znaku z określonego zestawu znaków
Kod, który został przedstawiony, to typowy przykład generowania losowego napisu, takiego jak hasło czy token sesji. Random służy tutaj do wielokrotnego losowania indeksów z określonego zakresu, które następnie są używane do pobierania znaków z puli liter. W efekcie – po przejściu całej pętli – zmienna 'wynik' zawiera napis złożony z 8 losowo dobranych liter z podanego zestawu. Tak się właśnie w praktyce koduje np. generator jednorazowych haseł lub krótkich identyfikatorów użytkowników. Często takie rozwiązania spotyka się w aplikacjach internetowych, gdzie bezpieczeństwo i nieprzewidywalność takich danych są kluczowe. Zresztą, korzystanie z Random i gotowej puli znaków to branżowy standard, jeśli chodzi o prostą losowość tekstową (chociaż do kryptografii są lepsze klasy, np. RNGCryptoServiceProvider). Warto też pamiętać, że pętle for idealnie nadają się do składania ciągów o z góry ustalonej długości, co jest bardzo czytelne i zgodne z dobrymi praktykami C#. Ogólnie, ten sposób generowania losowego stringa jest szybki, łatwy do zrozumienia i nieźle się skaluje – no i sprawdza się rewelacyjnie w różnych projektach, gdzie trzeba wygenerować coś pseudo-losowego, ale czytelnego dla człowieka. Sam się kiedyś złapałem na tym, jak często taki kod się przydaje przy rejestracji użytkowników czy obsłudze prostych quizów online.

Pytanie 11

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

A. Spring Boot
B. Django
C. ASP.NET Core
D. React Native
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 12

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. Symfony
B. Bootstrap
C. Yaml
D. Angular
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 13

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

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

Pytanie 14

Który z poniższych przykładów ilustruje deklarację złożonego typu w języku C++?

A. class Student {};
B. bool status;
C. float ocena = 4.5;
D. int wynik = 100;
`bool status;` deklaruje zmienną logiczną, a nie typ złożony. `int wynik = 100;` to deklaracja zmiennej całkowitej, co również nie jest typem złożonym. `float ocena = 4.5;` definiuje zmienną zmiennoprzecinkową, co oznacza przechowywanie liczb z częściami dziesiętnymi. Żadna z tych deklaracji nie odnosi się do definicji klasy lub innego złożonego typu danych, jakim jest `class` w C++.

Pytanie 15

Zaprezentowane oznaczenie praw Creative Commons umożliwia bezpłatne wykorzystywanie utworu

Ilustracja do pytania
A. w celu dokonywania zmian lub remiksowania
B. pod warunkiem zachowania go w pierwotnej formie
C. pod warunkiem udostępnienia go na takiej samej licencji
D. w celach komercyjnych
Pozostałe odpowiedzi zawierają błędne interpretacje dotyczące warunków licencji Creative Commons. Licencje takie jak CC BY-NC jasno określają, że utwory nie mogą być wykorzystywane w celach komercyjnych, co wyklucza możliwość zarabiania na nich bez zgody autora. To ograniczenie jest istotnym elementem licencji i zapewnia, że twórcy zachowują kontrolę nad komercyjnymi aspektami swojego dzieła. Przekonanie, że można swobodnie używać utworu w celach komercyjnych, jest częstym błędem wynikającym z niepełnego zrozumienia oznaczeń licencyjnych. Dodatkowo, sugerowanie że utwór musi być zostawiony w oryginalnej postaci jest charakterystyczne dla licencji NoDerivs (ND), która nie jest tu zastosowana. Taki wymóg ogranicza możliwość modyfikacji, co nie dotyczy licencji umożliwiających remiksowanie. Co więcej, niektóre licencje wymagają udostępniania dzieł pochodnych na tej samej licencji (ShareAlike), jednak nie jest to regułą dla wszystkich typów licencji i nie dotyczy bezpośrednio analizowanego przypadku. Pomyłki te często wynikają z niewłaściwego zapoznania się z symboliką i opisami licencji Creative Commons, co podkreśla potrzebę dokładnej analizy warunków przed ich zastosowaniem. Właściwe zrozumienie zasad i ograniczeń każdej licencji jest kluczowe, aby uniknąć nieintentionalnych naruszeń praw autorskich i promować odpowiedzialne podejście do wykorzystania zawartości twórczej w zróżnicowanych projektach i inicjatywach twórczych. Zrozumienie tych zasad nie tylko wspiera prawidłowe stosowanie licencji, ale także promuje etyczne zachowania wśród twórców i użytkowników zasobów cyfrowych.

Pytanie 16

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

class Animal {
  constructor(name) {
    this.name = name;
  }
  speak() {
    return `${this.name} makes a noise.`;
  }
}

class Dog extends Animal {
  speak() {
    return `${this.name} barks.`;
  }
}

let dog = new Dog('Rex');
console.log(dog.speak());
A. Rex makes a noise.
B. undefined
C. Error: speak is not defined
D. Rex barks.
Odpowiedź "Rex barks." jest prawidłowa, ponieważ kod definiuje klasę Dog, która dziedziczy po klasie Animal. W klasie Animal mamy metodę speak(), która zwraca tekst wskazujący na dźwięk wydawany przez zwierzę. Kiedy tworzymy instancję klasy Dog, przekazujemy jej imię 'Rex'. Następnie, kiedy wywołujemy metodę speak() na obiekcie dog, zostaje użyta metoda zdefiniowana w klasie Dog, a nie ta z klasy Animal. To dlatego zwracany tekst to 'Rex barks.', co jest poprawnym i oczekiwanym wynikiem. Przykładowo, w praktycznych zastosowaniach, jeśli miałbyś różne klasy zwierząt, można by je zdefiniować w podobny sposób, gdzie każde zwierzę mogłoby mieć swoją unikalną implementację metody speak(), co wprowadza elastyczność i możliwości rozszerzalności w kodowaniu.

Pytanie 17

W zestawieniu zaprezentowano doświadczenie zawodowe pracowników firmy IT. Do stworzenia aplikacji front-end powinien/powinna zostać wyznaczony/a

PracownikZnajomość technologii lub programów
AnnaInkscape, Corel Draw
KrzysztofAngular
PatrykHTML, CSS
EwaDjango, .NET
A. Krzysztof
B. Ewa
C. Anna
D. Patryk
Anna zna programy graficzne jak Inkscape czy Corel Draw, które są spoko do tworzenia grafiki wektorowej, ale nie nadają się do budowy aplikacji front-end. Te narzędzia bardziej są w rękach grafików, którzy robią ilustracje i projekty wizualne, więc to nie do końca pasuje do front-endu, gdzie liczy się programowanie interakcji i logiki. Patryk ogarnia HTML i CSS, co jest podstawą do stawiania stron, ale niestety to nie wystarczy do budowy nowoczesnych aplikacji front-end. Musi znasz również frameworki JavaScript, takie jak Angular, React czy Vue.js, żeby aplikacja była interaktywna i by dało się z danymi lepiej zarządzać. Ewa ma umiejętności w Django i .NET, które są używane po stronie serwera. Django to framework w Pythonie, a .NET obsługuje różne języki, w tym C#. Te technologie są super do backendu, ale do front-endu już nie bardzo. Dlatego Ewa może być świetna w budowie serwerowej części aplikacji, ale nie w tworzeniu interfejsu użytkownika. Zrozumienie różnic między backendem a frontendem jest kluczowe, bo jeśli wybierzesz niewłaściwą osobę do zadania, mogą być kłopoty z integracją i wydajnością aplikacji. Dlatego ważne, żeby do front-endu był ktoś z odpowiednim doświadczeniem, tak jak Krzysztof, który zna Angulara.

Pytanie 18

Jaki kod może być związany z treścią wygenerowaną w trakcie działania programu Java?

Exception in thread "main" java.lang.ArithmeticException: / by zero
A. if (x > y) ...
B. x = x % y;
C. x = tablica[6];
D. x = 0;
Kod x = x % y; jest klasycznym przykładem operacji, która może prowadzić do wystąpienia wyjątku ArithmeticException w Javie, szczególnie gdy zmienna y przyjmuje wartość zero. Operator modulo (%) w języku Java nie toleruje dzielenia przez zero – w przeciwieństwie do niektórych innych języków, które mogą zwracać np. NaN lub Infinity, tutaj od razu zostanie zgłoszony wyjątek. Taki wyjątek jest dość powszechny w pracy programisty, zwłaszcza w aplikacjach, gdzie dane wejściowe nie są do końca kontrolowane. Moim zdaniem dobrze jest od razu przyzwyczaić się do zabezpieczania wszystkich operacji dzielenia i modulo poprzez wcześniejsze sprawdzenie wartości dzielnika. Rekomenduje się stosowanie warunków typu if (y != 0) przed wykonaniem takiej instrukcji, co jest zgodne z dobrymi praktykami defensywnego programowania. Dodatkowo, w środowiskach produkcyjnych często otacza się te fragmenty kodu blokiem try-catch, aby elegancko obsłużyć wyjątek i np. wyświetlić użytkownikowi zrozumiały komunikat. Warto pamiętać, że ArithmeticException dziedziczy po RuntimeException, a więc nie musimy jej jawnie obsługiwać, ale nie oznacza to, że powinniśmy ją ignorować – w dobrze napisanym kodzie zawsze należy przewidywać takie sytuacje. Z mojego doświadczenia wynika, że najwięcej błędów z tym związanych pojawia się w aplikacjach przetwarzających dane liczbowe, gdzie nawet niepozorna operacja modulo może „wywalić” cały proces, jeśli nie zostanie odpowiednio zaopiekowana.

Pytanie 19

Jakie środowisko jest przeznaczone do tworzenia aplikacji mobilnych dla urządzeń Apple, wykorzystujące różne języki programowania, takie jak Java i Objective C?

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

Pytanie 20

Które z wymienionych stanowi przykład zagrożenia fizycznego w miejscu pracy?

A. Brak ergonomicznych miejsc pracy
B. Promieniowanie UV
C. Nieodpowiednie relacje w zespole
D. Obciążenie psychiczne
Przeciążenie psychiczne jest zagrożeniem psychospołecznym, a nie fizycznym – dotyczy zdrowia psychicznego i samopoczucia pracownika. Złe relacje w zespole są również zagrożeniem psychospołecznym, prowadzącym do konfliktów i obniżenia efektywności pracy. Brak ergonomicznych stanowisk pracy to zagrożenie ergonomiczne, które może prowadzić do problemów zdrowotnych, takich jak bóle pleców czy nadgarstków, ale nie jest klasyfikowane jako zagrożenie fizyczne. Zagrożenia fizyczne dotyczą głównie czynników środowiskowych wpływających bezpośrednio na ciało pracownika.

Pytanie 21

Który z podanych algorytmów można zrealizować zarówno w sposób iteracyjny, jak i rekurencyjny?

A. Algorytm wyszukiwania binarnego
B. Algorytm sortowania bąbelkowego
C. Algorytm generowania liczb losowych
D. Algorytm mapowania kluczy w tablicach asocjacyjnych
Sortowanie bąbelkowe to algorytm iteracyjny i nie ma naturalnej wersji rekurencyjnej, ponieważ jego działanie opiera się na powtarzających się pętlach. Algorytm mapowania kluczy w tablicach asocjacyjnych nie korzysta z rekurencji – jest to proces przypisywania wartości do odpowiednich kluczy, który realizowany jest w sposób iteracyjny. Algorytm generowania liczb losowych nie wymaga rekurencji ani iteracji – jest to operacja oparta na wywołaniu odpowiednich funkcji w zależności od użytej biblioteki i języka programowania.

Pytanie 22

Który z wymienionych objawów może sugerować nagłe zagrożenie dla zdrowia?

A. Intensywne pocenie się w gorącym otoczeniu
B. Ostry ból w klatce piersiowej
C. Zwiększona efektywność pracy
D. Obniżony nastrój w ciągu dnia
Ostry ból w klatce piersiowej to jeden z najbardziej alarmujących objawów wskazujących na nagłe zagrożenie zdrowotne, takie jak zawał serca lub zatorowość płucna. Tego rodzaju ból jest często opisywany jako gniotący, ściskający lub rozlewający się na inne części ciała, takie jak ramię, szyja czy żuchwa. W takich przypadkach kluczowe jest szybkie wezwanie pomocy medycznej, ponieważ każda minuta opóźnienia może zwiększyć ryzyko powikłań lub śmierci. Edukacja w zakresie rozpoznawania tego objawu może uratować życie, dlatego tak ważne jest rozróżnianie go od innych mniej groźnych objawów.

Pytanie 23

Jaki rodzaj licencji umożliwia dowolne zmienianie oraz rozpowszechnianie kodu źródłowego?

A. Licencja GNU GPL
B. Licencja komercyjna
C. Licencja shareware
D. Licencja OEM
Licencja komercyjna ogranicza możliwość modyfikacji kodu i zazwyczaj wymaga zakupu oprogramowania na określonych warunkach. Licencja shareware pozwala na testowanie oprogramowania przed zakupem, ale nie uprawnia do modyfikacji ani redystrybucji kodu. Licencja OEM (Original Equipment Manufacturer) jest związana z oprogramowaniem dostarczanym przez producenta sprzętu i ogranicza możliwość instalacji na innym urządzeniu lub modyfikacji kodu źródłowego.

Pytanie 24

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

A. Ból brzucha po spożyciu posiłku
B. Gorączka oraz dreszcze
C. Spadek nastroju
D. Intensywny ból w klatce piersiowej promieniujący do lewej ręki
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 25

Kod zaprezentowany w filmie w języku C++ nie przechodzi kompilacji. Co należy zmodyfikować w tym kodzie, aby kompilacja odbyła się bez błędów?

A. poprawnie zapisać warunek w instrukcji if w linii 11, np. sprawdz(x)==true
B. naprawić błąd w funkcji sprawdz, który polega na braku nawiasów {} w pętli for
C. zadeklarować zmienną sprawdz przed jej wykorzystaniem w linii 11
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 26

Jaką wartość dziesiętną reprezentuje liczba binarna 1010?

A. 14
B. 12
C. 10
D. 8
Odpowiedzi 8, 12 i 14 są błędne w kontekście konwersji liczby binarnej 1010 na wartość dziesiętną. Liczba 8 w systemie dziesiętnym odpowiada binarnej wartości 1000. W tym przypadku, 1 * 2^3 daje 8, co oznacza, że w zapisie binarnym nie ma cyfr odpowiadających wartościom 2^2, 2^1 oraz 2^0. Liczba 12 w systemie dziesiętnym jest reprezentowana jako 1100 w systemie binarnym, co oznacza, że ma ona 1 na pozycji 2^3, 1 na pozycji 2^2, a 0 na pozycjach 2^1 oraz 2^0. Natomiast liczba 14 jest reprezentowana jako 1110 w systemie binarnym, co wskazuje, że ma 1 na pozycjach 2^3, 2^2 oraz 2^1, a 0 na pozycji 2^0. W każdym z tych przypadków, niepoprawne odpowiedzi wynikają z błędnej interpretacji wartości binarnych oraz ich odpowiedników w systemie dziesiętnym. Zrozumienie systemów liczbowych jest kluczowe w informatyce i inżynierii, ponieważ liczby binarne są podstawą funkcjonowania komputerów oraz cyfrowych systemów obliczeniowych. Dlatego tak ważne jest precyzyjne wykonanie konwersji oraz znajomość reguł związanych z tym procesem.

Pytanie 27

Które z wymienionych sformułowań najlepiej definiuje oprogramowanie typu ransomware?

A. Złośliwe aplikacje wyświetlające reklamy
B. Oprogramowanie uniemożliwiające dostęp do danych w celu wymuszenia zapłaty
C. Oprogramowanie stosowane do realizacji ataków DDoS
D. Programy zbierające prywatne dane bez zgody użytkownika
Oprogramowanie typu ransomware to rodzaj złośliwego oprogramowania, które ma na celu zablokowanie dostępu do danych użytkownika, a następnie wymuszenie okupu w zamian za ich przywrócenie. Ransomware działa na zasadzie szyfrowania plików na zainfekowanym urządzeniu, co uniemożliwia użytkownikowi korzystanie z danych. Po dokonaniu szyfrowania, ofiara otrzymuje wiadomość z żądaniem okupu, zazwyczaj w kryptowalutach, które mają na celu anonimowość transakcji. Przykłady ransomware to oprogramowanie takie jak WannaCry oraz Petya, które spowodowały globalne ataki, skutkując znacznymi stratami finansowymi dla wielu organizacji. Zgodnie z definicjami i standardami, takimi jak NIST (National Institute of Standards and Technology), ransomware jest klasyfikowane jako jedno z najpoważniejszych zagrożeń dla bezpieczeństwa informacji. Warto również zauważyć, że ransomware rozwija się, a jego twórcy stosują różne techniki, aby zwiększyć skuteczność ataków, takie jak wykorzystywanie luk w oprogramowaniu oraz phishing, aby zainfekować systemy użytkowników.

Pytanie 28

Który z poniższych kodów realizuje przedstawiony fragment algorytmu?

Ilustracja do pytania
A. Kod 2
B. Kod 4
C. Kod 3
D. Kod 1
Bardzo dobrze wychwycone! Kod 3 idealnie odwzorowuje logikę algorytmu przedstawioną na schemacie blokowym. Pętla while sprawdza warunek y != 100 i dopóki jest spełniony, wykonuje instrukcję y = a + b. Zarówno przebieg pętli, jak i wyjście z niej odpowiadają dokładnie temu, co prezentuje ten diagram blokowy – czyli wykonujemy przypisanie y = a + b, jeśli warunek jest prawdziwy, a gdy przestaje być, wychodzimy z pętli. Takie podejście jest bardzo typowe w programowaniu, nie tylko w szkolnych zadaniach, ale też w praktyce, gdy musimy powtarzać akcję do momentu spełnienia konkretnego warunku. Moim zdaniem, dobrze jest tutaj zauważyć, że pętle while są preferowane, gdy nie znamy z góry liczby powtórzeń, a warunek wejścia ma być sprawdzany przed każdym przebiegiem – to klasyczna konstrukcja w językach takich jak C, Java czy Python. Tego typu algorytmy można spotkać choćby podczas obsługi wejścia użytkownika (np. powtarzaj pytanie, aż użytkownik poda poprawną wartość) albo w sterowaniu urządzeniami, gdy czekamy na określony sygnał wejściowy. Warto też pamiętać, że w profesjonalnym kodzie dobrze jest dbać o czytelność i jednoznaczność takich fragmentów – a ten kod właśnie taki jest. Swoją drogą, czasem warto dodać jeszcze zabezpieczenia, by uniknąć tzw. nieskończonej pętli, ale tutaj, jak widać, intencja jest jasna i zgodna ze standardami branżowymi.

Pytanie 29

Wskaż fragment kodu, który stanowi realizację przedstawionego algorytmu w języku C++.

Kod 1
do {
  suma = suma + i;
} while (suma <= liczba);
cout << suma;
Kod 2
if (suma <= liczba) {
  suma = suma + i;
  i++;
}
else
  cout << suma;
Kod 3
for (i = suma; i <= liczba; i++)
  suma = suma + i;
else
  cout << suma;
Kod 4
while (suma <= liczba) {
  suma = suma + i;
  i++;
}
cout << suma;
Ilustracja do pytania
A. kod 3
B. kod 4
C. kod 1
D. kod 2
W niepoprawnych fragmentach kodu problemem nie jest sam język C plus plus, tylko sposób odwzorowania algorytmu z rysunku. Schemat blokowy jasno mówi, że dopóki suma jest mniejsza lub równa liczba, mamy wielokrotnie dodawać kolejne wartości i oraz zwiększać licznik, a dopiero po wyjściu z tego cyklu jednorazowo wypisać wartość suma. Konstrukcja z pętlą do while wykonuje ciało przynajmniej raz bez wcześniejszego sprawdzenia warunku, czyli najpierw dodaje i do sumy, a dopiero później porównuje suma <= liczba. To subtelne przesunięcie powoduje, że kod może wykonać jedną iterację za dużo w stosunku do schematu. W praktyce bywa to bardzo groźne, na przykład przy obsłudze buforów w systemach wbudowanych czy przy obliczeniach finansowych. Fragment oparty wyłącznie na instrukcji if z else nie tworzy żadnej pętli, więc kod wykona maksymalnie jedno dodanie i, a to jest całkowicie sprzeczne z ideą powtarzania z diagramu. To typowy błąd uczniów, którzy mylą pojedyncze rozgałęzienie z cyklicznym przetwarzaniem danych. Z kolei użycie pętli for z else wygląda na pierwszy rzut oka efektownie, ale również nie odpowiada schematowi. Po pierwsze, zakres iteracji jest na sztywno powiązany z warunkiem i <= liczba, a algorytm operuje na warunku suma <= liczba. Po drugie, else po pętli for nie jest standardową konstrukcją w C plus plus i w praktyce taki kod nawet się nie skompiluje. Z mojego doświadczenia wynika, że źródłem większości takich pomyłek jest próba zbyt kreatywnego kombinowania zamiast trzymania się prostego tłumaczenia: warunek na rombie przekładamy na warunek w pętli, strzałka oznacza powrót na początek, a blok pisz suma to pojedyncza instrukcja po zakończeniu pętli. Dopiero jak to rozumiemy, można zaczynać optymalizacje czy inne fajerwerki składniowe.

Pytanie 30

Jakie jest poprawne określenie interfejsu (szablonu klasy) w języku Java?

interface IMyInterface {
    private: int a;
    IMyInterface() { a = 0; }
    void mth1();
}
Definicja 1
interface IMyInterface {
    private: int a;
    void mth1();
    int mth2() { return a; }
}
Definicja 2
interface IMyInterface {
    void mth1();
    int mth2() { return 0; }
}
Definicja 3
interface IMyInterface {
    void mth1();
    int mth2();
}
Definicja 4
A. Definicja 1
B. Definicja 4
C. Definicja 3
D. Definicja 2
W pierwszej definicji interfejsu obecność zmiennej prywatnej i konstruktora jest niezgodna z zasadami definiowania interfejsów w języku Java. Interfejsy nie mogą zawierać żadnych konstruktorów, ponieważ nie są klasami i nie można ich instancjonować. Dodatkowo, zmienne w interfejsach są domyślnie publiczne, statyczne i finalne, co oznacza, że nie mogą być prywatne jak w tej definicji. Druga definicja popełnia podobne błędy przez deklarowanie prywatnej zmiennej i implementację metody wewnątrz interfejsu, co przed Java 8 było niemożliwe. Trzecia definicja zawiera metodę z ciałem, co w kontekście starszych wersji Javy nie jest zgodne z zasadami, choć od Java 8 można deklarować metody domyślne z ciałem, jednak w tej sytuacji nie jest to poprawne bez specyfikacji default. Błędnie przyjęte podejścia do definicji interfejsów mogą wynikać z niezrozumienia, że interfejsy służą jedynie do deklarowania metod i ewentualnie statycznych finalnych zmiennych, nie zaś do implementacji logiki. Prawidłowe zrozumienie roli interfejsów jest kluczowe dla wykorzystania ich w tworzeniu elastycznego i rozszerzalnego kodu. Błędy te podkreślają potrzebę dbałości o zgodność ze specyfikacją języka oraz znajomość jego wersji i nowości wprowadzanych w kolejnych iteracjach.

Pytanie 31

Kod w bibliotece React.js oraz w frameworku Angular, który został zaprezentowany, ma na celu wyświetlenie

Fragment kodu React.js:
state = {    zm1: 0   };
hanleEv = () => {
    this.setState({zm1: this.state.zm1 + 1});
}
render() {
    return (<div>
        <span>{this.state.zm1}</span>
        <button onClick={this.handleEv}>BTN_1</button>
    </div>);
}
Fragment kodu Angular:
@Component({
    selector: 'sel1',
    template: `<span>{{ zm1 }}</span>
              <button (click)="onBtnCilcked()">BTN_1</button>`
})
export class Licznik1Component {
    zm1 = 0;
    onBtnCilcked() { this.zm1++; }
}
A. tylko napisu BTN_1
B. liczby kliknięć przycisku
C. wyłącznie przycisku oraz obsłużenie zdarzenia click, które ono generuje
D. wartości 0 po naciśnięciu przycisku
Ten kod, zarówno w React.js jak i w Angularze, jest klasycznym przykładem prostego licznika. To, co tu się dzieje, to tak naprawdę zliczanie kliknięć użytkownika w przycisk. Za każdym razem, gdy naciśniesz BTN_1, zmienna (zm1) jest inkrementowana – czyli po prostu zwiększana o jeden. W React za to odpowiada metoda setState, która zmienia stan komponentu – dzięki temu interfejs od razu aktualizuje się bez przeładowywania strony. W Angularze natomiast działa to przez tzw. dwukierunkową komunikację z template’em i automatyczną detekcję zmian – metoda onBtnCilcked w komponencie modyfikuje zmienną, a framework sam aktualizuje widok. Z mojego doświadczenia, takie podejście do zarządzania stanem to podstawa w nowoczesnych aplikacjach, szczególnie jeśli chodzi o responsywność i natychmiastową reakcję na akcje użytkownika. Liczniki są zresztą jednym z pierwszych przykładów, jakie się pisze ćwicząc frameworki frontendowe, bo świetnie pokazują, jak działa przepływ danych i odświeżanie elementów UI. Warto dodać, że trzymanie licznika kliknięć w stanie komponentu (a nie np. jako zmienną globalną) jest zgodne z dobrymi praktykami – bo ogranicza zakres danych i ułatwia zarządzanie większymi aplikacjami. Takie wzorce potem można z powodzeniem przenieść do trudniejszych projektów, na przykład liczników, koszyków, liczby zamówień czy nawet zaawansowanych dashboardów. W praktyce ten mechanizm inkrementowania wartości po kliknięciu użytkownika jest jednym z najczęściej używanych w interaktywnych aplikacjach internetowych.

Pytanie 32

Jakie będą skutki wykonania podanego fragmentu kodu w języku C++?

vector <int> liczby;
for(int i=0; i<10; i++) {
    liczby.push_back(2*i);
}
A. Z tablicy liczby usuwane są elementy, z każdym obiegiem pętli eliminowany jest element z jej początku.
B. Do tablicy liczby, na jej końcu, dodawane są nowe wartości.
C. Z tablicy liczby usuwane są elementy, z każdym obiegiem pętli eliminowany jest element z jej końca.
D. Do tablicy liczby, na jej początku, dodawane są nowe wartości.
Analizując zaproponowane odpowiedzi, łatwo zauważyć kilka typowych nieporozumień, które często pojawiają się na etapie nauki pracy z kolekcjami w C++. Po pierwsze, wielu osobom myli się pojęcie 'dodawania na początku' z 'dodawaniem na końcu', zwłaszcza że niektóre struktury standardowe, jak listy dwukierunkowe (std::list), umożliwiają wygodne wstawianie na początku (push_front). Jednak w przypadku std::vector nie ma metody push_front, a push_back oznacza zawsze dodanie nowego elementu do końca wektora, co powoduje, że kolejność elementów jest zachowana zgodnie z kolejnością ich dodawania. Błędne jest także przekonanie, że za każdym przebiegiem pętli z wektora coś jest usuwane – takie operacje wymagałyby jawnego wywołania metod erase(), pop_back() lub pop_front(), których tutaj w ogóle nie zastosowano. To bardzo istotne, bo domyślnie wektor nie usuwa niczego sam z siebie. Równie często spotykanym błędem jest mylenie działania innych kolekcji, jak np. kolejki FIFO (gdzie pop_front rzeczywiście usuwa pierwszy element), z zachowaniem vectora, który domyślnie dodaje na końcu. Sporo osób wychodzi z założenia, że 'dynamiczna tablica' powinna się samoistnie przesuwać lub skracać – ale to nie jest prawda w C++. Warto zapamiętać, że vector w C++ jest stworzony głównie do efektywnego rozbudowywania od końca i to jest zgodne z koncepcją dynamicznego zarządzania pamięcią w nowoczesnych językach programowania. Każdy inny sposób użycia wymaga dodatkowego kodu. Z mojego punktu widzenia dobrze jest od razu wyrobić sobie nawyk rozróżniania, która operacja jest domyślnie dostępna w danym kontenerze. Brak tej wiedzy prowadzi do błędnych założeń co do działania kodu i generuje trudne do wychwycenia błędy logiczne.

Pytanie 33

Definicja konstruktora dla zaprezentowanej klasy w języku C++ może być sformułowana jak poniżej:

class Owoc
{
    public:
        double waga;
        string nazwa;
        Owoc(double waga, string nazwa);
};

Deklaracja 1:
Owoc::Owoc(double waga, string nazwa) {
    this -> waga = waga;
    this -> nazwa = nazwa;
}

Deklaracja 2:
Construct::Owoc(double waga, string nazwa) {
    this -> waga = waga;
    this -> nazwa = nazwa;
}

Deklaracja 3:
Construct::Owoc(double waga, string nazwa) {
    this.waga = waga;
    this.nazwa = nazwa;
}

Deklaracja 4:
Owoc::Owoc(double waga, string nazwa) {
    this.waga = waga;
    this.nazwa = nazwa;
}
A. Deklaracji 4
B. Deklaracji 1
C. Deklaracji 3
D. Deklaracji 2
Deklaracja 1 pokazuje dokładnie taką definicję konstruktora, jaka powinna być użyta w języku C++. Nazwa klasy i konstruktora musi być identyczna, a składnia Owoc::Owoc(double waga, string nazwa) jest kanoniczna w C++ dla implementacji konstruktora poza klasą. Użycie this->waga = waga jasno wskazuje, że chodzi o przypisanie wartości z parametru do pola składowego klasy. W praktyce to jest bardzo często spotykany wzór przy pisaniu konstruktorów dla klasy, która ma kilka pól – tak można odróżnić parametry funkcji od pól klasy. Moim zdaniem warto zawsze zwracać uwagę na taki zapis, bo to pomaga unikać błędów, zwłaszcza przy większych projektach, gdzie pól może być sporo i łatwo się pomylić. W dodatku stosowanie składni this-> od razu sygnalizuje, że działamy na polach konkretnej instancji obiektu. Takie podejście jest zgodne ze wszystkimi standardami C++ i bez problemu skompiluje się w każdym środowisku. W praktyce często spotykam się z tym, że ktoś próbuje stosować inne notacje czy podpatrzone w innych językach konstrukcje, ale w C++ to właśnie taki zapis jest poprawny i klarowny dla każdego programisty. Dla czytelności kodu i łatwości utrzymania projektu, zdecydowanie polecam trzymać się tej formy. Dobrze jest też pamiętać, że w nowszych wersjach C++ można też użyć listy inicjalizacyjnej, ale tutaj przedstawiony sposób jest w pełni poprawny i zrozumiały.

Pytanie 34

Który z wymienionych elementów UI w aplikacjach mobilnych jest odpowiedzialny za przechodzenie pomiędzy ekranami?

A. Pasek narzędziowy
B. ListView
C. Przycisk
D. Navigation Drawer
Przycisk (Button) jest podstawowym elementem interfejsu użytkownika, ale nie spełnia funkcji nawigacyjnej na poziomie strukturalnym – jego zastosowanie ogranicza się do wywoływania pojedynczych akcji po kliknięciu. ListView to komponent wyświetlający listę elementów, ale nie odpowiada za nawigację pomiędzy ekranami aplikacji, a jedynie za prezentację danych. Pasek narzędziowy (Toolbar) to element, który zwykle znajduje się na górze ekranu i umożliwia dostęp do opcji takich jak wyszukiwanie lub ustawienia, ale nie pełni funkcji bocznego menu nawigacyjnego, jak Navigation Drawer.

Pytanie 35

Na przedstawionym obrazie widać fragment emulacji systemu iOS z prostą aplikacją. Górna część ekranu nachodzi na pasek stanu baterii. Który z poniższych zapisów powinien zostać użyty w miejscu znaków zapytania, aby ustawić jedynie marginesy górne tylko dla systemu iOS?

Ilustracja do pytania
A. x:TypeArguments="Thickness" <br/> (0, 20, 0, 0)
B. x:TypeArguments="Thickness"<br/> iOS= 20
C. x:TypeArguments="Thickness"<br/> iOS= "0, 20, 0, 0"<br/> Android= "0, 0, 0, 0"<br/> WinPhone= "0, 0, 0, 0"
D. x:TypeArguments="Thickness"<br/> iOS= "0, 0, 0, 0"<br/> Android= "0, 20, 0, 0"<br/> WinPhone= "0, 0, 0, 0"
W pierwszej opcji zastosowano jednolity margines 20 jednostek dla wszystkich platform, co jest niewłaściwe, ponieważ ignoruje specyficzne potrzeby i ograniczenia każdej platformy. Na przykład, na iOS margines ten kompensuje status bar, ale na innych platformach może nie być wymagany, co może prowadzić do nieestetycznego wyglądu aplikacji. Druga odpowiedź wprowadza margines tylko dla iOS, ale w niewłaściwym formacie, ponieważ same liczby nie są wystarczające bez poprawnego kontekstu struktury XAML. Trzecia opcja jest błędna, ponieważ przypisuje nieprawidłowe wartości platformie Android, co skutkuje odwrotnym efektem niż zamierzony. Traktowanie wszystkich platform identycznie pod względem marginesów pomija specyfikę każdej z nich, co jest częstym błędem początkowych deweloperów. Niezrozumienie różnic między platformami może prowadzić do aplikacji, które nie są optymalnie dostosowane do każdej z nich. Ważne jest, aby projektanci aplikacji wieloplatformowych zrozumieli, jak różne urządzenia i systemy operacyjne wpływają na sposób, w jaki aplikacja powinna wyglądać i działać, aby zapewnić użytkownikom spójne i wysokiej jakości doświadczenia niezależnie od platformy, na której aplikacja jest uruchamiana. Dostosowywanie UI do specyfiki każdej platformy jest kluczem do sukcesu w tworzeniu profesjonalnych aplikacji mobilnych.

Pytanie 36

Jakie są różnice pomiędzy środowiskiem RAD a klasycznym IDE w kontekście aplikacji webowych?

A. RAD funkcjonuje tylko w systemach Windows
B. RAD umożliwia szybsze prototypowanie i rozwój aplikacji dzięki narzędziom wizualnym
C. RAD koncentruje się wyłącznie na budowie frontendu aplikacji
D. RAD nie wspiera żadnych języków backendowych
Rapid Application Development (RAD) to metodologia, która koncentruje się na szybkim prototypowaniu i iteracyjnym tworzeniu aplikacji. Dzięki narzędziom wizualnym RAD umożliwia programistom i projektantom szybkie budowanie interfejsów użytkownika oraz testowanie funkcjonalności aplikacji na wczesnym etapie rozwoju. RAD skraca czas potrzebny na dostarczenie gotowego produktu, co czyni go idealnym rozwiązaniem w dynamicznie zmieniających się projektach webowych. Narzędzia RAD umożliwiają także automatyczne generowanie kodu, co znacznie przyspiesza proces programowania.

Pytanie 37

Z jakiego obiektu można skorzystać, aby stworzyć kontrolkę wskazaną strzałką na ilustracji?

Ilustracja do pytania
A. Windows - dla biblioteki WPF; JFrame - dla biblioteki Swing
B. Text - dla biblioteki WPF; JText - dla biblioteki Swing
C. Box - dla biblioteki WPF; JField - dla biblioteki Swing
D. TextBox - dla biblioteki WPF; JTextField - dla biblioteki Swing
Wybrałeś dokładnie to, co w praktyce programisty jest najważniejsze, czyli TextBox dla WPF i JTextField dla Swinga. Te dwa komponenty to absolutna podstawa, jeśli chodzi o pola do wprowadzania tekstu, zarówno w aplikacjach .NET, jak i Java. W WPF TextBox pozwala na przyjmowanie danych od użytkownika, obsługę zdarzeń, walidację, formatowanie tekstu – ogólnie wszystko, co potrzeba do pracy z tekstem w GUI. W Swingu JTextField jest odpowiednikiem, bardzo intuicyjnym i prostym w użyciu, świetnie się sprawdza przy prostych formularzach czy interfejsach użytkownika. Co ciekawe, oba te komponenty są bardzo elastyczne, można je stylizować, podłączać do systemów walidacji czy nawet rozbudowywać o własne mechanizmy autouzupełniania. Spotkałem się wielokrotnie z sytuacją, gdzie poprawne zastosowanie TextBoxa lub JTextFielda znacząco podnosiło jakość aplikacji – bo jednak wygoda użytkownika i poprawność danych są kluczowe. Takie wybory są zgodne z dokumentacją Microsoftu oraz Oracla, więc trzymasz się dobrych praktyk. Z mojej perspektywy, jeśli chcesz pisać nowoczesne, użytkowe aplikacje desktopowe, znajomość tych kontrolek to absolutny must-have.

Pytanie 38

Który z wymienionych kroków wchodzi w skład testowania aplikacji?

A. Debugowanie kodu w celu znalezienia błędów
B. Opracowywanie interfejsu graficznego
C. Kompilowanie aplikacji
D. Projektowanie bazy danych
Debugowanie kodu w celu znalezienia błędów to jeden z kluczowych etapów testowania aplikacji. Proces ten polega na uruchamianiu programu w trybie debugowania, co pozwala na śledzenie jego działania linijka po linijce i identyfikowanie miejsc, w których występują błędy. Debugowanie umożliwia analizowanie wartości zmiennych, śledzenie przepływu programu i wykrywanie nieoczekiwanych zachowań, co jest niezbędne do usunięcia błędów i poprawy wydajności aplikacji. Narzędzia do debugowania, takie jak Visual Studio, PyCharm czy Chrome DevTools, pozwalają na dokładne testowanie kodu na różnych etapach jego rozwoju, co znacząco skraca czas naprawy błędów i zwiększa jakość oprogramowania.

Pytanie 39

Co to jest framework?

A. zbiór procedur, danych oraz złożonych typów danych używanych w kodzie źródłowym aplikacji
B. narzędzie przeznaczone do opracowywania, edytowania, testowania i uruchamiania oprogramowania
C. oprogramowanie, które za pomocą metody drag and drop pozwala na stworzenie interfejsu aplikacji
D. platforma programistyczna oferująca określone komponenty oraz narzucająca szkielet lub metodologię tworzenia aplikacji
Sporo osób myli framework z innymi narzędziami programistycznymi, co moim zdaniem wynika z tego, że wszystkie te elementy – biblioteki, IDE, gotowe komponenty – jakoś się ze sobą przeplatają w codziennej pracy. Jednak framework to pojęcie o wiele szersze niż tylko zbiór procedur, danych czy typów danych obecnych w kodzie aplikacji. Tak naprawdę framework tworzy cały szkielet pod projekt i narzuca określone reguły, przez co programista nie ma pełnej swobody, ale za to zyskuje uporządkowanie pracy. Często ludzie utożsamiają framework z narzędziami typu drag and drop, bo te też przyspieszają budowę interfejsu, ale to zupełnie inna bajka. Framework nie ogranicza się wyłącznie do warstwy wizualnej ani do samego projektowania UI – obejmuje ogólną architekturę, zarządzanie zależnościami, obsługę zapytań czy nawet bezpieczeństwo. Z kolei środowisko programistyczne (IDE) rzeczywiście służy do kodowania, testowania czy uruchamiania aplikacji, ale nie narzuca architektury, nie daje gotowych założeń projektowych. Typowy błąd myślowy to traktowanie frameworka jako „większej biblioteki” albo narzędzia, które coś ułatwia – a sedno leży właśnie w tym, że narzuca określony sposób myślenia o projekcie i pilnuje, żeby kod rozwijał się według ustalonego schematu. Przykłady jak Spring, Django czy Laravel pokazują, że framework wyznacza kierunek całej aplikacji, a nie tylko dostarcza pojedyncze funkcje czy narzędzia. W praktyce, korzystanie z frameworka to nie tylko wygoda, ale i przestrzeganie pewnych standardów, co jest bardzo cenione w profesjonalnych zespołach developerskich.

Pytanie 40

Który z wymienionych składników wchodzi w skład podstawowego wyposażenia środowiska IDE?

A. Edytor graficzny, przeglądarka kodu, narzędzia analityczne
B. Kompilator, serwer webowy, system kontroli wersji
C. Edytor tekstowy, przeglądarka internetowa, translator
D. Kompilator, edytor kodu, debugger
Edytor tekstowy, przeglądarka internetowa i translator nie są integralnymi komponentami środowiska IDE. Chociaż edytor tekstowy może być używany do pisania kodu, brakuje mu zaawansowanych funkcji dostępnych w edytorach IDE, takich jak podpowiedzi składniowe, automatyczne uzupełnianie kodu czy narzędzia do debugowania. Kompilator, serwer webowy i system kontroli wersji są ważne w środowisku webowym, ale nie wszystkie aplikacje desktopowe wymagają serwera webowego. Edytor graficzny i narzędzia analityczne mogą wspierać rozwój interfejsu, ale nie są to podstawowe narzędzia każdego IDE.