2023년 2회 실전 E20

C 가 7문항으로 11회 중 가장 많다. 빈칸 셋 · 스택 · 공유 버퍼 · break 없는 switch. 용어는 HDLC 와 오류 제어 5칸 매칭 둘이 무겁다

왜 이 장을 하나
이 회차는 C 만 7문항이다. 코드가 어려운 것이 아니라 양이 많아 시간이 새는 회차라, 1회독 100분에서 C 한 문항에 5분을 넘기면 답 칸을 비우고 넘어가는 규칙을 시험한다. 용어 11문항 중 5칸 매칭이 둘(19 · 20번)이라 부분 점수를 최대로 받는 연습도 된다.
다루는 것2023년 2회 20문항 · 복원본
시계150분 · 실제 시험과 같다
끝나면문항마다 가는 장이 표로 나온다

01푸는 법

왜 이걸 하나 — 세트는 시험장과 같은 조건에서만 숫자가 된다. 조건은 E01 과 같다.

규칙은 E01 진단의 01절 그대로다. 시작을 누르면 150분이 돌고, 1회독 100분 · 2회독 40분 · 검토 10분으로 나눈다. 한 문항에 5분이 넘으면 답 칸을 비우고 넘어가며, 정답은 20문항을 다 적은 뒤에 연다.

이 회차의 배점은 프로그래밍 9문항(45점) · 보안 3문항(15점) · SQL·DB 3문항(15점) · 테스트 2문항(10점) · 네트워크 2문항(10점) · 디자인 패턴 1문항(5점)이다. 코드 문항 수만큼 5분씩을 1회독에서 먼저 떼어 두고, 남는 시간을 용어에 쓴다. 용어는 아는 것을 바로 적고 모르는 것은 비운다 — 용어에서 고민하는 시간이 코드 한 문항의 값이다.

자가 판정은 답안지에 그대로 적었을 때 채점자가 맞다고 할 것인가 하나다. 철자 하나, 줄바꿈 하나, 기호 대신 이름이면 틀렸다를 누른다. 후하게 준 5점은 시험장에서 사라진다.

02실전 세트

왜 이걸 하나 — 20문항을 한 번에 150분 안에 푸는 것 자체가 연습이다. 분야 장의 문제와 같은 문항이어도 조건이 다르다.

시작을 누르면 시계가 돌고 화면을 닫아도 이어진다. 다 적은 뒤 문항마다 정답 보기 → 맞았다 · 틀렸다를 누르면 위 막대에 점수와 분야별 결과가 모인다. 이 세트에서 채점한 기록은 분야 장의 같은 문항에도 그대로 보인다.

2023-2회 · 1번SQL

학생 테이블(학번, 이름, 학년, 과목, 전화번호)에 학번 98170823, 이름 '한국산', 3학년, '경영학개론', '050-1234-1234'인 학생을 삽입하는 SQL을 작성하시오.

정답INSERT INTO 학생 VALUES(98170823, '한국산', 3, '경영학개론', '050-1234-1234');

INSERT INTO 학생 VALUES(98170823, '한국산', 3, '경영학개론', '050-1234-1234');

원리 — 행을 넣는 명령은 INSERT INTO 테이블 VALUES(값들) 이다. 열 이름을 생략하면 값을 테이블의 열 순서(학번, 이름, 학년, 과목, 전화번호)대로 전부 적어야 한다. 숫자는 그대로, 문자열은 작은따옴표로 감싼다. 전화번호는 숫자처럼 보여도 하이픈이 있어 문자열이다. 열을 골라 넣으려면 INSERT INTO 학생(학번, 이름) VALUES(…) 처럼 열 목록을 적는다.

따라가기

  1. INSERT INTO 학생
  2. VALUES(98170823, '한국산', 3, '경영학개론', '050-1234-1234')
  3. 값 다섯 개가 열 다섯 개와 순서 · 개수가 맞는다

헷갈리는 자리 — 학년 3 을 '3' 으로 감싸는 것(틀리진 않지만 숫자 열은 숫자로), 전화번호의 따옴표를 빼는 것(오류). 값 순서를 바꾸면 열과 어긋난다. VALUES 를 VALUE 로 적는 것도 오류다.

답의 SQL 을 sqlite 3.49 에서 실행해 확인했다. 복원 출처 grandlife.co.kr(2026-09-14) — 공식 원문이 아니라 문장 · 열 이름이 실제와 다를 수 있다.

2023-2회 · 2번SQL

뷰(VIEW)를 제거할 때, 그 뷰를 참조하는 다른 뷰나 제약조건까지 연쇄적으로 함께 제거하는 DROP 옵션은?

정답CASCADE

— CASCADE. 뷰를 지울 때 그것에 기대고 있는 다른 뷰 · 제약까지 함께 지우는 옵션이다.

원리 — 뷰는 다른 테이블이나 뷰 위에 세운 창이다. 어떤 뷰 위에 또 다른 뷰가 서 있을 때 아래 것을 지우면 위 것이 허공에 뜬다. DROP VIEW 이름 CASCADE 는 "위에 기댄 것까지 연쇄로 지워라", RESTRICT 는 "기댄 것이 있으면 지우지 말고 막아라"다. 같은 짝이 DROP TABLE 에도 있다. cascade 는 폭포처럼 아래로 번진다는 뜻이다.

따라가기

  1. 지우려는 뷰를 참조하는 뷰 · 제약이 있다
  2. 함께 지우려면 → CASCADE
  3. 막으려면 → RESTRICT

헷갈리는 자리 — RESTRICT 와 반대로 적는 것. "연쇄 · 함께" 가 나오면 CASCADE, "막는다 · 거부" 가 나오면 RESTRICT 다. 외래키의 ON DELETE CASCADE 도 같은 낱말이라 문맥이 뷰인지 외래키인지 본다. 옵션을 아예 안 적으면 DBMS 마다 기본값이 달라(대개 RESTRICT), 시험 답으로는 문제가 묻는 낱말 하나만 적는다.

