Senior C++ Developer
13.1K subscribers
1.25K photos
4 videos
577 links
№ 4931128893
Изучаем C++.

По вопросам сотрудничества: @adv_and_pr
Download Telegram
#вопросы_с_собеседований
Что такое union?

Union - это специальный класс, который позволяет хранить данные разных типов в одной области памяти.
Основные характеристики:

- Объявляется с ключевым словом union.
- В каждый момент активно только одно поле.
- Размер равен наибольшему полю.
- Позволяет интерпретировать одну область памяти разными способами.
- Экономит память.
- Доступ к полям как в обычном классе.
#вопросы_с_собеседований
Что такое рефакторинг?

Рефакторинг - это процесс изменения внутренней структуры программы без изменения ее внешнего поведения.

Рефакторинг кода может применяться в следующих ситуациях:

- Улучшение читаемости и понятности кода.
- Оптимизация производительности.
- Устранение дублирования кода.

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

Ключевое слово const используется для создания констант и неизменяемых объектов.

- Const для объявления переменных: запрещает изменение объекта после инициализации.

- Const указатели и ссылки: указатель или ссылка на константный объект. Нельзя изменить объект через них, только читать.

- Функции, возвращающие const значения: гарантируют, что функция не изменит объект.

- Const члены класса: нельзя изменить через объект класса.

- Const методы класса: не меняют члены класса. Часто применяются к getter-методам.

#это_база
Ключевое слово auto

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

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

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

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

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

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

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

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

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

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

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

#это_база
Токенизация строки

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

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

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

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

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

#это_база
buf указатель

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

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

Часто применяется в сетевом программировании, криптографии.
std::array

std::arrayэто шаблонный контейнерный тип данных, представляющий собой статический массив с фиксированным размером.
В отличие от обычных C-style массивов, std::array является полноценным объектом со всеми преимуществами ООП.

Основные характеристики:
— Размер массива задается шаблонным параметром и не может изменяться во время выполнения.
— Элементы хранятся в последовательной памяти, что дает хорошую локальность и производительность.
— Поддерживает итераторы, можно использовать в циклах range-for.
— Имеет полезные методы — size(), front(), back(), data() и др.
— Автоматически инициализирует элементы по умолчанию.
— Передается по значению, в отличие от сырых указателей.
Декомпозиция при объявлении (structural bindings)

Structural bindings — это возможность С++17 разложить объект на отдельные переменные прямо в месте объявления.
Позволяет избежать временных объектов при разборе структур, сокращает и упрощает код при работе со структурами.

Structural bindings активно используется в модульном тестировании для проверки структур и классов.
Также применяется для деструктуризации данных в функциональном программировании.
static_assert

static_assert — это механизм проверки условий компиляции. Он позволяет выдавать ошибку компиляции, если не выполняется некое условие.

Основные случаи использования:
— Проверка размера типов данных.
— Проверка наличия функций или методов у классов.
— Верификация определенных свойств на этапе компиляции.
— Проверка корректности шаблонных параметров.
— Выявление ошибок в зависимостях между типами данных.

Преимущества:
— Выявляет ошибки на этапе компиляции, не дожидаясь выполнения.
— Позволяет проверить условия, которые нельзя проверить во время выполнения.
— Улучшает читаемость кода за счет явных проверок.

static_assert широко используется в шаблонах и метапрограммировании.
#вопросы_с_собеседований
Расскажите о работе с сырыми указателями.

Работа с сырыми указателями (raw pointers) требует внимания к управлению памятью:

— Сырой указатель содержит только адрес памяти, без информации о длительности владения.

— Память под указатель выделяется вручную с помощью new и освобождается вручную с delete.

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

— Нужно следить за правильностью вызовов new/delete во избежание ошибок.

— Может привести к проблемам при копировании указателей (неявное копирование объекта).

— Предпочтительно использовать умные указатели вроде unique_ptr для безопасности.

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

— Требуют явного кодирования работы с памятью в стиле Си.
#вопросы_с_собеседований
Расскажите об использовании realloc в контейнерах.

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

realloc вызывается при заполнении текущего буфера в контейнере и память перевыделяется большими блоками (обычно в 2 раза больше). Это позволяет избежать постоянного выделения памяти заново.
Само перевыделение происходит автоматически, скрыто от разработчика.

При частых вызовах может привести к фрагментации памяти.
Алгоритм equal_range

equal_range — это алгоритм поиска из стандартной библиотеки, который находит диапазон элементов, эквивалентных заданному значению.

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

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

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

partial_sort — это алгоритм сортировки из стандартной библиотеки, который упорядочивает только часть контейнера.
Сортирует элементы в диапазоне [first, middle). Элементы справа от middle остаются без изменений

При работе с частью данных эффективнее полной сортировки. Внутри использует алгоритм quicksort.

Применение:
— Быстрый поиск K наибольших/наименьших элементов.
— Сортировка только части большого массива данных.
— Оптимизация производительности по сравнению с полной сортировкой.

#это_база
#вопросы_с_собеседований
Что такое SIMD-инструкции?

SIMD-инструкции — это специальные команды процессора, которые работают с векторными регистрами и могут выполнять одну операцию над несколькими элементами данных параллельно.

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

Основные преимущества SIMD:
— Повышение производительности за счет параллельных вычислений.
— Эффективное использование пропускной способности процессора.
— Уменьшение количества инструкций за счет векторизации.
— Оптимизация алгоритмов обработки массивов, матриц, фильтрации, графики.
#вопросы_с_собеседований
Что такое variadic templates?

Variadic templates — это функция шаблонов, которая позволяет определить функцию или класс с переменным количеством аргументов.
Эта возможность появилась в C++11.

Variadic templates позволяют создавать функции, которые могут принимать произвольное количество аргументов, не зная заранее их типов.
Это достигается за счет использования упаковки аргументов (pack expansion) и рекурсивных шаблонов.

Проще говоря, variadic templates расширяют возможности шаблонов и позволяют создавать гибкие и универсальные компоненты.
This media is not supported in your browser
VIEW IN TELEGRAM
Плюсовики, отмечаем 2 августа в календаре: Яндекс проведет C++ Zero Cost Conf

Участников ждет прикладной C++ и десятки докладов от экспертов из Яндекса, Ozon, VK, Авито и других компаний. Конференция пройдет в трёх городах — Москве, Санкт-Петербурге и Белграде.

В Санкт-Петербурге Ваня Ходор, руководитель бэкенда каталога в
Яндекс Лавке, выступит с докладом на тему «i, j, k и шаблоны: вспоминаем линейную алгебру». Там же разработчики из VK, Кирилл Гарманов и Илья Кокорин, расскажут, с какими проблемами специалисты сталкиваются, когда пишут конкурентные структуры данных и как значительно облегчить боль от проверки и отладки конкурентного кода.

В Москве Антон Полухин, руководитель группы разработки общих компонентов в Техплатформе Городских сервисов Яндекса, расскажет, как использовать C++20 модули в больших существующих проектах с поддержкой старых стандартов.

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

Ромбовидное наследование (diamond inheritance) — это ситуация, когда класс наследуется от нескольких базовых классов, которые в свою очередь наследуются от общего предка.
Например:

class A { };
class B : public A { };
class C : public A { };
class D : public B, public C { };

Здесь класс D наследуется от B и C, которые оба наследуются от класса A. Получается ромбовидная иерархия наследования.

На изображении класс D наследуется от B и C, которые в свою очередь наследуют метод print() от A.
При вызове printAll() метод print() вызывается дважды — по пути наследования через B и через C.
Алгоритм stable_partition

Алгоритм std::stable_partition используется для разбиения контейнера на две части по какому-либо условию.

Он принимает начало и конец контейнера, а также условие в виде функции или лямбда-выражения.
В результате все элементы, для которых условие истинно, окажутся в начале контейнера, а остальные — в конце.

Отличие от partition в том, что stable_partition сохраняет относительный порядок элементов. Те, что шли перед разбиением в одной группе, останутся в том же порядке после.
Это бывает важно, например, при разбиении по нескольким критериям.

В примере мы разделили вектор на две части — четные и нечетные числа. Благодаря stable_partition сохранен относительный порядок элементов в каждой части.

#это_база
Функция resize

Функция resize служит для изменения размера контейнеров, например вектора или deque.
Она динамически меняет количество элементов в контейнере на указанное число.

Например, для вектора numbers вызов:
numbers.resize(100);

Установит размер вектора в 100 элементов.
Если изначально элементов было меньше — новые будут инициализированы по умолчанию (нулями). Если было больше — лишние удалятся.

Также можно явно задать значение для инициализации:
numbers.resize(80, -1);

Также resize принимает вектор-шаблон для копирования значений при расширении.

#это_база