Wyniki egzaminu

Informacje o egzaminie:
  • Zawód: Technik programista
  • Kwalifikacja: INF.04 - Projektowanie, programowanie i testowanie aplikacji
  • Data rozpoczęcia: 10 kwietnia 2026 12:36
  • Data zakończenia: 10 kwietnia 2026 12:42

Egzamin zdany!

Wynik: 24/40 punktów (60,0%)

Wymagane minimum: 20 punktów (50%)

Nowe
Analiza przebiegu egzaminu— sprawdź jak rozwiązywałeś pytania
Pochwal się swoim wynikiem!
Szczegółowe wyniki:
Pytanie 1

Która z poniższych metod tablicowych w JavaScript nie modyfikuje oryginalnej tablicy?

A. map()
B. push()
C. sort()
D. splice()
Metoda map() w JavaScript jest funkcją tablicową, która tworzy nową tablicę na podstawie wyników wywołania funkcji podanej jako argument dla każdego elementu oryginalnej tablicy. Kluczowym aspektem tej metody jest to, że nie modyfikuje oryginalnej tablicy, co czyni ją bezpiecznym narzędziem do transformacji danych. Zastosowanie map() jest szczególnie przydatne w sytuacjach, gdy chcemy przekształcić dane, ale zachować oryginał, na przykład w przypadku przetwarzania wyników z API lub operacji na danych wejściowych od użytkownika. Standardowe praktyki zalecają używanie map() w programowaniu funkcyjnym, co pozwala na bardziej deklaratywne podejście do manipulacji danymi. Przykład zastosowania: mając tablicę liczb, możemy użyć map() do stworzenia nowej tablicy, która zawiera tylko ich kwadraty: const numbers = [1, 2, 3]; const squares = numbers.map(num => num * num); W ten sposób oryginalna tablica numbers pozostaje nietknięta, co jest kluczowe w wielu aplikacjach, w których zachowanie stanu jest istotne.

Pytanie 2

Jaką wartość ma zmienna b po wykonaniu poniższego kodu?

int a = 1, b = 20, c = 3;
while (a <= 10) {
    b = b - c;
    a += 2;
}
A. 5
B. 2
C. 11
D. 20
Po przeanalizowaniu przedstawionego kodu, możemy zauważyć, że zmienne a b i c są zainicjalizowane odpowiednio wartościami 1 20 i 3. Pętla while jest zależna od warunku a <= 10 co oznacza że będzie się wykonywać dopóki a nie przekroczy 10. W ciele pętli najpierw zmniejszamy wartość b o wartość c czyli b = b - c a następnie zwiększamy a o 2 czyli a += 2. Ponieważ a jest początkowo równe 1 pętla będzie się wykonywać pięć razy zanim a stanie się większe niż 10 (1 3 5 7 9). Podczas każdej iteracji wartość b zmniejsza się o 3 (ponieważ c=3). Po pięciu iteracjach wartość b zostanie zmniejszona o 15 (5*3) z początkowej wartości 20 uzyskując ostatecznie 5. W tym kontekście poprawna odpowiedź to 5. Takie podejście do analizy pętli i zmiennych jest kluczowe podczas programowania ponieważ pozwala zrozumieć jak zmieniają się wartości zmiennych w czasie wykonywania programu. Zrozumienie tych zasad jest fundamentalne w programowaniu proceduralnym oraz w debugowaniu kodu.

Pytanie 3

Co to jest GraphQL?

A. Język zapytań do API oraz środowisko wykonawcze do obsługi tych zapytań
B. System zarządzania bazami grafowymi
C. Format danych podobny do JSON używany w komunikacji między aplikacjami
D. Biblioteka do tworzenia grafów i diagramów w aplikacjach webowych
GraphQL to innowacyjny język zapytań do API oraz środowisko wykonawcze, które umożliwia efektywne i elastyczne pobieranie oraz manipulowanie danymi. W przeciwieństwie do tradycyjnych API REST, gdzie każde zapytanie zwraca predefiniowany zbiór danych, GraphQL pozwala klientowi na zdefiniowanie dokładnie tego, co chce otrzymać. Oznacza to, że aplikacja może uniknąć nadmiarowych danych lub wielokrotnych zapytań do serwera. Przykładowo, w aplikacji mobilnej, która wyświetla profil użytkownika, możemy za pomocą jednego zapytania uzyskać wszystkie potrzebne informacje, takie jak imię, nazwisko, zdjęcie oraz listę znajomych, zamiast wysyłać osobne zapytania dla każdego z tych elementów. Tego rodzaju elastyczność jest kluczowa w skalowalnych architekturach, gdzie różne klienci mogą potrzebować różnych zbiorów danych. GraphQL promuje również dobre praktyki w zakresie wersjonowania API, umożliwiając jego rozwój bez wprowadzania niekompatybilnych zmian dla bieżących klientów.

Pytanie 4

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

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

Pytanie 5

Która z wymienionych kart graficznych oferuje lepszą wydajność w grach komputerowych?

A. AMD Radeon R7 240 - 2GB GDDR5, 64-bit
B. NVIDIA GeForce GTX 1050 Ti - 4GB GDDR5, 128-bit
C. AMD Radeon RX 580 - 8GB GDDR5, 256-bit
D. Intel UHD Graphics 630 - zintegrowana
AMD Radeon RX 580 to karta graficzna, która zapewnia wyższą wydajność w grach komputerowych w porównaniu do innych wymienionych opcji. Wyposażona w 8GB pamięci GDDR5 oraz 256-bitową szynę danych, karta ta jest w stanie obsługiwać bardziej złożone tekstury oraz większe rozdzielczości. Jej architektura Polaris pozwala na lepsze zarządzanie energią oraz wydajność w grach, co czyni ją idealnym wyborem dla graczy. Dzięki obsłudze technologii DirectX 12 i Vulkan, RX 580 jest w stanie wykorzystać najnowsze osiągnięcia w dziedzinie grafiki, co przekłada się na wyższą jakość obrazu oraz płynność animacji. Przykłady gier, w których RX 580 sprawdza się najlepiej to 'Far Cry 5' czy 'Shadow of the Tomb Raider', gdzie karta umożliwia granie w wysokich ustawieniach graficznych z zachowaniem wysokiej liczby klatek na sekundę. Standardy, takie jak PCIe 3.0, zapewniają pełną kompatybilność z nowoczesnymi płytami głównymi, co czyni tę kartę doskonałym wyborem dla entuzjastów gier komputerowych.

