Проходим собеседование на GoLang - разработчика
  • Введение
  • Общие вопросы
  • ✏️Шпаргалка по синтаксису GoLang
  • 📖GoLang теория
    • Типы данных
    • Строки
    • Массивы и слайсы
    • Мапы
    • Каналы
    • Goрутины
    • Гонка данных
    • Мьютексы
    • Контекст
    • ООП, интерфейсы
    • Другие вопросы по Go
  • 🚲GoLang Задачи
    • Задачи на строки
    • Задачи на слайсы
    • Задачи на мапы
    • Задачи на указатель
    • HTTP-запросы
    • Задачи про каналы
    • Задачи на интерфесы
    • Задачи на горутины
    • Задачи с БД
    • Задачи на defer
    • Задачи на таймер
    • Задачи на рефакторинг
    • Нерассортированные задачи
  • 🏬Базы данных
    • 🥥SQL (язык запросов)
    • 🍩Индексы
    • 🥞Транзакции
    • ✈️Масштабирование
  • 🚆Протоколы HTTP/UDP/TCP и т.д.
  • 🛞Алгоритмы
  • 🖥️Операционные системы
  • 🚢Сисдиз
  • 🤪Управление командой
Powered by GitBook
On this page
  1. GoLang Задачи

Задачи на таймер

1) Напишите функцию - троттлер trottle(f,ms), которая передает вызов в функцию f не более 1 раза в ms милисекунд, те вызовы, которые препадают на интервал простоя - должны игнорироваться. Напишите программу для демонстрации работы функции trottle.

package main

import (
	"fmt"
	"time"
)

// throttle принимает функцию f и интервал времени ms (в миллисекундах).
// Возвращает функцию, которую можно вызывать с той же частотой,
// но f будет выполняться не чаще одного раза в указанный интервал.
func throttle(f func(), ms int) func() {
	timer := time.NewTimer(0) // Создаем таймер с нулевой длительностью для немедленного первого вызова
	<-timer.C                 // Сразу же освобождаем таймер
	throttled := false        // Флаг, указывающий, активен ли таймер

	return func() {
		if !throttled {
			throttled = true
			f() // Вызываем функцию f
			timer.Reset(time.Duration(ms) * time.Millisecond)
			go func() {
				<-timer.C
				throttled = false
			}()
		}
	}
}

func main() {
	count := 0
	increment := func() {
		count++
		fmt.Println("Incremented:", count)
	}

	throttledIncrement := throttle(increment, 1000) // Создаем троттлированную версию функции increment

	// Пытаемся вызвать функцию несколько раз с интервалом в 300 мс
	for i := 0; i < 10; i++ {
		throttledIncrement()
		fmt.Println("Try:", i)
		time.Sleep(300 * time.Millisecond)
	}

	// Даем время для последнего вызова
	time.Sleep(1500 * time.Millisecond)
	fmt.Println("Final count:", count)
}

Объяснение:

1. Функция `throttle` принимает целевую функцию `f` и интервал `ms`. Она возвращает новую функцию, которая при вызове проверяет, активен ли таймер. Если таймер не активен, функция `f` вызывается, и таймер устанавливается на заданный интервал.

2. Внутри возвращаемой функции используется горутина для асинхронного ожидания окончания таймера. Как только таймер срабатывает, флаг `throttled` сбрасывается, позволяя следующему вызову функции выполнить `f` снова.

3. В функции `main` создается функция `increment`, которая увеличивает счетчик и выводит его значение. Затем создается троттлированная версия этой функции с интервалом в 1000 мс (1 секунда).

4. Цикл в `main` пытается вызвать `throttledIncrement` каждые 300 мс, но из-за троттлинга большинство вызовов игнорируются, и функция `increment` выполняется не чаще одного раза в секунду.

Этот подход позволяет контролировать частоту выполнения функции, предотвращая ее чрезмерный вызов и возможное перегружение ресурсов.

PreviousЗадачи на deferNextЗадачи на рефакторинг

Last updated 11 months ago

🚲