1. 다음은 Java 코드에 대한 문제이다. 아래 코드를 확인하여 알맞은 출력값을 작성하시오.
class Main {
public static void main(String[] args) {
int[] a = new int[]{1, 2, 3, 4};
int[] b = new int[]{1, 2, 3, 4};
int[] c = new int[]{1, 2, 3};
check(a, b);
check(a, c);
check(b, c);
}
public static void check(int[] a, int[] b) {
if (a==b) {
System.out.print("O");
}else{
System.out.print("N");
}
}
}
NNN
- 해당 프로그램은 Java에서 배열의 동등성 비교가 어떻게 이루어지는지를 테스트하는 프로그램이다.
- a, b, c는 각각 배열의 내용이 비슷하거나 동일하지만, 각 배열은 서로 다른 메모리 위치에 저장됩니다.
- a와 b는 내용이 [1, 2, 3, 4]로 같지만, Java에서는 배열을 생성할 때마다 새로운 메모리 주소가 할당됩니다. 따라서 a와 b는 서로 다른 메모리 주소를 갖습니다.
- c는 [1, 2, 3]을 가지며 a, b와는 길이와 내용이 다릅니다.
- check(a, b); → a와 b는 서로 다른 메모리 주소를 가지고 있으므로 N 출력.
- check(a, c); → a와 c는 내용도 다르고 메모리 주소도 다르므로 N 출력.
- check(b, c); → b와 c도 서로 다른 주소를 가지므로 N 출력.
2. 다음 문제에서 설명하는 용어를 작성하시오.
데이터를 중복시켜 성능을 향상시키기 위한 기법으로 데이터를 중복 저장하거나 테이블을 합치는 등으로 성능을 향상시키지만 데이터 무결성이 저하될 수 있는 기법
|
반정규화, 비정규화, 역정규화
* 반정규화
- 정규화된 엔티티, 속성, 관계에 대해 시스템의 성능 향상과 개발과 운영의 단순화를 위해 중복, 통합, 분리 등을 수행하는 데이터 모델링의 기법을 의미한다.
- 정규화를 통하여 정합성과 데이터 무결성이 보장되지만, 테이블의 개수가 증가함에 따라 테이블 간의 조인이 증가하여 조회 성능이 떨어질 수 있다.
- 즉, 반정규화란 DB의 성능 향상을 목적으로 정규화를 통해 분할된 테이블을 다시 합치는 과정을 의미한다.
* 반정규화의 유형
구분 | 유형 | 설명 |
테이블 분할 | 수평 분할 | 레코드 단위로 분할 |
수직 분할 | 컬럼 단위로 분할 | |
테이블 중복 | 통계 테이블 추가 | DW, OLAP 데이터 용 |
진행 테이블 추가 | 업무 프로세스 상태 | |
컬럼기반 분할 | 조회 빈도 기반 | 고빈도 컬럼 분리 |
크기 기반 분할 | 일정 용량 컬럼 분리 | |
컬럼 중복 | 중복 컬럼 추가 | 자주 조회되는 컬럼 추가 |
파생 컬럼 추가 | 연산 결과 별도 저장 |
3. 다음은 SQL에 관한 문제이다. 아래 SQL 구문의 빈칸을 작성하시오.
사원 [사원번호(PK), 이름, 나이, 부서]
부서 [사원번호(PK), 이름, 주소, 나이]
# 신입 사원이 들어와서 사원 테이블에 추가
INSERT INTO 사원 (사원번호, 이름, 주소, 부서) [ ① ] (32431, '정실기', '서울', '영업');
# 위에 신입사원을 검색하면서 부서 테이블에 추가
INSERT INTO 부서 (사원번호, 이름, 나이, 부서)
[ ② ] 사원번호, 이름, 나이, 23 FROM 사원 WHERE 이름 = '정실기';
# 전체 사원 테이블 조회
SELECT * [ ③ ] 사원;
# 퇴사로 인해 부서에 해당하는 값을 '퇴사'로 변경
UPDATE 사원 [ ④ ] 부서 = '퇴사' WHERE 사원번호 = 32431;
VALUES, SELECT, FROM, SET
* INSERT(삽입문)
INSERT INTO 테이블_이름 [(속성_이름...)] VALUES (속성값...); |
- 기존 테이블에 새로운 자료(튜플)을 삽입하는 경우 사용하는 명령문이다.
* SELECT(검색문)
SELECT (DISTINCT) 속성_이름 FROM 테이블_이름 (WHERE 조건) (GROUP BY 속성_이름 (HAVING 그룹조건)) (ORDER BY 속성_이름 (ASC/DESC)) |
- DISTINCT : 검색 결과에 중복되는 값이 있는 경우 한 번만 표현하도록 하는 옵션이며, 생략 시 중복된 값이 모두 표시된다.
- HAVING 그룹조건 : GROUP BY에 의해 그룹으로 분류를 한 후 조건을 제시할 때 사용된다.
- ASC : 오름차순(작은 값에서 큰 값)으로 정렬할 때 사용되는 옵션이다. 기본 옵션이다.
- DESC : 내림차순(큰 값에서 작은 값)으로 정렬할 때 사용되는 옵션이다.
* UPDATE(갱신문)
UPDATE 테이블_이름 SET 속성_이름 = 변경내용 (WHERE 조건); |
- SQL의 DML 명령어 중 UPDATE 명령문은 테이블의 자료(튜플) 중에서 값을 변경하고자 하는 경우에 사용되는 명령문이다.
4. 다음 릴레이션의 Cardinality와 Degree를 작성하시오.
이름
|
나이
|
A
|
B
|
김ㅇㅇ
|
23
|
1
|
5
|
박ㅇㅇ
|
25
|
2
|
3
|
고ㅇㅇ
|
42
|
3
|
8
|
최ㅇㅇ
|
20
|
2
|
9
|
이ㅇㅇ
|
25
|
1
|
2
|
Cardinality : 5
Degree : 4
- 카디널리티(Cardinality) : 릴레이션의 튜플의 갯수
- 차수(Degree) : 릴레이션의 속성의 개수
5. 다음은 프로토콜에 대한 내용이다. 알맞은 답을 작성하시오.
- Network layer에서 IP패킷을 암호화하고 인증하는 등의 보안을 위한 표준이다.
- 기업에서 사설 인터넷망으로 사용할 수 있는 VPN을 구현하는데 사용되는 프로토콜이다. - AH(Authentication Header)와 ESP(Encapsulating Security Payload)라는 두 가지 보안 프로토콜을 사용한다. |
IPsec
* IPsec(Internet Protocol Security)
- 통신 세션의 각 IP 패킷을 암호화하여 인증하는 안전한 인터넷 프로토콜 통신을 위한 3계층 보안 프로토콜이다.
- 기밀성, 비연결형 무결성, 데이터 원천 인증, 재전송 공격 방지, 접근 제어, 제한된 트래픽 흐름의 기밀성의 특징을 가지고 있다.
6. 다음은 Python에 대한 문제이다. 아래 코드를 읽고 알맞은 출력 값을 작성하시오.
def fnCalculation(x,y):
result = 0;
for i in range(len(x)):
temp = x[i:i+len(y)]
if temp == y:
result += 1;
return result
a = "abdcabcabca"
p1 = "ab";
p2 = "ca";
out = f"ab{fnCalculation(a,p1)}ca{fnCalculation(a,p2)}"
print(out)
ab3ca3
- 이 문제는 문자열 내에서 특정 패턴이 몇 번 등장하는지 세는 Python 함수에 관한 문제이다.
- fnCalculation 함수는 주어진 문자열 x에서 패턴 문자열 y가 몇 번 나타나는지를 세어 반환하는 역할을 한다. 이 함수는 for 반복문을 통해 부분 문자열을 하나씩 검사하여, y와 일치할 때마다 result 값을 증가시킨다.
- fnCalculation(a, p1)과 fnCalculation(a, p2)를 각각 호출하여 p1과 p2가 a에 몇 번 등장하는지 구한다.
- p1은 "ab"로 문자열 a에서 3번 나타나고, p2는 "ca"로 역시 3번 나타난다.
- 따라서 out에 f-string 형식을 사용하여 "ab3ca3"이 최종적으로 출력된다.
- 참고로 f"ab{fnCalculation(a,p1)}ca{fnCalculation(a,p2)}" 의 형태는 f-string이라고 해서 문자열 앞에 f를 넣고 각 출력할 변수를 {}로 중괄호 처리하는 방식이다.
- f-string의 기본 형식:
- f-string은 문자열 앞에 f 또는 F를 붙이고, 문자열 내부에서 {}로 감싼 부분에 변수를 넣어 해당 값이 문자열에 삽입되도록 하는 방식
- {} 내부에는 변수뿐 아니라 함수 호출, 표현식 등도 넣을 수 있어, 이를 계산한 결과가 문자열에 바로 적용된다.
- f-string의 기본 형식:
7. 아래 설명하는 내용을 확인하여 알맞은 알고리즘을 작성하시오.
- 대칭키 알고리즘으로 1997년 NIST(미국 국립기술표준원)에서 DES를 대체하기 위해 생성되었다.
- 128비트, 192비트 또는 256비트의 가변 키 크기와 128비트의 고정 블록 크기를 사용한다. - 높은 안전성과 효율성, 속도 등으로 인해 DES 대신 전 세계적으로 많이 사용되고 있다. |
AES
* 암호화 기법
대칭키 (비밀키) 기법 |
- 암호화, 복호화 할 때 사용하는 키가 동일한 경우 - 알고리즘 방식 : DES, 3-DES, AES, SEED, ARIA, MASK 등 |
비대칭키 (공개키) 기법 |
- 암호화 할 때 사용하는 키와 복호화 할 때 사용하는 키가 다른 경우 - 알고리즘 방식 : RSA, DSA 등 |
* 블록암호 알고리즘
알고리즘 | 블록 크기 | 키 길이 | 라운드 수 | 구조 | 대칭키/비대칭 |
DES | 64비트 | 56비트 | 16라운드 | Feistel 구조 | 대칭키 |
3-DES | 64비트 | 112/168비트 (2/3개의 키) |
암호화/복호화/암호화 (EDE 모드) |
Feistel 구조 | 대칭키 |
AES | 128비트 | 128/192/256비트 | 10/12/14라운드 | SPN 구조 | 대칭키 |
SKIPJACK | 64비트 | 80비트 | 32라운드 | Feistel 변형 구조 | 대칭키 |
IDEA | 64비트 | 128비트 | 8라운드 | Feistel + SPN 구조 | 대칭키 |
SEED | 128비트 | 128비트 | 16라운드 | Feistel 구조 (한국) | 대칭키 |
ARIA | 128비트 | 128/192/256비트 | 12/14/16라운드 | SPN 구조 (한국) | 대칭키 |
LEA | 128비트 | 128/192/256비트 | 24/28/32라운드 | SPN 구조 (한국, 경량) | 대칭키 |
CRYPTON | 128비트 | 0~256비트 | 12라운드 | SPN 구조 | 대칭키 |
* 스트림암호 알고리즘
- LFSR : 선형 피드백 시프트 레지스터
- RC4 : 인터넷 보안 프로토콜에서 널리 사용
- A5 : GSM 통신에서 사용
* 공개키암호 알고리즘
- 소인수 분해 : RSA, Rabin
- 이산대수 : Diffie-Hellman, DSA, ELGamal
- 타원곡선 : ECC
* 단방향암호 알고리즘
- MD5 : 빠른 계산 속도, 취약점 발견
- SHA : NIST(미국 국립표준기술연구소)에 의해 개발된 해시 함수
- HAS-160 : 한국에서 개발된 해시 함수, KCDSA(디지털서명)에 사용
8. 패킷 교환 방식 중 연결형과 비연결형에 해당하는 방식을 작성하시오.
연결형 : 가상회선
비연결형 : 데이터그램
* 패킷 교환 방식(Packet Switching)
- 메시지를 일정한 길이의 전송 단위인 패킷으로 나누어 전송하는 방식이다.
- 다수의 사용자 간에 비대칭적 데이터 전송을 원할하게 하므로 모든 사용자 간에 빠른 응답 시간 제공이 가능하다.
- 전송에 실패한 패킷의 경우 재전송이 가능하다.
- 패킷 단위로 헤더를 추가하므로 패킷별 오버헤드가 발생한다.
- 현재 컴퓨터 네트워크에서 주로 사용하는 방식이며, 패킷교환공중데이터통신망(PSDN)이라고도 한다.
- 패킷 교환 방식은 축적 후 전달(Store-and-Forward) 방식이다.
- 메시지를 작은 데이터 조각인 패킷으로 블록화한다.
- 종류 : 가상 회선 방식, 데이터그램 방식
가상회선 (Virtual Circuit) |
- 연결형 서비스 - 데이터를 패킷 단위로 나누어 전송 - 가상 연결 설정을 통해 전송되는 모든 패킷의 경로가 동일 - 패킷의 도착 순서가 일정(출발/도착 순서 동일) |
데이터그램 (Datagram) |
- 비연결형 서비스 - 패킷을 독립적으로 전송(서로 다른 경로, 경로를 미리 할당하지 않음) - 정보의 양이 적거나 상대적으로 신뢰성이 중요하지 않은 환경에서 사용 - 송신 호스트가 전송한 패킷은 보낸 순서와 무관한 순서로 수신(서로 다른 경로, 네트워크 혼잡도에 따라 가변적) |
9. 아래 내용을 확인하고 알맞은 답을 고르시오.
- 실행 순서가 밀접한 관계를 갖는 기능을 모아 모듈로 구성한다.
- 한 모듈 내부의 한 기능 요소에 의한 출력 자료가 다음 기능 원소의 입력 자료로서 제공되는 형태이다. |
ㄱ. 기능적(functional) ㄴ. 우연적(Coincidental) ㄷ. 통신적(Communication) ㄹ. 절차적(Procedural)
ㅁ. 시간적(Temporal) ㅂ. 순차적(sequential) ㅅ. 논리적(Logical) |
ㅂ. 순차적
* 응집도(Cohesion)
- 모듈 안의 요소들이 서로 기능적으로 관련되어 있는 정도
- 응집도가 강할수록 높은 품질의 모듈이다.
* 응집도 유형
기능적 (Functional) |
모듈 내부의 모든 기능 요소들이 한 문제와 연관되어 수행되는 경우 | 응집도 강함 |
순차적 (Sequential) |
한 모듈 내부의 한 기능요소에 의한 출력 자료가 다음 기능 요소의 입력 자료로 제공되는 경우 | |
통신(교환)적 (Communication) |
동일한 입력과 출력을 사용하는 소작업들이 모인경우 | |
절차적 (Procedural) |
모듈이 다수의 관련 기능을 가질 때 모듈 내부의 기능 요소들이 그 기능을 순차적으로 수행할 경우 | |
시간적 (Temporal) |
특정 시간에 처리되는 여러 기능을 모아 한 개의 모듈로 작성할 경우 | |
논리적 (Logical) |
유사한 성격을 갖거나 특정 형태로 분류되는 처리 요소들로 하나의 모듈이 형성되는 경우 | |
우연적 (Coincidental) |
모듈 내부의 각 기능 요소들이 서로 관련이 없는 요소로만 구성된 경우 | 응집도 약함 |
10. 아래는 디자인 패턴에 관한 설명이다. 아래 설명을 읽고 보기에서 알맞은 용어를 작성하시오.
- 컬렉션 객체의 내부 구조를 노출하지 않고 순차적으로 접근할 수 있게 하는 패턴이다.
- 이 패턴은 객체의 내부 표현 방식에 독립적으로 요소에 접근할 수 있도록 해준다 - 반복 프로세스를 캡슐화하여 클라이언트 코드에서는 컬렉션의 구체적인 구현에 종속되지 않도록 한다. |
생성패턴 | 구조패턴 | 행위패턴 |
Singleton | Adapter | Iterator |
Factory Method | Bridge | Visitor |
Abstract Factory | Composite | Observer |
Iterator
* 디자인 패턴(Design Pattern)
- 객체지향 프로그래밍 설계 시 유사한 상황에서 구조적인 문제를 해결할 수 있도록 방안을 제공
[생성 패턴]
- 객체를 생성하는 것과 관련된 패턴으로, 객체의 생성과 변경이 전체 시스템에 미치는 영향을 최소화하도록 만들어주어 유연성을 높일 수 있고 코드를 유지하기 쉬운 편이다.
- 객체의 생성과 참조 과정을 추상화함으로써 시스템을 개발할 때 부담을 덜어준다.
- 클래스나 객체의 생성과 참조과정을 정의하는 패턴
Factory Method |
- 객체를 생성하기 위한 인터페이스를 정의하며 어떤 클래스가 인스턴스화될 것인지는 서브 클래스가 결정하도록 함 - 객체를 생성하는 인터페이스와 실제 객체를 생성하는 클래스 분리 가능 - Virtual -Constructor(가상 생성자) 패턴이라도고 함 |
Singleton | - 전역 변수를 사용하지 않고 객체를 하나만 생성하도록 한다. - 생성된 객체를 어디에서든지 참조할 수 있도록 하는 패턴 |
Prototype | - 원본 객체를 복제하여 객체를 생성하는 패턴 - 일반적인 방법으로 객체를 생성하고 비용이 많이 소요되는 경우에 주로 사용 |
Builder | 작게 분리된 인스턴스를 조립하듯 조합하여 객체를 생성 |
Abstract Factory |
- 구체적인 클래스에 의존하지 않고 서로 연관되거나 의존적인 객체들의 조합을 만드는 인터페이스를 제공하는 패턴 - 관련된 서브 클래스를 그룹지어 한 번에 교체할 수 있음 |
[구조 패턴]
- 클래스나 객체를 조합해 더 큰 구조를 만드는 패턴
- 복잡한 형태의 구조를 갖는 시스템을 개발하기 쉽게 만들어주는 패턴
- 새로운 기능을 가진 복합 객체를 효과적으로 작성할 수 있다.
- ex) 서로 다른 인터페이스를 지닌 2개의 객체를 묶어 단일 인터페이스를 제공하거나 객체들을 서로 묶어 새로운 기능을 제공하는 패턴. 프로그램 내의 자료구조나 인터페이스 구조 등을 설계하는데 많이 활용
Composite | 여러 개로 객체로 구성된 복합 객체와 단일 객체를 클라이언트에서 구별없이 다루게 해주는 패턴 |
Adapter | 호환성이 없는 인터페이스 때문에 함께 사용할 수 없는 (기존)클래스를 개조하여 함께 작동할 수 있도록 해주는 패턴 |
Bridge | 기능 클래스 계층과 구현 클래스 계층을 연결하고, 구현부에서 추상 계층을 분리하여 각자 독립적으로 변형할 수 있도록 해주는 패턴 |
Decorator | 객체의 결합을 통해 기능을 동적으로 유연하게 확장할 수 있게 해주는 해턴 |
Facade | - '건물의 (앞쪽)정면' - Facade 인터페이스를 제공하여 facade 객체를 통해서만 모든 관계가 이루어질 수 있도록 인터페이스를 단순화 - 클래스 간 의존 관계가 줄어들고 복잡성이 낮아지는 효과 |
Flyweight | 인스턴스가 필요할 때마다 매번 생성하는 것이 아니고 가능한 한 공유해서 사용함으로써 메모리를 절약하는 패턴 |
Proxy | - '대리인'이라는 뜻으로, 뭔가를 대신해서 처리하는 것 - 접근이 어려운 객체와 여기에 연결하려는 객체 사이에서 인터페이스 역할을 수행하는 패턴 |
- 반복적으로 사용되는 객체들의 상호작용을 패턴화한 것으로, 클래스나 객체들이 상호작용하는 방법과 책임을 분산하는 방법을 정의한다.
- 메세지 교환과 관련된 것으로, 객체 간의 행위나 알고리즘 등과 관련된 패턴을 말한다.
Chain of Responsibility (책임 연쇄) |
- 요청을 처리할 수 있는 객체가 둘 이상 존재하여 한 객체가 처리하지 못하면 다음 객체로 넘어가는 형태의 패턴 - 요청을 처리할 수 있는 각 객체들이 고리(chain)로 묶여 있어 요청이 해결될 때까지 고리를 따라 책임이 넘어감 |
Iterator (반복자) |
- 자료 구조와 같이 접근이 잦은 객체에 대해 동일한 인터페이스를 사용하도록 하는 패턴 - 내부 표현 방법의 노출 없이 복합 객체의 원소를 순차적으로 접근할 수 있는 방법 제공 |
Command (명령) |
- 요청을 객체의 형태로 캡슐화하여 재이용하거나 취소할 수 있도록 요청에 필요한 정보를 저장하거나 로그에 남기는 패턴 - 요청에 사용되는 각종 명령어들을 추상 클래스와 구체 클래스로 분리하여 단순화함 |
Interpreter (해석자) |
- 언어의 문법 표현을 정의하는 패턴 - SQL 이나 통신 프로토콜과 같은 것을 개발할 때 문법 규칙을 클래스화한 구조 |
Memento (기록) |
- 특정 시점에서의 객체 내부 상태를 객체화함으로써 이후 요청에 따라 객체를 해당 시점의 상태로 돌릴 수 있는 기능을 제공하는 패턴 - Ctrl+Z와 같은 되돌리기 기능을 개발할 때 주로 이용 |
Observer (감시자) |
- 한 객체의 상태가 변하면 객체에 상속되어 있는 다른 객체들에게 변화된 상태를 전달하는 패턴 - 객체 사이에 일대다의 존속성을 정의 |
State (상태) |
- 객체의 내부 상태에 따라 동일한 동작을 다르게 처리해야 할 때 사용하는 패턴, 행위를 변경할 수 있게 함 - 이렇게 하면 객체는 마치 클래스를 바꾸는 것처럼 보인다. |
Strategy (전략) |
- 동일한 계열의 알고리즘들을 개별적으로 캡슐화하여 상호 교환할 수 있게 정의하는 패턴 - 클라이언트는 독립적으로 원하는 알고리즘을 선택하여 사용할 수 있으며, 클라이언트에 영향 없이 알고리즘의 변경이 가능함 - 즉, 클라이언트에게 알고리즘이 사용하는 데이터나 그 구조를 숨겨주는 역할을 한다. |
Visitor (방문자) |
- 각 클래스들의 데이터 구조에서 처리 기능을 분리하여 별도의 클래스로 구성하는 패턴 - 즉, 객체 구조의 요소들에 수행할 오퍼레이션을 표현한 패턴 - 분리된 처리 기능은 각 클래스를 방문(visit)하여 수행함 - 오퍼레이션이 처리할 요소의 클래스를 변경하지 않고도 새로운 오퍼레이션을 정의할 수 있게 함 |
Template Method |
- 상위 클래스에서 골격을 정의하고, 하위 클래스에서 세부 처리를 구체화하는 구조의 패턴 - 유사한 서브 클래스를 묶어 공통된 내용을 상위 클래스에서 정의함으로써 코드의 양 축소, 유지보수 용이 |
Mediator (중재자) |
- 수많은 객체들 간의 복잡한 상호작용(interface)을 캡슐화 하여 객체로 정의하는 패턴 - 객체 간의 통제와 지시의 역할을 하는 중재자를 두어 객체지향의 목표를 달성하게 해줌 - 객체 사이의 의존성을 줄여 결합도를 감소시킬 수 있음 |
[Study] 디자인 패턴(Design Pattern)
1. 디자인 패턴자주 사용하는 설계 형태를 정형화해서 이를 유형별로 설계 템플릿을 만들어둔 것으로, 소프트웨어 개발 중 나타나는 과제를 해결하기 위한 방법 중 한가지이다.다시 말헤, 모듈
juble00.tistory.com
11. 아래 그림을 바탕으로 RIP을 구성하여 최단 경로 비용을 계산하여 흐름에 맞게 작성하시오. (시작은 A, 끝은 F)

