Wyniki egzaminu

Informacje o egzaminie:
  • Zawód: Technik programista
  • Kwalifikacja: INF.04 - Projektowanie, programowanie i testowanie aplikacji
  • Data rozpoczęcia: 6 maja 2026 08:30
  • Data zakończenia: 6 maja 2026 08:44

Egzamin zdany!

Wynik: 25/40 punktów (62,5%)

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óre z poniższych nie jest wzorcem architektonicznym aplikacji mobilnych?

A. Clean Architecture
B. MVC (Model-View-Controller)
C. Linear Sequential Flow
D. MVVM (Model-View-ViewModel)
Wszystkie wymienione odpowiedzi, z wyjątkiem Linear Sequential Flow, są uznawane za wzorce architektoniczne aplikacji mobilnych. MVC, MVVM i Clean Architecture to powszechnie stosowane podejścia, które mają swoje unikalne cechy i zalety. MVC, czyli Model-View-Controller, dzieli aplikację na trzy główne komponenty, co ułatwia zarządzanie kodem oraz rozdzielanie logiki biznesowej od logiki prezentacji. Dzięki temu, programiści mogą pracować nad różnymi częściami aplikacji równolegle, co przyspiesza rozwój i ułatwia testowanie. MVVM, z kolei, jest często wykorzystywany w aplikacjach opartych na technologiach takich jak WPF czy Xamarin, gdzie wprowadza dwukierunkowe powiązania danych, co poprawia interaktywność i responsywność aplikacji. Clean Architecture jest bardziej złożonym podejściem, które sugeruje, aby aplikacja była podzielona na warstwy, co ułatwia jej rozwój, testowanie i utrzymanie. Wybierając niewłaściwy wzorzec, jak Linear Sequential Flow, programiści mogą napotkać problemy z elastycznością i możliwością dostosowania aplikacji do zmieniających się wymagań. Często takie podejście prowadzi do tzw. „technical debt”, gdzie trudności w wprowadzaniu zmian kumulują się, co w dłuższym okresie może być kosztowne i czasochłonne.

Pytanie 2

Co oznacza operator '===' w JavaScript?

A. Porównanie wartości i typów
B. Konkatenacja stringów
C. Porównanie wartości
D. Przypisanie wartości
Operator '===' w JavaScript jest używany do porównania wartości oraz ich typów. To znaczy, że aby dwa elementy uznano za równe, muszą mieć zarówno tę samą wartość, jak i ten sam typ. Przykładowo, porównanie liczby 5 i stringa '5' zwróci false, ponieważ różnią się typem. Używanie '===' jest zalecane w dobrych praktykach programistycznych, ponieważ eliminuje niejednoznaczności związane z równością luźną (operator '=='), która może prowadzić do nieprzewidywalnych wyników. Na przykład, '5' == 5 zwróci true, co może być mylące. Dlatego w sytuacjach, gdzie zależy nam na ścisłym porównaniu, powinno się zawsze stosować '===' dla jasności kodu i uniknięcia błędów. W kontekście profesjonalnego programowania, korzystanie z '===' zapewnia lepszą kontrolę typów danych, co jest kluczowe w większych projektach, gdzie błędy typów mogą prowadzić do poważnych problemów z debugowaniem i utrzymywaniem kodu.

Pytanie 3

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

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

Pytanie 4

Który z wymienionych elementów NIE stanowi części instrukcji dla użytkownika programu?

A. Instrukcje dotyczące obsługi poszczególnych funkcji aplikacji
B. Rozwiązywanie problemów związanych z użytkowaniem aplikacji
C. Opis metody instalacji aplikacji
D. Opis testów jednostkowych
Instrukcja użytkownika programu zawiera opisy dotyczące sposobu instalacji aplikacji, konfiguracji oraz obsługi poszczególnych funkcji. Jest to kluczowy dokument pomagający użytkownikom w szybkim wdrożeniu się w pracę z oprogramowaniem. Zawiera również sekcje dotyczące rozwiązywania typowych problemów oraz wskazówki, jak efektywnie korzystać z narzędzi i funkcji aplikacji. Instrukcja użytkownika może być dostępna w formie elektronicznej (PDF, strony WWW) lub papierowej, a jej celem jest uproszczenie procesu wdrażania oraz ograniczenie liczby zgłoszeń do działu wsparcia technicznego. Dokumentacja tego typu stanowi również ważny element budowania pozytywnego doświadczenia użytkownika (UX).

Pytanie 5

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

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

Pytanie 6

Zapisany fragment w Pythonie ilustruje:

