code Flashcards

1
Q

controller

A

package pl.com.coders.shop2.controller;

// … importy …

@SpringBootTest
@ExtendWith(SpringExtension.class)
@ActiveProfiles(“test”)
@AutoConfigureMockMvc
class ProductControllerTest {

// ... pola ...

@BeforeEach
void setUp() {
    objectMapper = new ObjectMapper();
    objectMapper.registerModule(new JavaTimeModule());
    category = createSampleCategory();
    product = createSampleProduct(category);
    when(productService.create(product)).thenReturn(product);
}

@Test
void create() throws Exception {
    when(productService.create(any())).thenReturn(product);
    performRequest("/product", HttpMethod.POST, product)
            .andExpect(status().isCreated())
            .andExpectProduct(product);
}

@Test
void get() throws Exception {
    Long productId = 1L;
    when(productService.get(productId)).thenReturn(product);
    performRequest("/product/{id}", HttpMethod.GET, null, productId)
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON))
            .andExpectProduct(product);
}

@Test
void delete() throws Exception {
    long productId = 1L;
    when(productService.delete(productId)).thenReturn(true);
    performRequest("/product/{id}", HttpMethod.DELETE, null, productId)
            .andExpect(status().isNoContent());
    verify(productService, times(1)).delete(productId);
}

@Test
void update() throws Exception {
    Long productId = 1L;
    Product updatedProduct = createSampleProduct(category);
    when(productService.update(updatedProduct, productId)).thenReturn(updatedProduct);
    performRequest("/product/{id}", HttpMethod.PUT, updatedProduct, productId)
            .andExpect(status().isOk())
            .andExpectProduct(updatedProduct);
}

private ResultActions performRequest(String url, HttpMethod method, Object requestBody, Object... uriVars) throws Exception {
    MockHttpServletRequestBuilder requestBuilder = null;

    switch (method) {
        case GET:
            requestBuilder = MockMvcRequestBuilders.get(url, uriVars);
            break;
        case POST:
            requestBuilder = MockMvcRequestBuilders.post(url)
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(objectMapper.writeValueAsString(requestBody));
            break;
        case PUT:
            requestBuilder = MockMvcRequestBuilders.put(url, uriVars)
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(objectMapper.writeValueAsString(requestBody));
            break;
        case DELETE:
            requestBuilder = MockMvcRequestBuilders.delete(url, uriVars)
                    .contentType(MediaType.APPLICATION_JSON);
            break;
    }

    assertNotNull(requestBuilder);

    return mockMvc.perform(requestBuilder);
}

// ... reszta kodu ...

private enum HttpMethod {
    GET, POST, PUT, DELETE
} }
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Propagacja w Springu

A

W Springu propagacja (ang. propagation) odnosi się do sposobu zarządzania transakcjami w kontekście wielu operacji, które są grupowane razem. Transakcje są używane w celu zapewnienia spójności i integralności danych w systemach bazodanowych. Propagacja transakcji wskazuje, jak nowa transakcja powinna się zachować w kontekście już istniejącej transakcji.

W Springu mamy kilka poziomów propagacji transakcji, które można ustawić za pomocą adnotacji @Transactional lub deklaracji XML w pliku konfiguracyjnym.

Poziomy propagacji transakcji w Springu:
REQUIRED (Domyślny):

Nowa transakcja zostanie utworzona, jeśli nie istnieje żadna transakcja. Jeśli istnieje transakcja nadrzędna, nowa transakcja dołączy się do istniejącej. Jest to poziom domyślny.
java
Copy code
@Transactional(propagation = Propagation.REQUIRED)
REQUIRES_NEW:

Zawsze utworzy nową transakcję. Jeśli istnieje transakcja nadrzędna, zostanie tymczasowo zawieszona, a nowa transakcja będzie wykonywana niezależnie.
java
Copy code
@Transactional(propagation = Propagation.REQUIRES_NEW)
MANDATORY:

Wymaga istnienia transakcji nadrzędnej. Jeśli nie ma żadnej transakcji nadrzędnej, zostanie zgłoszony wyjątek.
java
Copy code
@Transactional(propagation = Propagation.MANDATORY)
SUPPORTS:

Obsługuje transakcję, jeśli istnieje, ale nie wymaga jej. Jeśli nie ma transakcji, metoda będzie wykonywana bez transakcji.
java
Copy code
@Transactional(propagation = Propagation.SUPPORTS)
NOT_SUPPORTED:

