컬쥐네 다락방

우아한 테크코스 4기 프리코스 후기 본문

공부방/IT

우아한 테크코스 4기 프리코스 후기

코딩하는 갱얼쥐 2021. 12. 14. 21:09

우아한 테크코스 프리코스

정말 감사하게도 우아한 테크코스 4기 프리코스에 합격해 3주간 우테코의 프로세스를 체험해보는 기회를 얻었다. 의욕 넘치게 과제를 만들고 이 과정에서 서치를 통해 많은 것을 배웠는데 이 과정에서 느낀 점을 기록하고 계속 돌아보기 위해 후기를 작성해본다. 

 

사실 프리코스에 관해 이전 기수들이 진행한 과제가 어떤 기능을 구현하는 것인지 살펴봤었는데, 1주일이라는 시간동안 만들기에 정말 널널하겠다 라는 생각을 했었다. 만약 과거의 나에게 조언할 수 있다면 건방떨지 말고 자바의 정석이나 한 페이지 더 읽으라고 말해주고 싶다... 😨 

1주차 숫자 야구 게임

내가 작성한 코드 : https://github.com/39world/java-baseball-precourse/tree/sanggu

 

1주차 목표는 다음과 같이 작동하는 숫자 야구 게임을 구현하는 과제였다.

숫자를 입력해주세요 : 123
1볼 1스트라이크
숫자를 입력해주세요 : 145
1볼 
숫자를 입력해주세요 : 671
2볼 
숫자를 입력해주세요 : 216
1스트라이크 
숫자를 입력해주세요 : 713
3스트라이크 
3개의 숫자를 모두 맞히셨습니다! 게임 종료
게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.
1
숫자를 입력해주세요 : 123
1볼
…

그리고 과제를 진행하면서 지켜야 하는 프로그래밍 요구사항은 다음과 같았다.

  • 자바 코드 컨벤션을 지키면서 프로그래밍한다.
  • Indent(인덴트, 들여쓰기) depth를 3이 넘지 않도록 구현한다. (2까지만 허용)
  • 3항 연산자를 쓰지 않는다.
  • 함수(또는 메소드)가 한 가지 일만 하도록 최대한 작게 만들어라.
  • Random 값 추출과 사용자 입력 값은 제공된 패키지의 API를 사용한다.
  • Git의 커밋 단위는 기능 목록 단위이며, AngularJS 커밋 컨벤션을 참고한다.

기능 구현 자체는 어렵지 않았지만, 1주차 코스를 하면서 느낀건 난 지금까지 기능 구현에만 초점을 맞췄지 그 코드의 품질과 자바의 객체 지향적 설계는 하나도 지키지 않았다는 점을 알았다.

이전까지 나는 평소에 머리에 떠오르는 순서대로 마구마구 코드를 입력했고 (이 과정도 사실 반복되는 작업들을 하나로 묶지 않고 하드 코딩의 연속이었다.) 대충 많이 했다 싶을 때 한꺼번에 커밋을 했었다. 그러다보니 커밋 컨벤션도 엉망이었고, 커밋을 봤을 때 내가 뭘 만들었는지, 이 전과 무엇이 달라졌는지 한 눈에 찾아보기도 힘든 코드들 뿐이었다. 

그렇기에 간단한 기능 구현이었지만 그 과정에서 코드 한 줄을 작성할 때에도 이게 맞는 걸까 고민하게 됐고 시간이 많이 필요했던 것 같다.

 

1주차 과제를 통해 구현을 시작하기 전에 내가 목표로 하는 기능들을 나눠서 작성하는 것, 그리고 이를 하나 하나 해결하며 기능 단위로 커밋을 남기는 것 그리고 그 과정에서 커밋 컨벤션을 지켜 누구나 쉽게 알아볼 수 있도록 하는 것 등을 배웠다. 또 평소에 Git Desktop만 사용했었는데, test Repo를 하나 생성해서 Git 명령어로 브랜치를 파고 커밋하는 것들을 추가로 연습할 수 있었다.

 

1주차 과제를 끝내고 다른 분들의 코드를 구경했는데 정말 대단한 사람들이 많았었다. 항상 하드 코딩하던 나에게 람다와 스트림을 이용해 만든 간단 명료한 코드들은 참 멋지게 보였고 이를 추후에 조금이라도 적용해보고자 노력했다.

 

1주차 과제에 대한 피드백도 보내주셨는데, 기억에 남았던 내용들은 '반복하지 마라. 중복은 소프트웨어에서 모든 악의 근원이다...' 그리고 '매직 넘버를 사용하지 마라', '구현 순서도 코딩 컨벤션이다' 등이 있었다.

