Карточка товара собирается из двух частей. Описание берётся из одного
источника и проходит нормализацию. Цена берётся из другого источника в
долларах и пересчитывается в рубли. Функции-заглушки уже даны, их не меняем.
Нужно реализовать сборку карточки.
// даны, не трогаем
var fetchDesc = func(id int) string {
time.Sleep(time.Second)
return "Lorem ipsum dolor sit amet..."
}
var fetchUSDPrice = func(id int) float64 {
time.Sleep(2 * time.Second)
return 100
}
var normalize = func(desc string) string {
time.Sleep(time.Second)
re := regexp.MustCompile(`\W+`)
return re.ReplaceAllString(desc, "")
}
var toRub = func(usd float64) float64 {
time.Sleep(time.Second)
return usd * 70
}
type Card struct {
PriceRub float64
Desc string
}
func BuildCard(id int) Card
Требования
Desc = normalize(fetchDesc(id)), PriceRub = toRub(fetchUSDPrice(id)).
Каждая функция вызывается ровно один раз.
- Две ветки независимы и идут параллельно: обработка каждой
(
normalize / toRub) начинается сразу, как только готовы её данные, а не
после того, как закончит соседняя ветка. Для заглушек выше сборка занимает
≈ 3 с (самая длинная ветка), а не 5 с (сумма).
- После возврата горутин не остаётся. Код проходит
go test -race.
Пример
card := BuildCard(42) // ≈ 3 с
// Card{PriceRub: 7000, Desc: "Loremipsumdolorsitamet"}
func BuildCards(ids []int, limit int) []Card
- Собирает карточки для всех
ids, result[i] — карточка ids[i].
- Одновременно собирается не больше
limit карточек (limit < 1 считается
как 1), и лимит используется полностью: если карточек хватает, собираются
limit одновременно.
Устно:
- Нужна ли синхронизация, если две горутины пишут в разные поля одной структуры
Card?
- Что делать, если сетевой вызов упал: вернуть частичную карточку, цену в
долларах, ретраить? Как поменяется сигнатура?
- Какой таймаут поставить на внешние вызовы и как его прокинуть?
Разбор и эталонное решение — после своей попытки: на собеседовании подсказок не будет.
Сначала попробуй сам — подсказки не дают готовый ответ.