Вопросы для подготовки к собеседованию по Go на русском и английском

Как готовиться?
  1. Читаем на русском, затем на английском

Типы данных

Что такое Golang?
What is Golang?
Golang — это компилируемый многопоточный язык программирования, разработанный в Google в 2007–2009 годах Робертом Гризмером, Робом Пайком и Кеном Томпсоном для создания высокопроизводительных систем. Он сочетает простоту синтаксиса (как у Python) с производительностью C/C++, поддерживает конкурентность через горутины и применяется в серверных приложениях, облаках и DevOps


Golang is a compiled multithreaded programming language developed at Google in 2007-2009 by Robert Griesmer, Rob Pike and Ken Thompson to create high—performance systems. It combines the simplicity of the syntax (like Python) with the performance of C/C++, supports competitiveness through goroutines, and is used in server applications, clouds, and DevOps.

Как проверить версию Go?
How do I check the version of Go?
Проверка версии Go выполняется командой go version в терминале, которая выводит установленную версию, например, "go version go1.23.1 linux/amd64".

The Go version check is performed by the go version command in the terminal, which outputs the installed version, for example, "go version go1.23.1 linux/amd64".

Что такое GOPATH?
What is GOPATH?
GOPATH — это переменная окружения, указывающая директории для рабочих пространств: исходного кода (src), пакетов (pkg) и бинарников (bin); актуальна для проектов без модулей.

GOPATH is an environment variable that specifies directories for workspaces: source code (src), packages (pkg), and binaries (bin); relevant for projects without modules.


Что такое GOROOT?
What is GOROOT?
GOROOT — переменная, указывающая корневую директорию установки Go (бинарники, исходники stdlib); обычно задается автоматически и не требует ручной настройки.

GOROOT is a variable that specifies the root directory of the Go installation (binaries, stdlib sources); it is usually set automatically and does not require manual configuration.


Какие есть типы данные в Go?
What types of data are there in Go?
Типы данных в Go включают целые (int, uint и их вариации), с плавающей точкой (float32, float64), bool, string, byte (alias uint8), rune (alias int32), а также составные: массивы, срезы, мапы, каналы, структуры, указатели, функции, интерфейсы.

Data types in Go include integers (int, uint and their variations), floating-point (float32, float64), bool, string, byte (alias uint8), rune (alias int32), as well as composite ones: arrays, slices, maps, channels, structures, pointers, functions, interfaces.

Чем отличаются int, int8, int16, int32, int64?
What is the difference between int, int8, int16, int32, int64?
Они отличаются размером и диапазоном: int8 (8 бит, -128..127), int16 (16 бит, -32768..32767), int32 (32 бита), int64 (64 бита); все со знаком

They differ in size and range: int8 (8 bits, -128..127), int16 (16 bits, -32768..32767), int32 (32 bits), int64 (64 bits); all signed
От чего зависит размер типа int?
What determines the size of the int type?
Размер int зависит от архитектуры: 32 бита на 32-битных системах, 64 бита на 64-битных.

The size of an int depends on the architecture: 32 bits on 32-bit systems, 64 bits on 64-bit systems.
Что произойдёт при переполнении uint?
What happens when the uint overflows?
Переполнение uint приводит к обертыванию (wraparound): максимум+1 становится 0

Uint overflow leads to wrapping (wraparound): the maximum of +1 becomes 0
Какие проблемы возникают при приведении int64 к int на 32-битной системе?
What problems arise when converting int64 to int on a 32-bit system?
Приведение int64 к int на 32-битной системе обрезает старшие биты, вызывая потерю данных для |x| > 2^31-1

Uint overflow leads to wrapping (wraparound): the maximum of +1 becomes 0
Какие типы чисел с плавающей точкой есть в Go?
What types of floating point numbers are there in Go? (🔊)
Типы float — float32 (32 бита) и float64 (64 бита, по умолчанию).

Float types are float32 (32 bits) and float64 (64 bits, by default).
Почему нельзя сравнивать float значения через ==?
Why can't float values be compared using ==?
Сравнение float == ненадёжно из-за неточности представления (округления, машинный эпсилон).

Float comparison with equality operator (==) is unreliable due to inaccuracy of representation (rounding, machine epsilon).
Как корректно сравнивать float значения?
How can float values be compared correctly?
Правильно — сравнивать с допуском: math.Abs(a-b) ≤ epsilon, где epsilon примерно 1e-9.

