Найти тему
Simple Prog

15 вопросов с собеседований Golang из LinkedIn Assessment — подробные пояснения

Оглавление

Недавно я наткнулся на тест LinkedIn Golang, интересную возможность для разработчиков получить значок на сайте, демонстрирующий их знание языка (этот значок не только демонстрирует ваши навыки, но и помогает вам выделиться из толпы на конкурентном рынке труда).

Title
Title

Я нашёл вопросы в тесте довольно интересными, и я уже писал о некоторых из них ранее, так как они дают ценную информацию о различных аспектах языка программирования Go.

1. Что нужно, чтобы две функции были одного типа?

-2

Если мы хотим, чтобы две функции в Go были одного типа, они должны иметь одинаковую сигнатуру функции.

Фрагмент кода автора
Фрагмент кода автора

Это означает, что они должны иметь соответствующие параметры (количество, типы) и возвращаемые значения.

2. Что возвращает функция len(), если ей передаётся строка в кодировке UTF-8?

-4

Вот вам небольшая идея: в Go строки на самом деле представляют собой последовательности байтов. Это означает, что когда вы передаёте строку в кодировке UTF-8 функции len(), она считает байты, а не символы:

Фрагмент кода автора
Фрагмент кода автора

3. Каково значение Read?

Фрагмент кода автора
Фрагмент кода автора

Идентификатор iota в Go — интересная функция — она представляет целочисленное значение, которое начинается с 0 и увеличивается на 1 для каждого элемента в блоке const.

4. Как вы выведите запущенные тесты с помощью go test?

Варианты ответа
Варианты ответа

При использовании команды go test вы можете включить флаг -v (“verbose”) для более подробного вывода.

go test -v

Запустив go test с флагом -v, вы увидите название каждого теста, его результат и продолжительность теста по мере его выполнения:

Вывод для 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» или аналогичной модификации к имени метода, что приводит к ReaderWriterFormatter и CloseNotifier..

В этом случае идиоматическое название интерфейса будет Saver .

О, возможно, вы также сталкивались с интерфейсом Stringer(), который определяется следующим образом:

Фрагмент кода автора
Фрагмент кода автора

Это уловка, когда вы передаёте значение, реализующее интерфейс Stringer таким функциям, как fmt.Println() или fmt.Printf(), метод String() автоматически вызывается для получения строкового представления значения.

Спасибо за прочтенную статью! Если вам было интересно, подпишитесь на канал!