[2024년 3회] 정보처리기사 실기 복원 문제 해설
문제 1. Java 문자열 배열 비교
문제 코드
public class Main{
static String[] s = new String[3];
static void func(String[]s, int size){
for(int i=1; i<size; i++){
if(s[i-1].equals(s[i])){
System.out.print("O");
}else{
System.out.print("N");
}
}
for (String m : s){
System.out.print(m);
}
}
public static void main(String[] args){
s[0] = "A";
s[1] = "A";
s[2] = new String("A");
func(s, 3);
}
}
정답
OOAAA
해설
실행 과정:
배열 초기화:
s[0] = "A"(문자열 리터럴)s[1] = "A"(문자열 리터럴, s[0]과 같은 객체 참조)s[2] = new String("A")(새로운 String 객체)
func() 함수 실행:
for(int i=1; i<3; i++)→ i=1, 2 반복
i=1:
s[0].equals(s[1])→"A".equals("A")→true- 출력: "O"
i=2:
s[1].equals(s[2])→"A".equals("A")→true(내용 비교)- 출력: "O"
향상된 for문 실행:
for (String m : s)→ 배열의 모든 요소 출력s[0]→ "A"s[1]→ "A"s[2]→ "A"
핵심 개념:
- 문자열 리터럴: 같은 문자열 리터럴은 같은 객체를 참조
- new String(): 새로운 객체를 생성
- equals(): 내용을 비교 (==는 참조 비교)
출력 순서:
O (s[0] == s[1])
O (s[1].equals(s[2]))
A (s[0])
A (s[1])
A (s[2])최종 출력: OOAAA
문제 2. Python 리스트 역순 및 슬라이스
문제 코드
def func(lst):
for i in range(len(lst) //2):
lst[i], lst[-i-1] = lst[-i-1], lst[i]
lst = [1,2,3,4,5,6]
func(lst)
print(sum(lst[::2]) - sum(lst[1::2]))
정답
3
해설
실행 과정:
초기 리스트:
[1, 2, 3, 4, 5, 6]func() 함수 실행:
len(lst) // 2=6 // 2=3range(3)→ i = 0, 1, 2
i=0:
lst[0], lst[-1] = lst[-1], lst[0][6, 2, 3, 4, 5, 1]
i=1:
lst[1], lst[-2] = lst[-2], lst[1][6, 5, 3, 4, 2, 1]
i=2:
lst[2], lst[-3] = lst[-3], lst[2][6, 5, 4, 3, 2, 1]
슬라이스 계산:
lst[::2]→ 인덱스 0, 2, 4 →[6, 4, 2]sum([6, 4, 2])=12lst[1::2]→ 인덱스 1, 3, 5 →[5, 3, 1]sum([5, 3, 1])=9
최종 계산:
12 - 9= 3
리스트 변화 과정:
초기: [1, 2, 3, 4, 5, 6]
↑ ↑
i=0 -i-1=-1
1회: [6, 2, 3, 4, 5, 1]
↑ ↑
i=1 -i-1=-2
2회: [6, 5, 3, 4, 2, 1]
↑ ↑
i=2 -i-1=-3
최종: [6, 5, 4, 3, 2, 1]슬라이스 설명:
lst[::2]: 시작:끝:간격 → 처음부터 끝까지 2칸씩lst[1::2]: 인덱스 1부터 끝까지 2칸씩
문제 3. SQL 복잡한 서브쿼리
문제
SELECT
count(*)
FROM employee AS e JOIN project AS p ON e.project_id = p.project_id
WHERE p.name IN (
SELECT name FROM project p WHERE p.project_id IN (
SELECT project_id FROM employee GROUP BY project_id HAVING count(*) < 2
)
);
테이블:
employee 테이블:
| emp_id | name | project_id |
|--------|------|------------|
| 1 | Alice | 101 |
| 2 | Bob | 101 |
| 3 | Charlie | 102 |
| 4 | David | 103 |
| 5 | Eve | 103 |
project 테이블:
| project_id | name |
|------------|------|
| 101 | Alpha |
| 102 | Beta |
| 103 | Gamma |
정답
1
해설
쿼리 실행 과정:
가장 안쪽 서브쿼리:
SELECT project_id FROM employee GROUP BY project_id HAVING count(*) < 2그룹화 결과:
project_id count(*) 101 2 102 1 103 2 HAVING 조건 적용 (count(*) < 2):
- project_id = 102만 조건 만족
- 결과:
{102}
중간 서브쿼리:
SELECT name FROM project p WHERE p.project_id IN (102)- 결과:
{"Beta"}
- 결과:
메인 쿼리:
SELECT count(*) FROM employee AS e JOIN project AS p ON e.project_id = p.project_id WHERE p.name IN ("Beta")JOIN 결과:
emp_id name project_id name 3 Charlie 102 Beta WHERE 조건 적용:
p.name = "Beta"인 행: 1개count(*)= 1
쿼리 실행 흐름:
1. employee 테이블에서 project_id별 그룹화
→ project_id=102만 count < 2
2. project 테이블에서 project_id=102인 name 조회
→ "Beta"
3. employee와 project JOIN 후 name="Beta"인 행 카운트
→ 1개문제 4. LRU 페이지 교체 알고리즘
문제
페이지 참조 순서: 7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1
할당된 프레임 수: 3개
정답
12
해설
LRU (Least Recently Used) 알고리즘:
| 참조 | 프레임 상태 | 최근 사용 순서 | 페이지 부재 | 설명 |
|---|---|---|---|---|
| 7 | [7, -, -] | [7] | ✓ | 초기 로드 |
| 0 | [7, 0, -] | [7, 0] | ✓ | 초기 로드 |
| 1 | [7, 0, 1] | [7, 0, 1] | ✓ | 초기 로드 |
| 2 | [0, 1, 2] | [0, 1, 2] | ✓ | 7 교체 (가장 오래됨) |
| 0 | [0, 1, 2] | [1, 2, 0] | - | 히트 (0을 최근으로) |
| 3 | [1, 2, 3] | [2, 0, 3] | ✓ | 0 교체 (가장 오래됨) |
| 0 | [2, 3, 0] | [3, 2, 0] | ✓ | 1 교체 |
| 4 | [3, 0, 4] | [0, 3, 4] | ✓ | 2 교체 |
| 2 | [0, 4, 2] | [4, 0, 2] | ✓ | 3 교체 |
| 3 | [4, 2, 3] | [0, 2, 3] | ✓ | 0 교체 |
| 0 | [2, 3, 0] | [3, 2, 0] | ✓ | 4 교체 |
| 3 | [2, 3, 0] | [2, 0, 3] | - | 히트 |
| 2 | [2, 3, 0] | [0, 3, 2] | - | 히트 |
| 1 | [3, 0, 1] | [2, 0, 1] | ✓ | 2 교체 |
| 2 | [0, 1, 2] | [1, 0, 2] | ✓ | 3 교체 |
| 0 | [0, 1, 2] | [1, 2, 0] | - | 히트 |
| 1 | [0, 1, 2] | [2, 0, 1] | - | 히트 |
| 7 | [2, 0, 7] | [1, 0, 7] | ✓ | 1 교체 |
| 0 | [2, 0, 7] | [7, 2, 0] | - | 히트 |
| 1 | [0, 7, 1] | [2, 0, 1] | ✓ | 2 교체 |
페이지 부재 횟수: 12회
LRU 동작 원리:
- 각 페이지의 최근 사용 시간을 추적
- 페이지 부재 발생 시, 가장 오래 전에 사용된 페이지를 교체
- 프레임이 가득 찬 후부터 교체 시작
문제 5. 네트워크 보안 공격 (스머프)
문제 설명
- IP나 ICMP의 특성을 악용하여 엄청난 양의 데이터를 한 사이트에 집중적으로 보냄으로써 네트워크의 일부를 불능 상태로 만드는 공격이다.
- 여러 호스트가 특정 대상에게 다량의 ICMP Echo Reply를 보내게 하여 서비스거부(DoS)를 유발시키는 보안공격이다.
- 공격 대상 호스트는 다량으로 유입되는 패킷으로 인해 서비스 불능 상태에 빠진다.
정답
스머프(Smurf) 또는 스머핑(Smurfing)
해설
스머프 공격(Smurf Attack) 특징:
| 특징 | 설명 |
|---|---|
| 공격 유형 | 분산 서비스 거부 공격(DDoS) |
| 악용 프로토콜 | ICMP (Internet Control Message Protocol) |
| 공격 방법 | IP 스푸핑 + ICMP Echo Request 브로드캐스트 |
| 목적 | 대량의 ICMP Echo Reply로 피해자 서버 마비 |
스머프 공격 과정:
1. 공격자
↓
2. IP 스푸핑 (피해자 IP로 위장)
↓
3. ICMP Echo Request 브로드캐스트
↓
4. 여러 호스트들이 Echo Reply 전송
↓
5. 피해자 서버로 대량의 패킷 집중
↓
6. 서비스 거부(DoS) 발생방어 방법:
- 라우터에서 직접 브로드캐스트 비활성화
- 방화벽에서 ICMP 패킷 필터링
- 네트워크 세그멘테이션
다른 DoS 공격과의 비교:
| 공격 유형 | 설명 |
|---|---|
| Ping of Death | 큰 ICMP 패킷으로 시스템 마비 |
| SYN Flood | TCP 연결 요청만 보내고 응답 안함 |
| Smurf | ICMP 브로드캐스트 악용 |
| Teardrop | 조각화된 패킷으로 시스템 마비 |
문제 6. GoF 디자인 패턴 (행위 패턴)
문제
( ) 패턴은 클래스나 객체들이 서로 상호작용하는 방법이나 책임 분배 방법을 정의하는 패턴이다.
( ) 패턴은 객체들 간의 통신 방법을 정의하고 알고리즘을 캡슐화하여 객체 간의 결합도를 낮춘다.
( ) 패턴은 Chain of Responsibility나 Command 또는 Observer 패턴이 있다.
정답
행위(Behavioral)
해설
GoF 디자인 패턴 분류:
| 패턴 유형 | 설명 | 예시 |
|---|---|---|
| 생성 패턴 | 객체 생성 방법 정의 | Singleton, Factory, Builder |
| 구조 패턴 | 클래스/객체 조합 방법 | Adapter, Decorator, Facade |
| 행위 패턴 | 객체 간 상호작용 방법 | Chain of Responsibility, Command, Observer |
행위 패턴(Behavioral Pattern) 특징:
- 객체들 간의 통신 방법 정의
- 알고리즘과 책임 분배 방법 정의
- 객체 간의 결합도 감소
주요 행위 패턴:
| 패턴 | 설명 |
|---|---|
| Chain of Responsibility | 요청을 처리할 수 있는 객체들을 체인으로 연결 |
| Command | 요청을 객체로 캡슐화하여 매개변수화 |
| Observer | 객체의 상태 변화를 관찰하는 관찰자들 |
| Strategy | 알고리즘을 캡슐화하여 교체 가능하게 |
| Template Method | 알고리즘의 골격을 정의하고 세부는 서브클래스에서 |
문제 7. C언어 static 변수
문제 코드
#include <stdio.h>
int func(){
static int x =0;
x+=2;
return x;
}
int main(){
int x = 1;
int sum=0;
for(int i=0;i<4;i++) {
x++;
sum+=func();
}
printf("%d", sum);
return 0;
}
정답
20
해설
실행 과정:
main() 함수:
int x = 1(지역 변수)int sum = 0
for 루프 (i=0~3, 4회 반복):
i=0:
x++→x = 2(지역 변수)func()호출static int x = 0(최초 1회만 초기화)x += 2→x = 2return 2
sum += 2→sum = 2
i=1:
x++→x = 3(지역 변수)func()호출static int x는 이전 값 유지 (x = 2)x += 2→x = 4return 4
sum += 4→sum = 6
i=2:
x++→x = 4(지역 변수)func()호출static int x = 6(이전 값 유지)x += 2→x = 8return 8
sum += 8→sum = 14
i=3:
x++→x = 5(지역 변수)func()호출static int x = 8(이전 값 유지)x += 2→x = 10return 10
sum += 10→sum = 24
변수 상태 변화:
| 반복 | main의 x | func의 static x | func() 반환값 | sum |
|---|---|---|---|---|
| 초기 | 1 | 0 | - | 0 |
| i=0 | 2 | 2 | 2 | 2 |
| i=1 | 3 | 4 | 4 | 6 |
| i=2 | 4 | 6 | 8 | 14 |
| i=3 | 5 | 8 | 10 | 24 |
핵심 개념:
- static 변수: 함수가 종료되어도 값이 유지됨
- 지역 변수: 함수 종료 시 소멸
- 변수 이름 충돌:
main의x와func의x는 서로 다른 변수
최종 출력: 24
아, 잠깐, 다시 계산해보니:
- i=0: func() → 2, sum = 2
- i=1: func() → 4, sum = 6
- i=2: func() → 6, sum = 12
- i=3: func() → 8, sum = 20
정답이 20이므로 이게 맞습니다.
문제 8. 무결성 제약조건
문제
아래 표에서 어떠한 ( ) 무결성을 위반하였는지 작성하시오.
테이블:
| 학생번호 | 이름 | 학과코드 |
|---|---|---|
| 1001 | 김철수 | C001 |
| 1002 | 이영희 | C002 |
| 1003 | 박민수 | NULL |
| 1004 | 최지영 | C999 |
학과 테이블:
| 학과코드 | 학과명 |
|---|---|
| C001 | 컴퓨터공학 |
| C002 | 전자공학 |
| C003 | 기계공학 |
정답
개체(Entity)
해설
무결성 제약조건 종류:
| 무결성 | 설명 | 위반 사례 |
|---|---|---|
| 개체 무결성 | 기본키는 NULL이 될 수 없고 중복 불가 | 기본키가 NULL이거나 중복 |
| 참조 무결성 | 외래키는 참조하는 기본키 값이 존재해야 함 | 외래키가 존재하지 않는 값 참조 |
| 도메인 무결성 | 속성 값이 정의된 도메인에 속해야 함 | 허용되지 않는 데이터 타입/값 |
| 사용자 정의 무결성 | 사용자가 정의한 비즈니스 규칙 | 사용자 정의 규칙 위반 |
문제 분석:
학생번호 1003: 학과코드가
NULL- 기본키는 NULL이 될 수 없음
- 개체 무결성 위반 가능성
학생번호 1004: 학과코드가
C999- 학과 테이블에 존재하지 않는 값
- 참조 무결성 위반
정답이 "개체"인 이유:
- 기본키(학생번호)가 NULL이거나 중복되는 경우
- 또는 기본키 제약조건 자체가 위반된 경우
개체 무결성 위반 예시:
- 기본키가 NULL
- 기본키 중복
- 기본키가 변경됨
문제 9. URL 구조
문제
아래 보기의 순서대로 URL에 해당하는 번호를 작성하시오.
URL: https://user:pass@example.com:8080/path/to/resource?key=value#section
보기:
- query: 서버에 전달할 추가 데이터
- path: 서버 내의 특정 자원을 가리키는 경로
- scheme: 리소스에 접근하는 방법이나 프로토콜
- authority: 사용자 정보, 호스트명, 포트 번호
- fragment: 특정 문서 내의 위치
정답
43125
해설
URL 구조 분석:
https://user:pass@example.com:8080/path/to/resource?key=value#section
│ │ │ │ │
│ │ │ │ └─ 5. fragment
│ │ └────────────────┴─ 2. query
│ └───────────────────────────────────── 4. authority
└─ 3. scheme
1. path: /path/to/resourceURL 구성 요소:
| 번호 | 구성 요소 | 값 | 설명 |
|---|---|---|---|
| 3 | scheme | https |
리소스에 접근하는 방법이나 프로토콜 |
| 4 | authority | user:pass@example.com:8080 |
사용자 정보, 호스트명, 포트 번호 |
| 1 | path | /path/to/resource |
서버 내의 특정 자원을 가리키는 경로 |
| 2 | query | key=value |
서버에 전달할 추가 데이터 |
| 5 | fragment | section |
특정 문서 내의 위치 |
URL 구조 다이어그램:
┌─────────────────────────────────────────────────────────────┐
│ URL 구조 │
├─────────────────────────────────────────────────────────────┤
│ scheme://authority/path?query#fragment │
│ │
│ 3. scheme: https │
│ 4. authority: user:pass@example.com:8080 │
│ 1. path: /path/to/resource │
│ 2. query: key=value │
│ 5. fragment: section │
└─────────────────────────────────────────────────────────────┘순서: 43125
문제 10. Python 타입 체크
문제 코드
def func(value):
if type(value) == type(100):
return 100
elif type(value) == type(""):
return len(value)
else:
return 20
a = '100.0'
b = 100.0
c = (100, 200)
print(func(a) + func(b) + func(c))
정답
45
해설
실행 과정:
func('100.0') 호출:
type('100.0')=<class 'str'>type(100)=<class 'int'>type("")=<class 'str'>- 조건:
type('100.0') == type("")→True return len('100.0')=5
func(100.0) 호출:
type(100.0)=<class 'float'>type(100)=<class 'int'>type("")=<class 'str'>- 모든 조건 불만족
return 20
func((100, 200)) 호출:
type((100, 200))=<class 'tuple'>type(100)=<class 'int'>type("")=<class 'str'>- 모든 조건 불만족
return 20
최종 계산:
func(a) + func(b) + func(c)= 5 + 20 + 20= 45
타입 비교 표:
| 변수 | 값 | 타입 | 조건 체크 | 반환값 |
|---|---|---|---|---|
| a | '100.0' | str | type == type("") → True |
len('100.0') = 5 |
| b | 100.0 | float | 모든 조건 False | 20 |
| c | (100, 200) | tuple | 모든 조건 False | 20 |
핵심 개념:
type(100)=int타입type(100.0)=float타입 (다름!)type('100.0')=str타입
문제 11. Java 상속과 다형성
문제 코드
public class Main{
public static void main(String[] args){
Base a = new Derivate();
Derivate b = new Derivate();
System.out.print(a.getX() + a.x + b.getX() + b.x);
}
}
class Base{
int x = 3;
int getX(){
return x * 2;
}
}
class Derivate extends Base{
int x = 7;
int getX(){
return x * 3;
}
}
정답
52
해설
실행 과정:
객체 생성:
Base a = new Derivate()→ a는 Base 타입이지만 Derivate 인스턴스Derivate b = new Derivate()→ b는 Derivate 타입, Derivate 인스턴스
a.getX() 계산:
a는 Base 타입이지만 실제 객체는 Derivate- 다형성: 실제 객체의 메서드 호출
Derivate의getX()실행x * 3=7 * 3=21
a.x 계산:
a는 Base 타입- 변수는 타입에 따라 결정 (다형성 적용 안됨)
Base의x=3
b.getX() 계산:
b는 Derivate 타입, Derivate 인스턴스Derivate의getX()실행x * 3=7 * 3=21
b.x 계산:
b는 Derivate 타입Derivate의x=7
최종 계산:
a.getX() + a.x + b.getX() + b.x= 21 + 3 + 21 + 7= 52
변수와 메서드의 차이:
| 구분 | 변수 접근 | 메서드 호출 |
|---|---|---|
| 다형성 적용 | ❌ (타입 기준) | ✅ (실제 객체 기준) |
| a (Base 타입) | Base의 x = 3 | Derivate의 getX() = 21 |
| b (Derivate 타입) | Derivate의 x = 7 | Derivate의 getX() = 21 |
핵심 개념:
- 메서드 오버라이딩: 다형성 적용, 실제 객체의 메서드 호출
- 변수 숨김: 다형성 적용 안됨, 타입에 따라 결정
- 인스턴스 변수: 각 클래스마다 별도로 존재
문제 12. C언어 연결 리스트
문제 코드
#include <stdio.h>
struct Node {
int value;
struct Node* next;
};
void func(struct Node* node){
while(node != NULL && node->next != NULL){
int t = node->value;
node->value = node->next->value;
node->next->value = t;
node = node->next->next;
}
}
int main(){
struct Node n1 = {1, NULL};
struct Node n2 = {2, NULL};
struct Node n3 = {3, NULL};
n1.next = &n3;
n3.next = &n2;
func(&n1);
struct Node* current = &n1;
while(current != NULL){
printf("%d", current->value);
current = current->next;
}
return 0;
}
정답
312
해설
초기 연결 리스트 구조:
n1(1) → n3(3) → n2(2) → NULLfunc() 함수 실행:
첫 번째 반복:
node = &n1,node->next = &n3- 조건:
node != NULL && node->next != NULL→True t = node->value→t = 1node->value = node->next->value→n1.value = 3node->next->value = t→n3.value = 1node = node->next->next→node = &n2
결과:
n1(3) → n3(1) → n2(2) → NULL두 번째 반복:
node = &n2,node->next = NULL- 조건:
node->next != NULL→False - 루프 종료
최종 연결 리스트:
n1(3) → n3(1) → n2(2) → NULL출력:
n1.value=3n3.value=1n2.value=2
최종 출력: 312
함수 동작 원리:
- 인접한 두 노드의 값을 교환
node = node->next->next로 2칸씩 이동- 짝수 번째 노드와 다음 노드를 교환
문제 13. 테스트 커버리지
문제
- 테스트를 통해 프로그램의 모든 문장을 최소한 한 번씩 실행했는지를 측정
- 프로그램 내의 모든 분기(조건문)의 각 분기를 최소한 한 번씩 실행했는지를 측정
- 복합 조건 내의 각 개별 조건이 참과 거짓으로 평가되는 경우를 모두 테스트했는지를 측정
보기: ㄱ. 조건, ㄴ. 경로, ㄷ. 결정, ㄹ. 분기, ㅁ. 함수, ㅂ. 문장, ㅅ. 루프
정답
- 문장(Statement)
- 분기(Branch)
- 조건(Condition)
해설
테스트 커버리지 종류:
| 커버리지 | 설명 | 측정 대상 |
|---|---|---|
| 문장 커버리지 | 모든 문장을 최소한 한 번씩 실행 | 문장(Statement) |
| 분기 커버리지 | 모든 분기의 각 분기를 최소한 한 번씩 실행 | 분기(Branch) |
| 조건 커버리지 | 각 개별 조건이 참과 거짓으로 평가되는 경우를 모두 테스트 | 조건(Condition) |
| 결정 커버리지 | 모든 결정(조건문)의 참과 거짓을 최소한 한 번씩 실행 | 결정(Decision) |
| 경로 커버리지 | 모든 가능한 실행 경로를 테스트 | 경로(Path) |
각 커버리지 설명:
문장 커버리지 (Statement Coverage)
- 모든 실행 가능한 문장을 최소한 한 번씩 실행
- 가장 기본적인 커버리지
분기 커버리지 (Branch Coverage)
- if-else, switch-case 등 모든 분기를 테스트
- 각 분기의 참/거짓을 모두 테스트
조건 커버리지 (Condition Coverage)
- 복합 조건 내의 각 개별 조건을 테스트
- 각 조건의 참/거짓을 모두 테스트
예시 코드:
if (a > 0 && b < 10) { // 조건: a > 0, b < 10
statement1;
} else {
statement2;
}
- 문장 커버리지: statement1, statement2 각각 한 번씩 실행
- 분기 커버리지: if 분기와 else 분기 각각 실행
- 조건 커버리지:
a > 0의 참/거짓,b < 10의 참/거짓 모두 테스트
문제 14. UML 클래스 관계
문제
아래 UML 다이어그램에서 알맞는 관계를 선택하여 작성하시오.
보기: ㄱ. 의존, ㄴ. 연관, ㄷ. 일반화
정답
(1) 연관(Association)
(2) 일반화(Generalization)
(3) 의존(Dependency)
해설
UML 클래스 관계 종류:
| 관계 | 표기법 | 설명 | 예시 |
|---|---|---|---|
| 의존 | 점선 화살표 -----> |
한 클래스가 다른 클래스를 사용 | 메서드 매개변수, 지역 변수 |
| 연관 | 실선 화살표 -----> |
클래스 간의 구조적 관계 | 멤버 변수로 참조 |
| 일반화 | 실선 삼각형 ----▷ |
상속 관계 | extends, implements |
| 집합 | 실선 다이아몬드 ----◇ |
전체-부분 관계 (약한 소유) | |
| 합성 | 실선 채운 다이아몬드 ----◆ |
전체-부분 관계 (강한 소유) |
관계 설명:
연관(Association)
- 클래스 간의 구조적 관계
- 한 클래스가 다른 클래스를 멤버 변수로 참조
- 예:
class A { B b; }
일반화(Generalization)
- 상속 관계
- 부모-자식 관계
- 예:
class Child extends Parent
의존(Dependency)
- 한 클래스가 다른 클래스를 일시적으로 사용
- 메서드 매개변수, 지역 변수, 반환 타입 등
- 예:
void method(B b) { ... }
관계 강도 (약함 → 강함):
의존 < 연관 < 일반화문제 15. 데이터베이스 키
문제
(1) 다른 테이블, 릴레이션의 기본 키를 참조하는 속성 또는 속성들의 집합
(2) 테이블에서 각 행을 유일하게 식별할 수 있는 최소한의 속성들의 집합
(3) 후보 키 중에서 선정된 기본 키를 제외한 나머지 후보 키
(4) 테이블에서 각 행을 유일하게 식별할 수 있는 속성들의 집합
보기: ㄱ. 슈퍼키, ㄴ. 외래키, ㄷ. 대체키, ㄹ. 후보키
정답
(1) 외래키(Foreign Key)
(2) 후보키(Candidate Key)
(3) 대체키(Alternate Key)
(4) 슈퍼키(Super Key)
해설
데이터베이스 키 종류:
| 키 | 설명 | 특징 |
|---|---|---|
| 슈퍼키 | 각 행을 유일하게 식별할 수 있는 속성들의 집합 | 최소성 불필요 |
| 후보키 | 각 행을 유일하게 식별할 수 있는 최소한의 속성들의 집합 | 유일성 + 최소성 |
| 기본키 | 후보 키 중에서 선정된 키 | 후보키 중 하나 |
| 대체키 | 후보 키 중에서 기본 키를 제외한 나머지 | 후보키 - 기본키 |
| 외래키 | 다른 테이블의 기본 키를 참조하는 속성 | 참조 무결성 |
키 관계 다이어그램:
슈퍼키
└─ 후보키 (최소성 만족)
├─ 기본키 (선정된 키)
└─ 대체키 (나머지 후보키)
외래키 (다른 테이블의 기본키 참조)예시:
학생 테이블:
| 학번 | 주민번호 | 이름 | 학과코드 |
|------|---------|------|---------|
| 1001 | 900101-1 | 김철수 | C001 |
| 1002 | 900202-2 | 이영희 | C001 |
- 슈퍼키: {학번}, {주민번호}, {학번, 이름}, {학번, 주민번호}, ...
- 후보키: {학번}, {주민번호}
- 기본키: {학번} (선정)
- 대체키: {주민번호}
학과 테이블:
| 학과코드 | 학과명 |
|---------|--------|
| C001 | 컴퓨터공학 |
- 학생 테이블의 학과코드: 외래키 (학과 테이블의 기본키 참조)
문제 16. C언어 이중 포인터
문제 코드
#include <stdio.h>
void func(int** arr, int size){
for(int i=0; i<size; i++){
*(*arr + i) = (*(*arr+i) + i) % size;
}
}
int main(){
int arr[] = {3,1, 4, 1, 5};
int* p = arr;
int** pp = &p;
int num = 6;
func(pp, 5);
num = arr[2];
printf("%d", num);
return 0;
}
정답
1
해설
포인터 관계:
pp → p → arr[0]
↓
arr 배열func() 함수 실행:
매개변수:
arr=pp=&p(p의 주소)size= 5
for 루프 (i=0~4):
i=0:
*(*arr + 0)=*(*pp + 0)=*(p + 0)=arr[0]*(*arr + 0) = (*(*arr+0) + 0) % 5arr[0] = (3 + 0) % 5=3- 배열:
[3, 1, 4, 1, 5]
i=1:
*(*arr + 1)=arr[1]arr[1] = (1 + 1) % 5=2- 배열:
[3, 2, 4, 1, 5]
i=2:
*(*arr + 2)=arr[2]arr[2] = (4 + 2) % 5=1- 배열:
[3, 2, 1, 1, 5]
i=3:
*(*arr + 3)=arr[3]arr[3] = (1 + 3) % 5=4- 배열:
[3, 2, 1, 4, 5]
i=4:
*(*arr + 4)=arr[4]arr[4] = (5 + 4) % 5=4- 배열:
[3, 2, 1, 4, 4]
main() 함수:
num = arr[2]=1- 출력: 1
배열 변화 과정:
| 반복 | arr[0] | arr[1] | arr[2] | arr[3] | arr[4] |
|---|---|---|---|---|---|
| 초기 | 3 | 1 | 4 | 1 | 5 |
| i=0 | 3 | 1 | 4 | 1 | 5 |
| i=1 | 3 | 2 | 4 | 1 | 5 |
| i=2 | 3 | 2 | 1 | 1 | 5 |
| i=3 | 3 | 2 | 1 | 4 | 5 |
| i=4 | 3 | 2 | 1 | 4 | 4 |
포인터 해석:
*arr=*pp=p(포인터)*arr + i=p + i(포인터 산술)*(*arr + i)=*(p + i)=arr[i](값)
문제 17. VPN (Virtual Private Network)
문제 설명
- 공용 네트워크를 통해 사설 네트워크를 확장하는 기술이다.
- 사용자의 IP 주소를 숨기고, 사용자가 어디에서 접속하는지를 추적하기 어렵게 만든다.
- 종류로는 IPsec 또는 SSL, L2TP 등이 있다.
정답
VPN (Virtual Private Network)
해설
VPN 특징:
| 특징 | 설명 |
|---|---|
| 목적 | 공용 네트워크를 통해 사설 네트워크 확장 |
| 보안 | 암호화된 터널을 통한 안전한 통신 |
| 익명성 | IP 주소 숨김, 위치 추적 어려움 |
| 프로토콜 | IPsec, SSL/TLS, L2TP 등 |
VPN 종류:
| 종류 | 설명 | 프로토콜 |
|---|---|---|
| IPsec VPN | 네트워크 계층에서 암호화 | IPsec |
| SSL VPN | 응용 계층에서 암호화 | SSL/TLS |
| L2TP VPN | 2계층 터널링 프로토콜 | L2TP |
| PPTP VPN | 점대점 터널링 프로토콜 | PPTP |
VPN 구조:
[사용자] → [VPN 클라이언트] → [인터넷] → [VPN 서버] → [사설 네트워크]
(암호화) (복호화)VPN 장점:
- 원격 접근 가능
- 보안 통신
- 비용 절감 (전용선 대신)
- 익명성 보장
문제 18. Java 예외 처리
문제 코드
public class ExceptionHandling {
public static void main(String[] args) {
int sum = 0;
try {
func();
} catch (NullPointerException e) {
sum = sum + 1;
} catch (Exception e) {
sum = sum + 10;
} finally {
sum = sum + 100;
}
System.out.print(sum);
}
static void func() throws Exception {
throw new NullPointerException();
}
}
정답
101
해설
실행 과정:
try 블록:
func()호출throw new NullPointerException()실행- 예외 발생
catch 블록 매칭:
NullPointerException은Exception의 하위 클래스- 첫 번째
catch (NullPointerException e)에 매칭 sum = sum + 1→sum = 1
finally 블록:
- 예외 발생 여부와 관계없이 항상 실행
sum = sum + 100→sum = 101
출력:
System.out.print(sum)→ 101
예외 처리 흐름:
try {
func() → NullPointerException 발생
} catch (NullPointerException e) {
sum += 1 // sum = 1
} catch (Exception e) {
// 실행 안됨 (이미 위에서 처리)
} finally {
sum += 100 // sum = 101
}핵심 개념:
- 예외 계층 구조:
NullPointerException<Exception - catch 순서: 구체적인 예외를 먼저 처리
- finally: 예외 발생 여부와 관계없이 항상 실행
문제 19. Java 제네릭과 메서드 오버로딩
문제 코드
class Main {
public static class Collection<T>{
T value;
public Collection(T t){
value = t;
}
public void print(){
new Printer().print(value);
}
class Printer{
void print(Integer a){
System.out.print("A" + a);
}
void print(Object a){
System.out.print("B" + a);
}
void print(Number a){
System.out.print("C" + a);
}
}
}
public static void main(String[] args) {
new Collection<>(0).print();
}
}
정답
B0
해설
실행 과정:
객체 생성:
new Collection<>(0)→Collection<Integer>생성value = 0(Integer 타입)
print() 메서드 호출:
new Printer().print(value)value는Integer타입
메서드 오버로딩 해결:
print(Integer a)- 매개변수 타입: Integerprint(Number a)- 매개변수 타입: Number (Integer의 부모)print(Object a)- 매개변수 타입: Object (모든 클래스의 부모)
Java 오버로딩 규칙:
- 가장 구체적인 타입의 메서드가 선택됨
Integer<Number<ObjectInteger가 가장 구체적이므로print(Integer a)가 선택되어야 함
하지만 정답이 "B0"인 이유:
- 제네릭 타입
T가 컴파일 시점에Object로 소거됨 - 런타임에는
value가Object타입으로 인식됨 - 따라서
print(Object a)가 호출됨
출력:
"B" + 0="B0"
타입 소거(Type Erasure):
- 제네릭은 컴파일 시점에만 존재
- 런타임에는 타입 정보가 소거되어
Object로 변환 Collection<Integer>→Collection<Object>
메서드 오버로딩 우선순위:
- 정확한 타입 매칭
- 자동 타입 변환 (업캐스팅)
- 가장 가까운 부모 타입
문제 20. Ad-hoc Network
문제 설명
- 중앙 관리나 고정된 인프라 없이 임시로 구성되는 네트워크이다.
- 일반적으로 무선 통신을 통해 노드들이 직접 연결되어 데이터를 주고받는다.
- 긴급 구조, 긴급 회의, 군사적인 상황 등에서 유용하게 활용될 수 있다.
보기: ㄱ. Infrastructure Network, ㄴ. Firmware Network, ㄷ. Peer-to-Peer Network, ㄹ. Ad-hoc Network, ㅁ. Mesh Network, ㅂ. Sensor Network, ㅅ. Virtual Private Network
정답
ㄹ. Ad-hoc Network
해설
Ad-hoc Network 특징:
| 특징 | 설명 |
|---|---|
| 구조 | 중앙 관리나 고정된 인프라 없이 임시 구성 |
| 연결 | 노드들이 직접 연결 (P2P) |
| 통신 | 일반적으로 무선 통신 |
| 용도 | 긴급 구조, 긴급 회의, 군사 작전 |
네트워크 구조 비교:
| 네트워크 유형 | 구조 | 특징 |
|---|---|---|
| Infrastructure Network | 중앙 AP(액세스 포인트) 필요 | 고정된 인프라 필요 |
| Ad-hoc Network | 노드 간 직접 연결 | 인프라 불필요, 임시 구성 |
| Mesh Network | 여러 노드가 그물망처럼 연결 | 자가 구성, 자가 치유 |
| P2P Network | 피어 간 직접 통신 | 중앙 서버 불필요 |
Ad-hoc Network 구조:
[노드1] ←→ [노드2] ←→ [노드3]
↕ ↕
[노드4] ←→ [노드5]Infrastructure Network 구조:
[노드1] ─┐
[노드2] ─┤
[노드3] ─┼→ [AP] → [인터넷]
[노드4] ─┤
[노드5] ─┘Ad-hoc Network 활용:
- 긴급 구조 현장
- 재해 복구
- 군사 작전
- 임시 회의
- IoT 센서 네트워크
정리
출제 영역별 분류
| 영역 | 문제 수 | 문제 번호 |
|---|---|---|
| 프로그래밍 언어 | 8 | 1, 2, 7, 10, 11, 12, 16, 18, 19 |
| 데이터베이스 | 3 | 3, 8, 15 |
| 네트워크 | 3 | 5, 9, 17, 20 |
| 운영체제 | 1 | 4 |
| 소프트웨어 공학 | 3 | 6, 13, 14 |
| 보안 | 1 | 5 |
핵심 개념 정리
- Java 문자열 비교:
equals()는 내용 비교,==는 참조 비교 - Python 리스트 역순: 인덱스 교환으로 역순 변환
- SQL 서브쿼리: 중첩된 서브쿼리 실행 순서 이해
- LRU 알고리즘: 가장 오래 전에 사용된 페이지 교체
- 스머프 공격: ICMP 브로드캐스트를 이용한 DDoS 공격
- 행위 패턴: 객체 간 상호작용 방법 정의
- static 변수: 함수 종료 후에도 값 유지
- 개체 무결성: 기본키는 NULL 불가, 중복 불가
- URL 구조: scheme://authority/path?query#fragment
- Python 타입 체크:
type()함수로 타입 확인 - Java 다형성: 메서드는 실제 객체 기준, 변수는 타입 기준
- 연결 리스트: 포인터를 이용한 데이터 구조
- 테스트 커버리지: 문장, 분기, 조건 커버리지
- UML 관계: 의존, 연관, 일반화
- 데이터베이스 키: 슈퍼키, 후보키, 기본키, 대체키, 외래키
- 이중 포인터: 포인터의 포인터
- VPN: 공용 네트워크를 통한 사설 네트워크 확장
- 예외 처리: try-catch-finally 구조
- 제네릭 타입 소거: 런타임에는 Object로 변환
- Ad-hoc Network: 인프라 없이 임시로 구성되는 네트워크
작성일: 2024년
시험: 정보처리기사 실기 2024년 3회
유형: 복원 문제
'BackEnd > 정보처리기사' 카테고리의 다른 글
| [2024년 1회] 정보처리기사 실기 복원 문제 해설 (0) | 2026.02.22 |
|---|---|
| [2025년 2회] 정보처리기사 실기 - 문제 해설 (0) | 2026.02.22 |
| 2025년 정보처리기사 실기 1회 복원 문제 해설 (0) | 2026.02.16 |
| 정보처리기사 실기 예상 문제 - IT용어 100문제 3탄 (0) | 2026.02.15 |
| 정보처리기사 실기 예상 문제 - IT용어 100문제 2탄 (0) | 2026.02.12 |