codeit

컴퓨터 개론

프로그래밍 시장은 계속 커지고 있다. 하지만 사실 현업에서는 뛰어난 개발자를 없어서 못 구한다는 것. 프로그래밍의 세계는 광범위하기 때문에, 올바른 방향을 갖고 효과적으로 공부하는 것이 매우 중요하다. 코드잇의 컴퓨터 개론을 통해 프로그래밍 언어, 프로그래머, 프로그램에 대해 올바른 이해를 갖고, 나만의 커리어 로드맵을 만들어 보자.

💡Infomation: 컴퓨터 개론 학습은 하루 1시간 학습을 기준으로 약 12일이 소요됩니다.

프로그래밍 언어를 분류하는 두 가지 기준

전공자는 물론 비전공자도 이 강의만 들어도 기본적인 프로그래밍 언어의 특징과 분야를 이해할 수 있다. 비전공자를 위한 기초강의!

프로그래밍 언어가 너무 많다.

프로그래밍 언어들은 영어, 숫자 그리고 괄호나 점, 세미콜론 같은 기호로 이루어져 있다. 그래서 얼핏 보면 다 똑같아 보일 수 있지만 사실 차이점도 많이 존재한다. 눈에 드러나는 차이점도 있고 좀 더 공부를 해야 이해할 수 있는 차이점도 있다. 프로그래밍의 기본 개념인 자료형, 변수, 함수 파라미터를 통해 각 언어가 어떻게 다른지 간단히만 한 번 살펴보자.

아래 코드는 Python, Java, C 세가지 코드이다.

1
2
name = "James"
age = 23
1
2
String name = "James";
int age = 23;
1
2
char name[6] = "James";
int age = 23;

세 코드 모두 name 이라는 변수에 James 라는 문자열을 저장하고 age 라는 변수에 23 이라는 숫자를 저장하는 코드이다. 같은 의미를 갖는 코드인데 조금씩 생김새가 다르다. 다른 코드도 한 번 보자.

1
print("Hello")
1
2
3
4
5
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello");
    }
}
1
2
3
4
5
6
7
#include <stdio.h>

int main()
{
    printf("Hello\n");
    return 0;
}

세 코드 모드 Hello 라는 문자열을 출력하는 코드이다. 하지만 얼핏 봐도 코드를 작성하는 방식이 다르다. 코드의 내용까지는 이해가 인 되더라도 더 딻다, 더 길다 정도의 차이는 발견할 수 있을 것이다.

같은 기능을 만드는데 왜 여러가지 프로그래밍 언어들이 존재하는 것일까? 게다가 우리는 지금 세 언어만 살펴봤지만 이외에도 JavaScript, Ruby, php, swift 그리고 C++과 C# 등 언어가 그 이상으로 무척이나 많다. TIOBE 에서는 사람들에게 널리 통용되는 프로그래밍 언어가 250개 있다고 한다.

왜 이렇게 많은 언어가 생겨나게 된 것일까? 처음에는 단 하나의 프로그래밍 언어가 있었을 것이다. 이걸 사람들이 쓰다 보니 컴퓨터 프로그램 만들 때는 괜찮은데 휴대폰에 들어가는 프로그램 만들기는 좀 어렵다. 혹은 이 언어는 배우기가 너무 어렵다 등 다양한 이유로 불편함을 느낀다. 그래서 그 단점을 보완한 새로운 언어를 만들게 된다. 그러다가 또 시간이 지나서 사람들이 실행 속도를 매우 중요하게 생각하게 되었다. 그래서 배우기는 좀 어렵지만 실행 속도를 최고로 끌어올릴 수 있는 또 다른 언어를 만들어서 활용하게 된다. 이런 방식으로 사회의 상황에 따라, 개발자의 필요에 따라 여러가지 이유로 기존의 프로그래밍 언어에 불편함을 느끼게 되고 새로운 언어가 만들어지게 되는 것이다.

더군다나 요즘은 사업 분야도 워낙 다양해지고 프로그램으로 만들고자 하는 결과물의 종류도 많아서 그만큼 다양한 프로그래밍 언어에 수요가 있기도 하다. 정리하자면 용도, 상황 혹은 프로젝트 규모에 따라서 더 유용하고 적합한 언어가 있는 것이다. 그래서 각 필요에 따라 여러 가지 언어들이 등장하고, 일부는 사라지고, 일부는 지금까지 계속 인기를 얻어 남아있는 것이다.


첫 번째 패러다임: 객체 지향 프로그래밍

프로그래밍을 배우려면 먼저 언어를 골라야한다. 수 많은 프로그래밍 언어 중에 어떤 언어를 선택해서 공부해야 할까? 그러려면 먼저 어떤 언어가 어떤 특징을 가지고 있는지 알아야 한다. 많은 언어의 특징을 하나하나 파악하긴 쉽지 않다. 그래서 프로그래밍 언어를 분류해서 여러 언어들의 전반적인 특징을 대략적으로 알아보려고 한다.

프로그래밍 언어를 어떤 기준으로 분류할 수 있을까? 보통 뭔가를 분류할 때 큰 사건 혹은 중요한 개념이 나타나면 그걸 기준으로 분류하고는 한다. 마치 사회에서 산업 혁명이 일어나고 그것에 따라 많은 것이 바뀌면서 시대를 산업혁명 전후로 나눈 것처럼 말이다. 프로그래밍 세계에서도 이런 핵심적인 사건이 있었다. 바로 객체 지향의 등장이다. 아마 들어본 사람들도 있을 것이다. 객체 지향은 사실 대학교에서도 한 학기 동안 배울 만큼 내용이 많은 개념이다. 이것을 여기서 배우려는 것은 아니고 프로그래밍 언어의 흐름을 이해할 수 있을 정도로만 간단하게 알아보겠다.

객체지향은 프로그래밍에 대한 여러 접근 방식 중 하나이다. 어떤 방식을 사용하는지에 따라 코드 전체가 완전히 달라지게 된다. 이중 객체 지향은 지배적으로 많이 쓰이는 개념이고 이제는 객체 지향을 모르면 개발자라고 할 수 없는 수준까지 이르렀다. 객체지향을 워낙 많이 사용하다 보니 꽤 많은 프로그래밍 언어들이 아예 객체 지향에 맞춰서 등장하게 됐다. 객체 지향으로 프로그래밍을 할 거란 전제하에 모든 문법과 도구를 만들어 준 것이다. 그래서 심지어는 객체 지향을 잘 몰라도 은연중에 객체 지향 프로그래밍을 사용하게 되기도 한다. 요즘에는 사용하는 많은 언어가 객체 지향 언어이다. 하지만 객체 지향 언어가 아니라고 해서 무조건 안 좋거나 옛날 방식인 것은 아니다. 실행 속도 등의 이유로 객체 지향을 일부러 안 쓰는 경우도 있다.

어떤 것이 좋은지는 상황에 따라 다르다. C언어나 fortran, assembly언어, haskell 등은 객체 지향은 아니지만 요즘도 많이 사용하는 언어들이다. 이렇게 객체 지향을 지원하는지에 따라 프로그래밍 언어를 나눌 수 있다. 각자 장단점이 있기 때문에 내가 만들고자 하는 프로그램 혹은 일하고자 하는 분야에 따라 객체 지향 언어를 배우는 게 좋을지 객체 지향이 아닌 언어를 배우는게 좋을지 달라진다. 객체 지향이 어떤 개념인지 그리고 객체 지향 언어는 언제 좋은지 한 번 살펴보겠다.

객체 지향 프로그래밍 이해하기

객체 지향 프로그래밍이 어떤 것인지 알아보기 위해 등장한 배경을 한 번 알아보자. 인스타그램 같은 sns를 여러 개발자가 나눠 만드는 걸 상상해 보자. sns를 만들려면 필요한 기능, 즉 함수들이 있을 것이다. 보통 프로그램은 기능이 많고 복잡하기 때문에 개발자들은 협업을 해야 한다. 이때 개발자들은 프로그래밍 작업을 어떻게 나눌 수 있을까? 일단 전체 윤곽을 완성한 뒤 그 안에 어떤 함수가 필요한지 분석한다. 그리고 이걸 각자가 나눠서 만드는 것이다. 각자 기능을 다 완성하면 하나로 합치고 sns가 완성된다. 이렇게 전체를 각 부분으로 나눈 뒤 각자 완성해 나가는 것을 탑다운(Top-down) 방식이라고 한다. 큰 것을 쪼개서 작은 것으로 나눈다는 의미이다. 프로그래머들은 계속해서 이런 방식으로 일을 하고 있었다.

인스타그램

하지만 문제를 겪게 되는데, 바로 탑다운 방식은 전체를 합쳐야지만 제대로 동작하는지 알 수 있다는 문제이다. 즉 10개의 기능 중 한 개라도 미완성이면 전체를 실행할 수 없다. 전체 프로그램이 실행되는 과정을 보면 예를 들어서 로그인 기능 같은 경우에는 아이디, 비밀번호 같은 데이터들이 함수 파라미터로 넘어갔다가 리턴되어서 다시 돌아온다. ‘피드 올리기’ 같은 기능은 사진과 내용이 함수 파라미터로 넘어갔다가 다시 돌아오게 된다. 이런 방식으로 프로그램이 동작하게 된다. 그래서 하나의 데이터가 여러 함수에서 사용되기도 하고 언제, 어떤 데이터가 사용될지 쉽게 예측할 수 없다 보니 코드 전체가 완성되지 않고서는 동작을 제대로 확인해 볼 수 없는 것이다.

게다가 누군가가 함수를 잘 못 구현하면 다른 함수도 영향을 받게 되고 결국 전체가 다 망가지게 된다. 이런 방식으로 프로그래밍을 하면 기능을 일부 수정하기도 어렵다. 하나의 기능만 수정하려고 해도 다른 기능들이 다 데이터로 연결되어 있기 때문에 조금만 바꿔도 전체 코드를 점검해 봐야 하는 상황이 된다. 힘은 힘대로 드는데 실수 하나가 매우 치명적이라 코딩하기도 어렵고 매우 비효율적인 상황이 된다. 특히 많은 데이터를 다루는 sns 같은 프로그램에서는 이런 문제가 더욱더 심각해진다.

객체지향프로그래밍

이런 탑다운 방식의 문제를 해결하기 위해 개발자들은 접근 방식을 바꿔보기로 했다. 큰 프로그램의 일을 나눌 때 이전처럼 기능, 즉 함수를 기준으로 나누는 것이 아니라 다른 방법을 생각했다. 이전처럼 모든 데이터가 한곳에 모여서 기능이 다 얽혀 있는 것이 아니라 기능, 변수, 관련 있는 데이터를 하나로 묶어서 좀 더 의미 있는 단위로 나누기로 했다. 이런 방식으로 묶은 것을 객체라고 하며 영어로는 Object라고 한다. 객체 지향 프로그래밍의 객체가 바로 이 Object를 의미하는 것이다. 객체라는 개념을 적용해 프로그래밍을 한다고 해서 객체 지향 프로그래밍이라고 부르는 것이다.

sns만들기

앞서 예를 들었던 sns를 이 방식으로 만들면 어떻게 될까? 예를 들면 사용자라는 객체를 만들고 사용자와 관련이 있는 데이터인 아이디와 비밀번호, 자기소개 텍스트 등의 데이터를 객체가 갖게 한다. 그리고 사용자의 기능으로는 로그인, 새로운 친구 추가, 게시글 올리기 등이 있을 것이다. 또 게시글 객체를 만들고 그 안에 텍스트 내용, 업로드 시간 등의 데이터를 갖고 게시글 리스트에 추가할 수 있는 기능을 갖게 하자. 이런 방식으로 sns를 여러 객체로 분류한다. 이렇게 코드를 나누게 되면 데이터가 필요한 함수와 같이 묶여 있으니 이해도 더 직관적이고 직접 한 부분을 만들면서 테스트나 실행하기도 더 편하다. 데이터에 변화가 있을 때도 모든 코드, 모든 함수를 다 확인해 보는 것이 아니라 하나의 객체만 확인해 보면 된다. 무언가 프로그램이 고장이 났을 때도 그 부분만 망가지고 나머지 부분은 제대로 동작할 수 있는 것이다.

객체 지향이라는 개념이 프로그래밍 세계에 혁신이 됐을 것 같지 않은가? 앞서 살펴본 큰 단위를 만들고 작은 부분들을 완성해나가는 방식이 탑다운 방식이라고 한다면, 객체를 만들고 그것을 이용해서 큰 것들을 만드는 객체 지향 프로그래밍 방식은 바텀업(Bottom-up) 방식이라고 할 수 있다.

객체지향의 장점과 단점에 대해 정리해보았다.

두 번째 패러다임: 변수의 데이터 타입

객체지향의분류기준