SQL 표준 · 교재 정의와 대조했다. 복원 출처 grandlife.co.kr(2026-09-14) — 공식 원문이 아니라 문장이 실제와 다를 수 있다.

2023-2회 · 3번DB

데이터베이스 설계 4단계를 순서대로 나열하시오: (개념적 설계 / 물리적 설계 / 논리적 설계 / 요구사항 분석)

정답요구사항 분석 → 개념적 설계 → 논리적 설계 → 물리적 설계 (→ 구현)

— 요구사항 분석 → 개념적 설계 → 논리적 설계 → 물리적 설계 (→ 구현). 추상적인 것에서 구체적인 것으로 내려가는 순서다.

원리 — 데이터베이스는 집을 짓듯 설계한다. 먼저 무엇이 필요한지 듣고(요구사항 분석), 그것을 개체와 관계의 그림으로 그리고(개념적 설계 — E-R 다이어그램), 그 그림을 쓸 DBMS 종류에 맞는 표 구조로 바꾸고(논리적 설계 — 테이블 · 정규화), 마지막으로 저장 장치에 어떻게 놓을지(물리적 설계 — 인덱스 · 파일 구조) 정한 뒤 실제로 만든다(구현). 단계마다 "누가 봐도 같은 그림 → DBMS 에 맞춤 → 디스크에 맞춤"으로 구체성이 올라간다.

따라가기

  1. 요구사항 분석 — 무엇을 담을지
  2. 개념적 설계 — E-R 그림
  3. 논리적 설계 — 표 · 정규화
  4. 물리적 설계 — 인덱스 · 저장 구조 → 구현

헷갈리는 자리 — 논리와 물리를 바꾸는 것. 논리적 설계에 정규화 · 트랜잭션 인터페이스 설계가, 물리적 설계에 접근 경로 · 인덱스가 들어간다는 것으로 구분한다. 2026년 1회 4번은 구현까지 다섯 단계로 물었다.

교재 정의(관계형 모델 · 정규화 · 트랜잭션 표준 용어)와 대조했다. 복원 출처 grandlife.co.kr(2026-09-14) — 공식 원문이 아니라 문장이 실제와 다를 수 있다.

2023-2회 · 4번C

다음 C 프로그램의 실행 결과를 쓰시오.

#include <stdio.h> int main(void) { int count = 0; for (int number = 1; number <= 2023; number++) { if (number % 4 == 0) { count++; } } printf("%d", count); return 0; }
정답505

— 505. 1 부터 2023 까지 4 의 배수가 몇 개인지 세는 코드이고, 2023 ÷ 4 = 505.75 이므로 505 개다.

원리number % 4 == 0 은 "4 로 나눠 나머지가 없다", 즉 4 의 배수라는 뜻이다. 1 부터 N 까지 k 의 배수 개수는 N 을 k 로 나눈 몫이다 — 4, 8, 12, … 처럼 k 칸마다 하나씩 있기 때문이다. 코드는 2023 번 반복하며 하나씩 세지만 손으로는 나눗셈 한 번이면 된다. 시험에서는 반복문을 실제로 돌리지 말고 "무엇을 세는가"를 읽어 수식으로 바꾸는 것이 시간을 아끼는 길이다.

따라가기

  1. 4 의 배수: 4, 8, 12, …, 2020 (2020 = 4 × 505)
  2. 2024 는 범위 밖(number <= 2023)
  3. 개수 = 2023 ÷ 4 의 몫 = 505

헷갈리는 자리 — 505.75 를 반올림해 506 으로 적는 것. 마지막 배수 2020 뒤에 2024 는 없으니 몫만 센다. 범위가 < 2023 이어도 2023 은 배수가 아니라 답이 같지만, 2024 까지였다면 506 이다 — 끝 값이 배수인지 확인하는 습관을 둔다.

복원 코드를 gcc(도커 alpine)로 실행해 같은 출력을 확인했다. 복원 출처 grandlife.co.kr(2026-09-14) — 공식 원문이 아니라 문장 · 변수명이 실제와 다를 수 있다.

2023-2회 · 5번Python

다음 Python 프로그램의 실행 결과를 쓰시오.

text = "engineer information processing" first = text[:3] second = text[4:6] third = text[28:] print(first + second + third)
정답engneing

— engneing. 세 조각 eng · ne · ing 을 이어 붙인 것이다.

원리 — 슬라이스 text[a:b] 는 첨자 a 부터 b 까지다. 첨자는 0 부터 세고 b 번째 글자는 안 들어간다. [:3] 은 처음부터 첨자 2 까지 세 글자, [4:6] 은 첨자 4 · 5 두 글자, [28:] 은 첨자 28 부터 끝까지다. 첨자를 세려면 문자열 위에 0 1 2 … 를 적는다. 공백도 한 칸이다.

따라가기 — "engineer information processing" (공백 포함 31글자).

  1. [:3] → 첨자 0 · 1 · 2 → eng
  2. [4:6] → 첨자 4 · 5 → e n g i n ene
  3. [28:] → 첨자 28 부터 끝 → "processing" 의 마지막 세 글자 → ing
  4. 이어서 engneing

헷갈리는 자리 — [4:6] 을 첨자 4 · 5 · 6 세 글자로 세어 "nee" 를 넣는 것. 끝 첨자는 빠진다. [28:] 을 세다 공백을 빼먹으면 자리가 밀린다 — "engineer"(8) + 공백(1) + "information"(11) + 공백(1) = 21 이라 "processing" 은 첨자 21 부터, 28 은 그중 8번째 글자 i 부터다.

복원 코드를 Python 3.12 로 실행해 같은 출력을 확인했다. 복원 출처 grandlife.co.kr(2026-09-14) — 공식 원문이 아니라 문장 · 변수명이 실제와 다를 수 있다.

2023-2회 · 6번테스트

