💡 Инструкция: Выберите один ответ из пяти. На 30 вопросов отведено 85 минут. В каждом вопросе верен только один вариант. После завершения вы увидите общий результат и результаты по 6 тематическим шкалам с объяснениями и практическими рекомендациями.
Вопрос 12 из 30
В рабочем примере по теме «Аутентификация» важно отделить гарантию от догадки. Что здесь следует изменить прежде всего?
Go Аутентификация: фрагмент на ревью Копировать
// Фрагмент из ревью: требуется выбрать безопасную правку.
package main
import "net/http"
func auth(next http.Handler)http.Handler{return http.HandlerFunc(func(w http.ResponseWriter,r *http.Request){if r.Header.Get("Authorization")!="Bearer ok"{http.Error(w,"unauthorized",401);return};next.ServeHTTP(w,r)})}
func main(){}
Разделять аутентификацию и авторизацию, сравнивать секреты безопасным способом и ограничивать время проверки.
Создавать запрос с контекстом, проверять ошибку `Do`, статус и ограниченно читать тело, затем закрывать его.
Нормализовать пути осторожно, явно ограничивать методы и централизовать декодирование параметров.
Ограничить число попыток, использовать экспоненциальную задержку с разбросом и учитывать `Retry-After`.
Проверять ошибки до записи тела, устанавливать заголовки заранее и возвращаться после отправки ошибки.
Вопрос 21 из 30
Фрагмент относится к теме «Тестирование и наблюдаемость» в тесте «Middleware». Какой результат даст этот код на поддерживаемой реализации Go?
Go Тестирование и наблюдаемость: результат выполнения Копировать
// Фрагмент для трассировки.
package sample
import("net/http";"net/http/httptest";"testing")
func TestAuthStops(t *testing.T){called:=0;next:=http.HandlerFunc(func(http.ResponseWriter,*http.Request){called++});r:=httptest.NewRequest("GET","/",nil);w:=httptest.NewRecorder();auth(next).ServeHTTP(w,r);if called!=0||w.Code!=401{t.Fatal(called,w.Code)}}
func auth(next http.Handler)http.Handler{return http.HandlerFunc(func(w http.ResponseWriter,r *http.Request){http.Error(w,"no",401)})}
Специальный `Reader` с одним байтом за вызов проверяет, что функция не рассчитывает на заполнение буфера сразу.
Счётчик заглушки доказывает, что при 401 внутренний обработчик не был вызван.
`benchstat` сравнивает несколько выборок и показывает статистическую устойчивость различий.
Точный итог счётчика и чистый `-race` проверяют разные стороны: смысл и отсутствие обнаруженной гонки.
Тест считается успешным только если вызов действительно вызвал ожидаемую панику; отсутствие паники — отдельная ошибка теста.
Вопрос 22 из 30
На ревью разбирают тему «Тестирование и наблюдаемость» в тесте «Middleware». Что нужно поменять, чтобы граничный случай не превратился в сбой?
Go Тестирование и наблюдаемость: фрагмент на ревью Копировать
// Фрагмент из ревью: требуется выбрать безопасную правку.
package sample
import("net/http";"net/http/httptest";"testing")
func TestAuthStops(t *testing.T){called:=0;next:=http.HandlerFunc(func(http.ResponseWriter,*http.Request){called++});r:=httptest.NewRequest("GET","/",nil);w:=httptest.NewRecorder();auth(next).ServeHTTP(w,r);if called!=0||w.Code!=401{t.Fatal(called,w.Code)}}
func auth(next http.Handler)http.Handler{return http.HandlerFunc(func(w http.ResponseWriter,r *http.Request){http.Error(w,"no",401)})}
Использовать `iotest` и собственные маленькие заглушки, измерять число байтов и длительность без записи содержимого секретных потоков.
Проверять заголовки, контекст, статус, паники и дополнительные интерфейсы ResponseWriter.
Записывать метод, хост, статус, длительность и категорию ошибки, не превращая URL с идентификаторами в метки высокой кардинальности.
Хранить репрезентативные старые документы в `testdata`, проверять ограничения размера и не журналировать полный чувствительный JSON.
Выносить проверку паники в небольшую функцию и добавлять `debug.Stack()` в журнал на эксплуатационной границе.
Вопрос 23 из 30
В разделе «Тестирование и наблюдаемость» показан конкретный случай в тесте «Middleware». Какое свойство конструкции определяет её поведение?
Go Тестирование и наблюдаемость: проверка контракта Копировать
// Определите правило Go, которое объясняет результат.
package sample
import("net/http";"net/http/httptest";"testing")
func TestAuthStops(t *testing.T){called:=0;next:=http.HandlerFunc(func(http.ResponseWriter,*http.Request){called++});r:=httptest.NewRequest("GET","/",nil);w:=httptest.NewRecorder();auth(next).ServeHTTP(w,r);if called!=0||w.Code!=401{t.Fatal(called,w.Code)}}
func auth(next http.Handler)http.Handler{return http.HandlerFunc(func(w http.ResponseWriter,r *http.Request){http.Error(w,"no",401)})}
Конвейер тестируют на пустом входе, ранней отмене, медленном потребителе и закрытии всех выходов; отдельно считают активные работники.
Обобщённый алгоритм тестируют представителями разных ветвей ограничения и именованными типами, а не только `int`.
Синхронизацию проверяют под `-race`, повторными прогонами и инвариантами результата, а не только отсутствием паники.
Обработчики удобно тестировать `httptest.NewRequest` и `ResponseRecorder`, отдельно проверяя статус, заголовки и тело.
Каждый middleware тестируют отдельно и в реальном порядке цепочки, включая отсутствие вызова `next`.
Вопрос 27 из 30
В разделе «Конкурентность и эксплуатация» показан конкретный случай. Какую правку стоит предложить на ревью, сохранив назначение кода?
Go Конкурентность и эксплуатация: фрагмент на ревью Копировать
// Фрагмент из ревью: требуется выбрать безопасную правку.
package main
import("net/http";"sync/atomic")
var requests atomic.Uint64
func count(next http.Handler)http.Handler{return http.HandlerFunc(func(w http.ResponseWriter,r *http.Request){requests.Add(1);next.ServeHTTP(w,r)})}
func main(){}
Назначать уникальные порты через прослушивание `:0`, не менять глобальное окружение параллельно и закрывать серверы через Cleanup.
Ограничивать параллелизм, задавать контекст, отслеживать WaitCount/WaitDuration и избегать запросов N+1.
Ограничивать кардинальность меток, контролировать очередь лимитера и не удерживать глобальную блокировку во время `next`.
Снимать профиль блокировок под нагрузкой, проверять длины очередей и не включать дорогой сбор постоянно без оценки.
Считать запросы, категории ошибок, гистограмму задержки, очередь и ресурсы зависимостей; связывать с трассировкой через exemplar.