Ответ
Конечно, вот несколько классических примеров, которые часто встречаются в бэкенд-разработке на Go.
1. Простой HTTP-сервер
Это базовый пример для любого веб-сервиса. Он показывает, как запустить сервер и обработать входящий HTTP-запрос.
package main
import (
"fmt"
"log"
"net/http"
)
// handler обрабатывает запросы к корневому URL "/".
func handler(w http.ResponseWriter, r *http.Request) {
// Fprintf записывает форматированную строку в ResponseWriter.
fmt.Fprintf(w, "Привет, мир! Это мой первый веб-сервер на Go.")
}
func main() {
// Регистрируем наш обработчик для всех запросов к "/".
http.HandleFunc("/", handler)
// Запускаем сервер на порту 8080.
// ListenAndServe блокирует выполнение, пока сервер работает.
fmt.Println("Сервер запущен на http://localhost:8080")
err := http.ListenAndServe(":8080", nil)
if err != nil {
log.Fatal("Ошибка запуска сервера: ", err)
}
}
2. Конкурентная обработка задач (Worker Pool)
Этот пример демонстрирует мощь горутин и каналов для параллельного выполнения задач. Паттерн Worker Pool очень популярен для обработки фоновых задач, например, отправки email или обработки изображений.
package main
import (
"fmt"
"sync"
"time"
)
// worker — это горутина, которая получает задачи из канала `jobs`
// и отправляет результат в канал `results`.
func worker(id int, wg *sync.WaitGroup, jobs <-chan int, results chan<- int) {
defer wg.Done() // Сообщаем WaitGroup, что воркер завершил работу
for j := range jobs {
fmt.Printf("Воркер %d начал задачу %dn", id, j)
time.Sleep(time.Second) // Имитация долгой работы
results <- j * 2
fmt.Printf("Воркер %d закончил задачу %dn", id, j)
}
}
func main() {
const numJobs = 5
jobs := make(chan int, numJobs)
results := make(chan int, numJobs)
var wg sync.WaitGroup
// Запускаем 3 воркера
for w := 1; w <= 3; w++ {
wg.Add(1) // Увеличиваем счетчик WaitGroup
go worker(w, &wg, jobs, results)
}
// Отправляем 5 задач в канал jobs
for j := 1; j <= numJobs; j++ {
jobs <- j
}
close(jobs) // Закрываем канал, чтобы воркеры завершились после выполнения всех задач
// Ждем, пока все воркеры завершат свою работу
wg.Wait()
// Закрываем канал с результатами, так как больше записей не будет
close(results)
// Собираем результаты
for r := range results {
fmt.Println("Получен результат:", r)
}
}