13626
Изучаем C++. По вопросам сотрудничества: @adv_and_pr
std::memory_order_releasestd::memory_order_release — это одна из опций, используемых в C++ в контексте работы с атомарными операциями и многозадачностью. Она определяет, как должен вести себя компилятор и/или аппаратное обеспечение при выполнении операции записи в память. В частности, std::memory_order_release гарантирует, что все предыдущие операции записи и чтения будут завершены до момента записи с использованием этого порядка памяти.
Когда вы используете std::memory_order_release вместе с атомарными операциями записи, такими как std::atomic_store или std::atomic_exchange, это гарантирует, что все предшествующие операции записи, выполненные в этом потоке, завершатся до момента выполнения операции записи с порядком памяти std::memory_order_release. Это гарантирует, что изменения, сделанные в текущем потоке, видны другим потокам после операции записи с порядком памяти std::memory_order_release.
#для_продвинутых
В России можно посещать IT-мероприятия хоть каждый день: как оффлайн, так и онлайн
Но где их находить? Как узнавать о них раньше, чем когда все начнут выкладывать фотографии оттуда?
Переходите на канал IT-Мероприятия России. В нём каждый день анонсируются мероприятия со всех городов России
📆 в канале размещаются как онлайн, так и оффлайн мероприятия;
👩💻 можно найти ивенты по любому стеку: программирование, frontend-backend разработка, кибербезопасность, дата-аналитика, osint, devops и другие;
🎙 разнообразные форматы мероприятий: митапы с коллегами по цеху, конференции и вебинары с известными опытными специалистами, форумы и олимпиады от важных представителей индустрии и многое другое
А чтобы не искать по разным форумам и чатам новости о предстоящих ивентах:
🚀 IT-мероприятия России — подписывайся и будь в курсе всех предстоящих мероприятий!
Что такое пир-ревью и зачем оно нужно вашей команде
Процесс ревью полезен обеим сторонам. Человек, чью работу проверяют, получает оценку написанному, рекомендации, как можно сделать лучше. Ревьюер же анализирует, как пишут другие люди, тренируется искать ошибки и предлагать улучшения — от архитектуры до код-стайла.
Смотреть статью
Функция isprint()
В C++ isprint() — это предопределенная функция, используемая для обработки строк и символов. cstring — это заголовочный файл, необходимый для строковых функций, а cctype — заголовочный файл, необходимый для символьных функций.
Эта функция используется для проверки того, содержит ли аргумент какие-либо печатные символы.
Подробнее можно почитать здесь.
Интероперабельность между С++ и Rust
Смотреть статью
❤️ Приходите на Backend Talks от Яндекс 360
Санкт-Петербург, 13 ноября в 19:00
Разберём архитектуру облачной записи встреч, наведём порядок в API и покажем, как простые решения спасают сервисы.
В программе:
📌 Как не упустить важное: архитектура облачной записи и конспектирования видеовстреч в Телемосте — Илья Григорьев, разработчик бэкенда Телемоста.
📌 Укрощение API: процессы и инструменты, которые действительно работают — Никита Ломакин, разработчик в команде Техплатформы.
📌 Как мы закапывали звездолёт: почему важно отстаивать простоту на архревью — Артемий Коцюбенко, разработчик протокольных сервисов Почты.
Команда Яндекс 360 работает с нагрузками >1.000.000+ RPS и создает продукты которыми пользуются 95+ млн человек каждый месяц — Диск, Почта, Телемост, Мессенджер и другие.
🍻А после докладов вас будут ждать афтепати и нетворкинг!
Регистрируйтесь по ссылке
#вопросы_с_собеседований
Что такое stack overflow?
stack overflow (переполнение стека) — это программная ошибка, которая возникает, когда программа пытается использовать больше памяти на стеке, чем доступно. Стэк — это область памяти, используемая для хранения локальной информации функций, таких как параметры, локальные переменные и возвращаемые значения.
Когда функция вызывается, ее адрес возврата сохраняется на стеке. Затем, когда функция завершается, ее адрес возврата восстанавливается из стека, и управление передается следующей функции в стеке вызовов.
Когда происходит переполнение стека, программа аварийно завершается. Это может привести к потере данных или даже к повреждению системы.
Прочел на днях пост Вани Ходора (бэкенд-разработчик из Лавки) и вот что думаю. Мы привыкли думать про скорость как про «миллисекунды в графиках». Но speculative execution — про другое: про обещание. Обещание, что ваш продукт окажется там, где пользователь собирается быть, на полшага раньше него. Это и есть «магия» ощущения мгновенности.
Когда «спекуляция» — это фича, а не расточительство
Есть предсказуемый следующий шаг. Лента листается дальше, корзину после карточки товара открывают часто, фильтры в карте включают по типовым шаблонам. Если путь вероятен — предзагружайте.
Психология выигрыша больше, чем цена железа. Пользователь чувствует разницу между 800 мс и 80 мс сильнее, чем продукт-команда счет за CPU. Но только там, где эта разница влияет на удержание, конверсию, повтор.
Стоимость отказа низкая. Если «угадали» неправильно — легко выкинуть результат и не испортить состояние системы (идемпотентность, компенсации, отмены).
Формула грубо такая:
ожидаемая выгода = p(угадали) × выигрыш от скорости − (1 − p) × цена лишней работы.
Пока правая часть положительная — вы в плюсе.
Инженерные поручни (чтобы не сорваться)
Идемпотентность и отмена. Спекулятивные ветки должны быть безопасны к повтору и просто отменяемы (cancellation tokens, TTL на задания).
Бюджеты и приоритеты. Не «всегда префетчить», а «префетчить при свободных бюджетах»: квоты на пользователя/сессию/датацентр, классы приоритетов, circuit breakers.
Деградация и фолбэки. Нет бюджета — живём без спекуляции; нет сигналов — не угадываем.
Анти-шторм. Избегайте dogpile: джоб-коалесинг (одна задача на ключ), кэши с soft-TTL, jitter на обновления.
Наблюдаемость именно под спекуляцию. Отдельные метрики: hit-rate предсказаний, доля отменённых вычислений, «цена хита» (CPU/IO на один успешный предзагруженный ответ), влияние на p95/p99 основной ручки.
Сигналы лучше, чем хрустальный шар
Спекуляция не обязана быть «ML-магией». Начните с простых сигналов:
UI-хинты: вкладка «постинг» открыта → прогреть аплоад; виден блок «Похожие» → подгрузить их.
Поведенческие частоты: «после X часто делают Y» → прогреть Y.
Временные окна: топ-запросы часа/дня предвычислять пачками.
Когда эвристики исчерпаны — добавляйте модель. Но помните: для бизнеса важнее precision (не сжигать впустую), чем recall (угадать каждый шаг). Лучше 60% попаданий при дешёвой промашке, чем 90% с дорогой.
Экономика кэширования без самообмана
Управляйте свежестью. SLA на «мгновенность» ≠ SLA на «абсолютную актуальность». Делите ручки по требованиям к свежести, ставьте разные TTL/источники правды.
Локальный прогрев важнее «всё и сразу». Прогревать следующие 10 постов лучше, чем следующие 100, если это сохраняет p95 и батарейку пользователя.
Безопасность и этика (да, это сюда)
Спекуляция — это иногда пересылка/хранение того, что пользователь может быть захочет отправить. Значит:
явное согласие и прозрачность (особенно для медиа и PII),
шифрование на клиенте и в транзите,
уважение к лимитам устройства (сеть, батарея), доступность оффлайн.
Как начать завтра и не сжечь прод
Гипотеза → метрика → бюджет. «Если прогреем X, то конверсия в Y +N% при цене Z».
Теневой режим. Считать и отменять, не влияя на пользовательский ответ. Померили hit-rate и цену.
Маленький тумблер. 1–5% трафика, фича-флаг, откат за один клик.
Платформизируйте удачу. Вынесите в библиотеку/сервис: API «попроси спекуляцию», приоритеты, бюджеты, кэши, отмена, логирование.
Где ломаются хорошие идеи
Удвоили самые тяжёлые запросы «на всякий случай». Бюджетов нет — счёт растёт.
Спорная согласованность: кэш мгновенный, но устаревший → пользователь теряет доверие.
«Предсказываем всё» на мобильной сети → минус батарея и лояльность.
Нет идемпотентности → редкие гонки превращаются в баги с деньгами.
Спекулятивное исполнение — не трюк, а способ выразить заботу о времени пользователя. Это разговор бэкенда с продуктом на одном языке: «мы инвестируем ресурсы туда, где ускорение заметят и оценят».
#вопросы_с_собеседований
Может ли inline-функция быть рекурсивной в С++?
Да, inline-функция может быть рекурсивной в С++. Однако, компилятор может отказаться от встраивания рекурсивной функции, если это приведет к чрезмерному расходу памяти или времени.
Чтобы заставить компилятор встроить рекурсивную функцию, можно использовать директиву препроцессора #pragma inline_recursion(on).
На картинке выше функция вычисляет факториал числа. При компиляции этой функции с помощью компилятора GCC с опцией -O2 будет получен следующий результат:
factorial(int) at factorial.cc:5
factorial будет встроена в код.factorial вызывается очень часто, компилятор может решить, что встраивание функции приведет к избыточному дублированию кода. В этом случае компилятор будет использовать обычный вызов функции.
Читать полностью…
Хотите собрать свой мини-Google? 🚀
🗓 22 октября, 20:00 приглашаем на открытый урок OTUS «Мини-поисковик своими руками». На этом вебинаре вы создадите поисковик с нуля — без готовых библиотек и магии. Только алгоритмы и код.
Разберём, как:
• объединить КМП и префиксное дерево;
• реализовать автодополнение и подсчёт вхождений;
• оптимизировать поиск под большие тексты;
• превратить всё это в маленький, но работающий офлайн-поисковик.
После вебинара вы сможете самостоятельно:
— строить индекс слов и быстро искать по нему;
— собирать статистику запросов;
— понять, как внутри устроены поисковики.
Открытый урок проходит в преддверие старта курса «Алгоритмы и структуры данных». Все участники получат скидку на обучение.
Присоединяйтесь 22 октября в 20:00:
https://otus.pw/tJkvH/
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Forward_listForward_list в C++ - это контейнер, поддерживающий быструю вставку и удаление элементов из любого места в контейнере. Быстрый доступ к случайным элементам не поддерживается. Реализуется как односвязный список. По сравнению с std::list этот контейнер обеспечивает более эффективное хранение памяти, когда двунаправленная итерация не требуется.Forward_list соответствует требованиям Container (за исключением члена функции size и того, что сложность оператора == всегда линейна), AllocatorAwareContainer и SequenceContainer.
#для_продвинутых
Флаг компиляции -fPIC
Флаг компиляции -fPIC в С++ означает «Position Independent Code» (код с независимой позицией). Этот флаг заставляет компилятор создавать код, который может быть связан с другими библиотеками, независимо от того, где они расположены в памяти.
Код с независимой позицией необходим для создания динамических библиотек, которые могут быть загружены в память в любое место. Это также полезно для создания разделяемых модулей, которые могут быть подключены к другим программам.
Чтобы использовать флаг -fPIC, необходимо добавить его в командную строку компилятора. Например, для компиляции файла main.cpp с использованием флага -fPIC можно использовать следующую команду:
g++ -fPIC main.cpp -o main
Что такое PIMPL?
PIMPL (Pointer to Implementation) — это идиома проектирования в C++, которая используется для управления инкапсуляцией деталей реализации класса и сокрытия их от пользователей класса. Она также известна как «Cheshire Cat» (улыбка Чеширского кота) из-за того, что она позволяет «убрать» детали реализации из интерфейса класса, оставив только указатель на них.
Идея PIMPL заключается в том, чтобы внести все детали реализации класса в отдельную структуру или класс, а затем хранить указатель на эту структуру в основном классе. Таким образом, пользователи класса видят только публичный интерфейс основного класса, а детали реализации остаются скрытыми.
#для_продвинутых
std::unordered_setstd::unordered_set — это ассоциативный контейнер, который содержит множество уникальных объектов типа Key. Это позволяет быстро получить доступ к отдельным элементам, поскольку после вычисления хэша он указывает на точный бакет, в который помещен элемент.std::unordered_set использует хэширование для хранения элементов. Это означает, что каждый элемент контейнера преобразуется в целое число, называемое хеш-значением. Хеш-значения элементов используются для размещения их в бакетах, которые представляют собой массивы элементов.
Доступ к элементам std::unordered_set осуществляется с помощью их хеш-значений. Это позволяет получить доступ к элементу за время O(1), что быстрее, чем у других ассоциативных контейнеров, таких как std::map и std::multimap.
#для_начинающих
Вглубь std::unordered_map: магические числа
Смотреть статью
Узнаем длину аудио файла
В этом примере мы открываем файл с помощью std::ifstream, находим его размер, а затем вычисляем длительность аудио файла, зная частоту дискретизации (в данном случае 44100 Гц). Выводим длительность в минутах и секундах.
Убедитесь, что заменили "your_audio_file.wav" на путь к вашему аудио файлу, а также, если частота дискретизации вашего аудио файла отличается от 44100 Гц, замените это значение на соответствующее значение вашего аудио файла.
Кодовая база уменьшится на глазах, если применить несколько простых способов. И это не кликбейт, а проверенные советы инженера YADRO, который протестировал несколько инструментов на системе BMC для серверов и СХД и собрал опыт в статье на Хабре.
Вы узнаете, как оптимизировать объем бинарного файла с помощью флагов компилятора и линковки, а также через переработку кода и изменение архитектуры. Статью можно использовать как гайд или шпаргалку, когда нужно поработать с бинарем. И никаких «уменьшающих микстур» 😉
Прочитать →
Дружим Flutter с С# и С++
На Flutter`е очень удобно и хорошо пишутся интерфейсы для пользователей.
Смотреть статью
Бинарный поиск
Чаще всего бинарный поиск (бинпоиск) используют, чтобы найти элемент в отсортированном массиве. Мы начинаем искать с середины массива. Если находим то, что нужно, или если больше нечего рассматривать, мы останавливаемся. В противном случае мы решаем, в каком направлении — вправо или влево от середины — мы должны продолжить поиск. Так как пространство поиска после каждой проверки делится на два, то время выполнения алгоритма — O(log n).
C++23: сужение контекстных преобразований до bool.
https://dev.to/sandordargo/c23-narrowing-contextual-conversions-to-bool-2fh8
Poco
Набор open-sorce библиотек для создания кроссплатформенных сетевых и веб-приложений на C++, хорош тем, что множество типовых задач в библиотеке уже решены, что уменьшает время разработки и ошибки, плюс реализована удобная работа с базами данныхSQL, MonoDB и Redis.
https://pocoproject.org
#вопросы_с_собеседований
Напишите программу на C++, которая запрашивает у пользователя два числа и выполняет одну из простых математических операций: сложение, вычитание, умножение или деление. Пользователь должен вводить операцию в виде символа (+, -, *, /).
Подсказка: Используйте конструкцию switch для выполнения различных операций.
Решение:
1. Переменные: Определить переменные для чисел и операции.
2. Ввод данных: Запросить у пользователя два числа и символ операции.
3. Выбор операции: Использовать switch для определения типа операции.
4. Выполнение операции: Выполнить выбранную операцию, учитывая возможные ошибки (деление на ноль).
5. Вывод результата: Вывести результат операции.
6. Обработка ошибок: В случае ошибки вывести сообщение и завершить программу.
7. Возвращение значения: Вернуть 0 при успешном завершении, ненулевой код при ошибке.
Объясните разницу между глубоким и поверхностным копированием и приведите пример, когда каждый тип копирования может быть предпочтительнее.
Глубокое копирование создаёт новый объект, копируя все поля источника и рекурсивно создавая копии всех объектов, на которые эти поля ссылаются. Таким образом, все ссылки в копии ведут на отдельные объекты, не связанные с оригиналом. Поверхностное копирование создаёт новый объект, но копирует только значения полей на верхнем уровне. Если поля являются ссылками на другие объекты, то копия будет ссылаться на те же объекты, что и исходный.
Глубокое копирование предпочтительно, когда нужно полностью изолировать копию от оригинала, чтобы изменения в одном не влияли на другой. Поверхностное копирование эффективно, когда нужно сэкономить память или время на копирование, и если объекты, на которые есть ссылки, не изменяются или их изменения допустимы в обоих экземплярах.
#вопросы_с_собеседований
ext_aggregateext_aggregate — это функция, которая используется для вычисления агрегатных функций над элементами контейнера. Агрегатные функции — это функции, которые возвращают значение, основанное на значениях всех элементов контейнера. Например, функция sum() возвращает сумму всех элементов контейнера, а функция max() возвращает максимальное значение в контейнере.
Функция ext_aggregate принимает два аргумента:
Первый аргумент — это контейнер, над элементами которого необходимо вычислить агрегатную функцию.
Второй аргумент — это функция, которая определяет агрегатную функцию, которую необходимо вычислить.
Функция ext_aggregate возвращает значение, вычисленное агрегатной функцией.
#для_продвинутых
std::formatstd::format — это функция в C++, которая используется для форматирования текста. Она может использоваться для вставки значений переменных, строк и других объектов в шаблон текста.
Форматирование текста с помощью std::format похоже на форматирование текста с помощью printf. Однако std::format более безопасный и эффективный, чем printf.
Чтобы использовать std::format, вам необходимо включить заголовочный файл <format>.
#для_начинающих
⌨️ Открытый урок «Умные указатели в С++»
🗓 23 октября в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «C++ Developer. Professional».
🎯 Что рассмотрим на вебинаре:
✔️ Узнаем, для чего нужны умные указатели
✔️ Рассмотрим правило "взял память - верни, когда больше не нужна"
✔️ Разберемся с разными типами умных указателей
👥 Кому будет интересно:
- junior, junior+ C++ Разработчикам
Чему научатся участники по итогам вебинара:
- Научимся решать проблему управления ресурсами
- Рассмотрим глупый умный указатель; unique_ptr.; Shared_ptr; weak_ptr; enable_shared_from_this
- Научимся выбирать нужный умный указатель
🔗 Ссылка на регистрацию: https://otus.pw/5Dlx/
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Карьерный буст, робот в подарок и призовой фонд 7 500 000 рублей 🤖
Успей зарегистрироваться до 20 октября.
Все это ждет участников трека «Программирование роботов» на всероссийском ИТ-чемпионате МТС True Tech Champ 2025. Присоединяйся, если пишешь на С++, Go, Python, JS, Java, C# или другом языке.
Соревнования пройдут в командах от 2 до 4 человек в несколько этапов:
— Квалификация. Тебе предстоит запрограммировать робота на прохождение виртуального лабиринта.
— Полуфинал. Ты будешь дистанционно управлять роботом на офлайн-полигоне и наблюдать за его перемещениями в трансляции.
— Финал. За две недели до финала организаторы отправят тебе настоящего робота для кастомизации. Ты сможешь модифицировать его, чтобы он оказался быстрее других в многоуровневом офлайн-лабиринте и смог выбить соперников с платформы в шоу-битве.
Команды финалистов получат по одному роботу Waveshare Cobra Flex в подарок и сразятся за крупные денежные призы: 4 000 000 ₽ за первое место, 2 500 000 ₽ за второе и 1 000 000 ₽ за третье.
Еще ты сможешь:
— Получить практический опыт работы с инструментами, с помощью которых создают домашних и промышленных роботов.
— Прокачать компетенции, которые помогут развиваться в ИТ.
— Заявить о себе на всю Россию и ускорить свой профессиональный рост.
📍 Финал состоится 21 ноября в МТС Live Холл в Москве.
👉🏻 Регистрируйся на сайте до 20 октября.
Requires-expressionRequires-expression (выражение требований) – это мощная функциональность, появившаяся в C++20, которая позволяет выражать требования к типам и выражениям непосредственно в коде.
Вот основные особенности requires-expression:
— Логическое выражение: Оценивается в true или false во время компиляции.
— Используется для проверки:
— Соответствия типам и выражениям концепциям.
— Других требований к типам и выражениям.
Применение:
— Внутри шаблонов.
— Внутри constexpr функций.
— Вне шаблонов и constexpr функций (с ограничениями).
Преимущества использования requires-expression:
— Улучшение читаемости и понятности кода: Требования к типам и выражениям становятся более явными.
— Повышение безопасности кода: Ошибки, связанные с несоответствием типов, выявляются во время компиляции.
— Улучшение производительности: Константные проверки требований позволяют оптимизировать код.
#для_продвинутых
Алгоритм reverse_copy
Алгоритм копирует элементы из заданного диапазона, но в обратном порядке.
Принимает три параметра. Первые два параметра — это диапазон копируемых элементов, а третий параметр — начальная точка, из которой элементы копируются в обратном порядке.