프로그래밍Go 개발자

Go에서 슬라이스를 복사할 때 copy()는 어떻게 작동하나요? 슬라이스의 길이와 용량 증가에 관련된 특징, 제한 사항 및 예기치 않은 효과는 무엇인가요? 슬라이스가 서로 겹칠 때, 겹친 상태로 복사하려고 하면 어떤 일이 발생하나요?

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

답변

함수 copy(dst, src []T) intsrc의 요소를 dst로 복사합니다.

  • 복사된 요소의 수를 반환합니다: min(len(dst), len(src)).
  • 복사는 인덱스 기반으로 진행됩니다: 요소 src[i]dst[i]로 복사됩니다.
  • 값(내용)이 복사되며, 객체의 포인터는 복사되지 않습니다.

세부 사항 및 제한 사항:

  • 슬라이스가 겹치는 경우(예: 하나가 다른 슬라이스의 부분 배열인 경우), 복사는 원본 값의 스니펫을 가져온 다음 복사하는 것처럼 진행됩니다(겹침이 있을 경우의 정확성 보장은 없습니다).
  • dst의 길이가 src보다 작으면, dst의 길이가 허용하는 만큼만 데이터가 복사됩니다.
  • dst의 용량이 길이보다 크더라도 copy가 슬라이스를 확장하나요? — 아닙니다. 오직 len(dst)만이 목표로 간주됩니다. 확장을 위해서는 prepend를 사용해야 합니다.

예시:

a := []int{1,2,3,4,5} b := make([]int, 3) copy(b, a) // b: [1 2 3]

겹침:

x := []int{1,2,3,4} copy(x[1:], x[:3]) // [1 1 2 3]

함정 질문

copy()를 사용하여 슬라이스의 길이를 늘릴 수 있나요? 필요한 것보다 큰 용량을 갖지만 길이가 짧은 슬라이스를 copy에 전달하면 어떤 일이 발생하나요?

답변:

  • copy()는 대상 슬라이스의 길이를 변경하지 않고 — 오직 len(dst)까지 복사합니다.
  • dst의 용량이 길이보다 크면 먼저 dst = dst[:newLen]를 사용하여 확장한 후 copy()를 사용하세요.

자주 간과되는 예시:

a := []int{1,2,3} b := make([]int, 0, 5) copy(b, a) // b는 비어있게 남습니다, 왜냐하면 len(b)==0이기 때문입니다. b = b[:len(a)] copy(b, a) // 이제 b: [1,2,3]

이 주제를 잘 몰라서 발생한 실제 오류 사례


이야기

프로젝트에서 데이터를 한 슬라이스에서 다른 슬라이스로 복사했는데, copy가 자동으로 dst의 길이를 늘릴 것이라고 생각했습니다. 그렇지 않았고, 요소가 복사되지 않아 API의 응답에 0 데이터가 반환되었습니다. 슬라이스 길이를 비교한 후에야 오류를 발견했습니다 — 문제는 dst의 용량은 컸지만 길이가 0이었습니다.


이야기

마이크로서비스의 일부가 겹치는 슬라이스 작업을 하면서 copy가 항상 올바르게 작동할 것이라는 잘못된 계산을 했습니다. 결과적으로 앞쪽으로의 복사가 원본 데이터를 파괴하고, 버퍼 작업 중 '보이지 않는' 버그가 발생했습니다. 임시 버퍼를 사용하여 해결했습니다 (copy(tmp, src), 그런 다음 copy(dst, tmp)).


이야기

엔지니어가 데이터를 슬라이스 간 정렬을 위해 copy를 사용하여 배열을 최적화했습니다. dst의 길이를 조정할 것이라고 예상했는데, 그렇게 되지 않아서 패닉과 의미 있는 데이터 초과가 발생했습니다 — 복사하기 전에 슬라이스의 길이를 올바르게 변경하는 것을 잊었습니다.