우아한테크코스 7기 BE 최종 합격 후기

ppparkta·2024년 12월 27일
3

회고록

목록 보기
11/11

어쩌다 지원했나요?

프로젝트 경험은 많지만, 기초가 부실한 개발자 == 나

자바 개발자로 취업하고 싶은데 자바를 잘 다루지 못한다는게 늘 마음에 걸렸다. 자바 연습하는데엔 우테코 프리코스만한게 없다는 이야기를 종종 들었는데, 그 와중에 지인들 중 지원하는 사람이 많았기에 그렇게 지원하게 됐다.

시작은 가벼운 마음이 컸다.

인생 경험 자소서에 녹이기

지원 동기

분명 자바 공부 하려는 가벼운 마음이었지만, 지원서만큼은 공을 들여서 작성했다. 기업 자소서를 쓰고 있었기 때문에 자소서 항목을 뽑아내는 것은 어차피 해야 하는 일이었다.

다만, 우테코는 동아리나 기업 자소서에 비해 문항수가 적은 대신 글자수 제한이 컸다. 그래서 한 문항 안에 서사있는 사람으로 보이게 최대한 나를 포장했던 것 같다.

사실 나는 사학과에서 시작하여 복수 전공, 전과를 거쳐 전공자가 된 케이스이다. 20대 초반 내 진로는 풍파를 많이 맞은 상태였기에 왜 역사 공부 하던놈이 개발을 하게됐냐? 를 설득력 있게 담아내는게 중요하다고 생각했다.

대학교만 6년 다닌 사람으로서 이에 대해서는 할 말이 꽤 많았다.

지원 동기와 어떤 프로그래머가 되고 싶은지는 이런 인생 서사를 그냥 쭉 늘여썼다.

오랜 시간 몰입했던 경험

오랜 시간 몰입했던 경험은 생각나는게 여러개 있었는데, 그중에서 가장 오래 해온 일기쓰기를 썼다.

일기 쓰는게 무슨 몰입이냐 싶겠지만, 일기는 나를 P형 인간에서 J형 인간으로 바꿔준 고마운 친구다. 일기를 쓰기 시작하면서 15kg 다이어트도 성공하고 수석도 해보는 긍정적인 경험을 했는데, 그런 과정이 어떻게 이뤄졌는지를 썼다.

글쓰는 재주가 많지 않아 밋밋한 글이었지만, 일기쓰기와 회고를 메타인지와 엮어서 작성했다. 우테코 설명회에서 강조했던 키워드였다.

증빙 자료에는 내가 썼던 내용을 증명할 수 있도록 이에 관련된 사진과 주석을 첨부했다.

프리코스 목표

프리코스를 하면서 이루고싶은 목표는 여러 개가 있었다. 자바 실력의 상승이 가장 큰 목표였지만, 그걸 그대로 적기보단 지인들과 스터디를 계획하고 있었기 때문에 지원동기와 연결되도록 협동을 키워드로 작성했다.

스터디에서 계획해두었던 내용을 바탕으로 클린코드, 코드리뷰에 적극적인 사람이 되고자 했다.

마지막 문항은 스터디 계획서를 풀어쓰니 금방 작성할 수 있었다.

동기부여가 된 프리코스

프리코스는 디스코드와 우테코 지원페이지를 통해 진행됐다.

일단 지원하기만 하면 모두에게 프리코스에 참여할 기회를 준다니, 우테코에 가장 큰 호감을 느낀 부분이었다.

애플리케이션을 예쁘게 만들 자신은 없지만, 주어진 기능을 잘 돌아가게 만들 자신은 있었기 때문에 프리코스는 과제 중심으로 적극적으로 참여하고자 했다.

어벤저스터디

우테코에 지원한 학교 내 지인들과 함께 작은 규모의 스터디를 계획했다.
그러다가 스터디원 중 한명이 외부 인원도 받으면 코드리뷰가 더 다양해질 것 같다는 의견을 주었고, 스터디원을 추가로 모집하게 됐다.

초기 스터디원은 나를 포함하여 3명이었지만, 2주차가 시작할때 쯤 스터디원은 총 7명이 됐다.

인원이 많아지다보니 다양한 사람들을 볼 수 있었는데, 신기하게도 스터디원들 모두가 개발을 잘 했다. 나 혼자만 감자고 다른 사람들은 전부다 은둔고수처럼 느껴졌다.

스터디 방식은 노션을 통한 데일리 회고 공유, 주 1회 대면 코드 리뷰로 진행됐다.

데일리회고는 말 그대로 매일 하루를 회고하는거였다.

회고 구성은 매일 잘한 점, 아쉬운 점, 개선할 점 세가지의 항목을 하나 이상 작성하면서 하루를 피드백하는 방식이었다.

노션으로 진행했기 때문에 가끔 내 회고를 보고 다른 분들이 궁금한 점이나 의견을 댓글로 남겨주시기도 했다. 이런 댓글을 통한 토론을 통해 한번 더 생각해볼 수 있었던게 회고에서 가장 좋았던 것 같다.

주 1회 대면 코드 리뷰는 점진적으로 개선됐다.

처음에는 코드리뷰 방법이 자리잡히지 않아서 그냥 코드를 쭉 설명하는 식으로 진행됐다. 그런데 이렇게 진행하다보니, 내 코드에서 눈에 띄는 부분만 얘기하게 됐고, 그렇게 발표하는 식으로 하니까 제대로 리뷰가 진행되지 않는다는 느낌을 받았다.

다른 사람들도 코드 전반을 모두 이해하는건 까다로우니 그냥 와 이런식으로 짜다니 신기하네요~ 이런 느낌의 피드백 밖에는 주지 못했다.

그래서 2주차부터는 각자의 코드를 쭉 설명하지 않고, 대면 스터디 전 미리 스터디원들끼리 PR로 코드 리뷰를 진행한 뒤에 스터디룸에서 코드에 달린 코멘트를 주제로 간단히 토론을 하는 식으로 방식을 변경했다.

코드를 짤 때 충분히 생각하고 개발하는 사람들을 보면 배울 점이 참 많았는데, 스터디원분들 모두 개발을 할 때 사소한 디테일에도 고민하며 개발하는 분들이었다. 그렇다보니 대면 스터디는 한 번 모일때마다 최소 2시간에서 최대 4시간까지도 진행됐다. 배울 점도 참 많았다.

가장 기억에 남는 토론은 <왜 일급컬렉션을 사용해야 하는가?>에 대해서였다. 대체로 사용하는 것이 무조건 좋다는 의견이었으나, 각자가 생각하는 이유가 달랐기에 서로 그 이유를 늘어놓고 그 이유에 부합한 구현을 해온 것이 재미있었다.

나는 일급컬렉션을 공부하겠다고 데일리 회고에 써놨지만, 계속 미루다가 스터디에서 이야기가 나온 다음 날 부랴부랴 다시 공부를 했다. ㅋㅋ

1주차

첫번째 미션은 덧셈만 가능한 계산기를 만드는 미션이었다. 커스텀 구분자를 추가할 수 있다는 특이사항이 있었는데, 파싱은 C언어로 자주 해봤기 때문에 C언어로 개발했던 스타일 그대로 코드를 작성했다.

사실 객체지향에 대해서 고민을 많이 안 했기 때문에 처음에는 하나의 클래스 안에 코드를 쭉 써내려갔다.

그러다 제출하기 직전에 좀 아닌가...? 싶어져서 클래스를 분리하기 시작했다.

그러나 생각없이 써내려간 코드는 뒤늦게 쪼갠다고 책임에 맞게 분리해내기 어려웠고, 클린코드는 아예 고려하지도 못한채로 이렇게 되어버린 메서드를 제출하게 된다.

public List<Integer> parse(String removedString, List<String> separator) {
        List<Integer> operand = new ArrayList<>();
        String tmpOperand = "";

        for (int i = 0; i < removedString.length(); i++) {
            int separatorLength = isSeparator(removedString.substring(i), separator);

            if (separatorLength != -1) {
                if (!tmpOperand.equals("")) {
                    operand.add(Integer.parseInt(tmpOperand));
                    tmpOperand = "";
                }
                i += separatorLength - 1;
            } else if (Character.isDigit(removedString.charAt(i))) {
                tmpOperand += removedString.charAt(i);
            } else {
                throw new IllegalArgumentException("등록되지 않은 구분자가 포함되어 있습니다.");
            }
        }
        if (!tmpOperand.equals("")) {
            operand.add(Integer.parseInt(tmpOperand));
        }
        return operand;
    }