pierwiastki = {"N":"Azot","O":"Tlen","P":"Fosfor","Si":"Siarka"}
A. strukturę danych
B. tablicę asocjacyjną (słownik)
C. stos
D. kolejkę (LIFO)
W tym pytaniu chodziło o rozpoznanie tablicy asocjacyjnej (czyli słownika) w języku Python. Taka struktura danych pozwala bardzo szybko przypisywać wartości do kluczy i potem je równie sprawnie odnajdywać, co jest superpraktyczne w codziennych zadaniach programistycznych. Taki słownik, jak w przykładzie, gdzie symbole pierwiastków są kluczami, a ich polskie nazwy wartościami, pokazuje typowe zastosowanie tej struktury do przechowywania powiązanych danych bez konieczności przeszukiwania całej listy po kolei. Moim zdaniem słowniki to w ogóle jeden z najwygodniejszych wynalazków Pythona – nie musisz się martwić o kolejność, wystarczy znać klucz i już masz wartość. W branży wykorzystuje się słowniki na potęgę: do mapowania konfiguracji, przechowywania danych z plików JSON, czy nawet jako szybki cache. Warto dodać, że słowniki w Pythonie od wersji 3.7 zachowują kolejność dodania elementów, co czasem pomaga w czytelności kodu, chociaż to raczej miły „bonus” niż must-have. W kontekście dobrych praktyk zawodowych zawsze pilnuję, żeby klucze były niezmiennikami (np. stringi czy liczby), bo tego wymaga Python, a wartości mogą być dowolne. Jeżeli ktoś planuje automatyzować jakieś procesy lub pracować z danymi, bez słowników się nie obejdzie. To trochę taki niepozorny, a bardzo potężny „narzędzie” w arsenale każdego programisty.

Pytanie 7

Jakie jest główne zadanie ochrony danych osobowych?

A. Zabezpieczenie danych osobowych przed nieautoryzowanym dostępem i ich wykorzystaniem
B. Udostępnianie danych osobowych w celach marketingowych
C. Gwarantowanie anonimowości dla internautów
D. Utrudnianie działalności organom ścigania
Ochrona danych osobowych przed nieuprawnionym dostępem i wykorzystaniem to podstawowy cel ochrony danych osobowych. Zasady ochrony prywatności, takie jak RODO (GDPR), zapewniają użytkownikom prawo do kontroli nad swoimi danymi i decydowania, kto może je przetwarzać. Firmy i organizacje muszą wdrażać środki techniczne oraz organizacyjne, aby zabezpieczyć dane przed wyciekiem, kradzieżą i nadużyciami. Przestrzeganie tych zasad nie tylko chroni jednostki, ale również buduje zaufanie klientów do przedsiębiorstw.

Pytanie 8

Co to jest Redux?

A. System kontroli wersji dla projektów JavaScript
B. Narzędzie do optymalizacji wydajności aplikacji React
C. Biblioteka do zarządzania stanem aplikacji w JavaScript
D. Framework do tworzenia aplikacji mobilnych
Chociaż odpowiedzi związane z frameworkami do tworzenia aplikacji mobilnych, narzędziami do optymalizacji wydajności czy systemami kontroli wersji mogą być interesujące, nie są one związane z funkcją, jaką pełni Redux. Frameworki do tworzenia aplikacji mobilnych, takie jak React Native, pozwalają na rozwijanie aplikacji mobilnych z użyciem JavaScript, ale nie zarządzają one stanem aplikacji w sposób, w jaki robi to Redux. Optymalizacja wydajności aplikacji React nie jest bezpośrednią funkcją Redux; chociaż biblioteka ta może pośrednio przyczynić się do lepszej wydajności przez poprawne zarządzanie stanem, nie jest narzędziem służącym do optymalizacji. Z kolei systemy kontroli wersji, takie jak Git, służą do zarządzania historią zmian w kodzie źródłowym aplikacji, a nie do zarządzania stanem wykonawczej logiki aplikacji. Wybór niewłaściwego narzędzia wynika często z braku zrozumienia ich funkcji oraz zastosowania w procesie tworzenia aplikacji. Aby skutecznie zarządzać stanem w aplikacji, kluczowe jest zrozumienie różnic między tymi narzędziami oraz ich zastosowaniem w architekturze aplikacji, co jest fundamentalnym elementem współczesnego rozwijania oprogramowania.

Pytanie 9

Jakie jest podstawowe środowisko do tworzenia aplikacji desktopowych przy użyciu języka C#?

A. PyCharm
B. Eclipse
C. MS Visual Studio
D. NetBeans
MS Visual Studio to potężne zintegrowane środowisko programistyczne (IDE) zaprojektowane przez firmę Microsoft, które oferuje pełne wsparcie dla języka C#. Dzięki bogatym funkcjom, takim jak IntelliSense, które ułatwia pisanie kodu poprzez podpowiadanie składni oraz dostępność narzędzi do debugowania, programiści mogą efektywnie rozwijać aplikacje desktopowe. MS Visual Studio obsługuje różne frameworki, takie jak .NET Framework oraz .NET Core, co pozwala na budowanie aplikacji o różnej architekturze. W praktyce, programiści mogą tworzyć aplikacje w oparciu o Windows Presentation Foundation (WPF) lub Windows Forms, co umożliwia tworzenie rozbudowanych interfejsów użytkownika. Dodatkowo, MS Visual Studio oferuje szereg narzędzi do współpracy zespołowej, integracji z systemami kontroli wersji oraz wsparcie dla testowania jednostkowego. Jako standard w branży, MS Visual Studio jest często preferowanym wyborem w projektach komercyjnych i korporacyjnych, z uwagi na jego wszechstronność oraz wsparcie ze strony społeczności programistycznej.

Pytanie 10

Który z algorytmów ma złożoność O(n²)?

A. Bubble Sort
B. Binary Search
C. Merge Sort
D. Dijkstra
Bubble Sort to algorytm o złożoności O(n²), co oznacza, że jego czas wykonania rośnie kwadratowo wraz ze wzrostem liczby elementów wejściowych. Algorytm porównuje sąsiadujące elementy i zamienia je miejscami, jeśli są w złej kolejności. Proces ten powtarza się wielokrotnie, aż do uzyskania pełnego posortowania tablicy. Ze względu na swoją prostotę, Bubble Sort jest często wykorzystywany do nauki podstaw algorytmiki, ale w praktyce rzadko stosuje się go do sortowania dużych zbiorów danych, ponieważ jest nieefektywny w porównaniu do bardziej zaawansowanych algorytmów, takich jak QuickSort czy Merge Sort.

Pytanie 11

Który z wymienionych etapów w procesie przetwarzania instrukcji przez procesor odbywa się jako pierwszy?

A. Zapis wyników do pamięci (Write Back)
B. Realizacja instrukcji (Execution)
C. Rozkodowanie rozkazu (Decode)
D. Pobranie rozkazu z pamięci (Fetch)
Pierwszą rzeczą, jaką robi procesor, jest pobranie rozkazu z pamięci, co nazywamy Fetch. To bardzo ważny etap w budowie komputera. Normalnie cykl wykonywania instrukcji składa się z trzech głównych kroków: pobierania, dekodowania i wykonania. W fazie Fetch procesor dobiera się do pamięci i ściąga instrukcję, którą zaraz wykona. Do tego używa rejestru wskaźnika instrukcji, czyli Instruction Pointer, który pokazuje, gdzie w pamięci jest następna instrukcja. Jak to działa w praktyce? Można to zobaczyć na przykładzie procesora x86, gdzie CPU na początku cyklu sprawdza pamięć RAM, szukając instrukcji według adresu, który podaje wskaźnik. Standardy takie jak ISA (Instruction Set Architecture) mówią, że ten krok to podstawa, bo to właśnie od niego zaczyna się wszystko, co robi procesor.

Pytanie 12

Które z poniższych narzędzi jest używane do zarządzania wersjami kodu?

A. Jenkins
B. Git
C. Docker
D. Kubernetes
Git jest narzędziem służącym do zarządzania wersjami kodu, które zyskało ogromną popularność wśród programistów na całym świecie. Jego podstawową funkcją jest umożliwienie śledzenia zmian w kodzie źródłowym, co jest niezbędne w procesie tworzenia oprogramowania. Dzięki Gitowi możemy w łatwy sposób przechowywać historię zmian, co pozwala na cofanie się do wcześniejszych wersji projektu, a także na pracę zespołową, gdzie wielu programistów może jednocześnie pracować nad różnymi częściami tego samego projektu. Git wspiera również gałęzie (ang. branches), które umożliwiają równoległe rozwijanie nowych funkcji bez zakłócania głównej linii rozwoju. Jest to kluczowe w środowiskach, gdzie rozwój i wydanie nowych funkcji musi być dobrze zorganizowane. Narzędzie to jest nie tylko darmowe, ale również open-source, co oznacza, że każdy może przyczynić się do jego rozwoju. Git jest standardem w branży IT, a jego znajomość jest często wymagana przez pracodawców. Dzięki swojej elastyczności i wszechstronności Git jest stosowany w projektach open-source, komercyjnych i edukacyjnych.

Pytanie 13

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

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

Pytanie 14

Jakie jest główne zadanie portali społecznościowych?

A. Tworzenie kopii zapasowych plików
B. Udostępnianie informacji i interakcja między użytkownikami
C. Zarządzanie handlem produktami i usługami
D. Analiza rezultatów działalności gospodarczej
Główna funkcja portali społecznościowych polega na umożliwieniu użytkownikom tworzenia, udostępniania oraz wymiany treści, a także komunikacji w czasie rzeczywistym. Portale takie jak Facebook, Twitter czy Instagram pozwalają na interakcję poprzez posty, komentarze, polubienia oraz wiadomości prywatne. Użytkownicy mogą dzielić się zdjęciami, filmami, artykułami lub osobistymi przemyśleniami, co sprzyja budowaniu społeczności i nawiązywaniu relacji. Funkcjonalności te są zgodne z najlepszymi praktykami UX/UI, które kładą nacisk na intuicyjność i łatwość obsługi. W kontekście SEO, portale społecznościowe są także ważne ze względu na możliwość generowania ruchu na zewnętrzne strony internetowe poprzez linki i udostępnienia. Przykładem może być wykorzystanie platformy Instagram do promocji produktów, gdzie użytkownicy mogą kliknąć w linki do sklepu. Takie działania zwiększają widoczność marki w Internecie oraz angażują odbiorców, co jest kluczowe dla efektywnej strategii marketingowej.

Pytanie 15

Co to jest Continuous Integration (CI)?

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

Pytanie 16

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

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

Pytanie 17

Jaką rolę pełni instrukcja throw w języku C++?

