fa
Feedback
C/C++ | Вопросы собесов

C/C++ | Вопросы собесов

رفتن به کانال در Telegram

Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @easyoffer_adv

نمایش بیشتر
4 192
مشترکین
+224 ساعت
+17 روز
+1630 روز
آرشیو پست ها
🤔 Какие есть виды полиморфизма? В программировании, включая C++, полиморфизм (многоформенность) – это способность объекта или функции принимать разные формы. Полиморфизм является ключевой концепцией объектно-ориентированного программирования (ООП). 🚩Компиляторный (статический) полиморфизм Этот вид полиморфизма реализуется во время компиляции. Он достигается с помощью перегрузки функций (function overloading) и перегрузки операторов (operator overloading). 🟠Перегрузка функций В перегрузке функций одна функция имеет несколько определений с разными параметрами.
#include <iostream>

void print(int value) {
    std::cout << "Целое число: " << value << std::endl;
}

void print(double value) {
    std::cout << "Вещественное число: " << value << std::endl;
}

void print(const std::string& value) {
    std::cout << "Строка: " << value << std::endl;
}

int main() {
    print(42);           // Вызов функции для int
    print(3.14);         // Вызов функции для double
    print("Привет!");    // Вызов функции для строки
    return 0;
}
🟠Перегрузка операторов Перегрузка операторов позволяет определить, как стандартные операторы работают с пользовательскими типами данных.
#include <iostream>

class Complex {
    double real, imag;
public:
    Complex(double r, double i) : real(r), imag(i) {}

    Complex operator+(const Complex& other) const {
        return Complex(real + other.real, imag + other.imag);
    }

    void display() const {
        std::cout << real << " + " << imag << "i" << std::endl;
    }
};

int main() {
    Complex c1(1.0, 2.0), c2(3.0, 4.0);
    Complex c3 = c1 + c2; // Используется перегрузка оператора +
    c3.display();         // Вывод: 4 + 6i
    return 0;
}
🚩Рантаймный (динамический) полиморфизм Этот вид полиморфизма проявляется во время выполнения программы. Реализуется с использованием виртуальных функций и наследования. Виртуальные функции
#include <iostream>

class Animal {
public:
    virtual void sound() const { // Виртуальная функция
        std::cout << "Некоторый звук" << std::endl;
    }
};

class Dog : public Animal {
public:
    void sound() const override { // Переопределение
        std::cout << "Гав-гав" << std::endl;
    }
};

class Cat : public Animal {
public:
    void sound() const override { // Переопределение
        std::cout << "Мяу" << std::endl;
    }
};

void makeSound(const Animal& animal) {
    animal.sound(); // Динамическое определение, какой sound() вызывать
}

int main() {
    Dog dog;
    Cat cat;

    makeSound(dog); // Вывод: Гав-гав
    makeSound(cat); // Вывод: Мяу
    return 0;
}
Ставь 👍 и забирай 📚 Базу знаний

Долгожданный Solaris KRS в кредит на выгодных условиях Автозапуск и заводская телематика. Цифровой автомобиль. Оставьте заявк
Долгожданный Solaris KRS в кредит на выгодных условиях Автозапуск и заводская телематика. Цифровой автомобиль. Оставьте заявку! Узнать больше Изучите все условия кредита (займа) на сайте в соответствующем разделе. Оценивайте свои финансовые возможности и риски. Финансовые услуги оказывает: ПАО "Совкомбанк", СПАО "Ингосстрах" и другие. #реклама mrqz.me О рекламодателе

🤔 Что пришло на смену auto_ptr? На смену auto_ptr пришли умные указатели unique_ptr и shared_ptr. unique_ptr безопаснее управляет памятью и исключает случайное копирование, что было проблемой в auto_ptr. Эти новые указатели входят в стандарт C++11 и являются более надежными. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний

🤔 Каким свойством должен обладать объект, чтобы его можно было добавить в ассоциативные контейнеры в качестве ключа? Чтобы объект можно было использовать в качестве ключа в ассоциативных контейнерах (std::set, std::map, std::unordered_set, std::unordered_map), он должен обладать определёнными свойствами, которые зависят от типа контейнера. 🚩Требования к объекту-ключу 🟠Для `std::map` и `std::set` (красно-чёрное дерево) Класс или структура, используемая в качестве ключа, должна поддерживать операцию < (меньше).
#include <iostream>
#include <map>

struct Person {
    std::string name;
    int age;

    // Оператор сравнения, необходимый для std::map и std::set
    bool operator<(const Person& other) const {
        return age < other.age; // Ключи будут упорядочены по возрасту
    }
};

int main() {
    std::map<Person, std::string> people;
    people[{ "Alice", 30 }] = "Doctor";
    people[{ "Bob", 25 }] = "Engineer";

    for (const auto& [key, value] : people) {
        std::cout << key.name << " (" << key.age << "): " << value << '\n';
    }
}
🟠Для `std::unordered_map` и `std::unordered_set` (хеш-таблица) Объект-ключ должен поддерживать операции: Оператор == (для проверки равенства) Функция-хешер (по умолчанию std::hash<T>)
#include <iostream>
#include <unordered_map>

struct Person {
    std::string name;
    int age;

    // Оператор равенства нужен для сравнения ключей
    bool operator==(const Person& other) const {
        return name == other.name && age == other.age;
    }
};

// Специализация std::hash для структуры Person
namespace std {
    template <>
    struct hash<Person> {
        std::size_t operator()(const Person& p) const {
            return std::hash<std::string>()(p.name) ^ (std::hash<int>()(p.age) << 1);
        }
    };
}

int main() {
    std::unordered_map<Person, std::string> people;
    people[{ "Alice", 30 }] = "Doctor";
    people[{ "Bob", 25 }] = "Engineer";

    for (const auto& [key, value] : people) {
        std::cout << key.name << " (" << key.age << "): " << value << '\n';
    }
}
Ставь 👍 и забирай 📚 Базу знаний

Ищу желающих заполнять карточки товаров на ВБ! Работа полностью на удаленке с зп от 3-5 тыс. рублей в день. Без опыта, нужен
Ищу желающих заполнять карточки товаров на ВБ! Работа полностью на удаленке с зп от 3-5 тыс. рублей в день. Без опыта, нужен только телефон, занятость 3-6 часов в день. Всему обучат на бесплатном курсе и после возьму на работу. Как проходят уроки: ✅ 3 дня уроков по 30 минут ✅ Домашки с проверкой и оплатой бонусами ✅ Плачу 10 тыс за каждую выполненную домашку Все кто пройдет курс, получат сертификат от школы с образовательной лицензией. ⚡ Места ограничены. Набор может закрыться в любой момент. 👍 Жмите "Зарегистрироваться", чтобы успеть занять место. Зарегистрироваться #реклама 16+ course.wildcard.ru О рекламодателе

🤔 Зачем нам нужна move семантика? Move семантика введена с целью повышения эффективности работы с ресурсами, такими как память, файлы, сокеты и другие объекты, которые занимают значительные ресурсы. Она позволяет избежать ненужного копирования объектов, что может быть дорогостоящим как по времени, так и по памяти. 🚩Зачем она нужна? 🟠Эффективность работы с ресурсами Копирование больших объектов может быть очень затратным. Move семантика позволяет перенести ресурсы от одного объекта к другому без дорогостоящего копирования. 🟠Улучшение производительности Перемещение (move) быстрее копирования, поскольку оно всего лишь переназначает указатели на ресурсы, вместо создания их копий. Это особенно важно в приложениях с высокой производительностью, таких как игры, обработка видео, базы данных. 🚩Как это используется? Move семантика реализуется с помощью rvalue ссылок (ссылок на временные объекты) и специальных методов — move конструктора и move оператора присваивания.
#include <iostream>
#include <vector>

class MyClass {
public:
    int* data;
    size_t size;

    // Конструктор
    MyClass(size_t s) : size(s), data(new int[s]) {
        std::cout << "Constructing MyClass\n";
    }

