반응형

안녕하세요 오늘의 5분개발지식라디오~ 오늘의 주제는 Git flow입니다.많은 기업들에서 가장 일반적으로 사용하는git 브랜치 관리 전략인데요, 혹시 취준 중이시거나 입사예정이시라면 꼭 숙지하고 가시길 추천드립니다. 그럼 빠르게 알아보도록 하겠습니다.

가장 먼저 git flow를 구성하는 브랜치 타입들을 먼저 살펴보겠습니다.

 

첫번째는 master 브랜치입니다. master 브랜치는 실제로 사용자들에게 서비스가 되고 있는 코드를 담고 있는 브랜치입니다. 따라서 master에는 검증이 완료되고 빌드 에러 등이 없는 상태의 코드가 들어있어야합니다. 일반적으로 master 브랜치는 오직 pull request 머지를 통해서 코드를 넣도록 설정하여 직접 푸쉬를 할 수 없도록 막아둡니다.

 

실제 사용자들에게 서비스가 되는 코드는 이 master 브랜치를 배포하여 제공됩니다.

 

두번째는 develop 브랜치입니다. master에서 checkout하여 파생된 브랜치입니다. 실제로 사용자들을 가지고 있는 서비스의 경우 대부분 매일 혹은 수시로 배포를 하지 않고 일주일에 1번, 2주일에 1번처럼 배포 주기를 정해두는데요, 다음 배포일에 master로 병합될 코드들이 있는 브랜치입니다.

 

시간이 지나 다음 배포일이 다가오게 되면 develop에 있는 커밋, 코드들을 master로 병합시켜 실제 사용자들이 사용하고 있는 프로덕션에 반영하게 됩니다.

 

세번째는 feature 브랜치입니다. feature브랜치는 하나의 스펙을 개발할때 모든 검증 과정을 거친 후에 develop 브랜치에 넣을 수 있도록 각 스펙별로 분리한 브랜치입니다. 따라서 feature 브랜치는 develop 브랜치에서 생성하게 되는데요, 새로운 스펙의 기획이 나오고 개발이 시작될 때 그 시점의 develop 브랜치에서 feature/{스펙명}으로 생성합니다.

 

해당 스펙을 개발하는 개발자들을 개발하면서 develop으로 코드를 넣는 것이 아니라 feature 브랜치에 작업물을 넣습니다. 일련의 개발과정이 완료되면, QA를 거쳐 코드를 검증하고 develop 브랜치로 머지됩니다. 앞서 말씀드렸듯, develop 브랜치 또한 배포되기 직전의 코드들을 모아놓은 브랜치이기때문에 버그가 있는 코드, 미완성 코드들은 들어있으면 안됩니다. 따라서 feature브랜치에서 모든 코드 작업을 마무리하고 들어오게 됩니다.

 

이렇게 master, develop, feature 브랜치가 git flow의 가장 핵심적은 3개의 브랜치입니다. 하지만 이 3개만으로 큰 서비스를 운영하기엔 애로사항들이 있습니다. 그래서 추가적인 브랜치들이 3개 더 있습니다.

 

스펙이 매우 작은 것이 아니면 보통 최소 2~3명 정도가 같이 하나의 스펙을 개발하게 되는데요, 이 때 feature 브랜치에 바로바로 푸쉬를 하게되면 매번 푸쉬할때마다 다른 동료들의 코드를 pull 받고 conflict가 있을 경우 해결하고 다시 푸쉬를 해야됩니다. 또, pull request를 통한 리뷰도 받을 수 없습니다. 

 

그렇기때문에 각각의 작업자는 본인의 작업을 개인브랜치에서 진행합니다. 이 개인브랜치는 feature 브랜치에서 그때그때 checkout을 통해 생성하며 정해진 룰은 없지만 다른 개발자들이 리뷰하는게 힘들지 않도록 기능 단위로 생성하고 머지합니다. 

 

개발해야되는 스펙을 기능 단위로 분리하고 기능단위로 개인 브랜치를 생성하여 개발하고 pull request를 생성하여 feature 브랜치에 머지하고, 로컬에서 feature 브랜치를 pull하여 최신화한 뒤 다시 개인브랜치를 checkout하여 새로운 기능을 개발하는 프로세스를 스펙개발완료시까지 반복합니다. 이렇게 스펙개발이 완료되면 앞서 말씀드린 것 처럼 QA를 거친 후 완료된 스펙의 feature 브랜치를 develop으로 머지하게 됩니다.

 