제출할 때까지만 해도 나름 클래스도 분리했으니 이정도면 잘 짠 코드라고 생각했다.
그러나 매주 진행되는 과제 피드백과 코드 리뷰를 통해 1주차 코드가 아주 잘못됐음을 깨달았다.

https://github.com/woowacourse-precourse/java-calculator-7/pull/477

MVC에 대해 더 고민해보고 코드를 짜면 좋을 것 같다는 피드백을 많이 받았다.

이 리뷰에는 model에 부여한 책임이 작다는 피드백이 달렸는데, 사실 MVC 각각의 책임이 뭔지도 잘 몰랐다. 그냥 스프링부트에서 흔히 쓰던 개발 방식을 적용했을 뿐이었다.

역할? 책임? 익숙한 단어였지만 공통적으로 등장하는 느낌에 이것이 단순히 뜻에 맞게 사용하는게 아니라 어떠한 보편적인 단어일거란 느낌이 들었다.

그렇게 생각해보니 객체지향의 사실과 오해라는 책을 읽었을 때 이러한 단어들이 공통적으로 등장하던 것이 생각났다.

내게 리뷰를 달아준 사람들은 SOLID에 입각한 코드를 짜기 위해서 노력하고 있었다. 그에 비해 내 코드는 구색만 갖춘 허접한 코드라는 생각을 지울 수 없었다.

하루종일 리뷰 보며 생각하고 있으니 뒤늦게 부끄러움이 밀려왔고, 잘 이해하지 못하고 코드를 짰다는 답변만을 반복하게 됐던 것 같다.

이때부터 자바를 잘 하려면 객체지향을 공부해야겠다는 생각이 들기 시작했다.

2주차

2주차 스터디에서는 1주차 미션의 공통 피드백이 나왔다.

클래스나 메서드명을 통해 의도를 분명히 드러내야 한다는 피드백을 받았다. 공백, 스페이스, 주석 또한 클린코드에 영향을 준다는 사실을 알게 됐다.

1주차 미션에서 남들 다 쓰는 MVC 패턴을 나도 써보고자 깊은 생각 없이 도입했었다면, 2주차부터는 각 레이어가 수행해야 할 역할들에 대해서 조금 더 신경을 쓰기 시작했다.

그래서 2주차는 아래의 것들을 생각하면서 개발하게 됐다.

  • 패키지와 클래스의 중복 고려하여 네이밍하기
  • else 사용 지양하기
  • 인덴트 깊이 3단계 지양하기
  • 한 메서드의 길이 15줄 이내로 제한하기
  • 메서드 길이 줄이기 위해 헬퍼 함수의 도입 고려해보기
  • 변수의 단수,복수 맞추기
  • 코드의 책임 분리가 잘 되었는지 스스로 판단해보기

1주차 코드 리뷰로 받은 피드백과 공통피드백의 내용을 합산하여 정리한 것이다.

2주차 미션이었던 자동차 경주는 이러한 부분을 최대한 지켜내기 위해서 노력했다.

https://github.com/woowacourse-precourse/java-racingcar-7/pull/1050

하지만 여전히 역할 분리에 미숙함이 많았다.

그리고 2주차부터 단위테스트 코드를 작성하기 시작했다.

테스트코드를 작성하면서 위화감을 굉장히 많이 느꼈다. 테스트코드는 본문 검증을 위함인데, 테스트코드를 작성하기 위해서 코드 본문을 수정해야 하는 일이 생겼다. 특히 private으로 되어있던 메서드를 public으로 수정하거나, 본문에 사용하지 않는 생성자나 getter를 추가하는 일이 빈번해졌다.

3주차에 작성했던 소감문을 백업해두었는데, 소감문에도 이러한 단위테스트에 대한 아쉬움을 적었다.

한가지 뿌듯했던 점은 테스트커버리지를 높게 유지할 수 있었던 점이다. 테스트코드를 작성하면서 개발을 진행하다보니 내 코드에 확신이 생겨서 좋았다. 게다가 중간에 코드 수정이 빈번했는데도 테스트에 통과하기만 하면 내가 세운 일정 선은 넘은 느낌이었기에 귀찮은 확인 과정을 생략하고 개발에만 몰두할 수 있었다.

