C++ собеседования
839 subscribers
106 photos
222 links
Подготовка к собеседованиям на позицию C/C++ разработчик

Еще больше на сайте https://frontview-it.ru

Backend собеседования - @frontview_backend
C/C++ работа - @frontview_cpp_vacancies
Все IT вакансии - @frontview_all_vacancies
Download Telegram
🔥 Что такое move-семантика?

Move-семантика в C++ — это механизм, позволяющий оптимизировать работу с временными объектами и ресурсами. Она была введена в C++11 и позволяет передавать ресурсы от одного объекта к другому без копирования, что значительно повышает производительность.

Ключевым элементом move-семантики является rvalue-ссылка, обозначаемая как &&. Она позволяет захватывать временные объекты, которые больше не нужны в текущем контексте.

Для реализации move-семантики используются специальные функции: конструктор перемещения и оператор присваивания перемещением. Они принимают rvalue-ссылки и перемещают ресурсы.

Пример использования:


#include <iostream>
#include <utility>
#include <vector>

int main() {
std::vector<int> v1 = {1, 2, 3};
std::vector<int> v2 = std::move(v1); // Перемещение ресурсов из v1 в v2

std::cout << "v1 size: " << v1.size() << std::endl; // 0
std::cout << "v2 size: " << v2.size() << std::endl; // 3

return 0;
}


Move-семантика позволяет эффективно управлять ресурсами, избегая ненужных копирований, что особенно важно для контейнеров и объектов, работающих с динамической памятью.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍161
🔥 Как использовать std::span?

std::span — это легковесный объект, представляющий непрерывный участок памяти. Он был введен в C++20 и позволяет безопасно работать с массивами и контейнерами без копирования данных.

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

Пример использования:


#include <iostream>
#include <span>
#include <vector>

void printSpan(std::span<int> s) {
for (int value : s) {
std::cout << value << " ";
}
std::cout << std::endl;
}

int main() {
int arr[] = {1, 2, 3, 4, 5};
std::vector<int> vec = {6, 7, 8, 9, 10};

printSpan(arr); // 1 2 3 4 5
printSpan(vec); // 6 7 8 9 10

return 0;
}


std::span поддерживает операции срезов, что позволяет работать с подмассивами без копирования:


std::span<int> subSpan = s.subspan(1, 3); // элементы с 1 по 3


Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
🔥 Как использовать блоки try, catch?

В C++ блоки try и catch используются для обработки исключений, которые могут возникнуть во время выполнения программы. Эти конструкции позволяют перехватывать ошибки и предотвращать аварийное завершение программы.

Блок try содержит код, который может вызвать исключение. Если исключение возникает, управление передается в соответствующий блок catch, который обрабатывает это исключение.

Пример использования:


#include <iostream>
#include <stdexcept>

void process(int value) {
if (value < 0) {
throw std::invalid_argument("Negative value not allowed");
}
std::cout << "Processing value: " << value << std::endl;
}

int main() {
try {
process(-1);
} catch (const std::invalid_argument& e) {
std::cerr << "Caught exception: " << e.what() << std::endl;
}

return 0;
}


Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
🔥 Объясни работу со строками

Работа со строками в C++ осуществляется с помощью класса std::string, который предоставляет удобные методы для управления и манипуляции текстовыми данными. В отличие от C-строк, std::string автоматически управляет памятью и размером.

Создание и инициализация строки:


#include <iostream>
#include <string>

int main() {
std::string greeting = "Hello, world!";
std::cout << greeting << std::endl; // Вывод: Hello, world!

return 0;
}


std::string поддерживает операции конкатенации, сравнения и поиска:


std::string firstName = "John";
std::string lastName = "Doe";
std::string fullName = firstName + " " + lastName; // Конкатенация

if (fullName == "John Doe") {
std::cout << "Names match!" << std::endl;
}

size_t position = fullName.find("Doe"); // Поиск подстроки
if (position != std::string::npos) {
std::cout << "Found 'Doe' at position: " << position << std::endl;
}


Методы substr, replace, и insert позволяют изменять содержимое строк:


std::string text = "Hello, world!";
std::string sub = text.substr(0, 5); // "Hello"
text.replace(7, 5, "C++"); // "Hello, C++!"
text.insert(5, ", dear"); // "Hello, dear, C++!"


Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14
🔥 Каковы преимущества C++ по сравнению с Java?

C++ обладает рядом преимуществ, которые делают его предпочтительным в определенных сценариях.

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

C++ поддерживает множественное наследование, что позволяет классу наследовать поведение и характеристики от нескольких родительских классов. Это дает большую гибкость в проектировании архитектуры программного обеспечения.

Шаблоны в C++ обеспечивают систему обобщенного программирования, позволяя создавать универсальные и повторно используемые компоненты, которые могут работать с любыми типами данных.

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

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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍111
🔥 Как использовать std::lock_guard для синхронизации?

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

Использование std::lock_guard:


#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;
int sharedData = 0;

void increment() {
std::lock_guard<std::mutex> lock(mtx); // Блокировка мьютекса
++sharedData;
// Мьютекс автоматически разблокируется при выходе из области видимости
}

int main() {
std::thread t1(increment);
std::thread t2(increment);

t1.join();
t2.join();

std::cout << "Shared Data: " << sharedData << std::endl; // 2

return 0;
}


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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥1
🔥 Объясни принципы работы Qt

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

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

Пример использования сигналов и слотов:


#include <QApplication>
#include <QPushButton>

int main(int argc, char *argv[]) {
QApplication app(argc, argv);

QPushButton button("Click Me");
QObject::connect(&button, &QPushButton::clicked, &app, &QApplication::quit);

button.show();
return app.exec();
}


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

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

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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥1
🔥 Что такое std::weak_ptr и когда его использовать?

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

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

Для получения std::shared_ptr из std::weak_ptr используется метод lock(). Если объект уже удален, lock() вернет пустой std::shared_ptr.

Пример использования:


#include <iostream>
#include <memory>

int main() {
std::shared_ptr<int> sp = std::make_shared<int>(42);
std::weak_ptr<int> wp = sp;

if (auto locked = wp.lock()) {
std::cout << *locked << std::endl; // Вывод: 42
} else {
std::cout << "Object no longer exists" << std::endl;
}

sp.reset(); // Удаляем объект

if (auto locked = wp.lock()) {
std::cout << *locked << std::endl;
} else {
std::cout << "Object no longer exists" << std::endl; // Вывод: Object no longer exists
}

return 0;
}


std::weak_ptr — это важный инструмент для управления памятью в сложных структурах данных.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍61
🔥 Как управлять памятью в многопоточных приложениях?

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

Умные указатели, такие как std::shared_ptr и std::weak_ptr, помогают управлять временем жизни объектов. Однако std::shared_ptr не является потокобезопасным при одновременной модификации из нескольких потоков. Для этого требуется внешняя синхронизация, например, с помощью мьютексов.

Синхронизация доступа к общим данным осуществляется с помощью мьютексов std::mutex и других примитивов синхронизации, таких как std::lock_guard и std::unique_lock. Они предотвращают одновременный доступ к данным, что может привести к гонкам данных.

Пример использования мьютекса:


#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;
int sharedData = 0;

void increment() {
std::lock_guard<std::mutex> lock(mtx);
++sharedData;
}

int main() {
std::thread t1(increment);
std::thread t2(increment);

t1.join();
t2.join();

std::cout << "Shared Data: " << sharedData << std::endl; // 2

return 0;
}


Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍91
🔥 Что такое структура и как ее использовать?

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

Объявление структуры начинается с ключевого слова struct, за которым следует имя структуры и список её членов:


#include <iostream>
#include <string>

struct Person {
std::string name;
int age;
double height;
};

int main() {
Person person;
person.name = "Alice";
person.age = 30;
person.height = 1.75;

std::cout << "Name: " << person.name << std::endl;
std::cout << "Age: " << person.age << std::endl;
std::cout << "Height: " << person.height << "m" << std::endl;

return 0;
}


Структуры могут содержать методы, что делает их похожими на классы. Однако, по умолчанию, все члены структуры имеют public доступ, в отличие от классов, где они private.

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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥3🤩1
🔥 Объясни паттерн Adapter

Паттерн Adapter в C++ используется для приведения интерфейса одного класса к интерфейсу, ожидаемому клиентом. Это позволяет классам с несовместимыми интерфейсами работать вместе.

Adapter действует как обертка, которая преобразует интерфейс одного класса в интерфейс другого. Это особенно полезно при интеграции старого кода с новым или при работе с библиотеками, интерфейсы которых нельзя изменить.

Пример использования:


#include <iostream>

// Целевой интерфейс
class Target {
public:
virtual void request() const {
std::cout << "Target request" << std::endl;
}
};

// Класс с несовместимым интерфейсом
class Adaptee {
public:
void specificRequest() const {
std::cout << "Adaptee specific request" << std::endl;
}
};

// Адаптер, который делает интерфейс Adaptee совместимым с Target
class Adapter : public Target {
private:
Adaptee& adaptee;
public:
Adapter(Adaptee& a) : adaptee(a) {}

void request() const override {
adaptee.specificRequest();
}
};

int main() {
Adaptee adaptee;
Adapter adapter(adaptee);
adapter.request(); // Вывод: Adaptee specific request

return 0;
}


Паттерн Adapter позволяет использовать существующий код без изменений, обеспечивая гибкость и повторное использование.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥2
🔥 Как использовать ссылки в качестве параметров функций?

Ссылки в C++ позволяют передавать параметры в функции без копирования, что экономит память и время. Ссылки обеспечивают доступ к оригинальному объекту, позволяя функции изменять его состояние.

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


#include <iostream>

void increment(int& value) {
++value;
}

