[면접 회고] part. JAVA

falsovsveritas·2025년 3월 25일

기술면접

목록 보기
4/10
  • 최근 사용한 자바 버전, 8 이전 버전도 사용해봤는지?
  • 자바8에서 제공하는 Stream API
  • 자바 컬렉션에서 어레이리스트가 담고 있는 요소들을 다른 객체들을 변환할 때 어떤 걸 사용했는지
  • 메세지용 객체, 데이터 전달용 객체 class정의할 때 getter,setter 사용했는지?
  • 불변객체 / setter를 제공하지 않는 객체
  • 특정 클래스가 가지는 속성을 전부 final로 선언했을 때, 속성에 값을 할당할 때 어떤 방식으로 할당하는지.
  • 멤버변수에 값을 할당하는 방식 ( Setter와 생성자 )
  • 멤버변수를 final로 사용해봤는지

1. JAVA 버전별 특징

Java 버전별 주요 특징 정리

Java는 Java 8, 11, 17, 21 등의 LTS(Long-Term Support) 버전이 주로 사용되며, 그 외의 버전은 단기 지원입니다.

🔹 Java 8 (2014, LTS)

주요 특징:

  • Lambda 표현식 (() -> {})
  • Stream API (함수형 프로그래밍 지원)
  • Optional (널 값 방지)
  • 인터페이스에서 default, static 메서드 지원
  • 새로운 날짜/시간 API (java.time 패키지)
  • Collector API (Collectors.toList() 등)
  • Parallel Streams (병렬 스트림)
  • 오라클이 자바 인수 후 출시한 첫번째 LTS 버전

예제 - Lambda 표현식

// 기존 방식 (익명 클래스)
Runnable r1 = new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello, Java!");
    }
};

// 람다 표현식 사용
Runnable r2 = () -> System.out.println("Hello, Java!");

r1.run();
r2.run();

🔹 Java 9 (2017)

주요 특징:

  • 모듈 시스템 (Project Jigsaw) (module-info.java)
  • 컬렉션 팩토리 메서드 (List.of(), Set.of(), Map.of())
  • try-with-resources 개선 (AutoCloseable 자동 적용)
  • Stream API 개선 (takeWhile, dropWhile 등 추가)
  • private 인터페이스 메서드 지원
  • JShell (Java REPL 도구)

예제 - List.of() 사용

List<String> names = List.of("Alice", "Bob", "Charlie");

🔹 Java 10 (2018)

주요 특징:

  • var 키워드 도입 (지역 변수 타입 추론)
  • G1 GC 성능 개선
  • Optional.orElseThrow() 추가

예제 - var 사용

var message = "Hello, Java 10";
System.out.println(message);

🔹 Java 11 (2018, LTS)

주요 특징:

  • var 키워드를 람다 매개변수에서도 사용 가능
  • String 메서드 추가 (isBlank(), lines(), repeat())
  • Files.writeString(), Files.readString() 추가
  • HttpClient 정식 지원 (java.net.http 패키지)
  • Java EE, CORBA 모듈 제거

예제 - String의 repeat() 메서드

String text = "Hello! ";
System.out.println(text.repeat(3)); // Hello! Hello! Hello! 

🔹 Java 12 ~ Java 16 (단기 지원)

주요 특징:

  • Java 12: switch 문 개선 (break 없이 사용 가능)
  • Java 13: 텍스트 블록 (""" """ - 여러 줄 문자열)
  • Java 14: record 타입 도입
  • Java 15: sealed class 도입 (클래스 확장 제한)
  • Java 16: Pattern Matching for instanceof (instanceof 개선)

예제 - Java 14 record 사용

public record Person(String name, int age) {}

Person p = new Person("Alice", 30);
System.out.println(p.name()); // Alice

🔹 Java 17 (2021, LTS)

주요 특징:

  • sealed class 정식 도입 (상속 제한 가능)
  • Pattern Matching for switch (switch 문에서 instanceof 대체 가능)
  • 강화된 가비지 컬렉터 (ZGC, G1 개선)
  • Foreign Function & Memory API (JNI 대체 실험 기능)
  • Security 개선 (Strong encapsulation of JDK internals)