2주차 미션은 MVC패턴에 익숙해지고 테스트코드를 유용하게 써봤다는 점에서 배워간게 많았다.

3주차

3주차 미션인 로또에서는 2주차에 느꼈던 위화감을 해결하려는 방법으로 TDD를 도입했다.

이건 스터디원분이 이미 프로젝트를 TDD로 진행하고 계셔서 방법에 대해 조언을 많이 얻었는데, 일단 도메인 설계부터 진행하면서 메인 로직만 생각하고 인터페이스는 후순위로 미뤄두라는 이야기를 해주셨다. 그러다보면 테스트가 필요한 비즈니스로직이 나중에 수정되는 일이 적어진다는 조언이었다.

그 방법대로 TDD를 도입하여 로또 미션을 수행했는데, 테스트코드 작성도 어려워하는 내가 TDD를 도입하려니 시간이 배로 많이 걸렸다.

그리고 3주차 쯤에 공통피드백과 코드리뷰를 통해 일급컬렉션을 사용해야 한다고 깨닫게 됐다.

그래서 3주차는 아래와 같은 목표를 세웠다.

  • TDD를 통해 각 클래스의 기능 분리를 명확히 한다.
    • 각 클래스가 명확한 하나의 큰 기능을 수행하도록 한다.
  • 가독성 좋은 코드를 작성한다.
    • ENUM을 통해 중복되는 값을 관리한다.
    • 인덴트 깊이 2 이내로 작성한다.
    • 한 메서드가 15줄을 넘지 않는다.
    • 클래스, 메서드, 변수명의 의미를 확실히 한다.
  • 의도치 않은 외부 조작을 막는다.

https://github.com/woowacourse-precourse/java-lotto-7/pull/757

3주차 미션은 TDD도입을 통해 설계 방식에 변화를 줬고, 실제로 유의미한 결과를 냈다는 점에서 의미있는 주차였다. 물론 본문에 사용하지 않는 생성자나 getter를 완전히 없앨수는 없었지만, 데이터 조작을 막는 선에서는 이정도는 허용하기로 했다. ㅎ

4주차

대망의 4주차 과제는 편의점이었다.

https://github.com/ppparkta/java-convenience-store-7-ppparkta/pull/1

4주차 미션은 어려웠다.

3주차처럼 TDD로 개발을 시작했는데, 개발 시간이 모자라서 여유있게 제출하던 다른 주차와 달리 거의 마감시간을 10분 정도 남기고 아슬아슬하게 제출했다.

각 요구사항을 파악하고 설계하는 것에만 거의 3일이 걸렸고, 실제 구현은 학교 수업도 빠져가면서 했는데도 불구하고 며칠을 꼬박 새어서야 완성할 수 있었다.

3주차까진 Chat GPT의 도움을 전혀 받지 않고 개발했는데, 4주차는 시간이 부족해서 어떤 로직은 GPT가 써준 것을 그대로 낸 부분도 있었다.

제출하고 나서도 마음이 심란했다.

그 후

4주차 미션이 끝나고 1차 발표까지 몇 주의 시간이 비었다.

4주차 PR 링크 타고 들어가보면 눈치챌 수 있듯이, 4주차 이후 리뷰부터는 스터디 인원이 확 줄었다.

주차별로 스터디 인원이 조금씩 빠지더니 어느덧 나를 포함해 세명밖에 남지 않았다. 그러나 남은 분들이 다들 열심히, 또 깊게 생각하는 분들이셨기 때문에 이분들과 토론하면서 여전히 배워갈 점이 많았다.

스터디 운영하면서 운영방식에 대해 배운 점도 있고, 스터디 자체로 얻어가는 것도 있었기 때문에 스터디는 다시 생각해봐도 잘 한 선택이었다.

스터디에서는 매주 하나의 최종 코딩테스트 문제를 풀면서 1차 합격을 대비하기로 했다.
나는 4주차 과제를 마친 이후로 의기소침해 있었는데, 예전 기수 최종 코딩테스트 문제를 풀다보니 자신감을 되찾을 수 있었다.

5기와 6기의 문제가 생각보다 쉬웠기 때문이었다. 주어진 5시간 중 2~3시간만 투자하면 구현을 완성할 수 있었고 그 이후에 테스트코드를 추가하거나 리팩토링을 하는 등 유지보수하면 5시간을 알차게 쓸 수 있었다.

