Risk Management
BIS Financial Stability Institute
Artificial intelligence and climate change: balancing innovation and sustainability
Открыть оригинал ↗ Перевод заголовка: Искусственный интеллект и изменение климата: баланс инноваций и устойчивости
Статья рассматривает влияние искусственного интеллекта (ИИ) на климатическую трансформацию — как в позитивном аспекте (повышение энергоэффективности, оптимизация ресурсов, улучшение прогнозов и управления рисками), так и в негативном (рост потребления вычислительной мощности, увеличение электрической нагрузки и выбросов, зависящих от углеродной интенсивности энергии). Авторы анализируют два сценария: постепенный рост ИИ-навыков («AI copilot»), где эффекты развиваются медленно, и более радикальный сценарий с развитием обобщённого ИИ (AGI), при котором риски и выгоды могут значительно увеличиться и стать менее предсказуемыми. Важно понимать, что окончательный климатический эффект зависит не только от технологий, но и от их масштаба, энергетической эффективности и способности трансформировать экономику.
- Потребность в вычислительных ресурсах ИИ приводит к росту электрической нагрузки, что может усугубить выбросы, если энергия генерируется на углеродно-интенсивных источниках.
- Эффект «восстановления» (rebound effect) может снизить экологическую выгоду: снижение затрат и рост производительности могут привести к увеличению общего потребления ресурсов.
- Влияние ИИ на климат напрямую связано с его масштабом и интеграцией в экономику — рост ИИ может усилить инфляцию и нарушить финансовую стабильность через рост инвестиций в ИИ и энергетику.
- Центральные банки должны учитывать ИИ как фактор, влияющий на потенциальный объём производства и климатические риски, что требует новых подходов к мониторингу и регулированию.
- В сценарии AGI риски и выгоды становятся нелинейными и трудно оцениваемыми, что делает необходимым более раннее и системное регулирование.
Когда пригодится
Материал полезен для разработчиков, экономистов и руководителей, работающих над интеграцией ИИ в проекты, где важны экологические и финансовые последствия — например, при проектировании ИИ-систем для энергетики, логистики или инфраструктуры.
Вопросы для размышления
- Какие конкретные условия (например, типы моделей, масштабы вычислений) могут снизить углеродный след ИИ, не ухудшая его эффективность в климатических задачах?
- В каких сценариях AGI может привести к более серьёзным экологическим рискам, чем текущие ИИ-системы, и как это может повлиять на стратегию регулирования?
- Какова вероятность того, что рост ИИ-инноваций приведёт к увеличению инфляции через рост энергетических затрат, и как это может быть оценено в условиях нестабильной энергетики?
arXiv Quantitative Finance - Risk Management
Hour-Aware Adaptive Risk Management for Autonomous Memecoin Trading on Solana DEXs: Evidence, Theory, and Design Lessons from a 15-Day Deployment
Открыть оригинал ↗ Перевод заголовка: Часовой осознанный адаптивный риск-менеджмент для автономной торговли мемкоинами на DEX-платформах Solana: доказательства, теория и архитектурные уроки из 15-дневной эксплуатации
Автор проводит 15-дневную папер-трейдинг-эксперимент на Solana DEX, чтобы изучить три неисследованных аспекта рыночной структуры: временные паттерны возвратов, эффективность фильтров принятия решений и устойчивость статистики на фоне тяжелого хвоста распределения возвратов. Результаты показывают средний возврат в 0,62% на сделку, общий рост в +117,7%, с отрицательной скошностью и высоким эксцессом, что указывает на высокую волатильность. Анализ по часам выявляет отсутствие статистически значимой разницы в результатах между часами ввода и остальными, а проверка отказов показывает, что 56,25% из 48 событий привели к 50% падению, что значительно превышает средний уровень. Удаление трёх лучших сделок делает общий результат убыточным, что подчёркивает чувствительность к выбору в выборке.
- Какова граница применимости часового анализа в условиях высокой волатильности и нестабильности мемкоинов, если волатильность не является стационарной по времени?
- В каких условиях фильтры принятия решений могут быть не только неэффективными, но и вредными, если они не учитывают динамику волатильности в реальном времени?
- Какова сложность и масштабируемость архитектуры адаптивного риск-менеджмента, если она основана на малом выборке и не имеет внешних проверок?
Когда пригодится
Материал полезен при разработке стратегий торговли на децентрализованных рынках с высокой волатильностью, особенно в условиях отсутствия официальных данных о временных паттернах и рисках. Он особенно ценен для инженеров и исследователей, работающих над автономными системами, где требуется адаптивный риск-менеджмент на основе реальных данных и теоретических моделей.
Вопросы для размышления
- Какова граница применимости часового анализа в условиях высокой волатильности и нестабильности мемкоинов, если волатильность не является стационарной по времени?
- В каких условиях фильтры принятия решений могут быть не только неэффективными, но и вредными, если они не учитывают динамику волатильности в реальном времени?
- Какова сложность и масштабируемость архитектуры адаптивного риск-менеджмента, если она основана на малом выборке и не имеет внешних проверок?
AI
Habr AI
ИИ в DevOps или как мы слепо доверяем сгенерированным манифестам
Открыть оригинал ↗ Перевод заголовка: ИИ в DevOps или как мы слепо доверяем сгенерированным манифестам
ИИ в DevOps часто используется для генерации YAML-манифестов Kubernetes, но такие манифесты могут содержать критические ошибки — от устаревших версий API до отсутствия безопасности. Модели обучены на публичных примерах, которые обычно разрабатываются на локальных ноутбуках, а не в production-средах, поэтому их выводы не отражают реальные условия кластеров. В результате сгенерированные манифесты выглядят корректно, проходят валидацию, но ведут к нестабильности: утечка памяти, сбои health-probes, отсутствие ошибок в логах. Основные риски — устаревшие поля, отсутствие securityContext и использование тега :latest. Для защиты требуется валидация под реальную версию кластера через kubeconform, применение OPA-политик и dry-run через kubectl.
Когда пригодится
Материал полезен при разработке DevOps-процессов, где требуется безопасное и надежное генерирование инфраструктурных конфигураций с использованием ИИ, особенно в средах с высокими требованиями к безопасности и стабильности.
Вопросы для размышления
- Какие конкретные условия (например, версия кластера, политики безопасности, нагрузка) могут привести к тому, что валидация через kubeconform и OPA-политики не поймёт семантические изменения в API, и как это может быть компенсировано?
- В каких сценариях использование dry-run с kubectl может быть недостаточным, и как можно заменить его более надёжной альтернативой при работе с динамически меняющимися кластерами?
Сколько времени нужно непрограммисту, чтобы сделать приложение с сервером, офлайн‑режимом и SEO
Открыть оригинал ↗ Перевод заголовка: Сколько времени нужно непрограммисту, чтобы сделать приложение с сервером, офлайн-режимом и SEO
Непрограммист может создать полноценное приложение с сервером, офлайн-режимом и SEO за 10 календарных дней, используя ИИ-агента вроде Claude Code. Весь процесс занимал около 12 часов прямого взаимодействия с ИИ, при этом непрограммист не писал ни одной строки кода — всё делал через естественные запросы. Приложение работает на всех устройствах, синхронизируется без пароля и поддерживает офлайн-режим, а также интегрировано в поисковые системы.
- ИИ-агент может автоматически вносить изменения в код, выполнять тесты и обнаруживать ошибки, не требуя от пользователя технических навыков.
- Проект строится на основе понятных, неформальных инструкций — пользователь просто описывает желаемую функцию, а ИИ выполняет действия.
- Критически важные решения (например, выбор хостинга, структуры данных, уровня сложности) остаются за человеком, а ИИ лишь предлагает варианты и объясняет ограничения.
- Использование частотных списков (wordfreq и SUBTLEX-US) и открытых словарей (NGSL, NAWL) позволяет построить релевантный контент без привлечения специалистов.
- Офлайн-режим и синхронизация между устройствами реализуются через стандартные технологии, которые ИИ может настроить без глубоких знаний.
Когда пригодится
Материал полезен тем, кто хочет запустить личное приложение без программирования — например, для изучения языка, мониторинга личных задач или создания инструмента для семьи.
Вопросы для размышления
- В каких случаях ИИ-агент может ошибаться в оценке реальных потребностей пользователя, особенно если задача требует глубокого понимания контекста или культурных особенностей?
- Какие риски связаны с тем, что ИИ-агент может предложить решение, которое не подходит по технической надёжности или масштабируемости, особенно при работе с чувствительными данными (например, персональными данными)?
- Какова сложность и время выполнения задачи, если приложение должно поддерживать не только офлайн-режим, но и работу в условиях ограниченного интернета (например, в поезде или на самолёте) с минимальными ресурсами?
FRIDA Decisions: быстро думать на русском
Открыть оригинал ↗ Перевод заголовка: FRIDA Decisions: быстро думать на русском
FRIDA Decisions — это открытая модель быстрого мышления для русского языка, которая без генерации текста и за десятки миллисекунд выбирает из списка вариантов, ставит оценку, отвечает «да» или «нет» и ранжирует кандидаты. Модель работает на основе кросс-энкодера, использует упаковку запросов и кеш состояния, что позволяет сократить вычислительные затраты и время ответа, особенно при большом количестве вариантов или длинных текстах. Она достигает качества, сопоставимого с коммерческими API и крупными LLM, при этом обходится почти в 20 раз дешевле и не требует выхода данных наружу.
- Модель решает задачи без генерации текста: выбор интента, оценка срочности, проверка на спам, ранжирование — всё в одном проходе, без промптов и JSON-парсинга.
- Скорость достигает 28–34 мс на RTX 5060 Ti, что в 10–20 раз быстрее, чем аналогичные API, и позволяет запускать в реальном времени.
- Упаковка запроса и кеш состояния позволяют сократить токены на 6 раз при трёх вопросах и снизить время на разбор каталога из 243 интентов с 4,65 с до 0,44 с.
- Модель работает на CPU (ONNX int8), на Apple Silicon (MLX) и в vLLM-сервере, что делает её доступной для разных сред и платформ.
- Качество на бенчмарке razvilka достигает 0,893 — сопоставимо с TypeSafe Jev и Qwen3.5-35B, при этом уступает в ранжировании, но превосходит в выборе из списка.
Когда пригодится
Материал полезен там, где требуется быстрая, не генерирующая и локальная модель для решений, не требующих текстового ответа: маршрутизация запросов, модерация, разметка данных, реранкинг в RAG. Особенно ценен при работе с длинными текстами и сотнями вариантов, где скорость и цена API критичны.
Вопросы для размышления
- В каких сценариях сильнее проявляется выигрыш от упаковки запроса — при выборе из большого списка или при повторном анализе одного документа, и как это влияет на производительность в условиях высокой нагрузки?
- Какой компромисс между качеством и скоростью может быть при использовании int8-ONNX на CPU, если вводные данные длинные и требуют точности в оценке срочности?
- При каких условиях (размер текста, количество вариантов, тип вопроса) модель может начать терять точность, и как это может повлиять на её применение в production-среде?
MWS AI Vision Bench: что изменилось за год и зачем мы добавляем антифрод
Открыть оригинал ↗ Перевод заголовка: MWS AI Vision Bench: что изменилось за год и зачем мы добавляем антифрод
За год после запуска MWS AI Vision Bench модели значительно улучшились, но выявили несоответствия в разметке и потребовали добавления новой задачи — проверки способности моделей распознавать поддельные и сгенерированные документы. В новом бенчмарке появилась задача Anti-fraud, которая оценивает не только классификацию документа, но и качество объяснений, что делает метрику более приземлённой и практичной для реальных сценариев.
- Задача Anti-fraud включает три класса: исходные документы, ручные правки в графических редакторах и полностью синтетические документы, созданные генеративными моделями.
- Метрика оценивает не только правильность классификации, но и объяснение — для вручную отредактированных документов — с учётом конкретных изменённых реквизитов.
- Формула оценки включает корректировку на случайный уровень (вычитание 1/3) и взвешивает классификацию (75%) и объяснение (50%), что делает метрику более устойчивой к смещениям.
- В отличие от других метрик, Anti-fraud требует сбора confusion matrix и не может быть рассчитан как среднее по отдельным примерам — это техническая особенность, обеспечивающая надёжность.
- Модели, как показывает лидерборд, демонстрируют разные поведения: Claude Opus 5.5 лидирует по Anti-fraud, в то время как GPT-6.1 Sol, хотя и первенец по Overall, занимает лишь третье место.
Когда пригодится
Материал полезен при выборе универсальной мультимодальной модели для обработки документов, где важна способность распознавать подделки и объяснять свои выводы — например, в системах проверки паспортов, СНИЛС или водительских удостоверений.
Вопросы для размышления
- В чём заключается компромисс между объяснением и точностью в метрике Anti-fraud, и как это влияет на выбор модели в условиях ограниченного бюджета?
- Почему для полностью синтетических документов объяснение не оценивается, и как это может повлиять на оценку реальных рисков подделки в производственной среде?
- Какова вероятность того, что модель, хорошо справляющаяся с Anti-fraud, будет плохо справляться с другими задачами, например, с grounding или восстановлением вектора редактирования?
Как использование нейросетей изменило игровую индустрию и homebrew-cцену
Открыть оригинал ↗ Перевод заголовка: Как использование нейросетей изменило игровую индустрию и homebrew-сцену
Использование нейросетей кардинально изменило как процесс разработки игр, так и сцену homebrew-разработок, особенно в сфере взлома консолей и портирования старых игр. Вайбкодинг, поддерживаемый крупными LLM, таких как Claude 3.5 Sonnet и GPT-4o, позволил новичкам в кратчайшие сроки находить уязвимости в консолях, автоматизировать декомпиляцию и создавать рабочие эмуляторы. Это привело к массовому росту homebrew-проектов, где даже без глубоких технических знаний можно создавать полноценные порты и мэшапы игр, вплоть до сращивания движков разных игр в одну сущность.
- ИИ, в частности LLM и вайбкодеры, значительно сократил порог входа в взлом консолей — теперь даже новички могут в течение часов находить уязвимости, ранее требовавшие десятилетий работы и глубоких знаний в криптографии.
- Современные LLM позволяют автоматизировать декомпиляцию ROM-файлов, заменяя прямые обращения к консольным чипам на современные библиотеки (например, Vulkan, SDL2), что делает порты старых игр на ПК практически мгновенными и высокопроизводительными.
- Возникли массовые «мэшапы» — сращивание движков разных игр (например, Mario 64 в Elden Ring), где ИИ генерирует адаптеры и синхронизирует физику, анимации и логику, превращая мемы в реальные, играбельные проекты.
- Вопросы этики острее всего в homebrew-сцене: использование коммерческих ИИ-инструментов для взлома консолей вызывает споры о морали и правах производителей.
- Растёт риск «зловещей долины» — массовое использование ИИ приводит к стандартизации арта, музыки и диалогов, что угрожает авторскому стилю и художественной разнообразности.
Когда пригодится
Материал полезен для разработчиков, интересующихся индустрией игр, особенно тех, кто хочет понять, как ИИ меняет доступность и скорость создания игр, взлома и портов, а также для тех, кто анализирует этические и правовые последствия внедрения ИИ в геймдев.
Вопросы для размышления
- В каких условиях использование LLM для автоматического поиска уязвимостей в консолях может быть безопасным с точки зрения кибербезопасности и этики, и какова граница между «инновацией» и «нарушением»?
- Какова сложность и масштабность вайбкодинга при портировании игр с разных консолей, и в каких случаях такой подход может привести к потере качества или нестабильности в конечной игре?
- В каких сценариях использование ИИ для создания мэшапов игр может быть признано не просто «мемом», а действительно полезным инструментом для развития игровых движков и механик?
[Перевод] Как мы создали и внедрили AI‑разработчика: опыт EXANTE
Открыть оригинал ↗ Перевод заголовка: Как мы создали и внедрили AI-разработчика: опыт EXANTE
EXANTE разработал и внедрил систему Codey — автономного AI-агента, который самостоятельно проходит весь цикл разработки от постановки задачи в Jira до выпуска фичи в production. Система работает на основе оркестрации AI-агентов с разными ролями (Researcher, Developer, QA и др.), используя разные модели в зависимости от задачи, и обеспечивает контроль качества через автоматизированные проверки и ревью. Внедрение прошло поэтапно: сначала на рутинные задачи, затем — в общий бэклог, с постепенным укреплением доверия команды к AI.
- Codey использует мультиагентную архитектуру, где каждый агент выполняет определённую роль (исследование, разработка, проверка), с разными моделями под каждую задачу.
- Система настраивается под проект: для каждого вида кода и стека есть профиль с правилами, агенты адаптируются через накопленные паттерны и проверки.
- Качество изменений контролируется через CI-проверки (тесты, линтеры, безопасность), и задачи возвращаются на доработку при несоответствиях.
- Ошибки анализируются в Learning loop, где формируются гипотезы по улучшению, и изменения проходят бенчмаркирование перед внедрением.
- Внедрение идёт постепенно: сначала на простые задачи, затем — на весь бэклог, с учётом обратной связи и контроля рисков.
Когда пригодится
Материал полезен для команд, которые уже имеют структурированные процессы разработки и хотят внедрить AI-агентов не как «магический инструмент», а как часть рутинного цикла, с контролем качества и прозрачностью для разработчиков.
Вопросы для размышления
- В каких условиях (по структуре проекта, сложности задач, опыту команды) AI-агент может безопасно и эффективно выполнять 70% задач без ручного вмешательства, не нарушая качество и ревью?
- Какие технические и организационные компромиссы возникают при переходе от ручного отбора задач к автоматическому бэклогу, и как это влияет на доверие разработчиков к системе?
- При каких условиях использование более простой модели вместо мощной может привести к лучшему решению, и как это можно измерить без вмешательства в ручной ревью?
[Перевод] Где сломался AI-агент? Как отлаживать многоэтапные воркфлоу по шагам
Открыть оригинал ↗ Перевод заголовка: Где сломался AI-агент? Как отлаживать многоэтапные воркфлоу по шагам
При тестировании многоэтапных воркфлоу AI-агентов сложно определить, на каком этапе возникает сбой, потому что итоговый ответ может быть правдоподобным, несмотря на ошибки в промежуточных действиях. Полные запуски не дают точной картины, так как они расходуют ресурсы, нестабильны и не позволяют выявить конкретную причину. Решением стало поэтапное тестирование с использованием контрольных проверок (gate), которые оценивают фактические вызовы инструментов, а не необработанный журнал выполнения.
- Тестируйте воркфлоу накопительно: запускайте этапы по порядку, останавливаясь перед каждым следующим, чтобы изолировать сбой на конкретном уровне.
- Для каждого этапа определяйте явную контрольную проверку, которая проверяет реальное поведение агента, а не субъективность его ответа.
- Повторяйте запуски до тех пор, пока сбой не станет неожиданным — это позволяет избежать ложной уверенности в стабильности.
- Ограничивайте объём тестовых запусков, отключая последующие этапы до проверки более ранних.
- Оценивайте только фактически выполненные вызовы инструментов и их аргументы — это исключает ложные срабатывания из-за шума в журнале выполнения.
Когда пригодится
Материал полезен при разработке и отладке воркфлоу AI-агентов, где требуется надёжная, воспроизводимая и экономичная проверка поведения на каждом этапе, особенно в критически важных системах, где ошибки могут повлиять на принятие решений инженерами.
Вопросы для размышления
- Как изменится порог количества успешных прогонов для этапа, если он вводит в заблуждение дежурного инженера, например, путём неправильной интерпретации корреляции как причинно-следственной связи?
- В каких случаях контрольная проверка на основе вызовов инструментов может всё же пропустить ошибку, связанную с логикой агента, а не с его поведением?
- Какова сложность по времени и ресурсам при тестировании воркфлоу из 5 этапов с использованием накопительного подхода по сравнению с полным запуском?
Лабораторная работа № 4
Открыть оригинал ↗ Перевод заголовка: Лабораторная работа № 4
Автор проводит эксперимент по интеграции AI-агента в разработку корпоративного приложения, где вместо традиционных Markdown-файлов документации используется структурированная модель проекта в ERP-системе. Цель — создать управляемый процесс, при котором код и документация формируются одновременно, а не после завершения разработки. Вместо хаотичного накопления знаний в чатах, агент получает контекст из базы данных, что обеспечивает согласованность, трассируемость и возможность проверки изменений.
- Вместо Markdown-файлов агент получает структурированный контекст из ERP-системы, где объекты, реквизиты и требования хранятся в реляционной модели, что делает документацию более точной и проверяемой.
- Каждая функция проектируется как пользовательское действие с четким названием и связями с объектами, требованиями и инструкциями, что позволяет AI генерировать реализацию на основе предварительно согласованных правил.
- Агент не может выполнять задачи без разрешения — он создает «дорожные карты» и «заметки» в ERP-системе, что формирует процессный контроль и предотвращает непреднамеренные изменения.
- Реализация функции сопровождается визуальной инструкцией и включает в себя не только код, но и описание шагов, что делает документацию полезной для будущего сопровождения.
- Права доступа и реквизиты фиксируются в модели проекта, а не в коде, что обеспечивает безопасность и позволяет избежать дублирования логики и нарушений DRY.
Когда пригодится
Материал полезен при разработке сложных корпоративных приложений, где требуется долгосрочная поддержка, согласованность между участниками и трассируемость изменений. Особенно актуален для команд, работающих над несколькими проектами одновременно, и где документация должна быть не просто «выводом», а частью архитектуры.
Вопросы для размышления
- Какова сложность и границы применимости такого подхода при масштабировании до десятков агентов, если каждый из них работает с одной и той же моделью, но в разных сессиях и с разными задачами?
- В каких случаях введение меток DevInfo может быть оправдано, а в каких — это просто шум в коде, особенно при активном рефакторинге и частой переработке функций?
- Какой компромисс между гибкостью агента и строгой структурой модели проявляется при попытке внедрить новые реквизиты без предварительного согласования с командой?
InfoQ Architecture
Presentation: Multi-Agent Patterns from Spotify’s AI Powered Advertising Platform
Открыть оригинал ↗ Перевод заголовка: Многоагентные паттерны из платформы AI-рекламы Spotify
Спotify Ads AI — это масштабируемая платформа для создания рекламы на основе ИИ, где каждый агент отвечает за конкретную функцию: например, генерация сценариев, проверка соответствия политикам или рекомендации аудитории. Архитектура строится на принципах разделения ответственности: каждый агент — это отдельный пакет с чёткой собственностью, зависимостями и метриками, что обеспечивает прозрачность и контроль. Платформа использует Google ADK Java для оркестрации, а также встроенные механизмы отслеживания и оценки, позволяя избежать монолитных агентов и управлять затратами. Ключевые паттерны включают строгую границу между агентами и детерминированным кодом, стандартизацию инструментов через схемы, и три уровня оценки: траектория инструментов, детерминированные проверки и LLM-оценка качества.
Когда пригодится
Материал полезен для команд, разрабатывающих масштабные ИИ-системы в рекламе или других областях с высокой сложностью задач, где требуется управление контентом, аудиторией и стоимостью. Особенно актуален при построении агентных систем, где важно избежать «чёрного ящика» и обеспечить прозрачность поведения моделей, а также при необходимости внедрения оценки в реальных условиях.
Вопросы для размышления
- Какие конкретные риски могут возникнуть при использовании детерминированных гейтов вместо полной агентной автономии, и как это может повлиять на гибкость системы в динамичных сценариях?
- В каких условиях оценка через live evaluation становится неэффективной, и как можно сбалансировать затраты на оценку с необходимостью обнаружения аномалий в реальном времени?
- Какова сложность реализации границ между агентами при наличии пересекающихся сценариев (например, когда аудитория и тон агента зависят от одного и того же входного контекста)?
Cloudflare Open Sources Decision Models for AI Agents
Открыть оригинал ↗ Перевод заголовка: Cloudflare открыл для публики модели принятия решений для агентов ИИ
Cloudflare представил Clef — набор моделей ИИ, предназначенных для выбора между заранее определёнными вариантами, а не генерации текста. Модели принимают входные данные (текст, JSON, изображения, видео) и возвращают вероятности каждого допустимого варианта решения в одном прямом проходе, без необходимости парсить выходные данные. Такой подход позволяет агентам быстро и надёжно принимать решения, например, маршрутизировать запросы или передавать их на проверку человеку.
- Clef — это многомодальный модель с визуальным кодировщиком, способный обрабатывать изображения, в отличие от Jev, который работает только с текстом.
- У модели есть контекст до 64 тысяч токенов, что позволяет учитывать больше входных данных по сравнению с Jev (32к).
- Модель работает на инфраструктуре Cloudflare в «ближней точке» — это обеспечивает низкую задержку и возможность встраивания в критически быстрые потоки принятия решений.
- Clef-Flash — упрощённая версия (9B параметров) с задержкой 38,8 мс, что делает её подходящей для высокоскоростных сценариев.
- Cloudflare предлагает сервис по настройке модели под конкретные задачи, включая сегментацию поддержки и классификацию ботов, с возможностью использования собственных данных.
Когда пригодится
Материал полезен, когда нужно быстро и с низкой задержкой принимать решения на основе структурированных данных — например, в автоматизации обработки запросов, маршрутизации, или в системах с высокими требованиями к скорости реакции.
Вопросы для размышления
- Какой компромисс между точностью и задержкой может возникнуть при использовании Clef-Flash в критически быстрых сценариях, если входные данные включают сложные визуальные элементы?
- В каких условиях вероятность ошибки может стать критичной, если модель уверенно выбирает вариант, при котором ложноположительный результат приводит к значительным потерям?
- Какова сложность и масштабируемость процесса финальной настройки Clef на основе пользовательских данных, если данные несбалансированы или содержат редкие случаи?
Java / Spring
Habr Java
Linux из Java без JNI: от FFM и /dev/kvm до интерактивной консоли
Открыть оригинал ↗ Перевод заголовка: Linux из Java без JNI: от FFM и /dev/kvm до интерактивной консоли
Автор реализовал минимальную виртуальную машину на Java, запускающую настоящий Linux kernel через Foreign Function & Memory API (FFM), без использования JNI. Проект PanamaKVM демонстрирует, как через FFM напрямую вызывать системные функции KVM и реализовать загрузку Linux с отображением интерактивной консоли. Важно, что система не является полноценным виртуализатором, а представляет собой прозрачную, типизированную модель взаимодействия между Java-кодом и низкоуровневыми системными вызовами.
- FFM позволяет избежать написания C-обёрток и JNI-библиотек, оставляя native-вызовы и управление памятью в Java-коде, что упрощает разработку и поддержку.
- Проект сталкивается с критическими ошибками на уровне ABI — например, при вызове
KVM_GET_API_VERSIONвозвращаетсяEINVAL, потому что третий аргумент (в видеvoid*) не передаётся явно, что показывает недостаточность описания в FFM. - Загрузка Linux требует точного соблюдения x86-64 boot protocol: подготовки загрузочных параметров, E820, GDT, placement initramfs и передачи
boot_paramsчерез RSI. - Интерактивность достигается через UART, но требует глубокой настройки прерываний, TTY, echo и обработки сигналов, включая
Ctrl+C, что выявляет сложность передачи ввода-вывода между host и guest. - Проект не предназначен для production — отсутствуют сетевые и блочные устройства, SMP, безопасность и производительность не подтверждены, но он идеален для экспериментов и понимания взаимодействия JVM и системного кода.
Когда пригодится
Материал полезен при разработке экспериментальных проектов, где важно понять детали взаимодействия JVM с низкоуровневыми системными вызовами, а не просто использовать готовые виртуализаторы. Особенно ценен для студентов и разработчиков, изучающих системное программирование и архитектуру виртуализации.
Вопросы для размышления
- В каких случаях FFM может быть предпочтительнее JNI, несмотря на то, что он не решает проблемы с ABI-ошибками и не предоставляет гарантий корректности вызова?
- Какие минимальные условия (например, версия ядра, права доступа, настройки TTY) должны быть соблюдены для корректной работы
Ctrl+Cв виртуальной машине, и как это может быть проверено без использования отладчика?- В каких сценариях использование PanamaKVM может быть оправдано, если в проекте нет необходимости в полноценной виртуализации, а лишь в проверке гипотез о поведении Linux-загрузки?
HowToDoInJava
@GetMapping and @PostMapping in Spring Boot (Examples)
Открыть оригинал ↗ Перевод заголовка: @GetMapping и @PostMapping в Spring Boot (примеры)
В Spring Boot аннотации @GetMapping и @PostMapping упрощают настройку обработчиков HTTP-запросов: @GetMapping отвечает за чтение данных (например, получение списка или элемента), а @PostMapping — за создание новых ресурсов из тела запроса (например, добавление песни в формате JSON). Обе аннотации являются сокращёнными версиями @RequestMapping с фиксированным методом, что делает код более читаемым и безопасным. В примерах показано, как эти аннотации работают в REST-контроллере, включая обработку параметров, валидации, заголовков и ответов с определёнными статусами. Особое внимание уделено атрибутам, таким как consumes (тип содержимого), produces (тип ответа), params и headers, которые позволяют уточнять условия валидации запроса. Также описаны ограничения: например, @PostMapping не может применяться на уровне класса, и при отсутствии @RequestBody в методе запрос с JSON не будет обработан.
Когда пригодится
Материал полезен при разработке REST-интерфейсов в Spring Boot, где требуется явно отделить методы для чтения и создания данных, а также при необходимости настройки форматов ответов, валидации входных данных и поддержки версий API.
Вопросы для размышления
- В каких случаях использование @PostMapping без @RequestBody приведёт к неправильной обработке JSON-запроса, и как это может повлиять на безопасность приложения?
- Какой компромисс между гибкостью и читаемостью возникает при использовании множества путей в @GetMapping({"/top", "/popular"}) для одного метода, и как это влияет на масштабируемость приложения?
- При каких условиях @PostMapping может вернуть 415 Unsupported Media Type, даже если запрос содержит JSON, и как это может быть связано с настройками сервера или клиентом?
Swagger API Documentation Example in Spring Boot 4
Открыть оригинал ↗ Перевод заголовка: Пример документации API Swagger в Spring Boot 4
Swagger-документация — это веб-страница (Swagger UI), которая отображает все эндпоинты REST-API и позволяет отправлять тестовые запросы через браузер. Она строится на основе OpenAPI-документа (JSON или YAML), который описывает пути, параметры, тела запросов и ответы. В приложении на Spring Boot библиотека springdoc-openapi автоматически генерирует этот документ из кода контроллеров без необходимости вручную писать конфигурацию или аннотации.
Ключевые практические тезисы:
— Для включения документации добавляется зависимость springdoc-openapi-starter-webmvc-ui, после чего доступны два основных URL: /v3/api-docs (OpenAPI-документ) и /swagger-ui.html (интерфейс Swagger UI).
— Библиотека автоматически обнаруживает контроллеры и их маршруты, но для полноты описания требуется использовать аннотации: @Tag, @Operation, @ApiResponse, @Parameter, @Schema и Bean Validation.
— В production документацию следует отключать через свойства springdoc.api-docs.enabled=false и springdoc.swagger-ui.enabled=false, чтобы избежать рисков, связанных с доступом к чувствительным данным.
— При миграции с Springfox на springdoc-openapi необходимо заменить аннотации (например, @ApiOperation → @Operation) и перенести настройки в OpenAPI-конфигурацию, а также учесть изменение URL-шаблонов (от /v2/api-docs к /v3/api-docs).
Когда пригодится
Материал полезен при разработке REST-сервисов на Spring Boot, где требуется быстро генерировать и поддерживать актуальную документацию API для команд разработки фронтенда, интеграции с внешними системами или автоматического генерирования клиентских кодов.
Вопросы для размышления
- В каких случаях использование
@Hiddenв контроллере может быть неподходящим, и как правильно заменить его для обеспечения безопасности в production?- Как влияет на производительность и масштабируемость включение Swagger UI в production-среде, если не отключать его через профили?
- При каких условиях
@ApiResponseс@Contentможет привести к ошибке в генерации OpenAPI-документа, и как это может повлиять на валидацию ответов в реальных запросах?
Test Spring Boot Async REST Controller with MockMvc
Открыть оригинал ↗ Перевод заголовка: Тестирование асинхронного REST-контроллера в Spring Boot с MockMvc
Для тестирования асинхронного контроллера с помощью MockMvc необходимо выполнить запрос, проверить, что асинхронная обработка запущена, и затем вызвать метод asyncDispatch(mvcResult), чтобы получить конечный ответ. Первый вызов perform() возвращает сразу после того, как контроллер возвращает CompletableFuture, Callable или DeferredResult, поэтому тело ответа пусто. Второй вызов с asyncDispatch() ожидает завершения асинхронной задачи и завершает запрос. Такой подход необходим, когда результат генерируется на другом потоке — например, при генерации отчёта или вызове медленного внешнего сервиса.
Практические тезисы:
- Первый вызов perform() проверяет запуск асинхронной обработки, но возвращает пустой ответ — тело пустое, статус 200, поэтому любые проверки тела на этом этапе проваливаются.
- Для получения реального ответа требуется вызов asyncDispatch(mvcResult), который ожидает завершения асинхронной задачи и возвращает финальный ответ с телом.
- Проверки тела и статуса должны идти после asyncDispatch(), иначе тесты ошибаются из-за пустого тела.
- Вместо двух шагов можно использовать MockMvcTester с методом exchange(), который сам ожидает завершения асинхронной задачи и возвращает финальный ответ без дополнительных вызовов.
- Ошибки в асинхронной задаче передаются в обработчики исключений, но статус ошибки виден только после asyncDispatch(), что важно понимать при тестировании.
Когда пригодится
Материал полезен при разработке тестов асинхронных REST-эндпоинтов в Spring Boot, где результат генерируется на фоновом потоке — например, при работе с отчётами, внешними сервисами или задержками в обработке запросов.
Вопросы для размышления
- В каких случаях asyncDispatch() может привести к блокировке теста, если асинхронная задача не завершается в течение таймаута, и как это влияет на надёжность теста в production-среде?
- Какой компромисс между производительностью и точностью в тестах возникает при использовании MockMvcTester по сравнению с двумя вызовами perform() и asyncDispatch()?
- При каких условиях использование собственного ThreadPoolTaskExecutor в WebMvcConfigurer может привести к несовместимости с другими компонентами приложения или тестами?
Jackson Ignore Null Fields: NON_NULL, NON_EMPTY and More
Открыть оригинал ↗ Перевод заголовка: Игнорирование полей с null в Jackson: NON_NULL, NON_EMPTY и другие опции
В Jackson можно управлять сериализацией полей, игнорируя значения null, пустые или отсутствующие. Для этого используется аннотация @JsonInclude с параметрами NON_NULL, NON_ABSENT, NON_EMPTY или NON_DEFAULT, каждый из которых исключает разные категории значений: от простых null до пустых коллекций, строк и опциональных значений. Такой подход уменьшает объём JSON-ответов, делая их чище и более эффективными, особенно при работе с API, где опциональные поля должны не отображаться как null. Важно понимать, что NON_NULL не удаляет пустые Optional, NON_EMPTY исключает пустые строки и коллекции, а NON_DEFAULT удаляет по умолчанию значения примитивов (например, 0 для int). Поведение зависит от уровня аннотации — класса, поля или глобального настройки. Важно также учитывать, что NON_DEFAULT не подходит для числовых полей, где 0 может означать нормальное значение.
Когда пригодится
Материал полезен при разработке REST-API, где требуется минимизировать объём ответов, избегая отображения пустых или по умолчанию значений, особенно в случаях с большими объёмами опциональных полей.
Вопросы для размышления
- В каких сценариях безопасно использовать
NON_DEFAULTдля числовых полей, и какие компромиссы возникают при его применении в условиях, где 0 означает отсутствие значения?- Какой из вариантов (
NON_EMPTYилиNON_ABSENT) лучше подходит для сериализации объектов с опциональными полями, если в приложении допускается отсутствие данных, но не пустые строки или коллекции?- Какой из подходов — глобальная настройка или аннотация на уровне поля — более предпочтителен в микросервисной архитектуре, где разные сервисы используют разные правила сериализации?
Decimal to Hexadecimal Conversion in Java With Examples
Открыть оригинал ↗ Перевод заголовка: Конвертация из десятичной в шестнадцатеричную систему счисления на языке Java с примерами
Для преобразования десятичного числа в шестнадцатеричное используется деление на 16 с последующим чтением остатков в обратном порядке — например, 269 становится 10D. В Java методы Integer.toHexString() и String.format("%X") позволяют получить шестнадцатеричную строку, а Integer.parseInt("hex", 16) — вернуть десятичное значение. Важные сценарии использования включают цветовые коды, хэш-значения, адреса в памяти и байтовые массивы. В статье рассматриваются различные подходы: встроенные методы, форматирование строк, класс HexFormat (с Java 17) и реализация алгоритма вручную.
Integer.toHexString()иInteger.toString(num, 16)преобразуют десятичное число в шестнадцатеричную строку, возвращая строчные символы по умолчанию.String.format("%X")и%04Xпозволяют получить верхние буквы и заполнение нулями, что полезно для форматирования цветов или логов.HexFormat.of().toHexDigits()обеспечивает фиксированную длину вывода (например, 8 символов для int), что важно при работе с протоколами или байтовыми данными.- Для отрицательных чисел
Integer.toHexString()возвращает 32-битное неотрицательное значение (например,fffffef3), аInteger.toString(num, 16)— с минусом (-10d). - При парсинге ввода из пользовательского интерфейса рекомендуется использовать
OptionalIntдля обработки ошибок, чтобы избежать аварийного завершения при некорректных данных.
Когда пригодится
Материал полезен при работе с цветами в UI, хэш-кодами, байтовыми массивами, логами или протоколами, где требуется форматирование чисел в шестнадцатеричной системе. Особенно актуален для валидации ввода, когда возможны ошибки в формате или пропуски, и при необходимости сохранять фиксированную длину шестнадцатеричного представления.
Вопросы для размышления
- В каких случаях использование
Integer.toHexString()вместоInteger.toString(num, 16)может привести к ошибке при обработке отрицательных чисел, и как это влияет на безопасность парсинга в реальных приложениях?- Какой из вариантов —
HexFormat.toHexDigits()илиString.format("%08X")— предпочтительнее для форматирования байтового массива в логах, и почему?- При каких условиях метод
Math.addExact()вручную реализованной функции может привести к переполнению, и как это может повлиять на надёжность при обработке больших шестнадцатеричных строк?
Java Stream Sort With Null Values: nullsFirst and nullsLast
Открыть оригинал ↗ Перевод заголовка: Сортировка Java Stream с значениями null: nullsFirst и nullsLast
При сортировке потока или списка с null-значениями необходимо использовать обертку Comparator.nullsFirst() или Comparator.nullsLast(), чтобы избежать NullPointerException и правильно разместить null-элементы — в начале или в конце. Без такой обертки сортировка прерывается при первом сравнении с null. Важно понимать, что null-проверка должна происходить на уровне, где null может появиться — либо в элементе списка, либо в поле объекта. Для объектов с полями, где могут быть null, достаточно передать nullsLast() как второй параметр в Comparator.comparing(), а для списков с null-элементами — обернуть весь компаратор. При сортировке в обратном порядке важно использовать nullsLast(Comparator.reverseOrder()), а не применять reversed() к уже обернутому компаратору, так как это меняет позицию null-значений.
- Использование Comparator.nullsFirst() и nullsLast() — обертка вокруг компаратора, которая определяет, где будут располагаться null-значения: в начале (nullsFirst) или в конце (nullsLast).
- При сортировке объектов с полями, где могут быть null, достаточно передать nullsLast() в Comparator.comparing() для поля, а не в сам компаратор объекта.
- Если в списке есть как null-элементы, так и null-поля, требуется двойная обертка: внешняя для элементов, внутренняя — для полей.
- При сортировке в обратном порядке используйте nullsLast(Comparator.reverseOrder()), а не reversed() на обернутом компараторе, чтобы null-значения остались в конце.
- Для удаления null-элементов перед сортировкой можно применить filter(Objects::nonNull), если они не несут смысловой информации.
Когда пригодится
Материал полезен при работе с данными из базы, где строки или поля могут быть пустыми, или при сортировке задач, где даты могут отсутствовать — например, в приложениях для управления задачами или отчётов.
Вопросы для размышления
- В каких случаях использование nullsLast(null) вместо сортировки по значению полезно, и как это повлияет на порядок элементов при наличии нескольких null-полей?
- Какой компаратор выбрать, если в списке есть null-элементы и в полях объектов могут быть null-значения, и требуется, чтобы null-элементы шли в начало, а null-поля — в конец?
- При каких условиях применение reversed() к компаратору с nullsLast() приведёт к ошибке или неожиданному поведению в сортировке?
Isomorphic Strings in Java: Algorithm, Code and Examples
Открыть оригинал ↗ Перевод заголовка: Изоморфные строки на Java: алгоритм, код и примеры
Две строки называются изоморфными, если каждый символ первой строки может быть заменён на соответствующий символ второй строки в один-к-одному, без потерь и без повторений. Проверка изоморфности используется в задачах, где важна структура текста, а не его содержимое — например, в криптограммах или в тестах на понимание паттернов. Алгоритм проверяет соответствие по позициям повторяющихся символов, учитывая оба направления: от первой строки к второй и обратно.
- Проверка должна быть двусторонней — каждый символ должен иметь один и тот же партнёр в обоих направлениях.
- Строки должны иметь одинаковую длину, иначе изоморфность невозможна.
- Метод с массивами работает быстро, но поддерживает только ASCII-символы (до 255), и может выдать исключение при использовании символов вне этого диапазона.
- Вариант с HashMap и методом codePoints() безопасен для всех Unicode-символов, включая эмодзи и символы с кодами выше 255, и корректно обрабатывает строки с разными кодовыми точками.
- Проверка на изоморфность не зависит от букв, а определяется их паттерном — группировка по паттерну позволяет эффективно фильтровать слова в криптограммах.
Когда пригодится
Материал полезен при реализации криптографических решений, фильтрации слов по паттерну в приложениях для расшифровки, а также в тех случаях, когда структура текста (последовательность повторов) важнее самих букв. Особенно актуален для задач, где нужно сгруппировать слова по схожей структуре, например, в решении криптограмм.
Вопросы для размышления
- В чём заключается компромисс между скоростью и универсальностью при выборе между массивами и HashMap в алгоритме изоморфности?
- Как изменится поведение алгоритма при наличии в строках символов с кодами выше 255, если не использовать codePoints()?
- При каких условиях паттерн-группировка может привести к неверному результату, и как это может повлиять на надёжность решения в production?
Java Read File to String: Files.readString() and 6 More Ways
Открыть оригинал ↗ Перевод заголовка: Чтение файла в строку на Java: Files.readString() и 6 других способов
Чтение всего содержимого файла в строку в Java можно выполнить с помощью метода Files.readString(path) в Java 11+, который декодирует файл по стандарту UTF-8 и возвращает текст или выбрасывает исключение при ошибке. В более ранних версиях (Java 7–8) аналогичный результат даёт new String(Files.readAllBytes(path), StandardCharsets.UTF_8). Каждый из методов имеет разные поведения по обработке переносов строк и невалидных байт, а также ведёт себя по-разному при отсутствии файла или неправильной кодировке. При работе с большими файлами или при необходимости обработки построчно — лучше использовать потоковые методы, такие как Files.lines() или BufferedReader, чтобы избежать переполнения памяти. Важно учитывать, что методы, работающие с байтами (например, readAllBytes), могут вызывать OutOfMemoryError при размерах файла свыше 2 ГБ, а при неправильной кодировке — выбрасывают MalformedInputException или заменяют невалидные байты на символ U+FFFD.
Когда пригодится
Материал полезен при необходимости быстро и надёжно читать текстовый файл в строку в приложениях на Java, особенно в тестах, шаблонах или конфигурациях. Особенно актуален для Java 11+, где
Files.readString()обеспечивает чистый, безопасный и производительный путь к чтению текста без необходимости управления ресурсами или обработки исключений вручную.
Вопросы для размышления
- В каких случаях компромисс между сохранением переносов строк и памятью делает
Files.readString()неприемлемым, и как это влияет на выбор междуFiles.lines()иBufferedReader?- Какой из методов наиболее безопасен при работе с файлами, содержащими невалидные байты, и почему в случае ошибки
MalformedInputExceptionнельзя просто "игнорировать" в production-коде?- При каких условиях
Files.readString()может привести к неверному содержимому при чтении файлов из Windows (с\r\n), и как это влияет на надёжность парсинга в приложениях, где важны точные строки?
Microsoft for Java Developers
Faster by Design: Performance engineering in the Microsoft JDBC Driver for SQL Server
Открыть оригинал ↗ Перевод заголовка: Быстрее по дизайну: инженерия производительности в JDBC-драйвере Microsoft для SQL Server
В статье описывается процесс оптимизации производительности Microsoft JDBC-драйвера для SQL Server, основанный на глубоком профилировании реальных рабочих нагрузок. Оптимизации проводились без изменения поведения приложений, фокусируясь на устранении избыточных операций в критических путях выполнения — от обработки результатов запросов до аутентификации. В результате были достигнуты значительные улучшения в скорости и эффективности работы драйвера.
- Ускорение обработки результатов запросов за счёт раннего обнаружения NULL-значений и повторного использования декодеров, что снижает объём выделения памяти и количество операций декодирования.
- Улучшение производительности bulk-copy-операций за счёт расширения настройки через параметры подключения и прямого поддержки типов MONEY и временных данных, позволяя сохранять высокую производительность при вставке больших объёмов данных.
- Внедрение более точной передачи метаданных параметров через
defineParameterType()иsetObject()с указанием ожидаемой длины, что позволяет SQL Server лучше оптимизировать план запроса. - Ускорение работы Always Encrypted за счёт кэширования ключей и избежания повторных обращений к поставщику ключей при наличии уже загруженных данных.
- Снижение конкуренции при аутентификации за счёт проверки кэша токенов до синхронизации, что уменьшает задержки в высоконагруженных сценариях.
Когда пригодится
Материал особенно полезен для разработчиков, работающих с высокопроизводительными Java-приложениями, которые обрабатывают большие объёмы данных в SQL Server, включая Spark-интеграции, вставки в больших объёмах и сценарии с высокой нагрузкой на аутентификацию.
Вопросы для размышления
- В каких случаях избыточное кэширование ключей в Always Encrypted может привести к ухудшению производительности, и как это может быть оценено при разработке приложения?
- Какова сложность (в терминах времени и памяти) реализации параметров bulkCopyForBatchInsertAllowEncryptedValueModifications, и как это влияет на масштабируемость при работе с большими партиями данных?
- При каких условиях вставка с MONEY-типами может всё ещё падать с bulk-copy-пути, и как это может быть предотвращено без изменения структуры запросов?
System Design
ClickHouse
Why BigQuery can’t match ClickHouse Cloud for real-time analytics
Открыть оригинал ↗ Перевод заголовка: Почему BigQuery не может конкурировать с ClickHouse Cloud в области реального времени аналитики
В статье проводится сравнительный анализ эффективности систем в реальном времени: ClickHouse Cloud и BigQuery. При обработке потока данных в размере 113,2 миллиарда цитат, ClickHouse Cloud демонстрирует в 438 и 512 раз более высокую эффективность по стоимости на единицу производительности, что касается как подготовки данных, так и времени выполнения запросов. Основное преимущество ClickHouse заключается в интеграции подготовки данных (ориентированных на сортировку и предварительные агрегации) прямо в процесс вставки, что позволяет избежать задержек и обеспечивать актуальность данных в момент запроса. В то время как BigQuery делает данные доступными для запросов, пока фоновые процессы сортировки и обновления материализованных представлений продолжаются, запросы в BigQuery включают несуммаризированные данные, что увеличивает время выполнения.
- ClickHouse Cloud обеспечивает синхронную подготовку данных: сортировка и предварительные агрегации происходят в процессе вставки, что позволяет избежать задержек и поддерживать актуальность данных в реальном времени.
- В BigQuery данные становятся доступными для запросов до завершения фоновых операций по сортировке и обновлению, что приводит к необходимости включать необработанные строки в ответы, увеличивая время выполнения запросов.
- ClickHouse значительно снижает как стоимость подготовки данных (в 8–9 раз дешевле), так и стоимость выполнения запросов (в 94–491 раз дешевле), при этом время ответа на запросы в миллисекунды, в то время как у BigQuery — в секунды.
- В реальных сценариях (например, METRO Markets и Fountain) переход на ClickHouse привёл к сокращению времени обновления данных с нескольких часов до минут и уменьшению затрат на 66%.
- Важно, что ClickHouse не требует отдельных фоновых задач для обновления, в то время как BigQuery использует асинхронные процессы, которые не гарантируют актуальность данных в течение минуты.
Когда пригодится
Материал полезен при проектировании систем реального времени аналитики, где критична скорость ответа на запросы и предсказуемость затрат, особенно при работе с потоковыми данными, такими как финансовые котировки или логи пользовательских действий.
Вопросы для размышления
- Какова сложность реализации синхронной подготовки данных (сортировка и агрегация в процессе вставки) в ClickHouse, и как это может повлиять на масштабируемость при работе с потоками более чем в 100 миллиардов строк в секунду?
- В каких сценариях использование BigQuery с автоматическим обновлением MV может быть оправдано, несмотря на значительные задержки в ответах на запросы?
- Если бы ClickHouse не поддерживал сортировку в процессе вставки, как бы изменились бы результаты по времени выполнения и стоимости запросов, и как это повлияло бы на границы применимости архитектуры?
How we migrated Clera’s 500 GB production database to ClickHouse Managed Postgres overnight
Открыть оригинал ↗ Перевод заголовка: Как мы перенесли 500 ГБ производственной базы данных Clera в ClickHouse Managed Postgres за одну ночь
Команда Clera, работающей с более чем 200 000 кандидатами, перенесла свою базу данных из устаревшего поставщика в ClickHouse Managed Postgres, решив проблему медленных запросов и высокого потребления ресурсов. В ходе миграции, проводившейся в режиме «без перерывов» при сохранении производственного трафика, удалось сократить использование CPU с 100% до 10–20%, а производительность выросла благодаря использованию локальных NVMe-дисков, что обеспечило быстроту отклика при точечных запросах.
- Использование локального NVMe-хранилища в ClickHouse Managed Postgres обеспечивает существенное превосходство по IOPS по сравнению с сетевыми хранилищами, что критично для точечных запросов (point lookups), которые ранее блокировались фоновыми операциями.
- Миграция проводилась параллельно с активным трафиком: 500+ таблиц перенесены из Европы в США за одну ночь, при этом система оставалась в рабочем состоянии без перезагрузок.
- Оптимизация не требовала настройки: производительность была настроена «из коробки» под реальные рабочие нагрузки, что упростило внедрение и снизило риски.
- Важно, что миграция была не на всю базу данных, а только на операционную часть — в будущем возможна интеграция с аналитическими таблицами через синхронизацию с ClickHouse.
- Процесс включал подготовку (настройка WAL, публикаций, проверка ключей), запуск двух параллельных потоков через ClickPipes, восстановление триггеров и индексов, а также контроль за целостностью данных.
Когда пригодится
Материал полезен для команд, работающих с высокой нагрузкой на базу данных, где критичны точечные запросы и стабильность при активном трафике, особенно при необходимости миграции без остановки сервиса.
Вопросы для размышления
- В каких сценариях использование локального NVMe-хранилища может быть неэффективным, несмотря на высокую производительность в тестах?
- Какие риски связаны с восстановлением триггеров и индексов при миграции в режиме «без перерывов», если система уже подвергается частым схемным изменениям?
- При каких условиях (по объёму данных, типу запросов, нагрузке) ClickHouse Managed Postgres может потерять преимущество перед другими поставщиками, даже при наличии NVMe-хранилища?
Introducing JWT authentication in ClickHouse Cloud
Открыть оригинал ↗ Перевод заголовка: Введение аутентификации JWT в ClickHouse Cloud
ClickHouse Cloud теперь поддерживает аутентификацию через JWT-токены, позволяя вместо хранения долговременных паролей использовать кратковременные токены от существующих провайдеров OpenID Connect (например, Okta, Microsoft Entra). Вместо создания и управления постоянными пользователями в базе, доступ контролируется через токены, которые автоматически уничтожаются при истечении срока действия, что снижает риски утечек и упрощает управление доступом. В ClickHouse создаётся временный пользователь на основе токена, который получает роли и разрешения из токена, а затем удаляется после истечения срока действия — пользователь не сохраняется в базе данных. Роли и политики (настройки, квоты, политики строк) привязываются к уникальному UUID, вычисленному из идентификаторов провайдера, что обеспечивает сохранение конфигурации при каждом входе. Поддерживается интеграция с любыми провайдерами OpenID Connect, и токены могут быть получены как от внешнего провайдера, так и от встроенной системы ClickHouse Cloud.
Когда пригодится
Материал полезен для команд, работающих с интеграцией баз данных и идентификационными системами, где требуется минимизировать хранение паролей, обеспечить короткий срок действия доступа и автоматизировать процесс настройки прав пользователей без ручного вмешательства.
Вопросы для размышления
- Какой компромисс между гибкостью ролей и надёжностью контроля доступа возникает, если политики (например, квоты) привязаны к UUID, а не к имени пользователя, и как это влияет на возможность отслеживания изменений в правах?
- В каких сценариях может привести к сбоям использование JWT-токенов с кратким сроком действия в условиях высокой частоты запросов (например, в CI/CD-пайплайнах), и как это может повлиять на производительность или отказы в системе?
- Какой вклад в безопасность вносит поддержка EC-ключей (ES256, ES384, ES512) в сравнении с RSA, и как это может повлиять на масштабируемость и производительность в распределённой архитектуре ClickHouse Cloud?
DEV System Design
Designing a URL Shortener: Architecture, Base62, Redis Caching & Scaling
Открыть оригинал ↗ Перевод заголовка: Проектирование URL-сокращения: архитектура, Base62, кэширование в Redis и масштабирование
URL-сокращение кажется простой задачей: преобразовать длинную ссылку в короткую, сохранить отображение и перенаправить. Однако в реальном мире система сталкивается с чрезвычайно высокой нагрузкой на чтение, где один и тот же код может быть запрошен миллионами раз. Ключевыми проблемами становятся уникальность кодов, кэширование, отказоустойчивость и изоляция сбоев. Оптимизация начинается не с расширения базы данных, а с устранения избыточных запросов к базе — например, с внедрением кэша в Redis. Для генерации уникальных кодов предпочтительна случайная последовательность в Base62 с ограничением повторных попыток при коллизии. Важно обеспечить корректное завершение ссылок: кэш должен учитывать истечение срока действия, а не просто использовать фиксированный TTL. При вирусных переходах может возникнуть "горячий ключ" — одна ссылка приводит к перегрузке одного узла кэша, что требует локального кэширования в приложениях или распределения нагрузки. Также критически важно изолировать процесс аналитики от основного потока перенаправлений, чтобы не допустить замедления ответа.
Когда пригодится
Материал полезен при проектировании систем с высокой нагрузкой на чтение, где один и тот же идентификатор может быть запрошен миллионами раз — например, в сервисах с социальными медиа, вирусными ссылками или аналитикой кликов.
Вопросы для размышления
- Как изменится поведение системы при включении TTL-настройки в кэш, если истечение срока действия ссылки настроено на 10 минут, но кэш использует 24-часовой TTL?
- При каких условиях локальное кэширование в приложении может привести к потере данных или к некорректной обработке запросов при вирусных переходах?
- Какова сложность и границы применимости стратегии "сброса" событий аналитики при отказе брокера, если продукт требует точных, без потерь, счётчиков кликов?
System Design for Beginners: Vertical Scaling vs Horizontal Scaling
Открыть оригинал ↗ Перевод заголовка: Системное проектирование для новичков: вертикальное и горизонтальное масштабирование
Системное проектирование — это не просто рисование диаграмм, а процесс разработки архитектуры, способной масштабироваться под рост пользователей, нагрузки и данных. При росте числа пользователей и запросов система может перестать работать из-за нехватки ресурсов, что требует масштабирования. Основные подходы — вертикальное (усиление одного сервера) и горизонтальное (добавление новых серверов). Вертикальное масштабирование простое и быстрое, но имеет физический предел и один сбой — если сервер выйдет из строя, вся система прекратит работать. Горизонтальное масштабирование обеспечивает высокую доступность и масштабируемость, но требует сложных решений для управления состоянием сессий (например, с помощью Redis или распределённых кэшей). Выбор между ними зависит от размера нагрузки, её роста и требований к надёжности.
Когда пригодится
Материал полезен при подготовке к интервью по системному проектированию, особенно когда нужно объяснить выбор между вертикальным и горизонтальным масштабированием в зависимости от реальных условий нагрузки и требований к отказоустойчивости.
Вопросы для размышления
- В каких случаях вертикальное масштабирование может быть более эффективным, чем горизонтальное, несмотря на рост нагрузки?
- Какой из подходов (вертикальный или горизонтальный) лучше подходит для системы с нестабильной нагрузкой, где пиковые запросы могут быть в 10 раз выше среднего, и как это влияет на выбор кэширования?
- Какие риски связаны с использованием статичных сессий в горизонтально масштабируемой системе, и как это может повлиять на производительность при росте числа пользователей?
SSR Isn't Just About SEO
Открыть оригинал ↗ Перевод заголовка: SSR не является просто вопросом SEO
Современный фронтенд-инженер должен понимать, в каких случаях использовать SSR, SSG, ISR или CSR, и почему — не просто из-за SEO, а из-за глубоких архитектурных и производственных последствий. В серии «Bazaar» автор разбирает реальные приложения, чтобы показать, как принимаются решения о системной архитектуре и масштабируемости. В эпизоде 2 подчёркивается, что SSR — это не только решение для индексации поисковыми системами, но и механизм, влияющий на производительность и стабильность приложения через процесс "гидрации" (hydration), который может стать скрытой стоимостью. Разные страницы могут требовать разных стратегий рендеринга, что требует гибкого подхода к выбору между SSR, SSG, ISR и CSR. Эти решения напрямую влияют на реальную производительность и пользовательский опыт.
Когда пригодится
Материал полезен при проектировании фронтенд-архитектуры приложения, где важно понимать не только SEO-аспекты, но и технические риски, связанные с гидрацией, производительностью и масштабируемостью.
Вопросы для размышления
- В каких сценариях гидрация может привести к значительному увеличению времени загрузки, и как это может быть оценено без реальных тестов?
- При каких условиях SSR может быть неэффективным, даже если страница индексируется поисковыми системами?
- Какие компромиссы возникают при использовании ISR вместо SSR для страниц с динамическими данными, и как это влияет на отказоустойчивость?
Latency vs Throughput vs Bandwidth
Открыть оригинал ↗ Перевод заголовка: Задержка, пропускная способность и пропускная способность
Эти три термина часто используются как взаимозаменяемые, но они измеряют три разных аспекта производительности системы. Понимание различий позволяет лучше проектировать архитектуру и анализировать поведение сетей и распределённых систем.
Ключевые практические тезисы:
- Задержка (latency) — время, за которое один запрос достигает получателя, например, время ответа API или выполнения запроса к базе данных. Чем меньше, тем лучше.
- Пропускная способность (throughput) — количество запросов или данных, обрабатываемых системой в единицу времени (например, запросов в секунду). Чем выше, тем лучше, но не обязательно связано с задержкой.
- Пропускная способность канала (bandwidth) — теоретический максимум данных, который может передаваться по сети (например, 1 Гбит/с), и не зависит от реального использования.
Когда пригодится
Материал полезен при проектировании систем, где критичны временные характеристики — например, в реальном времени (игры, чаты), при передаче потоков (видео, аудио) или при разработке API с высокой нагрузкой.
Вопросы для размышления
- Почему увеличение пропускной способности сети не всегда приводит к снижению задержки, и как это влияет на реальную производительность в условиях высокой нагрузки?
- В каких сценариях пропускная способность может быть неэффективной, даже если теоретически высока, и какие факторы могут привести к снижению фактической пропускной способности?
- Какие компромиссы возникают при выборе между низкой задержкой и высокой пропускной способностью в системе с высокой нагрузкой, и как это влияет на масштабируемость и устойчивость?
What Happens When Your Website Suddenly Goes Viral?
Открыть оригинал ↗ Перевод заголовка: Что происходит, когда ваш сайт внезапно становится вирусным?
Многие небольшие веб-приложения работают стабильно при обычной нагрузке, но быстро терпят неудачу при резком росте трафика. Архитектура, спроектированная для средних нагрузок, становится узким местом при внезапных пиковых запросах, что приводит к перегреву серверов, увеличению задержек и сбоям. В статье предлагается переход от устаревшей модели с одним сервером к гибкой, безопасной и наблюдаемой архитектуре на AWS, где разные компоненты (статические ресурсы, динамические запросы, данные) изолированы и масштабируются независимо.
- Статические ресурсы (CSS, JS, изображения) хранятся в Amazon S3 и доставляются через CloudFront, что снижает нагрузку на приложение.
- Динамические запросы проходят через AWS WAF (фильтрация, ограничение скорости), API Gateway (валидация, тайм-ауты) и выполняются в AWS Lambda — без постоянного сервера.
- Данные хранятся в Amazon DynamoDB, доступ к которой ограничен через IAM-роли, исключая прямой доступ к базе из интернета.
- Все компоненты мониторируются через Amazon CloudWatch — от метрик до алертов, обеспечивая оперативную реакцию на сбои.
- Архитектура построена на принципах разделения обязанностей и масштабируемости, что позволяет быстро адаптироваться к пиковой нагрузке без перезапуска или перегрева.
Когда пригодится
Материал полезен для разработчиков и архитекторов, создающих публичные веб-приложения с высокой вариабельностью трафика (например, магазины, платформы с акциями, соцсети), где важно избежать сбоев при резких пиковых нагрузках и обеспечить безопасность и прозрачность работы системы.
Вопросы для размышления
- Как изменяется производительность Lambda при пиковой нагрузке, если не настроена оптимизация памяти и тайм-аутов?
- В каких сценариях может привести к сбоям отсутствие резервного копирования или автоматического восстановления в DynamoDB?
- Какой минимальный объём трафика может стать критическим для эффективности кэширования в CloudFront, если статические ресурсы не оптимизированы по размеру?
From ERD to DDD: 40 Years of Software Architecture (And Why I am Building TaroDomain)
Открыть оригинал ↗ Перевод заголовка: От ERD к DDD: 40 лет архитектуры ПО (и почему я создаю TaroDomain)
Через 40 лет развития ПО индустрия пережила циклические колебания: от данных в базе до объектов, от монолитов до микросервисов, и обратно. Каждая эпоха принесла свои преимущества и критические недостатки — от избыточных ERD до анемичных доменных моделей и распределённых "мешков из грязи". Автор отмечает, что истинная архитектура должна отражать бизнес-границы, а не технические структуры, и предлагает новый фреймворк TaroDomain как решение для современных задач.
- ERD в 80-х был центральным, но привёл к излишнему фокусу на базе данных, где объекты просто копировались из таблиц — это породило "анемичные модели".
- ОOP и UML начали структурировать бизнес-требования, но быстро превратились в избыточные диаграммы, а не рабочие инструменты.
- ORMs, хотя и упростили работу с базой, привели к утрате поведения в объектах — бизнес-логика переносилась в сервисы, и система стала "пустой".
- ActiveRecord в Rails дал огромную скорость разработки, но в итоге породил "мешок из грязи" из тяжёлых, взаимосвязанных моделей.
- Микросервисы не решили проблему — вместо упрощения появился распределённый "мешок из грязи", где сложные запросы требуют множества переходов и уязвимы к сбоям.
Когда пригодится
Материал полезен при проектировании сложных систем, где важны бизнес-границы, аудит и масштабируемость, например, в финансовых или логистических платформах, где требуется полная прозрачность и контроль за состоянием данных.
Вопросы для размышления
- В каких условиях CQRS и Event Sourcing действительно оправдывают свою сложность, а не просто становятся избыточными для средних проектов?
- Какие риски связаны с использованием TaroDomain в среде, где команды не имеют глубоких знаний DDD и не могут проводить Event Storming?
- В каких сценариях полезно использовать State-Based persistence вместо Event Sourcing, и как это влияет на производительность и отказоустойчивость?
DesignGurus
A Staff-Level System Design Interview: The Full 45-Minute Answer, Annotated
Открыть оригинал ↗ Перевод заголовка: Аннотированный полный ответ на интервью по системному дизайну на уровне стафф-инженера: 45 минут
На уровне стафф-инженера интервью по системному дизайну выглядит так же, как и на уровне старшего инженера — одинаковый формат, одинаковое время, одинакий вопрос. Однако суть отличается: здесь не просто проектируется система, а анализируется, что действительно важно, что можно пропустить, и какие организационные и операционные аспекты влияют на архитектуру. Кандидат демонстрирует способность управлять разговором, фокусироваться на ключевых технических вызовах и оценивать бизнес-компромиссы, а не просто описывать архитектуру. Важны вопросы о том, что не строится, как ведётся интеграция с существующими системами, и как требования к безопасности и размещению данных влияют на инфраструктуру.
- Какие конкретные границы валидности (например, не включать UI или биллинг) могут быть обоснованы на уровне стафф-инженера, и как это влияет на глубину анализа?
- В каких условиях (например, при масштабе или типе контента) CRDT становится неизбежным, а не просто опциональным, и как это влияет на выбор алгоритмической сложности?
- Какие риски могут возникнуть при пропуске интеграции с существующей системой хранения документов, и как это может повлиять на долгосрочную надёжность архитектуры?
Когда пригодится
Материал полезен при подготовке к интервью на уровне стафф-инженера, где оцениваются не только технические навыки, но и способность к стратегическому мышлению, управлению разговором и оценке реальных ограничений проекта.
Вопросы для размышления
- Какие конкретные границы валидности (например, не включать UI или биллинг) могут быть обоснованы на уровне стафф-инженера, и как это влияет на глубину анализа?
- В каких условиях (например, при масштабе или типе контента) CRDT становится неизбежным, а не просто опциональным, и как это влияет на выбор алгоритмической сложности?
- Какие риски могут возникнуть при пропуске интеграции с существующей системой хранения документов, и как это может повлиять на долгосрочную надёжность архитектуры?
Coding / Algorithms
DEV Data Structures
Part 1: Introducing Filters and Probabilistic Searching
Открыть оригинал ↗ Перевод заголовка: Введение в фильтры и вероятностное поисковое поисковое устройство
В статье рассматриваются фильтры как инструменты для вероятностного поиска, позволяющие быстро определять наличие ключа в множестве с допуском на ложные положительные результаты. В отличие от точных структур, таких как словари, фильтры используют значительно меньше памяти и обеспечивают быстрые проверки, при этом гарантируют, что отрицательные ответы всегда корректны, а положительные могут быть ложными с заданной вероятностью ε. Основные особенности фильтров — их компактность, одностороннюю ошибку (нет ложных отрицаний) и возможность настройки точности через параметр ε.
- Как влияет выбор значения ε на баланс между скоростью и точностью в фильтрах, и при каких условиях его можно снизить без потери производительности?
- В каких сценариях может привести к проблемам повторное добавление элемента в фильтр, и как это может повлиять на долгосрочную надёжность системы?
- Почему в некоторых реализациях фильтров отсутствует операция удаления, и как это влияет на безопасность и согласованность данных в production-среде?
Когда пригодится
Материал полезен, когда требуется быстро проверять наличие элемента в больших наборах данных с ограничениями по памяти или задержке, например, при предфильтрации запросов к базам данных, проверке паролей или доступа к внешним сервисам.
Вопросы для размышления
- Как влияет выбор значения ε на баланс между скоростью и точностью в фильтрах, и при каких условиях его можно снизить без потери производительности?
- В каких сценариях может привести к проблемам повторное добавление элемента в фильтр, и как это может повлиять на долгосрочную надёжность системы?
- Почему в некоторых реализациях фильтров отсутствует операция удаления, и как это влияет на безопасность и согласованность данных в production-среде?
How to Build a Java LRU Cache in 5 Lines
Открыть оригинал ↗ Перевод заголовка: Как построить LRU-кэш на Java за 5 строк
Для создания простого кэша «наименее часто используемых» (LRU) в Java достаточно наследовать LinkedHashMap и настроить параметр accessOrder на true, чтобы элементы перемещались в конец при каждом доступе. Дополнительно нужно переопределить метод removeEldestEntry, чтобы при превышении объёма кэша автоматически удалялся старший элемент. Такой подход требует всего пяти строк кода и использует встроенные механизмы стандартной библиотеки, обеспечивая O(1) время выполнения операций благодаря внутреннему двусвязному списку.
LinkedHashMapсaccessOrder = trueавтоматически перемещает элементы в конец приget()илиput(), что обеспечивает порядок использования в O(1).- Метод
removeEldestEntryвозвращаетtrue, когда размер кэша превышает заданную емкость, и таким образом удаляет самый старый элемент. - Реализация не требует ручного управления списками или хэш-таблицами — всё делается через стандартные методы библиотеки.
- Кэш не является потокобезопасным по умолчанию и требует обёртывания, например, через
Collections.synchronizedMap, что может негативно сказаться на производительности при высокой нагрузке. - В производственных средах с высокой конкуренцией рекомендуется использовать альтернативы, такие как Caffeine или Guava, которые обеспечивают потокобезопасность и высокую производительность без синхронизации.
Когда пригодится
Этот подход полезен в однопоточных или лёгких многопоточных сценариях, где важна простота и скорость, а не масштабируемость или отказоустойчивость.
Вопросы для размышления
- В каких условиях использование
Collections.synchronizedMapможет привести к значительному снижению производительности, и как это влияет на выбор междуLinkedHashMapиCaffeineв высоконагруженных сервисах?- Какова сложность проверки и удаления старшего элемента в
removeEldestEntry, если кэш часто переполняется и вставляются новые элементы с высокой частотой?- При каких условиях
LinkedHashMapсaccessOrder = trueможет не работать корректно, даже если размер кэша не превышает лимит, и как это может повлиять на логику кэширования?
Part 2: Bloom Filters, the Theory
Открыть оригинал ↗ Перевод заголовка: Часть 2: Фильтры Блума, теория
Фильтр Блума — один из первых и наиболее известных примеров структур для вероятностного поиска. Он использует битовый массив и несколько независимых хеш-функций для хранения «отпечатка» добавленных элементов, при этом при поиске возможны ложноположительные результаты. Основная идея заключается в том, что при добавлении элемента все хеш-функции устанавливают соответствующие биты в массив на 1, а при поиске проверяются те же позиции — если хотя бы один бит не установлен, элемент отсутствует; если все биты установлены, элемент может быть в структуре, но это не гарантирует его наличие.
- Фильтр Блума не может удалять элементы — удаление требует сложных механизмов, так как невозможно точно сбросить биты без риска ошибки.
- Вероятность ложноположительного результата зависит от размера массива, количества элементов и заданного порога ошибки — при увеличении количества элементов или снижении точности роста ошибки становится значительным.
- Оптимальное количество хеш-функций вычисляется по формуле ( h = \frac{b}{n} \ln 2 ), что обеспечивает минимальную вероятность ложноположительного результата при заданном размере массива.
Когда пригодится
Материал полезен при проектировании систем с ограниченной памятью, где требуется быстро проверять наличие элементов с допустимой вероятностью ошибки, например, в кэш-системах, базах данных или сетевых фильтрах.
Вопросы для размышления
- Как изменится вероятность ложноположительного результата, если размер битового массива увеличить вдвое при неизменных значениях n и ε?
- В каких сценариях использование фильтра Блума может привести к критической ошибке, даже если вероятность ложноположительного результата низка?
- Какой компромисс между памятью и точностью возникает при выборе значения ε = 0.01, и как это влияет на масштабируемость системы при росте количества элементов?
DEV LeetCode
I think me and LeetCode are getting along now
Открыть оригинал ↗ Перевод заголовка: Я думаю, что я и LeetCode теперь хорошо понимаем друг друга
Автор делится личным опытом перехода от страха до понимания LeetCode, подчёркивая, что успех в решении задач не зависит от воли или упорства, а требует системного подхода. Ключевые принципы — распознавание паттернов, использование чек-листа по сложности, признание неспособности решить задачу, регулярность и анализ процесса — объединяют все рекомендации.
- Большинство задач LeetCode повторяют одинаковые паттерны по структуре и решению, что делает их предсказуемыми при достаточном количестве практики.
- Чек-лист по Big-O на основе ограничений входных данных позволяет быстро исключить неэффективные подходы и сократить время поиска решения.
- Признание неспособности решить задачу в первый раз — важный шаг, который снижает стресс и учитывает реальность несовершенства знаний.
- Регулярность (например, ежедневные сессии) формирует привычку, а "стreak" в LeetCode создаёт мотивацию, даже если цель — не просто улучшение навыков.
- Начинать с жёсткого брутфорса, а не с оптимизированного решения, позволяет получить рабочий код, который затем можно улучшать, и избегает паники при первых попытках.
Когда пригодится
Материал особенно полезен для новичков в изучении алгоритмов, которые испытывают страх перед LeetCode и не понимают, как начать эффективно учиться.
Вопросы для размышления
- Какой именно порог в количестве решённых задач считается достаточным для начала распознавания паттернов, и как это может варьироваться в зависимости от уровня подготовки и стиля обучения?
- В каких случаях чек-лист по Big-O может ошибочно указывать на неоптимальный подход, и как это может повлиять на выбор алгоритма при ограниченных входных данных?
- Какой минимальный объём ошибок в логе может дать ощущение прогресса, и какова связь между частотой повторного решения старых задач и устойчивостью к забыванию?
LeetCode.ca Solutions
4032 - Longest Subarray With at Most K Distinct Prime Factors
Открыть оригинал ↗ Перевод заголовка: 4032 - Наибольшая подпоследовательность с не более чем k различными простыми делителями
Для нахождения длины наибольшей подпоследовательности, у которой объединённый набор простых делителей содержит не более k различных простых чисел, используется подход с движущимся окном. Простые делители для каждого числа предварительно вычисляются с помощью решета Эратосфена на диапазоне от 2 до 10⁵, что позволяет быстро получить множества простых делителей при обработке элементов массива. Алгоритм движется по массиву с двумя указателями: правый расширяет окно, левый сжимает его при превышении k различных простых делителей. При каждом шаге проверяется, не превышает ли текущее количество различных простых делителей порог k, и если нет — обновляется ответ как длина текущего окна.
- Предварительная обработка всех чисел от 2 до 10⁵ с помощью решета Эратосфена позволяет быстро получить список простых делителей каждого числа.
- Используется движущееся окно (sliding window), где правый указатель расширяет окно, а левый сжимает его при превышении k различных простых делителей.
- Для каждого элемента в окне добавляются его простые делители в хеш-таблицу, а при необходимости — удаляются делители из элемента, выходящего за левый предел.
- При каждом допустимом окне (с не более чем k различными простыми делителями) обновляется максимальная длина подпоследовательности.
- Временная сложность алгоритма — O(M log log M + n log M), где M = 10⁵, что делает его эффективным для заданных ограничений.
Когда пригодится
Материал полезен, когда нужно найти наибольшую подпоследовательность с ограниченным количеством различных простых делителей, например, в задачах по анализу структуры чисел, где важна разбивка на простые множители.
Вопросы для размышления
- Как изменится ответ, если k будет равен 0, и как это повлияет на границы применимости алгоритма?
- В каких случаях может возникнуть failure mode при использовании этого алгоритма, если числа в массиве не ограничены 10⁵?
- Какова оценка сложности по памяти при работе с большим числом элементов, и как это влияет на масштабируемость в production-среде?