Обновить

Бэкенд

Сначала показывать
Порог рейтинга

Новый режим для ваших приложений ⚡️

Раньше можно было запускать только статику (SSG) и одностраничные приложения (SPA). К ним добавился и серверный рендеринг (SSR).

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

Что дает этот режим:

  • +1 к гибкости разработки. В приложении можно использовать серверную логику, авторизацию и собственные API-обработчики.

  • +1 к SEO. Страницы рендерятся на сервере → лучше индексируются и быстрее попадают в выдачу.

  • +1 к простоте архитектуры. Не нужно создавать отдельный бэкенд, ведь часть логики можно держать в SSR.

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

Минимальный конфиг: от 510 ₽/мес с 1 CPU и 1 ГБ RAM

☝🏻 После деплоя режим изменить нельзя. Для других настроек создайте новое приложение.

Запустить SSR на своем проекте →

Теги:
+3
Комментарии0

Как стать инженером данных?

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

Мы обо всем позаботились и собрали на Хабр Карьере курсы по ключевым инструментам, которые нужны, чтобы стать крутым специалистом.

Вот, например, минимальный набор инженера данных:

  • Metabase. Инструмент для визуализации данных и построения дашбордов.

  • Airflow. Платформа для автоматизации и оркестрации процессов.

  • Redis. Быстрое кэш‑хранилище.

  • Kafka. Система потоковой передачи данных.

  • Hadoop. Фреймворк для распределённого хранения и обработки больших данных.

  • Apache Spark. Инструмент для быстрой обработки больших объёмов данных.

Сменить профессию или вырасти на текущей должности

Теги:
+5
Комментарии0

Запустили Yandex Cloud Stackland — инфраструктурную платформу для развёртывания приложений в закрытом контуре

С помощью Stackland можно как настроить среду для разработки собственных сервисов, так и быстро внедрять облачные решения. Это готовая инфраструктура со встроенными управляемыми базами данных, контейнерным оркестратором, объектным хранилищем, а также инструментами для управления доступом к графическим ускорителям, которые помогут решать задачи инференса при разработке ИИ‑решений. Выдавать доступы к разработке можно гранулярно, используя встроенные средства безопасности.

Платформу можно развернуть на любых виртуальных, арендованных или собственных серверах, а также интегрировать с уже существующими корпоративными системами. Также она позволяет без дополнительной интеграции внедрять готовые сервисы Yandex Cloud, доступные по модели on‑premises. Сейчас в Stackland доступны инструмент для речевой аналитики Yandex SpeechSense и BI‑система Yandex DataLens, в ближайшее время появится ещё несколько решений, в том числе Yandex AI Studio для разработки ИИ‑приложений и агентов.

Подробнее о разработке опенсорс‑решения для бэкапов CloudNativePG в Stackland и предыстории платформы мы уже рассказывали в отдельной статье.

Для получения доступа к Yandex Cloud Stackland оставьте заявку.

Теги:
+7
Комментарии0

lazy-tmux — быстрый и «ленивый» менеджер сессий tmux

Весь мой рабочий процесс происходит внутри сессий tmux. Долгое время я использовал tmux-resurrect + tmux-continuum. Они работали… но с нюансами. Иногда терялись все сохранённые сессии, а при множестве активных сессий всё оставалось загружено в память, в частности, запущенные nvim процессы, которые поднимаю lsp, что со временем отъедало все больше и больше ОЗУ.

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

Так родился lazy-tmux, написанный на Go. Ключевые фичи:

  • Сохраняет текущую сессию, конкретную сессию или все сессии целиком. Снимки сохраняют окна, панели, layout, команды (например, npm, docker-compose, редакторы) и опционально scrollback историю шела.

  • Ленивое восстановление: поднимается только выбранная сессия. RAM не расходуется на всё сразу.

  • Интерактивный TUI браузер с деревом сессий, окон и панелей, таблицей с активными командами, временем последнего снимка, количеством окон/панелей и статусом сессии. Поддержка fuzzy search для быстрого поиска.

  • Навигация и полное управление сессиями и окнами с клавиатуры в TUI браузере сессий.

  • Гибкая сортировка сессий и окон через флаги --session-sort и --window-sort

  • Можно заменить встроенный TUI на fzf, использую облегчённый бинарник.

  • Автосейв через фоновый демон, периодически снимающий все сессии на диск.

  • Восстановление при старте tmux для автоматизации workflow.

Проект ещё молодой, но буду рад любой помощи и идеям по улучшению: GitHub issues

За моими новостями можно следить в Telegram-канале

Теги:
+2
Комментарии0

29 демо-уроков для тех, кто не стоит на месте

Привет, Хабр. Эти уроки проводят преподаватели курсов Отус в преддверии старта новых потоков. На них можно узнать о формате обучения, пообщаться с экспертами и заодно закрыть пробелы в знаниях по интересующей теме. Это бесплатно. Приходите!

Еще больше бесплатных уроков от преподавателей курсов можно посмотреть в календаре мероприятий.

Теги:
+6
Комментарии0

Выпустили бесплатный курс для PHP-разработчиков

Пример одного из уроков курса
Пример одного из уроков курса

Всем привет! Год назад рассказывал в этой статье на Хабре о том, как мы подготовили и записали курс на 30+ часов для наших PHP-разработчиков. В итоге у нас вышло 43 урока, разбитые на 5 направлений.

Сначала думали упаковать все это в коммерческий формат, но решили оставить все как есть и просто поделиться с сообществом. Надеюсь, что он принесет вам пользу.

Курс охватывает PHP от базовых механизмов до архитектуры и тестирования. В программе — устройство языка, работа с памятью и производительностью, принципы ООП и проектирования, а также взаимодействие с базами данных.

Отдельные блоки посвящены внутренностям PHP (zval, сборщик мусора, OPcache, асинхронность), архитектурным подходам (SOLID, DDD, паттерны, организация бизнес-логики) и работе с БД — от проектирования схем до оптимизации запросов и масштабирования.

В части тестирования рассматриваются TDD, структура тестов и подходы к оценке их качества.

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

Теги:
+7
Комментарии2

Худший бэкап — не тот, что не восстановился. А тот, что положил прод.

Что, если post-script не отработал? Моргнула сеть или случился таймаут. Внешний оркестратор просто пишет в лог failed и снимает задачу. А вот PostgreSQL об этом не знает. База остается в режиме бэкапа и начинает непрерывно копить WAL-файлы, ожидая команды на завершение.

Получается, что инструмент для защиты бизнеса от даунтайма, своими руками этот даунтайм и устроил.

Уметь дернуть pg_backup_start( ) — мало. Если СРК не имеет встроенного watchdog-механизма для сброса зависших сессий, резервное копирование превращается в угрозу доступности. Разделение ответственности — правильный архитектурный подход, но он означает, что защита базы от переполнения диска полностью ложится на ваши плечи.

О зависшем backup mode, разрывах PITR и других неудобных вопросах эксплуатации PostgreSQL совместно с Акурой поговорим в режиме live-демо на вебинаре 26 марта в 11:00 (МСК).

Регистрация по ссылкеПриносите в комментарии свои вопросы.

Теги:
0
Комментарии0

Расширение AI-Less Habr — Чистим Хабр от ИИ

Надоела лента, забитая ИИ? У меня есть готовое решение для вас. Shut up and take my money:

Интерфейс расширения
Интерфейс расширения

Расширение для Chrome (и совместимых браузеров) позволяет скрывать статьи про «Искусственный интеллект». Скрывается не контент, написанный ИИ (LLM), а контент про ИИ (что сейчас обычно под этим подразумевается). Бесконечные статьи об очередной революции, вызванной тем, что такая‑то LLM модель опередила конкурентов на 0.1 балл в одном из 186 имеющихся бенчмарков, и вот этот вот всё.

Чтобы видеть счетчик скрытых статей, закрепите иконку расширения на панели инструментов через меню расширений (иконка паззла).

Есть следующие возможности:

  • скрывать хаб «Искусственный интеллект»

  • скрывать по словам в заголовке (настраиваемый список)

  • скрывать по тегам (настраиваемый список)

  • инвертированный режим (показать, попадающее под фильтры, и скрыть остальное)

По умолчанию включено только скрытие хаба «Искусственный интеллект». Фильтры по словам/тегам с большей вероятностью допускают ложноположительные срабатывания, поэтому выключены по умолчанию. По этой же причине в фильтрах по словам по умолчанию нет слов «ии»/«ai», так как есть достаточно много статей, содержащих что‑то вроде «без ИИ». Внимательно относитесь к добавлению слов в фильтры, чтобы минимизировать ложноположительные срабатывания.

Теги:
+20
Комментарии4

Всем привет! На связи Иван, руководитель НИИ Крокодил 😀

Это продолжение истории про медицинское приложение для клиники.

Часть 2. Как устроена медицинская система изнутри

Когда начинаешь работать с медицинской системой, быстро понимаешь: это не продукт, который можно «собрать и доработать потом». Любое изменение проходит через внутреннюю ИТ-команду клиники, потому что за каждым экраном стоят реальные процессы — расписания врачей, лаборатория, регистратура, страховые компании.

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

🧪 Отдельная история — тестирование. Мы проверяли не только интерфейс, а связку «мобильное приложение + сервер клиники». Запись и отмена приёма, конкуренция за слот, обработка ошибок, загрузка PDF-документов, корректная работа вложенных структур в истории посещений — всё это нужно было прогонять реальными сценариями.

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

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

Теги:
0
Комментарии1

Всем привет! На связи Иван, руководитель НИИ Крокодил 😀

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

Часть 1. Как устроена медицинская система изнутри

Это было гибридное мобильное приложение для клиники. По сути — интерфейс для пациента: записаться к врачу, посмотреть анализы, проверить визиты 🔽

Мобильное приложение не содержало бизнес-логики. Все расчёты, проверки, сценарии и данные находились на стороне backend-сервиса клиники. Приложение работало как тонкий клиент: отправляло запросы и отображало результат.

📦 Данные в приложении не хранились

Каждое действие пользователя превращалось в запрос на сервер: авторизация, запись к врачу, список анализов. Сервер возвращал актуальное состояние системы в ответе. Если данные менялись на сервере, пользователь сразу видел это в приложении.

🕓 Запись к врачу была не одной формой, а сценарием

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

⭐️ В следующих частях разберу технические сложности, с которыми мы столкнулись при разработке таких систем.

Теги:
0
Комментарии0

Заметил обнову на Хабре.

Появился новый счетчик "охвата" который судя по моим наблюдениям измеряется в степенях двойки (2,4,8,16,32 и тд). Но я так и не мог найти официальных данных как он работает. Смотрел официальный changelog Хабра — никаких недавних обновлений не вижу.

Как Хабр считает метрику "Охват", которая стала первым делом выводиться возле пользователя?

Кто знает, напишите в комменты или личку. По моему мнению, такие штуки в UI должны сопровождаться символом вопросика, при наведении на который дается информация или второй вариант — по клике на который, открывается страница описывающая то, как работает эта метрика.

UPD
Наглая реклама, но после того как соберу инфу, сделаю еще один репост на Хабре и в своем-тг

Теги:
+1
Комментарии2

Руководитель группы серверной разработки «Криптонита» Артём Корсаков ведёт проект Scalabook. Это уникальная русскоязычная база знаний по Scala.

И недавно он добавил туда новые страницы — делимся с вами. Отправляйте знакомым «скалистам»!

Теги:
0
Комментарии0

Сравнивал разные методы сделать call-once (а точнее инициализацию синглтона) - далее небольшие заметки.

Итак, нам нужно создать какой-то объект, пусть даже что-то нетривиальное (для определённости можно представлять что мы хотим прочитать данные из файла/эмбеддет ресурсов и разложить эти данные в хеш-мапу для будущих чтений). Рассмотрим следующие варианты:

  1. статичный глобальный объект, вычисление вызывается в конструкторе

  2. статичный глобальный объект + std::call_once

  3. статичный локальный объект в функции, вычисление вызывается в конструкторе

Чтобы в годболте видеть что и где вызывается - определяем тип имеющий только объявления методов (это заставит компилятор ставить явный call)

