코딩 테스트에 대한 7가지 사실과 오해
이제 IT 기업에서 소프트웨어 개발자를 뽑기 위해서 코딩 테스트를 보는 것이 당연한 시대가 되었다. 필자도 선발 과정에 직-간접적으로 참여하면서 코딩 테스트 문제를 출제하기도 했고 평가 과정에 참여하기도 했다. 개발자 역량 중에서 코드를 작성하는 역량이 중요하다는 것은 누구나 동의할 것이다. 그렇지만 오직 코딩 테스트만 잘하는 것을 바라지는 않는다.
이제 코딩 테스트 서비스와 플랫폼들이 대중화되면서 누구나 웹 사이트에서 코드를 작성하고, 즉시 테스트 결과를 확인할 수 있다. 회사들은 코딩 테스트 과정에서 점수로 나오는 평가의 편리함 덕분에 대규모 인원을 평가할 수 있다. 그렇지만 지원자 입장에서도, 회사 입장에서 대부분 코딩 테스트는 아쉬운 부분이 많다.
코딩 테스트는 입력에 따라 출력이 나오는 테스트 케이스를 통과하는지 확인하는 시험이다. 대부분 코딩 테스트 플랫폼들은 미리 준비해 놓은 테스트를 통과했는지 점수화해서 결과로 알려준다. 응시자들은 주어진 시간이 촉박하기 때문에 자연스럽게 테스트를 통과하는 데 집중하고, 테스트를 통과하는 그 코드가 정답이라고 믿는다.
테스트 케이스 통과와 함께 공간 복잡도, 시간 복잡도를 통과 조건으로 두기도 하는데 이런 경우는 알고리즘과 구현 방식까지 거의 정해주는 셈이다. 그러다 보니 이런 문제는 저런 방식으로 작성한다는 공식을 외워서 코드를 작성한다.
요즘 대학생들은 알고리즘 스터디를 많이 한다. 학교에서 외부 강사를 초대해서 특강으로 출제 유형을 분석하거나 족집게 강의를 해주기도 한다. 스스로 생각하는 과정을 알려주는 게 아니라, 문제 유형을 분석해서 특정 알고리즘으로 풀면 된다고 암기한다.
최근 코딩 테스트 결과를 보면 점수가 우상향 되어 있는 편이다. 그만큼 짧은 시간 동안 정답이 있는 시험을 잘 보기 위한 준비를 했기 때문이다.
필자가 생각하는 코딩 테스트의 오류는 바로 이 부분에서 시작한다. 개발자들이 해결해야 하는 문제들은 정답이 정해진 문제만 있지 않다. 추상적인 요구사항을 여러 단계로 나누고, 단계에 필요한 문제를 정의하는 것부터가 소프트웨어 개발의 시작이다. 정답이 정해진 문제만 답을 외워서 해결했기 때문에, 스스로 문제를 정의하지 못하고 큰 그림을 이해하지 못한다. 작은 문제를 해결하는 역량도 필요하지만, 그게 전부가 아니다. 마치 백일장처럼 같은 주제에 대해 다양한 문제의식에서 시작해서, 그 생각을 적절하게 기술적으로 표현한 코드를 볼 수 있어야 한다. 하지만 코딩 테스트는 정해진 정답을 찾은 사람만 골라내는 시험이 되어가고 있다.
대부분 코딩 테스트는 비교적 짧은 시간에 여러 문제를 풀도록 강제한다. 어떤 회사는 5-6문제를 3시간 이내에 풀도록 하기도 한다. 시간이 넉넉하지 않다는 핑계는 정답만 찾는 좋은 이유가 된다. 그러면서 빠르게 결과를 만드는 데 집중하게 만든다. 이런 조건에서는 과정보다는 결과에 무게 중심을 두게 된다.
개발 과정을 살펴보면 소위 삽질이라고 표현하는 과정이 필요하다. 문제 해결을 위해 가설을 세우고, 가설이 맞는지 시도하고, 결과를 확인해서 가설을 검증하는 과정이다. 코딩 테스트하면서도 이런 과정이 반복된다. 그렇지만 결과만 지향하다 보면 그 과정이 덜 중요하다고 생각하게 된다. 그러면 과정을 단축시키기 위해서 의도적으로 해야만 하는 다양한 사고 실험이 생략되거나 전략적으로 정답이라고 생각하는 방식으로 시야가 좁아진다.
채용 과정에서 코딩 테스트 이외에 다른 단계에서 결과가 아니라 과정을 보는 단계를 두기도 한다. 온사이트 인터뷰에서 화이트보드에 코드를 설명하는 단계를 두는 이유는 바로 문제 해결 과정을 살펴보기 위해서다. 채점 결과로 나오는 코딩 테스트로는 과정을 평가하기 어렵기 때문에 그것을 보완하는 단계가 있어야 한다.
테스트 케이스를 통과시키기 위해서 제한된 시간 내에 코드를 작성하다 보면 코드 품질은 나빠진다. 어뷰징을 막기 위해서 복사-붙여 넣기를 금지하면 컴파일 에러라도 확인하기 위해서 통합 개발 환경에서 우선 작성하고 나서 코딩 테스트 플랫폼에 다시 입력하는 과정을 거친다. 두 번이나 입력해야 하다 보니 변수명, 함수명을 생각할 시간조차 부족하다. 결과적으로 코드 품질이 나빠진다.
제한된 시간 내에 코드를 작성하다 보면 누구나 깊은 고민이나 생각을 하지 못하고, 의식의 흐름대로 작성하는 경우가 많다. 어차피 사람이 읽고 고칠 코드가 아니라 시험 볼 때 기계가 실행하고 나면 사라질 코드니까 신경 써서 클린 코드로 작성할 필요는 없다. 하지만 코드 품질을 완전히 무시하고 결과 지향적인 코드를 작성하는 것은 단지 시험을 위한 비현실적인 코드가 된다. 임시로 작성하고 버려질 코드는 그래도 상관없지만, 그런 코드만 작성하는 경험을 반복하는 것은 나쁜 습관이 된다. 계속해서 그런 코드만 작성했던 사람들은 코드 품질을 신경 써야 하는 경우에도 나쁜 습관에서 벗어나지 못한다.
앞서 말한 것처럼 코딩 테스트만 반복해서 연습하다 보면 시야가 좁아지고, 코드 품질도 나빠질 수 있다. 더 좋지 않은 것은 그렇게 초집중해서 해결한 코드는 제출하고 나면 피드백을 주는 사람도 없고 개선할 필요성을 느끼지 못하기 때문에 버려진다. 테스트 동안 작성한 코드는 주어진 조건 내에서 주어진 테스트 케이스는 통과할 수 있지만, 그 이외에 조건이나 환경에서는 다른 영향을 줄 수도 있다. 테스트 케이스에 포함되지 않은 오류는 검증할 수 없기 때문이다.
이렇게 임시로 주어진 조건에서만 동작하도록 만들고 버려지는 코드도 있을 수 있다. 그것을 부정하는 게 아니라, 그런 코드도 있지만 한 번 만들고 나면 쉽게 버려지지 않은 코드도 있다는 것이다. 응시자는 시험이 끝나고 코드를 보관하고 있다가 다른 방식으로 해결해 볼 수도 있고, 문제의 제약 사항을 바꿔서 다른 관점에서 해결하는 방법도 좋다. 회사 입장에서는 코딩 테스트 외에 이미 만들어진 레거시 코드를 개선하거나, 개선한 코드가 다른 코드에 영향을 주는지 확인하고, 리팩터링으로 결과는 갖지만 구조를 바꾸기 위해서 피드백 고리를 만들기를 권장한다. 그래야 단지 코드가 아니라 사고의 과정을 함께 살펴볼 수 있다.
여러 회사가 코딩 테스트를 보면서, 응시하는 사람들도 점점 점수가 높아진다. 그러면 회사는 점수만으로 변별할 수 있도록 더 제약 사항을 추가하고 더 어려운 문제를 출제한다. 최근 몇 년 동안 코딩 테스트는 악순환이 반복되고 있다. 그럼에도 응시자들은 문제 유형을 분석하고 정답을 외워서 코딩 테스트 만점을 받는 경우가 많아졌다. 다양한 사고의 흐름을 확인하려는 코딩 테스트가 단순한 암기 시험으로 변질되고 있다.
코딩 테스트에서 어려운 문제들은 현실적인 문제가 추상적으로 표현돼서 해결 방법을 찾기 어렵거나 특정한 알고리즘 방식으로 정교하게 구현하지 않으면 안 되는 문제들이다. 마치 불수능에 나올 법한 난해한 전문 분야의 지문을 읽고 척척 알아맞히길 바라는 문제일지도 모른다. 필자는 그런 문제를 반대한다. 솔직히 그런 문제를 풀어야만 한다고 납득이 되지 않는다. 그 문제를 꼭 풀어야 하는 포지션이나 업무가 따로 있을 수도 있지만 모든 개발자들이 다 어려운 문제를 풀 수 있어야만 하는 것은 아니다.
코딩 테스트를 하는 근본적인 목적이 무엇인가 다시 되짚어 봐야 한다. 코딩 테스트는 복잡하고 어렵고 정교한 알고리즘을 몰라서 못 푸는 문제보다는, 보편적으로 누구나 알 수 있는 최소한의 수준을 검증하는 것을 목표로 해야 한다. 주어진 조건에 맞춰서 동작하는 함수를 구현할 수 있고, 적절한 타입을 활용해서 메모리를 적절한 범위로 사용하도록 구현할 수 있으면 된다. 코딩 테스트는 최상을 뽑는 게 아니라, 최하를 걸러내는 선별의 수단이 되어야 한다.
요즘 알고리즘 문제 사이트에서 진행하는 맹목적인 문제 풀이와 회사들이 채용 과정에서 제시하는 코딩 테스트 문제들은 선별의 수단이 아니라 그 자체가 목적이 되어버렸다. 스스로 생각하는 방법을 잃어버리는 시험에 반복적으로 노출되는 상황이 안타깝다.
심지어 현업에 있는 대부분 지인들은 코딩 테스트 점수와 업무 역량이 크게 상관관계가 없다고 말한다. 어려운 코딩 테스트 문제를 술술 풀고, 칠판에도 어떻게 풀었는지 설명할 수 있는 분에게 업무 요구사항을 주면 어디서부터 시작할지 모르는 경우가 많다. 마치 오래전에 토익-토플 만점자가 외국인과 대화를 못하거나, 업무를 할 정도가 못된다는 도시괴담과 비슷해졌다.
제한적인 상황에서 동작하는 예외적인 문제를 푸는 코딩 테스트는 아쉽게도 선발 과정에서 점수 데이터를 얻기 위한 편리한 채용 업무 수단으로 전락했다. 이미 회사들이 최근 몇 년 동안 잘못된 방향으로 신호를 보냈고, 계속해서 그쪽으로만 가고 있다. 지금이라도 코딩 테스트 이외에 실무진이 직접 확인할 수 있는 다양한 방법을 찾아야 한다. 자신의 동료를 구하려면 같이 일 할 팀원들 모두가 채용 과정 시작부터 적극적으로 소통하고 검증해야 하는 시대가 됐다.
최근에는 코딩 테스트 허들을 낮추고, 과제형으로 문제를 제시하고 일정 기간 동안 해결한 내용을 온라인에서 또는 온사이트에서 확인하는 기업들도 늘어났다. 이런 시도는 채용이 소규모일 때 가능하고 일정 규모 이상 진행하기 어렵다. 확장성이 없고 지속 가능하지는 않기 때문이다.
적어도 앞으로 과도한 코딩 테스트만으로 선발하지 않기를 바라는 마음에서 정리해봤다. 선발 과정을 단순하게 처리할수록 놓치는 부분이 많고, 그 분야만 잘하는 사람을 뽑게 된다. 개발자 뽑기 어려운 시대일수록, 그 사람을 더 알 수 있는 방법을 고민했으면 좋겠다.