디버깅은 왜 중요할까?

Sunhee·2024년 4월 24일
0

자료구조

목록 보기
4/14
post-thumbnail

해당 포스트는 이지스퍼블리싱, 『알고리즘 코딩테스트 자바 편』, Gene 김종관 을 참고하여 작성하였습니다.


프로그램에서 발생하는 문법 오류나 **논리 오류를 찾아 바로잡는 과정을 디버깅(debugging)이라고 합니다. 문법 오류는 컴파일러가 자동으로 찾아 주므로 테스트할 때 문제가 되지 않습니다.
논리 오류는 코드가 사용자의 의도와 다르게 동작하는 것이며 다양한 형태로 발생합니다.

디버깅의 중요성

코딩 테스트에 떨어진 응시자와 만나 이야기하다 보면 이런 말을 많이 합니다.

학생 1: '아! index 범위 1개 차이로 이번 시험에 떨어졌어요. 너무 아쉬워요.'
학생 2: '계속 답이 나오지 않아 몇 시간 동안 헤맸는데, 알고 보니 int를 long으로만 바꾸면 되는 거였어요.'

두 학생이 디버깅을 제대로 했다면 아마 코딩 테스트에 통과했을 것입니다. 많은 사람이 문법을 배우는 과정에서 디버깅을 가볍게 생각하고 넘어갑니다. 하지만 디버깅은 코딩 테스트에 필요한 기술이고, 그냥 알아 두기만 하면 되는 것이 아니라 문제를 풀면서 반드시 해야 하는 과정입니다. 반드시 디버깅을 익힌 후에 코딩 테스트에 응시하기 바랍니다.

디버깅하는 법

디버깅을 하는 방법은 코드에서 디버깅하고자 하는 줄에 중단점break point을 설정하고, IDE의 디버깅 기능을 실행해 진행하면 됩니다. 구체적인 방법을 다음과 같습니다.

디버깅 방법
1. 코드에서 디버깅하고자 하는 줄에 중단점을 설정한다. 이때 중단점은 여러 개 설정할 수 있다.
2. IDE의 디버깅 기능을 실행하면 코드를 1줄씩 실행하거나 다음 중단점까지 실행할 수 있으며, 이 과정에서 추적할 변숫값도 지정할 수 있다. 이 방법으로 변숫값이 자신이 의도한 대로 바뀌는지 파악한다.
3. 변숫값 이외에도 원하는 수식을 입력해 논리 오류를 파악할 수도 있다.

2와 3에서 말하는 변숫값 추적은 이클립스의 Expressions 기능을 활용하면 됩니다.
Expressions 기능은 이후 디버깅을 설명하며 자주 보게 될 것이므로 눈에 익혀 두세요.


디버깅 활용 사례 살펴보기

코딩 테스트를 진행하며 실수하기 쉬운 4가지 오류 찾아보기

다음은 구간 합 관련 코드입니다. 언뜻 보면 문제가 없는 것 같지만 이 코드에는 실수하기 쉬운 4가지 오류가 숨어 있습니다. 우선 코드를 봅시다.

결함 있는 코드 예제

실제 코테에 입력할 코드와 비교하면 짧고 단순한 코드이다. 눈으로 오류를 금방 찾았을 수도 있습니다. 하지만 코테는 이보다 복잡한 알고리즘 로직이 필요하며, 코드의 길이도 길어서 논리 오류를 눈으로 찾기 쉽지 않습니다.
디버깅으로 논리 오류를 찾아보자.

오류 1. 변수 초기화 오류 찾아보기

1번째 오류는 변수 초기화 로직에서 초기화를 제대로 하지 않은 경우이다. 다음 화면에서 변숫값 기능을 보여주는 Variables 탭을 봅시다.

Variables 탭의 t가 2이므로 2번째 테스트 케이스를 진행하는 중이라는 것을 알 수 있습니다. 그리고 중단점은 20번째 줄을 가리키고 있으므로 이제 막 2번째 테스트 케이스를 실행하기 시작한 시점입니다. 그런데 answer의 값은 0이 아닌 1327708815입니다. 이는 초기화 로직에 문제가 있다는 것을 의미합니다. 1번째 케이스에서 도출한 answer의 값이 그대로 남아있는 모양입니다.

