Какие коллекции существуют в C#?
Что проверяют
Ориентируетесь ли вы в пространствах имён и умеете ли выбирать по сложности операций.
Как отвечать
Основные из System.Collections.Generic:
- List\<T\>: динамический массив. Доступ по индексу O(1), добавление в конец амортизированно O(1), вставка в середину O(n);
- Dictionary\<TKey, TValue\>: хеш-таблица, доступ в среднем O(1), порядок не гарантирован;
- HashSet\<T\>: множество уникальных значений, быстрая проверка вхождения и операции над множествами;
- SortedDictionary\<K,V\> (дерево, O(log n)) и SortedList\<K,V\> (два массива, быстрее по памяти и по индексу, но вставка O(n));
- Queue\<T\> и Stack\<T\>: очередь и стек;
- LinkedList\<T\>: двусвязный список, вставка по узлу O(1), доступ по индексу O(n).
Для многопоточности System.Collections.Concurrent: ConcurrentDictionary, ConcurrentQueue, ConcurrentBag, BlockingCollection для схемы «производитель и потребитель».
Неизменяемые: System.Collections.Immutable (ImmutableList, ImmutableDictionary), где изменение возвращает новую коллекцию, а старая остаётся валидной для других потоков.
Отдельно про интерфейсы: параметры методов лучше типизировать как IEnumerable<T> или IReadOnlyList<T>, а не как List<T>, чтобы не связывать вызывающего конкретной реализацией.
И про Span<T> и Memory<T>: они позволяют работать с участком памяти без копирования, что заметно в горячем коде.
Где спотыкаются
Используют List.Contains в цикле там, где нужен HashSet.
Берут LinkedList ради вставки, забывая про поиск позиции.
Возвращают List<T> наружу, позволяя вызывающему менять внутреннее состояние.
Не знают про конкурентные коллекции и оборачивают обычные в lock.