Wyniki egzaminu

Informacje o egzaminie:
  • Zawód: Technik programista
  • Kwalifikacja: INF.04 - Projektowanie, programowanie i testowanie aplikacji
  • Data rozpoczęcia: 2 lipca 2026 18:34
  • Data zakończenia: 2 lipca 2026 18:49

Egzamin zdany!

Wynik: 29/40 punktów (72,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

Ergonomiczną oraz właściwą pozycję do pracy przy komputerze zapewni fotel, którego

A. podłokietniki znajdują się 20 cm poniżej blatu
B. oparcie wspiera lordozę w dolnym odcinku pleców
C. podłokietniki są 30 cm powyżej blatu
D. oparcie w rejonie szyi jest nachylone do przodu o 40ᵒ
Prawidłowa i ergonomiczna pozycja pracy przy komputerze jest kluczowa dla zdrowia i komfortu użytkownika. Oparcie krzesła, które zapewnia lordozę w odcinku lędźwiowym, jest niezbędne, ponieważ pozwala na zachowanie naturalnej krzywizny kręgosłupa. Lordoza lędźwiowa to naturalne wygięcie kręgosłupa w dolnej części pleców, które wspiera prawidłowe ułożenie ciała podczas siedzenia. Krzesło powinno być zaprojektowane tak, aby oparcie przylegało do krzywizny ciała, co minimalizuje ryzyko bólu pleców oraz przeciążeń. Praktycznym przykładem ergonomicznej pozycji jest ustawienie oparcia w taki sposób, aby jego dolna część była dostosowana do odcinka lędźwiowego. Zgodnie z normami ISO 9241, które dotyczą ergonomii miejsc pracy przy komputerze, krzesło powinno umożliwiać użytkownikowi przyjęcie wygodnej pozycji z podparciem dla dolnej części pleców. W odpowiedniej pozycji stopy powinny spoczywać płasko na podłodze, a kolana powinny być na poziomie bioder, co wspiera prawidłowe krążenie krwi oraz redukuje napięcia mięśniowe.

Pytanie 2

W zaprezentowanym kodzie ukazano jedno z fundamentalnych założeń programowania obiektowego. Czym ono jest?

public class Owoc {
}

public class Truskawka extends Owoc {
}

public class Jablko extends Owoc {
}
Ilustracja do pytania
A. polimorfizm
B. dziedziczenie
C. abstrakcja
D. hermetyzacja
To właśnie jest klasyczny przykład dziedziczenia w programowaniu obiektowym. W tym przypadku mamy bazową klasę 'Owoc', z której dziedziczą klasy 'Truskawka' oraz 'Jablko'. Dzięki temu możemy zdefiniować wspólne cechy i zachowania dla wszystkich owoców w jednej klasie, a potem rozszerzać je w bardziej szczegółowych klasach. Moim zdaniem to jedno z najwygodniejszych założeń OOP, bo pozwala pisać kod, który jest łatwiejszy do utrzymania i rozbudowy. Jeśli kiedyś dołożysz nową funkcjonalność do wszystkich owoców, nie musisz jej wrzucać oddzielnie do każdej odmiany, tylko wystarczy, że zrobisz to raz w klasie 'Owoc'. To bardzo zgodne ze standardami SOLID i ogólnie dobrą praktyką DRY (Don't Repeat Yourself). W realnych aplikacjach, np. systemach do zarządzania magazynem, dziedziczenie pozwala łatwo rozróżnić typy produktów, a jednocześnie trzymać wspólny kod w jednym miejscu. Warto też pamiętać, że dziedziczenie to podstawa do późniejszego korzystania z polimorfizmu. Jeśli chcesz, żeby jakieś metody działały różnie w zależności od konkretnego typu owocu, wystarczy je nadpisać w podklasach. W sumie – nie da się pisać sensownych aplikacji obiektowych bez znajomości dziedziczenia, bo to daje ogromną elastyczność i porządek w kodzie.

Pytanie 3

W przedstawionym filmie ukazano kreator interfejsu użytkownika, dla którego automatycznie powstaje

A. obsługa wciśniętego przycisku
B. kod XML
C. kod Java
D. obsługa przycisku ekranu dotykowego
Kod XML jest obecnie najczęściej stosowanym formatem do definiowania wyglądu interfejsów użytkownika w takich narzędziach jak Android Studio czy różnego rodzaju designery graficzne. Kiedy projektujesz layout aplikacji mobilnej albo desktopowej, duża część nowoczesnych narzędzi tworzy właśnie pliki XML, które następnie są interpretowane przez system w czasie uruchamiania aplikacji. Ułatwia to rozdzielenie logiki aplikacji od jej prezentacji, co wydaje się fundamentalne przy większych projektach. Moim zdaniem takie podejście daje ogromne korzyści – można łatwo modyfikować wygląd bez dotykania kodu źródłowego. W praktyce, jeśli używasz np. Android Studio, zbudujesz interfejs przeciągając przyciski czy pola tekstowe, a pod spodem dostaniesz czytelny plik XML. To przyspiesza pracę, zwiększa czytelność projektu i pozwala na późniejsze automatyczne generowanie dokumentacji albo testów interfejsu. Takie standardy są rekomendowane nie tylko przez Google, ale też szeroko stosowane w innych środowiskach, jak chociażby XAML w Microsoft czy FXML w JavaFX. Przezroczystość działania tych narzędzi sprawia, że łatwiej jest pracować zespołowo, bo każdy może szybko zorientować się w strukturze UI patrząc na XML-a. Samo generowanie kodu XML przez narzędzia graficzne to duży krok w kierunku lepszej organizacji pracy i zgodności ze współczesnymi praktykami branżowymi.

Pytanie 4

Jakie pola powinny być umieszczone w klasie nadrzędnej w strukturze dziedziczenia?

A. Pola, które są wspólne dla wszystkich klas pochodnych
B. Pola, które są charakterystyczne jedynie dla pojedynczej klasy pochodnej
C. Pola, które są tylko prywatne
D. Pola, które są wykorzystywane tylko w funkcjach statycznych
W klasie bazowej w hierarchii dziedziczenia umieszcza się pola, które są wspólne dla wszystkich klas pochodnych. Dzięki temu klasy pochodne mogą dziedziczyć te same właściwości, co eliminuje konieczność ich wielokrotnego definiowania. Jest to jedna z głównych zalet programowania obiektowego, umożliwiająca reużywalność kodu i zwiększenie spójności w projekcie. Przykładem może być klasa 'Pracownik', która zawiera pola takie jak 'imię', 'nazwisko' i 'wynagrodzenie', a klasy pochodne, takie jak 'Inżynier' czy 'Księgowy', mogą dziedziczyć te same pola, dodając jedynie specyficzne właściwości dla swojej roli.

Pytanie 5

Jakie są główne cechy architektury klient-serwer?

A. Serwer pełni rolę pasywnego odbiorcy danych od klientów
B. Każdy klient funkcjonuje niezależnie od pozostałych
C. Dane są przechowywane i przetwarzane na serwerze, a klient wysyła żądania i odbiera odpowiedzi
D. Komunikacja odbywa się bezpośrednio między urządzeniami klienckimi
Architektura klient-serwer to model, w którym dane są przechowywane i przetwarzane na serwerze, a klient wysyła żądania i odbiera odpowiedzi. Model ten umożliwia centralizację zasobów, co prowadzi do łatwiejszego zarządzania aplikacjami i zwiększonego bezpieczeństwa. Klient-serwer jest podstawą działania aplikacji webowych, usług sieciowych oraz baz danych. Dzięki temu architektura ta umożliwia wielu użytkownikom jednoczesny dostęp do tych samych danych, co czyni ją wydajnym rozwiązaniem dla rozproszonych systemów informatycznych. Serwery mogą obsługiwać różne rodzaje klientów, takie jak przeglądarki, aplikacje mobilne czy urządzenia IoT, co sprawia, że jest to wszechstronny model stosowany w wielu branżach.

Pytanie 6

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. inicjacji elementów interfejsu użytkownika
B. aplikacji po wystąpieniu zdarzenia utraty fokusu przez pole opcji
C. naciśnięcia przycisku zatwierdzającego dialog
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 7

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

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

Pytanie 8

Dziedziczenie jest używane, gdy zachodzi potrzeba

A. sformułowania klasy bardziej szczegółowej niż już stworzona
B. wykorzystania stałych wartości, niezmieniających się w trakcie działania aplikacji
C. określenia zasięgu dostępności metod i pól danej klasy
D. asynchronicznej realizacji długotrwałych zadań
Dziedziczenie to naprawdę jeden z kluczowych fundamentów programowania obiektowego. Chodzi tu o możliwość stworzenia nowej klasy (tzw. klasy pochodnej), która rozszerza lub precyzuje działanie już istniejącej klasy bazowej. Dzięki temu nie trzeba pisać wszystkiego od nowa – można po prostu przejąć cechy i zachowania ogólnej klasy, a potem dołożyć własne, bardziej szczegółowe funkcjonalności. Przykład? Klasa "Pojazd" może być ogólna, a potem robisz z niej "Samochód", "Rower" czy "Motocykl". Każda z tych klas dziedziczy podstawowe właściwości pojazdu (jak np. liczba kół), ale może mieć swoje dodatkowe pole czy metodę. W praktyce to pozwala na bardzo elastyczne i czytelne projektowanie kodu, no i łatwiejsze zarządzanie nim na dłuższą metę. Według większości standardów branżowych, np. w językach Java, C# czy C++, dziedziczenie jest zalecane właśnie wtedy, gdy chcesz odwzorować relację „jest rodzajem” (is-a). Z mojego doświadczenia, używanie dziedziczenia według tej zasady pozwala uniknąć wielu problemów z powielaniem kodu i z czasem naprawdę oszczędza mnóstwo roboty. Warto pamiętać, że nie wszystko należy dziedziczyć na siłę – czasem lepiej postawić na kompozycję, ale jeśli faktycznie potrzebujesz klasy bardziej szczegółowej, to dziedziczenie to chyba najlepszy wybór.

Pytanie 9

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

<Windows Title="Tekst"...>
Fragment kodu w Java:
public class Okno extends JFrame {
    ...
    public Okno() {
        super();
        this.setTitle("Tekst");
    }
    ...
A. przypisanie nazwy obiektu obrazującego okno aplikacji
B. ustawienie tytułu okna na "Tekst"
C. zapisanie tytułu okna do obiektu Tekst
D. uzyskanie nazwy obiektu obrazującego okno aplikacji
Wybrana odpowiedź dokładnie oddaje sens działania kodu zarówno w WPF/XAML, jak i w Javie z użyciem JFrame. W jednym i drugim przypadku chodzi o ustawienie tytułu okna aplikacji, czyli tego tekstu, który pojawia się na pasku tytułowym okienka po uruchomieniu programu. Z mojego doświadczenia, jest to jedna z pierwszych rzeczy, jakie użytkownicy widzą w każdej aplikacji okienkowej, więc warto pamiętać, jak ją ustawić. W WPF właściwość Title w tagu Window służy właśnie do wyświetlenia krótkiego opisu albo nazwy programu. Z kolei w Javie metoda setTitle pozwala dynamicznie przypisywać tekst, co jest bardzo przydatne przy pisaniu aplikacji z wieloma oknami albo zmieniającym się stanem (np. można dodać tam nazwę pliku, z którym pracujemy). Branżowe standardy zachęcają do tego, żeby tytuły okien były krótkie, jednoznaczne i faktycznie informowały użytkownika o funkcji aktualnego widoku. Co ciekawe, w niektórych frameworkach można nawet dodać ikonę do tego paska tytułowego. Samo ustawienie tytułu nie zmienia żadnych właściwości obiektu aplikacji poza tym, jak jest widoczny dla użytkownika. To mały detal, ale bardzo ważny w codziennej pracy programisty interfejsów graficznych.

Pytanie 10

Jaki modyfikator umożliwia dostęp do elementu klasy z każdego miejsca w kodzie?

A. Private
B. Public
C. Protected
D. Static
Modyfikator 'Public' umożliwia dostęp do składowych klasy z dowolnego miejsca w programie, zarówno w ramach tej samej klasy, jak i poza nią. To najbardziej otwarty modyfikator dostępu, który pozwala na tworzenie interfejsów API, umożliwiających korzystanie z publicznych metod i właściwości przez inne klasy oraz moduły. W praktyce oznacza to, że publiczne metody są widoczne globalnie, co pozwala na ich wywoływanie bez ograniczeń. Jest to przydatne w przypadkach, gdy dana funkcjonalność musi być dostępna w różnych częściach programu lub aplikacji.

Pytanie 11

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

A. splice()
B. sort()
C. map()
D. push()
Wybór metod, które modyfikują oryginalną tablicę w JavaScript, może prowadzić do nieporozumień, szczególnie dla osób rozpoczynających przygodę z tym językiem programowania. Metody takie jak splice(), sort() czy push() wprowadzają zmiany w oryginalnych danych, co może skutkować niezamierzonymi efektami ubocznymi. Na przykład, splice() jest używane do usuwania lub dodawania elementów w tablicy, co bezpośrednio zmienia jej strukturę. Z kolei sort() zmienia kolejność elementów w tablicy na podstawie kryteriów porównania, co może prowadzić do utraty dotychczasowego porządku, jeśli oryginalna tablica jest nadal potrzebna w jej pierwotnej formie. Push() natomiast dodaje nowe elementy na końcu tablicy, co zwiększa jej długość oraz może wpłynąć na logikę aplikacji, jeżeli elementy są wykorzystywane w innych częściach kodu. Te metody mogą prowadzić do typowych błędów myślowych, takich jak założenie, że operacje na danych są statyczne i nie wpływają na ich oryginalne formy. Dlatego w praktyce programistycznej, szczególnie w większych i bardziej złożonych projektach, istotne jest, aby być świadomym, jakie metody wpływają na oryginalne dane, aby uniknąć przypadkowych błędów oraz nieprzewidzianych konsekwencji. Używanie funkcji, które nie zmieniają oryginalnej tablicy, takich jak map(), cieszy się dużą popularnością i jest zgodne z najlepszymi praktykami w programowaniu funkcyjnym.

Pytanie 12

Jaką wartość zwróci poniższa funkcja dla argumentu n = 5?

function silnia(n) {
  if (n <= 1) return 1;
  return n * silnia(n - 1);
}
A. 60
B. 24
C. 5
D. 120
Funkcja silnia(n) oblicza wartość silni z liczby n, co jest matematyczną operacją polegającą na mnożeniu wszystkich liczb całkowitych dodatnich od 1 do n. Dla argumentu n = 5, obliczamy silnię w następujący sposób: silnia(5) = 5 * silnia(4). Następnie, silnia(4) = 4 * silnia(3), a silnia(3) = 3 * silnia(2), gdzie silnia(2) = 2 * silnia(1), a silnia(1) zwraca 1, ponieważ jest to warunek bazowy. Teraz możemy podstawić wartości: silnia(2) = 2 * 1 = 2, silnia(3) = 3 * 2 = 6, silnia(4) = 4 * 6 = 24, a na końcu silnia(5) = 5 * 24 = 120. Tak więc, wartość zwrócona przez funkcję dla n = 5 to 120. W praktyce, obliczanie silni jest przydatne w różnych dziedzinach, takich jak kombinatoryka, statystyka czy analiza danych. Zrozumienie tej koncepcji jest kluczowe w programowaniu, ponieważ często wykorzystuje się rekurencję do rozwiązywania problemów, które można podzielić na mniejsze podproblemy. Korzystając z rekurencyjnych funkcji, warto pamiętać o podstawowych warunkach, które kończą wywołania rekurencyjne, aby uniknąć nieskończonych pętli.

Pytanie 13

Jaki typ testów ocenia funkcjonalność aplikacji z punktu widzenia użytkownika końcowego?

A. Testy zgodności
B. Testy użyteczności
C. Testy funkcjonalne
D. Testy obciążeniowe
Testy obciążeniowe skupiają się na sprawdzaniu, jak aplikacja działa pod dużym ruchem lub obciążeniem, co pozwala ocenić jej wydajność, ale nie dotyczy to bezpośrednio doświadczeń użytkownika. Testy funkcjonalne mają na celu sprawdzenie, czy poszczególne funkcje aplikacji działają zgodnie z założeniami, ale nie badają wygody użytkowania. Testy zgodności natomiast weryfikują, czy aplikacja spełnia określone normy i standardy, co ma niewiele wspólnego z oceną użyteczności aplikacji przez użytkownika końcowego.

Pytanie 14

Który element HTML5 służy do wyświetlania zawartości video?

A. <video>
B. <film>
C. <play>
D. <media>
Element HTML5 <video> jest kluczowym składnikiem do wyświetlania treści wideo w przeglądarkach. Dzięki niemu można łatwo osadzić filmy na stronach internetowych, co sprawia, że są one bardziej interaktywne i atrakcyjne dla użytkowników. Przykład użycia tego tagu wygląda następująco: <video src='film.mp4' controls></video>. Atrybut 'controls' pozwala na dodanie prostych przycisków odtwarzania, pauzy i regulacji głośności, co znacząco poprawia doświadczenia użytkownika. Warto również wspomnieć, że element <video> wspiera różne formaty wideo, takie jak MP4, WebM czy Ogg, co jest istotne w kontekście zgodności z różnymi przeglądarkami i urządzeniami. W praktyce, stosowanie <video> pozwala na łatwe zarządzanie wideo, w tym na dodawanie napisów, ustawienie automatycznego odtwarzania czy loopowania. To sprawia, że jest on niezwykle popularny w tworzeniu nowoczesnych stron internetowych, które chcą dostarczać wartościowe multimedia. Zastosowanie tego elementu jest zgodne z najlepszymi praktykami w zakresie dostępności i użyteczności, co czyni go niezwykle ważnym w dzisiejszym web development.

Pytanie 15

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

String a = "hello";
String b = "hello";
String c = new String("hello");
System.out.println(a == b);
System.out.println(a == c);
System.out.println(a.equals(c));
A. false, false, true
B. true, true, true
C. true, false, false
D. true, false, true
Wynik działania kodu to true, false, true. Pierwsza linia kodu, gdzie porównujemy zmienne 'a' i 'b' przy użyciu operatora '==', zwraca true, ponieważ obie zmienne wskazują na ten sam obiekt w pamięci, co jest efektem optymalizacji JVM dla literałów typu String. W przypadku drugiej linii, gdzie porównujemy 'a' i 'c', wynik to false, ponieważ 'c' to nowy obiekt utworzony przy pomocy operatora 'new', a więc ma inną referencję w pamięci. W trzeciej linii używamy metody 'equals()', która porównuje wartości obiektów, a nie ich referencje. W tym przypadku porównywane są wartości stringów i ponieważ wszystkie mają tę samą treść, wynik to true. Zrozumienie różnicy między operatorem '==' a metodą 'equals()' jest kluczowe w programowaniu w Javie. Przy pracy z obiektami, zawsze warto stosować 'equals()' do porównywania zawartości, aby uniknąć nieporozumień związanych z referencjami."

Pytanie 16

Który element dokumentacji technicznej jest istotny dla ustalenia metod ochrony danych w aplikacji?

A. Harmonogram zarządzania zadaniami
B. System ochrony aplikacji
C. Koncepcja interfejsu użytkownika
D. Opis architektury klient-serwer
Plan zarządzania zadaniami koncentruje się na harmonogramie i podziale pracy, ale nie odnosi się do ochrony danych. Opis architektury klient-serwer dotyczy modelu komunikacji między aplikacją a serwerem, ale nie precyzuje mechanizmów zabezpieczeń. Projekt interfejsu użytkownika jest kluczowy dla doświadczeń użytkowników, ale nie obejmuje bezpośrednich mechanizmów ochrony danych i aplikacji, które są uwzględniane w specyfikacji systemu zabezpieczeń.

Pytanie 17

W języku C# szablon List zapewnia funkcjonalność listy. Z tworzenia obiektu typu List wynika, że jego składnikami są:

List<int> wykaz = new List<int>();
A. liczby całkowite
B. elementy o nieokreślonym typie
C. liczby rzeczywiste
D. elementy typu List
Szablon List<int> w języku C# implementuje listę, której elementami są liczby całkowite. Jest to przykład zastosowania kolekcji generycznych, które wprowadzają typowanie silne w czasie kompilacji, co pozwala na uniknięcie błędów typowych dla kolekcji niegenerycznych. Definiując List<int> deklarujesz, że lista będzie przechowywać tylko liczby całkowite. Dzięki temu kompilator może wykrywać błędy związane z typowaniem już podczas pisania kodu, co zwiększa jego niezawodność i bezpieczeństwo. Typ generyczny T w List<T> umożliwia tworzenie kolekcji przechowujących dowolny typ, co ułatwia ponowne wykorzystanie kodu i zgodność z zasadą DRY (Don't Repeat Yourself). W praktyce List<int> jest szeroko stosowany w scenariuszach wymagających dynamicznie rozwijanych kolekcji, które nie ograniczają się do statycznej liczby elementów, takich jak tablice. Listy generyczne są wydajniejsze i bardziej elastyczne dzięki metodom takim jak Add, Remove czy Contains, które operują na elementach określonego typu. Dzięki implementacji IEnumerable/Listy są również zgodne z LINQ, co umożliwia stosowanie złożonych zapytań i operacji na danych, takich jak filtrowanie i sortowanie, w sposób czytelny i efektywny.

Pytanie 18

Reguła zaangażowania i konsekwencji jako jedna z zasad wpływania na innych odnosi się

A. do odwzajemniania się osobie, która nam pomogła
B. do kierowania się zdaniem danej grupy
C. do doprowadzania spraw do końca
D. do uległości wobec autorytetów
Reguła zaangażowania i konsekwencji, o której tu mowa, faktycznie odnosi się do potrzeby doprowadzania spraw do końca. To jedna z podstawowych zasad psychologicznych wykorzystywanych w wpływaniu na decyzje i zachowania ludzi, szczególnie w sprzedaży czy negocjacjach. Kiedy już się na coś zgodzimy lub podejmiemy pierwsze, nawet drobne zobowiązanie, automatycznie pojawia się w nas silna potrzeba zachowania spójności z wcześniejszymi deklaracjami — tak po prostu działa ludzka psychika. Z mojego doświadczenia wynika, że firmy bardzo często to wykorzystują, np. prosząc klienta o drobną przysługę, podpis czy mikroakceptację, bo potem jest większa szansa, że pójdzie za ciosem i zdecyduje się na większy krok. W psychologii społecznej ten mechanizm uznaje się za bardzo skuteczny – zresztą Robert Cialdini w swoich książkach szeroko o tym pisze. Na rynku pracy też to widać, bo pracodawcy chętniej powierzają ważne zadania osobom, które mają zwyczaj kończyć to, co zaczęły. W praktyce, jeśli ktoś raz się w coś zaangażuje — nawet formalnie nie podpisując żadnej umowy — to potem z dużym prawdopodobieństwem wytrwa przy swojej decyzji. Dlatego znajomość tej zasady jest nie tylko teoretycznie ciekawa, ale daje konkretne narzędzia do skuteczniejszego działania w relacjach międzyludzkich, marketingu czy zarządzaniu projektami.

Pytanie 19

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

A. jest większa niż złożoność sortowania bąbelkowego
B. jest zawsze mniejsza niż złożoność jakiegokolwiek innego algorytmu sortowania
C. jest większa niż O(n2)
D. jest różna w zależności od wyboru elementu dzielącego
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 20

Po wykonaniu poniższego kodu na konsoli zostanie wyświetlona liczba:

int a = 0x73;
cout << a;
A. 0
B. 115
C. 108
D. 73
Wartość 0x73 w kodzie oznacza liczbę zapisaną w systemie szesnastkowym (heksadecymalnym). To bardzo często wykorzystywana notacja w programowaniu, szczególnie gdy pracuje się z pamięcią, kodowaniem kolorów lub niskopoziomową obsługą sprzętu. 0x73 to po prostu 7 * 16 + 3, co daje 115 w systemie dziesiętnym. Gdy taki zapis przekażesz do cout, kompilator automatycznie prezentuje tę wartość jako liczbę w systemie dziesiętnym, czyli właśnie 115. Szczerze mówiąc, moim zdaniem warto jak najczęściej ćwiczyć odczytywanie i zamianę wartości pomiędzy systemami liczbowymi, bo to się naprawdę przydaje przy analizie kodu, debugowaniu czy choćby rozumieniu dokumentacji technicznej. Taka umiejętność jest praktycznie niezbędna w embedded, ale i w zwykłym C++ można czasem natknąć się na takie zapisy – szczególnie w kodzie legacy. Osobiście uważam, że dobrze od razu rozpoznawać takie zapisy i nie tracić czasu na kalkulatory. Warto też pamiętać, że podobnie działają inne systemy: np. 0b1101 to binarny, a 0x to zawsze heksadecymalny. W standardzie C++ zapis z prefiksem 0x jest w pełni poprawny i zalecany przy pracy z wartościami bitowymi. Fajnie, jak ktoś łapie takie rzeczy od razu, bo później w pracy nad większymi projektami to ogromne ułatwienie.

Pytanie 21

Jaką strukturę danych stosuje się w algorytmie BFS (przeszukiwanie wszerz)?

A. Kolejka
B. Tablica
C. Graf
D. Zbiór
Stos jest używany w algorytmie DFS (przeszukiwanie w głąb), a nie w BFS, ponieważ DFS eksploruje możliwie najgłębiej dany graf, zanim wróci do poprzedniego poziomu. Lista jest używana jako struktura ogólnego przeznaczenia, ale nie jest podstawowym narzędziem w algorytmie BFS. Drzewa są strukturą danych, którą BFS może przeszukiwać, ale sama struktura drzewa nie jest narzędziem używanym w algorytmie BFS – to kolejka pełni tę funkcję, przechowując wierzchołki do odwiedzenia.

Pytanie 22

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

function Person(name) {
  this.name = name;
}

Person.prototype.sayHello = function() {
  return `Hello, ${this.name}!`;
};

const person = new Person('John');
console.log(person.sayHello());
A. Hello, John!
B. Hello, undefined!
C. TypeError: person.sayHello is not a function
D. Hello, [object Object]!
Wynik działania podanego kodu to 'Hello, John!'. Dzieje się tak, ponieważ tworzony jest obiekt 'person' z konstruktora 'Person', który przypisuje wartość 'John' do właściwości 'name'. Metoda 'sayHello' zdefiniowana w prototypie klasy 'Person' wykorzystuje szablon literowy (template literal), aby zwrócić powitanie, wstawiając wartość 'name' obiektu. To podejście jest zgodne z dobrymi praktykami programowania w JavaScript, ponieważ wykorzystuje prototypy do dzielenia się metodami pomiędzy instancjami obiektów. W praktyce, takie rozwiązania pozwalają na oszczędność pamięci i zwiększają wydajność, gdyż wszystkie instancje korzystają z tej samej metody, a nie mają osobnych kopii. Przykładowo, jeśli chcielibyśmy dodać więcej osób, wystarczy utworzyć nowe instancje 'Person' bez konieczności powielania kodu metody 'sayHello'.

Pytanie 23

Która z wymienionych właściwości odnosi się do klasy pochodnej?

A. Nie ma możliwości dodawania nowych metod
B. Nie może być zastosowana w strukturze dziedziczenia
C. Jest automatycznie usuwana po zakończeniu działania programu
D. Dziedziczy atrybuty i metody z klasy bazowej
Stwierdzenie, że klasa pochodna nie może dodawać nowych metod, jest błędne – klasy pochodne mogą dodawać nowe metody, które rozszerzają funkcjonalność klasy bazowej. Automatyczne usuwanie klasy po zakończeniu programu dotyczy obiektów klasy, a nie samej klasy – za usuwanie obiektów odpowiada destruktor. Klasa, która nie może być używana w hierarchii dziedziczenia, to klasa oznaczona jako 'final' (w C++) lub 'sealed' (w C#), ale standardowe klasy pochodne nie mają tego ograniczenia, chyba że zostanie to jawnie zadeklarowane.

Pytanie 24

Zawarty w ramce opis licencji sugeruje, że mamy do czynienia z licencją

Rodzaj licencji, który zapewnia otwarty dostęp do oprogramowania dla wszystkich użytkowników programu, którego dotyczy: prawo do darmowego użytkowania, kopiowania, rozpowszechniania oraz tworzenia modyfikacji, ulepszania i rozbudowania.
A. Shareware
B. Open Source
C. OEM
D. Freeware
Opis podany w pytaniu idealnie pasuje do koncepcji licencji Open Source. W praktyce oznacza to, że każdy użytkownik ma nie tylko prawo korzystać z oprogramowania za darmo, ale także może pobierać kod źródłowy, analizować go, modyfikować, ulepszać i nawet udostępniać dalej własne warianty. To daje ogromne możliwości rozwoju – nie tylko dla pojedynczych programistów, lecz przede wszystkim dla całych społeczności, które budują narzędzia i rozwiązania dużo szybciej niż zamknięte firmy. Przykłady? Linux, GIMP, LibreOffice, czy nawet przeglądarka Firefox. Moim zdaniem, to jest wręcz fundament nowoczesnego IT – wiele firm (nawet tych największych, typu Google czy Microsoft) opiera się dziś na rozwiązaniach Open Source, bo to daje elastyczność, bezpieczeństwo i transparentność. Branżowe standardy, np. licencja GNU GPL lub MIT, jasno określają zasady współdzielenia i ochrony praw autorskich. Dobra praktyka to zawsze sprawdzić warunki licencji przed wdrożeniem projektu w firmie albo szkole. Fajnie jest też pamiętać, że Open Source to nie tylko darmowość, ale przede wszystkim filozofia dzielenia się wiedzą, co w informatyce często prowadzi do innowacji i lepszej jakości kodu.

Pytanie 25

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

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

Pytanie 26

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

A. componentDidMount()
B. componentWillUnmount()
C. componentDidUpdate()
D. componentWillPublish()
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 jakim etapie cyklu życia projektu tworzony jest szczegółowy opis wymagań funkcjonalnych oraz niefunkcjonalnych?

A. Analiza
B. Weryfikacja
C. Wdrożenie
D. Planowanie
Etap analizy to kluczowy moment w cyklu życia projektu, gdy powstaje szczegółowy opis wymagań funkcjonalnych i niefunkcjonalnych. W praktyce, właśnie wtedy zbierane są wszelkie informacje od interesariuszy – klient opowiada, czego oczekuje, a zespół projektowy zadaje mnóstwo pytań, by naprawdę zrozumieć potrzeby. Moim zdaniem to najważniejsza faza, bo jeśli coś pójdzie nie tak na tym etapie, to cała reszta projektu może się sypnąć. Analiza wymagań to nie tylko spisanie kilku zdań – tu trzeba dokładnie określić, co system ma robić (czyli funkcjonalności, np. użytkownik może dodać produkt do koszyka), oraz jakie ma mieć cechy pozafunkcjonalne, jak wydajność czy bezpieczeństwo. Dobre praktyki, jak np. BABOK czy normy ISO/IEC 29148, podkreślają, że precyzyjna analiza wymagań pozwala uniknąć kosztownych poprawek na późniejszych etapach. W rzeczywistych projektach IT korzysta się często z narzędzi typu diagramy przypadków użycia, user stories albo specyfikacje wymagań – wszystko po to, żeby nie było niejasności. Uczciwie powiem, że im więcej czasu i uwagi poświęci się na analizę, tym mniej niespodzianek pojawi się dalej. Warto to mieć na uwadze.

Pytanie 28

Który z wymienionych typów kolekcji pozwala na dostęp do ostatnio dodanego elementu w pierwszej kolejności?

A. Lista
B. Kolejka
C. Stos
D. Tablica dwuwymiarowa
Stos to struktura danych działająca na zasadzie LIFO (Last In First Out), co oznacza, że ostatnio dodany element jest usuwany jako pierwszy. Stos znajduje zastosowanie w implementacji mechanizmu wywołań rekurencyjnych, zarządzaniu pamięcią oraz w operacjach związanych z cofaniem i przywracaniem stanu (np. cofanie operacji w edytorach tekstów). Dzięki swojej prostocie stosy są fundamentalnym elementem w programowaniu, szczególnie w językach niskopoziomowych.

Pytanie 29

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

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

Pytanie 30

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

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

Pytanie 31

Jakiego typu testy są stosowane do sprawdzania funkcjonalności prototypu interfejsu?

A. Testy zgodności
B. Testy obciążeniowe
C. Testy interfejsu
D. Testy efektywnościowe
Testy interfejsu są kluczowe w procesie weryfikacji funkcji prototypu interfejsu użytkownika. Testy te koncentrują się na sprawdzeniu poprawności działania wszystkich elementów graficznych, takich jak przyciski, pola tekstowe, menu rozwijane oraz formularze. Testy interfejsu pozwalają upewnić się, że interakcje użytkownika z aplikacją przebiegają zgodnie z oczekiwaniami i nie powodują błędów w nawigacji. Dzięki nim można wykryć problemy związane z nieprawidłowym rozmieszczeniem elementów, brakiem reakcji na kliknięcia lub nieintuicyjnym działaniem, co pozwala na wczesne wdrożenie poprawek i zwiększenie użyteczności aplikacji.

Pytanie 32

Programista może wykorzystać framework Angular do realizacji aplikacji

A. mobilnej
B. typu front-end
C. desktopowej
D. typu back-end
Angular to naprawdę fajny framework, stworzony przez Google, który głównie skupia się na tworzeniu aplikacji webowych po stronie klienta, czyli na front-endzie. Umożliwia programistom tworzenie dynamicznych i interaktywnych interfejsów użytkownika. Dzięki tej modularnej budowie, można łatwo zarządzać różnymi częściami aplikacji, co jest super przydatne. Z własnego doświadczenia mogę powiedzieć, że Angular świetnie nadaje się do aplikacji jednoekranowych (SPA), bo pozwala na ładowanie danych asynchronicznie. Przykładem może być aplikacja do zarządzania projektami, gdzie użytkownik może dodawać, edytować i usuwać zadania bez przeładowywania strony. Angular integruje się też z RxJS, co sprawia, że zarządzanie zdarzeniami i strumieniami danych staje się efektywniejsze. Warto również dodać, że Angular CLI pozwala szybko generować komponenty i inne elementy aplikacji, co przyspiesza cały proces tworzenia i pomaga utrzymać spójność projektu.

Pytanie 33

Co będzie wynikiem wykonania poniższego kodu w języku C#?

string text = "hello world";
var result = string.Join("", text.Split(' ').Select(s => char.ToUpper(s[0]) + s.Substring(1)));
Console.WriteLine(result);
A. helloworld
B. HelloWorld
C. Hello World
D. HELLO WORLD
Wynik działania przedstawionego kodu to 'HelloWorld'. Zrozumienie tego wyniku wymaga analizy poszczególnych elementów kodu. Na początku mamy zmienną tekstową 'text' z wartością 'hello world'. Następnie, tekst jest dzielony na fragmenty za pomocą metody 'Split', która rozdziela go na podstawie spacji. W efekcie otrzymujemy tablicę z dwoma elementami: 'hello' i 'world'. Następnie, za pomocą metody 'Select', każdy z tych fragmentów jest przetwarzany. Pierwszy znak każdego słowa jest konwertowany na wielką literę dzięki 'char.ToUpper(s[0])', a następnie łączony z resztą słowa ('s.Substring(1)'). Tak uzyskane fragmenty są łączone w jeden ciąg za pomocą 'string.Join("", ...)'. W rezultacie otrzymujemy 'HelloWorld', co jest zgodne z praktykami konwencji nazewniczych w programowaniu, gdzie często łączy się słowa w jeden ciąg, eliminując spacje. Dzięki temu wynik jest bardziej zwięzły i czytelny."

Pytanie 34

Przykład wywołania funkcji zamien w języku C++ może wyglądać w następujący sposób:

void zamien(int *a, int *b) {
    int tmp;
    tmp = *a;
    *a = *b;
    *b = tmp;
}
A. zamien(*a, *b); // a, b - zmienne całkowite
B. zamien(&a, &b); // a, b - zmienne całkowite
C. zamien(12, 34)
D. zamien(m, n); // m, n - zmienne całkowite
W tym przypadku wywołanie zamien(&a, &b); jest prawidłowe, bo funkcja zamien oczekuje wskaźników do zmiennych całkowitych, nie samych wartości tych zmiennych ani ich referencji. Przekazując adresy przez &a i &b, pozwalamy funkcji modyfikować oryginalne zmienne, a nie ich kopie. To jest fundament operacji wskaźnikowych w C++. Takie podejście umożliwia tzw. przekazywanie przez adres, które jest wykorzystywane wszędzie tam, gdzie trzeba w funkcji podmienić faktyczną zawartość zmiennej, a nie tylko jej kopię. W praktyce, na przykład podczas sortowania tablic czy zamiany miejscami dwóch wartości, korzysta się właśnie z takiego mechanizmu. Przekazywanie wskaźników jest bardzo uniwersalne – pozwala nie tylko zmieniać wartości, ale też np. przekazywać duże struktury bez kopiowania całej ich zawartości, co przyspiesza program i zmniejsza zużycie pamięci. Moim zdaniem warto też zauważyć, że użycie wskaźników jest jednym z filarów programowania na niskim poziomie w C i C++. Wielu początkujących programistów boi się wskaźników (nie wiem czemu, chyba przez te wszystkie historie o błędach i segfaultach), ale jak się już zrozumie, dlaczego i jak przekazywać adresy zmiennych, to potem dużo łatwiej korzystać z bardziej zaawansowanych mechanizmów np. dynamicznej alokacji pamięci czy tablic wskaźników. Standard C++ wręcz zaleca, by wszędzie tam, gdzie funkcja ma zmienić przekazane wartości, używać wskaźników lub referencji. W tym przypadku wskaźniki są idealne, bo dokładnie tego wymaga deklaracja funkcji. Dobrze jest też znać różnicę między przekazywaniem przez wartość, wskaźnik i referencję, bo to pozwala świadomie projektować interfejsy funkcji.

Pytanie 35

Jakie jest najważniejsze działanie w trakcie analizy wymagań klienta przed rozpoczęciem realizacji projektu aplikacji?

A. Rozdzielenie ról w zespole projektowym
B. Stworzenie diagramu Gantta
C. Selekcja języka programowania
D. Zrozumienie potrzeb biznesowych i oczekiwań klienta
Fajnie, że zauważyłeś, jak ważne jest zrozumienie potrzeb biznesowych i oczekiwań klienta. To kluczowa sprawa przed rozpoczęciem pracy nad projektem aplikacji. Bez tego, nawet najfajniejszy kod może nie spełniać wymagań, a to byłoby szkoda, prawda? Analiza wymagań to nie tylko rozpoznanie celów, ale też spotkania z osobami zaangażowanymi w projekt i zbadanie rynku. Dzięki temu możemy stworzyć aplikację, która naprawdę odpowiada na specyficzne potrzeby, co czyni ją bardziej użyteczną i konkurencyjną. No i oczywiście, jak dobrze określimy, czego potrzebują użytkownicy, to mniej nieporozumień po drodze, a klienci będą bardziej zadowoleni, co zawsze jest na plus.

Pytanie 36

W zestawieniu przedstawiono doświadczenie zawodowe członków zespołu IT. Osobą odpowiedzialną za stworzenie aplikacji front-end powinna być:

PracownikZnajomość technologii/programów
AnnaInscape, Corel Draw
KrzysztofAngular
PatrykHTML, CSS
EwaDjango, .NET
A. Ewa
B. Krzysztof
C. Patryk
D. Anna
Wybór Krzysztofa jako osoby odpowiedzialnej za stworzenie aplikacji front-end jest zdecydowanie trafiony. Angular to obecnie jedno z najpopularniejszych frameworków do budowy zaawansowanych aplikacji webowych, które wykorzystują wiele komponentów, obsługują dynamiczne interfejsy użytkownika i muszą być skalowalne. Angular pozwala efektywnie zarządzać logiką front-endu, stanami aplikacji oraz integracją z backendem. Z mojego doświadczenia wynika, że osoby znające Angulara są w stanie nie tylko napisać klasyczny interfejs w HTML i CSS, ale również wdrożyć bardziej rozbudowane rozwiązania zgodne ze współczesnymi standardami, takimi jak SPA (single-page application). Praktyka pokazuje, że projekty front-endowe na dużą skalę, bez frameworków takich jak Angular, React czy Vue, bardzo szybko stają się nieczytelne i trudne w utrzymaniu. Krzysztof, mając doświadczenie z Angularem, będzie też znał TypeScript, który jest już właściwie standardem w dużych projektach front-endowych. To daje też lepszą kontrolę nad błędami i czytelność kodu, a to się liczy w zespole. Co ciekawe, w ofertach pracy na front-end developera, znajomość Angulara jest jednym z najczęściej wymienianych wymagań, właśnie przez wzgląd na szeroki zakres zastosowań i wsparcie społeczności. Tak naprawdę, jeżeli zależy nam na wydajnym, nowoczesnym i dobrze zaprojektowanym interfejsie użytkownika, Krzysztof jest tutaj najlepszym wyborem. Często początkujący myślą, że wystarczy sam HTML i CSS, ale prawdziwa praca front-endowca to już zupełnie wyższa liga. Szczerze mówiąc, mając taką osobę w zespole, można spać spokojnie, że front-end będzie wykonany zgodnie z branżowymi standardami.

Pytanie 37

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

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

Pytanie 38

Jak najlepiej przełożyć oczekiwania klienta na dokumentację techniczną dla programistów?

A. Tworząc szczegółowy dokument z funkcjami oraz wymaganiami technicznymi
B. Rozmawiając wyłącznie z zespołem programistów
C. Opracowując wizualne makiety bez dokładnych opisów
D. Pomijając szczegółowe wymagania techniczne
Sporządzenie szczegółowego dokumentu z funkcjami i wymaganiami technicznymi to najlepszy sposób na przełożenie wymagań klienta na specyfikację techniczną. Dokumentacja techniczna jest podstawą do stworzenia aplikacji zgodnej z oczekiwaniami klienta i pozwala na precyzyjne określenie zakresu prac. Zawiera ona opisy funkcjonalności, diagramy architektury, wymagania dotyczące wydajności oraz harmonogram wdrożenia, co minimalizuje ryzyko błędów i nieporozumień podczas realizacji projektu.

Pytanie 39

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

A. sortowanie szybkie
B. sortowanie bąbelkowe
C. sortowanie przez zliczanie
D. sortowanie przez wstawianie
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 40

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

Ilustracja do pytania
A. Box - dla biblioteki WPF; JField - dla biblioteki Swing
B. TextBox - dla biblioteki WPF; JTextField - dla biblioteki Swing
C. Windows - dla biblioteki WPF; JFrame - dla biblioteki Swing
D. Text - dla biblioteki WPF; JText - dla biblioteki Swing
W tej sytuacji łatwo się pomylić, bo nazewnictwo w różnych frameworkach bywa mylące i czasem wydaje się, że coś powinno się nazywać inaczej. Na przykład, Windows albo JFrame to nie są komponenty służące bezpośrednio do wprowadzania tekstu – Windows w WPF czy JFrame w Swingu to kontenery, czyli miejsca, gdzie umieszczasz różne kontrolki, a nie pole do wprowadzania tekstu. Bardzo częsty błąd początkujących to mylenie kontenera z komponentem – niby oba pojawiają się na ekranie, ale spełniają zupełnie inne role. Z kolei Text w WPF to po prostu właściwość przechowująca wartość tekstową, nie jest to oddzielna kontrolka, a JText w Swingu… cóż, taki komponent w ogóle nie istnieje, więc to trochę strzał w ciemno. Box i JField także nie są standardowymi kontrolkami wejściowymi – Box w WPF nie odnosi się do żadnej kontrolki tekstowej, a JField to nie jest nazwa wykorzystywana w Swingu. To pokazuje, jak ważne jest czytanie dokumentacji i praktykowanie na konkretnych przykładach, bo bardzo łatwo stworzyć sobie błędny obraz struktury frameworka. Najlepiej zapamiętać, że jeśli chodzi o pole tekstowe w WPF, zawsze będzie to TextBox, a w Swingu JTextField – są to podstawowe, powszechnie używane i dobrze udokumentowane klasy. Inne nazwy mogą prowadzić do niepotrzebnych komplikacji i błędnej logiki w aplikacji.