Skip to content

THO 5. About Coding Assessment Problems

Migrated

This article is migrated from which I wrote on another website.

안녕하세요. 알려드릴 수 없는 어떤 회사에서 코딩테스트 문제를 직업으로써 만들어본 경험을 한번 풀어보고 싶어서 글을 쓰게 되었습니다.

Disclaimer

저는 해당 회사를 퇴사한 지 한참 지났고, 내부의 상황이 지금과는 다를 것이기 때문에 문제가 되지 않는 선에서 제가 여러 가지를 익명으로 풀어보고자 합니다. 경우에 따라 조금 불쾌하다고 느껴지는 표현이 있을 수도 있는데, 비하의 의도는 전혀 없습니다.

저는 첫 번째 회사를 퇴사할 당시 다른 여러 회사를 알아보게 되었고 그 중 우연히 코딩테스트 문제 관련된 직종에 지원할 기회가 생겼습니다. 당시 저는 그 전 회사에서 업무적인 측면이나 여러 가지 방면에서 실패를 해서 자존감을 채우고 싶었고, 마침 알고리즘쪽은 나름 자신이 어느 정도 있는 편이었기에 해당 회사에 지원하여 바로 합격해서 출제 업무를 시작하게 되었습니다.


There was no automated process

제가 업무를 시작하고 맞닥뜨린 최초의 장애물은, 당시 회사에서 문제를 출제하기 위해 팀원들이 사용하는 일련의 자동화 프로세스가 전무했다는 점입니다. Codeforces에는 Polygon이라는 프레임워크가 있어 상당히 높은 자유도로 다양한 형태의 문제를 출제할 수 있었는데, 당시 해당 회사에서는 데이터 생성, 데이터 조건 검증, 틀린 풀이 교차 검증 등에 대한 자동화 툴이 전혀 없었습니다. 모든 팀원들이 매 문제를 만들 때마다 scratch부터 시작하여 코딩하는 것이었습니다. 이 방식은 다음 목록에 해당하는 잠재적인 문제점을 가지고 있습니다.

  1. 데이터나 솔루션이 잘못된 것을 검증하기가 어렵습니다. 코딩테스트에는 높은 난이도의 문제가 아예 나오지 않기 때문에 솔루션을 논리적으로 증명하는 데 어려움이 있진 않지만, 경우에 따라 edge case handling 등에서 틀린 부분이 나올 수도 있습니다. 물론 플랫폼에서 데이터 전체와 해당 문제에 대한 유저별 submission 통계를 end user들에게 보여주지 않으면 데이터가 한두개쯤 잘못되었거나 특정 풀이의 솔루션이 아예 잘못되었다고 하더라도 유저 입장에서 딴지를 걸 방법은 없기에 큰 문제가 되지는 않았습니다만, 어쨌거나 나중에라도 언젠가 문제가 될 가능성이 있습니다.

  2. 문제 만드는 속도가 너무 느립니다. 만들어진 데이터를 file로 출력하는 코드조차 매번 문제별로 직접 만드는 것은 어마어마한 비효율입니다. 심지어 솔루션과 몇몇 틀린 풀이를 만들어서 두 풀이를 상호 검증하는 절차는 입사 초기 당시에는 아예 존재하지 않았습니다.

위 2가지 문제점과 다른 여러 점들 때문에 저는 팀장님이 문제를 한 개 만들어보라고 주신 첫 일주일을 모두 자동화 툴 개발에 쏟았습니다. 그리고 그 툴을 이용해 첫 문제를 만들었고, 해당 문제는 성공적으로 납품이 되었습니다.

이 자동화 툴은 처음 몇 달 정도는 저만 사용하다가 점점 기능을 추가하면서 팀 내 유저수를 늘려갔고, 제가 퇴사할 당시에는 끝까지 본인의 방식을 고수하신 단 1명을 제외한 모든 팀원들이 공식적으로 사용하는 툴이 되었습니다. (그리고, 이 분조차 나중에는 제 툴을 사용하시게 됩니다) 저는 이게 마치 실제 사업하는 회사가 제품을 판매하는 거랑 비슷하다고 생각했습니다.