A. Ogranicza zasięg zmiennych w bloku try
B. Zgłasza wyjątek, który można przechwycić za pomocą bloku catch
C. Inicjuje nowy wyjątek podczas działania aplikacji
D. Przerywa działanie programu, gdy wystąpi wyjątek
Instrukcja 'throw' w C++ służy do zgłaszania wyjątków, które mogą być następnie przechwycone i obsłużone przez blok 'catch'. Mechanizm ten pozwala na przerwanie normalnego przepływu programu w przypadku wystąpienia błędu i skierowanie sterowania do odpowiedniego miejsca obsługi wyjątków. 'Throw' jest kluczowym elementem obsługi błędów i umożliwia propagowanie informacji o błędach na wyższe poziomy programu, co pozwala na ich efektywną obsługę. Używanie wyjątków poprawia czytelność kodu, umożliwiając oddzielenie logiki biznesowej od logiki obsługi błędów.

Pytanie 18

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 najwyższą pensją
C. Liczba pracowników z pensją powyżej średniej
D. Błąd składni SQL
Inne odpowiedzi sugerują mylne interpretacje funkcji i logiki zapytania SQL. Odpowiedź wskazująca na średnią pensję wszystkich pracowników nie uwzględnia faktu, że zapytanie nie zwraca wartości średniej, lecz liczbę pracowników, którzy zarabiają powyżej tej wartości. Odpowiedź odnosząca się do liczby pracowników z najwyższą pensją również jest niepoprawna, ponieważ w zapytaniu nie ma żadnych odniesień do konkretnego wynagrodzenia, a jedynie do wartości średniej. Ponadto, stwierdzenie, że zapytanie generuje błąd składni SQL, jest błędne, ponieważ składnia jest poprawna i zgodna z standardami SQL. Kluczową kwestią jest zrozumienie, że zapytania SQL mogą wykorzystywać zagnieżdżone zapytania do dynamicznego obliczania wartości w kontekście zbioru danych. Często popełnianym błędem jest mylenie funkcji agregujących z prostymi operacjami na kolumnach. Warto więc zaznajomić się z różnymi typami zapytań oraz ich zastosowaniem w praktyce, aby zwiększyć efektywność analizy danych. Zrozumienie logiki działania zagnieżdżonych zapytań oraz funkcji agregujących jest kluczowe dla skutecznej pracy z bazami danych.

Pytanie 19

Co to jest git rebase?

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

Pytanie 20

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

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

Pytanie 21

Który z frameworków bazuje na budowaniu komponentów przy użyciu języka JavaScript?

A. Node.js
B. React.js
C. ASP.NET Core
D. Django
Node.js to środowisko uruchomieniowe JavaScript, które działa po stronie serwera i umożliwia tworzenie aplikacji backendowych, a nie komponentów frontendowych. Django to framework do budowy aplikacji webowych w Pythonie i nie jest oparty na komponencie w JavaScript. ASP.NET Core to framework wykorzystywany do budowy aplikacji w języku C# i nie ma związku z tworzeniem komponentów w JavaScript.

Pytanie 22

Który z wymienionych poniżej przykładów ilustruje użycie systemu informatycznego w działalności gospodarczej?

A. System wentylacji
B. System nawigacji GPS
C. E-sklep
D. System sterowania ruchem miejskim
System wentylacji, mimo że jest istotnym elementem infrastruktury budynków, nie jest przykładem systemu informatycznego w kontekście działalności biznesowej. Wentylacja jest technologią mechaniczną, która ma na celu zapewnienie odpowiedniej jakości powietrza. Nie posiada zaawansowanych funkcji informatycznych, które mogłyby wspierać procesy biznesowe, jak np. zarządzanie danymi klientów czy automatyzacja sprzedaży. Systemy wentylacyjne są zaprojektowane głównie w celu poprawy komfortu użytkowników, a nie w celu generowania wartości dodanej dla przedsiębiorstwa poprzez informatyzację procesów. W przypadku systemu sterowania ruchem miejskim, jego głównym celem jest zarządzanie ruchem drogowym i zwiększenie efektywności transportu publicznego. Jest to również system technologiczny, jednak jego głównym zastosowaniem jest poprawa bezpieczeństwa i komfortu podróży, a nie wspieranie operacji biznesowych. Tego typu systemy, choć korzystają z technologii informatycznych, nie są bezpośrednio związane z procesami komercyjnymi ani z generowaniem przychodu. Z kolei system nawigacji GPS, choć istotny w kontekście transportu i logistyki, działa jako narzędzie wspierające nawigację i lokalizację, a nie jako integralna część systemu informatycznego w działalności przedsiębiorstw. Jego zastosowania w biznesie są zazwyczaj pośrednie i nie mają na celu bezpośredniego wsparcia dla funkcji komercyjnych, lecz przede wszystkim służą do optymalizacji tras dostaw czy lokalizacji klientów.

Pytanie 23

Które z wymienionych stwierdzeń najtrafniej charakteryzuje WPF?

A. Framework umożliwiający zarządzanie urządzeniami IoT
B. Biblioteka do obróbki danych w Pythonie
C. Framework przeznaczony do budowy aplikacji internetowych
D. Framework przeznaczony do budowy aplikacji stacjonarnych w systemie Windows
No i tutaj jest mały błąd. Frameworki do aplikacji webowych, to na przykład Angular czy React, a WPF służy do aplikacji desktopowych. Jak mówimy o przetwarzaniu danych w Pythonie, to raczej wspominamy np. o NumPy czy Pandas, ale one nie mają nic wspólnego z interfejsami. Jeśli chodzi o IoT, to nie używamy WPF, bo on jest bardziej związany z Windows, a do sprzętu raczej sięga się po Arduino IDE czy PlatformIO.

Pytanie 24

W jakich sytuacjach zastosowanie rekurencji może być bardziej korzystne niż użycie iteracji?

A. Gdy algorytm wymaga naturalnego podziału na mniejsze podproblemy
B. Kiedy liczba iteracji przewyższa maksymalny zakres zmiennej licznikowej
C. Kiedy program jest uruchamiany w środowisku wielowątkowym
D. Gdy kod źródłowy ma być zoptymalizowany dla starszych kompilatorów
Przekroczenie zakresu zmiennej licznikowej nie jest powodem, dla którego rekurencja jest bardziej efektywna. Problemy z zakresami zmiennych licznikowych można rozwiązać poprzez odpowiedni dobór typów danych, a nie przez zastosowanie rekurencji. Programowanie wielowątkowe nie jest bezpośrednio związane z rekurencją – chociaż niektóre algorytmy rekurencyjne mogą być implementowane w środowisku wielowątkowym, nie jest to ich główne zastosowanie. Optymalizacja kodu dla starszych kompilatorów nie ma związku z rekurencją, ponieważ starsze kompilatory mogą mieć ograniczoną obsługę rekurencji lub generować mniej efektywny kod rekurencyjny.

Pytanie 25

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

A. protokołu SSH
B. formatu JSON
C. biblioteki jQuery
D. metody POST
Format JSON to zdecydowanie najpopularniejszy i najwygodniejszy sposób przesyłania danych pomiędzy serwerem a aplikacją front-end. JSON, czyli JavaScript Object Notation, jest lekkim formatem wymiany danych, który został zaprojektowany właśnie pod kątem prostoty odczytu i zapisu, zarówno przez ludzi, jak i maszyny. Moim zdaniem trudno dziś znaleźć nowoczesną aplikację webową, która nie korzysta z JSON-a. W praktyce wygląda to tak, że serwer generuje odpowiedź HTTP z danymi w formacie JSON, a front-end (często napisany w JavaScript lub TypeScript) potrafi je bez problemu sparsować i wykorzystać. Standardy branżowe – jak REST API czy GraphQL – bazują w dużej mierze na tym formacie, bo jest uniwersalny, prosty i dobrze wspierany przez frameworki. JSON wspiera nawet zagnieżdżone struktury, tablice, obiekty, więc przekazywanie danych jest bardzo elastyczne. Z mojego doświadczenia, dzięki JSON-owi można bardzo sprawnie integrować różne technologie na back-endzie i front-endzie, co się naprawdę często przydaje przy dużych projektach. Warto pamiętać, że praktycznie każdy język programowania ma biblioteki do obsługi JSON-a, więc nie ma tu żadnych barier technologicznych. Nawet przy komunikacji asynchronicznej (np. z użyciem fetch czy XMLHttpRequest) JSON jest domyślnym wyborem. Tak naprawdę, jeśli chodzi o wymianę danych w aplikacjach webowych, JSON jest po prostu standardem de facto i warto go dobrze znać.

Pytanie 26

Która z poniższych metod nie należy do cyklu życia komponentu w React.js?

A. componentWillPublish()
B. componentDidUpdate()
C. componentWillUnmount()
D. componentDidMount()
Dla osób pracujących z React.js kluczowe jest zrozumienie cyklu życia komponentów, który składa się z określonych metod umożliwiających zarządzanie stanem komponentów w różnych momentach ich życia. Wśród powszechnie używanych metod znajdują się componentDidMount(), componentDidUpdate() oraz componentWillUnmount(). Każda z tych metod pełni istotną rolę w kontekście zarządzania komponentami. Metoda componentDidMount() jest pierwszym momentem, kiedy komponent jest dostępny w DOM, co sprawia, że jest idealna do wykonywania wszelkich operacji związanych z inicjalizacją, takich jak pobieranie danych z serwera. Z kolei componentDidUpdate() umożliwia reagowanie na zmiany stanu lub propów, co jest niezbędne w dynamicznych interfejsach użytkownika. Metoda componentWillUnmount() pozwala na odpowiednie czyszczenie zasobów, co zapobiega wyciekom pamięci, na przykład poprzez usuwanie nasłuchiwaczy. Użytkownicy mogą błędnie interpretować metodę componentWillPublish(), sądząc, że jest ona częścią standardowego cyklu życia komponentów, jednak nie jest to zgodne ze specyfikacją React. Kluczowe jest, aby nie mylić terminologii i zrozumieć, że właściwe metody cyklu życia są jasno zdefiniowane w dokumentacji React. Ignorowanie tego aspektu może prowadzić do problemów w zarządzaniu komponentami, ich stanem oraz interakcjami z użytkownikiem, co w dłuższej perspektywie wpływa na jakość i wydajność aplikacji.

Pytanie 27

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

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

Pytanie 28

Jaki typ pamięci RAM powinno się wybrać do efektywnego komputera do gier?

