취업·면접 · 실무
국비 과정 수료 후 개발자 취업 로드맵 - 6개월 실행 계획
CS 빈칸 메우기 - 프로젝트에서 출발하는 자료구조·DB·네트워크·운영체제
내 프로젝트 요청 하나를 따라가며 필요한 CS 찾기, 면접에 자주 나오는 핵심만 먼저, 서재 책 연결 순서, 완성 코드는 요청 흐름 단계를 받아 관련 CS 주제와 읽을 장 목록을 출력
개발자KR · 원고 갱신
이 장에서 배우는 것
팀 프로젝트에서 회원 가입과 게시글 조회를 구현했다면 이미 여러 컴퓨터 과학(CS) 개념을 사용한 셈이다. 목록을 담을 자료구조를 골랐고, 서버로 요청을 보냈고, 데이터베이스에서 값을 읽었다. 다만 기능을 완성하는 동안에는 그 선택의 이유까지 정리할 시간이 부족했을 수 있다. 짧은 기간에 서비스를 함께 완성한 경험을 출발점으로 삼으면, 새 용어를 외우는 데서 그치지 않고 자신이 만든 동작을 설명하는 공부를 할 수 있다.
앞 장에서 주 단위로 공부 시간과 완료 증거를 정했다. 이 장에서는 그 시간에 무엇을 읽고 어떤 질문에 답할지 고른다. 자료구조·데이터베이스·네트워크·운영체제를 처음부터 모두 다시 공부하는 대신, 프로젝트의 요청 하나를 따라가며 설명이 끊기는 지점을 찾는다. 마지막에는 요청 흐름 단계를 받아 관련 주제와 읽을 장 목록을 출력하는 작은 도구를 만든다.
- 프로젝트 요청 하나를 네 단계로 나누고 각 단계에 필요한 CS 질문을 붙인다.
- 면접에서 설명할 기반이 되는 핵심 개념을 먼저 고른다.
- 서재 책을 읽는 순서를 정하고 프로젝트 관찰 기록과 연결한다.
- 표준 라이브러리만 사용하는 학습 목록 생성기를 작성한다.
- 공부한 분량 대신 설명과 관찰을 완료 증거로 남긴다.
문제 상황
팀 프로젝트에서 게시글 목록 화면을 맡았다고 하자. 화면에는 제목과 작성자가 나오고, 다음 페이지 버튼도 동작한다. 발표 때 기능을 시연했고 팀은 정해진 일정에 서비스를 완성했다. 그런데 기능 설명 뒤에 다음 질문이 이어지자 답변이 짧아진다.
- 페이지 번호는 서버에 어떻게 전달되며, 서버는 무엇을 확인하는가.
- 동시에 여러 사람이 조회하면 각 요청은 어떤 실행 자원을 사용하는가.
- 조회 결과를 순서 있는 목록으로 다루는 이유는 무엇인가.
- 행이 늘어나면 같은 조회가 느려질 수 있는 이유는 무엇인가.
이 질문들은 새로운 서비스를 만들라는 요구가 아니다. 이미 만든 기능의 경계와 선택을 설명하라는 요구다. 화면이 동작한다는 사실과 내부 과정을 설명할 수 있다는 사실 사이에 학습할 공간이 있다. 그 공간을 모두 같은 깊이로 채울 필요는 없다. 지금 맡았던 기능을 기준으로 자주 마주치는 질문부터 골라야 한다.
예를 들어 “목록 조회가 느리다”는 말만으로 인덱스를 추가하겠다고 결정하면 원인을 놓칠 수 있다. 요청이 여러 번 전송되었을 수도 있고, 서버에서 같은 데이터를 반복 처리했을 수도 있다. 데이터 조회 이후 응답을 만드는 데 시간이 들 수도 있다. 이 장의 목표는 성능 문제를 해결하는 기법을 모두 익히는 것이 아니라, 어느 구간을 관찰하고 어떤 개념을 찾아볼지 구분하는 것이다.
요청 하나를 따라가며 빈칸을 찾는다
공부할 요청은 자신이 코드를 읽을 수 있는 것으로 고른다. 게시글 목록 조회, 상품 상세 조회, 예약 내역 조회처럼 입력과 결과가 분명한 요청이 알맞다. 처음에는 여러 외부 서비스가 얽힌 기능보다 프로젝트 안에서 흐름을 끝까지 확인할 수 있는 기능이 좋다. 여기서는 게시글 목록 조회를 네 단계로 나눈다.
첫 단계는 요청 수신이다. 브라우저가 보낸 경로와 질의 매개변수, 헤더를 서버가 읽는다. 하이퍼텍스트 전송 규약(HTTP)의 요청과 응답 구조를 알아야 이 구간을 설명할 수 있다. 통신이 연결되는 과정은 전송 제어 규약(TCP)의 역할과 연결해 읽는다. 두 규약이 같은 일을 한다고 설명하지 않도록, 메시지의 의미와 데이터 전송의 역할을 나누어 적는다.
두 번째는 서버 처리다. 서버는 입력을 확인하고 필요한 기능을 호출한다. 이 코드는 프로세스 안의 실행 흐름에서 동작하며, 스레드와 메모리 같은 자원을 사용한다. 다만 요청마다 새 스레드를 만드는지, 기존 스레드를 사용하는지, 다른 실행 방식을 쓰는지는 서버 구성에 따라 다르다. 개념 설명과 자신의 프로젝트에서 확인한 구조를 나누어 기록해야 한다.
세 번째는 데이터 조회다. 프로그램은 데이터베이스에 필요한 행을 요청한다. 이 구간에서는 테이블 간 관계와 키, 인덱스의 역할을 질문으로 남긴다. 구체적인 조인 작성과 실행 계획 해석, 트랜잭션 실습은 다음 장에서 자신의 테이블을 사용해 이어간다. 지금은 “어느 테이블에서 어떤 조건으로 데이터를 얻는가”를 설명할 정도의 지도를 만든다.
네 번째는 응답 구성이다. 조회 결과를 어떤 순서와 형태로 담을지 결정한다. 제목과 작성자처럼 이름으로 값을 찾는 항목은 매핑으로, 순서가 필요한 게시글 묶음은 목록으로 생각할 수 있다. 여기서 배열 기반 목록과 해시 테이블의 차이, 탐색 비용이 입력 크기에 따라 어떻게 달라지는지 읽을 이유가 생긴다.
실제 서비스에서는 네 구간이 더 세분화되거나 반복된다. 캐시가 있다면 데이터베이스를 읽지 않고 응답할 수도 있다. 따라서 이 그림은 모든 서버의 내부 구조를 고정한 모형이 아니다. 자신의 코드를 읽기 시작할 때 사용할 관찰 순서다. 각 단계 옆에 실제 파일명이나 함수명을 적으면 일반적인 설명이 프로젝트의 설명으로 바뀐다.
| 단계 | CS 질문 | 프로젝트에서 볼 곳 | 남길 증거 |
|---|---|---|---|
| 요청 수신 | 입력과 응답 상태는 어떻게 전달되는가 | 요청을 받는 함수와 요청 기록 | 경로·입력·상태를 적은 메모 |
| 서버 처리 | 코드는 어떤 실행 자원을 사용하는가 | 호출 관계와 서버 설정 | 확인한 사실과 미확인 사항 목록 |
| 데이터 조회 | 어떤 관계와 조건으로 행을 찾는가 | 조회 코드와 테이블 정의 | 테이블·조건·결과의 연결 그림 |
| 응답 구성 | 순서와 키 조회에 어떤 구조가 필요한가 | 결과 가공 코드와 응답 예시 | 자료구조 선택 이유 두 문장 |
핵심 개념을 질문과 설명으로 좁힌다
면접 준비를 위해서는 용어를 들었을 때 정의만 말하는 수준에서 한 걸음 더 나아가야 한다. “무엇인가”, “내 기능의 어디에 쓰이는가”, “언제 설명이 달라지는가”를 차례로 답해 본다. 자주 다루는 기반 개념을 먼저 익히되, 특정 질문이 반드시 나온다고 가정하지 않는다.
자료구조는 연산과 비용을 함께 말한다
배열 기반 목록, 해시 테이블, 스택, 큐를 먼저 비교한다. 이름을 네 개 외우는 대신 각 구조에서 자주 하는 연산을 적는다. 목록의 위치 접근, 해시 테이블의 키 조회, 스택의 마지막 항목 꺼내기, 큐의 먼저 들어온 항목 꺼내기를 구분한다. 그다음 시간 복잡도를 붙인다. 시간 복잡도는 특정 컴퓨터에서 걸린 초가 아니라 입력 크기에 따른 연산량의 증가 경향을 설명한다.
예를 들어 게시글 목록에서 식별자가 같은 항목을 반복해서 찾는다면 매번 처음부터 훑는 방식과 키로 찾는 방식을 비교할 수 있다. 해시 테이블의 조회를 설명할 때는 평균적인 조건에서 빠르다는 점과 충돌 등의 영향을 함께 말한다. 아직 사용하지 않은 구조를 프로젝트에 억지로 넣을 필요는 없다. 현재 구조가 필요한 연산에 맞는지 설명하는 것이 먼저다.
DB와 네트워크는 경계를 구분한다
데이터베이스(DB)에서는 기본 키와 외래 키, 인덱스, 트랜잭션의 목적을 먼저 정리한다. 인덱스는 읽기 경로를 도울 수 있지만 저장 공간과 변경 비용이 따른다. 트랜잭션은 관련 작업을 하나의 단위로 다루는 개념이며, 동시 실행에서 보이는 결과는 격리 수준과 구현에도 영향을 받는다. 이 장에서는 정의와 질문을 남기고, 자신의 테이블을 이용한 검증은 다음 장으로 연결한다.
네트워크에서는 요청과 응답의 구성, 상태 코드, 연결과 시간 초과를 먼저 읽는다. 서버가 응답을 만들었다는 사실과 클라이언트가 그 응답을 받았다는 사실은 구분해야 한다. 요청이 실패했을 때 다시 보내도 되는지는 작업의 의미와 서버 처리 방식에 달려 있다. 조회와 등록을 같은 방식으로 재시도한다고 가정하지 않고, 프로젝트에서 어떤 처리를 하는지 확인한다.
운영체제는 실행 주체와 공유 범위를 설명한다
운영체제에서는 프로세스와 스레드, 메모리 공유, 경쟁 상태를 먼저 다룬다. 같은 프로세스의 스레드는 여러 메모리 자원을 공유하므로, 공유 값을 여러 실행 흐름이 바꿀 때 순서에 따라 결과가 달라질 수 있다. 반대로 요청 처리 함수 안에 만든 값이라고 해서 다른 실행 흐름과 무조건 무관한 것도 아니다. 그 값이 공유 객체를 가리키는지 확인해야 한다.
처음부터 운영체제 내부의 모든 스케줄링 기법을 암기할 필요는 없다. “두 요청이 같은 값을 바꾼다면 무엇을 확인해야 하는가”라는 질문에서 시작한다. 공유 여부, 읽고 쓰는 범위, 동기화 여부를 설명한 뒤 더 필요한 내용을 읽는다. 서버 설정을 확인하지 못했다면 추측을 사실처럼 쓰지 않고 “실행 방식은 추가 확인이 필요하다”고 남긴다.
서재는 설명이 끊긴 지점부터 연결한다
서재의 책은 모두 첫 페이지부터 차례대로 읽는 목록이 아니다. 《비전공자를 위한 컴퓨터공학 지도》에서 요청 흐름과 관련된 분야의 위치를 잡고, 《개발자를 위한 컴퓨터 사이언스》에서 해당 개념을 읽는다. 그 뒤 자료구조의 연산 비교가 필요하면 《논리로 푸는 알고리즘》으로, 데이터 관계와 저장 방식이 궁금하면 《데이터베이스 개론》으로 이동한다.
아래 표와 도구의 “읽을 장”은 책의 실제 목차를 인용한 장명이 아니다. 독자가 가진 판본의 목차에서 찾아 읽을 주제다. 책마다 장 이름과 배치가 다를 수 있으므로, 표시된 주제를 포함하는 부분을 찾아 읽는다. 읽은 쪽수보다 읽고 나서 답할 수 있게 된 질문을 기록한다.
| 막힌 지점 | 연결할 자료 | 찾아 읽거나 할 일 | 다음 행동 |
|---|---|---|---|
| 분야 사이 관계가 흐림 | 《비전공자를 위한 컴퓨터공학 지도》 | 프로그램 실행과 통신의 큰 흐름 | 요청 그림에 분야 이름 붙이기 |
| 용어를 기능에 연결하기 어려움 | 《개발자를 위한 컴퓨터 사이언스》 | 프로세스·스레드·네트워크 | 프로젝트 코드 위치 연결하기 |
| 자료구조 선택 이유가 약함 | 《논리로 푸는 알고리즘》, 코드패스 | 연산 비용을 읽고 작은 입력으로 비교 | 입력 크기에 따른 차이 설명하기 |
| 조회 구조가 잘 보이지 않음 | 《데이터베이스 개론》, SQL 연구소 | 키와 관계를 읽고 내 조회 조건 정리 | 다음 장의 테이블 실습 질문 남기기 |
| 이해를 코드에 반영하기 어려움 | 《클린 코드 노하우》, 《코드 리뷰 실무》 | 책임 구분과 변경 이유를 읽기 | 설명하기 어려운 함수에 검토 메모 쓰기 |
| 말로 설명하면 순서가 흐트러짐 | 《개발자 실무 면접》 | 개념과 사례를 연결하는 부분 읽기 | 정의·적용·한계 순서로 답변 녹음하기 |
코드패스에서는 이 장에서 고른 자료구조 주제를 작은 코드로 확인하는 데 시간을 쓴다. SQL 연구소에서는 조회 조건과 테이블 관계를 정리해 다음 장의 실습으로 연결한다. 어느 공간을 사용하든 활동 자체를 완료 기준으로 삼지 않는다. 예를 들어 “목록 순회와 키 조회의 차이를 입력 크기와 함께 설명했다”처럼 확인 가능한 결과를 남긴다.
한 번에 고를 질문은 두 개 정도면 충분하다. 요청 수신이 막혔다면 요청·응답 구조와 연결의 역할을 먼저 고른다. 서버의 실행 방식까지 같은 날 끝내려 하지 않는다. 책을 읽고 프로젝트를 확인한 뒤 설명이 여전히 끊기는 문장을 다음 질문으로 남긴다. 이런 반복이 공부 범위를 줄이면서도 빠진 부분을 드러낸다.
| 확인 | 할 일 | 남길 자료 | 완료 기준 |
|---|---|---|---|
| □ | 내가 맡았던 요청 하나 고르기 | 입력과 응답 예시 | 요청 목적을 한 문장으로 설명함 |
| □ | 네 단계에 코드 위치 적기 | 파일명과 함수명 메모 | 미확인 구간도 따로 표시함 |
| □ | 막힌 질문 두 개 읽고 확인하기 | 읽을 주제와 관찰 기록 | 정의와 프로젝트 사례를 연결함 |
| □ | 학습 목록 도구 실행하기 | 실행 명령과 출력 | 단계 변경과 잘못된 입력을 확인함 |
| □ | 질문 하나를 소리 내어 설명하기 | 짧은 녹음 또는 답변 원고 | 확인한 사실과 한계를 구분함 |
완료 증거는 요청 흐름 메모 한 장, 질문 두 개에 대한 설명, 도구 실행 기록이다. 메모에는 실제 코드 위치와 아직 확인하지 못한 사항이 함께 있어야 한다. 설명에는 용어 정의뿐 아니라 자신의 기능에서 그 개념이 필요한 이유가 들어가야 한다. 잘 모르는 항목이 남아 있어도 다음에 확인할 질문으로 좁혔다면 이번 주의 작업을 마칠 수 있다.
완성 코드
다음 코드를 main.py로 저장한다. 명령행 인수가 없으면 네 단계를 모두 사용한다. 인수가 있으면 그 단계만 입력 순서대로 처리한다. 같은 단계를 여러 번 넣어도 한 번만 출력하며, 등록되지 않은 단계는 안내 문구를 남기고 건너뛴다. 외부 파일이나 네트워크를 사용하지 않으므로 같은 인수에는 같은 결과가 나온다.
import sys
GUIDE = {
"요청 수신": (
("네트워크", "HTTP 요청·응답, TCP의 역할"),
(
"《비전공자를 위한 컴퓨터공학 지도》: 통신의 큰 흐름",
"《개발자를 위한 컴퓨터 사이언스》: 요청·응답과 연결",
),
),
"서버 처리": (
("운영체제", "프로세스·스레드, 공유 메모리"),
(
"《비전공자를 위한 컴퓨터공학 지도》: 프로그램 실행",
"《개발자를 위한 컴퓨터 사이언스》: 실행 단위와 자원",
),
),
"데이터 조회": (
("DB", "키와 관계, 인덱스의 역할"),
(
"《개발자를 위한 컴퓨터 사이언스》: 데이터 저장",
"《데이터베이스 개론》: 키·관계·인덱스",
),
),
"응답 구성": (
("자료구조", "목록과 매핑, 탐색 비용"),
(
"《개발자를 위한 컴퓨터 사이언스》: 자료구조",
"《논리로 푸는 알고리즘》: 탐색과 시간 복잡도",
),
),
}
def make_plan(steps: list[str]) -> list[str]:
lines = ["CS 연결 계획", "읽을 장은 실제 목차에서 찾을 주제다."]
seen: set[str] = set()
for raw_step in steps:
step = raw_step.strip()
if step in seen:
continue
seen.add(step)
entry = GUIDE.get(step)
if entry is None:
lines.append(f"[건너뜀] 등록되지 않은 단계: {step!r}")
continue
topic, readings = entry
field, concepts = topic
lines.append(f"[{step}]")
lines.append(f" CS: {field} / {concepts}")
lines.append(" 읽을 장:")
for reading in readings:
lines.append(f" - {reading}")
lines.append("완료 증거: 단계별 코드 위치와 설명 두 문장")
return lines
def main() -> None:
steps = sys.argv[1:] or list(GUIDE)
print("\n".join(make_plan(steps)))
if __name__ == "__main__":
main()
이 프로그램은 프로젝트 소스를 분석하지 않는다. 입력한 단계와 미리 작성한 학습 지도를 연결한다. 따라서 출력된 목록을 공부 완료 판정으로 받아들이면 안 된다. 자신이 이미 설명할 수 있는 주제는 빠르게 확인하고, 설명이 막히는 주제를 이번 주 질문으로 고르는 데 사용한다.
줄별 해설
import sys는 실행할 때 전달한 인수를 읽기 위해 사용한다. sys.argv의 첫 항목은 실행 파일 이름이므로 [1:]로 그 뒤의 값만 가져온다. 문자열 안에 공백이 있는 단계는 실행 명령에서 따옴표로 묶어 하나의 인수로 전달한다.
GUIDE는 단계 이름을 키로 사용하는 딕셔너리다. 값에는 CS 분야와 개념의 묶음, 읽을 주제의 묶음이 차례로 들어 있다. 키로 단계를 찾는 작업과 출력 순서를 정하는 작업은 구분된다. 이 프로그램의 기본 순서는 딕셔너리에 단계를 작성한 순서다. Python 3.12에서는 이 삽입 순서가 유지된다.
make_plan은 단계 문자열 목록을 받아 출력할 문자열 목록을 돌려준다. 함수 안에서 바로 출력하지 않으므로, 결과를 비교하거나 다른 출력 방식으로 바꾸기 쉽다. list[str]은 문자열 목록을 기대한다는 형 표기다. 이 표기가 실행 중 모든 입력의 형을 자동 검사하는 것은 아니다.
lines에는 제목과 읽기 안내를 먼저 담는다. seen은 이미 처리한 단계 이름을 저장하는 집합이다. 집합은 중복 확인에만 사용하고 출력 순서를 만드는 데 사용하지 않는다. 따라서 출력은 steps를 순회한 순서를 따른다.
strip()은 각 인수의 앞뒤 공백을 제거한다. 그다음 이미 처리한 이름이면 continue로 다음 입력으로 넘어간다. 처음 본 이름은 곧바로 집합에 넣으므로, 같은 잘못된 입력을 반복해도 안내가 한 번만 나온다. 공백만 있는 입력은 빈 문자열이 되며 등록되지 않은 단계로 안내된다.
GUIDE.get(step)은 이름에 대응하는 값을 찾는다. 이 지도에는 None을 값으로 저장하지 않으므로, 반환값이 None이면 등록되지 않은 단계로 판단할 수 있다. {step!r}은 빈 문자열과 공백 문제도 알아보기 쉽도록 문자열의 표현을 출력한다.
topic, readings = entry와 그다음 줄은 중첩된 묶음을 이름 붙여 나누는 부분이다. 분야와 개념을 한 줄에 넣고, 읽을 주제는 반복문으로 각각 추가한다. 문자열 목록을 만든 뒤 마지막에 반환하므로 입력 처리와 화면 출력의 책임이 나뉜다.
main의 or list(GUIDE)는 인수가 없을 때 기본 네 단계를 선택한다. "\n".join(...)은 결과 목록을 줄바꿈으로 연결하며, print가 마지막 줄바꿈을 붙인다. 마지막 조건문은 이 파일을 직접 실행했을 때만 main을 호출하도록 한다.
실행 결과
macOS 또는 Linux 터미널에서 파일이 있는 디렉터리로 이동해 실행한다. 기본 실행의 명령과 예상 출력은 다음과 같다.
python3 main.py
CS 연결 계획
읽을 장은 실제 목차에서 찾을 주제다.
[요청 수신]
CS: 네트워크 / HTTP 요청·응답, TCP의 역할
읽을 장:
- 《비전공자를 위한 컴퓨터공학 지도》: 통신의 큰 흐름
- 《개발자를 위한 컴퓨터 사이언스》: 요청·응답과 연결
[서버 처리]
CS: 운영체제 / 프로세스·스레드, 공유 메모리
읽을 장:
- 《비전공자를 위한 컴퓨터공학 지도》: 프로그램 실행
- 《개발자를 위한 컴퓨터 사이언스》: 실행 단위와 자원
[데이터 조회]
CS: DB / 키와 관계, 인덱스의 역할
읽을 장:
- 《개발자를 위한 컴퓨터 사이언스》: 데이터 저장
- 《데이터베이스 개론》: 키·관계·인덱스
[응답 구성]
CS: 자료구조 / 목록과 매핑, 탐색 비용
읽을 장:
- 《개발자를 위한 컴퓨터 사이언스》: 자료구조
- 《논리로 푸는 알고리즘》: 탐색과 시간 복잡도
완료 증거: 단계별 코드 위치와 설명 두 문장
이번 주에 요청 수신만 공부한다면 다음처럼 범위를 좁힌다. 같은 단계를 반복해도 한 번만 나오며, 잘못된 이름은 실행을 중단하지 않고 표시된다.
python3 main.py "요청 수신" "요청 수신" "없는 단계"
CS 연결 계획
읽을 장은 실제 목차에서 찾을 주제다.
[요청 수신]
CS: 네트워크 / HTTP 요청·응답, TCP의 역할
읽을 장:
- 《비전공자를 위한 컴퓨터공학 지도》: 통신의 큰 흐름
- 《개발자를 위한 컴퓨터 사이언스》: 요청·응답과 연결
[건너뜀] 등록되지 않은 단계: '없는 단계'
완료 증거: 단계별 코드 위치와 설명 두 문장
문법 검사와 실행을 나누어 확인하려면 다음 두 명령을 순서대로 실행한다. 첫 명령은 정상일 때 출력이 없으며, 두 번째 명령의 출력은 위의 기본 실행 결과와 같다. 문법 검사는 학습 지도의 내용이 옳은지까지 판정하지 않으므로, 출력과 요청 단계의 연결도 함께 읽어야 한다.
python3 -W error -m py_compile main.py
python3 main.py
실무에서 자주 틀리는 것
출력 순서가 필요한 입력을 집합으로 바꾼다
중복을 없애려고 다음처럼 작성하면 사용자가 준 순서를 보존하지 못한다. 집합의 순회 순서를 화면 출력의 약속으로 삼으면 안 된다.
# 틀린 코드
for step in set(steps):
print(step)
# 고친 코드
seen = set()
for step in steps:
if step in seen:
continue
seen.add(step)
print(step)
고친 코드는 입력 목록을 순회하면서 집합에는 처리 여부만 저장한다. 순서를 보존할 책임과 중복을 확인할 책임을 나누는 예다. 완성 코드에서는 공백을 정리한 이름을 기준으로 이 처리를 한다.
등록되지 않은 입력도 존재한다고 가정한다
명령행 입력은 지도에 있는 값만 들어온다고 보장할 수 없다. 키로 바로 접근하면 오타 하나가 전체 실행을 중단시킬 수 있다.
# 틀린 코드
entry = GUIDE[step]
# 고친 코드
entry = GUIDE.get(step)
if entry is None:
lines.append(f"[건너뜀] 등록되지 않은 단계: {step!r}")
continue
고친 부분은 반복문 안에서 사용한다. 실패를 숨기지 않고 표시한 뒤 다른 유효한 입력의 처리를 이어간다. 업무 프로그램에서 입력을 거절할지 건너뛸지는 목적에 따라 정해야 한다. 이 도구는 여러 학습 단계를 한 번에 받으므로 건너뛰는 방식을 선택했다.
문자열이 포함된 횟수를 실행 시간이라고 부른다
복잡도를 공부하다가 반복 횟수와 실제 시간을 섞어 설명하기 쉽다. 다음 코드는 찾는 값이 마지막에 있다고 가정할 때 검사할 항목 수를 적은 것이다. 실행 시간을 측정한 값이 아니다.
# 틀린 코드
items = [10, 20, 30]
elapsed_seconds = len(items)
print(f"실행 시간: {elapsed_seconds}초")
# 고친 코드
items = [10, 20, 30]
checks_if_last = len(items)
print(f"마지막 항목까지 순회할 때 검사 수: {checks_if_last}")
비용을 설명할 때는 무엇을 센 것인지 이름에 드러낸다. 실제 시간은 실행 환경과 데이터 상태에도 영향을 받는다. 복잡도 설명과 시간 측정은 서로 보완할 수 있지만 같은 결과를 뜻하지 않는다.
설정과 공유 범위를 보지 않고 안전하다고 적는다
요청 처리에 쓰이는 값을 함수 안에서 읽었다는 이유만으로 공유 문제가 없다고 판단하면 안 된다. 다음 예시는 여러 실행 흐름이 같은 딕셔너리를 바꿀 가능성이 있다.
# 틀린 코드: 공유 값의 읽기와 쓰기를 보호하지 않는다.
counter = {"value": 0}
def record_request():
counter["value"] += 1
같은 프로세스 안의 여러 스레드가 이 값을 갱신한다는 조건이라면, 관련 접근이 같은 잠금을 사용하도록 설계할 수 있다. 다음 코드는 그 조건에서 사용할 수 있는 수정 예다.
from threading import Lock
counter = {"value": 0}
counter_lock = Lock()
def record_request():
with counter_lock:
counter["value"] += 1
이 잠금이 여러 프로세스나 여러 서버의 값을 한꺼번에 보호하지는 않는다. 또한 다른 코드가 잠금 없이 같은 값을 바꾸면 보호 범위가 깨진다. 운영체제 공부에서는 수정 문법만 외우기보다 어떤 실행 흐름이 무엇을 공유하는지 먼저 그리는 습관이 필요하다.
한눈에 보기
| 분야 | 먼저 설명할 개념 | 프로젝트 연결 질문 | 완료 증거 |
|---|---|---|---|
| 자료구조 | 목록·매핑과 연산 비용 | 왜 이 형태로 결과를 담았는가 | 다른 선택과 비교한 두 문장 |
| DB | 키·관계·인덱스의 목적 | 어떤 조건으로 어떤 행을 찾는가 | 조회 흐름과 다음 실습 질문 |
| 네트워크 | 요청·응답과 연결의 역할 | 입력과 실패를 어떻게 구분하는가 | 요청 예시와 응답 상태 메모 |
| 운영체제 | 프로세스·스레드와 공유 | 동시에 실행되면 무엇을 공유하는가 | 실행 구조의 확인·미확인 목록 |
학습 목록 생성기가 출력한 주제는 출발점이다. 실제 완료 여부는 코드 위치를 짚고 선택의 이유와 한계를 말할 수 있는지로 판단한다. 다음 장에서는 여기서 남긴 데이터 조회 질문을 가져가 조인·인덱스·트랜잭션을 자신의 프로젝트 테이블로 확인한다.
연습 문제
- 명령행에
"응답 구성" "요청 수신" "응답 구성"을 전달하면 어떤 단계가 어떤 순서로 출력되는지 적는다. 코드에서 그 순서를 결정하는 부분과 중복을 막는 부분을 각각 찾는다. make_plan([" 요청 수신 ", "요청 수신", " "])이 만드는 단계 출력과 건너뜀 안내를 예상한다. 빈 입력이 기본 네 단계로 바뀌는지도 설명한다.- 학습 지도에
"공유 값 변경"단계를 추가한다. 분야는 운영체제, 개념은 경쟁 상태와 동기화로 정하고 읽을 주제 두 개를 연결한다. 기존 단계의 상대적인 순서를 유지한다. - 자신의 프로젝트 요청 하나를 골라 네 단계 중 두 단계의 코드 위치를 적는다. 각 단계마다 “확인한 사실”, “설명을 위해 읽을 주제”, “아직 모르는 점”을 한 문장씩 쓴다.
정답과 해설
-
응답 구성,요청 수신순서로 한 번씩 출력된다. 순서는for raw_step in steps가 입력 목록을 차례대로 읽기 때문에 유지된다. 중복은seen에 이미 들어 있는지 확인하여 막는다. 지도에 등록된 순서는 인수를 생략했을 때 기본 목록을 만드는 데 사용된다. -
앞뒤 공백을 제거한 두 요청 수신 입력은 같은 이름이므로 해당 단계는 한 번만 출력된다. 공백만 있는 입력은 빈 문자열이 되어 다음 안내가 한 번 추가된다.
[건너뜀] 등록되지 않은 단계: ''기본 네 단계로 바뀌지 않는다. 기본값 선택은
main에서 명령행 인수 목록이 비었을 때 수행한다. 이 문제는make_plan에 세 항목이 있는 목록을 직접 전달했으므로 각 항목을 그대로 처리한다. -
GUIDE의 마지막 항목 뒤에 다음 항목을 추가할 수 있다. 기존 네 단계의 상대적인 순서는 유지되며 기본 실행의 끝에 새 단계가 붙는다. 읽을 주제는 실제 목차에서 대응하는 부분을 찾기 위한 표현이다."공유 값 변경": ( ("운영체제", "경쟁 상태와 동기화"), ( "《비전공자를 위한 컴퓨터공학 지도》: 동시 실행", "《개발자를 위한 컴퓨터 사이언스》: 공유 자원과 동기화", ), ),추가 후
python3 main.py "공유 값 변경"으로 새 항목을 확인한다. 기본 실행에도 새 항목이 포함되는지 확인하면 등록 위치와 기본 순서의 관계를 볼 수 있다. -
답은 프로젝트마다 다르다. 예를 들어 “요청 수신 함수에서 페이지 번호를 읽는 코드를 확인했다”, “요청 매개변수와 응답 상태를 읽겠다”, “잘못된 페이지 번호의 처리 경로는 아직 확인하지 못했다”처럼 쓸 수 있다. 서버 처리 단계에서는 실제 설정을 보지 않고 요청마다 스레드가 생긴다고 단정하지 않는다. 코드 위치를 제시하고 미확인 사항을 좁혔는지가 답의 기준이다.
READER FEEDBACK
질문·의견
내용에 관한 질문이나 더 나은 설명을 위한 의견을 남겨 주세요. 오탈자는 위의 제보 양식이 더 빨리 반영됩니다. 이 댓글은 원래 게시글과 같은 자리에 쌓입니다.
댓글 0
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.