Wyniki egzaminu

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

Egzamin niezdany

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

Wymagane minimum: 20 punktów (50%)

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

W jakiej fazie cyklu życia projektu informatycznego następuje integracja oraz testowanie wszystkich modułów systemu?

A. Faza wdrożenia
B. Etap implementacji
C. Etap planowania
D. Faza analizy
Planowanie to faza początkowa, w której określane są cele projektu, harmonogram i zasoby, ale nie jest to etap integracji systemu. Analiza skupia się na zbieraniu wymagań i definiowaniu specyfikacji technicznej, ale nie obejmuje łączenia modułów ani testowania gotowego produktu. Wdrożenie to końcowy etap cyklu życia projektu, który następuje po pełnej integracji i testowaniu – polega na uruchomieniu systemu w środowisku produkcyjnym i udostępnieniu go użytkownikom końcowym.

Pytanie 2

Co oznacza pojęcie TDD w kontekście programowania?

A. Test-Driven Development - praktyka pisania testów przed implementacją kodu
B. Type Definition Document - dokumentacja typów danych w aplikacji
C. Task Deployment Diagram - schemat wdrażania zadań w projekcie
D. Technical Design Document - dokumentacja techniczna projektu
Pojęcia takie jak Type Definition Document, Technical Design Document, czy Task Deployment Diagram są związane z dokumentacją i zarządzaniem projektami, a niekoniecznie z samym procesem programowania, jakim jest TDD. Type Definition Document odnosi się do szczegółowego opisu typów danych używanych w aplikacji, co jest ważne, ale nie wpływa na proces tworzenia kodu i testowania. Z kolei Technical Design Document to dokument, który opisuje architekturę i techniczne aspekty projektu, ale nie stanowi podstawy dla praktyki TDD, w której testy są kluczowym elementem cyklu życia oprogramowania. Task Deployment Diagram to wizualizacja procesu wdrażania zadań w projekcie, co ma zastosowanie w zarządzaniu projektami, lecz nie odnosi się do samego wytwarzania oprogramowania. Takie nieporozumienia mogą wynikać z mylnego przekonania, że dokumentacja jest kluczowym elementem procesu programowania, co nie jest do końca prawdą. W rzeczywistości, TDD skupia się na iteracyjnym rozwoju poprzez testy, co prowadzi do lepszej jakości kodu, a jego podstawą jest koncepcja "testy przed kodem", a nie tworzenie dokumentacji czy schematów. Zrozumienie TDD jako podejścia programistycznego, które koncentruje się na testach, a nie na dokumentowaniu typu danych czy architektury, jest kluczowe dla właściwego podejścia do programowania w nowoczesnych projektach IT.

Pytanie 3

Jakie są różnice między konstruktorem a zwykłą metodą w klasie?

A. Konstruktor zawsze nosi tę samą nazwę co klasa i nie zwraca wartości
B. Konstruktor jest uruchamiany jedynie przez destruktor
C. Konstruktor powinien zwracać jakąś wartość
D. Konstruktor można wywołać bez konieczności tworzenia obiektu
Konstruktor nie zwraca wartości, w przeciwieństwie do zwykłych metod klasy, które mogą zwracać typy danych (`int`, `float`, `string`). Konstruktor nie może być wywoływany bez tworzenia obiektu – jest to mechanizm związany wyłącznie z procesem inicjalizacji obiektu. Destruktor, a nie konstruktor, jest wywoływany po zakończeniu życia obiektu w celu zwolnienia zasobów. Konstruktor jest pierwszą metodą, która działa podczas tworzenia obiektu, co odróżnia go od destruktora, który działa na końcu życia obiektu.

Pytanie 4

Jakiego rodzaju zmiennej użyjesz w C++, aby przechować wartość "true"?

A. bool
B. liczba całkowita
C. liczba zmiennoprzecinkowa
D. tekst
Typ danych 'bool' w języku C++ jest przeznaczony do przechowywania wartości 'true' lub 'false'. Deklaracja 'bool isReady = true;' to przykład poprawnego przypisania wartości logicznej do zmiennej. Typ boolean jest kluczowy w warunkach decyzyjnych, pętlach i operacjach porównawczych. W programowaniu typ 'bool' jest wykorzystywany do kontroli przepływu programu, obsługi wyjątków oraz sprawdzania poprawności danych. Użycie booleanów w kodzie zwiększa jego czytelność i pozwala na bardziej przejrzyste budowanie logiki aplikacji.

Pytanie 5

Jaką wartość będzie miała zmienna result po wykonaniu poniższego kodu PHP?

$array = [5, 1, 8, 3, 7];
$result = 0;
foreach ($array as $value) {
  if ($value > $result) {
    $result = $value;
  }
}
A. 24
B. 5
C. 7
D. 8
Wartości 24, 5 oraz 7 nie są poprawne w kontekście działania podanego kodu PHP. Gdy spojrzymy na odpowiedź 24, zauważymy, że nie ma takiej wartości w tablicy $array, która wynosi 5, 1, 8, 3 ani 7. Zatem, próbując uzyskać taką wartość z operacji na tych liczbach, prowadzi do złych wniosków. Możliwe, że błąd wynikał z niewłaściwego zrozumienia, czym jest proces iteracji w tablicy oraz jak działa przypisanie wartości. W przypadku wartości 5, można pomyśleć, że jest to największa liczba w tablicy, ponieważ jest to pierwsza liczba, która jest porównywana z wartością początkową zmiennej $result. Jednak nie uwzględnia ona kolejnych iteracji, które dostarczają większe wartości. Wartość 7, chociaż jest większa od 5, również nie jest największa, ponieważ istnieje jeszcze większa liczba - 8. W przypadku programowania, kluczowe jest zrozumienie, że pętla foreach nie tylko przegląda elementy, ale także pozwala na dynamiczne aktualizowanie zmiennej w zależności od warunku. Niezrozumienie tego aspektu może prowadzić do błędnych odpowiedzi, jak w tym przypadku, gdzie nie tylko nie dostrzegamy maksymalnej wartości, ale także nie rozumiemy poprawnych operacji na zmiennych. W programowaniu ważne jest, aby nie tylko znać składnię, ale także rozumieć logikę stojącą za danym algorytmem.

Pytanie 6

Na zaprezentowanych ilustracjach znajduje się okno aplikacji w wersji początkowej oraz po wprowadzeniu danych. Przyjmując, że pole "Dostępne środki" służy do wprowadzania wartości typu rzeczywistego, wskaż elementy struktury, które najlepiej odpowiadają tym danym?

Ilustracja do pytania
A. Kod 1
B. Kod 4
C. Kod 2
D. Kod 3
Struktury zawierające typy całkowite, takie jak int, nie są odpowiednie do przechowywania wartości pieniężnych lub zmiennoprzecinkowych, ponieważ tracą dokładność w przypadku wartości ułamkowych. Struktury oparte na typach string są przeznaczone do tekstu, a nie danych numerycznych. Użycie struktury tablicowej nie jest optymalne, gdyż wartości zmiennoprzecinkowe powinny być przechowywane jako pojedyncza zmienna, a nie w postaci listy.

Pytanie 7

Celem zastosowania wzorca Obserwator w tworzeniu aplikacji WEB jest

A. informowanie obiektów o modyfikacji stanu innych obiektów
B. dostosowanie interfejsu użytkownika do różnych typów odbiorców
C. monitorowanie interakcji użytkownika i wysyłanie wyjątków
D. zarządzanie funkcjami synchronicznymi w kodzie aplikacji
Wszystkie pozostałe odpowiedzi są błędne z kilku powodów. Dopasowanie interfejsu użytkownika do różnych typów użytkowników nie jest funkcją wzorca Obserwator, lecz bardziej związane jest z koncepcjami UX/UI (User Experience/User Interface) i personalizacją. Chociaż interfejs może korzystać z danych powiadomień od wzorca Obserwator, sam wzorzec nie zajmuje się dostosowywaniem interfejsu do preferencji użytkownika. Obserwowanie interakcji użytkownika i wysyłanie wyjątków również nie jest celem wzorca Obserwator. Takie działania zazwyczaj są obsługiwane przez mechanizmy zdarzeń lub kontrolery, które rejestrują interakcje, ale nie mają na celu bezpośredniego monitorowania i reagowania na zmiany stanu innych obiektów. Wreszcie, obsługa funkcji synchronicznych w kodzie aplikacji jest zupełnie inną kwestią, powiązaną z asynchronicznością, obiegiem zdarzeń i obiektami Promise, a nie z tym, co oferuje wzorzec Obserwator. Wzorzec ten nie ma na celu synchronizacji, a raczej dążenie do luźnego powiązania między obiektami, co jest kluczowe dla efektywnej i elastycznej architektury aplikacji.

Pytanie 8

Jaki rodzaj ataku hakerskiego polega na bombardowaniu serwera ogromną ilością żądań, co prowadzi do jego przeciążenia?

A. Man-in-the-Middle
B. Phishing
C. DDoS
D. SQL Injection
Atak DDoS (Distributed Denial of Service) polega na zasypywaniu serwera dużą ilością zapytań, co prowadzi do jego przeciążenia i unieruchomienia. W tym rodzaju ataku, hakerzy wykorzystują sieć skompromitowanych komputerów, znanych jako botnety, aby wysłać ogromne ilości nieautoryzowanych żądań do docelowego serwera w krótkim czasie. Celem DDoS jest spowodowanie, że serwer nie jest w stanie odpowiedzieć na prawidłowe zapytania od autentycznych użytkowników, co skutkuje awarią usługi. Przykłady ataków DDoS obejmują SYN Flood, UDP Flood oraz HTTP Flood, gdzie każdy z tych typów wykorzystuje różne protokoły i metody do zablokowania normalnego ruchu. Standardy takie jak RFC 793 definiują protokół TCP, który może być narażony na ataki SYN Flood. Ważne jest, aby organizacje stosowały odpowiednie środki zabezpieczające, takie jak systemy detekcji intruzów (IDS), firewalle, oraz usługi ochrony DDoS, aby minimalizować ryzyko i skutki tych ataków.

Pytanie 9

Jakie są różnice między kompilatorem a interpretem?

A. Interpreter konwertuje kod źródłowy na język maszynowy przed jego kompilacją
B. Kompilator przekształca kod źródłowy na język maszynowy przed uruchomieniem aplikacji
C. Kompilator przetwarza kod na język maszynowy w momencie jego wykonywania
D. Interpreter tworzy plik wykonywalny, który funkcjonuje niezależnie od otoczenia
Kompilator nie tłumaczy kodu w trakcie jego działania, bo to już zadanie interpretera. Interpreter przetwarza kod linijka po linijce podczas działania programu. Z tego powodu nie tworzy plików wykonywalnych, program po prostu działa w czasie rzeczywistym, a to sprawia, że działa wolniej. Mówiąc krótko, tłumaczenie kodu przed kompilacją to nie jest to, co się robi – kompilacja to proces, który tworzy plik wykonywalny z kodu źródłowego. Dlatego interpreter nie generuje żadnych niezależnych plików, tylko analizuje i wykonuje kod od razu.

Pytanie 10

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 2
B. kod 1
C. kod 4
D. kod 3
Wybrałeś fragment kodu, który faktycznie odwzorowuje logikę schematu blokowego: najpierw sprawdzamy warunek suma <= liczba, a dopiero gdy jest spełniony, wchodzimy do pętli, dodajemy i do zmiennej suma, inkrementujemy licznik i i wracamy do ponownego sprawdzenia warunku. To jest klasyczne zastosowanie pętli while, czyli sytuacji, kiedy nie znamy liczby iteracji z góry, ale wiemy, kiedy mamy skończyć – w tym wypadku, gdy suma przekroczy wartość graniczną liczba. Z mojego doświadczenia właśnie tak wygląda typowy fragment kodu sumujący kolejne liczby naturalne, dopóki nie zostanie osiągnięty limit. Ważne jest też to, że instrukcja wypisania wyniku znajduje się dopiero za pętlą, więc zostanie wykonana dokładnie raz, po zakończeniu obliczeń, co idealnie zgadza się z blokiem pisz suma na schemacie. W dobrych praktykach programistycznych zawsze pilnujemy, żeby warunek pętli dokładnie odpowiadał opisowi w algorytmie, a modyfikacja zmiennych sterujących, takich jak suma i i, była wykonywana wewnątrz pętli w spójny sposób. Taka konstrukcja jest potem łatwa w utrzymaniu, przeniesieniu do innych języków czy modyfikacji, na przykład można bez problemu zmienić warunek na suma < liczba albo dodać dodatkowe sprawdzenie, czy i nie rośnie za szybko. W praktycznych projektach, np. przy obliczaniu sum kontrolnych, limitów budżetowych, punktów gracza w grze, dokładnie taki wzorzec while warunek, obliczenia, inkrementacja, wypisz wynik pojawia się naprawdę często.

