반응형

Mac은 기본적으로 Git 이 설치되어 있는데 버전도 낮고, 업그레이드 하려면 새로 다운로드를 받아야하는데 매번 이렇게 관리하는 것도 귀찮다. 그래서 맥북을 사용할 때 Homebrew 를 이용해서 대부분의 응용프로그램들을 관리하면 편하다. Git 도 마찬가지다

Homebrew 란?
Homebrew 는 brew 라고 흔히 부르는데 MacOS 와 Linux 용 패키지 관리 매니저이다.
brew 를 통해 패키지를 쉽게 설치하고 제거할 수 있다. 웬만한 프로그램은 다 있기 때문에 없는 것 빼고는 brew 를 통해 관리하는게 좋다.
프로그래밍을 할 때도 마찬가지지만 내가 통제할 수 있는 상태가 좋기 때문이다.

Git 설치

Homebrew 설치

Homebrew 가 설치되어 있지 않다면 먼저 설치하자.
아래 스크립트를 입력하면 자동으로 설치된다

$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

$ brew list --cask

Homebrew 를 이용해 Git 설치

간단하다.
설치하기 전후로 git 버전을 확인해보면 엄청나게 차이가 많이나는 걸 확인할 수 있다.

$ brew install git

$ git --version

Git 기본 설정

Git 을 설치했으면 사용하기 전에 기본적으로 세팅해주자.
설정은 설정 명령어를 통해 설정 파일을 읽고 쓰는 방식으로 바꿀 수 있다. 설정의 우선순위는 저장소 > 사용자 설정 > 시스템 이다.
처음에는 사용자 이름과 이메일 주소 정도만 설정해주면 된다.

# 이름 설정
$ git config --global user.name "Noah"

# 이메일 설정
$ git config --global user.email "noah@example.com"

# 설정 확인
$ git config --list

도움말 보기

# Git config 명령 도움말
$ git help config

# Git 명령어 도움말
$ git help
반응형
반응형

개발 프로젝트를 할 때 Git 을 많이 사용한다. 협업을 위해서도 사용하고, 개인으로 프로젝트를 관리하기 위해서도 많이 사용한다.
보통은 Git 의 사용법만 적당히 익힌 뒤 사용하는 경우가 많아서 Git 의 기능을 제대로 사용하지 못하거나 충돌같은 문제가 생기면 제대로 대응하지 못하는 경우가 많다. 그렇기 때문에 Git 에 대해 알고 사용하자.

Git 이란

Git 은 컴퓨터 파일의 변경사항을 추적하고 협업을 하기 위한 분산 버전 관리 시스템이다.
Git 은 2005년에 리눅스 토발즈와 리눅스 커널 개발자들이 함께 개발 하였다. 2002년에 오픈소스 프로젝트 리눅스 커널은 BitKeeper 라고 하는 상용 분산 버전 관리 시스템을 사용하였다. 그런데 2005년에 BitKeeper 가 유료화가 되면서 리눅스 커널과의 관계가 틀어지고, 리눅스 토발즈와 개발자들이BitKeeper 를 사용하면서 배운 점을 바탕으로 Git 을 만든 것이다.

Git 의 목표

지금도 그렇고 Git 이 추구하는 목표는 다음과 같다.

  1. 빠른 속도

  2. 단순한 구조

  3. 비선형적인 개발(수천 개의 동시 다발적인 브랜치)

  4. 완벽한 분산

  5. 리눅스 커널 같은 대형 프로젝트에도 속도나 데이터 크기 면에서 유용할 것

버전 관리란

Git 에 대해 알기 위해서는 먼저 버전 관리에 대해 알아야 한다.
버전 관리 시스템(VCS, Version Control System)은 파일 변화를 시간에 따라 기록했다가 나중에 특정 시점의 버전을 다시 꺼내올 수 있는 시스템이다.
우리가 일상에서도 버전 관리 시스템을 쓰고 있는데 문서 되돌리기나, 포토샵에서 레이아웃 작업 이력 등도 모두 버전 관리 시스템이라 볼 수 있다.
VCS 를 사용하면 각 파일을 이전 상태로 되돌릴 수 있고, 프로젝트를 통째로 이전 상태로 되돌릴 수도 있고, 시간에 따라 수정 내용을 비교해볼 수 있고, 누가 문제를 일으켰는지도 추적할 수 있고, 누가 언제 만들어낸 이슈인지도 알 수 있다. 또한 파일을 잃어버리거나 잘못 고쳤을 때도 쉽게 복구할 수 있다.

버전 관리 종류

로컬 버전 관리

VCS 는 로컬 버전 관리부터 시작된다. 로컬 버전 관리는 서버없이 내 컴퓨터에서 간단한 데이터베이스를 사용해 파일의 변경 정보를 관리하는 시스템이다.
버전을 관리하기 위해 디렉터리로 파일을 복사하는 방법을 사용할 수 있는데 이러면 디렉터리가 지워지거나, 실수로 파일을 수정하거나 잘못 복사할 수 있다. 이러한 이유로 프로그래머들에 의해 VCS 가 탄생하였다. 하지만 로컬 버전 관리는 말그대로 내 컴퓨터에서만 사용하기 위한 것으로 협업이 어려운 단점이 있다.

중앙집중식 버전 관리

중앙집중식 버전 관리(CVCS, Centrolized Version Control System) 는 파일을 관리하는 서버가 별도로 있고 클라이언트가 중앙 서버에서 파일을 받아서 사용(Checkout) 하는 시스템이다. 로컬 버전 관리로는 프로젝트 협업 등이 어렵기 때문에 만들어졌으며 Subversion(SVN) 같은 시스템이 대표적이다. 또한 관리자는 누가 무엇을 할지 관리할 수 있고, 모든 클라이언트의 로컬 데이터베이스를 관리할 필요 없이 VCS 하나를 관리하기 때문에 훨씬 쉽다.
하지만 CVCS 도 결점이 있는데 가장 대표적인 것이 중앙 서버가 다운되면 협업이 불가능하고, 백업할 방법도 없어진다. 그리고 중앙 데이터베이스가 있는 하드디스크에 문제가 생기면 프로젝트의 모든 히스토리를 잃는다.

분산 버전 관리 시스템

Git 과 같은 분산 버전 관리 시스템(DVCS, Distributed Version Control System)은 저장소를 전부 복제하는 방식의 시스템이다.
로컬 버전 관리나 중앙집중식 버전 관리의 결점들을 보완하여 클라이언트 중에서 아무거나 골라도 서버를 복원할 수 있고, 모든 Checkout 은 모든 데이터를 가진 진정한 백업이다. 대부분의 DVCS 환경에서는 리모트 저장소가 존재한다. 사람들은 동시에 다양한 그룹과 다양한 방법으로 협업할 수 있다. 계층 모델 같은 중앙집중식 시스템으로는 할 수 없는 워크플로를 다양하게 사용할 수 있다.

Git 의 특징

Subversion 이나 Perfoce 같은 것을 사용해봤다고 하면 개발한지 오래됐을 확률이 높다. Git 을 배우려면 SVN 등을 사용하던 경험을 버려야 한다고 하는데 작동 방식이 다르기 때문이다.

차이가 아닌 스냅샷을 저장한다

위에서 언급 했듯이 SVN 등과 Git 의 가장 큰 차이점은 데이터를 다루는 방법에 있다. SVN 등은 파일의 변화를 시간순으로 관리하면서 파일들의 집합을 관리한다. 즉 데이터 기반 관리 시스템인 것이다. 예를들어 1 + 2 + 3 을 쌓아 간다면 되돌아 가기 위해서는 -3, -2 로 역산해 나가야 한다.
대신 Git 은 시간순으로 프로젝트의 스냅샷을 저장한다. 파일이 달라지지 않았으면 Git 은 성능을 위해서 파일을 새로 저장하지 않는다. 단지 이전 상태의 파일에 대한 링크(레퍼런스 참고)만 저장한다. 그렇기 때문에 Git 은 한 달 전의 파일과 지금의 파일을 로컬에서 찾는다. 파일을 비교하기 위해 리모트에 있는 서버에 접근하고 나서 예전 버전을 가져올 필요가 없다. Git 은 데이터를 스냅샷의 스트림처럼 취급한다.

스탭샷(snapshot) 이란

컴퓨터 파일 시스템에서 스냅샷은 과거의 한 때 존재하고 유지시킨 컴퓨터 파일과 디렉터리의 모임이다.
스냅샷은 마치 사진을 찍듯이 특정 시점에 파일 시스템을 포착해 보관한다고 해서 붙여진 이름이다. 스냅샷은 원본 데이터를 그대로 복사해 다른 곳에 저장하는 백업과 달리 초기 생성 시 혹은 데이터의 변경이 있기 전까지는 스토리지의 공간을 차지하지 않는다.

거의 모든 명령을 로컬에서 실행한다

Git 은 거의 모든 명령이 로컬 파일과 데이터만 사용하기 때문에 네트워크에 있는 다른 컴퓨터는 필요 없다. 프로젝트의 모든 히스토리가 로컬 디스크에 있기 때문에 모든 명령이 순식간에 실행된다. “가장 빠른건 역시 localhost” 와 같은 이치다. 그래서 Git 에서 프로젝트의 히스토리를 조회할 때 서버가 필요없다.

Git 은 무결성을 보장한다

Git 은 데이터를 저장하기 전에 항상 체크섬을 구하고 그 체크섬으로 데이터를 관리한다.
체크섬은 Git 에서 사용하는 가장 기본적인(Atomic) 데이터 단위이자 Git 의 기본 철학이다. Git 은 SHA-1 해시를 사용하여 체크섬을 만든다. 만든 체크섬은 40자 길이의 16진수 문자열이다. 실제 사용할 때에는 줄여서 8글자만으로도 사용이 가능하다. 파일의 내용이나 디렉터리 구조를 이용하여 체크섬을 구한다. 실제로 Git 은 파일을 이름으로 저장하지 않고 해당 파일의 해시로 저장한다.

체크섬(checksum) 이란

체크섬은 자료의 무결성을 보호하는 단순한 방법이다.
데이터에 checksum 을 추가하여 연산을 통해 checksum 이 맞아 떨어지는지 확인해 봄으로써 데이터가 손상되지 않았다고 알 수 있다.
예를들면 위조 및 변조 방지를 위해 추가하는 주민등록번호 끝자리가 있다. 주민등록번호를 앞의 12자리 숫자에 각각 순서대로 2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5 를 곱한 뒤 모두 더한다. 그리고 더한 값을 11로 나눠서 나온 나머지 값을 11에서 뺀 숫자와 주민등록번호 끝자리가 같으면 유효한 것이다.

Git 은 데이터가 추가 되기만 할 뿐이다

Git 으로 한 것이면 무엇이든 Git 데이터베이스에 데이터가 추가된다. 데이터를 되돌리거나 데이터를 삭제할 방법이 없다. 되돌리기나 삭제를 하면 되돌리거나 삭제 했다는 내역을 추가할 뿐이다.

세 가지 상태

Git 은 Committed, Modified, Staged 이렇게 세가지 상태로 관리한다.

  • Committed: 데이터가 로컬 데이터베이스에 안전하게 저장됐다는 것을 의미, Git 디렉터리 단계

  • Modified 는 수정한 파일을 아직 로컬 데이터베이스에 커밋하지 않은 것을 의미, 워킹 트리 단계

  • Staged: 현재 수정한 파일을 곧 커밋할 것이라고 표시한 상태를 의미, Staging Area 단계

Git 디렉터리는 Git 이 프로젝트의 메타데이터와 객체 데이터베이스를 저장하는 곳을 말한다. Git 디렉터리가 Git 의 핵심이다. 다른 컴퓨터에 있는 저장소를 Clone 할 때 Git 디렉토리가 만들어 진다.

워킹 트리는 프로젝트의 특정 버전을 Checkout 한 것이다. Git 디렉터리는 지금 작업하는 디스크에 있고 그 디렉터리안에 압축된 데이터베이스에서 파일을 가져와서 워킹트리를 만든다.

Staging Area 는 Git 디렉터리에 있다. 단순한 파일이고 곧 커밋할 파일에 대한 정보를 저장한다.

Git 의 프로세스는 다음과 같다.

  1. 워킹 트리에서 파일을 수정

  2. Staging Area 에 있는 파일을 Stage 해서 커밋할 스냅샷을 생성

  3. Staging Area 에 있는 파일들을 커밋해서 Git 디렉토리에 영구적인 스냅샷으로 저장

Git 디렉토리에 있는 파일들은 Committed 상태이다. 파일을 수정하고 Staging Area에 추가했다면 Staged 이다. 주로 스테이지에 올린다고 표현한다. 그리고 Checkout 하고 나서 수정했지만, 아직 Staging Area에 추가하지 않았으면 Modified이다.


해당 포스팅은 Pro Git 을 참고하였습니다.

반응형
반응형

코딩(혹은 프로그래밍) 공부를 하다 보면 정작 우리가 당연히 사용하는 컴퓨터에 대해서는 기본 지식인 양 넘어가는 것들이 많다. 그래서 코딩(혹은 프로그래밍) 공부를 시작하기 전에 상식으로 알아두면 좋을 것들을 간단히 정리해 보았다.

 

컴퓨터에 대해여

컴퓨터라(computer)는 이름은 계산하는 기계라는 뜻으로 "계산하다(compute)"라는 동사에서 유래되었다.(항상 이름의 뜻을 잘 알아두자!)
이렇듯 컴퓨터는 인간의 연산을 돕기 위해 컴퓨터가 발명된 것이다.

 

 

 

프로그래밍 언어

우리가 영어나 한글을 사용하듯이 컴퓨터는 0과 1로 이루어진 이진수를 언어로 사용한다. 이를 기계어라고 한다.

세상에 인간의 언어가 다양하듯이 프로그래밍 언어도 다양하고, 지금 이순간에도 새로운 프로그래밍 언어들이 만들어지고 있다. 대략적인 프로그래밍 언어의 발전 흐름을 살펴보면 다음과 같다.

  • 1세대: 기계어

  • 2세대: 어셈블리어

  • 3세대: C, 포트란, 베이직, 코볼 등

  • 4세대: 비주얼베이직, 델파이, 파워빌더 등

  • 5세대: 자바, C++, C#, ASP, PHP 등

여기서 어셈블리어는 기계어를 그나마 사람이 사용할 수 있도록 0101001 같은 숫자를 기호화 한 언어라고 볼 수 있다.

3세대 언어들은 주로 절차 지향 중심의 언어들인데 이때부터 프로그래밍 언어가 컴퓨터보다 사람에게 더 친숙하게 만들어지기 시작한다.

그래서 기계어, 어셈블리어를 저급언어(low-level), 이후의 언어들을 고급 언어(high-level)라고 한다.

4세대 언어들은 주로 데이터를 처리하기 위한 데이터베이스 관련 프로그램을 개발할 수 있는 언어들이다.(대부분 5세대 언어들에 의해 대체되고 있다.)

5세대 언어들은 객체지향 언어가 많고 또한 네트워크 관련 기능이 강화된 언어들이 많다.

최근에 많이 쓰이는 언어들은 대부분 5세대 언어라고 생각하면 된다.

 

 

 

컴퓨터는 어떻게 우리가 작성한 코드를 알아들을까

컴퓨터의 언어는 0과 1로 이루어진 기계어인데 어떻게 우리가 작성한 프로그래밍 언어(코드)를 인지하는 걸까?

위에서 언급했듯이 3세대 언어부터는 사람에 친화적인 프로그래밍 언어이기 때문에 컴퓨터가 프로그래밍 언어를 이해하기 위해서는 별도의 번역기가 필요하다.

비유하자면 컴퓨터에게 어셈블리어까지는 사투리라고 한다면 3세대 언어부터는 아예 외국어가 되는 것이다.

그렇기 때문에 코드(프로그램)가 컴퓨터에서 실행되기 위해서는 컴퓨터가 인식할 수 있는 기계어로 번역되어야 한다.

사람에 의해 작성된 코드는 번역기를 거쳐 기계어로 번역되고, 컴퓨터는 기계어로 작성된 코드들을 실행하는 방식이다.

번역하는 방법에는 크게 컴파일, 인터프리트가 있다.

컴파일

컴파일(compile)은 코드를 컴파일러(compiler)라는 것을 사용해 기계어로 번역한 다음 번역된 파일을 생성해 컴퓨터에서 실행시키는 방법이다.

여기서 컴파일러는 프로그래머에 의해 만들어진 소프트웨어이다. 

컴파일의 장점은 한번 작성된 코드가 번역되어 실행 파일이 생성되면 이후로는 다시 번역할 필요 없이 번역된 실행파일을 실행시키면 되기 때문에 시간상의 효율성이 뛰어나다.

단점으로는 특정 시스템에서 번역된 실행 파일은 다른 시스템에서는 실행되지 않는다. 예를 들어 윈도우에서 번역된 파일은 맥에서는 실행되지 않기 때문에 각각 시스템에 맞는 컴파일러를 별도로 만들어 줘야 한다. (윈도우용과 맥용 프로그램이 따로 있는 이유가 여기에 있다!)

 

 

인터프리트

인터프리트(interpret)는 인터프리터(interpreter)라는 것을 사용해 코드를 직접 한 줄씩 번역한 다음 바로 실행시키는 방법이다. 한 줄씩 번역하여 실행시키기 때문에 매번 버그가 발생할 때마다 전체를 컴파일하지 않아도 돼서 디버깅에 편리하다.

또한 인터프리터만 있으면 컴파일 방법처럼 시스템마다 별도의 컴파일러가 필요한 방식이 아니라서 이식성이 뛰어나다.

주로 스크립트 언어들이 인터프리트 방법을 사용한다.

하지만 한 줄씩 번역하고 실행시키다 보니 전체를 기계어로 번역해서 실행시키는 컴파일 방법보다는 상대적으로 시간 효율성이 떨어진다.

최근에는 컴파일과 인터프리트 방법을 모두 사용하는 하이브리드 방식을 사용하고 , 하드웨어 성능이 높아져서 예전처럼 컴파일 언어와 인터프리터 언어의 성능 차이를 사람이 체감할 정도로 크지 않다.

하이브리드 방식은 사람이 작성한 코드를 컴파일러를 사용해 중간 코드(바이트 코드)로 변환하고 이 중간 코드를 가상 머신을 통해 한 줄씩 기계어로 번역하여 즉시 실행시키는 방식이다.

 

 

 

운영체제

운영체제(OS, Operating System)는 사용자가 컴퓨터를 편리하게 사용할 수 있도록 하드웨어 자원을 관리해주는 소프트웨어이다. 초기에는 컴퓨터 제작 회사별로 각자의 운영체제를 만들어 제공하였지만, 퍼스널 컴퓨터(PC)가 등장하고 나서부터는 일관된 형태의 운영체제가 사용되고 있다.

운영체제의 종류

DOS(Disk Operating System)

일명 도스로 불리며 퍼스널 컴퓨터가 처음 개발되었을 때 사용했던 운영체제이다. DOS는 명령어를 직접 입력하여 운영체제를 사용하는 CUI(Command-line User Interface) 형태의 운영체제이다. 맥에서 터미널이나 윈도우에서 콘솔 창이 이에 해당한다.

 

Windows 계열 운영체제

우리가 모두 그 Windows 다. Windows는 마우스로 편리하게 사용할 수 있는 GUI(Graphical User Interface) 방식의 운영체제로 1985년 마이크로소프트 사는 Windows 1.0 운영체제를 처음 발표하였다.

이후 Windows 1.0 ~ 3.0, Windows 95, Windows NT(New Technology), Windows 2000, Windows XP, Windows Vista, Windows 7 ~ 10 등이 계속해서 개발되었다.

 

Mac 운영체제

1984년 미국의 애플에서 매킨토시 계열의 퍼스널 컴퓨터나 워크스테이션에서 사용할 수 있는 Mac 운영체제를 개발하였다. Mac 운영체제는 마우스를 사용하는 최초의 GUI 형태의 운영체제이다.

 

유닉스(Unix) 계열 운영체제

1969년 미국의 AT&T사의 벨 연구소에서 개발된 운영체제로 주로 중대형 컴퓨터의 운영체제로 사용되었다. 1974년 데니스 매 캘리 스테어 리치(이름도 어렵다...)가 유닉스를 C 언어로 다시 개발하였고, 서로 다른 기종의 컴퓨터에도 유닉스가 쉽게 이식되어 사용될 수 있게 되었다. 그 이후 유닉스는 발전을 거듭하여 상용 운영체제인 솔라리스와 FreeBSD 유닉스를 탄생시켰다.

 

리눅스(Linux) 운영체제

1991년 핀란드 헬싱키 대학교의 학생인 리누스 토발즈에 의해 만들어진 운영체제로 유닉스를 PC에서 사용할 수 있게 만든 운영체제이다.

리눅스는 누구나 변환하여 사용할 수 있는 오픈소스이며, 개인용 컴퓨터 운영체제 또는 서버용 운영체제로도 많이 사용된다.

리눅스는 처음부터 소스코드를 공개하여 많은 사용자들로부터 유틸리티 소프트웨어가 만들어졌고, 배포판으로는 레드햇(Red Hat), 데비안(Debian) 등이 제공되고 있다.

 

스마트폰 운영체제

스마트폰에서 사용되는 운영체제로는 구글의 안드로이드, 애플의 iOS 등이 대표적이고 그 외 심비안, 블랙베리, 윈도우폰 7, 삼성의 바다 등이 있다.

 

 

 

데이터의 표현

이진수의 표현

컴퓨터는 0과 1로 구성된 이진수를 바탕으로 모든 데이터를 표현한다.

하나의 0이나 1을 비트(bit)라고 한다. 이진수를 사용하여 상태를 표현하면 두 가지 상태만 나타낼 수 있으므로 여러 개의 비트를 모아 하나의 상태를 표현한다.

컴퓨터에 저장할 수 있는 정보의 규모를 나타내는 단위 

 

 

문자의 표현

컴퓨터에서 사용하는 문자에는 영문자, 한글, 숫자, 특수 기호 문자 등이 있다.

초기의 컴퓨터에서는 컴퓨터마다 서로 다른 문자 코드 체계를 사용하여 프로그램의 호환성이 문제가 되었다. 이러한 호환성을 해결하기 위해 표준화된 코드체계가 필요했고, 그렇게 만들어진 대표적인 코드 체계로 아스키(ASCII) 코드와 유니코드(Unicode)가 있다.

아스키코드(ASCII, Amercian Standard Code for Information Interchange)

아스키코드는 영문 알파뱃을 사용하는 대표적인 표준 코드체계로 1967년에 표준으로 제정되었다.

아스키 코드는 7비트를 사용하여 표현하는 코드 체계로 33개의 제어 문자들과 공백을 포함하는 95개의 출력 가능한 문자로 구성되어 있다.

출력 가능한 문자들은 52개의 영문 알파벳 대소문자와 10개의 숫자, 32개의 특수 문자, 하나의 공백 문자로 이루어져 있다.

아스키코드표 보기

 

유니코드(Unicode)

7비트로 구성된 아스키코드는 표현할 수 있는 개수가 정해져 있기 때문에 세계의 다양한 문자들을 표현할 수 없었다.

그래서 1991년 유니코드가 개발이 시작되었고, 전 세계 모든 문자를 컴퓨터에서 일관되게 표현하고 다룰 수 있도록 애플, HP, IBM, Sun, MS, 오라클 등과 같은 업체들이 모여 표준으로 제정하였다.

유니코드는 사용 중인 운영체제, 프로그램 언어와 상관없이 문자마다 고유한 값을 제공하는 새로운 개념의 코드체계이다. 모든 문자들이 16비트로 표현하므로 최대 65,536개의 문자들을 표현할 수 있다.

 

 

숫자의 표현

프로그램에서 숫자 데이터는 연산의 대상이 되는 데이터들을 의미한다.

컴퓨터에서는 정수와 실수의 표현이 가능하다.

정수의 표현

대부분의 언어에서 정수를 나타내기 위해서 32비트(4바이트) 크기의 공간을 사용하고, 정수에서는 양수와 음수를 표현할 수 있어야 하기 때문에 32비트 중에서 최상위 비트를 부호 비트로 사용한다. 부호 비트가 0이면 양수, 1이면 음수를 타나 낸다.

첫 번째 비트가 부호를 나타내고 있으므로, 실제 정수를 나타낼 수 있는 비트수는 31비트로 표현해야 한다.

그래서 정수의 범위는 -2의 31승 (-2,147,483,648) ~ 2의 31승 (2,147,483,647)까지이다. 

정확한 값이 중요하기보단 대략 정수 10자리 정도까지 표현이 가능하다고 알아두면 되겠다.

참고로 음수는 2의 보수법으로 만들어진다. 

 

실수의 표현

컴퓨터는 실수를 표현하기 위해 부동 소수점(floating-point) 표기법을 사용한다. 부동 소수점 표현 방식은 소수점의 위치를 고정시켜 표현하는 방식이다.

컴퓨터는 실수를 저장하기 위해 부호 비트(1비트), 지수 비트(실제 소수점의 위치를 지수승으로 표현한 것), 가수 비트(실수의 유효 자릿수들을 부호화된 고정 소수점으로 표현한 것) 형식을 사용한다.

 

 

 

 

 

* 해당 포스팅은 처음 시작하는 프로그래밍을 참고하였습니다.

 

반응형

'IT 정보 로그캣 > CS' 카테고리의 다른 글

[Mac] Git 설치하기  (0) 2021.01.14
Git 이란  (1) 2021.01.12
정규 표현식  (0) 2020.02.03
[네트워크] 네트워크 기초 지식 정리  (0) 2019.09.03
[네트워크] HTTP 쿠키와 세션이란 ?  (2) 2019.06.16
반응형

 코딩을 하다보면 정규표현식이 필요할 때가 많다.

표현하고 싶은 문자열의 패턴을 간단한 표현으로 나타낼 수 있기 때문이다.

정규 표현식을 사용하지 않으면 코드가 엄청 길어지거나 표현하기 까다로운 경우가 많다.

예를들어 이메일이나 비밀번호는 특정한 입력 조건이 필요하다.

이 때 특수 문자가 반드시 들어가야 한다든지 특정 특수 문자는 입력이 불가능 하다든지와 같이 유효성 검사를 할 때 정규 표현식이 요긴하게 사용된다.

또한 텍스트에서 특정 정보나 패턴을 찾을 때 혹은 단어나 데이터 등을 변환할 때에도 정규 표현식을 사용할 수 있다.

간혹 정규 표현식을 사용하면 알고리즘 문제 등도 쉽게 해결되는 경우도 있다.

정규 표현식도 결국 개발자(정규표현식은 개발자 이외에도 자료를 다루는 사람 등도 해당된다.)의 생산성이나 유지보수에 있어서 좋기 때문에 사용한다고 보면 된다 :)

 

 

 

 

정규 표현식(Regular expression) 이란

 정규 표현식은 정규식, Regex 으로도 많이 부르는데 특정한 규칙을 가진 문자열의 집합을 표현하는 데 사용하는 형식 언어이다.

한글로 표현하면 뜻이 더 어렵게 느껴지는데 영어 그대로 보자면 규칙적인 것, 일종의 패턴을 표현하는 언어라고 보면 된다.

정규 표현식은 대부분의 프로그래밍 언어나 텍스트 편집기(Intellj, visual studio code ...), OS(Unix/Linux, Mac, Windows) 에서 사용할 수 있다.

 

 

 

정규 표현식의 역사

 정규 표현식은 1956년 스티븐 클레이니가 정규 집합(regular set)이라는 자신의 수학적 개념을 이용하여 정규 언어를 기술한 것을 기원으로 보고 있다. 여러 형태의 정규 표현식이 유닉스 프로그램에 사용되었고, 이후에 정규 표현식이 POSIX에 표준으로 인정 되었다.

POSIX의 정규 표현식도 다시 Basic 과 Extended 로 나뉘어 진다.

 

POSIX(Portable Operating System Interface X, x는 유닉스 호환 운영체제에 보통 x가 붙는 것에서 유래) 란

POSIX는 이식 가능 운영체제 인터페이스라는 뜻으로 서로 다른 UNIX OS의 공통 API를 정리하여 이식성 높은 유닉스 응용 프로그램을 개발하기 위한 목적으로 IEEE가 책정한 애플리케이션 인터페이스 규격이다. 즉, UNIX OS 간에 호환이 가능하도록 기준을 마련한 것으로 이해하면 된다. 

 

1980년대에 POSIX의 정규 표현식을 확장한 Perl의 정규 표현식이 등장했으며, 이 또한 PCRE (Perl Compatible Regular Expressions)로 정리되며 많은 프로그래밍 언어에서 사용된다. 

정규 표현식은 하나의 갈래로 이어져 확장되는게 아니라 기본적인 체계는 비슷하면서도 사소하게 다른 형태로 나뉘어져 있다.

그래서 정규 표현식은 프로그래밍 언어마다 문법이 조금씩 다르다. 

하지만 또 그렇게 큰 차이는 없어서 언어 별로 정규 표현식을 사용하는데 어려움은 없지만 다량의 텍스트를 다룰 때는 실수를 할 수 있는 확률이 높아 주의할 필요가 있다. 때문에 자신이 사용하는 언어의 정규 표현식을 확인은 하고 사용하는게 좋다.

 

 

 

정규 표현식 문법

 

패턴 구분자

 정규 표현식의 패턴이 달라질 경우 패턴을 구분하는 문자인데 보통은 슬래쉬(/)로 정규 표현식을 감싸준다.

"보통은" 이라고 말한 이유는 꼭 슬래쉬(/)가 아니어도 되기 때문이다.

예를들어 아래 처럼 해쉬(#) 나 (%) 등 특수문자 중에 공백이 아닌 문자나 역슬래쉬(\)를 제외하고는 아무거나 사용이 가능하다. 

  • /^[0-9]*$/

  • #^[0-9]*s#

  • %^[0-9]*s%

 

 

 

메타 문자

 정규 표현식에서 일정한 의미를 가지고 사용되는 특수문자를 메타 문자라고 한다.

 

  • ^ : 문자열의 시작

  • $ : 문자열의 종료

  • . : 임의의 한 문자

  • | : or 을 의미

  • [] : 문자 클래스. 문자 클래스 안에서 ^ 는 not 을 의미하고 - 는 범위를 의미함

  • ? : ?의 앞 문자가 없거나 하나 있음

  • + : +의 앞 문자가 하나 이상 있음

  • * : *의 앞 문자가 0개 이상 있음

  • {n} : {n}의 앞 문자가 정확히 n개 있음

  • {n,} : {n}의 앞 문자가 n 번 이상 있음

  • {n,m} : 앞 문자가 n개 이상 m개 이하로 있음

  • () : 연산자의 범위와 우선권을 정의할 수 있음

  • \s : 공백 문자

  • \b : 문자와 공백 사이를 의미

  • \d : 숫자 [0-9]와 동일

  • \t : 탭문자

  • \w : 밑줄(_)을 포함한 영숫자 문자로 [A-Za-z0-9_]와 동일 

* 문자 이스케이프는 대문자로 적으면 반대를 의미한다.

 

 

 

패턴 변경자

 패턴 구분자가 끝나면 그 뒤에 쓰는 것으로, 패턴에 일괄적으로 변경을 가할 때 사용한다.

 

  • g: global을 의미하며 문자열 내의 모든 패턴을 찾음 (^ 를 문서의 처음에 $ 를 문서의 끝에 매치되게 변경)

  • i : ignore case를 의미하며 대소문자를 구별하지 않음

  • m : Multi line을 의미하며 문자열에 줄바꿈이 있더라도 패턴을 찾음

  • s : 문자열에 개행 문자(\n)도 포함하여 패턴을 찾음

  • x : 공백 문자를 무시함

 

 

 

자주 사용되는 정규 표현식

  • 숫자 : ^[0-9]*$

  • 영문자: ^[a-zA-Z]*$ 

  • 유니코드 한글: ^[가-힣]*$

 

  

 

 언급했듯이 프로그래밍 언어 마다 조금씩 지원하는 정규 표현식 문법이 다르기 때문에 이정도의 기본 정도만 익혀두고 자기가 사용하는 언어의 정규 표현식을 찾아 따로 확인을 해야한다.

어차피 대부분 정규 표현식을 자주 까먹기 때문에 보통은 정규 표현식을 작성할 때 마다 다시 확인하는 경우가 많다. (나만 그런가?)

하지만 정규 표현식을 잘 익혀두면 유용하게 사용하는 경우가 많아서 한 번쯤은 공부하고 정리하는게 필요한 부분이다.

 

 

 

 

 

반응형
반응형

네트워크에 대한 전반적인 기초 지식 정리.

 

네트워크 구성

 

 

 

네트워크 (네트워크 기술)


 네트워크 기술이란 서버와 클라이언트의 정보가 오고 가는 다리 역할을 하는 기술의 총칭을 의미한다.

네트워크라는 말은 연결되어 있다라는 뜻으로 컴퓨터 네트워크는 데이터를 케이블에 실어 나르는 것을 의미한다.

(무선 LAN은 전파로 데이터를 실어 나른다.)

 

 

 

LAN (Local Area Network)


 LAN 이란 기업이나 조직 등 비교적 좁은 범위 안에 존재하는 컴퓨터 네트워크를 의미한다.

LAN은 LAN 케이블을 이용하여 데이터를 전송하는 유선 LAN과 전파를 이용하여 데이터를 전송하는 무선 LAN으로 구분한다.

 

LAN 케이블 이란
 LAN 케이블은 LAN을 연결 하기 위한 케이블

 

LAN 스위치 란
LAN 스위치는 LAN을 구성하기 위한 네트워크 기기

 

 

 

네트워크 작동 원리


 네트워크는 OSI 참조 모델을 바탕으로 작동한다. OSI 참조 모델은 국제표준화기구(ISO)가 컴퓨터 통신 기능을 계층 구조로 나눠서 정리한 모델로 일종의 통신 규칙 모음이라 생각하면 된다.

보통 OSI 7계층이라고 하는데 하위 계층(물리 계층) 부터 상위 계층(전송 계층)으로 구성된다. 

 

 

OSI 7계층

  • 제 1계층(물리 계층) : 네트워크 케이블의 재질이나 커넥터의 형식, 핀의 나열 방법 등 물리적인 요소를 모두 규정한다.

  • 제 2계층(데이터 링크 계층) : 직접 연결된 기기 사이에 논리적인 전송로(데이터 링크)를 확립하는 방법을 규정한다.

  • 제 3계층(네트워크 계층) : 동일 또는 다른 네트워크의 기기와 연결하기 위한 주소와 경로의 선택 방법을 규정한다.

  • 제 4계층(전송 계층) : 데이터를 통신할 상대에게 확실하게 전달하는 방법을 규정한다.

  • 제 5계층(세션 계층) : 데이터를 흘려보내는 논리적인 통신로(커넥션)의 확립과 연결 끊기에 대해 규정한다.

  • 제 6계층(표현 계층) : 애플리케이션 데이터를 통신에 적합한 형태로 변환하는 방법을 규정한다.

  • 제 7계층(응용 계층) : 애플리케이션 별로 서비스를 제공하는 방법을 규정한다.

 

OSI 참조 모델

프로토콜

응용 계층 (제 7계층)

애플리케이션 프로토콜 (HTTP 등)

표현 계층 (제 6계층)

애플리케이션 프로토콜 (HTTP 등)

세션 계층 (제 5계층)

애플리케이션 프로토콜 (HTTP 등)

전송 계층 (제 4 계층)

TCP / UDP

네트워크 계층 (제 3 계층)

IP / ICMP / ARP

데이터링크 계층 (제 2계층)

이더넷

물리 계층 (제 1계층)

이더넷

<OSI 참조 모델과 프로토콜 >

 

 

 

프로토콜


 프로토콜이란 네트워크 통신을 위한 통신규칙을 의미한다.

프로토콜의 역할은 데이터의 캡슐화와 캡슐 해제화를 하는 것이다. 네트워크 통신에서 OSI 참조 모델의 계층을 넘어설 때마다 데이터를 캡슐에 넣거나 꺼낸다.

 

프로토콜 캡슐화 / 캡슐 해제화

 

 

 

이더넷


 이더넷은 OSI 제 1계층과 제 2 계층의 기술 규격이다. 유선 네트워크의 경우 거의 대부분이 이더넷을 사용한다.

이더넷은 네트워크 계층으로부터 받은 데이터(패킷)에 프레임의 처음을 나타내는 프리앰블(preamble)과 목적지(수신자)와 출발지(송신자)를 나타내는 헤더, 비트 오류체크에 사용하는 FCS(Frame Check Sequence)를 추가하여 프레임을 생성한다. 이더넷은 MAC 주소라는 48비트로 된 식별자를 사용하여 컴퓨터를 식별한다.

 

프레임 구조

 

 

 

MAC 주소


 MAC 주소란 데이터링크 계층(제 2계층)에서 통신을 위해 사용되는 48비트로 된 식별자이다.

MAC 주소는 8비트 마다 하이픈( - ) 이나 콜론 ( : ) 으로 구분하여 16진수로 표기한다.

상위 24비트는 전기 및 전자관계 기술자 단체인 미국전기전자학회(IEEE)가 기기의 제조업체 별로 할당한 제조업체 코드(OUI, Organizationally Unique Identifier) 라고 하는데 해당 코드로 제조업체를 알 수 있다.

하위 24비트는 제조업체가 기기 별로 고유한 값을 할당한 코드이다.

NIC 에 할당되어 있는 MAC 주소는 전 세계에 하나밖에 없는 고유한 값이다.

예를들어 내 컴퓨터의 MAC 주소는 98:24:01:6E:09:5B 또는 98-24-01-6E-09-5B 로 표현 될 수 있다. (.. 물론 아무렇게나 적은 가짜 MAC 주소다 )

여기서 앞부분 98-24-01 상위 24비트는 제조업체 코드이고 뒷부분 6E-09-5B 하위 24비트는 제조업체 내부 코드이다.

 

NIC(Network Interface Controller)란
 NIC은 컴퓨터를 네트워크에 연결하여 통신하기 위해 사용하는 하드웨어 장치이다. 
흔히 우리가 네트워크 카드, 랜 카드로 부르는 것이 NIC 이다.

 

 

 

스위칭


 네트워크 스위치가 데이터 패킷 내 포함된 주소 정보에 따라 해당 입력 패킷을 해당 출력 포트에 빠르게 접속 시키는 기능을 스위칭이라고 한다. 쉽게 설명하자면 네트워크 스위치가 수행하는 프레임 전송을 스위칭이라고 한다.

 

네트워크 스위치 란
 네트워크 스위치는 L2 (제 2계층, 데이터 링크 계층)에서 사용하는 네트워크 기기로 LAN 케이블을 통해 컴퓨터를 연결한다.
(.. 레이어(Layer)는 계층을 의미하고 해당 계층의 장비는 해당 계층에서 사용하는 프로토콜을 주고 받는다고 이해하면 쉽다)
네트워크 스위치는 프레임이 들어온 LAN 포트 번호와 그 프레임의 출발지 MAC 주소를 테이블로 만들어 일정 기간 동안 기억하며 불필요한 프레임 전송을 막고 이더넷 네트워크 통신의 효율을 향상 시키는 역할을 한다.
이때 LAN 포트 번호와 출발지 MAC 주소의 테이블을 MAC 주소 테이블이라고 한다.

 

MAC 주소

포트

A

1

B

2

C

3

< MAC 주소 테이블 >

 

 

 

IP (Internet Protocol)


IP는 전송 계층 (제 4계층)으로부터 받은 데이터(세그먼트)에 IP 헤더를 붙여 패킷으로 만드는 역할을 한다. IP헤더에는 여러 필드 값(버전,헤더길이,프로토콜 등), 출발지 IP주소, 도착지 IP주소가 들어간다.

 

패킷 구조

 

IP는 IP 주소라는 32비트로 된 식별번호를 사용하여 컴퓨터를 식별한다.

IP주소는 8비트 마다 점( . )으로 구분하고 10진수로 표기한다. IP주소는 네트워크 분리 및 구분을 위해 서브넷 마스크라는 32비트로 된 값과 세트로 사용한다. 또한 IP주소는 서브넷 마스크로 분할된 네트워크부와 호스트부로 구성되어 있다. 네트워크부는 네트워크 자체를 나타내고, 호스트는 해당 네트워크에 연결되어 있는 단말을 나타낸다. 서브넷 마스크는 연속된 1의 값이나 연속된 0의 값만 가질 수 있는데 이때 1의 값을 가지는 부분은 네트워크 부이고, 0의 값을 가지는 부분이 호스트부이다.

예를들어 IP 주소가 192.168.1.1 이고 서브넷 마스크가 255.255.0.0 이라고하자.

서브넷 마스크를 2진수로 나타내면 11111111.11111111.00000000.00000000 이다. 여기서 서브넷 마스크가 1이 되는 부분이 네트워크부 이기 때문에 192.168. 이 네트워크 부이고 1.1 부분은 서브넷 마스크가 0인 부분이기 때문에 호스트부이다. 서브넷 마스크의 1의 개수로 IP 주소를 간편하게 나타내면 192.168.1.1/16 이 된다.

만약 서브넷 마스크가 255.255.255.0 이라면 네트워크부는 192.168.1. 까지가 되고 나머지 1이 호스트부가 된다.

 

서브넷 마스크를 사용하는 이유
 서브넷 마스크를 사용하는 이유는 IP 주소 자체가 개수가 제한되어 있고, 네트워크를 효율적으로 분배하기 위해서이다.
서브넷 마스크 원리는 서브네팅을 찾아보면 된다. ( ..서브넷 마스크 계산법을 찾아봐야한다)

 

 

 

라우팅

 라우팅이란 라우터가 네트워크에서 패킷을 목적지까지 최적의 경로를 선택하는 과정이다. 

 

라우터 란
 라우터는 각 독립된 네트워크들을 연결할 때 L3(제 3계층, 네트워크 계층)에서 사용하는 네트워크 기기이다. L3 장비이기 때문에 패깃을 전송한다.

 

 라우터는 라우팅 테이블을 이용하여 패킷을 전송한다. 라우팅 테이블은 목적지 네트워크와 목적지 네트워크로 가기 위해 보내야할 곳의 IP주소(넥스트 홉,  next hop)로 구성되어 있다. 넥스트 홉이란 패킷이 목적지 네트워크까지 가기위해 도달하는 다음 라우터를 의미한다.

패킷이 목적지까지 가는데 거치는 라우터 개수를 홉 수(hop count) 라고 한다.

라우터는 패킷을 받으면 해당 패킷의 목적지 IP 주소와 라우팅 테이블의 목적지 네트워크를 대조하여 해당 IP주소가 있으면 패킷을 전송하고 없으면 패킷을 폐기한다.

 

라우팅에는 정적 라우팅과 동적 라우팅이 존재한다. 

 

정적 라우팅

  • 정적 라우팅이란 수동으로 라우팅 테이블을 만드는 방법

  • 목적지 네트워크와 넥스트 홉을 하나하나 설정

  • 정적 라우팅은 네트워크를 구성하는 모든 라우터에 대해 라우팅 설정이 필요

  • 설정을 알기 쉽고 관리하기 쉽기 때문에 소규모 네트워크 환경에서 주로 사용

 

 

동적 라우팅

  • 동적 라우팅이란 인접하는 라우터들이 라우팅 정보를 서로 교환하여 라우팅 테이블을 자동으로 만드는 방법

  • 라우팅 정보를 교환하기 위한 프로토콜을 라우팅 프로토콜이라고 함

  • 네트워크 환경의 변화대응과 장애 내구성 향상이 가능하기 때문에 중간부터 대규모 네트워크 환경에서 주로 사용

 

 

 

ARP (Address Resolution Protocol)


 ARP는 MAC 주소와 IP 주소를 협조하면서 이용할 수 있도록 물리와 논리의 다리 역할을 한다.

즉, 물리적인 주소인 MAC 주소와 논리적인 주소인 IP 주소를 대응 시키는 역할을 하는 것이다.

네트워크 통신을 하기 위해서는 제 3계층으로부터 받은 패킷을 프레임으로 만들어 케이블로 흘려보내야 하는데 이때 출발지 MAC 주소는 자기 자신의 NIC에 쓰여 있는 MAC 주소라서 알 수 있지만 목적지 MAC 주소는 알 수가 없다. 이때 ARP를 이용하여 IP 주소로부터 MAC 주소를 구할 수 있다.

과정은 ARP request-> ARP reply -> ARP 테이블 등록 순이다.

동일 네트워크 상에서는 수집된 ARP 테이블을 참고하여 프레임을 만든다. 다른 네트워크 간 통신은 기본 게이트웨이의 MAC 주소를 ARP에서 조회하여 목적지 MAC 주소로 등록한다.

기본게이트웨이는 자신 이외의 네트워크로 갈 때 사용하는 출구가 되는 IP 주소이다. 보통 방화벽이나 라우터의 IP 주소가 기본 게이트웨이가 되는 경우가 많다.

IP 주소는 목적지까지 바뀌지 않지만 MAC 주소는 NIC을 경유할 때 마다 바뀐다.

 

 

 

TCP/UDP


TCP(Transmission Control Protocol)

 TCP는 전송 제어 프로토콜로 IP와 함께 TCP/IP로 불리며 제 4계층(전송 계층)에서 사용되는 프로토콜이다.

TCP는 데이터를 송신할 때 마다 확인 응답을 주고 받는 절차가 있어서 통신의 신뢰성을 높인다. 

웹이나 메일, 파일 공유 등과 같이 데이터를 누락시키고 싶지 않은 서비스에 주로 사용된다.

 

 

UDP(User Datagram Protocol)

 UDP는 TCP와 함께 데이터 그램으로 알려진 단문 메시지를 교환하기 위해 사용하는 프로토콜이다.

테이터만 보내고 확인 응답과 같은 절차를 생략할 수 있으므로 통신의 신속성을 높인다.

주로 DNS, VoIP 등에 사용 된다.

 

 

TCP 와 UDP 

TCP 와 UDP 모두 포트 번호로 서비스를 식별한다. 

두 프로토콜을 구분하는 주요한 차이는 통신의 신뢰성이냐 신속성이냐이다. 

애플리케이션 데이터에 TCP 또는 UDP 헤더를 추가하여 TCP 세그먼트나 UDP 세그먼트가 만들어진다.

 

 

 

포트 번호


포트 번호는 컴퓨터 안에서 작동하는 애플리케이션을 식별하기 위해 사용하는 숫자이다. 포트 번호는 0~65535(16비트 분)까지 숫자로 범위에 따라 용도가 정해져 있다. 포트 번호는 세그먼트를 만들 때 헤더에 출발지 포트와 목적지 포트로 들어간다.

  • 0~1023 : 잘 알려진 포트(well-known port) 라고 해서 웹 서버나 메일 서버 등 일반적인 서버 소프트웨어가 서비스 요청을 대기할 때 사용된다.

  • 1024~49151 : 등록된 포트(registered port)라고 해서 제조업체의 독자적인 서버 소프트웨어가 클라이언트 서비스 요청을 대기할 때 사용된다.

  • 49152~65535 : 동적 포트(dynamic port)로 서버가 클라이언트를 식별하기 위해 사용된다. (클라이언트에서 서버에 대해 요청을 보낼 때 출발지 포트로 랜덤으로 지정해서 보낸다.)

 

 

 

NAT 와 NAPT


NAT 와 NAPT 는 기업이나 가정의 LAN 에서 사용하는 프라이빗 IP 주소를 인터넷에서 사용하는 글로벌 IP 주소로 변환하는 기술이다.

 

 

NAT(Network Address Translation)

NAT 는 프라이빗 IP 주소와 글로벌 IP 주소를 일대일로 연결하여 변환한다. 하나의 프라이빗 IP 주소와 하나의 글로벌 IP 주소를 연결하는 것이다. 주로 서버를 인터넷에 공개할 때 사용한다.

LAN 에서 인터넷으로 연결할 때는 출발지 IP 주소를 변환한다. 반대로 인터넷에서 LAN 으로 연결할 때는 목적지 IP 주소를 변환한다.

 

 

NAPT(Network Address Port Translation)

NAPT 는 프라이빗 IP 주소와 글로벌 IP 주소를 n 대 1로 연결하여 반환한다. NAPT 는 LAN 에서 인터넷에 엑세스 할 때 출발지 IP 주소 뿐만 아니라 출발지 포트 번호도 같이 반환함으로써 n 대 1 변환을 한다. 

(하나의 IP에 포트가 여러개이기 때문에 N 대 1이 가능한 것이다.)

 

 

 

 

 

 

반응형
반응형

 HTTP 에는 쿠키라는 개념이 존재하는데, 이름부터가 친숙하고 귀엽다. 

쿠키라는 이름이 붙여졌을까에는 여러가지 이야기들이 있는데, 내가 처음 공부할 때 들었던 이야기는 헨젤과 그레텔 동화에서 쿠키라는 이름이 유래했다는 것이다. 동화에서 헨젤과 그레텔이 자신들이 지나온 길을 표시하기 위해 쿠키조각을 바닥에 떨어뜨린 것과 마찬가지로 서버에 요청한 사람이 누구인지 표시하기 위해 클라이언트에 쿠키를 남긴다해서 쿠키라 부른다는 것이다. ( ..그럴싸 하다.)

또 다른 이야기로는 쿠키 안에 운세 같은 메세지가 담겨있는 포춘쿠키와 유사하다고 해서 쿠키가 되었다라는 이야기도 있다.

하지만 사실은 유닉스 운영체제에서 두 프로그램 사이에 전송되는 작은 데이터 패킷을 매직 쿠키라 불렀는데 여기서 HTTP 쿠키가 유래되었다. HTTP 쿠키를 만든 루 몬텔루 라는 웹 브라우저 개발자가 사용자들의 방문 기록을 남기기 위해 매직 쿠키에서 개념을 차용해서 사용한 것이다.

(.. 출처는 구글질문 에서 찾았는데 루 몬텔루에게 직접 확인된 사실이라 한다. 물론 위키백과에도 나와있다. 위에 언급된 이야기들은 아마 매직쿠키의 유래가 아닌가 싶다. )

 

 

 

HTTP 쿠키( Cookie) 란


 HTTP 쿠키는 웹 쿠키, 브라우저 쿠키로도 불리는데 서버가 사용자의 웹 브라우저에 전송하는 작은 데이터 조각을 의미한다.

위에서 언급했듯이 유닉스의 매직쿠키에서 이름과 개념이 유래하였고, 루 몬텔루라는 웹 브라우저 개발자가 웹 사이트에 접속한 클라이언트를 확인하기 위해 만들었다. HTTP 통신은 stateless 하기 때문에 클라이언트를 확인하기 위해서는 쿠키라는 개념이 따로 필요했기 때문이다.

쿠키는 주로 세션 관리( 서버에서 관리하는 로그인 등의 정보를 의미한다. ), 개인 설정유지, 사용자 트래킹( 사용자의 행동을 기록하고 분석하는 것 ) 용도로 사용된다.

HTTP의 stateless 란
statsless 라는 것은 번역하자면 상태가 없다는 뜻이다. HTTP에서 stateless 하다는건 서버 입장에서 클라이언트의 상태가 없다는 의미로 동일한 클라이언트의 요청이라도 매번 각 요청은 독립적이라는 의미이다. 예를들어 놀이공원(서버)에서 손님이 입장(요청)했다가 퇴장(응답)했을 때 손님들을 한명 한명 다 기억할수가 없다. 그렇기 떄문에 놀이공원에서는 재입장하는 손님을 구분하기 위해 팔찌같은 입장권을 준다.
마찬가지로 서버에서도 이미 요청을 했었던 클라이언트인지 매번 확인하기 어렵기 때문에 입장권처럼 쿠키를 주는 것이다.

 

 

 

HTTP 쿠키의 특징

  • 쿠키는 한개에 4KB 까지 저장 가능하며, 최대 300개 까지 저장할 수 있는 텍스트 파일이다.

  • 쿠키는 클라이언트에 저장된다.

  • 쿠키에는 이름, 값, 만료날짜, 경로 정보가 들어있다.

  • 기본적으로 쿠키는 웹 브라우저가 종료되면 삭제된다. ( 만료날짜를 지정해 주면 만료일이 되야 삭제된다.)

  • 웹 브라우저에 해당 서버의 쿠키 정보가 있으면 HTTP 요청 (HTTP 헤더의 Cookie)에 무조건 담아 보낸다.

 

 

 

HTTP 쿠키 작동방식


 쿠키도 결국 HTTP 통신에서 이루어지는 것이기 때문에 HTTP 의 응답과 요청에 따라 작동한다.

요청을 받은 서버에서 쿠키를 클라이언트(웹 브라우저)로 보내고 클라이언트는 쿠키를 받으면 도메인 서버 이름으로 정렬된 쿠키 디렉토리에 쿠키(정보)를 저장한다. 이후 클라이언트가 동일한 서버로 HTTP 요청을 보내면 저장된 쿠키도 같이 전송되며, 만약 서버에서 쿠키에 업데이트된 내용이 있으면 응답할 때 다시 업데이트된 쿠키를 보내준다.

 

< 쿠키 작동순서 >

 

 

 

HTTP 세션(seesion) 이란


 세션이란 통신을 하기 위해 서로 연결된 순간부터 통신을 마칠 때 까지의 기간을 의미한다.

단순히 session 의 뜻을 찾아보아도 시간, 시즌 이라고 나온다.

HTTP 세션이란 클라이이언트가 웹서버에 연결된 순간부터 웹 브라우저를 닫아 서버와의 HTTP 통신을 끝낼 때 까지의 기간이다.

하지만 보통 세션이라고 말할 때에는 서버에 세션에 대한 정보(세션 상태, 클라이언트 상태, 세션 데이터 등)를 저장해 놓고 세션 쿠키( 고유한 세션 ID 값 )를 클라이언트에게 주어 서버가 클라이언트를 식별할 수 있도록 하는 방식자체를 의미하는 경우가 많다.

 

 

 

세션의 특징


  • 따로 용량의 제한이 없다. ( 서버의 능력에 따라 다를 수 있다. )

  • 서버에 세션 객체를 생성하며 각 클라이언트 마다 고유한 세션 ID 값을 부여한다.

  • 쿠키를 사용하여 세션 ID 값을 클라이언트에 보낸다.

  • 웹 브라우저가 종료되면 세션 쿠키는 삭제된다.

 

 

 

세션 작동방식


 세션의 작동방식을 보면 우선 클라이언트가 서버에 요청을 보내면 서버에서는 요청헤더( Cookie )를 확인하고 세션 ID가 있는지 확인한다. 

만약 요청에 세션 ID가 없다면 서버에서는 세션 ID를 생성한 뒤 응답을 보낼 때 쿠키에 세션 ID를 담아 보낸다. (서버에서는 이때 가장 먼저 세션 객체를 생성하여 정보를 저장한다.)

클라이언트는 응답에서 받은 세션 쿠키(세션 ID 값)를 저장해두고, 매번 해당 서버에 요청을 보낼 때마다 세션 쿠키를 함께 보내서 자신이 누구인지 인증한다. 세션 쿠키는 브라우저가 종료되면 삭제된다.

 

< 세션 동작 순서 >

 

 

 

쿠키와 세션의 관계


 흔히 쿠키와 세션을 비교할 때 쿠키는 클라이언트(웹 브라우저)에 정보를 저장하는 것이고, 세션은 서버에 정보를 저장하는 것이다 라고 비교한다. 맞는 말이지만 마치 서로 반대되는 개념처럼 오해할 수 있는데, 결국 세션은 쿠키를 이용하는 하나의 방식일 뿐이다. ( 쿠키와 세션은 방식의 차이일 뿐 반대 개념이 아니다. )

쿠키는 stateless 한 HTTP 통신에서 클라이언트에게 정보(표시)를 주어 해당 클라이언트를 식별하기 위해 만들어졌다.

클라이언트가 식별이 가능해야 서버는 특정 클라이언트와 계속해서 통신을 하고 있는지 확인이 가능하기 때문이다.

하지만 클라이언트에 저장된다는 쿠키의 특징은 보안에 있어서는 치명적인 단점이다.

예를들어 로그인을 위해 사용자가 입력한 아이디와 비밀번호를 쿠키에 담아 클라이언트에 저장한 뒤 서버에서는 쿠키로 해당 사용자가 로그인한 사용자인지 확인한다고 생각해보자. 그러면 누군가 마음만 먹으면 쿠키를 확인해 클라이언트에 저장된 아이디와 비밀번호를 볼 수 있다.

그래서 세션이라는 개념을 통해 중요한 정보는 서버에서 관리하고 클라이언트에게는 세션 쿠키( 세션 ID )를 주어 식별이 가능하도록 한 것이다. 

결론적으로 사전적 정의로 보면 세션( 통신을 시작하고 마칠 때 까지의 기간)을 유지하기 위해 쿠키를 사용하는 것인데, 용어 상으로는 세션이란 서버에 정보를 저장하고 세션 쿠키를 통해 클라이언트를 식별하는 방식을 통틀어 말하는 것으로 보면 되겠다.

 

 

 

쿠키와 세션 정리


 쿠키와 세션도 결국 목적( 클라이언트에서 관리하느냐, 서버에서 관리하느냐 )에 맞게 사용하면 되겠다.

(.. 클라이언트는 믿을 수 없다. 중요한 정보나 처리는 서버에서 다뤄야한다! 만 명심하자.)

예를들어 쿠키는 쇼핑몰의 장바구니, 개인 설정(팝업창 표시여부 등) 같은 것들에 많이 사용되고 세션은 로그인 유지 등에 많이 사용된다. 

 

 

 

 

반응형

'IT 정보 로그캣 > CS' 카테고리의 다른 글

정규 표현식  (0) 2020.02.03
[네트워크] 네트워크 기초 지식 정리  (0) 2019.09.03
[네트워크] get 과 post 의 차이  (2) 2019.06.03
[네트워크] http 란  (0) 2019.06.01
[알고리즘] 재귀함수  (0) 2019.04.13
반응형

GET 과 POST 는 HTTP 메서드로 클라이언트에서 서버로 무언가를 요청할 때 사용한다. 

 

2019/06/01 - [IT 정보 로그캣/CS] - [네트워크] http 란

 

[네트워크] http 란

기본적으로 네트워크 통신을 할 때 처음 접하는게 http 통신이다. 개발자가 아니더라도 http는 많이 듣는 용어일 정도로 우리가 많이 접하고 있고, 중요하다. 내가 사용하는 기술이 최소한 어떤 건지, 왜 사용하는..

noahlogs.tistory.com

과거에  5년차 이상 서버 개발자와 일한 경험이 있는데, 로그인 API를 요청했는데 GET 과 POST 둘 다 요청이 가능하도록 만들어 주는 것이었다... 암호화를 한것도 아니라서 POST도 완벽한 보안이 되는건 아니지만 정말 최소한의 보안 의식도 없는건가 아니면 구분을 못해서 그런건가 싶었다. 이렇듯 HTTP 통신을 제대로 사용하기 위해서도 둘의 차이를 아는 게 중요하다.

 

 

 

GET 이란?


 GET 은 클라이언트에서 서버로 어떠한 리소스로 부터 정보를 요청하기 위해 사용되는 메서드이다. 

예를들면 게시판의 게시물을 조회할 때 쓸 수 있다.

GET을 통한 요청은 URL 주소 끝에 파라미터로 포함되어 전송되며, 이 부분을 쿼리 스트링 (query string) 이라고 부른다.

방식은 URL 끝에 " ? " 를 붙이고 그다음 변수명1=값1&변수명2=값2... 형식으로 이어 붙이면 된다.

예를들어 다음과 같은 방식이다. 

www.example.com/show?name1=value1&name2=value2

서버에서는 name1 과 name2 라는 파라미터 명으로 각각 value1 과 value2 의 파라미터 값을 전달 받을 수 있다.

 

 

 

GET의 특징


  • GET 요청은 캐시가 가능하다. 

     : GET을 통해 서버에 리소스를 요청할 때 웹 캐시가 요청을 가로채 서버로부터 리소스를 다시 다운로드하는 대신 리소스의 복사본을 반환한다. HTTP 헤더에서 cache-control 헤더를 통해 캐시 옵션을 지정할 수 있다.

  • GET 요청은 브라우저 히스토리에 남는다.

  • GET 요청은 북마크 될 수 있다.

  • GET 요청은 길이 제한이 있다.

     : GET 요청의 길이 제한은 표준이 따로 있는건 아니고 브라우저마다 제한이 다르다고 한다. 

  • GET 요청은 중요한 정보를 다루면 안된다. ( 보안 )

     : GET 요청은 파라미터에 다 노출되어 버리기 때문에 최소한의 보안 의식이라 생각하자.

  • GET은 데이터를 요청할때만 사용 된다.

 

 

 

POST 란?


 POST는 클라이언트에서 서버로 리소스를 생성하거나 업데이트하기 위해 데이터를 보낼 때 사용 되는 메서드다. 예를들면 게시판에 게시글을 작성하는 작업 등을 할 때 사용할 된다.

POST는 전송할 데이터를 HTTP 메시지 body 부분에 담아서 서버로 보낸다. ( body 의 타입은 Content-Type 헤더에 따라 결정 된다.)

GET에서 URL 의 파라미터로 보냈던 name1=value1&name2=value2 가 body에 담겨 보내진다 생각하면 된다.

POST 로 데이터를 전송할 때 길이 제한이 따로 없어 용량이 큰 데이터를 보낼 때 사용하거나 GET처럼 데이터가 외부적으로 드러나는건 아니라서 보안이 필요한 부분에 많이 사용된다. 

( 하지만 데이터를 암호화하지 않으면 body의 데이터도 결국 볼 수 있는건 똑같다. )

POST를 통한 데이터 전송은 보통 HTML form 을 통해 서버로 전송된다. 

 

 

 

POST의 특징


  • POST 요청은 캐시되지 않는다.

  • POST 요청은 브라우저 히스토리에 남지 않는다.

  • POST 요청은 북마크 되지 않는다.

  • POST 요청은 데이터 길이에 제한이 없다.

 

 

 

GET 과 POST 의 차이점 


 GET과 POST의 특징만 보아도 차이가 나긴하지만 추가적으로 차이점을 정리해보면 다음과 같다.

 

  • 사용목적 : GET은 서버의 리소스에서 데이터를 요청할 때, POST는 서버의 리소스를 새로 생성하거나 업데이트할 때 사용한다.

    DB로 따지면 GET은 SELECT 에 가깝고, POST는 Create 에 가깝다고 보면 된다.

  • 요청에 body 유무 : GET 은 URL 파라미터에 요청하는 데이터를 담아 보내기 때문에 HTTP 메시지에 body가 없다. POST 는 body 에 데이터를 담아 보내기 때문에 당연히 HTTP 메시지에 body가 존재한다.

  • 멱등성 (idempotent) : GET 요청은 멱등이며, POST는 멱등이 아니다.

멱등이란?

멱등의 사전적 정의는 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질을 의미한다.

GET은 리소스를 조회한다는 점에서 여러 번 요청하더라도 응답이 똑같을 것 이다. 반대로 POST는 리소스를 새로 생성하거나 업데이트할 때 사용되기 때문에 멱등이 아니라고 볼 수 있다. (POST 요청이 발생하면 서버가 변경될 수 있다.)

 

 

 

GET과 POST는 이런 차이들이 있기 때문에 사용하려는 목적에 맞는 확인한 후에 사용해야한다.

GET과 POST 이외에도 PUT , DELETE 등을 적절히 사용하는게 좋은데 예를들어 봇의 경우에 사이트를 돌아다니면서 GET 요청을 날린다. 이럴 때 DELETE 등을 GET으로 처리하면 봇에 의해 서버에 있는 리소스들이 삭제 되는 상황이 일어 날수 있다! 항상 기술을 사용할 때 를 잊지말자.

 

 

 

 

 

 

반응형
반응형

 기본적으로 네트워크 통신을 할 때 처음 접하는게 http 통신이다. 

개발자가 아니더라도 http는 많이 듣는 용어일 정도로 우리가 많이 접하고 있고, 중요하다.

내가 사용하는 기술이 최소한 어떤 건지, 왜 사용하는지 정도는 알고 있어야 한다고 생각하기 때문에 이번 기회에 간략히 정리를 한다.

 

 

 

HTTP 란?


 HTTP 는 HyperText Transfer Protocol 의 줄임말로 www 상에서 사용하는 프로토콜이다.

1990년 대 팀 버너스리가 월드와이드웹을 만들어서 하이퍼텍스트 문서들을 주고 받기 위한 규약으로 만든 것이 HTTP 이다. 현재에는 문서들 뿐만 아니라 이미지, 비디오, 음성 등 거의 모든 형식의 데이터를 전송하는데 사용 되고있다.

HTTP는 서버와 클라이언트 사이에 요청과 응답을 주고 받는 프로토콜로 우리가 흔히 웹브라우저 주소창에 입력하는 웹 주소인 URL을 통해 요청과 응답이 이루어진다.

실제 전송은 TCP를 통해 이루어 지며 포트는 80번을 이용한다.

 

용어 정리

  • 하이퍼텍스트(HyperText) : 참조(하이퍼링크)를 통해 한 문서에서 다른 문서로 즉시 접근할 수 있는 텍스트를 의미한다. 하이퍼텍스트라는 용어는 1965년 테드 넬슨이라는 철학자가 만들었다. 

  • 월드와이드 웹(www, World Wide Web) : 인터넷에 연결된 컴퓨터를 통해 사람들이 정보를 공유할 수 있는 가상의 공간이다. 1990년대 팀 버너스리가 하이퍼텍스트들을 인터넷 상에서 웹주소인 URL(Uniform Document Idenfier) 을 통해 연결 시키려고 만든 것이다. 팀 버너스리는 www 를 모두 공개했고, 이후 웹이 퍼져나가면서 웹 브라우저도 개발 되었다. 

 

 

 

HTTP 버전


 HTTP는 초기에 버전 표기가 없었고, 이후 업데이트되면서 버전 표시가 필요하게 되어 1991년 HTTP/0.9 부터 시작하여 1996년 HTTP/1.0 을 거쳐  1999년  HTTP/1.1 까지 확장 되었다. HTTP/1.1 이후로는 버전 업 없이 계속 사용되고 있다. 

 하지만 오늘날 웹 환경은 과거에 비해 더 많은 리소스를 사용하고, 동적인 부분이도 많아지고, 보안이 중요해지는 등의  변화를 겪다 보니 HTTP/1.1에 한계를 많이 느끼게 된다. 그래서 2015년 구글이 SPDY 프로토콜을 기반으로 만든 HTTP/2 가 공식적으로 표준화 되어 나왔다.

아직까지 많은 사이트들에서  HTTP/1.1을 사용하지만 HTTP/2을 지원하는 사이트들도 늘어나고 있다.

 

버전 정리

  • HTTP/0.9 :  단순한 구성으로 이루어져 요청가능한 메서드는 GET 이 유일했고, HTTP 헤더가 존재하지 않아 HTML 파일만 전송이 가능했다. 

  • HTTP/1.0 : HTTP 헤더 개념이 도입되어, 브라우저가 요청에 대한 성공과 실패를 알 수 있게 되었다. 데이터에 대한 정보를 담고 있는 메타데이터 전송도 허용하고, Content-Type 의 추가는 HTML 외에 다른 문서들도 전송 가능하게 하였다.

  • HTTP/1.1 : HTTP의 표준 프로토콜이며 많은 부분들이 개선되었다. 개선된 부분 중에는 커넥션 제어에 관한 두가지 모델의 추가도 있다. 하나는 커넥션이 재사용될 수 있는 모델로 서버를 다루다 보면 보게되는 Keep-Alive 옵션이다. 또 다른 하나는 파이프라이닝을 추가하여 요청에 대한 응답이 완전히 전송되기 이전에 두번째 요청을 전송 가능하게 하여 네트워크 지연을 줄이는 모델이다.

단일 모델

 

커넥션 재사용 모델

 

파이프라이닝 모델

 

 

  • HTTP/2 : 구글이 만들었고, 네트워크 지연 시간을 줄이기 위한 성능에 목표를 둔 HTTP의 두 번째 버전. HTTP 헤터 데이터 압축이나 서버 푸시기술 추가 등 많은 부분들이 보완되었다.
    ( HTTP/2 공부를 따로 해야할 정도이다.. )
    하지만 중요한 점은 HTTP/2 가 HTTP 표준을 대체하는 것이 아니라 확장한다는 점이다.
    (구글이 직접 발표한 부분이다!)

 

 

 

HTTP 메시지 구조 


 HTTP  메시지는 ASCII 로 인코딩된 텍스트로 되어 있다. 

기본적인 메시지 구조는 다음과 같다.

시작 줄 (start-line)

HTTP 헤더 (HTTP headers)

공백 (empty line)

바디(body)

 

 HTTP 메시지는 기본적으로 클라이언트가 요청하고 서버가 응답하는 구조이기 때문에 메시지는 요청이냐 응답이냐에 따라 각 메시지의 구성 내용이 달라 진다.

구분

요청 (클라이언트 request)

응답 (서버 response)

시작줄
(start-line)

  1. HTTP 메서드 ( GET, POST, PUT ... )

  2. 요청 URL

  3. HTTP 버전 

  1. HTTP 버전

  2. 상태 코드 ( 200, 404 ... )

  3. 상태 텍스트 ( Not Found ... )

HTTP 헤더
(HTTP headers)

  1. request 헤더 ( Host, User-Agent, Accept ... )

  2. general 헤더 ( Connection ... )

  3. entity 헤더 ( Content-Type ... )

  1. response 헤더 ( Server, Set-Cookie, Age ... )

  2. general 헤더 ( Connection ... )

  3. entity 헤더 ( Content-Type ... )

공백 (empty line) 

메타 데이터 전송이 끝났음을 알리는 공백 

바디 (body)

서버에 전송하는 데이터 등 

클라이언트에 전달하는 데이터 등

 

 

실제 HTTP 메시지 구성 예시 ( 출처 : https://developer.mozilla.org/ko/docs/Web/HTTP/Messages#%EB%B3%B8%EB%AC%B8 )

 

 

 

HTTP 메서드 


 HTTP 메서드는 클라이언트가 서버에 요청의 목적 및 종류를 알리는 수단이다.

HTTP 요청시에 메세지 시작줄에 표시된다.

RestFul API 구조 등이 많이 사용되기 때문에 주로 GET , POST, PUT, DELETE 정도의 메서드 위주로 알아 두면 좋다.

 

메서드

설명

GET

리소스 요청

POST

서버에 내용(파일 포함) 전송

HEAD

메세지 헤더(문서 정보) 요청

PUT

리소스 전체 수정 요청

DELETE

리소스 제거 요청

OPTIONS

서버에서 제공하는 메서드 목록 요청

TRACE

요청 리소스가 수신되는 경로를 보여줌 메세지 loop-back 테스트 요청

CONNECT

프록시 서버와 같은 중간 서버 경유

PATCH

리소스 부분 수정 요청

 

 

 

HTTP 헤더 


 HTTP 메시지 구조를 보면 HTTP 헤더가 들어가는데 요청/응답 헤더 , general 헤더, entity 헤더 로 구분된다.

헤더는 기본적으로 key : value 방식으로 표기되며, 헤더안에 들어갈 수 있는 종류는 매우 많다.

하지만 주로 많이 사용되는 헤더들을 정리해보자면 다음과 같다.

 

요청(request) 헤더

헤더 명

설명

Host

요청하는 호스트에 대한 호스트 명 및 포트번호

User-Agent

클라이언트 소프트웨어( 웹 브라우저 or 모바일 )의 이름과 버전 등의 정보

Accept

클라이언트가 원하는 미디어 타입 및 우선순위 ( */* 은 모든 파일형식을 지원한다는 의미)

Accept-Language

클라이언트가 원하는 가능한 언어

Accept-Encoding

클라이언트가 원하는 문자 인코딩 방식

If-Modified-Since

제시한 일시 이후로 변경된 리소스 요청

Cookie

서버에 의해 Set-Cookie 로 클라이언트에 설정된 쿠키 정보

Referer

특정 페이지에서 링크를 클릭하여 요청하였을 경우 직전에 머물렀던 링크 주소

 

응답(response) 헤더

헤더 명

설명

Server

서버 소프트웨어 정보

Access-Control-Allow-Origin

요청을 보내는 프론트 주소와 받는 백엔드 주소가 다르면 CORS 에러 발생

Set-Cookie

서버에서 클라이언트로 쿠키 생성 

Etag

HTTP 컨텐츠가 바뀌었는지 검사하는 태그 

Allow

서버에서 지원가능한 HTTP 메소드 리스트

 

general 헤더

헤더 명

설명

Date

HTTP 메시지 생성 일시

Connection

커넥션 정보 ( keep-Alive / token list ) 

Cache-Control

캐싱 관련 옵

 

entity 헤더 ( body 가 없는 경우 전송되지 않음)

헤더 명

 설명

Content-Type

미디어 타입 정보

 

 

 

 

HTTP 상태코드


 HTTP 상태코드는 응답 메시지 중에서도 start-line 에 표기 된다. 

HTTP 상태코드는 요청에 대한 처리 결과를 알려 준다.

상황에 따라 상태코드는 3자리 숫자로 표현하는데 100 대 부터 500 대까지가 있다. 

상태 코드별 값과 의미가 다양 하지만 각 번호대의 대략적인 의미는 다음과 같다.

 

  • 1xx : 정보성 

  • 2xx : 성공 

  • 3xx : 리다이렉션

  • 4xx : 클라이언트 오류

  • 5xx : 서버 오류

 

 

 

 

 

 

 

 

반응형
반응형

알고리즘 문제를 풀다보면 프랙탈(fractal)  과 같이 패턴이 반복되는 구조를 마주칠 때가 있다. 

반복되는 구조를 코드로 작성하려면 for 문을 사용하면 되지만 재귀함수를 통해서도 구현할 수 있다.

결국 자신이 원하는 결과를 얻기 위해 올바른 코드를 작성했으면 for 문이든 재귀함수든 결과는 똑같겠지만

그럼에도 불구하고  for문과 재귀함수에 어떤 차이가 있는지 알고 사용하는게 중요하다. 

개인적으로는 자신에게 쉽고 빠른 방법을 선택하는게 좋은 것 같다 :) 

 

 

 

재귀함수 (Recursive Function) 란?


 재귀라는 단어는 원래 자리로 되돌아가거나 되돌아옴 을 뜻한다.

프로그래밍에서 재귀는 자기 자신을 호출하는 것을 의미한다.

이러한 재귀의 의미를 사용하여 자기 자신을 다시 호출하여 재참조하는 구조의 함수를 재귀함수라고 한다.

 

 

재귀함수의 구조


 재귀 함수는 보통 피보나치 수열이나 하노이의 탑 알고리즘에서 많이 사용된다. 

이외에도 1 부터 n 까지 숫자의 합이나 팩토리얼 ( ! ) 같은 연산을 할 때에도 사용될 수 있다.

예를들어 1 부터 n 까지 숫자의 합을 구하는 재귀함수는 아래와 같다.

 

public int sum(int n){
	
    if(n==0) {
    return 0;
    }
    
    return n + sum(n-1);
}

int total = sum(10); // 55 ( 1 부터 10까지의 합 ) 

 

 

재귀함수를 살펴보면 return 을 통해 다시 자기자신을 호출하고 있는 걸 볼 수 있다.

그런데 재귀함수를 사용할 때 주의할 점이 있다. 재귀함수가 종료되는 조건을 넣어 줘야한다는 것이다. 그렇지 않으면 재귀함수는 무한루프에 빠지게 된다.

코드에서 보듯이 처음에 if 문을 통해 n 이 0 인지 체크하고 0 이면 0 값을 반환하고 함수를 종료한다. 

 

 

 

재귀함수의 특징


1. 코드의 가독성이 좋다. 

2. 스택 메모리를 사용한다.

 

 

 

재귀함수와 for 문 (반복문) 의 차이


1. 메모리 

 : 재귀함수는 함수를 반복적으로 호출하기 때문에 스택 메모리를 사용한다.

(스택 오버플로우가 발생할 수 있다. )

반면 반복문은 메모리 힙을 사용한다.

 

2. 코드길이

 - 재귀함수를 사용하면 반복문에 비해 코드수를 줄일 수 있다. 

 

 

 

 

 

 

 

 

 

 

 

반응형

'IT 정보 로그캣 > CS' 카테고리의 다른 글

[네트워크] get 과 post 의 차이  (2) 2019.06.03
[네트워크] http 란  (0) 2019.06.01
[알고리즘] 비트마스크란  (0) 2019.03.23
[자료구조] 연결 리스트  (0) 2019.03.16
[자료구조] 동적배열 (Dynamic Array)  (0) 2019.03.14
반응형

컴퓨터의 언어는 기계어라고 불리는 이진수이다. 

이진수는 독일의 철학자 라이프니츠가 발명한 수 체계이다. 

컴퓨터가 이진수를 사용하는 이유는 무엇일까?

그 이유는 전기신호로 작동하는 컴퓨터에게 전기가 통할 때 (1), 전기가 통하지 않을 때(0) 2가지 신호를 나타낼 수 있는 이진수가 가장 효율적이기 때문이다.

예를 들어 단순히 생각해보면 이진수는 전선이 하나만 있으면 표현이 가능하다. 

하지만 십진수의 경우 0부터 9까지 숫자를 표현 해야하기 때문에 10개의 전선이 필요하다.

십진수 체계에서 하나의 전기신호만 보내면 되는 상황이면 나머지 9개의 전선은 낭비인 것이다.

그래서 필요에 따라 이진수를 여러번 사용하는게 가장 효율적이다.




비트(bit) 란?


 비트는 데이터를 나타내는 최소 단위로 이진수의 한자리인 0 또는 1 의 값을 가진다. 

비트라는 이름은 바이너리 디지트(binary digit)의 약자를 의미한다.

부호 없는 N비트 정수형 변수는 N자리의 이진수로 나타낼 수 있다.

이때 비트가 표현하는 값은  부터  까지이다. 

여기서 에 해당하는 비트값을 최상위 비트(Most Significant Bit) 라 하고,   에 해당하는 비트값을 최하위 비트(Least Significant Bit) 라고 한다.


예를 들어 부호없는 4비트 정수형은 네 자리 이진수로 표시할 수 있는 모든 정수를 나타낼 수 있다. 

( 아래 그림과 같이 4칸의 공간에 이진수 0 또는 1을 넣은 모든 경우의 수를 의미한다. )

이때 비트가 표현하는 값은  부터 이다.





그리고 여기서 에 해당 하는 비트값(1) 이 최상위 비트이고  에 해당하는 비트값(1)이 최하위 비트이다.




비트마스크란?


 비트마스크에 대해 알기위해 기본적으로 컴퓨터의 언어인 이진수와 비트에 대해 알아보았다.

비트마스크란 컴퓨터의 언어인 이진수를 사용하면 연산이 빠른점을 이용해 어떠한 정수를 이진수 형태로 표현하여 자료구조로써 사용하는 기법이다.

 



비트마스크의 장점


 1. 다른 자료 구조에 비해 수행 시간이 더 빠르다. 


 2. 비크 연산자를 사용하여 코드가 더 간결해 진다. 


 3. 비트마스크를 사용하여 더 작은 메모리를 사용할 수 있다.




비트 연산


 비트 연산은 이진수에 대해 비트 단위로 적용되는 연산을 의미한다.




비트 연산자 ( java 기준 )


 1. AND 연산자( & ) 두 정수를 한 비트씩 비교하면서 양쪽 비트가 모두 1이면 결과도 1 이고 나머지는 0 을 반환


예) 101 & 100 = 100


 

 2. OR 연산자( | ) : 두 정수를 한 비트씩 비교하면서 양쪽 비트 중 하나라도 1이면 결과가 1 이고 나머지는 0 을 반환


예) 101 | 100 = 101



 3. XOR 연산자 ( ^ ) : 두 정수를 한 비트씩 비교하면서 양쪽 비트가 서로 다르면 1 , 같으면 0을 반환


예) 101^100 = 010



 4. NOT 연산자 ( ~ ) : 정수 하나의 각 비트를  1 이면 0 , 0 이면 1 로 바꾸는 연산


예) ~101 = 010



 5. 쉬프트 연산자 ( a << b ) : 정수 a 를 왼쪽으로 b 비트 만큼  이동


예) 0000101 << 3 = 0101000



 6. 쉬프트 연산자 ( a >> b ) : 정수 a 를 오른쪽으로 b 비트 만큼 이동


예) 111000 >> 3 = 000111



 7. 쉬프트 연산자 ( a >>> b ) : 정수 a를 오른쪽으로 b 비트 만큼 이동 한뒤 왼쪽에는 모두 0 으로 채움


예) 11110000 >>> 3 = 00011110




비트마스크를 이용한 집합 


 비트마스크의 연산을 이용하면 비트마스크를 이용한 집합을 구현할 수 있다. 

기본적으로 0 을 공집합으로 여기고, 꽉찬 집합 ( 비트가 모두 1 인 집합) 을 구할 수 있다.

또한 집합에 원소를 추가하거나 삭제, 번경을 할 수 있으며 두 집합에 대해 연산도 가능하다.

집합의 크기 또한 구할 수 있는데 예를 들어 32비트 부호없는 정수를 a 에서 켜진 비트 (1) 의 수를 구할 수 있다. 구하는 방법은 언어 또는 컴파일러 별로 최적화되어 구현되어 있기 때문에 사용할 수 있다.


 1. gcc/g++ : __builtin_popcount(a)


 2. Visual C++ : __popcnt(a)


 3. java : Integer.bitCount(a)

 

반응형

'IT 정보 로그캣 > CS' 카테고리의 다른 글

[네트워크] http 란  (0) 2019.06.01
[알고리즘] 재귀함수  (0) 2019.04.13
[자료구조] 연결 리스트  (0) 2019.03.16
[자료구조] 동적배열 (Dynamic Array)  (0) 2019.03.14
[자료구조] 스택, 큐, 데크  (0) 2019.03.07

+ Recent posts