변수 초기화 로직은 놓치기 쉽습니다. 코드가 복잡해지면 더욱 그렇겠지요 그리고 변수 초기화 로직 때문에 테스트를 통과하지 못하는 경우가 의외로 많습니다. 따라서 실제 코딩 테스트의 2번째 테스트 케이스부터 통과되지 않는다면 모든 변수가 정상적으로 초기화되고 있는지 디버깅을 이용해 확인해 보는 것도 해결에 도움이 됩니다.


오류 2. 반복문에서 인덱스 범위 지정 오류 찾아보기

2번째 오류는 반복문에서 인덱스 범위를 잘못 지정한 경우입니다. 다음 화면을 봅시다.

종종 반복문에서 반복 범위를 잘못 지정하거나 비교 연산자를 반대로 사용하는 경우가 있습니다. 위 경우 Variables 탭에서 볼 수 있듯이 S[10000]부터의 값이 모두 0입니다. 반복문에서 배열 S에 값이 제대로 저장되지 않은 것이죠. 13~17번 라인을 보면 초기에 합 배열을 구하는 과정에서 반복문의 범위가 10000입니다. 배열 A와 S의 크기가 100001이므로 반복 범위는 100000이어야 합니다. 0을 하나 누락한 것입니다.

이런 경우 외에도 배열 인덱스가 0부터 시작한다는 사실을 간과하는 경우도 있고, 반복문을 N까지 반복하도록 설정해야 하는데 비교 연산자를 잘못 입력하여 N - 1까지 반복하도록 설정하는 경우도 있습니다. 인덱스 범위 지정 오류는 여러 형태로 발생할 수 있으니 반복문을 사용할 때마다 범위와 시작 인덱스를 꼼꼼하게 확인하고, 혹시 모를 오입력을 대비해 디버깅하는 습관을 들이기 바랍니다.

오류 3. 잘못된 변수 사용 오류 찾아보기

출력 부분이나 로직 안에서 사용해야 하는 변수를 다른 변수와 혼동하여 잘못 사용하는 경우도 있다. 예를 들어 반복문에서 반복 변수를 사용해야 하는데 기준 변수를 사용하거나 변수 이름 자체가 비슷해서 잘못 사용하는 경우이다.

t는 1이므로 1번째 케이스다. 그리고 디버깅은 26번째 줄을 가리키고 있다. 원래 문제에서 요구한 테스트 케이스의 출력 결과는 '몇 번째 테스트 케이스의 답이 무엇이다'이므로 1 999999와 같이 출력되어야 한다. 그런데 Console 탭을 보면 5-1875592971을 출력하고 있다. 분명 1번째 테스크 케이스를 실행하는 중이므로 1이 출력되어야 하는데 그렇지 않다. 이는 26번째 줄에서 출력 변수를 t가 아니라 testcase로 지정했기 때문이다. 코딩을 하는 도중에 t와 testcase를 혼동했을 가능성이 높다.

Variables 탭의 answer 값이 Console 탭의 answer의 값과 다른 이유는? Console 탭의 answer 값 -1875592971의 경우 i가 0인 경우 출력한 값이고, Variables 탭의 answer값 1862370832는 이후 i가 1이 되며 새로 계산된 값이다.

오류 4. 자료형 범위 오류 찾아보기

Variables 탭에서 배열 S를 보면 음수로 된 값들이 보인다. 이 문제에서 S에 음수를 허용하지 않으므로 이상한 값이 저장된 것임은 분명하다. 왜 그럴까? 그 이유는 배열을 int형으로 선언했기 때문이다. 계산 과정에서 int형이 저장할 수 없는 범위의 값이 나온 것이다. 배열을 선언할 때 int형이 아니라 long형으로 선언했다면 이런 오류는 발생하지 않았을 것이다.

int형은 -2147483648 ~ 2147483647 범위를, long형은 -922337203685475808 ~ 9223372036854775807 범위를 저장할 수 있다.

디버깅을 이용하면 자신이 작성한 로직에 존재하는 논리 오류를 좀 더 효율적으로 발견할 수 있다. 실제 코테에서는 시간이 촉박하므로 디버깅에 익숙해지는 것이 좋다.



[참고 자료1] https://help.eclipse.org/latest/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Freference%2Fviews%2Fexpressions%2Fref-expressions_view.htm

[참고 자료2] https://goodafteryoon.tistory.com/109

0개의 댓글

관련 채용 정보