Skip to content

Latest commit

 

History

History

golang

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

Вопросы по языку Golang

1. Что из себя представляет тип данных string в языке Golang? Можно ли изменить определенный символ в строке? Что происходит при склеивании строк?

Строка Go - это байтовый срез, предназначенный только для чтения, который может содержать байты любого типа и иметь произвольную длину. Строка неизменяемая и изменить определенный символ в конкретной строке нельзя. Создается новая строка (в простейшем случае).

2. Вытекающий вопрос — как эффективно склеивать множество строк?

Например, чтобы избавиться от лишних аллокаций, можно воспользоваться типом strings.Builder и методом WriteString:

 func join(strs ...string) string {
    var sb strings.Builder
    for _, str := range strs {
            sb.WriteString(str)
    }
    return sb.String()
 }

И никто не мешает пользоваться пакетом strings.

8. Как задать направление канала?

Мы можем задать направление передачи сообщений в канале, сделав его только отправляющим или принимающим. Например:

func f(c chan<- string)

и канал c будет только отправлять сообщение. Попытка получить сообщение из канала c вызовет ошибку компилирования. Также мы можем изменить функцию f:

func f(c <-chan string)

Существуют и двунаправленные каналы, которые могут быть переданы в функцию, принимающую только принимающие или отправляющие каналы. Но только отправляющие или принимающие каналы не могут быть переданы в функцию, требующую двунаправленного канала!

9. Напишите собственную функцию Sleep, используя time.After

func sleep(s int) {
  <- time.After(time.Second * time.Duration(s)):
}

10. Что такое буферизированный канал? Как создать такой канал с ёмкостью в 20 сообщений?

При инициализации канала можно использовать второй параметр:

c := make(chan int, 1)

и мы получим буферизированный канал с ёмкостью 1. Обычно каналы работают синхронно - каждая из сторон ждёт, когда другая сможет получить или передать сообщение. Но буферизованный канал работает асинхронно — получение или отправка сообщения не заставляют стороны останавливаться. Но канал теряет пропускную способность, когда он занят, в данном случае, если мы отправим в канал 1 сообщение, то мы не сможем отправить туда ещё одно до тех пор, пока первое не будет получено.

11. Напишите программу, которая меняет местами два числа (x := 1; y := 2; swap(&x, &y) должно дать x=2 и y=1)

func main()  {
	x := 1
	y := 2

	swap(&x, &y)

	fmt.Println(x, y)
}

func swap(x, y *int) {
	*x, *y = *y, *x
}

12. Какое будет значение у переменной x после выполнения программы?

func square(x *float64) {
	*x = *x * *x
}

func main() {
	x := 1.5
	square(&x)

	fmt.Println(x)
}
Ответ Ответ: 2.25

13. Какое значение примет выражение (true && false) || (false && true) || !(false && false)?

fmt.Println((true && false) || (false && true) || !(false && false))
Ответ Ответ: true

14. Мы знаем, что в десятичной системе самое большое число из одной цифры - это 9, а из двух - 99. В бинарной системе самое большое число из двух цифр это 11 (3), самое большое число из трех цифр это 111 (7) и самое большое число из 4 цифр это 1111 (15). Вопрос: каково самое большое число из 8 цифр?

Подсказка:

  1. 101 - 1 = 9, a 102 - 1 = 99 (Решение через знание степеней 2)
  2. 11110 это 15 * 2 = 30, а 111100 это 15 * 2 * 2 = 60 (Решение через битовый сдвиг)
Ответ Ответ: 255

15. Что выведет следующая программа?

package main

import "fmt"

func main() {
   i := 65
   fmt.Println(string(i))
}

Варианты:

  1. A
  2. 65
  3. Ошибка компиляции
  4. Нет правильного ответа
  5. Я не знаю
Ответ Ответ: А

16. Что выведет следующая программа?

package main

import "fmt"

func main() {
   a := [5]int{1, 2, 3, 4, 5}
   t := a[3:4:4]
   fmt.Prinln(t[0])
}

Варианты:

  1. 3
  2. 4
  3. Ошибка компиляции
  4. Нет правильного ответа
  5. Я не знаю
Ответ Ответ: 4

17.Как работает Garbage Collection в Go?

Garbage Collection - это процесс освобождения места в памяти, которое больше не используется. В документации указано следующее:

GC выполняется конкурентно (concurrent), одновременно с потоками мутатора (mutator), в точном соответствии с типом (этот принцип также известен как чувствительность к типу), допускается парааллельная выполнение нескольких потоков GC. Это конкурентная пометка и очистка (mark-sweep), при которой используется барьер записи (write barrier). При этом в процессе ничего не генерируется и не сжимается. Освобождение памяти выполняется на основе размера, выделенного для каждой программы Р, чтобы в общем случае минимизировать фрагментацию и избежать блокировок.

В основе работы GC Go лежит "трехцветный алгоритм". Официальное название "трехцветный алгоритм пометки и очистки". Использует барьер памяти. Главный принцип алгоритма трехцветной пометки и очистки состоит в разделении объектов, находящихся куче, на три набора, в соответствии с "цветом". Условно разделяются на 3 цвета:

  • черные объекты - гарантированно не имеют указателей на белые объекты;
  • серые объекты - могут иметь указатели на белые объекты;
  • белые объекты - на них могут ссылаться некоторые серые объекты и сами некоторые белые объекты могут ссылаться на некоторые черные. Краткий алгоритм:
  1. Все объекты сначала белые;
  2. Идет перебор "корневых" объектов, помечаются как серые. Корневые - это объекты к которым можно обращаться напрямую, например глобальные переменные, элементы в стеке и т.д.
  3. Идет перебор серых объектов, проверяются ссылки на другие объекты и помечаются на черные объекты. Если есть ссылка на белый объект, то белый становится серым.
  4. Продолжается до тех пор, пока не будут перебраны все серые объекты.
  5. Оставшиеся после перебора белые объекты считаются недостижимыми и занимаемая ими область памяти может быть освобождена. Есть еще Мутатор - это приложение, работающее во время сборки мусора. Вызывает функцию барьера записи. Выполняется каждый раз, когда меняется указатель в куче. После изменения указателя объект считается достижимым и помечается как серый.

18.Что такое interface, как они работают в Go?

// todo

19.Что такое slice, как устроены и чем отличаются от массивов?

// todo

20.Что такое len и capacity в slice Go?

// todo

21.Возможно ли предугадать, что GC отработает за константное время N?

// todo

22.Что будет, если создать канал и отправить туда запись, но у него нет читателей?

// todo