A. LPDDR4
B. DDR4
C. DDR3
D. DDR5
Wybór odpowiedniego rodzaju pamięci RAM jest kluczowy dla osiągnięcia maksymalnej wydajności w komputerze gamingowym. DDR5, najnowszy standard pamięci dynamicznej RAM, oferuje znaczące ulepszenia w porównaniu do swoich poprzedników. Główne różnice dotyczą prędkości, efektywności energetycznej oraz pojemności. DDR5 może oferować prędkości sięgające 8400 MT/s, co przyczynia się do szybszego transferu danych, co ma bezpośredni wpływ na wydajność gier i aplikacji wymagających wysokiej przepustowości. Ponadto, DDR5 wprowadza architekturę, która pozwala na zwiększenie ilości pamięci w jednym module, co umożliwia konfiguracje do 128 GB na pojedynczy moduł, co jest niezwykle korzystne dla graczy korzystających z bardziej wymagających tytułów. Przykłady gier, które potrafią w pełni wykorzystać możliwości DDR5 to Cyberpunk 2077 czy Call of Duty: Warzone, gdzie wydajność pamięci jest kluczowym elementem w uzyskiwaniu płynności rozgrywki. Stosowanie DDR5 nie tylko poprawia wydajność, ale również zwiększa przyszłościowość sprzętu, co sprawia, że jest to najlepszy wybór na dzisiejszym rynku komputerów gamingowych.

Pytanie 29

Jakie jest zadanie interpretera?

A. wykonywanie skryptu krok po kroku
B. analiza składni całego programu przed jego uruchomieniem
C. tłumaczenie kodu na kod maszynowy
D. optymalizacja większej części kodu, aby przyspieszyć jego wykonanie
Zobacz, dlaczego niektóre odpowiedzi były błędne w przypadku interpretera. Przede wszystkim, optymalizacja kodu nie jest jego głównym zadaniem. Choć można powiedzieć, że interpreter czasem poprawia wydajność, to nie o to tutaj chodzi. I pamiętaj, tłumaczenie kodu na kod maszynowy to zadanie kompilatora. Kompilatory biorą cały program i przetwarzają go przed uruchomieniem, a interpreter działa trochę inaczej – wykonuje kod krok po kroku. Dlatego nie tworzy oddzielnego pliku do uruchomienia. Co więcej, mówiąc o analizie składni, to jasne, że interpreter to robi, ale nie jest to jego główny cel. Chodzi o to, żeby wykonać kod od razu, a nie analizować wszystko przed. Te różnice są ważne i pokazują, jak bardzo się różnią kompilatory od interpreterów oraz gdzie każdy z nich ma swoje miejsce.

Pytanie 30

W programie desktopowym stworzono rozwijaną listę oraz przypisano cztery funkcje do obsługi zdarzeń tej kontrolki. Jaki komunikat pojawi się po dokonaniu wyboru w tej liście?
W XAML (uproszczona wersja):

<ComboBox SelectionChanged="Funkcja1" DragEnter="Funkcja2"
    LostFocus="Funkcja3" KeyDown="Funkcja4">
</ComboBox>
W kodzie:
private void Funkcja1(object sender, SelectionChangedEventArgs e)
{
    MessageBox.Show("Zdarzenie 1");
}
private void Funkcja2(object sender, DragEventArgs e)
{
    MessageBox.Show("Zdarzenie 2");
}
private void Funkcja3(object sender, RoutedEventArgs e)
{
    MessageBox.Show("Zdarzenie 3");
}
private void Funkcja4(object sender, KeyEventArgs e)
{
    MessageBox.Show("Zdarzenie 4");
}
A. Zdarzenie 3
B. Zdarzenie 1
C. Zdarzenie 2
D. Zdarzenie 4
Wybrałeś dokładnie to, co trzeba. W tej sytuacji kluczowe jest rozpoznanie, że zdarzenie SelectionChanged jest wywoływane zawsze wtedy, gdy użytkownik wybierze inną pozycję z ComboBoxa. I to właśnie do tego zdarzenia przypisana jest metoda Funkcja1, która wyświetla komunikat "Zdarzenie 1". Trochę to wygląda niepozornie, ale SelectionChanged to jeden z najczęściej obsługiwanych eventów w aplikacjach desktopowych opartych na WPF czy UWP – praktycznie zawsze reagujemy na wybór użytkownika w kontrolkach ComboBox, ListBox albo nawet ListView. Z mojego doświadczenia wynika, że początkujący programiści często mylą to zdarzenie z innymi, jak LostFocus, które odpala się, gdy kontrolka traci fokus, albo z DragEnter (zupełnie inny przypadek, bo dotyczy przeciągania danych). Warto pamiętać, że KeyDown reaguje dopiero na naciśnięcie klawisza, a nie na wybór myszką. Takie rozróżnienie jest codziennością przy tworzeniu bardziej zaawansowanych interfejsów użytkownika. Praktyczna wskazówka: jeśli chcesz reagować na wybór użytkownika i np. ładować dodatkowe dane czy weryfikować coś po stronie aplikacji, to SelectionChanged jest strzałem w dziesiątkę. Standardy branżowe sugerują nie przesadzać z obsługą zbyt wielu eventów jednocześnie dla tej samej kontrolki, bo to może prowadzić do konfliktów i dziwnych zachowań UI. Mocno polecam samemu poeksperymentować – otworzyć Visual Studio, zrobić prostą aplikację WPF, podpiąć te eventy i zobaczyć, które kiedy się odpalają. Dzięki temu dużo szybciej utrwala się ta wiedza niż z samej teorii.

Pytanie 31