Pytanie 11

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

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

Pytanie 12

Jaką kategorię własności intelektualnej reprezentują znaki towarowe?

A. Własność przemysłowa
B. Autorskie prawa majątkowe
C. Prawa pokrewne
D. Dobra niematerialne
Znaki towarowe należą do kategorii własności przemysłowej. Ochrona znaków towarowych pozwala firmom na zabezpieczenie ich brandingu, logotypów oraz nazw produktów przed nieuprawnionym wykorzystaniem przez konkurencję. Rejestracja znaku towarowego daje właścicielowi prawo do wyłącznego używania go w celach komercyjnych i przeciwdziałania naruszeniom. Własność przemysłowa obejmuje także patenty, wzory przemysłowe i oznaczenia geograficzne, stanowiąc kluczowy element strategii ochrony marki oraz wartości firmy na rynku międzynarodowym.

Pytanie 13

Jaki jest podstawowy cel przystosowania aplikacji do publikacji w sklepie mobilnym?

A. Dostosowanie kodu aplikacji w celu zwiększenia jej wydajności
B. Dostosowanie aplikacji do wymogów platformy oraz regulacji sklepu
C. Zapewnienie, że aplikacja działa jedynie w trybie offline
D. Zmniejszenie rozmiaru aplikacji poniżej 10 MB
Dostosowanie aplikacji do wymagań platformy i przepisów sklepu mobilnego (np. Google Play lub App Store) to kluczowy krok w procesie publikacji aplikacji. Sklepy mobilne wymagają, aby aplikacje spełniały określone standardy dotyczące bezpieczeństwa, dostępności, wydajności oraz zgodności z wytycznymi interfejsu użytkownika. Proces ten obejmuje testowanie aplikacji pod kątem stabilności, optymalizację grafik i ikon, a także dostosowanie opisów i metadanych aplikacji, co zwiększa jej widoczność i atrakcyjność dla użytkowników. Przestrzeganie wytycznych App Store lub Google Play jest niezbędne, aby aplikacja mogła zostać zatwierdzona i udostępniona do pobrania.

Pytanie 14

W jednostce centralnej, za obliczenia na liczbach zmiennoprzecinkowych odpowiada

A. FPU
B. AU
C. ALU
D. IU
Funkcjonuje takie przekonanie, że wszystkie jednostki w procesorze ogarniają po trochu te same rzeczy, ale to nie do końca tak działa. ALU, czyli Arithmetic Logic Unit, rzeczywiście odpowiada za większość podstawowych operacji arytmetycznych oraz logicznych – dodawanie, odejmowanie, AND, OR czy XOR, ale jest zoptymalizowana do operacji na liczbach całkowitych. Kiedy jednak w grę wchodzą liczby zmiennoprzecinkowe, ALU sobie zwyczajnie nie radzi – nie została do tego zaprojektowana. Warto też wspomnieć o IU, czyli Integer Unit, która – jak sugeruje sama nazwa – jest odpowiedzialna za przetwarzanie liczb całkowitych. Spotkałem się z sytuacjami, gdzie niektórzy mylą IU z FPU, bo niby też coś liczy, ale jeśli chodzi o typy float czy double, to IU nic nie wskóra. AU natomiast, tak szczerze, nie jest powszechnie stosowanym terminem w kontekście architektury procesora. Może się czasem pojawić jako ogólne określenie Arithmetic Unit, ale to raczej archaiczne albo bardzo szerokie pojęcie, nie wskazujące konkretnie, które operacje są obsługiwane. Spotkałem się z tym głównie w starych podręcznikach lub bardzo ogólnych opisach sprzętu, ale dzisiaj nikt poważny nie mówi o AU w kontekście obliczeń zmiennoprzecinkowych. Typowym błędem myślowym jest założenie, że skoro coś jest „arytmetyczne”, to obsłuży dowolny typ liczby. W praktyce inżynierowie projektujący architekturę procesorów zawsze wyraźnie rozdzielają jednostki dla liczb całkowitych od tych dla zmiennoprzecinkowych, bo to zupełnie inne algorytmy i logika działania. Standardy takie jak IEEE 754 dotyczą właśnie FPU i precyzji operacji na floatach, a nie ALU czy IU. W praktycznym zastosowaniu, np. w oprogramowaniu do grafiki, multimediach czy symulacjach naukowych, to właśnie obecność FPU decyduje o wydajności i poprawności obliczeń. Dlatego akurat w tej dziedzinie nie ma miejsca na dowolność – każda jednostka procesora ma swoje konkretne zadanie i nie warto ich ze sobą mieszać.

Pytanie 15

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. stworzenia losowego napisu o długości 8 znaków składającego się z liter
B. jednorazowego wylosowania znaku z określonego zestawu znaków
C. uzupełniania tablicy danymi w postaci liczb pseudolosowych
D. wielokrotnego generowania liczby, aby stworzyć ciąg z liczb pseudolosowych
Wiele osób, widząc fragmenty z random i pętlą, instynktownie myśli o generowaniu ciągów liczb pseudolosowych lub o uzupełnianiu tablic danymi liczbowymi – i to jest bardzo częsty błąd w interpretacji tego typu kodu. Problem polega na tym, że tutaj nie chodzi o liczby, tylko o znaki, a dokładniej: losowe litery z określonego zbioru. Kod nie tworzy tablicy liczb, nie używa random raz na całą pętlę ani nie generuje pojedynczego znaku. Pętla for jasno pokazuje, że proces losowania zachodzi kilka razy (osiem), a każdorazowo wybierany jest indeks, który służy do pobrania znaku z puli znaków. Moim zdaniem, spora część nieporozumień bierze się z niedoczytania, że random.Next nie zwraca znaku, tylko liczbę, którą następnie wykorzystuje się jako indeks do stringa – to takie klasyczne pomylenie poziomów abstrakcji. Także nie jest to uzupełnianie tablicy, bo 'wynik' to po prostu string, nie tablica czy lista. Kolejną pułapką jest założenie, że losujemy tylko jeden znak, a przecież pętla jest powtarzana 8 razy – to podkreśla, że końcowym efektem jest cały napis, nie pojedynczy znak. Warto mieć na uwadze, że w praktyce takie rozwiązanie stosuje się właśnie wtedy, gdy chcemy złożyć nowy losowy string o określonej długości, a nie pojedynczą wartość czy zestaw liczb. Wreszcie, ograniczenie się w odpowiedzi do liczby pseudolosowej czy tablicy to typowy przykład nadinterpretacji funkcji random lub nieuwzględnienia pełnego zakresu operacji na stringach, które są coraz częstsze w nowoczesnych aplikacjach. Po prostu – sednem tego kodu jest generowanie konkretnego losowego napisu, a nie robienie operacji liczbowych.

Pytanie 16

Które z podejść do tworzenia aplikacji najlepiej uwzględnia przyszłe zmiany w funkcjonalności?

A. Pisanie kodu bez jakiejkolwiek dokumentacji
B. Tworzenie bez wcześniejszej specyfikacji technicznej
C. Zastosowanie modularnej architektury aplikacji
D. Skupienie się tylko na estetce aplikacji
Użycie modularnej architektury aplikacji to najlepsze podejście do projektowania systemów, które muszą uwzględniać przyszłe modyfikacje funkcjonalności. Modularność pozwala na podział aplikacji na mniejsze, niezależne komponenty, które mogą być rozwijane, testowane i aktualizowane niezależnie od siebie. Takie podejście zwiększa elastyczność, ułatwia zarządzanie kodem i pozwala na szybkie wdrażanie nowych funkcji bez konieczności ingerencji w cały system. Architektura modularna jest szczególnie przydatna w dużych projektach, gdzie zmiany są częste, a wymagania dynamicznie się zmieniają.

Pytanie 17

W języku Java wyjątek ArrayIndexOutOfBoundsException występuje, gdy następuje próba dostępu do elementu tablicy, którego

A. indeks mieści się w zakresie od 0 do n-1, gdzie n oznacza rozmiar tablicy
B. indeks jest równy lub większy od rozmiaru tablicy
C. wartość przekracza rozmiar tablicy
D. wartość przewyższa jego indeks
Temat ArrayIndexOutOfBoundsException w Javie często rodzi nieporozumienia, zwłaszcza gdy ktoś nie do końca rozumie sposób indeksowania tablic w tym języku. Wydaje się naturalne myśleć, że błąd pojawia się, gdy wartość przechowywana w tablicy przekracza jakiś limit albo że indeksy są liczone od jeden czy od wartości logicznych, ale to nie tak. Tablica w Javie zawsze ma indeksy zaczynające się od 0, a kończące na długość minus jeden. Przekonanie, że wyjątek pojawia się, gdy wartość przekracza rozmiar tablicy, jest dość mylące, bo silnik Javy w ogóle nie analizuje wartości elementów, tylko patrzy na indeks. W innym błędnym podejściu wskazuje się, że wyjątek wystąpi, gdy indeks mieści się w zakresie od 0 do n-1 – to przeczy całej idei tablicy w Javie, bo właśnie te indeksy są w pełni poprawne: to jest naturalny, dozwolony zakres. Jeszcze inny mylny trop to przekonanie, że chodzi o wartość elementu przewyższającą jego indeks – nie ma to żadnego znaczenia, bo tablica może przechowywać dowolne wartości pod dowolnym indeksami, a wyjątek jest związany wyłącznie z odwołaniem się do nieistniejącego indeksu, czyli np. próbą dostępu do szóstego elementu w pięcioelementowej tablicy. Takie nieporozumienia zwykle wynikają z braku praktycznego doświadczenia lub z mylenia zasad działania tablic z innymi strukturami danych. Z mojego doświadczenia wynika, że najlepsze efekty daje po prostu pamiętanie, by zawsze operować na indeksach w zakresie 0 do length - 1 oraz korzystać z length w warunkach pętli. Profesjonalni programiści często automatyzują testy na takich przypadkach, bo to klasyczne źródło bugów w dużych projektach – lepiej nauczyć się od razu, niż potem szukać błędów na produkcji.

Pytanie 18

W jakim modelu Cyklu Życia Projektu Informatycznego znajduje się etap analizy ryzyka?

A. W spiralnym
B. W kaskadowym
C. W modelu Fry’ego
D. W modelu z prototypem
Często spotyka się przekonanie, że analiza ryzyka jest obecna w każdym modelu cyklu życia projektu informatycznego, ale to nie do końca tak działa. W modelu kaskadowym, czyli tzw. waterfall, wszystko odbywa się etapami – analiza, projektowanie, implementacja i tak dalej, w sztywno określonej kolejności. Tu niestety nie ma miejsca na systematyczną analizę ryzyka na każdym etapie, bo cała koncepcja tego modelu polega na tym, że raz wykonane czynności trudno potem cofnąć lub poprawić, szczególnie gdy coś pójdzie nie tak. To, moim zdaniem, jest jeden z powodów, dla których model kaskadowy bywa krytykowany – brak elastyczności i mała odporność na niespodziewane problemy. Podobnie jest w modelu z prototypem – tam niby tworzy się szybkie makiety czy prototypy, ale głównym celem jest poznanie potrzeb użytkownika i szybkie zebranie informacji zwrotnej, a nie formalna analiza ryzyka. Ryzyko oczywiście można zidentyfikować przy okazji, ale nie jest to centralny punkt tego podejścia. Model Fry’ego to już zupełnie inna bajka – jest bardzo liniowy, nacisk kładzie raczej na dokumentację i ścisłe trzymanie się etapów, a nie na adaptacyjność czy zarządzanie niepewnością. Z mojego punktu widzenia, błędne wybranie któregoś z tych modeli jako tego, gdzie analizuje się ryzyko, wynika z przekonania, że wszędzie jest miejsce na refleksję nad zagrożeniami – niestety, tylko model spiralny wprost i metodycznie wpisuje analizę ryzyka w swój rdzeń. W innych przypadkach analiza ryzyka jeśli się pojawia, to głównie z inicjatywy zespołu, a nie jako zaplanowany, powtarzający się etap procesu. Warto o tym pamiętać przy wyborze metodyki do danego projektu – nie każda zapewni takie same mechanizmy zabezpieczające przed błędami i nieprzewidzianymi zdarzeniami.

