🎁 지금 가입하면 온라인 AI를 최대 30분 무료로 사용할 수 있습니다. 신용카드는 필요하지 않습니다.

소프트웨어 엔지니어 면접 질문과 답변 (2026): 코딩, 기초, 설계, 행동 면접

October 14, 2026
답변이 포함된 소프트웨어 엔지니어 면접 질문 20개: 테스트를 거친 Python 풀이가 있는 코딩 문제 8개, CS 기초, 시스템 디자인, 행동 질문, 그리고 준비 방법.
소프트웨어 엔지니어 면접 질문과 답변 (2026): 코딩, 기초, 설계, 행동 면접
소프트웨어 엔지니어 면접 질문
소프트웨어 엔지니어링 면접
코딩 면접 질문
SWE 면접 준비
소프트웨어 개발자 면접 질문

소프트웨어 엔지니어 면접은 대부분의 회사에서 익숙한 순서를 따릅니다. 채용 담당자와의 통화, 코딩 라운드 한두 번, 중급 및 시니어 직무의 시스템 디자인 라운드, 그리고 행동 면접 라운드입니다. 아래에는 라운드별로 묶은 소프트웨어 엔지니어 면접 질문 20개와 답변이 있습니다. 모든 코드 샘플은 게시 전에 수천 개의 무작위 입력으로 전수 탐색 버전과 대조해 검증했습니다.

각 라운드가 평가하는 것

라운드일반적인 형식평가 기준
채용 담당자 스크리닝전화로 20~30분경력 배경, 지원 동기, 연봉 범위, 일정 등 실무 사항
코딩공유 편집기에서 45~60분문제 해결, 깔끔한 코드, 테스트, 작업하면서 말하기
CS 기초코딩 중간에 섞이거나 별도 라운드사용하는 시스템을 이해하고 있는지 여부
시스템 디자인화이트보드나 문서로 45~60분트레이드오프, 규모, 명확한 의사소통
행동 면접30~45분책임감, 협업, 실패를 다루는 방식

신입 졸업생 면접은 주로 코딩과 행동 면접으로 이뤄집니다. 시니어 면접에서는 시스템 디자인이 더해지고, 과거 프로젝트에 대해 더 깊은 답변을 기대합니다. 채용 담당자와의 통화는 전화 스크리닝 면접 질문 글을 참고하세요.

코딩 질문

모든 코딩 라운드에서는 입력하기 전에 접근 방식을 먼저 말하고, 시간 복잡도와 공간 복잡도를 밝힌 뒤, 마지막에 작은 예시로 테스트하세요. 복잡도 부분은 Big O 치트시트에서 다룹니다.

1. 두 수의 합: 목표 값을 만드는 두 숫자의 인덱스 반환하기

각 숫자의 인덱스를 해시 맵에 저장하세요. 새 숫자가 나올 때마다 그 짝(목표 값에서 뺀 값)이 이미 맵에 있는지 확인하세요.

def two_sum(nums, target):
    seen = {}
    for i, x in enumerate(nums):
        if target - x in seen:
            return [seen[target - x], i]
        seen[x] = i
    return []

print(two_sum([2, 7, 11, 15], 9))  # [0, 1]

시간 복잡도 O(n), 공간 복잡도 O(n)입니다. 전수 탐색 버전은 모든 쌍을 O(n²)으로 확인하는데, 면접관은 보통 먼저 이를 언급한 뒤 개선하기를 기대합니다.

2. 유효한 괄호: 모든 괄호가 올바른 순서로 닫혔는지 확인하기

여는 괄호를 스택에 넣으세요. 닫는 괄호가 나오면 스택의 맨 위가 짝이 되는 여는 괄호여야 합니다.

def is_valid(s):
    pairs = {")": "(", "]": "[", "}": "{"}
    stack = []
    for ch in s:
        if ch in pairs:
            if not stack or stack.pop() != pairs[ch]:
                return False
        else:
            stack.append(ch)
    return not stack

print(is_valid("([]{})"), is_valid("(]"))  # True False

