Вопросы к собеседованию Flashcards
Как реализовано ООП в go?
В go нет классической реализация ООП, так как он не объектно-ориентированный язык. При этом в go есть свои приближения к этой реализации.
Наследование.
Наследование (англ. inheritance) — концепция объектно-ориентированного программирования, согласно которой абстрактный тип данных может наследовать данные и функциональность некоторого существующего типа, способствуя повторному использованию компонентов программного обеспечения.
У нас есть структуры - это специальные типы, в которые мы можем включать другие типы, в том числе такие же структуры. При этом методы дочерних структур родительская структура также будет наследовать.
Инкапсуляция
Инкапсуляция – сокрытие поведения объекта внутри него. Объекту «водитель» не нужно знать, что происходит в объекте «машина», чтобы она ехала.
Инкапсуляция в go - это возможность задавать переменным, функциям и методам первую букву названия в верхнем или нижнем регистре. Соответственно нижний регистр будет значить, что переменная, функция или метод доступна только в рамках пакета. Тогда как верхний регистр даст доступ к переменной, функции или методу за рамками пакета.
Полиморфизм
Полиморфизм — это способность объекта использовать методы производного класса, который не существует на момент создания базового.
Способность функции работать с данными разных типов.
Полиморфизм в go реализован с помощью интерфейсов.
Основная идея заключается в том, что мы можем объявить интерфейсы (контракты на определённое поведение) для наших типов. При этом, для типов мы должны реализовать методы, удовлетворяющие этим интерфейсам. Таким образом, мы сможем работать со всем набором типов, у которых реализовали интерфейсы, как с единым интерфейсным типом.
Что такое пакеты в go?
Пакет - это механизм переиспользования кода, при котором go файлы помещаются в общую директорию. В начале каждого такого файла объявляется зарезервированное слово package, а после него прописывается имя пакета. В рамках пакета все функции и глобальные переменные, объявленные как в верхнем, так и в нижнем регистре, видят друг друга.
Что такое глобальная переменная?
Глобальная переменная - это переменная уровня пакета, то есть объявленная вне функции. Глобальная переменная также может быть доступна за рамками пакета, конечно только в том случае, если ее наименование начинается в верхнем регистре.
Что такое фигурные скобки с не объявленным оператором в go функции?
В go функции действительно можно объявить{} без оператора, ограничив область видимости куска кода в рамках этой функции.
func main() { solder := "Bill"
{ solder := "Den" fmt.Println(solder) } fmt.Println(solder) }
В go есть оператор switch case, можно ли выполнить несколько условий в одном объявленном операторе?
Такое возможно благодаря ключевому слову fallthrough. Оно заставляет выполнять код в следующей объявленной булевой секции, вне зависимости подходит ли булевое условие case этой секции.
func main() { animals := []string{"bear", "bear", "rabbit", "wolf"}
for _, animal := range animals { switch animal { case "rabbit": fmt.Println(animal, "is so weak!") fallthrough
case "bear", "wolf": fmt.Println(animal, "is so strong!") } } }
bear is so strong! bear is so strong! rabbit is so weak! rabbit is so strong! wolf is so strong!
Что представляют из себя строки в go?
В Go строка в действительности является срезом (slice) байтов, доступным только для чтения.
type _string struct {
elements *byte // underlying bytes
len int // number of bytes
}
Как можно оперировать строками?
Строки в go можно складывать(конкатенировать). Для многих операций есть стандартные пакеты, к примеру strings, fmt. Кроме того, надо понимать, что все варианты конкатенации имеют свою производительность.
Что будет если сложить строки?
Ранее мы говорили о том что, строки - это массивы байт. Из этого следует, что при работе со строками (конкатенация и тд) мы будем получать новые строки
Как определить количество символов для строки? или Какие есть нюансы при итерации по строке?
Исходя из того же знания, что строка это массив байт, взяв базовую функцию len() от строки мы получим количество байт. Похожее поведение будет при итерации по строке - итерация по байтам. Тогда как в зависимости от кодировки, символ в строке может занимать не один байт.
Для того, чтобы работать именно с символами, необходимо преобразовать строку в тип []rune.
Еще одним способом определения длинны строки является функция RuneCountInString пакета utf8.
func main() { str := "世界, 你好!"
fmt.Printf("len bytes: %d\n", len(str)) fmt.Printf("len runes: %d\n", len([]rune(str))) fmt.Printf("len runes: %d\n", utf8.RuneCountInString(str)) }
В Go присутствует синтаксический сахар при обходе строки. Если использовать конструкцию for range, строка автоматически будет преобразована в []rune, то есть обход будет по Юникод символам
Какие численные типы есть в go?
int/int8/int16/int32/int64;
uint/uint8/uint16/uint32/uint64;
float32/float64;
complex64/complex128;
rune(int32).
Чем отличается int от uint?
int содержит диапазон от отрицательных значений до положительных, тогда как uint - это диапазон от 0 в строну увеличения положительных значений.
Пример: int64 это диапазон от –9 223 372 036 854 775 808 до 9 223 372 036 854 775 807 , uint64 от 0 до 18 446 744 073 709 551 615.
Что такое обычный int и какие есть нюансы его реализации?
В зависимости от того какая архитектура платформы, на которой мы стартуем, компилятор преобразует int в int32 для 32 разрядной архитектуры и в int64 для 64 разрядной архитектуры.
Как преобразовать строку в int и наоборот? Можно ли сделать int(string) и string(int) соответственно?
Преобразование типов между int и string указанным синтаксисом невозможно. Для преобразования необходимо использовать функции из пакета strconv стандартной библиотеки go.
При этом для преобразования строк в/из int и int64 используются разные функции, strconv.Atoi и strconv.Itoa для int, strconv.ParseInt и strconv.FormatInt соответственно.
Сколько в памяти занимают реализации int32 и int64?
В предыдущем вопросе мы отвечали сколько места в памяти занимают эти типы. Таким образом с помощью 4 или 8 байт можно закодировать разные по диапазону значения.
Для int64 это диапазон от –9 223 372 036 854 775 808 до 9 223 372 036 854 775 807, для int32 от –2 147 483 648 до 2 147 483 647.
Какой результат получим если разделить int на 0 и float на 0?
Это вопрос с подвохом. Деление int на 0 в go невозможно и вызовет ошибку компилятора. Тогда как деление float на 0 дает в своем результате бесконечность.
func main() { f := 500.0
fmt.Printf("float: %v\n", f/0) } float: +Inf
func main() { i := 500
fmt.Printf("int: %v\n", i/0) } division by zero
Что такое константы и можно ли их изменять?
Константы - это неизменяемые переменные, изменить константу нельзя.