ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [23.12.28] 2024년 자바 개발자를 위한 면접 질문 - 1
    블로그 번역 2023. 12. 28. 11:07
    반응형

     

     

    이번 주제는 자바 개발자 인터뷰 관련 질문 및 답변에 관한 주제입니다.

    소개글

    요즘 전형적인 자바 개발자 면접 항목은 OOP 및 자바 중요 개념부터 시작한다.

    그리고 Spring, Hibernate, Spring Boot, MSA 등 어려운 주제로 확장되어간다.

    그 후 2차 기술인 AWS, GCP, Azure, SQL, Kafka 등을 평가한다.

    물론 K8S, Docker 등 Devops 질문도 마찬가지이다.

    그 중에서도 자바에 관련한 질문을 위주로 살펴보자.

     

    1.  자바 직렬화 관련 단어인 "transient"의 중요성에 대해 설명하세요

    자바에서 transient를 붙인 필드는 객체 직렬화 시 변수는 직렬화 하지 않겠다는 의미이다.

    transient는 민감하거나 임시 저장 목적으로 사용되어지는 데이터를 다룰 때 유용하다.

    public class Person implements Serializable {
        transient int age = 10;
        String name = "jihun";
    }
    
    ObjectOutputStream stream = new ObjectOutputStream(new FileOutputStream("serializedObject.txt"));
    Person person = new Person();
    stream.writeObject(person);
    

     

    2. "equals()" 와 "==" 차이점을 설명하세요

     

    두 가지 모두 비교를 위해 사용되는 연산자 및 메서드이다.

    "==" 연산자는 같은 메모리에 위치해있는지 객체 참조 값을 비교한다.

    반대로 "equals()" 메서드는 클래스에 오버라이드하여 클래스 내부 내용을 비교하기 위해 사용된다.

    이 때 "hashCode()"도 오버라이드 해주어야한다. 왜냐하면 아래와 같은 상황이 발생할 수 있기 때문이다.

    @Override
    public boolean equals(Object o) {
        if(o == null) {
            return false;
        }
        if (o == this) {
            return true;
        }
        if (getClass() != o.getClass()) {
            return false;
        }
    
        Animal a = (Animal) o;
        return (this.getName().equals(a.getName()));
    }
    
    Animal a1 = new Animal("lion");
    Animal a2 = new Animal("lion");
    
    System.out.println(a1.equals(a2)); // true
    

     

    3. 자바에서 옵저버 디자인 패턴을 설명하세요

     

    옵저버 패턴이란 어떤 객체 상태가 변경되는 경우 연관 객체들에게 알림을 보내는 디자인 패턴이다.

    예시로 1명의 선생님과 3명의 학생들이 한 반이고 공지사항을 학생들이 받는 상황을 생각해보자.

    public interface Teacher {
        void subscribe(Student s);
        void unsubscribe(Student s);
        void notifyStudent(String msg);
    }
    
    public interface Student {
        void receiveMsg(String msg);
    }
    
    public class TeacherA implements Teacher {
    
        private List<Student> students = new ArrayList<>();
    
        @Override
        public void subscribe(Student s) {
            this.students.add(s);
        }
    
        @Override
        public void unsubscribe(Student s) {
            this.students.remove(s);
        }
    
        @Override
        public void notifyStudent(String msg) {
            students.forEach(student -> student.receiveMsg(msg));
        }
    }
    
    public class StudentA implements Student {
        @Override
        public void receiveMsg(String msg) {
            System.out.println("StudentA receive Message : " + msg);
        }
    }
    
    @Test
    void observePattern() {
        Teacher teacherA = new TeacherA();
        Student studentA = new StudentA();
        Student studentB = new StudentB();
        Student studentC = new StudentC();
    
        teacherA.subscribe(studentA);
        teacherA.subscribe(studentB);
        teacherA.subscribe(studentC);
    
        teacherA.notifyStudent("안녕하세요~");
    }
    

     

    학생들(Observer)이 선생님(Observable)을 구독하면서 상태 변경 시 옵저버들도 인식할 수 있도록 하는 패턴이다.

    주로 분산 이벤트 시스템에 사용되어지는 패턴이다.

     

    4. 자바 예외 처리 방법인 "try-with-resources" 사용에 대해 설명하세요

    자바 7에서 소개되어진 "try-with-resources" 구문은 자동으로 File 또는 Socket 관련 IO를 자동으로 닫을 수 있게 해주는 기능이다.

    이전 "try-catch-finally" 보다 close 메서드 호출 제거 및 가독성 향상이 차별점이다.

    try(BufferedReader br = new BufferedReader(new FileReader("hello.txt"))) {
        // TODO
    } catch (IOException e) {
        e.printStackTrace();
    }

     

     

    5. 함수형 인터페이스는 무엇이고 어떻게 이것을 활용할지 설명하세요

    함수형 인터페이스는 추상화 된 한 가지 메서드만 포함하고 default 혹은 static 메서드를 여러 개 가질 수 있는 인터페이스를 말한다.

    람다 표현식과 함께 많은 인기를 얻었다.

    자바의 기본 제공해주는 인터페이스가 있다.

    그 외 커스텀 제작 인터페이스는 잘 사용하지 않는다. 왜냐하면 왠만한 인터페이스는 다 구현되어져 있다.

    아래는 Consumer 예시이지만 Supplier, Function, Operator, Predicate... 등 다양한 인터페이스를 찾을 수 있다.

    Consumer 객체 T를 받아 소비한다. void accept(T t)
    BiConsumer<T, U> 객체 T와 U 두가지를 받아 소비한다. void accept(T t, U u)
    DoubleConsumer double 값을 받아 소비한다. void accept(double value)
    IntConsumer int 값을 받아 소비한다. void accept(int value)
    LongConsumer long 값을 받아 소비한다. void accept(long value)
    ObjDoubleConsumer 객체 T와 double 을 받아 소비한다. void accept(T t, double value)
    ObjIntConsumer 객체 T와 int 를 받아 소비한다. void accept(T t, int value)
    ObjLongConsumer 객체 T와 long 을 받아 소비한다. void accept(T t, long value)

     

     

    6. 자바에서 "ClassLoader"의 사용과 동적 클래스 로딩에 대해서 설명하세요

     

    클래스 로더는 자바 런타임 환경에서 클래스 동적 로딩을 책임지고 있는 컴포넌트이다.

    로딩 -> 링크 -> 초기화 과정을 거쳐서 클래스들이 올라간다.

    그리고 2가지 동적 로딩이 존재한다. "런타임 동적 로딩" 과 "로드타임 동적 로딩" 이다.

     

    런타임 동적 로딩은 객체가 참조하는 순간 로딩하는 방식이다. 즉 코드를 실행할 때 클래스를 로딩한다.

    로드타임 동적 로딩은 하나의 클래스 로딩 시 사용 클래스가 모두 로딩되는 것을 말한다.

     

     

    7. 자바 Stream API 의 장단점을 설명하세요

     

    자바 8부터 사용되어진 스트림은 가독성 및 Immutable한 코드를 구성하는데 많은 도움을 준다.

    그러나 기존 방식보다 코드를 짜기 어려우며 메모리 관점에서 성능을 더 악화할 수 있다.

    선택적으로 사용해야한다.

     

     

    8. 자바 멀티 스레딩 개념 중 "volatile" 단어에 대해서 설명하세요 

     

    Volatile 변수란 CPU Cache가 아닌 메인 메모리에 저장하여 Thread간 변수 불일치를 확실하게 없애고자 만들어진 것이다.

    Volatile 변수를 써야하는 경우는 멀티 스레드 환경에서 쓰레드 1이 Read & Write 그리고 쓰레드 2는 Read하는 경우 Sync를 맞추기 위해서 사용할 수 있다. 메인 메모리를 사용하기 때문에 남발하는 것은 옳은 방법이 아니다.

     

     

     

    반응형

    댓글

Designed by Tistory.