Pytanie 6

Która metoda wyszukiwania potrzebuje posortowanej listy do prawidłowego działania?

A. Wyszukiwanie sekwencyjne
B. Wyszukiwanie z hashem
C. Wyszukiwanie binarne
D. Wyszukiwanie liniowe
Wyszukiwanie binarne wymaga posortowanej tablicy do działania, co pozwala na dzielenie tablicy na pół przy każdym kroku, redukując liczbę operacji do O(log n). Algorytm ten działa poprzez porównanie poszukiwanego elementu ze środkowym elementem tablicy – jeśli element jest mniejszy, wyszukiwanie kontynuuje w lewej części tablicy, a jeśli większy, w prawej. Dzięki tej efektywności, wyszukiwanie binarne jest szeroko stosowane w bazach danych, systemach plików oraz aplikacjach, które operują na dużych zbiorach danych. Wyszukiwanie binarne jest prostym, ale potężnym algorytmem, który znacząco skraca czas przeszukiwania dużych zbiorów.

Pytanie 7

Jakie z wymienionych narzędzi służy do testowania aplikacji?

A. WordPress
B. Selenium
C. Photoshop
D. Git
Git to system kontroli wersji, który umożliwia śledzenie zmian w kodzie źródłowym i współpracę w zespołach deweloperskich, ale nie służy do automatycznego testowania aplikacji webowych. Photoshop to narzędzie graficzne do edycji zdjęć i tworzenia grafik, nie ma zastosowania w testowaniu oprogramowania. WordPress to system zarządzania treścią (CMS), który pozwala na tworzenie i zarządzanie stronami internetowymi, ale nie pełni funkcji narzędzia do testowania aplikacji webowych.

Pytanie 8

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

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

Zaprezentowany kod zawiera pola danej klasy. Które pole (pola) mogą być dostępne z poziomu głównego programu poprzez odwołanie w formie nazwaObiektu.nazwaPola?

private int p1;
private short p2;
public string p3;
protected string p4;
protected float p5;
A. jedynie p3
B. p1
C. p3 i p4
D. wyłącznie p3, p4, p5
To jest właśnie sedno sprawy z modyfikatorami dostępu w programowaniu obiektowym, szczególnie w językach takich jak Java czy C#. Kiedy masz pole oznaczone jako public, jak w przypadku p3, to znaczy, że możesz się do niego odwołać z poziomu dowolnego innego kodu, czyli np. z głównego programu poprzez konstrukcję nazwaObiektu.nazwaPola. To jest bardzo wygodne, choć uczciwie mówiąc, nie zawsze bezpieczne – branżowo najczęściej rekomenduje się stosowanie enkapsulacji, czyli raczej private i dostęp przez gettery/settery. Moim zdaniem lepiej rozumieć, dlaczego public coś udostępnia, a protected czy private już nie. Protected pozwala na dostęp tylko w klasach pochodnych, więc w samym głównym programie (po prostu mając obiekt tej klasy) nie masz do niego dostępu. Private – to już w ogóle, jedynie sama klasa może się dobrać do własnych pól, cała reszta odpada. To, co często zaskakuje, to fakt, że nawet jeśli coś jest protected, to nie zrobisz obiekt.protectedPole w zwykłym programie – musiałbyś pisać klasę dziedziczącą. Praktycznie public daje największą swobodę, ale z mojego doświadczenia, jeśli nie musisz, nie rób wszystkiego na public. W tym przykładzie jedynie p3 można bezpośrednio wywołać z głównego programu przez nazwaObiektu.p3 – reszta jest ukryta przez modyfikatory dostępu, i to jest zdecydowanie zgodne ze sztuką programowania obiektowego i zasadą hermetyzacji.

Pytanie 10

Jakie środowisko deweloperskie jest powszechnie wykorzystywane do produkcji aplikacji webowych w języku Java?

A. XCode
B. Eclipse
C. PyCharm
D. Android Studio
Eclipse to jedno z najpopularniejszych środowisk programistycznych (IDE) wykorzystywanych do tworzenia aplikacji webowych w języku Java. Jest to potężne narzędzie, które wspiera zarówno tworzenie aplikacji desktopowych, jak i rozbudowanych systemów backendowych. Eclipse oferuje wiele wtyczek i rozszerzeń umożliwiających integrację z narzędziami do zarządzania bazami danych, serwerami aplikacji oraz systemami kontroli wersji. Dzięki temu programiści mogą efektywnie budować i testować aplikacje webowe napisane w Javie.

Pytanie 11

Jak przedstawia się liczba dziesiętna 255 w systemie szesnastkowym?

A. EF
B. FE
C. 100
D. FF
Liczba dziesiętna 255 jest reprezentowana w systemie szesnastkowym jako FF. Aby zrozumieć, dlaczego tak jest, należy przyjrzeć się procesowi konwersji z systemu dziesiętnego na szesnastkowy. System dziesiętny oparty jest na podstawie 10, co oznacza, że używa dziesięciu cyfr od 0 do 9. W systemie szesnastkowym, który ma podstawę 16, używane są cyfry od 0 do 9 oraz litery od A do F, gdzie A odpowiada 10, B - 11, C - 12, D - 13, E - 14, a F - 15. Aby przeliczyć 255 na system szesnastkowy, dzielimy tę liczbę przez 16. Pierwsza operacja daje nam 15 jako wynik całkowity oraz 15 jako resztę, co w systemie szesnastkowym jest reprezentowane literą F. Dalsze dzielenie 15 przez 16 daje wynik 0 oraz resztę 15, co również jest reprezentowane jako F. Zatem, zapisując reszty w odwrotnej kolejności, otrzymujemy FF. Taki zapis jest używany w różnych standardach, takich jak HTML i CSS, gdzie kolory są przedstawiane w formacie szesnastkowym. Przykładem może być kolor czerwony, którego zapis to #FF0000, co oznacza maksymalną wartość czerwonego składnika i zera dla niebieskiego oraz zielonego. Warto znać te konwersje, zwłaszcza w programowaniu i projektowaniu stron internetowych, gdzie często pracuje się z wartościami szesnastkowymi.

Pytanie 12

Jakie jest zastosowanie języka XAML przy tworzeniu aplikacji desktopowych?

