2025-07-16-TIL
Today I Learned
4주간의 멘토링 질문/답변을 정리해보고, 스스로 답변을 작성해보았다. 질문만 보고 답변을 작성해보면서 어떤 부분이 제대로 정리되지 않았는지 확실히 파악이 가능했다.
- 메소드 시그니처란?
- 자바에서 메소드를 구분하기 위한 최소한의 기준이자, 내부적인 처리단위이다.
- 메소드 이름, 매개변수의 타입과 순서, 매개변수의 개수가 해당된다.
- static
- 자바에서 static은 클래스 레벨에 존재하며, 클래스 로딩 중에 메모리의 메서드 영역에 할당된다. 따라서 인스턴스 생성없이 접근 가능하다.
- 여기서 주의할 점이 static이 붙은 요소가 메모리의 메서드 영역에 할당된다는 의미는 아니다. static은 말 그대로 인스턴스 생성없이 접근 가능하다는 뜻이다.
- static 변수는 공통 변수로 public인 경우, 모든 객체가 공유 가능하다.
- static 메서드는 객체 없이 호출이 가능하다.
- static 블록은 클래스 로딩 시 한 번만 실행되는 초기화 블록이다.
- static 멤버변수로 ArrayList를 하나 만들었을 때, 계속 add를 하게되면?
- ArrayList는 내부적으로 배열을 사용한다. 공간이 부족하면 자동으로 크기를 증가시켜 새로운 배열을 할당하고 복사한다.
- 배열의 저장공간은 힙 영역이므로 수천, 수만 개를 넣어도 논리적으로는 문제가 없으며 계속 늘어난다.
- 이 list는 static이므로 JVM 종료 전까지 GC 대상이 되지않으며, 힙 영역을 다 채울정도로 요소가 가득차게되면 힙 메모리 부족(OutOfMemoryError)이 발생할 수 있다.
- static이 붙은 참조형 변수의 ArrayList 각 요소는 gc 대상인가?
- 다른 곳에서 참조하지 않는다면 GC 대상이 된다.
- 단, 참조하지 않도록 하기위해서
list.set(0, null)
,list.remove(0)
,list.remove(someObject)
- 또는
list = new ArrayList<>()
새 리스트로 교체하는 등 모든 참조가 사라져야 한다. - 따라서 기본적으로는 읽기전용 immutable 데이터 전용(final)으로만 쓰고, 전역 mutable 컬렉션은 피하는 것이 좋다.
- mutable을 사용해야한다면,
static
컬렉션은 되도록 캐시처럼 만료 정책을 두거나, 약한 참조(WeakReference
,WeakHashMap
)를 고려하는 것이 좋다.
- Overflow란?
- 컴퓨터 프로그램에서 값이 해당 자료형의 범위를 초과하는 상황
- JVM안에서 스택을 연다라고 표현하는것은?
- 보통 메서드를 호출하면, call stack에 frame을 푸시하는데 이를 말한다.
- “새로운 메서드 실행을 시작한다, 즉 호출 스택에 새로운 프레임을 추가한다“라는 의미이다.
- Stack overflow, overflow -> 보수때문에 사인 비트가 역전되면서 부호가 마이너스로 된다.
- OOM의 발생원인?
- 자바에 할당된 힙 영역을 초과해서 객체가 쌓이면 발생. -> GC가 더 이상 회수 불가능한 객체 발생
- GC가 계속 돌지만 거의 회수를 못할 때, JVM은 성능 저하를 막기 위해 OOM 발생시킴
- ClassLoader를 계속 새로 생성하며, Metaspace에 클래스 메타 정보가 쌓이고 GC되지 않는다.
- 상태란 무엇인가?
- 컴퓨터에서 특정 요소가 가지고 있는 값이다. 객체에서는 멤버변수의 값이 해당
- 클래스가 상태를 가진다는 의미는? 무슨 문제가 발생하는가?
- dto도 상태를 가질텐데, 롬복으로 getter setter 관리를 하지만 … -> immutable
- API를 stateless로 만들어야 하는 이유는?
- API에서 상태는?
- API에서 말하는 state(상태)란, 클라이언트와 서버 간의 상호작용(요청-응답)에서 어떤 정보를 기억하거나 유지하고 있는지 여부를 의미한다. 이 개념은 주로 Stateless vs Stateful 아키텍처를 설명할 때 사용된다.
- 음원 업로드 API에서 멱등성을 유지한다는 의미는? 이를 보장하기 위해서는?
- 특정 곡에 대해서 음원이 2개 이상 중복 등록되지 않도록 하는것. 즉, 같은 요청을 여러번 보내더라도 서버는 1개만 등록한다.
- idempotency-key를 두고, 같은 키가 요청되면 처리결과를 캐싱하거나 재사용한다.
- 파일의 해시값을 클라이언트가 보내도록 하여, 해당 해시값의 파일이 이미 있는지 중복검사
- 회원가입을 하는데 멱등성을 보장한다는 의미는? 이를 보장하기 위해서는?
- Stateless, Statsful API란? 대표적인 사례를 말해봐라.
- assignment vs equallity vs equals
- = 는 좌변의 변수에 우변의 값을 할당하는 연산자이다.
- == 는 좌변과 우변의 값을 비교하여 boolean을 리턴한다. 이때 참조형 변수는
- equals를 롬복 외에 직접 구현해본적이 있는가?
- hashCode는 무엇인가?
- 자바에서 HashMap, HashSet의 객체의 키값으로 사용되는 값
- 해시 충돌을 최대한 회피할 수 있는 값으로 작성해야하는데, 이를 위해서 소수(prime number)를 포함한 계산식으로 최대한 고유한 키값을 생성해낼 수 있다.
- volatile이란?
- volatile은 메인 메모리 전체에서 접근 가능하도록 하는 키워드이다.
- transient란?
- Serializable을 구현한 클래스에서 transient가 붙은 필드는 직렬화 대상에서 제외된다. 보안상 숨겨야하거나 직렬화할 필요가 없는 필드에 붙이면 된다.
- 자바는 인터프리터 언어인가? 컴파일 언어인가?
- state와 behavior
- 변수의 종류 4가지? -> 지역 변수, 매개 변수, 클래스 변수, 인스턴스 변수 -> 각 변수가 언제, 누가 GC하는지 아는게 중요 -> 자바최적화 책을 참고! 데이터중심 애플리케이션 설계와 이 책 두 개만 보면 면접 거의 합격
- 프리미티브 타입 vs 래퍼런스 타입
- 자바에서 배열이 있고 복사를 할때 시간복잡도는? O(n)이 아니고 상수 시간복잡도를 가진다. 어셈블리어 까지 봐야함 -> System.arrayCopy -> JVM 코드 및 리눅스 커널까지
- 디스크와 메모리의 차이는? -> 개략적인 규모 추정
- String을 리터럴로 정의했을때와 new String으로 생성했을때의 차이는?
- static final String = “a” -> static은 JVM에서 딱 하나만 생성하는 방법이다. 락 관련해서 이야기를 할 부분이 또 있음.
- floating point란?
- 자바에서 실수를 표현하기 위한 방법으로, 고정 소수점과는 대비되는 개념이다.
- 말 그대로 소수점이 유동적으로 위치하는 방식으로 계산하여 수를 표현한다.
- 구조를 보면 1bit의 부호비트, 8bit의 exponent, 23bit의 mantissa로 구성되어있다.
- exponent는 소수점의 위치를 결정하며, mantissa는 실제 수의 값 자체에 해당한다. 이 부분이 값의 정확도를 결정한다.
- 이 방식의 문제점은 순환소수가 포함되었을 때, 이진수로 변환과정에서 mantissa의 값이 오염되어서 정확도가 떨어진다는 점이다.
- 예를 들면, 0.1은 이진수로 표현하면 00111101110011001100110011001101… 인데, 이런 순환소수가 포함된 연산이 누적되면 오차가 크게 발생할 수 있다.
- floating point의 계산중에 순환소수가 포함되지 않으리라는 보장이 있나? 그러면 계산중에 순환소수가 발생하지만 않으면 무조건 안전한가? 그렇다고 한다면 순환소수가 런타임 중에 입력으로 들어오는지를 실시간으로 감시하다가 순환소수가 들어오면 분기처리하는 방식도 가능할까?
- GraphQL를 사용했을때의 장단점, 문제점? DB와 캐시까지 고려해서? -> DB에서 쿼리로 가져올때 불필요한 조인을 통해 데이터 셋 전체를 가져와야함. 캐시는 key-value 스토어인데, 파라미터 조합별로 경우의수가 많아지고 캐시 스토리지를 많이 사용할 수 있다. 즉, 인풋을 원하는대로 조작하기 어려움. 캐시는 극단적으로 적용하게 되면 비용면에서 이득인데, trade-off를 살펴보고 그 임계치를 계산으로 알아내는 것이 중요하다.
- NoSQL이란? NoSQL의 장점은?
- B+Tree vs LSM Tree
- MySQL vs MongoDB, InnoDB vs WiredTiger -> 엔진의 차이를 모르고 DB를 선택하지 말라. 엔진의 차이를 보고 이 서비스에서 어떤 DB가 더 적합한지를 판단하는 과정이 필요
- 도큐먼트란?
- PostgreSQL, MySQL 중에서도 Aurora의 차이는?
- GC란?
- 자바의 JVM에서 메모리의 힙 영역을 효율적으로 사용하기 위해서 더이상 참조하지 않는 객체를 메모리에서 해제하는 작업
- 기본적인 GC의 메커니즘은 Mark and Swap이며 Mark하는 중에 STW가 발생한다. 이는 Marking 중에 일관된 참조 상태를 보장하기 위해서이다.
- 그리고 JVM은 힙 영역을 Young Generation, Old Generation, Metaspace로 나누어서 관리한다.
- Young에는 Eden과 Survivor 영역으로 나뉘며, 새롭게 객체가 생성되면 Eden에 배치된다. 그리고 Eden에서 살아남은 객체는 S0, S1으로 이동한다. 대부분의 객체는 Young에서 생성되고 빠르게 소멸된다.
- Old는 Young에서 살아남은 객체가 이동한다.
- GC 알고리즘은 Serial GC, CMS GC, G1GC, ZGC가 있음
- State란?
- API에서 state란?
- stateful한 서버를 확장하려면?
- hashCode란? 구현은? 31을 곱하는 이유는?
- 자바에서 객체를 식별하기 위한 정수값(해시코드)을 반환하는 메서드이다. 주로 HashMap, HashSet, HashTable에서 이 값을 키로 사용한다.
hashCode()
의 목적은 정확한 동등성 비교가 아니라, 좋은 해시 분포를 통해 충돌을 줄이는 것입니다. 그 목적을 벗어나 너무 복잡하게 만들면 오히려 성능만 나빠진다.
- HashMap, HashSet 구현 열어보기
- HashMap 구현중에서 정말 좋은 알고리즘이 있어서 참고해볼것
- hash()에서 고속 시프트 연산 »> 16과 XOR을 사용해 상/하위 비트를 섞어서 분산성을 향상시킨다.
- HashSet은 내부적으로는 HashMap으로 구현됨
transient HashMap<E,Object> map;
- volatile과 transient는? -> n개의 스레드가 하나의 메인메모리에 접근할 때 쓰기는 위험할 수 있지만, 읽기 작업도 위험한가?
- serializable
- floating point
- BigDecimal이 아니라 자료구조를 직접 작성해서 쓰는 경우가 있다. 성능이 600배 빨라지기도 한다. BigDecimal의 구현을 알아보라.
- 프리미티브 타입 배열에는 기본값이 있나? int는 0으로 세팅됨. C나 C++은 쓰레기값이 들어감.
- 래퍼런스 타입 배열에는 기본값이 있나?
- 래퍼런스 타입에다가 null을 add할 수 있나?
- 배열의 toString을 호출하면 어떤 값이 출력되나? -> 정확하게는 hashCode값일텐데..
- invoke 패밀리에 대해서 공부하기
- invokevirtual
- 배열의 크기를 벗어난 영역을 참조하면 ArrayIndexOutOfBounderException이 발생하는데, 처음부터 크기를 크게 잡으면 안되나? ArrayList는 왜 처음에 크기를 작게하고 add하면 크기를 키우는 방식을 채택했을까?
- 배열을 컴퓨터에서 최대로 잡으면 사이즈가 몇이되나? -> int max value
- ArrayList 구현해본적 있는가?
- 네이버에서 HashMap을 구현하라는 문제
- HashSet은 실제로 HashMap을 사용한다.
- ConcurrentHashMap이 syncronized를 사용한 HashMap보다 훨씬 빠른 이유는?
- 동시성과 병렬성의 차이는?
- ConcurrentHashMap은 16개 기준으로 스레드를 잡고 16개의 버킷이 있다. 그 이유는? 직접 구현해봐라
- JPA에서 NoArgsConstructor를 반드시 선언해야하는 이유는? 리플렉션 때문
- 리플렉션을 왜 내부적으로 사용하는가?
- static 키워드를 주의해야하는 이유는? gc 대상이 아니라서 메모리를 계속 점유하고 있음
- Pass by value vs pass by reference
- MSA의 정의?
- 보상 트랜잭션
- 자바는 pointer가 없는데 왜 NPE가 나는가?
- sqs vs rabbitmq vs kafka 차이를 알기
- 고승범 카프카 책 보기
- 레디스는 nxset 커맨드 왜 나온지 알아보기
- 가상면접사례로 .. 책 보기 데이터 중심… 책도 보기
floating point란?
자바 패키지에서 금지된 예약어?
- 자바의 예약어(keyword)는 모두 사용할 수 없다. -> for, new, if, switch, …
- java.lang은 컴파일은 되지만, 클래스 로딩 시 충돌 or 금지됨
- 숫자로 시작할 수 없음, 언더스코어를 제외한 특수문자 금지, 공백포함 금지, 도트사용 금지(패키지 계층 표현할때만 사용가능),
패키지란?
패키지의 목적은?
접근 제어자?
필드는 프라이빗, 메소드는 퍼블릭으로 만드는 이유는? -> 캡슐화를 위해
자바 레코드
오버로딩
오버라이딩
오버라이딩할때 접근제어자의 제약?
다형성이란?
다형성을 이용한 디자인 패턴?
instanceOf란?
Stack, Vector가 상속과 잘못된 syncronized 구현으로 망친 사례
상속보다는 합성을 사용하라
컴포지트 패턴이란? -> HashMap 구현을 보면 이해가 됨
부분-전체 계층 구조를 표현할 때 사용하는 Structural Pattern이다.
트리 구조로 구성된 객체들을 동일한 방식으로 다루기 위해 사용한다.
1 2 3
Component (인터페이스 또는 추상 클래스) ├── Leaf (단일 객체) └── Composite (다른 Component들을 포함하는 객체)
- 공통 인터페이스로 단일 객체와 복합 객체를 일관된 방식으로 처리가능, 재귀와 잘 어울림
API란?
Equals and hashCode?
equals를 오버라이딩하고 hashCode를 오버라이딩 하지않으면? -> hash collision
Wait and notify
Finalize and clone -> copy
equals의 다섯가지 항목 -> JPA에서도 도움이 되는 부분. 이에 대한 테스트 코드를 작성해주면 좋음
인터페이스란?
- 메서드의 이름, 매개변수, 반환 타입만 정의하고 실제 구현은 하지 않는 계약서 or 기능명세 역할
- 다형성을 제공하고, 클래스 간 결합도를 낮춰 유연하고 확장 가능한 설계를 가능하게 함
- 모든 메서드는 기본적으로
public abstract
모든 필드는 기본적으로public static final
다중 구현 가능 (Java는 클래스 다중 상속 X, 인터페이스는 다중 구현 O)
인터페이스와 추상클래스의 차이?
- 추상 클래스는 추상 메서드와 일반 메서드를 가질 수 있으며, 단일 상속만 가능하다.
- 인터페이스는 생성자가 없고, 모두 public이며 다중 구현이 가능하다.
SOLID 원칙
- Single Responsibility: 클래스는 하나의 책임만 가져야 한다. 변경의 이유도 하나뿐이어야 한다.
- Open/Closed: 소프트웨어 요소는 확장에는 열려있고, 변경에는 닫혀 있어야 한다. -> 전략 패턴 or 다형성으로 가능, DiscountPolicy
- Liskov Substitution: 자식 클래스는 부모 클래스를 대체할 수 있어야 한다. -> 계약을 위반하면 안된다.
- Interface Segregation: 클라이언트는 자신이 사용하지 않는 인터페이스에 의존하면 안된다. -> 인터페이스를 쪼개어서 꼭 필요한것만 구현하도록 해야한다.
- Dependency Inversion: 고주순 모듈은 저수준 모듈에 의존하면 안된다. 추상화에 의존해야한다.
final이란? -> final이 붙으면 immutable
enum이란?
- 열거형 상수만을 포함한 특수한 클래스이다. 내부적으로는 static으로 선언되어서 메모리 상에 딱 하나만 생성된다.
enum은 JVM안에서 몇 개나 생성되나? -> static으로 취급해서 하나만 생성됨
예외란?
- Throwable 클래스를 상속한 클래스들의 인스턴스이다.
Checked exception vs unchecked exception
- checked exception은 Exception 클래스를 바로 확장한 클래스이며, thorws or try~catch로 처리하는 로직이 반드시 작성되어야 한다.
- unchecked exception은 Exception을 상속하는 RuntimeException을 확장한 클래스이며, 반드시 처리하는 로직을 작성할 필요가 없다.
- @Transactional 안에서는 ‘예기치 못한’ 상황에 대해서만 트랜잭션을 롤백하라고 명시되어 있다. 따라서 기본적으로는 Unchecked Exception 발생 시 롤백되며, Checked Exception 발생 시 롤백되지 않고 커밋된다.
equals 다섯가지 고려사항?
- Reflexivity: null이 아닌 x에 대해 x.equals(x) == true
- Symmetry: null이 아닌 x, y에 대해 x.equals(y) == true -> y.equals(x) == true
- Transivity: null이 아닌 x, y, z에 대해 x.equals(y) == true and y.equals(z) == true -> x.equals(z) == true
- Consistency: null이 아닌 x, y에 대해 x.equals(y) == true -> x.equals(y) == true, x.equals(y) == true, … 항상 보장
- Null 아님: null이 아닌 x에 대해 x.equals(null) == false여야 한다.
equals와 JPA에서의 주의할 점
인터페이스란?
- 객체가 가져야할 동작(메서드)을 정의하는 계약의 명세서이다. 따라서 기본적으로는 public 추상메서드만 가진다.
- 추상 클래스는 마찬가지로 공통 동작(메서드)을 정의할 수 있다. 추상 메서드를 가질 수 있고, 구현 메서드를 포함할 수 있다.
- 다만, 단일 상속만 가능하므로 다중 구현이 가능한 인터페이스에 비해 유연성이 떨어진다.
- 인터페이스는 “이렇게 해야 해!”라고 명세만 정하는 설계도.
- 추상 클래스는 “기본은 이렇게 할 테니, 이 부분만 알아서 해!”라고 기본 구현까지 제시하는 반쯤 완성된 클래스.
리스코프 치환원칙이란?
- 하위타입의 객체로 상위타입의 객체를 대체할 수 있어야한다.
- 이는 상위타입에서 규정한 계약을 위반하면 안된다는 의미이다.
- 예를 들어, 상위타입에서 예외없이 특정 동작을 하도록 계약을 명시했음에도 불구하고, 하위타입에서 예외를 발생시키는 등 계약을 위반하면 안된다는 뜻이다.
서비스 레이어를 작성할 때 인터페이스를 만들어두고 구현체가 implements해서 작성하는 이유는?
- DIP. 상위계층인 컨트롤러가 구현체가 아니라 인터페이스에 의존하게 함으로써, 변경에 유연한 구조
- 구현체가 바뀌어도 인터페이스만 유지되면 상위 계층을 수정할 필요가 없음
자바 wait, notify
- 자바의 Object에 공통으로 정의된 메소드로, 스레드의 락을 해제하고, 선점할 때 사용하는 메소드이다.
- wait은 락을 해제하고 대기상태가 되며, notify는 락을 선점하여 실행 상태가 된다.
ReentrantLock
- 같은 스레드가 여러 번 락을 획득할 수 있음 (
lock()
여러 번 호출해도 deadlock 없음)
- 같은 스레드가 여러 번 락을 획득할 수 있음 (
Synchronized에서 락을 보는 세 가지 방법?
- 메소드에, 블록에, synchronized안에 객체를 넣는 방법
JIT컴파일러가 없다는 가정하에 String을 +하는 로직이 나쁘다고 말하는 이유는?
- 자바의 String은 기본적으로 immutable로 구현되며, 이를 구현하기위해서 String Pool이라는 개념을 사용한다.
- String Pool은 내부적으로 동일한 문자열에 대해서 일종의 HashMap 형태로 상수화해서 저장하는데, 이때 +연산을 하게되면 내부적으로는 매번 String 객체를 생성하게 된다. 따라서 객체 생성 비용이 매번 발생한다.
그렇다면 메모리 낭비없이 String concatenation을 하려면?
- StringBuilder or StringBuffer를 사용한다. 이 둘은 객체를 한 번만 생성하고 append 메소드로 concatenation을 수행한다.
StringBuilder vs StringBuffer?
- StringBuilder는 thread-safe하지 않고, StringBuffer는 thread-safe하다.
그러면 성능은 뭐가 더 빠른가?
- 경우에 따라 다르지만, 단일 스레드를 기준으로 했을때는 StringBuilder가 더 빠르다. 왜냐하면 StringBuffer은 thread-safe를 보장하지 위한 로직들이 포함되기 때문이다.
문자열 인코딩 방식?
- 사람이 읽을 수 있는 문자를 컴퓨터가 이해할 수 있는 이진수로 변환하는 규칙 or 방식, 각 바이트를 읽고 해석하는 방법
- 데이터를 저장, 전송, 읽을 때 모두 같은 인코딩 방식을 사용해야한다.
UTF-8, UTF-16이 어떻게 구성되었는지? -> 바이트 배열이 어떻게 구성되는지 알아보고, 인코딩 방식을 변경함에 따라 테스트코드를 작성해보기
캐릭터셋?
- 사용 가능한 문자의 목록(집합)
- ‘ASCII’는 128개의 문자를 표현 가능하다.
- ‘유니코드’라는 캐릭터 셋은 ‘A’, ‘B’, ‘가’, ‘1’, ‘#’, ‘☺️’ 등 140,000자 이상을 포함하는 캐릭터 셋
- 유니코드는 UTF-8, UTF-16, UTF-32 등 다양한 방법으로 저장 가능
inner class란?
- nested class 중에 클래스 안에 정의된 이름을 가지는 클래스이다.
inner class가 gc에 방해가 되는 원인은?
inner class의 적용 사례?
- GUI 라이브러리에서 많이 사용됨
nested class란?
익명 클래스란?
- Nested class 중에 클래스 안에 정의된 클래스이면서 이름을 가지지 않는 클래스이다.
- 이는 정의된 블록 내부에서만 사용되며, 해당 블록을 벗어나면 더이상 참조할 수 없게된다. (참조할 이름이 없으므로)
- 따라서 단순히 해당 블록 내에서 코드를 간소화하기 위해서 사용된다.
자바 어노테이션이란?
- 자바에서 컴파일러가 인식할 수 있는 특수한 형태의 주석이다. @로 표현한다.
어노테이션이 동작하지 않는 JVM? -> GraalVM, 네이버에서는 이것을 활용하여 스프링 애플리케이션은 3초만에 띄우는 실험
@SuppressWarning 왜 함부로 쓰지말라고 하는가?
- 반드시 필요한 Warning이 있을 수 있는데, SupressWarning으로 인해서 모두 제거되므로 프로그램의 안정성이 떨어질 수 있다.
lombok이란?
- 자바에서 DTO에 생성자, getter, setter, equals and hashCode 같은 보일러 플레이트를 어노테이션 기반으로 간단히 작성할 수 있게 해주는 도구이다.
lombok의 실행 시점?
- 컴파일 타임에 실행해서 어노테이션이 붙은 클래스에 해당 메소드를 자동으로 작성해준다.
lombok의 단점? 컴파일러 해킹?
- 내부적인 코드 구현체를 모르고 사용하므로 예기치 못한 동작을 할 수 있다.
스프링 빈이 등록되는 과정? -> 클래스 패스에서 찾고, 빈 definition, 팩토리에 등록, …
빈 라이프사이클?
@Transacional 동작
프록시 기반의 AOP를 활용하여 트랜잭션을 시작하고, 정상 완료 시 커밋하거나 런타임 예외 발생 시 롤백하는 방식이다.
Checked Exception이 발생하면 커밋이 되어버리고 롤백 되지 않으므로 주의해야한다.
스프링은 기본적으로 예외가 “복구 불가능”한 경우에만 롤백한다고 명시되어있다.
1 2 3 4
@Transactional(rollbackFor = IOException.class) public void processChecked() throws IOException { throw new IOException(); // 강제 롤백됨 }
- 위와 같이 강제로 롤백하도록 checked exception도 포함할 수 있다.
프록시가 무엇인가?
- 보통 클라이언트와 서버 사이에 중계 역할을 하는 서버나 소프트웨어를 의미한다.
- 자바에서 프록시는
AOP란? AOP가 @Transactional을 적용하는 과정
자바의 정석 연습문제에 대한 답을 줄줄 할 수 있어야함. 그 중에 안되는 부분을 집중적으로 커버
GC에서 STW가 왜 발생하는가? STW가 덜 발생하게끔 유도하는게 튜닝 포인트이다.
primitive vs wrapper type
System.exit(), System.gc()
- 시스템 강제종료이므로 자원을 해제하거나 finally 블록을 실행하는 등의 처리가 누락될 수 있다. 따라서 graceful shutdown을 구현하거나 지원하도록 유도하는 것이 바람직하다.
- System.gc()를 호출하면 즉시 Full GC를 수행한다.
장애란? 장애가 나면 왜 안되는지? 왜 장애가 안나게 작성해야하는지?
System.out.println을 사용하지 말라는 이유는? -> blocking I/O + synchronized라서 성능이 안 좋은 최악의 메소드. 콘솔에 출력하는 거라서 파일로 떨구는것보다 성능이 안 좋음
logback, log4j 성능차이
애플리케이션이 서비스에서 돌아가는데 로그를 찍는게 굉장히 비용이 많이든다. 어떻게 개선할까? -> 비동기로 처리한다. 비동기로 처리하는 방법 중에는 @Async도 있을거고, 이벤트 기반으로 처리할수도 있다.
- 지식을 구체화해서 기억하기보다는 추상화해서 카테고리를 분류해서 차곡차곡 정리하자.
- 비동기로 처리한다 -> 그 방법 중에는 @Async, 이벤트 루프 등등이 있다.
Generic이 유지보수 측면에서 좋은점은?
- 컴파일러에게 타입 정보를 제공해줌으로써 런타임이 아닌 컴파일 타임에 타입체크가 가능하다.
- 타입별로 개별 작성해야하는 코드를 하나의 클래스와 메서드로 작성할 수 있다.
- instanceOf가 반복되는 복잡한 분기문을 한 문장으로 압축 가능하다.
공변성과 반공변성
- 공변성: 하위 타입 관계를 그대로 유지
Sub
가Super
의 하위 타입이면,List<Sub>
는List<Super>
의 하위 타입으로 간주할 수 있음.- 읽기 전용(Read-only)일 때 주로 사용
- 반공변성: 하위 타입 관계를 역전시킴
Sub
가Super
의 하위 타입이면,Consumer<Super>
는Consumer<Sub>
의 하위 타입이 됨- 쓰기 전용(Write-only)일 때 주로 사용
- 공변성: 하위 타입 관계를 그대로 유지
자바에서 제네릭은 기본적으로 불공변성(Invariant)
자바에서는 다음과 같은 코드가 컴파일 오류가 나는 이유가 바로 불공변성이기 때문입니다:
1 2
List<Dog> dogList = new ArrayList<>(); List<Animal> animalList = dogList; // ❌ 컴파일 오류
Dog
는Animal
의 하위 타입이지만,List<Dog>
는List<Animal>
의 하위 타입이 아니기 때문- 즉, 기본 제네릭 타입은 타입 파라미터가 다르면 전혀 다른 타입으로 간주
Generic의 extends와 super를 공변성(Covariance)와 반공변성(Contravariance)연관지어 설명하라.
- PECS
Generic을 잘 쓰는 디자인 패턴은?
- Visitor는 다양한 타입의 객체를 방문(visit)하면서, 타입별로 다른 동작을 수행
- 방문 대상은 고정되지만, 방문자(Visitor)는 다양한 구체 타입을 받아야 하므로 반공변성(
? super T
)이 유리 Visitor<? super Dog>
는Visitor<Dog>
,Visitor<Animal>
,Visitor<Object>
등 상위 타입 모두 허용- 다양한 Visitor 구현체가 Dog를 처리할 수 있음 → 반공변성 활용
kotlin reified
make (something abstract) more concrete or real.
일반적인 제네릭 함수 body에서 타입 T는 컴파일 타임에는 존재하지만 런타임에는 Type erasure 때문에 접근할 수 없다. 따라서 일반적인 클래스에 작성된 함수 body에서 제네릭 타입에 접근하고 싶다면 genericFunc 처럼 명시적으로 타입을 파라미터로 전달해주어야 한다.
하지만 reified type parameter 와 함께 inline 함수를 만들면 추가적으로
Class<T>
를 파라미터로 넘겨줄 필요 없이 런타임에 타입T
에 접근할 수 있다. 따라서myVar is T
처럼 변수가T
의 인스턴스인지 쉽게 검사할 수 있다.
C++ Template
ArrayList에 add를 하다가 ConcurrentModificationException이 발생하는 이유는? 어떻게 발생시킬 수 있을까? -> transient 필드가 있으면 발생한다.
실무에서는 ArrayList 대신에 thread-safe를 위해서 CopyOnWriteArrayList를 사용한다.
WebFlux의 back pressure란?
ArrayList가 두 배가 될때, 꽉 찼을때?
쿠키와 세션?