Библиотека собеса по C++ | вопросы с собеседований
4.71K subscribers
384 photos
2 videos
163 links
Вопросы с собеседований по C++ и ответы на них.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/9ccf302b

Работать у нас: https://job.proglib.io/

Наши каналы: https://yangx.top/proglibrary/9197
加入频道
std::lock_guard

std::lock_guard — это один из классов в стандартной библиотеке C++, предназначенных для обеспечения многопоточной безопасности при работе с разделяемыми данными. Он используется для автоматического захвата и освобождения мьютекса (mutex) при входе и выходе из блока кода.

Прежде всего, мьютекс (mutex) — это механизм синхронизации, который предоставляет эксклюзивный доступ к разделяемым данным одному потоку в данный момент времени. std::lock_guard является удобной оберткой для работы с мьютексами.
Лямбда-функция

Лямбда-функция (или просто лямбда) — это анонимная функция в C++, которая может быть определена непосредственно внутри кода. Лямбда-функции предоставляют более компактный и удобный способ создания небольших функций на лету, без необходимости объявления их отдельно.

Лямбда-функции также часто используются вместе с алгоритмами стандартной библиотеки C++, такими как std::for_each, std::transform, std::sort (как на примере выше), и другими, чтобы создавать более компактный и выразительный код.
std::bitset

std::bitset — это шаблон класса, который представляет собой последовательность битов фиксированного размера N. Битовые множества могут управляться стандартными логическими операторами и преобразовываться в строки и целые числа.

В этом примере мы создаем битовое множество b размером 8 бит и инициализируем его значением 42. Затем мы выводим его на экран. Результат работы этого кода: 00101010.
Функция memmove

Функция memmove в C++ используется для перемещения блока памяти из одной части массива в другую, даже если эти блоки памяти перекрываются. Это отличается от функции memcpy, которая не гарантирует правильное копирование, если исходный и целевой блоки перекрываются.

Прототип функции memmove выглядит следующим образом:

void* memmove(void* destination, const void* source, size_t num);

Здесь:

destination — указатель на начало блока памяти, в который нужно переместить данные.
source — указатель на начало блока памяти, из которого нужно скопировать данные.
num — количество байтов, которые нужно переместить.

Функция memmove обеспечивает корректное копирование данных, даже если destination и source перекрываются. Это означает, что она может быть использована в случаях, когда memcpy может привести к неправильным результатам из-за перекрытия.
Побитовое копирование

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

В C++ побитовое копирование выполняется конструктором копирования. Если конструктор копирования не определен для класса, компилятор генерирует его неявно. Генерируемый компилятором конструктор копирования выполняет побитовое копирование всех членов данных класса.
Спецификаторы доступа

В C++ используются три спецификатора доступа: public, private и protected. Они определяют, кто может получить доступ к членам класса или структуры.

public — члены с таким спецификатором доступны из любого места программы, включая другие классы и структуры.
private — члены с таким спецификатором доступны только из самого класса, в котором они объявлены.
protected — члены с таким спецификатором доступны из самого класса, в котором они объявлены, а также из производных классов.

По умолчанию все члены класса объявляются с спецификатором private, а члены структуры — с public.

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

Функция floor в C++ используется для округления числа с плавающей запятой (типа float или double) вниз до ближайшего целого числа, которое меньше или равно исходному числу. Функция floor является частью стандартной библиотеки C++ и объявлена в заголовочном файле cmath.

Функция floor полезна, например, при работе с денежными суммами, когда вам нужно округлить результат вниз до ближайшего целого значения валюты, чтобы учесть минимальные единицы валюты.
🧑‍💻 Статьи для IT: как объяснять и распространять значимые идеи

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

Что: семь модулей, посвященных написанию, редактированию, иллюстрированию и распространению публикаций.

Для кого: для авторов, копирайтеров и просто программистов, которые хотят научиться интересно рассказывать о своих проектах.

👉Материалы регулярно дополняются, обновляются и корректируются. А еще мы отвечаем на все учебные вопросы в комментариях курса.
Флаги оптимизации

🤔 Что это за флажки?
Флажки оптимизации — это специальные параметры, которые передают компилятору инструкции о том, насколько сильно он должен оптимизировать ваш код при компиляции. Уровень оптимизации может варьироваться от минимального (O0) до максимального (O3).

🔍 Чем отличаются уровни оптимизации?
O0 (Отсутствие оптимизации): Этот уровень подходит для отладки. Компилятор минимизирует время компиляции, не внося оптимизаций, чтобы облегчить отслеживание багов

O1 (Базовая оптимизация): Проводит базовые оптимизации, например, устранение мертвого кода и простые inline-функций

O2 (Средняя оптимизация): Включает более сложные оптимизации, такие как оптимизация циклов и векторизация, что приводит к более эффективному исполнению кода

O3 (Максимальная оптимизация): Производит максимально возможное количество оптимизаций. Подходит для создания высокопроизводительного кода, но может увеличить время компиляции
Вывод типа шаблона (Template Type Deduction)

⚙️ Начиная с C++11 появилась возможность переложить вывод типа на компилятор — вывод типа шаблона (Template Type Deduction)

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

Начиная с C++11 каждый класс, помимо конструктора по умолчанию, имеет следующие 5 дефолтных операций:

1. Конструктор копирования (Copy Constructor):
• Принимает объект своего же типа в качестве параметра
• Создает новый объект, инициализируя его значениями из переданного объекта

2. Оператор присваивания (Copy Assignment Operator):
• Присваивает значения одного объекта другому
• Вызывается при использовании оператора присваивания (=) между двумя объектами

3. Конструктор перемещения (Move Constructor):
• Это нововведение в C++11
• Принимает rvalue-ссылку на объект своего типа в качестве параметра

4. Оператор перемещения (Move Assignment Operator):
• Также нововведение в C++11
• Принимает rvalue-ссылку на объект своего типа в качестве параметра

5. Деструктор (Destructor):
• Освобождает ресурсы, занимаемые объектом, при его уничтожении (выходе из области видимости, удалении из контейнера)
Сортировка контейнеров в заданном порядке

В C++, сортировка элементов в контейнерах может быть легко реализована с использованием std::sort и специализированных функциональных объектов
📚 std::exception — это базовый класс для всех стандартных исключений в C++

Почему стоит наследоваться от std::exception?

Единообразие в обработке исключений: Когда вы наследуетесь от std::exception, ваш класс исключения приобретает интерфейс, который делает его совместимым с другими стандартными исключениями

what() метод: std::exception предоставляет важный метод what(), который возвращает строковое представление исключения. Это позволяет вам предоставлять информативные сообщения об ошибке при обработке исключений

Легкость в поддержке кода: Если вы используете сторонние библиотеки или фреймворки, они также могут ожидать обработку исключений, производных от std::exception

Стандартные типы исключений: std::exception имеет несколько стандартных подклассов, таких как std::runtime_error, std::logic_error и другие. Вы можете использовать эти подклассы вместо базового std::exception, чтобы более точно определить характер ошибки
🔍 Что такое std::thread?

std::thread предоставляет собой интерфейс для взаимодействия с системными потоками

💡Что можно запустить?
• Любой функтор можно превратить в поток

💡Что можно передать при запуске потока?
• Можно передать любое количество параметров, но стоит учитывать, что все они будут копироваться
• Чтобы передать ссылку, её стоит обернуть в std::ref или std::cref

💡Что можно сделать с потоком?
• После создания потока мы можем с ним делать две вещи: вызвать join и ждать завершение потока или вызвать detach, тогда поток просто будет работать (пока сам не завершится)

💡Начиная с C++20 появился std::jthread
• Это тоже самое, но в деструкторе будет вызываться join
Dependency Injection

Dependency Injection (DI) — это паттерн проектирования, который помогает управлять зависимостями в приложениях. Он особенно важен в объектно-ориентированных языках программирования, таких как C++, где классы и объекты играют центральную роль.

DI предполагает, что зависимости (например, объекты других классов, которые класс использует) должны передаваться в класс извне, а не создаваться им самостоятельно. Это делает класс более независимым и более тестируемым. В C++, DI можно реализовать следующими способами: внедрение через конструктор, внедрение через метод и использование фабрик. В картинке с примером мы используем внедрение через конструктор, так как это самый распространенный способ DI в C++. В конструкторе класса вы передаете зависимости как параметры.

Использование DI в C++ способствует лучшей организации кода, более простой поддержке и тестированию. Он позволяет избегать жестких зависимостей и делает ваш код более гибким и расширяемым.
Может ли виртуальный метод быть шаблонной функцией?

Ответ: нет не может

Пояснение
• Если шаблоны будут виртуальными, то вместо перечисления функций в базовом классе надо искать все подстановки шаблона при вызовах функции
• Для этого вместо индексов надо использовать имена, и искать эти имена в хеш-таблице
• Скорость вызова значительно упадет, т.к. надо будет разрешать коллизии
co_await, co_yield и co_return

co_await, co_yield и co_return — это ключевые слова, которые используются для реализации корутин (coroutines).

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

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

co_return используется для завершения корутины и возврата результата.

В этом примере используются все три ключевых слова:
— co_await приостанавливает корутину create_task в начале.
— co_yield можно было бы использовать для дополнительных приостановок.
— co_return завершает корутину в конце.
🤔 Что такое structural bindings?

• Данная фитча появилась в C++17
• Это механизм, который позволяет нам декомпозировать структуры данных, такие как tuple, pair, и даже свои пользовательские структуры, на более простые именованные переменные
• Это делает код более читаемым, компактным и легко поддерживаемым

🌐 Ссылки
Восемь возможностей C++17, которые должен применять каждый разработчик
Structured binding declaration
Structured binding in C++ https://habr.com/ru/articles/343622/
Что такое TDD?

TDD (Test-Driven Development) — это методология разработки программного обеспечения, которая основана на повторении очень коротких циклов разработки: сначала пишется тест, покрывающий желаемое изменение, затем пишется код, который позволит пройти тест, и под конец проводится рефакторинг нового кода к соответствующим стандартам.

TDD означает, что программист сначала пишет модульный тест, который проверяет ожидаемое поведение некоторой части кода. Затем программист пишет код, который заставляет тест пройти. После этого программист может провести рефакторинг кода, чтобы улучшить его читаемость, производительность или другие свойства.
🌟 Что такое std::optional?

Это класс, появился начиная с C++17, который даёт удобный способ работы с «возможно отсутствующим» значением

🌐 Ссылки
std::optional
std::optional in C++
Рефакторинг с использованием C++17 std::optional
• Использование std::optional в С++17