압도적인 성능의 제품을 풀면, 점유율은 시간이 지나면서 자연스럽게 올라가고, 끝내 극소수를 제외하면 대부분이 해당 제품을 사용하게 되는 일련의 시나리오를 믿게 되었습니다. 대표적인 예시로 생산 공장의 기계, 스마트폰, 그리고 ChatGPT 같은 인공지능이 있을 것입니다.


Low difficulty and quality

두 번째 장애물은, 높은 수준의 문제를 몇 개 만드는 것보다 수능수학 2점짜리 문제를 찍어내는 것 마냥 낮은 난이도의 문제를 대량 생산하는 것이 더 중요하다는 현실이었습니다. Codeforces Div1C, 아니 Div1B 정도만 되어도 해당 문제를 풀 수 있는 인원은 사실상 거의 없으며, 구현 난이도에 비해 아이디어 난이도가 조금이라도 높으면 정답률이 정말 많이 떨어졌고, 일부 고객사들은 변별력을 기르는 것보다 오히려 평균 점수를 높이는 것을 선호하는 경우조차 있었습니다.

또 본질적으로 거의 동일한 성능으로 똑같은 연산을 하는 것임에도 두 코드를 다르게 생각하는 사람들(+고객사들)이 정말 많았습니다. 그래서 말장난으로 똑같은 알고리즘을 조금씩 코드만 다르게 변형해서 문제를 양산하는 것이 가능했습니다. 극단적으로 단순한 예시를 들면 다음과 같습니다.

s = []

# Method 1
s.extend("abcd")

# Method 2
for obj in "abcd":
    s.append(obj)

# Method 3
s += "abcd"

예를 들어 분할정복을 문제로 낸다고 할 때, 해당 재귀가 배열을 앞뒤 반반씩 나눠서 탐색하는지, 3구간으로 나눠서 탐색하는지, 홀수/짝수 인덱스로 나눠서 탐색하는지 등만 조금씩 바꿔서 내도, 다른 문제로 인식한다는 것입니다. 거기에 그 어떤 다른 추가적인 이론이 들어가지 않는다고 하더라도 말입니다.

사실 저는 난이도가 낮더라도 아이디어 또는 접근과정이 비교적 참신하거나, 아니면 구현을 스마트하게 해서 난이도를 낮추는 식의 문제는 좋아합니다. 이에 관해서 좀 더 자세히 서술하면, 대부분의 고객사와 유저들은 조금이라도 "수학적인" 무언가가 코테에서 등장하는 것을 아주 싫어했습니다.

제가 문제 검수 과정에서 받은 가장 황당한 피드백들은 다음과 같습니다.

Quote

"'경우의 수' 라는 표현이 너무 수학적이기 때문에 지문에서 해당 표현을 '가짓수'로 대체합시다."

"Python은 bool 자료형으로 True를 쓰고 C++ 등 다른 언어는 true를 쓰는데, 지문에서 어느 한 쪽을 채택하면 설령 지문에서 자료형을 명시한다 하더라도 다른 쪽의 언어만을 사용하는 유저가 혼란을 겪을 수 있으므로 bool 자료형을 언급하는 것은 지양해야 합니다."

그런 피드백을 받을 때마다 "이 정도까지 고려해야 할 정도면 그건 회사가 채용해야 하는 개발자가 맞습니까?"라는 질문이 목구멍까지 여러 번 올라왔지만, 참았습니다.

지금 생각해보면 제가 아니라 회사의 방침이 맞았던 것 같습니다. 왜냐하면 높은 위치에 있는 개발자들일수록 코테의 비중은 점점 줄어들기도 하고, 그 사람들이 이전에 쌓은 경력과 기술 그리고 제품을 기반으로 이직을 하는 것일텐데, 이와 정반대로 코딩 교육이나 코딩 테스트는 초심자의 돈이 중요한 money source인 사업인데, 그런 사람들에게 불친절하면 필연적으로 매출의 감소로 이어질 게 뻔하기 때문이었습니다.


How much this job is profitable?