Wykonuje się bez transakcji, nawet jeśli istnieje transakcja nadrzędna. Jeśli istnieje transakcja, zostanie tymczasowo zatrzymana.
java
Copy code
@Transactional(propagation = Propagation.NOT_SUPPORTED)
NEVER:

Wykonuje się tylko wtedy, gdy nie ma żadnej transakcji. Jeśli istnieje transakcja nadrzędna, zostanie zgłoszony wyjątek.
java
Copy code
@Transactional(propagation = Propagation.NEVER)
NESTED:

Podobny do REQUIRES_NEW, ale nowa transakcja będzie zagnieżdżona w transakcji nadrzędnej. Jeśli transakcja nadrzędna zostanie zakończona, zagnieżdżona transakcja zostanie zatwierdzona lub cofnięta niezależnie.
java
Copy code
@Transactional(propagation = Propagation.NESTED)
Wybór odpowiedniego poziomu propagacji zależy od wymagań biznesowych i tego, jak chcemy, aby nasze transakcje się zachowywały w kontekście innych transakcji.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Spring isolation

A

W Springu, izolacja (isolation) transakcji odnosi się do poziomu izolacji transakcji bazodanowej. Poziom izolacji definiuje, w jaki sposób transakcja bieżąca widzi dane modyfikowane przez inne równoległe transakcje. Spring umożliwia konfigurację izolacji transakcji za pomocą adnotacji @Transactional lub deklaratywnie w pliku konfiguracyjnym XML.

W Springu, poziomy izolacji transakcji są zdefiniowane w wyliczeniu Isolation w pakiecie org.springframework.transaction.annotation. Oto kilka podstawowych poziomów izolacji:

DEFAULT (Domyślny):

Używa domyślnego poziomu izolacji bazy danych.
java
Copy code
@Transactional(isolation = Isolation.DEFAULT)
public void metodaZTransakcja() {
// …
}
READ_UNCOMMITTED:

Transakcja widzi niezatwierdzone zmiany dokonywane przez inne transakcje.
java
Copy code
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void metodaZTransakcja() {
// …
}
READ_COMMITTED:

Transakcja widzi tylko zatwierdzone zmiany dokonywane przez inne transakcje.
java
Copy code
@Transactional(isolation = Isolation.READ_COMMITTED)
public void metodaZTransakcja() {
// …
}
REPEATABLE_READ:

Transakcja widzi tylko te dane, które istniały w momencie rozpoczęcia transakcji. Unika czytania nowych danych, które mogłyby zostać dodane przez inne transakcje.
java
Copy code
@Transactional(isolation = Isolation.REPEATABLE_READ)
public void metodaZTransakcja() {
// …
}
SERIALIZABLE:

Najbardziej rygorystyczny poziom izolacji. Zapewnia, że żadna inna transakcja nie może modyfikować danych, z którymi obecna transakcja pracuje, aż do jej zakończenia.
java
Copy code
@Transactional(isolation = Isolation.SERIALIZABLE)
public void metodaZTransakcja() {
// …
}
Domyślny poziom izolacji zazwyczaj jest ustawiony na poziomie bazy danych. Wybór odpowiedniego poziomu izolacji zależy od specyfiki aplikacji i wymagań dotyczących równoległego dostępu do danych. Ważne jest również, aby zrozumieć ewentualne konsekwencje wydajnościowe związane z wyborem konkretnego poziomu izolacji.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Jaka jest różnica między JDK, JRE oraz JVM?

A

Różnice między JDK (Java Development Kit), JRE (Java Runtime Environment) a JVM (Java Virtual Machine) można opisać następująco:

JVM (Java Virtual Machine):

JVM to maszyna wirtualna, która jest częścią środowiska uruchomieniowego Java (JRE).
Jest odpowiedzialna za wykonywanie bytecode’u, który jest generowany podczas kompilacji kodu źródłowego Java.
JVM dostosowuje kod bytecode do specyfiki platformy, na której jest uruchamiana.
Zapewnia niezależność od platformy dla aplikacji napisanych w języku Java.
JRE (Java Runtime Environment):

JRE to kompletna implementacja środowiska uruchomieniowego Java.
Obejmuje JVM, biblioteki klas (Java API), pliki konfiguracyjne i inne pliki, które są niezbędne do uruchamiania aplikacji Java.
JRE jest przeznaczone dla użytkowników końcowych, którzy chcą uruchamiać aplikacje napisane w języku Java.
Nie zawiera narzędzi deweloperskich takich jak kompilator czy debugger.
JDK (Java Development Kit):

