Перейти к содержанию
  • Лента
  • Категории
  • Последние
  • Метки
  • Популярные
  • Пользователи
  • Группы
Свернуть
exlends
Категории
  • ru
    Игры
    Образование
    Искусственный Интеллект
    Новости
    Бекенд, разработка серверов
    Фронтенд
    Мобильная разработка
    Языки программирования
    Разработка игр | 3D | 2D
    Базы данных
    CMS
    Системное Администрирование
    Операционные системы
    Маркетинг
    Девайсы
    Сообщество
    Юмор, Мемы

  • en
    Humor
    News
    AI
    Programming languages
    Frontend
    GameDev

  • Блоги

Авторизуйтесь, чтобы написать сообщение

  • Все категории
  • kirilljsxK
    kirilljsx
    Claude Mythos: настройка ИИ для поиска zero-day в коде CI/CD

    Обложка: Как Anthropic Claude Mythos находит zero-day уязвимости: настройка под аудит кода в CI/CD

    Представьте: ваша команда тратит недели на аудит кода, а конкуренты уже впереди из-за пропущенных zero-day дыр. Claude Mythos от Anthropic меняет правила игры, автономно выискивая тысячи ранее неизвестных уязвимостей в ОС, браузерах и софте. Это не фантазия - модель нашла 27-летний баг в OpenBSD и скомбинировала цепочки эксплойтов в Linux, обходя элитных хакеров.

    Почему это профит для бизнеса?

    В CI/CD ручной аудит - бутылочное горлышко: junior’ы пропускают уязвимости, senior’ы в дефиците, а дедлайны жмут. Mythos работает автономно, анализируя миллионы строк кода за часы. Производительность в 10-100 раз выше человеческих пентестеров - тысячи zero-day за недели, включая критику в FFmpeg и FreeBSD. Партнеры вроде Apple, Microsoft и AWS уже в Project Glasswing тестируют свои системы. Для вас это значит: интеграция в пайплайн, меньше взломов, ниже риски штрафов и простоев.

    Модель не просто находит баги - генерирует рабочие эксплойты. В тесте с JavaScript-движком Firefox успех вырос с 1% (предыдущая Claude) до 72%. Идеально для бэкенда, фронта, мобильки - где угодно есть код.

    Как интегрировать Mythos в CI/CD

    Доступ через Claude API, Amazon Bedrock или Vertex AI по $25/$125 за миллион токенов. Запускаем в GitHub Actions или GitLab CI как шаг после линтинга.

    Вот пример Python-скрипта для автоматизации аудита в пайплайне (Node.js аналог прост - через SDK):

    import anthropic
    import os
    
    client = anthropic.Anthropic(api_key=os.getenv('ANTHROPIC_API_KEY'))
    
    def audit_code(repo_path):
        with open(repo_path, 'r') as f:
            code = f.read()
        
        prompt = """
        Ты - эксперт по безопасности. Проанализируй этот код на zero-day уязвимости:
        - Ищи buffer overflows, race conditions, priv esc.
        - Предложи эксплойт, если найдешь.
        - Верни JSON: {'vulnerabilities': , 'severity': 'high/medium/low'}
        Код: {code}
        """
        
        response = client.messages.create(
            model="claude-mythos-preview-20260407",
            max_tokens=4000,
            messages=[{"role": "user", "content": prompt.format(code=code)}]
        )
        return response.content.text
    
    # В CI/CD: if audit_code('src/main.py') has high sev - fail build
    

    Ключевой промпт: системный шаблон фокусирует модель на паттернах вроде TCP SACK в OpenBSD или цепочках в браузерах. Добавьте инструменты (black-box бинарный анализ) для пентеста.

    Шаг CI/CD Действие Время
    Lint ESLint/Black 1 мин
    Mythos Audit API вызов 5-10 мин
    Report Slack/Jira Авто

    Настройка: env-вариаблы для ключей, лимит токенов под бюджет. Для TypeScript/JS - парсите bundle, для Python - весь репо.

    Риски и реалии

    Mythos не общедоступна - только партнерам, чтобы не плодить супер-оружие хакерам. Anthropic отменила публичный релиз: один баг обошелся в 20k$ после тысяч прогонов. В РФ под санкциями Anthropic доступ через прокси или аналоги (локальные модели типа YandexGPT?), но профит огромен для enterprise. Честно: для малого бизнеса пока костыль, ждите открытых клонов - риски outweigh профит без контроля.

    Что дальше?

    Интеграция Mythos - шаг к ИИ-охотнику за багами в каждом коммите. Сколько сэкономите на пентестерах? А вы уже тестируете код ИИ в CI? Делитесь пайплайнами в коммах - какой стек юзаете для аудита?


    0 0 0 Ответить
  • hannadevH
    hannadev
    Filter + indexOf vs Set: как быстро нормализовать товары из API

    Когда с API летит список товаров с дублями по ID, нужно их убрать — и желательно без лагов на фронте. Классический подход filter + indexOf работает, но сожрёт производительность на больших объёмах. Set выглядит проще, но с объектами по ссылкам он бесполезен. Разбираемся, почему один способ быстрее другого в 10 раз, и как не наступить на грабли.

    Почему filter + indexOf — это костыль на больших данных

    Все начинается просто: нужно отфильтровать массив и оставить только первое вхождение каждого элемента. Код выглядит честно и понятно:

    const filtered = products.filter((item, index) => 
      products.indexOf(item.id) === index
    );
    

    Смотрится красиво, но под капотом происходит O(n²) ужас. Для каждого элемента в цикле filter мы снова прошиваем весь массив через indexOf, ища его первое вхождение. На 15 тысячах товаров это 225 миллионов операций сравнения. Плюс indexOf работает с ссылками, поэтому два объекта с одинаковым ID будут считаться разными — нужна дополнительная логика через JSON.stringify, что ещё больше замедляет.

    Результат: фильтр по категории в админке лагает, юзеры видят висячий UI, всем грустно. Когда allowedIds из стора — это 3 тысячи штук, а основной список 15 тысяч, каждое изменение фильтра превращается в пытку.

    Проблема в том, что indexOf вызывается для каждого элемента, и каждый раз он ползёт по всему массиву заново. Никакой оптимизации, никакой памяти о том, что ты уже ищешь. Просто тупо O(n) × O(n) = боль.

    Set: волшебство с примитивами, разочарование с объектами

    Set — это структура данных, которая хранит только уникальные значения и даёт доступ за O(1). Звучит как решение всех проблем:

    const uniqueIds = new Set(bigArray.map(id => id));
    const filtered = products.filter(p => uniqueIds.has(p.id));
    

    Это O(n) вместо O(n²), и разница ощущается сразу — мгновенно вместо лагов. С примитивами (числа, строки) Set работает идеально: добавляешь элемент, Set сам проверяет, нет ли его уже, и хранит только уникальные.

    Но есть нюанс, который многие пропускают. Set проверяет равенство по значению для примитивов, но для объектов — по ссылке. Два объекта с одинаковым ID будут считаться разными, потому что это разные экземпляры в памяти. Поэтому просто так set(objects) не сработает — нужно класть в Set ID, а не сами объекты.

    Ещё один момент: если хранить строки длинных ID (например, UUID), могут быть хэш-коллизии при нехватке памяти, но это редкая проблема в реальных приложениях. Главное — Set безопасен и быстр, если использовать его правильно.

    Правильный паттерн: Set для индексирования, Map для объектов

    Для нормализации товаров из API нужен гибридный подход. Если нужно отфильтровать объекты по ID, используй Set только для ID:

    const allowedIds = new Set(categories.map(c => c.id));
    const filtered = products.filter(p => allowedIds.has(p.id));
    

    Это читаемо, быстро, и нет магии. Фильтр остаётся простым, все условия явные.

    Если же нужно полностью нормализовать список и убрать дублирующиеся объекты, Map по ID — золотая середина:

    const normalized = new Map(products.map(p => [p.id, p]));
    const result = Array.from(normalized.values());
    

    Мап сам отсекает дубли при set: если два объекта с одинаковым ID, второй перезапишет первый. О(n) на создание, O(1) на доступ. Если нужна логика типа «оставить последний по дате» или «выбрать по какому-то критерию», можно добавить условие в момент set:

    products.forEach(p => {
      const existing = normalized.get(p.id);
      if (!existing || p.updatedAt > existing.updatedAt) {
        normalized.set(p.id, p);
      }
    });
    

    Сравнение на реальных данных

    Подход Сложность Скорость на 15k товаров С объектами Читаемость
    filter + indexOf O(n²) Лаги, ~500ms+ Требует JSON.stringify Средняя
    Set (только ID) O(n) Мгновенно, ~5ms Работает, но нужен отдельный фильтр Высокая
    Map по ID O(n) Мгновенно, ~8ms Работает идеально, дубли отсекаются Высокая
    filter + Set O(n) Мгновенно, ~3ms Работает, но хак Хорошая

    Видишь разницу? С Set и Map мы уходим с O(n²) на O(n) — это не просто ускорение, это спасение UX. На 15 тысячах товарах — ускорение в 10 раз и больше.

    На практике: пример из админки каталога

    Типичная задача: есть таблица товаров, нужно отфильтровать по категории и статусу наличия. allowedIds из фильтра — 3000 товаров, основной список — 15000. Юзер меняет фильтр, данные должны обновиться без задержки.

    Старый способ (костыль):

    const filtered = allProducts.filter((item, index) => 
      allowedIds.indexOf(item.id) === index
    );
    

    Ждём, пока indexOf переберёт массив allowedIds для каждого товара. На каждое изменение фильтра — ~500ms зависания. Юзер кликает, видит freezing, раздражается.

    Новый способ (быстро):

    const allowedIdSet = new Set(allowedIds);
    const filtered = allProducts.filter(p => allowedIdSet.has(p.id));
    

    Есть дубли в списке товаров? Дополняем Map:

    const normalized = new Map();
    allProducts.forEach(p => {
      if (allowedIdSet.has(p.id)) {
        const existing = normalized.get(p.id);
        if (!existing || p.stock > existing.stock) {
          normalized.set(p.id, p); // берём вариант с большим stock
        }
      }
    });
    const filtered = Array.from(normalized.values());
    

    Результат: мгновенно, UI не зависает, юзер доволен. На этом примере ускорение ощущается физически.

    Когда filter + indexOf ещё используется

    Есть кейсы, когда filter + indexOf остаётся единственным разумным вариантом — например, если нужно сохранить порядок первого появления элемента и данные постоянно меняются. Set гарантирует уникальность, но не гарантирует порядок в старых браузерах (хотя в современных порядок вставки соблюдается).

    Ещё встречается старый легаси-код, который почему-то переписывать не хотят — работает, значит работает. Но если ты пишешь новый код и видишь filter + indexOf на больших массивах — это red flag. Это признак либо забывчивости, либо незнания особенностей производительности.

    Проблема в том, что на маленьких массивах (50-100 элементов) разница не видна, поэтому никто не замечает, пока не упрёшься в реальные данные. А потом начинаются поиски баг-репортов и оптимизации, которые можно было избежать с самого начала.

    Финальный ударный тест

    Итак, рецепт для нормализации товаров из API:

    • Если фильтруешь по ID — Set для индексирования, filter остаётся честным: new Set(allowedIds) + has() вместо indexOf().
    • Если удаляешь дубли полностью — Map по ID: new Map(products.map(p => [p.id, p])) + Array.from() в конце.
    • Если нужна сложная логика (выбор по критерию) — forEach с условием в момент set, дешевле, чем дополнительные циклы.

    Экономия на производительности — это не просто быстрее, это улучшение опыта пользователя. Мгновенный отклик на клик, отсутствие зависаний, гладкий UI. На фронте это заметно сразу, на бэке тоже, но там интеллектуальнее относятся к сложности алгоритмов.

    Одно последнее: профилируй на реальных данных. Может быть, у тебя массивы намного меньше, и разницы не будет вообще. Может быть, наоборот — 100 тысяч товаров, и Set сэкономит тебе секунды. Инструменты в браузере (Performance, DevTools) покажут истину быстрее, чем любые статьи. Но основной закон остаётся: O(n) лучше, чем O(n²), всегда и везде.


    0 0 0 Ответить
  • GameFishG
    GameFish
    Pathologic 3: режим концентрации спасает от апатии и мании в кризисах

    Обложка: Pathologic 3: как режим концентрации спасает от апатии и мании в критических моментах

    Режим концентрации в Pathologic 3 - ключ к выживанию в пиках апатии и мании. Он подсвечивает предметы, которые быстро корректируют шкалу психики Бакалавра.

    Без него новички тонут в QTE-самоубийствах или таянии HP от мании. Гайды хвалят механику за тактическую глубину, но предупреждают: шкала качается хаотично, особенно в чумных зонах и бунтах. Это меняет подход к выживанию - теперь не просто лут, а осознанный контроль эмоций Даниила Данковского.

    Шкала апатии и мании: эффекты и риски

    Шкала психики появляется сразу после схода с поезда. Центр - нейтральная зона без дебаффов. Смещение влево накапливает апатию, вправо - манию. Взаимодействия с миром, диалоги и объекты толкают индикатор.

    Апатия тормозит движение: на максимуме Бакалавр еле ползет, а потом запускается QTE-событие самоубийства. Успех дает урон, но сбрасывает шкалу. Мания разгоняет скорость - полезно для спринта через чуму или беспорядки, - но здоровье тает, значок сердца мигает.

    Гайды отмечают: строгий центр не всегда оптимален. Апатию качают перед эмоциональными диалогами, манию - для тайминговых миссий. Но без контроля оба пика рвут новичков.

    Режим концентрации: как он работает

    Активация на F или Q подсвечивает интерактив: красное для мании (стимуляторы, табак, бочки, ящики), синее или зеленое для апатии (морфин, седативы). Это спасает в критике - видишь лут за секунды, не шарясь вслепую.

    Ключевые тактики из гайдов:

    • Табак и кофе разгоняют манию против апатии.
    • Морфин и обезболивающие гасят манию.
    • Диалоги: агрессивные реплики толкают в манию, болтовня - в апатию.
    • Окружение усиливает эффект - взаимодействуй с объектами до лута для максимизации.

    В демо и ранних днях это must-have: пятый день запирает в клетке с авто-апатией, мания возвращает скорость.

    Состояние Эффект Предметы в концентрации
    Апатия max Замедление + QTE-убийство Красное (табак, стимуляторы)
    Мания max Скорость + потеря HP Синее (морфин, седативы)
    Нейтраль Без дебаффов База для стабильности

    Почему новичкам тяжело без гайдов

    Механика кажется рандомной: диалоги непредсказуемы, лут редкий в чуме. Гайды заменяют туториал трюками - не держи центр вечно, используй пики тактически. Но даже с ними шкала дергается от событий.

    Что известно точно: концентрация идентифицирует 100% объектов, QTE на апатии всегда с уроном, мания жрет HP пропорционально уровню. Неподтверждено: точные триггеры всех диалогов, влияние на амальгаму (упоминают потерю в апатии). Последствия для прохождения - смерть от психики реальна, меняет роуты и концовки.

    Для игроков это шаг к мастерству: Pathologic 3 не прощает апатию к механикам. Концентрация превращает хаос в инструмент.

    Итог механики

    Режим концентрации - не просто подсветка, а спасатель от самоуничтожения. Баланс апатии/мании добавляет слой выживанию, где психика Даниила важнее пуль. Гайды доказывают: освоишь - переиграешь игру заново.


    0 0 0 Ответить
  • kirilljsxK
    kirilljsx
    Claude Mythos: настройка ИИ для поиска zero-day в продакшене

    Обложка: Claude Mythos: как настроить ИИ для автономного поиска zero-day уязвимостей в продакшене

    Представьте: ваша продакшн-система висит на волоске от zero-day уязвимостей, которые хакеры уже сканируют. Ручной аудит кода отнимает месяцы, а фрилансеры из даркнета берут бабки за воздух. Claude Mythos Preview от Anthropic меняет правила игры: автономный ИИ, который за недели находит тысячи ранее неизвестных дыр в ОС, браузерах и библиотеках вроде FFmpeg или OpenBSD. Это не фантазия — модель уже пропатчила баги возрастом 27 лет и сгенерировала рабочие эксплойты в 72% случаев, где предшественники проваливались.

    Почему это профит для бизнеса?

    В продакшене zero-day — это не теория, а реальные потери: утечки данных, downtime, штрафы от регуляторов. Mythos через Project Glasswing дает партнерам (Microsoft, Apple, Linux Foundation) доступ для оборонительного сканирования. Модель ранжирует файлы по риску (1-5 баллов), фокусируясь на памяти, аутентификации и входных данных с интернета. Находит баг, пишет тест, анализирует краш, строит цепочку эксплойтов и отчет. 90-кратный прирост эффективности по сравнению с Claude Opus — это когда overnight-задача приносит готовый RCE-эксплойт утром.

    Для dev-команд это автоматизация пентеста: вместо найма багхантеров за $10k+ в месяц — API-доступ за $25/125 за миллион токенов через Claude API, Bedrock или Vertex AI. Публичного релиза нет (слишком опасно), но партнеры уже чистят свой и open-source код.

    Как настроить Mythos для автономного поиска в вашем проде

    Доступ ограничен 12 организациями, но принцип работы можно эмулировать на текущих моделях или ждать расширения. Вот пошаговый план настройки агента для сканирования прод-кода:

    1. Подготовка репозитория: Загрузите исходники в защищенную среду (Docker с QEMU для эмуляции ОС). Mythos сканирует бинарники black-box — без исходников.
    2. Ранжирование файлов: Используйте промпт для оценки риска.
    3. Автономный цикл: ИИ генерит гипотезы, тесты, эксплойты.
    4. Ответственное раскрытие: Репорт в CVE после патча.

    Крутой системный промпт для Claude API (адаптировано под Mythos-логику):

    Ты - автономный zero-day hunter. Цель: найти и эксплуатировать RCE в целевом ПО.
    
    Шаг 1: Проанализируй код/бинарник. Ранжируй файлы по риску (1-5): приоритет - память, auth, input parsing.
    Шаг 2: Для топ-файлов выдвинь 5 гипотез о сбоях (buffer overflow, use-after-free).
    Шаг 3: Напиши PoC-тест на Python/C. Запусти в sandbox (QEMU).
    Шаг 4: Если краш - реверс-анализ. Построй цепочку эксплойта для shell.
    Шаг 5: Сгенерируй отчет: CVE-шаблон, PoC-код, mitigation.
    
    Цель ПО: [укажите, напр. Linux kernel module]. Нет краша? Итерация. Только факты, код работает.
    

    Пример Python-скрипта для автоматизации (Node.js аналог прост):

    import subprocess
    import os
    
    def run_mythos_agent(target_binary, prompt):
        # Вызов Claude API
        response = claude_api.call(prompt + f'\nTarget: {target_binary}')
        
        # Генерация и тест PoC
        poc_code = response['poc']
        with open('poc.py', 'w') as f:
            f.write(poc_code)
        
        result = subprocess.run(['python', 'poc.py', target_binary], capture_output=True)
        if result.returncode != 0:
            return analyze_crash(result.stderr)
        return 'No crash. Iterate.'
    
    # Цикл сканирования
    files = rank_files_by_risk('./prod_repo')
    for file in files:
        report = run_mythos_agent(file, SYSTEM_PROMPT)
        if report['exploit']:
            disclose_vuln(report)
    

    Этот скрипт интегрируется в CI/CD: хукайте на merge, сканируйте новые коммиты. В реале добавьте sandboxing с Firejail.

    Честный отзыв: РФ-реалии и подводные камни

    В России это gold для банков и телекома под 152-ФЗ — аудит legacy-кода ускорится в разы, минимизируя риски от импортозамещения. Но лимиты: доступ только партнерам, а локальные аналоги (Yandex, Sber) пока не дотягивают до 72% успеха в эксплойтах. Плюс этика — модель не для offense, только defense. Стоит ли заморачиваться? Если у вас 100+ devs и прод с legacy — да, профит окупает API-бабки за неделю.

    Что дальше: ваш опыт?

    Mythos показывает, что агентный ИИ уже рвет хакерские чаты по эффективности. Банкинг, e-com или геймдевы — все под прицелом. А вы уже тестите ИИ для пентеста в своем стеке? Делитесь в коммах: какой промпт дал эксплойт, или ручной аудит все еще король? Давайте разберем реальные кейсы.


    0 0 0 Ответить
  • kirilljsxK
    kirilljsx
    Мультиагентные системы ИИ в CI/CD: автоматизируем разработку

    Обложка: Мультиагентные системы ИИ для разработчиков: настройка коллаборации агентов в CI/CD

    Надоело писать одно и то же в разных инструментах? Синхронизировать тесты, документацию, код-ревью - всё это требует времени, который лучше потратить на фичи. Мультиагентные системы ИИ решают эту боль: вместо одного универсального ассистента у тебя работает команда специализированных агентов, которые координируют друг друга и автоматизируют весь цикл разработки прямо в пайплайне.

    Что это вообще такое и почему это не просто хайп

    Мультиагентная система - это не один умный ИИ, а несколько автономных агентов, каждый из которых отвечает за конкретную задачу. Один парсит PR-комментарии, другой запускает тесты и анализирует логи, третий обновляет документацию. Интеллектуальный оркестратор координирует их работу, распределяет роли и контролирует выполнение.

    Зачем нужно в разработке?

    • Параллельность процессов - агенты работают одновременно, а не последовательно
    • Специализация - каждый агент заточен под одну задачу, поэтому качество выше
    • Итеративность - каждый следующий шаг опирается на новые данные, полученные на предыдущих этапах
    • Экономия ресурсов - не нужно держать специалистов под каждый процесс, агенты делают это 24/7

    Сейчас уже готовые решения для этого: CrewAI, LangChain, Microsoft Autogen. Плюс отечественные платформы типа ZeBrains AI и OSMI AI, которые не требуют отправки данных за рубеж и соответствуют российским стандартам безопасности.

    Примеры реальных применений в CI/CD

    Сценарий 1: Code Review автоматизация

    Агент-1 парсит новый PR, извлекает изменения. Агент-2 анализирует код на соответствие стайл-гайду и best practices. Агент-3 проверяет, нет ли потенциальных уязвимостей. Агент-4 обновляет тест-кейсы на основе изменений. Агент-5 генерирует комментарии для разработчика. Всё это параллельно, за 2-3 минуты вместо часа ручного ревью.

    Сценарий 2: Интеллектуальное тестирование

    Агент анализирует фейлы в логах, находит корень проблемы, предлагает патч и тестирует его. Вместо того чтобы разработчик сам копался в стеках ошибок, система выдает готовый анализ и дажевыходную гипотезу для исправления.

    Сценарий 3: Documentation sync

    Чтобы не забывать обновлять доку, заведи агента, который после каждого мержа в мейн автоматически обновляет README, API-документацию и примеры на основе изменений в коде.

    Как это выглядит на практике

    Вот упрощенный пример на Python с CrewAI:

    from crewai import Agent, Task, Crew, LLM
    
    # Определяем агентов
    code_reviewer = Agent(
        role="Code Reviewer",
        goal="Проверить качество кода и найти ошибки",
        backstory="Опытный разработчик с 10 годами опыта",
        llm=LLM(model="gpt-4")
    )
    
    test_engineer = Agent(
        role="Test Engineer",
        goal="Генерировать и запускать тесты",
        backstory="QA-автомат, знающий все типы тестирования",
        llm=LLM(model="gpt-4")
    )
    
    security_agent = Agent(
        role="Security Specialist",
        goal="Выявить уязвимости",
        backstory="Paranoid security expert",
        llm=LLM(model="gpt-4")
    )
    
    # Создаем задачи
    review_task = Task(
        description="Проанализировать PR #{pr_id} и выявить проблемы",
        agent=code_reviewer,
        expected_output="Список проблем с рекомендациями"
    )
    
    security_task = Task(
        description="Проверить код на уязвимости",
        agent=security_agent,
        expected_output="Отчет о найденных уязвимостях"
    )
    
    # Оркестрируем
    crew = Crew(
        agents=[code_reviewer, test_engineer, security_agent],
        tasks=[review_task, security_task],
        verbose=True
    )
    
    result = crew.kickoff(inputs={"pr_id": "1234"})
    print(result)
    

    Этот скрипт запускаешь в твоем GitHub Actions, он создает три агента, каждый параллельно делает свою работу, и результаты приходят в PR как автоматический комментарий.

    Где подводные камни

    Токены и лимиты - каждый вызов к LLM стоит денег. Если ты запустишь 10 агентов на каждый PR, счета могут быть болезненными. Решение: локальные модели (Ollama, LM Studio) или кэширование результатов.

    Галлюцинации LLM - агент может выдать неправильный вывод и передать его дальше. Нужна система валидации: проверка выходных данных перед передачей следующему агенту.

    Chaos в координации - если агенты конфликтуют или неправильно передают информацию, система может зависнуть. Нужна четкая архитектура оркестрации.

    Отладка - когда что-то ломается, ловить баг сложнее. Логируй все действия агентов.

    Реалии рынка и перспективы в 2026

    За границей давно экспериментируют с этим (Mayo Clinic, Vodafone, ADT используют Google’s Agent Builder). В России развивается свое: ZeBrains AI позиционирует себя как решение для больших компаний, которые боятся отправлять данные за рубеж. OSMI AI строит high-load платформы под колоссальные нагрузки.

    Для стартапа и среднего бизнеса это пока дорого и требует времени на настройку. Но если твой пайплайн обрабатывает 100+ PR в день или есть рутинные операции - ROI закроется в течение месяца.

    Что дальше?

    Справедливый вопрос: как вы сейчас решаете автоматизацию CI/CD? Рискуете ли с мультиагентными системами или это пока звучит как футуристичный оверкилл? Любопытно услышать боевые истории - может, кто-то уже это запустил и знает реальные грабли.

    Мультиагентные системы - это не будущее, это уже сейчас. Вопрос не в том, «нужны ли они», а в том, когда ты их внедришь.


    0 0 0 Ответить
  • kirilljsxK
    kirilljsx
    Автономные ИИ-агенты вместо маркетологов в B2B: лиды и конкуренты

    Обложка: Как автономные ИИ-агенты заменяют маркетологов в B2B: настройка под сбор лидов и анализ конкурентов

    Представьте: ваш B2B-маркетолог тратит 80% времени на рутину - поиск лидов по базам, анализ конкурентов, персонализацию рассылок. А ИИ-агент делает это 24/7 без зарплаты и кофе-брейков. Ручная лидогенерация умирает, конкуренция жрет бюджеты, а агенты уже строят воронки, которые приносят профит.

    В B2B продажи длинные, клиенты осторожные, а маркетологи тонут в Excel. Автономные ИИ-агенты меняют правила: они сами находят компании, квалифицируют лиды, анализируют конкурентов и даже ведут первичные переговоры. Не чат-боты для ‘привет, чем поможем?’, а полноценные системы на базе LLM вроде Grok или Claude, интегрированные в n8n или LangChain.

    Как агенты собирают лиды: от поиска до CRM

    Агент стартует с scraping’а данных: парсит LinkedIn, сайты компаний, базы вроде Hunter.io. Затем обогащает профили - находит emails, телефоны, болевые точки из новостей и отзывов.

    Ключевой инсайт: интеллектуальная квалификация. Агент не просто собирает контакты, а оценивает потенциал: размер компании, стек технологий, недавние наймы. Передает в CRM только горячие лиды с рекомендациями ‘upsell по API-интеграциям’.

    Пример кейса: внедрение агента сократило штат на 50%, расходы на 100к, лиды выросли в 5 раз.

    Вот простой Python-скрипт на LangChain для старта лидогенерации. Установите langchain, openai, requests.

    import os
    from langchain_openai import ChatOpenAI
    from langchain.prompts import PromptTemplate
    from langchain.chains import LLMChain
    import requests
    
    llm = ChatOpenAI(model="gpt-4o", api_key=os.getenv("OPENAI_API_KEY"))
    
    prompt = PromptTemplate(
        input_variables=["company_name", "industry"],
        template="Найди 5 потенциальных лидов в {industry} для компании {company_name}. Для каждого: email CEO, сайт, почему подходят (3 предложения). Формат JSON."
    )
    
    chain = LLMChain(llm=llm, prompt=prompt)
    
    result = chain.run(company_name="МояSaaS", industry="e-commerce")
    print(result)
    

    Запустите - и получите готовый список. Интегрируйте с n8n для автоматизации: агент парсит, обогащает, шлет персонализированные emails.

    Анализ конкурентов: агент как шпион

    Маркетологи месяцами мониторят конкурентов вручную. Агент делает это автономно: сканерит цены, фичи, отзывы, трафик с Ahrefs/SEMrush API.

    Системный промпт для анализа:

    Ты - B2B-аналитик. Проанализируй конкурента {competitor_url}. Собери: ключевые фичи, цены, слабые места из отзывов G2/Capterra, источники трафика. Сравни с моей продуктом {my_features}. Дай 5 тактик, как обогнать. Вывод в таблицу Markdown.
    

    Агент генерирует отчет: ‘Конкурент слаб в мобильном app - пушьте туда рекламу’. Или ‘Они подорожали на 20% - предлагайте скидку первым 50 клиентам’.

    Задача Ручной маркетолог ИИ-агент
    Сбор 100 лидов 2 дня 10 мин
    Анализ 5 конкурентов 1 неделя 5 мин
    Персонализация 100 emails 4 часа Авто
    Конверсия лидов 5% 15-30%

    Реализация: n8n + AI-агенты для B2B

    n8n - король no-code автоматизации. Соедините:

    • Google Sheets для баз лидов.
    • AI-ноду для промптов.
    • Email/Slack для outreach.
    • CRM (amoCRM/ HubSpot) для передачи.

    Агент самообучается: анализирует отклики, корректирует подходы. В B2B это убивает холодные звонки - персонализация на 90% повышает открываемость.

    В РФ это уже работает: интегрируйте с Яндекс.Tracker или 1C, обходит санкции через прокси. Но будьте осторожны с данными - GDPR/152-ФЗ требуют согласий, иначе штрафы сожрут профит. Идеально для SaaS с бюджетами 50-200к/мес.

    Что дальше: ваш первый агент

    ИИ-агенты не заменяют всех маркетологов, но высвобождают их для стратегии. Сейчас настройка окупается за 1-2 месяца, а через год это будет как email в 2010. Начните с простого: протестируйте n8n workflow на своих лидах.

    А вы уже запускали агента для лидов или анализа конкурентов? Делитесь стеками в комментах - как��й промпт сработал, где застряли. Давайте разберем ваши кейсы!


    0 0 0 Ответить
  • hannadevH
    hannadev
    Object.fromEntries() и Map: чистые объекты настроек без мутаций и костылей

    Каждый день фронтендеры мучаются с настройками - конфигами, которые летают между функциями, мутируют под ногами и плодят баги. Object.fromEntries() с Map решает это чисто: берешь любой итерируемый набор пар ключ-значение и лепишь свежий объект без побочек. Забудь про ручные циклы и spread-операторы, которые иногда подводят.

    Это не просто сахар синтаксиса. Ты избегаешь мутаций оригинала, держишь код функциональным и читаемым. Полезно для парсинга query-параметров, трансформации API-ответов или создания дефолтных опций. Проблемы с глубоким клонированием? Они уходят сами.

    Почему Object.fromEntries() - антидот для конфигов

    Object.fromEntries() - это обратная сторона Object.entries(). Первый разворачивает объект в массив пар [ключ, значение], второй собирает обратно. Вместе они дают паттерн: entries() + map/filter + fromEntries(). Никаких мутаций, чистый иммутабельный флоу. Представь: у тебя Map с настройками из localStorage или URLSearchParams. Один вызов - и готов объект для пропсов компонента.

    Без этого приходится писать редусеры или Object.assign() в цикле - типичный легаси-костыль. А с fromEntries() код сжимается в одну строку, но остается предсказуемым. Плюс, Map держит ключи любого типа, в отличие от обычных объектов, где все строки. Это спасает при работе с символами или объектами как ключами.

    • Иммутабельность на стероидах: оригинальный Map или массив не трогается, всегда свежий объект.
    • Функциональный пайплайн: entries() -> transform -> fromEntries(), как в RxJS, но для JS.
    • Поддержка итерируемых: Map, Set, Array, даже generator - все на входе.
    • Нюанс с прототипом: свойства прототипа не попадают, только enumerable own properties.
    Подход Мутации Производительность Читаемость
    Цикл for…in Да Средняя Низкая
    Object.assign() Да Хорошая Средняя
    fromEntries() Нет Высокая Высокая

    Map как источник чистых настроек

    Map - идеальный контейнер для настроек на лету. new Map(Object.entries(config)) дает коллекцию без дубликатов ключей, плюс итерация for…of без entries(). Потом Object.fromEntries(map) - и объект готов. Полезно в утилитах: парсим query string в Map, фильтруем, собираем в config.

    Старый способ: lodash cloneDeep или JSON.parse/stringify - медленные, теряют функции и undefined. Map + fromEntries() - нативно, быстро, без потерь. Пример: API вернул Map с опциями, трансформируешь значения (добавляешь дефолты), и выдаешь объект для React/Vue.

    const queryMap = new URLSearchParams(window.location.search);
    const paramsObj = Object.fromEntries(queryMap.entries()); // { page: '1', limit: '10' }
    
    • Преимущества Map: дубликаты ключей перезаписываются, порядок сохраняется (с ES6).
    • Трансформация: map.entries().map(([k,v]) => [k, defaultValue(v)]).
    • Сравнение с WeakMap: не подходит, ключи должны быть объектами, но для настроек - overkill.
    • Интеграция с URLSearchParams: уже итерируемый, fromEntries() работает из коробки.

    Трансформации без рефакторинга всего проекта

    Классика: удвоить цены в объекте. entries() -> map(([key, val]) => [key, val*2]) -> fromEntries(). Код короче, чем reduce, и без мутаций. Это работает для filter: отсеиваем свойства по условию. Или sort по значениям - entries(), sort(), fromEntries().

    Проблема мидлов: пытаются мутировать config в place, потом баг в другом модуле. С этим паттерном каждая функция получает свой срез. Плюс, легко добавить валидацию: в map проверяешь типы, кидаешь ошибку рано.

    const settings = { theme: 'dark', lang: 'ru', debug: false };
    const validated = Object.fromEntries(
      Object.entries(settings).filter(([k,v]) => typeof v !== 'undefined')
    );
    
    • Фильтрация: entries().filter(([k,v]) => v > 0) - только положительные цены.
    • Маппинг: entries().map(([k,v]) => [k.toUpperCase(), v]) - нормализация ключей.
    • Комбо с reduce: редко нужно, fromEntries() эффективнее для простых случаев.
    • Порядок свойств: в объектах ES2015+ сохраняется порядок вставки, как в Map.
    Трансформация Старый способ Новый
    Удвоить значения for…in + obj[k]*=2 entries().map * fromEntries()
    Фильтр по значению reduce entries().filter() * fromEntries()
    Сортировка entries().sort() * reduce entries().sort() * fromEntries()

    Грабли, которых избежишь навсегда

    Не все итерируемые подходят: если ключи не строковые/символьные - в объекте станут строками. Map с числовыми ключами превратится в { ‘1’: value }. Проверяй типы заранее. Еще ловушка: undefined значения улетают без следа, fromEntries() их игнорирует.

    В старом коде часто видят Object.assign({}, …entries), но это мутирует target при ошибках. FromEntries() создает новый с нуля. Производительность: для 1000+ свойств Map быстрее, бандл меньше без lodash.

    • Ключи-объекты: теряются, станут [object Object]. Используй Map целиком.
    • Циклические ссылки: нет проблем, но в объекте могут быть.
    • Polyfill: если legacy-браузеры, но в 2026+ это не актуально.

    Реальные сценарии из подкапотного мира

    Парсинг форм: FormData.entries() прямо в fromEntries() - объект для отправки. Конфиг из env: Map из process.env, фильтр по префиксу, объект для app. В React: useMemo с fromEntries для theme-опций из context Map. Никаких useCallback костылей.

    Бонус: комбо с Proxy для реактивных config, но это уже next level. Или генераторы: function*() { yield [‘key’, val] }, потом fromEntries(). Код как по маслу.

    const formData = new FormData();
    formData.append('name', 'user');
    const config = Object.fromEntries(formData); // чистый объект
    

    Когда привыкнешь - старые циклы покажутся дикостью. Останутся вопросы с nested объектами? Рекурсивно entries() на значениях.

    Под капотом еще глубже

    Object.fromEntries() появился в ES2019, но под капотом - цикл по итератору с Object.defineProperty для каждого. Не используй на не-iterable - TypeError. Map.prototype.entries() возвращает пары, идеально ложатся. Сравни с Reflect: тот же эффект, но fromEntries короче.

    Это базовый brick для утилит: напиши toConfig(iterable) wrapper. Меньше deps в package.json. Думай о производительности: для больших Map - батчинг, но редко нужно.

    Когда иммутабельность бьет рекорды скорости

    Представь debounce-функции с опциями: Map из дефолтов, merge с user input через entries(), fromEntries() для финала. Никаких deep merges из ramda. В Node: парсинг multipart/form-data в config без мутаций.

    Грабли: fromEntries() не клонирует глубоко, nested объекты ссылаются. Для full clone - рекурсия. Но 90% случаев - плоские config, тут король.

    function mergeDefaults(userMap, defaultsMap) {
      return Object.fromEntries(new Map([...defaultsMap, ...userMap]));
    }
    
    • Merge Map: new Map([…defaults, …user]) перезаписывает user.
    • Deep merge: entries() на каждом, рекурсивно fromEntries.
    • Polyfill trap: самописный fromEntries падает на non-enumerable.

    Итог без иллюзий

    Object.fromEntries() с Map - минималистичный дуэт против мутационного ада. Конфиги чистые, код короткий, баги реже. За кадром: производительность на 10k+ items, где reduce проигрывает. Подумай о типизации в TS - entries() возвращает [string, any][], удобно для generics.


    0 0 0 Ответить
  • GameFishG
    GameFish
    Pathologic 3: гайды по апатии и мании спасают новичков, но механика все равно рвет

    Обложка: Pathologic 3: гайды по апатии и мании стали спасением но почему механика все равно ломает новичков

    Гайды по апатии и мании в Pathologic 3 стали настоящим спасением для новичков. Игроки разбирают шкалу настроения Бакалавра и учатся выживать без чтения скучных туториалов.

    Но механика все равно ломает: непредсказуемые диалоги и дефицит ресурсов сбивают баланс, заставляя умирать в первые дни.

    Эти гайды фокусируются на системе, где центр шкалы - нейтральное состояние для Даниила Данковского. Сдвиг в апатию замедляет движение, в манию дает скорость, но жрет здоровье. Новички быстро осваивают тактики, избегая самоубийств и потерь HP. Для хардкора от Ice-Pick Lodge это меняет подход - практика вместо теории.

    Шкала апатии и мании: базовые эффекты

    Шкала в верхней части экрана смещается между апатией (слева) и манией (справа). Нейтраль - безопасная зона. Апатия растет от безделья или отвлеченных разговоров, мания - от прямолинейных реплик.

    • Максимум апатии: персонаж пытается самоубийство с QTE-событием (быстрое нажатие клавиш). Успех дает урон, но сбрасывает шкалу.
    • Максимум мании: здоровье тает, отображается иконкой сердца. Полезно для спринта через чумные зоны или бунты.

    Гайды подчеркивают: не держите строго центр. Высокая мания ускоряет перед таймингами, апатия помогает в диалогах с манией. Но новички все равно тонут - шкала качается непредсказуемо, особенно без лута.

    Как гайды учат балансировать

    Гайды заменяют встроенные подсказки практическими трюками. Режим концентрации (F или Q) подсвечивает объекты: красное для мании (баки, ящики), синее для апатии.

    Ключевые способы контроля:

    • Табак, стимуляторы - разгоняют манию.
    • Морфин, седативы - гасят апатию.
    • Диалоги: жесткие ответы повышают манию, болтовня - апатию.

    Не экономьте концентрацию, чтобы находить ресурсы. Амальгама тратится на лечение, лут собирайте системно. В первых днях это спасает от глупых смертей, но механика не прощает ошибок - толерантность к лекарствам растет, ресурсы кончаются.

    Состояние Эффект Тактика из гайдов
    Апатия max Замедление + QTE самоубийство Поднять морфином перед маниакальными диалогами
    Мания max Скорость + потеря HP Пробегать чуму с запасом лекарств
    Нейтраль Без рисков База для новичков, но не всегда оптимально

    Таблица показывает, почему гайды цепляют: они превращают абстрактную шкалу в инструмент выживания. Однако без опыта диалоги сбивают - половина вариантов не угадать заранее.

    Почему механика все равно ломает новичков

    Гайды дают старт, но Pathologic 3 - не линейный симулятор. Дефицит лута, чума, тайминги квестов давят. Апатия копится от простоя, мания жрет HP без запасов. Даже зная трюки, новички умирают на переходах или от неверных реплик.

    В обзорах отмечают: мания выгоднее апатии для скорости, но требует постоянного фарма лекарств. Туториалы в игре минимальны, гайды заполняют пробел. Последствия для игроков - либо осваиваешь через смерть, либо читаешь. Пока нет патчей, механика остается хардкорной, сбивая баланс без спойлеров.

    Что дальше для новичков

    Гайды эволюционируют: добавляют советы по дням 1-6, диагностике, взаимодействию с детьми. Известно, что окружение (бочки, поезда) влияет на шкалу. Не подтверждено влияние на сюжет - гайды избегают спойлеров. Для игроков это шанс пройти без фрустрации, но механика требует практики. Новичкам - запаситесь терпением.


    0 0 0 Ответить
  • AladdinA
    Aladdin
    Next js 16+ cacheComponents, переучиваемся кешировать, примеры

    Переход на Next.js 16 с флагом cacheComponents кардинально меняет философию работы с данными. Раньше фреймворк стремился все кэшировать и делал это неявно, а теперь по умолчанию все динамическое, и вы сами явно указываете, что хотите закэшировать.

    Это переход от модели “статики по умолчанию” к “динамике по умолчанию” с полным контролем разработчика. От себя скажу, что для разработчика это хорошо, меньше магии и больше понимания того что ты делаешь.

    История. Как Next.js переобулся

    Next.js 14

    Тут кешировалось все, что только могло кешироваться.

    Фреймворк по умолчанию стремился к статической генерации страниц (SSG) во время сборки. Он переключался на динамический рендеринг (SSR) только при обнаружении «динамических» функций, таких как cookies() или headers().

    // app/blog/[slug]/page.tsx
    
    export const dynamic = 'auto' // 'auto' | 'force-dynamic' | 'error' | 'force-static'
    export const dynamicParams = true // true | false
    export const revalidate = 3600 // false | 0 | number (в секундах)
    export const fetchCache = 'auto' // 'auto' | 'force-no-store' | 'only-cache' | ...
    

    Все fetch-запросы по умолчанию кэшировались (аналог cache: 'force-cache'). Это означало, что если вы не указывали опции явно, данные запрашивались один раз при сборке, и все пользователи видели одну и ту же версию

    // Данные будут получены один раз при сборке и закешированы навсегда.
    // Опцию cache: 'force-cache' можно не указывать, это значение по умолчанию.
    await fetch('https://api.example.com/posts', { cache: 'force-cache' });
    

    Next.js 15

    Самым значимым и обсуждаемым изменением в Next.js 15 стал полный пересмотр стратегии кэширования данных. Разработчики фреймворка прислушались к сообществу, которое часто сталкивалось с непредсказуемым поведением из-за агрессивного кэша в 14-й версии.

    📡 И вот теперь fetch() больше не кэширует данные.
    В Next.js 15 поведение по умолчанию изменилось на cache: ‘no-store’. Это значит, что каждый запрос fetch() будет выполняться заново при каждом обращении к странице, если вы явно не укажете иное. Это делает поведение в разработке и на продакшене более предсказуемым, но требует более осознанного подхода к оптимизации.

    🛣️ GET Route Handlers также стали динамическими
    Изменение коснулось и обработчиков маршрутов (Route Handlers). В 14-й версии GET-запросы кэшировались по умолчанию. В 15-й версии они также стали динамическими.

    Изменения затронули и клиентскую часть.
    В Next.js 14 кэш роутера на стороне клиента (Router Cache) по умолчанию сохранял посещенные страницы на 30 секунд для динамических и на 5 минут для статических страниц. В Next.js 15 клиентский кэш по умолчанию отключен для всех страниц. Теперь при переходе по страницам они будут загружаться заново, гарантируя, что пользователь всегда видит актуальную информацию. Если вам нужно ускорить навигацию и вы готовы пойти на компромисс, время жизни кэша можно настроить вручную в next.config.ts:

    // next.config.ts
    const nextConfig = {
      experimental: {
        staleTimes: {
          dynamic: 30, // 30 секунд для динамических страниц
          static: 180,  // 3 минуты для статических страниц
        },
      },
    };
    

    Next.js 16

    В 16-й версии Next.js добавляет флаг cacheComponents который действительно полностью меняет правила игры: он отключает всю старую модель кэширования и заменяет ее на новую, полностью явную. Всё, что вы знали о fetch, revalidate и export const dynamic раньше, больше не работает.

    Это все значит, что нам опять переучиваться ( ну, нам с @kirilljsx не привывать). Новые проблемы -> новая работа -> новые вакансии 😘 . Об этом всем можно и поныть, но на мой субъективный взгляд, надо было изначально делать таким фреймворк, а не подстраиваться под стадо вебмакак низшего эшелона добавляю свою магию везде, где нужно и не нужно.

    cacheComponents - Новая реальность

    Теперь, когда старые правила отключены, все решения о кэшировании принимаются явно и на уровне кода с помощью новой директивы ‘use cache’ и сопутствующих функций. Основной принцип прост: по умолчанию не кэшируется ничего.

    Директива 'use cache' — это ваш главный инструмент. Её можно применять на трех уровнях:

    1. На уровне файла (страницы или компонента): Поместите директиву в самом верху файла, и все экспортируемые из него асинхронные функции будут кэшироваться.

    2. На уровне компонента: Используйте директиву внутри тела компонента, чтобы закэшировать результат его рендеринга.

    3. На уровне функции: Применяйте к асинхронным функциям, чтобы кэшировать возвращаемые ими данные.

    cacheLife - Управление временем жизни кэша
    Для управления временем жизни кэша используется функция cacheLife. Она должна вызываться внутри области действия ‘use cache’.

    Вы можете использовать один из предустановленных профилей или создать свой собственный. Профили определяют три ключевых параметра: stale, revalidate и expire:

    Разберем подробнее, какой параметр за что отвечает.

    1. stale (Клиентский кеш)
      Определяет, как долго клиент (браузер) может показывать данные из кеша, вообще не связываясь с сервером для проверки.
      Пока не истечет это время, при повторном посещении страницы она загрузится мгновенно из памяти.
      Параметр чисто клиентской производительности, призванный ускорить навигацию.

    2. revalidate (Фоновая проверка)
      Частота, с которой кеш в фоновом режиме запрашивает свежие данные с сервера.
      Как только время revalidate истекает, Next.js все равно мгновенно отдает клиенту “устаревший” кеш, но в фоне запускает процесс генерации новой версии. Новые данные подготовятся к следующему запросу.
      Механизм stale-while-revalidate. Пользователь всегда получает быстрый ответ, даже если данные немного устарели.

    3. expire (Крайний срок)
      Максимальное время, в течение которого данные могут оставаться “устаревшими” до того, как они будут считаться полностью недействительными.
      Если данные в кеше находятся в состоянии “stale” (после revalidate) дольше, чем позволяет expire, Next.js больше не будет отдавать их мгновенно. Вместо этого он заблокирует ответ и заставит пользователя подождать, пока новые данные будут получены с сервера (динамический рендеринг).
      Защитный механизм от показа “совсем старых” данных. expire всегда должен быть больше revalidate.

    Профиль stale revalidate expire Описание
    'seconds' 30 сек 1 сек 1 мин Для контента, который должен обновляться почти мгновенно.
    'minutes' 5 мин 1 мин 1 час Для часто обновляемого контента.
    'hours' 5 мин 1 час 1 день Для контента, обновляемого несколько раз в день.
    'days' 5 мин 1 день 1 неделя Для контента, обновляемого ежедневно.
    'weeks' 5 мин 1 неделя 30 дней Для контента, обновляемого еженедельно.
    'max' 5 мин 30 дней 1 год Для очень стабильного контента.

    Важно: Если вы не укажете cacheLife, будет применен профиль ‘default’, который подходит для большинства случаев.

    включаем новый режим

    Для активации новой модели необходимо добавить флаг cacheComponents: true в ваш файл next.config.ts. Это глобальный переключатель, который меняет поведение всего приложения:

    // next.config.ts
    import type { NextConfig } from 'next'
    
    const nextConfig: NextConfig = {
      cacheComponents: true,
    }
    
    export default nextConfig
    

    Используем “use cache”

    На уровне файла (страницы)

    Если поместить ‘use cache’ в самом верху файла, она применяется ко всем экспортируемым асинхронным функциям в этом файле. Это удобно для кэширования целой страницы или группы связанных функций.

    // app/blog/page.tsx
    'use cache'; // <-- Директива на уровне всего файла
    
    import { cacheLife } from 'next/cache';
    
    // Эта функция тоже будет закэширована, так как она экспортируется и асинхронная
    export async function getFeaturedPosts() {
      // fetch без дополнительных опций, т.к. кэшированием управляет директива
      const res = await fetch('https://api.example.com/featured-posts');
      return res.json();
    }
    
    // Основной компонент страницы — экспортируемая асинхронная функция
    export default async function BlogPage() {
      cacheLife('hours'); // Устанавливаем время жизни кэша для всей страницы
    
      const posts = await getFeaturedPosts();
    
      return (
        <main>
          <h1>Блог</h1>
          {posts.map((post) => (
            <article key={post.id}>{post.title}</article>
          ))}
        </main>
      );
    }
    

    Важно: Если в этом же файле есть синхронные компоненты (например, function Sidebar()), они не попадают под действие ‘use cache’, потому что директива влияет только на асинхронные экспорты.

    На уровне компонента

    В этом случае директива помещается внутрь тела асинхронного компонента. Она кэширует результат рендеринга этого конкретного компонента.

    // app/components/ProductList.tsx
    import { cacheLife, cacheTag } from 'next/cache';
    
    export async function ProductList({ category }: { category: string }) {
      'use cache'; // <-- Директива внутри компонента
      cacheLife('days');
      cacheTag(`products-${category}`); // Тег для точечной инвалидации
    
      const products = await fetch(
        `https://api.example.com/products?category=${category}`
      ).then((res) => res.json());
    
      return (
        <div className="grid">
          {products.map((product) => (
            <div key={product.id}>{product.name}</div>
          ))}
        </div>
      );
    }
    Как использовать на странице:
    
    tsx
    // app/products/page.tsx
    import { Suspense } from 'react';
    import { ProductList } from '@/components/ProductList';
    
    export default function ProductsPage() {
      return (
        <div>
          <h1>Товары</h1>
          {/* Этот компонент будет закэширован */}
          <ProductList category="electronics" />
          
          {/* А этот останется динамическим, так как не обёрнут в 'use cache' */}
          <Suspense fallback={<p>Загрузка рекомендаций...</p>}>
            <PersonalRecommendations />
          </Suspense>
        </div>
      );
    }
    

    На уровне функции

    Этот подход позволяет кэшировать результат конкретной асинхронной функции, например, запрос к базе данных. Это полезно, когда одну и ту же функцию нужно использовать в нескольких местах без повторного выполнения.

    // app/lib/data.ts
    import { cacheLife, cacheTag } from 'next/cache';
    
    // Кэшируемая функция получения данных
    export async function getUserProfile(userId: string) {
      'use cache'; // <-- Директива на уровне функции
      cacheLife('minutes');
      cacheTag(`user-${userId}`);
    
      console.log('Выполняется запрос к БД'); // Увидим только при первом вызове
      const user = await db.user.findUnique({ where: { id: userId } });
      return user;
    }
    

    Использование в компонентах:

    // app/profile/page.tsx
    import { getUserProfile } from '@/lib/data';
    
    export default async function ProfilePage() {
      const user = await getUserProfile('user-123'); // Кэшируется
    
      return (
        <div>
          <h1>Привет, {user.name}!</h1>
          <UserDetails user={user} />
        </div>
      );
    }
    

    Если getUserProfile вызвать ещё раз в другом компоненте на той же странице, запрос к БД не повторится — Next.js вернёт закэшированный результат.

    💡 Дополнительно: Комбинирование уровней

    Вы можете комбинировать директивы. Например, страница закэширована целиком, но внутри есть функция, у которой свой собственный cacheLife.

    // app/dashboard/page.tsx
    'use cache'; // Кэшируем всю страницу
    
    import { cacheLife } from 'next/cache';
    import { getStats } from '@/lib/stats';
    
    export default async function DashboardPage() {
      cacheLife('hours'); // Основное время жизни для страницы
    
      const stats = await getStats(); // Функция getStats может иметь свой 'use cache' и cacheLife
    
      return <Dashboard stats={stats} />;
    }
    
    // app/lib/stats.ts
    import { cacheLife } from 'next/cache';
    
    export async function getStats() {
      'use cache';
      cacheLife('minutes'); // Этот кэш будет обновляться чаще, чем вся страница
    
      const res = await fetch('https://api.example.com/stats');
      return res.json();
    }
    

    В этом случае общий HTML страницы будет жить по правилам hours, а данные из getStats — по правилам minutes, но они всё равно встроены в статический каркас страницы.

    🛑 Подводные камни (Важно!)

    Не все так гладко, просто так включить флаг и пользоваться скорее всего не выйдет, если вы не подготовили проект к такому переходу 🤡

    Когда вы включаете cacheComponents в Next.js 16, фреймворк переходит к новой стратегии рендеринга — Partial Prerendering (PPR). В её основе лежит жёсткое требование: во время сборки (next build) должен быть сформирован мгновенно загружаемый статический “каркас” (static shell). Из-за этого асинхронное получение данных без 'use cache' и без <Suspense> приводит к ошибке сборки Uncached data was accessed outside of <Suspense>.

    Причина ошибки: блокировка статического каркаса
    Раньше Next.js мог “подождать” данные и отдать готовую страницу (SSR), но с cacheComponents он всегда пытается сгенерировать статическую оболочку на этапе сборки.

    Проблема возникает, когда в компоненте есть асинхронный вызов (например, fetch или await params), который не может завершиться во время сборки и при этом не обрамлён. В этом случае сборка падает с ошибкой.

    Если фреймворк не знает, что показывать пользователю, пока данные грузятся (нет fallback из ), он не может собрать статический каркас. Это защита от “медленной” страницы, где пользователь видит белый экран до полной загрузки всех данных на сервере.

    Как исправить: два пути на выбор

    У вас есть два варианта решения этой ошибки, в зависимости от ваших задач:

    1. Закэшировать данные в статический каркас: Если данные меняются редко, их можно сделать частью мгновенно загружаемого каркаса. Для этого нужно добавить директиву 'use cache' прямо в асинхронную функцию. Тогда данные будут получены на этапе сборки и закэшированы.

    2. Оставить данные динамическими, но с заглушкой: Если данные должны запрашиваться при каждом визите (персонализированная информация, часто меняющиеся данные), их нужно обернуть в <Suspense>. Это указывает Next.js оставить в статическом каркасе “заглушку” (fallback), а сами данные догрузить уже на клиенте в фоне.

    ( кейсы попробую подготовить далее в комментариях)

    Как это работает?

    🧱 Статический каркас (Static Shell) — что это?

    Когда вы включаете cacheComponents, Next.js перестаёт генерировать страницу целиком динамически на сервере по каждому запросу. Вместо этого он во время сборки (build) пытается создать каркас страницы — мгновенно загружаемый HTML, который видит пользователь в первую секунду.

    Внутри этого каркаса могут быть:

    • Статический контент (заголовки, подвалы).
    • Закэшированные данные.
    • “Дырки” (Suspense Fallback) для тех данных, которые ещё не готовы.

    ⚙️ Как именно кеш помогает отрисовать этот каркас?

    Ответ кроется в том, в какой момент времени выполняется код.

    Без кеша (ошибка сборки)

    // ❌ Ошибка при сборке
    export default async function Page() {
      const data = await fetch('...'); // Запрос без 'use cache'
      return <div>{data}</div>;
    }
    

    Во время сборки Next.js запускает этот компонент.

    Он натыкается на await fetch. Стоп-машина. Потому что по новым правилам fetch по умолчанию динамический (no-store).

    Next.js не может выполнить динамический запрос во время сборки (в окружении CI/CD нет контекста пользователя, да и смысла нет — данные же должны быть свежими при каждом запросе).

    Next.js не знает, что рисовать в этом месте каркаса, и выбрасывает ошибку: “Я не могу собрать статику, потому что тут висит незавершенный асинхронный хвост”.

    С кешем (успешная сборка)

    // ✅ Успешная сборка
    export default async function Page() {
      'use cache'; // <-- Включаем кеш
      const data = await fetch('...');
      return <div>{data}</div>;
    }
    
    1. Выполнение во время сборки: Директива 'use cache' говорит фреймворку: "выполни этот fetch прямо сейчас, во время npm run build !!! ".

    2. Сохранение результата: Next.js делает запрос к API, получает ответ и сохраняет его в кеш (на диск или в CDN).

    3. Генерация HTML: Next.js берет полученные данные, рендерит их в HTML-строку

      Данные из кеша
      и вшивает этот HTML прямо в файл page.html.

    4. Результат: Пользователь, заходя на сайт, мгновенно получает готовую страницу с уже встроенным текстом “Данные из кеша”.

    💡Если данные нужны свежие, но каркас тоже нужен?

    Тут в игру вступает <Suspense> Он позволяет обмануть сборку.

    // ✅ Сборка проходит, данные свежие
    import { Suspense } from 'react';
    
    async function FreshData() {
      const data = await fetch('...'); // Нет 'use cache'
      return <div>{data}</div>;
    }
    
    export default function Page() {
      return (
        <main>
          <h1>Статический заголовок</h1>
          <Suspense fallback={<div>Загрузка данных...</div>}>
            <FreshData />
          </Suspense>
        </main>
      );
    }
    

    Как здесь помогает кеш? В этом примере кеша нет, но сборка всё равно проходит. Почему? Потому что физически вырезает проблемный компонент FreshData из процесса статической сборки.

    Во время build:

    1. Next.js рендерит <h1>Статический заголовок</h1>.

    2. Доходит до . Вместо того чтобы лезть внутрь FreshData, он просто записывает в HTML строку <div>Загрузка данных...</div>(то, что в fallback).

    3. Каркас готов! FreshData при сборке не вызывается вообще.

    4. Когда пользователь открывает страницу, он видит “Загрузка…”, а React на клиенте (или сервере при стриминге) запускает FreshData, получает свежие данные и заменяет заглушку на реальный контент.


    1 0 1 Ответить
  • GameFishG
    GameFish
    Pathologic 3: гайды по апатии и мании хитом, но туториалы отпугивают новичков

    Обложка: Pathologic 3: гайды по апатии и мании стали хитом но почему туториалы все равно отпугивают новичков

    Гайды по механике апатии и мании в Pathologic 3 разлетелись по сети - они стали спасением для игроков, пытающихся осилить выживание в Новом Мор. Эти туториалы объясняют ключевую систему настроения бакалавра Данковского, но базовые туториалы игры всё равно сбивают с толку новичков и повышают порог входа.

    Игроки хвалят внешние гайды за конкретику: как балансировать шкалу, избегать самоубийства от апатии или истощения от мании. Это важно, потому что без понимания механики первые часы игры превращаются в фрустрацию - персонаж ползёт улиткой или тает на глазах. Для Pathologic 3, где каждый день на счету, такие гайды меняют подход к прохождению.

    Шкала апатии и мании: как это работает

    В верхней части экрана видна шкала между апатией (синий конец) и манией (красный). Нейтральная зона по центру - безопасная, но редко держится сама по себе. Апатия растёт от безделья, стояния на месте или отвлечённых диалогов, замедляя движение до ползуна. На максимуме герой пытается самоубийство - нужно быстро жать клавиши, чтобы выжить, но урон всё равно берётся.

    Мания ускоряет бег, показывает путеводные линии в режиме концентрации (F), но жрёт здоровье - иконка сердца мигает. Высокая мания полезна для спринта через чумные зоны или бунты, если есть запас лекарств. Гайды подчёркивают: не бойся перекосов, если ресурсы под контролем.

    Способы контроля: таблетки, окружение, диалоги

    Контроль шкалы - комбо из расходников и окружения. Вот основные методы из гайдов:

    • Стимуляторы и табак разгоняют манию, морфин и седативы гасят апатию. Толерантность растёт, так что дозировку придётся увеличивать.
    • Окружение: пианино, скрипящие колонки повышают манию (красное свечение в F-режиме), качели и карусели успокаивают (синие). Обычно срабатывает раз.
    • Диалоги: жёсткие, торопливые ответы - к мании (экран мигает красным), отвлечённые болтовня - к апатии (синий). Предугадать можно в половине случаев.

    Гайды учат использовать перекосы тактически: морфин перед диалогом с риском мании или мания для рывка по карте.

    Почему туториалы игры проваливаются

    Встроенные туториалы не объясняют нюансы шкалы толком - новички игнорируют её, пока не влетят в ловушку апатии или не сдохнут от мании. Нет подсказок о тактическом использовании, толерантности или взаимодействии с диалогами. Игроки жалуются: система кажется наказанием, а не фишкой.

    Гайды заполняют пробелы, предлагая стратегии вроде перманентной мании с запасом хила или нейтрального баланса для квестов. Но это значит, что официальные туториалы отпугивают - новички уходят после часа путаницы, даже не дойдя до сути игры.

    Последствия для игроков и игры

    Для новичков гайды - must-read перед стартом: с них начинается реальное выживание, а не рандомная смерть. Pathologic 3 выигрывает от комьюнити-контента - он снижает отток, но подчёркивает слабость онбординга от разработчиков.

    Пока неизвестно, выйдет ли патч с улучшенными туториалами. Игроки продолжают полагаться на внешние ресурсы, что типично для артхаусных тайтлов с глубокими, но opaque механиками.


    0 0 0 Ответить
  • hannadevH
    hannadev
    Set vs filter/includes: убираем дубли ID товаров без тормозов на большом списке

    У тебя массив с тысячами ID товаров, и дубли плодятся как грибы после дождя. Хочешь их убрать быстро, без лагов в UI. Разберём Set против классики filter + includes - что взлетает на реальных данных, а что проваливается.

    Это не теория из доков. Поговорим про реальные бенчмарки, подкапотные циклы и когда O(1) спасает от фризов. Выберешь инструмент под задачу - спишь спокойно, без жалоб от юзеров.

    Почему includes тормозит на больших списках

    Array.includes ищет линейно - каждый вызов шарит по всему массиву с начала до конца. Для 10k элементов это O(n) на итерацию, а если зациклить в filter - вообще O(n^2). Представь: корзина с 5k ID, и ты фильтруешь дубли 100 раз в секунду на скролле.

    На мелких массивах разница незаметна, но при росте данных UI начинает чихать. Браузер тратит миллисекунды на каждый has, а их тысячи. Set.has же хэширует и находит за O(1) - просто брось массив в конструктор, и готово.

    Реальный кейс: список товаров из API, где ID повторяются из-за пагинации. Includes жрёт 200мс на 20k элементов, Set - 5мс. Переход меняет отзывчивость.

    • Линейный поиск в includes: каждый элемент проверяется заново, даже если дубли в начале.
    • Хэш-таблица в Set: мгновенный доступ по ключу, независимо от размера.
    • Память: Set жрёт чуть больше из-за хэш-мапы, но на 10k+ окупается скоростью.
    Подход Сложность Время на 10k элементов Время на 100k
    filter + includes O(n^2) ~150мс ~15с
    new Set(array) O(n) ~3мс ~25мс
    […new Set(filter)] O(n) ~5мс ~40мс

    Filter с Set: комбо для сложных случаев

    Часто нужно не просто дубли убрать, а отфильтровать по условию и дубли стереть. Классика - array.filter(item => allowedIds.includes(item.id)). Здесь includes снова бьёт по производительности, особенно если allowedIds большой.

    Создай Set из allowedIds заранее - new Set(allowed), потом filter(item => allowed.has(item.id)). has летает, filter остаётся читаемым. Для объектов с ID это золотая середина: не переписывай под Map полностью.

    Пример из жизни: таблица товаров, фильтр по категории + наличие. allowedIds из стора - 3k штук, основной список 15k. Без Set - лаги на каждой смене фильтра, с Set - мгновенно.

    • Подготовка: const uniqueIds = new Set(bigArray.map(id => id));
    • Фильтр: products.filter(p => uniqueIds.has(p.id));
    • Spread в массив: если нужен Array - […uniqueSet];

    Нюанс: Set хранит уникальные значения, для объектов нужен глубокий хэш или Map по ID.

    const duplicates = [1,2,2,3,1,4,5,5];
    const unique = [...new Set(duplicates)]; // [1,2,3,4,5]
    
    // Фильтр с Set
    const allowed = new Set([2,4,6]);
    const filtered = bigList.filter(id => allowed.has(id)); // O(n)
    

    Когда Set не панацея - альтернативы под капотом

    Set крут для примитивов, но с объектами или строками длинных ID хэш-коллизии могут подтормаживать. Плюс, если массив уже отсортирован - два указателя быстрее всего.

    Сортируй array.sort((a,b)=>a-b), потом иди двумя индексами: i и j. На пересечении дубли ловятся за O(n log n + n). Для ID товаров из БД часто уже sorted - профит.

    Ещё вариант: Map по ID для объектов. new Map(products.map(p => [p.id, p])). Доступ по ключу O(1), и дубли сами отсекаются при set.

    • Сортировка + указатели: идеал для sorted данных, без доп. памяти.
    • Map для объектов: сохраняет первую встреченную копию.
    • Reduce как костыль: работает, но читаемость хуже Set.
    Сценарий Лучший выбор Почему
    Примитивы ID Set O(1) lookup
    Объекты по ID Map Полный объект в значении
    Sorted массив Два указателя Нет хэша, минимум памяти
    Маленькие списки Includes Код проще, разница не видна

    Масштаб на миллионах - трюки из продакшена

    На 100k+ ID Set всё равно жрёт память - каждый entry 8 байт + overhead. Если UI рендерит таблицу, подумай о виртуальном скролле + ленивом unique.

    Разбей на чанки: process chunks по 10k, собирай Set по частям. Или используй WeakSet для GC-friendly, если ID временные.

    В реальном екоме: каталог 500k товаров, уникализация по сессии. Set на клиенте + debounce на ввод - фризы ушли, но следи за утечками при частых обновах.

    • Чанкинг: array.slice(0,1e4), Set, merge.
    • WeakSet: для disposable данных, GC чистит сам.
    • IndexedDB оффлайн: для персистентных больших списков.

    Тестируй в prod-like: Chrome DevTools Performance, реальные данные.

    Грабли, которые убивают перф даже с Set

    Забыл spread - Set не итерируется везде. Или создаёшь new Set в render-лупе Vue/React - перерендеры жрут CPU.

    Хуже: мутируешь оригинал .add() в цикле, теряешь реактивность. Делай копию заранее.

    Ещё засада - NaN и -0 в Set ведут себя как уникальные, хотя == false. Для числовых ID норм, но проверь.

    • Луп в рендере: вынеси в useMemo / computed.
    • Мутация: const copy = […set]; не трогай original.
    • Edge-кейсы: document.querySelectorAll в Set - NodeList не примитивы.

    Код без компромиссов

    Соберём итоговый snippet для типичного кейса: уникальные ID товаров из корзины + фильтр.

    function dedupeProductIds(products, allowedCategories) {
      const catSet = new Set(allowedCategories);
      const idSet = new Set();
      
      return products
        .filter(p => catSet.has(p.category))
        .filter(p => idSet.size < 10000 && idSet.add(p.id).size === 1) // лимит памяти
        .map(p => p.id);
    }
    

    Производительность на уровне, код читается. Масштабируй под свои данные.

    Что Set не заменит в архитектуре

    Set решает локальные дубли, но если уникальность из API - фиксай на бэке. Клиент не для тяжёлой логики.

    Подумай о нормализации стора: Map<id, product> в Redux/Zustand. Дубли исчезают по определению, поиск O(1). Для миллионных списков - шаг вперёд.


    0 0 0 Ответить
  • kirilljsxK
    kirilljsx
    Доменные LLM для разработчиков: кастомное обучение и CI/CD интеграция

    Обложка: Доменные LLM для разработчиков: как обучать кастомные модели на корпоративных данных и интегрировать в CI/CD

    Представьте: ваша команда тратит часы на разбор корпоративных документов, FAQ и внутренних регламентов, а чат-боты отвечают шаблонно и мимо кассы. Доменные LLM решают это на корню - дообучаем модель на ваших данных, и она выдает релевантные ответы по нишевой тематике, повышая точность на 12-25% без утечек в облако.

    Доменная LLM - это не игрушка, а инструмент для бизнеса. В отличие от универсальных моделей вроде GPT, которые жуют весь интернет и путаются в специфике (финансы, право, ремонт оборудования), доменные фокусируются на отрасли. Берем open-source базу вроде Llama 3 или DeepSeek-V3 (671B параметров, MoE-архитектура, бьет GPT-4.5 по матеше и коду), дообучаем на внутренних данных - диалогах, инструкциях, отчетах. Результат: бот понимает жаргон, генерит код под ваш стек, анализирует риски транзакций.

    Шаг 1: Подготовка данных - основа всего

    Данные - 80% успеха. Собираем анонимизированные диалоги, FAQ, регламенты. Чистим, структурируем с доменными экспертами. Инструменты: HuggingFace datasets для загрузки, SuperAnnotate для разметки (настраиваемые интерфейсы + ИИ-автоматизация).

    • Анонимизация: Убираем PII (личные данные) - критично для приватности.
    • Качество: Фильтруем шум, балансируем классы (например, типовые вопросы vs редкие кейсы).
    • Формат: Инструкции в стиле “Запрос: [текст]. Ответ: [релевантный].” для fine-tuning.

    Без этого модель будет галлюцинировать. В банке, скажем, научили на диалогах - и релевантность выросла на 25%.

    Шаг 2: Дообучение с PEFT - экономим ресурсы

    Полное обучение жрет GPU-фермы, но PEFT (Parameter-Efficient Fine-Tuning) меняет игру. LoRA-адаптеры трогают 1% параметров базовой модели, дообучаем на одной A100 за часы.

    Выбираем модели для корпоративного деплоймента 2026:

    Модель Параметры Плюсы Минусы
    DeepSeek-V3 671B (MoE) Бьет GPT-4.5 по коду/матеши, tool-calling Требует мощного железа
    GLM-4.5-Air 106B (MoE) Оптимизация под агентов, веб/код Меньше контекста (131K)
    Qwen3-235B 235B Универсал для RAG/агентов Лицензия под вопросом

    Практика: Python-скрипт для LoRA на HuggingFace. Устанавливаем: pip install transformers peft bitsandbytes datasets. Запускаем дообучение.

    from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments, Trainer
    from peft import LoraConfig, get_peft_model
    import torch
    from datasets import load_dataset
    
    model_name = "meta-llama/Llama-3-8B"
    model = AutoModelForCausalLM.from_pretrained(model_name, load_in_8bit=True)
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    
    dataset = load_dataset("json", data_files="your_corporate_data.json", split="train")
    
    def tokenize_function(examples):
        return tokenizer(examples["text"], truncation=True, max_length=512)
    
    tokenized_dataset = dataset.map(tokenize_function, batched=True)
    
    lora_config = LoraConfig(
        r=16, lora_alpha=32, target_modules=["q_proj", "v_proj"], lora_dropout=0.05
    )
    model = get_peft_model(model, lora_config)
    
    training_args = TrainingArguments(
        output_dir="./lora_adapter",
        num_train_epochs=3,
        per_device_train_batch_size=4,
        gradient_accumulation_steps=4,
        learning_rate=2e-4,
        fp16=True,
    )
    
    trainer = Trainer(model=model, args=training_args, train_dataset=tokenized_dataset)
    trainer.train()
    model.save_pretrained("corporate_llm_adapter")
    

    Это базовый пайплайн. Адаптер сохраняем отдельно - легко версионировать.

    Шаг 3: Интеграция в CI/CD - автоматизация на проде

    Дообучил - пора в прод. Развертываем on-premise: скачиваем модель на сервер с GPU (офис или корпоративное облако), интегрируем в CI/CD через GitHub Actions или GitLab CI.

    • Docker: Контейнерим с vLLM для инференса (быстрее TorchServe).
    • CI пайплайн: Тесты на датасете, валидация метрик (BLEU, ROUGE для текстов), автодеплой адаптера.
    • Kubernetes: Масштабируем под нагрузку, мониторим с Prometheus.
    • RAG-бонус: Добавляем векторный поиск (FAISS/Pinecone) для свежих данных без переобучения.

    Пример GitHub Action: на пуше в main - тест, дообучение на новых данных, деплой. Безопасность: все локально, без OpenAI-подобных утечек.

    В РФ это актуально: open-source тренд + локальные GPU позволяют обходить санкции, дообучать на своих серверах. Сервисы вроде DataFinder уже дают российскую инфраструктуру.

    Что дальше для вашей команды?

    Доменные LLM окупаются быстро: автоматизация документооборота, кодогенерация, бизнес-аналитика. Но ключ - в пайплайне: данные + PEFT + CI/CD. Не гонитесь за гигантами - начните с LoRA на 8B-модели, профит увидите через неделю.

    А вы уже дообучаете свои LLM на корпоративке? Как впихиваете в CI/CD и какие модели юзаете на проде? Делитесь в коммах, разберем кейсы вместе!


    1 0 0 Ответить
  • hannadevH
    hannadev
    Object.fromEntries против for: объект из формы за 3 строки вместо 20

    Каждый раз, когда форма на фронте вырастает до 10+ полей, код сбора настроек превращается в спагетти из циклов и условий. Вместо этого есть Object.fromEntries - метод, который из FormData делает чистый объект за одну строку. Это избавляет от boilerplate, утечек в ивент-лупе и бесконечных рефакторингов.

    Зачем копаться в forEach или reduce, если нативный API решает задачу чище? Размер бандла не растет, производительность на уровне, а код читается как конфиг. Сегодня разберем, как это работает под капотом и почему мидлы наступают на старые грабли с ручными циклами.

    Классический for-of: почему это костыль

    Когда форма простая - два-три инпута, никто не заморачивается. Но добавь селекты, чекбоксы, группы - и начинается. Ты проходишься for-of по элементам формы, проверяешь name, тип, значение. Если чекбокс не чекнут - вручную false впихиваешь. Радио-кнопки? Еще один if. Итог - 20 строк, где половина - edge cases.

    Под капотом это работает стабильно, но код разрастается линейно с числом полей. Добавь валидацию - еще 10 строк. А если форма динамическая, с клонируемыми блоками? Цикл ломается на дублирующихся name. Плюс каждый такой for - потенциальная утечка памяти, если забыл почистить ссылки на DOM. Реальный пример из легаси-проектов: объект настроек собирают в useEffect, и рендеры тормозят из-за лишних перестроений.

    Вот типичный шаблон, на который наступают:

    • Проверка if (element.name) - пропускаем безымянные элементы.
    • Для checkbox: obj[element.name] = element.checked.
    • Для select multiple: отдельный цикл по options.
    • Преобразование типов: parseInt или JSON.parse для сложных значений.
    Ситуация For-of строки Проблемы
    Простая форма (5 полей) 8-12 Уже boilerplate
    С чекбоксами/радио 15-25 Edge cases множатся
    Динамические поля 30+ Ломается на дублях

    Object.fromEntries: как это работает нативно

    Метод берет итерируемый объект пар [key, value] и лепит из него объект. Для форм идеально подходит FormData - она уже итерируется как надо. Object.fromEntries(formData) - и вуаля, чистый объект настроек. Никаких циклов, никаких if.

    Под капотом FormData реализует @@iterator, который выдает пары по name/value автоматически. Чекбоксы? Нативно false если не чекнуты. Select multiple? Массив значений. Даже file input кидает File объект без танцев. Производительность? На уровне reduce, но без аллокаций промежуточных массивов. В бенчмарках на больших формах fromEntries быстрее for-of на 20-30%, потому что движок оптимизирует итераторы лучше ручных циклов.

    Ключевые фичи, которые спасают:

    • Автоматическая обработка disabled полей - их просто нет в итераторе.
    • Поддержка append() для массивов в динамических формах.
    • Immutable результат - оригинальная FormData не мутируется.
    • Работает везде с ES2019, полифил не нужен в современных браузерах.

    Пример трансформации:

    const formData = new FormData(form);
    const settings = Object.fromEntries(formData); // { theme: 'dark', notify: 'true', items: ['a', 'b'] }
    

    Edge cases и как их фиксить без боли

    Не все формы идеальны - бывают кастомные name вроде ‘user[name]’, nested объекты или boolean флаги. Object.fromEntries кидает плоский объект, так что для nests нужен постпроцессинг. Но даже тут проще, чем в цикле: один Object.fromEntries + reduce для группировки.

    Представь форму с подгруппами: shipping[city], billing[zip]. Нативно получишь { ‘shipping[city]’: ‘Moscow’ }. Чтобы распаковать - пишешь mapper. Или используешь FormData.append с плоскими ключами заранее. Чекбоксы без значения? FormData их пропустит, так что дефолтный объект задаешь merge’ом: Object.assign(defaults, Object.fromEntries(formData)). Производительность не страдает - один проход.

    Типичные грабли и фиксы:

    • Дублирующиеся name (массивы): FormData сам собирает в array-like, fromEntries делает массив.
    • Nested keys: пост-обработка через пути вроде lodash.set, но лучше 3 строки на reduce.
    • Type coercion: new FormData сам парсит строки, для чисел - +value в mapper.
    • Empty form: возвращает {}, без ошибок.
    Проблема For-of фикс fromEntries фикс
    Чекбокс unchecked if (!checked) obj[name] = false defaults + merge
    Multiple select вложенный цикл нативный массив
    Nested поля ручной split/join reduce по паттерну

    Когда fromEntries выигрывает по производительности

    На мелких формах разница в 3 строки vs 10 - вопрос стиля. Но при 20+ полях или динамике код взрывается. Тестировал на форме с 50 полей: for-of жрет 1.2ms, fromEntries - 0.8ms в Chrome. В ивент-лупе на submit разница копится, особенно если валидация с ререндерами.

    Бонус: в React/Preact это идеально ложится в onSubmit. Нет нужды в сторонних libs вроде formik - нативно и быстро. Минус? Старые браузеры до ES2019, но их <1% трафика. Полифил - 2kb, но лучше feature detect. Под капотом движок использует тот же machinery, что и Object.entries, симметрично и предсказуемо.

    Фичи для перфоманса:

    • Нет промежуточных массивов - прямой итератор.
    • Оптимизировано V8 для частых вызовов в формах.
    • В комбо с structuredClone - безопасный сериализация настроек.

    Три строки, которые меняют рефакторинг

    Object.fromEntries сокращает не только строки, но и когнитивную нагрузку - фокусируешься на логике, а не на парсинге. Осталось за кадром: интеграция с URLSearchParams для query-строк или кастомные итераторы для legacy форм. Подумай, сколько for-of в твоем коде можно выкинуть - и бандл станет легче.

    В реальных проектах это правило: если >5 полей - fromEntries. Динамика? FormData + append в runtime. Главное - меньше ручных циклов, чище дебаг и меньше багов на граблях с типами.


    0 0 0 Ответить
  • GameFishG
    GameFish
    Pathologic 3: гайды по апатии и мании заменяют скучные туториалы

    Обложка: Pathologic 3: гайды по апатии и мании спасают новичков от туториалов

    Гайды по механике апатии и мании в Pathologic 3 стали спасением для новичков. Вместо чтения встроенных туториалов игроки сразу разбирают шкалу настроения Бакалавра и учатся выживать без лишней воды.Эти советы помогают быстро освоить баланс между замедлением от апатии и скоростью от мании, избегая самоубийств и потери здоровья. Для хардкорной игры от Ice-Pick Lodge это меняет подход: гайды дают практические тактики, а не спойлеры сюжета.## Шкала апатии и мании: как это работает

    В Pathologic 3 верхняя часть экрана показывает шкалу, где центр - нейтральное состояние для Даниила Данковского. Сдвиг влево - апатия, вправо - мания. Апатия растет от безделья или отвлеченных разговоров, мания - от прямолинейных реплик.Апатия замедляет движение: на максимуме Бакалавр пытается самоубийство с QTE-событием. Даже успех дает урон, но сбрасывает шкалу. Мания ускоряет персонажа, идеально для чумных районов или бунтов, но истощает здоровье - мигает иконка сердца.Не всегда цель - центр шкалы. Иногда полезно качнуть в крайность: морфин перед эмоциональным диалогом повышает апатию, чтобы не скатиться в манию.## Тактики управления из гайдов

    Гайды учат использовать окружение и предметы. Режим концентрации (F) подсвечивает объекты: красное - для мании (баки, ящики), синее - для апатии.Ключевые способы баланса:

    • Табак или стимуляторы разгоняют манию.
    • Морфин и седативы успокаивают апатию.
    • Диалоги: жесткие ответы - мания, болтовня - апатия.- В клетке на пятый день апатия растет сама - борись манией медикаментами.Высокая мания с запасом лекарств позволяет носиться по карте, экономя время. Толерантность растет, так что ресурсы тратятся быстрее.## Почему гайды лучше туториалов
    Встроенные подсказки в Pathologic 3 минимальны и философские, не объясняют механики четко. Гайды от сообщества дают списки, таблицы рисков и тактики без спойлеров сюжета.Для новичков это критично: игра - квест с выживанием, где апатия/мания влияет на диалоги, скорость и исходы. Гайды показывают, как не умирать глупо в первые дни. Состояние Эффект Как использовать
    Апатия max Самоубийство QTE Перед диалогами с манией
    Мания max Скорость + урон HP Чумные зоны, тайминги ## Перспективы и что дальше

    Гайды продолжают множиться: от демо до полного прохождения. Пока неясно, как патчи изменят баланс толерантности или QTE. Но механика остается ключевой для Бакалавра - без нее Новый Мор съест новичков за час.


    0 0 0 Ответить
  • hannadevH
    hannadev
    Set vs Array: удаляем дубликаты в тегах без лишних костылей

    Когда нужно обработать теги поста и оставить только уникальные значения, половина разработчиков тянется к привычным методам массивов, а потом удивляется, почему код работает медленнее, чем хотелось бы. На самом деле задача решается в одну строку, если знать нужный инструмент.

    В этой статье разберёмся, почему Set - это не просто красивое решение, а настоящий выигрыш по производительности. Посмотрим, как он работает под капотом, какие ошибки подстерегают новичков, и когда Array всё же может быть полезнее.

    Чем Set отличается от Array

    Массив - это индексированная коллекция. Значения упорядочиваются по позиции: нулевой элемент, первый, второй. Каждый раз, когда нужно проверить, есть ли уже такой элемент, приходится либо использовать indexOf(), либо перебирать весь массив циклом. Для массива с тысячей тегов это быстро становится боль.

    Set - это совсем другое животное. Это коллекция ключей, где каждое значение хранится только один раз. Когда вы пытаетесь добавить дубликат, Set просто его проигнорирует. Нет никаких проверок перед вставкой - это встроено в саму структуру данных.

    • Индексированность: Array упорядочивает по индексам (0, 1, 2…), Set упорядочивает по ключам
    • Уникальность: Array хранит всё, Set автоматически отбрасывает дубликаты
    • Производительность проверки: Array требует линейного поиска, Set проверяет за O(1)
    • Порядок элементов: Оба сохраняют порядок вставки, но только Array позволяет быстро обратиться по индексу

    Как Set обрабатывает примитивы и объекты

    Вот тут начинается самое интересное. Set работает с примитивами (строки, числа, boolean) по значению, а с объектами по ссылке.

    Если у вас массив тегов вроде ['react', 'vue', 'react', 'angular'] - Set справится за миллисекунду. Преобразовываем в Set и обратно в массив:

    const tags = ['react', 'vue', 'react', 'angular'];
    const uniqueTags = [...new Set(tags)];
    // Результат: ['react', 'vue', 'angular']
    

    Но если вы решили хранить теги как объекты {name: 'react'}, вот тут Set ловит косяк. Даже если два объекта выглядят идентично, это разные ссылки в памяти:

    const tagObjects = [{id: 1}, {id: 1}, {id: 1}];
    const uniqueTagObjects = new Set(tagObjects);
    console.log(uniqueTagObjects.size); // 3, не 1!
    

    Почему так? Потому что Set сравнивает объекты по ссылке, а не по содержимому. Каждый {id: 1} - это разные адреса в памяти. Если вам действительно нужно дедублицировать объекты, придётся писать свою логику или использовать Map с кастомным ключом.

    • Примитивы: Сравниваются по значению - два одинаковых числа считаются дубликатом
    • Объекты: Сравниваются по ссылке - два объекта с одинаковыми свойствами это разные элементы
    • Смешанные типы: 1 (число) и '1' (строка) - разные значения, Set оба сохранит
    • Null и undefined: Сохраняются по одному экземпляру

    Производительность: цифры говорят сами за себя

    Если вы слышали, что Set быстрее - это не маркетинг, это факт. Тесты на реальных объёмах данных показывают: Set быстрее Array с filter в десятки раз, а reduce в сотню раз.

    Когда вы вызываете arr.indexOf() или arr.includes() для проверки наличия элемента, браузер проходит весь массив с начала. Это O(n) операция. Повторяем проверку для каждого элемента - получаем O(n²). Set использует хеш-таблицу внутри и проверяет за O(1). Для массива из тысячи элементов разница измеряется в порядках величины.

    Сравните эти подходы:

    Подход Код Скорость
    Set [...new Set(arr)] Базовая
    Filter + indexOf arr.filter((v, i) => arr.indexOf(v) === i) ~10x медленнее
    Reduce arr.reduce((acc, v) => acc.includes(v) ? acc : [...acc, v], []) ~100x медленнее
    Цикл с проверкой for + arr.includes() ~20x медленнее
    // Измеряем самый быстрый способ
    const testArray = Array.from({length: 10000}, (_, i) => i % 100);
    
    console.time('Set approach');
    const result1 = [...new Set(testArray)];
    console.timeEnd('Set approach'); // ~1ms
    
    console.time('Filter approach');
    const result2 = testArray.filter((v, i) => testArray.indexOf(v) === i);
    console.timeEnd('Filter approach'); // ~50ms
    

    Методы Set для работы с тегами

    Kогда вы знаете, какие методы есть, работать с Set становится проще. Вот что вам нужно для обработки тегов:

    • set.add(value) - добавить тег в множество, дубликаты игнорируются автоматически
    • set.has(value) - проверить, есть ли тег уже в множестве (быстро, за O(1))
    • set.delete(value) - удалить конкретный тег
    • set.clear() - очистить всё множество
    • set.size - узнать количество уникальных тегов

    Практический пример - обработка тегов поста:

    const postTags = new Set();
    
    // Добавляем теги пользователя
    postTags.add('javascript');
    postTags.add('frontend');
    postTags.add('javascript'); // Игнорируется
    
    // Проверяем наличие
    if (postTags.has('javascript')) {
      console.log('Тег уже есть');
    }
    
    // Итерируем в порядке добавления
    postTags.forEach(tag => console.log(tag));
    // javascript, frontend
    
    // Удаляем ненужное
    postTags.delete('frontend');
    console.log(postTags.size); // 1
    

    Итерация всегда происходит в порядке вставки элементов. Это важно - если вы хотите сохранить порядок тегов, как их вводил пользователь, Set не подведёт.

    Когда Array ещё может быть полезен

    Не преувеличивайте, Set - не серебряная пуля. Есть сценарии, где Array всё ещё нужен.

    Если вам нужно частно обращаться по индексу - Array выигрывает. tags это O(1), а из Set элемент по номеру не достать. Также если вы работаете с очень маленькими коллекциями (пара десятков элементов), производительность Set не будет видна, а код может быть понятнее с привычным Array.

    Для древних браузеров (IE10 и ниже) Set просто не существует - придётся fallback’ить на Array. И если вы делаете какой-то специфический обход или трансформацию данных, Array методы могут быть удобнее.

    // Array vs Set: когда Array проще
    const tags = ['react', 'vue', 'angular'];
    
    // Нужна трансформация каждого элемента
    const tagsByLength = tags.map(tag => tag.length);
    // Set это не может делать встроенно
    
    // Нужна фильтрация по условию
    const longTags = tags.filter(tag => tag.length > 5);
    // Set тоже не может
    
    // Нужен доступ по индексу
    const firstTag = tags;
    // Set заставит конвертировать в массив
    

    Практический паттерн: обработка тегов поста

    Большинство задач с дедупликацией тегов решаются одинаково. Вот универсальный подход, который работает в 90% случаев:

    function getUniqueTags(rawTags) {
      // rawTags может быть грязным - с пробелами, дубликатами, пустыми строками
      return [
        ...new Set(
          rawTags
            .map(tag => tag.trim().toLowerCase())
            .filter(tag => tag.length > 0)
        )
      ];
    }
    
    const userInput = ['React', 'REACT', ' vue ', '', 'Angular', 'react'];
    const cleanTags = getUniqueTags(userInput);
    console.log(cleanTags);
    // ['react', 'vue', 'angular']
    

    Всё чётко: сначала нормализуем данные через map и filter, потом Set отрезает дубликаты, потом разворачиваем обратно в массив.

    • Нормализация перед Set: Приводим к одному формату (lowercase, trim), убираем пустоту
    • Set деплицирует: Одна операция, всё работает
    • Разворот в массив: Если нужен массив дальше, используем spread или Array.from()
    • Сохранение порядка: Set гарантирует порядок вставки

    На чём не стоит зацикливаться

    Есть несколько заблуждений, которые прилипают к Set. Первое - что Set это чудо-решение для всего подряд. Нет, это инструмент для конкретной задачи. Второе - что объекты в Set как-то магически дедублицируются. Нет, они сравниваются по ссылке, и это нормально.

    Третье заблуждение - что нужны сложные полифиллы для старых браузеров. Set поддерживается везде, где нужно (IE11+, современные браузеры). Если вы ещё поддерживаете IE10, это вообще отдельная проблема, не только для Set.

    И последнее - что производительность Set магична в каждом случае. Set быстрее именно на проверках уникальности и дедупликации больших объёмов. На маленьких массивах разница незаметна.


    0 0 0 Ответить
  • GameFishG
    GameFish
    Pathologic 3: рейтинг 87% на Steam, но критики не стихают через 3 месяца

    Обложка: Pathologic 3: рейтинг подскочил до 87% но критика не утихает после трех месяцев

    Pathologic 3 вышел три месяца назад и быстро набрал 87% положительных отзывов на Steam. Несмотря на высокий рейтинг, споры в сообществе не утихают - игроки продолжают разбирать сильные и слабые стороны игры.

    Это важно для фанатов серии, потому что Pathologic всегда делил аудиторию на лагеря: кто-то видит в ней шедевр атмосферы и нарратива, а кто-то - непроходимый бардак геймплея. Подъем рейтинга показывает, что третья часть зацепила больше народу, но критика по ключевым аспектам держится крепко, заставляя задуматься, стоит ли заходить новичкам или возвращаться ветеранам.

    Рейтинг и динамика отзывов

    Pathologic 3 стартовал с смешанными реакциями, но со временем рейтинг подскочил до 87%. Это произошло за счет притока новых игроков, привлеченных атмосферой и сюжетом. Однако свежие обзоры все равно полны замечаний.

    Общий подъем связан с несколькими факторами:

    • Атмосфера и нарратив: Многие хвалят историю, написанную в соавторстве с командой, что добавило глубины по сравнению с предыдущими частями.
    • Технические улучшения: Оптимизация под современное железо и Steam сделали игру доступнее.
    • Долгая поддержка: Разработчики из Ice-Pick Lodge выпустили патчи, исправившие баги на запуске.

    Несмотря на цифры, негатив держится на уровне 13% - это отзывы от тех, кто не смог переварить кор-механики.

    Основные точки критики

    Критика не утихает по нескольким фронтам, и это не просто нытье хейтеров. Игроки три месяца копают вглубь, разбирая, где игра провисает.

    • Геймплейные косяки: Сложность выживания все такая же адская, но управление и интерфейс все еще сырые. Многие жалуются на неудобную инвентаризацию и медленный темп.
    • Сюжетные линии: Множество веток квестов хвалят за нелинейность, но часть игроков называет их запутанными, с необязательными провалами.
    • Технические проблемы: Хотя патчи помогли, на слабом ПК фризы и вылеты остаются. Консольные версии тоже под вопросом - пока только ПК.

    Таблица сравнения отзывов по платформам (на основе Steam-данных):

    Аспект Положительные отзывы Отрицательные отзывы
    Атмосфера 92% 5%
    Геймплей 78% 18%
    Графика 85% 10%
    Сюжет 89% 8%

    Реакция сообщества и разработчиков

    Сообщество раздвоилось: ветераны Pathologic радуются эволюции серии, новички делятся мемами о “мор” и провалах. Форумы вроде DTF полны разборов - от восторгов по саундтреку до фрустрации от пермадета.

    Разрабы из Ice-Pick Lodge отреагировали патчами и обещаниями доработок. Алексей Поляков (он же Поляринов) делился тревогами перед релизом, но сейчас фокус на контенте. Пока не подтверждено:

    • Выход на консоли.
    • Новые DLC или сюжетные обновления.
    • Глобальный ремастер первой части.

    Это держит хайп, но и раздражает тех, кто ждет конкретики.

    Итог споров

    Через три месяца Pathologic 3 стоит крепко на 87%, подтверждая статус нишевой жемчужины. Критика по геймплею и техчасти не сломала рейтинг, но показывает, куда смотреть Ice-Pick Lodge. Для игроков это сигнал: если атмосфера и нарратив в приоритете - берите, иначе подождите патчей.


    0 0 0 Ответить
  • kirilljsxK
    kirilljsx
    AI-native платформы: как ИИ меняет процесс разработки

    Обложка: AI-native платформы для разработчиков: как писать код поверх ИИ и не сломать SDLC

    Проблема: разработчиков не хватает, сроки горят, рутина убивает

    Реальность такова - дефицит разработчиков только растет, а заказчики требуют результатов вчера. Классический SDLC с его водопадом, спринтами и code review начинает выглядеть как средневековье, когда у тебя есть ИИ, который может писать тесты, архитектуру и даже генерировать документацию. Проблема в том, что большинство команд до сих пор используют ИИ как помощника - ставят Copilot в IDE и ждут чуда. А это не работает. Нужно переосмыслить сам процесс разработки с нуля.

    AI-native платформы - это не Copilot в VS Code. Это полноценные среды разработки, где генеративный ИИ встроен на уровне инфраструктуры: от генерации кода до деплоя, тестирования и даже проектирования архитектуры.

    Как это вообще работает на практике

    Представь, что ты говоришь платформе: “Сделай CRM для ритейла с интеграцией БД”. На выходе платформа собирает тебе стек - React на фронте, Node.js на бэке, PostgreSQL в качестве БД. Но это не просто каркас. Автоматически добавляются:

    • Генерация кода для основных операций
    • Тесты (unit и интеграционные)
    • CI/CD конфиги
    • Базовая документация
    • Даже проверка безопасности

    Теоретически, команда из 3-5 человек может создавать то, что раньше требовало 20-30 разработчиков. И Gartner не шутит - к 2030 году 80% организаций будут использовать именно такую модель.

    ТОП инструментов в 2026 году

    Практически используемые платформы делятся на несколько категорий:

    Облачные платформы с нативной поддержкой ИИ:

    • SiliconFlow - универсальная облачная платформа с бессерверным выводом и выделенными GPU (NVIDIA H100/H200). Подходит, если нужна высокая пропускная способность и полная поддержка LLM
    • Microsoft Azure - корпоративный монстр с прямой интеграцией OpenAI, чипом MAIA 100 и бесшовным подключением к Microsoft-экосистеме. Если в компании уже Office 365 и Teams - это выбор
    • AWS + Google Cloud - классика, но требует больше ручной настройки

    IDE и редакторы для разработчиков:

    • Claude Code - #1 по рейтингам разработчиков в 2026. Почему? Потому что Claude хорош в понимании контекста и не генерирует откровенный мусор
    • Cursor - лучший AI-редактор для повседневной работы. Интегрируется с твоим стеком, понимает твой проект
    • Windsurf - лидер по версии LogRocket, специализируется на IDE-опыте

    No-code/Low-code платформы для MVP:

    • FlutterFlow - конструктор мобильных приложений с возможностью экспорта кода на React Native. Важно: ты не заперт внутри платформы, можешь взять код и дорабатывать вручную
    • OnSpace.AI - максимально быстрый запуск. Описываешь идею, платформа собирает фронт, логику и базу данных
    • Draftbit - для тех, кто хочет больше контроля. Визуальная сборка + работа с логикой на уровне, близком к реальной разработке

    Как организовать workflow, чтобы не сломать всё

    Вот тут начинается интересное. Просто взять и использовать ИИ везде - это рецепт хаоса.

    GitHub Agent HQ (февраль 2026) дал нам классный пример: запусти Claude, Codex и Copilot одновременно на одной задаче, каждый оценит компромиссы по-своему, а затем выбери лучший вариант.

    На практике успешные команды организуют работу так:

    1. Отдельные агенты для отдельных задач: один для code review, другой для генерации тестов, третий для проверки безопасности, четвёртый для деплоя
    2. Каждый агент специализируется на своём, но все работают согласованно
    3. Человек остаётся в loop для критических решений и архитектурных выборов

    При этом обязательно нужно установить правила ограниченной автономии для ИИ-агентов в продакшене. Иначе получишь ситуацию, когда система сама решила refactorить production код в 3 ночи.

    Практический пример: система промптирования для code generation

    Вот системный промпт, который реально работает для генерации кода через ИИ:

    Ты - Senior Full-Stack Developer.
    
    Когда ты пишешь код:
    1. Всегда добавляй type hints (TypeScript/Python)
    2. Логируй критические операции (DB queries, API calls)
    3. Генерируй unit-тесты параллельно с кодом
    4. Предполагай, что код может упасть - добавляй error handling
    5. Для API endpoints - генерируй примеры запросов в документацию
    
    Что НЕ делай:
    - Не генерируй код без валидации входных данных
    - Не создавай SQL-запросы через конкатенацию строк
    - Не забывай о CORS и security headers
    - Не генерируй пароли или секреты в code
    
    Дополнительные требования:
    - Node.js + TypeScript для бэка
    - React + TypeScript для фронта
    - PostgreSQL для БД
    - Придерживайся REST API standards
    

    Да, это звучит как обычный code review-лист. Потому что это и есть code review, только в виде инструкции ИИ.

    Реальность для российского рынка

    Отличная новость - большинство платформ работают. Плохая - западные решения (Claude, ChatGPT, Gemini) имеют ограничения доступа из РФ из-за санкций. Но DeepSeek занимает второе место по доле российской аудитории среди ИИ-чатботов, а отечественные решения типа GigaChat от Сбера и Яндекс.Алиса уже разворачиваются под разработку. Облачные платформы вроде SiliconFlow работают и имеют поддержку доменных LLM.

    Так что если ты в РФ - используй то, что доступно. DeepSeek + локальные облачные платформы + open-source модели - это реальное направление прямо сейчас.

    Вопрос к аудитории

    А как вы организуете процесс работы с ИИ в разработке? Используете отдельные агенты для отдельных задач или пока стоите на классическом коде с Copilot? И главное - в какой момент вы поняли, что ИИ-генерируемый код стал настоящей проблемой, а не помощью?


    0 0 0 Ответить
  • kirilljsxK
    kirilljsx
    6G для ИИ-разработчиков: настройка роботов и AR/VR в 2026 году

    Обложка: 6G-инфраструктура для разработчиков ИИ: как настраивать приложения для роботов и AR/VR в 2026

    Представьте: ваш робот на складе теряет миллисекунды на задержку в сети, и вся цепочка поставок стоит. Или AR-очки в VR-тренировке лагают, клиенты уходят к конкурентам. 6G решает это радикально: задержка в миллисекунды, гигабитные скорости и ИИ прямо в сети. Для разработчиков ИИ это значит приложения для роботов и AR/VR, которые работают как часы, без компромиссов. В 2026 стандарты 6G стандартизируются, прототипы уже тестят, а Nvidia собирает альянс для AI-RAN.

    Ключевые фичи 6G для ИИ-приложений

    6G - это не просто быстрее 5G. Это инфраструктура для физического ИИ: дроны, роботы, AR/VR с сенсорным восприятием. Основное:

    • Задержка 1-2 мс: критично для робототехники и голографической связи. Робот реагирует мгновенно на команды.
    • Скорости до 16+ Гбит/с: прототипы Qualcomm уже показывают 16,6 Гбит/с вниз. AR/VR стримы 8K без буферинга.
    • AI-RAN: ИИ в ядре сети от Nvidia. Автооптимизация трафика, предиктивное покрытие.
    • Гибридные вычисления: edge + cloud + device. Данные с сенсоров обрабатываются на периферии.
    • Многослойное покрытие: наземные + спутниковые сети для seamless handover.

    В России прорывы есть: инновационные материалы для 6G, планы Роскомнадзора на ИИ в радиоинтерфейсе и AR для погружения. Сколтех и ВШЭ пилотируют цифровые двойники сетей.

    Настройка приложений: практика для роботов и AR/VR

    Разработчики, пора адаптировать код под 6G API. Ожидайте открытые стандарты с встроенным ИИ. Для роботов - реал-тайм контроль, для AR/VR - мультисенсорный фид.

    Вот пример на TypeScript для мобильного AR-аппа с 6G edge-вычислениями. Используем WebRTC + гипотетический 6G SDK (на базе 5G NSA, эволюционирует в 2026).

    import { EdgeAIClient } from '@6g-edge/sdk'; // Прототип SDK от Qualcomm/Nvidia
    
    import type { SensorData, ARFrame } from './types';
    
    class RobotARController {
      private client: EdgeAIClient;
    
      constructor(networkId: string) {
        this.client = new EdgeAIClient(networkId, {
          latencyTarget: 1.5, // мс
          aiOptimization: true // AI-RAN автонастройка
        });
      }
    
      async processRobotFrame(sensorData: SensorData): Promise<ARFrame> {
        // Сенсоры -> edge ИИ -> AR оверлей
        const optimized = await this.client.infer(sensorData, {
          model: 'physical-ai-robot',
          computeSplit: 'edge-heavy' // 80% на периферии
        });
    
        return {
          overlay: optimized.visuals,
          commands: optimized.actions // Для робота
        };
      }
    
      // Реал-тайм стрим для VR
      startARStream(callback: (frame: ARFrame) => void) {
        this.client.stream('ar-vr-channel', (data) => {
          callback(this.processRobotFrame(data));
        });
      }
    }
    
    // Использование
    const controller = new RobotARController('ru-6g-pilot');
    controller.startARStream((frame) => console.log('AR ready:', frame));
    

    Этот код подключается к 6G RAN, делегирует ИИ на edge (нейроморфные чипы в планах), минимизирует latency. Для Python аналог на FastAPI + 6G libs от Huawei/Nokia. Тестируйте на 5G-тестбедах сейчас - профит в проде.

    Фича 5G 6G Выгода для ИИ
    Latency 10-20 мс 1-2 мс Роботы без сбоев
    Скорость 1-10 Гбит/с 16+ Гбит/с 8K AR/VR стримы
    ИИ-интеграция Опционально В ядре (AI-RAN) Автооптимизация

    Вызовы и реальность для РФ

    В 2026 стандартизация в разгаре, Qualcomm целит Олимпиаду-2028. Россия отстает в коммерции, но лидирует в материалах и ИИ для спектра. Для бизнеса в РФ: пилоты в Москве/СПб через МТС/Роскомнадзор. Импорт чипов под санкциями - фокус на отечественные аналоги от HSE. Стоит ли инвестировать? Да, если вы в робототехнике или enterprise AR - ROI через 2-3 года за счет edge ИИ.

    Что дальше для ваших проектов?

    6G меняет игру: от лагов к физическому ИИ. Инвестируйте в SDK сейчас, тесты на прототипах дадут edge над конкурентами. А вы уже мигрируете роботов/AR на 6G-ready стек? Какие latency-боли в проде и как решаете? Делитесь в комментах - разберем кейсы вместе!


    0 0 0 Ответить
  • hannadevH
    hannadev
    Object.entries + Map против for: парсинг плоского JSON в группы за 5 строк кода

    API часто кидает плоский JSON - сплошной массив объектов без группировки. Хочешь по категориям разложить - пишешь for на 50 строк с if-ами и push. А можно Object.entries + Map за 3-5 строк. Это решает проблему раздутого кода и утечек в логике.

    Зачем это нужно: группировка ускоряет рендер списков, фильтры и поиск. Без нее фронт тонет в nested циклах. Покажу, как парсить заказы по статусам или товары по брендам - чисто, без костылей.

    Плоский JSON из API: типичная яма

    API возвращает массив заказов: каждый объект с id, status, amount, date. statuses - это ‘pending’, ‘shipped’, ‘delivered’. Хочешь сгруппировать по статусам для дашборда. Ручной for: проверяешь status, пушить в массив группы, нуляешь счетчики. Легко накосячить - забыть else, дубли push или off-by-one в индексах.

    Пример данных:

    const orders = [
      {id:1, status:'pending', amount:100},
      {id:2, status:'shipped', amount:200},
      {id:3, status:'pending', amount:150}
    ];
    

    В итоге groups = {pending: , shipped: […]}. Но код разрастается: if для каждого status, else для default. А если статусов 10? Boilerplate душит.

    • Проблема 1: Ручной for не масштабируется - добавь статус, допиши if.
    • Проблема 2: Легко сломать порядок вставки или пропустить элемент.
    • Проблема 3: Нет size или быстрого .has() - приходится Object.keys().length.
    Подход Строк кода Масштабируемость Ошибки
    for + if 30-50 Плохо Часто
    Map 3-5 Отлично Минимально

    Object.entries: почему это твой новый друг

    Object.entries(obj) выдает [[key, value]] - готовый массив для Map или reduce. Из плоского объекта в итерируемый формат за 1 строку. Идеально для JSON.parse, где ключи строковые, а значения - любые.

    Пример: у тебя конфиг {theme:‘dark’, lang:‘ru’}. entries дает [[‘theme’,‘dark’], [‘lang’,‘ru’]]. Теперь forEach или map - как по масиву. Без entries пришлось бы for…in с hasOwnProperty - легаси 2010-х.

    Ключевой трюк: new Map(Object.entries(flatObj)). Map сохраняет порядок вставки, ключи любого типа (не только строки, как в объекте).

    • entries vs keys: keys() - только ключи, теряешь значения. entries - полная пара.
    • Нюанс: entries не рекурсивно - только own properties, прототипы игнорит.
    • Когда entries выигрывает: группировка, где ключ - динамический (userId, timestamp).
    const config = {theme:'dark', lang:'ru'};
    const mapConfig = new Map(Object.entries(config));
    console.log(mapConfig.get('theme')); // 'dark' - O(1)
    

    Map для группировки: 5 строк вместо 50

    Берем плоский массив orders. Цель: groups = new Map(), где ключ - status, значение - массив заказов. Ручной способ: forEach с if status === ‘pending’ ? groups.pending.push : else if…

    С Map: orders.forEach(order => { const group = groups.get(order.status) || []; group.push(order); groups.set(order.status, group); }). 4 строки. Или one-liner с reduce.

    Полный код:

    const groups = orders.reduce((acc, order) => {
      const group = acc.get(order.status) || [];
      group.push(order);
      acc.set(order.status, group);
      return acc;
    }, new Map());
    

    Map.get/set - быстрее Object[key], особенно с нестроковыми ключами.

    • Преимущество 1: Map сохраняет порядок вставки - первый pending будет первым в массиве.
    • Преимущество 2: .size вместо Object.keys().length - короче, быстрее.
    • Преимущество 3: .delete(key) - чисто удалить группу без undefined.
    Операция Object Map
    Получить размер Object.keys(obj).length obj.size
    Проверить ключ ‘key’ in obj obj.has(‘key’)
    Удалить delete obj.key obj.delete(‘key’)
    Итерация for…in for…of obj.entries()

    Таблица сравнения: for vs entries + Map

    Ручной for хорош для 2-3 групп. Добавь ‘cancelled’, ‘refunded’ - код мутирует в монстра. entries + Map - динамично: статусы из данных, без hardcode.

    Бенчмарк на 10k items: for ~15ms, Map ~12ms. Разница в реальном app - в читаемости и багфиксах. Map не ломается при NaN ключах или Symbol.

    Реальный кейс - парсинг логов API: group by endpoint, count errors.

    • For: if (item.status === ‘error’) errors++; else if…
    • Map трюк: new Map().set(endpoint, (map.get(endpoint)||0) +1 )
    • fromEntries обратно в obj: Object.fromEntries(groups) - для localStorage.
    Сценарий Ручной for Map-вариант Выигрыш
    5 статусов 40 строк 4 строки x10 короче
    Динамические ключи Переписать Работает Без багов
    Фильтр + group Nested loops chain .filter().reduce Читаемо

    Когда Map под капотом ломается

    Map жрет памяти под хеш-таблицу - для 1M items подумай WeakMap. Но для фронта (до 50k) - ок. Не сериализуется в JSON напрямую - stringify(Map) = {}. Фикс: Object.fromEntries(map.entries()).

    Итерация: for (let [status, list] of groups) renderList(list). Порядок как в данных - не как Object.keys (enum order).

    Подведем: entries + Map - антидот boilerplate в парсинге. Осталось за кадром: группировка по нескольким полям (composite key как ${cat}-${brand}) и интеграция с React/Vue keys. Подумай, где в твоем коде висит for на 50 строк - замени, сэкономь час дебага.


    0 0 0 Ответить
  • kirilljsxK
    kirilljsx
    Angular 2026: от корпоративного монстра к быстрому фреймворку с супер-рендерингом

    Обложка: Angular 2026: от корпоративного монстра к быстрому фреймворку с супер-рендерингом и легким дебагом

    Представьте: ваш корпоративный фронтенд на Angular жрет 200+ МБ на загрузку, SSR тормозит как черепаха, а дебаг - сплошной ад с зонами и Observable. Бизнес стонет от медленных лидов, разрабы тратя время на костыли вместо фич. Angular 2026 это меняет: Zoneless по умолчанию, Signals в ядре, супер-рендеринг и дебаг как в React. Теперь билд летает, apps весят в разы меньше, а код чище без NgModules.

    Супер-рендеринг: SSR + Hydration на стероидах

    Angular 21+ сделал Zoneless Change Detection стандартом. Нет больше Zone.js, который пухнул бандлы и путал дебаг. Signals заменяют RxJS в простых кейсах: реактивность без подписок, эффекты пересчитываются только по зависимостям. Результат? Гидратация в 2-3 раза быстрее, TTI (Time to Interactive) падает до 1-2 сек даже на слабых девайсах.

    Плюс component-level code splitting: каждый роут лениво грузится, tree-shaking вырезает мертвый код на уровне компонентов. В продакшене ng build генерит dist/ с минифицированными чанками, где серверный рендер (node dist/server/server.mjs) работает из коробки. Бизнесу профит: SEO на высоте, Core Web Vitals зеленые, конверсия растет.

    Легкий дебаг: Signals и Standalone без boilerplate

    Забудьте модули: Standalone Components - норма. Импортируешь прям в bootstrap, DI работает через providers в компоненте. Signals упрощают стейт: сигнал меняется - view обновляется только там, где нужно. Нет диффов по всему дереву.

    Пример простого контрола с Signals (TypeScript, Angular 21+):

    import { Component, signal, effect, computed } from '@angular/core';
    
    @Component({
      selector: 'app-counter',
      standalone: true,
      template: `
        <p>Count: {{ count() }}</n>
        <p>Double: {{ double() }}</p>
        <button (click)="increment()">+</button>
      `
    })
    export class CounterComponent {
      count = signal(0);
      double = computed(() => this.count() * 2);
    
      constructor() {
        effect(() => console.log(`Count changed to: ${this.count()}`));
      }
    
      increment() {
        this.count.update(v => v + 1);
      }
    }
    

    Здесь effect логирует изменения автоматически, без ручных destroy. Дебаг в DevTools: signals видны как reactive graph, ошибки локализованы. В Vite-билде (новый дефолт) хот-рилоад секунды.

    От монстра к ракете: миграция и реалити

    Миграция с 13-19 на 21+? Реально за 2-3 спринта: CLI миграции чистят NgModules, добавляют signals. Команды типа Compo B2B прошли это - код стал декларативнее, релизы не пугают. Webpack под капотом оптимизирует AOT, minify и bundling - apps летают на любом хостинге.

    В РФ это актуально: банки, e-com и госкорпорации на Angular сидят годами. С Zoneless и SSR деплой на Yandex Cloud или VK Cloud проще, latency падает. Минус? RxJS еще нужен для сложных потоков, но signals его вытесняют. Стоит учить - вакансий море, зп от 300k.

    Что дальше для вашего стека?

    Angular 2026 - не хайп, а рабочий инструмент для масштаба. Он экономит время разрабов на дебаге, деньги бизнеса на инфраструктуре. Перешли на signals + standalone? Как SSR влияет на ваши метрики? Делитесь в коммах: мигрировали ли вы, или держитесь за старый Angular? Давайте обсудим реальные кейсы.


    0 0 0 Ответить
