В каждой компании, где я работал, были свои правила формализации и постановки обнаруженных багов. Чаще всего - никаких правил. Что нашел тестировщик, то отписал в комментарии к задаче (и это еще хорошо!), а иногда просто на созвоне обсудил с разрабом, тот быстро пофиксил и факт найденного бага остался между ними. Для мелких студий так работать, может, и допустимо, но рано или поздно отсутствие элементарного порядка начинает надоедать. И тут появляются вопросы:
Как оформить баг? Комментарий к задаче? Отдельная задача? Чек-лист в описании задачи?
Как отметить баг выполненным? Проверенным? Повторно проявившимся?
Какая система багтрекинга вам показалась наиболее удобной? Jira? Youtrack? Яндекс.Трекер? Битрикс24? Что-то из новомодного импортозамещения?
Какие шаблоны описания бага приняты в вашей компании? Нет правил? Шаг 1 - шаг 2 - шаг 3 - ожидание - реальность? Скриншот со стрелочками? Видеозапись с экрана?
Есть ли какая-то классификация багов? Минор / мажор? Бэк / фронт? Бэклог / критикал?
Очень интересует ваш опыт в данной теме. Буду очень признателен, если поделитесь своими знаниями в комментариях.
Какую тему для книги можно выбрать в 2025? Современный мир — насыщенный мир. Книг выходит очень много. Как, интересно, можно выбрать тему для книги? От этого зависит конечная аудитория книги всё-таки. Микросервисы? Внедрение зависимостей? Ещё что-нибудь? Я в смятении. А выбирать пора уже. Полгода как прошлая книга вышла...
Не успели начать июнь с грандиозных планов? У нас есть отличный способ встряхнуться и достичь своей цели — 5-дневный IT-челлендж с 16 по 20 июня.
Пять дней, пять тем: Linux, сети, Docker, SQL, безопасность. Вас ждут вопросы и практические задания в формате Google Форм. А чтобы в будничной суете не забыть об испытаниях, Telegram-бот напомнит о челлендже и поведёт вас по шагам.
Победители получат ценные призы, среди которых:
🔥 Подписка на курсы Слёрма
🔥 Курс «Администрирование Linux»
🔥 Курс «Ansible: Infrastructure as Code»
Для самых стойких участников, дошедших до конца — скидка 30% на все курсы.
В cедьмой серии курса «Паттерны и практики написания кода» разберем три последних подхода в теме Структурных Паттернов: Мост, Заместитель и Приспособленец. Вместе с бэкенд-инженером Юрой Афанасьевым посмотрим, как паттерны реализуются в коде и в чём состоит их ключевое назначение.
Подписывайтесь на канал AvitoTech в Telegram, там мы рассказываем больше о профессиональном опыте наших инженеров, проектах и работе в Авито, а также анонсируем митапы и статьи.
Обновляем платформу SourceCraft и открываем доступ к ней для всех разработчиков
Сегодня Yandex B2B Tech открыла публичный доступ к платформе для разработки SourceCraft и представила её новые возможности. В платформу интегрированы инструменты безопасности, которые обеспечат защищённую разработку программных продуктов. А в ИИ‑помощнике SourceCraft Code Assistant появился чат‑режим, что увеличит скорость и эффективность разработки.
Удобство командной работы повысится за счёт бранч‑ и ревью‑политик, встроенных в интерфейс, а также аутентификации через SSO. Также появляется возможность зеркалирования репозиториев с GitHub и публичный API.
Инструменты безопасности
На платформе стали доступны инструменты безопасной разработки: сканер секретов в коде и анализ зависимостей в кодовой базе.
По данным исследования аналитиков Forrester интеграция инструментов безопасности в разработку на 81% снижает трудозатраты на ИБ‑поддержку всего проекта.
Чат‑режим в SourceCraft Code Assistant
ИИ‑помощником SourceCraft Code Assistant пользуются десятки тысяч разработчиков. Теперь в нём доступен чат‑режим, интегрированный непосредственно в среду разработки. В диалоговом режиме на естественном языке можно задать вопрос ИИ‑ассистенту, сгенерировать код, юнит‑тесты, документацию. Это ускорит поиск необходимой информации и оценку предлагаемых решений. Функциональность доступна в плагинах для VSCode и IDE от JetBrains.
Зеркалирование и бесшовная миграция
Миграция проектов с GitHub становится бесшовной — кроме кода переносятся Issues, PRs, Labels, Milestones, Comments. Также можно выбрать ветки для зеркалирования — непрерывной синхронизации кода.
Также появился федеративный доступ к платформе для компаний — авторизация через SSO.
Публичный API
Благодаря появлению публичного API платформа становится расширяемой. Пользователь сможет взаимодействовать с SourceCraft и обеспечивать автоматизацию и интеграцию с другими приложениями. Первая версия публичного API доступна для управления задачами, список будет пополняться.
Правила работы с ИТ‑проектами
В интерфейсе платформы появились бранч‑ и ревью‑политики — правила работы с ветками и проверками кода, которые интегрируются в систему контроля версий и процессы CI/CD.
Опенсорс
Появился анонимный доступ к публичным репозиториям платформы.Пользователи SourceCraft смогут создавать независимые копии репозиториев (forks) опенсорс‑проектов. Это позволит вносить персональные изменения, не затрагивая напрямую исходную кодовую базу. При этом копия сохраняет связь с оригиналом для получения обновлений.
Удобство работы с кодом
Интерфейс платформы теперь позволяет просматривать структуру файлов для шести языков программирования: Python, C++, Java, Go, TypeScript и JavaScript. Функциональность навигации по коду стала умнее и аналогично теперь поддерживает 6 языков.
Автоматизация CI/CD‑процессов
Среди обновлений, связанных со сборкой и развертыванием кода, появились self‑hosted runners — теперь можно запускать задачи как на виртуальных машинах Yandex Cloud, так и в своём окружении. Также появились flavours — теги для пользовательских задач, за счёт которых можно выбирать, где запускать задачу. Помимо этого в интерфейсе платформы появилась возможность не только разрабатывать, но сразу публиковать мобильные приложения в App Store, Google Play, RuStore, Huawei AppGalery.
Packages
Появилась возможность создавать и использовать собственные программные пакеты популярных форматов: наборы кода, библиотек, модулей или компонентов. Разработчик сможет хранить их в персональном облаке, привязанном к организации SourceCraft, и использовать в своих проектах. Packages также интегрированы с CI/CD платформы.
Вход в SourceCraft реализован через Яндекс ID аккаунт. Зайти на обновлённую платформу можно на сайте SourceCraft.
На днях в офисе я столкнулась с коллегами из направления системного программирования в «Криптоните». Они пишут на С++ — а ошибки на этом языке у нас ещё не было!
Поэтому я попросила их придумать код с ошибкой специально для Хабра — и вот что получилось!
Итак, есть ли в этом коде проблема кроме narrowing conversion? Ждём ваши варианты в комментариях.
#include <cstdint>
#include <vector>
struct Type
{
Type(uint16_t, uint32_t = {})
{}
};
int main()
{
std::vector<Type> vector;
std::uint32_t object_id{};
// Есть предупреждение о narrowing conversion
vector.insert(vector.begin(), {0, object_id});
// Нет narrowing conversion
vector.push_back({0, object_id});
// Нет narrowing conversion
vector.insert(vector.begin(), Type{0, object_id});
}
АККУРАТНО, ДАЛЬШЕ СПОЙЛЕР!
Проблема в том, что в строке
vector.insert(vector.begin(), {0, object_id});
в вектор вставляется 2 элемента типа Type, а не один, как ожидает программист.
Причина в том, что метод insert у вектора имеет перегрузку (номер 5), которая вторым параметром принимает std::initializer_list. А компилятор, видя фигурные скобки в коде, в первую очередь пытается создать объект такого типа.
И тут ему это удается, потому что у конструктора Type второй параметр имеет значение по умолчанию, следовательно, Type умеет создаваться, если в конструктор передали только один аргумент. В итоге компилятор успешно создает std::initializer_list с двумя элементами типа Type.
Так как создание std::initializer_list выполняется с использованием uniform initialization, то компилятор следит за корректностью преобразований. В примере объект типа std::uint32_t передается в конструктор Type, который принимает первым параметром std::uint16_t. То есть, возникает риск потери точности (32 бита не могут поместиться в 16 бит).
Об этом компилятор и предупреждает. Вот упрощенный пример, где видим то же самое предупреждение.
Может возникнуть вопрос, почему создание Type от 0 не вызывает предупреждение, ведь 0 - это int, а он, скорее всего 32 бита и тоже не помещается в 16 бит. Но тут литерал. Компилятор видит, что 0 вмещается в 16 бит и не предупреждает. Но если поместить int в переменную, то также возникает предупреждение.
Positive Technologies представляет новую версию PT NAD 12.3.
Главное в продукте: повышение производительности, плейбуки и возможность хранения метаданных в облаке.
🗓️ 5 июня на онлайн-запуске PT NAD 12.3 вы сможете узнать, как команда продукта трансформирует подход к обнаружению сетевых атак за счет централизованного управления, опции хранения метаданных в облаке и плейбуков.
📌 Добавляйте слот в календарь: 5 июня, 14:00.
В программе:
🔻 Экспертиза: обновленные модули, репутационные списки и плейбуки — чтобы ваша команда могла быстрее реагировать на угрозы;
🔻 Центральная консоль: как сократить затраты на команду мониторинга и контролировать атаки во всех филиалах из единой точки;
🔻 «Облако» vs локальные хранилища: гибкое хранение метаданных для экономии денег без потери скорости;
🔻 Скорость: оптимизация производительности для ускорения анализа угроз и обработки трафика даже в крупных сетях.
✍️ Регистрируйтесь на онлайн-запуск PT NAD 12.3 по ссылке.
Что обсудили: — рабочий день техлида, — горизонтальное vs вертикальное развитие: что выбрать, — сложности руководства командой, — опыт работы в Германии и возвращения, — почему Юрий выбрал МойОфис, и как у нас устроена инженерная культура, — как развиваться самому и развивать продукт.
Хотите стать техлидом или просто узнать, что значит вести команду? В этом выпуске — кейсы и честные истории про задачи и людей.
За 5 лет, что я проектирую API, вывела для себя шесть базовых принципов, которых стараюсь придерживаться:
Проектировать для потребителя
Ориентироваться на потребности клиентов API, а не на простоту реализации или устройство базы данных. Об этом, кстати, подробно написано в отличной книге Лоре Арно “Проектирование веб-API”.
Учитывать интересы всех клиентов. Не забывать, что могут появиться новые клиенты.
Сложную логику реализовывать на сервере. Искать баланс между универсальностью API и нагрузкой на клиента, исходя из реалий проекта.
Проектировать понятные API-схемы
Наименования и структуры должны быть максимально прозрачными, ясными и лаконичными.
Избегать обобщающих наименований, типа “flag”. Описывать в названии, какой бизнес-смысл несет этот параметр или метод. Например, флаг с признаком пустой упаковки можно назвать “isEmpty”.
Человек при прочтении схемы должен без дополнительной документации понять, зачем нужен этот API и что он делает.
Отдавать адекватные текстовые коды ошибок, из которых будет однозначно понятно, что поправить в запросе для успешного его выполнения. Например, отдавать не 400 BAD_REQUEST, а 400 PRODUCT_NOT_FOUND.
Принять конвенции и придерживаться их
Использовать везде либо snake_case, либо camelCase, либо kebab-case, не менять правила от метода к методу.
Стандартизировать формат ошибок - во всех методах отдавать их в одинаковой структуре.
Если это HTTP, то зафиксировать, в каких случаях какие коды ответов будут возвращаться. Например, иногда возвращается всегда 200, а потребители ориентируются только на тело ответа.
Договориться о формате версионирования API.
Стандартизировать типы данных: формат дат, UUID и пр.
Думать о безопасности, производительности и надежности
Использовать аутентификацию, авторизацию и ACL. Разграничивать доступ на уровне конкретных методов и даже параметров.
Сначала писать документацию, а только потом разрабатывать. Такой подход минимизирует количество ошибок и проблем с API.
Помечать изменения тегами задач и, при необходимости, цветом.
Описывать логику работы методов/топиков/очередей. При необходимости добавлять диаграммы последовательности и маппинги данных.
Мониторить и анализировать
Понимать, какие методы как часто вызываются и как быстро работают. Как быстро обрабатываются сообщения в очередях и топиках, какое их количество и размеры. Это важно для принятия решений о дальнейших доработках API.
Смотреть в консоли разработчика на проде, как быстро отрабатывают те или иные запросы и т.д.
По возможности настраивать системы мониторинга и алертинга. Это помогает прогнозировать рост нагрузки и отслеживать эффективность системы.
У каждого API‑проектировщика со временем появляется свой набор правил. Было бы интересно сравнить — добавляйте свои пункты в комментариях.
Другие мои материалы можно почитать в телеграм-канале breakfront.
Выбор облачной архитектуры — это не только про экономию, но и про грамотное распределение ресурсов.
Поговорим об этом на бесплатном вебинаре в рамках нового проекта FinOps.
11 июня, в 17:00 по МСК встречаемся с технологическим евангелистом VK Cloud Станиславом Погоржельским и будем обсуждать облачные решения: как снизить затраты и повысить эффективность.
Вместе:
разберём частые ошибки компании при использовании облачных технологий;
оценим важность сетевых сервисов;
посмотрим на примере ПО, как неверный выбор ресурсов для приложения может привести к непредсказуемым последствиям;
обсудим резервное копирование и как его игнор может поставить под угрозу весь бизнес.
Устройство компилятора (кратко) на LLVM Компилятор - инструмент конвертации исходного кода, написанного на высокоуровневом языке программирования в машинный код, который может исполнять компьютер.
Компилятор делится на 3 этапа:
FRONTEND - анализирует текст исходного кода и преобразует его в IR.
MIDDLE - анализирует и оптимизирует этот сгенерированный код IR.
BACKEND - преобразует IR в машинный код.
Сам компилятор, и собственно язык программирования состоит из нескольких частей.
Lexer - лексер
Лексер сканирует и превращает сырой текст в токены. То есть сам исходный код разбиваеты на набор токенов (такие как литералы, идентификаторы, ключевые слова, операторы, разделители) Лексер читает исходный код символ за символом и идентифицирует последовательности символов, соответствующие определённым правилам языка.
Парсинг
Парсинг немного сложнее чем лексический анализ. Существует множество паресров и парсеров-генераторов.
Парсеры в компиляторах обычно принимают входные данные в форме токенов и строят определенное дерево - AST или дерево парсинга.
Обычно компиляторы строятся из множества маленьких компонентов, которые берут входные данные, меняют их или преобразуют их в различные выходные данные. Это одна из причин, по которым функциональные языки хорошо подходят для создания компиляторов. Другие причины — прекрасное сопоставление с эталоном и довольно обширные стандартные библиотеки. Прикольный факт: первая реализация компилятора Rust была на Ocaml.
Советую держать эти компоненты как можно более простыми и автономными — модульность сильно облегчит процесс. По-моему, то же можно сказать и о многих других аспектах разработки ПО.
AST
AST - абстрактное синтаксическое дерево. Это структурированное представление исходного кода программы в виде дерева, где каждый узел дерева представляет собой синтаксическую конструк языка программирования. Это дерево предоставляет абстракцию, которая позволяет анализировать и манипулировать программным кодом на высоком уровне.
IR
Эта часть занимается созданием [[1.2 IR]]. Через примитивы LLVM мы можем сгенерировать промежуточное представление. Каждому типу в AST дается метод, называемый codegen, который всегда возвращает объект значение LLVM, используемый для представления одного регистра присваивания (single assignment register), который является переменной для компилятора, которая может быть назначена только один раз. Интересно, что в этих примитивах IR то, что в отличии от ассемблера, они не зависят от какой-либо конкретной архитектуры машины, и это значительно упрощает работу для разработчиков языков, которым больше не нужно сопоставлять вывод в набор инструкций процессора. Теперь, когда фронтенд может генерировать IR, инструмент LLVM Optimizer используется для анализа и оптимизации сгенерированного кода. Он выполняет несколько проходов по IR и выполняет такие действия как устранение мертвого кода и скалярная замена агрегатов, и, наконец, это приводит нас к бекенду, где мы пишем модуль, который принимает IR в качестве входных данных, который выдает объектный код, который может работать на любой архитектуре.
В новом эпизоде отрытого курса «Паттерны и практики написания кода» вместе с бэкенд-инженером Авито Юрой Афанасьевым продолжаем тему Структурных Паттернов. Разберём два новых подхода — Декоратор и Фасад, поговорим про UML-диаграммы паттернов и их реализацию в коде, а также рассмотрим основные преимущества подходов.
Подписывайтесь на канал AvitoTech в Telegram, там мы рассказываем больше о профессиональном опыте наших инженеров, проектах и работе в Авито, а также анонсируем митапы и статьи.
Как грамотно управлять IT-инфраструктурой в облачном сервисе?
Облака — это уже не будущее, а настоящее. Можно развернуть сервер за минуты, не тратясь на железо, можно быстро адаптировать инфраструктуру под нагрузку. Главное — знать, как это делать правильно. Облака — это про гибкость, масштабируемость и экономию ресурсов.
👉 Слёрм совместно с Selectel, ведущим провайдером IT-инфраструктуры, подготовил бесплатный курс «Работа с облаком и IT-инфраструктура проекта».
На курсе практикуемся на платформе Selectel и разбираем важные темы: от подбора облачного сервиса до сохранения медиафайлов. После обучения вы сможете:
Обычно, концепция Model‑View‑Controller используется в компонентах Joomla, но я хочу поделиться опытом её применения в плагинах.
Для чего это надо? — Сделать код более простым и понятным.
Задача плагина Joomla — подписываться на события и выполнять определенные действия. Но не стоит размещать весь код в классе плагина, лучше разделить его на несколько классов. Особенно, если для ваших задач Joomla предлагает готовые родительские классы.
Почему я предлагаю использовать MVC-фабрику? - Она не только создаёт экземплр класса, но и устанавливает основные зависимости из DI контейнера.
Например, плагин должен ответить на AJAX-запрос и вернуть массив данных. Для этого надо написать свой класс модели, наследующий Joomla\CMS\MVC\Model\ListModel.
Как это сделать? - Примерно так же как и в компонентах.
Классу плагина подключаем трейт Joomla\CMS\MVC\Factory\MVCFactoryAwareTrait.
В файле provider.php плагина регистрируем сервис-провайдер MVC-фабрики и передаём ему пространство имён плагина.
В src папке плагина, создаём папку Administrator, в ней папку Model и в ней файл с классом модели. То есть классы моделей будут расположены по пути Root\plugins\radicalmart\wishboxcdek\src\Administrator\Model.
Обратите внимание на папку Administrator, метод создания моделей обязательно требует либо Site либо Administrator в namespace.
В своём плагине я наследовал класс модели от BaseDatabaseModel, для работы с другими классами может потребоваться переопределение каких-либо свойств и методов.
Задачи Структурных Паттернов: Адаптер и Компоновщик — в чём суть?
В пятой серии открытого курса «Паттерны и практики написания кода» мы начинаем новую объёмную тему — изучение Структурных Паттернов. Она состоит из семи подходов. В эпизоде вместе с бэкенд-инженером Юрой Афанасьевым погрузимся в особенности работы Адаптера и Компоновщика.
Подписывайтесь на канал AvitoTech в Telegram, там мы рассказываем больше о профессиональном опыте наших инженеров, проектах и работе в Авито, а также анонсируем митапы и статьи.
«Мы же всё пофиксили!» — но инциденты повторяются?
6 признаков «токсичного» процесса безопасности:
В CI/CD нет автоматических проверок безопасности, только ручные ревью
Уязвимости находят не сканеры, а пользователи в проде
Отчёты от SAST/SCA просто лежат в почте или Jira
Dev и Sec не взаимодействуют напрямую, всё через багтрекер
После каждого инцидента «делаем выводы», но всё повторяется
Любая интеграция в пайплайн вызывает страх: «только бы не сломать»
Это не история про «плохую команду» или «плохих людей». Это признаки системы, в которой безопасность живёт отдельно. От этого страдают все: Dev, Sec, Ops и бизнес.
Что можно сделать:
Настроить автоматические проверки в CI/CD
Добавить чеклист ревью по безопасности
Согласовать зону ответственности за уязвимости
Наладить процесс triage: кто, когда и как разбирает отчёты
Обсудить на ретроспективе: как снизить риск, а не тушить
📎 А если вы хотите собрать из всего этого рабочую систему — приходите на DevSecOps Bootcamp. Мы не говорим «ставьте сканер, и будет хорошо». Мы помогаем выстроить устойчивый DevSecOps-процесс внутри вашей команды.
В Облаке Рег.ру запустили услугу резервного копирования
Добавили в облачной платформе возможность автоматизированного создания, хранения и восстановления резервных копий. Этот релиз — первый шаг по запуску полноценного Backup as a Service в Облаке Рег.ру.
Что внутри нового сервиса:
настройка расписания бэкапов и снапшотов;
удаленное хранение бэкапа;
восстановление сервера до нужного состояния, если возникнет такая необходимость;
создание снапшотов.
Теперь пользователи могут сами настраивать политику хранения бэкапа — от ежемесячной до ежедневной. На случай локальных сбоев предусмотрели защиту от потери данных — консистентные резервные копии хранятся в удаленном объектном хранилище S3. Отсюда и повышенная катастрофоустойчивость инфраструктуры пользователей в целом. Тарификация происходит по модели pay-as-you-go за фактический объем хранения.