티스토리 뷰

컴퓨터 세계에 빠져들면 언젠가는 컴퓨터나 운영체제, 새로운 프로그래밍 언어를 만들고 싶다는 욕심을 갖게 된다. 하지만 이른바 전체적이고 종합적인 '기본기'가 충실히 쌓여 있지 않다면 그 꿈은 꿈으로 그칠 수밖에 없다. 이 글은 전산학이라는 화두를 갖고, 아무리 강조해도 지나치지 않는 개발자가 알아야 할 '기본 지식'을 살펴보는 데 그 목적이 있다.

 

 

"컴퓨터를 전공하지 않은 사람인데, 컴퓨터를 잘할 수 있을까요?" 예전에 어떤 사람이 이런 질문을 해왔다. 이 질문으로 얘기를 시작해 보자(사실 필자도 컴퓨터를 학문으로 전공한 사람은 아니다).

모든 분야의 일이 마찬가지지만, 컴퓨터 관련 엔지니어링 분야만큼 이론과 실제의 차이가 항상 민감하게 교차되는 분야가 그리 흔하지는 않다. 우선 우리는 컴퓨터를 '과학'으로 볼 것인지, '공학'으로 볼 것인지를 결정해야 한다.

과학이란 무엇인가. 간단하게 과학은 '가설과 검증'이라고 정의할 수 있다. 과학은 가설을 세우고, 이를 검증해 이론을 만드는 것을 말한다. 그러나 공학은 좀 다르다. 공학은 실제로 유용한 구현물을 만들기 위한 방법을 만드는 것이다. 따라서 공학의 목적은 무언가 구체적인 '구현' 혹은 '공정'이 된다.

◆ 과학 : 가설과 검증 이론
◆ 공학 : 방법과 효율 구현

우리나라 전산학의 영문 명칭은 대부분 'Computer Science'로 표기된다. 하지만, 앞서 언급했듯이 컴퓨터 과학과 컴퓨터 공학은 조금 명확히 구분할 필요가 있다. 이 글을 읽는 독자의 대부분이 소프트웨어 개발 혹은 프로그래밍의 관점에서 컴퓨터를 바라보고 있을 것이다('공학'의 입장에서 컴퓨터를 바라보는 것이다). 이론을 만드는 게 목적이 아니라는 점을 명확히 하자.

필자는 이 글을 통해 전산학 이론에 대한 말하고자 하는 것이 아니다. 그보다 전산학에서는 무엇을 공부하는지 살펴보고, 전산학의 여러 분야 중에서 우리가 실제 소프트웨어를 개발하는 일에 구체적인 도움이 되는 부분에는 어떤 것이 있는지 '상식'선에서 짚어보고자 한다.

언제나 '기본'이 중요하다는 사실을 다시 돌이켜 보자. 이론에서 실질적인 도움을 얻을 수 있는 부분들, 이론 중에서 기본적으로 알아둬야 할 상식들, 잘못 이해되고 있는 부분들(이론과 실제의 차이)을 살펴보자.


전산학의 기초 '빅 5'

컴퓨터를 접하고 이를 공부하기 시작하면 누구나 언젠가는 컴퓨터를 직접 만들거나, 운영체제를 만들어 본다거나 새로운 프로그래밍 언어를 만들겠다는 생각을 한 적이 있을 것이다. 전산학의 분야를 보면 실제로 이런 분야가 들어 있다. 전산학의 여러 분야 가운데 기본이 되는 다섯 분야를 꼽는다면 다음과 같다.

1. 컴퓨터 구조론
2. 운영체제
3. 자료구조와 알고리즘
4. 프로그래밍 언어론, 컴파일러
5. 데이터베이스론

이 다섯 개의 분야는 기초분야로 꼽히며, 실제로 거의 모든 전산학과에서 강의가 이뤄지고 있다.

이 밖에 소프트웨어 공학, 네트워크, 인공지능 등의 분야가 있으며, 학교에 따라 조금씩 다른 특성을 갖고 커리큘럼이 운영된다.

독자 여러분도 이미 알겠지만, 이 분야를 모두 공부해야 프로그래밍을 할 수 있는 것은 아니다. 다시 말해 '프로그래밍'하는 것과 이 분야를 공부하는 것은 전혀 별개의 문제일 수 있다. 프로그래밍은 누구나 할 수 있다.

