[말랑 퀴즈] 26/09/25 문제

게시:     수정

카테고리:

태그:

제 말랑말랑 퀴즈 생성기는 이곳에서 확인하실 수 있습니다.

말랑말랑 퀴즈 📝

날짜: 2026-09-25 문제 수: 6문제


Q1. 🔴 어려움

템플릿 메타프로그래밍(TMP)에 대해 답하시오.

(1) TMP란 무엇인지 정의하고, 기존에 런타임에서 하던 작업을 컴파일 타임으로 옮겼을 때 얻는 대표적인 이점 두 가지를 쓰시오.

(2) TMP에는 반복(iteration) 의미의 루프가 없다. 대신 무엇을 사용해 반복의 효과를 내는가? 아래 팩토리얼 코드에서 그 메커니즘이 어떻게 나타나는지 설명하시오.

template<unsigned n>
struct Factorial {
    enum { value = n * Factorial<n-1>::value };
};

// 템플릿 특수화
template<>
struct Factorial<0> {
    enum { value = 1 };
};

(3) BigMatrix result = m1 * m2 * m3 * m4 * m5;처럼 큰 정방행렬 다섯 개를 operator*로 곱하면 어떤 성능 문제가 생기는가? TMP를 응용한 어떤 기법으로 이 문제를 해결하는가?

출처: game_dev/cpp/chapter7/2025-11-03-cpp_7_48.md

📝 내 풀이:

(1) 1. 런타임 시점에 계산되던 작업이 컴파일 시점으로 옮겨가 계산할 필요가 없어진다.

  1. 에러가 컴파일 시점에 발생되어 파악하기 쉬워진다.

(2) 템플릿 특수화와 enum을 사용한다.
종료 시점이 템플릿 특수화 0, 구조체 안의 enum 변수를 통해 값을 저장한다.

(3) 한번의 연산마다 생성과 소멸이 발생하게 된다.
중첩 템플릿 기법이라 했던 것 같다. 템플릿을 말 그대로 중첩시켜 연산하는 방식으로 해결한다.


Q2. 🟡 보통

빈칸을 채우시오.

컴파일러가 자동으로 만들어주는 복사 생성자·복사 대입 연산자를 막고 싶을 때, 그 멤버 함수를 직접 ① ___(으)로 선언하고 구현은 비워두면 외부에서 복사를 시도해도 막을 수 있다. 다만 이 경우 에러가 컴파일이 아니라 ② ___ 시점에 나서 아쉽다. 이 에러를 컴파일 시점으로 앞당기려면, Uncopyable처럼 복사 연산을 막아 둔 클래스를 ③ ___(으)로 상속하면 된다. Uncopyable은 데이터 멤버가 전혀 없어서 ④ ___(이)라는 최적화 기법이 적용될 여지가 있다.

출처: game_dev/cpp/chapter2/2025-04-23-cpp_2_6.md

📝 내 답: 가상 함수, 런타임, 부모, EBO


Q3. 🟡 보통

클래스 기반 프로그래밍과 템플릿 기반 프로그래밍의 인터페이스·다형성 차이에 대한 설명으로 가장 올바른 것은?

  • A. 클래스 기반 설계에서는 인터페이스가 함수 시그너처로 명확히 드러나는 명시적 인터페이스이고, 다형성은 가상 함수를 통해 런타임에 결정된다. 템플릿 기반 설계에서는 인터페이스가 사용 패턴(유효 표현식)으로 추론되는 암시적 인터페이스이고, 다형성은 템플릿 인스턴스화를 통해 컴파일 타임에 결정된다. 두 방식 모두 인터페이스 위반은 컴파일 타임에 걸러진다는 공통점이 있다.
  • B. 템플릿 매개변수 T가 만족해야 하는 조건은 반드시 operator>와 operator!=를 T 자신이 직접 정의하는 것이며, 타입 변환을 통해 간접적으로 만족시키는 것은 허용되지 않는다.
  • C. 암시적 인터페이스는 런타임에 검증되므로, 템플릿이 요구하는 함수가 없는 타입을 넘겨도 일단 컴파일은 되고 실행 중에 에러가 난다.
  • D. 클래스 기반의 명시적 인터페이스는 유연성이 높아 다양한 타입에 재사용하기 쉽고, 템플릿 기반의 암시적 인터페이스는 특정 타입에 고정되어 있어 유연성이 낮다.

출처: game_dev/cpp/chapter7/2025-10-28-cpp_7_41.md

📝 내 선택: D

A: 마지막 문단이 틀렸다. 클래스는 런타임, 템플릿은 컴파일
B: 이거는 잘 모르겠다. C: 암시적 인터페이스는 컴파일 타임. 런타임 시점 에러.


Q4. 🟢 쉬움

다음 명제가 참(O)인지 거짓(X)인지 판단하라.

분산 처리는 확장성뿐 아니라 안정성에도 도움이 된다. 수직 분산 구조에서 서버 하나가 멈추면 그 서버가 담당하던 기능만 못 쓰게 되고 나머지 기능은 정상 동작하지만, 수평 분산 구조에서는 서버 하나가 멈추면 전체 시스템이 완전히 마비되어 모든 플레이어의 접속이 끊긴다.

출처: server/game_server/9/2026-03-22-game_server_9_11.md

📝 내 답: X. 마지막 문단에서 틀렸다. 수평 분산 구조에선 서버 하나만 멈추고, 전체 시스템이 마비되진 않는다.


Q5. 🟡 보통

게임 서버의 데이터 저장 방식(RDBMS vs NoSQL)에 대한 설명으로 가장 올바른 것은?

  • A. RDBMS는 필드 구조를 바꿀 때 레코드 개수와 무관하게 즉시 적용되며, 기존 레코드가 1억 개여도 그 필드가 null을 허용하면 서버가 멈추지 않는다.
  • B. RDBMS의 레코드는 리스트·배열 구조의 데이터이고, 필드 구조를 바꾸려면 기존 레코드 전체에 손을 대야 해서(외래 키를 쓰더라도 마찬가지일 수 있다) 점점 복잡해진다. 예를 들어 레코드 1억 개에 필드를 하나 추가하면, null을 허용하더라도 장시간 서버가 멈출 수 있다. 반면 NoSQL은 레코드가 트리나 구조체 형태를 가질 수 있어 이런 제약에서 비교적 자유롭다.
  • C. NoSQL은 레코드가 반드시 리스트나 배열 구조를 가져야 하며, 트리 구조의 데이터는 저장할 수 없다.
  • D. 외래 키를 사용하면 RDBMS에서 필드 구조를 바꾸는 일이 전혀 복잡해지지 않는다.

출처: server/game_server/8/2026-03-08-game_server_8_1.md

📝 내 선택: B

A: 즉시 적용되지 않고 오래 걸리며, 1억개 필드가 null을 허용한다 해도 서버가 멈춘다.
C: NoSQL은 트리 구조나 구조체 형태이다.
D: 외래 키를 사용하더라도 연관된 DB들이 있으므로 복잡해진다.


Q6. 🔴 어려움 · 📌 오답노트 (3번째 복습)

DB 수평 확장을 위해 유저 DB를 샤드 10개로 나눠 운영하는 상황이다.

(1) 클라이언트가 ID/PW로 로그인할 때, 어느 샤드에 질의를 보낼지는 어떻게 결정되는가? 이때 사용되는 키를 무엇이라 부르는가?

(2) 샤드를 10개에서 11개로 늘릴 때, 일반적인 해시 테이블 방식이라면 왜 대부분의 레코드를 리해시해야 하는가? 반면 일관된 해시 알고리즘을 쓰면 샤드 1개를 증설할 때 재배치가 필요한 샤드가 몇 개로 줄어드는가? 그리고 이 구조를 왜 “링형”이라고 부르는가?

(3) 매핑 DB 방식에서는 샤드를 추가할 때 레코드 이동이 필요 없다고 한다. 그 이유는 무엇인가? 그런데 매핑 DB 방식에는 일관된 해시에는 없는 새로운 위험이 하나 생긴다 — 그것은 무엇이며, 어떻게 완화하는가?

(4) 일관된 해시와 매핑 DB 둘 다, 샤드가 크게 늘어나거나 줄어드는 대규모 변경 상황에서는 한계가 있다. 일관된 해시의 한계와 매핑 DB의 한계는 각각 무엇인가? 같은 이유인지 다른 이유인지 구분해서 설명하시오.

출처: server/game_server/9/2026-03-26-game_server_10_2.md 오답노트: wn-1da60a18 · 2026-09-09 최초 오답 · 이번이 3번째 복습

📝 내 풀이:

(1) 샤드 키를 해시 함수에 전달해 어느 샤드에 보낼지 결정한다. 샤드 키

(2) 해시 함수가 샤드 전체에 대해 배정되어 있기 때문이다.
일관된 해시 알고리즘을 쓰면 1개로 줄어든다.
미리 N만큼의 범위를 배정해두고, 넓은 해시가 0->N->0으로 연결되는 구조를 갖고 있기 떄문이다.

(3) 매핑 DB에는 키와 값만 연결해주면 되기 때문이다.
매핑 DB가 죽어버리는 SPOF가 발생할 수 있기 때문이며, 복제/분산하여 완화한다.

(4) 샤드가 크게 늘어나면 일관된 해시 함수에서 결국 재배치를 여러번하게 되기 때문이다.
매핑 DB는 DB 크기가 증가하며, 병목이 발생한다.


MallangQuiz 카테고리 내 다른 글 보러가기

댓글남기기