결정 포인트 내의 모든 개별 조건식이 참 한 번, 거짓 한 번을 갖도록 테스트케이스를 설계하는 화이트박스 커버리지는?

정답조건 커버리지 (Condition Coverage)

— 조건 커버리지(Condition Coverage). 결정문 전체가 아니라 그 안의 "개별 조건식" 하나하나가 참 · 거짓을 한 번씩 갖게 하는 기준이다.

원리 — if (A && B) 에서 결정(decision)은 A && B 전체의 결과이고, 조건(condition)은 A 와 B 각각이다. 분기(결정) 커버리지는 A && B 가 참 한 번, 거짓 한 번이면 만족한다 — (T,T) 와 (F,T) 두 케이스면 되고 이때 B 는 늘 참이다. 조건 커버리지는 A 도 T/F, B 도 T/F 를 각각 한 번씩 가져야 한다 — (T,F) 와 (F,T) 두 케이스로 만족하는데, 이러면 A && B 는 둘 다 거짓이라 결정 커버리지는 오히려 미달이다. 그래서 둘은 서로를 포함하지 않고, 둘을 합친 것이 조건/결정 커버리지다.

따라가기

  1. "결정 포인트 내의 모든 개별 조건식" → 결정이 아니라 조건 하나하나
  2. "참 한 번, 거짓 한 번" → 조건 커버리지

헷갈리는 자리 — 분기(결정) 커버리지로 적는 것. 문장에 "개별 조건식"이 있으면 조건 커버리지, "분기 · 결정 결과"가 있으면 결정 커버리지다. 강도 순서는 구문 < 결정 < 조건 < 조건/결정 < MC/DC < 다중 조건인데, 조건이 결정보다 "강하다"기보다 "다른 것을 본다"는 점을 기억한다.

표준 · 교재 정의(ISTQB 용어 · 커버리지 6단계 · 테스트 수준)와 대조했다. 복원 출처 grandlife.co.kr(2026-09-14) — 공식 원문이 아니라 문장이 실제와 다를 수 있다.

2023-2회 · 7번테스트

통합 테스트에서 ① 하향식 테스트 시 아직 개발되지 않은 하위 모듈을 대신하는 임시 모듈 ② 상향식 테스트 시 상위 모듈을 대신해 테스트를 구동하는 임시 모듈은?

정답① 스텁(Stub) ② 드라이버(Driver)

— ① 스텁(Stub) ② 드라이버(Driver). 하향식에는 아래를 대신하는 스텁, 상향식에는 위를 대신하는 드라이버가 필요하다.

원리 — 통합 테스트는 모듈을 붙여 가며 검사하는데, 아직 없는 모듈의 자리를 가짜로 채워야 한다. 하향식(top-down)은 위(메인)부터 만들고 아래로 내려간다 — 위 모듈이 부르는 아래 모듈이 아직 없으니, 호출되면 정해진 값을 돌려주는 가짜 하위 모듈이 필요하다. 그것이 스텁이다(그루터기 — 잘려 나간 자리). 상향식(bottom-up)은 아래(말단)부터 만들고 위로 올라간다 — 아래 모듈을 불러 줄 위 모듈이 없으니, 대신 호출해 주는 가짜 상위 모듈이 필요하다. 그것이 드라이버다(운전자 — 부르는 쪽).

따라가기

  1. 하향식 · "하위 모듈을 대신" → 호출당하는 가짜 → 스텁
  2. 상향식 · "상위 모듈을 대신해 구동" → 호출하는 가짜 → 드라이버

헷갈리는 자리 — 둘을 바꾸는 것. "드라이버는 운전(호출)하는 쪽 = 위", "스텁은 잘린 그루터기 = 아래"로 붙잡는다. 하향식은 스텁이 많이 들고, 상향식은 드라이버가 든다. 같은 문제가 2026-1-15 에 다시 나왔다.

표준 · 교재 정의(ISTQB 용어 · 커버리지 6단계 · 테스트 수준)와 대조했다. 복원 출처 grandlife.co.kr(2026-09-14) — 공식 원문이 아니라 문장이 실제와 다를 수 있다.

2023-2회 · 8번Java

다음 Java 프로그램의 실행 결과를 줄마다 쓰시오.

public class Main { public static void main(String[] args) { String first = "Programming"; String second = "Programming"; String third = new String("Programming"); System.out.println(first == second); System.out.println(first == third); System.out.println(first.equals(third)); System.out.println(second.equals(third)); } }
정답true
false
true
true

— true / false / true / true. == 는 같은 객체인지, equals 는 글자 내용이 같은지를 묻는다.

원리 — 자바에서 문자열 변수는 글자 자체가 아니라 글자 덩어리가 놓인 자리(참조)를 든다. "Programming" 처럼 따옴표로 쓴 글자는 같은 글자면 하나만 만들어 공유한다(문자열 풀). 그래서 first 와 second 는 같은 덩어리를 가리키고 == 가 true 다. new String(…) 은 "무조건 새 덩어리를 만들어라"이므로 third 는 다른 자리에 있고, first 와 == 하면 false 다. 내용을 견주려면 equals 를 써야 하고 그것은 세 변수 모두 true 다.

따라가기

  1. first == second → 같은 풀의 덩어리 → true
  2. first == third → new 로 만든 다른 덩어리 → false
  3. first.equals(third) → 글자 같음 → true
  4. second.equals(third) → true

헷갈리는 자리 — 둘째 줄을 true 로 적는 것. 글자가 같아도 new 는 새 객체다. 반대로 첫째 줄을 false 로 적는 것 — 따옴표 글자는 공유된다. == 는 "같은 집인가", equals 는 "같은 내용인가"로 나눠 외운다.

복원 코드를 JDK 17 로 컴파일 · 실행해 같은 출력을 확인했다. 복원 출처 grandlife.co.kr(2026-09-14) — 공식 원문이 아니라 문장 · 변수명이 실제와 다를 수 있다.

2023-2회 · 9번C

