Go
Golang
Google이 개발한 시스템 언어. 고루틴으로 동시성 지원. Docker, K8s에 사용.
Golang
Google이 개발한 시스템 언어. 고루틴으로 동시성 지원. Docker, K8s에 사용.
Go(Golang)는 2009년 Google의 Robert Griesemer, Rob Pike, Ken Thompson이 개발한 정적 타입 컴파일 언어입니다. C++의 복잡성과 긴 컴파일 시간에 대한 불만에서 시작되어, 단순함과 효율성을 핵심 설계 철학으로 삼았습니다. Go는 "적게 하면서 더 많이 이루는" 언어로, 배우기 쉽고 읽기 쉬운 코드를 작성할 수 있습니다.
Go의 가장 강력한 특징은 고루틴(goroutine)과 채널(channel)을 통한 동시성 프로그래밍입니다. 고루틴은 OS 스레드보다 훨씬 가벼워서 수만 개를 동시에 실행할 수 있으며, 채널을 통해 고루틴 간 안전하게 데이터를 주고받습니다. "공유 메모리로 통신하지 말고, 통신으로 메모리를 공유하라"는 Go의 철학이 이를 잘 보여줍니다.
Go는 가비지 컬렉션을 제공하면서도 네이티브 바이너리로 컴파일되어 뛰어난 실행 성능을 제공합니다. 크로스 컴파일이 내장되어 있어 단일 코드베이스에서 Linux, Windows, macOS용 실행 파일을 쉽게 빌드할 수 있습니다. 컴파일 속도가 매우 빨라 대규모 프로젝트도 몇 초 만에 빌드됩니다.
실무에서 Go는 Docker, Kubernetes, Terraform, etcd 등 클라우드 네이티브 생태계의 핵심 도구들에 사용됩니다. 마이크로서비스, API 서버, CLI 도구, DevOps 인프라 개발에 특히 강점이 있으며, Netflix, Uber, Dropbox, Cloudflare 등 대규모 서비스에서 널리 채택하고 있습니다.
package main
import (
"fmt"
"net/http"
"sync"
"time"
)
// 1. 기본 HTTP 서버
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "안녕하세요! 현재 시간: %s", time.Now().Format("15:04:05"))
}
// 2. 고루틴과 채널을 활용한 동시성 처리
func fetchURLs(urls []string) map[string]int {
results := make(map[string]int)
ch := make(chan struct{ url string; status int })
var wg sync.WaitGroup
for _, url := range urls {
wg.Add(1)
go func(u string) {
defer wg.Done()
resp, err := http.Get(u)
if err != nil {
ch <- struct{ url string; status int }{u, 0}
return
}
defer resp.Body.Close()
ch <- struct{ url string; status int }{u, resp.StatusCode}
}(url)
}
go func() {
wg.Wait()
close(ch)
}()
for result := range ch {
results[result.url] = result.status
}
return results
}
// 3. 구조체와 메서드
type User struct {
ID int
Name string
}
func (u *User) Greet() string {
return fmt.Sprintf("안녕하세요, %s님!", u.Name)
}
func main() {
// HTTP 서버 시작
http.HandleFunc("/", helloHandler)
fmt.Println("서버 시작: http://localhost:8080")
http.ListenAndServe(":8080", nil)
}
"이 마이크로서비스는 Go로 개발하면 좋겠습니다. 고루틴으로 수천 개의 동시 요청을 효율적으로 처리할 수 있고, 단일 바이너리로 배포가 간편해서 Docker 이미지 크기도 10MB 이하로 줄일 수 있어요."
"Go의 동시성 모델에서 고루틴은 M:N 스케줄링을 사용합니다. 여러 고루틴이 OS 스레드 위에 다중화되어 컨텍스트 스위칭 비용이 적습니다. 채널을 통한 통신은 뮤텍스보다 데이터 레이스를 방지하기 쉽고, select 문으로 여러 채널을 동시에 대기할 수 있습니다."
"이 고루틴에서 생성한 채널을 닫지 않아서 고루틴 리크가 발생할 수 있습니다. defer로 close(ch)를 추가하거나, context를 사용해서 취소 시그널을 전파하는 방식으로 수정해주세요."
Go는 예외 대신 에러 값을 반환합니다. `result, _ := someFunc()`처럼 에러를 무시하면 런타임에 예상치 못한 문제가 발생합니다. 항상 `if err != nil` 체크를 하세요.
채널에서 영원히 대기하거나 종료 조건 없이 실행되는 고루틴은 메모리 누수를 일으킵니다. context.WithCancel이나 context.WithTimeout을 사용해 고루틴의 생명주기를 관리하세요.
go mod init으로 모듈을 초기화하고, go mod tidy로 의존성을 정리하세요. go.sum 파일은 버전 관리에 포함하여 재현 가능한 빌드를 보장합니다.