항상 하드 코딩하던 나에게 한 번더 반성하게 만드는 구절이기도 했고, 항상 숫자로 써놓던 코드를 static final을 이용한 상수로 만들어서 어느 누가 내 코드를 보더라도 목적을 이해하도록 노력해야겠다 생각했다.

2주차 자동차 경주 게임

내가 작성한 코드 : https://github.com/39world/java-racingcar-precourse/tree/sanggu

 

2주차 목표는 다음과 같이 작동하는 자동차 경주 게임을 구현하는 것이었다.

경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)
pobi,woni,jun
시도할 회수는 몇회인가요?
5

실행 결과
pobi : -
woni : 
jun : -

pobi : --
woni : -
jun : --

'
'
'

pobi : -----
woni : ----
jun : -----

최종 우승자 : pobi, jun

2주차에 추가된 프로그래밍 요구사항은 다음과 같다.

  • 함수(또는 메소드)의 길이가 15라인을 넘어가지 않도록 한다.
  • else 예약어를 쓰지 않는다.

그리고 추가적인 기능 요구사항으로 에러가 발생했을 때 Exception을 발생시키는 것에서 끝나는게 아니라 에러 메시지를 출력하고 그 부분부터 재입력받도록 만드는 것!

이를 해결하기 위해 throw new를 통해 Exception을 발생시키고 이를 try, catch를 사용해서 잡아내 에러 메시지를 출력하고 다시 기능을 수행하도록 유도했다. 

 

기능 구현자체가 어려웠던 주차는 아니었지만, 과제가 올라온 당일날부터 시작된 사람들의 Pull Request를 보면서 자신의 코드에 자신감 넘치는 모습들이 정말 부러웠다. 실제로 코드들도 깔끔했고 내가 적용하지 못한 MVC 패턴들도 적용한 모습이 멋있었다.

나는 2주차까지는 Domain으로만 이뤄진 코드를 작성했었는데, 몇몇 사람들은 Controller로 요구사항을 주고 받고 메시지를 출력하거나 입력받는 기능들을 inputView나 ouputView로 나눠서 작성해놓은걸 발견했다. 여기서 또 나는 메시지를 출력하고 입력받는 과정을 또 반복하고 있었구나 생각했다. 물론 과제의 목표 사항에 MVC 패턴 적용이라는 목표는 없었기에 괜히 적용하다 내 코드가 꼬일까봐 걱정돼 적용하진 않았지만 사람들의 코드를 구경하며 정말 많이 배웠다.

 

2주차 피드백에서 가장 인상깊었던 점은 '객체에 메시지를 보내라' 였다. 프리코스 이전까지는 코딩하면서 getter와 setter를 정말 많이 사용했고, 값을 비교할 때도 getter를 사용해서 값을 꺼낸 후 비교를 했었는데, 객체에 메시지를 보내서 확인하라는 피드백이었다. 보내주신 예시를 적어보면 다음과 같다.

private boolean isMaxPosition(Car car) {
	return car.getPosition() == maxDistance;
}

내가 구현했던 코드는 다음과 같다.

for (Car car : this.cars) {
	if (car.getPosition() == maxPosition) {
		winners.add(car.getName());
	}
}

나같이 get을 이용해 꺼내온 후 데이터를 비교했던 사람들이 많았던게 분명하다.. getter를 사용하지 말아야하는 큰 이유는 외부에서 바라봤을 때 이 객체가 어떤 데이터들을 가지고 있는지 숨기면서 원하는 결과 값을 얻을 수 있어야 하기 때문이라고 공부했다. 이를 개선하면 if 문의 조건이 예시로 보여주신 것 처럼 boolean 값을 전달받아 진행하도록 고칠 수 있고, 또 Name을 꺼내와서 등록하는게 아니라 하나의 메소드로 구현해놓고 Car 객체를 넣어주면 될 것 같다고 생각했다.

 

3주차 자판기

대망의 마지막 3주차 과제! 자판기 구현이었다.

내가 작성한 코드 : https://github.com/39world/java-vendingmachine-precourse/tree/sanggu  

 

3주차 목표는 다음과 같이 작동하는 자판기 구현이 목표였다.

자판기가 보유하고 있는 금액을 입력해 주세요.
450

자판기가 보유한 동전
500원 - 0개
100원 - 4개
50원 - 1개
10원 - 0개

상품명과 가격, 수량을 입력해 주세요.
[콜라,1500,20];[사이다,1000,10]

