Недавно я наткнулся на тест LinkedIn Golang, интересную возможность для разработчиков получить значок на сайте, демонстрирующий их знание языка (этот значок не только демонстрирует ваши навыки, но и помогает вам выделиться из толпы на конкурентном рынке труда).
Я нашёл вопросы в тесте довольно интересными, и я уже писал о некоторых из них ранее, так как они дают ценную информацию о различных аспектах языка программирования Go.
1. Что нужно, чтобы две функции были одного типа?
Если мы хотим, чтобы две функции в Go были одного типа, они должны иметь одинаковую сигнатуру функции.
Это означает, что они должны иметь соответствующие параметры (количество, типы) и возвращаемые значения.
2. Что возвращает функция len(), если ей передаётся строка в кодировке UTF-8?
Вот вам небольшая идея: в Go строки на самом деле представляют собой последовательности байтов. Это означает, что когда вы передаёте строку в кодировке UTF-8 функции len(), она считает байты, а не символы:
3. Каково значение Read?
Идентификатор iota в Go — интересная функция — она представляет целочисленное значение, которое начинается с 0 и увеличивается на 1 для каждого элемента в блоке const.
4. Как вы выведите запущенные тесты с помощью go test?
При использовании команды go test вы можете включить флаг -v (“verbose”) для более подробного вывода.
go test -v
Запустив go test с флагом -v, вы увидите название каждого теста, его результат и продолжительность теста по мере его выполнения:
5. Что делает блок sync.Mutex, пока он заблокирован?
В Go sync.Mutex служит механизмом взаимного исключения, гарантируя, что только одна горутина может одновременно получить доступ к критическому разделу кода.
Фраза «любое чтение или запись переменной, которую он блокирует» соответствует нашему пониманию, поскольку мы используем sync.Mutex для защиты доступа к общим переменным.
6. Каков идиоматический способ приостановить выполнение текущей области до тех пор, пока не будет возвращено произвольное количество подпрограмм?
Если у вас была возможность изучить мою статью о пакете Go Sync, вы, возможно, помните, что сначала я использовал функцию time.Sleep, прежде чем перейти к более эффективному sync.WaitGroup:
sync.WaitGroupGo — это удобный инструмент, который позволяет вам дождаться завершения группы горутин, прежде чем приступить к выполнению.
Он работает с использованием простого счётчика и эффективно блокирует текущую область действия до тех пор, пока все рабочие горутины не завершат свои задачи, а счётчик WaitGroup не достигнет нуля.
7. Каков побочный эффект использования time.After в утверждении select?
Если вы не знакомы с time.After, это функция в пакете Go time, которая возвращает набор каналов для отправки текущего времени после указанной продолжительности.
func After(d Duration) <-chan Time
Обычно она используется в операторах select для реализации тайм-аутов или задержек. Например, представьте, что вы ждёте 3 секунды, прежде чем вывести что-то на экране:
Теперь поговорим о побочном эффекте.
Для кратковременных time.After периодов это может не иметь большого значения, но рассмотрим сценарий, в котором тайм-аут установлен на 1 час, а работа завершается до истечения времени ожидания. В этой ситуации таймер всё ещё задерживается в памяти:
Как следствие, горутина, созданная с помощью time.After, не завершится, пока не истечёт полный час, даже если операция завершится раньше.
8. Какие ограничения есть на тип var для компиляции i := myVal.(int)?
В контексте утверждения типа i := myVal.(int) переменная myVal должна быть типом интерфейса для успешной компиляции кода.
Однако использование её таким образом может быть рискованным и неэффективным, так как это может вызвать панику во время выполнения, если myVal не типа int. Чтобы более изящно справиться с этой ситуацией, лучше использовать форму утверждения типа с двумя значениями, которая обеспечивает резервный механизм:
9. Как правильно передать это как тело запроса HTTP POST?
Чтобы отправить данные в виде тела запроса HTTP POST, важно знать тип содержимого. Поскольку это необработанный текст, мы будем использовать тип содержимого «текст/обычный». Функция http.Post требует io.Reader в качестве тела, а не строку или байты
Интерфейс Reader определяется следующим образом:
Чтобы выполнить требования, мы преобразуем тело в буфер, реализующий этот интерфейс:
Таким образом, правильный способ отправки данных в виде HTTP-запроса POST:
10. Каким должно быть идиоматическое имя для интерфейса с одним методом и сигнатурой Save() error?
Основываясь на эффективном соглашении об именах Go для интерфейсов, интерфейсы с одним методом обычно именуются путём добавления суффикса «-er» или аналогичной модификации к имени метода, что приводит к Reader, Writer, Formatter и CloseNotifier..
В этом случае идиоматическое название интерфейса будет Saver .
О, возможно, вы также сталкивались с интерфейсом Stringer(), который определяется следующим образом:
Это уловка, когда вы передаёте значение, реализующее интерфейс Stringer таким функциям, как fmt.Println() или fmt.Printf(), метод String() автоматически вызывается для получения строкового представления значения.
Спасибо за прочтенную статью! Если вам было интересно, подпишитесь на канал!