상권's

TIL 49 (git branch, 개인프로젝트2) (2021.11.30) 본문

~2022 작성 글/TIL

TIL 49 (git branch, 개인프로젝트2) (2021.11.30)

라마치 2021. 11. 30. 14:35
-오늘의 토이 2021.11.30-
coinChange
문제
다양한 동전들을 가지고 특정 금액을 만들 수 있는 모든 경우의 수를 리턴해야 합니다.
예를 들어, 100원, 500원짜리 동전을 가지고 1,000원을 만들 수 있는 방법은 총 3가지 입니다.100원 10개, 100원 5개 + 500원 1개, 500원 2개
    // 앞 서 배웠던 dp를 이용해 본다 
    // 먼저 total 금액까지 갈 수 있는 배열을 하나 만들어준다. target = []
    // 그리고 이 배열의 인덱스가 각 동전보다 클 경우에,
    // 각 동전으로 해당 target 을 만들 수 있는 방법은
    // total - 동전 = 금액 => 이 금액을 만드는 총 경우의 수와 동일하다.
const coinChange = function (total, coins) {
    let target = [1]
    // target 의 0번째 인덱스에 1을 넣어줌으로써
    // coins[x]과 target[x]의 값이 같을 경우에,
    // target[x] = target[x] + tartget[x - conins[x]]
    // 이 공식을 통해서 target의 0번째 인덱스 1을 불러와
    // 경우의 수가 1이 될 수 있다.
    
    for ( let n = 1; n <= total; n++ ) {
      target[n] = 0
    }
    for ( let j = 0; j < coins.length; j++ ) {
      for ( let n = 1; n <= total; n++ ) {
        if( coins[j] <= n ) {
          target[n] += target[n - coins[j]]
        }
      }
    }
    return target[total]
  };

요즘 토이는 토이대로 난이도가 너무 올라가서 지치고, 개인프로젝트 때문에도 지치고 있는 상황에서 간만에 아는! 그리고 열심히 공부했던! DP가 나와서 기분 좋게 아침을 시작했습니다. 수도코드는 바로 나왔지만, 코드는 몇 번의 수정을 거쳐서 테스트를 통과할 수 있었습니다. 학습을 활용했다는 즐거움에 그치는 것이 아니라 몇 번이고 더 연습해서 코드를 빠르고 정확하게 구현할 수 있도록 노력해야겠습니다.

<--- Last few GCs --->

[7985:0x4d1dbc0]      734 ms: Scavenge 1136.0 (1169.7) -> 1136.0 (1169.7) MB, 0.2 / 0.0 ms  (average mu = 1.000, current mu = 1.000) allocation failure 
[7985:0x4d1dbc0]     1090 ms: Mark-sweep 1709.9 (1743.5) -> 1383.1 (1415.9) MB, 9.6 / 0.0 ms  (+ 0.4 ms in 3 steps since start of marking, biggest step 0.4 ms, walltime since start of marking 729 ms) (average mu = 0.990, current mu = 0.990) allocation fai

<--- JS stacktrace --->

FATAL ERROR: invalid array length Allocation failed - JavaScript heap out of memory
 1: 0xa25510 node::Abort() [node]
 2: 0x9664d3 node::FatalError(char const*, char const*) [node]
 3: 0xb9a8be v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
 4: 0xb9ac37 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
 5: 0xd56ca5  [node]
 6: 0xd29c73  [node]
 7: 0xe9d320  [node]
 8: 0xea692d  [node]
 9: 0x1057553 v8::internal::Runtime_GrowArrayElements(int, unsigned long*, v8::internal::Isolate*) [node]
10: 0x1426919  [node]
Aborted (core dumped)

[Done] exited with code=134 in 1.804 seconds

[Running] node "/home/sangkwon/Study_Algorithm/Toy Problem/37_coinChange/sangkwon.js"

<--- Last few GCs --->

[8480:0x5396bc0]      744 ms: Scavenge 1136.0 (1169.4) -> 1136.0 (1169.4) MB, 0.3 / 0.0 ms  (average mu = 1.000, current mu = 1.000) allocation failure 
[8480:0x5396bc0]      955 ms: Mark-sweep 1709.9 (1743.2) -> 1496.4 (1529.3) MB, 8.0 / 0.0 ms  (+ 0.5 ms in 4 steps since start of marking, biggest step 0.4 ms, walltime since start of marking 701 ms) (average mu = 0.990, current mu = 0.990) finalize incre

