Go 언어 프로그래밍 학습 노트
Go 언어를 처음 접하는 사람을 위한 학습 문서. 문법 기초부터 동시성, 자료구조, 실전 패턴까지 단계적으로 다룬다.
각 챕터는 앞 챕터에서 다룬 개념만 사용하도록 의존성을 정리했다. 아직 배우지 않은 개념이 갑자기 튀어나오는 일은 없다.
1부. Go 시작하기
1장. Go 언어 소개
- Go란 무엇인가
- 특징과 장점
- 어디에 쓰이는가
- 다른 언어와의 비교
2장. 개발 환경 준비
- Go 설치 (macOS / Windows / Linux)
- 에디터 선택
- 첫 프로그램: Hello, World
go run과go build의 차이
3장. Go 프로그램의 기본 구조
package,import,func main의 역할- 세미콜론과 중괄호 규칙
- 주석 쓰기
gofmt로 코드 정리
2부. 기본 데이터 다루기
4장. 변수와 자료형
- 변수 선언 (
var,:=) - 기본 자료형 (정수, 실수, 불리언, 문자열)
- 상수 (
const) - 타입 변환 (
int(x),string(y)) - 제로값 개념
5장. 연산자
- 산술 / 비교 / 논리 연산자
- 대입 연산자
- 연산자 우선순위
6장. 문자열 다루기 기초
- 문자열의 본질 (불변, UTF-8)
- 연결 (
+) 과 비교 - 길이 구하기 (
len) - 인덱싱과 슬라이싱
byte와rune맛보기- 심화 내용은 27장에서
7장. fmt 패키지로 입출력
- 출력 함수
Print,Println,Printf
- 자주 쓰는 포맷 동사
%d,%f,%s,%t,%v,%T
- 너비 / 자릿수 지정
- 문자열 만들기 (
Sprintf) - 사용자 입력 받기
Scan,Scanln
- 미니 실습: 이름과 나이 입력받아 인사 출력
3부. 프로그램 흐름 제어
8장. 제어문
- 조건문
if/else if/else - 분기문
switch - 반복문
for(세 가지 형태) break,continue- 중첩 반복과 라벨
4부. 함수로 코드 묶기
9장. 함수
- 함수 정의와 호출
- 매개변수와 반환값
- 다중 반환값
- 명명된 반환값
- 가변 인자
defer의 동작 원리- 익명 함수와 클로저
10장. 변수의 범위 (Scope)
- 변수의 범위란 무엇인가
- 블록과 중괄호
{ }의 관계 - 세 가지 범위
- 패키지 수준 변수 (전역)
- 함수 수준 변수 (지역)
- 블록 수준 변수 (
if,for,switch안)
- 함수 매개변수의 범위
- 변수 가리기 (shadowing)
- 안쪽 블록에서 같은 이름을 다시 선언하면?
:=때문에 생기는 흔한 함정
- 전역 변수를 자제해야 하는 이유
5부. 여러 데이터 묶어 다루기
11장. 배열과 슬라이스
- 배열의 한계
- 슬라이스 선언과 사용
append,copy,make- 길이와 용량
- 슬라이스 순회 (
for range)
12장. 맵 (Map)
- 맵 선언과 초기화
- 값 추가 / 조회 / 삭제
- 키 존재 여부 확인
- 맵 순회
13장. 구조체 (Struct)
- 구조체 정의와 필드
- 초기화 방법들
- 중첩 구조체
- 익명 구조체
6부. 포인터와 추상화
14장. 포인터
- 포인터가 왜 필요한가
&와*의 의미- 함수 인자로 포인터 넘기기
- 구조체와 포인터
15장. 메서드
- 메서드란
- 값 리시버 vs 포인터 리시버
- 언제 어느 쪽을 쓰는가
16장. 인터페이스
- 인터페이스 기초
- 암묵적 구현
- 빈 인터페이스
any - 타입 단언과 타입 스위치
17장. 제네릭 (Generics)
- 제네릭이 왜 필요한가
- 같은 함수를 타입마다 복사하는 문제
- 빈 인터페이스
any의 한계
- 타입 매개변수 문법
func Sum[T int | float64](nums []T) T
- 타입 제약 (Constraints)
- 내장 제약:
any,comparable - 인터페이스를 제약으로 쓰기
- 타입 집합
int | float64 ~(underlying type) 의미
- 내장 제약:
- 제네릭 함수 예제
Map,Filter,Reduce직접 만들어 보기
- 제네릭 타입 맛보기
- 언제 쓰고 언제 안 써야 하는가
7부. 자료구조 깊이 이해하기
18장. 리스트, 큐, 스택, 링
- Go 표준 자료구조 한눈에 보기
- 메모리 구조부터 이해하기
- 슬라이스 (연속 메모리)
- 연결 리스트 (포인터로 이어진 노드)
- 어떤 차이가 성능 차이를 만드는가
- 이중 연결 리스트:
container/list - 큐 (FIFO) 구현하기
- 슬라이스로 구현 (주의점 포함)
container/list로 구현
- 스택 (LIFO) 구현하기
- 슬라이스로 깔끔하게
- 원형 자료구조:
container/ring - 우선순위 큐:
container/heap맛보기 - 연산별 속도 비교표 (Big-O)
19장. 맵 깊이 이해하기
- 해시 테이블이란 무엇인가
- 키를 인덱스로 바꾸는 원리
- 해시 함수의 역할
- Go 맵의 내부 구조
- 버킷(bucket) 배열
- 충돌 해결 방식 (chaining)
- 로드 팩터와 동적 확장
- 맵의 흥미로운 특성들
- 왜 순회 순서가 매번 바뀌는가
- 왜 동시 접근에 안전하지 않은가
- nil 맵의 함정
- 맵 vs 슬라이스 검색 속도 실험
- 맵을 잘 쓰는 패턴
- 집합(Set) 흉내 내기
- 카운터로 활용하기
8부. 코드 구성과 에러 처리
20장. 패키지와 모듈
- 패키지 만들기 / 가져오기
- 대문자 / 소문자 export 규칙
go.mod,go.sum- 외부 패키지 사용 (
go get)
21장. 에러 처리
error인터페이스- 에러 반환 관례
- 에러 래핑 (
fmt.Errorf,%w) panic과recover
9부. 동시성
22장. 고루틴과 채널 기초
- 고루틴이란
- 스레드와 무엇이 다른가
- 가벼움 (수십만 개도 가능)
- 고루틴 시작하기 (
go f()) - main 종료와 고루틴의 관계
- 채널 기초
- 송수신 문법
- 방향 채널
- 버퍼 vs 언버퍼
- 채널 닫기 (
close) 와range로 받기 select문 기초sync.WaitGroup으로 끝 기다리기
23장. 동시성 문제와 뮤텍스
- 무엇이 잘못될 수 있는가
- 경쟁 조건의 실제 예시
- 데이터 레이스와 경쟁 조건의 차이
- 탐지하기:
go run -race - 락 기반 해결
sync.Mutex사용법sync.RWMutex(읽기/쓰기 분리)
- 락 함정들
- 데드락 / 라이브락
- 락을 든 채 블로킹하는 안티패턴
- 락 순서 일관성 문제
- 원자 연산
sync/atomic맛보기
24장. 락 없이 동시성 설계하기
- Go 의 철학
- “공유 메모리로 통신하지 말고, 통신으로 메모리를 공유하라”
- 락이 답이 아닌 경우들
- 소유권 이전 패턴
- 데이터를 한 번에 한 고루틴만 가지게 하기
- 단일 작성자 패턴
- 쓰기는 한 고루틴만, 읽기는 여러 고루틴
- 영역 나누기 (Sharding / Partitioning)
- 키별로 고루틴 분배
- 처음부터 충돌을 없애기
- 역할 나누기 (생산자 / 소비자)
- 불변 데이터로 공유하기
- 언제 락이 낫고 언제 채널이 나은가
25장. 동시성 패턴과 도구 모음
- 실전 패턴
- 파이프라인 (단계별 처리)
- Fan-out / Fan-in
- 워커 풀 정식 구현
context로 취소와 타임아웃- context 의 등장 이유
- 트리 형태의 전파
- 그 밖의 동기화 도구
sync.Oncesync.Mapsync.Cond(간단히)
- 고루틴 누수 (goroutine leak)
- 어떻게 새는가
- 어떻게 막는가
- 동시성 디버깅 팁
10부. 효율적인 Go 프로그래밍
26장. 대용량 데이터와 메모리 효율
- 슬라이스의 메모리 동작 이해
- 슬라이스는 배열을 가리키는 “창문”
append가 일으키는 재할당make([]T, 0, cap)으로 cap 미리 잡기- 부분 슬라이스가 큰 배열을 붙잡는 함정
copy로 메모리 끊어내기
- 값 전달 vs 포인터 전달
- 큰 구조체의 복사 비용
- 포인터 전달이 능사가 아닌 이유 (GC, 힙 할당)
- 스택과 힙 (escape analysis 개념)
- 언제 값, 언제 포인터?
- 대용량 데이터 처리 패턴
- 한 번에 다 메모리에 올리지 않기
- DB 결과를 페이징 / 커서 / 배치로 가져오기
io.Reader로 스트림 처리- 채널로 파이프라인 만들기
bufio.Scanner로 줄 단위 처리
- 자주 쓰이는 최적화 기법
strings.Builder로 문자열 누적- 맵 / 슬라이스 크기 미리 지정
sync.Pool로 객체 재사용
- 성능을 직접 재 보기
testing.B로 벤치마크 작성pprof맛보기 (CPU, 메모리)
11부. 표준 라이브러리 활용
27장. 문자열 다루기 심화
strings패키지strconv로 변환하기
28장. 시간 다루기
time패키지 기초- 시간 포맷팅과 파싱
29장. 파일 입출력
os로 파일 열기 / 쓰기bufio로 한 줄씩 읽기defer로 안전하게 닫기
30장. JSON 다루기
- 구조체와 JSON 매핑
- 인코딩 / 디코딩
31장. 간단한 HTTP 서버
net/http로 서버 띄우기- 핸들러 등록
- JSON 응답 보내기
12부. 마무리
32장. 테스트 작성하기
testing패키지- 단위 테스트 작성
go test사용법
33장. 미니 프로젝트
- CLI 할 일 관리 도구
- JSON API 서버