실제 컴퓨터에 대한 이해가 전혀 없는 사람도 대략 4∼6개월 정도의 학습을 거치면 실전에서 애플리케이션을 개발할 정도의 능력이 배양된다. 하지만 여기서 모든 것이 해결되는 것은 아니다. 1년이나 2년이 지나면, '프로그램 짤 수 있다'는 정도의 내공(?)에 부족함을 느끼게 되는 것은 어쩌면 당연한 일인지도 모른다.

소프트웨어 개발에 따른 다양한 이슈를 소화하고, 실제 기술의 장단점을 논의하기 위해서는 조금은 다른 지식이 필요하다.

예컨대 개발된 애플리케이션의 수행 효율을 향상하기 위한 성능 튜닝, 이식, 프로그램 설치와 배포, 팀 개발을 이끌어 가는 프로젝트 관리 등의 프로그래밍 이외의 이슈를 만나면, '프로그램을 짤 수 있다'만으로는 해결되지 않는 구석이 많다는 사실을 깨닫게 된다. 즉, 기본기의 중요성을 절감하게 되는 것이다.

이 글의 목적은 전산학이라는 화두를 갖고, '기본기'라는 것을 살펴보기 위함이다. 이제부터 각 분야별로 살펴보자(이 글은 전산학의 전체를 얘기하는 것이 아니라, 전산학과 학부과정에서 배우는 내용과 교재에 한정한 얘기라는 점을 전제한다).

컴퓨터 구조론

강좌내용 : 컴퓨터 구조론은 글자 그대로 컴퓨터의 기본적인 하드웨어의 작동 원리와 구성에 대한 내용을 다루는 분야. 부울 대수(Boolean Algebra)와 논리 표현을 익히고, 이를 하드웨어로 어떻게 구현하는지 공부하고 집적회로(IC)의 동작원리를 배운다. CPU, 메모리, 입출력의 구성이나 주변 장치와의 통신방법 등도 포함된다.

소프트웨어를 하는 사람의 입장에서 컴퓨터 구조론은 '어셈블리어'를 익히고, 동작원리를 아는 데 의의가 있다. 컴퓨터 구조론은 컴퓨터를 만드는 데 필요한 내용을 공부하는 것이지만, 컴퓨터 구조론을 공부하는 것과 컴퓨터를 만드는 일에는 아주 큰 격차가 있다는 사실을 알아야 한다.

만일, 여러분이 컴퓨터를 만들고 싶다면 납땜질을 배우거나 원칩 마이크로 컴퓨터를 공부하는 것이 훨씬 빠를 것이다.


운영체제

강좌내용 : 컴퓨터와 운영체제의 구조, 가상 기억 장치, 멀티 태스킹, 프로세스 스케쥴링 등의 기본 개념 및 이들과 관련된 이슈를 공부한다.

대부분의 강좌에서 유닉스 운영체제의 구조와 작동원리를 실사례로 많이 사용한다. 유닉스는 C로 소스가 쓰여 있어 구체적으로 설명하기에 좋기 때문이다.

운영체제는 프로그램이 운영되는 환경을 제공하기 때문에 운영체제론은 소프트웨어를 개발하는 사람들에게 중요한 내용을 많이 담고 있다. 물론 메모리 관리, CPU 스케쥴링 알고리즘, 주변장치 관리 등에 대한 학습이 실제 코딩에 직접 사용되지 않더라도, 조금 규모가 있는 소프트웨어를 제작하는 경우 운영체제가 갖고 있는 여러 가지 정책에 대한 구현은 여러분이 소프트웨어 아키텍처를 설계하는 데 적지 않은 도움을 준다. 특히 '무슨 무슨 서버'라는 이름이 붙는 소프트웨어를 만든다면, 운영체제 전반에 대한 이해는 아주 필수적이다.


자료구조와 알고리즘

강좌내용 : 컴퓨터 프로그램 설계에 널리 사용되는 자료구조와 알고리즘, 알고리즘에 대한 복잡도를 분석하는 방법 등을 제공하며 각종 검색, 정렬 프로그래밍을 통해 실제로 구현해 보고 복잡도를 분석한다.

