Привет! Сегодня пришлось вспомнить, что вообще я гошник и почитать исходники. Вышел RC1 новой гошки, релиз в августе. Все обычно читают релиз-ноты как список фич, а я в этот раз прочитал их как некролог: несколько классических вопросов с собеседований официально уезжают на пенсию. Пройдёмся по покойникам (с поправкой, что это ещё RC и финальный список может чуть уехать).
Вопрос 1. «Почему метод не может объявить свои типовые параметры?»
Четыре года после появления дженериков этот вопрос кормил интервьюеров. Больше не кормит - в 1.27 дженерик-методы наконец завезли:
// Раньше: только отдельной функцией
func Map[T, U any](s List[T], f func(T) U) List[U]
// Go 1.27: метод со своим типовым параметром
func (s List[T]) Map[U any](f func(T) U) List[U]
Вместо Map(s, f) пишем s.Map(f). Причём радует даже не само "стало можно", а то, что пакеты перестанут распухать от функций, которые по-хорошему принадлежат типу.
Но у интервьюера остаётся полвопроса: интерфейсные методы свои типовые параметры объявлять всё ещё не могут. Почему - подумайте сами: диспетчеризация у интерфейсов динамическая, и компилятор заранее не знает, какие инстанциации метода ему понадобятся. Вот вам новый вопрос со звёздочкой взамен умершего.
Вопрос 2. «Зачем дочитывать resp.Body перед Close?»
Наш любимый карго-культ: io.Copy(io.Discard, resp.Body), чтобы соединение вернулось в пул, а не закрылось. В 1.27 Close дочитывает остаток тела сам (в разумных пределах и только для HTTP/1).
Вопрос 3. «Как найти утечку горутин?»
Канонический ответ был "pprof, дамп горутин, глаза и терпение". Теперь у рантайма есть отдельный профиль: /debug/pprof/goroutineleak. Идея: GC помечает горутину утёкшей, если она заблокирована на примитиве, до которого не может дотянуться ни одна живая горутина. Буквально - если тебя некому разбудить, значит ты утёк. Занёс фичу инженер из Uber, где горутины, видимо, утекают в промышленных масштабах.
Ловит профиль не всё, и это тоже новый вопрос со звёздочкой: какую утечку он НЕ увидит? Подсказка: горутину, которая вечно ждёт канал, пока живой (и достижимый) отправитель просто никогда в него не пишет по логике программы.
Вопрос 4. «Каким пакетом генерить UUID?»
Ответ "google/uuid, это же де-факто стандарт" устарел: uuid теперь в стандартной библиотеке. Тип тот же [16]byte, так что миграция - это буквально поменять строчку импорта. Отдельно порадовал NewV7(): тайм-сортируемые UUID, которые сильно добрее к индексам базы, чем рандомный v4.
Бонус, за которым следить: json/v2
Самое тихое изменение релиза: старый encoding/json теперь под капотом работает на новой реализации v2. Обещают то же поведение и заметно быстрее Unmarshalинг. В чудеса обратной совместимости на пакете, которым парсит JSON весь мир, я верю осторожно - тем более что стоп-кран GOEXPERIMENT=nojsonv2 в релиз-ноты положили явно не для красоты. Думайте.
Kremniy; подписаться