본문으로 건너뛰기
Previous
Next
C++ 코딩 테스트 | '백준·프로그래머스' 알고리즘 유형별 STL 활용법

C++ 코딩 테스트 | '백준·프로그래머스' 알고리즘 유형별 STL 활용법

C++ 코딩 테스트 | '백준·프로그래머스' 알고리즘 유형별 STL 활용법

이 글의 핵심

C++ 코딩 테스트의 C++, 테스트, "백준·프로그래머스", 들어가며: C++ 코딩 테스트 면접, 무엇을 준비해야 할까?를 실전 예제와 함께 상세히 설명합니다.

들어가며: C++ 코딩 테스트 면접, 무엇을 준비해야 할까?

코딩 테스트(알고리즘·자료구조 문제를 제한 시간 안에 코드로 푸는 시험) 면접은 대부분 화이트보드 또는 온라인 IDE에서 30~60분 안에 알고리즘 문제를 푸는 형태입니다. 회사마다 난이도는 다르지만, 자료구조·알고리즘 기본기C++ STL 활용 능력을 평가합니다. 이 글은 자주 나오는 문제 유형, STL 필수 함수, 실전 팁을 정리한 면접 준비 가이드입니다.

이 글에서 다루는 것:

  • 코딩 테스트 면접에서 자주 나오는 알고리즘 유형 7가지
  • C++ STL 필수 함수 정리 (vector, map, set, algorithm)
  • 시간복잡도 분석과 최적화 전략
  • 실전 팁: 입출력 최적화, 엣지 케이스, 코드 가독성
  • 면접 당일 체크리스트

코딩 테스트에서 자주 나오는 알고리즘 유형준비 흐름을 요약하면 아래와 같습니다.

flowchart LR
  subgraph type[유형]
    S[정렬·탐색]
    D[DP]
    G[그래프]
    T[트리]
  end
  subgraph prep[준비]
    STL[STL 활용]
    IO[입출력 최적화]
    TC[시간복잡도]
  end
  type --> prep

1. 자주 나오는 알고리즘 유형 7가지

1) 정렬과 탐색

대표 문제:

  • 배열 정렬 후 특정 값 찾기 (이진 탐색)
  • K번째 큰/작은 원소 찾기
  • 두 배열의 교집합·합집합

핵심 STL:

  • std::sort(v.begin(), v.end())
  • std::binary_search, std::lower_bound, std::upper_bound
  • std::nth_element (K번째 원소)

언제 정렬을 쓰나요?
정렬은 O(N log N)이라 비싼 연산이지만, 정렬 후에는 이진 탐색(O(log N)), 투 포인터(O(N)) 같은 효율적인 알고리즘을 쓸 수 있습니다. 무식하게 O(N²)로 풀 문제를 정렬 + 이진 탐색으로 O(N log N)에 해결할 수 있습니다.

lower_bound vs upper_bound:

  • lower_bound(x): x 이상인 첫 위치
  • upper_bound(x): x 초과인 첫 위치
  • 차이: upper_bound - lower_bound = x의 개수

예시 코드 (복사해 붙여넣은 뒤 g++ -std=c++17 -o binsearch_demo binsearch_demo.cpp && ./binsearch_demo 로 실행 가능):

// 복사해 붙여넣은 뒤: g++ -std=c++17 -o binsearch_demo binsearch_demo.cpp && ./binsearch_demo
#include <vector>
#include <algorithm>
#include <iostream>

int main() {
    std::vector<int> v = {3, 1, 4, 1, 5};
    std::sort(v.begin(), v.end());  // {1, 1, 3, 4, 5}
    bool found = std::binary_search(v.begin(), v.end(), 3);
    auto it = std::lower_bound(v.begin(), v.end(), 3);
    std::cout << found << " " << (it - v.begin()) << "\n";  // 1 2
    return 0;
}

실행 결과: 1 2 (found와 인덱스)가 한 줄 출력됩니다.

2) 해시맵 (빈도수, 중복 체크)

대표 문제:

  • 배열에서 중복 원소 찾기
  • 두 문자열이 애너그램인지 확인
  • 부분합이 K인 구간 개수 (누적합 + 해시맵)

핵심 STL:

  • std::unordered_map<int, int> (O(1) 평균 접근)
  • std::unordered_set<int> (중복 체크)