투입 금액을 입력해 주세요.
3000

투입 금액: 3000원
구매할 상품명을 입력해 주세요.
콜라

투입 금액: 1500원
구매할 상품명을 입력해 주세요.
사이다

투입 금액: 500원
잔돈
100원 - 4개
50원 - 1개

3주차에서 추가적인 제한 사항은 없었지만 프로그래밍 요구사항으로 주어진 Coin 클래스를 활용하라는 점이 있었다.

Enum 클래스로 만들어진 Coin은 동전의 가격에 따라 만들어진 클래스로 보였다. 평소에 Enum을 상태나 사용자 역할같이 정해진 값을 저장하는 용도로만 사용해봤었는데 Enum을 활용해서 코드를 만들라는 요구사항을 보고 사실 조금 막막했다. 그래도 여기서 멈출 수 없지! 

 

3주차에서는 나도 앞에서 다른 참가자들이 쓰던 stream이나 람다를 적용해봤는데 이 Coin 클래스가 시작이었다.

public static final List<Integer> LIST_OF_MONEY = Arrays.stream(values())
		.map(coin -> coin.amount)
		.collect(Collectors.toList());

앞서 포스팅에서 작성한 Randoms 클래스를 보면 알겠지만 3주차에서 랜덤 값을 추출할 때 사용하는 pickNumberInList는 List<Integer>을 입력받아 리스트에서 랜덤으로 값을 뽑아주는 함수였다.

금액을 입력받고 그 금액만큼 동전을 랜덤으로 만들기위해 동전의 금액으로 이루어진 List가 필요했다. 이를 해결하기 위해서 stream을 이용해 해당 클래스의 value들을 가지고오고 이 값들을 등록된 int 값인 amount로 변경해 List로 만들어줬다. 이걸 처음에 하나 하나 코드를 입력하니까 정말 길고 이해하기 힘든 코드가 만들어졌었다.

 

Coin 클래스를 사용하는 방법에 대해 구상이 끝나고부터는 속도가 붙었던 것 같다. 나는 단순히 고객, 코인, 자판기, 자판기 컨트롤러, 상품, 유효성 검증 이렇게 클래스를 나눠서 구현했는데, 끝나고 구경해보니 다른 참가자들의 코드는 문자열 파싱을 위해 각 클래스마다 파싱 담당 클래스를 만든다던지 각 클래스마다 컨트롤러를 만드는 등 정말 다양한 코드를 볼 수 있었다. 대단해...

 

3주차 과제를 하면서 느낀 점은 내가 1주차때 느꼈던 것처럼 난 정말 객체 지향적 설계가 서툴다는 점이었다. 2주차 까지는 사실 클래스간의 정보를 주고받을 필요가 있는 기능들이 별로 없어서 메소드를 짧게 나누는 것에 집중을 했었는데 자판기에서는 상품, 고객, 자판기가 서로의 정보를 주고받으며 기능을 수행해야 했기에 한 메소드가 복잡해지고 구현이 힘들었던 것 같다.

 

3주차를 마치며 가장 아쉬웠던 점은 MVC 패턴을 이용한 설계가 너무 미숙하다는 점. 비즈니스 로직과 UI 로직을 나누는게 아직도 너무 어렵다. 그러다보니 코드 자체도 흉내만 낸 MVC 패턴의 코드가 된 것 같다.

다음 시험까지 이제 3일정도 남았는데, MVC 패턴과 정적 변수(Static)을 좀 더 공부해보고 시험에서 제대로 적용할 수 있도록 노력해볼 예정이다. 

 

딱 3주동안 제한된 조건에서 프리코스를 통해 우테코를 체험했을 뿐인데 예전에 내가 짜놓은 코드를 보니까 고칠 부분이 한 두가지가 아니구나 싶을 정도로 정말 많이 성장한 것 같다.

다른 참가자들의 풀리퀘를 보니까 나보다 정말 잘하는 사람들이 많아서 우테코를 최종 합격할 지 모르겠지만 앞으로는 구현보다 구현하는 과정에 더 집중해서 퀄리티 높은 코드를 작성하고 싶다.

'공부방 > IT' 카테고리의 다른 글

[프리코스 1주차] Random 함수에 관한 공부  (0) 2021.11.26
Index와 SQL 기초  (0) 2021.10.25
머신 러닝 기초  (0) 2021.10.18
AL/ 머신러닝 / 딥 러닝 이란?  (0) 2021.10.17
운영 체제 공부 - 작성중  (0) 2021.08.11
Comments