티스토리 뷰
초급
문제1. 변수를 선언하는 방법에 대해 설명하세요. 예를 들어 정수형 변수를 선언하고 초기화하는 코드와 함께 설명해 보세요.
int num = 10;
final double PI = 3.14;
int col, row = 10; // col = 0, row = 10
먼저 데이터 타입 명시가 필요하다. 위의 예시처럼 변수를 선언함과 동시에 초기화도 가능하다.
final 키워드로 상수선언도 할 수 있다.
한 줄에 여러 개의 변수를 선언할 수 있지만 지양된다고 한다. 의도치 않은 초기화가 발생할 수 있고 여러 변수가 한 줄에 혼재된다는 점이 가독성을 떨어뜨리기 때문이다.
인텔리제이에서는 여러 개의 변수를 한 줄에 선언 후 초기화하면 다음과 같은 컴파일 에러가 발생한다.
🚫 Variable ‘col' might not have been initialized
초기화 되지 않아 사용할 수 없는 에러 발생
int col = 10, row = 10;
모든 변수에 대해 초기화를 잘해주자.
문제2. 다음 조건에 맞는 코드를 작성하세요.
- String 타입의 변수 greeting을 선언하고, 초기값으로 "Hello, SungbinClub!"를 할당하세요.
- 변수 greeting을 출력하세요.
String greeting = "Hello, SungbinClub!";
System.out.println(greeting);
문제3. 변수명을 지을 때 지켜야 하는 세 가지 명명 규칙을 제시하고, 적절한 변수 이름의 예시와 부적절한 변수 이름의 예시 각각 두 가지를 작성하세요.
변수명을 작성할 때 지켜야 하는 규칙은 다음과 같다.
- 숫자로 시작할 수 없다.player1, num2 (O)
- 1time, 126 (X)
- 공백이 들어갈 수 없다.userEmail, totalAmount (O)
- user email, total amount (X)
- 자바 예약어로만 구성된 변수를 사용할 수 없다.
- public, case, switch (X) isPublic, switchDirectionBy (O)
보편적으로 자바에서 변수명을 지을 때 카멜케이스를 이용한다. arrIdx, userName 등
abc와 같은 의미를 알 수 없는 무의미한 이름도 바람직하지 않으니 최대한 로직으로써의 변수의 의미를 잘 담도록 정해보자!
중급
문제1. 다음 조건에 맞는 코드를 작성하세요.
- final 키워드를 사용하여 상수 변수 DEFAULT_LIMIT를 int 타입으로 선언하고 초기값을 50으로 설정하세요.
- DEFAULT_LIMIT 값을 출력하고, 값을 변경하려 할 때 발생하는 에러 메시지를 확인하세요.
static final int DEFAULT_LIMIT = 50;
System.out.println(DEFAULT_LIMIT);
DEFAULT_LIMIT = 100;
DEFAULT_LIMIT인 상수를 변경하려 한다면 다음과 같은 컴파일 에러가 발생한다.
🚫 Cannot assign a value to final variable 'DEFAULT_LIMIT’
왜 발생할까?
‘final’이라는 키워드는 값을 초기 한번만 할당 할 수 있도록 하는 제약이 있다.
그렇기 때문에 JVM은 컴파일 시점 이 상수가 불변성이 보장되었는지 확인한다. 정확히는 클래스 로더에서 loading을 끝낸 후 바이트코드가 JVM의 명세에 맞는지 확인하는 과정에서 final 필드에 재할당 시도가 있었는지 검사하는 것.
메모리 사용 측면이나 데이터를 공유하는 스레드 간 실행안정성을 위해 필요한 작업 같다.
문제2. 다음 코드에서 각 변수(localValue, instanceValue, staticValue)가 JVM 메모리의 어느 영역에 저장되는지 설명하세요.
public class VariableExample {
public static int staticValue = 10;
public int instanceValue = 20;
public void method() {
int localValue = 30;
System.out.println(localValue);
}
}
일단 클래스 로더를 거쳐서 런타임 데이터 영역에 저장된다. 런타임 데이터 영역은 크게 네 부분으로 나눌 수 있다.
- 메서드 영역
- 메서드 영역은 일종의 테이블인 런타임 상수 풀을 가지고 클래스와 인터페이스의 상수들을 효율적으로 저장한다.
- 클래스 구조, static 변수, 메서드의 바이트코드 등이 저장된다.
- 힙 영역
- new로 생성한 객체, 인스턴스, 배열 등이 있다. 이런 것들은 당연히 최적화를 위해 GC의 대상이 된다.
- 프로그램에서 데이터 저장을 위해서 런타임 중에 동적으로 할당되는 변수들이 저장된다.
- 스택 영역
- 메서드가 호출될 때 생성되는 스레드 수행정보를 기록하는 프레임이 저장된다.
- 메서드 정보, 지역변수, 매개변수, 연산 중에 생기는 임시데이터 등
- 메서드가 끝날 때 까지 사용된다.
- PC 레지스터
- 컴퓨터의 CPU와 같이 실행 중인 JVM 명령어 주소가 저장되어 있다.
위 내용을 참고하면
staticValue는 클래스의 static 변수로 메서드 영역에 저장된다. 런타임 상수 풀에 저장되어 효율적으로 관리될 것이다.
instanceValue는 인스턴스 변수로 힙 영역에 저장된다. 런타임 중에 값이 할당되고 GC의 대상이 된다.
localValue는 메서드 안의 지역변수로 스택 영역에 저장된다. 메서드가 끝날 때까지 유효하다.
문제3. 변수 초기화와 리터럴의 차이점을 설명하고, 다음 코드에서 리터럴과 초기화된 변수를 구분하여 설명하세요.
double price = 99.99;
int quantity = 5;
boolean isAvailable = true;
변수 초기화는 변수를 선언한 뒤 처음으로 값을 할당하는 과정이다. 값 자체에 관심이 있다기 보다 값을 변수에 저장하고 재사용하기 위한 목적이 크다.
리터럴은 코드에서 직접적으로 표현되는 값 자체이며 실제 데이터 값에 의미가 있다.
첫 줄을 price라는 변수를 10이라는 정수 리터럴로 초기화했다.
두번째 줄은 quantity라는 변수를 5라는 정수 리터럴로 초기화했다.
세번째 줄은 isAvailable이라는 변수를 true라는 불리언 리터럴로 초기화했다.
고급
문제1. 메모리 효율성을 고려하여 static 키워드를 사용한 ItemCounter 클래스를 작성하세요.
- ItemCounter 클래스에 정적 변수 totalCount를 선언하고, 이를 증가시키는 addItem 메서드를 작성하세요.
- ItemCounter 클래스의 totalCount 변수가 인스턴스마다 공유되는지 확인하는 코드를 작성하세요.
- totalCount가 JVM의 어느 메모리 영역에 위치하는지도 설명하세요.
public class mission2 {
public static class ItemCounter {
private static int totalCount;
static void addItem(){
totalCount++;
}
public int getTotalCount(){
return this.totalCount;
}
}
public static void main(String[] args) {
ItemCounter counter1 = new ItemCounter();
ItemCounter counter2 = new ItemCounter();
System.out.println(ItemCounter.totalCount); //ItemCounter의 static 변수 totalCount 확인
counter1.addItem(); //counter1 totalCount 증가
counter1.addItem(); //counter1 totalCount 증가
System.out.println(counter1.getTotalCount()); // counter1 인스턴스의 TotalCount 확인
System.out.println(counter2.getTotalCount()); //counter1 변수 처리 후 counter2 인스턴스의 TotalCount 확인
counter2.addItem(); //counter2 totalCount 증가
System.out.println(counter2.getTotalCount()); //counter2 변수 처리 후 counter2 인스턴스의 TotalCount 확인
}
}
0 // 클래스 totalCount 값 초기
2 //counter1로 totalCount 증가 2번 결과
2 //counter2의 totaclCount 초기 값
3 // counter로 totalCount 증가 1번 결과
결과는 어떤 인스턴스로든 증가시킨 결과가 모두 동일하게 적용된다.
totalCount은 클래스의 static 변수로 메서드 영역에 저장된다.
클래스 로딩 시 초기에 한번만 메모리에 할당되고 생성되는 클래스의 인스턴스들은 이 메모리 공간을 공유한다.
문제2. 다음 코드의 각 변수들이 JVM 메모리 구조에서 어떻게 저장되고 관리되는지 설명하세요.
- 지역 변수, 인스턴스 변수, 정적 변수가 각각 어디에 저장되는지 설명하고, 코드의 totalAmount, orderCount, discountRate 변수가 해당하는 JVM 메모리 영역도 설명하세요.
public class Order {
public static double discountRate = 0.1;
public int orderCount = 0;
public void processOrder() {
double totalAmount = 200.0;
System.out.println(totalAmount * (1 - discountRate));
}
}
중급에서 JVM의 런타임 데이터 영역에 대해서 설명했다.
지역변수는 메서드 내에서 유효한 변수로 스택 영역에 저장된다. 위의 코드에서는 totalAmount가 해당한다고 볼 수 있다.
인스턴스 변수는 런타임 중 값이 할당되는 변수로 힙 영역에 저장된다. 위의 코드에서는 orderCount가 해당한다.
정적 변수는 메서드 영역에 저장되어 런타임 상수풀에서 관리된다. 위의 코드에서는 discountRate가 해당한다.
'Java' 카테고리의 다른 글
성빈클럽mission4 - 효율적으로 조건문 만들기 (2) | 2024.10.31 |
---|---|
성빈클럽mission3 - 연산자, 회로 단락 평가 (3) | 2024.10.31 |
성빈클럽mission1 - JVM과 System.out.println() (5) | 2024.10.30 |
[Eclipse]pom.xml xml태그 적용에러/Failed to create the part's controls 에러/이클립스 uninstall (0) | 2022.05.15 |
[Eclipse]프로젝트 import시 빨간색x박스에러+java.lang.UnsupportedClassVersionError (0) | 2022.03.03 |
- Total
- Today
- Yesterday
- 스터디
- gradlew권한에러
- 애자일로 가는 길
- 도커
- 오늘부터 개발자
- 자바 입문
- Eclipse
- jvm
- .travis.yml 빌드에러
- vscode
- 자바
- x박스에러
- 성빈클럽
- An error has occured
- Java
- 함께 자라기
- docker-compose
- 딥러닝
- 회로 단락 평가
- WSL2
- travis CI 에러
- docker
- 형변환
- 파이썬
- UnsupportedClassVersionError
- tuple
- 엘리스코딩
- eclipse 삭제
- jvm is not suitable for this product
- xml태그적용 에러
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |