고 (프로그래밍 언어)
고(Go)는 2009년 11월 구글이 개발한 프로그래밍 언어이다. 고 언어, 고 랭귀지(Go language) 또는 간략히 고 랭(Go lang)이라고도 한다.
암호화폐인 이더리움과 디크레드 및 시그마체인, 심버스 등의 개발에 고 언어가 사용되었다.
개요
고(Go)는 2009년 구글이 개발한 프로그래밍 언어다. 가비지 컬렉션 기능이 있고, 병행성(concurrent)을 잘 지원하는 컴파일 언어이다.[1]
역사
2009년 11월에 Go가 발표되었다. 구글의 생산 시스템 중 일부 및 기타 기업들에 사용되고 있다. Go는 다른 언어의 긍정적인 특징들을 유지하면서 공통이 되는 문제들을 해결할 새로운 프로그래밍 언어를 설계하기 위해 구글의 엔지니어 Robert griesemer, 롭 파이크, 켄 톰프슨에 의해 실험적으로 시작되었다. 이 새로운 언어는 다음의 기능을 포함할 작정이었다.
- 정적 타이핑 및 대형 시스템으로의 스케일 가능할 것 (마치 자바와 C++처럼)
- 너무 많은 필수적인 키워드와 반복 없이도 생산적이고 가독성이 좋을 것 (동적 언어와 같이 가벼움)
- 통합 개발 환겨이 필요하지 않지만 지원도 가능할 것
- 네트워킹 및 다중 처리를 지원할 것
나중에 인터뷰에서 언어 설계자 3명 모두 자신들은 C++의 복잡성을 싫어하며, 이로 인해 새로운 언어를 설계하는 계기가 되었다고 언급하였다.[1]
특징
많은 사람들이 Go 언어를 두고 높은 생산성과 성능을 위한 언어라고 이야기한다. Go 언어의 주요 특징은 아래와 같다.
정적 타입, 강 타입 C/C++, Java 와 같이 Compile Time 에 Type 결정이 이루어지며, 코드 내에서 암시적 형변환이 일어나지 않는다.
컴파일 언어 C/C++, Java, C# 등과 같이 컴파일이 필요한 언어이다. Java나 C#과 달리 실행 파일을 만들어낸다. 별도의 Runtime 환경이 필요 없어 실행 환경이 복잡하지 않다.
가비지 컬렉션 실행파일 내에 Garbage Collector가 탑재되어 있다.
병행성(Concurrency) Multi Thread, Multi Core 에 Go Routine이라는 단위의 함수 실행을 한 Thread나 Core 별로 동시에 실행시킬 수 있다. Thread와 Go Routine은 1:N 관계를 이룰 수 있다.
멀티코어 환경 지원 Go Routine 간에 채널을 통해 통신하여 데이터를 공유하고 실행 순서를 제어할 수 있다. 제어는 Multi Thread의 동기화와 비슷하다.
모듈화 및 패키지 시스템 npm, pip, gem이나 Maven과 같은 모듈 의존성에 따른 패키지 관리를 언어 차원에서 지원. 인터넷 상의 패키지들을 바로 가지고 올 수 있다. import 키워드만 있으면 되고, go get이나 go install 명령으로 자동으로 패키지들을 가지고 온다.
import "github.com/kylelemons/go-gypsy/yaml"
^ ^ ^ ^ | | | `-- Package name | | `-------- Project name | `------------------- Author's handle `----------------------------- Hosting site
빠른 컴파일 속도 C/C++은 헤더 파일 처리 부담으로 컴파일 속도가 느리고 의존 관계가 복잡하다. Go는 헤더 파일이 없고 소스 코드를 패키지화하므로 변결 시 패키지만 재컴파일한다. 문법도 최대한 단순화하여 컴파일 속도도 빠르고 생산성이 좋다.[2]
장점
학습 속도가 빠르다. Go는 공식 튜토리얼만 읽으면 다른 사람이 쓴 코드를 읽고 쓰는데 아무런 문제가 없다. 물론 Go의 튜토리얼 문서가 잘 돼 있기는 하지만, 다른 언어에 비해 크게 뛰어난 것은 아니다. 그냥 Go에는 프로그램을 작성하는데 필수적인 최소 기능들만 들어가 있기 때문이다.
Channel 기반 언어 Go는 대표적인 채널 기반 언어이다. 스레드라는 것을 명시적으로 주지 않고 goroutine을 생성하면 알아서 스레드를 생성해주고 적절한 스레드에 goroutine을 할당한다. goroutine 사이의 커뮤니케이션을 전부 채널을 통해서 한다면, 귀찮은 동기화 문제를 신경 쓰지 않아도 된다.
네이티브 바이너리가 나온다. 결과를 배포하는 입장에서 네이티브 바이너리가 나온다는 것은 매우 큰 장점이다. 요즘은 대부분 서버에 파이썬이나 JVM이 설치되어 있지만, 역시 배포는 네이티브 바이너리로 하는 것이 가장 편하다.
컨벤션이 통일되어 있다. Go는 컨벤션에 대한 논쟁이 전혀 없다. go에는 컨벤션에 맞춰서 코드를 수정해주는 go fmt라는 기능이 내장되어 있다. 개발자는 그저 go fmt을 돌리기만 하면 되기 때문에, 별도로 스타일 논쟁이 발생할 일이 없다. 코드를 올리기 전에 go fmt을 돌리는 것조차 귀찮은 사람을 위해서 vim-go 같은 플러그인이 있어서 개발자는 스타일을 신경 쓰지 않고 코드를 작성하기만 해도 컨벤션에 맞출 수 있다.
인터페이스 기반의 폴리모피즘 Go에서 폴리모픽한 코드를 작성하는 유일한 방법은 인터페이스를 인자로 넘기는 것이다. 이 덕분에 인터페이스 단위의 추상화가 자연스럽게 이루어진다.[3]
문제점
verbose 한 코드 Go는 템플릿도 매크로도 없다. 이는 Go의 코드를 단순하게 만들어주는 장점도 있다. 하지만 템플릿도 매크로도 없어서 단순한 코드가 반복해서 등장한다.
type introspection 모든 폴리모피즘이 인터페이스를 기반으로 돌아가기 때문에 구체적인 구조체 타입별로 다른 동작을 하기 위해서는 type introspection을 통해서 타입을 체크해야한다. 그래서 Go는 정적 타입 언어임에도 불구하고 아래처럼 동적 언어에서나 볼법한 코드가 나온다.
어설픈 최적화 Go는 함수를 inline 시키는 최적화를 하지 않는다. 다른 언어라면 별문제 없을 수도 있다. 하지만 Go는 함수를 사용할 일이 많다. 예를 들면 자원 관리나, recover 등을 위해서 defer를 사용할 일이 많은데 defer는 함수 단위로 호출된다. 따라서 특정 시점에서 자원을 해제시키고 싶다면 새로운 함수를 만들어 새 안에서 defer 함수를 호출해야 한다. 이 모든 함수가 인라이닝 되지 않기 때문에 실제로 스택 프레임을 변경시켜가며 함수를 호출했다 해제하는 일을 한다. 라이브러리 버전 관리 Go는 언제나 하나의 실행파일을 컴파일한다. 정적 라이브러리나 동적 라이브러리를 배포할 수 없고, 소스를 가져와서 컴파일하는 방식을 사용한다. 이는 딱히 나쁜 방식이 아니다. 현대의 패키지 매니저 중 많은 것들이 이런 방식을 취한다. 문제는 Go에는 라이브러리의 버전을 명시할 방법이 없다는 것이다. 만약 사용하고 있던 라이브러리가 버전 업을 해서 인터페이스가 변경되거나 버그가 발생하거나 해서 옛 버전을 사용해야 할 경우 문제가 되는 라이브러리뿐 아니라 모든 라이브러리의 버전 업을 할 수 없다.
변화에 민감한 스타일과 문법 Go는 컨벤션이 정해져 있는 것이 장점이라고 위에서 말했다. 컨벤션이 정해져 있다는 사실은 꽤 편하다. 하지만 몇몇 부분에서 잘못된 스타일을 사용한다. 예를 들면 Go는 필드의 타입 부분을 인덴트를 맞춘다. 따라서 아래와 같이 짧은 이름의 필드만 있던 구조체에 긴 이름의 필드가 추가되면 긴 이름에 맞춰서인덴트를 바꾼다. 이런 컨벤션은 보기 좋아 보일 수도 있다. 하지만 이런 스타일은 이력을 더럽히기 때문에 좋지 않다.[3]
사례
이준성 개발자는 데브시스터즈에서 서버 개발을 맡고 있다. 데브시스터즈는 과거에 주로 자바 언어와 스프링 프레임 워크를 이용해 게임 서버를 운영했고, 파이썬, C++도 일부 사용했다. 이준성 개발자는“새 게임을 준비하면서 개발 목표들을 추가하다보니 고 언어를 고려했다."라고 설명했다. 데브시스터즈는 먼저 복잡하지 않은 서버 구조를 설계하고자 했다. 스프링 프레임 워크는 구조가 복잡하고 규모가 큰 편이다. 간단한 어플리케이션을 만드는 데에 많은 사전 작업과 지식이 요구된다. 이준성 개발자는 “복잡한 구조는 전체적인 그림을 파악하기 어렵고, 필연적으로 더 많은 버그와 잘못된 코드를 만들 거라 생각했다."라고 설명했다. 두 번째로 서버 구성 요소들의 확장성을 높이려고 했다. 이준성 개발자는 “사용자가 폭발적으로 늘어날 때 장애 없이 안정적으로 서비스를 운영하려면 서버를 쉽게 늘릴 수 있어야 하고, 반대로 서버를 쉽게 줄일 수 있으면 서버 비용을 아낄 수 있는 장점이 있다."라며 “이때 마이SQL같은 관계형 데이터 베이스는 사용량이 늘어날 때 확장하는 데에 한계가 있고, 스키마 변경이나 구조 변경 또한 자유롭지 않다”라고 설명했다. 데브시스터즈는 실제로 ‘쿠키런 포 카카오’와 ‘라인 쿠키런’을 운영할 때 마이SQL로 인해 많은 장애를 겪어서 그 이후에는 가급적이면 마이SQL 사용을 최소화하는 방향으로 구조를 설계하고 있다고 한다. 자바나 고는 정적 타입 언어다. 정적 타입 프로그램은 타입 검사가 이루어지기 때문에 프로그램을 실행할 때 조금 더 안전하다. 파이썬은 컴파일 시, 타입 검사가 이루어지지 않아 개발자가 실수할 여지가 조금 더 많다. 최근에 출시되는 CPU는 듀얼 코어, 쿼드 코어 이상이 많고, 서버용 하드웨어의 경우에는 16개 이상의 코어를 활용하는 경우도 적지 않다. CPU의 코어를 여러 개 활용하면 더 높은 성능을 낼 수 있다. 이준성 개발자는 “이때 파이썬이나 루비의 경우 GIL의 존재 때문에 2개 이상의 코어를 잘 활용하지 못한다.”라고 평가했다. 고는 초보자가 익히기 쉬운 문법이다. 이준성 개발자는 “언어 차원에서 간단한 설계와 코드를 어느 정도 권장하고 강제하기 때문에, 프로젝트에 새로운 개발자가 합류했을 때에도 상대적으로 학습 과정이 짧았다.”라며 “어떤 문제가 생겼을 때 발견하고 해결하기에도 상대적으로 용이했다.”라고 설명했다. 언어 표현력 자체만을 비교했을 때는 자바나 고나 비슷하다. 하지만 런타임에서 기본적으로 제공하는 기능에서 많은 차이가 나고, 특히 동시성, 병렬성 문제를 풀 때와 C 바인딩 같은 부분에서는 고가 월등히 코드의 양에서 차이가 난다. 이준성 개발자는 “우리가 필요한 부분에서 고가 월등하다는 뜻이고, 모든 경우에서 자바보다 짜야할 코드의 양이 적다는 뜻은 아니다.”라고 밝혔다. 자바의 경우에는 JVM 위에서 동작하는 언어이다 보니 JVM 환경 세팅과 의존 라이브러리를 패키징하는 과정이 필요하다. 제대로 성능을 내기 위해서는 JVM, 톰캣, DB 풀 등의 파라미터를 튜닝한다. 이런 튜닝 과정에 많은 리서치와 시간이 필요하다. 고의 경우에는 여러 가지 최적화와 패키징 기능을 언어 차원에서 내장하고 있고, 필요한 라이브러리를 모두 모아 하나의 정적 바이너리를 생성하기 때문에 상대적으로 배포가 간단하다. 이준성 개발자는 “사실 최근에는 도커를 통한 컨테이너 디플로이가 대세가 되어가고 있기 때문에, 언어에 따른 차이는 거의 의미가 없다고 볼 수도 있다.”라고 설명했다. 마지막으로 그는 다른 언어와 잘 결합되는 언어를 찾았다. 이준성 개발자는 “다른 언어를 활용해서 성능과 관련된 로직이나 아직 해당 언어로는 구현되어 있지 않은 라이브러리를 사용할 수 있다.”라며 “우리 팀은 ‘퀵(QUIC)‘을 사용할 때가 있어 C++과의 결합성을 주로 평가했다.”라고 설명했다. 데브시스터즈는 위 목표에 맞게 세 가지 언어를 후보로 선택해 장단점을 비교하기 시작했다.[4]
평가
Go는 장점이 분명하다. 러닝 커브가 완만하므로 팀원에 누가 들어오더라도 쉽게 적응할 수 있다. 하지만 이 점을 제외하면 단점이 장점보다 많다. 다만, 지금까지 썼던 네이티브 바이너리가 나오는 언어 중에서 가장 학습하는 데에 걸리는 시간이 짧았다는 점은 중요하다고 생각한다. 네이티브 바이너리가 나오는 것이 가장 중요한 요구 사항이라면 Go를 고려해볼 만하겠지만, 그 외의 상황에서 Go를 사용하지는 않을 것 같다.[3]
각주
- ↑ 1.0 1.1 위키백과 공식 홈페이지 - https://ko.wikipedia.org/wiki/Go_(%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D_%EC%96%B8%EC%96%B4)
- ↑ Good joon's - https://goodjoon.tistory.com/241
- ↑ 3.0 3.1 3.2 슭의 개발 블로그 - https://blog.seulgi.kim/2016/07/go.html
- ↑ BLOTER - http://www.bloter.net/archives/245951
참고자료
- 위키백과 - https://ko.wikipedia.org/wiki/Go_(%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D_%EC%96%B8%EC%96%B4)
- Good Joon's, 〈Go 언어란? - 주요 특징〉, 《Good Joon's》, 2016-02-28
- Seulgi Kim, 〈Go, programming language〉, 《슭의 개발 블로그》, 2016-07-31
- 이지현 기자, 〈그들이 자바·파이썬 대신 고(Go)를 선택한 까닭〉, 《블로터》, 2015-12-15
같이 보기