질문 - 답변 형식으로 정리
클래스와 인스턴스의 차이에 대해 설명해주실 수 있을까요?
클래스는 객체를 정의하는 템플릿 또는 설계도입니다. 속성(변수)과 행위(메서드)를 정의하여 객체의 기본 형태와 기능을 설명합니다.
예를 들어, '자동차' 클래스에는 색상, 브랜드, 모델 등의 속성과 가속하기, 정지하기 등의 행위가 정의될 수 있습니다. 클래스는 실제 데이터나 상태를 저장하지 않으며, 객체의 구조와 행동만을 정의합니다.
인스턴스는 클래스에 정의된 구조와 행동을 실제로 가지는 구체적인 객체입니다.
클래스를 기반으로 메모리에 할당되며, 실제 데이터와 상태를 포함합니다.
클래스를 사용하여 인스턴스를 생성하면, 그 인스턴스는 해당 클래스의 모든 속성과 행위를 상속받아 사용할 수 있습니다.
예를 들어, '자동차' 클래스의 인스턴스는 특정 색상, 브랜드, 모델을 가진 실제 자동차를 나타냅니다.
클래스와 인스턴스의 차이점은, 클래스는 객체의 추상적인 정의를 제공하는 반면, 인스턴스는 그 정의를 바탕으로 생성 된 실체라는 점입니다.
클래스는 설계도에 비유되고, 인스턴스는 그 설계도로 구축된 실제 건물에 비유될 수 있습니다. 클래스는 정적인 개념이며, 인스턴스는 동적인 실체입니다.
Garbage Collector의 역할, 원리, 알고리즘에 대해 아는 만큼 설명해주실 수 있을까요?
Garbage Collector의 주 역할은 더 이상 애플리케이션에서 참조되지 않는 객체, 즉 가비지(garbage)를 감지하고 메모리를 회수하는 것입니다. 이 과정은 주로 두 단계로 진행됩니다.
- 마킹(Marking): 이 단계에서는 가비지 컬렉터가 모든 객체를 스캔하며, 애플리케이션에서 직접적으로 또는 간접적으로 참조되는 객체를 식별(마크)합니다. 참조되지 않는 객체들은 가비지로 간주됩니다.
- 스위핑(Sweeping): 마킹된 객체들 중에서 더 이상 참조되지 않는 객체들을 실제로 메모리에서 제거합니다. 이 과정을 통해 할당되었던 메모리 공간이 회수되어, 새로운 객체 할당을 위해 사용될 수 있습니다.
Garbage Collector의 알고리즘은 여러 가지가 있으며, 주로 사용되는 것은 다음과 같습니다:
- Mark-and-Sweep: 객체가 더 이상 필요하지 않게 되면 마크하고, 마킹 과정이 끝나면 불필요한 객체를 메모리에서 제거하는 방식입니다.
- Generational GC: 객체를 젊은 세대(Young Generation)와 늙은 세대(Old Generation)로 구분하여 관리합니다. 대부분의 객체는 젊은 세대에서 생성되고 빠르게 소멸되므로, 이 영역에서 더 빈번한 가비지 컬렉션이 일어납니다. 오래 살아남은 객체는 늙은 세대로 이동되며, 여기서의 가비지 컬렉션은 덜 빈번하게 발생합니다.
- Stop-the-World: GC가 실행되는 동안 애플리케이션의 모든 작업이 중단됩니다. 이는 GC 작업의 효율성을 높이기 위해 필요한 경우입니다.
가비지 컬렉터는 메모리 관리를 자동화하여 개발자가 메모리 해제와 관련된 복잡성을 직접 처리하지 않도록 돕습니다. 이는 프로그램의 안정성을 증가시키고, 메모리 누수와 같은 문제를 방지하는 데 중요한 역할을 합니다.
Java Map의 내부 구현은 어떻게 이루어져 있을지 추측해보실 수 있을까요?
Java의 Map 인터페이스는 키와 값의 쌍으로 데이터를 저장하는 구조입니다.
Map의 내부 구현은 구현체에 따라 다를 수 있으나, 가장 널리 사용되는 HashMap의 구현을 예로 들어 설명하겠습니다.
HashMap은 해시 테이블을 사용하여 키-값 쌍을 저장합니다.
해시 테이블은 키에 대한 해시 함수를 적용하여 생성된 해시 코드를 사용하여 각 요소(엔트리)의 저장 위치를 결정합니다. 이 구조를 통해 HashMap은 평균적으로 상수 시간(O(1))의 빠른 접근 시간을 제공합니다.
- 해시 함수와 버킷: HashMap 내부에서는 해시 함수를 사용하여 각 키의 해시코드를 계산하고, 이 해시코드를 사용하여 값을 저장할 버킷의 인덱스를 결정합니다. 버킷은 Map 내부의 배열에서 특정 인덱스에 해당하는 위치입니다.
- 충돌 처리: 두 개 이상의 키가 같은 해시코드를 가질 경우 충돌이 발생합니다. HashMap은 이러한 충돌을 처리하기 위해 버킷 내에서 연결 리스트 또는 레드-블랙 트리(자바 8 이후)를 사용합니다. 해시코드가 같은 요소들은 같은 버킷 내에서 리스트나 트리 형태로 관리되며, 이는 검색, 삽입, 삭제 작업의 효율성을 높입니다.
- 동적 재해싱(Rehashing): HashMap의 크기가 특정 임계값을 초과할 때, 배열의 크기를 확장하고 모든 요소를 새 배열에 재해싱하여 배치합니다. 이 과정은 해시 테이블의 로드 팩터(load factor)와 임계값(threshold)에 의해 결정되며, 해시 테이블의 성능을 최적화합니다.
HashMap 외에도 Java에는 TreeMap, LinkedHashMap 등 다른 Map 구현체들이 있으며, 각각의 구현체는 사용하는 데이터 구조와 성능 특성이 다릅니다.
예를 들어, TreeMap은 레드-블랙 트리를 기반으로 하여 정렬된 순서를 유지하며, LinkedHashMap은 삽입 순서 또는 접근 순서를 유지하는 링크드 리스트를 사용합니다
DI와 IoC에 대해 아는 만큼 설명해주실 수 있을까요?
IoC (Inversion of Control, 제어의 역전):
IoC는 애플리케이션의 흐름 제어를 사용자가 아닌 프레임워크나 컨테이너가 관리하는 디자인 패턴을 말합니다.
전통적인 프로그래밍에서는 사용자가 프로그램의 흐름을 직접 제어하지만, IoC에서는 프레임워크가 이를 담당하여 개발자는 애플리케이션의 특정 부분만을 구현하게 됩니다.
이로 인해 코드의 모듈성과 유연성이 향상되며, 테스트 및 유지보수가 용이해집니다.
DI (Dependency Injection, 의존성 주입):
DI는 IoC의 한 형태로, 객체의 생성과 이들 간의 의존 관계 설정을 외부 컨테이너나 프레임워크가 담당하는 방법입니다.
개발자는 사용할 객체를 직접 생성하지 않고, 이를 프레임워크에 위임합니다.
프레임워크는 구성 파일이나 어노테이션을 기반으로 필요한 객체를 생성하고, 이를 사용하는 클래스에 주입합니다.
이는 객체 간의 결합도를 낮추고, 코드의 재사용성을 높이며, 테스트를 용이하게 합니다.
DI의 방식은 생성자 주입, 세터 주입, 필드 주입 세 가지가 있으며 생성자 주입은 의존성이 불변하고 필수적일 때 사용되며, 세터 주입은 의존성이 선택적이거나 변경 가능할 때 사용됩니다, 필드 주입은 간편하지만 결합도와 테스트의 복잡성을 증가시킬 수 있습니다.
세 가지 DI 방식 중 스프링은 생성자 주입 방식을 권장하고 있습니다.
MVC 모델이란 무엇인지 설명해주실 수 있을까요?
MVC(Model-View-Controller) 모델은 애플리케이션을 세 가지 주요 구성 요소로 분리하여 관리하는 소프트웨어 디자인 패턴입니다.
이 패턴은 애플리케이션의 구조를 명확하게 하고, 유지보수를 용이하게 하며, 개발 과정에서 각 부분의 재사용성을 높이는 데 목적이 있습니다.
모델(Model): 모델은 애플리케이션의 데이터와 비즈니스 로직을 캡슐화합니다.
데이터의 접근, 저장, 수정과 같은 기능을 제공하며, 애플리케이션의 상태를 나타냅니다. 모델은 데이터 변경 시 뷰와 컨트롤러에 이를 알리는 역할도 합니다.
뷰(View): 뷰는 사용자에게 데이터를 시각적으로 표현하는 인터페이스입니다.
뷰는 모델로부터 데이터를 받아 사용자에게 보여주며, 사용자 인터페이스(UI) 요소를 관리합니다.
뷰는 모델이 가지고 있는 정보를 바탕으로 사용자에게 정보를 표시하지만, 모델의 로직을 직접적으로 처리하지는 않습니다.
컨트롤러(Controller): 컨트롤러는 사용자의 입력을 받아 처리하는 역할을 담당합니다.
사용자의 액션에 대한 로직을 구현하고, 모델을 업데이트하거나 뷰에 변경을 요청합니다.
컨트롤러는 모델과 뷰 사이의 중재자 역할을 하며, 애플리케이션의 흐름을 제어합니다.
MVC 패턴을 사용하면, 애플리케이션의 비즈니스 로직과 사용자 인터페이스가 분리되어, 각 부분을 독립적으로 개발하고 테스트할 수 있습니다.
이는 개발 과정의 복잡성을 줄이고, 코드의 재사용성을 높이며, 유지보수를 용이하게 합니다.
대규모 애플리케이션 개발에서 특히 이러한 구조적 접근 방식은 개발을 체계화하고, 팀 작업을 효율적으로 만들어 줍니다.
Annotation이란 무엇이고 구체적으로 어떤 것이 있는지 예시를 들어 설명해주실 수 있을까요?
Annotation(어노테이션)은 Java 5 이후 도입된 기능으로, 소스 코드에 메타데이터를 추가하는 방법입니다.
어노테이션은 코드에 대한 정보를 제공하며, 컴파일 타임이나 런타임에 해석될 수 있습니다.
이를 통해 개발자는 코드에 추가적인 의미나 정보를 부여할 수 있고, 이는 프레임워크나 라이브러리에서 해당 정보를 사용하여 특정 동작을 수행하게 합니다.
- @Override: 메서드가 부모 클래스의 메서드를 오버라이딩한다는 것을 나타냅니다. 컴파일러에게 이 메서드가 오버라이딩된 것임을 알려주어, 부모 클래스에서 해당 메서드의 존재를 검증하게 합니다.
- @Deprecated: 메서드나 클래스가 더 이상 사용되지 않으며, 향후 버전에서 제거될 수 있음을 나타냅니다. 이 어노테이션이 붙은 요소를 사용할 경우, 개발 환경에서 경고를 표시합니다.
- @SuppressWarnings: 컴파일러 경고를 무시하도록 지시하는 어노테이션입니다. 예를 들어 @SuppressWarnings("unchecked")는 체크되지 않은 연산에 대한 경고를 무시하도록 합니다.
- @Entity: JPA에서 사용되며, 클래스가 데이터베이스의 엔티티임을 나타냅니다. 이 어노테이션을 사용하면 해당 클래스의 인스턴스들이 데이터베이스의 테이블과 매핑됩니다.
- @SpringBootApplication: 스프링 부트에서 사용되며, 해당 클래스가 스프링 부트 애플리케이션의 메인 클래스임을 나타냅니다. 이 어노테이션은 @Configuration, @EnableAutoConfiguration, @ComponentScan 등 여러 스프링 구성 어노테이션을 한꺼번에 설정합니다.
어노테이션은 코드의 가독성을 높이고, 오류를 줄이며, 반복적인 작업을 줄이는 데 도움을 주며, 프레임워크나 라이브러리와의 상호작용을 통해 보다 효율적인 개발 프로세스를 지원합니다.
'항해 99' 카테고리의 다른 글
HTTP, HTTPS / HTTP 메서드 (0) | 2024.04.15 |
---|---|
WIL-10 (1) | 2024.04.14 |
기술면접 준비 1주차 정리 (0) | 2024.04.13 |
WIL-9 (0) | 2024.04.07 |
Git Project 관리 (0) | 2024.04.01 |