struct TSomeExternal {
    TSomeExternal(int);
    ~TSomeExternal();

    int DoCalc();
    char Data[60]; // просто чтобы было проще увидеть
};

Особенности первого варианта:

  • вычисление "до main"

  • неконтролируемый порядок инициализации глобальных ответов => нельзя иметь зависимости между такими объектами

  • вычисление только в рамках 1 потока

  • уникальный плюс: нет проверок "на горячем цикле" - при обращении к объекту вызывающая функция может считать что данные уже готовы (но именно этот плюс стоит нам второго пункта)

В годболте можно посмотреть на func1 - видно что она скомпилилась просто в забор поинтера, и call

TSomeExternal GlobalValue(7);
int func1() {
    int x = GlobalValue.DoCalc();
    return x + 14;
}

Также видно что были порождены - указание что нужно разместить объект

GlobalValue:
        .zero   60

А также _GLOBAL__sub_I_example.cpp - там видно, что вызывается конструктор, и регистрируется указатель на деструктор в пост-колбеках (__cxa_atexit)

Второй вариант (более правдоподобно было бы внести call_once внутрь глобального объекта, но для простоты сравнения сделал как ниже)

static std::once_flag flag;
static std::unique_ptr<TSomeExternal> ptr;
void init() {ptr = std::make_unique<TSomeExternal>(7);}

int func2() {
    std::call_once(flag, init);
    int x = ptr->DoCalc();
    return x + 14;
}
  • настоящая инициализация случается только в момент первого использования (ленивая инициализация). Это может быть как плюс (позволяет не тратиться на инициализацию если данные не будут использоваться), так и минус (первые запросы/итерации будут медленными)

  • разные инициализаторы данных вполне могут работать одновременно из разных потоков

  • имхо - дорогой основной цикл (очень много инструкций до TSomeExternal::DoCalc) - это всё подготовка вызова call pthread_once, который будет выполнен каждый раз

Третий вариант годболт

int func3() {
    static TSomeExternal prepared = {7};
    int x = prepared.DoCalc();
    return x + 14;
}
  • в рантайме есть проверка - но это проверка и так нужного нам указателя на null

push    rbx
movzx   eax, byte ptr [rip + guard variable for func3()::prepared]
test    al, al
je      .LBB0_1
  • если указатель не нулевой, то переход не будет выполнен и мы сразу переходим к

        lea     rdi, [rip + func3()::prepared]
        call    TSomeExternal::DoCalc()@PLT
  • в случае если указатель не готов, то подготовка случается под блокировкой (__cxa_guard_acquire)

  • конкретно в годболте не видно, но создаются слоты для guard variable for func3()::prepared и func3()::prepared (в этом смысле разницы со вторым вариантом мало)

Итого: ленивое вычисление, также возможна многопоточная инициализация, а также дешёвый success-path

Я бы назвал относительным неудобством третьего варианта, что указатель оказывается скрыт внутри функции, и надо сделать ещё доп действие чтобы использовать объект из нескольких функций. Пример такой обёртки Singleton.

Теги:
0
Комментарии1

Ближайшие события

Друзья, Digital Q.DataBase позволяет Вам не только сохранить прикладную логику СУБД Microsoft и Oracle.

🔹 В связке с другим нашим продуктом, предназначенным для замены SAP NetWeaver, Вы получаете возможность уйти от использования продуктов SAP без переписывания систем и без переписывания бизнес-логики.

Что это означает на практике:

🔹 ABAP-приложения продолжают работать на новой платформе
🔹 Данные и обработка переносятся в Digital Q.DataBase
🔹 Вся бизнес-логика сохраняется без изменений
🔹 Формируется импортонезависимый стек из отечественного ПО

🔹 В этом видео: 

ABAP-код → сохранение → активация → преобразование в C++ → компиляция → установка на сервер → запуск

📎 Полезные ссылки
🔹 Отдельный лендинг по замене SAP: renovation.diasoft.ru
🔹 Бесплатное получение СУБД дистрибутива: database.diasoft.ru
🔹 Документация: доступна внутри дистрибутива
🔹 Telegram-сообщество Digital Q.DataBase: t.me/dqdatabase

Теги:
+3
Комментарии0

Как стать Go-разработчиком?

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

Ловите подборку таких инструментов — они идеально подойдут как для входа в профессию, так и для развития профессиональных навыков, а на Хабр Карьере уже полно актуальных учебных программ по каждому из них:

— SQL. Работаем с базами данных

— Git. Отслеживаем изменения в коде.

— CI/CD. Автоматизируем сборки, тестирование и развёртывание кода.

Postman. Тестируем API через отправку HTTP-запросов и анализа ответов.

Bash. Работаем с операционной системой и пишем скрипты.

Полезные курсы по вашей специальности

Теги:
+2
Комментарии0

Бесплатный тест для Java‑разработчиков: оцени уровень и найди точки роста

Хороший Java‑разработчик — это не просто тот, кто пишет код, а специалист, который держит в голове целую экосистему: от базовых принципов языка до архитектуры распределенных систем.

Чтобы осознанно развиваться дальше, важно понимать:

  • какие технические навыки уже прокачаны;

  • где есть пробелы в знаниях архитектуры и проектировании;

  • какие технологии стоит изучить подробнее;

  • насколько уверенно ты ориентируешься в современном Java‑стеке.

Мы сделали бесплатный пробный тест — он поможет оценить твой уровень как Java‑разработчика и подсветит зоны для развития.

За 20 минут ты получишь:

  • оценку текущего уровня;

  • карту компетенций — наглядную схему всех навыков, необходимых для развития в профессии;

  • подборку материалов для самостоятельного изучения.

Пройти тест

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

Теги:
+2
Комментарии1

🔹 Стоит ещё раз подчеркнуть важную мысль: переход на российскую СУБД не обязательно означает полное переписывание системы.

До сих пор многие не воспринимают это как реальную возможность.
Крупные системы на Oracle или Microsoft можно переводить иначе. Без многолетней переработки всего кода. Достаточно перенести данные и изменить настройки.

При этом важно понимать условие: такой подход работает, если выбранная СУБД изначально к этому подготовлена. В ней должны быть реализованы необходимые доработки для совместимости, включая клонирование функциональности систем Microsoft и Oracle.

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

🔹 Мы предлагаем другой подход. В нашем подходе меняется само представление о миграции: не обязательно адаптировать приложение под PostgreSQL. Можно пойти другим путём, реализовать в СУБД функциональность, совместимую с зарубежными системами.

🔹 Если бы такой подход начали применять раньше, страна могла бы сэкономить колоссальные ресурсы.

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

📎 Полезные ссылки
🔹 Бесплатное получение дистрибутива: database.diasoft.ru
🔹 Документация: доступна внутри дистрибутива
🔹 Telegram-сообщество Digital Q.DataBase: t.me/dqdatabase

Cnews 12.03.2026 | МОСКВА
Cnews 12.03.2026 | МОСКВА
Теги:
+4
Комментарии2

Scala 3.8: три вещи, которые сломают ваш проект при апгрейде

Scala 3.8 вышла в январе 2026. Фич много, но сначала - про то, что может больно ударить при переезде.

1. JDK 17 - жёсткое требование

Никакого JDK 11, никакого JDK 8. Реализация lazy val переписана с sun.misc.Unsafe на VarHandles - потому что в JDK 26 Unsafe будет бросать исключения. Компилятор просто откажется работать на старой JVM.

Если ваша инфраструктура ещё на JDK 11 - апгрейд Scala придётся отложить до апгрейда JVM. Scala 3.3 LTS пока остаётся на JDK 8+.

2. stdlib скомпилирована Scala 3 - и один неочевидный момент

Бинарная совместимость сохранена, но явная передача ClassTag теперь требует using:

// ❌ Перестало компилироваться
Array.empty(reflect.ClassTag.Int)

// ✅
Array.empty(using reflect.ClassTag.Int)
// или просто
Array.empty[Int]

Хорошая новость: компилятор умеет чинить такие места автоматически. Запускаем на Scala 3.7.4 перед апгрейдом:

scalac -source:3.7-migration -rewrite YourFile.scala

3. betterFors меняет тип результата - молча

