[말랑 퀴즈] 26/08/31 문제
카테고리: MallangQuiz
태그: Quiz
제 말랑말랑 퀴즈 생성기는 이곳에서 확인하실 수 있습니다.
말랑말랑 퀴즈 📝
날짜: 2026-08-31 문제 수: 5문제
Q1. 🟢 쉬움
빈칸을 채우시오.
1인용 게임은 아래 세 단계가 계속 반복되는 게임 루프로 돌아간다.
┌─────────────────────────────────────────────┐
│ ① ___ : 입력 장치를 통해 정보를 획득한다 │
│ ↓ │
│ ② ___ : 세션의 상태를 변화시킨다 │
│ (보통 1초에 ③ ___ 번) │
│ ↓ │
│ ④ ___ : 변화된 상태를 화면에 표현한다 │
└──────────────────┘ ← 다시 위로 반복
그런데 온라인 게임은 한 명이 아니라 여러 명이 동시에 행동한다. 그래서 서로 간의 상호작용을 중재해서 ⑤ ___ 시켜 주어야 하고, 바로 여기서 서버와 클라이언트가 등장한다.
대부분의 게임 서버는 클라이언트가 하던 ⑥ ___ 처리를 일부 떼어내 서버로 옮긴 뒤 데이터를 주고받는다. 성능상의 이유만은 아니다 — 클라이언트가 허튼 수를 부리지 못하게 막으려는 목적도 있다.
출처:
server/game_server/4/2026-02-08-game_server_4_3.md
📝 내 답: (빈칸 수에 맞게 작성하세요)
Q2. 🟡 보통
아래 코드를 보자.
std::string* stringArray = new std::string[100];
...
delete stringArray; // ← []를 빠뜨렸다
이 코드에 대한 설명으로 가장 올바른 것은?
- A.
new std::string[100]이 잡은 것은 결국 연속된 메모리 한 덩어리이므로,delete를 쓰든delete[]를 쓰든 그 블록 전체가 운영체제에 반환된다.delete[]는 관례상 읽기 좋으라고 쓰는 표기일 뿐이다. - B. 배열을 할당하면 원소들과 함께 배열의 크기 정보도 저장되고,
delete[]는 그 값을 읽어 각 원소의 소멸자를 정확한 횟수만큼 호출한다.delete를 쓰면 그 구조를 모르는 채 단일 객체로 취급하므로 첫 번째 객체만 소멸되고 나머지 소멸자는 호출되지 않는 정의되지 않은 동작이 된다. - C. 문제가 되는 것은
std::string처럼 소멸자가 있는 타입일 때뿐이다.new int[100]처럼 소멸자가 없는 타입이라면 해제할 소멸자가 애초에 없으므로delete로 지워도 표준상 안전하다. - D.
typedef std::string AddressLines[4];처럼 배열을typedef로 감싸 두면 컴파일러가 그 이름이 배열임을 기억한다. 따라서new AddressLines로 만든 것은delete로 지워도 되며, 오히려 이런 실수를 막으려면 배열 타입을typedef로 감싸 두는 편이 안전하다.
출처:
game_dev/cpp/chapter3/2025-06-12-cpp_3_16.md
📝 내 선택: ( )
Q3. 🔴 어려움
게임 서버가 데이터베이스를 다루는 방식에 대한 문제다.
(1) 게임 서버가 필요할 때마다 아래처럼 질의 구문을 DB로 던지는 방식은 비효율적이다. 그 이유를 세 가지 쓰시오. 그리고 이를 줄이기 위해 쓰는 기법의 이름과, 그 기법이 어떻게 문제를 완화하는지 설명하시오.
select * from Character where CharacterID='Little Elf'
select * from Item where OwnerCharacterID='Little Elf'
(2) 아래는 강부자가 홍길동에게 100원을 보내는 코드다.
begin transaction
update UserAccount set Money=Money+100 where ID='Kang Bu Ja'
update UserAccount set Money=Money-100 where ID='Hong Gil Dong'
-- commit 또는 rollback transaction
- ㉠ 여기서 트랜잭션이 필요한 이유는 무엇인가?
- ㉡ 그런데 트랜잭션은 공짜가 아니다. 아래 상황에서 무슨 일이 벌어지는지 쓰고, 이것이 멀티스레딩의 무엇과 닮았는지 답하시오.
쿼리 프로세스 1 쿼리 프로세스 2
BEGIN TRANS BEGIN TRANS
A = A + 10
B = B + 10
B = B - 10 ⚠️
A = A - 10 ⚠️
- ㉢ ㉡을 예방하는 방법을 두 가지 이상 쓰시오.
(3) 아래는 두 플레이어가 아이템을 교환하는 게임 서버 코드다. 트랜잭션을 쓰지 않고 있다.
void RequestExchangeItems(player1, player2, item1, item2) {
// 사전 검증
if (!player1.hasItem(item1)) { ResponseExchangeItemsFail(...); return; }
if (!player2.hasItem(item2)) { ResponseExchangeItemsFail(...); return; }
...
player1.removeItem(item1); // 메모리상에서 먼저 처리
player2.removeItem(item2);
player1.addItem(item2);
player2.addItem(item1);
db.execute("update Item set owner={player2} where itemID={item1}");
db.execute("update Item set owner={player1} where itemID={item2}");
}
- ㉠ 이 코드가 트랜잭션 없이도 비교적 안전한 이유는 무엇인가? (코드에서 근거를 짚으시오.)
- ㉡ 그럼에도 두
db.execute사이에서 게임 서버가 크래시하면 데이터가 어긋난다. 이 경우를 어떻게 대비하는가?
출처:
server/game_server/7/2026-03-05-game_server_7_9.md
📝 내 풀이:
<풀이를 여기에="" 작성하세요=""> --- ## Q4. 🟡 보통 다음 명제가 참(O)인지 거짓(X)인지 판단하라. > 분산 처리는 **확장성**뿐 아니라 **안정성**에도 효과를 준다. 서버가 한 대뿐이라면 그 한 대가 멈추는 순간 서비스 전체가 멈추기 때문이다. > > **수평 분산**의 경우, 서버 한 대가 중지되어도 **그 서버에 있던 플레이어들만** 접속이 끊어진다. 그들은 다른 서버에 접속하면 되므로 나머지 플레이어에게는 영향이 없다. > > **수직 분산** 역시 마찬가지다. 기능별로 서버를 나눠 두었으므로 한 대가 멈추면 **그 서버가 담당하던 기능을 남은 서버들이 나눠 맡게 되어**, 서비스 전체가 아무런 영향 없이 그대로 계속된다. > **출처:** `server/game_server/9/2026-03-22-game_server_9_11.md` **📝 내 답:** O / X --- ## Q5. 🔴 어려움 C++ 템플릿에서 `typename` 키워드에 대한 문제다. (1) 아래 두 선언의 차이는 무엇인가? ```cpp template
댓글남기기