Pytanie 19

Przedstawione w filmie działania wykorzystują narzędzie

A. kompilatora dla interfejsu graficznego
B. generatora GUI przekształcającego kod do języka XAML
C. generatora kodu java
D. debuggera analizującego wykonujący kod
Wybrana odpowiedź jest trafna, bo faktycznie narzędzie pokazane w filmie to generator GUI, który potrafi przekształcać kod do języka XAML. XAML (czyli Extensible Application Markup Language) jest powszechnie używany do deklaratywnego opisywania interfejsów użytkownika, na przykład w aplikacjach WPF czy UWP na platformie .NET. Jak dla mnie, korzystanie z takich generatorów to ogromna wygoda, bo pozwala błyskawicznie przenosić projekt graficzny do formatu czytelnego dla platformy Microsoftu. Z mojego doświadczenia, wiele zespołów programistycznych stosuje takie rozwiązania, żeby oszczędzić czas na ręcznym pisaniu XAML-a (co potrafi być naprawdę żmudne przy dużych projektach). Co ciekawe, takie narzędzia bardzo dobrze współpracują z designerskimi edytorami UI i potrafią zautomatyzować konwersję nawet z innych formatów graficznych, np. Sketch czy Adobe XD do XAML-a. Branżowe standardy zalecają, by wykorzystywać generatorów GUI właśnie do tego celu, bo minimalizuje to liczbę błędów, przyspiesza wdrożenie zmian i ułatwia współpracę między programistami a projektantami. Warto pamiętać, że XAML jest bardzo elastyczny i umożliwia potem ręczną edycję wygenerowanego kodu – czasem powstają drobne poprawki, ale ogólnie to naprawdę przydatne narzędzie. Ogólnie – jeśli tylko projektujesz UI pod .NET, to automatyczna konwersja do XAML-a to jest coś, co warto znać i wykorzystywać w praktyce.

Pytanie 20

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

A. FF
B. FE
C. EF
D. 100
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 21

Które narzędzie służy do automatyzacji procesu budowania aplikacji?

A. Jenkins
B. Figma
C. Postman
D. Swagger
Jenkins to jeden z najpopularniejszych narzędzi do automatyzacji procesów budowania aplikacji, znany z integracji ciągłej (Continuous Integration, CI) oraz dostarczania ciągłego (Continuous Delivery, CD). Dzięki swojej elastycznej architekturze oraz bogatej bibliotece wtyczek, Jenkins umożliwia automatyzację wielu zadań związanych z budowaniem, testowaniem i wdrażaniem oprogramowania. W praktyce, z Jenkins można skonfigurować zadania, które uruchamiają skrypty budujące po każdej zmianie w kodzie źródłowym, co pozwala na szybkie wykrywanie błędów i zapewnienie jakości. Dobrą praktyką jest definiowanie pipeline'ów (pipelining), które integrują różne etapy, takie jak budowanie, testowanie i wdrożenie w jeden zautomatyzowany proces. Jenkins wspiera wiele języków programowania i środowisk, a także integruje się z narzędziami do zarządzania wersjami, co czyni go niezastąpionym narzędziem w procesie DevOps.

Pytanie 22

Jaki rodzaj testów można scharakteryzować przedstawionym opisem?

NazwaOpisCzynnościPo teście
Formularz osobowySprawdzenie odpowiedzi formularza na błędy użytkownika1. czy wpisano wszystkie wymagane pola?
2. czy e-mail zawiera znak @?
3. czy nr telefonu zawiera cyfry, zgodnie ze wzorcem?
4. czy jest zgoda na przetwarzanie danych?
Usunąć z bazy danych wpisane podczas testowania osoby
A. testy funkcjonalne
B. testy zgodności
C. testy jednostkowe
D. testy wydajnościowe
Wiele osób myli tu pojęcia i sądzi, że sprawdzanie formularza pod kątem walidacji danych to np. testy jednostkowe albo wydajnościowe. Moim zdaniem to typowy błąd wynikający z mylenia poziomów testowania albo niezrozumienia celów tych testów. Testy wydajnościowe koncentrują się na tym, ile system „wytrzyma” – chodzi o liczbę użytkowników, czas odpowiedzi czy zużycie zasobów, a nie o to, czy pola są dobrze sprawdzane. Testy jednostkowe z kolei dotyczą poszczególnych fragmentów kodu, takich jak pojedyncze funkcje czy metody – ich zadaniem jest wyłapywanie błędów logicznych w kodzie, ale nie sprawdzają one całościowego działania funkcji biznesowej z perspektywy użytkownika. Testy zgodności są czymś innym – mają na celu zweryfikowanie, czy system spełnia wymagania formalne, normy prawne albo branżowe standardy (np. czy spełnia RODO, WCAG itp.), a nie typowe błędy użytkownika. W praktyce, jeśli ktoś wskazuje na któryś z tych rodzajów testów w kontekście walidacji formularza, to pewnie wynika to z niejasnego rozróżniania, co jest funkcjonalnością, a co technicznym aspektem systemu. Warto pamiętać, że testy funkcjonalne zawsze dotyczą sprawdzenia, czy konkretny fragment oprogramowania robi dokładnie to, czego oczekuje użytkownik – nie mniej, nie więcej. To najbardziej „namacalne” z testów, bo pozwalają sprawdzić realne scenariusze użycia, często takie, które znajdą się później w rękach klientów. I to właśnie dlatego są kluczowe przy testowaniu formularzy czy innych elementów interfejsu.

Pytanie 23

W jaki sposób można ograniczyć problemy społeczne wynikające z nadmiernego używania internetu?

A. Unikać spotkań z ludźmi w realnym świecie
B. Całkowicie wycofać się z aktywności wirtualnych
C. Zwiększać czas spędzany przy ekranie
D. Zachować równowagę pomiędzy relacjami w sieci a tymi w rzeczywistości
Utrzymywanie równowagi między relacjami online i offline to kluczowy element zapobiegania problemom społecznym wynikającym z nadmiernego korzystania z internetu. Przeplatanie kontaktów wirtualnych z interakcjami twarzą w twarz wzmacnia więzi społeczne i poprawia umiejętności komunikacyjne. Równowaga między życiem cyfrowym a rzeczywistym pozwala unikać izolacji społecznej i wspiera rozwój empatii oraz zdolności interpersonalnych. Jest to szczególnie ważne w kontekście młodzieży, która może być bardziej podatna na negatywne skutki nadmiernej ekspozycji na treści online.

