Привет! Сегодня продолжаем серию мини-квизов в нашем блоге. Этот выпуск (предыдущий здесь) будет посвящен языку Go — будем считать, что это разминка в преддверие GopherCon Russia 2018 (кстати, у нас на этой конференции будет стенд, и мы планируем несколько интересных активностей).
Под катом — семь вопросов и пара пасхалок. Ответы на вопросы выложим апдейтом к посту в понедельник, 26.02. Если будете решать — кладите ответы под спойлер, чтобы не портить другим фана.
Enjoy!
1. Что выведет этот код?
package main
import (
"fmt"
)
func add(arr []int, v int) {
arr = append(arr, v)
}
func main() {
arr := make([]int, 0, 100000)
fmt.Printf("%v %p\n", arr, &arr)
add(arr, 10)
fmt.Printf("%v %p\n", arr, &arr)
}
Варианты ответов:
- Пустой массив до вызова add, массив из 1 элемента после. Адреса не совпадают.
- Оба раза пустой массив. Адреса совпадают.
- Пустой массив до вызова add, массив из 1 элемента после. Адреса совпадают.
- Оба раза пустой массив. Адреса не совпадают.
2. Что выведет этот код?
package main
import "fmt"
func main() {
numbers := [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s1 := numbers[:5:8]
fmt.Println(s1)
s2 := numbers[::4]
fmt.Println(s2)
}
Варианты ответов:
- Массив чисел от 0 до 5, затем массив чисел от 0 до 9
- Массив чисел от 0 до 4, затем массив чисел от 0 до 9
- Не скомпилируется
- Массив чисел от 0 до 4, затем пустой массив.
3. Допустим у вас следующая иерархия:
src/
package_1/
p1_a.go
p1_b.go
package_2/
p2_a.go
package_3/
p3_sh.go
p3_bash.go
p3_zsh.go
Каждый модуль верхнего уровня импортирует модуль нижнего уровня т.е. package_1 импортирует package_2, а тот в свою очередь package_3. В каждом файле объявлена init-функция след. содержания:
func init () {
fmt.Println(<название файла, например: p1_a.go>)
}
Что будет выведено на экран?
Варианты ответов:
- Ошибка компиляции: More than one file in package declares init function
- Порядок не определён
- p1_a.go
p1_b.go
p2_a.go
p3_a.go
p3_bash.go
p3_sh.go
p3_zsh.go - Функции будут вызваны в случайном порядке, но в соответствии с иерархии начиная с нижнего модуля (package_3) и заканчивая верхним (package_1)
4. Чему будут равны константы:
const (
_ = iota
Avito
OLX
LetGo
Craiglist = iota
eBay
)
Варианты ответов:
- 1,2,3,4,5
- Ошибка компиляции: incorrect constant declaration: iota used twice
- 0, 1, 2, 3, 4
- 1,2,3,0, 4
5. Опытный программист Роб решил добавить модуль для парсинга данных в стандартную библиотеку своего языка. Одним из модулей парсера будет конечный автомат, войдя в поток, Роб набросал следующий код, что произойдёт в момент первой компиляции?
package main
type state func(x int) state
func start(x int) state {
if x == 0 {
return middle
} else {
return end
}
}
func middle(_ int) state {
return end
}
func end(_ int) state {
return start
}
func main() {
state := start(0)
state = state(1)
state = state(2)
}
Варианты ответов:
- Ошибка в коде: произойдёт ошибка во время компиляции "type 'state' used in self declaration"
- В stdout ничего не выведется, но процесс завершится успешно
- Runtime ошибка: возникнет бесконечная рекурсия
6. Каким будет результат выполнения кода?
package main
import (
"fmt"
)
func test() (x int) {
defer func () {
x++
} ()
x = 1
return x
}
func main() {
fmt.Println(test())
}
- 1
- 2
- Compile error
7. Молодой китайский программист Jian Yang решил освоить Go для своего нового гео-стартапа. Начав с обычного Hello World, он решил слегка его модифицировать, дабы освоить конструкцию range… Каким будет результат выполнения кода?
package main
import (
"fmt"
)
func main() {
var rc, bc int
str := "Hello ??"
for _ = range str {
rc++
}
for _ = range []byte(str){
bc++
}
fmt.Println(rc, bc)
}
Варианты ответов:
- 8 8
- 8 12
- 8 14
- 8 16
Желаем хорошего дня и ждём ваших ответов в комментариях. Следующий выпуск Avito Quiz планируем сделать по PHP.
SONANT
2 Не скомпилируется
3 Функции будут вызваны в случайном порядке, но в соответствии с иерархии начиная с нижнего модуля (package_3) и заканчивая верхним (package_1)
4 1,2,3,4,5
5 В stdout ничего не выведется, но процесс завершится успешно
6 2
7 8 12
dmbreaker
Можно было просто ссылку на play.golang.org скинуть :)
Попортил фан
youROCK
Я, конечно же, (почти) всё уже проверил сам на play.golang.org, но вот мои оригинальные ответы:
2. Не скомпилируется (но я думал, что по причине того, что capacity не может быть меньше длины, а не потому что длина обязательна)
3. Функции будут вызваны в случайном порядке, но в соответствии с иерархии начиная с нижнего модуля (package_3) и заканчивая верхним (package_1)
4. 1,2,3,0,1 — кстати говоря, такого варианта у вас нет, видимо опечатка
5. В stdout ничего не выведется, но процесс завершится успешно — но за такой код я бы наказывал
6. 2
7. 8 14 — строго говоря, программисты на Го вряд ли должны знать ширину китайских иероглифов в UTF-8. Тут скорее важно, что сами ответы будут разные при итерации по символам и по байтам.
mirrr
2) никогда не использовал тройную запись, могу только предположить, что размерность 4 будет меньше длинны здесь: [::4]
3) конечно, иерархия должна присутствовать, иначе мы рискуем использовать подпакет, который не инициализирован.
4) iota сбрасывается каждый блок const, а он тут один.
5) в stdout, собственно, ничего и не выводим. Но это ж не причина для паники)
6) тут и объяснять ничего не надо, достаточно заменить return x на return, для тех, кто не заметил именованные возвратные значения
7) да кто их знает, сколько байт один иероглиф займет?)
Stronix
Но, кстати, мы можем таки получить доступ к данным:
mirrr
А если так?)
play.golang.org/p/VUwd0G21182
Stronix
С нулевой ёмкостью шах и мат, да) (если не использовать unsafe)
dronnix
Спасибо, вот вам в благодарность тоже задачка:
claygod
Чтобы ваш код работал так, как возможно, предполагается (ну на первый взгляд), надо после инициализации цикла добавить i:=i, а ещё лучше вот так:
RidgeA
Думаю в этом и фишка, что код работает не так как кажется на первый взгляд…
youROCK
Как раз он работает именно так, как кажется на первый взгляд — печатает 3 раза одно и то же число :). Другой вопрос, что наверное в цикле defer вызывать – не лучшая идея :).
youROCK
А ещё лучше просто вот так:
Потому что аргументы для вызова функции вычисляются на момент вызова defer
niamster
Вопрос знатокам Go по именным возвращаемым значениям, вы можете мне указать где в спецификации описывается следующее поведение:
Спасибо
Stronix
Отложенные ф-ции выполняются после возвращения из основной, т.е. сначала будет выполнено
return 2
(x = 2), а затем x++.niamster
Спасибо за ответ. Я имел в виду где описывается поведение `return 2` == `x = 2; return x`?
Stronix
golang.org/ref/spec#Return_statements