A. Do optymalizacji działania aplikacji
B. Do projektowania graficznego interfejsu użytkownika
C. Do obsługi zdarzeń klawiatury
D. Do zarządzania bazami danych
XAML (Extensible Application Markup Language) to język znaczników wykorzystywany w technologii WPF (Windows Presentation Foundation) oraz UWP (Universal Windows Platform) do projektowania graficznego interfejsu użytkownika (GUI). XAML pozwala na definiowanie układów, przycisków, etykiet oraz innych elementów interaktywnych w aplikacjach desktopowych. Dzięki XAML, projektowanie interfejsu jest intuicyjne, a kod interfejsu jest oddzielony od logiki aplikacji, co sprzyja przejrzystości projektu. XAML wspiera animacje, style i szablony, co umożliwia budowę nowoczesnych, dynamicznych aplikacji. Jego elastyczność i możliwość współpracy z C# sprawiają, że XAML jest niezastąpiony w środowisku Windows.

Pytanie 13

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 2
C. Deklaracji 3
D. Deklaracji 1
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 14

Rozpoczęcie tworzenia procedury składowej o nazwie dodajUsera w MS SQL wymaga użycia poleceń

A. add procedure dodajUsera
B. add dodajUsera procedure
C. create procedure dodajUsera
D. create dodajUsera procedure
Polecenie 'create procedure dodajUsera' to właśnie ten sposób, w jaki w Microsoft SQL Server deklaruje się początek nowej procedury składowanej. Wynika to bezpośrednio ze składni T-SQL, gdzie słowo 'create' inicjuje tworzenie nowego obiektu w bazie danych, a 'procedure' określa typ obiektu – procedurę składowaną. Dalej podaje się nazwę, tu akurat 'dodajUsera'. Moim zdaniem, to jedno z podstawowych, ale i najważniejszych poleceń dla każdego, kto chce serio pracować z SQL Serverem, bo bez zrozumienia tej składni bardzo szybko można się pogubić nawet przy prostych operacjach. T-SQL od lat nie zmienia tej konwencji i to jest bardzo wygodne – można śmiało korzystać z tutoriali czy dokumentacji sprzed kilku wersji serwera, bo tu akurat niewiele się zmienia. Przykład praktyczny: gdybyś chciał dodać prostą procedurę, która wstawia użytkownika do tabeli, zacząłbyś właśnie tak: 'create procedure dodajUsera AS BEGIN --tutaj kod END'. Warto wiedzieć, że dobrym zwyczajem jest zawsze nazywać procedury zgodnie z tym, co robią, a nie jakoś przypadkowo, i też często dodawać prefix, np. 'usp_' (od 'user stored procedure'), żeby potem łatwo było je odróżnić od funkcji czy triggerów. Przy dużym projekcie pozwala to zachować porządek. No i nie można zapominać o wersjonowaniu takich procedur – w firmach często stosuje się repozytoria kodu SQL. Generalnie, w środowisku produkcyjnym, każda nowa procedura powinna zaczynać się właśnie od 'create procedure', bez żadnych skrótów czy zamienników.

Pytanie 15

Jakie jest zastosowanie iteratora w zbiorach?

A. Do usuwania elementów ze zbioru
B. Do iterowania po elementach zbioru
C. Do generowania kopii zbiorów
D. Do zmiany rodzaju zbioru w trakcie działania aplikacji
Iterator w kolekcjach umożliwia przechodzenie przez elementy kolekcji w określonym porządku. Jest to abstrakcyjny obiekt, który pozwala na iterowanie po różnych strukturach danych, takich jak listy, wektory czy zbiory, bez konieczności znajomości ich wewnętrznej implementacji. Iteratory umożliwiają wykonywanie operacji na elementach kolekcji, takich jak odczyt, modyfikacja lub usuwanie, co czyni je niezwykle użytecznymi w programowaniu obiektowym. Dzięki iteratorom kod staje się bardziej czytelny i mniej podatny na błędy.

Pytanie 16

Jakie elementy zostaną wyświetlone w przeglądarce po wykonaniu kodu źródłowego stworzonego za pomocą dwóch funkcjonalnie równoważnych fragmentów? KOD W ANGULAR:

tags: string[] = ['tag1', 'tag2', 'tag3' ];
// ...
<p *ngFor="let tag of tags"> {{tag}} </p>
KOD W REACT.JS:
state = {   tags: ['tag1', 'tag2', 'tag3']   };
// ...   /* w instrukcji return metody render */
<React.Fragment>
  { this.state.tags.map(tag => <p key={tag}>{tag}</p>) }
</React.Fragment>
A. Trzy paragrafy, każdy odpowiadający kolejnemu elementowi tablicy tags.
B. Jeden paragraf z pierwszym elementem tablicy tags.
C. Trzy paragrafy, w każdym z nich tekst o treści: {tag}.
D. Jeden paragraf zawierający wszystkie elementy tablicy tags w kolejności.
Kod generuje trzy paragrafy, każdy z kolejnym elementem tablicy tags. Jest to standardowy sposób iteracji po elementach tablicy i renderowania ich jako oddzielnych elementów HTML. W praktyce, takie podejście jest szeroko stosowane w aplikacjach frontendowych, gdzie dynamicznie tworzone elementy interfejsu użytkownika są generowane na podstawie tablic lub list danych. Każdy element tablicy jest iterowany i osobno przekształcany w znacznik HTML, co pozwala na łatwe zarządzanie i aktualizowanie treści strony w czasie rzeczywistym. To podejście jest zgodne z najlepszymi praktykami dotyczącymi manipulacji DOM i zapewnia wysoką wydajność aplikacji.

Pytanie 17

Który z dokumentów stosowanych w metodologii Agile zawiera listę funkcjonalności produktu uporządkowanych według ich ważności?

A. Diagram Gantta
B. Product backlog
C. Harmonogram projektu
D. Backlog sprintu
Backlog sprintu zawiera jedynie zadania przypisane do aktualnego sprintu i jest podzbiorem całego backlogu produktu, co oznacza, że nie zawiera całości funkcjonalności. Diagram Gantta to narzędzie do planowania harmonogramu projektów, ale nie służy do zarządzania wymaganiami czy funkcjonalnościami produktu. Harmonogram projektu określa czas realizacji poszczególnych etapów, ale nie odnosi się do listy funkcji, jakie muszą zostać wdrożone, co jest celem backlogu.

Pytanie 18

Algorytm przedstawiony powyżej może zostać zaimplementowany w języku Java z wykorzystaniem instrukcji:

Ilustracja do pytania
A. if
B. try
C. while
D. switch
Instrukcja 'switch' to coś, co służy do wyboru pomiędzy kilkoma opcjami, więc nie da się jej użyć do powtarzania czegoś. 'if' to z kolei taki sposób na sprawdzenie warunku raz, a 'try' to konstrukcja do obsługi wyjątków, a nie do pętli. Chociaż 'if' może czasem być używane w bardziej złożonych pętlach, to nie jest to jego główna rola.

Pytanie 19

Prezentowana metoda jest realizacją algorytmu

public static String fun1(String str) {
    String output = " ";
    for (var i = (str.length()-1); i >= 0; i--)
        output += str.charAt(i);
    return output;
}
A. sortującego ciąg od znaku o najniższym kodzie ASCII do znaku o najwyższym kodzie
B. wyszukującego literę w ciągu
C. sprawdzającego, czy dany ciąg jest palindromem
D. odwracającego ciąg
Kod przedstawiony w zadaniu nie realizuje ani wyszukiwania konkretnej litery w ciągu, ani nie sprawdza, czy tekst jest palindromem, ani też nie sortuje znaków po kodzie ASCII. Często spotyka się mylenie tych koncepcji z prostym odwracaniem tekstu, bo wszystkie operacje dotyczą łańcuchów znaków, jednak ich logika jest zupełnie inna. Przykładowo, sprawdzanie palindromu najczęściej polega na porównywaniu znaków od początku i końca tekstu, aż do środka – nie wymaga to budowania nowego odwróconego tekstu, tylko ew. jednej pętli z warunkami. Jeśli chodzi o wyszukiwanie litery, tam szukamy, czy dany znak występuje w ciągu – sprawdza się to za pomocą pętli i instrukcji warunkowej, ale nie tworzy się nowego łańcucha, tylko ewentualnie zwraca pozycję znaku lub informację o jego obecności. Sortowanie znaków w napisie według kodu ASCII wymagałoby innego podejścia – należałoby przenieść znaki do np. tablicy znaków, użyć algorytmu sortowania (chociażby Arrays.sort()), a potem złożyć łańcuch z posortowanych znaków. W tym kodzie nie ma żadnych operacji porównywania kodów znaków ani przestawiania ich miejscami zgodnie z wartościami ASCII. Typowym błędem jest też sugerowanie się samą obecnością pętli i manipulacji na Stringu bez dokładnego prześledzenia, co dzieje się w każdej iteracji. Metoda fun1 po prostu dokleja kolejne znaki od końca oryginalnego napisu do nowego łańcucha, co wyraźnie wskazuje na typowo szkolny algorytm odwracania ciągu. To podejście jest bardzo przydatne do nauki podstaw przetwarzania tekstów i zrozumienia, jak można budować nowe napisy na bazie istniejących danych, ale nie spełnia żadnej z wymienionych innych funkcjonalności.

Pytanie 20

Która technologia służy do tworzenia responsywnych stron internetowych?

A. Local Storage
B. REST API
C. WebSockets
D. Media Queries w CSS
WebSockets to technologia, która służy do nawiązywania trwałej komunikacji między klientem a serwerem w czasie rzeczywistym, co jest szczególnie użyteczne w aplikacjach wymagających natychmiastowej wymiany danych, takich jak czaty czy gry online. Choć WebSockets umożliwiają dynamiczną interakcję, nie mają zastosowania w kontekście responsywności stron internetowych, ponieważ nie dotyczą one renderowania i dostosowywania treści do różnych rozmiarów ekranów. REST API to z kolei architektura służąca do tworzenia interfejsów programistycznych, która pozwala aplikacjom na komunikację ze sobą, ale także nie wpływa na responsywność stron. REST API jest używane głównie do wymiany danych między serwerami a aplikacjami, a nie do stylizacji i układu elementów na stronie. Local Storage to technologia pozwalająca na przechowywanie danych w przeglądarkach, co może wspierać funkcjonalność aplikacji webowych, ale również nie ma bezpośredniego związku z tworzeniem responsywnych interfejsów. Typowym błędem w myśleniu o responsywności jest mylenie technologii służących do przetwarzania danych z tymi, które są odpowiedzialne za prezentację i układ na stronie. Kluczem do efektywnego projektowania responsywnego jest zrozumienie potrzeby dostosowywania stylów CSS w zależności od urządzenia, a nie jedynie komunikacja czy przechowywanie informacji.

Pytanie 21

Jakie znaczenie ma framework w kontekście programowania?

A. Moduł do zarządzania systemami baz danych
B. Program do graficznego projektowania interfejsów użytkownika
C. System operacyjny, który umożliwia uruchamianie aplikacji
D. Zbiór gotowych bibliotek, narzędzi i zasad ułatwiających tworzenie aplikacji
Framework to zbiór gotowych bibliotek, narzędzi i reguł, które wspierają tworzenie aplikacji poprzez dostarczanie struktury ułatwiającej pracę programistów. Frameworki definiują standardowe komponenty aplikacji, umożliwiając programistom skoncentrowanie się na logice biznesowej zamiast na podstawowej architekturze aplikacji. Przykłady popularnych frameworków to .NET, Angular, Django i Spring. Frameworki przyspieszają proces programowania, poprawiają jakość kodu i wspierają skalowalność aplikacji, co czyni je nieodłącznym elementem nowoczesnego programowania.

Pytanie 22

Jakie elementy powinny być ujęte w dokumentacji programu?

A. Strategia marketingowa aplikacji
B. Szczegóły dotyczące konfiguracji serwera
C. Opis funkcji, klas i zmiennych w kodzie
D. Zestawienie błędów zidentyfikowanych w trakcie testów
Lista błędów wykrytych podczas testów stanowi część raportu testowego, a nie dokumentacji kodu. Choć jest istotna w procesie testowania i naprawy aplikacji, nie opisuje działania poszczególnych funkcji i klas. Plan marketingowy aplikacji to dokument dotyczący strategii promocyjnej i wdrożeniowej, ale nie zawiera informacji na temat kodu źródłowego ani jego implementacji. Szczegóły konfiguracji serwera dotyczą infrastruktury IT i wdrażania aplikacji w środowisku produkcyjnym, ale nie opisują bezpośrednio logiki i struktury kodu.

