Senior C++ Developer – Telegram
Senior C++ Developer
12.3K subscribers
1.36K photos
3 videos
609 links
Изучаем C++.

По вопросам сотрудничества: @adv_and_pr

РКН: https://www.gosuslugi.ru/snet/676e9a1e4e740947beca35ba
Download Telegram
buf указатель

buf — это указатель на буфер (массив байтов), часто использующийся для работы с бинарными данными.
Объявляется как u_char *buf или unsigned char *buf. Хранит данные типа unsigned char. Используется для указания на выделенный буфер памяти, куда будут помещаться данные.

В основном используется совместно с функциями memcpy, memset и др. для копирования данных.

Часто применяется в сетевом программировании, криптографии.
Токенизация строки

Токенизация строки — это процесс разбиения строки на токены (лексемы) — отдельные элементы, например слова, числа, операторы.

Для токенизации нужно:

— Разбить строку на токены при помощи разделителей, например пробелов.
— Классифицировать каждый токен — определить его тип (число, строка, оператор и т. д.)
— Преобразовать токены к нужному типу, например из строки в число.
— Сохранить результаты в подходящей структуре данных.
— Обрабатывать ошибки, например неверный формат числа.

Для разбиения строки на токены в С++ удобно использовать stringstream.
Для хранения результатов часто используют структуры или классы, хранящие тип и значение токена.

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

#это_база
rvalue

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

Константные ссылки или ссылки на const (const T&) могут связываться только с lvalues.
Неконстантные ссылки (T&) могут связываться как с lvalues, так и с rvalues.

*Lvalue — объект с именем, например переменная.

#это_база
#вопросы_с_собеседований
Как работают константные методы?

Константные методы — это методы, которые помечены модификатором final. Это означает, что тело метода не может быть переопределено в подклассах.

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

Основные характеристики константных методов:
— Могут вызываться на экземплярах класса, так как не являются статическими.
— Может обращаться к полям класса, даже нестатическим, т. к. вызывается на объекте класса.
— Может вызывать другие методы класса, в том числе не константные.
— Сигнатура константного метода в подклассе должна полностью совпадать с сигнатурой в суперклассе, иначе это будет перегрузка, а не переопределение.
#вопросы_с_собеседований
Что такое глубокое копирование?

Глубокое копирование (deep copy) — это создание полной копии объекта, включая все его внутренние объекты и поля.
В Java глубокое копирование нужно реализовывать вручную, так как оператор присваивания и конструктор копирования создают поверхностную копию (shallow copy).

При поверхностном копировании копируются только поля текущего объекта. Внутренние объекты не копируются, а их ссылки просто переносятся в новый объект.
При глубоком копировании рекурсивно копируются также все вложенные объекты. Это позволяет разорвать связь между исходным объектом и копией.

Для глубокого копирования в Java используют:
— Переопределение метода clone().
— Сериализацию объекта.
— Вручную рекурсивно копировать все поля и вложенные объекты.

Глубокое копирование нужно, чтобы изменения в копии объекта не влияли на оригинал. Это важно для правильной работы программы.
Паттерн Strategy

Паттерн Strategy — это паттерн проектирования, который позволяет определять семейства связанных алгоритмов и делать их взаимозаменяемыми.
Это дает возможность выбирать конкретный алгоритм во время выполнения программы.

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

Это паттерн используется, когда:
— Нужно использовать разные варианты одного и того же алгоритма в разных ситуациях.
— Нужно легко добавлять новые стратегии, не меняя существующий клиентский код.
— Нужно избавиться от условных операторов, выбирающих алгоритм.
std::byte

std::byteэто тип данных, представляющий собой байт, введенный в С++17.
Это тип с фиксированным размером в 1 байт, в отличие от char, размер которого зависит от платформы. Гарантированно не имеет знака (unsigned)
Поддерживает все операции сдвига и битовые операции

std::byte используется в следующих случаях:
— Для представления байтовых данных без неявных преобразований типов.
— В низкоуровневом коде, работающем с памятью, регистрами и т. д.
— В криптографии и работе с сетевыми данными.
— Для явного обозначения, что переменная содержит просто байт данных.

Преимущества std::byte:
— Независим от платформы, в отличие от char и uint8_t.
— Повышает читаемость кода, явно указывая на тип "байт".
— Исключает ошибки преобразования к int/bool при вычислениях.
Побитовое копирование

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

Побитовое копирование быстрее обычного копирования, так как не требует вызова конструкторов и деструкторов. Но при этом копируются все данные объекта, даже те, которые не нужны.

Чтобы предотвратить побитовое копирование для класса, можно объявить конструктор копирования и оператор присваивания private. Тогда компилятор выдаст ошибку при попытке копирования.
Также для предотвращения побитового копирования можно использовать ключевое слово delete для этих методов.

#это_база
Почленное копирование

Почленное копирование — это копирование объекта с полным копированием его внутреннего состояния.
Оно используется для корректного копирования там, где побитовое копирование оказывается неэффективным.

Почленное копирование выполняется с помощью конструктора копирования и оператора присваивания. В них для каждого поля выполняется отдельное копирование.
Для указателей и выделенной памяти почленное копирование подразумевает выделение новой памяти и копирование данных по элементам.

Почленное копирование медленнее побитового, так как требует дополнительных операций. Зато оно корректно копирует состояние объекта.
Но, зато оно помогает избежать типичных ошибок, связанных с побитовым копированием.

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

#это_база
#вопросы_с_собеседований
Почему вызов container.size() перед каждой итерацией цикла является плохой практикой?

Вызов container.size() перед каждой итерацией по контейнеру не является оптимальным, так как это приводит к линейной сложности O(n).

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

Это позволяет избежать лишних вычислений размера на каждой итерации и улучшает производительность.
#вопросы_с_собеседований
В чем разница между многопоточностью и асинхронностью?

Разница между многопоточностью и асинхронностью заключается в подходе к параллельному выполнению кода.

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

Асинхронность же основана на событийной модели — код выполняется последовательно в рамках одного потока, но части кода могут приостанавливаться в ожидании каких-либо событий (например, завершения ввода-вывода).
Это позволяет избежать сложностей синхронизации, но ограничивает возможности параллелизма.

Таким образом, многопоточность эффективнее использует ресурсы процессора, а асинхронность проще в реализации и избегает проблем синхронизации.
std::get

Функция std::get используется для получения элемента из структуры данных по указанному индексу или ключу.
Она применяется, когда нужно получить доступ к элементу внутри контейнера, такого как массив, вектор, map и другие. При этом сам тип контейнера может быть обобщенным.

std::get позволяет абстрагироваться от конкретного типа контейнера и работать с элементами единообразно, указывая лишь индекс или ключ нужного элемента.
Это упрощает код и делает его более универсальным. Нет необходимости писать отдельный код для доступа к элементам структур.
std::optional

std::optionalэто класс-обертка, который может содержать значение или быть пустым.
Он используется для обозначения опционального значения.

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

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

autoэто тип вывода, который позволяет компилятору автоматически определять тип переменной на основе выражения инициализации.
Он был введен в C++11 для упрощения объявления переменных, избавляя от необходимости указывать длинные и сложные типы.

При использовании auto тип переменной выводится компилятором во время компиляции и не может меняться во время выполнения.
Работает для любых типов данных — встроенных, пользовательских, шаблонов.

Переменная, объявленная с auto, всегда инициализируется при объявлении.

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

#это_база
Алгоритм find_if

Find_if — это алгоритм из стандартной библиотеки algorithm. Он применяется к диапазону элементов (например, контейнеру) и ищет элемент, удовлетворяющий заданному условию.
В качестве условия передается функция или функциональный объект (предикат). Предикат принимает элемент и возвращает истину, если элемент подходит.

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

Find_if удобно применять с лямбда-функциями в качестве предикатов поиска.

#это_база
#вопросы_с_собеседований
Какая разница между структурой и классом?

Главное отличие заключается в том, что структуры по умолчанию имеют public доступ к своим полям, в то время как классы по умолчанию имеют private доступ.

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

В целом, структуры чаще используются для простых данных, а классы — для представления более сложных сущностей и их взаимодействия.
Выбор между ними зависит от конкретной задачи и требований к программе.
#вопросы_с_собеседований
Как изменить поле класса в константном методе класса?

В константном методе класса нельзя изменить значение поля, объявленного как const.
Однако, можно изменить поле, объявленное без ключевого слова const, даже внутри const метода. Хотя это и не рекомендуется, так как нарушает идею неизменяемости объекта в константном контексте.

Чтобы все же иметь возможность модифицировать поля внутри const метода, можно объявить нужные поля как mutable. Тогда компилятор разрешит изменять эти поля, даже если вызов осуществляется на константный объект и из константного метода.
Но использование mutable стоит ограничивать, по возможности избегая. Лучше пересмотреть структуру класса, чтобы константные методы не нуждались в изменении полей.
std::any_cast

std::any_cast используется для приведения объектов типа std::any к конкретному типу данных во время выполнения программы.

Класс std::any может хранить данные любого типа, но при этом теряется информация о реальном типе данных.
Чтобы получить эти данные обратно в изначальный тип, и используется std::any_cast. Он проверяет, совместим ли хранимый в std::any объект с запрошенным целевым типом.
Если совместим — возвращает ссылку на данные нужного типа.

Например, если в std::any был помещен объект типа int, то с помощью std::any_cast этот int можно получить обратно в переменную типа int. Аналогично для других типов данных.
Функция value_or

Функция value_or используется для получения значения из объекта типа std::optional.

Класс std::optional позволяет хранить значение или отсутствие значения.
Чтобы получить это значение из optional, обычно используют метод value(). Но если значения нет, это выбросит исключение.

Чтобы избежать исключения при отсутствии значения, можно воспользоваться функцией value_or. Она принимает объект std::optional и значение по умолчанию.
Если в optional есть значение — возвращается оно. Если значения нет — возвращается значение по умолчанию.
memset

memset используется для заполнения блока памяти одним значением байта.
Она принимает указатель на блок памяти, значение байта для заполнения и размер блока в байтах.

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

#это_база
std::swap

std::swap находится в заголовочном файле <utility> и используется для обмена значениями двух переменных одного типа.
Функция принимает ссылки на две переменные типа T. Меняет их местами.

Работает с любыми типами данных, которые поддерживают оператор присваивания. Может быть перегружен для пользовательских типов данных.
Также стандартная библиотека С++ содержит специализированные версии swap для контейнеров.

Часто используется вместо ручного обмена значениями с помощью третьей переменной.

#это_база