하지만 hashCode() 값이 서로 다른 것이 HashSet, HashMap 성능에 좋다.
HashSet, HashMap에서 hashCode(), equals()
추가하려는 객체의 hashCode()값으로 버킷을 찾는다. 해당 버킷에 들어있는 객체들에 equals()를 사용해 동등한 객체가 있는지 판단한다.
hashCode()와 equals()의 차이
비교하는 두 객체가 동등하지 않으면 equals()는 false를 반환하지만, hashCode() 값은 같을 수 있다.
Q3. loop 문 안에서 문자열 연산을 조심하라고 하는데 왜 그런 걸까요?
문자열은 불변 객체라서 객체의 내부 상태를 변경할 수 없다. 따라서 loop문을 사용해 문자열 연산을 하면 연산 과정에서 새로운 문자열이 다량으로 생성되어 JVM의 힙 영역에 있는 Constant Pool에 추가된다. Constant Pool은 힙 영역에 있어 GC의 대상이 된다. 힙 영역이 부족하게 되면 GC가 빈번하게 실행되므로 성능에 악영향을 줄 수 있다.
3-1. 이 문제를 해결하기 위해서 자바에서는 어떤 방법을 사용하나요?
StringBuffer 또는 StringBuilder를 사용한다. StringBuffer, StringBuilder은 가변 객체라서 내부의 상태를 변경할 수 있다. 내부 버퍼(char[])를 사용해 새로운 객체를 생성하지 않으면서도 자유롭게 문자열 편집이 가능하다.
Q4. static 을 사용할 때 발생할 수 있는 문제는 무엇이 있나요? 예시도 같이 설명해주세요
메모리 누수(Memory Leak)
프로그램이 사용하지 않는 메모리를 계속 점유하는 문제를 말한다.
static 변수는 메소드 영역에 저장된다. 클래스 로드 시에 메소드 영역에 저장된 후 프로그램이 종료될 때까지 메모리 해제가 이루어지지 않는다(메소드 영역은 GC의 대상이 아니다). static 변수를 무분별하게 사용하면 불필요하게 메모리를 점유하게 된다.
동시성 문제
메소드 영역은 여러 쓰레드가 공유하는 메모리 영역이므로 static 변수를 final로 선언하지 않을 시 동시성 문제가 발생할 수 있다.
Q5. interface는 무엇인가요?
클래스가 구현해야할 추상 메소드들을 나열해 놓은 것.
인터페이스의 장점
인터페이스 설계와 구현을 분리하여 구현 시 구현에만 집중할 수 있다.
구체 클래스가 아닌 인터페이스에 의존하도록 하면 OCP 원칙을 지킬 수 있다.
5-1. interface와 abstract class의 차이는 무엇인가요?
공통점
둘 다 추상화 개념을 이용해 코드의 재사용성을 높일 수 있다.
차이점
인터페이스는 구현된 메소드가 없지만 추상 메소드는 구현 메소드를 가짐.
자바 8부터 default 메소드가 추가되면서 인터페이스도 구현 메소드를 가짐.
인터페이스는 다중 상속 가능.
인터페이스는 생성자가 없다.
인터페이스는 상수만 가질 수 있다. 추상 클래스는 변수도 가질 수 있다.
인터페이스는 다른 클래스와 상호 작용을 위해 사용하지만, 추상 클래스는 하위 클래스의 공통 기능을 추상화하기 위해 사용.