일반적인 애플리케이션에서 자료구조를 직접 설계하고 구현할 필요성은 점차 줄어들고 있다. 자료구조의 많은 내용이 클래스 라이브러리로 구축돼 이를 잘 활용하거나 데이터베이스에 자료를 저장하는 것이 일반화적인 현상으로 자리잡았기 때문이다. 비정형화된 자료는 복잡한 자료구조를 쓰는 것보다 XML로 저장하거나 전송하는 것이 상당히 보편화됐다.

예를 들어 C++ 프로그래머가 직접 자료구조를 만들지 않아도 되도록 CArray, CList, CMap 같은 세 개의 클래스는 각각 가변 길이 배열, 양방향 리스트, 해시를 구현하고 있다. 이 정도면 웬만한 비즈니스 애플리케이션을 작성하기에 충분하다.

마찬가지로 자바도 이런 기능을 가진 벡터나 해시 테이블 등을 클래스 라이브러리로 제공하고 있다. 더 고급 기능이 필요하면 직접 작성하는 것보다는 표준화한 자료구조와 알고리즘을 제공하는 C++의 STL을 이용해도 된다. 하지만, 자료구조나 알고리즘에 대한 이해 없이 이런 내용을 사용하는 것은 불가능하다.

자료구조는 적어도 양방향 리스트를 자신이 사용하는 언어로 직접 구현하는 수준까지 해봐야 한다. 대부분 프로그래머가 메모리 기반의 정렬/탐색 알고리즘은 기본으로 공부하지만, 실제는 파일 기반의 탐색과 정렬이 오히려 더 중요할 수 있다. 따라서 정렬의 경우 파일 기반의 병합 정렬 정도까지 마스터하는 것이 좋다.


프로그래밍 언어와 컴파일러

강좌내용 : 각종 언어의 특성을 서로 비교하며 프로그래밍 언어의 문법 및 데이터 타입 등을 다룬다. 논리 언어, 함수 언어, 그리고 객체 지향 언어의 특성 및 응용 분야 등이 여기에 해당한다. 컴파일러는 오토머터(Automata) 구성, 어휘 분석(lexical analysis) 등을 학습하고, 컴파일러 제작도구인 Lex나 Yacc를 이용해 간단한 언어를 만들어 본다.

컴파일러는 무척 복잡하고 까다로운 분야 중 하나다. HTML, XML과 같은 마크업 언어가 널리 사용되면서 컴파일러의 한 부분인 파서에 대한 관심이 높아졌으며, 이에 따라 공개된 파서도 많이 등장했다. 여러분의 애플리케이션에서 파서가 필요하고 이를 직접 구현해야 한다면 컴파일러 이론이 필요하겠지만, 흔하지 않은 일이다.


데이터베이스

강좌내용 : 주로 관계형 데이터베이스 구조와 동작 등에 대한 이슈를 공부하며, 정규화 방법과 데이터베이스 설계, 튜닝 등에 필요한 여러 가지 이론을 공부한다.

대부분의 애플리케이션에서 데이터베이스 사용은 필수적인 사항으로 SQL, ERD 작성, 정규화, 설계, 구축, 데이터베이스 애플리케이션 작성 등은 대부분의 개발자에게 요구되는 기술이 됐다. 특히 SQL에 대한 이해와 사용이 가장 중요하며, 데이터베이스 설계에 대한 이해가 필수적이다.


중요하지 않은 것은 하나도 없다

전산학의 기초를 이루고 있는 다섯 분야 중 실제 프로그래밍이나 소프트웨어 개발에 가장 크게 도움이 되는 분야를 꼽으라면, 주저 없이 '운영체제론'을 꼽을 것이다. 만일, 여러분의 팀에서 시간적 여유가 좀 있고, BOOK GROUP(특정한 책을 함께 공부하는 한시적인 학습 조직)을 운영한다면 운영체제론에 대한 학습을 가장 추천하고 싶다.

특히 (여러분이 윈도우를 쓴다고 해도) 유닉스에 대한 학습은 아주 필수적인 코스 중 하나다(여기서 말하는 학습은 유닉스 명령어나 사용법을 말하는 것이 아니다). 윈도우 2000의 내부적인 구성이 이전 버전과 비교해 유닉스를 많이 닮았다는 점과 맥 OS X이 완전히 유닉스 기반이라는 점은 시사하는 바가 크다. 보안과 관련해 네트워킹을 공부하는 사람이라면 유닉스는 더욱 중요하다. TCP/IP 등 대부분의 인터넷 관련 프로토콜이나 기반기술이 유닉스를 기반으로 하고 있기 때문이다.

