C++ C++  ·  30 вопросов  ·  ~85 мин  ·  ⏱ Таймер 25:00  ·  Сложный  · 

Модернизация старого C++

Тест предлагает не переписать старую систему «на современный лад», а выбрать безопасную последовательность изменений. В каждом случае важно сохранить наблюдаемое поведение, сделать владение явным и не спутать косметическую замену синтаксиса с устранением настоящего риска.

Отвечено: 0 из 30
⏱ --:--
0%
💡 Инструкция: Выберите один ответ из пяти. В тесте 30 вопросов, время — 85 минут. Во многих заданиях недостаточно узнать конструкцию: проследите порядок вычислений, время жизни объектов, владение ресурсами и условия, при которых решение остаётся корректным. После завершения откроются правильные ответы, объяснения, общий результат и тематические шкалы.
Вопрос 1 из 30
Поле `Engine* engine_` не удаляется в деструкторе и обязано указывать на движок, который живёт дольше автомобиля. Какая первая правка лучше выражает этот контракт?
C++C++20
class Car {
    Engine* engine_; // не владеет; nullptr недопустим
public:
    explicit Car(Engine* e) : engine_(e) {}
};
Вопрос 2 из 30
Функция возвращает выделенный массив и длину через второй параметр. Какой промежуточный интерфейс проще всего сделать безопасным, не меняя формат данных?
C++C++20
Record* load_records(const char* path, std::size_t* count);
Вопрос 3 из 30
Какой дефект останется, если механически заменить `Widget*` на `std::unique_ptr<Widget>`, но продолжить передавать `p.get()` в объект, который хранит указатель дольше владельца?
C++C++20
auto p = std::make_unique<Widget>();
registry.remember(p.get());
// p уничтожается раньше registry
Вопрос 4 из 30
Старый API принимает `char*`, хотя строку не меняет и требует завершающий ноль. Какая правка минимальна и содержательна?
C++C++20
int parse_name(char* text); // функция только читает text
Вопрос 5 из 30
Когда сырой указатель в современном интерфейсе остаётся уместным?
Вопрос 6 из 30
Как устранить утечку файла при любом раннем выходе, не размазывая `fclose` по веткам?
C++C++20
FILE* f = std::fopen(path, "rb");
if (!f) return error();
if (!read_header(f)) return bad_header(); // утечка
Вопрос 7 из 30
Какой современный тип заменяет ручную пару `mutex.lock()` / `mutex.unlock()` в простой критической секции?
C++C++20
mutex.lock();
update_state(); // может бросить
mutex.unlock();
Вопрос 8 из 30
C-библиотека возвращает `Handle*`, освобождаемый `destroy_handle`. Какой адаптер лучше всего локализует правило?
C++C++20
struct HandleDeleter {
    void operator()(Handle* h) const noexcept { destroy_handle(h); }
};
Вопрос 9 из 30
Конструктор вручную выделяет два ресурса. Второе выделение бросает. Почему деструктор класса не спасёт первый ресурс?
C++C++20
Session::Session() {
    socket_ = open_socket();
    buffer_ = new char[huge_size]; // может бросить
}
Вопрос 10 из 30
Как безопаснее модернизировать функцию с десятком `goto cleanup`, если она управляет разными ресурсами?
C++C++20
Result process() {
    File file = open_file();
    Lock lock = acquire_lock();
    Buffer buffer = allocate_buffer();

    if (auto error = read(file, buffer)) return std::unexpected(*error);
    return transform(buffer);
}
Вопрос 11 из 30
Почему макрос опасен при вызове `SQUARE(i++)`?
C++C++20
#define SQUARE(x) ((x) * (x))
int i = 3;
auto y = SQUARE(i++);
Вопрос 12 из 30
Чем лучше заменить числовой макрос, используемый как типизированная константа?
C++C++20
#define MAX_PACKET_SIZE 4096
Вопрос 13 из 30
Макрос журналирования должен полностью исчезать в выпускной сборке. Какая деталь важна при замене на функцию?
C++C++20
#ifdef DEBUG
#define TRACE(expr) log(expr)
#else
#define TRACE(expr) ((void)0)
#endif
Вопрос 14 из 30
Какой макрос обычно нельзя просто заменить constexpr-функцией?
Вопрос 15 из 30
Почему `#define private public` в тестах — плохая модернизация?
C++C++20
#define private public
#include "account.hpp"
#undef private

TEST(Account, InternalBalance) {
    Account a;
    EXPECT_EQ(a.balance_, 0);
}
Вопрос 16 из 30
Перед заменой сложного парсера без спецификации что сделать первым?
Вопрос 17 из 30
Как безопасно заменить глобальный вызов времени, мешающий тестам?
C++C++20
bool expired(const Token& t) {
    return std::time(nullptr) > t.deadline;
}
Вопрос 18 из 30
Старый интерфейс возвращает код ошибки и заполняет out-параметр. Какой порядок миграции снижает риск?
C++C++20
int read_user(int id, User* out); // 0 — успех, иначе код ошибки
Вопрос 19 из 30
Какой коммит слишком велик для безопасной модернизации?
Вопрос 20 из 30
Что означает strangler-подход для большого старого модуля?
Вопрос 21 из 30
Какой инструмент первым поможет найти чтение уже освобождённой памяти в старом тестовом прогоне?
C++C++20
auto* p = new Item;
delete p;
return p->id;
Вопрос 22 из 30
Почему включение `-Werror` сразу для всего старого проекта часто мешает безопасной модернизации?
C++C++20
# CMakeLists.txt
add_library(legacy_core ${LEGACY_SOURCES})
target_compile_options(legacy_core PRIVATE -Wall -Wextra)

add_library(new_core ${NEW_SOURCES})
target_compile_options(new_core PRIVATE -Wall -Wextra -Werror)
Вопрос 23 из 30
Как differential testing помогает при переписывании сериализатора?
C++C++20
auto old_bytes = legacy_encode(value);
auto new_bytes = modern_encode(value);
CHECK(normalize(old_bytes) == normalize(new_bytes));
Вопрос 24 из 30
Старый тест иногда падает из-за ожидания `sleep(50ms)`. Какая правка содержательнее увеличения задержки?
C++C++20
std::latch started{1};
std::promise<void> completed;

auto worker = std::async([&] {
    started.count_down();
    do_work();
    completed.set_value();
});

started.wait();
completed.get_future().wait();
Вопрос 25 из 30
Что важнее простого процента покрытия при модернизации?
Вопрос 26 из 30
После замены `const std::string&` на `std::string_view` функция стала быстрее в микротесте, но иногда падает. Наиболее вероятная причина?
C++C++20
std::string_view cached;
void remember(std::string_view s) { cached = s; }
remember(std::string("temporary"));
Вопрос 27 из 30
Как сохранить ABI библиотеки, постепенно меняя тяжёлую реализацию класса?
Вопрос 28 из 30
Старый getter возвращает большой vector по значению. Нужно ли автоматически менять его на const-ссылку?
C++C++20
std::vector<Row> make_report();
Вопрос 29 из 30
Какой признак указывает на слишком широкий старый API?
Вопрос 30 из 30
Как доказать, что модернизация не ухудшила производительность?

Ответьте на все 30 вопросов, чтобы получить результат

🔗 Встроить тест на свой сайт (iframe) ▼

Скопируйте код и вставьте в любое место на вашем сайте:

Также доступна прямая ссылка на embed-страницу