주니어 자바 개발자를 위한 100가지 질문 - 기초

cxoxee·2023년 10월 14일

Java

목록 보기
9/10

기초

# JDK와 JRE의 차이점은 무엇입니까?

JRE

  • Java Runtime Environment
  • 자바 실행 환경.
  • JVM뿐만 아니라 Java binaries, Java 클래스 라이브러리 등 다양한 파일을 포함하고 있어 자바 프로그램의 실행을 지원한다.
  • But, 컴파일러나 디버거등의 도구는 포함하지 않는다.
  • 따라서 자바 프로그램을 개발하는 것이 아니라 실행하기만 원한다면 JRE를 설치하면 된다.

JDK

  • Java Development Kit
  • 자바 개발 키트.
  • 자바 애플리케이션을 개발하기 위한 환경을 지원.
  • JDK는 JRE를 포함할 뿐만 아니라 컴파일러(javac), javadoc, jar 등 개발에 유용한 도구들을 포함하고 있다.
  • 따라서 자바 프로그램을 개발하기 위해서는 JDK를 다운받아야 한다.

정리, JRE는 자바 실행 환경이고, JDK는 자바 개발 도구이다. 자바 프로그램을 개발하려면 JDK를 다운받으면 된다.

# == 와 equals의 차이점은 무엇입니까?

==

  • Equal Operator
  • 비교 연산자
  • 두 값을 비교하여 두 값이 동일하면 ‘true’를, 다를 경우 ‘false’를 반환한다.
  • ‘true/false’ 를 반환하기 때문에 암시적으로 데이터 타입의 형변환이 발생할 수 있기 때문에 주의해야 한다.
  • int, float 등의 기본 데이터 타입의 비교에 주로 사용된다.

equals()

  • 메서드이다.
  • 클래스가 equals() 메서드를 오버라이딩(재정의)하여 자기 자신의 내부 상태를 비교하도록 구현해야 한다.
  • 두 객체를 비교하여 내용이 동일하면 ‘true’를, 다를 경우 ‘false’를 반환한다.
  • 사용자 정의 클래스 or 문자열같은 객체 비교에 주로 사용한다.

정리

  • 차이점 : ‘==’는 비교 연산자이고, ‘equals()’는 메서드이다. ‘==’는 대상의 주소값을 비교하고, ‘equals()’는 값 자체를 비교한다.
  • 공통점 : 둘 다 값을 비교하여 boolean 타입을 반환한다.

# 두 객체가 동일한 hashCode를 가지면 Equals()가 참이어야 합니다. 그렇죠?

  • 아니요.
  • 두 객체의 hashCode가 동일하다면, 두 객체는 같은 해시 버킷에 저장될 수 있다는 것을 의미한다.
  • But, ‘equals()’는 객체의 실제 내용을 비교하는 메서드이기 때문에 같은 hashCode 값을 가지고 있더라도 언제나 ‘true’를 반환하지 않을 수 있다.

정리, 해시 테이블에서 같은 해시 버킷에 저장되어 동일한 해시 코드 값을 가지고 있더라도 실제 두 객체의 내용이 다르다면 ‘equals()’ 메서드는 ‘false’를 반환하게 된다.

→ ‘equals()’ 메서드의 결과에 따라 반환 값이 결정된다.

# 자바에서 final 기능은 무엇입니까?

  • 더 이상 변경할 수 없도록 하는 역할.
  • 초기화하면 최종적인 값이 되어 프로그램 실행 도중 수정할 수 없다.
  • 변수, 메서드, 클래스에 사용된다.
  • 변수
    • 값이 변경되지 않도록 한다.
    • 변수를 대문자로 작성한다.
  • 메서드
    • 오버라이드 할 수 없도록 한다. → 메서드의 동작이 변경되지 못하도록 하기 위해.
    • 보안성 강화
  • 클래스
    • 상속 방지 → 다른 클래스에서 상속할 수 없음.
    • 보안상의 이유

# 자바에서 Math.round(-1.5)는 무엇을 의미합니까?

  • -1
  • Math.round() 는 static method로 가장 가까운 정수로 반올림된 숫자 값을 반환한다.
  • Java Math 클래스

# String은 기본 데이터 타입입니까?

  • 참조 데이터 타입이다.
  • Stack 영역이 아닌 Heap 영역에 저장된다.
  • 또한, String은 불변이라
  • String str = “a”;
  • str + “b”; 를 하게 되면,
  • “a” 메모리에 글자를 더하는 게 아니라 “ab” 메모리를 새로 만들어 주소를 재참조하는 형식이다.

# 자바에서 문자열을 조작하는 클래스는 무엇입니까? 각 클래스의 차이점은 뭘까요?

  • String 클래스, StringBuilder 클래스, StringBuffer 클래스
StringStringBuilderStringBuffer
불변가변가변
스레드 안전스레드 불안전스레드 안전
→ 멀티스레드 환경에 적합
  • 정리, 각 클래스의 주요 차이점은 불변성 여부와 스레드 안전성이다.

    • ‘String’은 불변하고 스레드 안전하며, ‘StringBuilder’는 가변하고 스레드 안전하지 않다. ‘StringBuffer’는 가변하고 스레드 안전하므로 멀티스레드 환경에서 안전하게 사용할 수 있다.
    • 작업의 특성과 성능, 스레드 안전성 요구사항에 따라 선택하면 된다.
  • String 클래스

    • ‘java.lang.String’ 클래스는 불변한 문자열을 나타낸다. → 문자열이 한 번 생성되면 수정할 수 없다.
    • 문자열을 연결하거나 변환하는 작업마다 새로운 문자열을 생성한다.
    • 주로 문자열을 저장하고, 비교하는 데 사용된다.
  • StringBuilder 클래스

    • ‘java.lang.StringBuilder’ 클래스는 가변한 문자열을 나타낸다. → 문자열을 동적으로 수정할 수 있다.
    • 문자열을 연결하거나 수정하는 작업에 사용하며, 작업 중간에 문자열의 길이나 내용을 효율적으로 변경할 수 있다.
    • 주로 문자열 조작 성능이 중요한 경우 사용된다.
  • StringBuffer 클래스

    • ‘java.lang.StringBuffer’ 클래스는 ‘java.lang.StringBuilder’와 유사하게 가변한 문자열을나타낸다.
    • ‘StringBuilder’와의 주요 차이점은 ‘StringBuffer’는 스레드 안전하기 때문에 멀티스레드 환경에서 안전하게 사용할 수 있다. → 스레드 안전성이 필요한 경우 ‘StringBuffer’ 사용.
    • 단일 스레드의 경우 ‘StringBuilder’를 사용하는 것이 성능상 더 효율적일 수 있다.

# String str= “i” 와 String str = new String(”i”) 가 동일합니까?

  • 다르다.

  • 저장된 공간이 다르다. → 저장된 공간의 메모리 주소도 다름.

  • String str = ”i”;

    • 문자열 리터럴을 사용하여 문자열을 생성하는 것.
    • 이 경우, 문자열 상수 풀(string pool)에 저장된다.
    • 문자열 상수 풀은 문자열을 재사용하며, 동일한 문자열 리터럴을 사용하면 동일한 문자열 객체를 참조한다.
    • 따라서 ‘”i”’는 이미 메모리에 존재하는 문자열을 가리키게 된다.
  • String str = new String(”i”);

    • ‘new’ 키워드를 사용하여 새로운 문자열 객체를 생성하는 것. → 항상 새로운 문자열 객체를 만든다.
    • 문자열 리터럴과는 별개의 새로운 문자열 객체가 생성되며, 그 객체를 참조한다.
  • 정리, ‘”i”’와 ‘new String(”i”)’는 두 개의 다른 문자열 객체를 생성하며, 메모리 상에서 다른 위치에 저장된다.

    • 일반적으로 문자열 리터럴을 사용하는 것이 문자열을 효율적으로 관리하고, 중복을 피하기 위해 권장된다.
    • 필요한 경우에만 ‘new String()’을 사용해야 한다.

# 문자열을 반전시키는 가장 좋은 방법은 무엇인가요?

  • ‘StringBuilder’ 객체를 생성하고 ‘reverse()’ 메서드를 호출하는 것.
  • StringBuilder로 반전시키는 법
String str = "abcde";

StringBuilder reversed = new StringBuilder(str);

reversed.reverse();

String result = reversed.toString();

System.out.println(result); //출력: edcba
  • 배열로 반전시키는 법
String str = "abcde";
	
char[] charArray = str.toCharArray();
char[] reversed = new char[charArray.length];

for (int i = charArray.length-1; i >= 0; i--) {
		reversed[charArray.length-1-i] = charArray[i];
}

String result = new String(reversed); 

System.out.println(result); //출력: edcba

# String 클래스의 일반적인 메서드는 무엇이 있나요?