Do implementacji w aplikacji jednokierunkowej funkcji skrótu, zwanej funkcją haszującą, można wykorzystać algorytm

A. RSA
B. MD5
C. DES
D. AES
MD5 to przykład klasycznej funkcji skrótu, czyli właśnie tej funkcji, która generuje z dowolnie długych danych wejściowych stałej długości skrót (hash). Funkcje haszujące są szeroko stosowane w informatyce, szczególnie tam, gdzie potrzebna jest szybka weryfikacja integralności danych albo przechowywanie haseł w bazie danych w sposób bezpieczny (chociaż MD5 dziś już nie poleca się do haseł przez znane luki bezpieczeństwa – lepsze są SHA-256 czy bcrypt). To, co wyróżnia funkcje skrótu jak MD5, to ich jednokierunkowość: znając wynik, praktycznie nie jesteśmy w stanie odtworzyć oryginalnych danych wejściowych, a nawet minimalnie różniące się dane dają zupełnie inne hashe. Przykład praktyczny? Sprawdzenie sumy kontrolnej pliku po pobraniu z internetu – porównujemy hash MD5 z podanym na stronie wydawcy i mamy pewność, że plik nie został podmieniony. W praktyce branżowej, zgodnie z normami bezpieczeństwa jak np. ISO/IEC 27001, funkcje haszujące są podstawą wielu procesów kryptograficznych. Moim zdaniem, znajomość takich algorytmów jak MD5, nawet jeśli już nie jest zalecany w nowych systemach, to podstawa do zrozumienia ogólnego działania funkcji skrótu i różnicy między nimi a szyfrowaniem. Często spotykałem się z myleniem tych pojęć, więc warto to dobrze rozumieć.

Pytanie 32

Który z wymienionych dokumentów jest najczęściej stosowany w zarządzaniu pracą zespołu Scrum?

A. Diagram Gantta
B. Lista zasobów ludzkich
C. Product backlog
D. Specyfikacja techniczna
Diagram Gantta jest fajnym narzędziem do pokazywania harmonogramu, ale nie ma go w zarządzaniu backlogiem. Specyfikacja techniczna to co innego – tam są szczegóły implementacyjne, a nie priorytety funkcji. Lista zasobów ludzkich to temat o zarządzaniu personelem, a nie o zadaniach i priorytetach w Scrumie. Więc tu bardziej musisz uważać na to, co do czego pasuje.

Pytanie 33

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

A. Generowanie bibliotek dynamicznych dla programu
B. Tłumaczenie kodu źródłowego na język maszynowy w czasie rzeczywistym
C. Analiza struktury kodu przed tłumaczeniem
D. Tworzenie pliku wykonywalnego
Generowanie pliku wykonywalnego to proces związany z kompilacją, a nie interpretacją. Kompilator przekształca cały kod źródłowy na kod maszynowy przed uruchomieniem programu, co odróżnia go od interpretacji. Analiza struktury kodu przed tłumaczeniem odnosi się do statycznej analizy kodu, a nie jego wykonywania. Tworzenie bibliotek dynamicznych to etap łączenia (linkowania), który następuje po kompilacji lub interpretacji, ale nie jest częścią samej interpretacji kodu źródłowego.

Pytanie 34

Jaką funkcję pełni operator "|" w języku C++?

A. Bitowe "lub"
B. Operację przesunięcia bitów w prawo
C. Bitowe "xor"
D. Logiczne "lub"
Operator `|` w języku C++ jest operatorem bitowym `OR`, który porównuje bity dwóch liczb i zwraca `1` w pozycji bitu, jeśli przynajmniej jeden z odpowiadających sobie bitów jest `1`. Przykład: `5 | 3` (w notacji binarnej `0101 | 0011`) zwróci `0111`, co odpowiada liczbie `7`. Operatory bitowe są często używane w programowaniu systemowym, kryptografii oraz manipulacji danymi na poziomie bitowym.

Pytanie 35

Które z poniższych nie jest algorytmem sortowania?

A. Bubble Sort
B. Quick Sort
C. Merge Sort
D. Binary Search
Binary Search jest algorytmem, który służy do efektywnego przeszukiwania uporządkowanych zbiorów danych, a nie do sortowania. Działa na zasadzie dzielenia zbioru na pół i eliminowania połowy z nich w każdym kroku, co pozwala na szybkie znalezienie poszukiwanej wartości. Jest to przykład algorytmu o czasie działania O(log n), co sprawia, że jest znacznie szybszy od prostego przeszukiwania liniowego. Przykładowo, gdy mamy posortowaną tablicę liczb, Binary Search może być użyty do znalezienia konkretnej liczby, eliminując w każdym kroku połowę zbioru, aż do odnalezienia wartości lub stwierdzenia, że jej nie ma. W kontekście branżowym, Binary Search jest szeroko stosowany w różnych aplikacjach, gdzie wymagane jest szybkie przeszukiwanie danych, na przykład w bazach danych i aplikacjach wyszukiwania. Kluczowe jest zrozumienie różnicy między algorytmem przeszukiwania a algorytmem sortowania; sortowanie odnosi się do organizacji danych w określonym porządku, podczas gdy Binary Search koncentruje się na znajdowaniu elementów w już posortowanych zbiorach.

Pytanie 36

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

Pytanie 37

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

