26-1
다음 Python 코드를 수행하면 무엇이 찍히는지 적으시오.
def stack(data):
rows = [[v] for v in data]
view = rows[:]
for i in range(2, len(view)):
view[i] += view[i - 2]
return sum(len(r) for r in rows), rows[-1]
total, last = stack([2, 4, 6, 8, 10])
print(total, last)9 [10, 6, 2]
[해설]
view = rows[:]는 얕은 복사라서 바깥 리스트만 새로 만들고, 안쪽 리스트들은 rows와 같은 객체를 공유한다. 리스트의 +=는 새 리스트를 만들지 않고 제자리에서 확장한다.
- i=2: view[2] += view[0] → [6, 2]
- i=3: view[3] += view[1] → [8, 4]
- i=4: view[4] += view[2] → [10, 6, 2] (이미 늘어난 [6, 2]가 붙음)
rows에도 같은 변화가 보이므로 길이 합은 1+1+2+2+3 = 9, 마지막 원소는 [10, 6, 2]이다. 출력은 튜플을 풀어 공백으로 이은 9 [10, 6, 2]이다.
26-1
빈칸 ( )에 공통으로 들어갈 용어를 적으시오.
- 레이스 컨디션(Race Condition) 공격은 여러 프로세스가 같은 자원에 거의 동시에 접근할 때 생기는 실행 순서의 틈을 노린다.
- 권한이 높은 프로그램이 임시 파일을 만들려는 순간, 공격자가 그 이름의 파일을 중요 시스템 파일을 가리키는 ( )(으)로 바꿔치기해 엉뚱한 파일이 덮어써지게 만든다.
- ( )은/는 실제 데이터 대신 원본 파일의 경로만 담고 있는 특수 파일로, 프로그램이 이를 열면 운영체제가 자동으로 원본 파일로 연결해 준다.
심볼릭 링크(Symbolic Link)
[해설]
원본 파일의 경로를 담아 원본으로 이어 주는 특수 파일은 심볼릭 링크(Symbolic Link)이다. 바로가기와 비슷해 소프트 링크라고도 한다.
검사 시점과 사용 시점 사이의 틈(TOCTOU)에 임시 파일이 심볼릭 링크로 바뀌면, 높은 권한으로 쓰기가 일어나 시스템 파일이 변조된다.
대응책으로는 임시 파일을 예측하기 어려운 이름으로 원자적으로 생성하고, 링크 여부를 확인한 뒤 여는 방법이 있다.
26-1
도서 대여 기록을 담는 RENTAL 테이블을 만드는 SQL 문이다. RENTAL 테이블의 BORROWER 칼럼이 MEMBER 테이블의 MEM_NO 칼럼을 참조하도록 외래키를 설정하려 한다. 빈칸 ①~⑤에 들어갈 SQL 예약어 또는 칼럼명을 적으시오. (단, 외래키 제약조건의 이름은 FK_RENT_MEM으로 하고, MEMBER 테이블은 이미 만들어져 있다.)
CREATE TABLE RENTAL (
RENT_ID CHAR(10) NOT NULL,
RENT_DATE DATE NOT NULL,
BORROWER CHAR(6) NOT NULL,
PRIMARY KEY (RENT_ID),
( ① ) FK_RENT_MEM
( ② ) KEY ( ③ ) ( ④ ) MEMBER ( ⑤ )
);① CONSTRAINT
② FOREIGN
③ BORROWER
④ REFERENCES
⑤ MEM_NO
[해설]
외래키는 CONSTRAINT 이름 FOREIGN KEY (자기 칼럼) REFERENCES 참조테이블 (참조 칼럼) 형식으로 선언한다.
- CONSTRAINT — 제약조건에 FK_RENT_MEM이라는 이름을 붙이는 예약어.
- FOREIGN — KEY와 짝을 이뤄 외래키 선언을 시작하는 예약어.
- BORROWER — RENTAL 쪽에서 외래키가 되는 칼럼.
- REFERENCES — 참조할 부모 테이블을 지정하는 예약어.
- MEM_NO — MEMBER 테이블에서 참조되는 칼럼.
참조되는 MEM_NO는 MEMBER의 기본키 또는 UNIQUE 칼럼이어야 참조 무결성을 검사할 수 있다.
26-1
다음 설명에 해당하는 공격 기법의 이름을 적으시오.
- 공격자는 표적 집단이 평소 자주 드나드는 정상 웹사이트를 먼저 찾아내 악성코드를 심어 둔다.
- 표적이 그 사이트에 접속하면 브라우저 등의 취약점을 통해 방문자 PC에 악성 프로그램이 내려받아진다.
- 사자가 물웅덩이 근처에서 먹잇감을 기다리는 모습에서 이름을 따왔다.
워터링 홀(Watering Hole)
[해설]
표적이 방문할 합법 사이트를 미리 감염시켜 두고 기다리는 공격은 워터링 홀(Watering Hole)이다.
불특정 다수가 아닌 특정 조직을 노리므로 APT(지능형 지속 위협)의 초기 침투 수단으로 자주 쓰인다.
- 드라이브 바이 다운로드: 방문만으로 악성코드가 설치되는 기술 자체를 가리킨다.
- 스피어 피싱: 표적에게 맞춤형 메일을 직접 보내 유인한다.
26-1
아래 C 프로그램의 출력 결과를 적으시오.
#include <stdio.h>
struct Hop {
int *(*jump)(int *);
};
int *twoAhead(int *q) {
return q + 2;
}
int main(void) {
struct Hop h;
int nums[] = {7, 13, 26, 45, 60, 91};
h.jump = twoAhead;
printf("%x", *h.jump(nums + 1) + *h.jump(nums));
return 0;
}47
[해설]
구조체 멤버 jump는 int*를 받아 int*를 돌려주는 함수 포인터이고, twoAhead를 가리킨다. twoAhead는 받은 주소에서 원소 두 칸 뒤의 주소를 돌려준다.
- h.jump(nums + 1) → nums + 3 → 역참조하면 nums[3] = 45
- h.jump(nums) → nums + 2 → 역참조하면 nums[2] = 26
- 합: 45 + 26 = 71
%x는 16진수로 출력하므로 71 = 4×16 + 7 → 47이다. 10진수 71로 적지 않도록 주의한다.
26-1
데이터베이스를 설계할 때 거치는 단계를 [보기]에서 골라 진행 순서대로 기호로 나열하시오.
[보기] ㄱ. 개념적 설계 ㄴ. 구현 ㄷ. 논리적 설계 ㄹ. 물리적 설계 ㅁ. 요구사항 분석
ㅁ → ㄱ → ㄷ → ㄹ → ㄴ
[해설]
데이터베이스 설계는 요구사항 분석 → 개념적 설계 → 논리적 설계 → 물리적 설계 → 구현 순서로 진행한다. 추상적인 단계에서 구체적인 단계로 내려가는 흐름이다.
- 요구사항 분석 — 사용자가 어떤 데이터를 어떻게 쓰려는지 파악해 요구사항 명세서를 만든다.
- 개념적 설계 — DBMS와 상관없이 E-R 다이어그램으로 개념 스키마를 만든다.
- 논리적 설계 — 목표 DBMS의 데이터 모델(관계형 등)에 맞춰 테이블로 바꾸고 정규화한다.
- 물리적 설계 — 저장 구조, 인덱스, 접근 경로를 정한다.
- 구현 — DDL로 실제 데이터베이스를 만든다.
혼동 주의: 정규화는 논리적 설계 단계에서 하고, 인덱스와 레코드 배치는 물리적 설계 단계에서 정한다.
26-1
아래 Java 프로그램이 출력하는 내용을 적으시오.
class Ops {
int twice(int a) {
return a * 2;
}
int diff(char a, char b) {
return a - b;
}
}
public class Main {
public static void main(String[] args) {
Ops op = new Ops();
int x1 = op.twice(7);
int x2 = op.diff('k', 'f');
String s = "0";
System.out.println(x1 + x2 + s + x2 + x1);
}
}190514
[해설]
+ 연산은 왼쪽부터 차례로 계산하며, 문자열을 만나기 전까지는 숫자 덧셈, 만난 뒤부터는 문자열 연결이 된다.
- x1 = twice(7) = 14, x2 = diff('k', 'f') = 107 − 102 = 5 (char 뺄셈은 문자 코드 차이)
- x1 + x2 = 19 (정수 덧셈)
- 19 + "0" → "190", 이후 + 5 → "1905", + 14 → "190514"
출력은 190514이다. 문자열 뒤의 x2, x1은 더해지지 않고 그대로 이어 붙는다.
26-1
모듈 응집도에 관한 설명이다. 빈칸 ①~③에 들어갈 응집도의 유형을 적으시오.
- ( ① ) 응집도: 모듈이 서로 관련된 여러 기능을 담고 있고, 그 구성 요소들이 정해진 순서에 따라 차례로 기능을 수행한다.
- ( ② ) 응집도: 같은 입력 자료를 쓰거나 같은 출력 자료를 만들어 내지만, 서로 다른 일을 하는 활동들이 한 모듈에 모여 있다.
- ( ③ ) 응집도: 모듈 안의 모든 요소가 오직 하나의 목적을 이루기 위해 함께 동작한다.
① 절차적 응집도(Procedural Cohesion)
② 교환적(통신적) 응집도(Communicational Cohesion)
③ 기능적 응집도(Functional Cohesion)
[해설]
응집도는 모듈 안의 요소들이 하나의 목적에 얼마나 강하게 묶여 있는지를 나타낸다. 강한 것부터 기능적 → 순차적 → 교환적 → 절차적 → 시간적 → 논리적 → 우연적 순이다.
- 절차적 응집도 — 서로 관련된 기능들이 정해진 순서에 따라 차례로 수행된다.
- 교환적(통신적) 응집도 — 같은 입력이나 출력 자료를 쓰지만 서로 다른 일을 하는 활동들이 한 모듈에 모여 있다.
- 기능적 응집도 — 모든 요소가 하나의 목적을 위해 함께 동작하며, 가장 바람직한 형태다.
혼동 주의: 한 활동의 출력이 다음 활동의 입력이 되면 순차적 응집도다. 순서만 정해져 있는 절차적 응집도와 구별해야 한다.
26-1
다음 Java 코드를 수행했을 때 콘솔에 나타나는 값을 적으시오.
class Printer {
String show(Object v) {
return "P";
}
String run() {
return show(7) + show("x");
}
}
class Laser extends Printer {
String show(Object v) {
return "L";
}
String show(Integer v) {
return "I";
}
String show(String v) {
return "S";
}
}
public class Main {
public static void main(String[] args) {
Printer p = new Laser();
System.out.println(p.run() + ((Laser) p).show("k"));
}
}LLS
[해설]
어떤 메서드를 부를지(오버로딩 선택)는 컴파일 시점에 참조 타입으로 정하고, 실제 실행은 객체 타입의 오버라이딩 메서드로 결정된다.
- run()은 Printer 클래스 안에 있으므로 컴파일러는 Printer의 show(Object)만 본다. show(7)과 show("x") 모두 show(Object)로 확정된다.
- 실행 객체는 Laser이므로 오버라이딩된 Laser.show(Object)가 두 번 실행되어 "LL"이 된다.
- ((Laser) p).show("k")는 참조 타입이 Laser라 가장 구체적인 show(String)이 골라져 "S"가 된다.
최종 출력은 LLS이다. 자식에만 있는 show(Integer)·show(String)은 부모 타입 안에서는 후보조차 되지 않는다.
26-1
비트 지향형 데이터 링크 계층 프로토콜인 HDLC에 관한 설명이다. 빈칸 ①~⑨에 알맞은 용어를 [보기]에서 골라 적으시오.
- HDLC 프레임은 플래그, 주소부, 제어부, 정보부, FCS(프레임 검사 순서), 플래그 순으로 이루어진다.
- 제어부 앞쪽 비트 값으로 프레임의 종류를 가린다. 첫 비트가 0이면 사용자 데이터를 실어 나르는 ( ① ) 프레임이다.
- 앞 두 비트가 10이면 오류 제어와 흐름 제어에 쓰는 ( ② ) 프레임, 11이면 링크 설정·해제 등 동작 모드를 관리하는 ( ③ ) 프레임이다.
- ( ④ ): 링크를 제어할 책임을 지는 국으로, 명령 프레임을 보내 링크 설정·흐름 제어·오류 복구를 이끈다.
- ( ⑤ ): 제어권 없이 ( ④ )의 지시를 따르며, 받은 명령에 대한 응답 프레임만 보낸다.
- ( ⑥ ): ( ④ )와 ( ⑤ )의 기능을 함께 갖춰 명령과 응답을 모두 보낼 수 있으며, 서로 대등하게 링크를 제어한다.
- ( ⑦ ): 불균형 링크에서 쓰는 전송 모드로, ( ⑤ )은/는 ( ④ )의 허가(Poll)를 받았을 때만 송신할 수 있다.
- ( ⑧ ): 점대점 균형 링크에서 쓰는 전송 모드로, ( ⑥ )끼리 상대의 허가 없이 아무 때나 전송을 시작할 수 있다.
- ( ⑨ ): 전이중 점대점 불균형 링크에서 쓰는 전송 모드로, ( ⑤ )이/가 허가 없이 송신할 수 있으나 링크 설정·오류 복구 같은 제어는 ( ④ )만 맡는다.
[보기] 감독, 동기 균형 모드, 동기 응답 모드, 릴레이, 복합국, 비동기 균형 모드, 비동기 응답 모드, 비번호, 양방향 응답 모드, 익명, 정규 응답 모드, 정보, 종국, 주국, 중계국
① 정보
② 감독
③ 비번호
④ 주국(Primary Station)
⑤ 종국(Secondary Station)
⑥ 복합국(Combined Station)
⑦ 정규 응답 모드(NRM)
⑧ 비동기 균형 모드(ABM)
⑨ 비동기 응답 모드(ARM)
[해설]
HDLC는 제어부 앞쪽 비트로 프레임 종류를 구분한다. 링크 제어 방식은 국의 역할과 전송 모드로 정한다.
- 정보(I) 프레임 — 제어부가 0으로 시작하며 사용자 데이터를 실어 나른다.
- 감독(S) 프레임 — 10으로 시작하며 오류 제어와 흐름 제어를 맡는다.
- 비번호(U) 프레임 — 11로 시작하며 링크 설정·해제와 동작 모드 관리에 쓴다.
- 주국 — 명령 프레임을 보내 링크 제어를 책임진다.
- 종국 — 제어권이 없고, 주국의 명령에 응답 프레임만 보낸다.
- 복합국 — 명령과 응답을 모두 보낼 수 있고, 상대와 대등하게 링크를 제어한다.
- 정규 응답 모드(NRM) — 불균형 링크에서 쓰며, 종국은 주국의 Poll을 받아야만 송신한다.
- 비동기 균형 모드(ABM) — 점대점 균형 링크에서 쓰며, 복합국끼리 허가 없이 송신한다.
- 비동기 응답 모드(ARM) — 종국이 허가 없이 송신할 수 있지만 링크 제어는 주국만 맡는다.
외우는 요령: 이름에 균형이 붙은 ABM만 복합국끼리 쓰는 모드다. 응답이 붙은 NRM과 ARM은 주국–종국 사이의 불균형 구조다.
26-1
[수강생] 테이블에 경영학과 40명, 전자공학과 70명, 건축학과 30명의 정보가 한 명당 한 행씩 저장되어 있다. 다음 SQL 문을 각각 실행했을 때 결과로 나오는 튜플(행)의 수를 적으시오. (단, 학과 칼럼에는 학과명이 들어 있다.)
① SELECT 학과 FROM 수강생;
② SELECT DISTINCT 학과 FROM 수강생;
③ SELECT COUNT(DISTINCT 학과) FROM 수강생 WHERE 학과 = '전자공학과';① 140
② 3
③ 1
[해설]
① 조건 없이 칼럼을 조회하면 중복을 그대로 둔 채 모든 행이 나오므로 40 + 70 + 30 = 140이다.
② DISTINCT는 같은 값을 하나로 합치므로 서로 다른 학과 수인 3이다.
③ 집계 함수 COUNT는 값이 몇이든 결과 행을 하나만 만든다. 값은 1이고 튜플 수도 1이다.
26-1
다음 설명에 해당하는 체계를 영문 약어로 적으시오.
- 기업·기관이 가진 핵심 정보 자산을 지키기 위해, 정보보호에 관한 정책·절차·통제 활동을 체계적으로 세우고 꾸준히 운영·개선해 나가는 종합 관리 체계이다.
- 국내에서는 일정 기준 이상의 사업자에게 이 체계에 대한 인증을 의무로 요구한다.
ISMS
[해설]
정보 자산을 지키기 위한 정책·절차·통제를 세우고 꾸준히 운영·개선하는 종합 체계는 ISMS(Information Security Management System, 정보보호 관리체계)다.
국내에서는 정보통신망법에 따라 일정 기준 이상의 사업자가 ISMS 인증을 반드시 받아야 한다. 계획·실행·점검·개선을 되풀이하는 순환 관리가 핵심이다.
혼동 주의: 개인정보 보호 항목까지 더한 인증은 ISMS-P다. 이 문항처럼 정보보호 관리체계만 물으면 답은 ISMS다.
26-1
아래 C 프로그램을 실행했을 때 화면에 찍히는 값을 적으시오.
#include <stdio.h>
double headAvg(int v[], int cnt) {
int k, total = 0;
for (k = 0; k < cnt; k++)
total += v[k];
return (double)total / cnt;
}
double tailAvg(int *v, int cnt) {
int k, total = 0;
for (k = 0; k < cnt; k++)
total += *(v + k);
return (double)total / cnt;
}
int main(void) {
int data[8] = {72, 15, 38, 64, 90, 27, 51, 43};
printf("%.2f", headAvg(data, 5) + tailAvg(data + 5, 3));
return 0;
}96.13
[해설]
배열을 매개변수로 받을 때 int v[]와 int *v는 똑같이 포인터로 처리된다. 그래서 v[k]와 *(v + k)는 같은 원소를 가리킨다.
- headAvg(data, 5): 72+15+38+64+90 = 279 → 279/5 = 55.8
- tailAvg(data + 5, 3): 시작 주소가 data[5]로 옮겨져 27+51+43 = 121 → 121/3 = 40.333…
- 합계 55.8 + 40.333… = 96.1333…
%.2f는 소수 셋째 자리에서 반올림해 둘째 자리까지 찍으므로 96.13이 출력된다. 정수 합을 (double)로 바꾼 뒤 나누므로 몫이 잘리지 않는다.
26-1
비기능 요구사항에 관한 다음 물음에 답하시오.
(1) 제약사항으로 적어 둔 ①~③ 각각의 제약 유형을 [보기 1]에서 하나씩 골라 적으시오.
- ① 한 가지 운영체제에 묶이지 않고 Windows·Linux·macOS 어디에 깔아도 동작해야 한다.
- ② 프로그램이 돌아가는 데 꼭 필요한 최소 메모리 크기를 정해 두어야 한다.
- ③ 요청이 들어오면 미리 약속한 n초를 넘기지 않고 답을 돌려주어야 한다.
[보기 1] 보안(Security), 성능(Performance), 운영(Operational), 자원(Resource), 정책(Policy), 품질(Quality)
(2) 다음은 온라인 도서 대출 서비스의 요구사항 일부이다. ㄱ~ㄹ 중 비기능 요구사항을 모두 골라, 각각 해당하는 품질 속성을 [보기 2]에서 찾아 연결하시오.
- ㄱ. 회원은 자신의 대출·반납 이력을 날짜별로 검색해 볼 수 있어야 한다.
- ㄴ. 회원의 비밀번호와 연락처는 암호화해 보관하고, 권한 없는 접근은 모두 차단해야 한다.
- ㄷ. 서버에 뜻밖의 장애가 생겨도 서비스는 1년 기준 99.9% 이상 이용 가능한 상태를 유지해야 한다.
- ㄹ. 모바일 앱은 소스 코드를 고치지 않고도 Android와 iOS에서 똑같이 동작해야 한다.
[보기 2] 가용성, 보안성, 사용성, 성능, 신뢰성, 유지보수성, 이식성
(1) ① 운영(Operational)
② 자원(Resource)
③ 성능(Performance)
(2) ㄴ 보안성
ㄷ 가용성
ㄹ 이식성
[해설]
(1) 운영 환경(OS 종류) 조건은 운영 제약, 확보해야 할 메모리 용량은 자원 제약, 정해진 시간 안의 응답은 성능 제약이다. 보안·정책·품질은 오답 보기다.
(2) ㄱ은 사용자가 할 수 있는 일을 정한 기능 요구사항이므로 제외한다.
- ㄴ 암호화·무단 접근 차단: 보안성
- ㄷ 장애에도 99.9% 이상 이용 가능: 가용성
- ㄹ 코드 수정 없이 다른 플랫폼에서 동작: 이식성
26-1
아래 Python 프로그램을 실행했을 때의 출력을 적으시오.
seq = list(range(3, 15))
for v in seq[-2::-3]:
print(v, end='#')
print()13#10#7#4#
[해설]
range(3, 15)는 끝값 15를 포함하지 않으므로 seq = [3, 4, …, 14]이다.
- seq[-2::-3]은 뒤에서 두 번째 원소인 13에서 시작해 거꾸로 3칸씩 이동한다.
- 13, 10, 7, 4 다음 위치는 리스트 앞쪽을 벗어나므로 거기서 멈춘다.
- end='#' 때문에 각 값 뒤에 줄바꿈 대신 #이 붙는다.
출력은 13#10#7#4#이고, 마지막 print()는 줄만 바꾼다.
26-1
GoF 디자인 패턴에 관한 설명이다. 빈칸 ①, ②에 들어갈 패턴의 이름을 각각 적으시오.
- ( ① ) 패턴: 추상화(기능) 쪽 클래스 계층과 구현 쪽 클래스 계층을 따로 두고 둘 사이를 연결만 해 두어, 어느 한쪽을 바꾸거나 늘려도 다른 쪽이 영향을 받지 않게 한다.
- ( ② ) 패턴: 어떤 객체의 상태가 달라지면 그 객체를 지켜보도록 등록된 여러 객체에 변화가 자동으로 통보되어 갱신된다. 일대다 의존 관계를 느슨한 결합으로 유지한다.
① 브리지(Bridge)
② 옵저버(Observer)
[해설]
기능 계층과 구현 계층을 분리해 각자 독립적으로 확장하게 하는 구조 패턴은 브리지(Bridge)이다.
주체(Subject)의 상태 변화를 구독자(Observer)들에게 일괄 통지하는 행위 패턴은 옵저버(Observer)이다. 게시·구독(Publish-Subscribe) 구조, 이벤트 리스너가 대표적인 예다.
브리지는 상속 대신 구성(합성)으로 두 계층을 잇는다는 점에서, 이미 있는 인터페이스를 맞춰 주는 어댑터와 구별된다.
26-1
다음 Python 코드를 돌렸을 때 화면에 나타나는 문자열을 적으시오.
s = "Blue Sky Note"
parts = []
for t in s.split():
parts.append(t)
joined = '-'.join(parts)
res = ''.join(ch for ch in joined[::-1] if ch not in 'eou-')
print(res)tNykSlB
[해설]
split()은 공백을 기준으로 문자열을 나누고, '-'.join으로 다시 이으면 joined는 Blue-Sky-Note가 된다.
- joined[::-1]로 뒤집으면 etoN-ykS-eulB가 된다.
- 여기서 소문자 e·o·u와 하이픈을 빼면 t, N, y, k, S, l, B가 남는다.
따라서 출력은 tNykSlB이다. 문자 비교는 대소문자를 구분하므로 대문자 N·S·B는 제거되지 않는다.
26-1
통합 테스트에서 쓰는 임시 모듈에 관한 설명이다. 빈칸 ①, ②에 알맞은 용어를 적으시오.
- ( ① ): 아직 만들어지지 않은 하위 모듈 자리를 대신해, 호출되면 정해진 값만 돌려주는 가짜 모듈이다. 하향식 통합 테스트에 필요하다.
- ( ② ): 아직 없는 상위 모듈을 대신해, 시험할 모듈을 호출하고 입력 데이터를 넘긴 뒤 결과를 받아 확인하는 가짜 모듈이다. 상향식 통합 테스트에 필요하다.
① 스텁(Stub)
② 드라이버(Driver)
[해설]
통합 테스트에서 아직 만들어지지 않은 모듈을 대신하는 임시 모듈이 스텁(Stub)과 드라이버(Driver)다.
스텁은 하향식(위→아래) 통합에서 빠진 하위 모듈을 흉내 내며, 호출되면 정해진 값만 돌려준다. 드라이버는 상향식(아래→위) 통합에서 빠진 상위 모듈 역할을 하며, 시험할 모듈을 호출하고 결과를 받아 확인한다.
외우는 요령: 하향식은 스텁, 상향식은 드라이버다. 드라이버는 운전하듯 아래 모듈을 호출하는 쪽이라고 기억하면 된다.
26-1
[사원] 테이블과 [부서] 테이블이 아래와 같을 때, 주어진 SQL 문의 실행 결과를 적으시오.
[사원]
| 사번 | 이름 | 부서코드 |
|---|---|---|
| 101 | 강다온 | D2 |
| 102 | 민서준 | D1 |
| 103 | 윤하람 | D4 |
| 104 | 조은별 | D2 |
| 105 | 임태오 | D3 |
| 106 | 배수아 | D4 |
[부서]
| 부서코드 | 예산 |
|---|---|
| D1 | 150 |
| D2 | 420 |
| D3 | 260 |
| D4 | 330 |
SELECT COUNT(*)
FROM 사원 s
JOIN 부서 b ON s.부서코드 = b.부서코드
WHERE b.예산 > (SELECT AVG(예산) FROM 부서);4
[해설]
먼저 서브쿼리가 부서 예산의 평균을 구한다. (150 + 420 + 260 + 330) / 4 = 290이다.
- 예산이 290보다 큰 부서: D2(420), D4(330)
- 조인 결과 중 D2 소속: 강다온, 조은별 → 2명
- D4 소속: 윤하람, 배수아 → 2명
조건을 만족하는 행은 모두 4개다. D1(150)·D3(260)은 평균 이하라 제외된다.
26-1
두 호스트의 IP 주소와 서브넷 마스크가 아래와 같을 때, 각 호스트가 속한 네트워크의 주소를 CIDR 표기(주소/프리픽스 길이)로 적으시오.
| 구분 | IP 주소 | 서브넷 마스크 |
|---|---|---|
| ① | 192.168.11.20 | 255.255.254.0 |
| ② | 192.168.13.200 | 255.255.254.0 |
① 192.168.10.0/23
② 192.168.12.0/23
[해설]
255.255.254.0은 앞에서부터 1이 23개이므로 프리픽스는 /23이다. 셋째 옥텟만 AND 연산하면 된다.
- ① 11 = 0000 1011, 254 = 1111 1110 → 0000 1010 = 10
- ② 13 = 0000 1101, 254 = 1111 1110 → 0000 1100 = 12
- 넷째 옥텟은 마스크가 0이므로 모두 0이 된다.
네트워크 주소는 ① 192.168.10.0/23, ② 192.168.12.0/23이다. /23은 셋째 옥텟이 짝수인 값에서 블록이 시작한다고 기억하면 빠르다.