예제 - sealed class 사용

sealed class Animal permits Dog, Cat {}

final class Dog extends Animal {}
final class Cat extends Animal {}

🔹 Java 21 (2023, LTS)

주요 특징:

  • Virtual Threads (가벼운 스레드, 고성능 동시성 지원)
  • Record Patterns (레코드 패턴 매칭 개선)
  • Unnamed Classes & Instance Main Methods (더 간결한 코드 가능)
  • Pattern Matching for switch 개선
  • Garbage Collection 최적화 (G1, ZGC 개선)

예제 - Virtual Threads (가벼운 스레드)

try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    executor.submit(() -> System.out.println("Hello from virtual thread!"));
}

🔹 Java 22 (2024 예정, 단기 지원)

  • Enhancements in Foreign Function API
  • Refined Virtual Threads
  • Performance optimizations

💡 LTS 버전 추천

실무에서는 Java 8, Java 11, Java 17, Java 21이 주로 사용됩니다.

  • 새로운 프로젝트: Java 17 or Java 21
  • 레거시 유지보수: Java 8 or Java 11


🔹Java 8 이전 버전 관련

"Java 8 이전 버전도 사용해봤는지?"

1. 레거시 코드 경험 여부 확인

Java 8 이전 버전에서 작성된 레거시 시스템이나 구형 애플리케이션을 다뤄본 경험이 있는지 확인하는 것. 많은 기업들이 여전히 Java 7이나 Java 6 같은 이전 버전에서 돌아가는 시스템을 운영하고 있기 때문에, 이전 버전의 Java를 다뤄본 경험이 있는지 확인하고 싶어할 가능성이 크다.

2. Java의 진화 과정에 대한 이해 확인

Java 8 이전 버전에서는 람다 표현식이나 Stream API와 같은 기능이 없었으므로, 기존의 Java 문법과 구조에 대한 이해도 중요한 요소이다. Java 8 이전의 익명 클래스기존의 for, Runnable 사용법 등을 잘 알고 있는지 확인하고 싶은 것일 수 있다.

3. 다양한 버전에서의 유연한 개발 능력

Java 8 이전 버전에서의 경험을 물어보는 이유는 다양한 환경에서 개발을 해본 경험을 갖추었는지 확인하려는 목적일 가능성이 크다. 최신 버전의 기능을 사용할 수 있지만, 구버전 코드와 호환되는 방식으로 작업할 수 있는 능력도 중요하기 때문이다.

4. 호환성과 유지보수 경험

대부분의 기업들이 구형 버전의 Java에서 새로운 기능을 추가하거나 유지보수하는 작업을 진행하고 있기 때문에, 구버전 Java를 사용한 경험이 있으면 그 부분에 대해 보다 효율적이고 신속한 대응이 가능할 것이라고 예상할 수 있다.


2. 자바 8에서 제공하는 Stream API

Java 8에서 Stream API를 통해 컬렉션을 함수형 스타일로 처리할 수 있습니다.

<대표적인 메서드>

  • filter(Predicate<T>): 조건에 맞는 요소 필터링
  • map(Function<T, R>): 요소 변환
  • collect(Collectors.toList()): 결과를 리스트로 변환
  • forEach(Consumer<T>): 요소 반복 처리
  • reduce(BinaryOperator<T>): 요소를 하나로 축약

메소드 활용 예제:

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> filteredNames = names.stream()
    .filter(name -> name.startsWith("A"))
    .collect(Collectors.toList());


//ArrayList의 요소를 변환할 때 - map();
//`map(Integer::parseInt)`를 사용하여 `String`을 `Integer`로 변환
List<String> numbers = Arrays.asList("1", "2", "3");
List<Integer> intNumbers = numbers.stream()
    .map(Integer::parseInt)
    .collect(Collectors.toList());

3. DTO와 불변 객체

