В чём заключается ‘killer feature’ языка Go, выделяющая его среди других?

Ответ

Ключевая особенность Go — это встроенная модель конкурентности (concurrency), основанная на горутинах (goroutines) и каналах (channels).

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

1. Горутины (Goroutines):

  • Это легковесные потоки, управляемые средой выполнения Go, а не операционной системой.
  • Их стек изначально очень мал (около 2 КБ) и может расти по мере необходимости. Можно легко запустить сотни тысяч и даже миллионы горутин одновременно.
  • Запускаются с помощью простого ключевого слова go.

2. Каналы (Channels):

  • Это типизированные "трубы", через которые горутины могут безопасно обмениваться данными, не прибегая к традиционным блокировкам (мьютексам).
  • Они реализуют философию Go: "Do not communicate by sharing memory; instead, share memory by communicating." (Не общайтесь, разделяя память; вместо этого разделяйте память, общаясь).

Пример: Worker Pool
Этот код создает пул из 3-х воркеров, которые конкурентно обрабатывают задачи из канала jobs и отправляют результаты в канал results.

package main

import (
    "fmt"
    "time"
)

// worker получает задачи из канала jobs и отправляет результат в results
func worker(id int, jobs <-chan int, results chan<- int) {
    for j := range jobs {
        fmt.Printf("worker %d started job %dn", id, j)
        time.Sleep(time.Second) // Имитация работы
        results <- j * 2
        fmt.Printf("worker %d finished job %dn", id, j)
    }
}

func main() {
    const numJobs = 5
    jobs := make(chan int, numJobs)
    results := make(chan int, numJobs)

    // Запускаем 3 воркера
    for w := 1; w <= 3; w++ {
        go worker(w, jobs, results)
    }

    // Отправляем 5 задач в канал jobs
    for j := 1; j <= numJobs; j++ {
        jobs <- j
    }
    close(jobs) // Закрываем канал, чтобы воркеры завершились после выполнения всех задач

    // Собираем результаты
    for a := 1; a <= numJobs; a++ {
        <-results
    }
}