브랜치 전략(git-flow) 정리

 최근 어플리케이션 개발을 거의 마치고 배포 단계에 들어섰는데, 나중에 버전 관리나 배포 자동화를 위해 Git 의 브랜치부터 체계적으로 잡고 가야한다는 생각이 들었다. 그래서 git-flow 전략을 찾아봤고, 프로젝트에 어떻게 적용할 것인지 흐름을 정리해 보고자 한다. git-flow 의 내용을 설명하기보단 개발 -> 배포까지의 흐름 위주로 정리했다. develop 브랜치 master 브랜치에서 분기되는 브랜치로, 해당 master 브랜치 버전의 기능 개발을 develop 브랜치에서 하게 된다. feature 브랜치 develop 브랜치에서 분기되는 브랜치로, 특정 기능을 개발하기 위한 브랜치이다. feature/{기능} 으로 이름지으며, 기능이 완성되면 develop 브랜치에 병합하고 feature 브랜치는 지운다. release 브랜치 기능 개발이 어느정도 이루어지고, 정식 배포가 얼마 남지 않았을 때, 테스트를 위해 develop에서 분기하는 브랜치이다. - 이번 프로젝트에서 release 브랜치를 테스트 브랜치로 두고, release 브랜치에 코드가 푸시되면 테스트 및 빌드 후 테스트 서버에 자동으로 배포되게끔 적용하려 한다.  정식 배포 기간이 되면 master, develop 두 브랜치에 모두 병합해야 한다. (버전을 태깅해 커밋하면 버전 관리에 용이함) hotfix 브랜치 release 나 master 브랜치에서 빠르게 고쳐져야 할 사항이 생길 경우 만들고, 수정 후 master, release, develop 모두에 병합해야 한다. master 브랜치 정식 출시가 되는 브랜치로, 버전이 업데이트 될 때만 병합되어야 한다. 정식으로 릴리즈된 내용을 기록하고, 버전을 관리하는 브랜치이다. 브랜치를 개발 흐름대로 정리해 보았다. 즉, 1. develop 브랜치에서 feature 브랜치로 기능을 개발하고 2. 기능 개발이 완료되면 release 브랜치로 테스트 3. hotfix 브랜치로 오류 수정 후 4. master 브랜치로 정식...

쉘 스크립트 - 테스트 서버 한번에 배포하기

개발중인 앱의 테스트 서버를 Springboot, EC2로 구축했다. 하지만 매번 테스트 서버를 배포할 때마다 빌드, 배포 코드를 똑같이 쳐주는 게 번거로워 이 작업을 한 번에 해 줄 수 있는 쉘 스크립트를 짜보려고 한다.(쉘 스크립트 연습 겸!) 먼저, 빌드, 배포 순서는 다음과 같다. 1. BackEnd 폴더에서 github 코드를 pull 한다. (1번은 수동으로 진행하기로 했다. 어차피 이후에 github actions와 연동할 계획이므로) 2. gradle로 빌드한다. 3. 미리 실행 중인(실행 중이 아니라면 생략) nohup 프로세스를 종료한다. 4. build/libs 의 .jar 파일을 배포한다. 위 과정을 쉘 스크립트 실행 한 번으로 대체해보자! 쉘 스크립트 파일 생성 vi deploy.sh 스크립트 파일 권한 부여 chmod +x deploy.sh  => 실행 권한 부여 쉘 스크립트 파일의 맨 위에 쉘 스크립트임을 알려주는 코드를 넣어주어야 한다. #!/bin/bash   => 스크립트 상단에 작성 스크립트 파일을 만들었으니, 그 동안 터미널에서 사용한 명령어들을 넣어주자 1. 수작업 2. gradle 빌드 필자의 빌드 커맨드는 다음과 같다. 스크립트에 그대로 추가해 주자. sudo ./gradlew bootjar 3. 실행중인 nohup 프로세스 종료 바로 nohup 명령어를 실행해주면 이전에 실행중인 프로세스와 충돌이 일어나 배포가 진행되지 않는다. 따라서 기존 nohup 프로세스를 종료하는 로직을 추가해주자. sudo kill -9 $(ps -ef | grep {실행중인 파일 명} | awk '{print $2}') - 명령어 정리 kill : 해당 프로세스 id 의 프로세스를 종료한다. ps -ef | grep : ps로 현재 실행중인 프로세스를 검색하는데, grep으로 원하는 문자열이 포함된 프로세스만 검색할 수 있다. awk : 테이블 형태로 된 값들을 조작하는 명령어이다. $1, $2, $3... ...

Git 명령어 정리

