Namgung Jong Min

토끼굴을 개척하는 개발자

cli와 gui의 차이

cli: command line / 시각적인 요소가 아닌 명령어를 통해 컴퓨터와 상호작용하는 방식입니다.

gui: graphic user interface / 평소에 폴더를 클릭하고, 그 폴더 안의 파일을 클릭해서 컴퓨터를 활용하는 방식입니다.

글로만 이루어진 화면을 토대로 어떤 폴더에 들어와있는지 구별할 줄 알고, 어떤 명령어를 입력했을 때 어떤 동작이 수행되는 지를 알아야 합니다.

기본 명령어

ls : 현재 경로의 모든 파일/폴더들을 리스팅

cd (경로) : 경로로 이동 / cd .. : 이전 경로로 이동

절대경로 vs 상대경로

절대경로 : 내가 위치한 곳과 상관없이, 특정한 폴더/파일이 위치한 경로의 전체 주소를 말합니다.
절대 경로는 앞에 ‘/‘를 붙습니다.

상대경로 : 내가 위치한 곳에서의 본 특정한 폴더/파일의 경로를 말합니다.

mkdir (폴더명) : 새 폴더 생성

mv 이동 / rm 삭제 / cp 복사 등의 여러 명령어가 있습니다.

깃관련 오류가 생겼을 때 현재 자신이 있는 경로가 잘못되어있는 경우가 많다. 항상 자신의 경로를 먼저 확인하도록 한다.

Git이란

버전 관리를 위한 프로그램입니다.
버전 관리라는건 특정한 프로젝트 등을 진행할 때, 진행 상황을 수시로 기록하면서, 필요할 때는 이전 상황으로 돌아갈 수 있게 해주는 등 종합적으로 폴더/파일의 수정 사항을 관리하는 것을 말합니다. 만약 자기소개서를 작성한다 가정해보겠습니다.

[1차 완]

1
2
3

안녕하세요

[2차 완]

1
2
3

안녕하세요. 제이름은

[최종]

1
2
3

안녕하세요. 제이름은남궁종민 입니다.

[찐 최종]

1
2
3

안녕하세요. 제 이름은 남궁종민 입니다.

이런식으로 수정의 수정을 거듭하면서 작성을 하게 되는데 이렇게 각각의 수정 사항을 원할 때마다 수시로 기록하면서 이전 수정 상태로 돌아갈 수 있도록 하는 기능이 바로 Git입니다!

Git 사용해보기

git 사용 개괄적으로 살펴보기

git add 명령어를 통해 어떤 파일을 관리할지 지정하고,
git commit 명령어로 현재 관리중인 파일을 하나의 버전으로 저장

git은 아직 git add 를 통해 관리되기 전 파일을 untracked file 이라고 말하고, 관리되는 파일을 tracked file이라고 말합니다.
commit이 되기 전 상태를 staged 상태라고 말합니다.

버전 관리 시작

우선 vscode를 실행하여 hello.txt라는 파일을 하나 만들고 ‘안녕하세요’라는 텍스트를 입력합니다.


git 폴더 설정

git init 명령어를 통해 git 저장소를 처음으로 만들어줍니다.

현재 폴더 자체를 git이 관리하고 있는 상태지만 아직 untracked 상태로 파일을 지켜보고 있지는 않은 상태입니다.


git으로 폴더를 관리하는 순간 .git이라는 숨김 파일이 생성되고 git 관련 버전등이 파일 안에서 관리되게 됩니다.


git 상태 확인하기/추가하기

git status 명령어를 통해 보면 폴더 내 파일들이 어떤 상태인지 확인할 수 있다. untracked 상태의 hello.txt 파일을 add하여 깃이 바라보게 해봅시다.

git 으로 staged 상태로 올려야 할 파일이 많을 때 git add . 을 입력하면 폴더 내 모든 파일을 관리하게 할 수 있지만, 각각의 기능 별로 add commit을 하는 실무의 특성상 좋은 습관은 아니다.


git 상태 되돌리기

git reset 명령어를 사용하면 staged 상태의 파일을 untracked 상태로 되돌릴 수 있습니다.


git commit 하기

