This commit is contained in:
parent
8dfab937cd
commit
65abba8ae6
20
dev/devops/docker/Docker Network.md
Normal file
20
dev/devops/docker/Docker Network.md
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
aliases:
|
||||
tags:
|
||||
- maturity/🌱
|
||||
date:
|
||||
- - 2024-03-25
|
||||
zero-link:
|
||||
- "[[../../../meta/zero/00 Docker|00 Docker]]"
|
||||
parents:
|
||||
linked:
|
||||
---
|
||||
При запуске докера создается локальная сеть и поднимается NAT. При запуске контейнера ему выдается IP адрес из этой локальной сети. А когда мы открываем порт для контейнера в iptables добавляется новая запись переадресации с порта хостовой машины на соответсвующий контейнеру IP адрес и порт в локальной сети. Из-за этого немного проседает производительность.
|
||||
|
||||
Если контейнер не запущен в какой-то сети, то он будет видеть все остальные контейнеры, которые не привязаны к какой-то конкретной сети. То есть из одного докер контейнера можно средствами терминала подключиться к другому контейнеру используя его локальный IP адрес.
|
||||
|
||||
- Контейнер может быть подключен к нескольким сетям (без рестарта)
|
||||
- Работает Service Discovery
|
||||
- Можно задать произвольные диапазоны IP адресов
|
||||
## Дополнительные материалы
|
||||
- [Изменить IP-адрес подсети Docker по умолчанию](Изменить%20IP-адрес%20подсети%20Docker%20по%20умолчанию.md)
|
@ -12,7 +12,7 @@ parents:
|
||||
linked:
|
||||
link: https://struchkov.dev/blog/ru/java-binary-search/
|
||||
---
|
||||
### Без рекурсии
|
||||
## Без рекурсии
|
||||
```java
|
||||
public class Binary {
|
||||
|
||||
@ -43,7 +43,7 @@ public class Binary {
|
||||
}
|
||||
```
|
||||
|
||||
### С использованием рекурсии
|
||||
## С использованием рекурсии
|
||||
```java
|
||||
public class Binary {
|
||||
|
||||
|
137
dev/java/Использование wildcard imports в Java.md
Normal file
137
dev/java/Использование wildcard imports в Java.md
Normal file
@ -0,0 +1,137 @@
|
||||
---
|
||||
aliases:
|
||||
tags:
|
||||
- maturity/🌱
|
||||
- type/opinion
|
||||
date:
|
||||
- - 2024-09-06
|
||||
zero-link:
|
||||
- "[[../garden/ru/meta/zero/00 Java разработка|00 Java разработка]]"
|
||||
parents:
|
||||
linked:
|
||||
---
|
||||
Разработчики Java используют подстановочный знак (`*`) в операторах `import` для добавления всех классов из определенного пакета. Но в ходе ревью большинство из вас, возможно, просили убрать этот подстановочный знак импорта и добавить полное имя класса. Разберемся почему не стоит использовать знак подстановки?
|
||||
|
||||
Но прежде, давайте вспомним, что полное имя класса, помимо названия, содержит также пакет, например: `java.util.List`. ==Такая запись позволяет нам иметь классы с одинаковыми именами, которые находятся в разных пакетах.==
|
||||
|
||||
```java
|
||||
package com.example;
|
||||
|
||||
public class WithoutImport {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
java.util.List myList = new java.util.ArrayList();
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Однако, полная запись весьма непрактична, поэтому в Java существует оператор импорта – `import`. Операторы импорта объявляют компилятору источник имен классов, статических переменных и статических имен методов, используемых в коде. Один раз написали полное имя класса, а дальше используем только название класса.
|
||||
|
||||
```java
|
||||
package com.example;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class WithImport {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
List myList = new ArrayList();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Если мы скомпилируем и запустим эти примеры, результат будет одинаковым.
|
||||
|
||||
Импорт с подстановочными знаками указывает компилятору искать имена классов в данном пакете. Следовательно, при использовании импорта с wildcard производительность во время компиляции может немного снизиться. Но в большинстве случаев это не окажет заметного влияния.
|
||||
|
||||
Во время выполнения проблемы с производительностью нет, потому что операторы импорта являются директивами компилятора, и мы не можем найти их в байт-коде. Чтобы пояснить это, мы напишем приведенный выше пример с импортом с подстановочными знаками.
|
||||
|
||||
```java
|
||||
package com.example;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class WithWildCard {
|
||||
public static void main(String[] args) {
|
||||
|
||||
List myList = new ArrayList();
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Если мы получим байт-код этого класса, то он будет выглядеть следующим образом
|
||||
|
||||
```bytecode
|
||||
Compiled from "WithWildCard.java"
|
||||
public class com.example.WithWildCard {
|
||||
public com.example.WithWildCard();
|
||||
Code:
|
||||
0: aload_0
|
||||
1: invokespecial #1 // Method java/lang/Object."<init>":()V
|
||||
4: return
|
||||
|
||||
public static void main(java.lang.String[]);
|
||||
Code:
|
||||
0: new #2 // class java/util/ArrayList
|
||||
3: dup
|
||||
4: invokespecial #3 // Method java/util/ArrayList."<init>":()V
|
||||
7: astore_1
|
||||
8: return
|
||||
}
|
||||
```
|
||||
|
||||
Если сравнить его с байт-кодом прошлого примера, то они оба имеют одинаковый байт-код.
|
||||
|
||||
Во время выполнения Java использует байт-код, а не исходный код. ==В байт-коде нет операторов импорта.== Из этого ясно следует, что использование импорта с подстановочными знаками не влияет на производительность Java-приложения во время выполнения.
|
||||
|
||||
## Недостатки
|
||||
Так если использование подстановочного знака не приводит к проблемам производительности, то почему бы его не использовать?
|
||||
|
||||
### Конфликты имен
|
||||
Самая серьезная проблема это возможные конфликты именования. Представьте, что у нас есть два класса из разных библиотек `org.test.Parser` и `dev.lib.Parser`. В нашем коде мы используем импорт с wildcard:
|
||||
|
||||
```java
|
||||
import org.test.*
|
||||
import dev.lib.*
|
||||
```
|
||||
|
||||
Компилятор никак не отреагирует на наличие классов с одинаковыми именами в двух разных пакетах, импортируемых таким образом, если только не будет предпринята попытка воспользоваться одним из этих классов.
|
||||
|
||||
Также проблема может возникнуть в будущем, когда вы обновите версию какую-то из библиотек. Допустим у нас была библиотека с классом `org.test.Parser`, а потом разработчик второй библиотеки тоже добавил класс `dev.lib.Parser`, таким образом мы получили конфлик именования в будущем, хотя раньше все было нормально.
|
||||
### Чистый код
|
||||
Импорты с подстановочными знаками помогают нам избежать длинного списка импортов. Следовательно, это влияет на читабельность кода, так как читателю может потребоваться прокрутить много страниц в каждом файле исходного кода, прежде чем он доберется до кода, который показывает логику. Несомненно, более читабельный код - это также чистый код.
|
||||
|
||||
Эта идея также поддерживается в книге "Чистый код" Роберта К. Мартина. Фактически, книга рекомендует использовать импорты с подстановочными знаками при использовании нескольких классов из одного источника. Другими словами, когда мы импортируем два или более классов, импортированных из пакета, лучше импортировать весь пакет.
|
||||
|
||||
Однако, я не считаю это какой-то проблемой, так как IntelliJ IDEA автоматически скрывает все строки импортов.
|
||||
|
||||
![](../../meta/files/images/Pasted%20image%2020240906164456.png)
|
||||
|
||||
Также читаемость ухудшается, потому что разработчик не получает четкого представления о полном пути классов, используемых в коде.
|
||||
|
||||
Однако, это тоже не является проблемой. Достаточно удерживая Ctrl (cmd) навести курсор на класс и вы увидите пакет, в котором этот класс размещается.
|
||||
|
||||
![](../../meta/files/images/Pasted%20image%2020240906164524.png)
|
||||
|
||||
Таким образом проблемы "чистого кода" более не актуальны.
|
||||
|
||||
## Настройки в Idea
|
||||
Intellij Idea автоматически сворачивает импорты, когда полные импорты из какого-то пакета достигают заданного количества. Эта опция настраивается в раделе Preferences > Editor > Code Style > Java во вкладке imports.
|
||||
|
||||
![](../../meta/files/images/Pasted%20image%2020240906164551.png)
|
||||
|
||||
Чтобы отключить автоматическое сворачивание импортов достаточно указать число 999. Вот и все, теперь Idea не будет автоматически сворачивать импорты.
|
||||
|
||||
## Резюмирую
|
||||
Использование подстановочных импортов никак не повлияет на производительность программы во время выполнения, но может немного повлиять на производительность во время компиляции.
|
||||
|
||||
Также при обновлении библиотек вы можете столкнуться с проблемой конфликта имен. Шанс этой проблемы не велик, но и не нулевой.
|
||||
|
||||
Что касается "чистого кода", то с использованием современных IDE эта проблема не является актуальной.
|
29
dev/java/Не используйте @Data.md
Normal file
29
dev/java/Не используйте @Data.md
Normal file
@ -0,0 +1,29 @@
|
||||
---
|
||||
aliases:
|
||||
tags:
|
||||
- maturity/🌱
|
||||
- type/opinion
|
||||
date:
|
||||
- - 2023-11-20
|
||||
zero-link:
|
||||
- "[[00 Java разработка]]"
|
||||
parents:
|
||||
linked:
|
||||
article: https://struchkov.dev/blog/ru/do-not-use-lombok-data/
|
||||
---
|
||||
Многие разработчики в принципе против использования Lombok. В общем, это холиварная тема. Но вы используете Lombok в проекте, то не используйте хотя бы спорные и откровенно вредные аннотации.
|
||||
|
||||
Одна из таких – это `@Data`. Во-первых, [мало кто помнит, что она под собой скрывает](https://projectlombok.org/features/Data).
|
||||
|
||||
- `@ToString`. Не помню, когда последний раз переопределял `toString()`. А если объект содержит чувствительную информацию?
|
||||
- `@EqualsAndHashCode`. Это самая вредная аннотация в @Data. ==Потому что она генерирует `equals()` и `hashCode()` по всем полям.== Обычно вы не хотите, чтобы генерация осуществлялась по всем полям. Например, для сущности достаточно идентификатора.
|
||||
- `@Getter` / `@Setter`. Здесь ничего плохого.
|
||||
- `@RequiredArgsConstructor`. Тоже окей.
|
||||
|
||||
Основная проблема в `@EqualsAndHashCode`. Можно, конечно, использовать `@EqualsAndHashCode.Exclude`. Эта аннотация запрещает использовать поле при генерации, но вы хотите расставлять это над почти всеми полями в сущности? Потому что `@EqualsAndHashCode.Include` просто не сработает, нельзя объявить только нужные поля, нужно будет именно исключать все ненужные.
|
||||
|
||||
Также избегайте всех аннотаций из пакета `experemental`. Все аннотации из этого пакета могут работать не стабильно, и при этом могут быть удалены из следующих версий. Исключением из этого пакета является [@FieldNameConstants](https://projectlombok.org/features/experimental/FieldNameConstants), за пару лет с ней не было никаких проблем, а все имеющиеся альтернативы не очень.
|
||||
|
||||
С Lombok код выглядит чище, но, как и в случае с любым другим магическим инструментом, важно понимать, как именно он работает и когда его использовать. В противном случае производительность приложения может снизиться, либо оно вовсе может перестать работать корректно.
|
||||
## Дополнительные материалы
|
||||
- [Lombok + JPA: Что может пойти не так? / Хабр](https://habr.com/ru/company/haulmont/blog/564682/)
|
32
dev/java/Сравнение enum в Java.md
Normal file
32
dev/java/Сравнение enum в Java.md
Normal file
@ -0,0 +1,32 @@
|
||||
---
|
||||
aliases:
|
||||
tags:
|
||||
- maturity/🌱
|
||||
- type/opinion
|
||||
date:
|
||||
- - 2023-11-20
|
||||
zero-link:
|
||||
- "[[../../meta/zero/00 Java разработка|00 Java разработка]]"
|
||||
parents:
|
||||
linked:
|
||||
article: https://note.struchkov.dev/sravnieniie-enum-v-java/
|
||||
---
|
||||
Enum это объект, как и все в Java. Однако это особенный объект. Каждый из объектов енума создаётся только единожды. Давайте на примере:
|
||||
|
||||
```java
|
||||
enum TestEnum {ONE, TWO, THREE}
|
||||
```
|
||||
|
||||
Если мы создадим 10 переменных `TestEnum.ONE`, то все они будут ссылаться на один и тот же объект. И поэтому enum можно сравнивать с помощью `==` и это корректно и будет работать.
|
||||
|
||||
Сторонники такого подхода называют следующие преимущества. Давайте их разберем.
|
||||
|
||||
**Вы никогда не получите `NullPointerException`.** И это правда, но если вы будете придерживаться правила ["сравнение константы слева"](Сравнение%20константы%20слева%20в%20Java.md), то и при использовании `.equals()` `NullPointerException` вам не страшен.
|
||||
|
||||
**Оператор == работает быстрее.** Быстрее чего? Видимо метода `.equals()`. Давайте посмотрим реализацию метода `.equals()` у enum.
|
||||
|
||||
![](../../meta/files/images/Pasted%20image%2020231120093026.png)
|
||||
|
||||
**Оператор == более понятный синтаксически.** Это еще почему? Для сравнения объектов в Java используется `.equals()`. Enum это объект. Логичнее и очевиднее использовать `.equals()` для сравнения, чтобы не нарушать единообразие сравнения объектов.
|
||||
|
||||
На мой взгляд, правильнее использовать `.equals()`, главное не забывать о правиле "[Сравнение константы слева](Сравнение%20константы%20слева%20в%20Java.md)".
|
63
dev/java/Сравнение константы слева в Java.md
Normal file
63
dev/java/Сравнение константы слева в Java.md
Normal file
@ -0,0 +1,63 @@
|
||||
---
|
||||
aliases:
|
||||
tags:
|
||||
- maturity/🌱
|
||||
- type/opinion
|
||||
date:
|
||||
- - 2024-09-06
|
||||
zero-link:
|
||||
- "[[../../meta/zero/00 Java разработка|00 Java разработка]]"
|
||||
parents:
|
||||
linked:
|
||||
---
|
||||
Представьте, что у вас есть enum, который отвечает за статус пользователя в системе: "онлайн", "офлайн" и "занят".
|
||||
|
||||
```java
|
||||
public enum UserStatus {
|
||||
|
||||
ONLINE, OFFLINE, BUSY
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
public class User {
|
||||
|
||||
...
|
||||
|
||||
@Column(name = "status")
|
||||
@Enumerated(EnumType.STRING)
|
||||
private UserStatus status;
|
||||
|
||||
...
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Скорее всего для выполнения бизнес-логики вам потребуется проверять статус пользователя
|
||||
|
||||
```java
|
||||
if (user.getStatus().equals(UserStatus.ONLINE)) {
|
||||
// to do something
|
||||
}
|
||||
```
|
||||
|
||||
Вроде бы все отлично, миссия выполнена. Но есть одно НО. Что если `getStatus()` вернет вам `null`? Правильно, вы получите `NullPointerException`.
|
||||
|
||||
Чтобы этого избежать следует придерживаться правила "Сравнения константы слева". Оно очень простое. В нашем примере, мы точно уверены, что `UserStatus.ONLINE` существует, поэтому `.equals()` стоит вызывать от него.
|
||||
|
||||
```java
|
||||
if (UserStatus.ONLINE.equals(user.getStatus())) {
|
||||
// to do something
|
||||
}
|
||||
```
|
||||
|
||||
В остальных подобных ситуациях делайте также, например со строками:
|
||||
|
||||
```java
|
||||
if ("Иванов".equals(user.getLastName())) {
|
||||
// to do something
|
||||
}
|
||||
```
|
||||
|
||||
Это простое правило защитит вас от `NullPointerException`.
|
7
index.md
7
index.md
@ -19,8 +19,9 @@ enableToc: false
|
||||
- [Java разработка](meta/zero/00%20Java%20разработка.md)
|
||||
- [Quarkus](meta/zero/00%20Quarkus.md)
|
||||
- [SpringBoot](meta/zero/00%20SpringBoot.md)
|
||||
## Чего стоит избегать
|
||||
> [!WARNING] DISCLAMER
|
||||
> Приветствуются комментарии по теме заметки для улучшения и исправления фактических ошибок. Но ==не стоит указывать на грамматические ошибки или опечатки.== В первую очередь это мои заметки, которые можн
|
||||
- [00 Hibernate](meta/zero/00%20Hibernate.md)
|
||||
- [DevOps](meta/zero/00%20DevOps.md)
|
||||
- [Docker](meta/zero/00%20Docker.md)
|
||||
- [Алгоритмы](meta/zero/00%20Алгоритм.md)
|
||||
|
||||
|
||||
|
BIN
meta/files/images/Pasted image 20231120093026.png
Normal file
BIN
meta/files/images/Pasted image 20231120093026.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
BIN
meta/files/images/Pasted image 20240906164456.png
Normal file
BIN
meta/files/images/Pasted image 20240906164456.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 230 KiB |
BIN
meta/files/images/Pasted image 20240906164524.png
Normal file
BIN
meta/files/images/Pasted image 20240906164524.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 387 KiB |
BIN
meta/files/images/Pasted image 20240906164551.png
Normal file
BIN
meta/files/images/Pasted image 20240906164551.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 410 KiB |
7
meta/zero/00 DevOps.md
Normal file
7
meta/zero/00 DevOps.md
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
tags:
|
||||
- type/zero-link
|
||||
parents:
|
||||
- "[[00 Разработка]]"
|
||||
title: DevOps
|
||||
---
|
21
meta/zero/00 Docker.md
Normal file
21
meta/zero/00 Docker.md
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
tags:
|
||||
- type/zero-link
|
||||
zero-link:
|
||||
- "[[00 DevOps|00 DevOps]]"
|
||||
---
|
||||
Для изоляции и управления ресурсами контейнеров активно используется [cgroup](Control%20group.md). Так же для изоляции активно используется [Namespace](Namespace.md). Все это функционал ядра Linux, поэтому не оказывает сильного влияния на производительность. Однако, нужно быть осторожным при работе с диском и сетью. С сутью больше всего проблем, например при запуске nginx можно получить просадку в 5%.
|
||||
|
||||
Обычно docker запускается от root пользователя.
|
||||
|
||||
- [Команды Docker](Команды%20Docker.md)
|
||||
- [Dockerfile](Dockerfile.md)
|
||||
- [Docker Network](../../dev/devops/docker/Docker%20Network.md)
|
||||
- [Структура хранилища файлов Docker](Структура%20хранилища%20файлов%20Docker.md)
|
||||
- [Очистка мусора в Docker](Очистка%20мусора%20в%20Docker.md)
|
||||
- [Настройка ротации логов в Docker](Настройка%20ротации%20логов%20в%20Docker.md)
|
||||
## Полезное
|
||||
- Утилита для анализа докер образов: [Утилита Dive](Утилита%20Dive.md)
|
||||
- Утилита [Hadolint](https://github.com/hadolint/hadolint). Проверяет докер файл на плохие практики.
|
||||
- xfs более производительный
|
||||
- Native Overlay Diff рекомендуют отключать (docker info)
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
parents:
|
||||
zero-link:
|
||||
- "[[00 Java разработка]]"
|
||||
tags:
|
||||
- type/zero-link
|
||||
|
@ -9,8 +9,14 @@ title: Java разработка
|
||||
- [Устройство Java](Устройство%20Java.md)
|
||||
- [Снипеты для Java](../../../garden/ru/meta/zero/00%20Снипеты%20для%20Java.md)
|
||||
- Фреймворки
|
||||
- [SpringBoot](00%20SpringBoot.md)
|
||||
- [Quarkus](00%20Quarkus.md)
|
||||
- [SpringBoot](00%20SpringBoot.md)
|
||||
- [Hibernate](00%20Hibernate.md)
|
||||
## Мои рассуждения
|
||||
- [Использование wildcard imports в Java](../../dev/java/Использование%20wildcard%20imports%20в%20Java.md)
|
||||
- [Сравнение константы слева в Java](../../dev/java/Сравнение%20константы%20слева%20в%20Java.md)
|
||||
- [Сравнение enum в Java](../../dev/java/Сравнение%20enum%20в%20Java.md)
|
||||
- [Не используйте @Data](../../dev/java/Не%20используйте%20@Data.md)
|
||||
## Версии Java
|
||||
- [[Java 1]]
|
||||
- [Java 7](Java%207.md)
|
||||
|
Loading…
Reference in New Issue
Block a user