후기


이전 기출들과는 달리 개념 문제가 쉬웠고, 코딩 문제가 까다로웠다. SQL 문제는 별거 없었다.

 

C언어의 static 변수의 함수 내 선언과 초기화, 구조체 + 링크드 리스트 + 이중포인터는 신선했다.

 

시나공에서 제공하는 2023년도 3회 기출부터 2020년도 1회까지 하루에 전부 풀고

하루는 개념을 한번 쭉 훑어봤다. 제대로 공부한 기간은 2일정도?한 듯하다.

 

평소에 CS를 깊이가 깊진 않지만 넓게 많이 알았던 것이 도움이 되었다.

 

애초에 VPN, 스머핑 등이 답이었던 문제는 컴퓨터 보안 수업을 듣지 않았다면 몰랐을 것이다.

 

코드 문제는 C++, Python, Java를 주로 쓰다보니 기출에 나왔던 것만 풀고 들어갔다.

 

그래서 Java 문제를 틀렸던 걸 수도 있다.

 

12월 11일에 합/불 결과 발표가 나지만, 최대한 틀려도 80점은 넘을 것 같아서 넉넉하게 합격할 듯하다.

 

 

 

2024 정보처리기사 실기 3회 오답노트 (가답안 기준)


1) 다음 코드를 보고 출력을 쓰시오. (제네릭)

public class Test {
public static void main(String[] args) {
new Container<>(0).print();
}
public static class Container<T> {
T value;
public Container(T t) {
value = t;
}
public void print() {
new Printer().print(value);
}
}
}
class Printer {
void print(Integer a) {
System.out.print("A" + a);
}
void print(Object a) {
System.out.print("B" + a);
}
void print(Number a) {
System.out.print("C" + a);
}
}

 

new Container<>(0).print(); 에서 0int 리터럴

  • 하지만, 자바에서는 자동 박싱(Auto-boxing)으로 인해 0Integer 객체로 변환된다.
  • 그래서 valueInteger 타입이다.

→ 여기까지 내가 생각했던 부분이다. 따라서 당연히 출력 결과는 A0 이라고 생각해서 적어 냈지만, 오답이었다.

 

 

 

중요한 부분) 제네릭 타입의 타입 소거(Type Erasure)

자바의 제네릭은 컴파일 시에만 타입을 검사하며, 런타임에서는 타입 소거(Type Erasure)가 발생한다.

즉, T 타입 정보는 컴파일 시에만 존재하고, 런타임에서는 모든 제네릭 타입이 Object로 변환된다.

  • Container<T>의 제네릭 타입 T는 컴파일 시에만 유효하고, 런타임에서는 TObject로 변환
  • 따라서 valueInteger 타입이지만, 런타임에서는 Object로 처리된다.

메서드 선택 과정

  • new Printer().print(value)는 결국 Object 타입으로 인식된 value를 넘긴다.
  • Printer 클래스의 print 메서드 중에서 가장 적합한 Object 타입을 받는 메서드print(Object a)가 호출된다.
    • 비록 value는 원래 Integer 타입이지만, 제네릭 타입 소거로 인해 Object로 변환되었으므로, print(Object a)가 호출되는 것이다.

따라서 B0 이 답이다.

 

 

 

 

2) 다음 코드를 보고 출력을 쓰시오. (상속)

class B {
int x = 3;
int getX() {
return x * 2;
}
}
class A extends B {
int x = 7;
int getX() {
return x * 3;
}
public class Test {
public static void main(String[] args) {
B b1 = new A();
A b2 = new A();
System.out.print(b1.getX() + b1.x + b2.getX() + b2.x);
}
}

 

b1.getX()는 21(메서드 오버라이딩), b1.x는 7, b2.getX()는 21, b2.x는 7을 반환한다고 생각하여 56을 써서 제출했다.

 

 

하지만 오답.

 

 

객체 b1b2 선언 및 초기화

  1. B b1 = new A();
    • b1B 타입의 참조 변수를 통해 A 객체를 참조한다. 부모 클래스 타입의 변수로 자식 클래스의 인스턴스를 참조하는 상황이다.
    • 필드는 참조 타입(B)을 기준으로 접근되지만, 메서드는 객체(A)를 기준으로 동작한다.
      • 이 원리를 이해하는 것이 중요하다.
  2. A b2 = new A();
    • b2A 타입의 참조 변수를 통해 A 객체를 참조한다. 이 경우는 참조 타입과 객체가 모두 A라서 딱히 생각할 게 없다.
  3. b1.getX():
    • b1B 타입의 변수로 A 객체를 참조하고 있습니다.
    • 메서드는 동적 바인딩(dynamic binding)으로 인해 실제 객체인 AgetX() 메서드가 호출된다.
    • 따라서 AgetX()가 호출되고, Ax는 7이므로, 결과는 7 * 3 = 21
  4. b1.x:
    • b1B 타입이므로, 필드 x는 정적 바인딩(static binding)으로 처리된다. 즉, B 클래스의 x 필드가 사용되며, Bx 값인 3이 사용된다.

따라서 정답은 21 + 3 + 21 + 7 = 52

 

 

 

런타임 시 자바가 제네릭을 어떻게 다루는 지와 필드는 정적 바인딩이 된다는 사실을 간과하고 있었던 것이다.
내가 알던 자바는 반쪽짜리 자바였다.
반성합니다.

 

 

조원준입니다