해시맵의 핵심:
해시맵은 O(1) 평균 시간에 삽입·삭제·탐색이 가능합니다. 이중 반복문으로 O(N²)에 풀어야 할 문제를 O(N)에 해결할 수 있는 경우가 많습니다.

Two Sum 문제 예시:
“배열에서 합이 K인 두 원소 찾기”

무식한 방법 (O(N²)):

for (int i = 0; i < n; ++i) {
    for (int j = i+1; j < n; ++j) {
        if (arr[i] + arr[j] == K) { /* 찾음 */ }
    }
}

해시맵 방법 (O(N)):

std::unordered_set<int> seen;
for (int x : arr) {
    if (seen.count(K - x)) { /* 찾음 */ }
    seen.insert(x);
}

예시 코드:

std::unordered_map<int, int> freq;
for (int x : arr) {
    freq[x]++;
}

// 가장 빈도 높은 원소
int maxFreq = 0, result = 0;
for (auto& [num, cnt] : freq) {
    if (cnt > maxFreq) {
        maxFreq = cnt;
        result = num;
    }
}

3) 투 포인터 (Two Pointers)

대표 문제:

  • 정렬된 배열에서 합이 K인 두 원소 찾기
  • 부분 배열의 합이 K 이하인 최대 길이
  • 회문(Palindrome) 판별

핵심 아이디어:

  • 왼쪽(left)과 오른쪽(right) 포인터를 동시에 이동하며 O(N)에 해결

예시 코드:

// 정렬된 배열에서 합이 target인 두 원소
std::vector<int> v = {1, 2, 3, 4, 5};
int target = 7;
int left = 0, right = v.size() - 1;

while (left < right) {
    int sum = v[left] + v[right];
    if (sum == target) {
        std::cout << v[left] << ", " << v[right] << '\n';
        break;
    } else if (sum < target) {
        left++;
    } else {
        right--;
    }
}

4) 동적 계획법 (Dynamic Programming, DP)

DP(동적 계획법—작은 부분 문제의 답을 저장해 두고 큰 문제를 풀 때 재사용하는 알고리즘 기법)의 대표 문제는 다음과 같습니다.

대표 문제:

  • 피보나치 수열
  • 최장 증가 부분 수열 (LIS)
  • 배낭 문제 (Knapsack)
  • 최단 경로 (DP + 그래프)

핵심 아이디어:

  • 메모이제이션: 이미 계산한 값을 배열에 저장해서 재사용

DP를 쓰는 이유:
재귀로 풀면 중복 계산이 많습니다. 예를 들어 fib(5)를 계산할 때:

  • fib(5) = fib(4) + fib(3)
  • fib(4) = fib(3) + fib(2)
  • fib(3)두 번 계산됩니다.

fib(50)을 순수 재귀로 계산하면 수십억 번 함수 호출이 일어나지만, DP를 쓰면 50번만 계산합니다.

Top-Down vs Bottom-Up:

  • Top-Down (메모이제이션): 재귀 + 캐시. 필요한 값만 계산.
  • Bottom-Up (타뷸레이션): 반복문으로 작은 문제부터 순서대로 계산. 보통 더 빠름.

예시 코드 (피보나치):

std::vector<long long> dp(100, -1);

long long fib(int n) {
    if (n <= 1) return n;
    if (dp[n] != -1) return dp[n];  // 이미 계산됨
    return dp[n] = fib(n-1) + fib(n-2);
}

Bottom-Up 방식 (더 빠름):

std::vector<long long> dp(100);
dp[0] = 0; dp[1] = 1;
for (int i = 2; i < 100; ++i) {
    dp[i] = dp[i-1] + dp[i-2];
}

5) 그래프 탐색 (BFS, DFS)

그래프(정점과 간선으로 이루어진 자료구조. 예: 지도에서 도시=정점, 도로=간선) 탐색의 대표 문제는 다음과 같습니다.

대표 문제:

  • 미로 최단 경로 (BFS)
  • 연결된 컴포넌트 개수 (DFS/BFS)
  • 사이클 탐지
  • 위상 정렬

핵심 STL:

  • std::queue<int> (BFS)
  • std::stack<int> 또는 재귀 (DFS)
  • std::vector<std::vector<int>> (인접 리스트)

BFS 예시:

