프로그래밍/개발일지

(진짜)우테코5기 사전교육 2주차까지 꾸역꾸역 해본 후기

구소장 2022. 11. 9. 12:46
728x90

다른 글에서 왜 우테코 사전교육 2주차까지 꾸역꾸역 했는지에 대한 후기를 적다가 정작 2주차에 대한 이야기는 하지 못했다. - 이렇게 변명이 많으니 글이 길어지는가보다. 본 내용은 이곳에 이어서 작성해보기로 한다. 

 

세줄정리

1. 자바의 기본적인 기능에 대해 새로 알게 되었고, 미약하게나마 써볼 수 있었다. 

2. 클래스를 생성하고 기능도 쪼개보는 연습을 하였다. 

3. 이번주도 성장했고, 오는 주차에 더 많이 성장하고싶다. 

 

1주차와 마찬가지로 2주차에서도 특정 기능구현을(숫자야구게임) 코드로 작성해보는 과제였다. 지난주와 달랐던 점은 테스트코드 작성, 인덴트 들여쓰기, 3항연산자 쓰지 않기, 함수를 작게 만들기 정도였는데, 이 모든것이 나에게는 아주 큰 챌린지였다. 함수를 분리하는 방법을 알기는 커녕 객체가 이해가 잘 안갔기 때문이다 (아직도 잘 모르겠다..ㅋ). 인덴트 같은 경우도 같은 이유로 아주 큰 챌린지였다. 테스트는 또 뭔가..ㅋ 오히려 3항연산자는 별로 상관 없다고 느꼈는데, 내가 3항 연산자를 잘 쓸줄 모르기 때문이다. - 그럼 난 무얼 할줄 아는가..

 

또 포기해야 할 각인가? 라는 생각이 스쳐지나갔지만 이내 성장에 초점을 맞춰보기로 했다. 그래서 이번 과제에서 나의 개인적인 목표를 세워 보았다. 1. main()에서 게임이 돌아만 가게라도 만들자. 2. 함수를 분리해보자. 

 

사실 게임이 돌아가게만이라도 만드는 건 할 수 있을 것 도 같았다. 컴퓨터가 랜덤숫자를 생성하게 만들고, scanner로 입력값을 만들고, 값을 올바로 입력했는지 체크한 후에, 문제가 없으면 반복함수를 걸어서 두 숫자가 맞을 때 까지 돌리면 되기 때문이다. 이정도는 내가 파이썬에서 배운 지식을 조금만 응용하면 할 수 있겠다는 생각이 들었다. 그런데 코드를 입력하려고 하니 바로 문제가 생겼다. 우테코에서 제공하는 랜덤함수 API를 보니 ArrayList라는 개념이 있는 것이었다. 나이거 처음 보는데... array는 본적있는데 이건 뭐냐. 주어진 API 코드에는 randomNumber 라는 랜덤넘버 3자리 입력값 변수가 있었는데, 나는 처음에 이 값을 출력해보면서, 이걸 어떻게 쪼개야 하나? 하는 생각을 했었다. 이미 작성되서 제공한 코드가 이걸 이미 세팅 해놨고 나는 ArrayList에 해당하는 변수만 가져다 쓰면 되는데, 자꾸 저 세자리 숫자를 어떻게 쪼개야 하는지에 한시간 이상 시간을 썼어야 했다. 나는 그냥 까막눈이었다. 이게 글자라는 것 정도만 아는. 이렇게 학습하면 조금 오래걸리겠다는 생각은 살짝 들었다. 그래도 이게 리스트의 일종이고, 대괄호 쓰고, 자리를 고정하지 않고 입력값에 따라 유동적이어서 메모리 관리에 도움이 된다는 것 정도는 알게되었다. 그리고 덕분에 뒤에 나오는 유저 입력값 받기는 상대적으로 덜 고통받으면서 할 수 있게 되었다. 

 

모든 기능에서 이런식이었다. 이해가 안가서 이리저리 고쳐보고, 검색해보고 책찾아보고 강의 찾아보고 등등. 확실히 하다보니까 머릿속에 남는게 많은지는 몰라도 검색스킬과 키워드 찾기는 조금씩 향상된다는 생각이 든다. 하지만 기본적인 문법을 좀 잘 알아야겠다는 생각이 좀많이 든다. (=키워드 니까)

 