자바 VM(Java Virtual Machine, 이하 JVM)은 운영체제와 그 역사가 전혀 다르지만, 자바 애플리케이션 입장에서 보면 JVM도 하나의 운영체제다. 시스템 프로그래밍을 하는 프로그래머가 운영체제에 대한 전반적인 지식을 필요로 하는 것과 마찬가지로, 자바 프로그래머들은 자신이 사용하고 있는 JVM의 특성에 대해 학습할 필요가 있다.

자바를 깊이 있게 다루는 프로그래머는 거의 한결 같이 자바가 100% 플랫폼 독립적이지는 않다고 말한다(아마도 정도의 문제일 것이다). 자바 기술은 대부분 썬이 스펙을 제공하고, 이를 여러 회사들이 구현하고 있다. JVM만 봐도 그렇다.

썬, 마이크로소프트, IBM 등 유수의 업체들이 나름대로 구현한 JVM을 내놓고 있으며 안정성, API 구현상의 특이점, 확장 기능 제공면에서 차이를 보이고 있다. 가끔은 이런 차이가 특정 JVM을 선택하는 기준이 되기도 한다. 또한 JVM 자체가 운영체제 위에서 운영되는 애플리케이션이기 때문에 JVM의 구현 특성과 운영체제의 환경을 무시할 수 없다.

그 다음으로 중요한 분야를 꼽는다면 '데이터베이스', '자료구조와 알고리즘'이다. 객체지향 데이터베이스(Object-Oriented DBMS)가 주목을 받아 많은 연구가 수행되고 있지만, 관계형 데이터베이스(Relational DBMS)를 완전히 대체하지는 못하고 있다(현재는 RDB에 ODB의 특성을 가미한 ORDB가 사실상의 표준이다).

이제 데이터베이스 프로그래밍은 더 이상 특수한 분야가 아니다. 대부분의 애플리케이션이 인터넷을 기반으로 하고 있고, 기본적으로 데이터베이스를 사용하고 있기 때문이다.

<표 1>은 이 다섯 분야의 교재로, 가장 널리 사용되는 책을 나열한 것이다(분야별로 다른 좋은 책이 많이 있으나 개인적 체험에 입각해 한 개씩 선정한 것이다). 이 책들은 모두 번역서도 있다.

<표 1> 분야별 대표적인 교재

과목
저서
컴퓨터 구조론
Computer System Architecture 2/e, M. Morris Mano, Prentice-Hall, 1982
운영체제론
Operating System Concepts 4/e, Avi Silberschatz, Peter Galvin, Addision Wesley Longman, Inc., 1998.
자료구조와 알고리즘
Fundamentals of DATA STRUCTURES in C++, Horowitz & Sahni, Computer Sci. Press, 1995.
컴파일러
Compilers: Principles, Techniques, and Tools, Alfred Aho, Ravi Sethi,Jeffrey Ullman, Addison-Wesley, 1986.
데이터베이스론
An introduction to Database Systems 6/e, C.J.Date, Addison-Wesley, 1995.



그 밖의 분야들

앞서 말한 분야 외에 소프트웨어 공학, 네트워크, 인공지능 같은 분야도 이에 못지 않게 기반이 되는 분야이다.

소프트웨어 공학은 분석 설계 구현을 큰 축으로 하는 소프트웨어 개발의 생명 주기를 바탕으로 개발시 여러 단계와 각 단계에서 발생하는 이슈를 주로 다룬다. 요즘은 객체지향 방법론과 분석/설계에 대한 내용이 많이 보강되고 있다. 네트워크는 주로 네트워킹의 기본 이론이 되는 OSI 7 계층에 대한 내용과 프로토콜 관련 이슈가 주류를 이룬다. 인공지능에선 문제 해결, 자연어 처리, 지식 처리, 추론 머신, 로보틱스, 에이전트 등의 연구가 진행되고 있다.

