Java 에 관한 정리

YEON·2022년 7월 12일
0

면접 준비

목록 보기
4/5

📝 java에 관해 공부한 것을 한 큐에👁 정리해보고자 합니다 (업데이트 상시 예정)


Java

Java의 특징

  • 객체지향 프로그래밍 언어
  • JVM(자바가상머신) 위에서 동작하기 때문에 운영체제에 독립적이다.
  • GC를 통한 자동 메모리 관리가 가능하다.
  • JVM 위에서 동작하기 때문에 실행 속도가 상대적으로 느리다.
  • 네트워크, 분산처리, 멀티쓰레드를 지원한다.
  • 동적 로딩을 지원한다.
  • 다중 상속이나 타입에 엄격하며 제약이 많다.

객체지향 프로그래밍(OOP)

자바가 객체지향 프로그래밍 언어이면, 자바가 지닌 객체지향 프로그래밍 특징은 무엇일까?

* 자세한 정리는 객체지향 포스팅 참조



Static

static 은 변수와 메소드에 선언하여 '공통적으로 같은 값을 유지' 하도록 만든다.

static(정적) 은 '공통적인, 고정된'이란 의미를 가지고 있다.
static 이라는 키워드를 사용하여 변수와 메소드에 선언하게 된다면 static 변수(정적 변수)와 static 메소드(정적 메소드)를 만들 수 있다. 이때, static 키워드를 사용한 변수나 메소드는 클래스가 메모리에 올라갈 때 자동으로 생성되므로, 인스턴스 생성 없이 바로 사용 가능하기 때문에 프로그램 내에서 공통으로 사용되는 데이터들을 관리할 때 이용합니다.

  • A. 인스턴스를 생성하면 각 인스턴스는 서로 독립적이기 때문에 다른 값을 유지한다.
  • B. 각 인스턴스들이 공통적으로 같은 값이 유지되어야 하는 경우 static을 붙인다.

메모리 할당

static 키워드를 통해 생성된 정적멤버들은 Heap 영역이 아닌 Static 영역에 할당된다.

Static 영역에 할당된 메모리는 모든 객체가 공유 하여 하나의 멤버를 어디서든지 참조할 수 있는 장점을 가진다. 때문에 static은 자주 변하지 않는 값이나 공통으로 사용되는 값 같은 공용자원에 대한 접근에 있어서 매번 메모리에 로딩하거나 값을 읽어들이는 것보다 일종의 '전역변수'와 같은 개념을 통해 접근하는 것이 비용도 줄이고 효율을 높일 수 있습니다.

하지만, Garbage Collector의 관리 영역(Heap) 밖에 존재하기 때문에 프로그램이 종료될 때까지 메모리에 값이 유지된 채로 존재하게 되므로 static을 남발하게되면 성능에 악영향을 줄 수 있다.

* 자세한 정리는 이전 static 과 객체지향적 관점 포스팅 참조



Final

final 은 클래스, 메소드, 변수, 인자를 선언할 때 사용하여 '변경 불가능' 하도록 만든다.

  • final class : 다른 클래스가 상속받지 못한다.
  • final method : 자식 클래스에서 상위 클래스의 final method를 오버라이드 하지 못한다.
  • final variable : 변하지 않는 상수 값이 되어서 새롭게 값을 할당할 수 없는 변수가 된다.

이때 불변 객체 란?

불변 객체는 객체 생성 이후 내부의 상태가 변하지 않는 객체이다.
Java에서는 필드가 원시 타입인 경우 final 키워드를 사용해 불변 객체를 만들 수 있다.
하지만, 참조 타입일 경우 에는 추가적인 작업이 필요하다.

* 자세한 정리는 이전 final 과 객체의 불변성 포스팅 참조



Wrapper class

객체지향 프로그래밍에서는 모든 것이 객체로 다루어져야 한다. 하지만 기본 자료형같은 경우 객체로 다루어지지 않는 것을 볼 수 있는데, 필요에 따라 기본형 변수도 객체로 다뤄야한다.
(ex. 매개변수로 객체를 요구하거나, 객체간의 비교가 필요한 경우 등)

