프로그래밍Go 백엔드 개발자

Go에서 슬라이스와 구조체 복사의 특징을 설명하십시오. 이들을 사용할 때 예기치 않은 효과를 피하려면 어떻게 해야 합니까?

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

답변

Go에서 구조체는 값에 따라 복사되며(1단계의 깊은 복사, 중첩된 구조체도 동일한 규칙에 따라 복사됨), 슬라이스는 값에 따라 복사되지만, 실제 배열은 복사되지 않습니다: 원본과 슬라이스 복사본 모두 동일한 백업 배열을 가리키므로, 한 슬라이스를 통해 변경하면 다른 슬라이스에도 반영됩니다. 배열을 명시적으로 복사하려면 copy()를 사용해야 합니다.

슬라이스 복사 예시:

s1 := []int{1,2,3} s2 := s1 // 동일한 버퍼를 가리킴! s2[0] = 99 fmt.Println(s1) // [99 2 3] // 배열 복사를 위해: s3 := make([]int, len(s1)) copy(s3, s1) s3[0] = 42 fmt.Println(s1) // [99 2 3], s3는 독립적임

구조체를 복사할 때: 구조체가 포인터 필드나 슬라이스 필드를 포함하고 있으면, 값이 아닌 단지 참조만 복사됩니다.

수수께끼의 질문

슬라이스를 "복제"하여 그 변경이 원본에 영향을 미치지 않도록 하려면 어떻게 해야 합니까?

잠재적으로 잘못된 답변: 그냥 b := a를 만들면 된다. 맞는 답변:

  • copy를 사용하여 필요한 길이의 새 슬라이스를 만들고 데이터를 복사해야 합니다:
newS := make([]int, len(a)) copy(newS, a)

이 주제에 대한 세부 사항을 모르는 것 때문에 발생한 실제 오류 사례들


이야기

설명: DB에 대한 요청을 생성할 때 요청 구조의 슬라이스 필드를 동적으로 변경하였고, 복사 없이 사용하였음. 반복 요청 시 데이터가 섞여 사용자가 잘못된 결과를 받았습니다.


이야기

설명: 데이터 병렬 처리 시 구조체를 단순히 할당으로 복사하고 한 고루틴에서 슬라이스를 확장하는 동안 다른 원본 슬라이스를 병행하여 사용하였습니다. 데이터가 "덮어쓰기" 되어 예측할 수 없는 버그가 발생했습니다.


이야기

설명: 버퍼 구조체를 사용하고, 단순히 할당을 통해 복사하는 것이 중첩된 슬라이스(shallow copy)를 고려하지 않아 한 곳의 변경이 다른 버퍼에 영향을 주었습니다 — 결과적으로 데이터 변경의 출처를 추적하기 어려웠습니다.