정수 다섯 개를 배열에 입력한 뒤 첫 번째 값을 맨 뒤로 보내 출력하려고 한다. ①에 들어갈 식을 쓰시오.

#include <stdio.h> int main(void) { int values[5]; int i; for (i = 0; i < 5; i++) { scanf("%d", &values[i]); } for (i = 0; i < 5; i++) { printf("%d", values[( ① )]); } return 0; }
정답(i + 1) % 5

(i + 1) % 5. i 가 0 · 1 · 2 · 3 일 때는 다음 칸(1 · 2 · 3 · 4)을, i 가 4 일 때는 5 % 5 = 0 으로 첫 칸을 가리켜 첫 값이 맨 뒤로 간다.

원리 — 나머지 연산 % 는 회전판이다. 어떤 수를 5 로 나눈 나머지는 0 · 1 · 2 · 3 · 4 만 나오고, 5 가 되는 순간 다시 0 으로 돌아간다. 그래서 "첨자 하나 앞으로, 끝에 닿으면 처음으로"라는 움직임은 언제나 (첨자 + 1) % 크기 로 적는다. 원형 큐나 시계의 시침이 같은 규칙이다. 첫 번째 값을 맨 뒤로 보낸다는 말은 출력 순서를 1번 칸부터 시작해 마지막에 0번 칸을 찍는다는 뜻이다.

따라가기 — 입력이 1 2 3 4 5 라 하면 values 는 [1, 2, 3, 4, 5].

  1. i = 0 → (0 + 1) % 5 = 1 → values[1] = 2
  2. i = 1 → 2 → 3, i = 2 → 3 → 4, i = 3 → 4 → 5
  3. i = 4 → (4 + 1) % 5 = 0 → values[0] = 1
  4. 화면: 23451 — 첫 값 1 이 맨 뒤로 갔다.

헷갈리는 자리i + 1 만 적으면 i = 4 에서 values[5] 를 읽어 배열 밖(쓰레기 값)이다. (i % 5) + 1 은 5 가 나올 수 있어 역시 밖으로 나간다. 괄호를 빼고 i + 1 % 5 로 적으면 % 가 먼저 계산돼 i + 1 과 같아진다 — 괄호가 답의 일부다.

빈칸에 답을 넣어 gcc(도커 alpine)로 컴파일 · 실행해 확인했다. 복원 출처 grandlife.co.kr(2026-09-14) — 공식 원문이 아니라 문장 · 변수명이 실제와 다를 수 있다.

2023-2회 · 10번C

다음 C 프로그램의 실행 결과를 쓰시오.

#include <stdio.h> int main(void) { int score[3] = { 76, 86, 78 }; int total = 0; for (int i = 0; i < 3; i++) { total += score[i]; } switch (total / 30) { case 10: case 9: printf("A"); case 8: printf("B"); case 7: case 6: printf("C"); default: printf("D"); } return 0; }
정답BCD

— BCD. 합 240 을 30 으로 나눈 몫 8 에서 시작해, break 가 없어 그 아래 case 를 전부 지나간다.

원리 — switch 는 값이 맞는 case 로 뛰어든 뒤 break 를 만날 때까지 아래로 계속 흘러내린다. 이 코드에는 break 가 하나도 없으므로 case 8 에 들어가면 그 아래의 case 7 · 6 · default 까지 전부 실행된다. 이름표(case)는 "여기서부터 시작"을 정할 뿐 "여기까지"를 정하지 않는다. 정수 나눗셈 total / 30 은 소수점을 버리므로 240 / 30 = 8 이다.

따라가기

  1. total = 76 + 86 + 78 = 240, 240 / 30 = 8
  2. case 8 진입 → B
  3. break 없음 → case 7, case 6 의 printf("C") → C
  4. default → D. 화면 BCD

헷갈리는 자리 — B 만 적는 것(break 가 있을 때의 답). 그리고 A 부터 적는 것 — 8 은 case 10 · 9 를 거치지 않고 case 8 로 바로 들어간다. 위쪽은 안 지나가고 아래쪽만 흘러내린다는 방향을 기억한다.

복원 코드를 gcc(도커 alpine)로 실행해 같은 출력을 확인했다. 복원 출처 grandlife.co.kr(2026-09-14) — 공식 원문이 아니라 문장 · 변수명이 실제와 다를 수 있다.

2023-2회 · 11번C

다음 C 프로그램의 실행 결과를 쓰시오.

#include <stdio.h> int stack[10]; int top = -1; void push(int value) { stack[++top] = value; } int pop(void) { return stack[top--]; } int main(void) { push(5); push(2); printf("%d", pop()); push(4); push(1); printf("%d", pop()); push(3); printf("%d", pop()); printf("%d", pop()); push(6); printf("%d", pop()); printf("%d", pop()); return 0; }
정답213465

— 213465. 넣은 순서의 거꾸로 꺼내는 스택을 push · pop 순서대로 그리면 한 자리씩 나온다.

원리 — 스택은 접시 더미다. 접시를 올릴 때(push) 맨 위에 놓고, 꺼낼 때(pop)도 맨 위 것을 집는다. 마지막에 넣은 것이 먼저 나온다(LIFO). 코드의 top 은 맨 위 접시가 놓인 칸 번호이고 처음엔 −1(접시 없음)이다. stack[++top] = value 는 top 을 하나 올린 뒤 그 칸에 넣는 것, stack[top--] 는 맨 위 칸을 읽은 뒤 top 을 하나 내리는 것이다. 읽은 값을 지우지는 않지만 top 이 내려갔으니 다음 push 가 그 칸을 덮는다.

따라가기 — 더미를 아래부터 적는다.

  1. push 5, push 2 → [5, 2]. pop → 2, 더미 [5]
  2. push 4, push 1 → [5, 4, 1]. pop → 1, 더미 [5, 4]
  3. push 3 → [5, 4, 3]. pop → 3, pop → 4, 더미 [5]
  4. push 6 → [5, 6]. pop → 6, pop → 5, 더미 []
  5. 찍힌 순서: 2 1 3 4 6 5 → 줄바꿈 없이 213465

