목차
개요
이번 포스팅에서 나오는 주요 키워드
- JRE, JDK, JVM: 자바 실행 환경(JRE)과 개발 환경(JDK)의 차이점은 JRE는 실행만 가능하고, JDK는 개발 도구까지 포함. JVM은 자바 바이트 코드를 실행하며, 플랫폼 독립성을 제공.
- 저급언어 vs 고급언어: 저급언어는 하드웨어에 종속적이고 이식성이 낮으며, 고급언어는 사람이 이해하기 쉬워 이식성이 높음.
- 컴파일러 vs 인터프리터: 컴파일러는 소스 코드를 전체 번역 후 실행 파일 생성. 인터프리터는 한 줄씩 번역과 실행을 동시에 수행.
- 파이썬과 자바의 실행 방식: 파이썬은 인터프리터 방식으로 즉시 실행, 자바는 컴파일 후 바이트 코드 생성 및 JVM 실행.
- .java 파일 vs .class 파일: .java는 사람이 작성한 소스 코드 파일, .class는 컴파일된 바이트 코드 파일로 JVM에서 실행 가능.
- main 메서드: 자바 프로그램의 시작점으로 JVM이 이를 찾아 실행.
- 자바의 플랫폼 독립성: 컴파일된 바이트 코드를 플랫폼별 JVM이 실행하므로 독립성 보장.
- 변수: 값이 저장되는 메모리 공간. 기본형은 스택에, 참조형은 힙에 저장.
- 명명 규칙: 변수 이름은 영문자, 숫자, 언더스코어, 달러 기호 사용 가능하며 예약어는 불가. 의미 있는 이름과 카멜 표기법 권장.
- var 키워드: Java 10부터 타입 추론 지원. 지역 변수에만 사용 가능하며 초기화 값 필수.
- 자바 vs 자바스크립트 변수 선언: 자바는 강타입 언어로 타입을 명시하거나 추론, 자바스크립트는 약타입 언어로 타입 명시 불필요하며 var, let, const 사용.
- boolean 타입 크기: JVM 구현에 따라 다르며 일반적으로 1바이트.
- 지역 변수 초기화: JVM이 초기값을 할당하지 않아 초기화하지 않으면 컴파일 오류 발생.
- long vs float: long은 64비트 정수형으로 정밀도가 높고 범위가 제한적. float은 32비트지만 부동소수점 방식으로 더 큰 범위 표현 가능.
- 문자열 비교: == 연산자는 주소값 비교, equals()는 실제 값 비교. 값 비교 시 equals() 사용 권장.
- 리터럴: 프로그램에 고정된 값. 정수형(10), 실수형(3.14), 문자형('A'), 문자열("Hello"), 논리형(true).
- String 포맷 형식: %[flags][width][.precision]conversion. flags는 정렬과 부호, width는 최소 폭, precision은 정밀도, conversion은 형식 지정.
- switch 구문: Java 7부터 String 지원. 해시코드 기반 최적화. long은 처리 비용 때문에 미지원.
본문
Q1. JRE, JDK, JVM 개념의 차이점을 설명해주세요
A1. JRE(Java Runtime Environment)은 자바 프로그램을 실행하기 위한 환경을 제공하는 소프트웨어 패키지이다.
JDK(Java Development Kit)는 자바 프로그램을 개발하기 위한 환경을 제공하며, JRE와 개발 도구를 포함한다.
JVM(Java Virtual Machine)은 자바 바이트 코드를 실행하는 가상 머신으로, 플랫폼에 종속적이다.
Q2. 저급언어와 고급언어의 개념과 차이점을 설명해주세요
A2. 저급언어는 기계어에 가까운 언어로 하드웨어에 최적화된 프로그램을 작성할 수 있으나 이식성이 떨어진다.
고급언어는 사람이 이해하기 쉬운 언어로, 하드웨어에 독립적이고 이식성이 높아 프로그램을 빠르게 작성할 수 있다.
Q3. 컴파일러와 인터프리터의 차이점을 설명해주세요.
A3. 컴파일러는 전체 소스 코드를 기계어로 번역하여 실행 파일을 생성한다.
반면, 인터프리터는 소스 코드를 한 줄씩 번역하고 실행하며, 번역된 코드를 즉시 실행한다.
Q4. 파이썬과 자바를 컴파일러와 인터프리터의 개념과 함께 차이점을 설명해주세요.
A4. 파이썬은 인터프리터 언어로 소스 코드를 실행 시 즉시 번역하고 실행한다.
자바는 컴파일러 언어로, 전체 소스 코드를 번역해 바이트 코드를 생성한 후 JVM이 실행한다.
Q5. 자바의 .java 파일과 .class 파일의 차이점을 설명해주세요.
A5.
.java 파일은 자바 소스 코드 파일로 사람이 읽을 수 있는 텍스트 파일이다.
.class 파일은 컴파일된 바이트 코드 파일로, JVM이 실행 가능한 이진 파일이다.
Q6. 자바를 실행시킬 때 main이라는 메서드가 필요한 이유를 설명해주세요.
A6. main 메서드는 프로그램의 시작점이며, JVM이 이를 찾아 실행한다. main 메서드가 종료되면 프로그램도 종료된다.
*https://www.javatpoint.com/java-main-method
Q7. main 메서드가 없어도 컴파일은 가능하지만 실행이 불가능한 이유를 컴파일러 javac와 JVM의 역할과 함께 설명해주세요.
A7. 컴파일러(javac)는 문법 검사를 통해 바이트 코드로 변환하지만, 실행은 JVM이 담당한다.
JVM은 프로그램의 시작점을 main 메서드로 인식하기 때문에 main 메서드가 없으면 실행할 수 없다.
Q8. 자바가 플랫폼에 독립적인 이유를 설명해주세요.
A8. 자바는 바이트 코드와 JVM 덕분에 플랫폼 독립적이다.
자바 컴파일러는 바이트 코드를 생성하며, 플랫폼에 종속적인 JVM가 이를 실행한다.
Q9. 변수의 정의와 컴퓨터 내 저장 구조를 설명해주세요.
A9. 변수는 값을 저장하는 메모리 공간으로, 메모리 주소와 값을 통해 데이터를 저장하고 읽는다.
변수 이름을 통해 해당 메모리 주소를 간접적으로 참조할 수 있다.
Q10. 기본형 변수와 참조형 변수의 차이점을 설명해주세요.
A10. 기본형 변수는 데이터를 직접 저장하며, 스택 메모리에 저장된다.
참조형 변수는 데이터의 주소를 저장하며, 힙 메모리에 동적으로 할당된다.
*https://java-programming.mooc.fi/part-5/3-primitive-and-reference-variables
Q11. 자바의 변수 명명 규칙을 설명해주세요.
A11. 변수 이름은 영문자, 숫자, 언더스코어(_), 달러($)로 구성할 수 있으며, 숫자로 시작할 수 없습니다.
대소문자를 구분하며 예약어를 사용할 수 없습니다. 의미 있는 이름과 카멜 표기법을 권장합니다.
Q12. 자바에서 변수 선언 시 var 키워드를 사용할 수 있는 경우와 사용할 수 없는 경우를 설명해주세요.
A12. var 키워드는 Java 10부터 지원되며 지역 변수의 타입을 추론할 때 사용됩니다.
초기화 값이 필요하며, 메서드 매개변수, 클래스 필드 등에는 사용할 수 없습니다.
Q13. 자바와 자바스크립트의 변수 선언 방식과 차이점을 설명해주세요.
A13. 자바는 Strongly Typed Language로 데이터 타입을 명시해야 하고, var 키워드로 타입을 추론할 수 있습니다.
자바스크립트는 Weakly Typed Language로 데이터 타입을 명시하지 않아도 되고, var, let, const 키워드를 사용합니다.
Q14. boolean 타입의 변수의 크기는 몇 바이트인지 설명해주세요.
A14. boolean 타입은 JVM의 구현에 따라 다르지만 일반적으로 1바이트 크기를 가지며, true와 false 값을 저장하는 데 사용됩니다.
Q15. 지역 변수는 초기화하지 않고 사용할 수 없는 이유에 대해서 설명해주세요.
A15. 지역변수의 구조를 확인해보면 컴파일 타임에는 초기화되지 않은 상태로 할당되며, JVM이 기본값을 부여하지 않는다는 특성이 있다.
값이 전역적으로 존재하는 특성을 가진 전역 변수와 달리, 특정 메서드나 함수 내부에서만 사용하는 변수의 관리에 따른 메모리의 효율성과 예측 가능한 동작을 위해 설계된 것이다.
초기화를 하지 않고 해당 변수를 사용하면, 값이 존재하지 않아 예기치 못한 동작이나 오류가 발생할 수 있으므로, 컴파일러가 이러한 상황을 사전에 막기 위해 초기화 여부를 체크힌다.
따라서 자바 컴파일러는 런타임 오류를 줄이고 프로그램의 안정성을 높이기 위해서 지역 변수가 반드시 초기화된 후 사용되도록 강제한다.
Q16. long과 float 자료형을 비교하자면 메모리 할당 크기는 long이 float보다 크지만, float이 long보다 큰 수를 표현할 수 있는 이유를 설명해주세요.
A16. long은 정수형 데이터 타입으로, 8바이트 크기를 가지며, 부호를 포함한 64비트 정수 값을 저장할 수 있습니다.
float은 실수형 데이터 타입으로, 4바이트 크기를 가지며, IEEE 754 표준에 따라 32비트 부동 소수점 값을 저장할 수 있습니다.
부동 소수점 방식은 소수점의 위치를 고정하지 않고, 가수와 지수로 나누어 실수를 표현하는 방식으로, 더 넓은 범위의 수를 표현할 수 있습니다.
따라서, float은 long보다 더 큰 수를 표현할 수 있지만, 정밀도가 떨어지기 때문에 정밀한 계산이 필요한 경우에는 double을 사용하는 것이 좋습니다.
Q17. 자바에서 문자열을 비교할 때 == 연산자와 equals() 메서드의 차이점을 설명해주세요.
A17.자바에서 문자열을 비교할 때 == 연산자는 두 문자열의 주소를 비교하는 연산자이고, equals() 메서드는 두 문자열의 값을 비교하는 메서드입니다.
연산자는 두 문자열의 주소를 비교하기 때문에, 두 문자열이 같은 주소를 참조하고 있는 경우에만 true를 반환합니다.
equals() 메서드는 두 문자열의 값을 비교하기 때문에, 두 문자열이 같은 값을 가지고 있는 경우에 true를 반환합니다.
따라서, 문자열의 값을 비교할 때는 equals() 메서드를 사용하는 것이 안전하고, 문자열의 주소를 비교할 때는 == 연산자를 사용하는 것이 효율적입니다.
2025.01.20 - [Java] - 예제로 배우는 자바 String Pool 이해하기
Q18. 하지만 ==로도 String 비교가 가능한 경우가 있습니다. 그 이유를 설명해주세요.
A18. 문자열 리터럴은 상수 풀(Constant Pool)에 저장되며, 동일한 리터럴은 동일한 주소를 참조합니다. 따라서 == 연산자로 비교해도 true를 반환할 수 있습니다.
Q19. 리터럴이 뭔가요? 리터럴의 종류와 예시를 설명해주세요.
A19. 리터럴은 프로그램에서 고정된 값을 의미하며, 정수형(10), 실수형(3.14), 문자형('A'), 문자열("Hello"), 논리형(true, false) 등이 있습니다.
Q20. String의 포맷 문자 형식을 설명해주세요. %[flags][width][.precision]conversion
A20. %[flags]는 출력 형식을 지정하는데 사용되며, -는 왼쪽 정렬, +는 부호 표시, 0은 빈 자리를 0으로 채움을 의미합니다.
%[width]는 출력 폭을 지정하는데 사용되며, 출력 폭은 최소 폭을 의미합니다.
%[.precision]은 출력 정밀도를 지정하는데 사용되며, 정수의 경우 소수점 이하 자리수를, 문자열의 경우 최대 길이를 의미합니다.
conversion은 출력 형식을 지정하는데 사용되며, d는 10진수, o는 8진수, x는 16진수, f는 실수, s는 문자열을 의미합니다.
Q21. switch 구문은 처음 설계될 당시 문자열을 사용할 수 없었지만, Java 7에서 허용되었습니다. 반면, 여전히 long은 사용할 수 없습니다. 이러한 설계 목적과 이유를 설명해주세요.
A21. switch 구문의 설계는 성능 최적화와 특정 데이터 타입의 사용 제한을 염두에 두고 이루어졌습니다.
사례를 통해 설계 이념(?) 을 확인해보면
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
1. String이 Java 7 이전에 지원되지 않았던 이유
초기 Java 설계에서 switch는 간단한 정수 기반 분기를 위해 만들어졌습니다.
이를 통해 컴파일러는 내부적으로 테이블 점프(table jump) 또는 바이너리 검색(binary search) 방식을 사용하여 매우 빠른 실행 속도를 제공할 수 있었습니다.
하지만 String은 참조 타입으로, 문자열 비교는 equals() 메서드를 사용해야 하고 해시코드 계산이 필요하기 때문에, 초기에는 switch 설계에서 제외되었습니다.
2. Java 7 이후 String이 지원된 이유
Java 7에서는 String 비교를 위한 최적화가 도입되었습니다.
내부적으로 switch는: 각 문자열의 해시코드를 기반으로 case를 구분합니다.
동일한 해시코드를 가진 문자열에 대해서는 equals() 메서드로 추가 확인을 수행합니다.
이를 통해 문자열 비교를 효율적으로 처리할 수 있게 되어, switch에서 String 사용이 허용되었습니다.
3. long이 여전히 지원되지 않는 이유
switch는 정수 기반 분기에 초점이 맞춰져 있습니다. long은 64비트 크기를 가지며, 이를 분기로 사용하기 위해서는 더 많은 메모리와 복잡한 처리가 필요합니다.
대부분의 경우, long을 switch에서 사용하는 사례는 드물며, 복잡한 비교가 필요한 경우 if-else가 더 적합합니다.
설계의 간소화를 위해 long은 지원하지 않는 것으로 유지되고 있습니다.
출처 & 추가로 알아보면 좋은것
- JVM 내부 구조
- Class Loader, Memory Area(Stack, Heap), Execution Engine.
- 2024.06.25 - [Java] - JVM스택메모리 구조 이해를 위한 바이트코드 예시
- 자바 컴파일 과정
- .java → .class → JVM 실행 과정
- 메모리 관리
- 가비지 컬렉션과 메모리 최적화 전략
- 2024.07.20 - [Java] - 자바 가비지 컬렉터(GC)의 발전; 시리얼 컬렉터부터 ZGC까지
- 멀티스레드 환경에서의 변수
- Thread-safe 변수와 동기화.
- 자바와 자바스크립트의 주요 차이점
- 언어의 기본 철학 및 사용 사례 비교.
'Java' 카테고리의 다른 글
예제로 배우는 제한자와 자바변수 설계 전략 (1) | 2025.01.22 |
---|---|
예제로 배우는 자바가 배열을 생성하는 원리 이해하기 (0) | 2025.01.21 |
예제로 배우는 자바 String Pool 이해하기 (0) | 2025.01.20 |
Java 조각모음 [2] (0) | 2025.01.17 |
Java 조각모음 [1] (1) | 2025.01.16 |