이 세 가지의 분야에 대한 지식은 간접적으로 소프트웨어 개발에 많은 '꺼리'를 던져준다. 실무에서 일하는 개발자들은 이들 분야에 대해선 지나치게 원론적인 이론서보다는 한 단계 쉽고 구체적인 안내서를 읽는 것이 훨씬 좋다.


프로세스의 메모리 구조

프로세스에 대한 이해는 프로그래밍의 핵심이라고 할 수 있다. 프로세스는 간단하게 '수행중인 프로그램'이라고 정의할 수 있다(참고로 프로그램은 수행 가능한 디스크상의 이미지라고 정의할 수 있다). 다시 말해, 프로세스는 디스크에 저장돼 있던 실행 가능한 프로그램이 메모리에 적재돼 운영체제의 제어를 받는 상태를 말한다.

프로그램을 작성해 컴파일하고 링크하면 실행 가능한 파일이 생성된다(윈도우라면 *.exe라는 파일이, 유닉스라면 기본적으로 a.out이라는 파일이 생성된다). 쉘을 통해 사용자가 프로그램을 수행시키면, 커널은 이 프로그램을 제어에 적합한 자료구조로 만들어 메모리로 읽어낸 후, 커널의 프로세스 테이블에 등록하고, 메모리, 파일, 입출력 장치 같은 자원을 할당하는데, 이때부터 프로그램은 커널의 한 프로세스로서 실행 상태가 된다.

프로세스는 Win32의 경우에 CreateProcess(), 유닉스의 경우에는 fork() 시스템 콜을 사용해 새로운 프로세스를 생성하고, 프로세스간에는 다양한 IPC(Inter-Process Communication) 방법을 통해 데이터를 교환하거나 프로세스간의 동기화를 수행한다.

<그림 1>은 프로그램이 메모리에 적재된 모습을 나타낸다. 이 구조는 유닉스와 윈도우가 크게 다르지 않다 (JVM에서 돌아가는 자바 프로그램도 비슷한 구조를 갖는다). 그림에서 위쪽이 낮은 주소번지가 된다. 그림에서 보이는 네 개의 범위(텍스트, 데이터, 힙, 스택)를 각각 세그먼트라고 한다.

각 세그먼트에 대해 좀더 자세하게 알아보자(여기서는 유닉스와 C를 기준으로 서술하지만, 윈도우에서도 공통적인 특성을 갖는다).

◆ 텍스트 : 프로그램의 실행 코드인 기계어 코드와 읽기 전용 데이터 등을 가진다(CPU가 읽어들여 수행한다고 해서 텍스트라고 부르며, 코드 영역이라고도 한다).

◆ 데이터 : C언어에서 전역 변수, 정적 변수 등으로 선언된 변수 영역(읽기/쓰기 가능)

◆ 힙 : 프로그램 수행 중 malloc(), free() 등의 시스템 콜로 할당되고, 해지되는 메모리 영역

◆ 스택 : C언어의 함수 호출시 지역 변수와 인수, 함수의 수행이 끝났을 때 리턴할 주소(return address)를 푸시한다(함수가 끝나면 이 값을 팝하고 리턴하게 된다).

운영체제는 프로그램의 텍스트 부분에 메모리를 읽기 전용으로만 사용하고, 프로세스간에는 메모리 영역을 침범하지 못하도록 한다. 따라서, 프로그램의 텍스트로 되어 있는 메모리 영역을 침범해 기록하면 버스 에러나 세그먼트 결함이 일어나서 프로그램이 종료된다. 여러분은 윈도우에서 '잘못된 연산을 수행해 프로그램을 종료합니다'란 메시지를 본적이 있을 것이다. 이 에러(잘못된 연산)의 95% 이상이 바로 앞서 이런 연유에서 발생한다.

C/C++와 같이 포인터(주소를 갖는 변수)를 사용해 메모리를 직접 액세스하는 언어로 개발할 때도 흔히 이와 같은 에러가 발생한다. 따라서 프로그램을 개발할 때 가장 중요한 점이 바로 메모리 관리다. 프로그램 오류의 80% 이상을 차지하는 이유를 살펴보면 다음과 같다.

◆ 초기화
◆ 해지