이럴때 Wrapper class를 사용하여 기본형 값을 객체로 다룰 수 있다.

  • 기본 자료형: boolean, char, byte, short, int, long, float, double
  • 래퍼 클래스: Boolean, Character, Byte, Short, Integer, Long, Float, Double
    (* 이때, Boolean, Character 를 뺀 나머지는 추상 클래스 Number의 자손이다.)
  • 박싱: 기본 자료형(Primitive data type)을 Wrapper class로 바꾸어 주는 것
  • 언박싱: Wrapper class를 기본 자료형(Primitive data type)으로 바꿔주는 것

Primitive vs Reference

기본형(primitive type)에는 8개의 타입(자료형)이 있다.
boolean, char, byte, short, int, long, float, double

매개변수의 타입이 기본형일 때는 기본형 값이 복사되지만, 참조형이면 인스턴스의 주소가 복사된다.
주소가 복사된다는 의미는 값이 복사될 때와 다르게 주소에 직접 접근하여 변경을 시도하기 때문에 값의 변경이 이루어진다.



String

자바에서 String은 불변 객체(immutable instance)이다.

즉, 한 번 객체가 생성되면 할당된 메모리 공간이 변하지 않으므로,
String 연산(ex.substring, replace 등)을 하게 될 경우, 기존에 생성된 String 클래스 객체 문자열에 다른 새로운 문자열을 기존 문자열에 붙이는 것이 아니라 새로운 객체를 생성하게 된다. 때문에 문자열 연산이 많은 경우 성능이 좋지 않을 수 있다.

String은 두가지 생성 방식이 있고 그에 따라 각각 차이점이 존재한다.

  • new 연산자를 이용한 방식 : new 연산자로 생성하면 같은 내용이라도 여러 개의 객체가 각각 Heap 영역을 차지하게 된다.
  • =(리터럴)을 이용한 방식 : Heap 영역 내 String Constant Pool에 저장되어 재사용될 수 있다.
String name1 = new String ("kim"); //heap 영역에 생성
String name2 = "Lee"; //String pool에 객체 생성

String, StringBuilder, StringBuffer 의 차이는?

StringBuilder, StringBuffer 의 경우 String과 다르게 가변 객체(mutable)이다.
String과 다르게 memory 에 append 하는 방식 으로, 클래스에 대한 객체를 직접 생성하지 않는다.

다만, StringBuffer는 동기화를 지원하여 멀티 쓰레드 환경에서 주로 사용하며,
StringBuilder는 동기화를 지원하지 않아 싱글 쓰레드 환경에서 주로 사용한다.



interface vs abstract

abstract

abstract 는 '추상의, 미완성의' 의미를 지니고 있다.
추상클래스는 자식 클래스가 그 추상클래스를 상속받아서 기능을 이용하고 확장 시키는데 목적 이 있다.

추상 클래스는 클래스 내 추상 메소드가 하나 이상 포함되거나 선언부만을 작성하며, 실제 내용은 상속받는(extends) 자손 클래스에서 구현받아서 적절히 구현해야한다. (단일 상속만이 가능하다.)

interface

interface 도 일종의 추상 클래스이다. 다만, 모든 메소드가 추상 메서드와 상수로만 이루어져 있는 더 추상화된 형태이다.
상속받을 자손 클래스에게 구현할 메소드들의 원형(껍데기)을 모두 알려주어, 클래스가 자신의 목적에 맞게 메소드를
구현하도록 하는 것이다. 구현 객체의 같은 동작을 보장하기 위한 목적 이 있다

그 자체로만으로 사용된다기 보다는 상속(implements)을 통해 다른 클래스를 작성하는데 도움 줄 목적으로 작성된다. (다중상속이 가능하다.)



Overriding, Overloading

자바에서는 주로 오버로딩(Overloading)과 오버라이딩(Overriding)을 통해서 다형성을 지원한다.
(* 다형성 : 하나의 메서드나 클래스가 있을 때 그것이 다양한 방법으로 동작하는 것)

오버라이딩(Overriding)

Riding = 올라타다. (같은 함수를 올라타서 덮어 씌우고 새롭게 정의한다)

상위 클래스에 있는 메소드를 하위 클래스에서 상속받아 재정의 하는 것이다.
한마디로, 부모에게 물려받아 변형한 함수.

  • 오버라이딩을 사용하면 좋은 점
    같은 기능을 구현한 서브클래스에서 동일한 메소드를 사용함으로 써 코드의 복잡성과 일관성을 제공할 수 있다.
