mirror of
https://github.com/goavengers/go-interview.git
synced 2026-02-04 12:46:20 +00:00
Fix GitHub Markdown Rendering
This commit is contained in:
186
docs/golang/README.md
Normal file
186
docs/golang/README.md
Normal file
@@ -0,0 +1,186 @@
|
||||
## <a name="golang_questions"></a> Вопросы по языку Golang
|
||||
|
||||
### <a name="1"></a> 1. Что из себя представляет тип данных string в языке Golang? Можно ли изменить определенный символ в строке? Что происходит при склеивании строк?
|
||||
|
||||
Строка Go - это байтовый срез, предназначенный только для чтения, который может содержать байты любого типа и иметь произвольную длину. Строка неизменяемая и изменить определенный символ в конкретной строке нельзя. Создается новая строка (в простейшем случае).
|
||||
|
||||
### <a name="2"></a> 2. Вытекающий вопрос — как эффективно склеивать множество строк?
|
||||
|
||||
Например, чтобы избавиться от лишних аллокаций, можно воспользоваться типом strings.Builder и методом WriteString:
|
||||
```go
|
||||
func join(strs ...string) string {
|
||||
var sb strings.Builder
|
||||
for _, str := range strs {
|
||||
sb.WriteString(str)
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
```
|
||||
И никто не мешает пользоваться пакетом strings.
|
||||
|
||||
### <a name="8"></a> 8. Как задать направление канала?
|
||||
|
||||
Мы можем задать направление передачи сообщений в канале, сделав его только отправляющим или принимающим. Например:
|
||||
|
||||
```go
|
||||
func f(c chan<- string)
|
||||
```
|
||||
|
||||
и канал `c` будет только отправлять сообщение. Попытка получить сообщение из канала c вызовет ошибку компилирования. Также мы можем изменить функцию `f`:
|
||||
|
||||
```go
|
||||
func f(c <-chan string)
|
||||
```
|
||||
|
||||
Существуют и двунаправленные каналы, которые могут быть переданы в функцию, принимающую только принимающие или отправляющие каналы. Но только отправляющие или принимающие каналы не могут быть переданы в функцию, требующую двунаправленного канала!
|
||||
|
||||
### <a name="9"></a> 9. Напишите собственную функцию Sleep, используя time.After
|
||||
|
||||
```go
|
||||
func sleep(s int) {
|
||||
<- time.After(time.Second * time.Duration(s)):
|
||||
}
|
||||
```
|
||||
|
||||
### <a name="10"></a> 10. Что такое буферизированный канал? Как создать такой канал с ёмкостью в 20 сообщений?
|
||||
|
||||
При инициализации канала можно использовать второй параметр:
|
||||
|
||||
```go
|
||||
c := make(chan int, 1)
|
||||
```
|
||||
|
||||
и мы получим буферизированный канал с ёмкостью __1__. Обычно каналы работают синхронно - каждая из сторон ждёт, когда другая сможет получить или передать сообщение. Но буферизованный канал работает асинхронно — получение или отправка сообщения не заставляют стороны останавливаться. Но канал теряет пропускную способность, когда он занят, в данном случае, если мы отправим в канал __1__ сообщение, то мы не сможем отправить туда ещё одно до тех пор, пока первое не будет получено.
|
||||
|
||||
### <a name="11"></a> 11. Напишите программу, которая меняет местами два числа (x := 1; y := 2; swap(&x, &y) должно дать x=2 и y=1)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
x := 1
|
||||
y := 2
|
||||
|
||||
swap(&x, &y)
|
||||
|
||||
fmt.Println(x, y)
|
||||
}
|
||||
|
||||
func swap(x, y *int) {
|
||||
*x, *y = *y, *x
|
||||
}
|
||||
```
|
||||
|
||||
### <a name="12"></a> 12. Какое будет значение у переменной x после выполнения программы?
|
||||
|
||||
```go
|
||||
func square(x *float64) {
|
||||
*x = *x * *x
|
||||
}
|
||||
|
||||
func main() {
|
||||
x := 1.5
|
||||
square(&x)
|
||||
|
||||
fmt.Println(x)
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Ответ</summary>
|
||||
Ответ: 2.25
|
||||
</details>
|
||||
|
||||
### <a name="13"></a> 13. Какое значение примет выражение (true && false) || (false && true) || !(false && false)?
|
||||
|
||||
```go
|
||||
fmt.Println((true && false) || (false && true) || !(false && false))
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Ответ</summary>
|
||||
Ответ: true
|
||||
</details>
|
||||
|
||||
### <a name="14"></a> 14. Мы знаем, что в десятичной системе самое большое число из одной цифры - это 9, а из двух - 99. В бинарной системе самое большое число из двух цифр это 11 (3), самое большое число из трех цифр это 111 (7) и самое большое число из 4 цифр это 1111 (15). Вопрос: каково самое большое число из 8 цифр? (Подсказка: 101-1=9 и 102-1=99)
|
||||
|
||||
`// todo`
|
||||
|
||||
### <a name="15"></a> 15. Что выведет следующая программа?
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
i := 65
|
||||
fmt.Println(string(i))
|
||||
}
|
||||
```
|
||||
|
||||
**Варианты:**
|
||||
|
||||
1. A
|
||||
2. 65
|
||||
3. Ошибка компиляции
|
||||
4. Нет правильного ответа
|
||||
5. Я не знаю
|
||||
|
||||
<details>
|
||||
<summary>Ответ</summary>
|
||||
Ответ: А
|
||||
</details>
|
||||
|
||||
### <a name="16"></a> 16. Что выведет следующая программа?
|
||||
|
||||
```go
|
||||
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. Я не знаю
|
||||
|
||||
<details>
|
||||
<summary>Ответ</summary>
|
||||
Ответ: 4
|
||||
</details>
|
||||
|
||||
### <a name="17"></a> 17.Как работает Garbage Collection в Go?
|
||||
Garbage Collection - это процесс освобождения места в памяти, которое больше не используется. В документации указано следующее:
|
||||
```go
|
||||
GC выполняется конкурентно (concurrent), одновременно с потоками мутатора (mutator), в точном соответствии с типом (этот принцип также известен как чувствительность к типу), допускается парааллельная выполнение нескольких потоков GC. Это конкурентная пометка и очистка (mark-sweep), при которой используется барьер записи (write barrier). При этом в процессе ничего не генерируется и не сжимается. Освобождение памяти выполняется на основе размера, выделенного для каждой программы Р, чтобы в общем случае минимизировать фрагментацию и избежать блокировок.
|
||||
```
|
||||
В основе работы GC Go лежит "трехцветный алгоритм". Официальное название "трехцветный алгоритм пометки и очистки". Использует барьер памяти. Главный принцип алгоритма трехцветной пометки и очистки состоит в разделении объектов, находящихся куче, на три набора, в соответствии с "цветом". Условно разделяются на 3 цвета:
|
||||
- черные объекты - гарантированно не имеют указателей на белые объекты;
|
||||
- серые объекты - могут иметь указатели на белые объекты;
|
||||
- белые объекты - на них могут ссылаться некоторые серые объекты и сами некоторые белые объекты могут ссылаться на некоторые черные.
|
||||
Краткий алгоритм:
|
||||
1. Все объекты сначала белые;
|
||||
2. Идет перебор "корневых" объектов, помечаются как серые. Корневые - это объекты к которым можно обращаться напрямую, например глобальные переменные, элементы в стеке и т.д.
|
||||
3. Идет перебор серых объектов, проверяются ссылки на другие объекты и помечаются на черные объекты. Если есть ссылка на белый объект, то белый становится серым.
|
||||
4. Продолжается до тех пор, пока не будут перебраны все серые объекты.
|
||||
5. Оставшиеся после перебора белые объекты считаются недостижимыми и занимаемая ими область памяти может быть освобождена.
|
||||
Есть еще Мутатор - это приложение, работающее во время сборки мусора. Вызывает функцию барьера записи. Выполняется каждый раз, когда меняется указатель в куче. После изменения указателя объект считается достижимым и помечается как серый.
|
||||
|
||||
### <a name="18"></a> 18.Что такое interface, как они работают в Go?
|
||||
`// todo`
|
||||
### <a name="19"></a> 19.Что такое slice, как устроены и чем отличаются от массивов?
|
||||
`// todo`
|
||||
### <a name="20"></a> 20.Что такое len и capacity в slice Go?
|
||||
`// todo`
|
||||
### <a name="21"></a> 21.Возможно ли предугадать, что GC отработает за константное время N?
|
||||
`// todo`
|
||||
### <a name="22"></a> 22.Что будет, если создать канал и отправить туда запись, но у него нет читателей?
|
||||
`// todo`
|
||||
Reference in New Issue
Block a user