어느덧 벌써 우아한테크코스 2주차가 지나갔습니다!! 시간이 너무 빠른 것 같네요..ㅜㅜ 이제는 어느정도 우테코 흐름에 적응한 것 같기도 하고...
이번주에는 다음과 같은 주제들에 대해서 학습하였습니다.
자바 문법 및 개념 이해
Git 특강
자동차 경주 게임 피드백
이 3가지 주제 중에서 Git과 자동차 경주 게임 피드백에 대해서 새롭게 알게 된 내용 혹은 잘 알지 못하고 있던 내용에 대해서 간략히 정리해보겠습니다.
(자바 문법 및 개념 이해
는 생략)
Git에 대해서 학습하였다. 크루들의 질문 중에서 가장 많은 표를 받은 'upstream, origin', 'add, commit, push' 를 중심으로 강의가 진행되었다.
우리가 주로 push할 때 많이 사용하는 upstream
혹은 origin
은 무슨 의미일까?
우선 이 두 용어는 원격 저장소(remote repository)에 붙는 이름이라고 생각하면 쉽다. 단어의 의미를 살펴보자.
upstream 은 '상류' 라는 의미를 가지는 영단어이고, origin 은 '원천' 이라는 의미를 가지는 단어이다. 즉, 나의 local 저장소(내 PC) 가 강의 하류라고 생각하면 원격 저장소(remote repository) 즉 우리가 주로 Github를 통해서 보는 레포지토리는 upstream 혹은 origin이 되는 것이다.
그렇다면 미션을 진행하는 것처럼 fork를 하는 경우에는 어떨까?? 결국 원본 저장소(woowacourse의 레포지토리) 그리고 fork한 레포지토리 둘 다 나의 local 저장소에서는 동일한 원격(remote) 저장소이다. 여기서 이름은 원본 저장소에 대해서는 upstream으로 그리고 fork한 레포지토리에 대해서는 origin(원천, 해당 저장소로 부터 clone하므로)으로 붙일 수 있다.
추가적으로 해당 강의를 들으며 git push -u origin main
과 같은 명령어를 접하게 되었는데, 본인의 경우 보통 git push origin main
과 같이 사용하였다. (생각해보면 -u 옵션을 붙여준 경우가 없었던 것 같다.) 그래서 이에 대해서 간략히 정리해보려고 한다.
-u
옵션은 --set-upstream
의 약자라고 이해할 수 있다. 이는 그 의미에서도 알 수 있다 시피 upstream으로 세팅을 하는 것으로 나의 로컬PC와 상류에 해당하는 origin의 관계를 설정해주기 위해서 해당 옵션을 추가해주는 것이라고 이해하면 되겠다. 이는 최초 push시에만 붙여 설정해주면 된다. (관련 내용을 찾지 못했지만..우리가 -u 옵션을 해주지 않아도 최초 push시에 git에서 알아서 설정을 해주는 것이 아닐까하는 생각이다..)
우리가 git init(초기화 뿐만 아니라 재초기화 수행하는 명령어)을 수행하면 해당 디렉토리가 로컬 레포지토리로 설정되면서 .git
이라는 숨김 폴더가 생성되는데, 그 내부를 살펴보면 여러 Git의 객체가 함께 생성되게 된다.
이 중에서도 특히 commit(tree 객체명, 부모 commit 객체명 등을 기록) 객체가 중요하다고 볼 수 있다. 이는 작업 디렉토리에 대한 스냅샷을 저장하는 객체로 스테이지의 내용으로 tree 객체(타입과 객체명, 파일명이 기록)를 생성한다.
강의만 들어서는 해당 내용들에 대한 이해가 많이 부족하다고 생각된다..향후에 다시 한 번 들여다볼 필요가 있다고 생각된다...ㅠㅠ
upstream, origin, remote의 관계를 익히기 위해서, 또 conflict 해결 및 리뷰 달기 등의 활동을 위해서 간단한 Git 미션을 진행해보았다.
해당 미션을 진행하고나서 이해한 내용 그리고 conflict가 났던 상황과 이를 해결한 방법은 아래와 같다.
자동차 경주 게임 미션을 진행하며 지키면 좋을..전체 피드백 내용에 대해서 정리해보려고 한다. 본인이 이미 잘 지키고 있거나 스스로 잘 알고 있다 생각되는 내용은 제외하고, 알고 있지만 잘 지키지 못하는 내용 혹은 처음 알게 된 내용을 위주로 정리하였다.
상수는 보통 static final
와 같은 키워드를 함께 사용한다.
왜 우리는 상수에 대해서 static과 final 선언을 해주는 것일까?
우선 static을 선언을 하면 인스턴스 변수와 달리 각각의 인스턴스와는 관련없이 어떠한 인스턴스에도 속하지 않는 상태로 메모리 공간에 단 하나만 존재하게 된다. 그리고 생성 시점에서도 차이가 있는데 인스턴스 생성 시점이 아닌 클래스 로딩 시점에 메모리에 적재되므로 static 메소드, 인스턴스 메소드 모두에서 해당 상수를 사용할 수 있게 된다.
다음으로 final 선언은 값을 단 한 번만 할당할 수 있으면 할당 된 값은 이후 변경이 불가능해진다. 즉 이는 변수가 아닌 상수라는 의미에도 적합해지는 선언이다.
이러한 이유로 상수에는 static final
선언이 적절하다.
변수 이름에 예를 들어 carList
와 같은 이름을 사용한다면 이것이 나중에 배열(Array)로 바뀔 때 혹은 Set으로 바뀔 때 자료형에 따라 변수명도 바뀌어야 하므로 좋지 않은 네이밍이다.
자동차 경주 게임 미션을 진행하면서 개인적으로 피드백 받은 내용 중에 하나이다. 값이 변하지 않을 것으로 생각되는 곳에는 final 선언을 해주어 향후에 해당 값을 프로그램 내에서 사용하게 될 때 개발자는 그 값이 변하지 않았을 것을 보장받으며 보다 편한 마음으로 개발에 임할 수 있게 된다.
객체가 어떠한 상태 값과 함께 Getter 혹은 Setter만을 가지는 경우 이는 객체라고 하기 어렵다.
public class Car {
private String name;
private int position = 1;
public Car(String name) {
this.name = name;
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
public String getName() {
return name;
}
}
객체라면 어떠한 책임(역할)을 부여받아야 마땅하다.
public class Car {
private static final int FORWARD_NUM = 4;
private int position;
...
public void move() {
if (getRandomNo() >= 4) {
this.position++;
}
}
public int getRandomNo() {
Random random = new Random();
return random.nextInt(10);
}
}
랜덤 값을 사용하는 위의 move() 메소드는 테스트하기 어렵다.
따라서 우리는 테스트가 가능한 부분과 불가능한 부분을 분리해 낼 수 있다.
(이 때 전략패턴을 사용함으로써 실행 중에 알고리즘을 선택하게도 할 수 있다.)
public interface MovingStrategy {
boolean isMovable();
}
...
public void move(MovingStrategy movingStrategy) {
if (movingStrategy.isMovable()) {
position++;
}
}
자동차 경주 게임을 예로 들겠다. 만약 Car에 대한 List를 인스턴스 변수로서 가지고 있다면 해당 데이터를 통해서 승자
를 유도해낼 수 있으므로 List와 List winnerName 을 가지고 있기 보다는 List 만을 가지고 해당 데이터로부터 승자를 유도해내는 것이 바람직하다.
2주차를 지내면서 느낀 점은 우테코 일정 이외의 추가적으로 주도적인 학습이 이루어지지 않고 있다는 것이었습니다...스스로 반성을 많이 하게 되네요..
다음 주 부터는 각 주제별로 조금 더 디테일하게 정리할 수 있는 저로서 성장하고 싶고, 각 주제별로 스스로 더 깊이 있는 공부를 해보아야 겠다는 생각입니다! (특히 stream에 대해서 공부해볼 필요성을 느꼈다!!)
추가적으로 스터디를 통해서 레벨1 필독서도 읽어야 겠다는 다짐을 하였습니다!!