public interface LottoGenerator {
    List<LottoNumber> makeLottos();
}
public class RandomLottoGenerator implements LottoGenerator {
	private final List<LottoNumber> numbers;
    ...
	public List<LottoNumber> makeLottos() { //매개변수가 같아야한다.
        Collections.shuffle(numbers);
        return numbers.subList(LOTTO_NUMBER_START_INDEX, LOTTO_NUMBER_END_INDEX);
    }
}

오버로딩(Overloading)

Loading = 불러오다. (전혀 다른 함수를 불러오다)

매개변수의 개수나 타입을 다르게 하여 같은 이름의 메소드를 여러 개 정의하는 것이다.
한마디로, 이름은 같지만 그냥 전혀 다른 함수.

  • 오버로딩을 사용하면 좋은 점
    같은 기능을 하는 메서드를 하나의 이름으로 사용할 수 있다. (메서드의 이름을 절약할 수 있다.)
void setStudent(String name){
	this.name = name;
}

void setStudent(String name, ing age){ //매개변수가 다르다.
	this.name = name;
    this.age = age;
}





JVM

JVM(Java Virtual Machine) 이란?
OS에 종속받지 않고 CPU 가 Java를 인식하고 실행할 수 있게 하는 가상 머신이다.
(*가상머신 : 프로그램을 실행하기 위해 물리적인 머신과 유사한 머신을 소프트웨어로 구현한 것)

JVM의 역할

  • Java가 OS에 구애받지 않고 재사용을 가능하게 도움 (Java Byte Code를 OS에 맞게 해석)
  • 메모리 관리 (Garbage collection 수행)

메모리 영역

JVM의 메모리 영역(Runtime Data Area)은 프로그램을 수행하기 위해 OS에서 할당받은 메모리 공간이다.
크게 Method area, Heap, Thread 마다 생성되는 영역(PC Register, JVM Stack, Native method Stack)으로 볼 수 있다.

  • Method(Static) area : 클래스, static 변수, 변수, 메소드의 정보 등을 저장한다.
  • Heap : 인스턴스를 생성할 때 생성되는 메모리 형식으로, new 연산자 로 생성되는 객체와 배열을 저장한다.
  • PC Register : 스레드가 시작될 때 생성되며, 각 스레드가 메서드를 실행할 때 관련된 정보 등을 저장한다.
  • JVM Stack : 메서드가 호출될 때마다 스택 프레임 이 생성되며 메서드와 관련된 정보(지역 변수,리턴 값 등)를 저장하고, 메서드가 종료되면 프레임이 소멸된다.
  • Native method Stack : Java 외 다른 언어로 작성된 코드를 위한 영역이다.

Garbage collection

JVM의 메모리 관리 기법 중 하나이다.
JVM은 GC를 이용하여 동적으로 할당된 메모리(Heap) 영역 중 더는 사용하지 않는 메모리를 자동으로 회수한다.

가비지 컬렉션 과정
Heap의 Young 영역과 Old 영역은 서로 다른 메모리 구조로 되어 있기 때문에, GC의 세부적인 동작 방식은 다르다.
하지만 기본적으로 가비지 컬렉션이 실행된다고 하면 Stop The World, Mark and Sweep 2가지 공통적인 단계를 따르게 된다.

Java 컴파일 과정

  1. 개발자가 .java 파일을 생성하고 build 한다.
  2. java compiler의 javac 의 명령어를 통해 바이트코드(.class)를 생성한다.
  3. Class Loader를 통해 JVM 메모리 내로 로드한다.
  4. 실행엔진을 통해 컴퓨터가 읽을 수 있는 기계어로 해석된다.(각 운영체제에 맞는 기계어)

* 더 자세한 정리는 JVM 포스팅 참조





Collection

자바에서 컬렉션이란 '데이터를 저장하는 클래스들을 표준화한 설계'이다.
쉽게 보면, 여러 원소들을 담을 수 있는 자료구조로 데이터들을 저장하고 연산할 수 있는 집합이다.

List vs Set vs Map

  • List 인터페이스는 객체의 순서가 있고, 데이터 중복을 허용한다
    (*구현 클래스: ArrayList, LinkedList, Stack, Vector 등)
  • Set 인터페이스는 객체의 순서가 없으며, 데이터 중복을 허용하지 않는다.
    (*구현 클래스: HashSet, TreeSet 등)
  • Map 인터페이스는 키(key)와 값(value)의 쌍으로 이루어진 데이터 집합이다. 객체의 순서가 없으며, 데이터 중복을 허용하지 않지만 값의 중복은 허용된다.
    (*구현 클래스: HashMap, TreeMap, HashTable 등)

