Deep Engineering

Go

Планировщик, каналы и сборщик мусора Go — по исходникам рантайма и предложениям, в которых эти решения принимались.

Разделы
4
Статьи
5
ИСТОЧНИКОВ
41
Сложность
5 статей · подходит

Разделы

Статьи

ПродвинутыйОпубликованоКанал в Go: буфер, мьютекс и две очереди — и что из них работает в каждый моментВ канале три части: кольцевой буфер, обычный мьютекс и две очереди ожидающих горутин. Почти всё удивительное в нём — про то, какая из трёх работает в конкретный момент. Когда очередь: значение идёт мимо буфера, и len(ch) остаётся нулём. Когда буфер: больше — не значит быстрее, лучший из замеренных размеров не самый большой. Когда только мьютекс: канал вдесятеро дороже atomic, потому что он и есть мьютекс плюс учёт.gochannelsselectconcurrencyruntime45 МИН6 ИСТОЧНИКОВЧитать →ПродвинутыйОпубликованоКарта в Go: контракт языка, Swiss Table и четыре следствия устройстваТри части и один порядок: сначала то, что карта обещает как конструкция языка — нулевое значение вместо ошибки, форма с двумя результатами, неопределённый порядок обхода и синхронизация; потом устройство поиска в Go 1.24 — отпечаток, группа из восьми и правило остановки; и только потом четыре следствия с замерами: промах дороже попадания, порядок провёрнут, а не перемешан, адрес элемента взять нельзя, а len(m) == 0 не значит, что память вернулась.gomapsswiss-tableruntimememory60 МИН9 ИСТОЧНИКОВЧитать →ПродвинутыйОпубликованоСрез в Go: три слова, общий массив и рост запаса не по тому правилу, которое все помнятСрез — это заголовок из трёх машинных слов над чужим массивом. Отсюда следует и то, что append иногда меняет соседний срез, и то, что кусок в десять байт держит в памяти пятьдесят мегабайт. А правило «×2 до 1024, дальше ×1,25» описывает рантайм до Go 1.18 — и даже тогда было неточным.goslicesappendmemoryruntime30 МИН8 ИСТОЧНИКОВЧитать →ПродвинутыйОпубликованоЦикл по функции в Go: тело — это функция, которую вызывает итератор, и отсюда всё остальное`for x := range f` выглядит сахаром над обычным циклом. Это не сахар: тело становится отдельной функцией, `break` превращается в `return false`, а `return` из тела не выходит немедленно — и ровно поэтому `defer` внутри итератора отрабатывает при любом выходе. Четыре ошибки итератора ловит рантайм, а обход стоит либо ноль, либо вызов на каждый элемент, и решает это не итератор, а то, видит ли компилятор функцию в точке обхода.goiteratorsrange-over-funcitercompiler50 МИН6 ИСТОЧНИКОВЧитать →ПродвинутыйОпубликованоДженерики в Go: одиннадцать типов, шесть тел кода и метод, до которого всё равно идут через словарьСначала язык: ограничение задаёт множество типов, множество типов задаёт операции, а сохранить связь между типом входа и типом выхода не умеет ни один интерфейс. Потом компилятор: Go порождает версию не под каждый тип, а под форму — одиннадцать типов дали шесть тел кода, три разных указателя одно. И только потом замер: дженерик по ограничению с методами прямого вызова не даёт и отстаёт вчетверо, но четвёрка эта на четыре пятых состоит из потерянного встраивания, а не из косвенности, и это здесь измерено, а не предположено.gogenericstype-parameterscompilergcshape60 МИН12 ИСТОЧНИКОВЧитать →

Граф знаний

НЕЛИНЕЙНО · С УЧЁТОМ ПРЕДПОСЫЛОК

Темы связаны между собой, и связи здесь не нарисованы, а посчитаны: каждая статья сама называет, на что опирается и с чем соседствует, а картинка собирается из этих названий. Пунктирный кружок — тема, которую статьи уже называют связанной, но которая ещё не написана.

5 · 0 вершин и связей

Связи списком

Связей пока нет: ни одна статья этого домена не назвала другую своей соседкой.

Без связей: channels, maps, slices, range-over-func, generics