Обновить

Бэкенд

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

Звёзды разработки и практикующие инженеры разбирают горячие темы — от FAIL до GOD. Встречайте tech-шоу «АйТир Лист» от МойОфис.

В нашем шоу мы берём одну область в разработке, выбираем самые обсуждаемые технологии, практики и подходы — и раскладываем их по шкале от FAIL до GOD.
Формат простой: эксперты защищают свои позиции, спорят, соглашаются и не соглашаются. 14 табличек, 14 поводов для споров и честный экспертный рейтинг без попытки всем понравиться.

Первый выпуск — опенсорс для фронтенда

Дебютный эпизод мы посвятили популярным опенсорс-решениям для фронтенда: от инструментов, которые давно пора отпускать, до стандартов индустрии.

В выпуске:

  • Александр Коротаев — эксперт по фронтенду и креативному кодингу

  • Алексей Золотых — тимлид команды веб-редакторов МойОфис

  • Ведущий — Эдгар Акопян

Обсуждаем инструменты, которые формируют повседневную фронтенд-разработку, и честно отвечаем на вопрос: что сегодня выглядит как GOD-tier, а что застряло на уровне MVP или FAIL.

Смотрите выпуск: YouTube | RuTube | VK

Второй выпуск — фичи и идиомы C++

Во втором эпизоде «АйТир Листа» — уже не инструменты, а язык.
Мы устроили полноценную битву мнений вокруг фич и идиом C++: 14 табличек превращаются в 14 поводов для дебатов, где каждая возможность языка проходит через экспертную оценку.

В выпуске:

  • Данил Черепанов — архитектор редакторов МойОфис

  • Антон Полухин — эксперт-разработчик C++ техплатформы городских сервисов Яндекс

  • Ведущий — Эдгар Акопян

Получилось много споров, неожиданных аргументов и ситуаций, где «привычно» не значит «хорошо».

Смотрите и делитесь мнением: YouTube | RuTube | VK

В следующих выпусках продолжим разбирать технологии без скидок на хайп и «так исторически сложилось». Предлагайте темы, а если готовы к жарким спорам – становитесь участниками нашего шоу) А как стать? Пишите в комменты с какой темой бы хотели поспорить!


Теги:
Всего голосов 12: ↑12 и ↓0+12
Комментарии0

Мне навеяло темой: "Что должно быть на каждой PCB с микроконтроллером":

В чем счастье эмбеддед программиста.

Больше 20 лет назад мы с товарищем, специалистом по схемотехнике — цифровой, аналоговой, любой, и конструкции плат, должны были прикрутить маленький экранчик (10х10 сантиметров примерно) для визуализации ввода к нашему секретному девайсу. И все было как обычно, он принес(прислал) мне описание контроллера экрана, я проверил схему подключения к атмеге (какая-то 8-ми битная микруха АТ серии там была), которую он нарисовал, на предмет программной управляемости (необходимости, достаточности и удобства конструкции). Он развел, вытравил, спаял, скрутил, собрал, проверил цепи,... я всего не знаю что там надо делать, я преклоняюсь перед талантом людей, которые все это знают и грамотно делают, иначе мне бы было не на чем работать! И в один прекрасный день мы собрались вдвоем (для меня это была как бы халтурка) чтобы включить, запрограммировать и окончательно проверить что схема и все необходимые функции программного управления работают и можно снять характеристики, все проверить для того чтобы написать уже пользовательскую программу. Я сначала всегда пишу программу, которая проверяет возможности железа: схемотехнику обвязки и возможности аппаратных модулей встроенных в контроллер-процессор, тайминги, какие-то взаимные ограничения на использование ног, периферийных юнитов, кросстайминги, просто свое понимание работы периферии полученное из теоретического описания. Все требует проверки на практике, на работающей железке с работающей программой.

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