자바는 가비지 컬렉션을 통해 사용하지 않는 메모리를 자동으로 해지하지만, 필요에 따라 명시해 주는 것이 좋다. C/C++에서는 쓰지 않는 메모리에 대해 반드시 명시적으로 delete를 써줘야 한다.

C/C++는 할당된 메모리에 대한 포인터를 잃어버리는 경우가 생기는데, 이를 메모리 누수라고 한다.

메모리 누수는 프로그래머를 괴롭히는 가장 큰 골칫거리 중 하나다. 꼼꼼히 확인하는 습관을 들이는 것이 좋다.

 

멀티로 시작하는 단어의 사용

멀티 프로그래밍, 멀티 프로세싱, 멀티 태스킹, 멀티 쓰레드, 멀티 유저는 비슷비슷한 용어이기 때문에 혼돈해 사용하지만 의미가 모두 다르다.

◆ 멀티 프로그래밍 : 여러 프로그램이 메모리에 적재돼 수행되는 것. 하나의 프로그램이 수행되다가 입출력을 하면 CPU는 다른 프로그램으로 제어권을 넘긴다. 즉, 프로그램의 입출력을 기준으로 프로그램 수행의 스위칭이 일어난다(요즘은 좀처럼 쓰이지 않는 말이다).

◆ 멀티 프로세싱 : 다수의 프로세서가 작업을 처리하는 것. 운영체제가 멀티 프로세싱을 지원한다는 것은 다수의 CPU를 지원할 수 있다는 뜻이다. 여러 CPU가 운영체제와 메모리를 공유해 프로그램을 수행하는 방식을 SMP(대칭형 멀티 프로세싱)라고 한다(윈도우 NT가 이런 방식이다).

◆ 멀티 태스킹(시분할 시스템) : 태스크(Task, 운영체제가 수행하는 기본 단위)가 여럿인 것. 운영체제가 강제로 CPU 시간을 프로세스에 할당한다.

◆ 멀티 유저 : 멀티 유저는 기본적으로 멀티 태스킹이 되는 시스템에 다중 사용자 파일 시스템 등 다중 사용자를 지원하기 위한 기능을 추가한 것이다.

◆ 멀티 쓰레드 : 하나의 프로세스 내에 여러 개의 수행경로가 존재하고, 이를 동시에 수행하는 것. 하나의 프로세스가 동시에 두 가지 이상의 작업을 수행하는데 활용된다(쉽게 말해 프로세스 내에서 멀티 태스킹을 하는 것이라고 볼 수 있다).

여기서 멀티 쓰레드에 대해 좀더 구체적으로 알아보자. 쓰레드는 '수행 경로'라고 정의할 수 있다.

CPU가 텍스트(코드)를 읽어 수행할 때 수행되는 절차를 하나의 수행 경로라고 한다. 멀티 쓰레드란 결국 이런 수행 경로가 여러 개 있다는 뜻이다. 멀티 쓰레드도 멀티 태스킹과 마찬가지로 기본적으로 여러 쓰레드를 번갈아 수행한다. 텍스트, 데이터, 힙, 스택의 각 세그먼트에 대한 주소를 CPU 레지스터에 담고 있는데, 이 레지스터의 내용을 바꿔(컨텍스트 스위칭) 다른 쓰레드를 수행하도록 한다. 쓰레드 간에 프로세스가 갖고 있는 메모리와 코드 영역을 공유하므로, 컨텍스트 스위칭할 때 레지스터의 내용을 조금만 바꿔도 멀티 태스킹에 비해 컨텍스트 스위칭 하는 속도가 빠르다.

멀티 태스킹이나 멀티 쓰레드는 두 개 이상의 작업이 동시에 수행되므로, 동시에 수행되는 작업에 대해 동기화가 필연적으로 필요하다.

자바는 언어 차원에서 동기화를 지원한다. synchronized 키워드를 이용해 손쉽게 동기화를 구현할 수 있지만, 꼭 필요할 때만 사용하는 것이 좋다. synchronized를 사용한 것이 사용하지 않은 코드에 비해 약 3∼4배정도 느려지기 때문이다. 대부분의 유닉스와 윈도우는 운영체제 차원에서 Event, Critical Section, Mutex, Semaphore 등의 동기화 메커니즘을 제공한다.


객체지향 방법론과 UML

요즘 소프트웨어 전반에 '객체지향'이란 말이 붙지 않은 분야가 없다. 객체지향 데이터베이스, 객체지향 프로그래밍 언어뿐만 아니라 소프트웨어 공학에도 객체지향 분석/설계, 방법론이 널리 사용되고 있다. 이제 UML(Unified Modeling Language)은 정착 단계에 들어섰다. 어느 글을 보든지, 표기법은 기본적으로 모두 UML을 사용하고 있다.

하지만 많은 사람들이 UML을 오해하고 있는데, 그 중 가장 대표적인 두 가지만 살펴보겠다.

1. UML은 객체지향 방법론이다.
2. UML은 프로젝트를 진행하는 데 생기는 많은 기술적인 문제를 푸는 데 도움이 된다.

UML은 방법론(methodology)이 아니다. UML은 표기법(notation)이다. 많은 사람들이 UML을 일종의 방법론처럼 생각하고 있는데, UML은 객체지향 분석/설계의 결과를 표시하는 표준적인 표기법을 제공할 뿐이지 UML 자체가 무엇인가를 해주는 것은 아니다. 방법론이라고 얘기하려면 표기법과 함께 공정을 갖고 있어야 한다.

방법론 = 표기법 + 공정

하지만 UML은 공정을 포함하고 있지 않다. 따라서 RUP(Rational Unified Process)를 쓰거나 자체의 고유한 공정을 써도 좋다는 얘기가 된다.

또 한 가지 사실은 UML을 쓰더라도 여전히 기술적인 문제들은 그대로 남아 있다는 점이다. 기술적인 문제는 어떤 방법론을 쓰건 방법론과는 별개로 풀어야 할 과제로 남게 된다.

그렇다면 왜 UML을 사용하는가. 그 답은 '남들이 모두 쓰니까'다. 우스개 소리 같지만 사실이자 곧 현실이다. 좀더 고상하게 말해 표준이기 때문이다. UML은 개발자간 혹은 개발자와 고객간의 의사소통에 있어 표준적인 형태를 제공한다는 데 가장 큰 의의가 있다. 사실 시스템을 분석/설계하는 것은 표기법이나 공정보다 '경험'이 훨씬 중요하다. 필자는 '경험'을 앞서는 것은 아무 것도 없다고 본다.

<그림 2> UML의 클래스 다이어그램



많은 사람이 재사용을 부르짖고 객체지향의 가장 큰 장점을 재사용에서 찾고 있지만, 실제 여러분의 프로젝트에서 얼마나 많은 코드가 재사용되고 있는지 돌이켜 보라.

재사용이 가장 잘 적용되는 분야가 바로 컴포넌트 기반의 개발(CBD; Component Based Development)이다. 그렇지만 실제 프로젝트에서 컴포넌트를 만들고 조립하는 역할과 배분이 그리 쉽게 이뤄지지는 않는다. 결국 객체지향론이나 재사용, CBD 등은 프로젝트를 진행하는 데 좀더 도움이 되도록 하는 독려의 대상이지 그 자체가 목적이 될 수는 없다. 소프트웨어 분야에서는 아무리 좋은 개념에 아무리 좋은 제품이라도 실제 활용되지 않으면 아무 소용이 없다.


컴퓨터와 수학

컴퓨터의 구조 자체가 수학이라는 것을 아는 사람은 생각보다 그리 많지 않은 것 같다.

사실 컴퓨터의 아키텍처는 부울 대수이고, 관계형 데이터베이스는 수학의 집합론을 그대로 옮겨 놓은 것이다. 관계형 데이터베이스가 계층형 데이터베이스나 네트워크 데이터베이스를 제치고 70년대부터 지금까지 널리 쓰이는 까닭은 수학적 이론을 바탕으로 했기 때문에 가능했다는 말도 있다.

물론 수학에 대한 이해와 지식이 있는 경우 프로그래밍을 하는 데 많은 도움을 받는 것은 사실이지만 절대 필수적인 것은 아니다. 어쩌면 중학교 3학년 정도의 수학이면 충분하다고 볼 수도 있다.