저는 결국 병역이라는 현실과 돈을 위하여 질보다 양을 선택했습니다. 첫 1달 정도는 그런 수준 낮은 문제를 양산하는 스스로에 대해 혐오감이 있었을 정도였지만 시간이 지나면서 익숙해졌습니다. 그 뒤 해당 툴을 활용하여 몇 달 동안 미친 속도로 문제를 양산하기 시작했습니다. 팀원이 많지 않았을 때에는 저 혼자 만드는 문제 개수가 다른 모든 팀원들이 동일 기간 동안 만드는 문제 개수를 합친 것보다 많았습니다.

1년 뒤, 저는 회사로부터 성과를 인정받아 입사 당시 연봉에 비해 50% 조금 안 되게 상승하게 됩니다. 이것도 팀장님으로부터 연봉 가스라이팅을 받아서 더 높아질 수도 있었던 게 여기서 협상이 되었던 거고요. 나중에서야 알게 되었지만 그것은 제가 많이 높아진 것이 아니라 그냥 초기 연봉이 턱없이 낮았던 것이었습니다.

합리적으로 생각해보면, 코딩테스트 문제 그 자체가 상업적으로 가지는 가치는 결국 코테 매출인데, 다른 팀들의 인건비도 여기에 contribution이 있다는 걸, 그리고 코딩테스트 문제 제작의 속도에 한계가 있다는 걸 고려한다면 결국 코딩테스트 문제 제작으로 벌 수 있는 월급에는 상한선이 높지 않은 곳에 정해져 있는 셈입니다. 개발은 똑같은 시간을 붓더라도 그 퀄리티와 영향이 천차만별일 수 있는데도 불구하고, 코딩테스트 문제는 그렇지 않은 거죠.


We shouldn't blindly correlate career length and salary

처음 연봉이 크게 올랐을 때도 돈 벌기 쉽다고 생각했지만 저는 해당 연봉을 입사할 때부터 제안받은 지원자의 존재를 알게 되면서, 그리고 주변 고연봉 개발자들을 실제로 만나서 진로 이야기를 하면서 팀장님으로부터 지속적으로 주입받은 연봉 가스라이팅에서 벗어나기 시작했습니다. 실제로 제가 퇴사 의사를 밝혔을 때, 사측에서는 다음날 바로 즉시 25% 연봉 인상을 제안했습니다.

연봉 가스라이팅에 관해 말하자면, 여기 OKKY도 그렇고 이 연차에 연봉 얼마면 적당하다는 식의 대화가 많이 보이는데 그런 건 절대로 없습니다. 자기보다 시니어인 사람들보다 많이 잘하면 자기가 돈을 더 많이 받고, 주니어인 사람들보다 많이 못하면 그 사람들보다 더 적은 보상을 받는게 자연스럽다고 생각합니다. 누구나 할 수 있는 단순한 작업이면 모르겠는데, 개발은 잘하는 주니어 1명이 못하는 시니어 3명보다 더 좋은 제품을 뽑아낼 수 있습니다. 물론 대한민국은 고용과 해고가 유연한 국가가 아니라는 특수성을 가지고 있기 때문에 나타나는 현실이라고 생각하긴 합니다.


Lots of ugly cheaters

코딩테스트 문제를 만들게 되면 높은 확률로 관련 대회(챌린지 등)나 혹은 입사시험 도중 일종의 감독관을 맡게 됩니다. 저는 정말로 다양한 유형의 치터와 진상들을 목격했습니다. 가장 기억에 남는 진상은 자신의 풀이가 옳다고 끝까지 고객센터에서 난리를 치는 유저였습니다.

그 어떤 대회나 코테에서도 테스트 진행 중 참가자의 풀이가 틀린 이유를 설명해주는 경우는 매우 드뭅니다만, 그 유저는 CS(Customer Service)에서 어마어마한 어그로를 끌었고 관련 부서 팀원들이 골머리를 썩히고 있었습니다. 저는 너무 화가 난 나머지, 역대 근무기간 중 유일하게 그 유저가 제출한 코드의 반례를 분석해서 직접 설명하게 됩니다. 몇 초간 벙찌더니 사과를 하더군요.

저는 그 때, "이 유저가 회사에 합격해서 돈을 벌고 승승장구할 가능성을 조금이라도 제거해야 하지 않을까?" 라는 굉장히 위험한 생각을 잠깐 하게 됩니다. 그래서 그 유저가 지원한 회사에 CS 상담기록을 통째로 전송하려는 계획을 하다가, 이게 어느 쪽으로든 악영향이 커질 경우 병역을 수행하는 제 입장에서 감당이 안 될 것 같았고, 그 유저도 본인의 생계가 걸린 일이었기에 이렇게 예민해질 수 있었을 것 같다는 것을 감안하게 되면서 이 일은 CS센터의 단순 해프닝으로 마무리가 됩니다.

사실, 코딩테스트 말고도 일상생활에는 사소한 치팅이 비일비재합니다. 작은 것으로는 과제 대행이나 팀플 무임승차가 있고, 더 큰 것으로는 채용과정 치팅(윗 문단에 나온 것들 포함, 더 심하면 거물 부모님의 압력 등)이 있을 것입니다. 과제 대행이나 팀플이야 사람들이 교수님 앞에서 대놓고 하지도 않고, 그게 학점에 반영되는 효과도 직관적으로 관찰하기 어렵기 때문에 별 체감은 안 되지만, 수많은 치터들을 직접 목격하는 포지션에 들어오게 되면 상당한 체감을 느끼게 됩니다. 그 때 느낀 점들 하나가 "많은 일반인들의 본성은 범죄자와 별로 다를 게 없다." 입니다.


Awards don't make you all-rounder

또, 저는 한때 올림피아드와 ICPC 같은 저명한 경시대회의 수상실적에 대해 집착했던 적이 있었습니다. 그런 곳에서 국제적으로 수상을 한 사람들은 특별한 사람들이라는 믿음을 가지고 있었고, 실제로 Terence Tao나 Vitalik Buterin 같은 사람들이 큰 영향을 끼치고 있었기에 저는 그런 사람들을 동경했습니다. 그런데 그런 수상실적을 가지고 있음에도 제가 가지고 있었던 기대를 실망시키는 팀원을 만나게 되고, 실제로 Codeforces 같은 곳에서 활동을 많이 하면서 별의별 사람들을 만나게 되고 이것도 그냥 케바케라는 것을 알게 되었습니다.


It was hard to do some creative trials

코딩테스트 문제 제작 자동화 툴 이외에도 여러 시도를 해보았습니다. 대표적으로 코딩테스트 지문에 manim을 활용하여 애니메이션을 삽입하는 시도를 했는데, 오히려 이를 당연하게 여기는 고객기업들이 등장하기 시작하면서 제가 난감해진 상황도 있었습니다. 다른 퇴사자분에게 듣기로는 제가 나간 이후로 애니메이션이 삽입된 문제가 만들어진 적이 거의 없다더군요.


I quited

돈을 많이 주는 것도 아니고, 지적 호기심을 충족시켜주지도 않고, 일을 뭔가 벌이면 오히려 귀찮아지는 분위기였습니다. 이 3가지 이유로 해당 직종을 탈출하고 싶다는 발언을 사내에서 공개적으로 한 적도 몇 번 있는데 회사 측에서 저를 개발직종으로 전환시켜줬다가 퍼포먼스 문제를 이유로 다시 코딩테스트 문제 직종으로 변환시키는 일도 있었습니다. 임원분으로부터 개발을 못한다는 말을 면전에서 들었을 정도였습니다. 하지만 저는 계속 탈출이 하고 싶었고 이후 꽤 많은 곳의 면접을 보았고, 우연히 퀀트회사에 합격하여 이후 저는 퀀트로 직종을 전환하게 됩니다.


길고 자극적인 글을 여기까지 침착하게 읽어주셔서 감사합니다. 아직도 쓸거리가 몇 개 남았지만, 이것은 여러 코딩테스트 회사들의 시스템적 한계와 관련된 내용들이 주를 이루기 때문에 작성하지 않는 것이 안전하다고 판단하였고 여기에서 마무리하였습니다. 좋은 하루 보내시길 바랍니다.