A → D → C → F
* RIP(Routing Information Protocol)
- 최단 경로 탐색에 Bellman-Ford 알고리즘을 사용하는 거리 벡터 라우팅 프로토콜이다.
- 최적의 경로를 산출하기 위한 정보로서 홉(거릿 값)만을 고려하므로, RIP를 선택한 경로가 최적의 경로가 아닌 경우가 많이 발생할 수 있다.
- 최대 홉 카운트를 15홉 이하로 한정한다.
- 소규모 네트워크 환경에 적합하다.
- 문제 설명
- 시작 지점(A)에서 끝 지점(F)까지 가는 최단 경로를 계산할 때, RIP의 특징에 따라 홉 수가 적은 경로를 선택해야 한다.
- 홉 수(hop count)는 두 노드를 연결하는 경유지의 수를 의미하며, RIP은 경로의 숫자가 아니라 노드 간 연결 갯수로 최적 경로를 판단한다.
- 답은 경유지 수가 가장 적은 경로인 A → D → C → F 이다.
- OSPF와의 차이점:
- OSPF(Open Shortest Path First)는 RIP과 다르게 홉 수가 아닌 경로의 상태(cost)를 고려하여 가장 낮은 비용의 경로를 선택한다. 따라서 홉 수가 적더라도 경로의 상태가 좋지 않다면 다른 경로를 선택할 수 있다.
12. 아래의 표를 확인하여 SRT 스케줄링의 평균 대기시간을 계산하여 작성하시오.
프로세스
|
도착 시간
|
서비스 시간
|
A
|
0
|
8
|
B
|
1
|
4
|
C
|
2
|
9
|
D
|
3
|
5
|
6.5
* SRT(Shortest Remaining Time) 스케줄링
- SRT 스케줄링은 SJF를 선점방식으로 운영하는 기법으로, 준비 큐에서 완료까지 남은 CPU 요구량이 짧은 것을 먼저 실행한다.
- 즉, 프로세스가 실행되는 중에 새로운 프로세스가 도착할 때, 남은 서비스 시간이 더 짧은 프로세스가 있으면 현재 실행 중인 프로세스가 중단되고 새로운 프로세스가 실행한다.
- 이 방식은 대기 시간을 최소화하는 데 도움은 준다.
- 스케줄링 과정
- 0초: A가 도착하여 실행 시작 (A의 남은 서비스 시간: 8).
- 1초: B가 도착하여 남은 서비스 시간이 더 짧으므로 A가 중단되고 B가 실행 (B의 남은 서비스 시간: 4).
- 5초: B가 종료. D가 도착했지만 A와 C보다 서비스 시간이 짧기 때문에 D가 실행된다 (D의 남은 서비스 시간: 5).
- 10초: D가 종료. 이제 A가 남은 시간이 7이므로 A가 실행된다 (A의 남은 서비스 시간: 7).
- 17초: A가 종료. C가 실행된다 (C의 남은 서비스 시간: 9).
- 26초: C가 종료.
- 대기 시간 계산
- A: (0~1초: 1초 실행 후 중단) 1초 실행 후 10초에 다시 시작, 총 대기 시간 = 10 - 1 = 9초.
- B: 0초 대기 (1초 도착 후 바로 실행) → 대기 시간 = 0초.
- C: 17초에 실행 (2초 도착) → 대기 시간 = 17 - 2 = 15초.
- D: 5초에 실행 (3초 도착) → 대기 시간 = 5 - 3 = 2초.
- 모든 대기 시간의 합
- 대기 시간 = A + B + C + D = 9 + 0 + 15 + 2 = 26초
- 평균 대기 시간 계산
- 평균 대기 시간 = 총 대기 시간 / 프로세스 수 = 26 / 4 = 6.5초
* 프로세스 스케줄링
- 프로세스의 생성 및 실행에 필요한 시스템의 자원을 해당 프로세스에 할당하는 작업을 말한다.
- 스케줄링의 기법은 비선점 기법과 선점 기법으로 구분할 수 있다.
* 비선점(Non-preemptive) 스케줄링
- 일단 CPU를 할당받으면 다른 프로세스가 CPU를 강제적으로 빼앗을 수 없는 방식
- 모든 프로세스에 대한 공정한 처리가 가능하다.
- 일괄 처리 시스템에 적합하다.
FCFS (First Come First Service) |
준비상태 큐에 도착한 순서대로 CPU를 할당하는 기법 - 평균 대기시간, 최대/최소 평균 반환시간 |
SJF (Shortest Job First) |
- 준비상태 큐에서 대기하는 프로세스들 중에서 실행 시간이 가장 짧은 프로세스에게 먼저 CPU를 할당하는 기법 - 평균 대기 시간을 최소화함 - 평균 실행시간, 평균 대기시간, 평균 반환시간 |
HRN (Highest Response-ratio Next) |
- 어떤 작업이 서비스 받을 시간과 그 작업이 서비스를 기다린 시간으로 결정되는 우선순위에 따라 CPU를 할당하는 기법 - 우선순위 계산식 = ( 대기시간 + 서비스시간 ) / 서비스시간 |
기한부 (Deadline) |
작업이 주어진 특별한 시간이나 만료시간 안에 완료되도록 하는 기법 |
우선순위 (Priority) |
- 준비상태 큐에서 대기하는 프로세스에게 부여된 우선순위가 가장 높은 프로세스에게 먼저 CPU를 할다하는기법 - 에이징(Aging) 기법 : 프로세스가 자원을 기다리고 있는 시간에 비례하여 우선순위를 부여함으로써 무기한 문제를 방지하는 기법 |
* 선점(Preemptive) 스케줄링
- 한 프로세스가 CPU를 할당받아 실행 중이라도 우선순위가 높은 다른 프로세스가 CPU를 강제적으로 빼앗을 수 있는 방식
- 긴급하고 높은 우선순위의 프로세스들이 빠르게 처리될 수 있다.
- 대화식 시분할 시스템에 적합하다.
SRT (Shortest Remaining Time) |
- 실행 중인 프로세스의 남은 시간과 준비상태 큐에 새로 도착한 프로세스의 실행 시간을 비교하여 실행 시간이 더 짧은 프로세스에게 CPU를 할당하는 기법 - 시분할 시스템에 유용함 - 평균 반환시간(최종 완료 시간 - 도착 시간) 그림그리기! |
RR (Round Robin) |
- 주어진 시간 할당량 안에 작업을 마치지 않으면 준비완료 리스트의 가장 뒤로 배치되는 기법 - 시간 할당량이 너무 커지면 FCFS와 비슷하고, 시간 할당량이 너무 작아지면 오버헤드가 커지게 됨 - 사용 순서, 평균 대기시간, 평균 반환시간(대기시간을 먼저 구한 후, 대기시간+실행시간/개수) |
다단계 큐 (MQ, Multi-level Queue) |
프로세스들을 우선순위에 따라 시스템 프로세스, 대화형 프로세스, 일괄처리 프로세스 등으로 상위, 중위, 하위 단계의 단계별 준비 큐를 배치하는 방법 |
다단계 피드백 큐 (MFQ, Multi-lever Feedback Queue) |
- 각 준비상태 큐마다 부여된 시간 할당량 안에 완료하지 못한 프로세스는 다음 단계의 준비상태 큐로 이동하는 기법 - 짧은 작업, 입/출력 위주의 작업 권에 우선권을 부여함 - 마지막 단계의 큐에서는 작업이 완료될 때까지 RR 방식을 취함 |
프로세스 스케줄링 계산식에 대한 특강은 흥달쌤 유투브를 참고하면 된다 !
https://youtu.be/3gyCZpqi6OM?si=1e5Fda-CHBFOb6sO
https://youtu.be/eLsf6qHZGzc?si=dqoBKU3a1Ouh6Mjo
https://youtu.be/AIbzzUXZN8k?si=66fsdAHfDdiPVh5g
https://youtu.be/z4wbl7hWIWU?si=LIKBYTyL61hwXHp0
13. 다음은 C언어에 대한 문제이다. 아래 코드를 확인하여 알맞은 값을 작성하시오.
#include <stdio.h>
int main() {
int arr[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int* parr[2] = {arr[1], arr[2]};
printf("%d", parr[1][1] + *(parr[1]+2) + **parr);
return 0;
}
21
- 이 문제는 C 언어에서 포인터와 배열을 활용하여 값을 계산하는 문제이다.
- 주어진 2차원 배열을 바탕으로 포인터 배열을 생성하고, 특정 포인터 연산을 통해 값을 계산한 후 결과를 출력한다.
- 2차원 배열 생성:
- arr 배열은 3x3 형태로 초기화된다.
- arr[0] = {1, 2, 3}, arr[1] = {4, 5, 6}, arr[2] = {7, 8, 9}
- 포인터 배열 생성:
- int* parr[2] = {arr[1], arr[2]};
- parr[0]는 arr[1]을 가리키고, parr[1]은 arr[2]를 가리킨다.
- parr[0]는 {4, 5, 6}, parr[1]는 {7, 8, 9}를 가리킨다.
- 값 계산:
- parr[1][1]는 arr[2][1] 즉, 8을 의미
- *(parr[1] + 2)는 parr[1][2]로서 arr[2][2] 즉, 9를 의미
- **parr는 *parr[0]로서 arr[1][0] 즉, 4를 의미
- 따라서 계산 결과는 8 + 9 + 4 = 21
14. 다음은 Java 언어에 대한 문제이다. 아래 코드를 확인하여 알맞은 값을 작성하시오.
class Main {
public static void main(String[] args) {
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
ODDNumber OE = new ODDNumber();
System.out.print(OE.sum(a, true) + ", " + OE.sum(a, false));
}
}
interface Number {
int sum(int[] a, boolean odd);
}
class ODDNumber implements Number {
public int sum(int[] a, boolean odd) {
int result = 0;
for(int i=0; i < a.length; i++){
if((odd && a[i] % 2 != 0) || (!odd && a[i] % 2 == 0))
result += a[i];
}
return result;
}
}
25, 20
- 이 문제는 Java 언어에서 인터페이스와 클래스, 그리고 조건문을 활용하여 배열 내의 홀수 및 짝수의 합을 계산하는 문제이다.
- 주어진 배열에서 홀수와 짝수를 구분하여 각각의 합계를 출력하는 프로그램이다.
- if((odd && a[i] % 2 != 0) || (!odd && a[i] % 2 == 0))
- odd가 true일 때는 홀수(a[i] % 2 != 0)를, false일 때는 짝수(a[i] % 2 == 0)를 검사하여 조건을 만족하는 경우에만 result에 값을 더한다.
- 홀수의 합 : 1 + 3 + 5 + 7 + 9 = 25
- 짝수의 합 : 2 + 4 + 6 + 8 + 10 = 20
- System.out.print(OE.sum(a, true) + ", " + OE.sum(a, false));
- 결과는 25, 20 이 된다.
15. 다음은 C언어에 대한 문제이다. 아래 코드를 확인하여 알맞은 출력값을 작성하시오.
#include <stdio.h>
#include <string.h>
void sumFn(char* d, char* s) {
int sum = 0;
while (*s) {
*d = *s;
d++;
s++;
}
*d = '\0';
}
int main() {
char* str1 = "first";
char str2[50] = "teststring";
int result=0;
sumFn(str2, str1);
for (int i = 0; str2[i] != '\0'; i++) {
result += i;
}
printf("%d", result);
return 0;
}
10
- 이 문제는 C언어에서 문자열 복사와 인덱스 계산을 다루는 코드이다.
- 주어진 문자열 str1의 내용을 str2에 복사하고, 복사된 문자열의 길이에 따라 인덱스의 합을 계산하여 출력하는 프로그램이다.
- 문자열 복사:
- sumFn 함수는 포인터 d에 s의 내용을 복사
- while (*s) 루프를 통해 s의 각 문자를 d에 복사하고, d의 끝에 null 문자(\0)를 추가하여 문자열의 끝을 표시
- 문자열 초기화:
- char* str1 = "first";는 문자열 리터럴을 포인터에 저장
- char str2[50] = "teststring";는 초기값을 가진 문자 배열을 선언
- 인덱스 합계 계산:
- for (int i = 0; str2[i] != '\0'; i++) 루프에서 str2의 인덱스를 순회하면서 인덱스 i를 result에 더한다.
- 인덱스의 합: 0 + 1 + 2 + 3 + 4 = 10.
16. 아래는 소프트웨어 설계에 대한 내용이다. 내용을 읽고 괄호안에 알맞은 답을 작성하시오.
- 어떤 모듈이 다른 모듈 내부의 논리적인 흐름을 제어하기 위해, 제어를 통신하거나 제어 요소를 전달하는 결합도이다.
- 한 모듈이 다른 모듈의 상세한 처리 절차를 알고 있어 이를 통제하는 경우나 처리 기능이 두 모듈에 분리되어 설계된 경우에 발생한다. |
( 제어 , Control ) Coupling
* 결합도(Coupling)
- 두 모듈 간의 상호 의존도
- 모듈 간의 결합도를 약하게 하면 모듈 독립성이 향상되어 시스템을 구현하고 유지보수 작업이 쉽다.
- 즉, 결합도가 낮을수록 높은 품질의 모듈이다.
* 결합도 유형
자료 (Data) |
- 모듈 간의 인터페이스가 자료 요소로만 구성된 경우 - 모듈 간의 인터페이스로 값이 전달되는 경우 |
결합도 약함 |
스탬프 (Stamp) |
- 두 모듈이 동일한 자료 구조를 조회하는 경우 - 모듈 간의 인터페이스로 배열이나 오브젝트, 스트럭처 등이 전달되는 경우 |
|
제어 (Control) |
- 어떤 모듈이 다른 모듈의 내부 논리 조작을 제어하기 위한 목적으로 제어신호를 이용하여 통신하는 경우 - 하위 모듈에서 상위 모듈로 제어신호가 이동하여 상위 모듈에게 처리 명령을 부여하는 권리 전도현상이 발생함 |
|
외부 (External) |
어떤 모듈에서 외부로 선언한 변수(데이터)를 다른 모듈에서 참조할 경우 | |
공통 (Common) |
여러 모듈이 공통 자료 영역을 사용하는 경우 | |
내용 (Content) |
한 모듈이 다른 모듈의 내부 기능 및 그 내부 자료를 조회하도록 설계되었을 경우 | 결합도 강함 |
17. 다음은 Java에 대한 문제이다. 아래 코드를 확인하여 알맞은 값을 작성하시오.
class Main {
public static void main(String[] args) {
String str = "abacabcd";
boolean[] seen = new boolean[256]; // ASCII 문자의 최대 갯수
System.out.print(calculFn(str, str.length()-1, seen));
}
// 재귀 함수를 이용한 문자열 뒤집기
public static String calculFn(String str, int index, boolean[] seen) {
if(index < 0) return "";
char c = str.charAt(index);
String result = calculFn(str, index-1, seen);
// 현재 문자가 이미 처리된 경우
if(!seen[c]) {
seen[c] = true;
return c + result;
}
// 현재 문자를 처리하고 재귀 호출
return result;
}
}
dcba
- 이 문제는 주어진 문자열을 역순으로 출력하되, 중복된 문자는 한 번만 포함하도록 하는 프로그램이다.
- 이 과정에서 재귀 함수를 사용하여 문자열을 처리하고, 각 문자의 등장 여부를 확인하기 위해 boolean 배열을 사용한다.
- boolean[] seen = new boolean[256];
- ASCII 문자에 대한 출현 여부를 기록하기 위한 배열
- 이 배열의 크기는 256으로, 모든 ASCII 문자를 커버할 수 있다.
- calculFn 함수는 문자열을 역순으로 처리
- 각 호출에서 현재 인덱스의 문자를 확인하고, 이전에 처리된 문자인지 여부를 seen 배열을 통해 확인
- 만약 현재 문자가 처음 등장한 것이라면 seen[c]를 true로 설정하고, 결과 문자열에 추가
char c = str.charAt(index); // 해당 인덱스에 있는 문자를 반환해서 c에 저장해라
if(!seen[c]) // 문자가 이전에 본 적이 없으면
seen[c] = true; // 문자를 본 것으로 처리하라
String result = calculFn(str, index-1, seen); // 재귀 함수를 호출하여 이전 문자를 처리하라
- 호출 과정
- 첫 번째 호출: calculFn("abacabcd", 7, seen)
- index = 7, char c = 'd'
- 아직 'd'는 등장한 적이 없으므로 seen['d'] = false
- seen['d'] = true로 바꾸고, 재귀적으로 calculFn("abacabcd", 6, seen) 호출
- 반환될 값: 'd' + 다음 결과
- 두 번째 호출: calculFn("abacabcd", 6, seen)
- index = 6, char c = 'c'
- 아직 'c'는 등장한 적이 없으므로 seen['c'] = false
- seen['c'] = true로 바꾸고, 재귀적으로 calculFn("abacabcd", 5, seen) 호출
- 반환될 값: 'c' + 다음 결과
- 세 번째 호출: calculFn("abacabcd", 5, seen)
- index = 5, char c = 'b'
- 아직 'b'는 등장한 적이 없으므로 seen['b'] = false
- seen['b'] = true로 바꾸고, 재귀적으로 calculFn("abacabcd", 4, seen) 호출
- 반환될 값: 'b' + 다음 결과
- 네 번째 호출: calculFn("abacabcd", 4, seen)
- index = 4, char c = 'a'
- 아직 'a'는 등장한 적이 없으므로 seen['a'] = false
- seen['a'] = true로 바꾸고, 재귀적으로 calculFn("abacabcd", 3, seen) 호출
- 반환될 값: 'a' + 다음 결과
- index = 4, char c = 'a'
- 다섯 번째 호출 이후 (calculFn("abacabcd", 3, seen)에서부터 재귀 반환):
- 이제 'c', 'a', 'b' 등은 이미 처리된 문자들이므로, 추가하지 않고 이전의 값만 반환합니다.
- 반환되는 값은 계속해서 마지막으로 추가된 문자 'a', 'b', 'c', 'd'에 해당합니다.
- 최종 반환 과정:
- 반환 값이 'a' + 'b' + 'c' + 'd'로 쌓이면서 최종적으로 dcba가 반환됩니다.
- 첫 번째 호출: calculFn("abacabcd", 7, seen)
18. 다음은 C언어에 대한 문제이다. 아래 코드를 확인하여 알맞은 출력 값을 작성하시오.
#include <stdio.h>
void swap(int a, int b) {
int t = a;
a = b;
b = t;
}
int main() {
int a = 11;
int b = 19;
swap(a, b);
switch(a) {
case 1:
b += 1;
case 11:
b += 2;
default:
b += 3;
break;
}
printf("%d", a-b);
}
-13
- 주어진 C 코드에서 변수 a와 b의 값을 swap하고, switch 문을 통해 b의 값을 조정한 뒤, 최종적으로 a와 b의 차이를 출력하는 프로그램이다.
- 이 과정에서 swap 함수는 매개변수로 받은 값들을 스왑하지만, 실제로 main 함수의 a와 b에는 영향을 미치지 않는다. 이러한 점을 이해하는 것이 중요하다 !
- 스위치 문
- switch(a)에서 a의 값이 11이므로, case 11:로 이동한다.
- b += 2가 실행되어 b의 값은 19 + 2 = 21이 된다.
- 이후 break가 없으므로, default:로 이동하여 b += 3가 실행된다. 이로 인해 b의 값은 21 + 3 = 24가 된다.
- break를 만나 스위치 문이 종료된다.
- 마지막으로 printf("%d", a - b);에서 a는 11, b는 24이므로, 출력값은 11 - 24 = -13이 된다.
19. 다음은 C언어의 구조체에 대한 문제이다. 아래 코드를 확인하여 알맞은 출력 값을 작성하시오.
#include <stdio.h>
struct node {
int n1;
struct node *n2;
};
int main() {
struct node a = {10, NULL};
struct node b = {20, NULL};
struct node c = {30, NULL};
struct node *head = &a;
a.n2 = &b;
b.n2 = &c;
printf("%d\n", head->n2->n1);
return 0;
}
20
- 주어진 C 코드에서는 구조체를 사용하여 연결 리스트의 형태를 만들고, 이를 통해 특정 값을 출력하는 프로그램이다.
- 구조체 node는 정수형 멤버 n1과 다음 노드를 가리키는 포인터 n2를 포함하고 있다.
- 프로그램은 세 개의 노드를 생성하고, 이들을 서로 연결한 뒤, 연결된 노드의 특정 값을 출력한다.
- 노드 연결
- head 포인터는 a 노드를 가리킨다.
- a.n2는 b를 가리키고, b.n2는 c를 가리킨다. 이렇게 해서 a → b → c 형태의 연결 리스트가 형성된다.
- printf("%d\n", head->n2->n1);
- head가 가리키는 노드인 a의 n2 포인터를 통해 b를 참조하고, b의 n1 값을 출력한다.
- head->n2는 a.n2를 의미하며, 이는 b를 가리킨다. 따라서 head->n2->n1은 b.n1, 즉 20이 된다.
20. 다음은 Java에 대한 문제이다. 아래 코드를 확인하여 알맞은 값을 작성하시오.
class Main {
public static void main(String[] args) {
String str = "ITISTESTSTRING";
String[] result = str.split("T");
System.out.print(result[3]);
}
}
S
- 문자열을 특정 구분자를 기준으로 나누고, 나눈 문자열 중 하나를 출력하는 프로그램이다.
- 이 문제는 문자열 처리의 기본 개념인 split() 메서드를 활용하여 배열로 변환한 후, 배열에서 특정 인덱스의 값을 참조하는 방식으로 이루어져있다.
- split("T");
- 문자열을 'T'를 기준으로 나눈다.
- ['I', 'IS', 'ES', 'S', 'RING']
- System.out.print(result[3]);
- 배열의 3번째 요소를 출력한다. 배열 인덱스는 0부터 시작하므로, result[3]는 "S"를 의미한다.
'정보처리기사' 카테고리의 다른 글
[정보처리기사 요약정리] PART 2. 소프트웨어 개발 + 기출포함 (11) | 2024.10.19 |
---|---|
[정보처리기사 요약정리] PART 1. 소프트웨어 설계 + 기출포함 (12) | 2024.10.18 |
[정보처리기사 실기 기출] 2024년 1회 (6) | 2024.10.17 |
[정보처리기사 실기 기출] 2023년 3회 (15) | 2024.10.16 |
[정보처리기사 실기 기출] 2023년 2회 (4) | 2024.10.16 |