Мы подключили программатор и загрузили прошивку! Ожидая что на экране что-то появится. Дисплей имел и графический режим управления, в котором можно было зажигать любые пиксели по координатам, но нас вполне устраивал символьный режим с курсором, в котором у нас было где-то 8 строк по 10 символов. И, как это обычно бывает, ничего не произошло, экран остался безжизненным. Первым делом надо проверить что прошивка работает - поморгать светодиодом, если нет светодиодов просто посмотреть запрограммированный сигнал на каком то выводе процессора осциллографом - все было в порядке, все сигналы на месте. Я начал строить предположения о том, что я мог неправильно понять и, соответственно неправильно настроить-сконфигурировать-передать-принять-перепутать порядок посылок при инициализации дисплея. На это ушел может быть час или два - я дотошно перебирал варианты, вплоть до самых невероятных - ничего не помогало, экран оставался мертвым. Я рассказал напарнику, что называется на пальцах, последовательность операций, которые выполняет моя прошивка. Что-то мы дополнительно проконтролировали по тестовым пинам, нигде логика не была нарушена, все сомнительные варианты мы перепроверили под контролем напарника. Экран оставался мертвым...

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

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

Всем удачи в Новом Году. Пусть у вас всегда будут в наличии необходимые регулировки, особенно аналоговые.

Теги:
Всего голосов 12: ↑11 и ↓1+14
Комментарии7

Вышла новая версия fq 0.16.0

fq - это инструмент, язык и декодер для работы с двоичными данными. Конечная цель проекта — объединить в одном инструменте функции jq, hexdump, dd и gdb.

Поддерживаем массу форматов, полный список: https://github.com/wader/fq/blob/master/doc/formats.md

Написан на Golang.

Демонстрация работы
Демонстрация работы

GitHub: https://github.com/wader/fq

ChangeLog: https://github.com/wader/fq/releases/tag/v0.16.0

Теги:
Всего голосов 2: ↑2 и ↓0+2
Комментарии0

Философия IT-собеседований: взгляд разработчика и DevOps-инженера

Привет, Хабр! Мой пост носит дискуссионный характер. В веб-разработке, администрировании и DevOps я уже 17 лет. Долгое время работал «на себя», оказывая помощь клиентам, с которыми выстроены надёжные взаимоотношения, но текущие реалии рынка подтолкнули к поиску работы по ТК, об этом я и хочу поговорить.

Обо мне: 40 лет, из которых 17 лет в коммерческой разработке. Прошел долгий путь как в fullstack-разработке (web), так и в создании embedded-решений (каршеринг), администрировании и DevOps.

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

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

  1. Диалог на равных.
    Мое лучшее интервью: техлид не мучил теорией, а предложил обсудить реальную дилемму, которую он решает в данный момент (внедрение NoSQL-хранилища ради одного специфичного сервиса, т.е. доп. точка отказа vs производительность). Без таймера и стресса мы искали решение. Итог — оффер и годы отличной работы.

  2. Проверка логики, а не памяти.
    Люблю кейсы в духе: «Вот дано А, почему происходит Б?». Из банального: может ли Вася из другого города достучаться до вашего локального IP? Это показывает понимание базы лучше любого теста.

  3. Ценность универсальных знаний.
    Универсальные знания долгое время позволяли быстро находить решение практически любой проблемы от хардверной, до нарушения самых элементарных паттернов проектирования в коде и эффективно их устранять. Мне нравятся задачи, где проблема может быть скрыта на любом уровне и нравятся клиенты, понимающие, как я могу снять их головную боль обеспечив работоспособность ПО в любой среде и условиях.

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

  1. Лайвкодинг.
    В 40 лет написание кода для меня — процесс интимный... хотя я практикую парное программирование в реальной команде и это мне нравится, но в предвкушении собеседований иногда хочется "психануть" и на предложение выбрать время для лайвокдинга сказать — "предлагаю парное программирование с одним из ваших специалистов, ведь для меня тоже важно, с кем я буду вести разработку". (Не пробовал так отвечать, но попробую, как только выдастся случай).

  2. Вакансии-обманки.
    Зачем заманивать стеком DevOps (Linux, Nginx, Ansible, Terraform, Puppet, Docker, Kubernetes, MySQL, PostgreSQL, Elasticsearch, Logstash, Kibana, Zabbix), если по факту сообщаете, что ничего этого не будет, а ищите классического сисадмина 9-18? — Давайте адкеватный запрос, а не тратьте время.

  3. Терминологическая каша. Сложно отвечать экспертно, когда интервьюер путает CI и OCI или Redis и Rabbit. Если нет погружения в контекст, конструктивного диалога не выйдет. Готовиться к собеседованию должен не только соискатель, но и тот, кто нанимает.

  4. Отсутствие пунктуальности.
    Для меня было шоком, что фаундер может просто не явиться на собседование, или рекретер забывает о диалоге и назначенной встрече. У вас там всё нормально?) Хотя рекрутер мало чем отличается от агента недвижимости, но фаундер забывающий про собеседование для меня персонаж странный.

  5. Узкая специализация.
    Раньше, как мне кажется, ценилась универсальность, способность разработчика понимать инфраструктуру, а инженера/админа — код. Сегодня индустрия уходит в жесткую сегментацию, видимо, для более точного просчёта рисков. А я считаю, что именно универсальность — это страховка проекта от того, что решение будет принято в вакууме одного стека, без учета общей картины.

Теги:
Всего голосов 6: ↑6 и ↓0+7
Комментарии2

Нагрузочное тестирование YMatrix

В партнерском материале расширяются результаты нагрузочного тестирования из статьи «Нагрузочное тестирование GP6 vs GP7 vs Cloudberry» и презентуются результаты тестирования YMatrix. Это дополнение к предыдущей статье, призванное сформировать понимание сравнимости результатов различных форков GreenPlum.

Теги:
Всего голосов 2: ↑1 и ↓10
Комментарии0

Если вы занимаетесь разработкой, не пропустите

У нас недавно выходили подборки полезных образовательных материалов для тех, кто хочет расти в ИТ. Заглядывайте:

Теги:
Всего голосов 3: ↑2 и ↓1+3
Комментарии0

Приглашаем на бесплатный вебинар «За кулисами Java: Секреты памяти, которые разгонят ваше приложение».

🕓 Когда: 25 декабря, 16:00–17:00 (Мск)

👨‍🎓 Спикер: Прощаев Сергей — эксперт в области Java.

Содержание:

✔️ Архитектура памяти в JVM: тонкости работы стека и кучи (Java 8+).

✔️ Фундаментальные проблемы параллелизма: видимость, упорядоченность, атомарность.

✔️ Сравнительный анализ инструментов синхронизации: synchronized, volatile, атомарные классы из java.util.concurrent.atomic.

✔️ Практические рекомендации по выбору инструментов для оптимальной производительности и надёжности.

Вы узнаете:

➕ Как проектировать стабильные многопоточные системы, предсказуемо работающие под нагрузкой.

➕ Как избегать распространённых ошибок, связанных с управлением памятью.

➕ Какие best practices применяют в отраслях с жёсткими требованиями к отказоустойчивости.

Для участия желательны базовые знания Java на уровне Middle и понимание основ многопоточности.

👉 Записаться

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

Выкладываем все карты на стол

Запустили IT Poker с K2 Cloud. Шоу, в котором сильнейшие девелоперы и техлиды показывают, на что способен их скиллсет.

Собрали 12 айтишников из ведущих компаний за столом для покера, но вместо обычной колоды приготовили технологии, сервисы и архитектурные решения. Представьте: в одной руке у игрока — API Gateway, в другой — брокер сообщений, а на флоп внезапно ложится Load Balancer.

Кто дойдёт до конца и сорвёт банк? Справятся ли инженеры без ИИ и техдоков?

Смотреть первые выпуски и болеть за своих уже можно в VK Видео и на YouTube.

Теги:
Всего голосов 1: ↑1 и ↓0+3
Комментарии0

Как написать свой линтер на Go?

Бэкенд-инженер AvitoTech Вячеслав Овчинников на стриме Go live-Coding разобрал механику линтеров и то, как работать с AST Go-проектов. Слава показал, что создание собственного правила — это не магия, а понятный и довольно увлекательный процесс. На стриме он:

  • написал простой, но полноценный линтер;

  • показал, как парсить AST и анализировать типы;

  • добавил своё правило и нашел проблемные конструкции в коде;

  • подключил линтер к golangci-lint.

Специально для вас мы сделали запись стрима, рекомендуем к просмотру всем, кому интересна тема линтеров на Go.

