프로그래밍언어론 2강 - 프로그래밍 언어의 발전 및 동작 원리
컴퓨터 시스템과 운영체제의 변화 속에서 프로그래밍 언어가 어떻게 발전했는지 시대별로 살펴본다. 프로그램이 실행되는 원리와 인터프리터·컴파일러·하이브리드 구현의 차이를 이해하고, 프로그래밍 언어의 요구사항과 평가 기준 및 기준 사이의 절충 관계를 정리한다.
제1장 컴퓨터 시스템과 프로그래밍 환경의 발전
1. 아이디어에서 전자식 컴퓨터로
프로그래밍 언어의 발전은 컴퓨터 시스템의 발전과 분리해서 이해하기 어렵다. 계산을 자동화하려는 생각은 실제 전자식 컴퓨터가 등장하기 전부터 존재했다. 아이디어 시대에는 튜링 기계처럼 계산 자동화를 위한 상상 속의 기계가 설계되었고, 이는 계산 절차를 기계적으로 수행한다는 발상의 토대가 되었다.
이후 에니악과 콜로서스 같은 전자식 컴퓨터가 등장하면서 전자 신호를 이용한 계산 기계가 현실이 되었다. 초기에는 계산 장치와 수행할 작업을 긴밀하게 결합하여 다루었지만, 프로그램 저장 방식의 컴퓨터가 등장하면서 프로그램과 처리기를 분리할 수 있게 되었다. 강의록은 에드박을 이러한 변화의 사례로 제시한다. 수행할 프로그램을 저장해 두고 처리기가 이를 읽어 실행하는 구조는 현대 컴퓨터와 프로그래밍 언어 구현을 이해하는 핵심 배경이다.
핵심 흐름: 계산 자동화에 대한 아이디어가 전자식 계산 기계로 구현되고, 프로그램 저장 방식이 도입되면서 프로그램과 처리기가 분리되었다. 이 분리는 같은 하드웨어에서 서로 다른 프로그램을 실행할 수 있는 기반이 된다.
2. 운영체제의 발전
컴퓨터 하드웨어가 발전하면서 컴퓨터를 효율적으로 운영하기 위한 운영체제도 함께 변화했다. 일괄 처리 운영체제에서는 작업을 모아 순서대로 처리하며, 사람이 맡던 관리자 역할을 대신하는 프로그램이 등장했다. 시분할 운영체제는 한 컴퓨터의 처리 시간을 나누어 여러 사람이 동시에 사용하는 환경을 가능하게 했다.
개인용 컴퓨터가 보급된 뒤에는 운영체제의 발전 방향도 달라졌다. DOS는 IBM 컴퓨터와 Apple 등의 개인용 컴퓨터가 등장하던 PC 환경을 대표하는 운영체제 흐름과 연결된다. 이후에는 사용자가 화면의 시각적 요소를 통해 컴퓨터를 다루는 GUI 운영체제와 Linux가 발전했다. 이러한 실행 환경의 변화는 언어가 제공해야 하는 기능과 프로그램을 작성·배포하는 방식에도 영향을 주었다.
| 발전 단계 | 핵심 특징 | 의의 |
|---|---|---|
| 일괄 처리 운영체제 | 작업을 모아 처리하며 관리자 역할을 프로그램이 대신함 | 컴퓨터 작업 운영의 자동화 |
| 시분할 운영체제 | 한 컴퓨터를 여러 사람이 동시에 사용함 | 다중 사용 환경의 확대 |
| DOS와 PC 환경 | IBM 컴퓨터와 Apple 등 개인용 컴퓨터가 등장함 | 컴퓨터 사용의 개인화 |
| GUI 운영체제와 Linux | 그래픽 사용자 환경과 다양한 운영체제 환경이 발전함 | 사용성과 실행 환경의 다양화 |
제2장 시대별 프로그래밍 언어의 발전
1. 1950년대: 초기 프로그래밍 언어
1950년대에는 오늘날 프로그래밍 언어의 주요 방향을 예고한 초기 언어들이 등장했다. Fortran은 IBM의 존 배커스가 개발한 과학 계산용 언어로, 이름도 수식 번역을 뜻하는 formula translation에서 왔다. 수식과 문장, 제어문을 사용하여 과학 계산 절차를 기계어보다 높은 수준에서 표현할 수 있게 했다는 점이 중요하다.
Algol은 본래 IAL, 즉 International Algebraic Language라는 이름을 가졌으며 국제위원회 ACM-GAMM을 통해 설계되었다. 알고리즘을 기술하기 위한 언어로서 구조화 프로그래밍의 발전에 영향을 주었다. 조건문과 블록 구조를 이용하여 수행 흐름을 조직하는 모습은 이후 여러 언어의 구조화된 표현으로 이어졌다.
LISP는 MIT의 존 매카시가 설계한 초기 함수형 언어이자 최초의 함수형 언어로 소개된다. 함수 적용을 중심으로 계산을 표현하며, 강의록의 (+ 3 (* 2 1)) 예처럼 식을 중첩한 형태로 연산 관계를 나타낼 수 있다.
| 언어 | 개발·설계 배경 | 핵심 의의 |
|---|---|---|
| Fortran | IBM의 존 배커스가 개발 | 수식·문장·제어문을 갖춘 과학 계산용 언어 |
| Algol | 국제위원회 ACM-GAMM이 설계 | 알고리즘 기술과 구조화 프로그래밍의 발전 |
| LISP | MIT의 존 매카시가 설계 | 최초의 함수형 언어 |
2. 1960년대: 응용 분야와 새로운 개념의 확대
1960년대에는 언어의 응용 분야가 넓어지고 새로운 프로그래밍 개념이 나타났다. Cobol은 미 해군에서 그레이스 호퍼가 이끄는 팀이 개발한 사무용 언어이다. 업무에서 다루는 여러 필드를 하나의 레코드로 조직하는 레코드 타입을 소개했다. 직원 이름, 사원 번호, 근무 시간과 시간당 급여처럼 서로 관련된 자료를 구조화하여 표현하는 데 적합하다.
PL/I는 여러 언어의 기능을 하나로 합치려 했으나 결과적으로 너무 복잡한 언어가 된 사례로 제시된다. 기능을 많이 제공하는 것이 언제나 좋은 설계로 이어지는 것은 아니며, 언어의 복잡도를 통제해야 한다는 교훈을 보여 준다.
BASIC은 Beginner’s All-purpose Symbolic Instruction Code의 약자로 교육용 언어로 사용되었다. Simula는 시뮬레이션 언어로서 객체지향 개념의 등장을 알렸다. 이 시기에는 사무 처리, 교육, 시뮬레이션처럼 목적에 따라 언어가 특화되는 흐름과 함께 레코드 및 객체지향 같은 새로운 추상화 수단이 나타났다.
3. 1970년대: 단순화와 프로그래밍 패러다임의 확장
1970년대에는 복잡해진 언어를 단순화하려는 흐름과 함께 여러 프로그래밍 패러다임이 발전했다. 니클라우스 버트가 개발한 Pascal은 구조화 프로그래밍을 지원하는 차세대 교육용 언어였다. 데니스 리치가 개발한 C는 Unix 개발을 위한 시스템 프로그래밍 언어로 출발했으며, Objective-C, C++, Java, C# 등 다양한 언어에 큰 영향을 주었다.
Prolog는 최초의 논리 언어로 소개되는 선언적 논리 언어이다. Smalltalk는 객체지향 언어를 발전시켰으며 GUI와 마우스를 최초로 도입한 언어 환경으로 제시된다. 명령을 순서대로 작성하는 방식 외에도 논리 관계를 선언하거나 객체 사이의 상호작용으로 프로그램을 조직하는 방식이 구체화된 것이다.
Ada는 안전성을 목표로 미국 국방성의 공모를 통해 추진되었다. 언어가 매우 복잡하여 1983년에 첫 컴파일러가 등장했다. ML은 Meta Language의 약자로 강력한 정적 타입 검사, 타입 추론, 패턴 검사와 예외 처리 등을 갖춘 현대적인 언어의 특징을 보여 주었다. Scheme은 LISP를 간결하게 만든 언어로 MIT 학생들의 기초 프로그래밍 언어로 사용되었다.
1970년대 언어들을 하나의 방식으로 묶어 암기하기보다 목적을 구분하는 것이 좋다. Pascal은 교육과 구조화, C는 시스템 프로그래밍, Prolog는 논리, Smalltalk는 객체지향, Ada는 안전성, ML은 타입 시스템, Scheme은 간결한 LISP라는 연결 관계를 잡으면 된다.
4. 1980년대: 현대 프로그래밍 언어의 등장
1980년대에는 기존 언어와 패러다임을 결합하거나 특정 처리 능력을 강화한 현대적 언어가 등장했다. Common Lisp는 방대하게 갈라진 LISP 계열을 통합하고 함수형 언어 패러다임과 객체지향 패러다임을 함께 지원했다.
Objective-C는 C를 기초로 Smalltalk의 객체지향 방식을 접목한 언어로, C 기반 객체지향 언어의 신호탄이 되었고 Apple의 애플리케이션 작성 언어로 발전했다. 비얀 스트로스트룹이 발표한 C++도 C에 클래스 개념을 도입하여 C를 객체지향 방향으로 확장했다.
래리 월이 설계한 Perl은 문자열 처리를 위한 언어이다. 정규식을 바탕으로 한 강력한 패턴 매칭 기능을 포함하여 문자열에서 일정한 규칙을 찾고 처리하는 작업에 초점을 두었다.
5. 1990년대 이후: 프로그래밍 언어의 대중화
1990년대 이후에는 개인용 컴퓨터와 웹 환경의 확산 속에서 프로그래밍 언어가 대중화되었다. 제임스 고슬링이 이끈 개발팀이 만든 Java는 단순한 객체지향 언어를 지향했다. 임베디드 컴퓨팅에서 웹브라우저 환경으로 발전했으며 JVM, 즉 Java Virtual Machine을 실행 기반으로 사용한다.
JavaScript는 Netscape에서 시작한 웹 프로그래밍 언어이다. 웹 환경에서 폭넓게 사용되었으며 Elm과 TypeScript 등 여러 변종 언어로 발전했다. 웹이라는 특정 응용 분야가 언어의 성장과 변화에 큰 영향을 준 사례이다.
귀도 반 로섬이 만든 Python은 빠른 프로토타이핑을 위한 스크립트 언어이다. 동적 언어를 추구하며 여러 프로그래밍 방식을 함께 지원하는 다중 패러다임 언어로 설명된다. 국제위원회가 만든 Haskell은 순수 함수형 언어로, 모나드가 탑재되면서 점차 인기를 얻었고 Scala에 영향을 주었다.
시대별 큰 흐름: 1950년대에는 과학 계산·알고리즘·함수형 언어의 기초가 마련되었고, 1960년대에는 업무·교육·객체지향의 영역이 넓어졌다. 1970년대에는 언어의 단순화와 다양한 패러다임이 전개되었으며, 1980년대에는 패러다임의 결합과 현대적 언어가 등장했다. 1990년대 이후에는 객체지향, 웹, 스크립트, 순수 함수형 언어가 대중화되었다.
제3장 컴퓨터 구조와 프로그램 동작 원리
1. CPU, 메모리와 저장장치
컴퓨터는 CPU, 메모리, 저장장치와 여러 입출력장치로 구성되며 이 장치들은 BUS를 통해 연결된다. CPU는 명령어를 처리하고, 메모리인 RAM은 현재 실행할 프로그램과 필요한 데이터를 담는다. HDD 같은 저장장치는 프로그램과 데이터를 지속적으로 보관하며, USB 드라이브 같은 외부 저장장치도 BUS를 통해 연결될 수 있다.
이 구조에서 프로그램은 저장장치에 보관되어 있기만 해서는 CPU가 곧바로 실행하는 대상이 되지 않는다. 실행하려는 프로그램이 메모리에 적재되어야 CPU가 그 명령어를 순서대로 가져와 처리할 수 있다. 따라서 저장장치, 메모리와 CPU 사이의 역할 구분이 프로그램 실행 과정을 이해하는 출발점이다.
2. 부팅 과정
컴퓨터의 전원을 켜면 ROM에 저장된 BIOS가 먼저 동작한다. BIOS는 하드웨어를 점검한 다음 저장장치의 특정 코드인 부트로더를 수행한다. 부트로더는 운영체제를 메모리에 적재하고 실행한다. 즉, BIOS에서 부트로더로, 부트로더에서 운영체제로 제어가 이어지며 일반 프로그램이 실행될 수 있는 환경이 준비된다.
부팅 흐름: 전원 켜기 → ROM의 BIOS 실행 및 하드웨어 점검 → 저장장치의 부트로더 실행 → 운영체제를 메모리에 적재 → 운영체제 실행의 순서로 이해한다.
3. CPU의 인출-해석-실행 주기
운영체제와 프로그램이 메모리에 적재되면 CPU는 메모리의 명령어를 수행한다. CPU는 먼저 수행할 명령어를 메모리에서 가져오는 인출 단계를 거친다. 이어서 가져온 명령어가 어떤 작업을 뜻하는지 해석하고, 마지막으로 해당 작업을 실행한다.
CPU는 한 번만 이 과정을 수행하는 것이 아니라 인출-해석-실행 주기를 반복한다. 프로그램은 이러한 반복을 통해 순차적으로 진행되며, 조건과 반복 같은 제어 구조에 따라 다음에 수행할 명령어의 위치가 달라질 수 있다.
시험 포인트: 프로그램은 메모리에 적재되어야 하며, CPU는 메모리에서 명령어를 인출하고 그 의미를 해석한 뒤 실행하는 주기를 반복한다.
제4장 프로그래밍 언어의 구현 방법
1. 기계어, 어셈블리어와 고급 프로그래밍 언어
기계어는 CPU가 직접 이해하고 수행하는 이진수 형태의 명령어이다. CPU에는 적합하지만 사람이 이진수 명령어를 직접 이해하고 작성하는 일은 매우 어렵다. 어셈블리어는 기계어에 거의 일대일로 대응하는 기호 언어이므로 기계어보다 사람이 읽기 쉽지만, CPU에 종속적이어서 이식성이 거의 없다.
고급 프로그래밍 언어는 사람에게 가까운 표현으로 프로그램을 나타내며 특정 기계에 직접 종속되지 않는다. 그러나 CPU는 고급 언어의 문장을 그대로 이해하지 못하므로, 고급 언어로 작성한 소스 프로그램을 CPU가 처리할 수 있는 형태의 목적 프로그램으로 연결하는 구현 과정이 필요하다.
| 구분 | 표현과 실행 | 기계 종속성과 이식성 |
|---|---|---|
| 기계어 | CPU가 직접 이해하는 이진수 명령어 | 특정 CPU에 직접 대응함 |
| 어셈블리어 | 기계어와 거의 일대일 대응하는 기호 언어 | CPU 종속적이며 이식성이 거의 없음 |
| 고급 언어 | 사람에게 가까운 표현으로 작성하며 별도 구현 과정이 필요함 | 특정 기계에 직접 종속되지 않음 |
2. 인터프리터 방식
인터프리터는 프로그래밍 언어로 작성된 고수준 명령을 해석하여 수행하는 프로그램이다. 소스 프로그램의 문장을 하나씩 읽고 그 의미를 해석한 뒤 컴퓨터 하드웨어가 해당 작업을 수행하도록 한다. 이 과정은 CPU가 명령어를 인출하고 해석하고 실행하는 주기를 고급 언어 수준에서 흉내 내는 것으로 이해할 수 있다.
인터프리터 방식에서는 소스 프로그램과 입력 데이터가 인터프리터에 전달되고, 인터프리터가 컴퓨터 하드웨어를 이용하여 실행 결과를 만든다. 실행 시점에 해석 과정이 이루어진다는 점이 미리 번역하는 컴파일러 방식과 구별된다.
3. 컴파일러 방식
컴파일러는 소스 프로그램을 CPU가 수행할 수 있는 형태로 미리 바꾸는 프로그램이다. 컴파일 과정에서 소스 프로그램이 기계어 코드로 번역되고, 번역된 목적 프로그램을 CPU가 실행하여 결과를 만든다.
인터프리터가 실행할 때 수행하는 해석 과정을 컴파일러는 미리 모두 처리한다. 따라서 번역된 프로그램을 실행할 때는 해석을 되풀이할 필요가 없어 효율적이다. 강의록에서는 상용 프로그램이 컴파일 방식으로 번역된 뒤 판매된다고 설명한다.
4. 하이브리드 구현과 가상기계
하이브리드 구현은 인터프리터 방식과 컴파일러 방식을 조합한다. 소스 프로그램을 작은 컴파일러가 중간 코드까지 번역한 뒤, 가상기계 안의 인터프리터가 이 중간 코드를 해석하여 컴퓨터 하드웨어에서 실행한다.
즉, 소스 프로그램을 처음부터 끝까지 직접 해석하는 것도 아니고 특정 CPU의 기계어로 바로 완전히 번역하는 것만도 아니다. 중간 코드라는 단계를 두고 이를 가상기계가 처리한다는 점이 핵심이다. Java의 JVM은 앞에서 살펴본 가상기계 기반 실행 환경의 대표적인 연결 사례로 이해할 수 있다.
| 구현 방식 | 처리 흐름 | 핵심 특징 |
|---|---|---|
| 인터프리터 | 소스 프로그램 → 인터프리터 → 하드웨어 | 고수준 문장을 실행 시점에 하나씩 해석하여 수행함 |
| 컴파일러 | 소스 프로그램 → 컴파일러 → 기계어 코드 → 하드웨어 | 해석을 미리 수행하여 실행 가능한 형태로 번역함 |
| 하이브리드 | 소스 프로그램 → 작은 컴파일러 → 중간 코드 → 가상기계의 인터프리터 → 하드웨어 | 컴파일과 인터프리트 방식을 결합함 |
구분 기준: 인터프리터는 고급 언어 문장을 실행하면서 해석하고, 컴파일러는 CPU가 수행할 수 있는 형태로 미리 번역한다. 하이브리드 구현은 중간 코드까지 컴파일한 뒤 가상기계의 인터프리터로 실행한다.
제5장 프로그래밍 언어의 요구사항과 설계 원칙
1. 세 가지 요구사항
프로그래밍 언어에는 표현 풍부성, 유지 보수성, 실행 가능성이 요구된다. 표현 풍부성은 프로그래머의 아이디어를 언어로 충분히 나타낼 수 있어야 한다는 요구이다. 원하는 계산과 구조를 표현할 수 없다면 문제 해결 도구로서의 역할이 제한된다.
유지 보수성은 프로그램이 변화에 쉽게 대처할 수 있어야 한다는 요구이다. 프로그램은 한 번 작성하고 끝나는 것이 아니라 오류를 고치거나 새로운 요구에 맞게 수정될 수 있으므로, 작성된 코드를 이해하고 변경하기 쉬워야 한다. 실행 가능성은 작성된 프로그램이 실제 컴퓨터에서 실행될 수 있어야 한다는 요구이다.
| 요구사항 | 의미 |
|---|---|
| 표현 풍부성 | 프로그래머의 아이디어를 표현할 수 있어야 함 |
| 유지 보수성 | 프로그램의 변화에 쉽게 대처할 수 있어야 함 |
| 실행 가능성 | 프로그램이 컴퓨터에서 실행될 수 있어야 함 |
2. 규칙성
규칙성은 언어의 기능들이 잘 조합될 수 있어야 한다는 설계 원칙이다. 규칙성은 일반성, 직교성, 일관성으로 구체화된다. 일반성은 어떤 기능을 일부 경우에만 제한적으로 적용하지 않고 넓은 상황에서 사용할 수 있게 하는 성질이다. 직교성은 언어 기능이 서로 불필요하게 간섭하지 않고 자유롭게 조합될 수 있는 성질이다. 일관성은 유사한 기능을 비슷한 형태로 표현하게 하는 성질이다.
규칙적인 언어에서는 개별 문법을 예외적으로 외워야 하는 부담이 줄고, 이미 배운 기능을 조합하여 새로운 표현을 만들기 쉬워진다. 따라서 규칙성은 언어의 이해와 사용에 중요한 설계 원칙이다.
3. 추상화 지원
추상화 지원은 실세계의 대상을 중요한 특징 중심으로 나타내고, 그 대상을 대상으로 연산을 수행할 수 있게 하는 원칙이다. 데이터 추상화는 데이터의 중요한 성질을 중심으로 표현하며, 제어 추상화는 복잡한 처리 절차를 하나의 의미 있는 제어 단위로 다룬다. 추상 데이터 타입 정의는 데이터와 그 데이터에 적용할 연산을 함께 규정하는 수단이다.
4. 복잡도 제어
복잡도 제어는 복잡한 대상과 처리 방법을 관리할 수 있게 하는 원칙이다. 캡슐화는 관련된 데이터와 기능을 묶고 내부 세부 내용을 적절히 감추는 데 도움을 준다. 모듈화는 큰 프로그램을 관리 가능한 여러 부분으로 나누어 구성하게 한다. 이를 통해 프로그래머는 전체 복잡성을 한꺼번에 다루는 대신 독립적인 단위에 집중할 수 있다.
설계 원칙의 연결: 규칙성은 일반성·직교성·일관성으로, 추상화 지원은 데이터 추상화·제어 추상화·추상 데이터 타입 정의로, 복잡도 제어는 캡슐화·모듈화로 구체화된다.
제6장 프로그래밍 언어의 평가 기준
1. 아홉 가지 평가 기준
프로그래밍 언어는 하나의 기준만으로 좋고 나쁨을 판단할 수 없다. 작성력은 프로그램의 수식이나 문장, 기능을 쉽게 표현할 수 있는지를 평가한다. 가독성은 작성된 프로그램을 보고 의미를 쉽게 이해할 수 있는지를 살핀다. 신뢰성은 작성된 프로그램이 오류에 빠질 가능성을 줄여 주는지를 판단한다.
직교성은 언어 기능이 서로 간섭하지 않고 자유롭게 조합될 수 있는지를 평가하며, 일관성은 유사한 기능을 같은 형태로 나타낼 수 있는지를 평가한다. 확장성은 사용자가 원하는 새로운 기능을 추가할 수 있는지를, 효율성은 작성된 프로그램이 효율적으로 수행될 수 있도록 하는지를 묻는다.
유연성은 프로그래머가 표현하려는 내용을 언어가 유연하게 수용하는지를 평가한다. 이식성은 프로그램을 다른 실행 환경으로 옮길 수 있는지를 판단한다. 어셈블리어가 CPU에 종속되어 이식성이 거의 없다는 점은 이식성 기준을 이해하는 좋은 대비 사례이다.
| 평가 기준 | 평가 질문 | 관련 요구사항 |
|---|---|---|
| 작성력 | 수식·문장·기능을 쉽게 표현할 수 있는가? | 유지 보수성 |
| 가독성 | 작성된 프로그램을 쉽게 이해할 수 있는가? | 유지 보수성 |
| 신뢰성 | 프로그램이 오류에 빠질 가능성을 줄이는가? | 유지 보수성, 실행 가능성 |
| 직교성 | 기능이 간섭 없이 자유롭게 조합되는가? | 표현 풍부성, 유지 보수성 |
| 일관성 | 유사한 기능을 같은 형태로 나타낼 수 있는가? | 표현 풍부성, 유지 보수성 |
| 확장성 | 사용자가 새로운 기능을 추가할 수 있는가? | 표현 풍부성, 유지 보수성 |
| 효율성 | 프로그램이 효율적으로 수행될 수 있는가? | 유지 보수성, 실행 가능성 |
| 유연성 | 표현하려는 내용을 유연하게 수용하는가? | 표현 풍부성, 유지 보수성 |
| 이식성 | 프로그램을 다른 실행 환경으로 이전할 수 있는가? | 유지 보수성, 실행 가능성 |
2. 평가 기준 사이의 절충
여러 평가 기준은 항상 같은 방향으로 움직이지 않으며 서로 상충할 수 있다. 프로그램 사용자는 검사 비용을 줄여 효율성을 높이고 싶어 하지만, 개발자는 신뢰성을 높이기 위해 더 많은 검사를 원할 수 있다. 검사를 줄이면 실행 비용은 낮아질 수 있으나 오류 가능성을 충분히 통제하기 어려울 수 있다.
간단한 기능은 사용자가 이해하기 쉬워 가독성에 유리하지만, 개발자는 다소 복잡하더라도 더 많은 기능이 지원되어 높은 작성력을 얻기를 원할 수 있다. 또한 안전을 위해 더 많은 제약을 가하면 신뢰성을 높일 수 있지만, 프로그램 작성 시 제약이 적어야 자유롭게 표현할 수 있으므로 유연성과 충돌할 수 있다.
| 절충 관계 | 한쪽의 요구 | 다른 쪽의 요구 |
|---|---|---|
| 효율성 ↔ 신뢰성 | 검사 비용을 줄여야 함 | 신뢰성을 위해 더 많이 검사해야 함 |
| 가독성 ↔ 작성력 | 간단한 기능이 이해하기 쉬움 | 복잡하더라도 많은 기능이 지원되어야 함 |
| 신뢰성 ↔ 유연성 | 안전을 위해 더 많은 제약이 필요함 | 작성할 때 제약이 적어야 함 |
평가 기준 사이의 절충은 어느 한 기준이 중요하지 않다는 뜻이 아니다. 언어의 목적과 사용자, 실행 환경에 맞추어 상충하는 요구 사이에서 적절한 지점을 선택해야 한다는 뜻이다.
3. 프로그래밍 언어의 선택 기준
실제로 배울 언어나 사용할 언어를 선택할 때는 언어 자체의 문법만 볼 것이 아니라 주변 환경과 학습 목적도 함께 고려해야 한다. 첫째, 해당 언어를 사용하는 커뮤니티가 활발하고 호의적인지 살핀다. 활발한 커뮤니티는 학습과 문제 해결에 도움을 준다.
둘째, 특정 응용 분야가 존재하는 언어인지 고려한다. 웹, 시스템, 문자열 처리, 과학 계산처럼 뚜렷한 분야가 있으면 목적에 맞는 경험을 쌓기 좋다. 셋째, 지금까지 접해 보지 못한 프로그래밍 패러다임을 지원하는지 살핀다. 새로운 패러다임을 배우면 문제를 바라보고 표현하는 방법을 넓힐 수 있다.
핵심 개념 정리
1. 발전 과정
계산 자동화에 대한 아이디어는 전자식 컴퓨터와 프로그램 저장 방식의 컴퓨터로 발전했다. 운영체제는 일괄 처리, 시분할, DOS와 PC 환경, GUI 운영체제와 Linux의 흐름으로 변화했다. 프로그래밍 언어는 1950년대 Fortran·Algol·LISP에서 출발하여 1960년대 Cobol·PL/I·BASIC·Simula, 1970년대 Pascal·C·Prolog·Smalltalk·Ada·ML·Scheme, 1980년대 Common Lisp·Objective-C·C++·Perl, 1990년대 이후 Java·JavaScript·Python·Haskell 등으로 발전했다.
2. 동작과 구현
프로그램은 메모리에 적재되어야 하며 CPU는 인출-해석-실행 주기를 반복해 명령어를 수행한다. 기계어는 CPU가 직접 수행하고, 어셈블리어는 기계어와 거의 일대일 대응하지만 이식성이 낮다. 고급 언어는 사람에게 가까운 표현을 제공하므로 소스 프로그램과 목적 프로그램의 간극을 인터프리터, 컴파일러 또는 하이브리드 구현으로 메워야 한다.
3. 요구사항과 평가
프로그래밍 언어의 요구사항은 표현 풍부성, 유지 보수성, 실행 가능성이다. 설계 원칙은 규칙성, 추상화 지원, 복잡도 제어이며, 평가 기준에는 작성력·가독성·신뢰성·직교성·일관성·확장성·효율성·유연성·이식성이 있다. 효율성과 신뢰성, 가독성과 작성력, 신뢰성과 유연성처럼 기준이 상충할 수 있으므로 언어의 목적에 맞는 절충이 필요하다.
최종 정리: 프로그래밍 언어는 컴퓨터 시스템과 사용 환경의 변화에 맞추어 새로운 표현 방식과 패러다임을 받아들이며 발전했다. 고급 언어로 표현된 프로그램은 인터프리트, 컴파일 또는 두 방식을 결합한 구현을 통해 실제 하드웨어에서 실행된다. 좋은 언어를 판단할 때는 한 가지 장점만 보지 말고 표현·유지 보수·실행의 요구와 여러 평가 기준 사이의 균형을 함께 살펴야 한다.
예상문제 20선
1. 프로그램 저장 방식 컴퓨터의 핵심 변화로 가장 적절한 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③
프로그램 저장 방식은 프로그램과 처리기를 분리하여 저장한 프로그램을 처리기가 읽어 실행하는 기반을 마련했다.
2. 시분할 운영체제의 특징은 무엇인가?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
시분할 운영체제는 컴퓨터의 처리 시간을 나누어 한 컴퓨터를 여러 사용자가 동시에 이용할 수 있게 한다.
3. 언어와 그 특징의 연결이 옳지 않은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
Cobol은 그레이스 호퍼가 이끄는 팀이 개발한 사무용 언어이며 레코드 타입을 소개했다.
4. 1960년대 언어에 대한 설명으로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
Simula는 시뮬레이션 언어로서 객체지향 개념의 등장을 알렸다. BASIC은 교육용이고 PL/I는 여러 기능을 합치면서 지나치게 복잡해졌다.
5. C 언어에 대한 설명으로 가장 적절한 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
C는 데니스 리치가 개발한 Unix용 시스템 프로그래밍 언어이며 여러 후속 언어에 큰 영향을 주었다.
6. ML이 갖춘 특징으로 강의록에서 제시되지 않은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
ML은 정적 타입 검사, 타입 추론, 패턴 검사와 예외 처리 등을 갖춘 언어이다. JVM은 Java와 연결되는 실행 환경이다.
7. 1980년대 언어의 설명으로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
비얀 스트로스트룹이 발표한 C++는 C에 클래스 개념을 도입하여 객체지향 방향으로 확장했다.
8. 언어와 개발자 또는 기관의 연결이 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③
Java는 제임스 고슬링이 이끈 개발팀이 개발했다. Python은 귀도 반 로섬, Perl은 래리 월, LISP는 존 매카시와 연결된다.
9. 컴퓨터의 부팅 과정을 올바르게 나열한 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
전원을 켜면 ROM의 BIOS가 하드웨어를 점검하고 부트로더를 실행하며, 부트로더가 운영체제를 메모리에 적재해 실행한다.
10. CPU가 메모리에 적재된 프로그램의 명령어를 수행하는 반복 주기는?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
CPU는 명령어를 메모리에서 인출하고, 의미를 해석한 뒤, 해당 명령을 실행하는 주기를 반복한다.
11. 어셈블리어에 대한 설명으로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
어셈블리어는 기계어와 거의 일대일 대응하는 기호 언어이며 특정 CPU에 종속되어 이식성이 거의 없다.
12. 인터프리터 방식의 특징으로 가장 적절한 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③
인터프리터는 고수준 명령을 실행 시점에 하나씩 읽고 해석하여 수행하며 CPU의 인출-해석-실행 주기를 흉내 낸다.
13. 하이브리드 구현의 처리 흐름으로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
하이브리드 구현은 소스를 중간 코드로 컴파일하고, 가상기계 안의 인터프리터가 중간 코드를 해석해 실행한다.
14. 프로그래밍 언어의 세 가지 요구사항에 포함되지 않는 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
강의록이 제시한 요구사항은 표현 풍부성, 유지 보수성, 실행 가능성이다.
15. 언어의 기능이 서로 간섭하지 않고 자유롭게 조합될 수 있는지를 평가하는 기준은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③
직교성은 언어의 기능들이 서로 불필요하게 간섭하지 않고 자유롭게 조합될 수 있는지를 평가한다.
16. 설계 원칙과 구체적 수단의 연결이 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
복잡도 제어는 복잡한 대상과 처리 방법을 관리하는 원칙이며 캡슐화와 모듈화가 이를 지원한다.
17. 프로그램을 다른 실행 환경으로 옮길 수 있는지를 묻는 평가 기준은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
이식성은 작성한 프로그램을 다른 실행 환경으로 이전할 수 있는지를 평가하는 기준이다.
18. 평가 기준 사이의 절충 관계에 대한 설명으로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
안전을 위해 제약을 늘리면 신뢰성에는 유리할 수 있으나 프로그래머가 자유롭게 표현하는 유연성은 줄어들 수 있다.
19. 프로그래밍 언어의 선택 기준으로 적절하지 않은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
강의록은 활발한 커뮤니티, 특정 응용 분야, 새로운 패러다임 지원 여부를 언어 선택 기준으로 제시한다.
20. 이번 강의의 내용을 종합한 설명으로 가장 적절한 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③
프로그래밍 언어의 역사는 시스템 환경과 패러다임의 변화로 이루어졌고, 실제 실행에는 구현 방식이 필요하며 언어 평가는 상충하는 여러 기준을 함께 고려해야 한다.
댓글
댓글 쓰기