예외처리도 했어야 했는데, 처음에는 인덴트 제한이고 뭐고 그냥 기능 구현이 목표였기 때문에 그냥 조건문 걸어서 유저 입력값이 안맞으면 게임을 종료하는 식으로 만들었다. 이미 indent가 3이 되었다. 뭐 기능구현이 목표니까... 조건을 만드는 것도 정말 원시적이었다. 내가 생각한 예외조건은 세자리 숫자,  0사용금지, 중복숫자 사용 금지 정도였는데, 중복숫자같은 경우에는 처음에 이런식으로 했다. 세자리 수를 100으로 나누기, 100으로 나누고 남은 나머지를 10으로 다시 나누기, 그리고 10으로 나눈 나머지. 그렇게 나온 세개의 값을 서로 비교해서 같으면 예외 처리 하는 식으로 했다. 코드가 아주 보기 흉했다. 그래도 뭐 기능구현이 중요한거니까...ㅋㅋ 이런 식이였다. 자릿수 같은 경우는 그냥 100~999사이로 했다가 어차피 0 들어가면 안되고 중복숫자 들어가면 안되니 123부터 987까지로 조건을 걸었었다. 어쨌든 목적지로 가기만 하면 되니까 (대략 비둘기 머리 돌아가는 짤). 결국 중복숫자는 Set 함수를 알게 되어서 활용해봤고, 자릿수는 .size 함수를 쓰니까 해결 됐다. 자연수는 0을 제외하면 되게끔 .contains 을 활용해 보았다. - 이렇게 되니 음수를 입력할수 있겠다고 생각했는데, 이건 적용하지는 못했다. 

 

컴퓨터가 랜덤문제를 만들었고 유저가 세개의 수를 입력하게 했으니 이제 두 수를 비교할 차례다. 자릿수까지 일치하면 슽트라이크, 숫자는 겹치지만 자릿수가 안맞으면 볼, 하나도 안맞으면 낫싱, 세개다 맞추면 3스트라이크로 게임이 끝나는 식이었다. 나 같은 경우에는 컴퓨터의 숫자와 유저의 숫자를 하나씩 뽑아서 각각의 차이를 구하고 0인 경우를 카운트 했다. 총 9번의 연산. 문제는 이게 스트라이크의 갯수가 아닌 볼과 스트라이크의 갯수를 합한 숫자가 된다는 것. 예를 들어 com = [a, b, c], user = [b,c,a] 면 위와 같이 계산 했을 때 a-b, a-c, a-a, b-b, b-c, b-a, c-b, c-c, c-a가 나오기 때문에 0이 세개가 된다. 근데 이게 볼 or 스트라이크의 개념이기 때문에 스트라이크 값을 찾아서 위 값에서 빼주면 볼 값이 나오는 걸 알 수 있었다. 같은 예에서 같은 위치의 수 끼리만 연산을 하면 각각 a-b, b-c, c-a가 되기 때문에 0값은 없어서 위의 예시에서 결과는 3볼이 되는 것. 아마 훨씬 단순하고 간단한 코드가 있겠지만, 나는 이렇게 해결책을 생각해낸 것 만으로도 굉장히 뿌듯했다. 이게 다 구구단 실습을 해본 덕분에 이중 반복에 대해 알고 있었기 때문에 생각해낼 수 있었던 것 같다. 그래서 많이 알수록 좋은 것 같다. 더 좋은 방법도 많이 있겠지만. 문제는 이게 이중반복 + 조건문을 써야 했기 때문에 이것 만으로 indent가 3이 되었다. (제한은 2..) 이것도 클래스를 나눌 수 있는지 잘 모르겠는데, 시간이 없어서 시도도 해보지 못했다. 이 매칭 파트가 나는 제일 재밌었다. 역시 유능감을 느낄 수 있어야 돼ㅋㅋ

 

여기까지 기본 기능을 넣고 do while 반복문을 써서 입력값 틀렸을 경우 돌아가기, 게임 종료 후 새 게임을 하고 싶을 때 한번 돌아가기 기능을 만들었다. 새게임 반복문 정도는 class를 나눌 수 있었을 것 같은데, 이것도 시간이 부족해서 하지 못했다. 이렇게 기능에 초점을 맞춘 엉망진창 코드를 만들고 나니 인덴트 5의 어마무시하게 지저분한 코드가 완성되었다. (근데 생각해보니까 네이버 웹사이트같은데 인덴트가 몇십개는 넘어보이던데......ㅋ)

 

사실 이때부터가 고난이었는데 나름 클래스에 대해 공부해보고 함수를 분리해보는게 목표였기 때문에 도전을 해 보았다. 클래스를 만들자니 두가지가 특히 고민이었는데 하나는 A클래스의 함수를 B로 받아오는 방법. 다른 하나는 A클래스의 변수를 어떻게 B로 가져오고 어떻게 적절한 타이밍에 초기화를 시키는지에 대한 궁금증이었다. - 지금 생각해보면 정말 어이없지만 그렇게 어려운 문제가 아니었고, 첫번째 문제를 해결하다보니 두번째 문제도 자연스럽게 해결이 되었다. 간략하게 얘기하자면 나는 뭔가 상속 기능을 써야 할 것 만 같다는 생각을 하고 계속 이를 시도하였다. 상속과 관련된 개념을 찾아보고 코드를 보면서 내 상황에서 어떻게 적용시킬 수 있을지에 대해 고민해보았다. 나중에 안 사실이지만 상속 기능을 쓸 필요가 없었고, 아니 쓸 상황이 아니었다. 상하관계가 아니라 그냥 내용만 받아오면 되기 때문이었다. 아무튼 (쓸데없는 것만) 계속 공부하고, 또 고민했다. 코드 한줄 적지 않고. 근데 이게 문제였다. 그냥 머릿속으로 상황을 그리고 해결하고자 하다보니 실체가 보이지 않았고 그래서 내가 잘못된 접근을 하고 있다는 것을 알게 되었다. 코드를 작성하다보니 뭔가 계속 이상해서 다른 방법을 찾아보게 됐고 그러다 보니 훨씬 간단한 해결책을 찾은 것이었다. 방법은 그냥 메소드 호출을 하면 되는 것이었다. 아직 입력과 리턴, 참조변수선언 등을 정확하게 이해하지는 못하지만 뭔가, 사용설명서를 보고 간신히 조립이라도 해 볼 수 있게 되었달까? 나름 하나의 성장이었다. 이틀동안 고민하고 공부했는데 해결 하지 못하고, 결국 몇시간 코드를 깔짝거리다 보니 얻은 수확이었다. 

 

자바를 설치하고 idk를 설치하고 System.out.println("Hello World"); 를 써본게 한걸음 앞으로 나간것 처럼 이번에는 java파일 하나 더 만들고 그곳에 class하나 만들어서 기존에 작성했던 코드를 복붙해서 고민한 것이 "class"의 차원에서 또다른 진일보였다는 생각이 든다. 해보면서 는다는 말이 이제야 좀 실감이 간다. 아무튼 이렇게 메서드를 분리해본 덕분에 인덴트를 3개까지 줄여볼 수 있었다. 새게임 반복문을 함수분리하고, 숫자비교에서 이중반복+조건문을 다른 방식으로 정리했다면 인덴트를 더 줄여볼 수 있었을 텐데 하는 아쉬움은 남지만, 나름 목표는 초과달성했다고 생각한다. 

 

마지막 고민거리는 예외처리였는데, 이건 책으로 공부하지는 못했고, 그냥 구글링하면서 주먹구구식으로 공부해서 코드를 꾸겨넣었다. 처음에 조건문으로 해서 처리했다가 과제안내에서 본 Illegal arugementException이라는 키워드를 보고 관련된 내용을 찾아보았다. 찾다보니  try-catch문에 관해 알게 돼서 이부분도 공부해 볼 수 있었다. (근데 과제 하다보니 그냥 throw만 하고 catch는 안썼어도 되는 것 같은데, 아직 잘 모르겠다. 그리고 나는 자체적으로 error를 customize해서 써봤는데 이게 맞는지도 잘 모르겠다. 그래도 아무튼 try-catch문을 써봤다는 것? 이를 위해 클래스를 나누고 함수도 쪼개보면서 여러 시도를 해볼 수 있었다는게 의미있었다고 할 수 있겠다. 

 

사실 이번 과제를 통해서 우테코측에서 의도했던 건 코드컨벤션, 인덴트 줄이기, 클래스 세분화하기 (이게 바로 객체지향의 꽃?!!), 그리고 테스트 코드 적용하기 정도였던 것 같은데, 거기에는 근처도 못가봤다. 아마 내가 2주차에 했던 수준이 1주차 어딘가의 수준이 아니었나 싶다. 그부분은 아쉽지만, 어차피 성장에 포커스를 맞추기로 했으니 나쁘지 않다. 한가지 아쉬웠던 것은 깃 커밋을 잘 활용하지 못했다는 것이다. 처음에는 나름 기능단위로 쪼개서 커밋하기 위해 노력했다. 그런데, 클래스를 쪼개면서부터 작업을 왔다갔다 하면서 하게 되었던것 같다. 눈에 보이는 문제들을 고치려다 보니 일관성있는 작업을 하지 못한 것 같다. 이건 어떻게 해결하는지 궁금하다. 오는 주에는 깃도 좀 더 잘 활용해봐야겠다. 아마 3주차에는 더 높은 수준을 요구하겠지만 이번주와 마찬가지로 내 페이스대로 한번 달려가봐야겠다. 

 

내가 구글링했던 키워드들

- Scanner : 입력하기

- 배열(Array)과 리스트(List)

- ArrayList 사용법

 

- boolean

- contains (문자열 포함여부 확인)

- String를 int로 바꿔주기 & 그 반대 (형변환)

- ArrayList를 통해 중복값 찾기

- Array 값 가져오기

- int 수의 자릿수 구하기: 나누기, 문자열 변환

- stream: int 를 자릿수별 int 배열로 분할하기 ㅁ

- Array 배열 활용하기 (for, Scanner 

- contains

- Generics

- Set: 중복 허용하지 않는 자료구조

- length (배열 전체크기) 와 size (리스트에 들어있는 원소 수)의 차이

- exception 예외 만들기

- try catch finally

- ArrayList 배열에 객체 class 지정, 데이터 삽입, 

- Exception is never thrown in body of corresponding tr statement

- 다른 클래스의 메소드 호출하기

- An illegal reflective access operation has occured

- java printf & Syntax

- git push

- 상속, 

- 예외처리,