Клёвый тренажёр+учебник по SQL
Тут можно потренироваться в хитрых джойнах, агрегациях и понабивать руку. Интерфейс очень приятный и позволяет потыкать схему БД, даёт подсказки как в коде, так и непосредственно по решению
В более сложные штуки (к примеру, в оконные функции) этот ресурс не лезет. Ну и запросы даже в самых сложных задачках получаются не сказать чтобы громоздкие
На сайте есть платная версия (которая позволяет смотреть авторские решения), но можно вполне обойтись и без неё
https://sql-academy.org/ru/trainer
👉 Java Portal
Тут можно потренироваться в хитрых джойнах, агрегациях и понабивать руку. Интерфейс очень приятный и позволяет потыкать схему БД, даёт подсказки как в коде, так и непосредственно по решению
В более сложные штуки (к примеру, в оконные функции) этот ресурс не лезет. Ну и запросы даже в самых сложных задачках получаются не сказать чтобы громоздкие
На сайте есть платная версия (которая позволяет смотреть авторские решения), но можно вполне обойтись и без неё
https://sql-academy.org/ru/trainer
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4❤1👍1
Используй
Проверяет, ссылаются ли два объекта
#Java #РазработкаПО
👉 Java Portal
Files.isSameFile(path1, path2), чтобы проверить, указывают ли два пути на один и тот же файл. Метод также резолвит симлинки.Проверяет, ссылаются ли два объекта
Path на один и тот же реальный файл в файловой системе.#Java #РазработкаПО
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
На собесе по Java понимание устройства JVM и управления памятью сильно влияет на оценку. Ниже — сжатое покрытие всех 25 тем без воды.
1. Heap vs Stack
Heap — аллокация объектов, шарится между потоками.
Stack — фреймы методов, локальные переменные, примитивы.
Объекты в heap, ссылки — в stack.
2. Сборка мусора
GC освобождает недостижимые объекты.
Сборщики: Serial, Parallel, CMS (устаревший), G1.
Объект попадает под GC при отсутствии достижимости по графу ссылок.
3. Области памяти JVM
Heap (Young/Old), Stack, Metaspace (вместо Method Area), Native Stack.
Metaspace хранит метаданные классов.
4. Алгоритмы GC
Minor GC — Young, Major/Full GC — Old.
Mark-and-Sweep, Copying, Mark-Compact.
5. Параметры JVM
GC-логи анализируются для поиска пауз и аллокаций.
6. Утечки памяти
Причины: статические коллекции, кеши без очистки, listener’ы.
Инструменты: VisualVM, JConsole, Eclipse MAT.
7. OutOfMemoryError
Heap overflow, Metaspace overflow, Direct memory.
Решения: тюнинг heap, профилинг, оптимизация аллокаций.
8. Типы ссылок
Soft — для кешей.
Weak — сборка при следующем GC.
Phantom — для пост-очистки.
9. ThreadLocal
Утечки из-за хранения значений без remove().
Проблема усиливается в пуле потоков.
10. finalize()
Непредсказуемый вызов, влияет на GC.
Замена — Cleaner или try-with-resources.
11. Direct Memory
Off-heap через
Контроль сложнее, GC не управляет напрямую.
12. JEP по GC
ZGC (JEP 307) — низкие паузы.
Shenandoah (JEP 189) — конкурентная очистка.
13. Архитектура JVM
ClassLoader, Runtime Data Areas, Execution Engine, JNI.
14. Загрузка классов
Loading → Linking → Initialization.
Загрузчики: Bootstrap, Platform (бывш. Extension), System.
15. Байткод
Инструкции JVM, стековая модель исполнения.
Интерпретируется и оптимизируется JIT.
16. JIT-компилятор
Горячий код компилируется в машинный.
Оптимизации: инлайнинг, удаление мертвого кода.
17. Структура .class
Magic number, constant pool, методы, атрибуты.
18. Жизненный цикл потоков
NEW → RUNNABLE → BLOCKED/WAITING → TERMINATED.
JVM управляет планированием через ОС.
19. JNI
Связка с нативным кодом (C/C++).
Используется для low-level операций.
20. Профилинг JVM
CPU, память, потоки.
Инструменты: VisualVM, JConsole.
21. HotSpot
Основная реализация JVM.
Использует адаптивную оптимизацию и JIT.
22. Манипуляция байткодом
ASM, BCEL, Javassist.
Применяется в прокси, AOP, фреймворках.
23. Инструменты диагностики
jstack — дамп потоков.
jmap — heap dump.
jstat — статистика GC.
24. Безопасность классов
Верификация байткода.
Security Manager (устаревший, но концепт важен).
25. Java Memory Model (JMM)
Правила видимости и happens-before.
Ключевые примитивы: volatile, synchronized.
👉 Java Portal
1. Heap vs Stack
Heap — аллокация объектов, шарится между потоками.
Stack — фреймы методов, локальные переменные, примитивы.
Объекты в heap, ссылки — в stack.
2. Сборка мусора
GC освобождает недостижимые объекты.
Сборщики: Serial, Parallel, CMS (устаревший), G1.
Объект попадает под GC при отсутствии достижимости по графу ссылок.
3. Области памяти JVM
Heap (Young/Old), Stack, Metaspace (вместо Method Area), Native Stack.
Metaspace хранит метаданные классов.
4. Алгоритмы GC
Minor GC — Young, Major/Full GC — Old.
Mark-and-Sweep, Copying, Mark-Compact.
5. Параметры JVM
-Xms, -Xmx — размер heap.-XX:NewRatio — соотношение поколений.GC-логи анализируются для поиска пауз и аллокаций.
6. Утечки памяти
Причины: статические коллекции, кеши без очистки, listener’ы.
Инструменты: VisualVM, JConsole, Eclipse MAT.
7. OutOfMemoryError
Heap overflow, Metaspace overflow, Direct memory.
Решения: тюнинг heap, профилинг, оптимизация аллокаций.
8. Типы ссылок
Soft — для кешей.
Weak — сборка при следующем GC.
Phantom — для пост-очистки.
9. ThreadLocal
Утечки из-за хранения значений без remove().
Проблема усиливается в пуле потоков.
10. finalize()
Непредсказуемый вызов, влияет на GC.
Замена — Cleaner или try-with-resources.
11. Direct Memory
Off-heap через
ByteBuffer.allocateDirect.Контроль сложнее, GC не управляет напрямую.
12. JEP по GC
ZGC (JEP 307) — низкие паузы.
Shenandoah (JEP 189) — конкурентная очистка.
13. Архитектура JVM
ClassLoader, Runtime Data Areas, Execution Engine, JNI.
14. Загрузка классов
Loading → Linking → Initialization.
Загрузчики: Bootstrap, Platform (бывш. Extension), System.
15. Байткод
Инструкции JVM, стековая модель исполнения.
Интерпретируется и оптимизируется JIT.
16. JIT-компилятор
Горячий код компилируется в машинный.
Оптимизации: инлайнинг, удаление мертвого кода.
17. Структура .class
Magic number, constant pool, методы, атрибуты.
18. Жизненный цикл потоков
NEW → RUNNABLE → BLOCKED/WAITING → TERMINATED.
JVM управляет планированием через ОС.
19. JNI
Связка с нативным кодом (C/C++).
Используется для low-level операций.
20. Профилинг JVM
CPU, память, потоки.
Инструменты: VisualVM, JConsole.
21. HotSpot
Основная реализация JVM.
Использует адаптивную оптимизацию и JIT.
22. Манипуляция байткодом
ASM, BCEL, Javassist.
Применяется в прокси, AOP, фреймворках.
23. Инструменты диагностики
jstack — дамп потоков.
jmap — heap dump.
jstat — статистика GC.
24. Безопасность классов
Верификация байткода.
Security Manager (устаревший, но концепт важен).
25. Java Memory Model (JMM)
Правила видимости и happens-before.
Ключевые примитивы: volatile, synchronized.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
image_2026-05-02_07-05-20.png
291.1 KB
Паттерны в Java: паттерн «Строитель» позволяет гибко и прозрачно конструировать сложные объекты. #Java #ПаттерныПроектирования
👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1
Для кого-то неожиданно узнать, что Java не конкатенирует строки на этапе выполнения в таком кейсе:
Что важно:
Строка в Java хранится как
Строки размещаются в двух областях:
- куча
- пул строковых констант (SCP)
Пример:
Пример:
При такой записи:
компилятор Java выполняет константную свёртку и подставляет готовое значение:
Конкатенации на этапе выполнения нет — это вычисляется на этапе компиляции.
но это не работает со строковыми переменными:
здесь компилятор Java уже не может сделать константную свёртку, поэтому генерируется вызов через
На уровне байткода это реализуется через механизм динамической конкатенации строк (JEP 280 / JEP 357), который выбирает оптимальную стратегию выполнения во время запуска.
В ранних версиях вместо этого использовался
👉 Java Portal
String c = "a" + "b";Что важно:
Строка в Java хранится как
byte[] + флаг кодировки:0 — LATIN1 (1 байт на символ, для ASCII экономия памяти)1 — UTF-16 (2 байта на символ)Строки размещаются в двух областях:
- куча
- пул строковых констант (SCP)
Пример:
String a = "hello", b = "hello";
a == b → true, обе переменные указывают на один объект из пулаПример:
String a = "hello", b = new String("hello");a == b → false, разные объекты в кучеПри такой записи:
String c = "a" + "b";
компилятор Java выполняет константную свёртку и подставляет готовое значение:
String c = "ab";
Конкатенации на этапе выполнения нет — это вычисляется на этапе компиляции.
но это не работает со строковыми переменными:
java id="xq7v2m"
String a = "a", b = "b", c = a + b;
здесь компилятор Java уже не может сделать константную свёртку, поэтому генерируется вызов через
invokedynamic с StringConcatFactoryНа уровне байткода это реализуется через механизм динамической конкатенации строк (JEP 280 / JEP 357), который выбирает оптимальную стратегию выполнения во время запуска.
В ранних версиях вместо этого использовался
StringBuilder, где код фактически превращался в цепочку append() и финальный toString().Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔6👍1
Spring Boot: можно добавить глобальные метаданные OpenAPI через аннотацию
✅ Её размещают на основном классе приложения Spring Boot или в отдельном конфигурационном классе.
#SpringBoot #JavaDev
👉 Java Portal
@OpenAPIDefinition.#SpringBoot #JavaDev
Please open Telegram to view this post
VIEW IN TELEGRAM
Этот Dockerfile для Spring Boot создаёт образ, который потребляет на 33% меньше памяти по сравнению с образом, собранным с помощью Buildpacks (рекомендуемый Spring способ сборки Docker-образов) 💪
👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6❤1
В Java можно ставить метку на выражение, которое уже промечено другой меткой. И так хоть до бесконечности.
Полезно? Вряд ли.
Стоит ли использовать? Точно нет.
Но как факт — это работает
Пример:
> Код компилируется
> Метки (
Вывод:
Иногда Java действительно говорит с нами стихами🫢
👉 Java Portal
Полезно? Вряд ли.
Стоит ли использовать? Точно нет.
Но как факт — это работает
Пример:
String question;
to: be: or: not: that: is: the: question = "What?";
out.println(question);
> Код компилируется
> Метки (
to:, be:, or: и т.д.) игнорируются, если не используются в break или continueВывод:
What?
Иногда Java действительно говорит с нами стихами
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
Java Portal | Программирование
Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика
Связь: @devmangx
РКН: https://clck.ru/3H4WUg
Связь: @devmangx
РКН: https://clck.ru/3H4WUg
В Java лямбда-выражение создаёт экземпляр функционального интерфейса. Во время выполнения этот экземпляр создаётся с помощью класса
Следующий код на Java создаёт объект
Во время выполнения объект создаётся с помощью кода, аналогичного следующему:
При выполнении этот код выведет в консоль❤️
👉 Java Portal
LambdaMetaFactoryСледующий код на Java создаёт объект
Function<String, String>Function<String, String> f = s -> s.toUpperCase();
Во время выполнения объект создаётся с помощью кода, аналогичного следующему:
@SuppressWarnings("unchecked")
void main() throws Throwable {
MethodHandles.Lookup lookup;
lookup = MethodHandles.lookup();
CallSite callSite;
callSite = LambdaMetafactory.metafactory(
lookup,
"apply",
MethodType.methodType(Function.class),
MethodType.methodType(Object.class, Object.class),
lookup.findStatic(
getClass(),
"lambda",
MethodType.methodType(String.class, String.class)
),
MethodType.methodType(String.class, String.class)
);
MethodHandle target;
target = callSite.getTarget();
Function<String, String> f;
f = (Function<String, String>) target.invokeExact();
String msg;
msg = f.apply("Hello, World!");
IO.println(msg);
}
private static String lambda(String s) {
return s.toUpperCase();
}При выполнении этот код выведет в консоль
HELLO, WORLD! Please open Telegram to view this post
VIEW IN TELEGRAM
❤7
Java-совет : можно использовать
✅ Это быстрый способ создать немодифицируемые списки и множества без использования
#Java #Коллекции
👉 Java Portal
List.of() и Set.of() для создания неизменяемых коллекций.Collections.unmodifiableList().#Java #Коллекции
Please open Telegram to view this post
VIEW IN TELEGRAM
Значения области видимости финализированы в Java 25.
Более чистая альтернатива переменным, привязанным к потоку, с ограниченным временем жизни и хорошей совместимостью с виртуальными потоками.
👉 Java Portal
Более чистая альтернатива переменным, привязанным к потоку, с ограниченным временем жизни и хорошей совместимостью с виртуальными потоками.
static final ScopedValue<User> USER = ScopedValue.newInstance();
ScopedValue.where(USER, user)
.run(() -> UserService.updateUser());
Please open Telegram to view this post
VIEW IN TELEGRAM
Spring Boot: использование Spring Cloud Config для централизованного управления конфигурацией — важная практика.
Вместо того чтобы каждый сервис хранил свой
Сначала нужно сконфигурировать сервер конфигурации.
Поднимается отдельное приложение сервера конфигурации с аннотацией
Сервер отдает конфигурацию по HTTP, клиенты подтягивают её при старте.
Структура Git-репозитория следует соглашениям именования Spring Boot:
или
Клиентское приложение нужно настроить: добавить стартовую зависимость и минимальную конфигурацию.
Динамическое обновление конфигурации без рестарта достигается через перезагружаемые бины с аннотацией
Конфиденциальные данные должны быть зашифрованы в файлах конфигурации:
👉 Java Portal
Вместо того чтобы каждый сервис хранил свой
application.yml, конфигурация подтягивается из единого источника.Сначала нужно сконфигурировать сервер конфигурации.
Поднимается отдельное приложение сервера конфигурации с аннотацией
@EnableConfigServer и Git-репозиторий, где лежат все .yml файлы.Сервер отдает конфигурацию по HTTP, клиенты подтягивают её при старте.
<!-- Setting Up the Config Server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
// Enable it with @EnableConfigServer annotation
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
# Point it to your Git repository
spring:
cloud:
config:
server:
git:
uri: https://github.com/your-org/config-repo
default-label: main
clone-on-start: true
server:
port: 8888
Структура Git-репозитория следует соглашениям именования Spring Boot:
{application-name}-{profile}.ymlили
{application-name}/{profile}.ymlКлиентское приложение нужно настроить: добавить стартовую зависимость и минимальную конфигурацию.
<!-- Add the client dependency -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
# Configure the application to fetch config from the config server
spring:
application:
name: order-service
config:
import: "optional:configserver:http://localhost:8888"
cloud:
config:
profile: dev
server:
port: 8080
Динамическое обновление конфигурации без рестарта достигается через перезагружаемые бины с аннотацией
@RefreshScope:package ...;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
Конфиденциальные данные должны быть зашифрованы в файлах конфигурации:
@Service
@RefreshScope
public class PricingService {
@Value("${pricing.discount.percentage:0}")
private int discountPercentage;
// This value updates when config changes, no restart needed
}
curl -X POST http://localhost:8080/actuator/refresh
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥2❤1
Java: начиная с Java 14 можно использовать records для создания коротких неизменяемых объектов, предназначенных для хранения данных.
✅ короче обычных POJO
✅ имеют встроенные
✅ по умолчанию неизменяемые
#JavaDev #Records
👉 Java Portal
equals(), hashCode(), toString()#JavaDev #Records
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
JetBrains использует IDE-нативные возможности понимания кода, чтобы делать ИИ-агентов эффективнее на больших кодовых базах.
Зачем тратить время и токены на
Интересный момент: Codex, судя по наблюдениям, заметно лучше использует такие инструменты, чем Claude Code.
👉 Java Portal
Зачем тратить время и токены на
grep, если в IDE уже есть семантический поиск, навигация по символам и рефакторинги?Интересный момент: Codex, судя по наблюдениям, заметно лучше использует такие инструменты, чем Claude Code.
Please open Telegram to view this post
VIEW IN TELEGRAM
The JetBrains Blog
We Gave Agents IDE-Native Search Tools. They Got Faster and Cheaper. | The JetBrains AI Blog
We ran the same coding tasks with and without prebundled tooling, across multiple models and languages. Here's what changed.
👍3
Совет по Java
Используйте осмысленные имена методов, которые отражают их назначение.
#JavaDev #CleanCode
👉 Java Portal
Используйте осмысленные имена методов, которые отражают их назначение.
#JavaDev #CleanCode
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
POST не идемпотентен.
PUT — идемпотентен.
PATCH — зависит от реализации.
Ошибка в этих свойствах ломает ретраи.
Идемпотентность означает: один и тот же запрос даёт один и тот же результат.
Это важно, потому что сеть нестабильна, а клиенты делают повторные запросы.
Неидемпотентные эндпоинты дублируют побочные эффекты.
Два запроса могут означать две оплаты или два заказа.
GET — идемпотентен.
PUT — идемпотентен.
DELETE — идемпотентен.
POST — не идемпотентен.
PATCH — зависит (инкремент vs установка значения).
Для неидемпотентных эндпоинтов используют идемпотентные ключи:
клиент отправляет уникальный ключ,
сервер сохраняет ключ и ответ,
повтор с тем же ключом возвращает тот же результат.
Так устроены платёжные системы.
Без этого ретраи превращаются в дублирование операций.
👉 Java Portal
PUT — идемпотентен.
PATCH — зависит от реализации.
Ошибка в этих свойствах ломает ретраи.
Идемпотентность означает: один и тот же запрос даёт один и тот же результат.
Это важно, потому что сеть нестабильна, а клиенты делают повторные запросы.
Неидемпотентные эндпоинты дублируют побочные эффекты.
Два запроса могут означать две оплаты или два заказа.
GET — идемпотентен.
PUT — идемпотентен.
DELETE — идемпотентен.
POST — не идемпотентен.
PATCH — зависит (инкремент vs установка значения).
Для неидемпотентных эндпоинтов используют идемпотентные ключи:
клиент отправляет уникальный ключ,
сервер сохраняет ключ и ответ,
повтор с тем же ключом возвращает тот же результат.
Так устроены платёжные системы.
Без этого ретраи превращаются в дублирование операций.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9🔥2
Возможно, один из самых безумных репозиториев с Docker
Он позволяет запускать полноценную macOS внутри Docker -контейнера и открывать её прямо из браузера.
- Поднимается macOS одной командой Докера
- Запуск полноценной macOS на Linux через QEMU/KVM
- Открывается сразу в браузере
- Поддержка нескольких версий macOS
- Подходит для тестирования, CI и macOS-специфичных инструментов
Такие проекты хорошо показывают, насколько далеко можно зайти с Docker и виртуализацией.
Репозиторий: https://github.com/dockur/macos
👉 Java Portal
Он позволяет запускать полноценную macOS внутри Docker -контейнера и открывать её прямо из браузера.
- Поднимается macOS одной командой Докера
- Запуск полноценной macOS на Linux через QEMU/KVM
- Открывается сразу в браузере
- Поддержка нескольких версий macOS
- Подходит для тестирования, CI и macOS-специфичных инструментов
Такие проекты хорошо показывают, насколько далеко можно зайти с Docker и виртуализацией.
Репозиторий: https://github.com/dockur/macos
Please open Telegram to view this post
VIEW IN TELEGRAM
GitHub
GitHub - dockur/macos: MacOS inside a Docker container.
MacOS inside a Docker container. Contribute to dockur/macos development by creating an account on GitHub.
👍3
Spring Boot: используйте
#SpringBoot #SoftwareDevelopment
👉 Java Portal
@Async только для небольших задач на оффлоадинг и только с явно заданным исполнителем.#SpringBoot #SoftwareDevelopment
Please open Telegram to view this post
VIEW IN TELEGRAM
Микросервисы — плохой выбор по умолчанию для 94% команд.
Зачем разбивать приложение на набор сервисов, которым нужно общаться через сеть.
На бумаге это выглядит как «правильный» подход. Масштабирование звучит привлекательно.
Но на практике я видел, как это ломается, шесть раз.
Команды из 5 инженеров поднимали 11 сервисов с несколькими очередями сообщений. Всё становилось медленнее.
Деплой, который занимал минуты, растягивался до 35 минут из-за зависимостей.
Отладка превращалась в кошмар: один баг — и приходится трейсить запрос через несколько сервисов и кодовых баз.
Сложность не уменьшилась. Она просто распределилась.
Микросервисы — это решение под масштабирование, но большинство команд внедряют их слишком рано, когда проблемы масштаба ещё нет.
Если ты всё ещё работаешь на localhost, основная проблема — не масштаб. Это стабильный релиз.
Когда микросервисы имеют смысл:
- команды блокируют работу друг друга
- части системы требуют независимого масштабирования
- есть нормальная трассировка в проде, и можно отлаживать без угадывания
Если этого нет — платишь налог распределённых систем без реальной выгоды.
Начинай с монолита и держи модульность. Делить стоит только тогда, когда связность начинает тормозить разработку.
Большинство обсуждений «нам нужны микросервисы» на деле не про архитектуру.
Они про грязную кодовую базу или болезненные деплои.
Сначала решаются эти проблемы.
Простые системы легче понимать. Перегруженные обычно разваливаются под собственным весом.
👉 Java Portal
Зачем разбивать приложение на набор сервисов, которым нужно общаться через сеть.
На бумаге это выглядит как «правильный» подход. Масштабирование звучит привлекательно.
Но на практике я видел, как это ломается, шесть раз.
Команды из 5 инженеров поднимали 11 сервисов с несколькими очередями сообщений. Всё становилось медленнее.
Деплой, который занимал минуты, растягивался до 35 минут из-за зависимостей.
Отладка превращалась в кошмар: один баг — и приходится трейсить запрос через несколько сервисов и кодовых баз.
Сложность не уменьшилась. Она просто распределилась.
Микросервисы — это решение под масштабирование, но большинство команд внедряют их слишком рано, когда проблемы масштаба ещё нет.
Если ты всё ещё работаешь на localhost, основная проблема — не масштаб. Это стабильный релиз.
Когда микросервисы имеют смысл:
- команды блокируют работу друг друга
- части системы требуют независимого масштабирования
- есть нормальная трассировка в проде, и можно отлаживать без угадывания
Если этого нет — платишь налог распределённых систем без реальной выгоды.
Начинай с монолита и держи модульность. Делить стоит только тогда, когда связность начинает тормозить разработку.
Большинство обсуждений «нам нужны микросервисы» на деле не про архитектуру.
Они про грязную кодовую базу или болезненные деплои.
Сначала решаются эти проблемы.
Простые системы легче понимать. Перегруженные обычно разваливаются под собственным весом.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10