이미지
git init 현재 폴더에 git을 등록한다. git clone {PATH} PATH의 깃 원격 저장소에 있는 내용들을 모두 가져온다. git clone은 다음과 같은 명령어들로 원격 저장소의 내용을 가져온다. 1. 저장소 폴더 생성 2. 저장소 폴더 내에서 git init 3. git remote add origin {PATH} 4. git fetch 5. git checkout {최종 커밋} git branch [-l], git branch -v, git branch -r, git branch -a -l 옵션은 생략이 가능하며, 로컬 브랜치들의 목록을 보여준다. -v 옵션은 로컬 브랜치들의 목록을 마지막 커밋 내용과 함께 보여준다. -r 옵션은 원격 브랜치들의 목록을 보여준다. -a 옵션은 원격/로컬 브랜치들의 목록을 모두 보여준다. git branch {이름}, git branch {생성 브랜치} {기준 브랜치} 새로운 브랜치를 생성한다.(단, 생성만 하고 이동은 하지 않는다) branch 명령어의 인자로 이름을 두 개 주면 뒤 브랜치를 기준으로 새로운 브랜치를 생성한다.(마찬가지로 새로운 브랜치로의 이동은 하지 않는다) git branch (-merged | -no-merged) -merged 옵션은 이미 merge 된 브랜치들, -no-merged 옵션은 아직 merge 되지 않은 브랜치들을 보여준다.(*이 붙지 않은 브랜치들은 이미 merge되었기 때문에 삭제가 가능하다) git branch -d (이름) 해당 브랜치를 삭제한다.(*이 붙어 있으면 삭제가 불가능하다) git branch -m (기존 이름 A) (바꿀 이름 B) 브랜치 A를 브랜치 B로 변경한다.(-M 옵션을 사용할 경우 동일한 이름의 브랜치도 덮어 쓴다) git add {파일 이름}, git add . , git add -u, git add -A, git add --all 파일 이름만 적게 되면 해당 파일만 스테이징한다. . 옵션을 주면 변화된 파일, 추가된 파일 을 스테이징한다....

백준 - 영재의 산책(19953번)

  문제 t 가 10억이므로 매 초마다 이동해주면 시간 초과가 날 수 밖에 없다. (v * m) % 10 의 규칙을 활용해야 한다. 여러 수를 대입해 본 결과 v, m 이 어떤 조합이던 간에 결과 값은 4개의 패턴만을 가진다. v = 1, m = 2 일 때 -> 2, 4, 8, 6 v = 123, m = 127 일 때 -> 1, 7, 9, 3 즉, 맨 처음 북쪽으로의 이동을 제외하면 다음 이동부터는 동, 서, 남, 북 네 방향으로의 이동 거리가 일정하다는 뜻이다. 처음 북쪽으로 이동한 뒤 그 지점을 시작점으로 잡고, 동, 서, 남, 북으로 각각 몇 번 갈 수 있는지 구한 뒤 이동 거리만큼 계산해주면 된다.

CS(Computer Science) 정리

 데이터 베이스 트랜잭션(Transaction) 데이터 베이스의 상태를 변화시키는 작업 중 더 이상 쪼개선 안되는 작업들의 모임이다. 즉, 원자성을 보장하는 작업들을 말한다. 트랜잭션이 진행되는 도중에 부분 작업이 실패하면 전체 작업에 영향을 끼치므로 롤백 을 통해 처음으로 되돌려햐 하며 모든 부분 작업이 성공적으로 완료되면 커밋 을 통해 변경 사항을 한꺼번에 데이터베이스에 반영하게 된다. RDBMS - 관계형 데이터베이스 관리 시스템 모든 데이터가 관계로서 표현되는 데이터 베이스 시스템으로, 모든 데이터는 행, 열로 묶인 테이블의 형태로 사용자에게 제공된다. 테이블 형식의 데이터를 관계 연산자를 사용한 쿼리문을 날려 조작하게 된다.(SQL) ex) MySQL, OracleDB, MariaDB ... 특징 데이터의 분류, 정렬, 탐색이 비교적 빠르다. 스키마가 정해져 있어 유연성이 떨어진다. NoSQL - 비관계형 데이터베이스 관리 시스템 RDBMS와는 반대되는 형태의 데이터 베이스 시스템이다. 데이터를 Key-Value 나 Dovument(JSON), Graph 형태로 저장하기 때문에 관계형보다 간단하게 데이터 베이스를 구성할 수 있다. ex) MongDB, Redis, Cassandra ... 특징 관계형 데이터 베이스에 비해 대용량의 데이터를 저장할 수 있다.(분산형 구조) 스키마가 정의되지 않아 변화에 유연하다. B-Tree 데이터베이스나 파일 시스템에서 데이터 인덱싱을 위해 사용되는 트리로, 다음과 같은 특징을 갖는 트리이다. 각 노드들은 M 개의 데이터를 가질 수 있고, 각 데이터 사이마다 양 옆 데이터의 사이에 있는 데이터들을 가진 자식 노드에 대한 링크가 있다. ex) A (B~E를 갖는 자식 노드 링크) F 한 노드가 M개를 넘어가게 되면 그 노드를 반으로 쪼개어 두 노드로 분할한다. 그리고 중간의 데이터를 부모 노드로 넘긴다. 부모 노드도 꽉찬다면 계속 반복한다. B+ Tree 기존의 B 트리는 데이터에 대해 순차적으로 접근하기 힘들다...