<--- JS stacktrace --->

FATAL ERROR: invalid array length Allocation failed - JavaScript heap out of memory
 1: 0xa25510 node::Abort() [node]
 2: 0x9664d3 node::FatalError(char const*, char const*) [node]
 3: 0xb9a8be v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
 4: 0xb9ac37 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
 5: 0xd56ca5  [node]
 6: 0xd29c73  [node]
 7: 0xe9d320  [node]
 8: 0xea692d  [node]
 9: 0x1057553 v8::internal::Runtime_GrowArrayElements(int, unsigned long*, v8::internal::Isolate*) [node]
10: 0x1426919  [node]
Aborted (core dumped)

오늘 토이 문제를 vscode에서 돌리는 데 이런 에러가 발생했었습니다. for 문에서 n의 범위 값을 잘 못 넣어서 발생했던 문젠데, 스택오버플로우에서는 v8의 메모리 관련된 문제라는 답변이 있었습니다. n의 범위를 제대로 설정해주니 이 에러는 바로 사라졌었는데, 오늘은 눈에만 익히고 다음에 관련된 문제가 발생할 경우 조금 더 자세하게 블로깅해보겠습니다.

 


Git branch

 

브랜치란?

브랜치란 독립적으로 어떤 작업을 진행하기 위한 개념

 - 각각의 브랜치는 다른 브랜치의 영향을 받지 않기 때문에, 여러 작업을 동시에 진행할 수 있다.

 

브랜치 기능의 장점

  • 한 소스코드에서 동시에 다양한 작업을 할 수 있게 해준다.
  • 소스코드의 한 시점과 동일한 상태를 만들고, 브랜치를 넘나들며 작업을 수행할 수 있다.
  • 각각의 브랜치에서 생긴 변화가 다른 브랜치에 영향을 주지 않고 독립적으로 코딩을 진행할 수 있다.

브랜치 종류

 

통합 브랜치 (Integration Branch)

배포될 소스 코드가 기록되는 브랜치. Github Repository를 생성하게 되면 기본적으로 main 브랜치가 생깁니다. (기존 Repository의 경우 master로 되어 있는 곳도 많습니다.) 해당 프로젝트의 모든 기능이 정상적으로 작동하는 상태의 소스코드가 담겨 있습니다.

 

피처 브랜치 (Feature Branch)

기능 추가, 버그 수정과 같이 단위 작업을 위한 브랜치. 통합 브랜치로부터 만들어내며, 피처 브랜치에서 하나의 작업이 완료가 되면 다시 통합 브랜치에 병합하는 방식으로 진행됩니다. 토픽 브랜치라고도 합니다.

 

브랜치 명령어

새로운 브랜치 생성

  • $ git branch 새로운 브랜치 이름

새로운 브랜치 생성 후 해당 브랜치로 전환

  • $ git switch -c 새로운 브랜치 이름
  • $ git checkout -b 새로운 브랜치 이름

브랜치 목록 확인

  • $ git branch

브랜치 목록과 각 브랜치의 최근 커밋 확인

  • $ git branch -v

브랜치 삭제

  • $ git branch -d 삭제할 브랜치 이름
  • $ git branch -D 해당 명령어는 병합하지 않은 브랜치를 강제 삭제하는 방법입니다.

브랜치 전환

  • $ git switch 브랜치 이름
  • $ git checkout 브랜치 이름

브랜치 병합

  • master 브랜치로 dev 브랜치를 병합할 때 (master ← dev)
  1. $ git checkout master
  2. $ git merge dev
  • master 브랜치로 dev 브랜치를 병합할 때 (master ← dev)
  1. $ git checkout dev
  2. $ git rebase master 

로그에 모든 브랜치를 그래프로 표현

  • $ git log --branches --graph --decorate

아직 commit 하지 않은 작업을 스택에 임시로 저장

  • $ git stash

스터디원의 레포를 clone해서 remote로 사용을 하면서 어느 정도 잘 사용하고 있다고 생각을 했었는데 브랜치를 학습하니 아직 배울 게 한창 많이 남았다는 생각이 들었습니다. 이후에 사용하면서 발생하는 에러나, 사용방법 등 직접 경험해보고 블로깅하도록 하겠습니다.

 

읽어볼 자료

 

https://git-scm.com/book/ko/v2/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-Rebase-%ED%95%98%EA%B8%B0

 