시간 복잡도 O(n), 공간 복잡도 O(n)입니다. 마지막 줄이 중요합니다. “((” 같은 문자열은 스택에 항목이 남아서 유효하지 않습니다.

3. 겹치는 구간 병합하기

시작 시각 순으로 정렬한 뒤, 마지막으로 병합된 구간을 늘리거나 새 구간을 시작하세요.

def merge_intervals(intervals):
    merged = []
    for start, end in sorted(intervals):
        if merged and start <= merged[-1][1]:
            merged[-1][1] = max(merged[-1][1], end)
        else:
            merged.append([start, end])
    return merged

print(merge_intervals([[1, 3], [2, 6], [8, 10], [15, 18]]))
# [[1, 6], [8, 10], [15, 18]]

정렬 때문에 시간 복잡도는 O(n log n)입니다. [1, 2]와 [2, 3]처럼 맞닿은 구간을 병합할지 면접관에게 물어보세요. 이 버전은 병합합니다.

4. 연결 리스트 뒤집기

리스트를 한 번 순회하면서 각 노드가 이전 노드를 가리키도록 바꾸세요.

class ListNode:
    def __init__(self, val, next=None):
        self.val = val
        self.next = next

def reverse_list(head):
    prev = None
    while head:
        head.next, prev, head = prev, head, head.next
    return prev

시간 복잡도 O(n), 추가 공간 복잡도 O(1)입니다. 다중 할당문이 면접관에게 너무 교묘해 보인다면, 임시 변수를 쓴 세 줄짜리 코드로 쓰세요. 짧은 것보다 명확한 것이 낫습니다.

5. 가장 많이 나온 원소 k개 반환하기

해시 맵으로 개수를 센 뒤, 힙으로 가장 큰 개수 k개를 고르세요.

from collections import Counter
import heapq

def top_k_frequent(nums, k):
    counts = Counter(nums)
    return [x for x, _ in heapq.nlargest(k, counts.items(), key=lambda p: p[1])]

print(top_k_frequent([1, 1, 1, 2, 2, 3], 2))  # [1, 2]

시간 복잡도 O(n log k)입니다. 후속 질문으로는 빈도별 버킷 정렬이 자주 나오는데, 이 방법은 O(n)을 얻습니다.

6. get과 put이 O(1)인 LRU 캐시 설계하기

빠른 조회와 최근 사용 순서에 따른 빠른 재정렬이 필요합니다. 해시 맵과 이중 연결 리스트를 함께 쓰면 둘 다 해결됩니다. Python에서는 OrderedDict가 정확히 그 조합입니다.

from collections import OrderedDict

class LRUCache:
    def __init__(self, capacity):
        self.capacity = capacity
        self.data = OrderedDict()

    def get(self, key):
        if key not in self.data:
            return -1
        self.data.move_to_end(key)
        return self.data[key]

    def put(self, key, value):
        if key in self.data:
            self.data.move_to_end(key)
        self.data[key] = value
        if len(self.data) > self.capacity:
            self.data.popitem(last=False)

면접관에 따라 연결 리스트를 직접 구현하라고 요구할 수 있습니다. 먼저 구조를 설명하세요. 맵은 리스트 노드를 가리키고, 가장 최근 노드는 한쪽 끝에 놓이며, 다른 쪽 끝에서 제거합니다.

7. 벽이 있는 격자에서 최단 경로 찾기

모든 이동 비용이 같다면 너비 우선 탐색(BFS)으로 최단 경로를 찾을 수 있습니다.

from collections import deque

def shortest_path(grid):
    rows, cols = len(grid), len(grid[0])
    if grid[0][0] or grid[rows - 1][cols - 1]:
        return -1
    queue = deque([(0, 0, 0)])
    seen = {(0, 0)}
    while queue:
        r, c, steps = queue.popleft()
        if (r, c) == (rows - 1, cols - 1):
            return steps
        for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)):
            nr, nc = r + dr, c + dc
            if 0 <= nr < rows and 0 <= nc < cols and not grid[nr][nc] and (nr, nc) not in seen:
                seen.add((nr, nc))
                queue.append((nr, nc, steps + 1))
    return -1

print(shortest_path([[0, 0, 0], [1, 1, 0], [0, 0, 0]]))  # 4

시간과 공간 복잡도는 O(rows × cols)입니다. 셀을 큐에서 꺼낼 때가 아니라 큐에 넣을 때 방문 표시를 하세요. 그렇지 않으면 같은 셀이 여러 번 큐에 들어갑니다.

8. 첫 번째 잘못된 버전 찾기

버전 1부터 n까지는 어느 시점까지 정상이고 그 뒤로는 잘못됩니다. 이진 탐색을 쓰면 O(log n)번의 확인으로 첫 번째 잘못된 버전을 찾을 수 있습니다.

def first_bad_version(n, is_bad):
    lo, hi = 1, n
    while lo < hi:
        mid = (lo + hi) // 2
        if is_bad(mid):
            hi = mid
        else:
            lo = mid + 1
    return lo

이 패턴은 한 번만 바뀌는 예/아니요 질문이라면 어디에든 적용되며, 실제로 자주 나옵니다. 이런 패턴을 다루는 문제 목록은 Blind 75를 참고하세요.

