12073
Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика Связь: @devmangx РКН: https://clck.ru/3H4WUg
Как один баг в Google Cloud уронил весь Интернет
12 июня Google Cloud упал, и вместе с ним перестали работать Spotify, Fitbit, Gmail, Google Drive, Vertex AI и десятки других сервисов. Причиной оказался всего один null pointer баг в Service Control — сервисе, через который проходит почти каждый запрос к Google Cloud API.
Все запросы проходят через Service Control, он как вышибала, решающий, есть ли у тебя доступ. Если он падает, то рушится всё.
В конце мая Google добавил туда новый код для проверки квот, где не было обработки ошибок на пустые поля. На тестах этот код не активировался, потому что требовалась специфичная политика. Не было ни feature flag, ни постепенного раската — просто мёртвый код, ждавший своего часа.
12 июня утром в базы попала политика с пустыми полями. Service Control попытался её обработать, наткнулся на null pointer и упал.
Spanner почти мгновенно разнёс некорректные данные по всему миру, и каждая инстанция, которая к ним обратилась, падала следом. Двух минут хватило, чтобы Google Cloud лег глобально.
Начались таймауты, 503 от перегруженных систем и 401, когда пустые политики интерпретировались как отсутствие прав.
Пользователи Spotify массово получали 401, Fitbit выдавал разные ошибки в зависимости от региона, сервисы не могли пройти аутентификацию к своим бэкендам.
У Google был kill switch — красная кнопка, чтобы отключить проблемный код. Её нажали через сорок минут, и большая часть регионов восстановилась. Но us-central1 оставался недоступен ещё три часа. Когда тысячи инстансов Service Control перезапустились одновременно, они одновременно пошли в базу и устроили эффект стада, который уронил даже сам фикс.
Хуже всего то, что статус-дэшборд Google тоже крутился на Google Cloud. Когда облако упало, он умер вместе с ним, и мониторинг ослеп. Команды поддержки почти час работали вслепую.
Инцидент случился потому, что не было feature flag на новом коде, не было проверки на null в критическом пути, данные с багом мгновенно разлетелись по всему миру, восстановление не имело задержек и мониторинг был привязан к той же инфраструктуре, которую он должен был отслеживать.
После этого Google заморозил изменения в Service Control, начал переделывать систему так, чтобы компоненты могли падать независимо, добавляет задержки в репликацию, чтобы отлавливать некорректные данные, и строит отдельный мониторинг, который будет жить вне основной системы.
В итоге вся история показала, что один пропущенный if может уронить одну из самых сложных платформ в мире. Не атака и не катастрофа, а просто null pointer.
В распределённых системах локальный сбой превращается в глобальную аварию быстрее, чем человек успевает отреагировать. Инфраструктура, которая даёт масштаб, так же усиливает и ошибки.
Любой запрос к API всегда на расстоянии одного непроверенного значения от фатала. Это и есть реальность современной облачной архитектуры.
Полный отчет о происшествии: ссылка
👉 Java Portal
Иногда я удивляюсь тому, насколько Java и C# похожи.
Оба языка работают в управляемой среде выполнения с JIT-компиляцией и сборкой мусора: JVM для Java и CLR для C#.
Оба имеют строгую статическую типизацию. Я также нашёл статью, в которой говорится, что к 2026 году даже разрыв в возможностях языков практически исчез: records, pattern matching, primary constructors и так далее.
Java Code Geeks, «The Feature Gap Has Closed», 2026.
Какой язык вы предпочитаете и почему?
👉 Java Portal
Хотите стать backend-инженером, которого в 2026 году захотят нанять компании уровня Google, Uber, Netflix и Stripe?
Тогда изучите:
## Сети
- DNS
- TCP/IP
- HTTP/2
- HTTP/3
- TLS
## Внутреннее устройство баз данных
- B+-деревья
- MVCC
- WAL
- оптимизаторы запросов
- индексы
## Проектирование API
- REST
- gRPC
- GraphQL
- идемпотентность
- пагинация
## Распределённые системы
- теорема CAP
- консенсус
- репликация
- CQRS
- Saga
## Событийно-ориентированная архитектура
- Kafka
- Outbox Pattern
- CDC
- потоковая обработка событий
## Инженерия производительности
- пулы соединений
- кэширование
- асинхронный ввод-вывод
- профилирование
## Cloud Native
- Docker
- Kubernetes
- Service Mesh
- автомасштабирование
## Наблюдаемость
- OpenTelemetry
- Prometheus
- Grafana
- ELK
## Безопасность
- OAuth 2.0
- JWT
- mTLS
- Zero Trust
- OWASP Top 10
## Production Engineering
- Blue-Green Deployments
- Canary Releases
- Chaos Engineering
- Disaster Recovery
👉 Java Portal
Spring Boot: HTTP-клиенты через интерфейсы с @HttpExchange.
✅ Аннотируйте интерфейс — Spring Boot создаст клиентскую реализацию
✅ Настройте тайм-ауты/SSL с помощью свойств spring.http.clients.*
#SpringBoot4 #HttpExchange
👉 Java Portal
Как опытный Java-разработчик/бэкенд-инженер, ты должен разбираться в отказоустойчивости и паттерне Circuit Breaker. Вот сценарий ненадёжного платёжного шлюза 💳 , чтобы проверить знания кандидата:
Сценарий:
Твоё приложение интегрируется со сторонним платёжным API. При пиковых нагрузках этот API стабильно даёт сбой примерно в 2% запросов. Это приводит к неудачным оплатам и ухудшает пользовательский опыт.
Вопрос:
Как ты спроектируешь интеграцию так, чтобы она была устойчива к этим сбоям и при этом сохраняла хороший UX? Объясни, какие именно паттерны (например, Circuit Breaker или Retry с экспоненциальной задержкой) ты бы применил и почему. Как бы ты обработал возможные дубликаты транзакций, возникающие из-за повторных запросов?
→ Что я оцениваю:
Понимание паттернов устойчивости и отказоустойчивости. Кандидат должен уметь объяснить такие концепции, как повторные запросы, Circuit Breaker (например, с использованием Resilience4j), fallback-механизмы, а также критическую важность идемпотентности при проектировании интеграций с платёжными системами.
В примере показано как реализовать Resilience4j с fallback-методом в Spring Boot
👉 Java Portal
Принципы проектирования программного обеспечения 👇
[1.] KISS (Keep It Simple, Stupid)
▶Программное обеспечение должно быть максимально простым.
▶Используйте понятный и лаконичный код, избегайте излишней сложности и сосредотачивайтесь на основных функциях.
[2.] DRY (Don't Repeat Yourself)
▶Код не должен дублироваться.
▶Используйте функции и классы для объединения общего кода.
▶Применяйте переменные и константы для хранения значений, которые используются в нескольких местах.
[3.] YAGNI (You Ain't Gonna Need It)
▶Не добавляйте в программное обеспечение функции, которые не нужны.
▶Поддерживайте простоту и удобство сопровождения.
[4.] SOLID
▶ Принцип единственной ответственности – класс должен выполнять только одну задачу.
▶ Принцип открытости/закрытости – классы должны быть открыты для расширения, но закрыты для изменения.
▶ Принцип подстановки Барбары Лисков – объекты дочернего класса должны заменять объекты базового класса без нарушения функциональности.
▶Принцип разделения интерфейса – клиенты не должны зависеть от методов, которые они не используют.
▶Принцип инверсии зависимостей – зависимости должны внедряться в класс, а не быть жёстко закодированными.
[5.] Принцип наименьшего удивления**
▶ Разрабатывайте программное обеспечение так, чтобы оно соответствовало ожиданиям пользователя.
▶ Используйте знакомую терминологию и соглашения, предоставляйте понятные инструкции.
▶ Применяйте четкие и лаконичные сообщения об ошибках.
[6.] Принцип модульности**
▶ Проектируйте программное обеспечение как набор независимых модулей.
▶ Это упрощает понимание, сопровождение и тестирование кода.
[7.] Принцип абстракции
▶ Скрывайте детали реализации от пользователя.
▶ Это делает программное обеспечение более понятным и удобным.
[8.] Принцип инкапсуляции
▶Программное обеспечение должно скрывать внутреннее состояние объекта от внешнего мира.
▶Это повышает устойчивость и удобство сопровождения.
[9.] Принцип наименьшего знания
▶ Проектируйте программное обеспечение так, чтобы минимизировать объем знаний модуля о других модулях.
▶ Это помогает повысить модульность и гибкость системы.
[10.] Принцип низкой связности и высокой когезии
▶Связность – это степень зависимости элементов модуля друг от друга.
▶Модуль с низкой связностью имеет мало зависимостей, и его элементы слабо зависят друг от друга.
❗ Когезия – это степень, с которой элементы модуля относятся к одной цели.
▶ Модуль с высокой когезией имеет одну четко определенную задачу, и все его элементы связаны с её выполнением.
👉 Java Portal
Я только что наткнулся на этот репозиторий — и он отличный.
Хотите самостоятельно хостить OAuth 2.0-аутентификацию и не зависеть от Auth0, Clerk, Firebase или Supabase?
Тогда OpenAuth — именно то, что вам нужно.
Это универсальный провайдер аутентификации на основе стандартов, который можно полностью развернуть в собственной инфраструктуре.
Он работает с любым фреймворком и на любой платформе, а также совместим с любым OAuth 2.0-клиентом.
Главные возможности:
Полная поддержка OAuth 2.0 — его может использовать любой OAuth-клиент.
Гибкое развёртывание: Node.js, Bun, AWS Lambda или Cloudflare Workers.
Нативная поддержка Google, GitHub и других провайдеров, а также локальных сценариев: email и пароль, PIN-код и другие.
Готовый интерфейс, который можно полностью настроить или заменить собственным.
Полный контроль над управлением пользователями: через простой callback success можно реализовать собственную логику создания и поиска пользователей.
Лёгкое хранилище на основе KV, включая Cloudflare KV и DynamoDB.
Типобезопасный API и простая интеграция.
Сис. дизайн: Балансировщик нагрузки
Балансировщик нагрузки равномерно распределяет входящий трафик между веб-серверами, объединёнными в балансируемую группу.
- Пользователь подключается напрямую к публичному IP-адресу балансировщика нагрузки. При такой схеме клиенты больше не могут обращаться к веб-серверам напрямую.
- Это повышает безопасность: для взаимодействия между серверами используются приватные IP-адреса, недоступные из интернета.
- Балансировщик нагрузки взаимодействует с веб-серверами через приватные IP-адреса.
Добавив второй веб-сервер, мы устранили проблему отсутствия отказоустойчивости и повысили доступность веб-уровня.
- Если сервер 1 выйдет из строя, весь трафик будет перенаправлен на сервер 2. Это не позволит сайту стать недоступным.
- Если трафик сайта резко вырастет и двух серверов окажется недостаточно, балансировщик нагрузки позволит корректно решить эту проблему. В пул можно добавить дополнительные веб-серверы, после чего балансировщик автоматически начнёт направлять запросы и на них.
Вертикальное и горизонтальное масштабирование
Вертикальное масштабирование, также называемое scale up, — это процесс увеличения мощности серверов: добавления CPU, оперативной памяти и других ресурсов.
Горизонтальное масштабирование, также называемое scale out, позволяет масштабировать систему за счёт добавления новых серверов в пул ресурсов.
При низкой нагрузке вертикальное масштабирование может быть хорошим вариантом, а его главное преимущество — простота.
Ограничения вертикального масштабирования
- Невозможно бесконечно добавлять CPU и память одному серверу.
- Отсутствует отказоустойчивость. Если сервер выходит из строя, сайт или приложение полностью перестаёт работать.
Для крупномасштабных приложений горизонтальное масштабирование обычно предпочтительнее из-за ограничений вертикального масштабирования.
Если множество пользователей одновременно обращаются к веб-серверу и нагрузка достигает его предела, пользователи сталкиваются с увеличением времени ответа или вообще не получают ответ.
Эта проблема решается с помощью горизонтального масштабирования и балансировщика нагрузки.
👉 Java Portal
Java Streams: limit(n) превращает бесконечный поток в конечный.
✅ Полезно при работе со Stream.iterate() / generate() — они могут создавать бесконечные потоки
✅ limit(5) означает: «взять первые 5 элементов и остановиться»
✅ Отлично подходит для выборки данных или получения первых N значений
#Java #Streams
👉 Java Portal
Databasement — это инструмент для управления резервными копиями баз данных через self-hosted веб-интерфейс.
👉 Java Portal
Системный дизайн: Архитектура с одним сервером
Проектирование системы, способной обслуживать миллионы пользователей, — сложная задача. Это долгий путь, требующий постоянной доработки и непрерывного улучшения.
Обычно всё начинается с простого варианта: все компоненты работают на одном сервере.
Посмотрим, как проходит запрос:
> Пользователь обращается к api.mysite.com через веб-приложение или мобильное приложение.
> DNS преобразует доменное имя в IP-адрес 27.220.30.232.
> Запрос поступает на единственный веб-сервер.
> Сервер выполняет всё самостоятельно:
обрабатывает API-запрос;
выполняет бизнес-логику;
обращается к базе данных.
> Сервер отправляет пользователю HTML-страницу или JSON-ответ для дальнейшего отображения.
👉 Java Portal
> 💡 Java: Тестируйте граничные случаи: null, пустые коллекции и предельные значения — именно там чаще всего скрываются баги.
✅ Одних тестов счастливого пути недостаточно — они не помогут выявить NullPointerException при отсутствии входных данных.
✅ Пустые списки и коллекции с одним элементом нередко ведут себя иначе, чем коллекции с «обычными» данными.
✅ Явные тесты для null, пустых коллекций, а также минимальных и максимальных значений документируют ожидаемое поведение.
#Testing
👉 Java Portal
Архитектура Docker
Если вы только начинаете работать с Docker, эта схема может показаться сложной.
Но на самом деле всё устроено довольно просто.
Вы вводите команду, например:
docker run nginx
Вы
│
▼
Docker Client
│
▼
Docker Daemon
│
▼
Docker Image
│
▼
Docker Container
Создавайте первоклассную документацию для своего API или проекта.
Starlight предлагает всё необходимое: высокую скорость благодаря Astro, встроенную оптимизацию для SEO, доступность и поиск, а также поддержку Markdown, MDX и нескольких языков.
→ http://starlight.astro.build/es
👉 Java Portal
Масштабирование базы данных и стратегии шардинга — простое объяснение с иллюстрациями
По мере роста приложения или системы база данных тоже должна масштабироваться, чтобы справляться с увеличивающейся нагрузкой. Ниже — обзор основных стратегий.
1. Горизонтальное масштабирование (Horizontal Scaling)
Добавление новых серверов для распределения нагрузки и увеличения общей производительности без перегрузки одного сервера.
2. Вертикальное масштабирование (Vertical Scaling)
Увеличение ресурсов существующего сервера — процессора, оперативной памяти или дискового пространства — чтобы он мог обрабатывать больше запросов.
3. Стратегии партиционирования (Partition Strategies)
Логическое разделение большой базы данных на части (например, по времени, региону или типу данных), что упрощает управление и ускоряет доступ к данным.
4. Шардинг по диапазонам (Range-Based Sharding)
Данные распределяются между шардами по диапазонам значений (например, по цене, дате или идентификатору), что ускоряет поиск по таким полям.
5. Равномерное распределение данных (Even Distribution)
Нагрузка равномерно распределяется между всеми серверами, что позволяет максимально эффективно использовать ресурсы и избегать узких мест.
6. Неравномерное распределение данных (Uneven Distribution)
Нагрузка распределена неравномерно: одни серверы перегружены, а другие практически простаивают, что снижает эффективность всей системы.
7. Шардинг по ключу (Key-Based Sharding)
Для распределения данных между шардами используется хеш-функция, которая обеспечивает стабильное и равномерное распределение записей.
8. Масштабирование операций чтения (Scaling Reads)
Создание нескольких реплик базы данных только для чтения (Read Replicas), чтобы обрабатывать большое количество запросов и снизить нагрузку на основную базу данных.
9. Монолитная база данных vs шардинг (Monolith vs Sharding)
Вместо одной большой монолитной базы данных данные разделяются на логические шарды. Такой подход облегчает масштабирование системы, упрощает организацию данных и повышает производительность.
Эти подходы являются основой проектирования масштабируемых систем и часто используются при разработке высоконагруженных приложений и при подготовке к техническим собеседованиям по System Design.
👉 Java Portal
Для null-safe проверки равенства лучше использовать Objects.equals(a, b).
✅ a.equals(b) выбросит NullPointerException, если a равен null
✅ Objects.equals корректно обрабатывает null с обеих сторон
✅ Оба значения null → true; одно значение null → false; иначе вызывается a.equals(b)
#Java #Objects
👉 Java Portal
Ты на интервью по системному дизайну. Спрашивают: «Как бы ты спроектировал слой кэширования для высоконагруженного веб-приложения?»
Вот подробный подход:
I. Что кэшировать → Кэшируй дорогие запросы к БД, горячие данные с большим количеством чтений и статические ресурсы; избегай очень динамичных, гигантских объектов или чувствительной PII, если только она не зашифрована и не защищена доступом.
II. Хранилище кэша → Используй Redis или Memcached для распределённого in-memory кэша, CDN для статики на краю сети, локальные in-process кэши (например, Caffeine) для сверхнизкой задержки L1.
III. Паттерн и запись → По умолчанию Cache-Aside: читаем из кэша, при промахе читаем из БД и заполняем кэш. Для сильной консистентности чтения — Write-Through (пишем одновременно в кэш и БД). Всегда сначала коммитим БД, потом обновляем/инвалидируем кэш, чтобы не дать устаревшим данным просочиться.
IV. Истечение и вытеснение → TTL для каждого типа данных, чтобы держать кэш свежим, политики вытеснения (LRU/LFU) для управления памятью, negative caching для промахов, чтобы не перегружать БД. Ограничивай размер объектов, чтобы не создавать проблемы с памятью и сборкой мусора.
V. Масштабирование и «горячие ключи» → Масштабируй через consistent hashing и реплики для пропускной способности чтения. Многоуровневый кэш (edge→regional→local). Горячие ключи — локальные L1 кэши, отдельные кэши для горячих ключей, либо rate-limiting запросов.
VI. Надёжность и наблюдаемость → Предотвращай «каскады» промахов через request coalescing, короткие блокировки (SETNX + expiry) или serve-stale-while-revalidate с jittered TTL. Мониторь hit rate, latency, eviction, память и replication lag с алертами.
👉 Java Portal
Утверждение «Go потребляет в 4 раза меньше памяти, чем Java» в целом верно, но применимо далеко не во всех сценариях.
При нагрузке в 500 запросов в секунду сервис на Go использует около 68 МБ памяти, а JVM — около 412 МБ (BackendBytes).
Но при 1 миллионе конкурентных задач ситуация меняется на противоположную: Java использует около 800 МБ, а Go — примерно 2,5 ГБ (WebDev|today).
«Победитель» по потреблению памяти зависит от конкретной нагрузки.
Именно поэтому нельзя просто разбрасываться случайными цифрами без учёта контекста.
👉 Java Portal
Концепции моделирования данных, которые должен знать каждый разработчик
1. Сущность — Объект реального мира или концепт, о котором вы хотите хранить данные (например, пользователь, заказ).
2. Атрибут — Свойство или поле сущности (например, имя, email, цена).
3. Первичный ключ — Уникальный идентификатор для каждой строки в таблице (например, user_id).
4. Внешний ключ — Ссылка на первичный ключ в другой таблице; используется для связывания сущностей.
5. Связь "один к одному" — Каждая строка в одной таблице связана с одной строкой в другой.
6. Связь "один ко многим" — Одна строка в таблице связана с несколькими строками в другой (например, пользователь → посты).
7. Связь "многие ко многим" — Несколько строк в одной таблице связаны с несколькими строками в другой (требуется таблица-связка).
8. Нормализация — Организация данных с целью уменьшения дублирования и повышения целостности.
9. Денормализация — Добавление избыточных (дублированных) данных для повышения скорости чтения.
10. Первая нормальная форма (1NF) — Устранение повторяющихся групп; каждая ячейка содержит атомарное значение.
11. Вторая нормальная форма (2NF) — Устранение частичных зависимостей от составного ключа.
12. Третья нормальная форма (3NF) — Устранение транзитивных зависимостей (неключевые столбцы не зависят от других неключевых столбцов).
13. Суррогатный ключ — Системно-сгенерированный идентификатор (например, UUID или auto-increment ID).
14. Естественный ключ — Уникальный идентификатор из реального мира (например, email или номер паспорта).
15. Составной ключ — Первичный ключ, состоящий из нескольких столбцов.
16. Уникальное ограничение — Обеспечивает уникальность значений в столбце (или группе столбцов).
17. Допустимость NULL — Возможность хранить в столбце NULL (т.е. отсутствие значения).
18. Ограничение по значению — Проверяет значения в столбце на соответствие условиям (например, age > 0).
19. Индекс — Повышает производительность поиска за счёт ускоренного доступа к данным.
20. Схема — Структура/определение таблиц, полей, типов и связей в базе данных.
21. ERD (диаграмма "сущность-связь") — Визуальное представление сущностей и их связей.
22. Кардинальность — Количество строк, которое может быть связано в рамках связи.
23. Тип данных — Определяет, какие значения может хранить столбец (например, INT, VARCHAR, DATE).
24. Перечисление — Поле, значение которого ограничено предопределённым набором (например, status = [pending, complete]).
25. Мягкое удаление — Пометка записи как удалённой без фактического удаления (например, deleted_at).
👉 Java Portal
Серия о проектировании систем : Кэш
Кэш — это временное хранилище, в котором в памяти сохраняются результаты ресурсоёмких запросов или часто используемые данные, чтобы последующие обращения обрабатывались быстрее.
При каждой загрузке страницы выполняется один или несколько запросов к базе данных. Многократные обращения к базе могут значительно снижать производительность приложения. Кэш помогает решить эту проблему.
> Уровень кэширования
Отдельный уровень кэширования даёт несколько преимуществ:
- повышает производительность системы;
- снижает нагрузку на базу данных;
- позволяет масштабировать кэш независимо от других компонентов.
Работа происходит следующим образом:
1. Получив запрос, веб-сервер сначала проверяет, есть ли нужный ответ в кэше.
2. Если ответ есть, сервер отправляет его клиенту.
3. Если ответа нет, сервер обращается к базе данных, сохраняет результат в кэше и отправляет его клиенту.
Такая стратегия называется read-through cache — «сквозное чтение через кэш».
Существуют и другие стратегии кэширования. Выбор зависит от типа и объёма данных, а также от характера обращений к ним.
> Когда использовать кэш?
Кэш особенно полезен, когда данные:
- часто читаются;
- редко изменяются.
Важные данные должны храниться в постоянном хранилище, поскольку кэш обычно находится в оперативной памяти и не предназначен для долговременного хранения.
> Политика истечения срока действия
Рекомендуется задавать срок жизни кэшированных данных.
Без такой политики данные могут оставаться в памяти неограниченно долго.
Слишком короткий срок жизни приведёт к частым обращениям к базе данных, а слишком длинный — к тому, что данные в кэше устареют.
> Согласованность данных
Необходимо поддерживать синхронизацию между основным хранилищем и кэшем.
Несогласованность может возникнуть, если изменения в базе данных и кэше выполняются не в рамках одной транзакции.
> Предотвращение сбоев
Один сервер кэша является единой точкой отказа, или SPOF — Single Point of Failure.
Поэтому для повышения отказоустойчивости рекомендуется использовать несколько серверов кэша.
> Политика вытеснения
Когда кэш заполняется, добавление новых элементов может приводить к удалению уже существующих.
Этот процесс называется вытеснением из кэша.
Самая популярная политика вытеснения — LRU, Least Recently Used, то есть удаление данных, которые не использовались дольше всего.
👉 Java Portal
💡 Используйте Optional.orElseThrow(), когда отсутствие значения — это ошибка.
✅ orElse(null) → NPE возникает позже, далеко от места поиска значения
✅ orElseThrow() останавливает выполнение в месте возникновения проблемы и выбрасывает понятное исключение
✅ Передавайте Supplier, чтобы в сообщении было указано, какое именно значение отсутствует
#Java #Optional
👉 Java Portal
⚡️💬 Оригинальный Claude API от $0.40 за 1M токенов
Без VPN, дорогих подписок и подмены модели под капотом.
ClaudeHub — для тех, кто использует ИИ в коде, учёбе, работе, ботах и своих проектах.
выбираете Claude — получаете Claude
Платите только за фактическое использование токенов и быстро начинаете через Telegram-бота.
Подходит для Cursor, Claude Code, Cline, Roo, Continue и любых проектов через API.
🆓 Первые 100 пользователей получают 50₽ на баланс по промокоду: FIRST100
✨ Быстрый старт: @claudehub_bot
🔗 Регистрация: app.claudehub.fun/register
💬 Поддержка: t.me/claudehub_support
💡 Java I/O: используйте Files.copy(), чтобы скопировать файл одной строкой.
✅ Отлично подходит для резервных копий: data.csv → data.csv.bak
✅ Используйте REPLACE_EXISTING, если целевой файл уже может существовать
✅ Работает с Path, поэтому код переносим между разными ОС
#Java #Files
👉 Java Portal
Системный дизайн: База данных
По мере роста числа пользователей одного сервера, на котором размещены веб-уровень и уровень данных, становится недостаточно. Поэтому нам потребуется несколько серверов:
- один для обработки веб- и мобильного трафика — веб-уровень (web tier);
- другой для базы данных — уровень данных (data tier).
Разделение серверов, обрабатывающих веб- и мобильный трафик, и серверов базы данных позволяет масштабировать эти уровни независимо друг от друга.
Какую базу данных использовать?
Можно выбрать между традиционной реляционной базой данных — RDBMS, или SQL-базой данных — и нереляционной базой данных — NoSQL.
Реляционные базы данных представляют и хранят данные в виде таблиц и строк. С помощью SQL можно выполнять операции JOIN между различными таблицами базы данных.
Нереляционная база данных может быть подходящим выбором, если:
- приложению требуется сверхнизкая задержка;
- данные неструктурированы или не имеют связей;
- требуется только сериализация и десериализация данных — JSON, YAML и т. д.;
- необходимо хранить огромные объёмы данных.
👉 Java Portal
Новый сервис, для конверта документов в Markdown: https://docs.context.dev/api-reference/utility/parse
Достаточно сделать один API-запрос: отправить содержимое файла и получить на выходе Markdown с сохранённой структурой, ссылками и порядком текста.
Сервис поддерживает PDF, Word, Excel, PowerPoint, HTML, CSV, изображения, исходный код и многие другие форматы. Если документ представляет собой скан или фотографию, встроенный OCR автоматически распознает текст.
👉 Java Portal
Rate Limiting ≠ Throttling ≠ Backpressure
Эти три термина часто используют как взаимозаменяемые…
Но на самом деле они решают совершенно разные задачи масштабирования.
Вот самый простой способ их запомнить:
- Rate Limiting → ограничивает количество запросов, которые клиент может отправить.
- Throttling → ограничивает скорость обработки запросов системой, когда она находится под высокой нагрузкой.
- Backpressure → позволяет медленному потребителю сигнализировать быстрому производителю, чтобы тот снизил скорость и не перегружал систему.
Простая шпаргалка
- Rate Limiting = ограничение количества запросов.
- Throttling = замедление обработки.
- Backpressure = управление потоком данных.
Где используется каждый из подходов?
Rate Limiting
Используется в:
- API Gateway
- Публичных API
- Эндпоинтах авторизации
- Защите от злоупотреблений и DDoS-атак
Типичный ответ сервера:
HTTP/1.1 429 Too Many Requests
PostgreSQL 19 представляет запросы в графовом стиле.
Вместо того чтобы вручную связывать таблицу за таблицей через JOIN
, теперь можно описать путь по данным:
клиент → купил → товар ← купил ← похожий клиент → подписан на → бренд
Такой подход полезен для:
• рекомендательных систем;
• управления доступом;
• обнаружения мошенничества;
• графов знаний (Knowledge Graphs);
• предоставления контекста для AI.
👉 Java Portal
FastAPI с трёхуровневой архитектурой в стиле Java: слои controller, service, crud, schema и model, организованные по аналогии с паттернами Spring Boot. Включает поддержку SQLAlchemy 2.0, авторизации на базе Casbin и Docker.
https://github.com/fastapi-practices/fastapi-best-architecture
👉 Java Portal
Java: Используйте Deque вместо Stack для реализации стека (LIFO — last in, first out, «последним пришёл — первым вышел»).
✅ Stack — это устаревший класс. Он наследуется от Vector и синхронизирует каждую операцию.
✅ Deque поддерживает те же методы: push, pop и peek.
✅ ArrayDeque работает быстрее, чем Stack.
#JavaDev
👉 Java Portal
Массивы в Java
Представьте, что вам нужно хранить оценки 100 студентов.
Неужели вы будете создавать 100 отдельных переменных?
int mark1;
int mark2;
int mark3;
...
int[] scores = {10, 20, 30, 40, 50};Индекс : 0 1 2 3 4
Значение:10 20 30 40 50
int[] numbers;
numbers = new int[5];
int[] numbers = new int[5];
int[] numbers = {10, 20, 30, 40, 50};System.out.println(numbers[2]); // 30
numbers[1] = 25;
numbers.length
for (int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}int[] arr = new int[3];
0 0 0
int[] arr = {10, 20, 30};
System.out.println(arr[3]);0, 1, 2