HashMap vs HashTable vs ConcurrentHashMap

  • HashMap은 key,value에 null을 입력할 수 있다.
  • HashTable은 key,value에 null을 허용하지 않는다.
  • ConcurrentHashMap은 HashMap을 thread-safe 하도록 만든 클래스로, key,value에 null을 허용하지 않습니다.





Generic

제네릭(Generic)은 데이터의 타입을 하나로 지정하지 않고 사용할 때마다 범용적으로 지정할 수 있는 기법이다.
모든 종류의 타입을 다룰 수 있도록 일반화 된 타입 매개 변수 (generic type)로 클래스나 메서드를 선언한다.

기존에는 Object 객체를 사용 했지만 이제는 지네릭 클래스 <T>를 사용함으로써 컴파일 시에 타입을 지정할 수 있게 되었고 다운 캐스팅이 필요없게 되었다.

제네릭 장점

  • 객체의 타입을 컴파일 시에 체크하기 때문에 객체의 타입 안정성을 높이고 형변환의 번거로움이 감소한다.
  • 타입을 사용함으로써 잘못된 타입이 사용될 수 있는 문제를 컴파일 과정에서 제거할 수 있어 에러를 사전에 방지할 수 있다. (또한 형변환을 생략하여 코드가 간결해질 수 있다)



Stream

java 는 기본적으로 객체지향 언어라 함수형 프로그래밍이 불가능한데,
JDK8부터 Stream API 와 람다식 등을 통하여 Java 를 이용해 함수형으로 프로그래밍 할 수 있는 API 를 제공해준다.

함수형 프로그래밍의 장점이 무엇이길래?

  • [불변이다] 함수형 프로그램은 대입문이 없기 때문에 기본적으로 한 번 값이 변수에 할당되고 나면 이후에 값이 변경되지 않는다. (부수효과(Side Effect)가 발생하지 않는다.)
  • [명확하다] 함수가 하는 일은 명확하게 정의되기 때문에 코드를 읽을 때 이해하기 쉬워진다는 장점이 있다. 또한 함수를 값으로 사용할 수 있다.

stream 을 사용하는 이유(장점)

  • 데이터 소스를 추상화하여 코드의 재사용성이 높아졌다
  • 작업을 내부 반복으로 처리함으로써 작업이 간결해질 수 있다.
  • 컬렉션 요소를 람다식으로 처리하여, 복잡한 구조의 데이터 처리를 간단하게 해주어 코드의 복잡도를 낮출 수 있다.

* 더 자세한 정리는 Stream 포스팅 참조





Reflection

자바에서 리플렉션은 구체적인 클래스 타입은 알지 못하지만, 그 클래스의 정보에 접근할 수 있도록 해주는 자바API를 말한다.

자바에서는 JVM이 실행되면 작성된 자바 코드가 static 영역에 저장된다.
Reflection API는 이 정보를 활용하여 (구체적인 클래스 타입을 알지 못해도) 클래스 이름을 통해 static 영역에서 그 클래스의 정보(메서드, 타입, 변수 등등)에 접근할 수 있게 해준다.
때문에, 코드를 작성할 시점에는 어떤 타입의 클래스를 사용할지 모르지만 런타임 시점에 지금 실행되고 있는 클래스를 가져와서 실행해야 하는 경우 사용된다.

Where ?

스프링에서 BeanFactory 는 어플리케이션이 실행한 후 객체가 호출 될 당시 객체의 인스턴스를 생성하게 되는데 이때 필요한 기술이 Reflection이다. 또한 프레임워크나 IDE에서 이런 동적 바인딩을 이용한 기능을 제공한다. (ex. intelliJ의 자동완성 기능, 스프링의 어노테이션)

JPA Entity 기본 생성자

Refelction API 는 JPA의 Entity가 기본 생성자를 지녀야 하는 이유와도 관련이 있다.
Reflection API 는 (클래스의 정보 중에서) 생성자의 인자 정보는 가져올 수 없다.
때문에 JPA를 사용할 때에는 기본 생성자가 있어야 객체를 생성할 수 있고 생성된 객체를 통해서 Reflection API는 필드 값 등을 넣어줄 수 있다.

