[Golang] 특징과 장점
Go언어(Golang)
Go언어를 단순하게 표현하면 아래와 같다.
- Simplicity
- Pragmatism
- Concurrency
- Scalability
- Compile Language
- Cross Platform
Not the feature of Go
- No classes
- No inheritance
- No constructors
- No final
- No exceptions
- No annotations
- No user-defined generics
Go언어는 2009년에 구글이 만든 프로그래밍 언어다. Go언어는 데니스 리치와 함께 유닉스와 C언어를 개발한 켄 톰슨 외 컴퓨터 과학계에서 저명한 롭 파이크, 로버트 그리즈머에 의해 설계 및 개발되었다. "40년 동안의 프로그래밍 언어에 대한 연구를 던져버린 유일한 언어"라는 평가를 받고 있다.
Go라는 이름으로 검색하기 힘들다면 golang(go language) 또는 외국에서 많이 부르는 gopher라고 검색하면 편하다.
- 빠른 개발속도
- 모듈화를 위한 의존성
- 정적타입이지만 동적타입 언어의 속성도 가진 언어
- Garbage Collection with no VM
- 쉬운 병렬처리
- 빠른 컴파일 속도
- 소스코드 UTF-8
Simplicity
프로그래밍 언어에서는 기본적으로 사용되는 if
, switch
등과 같은 키워드들이 정의되어 있다. Go언어는 25개의 키워드만으로 프로그래밍이 가능하며, 이는 자바의 절반에 해당하는 수준이다. 무조건 키워드가 적다고 간단하고 배우기 쉬운 언어는 아니지만 일단 키워드가 적으면 문법 익히는 것이 빨라지며 복잡도가 떨어질 수 있다.
또한 가비지 컬렉터가 있어 C와 C++과 달리 메모리 관리를 신경쓰지 않아도 된다. 메모리를 직접 할당하고 해제하는 작업이 없음에도 C와 C++처럼 포인터가 존재한다. 이 부분도 Go언어의 흥미로운 점 중 하나이다.
클라우드와 친한 언어
단순함과 병렬성 등의 특징으로 인해 클라우드 환경, 그리고 최근 주목받고 있는 마이크로 서비스 아키텍처에 적절한 프로그래밍 언어로 평가받고 있다.
컴파일 언어
컴파일 언어지만 컴파일러의 컴파일 속도가 매우 빨라서 인터프리터 언어처럼 사용할 수 있다. 예를 들어 특정 코드를 짜놓고 go run
으로 돌리면 마치 파이썬을 사용하는 것처럼 빠르고 간편하게 사용할 수 있다.
자바나 C#처럼 특정 환경에서만 돌아가는 바이트코드를 생성하는 방식이 아닌 C, C++처럼 완전한 네이티브 바이너리 실행파일을 만들어 낸다. 따라서 가상머신도 필요 없어서 실행환경이 간단하며, 실행파일 내에 라이브러리를 포함하여 배포가 쉽다.
단, 바이너리 컴파일러이기 때문에 서로 다른 플랫폼을 타겟으로 배포해야 할 경우 환경변수인 GOOS와 GOARCH 등을 재설정한 후 컴파일해서 여러 개의 배포한을 만들어야 한다.
Goroutine
Go는 Goroutine이라는 언어 차원에서 동시성과 병렬성을 지원한다. Goroutine은 멀티쓰레드 매커니즘의 경량 쓰레드 방식이며 자체적인 스케줄러에 의해 관리되기 때문에 OS에서 관리하는 쓰레드보다 더 가볍고 높은 성능을 보장한다. 자바의 쓰레드의 경우 1MB의 메모리가 필요하지만 go는 2KB의 스택 공간만 필요하다. Context switching 비용 또한 고루틴이 더 적다. 쓰레드는 blocking될 경우 다른 쓰레드가 그 자리를 스케줄링한다. 이렇게 바뀌는 과정에서 모든 레지스터들을 저장 및 복구해야 한다. 쓰레드는 16개의 범용 레지스터, PC, SP, segment 레지스터, 16개의 XMM 레지스터 등 많은 것들을 저장 및 복구해야 하지만 Goroutine은 3개의 레지스터(PC, SP, DX)만 저장 및 복구하면 된다.
Goroutine은 일급 객체(First Class)로 정수나 실수와 같은 데이터 타입과 동급으로 취급된다.
비동기 메커니즘을 제공한다. Go의 병행 처리 방식은 Communicating Sequential Processes(CSP) 방식에 근간을 두고 있어서 메모리를 공유하는 것이 아니라 메시지를 전달하는 방식으로 동기화가 된다. 각각의 고루틴은 병렬로 동작하며 메시지 채널을 통해 값을 주고 받는다. 고루틴을 사용하면 이벤트 처리, 병렬 프로그래밍 등이 훨씬 간단해진다. 단, 병렬화된 고루틴의 동기화 문제는 프로그래머가 다뤄야 하며 동기화를 무시할 경우 프로그램이 비정상 종료될 수도 있다.
goroutine은 OS 쓰레드보다 훨씬 가볍게 비동기 concurrent 처리를 구현하기 위해 만든 것으로, 기본적으로 Go 런타임이 자체 관리한다. Go 런타임 상에서 관리되는 작업단위인 여러 goroutine들은 종종 하나의 OS쓰레드 1개로도 실행되곤 한다. 즉, goroutine들은 OS쓰레드와 1:1 대응되지 않고, multiplexing으로 훨씬 적은 OS쓰레드를 사용한다. 메모리 측면에서도 OS쓰레드가 1메가바이트의 스택을 갖는 반면, goroutine은 이보다 훨씬 작은 몇 킬로바이트의 스택을 갖는다. 필요시 동적으로 증가할 수도 있다.
가비지 컬렉터
자바와 같이 주로 가상머신 위에서 실행되는 언어들은 별도의 플랫폼 위에서 인스턴스의 할당 및 해제 작업을 해줌으로써 메모리를 관리하는 가비지 컬렉터가 존재한다. Go도 역시 가비지 컬렉터가 있지만 실행파일 내에 내장되어 있어 별도의 가상머신이나 플랫폼이 필요하지 않다.
패키지
Go는 언어 자체적으로 python의 pip나 java의 maven와 같은 온라인 상의 패키지나 의존성을 관리해주는 기능이 내장되어 있다. 소스코드 내에서 import
키워드를 통해 github와 같은 인터넷 저장소의 주소를 지정해서 가져올 수 있다.
참고자료 및 요약
- Go언어는 병렬 프로그래밍과 네트워크 프로그래밍에 특화되어 있다.
- Go는 C언어가 진화된 것으로 C++과는 다르다.
- 고루틴은 stateless에서는 아주 좋지만 statefull에서는 한계가 있다.
- 대규모 분산 게임 서버에는 Front Server(클라이언트와 서버 간의 패킷 전달)는 stateless에 가깝고, 컨텐츠 로직이 없으므로 Go언어를 사용하면 아주 좋다.
- 메모리 자동 관리
- VM이 아니다!
- 네트워크 프로그래밍
- 병렬 프로그래밍
- goroutine
- 크로스 플랫폼 개발이 쉽다
- 네트워크에서 IOCP 지원