저희 팀 기준으로는 이니셜/기능명으로 브랜치명을 짓고 있지만 개인브랜치는 pr을 통해 feature 브랜치로 머지되고 나면 없어지는 일회용 브랜치이기때문에 브랜치이름이 그렇게 중요하지는 않습니다.

 

다음은 릴리즈 브랜치 입니다. 브랜치 이름 그대로 배포용 브랜치인데요, 앞서 develop 브랜치에 대해서 설명드릴때 develop브랜치가 배포하기 전 모아두는 브랜치라고 말
씀드렸습니다. release는 여기서 조금 더 배포일이 임박했을때 코드 프리징을 하는 용도로 사용합니다.

 

코드 프리징이란 코드에 더 이상 변화를 주지 않는 것인데요, 배포 직전까지 코드가 계속해서 변경되면 안정성을 장담할 수 없기때문에 배포일로부터 몇일전쯤 develop브랜치에서 release 브랜치를 하나 생성하여 배포 당일에는 develop이 아니라 release 브랜치를 master 브랜치에 머지합니다. release 브랜치가 생성된 다음에 develop 머지되는 feature 브랜치들은 그 다음 배포일에 서비스에 반영되게 되는 것이구요.

 

릴리즈 브랜치는 코드프리징을 하기때문에 이 브랜치의 코드가 진짜로 더 이상의 변화없이 몇일 뒤에 실제 서비스에 반영된다는 것을 뜻합니다. 따라서 회사에 QA가 있을 경우 이 브랜치에서 최종 QA를 진행하여 배포 직전 마지막으로 에러나 버그가 없는지 확인하고 있을 경우 수정하는 작업을 거칩니다.

 

마지막으로 핫픽스 브랜치가 있습니다. 앞서 master 브랜치가 실제로 사용자들이 사용하고 있는 배포되어있는 서비스의 코드라고 설명드렸는데요, 그럼 개발과정에서 발견하지 못한 중대한 버그가 있다면 어떡해야될까요? 페이지가 접근되지 않는다거나 의도한대로 동작하지 않는데 다음 정기배포일까지 방치할 수 없다거나 하는 경우가 생길 수 있습니다.

 

이 때, develop에서 오류사항을 수정하고 master에 머지를 하려고 하면 현재 배포되어있지는 않지만 다음 정기배포일에 배포하기 위해 머지해둔 스펙이 있을 수 있습니다. 이번에 빠르게 배포되어도 문제가 없는 스펙이라면 그래도 그나마 괜찮지만, 만약 마케팅팀과 연동되어 다음 배포일에 대대적인 홍보와 함께 같이 출시되어야하는 스펙이라면 절대 오류 수정과 같이 일정보다 빨리 배포되면 안됩니다.

 

그렇기때문에 정기배포일이 아니지만 프로덕션 환경에서 에러가 발생했을때는 master 브랜치에서 hotfix 브랜치를 하나 생성하여 발생한 오류만 수정하여 바로 master 브랜치에 머지한 후 재배포를 통해 오류를 프로덕션을 제거해줍니다.

 

끝!







반응형
블로그 이미지

개발자_무형

,
반응형

안녕하세요 오늘의 5분개발지식라디오~ 오늘의 주제는 Rust입니다. Rust라는 프로그래밍 언어가 있다라는 것을 여기저기서 들으셨을텐데요, 왜 쓰는지, 무엇이 장점인지를 살펴보도록 하겠습니다.

 

Rust의 장점을 알아보기 전에 Rust의 가장 큰 특징중 하나인 Ownership에 대해서 알아보겠습니다.

 

Rust는 garbage collector가 없는데요, 대신 ownership이라는 개념이 있습니다. 각 값에는 owner가 있고, 한번에 하나의 owner만 존재할 수 있습니다. 만약 이 owner가 scope에서 벗어나면, 값은 메모리에서 해제됩니다.

 

현재의 코드를 보시면 hello라는 값은 변수 s가 ownership을 가지고 있고, s가 괄호를 벗어나면, 즉, scope를 벗어나면 메모리에서 해제가됩니다. 괄호안의 scope에서는 s를 자유롭게 사용할 수 있죠.

 

다음 코드를 보시겠습니다. s1은 hello라는 값을 가지는 String타입입니다. 정확하게는 hello라는 값을 가지는 메모리에 대한 레퍼런스를 가지고 있죠. 그 다음 s2에게 s1의 레퍼런스를 넣어주는데요, 대부분의 언어에서 위의 코드는 지극히 정상적인 코드입니다. 

 

