21 вопросов
Фундамент языка Go: типы данных, переменные, константы, операторы и zero values. Эти знания необходимы для написания любой программы на Go и часто встречаются на собеседованиях.
string? 🟢 Лёгкий
▶
Каждый тип в Go имеет zero value - значение по умолчанию при объявлении переменной без инициализации. Для string это пустая строка "", не nil (строка - не указатель).
Подробнее →fmt.Println(1 + "1")? 🟢 Лёгкий
▶
Go - строго типизированный язык. Нельзя складывать int и string без явного приведения типов. В отличие от JavaScript или Python, Go не выполняет неявных преобразований.
Подробнее →Константы объявляются ключевым словом const. В Go нет let (это JavaScript), define (это C/препроцессор). var объявляет переменную, а не константу.
Подробнее →bool? 🟢 Лёгкий
▶
Zero value для bool - false. Для числовых типов - 0, для строк - "", для указателей - nil.
Подробнее →int? 🟢 Лёгкий
▶
Числовые типы (int, float64, uint и т.д.) имеют zero value равный 0. Не nil (это для указателей, каналов, слайсов, map, интерфейсов).
Подробнее →*int? 🟢 Лёгкий
▶
Указатели, слайсы, map, каналы, интерфейсы и функции имеют zero value равный nil. Указатель *int - не сам int, а ссылка на него, поэтому по умолчанию он nil, а не 0.
Подробнее →Оператор := - короткое объявление переменной. Go автоматически определяет тип по правой части. Можно использовать только внутри функций, не на уровне пакета.
Подробнее →:= на уровне пакета? 🟢 Лёгкий
▶
Оператор := работает только внутри функций. На уровне пакета используется var x = 5 или var x int = 5. Это ограничение синтаксиса Go.
Подробнее →fmt.Println(true && false)? 🟢 Лёгкий
▶
Оператор && - логическое И. Результат true только когда оба операнда true. true && false = false. Go выводит булевы значения как true/false, не как 1/0.
Подробнее →3.14 без явного указания? 🟢 Лёгкий
▶
Go использует float64 как тип по умолчанию для дробных литералов. Если нужен float32, его надо указать явно: var x float32 = 3.14. Типов double и decimal в Go нет.
Подробнее →Blank identifier _ используется, чтобы игнорировать значение. Например: _, err := someFunc() - первое возвращаемое значение игнорируется. Go не позволяет объявлять неиспользуемые переменные, поэтому _ необходим.
Подробнее →uint8? 🟢 Лёгкий
▶
uint8 - беззнаковое 8-битное целое. Диапазон: 0–255 (2⁸ − 1). Тип int8 (знаковый) имеет диапазон −128–127. byte - это алиас для uint8.
Подробнее →min(3, 1, 4, 1, 5) (Go 1.21+)? 🟢 Лёгкий
▶
С Go 1.21 min и max - встроенные функции, принимающие переменное число аргументов любого упорядоченного типа. min(3, 1, 4, 1, 5) = 1. Работают с int, float64, string. Больше не нужна math.Min для целых чисел.
Подробнее →import _ "github.com/lib/pq"? 🟢 Лёгкий
▶
Blank import (_) выполняет init() пакета без доступа к его именам. Драйверы БД регистрируют себя в init() через sql.Register. Без blank import Go не скомпилирует код с неиспользуемым импортом. Это стандартный способ подключения драйверов database/sql.
Подробнее →fmt.Println(len("Привет"))? 🟡 Средний
▶
Функция len() для строк возвращает количество байт, а не символов. Строки в Go - последовательности байт в UTF-8. Каждая кириллическая буква - 2 байта, поэтому "Привет" (6 букв) = 12 байт.
Подробнее →fmt.Println(010)? 🟡 Средний
▶
Литерал 010 - это восьмеричное число (префикс 0). В восьмеричной системе 10 = 1×8 + 0 = 8 в десятичной. Аналогично: 0x10 = 16 (шестнадцатеричное), 0b10 = 2 (двоичное).
Подробнее →x := 5; x, y := 10, 20; fmt.Println(x, y)? 🟡 Средний
▶
Во второй строке := допустим, потому что y - новая переменная. При этом x просто переприсваивается (не создаётся заново). Правило: в := хотя бы одна переменная должна быть новой.
Подробнее →x := 1; if true { x := 2; _ = x }; fmt.Println(x)? 🟡 Средний
▶
Оператор := внутри блока if создаёт новую переменную x, которая затеняет (shadow) внешнюю. Внешняя x остаётся равной 1. Это частая ошибка при обработке ошибок - вместо := нужно использовать = для присваивания существующей переменной.
Подробнее →fallthrough в switch? 🟡 Средний
▶
В Go, в отличие от C, switch не проваливается автоматически - после выполнения case он завершается. fallthrough принудительно переходит к следующему case без проверки его условия. Используется редко, но иногда нужно для последовательной обработки.
Подробнее →В одном файле может быть несколько init(). Все вызываются автоматически при инициализации пакета, в порядке появления в файле. init() нельзя вызвать явно. Порядок между файлами - алфавитный. init() вызывается после инициализации глобальных переменных пакета.
Подробнее →const x = 1 << 100; fmt.Println(x)? 🔴 Сложный
▶
Нетипизированные константы в Go имеют произвольную точность - объявление const x = 1 << 100 корректно. Но при передаче в fmt.Println() Go пытается привести x к типу int по умолчанию. Значение не помещается в int64, и компилятор выдаёт ошибку overflow.
Подробнее →