* 더 자세한 정리는 JPA Entity 생성자 포스팅 참조





Thread

Java에서 쓰레드를 생성하는 2가지 방법

  • Runnable 인터페이스를 확장해 run() 메소드 구현
  • Thread 클래스를 상속받고 run() 메소드를 오버라이딩해 구현

다만, Runnable 인터페이스를 implements 받는 방법을 추천한다.

'extends' 와 'implements' 의 차이점에서 알 수 있다.
extends을 받으면 내가 받고 싶지 않은 메소드도 상속 받게 되는 문제가 생긴다.
또한 private가 아닌 메소드나 변수를 자식 클래스가 받게 되고 낭비가 생긴다.

따라서 인터페이스 implements 방식을 사용해 필요한 기능만 갖게 되고 결합도를 낮추는 방식이 객체지향적으로 적합하다.





Design Pattern

Design Pattern 이란?
소프트웨어 개발 과정에서 발견한 설계 노하우를 패턴으로 정리한 것이다.
검증된 구조이며, 범용적인 코드스타일로 의사소통을 효율적으로 할 수 있다.
목적에 따라서 생성패턴, 구조패턴, 행동패턴으로 나눠진다.

싱글톤 패턴

클래스의 인스턴스가 하나만 생성되도록 하는 개발방법이다.
스프링 환경은 사용자의 요청이 1만건이 넘어서 그때마다 1만개의 객체를 생성할 수 없기에 하나의 객체를 생성해서 쓰레드로 공유하는 싱글톤 패턴 방식을 사용한다.

생성자가 private 인 것에 주목해보자.

public class Singleton {
	private static final Singleton INSTANCE = new  Singleton();
    
	private  Singleton() { }
	public static Singleton getInstance() {
		return INSTANCE;
	}
}

전략 패턴

객체들이 할 수 있는 행위 각각에 대해 전략 클래스를 생성하고, 유사한 행위들을 캡슐화 하는 인터페이스를 정의하여, 객체의 행위를 동적으로 바꾸고 싶은 경우 직접 행위를 수정하지 않고 전략을 바꿔주기만 함으로써 행위를 유연하게 확장하는 방법이다.

간단히 말해서, 객체가 할 수 있는 행위들 각각을 전략으로 만들어 놓고, 동적으로 행위의 수정이 필요한 경우 전략을 바꾸는 것만으로 행위의 수정이 가능하도록 만든 패턴이다.

public interface LottoGenerator {
    List<LottoNumber> makeLottos();
}
public class RandomLottoGenerator implements LottoGenerator {
	private final List<LottoNumber> numbers;
    ...
	public List<LottoNumber> makeLottos() {
        Collections.shuffle(numbers);
        return numbers.subList(LOTTO_NUMBER_START_INDEX, LOTTO_NUMBER_END_INDEX);
    }
}

팩토리 메소드 패턴

객체를 직접 생성하지 않고 객체를 생성하는 Factory 객체를 사용하는 패턴이다.

어댑터 패턴

어댑터를 사용해서 호환되지 않는 인터페이스를 호환하도록 하는 패턴이다.

템플릿 메소드 패턴

상속을 통해서 부모 클래스의 기능을 확장할 때 사용하는 방법이다.







🖍 면접 질문

1. 객체지향 프로그래밍에 대해서 설명해주세요.

실세계의 사물 또는 개념들을 객체로 바라보고, 상태와 행위를 가진 객체를 만들어 그 객체들 간 상호작용을 통해 프로그램이 동작하는 방식입니다.
유지보수가 어려웠던 절차지향, 구조적 프로그래밍을 해결하기 위해 등장했고,
특징인 상속, 추상화, 캡슐화, 다형성을 통해 객체를 독립성과 신뢰성이 보장되게 만들어 놓으면 재사용성이 높아지므로 유지보수가 용이합니다. 상추캡(이)다

(* 객체는 현실의 무언가를 추상적으로 표현한 것으로, 같은 종류의 데이터와 로직이 함께 있는 구성체라고 볼 수 있습니다. ex) 커피, 주문)

다형성과 상속에 대해서 설명해주세요. ↩️

다형성은 하나의 메소드나 클래스가 다양한 방법으로 동작하는 것을 말합니다.
부모 클래스의 메소드를 자식 클래스가 오버라이딩해서 자신의 역할에 맞게 활용하는 것이라고 볼 수 있으며
오버라이딩을 통해 인터페이스를 구현한 객체 인스턴스를 실행 시점에 유연하게 변경 할 수 있어 서버의 구현 기능을 유연하게 변경할 수 있습니다.

상속이란, 기존 클래스의 변수와 메소드를 모두 취하여 추가적인 기능도 가지는 클래스를 새로 만드는 것입니다.
부모 클래스에서 클래스의 행동과 정의를 가져다가 자식 클래스에서 사용할 수 있게 해줍니다. 자식 클래스를 정의할 때 이전 부모 클래스에서 새로운 행동을 추가하거나 새로운 타입에 대한 행동을 오버라이드 할 수 있습니다.

객체지향 설계 원칙에 대해서 알고 계시나요? ↩️

SRP, OCP, LSP, ISP, DIP 5개의 원칙이 있습니다.

SRP는 하나의 클래스는 하나의 책임만 가져야 한다.
OCP는 확장에는 개방되어있고, 변경에는 폐쇄적이어야한다.
LSP는 상위 타입은 항상 하위 타입으로 대체할 수 있어야 한다.
ISP는 범용 인터페이스 하나로 해결하기 보단, 여러 인터페이스로 분리하는 것이 좋다.
DIP는 구현체에 의존하지 말고 추상화에 의존해야한다.

Java 컴파일 과정에 대해서 설명해주세요

  1. 개발자가 .java 파일을 생성하고 build 한다.
  2. 자바 컴파일러(javac)가 자바 소스코드(.java)를 읽어들여 자바 바이트코드(.class)로 변환시킨다.
  3. Class Loader를 통해 class 파일들을 JVM으로 로드한다.
  4. Execution engine을 통해 각 OS에 맞는 기계어로 해석된다.

(* 컴파일은 프로그램이 실행되기 전 소스코드를 기계어로 번환하는 과정)
(* 프로그램 수행시 해석된 바이트 코드가 Runtime Data Area에 배치되어 수행된다)

JVM의 역할에 대해서 설명해주세요

JVM은 Java가 OS에 상관없이 재사용이 가능하게 도와주는 가상 머신입니다.
또한 가비지 콜렉션을 통해 자동으로 메모리 관리를 해주는 역할을 수행합니다.
(JVM 은 크게 클래스 로더, 실행 엔진, 런타임 데이터 영역으로 이루어져있습니다)

자바의 메모리 영역(JVM의 메모리 구조)에 관하여 설명해주세요.

자바의 메모리 공간은 크게 Method(Static) 영역, Heap 영역, Stack 영역으로 구분됩니다.

메소드 영역은 전역변수, static 변수 등을 저장하며, 프로그램의 시작부터 종료까지 메모리에 남아있습니다.
힙 영역은 new 연산자로 생성되는 인스턴스(객체,배열)를 저장하며 GC의 대상이 됩니다.
스택 영역은 메서드가 호출될 때마다 스택 프레임을 생성하여 지역 변수 등 메서드와 관련된 정보들을 저장하고, 메서드 종료시 소멸됩니다.

각 메모리 영역이 할당되는 시점에 대해서 설명해주세요

Method 영역은 JVM이 동작해서 클래스가 로딩될 때 생성되고,
Heap 영역은 컴파일 타임시 할당되며,
Stack 영역은 런 타임시 할당되며 메모리 영역이 할당됩니다.

메모리 상수 풀에 대해서 설명해주세요 ↩️

힙 영역에서 생성되는 메모리 영역으로, 자바 프로세스 종료까지 계속 유지됩니다.
프로그래머가 작성한 상수에 대해 찾아보고, 없으면 상수 풀에 추가한 후 그 주소값을 리턴해줌으로써 메모리를 절약합니다.

가비지 컬렉션과 과정에 대해서 설명해주세요

JVM이 가비지 컬렉션을 실행하기 위해 애플리케이션 실행을 멈추고, GC를 실행하는 쓰레드를 제외한 모든 쓰레드의 작업을 중단합니다. Heap에서 사용하지 않는 메모리를 제거하고나면 중단된 작업이 재개됩니다.

이때 삭제는 가비지 컬렉터가 Stack의 모든 변수, Reachable 객체를 스캔하면서 각각 어떤 객체를 참고하고 있는지 찾아서 마킹하고, 마킹되지 않은 객체를 Heap에서 제거하는 방식으로 이루어집니다.

