[말랑 퀴즈] 26/10/06 해답
카테고리: MallangQuiz
태그: Quiz
제 말랑말랑 퀴즈 생성기는 이곳에서 확인하실 수 있습니다.
말랑말랑 퀴즈 — 해답지 ✅
날짜: 2026-10-06 문제 수: 6문제 총점: 48/60 (80점) ✅ 잘했어요
📊 채점 결과
| 문항 | 유형 | 난이도 | 결과 | 점수 |
|---|---|---|---|---|
| Q1 | 객관식 | 🟡 보통 | ⭕ 정답 | 10 / 10 |
| Q2 | 빈칸 채우기 | 🟡 보통 | ❌ 오답 | 0 / 10 |
| Q3 | 서술형 | 🔴 어려움 | 🔺 부분 정답 | 8 / 10 |
| Q4 | OX | 🟢 쉬움 | ⭕ 정답 | 10 / 10 |
| Q5 | 객관식 | 🟢 쉬움 | ⭕ 정답 | 10 / 10 |
| Q6 | 빈칸 채우기 | 🟢 쉬움 · 📌 오답노트 | ⭕ 정답 | 10 / 10 |
| 합계 | 48 / 60 |
총평
객관식·OX 문제는 모두 맞혔고, 오답노트로 재출제된 Q6(레이스 컨디션)도 5개 빈칸을 전부 맞혀 복습 효과가 확실히 나타났습니다. Q3 락스텝은 통신량·난입 문제 등 큰 틀은 잘 이해했지만, 미래 시간을 너무 가깝게 잡았을 때의 현상(스터터링)과 체크섬의 목적(부정행위 감지)이 살짝 어긋났습니다. Q2 MongoDB 함수 이름은 글에서 쓴 이름(explain, ensureIndex, DropIndexes)을 떠올리지 못해 전부 놓쳤습니다.
Q1. 🟡 보통 — ⭕ 10/10
문제: C++11/C++14의 const_iterator에 대한 설명으로 가장 올바른 것은?
- A. C++98에서도 비
const컨테이너에cbegin()을 호출하면 간단히const_iterator를 얻을 수 있었으므로,const_iterator는 처음부터 널리 쓰였다. - B. C++11에서는 컨테이너의
cbegin()/cend()가 비const컨테이너에서도const_iterator를 돌려주고,insert·erase같은 STL 멤버 함수도 위치를const_iterator로 받을 수 있게 되어const_iterator를 쓰기 쉬워졌다. - C. 비멤버 함수
std::cbegin/std::cend는 C++11 표준에 이미 포함되어 있어, C++11에서도using std::cbegin;만으로 일반화된 템플릿 코드를 쓸 수 있다. - D. C++11에서 비멤버
cbegin을 직접 구현할 때는, 반드시 컨테이너의 멤버cbegin()을 호출해야const_iterator가 반환된다.
📝 내 답: B. 98과 11 버전의 차이점에 대해서는 정확히 잘 모르겠다.
정답: B
해설:
- A (✗): C++98에서는 비
const컨테이너로부터const_iterator를 얻는 간단한 방법이 없었고, 삽입/삭제 위치도iterator로만 지정할 수 있어 너무 불편했습니다. 그래서 대부분 쓰지 않는 분위기였습니다. - B (✓): C++11의
cbegin()/cend()는 비const컨테이너에서도const_iterator를 돌려주고,insert·erase등도const_iterator를 사용합니다. - C (✗): C++11에는 비멤버
begin/end만 추가되었고,cbegin·cend·rbegin·rend·crbegin·crend는 누락되었습니다. 이 템플릿은 C++14에서 잘 작동합니다. - D (✗): 직접 구현할 때는 멤버
cbegin이 아니라const C&로 받은 컨테이너에 비멤버std::begin을 호출합니다.const컨테이너에begin을 호출하면const_iterator가 반환되며, 이렇게 해야begin만 있고cbegin멤버가 없는 컨테이너나 내장 배열에도 동작합니다.
🔍 피드백: B가 정답입니다. “잘 모르겠다”고 적었지만 선택 자체는 했고 맞았으므로 만점입니다. 98→11의 차이는 “비const 컨테이너에서도 cbegin()으로 const_iterator를 얻을 수 있고, insert/erase도 const_iterator 위치를 받는다”로 정리하면 됩니다. C·D처럼 “C++11 비멤버 cbegin은 누락 → C++14에서 추가, 직접 구현 시 std::begin을 const 참조에 호출”이라는 디테일이 함정 포인트입니다.
출처:
game_dev/moderncpp/3/2026-05-02-moderncpp_3_13.md
Q2. 🟡 보통 — ❌ 0/10
문제: 빈칸을 채우시오. (함수 이름은 이 글에서 사용한 이름으로 답하시오. 대소문자는 구분하지 않습니다.)
MongoDB에서 쿼리의 성능을 분석하고 인덱스를 관리하는 코드이다.
db.coll1.find().①___("executionStats") // 성능 분석
db.coll1.②___({"a":1}) // 필드 a에 인덱스 추가
db.coll1.GetIndexes() // 인덱스 목록
db.coll1.DropIndex({"a":1}) // 인덱스 하나 제거
db.coll1.③___() // 인덱스 전체 제거
📝 내 답: exec, InsertIndex, RemoveAll
정답:
① explain ② ensureIndex ③ DropIndexes
해설:
.explain("executionStats")를 쿼리 뒤에 붙이면 실행 통계를 볼 수 있어 병목 분석에 쓰입니다. 인덱스 추가는 .ensureIndex(), 인덱스 하나 제거는 DropIndex({...}), 인자 없이 호출하는 DropIndexes()는 인덱스를 전부 제거합니다.
🔍 피드백: 세 칸 모두 글에서 쓴 이름과 달라 0점입니다(각 3.3점). 다만 기능은 올바르게 추론했습니다(성능 분석 → 실행, 인덱스 추가, 전체 제거). 이름 패턴을 외우는 것이 핵심입니다: 분석은 explain, 추가는 ensureIndex, 하나 제거는 DropIndex, 전부 제거는 복수형 DropIndexes.
출처:
server/game_server/8/2026-03-13-game_server_8_7.md
Q3. 🔴 어려움 — 🔺 8/10
문제: 실시간 전략 시뮬레이션(RTS) 게임의 락스텝(Lockstep) 동기화에 대해 답하시오.
(1) 락스텝은 다른 동기화 방식에 비해 통신량이 적다. 그 이유를 “무엇을 주고받는가”의 관점에서 설명하시오.
(2) 플레이어가 입력 명령을 보낼 때 “시간”과 함께 체크섬도 같이 보낸다. 체크섬은 무엇을 위한 것인가?
(3) 네트워크 지연(레이턴시)이 있는 환경에서는 명령이 “언제 실행될지”를 나타내는 미래 시간을 함께 보낸다. 이 미래 시간을 계산하는 식을 쓰고, 미래 시간을 너무 멀게 잡았을 때와 너무 가깝게 잡았을 때 각각 어떤 현상이 생기는지 쓰시오.
(4) 락스텝의 단점을 두 가지 이상 쓰시오.
📝 내 풀이:
(1) 서로의 입력만 주고 받아 화면에 그리기 떄문에 통신량이 적어진다.
(2) 변조를 막기 위함이다.
(3) 시간 + RTT/2 + 알파. 멀게 잡으면 느리게 반응한다. 가깝게 잡으면 더 빠르게 반응하며 명령을 받았을때 너무 이른 명령이 될 수 있다.
(4) 1. 접속자가 많아지면 모두에게 입력을 전송하고 동기화해야 한다.
- 난입한 플레이어에 대해 동기화하기 까다롭다.
정답:
(1) 각 플레이어는 입력 명령만 서로에게 보내고, 캐릭터의 이동 상태 같은 결과 상태는 주고받지 않습니다. 모든 클라이언트가 같은 명령으로 같은 시뮬레이션을 돌려 동시에 씬을 업데이트하므로 통신량이 적습니다.
(2) 해커(부정행위)를 감지하기 위한 것입니다. 모든 클라이언트가 동일한 시뮬레이션을 실행해야 하므로, 체크섬이 서로 다르면 어느 쪽이 조작되었거나 어긋났음을 알 수 있습니다.
(3) 식: 미래 시간 = 현재 시간 + 왕복 레이턴시(RTT) / 2 + 임의의 일정 값
- 너무 멀게 잡은 경우: 입력과 출력(화면 반영) 사이의 간격이 멀어져 렉이 생깁니다.
- 너무 가깝게 잡은 경우: 명령이 제때 도착하지 못해 캐릭터 움직임이 끊기는 스터터링(Stuttering) 현상이 생깁니다.
(4) 아래 중 두 가지 이상:
- 진행 중인 게임에 난입하는 기능을 만들기 까다롭다.
- 게임 플레이 연산에 부동소수점을 사용할 수 없다(결정론적 시뮬레이션 필수).
- 플레이어 수가 많아지면 통신량이 크게 증가한다.
- 씬 업데이트가 일시 정지할 확률이 높다(레이턴시가 가장 높은 사람 기준으로 미래 시간을 정해야 함).
- 입력 명령 속도에 민감한 게임(FPS, 액션 등)에 부적합하다.
🔍 피드백: 4개 논점(각 2.5점)으로 채점했습니다.
- (1) 2.5점 — “입력만 주고받는다”는 핵심을 정확히 짚었습니다.
- (2) 1.5점 — 부정행위 방지라는 방향은 맞습니다. 다만 체크섬은 변조를 “막는” 것이 아니라, 클라이언트 간 시뮬레이션 결과가 같은지 비교해 어긋남/조작을 감지하는 용도입니다.
- (3) 1.5점 — 식(
시간 + RTT/2 + α)과 “멀게 잡으면 느리게 반응(렉)”은 정확합니다. 하지만 가깝게 잡으면 “더 빠르게 반응”하는 것이 아니라, 명령이 제때 도착하지 못해 움직임이 끊기는 스터터링이 생깁니다. - (4) 2.5점 — 통신량 증가와 난입 어려움, 두 가지 모두 정답 목록에 있습니다.
출처:
server/game_server/5/2026-02-15-game_server_5_5.md
Q4. 🟢 쉬움 — ⭕ 10/10
문제: 다음 명제가 참(O)인지 거짓(X)인지 판단하라.
TCP는 1:1 통신만 허용하므로 소켓 1개는 상대의 끝점 하나와 대응된다. 또한 클라이언트에서
connect()를 호출하면 상대와의 연결 시도가 끝날 때까지 블로킹되며, 연결에 성공하면true, 실패하면false를 반환한다.
📝 내 답: O. TCP는 1:1 통신이며, 연결 완료될떄까지 블로킹된다.
정답: O
해설:
TCP는 1:1 통신만 허락하므로 소켓 하나는 끝점 하나와 1대1로 대응됩니다. 또한 connect()는 연결이 완료될 때까지 블로킹되고, 성공 시 true, 실패 시 false를 반환합니다. 두 문장 모두 글의 내용과 일치합니다.
🔍 피드백: 판단(O)과 근거(1:1 통신, 연결 완료까지 블로킹) 모두 정확합니다. 덧붙이면 성공 시 true, 실패 시 false를 반환한다는 반환값까지 기억해 두면 완벽합니다.
출처:
server/game_server/3/2026-02-03-game_server_3_2.md
Q5. 🟢 쉬움 — ⭕ 10/10
문제: 온라인 게임에서 서버의 역할에 대한 설명으로 가장 올바른 것은?
- A. 1인용 게임의 게임 루프는 “렌더링 → 입력 받기 → 게임 로직 처리” 순서로 반복된다.
- B. 온라인 게임에서는 여러 플레이어 사이의 상호작용을 중재(동기화)해야 하므로 서버가 필요하며, 대부분의 게임 서버는 클라이언트의 게임 로직 처리 일부를 서버로 옮겨 클라이언트가 허튼 수를 쓰지 못하게 한다.
- C. 게임 세션은 보통 1초에 6번 상태가 변화하며, 이것을 게임 로직 처리라고 한다.
- D. 서버는 변화된 상태를 화면에 표현하는 렌더링을 모든 클라이언트를 대신해 수행한다.
📝 내 답: B.
A: 게임 로직 처리, 렌더링, 입력 받기 였던것 같다. C: 1초에 60번 변화한다. D: 렌더링은 클라이언트가 수행하는 것이 일반적이다.
정답: B
해설:
- A (✗): 게임 루프 순서는 입력 받기 → 게임 로직 처리하기 → 렌더링입니다.
- B (✓): 온라인 게임은 여러 명이 행동하므로 서로의 상호작용을 중재·동기화해야 하고, 그래서 서버와 클라이언트가 등장합니다. 대부분의 서버는 클라이언트 로직 일부를 서버로 옮겨 클라이언트의 부정행위를 막습니다.
- C (✗): 세션은 보통 1초에 60번 상태가 변화합니다.
- D (✗): 렌더링은 변화된 상태를 화면에 표현하는 과정으로 클라이언트 쪽 일이며, 서버가 대신하지 않습니다.
🔍 피드백: B 정답이고 C(60번), D(렌더링은 클라이언트)의 근거도 정확합니다. A에서 기억하신 순서(“로직 처리 → 렌더링 → 입력”)는 실제와 다르니 주의하세요. 올바른 게임 루프 순서는 입력 받기 → 게임 로직 처리 → 렌더링입니다.
출처:
server/game_server/4/2026-02-08-game_server_4_3.md
Q6. 🟢 쉬움 · 📌 오답노트 — ⭕ 10/10
문제: 빈칸을 채우시오.
두 스레드가 x += y;를 실행하는 상황을 생각해 보자. x의 초기값은 2이고, 스레드 1은 y = 3, 스레드 2는 y = 4로 실행한다. 이 연산은 기계어 수준에서 t = x → t = t + y → x = t 세 단계로 쪼개진다.
# 스레드 1
t1 = x // t1 = 2
t1 = t1 + 3 // t1 = 5 ← 여기서 컨텍스트 스위치
# 스레드 2 (끝까지 실행)
t2 = x // t2 = 2
t2 = t2 + 4 // t2 = 6
x = t2 // x = 6
# 다시 스레드 1
x = t1 // x = ①___
이상적으로는 두 연산이 차례로 실행되어 x = 9가 되어야 하지만, 이처럼 두 스레드가 같은 데이터에 접근해 상태를 예측할 수 없게 되는 상황을 ②_ (또는 데이터 레이스)라고 한다. 이를 막으려면 num++처럼 하나의 작업 단위가 도중에 **쪼개지지 않도록** 하는 성질인 ③과, 배열 포인터와 크기처럼 여러 멤버가 항상 서로 어울리는 상태여야 한다는 성질인 ④을 지켜야 하며, 이 두 성질을 가능하게 하는 기술(임계 영역·뮤텍스·잠금 등)을 통칭 ⑤_라고 한다.
출처:
server/game_server/1/2025-05-30-game_server_1_5.md오답노트:wn-7f930a70· 2026-09-14 최초 오답 · 이번이 2번째 복습
📝 내 답: 5, 레이스 컨디션, 원자성, 일관성, 동기화
정답:
① 5 ② 경쟁 상태 ③ 원자성 ④ 일관성 ⑤ 동기화
해설:
스레드 1이 읽어 둔 t1 = 5를 나중에 x에 덮어쓰기 때문에 스레드 2가 만든 x = 6이 사라지고 x = 5가 됩니다. 이런 상황이 경쟁 상태(데이터 레이스)입니다. 이를 막으려면 작업이 쪼개지지 않는 원자성과 여러 멤버가 항상 어울리는 상태를 유지하는 일관성이 필요하고, 이를 가능하게 하는 기술의 통칭이 동기화(Synchronization)이며 임계 영역·뮤텍스·잠금이 대표 기법입니다.
🔍 피드백: 5칸 모두 정답입니다. ②의 “레이스 컨디션”은 “경쟁 상태”와 같은 용어(영문 표기)라 정답으로 인정했습니다. 연속 만점으로 이 항목은 마스터됩니다.
출처:
server/game_server/1/2025-05-30-game_server_1_5.md
📌 복습 포인트
- Q2 MongoDB 인덱스 함수 이름 —
explain("executionStats"),ensureIndex,DropIndex/DropIndexes(복수형은 전체 제거) →server/game_server/8/2026-03-13-game_server_8_7.md - Q3 락스텝의 체크섬과 미래 시간 — 체크섬은 어긋남/부정행위 감지용, 미래 시간을 너무 가깝게 잡으면 스터터링, 멀게 잡으면 렉 →
server/game_server/5/2026-02-15-game_server_5_5.md
댓글남기기