betterFors теперь включён по умолчанию. Новый дешугаринг убирает промежуточный map - это хорошо для производительности, но меняет поведение кода с Map и несколькими val-алиасами:

// Этот код даёт РАЗНЫЕ результаты в 3.7 и 3.8
val result: Iterable[(Int, Int)] =
  for
    (k, v) <- Map(1 -> 1, 2 -> 1, 3 -> 1)
    x = k + v
    (a, b) = f(x)
    (y, z) <- Map(42 -> 27)
  yield (a + y, b + z)
// 3.7 → List((43,29), (43,30), (43,31))
// 3.8 → Map(43 -> 31)

В 3.7 синтетический map превращал Map в Iterable. В 3.8 этого шага нет - Map остаётся Map, дубли ключей исчезают. 3.8.2 выдаёт предупреждение на такие места. Не игнорируйте.

Фикс простой - явно приводить к Seq:

(k, v) <- Map(1 -> 1, 2 -> 1, 3 -> 1).toSeq

В своем канале в Telegram и в канале Max о разработке в стартапах рассказываю ещё больше интересного и делюсь опытом, заходите, найдете полезные кейсы!

И ещё одно: не берите 3.8.0 и 3.8.1

Сразу после релиза в 3.8.0 нашли JVM linkage errors при использовании Scala 2.13 библиотек. 3.8.1 закрыл это, но оставил баг в for-comprehension. Стабильная версия — 3.8.2 (вышла 24 февраля 2026).

Обновляться - только на неё.

Теги:
+1
Комментарии0

WT CDEK library v.1.3.0 - обновление PHP SDK для Joomla + CDEK.

Небольшая нативная PHP Joomla библиотека для работы с API v.2 службы доставки CDEK. Библиотека представляет собой клиент для авторизации в CDEK API по OAuth, работы с некоторыми методами API: получения ряда данных и расчета стоимости доставки. Поддерживается Joomla 4.2.7 и выше.

В пакет входят:

  • библиотека Webtolk/Cdekapi

  • системный плагин System — WT Cdek для хранения настроек и AJAX‑интеграций

  • task‑плагин Task — Update WT Cdek data для обновления локальных копий справочников CDEK по расписанию

  • web asset с официальным JavaScript‑виджетом СДЭК

👉 v.1.3.0. Что нового?

  • Полный рефакторинг библиотеки. Библиотека переработана в entity‑based API с фасадом Cdek и отдельным слоем запросов. Обратная совместимость не нарушена, поэтому версия библиотеки — 1.3.0.

  • Добавлена поддержка новых разделов API СДЭК. Добавлена поддержка новых разделов API СДЭК: webhooks, prealert, печатные формы, payment, passport, reverse, intakes и других сущностей.

  • Улучшена интеграция с Joomla. Улучшена интеграция с Joomla: installer script для layouts, новые поля Joomla Form для тарифов и обновлённые js виджета CDEK.

  • документация библиотеки. Все методы библиотеки подробно описаны, а так же текст документации собран в отдельной папке в git репозитории.

Пример запроса — запрос информации о городе.

<?php

use Webtolk\Cdekapi\Cdek;

\defined('_JEXEC') or die;

// Вариант 1: брать credentials из настроек плагина
$cdek = new Cdek();

// Вариант 2: передать credentials явно
$cdek = new Cdek(test_mode: true, client_id: 'your_client_id', client_secret: 'your_client_secret');

$result = $cdek->location()->getCities([
    'postal_code' => '410012',
    'city'        => 'Саратов',
    'size'        => 1,
]);

Результат запроса:

Array
(
    [0] => Array
        (
            [code] => 428
            [city_uuid] => 7e54a0b3-76f0-41e2-92e0-f1e600ad84fd
            [city] => Саратов
            [fias_guid] => bf465fda-7834-47d5-986b-ccdb584a85a6
            [country_code] => RU
            [country] => Россия
            [region] => Саратовская область
            [region_code] => 47
            [fias_region_guid] => df594e0e-a935-4664-9d26-0bae13f904fe
            [sub_region] => городской округ Саратов
            [longitude] => 46.034266
            [latitude] => 51.533562
            [time_zone] => Europe/Saratov
            [payment_limit] => -1
        )

)

Библиотека эта нужна для разработчиков, создающих свои расширения для интеграции Joomla и курьерской службы CDEK.

Страница расширения

GitHub расширения

Теги:
+2
Комментарии0

Зелёные тесты ≠ хорошие тесты

Впервые в истории писать тесты стало легко и совсем не страшно. Вокруг теперь у всех покрытие 80%, 90%, а то и вовсе 100%. И вот тут начинается проблема: зелёные тесты ≠ хорошие тесты.

Проблема в метрике, которой мы все привыкли доверять. Code coverage считает строку протестированной, если она выполнилась во время теста. Всё. Не «поймает ли тест баг в этой строке», не «проверяет ли он правильность результата» — просто выполнилась. Можно написать тест без единого assert, и покрытие вырастет. 500 тестов, 90% coverage, а пользы ноль.

Мутационное тестирование — это совершенно другой путь. В простейшей реализации этот инструмент тупо берёт твой код и намеренно ломает его: меняет > на >=, + на ‑, True на False. Каждая такая поломка — мутант. Если после мутации все тесты по‑прежнему зелёные — значит они ничего не проверяют. Покрытие есть, защиты нет.

Почему это важно именно сейчас?

Потому что нейронка любит зелёненькое. Чем больше зелёных тестов — тем субъективно лучше. 100 тестов внушают больше доверия, чем 10, правда? А внутри там assert response.status_code == 200. assert result is not None. assert len(items) > 0. Тест проверяет, что функция вернула хоть что‑то — и радостно зеленеет. Поменяй логику условия, перепутай знак, сломай граничный случай — тест всё равно зелёный. Потому что он проверяет не правильность, а наличие.

Мутационное тестирование — единственный автоматический способ это поймать. Метрика называется mutation score: процент убитых мутантов. 60% — плохо. 90%+ — тесты реально что‑то защищают.

Кое‑какие инструменты для такого тестирования уже есть: mutmut и cosmic‑ray для Python, Stryker для JS/TS, PIT для Java. Медленно? Да, значительно медленнее обычного тест‑рана. Но запускать его не нужно на каждый коммит — достаточно на PR в критические модули.

Но есть нюансы. А где их нет, правда?

Первый: мутации рандомные. Замена > на >= — это не баг, который кто‑то реально допустит. Это синтетическая поломка. Половина мутантов генерирует код, который в реальности никогда не появится. Ты тратишь время на убийство мутантов, которые не имеют отношения к настоящим ошибкам. Это как тестировать замок, ковыряя его вилкой — формально проверка, по факту мимо.

Второй — ещё хуже. Чтобы убить мутанта, тест должен зафиксировать конкретное поведение. Каждую ветку, каждое значение, каждый edge case. Доведи mutation score до 100% — и ты прибил гвоздями каждую строчку кода. Буквально. Теперь попробуй отрефакторить. Переименовал внутренний метод — 40 тестов красные. Поменял порядок полей в ответе — ещё 20. Тесты превращаются из страховки в кандалы: код работает правильно, но тесты падают, потому что они проверяют не поведение, а реализацию.

Это реально ловушка. Слишком гонишься за mutation score — получаешь хрупкие тесты. Не гонишься — получаешь видимость тестирования.

Перемены — впереди!

И вот тут становится по‑настоящему интересно. Представь, что мутации генерирует не тупой набор правил «замени плюс на минус», а нейронка, которая понимает контекст. Которая знает, какие баги реально встречаются в таком коде. Которая мутирует не синтаксис, а логику: меняет порядок проверок, путает граничные условия, забывает обработать edge case — ровно так, как ошибается человек. Или другая нейронка.

Сейчас есть явный сдвиг в сторону таких инструментов, но всё еще ничего достойного не вышло. Но уже скоро точно появится. И это будет совсем другой уровень. Не «выжили ли тесты после рандомной поломки», а «выжили ли тесты после правдоподобной ошибки».

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

Ждём, когда мутанты станут умнее.

Теги:
+7
Комментарии3
1
23 ...