CS 기초 질문

9. 프로세스와 스레드의 차이는 무엇인가요?

프로세스는 자체 메모리 공간을 가진 실행 중인 프로그램입니다. 스레드는 프로세스 안에서 실행되며 그 메모리를 공유합니다. 스레드는 생성과 전환 비용이 낮고 데이터를 직접 공유할 수 있지만, 바로 그 공유 때문에 락이 필요하고 경쟁 상태(race condition)가 생깁니다. 프로세스는 서로 격리되어 있어서 하나가 충돌해도 다른 프로세스가 함께 죽지 않습니다.

10. TCP와 UDP의 차이는 무엇인가요?

TCP는 연결을 설정하고, 재전송과 흐름 제어로 순서가 보장되고 신뢰할 수 있는 전달을 보장합니다. UDP는 독립적인 패킷을 보내며 전달이나 순서를 보장하지 않지만 오버헤드가 적습니다. 웹 페이지, API, 파일 전송에는 TCP를 쓰세요. 실시간 음성, 영상, 게임처럼 늦게 도착한 패킷이 어차피 쓸모없는 경우에는 UDP가 적합합니다. 더 자세한 내용은 컴퓨터 네트워크 면접 질문을 참고하세요.

11. 브라우저 주소창에 URL을 입력하고 Enter를 누르면 무슨 일이 일어나나요?

브라우저는 DNS로 도메인을 IP 주소로 바꾸고, TCP 연결을 열며, HTTPS라면 TLS 핸드셰이크를 합니다. HTTP 요청을 보내면 서버(종종 로드 밸런서 뒤에 있음)가 응답을 돌려줍니다. 브라우저는 HTML을 파싱하고, 그 안에서 참조하는 CSS, JavaScript, 이미지를 요청한 뒤 페이지를 렌더링합니다. 면접관이 고른 부분을 더 깊이 설명하세요.

12. 해시 테이블은 어떻게 동작하며, 시간 복잡도는 얼마인가요?

해시 함수가 각 키를 배열의 버킷으로 매핑합니다. 조회, 삽입, 삭제는 평균적으로 O(1)입니다. 두 키가 같은 버킷에 들어가면 체이닝이나 다른 슬롯 탐색(probing)으로 충돌을 처리하고, 너무 차면 크기를 다시 늘립니다. 많은 키가 충돌하면 최악의 경우 O(n)입니다.

13. NoSQL 대신 SQL 데이터베이스를 언제 선택하나요?

데이터가 관계형이고 조인과 트랜잭션이 필요하며 스키마가 비교적 안정적이면 SQL을 선택하세요. 예를 들면 주문, 결제, 사용자 계정입니다. 접근 패턴이 단순하거나 데이터 구조가 다양하거나, 여러 대의 기계에 걸쳐 쓰기를 확장해야 하면 문서형이나 키-값 저장소를 선택하세요. 많은 시스템이 둘 다 씁니다. 면접관이 원하는 답은 승자를 고르는 것이 아니라 트레이드오프입니다. 그 위에 보통 올라가는 API 계층은 REST API 면접 질문에서 다룹니다.

시스템 디자인 질문

14. URL 단축기 설계하기

먼저 요구 사항을 명확히 하세요. 하루에 새로 만드는 링크 수, 조회 수, 링크 만료 여부, 사용자 지정 별칭 허용 여부 등을 확인합니다. 그다음 API(생성과 리다이렉트), 짧은 코드를 만드는 방법(base 62로 인코딩한 카운터, 또는 유일성 검사를 거친 무작위 코드), 저장소(코드에서 URL로 가는 키-값 저장소), 그리고 인기 링크를 위한 캐시를 설명하세요. 읽기가 쓰기보다 훨씬 많기 때문입니다. 시간이 남으면 분석과 악용 방지로 마무리하세요. 전체 설계는 시스템 디자인 가이드에서 자세히 다룹니다.

15. 레이트 리미터 설계하기

어디에서 동작하는지(API 게이트웨이, 사용자별 또는 API 키별)와, 클라이언트가 한도를 넘었을 때 무슨 일이 일어나는지(재시도 시간과 함께 HTTP 429 반환)부터 시작하세요. 토큰 버킷이 흔한 선택입니다. 각 클라이언트는 고정 속도로 다시 채워지고 최대 토큰 수를 가진 버킷을 갖고, 요청마다 토큰 하나를 씁니다. 짧은 버스트는 허용하면서 평균 속도는 제한합니다. 서버가 여러 대라면 카운터를 Redis 같은 공유 저장소에 두어 모든 서버가 같은 횟수를 보게 하세요. 연습하려면 시스템 디자인 면접 질문을 참고하세요.

