두둥.
드디어 우아한 테크코스 마지막 전형인 최종 코딩테스트를 응시하였다!
그간 고생했던 나, 그리고 프리코스 동료들 모두 수고하셨습니다. 😊
최종 코딩 테스트는 우아한 테크코스 선릉 캠퍼스에서 진행되었다. 모두가 선릉인 것은 아니고, 잠실 캠퍼스와 선릉 캠퍼스로 적절히 나뉘는 듯 했다.
우아한 테크코스의 최종 코딩 테스트는 알고리즘 테스트가 아니라, 프리코스 때 1주일동안 풀었던 문제들을 5시간 안에 구현해내는 것이 과제이다. 나는 프리코스에서 많은 성장을 경험했기 때문에 이 경험들을 총정리할 수 있는 최종 코딩테스트를 꼭 응시해보고 싶었고 감사하게도 대상자로 선정이 되어 오프라인으로 코딩 테스트를 응시할 수 있게 되었다.
💪 최종 코딩테스트 대비
프리코스가 끝나고부터 매주 하나씩 스터디에서 문제를 풀고 코드 리뷰를 하였었는데, 1차 심사 합격이 나고 나서 거의 매일 문제를 풀었던 것 같다. 꼭 최종 코딩테스트에서 내가 프리코스 기간에 성장하면서 얻었던 모든 것을 쏟아내고 오겠다는 생각으로 ..
최종 코딩 테스트는 오픈북이었기 때문에 최대한 많은 자료를 미리 가져가는 것이 좋다고 생각하였고, 아래와 같이 깃허브에 정리하기도 했다.
https://github.com/Mingyum-Kim/woowacourse-archive/tree/main/codingtest
그러나 코딩 테스트에서는 이 자료를 활용하지 않는 것을 추천하고, 실제로 나도 이 깃허브를 거의 참고하지 않았다. 여기 있는 내용을 외워가서 바로 작성하는 편이 시간 단축에 훨씬 좋고, 문제에 따라서 활용이 매우 달라지기 때문에 문법을 체화해서 스스로 적용할 수 있도록 훈련하는 것이 가장 좋다.
나도 코딩 테스트 당일에 모든 효율을 높이기 위해 내가 그간 써먹은 문법들은 모두 스스로 사용할 수 있게끔 연습하였고, 반복적인 로직이나 기본적으로 생성할 클래스는 snippet을 사용하였다.
snippet은 별거 아닌 것 같지만 정말 좋다. 은근 코딩 테스트 당일에는 정신이 없어서 일일이 내가 필요한 로직을 찾아서 작성하기가 힘들다. 가장 중요한 도메인 로직 개발에 내 시간을 온전히 쓰기 위해 그 부가적인 것들은 최대한 미리 준비해서 가려고 하였다.
내가 프리코스가 끝나고부터 최종 코딩테스트를 준비하기 위해 풀어봤던 문제들은 아래와 같다.
🚇 3기 프리코스 3주차 (지하철 노선도 경로 조회)
미션 PR : woowacourse/java-subway-map-precourse#122
📮 4기 프리코스 3주차 (자판기)
미션 PR : haebyun/java-vendingmachine-precourse#1
👫 4기 최종 코딩테스트 (페어 매칭)
미션 PR : woowacourse/java-pairmatching-precourse#164
미션 PR : haebyun/java-pairmatching-precourse#2
🌉 5기 프리코스 4주차 (다리 건너기)
미션 PR : bark20/java-bridge#9
🍱 5기 최종 코딩테스트 (점심 메뉴 추천)
미션 PR : haebyun/java-menu-precourse#1
⚾ 6기 프리코스 1주차 (야구 게임)
미션 PR : woowacourse-precourse/java-baseball-6#2794
🚗 6기 프리코스 2주차 (자동차 경주)
미션 PR : woowacourse-precourse/java-racingcar-6#2397
🎄 6기 프리코스 4주차 (크리스마스 프로모션)
미션 PR : woowacourse-precourse/java-christmas-6#17
최종 코딩테스트를 대비하기 위해서는 최대한 많은 문제를 풀어보면서 핵심을 구현하는 시간을 줄이고, 짧은 시간에 리팩토링과 테스트를 작성하는 것이 관건이라고 생각하였다. 그래서 간간히 개인 노트에 문제를 풀 때마다 막혔던 점, 어려웠던 것 등을 작성하면서 문제를 최대한 많이 풀고자 하였고, 문제를 풀 때마다 아래와 같이 새로운 목표를 정하고 다양한 문제 풀이 접근법에서 나의 효율성을 실험해보고자 하였다 .
그 결과 제한된 시간 내에 문제를 해결하는 나만의 루틴을 만들 수 있었고, 구현하다가 구글링을 하게 되는 문법이 있다면 따로 기록해서 다시 공부함으로써, 다음 문제 풀이에서는 바로 적용할 수 있도록 준비하였다.
내가 문제를 푸는 루틴은 아래와 같다.
초기 설계 (최대 1시간)
1. 전체 실행 결과 읽기
2. 세부 요구사항 파악하기
3. 테스트 코드 읽고 최종 구현 목표 파악하기
4. 10분 이상 프로그램 설계하기
5. 기능 구현 목록 작성하기
6. PR 보내기
개발 단계 (최대 3시간)
1. 구현 목록을 바탕으로 프로그래밍하기 (⭐기능 별 커밋⭐)
2. 리팩토링하기 (체크리스트)
3. 테스트 코드 작성하기
마무리하기 (최대 1시간)
1. 시스템 흐름도를 docs/README.md에 추가하기
2. 최종 제출 후 소감문 작성하기
나는 이 루틴 중에서 초기 설계 단계를 정립한 것의 큰 효과를 보았다.
원래는 기능 요구사항을 눈으로만 읽고 기능 구현 목록을 바로 작성하였는데, 내가 정한 루틴대로 하면 요구사항을 더 꼼꼼히 읽을 수 있고 내가 어떻게 이 기능을 구현할 지 설계 단계에서 윤곽이 잡히기 때문에 코딩이 더 쉬워진다.
나는 급박한 시간 제한 안에 문제를 풀려다보니 설계를 패스하고 바로 코딩하는 경향이 있다는 것을 알게 되었다. 그래서 의식적으로 초기 단계에 힘을 실어서 그 이후의 개발 단계에 꼬이는 일이 없도록 해당 루틴을 그대로 따랐다.
최종 코딩테스트 전날에는 문제를 하나 푼 다음, 최종 코딩 테스트 당일에 참고할 여러 자료들을 미리 준비하고
프리코스 문제들을 설계 단계까지만 연습해보며 실제 코딩테스트 환경을 시뮬레이션 하였다.
👩💻 최종 코딩 테스트 당일 & 문제 해결
설렘 반 긴장 반 인천에서 출발하여 1시간 반 거리를 선릉 캠퍼스로 향했다.
잠을 덜 잔 상태 + 아침 공복 지하철 타는 건 너무 힘들었다 ,, 가는 길에 조금이라도 더 복습하려고 하였는데
골골거리느라 복습이고 뭐고 아무것도 못했다. ㅎ
그렇게 도착한 선릉 캠퍼스에서는 우아한 형제들이라는 로고가 똭! 나를 반겨주었다.
캠퍼스 내부에 들어오니 신분증을 검사하고, 우아한테크코스 굿즈와 다과를 챙겨서 시험장 안으로 입실하였다.
시험장은 긴 테이블이 여러 개 붙어있어서 다른 참여자들과 나란히 앉아 시험을 보는 형태였다.
생각보다 다른 참여자들이랑 밀접하게 앉아있고 테이블을 사용할 수 있는 공간이 넓지는 않았다.
나는 노트북 거치대와 조금 큰 키보드, 마우스를 가져와서 양쪽 두 분에게 양해를 구하고 환경을 세팅하였다.
아, 그리고 왼손 코치님을 처음 뵀는데 인터넷에서만 보던 사람을 실제로 보니 너무 신기하고 내가 스스로 노력하여 우테코라는 곳에 와서 시험을 본다는 게 실감이 났다.
인터넷 상에서 나와있는 모든 코딩 테스트 후기를 찾아보면서 수없이 읽은 본문이다. 막상 미션을 전달받게 되니 마음이 많이 불안했고 그저 후회없이 최선을 다하기만 하자고 한번 더 다짐하였다.
그렇게 시간이 되어 문제가 출제되고, 기존에 연습했던 나의 루틴대로 문제를 읽고 풀어보면서 문제를 해결해 나갔다.
https://github.com/woowacourse-precourse/java-oncall-6
문제는 oncall, 비상 근무표를 생성하는 기능을 구현하는 것이다.
요구사항이 복잡해보이지만 찬찬히 읽어보면 입력된 월, 시작요일을 기준으로 월-일-요일-근무자를 배정해서 출력하는 것이 핵심이었다. 나는 문제를 읽고 설계하는 단계에서 자바의 Deque를 생각하였고, 이 컬렉션을 사용해 평일 및 휴일 순번에서 근무자를 꺼내어 최종 근무표에 넣고, 다시 맨 뒤로 돌려서 순번을 순회하는 로직을 구상하였다.
그렇게 구상한 설계로 기능 요구사항을 작성하고, 무난하게 프로그래밍을 하여 ApplicationTest를 3시간 만에 통과하였다. 2시간이 남은 상태라 나머지 시간동안 못 챙겼던 리팩토링과 테스트코드를 작성하기로 하고, 일급 컬렉션 생성과 검증 로직 분리, 요구사항을 한번 더 확인하는 등 코드를 거치며 커밋을 이어나갔다.
그런데 문제는 한시간 후에 발생하였는데 ....
갑자기 예상치못한 곳에서 에러가 발생하였다. 한창 리팩토링을 거치며 커밋을 하다가 ApplicationTest를 실행해보았는데 이런 에러가 떴었다.
처음 보는 에러라 조금 당황했지만, 시간이 많은 상태라 음? 왜 이럴까? ㅎㅎ 하고 여유로운 마음으로 코드를 살펴보았는데, 당시 내가 할 수 있는 모든 것을 해봐도 에러가 해결되지 않았다. Console.readLine() 메서드를 사용하면서 Scanner가 중간에 close 된다거나 등의 이유로 동작이 안된다는 것이었는데, 나는 콘솔 입출력과 관련해서 어떠한 중간 코드를 넣지 않았고 수없이 문제를 풀어오면서도 마주하지 못한 에러라 짧은 시간 안에 도무지 해결할 수 없었다.
이렇게 문제가 나는 코드를 들여다보고 있어도 모르겠고, 인터넷에 나온 해결방법을 최대한 적용해봐도 안되었다. 그렇게 점점 심각해져가는 상황에서 야속하게 시간은 흐르고 있었고, 그렇게 30분 정도 붙잡고 있으니 어느새 제출 시간이 되고 있었다. 그 때 나는 최후의 선택을 해야했다.
남은 시간동안 이 에러를 더 보고 있느냐, 아니면 해결되었던 시점의 커밋으로 되돌아가서 돌아가는 쓰레기를 제출할 것이냐 .. 마감 30분이 남은 시점에서 할 수 있는 선택은 지난 한 시간동안 구현한 리팩토링 커밋을 모두 버리고 ApplicationTest가 돌아가는 코드를 제출하는 것이었다.
그래서 정말 피눈물을 머금고 열심히 리팩토링해오고 세세한 검증로직을 작성한 커밋을 모두 Undo 하였고, 다행히 그 뒤로는 테스트 코드가 잘 돌아갔기에 얼른 소감문을 쓰고 제출을 완료하였다.
그 결과 모든 요구사항을 꼼꼼히 코드에서 보여주지 못했고, 내가 그동안 쌓아온 클린 코드와 테스트코드를 결과물에 반영하지 못해 이루 말할 수 없이 너무 아쉽고 아쉬웠다.
한번 뿐인 기회였는데 이렇게 준비한 것을 모두 쏟아내지 못하고 예상치 못한 곳에서 시간을 허비하게 된 게 너무 아쉬웠다. 소감문에서도 쓸 말이 많았는데, 시간에 쫓겨 최종 코딩테스트에서 충분히 저를 드러내지 못한 게 아쉽다는 말만 하다가 끝낸 것 같다.
여담으로 저 에러는 입력값에 대해 검증하고 예외를 던지는 메서드를 하나 추가하기만 하면 생겼다.
private void validateTotalSize(List<String> weekday, List<String> weekend) {
int totalSize = weekday.size() + weekend.size();
validateRange(totalSize, 5, 35);
}
private void validateRange(int number, int start, int end) {
if (isInvalidRange(number, start, end)) {
throw CustomException.from(ErrorMessage.INVALID_INPUT_ERROR);
}
}
private boolean isInvalidRange(int number, int start, int end) {
return number < start || number > end;
}
이렇게 전체 근무자에 대한 수를 검증하는 로직을 작성하였는데, 이걸 추가하면 에러가 생기고 없애면 에러가 안생겼다. (진짜 뭐지) 지금까지 이 로직을 그대로 다른 미션에서도 많이 사용해왔으므로 검증된 로직이고, 정말 아무런 문제를 발견하지 못하였다. 콘솔 입력에서 생기는 에러와 무슨 상관이 있는 건지도 .. 아직도 모르겠다.
아무튼, 그렇게 시험을 끝내고 아쉬움 가득한 마음으로 나와서 최종 코딩테스트를 함께 본 사람들과 술을 마시러 갔다 ㅎㅎ
아쉬운 점은 많았으나 누구나 그렇듯 뭐든지 완벽하게 해내기란 힘든거고, 결과와 상관없이 난 정말 최선을 다하였다고 말할 수 있기 때문에 미련을 갖지 않기로 하였다.
길고 긴 우아한테크코스 입과 과정이 끝났지만, 여전히 내 마음은 우아한 테크코스에 머물러 있다. 돌이켜보면 이렇게 단기간 성장할 수 있었던 순간이 있었나 싶고, 우아한 테크코스에 실제로 입과하게 되면 얼마나 성장할 수 있을지도 많이 기대가 된다. 정말 간절했던 만큼 후회하지 않기 위해 내 모든 시간과 노력을 투자하였고 이 또한 하나의 몰입 경험으로 앞으로의 삶을 살아가는 데 있어서 큰 자산이 될 것 같다.
좋은 경험을 하게 해주신 우아한 테크코스에게 감사드리며 .. 🥰
'우아한테크코스 > 레벨0' 카테고리의 다른 글
[회고] 우아한테크코스 6기 백엔드 최종 합격 후기 & 총정리 (10) | 2023.12.27 |
---|---|
[회고] 우아한 테크코스 6기 백엔드 최종 코딩테스트 회고 & 리팩토링 - 온콜 (1) | 2023.12.25 |
[회고] 우아한 테크코스 최종 코딩테스트 대비 - 지하철 노선도 (0) | 2023.12.14 |
[회고] 우아한 테크코스 최종 코딩테스트 대비 - 다리 건너기 (0) | 2023.12.13 |
[회고] 우아한테크코스 1차 심사 합격 + 앞으로의 계획 (0) | 2023.12.13 |