Ускорение выполнения большого количества сетевых запросов

Запустите ограниченное число работников, но синхронизируйте count++: простое добавление go создаст гонку и даст неверный счётчик.

Короткий ответ

Что ответить на собеседовании

Запустите ограниченное число работников, но синхронизируйте count++: простое добавление go создаст гонку и даст неверный счётчик.

Подробный разбор

Ответ с пояснениями

Условие

Необходимо повысить скорость выполнения функции networkRequest(), которая имитирует сетевой запрос, задерживая выполнение на time.Sleep(time.Millisecond), и увеличивает глобальный счётчик count.

import (
        "fmt"
        "time"
        )

const numRequests = 1000

var count int

func networkRequest() {
    time.Sleep(time.Millisecond)

    count++;
}

func main() {
    defer timer() ()

    for i := 0 ; i < numRequests; i++ {
        networkRequest()
    }
}

func timer() func () {
    start :=time.Now()

    return func(){
        fmt.Println("count %v took %v\n", count, time.Since(start))
       }
}

Ответ

Запустите ограниченное число работников, но синхронизируйте count++: простое добавление go создаст гонку и даст неверный счётчик.

Например, 100 работников получают задания из канала. Ниже полный минимальный вариант с тем же имитатором задержки:

package main

import (
    "fmt"
    "sync"
    "time"
)

var count int
var mu sync.Mutex

func networkRequest() {
    time.Sleep(time.Millisecond)
    mu.Lock()
    count++
    mu.Unlock()
}

func main() {
    start := time.Now()
    jobs := make(chan struct{})
    var wg sync.WaitGroup
    for i := 0; i < 100; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            for range jobs { networkRequest() }
        }()
    }
    for i := 0; i < 1000; i++ { jobs <- struct{}{} }
    close(jobs)
    wg.Wait()
    fmt.Printf("count %v took %v\n", count, time.Since(start))
}

После Wait число равно 1000. Реальное время не обязано быть ровно 10 мс: влияют планировщик и таймеры. В исходном timer для подстановки %v тоже нужен Printf, не Println.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее