Исправление форматирования
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing

This commit is contained in:
Struchkov Mark 2024-09-17 21:10:50 +03:00
parent b4b8f83b1f
commit d0de9bc884
No known key found for this signature in database
GPG Key ID: A3F0AC3F0FA52F3C
34 changed files with 127 additions and 127 deletions

View File

@ -9,13 +9,13 @@ parents:
- "[[Реактивное программирование]]" - "[[Реактивное программирование]]"
linked: linked:
--- ---
По сути, Event Loop - это реализация [шаблона Reactor](http://design-pattern.ru/patterns/reactor.html). Является неблокирующим потоком ввода-вывода, который работает непрерывно. Его основная задача — проверка новых событий. И как только событие пришло перенаправлять его тому, кто в данный момент может его обработать. Иногда их может быть несколько для увеличения производительности.  По сути, Event Loop - это реализация [шаблона Reactor](http://design-pattern.ru/patterns/reactor.html). Является неблокирующим потоком ввода-вывода, который работает непрерывно. Его основная задача — проверка новых событий. И как только событие пришло перенаправлять его тому, кто в данный момент может его обработать. Иногда их может быть несколько для увеличения производительности.
![](../../meta/files/images/Pasted%20image%2020231026115508.png) ![](../../meta/files/images/Pasted%20image%2020231026115508.png)
Выше приведён абстрактный дизайн цикла событий, который представляет идеи реактивного асинхронного программирования: Выше приведён абстрактный дизайн цикла событий, который представляет идеи реактивного асинхронного программирования:
- Цикл событий выполняется непрерывно в одном потоке, хотя у нас может быть столько циклов событий, сколько доступно [[../fundamental/Ядро процессора|ядер]]. - Цикл событий выполняется непрерывно в одном потоке, хотя у нас может быть столько циклов событий, сколько доступно [[../fundamental/Ядро процессора|ядер]].
- Цикл событий последовательно обрабатывает события из очереди событий и возвращается сразу после регистрации [[../../../../_inbox/Callback|обратного вызова]] в платформе. - Цикл событий последовательно обрабатывает события из очереди событий и возвращается сразу после регистрации [[../../../../_inbox/Callback|обратного вызова]] в платформе.
- Платформа может инициировать завершение операции, такой как вызов базы данных или вызов внешней службы. - Платформа может инициировать завершение операции, такой как вызов базы данных или вызов внешней службы.
- Цикл событий может запускать обратный вызов при уведомлении о завершении операции и отправлять результат обратно исходному вызывающему. - Цикл событий может запускать обратный вызов при уведомлении о завершении операции и отправлять результат обратно исходному вызывающему.

View File

@ -13,7 +13,7 @@ linked: []
Самый простой способ побороть эту проблему, это использовать fingerprint файла. То есть, когда файл меняется, вы меняете его название. Делается это обычно добавлением какого-нибудь префикса/суфикса к названию файла. Самый простой способ побороть эту проблему, это использовать fingerprint файла. То есть, когда файл меняется, вы меняете его название. Делается это обычно добавлением какого-нибудь префикса/суфикса к названию файла.
Например у нас есть файл стилей `style.css`, мы можем посчитать для него [[../cryptography/MD5|MD5]] хеш и добавить его в название. Тогда у нас получится следующее название: `style.e626dd36e0085927f334adbe3eb38e7a.css`. Например у нас есть файл стилей `style.css`, мы можем посчитать для него [[../cryptography/MD5|MD5]] хеш и добавить его в название. Тогда у нас получится следующее название: `style.e626dd36e0085927f334adbe3eb38e7a.css`.
При любом изменении файла [[../cryptography/MD5|MD5]] хеш должен пересчитываться. Таким образом при изменении файла у него будет другое название, и браузер будет вынужден скачать его в любом случае. При любом изменении файла [[../cryptography/MD5|MD5]] хеш должен пересчитываться. Таким образом при изменении файла у него будет другое название, и браузер будет вынужден скачать его в любом случае.
*** ***

View File

@ -18,7 +18,7 @@ linked:
sudo mkdir -p /var/nginx/cache sudo mkdir -p /var/nginx/cache
``` ```
Чтобы включить кэширование, нужно прописать несколько директив в основной конфигурации `nginx.conf`. Чтобы включить кэширование, нужно прописать несколько директив в основной конфигурации `nginx.conf`.
```nginx ```nginx
http { http {
@ -29,16 +29,16 @@ http {
} }
``` ```
`proxy_cache_path` указывает путь в файловой системе. `proxy_cache_path` указывает путь в файловой системе.
Не кэшируйте HTTP-ответы при первом обращении. Используйте `proxy_cache_min_uses 2`, чтобы кэшировать только те элементы, к которым обращались более одного раза. Таким образом, вы уменьшите нагрузку прокси-кэша на запись и предотвратите заполнение кэша содержимым, к которому редко обращаются. Не кэшируйте HTTP-ответы при первом обращении. Используйте `proxy_cache_min_uses 2`, чтобы кэшировать только те элементы, к которым обращались более одного раза. Таким образом, вы уменьшите нагрузку прокси-кэша на запись и предотвратите заполнение кэша содержимым, к которому редко обращаются.
Ключ кэширования Nginx по умолчанию не очень хорошо работает с сайтами с несколькими поддоменами. Вы можете настроить ключ кэширования, задав proxy_cache_key. В своей конфигурации я использую вот такой ключ: `proxy_cache_key $scheme$host$uri$is_args$args;` Ключ кэширования Nginx по умолчанию не очень хорошо работает с сайтами с несколькими поддоменами. Вы можете настроить ключ кэширования, задав proxy_cache_key. В своей конфигурации я использую вот такой ключ: `proxy_cache_key $scheme$host$uri$is_args$args;`
## Переносим кэш Nginx в RAM ## Переносим кэш Nginx в RAM
Можно значительно ускорить кэш, если смонтировать его не в файловую систему а в RAM. Можно значительно ускорить кэш, если смонтировать его не в файловую систему а в RAM.
Для этого также создаем папку для кэша, можно использовать ту же, но ее нужно очистить от папок. Далее монтируем созданный каталог в RAM с помощью команды [tmpfs](https://wiki.archlinux.org/index.php/Tmpfs), выделяя 256 мегабайт под кэш: Для этого также создаем папку для кэша, можно использовать ту же, но ее нужно очистить от папок. Далее монтируем созданный каталог в RAM с помощью команды [tmpfs](https://wiki.archlinux.org/index.php/Tmpfs), выделяя 256 мегабайт под кэш:
```shell ```shell
sudo mount -t tmpfs -o size=256M tmpfs /var/nginx/cache sudo mount -t tmpfs -o size=256M tmpfs /var/nginx/cache
@ -50,7 +50,7 @@ sudo mount -t tmpfs -o size=256M tmpfs /var/nginx/cache
sudo umount /var/nginx/cache sudo umount /var/nginx/cache
``` ```
Чтобы автоматически пересоздать каталог к'ша в RAM после перезагрузки сервера, нам нужно обновить файл `/etc/fstab`. Добавьте в него следующую строку: Чтобы автоматически пересоздать каталог к'ша в RAM после перезагрузки сервера, нам нужно обновить файл `/etc/fstab`. Добавьте в него следующую строку:
```txt ```txt
tmpfs /var/nginx/cache tmpfs defaults,size=256M 0 0 tmpfs /var/nginx/cache tmpfs defaults,size=256M 0 0

View File

@ -22,7 +22,7 @@ linked:
![](../../meta/files/images/Pasted%20image%2020240319200211.png) ![](../../meta/files/images/Pasted%20image%2020240319200211.png)
## Почему простаивание потока — это проблема? ## Почему простаивание потока — это проблема?
Каждый поток нуждается в памяти для хранения своего стека вызовов и других связанных с ним структур данных. ==Когда поток простаивает, он продолжает потреблять ресурсы для поддержания своего состояния.== Каждый поток нуждается в памяти для хранения своего стека вызовов и других связанных с ним структур данных. ==Когда поток простаивает, он продолжает потреблять ресурсы для поддержания своего состояния.==
Кроме того, процессорное время, которое выделяется неработающим потокам, могло бы быть использовано для других задач. Если большое количество потоков простаивает, это может привести к увеличению загрузки процессора и снижению производительности, так как операционная система будет тратить больше времени на переключение между потоками. Кроме того, процессорное время, которое выделяется неработающим потокам, могло бы быть использовано для других задач. Если большое количество потоков простаивает, это может привести к увеличению загрузки процессора и снижению производительности, так как операционная система будет тратить больше времени на переключение между потоками.
## Заметки ## Заметки

View File

@ -9,10 +9,10 @@ zero-link:
parents: parents:
linked: linked:
--- ---
Циклические зависимости между сервисами возникают, когда сервисы взаимно внедряются друг в друга. Например, сервис А внедряет сервис Б, но в тоже время сервис Б внедряет сервис А. В этом случае [SpringBoot](../../meta/zero/00%20SpringBoot.md) и [Quarkus](../../meta/zero/00%20Quarkus.md) не знают, как создать такие бины и внедрить их друг в друга. Циклические зависимости между сервисами возникают, когда сервисы взаимно внедряются друг в друга. Например, сервис А внедряет сервис Б, но в тоже время сервис Б внедряет сервис А. В этом случае [SpringBoot](../../meta/zero/00%20SpringBoot.md) и [Quarkus](../../meta/zero/00%20Quarkus.md) не знают, как создать такие бины и внедрить их друг в друга.
> [!WARNING] > [!WARNING]
> Обычно такая ситуация сигнализирует о плохо продуманной архитектуре приложения.  > Обычно такая ситуация сигнализирует о плохо продуманной архитектуре приложения.
Пример циклической зависимости в Spring: Пример циклической зависимости в Spring:
@ -44,7 +44,7 @@ public class ServiceTwo {
Вот что вы можете с этим сделать: Вот что вы можете с этим сделать:
## Пересмотреть архитектуру приложения ## Пересмотреть архитектуру приложения
==Это предпочтительный вариант.== Возможно вам стоит создать сервис В, который внедрит в себя сервисы А и Б. В таком случае вы распутаете циклическую зависимость. ==Это предпочтительный вариант.== Возможно вам стоит создать сервис В, который внедрит в себя сервисы А и Б. В таком случае вы распутаете циклическую зависимость.
```java ```java
@Service @Service
@ -75,7 +75,7 @@ public class ServiceTwo {
} }
``` ```
## Ленивое внедрение ## Ленивое внедрение
В Spring вы можете указать аннотацию `@Lazy` у аргумента конструктора одного их сервисов. Таким образом сначала будет создан один сервис, для второго сервиса спринг создаст прокси класс, создаст из него бин и внедрит его в ваш сервис. После чего создаст второй сервис и внедрит туда уже созданный первый. А далее заменит ссылку с прокси объекта на второй сервис. В Spring вы можете указать аннотацию `@Lazy` у аргумента конструктора одного их сервисов. Таким образом сначала будет создан один сервис, для второго сервиса спринг создаст прокси класс, создаст из него бин и внедрит его в ваш сервис. После чего создаст второй сервис и внедрит туда уже созданный первый. А далее заменит ссылку с прокси объекта на второй сервис.
```java ```java
@Service @Service

View File

@ -19,13 +19,13 @@ linked:
ssh-keygen -t ed25519-sk -O resident -O application=ssh:key_name -f ~/.ssh/key_name ssh-keygen -t ed25519-sk -O resident -O application=ssh:key_name -f ~/.ssh/key_name
``` ```
Все как с обычными SSH ключами, появится 2 файла в папке ssh `key_name` и `key_name.pub`. Только вот, воспользоваться секретным ключом без подключения аппаратного ([Yubikey](Yubikey.md)) не выйдет. Все как с обычными SSH ключами, появится 2 файла в папке ssh `key_name` и `key_name.pub`. Только вот, воспользоваться секретным ключом без подключения аппаратного ([Yubikey](Yubikey.md)) не выйдет.
Флаги: Флаги:
- `-O verify-required`. Потребует вводить пароль от аппаратного ключа для доступа к SSH ключу. - `-O verify-required`. Потребует вводить пароль от аппаратного ключа для доступа к SSH ключу.
- `-O application=ssh:key_name`. Позволяет установить название ключу, которое можно будет увидеть в приложении Yubico Authentification. ![](../../meta/files/images/Pasted%20image%2020240113100105.png) - `-O application=ssh:key_name`. Позволяет установить название ключу, которое можно будет увидеть в приложении Yubico Authentification. ![](../../meta/files/images/Pasted%20image%2020240113100105.png)
Такой ключ подойдет и для доступа к репозиториям. Но необходимо будет прописать в `~/.ssh/config` информацию о том, какой ключ использовать: Такой ключ подойдет и для доступа к репозиториям. Но необходимо будет прописать в `~/.ssh/config` информацию о том, какой ключ использовать:
```yaml ```yaml
Host github.com Host github.com

View File

@ -74,7 +74,7 @@ MySQL не решает из коробки проблемы кластериз
*** ***
- В InnoDB, заметьте, т.е. у нас архитектура разделяет репликацию выше, а storage engine ниже. Но storage engine, для того, чтобы репликация работала, должен, грубо говоря, замедлять insert'ы в таблицу. - В InnoDB, заметьте, т.е. у нас архитектура разделяет репликацию выше, а storage engine ниже. Но storage engine, для того, чтобы репликация работала, должен, грубо говоря, замедлять insert'ы в таблицу.
- Другая проблема состоит в том, что мастер выполняет запросы параллельно, т.е. одновременно, а слэйв их может применять последовательно. Возникает вопрос а почему слэйв не может применять их параллельно? На самом деле, с этим все непросто. Есть теорема о сериализации транзакций, которая рассказывает, когда мы можем выполнять запросы параллельно, а когда последовательно. Это отдельная сложная тема, разберитесь в ней, если вам интересно и нужно, например, почитав по ссылке  [http://plumqqz.livejournal.com/387380.html](http://plumqqz.livejournal.com/387380.html). - Другая проблема состоит в том, что мастер выполняет запросы параллельно, т.е. одновременно, а слэйв их может применять последовательно. Возникает вопрос а почему слэйв не может применять их параллельно? На самом деле, с этим все непросто. Есть теорема о сериализации транзакций, которая рассказывает, когда мы можем выполнять запросы параллельно, а когда последовательно. Это отдельная сложная тема, разберитесь в ней, если вам интересно и нужно, например, почитав по ссылке [http://plumqqz.livejournal.com/387380.html](http://plumqqz.livejournal.com/387380.html).
- В MySQL репликация упирается в процессор. Это прекрасная картинка большой, мощный сервер, 12 ядер. Работает одно ядро, заодно занято репликацией. Из-за этого реплика задыхается. Это очень грустно. - В MySQL репликация упирается в процессор. Это прекрасная картинка большой, мощный сервер, 12 ядер. Работает одно ядро, заодно занято репликацией. Из-за этого реплика задыхается. Это очень грустно.
Для того чтобы выполнять запросы параллельно существует группировка запросов. В InnoDB есть специальная опция, которая управляет тем, как именно мы группируем транзакции, как именно мы их пишем на диск. Проблема в том, что мы можем их сгруппировать на уровне InnoDB, а уровнем выше на уровне репликации этой функциональности не было. В 2010 г. Кристиан Нельсен из MariaDB реализовал такую фичу, которая называется Group Binary Log Commit. Получается, мы журнал повторяем на двух уровнях Storage Engine и репликация, и нам нужно таскать фичи из одного уровня на другой. Это сложный механизм. Более того, нам нужно одновременно консистентно писать сразу в два журнала two-phase-commit. Это еще хуже. Для того чтобы выполнять запросы параллельно существует группировка запросов. В InnoDB есть специальная опция, которая управляет тем, как именно мы группируем транзакции, как именно мы их пишем на диск. Проблема в том, что мы можем их сгруппировать на уровне InnoDB, а уровнем выше на уровне репликации этой функциональности не было. В 2010 г. Кристиан Нельсен из MariaDB реализовал такую фичу, которая называется Group Binary Log Commit. Получается, мы журнал повторяем на двух уровнях Storage Engine и репликация, и нам нужно таскать фичи из одного уровня на другой. Это сложный механизм. Более того, нам нужно одновременно консистентно писать сразу в два журнала two-phase-commit. Это еще хуже.

View File

@ -59,7 +59,7 @@ Logical Decoding способ визуализировать то, что н
### Дополнительные материалы ### Дополнительные материалы
- [[Настройка репликации в PostgreSQL]] - [[Настройка репликации в PostgreSQL]]
- [BDR User Guide - PostgreSQL wiki](https://wiki.postgresql.org/wiki/Logical_Log_Streaming_Replication) - [BDR User Guide - PostgreSQL wiki](https://wiki.postgresql.org/wiki/Logical_Log_Streaming_Replication)
- [PostgreSQL: Documentation: 16: Chapter 31. Logical Replication](https://www.postgresql.org/docs/current/logical-replication.html) - [PostgreSQL: Documentation: 16: Chapter 31. Logical Replication](https://www.postgresql.org/docs/current/logical-replication.html)
- [PostgreSQL: Documentation: 9.4: Logical Decoding](https://www.postgresql.org/docs/9.4/logicaldecoding.html). Аналог [libslave](libslave.md) в MySQL - [PostgreSQL: Documentation: 9.4: Logical Decoding](https://www.postgresql.org/docs/9.4/logicaldecoding.html). Аналог [libslave](libslave.md) в MySQL
- [Отладка и устранение проблем в PostgreSQL Streaming Replication / Хабр](https://m.habr.com/ru/company/oleg-bunin/blog/414111/) - [Отладка и устранение проблем в PostgreSQL Streaming Replication / Хабр](https://m.habr.com/ru/company/oleg-bunin/blog/414111/)
- [An Overview of Logical Replication in PostgreSQL | Severalnines](https://severalnines.com/blog/overview-logical-replication-postgresql/) - [An Overview of Logical Replication in PostgreSQL | Severalnines](https://severalnines.com/blog/overview-logical-replication-postgresql/)

View File

@ -14,7 +14,7 @@ linked:
Для решения этой проблемы нужно изменить подсеть Docker по умолчанию. Таким образом, вы можете выбрать те подсети, которые не конфликтует с вашей корпоративной сетью. Для решения этой проблемы нужно изменить подсеть Docker по умолчанию. Таким образом, вы можете выбрать те подсети, которые не конфликтует с вашей корпоративной сетью.
Откройте файл настроек `/etc/docker/daemon.json` и введите IP-адрес сетевой маски: Откройте файл настроек `/etc/docker/daemon.json` и введите IP-адрес сетевой маски:
```json ```json
{ {

View File

@ -9,7 +9,7 @@ zero-link:
parents: parents:
linked: linked:
--- ---
Гайдов, как устанавливать docker полно в интернете. [Официальная документации](https://docs.docker.com/engine/install/) написана доступным языком. Гайдов, как устанавливать docker полно в интернете. [Официальная документации](https://docs.docker.com/engine/install/) написана доступным языком.
Команды установки docker для CentOS 8 и RHEL 8. Команды установки docker для CentOS 8 и RHEL 8.
@ -31,7 +31,7 @@ chmod +x ~/.docker/cli-plugins/docker-compose
[Актуальная версия docker-compose](https://github.com/docker/compose/releases/) [Актуальная версия docker-compose](https://github.com/docker/compose/releases/)
> [!INFO] > [!INFO]
> Эта команда устанавливает Compose V2 для активного пользователя в каталог `$HOME`. Чтобы установить Docker Compose для всех пользователей вашей системы, замените `~/.docker/cli-plugins` на `/usr/local/lib/docker/cli-plugins`. > Эта команда устанавливает Compose V2 для активного пользователя в каталог `$HOME`. Чтобы установить Docker Compose для всех пользователей вашей системы, замените `~/.docker/cli-plugins` на `/usr/local/lib/docker/cli-plugins`.
Проверяем, что установка прошла успешно. Проверяем, что установка прошла успешно.
@ -41,7 +41,7 @@ Docker Compose 2.2.3
``` ```
> [!WARNING] > [!WARNING]
> Также обращаю ваше внимание, что в Compose V1 для работы использовалась команда `docker-compose`, а в V2 отказались от дефиса `docker compose` > Также обращаю ваше внимание, что в Compose V1 для работы использовалась команда `docker-compose`, а в V2 отказались от дефиса `docker compose`
*** ***
## Мета информация ## Мета информация

View File

@ -12,7 +12,7 @@ linked:
В такие моменты главное не поддаваться панике 😅 В такие моменты главное не поддаваться панике 😅
В Idea есть [замечательная функция LocalHisotry](https://www.jetbrains.com/help/idea/local-history.html), которая автоматически сохраняет все изменения над файлами. Если затертых файлов было не много, то нажмите ПКМ и в меню выберете `Local History —> Show History`. В Idea есть [замечательная функция LocalHisotry](https://www.jetbrains.com/help/idea/local-history.html), которая автоматически сохраняет все изменения над файлами. Если затертых файлов было не много, то нажмите ПКМ и в меню выберете `Local History —> Show History`.
![](../../meta/files/images/Pasted%20image%2020240908122428.png) ![](../../meta/files/images/Pasted%20image%2020240908122428.png)

View File

@ -11,7 +11,7 @@ linked:
--- ---
Когда-то давным давно скачал [JDK](JDK.md), работает и ладно. Посмотрел доклад про [нативные сборки](Нативные%20сборки%20в%20Java.md), и там упоминалось про [JDK](JDK.md) для Apple Silicon. Решил проверить, а такой ли у меня. Оказалось не такой. Когда-то давным давно скачал [JDK](JDK.md), работает и ладно. Посмотрел доклад про [нативные сборки](Нативные%20сборки%20в%20Java.md), и там упоминалось про [JDK](JDK.md) для Apple Silicon. Решил проверить, а такой ли у меня. Оказалось не такой.
В итоге вот сколько собирался большой [монолит](../../../../_inbox/Монолитная%20архитектура.md) (с генерацией javadoc), состоящий из 22 модуля на обычной [JDK](JDK.md). Все зависимости были закачены заранее и сборка была запущена в [многопоточном режиме](Параллельная%20сборка%20модулей%20в%20Maven.md). В итоге вот сколько собирался большой [монолит](../../../../_inbox/Монолитная%20архитектура.md) (с генерацией javadoc), состоящий из 22 модуля на обычной [JDK](JDK.md). Все зависимости были закачены заранее и сборка была запущена в [многопоточном режиме](Параллельная%20сборка%20модулей%20в%20Maven.md).
![](../../meta/files/images/Pasted%20image%2020240908115826.png) ![](../../meta/files/images/Pasted%20image%2020240908115826.png)

View File

@ -9,9 +9,9 @@ zero-link:
parents: parents:
linked: linked:
--- ---
Столкнулся с неочевидным поведением `@ElementCollection` в связке с `@OneToMany`. Может случиться так, что в `@OneToMany` будет дублирование значений из-за `@ElementCollection`. Проще объяснить на примере. Столкнулся с неочевидным поведением `@ElementCollection` в связке с `@OneToMany`. Может случиться так, что в `@OneToMany` будет дублирование значений из-за `@ElementCollection`. Проще объяснить на примере.
Допустим у нас есть три таблицы: `user`, `user_nickname`, `address`. Есть сущность `User`: Допустим у нас есть три таблицы: `user`, `user_nickname`, `address`. Есть сущность `User`:
```java ```java
@Entity @Entity
@ -37,15 +37,15 @@ public class User {
Допустим у нас одна запись про пользователя, у которого есть три адреса и один никнейм. В этом случае все хорошо, все придет корректно. Допустим у нас одна запись про пользователя, у которого есть три адреса и один никнейм. В этом случае все хорошо, все придет корректно.
==Добавим этому пользователю еще один никнейм. Теперь мы получаем шесть адресов и два никнейма. Откуда взялись еще три лишних адреса, в базе данных их все еще три.== Это дубликаты. При этом, если вы воспользуетесь пагинацией JPA, то дублей уже не будет. It is magic 💫 ==Добавим этому пользователю еще один никнейм. Теперь мы получаем шесть адресов и два никнейма. Откуда взялись еще три лишних адреса, в базе данных их все еще три.== Это дубликаты. При этом, если вы воспользуетесь пагинацией JPA, то дублей уже не будет. It is magic 💫
Магии в программировании, как вы понимаете, нет. Они создаются при использовании `FetchType.EAGER` у `@OneToMany` в совокупности с `@ElementCollection(fetch = FetchType.EAGER)`. Hibernate генерирует запрос с двумя-тремя полными соединениями, отсюда и берутся дубли. При этом в пагинации Hibernate не генерирует джойны, а использует кучу селектов, отсюда и отсутствие дублей при пагинации. Магии в программировании, как вы понимаете, нет. Они создаются при использовании `FetchType.EAGER` у `@OneToMany` в совокупности с `@ElementCollection(fetch = FetchType.EAGER)`. Hibernate генерирует запрос с двумя-тремя полными соединениями, отсюда и берутся дубли. При этом в пагинации Hibernate не генерирует джойны, а использует кучу селектов, отсюда и отсутствие дублей при пагинации.
Эта проблема решается несколькими способами: Эта проблема решается несколькими способами:
- Переделайте `List` в `Set` у `@OneToMany`. - Переделайте `List` в `Set` у `@OneToMany`.
- Уберите `FetchType.EAGER` у `@OneToMany`. - Уберите `FetchType.EAGER` у `@OneToMany`.
- Добавьте `@Fetch(FetchMode.SUBSELECT)` у `@OneToMany`. это аннотация Hibernate, которая вместо JOIN использует подзапрос. О [подзапросах я писал в отдельной статье](https://struchkov.dev/blog/ru/select-subquery). - Добавьте `@Fetch(FetchMode.SUBSELECT)` у `@OneToMany`. это аннотация Hibernate, которая вместо JOIN использует подзапрос. О [подзапросах я писал в отдельной статье](https://struchkov.dev/blog/ru/select-subquery).
*** ***
## Мета информация ## Мета информация
**Область**:: [[../../../meta/zero/00 Hibernate|00 Hibernate]] **Область**:: [[../../../meta/zero/00 Hibernate|00 Hibernate]]

View File

@ -12,7 +12,7 @@ linked:
--- ---
Провозился два дня, но в итоге смог собрать один из микро-сервисов в нативном режиме. Ничего сложного, но было много нюансов в настройке CICD. Провозился два дня, но в итоге смог собрать один из микро-сервисов в нативном режиме. Ничего сложного, но было много нюансов в настройке CICD.
Самое полезное, это вот [эта документация Quarkus](https://quarkus.io/guides/building-native-image). А конкретно флаги: Самое полезное, это вот [эта документация Quarkus](https://quarkus.io/guides/building-native-image). А конкретно флаги:
- `-Dquarkus.native.container-build=true` - `-Dquarkus.native.container-build=true`
- `-Dquarkus.native.remote-container-build=true` - `-Dquarkus.native.remote-container-build=true`
@ -46,7 +46,7 @@ CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
Сервис стал собираться в 2,5 раза больше, около 5 минут, вместо 2. Но теперь он стартует моментально, наверное за доли секунды. При этом на под выделяется всего 256 mb ОЗУ на старте и 512 mb в момент работы. Сервис стал собираться в 2,5 раза больше, около 5 минут, вместо 2. Но теперь он стартует моментально, наверное за доли секунды. При этом на под выделяется всего 256 mb ОЗУ на старте и 512 mb в момент работы.
## Более сложный путь ## Более сложный путь
Также слепил образ для GitLab-раннера, который совмещает GraalVM и Docker, осталось добавить в него Gradle, но пока использую `./gradlew`. Оставлю это тут на всякий случай. Также слепил образ для GitLab-раннера, который совмещает GraalVM и Docker, осталось добавить в него Gradle, но пока использую `./gradlew`. Оставлю это тут на всякий случай.
```Dockerfile ```Dockerfile
FROM ghcr.io/graalvm/graalvm-ce:ol9-java17-22.3.0 FROM ghcr.io/graalvm/graalvm-ce:ol9-java17-22.3.0

View File

@ -72,16 +72,16 @@ public class Binary {
} }
``` ```
Если элемент не найден, то вернется `-1`. Если элемент не найден, то вернется `-1`.
> [!WARNING] m = l + (r - l) / 2; > [!WARNING] m = l + (r - l) / 2;
> Во многих примерах в интернете можно встретить запись `int m = (l + r) / 2;`, вместо `int mid = l + (r - l) / 2;`. > Во многих примерах в интернете можно встретить запись `int m = (l + r) / 2;`, вместо `int mid = l + (r - l) / 2;`.
> >
> Но использование второго варианта является лучшей практикой, так как это помогает избежать переполнения, когда размер массива велик. > Но использование второго варианта является лучшей практикой, так как это помогает избежать переполнения, когда размер массива велик.
> >
> Например, если `l = 2147483647` и `r = 2147483647`, сумма `l` и `r` будет равна 4294967294, что превышает максимальное значение, которое может хранить `int`, вызывая переполнение. > Например, если `l = 2147483647` и `r = 2147483647`, сумма `l` и `r` будет равна 4294967294, что превышает максимальное значение, которое может хранить `int`, вызывая переполнение.
> >
> С другой стороны, если вы используете `mid = l + (r - l) / 2;` это будет работать, как и ожидалось, потому что вычитание будет сделано первым, а результат будет равен нулю, поэтому деление будет равно нулю, а сложение вернет значение `l`. > С другой стороны, если вы используете `mid = l + (r - l) / 2;` это будет работать, как и ожидалось, потому что вычитание будет сделано первым, а результат будет равен нулю, поэтому деление будет равно нулю, а сложение вернет значение `l`.
*** ***
## Мета информация ## Мета информация

View File

@ -9,9 +9,9 @@ zero-link:
parents: parents:
linked: linked:
--- ---
Разработчики Java используют подстановочный знак (`*`) в операторах `import` для добавления всех классов из определенного пакета. Но в ходе ревью большинство из вас, возможно, просили убрать этот подстановочный знак импорта и добавить полное имя класса. Разберемся почему не стоит использовать знак подстановки? Разработчики Java используют подстановочный знак (`*`) в операторах `import` для добавления всех классов из определенного пакета. Но в ходе ревью большинство из вас, возможно, просили убрать этот подстановочный знак импорта и добавить полное имя класса. Разберемся почему не стоит использовать знак подстановки?
Но прежде, давайте вспомним, что полное имя класса, помимо названия, содержит также пакет, например: `java.util.List`. ==Такая запись позволяет нам иметь классы с одинаковыми именами, которые находятся в разных пакетах.== Но прежде, давайте вспомним, что полное имя класса, помимо названия, содержит также пакет, например: `java.util.List`. ==Такая запись позволяет нам иметь классы с одинаковыми именами, которые находятся в разных пакетах.==
```java ```java
package com.example; package com.example;
@ -26,7 +26,7 @@ public class WithoutImport {
} }
``` ```
Однако, полная запись весьма непрактична, поэтому в Java существует оператор импорта  `import`. Операторы импорта объявляют компилятору источник имен классов, статических переменных и статических имен методов, используемых в коде. Один раз написали полное имя класса, а дальше используем только название класса. Однако, полная запись весьма непрактична, поэтому в Java существует оператор импорта `import`. Операторы импорта объявляют компилятору источник имен классов, статических переменных и статических имен методов, используемых в коде. Один раз написали полное имя класса, а дальше используем только название класса.
```java ```java
package com.example; package com.example;
@ -88,13 +88,13 @@ public class com.example.WithWildCard {
Если сравнить его с байт-кодом прошлого примера, то они оба имеют одинаковый байт-код. Если сравнить его с байт-кодом прошлого примера, то они оба имеют одинаковый байт-код.
Во время выполнения Java использует байт-код, а не исходный код. ==В байт-коде нет операторов импорта.== Из этого ясно следует, что использование импорта с подстановочными знаками не влияет на производительность Java-приложения во время выполнения. Во время выполнения Java использует байт-код, а не исходный код. ==В байт-коде нет операторов импорта.== Из этого ясно следует, что использование импорта с подстановочными знаками не влияет на производительность Java-приложения во время выполнения.
## Недостатки ## Недостатки
Так если использование подстановочного знака не приводит к проблемам производительности, то почему бы его не использовать? Так если использование подстановочного знака не приводит к проблемам производительности, то почему бы его не использовать?
### Конфликты имен ### Конфликты имен
Самая серьезная проблема это возможные конфликты именования. Представьте, что у нас есть два класса из разных библиотек `org.test.Parser` и `dev.lib.Parser`. В нашем коде мы используем импорт с wildcard: Самая серьезная проблема это возможные конфликты именования. Представьте, что у нас есть два класса из разных библиотек `org.test.Parser` и `dev.lib.Parser`. В нашем коде мы используем импорт с wildcard:
```java ```java
import org.test.* import org.test.*
@ -103,7 +103,7 @@ import dev.lib.*
Компилятор никак не отреагирует на наличие классов с одинаковыми именами в двух разных пакетах, импортируемых таким образом, если только не бу­дет предпринята попытка воспользоваться одним из этих классов. Компилятор никак не отреагирует на наличие классов с одинаковыми именами в двух разных пакетах, импортируемых таким образом, если только не бу­дет предпринята попытка воспользоваться одним из этих классов.
Также проблема может возникнуть в будущем, когда вы обновите версию какую-то из библиотек. Допустим у нас была библиотека с классом `org.test.Parser`, а потом разработчик второй библиотеки тоже добавил класс `dev.lib.Parser`, таким образом мы получили конфлик именования в будущем, хотя раньше все было нормально. Также проблема может возникнуть в будущем, когда вы обновите версию какую-то из библиотек. Допустим у нас была библиотека с классом `org.test.Parser`, а потом разработчик второй библиотеки тоже добавил класс `dev.lib.Parser`, таким образом мы получили конфлик именования в будущем, хотя раньше все было нормально.
### Чистый код ### Чистый код
Импорты с подстановочными знаками помогают нам избежать длинного списка импортов. Следовательно, это влияет на читабельность кода, так как читателю может потребоваться прокрутить много страниц в каждом файле исходного кода, прежде чем он доберется до кода, который показывает логику. Несомненно, более читабельный код - это также чистый код. Импорты с подстановочными знаками помогают нам избежать длинного списка импортов. Следовательно, это влияет на читабельность кода, так как читателю может потребоваться прокрутить много страниц в каждом файле исходного кода, прежде чем он доберется до кода, который показывает логику. Несомненно, более читабельный код - это также чистый код.

View File

@ -21,7 +21,7 @@ SonarLint работает так же, как статический анали
Если ваш проект анализируется в SonarQube или SonarCloud, SonarLint может подключиться к серверу, чтобы получить соответствующие профили качества и настройки для этого проекта. Если ваш проект анализируется в SonarQube или SonarCloud, SonarLint может подключиться к серверу, чтобы получить соответствующие профили качества и настройки для этого проекта.
**Кому рекомендую:** Если вы Junior, то для вас это незаменимый инструмент, который позволит улучшить ваш код. **Кому рекомендую:** Если вы Junior, то для вас это незаменимый инструмент, который позволит улучшить ваш код.
**Ссылка для установки:** [SonarLint - IntelliJ IDEs Plugin | Marketplace](https://plugins.jetbrains.com/plugin/7973-sonarlint) **Ссылка для установки:** [SonarLint - IntelliJ IDEs Plugin | Marketplace](https://plugins.jetbrains.com/plugin/7973-sonarlint)
## Translation ## Translation
@ -37,11 +37,11 @@ SonarLint работает так же, как статический анали
- Перевод JavaDoc - Перевод JavaDoc
- Озвучивание текста - Озвучивание текста
**Кому подойдет:** Этот плагин для тех, кто плохо знает английский язык. **Кому подойдет:** Этот плагин для тех, кто плохо знает английский язык.
**Ссылка на установку:** [Translation - IntelliJ IDEs Plugin | Marketplace](https://plugins.jetbrains.com/plugin/8579-translation) **Ссылка на установку:** [Translation - IntelliJ IDEs Plugin | Marketplace](https://plugins.jetbrains.com/plugin/8579-translation)
## .ignore ## .ignore
Простой плагин, который помогает генерировать файлы исключений, такие как `.gitignore` и `.dockerignore`. Простой плагин, который помогает генерировать файлы исключений, такие как `.gitignore` и `.dockerignore`.
![](../../meta/files/images/plugin-ignore.gif) ![](../../meta/files/images/plugin-ignore.gif)
@ -61,7 +61,7 @@ SonarLint работает так же, как статический анали
## Presentation Assistant ## Presentation Assistant
Этот плагин отлично дополнит ваш live coding, потому что его задача ненавязчиво выводить комбинации клавиш, которые вы нажимаете. Даже если вы не будете нажимать сочетание клавиш, а просто кликаете мышкой, но для этого есть хоткей, то он также будет выведен. Этот плагин отлично дополнит ваш live coding, потому что его задача ненавязчиво выводить комбинации клавиш, которые вы нажимаете. Даже если вы не будете нажимать сочетание клавиш, а просто кликаете мышкой, но для этого есть хоткей, то он также будет выведен.
**Кому подойдет:** Тем кто проводит вебинары. Также он мне больше нравится, чем Key Promoter X для изучения хоткеев. **Кому подойдет:** Тем кто проводит вебинары. Также он мне больше нравится, чем Key Promoter X для изучения хоткеев.
![](../../meta/files/images/Pasted%20image%2020240908110354.png) ![](../../meta/files/images/Pasted%20image%2020240908110354.png)

View File

@ -11,16 +11,16 @@ linked:
--- ---
Многие разработчики в принципе против использования Lombok. В общем, это холиварная тема. Но вы используете Lombok в проекте, то не используйте хотя бы спорные и откровенно вредные аннотации. Многие разработчики в принципе против использования Lombok. В общем, это холиварная тема. Но вы используете Lombok в проекте, то не используйте хотя бы спорные и откровенно вредные аннотации.
Одна из таких это `@Data`. Во-первых, [мало кто помнит, что она под собой скрывает](https://projectlombok.org/features/Data). Одна из таких это `@Data`. Во-первых, [мало кто помнит, что она под собой скрывает](https://projectlombok.org/features/Data).
- `@ToString`. Не помню, когда последний раз переопределял `toString()`. А если объект содержит чувствительную информацию? - `@ToString`. Не помню, когда последний раз переопределял `toString()`. А если объект содержит чувствительную информацию?
- `@EqualsAndHashCode`. Это самая вредная аннотация в @Data. ==Потому что она генерирует `equals()` и `hashCode()` по всем полям.== Обычно вы не хотите, чтобы генерация осуществлялась по всем полям. Например, для сущности достаточно идентификатора. - `@EqualsAndHashCode`. Это самая вредная аннотация в @Data. ==Потому что она генерирует `equals()` и `hashCode()` по всем полям.== Обычно вы не хотите, чтобы генерация осуществлялась по всем полям. Например, для сущности достаточно идентификатора.
- `@Getter` / `@Setter`. Здесь ничего плохого. - `@Getter` / `@Setter`. Здесь ничего плохого.
- `@RequiredArgsConstructor`. Тоже окей. - `@RequiredArgsConstructor`. Тоже окей.
Основная проблема в `@EqualsAndHashCode`. Можно, конечно, использовать `@EqualsAndHashCode.Exclude`. Эта аннотация запрещает использовать поле при генерации, но вы хотите расставлять это над почти всеми полями в сущности? Потому что `@EqualsAndHashCode.Include` просто не сработает, нельзя объявить только нужные поля, нужно будет именно исключать все ненужные. Основная проблема в `@EqualsAndHashCode`. Можно, конечно, использовать `@EqualsAndHashCode.Exclude`. Эта аннотация запрещает использовать поле при генерации, но вы хотите расставлять это над почти всеми полями в сущности? Потому что `@EqualsAndHashCode.Include` просто не сработает, нельзя объявить только нужные поля, нужно будет именно исключать все ненужные.
Также избегайте всех аннотаций из пакета `experemental`. Все аннотации из этого пакета могут работать не стабильно, и при этом могут быть удалены из следующих версий. Исключением из этого пакета является [@FieldNameConstants](https://projectlombok.org/features/experimental/FieldNameConstants), за пару лет с ней не было никаких проблем, а все имеющиеся альтернативы не очень. Также избегайте всех аннотаций из пакета `experemental`. Все аннотации из этого пакета могут работать не стабильно, и при этом могут быть удалены из следующих версий. Исключением из этого пакета является [@FieldNameConstants](https://projectlombok.org/features/experimental/FieldNameConstants), за пару лет с ней не было никаких проблем, а все имеющиеся альтернативы не очень.
С Lombok код выглядит чище, но, как и в случае с любым другим магическим инструментом, важно понимать, как именно он работает и когда его использовать. В противном случае производительность приложения может снизиться, либо оно вовсе может перестать работать корректно. С Lombok код выглядит чище, но, как и в случае с любым другим магическим инструментом, важно понимать, как именно он работает и когда его использовать. В противном случае производительность приложения может снизиться, либо оно вовсе может перестать работать корректно.
*** ***

View File

@ -22,7 +22,7 @@ mvn -T 1C clean install
![400](../../meta/files/images/Pasted%20image%2020231120092703.png) ![400](../../meta/files/images/Pasted%20image%2020231120092703.png)
По факту эти группы модулей зависят только друг от друга. Сначала собирается группа `domain`, от нее зависит группа `context`, потом core и так далее. Без `context` не собрать `core`, думаю суть понятна. Но вот модули core не зависят друг от друга, и могут собираться параллельно. По факту эти группы модулей зависят только друг от друга. Сначала собирается группа `domain`, от нее зависит группа `context`, потом core и так далее. Без `context` не собрать `core`, думаю суть понятна. Но вот модули core не зависят друг от друга, и могут собираться параллельно.
Для примера вот время сборки в последовательном режиме: Для примера вот время сборки в последовательном режиме:

View File

@ -15,19 +15,19 @@ Enum это объект, как и все в Java. Однако это особ
enum TestEnum {ONE, TWO, THREE} enum TestEnum {ONE, TWO, THREE}
``` ```
Если мы создадим 10 переменных `TestEnum.ONE`, то все они будут ссылаться на один и тот же объект. И поэтому enum можно сравнивать с помощью `==` и это корректно и будет работать. Если мы создадим 10 переменных `TestEnum.ONE`, то все они будут ссылаться на один и тот же объект. И поэтому enum можно сравнивать с помощью `==` и это корректно и будет работать.
Сторонники такого подхода называют следующие преимущества. Давайте их разберем. Сторонники такого подхода называют следующие преимущества. Давайте их разберем.
**Вы никогда не получите `NullPointerException`.** И это правда, но если вы будете придерживаться правила ["сравнение константы слева"](Сравнение%20константы%20слева%20в%20Java.md), то и при использовании `.equals()` `NullPointerException` вам не страшен. **Вы никогда не получите `NullPointerException`.** И это правда, но если вы будете придерживаться правила ["сравнение константы слева"](Сравнение%20константы%20слева%20в%20Java.md), то и при использовании `.equals()` `NullPointerException` вам не страшен.
**Оператор == работает быстрее.** Быстрее чего? Видимо метода `.equals()`. Давайте посмотрим реализацию метода `.equals()` у enum. **Оператор == работает быстрее.** Быстрее чего? Видимо метода `.equals()`. Давайте посмотрим реализацию метода `.equals()` у enum.
![](../../meta/files/images/Pasted%20image%2020231120093026.png) ![](../../meta/files/images/Pasted%20image%2020231120093026.png)
**Оператор == более понятный синтаксически.** Это еще почему? Для сравнения объектов в Java используется `.equals()`. Enum это объект. Логичнее и очевиднее использовать `.equals()` для сравнения, чтобы не нарушать единообразие сравнения объектов. **Оператор == более понятный синтаксически.** Это еще почему? Для сравнения объектов в Java используется `.equals()`. Enum это объект. Логичнее и очевиднее использовать `.equals()` для сравнения, чтобы не нарушать единообразие сравнения объектов.
На мой взгляд, правильнее использовать `.equals()`, главное не забывать о правиле "[Сравнение константы слева](Сравнение%20константы%20слева%20в%20Java.md)". На мой взгляд, правильнее использовать `.equals()`, главное не забывать о правиле "[Сравнение константы слева](Сравнение%20константы%20слева%20в%20Java.md)".
*** ***
## Мета информация ## Мета информация
**Область**:: [[../../meta/zero/00 Java разработка|00 Java разработка]] **Область**:: [[../../meta/zero/00 Java разработка|00 Java разработка]]

View File

@ -41,9 +41,9 @@ if (user.getStatus().equals(UserStatus.ONLINE)) {
} }
``` ```
Вроде бы все отлично, миссия выполнена. Но есть одно НО. Что если `getStatus()` вернет вам `null`? Правильно, вы получите `NullPointerException`. Вроде бы все отлично, миссия выполнена. Но есть одно НО. Что если `getStatus()` вернет вам `null`? Правильно, вы получите `NullPointerException`.
Чтобы этого избежать следует придерживаться правила "Сравнения константы слева". Оно очень простое. В нашем примере, мы точно уверены, что `UserStatus.ONLINE` существует, поэтому `.equals()` стоит вызывать от него. Чтобы этого избежать следует придерживаться правила "Сравнения константы слева". Оно очень простое. В нашем примере, мы точно уверены, что `UserStatus.ONLINE` существует, поэтому `.equals()` стоит вызывать от него.
```java ```java
if (UserStatus.ONLINE.equals(user.getStatus())) { if (UserStatus.ONLINE.equals(user.getStatus())) {
@ -59,7 +59,7 @@ if ("Иванов".equals(user.getLastName())) {
} }
``` ```
Это простое правило защитит вас от `NullPointerException`. Это простое правило защитит вас от `NullPointerException`.
*** ***
## Мета информация ## Мета информация
**Область**:: [[../../meta/zero/00 Java разработка|00 Java разработка]] **Область**:: [[../../meta/zero/00 Java разработка|00 Java разработка]]

View File

@ -8,13 +8,13 @@ zero-link:
parents: parents:
linked: linked:
--- ---
Ремарка, которую можно пропустить: Помню свой первый день на работе, тогда мне поручили настраивать сервер на CentOS 7. Установить необходимые пакеты, уже не помню точно что, но не суть. Я тогда еще обладатель ПК на windows погуглил и нашел команду `yum install pack_name`. Ремарка, которую можно пропустить: Помню свой первый день на работе, тогда мне поручили настраивать сервер на CentOS 7. Установить необходимые пакеты, уже не помню точно что, но не суть. Я тогда еще обладатель ПК на windows погуглил и нашел команду `yum install pack_name`.
И как же я был удивлен, когда это не сработало. Корпоративные сервера чаще всего находятся в изоляции от интернета, и для доступа необходимо настраивать прокси. Но я тогда не знал об этом, и устанавливал пакеты вручную, скачивая их сначала к себе и перенося на сервер, то еще занятие, на это ушел целый день 😄 И как же я был удивлен, когда это не сработало. Корпоративные сервера чаще всего находятся в изоляции от интернета, и для доступа необходимо настраивать прокси. Но я тогда не знал об этом, и устанавливал пакеты вручную, скачивая их сначала к себе и перенося на сервер, то еще занятие, на это ушел целый день 😄
Потом я узнал о существовании прокси, которое открывало доступ в интернет. Сейчас расскажу, как его настроить. Потом я узнал о существовании прокси, которое открывало доступ в интернет. Сейчас расскажу, как его настроить.
Особенность использования прокси в том, что его надо настраивать везде. Недостаточно настроить только на уровне ОС, надо также настроить на уровне каждого приложения, даже у пакетного менеджера типа `yum` и `dnf`, нужно указать прокси. Особенность использования прокси в том, что его надо настраивать везде. Недостаточно настроить только на уровне ОС, надо также настроить на уровне каждого приложения, даже у пакетного менеджера типа `yum` и `dnf`, нужно указать прокси.
## Настройка для ОС ## Настройка для ОС
Первым делом настраиваем прокси на linux машине. Для этого нужно установить значения для некоторых переменных среды. Первым делом настраиваем прокси на linux машине. Для этого нужно установить значения для некоторых переменных среды.
@ -41,10 +41,10 @@ export NO_PROXY="127.0.0.1,localhost"
``` ```
> [!WARNING] > [!WARNING]
> Если в имени пользователя или пароле используется символ `@`, добавьте обратную косую черту (`\`) перед `@`. > Если в имени пользователя или пароле используется символ `@`, добавьте обратную косую черту (`\`) перед `@`.
Данным способом мы установили временное прокси, ==после перезагрузки подключение пропадет.== Чтобы добавить постоянное прокси, нужно изменить файл `/etc/environment`. Данным способом мы установили временное прокси, ==после перезагрузки подключение пропадет.== Чтобы добавить постоянное прокси, нужно изменить файл `/etc/environment`.
Если вам повезло и редактор nano был предустановлен, то воспользуйтесь им, добавив следующие строчки: Если вам повезло и редактор nano был предустановлен, то воспользуйтесь им, добавив следующие строчки:
@ -76,7 +76,7 @@ export HTTPS_PROXY="http://USERNAME:PASSWORD@SERVER:PORT/"
export NO_PROXY="127.0.0.1,localhost" export NO_PROXY="127.0.0.1,localhost"
``` ```
Чтобы сохранинть изменения санчала нажмите `ESC`, а далее наберите `:wq`, чтобы выйти без сохранения нажмите `ESC` и наберите просто `:q` Чтобы сохранинть изменения санчала нажмите `ESC`, а далее наберите `:wq`, чтобы выйти без сохранения нажмите `ESC` и наберите просто `:q`
Если вам совсем не повезло, и по какой-то причине редакторов совсем не предустановлено, то воспользуйтесь следующей командой: Если вам совсем не повезло, и по какой-то причине редакторов совсем не предустановлено, то воспользуйтесь следующей командой:
@ -91,7 +91,7 @@ export NO_PROXY="127.0.0.1,localhost"
EOFXX EOFXX
``` ```
## Настройка для пакетных менеджеров ## Настройка для пакетных менеджеров
Теперь настроим прокси для пакетных менеджеров `yum` и `dnf`. Для этого отредактируем файл `/etc/yum.conf`, добавив в конец следующие строки: Теперь настроим прокси для пакетных менеджеров `yum` и `dnf`. Для этого отредактируем файл `/etc/yum.conf`, добавив в конец следующие строки:
```toml ```toml
proxy=http://SERVER:PORT proxy=http://SERVER:PORT

View File

@ -31,7 +31,7 @@ ssh username@192.168.0.1
Первым делом нам надо узнать, какой интерфейс был присвоен нашему соединению на роутере. Если это ваше первое соединение с Wireguard, то скорее всего это Wireguard0. Но давайте убедимся в этом. Первым делом нам надо узнать, какой интерфейс был присвоен нашему соединению на роутере. Если это ваше первое соединение с Wireguard, то скорее всего это Wireguard0. Но давайте убедимся в этом.
Для этого необходимо ввести `interface Wire` и нажать `Tab`: Для этого необходимо ввести `interface Wire` и нажать `Tab`:
```shell ```shell
(config)> interface Wire (config)> interface Wire
@ -87,7 +87,7 @@ ssh username@192.168.0.1
![](../../meta/files/images/Pasted%20image%2020240908112035.png) ![](../../meta/files/images/Pasted%20image%2020240908112035.png)
Нужно добавить правило на IN, иначе запросы в локальную сеть будут дропаться. Не забудьте заменить `Wireguard0` на другое значение, если у вас задействован другой интерфейс. Нужно добавить правило на IN, иначе запросы в локальную сеть будут дропаться. Не забудьте заменить `Wireguard0` на другое значение, если у вас задействован другой интерфейс.
```shell ```shell
(config)> interface Wireguard0 (config)> interface Wireguard0
@ -106,9 +106,9 @@ Network::RoutingTable: Added static route: 10.66.67.0/24 via Wireguard0.
``` ```
> [!DANGER] > [!DANGER]
> Не забудьте заменить значения на свои. `10.66.67.0` на свою подсеть Wireguard, а `Wireguard0` на свой интерфейс. > Не забудьте заменить значения на свои. `10.66.67.0` на свою подсеть Wireguard, а `Wireguard0` на свой интерфейс.
## Настройка сервера WG ## Настройка сервера WG
Теперь нужно настроить сервер Wireguard. Для этого нужно отредактировать файл конфигурации, обычно он лежит в папке `/etc/wireguard/wg0.conf`. Зайдите под root. Теперь нужно настроить сервер Wireguard. Для этого нужно отредактировать файл конфигурации, обычно он лежит в папке `/etc/wireguard/wg0.conf`. Зайдите под root.
```shell ```shell
su su
@ -136,7 +136,7 @@ PresharedKey = PRESHARED_KEY
AllowedIPs = 10.66.67.3/32,fd42:42:43::3/128 AllowedIPs = 10.66.67.3/32,fd42:42:43::3/128
``` ```
У нас тут все стандартно. Два пира, один из них роутер, второй телефон. Для роутера необходимо указать в `AllowedIPs` вашу локальную сеть, в данном случае `192.168.1.0/24`. У нас тут все стандартно. Два пира, один из них роутер, второй телефон. Для роутера необходимо указать в `AllowedIPs` вашу локальную сеть, в данном случае `192.168.1.0/24`.
После этого отключим и включим WG соединение. После этого отключим и включим WG соединение.

View File

@ -19,13 +19,13 @@ linked:
![](../../meta/files/images/Pasted%20image%2020240407184611.png) ![](../../meta/files/images/Pasted%20image%2020240407184611.png)
## 2. Убедитесь, что процесс сборки использует ваш порт ## 2. Убедитесь, что процесс сборки использует ваш порт
Нажмите `Ctrl+Shift+A` и найдите пункт “Edit Custom VM Options…” Нажмите `Ctrl+Shift+A` и найдите пункт “Edit Custom VM Options…”
Добавьте новую строку `-Dcompiler.process.debug.port=8000` и ==перезапустите IDEA.== Добавьте новую строку `-Dcompiler.process.debug.port=8000` и ==перезапустите IDEA.==
![](../../meta/files/images/Pasted%20image%2020240407184626.png) ![](../../meta/files/images/Pasted%20image%2020240407184626.png)
## 3. Включите “Debug build process” ## 3. Включите “Debug build process”
Нажмите `Ctrl+Shift+A` и пункт “Debug build process”. Нажмите `Ctrl+Shift+A` и пункт “Debug build process”.
> [!WARNING] > [!WARNING]
> Вам нужно будет повторять этот шаг каждый раз при перезапуске IDEA. > Вам нужно будет повторять этот шаг каждый раз при перезапуске IDEA.
@ -34,7 +34,7 @@ linked:
![](Pasted%20image%2020240407184705.png) ![](Pasted%20image%2020240407184705.png)
Для запуска вашего обработчика аннотаций пересоберите проект: `Build -> Rebuild Project`. ==При выборе пункта Build Project обработчик аннотации может не запуститься.== Для запуска вашего обработчика аннотаций пересоберите проект: `Build -> Rebuild Project`. ==При выборе пункта Build Project обработчик аннотации может не запуститься.==
Процесс сборки приостановится, и вы сможете подключить отладчик: Процесс сборки приостановится, и вы сможете подключить отладчик:

View File

@ -81,13 +81,13 @@ public class OkHttpUtil {
} }
``` ```
## Как это использовать? ## Как это использовать?
Перед получением `OkHttpClient` необходимо инициализировать настройки игнорирования сертификатов. Для этого вызываем метод: Перед получением `OkHttpClient` необходимо инициализировать настройки игнорирования сертификатов. Для этого вызываем метод:
```java ```java
OkHttpUtil.init(true); OkHttpUtil.init(true);
``` ```
После этого можете получить `OkHttpClient`: После этого можете получить `OkHttpClient`:
```java ```java
OkHttpUtil.getClient(); OkHttpUtil.getClient();
``` ```

View File

@ -8,7 +8,7 @@ zero-link:
parents: parents:
linked: linked:
--- ---
Когда я создаю [обучающие репозитории к своим статьям](https://github.com/Example-uPagge), то использую H2 в качестве базы данных. Проблема с H2 в том, что когда запущено приложение, нельзя просто подключиться и посмотреть что происходит в БД. Эта заметка показывает, как провернуть этот финт. Когда я создаю [обучающие репозитории к своим статьям](https://github.com/Example-uPagge), то использую H2 в качестве базы данных. Проблема с H2 в том, что когда запущено приложение, нельзя просто подключиться и посмотреть что происходит в БД. Эта заметка показывает, как провернуть этот финт.
Имеем следующее подключение к базе данных: Имеем следующее подключение к базе данных:
@ -25,7 +25,7 @@ spring:
database-platform: org.hibernate.dialect.H2Dialect database-platform: org.hibernate.dialect.H2Dialect
``` ```
В вашем Spring приложении необходимо создать следующий `@Bean`: В вашем Spring приложении необходимо создать следующий `@Bean`:
```java ```java
import org.h2.tools.Server; import org.h2.tools.Server;
@ -44,7 +44,7 @@ public class BeanConfig {
Это фактически создает сервер для остальных подключений к H2. Это фактически создает сервер для остальных подключений к H2.
> [!WARNING] > [!WARNING]
> Если класс `org.h2.tools.Server` не находится, то скорее всего у зависимости для H2 установлен scope `runtime`. Удалите значение `scope` и класс появится. > Если класс `org.h2.tools.Server` не находится, то скорее всего у зависимости для H2 установлен scope `runtime`. Удалите значение `scope` и класс появится.
Теперь можно подсоединиться к H2 используя следующий url: Теперь можно подсоединиться к H2 используя следующий url:
@ -54,7 +54,7 @@ jdbc:h2:tcp://localhost:9090/mem:blog
![Так выглядит окно соединения в IntelliJ Idea](../../meta/files/images/data-sources-in-idea.png) ![Так выглядит окно соединения в IntelliJ Idea](../../meta/files/images/data-sources-in-idea.png)
Ограничение этого способа в том, что ==нельзя подключиться к базе, если приложение не работает.== Ограничение этого способа в том, что ==нельзя подключиться к базе, если приложение не работает.==
*** ***
## Мета информация ## Мета информация

View File

@ -10,7 +10,7 @@ linked:
--- ---
PNG и JPG являются хорошими форматами изображений, которые можно [сжать без потери качества](Сжатие%20изображений%20без%20потери%20качества.md). Однако, на сегодняшний день существует более современный формат WebP, который может показать еще более эффективные результаты при сжатии изображений, но с едва заметным ухудшением качества. PNG и JPG являются хорошими форматами изображений, которые можно [сжать без потери качества](Сжатие%20изображений%20без%20потери%20качества.md). Однако, на сегодняшний день существует более современный формат WebP, который может показать еще более эффективные результаты при сжатии изображений, но с едва заметным ухудшением качества.
В [документации WebP](https://developers.google.com/speed/webp/docs/cwebp?hl=ru) перечислено множество параметров, которые повлияют на качество получаемого изображения. Вы можете провести экспериментальный подбор параметров онлайн на сайте [https://squoosh.app](https://squoosh.app/). В [документации WebP](https://developers.google.com/speed/webp/docs/cwebp?hl=ru) перечислено множество параметров, которые повлияют на качество получаемого изображения. Вы можете провести экспериментальный подбор параметров онлайн на сайте [https://squoosh.app](https://squoosh.app/).
Я вы выбрал для себя следующий набор параметров: Я вы выбрал для себя следующий набор параметров:
@ -18,17 +18,17 @@ PNG и JPG являются хорошими форматами изображе
cwebp -mt -af -progress -m 6 -q 80 -pass 10 input.jpg -o output.webp cwebp -mt -af -progress -m 6 -q 80 -pass 10 input.jpg -o output.webp
``` ```
Это команда преобразует JPG файл `input.jpg` в файл изображения WebP с именем `output.webp`. Команда включает несколько опций, которые управляют процессом кодирования: Это команда преобразует JPG файл `input.jpg` в файл изображения WebP с именем `output.webp`. Команда включает несколько опций, которые управляют процессом кодирования:
- `-mt` включает многопоточность, что может улучшить производительность  на многоядерных процессорах. - `-mt` включает многопоточность, что может улучшить производительность на многоядерных процессорах.
- `-af` включает автоматическую фильтрацию, которая применяет алгоритм фильтрации для повышения эффективности сжатия. - `-af` включает автоматическую фильтрацию, которая применяет алгоритм фильтрации для повышения эффективности сжатия.
- `-progress` выводит показывает процент обработки файла. - `-progress` выводит показывает процент обработки файла.
- `-m 6` устанавливает максимальное количество сегментов, используемых в процессе кодирования, равным 6, что может повысить эффективность сжатия за счет увеличения времени кодирования. - `-m 6` устанавливает максимальное количество сегментов, используемых в процессе кодирования, равным 6, что может повысить эффективность сжатия за счет увеличения времени кодирования.
- `-q 80` устанавливает коэффициент качества на `80`, который контролирует степень сжатия и влияет на визуальное качество выходного изображения. - `-q 80` устанавливает коэффициент качества на `80`, который контролирует степень сжатия и влияет на визуальное качество выходного изображения.
- `-pass 10` устанавливает число проходов кодирования равным 10, что может повысить эффективность сжатия за счет увеличения времени кодирования. - `-pass 10` устанавливает число проходов кодирования равным 10, что может повысить эффективность сжатия за счет увеличения времени кодирования.
> [!WARNING] > [!WARNING]
> `-lossless` позволяет использовать сжатие без потерь. Но тогда ваше новое изображение может оказаться существенно тяжелее исходного. > `-lossless` позволяет использовать сжатие без потерь. Но тогда ваше новое изображение может оказаться существенно тяжелее исходного.
Улучшим [скрипт сжатия изображений](Сжатие%20изображений%20без%20потери%20качества.md) и добавим преобразование в webp: Улучшим [скрипт сжатия изображений](Сжатие%20изображений%20без%20потери%20качества.md) и добавим преобразование в webp:
@ -41,7 +41,7 @@ find ./images/comp -type f -iregex '.*\.\(jpg\|jpeg\|png\)' -not -iregex '.*no-c
' _ {} \; ' _ {} \;
``` ```
Мы берем сжатые изображения из папки `comp` и преобразуем их в WebP, складывая в отдельную папку `webp`. Если вы захотите использовать другие параметры сжатия, вы всегда сможете пересоздать изображения с новыми параметрами. Мы берем сжатые изображения из папки `comp` и преобразуем их в WebP, складывая в отдельную папку `webp`. Если вы захотите использовать другие параметры сжатия, вы всегда сможете пересоздать изображения с новыми параметрами.
## Тесты преобразования ## Тесты преобразования
Продолжим наши эксперименты со сжатием. Теперь сожмем наши файл размером в 2,7 мб и 2.2 в формат WebP с разными параметрами качества: Продолжим наши эксперименты со сжатием. Теперь сожмем наши файл размером в 2,7 мб и 2.2 в формат WebP с разными параметрами качества:
- -q 90: Размер 325 кб. - -q 90: Размер 325 кб.
@ -59,7 +59,7 @@ find ./images/comp -type f -iregex '.*\.\(jpg\|jpeg\|png\)' -not -iregex '.*no-c
## Nginx ## Nginx
Теперь мы научим nginx при запросе изображений сначала пытаться найти WebP файл, и только потом отдавать сжатый PNG/JPG, а если и сжатого нет, то отдавать обычный файл. Теперь мы научим nginx при запросе изображений сначала пытаться найти WebP файл, и только потом отдавать сжатый PNG/JPG, а если и сжатого нет, то отдавать обычный файл.
Для этого напишем следующий `location`: Для этого напишем следующий `location`:
```nginx ```nginx
location ~* ^(/blog/ru/content/images/)(.+)\.(png|jpe?g)$ { location ~* ^(/blog/ru/content/images/)(.+)\.(png|jpe?g)$ {
@ -71,12 +71,12 @@ location ~* ^(/blog/ru/content/images/)(.+)\.(png|jpe?g)$ {
} }
``` ```
Данный `location` обрабатывает все запросы к адресам, которые начинаются с `/images/`, за которым следует любое количество символов, затем точка, а затем формат файла png/jpeg/jpg. Данный `location` обрабатывает все запросы к адресам, которые начинаются с `/images/`, за которым следует любое количество символов, затем точка, а затем формат файла png/jpeg/jpg.
Для запросов, соответствующих этому шаблону, выполняются следующие действия: Для запросов, соответствующих этому шаблону, выполняются следующие действия:
- Директива `alias` указывает путь к локальной директории, из которой будут отдаваться файлы. В данном случае путь к директории `/images`. - Директива `alias` указывает путь к локальной директории, из которой будут отдаваться файлы. В данном случае путь к директории `/images`.
- Директивы `set` назначают переменные, которые будут использоваться в последующих директивах. Переменная `$webp_image_subdir` устанавливается в `/webp/`, а переменная `$basename` устанавливается в захваченную подстроку шаблона регулярного выражения (т.е. имя файла без расширения). - Директивы `set` назначают переменные, которые будут использоваться в последующих директивах. Переменная `$webp_image_subdir` устанавливается в `/webp/`, а переменная `$basename` устанавливается в захваченную подстроку шаблона регулярного выражения (т.е. имя файла без расширения).
- Директива `try_files` пытается отдать Webp-версию запрошенного файла изображения, добавляя к переменным `$webp_image_subdir` и `$basename` суффикс `.webp`. Если NGINX сможет найти Webp-версию запрашиваемого файла изображения, он отдаст его. Если он не может найти WebP-версию, то отдаст сжатый JPG/PNG, если и сжатого файла не будет, то отдаст не сжатое. - Директива `try_files` пытается отдать Webp-версию запрошенного файла изображения, добавляя к переменным `$webp_image_subdir` и `$basename` суффикс `.webp`. Если NGINX сможет найти Webp-версию запрашиваемого файла изображения, он отдаст его. Если он не может найти WebP-версию, то отдаст сжатый JPG/PNG, если и сжатого файла не будет, то отдаст не сжатое.
*** ***
## Мета информация ## Мета информация
**Область**:: [[../../meta/zero/00 Снипеты на bash|00 Снипеты на bash]] **Область**:: [[../../meta/zero/00 Снипеты на bash|00 Снипеты на bash]]

View File

@ -9,11 +9,11 @@ parents:
- "[[../../../../knowledge/dev/java/other/Jackson|Jackson]]" - "[[../../../../knowledge/dev/java/other/Jackson|Jackson]]"
linked: linked:
--- ---
Чаще всего по работе я сталкиваюсь с проблемой десериализации и сериализации даты. Многие разработчики отступают от стандартного формата времени `yyyy-MM-dd'T'HH:mm:ss*SSSZZZZ` и изобретают свои форматы. Чаще всего по работе я сталкиваюсь с проблемой десериализации и сериализации даты. Многие разработчики отступают от стандартного формата времени `yyyy-MM-dd'T'HH:mm:ss*SSSZZZZ` и изобретают свои форматы.
К сожалению, в Jackson не заложены все возможные форматы даты, поэтому необходимо написать свой десериализатор. К сожалению, в Jackson не заложены все возможные форматы даты, поэтому необходимо написать свой десериализатор.
## Десериализация ## Десериализация
В данном случае это преобразование json формата в Java объект. Необходимо расширить абстрактный класс `StdDeserializer`. В данном случае это преобразование json формата в Java объект. Необходимо расширить абстрактный класс `StdDeserializer`.
```java ```java
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
@ -47,7 +47,7 @@ public class CustomDeserializer extends StdDeserializer<LocalDateTime> {
} }
``` ```
После этого необходимо над полем поставить аннотацию `@JsonDeserialize` c указанием нашего кастомного десериализатора. После этого необходимо над полем поставить аннотацию `@JsonDeserialize` c указанием нашего кастомного десериализатора.
```java ```java
public class Foo { public class Foo {
@ -63,7 +63,7 @@ public class Foo {
``` ```
## Сериализация ## Сериализация
В данном случае это преобразование Java объекта в json формат. Для сериализации необходимо расширить класс `StdSerializer`. В данном случае это преобразование Java объекта в json формат. Для сериализации необходимо расширить класс `StdSerializer`.
```java ```java
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonGenerator;
@ -93,7 +93,7 @@ public class CustomSerializer extends StdSerializer<LocalDateTime> {
} }
``` ```
Для работы над полем поставить аннотацию `@JsonSerialize` Для работы над полем поставить аннотацию `@JsonSerialize`
```java ```java
public class Foo { public class Foo {

View File

@ -40,24 +40,24 @@ touch $file
echo "$(date)" > $file echo "$(date)" > $file
``` ```
Этот скрипт сжимает изображения без потери качества. Он размещается рядом с каталогом `images`, в котором находятся ваши изображения. Разберемся, как он работает. Этот скрипт сжимает изображения без потери качества. Он размещается рядом с каталогом `images`, в котором находятся ваши изображения. Разберемся, как он работает.
Сначала скрипт проверяет, существует ли в текущем каталоге файл `comp.flag`. Если файл существует, он устанавливает значение `-newer $file` в переменную `option`, которая будет использоваться в качестве фильтра для поиска только тех файлов, которые были изменены после даты создания файла `optimg.flag`. Если файл не существует, переменная `option` будет пустой. Сначала скрипт проверяет, существует ли в текущем каталоге файл `comp.flag`. Если файл существует, он устанавливает значение `-newer $file` в переменную `option`, которая будет использоваться в качестве фильтра для поиска только тех файлов, которые были изменены после даты создания файла `optimg.flag`. Если файл не существует, переменная `option` будет пустой.
Затем скрипт использует команду `find` для рекурсивного поиска файлов в каталоге `images` и его подкаталогах, которые: Затем скрипт использует команду `find` для рекурсивного поиска файлов в каталоге `images` и его подкаталогах, которые:
- `-type f`. Являются обычными файлами. - `-type f`. Являются обычными файлами.
- Имеют расширение имени файла `.png`, `.jpeg` или `.jpg`. - Имеют расширение имени файла `.png`, `.jpeg` или `.jpg`.
- `-not -path`_._ Не находятся в указанных каталогах_._ В данном случае это каталоги `./images/comp`. Мы будем складывать туда сжатые изображения, и мы не хотим заново по ним проходить поиском и сжимать снова. - `-not -path`_._ Не находятся в указанных каталогах_._ В данном случае это каталоги `./images/comp`. Мы будем складывать туда сжатые изображения, и мы не хотим заново по ним проходить поиском и сжимать снова.
- `! -name "-no-comp."`. Оставим возможность не сжимать изображение, если его имя заканчивается на `-no-comp`. - `! -name "-no-comp."`. Оставим возможность не сжимать изображение, если его имя заканчивается на `-no-comp`.
- Для каждого из этих файлов сценарий использует свою команду оптимизации. - Для каждого из этих файлов сценарий использует свою команду оптимизации.
Мы не будем затирать оригиналы изображений. Вместо этого мы создадим дополнительную папку `comp` в каталоге `images`, в которую и сложим преобразованные изображения. Создаваемая структура подкаталогов в `comp` будет повторять структуру подкатологов в `images`. Мы не будем затирать оригиналы изображений. Вместо этого мы создадим дополнительную папку `comp` в каталоге `images`, в которую и сложим преобразованные изображения. Создаваемая структура подкаталогов в `comp` будет повторять структуру подкатологов в `images`.
Для файлов PNG сначала используется `optipng` для сжатия с самым высоким уровнем оптимизации (`-o7`). Далее используем `advpng` для дальнейшего сжатия с уровнем сжатия 4 (`-z4`). И наконец `pngcrush` для удаления из файла определенных фрагментов, которые можно безопасно удалить для уменьшения размера файла. Для файлов PNG сначала используется `optipng` для сжатия с самым высоким уровнем оптимизации (`-o7`). Далее используем `advpng` для дальнейшего сжатия с уровнем сжатия 4 (`-z4`). И наконец `pngcrush` для удаления из файла определенных фрагментов, которые можно безопасно удалить для уменьшения размера файла.
Для файлов JPEG используется `jpegoptim` для их оптимизации со сжатием без потерь (`--all-progressive --strip-all`). Для файлов JPEG используется `jpegoptim` для их оптимизации со сжатием без потерь (`--all-progressive --strip-all`).
После оптимизации всех подходящих изображений сценарий пересоздает файл `comp.flag`. Это гарантирует, что скрипт будет оптимизировать только те файлы, которые были изменены с момента последнего запуска. После оптимизации всех подходящих изображений сценарий пересоздает файл `comp.flag`. Это гарантирует, что скрипт будет оптимизировать только те файлы, которые были изменены с момента последнего запуска.
## Тесты на сжатие ## Тесты на сжатие
Возьмем два одинаковых изображения (3456 x 2234): одно форматом jpg и размером 2.2 мб, второе форматом png и размером 2,7 мб. Возьмем два одинаковых изображения (3456 x 2234): одно форматом jpg и размером 2.2 мб, второе форматом png и размером 2,7 мб.

View File

@ -8,13 +8,13 @@ zero-link:
parents: parents:
linked: linked:
--- ---
Для запуска `jar` файла в linux в виде сервиса, необходимо создать файл конфигурации. Для запуска `jar` файла в linux в виде сервиса, необходимо создать файл конфигурации.
```java ```java
sudo nano /etc/systemd/system/app_name_service.service sudo nano /etc/systemd/system/app_name_service.service
``` ```
В этот файл вставляем примерно следующее. Не забудьте заменить в выделенных строках `app_path`, `app_name`. В этот файл вставляем примерно следующее. Не забудьте заменить в выделенных строках `app_path`, `app_name`.
```java ```java
[Unit] [Unit]

View File

@ -3,6 +3,6 @@ tags:
- type/people - type/people
link: https://mnogosdelal.ru/ link: https://mnogosdelal.ru/
--- ---
Прокрастинатолог, специалист по продуктивности, тренер. Руководил проектами в компаниях DC BARS, Auriga, в Лаборатории Касперского, проработал в области разработки ПО почти 15 лет. Прокрастинатолог, специалист по продуктивности, тренер. Руководил проектами в компаниях DC BARS, Auriga, в Лаборатории Касперского, проработал в области разработки ПО почти 15 лет.
С 2013 ведет тренинги по продуктивности. Окончил физический факультет МГУ. С 2013 ведет тренинги по продуктивности. Окончил физический факультет МГУ.

View File

@ -31,9 +31,9 @@ linked:
- [Производительность SQL запросов](_inbox/Производительность%20SQL%20запросов.md) - [Производительность SQL запросов](_inbox/Производительность%20SQL%20запросов.md)
## Заметки ## Заметки
 - Классические СУБД хранят данные в двух местах: на диске и в памяти. - Классические СУБД хранят данные в двух местах: на диске и в памяти.
 - [[../../dev/fundamental/Страница|Страница]] модифицируется сначала в оперативной памяти, потом попадает на диск. - [[../../dev/fundamental/Страница|Страница]] модифицируется сначала в оперативной памяти, потом попадает на диск.
 - ![](Pasted%20image%2020240531082744.png) - ![](Pasted%20image%2020240531082744.png)
 - Часто думают, что реляционная таблица — это массив. Некоторые даже думают, что это двумерный массив. На самом деле, это гораздо более сложная штука. Это мультимножество набор определенного сорта кортежей, над которым не задано порядка. В SQL-таблице нет порядка. Это важно. И, как результат, когда вы делаете SELECT* из БД (просканировать все записи), результат выполнения запроса может меняться строчки могут быть в одном порядке, а могут и в другом. Про это нужно помнить. - Часто думают, что реляционная таблица — это массив. Некоторые даже думают, что это двумерный массив. На самом деле, это гораздо более сложная штука. Это мультимножество набор определенного сорта кортежей, над которым не задано порядка. В SQL-таблице нет порядка. Это важно. И, как результат, когда вы делаете SELECT* из БД (просканировать все записи), результат выполнения запроса может меняться строчки могут быть в одном порядке, а могут и в другом. Про это нужно помнить.
 - Профиль нагрузки на реляционную базу данных выглядит следующим образом: 80% запросов это чтение, 20% запросов это запись. Если запросов на запись больше, то возможно реляционная база данных вам не подходит. - Профиль нагрузки на реляционную базу данных выглядит следующим образом: 80% запросов это чтение, 20% запросов это запись. Если запросов на запись больше, то возможно реляционная база данных вам не подходит.

View File

@ -5,4 +5,4 @@ title: Образование
--- ---
- [[../../education/Метапознание|Метапознание]] - [[../../education/Метапознание|Метапознание]]
## Свободные заметки ## Свободные заметки
- Согласно исследованиям, оптимальное время для начала обучения и работы [лежит в промежутке 11:00-12:00](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5395635/). Хотя исследователи и признают, что это довольно индивидуально, и важно слушать свои ощущения. - Согласно исследованиям, оптимальное время для начала обучения и работы [лежит в промежутке 11:00-12:00](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5395635/). Хотя исследователи и признают, что это довольно индивидуально, и важно слушать свои ощущения.

View File

@ -24,15 +24,15 @@ zero-link:
- Нейромедиаторы и гормоны: [Кортизол](Кортизол.md), [Адреналин](Адреналин.md), [Норадреналин](Норадреналин.md), [Аденозин](Аденозин.md) - Нейромедиаторы и гормоны: [Кортизол](Кортизол.md), [Адреналин](Адреналин.md), [Норадреналин](Норадреналин.md), [Аденозин](Аденозин.md)
- [Фазы сна](Фазы%20сна.md): [Поверхностный сон](_inbox/Поверхностный%20сон.md), [Глубокая фаза сна](Глубокая%20фаза%20сна.md), [REM](Фаза%20быстрого%20сна.md) - [Фазы сна](Фазы%20сна.md): [Поверхностный сон](_inbox/Поверхностный%20сон.md), [Глубокая фаза сна](Глубокая%20фаза%20сна.md), [REM](Фаза%20быстрого%20сна.md)
## Зачем нужен сон? ## Зачем нужен сон?
**Сон играет роль уборщика**, [удаляя](https://www.sciencedirect.com/science/article/abs/pii/S2468867319301609#:~:text=The%20discovery%20that,dependence%20on%20glia.) из мозга продукты метаболизма — ненужные белки, которые накапливаются во время бодрствования и приводят к заболеваниям нервной системы. Среди таких белков — бета-амилоид, большая концентрация которого приводит к [гибели](https://med.stanford.edu/news/all-news/2013/09/scientists-reveal-how-beta-amyloid-may-cause-alzheimers.html#:~:text=Scientists%20at%20the%20Stanford%20University%20School%20of%20Medicine%20have%20shown%20how%20a%20protein%20fragment%20known%20as%20beta%2Damyloid%2C%20strongly%20implicated%20in%20Alzheimer%E2%80%99s%20disease%2C%20begins%20destroying%20synapses%20before%20it%20clumps%20into%20plaques%20that%20lead%20to%20nerve%20cell%20death.) нервных клеток и, [вероятно](https://www.medicalnewstoday.com/articles/325493#:~:text=If%20the%20cellular%20system%20became%20overloaded%20or%20slowed%20down%20as%20we%20aged%2C%20metabolic%20garbage%20would%20build%20up%20between%20the%20cells.%20This%20garbage%20includes%20products%20such%20as%20beta%2Damyloid%20%E2%80%94%20the%20protein%20associated%20with%20Alzheimer%E2%80%99s%20disease.), к [[../../../../knowledge/health/болезни/Болезнь Альцгеймера|болезни Альцгеймера]]. Всего одна бессонная ночь значительно [повышает](https://www.pnas.org/doi/10.1073/pnas.1721694115#:~:text=We%20show%20that%20one%20night%20of%20sleep%20deprivation%2C%20relative%20to%20baseline%2C%20resulted%20in%20a%20significant%20increase%20in%20A%CE%B2%20burden%20in%20the%20right%20hippocampus%20and%20thalamus.) объем этого белка в мозге человека. **Сон играет роль уборщика**, [удаляя](https://www.sciencedirect.com/science/article/abs/pii/S2468867319301609#:~:text=The%20discovery%20that,dependence%20on%20glia.) из мозга продукты метаболизма — ненужные белки, которые накапливаются во время бодрствования и приводят к заболеваниям нервной системы. Среди таких белков — бета-амилоид, большая концентрация которого приводит к [гибели](https://med.stanford.edu/news/all-news/2013/09/scientists-reveal-how-beta-amyloid-may-cause-alzheimers.html#:~:text=Scientists%20at%20the%20Stanford%20University%20School%20of%20Medicine%20have%20shown%20how%20a%20protein%20fragment%20known%20as%20beta%2Damyloid%2C%20strongly%20implicated%20in%20Alzheimer%E2%80%99s%20disease%2C%20begins%20destroying%20synapses%20before%20it%20clumps%20into%20plaques%20that%20lead%20to%20nerve%20cell%20death.) нервных клеток и, [вероятно](https://www.medicalnewstoday.com/articles/325493#:~:text=If%20the%20cellular%20system%20became%20overloaded%20or%20slowed%20down%20as%20we%20aged%2C%20metabolic%20garbage%20would%20build%20up%20between%20the%20cells.%20This%20garbage%20includes%20products%20such%20as%20beta%2Damyloid%20%E2%80%94%20the%20protein%20associated%20with%20Alzheimer%E2%80%99s%20disease.), к [[../../../../knowledge/health/болезни/Болезнь Альцгеймера|болезни Альцгеймера]]. Всего одна бессонная ночь значительно [повышает](https://www.pnas.org/doi/10.1073/pnas.1721694115#:~:text=We%20show%20that%20one%20night%20of%20sleep%20deprivation%2C%20relative%20to%20baseline%2C%20resulted%20in%20a%20significant%20increase%20in%20A%CE%B2%20burden%20in%20the%20right%20hippocampus%20and%20thalamus.) объем этого белка в мозге человека.
**Сон важен для физического самочувствия.** Пока мы спим, [усиливается](https://erj.ersjournals.com/content/38/4/870#:~:text=The%20release%20of%20GH%20is%20greatly%20enhanced%20during%20sleep%2C%20especially%20early%20in%20the%20night) выработка [«гормона роста»](https://ru.wikipedia.org/wiki/%D0%93%D0%BE%D1%80%D0%BC%D0%BE%D0%BD_%D1%80%D0%BE%D1%81%D1%82%D0%B0), который [восстанавливает](https://www.healthline.com/health/hgh-side-effects#:~:text=HGH%20helps%20to%20maintain%2C%20build%2C%20and%20repair%20healthy%20tissue%20in%20the%20brain%20and%20other%20organs.%20This%20hormone%20can%20help%20to%20speed%20up%20healing%20after%20an%20injury%20and%20repair%20muscle%20tissue%20after%20exercise.%20This%20helps%20to%20build%20muscle%20mass%2C%20boost%20metabolism%2C%20and%20burn%20fat.) мышцы после нагрузок и травм. Нехватка этого гормона [приводит](https://academic.oup.com/jcem/article/83/2/382/2865179?login=false#:~:text=1.%20Lean%20Body%20Mass%20(LBM).%20Reduced%20LBM%20is%20an%20important%20feature%20of%20AO%20GH%20deficiency.%20Initial%20studies%20demonstrated%20a%20mean%20reduction%20in%20LBM%20of%207%E2%80%938%25%2C%20corresponding%20to%20approximately%204%20kg%20lean%20tissue%20(6).%20Subsequent%20studies%20have%20confirmed%20these%20results%20(12%2C%2014%E2%80%9316).) к тому, что мышцы атрофируются. Также сон помогает нормализовать артериальное давление. **Сон важен для физического самочувствия.** Пока мы спим, [усиливается](https://erj.ersjournals.com/content/38/4/870#:~:text=The%20release%20of%20GH%20is%20greatly%20enhanced%20during%20sleep%2C%20especially%20early%20in%20the%20night) выработка [«гормона роста»](https://ru.wikipedia.org/wiki/%D0%93%D0%BE%D1%80%D0%BC%D0%BE%D0%BD_%D1%80%D0%BE%D1%81%D1%82%D0%B0), который [восстанавливает](https://www.healthline.com/health/hgh-side-effects#:~:text=HGH%20helps%20to%20maintain%2C%20build%2C%20and%20repair%20healthy%20tissue%20in%20the%20brain%20and%20other%20organs.%20This%20hormone%20can%20help%20to%20speed%20up%20healing%20after%20an%20injury%20and%20repair%20muscle%20tissue%20after%20exercise.%20This%20helps%20to%20build%20muscle%20mass%2C%20boost%20metabolism%2C%20and%20burn%20fat.) мышцы после нагрузок и травм. Нехватка этого гормона [приводит](https://academic.oup.com/jcem/article/83/2/382/2865179?login=false#:~:text=1.%20Lean%20Body%20Mass%20(LBM).%20Reduced%20LBM%20is%20an%20important%20feature%20of%20AO%20GH%20deficiency.%20Initial%20studies%20demonstrated%20a%20mean%20reduction%20in%20LBM%20of%207%E2%80%938%25%2C%20corresponding%20to%20approximately%204%20kg%20lean%20tissue%20(6).%20Subsequent%20studies%20have%20confirmed%20these%20results%20(12%2C%2014%E2%80%9316).) к тому, что мышцы атрофируются. Также сон помогает нормализовать артериальное давление.
**Сон нужен иммунной системе.** Во сне наше дыхание замедляется, а мышцы почти неподвижны, поэтому энергия в организме может [пойти](https://www.sleepfoundation.org/physical-health/how-sleep-affects-immunity#:~:text=During%20sleep%2C%20breathing%20and%20muscle%20activity%20slows%20down%2C%20freeing%20up%20energy%20for%20the%20immune%20system%20to%20perform%20these%20critical%20tasks.) на важные иммунные задачи. Например, [активируются](https://www.sleepfoundation.org/physical-health/how-sleep-affects-immunity#:~:text=Sleep%20is%20an,off%20an%20infection.) воспалительные процессы, помогающие заживлять раны и бороться с инфекциями. [[../../../../knowledge/health/болезни/Недосып|Недосып]] же имеет обратный эффект: те, кто спят меньше семи часов, [простужаются](https://pubmed.ncbi.nlm.nih.gov/19139325/#:~:text=There%20was%20a%20graded%20association%20with%20average%20sleep%20duration%3A%20participants%20with%20less%20than%207%20hours%20of%20sleep%20were%202.94%20times%20(95%25%20confidence%20interval%20%5BCI%5D%2C%201.18%2D7.30)%20more%20likely%20to%20develop%20a%20cold%20than%20those%20with%208%20hours%20or%20more%20of%20sleep.) почти в три раза чаще, чем спящие по восемь часов. **Сон нужен иммунной системе.** Во сне наше дыхание замедляется, а мышцы почти неподвижны, поэтому энергия в организме может [пойти](https://www.sleepfoundation.org/physical-health/how-sleep-affects-immunity#:~:text=During%20sleep%2C%20breathing%20and%20muscle%20activity%20slows%20down%2C%20freeing%20up%20energy%20for%20the%20immune%20system%20to%20perform%20these%20critical%20tasks.) на важные иммунные задачи. Например, [активируются](https://www.sleepfoundation.org/physical-health/how-sleep-affects-immunity#:~:text=Sleep%20is%20an,off%20an%20infection.) воспалительные процессы, помогающие заживлять раны и бороться с инфекциями. [[../../../../knowledge/health/болезни/Недосып|Недосып]] же имеет обратный эффект: те, кто спят меньше семи часов, [простужаются](https://pubmed.ncbi.nlm.nih.gov/19139325/#:~:text=There%20was%20a%20graded%20association%20with%20average%20sleep%20duration%3A%20participants%20with%20less%20than%207%20hours%20of%20sleep%20were%202.94%20times%20(95%25%20confidence%20interval%20%5BCI%5D%2C%201.18%2D7.30)%20more%20likely%20to%20develop%20a%20cold%20than%20those%20with%208%20hours%20or%20more%20of%20sleep.) почти в три раза чаще, чем спящие по восемь часов.
**Сон [формирует](https://www.pnas.org/doi/10.1073/pnas.2201795119) и закрепляет воспоминания**. Этот процесс называется [консолидация памяти](Консолидация%20памяти.md). Это подтверждается экспериментами: одна группа людей училась утром, а другая вечером. Контрольный тест показал, что чем ближе обучение ко сну, тем лучше усваивается информация. **Сон [формирует](https://www.pnas.org/doi/10.1073/pnas.2201795119) и закрепляет воспоминания**. Этот процесс называется [консолидация памяти](Консолидация%20памяти.md). Это подтверждается экспериментами: одна группа людей училась утром, а другая вечером. Контрольный тест показал, что чем ближе обучение ко сну, тем лучше усваивается информация.
Еще во сне мы [продолжаем](https://now.tufts.edu/2021/02/18/new-theory-why-we-dream#:~:text=In%20essence%2C%20that%E2%80%99s,need%20of%20disruption.) искать решение проблем, которые волновали нас днем. Еще во сне мы [продолжаем](https://now.tufts.edu/2021/02/18/new-theory-why-we-dream#:~:text=In%20essence%2C%20that%E2%80%99s,need%20of%20disruption.) искать решение проблем, которые волновали нас днем.
## Как возникает сон ## Как возникает сон
![](Циркадные%20ритмы.md#^a1a364) ![](Циркадные%20ритмы.md#^a1a364)
![](Мелатонин.md#^381eb3) ![](Мелатонин.md#^381eb3)