A. Systematycznie aktualizować oprogramowanie i wykonywać kopie zapasowe
B. Nie używać kopii zapasowych
C. Dzielić się hasłami do plików z współpracownikami
D. Przechowywać dane na niezabezpieczonych nośnikach przenośnych
Regularne aktualizowanie oprogramowania oraz tworzenie kopii zapasowych to kluczowe działania zapewniające bezpieczeństwo danych na komputerze. Aktualizacje łatają luki w zabezpieczeniach i eliminują błędy, które mogą zostać wykorzystane przez hakerów. Kopie zapasowe chronią dane przed utratą spowodowaną awarią sprzętu, atakiem ransomware lub przypadkowym usunięciem. Najlepszą praktyką jest przechowywanie kopii zapasowych w różnych miejscach – lokalnie i w chmurze – co dodatkowo zwiększa poziom zabezpieczenia przed nieprzewidzianymi sytuacjami.

Pytanie 38

Wskaż algorytm sortowania, który nie jest stabilny?

A. sortowanie szybkie
B. sortowanie przez wstawianie
C. sortowanie bąbelkowe
D. sortowanie przez zliczanie
Często podczas nauki algorytmów sortowania pojawia się zamieszanie na temat stabilności. Stabilność w sortowaniu oznacza, że elementy o tych samych kluczach nie zmieniają swojego wzajemnego położenia. W przypadku sortowania bąbelkowego, przez wstawianie i przez zliczanie – wszystkie te techniki są z natury stabilne, o ile ich standardowa implementacja nie została zmodyfikowana. To dość wygodne, bo gdy pracujemy z bardziej złożonymi danymi, np. obiektami z wieloma polami, stabilność pozwala zachować dodatkowe informacje przy kolejnych sortowaniach. Wielu jednak mylnie zakłada, że wszystkie szybkie algorytmy (jak Quick Sort) są stabilne, bo po prostu są bardziej zaawansowane. Niestety, to nie jest prawda – podstawowy Quick Sort nie zachowuje kolejności równych elementów i w praktyce może zamieszać nam w porządku danych. To jest błąd myślowy, który widzę często nawet u doświadczonych programistów. Sortowanie przez zliczanie (Counting Sort) jest stabilne, ponieważ dla każdego elementu dokładnie wiemy, na które miejsce ma trafić i w razie kolizji zawsze wybieramy ten, który był wcześniej. Podobnie klasyczne sortowanie bąbelkowe i przez wstawianie – oba algorytmy podczas przemieszczania elementów nie przestawiają tych samych wartości względem siebie. Moim zdaniem, właśnie ta stabilność jest często niedoceniana w codziennej pracy, a bywa naprawdę kluczowa przy pracy z danymi złożonymi. Warto zawsze, zanim wybierzemy algorytm sortowania, zastanowić się, czy zależy nam na tym, by zachować oryginalną kolejność dla równych wartości – wtedy zdecydowanie lepiej sięgnąć po stabilne podejście, zamiast używać np. Quick Sort. To nie jest tylko teoria, ale praktyczna wskazówka z życia programistycznego.

Pytanie 39

Co to jest dependency injection w programowaniu?

A. Proces kompilacji kodu źródłowego do kodu maszynowego
B. Technika, w której obiekt otrzymuje inne obiekty, od których zależy
C. Metoda optymalizacji zapytań do bazy danych
D. Metoda projektowania interfejsu użytkownika
Dependency injection (DI) to technika programowania, która polega na dostarczaniu obiektom ich zależności z zewnątrz, zamiast tworzenia ich samodzielnie wewnątrz klasy. Dzięki temu kod staje się bardziej modularny, łatwiejszy do testowania i utrzymania. Przykładem zastosowania DI jest framework Spring w języku Java, który umożliwia zarządzanie zależnościami za pomocą kontenerów IoC (Inversion of Control). Korzyści płynące z używania DI obejmują zwiększenie elastyczności oraz ułatwienie wprowadzania zmian w kodzie, ponieważ zmiany w jednej klasie nie wymagają modyfikacji innych. DI wspiera zasady SOLID, szczególnie zasadę odwrócenia zależności (Dependency Inversion Principle), co prowadzi do bardziej przejrzystego i zrozumiałego kodu. W praktyce, implementacja DI może odbywać się za pomocą konstruktorów, setterów lub interfejsów, co daje programiście wybór w doborze najodpowiedniejszej metody dla danego projektu.

Pytanie 40

Jakie działania należy podjąć, aby uniknąć nieskończonej rekurencji w danej funkcji?

A. Zastosować iterację zamiast rekurencji
B. Wykorzystać automatyczny debugger w kompilatorze
C. Dodać warunek zakończenia w funkcji
D. Rozszerzyć zakres zmiennych globalnych
Warunek stopu to taki kluczowy element w rekurencji, który właściwie mówi, kiedy funkcja powinna przestać się wywoływać. Jak masz ten warunek, to funkcja wraca z wynikiem zamiast kręcić się w kółko, co mogłoby prowadzić do jakiegoś szaleństwa, tzn. przepełnienia stosu. Myślę, że warto zwrócić uwagę, że dodanie tego warunku to naprawdę podstawowa sprawa w programowaniu, bo bez niego wszystko może się posypać i przestanie działać tak, jak powinno.