String 클래스

  • 불변 객체(immutable object) → String 인스턴스는 한 번 생성되면 그 값을 읽기만 할 수 있고, 변경할 수는 없다.
  • 즉, 자바에서 덧셈(+) 연산자를 이용하여 문자열 결합을 수행하면, 기존 문자열의 내용이 변경되는 것이 아니라 내용이 합쳐진 새로운 String 인스턴스가 생성되는 것입니다.
메소드설명
char charAt(int index)해당 문자열의 특정 인덱스에 해당하는 문자를 반환함.
int compareTo(String str)해당 문자열을 인수로 전달된 문자열과 사전 편찬 순으로 비교함.
int compareToIgnoreCase(String str)해당 문자열을 인수로 전달된 문자열과 대소문자를 구분하지 않고 사전 편찬 순으로 비교함.
String concat(String str)해당 문자열의 뒤에 인수로 전달된 문자열을 추가한 새로운 문자열을 반환함.
int indexOf(int ch)
int indexOf(String str)
해당 문자열에서 특정 문자나 문자열이 처음으로 등장하는 위치의 인덱스를 반환함.
int indexOf(int ch, int fromIndex)
int indexOf(String str, int fromIndex)
해당 문자열에서 특정 문자나 문자열이 전달된 인덱스 이후에 처음으로 등장하는 위치의 인덱스를 반환함.
int lastIndexOf(int ch)해당 문자열에서 특정 문자가 마지막으로 등장하는 위치의 인덱스를 반환함.
int lastIndexOf(int ch, int fromIndex)해당 문자열에서 특정 문자가 전달된 인덱스 이후에 마지막으로 등장하는 위치의 인덱스를 반환함.
String[] split(String regex)해당 문자열을 전달된 정규 표현식(regular expression)에 따라 나눠서 반환함.
String substring(int beginIndex)해당 문자열의 전달된 인덱스부터 끝까지를 새로운 문자열로 반환함.
String substring(int begin, int end)해당 문자열의 전달된 시작 인덱스부터 마지막 인덱스까지를 새로운 문자열로 반환함.
String toLowerCase()해당 문자열의 모든 문자를 소문자로 변환함.
String toUpperCase()해당 문자열의 모든 문자를 대문자로 변환함.
String trim()해당 문자열의 맨 앞과 맨 뒤에 포함된 모든 공백 문자를 제거함.
length()해당 문자열의 길이를 반환함.
isEmpty()해당 문자열의 길이가 0이면 true를 반환하고, 아니면 false를 반환함.

# 추상 클래스에서 추상 메서드는 필수적인가요?

  • 필수적이지 않다.
  • 추상메서드 : 구현을 제공하지 않은 메서드 → 자식 클래스는 반드시 구현해야 함(오버라이딩).

# 보통 클래스와 추상 클래스의 차이는 무엇인가요?

  • 추상 메서드의 유무와 직접 객체 생성 가능 여부.
  • 추상 클래스는 객체를 생성할 수 없다. → 상속을 통해서 자식 클래스에서만 객체를 생성할 수 있다.
  • 보통 클래스는 직접 개체를 생성할 수 있다.
  • 보통 클래스는 자식 클래스에게 특정 메서드를 구현하라고 강요할 수 없고, 추상 클래스는 부모 클래스가 가지는 추상 메서드를 자식 클래스에서 반드시 구현해야 한다.

# final은 추상 클래스를 수정할 때 사용할 수 있나요?

  • final 키워드는 클래스, 메서드 및 변수에 사용할 수 있으며, 해당 요소를 수정할 수 없도록 만듭니다.
  • 따라서 final을 사용한 클래스나 메서드는 상속되지 않고, 재정의되거나 수정되지 않습니다.
  • final 키워드를 클래스에 적용하면 해당 클래스는 상속될 수 없으므로 추상 클래스와 함께 사용하는 것은 일반적으로 모순됩니다. 추상 클래스는 하위 클래스에서 구현이 제공되어야 하므로, 상속을 허용하지 않는 final 클래스와는 목적과 설계가 다릅니다.
  • 따라서 추상 클래스와 final 키워드를 동시에 사용하는 것은 일반적으로 의미가 없습니다. 추상 클래스는 상속을 통해 확장하고 서브클래스에서 구체적인 동작을 제공하기 위해 사용됩니다.
  • 만약 클래스를 수정할 수 없도록 만들고자 한다면 final 키워드를 사용하되, 추상 클래스로 만들지 않는 것이 일반적인 접근 방법입니다.
  • 어차피 final과 abstract이 같이 붙으면 컴파일 단계에서 에러 발생함.

0개의 댓글