That's right, compare with the tolerance: math.Abs(a-b) ≤ epsilon, where epsilon is approximately 1e-9.
Почему нельзя использовать float для денежных расчётов?
Why can't float be used for financial calculations?
Float не для денег — неточность binary floating-point приводит к ошибкам вроде 0.1+0.2 != 0.3; используйте decimal или int (копейки).

Float is not for money — the inaccuracy of binary floating-point leads to errors like 0.1+0.2 != 0.3; use decimal or int (pennies).
Что такое строка в Go и в какой кодировке она хранится?
What is a string in Go and in what encoding is it stored?
Строка в Go — неизменяемая последовательность байт в UTF-8.

A string in Go is an immutable sequence of bytes in UTF-8.
В чём разница между len(s) и количеством символов в строке?
What is the difference between len(s) and the number of characters in a string?
len(s) vs символы — len возвращает байты, а не руны (символы); для кириллицы (2+ байта) len > utf8.RuneCountInString(s).

len(s) vs characters — len returns bytes, not runes (characters); for Cyrillic (2+ bytes) len > utf8.RuneCountInString(s).
Что такое rune (руна)?
What is rune?
Rune — int32 для Unicode code point (символ); []rune(s) декодирует UTF-8

Rune — int32 for Unicode code point (character); []rune(s) decodes UTF-8
Что такое zero value в Go?
What is zero value in Go?
Zero value — значение по умолчанию для инициализированных переменных.

Zero value is the default value for initialized variables.
Какие zero value (нулевые значения) у int, float, bool, string?
What is the zero value - int, float, bool, string?
Нулевые значения: int — 0, float — 0.0, bool — false, string — "".

Zero values: Int is zero, float is zero point zero, boolean is false, string is empty double quotes
Почему строки в Go неизменяемы?
Why are strings immutable in Go?
Строки неизменяемы, чтобы обеспечить безопасность потоков и неизменность в структурах без копирования

Strings are immutable to ensure thread safety and immutability in structures without copying.
Как получить корректно первый символ строки, если там содержится кириллица или иероглифы?
How do I get the first character of a string correctly if it contains Cyrillic or hieroglyphs?
Нужно преобразовать строку в срез рун и взять индекс 0
fmt.Printf("%c\n", []rune("Коля")[0])
или пройтись по строке циклом for range и выйти после первой итерации
word2 := "你好"
for _, r := range word2 {
fmt.Printf("%c\n", r)
break
}

You need to convert the string to a rune slice and take the element at index0 or iterate through the string with a for range loop and exit after the first iteration.

Сколько памяти занимает тип bool в Go и почему именно столько?
How much memory does the bool type take up in Go and why exactly that much?
bool занимает 1 байт (не 1 бит) для выравнивания памяти в структурах (padding)

bool takes 1 byte (not 1 bit) for memory alignment in structures (padding)

Что выведет код?
What is the output of the code?
Будет ошибка компилляции "cannot assign to s[0]", потому что строки неизменяемы.

There will be a compilation error "cannot assign to s[0]" because strings are immutable.

Какие есть проблемы? Как решить? (см. код)
What are the problems? How to solve them?
Есть три проблемы:
1. строки в Go неизменяемы, поэтому на каждой итерации создаётся новая строка, поэтому память расходуется неэффективно. Решение - использовать strings.Builder
2. число с точкой выглядит как float, для счетчика нужен int. Решение - убрать точку или использовать _(нижнее подчеркивание)
3. преобразование числа в строку через fmt.Sprintf("%d", i) медленнее, чем прямые методы (strconv.Itoa). Решение - использовать strconv.Itoa

финальный код

There are three problems:
1. Strings in Go are immutable, so a new string is created at each iteration, so memory is used inefficiently. The solution is to use strings.Builder
2. A number with a dot looks like a float, but an int is needed for the counter. The solution is to remove the dot or use _(underline)
3. Converting a number to a string using fmt.Sprintf("%d", i) is slower than direct methods (strconv.Itoa). The solution is to use strconv.Itoa

