Конфигурационное управление (КУ) – это совокупность методик, структур данных и процедур, обеспечивающих идентификацию, контроль изменений, учёт состояния и аудит конфигураций программных и данных артефактов. На уровне информатики КУ опирается на формальные модели (графы версий, хэш-функции, ограничения совместимости), алгоритмы (топологическая сортировка, трёхстороннее слияние, поиск на графах, проверка целостности) и дисциплину данных (абстракция конфигурационный элемент и базовая линия).
Почему это важно для ЕГЭ. Задачи ЕГЭ систематически проверяют: работу с графами (зависимости, топологическая сортировка), строки (сравнение версий, диффы), числа и хеши (контрольные суммы), логику и ограничительные условия (совместимость версий), а также корректную оценку сложностей. КУ – богатый контекст для этих умений.
Конфигурационный элемент и конфигурация
Пусть задано множество конфигурационных элементов I (исходный файл, библиотека, таблица данных, спецификация). Для каждого элемента i ∈ I существует множество версий V_i с отношением частичного порядка «предок–потомок» (обычно это DAG – ориентированный ацикличный граф версий).
Определение конфигурации:
C = { (i, v_i) | i ∈ I, v_i ∈ V_i }.
C – полное назначение версии для каждого элемента.
Базовая линия (baseline)
Базовая линия B_t – зафиксированная, проверенная на целостность конфигурация на момент t.
Требование воспроизводимости:
∀ C1, C2: (C1 = C2) ⇒ build(C1) = build(C2).
То есть одинаковый набор исходов порождает бит-идентичный артефакт.
Граф версий и операция слияния
Для элемента i граф версий G_i = (V_i, E_i) – DAG; ребро u → v означает «v получена из u коммитом/изменением».
Нижний общий предок (LCA) двух версий a, b – версия l, являющаяся их общим предком и находящаяся «ниже всех» среди общих предков. В трёхстороннем слиянии используется база l и изменения l→a, l→b.
Целостность (хеш-контроль)
Хеш-функция:
h: {0,1}* → {0,1}^k
должна обеспечивать устойчивость к коллизиям на практическом уровне. Проверка целостности файла F:
ok(F) = (h(F) = h_expected).
Совместимость версий (семантическое версионирование)
Версия представляется кортежем:
ver = (MAJOR, MINOR, PATCH)
Правила переходов в упрощённой модели:
несовместимые изменения → MAJOR := MAJOR + 1; MINOR := 0; PATCH := 0
обратная совместимость с добавлениями → MINOR := MINOR + 1; PATCH := 0
исправление без изменения интерфейсов → PATCH := PATCH + 1
Сравнение версий – лексикографическое по числам:
(a1,a2,a3) < (b1,b2,b3) ⇔
a1<b1 ∨ (a1=b1 ∧ a2<b2) ∨ (a1=b1 ∧ a2=b2 ∧ a3<b3).

