## Вопросы от Данила Подольского на позицию Senior Golang Backend Developer в компанию Evrone ### Go — императивный или декларативный? А в чем разница? В основном Императивный. Разница в подходе: - императивный - как сделать (прямо пошагово); - декларативный - что сделать (итоговый результат). ### Что такое type switch? Сравнение типов переменной, а не ее значений. ### Как сообщить компилятору, что наш тип реализует интерфейс? Если наш тип реализует все методы интерфейса, значит он реализует этот интерфейс. ### Как работает append? Если capacity исходного массива достаточно, он используется повторно. В противном случае выделяется новый базовый массив достаточной длины и данные копируются ### Какое у slice zero value? Какие операции над ним возможны? Zero value у slice == nil Возможные операции: len, cap, append. ### Как устроен тип map? Map в Go это хэш таблица, позволяющая хранить пары ключ-значение и обладающая следующими функциями: маппинг, вставка, удаление, поиск. Map in Go не упорядоченная. Место поиска определяется рандомно. Когда мы пытаемся получить значение из мапы, а его там нет, получаем «нулевое значение типа», что в случае числа 0. Map — ссылочный тип и мало объявить переменную, надо ее проинициализировать. ### Каков порядок перебора map? Случайным образом. ### Что будет, если читать из закрытого канала? Вернется нулевое значение. ### Что будет, если писать в закрытый канал? Произойдет вызов panic. ### Как вы отсортируете массив структур по алфавиту по полю Name? С помощью функции sort.SliceStable. Для этого сначала конвертируем массив в слайс. ```go slice := array[:] ``` ### Что такое сериализация? Зачем она нужна? Сериализация — это преобразование объекта в какой-либо формат с тем, чтобы потом tuj можно было восстановить из этого формата. Допустим, после передачи как набора байт по сети. ### Сколько времени в минутах займет у вас написание процедуры обращения односвязного списка? Тут каждый считает сам. Попробуйте с таймингом (засеките время). ### Где следует поместить описание интерфейса: в пакете с реализацией или в пакете, где этот интерфейс используется? Почему? Небольшое копирование лучше, чем небольшая зависимость. Даже в стандартной библиотеке есть места, где те же io.Reader или fmt.Stringer переопределены, чтобы избежать ненужной зависимости от других пакетов. Если интерфейс маленький, скопировать его не составит труда, а если он большой, то есть вероятность, что в будущем одному модулю понадобятся одни методы, а другому - другие. ### Предположим, ваша функция должна возвращать детализированные Recoverable и Fatal ошибки. Как это реализовано в пакете net? Как это надо делать в современном Go? ### Главный недостаток стандартного логгера? ### Есть ли для Go хороший orm? Ответ обоснуйте. Для работы с базами данных можно использовать пакет database/sql. Но есть куча ORM, можно выбрать любую. Все зависит от исходной посылки. ### Какой у вас любимый линтер? Go vet + golint ### Можно ли использовать один и тот же буфер []byte в нескольких горутинах? ### Какие типы мьютексов предоставляет stdlib? В стандартной библиотеке есть пакет sync. Он предоставляет следующие типы мьютексов: - sync.Mutex - блокирует и снимает блокировку; - sync.RWMutex - тоже самое, но есть отдельно блокировка на чтение/запись и отдельно на чтение; - отдельно стоит упомянуть sync.Map - вид мьютекса для мап. ### Что такое lock-free структуры данных, и есть ли в Go такие? ### Способы поиска проблем производительности на проде? ### Стандартный набор метрик prometheus в Go-программе? ### Как встроить стандартный профайлер в свое приложение? ### Overhead от стандартного профайлера? ### Почему встраивание — не наследование? Буква L в аббревиатуре SOLID обозначает Liskov Substitution - объекты в программе должны быть заменяемыми на экземпляры их подтипов без изменения правильности выполнения программы. Этот принцип предложила [Барбара Лисков](https://en.wikipedia.org/wiki/Barbara_Liskov). При использовании наследования объект представляет собой наследуемый тип, тем самым наследуя функциональность, которой делятся родители. При использовании композиции у объекта есть все признаки, что предоставляют необходимую для объекта функциональность. Другой объект может повторно использовать некоторые из данных функциональностей, однако тип родителя или иерархия, восходящая к нему, отсутствует. ### Какие средства обобщенного программирования есть в Go? Обобщенное программирование — это форма, в которой мы подключаем шаблоны, известные как дженерики, которые на самом деле не являются истинным исходным кодом, но компилируются компилятором для преобразования их в исходный код. [Дженерики будут](https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md) с версии 1.18. ### Какие технологические преимущества языка Go вы можете назвать? ### Какие технологические недостатки языка Go вы можете назвать?