캐시를 두는 이유는 CPU가 주기억장치에 접근하는 횟수를 줄이기 위해서이다.
자주 쓰는 데이터를 CPU 가까이의 빠른 캐시에 두면, 접근의 대부분이 캐시에서 처리되어(참조의 지역성) 느린 주기억장치 접근이 줄고 평균 접근 시간이 짧아진다.
- 프로세스 복제를 막기 위해 — 캐시는 보호 기능과 무관하다.
- CPU와 주기억장치를 직접 연결할 수 없어서 — 캐시 없이도 연결은 가능하다.
- 캐시가 주기억장치보다 저렴해서 — 캐시(SRAM)는 용량당 비용이 더 비싸다.
옳지 않은 것은 십진수 8을 이진수 1000으로 표현한다는 설명이다.
4비트 2의 보수의 표현 범위는 −8 ~ +7이므로 +8은 표현할 수 없고, 1000은 −8을 나타낸다.
- −4 → 0100의 2의 보수 = 1100 — 옳다.
- −1 → 0001의 2의 보수 = 1111 — 옳다.
- 5 → 0101 — 옳다.
옳지 않은 것은 하나의 명령어 처리에 걸리는 시간을 줄일 수 있다는 설명이다.
파이프라이닝은 여러 명령어를 단계별로 겹쳐 실행해 처리량(throughput)을 높이는 기법이며, 명령어 하나의 처리 시간(지연 시간)은 줄지 않고 단계 간 레지스터 때문에 오히려 약간 늘 수 있다.
- 이상적인 경우 단계 수만큼의 성능 향상을 목표로 한다 — 옳다.
- 일정 시간당 처리량을 향상시킨다 — 옳다.
- 가장 느린 단계가 클록 주기를 결정해 성능 향상을 제약한다 — 옳다.
ㄱ. 명령어의 종류를 해독하는 단계
ㄴ. 명령어에서 사용되는 피연산자(operand)를 가져오는 단계
ㄷ. 명령어를 프로그램 메모리에서 중앙처리장치로 가져오는 단계
ㄹ. 명령어를 실행하는 단계
ㅁ. 명령어의 결과를 저장하는 단계
처리 순서는 ㄷ-ㄱ-ㄴ-ㄹ-ㅁ이다.
명령어는 인출 → 해독 → 피연산자 인출 → 실행 → 결과 저장의 순으로 처리된다.
- ㄷ(명령어 인출) — 메모리에서 명령어를 가져와야 해독할 수 있으므로 가장 먼저이다.
- ㄱ(해독) — 명령어 종류를 알아야 어떤 피연산자를 가져올지 정할 수 있다.
- ㄴ(피연산자 인출) → ㄹ(실행) → ㅁ(결과 저장) 순으로 이어진다.
설명하는 자료 구조는 큐(queue)이다.
큐는 한쪽 끝(rear)에서 삽입하고 반대쪽 끝(front)에서 삭제하는 선입선출(FIFO) 구조이다.
- 스택 — 한쪽 끝에서만 삽입·삭제하는 후입선출(LIFO) 구조이다.
- 트리 — 계층적인 비선형 구조이다.
- 연결리스트 — 노드를 포인터로 연결한 구조로 임의 위치 삽입·삭제가 가능하다.
옳지 않은 것은 패킷교환 방식이 회선교환 방식보다 통신선로 사용 효율이 낮다는 설명이다.
회선교환은 통신 동안 회선을 독점해 데이터가 없을 때도 회선이 놀지만, 패킷교환은 여러 사용자의 패킷이 회선을 공유하므로 선로 효율이 더 높다.
- 패킷교환은 전용 경로 설정이 필요 없다 — 옳다.
- 회선교환은 경로가 고정되어 전송 지연이 적다 — 옳다.
- 기존 유선 전화는 회선교환 방식이다 — 옳다.
옳지 않은 것은 UDP가 비연결형으로 신뢰도가 높은 데이터 전송에 사용된다는 설명이다.
UDP는 연결 설정·확인 응답·재전송이 없는 비연결형 프로토콜이어서 신뢰성을 보장하지 않으며, 대신 빠른 전송이 필요한 곳에 쓰인다. 신뢰성 있는 전송은 TCP가 담당한다.
- 텔넷은 원격 호스트를 로컬처럼 사용하는 프로토콜이다 — 옳다.
- SNMP는 망 관리용 프로토콜이다 — 옳다.
- 텔넷, FTP, SMTP는 응용 계층 프로토콜이다 — 옳다.
| 데이터 이름 | 데이터 비트열 | 패리티 비트 |
|---|---|---|
| A | 01001101 | 1 |
| B | 01110110 | 1 |
| C | 10111000 | 0 |
| D | 11110001 | 0 |
| E | 10101010 | 0 |
에러가 발생한 데이터는 A와 D이다.
데이터 비트와 패리티 비트를 합친 1의 개수를 센다.
- A: 4+1 = 5(홀수)
- B: 5+1 = 6(짝수)
- C: 4+0 = 4(짝수)
- D: 5+0 = 5(홀수)
- E: 4+0 = 4(짝수)
두 개만 에러라면 정상인 세 개(B, C, E)가 짝수이므로 짝수 패리티를 쓴 것이고, 1의 개수가 홀수인 A와 D에서 1비트 에러가 난 것이다.
ㄱ. 어휘분석(lexical analysis)
ㄴ. 중간코드생성(intermediate code generation)
ㄷ. 구문분석(syntax analysis)
ㄹ. 의미분석(semantic analysis)
컴파일 순서는 ㄱ-ㄷ-ㄹ-ㄴ이다.
컴파일러는 어휘분석 → 구문분석 → 의미분석 → 중간코드생성 순으로 진행한 뒤 코드 최적화와 목적 코드 생성을 한다.
- 어휘분석 — 원시 코드를 토큰으로 나눈다.
- 구문분석 — 토큰으로 구문 트리(파스 트리)를 만든다.
- 의미분석 — 형 검사 등 의미상 오류를 검사한다.
- 중간코드생성 — 분석 결과를 중간 표현으로 바꾼다.
옳지 않은 것은 프리프로세서가 고급언어 프로그램을 실행 가능한 기계어로 변환하는 번역기라는 설명이다.
프리프로세서(전처리기)는 컴파일 전에 매크로 확장, 파일 포함, 조건부 컴파일 등을 처리해 원시 프로그램을 가공할 뿐, 기계어로 번역하지 않는다.
- 컴파일러는 원시 프로그램을 목적 프로그램으로 번역한다 — 옳다.
- 링커는 목적 프로그램과 라이브러리를 묶어 로드 모듈을 만든다 — 옳다.
- 디버거는 오류 추적·탐지에 쓰인다 — 옳다.
ㄱ. 요구분석
ㄹ. 구현
ㄴ. 유지보수
ㅁ. 설계
ㄷ. 시험
폭포수 모형의 진행 순서는 ㄱ-ㅁ-ㄹ-ㄷ-ㄴ이다.
폭포수 모형은 각 단계를 순차적으로 완료하고 다음 단계로 넘어가며, 요구분석 → 설계 → 구현 → 시험 → 유지보수 순이다.
- 설계를 요구분석보다 앞에 두는 배열 — 무엇을 만들지 정해야 설계할 수 있으므로 틀렸다.
- 시험을 구현보다 앞에 두는 배열 — 구현된 코드가 있어야 시험할 수 있으므로 틀렸다.
옳지 않은 것은 네 조건 중 어느 하나만 만족하면 교착상태가 발생한다는 설명이다.
교착상태는 상호배제, 점유와 대기, 비선점, 순환 대기의 네 조건이 모두 동시에 성립할 때 발생한다. 그래서 하나만 깨도 예방이 된다.
- 점유와 대기·비선점·순환대기 조건을 방지해 예방한다 — 옳다.
- 은행가 알고리즘은 회피 기법이다 — 옳다.
- 서로 상대가 점유한 자원을 기다려 진행하지 못하는 상태이다 — 옳은 정의이다.
옳지 않은 것은 광 컴퓨터가 전광집적회로를 사용하지 않는다는 설명이다.
광 컴퓨터는 전자 대신 빛(광자)을 이용해 연산·전송하는 컴퓨터로, 광학 소자와 함께 전기 신호와 빛 신호를 변환하는 전광집적회로를 활용한다.
- 나노 컴퓨터 — 원자·분자 크기 소자를 이용한다는 설명이 옳다.
- 바이오 컴퓨터 — 단백질·DNA 등 생체 소자를 이용한다는 설명이 옳다.
- 양자 컴퓨터 — 중첩 상태의 큐비트를 이용한다는 설명이 옳다.
장점으로 옳지 않은 것은 데이터 간의 종속성 유지이다.
데이터베이스는 응용 프로그램과 데이터 구조를 분리하는 데이터 독립성을 제공하는 것이 장점이다. 종속성은 파일 처리 시스템의 단점이다.
- 데이터 중복의 최소화 — 통합 관리로 중복이 줄어든다.
- 여러 사용자에 의한 데이터 공유 — 동시 공유가 가능하다.
- 데이터 내용의 일관성 유지 — 중복이 줄어 불일치가 감소한다.
개인 정보를 불법적으로 추출하는 방법이 아닌 것은 페이징(paging)이다.
페이징은 가상 메모리를 일정 크기의 페이지로 나누어 관리하는 운영체제의 메모리 관리 기법이다.
- 스니핑 — 네트워크 패킷을 엿들어 정보를 가로챈다.
- 스푸핑 — IP·MAC 주소 등을 위장해 속인다.
- 피싱 — 가짜 사이트·메일로 개인정보를 낚는다.
옳지 않은 것은 가상 메모리를 이용하면 개별 프로그램의 수행 속도가 향상된다는 설명이다.
가상 메모리는 주소 변환과 페이지 부재 시 디스크 입출력이 추가되므로 개별 프로그램의 속도는 오히려 느려질 수 있다. 장점은 메모리 크기 제약 완화와 다중 프로그래밍 효율이다.
- 물리적 메모리와 논리적 메모리 개념을 분리한다 — 옳다.
- 프로그램의 메모리 크기 제약이 줄어든다 — 옳다.
- 일부만 적재하므로 다중 프로그래밍이 쉬워진다 — 옳다.
#include<stdio.h>
int a=1, b=2, c=3;
int f(void);
int main(void) {
printf ("%3d \n", f());
printf ("%3d%3d%3d \n", a, b, c);
return 0;
}
int f(void) {
int b, c;
a=b=c=4;
return (a+b+c);
}1 2 3
1 2 3
4 4 4
4 2 3
출력은 첫 줄 12, 둘째 줄 4 2 3이다.
함수 f 안에서 b, c는 지역 변수로 새로 선언되었고 a는 선언되지 않았으므로 전역 변수 a를 가리킨다.
a=b=c=4 → 전역 a=4, 지역 b=c=4 → 반환값 4+4+4 = 12
main으로 돌아오면 전역 a는 4로 바뀌었지만 전역 b, c는 그대로 2, 3이다.
- 6 — f가 전역 값 1+2+3을 더한다고 본 경우이다.
- 4 4 4 — 지역 변수 b, c가 전역 b, c를 바꾼다고 본 경우이다.
- 1 2 3 — 전역 a가 바뀐 것을 놓친 경우이다.
<binary_digit>::=<digits_in_part> 010<digits_in_part> | 101
<digits_in_part>::=<digit>0 | <digit>1 | <digit>
<digit>::=1 | 0
생성할 수 없는 것은 01101이다.
<digits_in_part>는 1비트 또는 2비트 문자열이므로, binary_digit는 101이거나 (1~2비트)+010+(1~2비트) 꼴이어야 한다.
- 01101 — 길이 5이므로 앞뒤가 1비트씩이고 가운데 3비트가 110이 되어 010과 맞지 않는다.
- 1101000 — 11+010+00으로 생성된다.
- 001011 — 0+010+11로 생성된다.
- 1001011 — 10+010+11로 생성된다.
옳지 않은 것은 부트스트랩 프로그램이 일반적으로 하드 디스크에 저장되어 있다는 설명이다.
전원을 켜면 처음 실행되는 부트스트랩 프로그램은 전원이 꺼져도 지워지지 않는 ROM(펌웨어)에 저장되어 있으며, 이것이 하드 디스크의 운영체제를 메모리로 적재한다.
- 부트 과정의 목적은 운영체제를 메모리로 적재하는 것이다 — 옳다.
- 주요 구성 요소의 진단 검사를 수행한다 — 옳다(POST).
- 완료 후 제어권을 운영체제로 넘긴다 — 옳다.
- 다음에 수행할 명령의 주소를 기억한다.
- 상대주소지정방식(relative addressing mode)에서 유효 주소번지(effective address)를 구하기 위해서는 이 레지스터의 내용을 명령어의 오퍼랜드(operand)에 더해야 한다.
설명하는 레지스터는 PC(program counter)이다.
PC는 다음에 실행할 명령어의 주소를 보관하며, 상대 주소 지정 방식에서는 유효 주소 = PC + 오퍼랜드로 계산한다.
- AC — 연산 결과를 임시 저장하는 누산기이다.
- MAR — 접근할 메모리 주소를 담는 레지스터이다.
- MBR — 메모리와 주고받는 데이터를 담는 레지스터이다.