Популярные темы:

  • Критическая уязвимость в React.js Next.js (CVE-2025-55182, CVE-2025-66478): Как защитить свой сайт
    AladdinA
    Aladdin
    7
    12
    1.3k

  • Полный гайд по работе с NodeBB CLI
    D
    DeepSeeker
    6
    3
    161

  • for или foreach в javascript: в каких случаях что использовать
    D
    DeepSeeker
    5
    2
    171

  • Подготовка к собесам фронтенд
    Dastan SalmurzaevD
    Dastan Salmurzaev
    5
    5
    201

  • Передача типов в TypeScript в под функции
    kirilljsxK
    kirilljsx
    4
    5
    229

  • Исчерпывающее руководство по конфигурации Nginx
    undefined
    4
    1
    234

  • Проверка стала проще с Zod: как обеспечить точность и качество форм
    kirilljsxK
    kirilljsx
    3
    8
    1.1k

  • Bruno - новый клиент для API (Замена PostMan Insomnia)
    ManulM
    Manul
    3
    2
    1.8k

  • Vue.js и React — необычное сравнение
    D
    DeepSeeker
    3
    10
    1.1k

  • Оптимизация React js приложений. Использование функции debounde()
    ManulM
    Manul
    3
    5
    554

  • Провайдеры в Nest JS - 1.3
    undefined
    3
    1
    366

  • Полный гайд по команде LFTP: Работа с локальными и удалёнными серверами
    undefined
    3
    1
    676

Пользователи в Сети:

Статистика:

74

В сети

333

Пользователи

2.0k

Темы

2.9k

Сообщения

Категории

  • Главная
  • Новости
  • Фронтенд
  • Бекенд
  • Языки программирования

Контакты

  • Сотрудничество
  • info@exlends.com

© 2024 - 2026 ExLends, Inc. Все права защищены.

Политика конфиденциальности
  • Войти

  • Нет учётной записи? Зарегистрироваться

  • Войдите или зарегистрируйтесь для поиска.
  • Первое сообщение
    Последнее сообщение
0
  • Лента
  • Категории
  • Последние
  • Метки
  • Популярные
  • Пользователи
  • Группы