그러나...

인턴 합격

1차 합격 발표가 나오기 전, 학교 연계로 지원했던 IT기업의 인턴에 합격하게 됐다.

면접을 보러갈때도 설마 싶었는데, 굳이 없는 자리를 만들어서 나를 뽑아주셨다.

면접은 판교에서 진행됐는데, 준비 기간동안 면접을 도와주셨던 주니어 개발자분께 짧게 상담을 받을 수 있었다. 앞으로의 공부 방향이나 인턴을 하게 된다면 해야 할 일들에 대해서 알 수 있었다.

그분 말씀대로라면 2025년은 바빠서 정신없을 정도로 열심히 살아야 했다. 근데 요즘 취업시장 생각하면 그게 당연한거 같기도 했다.

우테코 1차 합격은 지원자 수를 생각했을 때 가능성이 희박하다고 생각했기 때문에 붙은 회사에 가는게 맞다고 생각했고, 그렇게 우테코 스터디는 1차 발표를 한 주 남기고 스터디를 중단하게 됐다.

1차 합격

졸업전시회, 기말고사 준비로 정신없을 때 쯤 1차 결과가 나왔다.

결과는...엥?

저 왜 합격이에요?

스터디를 하면서 나보다 개발을 잘하고 열정도 많은 분들이 많다는 것을 알게 됐다. 나는 열정은 많았지만 개발을 잘하진 않았다. 그냥 열심히 하는 감자였다.

그래서 나는 당연히 1차에서 탈락할거라고 생각했다.

내 어떤 부분을 좋게 봐주셨는지는 아직도 잘 모르겠다. 그래도 이왕 붙여주신거 후회하지 않을 정도로 준비하고 싶었다.

최종 코테 당일

그래서 최종 코딩테스트를 열심히 준비해갔냐고 한다면... 그건 아니었다.

번아웃이 와버렸다.
팀 프로젝트에서 받는 대인관계의 스트레스와 앞으로의 진로에 대한 걱정 때문에 아무것도 손에 안 잡히기 시작했고, 아무것도 안하고 하루 하루가 흘러갔다.

이대로 가다가는 후회할 일밖에 남지 않았다고 생각했고, 시험 전날 겨우 4기 최종 코딩테스트 문제였던 페어매칭 문제만을 풀어본 채로 시험장에 가게 됐다.

페어매칭 문제를 5시간 안에 모두 해결하지 못하고 인터페이스만 조금 깔짝였기 때문에 자신감이 많이 떨어졌다. 그래도 이왕 1차 붙었으니 신나는 마음으로 스터디를 같이 했던 분과 시험 당일에 만나서 가볍게 이야기를 나눴다.

시험장에 들어와서는 그냥 웃음만 나왔다.

문제를 다 풀거라고는 기대도 안 됐고, 그냥 교육장이 예뻐서 사진만 엄청 찍었다.

시험보는 자리는 고정이었다. 다들 좁은 테이블에 세명씩 앉다보니 불편해보였는데, 나는 운 좋게도 가장 마지막 자리에 배정돼서 테이블을 혼자 사용할 수 있었다.

시험장은 누가봐도 우테코 교육장처럼 보였다.

최종 코딩테스트

오후 1시가 되어 시험이 시작됐다.
우테코 교육장의 출석부 시스템을 만드는 과제가 나왔다.

인터페이스 형식이 4주차 페어매칭 문제와 비슷하다는 감상을 했고, 전날 잠깐이라도 문제를 풀어봤음에 감사해지기 시작했다.

전날 만든 인터페이스를 거의 그대로 가지고 와서 인터페이스부터 빠르게 만들었다. 시험 준비하면서 느꼈던건, 내가 도메인 설계에 지나치게 집중하다보면 문제를 제 시간 안에 풀지 못한다는 점이었다.

그래서 매번 부실한 인터페이스를 만들게 됐고, 일단 돌아가는 쓰레기를 만드려면 적어도 최종 시험에서만큼은 도메인 설계보단 인터페이스 구현부터 끝내는게 맞다는 생각을 했다.

그렇게 시험이 시작되고 한시간 반만에 간단한 설계와 기본적인 인터페이스를 구현해낼 수 있었다. 전날 풀어본 문제가 많은 도움이 됐다.

