Что будет на экране после выполнения программы #include <iostream.h> short x = 4, i = 0; void fun1() { if (i == 5) throw 2; } void fun2() { --x; fun1(); x++; } int main() { try { fun2(); } catch (int) { cout << "Exception "; } cout << x << " " << i; }
Anonymous Quiz
13%
Exception
38%
Exception 4 0
9%
Exception 3 0
40%
4 0
Каков результат следующего кода?
#include <iostream>
using namespace std; int main() { int arr[] = {10, 20, 30}; cout << sizeof(arr) / sizeof(arr[0]) << endl; return 0; }
#include <iostream>
using namespace std; int main() { int arr[] = {10, 20, 30}; cout << sizeof(arr) / sizeof(arr[0]) << endl; return 0; }
Anonymous Quiz
78%
3
10%
10
6%
20
6%
30
❓ Вопрос на собеседовании
Что такое Placement new в C++ и как оно используется?
Ответ ⬇️
Placement new — это особая форма оператора new, которая позволяет размещать объект в заранее выделенной области памяти. Вместо того чтобы выделять память в куче, как делает обычный new, placement new создает объект по адресу, который передается в качестве аргумента.
Это используется для более точного контроля над памятью, например, в реализациях кастомных аллокаторов, пулах памяти или для повышения производительности в системах с ограниченными ресурсами.
Пример использования ⚙️
```cpp
#include <iostream>
#include <new> // Для placement new
int main() {
alignas(alignof(int)) char buffer[sizeof(int)]; // Буфер для хранения объекта
int* ptr = new (buffer) int(42); // Размещение объекта в buffer
std::cout
```
@quizcpp
Что такое Placement new в C++ и как оно используется?
Ответ ⬇️
Placement new — это особая форма оператора new, которая позволяет размещать объект в заранее выделенной области памяти. Вместо того чтобы выделять память в куче, как делает обычный new, placement new создает объект по адресу, который передается в качестве аргумента.
Это используется для более точного контроля над памятью, например, в реализациях кастомных аллокаторов, пулах памяти или для повышения производительности в системах с ограниченными ресурсами.
Пример использования ⚙️
```cpp
#include <iostream>
#include <new> // Для placement new
int main() {
alignas(alignof(int)) char buffer[sizeof(int)]; // Буфер для хранения объекта
int* ptr = new (buffer) int(42); // Размещение объекта в buffer
std::cout
```
@quizcpp
❓ Вопрос на собеседовании
Как функционируют исключения без затрат в C++ и почему они считаются эффективными?
Ответ ⬇️
Исключения без затрат означают, что в процессе обычного выполнения программы исключения не оказывают влияния на производительность. Вместо проверок компилятор создает специальные таблицы (.eh_frame в ELF), которые используются только в случае выброса исключения. В отличие от проверок ошибок с помощью if, исключения в C++ не замедляют выполнение кода, пока не произойдет ошибка.
Пример использования ⚙️
#include
#include
void risky() { throw std::runtime_error("Ошибка!"); }
int main() {
try { risky(); }
catch (const std::exception& e) { std::cout
@quizcpp
Как функционируют исключения без затрат в C++ и почему они считаются эффективными?
Ответ ⬇️
Исключения без затрат означают, что в процессе обычного выполнения программы исключения не оказывают влияния на производительность. Вместо проверок компилятор создает специальные таблицы (.eh_frame в ELF), которые используются только в случае выброса исключения. В отличие от проверок ошибок с помощью if, исключения в C++ не замедляют выполнение кода, пока не произойдет ошибка.
Пример использования ⚙️
#include
#include
void risky() { throw std::runtime_error("Ошибка!"); }
int main() {
try { risky(); }
catch (const std::exception& e) { std::cout
@quizcpp
🔥1
❓ Вопрос на собеседовании
Что представляют собой корутины в C++ и как они функционируют?
Ответ ⬇️
Корутины в C++ — это механизм асинхронного выполнения кода, который даёт возможность приостанавливать и возобновлять выполнение функции без блокировки потока. В отличие от потоков, корутины являются лёгкими и не требуют создания новых системных потоков.
Корутины в C++ используют ключевые слова co_await, co_yield и co_return, а также требуют специального механизма возврата (std::generator, std::future, std::promise).
Пример использования ⚙️
#include
#include
struct Task {
struct promise_type {
Task get_return_object() { return {}; }
std::suspend_never initial_suspend() { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() {}
};
};
Task myCoroutine() {
std::cout
@quizcpp
Что представляют собой корутины в C++ и как они функционируют?
Ответ ⬇️
Корутины в C++ — это механизм асинхронного выполнения кода, который даёт возможность приостанавливать и возобновлять выполнение функции без блокировки потока. В отличие от потоков, корутины являются лёгкими и не требуют создания новых системных потоков.
Корутины в C++ используют ключевые слова co_await, co_yield и co_return, а также требуют специального механизма возврата (std::generator, std::future, std::promise).
Пример использования ⚙️
#include
#include
struct Task {
struct promise_type {
Task get_return_object() { return {}; }
std::suspend_never initial_suspend() { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() {}
};
};
Task myCoroutine() {
std::cout
@quizcpp
❓ Вопрос на собеседовании
Как функционирует expression SFINAE в C++, и чем оно отличается от обычного SFINAE?
Ответ ⬇️
SFINAE (Substitution Failure Is Not An Error) позволяет компилятору игнорировать неподходящие шаблонные перегрузки, не выдавая ошибок. Expression SFINAE — это метод, при котором проверяется не только наличие типа, но и возможность использования выражения с этим типом.
Обычный SFINAE работает с typename, тогда как expression SFINAE применяется в decltype() для проверки существования определенных операций или методов в типе.
Пример использования ⚙️
#include
#include
// Проверяем, есть ли у типа метод size()
template
auto has_size(int) -> decltype(std::declval().size(), std::true_type{}) {
return {};
}
template
std::false_type has_size(...) { return {}; }
int main() {
std::cout
@quizcpp
Как функционирует expression SFINAE в C++, и чем оно отличается от обычного SFINAE?
Ответ ⬇️
SFINAE (Substitution Failure Is Not An Error) позволяет компилятору игнорировать неподходящие шаблонные перегрузки, не выдавая ошибок. Expression SFINAE — это метод, при котором проверяется не только наличие типа, но и возможность использования выражения с этим типом.
Обычный SFINAE работает с typename, тогда как expression SFINAE применяется в decltype() для проверки существования определенных операций или методов в типе.
Пример использования ⚙️
#include
#include
// Проверяем, есть ли у типа метод size()
template
auto has_size(int) -> decltype(std::declval().size(), std::true_type{}) {
return {};
}
template
std::false_type has_size(...) { return {}; }
int main() {
std::cout
@quizcpp
➡️ Утверждение Валидности
Утверждения помогают проверять корректность выражений с помощью макроса assert из заголовочного файла . Это полезно для отладки, чтобы проверить правильность значения переменной.
Если выражение равно 0 (ложь), выводится сообщение об ошибке, и программа завершается.
🗣️ Например, переменная maxsize никогда не должна превышать 1024. Можно использовать утверждение для проверки значения и вывода сообщения об ошибке, если значение некорректно.
#include
int main() {
assert(maxsize
@quizcpp
Утверждения помогают проверять корректность выражений с помощью макроса assert из заголовочного файла . Это полезно для отладки, чтобы проверить правильность значения переменной.
Если выражение равно 0 (ложь), выводится сообщение об ошибке, и программа завершается.
🗣️ Например, переменная maxsize никогда не должна превышать 1024. Можно использовать утверждение для проверки значения и вывода сообщения об ошибке, если значение некорректно.
#include
int main() {
assert(maxsize
@quizcpp
❓ Вопрос на собеседовании
Что такое "RAII" (Resource Acquisition Is Initialization) и как это помогает в управлении ресурсами в C++?
Ответ ⬇️
"RAII" — это идиома, при которой инициализация объекта захватывает ресурс, а освобождение ресурса происходит автоматически при уничтожении объекта. Это гарантирует корректное освобождение ресурсов, таких как память или файловые дескрипторы, даже при исключениях.
🗣 Пример:
#include
class File {
public:
File(const char* filename) {
file_ = fopen(filename, "w");
if (file_) {
std::cout
@quizcpp
Что такое "RAII" (Resource Acquisition Is Initialization) и как это помогает в управлении ресурсами в C++?
Ответ ⬇️
"RAII" — это идиома, при которой инициализация объекта захватывает ресурс, а освобождение ресурса происходит автоматически при уничтожении объекта. Это гарантирует корректное освобождение ресурсов, таких как память или файловые дескрипторы, даже при исключениях.
🗣 Пример:
#include
class File {
public:
File(const char* filename) {
file_ = fopen(filename, "w");
if (file_) {
std::cout
@quizcpp
❓ Вопрос на собеседовании
Как работает RVO (Return Value Optimization) в C++, и в каких случаях оно не применяется?
Ответ ⬇️
RVO — это оптимизация, при которой компилятор устраняет временные объекты, возвращаемые из функции, что значительно снижает накладные расходы на создание копий. Однако, есть ситуации, когда RVO не применяется, например, при возврате различных объектов в зависимости от условий внутри функции.
🗣 Пример:
#include
struct MyObject {
MyObject() { std::cout
@quizcpp
Как работает RVO (Return Value Optimization) в C++, и в каких случаях оно не применяется?
Ответ ⬇️
RVO — это оптимизация, при которой компилятор устраняет временные объекты, возвращаемые из функции, что значительно снижает накладные расходы на создание копий. Однако, есть ситуации, когда RVO не применяется, например, при возврате различных объектов в зависимости от условий внутри функции.
🗣 Пример:
#include
struct MyObject {
MyObject() { std::cout
@quizcpp
❓ Вопрос на собеседовании
Что такое перемещение (move semantics) в C++11, как оно работает, и зачем нужен конструктор перемещения?
Ответ ⬇️
Перемещение — это оптимизация, которая позволяет передавать ресурсы (например, память или файлы) из одного объекта в другой без копирования, с помощью конструктора перемещения или оператора перемещения. Это достигается использованием std::move, который превращает объект в rvalue-ссылку, указывающую на временный объект. Конструктор перемещения предотвращает дорогостоящие копирования, делая код более производительным.
Пример использования ⚙️
#include
#include
#include // Для std::move
class MyVector {
private:
int* data;
size_t size;
public:
// Конструктор
MyVector(size_t n) : size(n), data(new int[n]) {
std::cout
@quizcpp
Что такое перемещение (move semantics) в C++11, как оно работает, и зачем нужен конструктор перемещения?
Ответ ⬇️
Перемещение — это оптимизация, которая позволяет передавать ресурсы (например, память или файлы) из одного объекта в другой без копирования, с помощью конструктора перемещения или оператора перемещения. Это достигается использованием std::move, который превращает объект в rvalue-ссылку, указывающую на временный объект. Конструктор перемещения предотвращает дорогостоящие копирования, делая код более производительным.
Пример использования ⚙️
#include
#include
#include // Для std::move
class MyVector {
private:
int* data;
size_t size;
public:
// Конструктор
MyVector(size_t n) : size(n), data(new int[n]) {
std::cout
@quizcpp
❓ Вопрос на собеседовании
Что такое perfect forwarding в C++, как оно работает и зачем оно нужно?
Ответ ⬇️
Perfect forwarding — это техника передачи аргументов в функции или конструкторы так, чтобы сохранить их исходные квалификаторы (например, lvalue, rvalue). Она достигается с помощью универсальных ссылок (T&&) и функции std::forward. Perfect forwarding используется для передачи аргументов в шаблонных функциях без лишних копирований.
Пример использования ⚙️
#include
#include
void process(int& x) {
std::cout
@quizcpp
Что такое perfect forwarding в C++, как оно работает и зачем оно нужно?
Ответ ⬇️
Perfect forwarding — это техника передачи аргументов в функции или конструкторы так, чтобы сохранить их исходные квалификаторы (например, lvalue, rvalue). Она достигается с помощью универсальных ссылок (T&&) и функции std::forward. Perfect forwarding используется для передачи аргументов в шаблонных функциях без лишних копирований.
Пример использования ⚙️
#include
#include
void process(int& x) {
std::cout
@quizcpp
❓ Вопрос на собеседовании
Что такое шаблонный метод std::enable_if в C++, как он работает, и в каких случаях его полезно использовать?
Ответ ⬇️
std::enable_if — это шаблонный механизм SFINAE (Substitution Failure Is Not An Error), позволяющий включать или отключать функции или классы на этапе компиляции в зависимости от выполнения условий. Это полезно для создания перегрузок шаблонов или ограничения их использования для определённых типов.
Пример использования ⚙️
#include
#include
// Шаблон для целых чисел
template
typename std::enable_if::type
printType(T value) {
std::cout
@quizcpp
Что такое шаблонный метод std::enable_if в C++, как он работает, и в каких случаях его полезно использовать?
Ответ ⬇️
std::enable_if — это шаблонный механизм SFINAE (Substitution Failure Is Not An Error), позволяющий включать или отключать функции или классы на этапе компиляции в зависимости от выполнения условий. Это полезно для создания перегрузок шаблонов или ограничения их использования для определённых типов.
Пример использования ⚙️
#include
#include
// Шаблон для целых чисел
template
typename std::enable_if::type
printType(T value) {
std::cout
@quizcpp
❓ Вопрос на собеседовании
Что такое emplace в C++ и чем оно отличается от push_back при работе с контейнерами STL?
Ответ ⬇️
Метод emplace добавляет новый элемент в контейнер, создавая его непосредственно на месте, вместо создания временного объекта и его копирования (как в случае с push_back). Это повышает производительность, особенно при добавлении сложных объектов. Метод emplace вызывает конструктор объекта с переданными аргументами прямо в памяти контейнера.
Пример использования ⚙️
#include
#include
#include
class MyClass {
public:
MyClass(const std::string& name, int value) : name(name), value(value) {
std::cout
@quizcpp
Что такое emplace в C++ и чем оно отличается от push_back при работе с контейнерами STL?
Ответ ⬇️
Метод emplace добавляет новый элемент в контейнер, создавая его непосредственно на месте, вместо создания временного объекта и его копирования (как в случае с push_back). Это повышает производительность, особенно при добавлении сложных объектов. Метод emplace вызывает конструктор объекта с переданными аргументами прямо в памяти контейнера.
Пример использования ⚙️
#include
#include
#include
class MyClass {
public:
MyClass(const std::string& name, int value) : name(name), value(value) {
std::cout
@quizcpp
👩💻 Задача по C++: Подсчёт слов в строке
Напишите функцию, которая принимает строку и возвращает количество слов в ней. Слова разделены пробелами, и строки могут содержать несколько подряд идущих пробелов.
Пример:
#include
#include
int main() {
std::string text1 = "Hello world!";
std::string text2 = " Multiple spaces between words ";
std::cout
@quizcpp
Напишите функцию, которая принимает строку и возвращает количество слов в ней. Слова разделены пробелами, и строки могут содержать несколько подряд идущих пробелов.
Пример:
#include
#include
int main() {
std::string text1 = "Hello world!";
std::string text2 = " Multiple spaces between words ";
std::cout
@quizcpp
❓ Вопрос на собеседовании
Что такое умные указатели в C++ (std::unique_ptr, std::shared_ptr, std::weak_ptr), и чем они отличаются друг от друга?
Ответ ⬇️
Умные указатели в C++ автоматизируют управление памятью и помогают избежать утечек памяти. Они находятся в заголовке .
std::unique_ptr владеет ресурсом единолично. При уничтожении указателя ресурс освобождается.
std::shared_ptr позволяет нескольким указателям совместно владеть ресурсом. Ресурс освобождается, когда последний shared_ptr уничтожается.
std::weak_ptr предоставляет доступ к ресурсу, но не увеличивает счётчик ссылок. Используется для предотвращения циклических зависимостей.
Пример использования ⚙️
#include
#include
int main() {
// unique_ptr: единоличное владение
std::unique_ptr uptr = std::make_unique(10);
std::cout
@quizcpp
Что такое умные указатели в C++ (std::unique_ptr, std::shared_ptr, std::weak_ptr), и чем они отличаются друг от друга?
Ответ ⬇️
Умные указатели в C++ автоматизируют управление памятью и помогают избежать утечек памяти. Они находятся в заголовке .
std::unique_ptr владеет ресурсом единолично. При уничтожении указателя ресурс освобождается.
std::shared_ptr позволяет нескольким указателям совместно владеть ресурсом. Ресурс освобождается, когда последний shared_ptr уничтожается.
std::weak_ptr предоставляет доступ к ресурсу, но не увеличивает счётчик ссылок. Используется для предотвращения циклических зависимостей.
Пример использования ⚙️
#include
#include
int main() {
// unique_ptr: единоличное владение
std::unique_ptr uptr = std::make_unique(10);
std::cout
@quizcpp
❌ Антипаттерн недели: Утечка памяти из-за забытых delete
Забыть освободить выделенную память с помощью delete может привести к утечке памяти (memory leak).
Каждый вызов new должен сопровождаться вызовом delete или delete[]. В противном случае выделенная память остаётся занята до завершения программы.
✔️ Как исправить:
Используйте умные указатели (std::unique_ptr или std::shared_ptr), чтобы автоматически управлять памятью. Если используете new, не забудьте вызвать delete.
#include
#include
void createArray() {
auto arr = std::make_unique(5);
arr[0] = 42;
std::cout
@quizcpp
Забыть освободить выделенную память с помощью delete может привести к утечке памяти (memory leak).
Каждый вызов new должен сопровождаться вызовом delete или delete[]. В противном случае выделенная память остаётся занята до завершения программы.
✔️ Как исправить:
Используйте умные указатели (std::unique_ptr или std::shared_ptr), чтобы автоматически управлять памятью. Если используете new, не забудьте вызвать delete.
#include
#include
void createArray() {
auto arr = std::make_unique(5);
arr[0] = 42;
std::cout
@quizcpp
❓ Вопрос на собеседовании
Что такое pimpl idiom в C++ и когда его использовать?
Ответ ⬇️
Pimpl idiom (Pointer to Implementation) — это паттерн, который скрывает реализацию класса за указателем на скрытый тип в заголовочном файле. Это улучшает инкапсуляцию, минимизирует зависимости и ускоряет компиляцию.
Пример использования ⚙️
// MyClass.h
#include
class MyClassImpl; // Forward declaration
class MyClass {
public:
MyClass();
void someFunction();
private:
std::unique_ptr pImpl; // Указатель на скрытую реализацию
};
// MyClass.cpp
#include "MyClass.h"
#include
class MyClassImpl {
public:
void someFunctionImpl() { std::cout someFunctionImpl(); }
// main.cpp
#include "MyClass.h"
int main() {
MyClass obj;
obj.someFunction();
return 0;
}
В этом примере pimpl idiom скрывает реализацию MyClassImpl, что позволяет изменять реализацию без изменения публичного интерфейса, улучшая инкапсуляцию и ускоряя компиляцию.
👩💻
@quizcpp
Что такое pimpl idiom в C++ и когда его использовать?
Ответ ⬇️
Pimpl idiom (Pointer to Implementation) — это паттерн, который скрывает реализацию класса за указателем на скрытый тип в заголовочном файле. Это улучшает инкапсуляцию, минимизирует зависимости и ускоряет компиляцию.
Пример использования ⚙️
// MyClass.h
#include
class MyClassImpl; // Forward declaration
class MyClass {
public:
MyClass();
void someFunction();
private:
std::unique_ptr pImpl; // Указатель на скрытую реализацию
};
// MyClass.cpp
#include "MyClass.h"
#include
class MyClassImpl {
public:
void someFunctionImpl() { std::cout someFunctionImpl(); }
// main.cpp
#include "MyClass.h"
int main() {
MyClass obj;
obj.someFunction();
return 0;
}
В этом примере pimpl idiom скрывает реализацию MyClassImpl, что позволяет изменять реализацию без изменения публичного интерфейса, улучшая инкапсуляцию и ускоряя компиляцию.
👩💻
@quizcpp
❓ Вопрос на собеседовании
Как работает std::atomic в C++, и в чём его преимущество перед обычными переменными в многопоточном программировании?
Ответ ⬇️
std::atomic — это шаблонный класс из библиотеки , который предоставляет атомарные операции с переменными, гарантируя их безопасность в многопоточной среде. Используя атомарные операции, вы избегаете гонок данных без необходимости явно использовать мьютексы.
Пример использования ⚙️
#include
#include
#include
std::atomic counter(0);
void increment() {
for (int i = 0; i < 1000; ++i) {
counter.fetch_add(1);
}
}
int main() {
std::thread t1(increment);
std::thread t2(increment);
t1.join();
t2.join();
std::cout
@quizcpp
Как работает std::atomic в C++, и в чём его преимущество перед обычными переменными в многопоточном программировании?
Ответ ⬇️
std::atomic — это шаблонный класс из библиотеки , который предоставляет атомарные операции с переменными, гарантируя их безопасность в многопоточной среде. Используя атомарные операции, вы избегаете гонок данных без необходимости явно использовать мьютексы.
Пример использования ⚙️
#include
#include
#include
std::atomic counter(0);
void increment() {
for (int i = 0; i < 1000; ++i) {
counter.fetch_add(1);
}
}
int main() {
std::thread t1(increment);
std::thread t2(increment);
t1.join();
t2.join();
std::cout
@quizcpp
❓ Вопрос на собеседовании
Как работает std::atomic в C++, и в чём его преимущество перед обычными переменными в многопоточном программировании?
Ответ ⬇️
std::atomic — это шаблонный класс из библиотеки , который предоставляет атомарные операции с переменными, гарантируя их безопасность в многопоточной среде. Используя атомарные операции, вы избегаете гонок данных без необходимости явно использовать мьютексы.
Пример использования ⚙️
#include
#include
#include
std::atomic counter(0);
void increment() {
for (int i = 0; i < 1000; ++i) {
counter.fetch_add(1);
}
}
int main() {
std::thread t1(increment);
std::thread t2(increment);
t1.join();
t2.join();
std::cout
@quizcpp
Как работает std::atomic в C++, и в чём его преимущество перед обычными переменными в многопоточном программировании?
Ответ ⬇️
std::atomic — это шаблонный класс из библиотеки , который предоставляет атомарные операции с переменными, гарантируя их безопасность в многопоточной среде. Используя атомарные операции, вы избегаете гонок данных без необходимости явно использовать мьютексы.
Пример использования ⚙️
#include
#include
#include
std::atomic counter(0);
void increment() {
for (int i = 0; i < 1000; ++i) {
counter.fetch_add(1);
}
}
int main() {
std::thread t1(increment);
std::thread t2(increment);
t1.join();
t2.join();
std::cout
@quizcpp
❓ Вопрос на собеседовании
Что такое std::allocator в C++, и как его можно использовать для управления памятью?
Ответ ⬇️
std::allocator — это стандартный шаблонный класс, предоставляющий низкоуровневые инструменты для управления памятью в STL-контейнерах. Он позволяет настраивать аллокацию памяти, предоставляя методы для выделения, освобождения и построения объектов.
Пример использования ⚙️
#include
#include
int main() {
std::allocator allocator;
// Выделяем память для 3 целых чисел
int* arr = allocator.allocate(3);
// Конструируем элементы
allocator.construct(arr, 10);
allocator.construct(arr + 1, 20);
allocator.construct(arr + 2, 30);
// Выводим значения
for (int i = 0; i < 3; ++i) {
std::cout
@quizcpp
Что такое std::allocator в C++, и как его можно использовать для управления памятью?
Ответ ⬇️
std::allocator — это стандартный шаблонный класс, предоставляющий низкоуровневые инструменты для управления памятью в STL-контейнерах. Он позволяет настраивать аллокацию памяти, предоставляя методы для выделения, освобождения и построения объектов.
Пример использования ⚙️
#include
#include
int main() {
std::allocator allocator;
// Выделяем память для 3 целых чисел
int* arr = allocator.allocate(3);
// Конструируем элементы
allocator.construct(arr, 10);
allocator.construct(arr + 1, 20);
allocator.construct(arr + 2, 30);
// Выводим значения
for (int i = 0; i < 3; ++i) {
std::cout
@quizcpp