프로그래밍Go 개발자

Go의 내장 함수 make의 특징에 대해 설명하십시오: 언제 필요하고, map, slice 및 channel에 대한 초기화 절단이 어떻게 작동하는지? make와 new의 잘못된 사용으로 인해 발생할 수 있는 오류는 무엇인가요?

Hintsage AI 어시스턴트로 면접 통과

답변

Go의 make 함수는 오직 slice, mapchannel 유형의 객체를 초기화하는 데 사용됩니다. 필요한 데이터 구조를 выдел하고 작업할 준비가 된 객체(포인터 아님)를 반환합니다.

예제:

s := make([]int, 5, 10) // 길이가 5이고 용량이 10인 슬라이스 m := make(map[string]int) // 빈 맵 ch := make(chan int, 2) // 2개의 버퍼가 있는 채널

세부 사항:

  • slice의 경우: 길이(len) 및 (선택적) 용량(cap) 매개변수.
  • mapchan의 경우 — (선택적) 용량(초기 크기/버퍼)만.
  • make 함수는 이미 초기화된 객체를 반환하며 사용 준비가 되어 있습니다.
  • 다른 유형(struct, array)의 경우 make를 사용하지 않고 리터럴이나 new를 통해 초기화합니다(이는 zero value의 포인터를 반환함).

new와의 비교:

  • new(T)는 모든 필드가 0인 *T를 반환합니다.
  • make(T)는 오직 세 가지 유형: slice, map, chan에 대해서만 T를 반환합니다.

함정 질문

make 대신 new를 사용하여 작업할 수 있는 map을 얻을 수 있나요?

m := new(map[string]int) (*m)["a"] = 1 // 무슨 일이 발생할까요?

많은 사람들이 이것이 올바르다고 생각하지만, runtime에서 panic이 발생합니다: assignment to entry in nil map. 왜냐하면 변수 *m에 nil이 있기 때문입니다!

올바른 방법: make를 사용하세요:

m := make(map[string]int) m["a"] = 1 // OK

이 주제에 대한 지식 부족으로 인한 실제 오류 사례


이야기

캐시를 저장하는 마이크로서비스에서 var cache map[string]interface{}를 초기화 없이 만들었고, 이로 인해 생산 중 기록 시 panic이 발생하여 이해할 수 없는 스택 트레이스를 남겼습니다. 코드 분석 후 문제를 발견했습니다: map이 nil이었습니다.


이야기

데이터 파이프라인을 작성할 때 채널의 버퍼를 잊어버리고 make(chan int)를 통해 생성했습니다. 그 결과, 고루틴이 읽기를 기다리면서 멈췄고 비동기 교환이 예상되었습니다. 오류는 대규모 테스트에서만 발견되었습니다.


이야기

new로 초기화하는 프로젝트에서, 일부 개발자들이 make([]int, 10) 대신 new([]int)를 사용하려 했고, 그 결과 nil 슬라이스의 포인터를 얻어 첫 번째 기록 시에 runtime panic이 발생했습니다.