JDK to pełen zestaw narzędzi deweloperskich do programowania w języku Java.
Obejmuje wszystko, co znajduje się w JRE, a dodatkowo zawiera kompilator (javac), debuger, narzędzia do tworzenia dokumentacji (javadoc), narzędzia do testowania i inne.
JDK jest niezbędne dla programistów tworzących aplikacje w języku Java, ponieważ zapewnia wszystkie niezbędne narzędzia do pisania, kompilowania, debugowania i testowania kodu źródłowego.
Podsumowując, JVM jest maszyną wirtualną, która wykonuje bytecode, JRE to środowisko uruchomieniowe zawierające JVM i niezbędne biblioteki, a JDK to zestaw narzędzi deweloperskich, w tym kompilator, debuger i inne, potrzebnych do tworzenia aplikacji w języku Java.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Wymień najważniejsze zmiany w języku Java, które weszły w wersjach 8 – 17.

A

Oto najważniejsze zmiany i nowości wprowadzone w języku Java w wersjach 8-17:

Java 8 (marzec 2014):

Wyrażenia lambda: Wprowadzenie nowego składniowego cukru dla interfejsów funkcyjnych, co umożliwiło programowanie funkcyjne w języku Java.

Strumienie (Streams): Nowa biblioteka do obsługi przetwarzania sekwencyjnego i równoległego danych, zbudowana na podstawie wyrażeń lambda.

Interfejsy funkcyjne: Dodanie adnotacji @FunctionalInterface i nowych metod do istniejących interfejsów, aby ułatwić tworzenie interfejsów funkcyjnych.

Nowe metody w klasach java.util.function: Dodanie wielu nowych interfejsów funkcyjnych, takich jak Predicate, Function, Supplier, Consumer, UnaryOperator, BinaryOperator.

Metoda referencji: Nowa składnia umożliwiająca odwoływanie się do istniejących metod i konstruktorów jako wyrażeń lambda.

Nowości w API Date and Time (java.time): Wprowadzenie nowego API do obsługi dat i czasu (java.time), zastępujące stare java.util.Date i java.util.Calendar.

Java 9 (wrzesień 2017):

Moduły (Project Jigsaw): Wprowadzenie systemu modułów, aby ułatwić zarządzanie zależnościami i izolację kodu.

JShell (Java REPL): Dodanie interaktywnego środowiska (Read-Eval-Print Loop), które umożliwia programistom testowanie i eksperymentowanie z kodem bez konieczności tworzenia pełnych aplikacji.

Ulepszenia w API kolekcji: Dodanie nowych metod do interfejsów List, Set, Map i innych w celu ułatwienia operacji na kolekcjach.

Ulepszenia w trybie obsługi wielu języków: Wprowadzenie obsługi wielu języków w JVM (Java Virtual Machine), umożliwiając integrację z językami takimi jak JavaScript.

Java 10 (marzec 2018):

Typy lokalne (Local-Variable Type Inference): Wprowadzenie nowej składni var, która umożliwia deklarację zmiennych bez jawnej deklaracji typu.

Ulepszenia w kolekcjach (Collectors): Dodanie nowych metod do interfejsu Collector i klasy Collectors.

Java 11 (wrzesień 2018):

Moduł HTTP Client: Wprowadzenie nowego modułu HTTP Client do obsługi żądań HTTP.

Zmiany w System klasie: Dodanie nowych metod do klasy System, takich jak System.lineSeparator() i System.arraycopy().

Lokalne zmienne finalne składające się z wieu słów: Umożliwienie stosowania final do różnych zmiennych lokalnych w jednej deklaracji.

Java 12 (marzec 2019):

Switch Expressions (Preview): Dodanie nowej składni do wyrażeń switch umożliwiającej bardziej wyraźne i zwięzłe konstrukcje.

Shenandoah Garbage Collector (Preview): Wprowadzenie nowego zbieracza śmieci (Garbage Collector) Shenandoah, zaprojektowanego z myślą o niskim czasie zatrzymania aplikacji.

Java 13 (wrzesień 2019):

Zmiany w Switch Expressions: Ulepszenia w składni wyrażeń switch z poprzedniej wersji, w tym możliwość użycia bloków kodu i bardziej czytelnych zapisów.