하지만 Rust는 다릅니다. s2에 s1의 레퍼런스를 넣는 과정에서 hello라는 값을 가지는 메모리의 ownership은 s2에게 넘어가고 s1은 더이상 해당 메모리에 접근할 수 없기때문에 가장 하단의 print에서 에러가 발생합니다. 위의 예시가 Rust의 ownership에 대해서 가장 잘 설명해주는 예시인 것 같습니다.

 

따라서 만약 같은 값을 사용하고 싶다면 현재의 코드처럼 clone을 해주어야합니다. 그럼 s1과 s2는 각각 다른 메모리를 참조하게 되기때문에 s1도 여전히 ownership을 가지고 있게 되고 계속해서 메모리에 접근할 수 있습니다.

 

밑의 예시는 변수의 값이 정수인 예시인데요, 정수와 같이 stack에 할당되는 primitive 타입들은 동작이 다릅니다. 다른 언어들도 primitive 타입은 변수를 통해 할당을 하더라도 값을 복사하는데요, Rust도 동일합니다. 따라서 y에 x를 할당한 이후에도 x도 여전히 메모리에 접근할 수 있습니다. 이는 x와 y가 서로 다른 메모리에 대해 ownership을 가지게 되기 때문입니다.

 

마지막으로 조금 더 복잡한 예시로 정리해보겠습니다. 다른부분은 비슷한데요, takes_ownership이라는 함수를 호출하는 부분을 살펴보겠습니다. s라는 변수가 takes_owneship의 인자로 넘어갈때, ownership은 takes_ownership함수의 some_string으로 넘어갑니다. 따라서 takes_ownership이 끝나는 시점에 hello라는 값을 가지는 메모리는 해제되고 some_string와 s모두 더이상 접근할 수 없습니다.

 

하지만 makes_copy로 넘어가는 x는 다릅니다. x는 정수타입이기때문에 makes_copy의 인자로 넘어가더라도 stack에 복사되어 some_integer가 복사본을 사용합니다. 따라서 makes_copy가 끝난 이후에도 x는 여전히 값에 접근할 수 있습니다.

 

Rust의 장점을 먼저 알아보겠습니다. 첫번째로 Rust는 성능이 매우 빠릅니다. 벤치마크 결과를 보면 C++와 비슷한 성능을 보여줍니다. 벤치마크용 알고리즘을 어떤것을 사용하는지에 따라 조금씩 달라질 수 있다는 점을 감안해주시면 될 것 같습니다.

 

두번째로 Rust는 크로스 플랫폼을 지향합니다. Rust는 3대 메이저 OS인 리눅스, 윈도우, 맥OS에서 모두 동작하며 이외에도 여러 플랫폼을 지원합니다. 이 때문에 최근에 Rust를 Web assembly로 컴파일하여 웹프로그래밍에서도 성능의 병목현상이 일어나는 곳에 rust를 부분적으로 도입하는 경우가 늘어나고 있죠. 컴파일이 완료되면 필요한 모든 소스는 바이너리에 같이 들어있기때문에 OS를 제외한 추가적인 runtime은 필요없다고 합니다. 

 

세번째로 Memory-safe합니다. C언어로 코딩을 해보셨다면 null이나 dangling 포인터로 애를 먹은 경험이 다들 있으셨을텐데요, Rust는 컴파일하는 과정에서 이런 에러들을 전부 걸러내준다고 합니다.

 

네번째로 앞서 설명드린 ownership방식을 사용하기 때문에 garbage collector가 없어 overhead가 적습니다.

 

마지막으로 Rust는 사용편의성이 좋다고 합니다. 다양한 내장 유틸리티 함수들을 가지고 있고, c와 c++ 개발자들이 rust를 사용하도록 하기위하여 c와 c++의 standard library들을 거의 모두 다 본인들의 standard library로 편입했다고 합니다.

 

하지만 Rust는 cross-platform을 지향하고 있기때문에 다른 플랫폼에서도 안정적으로 동작하는 것들만 가져왔다고 합니다. 그외에도 js개발자들이 많이 사용하는 npm처럼 cargo라는 써드파티 라이브러리 패키지 매니저를 사용하여 외부 라이브러리를 쉽게 가져다 쓸 수 있다고 합니다.



자 이제 Rust의 단점을 살펴보겠습니다.

 

첫번째로 일단 최신 언어라는 점입니다. Rust는 2015년에 1.0버전이 출시되었는데요, c와 c++와 달리 최근에 출시됐기때문에 아직까지 변동이 많습니다. 또, 무언가 문제가 생겼을때 비교적 레퍼런스가 적다는 점도 문제가 될 수 있습니다.

 