헷갈리는 자리 — 꺼낸 값을 지웠다고 생각해 다음 push 의 자리를 잘못 잡는 것과, 큐(먼저 넣은 것이 먼저)로 착각해 5 부터 적는 것. printf 에 줄바꿈이 없으니 여섯 자리를 붙여 적는다.

복원 코드를 gcc(도커 alpine)로 실행해 같은 출력을 확인했다. 복원 출처 grandlife.co.kr(2026-09-14) — 공식 원문이 아니라 문장 · 변수명이 실제와 다를 수 있다.

2023-2회 · 12번C

다음 C 프로그램에 alpha, beta, gamma를 차례대로 입력했을 때 출력 결과를 줄마다 쓰시오.

#include <stdio.h> char buffer[30]; char *readValue(void) { scanf("%29s", buffer); return buffer; } int main(void) { char *first = readValue(); char *second = readValue(); char *third = readValue(); printf("%s\n", first); printf("%s\n", second); printf("%s", third); return 0; }
정답gamma
gamma
gamma

— gamma / gamma / gamma. 세 포인터가 전부 같은 배열 buffer 를 가리키고, 그 배열엔 마지막 입력만 남아 있다.

원리readValue 는 값을 새로 만들어 주는 함수가 아니다. 전역 배열 buffer 한 채에 입력을 써넣고, 그 집의 주소를 돌려줄 뿐이다. 집은 하나인데 주소를 적은 쪽지(first · second · third)가 세 장인 셈이다. 두 번째 입력이 들어오면 같은 집의 내용이 지워지고 beta 로, 세 번째에 gamma 로 바뀐다. 나중에 세 쪽지를 따라가 보면 전부 같은 집이라 같은 글자가 보인다. 값을 따로 보관하려면 strcpy 로 다른 배열에 복사해야 한다.

따라가기

  1. first = readValue() → buffer 에 "alpha", first = buffer 의 주소
  2. second = readValue() → buffer 가 "beta" 로 덮임, second = 같은 주소
  3. third = readValue() → buffer 가 "gamma" 로 덮임, third = 같은 주소
  4. 세 printf 는 모두 buffer 를 찍는다 → gamma 세 번. 앞 둘엔 줄바꿈이 있고 마지막엔 없다.

헷갈리는 자리 — alpha / beta / gamma 라고 적는 것. 포인터는 값을 담는 그릇이 아니라 주소를 적은 쪽지라는 것을 잊으면 그렇게 된다. 함수가 지역 배열을 돌려주지 않고 전역 배열을 쓰는 것이 이 코드의 함정 장치다.

복원 코드를 gcc(도커 alpine)로 실행해 같은 출력을 확인했다. 복원 출처 grandlife.co.kr(2026-09-14) — 공식 원문이 아니라 문장 · 변수명이 실제와 다를 수 있다.

2023-2회 · 13번C

금액 4,620원을 1,000원, 500원, 100원, 10원 단위로 나눌 때 각 개수를 구하는 ①부터 ④의 식을 쓰시오.

public class Main { public static void main(String[] args) { int money = 4620; int a = ( ① ); int b = ( ② ); int c = ( ③ ); int d = ( ④ ); System.out.println(a); System.out.println(b); System.out.println(c); System.out.println(d); } }
정답① money / 1000, ② (money % 1000) / 500, ③ (money % 500) / 100, ④ (money % 100) / 10

— ① money / 1000(money % 1000) / 500(money % 500) / 100(money % 100) / 10. 큰 단위부터 몫을 세고, 나머지를 다음 단위로 넘긴다.

원리 — 4,620원을 지폐와 동전으로 바꾸는 절차 그대로다. 1,000원짜리는 4,620 을 1,000 으로 나눈 몫(4장). 남은 돈은 4,620 을 1,000 으로 나눈 나머지 620 이고, 그것을 500 으로 나눈 몫이 500원짜리(1개). 다시 나머지 120 을 100 으로 나눈 몫이 100원(1개), 나머지 20 을 10 으로 나눈 몫이 10원(2개). 정수 나눗셈 / 은 "몇 개", 나머지 % 는 "남은 돈"이다. 앞 단위의 나머지가 다음 단위의 입력이 되는 사슬이라 식마다 % 앞 단위 가 붙는다.

따라가기

  1. a = 4620 / 1000 = 4 (남은 돈 4620 % 1000 = 620)
  2. b = 620 / 500 = 1 (남은 돈 620 % 500 = 120)
  3. c = 120 / 100 = 1 (남은 돈 120 % 100 = 20)
  4. d = 20 / 10 = 2 → 화면에 4, 1, 1, 2 가 한 줄씩

헷갈리는 자리 — ② 를 money / 500 으로 적으면 9 가 된다(1,000원짜리로 이미 낸 돈을 또 센다). 나머지를 먼저 취해야 한다. money % 500 / 100 처럼 괄호를 빼도 % 와 / 는 같은 순위라 왼쪽부터 계산돼 결과는 같지만, 답안에는 괄호를 넣는 편이 안전하다.

빈칸에 답을 넣어 컴파일 · 실행해 확인했다. 복원 출처 grandlife.co.kr(2026-09-14) — 공식 원문이 아니라 문장 · 변수명이 실제와 다를 수 있다.

2023-2회 · 14번C

선택 정렬로 배열을 오름차순 정렬하려고 한다. ①에 들어갈 비교 연산자를 쓰시오.

#include <stdio.h> int main(void) { int values[] = { 64, 25, 12, 22, 11 }; int size = sizeof(values) / sizeof(values[0]); for (int i = 0; i < size - 1; i++) { for (int j = i + 1; j < size; j++) { if (values[i] ( ① ) values[j]) { int temp = values[i]; values[i] = values[j]; values[j] = temp; } } } return 0; }
정답>