1. DTO (데이터 전달 객체)

  • 기본 DTO (Getter/Setter 포함)

    • 데이터를 전달하기 위해 GetterSetter를 제공.
    public class UserDTO {
        private String name;
        private int age;
    
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
    
        public int getAge() { return age; }
        public void setAge(int age) { this.age = age; }
    }

2. 불변 객체 (Immutable Object)

  • 불변 객체 (Setter 없음)

    • Setter를 제공하지 않고, 생성자를 통해 초기화 후 변경 불가.
    public class ImmutableUserDTO {
        private final String name;
        private final int age;
    
        public ImmutableUserDTO(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() { return name; }
        public int getAge() { return age; }
    }
  • Java 14+ record 사용

    • record자동으로 불변 객체를 만들어 줌.
    public record UserDTO(String name, int age) {}

✅ 불변 객체의 특징

  • final 사용

    • 모든 필드를 final로 선언하여 불변성 보장.
    • 생성자에서만 초기화 가능하고, Setter는 제공되지 않음.
    public final class ImmutablePerson {
        private final String name;
        private final int age;
    
        public ImmutablePerson(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() { return name; }
        public int getAge() { return age; }
    }

3. Setter vs 생성자

  • Setter 사용 (Mutable 객체)

    • 값을 변경할 수 있는 객체.
    public class User {
        private String name;
    
        public void setName(String name) {
            this.name = name;
        }
    }
  • 생성자 사용 (Immutable 객체)

    • final을 사용하여 불변 객체를 구현.
    public class User {
        private final String name;
    
        public User(String name) {
            this.name = name;
        }
    
        public String getName() { return name; }
    }

4. final 활용

  • final을 사용하여 불변 객체상수 값을 안전하게 관리할 수 있음.
    • DTO메시지 객체, 설정값 저장 객체 등에서 활용.
    • static final을 사용하여 상수 값 정의.

불변 객체에서 final 활용

불변 객체에서 final은 객체의 상태가 한 번 설정되면 변경되지 않도록 보장합니다.
final을 사용하여 객체의 필드를 초기화 후 변경하지 않도록 하는 방식입니다.

  • 필드에 final을 사용하면 생성자에서만 초기화가 가능하고, 이후에는 변경할 수 없습니다.
public final class ImmutablePerson {
    private final String name;
    private final int age;

    public ImmutablePerson(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() { return name; }
    public int getAge() { return age; }
}

일반 객체에서 final 활용

일반 객체에서 final을 사용하면 값을 한 번만 할당할 수 있게 만들 수 있습니다.
이는 불변성을 유지하려는 목적에서 사용될 수 있지만, 객체 자체를 불변 객체로 만드는 것은 아님.

public class FinalExample {
    private final String name;

    public FinalExample(String name) {
        this.name = name;  // final 필드는 한 번만 할당
    }

    public String getName() { return name; }
}

이 경우, 객체는 여전히 변경 가능하지만, name 필드는 변경할 수 없도록 final을 사용하여 설정합니다.

[ final을 사용한 상수 정의 ]

final을 사용하여 상수 값을 정의할 때도 사용됩니다. 이 경우 값은 한 번만 할당되고, 이후 변경할 수 없습니다.

public class Constants {
    public static final String APP_NAME = "MyApplication"; // 상수 정의
}

결론

  • 불변 객체(Immutable Object)에서는 final을 사용하여 객체의 상태를 변경 불가능하게 보장합니다.
  • 일반 객체에서도 final을 사용하여 객체의 특정 속성이 변경되지 않도록 할 수 있으며, 이는 불변성을 보장하는 방식의 일환일 수 있습니다.
  • final값을 한 번만 할당할 수 있게 하므로, 값이 변경되지 않도록 보장하는 데 유용합니다.

핵심 요약

  • DTO 객체: 데이터를 전달하기 위해 Getter/Setter를 사용.
  • 불변 객체: final 필드, Setter 없음, 생성자를 통해 초기화 후 변경 불가.
  • Java 14+ record: 간결한 불변 객체 표현.
  • final: 불변 객체 보장, 상수 값 정의, 안전한 초기화.

0개의 댓글