Pytanie 23

Co oznacza termin 'immutability' w programowaniu funkcyjnym?

A. Funkcje mogą być przypisywane do zmiennych
B. Kod może być wykonywany równolegle
C. Stan obiektu nie może być modyfikowany po jego utworzeniu
D. Obiekty są automatycznie usuwane z pamięci
W programowaniu istnieje wiele koncepcji, które mogą być mylone z ideą immutability, jednak żadna z pozostałych opcji nie oddaje jej istoty. Możliwość przypisywania funkcji do zmiennych, choć istotna w wielu językach programowania, nie ma bezpośredniego związku z immutability. To zjawisko jest bardziej związane z dynamicznymi właściwościami języków, które pozwalają na traktowanie funkcji jako obiektów pierwszej klasy. W przypadku równoległego wykonywania kodu, choć jest to ważna cecha programowania, nie można jej utożsamiać z niemodyfikowalnością obiektów. Równoległość i współbieżność są efektem zarządzania złożonymi procesami, ale sama możliwość modyfikacji stanu obiektów pozostaje niezależna. Ostatnia koncepcja, dotycząca automatycznego usuwania obiektów z pamięci, odnosi się do zarządzania pamięcią i mechanizmów takich jak garbage collection. To również nie jest związane z immutability, ponieważ nawet obiekty, które są automatycznie usuwane, mogą być modyfikowalne. Kluczowym błędem w rozumieniu immutability jest mylenie go z innymi cechami obiektów, co prowadzi do nieporozumień w implementacji i projektowaniu aplikacji. W praktyce, zrozumienie immutability jako koncepcji pozwala na lepsze zarządzanie stanem oraz redukcję liczby błędów związanych z równoległym przetwarzaniem danych.

Pytanie 24

Zaprezentowany symbol odnosi się do

Ilustracja do pytania
A. prawa cytatu
B. domeny publicznej
C. Creative Commons
D. praw autorskich
Wiele osób zaczyna od skojarzenia tego symbolu z prawami autorskimi, Creative Commons albo prawem cytatu, jednak to prowadzi na manowce. Po pierwsze, standardowy symbol praw autorskich to samo „C” w kółku, bez przekreślenia – i on oznacza, że utwór jest objęty ochroną z mocy prawa i wszelkie wykorzystanie wymaga zgody twórcy lub spełnienia warunków ustawowych wyjątków. Natomiast tutaj mamy przekreślone „C”, co jednoznacznie sugeruje brak ochrony. Creative Commons to zupełnie inny zestaw symboli, z typowymi oznaczeniami: CC i różnymi dodatkami jak BY, SA, NC, ND, które precyzują warunki korzystania z utworu. Te licencje nadal wprowadzają ograniczenia, chociaż są dużo bardziej elastyczne niż klasyczne prawa autorskie – ale nigdy nie oznaczają całkowitego braku praw. Prawo cytatu z kolei to wyjątek w ustawie o prawie autorskim, który pozwala na ograniczone wykorzystywanie fragmentów cudzych utworów w określonych sytuacjach, ale nie oznacza, że cały utwór można wykorzystywać dowolnie i bez ograniczeń. Typowy błąd polega na utożsamianiu każdego oznaczenia związanych z literą C z szeroko rozumianą „wolnością” korzystania – a to nieprawda. Domena publiczna jest zupełnie oddzielną kategorią, gdzie utwór jest trwale wyjęty spod ochrony prawnej i można go używać naprawdę dowolnie. W praktyce, nieznajomość tych niuansów może prowadzić do błędów prawnych, np. nieświadomego naruszenia czyichś praw, albo niewłaściwego oznaczenia własnej pracy. W środowisku profesjonalnym bardzo ważne jest właśnie rozróżnianie tych pojęć i symboli – to wpływa na bezpieczeństwo prawne projektów i buduje zaufanie do twórcy.

Pytanie 25

Jakie z przedstawionych rozwiązań może pomóc w unikaniu porażeń prądem w biurze?

A. Wykorzystanie foteli o ergonomicznym kształcie
B. Stosowanie monitorów LCD
C. Systematyczne sprawdzanie instalacji elektrycznych
D. Kontrolowanie jakości powietrza
Regularne testowanie instalacji elektrycznych to podstawowy sposób zapobiegania porażeniom prądem w pracy biurowej. Testy te pozwalają wykryć uszkodzenia, przeciążenia i inne usterki, które mogą stanowić zagrożenie dla pracowników. Prawidłowo przeprowadzane przeglądy techniczne obejmują sprawdzanie stanu przewodów, gniazdek oraz urządzeń elektrycznych. Regularne kontrole zgodne z normami BHP oraz przepisami dotyczącymi instalacji elektrycznych są obowiązkowe i mają kluczowe znaczenie dla bezpieczeństwa pracy. Pamiętaj, że zaniedbanie testów elektrycznych może prowadzić do poważnych wypadków, takich jak pożary lub porażenia prądem.

Pytanie 26

Jakie kroki należy podjąć, aby skutecznie zabezpieczyć dane na komputerze?

A. Dzielić się hasłami do plików z współpracownikami
B. Przechowywać dane na niezabezpieczonych nośnikach przenośnych
C. Systematycznie aktualizować oprogramowanie i wykonywać kopie zapasowe
D. Nie używać kopii zapasowych
Brak tworzenia kopii zapasowych naraża dane na całkowitą utratę w przypadku awarii systemu lub ataku złośliwego oprogramowania. Przechowywanie danych na niezaszyfrowanych urządzeniach przenośnych stwarza ryzyko ich kradzieży i nieautoryzowanego dostępu. Udostępnianie haseł do plików współpracownikom stanowi poważne naruszenie zasad bezpieczeństwa, prowadząc do zwiększonego ryzyka wycieku danych lub ich nieuprawnionej modyfikacji.

Pytanie 27

Jakie mogą być konsekwencje długotrwałego narażenia na hałas w pracy?

