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
🔥 Что такое указатели и как они используются?

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

Указатели объявляются с использованием символа *. Например, int* ptr объявляет указатель на целое число. Для получения адреса переменной используется оператор &, а для доступа к значению по адресу — оператор разыменования *.

Указатели широко используются для передачи больших объектов в функции без копирования, для работы с массивами и динамическим выделением памяти.

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


#include <iostream>

void increment(int* ptr) {
(*ptr)++;
}

int main() {
int value = 10;
int* ptr = &value;

increment(ptr);
std::cout << value << std::endl; // Output: 11

return 0;
}


В этом примере указатель ptr передается в функцию increment, которая увеличивает значение переменной value по адресу, на который указывает ptr.

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

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

1. Парадигмы программирования:
- C++: Является языком общего назначения, поддерживающим процедурное, объектно-ориентированное и обобщённое программирование. Он предоставляет низкоуровневый контроль над памятью и ресурсами.
- C#: Основной язык для платформы .NET, ориентированный на объектно-ориентированное программирование. Он также поддерживает функциональные элементы и более высокий уровень абстракции.

2. Управление памятью:
- C++: Предоставляет прямой доступ к управлению памятью через указатели и динамическое выделение памяти. Программист несет ответственность за управление памятью, что может привести к утечкам.
- C#: Использует сборщик мусора для автоматического управления памятью, что упрощает разработку и снижает вероятность утечек памяти.

3. Компиляция и выполнение:
- C++: Компилируется в машинный код, что делает его более производительным и подходящим для системного программирования и приложений с высокими требованиями к производительности.
- C#: Компилируется в промежуточный язык (IL), который выполняется на виртуальной машине CLR (Common Language Runtime). Это обеспечивает переносимость между различными платформами, поддерживающими .NET.

4. Стандартные библиотеки:
- C++: Использует стандартную библиотеку C++ (STL), которая предоставляет контейнеры, алгоритмы и итераторы.
- C#: Имеет богатую библиотеку классов .NET, которая включает в себя широкий набор функций для работы с GUI, сетями, базами данных и веб-сервисами.

5. Области применения:
- C++: Часто используется в разработке операционных систем, драйверов, игр и приложений, требующих высокой производительности.
- C#: Популярен в разработке бизнес-приложений, веб-сервисов, десктопных приложений и приложений для Windows.

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

std::unique_ptr и std::shared_ptr — это умные указатели в C++, которые управляют динамически выделенной памятью, но имеют разные модели владения.

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

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

#include <memory>
#include <iostream>

int main() {
std::unique_ptr<int> uptr = std::make_unique<int>(42);
std::cout << *uptr << std::endl;

return 0;
}


std::shared_ptr:
- Обеспечивает совместное владение ресурсом. Несколько std::shared_ptr могут владеть одним объектом.
- Использует счетчик ссылок для отслеживания количества владельцев. Объект удаляется, когда счетчик достигает нуля.
- Подходит для сценариев, где объект должен иметь несколько владельцев.

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

#include <memory>
#include <iostream>

int main() {
std::shared_ptr<int> sptr1 = std::make_shared<int>(42);
std::shared_ptr<int> sptr2 = sptr1;
std::cout << *sptr1 << " " << *sptr2 << std::endl;

return 0;
}


Выбор между std::unique_ptr и std::shared_ptr зависит от требований к владению и производительности.

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

CMake — это кроссплатформенный инструмент автоматизации сборки, который управляет процессом компиляции программного обеспечения. Он генерирует файлы сборки для различных систем, таких как Makefiles для Unix или проектные файлы для Visual Studio.

Преимущества CMake перед Make:

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

2. Генерация файлов сборки: CMake генерирует файлы сборки для различных систем, что упрощает интеграцию с различными IDE и инструментами.

3. Модульность и повторное использование: CMake поддерживает модульную структуру, позволяя легко управлять большими проектами и повторно использовать код.

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

5. Современные возможности: CMake поддерживает современные практики разработки, такие как автоматическое обнаружение зависимостей и интеграция с системами контроля версий.

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

Core dump — это файл, содержащий снимок памяти процесса в момент его аварийного завершения. Он создается операционной системой, когда программа сталкивается с критической ошибкой, например, сегментационной ошибкой (segmentation fault). Core dump помогает разработчикам понять, что пошло не так, и исправить ошибку.

Для анализа core dump в C++ обычно используют отладчики, такие как GDB. Чтобы начать анализ, необходимо запустить GDB с исполняемым файлом и core dump:


gdb ./your_program core


После запуска GDB можно использовать команды для исследования состояния программы. Команда bt (backtrace) покажет стек вызовов в момент сбоя, что поможет определить, где произошла ошибка. Команда info locals отобразит локальные переменные в текущем фрейме стека.

Важно убедиться, что программа скомпилирована с отладочной информацией (флаг -g в GCC), чтобы анализ был более информативным.

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

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

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

Пример перегрузки функций:


int add(int a, int b) {
return a + b;
}

double add(double a, double b) {
return a + b;
}


В этом примере функция add перегружена для работы как с int, так и с double. Перегрузка не может быть основана только на возвращаемом типе функции.

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

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

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

Пример:


class MyClass {
public:
static int count;
MyClass() { ++count; }
};

int MyClass::count = 0;


В этом примере count — статическая переменная, которая увеличивается при создании каждого объекта MyClass.

Статические функции также объявляются с static и могут вызываться без создания объекта. Они имеют доступ только к статическим членам класса.

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

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

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

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


#include <vector>

std::vector<int> numbers;
numbers.push_back(1);
numbers.push_back(2);
numbers.push_back(3);


Методы push_back, pop_back, size, capacity и operator[] делают std::vector удобным для работы. Он обеспечивает безопасное управление памятью и поддерживает итераторы для удобного доступа к элементам.

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

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

Указатель на указатель объявляется с использованием двойного знака *. Например, int** ptr — это указатель на указатель на int.

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


int value = 10;
int* ptr = &value;
int** ptrToPtr = &ptr;

std::cout << **ptrToPtr << std::endl; // Выведет 10


В этом примере ptr хранит адрес переменной value, а ptrToPtr хранит адрес ptr. Доступ к значению осуществляется через двойное разыменование **ptrToPtr. Указатели на указатели часто используются в функциях, которые изменяют переданные указатели.

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

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

Для реализации паттерна требуется базовый класс с виртуальной функцией clone, которая возвращает указатель на новый объект.

Пример:


class Prototype {
public:
virtual Prototype* clone() const = 0;
virtual ~Prototype() {}
};

class ConcretePrototype : public Prototype {
public:
ConcretePrototype* clone() const override {
return new ConcretePrototype(*this);
}
};


В этом примере ConcretePrototype реализует метод clone, который создает копию объекта. Использование паттерна Prototype позволяет создавать объекты динамически, сохраняя их состояние.

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

std::terminate и std::uncaught_exception — это механизмы для работы с исключениями и завершением программы.

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

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


#include <iostream>
#include <exception>

void customTerminate() {
std::cerr << "Unhandled exception, terminating program." << std::endl;
std::abort();
}

int main() {
std::set_terminate(customTerminate);
throw std::runtime_error("Error");
return 0;
}


std::uncaught_exception (в C++17 и ранее) возвращает true, если в данный момент выброшено, но не поймано исключение. В C++20 его заменили на std::uncaught_exceptions, который возвращает количество активных исключений.

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


#include <iostream>
#include <exception>

class Example {
public:
~Example() {
if (std::uncaught_exception()) {
std::cerr << "Destructor called during stack unwinding." << std::endl;
}
}
};

int main() {
try {
Example ex;
throw std::runtime_error("Error");
} catch (...) {
std::cerr << "Exception caught." << std::endl;
}
return 0;
}


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

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

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

Объявление массива включает указание типа элементов и размера. Например, массив из 5 целых чисел:


int arr[5] = {1, 2, 3, 4, 5};


Доступ к элементам осуществляется с помощью индексов:


int firstElement = arr[0]; // 1
arr[2] = 10; // Изменение третьего элемента


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

Ставь 👍, если было полезно!
Еще больше ответов для подготовки к собеседованиям на сайте 👈
Please open Telegram to view this post
VIEW IN TELEGRAM
👍181🔥1
🔥 Что такое 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