Запись стрима также есть на YouTube.

В ноябре Александр Кувакин, backend-инженер в команде Engineering Excellence AvitoTech, рассказывал в статье на Хабре о том, как backend-разработчикам выстраивать систему тестов на бэкенде. В тексте Саша разобрал основные проблемы и тесты, которые проверяют бизнес-логику. Почитать можно вот по этой ссылке.

А вот здесь вы найдете еще больше материалов по Go — статьи, видео, подкасты.

Теги:
Всего голосов 29: ↑29 и ↓0+31
Комментарии0

Где учиться DevOps?

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

А сегодня — подборка по одному из самых востребованных направлений в IT. Если хотите разобраться в DevOps с нуля или системно прокачать навыки — поглядите курсы по основным инструментам:

Kubernetes. Оркестрация контейнеров, масштабирование сервисов и управление сложной инфраструктурой.

Docker. Упаковка приложений в контейнеры для удобного запуска и переноса между средами.

CI/CD. Автоматизация сборки, тестирования и доставки кода в продакшн.

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

Linux. Основа серверной среды и ключевой навык для работы с инфраструктурой.

→ А еще у нас есть курсы на любой вкус и кошелек — посмотрите

Теги:
Всего голосов 2: ↑2 и ↓0+4
Комментарии0

Метод registerListeners() в CMSPlugin в плагинах планируется удалить в Joomla 7.0.

Этот метод регистрирует устаревшие слушатели событий в диспетчере, имитируя работу плагинов Joomla! 3.x и ниже для Joomla 4+. По умолчанию этот метод ищет все общедоступные методы, название которых начинается с on. Он регистрирует лямбда-функции (замыкания), которые пытаются преобразовать аргументы отправленного события в аргументы вызова метода и вызвать ваш метод on<Нечто>. Результат передаётся обратно событию в его аргумент result.

Теперь этот слой совместимости с устаревшей Joomla 3 помечен к удалению в Joomla 7.0, которая должна выйти осенью 2027 года. Это означает, что те уникальные расширения от Joomla 2.5 / Joomla 3, которые ещё работали на Joomla 4-6 скорее всего окончательно перестанут работать на Joomla 7. Предполагается, что активные разработчики планомерно и постепенно избавляются от технического долга и обновляют свои расширения 😎

Чат русскоязычного Joomla-сообщества.

Теги:
Всего голосов 2: ↑1 и ↓10
Комментарии0

Усыпальница Java

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

В новой статье мы разберёмся, чем именно наполняется эта усыпальница и почему. Поговорим о legacy-коллекциях Java, финализаторах, Nashorn, SecurityManager и легендарном Unsafe. Какие задачи они решали? Какие архитектурные и эксплуатационные проблемы породили? И, конечно, разберём, какие современные альтернативы пришли им на смену.

Теги:
Всего голосов 6: ↑4 и ↓2+5
Комментарии4

Где учить английский язык?

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

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

Разговорный английский. Говорим уверенно без языкового барьера.

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

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

Деловой английский. Для встреч, переговоров, презентаций и рабочей переписки.

Английский для IT. Профильная лексика и упор на деловое общение.

→ На Хабр Карьере есть курсы под разные цели и уровни — заглядывайте к нам на витрину.

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

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

Баги на всех языках мира. Проверка LanguageTool

Всем привет! Hello, everyone! Hallo zusammen! Hola a tothom! مرحباً بالجميع!

В нашем блоге мы часто говорим про статический анализ, линтеры и подобные инструменты. Но на этот раз мы нашли их довольно интересного представителя! LanguageTool — это многоязычная программа проверки орфографии, стилистики и грамматики, которая помогает исправлять и перефразировать тексты.

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

Теги:
Всего голосов 3: ↑3 и ↓0+4
Комментарии0

Ожидается до минус 30...

... процентов скидки на IT-курсы от практикующих экспертов!

Условия простые:

➖ 1 курс: скидка 15% до 21.12 включительно, далее скидка будет уменьшаться
➖ 2 курса: -25%
➖ 3 курса: -30%
Годовая подписка: -20%

Несколько советов, как правильно выбрать курс:

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

2) Контент — вторично. Важнее обратная связь.
Узнайте заранее: кто и как проверяет домашки, есть ли ревью, разбор ошибок, можно ли задать вопрос и получить ответ. Без этого курс превращается в просмотр видео «для вдохновения».

3) Сопоставьте программу с требованиями рынка и карьерной целью.
Посмотрите 20–30 вакансий на нужный грейд и выпишите, что там реально требуют. Потом сравните с программой: покрывает ли она скиллы, за которые платят, или уводит в редкую экзотику.

Выбрать своё

Теги:
Всего голосов 7: ↑3 и ↓4+1
Комментарии0

36 бесплатных IT-уроков недели от практиков

Привет, Хабр. Делимся подборкой бесплатных открытых уроков, которые пройдут на этой неделе в Otus. Опытные практики проведут занятия онлайн — сможете узнать больше о формате обучения и задать вопросы экспертам. Занятия проходят по вечерам, в 19 или 20:00 по мск. Выбирайте свою тему и присоединяйтесь!

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

🐧 Linux для начинающих. Подробнее

📊 Основы SQL. Подробнее

🔀 Основы Git. Подробнее

🧑‍🎓 Выбор профессии в IT. Подробнее

15 декабря, понедельник

16 декабря, вторник

17 декабря, среда

18 декабря, четверг

Теги:
Всего голосов 4: ↑3 и ↓1+3
Комментарии0

📊 Multi-LLM Orchestrator v0.7.0: подсчёт токенов и мониторинг через Prometheus

На этой неделе вышел релиз v0.7.0 — завершена фаза observability. Теперь библиотека автоматически считает токены, оценивает стоимость запросов и экспортирует метрики в Prometheus. Всё работает из коробки.

Предыдущие релизы:

🔢 Автоматический подсчёт токенов

Библиотека автоматически считает токены для каждого запроса — и для prompt, и для completion. Используется tiktoken с fallback на оценку по словам.

from orchestrator import Router
from orchestrator.providers import GigaChatProvider, ProviderConfig

router = Router()
router.add_provider(GigaChatProvider(ProviderConfig(
    name="gigachat",
    api_key="your_key",
    model="GigaChat",
    verify_ssl=False
)))

# Токены считаются автоматически
response = await router.route("Напиши стихотворение про Python")

# Получаем статистику
metrics = router.get_metrics()
print(f"Total tokens: {metrics['gigachat'].total_tokens}")
print(f"  Prompt: {metrics['gigachat'].total_prompt_tokens}")
print(f"  Completion: {metrics['gigachat'].total_completion_tokens}")

Результат:

Total tokens: 75
  Prompt: 20
  Completion: 55

💰 Оценка стоимости запросов

Расчёт стоимости в реальном времени. Цены настраиваются в pricing.py (фиксированные значения для демонстрации — для production рекомендуется настроить под свои тарифы).

Результаты тестов с реальными провайдерами:

  • GigaChat: 75 tokens → ₽0.0750

  • YandexGPT: 105 tokens → ₽0.1575

  • Streaming: 342 tokens → ₽0.3420

📈 Интеграция с Prometheus

HTTP-эндпоинт /metrics в формате Prometheus. Метрики обновляются в реальном времени и готовы для scraping.

# Запускаем metrics server
await router.start_metrics_server(port=9090)

# Делаем запросы
await router.route("Привет!")

# Метрики доступны: http://localhost:9090/metrics

Экспортируемые метрики:

  • llm_requests_total — количество запросов

  • llm_request_latency_seconds — histogram латентности

  • llm_tokens_total — токены (prompt/completion)

  • llm_cost_total — стоимость в RUB

  • llm_provider_health — health status (0-1)

Готово для визуализации с Grafana.

🏗️ Архитектура

Router → Metrics Engine → Prometheus Exporter → Grafana.
Router → Metrics Engine → Prometheus Exporter → Grafana.

✅ Тестирование на реальных провайдерах

Все функции протестированы с production API и реальными ключами:

Подсчёт токенов:

  • GigaChat — 75 токенов, ₽0.0750 (стихотворение про Python)

  • YandexGPT — 105 токенов, ₽0.1575 (объяснение ML концепции)

Streaming-режим:

  • GigaChat — 342 токена, ₽0.3420 (генерация длинного текста)

Prometheus endpoint:

  • HTTP /metrics — корректный формат, все метрики экспортируются

Качество кода: 203 теста • 81% покрытие • mypy strict без ошибок


📦 Установка

pip install multi-llm-orchestrator==0.7.0

Новые зависимости: prometheus-client, tiktoken, aiohttp

🎯 Планы на v0.8.0

В следующей версии планируется добавить:

  • Динамическое обновление цен — автоматическое получение актуальных тарифов через API провайдеров

  • Provider-specific tokenizers — нативные токенизаторы для GigaChat и YandexGPT (вместо универсального tiktoken)

  • Расширенная аналитика латентности — percentiles p50, p95, p99 для детального анализа производительности

  • Cost analytics — уведомления о превышении бюджета, детальная разбивка расходов по моделям

  • Prometheus Pushgateway — поддержка push-модели для serverless окружений

Если используете библиотеку — пишите в комментариях, какие функции нужны вам!

🔗 Ссылки

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Required или нет?

Работая над одним из проектов, который недавно переехал из Framework 4.8 на Core 9, обнаружил множество самых разных вариантов использования модификатора required и атрибута Required, примерно каждый второй из которых был использован неправильно. Я написал это коллегам и хочу поделиться этим здесь. Это не обязательные правила, но сильно упрощают работу с кодом.

Небольшое пояснение

Атрибут Required нужен для проверки входящих преимущественно строковых данных в эндпоинтах. Возвращает ошибку, если значение null или пустая строка для строк (если не отключено параметром AllowEmptyStrings). Работает в Runtime. Также применяется в Entity Framework в подходе code-first но с включением опции <Nullable> в csproj про эти случаи можно забыть, сделав код чище.

Модификатор required нужен для обязательного указания значений полей при создании класса. Работает в Compile-time.

Примеры использования

// имеем класс с required полем
public class Example
{
    public required string Name { get; set; }
}

// пытаемся создать экземпляр в коде
var example1 = new Example();  // будет ошибка при попытке сборки проекта
var example2 = new Example { Name = string.Empty };  // тут ошибки не будет

// Вывод: модификатор required нужен для разработчика
// имеем класс с полем, у которого атрибут Required
public class Example
{
    [Required]
    public string Name { get; set; }
}

// пытаемся создать экземпляр в коде
var example = new Example();  // проект спокойно собирается

// имеем эндпоинт в контроллере
public IActionResult PostMethod([FromBody] Example model) => Ok();

/* передаём в теле запроса:
{}
или
{"Name": null}
или
{"Name": ""}
или
{"Name": "   "}
Получаем BadRequest с текстом ошибки. */

// передаём в теле запроса: {"Name": "name"}. Получаем OK.

// Вывод: атрибут Required нужен для пользователя

Как стоит и не стоит использовать.

public class BadExample
{
    public required string Field1 { get; set; } // 1
    
    public required string? Field2 { get; set; } // 2
    
    [Required]
    public required string Field3 { get; set; } // 3

    [Required]
    public string? Field4 { get; set; } // 4

    [Required]
    public int Field5 { get; set; } // 5

    public required int Field6 { get; set; } = 10; // 6
      
    public required List<int> Field7 { get; set; } // 7
}
  1. Ошибка, если класс используется как входящий параметр в эндпоинте. Соответственно, не стоит использовать, если десериализуем в него.

  2. Либо required, либо nullable.

  3. Надо выбрать одно из двух в зависимости от места использования.

  4. Либо Required, либо nullable. Тут даже AllowEmptyStrings = true не поможет.

  5. Required используется для строк. Но есть нюанс (*).

  6. Не нужно использовать required со значением по умолчанию.

  7. Не стоит усложнять жизнь, если поле можно проинициализировать при создании класса.

public class GoodExample
{
    public required string Field1 { get; set; } // 1
    
    [Required]
    public string Field2 { get; set; } = null!; // 2
    
    public string? Field3 { get; set; } // 3

    public int Field4 { get; set; } // 4

    public List<string> Field5 { get; set; } = []; // 5
}
  1. Хорошо где угодно за пределами эндпоинтов и десериализации, а значение не может принимать null.

  2. То что нужно для эндпоинта.

  3. Поле nullable. Поэтому никаких required.

  4. Не используем атрибут Required с не строками. Но есть нюанс (*).

  5. Избегаем использование required, проинициализировав коллекцию.

* - если передаётся json, в котором явно указано значение null ({"Field4": null}), то использование атрибута Required вернёт BadRequest.
Если же в json поле было опущено, то будет присвоено значение по умолчанию.

Надеюсь, это поможет сделать код чище и избежать неоднозначностей.

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Компьютерное зрение для кода: что PVS-Studio разглядел в OpenCV

Что общего у компьютерного зрения и статического анализа? Оба ищут смысл в данных. OpenCV находит образы среди миллионов пикселей, а PVS-Studio — ошибки среди тысяч строк кода. Изучим же исходники крупнейшей библиотеки компьютерного зрения.

На примере 14 фрагментов кода из OpenCV предлагаю посмотреть, как статический анализ помогает избежать попадания багов в релиз и облегчить жизнь разработчикам.

Давайте посмотрим на кусок кода из проекта:

template<typename T>
struct Ptr : public std::shared_ptr<T>;
// ....
Ptr<FlannNeighborhoodGraph> FlannNeighborhoodGraph::create(....) 
{           
    return makePtr<FlannNeighborhoodGraphImpl>(....);
}

void Utils::densitySort (const Mat &points, int knn, 
                         Mat &sorted_points, std::vector<int> &sorted_mask) 
{
  // ....
  FlannNeighborhoodGraph &graph =                                      // <=
                         *FlannNeighborhoodGraph::create(....);

  std::vector<double> sum_knn_distances (points_size, 0);
  for (int p = 0; p < points_size; p++) {
    const std::vector<double> &dists = graph.getNeighborsDistances(p);
    for (int k = 0; k < knn; k++)
      sum_knn_distances[p] += dists[k];
  }
  // ....
}

Если вы думаете, что использование умных указателей раз и навсегда решает проблему "висячих" ссылок и доступов к памяти, то здесь всё пошло не так. Давайте разбираться. Сейчас код работает следующим образом:

  1. Функция create создаёт и возвращает умный указатель на тип FlannNeighborhoodGraphImpl, и его счётчик ссылок на объект равен единице;

  2. Создаётся ссылка graph на значение этого умного указателя, при этом счётчик ссылок на объект не изменяется;

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

  4. В цикле for происходит обращение к невалидной ссылке.

В итоге код, который казался правильным, приводит к неопределённому поведению. Кроме того, эту проблему находит не только PVS-Studio, но и санитайзер. Пруф.

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

std::vector<double> sum_knn_distances (points_size, 0);

{
  // get neighbors
  auto graph = FlannNeighborhoodGraph::create(....);

  for (int p = 0; p < points_size; p++) {
    const std::vector<double> &dists = graph->getNeighborsDistances(p);
    for (int k = 0; k < knn; k++) 
      sum_knn_distances[p] += dists[k];
  }
}

Дополнительно ограничили область видимости graph, чтобы ресурс освободился после выполнения циклов.

Хотите узнать больше?

Статический анализ выявляет скрытые дефекты даже в больших работающих проектах. Какие ещё опасные фрагменты кода мы нашли в коде OpenCV? Полный разбор можно найти в отдельной статье.

Теги:
Всего голосов 3: ↑3 и ↓0+3
Комментарии1

20 демо-уроков, которые нельзя пропустить бэкенд-разработчикам

Привет, Хабр. Сегодня делимся подборкой открытых уроков, которые пройдут в Otus в декабре. Уроки проводят преподаватели курсов в формате живых вебинаров — это шанс не только получить нужные знания, но и задать свои вопросы экспертам. Участие бесплатное (нужно только зарегистрироваться). Присоединяйтесь!

Полное расписание бесплатных демо-уроков смотрите в календаре.

Теги:
Всего голосов 3: ↑3 и ↓0+4
Комментарии0