A. Obniżenie ostrości wzroku
B. Uszkodzenie słuchu i zmęczenie
C. Wzrost efektywności pracy
D. Choroby skórne
Długotrwały hałas w miejscu pracy może prowadzić do poważnych konsekwencji zdrowotnych, takich jak uszkodzenie słuchu oraz przewlekłe zmęczenie. Stała ekspozycja na hałas o wysokim natężeniu może powodować stopniową utratę słuchu, szumy uszne, a także zwiększać poziom stresu i obniżać koncentrację. Zmęczenie wynikające z hałasu wpływa negatywnie na produktywność i samopoczucie pracowników, prowadząc do spadku efektywności oraz wzrostu ryzyka popełniania błędów. W celu ochrony przed hałasem zaleca się stosowanie środków ochrony indywidualnej, takich jak nauszniki lub zatyczki do uszu, a także instalowanie ekranów dźwiękochłonnych i ograniczenie źródeł hałasu w środowisku pracy.

Pytanie 28

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

private void Button_click(object sender, routedEventArgs e) {
    int tmp = 0;
    for (int i=0; i<=100; i+=2) {
        tmp += i;
    }
    label.Content = tmp;
}
A. liczby z przedziału od 0 do 100
B. suma liczb parzystych z przedziału od 0 do 100
C. liczby parzyste z przedziału od 0 do 100
D. suma liczb z przedziału od 0 do 100
Wiele osób podczas analizy takich pytań może się zagubić, patrząc tylko pobieżnie na kod. Na przykład, ktoś mógłby pomyśleć, że wynik działania pętli for to po prostu zestaw liczb parzystych z przedziału 0–100, ale to nieprawda – kod nie wyświetla, ani nie zbiera tych liczb do żadnej kolekcji. Zamiast tego każda wartość jest sumowana do jednej zmiennej tmp, co jest dość typowym zabiegiem w programowaniu – chodzi o tzw. akumulację. Kolejna pułapka to założenie, że kod sumuje wszystkie liczby z przedziału 0–100. Gdyby tak było, inkrementacja w pętli powinna wyglądać inaczej (i++ zamiast i+=2) i wtedy rzeczywiście tmp zebrałby całą sekwencję naturalną do 100. Niektórzy mogą jeszcze sądzić, że etykieta label ma przyjąć wartości poszczególnych liczb (czyli np. wyświetlić wszystkie parzyste z zakresu), ale w rzeczywistości przypisujemy jej tylko końcowy wynik sumowania, a nie całą listę. W praktyce takie błędne rozumienie wynika czasem z tego, że nie do końca zwracamy uwagę na składnię pętli oraz na to, co tak naprawdę się dzieje w ciele tej pętli. Z mojego doświadczenia wynika, że kluczem jest tu zrozumienie, jak działa inkrementacja i jak sumujemy wartości – nie każda pętla oznacza przetwarzanie wszystkich możliwych liczb. Kod ten jest dość czytelny, ale łatwo się pomylić, jeśli pobieżnie spojrzymy na zapis for (int i=0; i<=100; i+=2). Warto więc zawsze przeanalizować dokładnie warunki pętli oraz operacje wykonywane na zmiennych w jej wnętrzu. To, co tu robimy, to klasyczna suma liczb spełniających konkretny warunek – i to jest bardzo częsty motyw w zadaniach programistycznych, także na rozmowach kwalifikacyjnych czy sprawdzianach. Praktyka pokazuje, że precyzja w analizie kodu jest dużo ważniejsza niż szybkie czytanie treści.

Pytanie 29

Jakie składniki powinien mieć plan projektu?

A. Tylko czas wykonania i budżet
B. Terminy i zasoby ludzkie
C. Wyłącznie etapy projektu
D. Etapy projektu, ramy czasowe, zasoby i zadania
Zawieranie jedynie etapów projektu bez ram czasowych i zasobów nie dostarcza pełnej informacji o harmonogramie i może prowadzić do dezorganizacji. Uwzględnianie tylko czasu realizacji i budżetu pomija kluczowe aspekty związane z zasobami ludzkimi i podziałem zadań. Skupienie się wyłącznie na ramie czasowej, bez definiowania konkretnych etapów i zadań, sprawia, że harmonogram jest niekompletny i trudny do monitorowania.

Pytanie 30

Co zostanie wyświetlone po wykonaniu poniższego kodu w języku Python?

data = [1, 2, 3, 4, 5]
result = list(map(lambda x: x*2, filter(lambda x: x % 2 == 0, data)))
print(result)
A. [4, 8]
B. [2, 4, 6, 8, 10]
C. [1, 2, 3, 4, 5]
D. [2, 6, 10]
Analizując inne odpowiedzi, możemy zauważyć, że wszystkie one bazują na błędnych założeniach dotyczących działania funkcji filter i map. Niektóre z propozycji, takie jak [2, 6, 10], sugerują, że wszystkie liczby parzyste z oryginalnej listy byłyby mnożone przez 2, co jest nieprawidłowe. Funkcja filter zwraca jedynie liczby parzyste, a to oznacza, że tylko liczby 2 i 4 są brane pod uwagę, nie 6 i 10, których w oryginalnej liście po prostu nie ma. Ponadto odpowiedź [2, 4, 6, 8, 10] jest błędna, ponieważ dodaje liczby, które nie występują w danych wejściowych, co prowadzi do nieprecyzyjnego wyniku. Warto zrozumieć, że w Pythonie operacje na kolekcjach są często wykonywane w sposób, który wymaga precyzyjnej analizy danych wejściowych. W kontekście programowania, często popełnianym błędem jest zakładanie, że wszystkie liczby pasujące do jakiegoś warunku będą uwzględniane w dalszej obróbce bez dokładnego ich filtrowania. Stąd wynika, że zrozumienie, jak działają funkcje takie jak filter i map, jest kluczowe dla efektywnego i poprawnego programowania. W procesie nauki ważne jest, aby przyglądać się działaniu kodu krok po kroku i dokładnie analizować, jak funkcje przetwarzają dane. Zrozumienie tych podstawowych koncepcji jest niezbędne, aby uniknąć podobnych nieporozumień w przyszłości.

