Telegram Web
Вопрос: Один из ваших товарищей по команде отправил этот код на проверку. Этот код несет потенциальную угрозу. Определите ее и предложите решение для ее устранения.

package main 

import (
"fmt"
"time"
)

func main () {
ch := make ( chan int )

go func () {
time.Sleep( 2 * time.Second)
ch <- 42
fmt.Println( "Отправлено: 42" )
}()

val := <-ch
fmt.Println( "Получено:" , val)

fmt.Println( "Продолжение выполнения..." )
}


🌟 На первый взгляд ничего подозрительного в этом коде. Если мы попробуем его запустить, он действительно скомпилируется и запустится без каких-либо заметных проблем.

[Running] go run "main.go"

Отправлено: 42
Получено: 42
Продолжение выполнения...

[Done] exited with code=0 in 2.124 seconds


💡 Сам код тоже кажется в порядке. У нас есть правильно реализованное параллельное потребление с двумя горутинами, работающими независимо. Давайте разберем код и посмотрим, что происходит:

🌟 Канал ch создан с помощью make(chan int). Это небуферизованный канал.

🌟 Запускается горутина, которая спит 2 секунды, а затем отправляет значение 42 на канал.

🌟 Основная функция выполняет операцию чтения по ch с помощью val := <-ch.

🔍 Опять же, кажется, все в порядке. Но на самом деле операция отправки задерживается. Анонимная горутина ждет 2 секунды, прежде чем отправить значение в канал. Поэтому, когда мы запускаем этот код, основная функция начинает считывать канал и ожидает там значение, прежде чем канал будет заполнен значением. Эта операция блокирует дальнейшее выполнение кода.

❗️ Подобная блокировка может вызвать серьезные проблемы с параллелизмом. Если основная горутина (или любая критическая горутина) блокируется на неопределенное время, ожидая данные, это может помешать выполнению других важных задач, что приведет к взаимоблокировкам или неотзывчивому поведению.

💡 Чтобы избежать блокирования чтения, можно использовать неблокирующие альтернативы, такие как оператор select с вариантом по умолчанию. Оператор select в Go — это мощная функция, которая позволяет goroutine ожидать несколько операций связи, что позволяет выполнять неблокирующие операции и обрабатывать несколько каналов. Оператор select работает, оценивая несколько операций канала и продолжая с первой готовой. Если несколько операций готовы, одна из них выбирается случайным образом. Если ни одна операция не готова, выполняется вариант по умолчанию, если он есть, что делает его неблокирующей операцией.

🔍 Вот его синтаксис:
select { 
case <-ch1:
// Сделать что-то, когда ch1 готов к приему
case ch2 <- value :
// Сделать что-то, когда ch2 готов к отправке
default :
// Сделать что-то, когда ни один канал не готов (неблокируемый путь)
}


🌟 Теперь исправим изначальную проблему с помощью select:
package main 

import (
"fmt"
"time"
)

func main () {
ch := make ( chan int )

// Goroutine для отправки данных в канал через 2 секунды
go func () {
time.Sleep( 2 * time.Second)
ch <- 42
fmt.Println( "Отправлено: 42" )
}()

// Основная функция, выполняющая неблокирующее чтение
for {
select {
case val := <-ch:
fmt.Println( "Получено:" , val)
fmt.Println( "Продолжение выполнения..." )
return
default :
fmt.Println( "Значения не были получены" )
time.Sleep( 500 * time.Millisecond) // Некоторое время ждем, чтобы предотвратить зацикливание
// обрабатываем поток выполнения инструкций и операций, которые должны быть продолжены
}
}
}



@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Какой тип будет иметь value при переборе string с помощью for range?
Anonymous Quiz
10%
string
31%
byte
55%
rune
3%
Посмотреть результаты
Что выведет код?
Anonymous Quiz
40%
1 1
40%
1 2
14%
0 1
6%
2 2
Что произойдёт, если мьютекс заблокирован, но горутина завершится до вызова Unlock?
Anonymous Quiz
24%
Мьютекс автоматически разблокируется
16%
Программа завершится с ошибкой
60%
Мьютекс останется заблокированным навсегда
Есть вот такой код, давайте подумаем...
Что выведет первая строка?
Anonymous Quiz
52%
[1 2 3 4 5]
11%
[1 99 3 4 5]
31%
[1 99 3 4 10]
6%
[1 2 3 4 10]
Сотрудники Авито ведут свой telegram-канал ⭐️

И знаете, получается мега-лампово и увлекательно. Всего через несколько постов начинаешь уже чувствовать себя частью их уютного офиса: рядом — знакомые весёлые коллеги из постов, и вам точно есть что обсудить.

А вообще хвалим и одобряем. Во-первых, смело и интересно. Во-вторых, для тех, кто рассматривает работу в компании, это возможность изучить культуру и вайб команды ещё до трудоустройства.

🔥 Однозначно подписка — @avito_life
🔥🔥 Если думаешь о работе в Авито, то добавляй сразу — @avito_career
Освойте Golang и станьте высокооплачиваемым разработчиком!

Хотите создавать надежные и высокопроизводительные серверные приложения? Golang — один из самых востребованных языков, который используют крупнейшие компании по всему миру.

Курс «Golang Developer. Professional» поможет вам:
- работать с высоконагруженными проектами;
- писать чистый и эффективный код;
- разбираться в архитектуре микросервисов;
- управлять взаимодействием между системами.

Разработчики на Go востребованы в топовых IT-компаниях, а зарплаты middle- и senior-специалистов начинаются от 220 000. Конкуренция пока низкая, а спрос на специалистов растет!

Для старта необходимо:
- опыт разработки backend-приложений
- знание git, работа в GitHub
- общее знакомство с CI: GitLab CI, Travis CI

➡️ Пройдите вступительное тестирование, получите скидку на курс и начните путь к высокооплачиваемой карьере: https://otus.pw/YGrF/?erid=2W5zFG962dE

Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.
2025/02/28 05:06:01
Back to Top
HTML Embed Code: