Digital Recipe
[컴퓨터공학 개론] 01. 컴퓨터공학은 무엇인가? 본문
시작에 앞서,
이 "컴퓨터 공학의 이해"는 주관적인 입장에서 쓰여진 글로써 잘못된 점, 다른 의견, 추가적 의견을 받습니다.
이 게시글은 제 경험 속의 "이해한 컴퓨터 공학"을 이야기로 풀었습니다.
컴퓨터 공학이란 "요청에 대해서 논리적인 연산을 하여 결과를 보여주는 장치에 대한 학문"이라고 표현 가능할 것 같다.
예를 들어, 시간의 흐름을 분(Min) 혹은 초(Second)라는 논리적인 개념으로 변경하여 컴퓨터에 넣었을 때 이를 연산(계산, 혹은 Computing)하여 사용자가 형태의 논리적 시간으로 결과를 보여준다면 컴퓨터 장치가 될 것이다.
이런 컴퓨터는 하드웨어에서 시작되었다.
하드웨어를 통해 입력 -> 처리 -> 결과 형태의 위 역할을 수행할 수 있었을 것이다.
계산기를 예를 들어 보자.
1단계. 1 + 2을 입력한다.
2단계. 더하기(+)라는 처리를 수행한다.
3단계. 결과값 3을 보여준다.
하지만 이런 하드웨어의 제한적 형태를 해결하고 역할확장을 위해 소프트웨어가 발전되었다고 본다.
하여 컴퓨터공학이라고 하면 크게 2가지를 배운다.
+ 하드웨어(계산기)에 대한 이해
+ 하드웨어를 다룰 수 있는 소프트웨어
즉, 지금의 컴퓨터란 하드웨어와 소프트웨어의 조화이다.
다시 소프트웨어가 할 수 있는 일들을 몇 가지로 나눠보면 아래와 같다.
+ 하드웨어 조작
+ 소프트웨어를 조작하는 소프트웨어 (Ex. 응용 소프트웨어)
+ 현실을 디지털화 (Ex. 모델링, 가상화 등등으로 표현될 수 있겠다.)
첫 번째, 하드웨어 조작
소프트웨어가 하드웨어를 어떻게 움직이게 할 것인지 통제 가능하다는 이야기이다. 소프트웨어는 하드웨어와 레지스터를 통해 이야기를 나눌 수 있다. 레지스터라는 메모리를 통해 소프트웨어는 하드웨어가 무엇을 하기를 원하는지 명령을 내리거나 하드웨어가 무엇을 하고 있는지 상태확인을 할 수 있다. 또한 하드웨어 리소스(CPU, 메모리, 스토리지등)을 소프트웨어가 어떻게 사용하고자 하는지 명령을 내릴 수 있다.
이런 역할을 하는 소프트웨어를 시스템 소프트웨어, 즉 운영체제라고 말할 수 있다.
두 번째, 소프트웨어를 조작하는 소프트웨어
하드웨어를 조작할 수 있는 소프트웨어가 있다면 다시 이런 소프트웨어를 활용하는 소프트웨어가 있다. 예를 들어 응용 소프트웨어라고 할 수 있다. 범위를 넓히면 소프트웨어 플랫폼도 들어갈 것이다. 더 자세한 예시를 들어보면 Windows 10이라는 운영체제가 있고, 이런 운영체제를 더욱 쉽게 사용할 수 있게 도와주는 C++, C# 등과 같은 플랫폼 혹은 프레임워크가 있고 또 이를 활용한 다양한 응용 소프트웨어가 있다.
세 번째, 현실을 디지털화.
응용소프트웨어로부터 파생되는 한 부분으로 볼 수도 있겠다. 시간을 분(Min)이나 초(Sec)처럼 사람이 인식가능한 논리적인 형태로 변환하는 것처럼 현실을 사람들이 인지 가능한 형태로 변환해 주는 것을 디지털화라고 할 수 있겠다. 아날로그를 디지털화 하는 것을 모델링이라고 표현하기도 하며 이런 모델링을 통해 현실의 하나의 역할 수행이 가능한 것을 만들어 내면 이를 시뮬레이터라고 할 수 있겠다. 확장하여 실제로 없는 것을 실제로 있는 것처럼 만든다면 가상화가 될 것이다.
이제 좋은 소프트웨어를 개발하기 위해 기본이라 생각되는 학문을 살펴보자.
그리고 이 지식들이 왜 필요하고 어떻게 사용될 수 있는 지 살펴보자.
+ 디지털 표기법(2진법, 16진법)
+ 어셈블리어
+ 컴파일러
+ 하드웨어 리소스의 이해
+ 자료구조
+ 운영체제
+ 데이터베이스
+ 네트워크
1. 디지털 표기법
소프트웨어는 디지털이다. 이 말은 비트(Bit)단위, 0과 1만 인지할 수 있다는 것이다. 하나의 비트(Bit)는 한다/안한다, 참/거짓 정도의 단순한 정보를 나타나겠지만 1Byte의 데이터(8개의 Bit)는 256가지(2^8) 정보를 표현할 수 있다. 때문에 프로그래밍 언어에서 4Bytes짜리 INT형은 약 42억(2^32) 종류의 서로 다른 정보를 표현할 수 있는 것이다.
일부 프로그래밍 언어에서는 비트 연산을 제공하며, 비트 연산을 임베디드 시스템과 같이 메모리 리소스가 제한적인 곳에서 정교한 데이터 컨트롤이 가능하고, 연산에 있어서도 성능향상을 기대할 수 있다. 다만 2진수는 사람이 인지하기에 어렵기 때문에 필요 시 이를 1Byte 단위로 구분하여 이를 16진수로 표현한다.
2. 어셈블리어
어셈블리어는 CPU가 1 Clock 마다 연산하는 최소 단위의 원자성을 가지는 명령어들이다. 컴퓨터의 제일 중요한 역할은 연산이고 CPU가 수행한다. 이 CPU가 수행하는 단위로 이 명령들은 수행되던가 수행되지않던가 둘 중 하나 뿐인 명령이다(중간은 없다). 예를 들면 A와 B를 비교하라. 메모리 주소 0x1000에 값 1을 저장하라. 메모리 주소 0x2000에서 값을 읽어와라. 등의 단순한 명령들이다.
(일반적으로 메모리 주소는 16진수로 표현하며, 16진수 표기법으로 앞에 0x를 붙입니다.)
이 어셈블리어는 컴퓨터의 단순하게 직접적으로 수행되는 명령들이다. 즉 컴퓨터는 이 만들어진 어셈블리어를 수정하거나 최적화하지 않고 있는 그대로 수행한다. 때문에 실제로 컴퓨터가 어떻게 동작하고 있는지 이해하고자 할 때 어셈블리어 단위로 행동을 이해할 필요가 있다.
3. 컴파일러
컴파일러는 사람이 이해할 수 있는 프로그래밍 언어를 컴퓨터가 이해할 수 있는 언어로 바꿔주는 것이다. 즉 C++과 같은 고수준 언어를 어셈블리어로 변경하고 최종적으로 0과 1로 이루어진 기계어로 변경한다. 이때 컴파일러가 수행하는 추가적 역할은 아래와 같다.
1) 대상이 되는 하드웨어에 맞게 변경
2) 고수준 언어를 최적화하여 어셈블리어로 변경한다.
3) 어셈블리어를 기계어로 변환한다.
여기서 최적화라는 것은 사용자가 작성한 고레벨 언어를 있는 그대로 어셈블리어로 직역하는 것이 아니라 더 좋은 성능을 발휘할 수 있는 상태로 번역한다고 보면 된다. 때문에 사용자의 의도와 다르게 컴퓨터가 다르게 동작하는 경우도 발생할 수 있다.
물론 컴파일러를 통해 고수준 언어를 기계어로 어떻게 번역하는지 그 과정을 살펴볼 수 있기 때문에 새로운 고수준 언어를 만들기 위해서는 컴파일러에 대한 깊은 이해가 필요하다.
추가적인 컴파일과 링킹에 대한 내용은 [링크]를 참조하라.
4. 하드웨어의 이해
소프트웨어는 결국 하드웨어에 의해서 수행된다. 하드웨어의 기본은 연산장치(CPU)와 메모리(Memory) 일 것이다. CPU가 메모리에 있는 것을 가져와서 계산하고 결과값을 메모리에 저장한다. 하지만 확장성을 위해 여러가지 하드웨어가 추가된다.
예를 들면 아래와 같은 것들이 있다.
1) 다양한 메모리 종류 (Register, SRAM, DRAM)
2) 2차 저장장치 (HDD, SSD)
3) 그래픽 연산장치(GPU)
4) 네트워크 장치등 (LAN)
메모리라고 해도 빠르고 비싼것부터 느리고 싼 것까지 여러 가지가 존재하고 필요에 따라 Register, SRAM, DRAM등을 사용하여 기회비용을 따져서 메모리를 사용한다. 또한 위와 같은 메모리는 휘발성이기 때문에 데이터의 영구성을 위해 느리지만 영구적으로 저장가능한 2차 저자장치가 추가되고 병렬적인 연산에 강점을 가진다는 그래픽 연산을 위한 GPU도 추가되고 있다.
5. 자료구조
우리는 물품을 정리할 때, 용도별 혹은 분류별로 물품을 분류하고 이 것들을 공통된 목적의 상자에 담을 수 있다. 이 것들을 소프트웨어적으로 가상의 상자를 만든 것이 자료구조이다. 하지만 다양한 자료구조가 존재한다. 왜 다양한 자료구조가 존재하는 것일까?
이유는 우리가 데이터를 모아둔 목적이 서로 다르기 때문이다.
상자에 물건을 넣는다/가져온다 라는 점은 동일하다. 상자 내부를 어떻게 구성하느냐에 따라 목적에 따라 물건을 쉽게 꺼낼 수도 있고 어렵게 꺼낼 수도 있을 것이다.
기본적인 자료구조로 Stack, Queue, Tree, Linked List등이 있다.
이런 것들을 예로 들어보자.
가장 마지막에 넣은 것을 빠르게 빼고 싶다. 그럼 Stack이라는 구조로 상자를 구성하면 된다.
가장 먼저 넣은 것을 빠르게 빼고 싶다. 그럼 Queue라는 구조로 상자를 구성하면 된다.
필요한 것을 빠르게 빼고 싶다. 그럼 Tree 구조가 유용할 수 있다.
추가적인 자료 특성별 자료구조 추천은 이 [링크]를 참조하라.
그럼 이제 대표적인 Stack와 Queue가 활용될 수 있는 부분을 살펴보자.
운영체제에서 프로그램을 수행할 때 새로 호출되는 함수를 Stack 구조에 넣는다. 이유는 그 함수가 끝나고 그 이전의 함수로 돌아와야 하기 때문이다. Queue는 버퍼링과 같은 곳에서 사용될 수 있다. 먼저 들어온 것들을 모아두고 순서대로 하나씩 처리하기 때문이다.
정리하면, 데이터는 효율성을 위해 목적에 따라 관리하는 방법이 달라져야 하고 이를 위해 고안된 것이 자료 구조이다.
6. 운영체제
운영체제는 하드웨어 리소스를 관리하는 소프트웨어이다. 시스템 소프트웨어라고도 한다. 이 운영체제는 대표적인 역할은 프로세스 관리, 메모리 관리, 데이터 관리가 있다.
컴퓨터에 일할 수 있는 CPU는 기본적으로 1개, 많게는 16개까지도 늘어나지만 수행되어야 할 프로세스는 그 이상이다. 그럼 각 프로세스들은 CPU를 돌아가면서 사용해야 한다. 이런 관리를 프로세스 관리라고 한다. 메모리도 유사하다. 모든 프로세스가 메모리를 사용하기에는 메모리가 부족하다. 때문에 운영체제는 프로세스가 메모리를 실제 사용하거나 가상으로 사용하는 것처럼 관리한다. 다음으로 데이터 관리이다. 2차 저장장치를 여러 개의 프로세스가 잘 나눠쓰고, 이를 효율적으로 처리 가능하게 도와주는 역할을 가지고 있다.
이렇게 운영체제는 다양한 소프트웨어가 자신의 관리 속에서 하드웨어를 잘 사용할 수 있게 도와주는 역할을 한다.
이런 소프트웨어를 응용 소프트웨어라고 할 수 있고, 역할에 따라서 플랫폼(Platform), 프레임워크(Framework) 으로 분류하기도 한다.
7. 데이터베이스
방대해진 데이터를 효율적으로 관리하고 활용하기 위한 분야이다. 주요 역할은 아래와 같다.
1) 데이터 공유
2) 효율적인 데이터 관리
여기서 말하는 데이터의 효율적인 관리란 검색/갱신의 효율성, 데이터 무결성 등을 의미한다. 데이터베이스도 철학과 목적에 따라 데이터를 관리하는 방식을 변경하고 있으며, 관계형 데이터베이스가 주로 쓰이지만 최근 빅데이터 분야의 발전에 따라 NoSQL(Not Only SQL) 데이터베이스도 활용되고 있다.
8. 네트워크
원격지에 있는 컴퓨터에 데이터를 송.수신하기 위한 방법이다. 데이터 전송은 아날로그로 이루어지기 때문에 디지털 <-> 아날로그 간의 어떻게 변환이 이루어지는지, 데이터를 효율적으러 처리하기 위한 데이터 가공하는 프로토콜등을 이해해야 한다.
특히 프로토콜은 "정보"를 어떻게 생긴 "데이터"로 송.수신 할지 미리 정해둔 약속으로 프로토콜의 역할은 크게 2가지로 나눌 수 있다.
1) 데이터의 이해
2) 데이터의 효율적이고 안정적인 송.수신
프로토콜 없이는 서로 간의 데이터 이해가 불가능하다. 예를 들어 "01100001111000000...."형태의 데이터가 전달되었는데 앞에서부터 8개의 비트(Bit)는 전화번호에요.라고 알려주지 않으면 앞에서부터 4개의 비트만 읽어야 할지, 10개의 비트를 읽어야 할지 알 수 없고 읽은 데이터가 어떤 정보인지도 알 수가 없다. 그리고 효율적이고 안정적인 데이터 송.수신을 위해 새로운 정보를 추가하는데 이 정보를 어떻게 추가하고 어떻게 처리할지에 대한 이야기도 필요하다.
이와 함께 파생되는 분야로는 웹프로그래밍, 서버프로그래밍, 분산시스템 등이 있다.
Written By Hoseok Seo
2016. 05. 01