Pytanie 24

Która z poniższych metod HTTP jest idempotentna?

A. POST
B. PATCH
C. GET
D. CONNECT
Metoda GET jest uznawana za idempotentną, co oznacza, że wielokrotne wykonanie tej samej operacji nie zmienia stanu zasobu na serwerze. W praktyce, jeżeli wysyłamy zapytanie GET do określonego zasobu, niezależnie od tego, ile razy je powtórzymy, zwróci ono tę samą odpowiedź oraz nie wpłynie na stan zasobu. Wykorzystanie metody GET jest powszechne w aplikacjach webowych, na przykład podczas ładowania strony, gdzie użytkownik chce pobrać informacje, takie jak artykuły lub dane z bazy. Zgodnie z zasadami RESTful, metody idempotentne powinny być stosowane w przypadkach, gdy zależy nam na stabilności i przewidywalności działania systemu. Przykładem zastosowania metody GET w praktyce może być API, które zwraca szczegóły użytkownika na podstawie jego identyfikatora. W takim przypadku, wywołanie GET na danym URI zawsze zwróci te same dane, o ile nie nastąpią zmiany w bazie danych.

Pytanie 25

Który z wymienionych terminów dotyczy klasy, która stanowi podstawę dla innych klas, lecz nie może być tworzona w instancji?

A. Klasa pochodna
B. Klasa statyczna
C. Klasa abstrakcyjna
D. Klasa finalna
Klasa statyczna jest klasą, która zawiera tylko statyczne metody i pola, ale może być instancjonowana. Klasa pochodna to klasa, która dziedziczy z klasy bazowej i nie jest sama w sobie abstrakcyjna, chyba że zawiera metody czysto wirtualne. Klasa finalna (w niektórych językach, np. Java) to klasa, która nie może być dziedziczona, co jest odwrotnością klasy abstrakcyjnej, której głównym celem jest właśnie dziedziczenie.

Pytanie 26

Jakie określenie w programowaniu obiektowym odnosi się do "zmiennej klasy"?

A. Metoda
B. Pole
C. Konstruktor
D. Obiekt
Obiekt to instancja klasy, która posiada swoje pola i metody, ale sam w sobie nie jest zmienną klasy – jest to jednostka przechowująca dane i wykonująca operacje. Metoda to funkcja należąca do klasy, która definiuje zachowanie obiektu, ale różni się od pola, które przechowuje dane. Konstruktor to specjalna metoda klasy, która jest wywoływana podczas tworzenia obiektu i służy do inicjalizacji jego pól, ale sam w sobie nie jest zmienną klasy – raczej definiuje, jak te zmienne są ustawiane podczas tworzenia obiektu.

Pytanie 27

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

int zm1;
float zm2;
char zm3;
boolean zm4;
A. zm1
B. zm3
C. zm4
D. zm2
Z perspektywy programowania w Javie, wybór nieprawidłowego typu zmiennej do przechowywania pojedynczego znaku, takiego jak 'T', wynika najczęściej z niejasnego rozróżnienia między typami prostymi oraz nieznajomości ich przeznaczenia. Typ 'int' przechowuje liczby całkowite, np. 5, -100, 0, i nie nadaje się do przechowywania znaków, mimo że za pomocą przekształceń można uzyskać kod liczbowy znaku (np. 'A' jako 65), ale to zupełnie inny kontekst. Niejednokrotnie początkujący mylą typ 'char' z 'int' właśnie z powodu tej numerycznej reprezentacji, jednak w praktycznym zastosowaniu – kiedy naszym zadaniem jest operowanie na znakach, nie na ich kodach – 'char' jest właściwym wyborem. Z kolei typ 'float' przechowuje liczby zmiennoprzecinkowe, a więc wartości takie jak 3.14 czy -0.01. Przypisanie do niego znaku jest niemożliwe bez nieintuicyjnych konwersji i najczęściej prowadzi do błędów kompilacji lub nieczytelnego kodu. Często widzę, że ktoś próbuje „upchnąć” znak w typie liczbowym, bo myśli, że 'wszystko to przecież liczby' – to jednak nieporozumienie. Typ 'boolean' natomiast przechowuje jedynie dwa stany: true lub false, a zatem absolutnie nie może służyć do przechowywania znaków. Próbując przypisać znak do zmiennej boolean, dostaniemy błąd już na etapie kompilacji. W branży promuje się zasadę doboru typu danych do ich faktycznego zastosowania, a w przypadku pojedynczego znaku – zawsze należy użyć 'char'. Ignorowanie tego prowadzi do błędów, trudniejszych do wychwycenia w złożonym kodzie. Z mojej perspektywy, warto poświęcić chwilę na dobre zrozumienie tej różnicy, bo to procentuje później w pracy z kodem i ułatwia implementację rozwiązań zgodnych ze standardami Javy, a także sprawia, że kod jest czytelniejszy i bardziej przewidywalny dla innych programistów.

Pytanie 28

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

Definicja typu:

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

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

Kod React.js:
<ul>
    {this.books.map(book => <li key={book}> book </li>)}
</ul>
A. Taką liczbę elementów, ile znajduje się w tablicy books; w każdym punkcie listy umieszczony jest jeden element tablicy.
B. Jedynie jeden element o treści Harry Potter.
C. Wyłącznie jeden element o treści Harry Potter, Hobbit, Władca pierścieni.
D. Tyle elementów, ile znajduje się w tablicy books; w każdym punkcie listy widnieje element o treści {book}.
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 29

W pokazanych fragmentach kodu zdefiniowano funkcję o nazwie fun1. W tej funkcji należy zaimplementować obsługę. Fragment kodu interfejsu użytkownika (XAML):