std::vector<std::vector<int>> graph(n);
std::vector<bool> visited(n, false);
std::queue<int> q;

q.push(start);
visited[start] = true;

while (!q.empty()) {
    int node = q.front();
    q.pop();
    
    for (int neighbor : graph[node]) {
        if (!visited[neighbor]) {
            visited[neighbor] = true;
            q.push(neighbor);
        }
    }
}

6) 그리디 (Greedy)

대표 문제:

  • 회의실 배정 (활동 선택 문제)
  • 동전 거스름돈 (특정 조건)
  • 최소 신장 트리 (Kruskal, Prim)

핵심 아이디어:

  • 매 순간 최선의 선택을 하면 전체 최적해가 나오는 경우

예시 코드 (회의실 배정):

struct Meeting {
    int start, end;
};

std::vector<Meeting> meetings = {{1, 3}, {2, 4}, {3, 5}};

// 끝나는 시간 기준 정렬
std::sort(meetings.begin(), meetings.end(),  {
    return a.end < b.end;
});

int count = 0, lastEnd = 0;
for (auto& m : meetings) {
    if (m.start >= lastEnd) {
        count++;
        lastEnd = m.end;
    }
}

7) 백트래킹 (Backtracking)

대표 문제:

  • N-Queen
  • 순열·조합 생성
  • 스도쿠 풀이

핵심 아이디어:

  • 재귀적으로 모든 경우를 시도하되, 조건에 맞지 않으면 즉시 되돌아옴

예시 코드 (순열):

void permute(std::vector<int>& nums, int start) {
    if (start == nums.size()) {
        // 순열 하나 완성
        for (int x : nums) std::cout << x << ' ';
        std::cout << '\n';
        return;
    }
    
    for (int i = start; i < nums.size(); ++i) {
        std::swap(nums[start], nums[i]);
        permute(nums, start + 1);
        std::swap(nums[start], nums[i]);  // 백트래킹
    }
}

또는 STL:

std::vector<int> v = {1, 2, 3};
std::sort(v.begin(), v.end());
do {
    for (int x : v) std::cout << x << ' ';
    std::cout << '\n';
} while (std::next_permutation(v.begin(), v.end()));

2. C++ STL 필수 함수 정리

vector

std::vector<int> v = {1, 2, 3};
v.push_back(4);           // 끝에 추가
v.pop_back();             // 끝에서 제거
v.size();                 // 크기
v.empty();                // 비어 있는지
v.clear();                // 전체 삭제
v[0];                     // 인덱스 접근 (범위 체크 X)
v.at(0);                  // 범위 체크 O (예외 발생)

map (정렬된 키)

std::map<std::string, int> m;
m[apple] = 1;
m[banana] = 2;

if (m.count("apple")) {   // 키 존재 여부
    std::cout << m[apple] << '\n';
}

for (auto& [key, val] : m) {  // 키 순서대로 순회
    std::cout << key << ": " << val << '\n';
}

unordered_map (해시맵, O(1) 평균)

std::unordered_map<int, int> freq;
for (int x : arr) {
    freq[x]++;
}

set (중복 없는 정렬된 집합)

std::set<int> s = {3, 1, 4, 1, 5};  // {1, 3, 4, 5}
s.insert(2);
s.erase(3);
bool exists = s.count(4);  // 1 (있음) 또는 0 (없음)

algorithm 헤더

#include <algorithm>

std::sort(v.begin(), v.end());                    // 오름차순 정렬
std::sort(v.begin(), v.end(), std::greater<>());  // 내림차순

std::reverse(v.begin(), v.end());                 // 뒤집기

auto it = std::find(v.begin(), v.end(), 42);      // 값 찾기
if (it != v.end()) { /* 찾음 */ }

int maxVal = *std::max_element(v.begin(), v.end());
int minVal = *std::min_element(v.begin(), v.end());

std::next_permutation(v.begin(), v.end());        // 다음 순열

3. 시간복잡도 분석과 최적화

자주 나오는 시간복잡도

복잡도N=100N=10,000N=1,000,000예시 알고리즘
O(1)111해시맵 접근
O(log N)71320이진 탐색
O(N)10010,0001,000,000선형 탐색, 순회
O(N log N)700130,00020,000,000정렬 (merge sort)
O(N²)10,000100,000,0001,000,000,000,000이중 반복문
O(2^N)1.3×10³⁰--완전 탐색 (백트래킹)

