자바 8과 자바 11
자바란?
Java는 James Gosling과 Sun Microsystems의 다른 연구원들이 개발한 객체 지향 프로그래밍 언어입니다.
자바 언어의 특징
- 객체 지향 언어입니다.
- 유지 관리가 쉽고 확장성이 뛰어납니다.
- 휴대성이 높습니다.
- JVM에서 실행되기 때문에 운영체제 종류와 상관없이 동작한다.
- 메모리를 자동으로 관리합니다.
- 이 프로그램은 C/C++보다 안정적입니다.
- 다중 스레드 구현은 쉽습니다.
- 스레드 생성 및 제어와 관련된 라이브러리 API를 제공합니다.
- 동적 로딩을 지원합니다.
- 모든 클래스가 런타임에 로드되는 대신 필요할 때 클래스가 로드됩니다.
- 애플리케이션 변경도 상대적으로 적은 작업으로 처리할 수 있습니다.
- 분산 환경 지원.
- 기본적으로 TCP/IP 라이브러리가 포함되어 있으며 HTTP 프로토콜을 지원합니다.
- 오픈 소스 라이브러리가 풍부합니다.
자바 언어의 단점
- JVM에 의해 번역되고 실행되는 과정을 거쳐 컴파일되자마자 기계어로 변환되는 C, C++에 비해 속도가 현저히 떨어진다.
- 그러나 최근 자바 컴파일러를 JIT 컴파일 방식으로 개선해 속도를 크게 높였다.
- 다른 언어에 비해 작성할 코드의 길이가 다소 길다.
- 프로그램 발생 시 발생할 수 있는 예외 사항은 개발자가 직접 처리해야 합니다.
자바를 사용하는 이유? (개인적인 의견)
자바는 객체지향 프로그래밍을 구현하는 데 가장 대중적이고 편리한 언어로 꼽히며, 오랫동안 많은 기업에서 사용되어 왔기 때문에 안정성이 보장된 언어라는 평가를 받아왔다. 또한 자바진영에서는 하위호환성을 중요시하고 레퍼런스와 커뮤니티가 활발히 활동하고 있는 점도 매력적이다. 이러한 이유로 Java를 주 언어로 사용하여 개발합니다.
자바 8의 기능
힙 영구 생성 제거

Java 8 이전에는 초기 구성 중에 PermSize 및 MaxPermSize를 설정해야 했지만 Java 8부터는 Permanent Generation이 Metaspace로 대체되었습니다. Metaspace는 런타임 시 메모리 요구 사항에 따라 자체 크기를 조정하며, 필요한 경우 MaxMetaspaceSize 매개 변수를 설정하여 메타스페이스 크기를 조정할 수 있습니다.
영구 세대
- Permanet Generation은 Class 또는 Method Code가 저장되는 영역입니다.
- PermGen은 힙 영역에 속합니다.
- 기본적으로 크기가 제한되어 있습니다.
메타스페이스
- Metaspace는 지금까지 Java 클래스 로더에서 로드한 클래스의 메타데이터가 저장되는 공간입니다.
- JVM이 관리하는 힙 영역이 아닌 OS 레벨에서 관리하는 네이티브 메모리 영역에 위치한다.
- 따라서 개발자는 영역 확보의 상한선을 크게 의식할 필요가 없다. PermGen이 없는 힙 영역만 잘 관리하면 된다.
- 기본적으로 제한된 크기가 없으며 필요에 따라 커집니다.

