프로그래밍Java 개발자

자바에서 객체 직렬화가 어떻게 이루어지는지, 어떤 종류의 객체를 직렬화할 수 있는지, 직렬화 작업에서 발생할 수 있는 함정은 무엇인지에 대해 설명해 주세요.

Hintsage AI 어시스턴트로 면접 통과

답변.

직렬화는 객체를 바이트 스트림으로 변환하여 이후 저장하거나 전송할 수 있게 하는 메커니즘입니다. 자바에서는 1.1 버전부터 플랫폼과 함께 직렬화가 API의 일부로 도입되었습니다. 이는 분산 애플리케이션의 인기로 인해 발생한 필요로, JVM 간에 복잡한 객체 그래프를 전송하고 상태를 저장할 수 있게 하여 개발자에게 투명한 과정을 제공합니다.

직렬화 문제점은 데이터의 무결성을 철저하게 유지해야 하고, 클래스 버전 관리를 지원하며, 복잡한 구조(예: 순환 링크가 있는 그래프)를 올바르게 처리해야 한다는 것입니다. 모든 객체가 직렬화 가능한 것은 아닙니다(예: 스트림, 소켓, OS 자원) 및 직렬화는 보안에 주의가 필요합니다.

해결책Serializable 인터페이스를 통해 구현됩니다:

import java.io.*; class Person implements Serializable { private static final long serialVersionUID = 1L; private String name; private transient int age; // 직렬화되지 않음 public Person(String name, int age) { this.name = name; this.age = age; } }

ObjectOutputStreamObjectInputStream을 사용하여 객체를 파일에 쓰고 복원할 수 있습니다:

Person p = new Person("Alice", 30); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser")); oos.writeObject(p); // 직렬화 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser")); Person restored = (Person) ois.readObject();

주요 특징:

  • 직렬화를 위해서는 클래스가 Serializable 인터페이스를 구현해야 합니다.
  • transient 수정자가 있는 필드는 직렬화되지 않습니다.
  • 직렬화는 순환 링크를 포함한 객체 그래프의 저장 및 복원을 지원합니다.

함정 질문들.

직렬화가 불가능한 필드가 있는 객체를 직렬화할 수 있나요?

답변: 필드가 transient로 표시되면 전혀 직렬화되지 않으며, 이 과정에서 예외가 발생하지 않습니다. 그러나 풀 필드가 직렬화 불가능하고 transient가 아닐 경우 NotSerializableException 예외가 발생합니다.

정적 필드는 Serializable을 구현하는 클래스의 경우 직렬화 가능합니까?

답변: 아닙니다, 정적 필드는 클래스에 속하고, 인스턴스가 아니므로 직렬화되지 않습니다. 오직 인스턴스의 상태만 저장됩니다.

직렬화 후 클래스 구조가 변경되면 (예: 필드 추가 또는 삭제), 무슨 일이 발생하나요?

답변: serialVersionUID를 지정하고 구조가 비호환적으로 변경되면, 역직렬화 시 InvalidClassException이 발생합니다. 호환성을 보장하기 위해 직렬화 힌트와 수동 serialVersionUID 관리를 사용합니다.

일반적인 오류 및 안티패턴

  • serialVersionUID 미선언으로 인해 클래스 버전의 비호환성으로 오류가 발생
  • 비종결 자원이 포함된 객체를 직렬화하려고 하는 시도 (예: 스트림)
  • sensitive data 유출을 초래할 수 있는 transient 수정자 무시

실제 사례

부정적인 케이스

엔지니어들이 serialVersionUID를 추가하지 않고 OS 자원을 참조하는 필드를 transient로 선언하지 않은 객체를 직렬화하기로 했습니다. 애플리케이션과 클래스 업데이트 후 InvalidClassException이 발생하며 객체의 무결성이 상실되었고, 역직렬화가 불가능해졌습니다.

장점:

  • 상태 저장의 신속한 구현

단점:

  • 업데이트 시 데이터 손실
  • 역직렬화 시 크래시
  • 자원 누수 가능성

긍정적인 케이스

직렬화를 위해 명시적인 serialVersionUID를 가진 이식 가능한 클래스를 구현하였고, 모든 자원 필드는 transient로 선언되며, 수동 직렬화가 주요 지점을 제어합니다.

장점:

  • 버전 간의 유연한 마이그레이션
  • 변경 후 올바른 작동

단점:

  • 더 많은 규율과 추가 테스트 필요