msg_ptr (message pointer)
msg_ptr это указатель на структуру или класс, который содержит данные сообщения. Обычно это просто указатель void*.
Он используется в многопоточном программировании для передачи сообщений между потоками.
Использование указателей вместо копирования данных позволяет избежать лишних копий и ускорить передачу сообщений между потоками.
Если запустить код из примера, можно увидеть, что данные успешно передаются между потоками через очередь с использованием указателей на сообщения.
msg_ptr это указатель на структуру или класс, который содержит данные сообщения. Обычно это просто указатель void*.
Он используется в многопоточном программировании для передачи сообщений между потоками.
Использование указателей вместо копирования данных позволяет избежать лишних копий и ускорить передачу сообщений между потоками.
Если запустить код из примера, можно увидеть, что данные успешно передаются между потоками через очередь с использованием указателей на сообщения.
Функция before_begin()
Метод before_begin() контейнера forward_list возвращает итератор, указывающий на позицию перед первым элементом списка.
Это полезно, например, чтобы вставить элемент в начало списка.
Работает за константное время O(1), т.к. получает ссылку на начало списка.
#это_база
Метод before_begin() контейнера forward_list возвращает итератор, указывающий на позицию перед первым элементом списка.
Это полезно, например, чтобы вставить элемент в начало списка.
Работает за константное время O(1), т.к. получает ссылку на начало списка.
#это_база
try_emplace
Метод try_emplace() в C++17 - это один из способов вставки элемента в ассоциативный контейнер (например, map или unordered_map).
Позволяет вставить новый элемент по ключу, если такого ключа еще нет в контейнере.
Если ключ уже существует, то ничего не происходит.
Преимущества:
- Более эффективно, чем insert, т.к. сразу конструирует элемент на месте.
- Не делает лишних копирований или перемещений.
- Позволяет избежать ненужного перезаписывания элемента по существующему ключу.
Метод try_emplace() в C++17 - это один из способов вставки элемента в ассоциативный контейнер (например, map или unordered_map).
Позволяет вставить новый элемент по ключу, если такого ключа еще нет в контейнере.
Если ключ уже существует, то ничего не происходит.
Преимущества:
- Более эффективно, чем insert, т.к. сразу конструирует элемент на месте.
- Не делает лишних копирований или перемещений.
- Позволяет избежать ненужного перезаписывания элемента по существующему ключу.
#вопросы_с_собеседований
Почему std::make_pair больше не нужна?
В новых стандартах C++ она утратила актуальность по нескольким причинам:
— Появились инициализаторы со скобками {} для создания std::pair напрямую.
— Для вставки в контейнеры теперь есть функция emplace(), которая конструирует элемент прямо на месте.
— Можно использовать агрегатную инициализацию.
— Инициализаторы из C++17 позволяют сразу указывать ключ и значение.
Почему std::make_pair больше не нужна?
— Появились инициализаторы со скобками {} для создания std::pair напрямую.
— Для вставки в контейнеры теперь есть функция emplace(), которая конструирует элемент прямо на месте.
— Можно использовать агрегатную инициализацию.
— Инициализаторы из C++17 позволяют сразу указывать ключ и значение.
insert_or_assign
insert_or_assign — это функция из стандартной библиотеки языка C++, добавленная в C++17. Она используется для вставки элемента в ассоциативный контейнер (например, std::map) или обновления значения элемента, если ключ уже существует.
Преимущества перед operator[]:
— Более безопасна, так как проверяет существование элемента.
— Избавляет от лишнего кода для проверки наличия ключа.
insert_or_assign — это функция из стандартной библиотеки языка C++, добавленная в C++17. Она используется для вставки элемента в ассоциативный контейнер (например, std::map) или обновления значения элемента, если ключ уже существует.
Преимущества перед operator[]:
— Более безопасна, так как проверяет существование элемента.
— Избавляет от лишнего кода для проверки наличия ключа.
std::size
std::size — это функция из стандартной библиотеки C++, которая возвращает размер контейнера или массива.
Она определена в заголовочном файле <iterator>, работает со всеми стандартными контейнерами (vector, deque, list, array и др.) и с массивами всех типов, позволяя получить размер контейнера или массива в runtime.
#это_база
std::size — это функция из стандартной библиотеки C++, которая возвращает размер контейнера или массива.
Она определена в заголовочном файле <iterator>, работает со всеми стандартными контейнерами (vector, deque, list, array и др.) и с массивами всех типов, позволяя получить размер контейнера или массива в runtime.
#это_база
Атрибут nodiscard
Атрибут nodiscard — это специальный атрибут-маркер, который указывает компилятору предупреждать при игнорировании возвращаемого значения функции или метода.
Он был добавлен в С++17 для улучшения качества кода, указывается перед объявлением функции или метода и информирует компилятор, что возвращаемое значение не должно игнорироваться.
Позволяет избежать логических ошибок при игнорировании важных результатов функции.
В этом примере функция getResult() помечена атрибутом [[nodiscard]].
При вызове getResult() без использования возвращаемого значения компилятор выдаст предупреждение об игнорировании результата.
Атрибут nodiscard — это специальный атрибут-маркер, который указывает компилятору предупреждать при игнорировании возвращаемого значения функции или метода.
Он был добавлен в С++17 для улучшения качества кода, указывается перед объявлением функции или метода и информирует компилятор, что возвращаемое значение не должно игнорироваться.
Позволяет избежать логических ошибок при игнорировании важных результатов функции.
В этом примере функция getResult() помечена атрибутом [[nodiscard]].
При вызове getResult() без использования возвращаемого значения компилятор выдаст предупреждение об игнорировании результата.
Функция strrchr()
Функция strrchr(), объявленная в заголовочном файле <cstring>, ищет последнее вхождение указанного символа в строке и возвращает указатель на это вхождение.
Принимает два параметра: указатель на строку и символ для поиска, возвращает указатель на последнее вхождение символа в строке. Если символ не найден, возвращается нулевой указатель.
Полезна, когда нужно найти последнее вхождение разделителя, например точки в URL.
В примере функция strrchr() возвращает указатель на найденный символ, мы вычитаем из этого указателя начало строки, чтобы получить позицию последней точки.
#это_база
Функция strrchr(), объявленная в заголовочном файле <cstring>, ищет последнее вхождение указанного символа в строке и возвращает указатель на это вхождение.
Принимает два параметра: указатель на строку и символ для поиска, возвращает указатель на последнее вхождение символа в строке. Если символ не найден, возвращается нулевой указатель.
Полезна, когда нужно найти последнее вхождение разделителя, например точки в URL.
В примере функция strrchr() возвращает указатель на найденный символ, мы вычитаем из этого указателя начало строки, чтобы получить позицию последней точки.
#это_база
#вопросы_с_собеседований
Что такое сложность алгоритма и от чего она зависит?
Сложность алгоритма - это количественная характеристика его эффективности, которая показывает, как зависят затраты ресурсов (времени, памяти) от размера входных данных.
Сложность зависит от:
— Объема операций, которые алгоритм выполняет при обработке данных.
— Количества итераций циклов, рекурсивных вызовов.
— Зависимости числа операций от размера входных данных.
— Операций внутри вложенных циклов и структур.
Чем быстрее растёт сложность функции с ростом входных данных, тем менее эффективен алгоритм.
Что такое сложность алгоритма и от чего она зависит?
Сложность зависит от:
— Объема операций, которые алгоритм выполняет при обработке данных.
— Количества итераций циклов, рекурсивных вызовов.
— Зависимости числа операций от размера входных данных.
— Операций внутри вложенных циклов и структур.
Чем быстрее растёт сложность функции с ростом входных данных, тем менее эффективен алгоритм.
absl::btree
absl::btree — это реализация B-дерева в библиотеке Abseil для C++.
Преимущества absl::btree — это хранение данных в отсортированном порядке, быстрый поиск, вставка и удаление за O(logN), поддержка уникальных и неуникальных ключей, реализация set и map.
Применяется в задачах, где нужна высокопроизводительная структура данных с отсортированным доступом, например:
Реализация словарей и сортированных множеств;
Для хранения данных в базах данных;
В поисковых системах для индексов;
В структурах вроде кэша для быстрого доступа;
В задачах машинного обучения для хранения данных.
absl::btree — это реализация B-дерева в библиотеке Abseil для C++.
Преимущества absl::btree — это хранение данных в отсортированном порядке, быстрый поиск, вставка и удаление за O(logN), поддержка уникальных и неуникальных ключей, реализация set и map.
Применяется в задачах, где нужна высокопроизводительная структура данных с отсортированным доступом, например:
Реализация словарей и сортированных множеств;
Для хранения данных в базах данных;
В поисковых системах для индексов;
В структурах вроде кэша для быстрого доступа;
В задачах машинного обучения для хранения данных.
std::clamp
std::clamp — это функция из стандартной библиотеки, которая позволяет ограничить значение в заданном диапазоне.
Функция принимает значение, нижнюю и верхнюю границы и возвращает исходное значение, если оно входит в диапазон, или же возвращает ближайшую границу, если значение вне диапазона.
Применяется для:
— Ограничения числовых значений в заданных пределах.
— Обработки данных из недостоверных источников.
— Защиты от переполнения/обрезания данных.
— Нормализации данных в ML и компьютерном зрении.
— Реализации игровой логики в движках.
— Обработки аудио- и видео- сигналов.
std::clamp — это функция из стандартной библиотеки, которая позволяет ограничить значение в заданном диапазоне.
Функция принимает значение, нижнюю и верхнюю границы и возвращает исходное значение, если оно входит в диапазон, или же возвращает ближайшую границу, если значение вне диапазона.
Применяется для:
— Ограничения числовых значений в заданных пределах.
— Обработки данных из недостоверных источников.
— Защиты от переполнения/обрезания данных.
— Нормализации данных в ML и компьютерном зрении.
— Реализации игровой логики в движках.
— Обработки аудио- и видео- сигналов.
Алгоритм generate
std::generate — это алгоритм из стандартной библиотеки C++, который используется для заполнения диапазона элементов сгенерированными значениями.
Принимает три параметра: начало диапазона, конец диапазона и функцию генерации. Функция генерации должна принимать неявный счетчик и возвращать очередное значение.
Для каждого элемента в заданном диапазоне будет вызываться функция генерации, и результат будет записан в этот элемент.
В этом примере std::generate совместно с генератором случайных чисел используется для быстрого заполнения вектора случайными значениями.
#это_база
std::generate — это алгоритм из стандартной библиотеки C++, который используется для заполнения диапазона элементов сгенерированными значениями.
Принимает три параметра: начало диапазона, конец диапазона и функцию генерации. Функция генерации должна принимать неявный счетчик и возвращать очередное значение.
Для каждого элемента в заданном диапазоне будет вызываться функция генерации, и результат будет записан в этот элемент.
В этом примере std::generate совместно с генератором случайных чисел используется для быстрого заполнения вектора случайными значениями.
#это_база
#вопросы_с_собеседований
Может ли inline-функция быть рекурсивной?
Поскольку компилятор просто встраивает код inline-функции в место вызова, не имеет значения, является ли эта функция рекурсивной или нет. Компилятор будет просто копировать один и тот же код функции при каждом рекурсивном вызове.
Таким образом, рекурсивные inline-функции абсолютно допустимы и часто используются, когда нужна рекурсия без накладных расходов на стандартные вызовы функций.
Может ли inline-функция быть рекурсивной?
Таким образом, рекурсивные inline-функции абсолютно допустимы и часто используются, когда нужна рекурсия без накладных расходов на стандартные вызовы функций.
#вопросы_с_собеседований
Для чего нужен атрибут fallthrough?
Атрибут [[fallthrough]] используется для явного указания того, что в конструкции switch нужно пропустить break в конце case и перейти к выполнению следующего case.
По умолчанию в С++17 и новее переход между case без break приводит к ошибке компиляции и чтобы сохранить старое поведение и разрешить переход, нужно добавить [[fallthrough]].
Это улучшает читаемость кода, явно указывая на отсутствие break и помогает избежать случайного отсутствия break, когда разработчик забыл его добавить.
[[fallthrough]] также полезен при рефакторинге старого кода с switch в современный стандарт С++.
Для чего нужен атрибут fallthrough?
По умолчанию в С++17 и новее переход между case без break приводит к ошибке компиляции и чтобы сохранить старое поведение и разрешить переход, нужно добавить [[fallthrough]].
Это улучшает читаемость кода, явно указывая на отсутствие break и помогает избежать случайного отсутствия break, когда разработчик забыл его добавить.
[[fallthrough]] также полезен при рефакторинге старого кода с switch в современный стандарт С++.
#вопросы_с_собеседований
Для чего нужен атрибут maybe_unused?
Атрибут [[maybe_unused]] используется для подавления предупреждений компилятора об неиспользуемых объектах.
Компилятор выдает предупреждение, если объект объявлен, но нигде не используется и чтобы избавиться от ложных предупреждений, например, когда объект используется только в отладочной сборке, применяют [[maybe_unused]].
Позволяет задать политику использования на уровне отдельных объектов и улучшает читаемость кода, явно объясняя причину неиспользования.
Для чего нужен атрибут maybe_unused?
Компилятор выдает предупреждение, если объект объявлен, но нигде не используется и чтобы избавиться от ложных предупреждений, например, когда объект используется только в отладочной сборке, применяют [[maybe_unused]].
Позволяет задать политику использования на уровне отдельных объектов и улучшает читаемость кода, явно объясняя причину неиспользования.
Лямбда-выражения
Лямбда-выражения (lambda) — это безымянные функции, которые можно использовать для передачи поведения или сравнения.
Объявляются как {body;}, в квадратных скобках указываются аргументы, в фигурных — тело.
Полезны для задания функций сравнения, например в алгоритмах sort(), когда нужно быстро передать функциональность, не создавая отдельную функцию.
Поддерживают захват по значению [=] и по ссылке [&].
Можно сохранить в переменной с помощью auto.
#это_база
Лямбда-выражения (lambda) — это безымянные функции, которые можно использовать для передачи поведения или сравнения.
Объявляются как {body;}, в квадратных скобках указываются аргументы, в фигурных — тело.
Полезны для задания функций сравнения, например в алгоритмах sort(), когда нужно быстро передать функциональность, не создавая отдельную функцию.
Поддерживают захват по значению [=] и по ссылке [&].
Можно сохранить в переменной с помощью auto.
#это_база
string at()
std::string::at() — это метод для доступа к символу строки по указанному индексу.
Принимает в качестве аргумента индекс символа типа size_t и возвращает ссылку на символ по данному индексу.
— Индексация начинается с 0 до size()-1.
— Выбрасывает исключение out_of_range, если индекс вне диапазона.
— Более безопасен, чем оператор [], так как проверяет границы.
Полезен в циклах для доступа к каждому символу, когда нужен безопасный доступ для чтения/записи конкретного символа.
#это_база
std::string::at() — это метод для доступа к символу строки по указанному индексу.
Принимает в качестве аргумента индекс символа типа size_t и возвращает ссылку на символ по данному индексу.
— Индексация начинается с 0 до size()-1.
— Выбрасывает исключение out_of_range, если индекс вне диапазона.
— Более безопасен, чем оператор [], так как проверяет границы.
Полезен в циклах для доступа к каждому символу, когда нужен безопасный доступ для чтения/записи конкретного символа.
#это_база
std::data
std::data — это стандартная функция, которая возвращает указатель на недоступное буферное хранилище контейнера.
Она используется для непосредственного доступа к данным контейнера в памяти.
Основные применения:
— Прямой доступ к элементам массива или вектора для чтения/записи.
— Передача данных контейнера в функции, принимающие указатель в качестве аргумента.
— Выполнение операций, зависящих от порядка элементов в памяти.
— Оптимизации производительности за счёт избежания копирования.
— Низкоуровневые операции и интеграция с кодом на С.
— Итерация элементов в порядке хранения.
std::data — это стандартная функция, которая возвращает указатель на недоступное буферное хранилище контейнера.
Она используется для непосредственного доступа к данным контейнера в памяти.
Основные применения:
— Прямой доступ к элементам массива или вектора для чтения/записи.
— Передача данных контейнера в функции, принимающие указатель в качестве аргумента.
— Выполнение операций, зависящих от порядка элементов в памяти.
— Оптимизации производительности за счёт избежания копирования.
— Низкоуровневые операции и интеграция с кодом на С.
— Итерация элементов в порядке хранения.
std::filesystem
std::filesystem — это библиотека для работы с файловой системой: файлами, каталогами, путями.
Она появилась в С++17 и используется для:
— Получения информации о файлах.
— Операций с каталогами.
— Работы с путями.
— Проверки существования файлов и каталогов.
— Обхода дерева каталогов, в т. ч. рекурсивного.
— Копирования и перемещения файлов, директорий.
— Синхронной и асинхронной работы с файлами.
— Работы с правами доступа и временными метками.
std::filesystem — это библиотека для работы с файловой системой: файлами, каталогами, путями.
Она появилась в С++17 и используется для:
— Получения информации о файлах.
— Операций с каталогами.
— Работы с путями.
— Проверки существования файлов и каталогов.
— Обхода дерева каталогов, в т. ч. рекурсивного.
— Копирования и перемещения файлов, директорий.
— Синхронной и асинхронной работы с файлами.
— Работы с правами доступа и временными метками.
Функция minmax_element
Функция minmax_element — это алгоритм из стандартной библиотеки algorithm, который позволяет найти минимальный и максимальный элементы в диапазоне.
Функция принимает два итератора, задающих диапазон поиска и возвращает пару итераторов на минимальный и максимальный элементы. Работает для любых типов данных, поддерживающих операцию сравнения <.
Некоторые характеристики:
— Позволяет найти границы диапазона за один проход по последовательности.
— Удобна при необходимости найти пределы в контейнере или массиве.
— Предпочтительнее циклов, т. к. проще в использовании и читабельнее.
— Может применяться со стандартными контейнерами, векторами, списками.
#это_база
Функция minmax_element — это алгоритм из стандартной библиотеки algorithm, который позволяет найти минимальный и максимальный элементы в диапазоне.
Функция принимает два итератора, задающих диапазон поиска и возвращает пару итераторов на минимальный и максимальный элементы. Работает для любых типов данных, поддерживающих операцию сравнения <.
Некоторые характеристики:
— Позволяет найти границы диапазона за один проход по последовательности.
— Удобна при необходимости найти пределы в контейнере или массиве.
— Предпочтительнее циклов, т. к. проще в использовании и читабельнее.
— Может применяться со стандартными контейнерами, векторами, списками.
#это_база
Алгоритм is_partitioned
Алгоритм is_partitioned — это алгоритм из стандартной библиотеки algorithm, который проверяет, разбит ли диапазон элементов определенным образом.
Принимает три параметра:
— Два итератора, задающих проверяемый диапазон.
— Предикат (функцию или функтор), определяющий разбиение.
Возвращает bool значение — true если диапазон разбит согласно предикату и false в противном случае.
Этот алгоритм предпочтительнее цикла, т. к. проще в использовании и читабельнее, ведь он эффективно проверяет условие за один проход по последовательности.
В примере мы определяем предикат isEven для проверки четности числа, передаем его в is_partitioned вместе с вектором v и выводим результат.
#это_база
Алгоритм is_partitioned — это алгоритм из стандартной библиотеки algorithm, который проверяет, разбит ли диапазон элементов определенным образом.
Принимает три параметра:
— Два итератора, задающих проверяемый диапазон.
— Предикат (функцию или функтор), определяющий разбиение.
Возвращает bool значение — true если диапазон разбит согласно предикату и false в противном случае.
Этот алгоритм предпочтительнее цикла, т. к. проще в использовании и читабельнее, ведь он эффективно проверяет условие за один проход по последовательности.
В примере мы определяем предикат isEven для проверки четности числа, передаем его в is_partitioned вместе с вектором v и выводим результат.
#это_база