Program

프로그램이 컴파일되어, 실행되는 과정을 간략하게 설명해 주세요.

Build
Build는 무엇을 짓다라는 뜻이다. 프로그래밍에서 컴퓨터는 기본적으로 0과 1밖에 모르기 때문에 우리가 작성한 고급 언어인 소스 코드를 바로 이해하기란 불가능하다. 따라서 우리가 작성한 소스 코드를 CPU가 이해할 수 있는 기계어로 바꾸어 줘야 하는데, 이 과정을 Build라고 한다.

https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd3s6bS%2FbtqNRJdufUI%2FfUfigVgPdDFR8rIAVMdQu1%2Fimg.png

Build를 하는 방식은 다음과 같이 크게 세 가지로 구분할 수 있다.

TypeProcess
Compile소스코드 전체를 기계어로 번역
Interpreted소스코드를 한 줄씩 번역하면서 실행
Hybrid소스코드 전체를 중간 코드 (바이트 코드)로 번역한 뒤 가상머신에서 한 줄씩 실행

링커와 로더의 차이에 대해 설명해 주세요.

컴파일 언어와 인터프리터 언어의 차이에 대해 설명해 주세요.

Compile (C++)

컴파일 타입은 우리가 작성한 소스 코드를 한꺼번에 번역해서 실행 파일로 만든다. 한마디로 말하자면 통번역이다. 이렇게 한 번에 번역하는 언어들을 보통 Compile Language라고 하는데, 대표적으로 C, C++, Go 언어가 있다.

https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlANHp%2FbtqNU1kYGLA%2FZ5ksDLwxxBxmqTOhgYlb40%2Fimg.png

Preprocessing (전처리): 전처리기에 의해 소스코드에 포함된 매크로나 지시자 같은 것들을 포함시켜 주는 과정이다. 소스코드의 중심이 실행되기 전에 사전에 준비하는 과정이라고 생각하면 된다. 예를 들어 #include #define 등을 준비한다.

Compilation (컴파일): 컴파일러는 번역만 하는 것이지 실행할 수 있는 파일을 만드는 것은 아니다. C나 C++을 다뤄 보았다면 gcc, g++ 같은 컴파일러를 들어봤을 수도 있다. 컴파일러로 컴파일하면 바로 기계어가 되는 것이 아니라 저수준 언어인 어셈블리어로 번역된다.

Assemble (어셈블): 이제 어셈블리어를 기계어로 번역해 주는 것이 어셈블러이다. CPU가 이해할 수 있는 Object file (목적 파일)로 만들어 준다. 목적 파일은 링크 단계 전까지는 각 파일별로 번역되기 때문에 그 번역된 파일 하나하나가 실행하는 최종 파일의 일부분으로 객체처럼 작용한다고 생각하면 된다.

Link (링크): 목적 파일은 기계어가 이해할 수 있는 번역본일 뿐 실행할 수 있는 파일은 아니다. 따라서 목적 파일들과 필요한 라이브러리들을 연결시켜 주고 최종적으로 하나의 실행 가능한 파일로 만들어 주는 것을 링킹이라고 한다.

컴파일 언어의 장점

  • 빌드가 완료된 실행 가능한 파일은 실행 속도가 빠르다.
  • 매번 번역할 필요 없이 실행 파일만 실행하면 되기 때문에 전체적인 시간적으로 효율적이다.

컴파일 언어의 단점

  • 프로그램을 수정해야 할 경우 처음부터 다시 빌드 과정을 거쳐야 하기 때문에 대규모 프로젝트에서는 생산성이 떨어진다.
  • 플랫폼에 매우 의존적이다. (어셈블리어가 CPU 명령 체계에 1:1 매칭이기 때문에 운영체제에 따라 다르게 동작할 수도 있다)

Interpreted (Python, Javascript)

소스코드를 통번역하는 것이 아니라 한 명령 단위로 해석하면서 즉시 실행하는 방법이다.

https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbO2Oo5%2FbtqOeBdcHxz%2FWlUKczXrK02kNeE787Aa50%2Fimg.png

위 사진처럼 목적 파일을 생성하지 않고 바로 실행된다는 것이 가장 큰 특징이다. 쉽게 말하면 소스 코드의 한 명령 세트마다 기계어로 번역하면서 바로바로 실행할 수 있게 해 주는 방식을 인터프리트라고 한다. 그리고 이렇게 번역해 주는 프로그램 또는 환경을 인터프리터라고 한다. 실행 가능한 파일이 없는 거라고 생각될 수도 있는데, 소스 코드 그 자체가 실행 가능한 파일이 되는 것이다.

인터프리트 언어의 장점

  • 컴파일 과정 없이 바로 실행되기 때문에 수정, 디버깅에 유리해 개발 속도가 빠르다.
  • 각 플랫폼에 지원하는 인터프리터만 있다면 실행 가능하기 때문에 플랫폼에 독립적이다.

인터프리트 언어의 단점

  • 빌드되어 있는 컴파일 언어보다 실행 시간이 느리다.
  • 코드를 열면 다 보이기 때문에 보안에 좋지는 않다.

JIT에 대해 설명해 주세요.

자바는 바이트 코드 명령어를 하나씩 읽어서 해석하고 바로 실행한다. JVM 안에서 바이트코드는 기본적으로 인터프리터 방식으로 동작한다. 다만 같은 메소드라도 여러 번 호출이 된다면 매번 해석하고 수행해야 해서 전체적인 속도는 느리다.

이러한 인터프리터의 단점을 보완하기 위해 도입된 방식이다. 반복되는 코드를 발견하여 바이트 코드 전체를 컴파일한 후 Native Code로 변경하고 이후에는 해당 메서드를 더 이상 인터프리팅하지 않고 캐싱해 두었다가 네이티브 코드로 직접 실행하는 방식이다.

한 번 캐싱된 메소드는 다시 호출되었을 경우 또 해석하지 않고 캐싱해 둔 네이티브 코드를 직접 실행하는 것이다. 따라서 인터프리팅 방식보다 빠르다.

하지만 바이트 코드 전체를 네이티브 코드로 변환하는 데에는 많은 비용이 소요되기 때문에, JVM은 모든 코드를 JIT 방식으로 실행하지 않고 인터프리터 방식을 사용하다가 일정 수준이 넘어가면 JIP 컴파일 방식으로 명령어를 실행한다.

본인이 사용하는 언어는 어떤 식으로 컴파일 및 실행되는지 설명해 주세요.

Hybrid (Java)

컴파일 방식과 인터프리트 방식을 혼합한 방법이다. 컴파일 언어의 단점은 실행 가능한 파일이 플랫폼에 의존적이라는 것이고, 인터프리트 언어의 단점은 실행 속도가 느리다는 것이다. 두 방식의 단점을 보완해서 나온 것이 하이브리드 방식이다. 바이트 코드 언어라고도 한다.

https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdm5iRN%2FbtqOnyVFdv9%2FakMnSPl9xg5WVxD4eqr6Ok%2Fimg.png

고급 언어로 작성된 소스코드를 바이트코드로 변환한다. 바이트 코드란 일종의 중간 언어라고 생각하면 된다. 그리고 가상 머신이라는 프로그램에서 바이트 코드를 기계어로 바꿔 준다. 가상머신은 우리가 만든 프로그램을 가상머신이라는 프로그램 위에서 실행시킨다고 생각하면 된다. 즉 각 플랫폼들에 맞는 가상머신이 만들어져 있다면, 플랫폼에 의존하지 않고 실행이 가능하다.

자바에서 JVM, JDK, JRE의 개념을 많이 헷갈려하는데, 정리하자면 다음과 같다.

JVM이 컴퓨터와 소통을 하고 Java Bytecode를 번역해 준다. 이때 우리가 작성한 Java 코드를 Java Bytecode로 번역해 주는 것이 JDK (Java Development Kit)이다. JDK는 자바를 개발하기 위한 도구 모음집이고, Java 언어를 java Bytecode로 변환해 주는 컴파일러 (javac)이고 Jaba Bytecode를 실행해 보기 위한 JVM이다.

JDK는 만들어진 자바 프로그램을 실행하는 데에는 필요하지 않다. 만들어진 프로그램을 쓰기만 하는데 개발 도구를 다 갖추지는 않기 때문이다. 따라서 프로그램의 실행을 위한 것만 따로 모은 것이 JRE (Java Runtime Environment)이다. JRE는 JVM과 JVM이 사용할 기타 라이브러리를 포함한 자바로 작성된 프로그램의 실행 환경이다.

https://velog.velcdn.com/images/morion002/post/e990b310-61bf-4414-a8b1-be383fc08c55/image.png

하이브리드 언어의 장점

  • 각 플랫폼에 지원하는 가상 머신이 있다면 실행 가능하기 때문에 플랫폼에 독립적이다.

하이브리드 언어의 단점

  • 컴파일 언어처럼 하드웨어를 직접 제어하는 작업은 불가능하다.

Python 같은 언어는 CPython, Jython, PyPy 등의 다양한 구현체가 있습니다. 각각은 어떤 차이가 있을까요? 또한 실행되는 과정 또한 다를까요?

CPython

CPython은 공식적으로 배포되고 있는 Python을 의미한다. Python은 Source-to-source Compiler (기존에 널리 사용되는 프로그래밍 언어를 사용하여 컴파일러를 작성한 언어)이므로 C언어로 작성된 컴파일러를 활용해 라인 단위로 Code를 인터프리팅하여 실행한다.

PyPy

PyPy는 Python의 self-hosted compiler (자신 언어로 컴파일러를 작성한 언어) 버전으로 컴파일러가 파이썬으로 작성되어 있다. 똑같은 인터프리트 언어이다.

Jython

JVM을 활용하는 Python 구현체 . 중하나로, Python syntax로 작성된 코드를 JVM이 이해할 수 있는 바이트 코드로 만들고 이 바이트 코드를 JVM이 실행한다.

우리가 흔히 fork() exec() 시스템 콜을 사용하여 프로그램을 적재할 수 있다고 배웠습니다. 로더의 역할은 이 시스템 콜과 상관 있는 걸까요? 아니면 다른 방식으로 프로세스를 적재할 수 있는 건가요?

로더
exec() 시스템 콜을 통해 프로세스를 적재하는 데 관여한다. 실행 파일을 읽고, 메모리를 초기화하고, 프로그램의 진입점을 설정하여 CPU가 실행을 시작할 위치를 정의하는 역할을 한다.

로더는 exec() 시스템 콜의 내부에서 동작하며, 프로그램의 실행 파일을 분석하고 메모리 배치를 수행하는 실질적인 작업을 담당한다.

커널 모듈 로드 등 커널 내부에서 프로그램을 적재할 수 있으나, 잘 사용하지 않는다.

0개의 댓글

Powered by GraphCDN, the GraphQL CDN