This media is not supported in your browser
VIEW IN TELEGRAM
Я сам решу! Что нужно идти на Golang meetup by Sber — 6 августа в 18:00! 😉
В программе 3 доклада:
🔹 «Улучшаем качество отчётов нагрузочного тестирования с помощью Go, langchain и GigaChat». Антон Юрченко, Сбер
🔹 «Не ждите ковариантности в Go — берите дженерики в работу». Станислав Иванкевич, СберТех
🔹 «Покой и любовь в тестировании сервисов на Go». Макс Теричев, YADRO
А ещё — стенды, нетворкинг и фуршет ☺️
Участвуйте как удобно: офлайн в Москве или онлайн. Ждём вас — регистрируйтесь по ссылке! 👌
В программе 3 доклада:
🔹 «Улучшаем качество отчётов нагрузочного тестирования с помощью Go, langchain и GigaChat». Антон Юрченко, Сбер
🔹 «Не ждите ковариантности в Go — берите дженерики в работу». Станислав Иванкевич, СберТех
🔹 «Покой и любовь в тестировании сервисов на Go». Макс Теричев, YADRO
А ещё — стенды, нетворкинг и фуршет ☺️
Участвуйте как удобно: офлайн в Москве или онлайн. Ждём вас — регистрируйтесь по ссылке! 👌
👎1
😁21👎2❤1
package main
import (
"fmt"
)
func tricky() (err error) {
defer func() {
fmt.Println("D1:", err) // состояние именованного результата до recover
if r := recover(); r != nil {
err = fmt.Errorf("recovered: %v", r)
}
fmt.Println("D2:", err) // состояние после recover
}()
defer func() {
panic(2) // паника №2 во время размотки стека
}()
panic(1) // паника №1
}
func main() {
fmt.Println("start")
fmt.Println("ret:", tricky())
fmt.Println("end")
}
Вопросы:
@golangtests
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🔥3👍1
😁21👎15🤬8👏5🤯3👍2
Forwarded from Golang
- Release notes: https://go.dev/doc/go1.25
- Скачать: https://go.dev/dl/#go1.25.0
Здесь можно посмотреть интерактивную версию релиза с множеством примеров, показывающих, новые фичи и посмотоеть как они работают
@golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤2🔥1🥰1
😁5🤔1
❤2👍2🤔1
Forwarded from Golang вопросы собеседований
🔎 Задача на Go с подвохом
Код:
Вопрос: Что выведет этот код?
Варианты ответа:
A.
B.
C.
D.
Правильный ответ:B
Объяснение:
1. Создается срез с длиной 3 и capacity 4, заполненный значениями [1, 2, 3]
2. При передаче в функцию modifySlice:
— append добавляет элемент 4, но не вызывает переаллокацию
— Изменение s[0] = 100 применяется к тому же underlying массиву
3. Однако исходный срез в main() останется длины 3, но первый элемент изменится:
— Длина среза в main не меняется
— Но изменения элементов видны, так как используется тот же массив
@golang_interview
Код:
package main
import "fmt"
func main() {
s := make([]int, 3, 4) // Длина 3, capacity 4
s[0], s[1], s[2] = 1, 2, 3
modifySlice(s)
fmt.Println(s)
}
func modifySlice(s []int) {
s = append(s, 4)
s[0] = 100
}
Вопрос: Что выведет этот код?
Варианты ответа:
A.
[1 2 3]
B.
[100 2 3]
C.
[1 2 3 4]
D.
[100 2 3 4]
Правильный ответ:
Объяснение:
1. Создается срез с длиной 3 и capacity 4, заполненный значениями [1, 2, 3]
2. При передаче в функцию modifySlice:
— append добавляет элемент 4, но не вызывает переаллокацию
— Изменение s[0] = 100 применяется к тому же underlying массиву
3. Однако исходный срез в main() останется длины 3, но первый элемент изменится:
— Длина среза в main не меняется
— Но изменения элементов видны, так как используется тот же массив
@golang_interview
👍10❤3
Anonymous Quiz
47%
false false false false
20%
true true false false
9%
false false true true
24%
true true true true
👍5❤2
Команда Ozon Tech готовит мощнейший трек по бэкенду в рамках своей конференции E-CODE 💙
И это только одна из причин, почему стоит быть там 13-14 сентября. А ещё: качественный нетворк, 1х1 с топовыми IT-экспертами и HR, эксклюзивный мерч и интерактивы, вечеринки с участием НТР, Заточки, ILWT и Нейромонаха Феофана.
Успейте зарегистрироваться. Это обязательно⬅
И это только одна из причин, почему стоит быть там 13-14 сентября. А ещё: качественный нетворк, 1х1 с топовыми IT-экспертами и HR, эксклюзивный мерч и интерактивы, вечеринки с участием НТР, Заточки, ILWT и Нейромонаха Феофана.
Успейте зарегистрироваться. Это обязательно
Please open Telegram to view this post
VIEW IN TELEGRAM
🎯 Задача (Go, продвинутая конкуррентность; версия: Go 1.21+)
Сделай универсальную функцию обработки массива с контролем параллельности, сохранением исходного порядка результатов и мгновенной отменой при первой ошибке.
🟠 Требования:
- Сигнатура:
Process[T any, R any](ctx context.Context, in []T, worker func(context.Context, T) (R, error), parallelism int) ([]R, error)
- Параллельная обработка не более parallelism задач одновременно.
- Результаты возвращаются в том же порядке, что и входной срез, даже если отдельные задачи завершаются вразнобой.
- При первой ошибке:
- немедленно отменить все ещё выполняющиеся задачи,
- вернуть первую ошибку,
- не оставить «утекших» горутин.
- Учитывать ctx.Done() и корректно завершаться по таймауту/отмене.
- Без внешних зависимостей; только стандартная библиотека.
🟠 Подсказка:
- Используй context.WithCancelCause для распространения причины отмены.
- Организуй пул рабочих через буферизованный канал с задачами.
- Результаты складывай по индексу, чтобы сохранить порядок.
- Для потокозащищённой фиксации первой ошибки используй sync.Once.
Ниже — эталонная реализация и пример использования.
Код (Go 1.21+):
🟠 Как проверить:
- go run . — запусти несколько раз, чтобы увидеть разные порядки завершения, но стабильный порядок результатов.
- Поменяй порог ошибки в worker (например, x%3==0), чтобы убедиться, что отмена срабатывает мгновенно и горутины не висят.
- Проверь на гонки: go run -race .
Сделай универсальную функцию обработки массива с контролем параллельности, сохранением исходного порядка результатов и мгновенной отменой при первой ошибке.
- Сигнатура:
Process[T any, R any](ctx context.Context, in []T, worker func(context.Context, T) (R, error), parallelism int) ([]R, error)
- Параллельная обработка не более parallelism задач одновременно.
- Результаты возвращаются в том же порядке, что и входной срез, даже если отдельные задачи завершаются вразнобой.
- При первой ошибке:
- немедленно отменить все ещё выполняющиеся задачи,
- вернуть первую ошибку,
- не оставить «утекших» горутин.
- Учитывать ctx.Done() и корректно завершаться по таймауту/отмене.
- Без внешних зависимостей; только стандартная библиотека.
- Используй context.WithCancelCause для распространения причины отмены.
- Организуй пул рабочих через буферизованный канал с задачами.
- Результаты складывай по индексу, чтобы сохранить порядок.
- Для потокозащищённой фиксации первой ошибки используй sync.Once.
Ниже — эталонная реализация и пример использования.
Код (Go 1.21+):
package main
import (
"context"
"errors"
"fmt"
"math/rand"
"sync"
"time"
)
type job[T any] struct {
i int
val T
}
func Process[T any, R any](
parent context.Context,
in []T,
worker func(context.Context, T) (R, error),
parallelism int,
) ([]R, error) {
if parallelism <= 0 {
return nil, errors.New("parallelism must be > 0")
}
ctx, cancel := context.WithCancelCause(parent)
defer cancel(nil)
jobs := make(chan job[T], parallelism) // лёгкая обратная давление
out := make([]R, len(in))
var wg sync.WaitGroup
var once sync.Once
var firstErr error
// Рабочие
workerFn := func() {
defer wg.Done()
for {
select {
case <-ctx.Done():
return
case j, ok := <-jobs:
if !ok {
return
}
res, err := worker(ctx, j.val)
if err != nil {
once.Do(func() {
firstErr = err
cancel(err) // прерываем остальных
})
return
}
// Сохраняем порядок
out[j.i] = res
}
}
}
// Старт пула
wg.Add(parallelism)
for k := 0; k < parallelism; k++ {
go workerFn()
}
// Диспетчер задач
sendLoop:
for i, v := range in {
select {
case <-ctx.Done():
break sendLoop
case jobs <- job[T]{i: i, val: v}:
}
}
close(jobs)
// Ждём завершения
wg.Wait()
// Если была отмена по ошибке — вернём её
if firstErr != nil {
return nil, firstErr
}
// Если отменил родительский контекст — вернём его причину
if err := context.Cause(ctx); err != nil && !errors.Is(err, context.Canceled) && !errors.Is(err, context.DeadlineExceeded) {
// это cause из cancel(err), уже обработали выше
} else if err := context.Cause(parent); err != nil {
return nil, err
}
return out, nil
}
// Демонстрация: умножаем числа с случайной задержкой; каждое третье число — ошибка.
// Видно, что вывод упорядочен по входу, а отмена срабатывает на первой ошибке.
func main() {
rand.New(rand.NewSource(time.Now().UnixNano()))
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
input := []int{1, 2, 3, 4, 5, 6, 7}
parallelism := 3
worker := func(ctx context.Context, x int) (int, error) {
// эмуляция непредсказуемого времени работы
time.Sleep(time.Duration(rand.Intn(120)) * time.Millisecond)
if x%7 == 0 { // попробуй поменять условие на (x%3==0), чтобы увидеть раннюю отмену
return 0, fmt.Errorf("bad luck on %d", x)
}
select {
case <-ctx.Done():
return 0, ctx.Err()
default:
return x * x, nil
}
}
res, err := Process[int, int](ctx, input, worker, parallelism)
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println("results:", res)
}
- go run . — запусти несколько раз, чтобы увидеть разные порядки завершения, но стабильный порядок результатов.
- Поменяй порог ошибки в worker (например, x%3==0), чтобы убедиться, что отмена срабатывает мгновенно и горутины не висят.
- Проверь на гонки: go run -race .
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍2🔥2
Anonymous Quiz
6%
data.val = <nil>
7%
data.val = 0
84%
data.val = 5
3%
data.val = undefined
😁3❤1👍1👎1