스위핑 알고리즘

 스위핑 알고리즘이란? 스위핑(sweeping) : 청소하다, 휩쓸다 스위핑 알고리즘이란 단어의 뜻 그대로 휩쓸고 지나가며 문제를 해결하는 방식으로, 특정 기준에 따라 정렬한 후 순서대로 처리하는 알고리즘이다. 여러 문제를 풀어보았는데 보통 N = 100000 정도가 주어지고, 선분의 겹침 처리 문제가 많이 나오는 것 같고 시간 복잡도는 정렬의 시간복잡도인 NlogN이 대부분이다.(백준 골드 기준) 예제 1번 : 백준 - 공주님의 정원(2457) 문제 링크 간단한 날짜 전처리 + 그리디(정렬 기준 중요) + 스위핑 문제이다. 먼저, 월과 일로 주어지는 시작, 끝 점을 1 ~ 365 사이의 수로 전처리하는 과정이 필요하다. 각 점들을 직선 상의 선분들로 나타낸 뒤 시작점의 오름차순, 끝점의 내림차순으로 정렬해 스위핑한다. end 점 : 현재까지 심은 꽃의 마지막 좌표 maxE 점 : end 점과 새로운 선분을 이을 때 가장 멀리 갈 수 있는 끝점 좌표 maxE 보다 새로운 선분의 시작 점(nowS)이 크다면 선분은 중간에 끊어지게 되므로 카운트 0이 되고 종료한다.(시작점에 대해 정렬되어 있으므로) 아니라면 현재 선분과 새로운 선분을 이을 수 있다. 다음과 같이 진행한다. - end 보다 새로운 선분의 시작 점(nowS)이 크다면 -> 새로운 선분을 이어야 한다.(카운트 1증가) - 새로운 선분의 끝 점(nowE)과 maxE를 비교해 maxE를 계속 갱신한다. - maxE 가 11월 30일을 넘어가게 되면 그 선분과 바로 이으면 되므로 카운트 1을 증가시키고 종료한다. (끝점에 대해 내림차순이므로 다음 선분은 더 짧다) 예제 2번 : 백준 - Lifeguards(Silver)(15589) 문제 링크 여러 선들이 주어지는데, 단 하나의 선만 제거했을 때 선들이 겹치는 길이를 최대화하는 문제이다. 아이디어는 다음과 같다. fixLine = 두 개 이상의 선들이 겹치는 구간으로, 선 하나를 제거해도 여전히 유효하므로 답에 무조건 더해져야 한다. line ...

백준 - 카지노(13252번)

  링크 그리디 + dp 메모이제이션 문제이다. 문제에서 최적의 방법이란 매 라운드마다 다음 라운드로 최대한의 칩을 보내는 것이다. 따라서 현재 남은 칩과, M 에 의해 칩의 배치가 결정된다. 1. 칩 < M  --> 칩을 한 개씩만 놓는 게 최선이다. 2. 칩 % M == 0  --> 칩을 (칩 / M) 개씩 모든 M 자리에 놓는 게 최선이다. 3. 칩 % M != 0  --> 칩을 (칩 / M) 개씩 모든 M 자리에 놓아도 나머지만큼의 칩이 남는다. 남는 칩들은 하나씩 각기 다른 자리에 놓는다. 1 번의 확률은 딜러가 칩을 집을 확률 = 칩의 개수 / M + 칩을 집지 않을 확률 = (M - 칩의 개수) / M 2 번의 확률은 모든 자리의 칩의 개수가 같으므로 1이다. 3 번의 확률은 딜러가 (칩 / M) 개의 칩을 집을 경우 = (M - 나머지) / M + (칩 / M + 1) 개의 칩을 집을 경우 = 나머지 / M 위와 같이 현재 라운드의 칩의 개수에 따라 재귀 함수를 진행하면 된다. 하지만 매 라운드마다 최대 2개의 분기가 일어나므로 2^50 의 시간 초과가 난다. 1, 2, 3 번을 나누는 기준은 (칩 % M) 임을 알 수 있다. 따라서 각 라운드마다 (칩 % M) 인 상태를 메모이제이션 해 주어 시간을 줄일 수 있었다. #include<iostream> #include<memory.h> #include<algorithm> #include<math.h> #include<string> #include<vector> #include<stack> #include<queue> #include<map> #include<set> using namespace std; #define FIO ios_base::sync_with_stdio(false); cin.tie(NULL) ...