    // Деструктор
    ~MyClass() {
        delete[] data;
        std::cout << "Destructing MyClass\n";
    }

    // Move конструктор
    MyClass(MyClass&& other) noexcept : data(other.data), size(other.size) {
        other.data = nullptr; // Обнуляем указатель у "старого" объекта
        other.size = 0;
        std::cout << "Move constructing MyClass\n";
    }

    // Move оператор присваивания
    MyClass& operator=(MyClass&& other) noexcept {
        if (this != &other) {
            delete[] data; // Освобождаем старый ресурс
            data = other.data;
            size = other.size;
            other.data = nullptr; // Обнуляем указатель у "старого" объекта
            other.size = 0;
            std::cout << "Move assigning MyClass\n";
        }
        return *this;
    }
};

int main() {
    MyClass a(10); // Создаем объект a
    MyClass b = std::move(a); // Перемещаем ресурсы от a к b
    
    return 0;
}
Ставь 👍 и забирай 📚 Базу знаний

IT-инфраструктура под ключ с поддержкой Yandex Cloud Спроектируем, запустим и возьмём на сопровождение. Экспертиза целой кома
+4
IT-инфраструктура под ключ с поддержкой Yandex Cloud Спроектируем, запустим и возьмём на сопровождение. Экспертиза целой команды без найма в штат. 💰Новым клиентам — грант на облачные сервисы, платите только за работу специалистов. Оставьте заявку на сайте: подберём партнёра и рассчитаем стоимость. Получить консультацию #реклама 16+ yandex.cloud О рекламодателе

🤔 Чисто виртуальный метод зачем он нужен и какой синтаксис? Чисто виртуальный метод в C++ определяет интерфейс для производных классов без предоставления реализации. Синтаксис: `virtual ReturnType MethodName() = 0;`. Класс, содержащий чисто виртуальные методы, становится абстрактным, и его нельзя инстанцировать напрямую. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний

Регистрируйтесь на Yandex Scale 2026 Главная конференция Yandex Cloud. Узнайте о сервисах, которые меняют ваш бизнес. 4 офлай
+5
Регистрируйтесь на Yandex Scale 2026 Главная конференция Yandex Cloud. Узнайте о сервисах, которые меняют ваш бизнес. 4 офлайн-трека (AI, Infra + DevTools, Data, Security), онлайн-трек Deep Tech, воркшопы по ИИ и интерактивы. Подробнее о программе читайте в карточках🗒 📅24 сентября 🚗Москва + 💻онлайн Участие бесплатное! Зарегистрироваться #реклама 16+ scale.yandex.cloud О рекламодателе

🤔 В какой момент принимается решение, что хеш таблице надо перестроиться? Решение о необходимости перестроения (рехеширования) хэш-таблицы принимается на основе значения нагрузки (load factor). Нагрузка — это отношение количества элементов в хэш-таблице к количеству бакетов (размеру массива). 🚩Порог нагрузки Для каждой хэш-таблицы обычно определяется пороговое значение нагрузки. Когда фактическая нагрузка превышает это пороговое значение, происходит рехеширование. Формула нагрузки:
\text{load factor} = \frac{\text{number of elements}}{\text{size of table}} 
Типичные пороговые значения: Пороговое значение нагрузки часто устанавливается в пределах от 0.5 до 1.0, в зависимости от реализации. Например, std::unordered_map в стандартной библиотеке C++ по умолчанию использует пороговое значение 1.0. 🚩Процесс рехеширования 1⃣Увеличение размера таблицы Размер массива увеличивается, часто в два раза. 2⃣Перераспределение элементов Все существующие элементы перераспределяются в новую таблицу с использованием новой хэш-функции или той же хэш-функции, но с новым размером таблицы. 🚩Пример
#include <iostream>
#include <list>
#include <vector>

class HashTable {
private:
    int currentSize;
    int numberOfElements;
    double loadFactorThreshold;
    std::vector<std::list<std::pair<int, std::string>>> table;

    void rehash() {
        int oldSize = currentSize;
        currentSize *= 2; // Увеличиваем размер таблицы
        std::vector<std::list<std::pair<int, std::string>>> newTable(currentSize);

        for (const auto& list : table) {
            for (const auto& pair : list) {
                int hashValue = pair.first % currentSize;
                newTable[hashValue].emplace_back(pair.first, pair.second);
            }
        }

        table = std::move(newTable);
    }

public:
    HashTable(int size = 10, double threshold = 0.75) 
        : currentSize(size), numberOfElements(0), loadFactorThreshold(threshold) {
        table.resize(currentSize);
    }

    int hashFunction(int key) {
        return key % currentSize;
    }

    void insertItem(int key, std::string value) {
        int hashValue = hashFunction(key);
        table[hashValue].emplace_back(key, value);
        numberOfElements++;

        // Проверяем, нужно ли выполнять рехеширование
        if (static_cast<double>(numberOfElements) / currentSize > loadFactorThreshold) {
            rehash();
        }
    }

    void displayTable() {
        for (int i = 0; i < currentSize; i++) {
            if (!table[i].empty()) {
                std::cout << "Bucket " << i << ": ";
                for (auto& pair : table[i]) {
                    std::cout << "[" << pair.first << ": " << pair.second << "] ";
                }
                std::cout << std::endl;
            }
        }
    }
};

int main() {
    HashTable ht;
    ht.insertItem(1, "one");
    ht.insertItem(2, "two");
    ht.insertItem(11, "eleven"); // Триггер рехеширования при необходимости

    ht.displayTable();
    // Вывод:
    // Bucket 1: [1: one] 
    // Bucket 2: [2: two] 
    // Bucket 11: [11: eleven]

    return 0;
}
🚩Когда происходит Рехеширование обычно инициируется в момент, когда после добавления нового элемента нагрузка превышает установленное пороговое значение. Это гарантирует, что хэш-таблица будет эффективно обрабатывать операции поиска, вставки и удаления, поддерживая амортизированное постоянное время для этих операций. Ставь 👍 и забирай 📚 Базу знаний

Как PostgreSQL ведёт себя под большой нагрузкой Борьба с блокировками в PostgreSQL: как сохранить параллельность при высокой
Как PostgreSQL ведёт себя под большой нагрузкой Борьба с блокировками в PostgreSQL: как сохранить параллельность при высокой нагрузке. 📅 8 сентября, 20:00 МСК - открытый урок курса «Высоконагруженные системы: архитектура и масштабирование». 📚 Разберём блокировки на уровне транзакций и строк, научимся выявлять взаимные блокировки и узкие места. На реальных примерах покажем оптимизацию запросов и архитектурные приёмы для поддержания производительности. Для разработчиков, архитекторов, инженеров, DBA и аналитиков, работающих с PostgreSQL. Регистрируйтесь - получите практические приёмы и спецусловия на обучение. 😊 Узнать больше #реклама 16+ otus.ru О рекламодателе

🤔 Альтернативное решение для хранения float цены в качестве ключа? Вместо хранения float можно: 1.Преобразовать цену в целочисленное значение (например, умножить на 100 или 1000 для точности до копеек/центов). 2.Хранить результат как int, что обеспечит точное сравнение и отсутствие ошибок округления. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний

🤔 Какой подсчет ссылок имеется в shared_ptr? В умном указателе shared_ptr используется два основных счётчика: счётчик сильных ссылок (strong reference count) и счётчик слабых ссылок (weak reference count). Эти счётчики управляют жизненным циклом объекта и связанных с ним ресурсов различными способами. 🚩Счётчик сильных ссылок Увеличивается каждый раз, когда новый shared_ptr создаётся как копия другого shared_ptr или когда объект присваивается shared_ptr. Этот счётчик уменьшается, когда shared_ptr уничтожается или когда его значение присваивается другому объекту. Когда счётчик достигает нуля, это означает, что больше нет shared_ptr, управляющих этим объектом, и объект удаляется. Это гарантирует, что ресурсы, связанные с объектом, будут освобождены только тогда, когда не останется ни одной "сильной" ссылки. 🚩Счётчик слабых ссылок Используется вместе с weak_ptr, другим типом умных указателей, который может ссылаться на объект, управляемый shared_ptr, но не увеличивает счётчик сильных ссылок. Слабые ссылки не предотвращают удаление объекта, к которому они имеют доступ, так как не участвуют в владении объектом. Счётчик слабых ссылок увеличивается каждый раз, когда создаётся weak_ptr, указывающий на объект, и уменьшается, когда такой weak_ptr уничтожается. Когда счётчик сильных ссылок достигает нуля и объект удаляется, память, выделенная под сам объект, освобождается, но "control block" (блок управления), содержащий счётчики, сохраняется до тех пор, пока счётчик слабых ссылок также не обнулится.
#include <iostream>
#include <memory>

int main() {
    std::shared_ptr<int> sp1 = std::make_shared<int>(10);
    std::cout << "sp1 use_count: " << sp1.use_count() << '\n';  // Вывод: 1

    {
        std::shared_ptr<int> sp2 = sp1;  // Копирование shared_ptr
        std::cout << "sp1 use_count after copy: " << sp1.use_count() << '\n';  // Вывод: 2

        std::weak_ptr<int> wp1 = sp1;  // Создание weak_ptr
        std::cout << "wp1 use_count: " << wp1.use_count() << '\n';  // Вывод: 2
    }  // sp2 выходит из области видимости, use_count уменьшается до 1

    std::cout << "sp1 use_count after sp2 destruction: " << sp1.use_count() << '\n';  // Вывод: 1
    return 0;
}
Ставь 👍 и забирай 📚 Базу знаний

Бесплатный курс по дизайну в FIGMA от Yudaev School Онлайн-программа с наставником и чатом. Внимание! 80% практики. ✅По результату обучения у вас будет портфолио из нескольких работ. ✅Сертификат о прохождении курса. ✅Возможность пройти полное обучение и получить карьерное сопровождение! Учитесь дизайну у профессионалов в Yudaev Shool. Переходи по кнопки: "Подробнее" и начинай свое обучение. Доступ 0 руб. Узнать больше #реклама 16+ yudaevschool24.online О рекламодателе

🤔 В каких STL контейнерах внутри находится хеш таблица? 🚩В стандартной библиотеке шаблонов (STL) C++ хеш-таблица используется для реализации следующих контейнеров 🟠std::unordered_map Ассоциативный контейнер, который хранит пары ключ-значение, с уникальными ключами. Обеспечивает амортизированное среднее время доступа, вставки и удаления за O(1). 🟠std::unordered_multimap Ассоциативный контейнер, который хранит пары ключ-значение, где ключи могут повторяться. Обеспечивает амортизированное среднее время для основных операций за O(1), несмотря на дублирование ключей. 🟠std::unordered_set Ассоциативный контейнер, который хранит уникальные элементы, неупорядоченные. Обеспечивает амортизированное среднее время для основных операций за O(1). 🟠std::unordered_multiset Ассоциативный контейнер, который хранит элементы, где значения могут повторяться, неупорядоченные. Обеспечивает амортизированное среднее время для основных операций за O(1), несмотря на дублирование элементов. Ставь 👍 и забирай 📚 Базу знаний

🤔 Сложность удаление из конца у vector? Удаление элемента из конца vector выполняется за O(1), поскольку не требуется сдвигать элементы. Это делает vector эффективным для операций добавления и удаления в конце. Операции вставки и удаления в конце vector работают за постоянное время, если не требуется перераспределение памяти. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний

Выигрывайте призы от Яндекс Образования Популярные блогеры и студенты ЯО делают что-то новое — и у них получается очень вдохн
Выигрывайте призы от Яндекс Образования Популярные блогеры и студенты ЯО делают что-то новое — и у них получается очень вдохновляюще! Общайтесь с любимыми блогерами и выигрывайте призы Узнать больше #реклама 16+ refer.id О рекламодателе

🤔 Строгая гарантия исключений? Гарантии безопасности исключений (exception safety) в C++ бывают трёх уровней: Базовая гарантия (Basic Guarantee) – программа не падает, но состояние может быть некорректным. Строгая гарантия (Strong Guarantee) – либо операция завершается успешно, либо объект остаётся в исходном состоянии. Гарантия отсутствия исключений (No-throw Guarantee) – операция никогда не бросает исключения. 🚩Что такое строгая гарантия исключений? Строгая гарантия исключений означает, что если во время выполнения метода выбросится исключение, объект останется в том же состоянии, в каком был до вызова метода.
#include <iostream>
#include <vector>

class BadContainer {
    std::vector<int> data;
public:
    void add(int value) {
        data.push_back(value);  // push_back() может выбросить исключение
    }

    void print() {
        for (int x : data) std::cout << x << " ";
        std::cout << std::endl;
    }
};

int main() {
    BadContainer c;
    c.add(1);
    c.add(2);
    c.add(3);
    c.print();  // Вывод: 1 2 3

    try {
        c.add(42);  // Может выбросить исключение (например, при нехватке памяти)
    } catch (...) {
        std::cout << "Ошибка!" << std::endl;
    }

    c.print();  // ?? Возможно, состояние испорчено!
}
🚩Как реализовать строгую гарантию? Чтобы добиться строгой гарантии, используем Copy & Swap: 1. Создаём временный объект. 2. Выполняем изменения на временном объекте. 3. Если всё прошло успешно – меняем указатель (swap).
#include <iostream>
#include <vector>

class SafeContainer {
    std::vector<int> data;
public:
    void add(int value) {
        std::vector<int> temp = data;  // Копируем текущее состояние
        temp.push_back(value);         // Изменяем копию
        std::swap(data, temp);         // Если исключения нет, меняем данные
    }

    void print() {
        for (int x : data) std::cout << x << " ";
        std::cout << std::endl;
    }
};

int main() {
    SafeContainer c;
    c.add(1);
    c.add(2);
    c.add(3);
    c.print();  // Вывод: 1 2 3

    try {
        c.add(42);  // Если тут исключение, объект не изменится
    } catch (...) {
        std::cout << "Ошибка!" << std::endl;
    }

    c.print();  // Вывод: 1 2 3 (не испорчен!)
}
🚩Где ещё применяется строгая гарантия? Операции присваивания (operator=) с Copy & Swap Функции, изменяющие состояние контейнеров (std::vector::resize, std::map::insert) Операции перевыделения памяти Функции стандартной библиотеки (std::sort) Ставь 👍 и забирай 📚 Базу знаний

🤔 Асимптотическая сложность в list? std::list — это двусвязный список, где каждый элемент хранит ссылку на предыдущий и следующий элементы. Это даёт эффективное добавление и удаление элементов в любой части списка, но делает доступ по индексу медленным 🚩Разбор операций в `std::list` с примерами Добавление в начало и конец — O(1)
std::list<int> lst;
lst.push_back(10);  // O(1)
lst.push_front(5);  // O(1)
Доступ по индексу — O(n)
auto it = std::next(lst.begin(), 2); // O(n), приходится идти от начала
std::cout << *it << std::endl;
Вставка и удаление по итератору — O(1)
auto it = lst.begin();
std::advance(it, 1);  // Двигаем итератор на 1 элемент (O(n))

lst.insert(it, 8);  // O(1), просто меняем указатели
lst.erase(it);      // O(1), просто изменяем ссылки соседних элементов
Поиск элемента — O(n)
auto it = std::find(lst.begin(), lst.end(), 8); // O(n)
Сортировка — O(n log n)
lst.sort(); // O(n log n), потому что используется сортировка слиянием
Ставь 👍 и забирай 📚 Базу знаний

🤔 Что такое абстрактный класс? Это класс, который содержит хотя бы одну чисто виртуальную функцию. Он не может быть создан как объект и предназначен для использования в качестве базового класса. Такие классы служат для определения интерфейсов и полиморфного поведения. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний