| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 자바공부
- 자바
- 정렬
- Java
- 알고리즘공부
- 프로그래밍기초
- 객체지향
- 예외처리
- 자바기초
- 자료구조
- 메모리관리
- 파이썬
- JVM
- 클린코드
- 코딩테스트준비
- 코딩공부
- 프로그래머스
- 자바프로그래밍
- 코딩인터뷰
- 알고리즘
- 자바개발
- 백준
- 코딩테스트팁
- HashMap
- 가비지컬렉션
- 개발자팁
- 멀티스레드
- 개발공부
- 코딩테스트
- 개발자취업
- Today
- Total
코드 한 줄의 기록
입사 코딩테스트 합격하려면 꼭 알아야 할 예외 케이스 처리와 디버깅 실전 팁 본문
코딩테스트를 조금이라도 풀어본 사람이라면 한 번쯤 이런 경험을 했을 것이다.
“로컬 테스트할 땐 다 통과했는데, 제출만 하면 실패”, “예제 입력은 다 맞는데 채점에서 틀렸다고 뜨는 경우”, “시간 초과는 안 나는데 자꾸 한두 개 테스트만 깨지는 경우”.
이런 상황의 대부분은 예외 케이스 미처리와 허술한 디버깅 습관에서 나온다.
이 글은 “나도 계속 공부해 나가면서, 동시에 다른 사람에게도 설명하는” 느낌으로, 실제 코딩테스트 준비 과정에서 바로 써먹을 수 있는 예외 케이스 처리 방법과 디버깅 팁을 정리해 본다.
왜 ‘예외 케이스’에서 자꾸 발목을 잡힐까?
문제를 풀다가 기본 로직은 금방 떠오르는데, 제출하면 70~80%에서만 통과하고 몇 개 테스트가 깨지는 경우가 많다. 이때 대부분의 패턴은 다음 둘 중 하나다.
- 문제에서 “특별히 강조하지 않은 조건”을 놓친 경우
- 데이터 범위와 극단값(최대/최소)을 신경 쓰지 않은 경우
코딩테스트 문제는 출제자가 “여기에서 자주 틀리더라” 싶은 패턴을 알고 의도적으로 케이스를 넣는다. 그래서 예외 케이스를 잘 잡는 연습만으로도 같은 알고리즘 실력을 가진 사람들 사이에서 한 단계 위로 올라갈 수 있다.
예외 케이스를 잘 처리하기 위해서는 두 가지를 반드시 습관으로 만들면 좋다.
- 코드 작성 전, 머릿속/메모장으로 입력 케이스를 직접 설계해 보기
- 풀이를 완성한 후, ‘틀리기 쉬운 상황’을 일부러 만들어서 찍어보기
이 두 가지를 코딩테스트 연습할 때마다 의식적으로 반복하면, 자연스럽게 예외를 먼저 떠올리는 사고 방식이 몸에 배게 된다.
코딩테스트에서 자주 등장하는 예외 케이스 유형
예외 케이스라고 해서 특별한 게 아니다. 계속 반복되는 패턴이 있다. 문제를 읽을 때, 코드 짜기 전에 다음 체크리스트를 한 번 훑어보자.
최소/최대 크기(경계값) 케이스
- 배열/리스트 길이가 0, 1, 2 같은 극단적으로 작은 값일 때
- (N), (M) 같은 입력의 크기가 문제에서 주어진 최대값일 때
- 값 자체가 최대 정수, 최소 정수에 가깝게 들어올 때 (예: 10억, -10억)
예시로 정렬 후 인접 원소 차이를 비교하는 문제가 있다면
N = 1인 경우: 인접 원소가 아예 없는데 코드에서for (i in 0 until n-1)돌리면?N = 2인데 인덱스 접근을 실수하면?
그래서 항상 코드 짜기 전에 이렇게 스스로 질문해보는 습관이 필요하다.
- “길이가 0이면?”, “길이가 1이면?”, “길이가 2면?”
- “입력 수가 최대인 경우, 지금 알고리즘 시간복잡도로 버틸 수 있나?”
이 질문만 해봐도 적어도 인덱스 에러나 단순 로직 버그는 많이 줄어든다.
정렬/탐색에서의 동점, 중복 값
- 점수 순 정렬, 키/몸무게 정렬 등에서 값이 같은 경우(동점) 정렬 기준을 잘못 처리
- 해시맵/딕셔너리에서 같은 키가 여러 번 들어올 때 누적을 안 하고 덮어쓰기만 할 때
예를 들어 “점수 내림차순, 점수 같으면 이름 사전순”이라고 했는데, 점수만 기준으로 정렬하면 동점일 때 순서가 잘못될 수 있다.
또 “이름별 등장 횟수”를 세는 문제에서, 이미 존재하는 키에 대해 count[name] = 1로 덮어써버리는 실수도 흔하다.
이런 문제를 막으려면
- 문제에서 동점, 중복이 나올 수 있는지 꼭 확인
- 정렬 기준을 최종 정렬 조건 그대로 구현 (복합 정렬 기준)
- 해시맵/딕셔너리 사용할 때는 “기존 값에 누적하는지” 항상 의식하기
나누기, 나머지, 음수/0 처리
- 나누는 값이 0이 될 수 있는지
- 음수를 다뤄야 할 때, 언어별 나머지 연산 결과 차이
예를 들어 평균 계산할 때, 분모가 0이 되면 안 되는데, 그룹에 속한 원소가 하나도 없는 케이스가 나올 수 있다. 조건에서 “항상 한 명 이상”이라고 보장해 주지 않았다면, 스스로 이 케이스를 생각해야 한다.
또 언어에 따라 (-1 mod 3) 결과가 다를 수 있다. 자바, 파이썬, C++ 등은 대부분 음수 나머지를 허용하지만, 결과값의 부호는 언어마다 정의가 조금씩 다르다. 코딩테스트에서 흔히 나오는 패턴은 아니지만, 그래프/수학 관련 문제에서 슬쩍 낚싯줄처럼 등장하는 경우가 있다.
문자열 처리에서의 공백, 빈 문자열, 줄바꿈
- 입력이 빈 문자열인 경우
- 문자열 앞/뒤에 공백이 붙어 있는 경우
- 줄바꿈이 애매하게 들어오거나, 마지막에 공백 줄이 하나 더 있는 경우
특히 코딩테스트 플랫폼마다 입력 형식이 조금씩 달라서, split(" ") 같은 식으로 고정 공백 기준으로 자르면 연속 공백이나 탭 문자에서 오작동할 수 있다.
언어별로 split 계열 함수의 옵션(정규식인지, 연속 공백 처리 방식 등)을 대략적으로라도 알아두면 예외를 덜 맞는다.
연습할 때는 스스로 테스트 케이스를 만들 때 다음을 꼭 섞어보자.
- 문자열 길이가 0인 입력
- 공백만 잔뜩 있는 입력
" " - 탭 문자, 여러 개의 공백이 섞인 입력
그래프/트리에서의 고립 노드, 단일 노드
- 연결 요소가 여러 개 있을 때(완전 연결 그래프가 아님)
- 간선이 하나도 없는 노드가 있을 때
- 노드가 1개밖에 없는 그래프 (N=1)
예를 들어 DFS/BFS 문제를 풀 때, 방문 배열을 초기화하는 시점, 반복문에서 시작 정점을 어떻게 잡는지에 따라 고립 노드가 빠질 수 있다.
그래서 테스트 케이스를 직접 만들 때는
- N=1, 간선 0개
- N이 작고, 간선이 매우 적은(거의 없는) 그래프
- 여러 연결 요소로 나뉘어진 그래프
이 세 가지는 항상 별도로 확인해 보는 것이 좋다.
예외 케이스를 체계적으로 찾는 체크리스트
코드를 다 짰다고 바로 제출하는 대신, 5분만 투자해서 체크리스트를 돌려보는 습관을 만들어 보자.
다음 질문을 하나하나 스스로에게 던져보면 좋다.
- 입력 크기가 최소일 때(0, 1, 2) 코드가 정상 동작하는가?
- 입력 크기가 최대일 때 시간복잡도, 메모리가 버티는가?
- 정렬/탐색에서 동점, 중복 값이 들어오면 의도한 대로 동작하는가?
- 나누기/나머지 연산에서 0이나 음수가 들어와도 안전한가?
- 문자열 앞뒤 공백, 빈 문자열, 줄바꿈 케이스도 처리됐는가?
- 그래프/트리 문제라면, 고립 노드, 단일 노드 케이스를 처리했는가?
- 배열/리스트 인덱스에서
-1,n같은 잘못된 접근 가능성은 없는가?
처음에는 이걸 전부 생각하는 것이 피곤할 수 있지만, 몇 번만 의식적으로 반복하면 자연스럽게 머릿속에서 자동으로 체크가 돌아간다.
실제로 합격하는 사람들과 아슬아슬하게 떨어지는 사람들의 차이는 이런 “습관”에서 나온다.
디버깅 사고방식: “버그를 찾는 방법”을 연습하자
예외 케이스를 잘 떠올리는 것도 중요하지만, 현실에서는 코드가 이미 틀렸을 때, 어디가 문제인지 빨리 찾는 능력이 훨씬 중요하다.
코딩테스트 디버깅에서 중요한 포인트는 크게 두 가지다.
- 증상이 아니라 원인에 집중하기
- “한 번에 고치려는 욕심”을 버리고, 문제를 쪼개서 좁혀 가기
예를 들어, 채점 결과에서 “오답”이 떴다고 할 때 많은 사람이 하는 실수는
- 전체 로직을 다시 머릿속에서 시뮬레이션하면서 “대충 맞는 것 같은데…” 상태에 빠지는 것
- 작은 로그를 찍어보지 않고, 감으로 한두 줄 고쳐서 다시 제출해 보는 것
좋은 디버깅 습관은 다음 순서로 진행된다.
- 문제가 되는 입력을 하나라도 찾는다.
- 직접 다양한 케이스를 만들어보다가 깨지는 입력을 찾거나,
- 로컬에 비슷한 상황을 강제로 만들어 본다.
- 그 입력 하나만 가지고 코드를 한 줄씩 따라간다.
- 중요한 지점마다 출력(log)을 찍어서 중간 상태를 본다.
- “실제 값”과 “원래 기대한 값”의 차이가 처음으로 발생하는 지점을 찾는다.
- 그 지점이 바로 로직이 어긋난 곳이다.
즉, 전체 코드가 막연히 틀린 게 아니라, 어디서부터 잘못됐는지 경계선을 찾는 과정이 디버깅이다.
실전 디버깅 팁: 로그를 “전략적으로” 찍자
온라인 코딩테스트 환경에서는 println이나 System.out.println 같은 출력이 디버깅의 거의 전부다. 이 단순한 출력도 “어디에, 무엇을” 찍느냐에 따라 효율이 완전히 달라진다.
“입력 → 중간 상태 → 결과”의 3단계로 찍기
디버깅할 때는 적어도 다음 세 지점을 확인해 보자.
- 입력을 제대로 읽어왔는지
- 핵심 로직을 통과한 직후, 중간 결과가 예상과 같은지
- 최종 출력 직전에 값이 의도한 대로 나왔는지
예문을 들면, 정렬 후 슬라이싱을 하는 문제라면
- 정렬 직후 배열 상태
- 슬라이싱한 범위
- 슬라이싱 결과
이 세 가지만 봐도 상당수 버그를 바로 찾을 수 있다.
모든 반복마다 찍지 말고, “경계 지점”만 찍기
for/while 문 안에 매번 로그를 찍으면, 입력이 조금만 커져도 출력이 폭발해서 오히려 디버깅이 힘들어진다.
그래서 다음과 같은 지점을 골라서 찍는 것이 좋다.
- 첫 번째 반복, 마지막 반복
- 인덱스가 경계인 지점 (예: 0, n-1, n-2)
- 조건문이 분기되는 지점(조건이 참일 때/거짓일 때 하나씩)
반복문 안에서 “특정 조건을 만족하는 원소만 출력”하는 식으로 필터링해서 찍어도 좋다.
단계별로 출력 포맷을 정해두기
디버깅할 때 출력 포맷을 대충 찍으면, 나중에 로그를 읽다가 헷갈리기 쉽다. 간단히라도 패턴을 정해 두자.
[STEP1],[STEP2]처럼 단계 번호를 붙이기"before sort: ...","after sort: ..."처럼 상황을 구분해서 출력"i=3, val=10"형태로 인덱스와 값을 같이 출력
이렇게 포맷을 통일하면, 여러 번 디버깅해도 로그를 빠르게 스캔할 수 있다.
시간 초과(TLE) 디버깅: 로직이 맞아도 시간에서 터질 때
많은 경우, 예외 케이스 이전에 시간복잡도 때문에 터지는 실수가 있다. 이때는 단순 로직 디버깅이 아니라, 어디에서 O(N²)이 나오는지 구조를 잡아내는 것이 핵심이다.
체크 포인트는 다음과 같다.
- 이중 for문(
for i in ... for j in ...)이 있는 부분에서, 최악의 경우 반복 횟수를 곱셈으로 계산해 본다. - 재귀/DFS/BFS에서 같은 노드를 여러 번 방문하고 있지는 않은지 확인한다.
- 정렬, 우선순위 큐, 해시맵 등 더 나은 자료구조로 바꿀 수 있는 부분이 있는지 본다.
시간 초과 디버깅도 결국은 “어디서 문제인지 좁혀 가는 작업”이다. 입력을 조금씩 키워보면서, 어느 순간부터 급격히 느려지는지 체감해 보는 것도 도움이 된다.
입사 코딩테스트용 루틴: 문제 한 개 풀 때 연습 루트
실전에서 긴장하지 않으려면, 평소 연습할 때부터 같은 루틴으로 움직이는 것이 좋다. 예를 들어 다음과 같은 흐름을 몸에 익혀 보자.
- 문제를 읽으면서 입력/출력 예시를 직접 손으로 다시 적어본다.
- 바로 코드를 치지 말고, 간단한 케이스 + 극단 케이스를 메모장에 먼저 써 본다.
- 최소 입력, 최대 입력
- 동점/중복
- 공백/빈값
- 큰 흐름을 종이에 간단히 쓰고 나서 코드를 구현한다.
- 구현이 끝나면, 아까 적어 둔 테스트 케이스로 로컬에서 직접 돌려 본다.
- 한 번에 맞으면 좋지만, 틀리면 디버깅 모드로 전환한다.
- 문제 되는 케이스를 찾고
- 중간 상태를 찍어 보며, 로직이 어긋나는 최초 지점을 찾는다.
- 최종적으로 AC(통과)를 받으면, 어디서 헷갈렸는지, 무슨 예외 케이스를 추가로 떠올렸는지를 짧게라도 기록한다.
- 블로그에 정리하면서, 그때 그때 배운 예외 케이스 패턴을 쌓아가기
이 루틴을 그대로 블로그에 시리즈처럼 정리해 두면, 나중에 다시 볼 때도 좋고 면접 때 “코딩테스트를 어떻게 준비했는지” 설명할 때도 큰 도움이 된다.
블로그용으로 예외 케이스/디버깅 글을 쓸 때의 팁
“나도 공부하면서 정리하고, 다른 사람도 보게 하자”는 컨셉으로 글을 쓸 거라면, 다음 구성을 기준으로 시리즈를 기획해 볼 수 있다.
- 1편: 예외 케이스 개념 정리 + 공통 패턴 소개
- 2편: 자료구조별(배열/문자열/그래프) 실전 예외 케이스 모음
- 3편: 디버깅 기본기 – 로그 찍는 위치, 생각하는 방법
- 4편: 시간 초과/메모리 초과 디버깅 사례
- 5편: 코딩테스트 복기 노트 작성법 (틀린 문제 기록하는 법)
각 글마다 실제로 풀었던 문제를 예로 들어
- 처음에 어떤 예외 케이스를 놓쳤는지
- 그걸 어떻게 찾아냈는지(어떤 로그를 찍었는지)
- 다시 풀면 어디에 주의할 것인지
이 세 가지 포인트를 구체적으로 써주면, 보는 사람도 공감하기 쉽고, 작성자 본인도 기억에 오래 남는다.
앞으로 연습하면서 같이 챙겨볼 포인트 정리
마무리로, 입사 코딩테스트를 준비하면서 예외 케이스와 디버깅 쪽에서 계속 의식해야 할 포인트를 다시 한 번 묶어보자.
- 코드 치기 전에 예외 케이스를 먼저 떠올리는 습관을 들이자.
- 최소/최대 크기, 동점/중복, 빈 문자열, 고립 노드 등
- 한 번에 정답을 맞추려 하지 말고, “틀려도 금방 고치면 된다”는 마인드로 디버깅 루틴을 정해 두자.
- 문제 되는 입력 하나 찾기 → 중간 상태 출력 → 최초로 어긋나는 지점 찾기
- 디버깅용 출력은 전략적으로 찍자.
- 입력, 핵심 중간 상태, 최종 결과
- 경계 인덱스, 조건 분기 시점
- 연습이 끝나면, 그날 틀렸던 문제의 예외 케이스와 디버깅 과정을 블로그에 한 번씩 정리하자.
- “오늘도 감으로 풀다가 예외 케이스 맞았다”라는 기록이 몇 번만 쌓여도, 다음부터는 감으로 안 풀게 된다.
결국 코딩테스트는 단순히 알고리즘 지식만 보는 시험이 아니라, 문제를 꼼꼼히 읽고, 예외 케이스를 스스로 찾아내고, 틀렸을 때 차분하게 원인을 좁혀 가는 실력을 함께 본다.
이 글에서 정리한 예외 케이스 패턴과 디버깅 습관을 연습 때부터 의식적으로 적용해 보면, 실제 입사 코딩테스트에서도 훨씬 안정적으로 점수를 만들어 낼 수 있을 것이다.
앞으로 다른 문제를 풀면서도 “이번 문제에서는 어떤 예외 케이스가 있었나?”, “디버깅할 때 어디부터 확인했더라?”를 하나씩 정리해 나가면, 이 글 자체도 계속 확장해 나갈 수 있다.
이런 식으로 공부 과정을 공유하는 글을 쌓다 보면, 어느 순간에는 “코딩테스트 잘 보는 사람”이 아니라, “코딩테스트를 잘 준비하는 방법을 설명할 수 있는 사람”이 되어 있을 것이다.
코딩테스트 합격을 위한 변수명과 함수명 짓는 완벽 가이드
대부분의 개발자가 처음 코딩테스트를 준비할 때 간과하기 쉬운 부분이 있습니다. 바로 변수명과 함수명을 짓는 방식입니다. 많은 사람들이 알고리즘 해결 자체에만 집중하다 보니 코드의 가독
byteandbit.tistory.com
'코딩테스트' 카테고리의 다른 글
| 완전탐색 vs 그리디 vs 백트래킹: 코딩테스트 알고리즘 완벽 가이드 (0) | 2025.12.21 |
|---|---|
| 코딩테스트 입출력 처리와 파싱 노하우: 실전 팁과 주의사항 (0) | 2025.12.20 |
| 코딩테스트 합격을 위한 변수명과 함수명 짓는 완벽 가이드 (0) | 2025.12.16 |
| 입사 코딩테스트 준비할 때 ‘주석’과 ‘가독성’ 좋은 코드 작성 실전 팁 (0) | 2025.12.15 |
| 입사 코딩테스트 준비, 여러 언어로 효율적으로 문제 풀기 (0) | 2025.12.14 |