https://dangitgit.com/ko


개인프로젝트를 진행하면서 sequelize에서 seed를 만들었는데, seed 명령어를 쓰고나면 꼭 오탈자가 확인이 되서 undo를 했습니다. 근데 undo를 한다고해서 auto_increment도 리셋이 될 줄 알았는데 그렇지는 않았습니다. 

ALTER TABLE [TABLE NAME] AUTO_INCREMENT = 1;

이렇게 입력을 하면 auto_increment도 리셋을 할 수 있습니다.


어제, 오늘 sequelize 테이블과 column 설정 관련해서 실수를 너무 많이해서 수정도 하고 삭제도 했었습니다. 그때 up에서 사용했던 메소드들입니다. down에서는 다시 원상복구 시킬 수 있도록 메소드들을 사용했습니다.

이 모듈은 up()과 down() 메소드를 노출하는데 각 각 마이그레이션과 롤백을 담당한다. up() 함수에 새로운 컬럼을 추가하는 코드를 작성하면, down() 함수에는 추가한 컬럼을 삭제하는 코드를 작성하는 식이다. 간단히 User 테이블에 nickname 컬럼을 추가하는 코드를 작성해 보자.

출처 김정환님 블로그 sequelize 마이그레이션 일부
column 삭제하는 방법
queryInterface.removeColumn('테이블명', '삭제할 column명');
예시
await queryInterface.removeColumn(
	'Users',
	'email'
);

column 명 바꾸는 방법
queryInterface.renameColumn("테이블명", "바꿀 대상 column명", "바꿀 column명");
예시
await queryInterface.renameColumn("Users", "firstName", "name");

column 속성 바꾸는 방법
queryInterface.changeColumn('테이블명', 'column명', {변경할 key: 변경할 value})
예시
await queryInterface.changeColumn('spicies', 'value', {
	type: Sequelize.STRING,
    allowNull : false
})

오늘 개인프로젝트 진행 중에 발생했던 에러입니다.

controller에 get 메소드를 정의해줬는데 routes/menu 에서 get 메소드를 적지 않아 발생했던 에러입니다. 

Route.get()에는 콜백 함수가 필요한데 controller에서 객체로 exports하다보니 아래와 같은 에러가 발생한 듯 합니다.

 

다음은 sequelize에서 user table의 column을 수정하려고 작성했던 migration에서 발생한 에러입니다. 삭제하고 새로운 column을 추가해주려고 했는데 에러의 정확한 이유는 아직 확인하지 못했습니다.

아마 처음에는 기존에 있던 id, createdAt, updatedAt을 제외하고 firstName, lastName, email을 다 removeColumn을 해서 위와 같은 에러가 발생을 했는지 모르겠는데, lastName, email은 remove 해주고 firstName은 rename을 해주니 정상적으로 작동했습니다.

module.exports = {
  up: async (queryInterface, Sequelize) => {
    // await queryInterface.removeColumn(
    //   'Users',
    //   'lastName'
    // );
    // await queryInterface.removeColumn(
    //   'Users',
    //   'email'
    // );
    // await queryInterface.removeColumn(
    //   'Users',
    //   'email'
    // );
    await queryInterface.renameColumn("Users", "firstName", "name");
    /**
     * Add altering commands here.
     *
     * Example:
     * await queryInterface.createTable('users', { id: Sequelize.INTEGER });
     */
  },
  down: async (queryInterface, Sequelize) => {
    // await queryInterface.addColumn(
    //   'Users',
    //   'lastName',
    //  Sequelize.STRING
    // );
    // await queryInterface.addColumn(
    //   'Users',
    //   'email',
    //   Sequelize.STRING
    // );
    await queryInterface.renameColumn("Users", "name", "firstName");
    /**
     * Add reverting commands here.
     *
     * Example:
     * await queryInterface.dropTable('users');
     */
  }
};

위와 같은 코드로 첫 migrate를 했는데, email을 removeColumn을 두 번 넣어서 아래와 같은 에러가 발생했습니다. 수정하고 나니 lastName은 존재하지 않아서 drop 할 수 없다는 에러가 또 발생을 했습니다.

그래서 확인을 해보니 에러가 나기전까지는 처리가 되었습니다. 아직까지는 공식문서에서 해당하는 부분을 확인하질 못했지만, 추후에 상기 내용과 관련된 부분을 확인한다면 글을 수정하도록 하겠습니다.

Comments