Pytanie 31

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. Wyłącznie jeden element o treści Harry Potter, Hobbit, Władca pierścieni.
B. Taką liczbę elementów, ile znajduje się w tablicy books; w każdym punkcie listy umieszczony jest jeden element tablicy.
C. Tyle elementów, ile znajduje się w tablicy books; w każdym punkcie listy widnieje element o treści {book}.
D. Jedynie jeden element o treści Harry Potter.
Dokładnie tak właśnie działa iteracja po tablicy w Angularze i React.js. Zarówno Angularowy *ngFor, jak i funkcja map() w Reactcie to narzędzia do dynamicznego generowania elementów listy na podstawie danych z tablicy – w tym przypadku books. Każdy element tablicy tworzy osobny <li>, a więc liczba elementów na stronie zawsze odpowiada długości tablicy. To jest bardzo praktyczne, bo pozwala wyświetlać listy o dowolnej długości, zależnie od zawartości danych, bez przepisywania kodu – wystarczy zmienić dane źródłowe. W Angularze taki sposób budowania widoków jest zgodny z podejściem deklaratywnym – opisujesz, co ma się pojawić, a nie jak dokładnie to zrobić krok po kroku. React „mapuje” dane na elementy JSX, przy okazji warto pamiętać o kluczach (key), bo to pomaga w optymalizacji pracy wirtualnego DOM-u. Takie podejście to dzisiaj absolutny standard w branży – ułatwia utrzymanie kodu, testy i reużywalność komponentów. Moim zdaniem, kiedy raz się to opanuje, ciężko wyobrazić sobie inne podejście do budowy dynamicznych interfejsów. Zauważ, że każdy <li> wyświetla dokładny tekst z tablicy, a nie jakieś szablony czy placeholdery – to bardzo czytelne i naturalne dla użytkownika. W realnych projektach często tak renderuje się np. listy produktów, komentarzy czy zadań do wykonania. Dodatkowo, jeśli zmodyfikujesz tablicę, to widok automatycznie się odświeży – nie musisz ręcznie aktualizować DOM. To ogromne ułatwienie i podstawa nowoczesnego frontendu.

Pytanie 32

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

A. zadeklarować zmienną sprawdz przed jej wykorzystaniem w linii 11
B. naprawić błąd w funkcji sprawdz, który polega na braku nawiasów {} w pętli for
C. dodać deklarację funkcji sprawdz przed funkcją main
D. poprawnie zapisać warunek w instrukcji if w linii 11, np. sprawdz(x)==true
Odpowiedź jest trafna, bo w języku C++ kompilator musi wiedzieć o istnieniu funkcji zanim zostanie ona użyta w kodzie, np. w funkcji main. Bez wcześniejszej deklaracji, kompilator nie zna sygnatury funkcji i nie potrafi zweryfikować wywołania, co skutkuje błędem typu 'implicit declaration of function'. Deklaracja funkcji to taki sygnał informujący kompilator „hej, taka funkcja będzie i będzie przyjmować takie argumenty, a zwracać taki typ”. Praktycznie rzecz biorąc, przed funkcją main wystarczy wpisać np. 'bool sprawdz(int x);', żeby wszystko grało. To szczególnie ważne przy większych projektach czy pracy w zespołach, gdzie pliki nagłówkowe z deklaracjami funkcji są standardem. Pozwala to na lepszą czytelność i porządek w kodzie – kompilator wie, czego się spodziewać, a Ty unikasz dziwnych, trudnych do znalezienia błędów. Moim zdaniem taka organizacja kodu to podstawa, szczególnie jeśli kiedyś będziesz korzystać z bibliotek lub cudzych funkcji – deklaracje są wtedy wręcz obowiązkowe. To zasada, której trzyma się większość zespołów programistycznych i, szczerze mówiąc, sam kilka razy w młodości zapomniałem o deklaracji, przez co debugowanie trwało wieki. Warto od razu wyrobić sobie taki nawyk, bo to oszczędza sporo nerwów i czasu, a kod staje się solidniejszy i bardziej profesjonalny.

Pytanie 33

Co należy zrobić w sytuacji silnego krwawienia z rany?

A. Przepłukać ranę wodą utlenioną i zostawić do wyschnięcia
B. Poczekać, aż krwawienie ustanie samoistnie
C. Założyć opatrunek uciskowy oraz unieść kończynę powyżej poziomu serca
D. Nałożyć elastyczny bandaż bez ucisku
Przemycie rany wodą utlenioną i pozostawienie jej do wyschnięcia jest odpowiednie dla drobnych skaleczeń, ale nie skuteczne przy silnym krwotoku, ponieważ nie zatrzymuje aktywnego krwawienia. Nałożenie bandaża elastycznego bez ucisku może być pomocne w przypadku obrzęków, ale nie zapobiega utracie krwi. Czekanie na samoistne ustanie krwawienia to błąd, który może prowadzić do poważnych konsekwencji zdrowotnych, w tym wstrząsu hipowolemicznego i śmierci z powodu nadmiernej utraty krwi.

Pytanie 34

Które z poniższych nie jest narzędziem do zarządzania stanem w aplikacjach React?

A. Redux
B. Webpack
C. MobX
D. Context API
Webpack to narzędzie do budowania, które służy do zarządzania zasobami w projekcie, a nie do zarządzania stanem aplikacji. Jego głównym celem jest przekształcanie i optymalizacja plików, takich jak JavaScript, CSS czy obrazy, przed ich wdrożeniem na produkcję. Dzięki Webpackowi można tworzyć modułowe aplikacje, które pozwalają na łatwe zarządzanie zależnościami. Przykładem użycia Webpacka może być skonfigurowanie go do kompresji plików JavaScript oraz CSS w celu zwiększenia wydajności aplikacji. W praktyce, Webpack jest szeroko stosowany w projektach React, aby efektywnie łączyć i optymalizować kod z różnych źródeł, co przekłada się na szybsze ładowanie się aplikacji. Standardy dotyczące zarządzania projektami przewidują, że narzędzia do budowania, takie jak Webpack, powinny być odpowiednio skonfigurowane w celu zapewnienia najlepszych praktyk dotyczących wydajności i organizacji kodu.

Pytanie 35

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

A. Opracowywanie interfejsu graficznego
B. Projektowanie bazy danych
C. Kompilowanie aplikacji
D. Debugowanie kodu w celu znalezienia błędów
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 36

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

def fun(x, l=[]):
    l.append(x)
    return l