싱글톤 패턴에 대해서 설명해주세요

싱글톤 패턴은 인스턴스를 한 개만 생성하여 사용하는 디자인 패턴입니다.
인스턴스가 1개만 존재해야하는 것을 보장하고 싶거나 동일한 인스턴스를 자주 생성해야 하는 경우에 주로 사용합니다.
메모리 낭비 방지할 수 있다는 장점이 있습니다.



오버라이딩과 오버로딩의 차이에 대해 설명해주세요.

오버라이딩(Overriding)은 상위 클래스에 있는 메소드를 하위 클래스에서 재정의 하는 것을 말하고,
오버로딩(Overloading)은 매개변수의 개수나 타입을 다르게 하여 같은 이름의 메소드를 여러 개 정의하는 것을 말합니다.

불변 객체나 final을 굳이 사용해야 하는 이유가 있을까요?

  1. Thread-Safe하여 병렬 프로그래밍에 유용하며, 동기화를 고려하지 않아도 된다.
    (공유 자원이 불변이기 때문에 항상 동일한 값을 반환하기 때문)
  2. 실패 원자적인 메소드를 만들 수 있다.
    (어떠한 예외가 발생되더라도 메소드 호출 전의 상태를 유지할 수 있어 예외 발생 전과 똑같은 상태로 다음 로직 처리 가능)
  3. 부수효과를 피해 오류를 최소화 할 수 있다.
    ※ 부수효과 : 변수의 값이 바뀌거나 객체의 필드 값을 설정하거나 예외나 오류가 발생하여 실행이 중단되는 현상
  4. 메소드 호출 시 파라미터 값이 변하지 않는다는 것을 보장할 수 있다.
  5. 가비지 컬렉션 성능을 높일 수 있다.
    (가비지 컬렉터가 스캔하는 객체의 수가 줄기 때문에 Gc 수행 시 지연시간도 줄어든다.)

static 에 대해서 설명해주세요.

static 을 변수와 메소드에 선언하면 Static 영역에 할당되되므로 인스턴스를 생성하지 않고도 프로그램 내에서 공통으로 사용되는 데이터들을 관리할 수 있습니다.
하지만, GC 관리 영역 밖에 존재하기 때문에 메모리에 주의하여 사용해야합니다.

static 을 사용하는 이유는 무엇인가요?

static은 자주 변하지 않는 값이나 공통으로 사용되는 값 같은 공용자원에 대한 접근에 있어서 매번 메모리에 로딩하거나 값을 읽어들이는 것보다 일종의 '전역변수'와 같은 개념을 통해 접근하는 것이 비용도 줄이고 효율을 높일 수 있습니다.

자바에서 static의 사용을 지양하는 이유는 무엇일까요?

자바 메모리 공간은 크게 static , stack , heap 영역으로 구분된다. 이때 static 메모리 공간은 전역변수와 static(정적)멤버변수를 저장하고 static 영역의 데이터는 프로그램의 시작부터 종료가 될 때까지 메모리에 남아있게 된다.
때문에 무분별하게 이 곳에 저장하다보면 메모리를 낭비하여 필요한 변수만 사용할 필요가 있다.

또한, 객체지향적 프로그래밍 측면에서 static은 외부에서 변경이 가능하게 되므로 객체의 데이터들이 캡슐화되어야 한다는 객체지향 프로그래밍 원칙에 위반된다.

interface vs abstract

추상 클래스는 클래스 내 추상 메소드가 하나 이상 포함되거나 abstract로 정의된 경우를 말하고,
인터페이스는 모든 메소드가 추상 메소드로만 이루어져 있는 것을 말합니다.
추상클래스는 다중상속이 불가능하지만, 인터페이스는 다중상속이 가능하다.

Wrapper Class란 무엇이며, Boxing과 UnBoxing은 무엇인지 설명해주세요.

기본 자료형(Primitive data type)에 대한 객체 표현을 Wrapper class라고 합니다.
기본 자료형 → Wrapper class로 변환하는 것을 Boxing이라 하며,
Wrapper class → 기본 자료형으로 변환하는 것을 UnBoxing이라 합니다.

new String()과 리터럴("")의 차이에 대해 설명해주세요.

new String()은 new 키워드로 새로운 객체를 생성하기 때문에 Heap 메모리 영역에 저장되고,
""는 Heap 안에 있는 String Constant Pool 영역에 저장됩니다.

String, StringBuffer, StringBuilder의 차이를 설명해주세요.

String은 불변의 속성을 가지며, StringBuffer와 StringBuilder는 가변의 속성을 가집니다.
StringBuffer는 동기화를 지원하여 멀티 쓰레드 환경에서 주로 사용하며,
StringBuilder는 동기화를 지원하지 않아 싱글 쓰레드 환경에서 주로 사용합니다.

String 객체가 불변인 이유에 대해 아는대로 설명해주세요.

https://dololak.tistory.com/699

Reflection 에 대해서 설명해주세요

리플렉션이란 구체적인 클래스 타입을 알지 못해도 그 클래스의 메소드, 타입, 변수들에 접근할 수 있도록 해주는 자바 API 입니다.
코드를 작성할 시점에는 어떤 타입의 클래스를 사용할지 모르지만, 런타임 시점에 지금 실행되고 있는 클래스를 가져와서 실행해야 하는 경우 사용됩니다.
프레임워크나 IDE에서 이런 동적인 바인딩을 이용한 기능을 제공합니다. intelliJ의 자동완성 기능, 스프링의 어노테이션이 리플렉션을 이용한 기능이라 할 수 있습니다.

Generic 에 대해서 설명해주세요.

제네릭은 데이터의 타입을 하나로 지정하지 않고 사용할 때마다 범용적으로 지정할 수 있습니다.
타입을 사용함으로써 잘못된 타입이 사용될 수 있는 문제를 컴파일 과정에서 제거할 수 있어 에러를 사전에 방지할 수 있습니다.

Collection 클래스에서 Generic 을 사용하는 이유는 무엇인가요?

Collection class에서 Generic을 사용하게되면, 컴파일러는 특정한 타입만 포함될 수 있도록 컬렉션을 제한합니다.
컬렉션 클래스에 저장되는 인스턴스 타입을 제한하여 런타임에 발생할 수 있는 잠재적인 모든 예외를 컴파일 타임에 잡아낼 수 있도록 도와주기 때문에 사용합니다.

HashMap vs HashTable vs ConcurrentHashMap

HashMap은 key,value에 null을 입력할 수 있습니다.
HashTable은 key,value에 null을 허용하지 않습니다.
ConcurrentHashMap은 HashMap을 thread-safe 하도록 만든 클래스로, key,value에 null을 허용하지 않습니다.

Synchronized에 대해 아는 대로 말해주세요.

여러 개의 쓰레드가 한 개의 자원을 사용하고자 할 때, 현재 데이터를 사용하고 있는 쓰레드를 제외하고 나머지 쓰레드들은 데이터에 접근할 수 없게 막는 개념입니다.

데이터의 thread-safe를 하기 위해 자바에서 Synchronized 키워드를 제공해 멀티 쓰레드 환경에서 쓰레드간 동기화를 시켜 데이터의 thread-safe를 보장합니다.







[참조]
Java의 정석
https://github.com/JaeYeopHan/Interview_Question_for_Beginner/tree/master/Java#jvm-%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C-gc-%EC%9D%98-%EC%9B%90%EB%A6%AC
https://dev-coco.tistory.com/153?category=1056309#%F-%-F%--%A-%--Java%EC%--%--%EC%--%-C%--%EC%A-%-C%EA%B-%B-%ED%--%--%EB%-A%--%--%EC%-B%--%EC%-B%-C%--%ED%--%--%EC%-E%--%EB%--%A-%EC%--%--%--%EB%AC%B-%EC%--%--%EC%-D%B-%--%EC%-E%--%EA%B-%A-%-C%--%EA%B-%--%EA%B-%--%--%EB%AA%--%--%EB%B-%--%EC%-D%B-%ED%-A%B-%EB%A-%BC%--%EC%B-%A-%EC%A-%--%ED%--%--%EB%--%--%EC%-A%--%-F
https://imbf.github.io/interview/2020/12/11/NAVER-Interview-Preparation-3.html
https://dololak.tistory.com/699 /String
https://tecoble.techcourse.co.kr/post/2021-09-30-java8-functional-programming/ 함수형 프로그래밍
https://n1tjrgns.tistory.com/288
https://victorydntmd.tistory.com/292 / 전략 패턴

profile
- 👩🏻‍💻

0개의 댓글