프로그래밍Go 백엔드 엔지니어

Go에서 map 및 slice 작업 시 range 메커니즘이 어떻게 작동하는지 설명해 주세요. 루프 변수 사용 시 주의할 점과 어떤 오류에 직면할 수 있는지에 대해 논의해 주세요.

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

답변

for ... range 루프는 슬라이스 (slice), 맵 (map), 배열 또는 문자열의 요소를 편리하게 반복하는 데 사용됩니다.

  • 슬라이스의 경우: 각 반복에서 인덱스와 요소의 복사를 반환합니다.
  • 맵의 경우: 키와 값의 복사를 반환합니다.

예제:

s := []int{1, 2, 3} for i, v := range s { fmt.Println(i, v) } m := map[string]int{"a":1, "b":2} for k, v := range m { fmt.Println(k, v) }

중요한 주의사항: 변수 i, v, k 등은 모든 반복에서 재사용됩니다! 이는 루프 내에서 참조로 전달하거나 range 내에서 goroutine을 실행할 때 버그의 원인이 되는 경우가 많습니다.

속임수 질문

슬라이스 내에서 range 루프 중 goroutine을 실행하고 반복 변수를 캡처하면 어떻게 될까요? 오류를 피하려면 어떻게 해야 하나요?

답변: 일반적인 오류가 발생합니다: goroutine 내부에서 루프 변수를 사용하면 루프가 종료된 후 마지막 값이 의해 사용됩니다. 이를 피하려면 로컬 복사본을 만들어야 합니다:

nums := []int{1, 2, 3} for _, v := range nums { go func(val int) { fmt.Println(val) }(v) }

잘못된 점에 대한 실제 오류 사례


이야기

한 프로젝트에서 여러 goroutine을 통해 슬라이스를 채우기 위해 range를 사용하면서 루프 변수의 복사본을 생성하는 것을 잊어버렸습니다. 모든 goroutine이 배열의 마지막 값을 출력하여 비즈니스 로직이 크게 손상되었습니다.


이야기

map을 순회하면서 값을 새 포인터 슬라이스에 저장했습니다. 결과적으로 새로운 슬라이스의 모든 요소가 루프에서 사용되는 같은 변수에 참조되어 버그가 발생했습니다 (panic: invalid memory address 또는 예상치 못한 데이터).


이야기

내부 도구에서 string을 순회하며 중요한 서브스트링의 처리기를 실행했지만 각 반복에서 바이트 오프셋을 받았고, Unicode 문자로 처리되지 않았습니다. 결과: Unicode 문자열에 대한 잘못된 처리, 잘못된 문자 분할이 발생했습니다.