Java 8부터는 PermGen 영역이 제거되고 Metaspace가 대체되어 위 구조가 됩니다.
인터페이스 기본 및 정적 메서드
이제 인터페이스에 기본 메서드와 정적 메서드를 포함할 수 있습니다.
interface TestInterface {
default String logic() {
return "test";
}
static String logic2() {
return "test2";
}
}
기본 메서드는 하위 구현 클래스에서 재정의할 수 있지만 정적 메서드는 구현 클래스에서 재정의할 수 없습니다.
기능적 인터페이스
단일 기능을 제공하는 하나의 추상 메서드만 정의하는 인터페이스가 추가되었습니다. 그러나 추상 메소드 외에도 기본 메소드 또는 정적 메소드를 원하는 만큼 사용할 수 있습니다. @FunctionalInterface와 함께 사용되며 추상메서드가 여러 개일 경우 컴파일 타임에 오류를 잡을 수 있다.
주요 기능 인터페이스에는 Consumer, Supplier 및 Function이 포함됩니다.
람다 식
람다 식은 식으로 표현되는 메서드입니다. 또한 람다 식은 함수 이름이 없기 때문에 익명함수라고 불리며, 메서드 매개변수로 전달되거나 메서드 결과로 반환될 수 있기 때문에 함수를 변수로 취급할 수 있는 장점이 있다.
람다 식은 메서드의 식이지만 엄밀히 말하면 이 방법으로 객체를 생성하는 것을 잊지 마십시오.해야한다. 따라서 람다 식을 사용하여 기능 인터페이스의 익명 개체를 대체하고 간결하고 부작용 없는 코드를 만들 수 있습니다.
// 외부 반복
for (String value: myCollection) {
System.out.println(value);
}
// 내부 반복
myCollection.forEach(value -> System.out.println(value));
위의 코드에서 마이컬렉션 이 목록이 호출되면 각각() 메서드의 인수는 Consumer가 됩니다. 람다식 대신 익명객체를 구현하는 것도 가능하지만 Java 8부터는 람다식을 이용하여 위와 같이 간결하게 표현하는 것이 가능하다.
방법 참조
메서드 참조는 람다 식을 보다 간결하게 표현하는 데 사용됩니다. 메서드를 참조하는 네 가지 방법이 있습니다.
정적 메서드 참조
정적 메서드에 대한 참조는 Class::MethodName으로 사용됩니다. 먼저 람다식이 사용되는 경우를 살펴보겠습니다.
boolean isReal = list.stream().anyMatch(u -> User.isRealUser(u));
이것을 메서드 참조로 변경하면
boolean isReal = list.stream().anyMatch(User::isRealUser);
위와 같이 수정 가능합니다.
인스턴스 메서드 참조
인스턴스 메서드에 대한 참조는 instance::method 이름으로 사용됩니다. 아래 코드는 User의 isLegalName(String string)을 호출하는 것을 의미합니다.
User user = new User();
boolean isLegalName = list.stream().anyMatch(user::isLegalName);
특정 유형의 객체의 인스턴스 메서드 참조
특정 유형(String, BigDecimal 등)의 인스턴스 메서드에 대한 메서드 참조를 사용할 수 있습니다.
long count = list.stream().filter(String::isEmpty).count();
생성자 참조
생성자 참조는 클래스 이름::new로 사용됩니다. 생성자는 특별한 메서드이므로 메서드 이름으로 new를 사용합니다.
Stream<User> stream = list.stream().map(User::new);
스트림 API
스트림은 컬렉션의 저장된 요소를 하나씩 참조하고 람다 식으로 처리할 수 있는 내부 반복기입니다.
List<String> list = Arrays.asList("apple", "banana", "orange");
long count = list.stream().filter(str -> str.length() > 5).count();
System.out.println(count);

