이번 포스팅에서는 컴퓨터에서 문자를 표현하는 방법에 대해 알아보겠습니다.


컴퓨터에서 문자를 저장하는 방법

컴퓨터에서는 숫자만 저장할 수 있기 때문에 문자 'A' 를 숫자로 변환하여 저장합니다. 영어 알파벳을 예로들면, a~Z까지 52개가 존재하는데 이는 6비트를 조합하면(64개) 모두 표현이 가능합니다. 000001 = 'a' 라고 규칙을 정해놓는 셈입니다. 


하지만 전세계적으로 네트워크가 발달하여 각 나라에서 사용하는 코드체계가 달라 서로 소통하기가 어렵고 6비트만으로는 전세계의 언어를 표현할 수가 없었습니다.  예를 들어 미국에서 000001 = 'a' 이지만 한국에서는 000001이 = 'ㄱ' 으로 사용했었다면 같은 비트더라도 해석하는 방법이 다르기 때문에 어려움이 있었습니다. 


이러한 문제를 해결하기위한 코드체계 표준안을 만들게 되었습니다.


ASCII (American Standard Code For Information Interchange)

아스키는 문자 인코딩 표준으로 7bit 인코딩으로 128문자를 표현하는 코드체계입니다. 33개의 출력 불가능한 제어 문자들과 공백을 비롯한 95개의 출력 가능한 문자들로 이루어져 있습니다. 아래에서는 정수, 16진수, 8진수, 문자형으로 표현한 아스키코드표입니다. 



확장 아스키

표준 문자 이외의 악센트 문자, 도형 문자, 특수 문자, 특수 기호 등 부가적인 문자 128개를 더 추가할 수 있게하는 부호. 하지만 부가적인 문자는 컴퓨터 생산자나 소프트웨어 개발자에 의해 할당되므로 서로 다른 생산자, 개발자끼리는 공용으로 사용할 수 없습니다.


유니코드

아스키는 알파벳을 기준으로 만들어진 코드체계이고 전 세계의 다양한 언어를 표현하지 못합니다. 이러한 다국어 처리를 위한 표준이 유니코드입니다.



유니코드는 다시 Character-Set에 따라 UCS-2(Universal Character Set 2), UCS-4(Universal Character Set 4)로 구분됩니다. 이는 유니코드를 저장하는 변수의 크기를 정의하는데 문자(파일)을 인식할 때 UCS-2인지, UCS-4인지 구분해서 구현해야 하는 문제가 생겼습니다. 이러한 문제를 해결하기위해 변수 크기에 따라 표준안을 만들게 되었습니다. 


유니코드 인코딩

UTF-8 (in web) - 한 문자를 표현하는데 최소 1바이트 ~ 최대 4바이트를 사용합니다.
UTF-16(in windows, java) - 한 문자를 표현하는데 최소 2바이트 ~ 최대 4바이트를 사용합니다.
UTF-32(int unix) - 한 문자를 표현하는데 최소,최대 4바이트를 사용.



'CS > 개발지식' 카테고리의 다른 글

base64 인코딩/디코딩 원리  (0) 2017.04.04
OOP  (0) 2017.03.21
프로세스와 쓰레드의 차이점  (0) 2017.03.20
Runnable 과Thread의 차이  (0) 2017.03.19

base64 란 ?

8비트 이진데이터를(예를 들어 실행 파일이나, ZIP파일등..) 공통아스키 영역의 문자들로만 이루어진 일련의 문자열로 바꾸는 인코딩 방식

왜 사용하는가?

공통된 아스키영역의 문자들만을 사용함으로써 다른 문자코드에 영향을 받지 않음.

인코딩 / 디코딩원리


위에서 말했듯이 Base64 인코딩은 64개의 문자를 이용하여 바이너리 데이터를 공통아스키 영역의 문자들로 변환하는 인코딩 방식이다. 즉 8bit의 데이터(바이너리)를 6bit크기로 표현한다. 따라서 3개의 문자(24bit) 단위를 기준으로 4개의 인코딩된 문자를 얻을 수 있다.



위와같이 abc(24bit)를 base64 방식으로 인코딩하면 YWJj(24bit) 4개의 문자를 얻을 수 있다.


<base64 테이블>


그렇다면 3개(24bit)의 문자단위가 아닐때는 어떻게 될까..?

위의 예시처럼 a(8bit)를 24bit 단위로 표현하면 01100001 0000000 0000000 와 같이 되는데 base64는 6비트단위씩 끊으므로
011000 010000 000000 000000로 변환이 된다.  000000은 A인데 왜 =로 표현되느냐? '='은 bit수를 맞춰주기 위해 0으로 채워주는 패딩값의 표현이다.
즉 문자(바이너리데이터)수가 3n+1이라면 24bit + 8bit인데 24bit단위로 맞춰주기위해 3n(24bit) + 1(8bit) + 16bit를 해주게 되는데, 8bit에서 앞의 6bit는 base64로 인코딩되고 , 남은 2bit와 뒤에 0으로채워진 4bit로 하나의 인코딩된값을 또 얻을 수 있다. 남은 12bit를 2개의 '='으로 채워주게 된다.
즉 3n+1 문자개수라면 '='의 개수가 2개가 되고 , 3n+2 문자개수라면 '='의 개수는 1개가 된다. 


<디코딩의 문제점>

인코딩의 원리는 위와같고, 같은원리로 디코딩역시 YQ== 은 a로 디코딩되는 것을 알 수 있을텐데 여기서 한가지 문제가 발생한다. 인코딩 원리에서 말했듯이 '='이 2개면 3n+1의 문자개수이고 , '='이 1개면 3n+2의 문자개수를 나타낼수 있다.

디코딩 과정에서 '='이 2개면 인코딩된 문자(24bit)중 앞의 8bit만 바이너리 데이터로 변환하고 , 남은 bit는 어떤값이 되던지 신경쓰지 않는다. '='이 1개면 인코딩된 문자(24bit) 중 앞의 16비트만 바이너로 데이터로 변환하고, 마찬가지로 남은 bit값이 어떤값인지 신경쓰지 않는다. 

즉 인코딩된 문자열 YR==,YS==,YT== 등 더있을수있음 디코딩을 해보면 모두 'a'가 나온다.  충돌이 일어날 수 있는 수는 3n+1개의 문자일때는 뒤의 12비트에서 8비트만 정상디코딩이 되고, 남은 4비트가 충돌이 일어나므로 2의 4승인 16개가 생기고 , 3n+2의 문자일때는 2의2승인 4개가 생길것이다.





[출처] http://bbolmin.tistory.com/46




'CS > 개발지식' 카테고리의 다른 글

문자 표현 방식  (0) 2019.02.16
OOP  (0) 2017.03.21
프로세스와 쓰레드의 차이점  (0) 2017.03.20
Runnable 과Thread의 차이  (0) 2017.03.19

OOP 란?

단 몇 줄로 정리할 수 있는 개념은 아닌 것 같지만, 항상 정의내리기 어려워서 간단하게나마 정리해둠. OOP란 Object-Oriented-Programming의 약어로써, 객체지향 프로그래밍을 의미. 
 유형 또는 무형의 사물(데이터)를 객체로 취급하여 프로그램에 반영한 것이며, 순차적으로 프로그램이 동작하는 기존의 것들과는 다르게 객체와 객체의 상호작용을 통해 프로그램이 동작하는 것을 말한다.
 

OOP의 특징

코드의 재사용성이 높음.
코드의 변경이 용이
직관적인 코드 분석
추상화, 캡슐화, 상속, 다형성


캡슐화

캡슐화는 클래스 내부에 여러 속성과 기능을 함께 묶는 것을 의미하기도 하며, 클래스 내부의 속성이나 기능을 외부에 노출하지 않고 보호하는 것을 의미한다. 즉 여러 속성과 기능을 함께 묶어 클래스로 취급하며, 이러한 클래스 내부를 외부에서 접근하지 못하도록 보호하는 것이다.

why ?

1.클래스 단위로 묶음으로써 프로그램을 바라보는 단위가 커진다. 절차지향언어처럼 함수단위로 구조화하는 것이 아니라, 프로그램 전체를 클래스 단위로 바라볼 수 있게 해준다. 

2.내부의 데이터나 함수를 외부에서 참조하지 못하도록 함으로써 내부의 변경이 자유로워 진다. 외부에 노출되어 많은곳에서 사용 또는 변경된다면 , 클래스 내부의 변경으로 인해 영향가는 곳이 많기 때문이다. 따라서 객체 지향에서는 클래스 내부의 데이터를 외부에서 참조하지 못하도록 차단한다. 내부의 데이터나 함수를 외부에서 참조하지 못하도록 차단하는 개념을 정보은닉이라고 한다. 


추상화

추상화는 객체에서 공통된 속성과 행위를 추출하는 것을 의미한다. 예를 들어, A대학 교수  , B대학 교수 , C대학 교수가 있는데 이들의 공통된 속성과 행위를 교수라는 클래스로 추상화할 수 있다. 

why?

필자의 생각으로는 확장성 때문인 것 같다. 보통 클래스는 설계도라고 비유하고  , 추상클래스는 미완성 설계도라고 비유한다. 미완성 설계도로 제작(객체생성)을 할 수 없지만 공통이 되는 설계도를 가지고 있는 것과 아무것도 없는 상태에서 완성 설계도를 만드는 것은 확연한 차이가 있을 것이다.


상속

클래스의 속성과 오퍼레이션을 하위 클래스에 물려주거나, 상위클래스에서 물려받는 것을 말한다. 

why?

재사용으로 인해 코드가 줄어든다. 상위클래스에 정의되어있는 멤버변수나 메소드를 다시 정의하지 않고 재사용할 수 있으므로, 코드가 줄어든다.

다형성

흔히들 알고있는 부모자료형에 자식자료형을 담는 것이라고 알고있었지만,객체지향에서의 다형성은 '여러 클래스들이 동일한 이름의 오퍼레이션을 서비스하도록 하는 것' 이라고 한다. 후자의 개념에 전자가 포함되는 것 같다. 후자에 의하면 메소드 오버라이딩도 , 메소드 오러로딩도 다형성이다. 

why?

여러타입의 클래스를 하나의 타입으로 관리하니 유지보수가 좋음. 확장성이 좋고, 결합도가 강하지 않은 프로그래밍이 가능하다.

확장성이 좋은이유? 새로운 타입의 클래스를 정의하여도 부모클래스를 상속받거나 or 인터페이스를 구현하여 기능만 추가하면 코드가 변하지 않음.


'CS > 개발지식' 카테고리의 다른 글

문자 표현 방식  (0) 2019.02.16
base64 인코딩/디코딩 원리  (0) 2017.04.04
프로세스와 쓰레드의 차이점  (0) 2017.03.20
Runnable 과Thread의 차이  (0) 2017.03.19

멀티프로세싱 운영체제에서는 동시에 여러 프로그램을 실행할 수 있다. 그때 실행중인 프로그램에 대한 인스턴스를 프로세스라고 한다. 프로세스는 운영체제로부터 주소공간,파일,메모리 등을 할당받는다.


리눅스 시스템에서는 코드 영역과 라이브러리를 프로세스 간에 공유하므로, 메모리 내에 코드와 라이브러리는 하나만 존재한다. 변수에 할당되는 공간으로 데이터 세그먼트와 스택 세그먼트는 프로세스 각각 가지고 있다. 그리고 각 프로세스 마다 실행 위치를 나타내는 PC(Program Counter)도 프로세스별로 관리한다.


스레드란 한 프로세스 내에서 동작되는 여러 실행의 흐름으로, 프로세스 내의 주소 공간이나 자원들을 공유하면서 실행된다.


기본적으로 하나의 프로세스가 생성되면 하나의 스레드가 같이 생성된다. 이를 메인 스레드라고 부르며, 스레드를 추가로 생성하지 않는 한 모든 프로그램 코드는 메인 스레드에서 실행된다. 또한 프로세스는 여러개의 스레드를 가질 수 있으며 이를 멀티 스레드라고 한다.


스레드는 프로세스 내에서 각각의 스택 공간을 제외한 나머지 공간과 시스템 자원을 공유한다. 그러므로 프로세스를 이용하여 동시에 처리하던 일을 스레드로 구현할 경우 메모리 공간은 물론 시스템 자원 소모도 현격히 줄어든다. 스레드간의 통신이 필요한 경우 별도의 자원을 이용하는 것이 아니라 전역 변수의 공간을 이용하여 데이터를 주고 받을 수 있다.


스레드의 장점

시스템의 throughput(처리율)이 향상된다.
시스템의 자원 소모가 줄어든다.
프로그램의 응답시간이 단축된다.
프로세스 간 통신 방법에 비해 스레드 간의 통신 방법이 훨씬 간단하다. 데이터 세그먼트, 즉 전역변수를 이용하여 구현한다.


스레드의 단점

공유하는 전역 변수를 여러 스레드가 함께 사용하려면 충돌 문제가 생길 수 있다. 이러한 문제가 발생하지 않도록 동기화 문제를 해결해야 한다.



'CS > 개발지식' 카테고리의 다른 글

문자 표현 방식  (0) 2019.02.16
base64 인코딩/디코딩 원리  (0) 2017.04.04
OOP  (0) 2017.03.21
Runnable 과Thread의 차이  (0) 2017.03.19

쓰레드를 구현하는데 Runnable인터페이스를 구현한 것과 Thread클래스를 상속받는 것의 차이는 무엇일까

쓰레드를 구현하는 방법은 Thread클래스를 상속받는 것과  , Runnable 인터페이스를 구현하는 방법, 모두 2가지가 있다. 이 두가지 방법 중 어느 쪽을 사용해도 별 차이는 없지만 Thread 클래스를 상속받으면 다른 클래스를 상속받을 수 없기 때문에 , Runnable 인터페이스를 구현하는 것이 일반적이다.

Runnable인터페이스를 구현하는 방법은 재사용성이 높고 코드의 일관성을 유지할 수 있다는 장점이 있기 때문에 보다 객체지향적인 방법이라 할 수 있다.

Thread 클래스를 상속

class ThreadEx1 extends Thread{
public void run(){
//작업내용
}
}
ThreadEx1 ex1 = new ThreadEx1();
ex1.start();

Runnable 인터페이스를 구현

class ThreadEx2 implements Runnable{
public void run(){
//작업내용
}
}
ThreadEx2 ex2 = ThreadEx2();
Thread t = new Thread(ex2);
t.start();


start()와 run()에 대한 차이와 쓰레드가 실행되는 과정

run()을 호출하는 것은 생성된 쓰레드를 실행시키는 것이 아니라 단순히 클래스에 속한 메서드 하나를 호출하는 것이다. 반면에 start()는 새로운 쓰레드가 작업을 실행하는데 필요한 호출스택을 생성한 다음에 run()을 호출해서, 생성된 호출스택에 run()이 첫번째로 저장되게 한다.


'CS > 개발지식' 카테고리의 다른 글

문자 표현 방식  (0) 2019.02.16
base64 인코딩/디코딩 원리  (0) 2017.04.04
OOP  (0) 2017.03.21
프로세스와 쓰레드의 차이점  (0) 2017.03.20

+ Recent posts