포스트

(Day2) - 2일차_플랫폼, 기계어, 어셈블리와 자바

이 글은 제가 교육을 수강하며 기록한 내용입니다. 강사님과 무관하게 잘못된 내용이 있을 수 있습니다.


클라우드 기반 웹 데브옵스 프로젝트 개발자 교육 과정 (5기)

  • 비트캠프 엄진영 강사님 (https://github.com/eomjinyoung/)
  • 훈련기관 : 네이버클라우드주식회사
  • 기간: 2023-11-14 ~ 2024-5-22
  • 남은 일자 : 127 일 ( 2/129 )

2일(2023-11-15, 수)

CPU와 기계어(instruction set)의 관계를 설명할 수 있는가?

CPU는 기계어만을 통해 명령어와 데이터를 받을 수 있다. 기계어는 전자기적인 신호의 있고 없음으로 구성된다. 각기 다른 종류의 CPU마다 읽을 수 있는 기계어들의 집합이 다른데 이를 Instruction set 이라고 한다.

CPU는 정해진 명령어 집합으로만 제어할 수 있다. 전기 신호의 있고 없음으로만 명령을 줄 수 있다는 것이다. N비트 컴퓨터라면 CPU는 N개의 핀을 가지고 있어서 N 비트로 이뤄진 명령어를 받게 된다. 전기 신호가 있으면 1, 없으면 0이다. 기계어는 사전에 정해진 명령어들의 집합이므로 Instruction set 이라고 불린다.

동일한 CPU에 OS가 다를 때 프로그램이 호환되지 않는 이유를 설명할 수 있는가?

OS가 다른 경우 실행 파일의 형식이 다를 수 있기에 호환성을 보장할 수 없다.

실행파일의 형식
Windows는 PE라는 형식을, MacOS는 Mach-O 라는 형식을, 리눅스는 ELF(Executable and Linkable Format)을 쓴다. 실행 프로그램의 코드가 OS별로 형식이 다르기에, 호환되지 않는 형식을 사용하는 경우 호환성을 보장할 수 없는 것이다.

동일한 OS에 CPU 아키텍처가 다를 때 프로그램이 호환되지 않는 이유를 설명할 수 있는가?

사용하는 기계어 명령어 집합이 달라서 같은 이진 코드가 호환되지 않기 때문이다.

CPU 아키텍처가 다르다는 것은 CPU의 ISA(Instruction Set Architecture)가 다르다는 것이다. 즉 사용하는 기계어 명령어들이 호환이 안된다는 것이다.

동일한 OS라고 하더라도 다른 CPU이며 그 CPU들이 사용하는 ISA가 다르다면 같은 프로그램이 호환되지 않는다, 실행 파일의 이진 코드가 CPU와 호환되지 않는 명령어인 것이 그 이유이다.

어셈블리와 C 언어를 사용해 애플리케이션 만드는 과정을 설명할 수 있는가?

C 언어로 작성한 소스파일을 컴파일하면 어셈블리 언어를 거쳐 다시 기계어로 컴파일되어 실행된다.

어떤 경우에도 CPU는 기계어만 처리할 수 있다. 어셈블리 언어는 기계어를 사람이 읽기 쉽게 표현한 것이다.

어셈블리어는 Mnemonic으로 기계어 명령어를 대응시켜 사람이 기억하고 이해하기 쉽게 대응시켜 준 것이다. 기계어 그 자체는 아니므로 어셈블리어 또한 기계어로 컴파일(번역)하는 과정이 필요하며 이는 대부분 CPU 제조사에서 제공한다.

그런데 어셈블리 언어는 기계어의 명령어에 (대부분이) 일대일 대응되는 언어이다보니 CPU가 ISA가 달라지는 경우마다 어셈블리어가 달라지며, 간단한 프로그램을 만들 때도내려야 하는 명령이 많다보니 코딩 자체가 많이 힘들어진다.

C언어는 고수준 언어로, 소스 코드를 실행하려면 C -> Compiler -> Assembly -> Compiler -> Binary code 형태로 컴파일 및 실행된다. 왜 C Language가 등장했나? 어셈블리어는 (사실상) 기계어에 일대일 대응되는 언어이므로 아주 간단한 명령어들을 엄청나게 많이 써서 프로그래밍을 해야 한다. 이러면 프로그래머가 힘들어진다. 기계보다 사람에 가깝고 더 효율적인 작성이 가능한 언어에 대한 필요성이 생긴 것이다. 그래서 데니스 리치가 C언어를 만들었다.

Low-level 언어와 High-level 언어의 의미를 설명할 수 있는가?

저수준 언어(혹은 저급 언어)와 고수준 언어(혹은 고급 언어)는 기계어에 가깝냐, 사람에 가깝냐 를 기준으로 프로그래밍 언어를 분류하려는 용어이다.

저수준 = 기계에 가까움, 고수준 = 사람에 가까움.

오해하면 안된다. 저수준 혹은 고수준이라는 표현이 프로그래밍 언어의 좋고 나쁨을 평가하는 것이 아니다.

기계에 가깝다면 CPU를 제어하기 위한 명령어 집합(기계어)와 유사하다는 것으로, 이러한 언어를 저수준 언어라고 한다. 저수준 언어는 CPU의 명령어와 OS에 따라 달라질 수 있다. 따라서 생산성이 떨어진다. 그러나 기계어와 대응되는 언어라 별도의 처리 없이 바로 실행할 수 있어 성능에서 이점이 있다.

고수준 언어는 저수준 언어의 단점을 극복하기 위해 고안된 것이다. OS, CPU의 ISA에 의존적이지 않으며, 같은 일을 CPU에 시키더라도 저수준 언어보다 작성해야 하는 소스코드의 많이 양이 적다. 그래서 생산성이 높다.

자바 애플리케이션을 만드는 방법을 설명할 수 있는가?

자바는 고급 언어이며, 애플리케이션을 만들기 위해서는 우선 Java로 소스를 작성해야 한다. 소스가 작성되면 Java Compiler를 통해 bytecode(Portable code, p-code)로 컴파일한다. 그 결과로 바이트코드인 *.class 파일이 생성된다. 이 바이트코드는 OS 및 CPU에 종속성이 없다. 바이트코드는 binary code가 아니므로 cpu가 직접 실행할 수 없다. JVM을 통해서 실행하게 된다. JVM으로 바이트코드를 실행하며, JVM은 GC 역할도 수행한다. javac와 JVM은 jdk에 포함된 것이다.

Java Virtual Machine
JVM은 물리적인 머신을 소프트웨어를 통해 가상으로 구현한 것이다. 왜 JVM을 만들었나? 매번 ISA가 달라지는 환경마다 소스코드를 바꾸고 싶지 않고, 매번 다시 컴파일하고싶지 않기 때문이다. JVM만 여러 CPU와 OS에 대응시키는 것으로 끝내고 싶은 것이다.

REPL과 jShell 을 설명할 수 있는가?

REPL은 Read-Evaluate-Print-Loop 의 줄임말이다. 소스코드를 실행 가능한 라인 단위로 읽고, 실행하며, 그 결과를 출력하고, 다음 소스코드 라인에 REP를 Loop하는 것이 REPL이다. REPL은 소스코드를 실행하기까지의 긴 과정을 간소화하기 위해서 등장했다. jShell은 Java 언어에서 REPL을 구현하기 위한 쉘이다.

java의 경우 소스코드를 실행하기까지 javac(자바 컴파일러)를 사용하여 소스파일을 컴파일하고, 컴파일의 결과로 클래스 파일을 생성하고, 해당 클래스파일을 jvm에 넘겨주는 과정들이 있다. 매번 이렇게 하기 힘드니 구현된 것이다.

  • 요새는 IDE에서 이런 수고로움을 없애주지만, 소스코드를 컴파일하여 실행하기까지 그 과정은 변하지 않았기에 어떻게 소스파일이 실행되는지는 당연히 알아둬야 한다. 그걸 알아보면 REPL이 왜 등장했는지 알 수 있다.
쉘(Shell)
“쉘(shell)”은 사용자와 운영 체제(OS) 또는 컴퓨터 시스템 간의 인터페이스를 제공하는 프로그램 을 말한다.

JVM, JRE, JDK, JavaSE, JavaEE, JavaME를 설명할 수 있는가?

JVM(Java Virtual Machine)
자바 소스파일을 컴파일한 바이트코드의 실행기로, 바이트코드가 플랫폼(OS, CPU)에 비종속적일 수 있는 이유이다.
JRE(Java Runtime Environment)
자바로 만든 프로그램을 실행하기 위해 필요한 환경. JVM 및 필수 라이브러리로 이뤄짐.
JDK(Java Developer Kit)
Java 개발자를 위해 JRE에 개발자용 도구(컴파일러, 디버거, 프로파일러 등)가 추가된 개발자용 키트이다.
SE=Standard Edition, EE=Enterprise Edition, ME=Micro Edition
JDK의 목적별 에디션(~판) 이다.
용어설명
JVM (Java Virtual Machine)자바 언어로 작성된 프로그램을 실행하는 데 사용되며, 플랫폼 독립적인 실행 환경을 제공합니다.
JRE (Java Runtime Environment)자바 어플리케이션을 실행하기 위한 환경을 제공하며, JVM과 필수 라이브러리를 포함합니다.
JDK (Java Development Kit)자바 어플리케이션 및 애플릿을 개발하기 위한 도구와 라이브러리를 제공하는 패키지입니다.
JavaSE (Java Standard Edition)일반적인 자바 프로그램을 개발하고 실행하기 위한 표준 플랫폼을 제공합니다.
JavaEE (Java Platform, Enterprise Edition)대규모 엔터프라이즈 레벨의 자바 어플리케이션을 개발하고 실행하기 위한 확장된 플랫폼을 제공합니다.
JavaME (Java Platform, Micro Edition)제한된 자원을 가진 임베디드 시스템 및 모바일 기기에서 동작하는 자바 어플리케이션을 개발하고 실행하기 위한 플랫폼을 제공합니다.

JVM은 바이트코드를 실행하기 위한 것으로, 머신을 소프트웨어를 통해 가상으로 구현한 것이다. 이로서 자바는 환경(CPU와 OS)이 바뀔 때마다 컴파일하지 않고, 같은 바이트코드(클래스 파일)을 통해서 실행이 가능하게 된다.

JRE는 JVM 및 바이트코드 실행을 위한 관련된 파일들을 포함한 자바의 사용자용 환경을 말한다.

JDK는 JRE의 파일들에 더하여 컴파일러, 디버거, 프로파일러 등의 개발 도구가 추가된 개발자용 키트(묶음)을 말한다.

SE, EE, ME는 배포판(JDK, JRE)의 에디션으로, 일반 사용자용 Standard, 기업용 Enterprise, 자원이 제한된 임베디드 환경 등을 위한 Micro 에디션이 있다.

JDK를 설치하고 설정할 수 있는가?

이 질문에는 아주 많은 정답이 있을 수 있다. 어떤 JDK 구현체를 사용해야 하는지를 라이센스나 하드웨어 적합도 등에 따라 판단하는 일부터, JDK 버전 관리를 위해 어떻게 할 것인지 가이드를 잡는 일까지 말이다. (SDKManager 같은 솔루션도 있다.)

JAVA_HOME, PATH 환경 변수를 설정하는 이유를 알고 있는가?

CLI(Command Line Interface) 에서 명령어를 입력하면 그 명령어를 환경 변수에서 찾는다. 환경 변수에 자바가 사용하는 명령어가 저장되어 있지 않으면 그 명령어들을 찾을 수 없다. 그러면 명령어를 실행할 수 없으니 컴파일도 실행도 할 수 없다.

환경 변수
환경 변수는 운영 체제에서 사용되는 변수 로, 시스템 환경에 대한 정보를 저장하고 프로세스 간에 이 정보를 공유하는 데 사용됨.

VSCode를 설치하고 자바 애플리케이션 작성에 필요한 환경을 설정할 수 있는가?

사용하는 운영체제 및 CPU의 ISA에 따라 맞게 Visual Studio Code를 설치하라. Homebrew, apt-get, Chocolatey 같은 패키지 매니저를 사용하는 것도 방법이다.

설정에는 정답이 없다. 중요한 것은 다른 개발자들과 협력하기 편하도록 Style-Guide를 잡고 통일하도록 하자. Tab size, Indentation, Action on save, Formatter 등을 키워드로 잡고 설정하고, Visual Studio Code는 Extension 없이는 단순 편집기에 불과하므로 필요한 Extension을 설치해주자. Hex Editor 같이 16진수로 파일을 볼 수 있는 확장도 있고, 마크다운 파일을 렌더링하여 보여주는 뷰어도 있다.

Coding Convention
http://sideeffect.kr/popularconvention/

Coding Convention 은 주로 코드의 구조와 포맷에 관한 규칙을 나타내고, Style Guide는 더 큰 범위에서 코드 작성에 대한 일반적인 지침을 말하는 용어. 그러나 이 두 용어는 상황에 따라 혼용되기도 하고 명확히 의미를 지켜서 쓰지 않는 경우가 많음.

github.com 에 저장소를 생성할 수 있는가?

우선 git이 설치되어 있어야 한다. 유닉스, 리눅스 기반 운영체제들은 대부분 깃이 사전에 설치되어 있다. 윈도우의 경우 https://git-scm.com/ 에서 인스톨러를 설치하여 git과 bash를 설치해주자. github.com 은 깃 서버를 제공하는 회사 중 하나이며, 가입 후 Repository(저장소)를 브라우저를 통해 GUI를 통해서도 생성할 수 있다.

git
Global Information Tracker 라는 이름보다는 단순히 깃으로 더 많이 불린다. 버전관리를 위한 소프트웨어이다.
bash
born again shell 이다. 사용자에게 Command Line Interface를 제공하는 소프트웨어이다. 리눅스 명령어가 없는 윈도우 운영체제에서 리눅스 명령어를 쓸 수 있으므로 같이 설치하자.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.