레벨 1을 진행하면서 공부 및 경험한 것
Exception
자바 Exception 의 계층 구조
Throwable -> Exception -> RuntimeException
Throwable -> Error
Error 은 사용자가 정상적인 경우에는 복구가 불가능하다
CheckedException vs UncheckedException
Throwable 의 하위클래스 중 Error 나 RuntimeException 을 상속하지 않는 경우가 다 Checked Exception 이다.
Error 나 RuntimeException 의 하위 클래스에서는 UncheckedException 이다
Exception 이 성능에 안좋은 이유
Throwable 의 생성자를 확인해보면 무조건 StackTrace 를 전부 채우게 되어있습니다
예외를 생성할 때마다 현재 스택 프레임을 기록하기에, 그 부분이 시간이 많이 들어갔습니다
Generic
배열의 공변성에 따라 생긴 문제들
String[] strings=new String[1];
Object[] objects=strings;
objects[0]=1;
대입이 가능하지만, 컴파일 타임에 검증되지 않는 상황이 됩니다
super, extends 의 차이
super는 특정 타입을 기준으로 Object 까지 상위 타입을 모두 받겠다는 의미가 됩니다
Integer 의 Super는 Number, Object 가 가능합니다
extends 는 특정 타입을 기준으로 하위 타입을 모두 받겠다는 의미가 됩니다
Number 의 하위 타입으로 Integer, Double, Long 같은 숫자 클래스들이 있습니다
T super 타입이 존재하지 않는 이유
T super 타입 은 T의 상위타입이면 다 된다는 의미입니다. 이때 상위 타입에 Object 가 들어가기에 Object 타입으로밖에 접근할 수가 없습니다.
Object 타입으로밖에 접근하지 못하기에, T 타입의 의미가 사라지기에 없앴다고 합니다
런타임에 발생하는 type erase
generic 데이터는 런타임으로 가면 모두 사라집니다.
ArrayList<Integer> list=new ArrayList<>();
list.add(0);
int a= list.get(0);
가 런타임으로 가면
ArrayList list=new ArrayLIst();
list.add(0);
int a=(int)list.get(0);
으로 변화합니다
generic 배열을 만들 수 없는 이유
배열을 선언하게 되면 위에 적혀있는 배열의 공변성때문에 생기는 문제를 막을 수 없게 됩니다
Object[] array=T[];
array[0]=1;
같은 방식으로 대입이 가능해지기에 generic 의 장점을 살릴 수 없기에 사용하지 못하게 되어있습니다
인터페이스와 추상클래스
인터페이스와 추상클래스의 차이
인터페이스는 protected, default 접근 제어자가 불가능합니다
또한 상태를 갖을 수 없습니다
상태를 갖는 경우이거나, default, protected 가 필요하다면 추상클래스로 만들어야 합니다
default 메서드
default 메서드를 사용하는 이유
기존 인터페이스를 상속하고 있는 클래스에 변화를 끼치지 않으면서, 새로운 기능을 추가하고 싶을 때 사용할 수 있습니다
default 메서드를 사용해서 불변식이 깨진 경우
collection api 에서 removeIf 라는 함수가 있습니다.
default boolean removeIf(Predicate<? super E> filter) {
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean result = false;
for (Iterator<E> it = iterator(); it.hasNext();) {
if (filter.test(it.next())) {
it.remove();
result = true;
}
}
return result;
}
최대한 범용적으로 작성된 코드이지만, 동시성을 보장해야 하는 구현체의 경우에 이 메서드를 통해 접근하게 되면 동시성 보장이 안되는 문제가 생길 수 있습니다
하위 구현체에 대한 불변식을 깨는 문제가 생길 수 있으므로 주의해야합니다
Collector 인터페이스
Collector Interface 는
시작시 호출하는 함수
병합 함수2개,
최종 연산
구현체에 대한 정보
이렇게 총 5가지의 항목으로 이루어져있습니다
첫 함수는 데이터를 어디에 저장할지에 대한 내용입니다
병합 함수는, 단일 원소를 합칠 때, 여러 쓰레드에서 돌아갔을 때, 결과를 합칠 때를 다뤄줍니다
최종 연산은 마지막으로 원하는 형태로 데이터를 바꾸기 위한 연산입니다.
결과물에 대한 함수를 만든다고 생각하시면 될 것 같아요
구현체에 대한 정보는 총 3가지가 가능합니다
멀티 쓰레드에서 돌려도 되는지, 순서 보장이 필요한지, 최종 연산이 필요 없는지가 있습니다
람다
변하는 지역변수는 받을 수 없는 이유 final, effectively final
지역 변수는 쓰레드마다 할당되는 스택 영역에서 저장됩니다. 람다식은 어떤 쓰레드에서도 사용할 수 있기에, 쓰레드의 지역 변수를 볼 수 없습니다.
만약 이 변수가 할당된 이후에 변경된다면, 동기화를 할 수 없기에, 이런 위험성을 미연에 방지하기 위해서 변하는 지역 변수를 사용하는 것을 막았습니다
다른 변수는 힙 영역에 있기에, 동기화가 가능합니다. 따라서 변하더라도 사용할 수 있습니다
BigDecimal
BigDecimal 은 숫자의 정밀도를 보장하기 위해서 만들어져있습니다
내부적으로 scale, precision 을 이용해서 숫자의 정밀도를 보정합니다
scale 은 0이 아닌 소숫점 자리수
precision 은 양옆에 0이 아닌 부분을 정수로 바꾼 값 입니다
intCompact 를 통해서 long 범위 안의 숫자라면 직접 갖고 있습니다
0이 아닌 경우라면 intVal 로 데이터를 가지고 있게 됩니다
0부터 10까지의 범위를 미리 캐싱해두기에, 이런 부분을 활용하기 위해 valueOf 를 통해 생성할 수 있다면 생성하는 것이 좋습니다
equals 와 compareTo
equals는 1.0 과 1.00 은 다른 숫자라고 판정하지만
compareTo 는 1.0 과 1.00 은 같은 숫자라고 판정합니다
단순 숫자 크기 비교가 중요한 경우와, 동일함이 중요한 경우를 나눠놓은 것 같습니다
'우아한테크코스' 카테고리의 다른 글
레벨 인터뷰 스터디 (0) | 2023.05.07 |
---|---|
레벨 인터뷰 스터디 준비 (0) | 2023.04.23 |
다른 사람의 리뷰를 훔치자 (5) | 2023.03.19 |
[3주차 회고] 오리같이 살아보자 (1) | 2023.02.28 |
[2주차 회고] 사다리 게임 페어 프로그래밍 (0) | 2023.02.19 |