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

게시:     수정

카테고리:

태그:

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

말랑말랑 퀴즈 📝

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


Q1. 🟡 보통

다음 템플릿 함수와 C++의 인터페이스·다형성에 대한 설명으로 가장 올바른 것은?

template<typename T>
void doProcessing(T& w) {
    if (w.size() > 10 && w != someNastyWidget) {
        T temp(w);
        temp.normalize();
        temp.swap(w);
    }
}
  • A. 클래스의 명시적 인터페이스는 컴파일 중에, 템플릿의 암시적 인터페이스는 프로그램 실행 중에 점검된다.
  • B. 템플릿의 암시적 인터페이스는 함수 시그너처가 아니라 템플릿 안에서 T의 객체에 사용된 유효 표현식들로 이루어지며, T가 그 표현식을 지원하지 않으면 템플릿 인스턴스화 단계, 즉 컴파일 중에 에러가 난다.
  • C. 위 코드에서 w.size() > 10이 유효하려면, T의 size()는 반드시 정수 타입을 반환해야 한다.
  • D. 가상 함수를 통한 다형성은 컴파일 중에 결정되고, 템플릿 인스턴스화를 통한 다형성은 프로그램 실행 중에 결정된다.

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

📝 내 선택: B

A: 둘다 컴파일 시점에 점검된다. C: 반드시 정수 타입을 반환할 필요가 없다. 왜냐면 > 연산자에서 bool 타입을 반환하면 되기 때문이다. D: 서로 반대이다. 가상 함수를 통한 다형성은 프로그램 실행 중, 템플릿 인스턴스화를 통한 다형성은 컴파일 시점이다.


Q2. 🟡 보통

빈칸을 채우시오. (대소문자는 구분하지 않습니다.)

SQL Server에서 테이블의 필드 데이터 형식을 고를 때의 지침이다.

  • 한글을 저장할 필드에는 varchar가 아니라 ① ___를 사용한다. (varchar는 한글이 깨진다)
  • 금융 계산처럼 정확한 값이 필요하면 오차가 있는 float 대신 ② ___를 사용한다.
  • 구형 타입 text는 Deprecated 되었으므로 대신 ③ ___를 사용한다.
  • null은 값 자체가 없음을 뜻하며, 0이나 ""(빈 문자열)과 ④ ___하기 위해 존재한다.

출처: server/game_server/7/2026-03-02-game_server_7_4.md

📝 내 답:


Q3. 🔴 어려움

swap을 직접 만든 클래스에 대해 효율적으로 지원하는 방법에 대해 답하시오.

표준 std::swap은 아래와 같이 구현되어 있다. 그리고 Widget은 실제 데이터를 담은 WidgetImpl 객체를 포인터 pImpl로 가리키는 pimpl 구조의 클래스이다.

namespace std {
    template<typename T>
    void swap(T& a, T& b) {
        T temp(a);
        a = b;
        b = temp;
    }
}

class Widget {
    ...
private:
    WidgetImpl* pImpl;
};

너무 헷갈려서 레퍼런스를 살펴보고 답안을 적어 0점 처리입니다.

(1) Widget 두 객체를 std::swap으로 맞바꾸면 왜 비효율적인가? 몇 개의 무엇이 복사되는지 쓰시오.

(2) Widget이 클래스 템플릿이 아닌 경우, std::swap<Widget>을 완전 특수화하여 본문에서 swap(a.pImpl, b.pImpl);을 직접 호출하면 컴파일되지 않는다. 이유는 무엇이며, 어떻게 해결하는가?

(3) Widget<T>가 클래스 템플릿인 경우에는 std 네임스페이스에서 다음 두 방법을 쓸 수 없다. 각각 왜 안 되는지 설명하고, 올바른 해결 방법을 쓰시오.

  • 가. template<typename T> void swap<Widget<T>>(Widget<T>&, Widget<T>&) 처럼 std::swap을 부분 특수화
  • 나. std 안에 template<typename T> void swap(Widget<T>&, Widget<T>&)를 새로 오버로딩

(4) 사용자 코드에서 std::swap(obj1, obj2);로 호출하면 안 되는 이유와, 올바른 호출 방식을 쓰시오.

출처: game_dev/cpp/chapter4/2025-07-02-cpp_4_25.md

📝 내 풀이:

(1) Widget을 맞바꾸기 위해 불필요한 복사 연산이 생긴다. 3개의 Widget과 3개의 WidgetImpl

(2) pImpl이 private 멤버이기 때문이다. swap의 완전 템플릿 특수화 버전이 Widget 클래스의 swap 멤버 함수를 호출하도록 짠다.

(3) 가: 함수 템플릿에 대해 부분 특수화를 허용하지 않는다. 나: std 네임스페이스에 오버로딩하는 것은 허용되지 않는다.
사용자 네임스페이스에 swap의 부분 템플릿 특수화 버전을 선언하고, Widget 클래스의 swap 멤버 함수를 호출하도록 한다.

(4) using std::swap; swap(obj1, obj2);


Q4. 🟡 보통

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

std::unordered_map<std::string, int> m;의 원소는 실제로 std::pair<const std::string, int> 타입이다. 따라서 for (const std::pair<std::string, int>& p : m)처럼 const가 빠진 타입으로 순회해도 원소를 복사 없이 그대로 참조하므로, for (const auto& p : m)으로 바꿔도 성능 차이는 없다.

출처: game_dev/moderncpp/2/2026-04-07-moderncpp_2_5.md

📝 내 답: O. 잘은 모르겠지만, 그럴 것으로 예상된다


Q5. 🟡 보통

다음 다중 상속 코드에 대한 설명으로 가장 올바른 것은?

class BorrowableItem {
public:
    void checkOut();           // 도서관에서 체크아웃
};

class ElectronicGadget {
private:
    bool checkOut() const;     // 테스트 실시 후 성공 여부 반환
};

class MP3Player : public BorrowableItem, public ElectronicGadget { };

MP3Player mp;
mp.checkOut();
  • A. ElectronicGadget::checkOut이 private이므로 접근할 수 없는 후보에서 제외되어, BorrowableItem::checkOut이 자동으로 호출된다.
  • B. 컴파일러는 최적 일치 함수를 먼저 찾은 뒤에 접근 가능성을 점검하므로 public/private 차이와 무관하게 모호성 에러가 나며, mp.BorrowableItem::checkOut();처럼 클래스를 명시해 해결한다.
  • C. 마름모꼴 상속에서는 데이터 중복을 막기 위해 가상 상속이 필요하며, 가상 상속은 비용이 없으므로 항상 사용하는 것이 좋다.
  • D. 가상 기본 클래스에는 데이터를 넣는 편이 초기화와 대입의 복잡성을 줄여 준다.

출처: game_dev/cpp/chapter6/2025-10-28-cpp_6_40.md

📝 내 선택: B

A: private 상속이라 해서, 그것을 상속한 클래스에서 접근할수 없는 것이 아니다. C: 가상 상속은 항상 비용이 있으며, 단일 상속을 추천한다. D: 데이터를 넣으면 오히려 복잡성이 늘어난다.


Q6. 🟡 보통 · 📌 오답노트 (3번째 복습)

게임 서버에서 여러 스레드가 공유 데이터를 다룰 때의 문제에 대해 답하시오.

(1) 전역 변수 gold의 값이 100일 때, 스레드 A는 gold += 50;을, 스레드 B는 gold += 30;을 동시에 실행한다. 이 연산은 기계어 수준에서 t = gold → t = t + y → gold = t 세 단계로 쪼개진다. 실행이 어떻게 섞이느냐에 따라 gold가 최종적으로 가질 수 있는 값을 모두 쓰고, 각각 어떤 경우인지 설명하시오.

(2) 소수를 찾는 4개의 스레드가 공유 변수 num을 while (num <= 1000000) { ...; num++; }으로 함께 증가시키면, num++ 때문에 어떤 현상이 생길 수 있는가? 두 가지를 쓰시오.

(3) 4개의 스레드가 공유하는 Array<int> primes는 내부에 “배열을 가리키는 포인터”와 “배열의 크기 정보”를 가지고 있다. 여러 스레드가 동시에 primes.Add()를 호출하다가 공간이 부족해 내부에서 메모리 재할당이 일어나면 어떤 일이 벌어질 수 있는지, 포인터의 변화를 중심으로 설명하시오.

(4) (2)와 (3)의 문제를 해결하려면 보장해야 하는 두 가지 성질의 이름을 쓰고, 각각 (2)·(3) 중 어느 문제와 대응되는지 한 줄로 설명하시오. 또한 이를 가능하게 하는 동기화 기법 세 가지를 쓰시오.

출처: server/game_server/1/2025-05-30-game_server_1_5.md 오답노트: wn-2de515c0 · 2026-09-09 최초 오답 · 이번이 3번째 복습

📝 내 풀이: (1) 130, 150, 180. 각 기계어 명령은 섞일수 있으며, 여기서 결과가 나뉘는 핵심은 gold = t 실행의 순서로 결정된다(자세한 내용은 너무 길게 써야해 생략한다)

(2) 1. num++의 기계어 수준에선 3단계로 쪼개지기에 num이 증가되지 않는 경우가 생긴다.
2: 나머지 하나는 모르겠다

(3) 재할당이 일어났을때 배열을 가리키는 포인터가 이동했을수도 있다. 댕글링 포인터 문제로 인해 프로그램이 종료될수 있다고

(4) 원자성, 일관성. 뮤텍스, 모니터, 세마포어


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

댓글남기기