이번에는 면접 리스트편중 자바를 가져왔습니다. 자바의 기초질문들도 같이 공부하는게 좋을것 같아서 쭉 나열해보며 개념을 적었습니다. 틀린 부분은 댓글로 알려주세요 :)
https://sunro1994.tistory.com/230
[백엔드 자바 면접 빈출 질문 대비하기 - 리스트 업
어느날 한 취업준비를 하기 위해 여러 영상들을 보고 어떤 질문들을 주로 준비해야 하는지 하나씩 리스트로 추출하고 있었다. 리스트를 만들어본 결과 내가 가장 대답하기 곤란하고 생각지도
sunro1994.tistory.com](https://sunro1994.tistory.com/230)
JVM
JVM 실행 과정에 대해 설명해주세요.
Java Virtual Machine(JVM)은 자바 프로그램을 실행하기 위한 가상 머신입니다. JVM의 실행 과정은 다음과 같이 이루어집니다:
- 소스 코드 컴파일: 자바 소스 파일(.java)은 자바 컴파일러(javac)에 의해 바이트코드(.class)로 컴파일됩니다. 이 바이트코드는 플랫폼에 독립적이며, JVM이 실행할 수 있는 코드입니다.
- 클래스 로드: JVM은 ClassLoader를 통해 필요한 클래스들을 메모리로 로드합니다. 이 단계에서 필요한 클래스들이 메모리로 읽혀 들어옵니다.
- 바이트코드 검증: JVM은 로드된 바이트코드가 유효한지 검증합니다. 이를 통해 코드의 안정성을 보장하며, JVM이 실행할 때 발생할 수 있는 오류를 방지합니다.
- 바이트코드 실행: JVM의 실행 엔진이 바이트코드를 인터프리트하거나 JIT(Just-In-Time) 컴파일러를 통해 기계어로 변환하여 실행합니다. 인터프리터는 바이트코드를 한 줄씩 실행하지만, JIT는 바이트코드를 기계어로 변환하여 빠르게 실행할 수 있게 합니다.
- 메모리 관리 및 가비지 컬렉션: JVM은 메모리 영역을 관리하며, 더 이상 참조되지 않는 객체를 가비지 컬렉션을 통해 자동으로 제거합니다.
컴파일러와 인터프리터 차이
- 컴파일러: 소스 코드를 한 번에 전부 기계어 또는 바이트코드로 변환하여 실행 파일을 생성합니다. 실행 속도가 빠르지만, 컴파일 시간이 필요합니다.
- 인터프리터: 소스 코드를 한 줄씩 해석하여 실행합니다. 컴파일 시간이 필요 없지만, 실행 속도가 상대적으로 느립니다.
클래스 로드 방법과 과정에 대해 설명해주세요.
JVM의 클래스 로드 과정은 세 단계로 이루어집니다:
- 로딩(Loading): ClassLoader가 클래스를 로드하여 메모리(Method Area)에 저장합니다. ClassLoader는 Bootstrap ClassLoader, Extension ClassLoader, Application ClassLoader 등의 계층 구조를 가집니다.
- 링크(Linking): 로드된 클래스의 구조를 확인하고, 필요한 참조를 연결합니다. 이 과정은 세 단계로 나뉩니다:
- 검증(Verification): 클래스 파일이 유효한지 확인합니다.
- 준비(Preparation): 클래스의 정적 변수들이 메모리에 할당되고 초기값이 설정됩니다.
- 해결(Resolution): 심볼릭 레퍼런스를 실제 메모리 주소로 변환합니다.
- 초기화(Initialization): 클래스의 정적 변수들이 초기화되고, 정적 초기화 블록(static block)이 실행됩니다.
가비지 컬렉션
가비지 컬렉션이란?
가비지 컬렉션(Garbage Collection)은 JVM이 더 이상 사용되지 않는 객체를 자동으로 메모리에서 해제하는 프로세스입니다. 이를 통해 메모리 누수를 방지하고, 개발자가 명시적으로 메모리를 해제하지 않아도 됩니다.
가비지 컬렉션이 일어나는 과정에 대해 설명해주세요
가비지 컬렉션은 주로 Young Generation과 Old Generation으로 나뉘어 관리됩니다.
- Young Generation: 새로운 객체가 할당되는 영역입니다. 여기에서 자주 가비지 컬렉션이 발생하며, Minor GC라고 합니다. 이 영역은 다시 Eden과 두 개의 Survivor(S0, S1) 영역으로 나뉩니다.
- Old Generation: Young Generation에서 살아남은 객체들이 이동하는 영역입니다. 이 영역에서 발생하는 가비지 컬렉션을 Major GC 또는 Full GC라고 하며, 시간이 오래 걸릴 수 있습니다.
가비지는 어떻게 참조하지 않는 메모리를 처리하나요?
JVM은 참조 그래프를 사용하여 객체가 참조되지 않는 경우(즉, 루트 노드로부터 도달할 수 없는 객체)를 가비지로 인식하고 메모리에서 해제합니다.
왜 Survivor 1과 2 영역이 따로 있나요?
Survivor 영역은 두 개로 나누어져 있는데, 이는 객체의 생존 여부를 판단하기 위함입니다. Minor GC가 발생할 때 Eden 영역의 객체는 하나의 Survivor 영역으로 이동하고, 그 후 다음 GC에서 살아남은 객체는 다른 Survivor 영역으로 이동합니다. 이 과정에서 한쪽 Survivor 영역은 항상 비어 있게 됩니다.
Survivor 영역이 가득 찼다면 어떻게 되나요?
Survivor 영역이 가득 차면, 살아남은 객체들은 Old Generation으로 이동합니다. 이 과정을 Promotion이라고 하며, Old Generation이 가득 차면 Major GC가 발생합니다.
STW에 대해서 알고 있나요?
GC를 사용해도 메모리 누수가 발생할 수 있나요?
발생할 수 있습니다. 다음과 같은 다양한 경우에 GC가 관리할 수 없습니다.
1. Static 변수에 의한 객체 참조가 발생할 경우 static은 GC대상이 되지 않기 때문에 메모리 누수가 발생할 수 있습니다.
2. 모든 현재 자바 스레드 스택 내의 지역변수, 매개 변수에 의한 객체 참조에 의해 발생할 수 있습니다. 자바에서 실행중인 모든 메서드 내에 선언된 지역 변수와 매개 변수에 참조되는 객체, 그 객체로부터 직간접적으로 참조되는 객체들이 있습니다.
3. 래퍼 클래스를 사용하여 무의미한 객체를 생성하고 반환하지 않는 경우
4. 맵에 캐쉬 데이터를 선언하고 해제하지 않는 경우
5. 스트림 객체를 사용하고 닫지 않는 경우
6. 맵의 키를 사용자 객체로 정의하면서 equals(), hashCode()를 재정의 하지 않아 같은 키로 착각하고 계속해서 데이터가 쌓이는 경우
메모리 누수를 해결하는 방법은?
1. 명시적으로 참조된 객체를 모두 사용한 경우 null로 참조 해제를 해줍니다.
2. try-with-resources 구문으로 자동으로 리소스를 닫아줄수 있도록 합니다.
3. 캐시처리한 데이터를 시간에 따라 가치를 떨어트려 삭제하는 방법을 사용할 수 있습니다.
JVM와 GC에 대해서 더 자세히 알아보기
https://sunro1994.tistory.com/200
[Java - JVM과 GC란? 자세히 파헤치기
[Java] - JVM 작성일시: 2023년 9월 11일 오후 12:45 복습: No JVM 구조 📌 JVM은 자바 언어 뿐만아니라 코틀린, 스칼라 언어에서도 작동방식을 그대로 따른다. 📌 JVM을 정확히 이해하면 모던 언어를 이해
sunro1994.tistory.com](https://sunro1994.tistory.com/200)
객체 지향 프로그래밍
객체 지향 프로그래밍이란?
객체 지향 프로그래밍(OOP)은 프로그램을 객체로 모델링하여 개발하는 프로그래밍 패러다임입니다. 객체는 데이터(속성)와 행동(메서드)을 포함하며, 이들 간의 상호작용을 통해 프로그램이 동작합니다.
객체 지향 프로그래밍과 함수형 프로그래밍의 차이는?
- 객체 지향 프로그래밍: 데이터와 메서드를 캡슐화한 객체 중심의 프로그래밍입니다. 상속, 다형성, 캡슐화, 추상화 등의 개념을 활용합니다.
- 함수형 프로그래밍: 상태나 부작용 없이 순수 함수를 사용하여 프로그램을 구성합니다. 데이터는 불변성을 가지며, 함수는 일급 객체로 취급됩니다.
객체지향 프로그래밍의 4가지 특징은?
- 캡슐화(Encapsulation): 객체의 데이터를 외부에서 직접 접근하지 못하도록 보호하고, 데이터를 조작하는 메서드만을 제공하는 방식입니다. 이때 접근제한자를 사용하여 접근 영역을 설정할 수 있습니다.
- 상속(Inheritance): 새로운 클래스가 기존 클래스를 확장하여 재사용하는 방식입니다.
- 다형성(Polymorphism): 동일한 인터페이스나 상위 클래스를 참조하여 다른 구현을 사용할 수 있는 특성입니다.
- 추상화(Abstraction): 복잡한 시스템에서 필요한 부분만을 표현하여 간단하게 만들고, 세부 구현을 숨깁니다.
객체지향 설계 5대 원칙
객체 지향 설계의 5대 원칙(SOLID)은 다음과 같습니다:
- 단일 책임 원칙(Single Responsibility Principle): 클래스는 하나의 책임만 가져야 합니다.
- 개방-폐쇄 원칙(Open/Closed Principle): 클래스는 확장에는 열려 있어야 하고, 수정에는 닫혀 있어야 합니다.
- 리스코프 치환 원칙(Liskov Substitution Principle): 서브 클래스는 언제나 상위 클래스를 대체할 수 있어야 합니다.
- 인터페이스 분리 원칙(Interface Segregation Principle): 하나의 인터페이스보다는 여러 개의 구체적인 인터페이스를 만드는 것이 좋습니다.
- 의존성 역전 원칙(Dependency Inversion Principle): 고수준 모듈은 저수준 모듈에 의존해서는 안 되며, 둘 다 추상화에 의존해야 합니다.
코드를 작성할 때 이 원칙에 맞춰 리팩토링을 해봤는가?
이 원칙에 맞춰 리팩토링을 시도해본 경험이 있습니다. 예를 들어, 단일 책임 원칙을 지키기 위해 복잡한 클래스를 여러 개의 작은 클래스로 분리하거나, 개방-폐쇄 원칙을 적용하여 새로운 기능 추가 시 기존 코드를 변경하지 않도록 설계하는 등의 작업을 수행한 적이 있습니다.
자바는 Call by Reference인가 Value인가? 이 두개의 차이점은 무엇인가?
자바는 기본적으로 Call by Value 방식을 사용합니다. 기본형 변수는 값을 복사하여 전달하지만, 객체의 경우 참조를 복사하여 전달합니다. 이 때문에 객체를 수정하면 원본 객체도 영향을 받지만, 객체 자체를 재할당하면 원본 참조는 변경되지 않습니다.
추상 클래스와 인터페이스 차이
- 추상 클래스: 공통적인 기능을 포함할 수 있으며, 메서드의 기본 구현을 제공할 수 있습니다. 하나의 클래스만 상속할 수 있습니다.
- 인터페이스: 클래스가 구현해야 할 메서드의 계약을 정의합니다. 다중 구현이 가능하며, 기본적으로 모든 메서드는 추상적입니다.
어떤 상황에 추상 클래스를 써야하고 인터페이스를 써야 하죠?
- 추상 클래스: 공통된 속성이나 메서드 구현이 필요한 경우 사용합니다.
- 인터페이스: 클래스 간의 관계를 정의하거나, 다중 상속이 필요한 경우 사용합니다.
default메서드가 인터페이스에 생겼는데 굳이 추상클래스를 써야 할까요?
default 메서드가 인터페이스에 추가되면서 인터페이스도 기본 구현을 가질 수 있지만, 여전히 상태(필드)를 가지는 경우나 일부 메서드만 구현하고 공통 속성이 필요한 경우 추상 클래스를 사용하는 것이 적절할 수 있습니다.
오버로딩과 오버라이딩 차이
- 오버로딩: 같은 이름의 메서드를 인자의 타입이나 개수를 다르게 하여 여러 개 정의하는 것. 편의성을 제공하며, 동일한 이름으로 다른 기능을 수행할 수 있습니다.
- 오버라이딩: 상위 클래스의 메서드를 서브 클래스에서 재정의하는 것. 다형성을 실현하며, 서브 클래스에서 상위 클래스의 동작을 변경할 수 있습니다.
왜 오버로딩을 사용해서 굳이 같은 이름의 메서드를 쓰죠?
오버로딩을 사용하면 메서드 이름을 통일하여 코드의 가독성을 높이고, 비슷한 기능을 하는 메서드를 쉽게 사용할 수 있습니다.
오버라이딩을 하면 이점이 있을까요?
오버라이딩을 통해 상위 클래스의 기본 동작을 서브 클래스에서 원하는 대로 수정할 수 있습니다. 이는 다형성을 제공하여 코드의 확장성과 유연성을 높입니다.
정적변수와 전역변수의 차이
- 정적 변수(static variable): 클래스에 속하며, 클래스의 모든 인스턴스가 공유합니다. 클래스가 로드될 때 메모리에 할당됩니다.
- 전역 변수: 자바에서는 전역 변수가 없으며, 클래스 변수(static variable)가 전역 변수의 역할을 일부 대체합니다.
접근제어자에 대해 설명, 사용하는 이유
접근 제어자는 클래스, 메서드, 변수 등의 접근 범위를 제어합니다:
- private: 클래스 내부에서만 접근 가능합니다.
- default(package-private): 동일한 패키지 내에서 접근 가능합니다.
- protected: 동일한 패키지와 서브 클래스에서 접근 가능합니다.
- public: 모든 곳에서 접근 가능합니다.
이들을 사용하여 캡슐화를 구현하고, 불필요한 접근을 방지하여 코드의 안정성을 높입니다.
final키워드를 언제 사용해야 하는가?
- 클래스: 클래스를 상속할 수 없게 만듭니다.
- 메서드: 메서드를 오버라이딩할 수 없게 만듭니다.
- 변수: 변수의 값을 변경할 수 없게 만듭니다(상수).
제네릭을 평소에 어떻게 활용하는가?
제네릭을 사용하여 코드의 재사용성을 높이고, 컴파일 시 타입 안전성을 보장받습니다. 예를 들어, List<T>
를 사용하여 다양한 타입의 리스트를 처리할 수 있으며, 잘못된 타입의 요소를 추가하는 실수를 방지할 수 있습니다.
컬렉션 프레임워크
Vector 와 ArrayList차이
- Vector: 동기화된(synchronized) 메서드를 제공하여 멀티스레드 환경에서 안전합니다. 하지만 동기화 때문에 성능이 떨어질 수 있습니다.
- ArrayList: 동기화되지 않아 단일 스레드 환경에서 더 빠르며, 일반적으로 더 많이 사용됩니다.
ArrayList는 내부적으로 어떻게 구현되어 있을까요?
ArrayList는 동적 배열을 사용하여 구현됩니다. 데이터는 배열에 저장되며, 배열이 가득 차면 크기가 1.5배로 증가하여 새로운 배열을 할당하고 기존 데이터를 복사합니다.
만약 크기가 꽉 차면 일반 배열처럼 예외가 발생할텐데 ArrayList는 어떻게 무한히 데이터를 받을 수 있을까요?
ArrayList는 내부 배열이 가득 차면 자동으로 크기를 확장합니다. 이 과정에서 기존 배열의 모든 요소를 새 배열로 복사합니다.
깊은 복사와 얕은 복사에 대해 알고 있나요?
얕은 복사는 객체를 복사할 때, 해당 객체만 복사하여 새 객체를 생성합니다.
복사된 객체의 인스턴스 변수는 원본 객체의 인스턴스 변수와 같은 메모리 주소를 참조합니다.
하지만 깊은 복사는 객체를 복사할 때, 해당 객체와 인스턴스 변수까지 복사하게 됩니다.
전부 복사하여 새 주소에 담기 때문에 서로 다른 주소를 참조합니다.
HashSet, TreeSet, LinkedHashSet 차이
- HashSet: 요소를 해시 테이블로 관리하며, 순서가 없고 중복을 허용하지 않습니다.
- TreeSet: 요소를 이진 검색 트리로 관리하며, 정렬된 상태로 저장됩니다.
- LinkedHashSet: 요소를 해시 테이블과 이중 연결 리스트로 관리하며, 삽입된 순서가 유지됩니다.
위 클래스를 사용해본 경험이 있나요?
- HashSet은 태그를 저장할 때 사용했습니다. 중복된 태그를 적더라도 하나만 입력받게 할 때 사용했습니다.
- TreeSet은 일정한 정렬 기준이 필요할 때 사용했습니다. 날짜별로 정렬된 이벤트리스트를 받을때 사용했습니다.
- LinkedHashSet은 사용자가 방문한 페이지를 받아올때 순서대로 정렬하고 중복된 페이지는 제거해야 하는 경우에 사용했습니다.
컬렉션 프레임워크의 각 인터페이스 구현체에서 쓰레드 세이프처리는 어떻게 하는 방법에 대해 알고 있는가?
컬렉션 프레임워크에서 쓰레드 세이프하게 사용하는 방법은 다음과 같습니다:
- 동기화된 컬렉션:
Collections.synchronizedList
,synchronizedSet
등을 사용하여 동기화된 컬렉션을 생성할 수 있습니다. - Concurrent Collections:
ConcurrentHashMap
,CopyOnWriteArrayList
등은 높은 성능을 유지하면서 쓰레드 세이프를 보장합니다.
Object
자바의 모든 클래스는 Object클래스를 상속받습니다. 그리고 Object에는 equals와 hashCode메서드가 구현되어 있습니다. 이 두개의 역할과 차이점은 무엇일까요?
- equals: 두 객체가 논리적으로 동일한지를 비교합니다. 기본 구현은 참조 비교(
==
)를 수행합니다. - hashCode: 객체를 해시 테이블에서 빠르게 검색하기 위한 해시 코드를 반환합니다. 같은 값을 가지는 객체는 동일한 해시 코드를 반환해야 합니다.
hashCode를 오버라이드 했을때 메모리 주소를 리턴할 수 있나요?
기본적으로 hashCode
메서드는 객체의 메모리 주소를 기반으로 해시 코드를 생성합니다. 하지만 이를 오버라이드할 때는 논리적으로 동일한 객체에 대해 동일한 해시 코드를 반환하도록 구현해야 합니다.
자바에서는 개발자가 직접 메모리에 접근할 수 있나요?
자바는 메모리에 직접 접근할 수 없도록 설계되어 있습니다. 메모리 관리는 JVM이 자동으로 처리합니다.
hashCode를 잘못 오버라이딩하면 HashMap등 hash컬렉션의 성능이 떨어질 수가 있습니다. 어떤 케이스에 그런 상황이 발생할까요? (HashMap 내부 LinkedList, RBT관련 내용)
hashCode를 잘못 오버라이딩하여 모든 객체가 동일한 해시 코드를 반환하면, 모든 요소가 해시 버킷의 동일한 위치에 저장됩니다. 이로 인해 HashMap이 LinkedList로 작동하게 되며, 시간 복잡도가 O(1)에서 O(n)으로 증가합니다.
기존 HashMap의 시간복잡도는 얼마이고, hashCode를 잘못 오버라이딩 했을때의 시간 복잡도는 얼마일까요?
- 기존 HashMap: 평균 시간 복잡도는 O(1)입니다.
- hashCode를 잘못 오버라이딩 했을 때: 최악의 경우 시간 복잡도는 O(n)으로 증가할 수 있습니다.
String
String, StringBuilder, StringBuffer차이
- String: 불변 객체로, 변경할 수 없습니다. 새로운 문자열을 생성하면 메모리에 새로운 객체가 생성됩니다.
- StringBuilder: 가변 객체로, 문자열을 변경할 수 있습니다. 동기화되지 않아 성능이 뛰어납니다.
- StringBuffer: 가변 객체로, 동기화되어 있습니다. 멀티스레드 환경에서 안전하지만 성능이 떨어질 수 있습니다.
왜 synchronized가 걸려있으면 느릴까요?
synchronized 키워드는 쓰레드 안전성을 보장하기 위해 락을 사용합니다. 락을 획득하고 해제하는 데 시간이 소요되기 때문에 성능이 떨어질 수 있습니다.
싱글 스레드로 접근한다는 가정하에서는 StringBuilder와 StringBuffer의 성능이 똑같을까요?
네, 싱글 스레드 환경에서는 StringBuilder와 StringBuffer의 성능이 거의 동일합니다. 하지만 StringBuffer는 synchronized 키워드로 인해 약간의 오버헤드가 있을 수 있습니다.
String이 불변 객체인 이유
String이 불변 객체로 설계된 이유는 다음과 같습니다:
- 안전성: 불변 객체는 변경되지 않기 때문에 여러 쓰레드에서 안전하게 공유할 수 있습니다.
- 성능: String이 불변이기 때문에 해시 코드를 캐싱할 수 있어, 해시 기반 컬렉션에서의 성능이 향상됩니다.
- 보안: 불변 객체는 해킹이나 무단 변경으로부터 안전합니다.
Thread
Thread는 왜 써야 하는걸까요?
쓰레드는 CPU의 자원을 더 효율적으로 사용하고, 동시에 여러 작업을 병렬로 처리할 수 있게 해줍니다. 이는 응답성을 높이고, 대규모 연산을 동시에 처리하는 데 유리합니다.
Thread를 쓰면 동시에 여러 일을 처리할 수 있으니 많을 수록 좋을까요?
쓰레드가 많을수록 문맥 교환(Context Switching) 비용이 증가하고, 과도한 쓰레드 생성은 성능 저하를 유발할 수 있습니다. 적절한 쓰레드 수를 유지하는 것이 중요합니다.
쓰레드 하나 당 메모리는 얼마나 사용될까요?
쓰레드마다 할당되는 스택 메모리는 보통 1MB에서 2MB 사이입니다. 이는 JVM 옵션으로 조정할 수 있습니다.
컨텍스트 스위칭
비용이 얼마나 들까요?
컨텍스트 스위칭은 보통 수십에서 수백의 CPU 사이클을 소모합니다. 이는 시스템 환경에 따라 다르며, 과도한 컨텍스트 스위칭은 성능에 영향을 미칠 수 있습니다.
0이 들어있는 변수에 10개의 스레드가 동시에 접근해서 ++연산을 하면 우리 예상과 다르게 10이 나오지 않습니다. 왜 그럴까요?
++연산은 세 단계(읽기, 증가, 쓰기)로 이루어지기 때문에, 여러 쓰레드가 동시에 접근하면 경합이 발생하여 예상치 못한 결과가 나올 수 있습니다.
10이 나오게 하려면 어떻게 해야 할까요?
동기화(synchronized)를 사용하여 하나의 쓰레드만 접근할 수 있도록 하거나, AtomicInteger
와 같은 원자적 연산을 지원하는 클래스를 사용해야 합니다.
멀티 스레드 프로그래밍이 무엇인가요?
멀티 스레드 프로그래밍은 동시에 여러 쓰레드를 실행하여 병렬로 작업을 수행하는 프로그래밍 방식입니다.
멀티 스레드 프로그래밍중 발생하는 문제는 뭐가 있을까요?
경합, 교착 상태(데드락), 자원 부족 등이 발생할 수 있으며, 이러한 문제는 성능 저하와 프로그램 비정상 종료로 이어질 수 있습니다.
데드락과 자원 부족은 어떠한 경우에 발생하나요?
교착 상태(데드락)는 둘 이상의 스레드가 서로 자원을 점유한 채, 상대방이 점유하고 있는 자원을 기다리면서 무한정 대기하는 상황을 말합니다. 이 경우, 각 스레드가 필요한 자원을 얻지 못해 작업을 진행할 수 없게 되고, 시스템이 멈추게 됩니다.
자원 부족은 시스템의 메모리, CPU, 파일 디스크립터 등의 자원이 한정되어 있어, 여러 스레드가 동시에 실행될 때 각 스레드가 필요한 자원을 충분히 얻지 못해 발생하는 문제입니다.
동시성
동시성과 관련된 예약어를 모두 말해보세요
volatile
, synchronized
, final
, Atomic*
클래스 등이 동시성 관련 예약어 및 클래스입니다.
volatile키워드는 어떤 키워드일까요?
volatile
키워드는 변수의 값을 메인 메모리에서 직접 읽고 쓰도록 강제하여, 가시성을 보장합니다.
이 키워드는 가시성을 보장해준다는데 무슨 말일까요?
가시성은 한 쓰레드에서 변경한 변수의 값을 다른 쓰레드에서 즉시 볼 수 있는 것을 의미합니다. volatile
은 CPU 캐시 대신 메인 메모리에서 값을 읽고 쓰기 때문에 가시성을 보장합니다.
I/O
System.out.println메서드는 현업에서 절대 사용하지 않는데 이유를 아시나요?
System.out.println
은 동기화된 메서드로 성능이 저하될 수 있습니다. 또한, 로깅 라이브러리를 사용하지 않고 println
을 사용하는 것은 유지 보수와 디버깅에 비효율적입니다.
synchronized 키워드는 왜 현업에서 큰 성능 저하를 발생시킬까요?
synchronized
는 락을 사용하여 동시에 하나의 쓰레드만 접근할 수 있도록 하기 때문에, 경합이 발생할 경우 성능이 저하됩니다.
blocking IO는 왜 성능을 저하시킬 수 있을까요?
Blocking I/O는 데이터가 준비될 때까지 쓰레드가 블록되기 때문에, I/O 작업 중에 CPU가 유휴 상태가 되어 성능이 저하될 수 있습니다.
synchronized가 Blocking I/O와 만나면 어떤 일이 발생할까요?
synchronized로 인해 다른 쓰레드가 I/O 작업을 기다리는 동안 블록되면, 전체 시스템의 성능이 크게 저하될 수 있습니다.
Bloacking I/O와 None Blocking I/O의 차이를 말해보세요
- Blocking I/O: I/O 작업이 완료될 때까지 쓰레드가 블록됩니다.
- Non-Blocking I/O: I/O 작업이 완료될 때까지 기다리지 않고, 다른 작업을 계속 수행합니다.
Bloackg I/O가 발생하면 스레드에 무슨 일이 생길까요?
쓰레드는 I/O 작업이 완료될 때까지 블록되고, CPU는 다른 작업을 할 수 없게 됩니다.
스레드가 멈춰있는 동안 CPU는 어떻게 될까요?
CPU는 유휴 상태가 되거나 다른 쓰레드를 실행합니다.
CPU가 쉬는 것을 막으려면 어떻게 해야 할까요?
Non-Blocking I/O를 사용하거나, 멀티쓰레딩을 통해 다른 작업을 병렬로 수행할 수 있습니다.
스레드를 늘리면 단점이 뭘까요?
쓰레드가 많아지면 컨텍스트 스위칭 비용이 증가하고, 메모리 사용량이 늘어나며, 경합이 발생할 확률이 높아집니다.
Non-Bloacking I/O는 CPU활용률이 어떨까요? (Spring Webflux와 Netty)
Non-Blocking I/O는 CPU 활용률을 높일 수 있습니다. Spring Webflux와 Netty는 비동기 처리로 높은 성능과 확장성을 제공합니다.
Exception 처리
왜 예외 처리가 필요할까요?
예외 처리는 프로그램의 비정상 종료를 방지하고, 오류를 적절히 처리하여 시스템의 안정성을 유지하기 위해 필요합니다.
Checked Exception 과 UnCheckedException차이
- Checked Exception: 컴파일 타임에 예외 처리를 강제하며, 반드시 처리해야 합니다. 예:
IOException
,SQLException
. - UnChecked Exception: 런타임에 발생하며, 예외 처리를 강제하지 않습니다. 예:
NullPointerException
,ArrayIndexOutOfBoundsException
.
예외 처리 방법을 아는대로 말해보세요
try-catch
블록을 사용하여 예외를 처리합니다.throw
키워드를 사용하여 예외를 발생시킵니다.throws
키워드를 사용하여 메서드 시그니처에 예외를 명시합니다.finally
블록을 사용하여 예외 발생 여부와 관계없이 항상 실행되는 코드를 작성합니다.
Error와 Exception의 차이는 무엇인가요?
- Error는 프로그램에서 복구할 수 없는 심각한 오류를 말합니다. 주로 JVM레벨에서 발생하는 문제로, 애플리케이션이 이 문제를 처리하고 복구할 수 없습니다. OutOfMemory나 StackOverFlowError등을 말합니다.
- Excpetion은 애플리케이션 코드에서 발생하며 프로그램에서 복구 가능한 오류를 말합니다. 개발자가 적절히 처리하여 프로그램을 정상적으로 유지할 수 있습니다. IOExcpetion, SQLException, NullPointerException등을 말합니다.
'면접 준비' 카테고리의 다른 글
백엔드 자바 CS 면접 빈출 질문 대비하기 - 데이터 베이스 개념 정리 1 (0) | 2024.08.22 |
---|---|
백엔드 자바 CS 면접 빈출 질문 대비하기 - 스프링 (1) | 2024.08.14 |
백엔드 자바 CS 면접 빈출 질문 대비하기 - Security (0) | 2024.08.01 |
백엔드 자바 면접 빈출 질문 대비하기 - 리스트 업 (0) | 2024.08.01 |
[CS면접 및 자바 면접 준비] DB 데이터 베이스 면접 정리 - DB의 기 (0) | 2024.03.28 |