Классы
DoubleSummaryStatistics, IntSummaryStatistics и LongSummaryStatistics служат для хранения агрегированных данных о числовом потоке. А конкретно: количество, сумма, минимальное, максимальное и среднее.Пример:
List<Integer> iList = List.of(1, 2, 3);
IntSummaryStatistics stats = iList.stream().collect(Collectors.summarizingInt(i -> i));
System.out.println(stats);
// IntSummaryStatistics{count=3, sum=6, min=1, average=2,000000, max=3}
#java #IntSummaryStatistics #DoubleSummaryStatistics #LongSummaryStatistics
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤1
«И» (AND): конъюнкция, логическое умножение
true && true = true
false && false = false
true && false = false
false && true = false
true & true = true
false & false = false
true & false = false
false & true = false
Побитовые операции:
1010
&&&&
1001
====
1000
Включающее «ИЛИ» (OR): дизъюнкция, логическое сложение
true || true = true
false || false = false
true || false = true
false || true = true
true | true = true
false | false = false
true | false = true
false | true = true
Побитовые операции:
1010
||||
1001
====
1011
Исключающее «ИЛИ» (XOR): строгая дизъюнкция, логическое вычитание
true ^ true = false
false ^ false = false
true ^ false = true
false ^ true = true
Побитовые операции:
1010
^^^^
1001
====
0011
«НЕ» (NOT): инверсия, отрицание
!true = false
!false = true
Побитовый унарный оператор NOT:
~~
01
==
10
Порядок выполнения операторов
Когда в выражении несколько логических операторов, результат вычисляется с учётом их приоритета. Если нет логических скобок, то операции выполняются в таком порядке:
! ~ (NOT)
& (AND)
^ (XOR)
| (OR)
&& (условный AND)
|| (условный OR)
Если одинаковые операции стоят по соседству, то раньше выполняется та, что левее.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤2
public class Survive {
private Survive internalInstance = new Survive();
public Survive() throws Exception {
throw new Exception("I'm not coming out");
}
public static void main(String[] args) {
try {
Survive b = new Survive();
System.out.println("WIN!");
} catch (Exception ex) {
System.out.println("LOSE!");
}
}
}#java #quest
🔥4🎉1
Пример POJO:
public class Person {
private String name;
private int age;
// Конструктор
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Геттеры и сеттеры
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
POJO используется для создания простых объектов без привязки к какой-либо специфической архитектуре или фреймворку. Например, в JPA объекты-сущности часто являются POJO, что позволяет их использовать независимо от платформы.
#java #pojo
Please open Telegram to view this post
VIEW IN TELEGRAM
❤16👍3
ORM (Object-Relational Mapping) — это технология, которая позволяет автоматически преобразовывать данные между объектами в программном коде и записями в реляционной базе данных. Благодаря ORM, программисты могут работать с базой данных на уровне объектов, а не SQL-запросов, что упрощает разработку.
JPA (Java Persistence API) — это стандарт спецификации ORM в Java. JPA определяет набор интерфейсов и аннотаций для работы с объектами и их сохранением в базу данных. Однако JPA сама по себе не является реализацией, а только задает стандарт. Реализации JPA включают Hibernate, EclipseLink и другие.
#java #jpa
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤1
Особенности HQL:
✔️ Запросы формулируются относительно классов и их полей, а не таблиц.
✔️ Поддерживает агрегатные функции (например, COUNT, SUM).
✔️ Поддерживает JOIN для работы с ассоциациями между объектами.
✔️ HQL автоматически преобразуется в SQL, что облегчает работу с реляционной базой данных, абстрагируя детали.
Пример HQL-запроса:
SELECT u FROM User u WHERE u.name = :name
Здесь
User — это класс сущности, а запрос вернет объекты этого класса.#java #HQL #Hibernate
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
public class Quest {
public static void main(String[] args) {
int[][] tests = {
{6, 5, 4, 3, 2, 1},
{1, 2},
{1, 2, 3},
{1, 2, 3, 4},
{1}
};
int n = 0;
try {
int i = 0;
while (true) {
if (thirdElementIsThree(tests[i++])) n++;
}
} catch (ArrayIndexOutOfBoundsException e) {
}
System.out.println(n);
}
private static boolean thirdElementIsThree(int[] a) {
return (a.length >= 3) & (a[2] == 3);
}
}
#java #quest
❤5
👍4🎉2
Автоконфигурация
Spring Boot автоматически настраивает компоненты приложения на основе зависимостей, которые вы добавляете в проект. Это избавляет от необходимости писать обширные XML-конфигурации или классы конфигурации.
Встроенные серверы
Spring Boot предоставляет возможность запускать приложение с встроенными серверами, такими как Tomcat или Jetty. Это означает, что вам не нужно отдельно настраивать сервер — приложение можно запустить как обычный JAR-файл.
Spring Initializr
Веб-инструмент, который позволяет быстро генерировать новый проект Spring Boot с нужными зависимостями, что делает старт разработки ещё проще.
Actuator
Модуль для мониторинга и управления приложением на продакшене. Он предоставляет различные эндпоинты для проверки состояния, статистики и метрик приложения.
Миграции баз данных
Spring Boot поддерживает интеграцию с инструментами миграции баз данных, такими как Flyway и Liquibase, что упрощает управление схемами базы данных.
#java #SpringBoot
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤1🔥1
Spring Framework предлагает решения для реализации Service Discovery, такие как Spring Cloud, который интегрируется с популярными механизмами регистрации сервисов, такими как: Netflix Eureka, HashiCorp Consul, Apache Zookeeper.
Как работает процесс Service Discovery:
✔️ Регистрация сервиса — каждый микросервис при запуске автоматически регистрируется в реестре (например, Eureka или Consul), передавая своё местоположение (IP и порт).
✔️ Обнаружение сервиса — при необходимости взаимодействовать с другим микросервисом, сервис может запрашивать реестр для получения списка доступных сервисов и их адресов.
✔️ Health Checks — в большинстве систем Service Discovery интегрированы проверки состояния сервисов. Если сервис становится недоступен, он удаляется из реестра.
Зачем это нужно?
✔️ Масштабируемость: При динамическом добавлении и удалении экземпляров сервисов, они автоматически обнаруживаются и учитываются другими сервисами.
✔️ Гибкость развертывания: Сервисы могут развертываться на разных машинах и сетях, не требуя жесткой привязки к IP-адресам.
✔️ Устойчивость: В случае отказа одного из экземпляров сервиса другие сервисы могут быть обнаружены и использованы.
#java #ServiceDiscovery
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤1
ArrayList — это реализация динамического массива из стандартной библиотеки коллекций java.util. Он представляет собой список, который может изменять свой размер в зависимости от количества добавляемых элементов. ArrayList основан на массиве объектов. Это означает, что под капотом у него есть массив фиксированного размера. Когда этот массив заполняется, создается новый массив большего размера, в который копируются элементы старого массива, а затем старый массив удаляется.Размер и емкость
✔️ Размер (size) — это количество элементов, которые фактически содержатся в
ArrayList.✔️ Емкость (capacity) — это текущий размер внутреннего массива. Когда количество элементов превышает емкость, массив расширяется.
Когда
ArrayList инициализируется, его емкость по умолчанию равна 10. Если количество элементов в массиве превышает емкость, массив автоматически увеличивается. Обычно емкость увеличивается по формуле: новая емкость = старая емкость * 1.5.Для удаления элементов используется метод
remove(int index). После удаления элемента все элементы, находящиеся справа от удаленного, смещаются на одну позицию влево, что требует временных затрат O(n).После удаления элементов
ArrayList не автоматически уменьшает емкость внутреннего массива, то есть массив может занимать больше памяти, чем требуется для хранения фактических элементов. Однако для оптимизации можно вручную уменьшить емкость до текущего размера с помощью метода trimToSize().Одним из преимуществ
ArrayList является возможность доступа к элементам по индексу за время O(1). Это возможно благодаря тому, что элементы хранятся в массиве, и доступ к ним осуществляется через индекс.#java #ArrayList
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14❤2🤓2
🔄 Бесконечные потоки
Интерфейс Stream имеет два статических метода для генерации бесконечных потоков:
iterate
generate
📌 При работе с бесконечными потоками, крайне важно вызвать метод limit() перед вызовом терминальной операции, иначе наша программа будет работать бесконечно.
Интерфейс Stream имеет два статических метода для генерации бесконечных потоков:
iterate() и generate().iterate
(final T seed, final UnaryOperator<T> f) возвращает бесконечный последовательный упорядоченный поток, созданный путем итеративного применения функции f к исходному элементу начального значения, создавая поток, состоящий из начального числа, f(начальное число), f(f(начальное число)) и т. д.generate
(Supplier<? extends T> s) возвращает бесконечный последовательный неупорядоченный поток, в котором каждый элемент создается предоставленным поставщиком (Supplier). Это подходит для генерации константных потоков, потоков случайных элементов и т. д.📌 При работе с бесконечными потоками, крайне важно вызвать метод limit() перед вызовом терминальной операции, иначе наша программа будет работать бесконечно.
🔥13❤3
TreeSet и HashSet — это два класса, реализующих интерфейс Set, но они имеют разные внутренние механизмы и свойства.Структура данных
✔️
HashSet использует хеш-таблицу для хранения элементов. Это позволяет быстро добавлять, удалять и искать элементы, не обеспечивая никакого порядка их хранения.✔️
TreeSet использует красно-черное дерево (Red-Black Tree), что позволяет хранить элементы в отсортированном порядке (естественном порядке элементов или порядке, определённом компаратором).Порядок элементов
✔️
HashSet не гарантирует какого-либо порядка элементов. Порядок может быть случайным, и он не сохраняется при добавлении/удалении элементов.✔️
TreeSet хранит элементы в отсортированном порядке. Если элементы реализуют интерфейс Comparable, то сортировка будет основана на их естественном порядке (например, для чисел — по возрастанию). Также можно задать пользовательский порядок с помощью объекта Comparator.Скорость операций
✔️
HashSet обеспечивает O(1) для операций добавления, удаления и поиска (в среднем, если хеш-функция работает эффективно и коллизий мало).✔️
TreeSet обеспечивает O(log n) для операций добавления, удаления и поиска из-за использования сбалансированного дерева.Поддержка дополнительных операций
✔️
HashSet не поддерживает дополнительные методы для работы с диапазонами или порядком элементов.✔️
TreeSet предоставляет такие методы, как subSet(), headSet(), tailSet(), которые позволяют работать с диапазонами элементов в отсортированном множестве.Null-значения
✔️
HashSet может хранить одно null значение.✔️
TreeSet не позволяет хранить null значения, так как при добавлении null неясно, как его сравнивать с другими элементами.Когда использовать
✔️ Используйте
HashSet, если вам не важен порядок элементов и вам нужна максимальная производительность.✔️ Используйте
TreeSet, если нужно поддерживать элементы в отсортированном порядке.#java #HashSet #TreeSet
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16❤4🔥3
🎉6🌚4🫡1
🎉8
Основные компоненты
✔️ Config Server — сервер, который хранит конфигурации (обычно в Git) и раздает их микросервисам.
✔️ Config Client — клиент в микросервисах, который получает конфигурации от Config Server.
Возможности
✔️ Централизация конфигураций всех сервисов.
✔️ Поддержка версионирования конфигураций (например, через Git).
✔️ Динамическое обновление конфигураций без перезапуска приложений с помощью Spring Cloud Bus.
✔️ Поддержка различных сред и профилей (dev, prod и т.д.).
Пример настройки Config Server:
spring:
cloud:
config:
server:
git:
uri: https://github.com/your-repo/config-repo
Пример настройки Config Client:
spring:
cloud:
config:
uri: http://localhost:8888
profile: dev
Преимущества: упрощает управление конфигурациями, поддерживает разные среды, позволяет динамически обновлять настройки.
Недостатки: важен контроль за доступом и стабильностью Config Server.
#java #Spring #Cloud #Config
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤3🔥1
При работе с JPA есть несколько событий, о которых мы можем получать уведомления в течение жизненного цикла объекта.
JPA определяет семь событий жизненного цикла:
@PrePersist - перед тем, как вызывается persist для нового объекта
@PostPersist - после того, как вызывается persist для нового объекта
@PreRemove - прежде чем сущность будет удалена
@PostRemove - после удаления объекта
@PreUpdate - перед операцией обновления
@PostUpdate - после обновления сущности
@PostLoad - после загрузки объекта
Итак, если мы создаем новую сущность и вызываем метод сохранения нашего репозитория, вызывается наш метод, аннотированный
@PrePersist, затем запись вставляется в базу данных и, наконец, вызывается наш метод @PostPersist. Если мы используем @GeneratedValue для автоматической генерации наших первичных ключей, мы можем ожидать, что этот ключ будет доступен в методе @PostPersist.Для операций
@PostPersist, @PostRemove и @PostUpdate в документации упоминается, что эти события могут произойти сразу после выполнения операции или в конце транзакции.Следует отметить, что обратный вызов
@PreUpdate вызывается только в том случае, если данные действительно изменяются, то есть если необходимо выполнить фактический оператор обновления SQL. Обратный вызов @PostUpdate вызывается независимо от того, действительно ли что-то изменилось.Если какой-либо из наших обратных вызовов для сохранения или удаления объекта выдаст исключение, транзакция будет отменена.
@Entity
public class User {
private static Log log = LogFactory.getLog(User.class);
@Id
@GeneratedValue
private int id;
private String userName;
private String firstName;
private String lastName;
@Transient
private String fullName;
// getter and setter
@PrePersist
public void logNewUserAttempt() {
log.info("Attempting to add new user with username: " + userName);
}
@PostPersist
public void logNewUserAdded() {
log.info("Added user '" + userName + "' with ID: " + id);
}
@PreRemove
public void logUserRemovalAttempt() {
log.info("Attempting to delete user: " + userName);
}
@PostRemove
public void logUserRemoval() {
log.info("Deleted user: " + userName);
}
@PreUpdate
public void logUserUpdateAttempt() {
log.info("Attempting to update user: " + userName);
}
@PostUpdate
public void logUserUpdate() {
log.info("Updated user: " + userName);
}
@PostLoad
public void logUserLoad() {
fullName = firstName + " " + lastName;
}
}
#java #Entity #Lifecycle
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤4🔥1