Zmiany w StringBuilder: Dodanie nowych metod do klasy StringBuilder, takich jak StringBuilder.indent(int n).

Java 14 (marzec 2020):

Pattern Matching (Preview): Wprowadzenie podglądu (Preview) dla mechanizmu dopasowywania wzorców, co ułatwia operacje na obiektach w bardziej zwięzły sposób.

Records (Preview): Dodanie podglądu dla rekordów, czyli skróconej i bardziej zwięzłej składni do definiowania klas danych.

Java 15 (wrzesień 2020):

Sealed Classes (Preview): Wprowadzenie podglądu dla klas uszczelnionych, które umożliwiają kontrolowanie, które klasy mogą dziedziczyć po danej klasie.

Text Blocks: Dodanie składni do obsługi wieloliniowych ciągów znaków, ułatwiając formatowanie i czytelność kodu.

Java 16 (marzec 2021):

Pattern Matching: Pełne wsparcie dla mechanizmu dopasowywania wzorców, który został wprowadzony jako podgląd w wersji 14.

JEP 338 - Vector API (Incubator): Dodanie API wektorowego, umożliwiającego programowanie równoległe i wektorowe w kontekście maszyny wirtualnej Java.

Java 17 (wrzesień 2021):

JEP 356 - Enhanced Pseudo-Random Number Generators: Ulepszenia w generatorach pseudolosowych.

JEP 413 - Code Snippets in Java API Documentation: Wsparcie dla fragmentów kodu w dokumentacji API Javy.

To tylko kilka naj

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Algorytmy sortowania

A

Istnieje wiele algorytmów sortowania, z których każdy ma swoje własne cechy i zastosowania. Poniżej przedstawiam kilka popularnych algorytmów sortowania:

Sortowanie bąbelkowe (Bubble Sort):

Algorytm porównuje sąsiednie elementy i zamienia je, jeśli są w złej kolejności. To powtarza się dla wszystkich elementów, aż do momentu, gdy cała lista jest posortowana.
Sortowanie przez wstawianie (Insertion Sort):

Algorytm sortuje elementy jednego po drugim. Przyjmuje, że część listy jest już posortowana, a następnie wstawia każdy nowy element we właściwe miejsce.
Sortowanie przez wybieranie (Selection Sort):

Algorytm znajduje najmniejszy element w liście i zamienia go z pierwszym elementem. Następnie znajduje najmniejszy element w reszcie listy i zamienia go z drugim elementem. Proces ten powtarza się, aż cała lista jest posortowana.
Sortowanie szybkie (Quick Sort):

Algorytm dzieli listę na dwie części na podstawie elementu zwanej pivotem. Elementy mniejsze od pivota są umieszczane przed nim, a większe po nim. Proces ten powtarza się rekurencyjnie dla każdej z dwóch części.
Sortowanie przez scalanie (Merge Sort):

Algorytm dzieli listę na dwie części, sortuje każdą z nich, a następnie scalają je w jedną posortowaną listę. Proces ten powtarza się rekurencyjnie, aż do posortowania całej listy.
Sortowanie przez kopcowanie (Heap Sort):

Algorytm buduje kopiec z danych, a następnie usuwa z niego elementy, umieszczając największy element na końcu listy. Proces ten powtarza się, aż cała lista jest posortowana.
Sortowanie kubełkowe (Bucket Sort):

Algorytm rozdziela elementy do kubełków na podstawie ich wartości, a następnie sortuje każdy kubełek z osobna. Elementy są zbierane z kubełków w odpowiedniej kolejności.
Sortowanie przez zliczanie (Counting Sort):

Algorytm tworzy tablicę zliczającą liczbę wystąpień każdego elementu, a następnie używa tych informacji do umieszczenia elementów w odpowiedniej kolejności.
Sortowanie przez wymianę (Cocktail Shaker Sort):

Jest to ulepszona wersja sortowania bąbelkowego, w której elementy przesuwane są w obie strony, co przyspiesza proces sortowania.
Sortowanie przez mieszanie (TimSort):

Algorytm, który jest hybrydą sortowania przez scalanie i sortowania przez wstawianie. Jest wykorzystywany w implementacji sortowania w Javie.
Wybór konkretnego algorytmu sortowania zależy od wielu czynników, takich jak rodzaj danych, ilość danych, oczekiwany czas sortowania i pamięć dostępna dla algorytmu. Niektóre algorytmy są bardziej efektywne dla określonych przypadków użycia niż inne.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly