프리코스가 끝나고 나서는 그동안 못했던 학교 시험 공부를 했습니다. 그리고 종강 후에는 교내 해커톤에 출전해 수상도 하고, 1년동안 진행한 동아리 프로젝트에서도 최우수상을 수상하며 나름 바쁜 나날들을 보내고 있었습니다.

그러던 25년 12월 29일 오후 3시 9분 우아한테크코스 8기 1차 심사 합격 메일을 받았습니다. 프리코스 기간동안에 정말 열심히 참여했지만, 다른 분들도 모두 열심히 하셨기 때문에 저는 붙을거란 기대가 없었습니다. 그런데 1차 심사 합격 메일을 받고는 정말 기뻤습니다. 기회가 주어지면 최선을 다해야 한다는 마음가짐으로, 1차 합격 메일을 받자마자 최종 코데 준비 계획을 세웠습니다. 하지만 다음날에 원인 모를 몸살에 걸려 중요한 기간에 2-3일을 아무것도 못하고 앓아 눕게 됩니다.. 첫 날부터 계획에 차질이 생겼었지만, 원래 계획대로 안되는게 삶 아니겠습니까 다시 준비를 시작했습니다. 저는 몸살 이후 어떤 마음가짐으로 연습을 했는지, 그리고 그 과정에서 어떤걸 배우게 되었는지 적어보려고 합니다.
저의 연습 목표는 지긋지긋하게 연습하기였습니다. 대부분 시험장에서 떨리는 이유는 결과가 좋아야 한다는 마음에서 비롯되는 것 같습니다. 따라서 이런 떨림을 없애는 가장 좋은 방법은 결과가 중요해지지 않을 정도로 힘들게 연습하는 것이라고 생각했습니다.
2차 코딩테스트 준비의 목표인 힘들게 연습하기 위한 요소를 3가지로 나누었습니다. 첫 번째 시간 감축은 원래 시간인 5시간이 아닌 4시간만 배분해 시간 압박을 늘렸습니다. 두 번째 장소 변화는 소음이 없는 독서실부터 시끄러운 카페까지 다양한 장소에서 미션을 풀도록 하여 낯선 장소에서 저만의 페이스를 찾는 연습을 했습니다. 세 번째는 미션 구현 정도의 선택입니다. 실제 최종 코딩 테스트는 어떤 형식으로 나올지 모르기 때문에, 클린코드를 최대로 끌어올리는 클린코드 연습과 복잡한 구현을 빠르게 하는 방식 두 개를 섞어가며 연습했습니다. 추가로 시간 안에 구현을 하지 못한 경우, 추가 시간을 재며 끝까지 구현하고 리팩토링하는 연습을 했습니다. 그리고 마지막으로 AI를 이용한 채점을 하여 고려하지 못한 비지니스 오류나 자주하는 실수들을 정리했습니다.
위와 같은 연습을 하면서 시간안에 구현을 하지 못하는 경우도 많았고, 심각한 비지니스 오류를 발견하지 못하는 경우도 많았습니다. 이런 연습을 하면서 시험장에서도 이런 실수를 하게 될까 두려웠지만, 오늘 두렵지 않았다면 시험 당일에 반드시 두려운 일이 일어날 것이라 생각을 했습니다. 그렇기에 저는 연습할때 최대한 많이 저의 약점을 파고들고 스스로 무너지기 위해 집요하게 노력했던 것 같습니다.
저는 실수를 금방 발견할 수 있는 코드를 짜기 위해 노력했습니다. 실전에서도 분명 실수를 할텐데, 그렇다면 실수한걸 알았을 때 빠른 시간 안에 실수를 찾아야 할 것입니다. 실수를 빠르게 찾는 방법은 무작정 빠르게 개발하는 것이 아니라, 클린 코드를 지향하며 개발해야 합니다. 그러나 코드 품질을 한 없이 높히기만 하면 시간 안에 요구사항을 모두 완료하지 못할 것입니다. 그래서 최종 코딩테스트에서의 클린 코드란 무엇인지 생각했습니다. 최종 코딩테스트에서의 클린 코드는 문제가 되는 코드가 어디에 있는지 아는 것이라고 정의했습니다. 그리고 이를 위해 도메인 주도 개발과 MVC 패턴을 어떻게 녹여낼지 고민했고, MVC 패턴으로 가되 도메인의 역할과 협력을 서비스 계층을 두어 협력하는 방식을 채택했습니다.
이 두 방법을 합친 이유는, 도메인 주도 개발을 하게 되면 새로운 미션마다 지나치게 달라지는 도메인 때문에 초반 설계 시간이 지나치게 많이 소요 됩니다. 반대로 MVC 패턴으로만 개발하게 되면 역할이 분명히 나누어져 있기에 설계는 일관되고 빠르게 할 수 있지만, 지나치게 추상화된 계층 때문에 서비스나 컨트롤러에 코드가 집약될 수 있습니다. 따라서 MVC 패턴을 주도로 하며 초반에 빠른 설계를 열어두고, 서비스 계층에서 도메인 협력을 하여 코드가 집약되는 것을 방지하기 위해 노력했습니다.

아침부터 긴장 되었지만, 잘 보려던 생각보단 그냥 연습때처럼만 하자는 생각으로 잠실로 갔습니다. 잠실에서 프리코스때 스터디를 같이 했던 분과 만나 가볍게 이야기 하고 최종 코테 장소가 달라 각자 시험장으로 갔습니다. 그리고 우연히 최종 코딩테스트 스터디를 하셨던 분과 스타벅스에서 만났어요! 짧았지만 반가웠습니다ㅎㅎ
저는 삼성생명 잠실빌딩이었습니다. 들어오자마자 신분증 검사를 했는데, 포비님께서 신분증 검사를 해주셔서 내적 친밀감이 있었어요. 다른 분들처럼 저도 싸인을 받고싶었는데, 약간 부끄러워서 멀리서 인사 드렸습니다(꾸벅)
시험장 분위기는 편안했습니다. 시험 자리는 조금 협소했지만, 시간지 지나니 크게 불편함으로 와닿진 않았습니다.
1시가 되고 시험이 시작되었습니다. 최종 코테 문제를 보자마자 이전 기수들과 다른 형식이라 당황했습니다. 지금까지는 1시부터 6시까지 어려운 문제를 푸는 형식이었지만, 이번엔 프리코스 3주차와 비슷하거나 혹은 더 쉬운 수준이었습니다. 그리고 InputView와 OutputView가 모두 구현 되어있어 저희는 추가 유효성 검증과 비지니스 로직만 구현하면 됐습니다. 하지만 코딩 테스트 시간은 1시부터 5시까지고, 5시부터 6시까지 회고를 작성하는 시간을 주었습니다.

그리고 이번에 새롭게 추가된 내용은 도전과제였습니다.

이번 우아한테크코스의 핵심 비전은 도전이었기에, 최종 코딩테스트에서도 목적에 맞게 리팩터링과 기능 확장 중 하나의 도전 과제를 선택하여 수행하는 것이었습니다.
둘 중 어느것을 할지 고민을 많이 했습니다. 이 자리에서는 완전히 새로운 도전을 하기 보단, 지금까지 도전했던 것을 녹여내는 자리라고 생각했습니다. 저는 오픈 미션을 할때 주제에 대해 고민하는 시간이 정말 오래 걸렸습니다. 그렇다고 해서 새롭게 기획하고 도전했던 내용을 최종 코테에서 녹여내기는 조금 어렵겠다는 생각이 들었습니다. 그와 반대로 리팩터링은 1주차부터 3주차때 연습했던 TDD와 클린 코드를 위해 했던 도전들, 그리고 오픈미션을 도전하면서 느꼈던 리팩터링의 중요성을 경험했기에 프리코스에서 했던 도전을 잘 녹일 수 있을 것 같았습니다. 그래서 저는 리팩터링, 클린코드를 목적으로 개발을 시작했습니다.
구현은 2시 40분 쯤에 완료했습니다. 도전과제 성공의 전제 조건은 요구사항을 만족하는 것이었기에, 우선 그동안 연습했던 방식으로 구현을 완료 했습니다. 하지만 TDD를 추구하며 개발했기에 평소보다는 조금 오래걸렸던 것 같습니다. 구현도 중요하지만 도전 과제도 중요하기에 약 20분 동안 도전과제를 어떻게 수행할지 리드미에 정리했습니다.

(다시 보니까 리팩토링을 래픽터링으로 오타를 냈네요..ㅎㅎ 머쓱)

작성을 완료할 때 쯤, 3시부터 10분간 일괄 휴식시간을 가졌습니다. 모두 노트북을 닫고 쉬는 시간을 가졌는데, 이때 중간에 포비님께서 좋은 말씀들을 해주셨습니다. 그리고 자주 하는 실수들에 대해서도 이야기 해주셨는데, 바로 레포지토리를 포크하지 않고 바로 클론해서 push가 안되는 경우였습니다. 사실 제가 시험 시작때 할 뻔한 실수라 공감이 되었습니다ㅎㅎ
10분 쉬고 다시 시작하니 확실히 이전보다 집중이 잘되었습니다. 남은 1시간 50분 동안 무한 리팩터링 천국? 지옥?을 하면서 계속 리팩터링 했습니다. 그리고 프리코스, 최종 코테 연습에서 TDD와 리팩터링을 끝까지 해보아서 다행이란 생각이 들었습니다. 4시 58분까지 리팩터링을 하고, 5시부턴 왜 리팩터링을 이렇게 했는지에 대해 하고 싶은 이야기들을 적으며 회고했습니다. 아래는 회고문 일부입니다!
저는 리팩터링 도전을 선택했습니다. 이 선택이 저에게 중요한 이유는 오픈미션에서 리팩터링을 제대로 하지 못해서 코드의 맥락 파악과 관리를 하지 못했던 경험이 있기 때문이었습니다. 따라서 오픈미션과 최종 코딩 테스트에서 연습했던 리팩터링의 필요성과 저만의 기준을 이용해 조금은 급하게 짠 코드의 품질을 높히는 도전을 했습니다.
프리코스에서 연습한 TDD를 끝까지 적용하기 위해 노력했습니다. 개발을 할 때는 두 가지 뇌의 스위칭이 필요합니다. 첫 번째는 기능이 안전하게 돌아가는지 확인하는 뇌, 두 번째는 기능을 효율적으로 구현하는 뇌입니다. 개인적으로 기능을 효율적으로 구현하고 나면, 기능이 안전하게 돌아가는지를 제가 짠 로직에 근거하여 테스트 하게 됩니다. 따라서 이를 방지하고 더 안전한 기능을 만들기 위해 저는 테스트 코드 -> 기능 개발 -> 리팩토링을 하는 TDD를 차용했습니다. 연습을 하면서 TDD가 장점이 됨을 느꼈던 순간은 사용자의 입력값 유효성을 검증할때 였습니다. 사용자 입력값은 상당히 자유롭기 때문에, 다양한 값에 대해서 유효성을 검증 해야 합니다. 하지만 이를 테스트 코드 없이 먼저 개발하게 되면 무조건 실수가 일어나는 경험을 했습니다. 그리고 유효성 검증 메서드의 테스트 코드를 먼저 짜고 개발을 하니 예외를 잘 검증하는지 확인하는 시간도 대폭 줄일 수 있었고 실수 또한 줄었습니다.
이처럼 TDD가 가져다주는 장점도 있지만, 아쉬운 부분도 있었습니다. 바로 private 메서드를 테스트 하기 위한 public 전환 입니다. 저는 이번 행성 로또의 등수를 계산할 때, calculateRank() 라는 메서드를 사용했습니다. 하지만, 이는 calculateResult()에서만 이용하기 때문에 public으로 둘 필요가 없었습니다. 하지만 제가 calculateRank()를 public으로 둔 이유는, 행성 로또 프로그램에서 핵심이 되는 로직이었기 때문입니다. 등수는 실행 결과에 심각한 영향을 줄 수 있기 때문에, calculateRank() 메서드의 동작 확인을 테스트 하는 테스트 코드가 있어야 했습니다. 따라서 TDD를 지향하기 위해 외부에서 사용하지 않는 메서드의 테스트를 위해 public으로 변경했습니다.
저는 프리코스 2주차 미션을 하면서, 도메인 주도 개발과 MVC 패턴의 충돌 경험을 했습니다. 그리고 이런 경험은 최종 코딩테스트 연습을 할 때 적극적으로 반영되었습니다. 위에서 언급한 바와 같이, MVC패턴과 도메인 주도 개발 사이의 저만의 합의점을 찾아내었습니다. 그리고 이번 코드에서 MVC 패턴의 장점이라고 생각하는 계층 끼리의 책임 분리와, 로또 도메인을 활용하여 적절한 비지니스 로직을 만들었습니다.
리팩토링을 하면서 또 노력했던 것은 바로 정책에 유연한 프로그램을 만드는 것이었습니다. 프리코스 3주차 미션에서는 로또 1장의 가격은 1000원, 로또 번호의 범위는 1에서 45, 로또 번호의 개수는 6개, 로또 등수 책정 방법도 행성 로또와는 달랐습니다. 저는 이처럼 같은 프로그램이더라도, 정책이 달라질 수 있겠다는 생각이 들었습니다. 따라서 로또 1장의 가격, 로또 번호의 숫자 범위, 로또 번호의 개수를 PolicyConstant로 분리했고, 등수는, Rank enum으로 분리하고 of()메서드를 활용하여 로또가 당첨 번호와 몇 개가 맞는지와 보너스 번호 일치 유무를 가지고 Rank를 반환하도록 했습니다. 이렇게 분리 하면, 이제 정책을 변경하고 싶을 때 프로그램을 수정할 필요 없이 PolicyConstant와 Rank의 of만 수정하면 됩니다. 이렇게 되면 정책 변경을 할 때 발생하는 비용을 줄일 수 있어 효율적이라고 생각합니다. 추가로 ErrorMessage에서도 정책값을 사용하고 있어 이에 맞게 에러 메세지도 변경될 수 있도록 리팩터링 했습니다.
저의 리드미 파일의 리팩터링 리스트를 보시면, "기본 메서드를 제외한 모든 메서드 15줄 이하로 리팩터링하기"를 완료하지 못했습니다. 완료를 하지 못했던 부분은 Rank에 있는 of() 메서드였습니다. 저는 "기본 메서드를 제외한 모든 메서드 15줄 이하로 리팩터링하기"의 목적은 메서드는 하나의 기능만 하도록 하는 것과 더 나은 가독성을 위함이라고 생각했습니다. 하지만 of() 메서드는 메서드의 줄이 15줄을 넘어가지만, 하나의 기능만 할 뿐 아니라 가독성 또한 충분히 좋습니다. 오히려 15줄이라는 맹목적 규칙에 맞게 리팩터링을 하게 되면 직관적이지 않은 메서드가 될 것이라 생각하여 이를 남겨두었습니다.
5시 50분 쯤 소감문 작성을 완료하고 6시까지 내용 검토 후에 시험이 끝났습니다.

최종 코테가 끝나고 그동안 했던 활동과 그때의 기억들이 주마등처럼 스쳐지나갔습니다. 학교 중간고사가 끝날때 시작하여 종강을 하고 해가 바뀌는 동안 상당히 긴 기간동안 프리코스를 하면서 그동안 생각해보지 못했던 것에 대해 고민해보고 디스코드에서 다양한 사람들의 글을 읽으며 저 또한 많이 성장한 것 같습니다.
마지막으로 우아한테크코스의 프리코스와 최종 코딩테스트를 준비하면서 저는 참 많은 도전과 성취를 한 것 같습니다. 무언갈 간절히 바랐던 것도, 바라던 목표를 이루었던 것도, 간절히 바라던 목표를 이루고 싶어 열심히 연습했던 것도 저에겐 모두 값진 경험이었습니다. 오늘부로 최종 코딩테스트도 모두 마무리 되었지만, 앞으로 또 다른 이루고 싶은 목표가 생긴다면 지금 우아한테크코스를 준비했던 마음과 태도를 가지고 도전할 준비를 할 것 같습니다.
일단 10월부터 대학교 공부와 동아리 프로젝트, 프리코스를 병행하면서 정말 바쁜 나날을 보냈습니다. 종강 후에도 제대로 휴식이란걸 하지 못한 것 같아 며칠은 푹 쉴 것 같습니다. 그리고 결과에 상관없이 해야할 일들이 있기에 이제 그 일들을 할 것 같습니다.
이번에도 역시 합격을 기대하지 않습니다. 사실 합격을 기대하지 않기 위해 노력중입니다. 결과에 흔들리지 않기 위해 최선을 다해 노력했지만, 노력했기에 기대를 하게 됩니다. 그래도 남은 기간 동안 이런 마음과 생각을 잘 다스리는 것도 앞으로 수없이 해야 할 중요한 도전에 좋은 경험이 될 것 같습니다.
정말 마지막으로 다들 수고하셨습니다:) 그리고 부족한 글 읽어주셔서 감사합니다!
26.01.23 - 최종 합격 했습니다! 최종 합격 회고로 뵙겠습니다☺️
저도 7기 프리코스 해봤지만 학기 중에 병행하기 어려우셨을텐데 대단하시네요.. 원하시는 결과 얻으셨으면 좋겠습니다!!