두번째로 어렵습니다. 앞서 설명들이 ownership 개념외에도 기성 프로그래밍 언어를 사용하시던 분들은 생소하실 컨셉들이 여러가지가 있고, 이는 처음 Rust를 접하는 개발자들에게 큰 러닝커브로 다가올 것 같습니다.

 

마지막으로 Rust는 시스템 레벨 언어로 사용될 수 있습니다. c와 c++과 동일하게 rust는 메모리에 직접 접근할 수 있습니다. 이 특징때문에 시스템 프로그래밍을 할때 많이 사용되는데요, 이게 왜 단점이 되냐면 개발자들이 많이 사용하는 파이썬과 같은 하이레벨 언어에 비해 코드가 길어질 여지가 있습니다.

 

성능이 그렇게 크리티컬한 요소가 아니라면 파이썬으로 1분만에 작성하여 돌아가는데 1초가 걸리는 것이 Rust로 30분걸려 작성하고 돌아가는데 300밀리세컨드 걸리는 것보다 더 효율적일 수 있습니다.

 

끝!

반응형
블로그 이미지

개발자_무형

,
반응형

Veraport와 같은 은행, 정부 홈페이지들을 들어가면 설치해야되는프로그램들을 찾아서 삭제해주는 프로그램입니다.

 

Hoax Eliminator.exe
0.65MB

 

원본: https://teus.me/653

반응형
블로그 이미지

개발자_무형

,
반응형

Vanilla Javascript:

function DoPropertiesExist(parent, propertyNames, operator, isArray){
  let checkAND = true
  let checkOR = false

  propertyNames.forEach(prop => {
    //If Property exists
    console.log(prop)
    if (Object.prototype.hasOwnProperty.call(parent, prop) && parent[prop] != null) {
      if (isArray) {
        if (parent[prop].length == 0) checkAND = false
        else checkOR = true
      } else checkOR = true
    } else {
      checkAND = false
    }
  })

  if (operator == "AND") return checkAND
  else if (operator == "OR") return checkOR
}

parent에 검사하고 싶은 object,

propertyNames에는 확인하고 싶은 propertyNames들을 배열로 (ex: ["prop1","prop2","prop3"])

operator에는 "AND" 나 "OR"을

isArray에는 해당 property가 array인지 아닌지를 true / false로 넣어주면 빈 배열이 들어왔을 경우 걸러줍니다.

 

typescript 버전:

function DoPropertiesExist(parent: any, propertyNames: string[], operator: "AND" | "OR", isArray: boolean = false): boolean {
  let checkAND = true
  let checkOR = false

  propertyNames.forEach(property => {
    //If Property exists
    if (Object.prototype.hasOwnProperty.call(parent, property) && parent[property] != null) {
      if (isArray) {
        if (parent[property].length == 0) checkAND = false
        else checkOR = true
      } else {
        checkOR = true
      }
    } else {
      checkAND = false
    }
  })

  if (operator == "AND") return checkAND
  else if (operator == "OR") return checkOR
}
반응형
블로그 이미지

개발자_무형

,
반응형

Float형은 Int형과 달리 메모리에 저장될때:

sign bit + Exponent + value 형태로 저장되게 되는데 이 값을 다시 float형으로 출력하려면 %f로 출력하면 되지만 공부를 할 때에 이 실수가 어떻게 저장되는지 보고싶을 때가 있습니다. 이 때에 사용하면 되는 코드입니다. 

 

#include <stdio.h>
#include <stdlib.h>

int bit_return(int a, int loc) // Bit returned at location
{
  int buf = a & 1<<loc;
        if (buf == 0)
                return 0;
        else
                return 1;
}
int main()
{
        float a;
        scanf("%f",&a);
        void *b;
        b = &a;
        int i = 0;
        for (i = 31; i>=0; i--)
        {
                int j =0;
                printf("%d",bit_return(*((int*)b),i));
                j = 31 - i;
                switch(j){
                case 0:
                case 8:
                        printf(" ");
                }
        }
        printf("\n");
        return 0;
}
반응형
블로그 이미지

개발자_무형

,
반응형

 

실행시키면 이렇게 뜨는데 실행시키면 자동으로 이전에 있던 자동종료 타이머를 종료시킵니다. 예약해놓았던 타이머를 취소만 시키고 싶다면 켰다가 끄면 됩니다.

 

분단위로 끄고 싶은 시간 입력하고 Enter를 누르면 종료 예약이 됩니다.

업데이트나 다운로드 등 시간이 걸리는데 끝나고 수동으로 끌 수 없을때 설정해놓고 다른일 하시면 될 것 같습니다~

timer.bat
0.00MB

반응형
블로그 이미지

개발자_무형

,