프로그래밍 언어를 분류할 첫 번째 기준은 객체 지향의 지원 유무였다. 두 번째로는 뭐가 있을까? 위 그림에서 두 그룹의 코드를 비교하여 차이점을 찾아보자. 어떤 차이가 보이는가? 물론 여러 차이가 있지만 A 그룹은 변수명, =, 값 총 3개의 요소로만 이루어져 있다. 하지만 B 그룹은 변수명 앞에 무언가 더 있다. 이것은 자료형이라는 것으로 변수에 담길 데이터가 어떤 타입인지 미리 정해 주는 것이다. 만약 name이라는 변수에 문자열을 담을 거라고 미리 정해줬는데 숫자 20을 넣으라고 하면 에러가 난다. 반면 A 그룹 언어의 변수는 뭐든지 담을 수 있다. 애초에 변수에 어떤 자료형을 담을지 정해주지 않기 때문이다. 프로그래밍할 때 변수를 선언하는 일은 정말 너무나도 만히 일어난다. 어쩌면 코드에서 가장 많이 일어나는 문법일지도 모른다. 그런데 변수의 자료형을 정해 주는 것이 프로그래밍 언어로 분류할 만큼 큰 차이인 것일까?

다른 케이스도 한 번 살펴보자. 이번에는 함수를 살펴보자.

함수케이스

A 그룹인 Python의 함수를 보자. 이것을 B 그룹인 Java로 표현해 보면 코드가 위와 같이 된다. 코드를 보면 파라미터에도 다 자료형을 적어 줘야 하고 여러 가지 용도를 더 적어 줘야 한다. 같은 내용이라도 함수를 사용할 때 두 부류의 문법이 다르다는 것을 알 수 있다. A 그룹과 B 그룹의 언어를 보면 프로그래밍 언어의 가장 기본적인 요소인 변수와 함수에서도 이렇게 차이가 많이 나는데 전체 코드로 비교하면 차이가 훨씬 클 것이다.

두 부류의 차이

그렇다면 프로그래밍 언어를 만든 사람들은 어떤 이유로 이렇게 다르게 만들었을까? A 그룹은 간편함, 편리함을 추구한다. 딱 봐도 느낌이 올 것이다. 변수에 뭘 담을지 그런 건 고민하지 않아도 되고 최대한 코드를 짧고 간단하게 만들었다. 예를 들면 A 그룹은 레고와 비슷하다. 레고는 연결하는 모양이 똑같이 생겼기 때문에 어디, 어떻게든 쉽게 연결할 수 있다. 하지만 연결하는 모양이 다 똑같이 생겼기 때문에 잘 연결했는지 확인할 안전장치가 없다. 이렇게 하면 간단하고 빠르게 뚝딱 만들어 볼 때는 더 좋겠지만 때로는 잘못된 결과를 초래할 수도 있다. 만약 이것이 치명적인 문제라면 실행 도중에 오류가 발생하고 실제 사용자들이 사용하다가 프로그램이 멈춰버릴 수도 있다.

B그룹은 마치 시계 같다

반대로 B 그룹은 복잡하고, 불편하고, 생각할게 많아지는데 왜 굳이 자료형을 정해 줬을까? 그 이유는 코드를 더 정밀하게 만들기 위해서이다. 예를 들어서 시계를 만든다고 생각해 보자. 시계는 아주 섬세한 기계다. 그래서 내부에는 작고 헷갈리기 쉬운 부품들이 많은데 모든 부품이 설계도에 정해진 대로 다 정확한 위치에 딱 맞게 들어가야 작동한다. 시계는 잘못된 방식으로 연결하려고 하면 아예 조립이 되질 않는다. 완벽하게 조립해야 되기 때문에 이런 경우에는 어떤 제약을 주는 것이 더 안전할 것이다. 그래서 정확한 위치에 부품이 들어가야 비로소 조립이 되도록 제약을 두어야 실수를 방지하고 기계가 고장 날 확률을 줄여준다. 또한 B 그룹의 언어는 코드를 작성하면서 그리고 실행할 때마다 연결 부위를 다 맞게 조립했는지 확인하는 절차를 필수적으로 거치게 된다. 만약 어딘가 실수가 있었다면 컴퓨터가 알아서 확인해 주고 어느 연결 부분이 틀렸는지 알려준다. 프로그래머는 그 에러 메시지를 확인하여 해당 코드를 고치면 된다. 만약 프로그램이 잘 싱행된다면 코드가 잘 조립되어 있다는 뜻이다.

프로그래밍을 하다 보면 나누어서 코드를 만들고, 합칠 때가 많은데 나누고, 합치는 것이 더 복잡한 프로그램일수록 이런 제약이 오히려 안전장치 역할을 한다.


이전 내용 보기 다음 내용 보기

Leave a comment