행동 질문

각 이야기는 명확한 구조로 말하세요. 상황, 한 일, 결과 순서이며, 숫자가 있다면 숫자를 넣으세요.

16. 자기소개를 해 주세요

경력을 2분 분량으로 요약하고, 이 직무에 지원하는 이유로 마무리하세요. 구체적인 결과가 있는 프로젝트 한두 개를 언급하세요. 저희 자기소개 질문 가이드에 예시가 있습니다.

17. 해결했던 어려운 버그에 대해 말해 주세요

샘플 답변: “저희 결제 서비스가 하루에 몇 번씩 패턴 없이 타임아웃되기 시작했습니다. 요청 ID를 로그에 추가했더니, 모든 타임아웃이 장바구니에 상품이 50개를 넘을 때만 실행되는 하나의 데이터베이스 쿼리에서 나온다는 것을 찾았습니다. 쿼리의 조인 컬럼에 인덱스가 없었습니다. 인덱스를 추가하자 느린 쿼리가 약 4초에서 50밀리초 미만으로 줄었고, 다음번에는 더 일찍 잡아낼 수 있도록 그 쿼리의 지연 시간에 알림을 추가했습니다.”

18. 팀원과 의견이 충돌했던 경험에 대해 말해 주세요

샘플 답변: “한 팀원이 알림 서비스를 새 프레임워크로 다시 쓰자고 했는데, 출시 전이라 위험이 너무 크다고 생각했습니다. 회의에서 언쟁하는 대신, 각자 비용과 위험을 적어 보자고 제안했습니다. 출시 전에 현재 코드의 가장 심각한 문제 두 가지를 고치고, 재작성은 다음 분기로 계획하기로 합의했습니다. 출시는 제때 이뤄졌고, 두 달 뒤 제대로 된 테스트 계획과 함께 재작성을 진행했습니다.”

19. 실패했던 프로젝트에 대해 말해 주세요

본인이 일부 책임을 졌던 실제 실패를 고르세요. 무엇이 잘못되었는지, 다르게 한다면 무엇을 할지, 그 뒤에 무엇을 바꿨는지 설명하세요. 면접관은 완벽한 기록이 아니라 정직함과 배움을 확인하려는 것입니다.

20. 왜 이 회사에서 일하고 싶은가요?

회사의 제품이나 엔지니어링 작업에서 구체적인 점 하나를 본인의 경험과 연결하세요. “2년 동안 귀사의 API를 사용해 왔고, 플랫폼 쪽에서 일하고 싶습니다”가 “훌륭한 회사라서요”보다 낫습니다.

면접관에게 할 질문

  • 이 팀에서 일하는 사람의 일주일은 보통 어떤가요?
  • 업무는 어떻게 계획되고, 우선순위는 누가 정하나요?
  • 여기서 코드 리뷰와 배포는 어떻게 진행되나요?
  • 입사 후 첫 6개월 동안 성공은 어떤 모습인가요?
  • 팀이 지금 풀고 있는 가장 어려운 기술 문제는 무엇인가요?

더 많은 내용은 면접 마지막에 할 질문을 참고하세요.

준비 방법

  1. 언어 하나를 정해서 모든 연습 문제에 쓰세요. 코드가 짧아서 Python이 가장 흔한 선택입니다. 언어 자체에 대해서는 Python 면접 질문에서 다룹니다.
  2. 개수보다 유형별로 연습하세요. 해시 맵, 투 포인터, 슬라이딩 윈도우, 이진 탐색, BFS와 DFS, 힙, 동적 프로그래밍이 있습니다.
  3. 타이머를 켜고 소리 내어 문제를 푸세요. 말없이 푼 정답 풀이는 명확하게 설명한 풀이보다 점수가 낮습니다.
  4. 실제로 쓸 편집기에서 연습하세요. 많은 회사가 CoderPad를 쓰며, CoderPad에는 무료 샌드박스가 있습니다.
  5. 대부분의 행동 면접 질문에 맞게 바꿔 쓸 수 있는, 본인 업무에서 나온 이야기 다섯 개를 준비하세요.
  6. 중급 및 시니어 직무라면, 누군가 후속 질문을 던지는 완전한 시스템 디자인 연습을 최소 몇 번은 하세요.

코딩 면접을 소리 내어 연습하세요

YesToTheOffer가 답변을 텍스트로 변환해 주어, 풀이를 어떻게 설명했는지 돌아볼 수 있습니다. 스크린샷을 0.2배속으로 보며 코딩 도움도 받을 수 있습니다. 30분 무료, 구독 없음.

iOS & Android — 출시 예정
요금 보기