Что выведет код и почему?
What is the output of the code?
Код выведет
Длина через Len: 8
Длина через RuneCountInString: 5
Потому что в Go строка — это последовательность байт в UTF‑8, и len(str) считает байты, а не символы, в кириллице одна буква зачастую представлена двумя байтами. utf8.RuneCountInString считает руны (Unicode‑символы) и даёт их реальное количество

The code will output
Length via Len: 8
Length via RuneCountInString: 5

Because in Go, a string is a sequence of bytes in UTF—8, and len(str) counts bytes rather than characters, in Cyrillic, one letter is often represented by two bytes. utf8.RuneCountInString counts runes (Unicode characters) and gives their real number

Какие есть проблемы? Как решить? (см. код)
What are the problems? How to solve them?
Проблема в том, что цикл for выведет обходит строку по байтово, а эмодзи занимает несколько байтов. Корректнее использовать range.

финальный код

The problem is that the for loop outputs a byte-by-byte traversal of the string, while the emoji takes up several bytes. It is more correct to use range.

Типы данных: map

вопросы на собеседовании
Что такое map в Go и как устроен внутри?
What is a map in Go and how does it work inside?
Map — встроенная хеш-таблица, хранящая пары ключ-значение. Внутри реализована с помощью массива бакетов и хеш-функции.

Map is an embedded hash table that stores key-value pairs. It is implemented internally using an array of buckets and a hash function.

Какие типы можно использовать в качестве ключей?
What types can be used as keys?
Comparable-типы: числа, строки, указатели, структуры с comparable-полями.

Comparable types: numbers, strings, pointers, structures with comparable fields.

Почему нельзя использовать слайсы, функции или другие map в качестве ключей?
Why can't you use slices, functions, or other maps as keys?
Эти типы несравнимы (== не определён), а map требует операции сравнения для проверки уникальности ключей.

These types are not comparable (equality check is undefined), but a map requires comparison operation to ensure the uniqueness of keys.

Потокобезопасна ли map?
Is the map thread-safe?
Нет. Для безопасного конкурентного доступа используются Mutex или sync.Map.

No. Mutex or sync.Map are used for secure competitive access.

Что произойдёт, если несколько горутин одновременно запишут в map без синхронизации?
What will happen if several goroutines write to a map simultaneously without synchronization?
Рантайм детектирует гонку и вызовет panic «fatal error: concurrent map writes»

The runtime detects the race condition and will trigger a panic with the message «fatal error: concurrent map writes».

Как проверить наличие ключа?
How do I check the availability of the key?
Через второй возвращаемый параметр: value, ok := m[key]

Through the second returned parameter: value, ok := m[key]

Как удалить элемент из map?
How do I delete an element from a map?
Через функцию delete: delete(m,key)

Using the delete function: delete(m,key)

Есть ли гарантированный порядок перебора элементов map? Почему?
Is there a guaranteed order of iterating through the map elements? Why?
Нет, так как позиция зависит от хеша ключа, и Go специально изменяет порядок для защиты от атак (hash-flooding).

No, because the position depends on the hash of the key, and Go specifically changes the order to protect against attacks (hash-flooding).

Как происходит эвакуация данных в map при расширении?
How does data evacuation in a map occur during expansion?
При превышении порога (в среднем 6.5 элементов на бакет), Go инкрементально переносит элементы в новый массив бакетов удвоенного размера.

When the threshold is exceeded (on average 6.5 elements per bucket), Go incrementally transfers items to a new bucket array of twice the size.

Какая сложность операций добавления, удаления и поиска в map?
What is the time complexity of insert, delete, and lookup operations in a Go map?
В среднем O(1). ("о" от одного)

The average time complexity is O of one

Можно ли взять адрес элемента map? Почему?
Is it possible to get a pointer to a map element in Go? Explain why.
Нет, так как элементы могут перемещаться во время эвакуации и адрес не постоянен.

No. Map elements may move during evacuation, so their address isn’t fixed.
Что такое set и как реализовать его в Go?
What is a set, and how can it be implemented in Go?
Set — структура, хранящая только уникальные элементы. В Go обычно реализуют как map[K]struct{}: уникальность обеспечивается ключами, а «пустая» структура (struct{}) не занимает памяти.

A set is a data structure that stores only unique elements. In Go, it is typically implemented as
map[K]struct{} (map, then K in square brackets, then struct in empty curly brackets),
uniqueness is ensured by the keys, and the empty struct consumes no memory.
Как создать nil-map?
How do I create a nil map?
var m map[string]int

