💡 Инструкция: Выберите один ответ из пяти. На 20 вопросов отведено 55 минут. В каждом вопросе верен только один вариант. После завершения вы увидите общий результат и результаты по 4 тематическим шкалам с объяснениями и практическими рекомендациями.
Вопрос 1 из 20
Команда проверяет решение по теме «Создание ошибок». Какое описание результата совпадает с правилами Go?
Go Создание ошибок: результат выполнения Копировать
// Фрагмент для трассировки.
package main
import "errors"
func sqrt(n int) (int,error){ if n<0{return 0,errors.New("negative")}; return n,nil }
func main(){ _,_ = sqrt(-1) }
Вызов `sum(xs...)` передаёт элементы `xs` как отдельные аргументы и возвращает `6`.
Отложенная функция увеличивает именованный результат, поэтому `answer()` возвращает `2`, а не `1`.
Функция возвращает ненулевую ошибку при отрицательном входе, а вызывающий код может обработать её без паники.
Отложенная функция получает значение `"boom"`, и программа продолжает выполнение после завершения функции `run`.
Функция возвращает `7, nil`; запись `n, err := parse()` корректно получает оба результата.
Вопрос 2 из 20
Перед публикацией кода по теме «Создание ошибок» нужно уточнить контракт. Какая правка устраняет причину, а не маскирует её проявление?
Go Создание ошибок: фрагмент на ревью Копировать
// Фрагмент из ревью: требуется выбрать безопасную правку.
package main
import "errors"
func sqrt(n int) (int,error){ if n<0{return 0,errors.New("negative")}; return n,nil }
func main(){ _,_ = sqrt(-1) }
Объединять несколько значений в одном `case`, если им соответствует одно действие, вместо цепочки пустых ветвей.
Не менять вариативный срез без явного контракта: при передаче `xs...` он может разделять массив с данными вызывающего кода.
Использовать метку, когда она делает цель выхода очевидной; при сложной логике лучше вынести поиск в отдельную функцию и вернуть результат.
Использовать пакетную sentinel-ошибку только когда вызывающему коду действительно нужно программно различать этот случай.
Возвращать значение и ошибку, когда отсутствие результата вызвано сбоем, а не кодировать ошибку магическим числом.
Вопрос 3 из 20
В рабочем примере по теме «Создание ошибок» важно отделить гарантию от догадки. Что именно гарантирует Go в этой ситуации?
Go Создание ошибок: проверка контракта Копировать
// Определите правило Go, которое объясняет результат.
package main
import "errors"
func sqrt(n int) (int,error){ if n<0{return 0,errors.New("negative")}; return n,nil }
func main(){ _,_ = sqrt(-1) }
Ошибка — значение, обычно возвращаемое отдельным результатом; `errors.New` подходит для постоянного сообщения без форматирования.
Неинициализированная переменная получает нулевое значение своего типа; это не означает, что такое значение подходит предметной области.
Несколько результатов — обычная часть сигнатуры; вызывающий код обязан принять их все либо явно отбросить через `_`.
Нетипизированная константа сохраняет точное значение до контекста, где требуется конкретный тип, если значение представимо.
Именованные результаты являются локальными переменными и участвуют в `return` без выражений, но могут быть изменены отложенной функцией.
Вопрос 11 из 20
В рабочем примере по теме «Проверка цепочки errors.Is» важно отделить гарантию от догадки. Как точнее всего описать выполнение фрагмента?
Go Проверка цепочки errors.Is: результат выполнения Копировать
// Фрагмент для трассировки.
package main
import("errors";"fmt")
var ErrMissing=errors.New("missing")
func main(){ err:=fmt.Errorf("open: %w",ErrMissing); _=errors.Is(err,ErrMissing) }
Функция возвращает `7, nil`; запись `n, err := parse()` корректно получает оба результата.
Отложенная функция увеличивает именованный результат, поэтому `answer()` возвращает `2`, а не `1`.
Вторая строка компилируется: `err` уже существует, но `n` объявляется впервые в этом блоке.
Для ошибки, обёрнутой через `%w`, `errors.Is(err, ErrMissing)` возвращает `true`.
Вызов `sum(xs...)` передаёт элементы `xs` как отдельные аргументы и возвращает `6`.
Вопрос 16 из 20
Фрагмент относится к теме «Проектирование контекста». Что именно произойдёт при выполнении показанного фрагмента?
Go Проектирование контекста: результат выполнения Копировать
// Фрагмент для трассировки.
package main
import "fmt"
func parse(id int, err error) error { return fmt.Errorf("parse invoice %d: %w", id, err) }
func main(){}
Два `n++` могут потерять обновление и образуют гонку, потому что операция состоит из чтения, вычисления и записи.
Сообщение `parse invoice 42: invalid date` полезнее, чем абстрактное `failed`, потому что сохраняет действие и объект.
Каждая горутина получает собственное значение `v`, поэтому не читает одну меняющуюся переменную цикла.
Горутина зависнет на отправке в небуферизованный канал, потому что никто не выполняет чтение.
Код печатает `busy`, потому что никто не готов принять значение из небуферизованного канала.
Вопрос 18 из 20
В разделе «Проектирование контекста» показан конкретный случай. Какой принцип позволяет вывести ответ без запуска программы?
Go Проектирование контекста: проверка контракта Копировать
// Определите правило Go, которое объясняет результат.
package main
import "fmt"
func parse(id int, err error) error { return fmt.Errorf("parse invoice %d: %w", id, err) }
func main(){}
Закрытие сообщает, что новых значений больше не будет; обычно канал закрывает отправитель, который знает о завершении всех отправок.
Хорошая ошибка сообщает, какая операция и над каким объектом не удалась, но не дублирует слово `error` на каждом уровне.
Пакет `sync/atomic` обеспечивает атомарность отдельных операций и заданный порядок памяти, но не объединяет несколько полей в общий инвариант.
Присваивание каналу значения `nil` отключает соответствующую ветвь `select`, потому что операция никогда не готова.
Детектор гонок инструментирует доступы к памяти и сообщает конфликтующие стеки, если гонка проявилась во время запуска.