>. 오름차순은 앞 칸이 뒤 칸보다 클 때 자리를 바꿔야 한다.

원리 — 선택 정렬의 이 꼴은 i 번째 칸을 고정하고 그 뒤의 모든 칸 j 와 비교해, 조건이 맞으면 두 칸을 맞바꾼다. 안쪽 반복이 끝나면 i 칸에는 뒤쪽 전체에서 가장 작은 값이 남는다. 오름차순(작은 것부터)이 되려면 "앞이 뒤보다 크다"가 교환 조건이어야 하므로 부등호는 > 다. 내림차순이면 반대로 <. 부등호를 "정렬 결과와 반대인 상태를 잡아내는 조건"으로 읽으면 헷갈리지 않는다.

따라가기 — 64 25 12 22 11 에서 i = 0 만 본다.

  1. j = 1: 64 > 25 → 교환 → 25 64 12 22 11
  2. j = 2: 25 > 12 → 교환 → 12 64 25 22 11
  3. j = 3: 12 > 22 아니다, j = 4: 12 > 11 → 교환 → 11 64 25 22 12
  4. i = 0 자리에 최소값 11 이 앉았다. 같은 식으로 i 를 늘리면 11 12 22 25 64.

헷갈리는 자리>= 도 결과는 같지만 답은 문제가 준 꼴대로 > 하나를 적는다. < 를 넣으면 64 25 22 12 11 로 내림차순이 된다. 이 코드는 출력문이 없어 화면엔 아무것도 안 찍힌다는 것도 눈여겨본다.

빈칸에 답을 넣어 gcc(도커 alpine)로 컴파일 · 실행해 확인했다. 복원 출처 grandlife.co.kr(2026-09-14) — 공식 원문이 아니라 문장 · 변수명이 실제와 다를 수 있다.

2023-2회 · 15번보안

다음 암호 알고리즘을 대칭키와 비대칭키로 분류하시오: DES, AES, RSA, ECC, ARIA, SEED

정답대칭키: DES, AES, ARIA, SEED / 비대칭키: RSA, ECC

— 대칭키: DES · AES · ARIA · SEED, 비대칭키: RSA · ECC. 암호화와 복호화에 같은 키를 쓰면 대칭, 다른 키(공개키 · 개인키)를 쓰면 비대칭이다.

원리 — 대칭키 암호는 잠글 때와 열 때 같은 열쇠를 쓴다 — 빠르지만 열쇠를 상대에게 안전하게 건네는 문제가 있다. DES(옛 미국 표준, 56비트) · AES(현 표준, 128/192/256비트) · SEED(한국, KISA) · ARIA(한국, 국정원 · 학계) 가 여기다. 비대칭키 암호는 공개키로 잠그고 개인키로 열어 열쇠 전달 문제를 푼다 — 느려서 키 교환 · 서명에 쓴다. RSA(소인수분해) · ECC(타원 곡선) · DH(키 교환) 가 여기다. 이름을 두 상자에 나눠 외운다.

따라가기

  1. DES · AES → 미국 표준 대칭, ARIA · SEED → 한국 대칭
  2. RSA · ECC → 비대칭

헷갈리는 자리 — SEED · ARIA 를 낯설어 비대칭에 넣는 것. 한국산 블록 암호는 전부 대칭이다(LEA · HIGHT 도). 해시(SHA · MD5)는 키가 없어 어느 쪽도 아니라는 것도 같은 묶음에서 나온다.

표준 · 교재 정의(암호 · 인증 · 접근 통제 용어)와 대조했다. 복원 출처 grandlife.co.kr(2026-09-14) — 공식 원문이 아니라 문장이 실제와 다를 수 있다.

2023-2회 · 16번보안

임의 길이 데이터를 고정 길이 값으로 변환하며, 복호화(역변환)가 불가능한 단방향 암호화에 사용되는 함수는?

정답해시 (함수)

— 해시(함수). 어떤 길이의 입력이든 고정 길이 값으로 바꾸고, 그 값에서 원래 입력을 되찾을 수 없는 한 방향 함수다.

원리 — 해시는 문서의 지문이다. 긴 파일도 짧은 메시지도 같은 길이(SHA-256 이면 256비트)의 값이 되고, 입력이 한 글자만 달라도 값이 완전히 달라지며, 값에서 입력으로 되돌아갈 수 없다(단방향). 그래서 비밀번호를 원문 대신 해시로 저장하고, 파일이 바뀌지 않았는지(무결성) 해시를 견주어 확인한다. 암호화와 달리 키가 없고 복호화라는 것이 없다. MD5 · SHA-1 · SHA-256 이 대표다.

따라가기

  1. 임의 길이 → 고정 길이 · 역변환 불가 · 단방향 → 해시 함수

헷갈리는 자리 — "단방향 암호화"라는 말 때문에 대칭 · 비대칭 암호를 적는 것. 되돌릴 수 없으면 암호화가 아니라 해시다. 2026년 2회 15번에 같은 정의가 빈칸으로 다시 나왔다.

표준 · 교재 정의(암호 · 인증 · 접근 통제 용어)와 대조했다. 복원 출처 grandlife.co.kr(2026-09-14) — 공식 원문이 아니라 문장이 실제와 다를 수 있다.

2023-2회 · 17번보안

소프트웨어에 위·변조 검증 코드를 삽입하여, 불법 수정이 감지되면 실행되지 않도록 하는 역공학 방지 기술은?

정답템퍼 프루핑 (Tamper Proofing)

— 템퍼 프루핑(Tamper Proofing). 프로그램이 자기가 고쳐졌는지 검사해 고쳐졌으면 돌지 않게 하는 위 · 변조 방지 기술이다.