이후에는 git commit 명령어를 통해 버전으로 저장합니다.

제 경우에는 git 에디터 기본으로 vim으로 설정되어 있기 때문에 vim창이 떴지만 일반 유저 분들은 git commit -m “{커밋 메시지}” 를 적어주시면 됩니다.

commit이 정상적으로 진행 되었다는 메시지를 확인할 수 있습니다.

commit 관련해서도 지켜야할 규칙이나 컨벤션이 존재하지만 이는 기업 컨벤션마다 다르고 일반적인 규칙 등은 차후 다루겠습니다.

git commit 메시지 수정하기

git commit –amend 명령어를 통해 수정할 수 있습니다.

가장 최근 커밋을 불러와 내가 원하는 방식으로 바꿀 수 있습니다.


추가 커밋하고 버전 확인하기

text 내용을 바꾸고 추가로 add 후 commit을 해주었습니다.

추가로 커밋한 버전이 로그에 잘 올라와있나 확인해봅시다.

변경한 텍스트의 버전과 변경하기 전 텍스트 버전이 둘다 로그에 남아있는 것을 확인할 수 있습니다. 업데이트 하기 전 버전으로 돌아가고 싶다면 로그에 나와있는 커밋 정보를 활용해 명령어를 사용하면 되겠죠?


커밋은 기능단위로 하는 것이 원칙입니다!! 여러가지 파일이 있다면 각 파일의 기능 단위로 add와 commit을 진행해야 합니다.

모든 수정사항을 하나의 커밋으로 저장하게 된다면 커밋에 여러 기능에 대한 업데이트가 혼재하는 상황이 발생하게 됩니다. 이것은 추후 작업의 진행사항을 파악하고, 버그를 찾아내는 것에 큰 걸림돌이 될 수 있습니다.

버전 되돌리기

우선 커밋 버전으로 돌아가려면 각 커밋 버전을 지칭하는 대상을 알아야 합니다.

로그를 통해 커밋의 고유 번호를 확인할 수 있습니다.

2가지 방식이 있습니다.

revert - 현재까지의 commit 기록을 유지하면서, 특정한 commit 이전으로 되돌리는 명령어입니다.

“추가수정사항” 이라는 텍스트를 추가하고 커밋했습니다. 세번째 줄이 없던 버전으로 돌아가고 싶다면


로그의 가장 최근 커밋이 없었던 때로 돌아가야 합니다.

git revert [해당 커밋 고유번호] 를 입력하면 최근 수정사항의 커밋이 없던 때로 돌아가기 때문에 세번째 텍스트가 사라지게 됩니다.

로그를 살펴보면 어떤 커밋을 없던 상태로 되돌렸는지 있었던 커밋, 되돌린 커밋 또한 로그에서 확인할 수 있습니다.

reset - 특정 커밋으로 돌아가면서, 그 커밋 이후의 커밋 기록을 삭제하는 명령어입니다. 마치 그 이후의 커밋이 없었던 것처럼 만들어주는 것입니다

soft / hard / mixed 세가지의 옵션이 있습니다.

soft - 파일은 그대로 두면서 커밋 기록만 되돌아갑니다. 수정 사항은 staged 상태가 됩니다.

hard - 파일도 함께 되돌아갑니다.

mixed - 파일을 그대로 두면서 커밋 기록이 돌아가는데 수정사항을 staged 상태가 아닌 untracked 상태로 둡니다.


Github

git을 통해 관리하는 컴퓨터 내의 저장소를 local저장소라 합니다.

github 사이트를 통해 관리하는 곳을 원격저장소 remote 저장소라고 합니다. github 사이트에서 새로운 레포지토리를 만들었습니다.

원격저장소와 연결하기

git remote add origin [깃허브 클론주소] 명령어를 입력하여 github와 연동시켜줍니다.


연결 후에 git push origin main 명령어를 통해 원격 저장소의 main 브랜치에 연동된 local 저장소를 푸시해봅니다.

원격 저장소에 로컬 저장소의 파일들이 업로드 된 것을 확인할 수 있습니다.


마크다운 관련 수업

(배지 찾기 사이트)
https://github.com/alexandresanlim/Badges4-README.md-Profile


원격 저장소의 버전을 로컬로 가져오기

md파일을 원격 저장소에서 수정해봅시다.

수정된 원격 저장소의 버전과 로컬 저장소의 버전이 다르기 때문에 동기화를 시켜주기 위해서는 pull시켜 주어야 합니다.

명령어 git pull origin main을 통해 동기화 시켜줍니다.

로컬 저장소의 상태가 원격 저장소와 완전히 같아졌습니다!


github로 협업하기

clone / fork 두가지 방법

clone : 하나의 레포지토리로 여러명이서 작업합니다. 원격 저장소 1개에 같이 작업할 사람을 collaborator 로 추가하여 함께 작업합니다.

git clone은 깃허브에 있는 저장소를 그대로 내 컴퓨터로 가져오고 싶을 때 쓰는 명령어입니다.

단순히 파일 다운로드만을 하는 것이 아니라 commit 기록과 역사까지 전부 가져오기 때문에 이전 기록으로 돌아갈 수도 있고, pull / push 등을 통해 실제 저장소에 반영할 수도 있습니다.

원격 저장소를 클론했습니다. 그리고 원격 저장소에서 수정을 거친 뒤 pull을 받아보겠습니다.

git pull origin main 명령어를 수행하면

수정된 사항이 로컬 저장소에도 적용되는 것을 볼 수 있습니다.

개발단위가 작은 소규모 개발팀 등에서 사용하는 방식입니다.

fork : 하나의 레포지토리를 각자가 복사하여 자기 레포지토리에서 작업하고 원본 레포지토리에 요청을 보내 합쳐가면서 작업합니다.

1. 변수의 정의
2. 변수가 필요한 이유
3. 자바스크립트 메모리 접근
4. 자바스크립트 변수의 동작

변수의 정의

변수란 하나의 값을 저장하기 위해 확보한 메모리 공간 자체, 또는 그 공간을 식별하기 위해 붙인 이름입니다.

변수가 필요한 이유

1
10 + 20;

다음과 같은 식을 코드에서 실행한다고 생각해보겠습니다.

자바스크립트 엔진이 위의 식을 해석하면 10과 20은 컴퓨터의 메모리에 담기고 +연산자는 cpu에서 실행되게 됩니다. 이 때 메모리에 10과 20, 그리고 연산 결과 30은 2진수의 형태로 메모리 셀에 저장되게 됩니다.

이렇게 30이라는 값을 연산하여 얻어냈다는 것은 그 값을 사용해 무엇인가를 하겠다는 의도가 있을 것입니다. 30이라는 값을 재사용하기 위해서는 저장된 메모리 공간에 대한 접근이 필요합니다.

자바스크립트 메모리 접근

자바스크립트는 메모리에 직접적인 접근을 허용하지 않는다!

저장된 값을 사용하기 위해서 메모리에 접근하는 것이 필요하다 했습니다. 그러나 메모리에 직접적으로 접근하는 것은 치명적인 오류를 발생시킬 수 있습니다. 만약 실수로 운영체제가 사용하고 있는 값을 변경하게 되면 시스템이 멈출 수도 있습니다.

또한 자바스크립트는 값이 저장될 메모리 주소를 코드가 실행될 때마다 메모리 상황에 따라 임의로 결정합니다. 따라서 동일한 코드를 실행해도 실행마다 값이 저장되는 메모리 주소가 변경되고, 이전 값이 저장된 주소를 알수도 없으며, 알려주지도 않기 때문에 값이 저장된 메모리를 직접적으로 찾는 것은 올바른 방법이 아닙니다.

자바스크립트는 변수를 통해 간접적으로 메모리에 접근한다!

따라서 자바스크립트에서는 메모리에 접근할 때 변수라는 요소를 통해 값이 저장된 메모리에 간접적으로 접근하여 안전하게 사용할 수 있습니다. 이러한 메모리 관리 방식을 가진 언어를 매니지드 언어라고 합니다.


매니지드 언어 VS 언매니지드 언어

프로그래밍 언어는 메모리 관리 방식에 따라서 매니지드 언어와 언매니지드 언어로 분류됩니다. 두 메모리 관리 방식은 성능과 생산성에 있어 장단점을 지닙니다.

매니지드 언어

자바스크립트와 같은 매니지드 언어는 메모리의 할당이나 해제를 언어 자체에서 담당하고 개발자의 직접적인 메모리 접근을 허용하지 않습니다. 즉, 개발자가 명시적으로 메모리를 제어할 수 없습니다. 메모리 접근은 변수를 통해 간접적으로 이루어지며, 메모리의 해제 또한 ‘가비지 컬렉터’를 통해 자동적으로 이루어집니다.

이와 같은 특성을 지닌 매니지드 언어인 자바스크립트는 개발자가 직접 제어해야 하는 부분이 줄어든 만큼 일정한 생산성을 확보할 수 있다는 장점이 있지만 성능 면에서는 손실을 감수해야합니다.

언매니지드 언어

C 언어와 같은 언매니지드 언어는 개발자가 명시적으로 메모리를 제어합니다. 개발자 주도로 메모리를 제어하기 때문에 개발자의 역량에 따라 최적의 성능을 확보할 수 있다는 장점이 있지만 반대의 경우 오히려 성능의 최적화가 힘들 수 있습니다. 또한 매니지드 언어에 비해 부족한 생산성이 단점이 될 수 있습니다.


자바스크립트 변수의 동작

변수 선언

변수를 사용하기 위해 변수를 선언해야 합니다. 먼저 선언을 통해 자바스크립트 엔진에 식별자의 존재를 알립니다. 이 때 자바스크립트 엔진은 식별자가 참조할 메모리 공간을 확보하게 됩니다. 이후에 자바스크립트 엔진은 실행 컨텍스트에 식별자를 등록하게 됩니다.

메모리의 공간을 확보한다 했으니 해당 메모리가 비어있다고 생각할 수 있지만, 사실 메모리는 비어있는 것이 아닌 이전에 다른 어플리케이션에서 사용하고 참조가 끊어진 쓰레기 값(garbage value)가 들어있으며 자바스크립트 엔진은 암묵적으로 undefined를 할당하여 초기화하게 됩니다.

왜 undefined로 초기화하는 과정을 거칠까?

초기화 과정을 거치지 않는다면 이전에 썼던 쓰레기 값이 들어있는 메모리셀을 참조하게 되기 때문에 할당 직전 값을 참조하게 될 경우 원하지 않는 동작이 일어날 수 있습니다.

1
2
3
var test;

console.log(test + 1);

위 코드를 살펴보겠습니다. test라는 식별자에 어떠한 값도 할당하지 않고 1을 더한 연산한 결과를 출력했기 때문에 숫자가 아니라는 NaN 값이 나오게됩니다. 하지만 초기화를 하지 않아 쓰레기 값으로 ‘1’과 같은 값이 들어있다고 가정해보면 자바스크립트의 암묵적 타입 변환을 통해 ‘11’이라는 값이 출력되게 됩니다.

즉 초기화 과정을 거치지 않게 되면 코드 동작의 일관성을 저해하게 되며 개발자가 예상하지 못하는 결과를 출력할 수 있게 되기 때문에 초기화 과정이 필요합니다.

변수 선언의 시점

자바스크립트 엔진은 코드를 읽기 전에 가장 먼저(런타임 이전) 전체 코드에서 선언문을 전부 가져와 실행컨텍스트에 등록을 하게 됩니다. 이 후 변수 선언 키워드에 따라 초기화와 할당의 시점이 달라지게 됩니다. 변수 선언이 코드를 읽기 전에 가장 먼저 실행된다는 것을 다음 코드를 통해 확인할 수 있습니다.

1
2
3
4
5
console.log(test); // output: undefined

var test = 20;

console.log(test); // output: 20

만약 코드가 실행되는 런타임에 변수가 선언되었다면, 선언문 위에 있는 console.log(test)는 아직 선언 이전이기 때문에 ‘식별자를 참조하려 했으나 식별자를 찾을 수가 없어!’라는 뜻의 Reference 에러를 내야합니다. 그러나 코드가 정상 동작하는 것을 위 코드에서 확인할 수 있습니다.

이것을 통해 변수의 선언은 코드가 실행되는 런타임이 아닌 그 이전에 먼저 실행된다는 것과 undefined로 초기화까지 일어난다는 것을 알 수 있습니다. 이러한 현상을 ‘호이스팅’이라고 합니다. 자바스크립트의 모든 변수, 함수, 클래스는 이렇게 런타임 이전 식별자 정보를 실행컨텍스트에 먼저 등록하는 과정을 거치게 됩니다.
'호이스팅'에 대해서는 차후 다른 포스팅에서 자세히 다루겠습니다.

1
2
3
4
5
6
7
8
console.log(test1); // ReferenceError
console.log(test2); // ReferenceError

let test = 20;
const test = 21;

console.log(test1);
console.log(test2);

그러나 위의 코드의 경우(let과 const 키워드를 사용한 변수 선언) ReferenceError를 내보내게 됩니다. 그 이유는 var 키워드와 ‘초기화 시점’이 다르기 때문입니다.

let과 const의 경우 초기화 과정과 할당 과정이 선언과 분리되어 코드가 직접 실행되는 런타임에 이루어집니다. 위에서 말했듯이 초기화는 이전 쓰레기 값의 참조를 방지하기 위해 꼭 필요한 작업입니다. 따라서 초기화 시점이 다른 let과 const의 경우 초기화가 되기 이전 상황에서는 메모리에 접근할 수 없기 때문에 이러한 오류를 내보내게 됩니다.

변수 할당

1
var score = 100;

위 코드는 하나의 문처럼 보이지만 사실 두개의 문의 단축 표현입니다. 즉 자바스크립트는 변수 선언과 값의 할당을 2개의 문으로 나누어 각각 실행합니다. 따라서 단축 표현시에도 식별자 선언 후 undefined가 먼저 먼저 할당되어 초기화, 그 이후 100이라는 값이 할당이 되는 것은 변함이 없습니다.

1
2
3
4
var score;
// 선언
score = 100;
// 할당

변수 초기화와 할당 시 메모리 동작

변수에 값이 할당될 때, undefined가 저장되어있는 메모리 공간을 지우고 그 메모리 공간에 할당 값 80을 다시 넣어주는 것이 아닙니다. 값을 할당할 때에는 변수가 참조할 메모리 영역을 새로 확보하고 그 메모리 영역을 변수가 새로이 참조하게 됩니다.

왜 undefined로 초기화 된 영역을 업데이트하는 것이 아니라 새로운 영역을 확보하고 값을 할당할까? 자바스크립트가 개발자의 메모리 제어를 허용하지 않기 때문이다. 메모리를 확보하고 그 메모리의 값을 바꾼다는 것 자체가 메모리를 제어하게 되는 것이다. 엔진은 자바스크립트 기본원리에 따라 매번 값의 생성시에 임의로 새로운 메모리 주소를 부여한다. 이 때문에 메모리 동작에 있어서 매니지드 언어는 성능 상 손해를 감수할 수 밖에 없다.

변수 할당 전 undefined로 초기화 되는 과정은 변수의 값이 저장될 공간을 미리 확보하는 것이 아닌 할당 전 변수에 접근했을 때 예상치 못한 결과를 막기 위한 것을 다시 한번 기억해야합니다.

재할당의 경우도 마찬가지입니다. score의 값을 200으로 재할당 한다면 기존 100이 저장된 메모리의 값을 변경하는 것이 아니라 새로운 메모리 공간을 확보하여 값을 저장합니다.

가비지 컬렉터

변수의 동작 과정에서 초기화, 할당, 재할당 시 새로운 메모리 공간을 확보하게 된다고 했습니다. 이 때 변수가 더 이상 참조하지 않게 되는 메모리 공간은 어떻게 될까요?
가비지 컬렉터가 메모리를 해제하여 메모리 누수를 방지합니다. 언제 가비지 컬렉터가 메모리를 해제하는지는 예측할 수 없습니다. 또한 가비지 컬렉터는 단순히 확보한 메모리 (더 이상 이 메모리를 참조할 수 없는 상태)를 해제할 뿐이지 메모리에 저장된 값 자체를 삭제하지는 않습니다.

0%