CPU·메모리·디스크 따라가기
65분 안팎
학습 목표
명령 실행·값 계산·파일 저장의 역할과 이진수 표현을 설명합니다.
개념
왜 실행과 저장을 나눠야 하는가
독서 제목을 화면에 한 번 출력했다고 다음 실행에서도 기록이 남는 것은 아닙니다. 프로그램 종료 뒤 제목이 사라졌다는 신고를 받으면 입력·계산·출력·저장을 구분해야 합니다. 이 레슨은 CPU·메모리·디스크를 부품 이름 암기 대신 한 제목의 이동으로 설명합니다. 제목은 파일에서 읽혀 메모리의 문자열이 되고, 실행 중 리스트에 들어가며, 명시적인 파일 쓰기로 저장됩니다. 출력은 터미널로 보낼 뿐 저장 파일을 만드는 코드와 같지 않습니다. 두 번의 실행을 비교해 경계를 직접 관찰합니다.
CPU가 하는 일
CPU는 기계 명령을 실행하는 장치입니다. Python 소스의 글자를 CPU가 직접 한국어처럼 읽는 것은 아닙니다. 인터프리터가 소스를 처리하고 그 인터프리터를 구성하는 기계 명령이 CPU에서 실행됩니다. 쪽수 두 수를 더하거나 문자열을 처리할 때도 실행 작업이 필요합니다. 실제 컴퓨터에는 캐시와 여러 코어 등 추가 구조가 있지만 여기서는 실행 중 계산 담당이라는 역할에 집중합니다. 파일을 오래 보관하는 장치와 계산하는 장치를 구분하면 제목 출력 실패를 CPU 성능 문제로 곧바로 판단하지 않게 됩니다.
메모리에 있는 실행 상태
프로그램이 실행되는 동안 records 리스트와 제목 문자열 같은 객체를 메모리에 둡니다. records = []는 빈 리스트를 새로 만드는 문장입니다. records.append로 제목을 추가하면 현재 실행의 리스트 길이가 증가합니다. 같은 소스를 새 프로세스로 실행하면 처음부터 이 문장을 수행하므로 다시 빈 리스트로 시작합니다. 컴퓨터 전체 메모리가 모두 비워진다는 뜻이 아니라 해당 프로그램이 이전 리스트를 자동 복구하지 않는다는 뜻입니다. 메모리에 있던 상태를 다음 실행으로 이어 쓰려면 파일이나 다른 저장소에서 복원하는 코드를 따로 작성해야 합니다.
디스크에 남는 파일
이 수업에서 디스크는 SSD를 포함한 지속 저장 장치의 역할을 가리킵니다. Path.write_text로 saved.txt를 쓰고 실행이 종료된 후 cat으로 읽으면 같은 제목이 나옵니다. 일반적인 정상 종료에서 파일 내용은 다음 실행에도 존재합니다. 이것을 정전 상황에서 데이터의 완전한 내구성을 보장했다는 의미로 확대하지 않습니다. 이번 실습은 정상적인 파일 쓰기와 닫기를 관찰하며 전원 장애나 복구 기술은 다루지 않습니다. 저장 파일은 자동으로 메모리 리스트가 되지 않습니다. 다음 모듈들에서 읽기·변환·복원의 계약을 차례로 추가합니다.
세 역할을 제목 흐름으로 설명하기
data/sample.txt의 제목을 읽으면 파일의 바이트가 프로그램에서 처리할 문자열로 변환됩니다. 메모리에는 그 문자열을 참조하는 실행 상태가 있습니다. CPU는 인터프리터의 명령을 실행해 리스트 조작과 출력 요청을 처리합니다. 저장 코드를 수행하면 문자열을 다시 UTF-8 바이트로 표현해 파일에 씁니다. 운영체제가 파일 접근과 출력 같은 자원을 관리합니다. 따라서 CPU가 디스크에 제목을 직접 영구 보관한다거나 메모리가 텍스트 파일 이름과 같은 것이라고 설명하면 흐름을 혼동한 것입니다. 한 동작에는 여러 역할이 참여하지만 각 역할의 목적은 구분할 수 있습니다.
이진수는 다른 표기다
비트는 두 상태를 나타내는 단위이며 바이트는 8비트입니다. Python의 bin(13)은 같은 정수 값을 이진수 표기 문자열로 보여 줍니다. 1101은 8과 4와 1을 더한 값 13입니다. 앞의 0b는 이진수 표기라는 접두사이지 숫자의 일부 자릿수가 아닙니다. 이진수로 표시했다고 계산 결과나 저장된 독서 쪽수가 바뀌지 않습니다. Python 정수를 모두 8비트 범위라고 생각하지 않습니다. 이번 실습은 값의 표현을 보는 것이며 CPU 내부 명령이나 Python 객체 전체의 실제 메모리 배치를 측정하는 실험은 아닙니다.
문자와 UTF-8 바이트
제목 문자열은 저장할 때 인코딩 규칙을 통해 바이트로 바뀝니다. UTF-8에서 한글 음절 하나는 여러 바이트를 사용하므로 문자열 길이와 파일 용량을 같은 숫자로 기대하면 안 됩니다. 이 레슨의 제목 책A는 Python len으로 코드포인트 두 개이고 UTF-8로 인코딩하면 네 바이트입니다. encode는 바이트로 바꾸고 decode는 그 바이트를 문자열로 되돌립니다. 두 쪽에서 utf-8을 동일하게 지정하면 같은 제목을 확인할 수 있습니다. 글꼴에 보이는 글자 수와 코드포인트 수도 항상 같지는 않으므로 여기서는 단순한 제목으로 관찰 범위를 제한합니다.
쓰기·읽기 오류를 분리한다
saved.txt에 쓰는 줄이 빠져 있으면 출력은 정상이어도 파일이 생기지 않습니다. 파일이 없는데 read_text를 실행하면 FileNotFoundError가 납니다. 인코딩이 다른 바이트를 UTF-8로 읽으면 UnicodeDecodeError가 발생할 수 있습니다. 해당 파일 경로와 encoding 인자를 먼저 확인합니다. 오류를 숨기려고 무시 옵션을 넣으면 제목 일부가 사라질 수 있습니다. 이번 실습은 명시적 UTF-8 쓰기를 완성하는 문제입니다. 처음 실행 전에 저장 파일이 없어도 올바른 코드가 파일을 만들며, 다음 실행에서도 같은 고정 제목으로 덮어씁니다. 누적 기록 저장과 구분합니다.
관찰과 추론의 경계
observe.py를 두 번 실행해 매번 시작 기록 0, 실행 중 기록 1을 얻습니다. 실행 사이에 saved.txt를 읽을 수 있으면 정상 종료 뒤 파일이 남았다는 관찰입니다. 여기서 이전 메모리의 물리적 비트가 어떻게 재사용되는지는 확인하지 않았습니다. 미션 문서에는 확인한 출력과 그 출력이 보여 주는 범위를 함께 씁니다. 검사기는 새 임시 폴더에서 두 프로세스를 실행하며 둘 다 같은 출력인지와 저장 파일 내용을 확인합니다. 메모리 초기화와 파일 지속이라는 설명을 자신의 관찰에 연결할 수 있으면 목표를 달성한 것입니다. 더 읽기에서는 비트 폭과 문자 경계를 확장하되 이번 프로젝트에는 아직 그 기능을 추가하지 않습니다.
따라하기
정수 표기 확인
코드를 representation.py에 저장하고 python3 representation.py로 실행합니다. 이후 단계도 별도 파일로 실행할 수 있습니다.
pages = 13
print(pages)
print(bin(pages))
print(8 + 4 + 1)실행 결과
13 0b1101 13
제목의 바이트 확인
코드포인트 수와 UTF-8 바이트 수를 단위와 함께 적습니다.
title = '책A'
data = title.encode('utf-8')
print(len(title), len(data))
print(data.hex())
print(data.decode('utf-8'))실행 결과
2 4 ecb18541 책A
새 프로세스와 파일 비교
새 연습 폴더에서 실행합니다. 두 새 프로세스의 상태를 비교하고 파일을 씁니다. 실행 종료 뒤 cat saved.txt로 읽은 제목도 관찰 문서에 적습니다.
from pathlib import Path
import subprocess, sys
source = "records = []\nprint('시작:', len(records))\nrecords.append('달빛 도서관')\nprint('현재:', len(records))\n"
for attempt in range(2):
subprocess.run([sys.executable, '-c', source], check=True)
Path('saved.txt').write_text('달빛 도서관\n', encoding='utf-8')
print('파일:', Path('saved.txt').read_text(encoding='utf-8').strip())실행 결과
시작: 0 현재: 1 시작: 0 현재: 1 파일: 달빛 도서관
확인 문제
실습
observe.py의 TODO에 UTF-8 파일 쓰기를 추가합니다. 새 실행마다 빈 리스트로 시작하고 종료 뒤 saved.txt에 제목이 남는지 확인합니다. starter의 README.md에서 실행 방법과 검사 대상을 확인합니다. tests/check.py와 check.sh는 변경하지 않습니다. 일부 검사가 실패하는 시작 상태를 확인한 뒤 수정하고 다시 검사합니다.
실행 명령
bash check.sh
기대 결과
모든 검사 줄이 PASS이며 마지막 줄은 ALL PASS, 종료 코드는 0입니다.
모범 답안
모범 답안 내려받기더 읽기
면접 질문
- 메모리와 디스크에 저장된 데이터의 차이를 설명합니다.