왜 나는 백엔드 엔지니어링에 Go를 선택했는가 (장점·단점, 그리고 솔직한 트레이드오프)
Source: Dev.to
위에 있는 Source 라인만 그대로 두고, 번역하고 싶은 본문 내용을 제공해 주시면 한국어로 번역해 드리겠습니다.
Introduction
제가 백엔드 개발에 Go를 사용한다고 말하면 가장 흔히 듣는 반응은 다음과 같습니다:
- “왜 Java가 아니에요?”
- “Go가 너무 단순하지 않나요?”
- “Rust가 더 멋지지 않나요?”
저는 Go가 트렌디해서 혹은 트위터에 누가 미래라고 말해서 선택한 것이 아닙니다. 이 글은 Go 튜토리얼이 아니라 제가 Go를 사용하는 이유, Go가 잘하는 점, 저를 좌절시키는 점, 그리고 왜 여전히 백엔드 엔지니어링에 Go를 고수하는지에 대한 이야기입니다.
Go를 사용하기 전, 제 백엔드 지식은 조각조각 나뉘어 있었습니다:
- API를 어떻게 작성하는지 알았다
- 데이터베이스를 어떻게 연결하는지 알았다
- 시스템보다는 프레임워크에 더 익숙했다
로드, 장애, 동시성 상황에서 백엔드가 실제로 무엇을 하고 있는지 이해하지 못했습니다. 동시에 대학에서 운영체제, 컴퓨터 네트워크, DBMS를 공부하고 있었죠. 그때 Go가 딱 맞아떨어졌습니다.
Go의 단순성
Go는 “너무 단순하다”는 비판을 자주 받습니다. 화려한 문법이 없어서 처음에는 제약처럼 느껴질 수 있습니다. 하지만 이러한 단순성은 다음을 강요합니다:
- 읽기 쉬운 코드를 작성하게 함
- 추상화를 추가하기 전에 생각하게 함
- 결정을 명시적으로 만들게 함
백엔드 시스템을 구축할 때는 영리함보다 명확함이 더 중요합니다.
오류 처리
Go에는 예외가 없습니다. 실패를 숨기는 대신 직접 마주하게 합니다:
result, err := doSomething()
if err != nil {
return err
}
처음에는 반복적인 것처럼 느껴지지만 중요한 교훈을 줍니다: 백엔드 시스템은 항상 실패합니다—실패를 무시하는 것은 위험합니다. 명시적인 오류 처리는 다음을 촉진합니다:
- 실패 경로를 고려하게 함
- 더 안전한 API 설계
- “행복한 경로만” 생각하는 것을 방지
이는 운영체제와 DBMS 개념과도 잘 맞습니다.
동시성 모델
스레드, 컨텍스트 스위칭, 동기화, 레이스 컨디션과 같은 OS 개념을 공부한 후, Go의 동시성 모델은 솔직하게 느껴졌다. 고루틴은 가볍지만 마법은 아니다. Go는 버그가 있는 동시성 코드를 작성하는 것을 막지 않는다; 동시성을 숨기지 않고 눈에 보이게 만든다.
그 가시성은 중요하다, 왜냐하면 Go는 다음으로부터 당신을 구해주지 않기 때문이다:
- 레이스 컨디션
- 교착 상태
- 부실한 동기화 설계
여전히 규율, 이해, 그리고 테스트가 필요하며—나는 오히려 그것이 좋다.
백엔드 작업에 실용적인 적합성
기본 제공되는 Go는 다음을 제공합니다:
- HTTP 서버
- 네트워킹 기본 요소
- 인코딩/디코딩 유틸리티
- 동시성 도구
시작하기 위해 수십 개의 라이브러리가 필요하지 않습니다. Go는 또한 다음을 제공합니다:
- 좋은 성능
- 예측 가능한 메모리 사용량
- 빠른 시작 시간
수동 메모리 관리나 지나치게 복잡한 언어 규칙 없이 모두 가능합니다. 백엔드 서비스에 이 균형은 강력합니다.
배포 장점
- 단일 정적 바이너리
- 최소 런타임 의존성
- 쉬운 컨테이너화
프로젝트를 배포하는 학생으로서, 이 감소된 마찰은 크게 도움이 됩니다.
단점 및 제한 사항
Go 코드는 반복적이라고 느껴질 수 있습니다:
- 어디서든 오류 검사
- 일부 패턴에서 보일러플레이트
이는 작은 스크립트에서 속도를 늦출 수 있습니다. 이제 제네릭이 존재하지만, 의도적으로 보수적이며 일부 패턴은 여전히 어색합니다. 강력한 제네릭을 제공하는 언어에서 온 경우 제한적으로 느껴질 수 있습니다.
Go를 사용하면 안 되는 경우
- UI‑중심 애플리케이션
- 복잡한 도메인‑중심 비즈니스 로직
- 단순성보다 표현력 있는 타입 시스템이 더 중요한 상황
Go는 시스템 및 서비스에 강점이 있으며, 모든 곳에 적합한 것은 아닙니다.
정신 모델의 이점
생산성을 넘어, Go는 나에게 명확한 정신 모델을 제공했습니다:
- 코드가 무엇을 하는지 이해한다
- 동시성을 존중한다
- 실패에 대해 생각한다
- 기능만이 아니라 시스템을 구축한다
그 기반은 여러 프레임워크를 배우는 것보다 더 중요합니다.
다른 언어와의 비교
Go가 모든 것보다 “더 낫다”고 생각하지는 않습니다:
- Java는 방대한 생태계를 가지고 있습니다
- Rust는 더 강력한 안전 보장을 제공합니다
- Python은 놀라울 정도로 생산적입니다
Go는 단순하고, 빠르며, 시스템에 대해 솔직한 절충점에 위치합니다—백엔드 엔지니어링에 잘 맞는 트레이드‑오프입니다.
지속적인 학습
- 더 나은 동시성 패턴
- 분산 시스템
- 관측성
- 데이터베이스 내부 구조
- 시스템 설계 트레이드오프
Go가 이 문제들을 해결해 준 것은 아니지만, 문제들을 눈에 보이게 만들었으며, 그것이 더 중요합니다.
백엔드 언어 선택
백엔드 언어를 선택하는 것은 과대광고에 관한 것이 아니라; 다음과 관련이 있습니다:
- 생각하는 방식을 어떻게 형성하는가
- 실패를 어떻게 처리하는가
- 복잡성이 증가함에 따라 어떻게 확장되는가
저에게 Go는 CS 기본 개념과 실제 백엔드 시스템 사이의 격차를 메우는 데 도움이 되었으며, 이것이 무엇보다 중요했습니다.
읽어 주셔서 감사합니다 — 아직 배우고 있고, 아직 만들고 있습니다.