<RadioButton Content="opcja1" />
<RadioButton Content="opcja2" />
<Button Content="OK" Width=75 Click="fun1"/>
Fragment kodu logiki programu (C#):
private void fun1(object sender, RoutedEventArgs e) { ... }
A. naciśnięcia przycisku zatwierdzającego dialog
B. inicjacji elementów interfejsu użytkownika
C. aplikacji po wystąpieniu zdarzenia utraty fokusu przez pole opcji
D. usunięcia kontrolek z pamięci RAM
Obsługa zdarzeń związanych z przyciskami zatwierdzającymi dialogi jest kluczową częścią interakcji użytkownika z aplikacją. W wielu środowiskach programistycznych, takich jak JavaScript, C# czy Java, przyciski te wywołują funkcje obsługi zdarzeń (event handlers), które mogą walidować dane, przetwarzać informacje lub wykonywać inne działania po naciśnięciu przycisku. Implementacja funkcji obsługującej przycisk jest nieodzowna w aplikacjach graficznych, gdzie interakcja z użytkownikiem wymaga dynamicznego reagowania na jego działania. Dzięki temu aplikacje stają się bardziej interaktywne i responsywne, co zwiększa komfort użytkownika i poprawia ogólną użyteczność oprogramowania.

Pytanie 30

Który z wymienionych poniżej typów danych stanowi przykład typu stałoprzecinkowego?

A. decimal
B. int
C. double
D. float
Typ danych 'int' (integer) to przykład typu stałoprzecinkowego, który przechowuje liczby całkowite. Stałoprzecinkowe typy danych są podstawą w programowaniu, ponieważ pozwalają na efektywne przechowywanie wartości bez części ułamkowej, co przyspiesza obliczenia i redukuje zużycie pamięci. Typ 'int' jest szeroko stosowany w językach takich jak C, C++, Java i Python, a jego główną zaletą jest szybkość operacji arytmetycznych oraz przewidywalność wyników. Stałoprzecinkowe typy danych znajdują zastosowanie w algorytmach, systemach sterowania i aplikacjach embedded, gdzie precyzja obliczeń jest kluczowa.

Pytanie 31

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

A. Tłumaczenie kodu źródłowego na język maszynowy
B. Optymalizacja kodu
C. Analiza działania programu w czasie rzeczywistym
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 32

Cytat zaprezentowany powyżej dotyczy metodyki RAD. Co oznacza ten skrót w języku polskim?

... (RAD) .... is a general term for adaptive software development approaches, and the name for James Martin's method of rapid development. In general, RAD approaches to software development put less emphasis on planning and more emphasis on an adaptive process. Prototypes are often used in addition to or sometimes even instead of design specifications.
Źródło: https://en.wikipedia.org/wiki Dostęp: 25.03.2021
A. środowisko do tworzenia aplikacji
B. szybki rozwój aplikacji
C. zintegrowane środowisko deweloperskie
D. środowisko błyskawicznego programowania
RAD czyli Rapid Application Development to podejście do tworzenia oprogramowania które skupia się na szybkim wytwarzaniu aplikacji. Kluczowym elementem tej metodyki jest minimalizacja czasu spędzanego na planowaniu i projektowaniu na rzecz szybkiego prototypowania i elastycznego dostosowywania się do zmieniających się wymagań. W praktyce RAD wykorzystuje krótkie cykle rozwoju oraz intensywną współpracę z użytkownikami końcowymi co pozwala na szybkie reagowanie na ich potrzeby. W porównaniu do tradycyjnych metod RAD zapewnia większą elastyczność i skrócenie czasu dostarczenia produktu co jest szczególnie wartościowe w dynamicznie zmieniających się środowiskach biznesowych. Dobre praktyki w RAD obejmują użycie narzędzi do szybkiego prototypowania oraz zaangażowanie użytkowników w proces testowania co pozwala na bieżące wprowadzanie zmian i udoskonaleń. Dzięki temu uzyskuje się produkt lepiej dopasowany do oczekiwań użytkowników co zwiększa jego użyteczność i satysfakcję końcową. RAD jest często stosowany w projektach gdzie czas dostarczenia jest krytycznym czynnikiem sukcesu co odzwierciedla jego praktyczne zastosowanie w wielu branżach

Pytanie 33

Z analizy złożoności obliczeniowej różnych algorytmów sortowania na dużych zbiorach danych (przekraczających 100 elementów) wynika, że najefektywniejszą metodą jest algorytm sortowania

sortowanie bąbelkoweO(n²)
sortowanie przez wstawianieO(n²)
sortowanie przez scalanieO(n log n)
sortowanie przez zliczanieO(n)
sortowanie kubełkoweO(n²)
A. przez zliczanie
B. bąbelkowego
C. przez scalanie
D. kubełkowego
Sortowanie przez zliczanie jest jedną z najszybszych metod sortowania w przypadku określonych typów danych wejściowych. W szczególności działa ono efektywnie, gdy znamy ograniczenia co do zakresu wartości w zbiorze danych, ponieważ jego złożoność obliczeniowa wynosi O(n+k), gdzie n to liczba elementów do posortowania, a k to zakres wartości. Dzięki temu, w przeciwieństwie do metod sortowania porównawczego, takich jak sortowanie przez scalanie czy bąbelkowe, sortowanie przez zliczanie może osiągnąć liniową złożoność czasową, jeśli k jest stosunkowo małe w porównaniu do n. Algorytm ten działa poprzez zliczanie wystąpień każdego elementu, co pozwala na szybkie umieszczenie go w odpowiedniej pozycji w posortowanej tablicy. Przykładowe zastosowania sortowania przez zliczanie to sortowanie wyników egzaminów czy organizacja danych liczbowych w określonym przedziale, co jest często spotykane w analizach statystycznych. Standardy branżowe często korzystają z tej metody, gdy operujemy na dużych zbiorach danych o ograniczonym zakresie, co jest zgodne z najlepszymi praktykami efektywnego przetwarzania danych.

Pytanie 34

Co to jest serverless computing?

A. Proces kompilacji kodu bezpośrednio w przeglądarce użytkownika
B. Model wykonywania kodu w chmurze bez konieczności zarządzania infrastrukturą serwerową
C. Technika projektowania baz danych bez użycia serwera SQL
D. Metoda tworzenia aplikacji bez użycia back-endu
Serverless computing nie jest tożsamy z koncepcjami przedstawionymi w pozostałych odpowiedziach. Tworzenie aplikacji bez użycia back-endu nie jest zdefiniowane w ramach serverless computing, ponieważ model ten wciąż zakłada istnienie backendu, który jest zarządzany przez dostawcę usług chmurowych. Użytkownik nie musi się martwić o serwery, ale backend wciąż funkcjonuje, co jest kluczowe dla działania aplikacji. Technika projektowania baz danych bez użycia serwera SQL również nie odnosi się do serverless computing. W rzeczywistości, serverless może wykorzystywać zewnętrzne bazy danych, takie jak DynamoDB, które są w pełni zarządzane przez dostawcę chmury. Również proces kompilacji kodu w przeglądarce użytkownika to odmienna koncepcja, która dotyczy raczej aplikacji webowych i nie ma związku z serverless computing. Pojęcie serverless odnosi się do automatyzacji zarządzania infrastrukturą, co odmienia sposób, w jaki aplikacje są rozwijane i skalowane. Wprowadzenie w błąd w tym kontekście może prowadzić do nieefektywnej architektury oraz niepoprawnego rozumienia aktualnych trendów w inżynierii oprogramowania.

Pytanie 35

Która z poniższych struktur danych jest najbardziej odpowiednia do przechowywania unikalnych elementów?

A. Sekwencja
B. Kolejka priorytetowa
C. Zbiór (Set)
D. Tablica
Zbiór, czyli Set, to taki specjalny rodzaj struktury danych, który trzyma tylko unikalne elementy. To znaczy, że nie znajdziesz tam powtórzeń – jak masz listę użytkowników czy tagów, to świetnie, bo zbiór to idealnie rozwiązuje. Jest przy tym bardzo szybki w operacjach jak dodawanie, usuwanie czy wyszukiwanie. To dlatego zbory są używane w różnych algorytmach, zwłaszcza gdy chodzi o przetwarzanie dużych ilości danych i zarządzanie unikalnymi zasobami. Fajna sprawa, nie?

Pytanie 36

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

SELECT COUNT(*)
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
A. Średnia pensja wszystkich pracowników
B. Liczba pracowników z pensją powyżej średniej
C. Liczba pracowników z najwyższą pensją
D. Błąd składni SQL
Odpowiedź, że wynik działania zapytania SQL to liczba pracowników z pensją powyżej średniej, jest całkowicie poprawna. Zapytanie to korzysta z funkcji agregującej COUNT(*), która zlicza liczbę rekordów spełniających określony warunek. W tym przypadku warunkiem jest, że pensja pracownika jest większa od średniej pensji wszystkich pracowników, którą obliczamy za pomocą wewnętrznego zapytania (subquery). Tego rodzaju operacje są powszechnie stosowane w analizie danych w bazach danych, gdzie często musimy wykonać porównania względem wartości agregatów, takich jak średnia, mediana czy suma. Przykładowo, w analizie wynagrodzeń w danej firmie, można użyć podobnych zapytań do oceny, jaki odsetek pracowników jest wynagradzanych powyżej średniej, co może być istotne z punktu widzenia polityki płacowej oraz budżetowania. Pamiętaj, że dobre praktyki w pracy z bazami danych obejmują optymalizację zapytań oraz unikanie niepotrzebnych obliczeń, co może wpłynąć na wydajność systemu.

Pytanie 37

Jakie informacje można uzyskać na temat metod w klasie Point?

public class Point {
    public void Move(int x, int y) {...}
    public void Move(int x, int y, int z) {...}
    public void Move(Point newPt) {...}
}
A. Są przeciążone.
B. Służą jako konstruktory w zależności od liczby argumentów.
C. Zawierają przeciążenie operatora.
D. Zawierają błąd, ponieważ nazwy metod powinny być różne.
Metody przeciążone mogą mieć tę samą nazwę – różnią się sygnaturą, czyli liczbą i typami argumentów, co jest zgodne z zasadami programowania obiektowego. Przeciążenie metod to nie to samo co przeciążenie operatorów, które polega na definiowaniu nowego sposobu działania operatorów (np. +, -, *). Pełnienie funkcji konstruktorów to inny mechanizm i dotyczy głównie klas i ich instancjonowania, nie przeciążania metod.

Pytanie 38

Co to jest klasa abstrakcyjna?

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

Pytanie 39

Który z wymienionych poniżej przykładów ilustruje prawidłowy szkielet zarządzania wyjątkami w języku C++?

A. try { kod } except { obsługa }
B. try { kod } catch { obsługa }
C. try { kod } handle { obsługa }
D. try { kod } finally { obsługa }
Niestety, skrypt 'try { kod } handle { obsługa }' nie zadziała w C++. Słowo 'handle' nie jest czymś, co znajdziesz w tym języku – używamy 'catch'. Poza tym, 'except' to termin z Pythona, nie C++. No i 'finally' też nie istnieje w C++, to też jest z języków jak Java czy Python, które mają to w inny sposób. Tak że jedynym poprawnym rozwiązaniem w C++ jest właśnie 'try' i 'catch'. Tylko to gwarantuje, że wszystko będzie działać jak należy.

Pytanie 40

Jak określa się proces transferu danych z lokalnego komputera na serwer?

A. Streaming
B. Pobieranie danych
C. Wysyłanie danych
D. Przesyłanie danych
Proces przesyłania danych z komputera lokalnego na serwer nazywany jest wysyłaniem danych. To kluczowy element komunikacji w sieciach komputerowych, który wskazuje na transfer informacji z jednego punktu do drugiego. Wysyłanie danych odbywa się za pomocą różnych protokołów, takich jak FTP (File Transfer Protocol), HTTP (Hypertext Transfer Protocol) czy SFTP (Secure File Transfer Protocol). Przykładem może być przesyłanie plików z komputera na zdalny serwer, co jest powszechnie wykorzystywane w przypadku tworzenia stron internetowych. W kontekście aplikacji, wysyłanie danych może dotyczyć również przesyłania formularzy do bazy danych. Ważne jest, aby dane były odpowiednio pakowane i kodowane w celu zapewnienia ich integralności oraz bezpieczeństwa. Stosowanie protokołów szyfrowania, takich jak SSL/TLS, dodatkowo zabezpiecza proces, co jest istotne w dobie rosnących zagrożeń cybernetycznych. Zbierając wszystkie te elementy, wysyłanie danych jest fundamentalnym procesem w architekturze nowoczesnych systemów informatycznych.