1. Java 의 장단점에 대해 설명해주세요.
- 장점
- JVM에서 동작하기 때문에 운영체제에 독립적
- 객체지향 언어이기 때문에 이해하기 쉽다.
- 오픈소스로 사용할 수 있고 커뮤니티가 잘 발달되어 있다.
- 멀티쓰레드를 쉽게 구현할 수 있다.
- 가비지 컬렉터에 의해 메모리 관리를 자동으로 해준다.
- 단점
- 컴파일되고 번역하는 과정을 거치기 때문에 비교적 느리다.
- 가비지 컬렉터로 인해 메모리 공간 필요
2. Java 의 데이터 타입에 대해 설명해주세요.
자바의 데이터 타입은 기본 데이터 타입과 참조 타입으로 나뉩니다. 기본 데이터 타입으로는 byte, short, int, long, float, double, boolean, char 가 있으며 Stack 영역에
저장됩니다. 참조 타입은 기본형은 제외한 모든 타입이며, Heap 영역에 저장됩니다.
- 기본 데이터 타입(Primitive Data Type)
- 정수형 : byte, short, int, long
- 실수형 : float, double
- 논리형 : boolean(ture/false)
- 문자형 : char
- 기본 타입의 크기가 작고 고정적이기 때문에 메모리의 Stack 영역에 저장된다.
- 참조 타입(Reference Data Type)
- 참조 타입 종류: class, array, interface, Enumeration
- 기본형을 제외하고는 모두 참조형
- new 키워드를 이용하여 객체를 생성하여 데이터가 생성된 주소를 참조하는 타입이다.
- String과 배열은 참조 타입과 달리 new 없이 생성이 가능하지만 기본 타입이 아닌 참조 타입이다.
- 참조 타입의 데이터의 크기가 가변적, 동적이기 때문에 동적으로 관리되는 Heap 영역에 저장된다.
- 더 이상 참조하는 변수가 없을 때 가비지 컬렉션에 의해 파괴된다.
- 참조 타입은 값이 저장된 곳의 주소를 저장하는 공간으로 객체의 주소를 저장한다. (Call-By-Value)
3. Wrapper 클래스와 Boxing, Unboxing 에 대해서 설명해주세요.
Wrapper 클래스는 프로그램에 따라 기본 데이터 타입을 객체로 취급해야 하는 경우, 기본 타입들의 데이터를 객체로 포장한 클래스입니다. 기본 타입의 데이터를 Wrapper 클래스의 값으로 변환하면 Boxing,
반대의 경우를 Unboxing이라고 합니다.
- Wrapper Class
- 프로그램에 따라 기본 데이터 타입을 객체로 취급해야 하는 경우, 기본 타입들의 데이터를 객체로 포장한 클래스
- java.lang 패키지에 존재
| 기본 타입 | 래퍼 클래스 |
|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
- Boxing
- 기본 타입의 데이터를 Wapper 클래스의 인스턴스로 변환하는 과정
- Unboxing
- Wrapper 클래스의 인스턴스에 저장된 값을 기본 타입의 데이터로 꺼내는 과정
4. Java는 Call by Value인가요 Call by Reference인가요?
자바는 Call by Value 를 따릅니다. 기본 자료형의 경우 해당 값이 복사되어 전달되고, 참조 자료형의 경우 힙 메모리의 참조값이 복사되어 전달됩니다.
-
자바에서 파라미터는 항상 값으로 전달됩니다. (파라미터의 복사본이 메서드에 전달)
-
기본 자료형의 경우 값의 복사본이 전달됩니다.
-
참조 자료형의 경우 힙 메모리의 주소값이 복사되어 전달됩니다.
- 아래 예시의 경우 User 의 메모리가 복사되어 전달된다. b 의 경우 새로운 주소를 할당하는데 메서드가 종료되면 원본 b 에는 반영되지 않는다.
class User {
public int age;
public User(int age) {
this.age = age;
}
}
public class ReferenceTypeTest {
void test() {
User a = new User(10);
User b = new User(20);
System.out.println(a);
System.out.println(b);
modify(a, b);
System.out.println(a);
System.out.println(b);
}
private void modify(User a, User b) {
a.age++;
b = new User(30);
b.age++;
}
}
5. Java 의 접근제어자는 어떤 것이 있나요?
자바의 접근 제어자로는 제약 없이 접근 가능한 public, 동일 패키지 또는 상속 관계에서 접근 가능한 protected, 동일 패키지에서만 접근 가능한 package-private, 선언한 객체에서만 사용 가능한
private 이 있습니다.
| 접근 제어자 | 설명 |
|---|
public | 해당 객체를 사용하는 프로그램 어디에서나 접근 가능 |
protect | 동일 패키지 또는 상속 관계의 객체에서 접근 가능 |
package-private | 동일 패키지에서 접근 가능 |
private | 해당 객체에서만 사용 가능 |
6. 클래스, 객체, 인스턴스를 비교해주세요.
클래스는 객체를 만들어 내기 위한 틀로서 객체가 가질 수 있는 속성과 메서드를 정의하며, 이를 실체화한 것이 객체입니다. 인스턴스는 객체의 구체적인 사례입니다.
- 클래스(Class)
- 객체를 만들어 내기 위한 설계도 혹은 틀
- 연관되어 있는 변수와 메서드의 집합
- 객체(Object)
- 소프트웨어 세계에 구현할 대상
- 클래스에 선언된 모양 그대로 생성된 실체
- '클래스의 인스턴스(instance)' 라고도 부른다.
- 인스턴스(Instance)
- 설계도를 바탕으로 소프트웨어 세계에 구현된 구체적인 실체
- 즉, 객체를 소프트웨어에 실체화 하면 그것을 '인스턴스'라고 부른다.
- 실체화된 인스턴스는 메모리에 할당된다.
7. static 키워드에 대해 설명해주세요.
클래스 멤버를 정의할 때 사용되며, 객체가 생성되기 전에 초기화 되며, 모든 인스턴스에서 공유되어 사용됩니다.
- 클래스 멤버를 정의할 때 사용
- 객체가 생성되기 전에 클래스의 로딩 과정에서 메모리에 할당되므로, 객체 생성 없이 클래스 이름만으로 접근할 수 있다.
- static 키워드를 적절히 사용하면, 메모리를 효율적으로 사용하거나 객체 생성 없이도 편리하게 접근할 수 있는 장점이 있다.
8. 클래스 멤버와 인스턴스 멤버
- 클래스 멤버: 클래스에 존재하는 변수와 메서드.
- 인스턴스 멤버: 객체(인스턴스)에 존재하는 변수와 메서드. static 키워드를 사용하지 않고 정의한다.
- 클래스 멤버에서는 인스턴스 멤버가 접근 가능하지만, 인스턴스 멤버에서는 클래스 멤버로 접근이 불가능하다.
9. static 멤버와 non-static 멤버는 무슨 차이가 있나요?
- static 멤버는 클래스가 로딩될 때 메모리에 할당되며, 모든 인스턴스에서 공유됩니다. 반면에 non-static 멤버는 각 인스턴스가 생성될 때 메모리에 할당되고, 인스턴스마다 고유한 값을 가집니다.
| 항목 | 메모리 할당 시기 | 접근 방법 | 공유 여부 |
|---|
static | 클래스가 로딩될 때 | 인스턴스를 생성하지 않고 클래스 이름으로 접근 | 모든 인스턴스가 동일한 값 공유 |
non-static | 인스턴스가 생성될 때 | 인스턴스를 생성한 후 접근 | 인스턴스마다 고유한 값 존재 |
10. main 메서드는 왜 static 메서드인가요?
- main 메서드는 프로그램이 실행될 때 가장 먼저 호출됩니다. 인스턴스가 생성되기 전에 호출되어야 하기 때문에 static으로 정의되어야 합니다.
- main 메서드는 프로그램이 시작할 때 JVM에 의해 호출됩니다. 만약 non-static 메서드라면, main 메서드를 호출하기위해 클래스를 인스턴스화 시켜야 하기 때문에 JVM 에서 직접 호출이 불가능합니다.
따라서 main 메서드는 static 메서드여야 합니다.
11. 자바 프로그램 실행 시 static 이 붙은 변수는 어떻게 처리되나요?
- static 이 붙은 변수는 해당 클래스가 로딩될 때 Method Area에 한번 초기화되고 값 변경이 일어나지 않습니다. 이후에 인스턴스를 초기화하지 않고 사용할 수 있습니다.
- 자바 프로그램이 실행되고 JVM이 프로그램에서 사용되는 클래스를 로드하고, 해당 static 변수를 초기화합니다.
- JVM은 Method Area 에 static 변수에 메모리를 할당합니다.
12. 오버로딩과 오버라이딩을 비교해주세요.
- 오버로딩은 메서드의 이름은 같고 파라미터를 다르게 한 것이고, 오버라이딩은 부모 클래스의 메서드를 자식 클래스에서 재정의하는 것을 의미합니다.
- 오버로딩
- 이름은 같고 매개변수의 수, 타입 또는 순서가 다른 여러 메서드 정의
- 반환하는 타입은 달라도 된다.
- 오버라이딩
- 메서드 이름과 매개변수가 동일한 부모 클래스의 메서드를 자식 클래스에서 재정의하는 것
- 오버라이딩된 메서드가 자식클래스의 인스턴스에서 호출되면 부모 클래스의 메서드는 무시된다.
13. 인터페이스와 추상클래스를 비교해주세요.
- 둘의 차이는 목적에 있어 차이가 있습니다. 추상클래스는 abstract 키워드로 선언된 클래스로서 기능을 이용하고 확장하도록 의도합니다. 반면, 인터페이스는 추상메서드로만 이루어진 것으로 기능의 구현을 강제하도록 의도합니다. 이때문에 추상클래스는 공통 기능을 가지는 기반 클래스로 적합하며, 인터페이스는 다형성이 필요한 경우에 적합합니다.
- 추상클래스
- abstract 키워드로 선언된 클래스
- 자식 클래스가 추상클래스의 기능을 이용하고 확장하는데 초점을 둔다.
- 클래스이기 때문에 다중상속은 지원하지 않는다.
- 기능의 확장에 초점을 두기 때문에 공통 기능을 가지는 베이스 클래스에 적합하다.
- 인터페이스
- 추상 메서드와 상수로만 이루어진 것
- 인터페이스는 선언된 기능을 구현하도록 강제한다.
- 기능의 구현을 강제하기 때문에 같은 기능을 다르게 구현하는 다형성이 필요한 경우에 적합하다.
- 다중 상속이 가능하다.
- 다중 상속을 할 때 메서드 충돌은 어떻게 해결할까?
- 다중 상속을 하더라도 인터페이스에는 구현부가 없고, 구현 부분이 하나이기 때문에 컴파일 에러는 나타나지 않는다.
- 다만, default 메서드를 통해 인터페이스에서 구현하는 경우 컴파일러는 오류를 내보낸다. (모두 구현된 경우)
- 이 경우 2가지 해결 방법이 존재한다.
- 인터페이스에서 구현하지 않고 상속한 클래스에서 구현한다.
- 하나의 인터페이스로 구현을 위임한다.
- 추상 메서드
- abstract 키워드와 함께 구현부는 작성되지 않고 선언부만 작성된 메서드
- final 키워드가 붙은 메서드는 추상 메서드로 만들 수 없다.
- 물론 static 메서드도 추상 메서드로 만들 수 없다.
14. 클래스는 왜 다중 상속을 허용하지 않을까요?
-
다중 상속을 허용하지 않는 이유는 모호성때문입니다. 다중 상속하는 클래스에서 이름이 같은 메서드가 있다면 어떤 메서드를 컴파일러가 호출할지 모호하기 때문에 자바에서는 다중 상속을 지원하지 않습니다.
-
자바에서는 모호성때문에 다중 상속을 지원하지 않는다.
-
부모 클래스들에서 같은 이름을 가진 메서드나 변수가 있다면, 자식 클래스에서 어떤 메서드를 컴파일러가 호출할지 모호하기 때문이다.
15. Java의 Error, Exception 구조에 대해 설명해주세요.
- 자바의 Error 와 Exception 은 모두 Throwable 객체를 상속받습니다. Error 는 주로 시스템 레벨의 심각한 에러로서 개발자가 처리할 수 없는 에러입니다. 반면, Exception 은 크게 RuntimeException 과 다른 Exception 으로 구분되며, 주로 개발자가 작성한 프로그램에서 발생하는 에러입니다.
- Error
- 시스템에 발생하는 심각한 예외 상황을 나타냄
- OutOfMemoryError, StackOverflowError 등
- 시스템 자체에서 발생하여 개발자가 대응할 수 없다. -> 따로 처리하지 않아도 된다.
- Exception
- 개발자가 작성한 프로그램에서 발생하는 예외 상황을 나타냄
- RuntimeException, IOException 등
- 일반적으로 RuntimeException 과 나머지 Exception 으로 구분되어 구조화한다.
- try-catch-finally 구문을 사용하여 예외 처리를 해야한다.
16. CheckedException 과 UncheckedException 은 무슨 차이인가요?
- UncheckedException 와 CheckedException 의 차이는 예외 처리의 강제성에 있습니다. CheckedException 은 컴파일 과정에서 발생하여 예외를 강제하는 반면, UncheckedException 은 런타입 과정에서 발생하는 예외이기 때문에 컴파일 과정에서 예외 처리를 강제하지 않습니다.
- UncheckedException
- RuntimeException 과 이를 상속한 예외
- 런타임 과정에서 발생하는 예외
- 예외 처리를 강제받지 않음
- 다만 예외가 런타임 과정에서 발생하기 때문에 예상하지 못한 에러가 발생할 수 있다.
- 따라서 예외 상황이 발생할 것을 대비하여 예외 처리를 하는 것이 좋다.
- CheckedException
- RuntimeException 을 제외한 Exception 예외
- 컴파일 과정에서 발생하는 예외
- 컴파일러에 의해 예외 처리가 강제됨
17. 예외처리의 세 가지 방법을 설명해주세요.
- 예외 처리 방법으로 예외 상황을 정상 상태로 돌려놓는 예외 복구, 호출한 메서드로 예외 처리를 넘기는 예외 회피, 다른 예외로 전환하는 예외 전환이 있습니다.
- 예외 복구
- 예외가 발생하더라도 애플리케이션이 정상적인 흐름으로 동작하도록 진행
- 예외 회피
- 예외가 발생하면 throws 를 통해 호출한 메서드로 예외 처리를 위임하는 것
- 예외 전환
- 다른 예외로 전환.
- 호출한 메서드에서 예외를 처리할 때 더 명확하게 예외 상황을 인지할 수 있도록 돕는다.
- throw 를 통해 실행
18. final 키워드는 왜 사용할까요? 어떤 이점이 있을까요?
- final 키워드는 변수와 메서드, 클래스에 붙어 변하지 않도록 하는 역할을 수행합니다. 의도치 않은 변경을 줄여 코드 안정성을 보장하고 final 변수는 상수이기 때문에 컴파일 과정에서 성능 향상을 가져올 수 있습니다. 또한, 코드 가독성을 높일 수 있습니다.
- 코드 안정성
- 의도치 않은 코드 변경을 줄일 수 있기 때문에 코드 안정성이 높아진다.
- 성능 향상
- final 변수는 상수로 취급하여 컴파일 과정에서 변수를 계산하는 과정이 준다. 이만큼 성능 향상을 불러올 수 있다.
- 코드 가독성
- 변수, 메서드, 클래스에 final 키워드를 붙이면 변경되지 않는다는 의미를 명확하게 전달할 수 있다.
19. final, finally, finalize 에 대해 설명해주세요
- final 키워드는 변수, 메서드, 클래스를 변경 불가능하도록 만드는 것이고, finally 는 try-catch 구문 마지막에 항상 실행될 코드 블록을 정의하기 위해 사용됩니다. 마지막으로 finalize 는 GC 가 더이상의 참조가 존재하지 않는 객체를 메모리에서 삭제할 때 사용되는 메서드입니다.
- final
- 기본 데이터 타입에 적용: 변수에 저장된 값의 변경이 불가능
- 참조 데이터 타입에 적용: 참조 변수의 힙 메모리를 재할당 불가능
- 메서드에 적용: 오버라이드 불가능
- 클래스에 적용: 상속 불가능
- finally
- try-catch 구문이 종료될 때 항상 실행될 코드 블록을 정의하기 위해 사용
- JVM 이 종료되거나 해당 프로세스가 종료되지 않는 이상 무조건 실행된다.
- return 문이 try 에 있어도 finally 코드 블록이 실행됨
- try-with-resources 구문을 사용할 수 있으면 try-catch-finally 대신 사용할 것
- 예외가 중복될 경우 디버깅이 힘듦
- 가독성이 나빠짐
- finalize
- Garbage Collector 가 더이상 참조가 존재하지 않는 객체를 메모리에서 삭제할 때 호출하는 메서드
- Object 클래스의 finalize 메서드를 오버라이딩하여 커스텀할 수 있다.
20. final 키워드는 컴파일 과정에서 다르게 실행될까요?
- final 키워드가 붙은 변수는 상수와 같이 취급이 됩니다. 메서드는 오버라이딩이 안되기 때문에 오버라이딩한 메서드를 찾는 과정이 생략됩니다. 클래스는 상속이 불가능하기 때문에 자식 클래스를 찾는 과정이 생략됩니다.
21. 제네릭에 대해 설명해주세요.
- 제네릭은 클래스 내부에서 사용하는 타입을 외부에서 지정할 수 있는 방법입니다. 장점으로는 컴파일 시점에 타입 체크를 진행해 타입 안정성을 보장하고 코드 중복을 줄여줍니다. 반면 단점으로는 문법이 생소하여 가독성이 떨어지고 공변성 때문에 배열과의 호환성이 좋지 않습니다.
- 클래스 내부에서 사용하는 타입을 외부에서 지정하는 방법
- 장점
- 컴파일 시점에 타입 체크를 통해 타입 안정성을 보장
- 코드 중복을 줄여줌
- 단점
- 문법이 생소하여 가독성이 떨어짐.
- 배열의 공변성으로 인해 배열과의 호환성이 떨어짐
22. 리플렉션이 무엇이고, 언제 활용 가능한지 설명해주세요.
-
리플렉션은 동적으로 클래스의 정보를 얻어 사용할 수 있는 기법입니다. 주로 런타임에 클래스에 접근하여 정보를 얻어야 할 때 사용됩니다. 예시로는 Spring 의 애노테이션, Jackson 등이 있습니다.
-
런타임에 클래스의 이름, 메서드, 필드 등을 동적으로 가져오는 API
-
클래스 정보가 런타임 시점에 필요할 때 이용
-
Spring 의 애노테이션, IDE 의 자동완성, Jackson 등이 있다.
23. 리플렉션의 장단점에 대해 설명해주세요.
24. 자바의 직렬화와 역직렬화에 대해 설명해주세요.
자바에서 직렬화는 시스템 내부에서 사용되는 객체 또는 데이터를 외부 시스템에서도 사용할 수 있도록 바이트 형태로 변환하는 기술입니다. 반면, 역직렬화는 바이트로 변환된 데이터를 객체로 변환하는 기술입니다.
- 직렬화
- 시스템 내부에서 사용되는 객체 또는 데이터를 외부 시스템에서도 사용할 수 있도록 바이트 형태로 변환하는 기술
- JVM 의 메모리(힙 또는 스택)에 있는 객체 데이터를 변환
- 조건
- 기본 타입 (primitive)
java.util.Serializable 인터페이스를 상속받은 객체
- 방법
java.io.ObjectOutputStream 객체 이용
- 역직렬화
- 바이트로 변환된 데이터를 객체로 변환하는 기술
- JVM 의 메모리에 저장
- 조건
- 직렬화 대상이 된 객체의 클래스가 클래스 패스에 존재해야 하며,
import 되어 있어야 한다.
- 직렬화와 역직렬화를 진행하는 과정이 다른 시스템에서 일어날 수 있다.
- 자바 직렬화 대상 객체는 동일한
serialVersionUID 를 가지고 있어야 한다.
- 방법
java.io.ObjectInputStream 객체 이용
25. 자바의 직렬화는 언제, 어디서 사용되나요?
26. 자바의 Synchronized 키워드를 설명해주세요.
-
Synchronized 키워드를 통하여 메서드나 코드 블록에 Lock 을 걸어 스레드 간 상호 배제를 할 수 있습니다. 메서드에 작성할 경우 해당 클래스 인스턴스에 Lock 을 걸고, 코드 블록에 작성할 경우 블록으로 작성된 부분만 Lock 이 걸리게 됩니다.
-
Lock 을 걸어 스레드 간의 상호배제를 할 수 있는 키워드.
-
적용 위치: 메서드, 코드 블록
-
메서드에 적용
- 클래스 인스턴스에 Lock
-
static 메서드에 적용
- 클래스에 Lock
- static synchronized 메서드와 synchronized 메서드의 Lock 은 공유하지 않는다.
-
메서드의 코드 블록에 적용
- 인스턴스의 블록 단위에 Lock
- 동기화 전후에는 Lock 이 적용되지 않기 때문에, 효율적 사용 가능
- block 에
this 를 명시할 경우 메서드에 붙은 것과 같은 효과
public class Test {
public void run() {
synchronized (this) {
}
}
}
-
block 에는 객체 인스턴스를 지정하거나 클래스를 지정할 수 있다.
-
static 메서드의 코드 블록에 적용
- 클래스에 Lock
- 코드 블록에 this 를 지정할 수 없다.
-
동기화 순서
- Thread 의 동기화 순서를 보장하지 않는다.
27. 동기화와 비동기화의 차이를 설명해주세요.
- 동기화와 비동기화의 차이는 호출되는 함수의 반환을 신경쓰는지 여부와 연관이 있습니다. 호출되는 함수의 반환값을 기다리면 동기화, 기다리지 않으면 비동기화입니다. 자바에서 동기화는 synchronized 키워드를 통해 구현 가능하고, 비동기화는 Thread 클래스를 통해 구현할 수 있습니다.
- 동기화
- 호출되는 함수의 반환값을 기다린다. 반환이 되었으면 다음 흐름을 진행한다.
- synchronized 키워드
- Atomic 클래스
- volatile
- Main Memory 에 저장
- 모든 스레드에서 Main Memory 에 읽기, 쓰기를 하기 때문에 값이 일치함
- 비동기화
- 호출되는 함수의 반환값을 기다리지 않고 다음 흐름을 진행한다.
- Thread 를 통해 구현
28. 동시성 문제가 무엇인가요? 자바에서 동시성 문제를 해결할 수 있는 방법이 있을까요?
-
동시성 문제란 동일한 자원에 대해 여러 스레드가 동시에 접근하면서 발생하는 문제입니다. 자바에서는 해당 쓰레드만 접근할수 있는 ThreadLocal 를 통해 해결할 수 있습니다. 하지만 ThreadLocal 의 사용이 끝나면 반드시 저장된 값을 제거하는 과정을 거쳐야합니다.
-
동일한 자원에 대해 여러 스레드가 동시에 접근하면서 발생하는 문제
-
지역 변수에서는 발생하지 거의 발생하지 않고, 싱글톤, static 과 같은 공용 필드에서 주로 발생
-
읽기와 쓰기를 동시에 하는 경우에 발생
29. Thread Local에 대해 설명해주세요.
- 스레드마다 접근할 수 있는 개인 저장소를 의미합니다. ThreadLocal 의 데이터는 사용이 끝나면 반드시 삭제해야합니다. 스레드 풀 환경에서 사용이 완료된 데이터를 지워주지 않으면 재사용되는 스레드가 올바르지 않는 데이터를 참조할 수 있기 때문입니다.
30. 자바의 어노테이션에 대해 설명해주세요.
31. 자바 8에 추가된 기능들에 대해 간단히 설명해주세요.
-
자바 8에는 익명 함수를 단순하게 표기한 람다 표현식, 하나의 추상 메서드만 갖고 있는 함수형 인터페이스, 인터페이스의 default 메서드, 연속된 정보를 처리하는 Stream 클래스, null 처리를 간편하게 하기 위한 Optional 클래스 등이 있습니다.
-
주요하게 추가된 것
- Lambda
- Functional Interface
- Stream
- Optional
- 인터페이스의 Default Method
- 날짜 관련 클래스 추가
ZoneDataTime, LocalDate, DateTimeFormatter, DayOfWeek
- 병렬 배열 정렬
- StringJoiner
- 순차적으로 나열되는 문자열 사이에 특정 문자열을 넣어줄 때 사용
32. Stream에 대해 설명해주세요.
33. Stream과 반복문 for문의 성능차이가 있을까요?
- for 문은 단순 인덱스 기반으로 접근하고, 컴파일러가 최적화를 하기 때문에 성능이 더 빠릅니다. 특히 for 문은 기본 데이터 타입을 통해 접근하면 wrapper 타입에 비해 Heap 메모리에 접근하지 않아도 되서 성능이 더 올라가게 됩니다.
34. Stream에서 사용할 수 있는 함수형 인터페이스에 대해 설명해주세요.
- 사용할 수 있는 함수형 인터페이스로는 인자를 받지 않고 반환만 하는 Supplier, 인자를 받고 반환은 하지 않는 Consumer, 인자를 받고 반환을 하는 Function, 인자를 받아서 참 거짓을 판단하는 Predicate 등이 있습니다.
35. Lambda에 대해 설명해주세요.
36. 익명 클래스(Anonymous Inner Class)와 Lambda의 차이점을 알고계신가요?
- 익명 클래스는 클래스를 의미하고 여러 메서드를 포함할 수 있지만, Lambda 는 익명 메서드를 의미합니다. 또한 익명 클래스의 this 는 새로 생성된 클래스 객체를 의미하고 Lambda 의 this 는 Lambda 를 정의한 클래스를 의미합니다.
- 익명 클래스
- 이름 없는 클래스
- 추상 및 구체 클래스 확장 O
- 여러 추상 메서드를 포함하는 인터페이스 구현 O
- 익명 클래스 생성 시 인스턴스 변수 선언 O
- 익명 내부 클래스 인스턴스화 O
- this 키워드가 생성된 익명 클래스 객체를 의미
- Lambda
- 이름 없는 메서드
- 추상 및 구체 클래스 확장 X
- 여러 추상 메서드를 포함하는 인터페이스 구현 X
- 익명 클래스 생성 시 인스턴스 변수 선언 X
- 익명 내부 클래스 인스턴스화 X
- this 키워드가 생성된 Lambda 가 정의된 클래스를 의미
37. 람다식에서, 외부 변수를 사용할 때 final 키워드를 붙여서 사용하는 이유가 무엇일까요? final을 안 붙여도 되지 않을까요?
- 외부 지역 변수를 제어하는 스레드와 람다식을 제어하는 스레드가 다를 수 있기 때문입니다. 이 경우 각 스레드간 스택 영역이 다르기 때문에 값을 공유할 수 없고, 동기화할 수 없기 때문에 외부 변수가 최신 값으로 변경이 되었는지 확신할 수 없습니다. 따라서 매번 다른 결과가 도출될 수 있기 때문에 final 키워드를 붙여야 합니다.