Senior Go Interview Prep - Core Go: https://go.vbloher.org/docs/01-core-go/ - Механика defer в Go: https://go.vbloher.org/docs/01-core-go/defer/ - Встраивание структур и интерфейсов (Embedding): https://go.vbloher.org/docs/01-core-go/embedding/ - Ошибки в Go: error, wrapping, errors.Is/As/Join: https://go.vbloher.org/docs/01-core-go/errors/ - Дженерики в Go (1.18+): https://go.vbloher.org/docs/01-core-go/generics/ - Интерфейсы в Go: https://go.vbloher.org/docs/01-core-go/interfaces/ - Устройство map в Go: https://go.vbloher.org/docs/01-core-go/maps/ - panic / recover: механика, раскрутка стека и runtime-паники: https://go.vbloher.org/docs/01-core-go/panic-recover/ - Указатели в Go: https://go.vbloher.org/docs/01-core-go/pointers/ - Рефлексия в Go (reflect): https://go.vbloher.org/docs/01-core-go/reflection/ - Внутреннее устройство слайсов в Go: https://go.vbloher.org/docs/01-core-go/slices/ - Строки, руны и байты в Go: https://go.vbloher.org/docs/01-core-go/strings-runes-bytes/ - Система типов Go: defined types, alignment, memory layout: https://go.vbloher.org/docs/01-core-go/type-system/ - Concurrency: https://go.vbloher.org/docs/02-concurrency/ - sync/atomic: https://go.vbloher.org/docs/02-concurrency/atomic/ - Буферизованные vs небуферизованные каналы: https://go.vbloher.org/docs/02-concurrency/buffered-unbuffered/ - Канал vs Mutex: когда что выбрать: https://go.vbloher.org/docs/02-concurrency/channel-vs-mutex/ - Каналы: устройство hchan: https://go.vbloher.org/docs/02-concurrency/channels/ - Утечки горутин, дедлоки, livelock, starvation: https://go.vbloher.org/docs/02-concurrency/common-leaks-deadlocks/ - sync.Cond: https://go.vbloher.org/docs/02-concurrency/cond/ - context: https://go.vbloher.org/docs/02-concurrency/context/ - Горутины: жизненный цикл, стоимость, стек: https://go.vbloher.org/docs/02-concurrency/goroutines-lifecycle/ - sync.Mutex и sync.RWMutex: https://go.vbloher.org/docs/02-concurrency/mutex-rwmutex/ - sync.Once: https://go.vbloher.org/docs/02-concurrency/once/ - Паттерны конкурентности: https://go.vbloher.org/docs/02-concurrency/patterns/ - Race Detector (гонки данных и -race): https://go.vbloher.org/docs/02-concurrency/race-detector/ - Планировщик GMP: https://go.vbloher.org/docs/02-concurrency/scheduler-gmp/ - select: https://go.vbloher.org/docs/02-concurrency/select/ - sync.WaitGroup: https://go.vbloher.org/docs/02-concurrency/waitgroup/ - Runtime и память: https://go.vbloher.org/docs/03-runtime-memory/ - Паттерны аллокаций и снижение давления на GC: https://go.vbloher.org/docs/03-runtime-memory/allocation-patterns/ - Escape Analysis: когда переменная убегает в кучу: https://go.vbloher.org/docs/03-runtime-memory/escape-analysis/ - Сборщик мусора Go: concurrent tri-color mark-sweep: https://go.vbloher.org/docs/03-runtime-memory/gc/ - Тюнинг GC: GOGC и GOMEMLIMIT: https://go.vbloher.org/docs/03-runtime-memory/gogc-gomemlimit/ - GOMAXPROCS: параллелизм планировщика и проблема контейнеров: https://go.vbloher.org/docs/03-runtime-memory/gomaxprocs/ - Утечки горутин (goroutine leaks): https://go.vbloher.org/docs/03-runtime-memory/goroutine-leaks/ - Утечки памяти в Go (несмотря на GC): https://go.vbloher.org/docs/03-runtime-memory/memory-leaks/ - Модель памяти Go (Go Memory Model): happens-before и синхронизация: https://go.vbloher.org/docs/03-runtime-memory/memory-model/ - pprof: профилирование CPU, памяти и блокировок в Go: https://go.vbloher.org/docs/03-runtime-memory/pprof/ - Execution Tracer и runtime/trace: тайминги вместо агрегатов: https://go.vbloher.org/docs/03-runtime-memory/runtime-tracing/ - Стек vs Куча: где живут данные в Go: https://go.vbloher.org/docs/03-runtime-memory/stack-vs-heap/ - Тестирование: https://go.vbloher.org/docs/04-testing/ - testify, assert/require и golden files: https://go.vbloher.org/docs/04-testing/assertions-testify/ - Бенчмарки в Go: https://go.vbloher.org/docs/04-testing/benchmarks/ - Покрытие, -race и флаки-тесты: https://go.vbloher.org/docs/04-testing/coverage-race/ - Нативный fuzzing в Go (1.18+): https://go.vbloher.org/docs/04-testing/fuzzing/ - Интеграционные тесты, testcontainers-go, TestMain: https://go.vbloher.org/docs/04-testing/integration-testcontainers/ - Моки, стабы и тестируемость: https://go.vbloher.org/docs/04-testing/mocks/ - Table-driven тесты, subtests и параллельность: https://go.vbloher.org/docs/04-testing/table-driven/ - Backend: https://go.vbloher.org/docs/05-backend/ - Аутентификация и авторизация: AuthN/AuthZ, сессии vs токены, RBAC/ABAC, API keys, mTLS, секреты: https://go.vbloher.org/docs/05-backend/auth-authz/ - Graceful Shutdown HTTP/gRPC сервера в Go: https://go.vbloher.org/docs/05-backend/graceful-shutdown/ - gRPC: типы RPC, интерсепторы, контекст, метаданные, error model: https://go.vbloher.org/docs/05-backend/grpc/ - JWT (JSON Web Token): https://go.vbloher.org/docs/05-backend/jwt/ - Middleware-паттерн в Go: https://go.vbloher.org/docs/05-backend/middleware/ - net/http: Server, Handler, ServeMux, таймауты, Client и контекст: https://go.vbloher.org/docs/05-backend/net-http/ - OAuth2: роли, grant types, OIDC, токены и типовые ошибки: https://go.vbloher.org/docs/05-backend/oauth2/ - OpenAPI/Swagger, code generation, contract-first vs code-first, валидация: https://go.vbloher.org/docs/05-backend/openapi/ - Protocol Buffers: схемы, wire format, эволюция и совместимость: https://go.vbloher.org/docs/05-backend/protobuf/ - REST: принципы, версионирование, идемпотентность, статусы, пагинация, ошибки: https://go.vbloher.org/docs/05-backend/rest/ - Сети и протоколы: https://go.vbloher.org/docs/06-networking/ - Пулы соединений: http.Transport, БД, утечки: https://go.vbloher.org/docs/06-networking/connection-pooling/ - DNS: записи, резолвинг, кэширование, DNS в Go: https://go.vbloher.org/docs/06-networking/dns/ - Версии HTTP: 1.1, 2, 3: https://go.vbloher.org/docs/06-networking/http-versions/ - TCP/IP: модель, транспорт и что важно бэкендеру: https://go.vbloher.org/docs/06-networking/tcp-ip/ - TLS: handshake, сертификаты, mTLS, производительность: https://go.vbloher.org/docs/06-networking/tls/ - UDP и надёжность поверх UDP: https://go.vbloher.org/docs/06-networking/udp/ - WebSocket: upgrade, фреймы, масштабирование: https://go.vbloher.org/docs/06-networking/websocket/ - Базы данных: https://go.vbloher.org/docs/07-databases/ - Пул соединений к PostgreSQL в Go: database/sql, pgx, pgxpool, PgBouncer: https://go.vbloher.org/docs/07-databases/connection-pooling-pgx/ - Взаимоблокировки (Deadlocks) в PostgreSQL: https://go.vbloher.org/docs/07-databases/deadlocks/ - Индексы в PostgreSQL: https://go.vbloher.org/docs/07-databases/indexes/ - Уровни изоляции транзакций в PostgreSQL: https://go.vbloher.org/docs/07-databases/isolation-levels/ - MVCC в PostgreSQL: версии строк, видимость, VACUUM и bloat: https://go.vbloher.org/docs/07-databases/mvcc/ - Обзор NoSQL и Redis: https://go.vbloher.org/docs/07-databases/nosql-redis/ - Партиционирование таблиц в PostgreSQL: https://go.vbloher.org/docs/07-databases/partitioning/ - Архитектура PostgreSQL: https://go.vbloher.org/docs/07-databases/postgresql-architecture/ - Планирование и оптимизация запросов в PostgreSQL: https://go.vbloher.org/docs/07-databases/query-planning/ - Репликация в PostgreSQL: https://go.vbloher.org/docs/07-databases/replication/ - Шардирование (горизонтальное масштабирование): https://go.vbloher.org/docs/07-databases/sharding/ - Транзакции в PostgreSQL и Go (database/sql, pgx): https://go.vbloher.org/docs/07-databases/transactions/ - Распределённые системы: https://go.vbloher.org/docs/08-distributed-systems/ - CAP теорема: https://go.vbloher.org/docs/08-distributed-systems/cap-theorem/ - Circuit Breaker: https://go.vbloher.org/docs/08-distributed-systems/circuit-breaker/ - Консенсус и Raft: репликация состояния в присутствии отказов: https://go.vbloher.org/docs/08-distributed-systems/consensus-raft/ - Модели согласованности: https://go.vbloher.org/docs/08-distributed-systems/consistency/ - Гарантии доставки сообщений: at-most-once / at-least-once / exactly-once: https://go.vbloher.org/docs/08-distributed-systems/delivery-guarantees/ - Eventual Consistency: https://go.vbloher.org/docs/08-distributed-systems/eventual-consistency/ - Идемпотентность в распределённых системах: https://go.vbloher.org/docs/08-distributed-systems/idempotency/ - Apache Kafka: https://go.vbloher.org/docs/08-distributed-systems/kafka/ - Transactional Outbox: https://go.vbloher.org/docs/08-distributed-systems/outbox/ - RabbitMQ: AMQP 0-9-1, маршрутизация, надёжность доставки и сравнение с Kafka: https://go.vbloher.org/docs/08-distributed-systems/rabbitmq/ - Ретраи: backoff, jitter, budgets и идемпотентность: https://go.vbloher.org/docs/08-distributed-systems/retries/ - Saga Pattern: https://go.vbloher.org/docs/08-distributed-systems/saga/ - Observability: https://go.vbloher.org/docs/09-observability/ - Grafana: https://go.vbloher.org/docs/09-observability/grafana/ - Метрики: RED, USE, Golden Signals: https://go.vbloher.org/docs/09-observability/metrics/ - OpenTelemetry: https://go.vbloher.org/docs/09-observability/opentelemetry/ - Prometheus: https://go.vbloher.org/docs/09-observability/prometheus/ - SLI / SLO / SLA: https://go.vbloher.org/docs/09-observability/slo-sli/ - Структурированное логирование (slog): https://go.vbloher.org/docs/09-observability/structured-logging/ - Distributed Tracing: https://go.vbloher.org/docs/09-observability/tracing/ - System Design: https://go.vbloher.org/docs/10-system-design/ - Analytics Pipeline: https://go.vbloher.org/docs/10-system-design/analytics-pipeline/ - Chat System: https://go.vbloher.org/docs/10-system-design/chat/ - Фреймворк System Design интервью: https://go.vbloher.org/docs/10-system-design/framework/ - Notification Service: https://go.vbloher.org/docs/10-system-design/notification-service/ - Order Service: https://go.vbloher.org/docs/10-system-design/order-service/ - Payment Service: https://go.vbloher.org/docs/10-system-design/payment-service/ - Rate Limiter: https://go.vbloher.org/docs/10-system-design/rate-limiter/ - URL Shortener: https://go.vbloher.org/docs/10-system-design/url-shortener/ - DevOps: https://go.vbloher.org/docs/11-devops/ - CI/CD: пайплайны, стадии, стратегии деплоя: https://go.vbloher.org/docs/11-devops/cicd/ - Облака (AWS / GCP) для бэкендера: https://go.vbloher.org/docs/11-devops/cloud-aws-gcp/ - Docker для Go-разработчика: https://go.vbloher.org/docs/11-devops/docker/ - GitHub Actions и GitLab CI: https://go.vbloher.org/docs/11-devops/github-gitlab-ci/ - Kubernetes для Go-разработчика: https://go.vbloher.org/docs/11-devops/kubernetes/ - Terraform / Infrastructure as Code: https://go.vbloher.org/docs/11-devops/terraform/ - Алгоритмы: https://go.vbloher.org/docs/12-algorithms/ - Типовые алгоритмические задачи и паттерны: https://go.vbloher.org/docs/12-algorithms/common-problems/ - Асимптотическая сложность (Big-O): https://go.vbloher.org/docs/12-algorithms/complexity/ - Структуры данных в Go: https://go.vbloher.org/docs/12-algorithms/data-structures/ - Специфика live-coding на Go: https://go.vbloher.org/docs/12-algorithms/go-specifics/ - Behavioral: https://go.vbloher.org/docs/13-behavioral/ - Конфликты, разногласия и работа со стейкхолдерами: https://go.vbloher.org/docs/13-behavioral/conflicts/ - Как проходит senior-интервью: этапы, оценка, оффер: https://go.vbloher.org/docs/13-behavioral/interview-flow/ - Лидерство и менторство: https://go.vbloher.org/docs/13-behavioral/leadership-mentoring/ - Типовые поведенческие вопросы для Senior: https://go.vbloher.org/docs/13-behavioral/senior-questions/ > Модуль: Алгоритмы · Уровень: Middle+/Senior ## TL;DR - Go аскетичен: из коробок — слайсы и map. Остальное (`container/list`, `container/ring`, `container/heap`) — в `container/*`, причём `heap` это **интерфейс над вашим слайсом**, а не готовый тип. - На live-coding 90% задач решаются **слайсом + map**. Stack/queue делаются на слайсе руками. Heap — через `container/heap`. - `linked list`, `tree`, `trie`, `graph` пишут вручную через структуры с указателями. Знать обходы и инварианты. - В Go 1.21+ есть `slices` и `maps` пакеты (generics) — `slices.Sort`, `slices.Contains`, `maps.Keys` и т.д. - Senior должен знать **сложности всех операций**, когда какая структура нужна, и подводные камни Go (shared backing array, nil map, random iteration). ## Теория ### Массивы и слайсы **Массив** `[N]T` — фиксированный размер, value-тип (копируется при передаче). Редко используется напрямую. **Слайс** `[]T` — header `{ptr, len, cap}` поверх массива; основная рабочая структура. ```go a := [3]int{1, 2, 3} // массив, размер часть типа s := []int{1, 2, 3} // слайс s = append(s, 4) // O(1) аморт. m := make([]int, 0, 100) // len=0, cap=100 — pre-allocation // Удаление элемента i (порядок не важен) — O(1): s[i] = s[len(s)-1] s = s[:len(s)-1] // Удаление с сохранением порядка — O(n): s = append(s[:i], s[i+1:]...) // или Go 1.21+: s = slices.Delete(s, i, i+1) ``` | Структура | Когда | Минусы | |---|---|---| | `[N]T` массив | фикс. размер, value-семантика | копирование, негибкость | | `[]T` слайс | почти всегда | shared backing, реаллокации | ### Hash map `map[K]V` — встроенная хеш-таблица. Ключ — любой comparable тип (нельзя слайс, map, функцию; можно struct из comparable полей, массив). ```go m := make(map[string]int) m["a"] = 1 v, ok := m["a"] // idiomatic check delete(m, "a") for k, v := range m { // ВНИМАНИЕ: порядок случайный _ = k; _ = v } // map как множество (set): set := make(map[string]struct{}) set["x"] = struct{}{} // struct{} занимает 0 байт _, exists := set["x"] ``` - Lookup/insert/delete — O(1) среднее. - **nil map** читать можно (вернёт zero value), писать — panic. `var m map[K]V` нужно инициализировать через `make`. - Итерация в **случайном порядке** (намеренно рандомизирована). Нужен порядок — собрать ключи в слайс и отсортировать. ### Linked list Однонаправленный/двунаправленный список. Вставка/удаление O(1) при наличии указателя; доступ по индексу O(n). Плохая cache locality. ```go type Node struct { Val int Next *Node } // Разворот списка — классика live-coding, O(n) время, O(1) память: func reverse(head *Node) *Node { var prev *Node for head != nil { head.Next, prev, head = prev, head, head.Next } return prev } ``` **`container/list`** — готовый двусвязный список (`*list.List`, `*list.Element`): ```go import "container/list" l := list.New() e := l.PushBack(10) // *list.Element l.PushFront(5) l.Remove(e) // O(1) for el := l.Front(); el != nil; el = el.Next() { _ = el.Value // interface{} / any — нет дженериков! } ``` Минус: `Value any` → накладные расходы и приведения типов. На практике редко нужен; чаще пишут свой типизированный список. ### Stack и Queue В Go нет отдельных типов — делают на слайсе. ```go // Stack (LIFO) на слайсе: var st []int st = append(st, 1) // push top := st[len(st)-1] // peek st = st[:len(st)-1] // pop // Queue (FIFO) на слайсе — простой вариант (O(1) аморт. amortized, но память течёт): var q []int q = append(q, 1) // enqueue front := q[0] // peek q = q[1:] // dequeue — backing array не освобождается! ``` Для долгоживущей очереди лучше **ring buffer** или `container/list`, чтобы не накапливать «голову» backing array. Для интервью слайс-вариант обычно ОК, но проговорите нюанс. ### Heap (`container/heap`) В stdlib нет готовой кучи — есть **интерфейс**, который вы реализуете над своим слайсом. Реализуете `heap.Interface` (= `sort.Interface` + `Push`/`Pop`). ```go import "container/heap" type IntHeap []int func (h IntHeap) Len() int { return len(h) } func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] } // min-heap func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } func (h *IntHeap) Push(x any) { *h = append(*h, x.(int)) } func (h *IntHeap) Pop() any { old := *h n := len(old) v := old[n-1] *h = old[:n-1] return v } func main() { h := &IntHeap{5, 2, 8} heap.Init(h) // O(n) heap.Push(h, 1) // O(log n) min := heap.Pop(h).(int) // O(log n), вернёт 1 _ = min } ``` - Push/Pop — O(log n), Init — O(n). - Для max-heap инвертируйте `Less` (`h[i] > h[j]`). - Применение: Dijkstra, top-K, merge K sorted lists, медиана потока. ### Tree Бинарное дерево / BST / сбалансированные (AVL, red-black). В stdlib готового дерева нет (внутри runtime/map есть, но не экспортирован). Пишут руками. ```go type TreeNode struct { Val int Left, Right *TreeNode } // In-order обход BST даёт отсортированную последовательность: func inorder(root *TreeNode, out *[]int) { if root == nil { return } inorder(root.Left, out) *out = append(*out, root.Val) inorder(root.Right, out) } ``` BST: search/insert/delete — O(h), где h высота; O(log n) для сбалансированного, O(n) для вырожденного. Обходы: pre/in/post-order (DFS) и level-order (BFS через очередь). ### Trie (префиксное дерево) Для префиксного поиска по строкам. Узел = карта/массив детей. ```go type Trie struct { children map[rune]*Trie end bool } func NewTrie() *Trie { return &Trie{children: map[rune]*Trie{}} } func (t *Trie) Insert(word string) { cur := t for _, r := range word { // range по строке даёт руны — важно! nxt, ok := cur.children[r] if !ok { nxt = NewTrie() cur.children[r] = nxt } cur = nxt } cur.end = true } func (t *Trie) Search(word string) bool { cur := t for _, r := range word { nxt, ok := cur.children[r] if !ok { return false } cur = nxt } return cur.end } ``` Search/Insert — O(len слова). Применение: автодополнение, словари, IP-роутинг. ### Graph Представления: - **Список смежности** `map[int][]int` или `[][]int` — для разреженных графов, O(V+E) памяти. - **Матрица смежности** `[][]bool` — для плотных, O(V²) памяти, O(1) проверка ребра. ```go type Graph struct { adj map[int][]int } func (g *Graph) AddEdge(u, v int) { g.adj[u] = append(g.adj[u], v) g.adj[v] = append(g.adj[v], u) // для неориентированного } // BFS — кратчайший путь по числу рёбер, O(V+E): func bfs(g *Graph, start int) []int { visited := map[int]bool{start: true} queue := []int{start} var order []int for len(queue) > 0 { node := queue[0] queue = queue[1:] order = append(order, node) for _, n := range g.adj[node] { if !visited[n] { visited[n] = true queue = append(queue, n) } } } return order } ``` ### Что есть в стандартной библиотеке (сводка) | Структура | В stdlib? | Пакет | |---|---|---| | Slice, Map | да, встроены | builtin | | Двусвязный список | да | `container/list` | | Кольцевой буфер | да | `container/ring` | | Heap (интерфейс) | да | `container/heap` | | Stack / Queue | нет | делать на слайсе | | Tree / BST | нет | вручную | | Trie | нет | вручную | | Graph | нет | вручную (map/slice) | | Set | нет | `map[T]struct{}` | | Утилиты для slice/map | да (1.21+) | `slices`, `maps` | **`container/ring`** — кольцевой список фиксированного размера, для циклических буферов: ```go import "container/ring" r := ring.New(3) // 3 элемента в кольце for i := 0; i < 3; i++ { r.Value = i r = r.Next() } r.Do(func(v any) { _ = v }) // обход всех ``` ## Подводные камни / gotchas - **Slice shared backing array** — `s[a:b]` разделяет память; `append` может затереть «соседей». Используйте `slices.Clone` для независимой копии. - **Queue через `q = q[1:]`** не освобождает голову backing array — память растёт в долгоживущей очереди. Для прод-кода — ring buffer или периодический re-slice с копированием. - **`container/heap` — это не тип, а интерфейс.** Частая ошибка кандидата: искать `heap.New()`. Нужно реализовать 5 методов, причём `Push`/`Pop` на указателе. - **`Push`/`Pop` у heap не вызывают напрямую** — это методы интерфейса; пользователь зовёт `heap.Push(h, x)` / `heap.Pop(h)`, которые поддерживают инвариант кучи. - **nil map panic при записи** — `var m map[K]V; m[k]=v` падает. Всегда `make`. - **`container/list` и `ring` хранят `any`** — нет дженериков, накладные расходы и runtime-приведения. В новом коде чаще свой типизированный вариант. - **range по строке даёт руны (rune), не байты** — важно для trie/строковых задач с UTF-8. `for i := range s` даёт байтовые индексы. - **map итерация рандомизирована** — нельзя полагаться на порядок; для детерминизма сортируйте ключи. ## Вопросы / задачи на собеседовании **В:** Как реализовать stack и queue в Go? **О:** Оба на слайсе. Stack: `append` для push, `s[:len-1]` для pop, `s[len-1]` для peek. Queue: `append` для enqueue, `q[0]` peek, `q[1:]` dequeue. Нюанс очереди — `q[1:]` не освобождает backing array, для долгоживущей очереди лучше ring buffer или `container/list`. **В:** Почему в Go нет готового Set? **О:** Идиома — `map[T]struct{}`. `struct{}` занимает 0 байт, так что это эффективно. `map[T]bool` тоже работает, но тратит память на значения и допускает неоднозначность (false vs отсутствие). **В:** Как использовать `container/heap`? Что нужно реализовать? **О:** Это интерфейс, не тип. Реализуете `heap.Interface`: `Len`, `Less` (определяет min/max), `Swap` (это sort.Interface) плюс `Push(any)` и `Pop() any` на указателе. Затем `heap.Init`, `heap.Push(h,x)`, `heap.Pop(h)`. Push/Pop — O(log n). **В:** Список смежности vs матрица смежности — когда что? **О:** Список (`map[int][]int` / `[][]int`) — для разреженных графов, память O(V+E), обход соседей эффективен. Матрица (`[][]bool`) — для плотных, O(V²) памяти, но O(1) проверка наличия ребра. На практике чаще список. **В:** В чём опасность slicing'а в Go? **О:** `b := a[i:j]` разделяет backing array с `a`. Мутации `b` видны в `a`; `append(b, x)` при наличии cap затрёт элементы `a`; маленький под-слайс удерживает весь большой массив в памяти. Решение — `slices.Clone(b)` или `append([]T(nil), b...)`. **В:** Как обойти дерево в ширину и в глубину? **О:** DFS — рекурсией (pre/in/post-order) или явным стеком; память O(h). BFS — очередью (level-order); память O(ширины уровня), даёт кратчайший путь по рёбрам в невзвешенном графе. **В:** Зачем нужен trie, если есть map? **О:** Trie даёт O(len) поиск по **префиксу** и перечисление всех слов с данным префиксом (автодополнение), чего map не умеет эффективно. Map даёт только точный lookup. Trie разделяет общие префиксы — экономит память на больших словарях с общими началами. ## На что копают на senior+ - Знание **точных сложностей** всех операций и умение выбрать структуру под задачу (top-K → heap, префиксы → trie, кратчайший путь → BFS/Dijkstra). - Понимание **memory layout**: cache locality слайса vs указательный связный список; почему слайс почти всегда быстрее на практике. - Реализация `container/heap` с нуля без подсказок, понимание sift-up/sift-down. - Подводные камни Go: shared backing array, nil map, random iteration, рост памяти у naive queue. - Когда брать stdlib (`container/list`, `heap`), а когда писать своё (типобезопасность, отсутствие boxing в `any`). - Альтернативные представления и trade-offs (graph: list vs matrix; set: map vs bitset для плотных целочисленных множеств).