Go 주니어 코딩 면접

Go 주니어 (1~3년) 코딩 · 알고리즘 5문항 조회수 93 · 2026-06-12 (금) 03:10:47
1 슬라이스 조작
Easy

Q. 정수 슬라이스에서 특정 값을 모두 제거하는 함수를 구현하려고 합니다. 예를 들어 [1, 2, 3, 2, 4, 2]에서 2를 제거하면 [1, 3, 4]가 되어야 합니다. 어떤 방식으로 구현하시겠으며, 원본 슬라이스를 수정하지 않으려면 어떻게 해야 하나요?

A. 모범답안

새로운 슬라이스를 생성하여 제거할 값이 아닌 요소만 append하는 방식으로 구현합니다. for range로 슬라이스를 순회하면서 조건에 맞는 값만 새 슬라이스에 추가합니다. 원본을 수정하지 않으려면 반드시 새로운 슬라이스를 생성해야 하며, 용량을 미리 할당하면 성능을 개선할 수 있습니다. 시간복잡도는 O(n)이며, 공간복잡도도 최악의 경우 O(n)입니다.

핵심 포인트
  • • 새 슬라이스 생성 후 조건에 맞는 요소만 append
  • • for range로 순회하며 필터링
  • • make로 용량을 미리 할당하면 성능 향상
  • • 원본 슬라이스는 변경되지 않음
Follow-up 질문

만약 메모리 효율을 위해 원본 슬라이스를 in-place로 수정하는 방식으로 구현한다면 어떻게 하시겠습니까?

2 문자열 처리
Medium

Q. 문자열에서 각 단어의 첫 글자를 대문자로 변환하는 함수를 구현하려고 합니다. 예를 들어 'hello world go'를 'Hello World Go'로 변환해야 합니다. strings 패키지의 어떤 함수들을 활용할 수 있으며, 유니코드 문자를 올바르게 처리하려면 어떤 점을 주의해야 하나요?

A. 모범답안

strings.Fields로 문자열을 공백 기준으로 분리하여 단어 슬라이스를 만들고, 각 단어에 대해 strings.Title이나 cases 패키지를 사용합니다. Go 1.18 이후로는 strings.Title이 deprecated되어 golang.org/x/text/cases 패키지의 Title 함수 사용을 권장합니다. 각 단어를 처리한 후 strings.Join으로 다시 합칩니다. 유니코드를 올바르게 처리하려면 []rune으로 변환하여 unicode.ToUpper를 사용하는 것이 안전합니다.

핵심 포인트
  • • strings.Fields로 단어 분리
  • • cases 패키지 사용 권장 (strings.Title은 deprecated)
  • • []rune 변환으로 유니코드 안전하게 처리
  • • strings.Join으로 결과 합치기
Follow-up 질문

만약 단어 구분자가 공백뿐만 아니라 탭, 하이픈, 언더스코어 등 여러 종류라면 어떻게 처리하시겠습니까?

3 자료구조
Medium

Q. LRU(Least Recently Used) 캐시를 간단하게 구현하려고 합니다. 고정된 용량을 가지며, 용량 초과 시 가장 오래 사용되지 않은 항목을 제거해야 합니다. Get과 Put 연산을 O(1) 시간복잡도로 구현하려면 어떤 자료구조를 조합해야 하며, Go에서는 어떻게 구현할 수 있나요?

A. 모범답안

map과 doubly linked list를 조합하여 구현합니다. map은 키를 통한 O(1) 접근을 제공하고, doubly linked list는 최근 사용 순서를 유지합니다. container/list 패키지의 List를 사용하여 linked list를 구현하고, map[key]*list.Element로 각 키에 대한 노드를 저장합니다. Get 시 해당 노드를 리스트의 맨 앞으로 이동시키고, Put 시 용량 초과면 리스트의 맨 뒤 노드를 제거합니다. 모든 연산이 O(1)에 수행됩니다.

핵심 포인트
  • • map과 doubly linked list 조합
  • • container/list 패키지 활용
  • • Get/Put 시 노드를 리스트 맨 앞으로 이동
  • • 용량 초과 시 리스트 맨 뒤 노드 제거로 O(1) 보장
Follow-up 질문

멀티스레드 환경에서 이 LRU 캐시를 안전하게 사용하려면 어떤 동기화 메커니즘을 추가해야 하나요?

4 동시성
Hard

Q. 여러 파일을 동시에 읽어서 각 파일의 라인 수를 세는 프로그램을 작성하려고 합니다. 파일 목록이 주어졌을 때, goroutine을 사용하여 병렬로 처리하되 결과를 파일명과 라인 수의 맵으로 반환해야 합니다. 에러가 발생한 파일이 있어도 다른 파일은 계속 처리되어야 하며, 모든 결과를 수집하는 방법을 설명해주세요.

A. 모범답안

각 파일마다 goroutine을 생성하여 처리하고, 결과를 구조체로 만들어 channel로 전송합니다. 결과 구조체는 파일명, 라인 수, 에러를 포함합니다. sync.WaitGroup으로 모든 goroutine의 완료를 기다리며, 별도의 goroutine에서 WaitGroup이 끝나면 channel을 닫습니다. 메인 goroutine에서는 channel을 range로 순회하며 결과를 맵에 수집합니다. 에러가 발생해도 결과 구조체에 에러를 담아 전송하므로 다른 파일 처리에 영향을 주지 않습니다.

핵심 포인트
  • • 각 파일마다 goroutine 생성
  • • 결과 구조체(파일명, 라인수, 에러)를 channel로 전송
  • • sync.WaitGroup으로 완료 대기 후 channel 닫기
  • • 에러를 결과에 포함시켜 부분 실패 허용
Follow-up 질문

파일이 수천 개라면 goroutine을 무제한으로 생성하는 것이 문제가 될 수 있습니다. 이를 제한하는 worker pool 패턴으로 어떻게 개선하시겠습니까?

5 알고리즘
Medium

Q. 정수 슬라이스에서 연속된 부분 배열의 합이 최대가 되는 값을 찾는 Maximum Subarray 문제를 해결하려고 합니다. 예를 들어 [-2, 1, -3, 4, -1, 2, 1, -5, 4]에서 답은 6입니다([4, -1, 2, 1]). 이를 O(n) 시간복잡도로 해결하는 Kadane's Algorithm의 접근 방법을 설명하고, Go에서 구현 시 주의할 점을 말씀해주세요.

A. 모범답안

현재 위치까지의 최대 부분합(currentMax)과 전체 최대값(globalMax)을 유지하며 순회합니다. 각 위치에서 currentMax는 현재 요소를 포함하여 이전 부분합을 이어가거나, 현재 요소부터 새로 시작하는 것 중 큰 값을 선택합니다. globalMax는 매 단계마다 currentMax와 비교하여 갱신합니다. 초기값 설정이 중요한데, 모든 값이 음수인 경우를 고려하여 globalMax를 첫 번째 요소나 math.MinInt로 초기화해야 합니다. 시간복잡도는 O(n), 공간복잡도는 O(1)입니다.

핵심 포인트
  • • currentMax와 globalMax 두 변수 유지
  • • 각 위치에서 이어가기 vs 새로 시작하기 선택
  • • 모든 값이 음수인 경우를 위한 초기값 설정
  • • O(n) 시간, O(1) 공간복잡도
Follow-up 질문

만약 최대 합뿐만 아니라 그 부분 배열의 시작과 끝 인덱스도 함께 반환해야 한다면 어떻게 수정하시겠습니까?

댓글 0

로그인 후 댓글을 작성할 수 있습니다.

아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!