Go 주니어 기술면접

Go 주니어 (1~3년) 종합 5문항 조회수 77 · 2026-06-04 (목) 19:10:44
1 자료구조
Easy

Q. Go에서 map을 사용할 때 키(key)로 사용할 수 없는 타입은 무엇이며, 그 이유는 무엇인가요? 또한 map의 값을 순회할 때 주의해야 할 점을 설명해주세요.

A. 모범답안

map의 키로 사용할 수 없는 타입은 slice, map, function과 같이 비교 연산이 불가능한(non-comparable) 타입입니다. map의 키는 반드시 == 연산자로 비교 가능해야 하며, 해시 가능해야 합니다. map을 순회할 때는 순서가 보장되지 않는다는 점을 주의해야 하며, 매번 실행할 때마다 순회 순서가 달라질 수 있습니다. 순서가 중요한 경우에는 키를 별도로 정렬하거나 slice에 담아서 사용해야 합니다.

핵심 포인트
  • • slice, map, function 등 비교 불가능한 타입은 키로 사용 불가
  • • 키는 == 연산자로 비교 가능하고 해시 가능해야 함
  • • map 순회 시 순서가 보장되지 않으며 매번 달라질 수 있음
  • • 순서가 필요한 경우 별도로 정렬 처리 필요
Follow-up 질문

struct를 map의 키로 사용할 수 있나요? 사용할 수 있다면 어떤 조건을 만족해야 하나요?

2 동시성
Medium

Q. Go에서 sync.WaitGroup의 역할은 무엇이며, 어떤 상황에서 사용하나요? Add, Done, Wait 메서드의 사용법과 함께 주의해야 할 점을 설명해주세요.

A. 모범답안

sync.WaitGroup은 여러 goroutine의 완료를 기다려야 할 때 사용하는 동기화 도구입니다. Add(n)으로 대기할 goroutine 수를 설정하고, 각 goroutine에서 작업 완료 시 Done()을 호출하며, Wait()로 모든 goroutine이 완료될 때까지 대기합니다. 주의할 점은 Add를 goroutine 시작 전에 호출해야 하며, Done 호출 횟수가 Add 횟수와 정확히 일치해야 합니다. Done을 너무 많이 호출하면 panic이 발생하고, 적게 호출하면 Wait에서 영구적으로 블로킹됩니다.

핵심 포인트
  • • 여러 goroutine의 완료를 동기화하는 도구
  • • Add는 goroutine 시작 전에, Done은 작업 완료 시, Wait은 모든 완료 대기용
  • • Add와 Done 호출 횟수가 정확히 일치해야 함
  • • Done 호출 과다 시 panic, 부족 시 데드락 발생
Follow-up 질문

WaitGroup을 함수 파라미터로 전달할 때 포인터로 전달해야 하는 이유는 무엇인가요?

3 HTTP 서버
Medium

Q. Go의 http.Handler와 http.HandlerFunc의 차이점은 무엇이며, HandlerFunc는 어떤 원리로 Handler 인터페이스를 만족하나요? 실무에서는 어떤 경우에 각각을 사용하나요?

A. 모범답안

http.Handler는 ServeHTTP(ResponseWriter, *Request) 메서드를 가진 인터페이스이고, http.HandlerFunc는 함수 타입으로 정의되어 있으며 자체적으로 ServeHTTP 메서드를 구현하고 있습니다. HandlerFunc는 함수 타입이지만 메서드를 가지므로 Handler 인터페이스를 만족하며, 일반 함수를 Handler로 변환하는 어댑터 역할을 합니다. 간단한 핸들러는 HandlerFunc로 작성하고, 상태를 가지거나 복잡한 로직이 필요한 경우 Handler 인터페이스를 직접 구현한 구조체를 사용합니다.

핵심 포인트
  • • Handler는 ServeHTTP 메서드를 가진 인터페이스
  • • HandlerFunc는 함수 타입이지만 ServeHTTP 메서드 구현으로 Handler 만족
  • • HandlerFunc는 함수를 Handler로 변환하는 어댑터 패턴
  • • 간단한 경우 HandlerFunc, 상태 관리 필요 시 Handler 구조체 사용
Follow-up 질문

미들웨어 체인을 구현할 때 Handler를 반환하는 함수를 어떻게 작성하나요?

4 데이터베이스
Medium

Q. Go에서 database/sql 패키지를 사용할 때 Query와 Exec 메서드의 차이점은 무엇이며, 각각 어떤 상황에서 사용해야 하나요? 또한 prepared statement를 사용해야 하는 이유를 설명해주세요.

A. 모범답안

Query는 SELECT와 같이 결과 행을 반환하는 쿼리에 사용하며 Rows를 반환하고, Exec는 INSERT, UPDATE, DELETE처럼 결과 행이 없는 쿼리에 사용하며 Result를 반환합니다. Query 후에는 반드시 rows.Close()를 호출해야 연결이 반환됩니다. prepared statement는 SQL 인젝션 공격을 방지하고, 쿼리 파싱을 재사용하여 성능을 향상시킵니다. database/sql의 Query와 Exec는 내부적으로 prepared statement를 사용하므로, 파라미터는 항상 플레이스홀더(?)로 전달해야 합니다.

핵심 포인트
  • • Query는 결과 행 반환(SELECT), Exec는 영향받은 행 수 반환(INSERT/UPDATE/DELETE)
  • • Query 후에는 반드시 rows.Close() 호출 필요
  • • prepared statement는 SQL 인젝션 방지와 성능 향상
  • • 파라미터는 문자열 결합이 아닌 플레이스홀더로 전달
Follow-up 질문

트랜잭션을 사용해야 하는 경우는 언제이며, Go에서 트랜잭션은 어떻게 시작하고 커밋하나요?

5 시스템 설계
Medium

Q. 채팅 애플리케이션에서 사용자가 메시지를 전송하면 상대방에게 실시간으로 전달되어야 합니다. HTTP 기반으로 이를 구현할 때 어떤 방식들이 있으며, 각 방식의 장단점을 설명해주세요. Go에서는 어떤 방식을 추천하나요?

A. 모범답안

HTTP 기반 실시간 통신 방식으로는 폴링(Polling), 롱 폴링(Long Polling), Server-Sent Events(SSE), WebSocket이 있습니다. 폴링은 구현이 간단하지만 불필요한 요청이 많고, 롱 폴링은 폴링보다 효율적이지만 여전히 HTTP 오버헤드가 있습니다. SSE는 서버에서 클라이언트로 단방향 푸시가 가능하며 자동 재연결을 지원하지만 양방향 통신이 불가능합니다. WebSocket은 양방향 실시간 통신이 가능하고 오버헤드가 적어 채팅에 가장 적합하며, Go에서는 gorilla/websocket 라이브러리를 많이 사용합니다.

핵심 포인트
  • • 폴링: 간단하지만 비효율적, 롱 폴링: 개선되었지만 여전히 오버헤드 존재
  • • SSE: 서버→클라이언트 단방향 푸시, 자동 재연결 지원
  • • WebSocket: 양방향 실시간 통신, 낮은 오버헤드로 채팅에 최적
  • • Go에서는 gorilla/websocket 라이브러리 활용
Follow-up 질문

WebSocket 연결이 많아질 때 서버 확장성을 위해 고려해야 할 사항은 무엇인가요?

댓글 0

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

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