컴파일러와 인터프리터
프로그래밍 언어로 작성한 코드는 사람이 이해하기 쉬운 형태이다.
하지만 컴퓨터는 우리가 작성한 Python, C, Java 같은 코드를 그대로 이해하지 못한다. 컴퓨터가 실제로 실행할 수 있는 형태로 바꾸는 과정이 필요하다.
이때 사용하는 방식이 크게 두 가지로 나뉜다.
컴파일 방식
인터프리터 방식
컴파일 방식에서는 컴파일러가 사용되고, 인터프리터 방식에서는 인터프리터가 사용된다.
컴파일러
컴파일러(Compiler)는 소스 코드를 실행하기 전에 한 번에 기계어 또는 실행 가능한 형태로 변환하는 프로그램이다.
예를 들어 C언어로 작성한 코드는 컴퓨터가 바로 실행할 수 없다.
먼저 컴파일 과정을 거쳐 실행 파일을 만들어야 한다.
소스 코드
컴파일
실행 파일
프로그램 실행
C언어를 예로 들면 다음과 같은 흐름이다.
#include <stdio.h>
int main() {
printf("Hello World");
return 0;
}
이 코드는 사람이 읽을 수 있는 소스 코드이다.
컴파일러는 이 코드를 컴퓨터가 실행할 수 있는 실행 파일로 변환한다.
그다음 사용자는 만들어진 실행 파일을 실행한다.
hello.c
컴파일
hello.exe 또는 실행 파일
실행
컴파일러 방식에서는 실행 전에 변환 작업이 먼저 이루어진다.
컴파일러의 특징
컴파일러는 전체 코드를 한 번에 검사하고 변환한다.
그래서 실행 전에 문법 오류를 미리 발견할 수 있다.
예를 들어 코드에 문법 오류가 있으면 컴파일 단계에서 오류가 발생하고 실행 파일이 만들어지지 않는다.
코드 작성
컴파일
오류가 있으면 실행 파일 생성 실패
오류가 없으면 실행 파일 생성
컴파일이 완료된 뒤에는 실행 파일을 바로 실행할 수 있다.
실행할 때마다 다시 전체 코드를 변환하지 않아도 되기 때문에 실행 속도가 빠른 편이다.
대표적인 컴파일 언어에는 C, C++, Go, Rust 등이 있다.
대표적인 컴파일 언어
C
C++
Go
Rust
인터프리터
인터프리터(Interpreter)는 소스 코드를 한 줄씩 읽고 바로 실행하는 프로그램이다.
컴파일러처럼 실행 파일을 미리 만들어두는 방식이 아니라, 코드를 실행하는 시점에 해석하면서 동작한다.
Python을 예로 들어보자.
print("Hello World")
Python 코드는 별도의 실행 파일을 만들지 않고도 바로 실행할 수 있다.
소스 코드
인터프리터가 한 줄씩 해석
바로 실행
인터프리터는 코드를 읽으면서 그때그때 실행한다.
그래서 코드를 수정하고 바로 실행해보기 쉽다.
인터프리터의 특징
인터프리터는 실행 시점에 코드를 해석한다.
코드를 한 줄씩 실행하기 때문에, 개발 중에 빠르게 결과를 확인하기 좋다.
예를 들어 Python에서 코드를 조금 수정한 뒤 바로 실행하면 결과를 바로 볼 수 있다.
a = 10
b = 20
print(a + b)
이런 방식은 학습이나 실험, 데이터 분석, 스크립트 작성에 편리하다.
하지만 실행할 때마다 코드를 해석해야 하므로, 일반적으로 컴파일 방식보다 실행 속도가 느릴 수 있다.
대표적인 인터프리터 언어에는 Python, JavaScript, Ruby, PHP 등이 있다.
대표적인 인터프리터 언어
Python
JavaScript
Ruby
PHP
컴파일러와 인터프리터의 차이
컴파일러와 인터프리터의 가장 큰 차이는 코드를 언제 변환하느냐이다.
컴파일러는 실행 전에 전체 코드를 변환한다.
인터프리터는 실행하면서 코드를 해석한다.
| 구분 | 컴파일러 | 인터프리터 |
| 실행 방식 | 실행 전에 전체 코드를 변환 | 실행하면서 한 줄씩 해석 |
| 실행 파일 | 보통 실행 파일을 생성 | 보통 실행 파일을 따로 만들지 않음 |
| 오류 발견 | 컴파일 단계에서 발견 | 실행 중 해당 코드에 도달했을 때 발견 |
| 실행 속도 | 상대적으로 빠른 편 | 상대적으로 느릴 수 있음 |
| 개발 편의성 | 수정 후 다시 컴파일 필요 | 수정 후 바로 실행 가능 |
| 대표 언어 | C, C++, Go, Rust | Python, JavaScript, Ruby |
오류 확인 방식의 차이
컴파일러는 전체 코드를 먼저 검사한다.
그래서 코드 중간에 문법 오류가 있으면 실행 전에 알 수 있다.
printf("Hello World")
C언어에서 세미콜론을 빼먹었다면 컴파일 단계에서 오류가 발생한다.
인터프리터는 코드를 실행하면서 해석한다.
그래서 오류가 있는 줄에 도달했을 때 오류가 발생한다.
print("첫 번째 줄")
print("두 번째 줄")
print(unknown_value)
위 코드에서 unknown_value가 정의되어 있지 않다면, 앞의 두 줄은 실행된 뒤 세 번째 줄에서 오류가 발생한다.
이런 차이 때문에 컴파일 방식은 실행 전에 오류를 잡기 좋고, 인터프리터 방식은 코드를 빠르게 실행해보며 개발하기 좋다.
실행 속도의 차이
컴파일러 방식은 실행 전에 기계어에 가까운 형태로 변환해둔다.
그래서 실행 시점에는 이미 변환된 코드를 실행하면 된다.
반면 인터프리터 방식은 실행 중에 코드를 해석해야 한다.
그래서 일반적으로 실행 속도는 컴파일 방식이 더 빠른 편이다.
컴파일러
미리 번역해둔 뒤 실행
인터프리터
실행하면서 번역
다만 현대 언어들은 단순히 컴파일러와 인터프리터로만 나누기 어렵다.
Java, Python, JavaScript 같은 언어들은 내부적으로 바이트코드, JIT 컴파일 같은 방식을 함께 사용하기도 한다.
Java는 컴파일 언어일까 인터프리터 언어일까?
Java는 조금 특이하다.
Java 코드는 먼저 컴파일되어 바이트코드가 된다.
Java 소스 코드
컴파일
바이트코드
이 바이트코드는 JVM에서 실행된다.
JVM은 바이트코드를 해석하거나, 필요하면 JIT 컴파일을 통해 더 빠르게 실행할 수 있다.
.java
컴파일
.class
JVM에서 실행
그래서 Java는 단순히 컴파일 언어 또는 인터프리터 언어 하나로만 설명하기 어렵다.
컴파일 과정도 있고, 실행 환경에서 해석하거나 최적화하는 과정도 있다.
Python은 인터프리터 언어일까?
Python은 보통 인터프리터 언어로 분류한다.
하지만 Python도 내부적으로는 .py 파일을 바로 한 줄씩 기계어로 실행하는 것이 아니라, 바이트코드로 변환한 뒤 Python 가상 머신이 실행한다.
.py 파일
바이트코드 변환
Python 가상 머신에서 실행
그래도 사용자가 체감하는 방식은 인터프리터에 가깝다.
실행 파일을 따로 만들지 않고, 코드를 작성한 뒤 바로 실행할 수 있기 때문이다.
비유로 이해하기
컴파일러는 책 전체를 미리 번역해두는 것과 비슷하다.
외국어 책 한 권을 한국어로 전부 번역해 책으로 만들어두면, 읽을 때는 빠르게 읽을 수 있다.
컴파일러
전체 번역 후 읽기
인터프리터는 통역사가 문장을 들을 때마다 바로바로 통역해주는 것과 비슷하다.
미리 전체 번역본을 만들지는 않지만, 그 자리에서 바로 이해할 수 있게 도와준다.
인터프리터
한 문장씩 바로 통역
그래서 컴파일러는 준비 시간이 필요하지만 실행이 빠른 편이고, 인터프리터는 바로 실행하기 편하지만 실행 중 해석 비용이 생길 수 있다.
정리
컴파일러와 인터프리터는 사람이 작성한 소스 코드를 컴퓨터가 실행할 수 있도록 처리하는 방식이다.
컴파일러는 실행 전에 전체 소스 코드를 한 번에 변환한다.
컴파일이 끝나면 실행 파일이 만들어지고, 이후에는 그 실행 파일을 실행한다.
컴파일 방식은 실행 속도가 빠른 편이고, 실행 전에 오류를 발견하기 좋다.
다만 코드를 수정하면 다시 컴파일해야 한다.
인터프리터는 소스 코드를 실행하면서 한 줄씩 해석한다.
별도의 실행 파일을 만들지 않고 바로 실행할 수 있어 개발과 테스트가 편하다.
다만 실행 중에 해석 과정이 필요하므로 컴파일 방식보다 느릴 수 있다.
간단히 정리하면 다음과 같다.
컴파일러
실행 전에 전체 코드를 미리 번역한다.
인터프리터
실행하면서 코드를 그때그때 해석한다.
C, C++, Go, Rust는 대표적인 컴파일 언어이다.
Python, JavaScript, Ruby는 대표적인 인터프리터 언어로 자주 분류된다.
다만 현대 언어들은 컴파일과 인터프리터 방식을 함께 사용하는 경우도 많다. Java는 소스 코드를 바이트코드로 컴파일한 뒤 JVM에서 실행하고, Python도 내부적으로 바이트코드를 거쳐 실행된다.
'STUDY' 카테고리의 다른 글
| [자료구조] 스택, 큐, 링크드 리스트 구현 개념 정리 (0) | 2026.05.29 |
|---|---|
| [프로그래밍 기초] 정적 타이핑, 동적 타이핑, 강타입, 약타입 정리 (0) | 2026.05.29 |
| [객체지향] 객체지향 4대 특성 정리: 캡슐화, 상속, 다형성, 추상화 (0) | 2026.05.29 |
| [소프트웨어공학] UML 다이어그램 종류와 용도 정리 (0) | 2026.05.29 |
| [소프트웨어공학] SDLC 개발 방법론 정리: 폭포수, 나선형, 애자일/스크럼 (0) | 2026.05.29 |