원리 — 역공학(리버스 엔지니어링)으로 프로그램을 뜯어 인증 검사를 지우거나 값을 바꾸는 것을 막는 기술들이 있다. 난독화는 코드를 읽기 어렵게 만들고, 템퍼 프루핑은 코드 안에 자기 검증 루틴(해시 · 체크섬)을 심어 실행 때 원본과 다르면 멈추거나 오작동하게 한다. 저작권 보호 · 게임 치트 방지에 쓴다. "위 · 변조 검증 코드 삽입 · 수정되면 실행 안 됨"이 표지다.

따라가기

  1. 변조 검증 코드 삽입 + 불법 수정 시 실행 차단 → 템퍼 프루핑

헷갈리는 자리 — 난독화(Obfuscation)를 적는 것. 난독화는 "읽기 어렵게", 템퍼 프루핑은 "고치면 안 돌게"다. 워터마킹은 출처 표시라 또 다르다. 셋이 역공학 방지 묶음으로 함께 나온다.

표준 · 교재 정의(공격 기법 · 보안 솔루션 · 시큐어 코딩 가이드)와 대조했다. 복원 출처 grandlife.co.kr(2026-09-14) — 공식 원문이 아니라 문장이 실제와 다를 수 있다.

2023-2회 · 18번디자인패턴

① 클래스의 인스턴스를 하나만 생성해 어디서든 참조하게 하는 패턴 ② 원소 클래스를 수정하지 않고 새로운 연산을 추가할 수 있게 하는 행위 패턴

정답① 싱글톤(Singleton) ② 비지터(Visitor)

— ① 싱글톤(Singleton) ② 비지터(Visitor). "인스턴스 하나만"과 "클래스를 안 고치고 연산 추가"가 각각의 표지다.

원리 — 싱글톤은 생성 패턴이다. 생성자를 private 으로 막고 static 메서드(getInstance)로만 객체를 내주어, 프로그램 전체에서 인스턴스가 하나만 있게 한다 — 설정 · 로그 · 연결 풀처럼 여러 개면 곤란한 것에 쓴다. 비지터는 행위 패턴이다. 자료 구조(원소 클래스들)는 그대로 두고, 그 위에서 할 "연산"을 별도의 방문자 객체로 뺀다. 원소는 accept(visitor) 만 갖고, 새 연산이 필요하면 원소를 고치지 않고 새 방문자 클래스를 하나 더 만든다 — 자료 구조는 안정적이고 연산은 자주 바뀔 때 맞는 패턴이다.

따라가기

  1. "인스턴스를 하나만 · 어디서든 참조" → 싱글톤
  2. "원소 클래스를 수정하지 않고 새 연산 추가 · 행위" → 비지터

헷갈리는 자리 — ②를 데코레이터로 적는 것. 데코레이터는 "객체에 기능을 덧입히는" 구조 패턴이고, 비지터는 "구조를 돌며 연산을 수행하는" 행위 패턴이다. "새로운 연산(operation)"이라는 말과 "행위 패턴"이라는 힌트가 비지터를 가리킨다.

GoF 책 Design Patterns 의 패턴 정의(생성 5 · 구조 7 · 행위 11)와 대조했다. 복원 출처 grandlife.co.kr(2026-09-14) — 공식 원문이 아니라 문장이 실제와 다를 수 있다.

2023-2회 · 19번네트워크

HDLC 프로토콜의 프레임 3종류(①②③)와 동작 모드 중 2가지(④⑤)를 쓰시오. ④: 양쪽 모두 명령·응답 가능한 균형 모드 ⑤: 종국이 주국 허가 없이 응답 가능한 모드

정답① 정보 프레임 ② 감독 프레임 ③ 비번호 프레임 ④ 비동기 균형 모드(ABM) ⑤ 비동기 응답 모드(ARM)

— ① 정보 프레임 ② 감독 프레임 ③ 비번호 프레임 ④ 비동기 균형 모드(ABM) ⑤ 비동기 응답 모드(ARM). HDLC 의 세 프레임과 세 모드 중 둘이다.

원리 — HDLC 는 데이터링크 계층의 프로토콜로 프레임을 세 종류로 나눈다. 정보(I) 프레임은 실제 데이터를 나른다. 감독(S) 프레임은 데이터 없이 "잘 받았다 · 다시 보내라 · 잠깐 멈춰라" 같은 흐름 · 오류 제어만 한다. 비번호(U) 프레임은 순서 번호가 없고 연결 맺기 · 끊기 · 모드 설정에 쓴다. 동작 모드는 누가 명령할 수 있느냐로 셋이다 — 정규 응답 모드(NRM)는 주국만 명령하고 종국은 허가 받아야 응답, 비동기 응답 모드(ARM)는 종국이 허가 없이 응답 가능, 비동기 균형 모드(ABM)는 양쪽이 대등하게 명령 · 응답 가능.

따라가기

  1. 프레임 셋 → 정보 · 감독 · 비번호
  2. 양쪽 모두 명령 · 응답 → 균형 → ABM
  3. 종국이 허가 없이 응답 → ARM

헷갈리는 자리 — ARM 과 NRM 을 바꾸는 것. "허가 없이"면 ARM, "허가 받아야"면 NRM 이다. 프레임 이름을 영문 약자(I · S · U)로만 적으면 감점될 수 있으니 우리말 이름을 적고 괄호에 약자를 더한다. 2026년 1회 6번에 그대로 다시 나왔다.

표준 · 교재 정의(OSI · TCP/IP · IEEE · RFC 용어)와 대조했다. 복원 출처 grandlife.co.kr(2026-09-14) — 공식 원문이 아니라 문장이 실제와 다를 수 있다.

2023-2회 · 20번네트워크

오류 제어 용어 매칭: ① 2비트 오류 검출+1비트 수정 가능한 코드 ② 수신 측이 스스로 오류를 수정하는 방식 ③ 재전송을 요구하는 방식 ④ 1비트 추가로 홀짝 검사 ⑤ 다항식 나눗셈 기반 검출

정답① 해밍 코드 ② FEC(전진 오류 수정) ③ BEC(후진 오류 수정) ④ 패리티 검사 ⑤ CRC

— ① 해밍 코드 ② FEC(전진 오류 수정) ③ BEC(후진 오류 수정) ④ 패리티 검사 ⑤ CRC. 오류를 "찾기만 하나 · 고치나 · 다시 받나"로 가르는 다섯 낱말이다.

원리 — 통신 중 비트가 뒤집히는 오류를 다루는 방법은 두 갈래다. 수신 측이 스스로 고치는 전진 오류 수정(FEC, Forward)과 재전송을 요구하는 후진 오류 수정(BEC, Backward — ARQ 가 여기 속함). FEC 의 대표가 해밍 코드로, 여분 비트를 넣어 1비트 오류는 어디인지 찾아 고치고 2비트 오류는 있다는 것까지 안다. 검출만 하는 방법으로 패리티(비트 하나를 더해 1 의 개수가 홀수 · 짝수인지 검사)와 CRC(정해진 다항식으로 나눈 나머지를 붙여 검사)가 있다.

따라가기

  1. 2비트 검출 + 1비트 수정 → 해밍 코드
  2. 수신 측 자가 수정 → FEC
  3. 재전송 요구 → BEC
  4. 1비트 추가 홀짝 → 패리티, 다항식 나눗셈 → CRC

헷갈리는 자리 — FEC 와 BEC 를 바꾸는 것. "앞으로(Forward) 혼자 간다 = 스스로 고친다", "뒤로(Backward) 돌아간다 = 다시 보내 달라"로 방향을 잡는다. 패리티는 짝수 개 오류를 못 잡는다는 것도 자주 묻는다. 2025년 3회 6번이 영문 약자로 같은 문제다.

표준 · 교재 정의(OSI · TCP/IP · IEEE · RFC 용어)와 대조했다. 복원 출처 grandlife.co.kr(2026-09-14) — 공식 원문이 아니라 문장이 실제와 다를 수 있다.

03채점 뒤 할 일

왜 이걸 하나 — 점수보다 어느 장으로 돌아가느냐가 결과다. 문항마다 가는 장이 정해져 있다.

코드 9문항 중 C 7 · Java 1 · Python 1 이다. 빈칸이 셋(9번 순환 첨자, 13번 화폐 단위 식, 14번 정렬 비교 연산자)이고 실행 결과가 여섯이다. 4번(4의 배수 개수)은 2023 ÷ 4 를 종이에 적으면 끝나고, 11번 스택은 push · pop 을 표로 적어야 213465 가 나온다.

12번은 세 번 읽은 값이 같은 전역 버퍼를 가리켜 전부 gamma 가 찍힌다. 포인터가 가리키는 자리가 어디인지 그림을 그리지 않으면 alpha · beta · gamma 로 적고 5점을 잃는다. 10번은 break 가 없는 switch 라 8 에서 시작해 BCD 까지 흘러내린다.

용어는 보안 3(대칭 · 비대칭 분류, 해시, 템퍼 프루핑) · DB 3(INSERT 작성 · CASCADE · 설계 4단계) · 테스트 2(조건 커버리지 · 스텁과 드라이버) · 패턴 2칸 · 네트워크 5칸 둘이다. 19 · 20번은 칸마다 부분 점수가 있어(배분은 공단 비공개) 아는 칸만 적어도 점수가 된다.

문항마다 가는 장

틀린 문항의 「가는 장」을 열면 그 문항이 04절에 그대로 있고, 앞뒤로 같은 꼴의 문항이 붙어 있다. 몰라서 틀렸으면 그 장 03절부터, 알았는데 틀렸으면 05절만 읽는다. 판정 기준은 E01 의 03절 표와 같다.

문항분야가는 장무엇을 묻나
1SQLE09INSERT 문 작성
2SQLE09DROP VIEW … CASCADE
3DBE10DB 설계 4단계 순서
4CE041~2023 중 4의 배수 개수
5PythonE07문자열 슬라이스 세 조각 잇기
6테스트E18조건 커버리지 정의
7테스트E18스텁과 드라이버
8JavaE06String == 와 equals
9CE02순환 첨자 (i + 1) % 5
10CE04break 없는 switch 통과
11CE02배열 스택 push · pop 순서
12CE02공유 버퍼를 가리키는 포인터 셋
13CE04화폐 단위 나누기 — / 와 % 식
14CE02선택 정렬 오름차순 비교 연산자
15보안E13대칭키 · 비대칭키 알고리즘 분류
16보안E13단방향 해시 함수 정의
17보안E14템퍼 프루핑
18디자인패턴E17싱글톤과 비지터 패턴
19네트워크E11HDLC 프레임 3종과 모드 2종
20네트워크E11오류 제어 용어 5칸 매칭

이 회차에서 눈여겨볼 문항

문항왜 갈리나
11번push 5 2 → pop 2 · push 4 1 → pop 1 · push 3 → pop 3 · pop 4 · push 6 → pop 6 · pop 5. 213465
12번readValue 가 돌려주는 것은 늘 buffer 의 주소다. 세 포인터가 같은 곳을 가리켜 마지막 입력 gamma 가 세 번 찍힌다
13번4620 → 1000 으로 나눈 몫, 나머지를 500 으로, 그 나머지를 100 으로. 답은 나눗셈과 나머지의 짝이다
19 · 20번HDLC 프레임 3종 + 모드 2종, 오류 제어 5칸. 10칸 중 아는 것부터 적는다 — 빈칸은 0점이지만 틀린 칸도 0점이라 적는 쪽이 낫다

채점 결과는 오답노트에 회차별 점수와 틀린 문항 목록으로 모인다. 세트를 하나 끝낼 때마다 거기서 같은 장에서 반복해서 틀리는지를 본다. 두 세트에서 같은 장이 나오면 그 장의 06절 훈련을 그날 5문항 푼다.

04다음

왜 이걸 하나 — 세트의 결과는 다음에 열 장의 이름이어야 한다.