고등학교 이상의 수학 실력이 필요한 분야는 컴퓨터 그래픽스다(컴퓨터 그래픽스를 프로그래밍으로 접근하는 경우). 만일 보다 심도 깊은 연구가 필요하다면, 이산 수학(Discrete Mathematics)이라는 수학분야를 공부할 것을 권한다. 이산 수학은 전산학의 기초 이론을 수학적인 입장에서 다룬다. 수학이라는 학문에서 가장 중요하다는 무한(Infinity)와 연속(Continuity)을 뺀 수학이라고 보면 틀리지 않는다.


미래를 좌우하는 것

인터넷의 확산은 엔터프라이즈 애플리케이션과 데스크톱 애플리케이션의 경계를 허물었고, 소프트웨어 산업전체를 뒤집어 놓았다. 대부분의 애플리케이션 개발은 웹 기반으로 전환됐으며, 인터넷을 빼놓고선 소프트웨어를 말하기가 힘들어졌다.

그 다음은 무엇인가. 그것은 바로 '모바일'일 것이라는 점에 많은 사람이 공감을 표시하고 있다.

모바일 시장의 활성화에 따라 특수 목적의 운영체제나 하드웨어가 각광받을 것이고 더욱 더 많은 기술이 발표될 것이다. 현재도 기술은 약어집이 필요할 정도로 쏟아져 나오고 있다. 따라서 점차 코딩은 기술과 기술을 묶어내는 도구로 사용되고 있다.

많은 플랫폼과 언어가 흥망성쇠를 거듭해 가면서 발전하고 있지만, 기본과 기반기술은 크게 변하지 않았다. 하드웨어 구조 자체가 '폰 노이만 구조(stored program)'를 벗어나지 않고 있고, 소프트웨어의 모든 기술이 이전 기술을 바탕에 두고 시작하기 때문이다.

UML을 예로 들어보자. UML은 사실 전혀 새로운 것이 아니다. 이전의 여러 기술과 개념을 종합하고 표준화했을 뿐이다. C#도 C++, 스몰토크, 자바와 같은 조상 언어와 COM/DCOM에 기반해 만들어졌다.

필자는 개인적으로 향후 대중적인 프로그래밍 언어의 대표 주자는 자바와 C#이 될 것으로 점치고 있다. C#은 클래스 라이브러리 전체가 COM 객체로 구성돼 있고, 자바는 EJB를 통해 CBD를 지원하고 있다. JVM과 .NET 플랫폼을 보면 재사용 가능한 컴포넌트가 플랫폼에 흡수되는 것을 볼 수 있다.

이런 얘기가 사뭇 다르게 들릴지 몰라도, 조금만 깊게 살펴보면 실은 비슷한 개념의 기반기술을 배경으로 하고 있다는 것을 알 수 있다.

웹뿐만 아니라 다른 서비스에도 XML과 SOAP는 더욱 더 많이 쓰이게 될 것이다(XML과 SOAP는 여러 가지 기능을 묶어내고 연결하는 기본적인 방법이 될 것이다). 이제 개발자들에게는 네트워크를 기반으로 다양한 지식을 자신이 선호하는 언어로 요리해 엮어내고 연결할 수 있는 자질이 요구되고 있다. @

참고 문헌
Operating System Concepts 3/e, A. Silberschatz, J. Peterson, P. Galvin, Addison-Wesley, 1992

Digital Logic and Computer Design, M. Morris Mano, Prentice-Hall, 1979

Computer System Architecture 2/e, M. Morris Mano, Prentice-Hall, 1982

Computer Organization and Architecture: Principles of Structure and Function, William Stallings, Macmillan Publishing Company, 1987

Discrete Mathematics with Computer Science Applications, Skvarcius, Robinson, The Benjamin/Cummings Publishing Company, 1986

Fundamentals of Data Structures in C++, Ellis Horowitz, Sartaj Sahni and Dinesh Mehta, Computer Science Press, 1995

Introduction to Algorithms: A Creative Approach, Udi Manber, Addison-Wesley Publishing Company, 1989

Object Lifecycles, Sally Shlaer, Stephen J. Mellor, Prentice-Hall, New Jersey, 1992

Object-Oriented Modeling and Design, J. Rumbaugh, M. Blaha, W
. Premerlani, F. Eddy, W. Lorensen, Prentice-Hall, 1991



출처 : 마이크로 소프트 웨어




웹마스터되기

댓글