Сообщения

Сообщения за ноябрь, 2020

Разница между fail-fast и fail-safe итератором в Java

Изображение
fail-fast Iterator Итераторы в Java используются для итерации по объектам Collection. Fail-Fast итераторы немедленно вызывают ConcurrentModificationException, если есть структурная модификация коллекции. Структурная модификация означает добавление, удаление или обновление любого элемента из коллекции, когда поток выполняет итерацию по этой коллекции. Iterator в классах ArrayList, HashMap - это примеры fail-fast Iterator. import java.util.ArrayList; import java.util.Iterator; public class FailFastIteratorExample { public static void main(String[] args) { // Создание ArrayList целых чисел ArrayList<Integer> list = new ArrayList<Integer>(); // Добавление элементов в список list.add(1452); list.add(6854); list.add(8741); // Получение итератора из списка Iterator<Integer> it = list.iterator(); while (it.hasNext()) { Integer integer =

LinkedHashMap в Java

Изображение
LinkedHashMap похож на HashMap с дополнительной функцией поддержания порядка вставленных в него элементов. Класс Java LinkedHashMap - это реализация Hashtable и Linked list интерфейса Map с предсказуемым порядком итераций. Он наследует класс HashMap и реализует интерфейс Map. Характеристики: Java LinkedHashMap содержит значения на основе ключа. Java LinkedHashMap содержит уникальные элементы. Java LinkedHashMap может иметь один нулевой ключ и несколько нулевых значений. Java LinkedHashMap не синхронизируется. Java LinkedHashMap поддерживает порядок вставки. Первоначальная емкость класса Java HashMap по умолчанию составляет 16 с коэффициентом загрузки 0,75. import java.util.LinkedHashMap; import java.util.Set; import java.util.Iterator; import java.util.Map; public class LinkedHashMapDemo { public static void main(String args[]) { // Объявление HashMap LinkedHashMap<Integer, String> lhmap = new LinkedHashMap<Integer, String>(

Коллекции, предоставляемые интерфейсом Map в Java

Изображение
В дереве наследования интерфейса Map есть несколько реализаций, но только 3 основных, общих и универсальных - это HashMap, LinkedHashMap и TreeMap. HashMap В этой реализации в качестве базовой структуры данных используется хэш-таблица. Он реализует все операции Map и допускает нулевые значения и один нулевой ключ. Этот класс примерно эквивалентен Hashtable - устаревшей структуре данных до Java Collections Framework, но он не синхронизируется и допускает значения null. HashMap не гарантирует порядок элементов "ключ-значение". Поэтому рассмотрите возможность использования HashMap, когда порядок не имеет значения и допустимы значения null. Map<Integer, String> mapHttpErrors = new HashMap<>(); mapHttpErrors.put(200, "OK"); mapHttpErrors.put(303, "See Other"); mapHttpErrors.put(404, "Not Found"); mapHttpErrors.put(500, "Internal Server Error"); System.out.println(mapHttpErrors); Вывод: {404=Not Found, 500=Interna

Как HashMap работает в Java

Изображение
HashMap в Java работает по принципу хеширования. Это структура данных, которая позволяет сохранять объект и извлекать его за постоянное время O(1). При хешировании хеш-функции используются для связывания ключа и значения в HashMap. Объекты сохраняются путем вызова метода put(key, value) HashMap и извлекаются путем вызова метода get(key). Когда мы вызываем метод put, вызывается метод hashcode() ключевого объекта, чтобы хеш-функция карты могла найти место в корзине для хранения объекта значения, который на самом деле является индексом внутреннего массива, известного как таблица. HashMap внутренне хранит отображение в виде объекта Map.Entry, который содержит как объект ключа, так и объект значения. Поскольку внутренний массив HashMap имеет фиксированный размер, и если вы продолжаете хранить объекты, в какой-то момент хеш-функция будет возвращать одно и то же местоположение корзины для двух разных ключей, это называется столкновением в HashMap. В этом случае связанный список формируется в

Интерфейсы Comparable и Comparator в Java

Изображение
Comparable и Comparator являются интерфейсами и могут использоваться для сортировки элементов коллекции. Comparable Comparator Comparable обеспечивает единую последовательность сортировки. Другими словами, мы можем отсортировать коллекцию на основе одного элемента, такого как идентификатор, имя и цена. Comparator предоставляет несколько последовательностей сортировки. Другими словами, мы можем отсортировать коллекцию по нескольким элементам, таким как идентификатор, имя, цена и т. д. Comparable влияет на исходный класс, т.е. модифицируется фактический класс. Comparator не влияет на исходный класс, т.е. фактический класс не изменяется. Comparable предоставляет метод compareTo() для сортировки элементов. Comparator предоставляет метод compare() для сортировки элементов. Comparable присутствует в пакете java.lang. Comparator присутствует в пакете java.util. Мы можем отсортировать элементы списка типа Comparable методом Collections.sort(List). Мы можем отсортироват

Как HashMap обрабатывает коллизии в Java

Изображение
До Java 8, HashMap и все другие классы реализации карты на основе хэш-таблиц в Java обрабатывают столкновения путем объединения в цепочку, то есть они используют связанный список для хранения записей карты, которые заканчиваются в той же корзине из-за столкновения. Если ключ попадает в то же место корзины, где уже хранится запись, то эта запись просто добавляется в начало связанного списка. В худшем случае это снижает производительность метода get() HashMap до O(n) с O(1). Чтобы решить эту проблему в случае частых конфликтов HashMap, Java 8 начала использовать сбалансированное дерево вместо связанного списка для хранения конфликтующих записей. Это также означает, что в худшем случае вы получите прирост производительности с O(n) до O(log n). Порог переключения на сбалансированное дерево определяется как константа TREEIFY_THRESHOLD в коде java.util.HashMap JDK 8. В настоящее время его значение равно 8, что означает, что если в одной корзине более 8 элементов, то HashMap будет использова

В чем будет проблема, если не переопределять метод hashCode()

Изображение
Некоторые коллекции, такие как HashSet, HashMap или HashTable, используют значение хэш-кода объекта, чтобы узнать, как объект будет храниться в коллекции, и впоследствии хэш-код используется, чтобы помочь найти объект в коллекции. Извлечение хэша участвует: Во-первых, в поиске нужного бакета (корзины) с помощью hashCode() Во-вторых, в поиске в корзине нужного элемента, используя equals() Если hashCode() не переопределен, то реализация по умолчанию в классе Object будет использоваться коллекциями. Эта реализация дает разные значения для разных объектов, даже если они равны согласно методу equals(). Пример: public class Person { private int id; private String name; public Person(int id, String name) { this.name = name; this.id = id; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { t

Различия между Array и ArrayList в Java

Изображение
1. Размер : массив в Java имеет фиксированный размер. Мы не можем изменить размер массива после его создания. ArrayList имеет динамический размер. Когда мы добавляем элементы в ArrayList, его емкость увеличивается автоматически. 2. Производительность : в Java Array и ArrayList дают разную производительность для разных операций. add() или get(): добавление или извлечение элемента из массива или объекта ArrayList имеет аналогичную производительность. Это операции с постоянным временем. resize(): автоматическое изменение размера ArrayList снижает производительность. ArrayList внутренне поддерживается массивом. В resize() временный массив используется для копирования элементов из старого массива в новый массив. 3. Примитивы : массив может содержать как примитивные типы данных, так и объекты. Но ArrayList не может содержать примитивные типы данных. Он содержит только объекты. 4. Итератор : в ArrayList мы используем объект Iterator для обхода элементов. Мы используем цикл for для перебо

Модель памяти Java (JMM, Java Memory Model)

Изображение
Модель памяти Java, используемая внутри JVM, разделяет память между стеками потоков и кучей (heap). Каждый поток, выполняющийся в виртуальной машине Java, имеет свой собственный стек потока. Стек потока содержит информацию о том, какие методы вызвал поток для достижения текущей точки выполнения. Стек потока также содержит все локальные переменные для каждого выполняемого метода (все методы в стеке вызовов). Поток может получить доступ только к своему собственному стеку потока. Локальные переменные, созданные потоком, невидимы для всех других потоков, кроме потока, который его создал. Даже если два потока выполняют один и тот же код, два потока все равно будут создавать локальные переменные этого кода в своем собственном стеке потока. Таким образом, каждый поток имеет свою версию каждой локальной переменной. Все локальные переменные примитивных типов (boolean, byte, short, char, int, long, float, double) полностью хранятся в стеке потока и поэтому не видны другим потокам. Один поток м

Жизненный цикл сервлета

Изображение
В жизненном цикле сервлета центральное место занимают три метода. Это init(), service() и destroy(). Они реализуются каждым сервлетом и вызываются сервером в определенное время. На этапе инициализации жизненного цикла сервлета веб-контейнер инициализирует экземпляр сервлета, вызывая метод init(), передавая объект, реализующий интерфейс javax.servlet.ServletConfig. Этот объект конфигурации позволяет сервлету получать доступ к параметрам инициализации значения имени из веб-приложения. После инициализации экземпляр сервлета может обслуживать запросы клиентов. Каждый запрос обслуживается в отдельном потоке. Веб-контейнер вызывает метод сервлета service() для каждого запроса. Метод service() определяет тип выполняемого запроса и отправляет его соответствующему методу для обработки запроса. Разработчик сервлета должен предоставить реализацию для этих методов. Если запрос сделан для метода, который не реализован сервлетом, вызывается метод родительского класса, что обычно приводит к возвра

Java Servlet

Изображение
Jakarta Servlet (ранее Java Servlet) - это программный компонент Java, который расширяет возможности сервера. Хотя сервлеты могут отвечать на многие типы запросов, они чаще всего реализуют веб-контейнеры для размещения веб-приложений на веб-серверах и, таким образом, квалифицируются как веб-API сервлетов на стороне сервера. Такие веб-сервлеты являются эквивалентом Java для других технологий динамического веб-контента, таких как PHP и ASP.NET. Сервлет Jakarta обрабатывает или сохраняет класс Java в Jakarta EE, который соответствует API сервлета Jakarta, стандарту для реализации классов Java, отвечающих на запросы. Сервлеты могут в принципе взаимодействовать по любому протоколу клиент-сервер, но чаще всего они используются с HTTP. Таким образом, "сервлет" часто используется как сокращение для "HTTP-сервлета". Таким образом, разработчик программного обеспечения может использовать сервлет для добавления динамического содержимого на веб-сервер с помощью платформы Java.

Интеграционное тестирование в Spring: тестирование клиентских приложений

Изображение
Вы можете использовать тесты на стороне клиента для тестирования кода, который внутренне использует RestTemplate. Идея состоит в том, чтобы объявить ожидаемые запросы и предоставить "заглушки" (stubs) ответов, чтобы вы могли сосредоточиться на тестировании кода изолированно (то есть без запуска сервера). В следующем примере показано, как это сделать: RestTemplate restTemplate = new RestTemplate(); MockRestServiceServer mockServer = MockRestServiceServer .bindTo(restTemplate) .build(); mockServer.expect(requestTo("/greeting")) .andRespond(withSuccess()); // Тестовый код, // который использует вышеуказанный RestTemplate ... mockServer.verify(); В предыдущем примере MockRestServiceServer (центральный класс для клиентских REST-тестов) настраивает RestTemplate с помощью настраиваемой ClientHttpRequestFactory, которая утверждает фактические запросы против ожиданий и возвращает &

Интеграционное тестирование в Spring: Spring MVC Test Framework, асинхронные запросы

Изображение
Асинхронные запросы Servlet 3.0, поддерживаемые в Spring MVC, работают, выходя из потока контейнера сервлета и позволяя приложению вычислять ответ асинхронно, после чего выполняется асинхронная отправка для завершения обработки в потоке контейнера сервлета. В Spring MVC Test можно протестировать асинхронные запросы, сначала подтвердив созданное значение async, затем вручную выполнив асинхронную отправку и, наконец, проверив ответ. Ниже приведен пример теста для методов контроллера, которые возвращают DeferredResult, Callable или реактивный тип, например Reactor Mono: @Test void test() throws Exception { MvcResult mvcResult = this.mockMvc.perform(get("/path")) .andExpect(status().isOk()) // Статус ответа на проверку не изменился .andExpect(request().asyncStarted()) // Асинхронная обработка должна быть запущена .andExpect(request().asyncResult("body")) // Подождите и подтвердите результат async .andReturn();

Интеграционное тестирование в Spring: Spring MVC Test Framework, определение ожиданий

Изображение
Вы можете определить ожидания, добавив один или несколько вызовов .andExpect(..) после выполнения запроса, как показано в следующем примере: mockMvc.perform(get("/accounts/1")) .andExpect(status().isOk()); MockMvcResultMatchers.* предоставляет ряд ожиданий, некоторые из которых дополнительно вложены в более подробные ожидания. Ожидания делятся на две общие категории. Первая категория утверждений проверяет свойства ответа (например, статус ответа, заголовки и содержимое). Это самые важные результаты, которые нужно утверждать. Вторая категория утверждений выходит за рамки ответа. Эти утверждения позволяют вам проверять конкретные аспекты Spring MVC, например, какой метод контроллера обработал запрос, было ли вызвано и обработано исключение, каково содержимое модели, какое представление было выбрано, какие атрибуты были добавлены и т. д. Они также позволяют вам проверять конкретные аспекты сервлета, такие как атрибуты запроса и сеанса. Следующий тест утверждает,

Интеграционное тестирование в Spring: Spring MVC Test Framework, выполнение запросов

Изображение
Вы можете выполнять запросы, которые используют любой метод HTTP, как показано в следующем примере: mockMvc.perform(post("/hotels/{id}", 42) .accept(MediaType.APPLICATION_JSON)); Вы также можете выполнять запросы загрузки файлов, которые внутренне используют MockMultipartHttpServletRequest, чтобы не было фактического синтаксического анализа составного запроса. Скорее, вы должны настроить его, как в следующем примере: mockMvc.perform(multipart("/doc") .file("a1", "ABC".getBytes("UTF-8"))); Вы можете указать параметры запроса в стиле шаблона URI, как показано в следующем примере: mockMvc.perform(get("/hotels?thing={thing}", "somewhere")); Вы также можете добавить параметры запроса сервлета, которые представляют параметры запроса или формы, как показано в следующем примере: mockMvc.perform(get("/hotels").param("thing", "somewhere")); Если код прилож

Интеграционное тестирование в Spring: Spring MVC Test Framework, возможности установки

Изображение
Независимо от того, какой конструктор MockMvc вы используете, все реализации MockMvcBuilder предоставляют некоторые общие и очень полезные функции. Например, вы можете объявить заголовок Accept для всех запросов и ожидать статус 200, а также заголовок Content-Type во всех ответах, как показано ниже: // static import of MockMvcBuilders.standaloneSetup MockMvc mockMvc = standaloneSetup(new MusicController()) .defaultRequest(get("/") .accept(MediaType.APPLICATION_JSON)) .alwaysExpect(status().isOk()) .alwaysExpect(content().contentType("application/json;charset=UTF-8")) .build(); Кроме того, сторонние платформы (и приложения) могут предварительно упаковать инструкции по установке, например, в MockMvcConfigurer. Spring Framework имеет одну такую встроенную реализацию, которая помогает сохранять и повторно использовать сеанс HTTP для разных запросов. Вы можете использовать его следующим образом: // static import of SharedHttpSessionConfi

Интеграционное тестирование в Spring: Spring MVC Test Framework, варианты установки

Изображение
У вас есть два основных варианта создания экземпляра MockMvc. Первый - загрузить конфигурацию Spring MVC через TestContext framework, которая загружает конфигурацию Spring и вводит WebApplicationContext в тест, чтобы использовать его для создания экземпляра MockMvc. В следующем примере показано, как это сделать: @SpringJUnitWebConfig(locations = "my-servlet-context.xml") class MyWebTests { MockMvc mockMvc; @BeforeEach void setup(WebApplicationContext wac) { this.mockMvc = MockMvcBuilders .webAppContextSetup(this.wac) .build(); } // ... } Второй вариант - вручную создать экземпляр контроллера без загрузки конфигурации Spring. Вместо этого автоматически создается базовая конфигурация по умолчанию, примерно сопоставимая с конфигурацией MVC JavaConfig или пространства имен MVC. Вы можете настроить его до определенной степени. В следующем примере показано, как это сделать: class MyWebTests {

Интеграционное тестирование в Spring: Spring MVC Test Framework

Изображение
Spring MVC Test framework обеспечивает первоклассную поддержку для тестирования кода Spring MVC с помощью свободного API, который вы можете использовать с JUnit, TestNG или любым другим фреймворком тестирования. Он построен на mock объектах Servlet API из модуля spring-test и, следовательно, не использует работающий контейнер сервлетов. Он использует DispatcherServlet для обеспечения полного поведения среды выполнения Spring MVC и обеспечивает поддержку загрузки фактической конфигурации Spring с TestContext framework в дополнение к автономному режиму, в котором вы можете вручную создавать экземпляры контроллеров и тестировать их по одному. Spring MVC Test также обеспечивает поддержку на стороне клиента для тестирования кода, использующего RestTemplate. Клиентские тесты имитируют ответы сервера, а также не используют работающий сервер. Spring Boot предоставляет возможность писать полные сквозные интеграционные тесты, которые включают работающий сервер. Серверные тесты Вы можете напи

Интеграционное тестирование в Spring: TestContext Framework, классы поддержки TestNG

Изображение
Пакет org.springframework.test.context.testng предоставляет следующие классы поддержки для тестовых случаев на основе TestNG: AbstractTestNGSpringContextTests AbstractTransactionalTestNGSpringContextTests AbstractTestNGSpringContextTests - это абстрактный базовый тестовый класс, который объединяет Spring TestContext Framework с явной поддержкой тестирования ApplicationContext в среде TestNG. Когда вы расширяете AbstractTestNGSpringContextTests, вы можете получить доступ к защищенной переменной экземпляра applicationContext, которую можно использовать для выполнения явных поисков bean-компонентов или для проверки состояния контекста в целом. AbstractTransactionalTestNGSpringContextTests - это абстрактное транзакционное расширение AbstractTestNGSpringContextTests, которое добавляет некоторые удобные функции для доступа JDBC. Этот класс ожидает, что bean-объект javax.sql.DataSource и bean-объект PlatformTransactionManager будут определены в ApplicationContext. Когда вы расширяете Ab

Интеграционное тестирование в Spring: TestContext Framework, внедрение зависимостей с помощью SpringExtension

Изображение
SpringExtension реализует API расширения ParameterResolver из JUnit Jupiter, что позволяет Spring обеспечивать внедрение зависимостей для конструкторов тестов, методов тестирования и методов обратного вызова жизненного цикла тестирования. В частности, SpringExtension может внедрять зависимости из ApplicationContext теста в конструкторы и методы тестов, аннотированные с помощью @BeforeAll, @AfterAll, @BeforeEach, @AfterEach, @Test, @RepeatedTest, @ParameterizedTest и других. Внедрение конструктора Если конкретный параметр в конструкторе для тестового класса JUnit Jupiter имеет тип ApplicationContext (или его подтип) или аннотируется или метааннотируется с помощью @Autowired, @Qualifier или @Value, Spring вводит значение для этого конкретного с соответствующим bean-компонентом или значением из ApplicationContext теста. Spring также может быть настроен на автоматическое подключение всех аргументов для конструктора тестового класса, если конструктор считается автоматическим. Конструкто

Интеграционное тестирование в Spring: TestContext Framework, SpringExtension для JUnit Jupiter

Изображение
Spring TestContext Framework предлагает полную интеграцию со средой тестирования JUnit Jupiter, представленной в JUnit 5. Аннотируя тестовые классы с помощью @ExtendWith(SpringExtension.class), вы можете реализовать стандартные модульные и интеграционные тесты на основе JUnit Jupiter и одновременно воспользоваться преимуществами TestContext framework, такими как поддержка загрузки контекстов приложения, внедрение зависимостей тестовых экземпляров, выполнение транзакционного метода тестирования и т. д. Кроме того, благодаря богатому API расширений в JUnit Jupiter Spring предоставляет следующие функции помимо набора функций, которые Spring поддерживает для JUnit 4 и TestNG: Внедрение зависимостей для конструкторов тестов, методов тестирования и методов обратного вызова жизненного цикла теста. Мощная поддержка выполнения условного теста на основе выражений SpEL, переменных среды, системных свойств и т. д. Пользовательские составные аннотации, сочетающие аннотации из Spring и JUnit Ju

Интеграционное тестирование в Spring: TestContext Framework, классы поддержки JUnit 4

Изображение
Пакет org.springframework.test.context.junit4 предоставляет следующие классы поддержки для тестовых случаев на основе JUnit 4 (поддерживаются в JUnit 4.12 или выше): AbstractJUnit4SpringContextTests AbstractTransactionalJUnit4SpringContextTests AbstractJUnit4SpringContextTests - это абстрактный базовый тестовый класс, который объединяет Spring TestContext Framework с явной поддержкой тестирования ApplicationContext в среде JUnit 4. Когда вы расширяете AbstractJUnit4SpringContextTests, вы можете получить доступ к защищенной переменной экземпляра applicationContext, которую вы можете использовать для выполнения явного поиска bean-компонентов или для проверки состояния контекста в целом. AbstractTransactionalJUnit4SpringContextTests - это абстрактное транзакционное расширение AbstractJUnit4SpringContextTests, которое добавляет некоторые удобные функции для доступа JDBC. Этот класс ожидает, что bean-объект javax.sql.DataSource и bean-объект PlatformTransactionManager будут определены

Интеграционное тестирование в Spring: TestContext Framework, Spring JUnit 4 Rules

Изображение
Пакет org.springframework.test.context.junit4.rules предоставляет следующие JUnit 4 Rules (поддерживаются в JUnit 4.12 и выше): SpringClassRule SpringMethodRule SpringClassRule - это JUnit TestRule, который поддерживает функции уровня класса Spring TestContext Framework, тогда как SpringMethodRule - это JUnit MethodRule, который поддерживает функции уровня экземпляра и уровня метода Spring TestContext Framework. В отличие от SpringRunner, поддержка JUnit на основе правил Spring имеет то преимущество, что не зависит от какой-либо реализации org.junit.runner.Runner и, следовательно, может быть объединена с существующими альтернативными runner (такими как JUnit 4 Parameterized) или сторонними runner (например, MockitoJUnitRunner). Чтобы поддерживать полную функциональность TestContext framework, вы должны объединить SpringClassRule с SpringMethodRule. В следующем примере показан правильный способ объявления этих правил в интеграционном тесте: // Опционально можно указать // не