int main() {
int num = 5;
increment(num);
std::cout << num << std::endl; // 6

return 0;
}


Ссылки также могут быть константными, если требуется защитить данные от изменений. Константные ссылки const & позволяют передавать большие объекты без копирования, сохраняя их неизменными:


#include <iostream>

void printValue(const int& value) {
std::cout << value << std::endl;
}

int main() {
int num = 10;
printValue(num); // 10

return 0;
}


Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥21
🔥 Как работают перечисления?

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

В C++ существует два типа перечислений: старые перечисления (unscoped enums) и новые перечисления (scoped enums), введенные в C++11.

Старые перечисления объявляются с помощью ключевого слова enum и создают набор целочисленных констант, которые автоматически увеличиваются на единицу, начиная с нуля, если не указано иное:


enum Color { Red, Green, Blue };
Color c = Red;


Новые перечисления объявляются с использованием enum class и обеспечивают лучшую область видимости и типобезопасность. Значения таких перечислений неявно не преобразуются в целые числа:


enum class Color { Red, Green, Blue };
Color c = Color::Red;


Scoped enums требуют явного указания области видимости, что предотвращает конфликты имен и улучшает читаемость кода.

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1121
💡Директива #include в C++ используется для подключения заголовочных файлов в программу. Она позволяет компилятору вставлять содержимое указанного файла в точку, где находится директива. Это необходимо для использования функций, классов и других элементов, определённых в подключаемых файлах.

Существует два типа #include: с угловыми скобками <...> для стандартных библиотек и с кавычками "..." для пользовательских файлов. Это упрощает управление кодом и способствует его повторному использованию, обеспечивая модульность и структурированность программы.

Ставь 👍, если было полезно!
Больше ответов на сайте 👈

✈️ С++ собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍111
Std::list и std::vector — это контейнеры из стандартной библиотеки C++, но они имеют разные характеристики и предназначения.

1️⃣ std::vector — это динамический массив, который обеспечивает быстрый доступ к элементам по индексу и эффективное добавление элементов в конец. Однако вставка или удаление элементов в середине может быть медленной, так как требует сдвига элементов.

2️⃣ std::list — это двусвязный список, который позволяет быстро вставлять и удалять элементы в любом месте, но доступ к элементам по индексу медленный, так как требуется последовательный обход.

ℹ️Выбор между ними зависит от конкретных требований к производительности и операциям.

Ставь 👍, если было полезно!
Больше ответов на сайте 👈

✈️ С++ собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥41
ℹ️Подписывайся на наши новые каналы!

🖥 JS собеседования
🖥 Backend собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
Namespaces используются для организации кода и предотвращения конфликтов имен. Они позволяют группировать связанные классы, функции и переменные, что особенно полезно в больших проектах или при использовании сторонних библиотек.

namespace MyNamespace {
int myVariable;
void myFunction() {
// код
}
}


🔵Для доступа к элементам namespace используется оператор ::

MyNamespace::myFunction();


🔵Можно использовать директиву using, чтобы упростить доступ

using namespace MyNamespace;
myFunction();

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

Ставь 👍, если было полезно!
Больше ответов на сайте 👈

✈️ С++ собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍101
🔥Приоритет операторов в C++ определяет порядок, в котором выполняются операции в выражении. Операторы с более высоким приоритетом выполняются раньше, чем операторы с более низким приоритетом. Например, в выражении 3 + 4 * 5 сначала выполняется умножение, а затем сложение, так как оператор * имеет более высокий приоритет, чем +.

Ставь 👍, если было полезно!
Больше ответов на сайте 👈

✈️ С++ собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥1😎1
Множественное наследование - это механизм, позволяющий классу наследовать свойства и методы от нескольких базовых классов одновременно.

При множественном наследовании производный класс получает все члены всех своих базовых классов. Это дает возможность комбинировать функциональность разных классов в одном.

Пример синтаксиса:

class Derived : public Base1, public Base2 {
// тело класса
};


Основные проблемы множественного наследования:
〰️ Ромбовидное наследование (diamond problem)
〰️ Неоднозначность при одинаковых именах членов базовых классов
〰️ Увеличение сложности кода

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

Ставь 👍, если было полезно!
Больше ответов на сайте 👈

✈️ С++ собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥1
✏️ std::cout и std::cin — это стандартные потоки ввода и вывода. Они определены в библиотеке <iostream>.

1️⃣ std::cout используется для вывода данных на стандартный поток вывода, обычно это консоль. Пример использования: std::cout << "Hello, World!";.

2️⃣ std::cin предназначен для ввода данных с клавиатуры. Он считывает данные из стандартного потока ввода. Пример: int x; std::cin >> x;.

Оба потока являются частью пространства имен std, поэтому перед их использованием необходимо либо указать using namespace std;, либо явно использовать префикс std::.

Ставь 👍, если было полезно!
Больше ответов на сайте 👈

✈️ С++ собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥5