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

Модули и организация крупного проекта

Профессиональный тест рассматривает модули не как замену пары include guard, а как новую границу видимости и сборки. Вопросы охватывают экспорт, partitions, global module fragment, ODR, циклические зависимости и архитектуру компонентов, которую нельзя исправить одним `export`.

Отвечено: 0 из 30
⏱ --:--
0%
💡 Инструкция: Выберите один ответ из пяти. В тесте 30 вопросов, время — 85 минут. Во многих заданиях недостаточно узнать конструкцию: проследите порядок вычислений, время жизни объектов, владение ресурсами и условия, при которых решение остаётся корректным. После завершения откроются правильные ответы, объяснения, общий результат и тематические шкалы.
Вопрос 1 из 30
Что делает строка `export module math;`?
C++C++20
export module math;

export int add(int a, int b);

int hidden_helper(int value) {
    return value * 2;
}
Вопрос 2 из 30
Что увидит импортирующий код из блока `export { ... }`?
C++C++20
export module geometry;

export {
    struct Point { double x, y; };
    double distance(Point a, Point b);
}

int internal_counter = 0;
Вопрос 3 из 30
Чем implementation unit `module math;` отличается от interface unit?
C++C++20
// math.cppm — interface unit
export module math;
export int add(int, int);

// math.cpp — implementation unit
module math;
int add(int a, int b) { return a + b; }
Вопрос 4 из 30
Для чего нужна module partition `math:detail`?
C++C++20
// math-detail.cppm
export module math:detail;
export int normalize(int);

// math.cppm
export module math;
import :detail;
export int calculate(int value);
Вопрос 5 из 30
Становится ли импортированный модуль автоматически доступен клиенту модуля?
C++C++20
export module reports;
import formatting;          // только внутренняя зависимость
export import report_types; // доступна импортирующему коду
export Report build_report();
Вопрос 6 из 30
Главное отличие textual `#include` от `import` модуля?
C++C++20
// Текстовое включение зависит от макросов места включения.
#define VALUE_TYPE long
#include "configurable.hpp"

// Импорт получает уже собранный интерфейс модуля.
import configuration;
Вопрос 7 из 30
Зачем нужен global module fragment, начинающийся с `module;`?
C++C++20
module;
#include <windows.h>
#include "legacy_c_api.h"

export module platform;
export Handle open_handle();
Вопрос 8 из 30
Что такое header unit?
C++C++20
import <vector>;
import <string>;
// стандартные заголовки используются как header units,
// если это поддерживает toolchain и конфигурация сборки
Вопрос 9 из 30
Почему конфигурационный заголовок, зависящий от макросов перед include, трудно превратить в header unit?
C++C++20
// legacy_config.hpp
#if FEATURE_LEVEL >= 2
using Payload = RichPayload;
#else
using Payload = CompactPayload;
#endif

// разные TU раньше задавали FEATURE_LEVEL перед #include
Вопрос 10 из 30
Нужен ли include guard внутри настоящей module interface unit?
C++C++20
export module geometry;
export struct Point {
    double x;
    double y;
};
Вопрос 11 из 30
Что запрещает ODR для обычной невстроенной функции с внешним связыванием?
C++C++20
// a.cpp
int calculate() { return 1; }
// b.cpp
int calculate() { return 2; }
// обе функции имеют внешнее связывание
Вопрос 12 из 30
Почему inline-функция может иметь определения в нескольких единицах трансляции?
C++C++20
// math.hpp
inline int clamp_positive(int x) {
    return x < 0 ? 0 : x;
}
// одинаковое определение встречается в нескольких TU
Вопрос 13 из 30
Каким образом модули уменьшают риск случайных нарушений ODR по сравнению с текстовыми заголовками?
C++C++20
export module parser;
export int parse(std::string_view text);

module parser;
int parse(std::string_view text) {
    return implementation(text);
}
Вопрос 14 из 30
Почему разный `#pragma pack` вокруг одного заголовка в двух единицах особенно опасен?
C++C++20
// a.cpp
#pragma pack(push, 1)
#include "packet.hpp"
#pragma pack(pop)

// b.cpp
#include "packet.hpp"

static_assert(sizeof(Packet) /* различается */);
Вопрос 15 из 30
Где должно находиться определение экспортируемого шаблона `Box`, чтобы его могли использовать импортирующие единицы?
C++C++20
export module containers;
export template<class T>
class Box {
public:
    explicit Box(T value) : value_(std::move(value)) {}
private:
    T value_;
};
Вопрос 16 из 30
Почему экспорт `std::vector<InternalType>` раскрывает реализацию?
C++C++20
export module catalog;

class InternalType;
export std::vector<InternalType> load_items();
// Клиенту нужен layout и операции vector<InternalType>.
Вопрос 17 из 30
Когда pImpl остаётся полезным даже с modules?
C++C++20
export module storage;
export class Storage {
public:
    Storage();
    ~Storage();
    void save(Record);
private:
    struct Impl;
    std::unique_ptr<Impl> impl_;
};
Вопрос 18 из 30
Как разорвать цикл компонентов A ↔ B?
C++C++20
// contracts module
export struct EventSink {
    virtual void on_event(const Event&) = 0;
    virtual ~EventSink() = default;
};
// A и B зависят от EventSink, но не друг от друга
Вопрос 19 из 30
Что лучше экспортировать из инфраструктурного модуля логирования?
Вопрос 20 из 30
Почему “один модуль на каждый исходный файл” не обязательно хорошая миграция?
Вопрос 21 из 30
Почему stale BMI опасен?
Вопрос 22 из 30
Как проверить, что имя действительно экспортировано?
Вопрос 23 из 30
Почему сборка разными версиями компилятора/флагами может ломать импорт готового BMI?
Вопрос 24 из 30
Как обнаружить скрытую зависимость от textual include?
Вопрос 25 из 30
Какой тест полезен при миграции legacy-заголовка в модуль?
Вопрос 26 из 30
Всегда ли modules ускоряют любую сборку?
Вопрос 27 из 30
Что сильнее всего расширяет область пересборки?
Вопрос 28 из 30
Почему большой шаблонный API остаётся дорогим даже в модуле?
Вопрос 29 из 30
Как выбрать размер модуля?
Вопрос 30 из 30
Какая метрика миграции кроме времени сборки важна?

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

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

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

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