제한 시간과 복잡도

1초 제한에서 대략:

  • O(N): N ≤ 10⁸
  • O(N log N): N ≤ 10⁶
  • O(N²): N ≤ 10⁴
  • O(N³): N ≤ 500

왜 이런 기준인가요?
현대 컴퓨터는 1초에 약 10⁸~10⁹ 번의 기본 연산을 수행할 수 있습니다. 하지만 실제 알고리즘은 기본 연산 외에 함수 호출, 메모리 접근, 분기 등의 오버헤드가 있으므로, 안전하게 10⁸ 정도로 잡습니다.

구체적인 예시:

  • N=10⁶, O(N²) → 10¹² 연산 → 1000초 (시간 초과)
  • N=10⁶, O(N log N) → 2×10⁷ 연산 → 0.2초 (통과)

면접에서 자주 하는 실수: O(N²) 알고리즘을 N=10⁶ 입력에 적용 → 시간 초과

: 문제에서 N의 범위를 보고 허용되는 복잡도를 역산하세요.

  • N ≤ 10 → O(N!) 가능 (완전 탐색)
  • N ≤ 20 → O(2^N) 가능 (비트마스크 DP)
  • N ≤ 500 → O(N³) 가능 (플로이드-워셜)
  • N ≤ 10⁴ → O(N²) 가능 (이중 반복문)
  • N ≤ 10⁶ → O(N log N) 필요 (정렬, 세그먼트 트리)
  • N ≤ 10⁸ → O(N) 필요 (선형 알고리즘)

최적화 전략

1. 불필요한 반복 제거:

// ❌ 매번 size() 호출
for (int i = 0; i < v.size(); ++i) { }

// ✅ 한 번만 계산
int n = v.size();
for (int i = 0; i < n; ++i) { }

2. 해시맵으로 O(N²) → O(N):

// ❌ O(N²)
for (int i = 0; i < n; ++i) {
    for (int j = i+1; j < n; ++j) {
        if (arr[i] + arr[j] == target) { /* ....*/ }
    }
}

// ✅ O(N)
std::unordered_set<int> seen;
for (int x : arr) {
    if (seen.count(target - x)) {
        // 찾음
    }
    seen.insert(x);
}

3. 정렬 활용:

정렬하면 O(N log N)이지만, 이후 이진 탐색·투 포인터로 O(N²) → O(N log N) 또는 O(N) 가능.


2. C++ STL 필수 함수 정리

컨테이너 선택 가이드

요구사항추천 컨테이너시간복잡도
순서 유지, 빠른 접근vector접근 O(1), 삽입/삭제 O(N)
중복 없는 집합, 정렬set삽입/삭제/탐색 O(log N)
중복 없는 집합, 순서 무관unordered_set평균 O(1)
키-값 쌍, 정렬mapO(log N)
키-값 쌍, 순서 무관unordered_map평균 O(1)
큐 (FIFO)queueO(1)
스택 (LIFO)stackO(1)
우선순위 큐priority_queue삽입/삭제 O(log N)

algorithm 헤더 자주 쓰는 함수

#include <algorithm>

// 정렬
std::sort(v.begin(), v.end());
std::sort(v.begin(), v.end(),  { return a > b; });  // 내림차순

// 탐색
auto it = std::find(v.begin(), v.end(), 42);
bool found = std::binary_search(v.begin(), v.end(), 42);  // 정렬 필요

// 최소/최대
int maxVal = *std::max_element(v.begin(), v.end());
int minVal = *std::min_element(v.begin(), v.end());

// 중복 제거 (정렬 후)
std::sort(v.begin(), v.end());
v.erase(std::unique(v.begin(), v.end()), v.end());

// 순열
std::next_permutation(v.begin(), v.end());

// 부분 정렬 (K번째 원소)
std::nth_element(v.begin(), v.begin() + k, v.end());

string 함수

std::string s = "hello";
s.size();                     // 길이
s.substr(1, 3);               // "ell" (시작 인덱스, 길이)
s.find("ll");                 // 2 (위치), 없으면 std::string::npos
s.rfind("l");                 // 3 (뒤에서부터 찾기)

// 문자열 → 숫자
int num = std::stoi("123");
long long big = std::stoll("123456789012");

// 숫자 → 문자열
std::string str = std::to_string(123);

4. 실전 팁: 입출력, 엣지 케이스, 가독성

입출력 최적화

백준·프로그래머스 같은 온라인 저지에서는 입출력이 많으면 시간 초과가 날 수 있습니다.

#include <bits/stdc++.h>
using namespace std;

int main() {
    ios_base::sync_with_stdio(false);  // ✅ C 스트림과 동기화 끄기
    cin.tie(NULL);                     // ✅ cin/cout 버퍼 분리
    
    int n;
    cin >> n;
    
    // 출력은 endl 대신 '\n'
    cout << n << '\n';  // ✅ 빠름
    // cout << n << endl;  // ❌ 매번 flush로 느림
    
    return 0;
}

왜 이렇게 해야 하나요?

sync_with_stdio(false):
기본적으로 C++ 스트림(cin, cout)과 C 스트림(scanf, printf)은 동기화되어 있습니다. 섞어 써도 출력 순서가 보장됩니다. 하지만 이 동기화는 오버헤드가 큽니다. C 스트림을 안 쓴다면, 동기화를 끄면 2~3배 빨라집니다.

cin.tie(NULL):
기본적으로 cincout묶여(tie) 있습니다. cin으로 입력받기 전에 cout 버퍼를 자동으로 flush합니다. 이는 대화형 프로그램에서는 유용하지만, 코딩 테스트에서는 불필요한 flush로 느려집니다.

endl vs \n:
endl은 줄바꿈 + 버퍼 flush입니다. 출력이 10만 번이면 10만 번 flush가 일어나 극도로 느립니다. '\n'은 줄바꿈만 하고, 버퍼는 자동으로 또는 프로그램 종료 시 flush됩니다.

실전 효과:
입력 10만 줄, 출력 10만 줄인 문제에서:

  • 최적화 없음: 3~5초 (시간 초과)
  • 최적화 적용: 0.3~0.5초 (통과)

관련 글: C++ 코딩테스트 입출력 치트시트

엣지 케이스 체크

면접관이 자주 확인하는 것:

  • 빈 입력 (N=0, 빈 배열)
  • 최소/최대값 (N=1, N=10⁶)
  • 중복 원소 (모든 원소가 같음)
  • 음수·0 (문제에서 양수만 가정하지 않았는지)
  • 오버플로우 (int 범위 초과 → long long 사용)

예시:

// ❌ N=0일 때 크래시
int maxVal = v[0];
for (int x : v) maxVal = std::max(maxVal, x);

// ✅ 빈 배열 처리
if (v.empty()) return -1;  // 또는 예외 처리
int maxVal = *std::max_element(v.begin(), v.end());

코드 가독성

면접에서는 정답만큼 “읽기 쉬운 코드”도 중요합니다.

1. 의미 있는 변수명:

// ❌
int a = 0, b = 0;

// ✅
int leftPointer = 0, rightPointer = n - 1;

2. 함수 분리:

// ✅ 복잡한 로직은 함수로 분리
bool isPrime(int n) {
    if (n < 2) return false;
    for (int i = 2; i * i <= n; ++i) {
        if (n % i == 0) return false;
    }
    return true;
}

3. 주석 (필요 시):

// 투 포인터로 합이 target인 쌍 찾기
int left = 0, right = n - 1;

5. 면접 당일 체크리스트

문제 이해 단계 (5분)

  • 입력 형식과 범위 확인 (N ≤ ?, 음수 가능?)
  • 출력 형식 확인 (여러 줄? 공백 구분?)
  • 예제 입력·출력 손으로 따라가 보기
  • 엣지 케이스 생각해 보기 (N=0, N=1, 중복, 최대값)

알고리즘 설계 단계 (5~10분)

  • 무식한 방법(Brute Force)의 시간복잡도 계산
  • 제한 시간 내에 가능한지 판단
  • 최적화 방법 떠올리기 (정렬? 해시맵? DP?)
  • 면접관에게 접근법 설명 (화이트보드 면접 시 필수)

코딩 단계 (15~30분)

  • 입출력 최적화 템플릿 복붙 (sync_with_stdio, cin.tie)
  • 함수·변수명 명확하게
  • 반복문 범위 확인 (< vs <=, 인덱스 0 vs 1)
  • 오버플로우 체크 (int vs long long)

테스트 단계 (5~10분)

  • 예제 입력으로 실행
  • 엣지 케이스 직접 테스트 (N=0, N=1, 최대값)
  • 시간복잡도 다시 확인

설명 단계 (면접관에게)

  • 알고리즘 접근법 설명
  • 시간복잡도·공간복잡도 언급
  • 최적화 가능한 부분 언급 (시간이 남으면)

자주 나오는 면접 질문

1. “시간복잡도가 어떻게 되나요?”

답변 예시:

“정렬에 O(N log N), 이후 투 포인터로 O(N)이므로, 전체 O(N log N)입니다.”

2. “공간복잡도는요?”

답변 예시:

“입력 배열 외에 해시맵을 쓰므로 최악의 경우 O(N)입니다.”

3. “더 최적화할 수 있나요?”

답변 예시:

“현재 O(N log N)인데, 입력이 특정 범위로 제한되어 있다면 카운팅 정렬로 O(N)까지 줄일 수 있습니다.”

4. “엣지 케이스는 어떻게 처리하나요?”

답변 예시:

“N=0일 때는 빈 배열을 반환하고, N=1일 때는 첫 원소를 바로 반환하도록 예외 처리했습니다.”


실전 준비 로드맵

1단계: 기본 자료구조·알고리즘 복습 (1~2주)

  • 자료구조: 배열, 연결 리스트, 스택, 큐, 해시맵, 트리, 힙
  • 알고리즘: 정렬, 탐색, 재귀, DP, 그래프(BFS/DFS), 그리디

추천 자료:

  • 백준 단계별로 풀어보기
  • 프로그래머스 Level 1~2

2단계: 유형별 문제 풀이 (2~3주)

  • 정렬·탐색: 백준 10문제
  • DP: 백준 10문제 (피보나치, LIS, 배낭)
  • 그래프: BFS/DFS 각 5문제
  • 그리디: 5문제
  • 투 포인터·슬라이딩 윈도우: 5문제

3단계: 모의 면접 (1주)

  • 타이머 30분 설정하고 문제 풀기
  • 화이트보드에 손으로 써 보기 (타이핑 없이)
  • 친구·동료와 모의 면접 (설명 연습)

4단계: 기출 문제 풀이

  • 지원하는 회사의 코딩 테스트 후기 검색 (백준, 프로그래머스 등)
  • 비슷한 유형 집중 연습

면접 중 커뮤니케이션 팁

1. 문제를 이해했는지 확인

“제가 이해한 게 맞는지 확인하고 싶은데요, 입력은 N개의 정수 배열이고, 합이 K인 두 원소의 인덱스를 반환하는 거 맞나요?“

2. 접근법 먼저 설명

“먼저 배열을 정렬하고, 투 포인터로 양 끝에서 좁혀 가며 합을 확인하겠습니다. 시간복잡도는 O(N log N)입니다.”

3. 막히면 힌트 요청

“지금 DP 테이블을 어떻게 정의해야 할지 고민 중인데, 힌트를 주실 수 있을까요?“

4. 트레이드오프 언급

“해시맵을 쓰면 O(N)이지만 공간복잡도가 O(N)이고, 정렬하면 O(N log N)이지만 공간은 O(1)입니다. 어느 쪽이 나을까요?”


자주 하는 실수

1. 입출력 최적화 안 함

대량 입출력 문제에서 sync_with_stdio(false), cin.tie(NULL) 없이 제출 → 시간 초과

2. int 오버플로우

int a = 1000000, b = 1000000;
int result = a * b;  // ❌ int 범위 초과 (2×10¹²)

해결:

long long result = (long long)a * b;  // ✅

3. 배열 범위 초과

int arr[100];
for (int i = 0; i <= 100; ++i) {  // ❌ i=100은 범위 초과
    arr[i] = 0;
}

해결: i < 100 또는 vectorat() 사용.

4. 정렬 안 하고 이진 탐색

binary_search정렬된 배열에서만 작동합니다.

std::vector<int> v = {3, 1, 4};
bool found = std::binary_search(v.begin(), v.end(), 3);  // ❌ 정렬 안 됨

해결:

std::sort(v.begin(), v.end());
bool found = std::binary_search(v.begin(), v.end(), 3);  // ✅

추천 연습 플랫폼

플랫폼특징추천 대상
백준(BOJ)한국어, 단계별 문제, 다양한 난이도국내 취준생
프로그래머스한국어, 기업 기출 문제국내 기업 면접 준비
LeetCode영어, 글로벌 기업 기출 (FAANG)해외 취업, 고난도
Codeforces영어, 경진대회 스타일알고리즘 실력 향상

한 줄 요약: C++ 코딩테스트는 STL·입출력 최적화·자주 쓰는 패턴을 익히고, 백준·프로그래머스로 연습하면 됩니다. 다음으로 입출력 치트시트STL 알고리즘을 읽어보면 좋습니다.


자주 묻는 질문 (FAQ)

Q. C++가 Python보다 코딩 테스트에 유리한가요?

A: 문제에 따라 다릅니다.

  • 유리한 점: 실행 속도가 빠름 (시간 제한 빡빡한 문제)
  • 불리한 점: 코드가 길고, 입출력 설정이 복잡함
  • 결론: 본인이 익숙한 언어를 쓰는 것이 가장 중요합니다.

Q. bits/stdc++.h는 항상 써도 되나요?

A: 온라인 저지(백준, 프로그래머스)에서는 OK지만, 실무에서는 쓰지 않습니다. 컴파일 시간이 느리고, 이식성이 떨어집니다. 면접에서는 “코딩 테스트용 편의 헤더”라고 설명하면 됩니다.

Q. STL을 모르면 C++ 코딩 테스트는 불가능한가요?

A: 거의 불가능합니다. vector, map, sort 같은 기본 STL 없이 배열·정렬을 직접 구현하면 시간이 부족합니다. 최소한 vector, map, set, sort, find는 익혀야 합니다.

Q. 면접 중에 컴파일 에러가 나면?

A: 당황하지 말고 에러 메시지를 읽고 차근차근 고치세요. 면접관은 디버깅 능력도 평가합니다. “세미콜론을 빠뜨렸네요”라고 말하며 고치면 됩니다.


관련 글


C++ 코딩 테스트 면접알고리즘 지식 + STL 활용 능력 + 시간복잡도 분석을 모두 평가합니다. 위 7가지 유형을 각 10문제씩 풀어 보고, 입출력 최적화 템플릿을 외워 두면 대부분의 문제에 대응할 수 있습니다. 면접 중에는 접근법을 먼저 설명하고, 엣지 케이스를 언급하면 좋은 인상을 줄 수 있습니다. 막히더라도 사고 과정을 소리 내어 말하면서 진행하세요. 면접관은 정답보다 문제 해결 과정을 보고 싶어 합니다.

검색 시 참고 키워드: C++ 코딩테스트, 코딩 테스트 면접 준비, 백준 프로그래머스, STL 알고리즘 유형, 시간복잡도


같이 보면 좋은 글 (내부 링크)

이 주제와 연결되는 다른 글입니다.

이 글에서 다루는 키워드 (관련 검색어)

C++, 코딩테스트, 면접준비, 알고리즘, STL, 시간복잡도, 백준, 프로그래머스 등으로 검색하시면 이 글이 도움이 됩니다.

심화 부록: 구현·운영 관점

이 부록은 앞선 본문에서 다룬 주제(「C++ 코딩 테스트 | ‘백준·프로그래머스’ 알고리즘 유형별 STL 활용법」)를 구현·런타임·운영 관점에서 다시 압축합니다. 도메인별 세부 구현은 글마다 다르지만, 입력 검증 → 핵심 연산 → 부작용(I/O·네트워크·동시성) → 관측의 흐름으로 장애를 나누면 원인 추적이 빨라집니다.

내부 동작과 핵심 메커니즘

flowchart TD
  A[입력·요청·이벤트] --> B[파싱·검증·디코딩]
  B --> C[핵심 연산·상태 전이]
  C --> D[부작용: I/O·네트워크·동시성]
  D --> E[결과·관측·저장]
sequenceDiagram
  participant C as 클라이언트/호출자
  participant B as 경계(런타임·게이트웨이·프로세스)
  participant D as 의존성(API·DB·큐·파일)
  C->>B: 요청/이벤트
  B->>D: 조회·쓰기·RPC
  D-->>B: 지연·부분 실패·재시도 가능
  B-->>C: 응답 또는 오류(코드·상관 ID)
  • 불변 조건(Invariant): 버퍼 경계, 프로토콜 상태, 트랜잭션 격리, FD 상한 등 단계별로 문장으로 적어 두면 디버깅 비용이 줄어듭니다.
  • 결정성: 순수 층과 시간·네트워크·스케줄에 의존하는 층을 분리해야 테스트와 장애 분석이 쉬워집니다.
  • 경계 비용: 직렬화, 인코딩, syscall 횟수, 락 경합, 할당·GC, 캐시 미스를 의심 목록에 둡니다.
  • 백프레셔: 생산자가 소비자보다 빠를 때 버퍼·큐·스트림에서 속도를 줄이는 신호를 어디에 둘지 정의합니다.

프로덕션 운영 패턴

영역운영 관점 질문
관측성요청 단위 상관 ID, 에러율·지연 p95/p99, 의존성 타임아웃·재시도가 대시보드에 보이는가
안전성입력 검증·권한·비밀·감사 로그가 코드 경로마다 일관적인가
신뢰성재시도는 멱등 연산에만 적용되는가, 서킷 브레이커·백오프·DLQ가 있는가
성능캐시·배치 크기·커넥션 풀·인덱스·백프레셔가 데이터 규모에 맞는가
배포롤백 룬북, 카나리/블루그린, 마이그레이션·피처 플래그가 문서화되어 있는가
용량피크 트래픽·디스크·FD·스레드 풀 상한을 주기적으로 검증하는가

스테이징은 데이터 양·네트워크 RTT·동시성을 프로덕션에 가깝게 맞출수록 재현율이 올라갑니다.

확장 예시: 엔드투엔드 미니 시나리오

앞선 본문 주제(「C++ 코딩 테스트 | ‘백준·프로그래머스’ 알고리즘 유형별 STL 활용법」)를 배포·운영 흐름에 맞춰 옮긴 체크리스트입니다. 도메인에 맞게 단계 이름만 바꿔 적용할 수 있습니다.

  1. 입력 계약 고정: 스키마·버전·최대 페이로드·타임아웃·에러 코드를 경계에 둔다.
  2. 핵심 경로 계측: 요청 ID, 단계별 지연, 외부 호출 결과 코드를 로그·메트릭·트레이스에서 한 흐름으로 본다.
  3. 실패 주입: 의존성 타임아웃·5xx·부분 데이터·락 대기를 스테이징에서 재현한다.
  4. 호환·롤백: 설정/마이그레이션/클라이언트 버전을 되돌릴 수 있는지 확인한다.
  5. 부하 후 검증: 피크 대비 p95/p99, 에러율, 리소스 상한, 알림 임계값을 점검한다.
handle(request):
  ctx = newCorrelationId()
  validated = validateSchema(request)
  authorize(validated, ctx)
  result = domainCore(validated)
  persistOrEmit(result, idempotentKey)
  recordMetrics(ctx, latency, outcome)
  return result

문제 해결(Troubleshooting)

증상가능 원인조치
간헐적 실패레이스, 타임아웃, 외부 의존성, DNS최소 재현 스크립트, 분산 트레이스·로그 상관관계, 재시도·서킷 설정 점검
성능 저하N+1, 동기 I/O, 락 경합, 과도한 직렬화, 캐시 미스프로파일러·APM으로 핫스팟 확인 후 한 가지씩 제거
메모리 증가캐시 무제한, 구독/리스너 누수, 대용량 버퍼, 커넥션 미반납상한·TTL·힙/FD 스냅샷 비교
빌드·배포만 실패환경 변수, 권한, 플랫폼 차이, lockfileCI 로그와 로컬 diff, 런타임·이미지 버전 핀
설정 불일치프로필·시크릿·기본값, 리전스키마 검증된 설정 단일 소스와 배포 매트릭스 표준화
데이터 불일치비멱등 재시도, 부분 쓰기, 캐시 무효화 누락멱등 키·아웃박스·트랜잭션 경계 재검토

권장 순서: (1) 최소 재현 (2) 최근 변경 범위 축소 (3) 환경·의존성 차이 (4) 관측으로 가설 검증 (5) 수정 후 회귀·부하 테스트.

배포 전에는 git addgit commitgit pushnpm run deploy 순서를 권장합니다.