[말랑 퀴즈] 26/10/15 해답

게시:     수정

카테고리:

태그:

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

말랑말랑 퀴즈 — 해답지 ✅

날짜: 2026-10-15 문제 수: 6문제 총점: 38.5/60 (64점) 🟡 복습이 필요해요

📊 채점 결과

문항 유형 난이도 결과 점수
Q1 OX 🟢 쉬움 ❌ 오답 0 / 10
Q2 객관식 🟡 보통 ⭕ 정답 10 / 10
Q3 빈칸 채우기 🟡 보통 ❌ 오답 0 / 10
Q4 서술형 🔴 어려움 🔺 부분 정답 8.5 / 10
Q5 객관식 🟢 쉬움 ⭕ 정답 10 / 10
Q6 📌 OX 🟡 보통 ⭕ 정답 10 / 10
합계       38.5 / 60

총평

객관식 두 문제(Q2, Q5)는 오답 보기까지 근거를 정확히 짚으셨고, 오답노트 복습 문제(Q6)도 “코드 최적화 → 분산” 순서를 정확히 기억하셨습니다. Q4 RAII 문제는 (1), (2)가 만점이고 어려운 문제인데도 8.5점으로 잘 푸셨습니다. 반면 Q1은 메시지 메타데이터가 하위 호환성에는 오히려 유리하다는 점을 놓쳤고, Q3은 프라우드넷 RMI 용어(Proxy, Stub, PIDL, StubFunctional)를 전혀 기억하지 못했습니다.


Q1. 🟢 쉬움 — ❌ 0/10

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

게임 서버와 클라이언트가 주고받는 메시지에 “Action: BuyItem”, “Type: Sword”처럼 메타데이터를 붙이면 데이터 통신량이 늘고 해킹에 취약해진다는 단점이 있고, 서버와 클라이언트의 버전이 서로 다를 때의 하위 호환성 측면에서도 불리해진다.

📝 내 답: O. 이를 해결하기 위해 암호화해서 전송했던것같다.

정답: X

해설:

메타데이터의 단점은 데이터 통신량이 많아지고 해킹에 취약해진다는 점이 맞다. 그러나 하위 호환성 측면에서는 오히려 유리하다. 서버는 버전 2, 클라이언트는 버전 1·2가 공존하는 경우에도, 일부 내용(예: 개수 값)이 없으면 서버가 상황에 맞춰 작동을 다르게 구현(개수를 1로 가정)할 수 있기 때문이다.

🔍 피드백: 명제의 앞부분(통신량 증가, 해킹 취약)은 맞지만, 마지막의 “하위 호환성에서도 불리하다”가 틀려서 전체가 거짓입니다. 메타데이터가 있으면 필드가 빠진 구버전 메시지도 서버가 상황에 맞춰 처리할 수 있어 하위 호환성에는 유리합니다. “암호화로 해결했던 것 같다”는 해킹 취약 문제에 대한 대응이라 이 명제의 거짓 부분과는 관련이 없어, 판단(7점)과 근거(3점) 모두 점수를 드리지 못했습니다.

출처: server/game_server/2/2025-12-09-game_server_2_8.md


Q2. 🟡 보통 — ⭕ 10/10

문제: 데이터베이스 샤드를 10개에서 11개로 늘리면 샤드 키를 해시한 값으로 샤드를 정하던 기존 방식에서는 리해시(기존 레코드의 재배치)가 발생한다. 이 문제를 피하기 위해 입력(키) → 샤드 인덱스 정보를 가진 DB를 따로 두는 매핑 DB 방식에 대한 설명으로 가장 올바른 것은?

  • A. 샤드를 추가할 때 기존 레코드를 이동하지 않고, 새 샤드를 채우기만 하면 된다.
  • B. 매핑 DB는 모든 요청이 거치는 곳이지만, 과부하가 걸리더라도 단일 실패 지점(SPOF)이 되지는 않는다.
  • C. 샤드를 제거할 때도 매핑 DB와 유저 DB 모두 아무 변경이 필요 없다.
  • D. 인증 서버는 ID를 해시 함수에 넣어 직접 샤드 인덱스를 계산하므로, 매핑 DB에는 질의하지 않는다.

📝 내 선택: A

정답: A

해설:

매핑 DB 방식에서 샤드를 추가할 때는 레코드 이동 없이 채우기만 하면 된다.

  • B: 매핑 DB에 과부하가 걸리면 의미가 없고, 단일 실패 지점(SPOF)이 된다. 그래서 매핑 DB도 레코드를 여러 샤드에 나누어 확장성을 추가한다.
  • C: 샤드 제거 시에는 매핑 DB에서 레코드를 이동하고 유저 DB에서 바뀐 위치를 반영해야 한다.
  • D: ID를 해시 함수에 넣어 샤드 인덱스를 얻는 것은 기존 해시 방식이고, 매핑 DB 방식에서는 인증 서버가 매핑 DB에 질의해 DB 인덱스(샤드 넘버)를 얻는다.

🔍 피드백: A를 정확히 골랐고, B(SPOF라서 매핑 DB도 분산), C(샤드 제거 시 매핑 DB·유저 DB 갱신), D(인증 서버 → 매핑 DB → 샤드 순서) 근거가 모두 해답과 일치합니다.

출처: server/game_server/9/2026-03-26-game_server_10_2.md


Q3. 🟡 보통 — ❌ 0/10

문제: 빈칸을 채우시오.

프라우드넷의 RMI(원격 메소드 호출)에 대한 설명이다.

  • RMI를 호출하는 쪽에서 함수 호출을 대신 해 주는 송신 측 코드(클래스)를 ① ___(이)라고 한다. (영문 이름)
  • RMI를 호출받는 쪽에서 메시지를 받아 해당 함수를 호출해 주는 수신 측 코드(클래스)를 ② ___(이)라고 한다. (영문 이름)
  • RMI 함수는 확장자가 ③ ___인 파일에서 선언하며, 이 파일을 컴파일하면 송수신 코드 클래스가 자동 생성된다. (영문 대문자 네 글자)
  • 수신 측 코드를 상속해 클래스를 만드는 대신, 함수나 람다식을 직접 넣어서 쓸 수 있도록 제공되는 클래스는 CalcC2S:: 뒤에 ④ ___를 붙여 쓴다. (영문 클래스 이름, ②로 시작함)

📝 내 답: RMIServer, RMIClient, ?, RMIClient_Impl(모름)

정답:

① Proxy ② Stub ③ PIDL ④ StubFunctional

해설:

함수 호출을 대신해 준다는 의미로 송신 코드를 proxy, 함수를 호출해 주는 기반이라는 의미로 수신 코드를 stub이라고 한다. RMI 함수는 PIDL 파일에서 선언하고 컴파일해 Proxy/Stub 클래스를 생성한다. StubFunctional은 함수나 람다식을 직접 넣어 쓸 수 있는 형태다.

🔍 피드백: 네 칸 모두 점수를 드리지 못했습니다. ①②는 “함수 호출을 대신 해 주는 쪽 = Proxy(대리자)”, “함수를 호출해 주는 기반 = Stub“으로 외우면 됩니다. ③은 .PIDL 파일(ProudNet Interface Definition Language)이고, ④는 ②로 시작한다는 힌트대로 Stub + Functional, 즉 StubFunctional입니다.

출처: server/game_server/6/2026-02-25-game_server_6_6.md


Q4. 🔴 어려움 — 🔺 8.5/10

문제: C++ RAII 클래스가 관리하는 자원을 외부에 노출하는 방법에 대해 답하시오.

shared_ptr<Investment> pInv(createInvestment());
int daysHeld(const Investment *pi);

int days = daysHeld(pInv);   // 컴파일 에러

(1) 위 코드가 컴파일 에러가 나는 이유를 쓰시오. 그리고 올바르게 호출하려면 어떻게 써야 하며, 이처럼 호출하는 방식의 변환을 무엇이라 하는가?

class Font {
public:
	explicit Font(FontHandle fh) : f(fh) {}
	~Font() { releaseFont(f); }

	FontHandle get() const { return f; }
	operator FontHandle() const { return f; }

private:
	FontHandle f;
};

void changeFontSize(FontHandle f, int newSize);

(2) Font f(getFont());가 있을 때 changeFontSize(f, 12);처럼 Font 객체를 그대로 넘겨도 컴파일되는 이유는 무엇이며, 이런 방식의 변환을 무엇이라 하는가?

(3) Font f1(getFont()); 다음에 FontHandle f2 = f1;이라고 쓰면, 어떤 일이 일어나고 어떤 문제가 생기는가? (f1이 소멸된 이후를 포함해서 쓰시오.)

(4) 명시적 변환과 암시적 변환 중, 안정성 측면에서 유리한 쪽과 고객 편의성 측면에서 유리한 쪽은 각각 무엇인가? 또 어떤 성격의 자원일 때 암시적 변환을 피하는 것이 좋은가?

📝 내 풀이:

(1) shared_ptr을 포인터에 집어넣은 것, pInv.get(), 명시적 변환 (2) operator FontHandle()로 인해 FontHandle로의 암시적 변환 때문. 암시적 변환 (3) f2에 f1의 fonthandle이 복사된다. f1이 먼저 소멸되는 경우, f2가 이미 소멸된 값을 가진다. (4) 안전성은 명시적, 편의성은 암시적이다. 서로 어떤 객체가 먼저 소멸될지 모르는 경우?

정답:

(1) pInv는 shared_ptr<Investment>인데 daysHeld는 Investment*를 받기 때문에 타입이 맞지 않아 컴파일 에러가 난다. daysHeld(pInv.get())처럼 get()으로 실제 포인터를 꺼내 넘겨야 하며, 이런 방식을 명시적 변환(explicit conversion)이라 한다.

(2) Font에 변환 연산자 operator FontHandle()이 정의되어 있어서 Font 객체가 FontHandle로 자동 변환되기 때문이다. 이를 암시적 변환(implicit conversion)이라 한다.

(3) 의도는 Font 객체를 복사하는 것이었지만, 암시적 변환이 일어나 FontHandle만 복사된다(f2는 FontHandle 타입). 그 결과 f1이 소멸되면서 FontHandle이 해제되면, f2는 이미 해제된 자원을 계속 가리키게 된다. 이는 자원 관리 객체의 목적과 상충한다.

(4) 안정성은 명시적 변환이 유리하고, 고객 편의성은 암시적 변환이 유리하다. 복사가 오용될 수 있는 자원이거나 자원을 명확히 관리하는 책임이 중요한 경우에는 암시적 변환을 피하는 것이 좋다. (단순한 포장(wrapper) 클래스라면 암시적 변환도 괜찮다.)

🔍 피드백:

  • (1) 2.5/2.5 — 타입 불일치(shared_ptr ≠ 포인터), get(), 명시적 변환 모두 맞습니다.
  • (2) 2.5/2.5 — operator FontHandle()에 의한 암시적 변환을 정확히 답했습니다.
  • (3) 2/2.5 — f2에 핸들만 복사되고, f1 소멸 후 f2가 해제된 값을 가진다는 핵심은 맞습니다. 다만 “Font 객체를 복사하려던 의도와 달리 암시적 변환 때문에 FontHandle만 복사된다”는 점(자원 관리 객체의 목적과 상충)이 빠졌습니다.
  • (4) 1.5/2.5 — 안정성은 명시적, 편의성은 암시적이라는 짝은 맞습니다. 암시적 변환을 피할 자원의 성격은 “복사가 오용될 수 있는 자원, 즉 자원을 명확히 관리하는 책임이 중요한 경우”입니다. “어떤 객체가 먼저 소멸될지 모르는 경우”는 (3)에서 본 증상(해제된 핸들 사용)과 연결되는 추측이지만, 자원의 성격을 말해 주는 표현은 아니라 부분 점수만 드렸습니다.

출처: game_dev/cpp/chapter3/2025-06-11-cpp_3_15.md


Q5. 🟢 쉬움 — ⭕ 10/10

문제: 게임 서버 구조의 발전 과정에서 데디케이티드 서버에 대한 설명으로 가장 올바른 것은?

  • A. 렌더링과 사용자 입력 처리를 하지 않고 순전히 클라이언트의 연결을 처리하며, 게임 플레이에는 참여하지 않는 프로그램이다.
  • B. 플레이어 중 한 명이 호스트가 되어 서버 역할까지 겸하는 방식이다.
  • C. 호스트 플레이어가 게임 중간에 이탈하면 게임 진행에 문제가 생긴다는 단점이 있다.
  • D. 서버 기능과 함께 렌더링도 수행하므로, 호스트 플레이어에게 유리해질 수 있다.

📝 내 선택: A

정답: A

해설:

데디케이티드 서버는 렌더링과 사용자 입력 처리를 하지 않고 순전히 클라이언트의 연결만 처리하는 프로그램이며, 게임 플레이에 참여하지 않는다.

  • B: 플레이어 중 한 명이 호스트 겸 서버가 되는 것은 세션 방식이다.
  • C: 호스트 이탈 시 문제가 생기는 것은 세션 방식의 단점이다.
  • D: 호스트도 렌더링을 하고 호스트에게 유리할 수 있는 것은 세션 방식이며, 데디케이티드 서버는 공정하다.

🔍 피드백: A를 정확히 골랐고, B·D가 리슨(세션) 서버 방식이라는 점, C의 호스트 이탈 문제가 데디케이티드 서버에는 해당하지 않는다는 점까지 근거가 모두 맞습니다.

출처: server/game_server/4/2026-02-08-game_server_4_1.md


Q6. 🟡 보통 · 📌 오답노트 — ⭕ 10/10

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

클라이언트 ― 방화벽 ― 스위치/라우터 ― 서버 ― 데이터베이스로 이어진 단일 서버에서는, 라우터/스위치·방화벽·CPU·스토리지 중 하나라도 한계를 넘어서면 분산 처리가 필요하다. 이때 먼저 성능 분석으로 과부하 지점을 찾고, 더 자세한 성능 분석으로 어떤 함수가 많은 처리량을 차지하는지 확인한 뒤, 분산을 먼저 진행하고 그다음에 코드 최적화를 진행한다. 분산 단위는 데이터 단위와 기능 단위로 나뉜다.

📝 내 답: X. 코드 최적화를 진행하고, 그래도 안되면 분산한다.

정답: X

해설:

과부하 지점 네 곳(라우터/스위치, 방화벽, CPU, 스토리지), 성능 분석 후 더 자세한 분석으로 처리량이 큰 함수를 확인하는 과정, 분산 단위(데이터 단위·기능 단위)는 모두 원문과 일치한다. 틀린 곳은 순서다. 원문의 순서는 성능 분석 → 더 자세한 분석 → 어떤 함수가 처리량을 차지하는지 확인 → 코드 최적화 → 분산이며, 코드 최적화를 먼저 하고 분산은 그다음에 진행한다.

🔍 피드백: 판단(X)과 틀린 곳(순서: 코드 최적화가 먼저, 분산은 그다음)을 정확히 짚었습니다. “그래도 안 되면 분산한다”는 표현도 해답의 순서와 같은 뜻입니다.

출처: server/game_server/9/2026-03-18-game_server_9_4.md 오답노트: wn-11a5330b · 2026-09-15 최초 오답 · 이번이 2번째 복습


📌 복습 포인트

  • Q1 메시지 메타데이터의 장단점 — 통신량 증가·해킹 취약은 단점이지만, 하위 호환성에는 유리함 → server/game_server/2/2025-12-09-game_server_2_8.md
  • Q3 프라우드넷 RMI 용어 — 송신 Proxy, 수신 Stub, 선언 파일 PIDL, 람다용 StubFunctional → server/game_server/6/2026-02-25-game_server_6_6.md
  • Q4 RAII 자원 노출 — 암시적 변환의 위험(복사 시 핸들만 복사되어 dangling)과 암시적 변환을 피할 자원의 성격 → game_dev/cpp/chapter3/2025-06-11-cpp_3_15.md

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

댓글남기기