var m, map string to int
Можно ли добавить ключ в nil-map? Что произойдет?
Is it possible to add a key to the nil-map? What's going to happen?
Нельзя. Если попытаться присвоить значение по ключу в nil-map, будет паника panic: assignment to entry in nil map. Чтобы добавить ключ, map нужно сначала инициализировать через make.

You can’t do that. If you try to set a key in a nil map, Go will panic. Remember to initialize a map before you add any keys.

example:
m := make(map[string]int) // em is make map string int
m["key"] = 1 //em of key equals 1
Что выведет и почему? (см. код)
What will this output, and why?
Выведет пары ключ-значение a 1, b 2, c 3 в случайном порядке (например, b 2, a 1, c 3).
Почему: итерация по map через range не гарантирует порядок — Go рандомизирует порядок ключей для предотвращения зависимости от порядка вставки.

Outputs the key-value pairs a1, b2, c3 in random order (for example, b2, a1, c3).
Why: iterating over the map via range does not guarantee order — Go randomizes the order of keys to prevent dependency on insertion order.
Что выведет и почему? (см. код)
What will this output, and why?
Выведет 20. Сохраняем указатель на v в map. Когда меняем v = 20, значение по тому же адресу меняется. Разыменовка *m[1] видит обновлённое значение.

It prints twenty. We store a pointer to v in the map. When we do v equals twenty, it changes the value at that memory address. Dereferencing m of one shows the updated value
Что выведет и почему? (см. код)
What will this output, and why?
Выведет 10. Берём указатель на значение map ptr := &m[1], но потом не используем его. fmt.Println(m[1]) читает напрямую из map, где значение осталось 10

It prints ten. We create a pointer to m of one, but then we don't use that pointer. Println m of one reads directly from the map, where the value is still ten
Программа выведет: Количество слов: map[apple:2 banana:2 grape:1 kiwi:1 orange:1]
Мапа просто соберет все уникальные слова и их количество, проигнорировав лимит.

Чтобы решить задачу:
  1. В структуру WordCounter добавляем слайс order []string.
  2. Когда добавляем новое слово:
  • Если слова еще нет в мапе — добавляем его в конец слайса order.
  • Если лимит превышен — берем первый элемент из слайса order (самый старый), удаляем его из мапы и из слайса.

Решение

To solve the problem:
We add the order []string slice to the WordCounter structure.
When adding a new word:
If the word is not in the map yet, add it to the end of the order slice.
If the limit is exceeded, we take the first element from the order slice (the oldest), remove it from the map and from the slice.

Типы данных: array, slice
Вопросы на собеседовании
Что такое массив (array)?
What is array?
Массив — это структура фиксированной длины, которая хранит элементы одного типа. Размер массива определяется при его создании и не может быть изменён позже.

var arr [3]int // массив на 3 элемента типа int
arr[0] = 10
Длина массива — часть типа, [3]int и [5]int — разные типы.

Размер массива нельзя изменить после создания.

An array is a fixed—length structure that stores elements of the same type. The size of the array is determined when it is created and cannot be changed later.

var arr [3]int // an array of 3 elements of type int
arr[0] = 10
The length of the array is part of the type, [3]int and [5]int are different types.

The size of the array cannot be changed after creation.
Что такое слайс (slice)?
What is slice?
Слайс — это структура данных, которая дает удобный интерфейс для работы с динамическими массивами. Под капотом слайс хранит указатель на массив, текущую длину (len) и ёмкость (cap). В отличие от массивов, размер слайса может изменяться.

type slice struct {
  array unsafe.Pointer // указатель на массив данных
  len  int      // текущая длина слайса
  cap  int      // ёмкость (вместимость) слайса
}

A slice is a data structure that provides a user—friendly interface for working with dynamic arrays. Under the hood, the slice stores a pointer to an array, the current length (len) and capacity (cap). Unlike arrays, the slice size can vary.
Чем отличается слайс от массива?
What is the difference between a slice and an array?
Массив имеет фиксированную длину и передаётся по значению (копируется полностью), слайс имеет динамическую длину и передаётся по ссылке (копируется только структура, содержащая указатель).

The array has a fixed length and is passed by value (copied in full), the slice has a dynamic length and is passed by reference (only the structure containing the pointer is copied).
Что такое len и cap в слайсе?
What is the len and cap in slice?
len — количество текущих элементов в слайсе,
cap — общая вместимость слайса, т.е. сколько элементов можно хранить без выделения дополнительной памяти.

len is the number of current items in the slice
cap is the total capacity of the slice, i.e. how many items can be stored without allocating additional memory.
Как создать пустой слайс?
How do I create an empty slice?
Пустой слайс в Go создаётся тремя способами: var s []int (nil-слайс), s := []int{} или make([]int, 0) (не-nil, но len=0). Оба подходят для append, но nil равен nil, пустой — нет

In Go, you create an empty slice in three ways: var s []int for a nil slice, or s := []int{} or make([]int, 0) for a non-nil one with len=0. Both work fine with append, but only the nil slice equals nil— the empty one doesn't
Как работает append()?
How does append() work?
Функция append() добавляет элементы в слайс:
s := []int{1, 2, 3}
s = append(s, 4) // [1,2,3,4]
1. Если в слайсе хватает ёмкости (cap), элемент добавляется сразу.
2. Если места нет, создаётся новый массив большего размера, старые элементы копируются туда, а затем добавляется новый элемент.

The append() function adds elements to the slice
1. If the slice has enough capacity (cap), the element is added immediately.
2. If there is no space, a new larger array is created, the old elements are copied there, and then a new element is added.
Почему изменение элементов слайса влияет на исходный массив?
Why does changing the slice elements affect the original array?
Слайс является ссылкой на базовый массив. Поэтому изменения через слайс влияют на элементы исходного массива.

The slice is a reference to the base array. Therefore, changes through the slice affect the elements of the original array.
Можно ли сравнивать слайсы оператором ==?
Is it possible to compare slices with the equals-equals operator?
Слайсы сравниваемы только с nil, между собой — нет, будет ошибка slice can only be compared to nil.

Slices can only be compared to nil, but not to each other, there will be an error slice can only be compared to nil.
Чем make([]T, len) отличается от make([]T, len, cap)?
How does make([]T, len) differ from make([]T, len, cap)??
make([]T, len) создаёт слайс с емкостью len и длиной len, где все элементы инициализируются zero-value от типа данных T

make([]T, len, cap) создаёт слайс с емкостью cap и длиной len, где элементы до len заполняются zero-value.

Если попытаться взять элемент за пределами len, но внутри cap, будет паника: попытка обратиться к области за пределами памяти.
Например:
s := make([]int, 2, 5)
fmt.Println(s, len(s), cap(s)) // [0, 0], 2, 5
fmt.Println(s[3]) // panic: index out of range [3] with lenght 2


make([]T, len) creates a slice with a capacity of len and a length of len, where all elements are initialized to zero-value from the data type T

make([]T, len, cap) creates a slice with a cap capacity and a length of len, where the elements up to len are filled with zero-value.

If you try to take an element outside of len, but inside cap, there will be a panic: an attempt to access an area outside of memory.
Что является нулевым значением (zero value) для массива и для слайса?
What is the zero value for an array and for a slice?
Для массива — нулевое значение типа данных значений этого массива, так как при объявлении сразу выделяется память

Для слайса — нулевое значение nil, которые не имеет указателя на базовый массив.

For an array, the value of the data type of the values of this array is zero, since memory is immediately allocated during the declaration.

For a slice, the nil value is zero, which does not have a pointer to the base array.
Как работает `copy(dst, src)` ?
How does `copy(dst, src)` work?
Функция безопасного копирования слайсов. Синтаксис выглядит как copy(куда скопировать, откуда скопировать), возвращает int-значение, как количество скопированных элементов

Под капотом мутирует слайс, обращаясь только к индексам слайсов, без append. Из этого следует, что если len(dst) < len(src), в dst скопируется столько элементов из src, насколько хватает len(dst).


The function of safely copying slices. The syntax looks like copy (where to copy, from where to copy), returns an int value as the number of copied elements.

Under the hood, the slice is mutated, referring only to the slice indexes, without append. It follows that if len(dst) < len(src), as many elements from src as len(dst) are copied to dst.
Типы данных: struct
Вопросы на собеседовании
Что такое struct в Go?
What is struct in Go?
Композитный тип, объединяющий несколько полей потенциально разных типов. Хранится в памяти как сплошной блок с выравниванием под каждое поле.

A composite type that combines several fields of potentially different types. It is stored in memory as a solid block with alignment for each field.
Чем отличаются вложенная и embedded-структуры?
What is the difference between nested struct and embedded struct?
Вложенная — обычное поле; embedded — анонимное поле, его методы/поля «промотируются».

Nested is an ordinary field; embedded is an anonymous field, its methods/fields are "promoted".
Почему порядок полей влияет на размер?
Why does the order of the fields affect the size?
Из-за выравнивания

Because of the alignment
Можно ли сравнивать структуры?
Is it possible to compare structs?
Да, если все поля сравнимы (==), иначе компилятор запретит

Yes, if all fields are comparable (==), otherwise the compiler will prohibit
Чем отличаются методы с value receiver и pointer receiver?
What is the difference between value receiver and pointer receiver methods?
Методы с value receiver работают с копией значения, поэтому изменения не влияют на исходный объект. Методы с pointer receiver получают указатель на значение, что позволяет изменять его состояние и избегать копирования.

Methods with the value receiver work with a copy of the value, so changes do not affect the original object. Methods with pointer receiver receive a pointer to the value, which allows you to change its state and avoid copying.

Когда обязательно использовать pointer receiver?
When is it mandatory to use the pointer receiver?
Когда нужно менять состояние или избежать копирования, а также если этого требует интерфейс.

When you need to change the state or avoid copying, as well as if the interface requires it.
Можно ли использовать структуру как ключ в map?
Is it possible to use a struct as a key in a map?
Да, если поля структуры можно сравнивать

Yes, if the fields of the struct can be compared
Что такое теги структур?
What are struct tags?
Мета-данные, которые позволяют ассоциировать поля структуры при кодировании для их обработки другим кодом.

Meta-data that allows you to associate the fields of a structure during encoding for their processing by other code.
Что делает omitempty?
What does omitempty do?
Не включает в сериализацию поле, если оно не инициализировано и является zero-value

Does not include a field in serialization if it is not initialized and is zero-value.
Чем json:"-" отличается от omitempty?
How does json:"-" differ from omitempty?
"-" полностью исключает из сериализации поле

"-"(hyphen) completely excludes the field from serialization
Можно ли использовать несколько тегов для одного поля?
Is it possible to use multiple tags for a single field?
Можно, например для json, db

It is possible, for example, for json, db
Типы данных: interface
Вопросы на собеседовании
Что такое интерфейс в Go?
What is interface in Go?
Интерфейс в Go — это тип, определяющий множество методов (без реализации). Тип реализует интерфейс неявно, если имеет все его методы

An interface in Go is a type that defines many methods (without an implementation). A type implements an interface implicitly if it has all its methods.
Зачем нужны интерфейсы?
Why do we need interfaces?
Интерфейсы дают полиморфизм без наследования, инверсию зависимостей и моки для тестов.

Interfaces provide polymorphism without inheritance, dependency inversion, and mock tests.
Как тип реализует интерфейс?
How does the type implement the interface?
Реализация автоматическая: если у типа есть все методы интерфейса — он его реализует. Явного implements нет

The implementation is automatic: if the type has all the interface methods, it implements it. There are no explicit implements
Может ли тип реализовать несколько интерфейсов?
Can a type implement multiple interfaces?
Тип реализует все интерфейсы сразу. Количество не ограничено

The type implements all interfaces at once. The quantity is unlimited
Что такое полиморфизм в Go?
What is polymorphism in Go?
Полиморфизм в Go — это когда одна функция работает с разными типами через интерфейсы.

Polymorphism in Go is when one function works with different types through interfaces.
Чем пустой интерфейс (any) отличается от обычного?
Чем пустой интерфейс (any) отличается от обычного?
У него 0 методов, поэтому любой тип его реализует; потеря статической типизации → нужны type assertion/switch.

It has 0 methods, so any type implements it; loss of static typing → type assertion/switch are needed.
Что такое zero value для интерфейса?
What is zero value for an interface?
Интерфейс nil — это пустая пара (тип=nil, значение=nil). Методы на nil-интерфейсе вызовутся с nil-получателем

The nil interface is an empty pair (type=nil, value=nil). Methods on the nil interface will be invoked with a nil recipient.
Можно ли сравнивать интерфейсы оператором ==?
Is it possible to compare interfaces using the == (equals equals) operator?
В Go интерфейсные значения можно сравнивать оператором ==, но только если их динамические типы сравнимы. Если внутри интерфейса несравнимый тип (например, срез или map), сравнение == приведёт к panic.

In Go, interface values can be compared with the == operator, but only if their dynamic types are comparable. If there is an incomparable type inside the interface (for example, slice or map), comparing == will lead to panic.
Что находится внутри интерфейса в рантайме?
What is inside the interface in runtime?
Два слова: data (указатель на значение) и itab (указатели на методы + тип).

Two words: data (pointer to value) and itab (pointers to methods + type).
Что такое type assertion?
What is type assertion?
Type assertion в Go — извлечение конкретного типа из интерфейса.
value, ok := interfaceValue.(ConcreteType)
- ok == true → значение извлечено;
- ok == false → тип не совпал.
для множества типов — type switch.


Type assertion in Go is the extraction of a specific type from an interface.value, ok := interfaceValue.(ConcreteType)- ok == true → value extracted; - ok == false → the type did not match.for multiple types — type switch.
Что такое type assertion?
What is type assertion?
Type switch — это switch i.(type), где проверяем тип интерфейса и в каждом case получаем значение нужного типа. Альтернатива цепочке if v, ok := i.(T)

Type switch is switch i.(type), where we check the type of interface and in each case get the value of the type we need. Is an alternative to if v, ok := i.(T)
Можно ли изменить набор методов интерфейса во время выполнения?
Is it possible to change the set of interface methods at runtime?
Интерфейсы — это статическая структура, определяемая на этапе компиляции. Набор методов фиксирован в типе и не изменяется в runtime

Interfaces are a static structure defined at the compilation stage. The set of methods is fixed in the type and does not change in runtime.
Указатели в Go
Вопросы на собеседовании
Сколько весит указатель?
How much does the pointer weigh?
Одно машинное слово:8 байт на 64-bit,  4 байта на 32-bit.

One machine word:8 bytes for 64-bit, 4 bytes for 32-bit.
Как получить адрес переменной?
How do I get the address of a variable?
Адрес переменной берём через амперсанд — &x.

x := 42
p := &x
fmt.Println(p) // 0xc0000140a8 (адрес)

You get the address with ampersand — &x.
Как разыменовать указатель?
How can I dereference a pointer?
Разыменовываем звёздочкой — *p. Берём значение по адресу p

You dereference with star — *p. That gets the value at address p
Что будет при разыменовании nil?
What happens when nil is dereferenced?
panic: runtime error — nil pointer dereference.
Ошибки и defer в Go
Вопросы на собеседовании
Как возвращают ошибки?
How are errors returned?
Функции возвращают (результат, error). Проверяем if err != nil. Ошибка — обычное значение, а не исключение.

The functions return (result, error). Checking if err != nil. An error is a common value, not an exception.
Что такое интерфейс error?
What is the Error Interface? 
Это простейший интерфейс с одним методом: Error() string

This is the simplest interface with one method: Error() string
Когда использовать panic?
When to use panic?
panic — для фатальных ошибок, которые программа не может обработать. Обычные ошибки — через error

panic — for fatal errors that the program cannot handle. Common errors — via error
Как работает defer?
How does defer work?
defer откладывает выполнение функции до выхода из текущей функции. Выполняется в обратном порядке (LIFO — стек).

defer postpones the execution of a function until the current function exits. It is executed in reverse order (LIFO stack).
Что делает recover?
What does recover do?
Функция recover() перехватывает панику внутри функции, объявленной с defer, и превращает её в обычное значение вместо аварийного завершения программы.

The recover() function intercepts the panic inside the function declared with defer and turns it into a normal value instead of an emergency program termination.
Можно ли recover без defer?
Is it possible to recover without defer?
Нет. recover() работает только в контексте функции, отложенной через defer в той же горутине, где произошла паника. Она перехватывает панику, предотвращая аварийное завершение и возвращая значение, переданное в panic().

No. recover() only works in the context of a function deferred via defer in the same goroutine where the panic occurred. It intercepts the panic, preventing an emergency shutdown and returning the value passed to panic().