이 칼럼은 기술적인 심층 내용을 중심으로 소프트웨어 분야의 관련 지식을 포괄적으로 해석하며, 주로 프로그래밍 언어, 시스템 아키텍처, 오픈 소스 프레임워크, 기술 관리 등을 다룹니다. 각 주제에는 여러 기사가 포함되어 있습니다.
이 기사는 칼럼의 첫 번째 기사이자 GO 언어 시리즈의 첫 번째 기사입니다. 오늘은 GO 언어에 대한 전반적인 인상을 모든 측면에서 전달하고 싶습니다. 후속 기사에서는 각 기능과 프로그래밍 기술을 소개합니다. 깊이.
소개
역사부터 Go 언어의 저자는 Robert Griesemer, Rob Pike 및 Ken Thompson입니다. 그중 Ken Thompson은 UNIX 및 C 언어 개발에 큰 공헌을 한 것으로 프로그래머들에게 잘 알려져 있습니다. 지금까지 Go에서는 어떤 소프트웨어가 작성되었나요? 컨테이너 소프트웨어 Docker, 기본 소프트웨어 ETCD 및 Kubernetes, 데이터베이스 소프트웨어 TiDB 및 InfluxDB, 메시징 시스템 NSQ, 캐싱 구성 요소 GroupCache.
인프라 소프트웨어의 거의 모든 분야에서 Go 언어로 작성된 새로운 소프트웨어가 등장했으며 이러한 소프트웨어의 시장 점유율이 계속 상승하고 있음을 알 수 있습니다. Go 언어는 인프라 소프트웨어를 위한 언어일 뿐만 아니라 서버 측 범용 언어로서 점점 더 많은 기회를 갖고 있습니다. Beego 및 Gorilla와 같은 Go 언어 웹 프레임워크의 인기에서도 일부 개발 추세를 볼 수 있습니다.
샘플 프로그램
간단한 샘플 프로그램을 통해 GO의 코딩 스타일을 살펴보겠습니다.
Package main
import "fmt"
func main(){
fmt.Println ("hello, world");
}
위 코드를 실행하는 방법 GO 언어는 컴파일된 언어입니다. GO의 도구 체인은 프로그램의 소스 파일을 기계 관련 기본 명령어(바이너리)로 변환합니다. 가장 기본적인 도구는 하나 이상의 GO 소스 파일(접미사로 .go 사용)을 컴파일하고 링크할 수 있는 실행 명령입니다. 링크한 후 생성된 실행 파일이 실행되기 시작합니다.
1 .$go run helloworld.go
Print: hello, world
위의 컴파일, 링크, 실행은 모두 일회성 작업이므로 다음에 go run 명령을 실행할 때 모든 내부 프로세스가 다시 할 것입니다. go build 명령을 통해 바이너리 프로그램을 생성한 다음 아래와 같이 임의로 호출할 수 있습니다.
$go build helloworld.go
$./helloworld
hello,world
여기서 컴파일된 언어에 대해 언급했습니다. 컴파일된 언어로 작성된 프로그램을 기계에서 인식하려면 컴파일과 링크라는 두 단계를 거쳐야 합니다. 소스 코드를 기계어 코드로 컴파일하는 것입니다. , 링크는 각각을 변환하는 것입니다. 모듈의 기계어 코드와 종속 라이브러리를 연결하여 실행 파일을 생성합니다.
컴파일된 언어의 장점과 단점을 살펴보겠습니다. 사전 컴파일 프로세스가 있기 때문에 코드를 최적화할 수 있으며 한 번만 컴파일하면 런타임 효율성이 높아지고 실행될 수 있습니다. 단점은 수정된 모듈 전체를 컴파일해야 한다는 것입니다.
컴파일 언어에 비해 해석 언어는 프로그램 실행 시 한 줄씩만 번역합니다. 그렇다면 링크란 무엇입니까? 정확하게 말하면 링크와 로딩, 즉 컴파일 후에 이 두 단계를 수행하여 프로그램이 메모리에서 실행될 수 있도록 하는 것입니다. 연결은 여러 대상 파일을 완전하고 로드 가능하며 실행 가능한 대상 파일로 연결하는 커넥터를 통해 완료됩니다. 전체 프로세스에는 기호 확인(대상 파일의 응용 프로그램 기호를 해당 정의와 연결)과 기호 연결이 포함됩니다. 메모리 위치를 사용한 정의.
명명 규칙
GO 언어의 함수, 상수, 변수, 유형, 명령문, 레이블 및 패키지의 이름은 비교적 균일한 명명 규칙을 따릅니다. 이름은 문자나 밑줄로 시작하고 뒤에는 어떤 숫자도 올 수 있습니다. 문자, 숫자 또는 밑줄로 구성됩니다. GO 언어는 대소문자를 구분하며 키워드는 이름으로 사용할 수 없습니다. 단어로 구성된 이름을 접할 때 GO 프로그래머는 일반적으로 "카멜 케이스" 스타일을 사용합니다.
이 얘기가 나와서 말인데, Java의 명명 규칙을 살펴보겠습니다. $를 예로 들자면 오라클 공식 홈페이지에서는 변수명 시작에 $나 _를 사용하지 말 것을 권장하고 있으며, 이름 지정 시 "$" 문자를 전혀 사용하지 않는 것을 권장하고 있습니다. 변수 이름을 항상 '$' 또는 '_'"가 아닌 문자로 시작하십시오. 이 기사에 대해 Baidu는 클래스 이름이 "$" 기호 사용을 지원할 수 있지만 시스템 생성(예: 익명 클래스, 프록시 클래스)에만 사용되며 인코딩을 사용할 수 없다고 생각합니다.
많은 분들이 StackOverFlow에서 이런 문제를 제기해 오셨는데요. 크게 신경쓰실 필요는 없다는 것이 주류입니다. 원래 코드가 존재하는지 여부만 주의하시면 됩니다. 존재하지 않는 경우에는 사용하지 마십시오. '_'를 최대한 사용하지 말아야 하는 이유에 대해 누군가는 저해상도 디스플레이로 인해 육안으로 '_'(밑줄 1개)와 '__'(밑줄 2개)를 구별하기 어렵기 때문이라고 제안하기도 했습니다.
개인적으로는 C언어의 코딩 표준 때문이 아닐까 생각합니다. C 언어에서는 시스템 헤더 파일의 매크로 이름, 변수 이름, 내부 함수 이름이 _로 시작하므로 시스템 헤더 파일을 #include할 때 해당 파일의 이름이 사용하는 이름과 일치하면 정의됩니다. 충돌은 다양한 이상한 현상을 일으킬 수 있습니다. 다양한 정보를 바탕으로 읽기 어렵거나 이상한 문제가 발생하지 않도록 이름 앞에 "_", "$", 공백을 사용하지 않는 것이 좋습니다.
클래스 이름에 대해 러시아 Java 전문가 Yegor Bugayenko가 제시한 제안은 실생활에서 엔터티 추상화를 사용하려고 시도하는 것입니다. 클래스 이름이 "-er"로 끝나는 경우 이는 권장되는 명명 방법이 아닙니다. 그는 이 기사에는 예외가 있으며 이는 StringUtils, FileUtils 및 IOUtils와 같은 도구 클래스임을 지적했습니다. 인터페이스 이름에는 IRecord, IfaceEmployee, RedcordInterface를 사용하지 말고 대신 실제 엔터티 이름 지정을 사용하세요.
물론 위의 내용은 모두 Java에 대한 것이며 GO와는 아무런 관련이 없습니다. GO 언어는 C 언어의 영향을 더 많이 받습니다.
변수 개요
GO 언어에는 변수(var), 상수(const), 유형(type) 및 함수(func)의 네 가지 주요 선언 방법이 있습니다. 변수와 관련된 몇 가지 느낌에 대해 이야기해 보겠습니다.
1. var 선언은 특정 유형의 변수를 생성한 다음 여기에 이름을 붙이고 초기 값을 설정합니다: var name type = 표현식. 한 가지 더, Go 언어는 빈 문자열을 허용하고 널 포인터 오류를 보고하지 않습니다.
2. name:=expression을 사용하여 변수를 선언할 수 있습니다. 참고: =는 선언을 의미하고 =는 할당을 의미합니다.
변수의 수명이 var x int인 경우 &x(x의 주소) 표현식은 정수 변수에 대한 포인터를 얻고 해당 유형은 정수 포인터(*int)입니다. 값이 p라고 하면 p가 x를 가리키거나 p가 x의 주소를 포함한다고 말할 수 있습니다. p가 가리키는 변수는 *p로 기록됩니다. *p 표현식은 변수 값(이 경우 정수)을 가져옵니다. *p는 스칼라를 나타내기 때문에 할당 연산자의 왼쪽에도 나타날 수 있으며 변수 값을 업데이트하는 데 사용됩니다.
x:=1
p:=&x//p는 정수 포인터이며, //Equivalent to x=2
fmt.Println(x)//Output "2"
Java의 NULL과 비교하여 GO는 포인터 유형의 0 값이 nil임을 의미합니다.
}
var dummy 정수
return &dummy
}
gofmt 도구
Gofmt는 프로그램을 읽고 포맷합니다. 예를 들어 gofmt filename 명령을 사용하면 포맷된 코드가 인쇄됩니다. 샘플 프로그램(프로그램 이름 데모.go)을 살펴보겠습니다.
Garbage collection
가비지 수집기를 아는 방법 고급 언어의 경우 변수를 재활용해야 합니까? 기본 아이디어는 현재 실행 중인 함수의 모든 로컬 변수뿐만 아니라 모든 패키지 수준 변수를 변수를 추적하는 경로의 소스로 사용할 수 있다는 것입니다. 포인터 및 기타 참조를 통해 찾을 수 있습니다. 변수의 경로가 존재하지 않으면 스칼라에 액세스할 수 없으므로 다른 계산에는 영향을 주지 않습니다.
변수의 수명은 도달 가능 여부에 따라 결정되므로 지역 변수는 이를 포함하는 루프를 한 번 반복한 후에도 계속 존재할 수 있습니다.
GO 언어의 가비지 수집기 설계 목표는 비차단 수집기입니다. GO1.5는 10밀리초 이내에 재활용을 달성합니다. (실험에 따르면 이 진술은 GC에 충분한 CPU 시간이 있을 때만 유효할 수 있습니다.) . 디자인 원리 관점에서 Go의 리사이클러는 1978년 Dijkstra가 제안한 동시 3색 마크 앤 클리어 리사이클러이며 그 목표는 현대 하드웨어의 특성과 현대적 특성을 일치시키는 것입니다. 소프트웨어. 낮은 대기 시간 요구 사항이 완벽하게 일치합니다. 요약요약하자면, 모든 새로운 언어에는 이유가 있습니다. 일반적으로 말하면 두 가지 주요 이유가 있습니다:
1. 현재 주류 언어로 해결할 수 없는 복잡한 시나리오나 특정 문제가 발생했습니다.
2.
완전히 개인적인 감정으로 뭔가를 하려는 벨랩을 제외하고는 어떤 회사도 출구 없이 함부로 새로운 기술을 내놓는 회사는 없을 것 같아요. Rob Pike가 말했듯이 "복잡성은 곱셈 방식으로 증가합니다." 특정 문제를 해결하기 위해 시스템의 특정 부분을 조금씩 복잡하게 만들면 필연적으로 다른 부분에도 복잡성이 추가됩니다.
시스템 기능, 옵션 및 구성을 추가하고 신속하게 출시해야 한다는 지속적인 압력 속에서 단순성은 종종 간과됩니다. 단순성을 달성하려면 프로젝트 시작 시 아이디어의 본질을 압축하고 프로젝트 수명 전반에 걸쳐 어떤 변화가 좋은지, 나쁘거나 치명적인지를 식별하기 위한 보다 구체적인 지침을 개발해야 합니다.
우리가 열심히 일하는 한, 좋은 변화는 Fred Brooks가 소프트웨어 디자인의 "개념적 무결성"이라고 부르는 것을 손상시키지 않고 목적을 달성할 수 있습니다. 나쁜 변경은 이를 수행하지 않으며, 치명적인 변경은 편의성을 위해 단순성을 희생합니다. 그러나 설계의 단순성을 통해서만 시스템이 성장함에 따라 안정적이고 안전하며 자체 일관성을 유지할 수 있습니다. Go 언어는 언어 자체, 도구 및 표준 라이브러리를 포함할 뿐만 아니라 극도로 단순한 행동 문화를 유지합니다.