Топологическая сортировка (порядок сборки)
Пусть зависимости компонентов заданы графом G=(V,E), где u→v означает «v зависит от u». Требуется упорядочить сборку так, чтобы каждый компонент собирался после зависимостей. Решение – топологическая сортировка (алгоритм Кана):
Псевдокод (копируемый):
toposort(G):
in[v] := входная_степень(v) для всех v∈V
Q := очередь всех v с in[v]=0
order := []
while Q не пуста:
u := pop(Q); append(order,u)
для каждого ребра (u→w):
in[w] := in[w] - 1
если in[w]=0: push(Q,w)
если |order| < |V|: цикл существует (ошибка)
вернуть order
Сложность O(|V|+|E|).
Трёхстороннее слияние (three-way merge)
Даны тексты Base, A, B. Строится дифф Base→A и Base→B и применяется к Base. Конфликт возникает при перекрывающихся изменениях в одинаковом диапазоне. Упрощённая эвристика: «если обе стороны модифицировали разный контекст – слияние автоматическое; иначе – конфликт».
Контрольная сумма (упрощённый пример для задач)
Для учебных целей удобно использовать проверку:
hash(s) = (Σ_{i=1..|s|} code(s[i])) mod M,
где code(c) – код символа (например, Unicode), M – заданный модуль (простое число).
Разрешение зависимостей как задача удовлетворения ограничений
Пусть множество требований:
R = { i: ver(i) ∈ Di }
где Di – допустимые версии (a.b.x, ≥1.2.0, =2.*). Поиск согласованной базовой линии сводится к перебору с отсечениями (backtracking) или редукции к SAT/ILP в общем случае; в экзаменационном контексте достаточно целенаправленного DFS по сортированным доменам.
Правило 1. Неизменяемость истории. Опубликованные версии/артефакты не переписываются; исправление = новая версия.
Правило 2. Атомарность коммитов. Один коммит – одна логическая единица изменения; сообщение фиксирует «что» и «зачем».
Правило 3. Полная трассировка. Каждое изменение трассируется: CR → коммит(ы) → сборка → тест → релиз.
Правило 4. Воспроизводимость сборки. Жёсткие версии зависимостей, зафиксированные хеш-идентификаторы источников и артефактов; сборка «из кода» детерминирована.
Правило 5. Контроль целостности. Все артефакты снабжены хешами/подписями; при переносе – обязательная верификация.
Правило 6. Управление ветками. Главная линия стабильности (main/release) и краткоживущие ветви задач; слияние – через ревью и тесты.
Правило 7. Базовые линии. Любой релиз – это помеченная базовая линия; входящие версии перечислены и проверены.
Правило 8. Идемпотентные конфигурации среды. Параметры развертывания – как код (скрипт/манифест); повторный запуск при одинаковом входе даёт одинаковый результат.
Упражнение 1. Топологическая сортировка и проверка на циклы
Дан набор компонентов V = {A,B,C,D,E} и зависимости
A→C, B→C, C→D, B→E.
a) Постройте любой корректный топологический порядок сборки.
b) Оцените временную сложность алгоритма Кана для данного графа.
c) Добавьте зависимость D→B и объясните, почему теперь порядок не существует. Опишите, как алгоритм обнаружит цикл (критерий |order| < |V|).
Упражнение 2. Трёхстороннее слияние (обнаружение конфликта)
Имеются тексты (по строкам):
Base
1: color = blue
2: size = M
3: mode = auto
A
1: color = blue
2: size = L
3: mode = auto
B
1: colour = blue
2: size = M
3: mode = auto
a) Выполните трёхстороннее слияние Base, A, B.
b) Объясните, какие изменения независимы (локальны), а какие приводят к конфликту (переименование color→colour и изменение выравнивания пробелов – влияет ли на содержательную часть?).
c) Сформулируйте правило нормализации пробельных последовательностей перед слиянием, уменьшающее ложные конфликты.
Упражнение 3. Сравнение и упорядочивание версий
Даны версии: 2.10.3, 2.9.11, 3.0.0, 2.10.2, 2.10.3-alpha (считайте, что суффикс -alpha меньше любого финального PATCH).
a) Отсортируйте их по возрастанию с учётом правила: предварительные релизы < финальных при равных MAJOR.MINOR.PATCH.
b) Укажите, какая версия должна быть выбрана как следующая исправляющая после 2.10.3 (PATCH+1).
c) Объясните, почему лексикографическое сравнение строк без разбиения на числа даёт неправильный порядок для 2.10.x и 2.9.x.
Упражнение 4. Контрольные суммы и выявление дубликатов
Пусть M = 1000003 (простое). Даны имена файлов и их содержимое (короткие строки). Требуется:
a) Вычислить hash для каждого файла по формуле
hash(s) = (Σ code(s[i])) mod M
b) Обнаружить дубликаты содержимого по совпадающим hash и длине строки.
c) Объяснить, почему одинаковые hash при разной длине – индикатор возможной коллизии. Предложить стратегию детерминированной до-проверки (побайтное сравнение при совпадении hash).
Упражнение 5. Разрешение зависимостей как задача ограничений
Компоненты A,B,C имеют домены версий:
A ∈ {1.2.0, 1.3.0}, B ∈ {2.0.0, 2.1.0}, C ∈ {3.0.0, 3.1.0}.
Ограничения:
Конфигурационное управление – строго формализуемая область информатики, где встречаются фундаментальные структуры и алгоритмы: графы зависимостей (топология), частичные порядки (версии), хеш-контроль (целостность), унификация изменений (merge) и удовлетворение ограничений (совместимость). Освоение изложенных правил (неизменяемость истории, атомарность, трассировка, воспроизводимость, контроль целостности, дисциплина ветвления и базовых линий) вместе с алгоритмическими техникami даёт двойной эффект: повышает качество инженерных решений и прямо укрепляет навыки, проверяемые на ЕГЭ – работу с графами, строками, числами, логикой и сложностью.