Поддерживает ли связный список (linked list) механизм copy-on-write по умолчанию?

«Поддерживает ли связный список (linked list) механизм copy-on-write по умолчанию?» — вопрос из категории Алгоритмы и структуры данных, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Нет. Связный список, как структура данных, основанная на явных ссылках между узлами, по умолчанию не поддерживает механизм copy-on-write (CoW). При простом присваивании (list2 = list1) копируется только ссылка на головной узел, а не вся структура данных. Это приводит к проблеме разделяемого состояния.

Пример проблемы (Swift):

class Node<T> {
    var value: T
    var next: Node?
    init(_ value: T) { self.value = value }
}

var list1 = Node(1)
list1.next = Node(2)
var list2 = list1 // list1 и list2 ссылаются на одни и те же узлы

list2.value = 10 // Изменение затронет и list1.value!
print(list1.value) // Выведет 10, а не 1

Почему это важно? Без CoW нарушается принцип value-семантики, что ведет к неожиданным побочным эффектам и усложняет отладку.

Как реализовать CoW для связного списка?

  1. Использовать value-типы для узлов: Обернуть данные в класс (reference type) и управлять копированием этого класса.
  2. Проверять уникальность ссылки: Перед модификацией проверять, является ли экземпляр единственным владельцем данных с помощью isKnownUniquelyReferenced.
  3. Выполнять копирование при записи: Если ссылка не уникальна, создать полную копию структуры данных перед её изменением.

Встроенные коллекции Swift (Array, Dictionary, Set) реализуют CoW автоматически, но для кастомных структур это необходимо делать вручную.