Только успел отправить призы с новогоднего розыгрыша - уже наступил новый праздник)
Поздравляю мужскую часть канала с 23 февраля!
Не буду сегодня говорить про Родину - знаю, что у всех на этот счёт разные мнения. Да и из моих уст, как человека с несколькими гражданствами, это звучало бы странно.
В этот день желаю вам здоровья, силы и чести.
Становиться лучше с каждым днём - чтобы иметь возможность защитить себя, свою семью и свои ценности.
Буду продолжать радовать вас новыми видео и проектами. Совсем недавно выпустил разбор Go 1.26. Честно говоря, про сам язык Go я уже будто разобрал всё, что можно. Очень много видео-лекций сейчас лежат и ждут монтажа.
Поставьте, пожалуйста,🙂 , если вам было бы интересно увидеть их в сыром формате.
На текущий момент хочу начать разбирать всё, что связано с архитектурой проекта на Go и не только. До конца февраля выйдет полноценный разбор gRPC, начиная от внутреннего устройства HTTP/2, заканчивая проектированием API и генерацией кода.
Поздравляю мужскую часть канала с 23 февраля!
Не буду сегодня говорить про Родину - знаю, что у всех на этот счёт разные мнения. Да и из моих уст, как человека с несколькими гражданствами, это звучало бы странно.
В этот день желаю вам здоровья, силы и чести.
Становиться лучше с каждым днём - чтобы иметь возможность защитить себя, свою семью и свои ценности.
Буду продолжать радовать вас новыми видео и проектами. Совсем недавно выпустил разбор Go 1.26. Честно говоря, про сам язык Go я уже будто разобрал всё, что можно. Очень много видео-лекций сейчас лежат и ждут монтажа.
Поставьте, пожалуйста,
На текущий момент хочу начать разбирать всё, что связано с архитектурой проекта на Go и не только. До конца февраля выйдет полноценный разбор gRPC, начиная от внутреннего устройства HTTP/2, заканчивая проектированием API и генерацией кода.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
10 124🫡14❤🔥11 4🖕3
Последние пару месяцев меня очень часто спрашивали про то, когда будет запуск курса по Go.
Хоть я и так выкладываю и буду выкладывать огромное количество уникальных материалов в открытый доступ, многие хотят разобраться и погрузиться ещё глубже.
Что скрывать, язык Go действительно набрал огромную популярность. В этом году это топ-1 курс по выбору в ИТМО.
То есть, мало того, что AI и кризис создают инфляцию знаний, так ещё и подрастает конкурирующее поколение, которое сейчас учится в ведущих вузах страны, в том числе на моих курсах.
Уже периодически слышу истории про то, как люди не могут найти работу после сокращений с несколькими годами опыта разработки, и дальше будет только хуже.
Единственный способ победить это повысить свою компетентность.
Как раз для этого запускаю уникальный и ограниченный поток «The Nature of Go», в котором собрал симбиоз своих нескольких курсов.
База computer science, внутреннее устройство Go, разработка микросервисов, применение AI, написание резюме, софтскиллы и прохождение собеседований.
Полный набор для того, чтобы адаптироваться к новой реальности и не проиграть.
Please open Telegram to view this post
VIEW IN TELEGRAM
7 27🤩14❤10🔥5 2
Как и говорил, хочу начать разбирать всё, что связано с архитектурой проекта на Go и не только.
В новом видео подробно разобрал тему gRPC, начиная от истории создания и внутреннего устройства HTTP/2, заканчивая генерацией кода на Go через buf (easyp). Приятного просмотра!
🟣 Rutube
Please open Telegram to view this post
VIEW IN TELEGRAM
8❤🔥33🤩6 4✍3 3
Forwarded from Yandex for Backend
Многие продукты Яндекса используют этот язык в своих сервисах: от инфраструктуры автономного транспорта до продуктовых сервисов финтеха. Поэтому разработчики постоянно расширяют экспертизу в Go: изучают лучшие практики, делятся опытом, проводят митапы и подробно разбирают нововведения.
Сейчас есть отличный повод этим заняться: 10 февраля вышел Go 1.26.
Подписывайтесь:
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
7❤24 12✍4🔥2
Forwarded from igoroutine.courses
Data race это частный случай race condition. Определять термин data race на самом деле можно по-разному.
Самое простое определение:
Состояние во время исполнения, когда две операции над переменной происходят из разных горутин без синхронизации, при этом хотя бы одна из них является записью.
Чуть более сложное:
Состояние во время исполнения, когда две конфликтующие операции над переменной происходят из разных горутин без синхронизации.
И самое сложное на основании формализма из Go memory model:
Состояние во время исполнения, когда две конфликтующие операции над переменной нельзя разделить отношением happens before
Казалось бы, да ну их, есть прекрасный инструмент race detector, который инструментриует программу при компиляции и позволяет во время исполнения находить data race.
Но, внезапно, выясняется, что он не всегда может найти проблему. Это напрямую следует из его устройства.
Пример:
Мейнтейнеры Go пытались реализовать такой интерфейс:
type Cron interface {
Run(ctx context.Context, action func(), next func() time.Duration)
}
Реализация должна вызывать
action, ожидая перед каждым запуском next() времени. После отмены контекста не должно быть вызовов action.Такой подход на практике очень часто используется, например:
• HTTP ретраи
• Service discovery
• Adaptive polling
• Keepalive / heartbeat
• Любые задачи с backoff
Сходу у них получилась следующая реализация:
func (c *cronImpl) Run(ctx context.Context, action func(), next func() time.Duration) {
var t *time.Timer
t = time.AfterFunc(next(), func() {
select {
case <-ctx.Done():
return
default:
action()
t.Reset(next())
}
})
<-ctx.Done()
}
Запускаем тесты:
func TestCron(t *testing.T) {
synctest.Test(t, func(t *testing.T) {
c := New()
var n atomic.Int64
next := func() time.Duration {
if n.Add(1) <= 5 {
return 0
}
return 1 * time.Second
}
var calls atomic.Int64
ctx, cancel := context.WithCancel(t.Context())
t.Cleanup(func() {
cancel()
})
done := make(chan struct{})
go func() {
defer close(done)
c.Run(ctx, func() {
calls.Add(1)
}, next)
}()
synctest.Wait()
require.Greater(t, calls.Load(), int64(0))
cancel()
synctest.Wait()
select {
case <-done:
default:
t.Fatalf("Run did not exit after cancel")
}
})
}
Которые успешно проходят даже с race detector'ом.
Но в этой реализации действительно есть data race, и race detector его не находит.
Ссылка с примером использования: https://go.dev/play/p/Fq-yNa0wXWj
P.S. Пожалуйста, те, кто проходил курс и решал это задание на практике, не пишите сразу правильный ответ)
Please open Telegram to view this post
VIEW IN TELEGRAM
9🤔8👍2❤1✍1
Forwarded from igoroutine.courses
Продолжение к предыдущему посту.
Итак, разработчик из Go team написал такую реализацию:
func (c *cronImpl) Run(ctx context.Context, action func(), next func() time.Duration) {
var t *time.Timer
t = time.AfterFunc(next(), func() {
select {
case <-ctx.Done():
return
default:
action()
t.Reset(next())
}
})
<-ctx.Done()
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
c := cronImpl{}
c.Run(ctx,
func() {
fmt.Println("Hello, @igoroutine")
},
func() time.Duration {
return time.Second
},
)
}
Всё ожидаемо работает:
Hello, @igoroutine
Hello, @igoroutine
Hello, @igoroutine
Hello, @igoroutine
Hello, @igoroutine
Hello, @igoroutine
Hello, @igoroutine
Hello, @igoroutine
Hello, @igoroutine
Hello, @igoroutine
Program exited 0.
Мы, как ответственные люди, дополнительно написали тест. Более того, включили race detector при компиляции.
go test -v -race ./...
func TestCron(t *testing.T) {
synctest.Test(t, func(t *testing.T) {
c := New()
var n atomic.Int64
next := func() time.Duration {
if n.Add(1) <= 5 {
return 0
}
return 1 * time.Second
}
var calls atomic.Int64
ctx, cancel := context.WithCancel(t.Context())
done := make(chan struct{})
go func() {
defer close(done)
c.Run(ctx, func() {
calls.Add(1)
}, next)
}()
synctest.Wait()
require.Greater(t, calls.Load(), int64(0))
cancel()
synctest.Wait()
select {
case <-done:
default:
t.Fatalf("Run did not exit after cancel")
}
})
}
=== RUN TestCron
--- PASS: TestCron (0.00s)
PASS
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x0 pc=0x1009927fc]
Пробуем дебагать и снова запускать тесты. Для надёжности прогоняем их с count=10000:
go test -v -count=10000 ./...
PASS
ok 0.787s
Попробуем запустить с race detector'ом и count=100:
go test -v -race -count=100 ./...
PASS
ok 4.079s
От безысходности запускаем тесты с race detector'ом и
count=1000000 и видим вот это:
WARNING: DATA RACE
Read at 0x00c0000024a0 by goroutine 3543:
cron.go:30 +0x90 // t.Reset(next())
Previous write at 0x00c0000024a0 by goroutine 3541:
cron.go:24 +0x194 // t = time.AfterFunc(next() ...
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x0 pc=0x1050ae7fc]
Всё дело в том, что AfterFunc внутри создаёт отдельную горутину:
func AfterFunc(d Duration, f func()) *Timer {
return newTimer(when(d), 0, goFunc, f, nil)
}
func goFunc(arg any, seq uintptr, delta int64) {
go arg.(func())()
}
При очень маленьком
d в этом коде
t = time.AfterFunc(next(), func() {
...
t.Reset(next())
})
Горутина с t.Reset может начать исполняться раньше, чем значение будет сохранено в t. Соответственно, получается nil pointer dereference. На самом деле причина может быть в аппаратной реализации, например, t может находиться в кэше ядра. И таких «аппаратных» объяснений может быть очень много в зависимости от архитектуры.
С точки зрения Go memory model это не важно.
Важно, что мы пишем (t = ...) и читаем (t.Reset) общую переменную без синхронизации. Это data race по определению.
И race detector не всегда может тривиально обнаружить такие проблемы, это напрямую следует из его устройства.
Более того, эту реализацию можно переписать более эффективно, чтобы избежать создания лишней горутины.
Это как раз одно из многочисленных заданий на курсе The Nature of Go.
Please open Telegram to view this post
VIEW IN TELEGRAM
4🤯13👍3😱2✍1
Случайно решил почитать про историю праздника на wiki.
Сознание определенно расширилось
Please open Telegram to view this post
VIEW IN TELEGRAM
❤21 11✍3
Недавно выкладывал пост, после которого по реакциям понял, что многим интересно увидеть мои видео-лекции по разным направлениям.
Некоторые из них слишком сложные и перегруженные для ютуба. Поэтому, уже начал готовить для вас на своем сайте отдельный каталог с бесплатными видео и текстовыми материалами, он появится в открытом доступе в ближайшее время.
Как раз недавно провёл в ШАД (Школа анализа данных от Яндекса) лекции на курсе Go про продвинутое тестирование и concurrency. По concurrency получилось хорошо пройтись по базе, не углубляясь в нюансы.
Из интересного, сам перед лекцией разбирался с новой реализацией sync.Map (HashTrieMap), которую добавили в Go 1.24, там все оказалось довольно интересно))
Про тестирование за 3 часа получилось рассказать почти все, что можно, начиная от устройства пакета testing, заканчивая интеграционными тестами и настройкой CI. Как раз эта большая лекция про тестирование будет одной из первых на сайте.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
8❤40 17🥰8🙏1 1