Stream은 람다 식으로 요소 처리 내용 만 전달하며 컬렉션 내에서 반복이 발생합니다. 이는 개발자의 관점에서 작성되는 코드를 단순화합니다.
스트림 특성
- Streams API의 특성은 선언적이고 구성 가능하며 병렬화 가능합니다.
- 스트림은 연속 요소, 중간 작업 및 최종 작업으로 구성됩니다.
- Java 컬렉션은 외부 반복을 사용하고 스트림은 내부 반복을 사용합니다.
- 중간 작업은 파이프라인으로 연결되어 최종 작업에서 한 번에 하나씩 처리됩니다. 이를 지연 계산이라고 합니다.
- 중간 작업은 Stream을 반환하고 최종 작업은 스트림이 아닌 결과를 반환합니다.
- 중간 작업의 예로는 map, filter 및 flatMap이 있고 최종 작업의 예로는 count, foreach 및 collect가 있습니다.
데이터 수집과 스트림의 차이점은 무엇입니까?
컬렉션은 데이터를 저장, 관리 및 액세스하는 방법을 목표로 하는 반면 스트림은 데이터를 직접 액세스하거나 조작하는 기능을 제공하지 않고 데이터를 계산하는 방법을 목표로 합니다.
날짜 및 시간 API 애플리케이션
Java 8부터 LocalDate, LocalTime 및 LocalDateTime과 같은 라이브러리를 사용하면 이전보다 훨씬 쉽게 날짜 관련 논리를 작성할 수 있습니다.
// Java 8 이전 - 오늘 날짜 구하기
Calendar cal = Calendar.getInstance();
String format = "yyyy-MM-dd";
SimpleDateFormat sdf = new SimpleDateFormat(format);
String date = sdf.format(cal.getTime());
System.out.println(date);
// Java 8 이후 - 오늘 날짜 구하기
LocalDate now = LocalDate.now();
System.out.println(now);
또한 기존에 사용되던 날짜 관련 클래스인 Date, Calendar 등은 가변 객체이기 때문에 스레드로부터 안전하지 않습니다.
선택적 지원
옵션을 통해 null에 대한 참조는 안전할 수 있습니다. 과거에는 null이 아닌지 확인하는 조건문이 많이 사용되었지만 Java 8부터는 Optional을 통해 NPE를 얻는 상황을 쉽게 처리할 수 있습니다.
// Java 8 이전
public String logic() {
User user = getUser();
if (user != null) {
Address address = user.getAddress();
if (address != null) {
String street = address.getStreet();
if (street != null) {
return street;
}
}
}
return "not specified";
}
// Java 8 이후
public String logic() {
Optional<User> user = Optional.ofNullable(getUser());
String result = user
.map(User::getAddress)
.map(Address::getStreet)
.orElse("not specified");
return result;
}
배열 정렬의 병렬 처리
배열을 정렬할 때 Arrays.sort() 메서드를 사용했는데, 이 메서드는 정렬이 단일 스레드에서 순차적으로 실행된다는 단점이 있었습니다. 자바 8부터 Arrays.parallelSort() 배열을 병렬로 정렬할 수 있습니다.
가비지 컬렉터
Java 8의 기본 GC는 병렬 GC입니다.
자바 11
String 클래스에 새 메서드 추가
다음 6가지 방법이 추가되었습니다.
- 조각(): 문자열 앞뒤의 공백을 제거합니다.
- 스트립리딩(): 문자열 앞의 공백을 제거합니다.
- 스트립 후행(): 문자열에서 후행 공백을 제거합니다.
- isBlank(): 문자열이 비어 있거나 공백만 포함되어 있으면 true를 반환합니다.
- String.trim().isEmpty() 결과는 동일합니다.
- 반복(n): 문자열을 n번 반복하여 추가하여 반환합니다.
java.nio.file.Files 클래스에 새 메소드 추가
다음 3가지 방법이 추가되었습니다.
- 길 writeString(경로, 문자열, 문자 집합, OpenOption): 문자열을 파일에 쓰고 경로로 반환합니다. 파일 열기 옵션에 따라 동작 방식이 다르며 charset을 지정하지 않으면 UTF-8을 사용한다.
- 끈 읽기 문자열(경로, 문자셋): 파일의 전체 내용을 읽어 String으로 반환하고 파일의 모든 내용을 읽거나 예외가 발생하면 자동으로 닫습니다. charset을 지정하지 않으면 UTF-8이 사용됩니다.
- 부울 isSameFile(경로, 경로): 두 경로 모두 동일한 파일을 가리키며 true를 반환하고 그렇지 않으면 false를 반환합니다.
컬렉션 인터페이스에 새로운 메소드 추가
컬렉션의 toArray() 메서드를 오버로드하는 메서드가 추가되었으며, 원하는 타입의 배열을 선택하여 반환할 수 있습니다.
List sampleList = Arrays.asList("Java", "Kotlin");
String() sampleArray = sampleList.toArray(String()::new);
assertThat(sampleArray).containsExactly("Java", "Kotlin");
술어 인터페이스에 새 메소드 추가
부정을 나타내기 위해 술어 인터페이스에 not() 메서드가 추가되었습니다.
List<String> sampleList = Arrays.asList("Java", "\n \n", "Kotlin", " ");
List withoutBlanks = sampleList.stream()
.filter(Predicate.not(String::isBlank))
.collect(Collectors.toList());
assertThat(withoutBlanks).containsExactly("Java", "Kotlin");
람다에서 지역 변수 Var 사용
Var는 이제 람다 식에서 사용할 수 있습니다.
List<String> sampleList = Arrays.asList("Java", "Kotlin");
String resultString = sampleList.stream()
.map((@Nonnull var x) -> x.toUpperCase())
.collect(Collectors.joining(", "));
assertThat(resultString).isEqualTo("JAVA, KOTLIN");
자바 파일 실행
Java 파일은 javac를 통해 컴파일하지 않고 직접 실행할 수 있습니다.
// Java 11 이전
$ javac HelloWorld.java
$ java Helloworld
Hello Java 8!
// Java 11 이후
$ java HelloWorld.java
Hello Java 11!
가비지 컬렉터
Java 8의 기본 GC는 G1 GC입니다.
Java 버전 선택 기준(개인 의견)
현재 업체들을 보면 Java 8이나 Java 11이 주로 채택되어 사용되고 있는 것으로 보입니다. 개인적으로 Java 8의 기능을 수용하고 더 나은 라이브러리를 추가하고 성능이 향상된 G1 GC를 사용하는 Java 11을 사용하는 경향이 있습니다. 또한 Java 11은 LTS 버전이기 때문에 장기적인 지원이 보장되므로 향후 유용한 기능이 나올 것으로 기대하고 있습니다.
예상 인터뷰 질문 및 답변
Java 언어의 장단점을 설명하십시오.
- 장점
- 객체 지향 언어입니다.
- 유지 관리가 쉽고 확장성이 뛰어납니다.
- 휴대성이 높습니다.
- JVM에서 실행되기 때문에 운영체제 종류와 상관없이 동작한다.
- 메모리를 자동으로 관리합니다.
- 이 프로그램은 C/C++보다 안정적입니다.
- 다중 스레드 구현은 쉽습니다.
- 스레드 생성 및 제어와 관련된 라이브러리 API를 제공합니다.
- 동적 로딩을 지원합니다.
- 모든 클래스가 런타임에 로드되는 대신 필요할 때 클래스가 로드됩니다.
- 애플리케이션 변경도 상대적으로 적은 작업으로 처리할 수 있습니다.
- 분산 환경 지원.
- 기본적으로 TCP/IP 라이브러리가 포함되어 있으며 HTTP 프로토콜을 지원합니다.
- 오픈 소스 라이브러리가 풍부합니다.
- 객체 지향 언어입니다.
- 불리
- JVM에 의해 번역되고 실행되는 과정을 거쳐 컴파일되자마자 기계어로 변환되는 C, C++에 비해 속도가 현저히 떨어진다.
- 그러나 최근 자바 컴파일러를 JIT 컴파일 방식으로 개선해 속도를 크게 높였다.
- 다른 언어에 비해 작성할 코드의 길이가 다소 길다.
- 프로그램 발생 시 발생할 수 있는 예외 사항은 개발자가 직접 처리해야 합니다.
- JVM에 의해 번역되고 실행되는 과정을 거쳐 컴파일되자마자 기계어로 변환되는 C, C++에 비해 속도가 현저히 떨어진다.
왜 자바 언어를 사용합니까?
자바는 객체지향 프로그래밍을 구현하는 데 가장 대중적이고 편리한 언어로 꼽히며, 오랫동안 많은 기업에서 사용되어 왔기 때문에 안정성이 보장된 언어라는 평가를 받아왔다. 또한 자바진영에서는 하위호환성을 중요시하고 레퍼런스와 커뮤니티가 활발히 활동하고 있는 점도 매력적이다. 이러한 이유로 Java를 주 언어로 사용하여 개발합니다.
Java 8에 추가된 새로운 기능에 대해 설명하십시오.
- 힙 영구 생성 제거
- 인터페이스에 기본 및 정적 메서드 추가
- 기능적 인터페이스, 람다 식 및 메서드 참조 기능 추가
- 스트림 API 소개
- 새로운 날짜 관련 라이브러리 추가
- 선택적 지원
- 병렬 처리 지원
Java 11에 추가된 새로운 기능에 대해 설명하십시오.
- Spring에 새로운 메소드 추가
- Files 클래스에 새 메서드 추가
- 컬렉션 인터페이스에 새로운 메소드 추가
- 술어 인터페이스에 새 메소드 추가
- 람다에서 지역 변수 Var 사용
- Java 파일 실행 방식 간소화
자바 8 또는 자바 11?
현재 업체들을 보면 Java 8이나 Java 11이 주로 채택되어 사용되고 있는 것으로 보입니다. 개인적으로 Java 8의 기능을 수용하고 더 나은 라이브러리를 추가하고 성능이 향상된 G1 GC를 사용하는 Java 11을 사용하는 경향이 있습니다. 또한 Java 11은 LTS 버전이기 때문에 장기적인 지원이 보장되므로 향후 유용한 기능이 나올 것으로 기대하고 있습니다.
참조