지은이 / Hisao Yazawa | 옮긴이 / 이영란
성공과 실패를 결정하는 1%의 컴퓨터 원리
2004년 1월 10일 1판 1쇄 발행
글쓴이 : Hisao Yazawa
번역 : 이영란
펴낸곳 : 성인당(서울특별시 마포구 서교동 353-4)
프로그래밍에서는 한 단위의 명령군에 이름을 붙여서 ‘함수’, ‘문장’, ‘메쏘드’, ‘서브루틴’, ‘하위 프로그램’ 등으로 부릅니다. 여담이지만 컴퓨터 업계에서는 동일한 것을 나타내는 데 다양한 용어를 사용한다는 것에 주의하기 바랍니다. 이것들을 어떤 하나의 이름으로 부르고 싶다면 일반적으로 쉽게 통하는 함수(function)라고 부르면 됩니다. [25p]
컴퓨터의 사정의 대표적인 예는 모든 정보를 수치로 나타내는 것입니다. 이것이야말로 인간의 감각에 맞지 않는 가장 첫 번째 사정이겠지요. [28p]
.NET
컴퓨터란 프로그램을 작동시키기 위한 것이다. 프로그램은 명령과 데이터의 집합체이다. 마이크로소프트는 인터넷으로 서로 연결된 컴퓨터를 프로그램적으로 연결시키기 위해 SOAP 및 XML이라는 방법을 사용하고 있다. SOAP는 명령을 호출하기 위한 방법이며, XML은 데이터 형식을 방법이다.
명령과 데이터의 방법이 있으면 그에 따르는 프로그램을 가진 컴퓨터를 서로 연결할 수 있는 것은 당연하다. 컴퓨터의 연결이란 하나의 컴퓨터에 입력된 데이터가 인터넷으로 연결된 다른 컴퓨터로 보내져 연산되고, 그 출력 결과를 원래 컴퓨터에 되돌리는 것이다. 다른 컴퓨터에 있는 연산을 수행해 주는 프로그램을 XML 웹 서비스라고 한다. [30p]
하이 임피던스
컴퓨터는 0또는 1밖에 판별할 수 없고, 컴퓨터에 사용되는 모든 부품들도 그렇습니다. 그렇기 때문에 컴퓨터에서는 보통 +5V의 전압이 흐르는 선은 1, 0V의 전압이면 0으로 판별해서 분류하고 있습니다. 0V라는 것이 이상하게 들릴지 모르겠지만 이것은 ‘연결한 양쪽의 전위 차가 없어서 전류가 흐르지 않는다’는 상태인 것입니다. 말하자면 전선의 양끝을 모두 똑같이 +극에 연결한 것과 같은 상황입니다.
그런데 경우에 따라서, ‘연결했지만 전류가 흐르지 않는다’가 아닌, ‘연결하지 않은’ 상태가 필요할 때가 있습니다. 분명히 선이 연결되어 있지만 연결되지 않은 것과 같은 상태를 바로 하이 임피던스라고 합니다. 회로에서 일부분이 하이임피던스가 되었다는 것은 회로가 끊어진 것과 같은 상태가 되었다고 보면 됩니다. 물론 실제로 끊어진 것은 아니므로 나중에 다시 +5V나 0V 상태로 전환될 수 있습니다. [50p]
프로그램의 세 가지 흐름은 강의 흐름과 똑같습니다. 산 위의 샘에서 솟아나온 맑은 물이 흐름의 시작입니다(프로그램의 실행 시작 위치). 산을 흘러 내려오는 물은 똑바로 흐르기도 하고(순차 진행), 도중에 줄기가 갈라지기도 하고(조건 분기), 경우에 따라 소용돌이(반복)를 치기도 합니다. [91p]
구조화된 프로그래밍은 다익스트라(Dijkstra)라는 학자가 개발한 프로그래밍 스타일입니다. 구조화된 프로그래밍이란 무엇인지 간단히 설명하자면 ‘프로그램을 구조적으로 만들자. 그러기 위해서는 프로그램의 흐름을 순차 진행, 조건 분기, 반복만으로 나타내고, 분기 명령을 사용하지 않도록 하자’라는 것입니다. 프로그램의 흐름을 순차 진행, 조건 분기, 반복만으로 나타낸다고 하는 것은 당연하지만, 무조건 분기 명령을 사용하지 않는다는 것에 주목해주세요. -중력- 분기 명령은 프로그램을 프로그램의 흐름이 복잡하게 얽혀있는 ‘스파게티 코드’로 만들 위험이 높기 때문입니다. [102p]
.NET(닷넷이라고 읽습니다)이란, 마이크로소프트가 내놓은 새로운 컴퓨팅 패러다임으로, 원래는 굉장히 여러 가지를 포함하는 매우 큰 개념입니다. 하지만 프로그래밍에 해당하는 Visual Studio .NET에 대해서만 얘기하면, 컴파일해서 원시 코드(Native Code)를 만들지 않고 닷넷 프레임워크라는 프로그램이 이해할 수 있는 중간 코드(Pseudo Code)만 만듭니다. 그리고 실제 실행할 때는 닷넷 프레임워크가 이 중간 코드를 해석하여 실행시켜 줍니다. 이 방법의 장점은 한번 닷넷으로 컴파일한 프로그램은 닷넷 프레임워크가 있는 곳에서는 어디든 실행될 수 잇다는 것입니다. 윈도우용 프로그램은 유닉스나 리눅스에서 실행되지 않지만, 유닉스/리눅스용 닷넷 프레임워크를 설치하고, 여기서 닷넷으로 컴파일한 프로그램을 돌린다면 윈도우용 닷넷 프로그램이 훌륭하게 구동될 수 있습니다. 도한 닷넷은 모든 언어가 동일한 중간 코드를 만들기 때문에 언어에 구애 받지 않고 잘 사용하는 언어로 필요한 프로그램을 만들 수 있다는 장점도 잇습니다. [103p]
저항의 색 코드 암기법
‘까만 동그라미, 갈색 커피 한잔, 빨리와, 제3의 주홍글시, 노찾사, 초록의 오월, 파육지세, 보라돌이 칠남매, 회색빛 팔팔담배재, 하얀 비둘기 구구’
0 1 2 3 4 5 6 7 8 9 [115p]
마지막으로 무엇보다 중요한 포인트를 설명하겠습니다. 그것은 ‘알고리즘을 생각할 때는 갑자기 프로그램을 입력해 넣는 것이 아니라 종이 위에 문서나 그림으로 절차를 그려본다는 것’입니다. [136p]
프로그램을 작성하는 사람은 알고리즘(처리의 절차)과 데이터 구조(처리의 대상이 되는 데이터 나열 방법), 이 두 가지를 함께 생각해야 합니다. 알고리즘에 알맞은 데이터 구조, 데이터 구조에 알맞은 알고리즘이 필요하기 때문입니다. [139p]
배열은 데이터 구조라고 할 수 있습니다. 배열이 메모리의 물리적 구조 그 자체이기 때문입니다. 메모리에는 데이터를 저장하기 위한 영역이 연속적으로 나열됩니다. 프로그램에서는 메모리 전체 중에서 필요한 영역을 확보하여 사용합니다. 이것을 프로그램 구문으로 나타내면 배열이 되는 것입니다. [146p]
스택 // 데이터를 산처럼 쌓아올린다.
큐 // 데이터를 행렬처럼 나열한다.
리스트 // 데이터의 나열 순서를 임의로 변경한다.
이진 트리 // 데이터의 나열 방법을 두 가지로 나눈다. [149p]
스택을 구현하려면 먼저 스택의 크기(스택에 저장할 수 있는 최대 데이터수)를 요소 개수로 한 배열과 스택의 맨 위에 저장될 데이터의 인덱스를 나타내는 변수를 선언합니다. 이 변수를 ‘스택 포인터(stack pointer)’라고 합니다. 스택의 크기는 프로그램의 목적에 따라 임의로 정합니다. [152p]
큐를 구현하기 위해서는 임의의 크기의 배열, 큐의 첫 번재 데이터의 인덱스를 나타내는 변수, 큐의 마지막 데이터의 인덱스를 나타내는 변수, 큐에 데이터를 저장하는 함수와 큐에서 데이터를 꺼내는 함수가 쌍으로 필요합니다. 배열의 끝까지 데이터를 저장했다면 그 다음 저장 위치는 배열의 맨 처음으로 돌아오도록 합니다. 이렇게 배열의 끝과 처음을 연결하므로 물리적으로는 ‘직선’인 배열이 논리적으로 ‘고리’가 됩니다. [153p]
객체 지향 프로그래밍을 위한 설계에서는 사방에 흩어져 있는 함수와 변수를 나중에 클래스로 그룹화하는 것이 아닙니다. 처음부터 필요한 수만큼 클래스를 정하고, 나중에 각 클래스가 가져야 할 함수와 변수를 열거해 나갑니다. 즉, 프로그램의 대상이 되는 현실 세계를 보고 ‘어떤 사물(클래스)로 구성되어 있을까’라고 생각하는 것입니다. [174p]
상속은 기존의 클래스가 갖고 있는 멤버를 이어받아 새로운 클래스를 만드는 것입니다. 캡슐화는 클래스가 갖고 있는 멤버 중에서 클래스 사용자에게 보일 필요가 없는 것을 숨기는 것입니다. 다형성이란 같은 메시지에 대해 객체가 여러 형태의 조작을 수행하는 것입니다. [177p]
클래스를 사용하는 사람은 세 가지 방법으로 클래스를 사용할 수 있다는 것을 알아두세요. 클래스가 갖고 잇는 멤버(함수와 변수)를 개별적으로 사용하기만 하는 방법, 클래스의 정의 안에 다른 클래스를 포함시키는 방법(집약이라고함), 기존의 클래스를 상속해서 새로운 클래스를 정의하는 방법입니다. [181p]
마지막으로 프로그램이 객체 지향 프로그래밍에서 벗어날 수 없는 이유를 설명하겠습니다. 그것은 앞으로 개발 환경으로 Java나 .NET이 주류가 될 것이기 때문입니다. Java와 .NET은 OS(윈도우나 리눅스 등) 상에 존재하고, OS의 복잡함을 숨김으로써 개발을 효율화하기 위한 프로그램 집합인 ‘프레임워크(framework)’라고 합니다. 프레임워크는 프로그램을 안전하게 실행해주는 ‘실행 엔진’과 프로그램의 부품들인 ‘클래스 라이브러리’로 구성되어 있습니다. [183p]
객체 지향 프로그래밍에 관한 다양한 접근 방법을 종합해서 정리하믕로써 객체 지향 프로그래밍의 전체 이미지를 잡았다고 생각하지만, 한 가지 주의할 것이 있습니다. 그것은 ‘객체 지향 프로그래밍을 학문이라고 생각하지 말라’는 것입니다. 프로그래머는 엔지니어입니다. 엔지니어링은 학문이 아니라 경제 활동입니다. 객체 지향 프로그래밍의 다양한 개념이나 프로그래밍 테크닉에 묶이지 말고, 효율적이고 유지-보수가 쉬운 프로그래밍 방법으로 적절한 장소에 객체 지향 프로그래밍을 ‘실천’해주세요. [184p]
키는 테이블간의 관계를 정의하는 것입니다. 인덱스를 데이터 검색 속도를 향상시키는 구조입니다. [189p]
‘일관되고 안전하게 유지한다’는 의미는 나중에 설명하기로 하고, 우선은 데이터베이스 시세틈의 구성 요소를 설명하겠습니다. 데이터베이스 시스템의 구성 요소는 ‘데이터 파일’, ‘DBMS’, ‘애플리케이션’ 이 세 가지입니다. 소규모 세시틈에서는 한 대의 PC상에 데이터 파일, DBMS, 애플리케이션을 모두 배치합니다. 이것을 ‘독립형 시스템(stand alone system)’이라고 합니다. 중간 규모 시스템에서는 한 대의 PC에 데이터 파일을 두고, 그것을 DBMS와 애플리케이션이 배치된 여러 대의 PC가 공유합니다. 이것을 ‘파일 공유 시스템’이라고 합니다. 대규모 시스템에서는 한 대(또는 여러 대)의 PC에 데이터 파일, DBMS를 두고, 그것을 애플리케이션이 있는 여러 대의 PC가 사용합니다. 이것을 ‘클라이언트/서버 시스템’이라고 합니다. 데이터 파일과 DBMS가 있는 PC가 서버(server, 서비스 제공자)이고, 애플리케이션이 있는 PC가 클라이언트(client, 서비스 사용자)가 됩니다. 서버와 클라이언트가 인터넷으로 연결되어 있다면 ‘웹 시스템’이 됩니다. 웹 시스템에서는 일반적으로 서버에 애플리케이션을 두고, 클라이언트에는 웹 브라우저만 둡니다. [192~193p]
여기서 데이터베이스 용어를 몇가지 기억해두세요. 관계형 데이터베이스에서는 테이블에 등록된 한 행의 데이터를 ‘레코드(record)’라고 합니다. 하나의 레코드를 구성하는 상품명, 단가 등의 항목을 ‘필드(field)’라고 합니다. 레코드를 ‘행’이나 ‘로우(row)’라고 하고, 필드를 ‘열’이나 ‘칼럼(column)’이라고도 합니다. 속성의 설정 대상이 되는 것은 필드입니다. 필드에는 저장되는 데이터를 대표하는 ‘필드명’을 붙입니다. [그림 8-5]에서는 하나의 레코드를 구성하는 여러 개의 필드를 설정하고 있습니다. 나중에 레코드를 등록해나가면 테이블이 완성됩니다. [195p]
문제는 두 가지 있습니다. 하나는 첫 번째와 두 번째 레코드에 있는 ‘성 이호, 서울시 마포구, 02-2222-2222’와 같이 똑같은 데이터를 여러 번 등록하지 않으면 안된다는 것입니다. 그러면 애플리케이션의 조작이 귀찮아지고 디스크 용량이 쓸데없이 낭비됩니다. 또 다른 문제는 세 번째 레코드처럼 ‘위스키’라고 입력해야 하는데 실수로 ‘우스키’라고 입력하면 실제로는 같은 상품인데 컴퓨터상에서는 다른 상품으로 인식되어 버린다는 것입니다. 즉, 테이블이 하나만 있다면 각 레코드가 한 장의 카드에 해당하는 카드형 데이터베이스와 똑같은 운용상 문제가 생길 경우가 있습니다.
관계형 데이터베이스의 설계에서는 이런 문제를 해결하기 위해 ‘정규화’라는 작업을 수행합니다. 정규화란 테이블을 여러 개로 나눠서 데이터베이스의 구조를 정리하는 것입니다. 정규화를 수행함으로써 보다 좋은 데이터베이스를 만들 수 있습니다. DBMS는 간단한 조작으로 비주얼적으로 정규화를 수행하는 도구도 제공하고 있습니다.
정규화의 핵심은 하나의 데이터베이스 안에 같은 데이터가 중복해서 기록되지 않도록 하는 것입니다. 여기서는 주류 판매 데이터베이스를 ‘상품 테이블’, ‘고객 테이블’, ‘매상 테이블’ 이 세 개로 나누고 관계(선으로 연결하는 부분)를 설정하고 있습니다. 이에 의해 같은 고객의 이름, 주소, 전화번호를 여러 번 입력할 수고를 덜고, 같은 상품의 이름을 잘못 입력하는 실수를 막을 수 있습니다.
다대다 관계가 되는 경우는 두 개의 테이블 사이에 하나의 다른 테이블을 추가하고 두 테이블을 일대다 관계로 나눌 수가 있습니다. 이런 테이블을 ‘연결 테이블(link table)’이라고 합니다. [196~197p]
캐스케이드 삭제(Cascade delete)
경우에 따라서는 참조무결성 때문에 불편할 때가 있습니다. 본문에서 예를 든 것처럼 참조무결성을 정의해 놓은 상품테이블에서 ‘소주’레코드를 삭제하려고 합니다. 원칙대로라면 판매 테이블에서 소주를 산 레코드가 존재하는 한 이 레코드는 삭제할 수 없습니다. 하지만 사용자의 명시적인 요청에 의해 예외적으로 ‘소주’ 레코드를 삭제할 수 있기도 합니다. 이때는 ‘소주’ 레코드를 삭제하면, 판매 테이블에서 소주를 산 레코드도 같이 자동으로 삭제하게 되는 것입니다. 삭제를 수행한 결과를 보면 참조무결성은 손상되지 않았지요. 이렇게 무결성을 유지하기 위해 참조 관계에 있는 테이블들의 데이터를 같이 삭제하는 방벙을 ‘캐스케이스 삭제(Casecade delete)’라고 하며, 많은 DBMS에서 옵션으로 제공하고 있습니다. [200p]
DBMS의 기능 중 하나로 테이블 각각의 필드에 ‘인덱스(index)’를 설정할 수 있습니다. 인덱스는 키와 혼동하기 쉽지만 전혀 다른 것입니다. 인덱스는 데이터의 검색과 정렬 속도를 향상시키는 내부적 장치에 지나지 않습니다. 필드에 인덱스를 설정하면 그 필드에 대한 인덱스 파일이 자동으로 만들어집니다. [201p]
검색과 정렬 속도가 향상된다면 모든 테이블의 모든 필드에 인덱스를 설정하면 좋지 않냐고 생각할 지도 모르겠습니다. 하지만 그런 것은 아닙니다. 인덱스를 설정하면 테이블에 레코드가 등록될 때마다 인덱스 테이블을 갱신하는 처리가 필요합니다. 검색과 정렬 속도가 향상되는 대신, 등록 속도가 저하되는 것입니다. 따라서 그 필드를 대상으로 자주 검색이나 정렬을 수행하는 경우에만 인덱스를 설정해야 합니다. 주류 판매 데이터베이스의 경우는 고객 테이블의 고객명 필드와 상품 테이블의 상품명 필드에만 인덱스를 설정하면 충분할 것입니다. [202p]
시스템 설계의 순서는 데이터베이스 설계가 먼저이고, 사용자 인터페이스 설계가 나중이라는 것을 기억해두세요. 이것은 아주 중요합니다. [203p]
데이터베이스 조작의 종류는 네 가지가 있습니다. 바로 레코드를 ‘추가’, 검색‘, ’새로 고침‘, ’삭제‘하는 것입니다. 데이터베이스 애플리케이션은 이 네 가지 조작이 가능하면 되는 것입니다. [203p]
MAC 주소는 하드웨어적으로 네트워크 카드를 식별하는 것이지만, 이것만 사용하면 좀 귀찮아집니다. 왜냐하면 기업 단위로 MAC 주소의 상위 자리를 정돈하는 그룹화가 불가능하기 때문입니다. 인터넷처럼 전세계 컴퓨터를 연결한 대규모 네트워크에서는 데이터의 수신처를 우편번호처럼 질서있게 식별하는 장치가 필요해집니다. 만일 MAC주소만으로 인터넷을 구현하면 어떻게 될까요? 인터넷으로 연결되어 있는 방대한 수의 컴퓨터에는 그룹화되어 있지 않은 번호(MAC 주소)가 있을 뿐입니다. 정보의 수신처를 찾는데 굉장한 시간이 걸릴 것입니다.
그래서 TCP/IP 네트워크에서는 하드웨어적인 MAC주소와는 별도의 소프트웨어적인 번호를 컴퓨터마다 설정하고 있습니다. 이 번호가 여러분이 알고 있는 ‘IP주소’입니다. [224p]
DHCP란 Dynamic Host Configuration Protocol의 약자로 동적으로 호스트를 설정하는 프로토콜이라는 뜻입니다. [226p]
라우터(router)란 그 이름처럼 경로(route)를 정하는 것입니다. 라우터도 LAN 상의 다른 컴퓨터와 똑같이 허브에 연결되어 있습니다. LAN 내부는 CSMA/CD방식이기 때문에 라우터에도 모든 송신 데이터가 보내집니다. 사내 컴퓨터에서 다른 회사의 컴퓨터로 데이터를 보내면 어떻게 될까요? 데이터의 LAN 상의 컴퓨터는 무시하지만 라우터는 무시하지 않습니다. 라우터는 IP 주소 중에서 네트워크 주소를 조사해서, 그것이 LAN 상의 컴퓨터에게 온 것이 아니라면 LAN의 외부 즉, 인터넷으로 보내는 장치입니다. [227p]
TCP/IP라는 말은 TCP와 IP 이 두 개의 프로토콜을 같이 사용하고 있다는 것을 의미합니다. IP는 지금까지 설명해왔듯이 데이터를 보내는 상대를 IP 주소로 지정하고, 라우팅 테이블을 전송하기 위한 프로토콜입니다. TCP는 데이터의 송신자와 수신자가 서로 상대를 확인하면서 확실히 데이터를 주고 받기 위한 프로토콜입니다. [234p]
XML이라는 말의 의미부터 설명하겠습니다. XML은 Extensible Markup Language의 약자로, 직역하자면 ‘확장 가능한 마크업 언어’가 됩니다. 먼저 ‘마크업 언어’란 무엇인지 설명하겠습니다. ‘확장 가능’에 관해서는 잠시 후 설명하겠습니다.
여러분은 이미 마크업 언어를 이용하고 있습니다. 예를 들면 웹 페이지를 작성하기 위한 HTML(Hypertext Markup Language)입니다. HTML은 마크업 언어입니다. 이 웹페이지의 실체는 자카르타 서울 프로젝트의 웹 서버에 있는 index.html이라는 HTML파일입니다. HTML 파일은 일반적으로 파일명의 확장자를 ‘.html’ 또는 ‘.htm’으로 합니다.
웹 브라우저의 ‘보기’ 메뉴에서 ‘소스’를 선택하면 윈도우에 있는 텍스트 편집기인 ‘메모장(notepad.exe)’이 자동으로 시작되고, index.html의 내용이 그대로 표시됩니다.
<html>,<head>,<title>,<body>등 ‘<’와 ‘>’로 둘러싸인 부분이 많이 있지요? 이것을 ‘태그(tag)’라고 합니다.<html>은 HTML파일이라는 것을 나타내는 태그입니다. 마찬가지로<head>헤더라는 것을,<title>은 웹 페이지의 타이틀이라는 것을,<body>는 웹 페이지의 본문이라는 것을, 각각 의미를 붙이고 있습니다. 문자열을 크게 굵게 하는<b>나 웹 페이지에 그림을 삽입하는<img>와 같은 태그도 있습니다.
태그에 의해 정보에 의미를 붙이는 행위를 ‘마크업(markup)’이라고 합니다. 이 의미를 붙이기 위한 약속을 정한 언어가 ‘마크업 언어’인 것입니다. HTML은 웹 페이지를 작성하기 위한 마크업 언어입니다. 좀 더 간단히 말하면 ‘웹 페이지를 작성하는데 사용 가능한 태그를 정한 것’이 HTML입니다.
즉, 사용 가능한 태그의 종류가 마크업 언어의 구조를 정하고 있다고 할 수 있습니다. [260~261p]
- HTML에서는 HTML에서 정해진 종류의 태그밖에 사용하지 못합니다. HTML은 ‘고정적인 마크업 언어’입니다. 이데 비해 XML은 ‘확장 가능한 마크업 언어’인 것입니다. 좀 머리가 혼란스러울지 모르겠지만 곧 HTML과 XML의 차이를 분명히 이해할 수 있을 것입니다. [262p]
- 비즈니스 세계에서는 다양한 의미를 가진 정보가 무수히 존재합니다. 업종이 바뀌면 정보의 종류도 달라집니다. 시대에 따라 새로운 업종도 생겨납니다. 모든 업종을 처리하려면 HTML 태그가 아무리 많아도 부족할 것입니다. 그래서 HTML의 사용은 어디까지나 웹 페이지를 표시한다는 비주얼적인 용도로 한정해두고, 새로 XML이라는 메타 언어가 고안된 것입니다. XML을 사용하여 업계 또는 특정의 용도마다 자유롭게 마크업 언어를 사용하라는 것입니다. 즉 XML의 용도는 ‘주로 인터넷에서 교환되는 정보에 의미를 붙이는 것’입니다. [267p]