[말랑 퀴즈] 26/08/21 문제

게시:     수정

카테고리:

태그:

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

말랑말랑 퀴즈 📝

날짜: 2026-08-21 문제 수: 5문제


Q1. 🔴 어려움

UE5의 AGameMode는 매치 상태머신(EnteringMapWaitingToStartInProgressWaitingPostMatch → …)을 내장하고 있고, 각 상태에 진입할 때 훅이 불린다. 아래는 엔진 코드의 일부다.

// 엔진 GameMode.cpp:148-161
void AGameMode::HandleMatchIsWaitingToStart()
{
    ...
    // Calls begin play on actors, unless we're about to transition to match start
    if (!ReadyToStartMatch())
    {
        GetWorldSettings()->NotifyBeginPlay();       // ①
    }
}

// 엔진 GameMode.cpp:203-221
void AGameMode::HandleMatchHasStarted()
{
    ...
    // First fire BeginPlay, if we haven't already in waiting to start match
    GetWorldSettings()->NotifyBeginPlay();           // ②
}

그리고 이를 상속한 게임 코드는 다음과 같다. (ReadyToStartMatch()는 최소 인원 조건을 걸도록 오버라이드되어 있다.)

void AEPGameMode::HandleMatchHasStarted()
{
    for (TActorIterator<AEPItemSpawner> It(GetWorld()); It; ++It)
        It->SpawnLoot();                 // ← Super 호출 이전

    Super::HandleMatchHasStarted();      // ← 여기서 NotifyBeginPlay()
    ...
}

(1) 액터의 BeginPlay가 불릴 수 있는 지점이 왜 두 곳인지, 그리고 어떤 조건일 때 어느 쪽이 실행되는지 설명하시오.

(2) 위 AEPGameMode::HandleMatchHasStarted()는 현재 정상 동작하지만 잠복 위험을 안고 있다. 무엇이 문제이며, 어떤 조건이 갖춰졌을 때 실제 버그가 되는지 설명하시오.

출처: game_dev/devlog/2026-02-08-EP_Gameplay_Framework-3.md

📝 내 풀이:

(1) HandleMatchIsWaitingToStart()는 서버 측에서 WaitingToStart에 도착한 순간 클라에서 호출되고,
HandleMatchHasStarted()는 서버 측에서 InProgress에 도착한 순간 클라에서 호출된다.

두 곳이 존재하는 이유는 클라가 접속한 시점이 각자 달라 BeginPlay가 호출되지 않을 수 있기 때문이다.

(2) 매칭 시작 대기방이 따로 없는 경우? 잘 모르겠다.


Q2. 🟡 보통

분산 처리를 전혀 적용하지 않은 단일 게임 서버에 동시접속자 수가 계속 늘어나는 상황이다. 이때 각 구성 요소에서 벌어지는 일에 대한 설명으로 가장 올바른 것은?

  • A. 32비트 서버는 물리 메모리보다 많은 메모리를 할당해 대량의 메모리 스와핑이 발생하고, 64비트 서버는 malloc()이 null을 반환하며 비정상 종료한다.
  • B. 서버의 CPU/RAM 사용량이 늘어나는 것은 메시지 수신 속도가 처리 속도를 앞지르고 요청 발생 속도가 송신 속도를 앞지르기 때문이며, 네트워크 기기 쪽에서는 라우터 과부하로 패킷이 유실되고 TCP 재전송 타임아웃으로 연결이 해제된다.
  • C. 클라이언트가 겪는 증상은 메시지 응답 지연과 접속 지연뿐이며, 이미 맺어진 TCP 연결 자체는 끊기지 않는다.
  • D. 데이터베이스는 질의 수가 디스크 최대 처리 속도를 넘지 않는 한 메모리 사용량이 늘어나지 않으므로 병목이 되지 않는다.

출처: server/game_server/9/2026-03-17-game_server_9_2.md

📝 내 선택: A


Q3. 🟢 쉬움

빈칸을 채우시오.

모든 작업을 수평 분산 처리로 해결할 수 있는 것은 아니다.

  • 동기 분산 처리: ① ___ 법칙이 심하게 작용한다.
  • 비동기 분산 처리: 요청과 응답을 주고받아야 한다.
  • 데이터 복제 기반 분산 처리: ② ___이(가) 깨진다.

이럴 때는 경매장이나 채팅처럼 기능 단위로 서버를 따로 두는 방식을 쓰며, 이를 기능적 분산 처리 또는 ③ ___ 분산 처리라고 부른다. 다만 수평 분산 처리보다 분산 효율성이 떨어지므로 최후의 수단으로 본다.

출처: server/game_server/9/2026-03-20-game_server_9_8.md

📝 내 답: 1. 모르겠다(한 서버 약간의 변경점으로도 다수의 서버가 영향을 받는 법칙이 있었나?) 2. 무결성 3. 수직


Q4. 🔴 어려움

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

// AddressLines는 string 4개짜리 배열 타입이다
typedef std::string AddressLines[4];

std::string* pal = new AddressLines;

delete pal;

new를 호출할 때 []를 쓰지 않았으므로, 해제도 [] 없이 delete pal;로 하는 것이 new와 delete의 형태를 맞춘 올바른 코드다.

출처: game_dev/cpp/chapter3/2025-06-12-cpp_3_16.md

📝 내 답: X. 배열은 delete [] 형태로 사용해야 한다.


Q5. 🟡 보통

프라우드넷으로 채팅을 구현했다. 서버는 클라이언트에게서 메시지를 받아 다른 클라이언트들에게 뿌려주는 중계 역할을 한다. 아래는 서버 측 의사 코드다.

class MyGameServer {
    CNetServer* m_netServer;
    CriticalSection m_critSec;
    map<HostID, shared_ptr<RemoteClient>> m_remoteClients;
    MyGameS2C::Proxy m_s2cProxy;

    MyGameC2S::Stub::Chat(senderHostID, rmiContext, text) {
        CriticalSectionLock lock(m_critSec, true);

        // 1
        shared_ptr<RemoteClient> sender =
            m_remoteClients.find(senderHostID).second;

        // 2
        vector<HostID> sendTo;
        for(auto r : m_remoteClients) {
            if(r.first != senderHostID)
                sendTo.push_back(r.first);
        }

        // 3
        m_s2cProxy.ShowChat(&r[0], r.size(), sender->m_name, text);
    }
}

(1) 주석 1·2·3번 단계가 각각 무슨 일을 하는지 설명하시오.

(2) m_remoteClients에 접근할 때 CriticalSectionLock으로 보호하는 이유는 무엇인가?

(3) 클라이언트 측 메인 루프는 아래와 같다. FrameMove()는 어떤 역할을 하는가?

MainLoop() {
    while(true) {
        m_netClient->FrameMove();
        update_scene();
        render_scene();
    }
}

출처: server/game_server/6/2026-02-27-game_server_6_8.md

📝 내 풀이:

(1) 1. 전송자의 RemoteClient 객체를 얻는 과정 2. 수신자들의 HostID를 수집하는 과정 3. 수신자들에게 송신자의 이름과 메세지를 전송한다.

(2) 도중 접속/퇴장이 발생해 m_remoteClients 변수에 영향이 가, 전송자를 찾는 과정에 오류가 발생할 수 있기 때문

(3) 클라이언트의 한 프레임을 진행시킨다.

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

댓글남기기