print(fun(1))
print(fun(2))
print(fun(3, []))
print(fun(4))
A. [1], [2], [3], [4]
B. [1], [1, 2], [3], [1, 2, 4]
C. [1], [2], [3], [4, 3]
D. [1], [1, 2], [3], [3, 4]
Wynik działania tego kodu jest poprawny i wynika z zrozumienia, jak Python obsługuje domyślne argumenty funkcji. W momencie, gdy funkcja 'fun' jest wywoływana po raz pierwszy z argumentem 1, lista 'l' jest pusta i dodawany jest do niej element 1, co skutkuje wynikiem [1]. Przy kolejnym wywołaniu z argumentem 2, lista 'l' nie jest tworzona na nowo, a zamiast tego używane jest to samo odniesienie do istniejącej listy, co oznacza, że 2 zostaje dodane do listy, przekształcając ją w [1, 2]. W trzecim wywołaniu funkcji, przekazujemy nową, pustą listę, więc wynik to [3]. Kiedy po raz czwarty wywołujemy funkcję z argumentem 4, znowu używamy tej samej listy, do której dodano już 1 i 2, co daje nam wynik [1, 2, 4]. Kluczowe jest zrozumienie, że domyślne argumenty w Pythonie są tworzone raz, więc nie są resetowane przy kolejnych wywołaniach funkcji. Takie zarządzanie pamięcią w Pythonie jest zgodne z dobrymi praktykami programistycznymi oraz pozwala na efektywne użycie zasobów.

Pytanie 37

Jakiego kodu dotyczy treść wygenerowana w trakcie działania programu Java?

Ilustracja do pytania
A. Kodu 2
B. Kodu 4
C. Kodu 3
D. Kodu 1
Zrozumienie typowych błędów jakie mogą wystąpić w kodzie jest kluczowe dla właściwego programowania. Analizując błędne opcje zaczniemy od kodu 1 gdzie zmienna x jest przypisana wartością zero. Samo przypisanie wartości zero do zmiennej nie powoduje żadnego wyjątku arytmetycznego w Javie ponieważ nie zachodzi tutaj żadna operacja matematyczna która mogłaby prowadzić do wyjątku. W przypadku kodu 2 widzimy próbę dostępu do elementu tablicy o indeksie 6. Taki kod może prowadzić do ArrayIndexOutOfBoundsException jeśli tablica nie ma co najmniej siedmiu elementów ale nie jest to wyjątek arytmetyczny który wskazuje na dzielenie przez zero. Przykład kodu 3 zawiera instrukcję warunkową if porównującą zmienne x i y. Tego typu operacje są bezpieczne i nie prowadzą do wyjątków arytmetycznych ponieważ nie wykonują podziału ani innych operacji które mogłyby spowodować błędy matematyczne. Często spotykanym błędem jest zakładanie że każda operacja matematyczna musi powodować wyjątek jednak w rzeczywistości problem pojawia się tylko kiedy wystąpi specyficzna nieprawidłowość jak w przypadku dzielenia przez zero. Rozumienie tych subtelności jest kluczowe w tworzeniu poprawnego kodu w języku Java i jest niezbędnym elementem wiedzy każdego programisty. Poprawna obsługa wyjątków pozwala stworzyć bardziej stabilne i niezawodne aplikacje co jest jednym z fundamentów profesjonalnego programowania. Warto zawsze weryfikować kod pod kątem potencjalnych błędów logicznych i syntaktycznych co zwiększa jego jakość i bezpieczeństwo działania.

Pytanie 38

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

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

Pytanie 39

Zaznaczone elementy w przedstawionych obramowaniach mają na celu:
Fragment kodu w WPF/XAML:

<Windows Title="Tekst"...>
Fragment kodu w Java:
public class Okno extends JFrame {
    ...
    public Okno() {
        super();
        this.setTitle("Tekst");
    }
    ...
A. przypisanie nazwy obiektu obrazującego okno aplikacji
B. uzyskanie nazwy obiektu obrazującego okno aplikacji
C. zapisanie tytułu okna do obiektu Tekst
D. ustawienie tytułu okna na "Tekst"
Odpowiadając na to pytanie, łatwo pomylić pojęcia związane z nazwą obiektu a tytułem okna aplikacji. Fragmenty kodu, które są tu pokazane, nie mają nic wspólnego z uzyskaniem czy przypisaniem nazwy obiektu programistycznego – chodzi wyłącznie o to, co użytkownik zobaczy na pasku tytułu okna po uruchomieniu programu. W językach takich jak Java, nazwa obiektu (np. instancji JFrame) to coś, co ustalamy we własnym kodzie i nie jest to tożsame z tym, co widać na ekranie. W przypadku XAML, a konkretnie atrybutów jak Title, nie przypisujemy żadnej nazwy programistycznej, lecz tylko wyświetlany tekst. Innym błędem jest sądzenie, że kod zapisuje tytuł do obiektu o nazwie „Tekst” – nie ma tu żadnej referencji do obiektu o tej nazwie; to po prostu wartość tekstowa, która będzie widoczna dla użytkownika. Takie błędne rozumowanie często wynika z mylenia pojęć 'nazwa obiektu' i 'wyświetlany tytuł', co niestety bywa źródłem nieporozumień na egzaminach. W praktyce, operując na GUI, tytuł okna nadajemy, żeby użytkownik rozpoznawał aplikację lub jej aktualny stan, a nie po to, żeby zarządzać obiektami w kodzie. Jest to raczej kwestia interfejsu użytkownika, nie stricte struktury programu. Z punktu widzenia dobrych praktyk, ważne jest, żeby pamiętać o tym rozróżnieniu i nie traktować tekstów wyświetlanych użytkownikowi jako nazw czy zmiennych w kodzie. Takie myślenie może prowadzić do niejasności i błędów, zwłaszcza przy rozbudowanych aplikacjach okienkowych, gdzie zarządzanie nazwami obiektów i elementami interfejsu powinno być jasno rozdzielone.

Pytanie 40

Która z operacji logicznych zwróci wartość "true", gdy obie zmienne są sobie równe?

A. x || y
B. x == y
C. x && y
D. x != y
Operator `x && y` to operator logiczny `AND`, który zwraca `true` tylko wtedy, gdy zarówno `x`, jak i `y` są prawdziwe (różne od zera). Operator `x || y` to operator `OR`, który zwraca `true`, jeśli przynajmniej jedna z wartości jest prawdziwa. Operator `x != y` to operator nierówności, który zwraca `true`, jeśli wartości `x` i `y` są różne. Żaden z tych operatorów nie służy do porównywania równości dwóch wartości w taki sposób jak `==`.