기능 구현

기능 구현은 그냥 저냥 무난하게 진행됐다.

시험 중간에 학장님이 들어오셔서 돌아가는 쓰레기를 만들어야 한다. 도메인 구현하다가 인터페이스 연결 못하는 사람들이 많다. 이런 얘기를 해주셨다.

그래서 그때부터는 클린코드는 버려두고 else 범벅인 코드를 작성했다.

함정

4주차 미션이었던 편의점에서도 테스트코드 내에 숨은 요구사항이 있었다. 이번 최종 미션에서도 비슷한 숨은 요구사항이 존재했다. 그러나 시험장에서는 그런 요구사항을 바로 파악하지 못했고, 테스트를 돌려보고 나서야 뭔가가 있음을 알 수 있었다.

부랴부랴 기존 교육생 초기화 코드에 요구사항에 맞게 기능을 추가했는데, 이미 시간은 종료까지 30분 정도만을 남겨놓고 있었다. 다행히 마지막 테스트코드를 통과할 수 있었지만, 테스트코드에는 없는 4번 기능에 대한 요구사항이 남아있었다.

포기하고 소감문에 집중할까 하다가, 그렇게 하면 시험장을 나서고 후회할거라는 생각이 들었고, 결국 소감문은 5분컷으로 미리 작성한 뒤에 남은 모든 시간을 4번 기능 구현에 쏟았다.

약 20분 남짓한 시간동안 기능을 구현하는건 불가능할거라고 생각했지만, 정렬에 대한 요구사항을 완전히 포기하니 그냥 기존에 만들었던 메서드 몇 개만 가져다 쓰면 끝날 정도로 간단히 구현이 가능했고, 그렇게 시험 종료 2분 전에 4번 기능까지 구현을 완료하게 됐다.

그러나 기능 구현을 하면서 테스트코드 통과를 위한 수정때문에 특정 케이스에서 np가 터질거란 것을 직감했고, 시험이 끝난 후에 혼자 터미널에서 이것저것 테스트해보면서 내 예감이 사실이었음을 알게 됐다.

후기

아쉬움 없는 코드를 짤 수는 없었다. 테스트코드도 못 썼고, 클린코드도 아니고, 요구사항은 많이 빼먹었고... np터지고 <-이게 제일 치명타였다.

그래도 시험장을 나서면서 굉장히 기분이 좋았다.

시간 안에 애플리케이션의 모든 기능을 만들었다는 점에서 스스로가 너무 대견했다. 정렬같은 요구사항이야 구현하고 나서 유지보수하면서 추가해도 되는 기능이니, 나는 실전이었으면 일정 맞추는 개발자가 된거라는 자기위안을 했다. ㅋㅋㅋㅋ 지금 생각하니까 좀 뻔뻔하다.

그래도 이런 마음가짐 덕분에 시험이 끝나고 나서 가족, 연인과 기쁘게 통화하며 소식을 전할 수 있었다.

결과

1차 발표날에도 약속된 시간에서 한참 지난 뒤에 메일이 왔다.

최종 발표 메일은 무려 3시간이나 지나서 도착했다.

어렴풋이 문제가 어려웠고, 테스트도 다 맞추지 못한 사람이 많을거라고 예상했다. 그래서 np터진 쓰레기 코드가 아쉽지만 결국 우테코에는 붙지 않을까 했다. 그러나 3시간 동안 도착하지 않는 메일에 마음졸이면서 혹시나 내가 테스트를 다 통과하고도 탈락하는걸까? 내 코드가 그렇게 별로였나? 하는 생각을 했다.

뭐라도 하지 않으면 이 시간이 느리게 흘러갈 것 같아서 게임을 하다가 메일이 도착했다. 6시였다.

결과는 진짜... 붙었다.

합격 발표를 받자마자 산학협력 인턴은 포기했다. 고민할 것도 없었다.

최종발표 결과를 보며, 부끄럽지만 친한 동생이 최근 나에게 해준 말이 맴돌았다. 언니를 보면 준비된 사람에게 기회가 온다는걸 실감해.

누군가 나를 좋게 봐준 만큼 더 멋진 모습으로 응하고 싶다.

기대에 보답하고 싶다.

profile
겉촉속촉

0개의 댓글