Как изучить внутреннее устройство языка программирования go? для новичков

Недавно я участвовал в нескольких собеседованиях на работу в Go. Первый спросил у меня How is channel implemented?, второй - How is goroutine implemented?. Ну как нетрудно догадаться, следующий спросил How is a Go interface implemented?.

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

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

Итак, вопрос для новичка в Go: как мне изучить внутреннее устройство Go?

Релевантно: github.com/teh-cmc/go-internals

zerkms 11.04.2018 11:51

@zerkms Да, я был там, но я имею в виду, есть ли какие-нибудь документы или руководства более низкого уровня?

FrontMage 11.04.2018 11:55

Если я получаю подобные вопросы на собеседовании, это говорит мне, что я не хочу там работать, потому что они задают (в основном) неактуальные вопросы. Если, с другой стороны, они спросят: «Как бы вы реализовали каналы?», Это полезно, потому что исследует мыслительный процесс ваш, а не вашу способность изрыгать запомненную информацию.

Flimzy 11.04.2018 12:39
9
3
2 815
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Наиболее организованный набор ссылок на внутренние ресурсы, вероятно, таков:

Внутренние ресурсы Golang

Кроме того, ответы на эти вопросы не собираются в одном месте, а разбросаны по разным сообщениям в блогах.

Внутреннее устройство среза: Блог Go: использование и внутреннее устройство

Внутреннее устройство строки: Блог Go: строки, байты, руны и символы в Go

Внутренние компоненты констант: Блог Go: Константы

Понимание отражения: Блог Go: законы отражения

Внутреннее устройство интерфейса: RSC: Go Data Structures: Интерфейсы

Реализация канала: Обзор SO: Как реализованы каналы Go?

Внутреннее устройство канала: Перейти на канал на стероидах

Реализация карты: Обзор SO: Внутренняя реализация карты Голанга - как она ищет на карте ключ?; также имеет отношение: Карты Go под капотом

Внутреннее устройство карты: Макро-вид внутренних элементов карты в Go

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

(Отказ от ответственности: время от времени я прохожу собеседование с программистами Go, для довольно сложного проекта, поэтому все нижеприведенное - моя личная мировоззрение. Тем не менее, его разделяют мои коровы-орки ;-)).

В большинстве случаев сотруднику совершенно бесполезно знать, как именно реализована та или иная часть среды выполнения (или компилятора) - отчасти потому, что это может измениться в любом будущем выпуске, а отчасти потому, что там существуют по крайней мере две современные реализации Go ("пакет gc" и часть GCC), и все они могут свободно реализовать определенную функцию любым способом они пожелают.

Что действительно интересует (разумного) интервьюера должен, так это понимаете ли вы «почему» той или иной основной функции.

Скажем, когда они просят вас объяснить, как реализован канал, что им должен интересно услышать от вас, так это то, что канал обеспечивает синхронизацию, а также может обеспечивать буферизацию. Так что вы можете сказать им, что канал как переменная, защищенная мьютексом - в случае небуферизованного канала, - или как срез, защищенный мьютексом. А затем добавьте, что результат использования канала вместо созданного вручную решение, связанное с мьютексом, заключается в том, что операции над каналами можно легко комбинировать с помощью оператора select, реализуя возможна функция сопоставления без каналов (и к тому времени они, вероятно, захотят услышать от вас о sync.Cond) но это действительно громоздко и подвержено ошибкам.

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

То же самое и с горутинами. Вы должны сохранять четкое представление о том, что различия между процессом ОС и потоком, работающим в нем, и что контекст принадлежит потоку - то есть, что необходимо сохранить и восстанавливается при переключении между потоками. А затем различия между потоком ОС и "зеленым потоком", который горутина в основном есть. Это нормально - просто знать, кто планирует потоки ОС и кто планирует горутины, и почему последний быстрее. И каковы преимущества использования горутин (основная из них - сетевая опросчик интегрирован в планировщик (см. это), второй - динамические стеки, третий - низкие накладные расходы на переключение контекста большую часть времени).

Я рекомендую прочитать список, представленный @icza.

И в дополнение к тому, о чем вы спрашивали, Я бы представил следующий список того, что хороший кандидат должны быть знакомы - в порядке от простого к сложному (до грока):

  • Механика ломтиков и append. Вы должны знать, что массивы существуют и чем они отличаются от ломтиков.

  • Как реализованы интерфейсы.

  • Дуалистическая природа струн го (учитывая, что s содержит строку, в чем разница между итерацией по его содержимому через for i := 0; i < len(s); i++ { c := s[i] } вместо for i, c := range s {}).

    Также: какие типы строк данных могут содержать - вы должны знать, что это совершенно нормально содержать в них произвольные двоичные данные, UTF-8 не требование.

    Различия между string и []byte.

  • Как реализована блокировка ввода-вывода (для сети; это примерно netpoller интегрирован в среду выполнения).

    Зная о разнице в обработке несетевого блокирующего ввода-вывода и системные вызовы вообще бонус.

  • Как реализован планировщик (те P, на которых работают G на M).

Хорошо сказано. В прошлом я был интервьюером (по Java), и, задавая внутренние вопросы, я никогда не беспокоился о том, знает ли кандидат фактические детали, а больше о его общих знаниях и понимании контекста.

icza 11.04.2018 12:37

"коровы-орки" - это опечатка или намерение в вашем ответе?

icza 11.04.2018 17:58

@icza, это американская шутка (я узнал в сообщество tcl) :-)

kostix 11.04.2018 18:29

Хорошо объяснено, но меня все еще преследует вопрос: go был разработан, чтобы быть простым, чтобы скрыть сложность за простотой, поэтому повышает удобочитаемость. Итак, чего именно мы можем достичь, зная внутреннее устройство? Под этим я подразумеваю, что можно использовать горутины и каналы для создания приложения, даже не зная концепции потоков и сопрограмм.

FrontMage 12.04.2018 04:23

@FrontMage Go был разработан, чтобы быть простым, что также означает, что у него относительно мало функций по сравнению с другими языками. Зная внутреннее устройство, вы приобретаете навыки и знания, позволяющие лучше создавать функции, в которых вы нуждаетесь, но не предоставляет Go; или, возможно, достичь того, чего вы хотите, с помощью того, что предоставляет Go делает, используя функции более оптимально, потенциально для вещей, которые изначально не предназначались. Например, каналы были разработаны для безопасной связи между горутинами, но их можно использовать для простого и безопасного пул памяти объектов.

icza 12.04.2018 11:37

«Под этим я подразумеваю, что можно использовать горутины и каналы для создания приложения, даже не зная концепции потоков и сопрограмм». Это просто неправда. Вы не можете этого сделать, не зная о них концепции. Вполне возможно, что вы действительно хотели сказать «… не зная подробностей их реализации». Тогда да, это было бы правдой, но тогда это то, что сказал @icza ...

kostix 12.04.2018 12:42

… Но затем обратите внимание, что Go обеспечивает хороший баланс между достаточно высоким уровнем и - в то же время - близко к металлу. Это последнее свойство допускает две вещи. 1) Проблемы с производительностью можно разумно оценить и проанализировать (и в Go есть для этого хорошие инструменты). Но такой анализ может потребовать знания того, как все работает. 2) Знание того, как все работает, позволяет вам думать о способах оптимизации ваших алгоритмов, когда и где это необходимо.

kostix 12.04.2018 12:46

Этот репозиторий на GitHub был бы полезен, чтобы узнать о внутреннем устройстве go.

Вы можете получить все ресурсы, связанные с внутренним устройством, здесь.

Сборник статей и видео для понимания внутреннего устройства Golang.

enter image description here

Книга об устройстве языка программирования Go.

enter image description here

Другие вопросы по теме