곧 2025년도 1회 시험이 다가오는 기념으로.. 저번에 봤던 시험을 복습 겸 정리해보려고 한다 !
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
1. 배열 초기화
- s[0] = "A" → String 리터럴 "A" 저장 (스트링 풀)
- s[1] = "A" → 기존 "A" 리터럴 재사용 (같은 주소)
- s[2] = new String("A") → Heap에 새로운 "A" 객체 생성 (다른 주소)
2. func(s, 3) 실행
- s[0].equals(s[1]) → "A".equals("A") → true → "O" 출력
- s[1].equals(s[2]) → "A".equals(new String("A")) → true → "O" 출력
- equals()는 문자열 내용이 같으면 true를 반환
- 하지만 == 비교 시 s[0] == s[1]은 true, s[1] == s[2]는 false이다.
3. 배열 출력
for (String m : s) {
System.out.print(m);
}
- "A", "A", "A" 순서대로 출력 → "AAA" 출력
2. 다음은 파이썬에 대한 문제이다. 아래 코드를 확인하여 알맞은 출력값을 작성하시오.
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. 첫 번째 반복, i = 0;
lst[0], lst[-1] = lst[-1], lst[0] # lst[0] ↔ lst[5]
- lst = [6, 2, 3, 4, 5, 1]
2. 두 번째 반복, i = 1;
lst[1], lst[-2] = lst[-2], lst[1] # lst[1] ↔ lst[4]
- lst = [6, 5, 3, 4, 2, 1]
3. 세 번째 반복, i = 2;
lst[2], lst[-3] = lst[-3], lst[2] # lst[2] ↔ lst[3]
- lst = [6, 5, 4, 3, 2, 1]
- 리스트의 길이가 **6(짝수)**이므로 i는 0, 1, 2까지 총 3번 실행되며, 리스트가 완전히 뒤집힌다.
4. sum(lst[::2]) - sum(lst[1::2]) 계산
- lst[::2] = [ 6, 4, 2 ] → 합 : 6 + 4 + 2 = 12
- lst[1::2] = [ 5, 3, 1 ] → 합 : 5 + 3 + 1 = 9
- 12 - 9 = 3
3. 아래의 employee 테이블과 project 테이블을 참고하여 보기의 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
)
);
1
* 조인(JOIN)
- 둘 이상의 테이블로부터 특정 공통된 값을 갖는 행을 연결하거나 조합하여 검색하는 것
- 동등 조인(Equi Join)에서의 JOIN~ON
- 동등 조인은 조인 대상 테이블에서 공통 속성을 '='(equal) 비교를 통해 같은 값을 가지는 행을 연결한다.
- 임의의 조건을 지정하거나 조인할 컬럼을 지정하려면 ON절을 사용한다.
- 두 테이블을 JOIN 연산한 뒤 자료를 검색하는 형태의 질의문을 말한다.
- 형식 : [테이블1] JOIN [테이블2] ON [조인조건]
- 교차 조인 (Cross Join)
- 교차조인은 '카티션 곱'이라고도 하며, 참조되는 두 테이블의 각 행의 수를 모두 곱한 결과의 행 수로 테이블이 반환된다. 대개 테스트로 사용할 대용량의 테이블을 생성할 경우에 사용된다.
- 반환되는 결과 테이블은 두 테이블의 디그리의 합과 카디널리티의 곱의 크기이다.
- 형식 : SELECT 속성리스트 FROM 테이블1 CROSS JOIN 테이블2 WHERE 조건식;
세타 조인 (Theta Join) |
- 조인에 참여하는 두 릴레이션의 속성 값을 비교하여 조건을 만족하는 튜플만 반환한다. - 비교 연산자로 =, >, <, >=, <=, <> 등이 사용될 수 있다. - 일반적으로 모든 조건 기반 조인을 세타 조인이라고 부르며, 동등 조인과 자연 조인 또한 세타 조인의 특수한 경우로 볼 수 있으며, 두 테이블 간의 특정 관계를 규명할 때 사용된다. |
동등 조인 (Equi Join) |
- 조건이 정확하게 '=' 등호로 일치하는 결과를 반환한다. - 조인 대상이 되는 두 테이블에서 공통적으로 존재하는 컬럼의 값이 일치되는 공통 행을 연결하여 결과를 생성하는 조인 방법 - 동등 조인은 WHERE절에 조인 조건으로 '=' 비교 연산자를 사용한다. |
자연 조인 (Natural Join) |
- 동등 조인에서 조인에 참여한 속성이 두 번 나오지 않도록 중복된 속성을 제거한 결과를 반환한다. - 테이블 간의 모든 컬럼을 대상으로 공통 컬럼을 자동으로 조사하여 같은 컬럼명을 가진 값이 일치할 경우 조인 조건을 수행한다. |
* SELECT(검색문)
SELECT (DISTINCT) 속성_이름 FROM 테이블_이름 (WHERE 조건) (GROUP BY 속성_이름 (HAVING 그룹조건)) (ORDER BY 속성_이름 (ASC/DESC)) |
- DISTINCT : 검색 결과에 중복되는 값이 있는 경우 한 번만 표현하도록 하는 옵션이며, 생략 시 중복된 값이 모두 표시된다.
- HAVING 그룹조건 : GROUP BY에 의해 그룹으로 분류를 한 후 조건을 제시할 때 사용된다.
- ASC : 오름차순(작은 값에서 큰 값)으로 정렬할 때 사용되는 옵션이다. 기본 옵션이다.
- DESC : 내림차순(큰 값에서 작은 값)으로 정렬할 때 사용되는 옵션이다.
4. 다음 운영체제 페이지 순서를 참고하여 할당된 프레임의 수가 3개일 때 LRU 알고리즘의 페이지 부재 횟수를 작성하시오.
페이지 참조 순서 : 7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1
|
12
* 페이지 교체 알고리즘
- 프로세스 실행 시 페이지 부재(Page Fault) 발생 시 가상기억장치의 페이지를 주기억장치에 적재해야 하는데, 이때 주기억장치의 모든 페이지 프레임이 사용 중이면 어떤 페이지 프레임을 교체할 지 결정하는 기법이다.
- 교체 알고리즘의 종류
OPT (OTPimal page relpacement) |
- 이후에 가장 오랫동안 사용되지 않을 페이지를 먼저 교체하는 기법 - 실현 가능성이 희박함 |
FIFO (First In First Out) |
- 가장 먼저 적재된 페이지를 먼저 교체하는 기법 - 벨레이디의 모순(Belady's Anomaly) 현상이 발생함 |
LRU (Least Recently Used) |
가장 오랫동안 사용되지 않았던 페이지를 먼저 교체하는 기법 |
LFU (Least Requently Used) |
참조된 횟수가 가장 적은 페이지를 먼저 교체하는 기법 |
NUR (Not Used Recently) |
- 최근에 사용하지 않은 페이지를 먼저 교체하는 기법 - 매 페이지마다 두 개의 하드웨어 비트(참조 비트, 변형 비트)가 필요함 |
SCR (Second Chance Replacement) |
각 페이지에 프레임을 FIFO 순으로 유지하면서 LRU 근사 알고리즘처럼 참조 비트를 갖게 하는 기법 |
* 페이지 부재(Page Fault)
- 참고할 페이지가 주기억장치에 없는 현상이다.
- 페이지 부재율(Page Fault Rate)에 따라 주기억장치에 있는 페이지 프레임의 수를 늘리거나 줄여 페이지 부재율을 적정 수준으로 유지하는 것이 바람직하다.
* LRU (Least Recently Used) 알고리즘
- LRU는 가장 오랫동안 사용되지 않은 페이지를 교체하는 방식
- 각 페이지가 참조될 때, 페이지가 가장 최근에 참조된 순서를 기준으로 교체 대상이 결정
- 따라서 크기 3의 리스트에서 새 요소가 앞에 추가되며, 기존 요소는 밀려나고 가장 오래된 것이 제거되는 방식
- LRU 알고리즘 수행 과정
단계 | 참조 페이지 | 프레임 상태 | 페이지 부재 여부(누적 횟수) | 교체된 페이지 |
1 | 7 | [7] | O(1) | |
2 | 0 | [0, 7] | O(2) | |
3 | 1 | [1, 0, 7] | O(3) | |
4 | 2 | [2, 1, 0] | O(4) | 7 |
5 | 0 | [0, 2, 1] | ||
6 | 3 | [3, 0, 2] | O(5) | 1 |
7 | 0 | [0, 3, 2] | ||
8 | 4 | [4, 0, 3] | O(6) | 2 |
9 | 2 | [2, 4, 0] | O(7) | |
10 | 3 | [3, 2, 4] | O(8) | 0 |
11 | 0 | [0, 3, 2] | O(9) | 4 |
12 | 3 | [3, 0, 2] | ||
13 | 2 | [2, 3, 0] | ||
14 | 1 | [1, 2, 3] | O(10) | 0 |
15 | 2 | [2, 1, 3] | ||
16 | 0 | [0, 2, 1] | O(11) | 3 |
17 | 1 | [1, 0, 2] | ||
18 | 7 | [7, 1, 0] | O(12) | 2 |
19 | 0 | [0, 7, 1] | ||
20 | 1 | [1, 0, 7] |
- 총 페이지 부재 횟수 (LRU): 12회
5. 다음은 네트워크 취약점에 대한 문제이다. 아래 내용을 보고 알맞은 용어를 작성하시오.
- IP나 ICMP의 특성을 악용하여 엄청난 양의 데이터를 한 사이트에 집중적으로 보냄으로써 네트워크의 일부를 불능 상태로 만드는 공격이다.
- 여러 호스트가 특정 대상에게 다량의 ICMP Echo Reply를 보내게 하여 서비스거부(DoS)를 유발시키는 보안공격이다. - 공격 대상 호스트는 다량으로 유입되는 패킷으로 인해 서비스 불능 상태에 빠진다. |
스머핑(Smurfing)
* 스머프(Smurf)
- 공격 대상의 IP 주소를 근원지로 대량의 ICMP 응답 패킷을 전송하여, 서비스 거부를 유발하는 공격 방법이다.
- IP 또는 ICMP의 특성을 악용하여 특정 사이트에 집중적으로 데이터를 보내 네트워크 또는 시스템의 상태를 불능으로 만드는 공격 방법이다.
6. 다음은 GoF 디자인 패턴과 관련된 문제이다. 괄호 안에 알맞은 용어를 작성하시오.
- ( ) 패턴은 클래스나 객체들이 서로 상호작용하는 방법이나 책임 분배 방법을 정의하는 패턴이다.
- ( ) 패턴은 객체들 간의 통신 방법을 정의하고 알고리즘을 캡슐화하여 객체 간의 결합도를 낮춘다. - ( ) 패턴은 Chain of Responsibility나 Command 또는 Observer 패턴이 있다. |
행위
* GoF(Gang of Four) 디자인 패턴
- 에릭 감마(Eric Gamma), 리처드 헬름(Richard Helm), 랄프 존슨(Ralph Johnson), 존 브리시데스(John Vlissides)가 제안
- 객체지향 설계 단계 중 재사용에 관한 유용한 설계를 디자인 패턴화하였다.
- 생성패턴, 구조패턴, 행위패턴으로 분류
(1) 생성 패턴
- 객체를 생성하는 것과 관련된 패턴
- 객체의 생성과 변경이 전체 시스템에 미치는 영향을 최소화하도록 만들어주어 유연성을 높일 수 있고 코드를 유지하기 쉬운 편
(2) 구조 패턴
- 클래스나 객체를 조합해 더 큰 구조를 만드는 패턴
- 복잡한 형태의 구조를 갖는 시스템을 개발하기 쉽게 만들어주는 패턴
- 새로운 기능을 가진 복합 객체를 효과적으로 작성할 수 있음
(3) 행위 패턴
- 반복적으로 사용되는 객체들의 상호작용을 패턴화한 것
- 클래스나 객체들이 상호작용하는 방법과 책임을 분산하는 방법을 정의
- 메시지 교환과 관련된 것으로, 객체 간의 행위나 알고리즘 등과 관련된 패턴
Chain of Responsibility (책임 연쇄) |
- 요청을 처리할 수 있는 객체가 둘 이상 존재하여 한 객체가 처리하지 못하면 다음 객체로 넘어가는 형태의 패턴 - 요청을 처리할 수 있는 각 객체들이 고리(chain)로 묶여 있어 요청이 해결될 때까지 고리를 따라 책임이 넘어감 |
Iterator (반복자) |
- 자료 구조와 같이 접근이 잦은 객체에 대해 동일한 인터페이스를 사용하도록 하는 패턴 - 내부 표현 방법의 노출 없이 복합 객체의 원소를 순차적으로 접근할 수 있는 방법 제공 |
Command (명령) |
- 요청을 객체의 형태로 캡슐화하여 재이용하거나 취소할 수 있도록 요청에 필요한 정보를 저장하거나 로그에 남기는 패턴 - 요청에 사용되는 각종 명령어들을 추상 클래스와 구체 클래스로 분리하여 단순화함 |
Interpreter (해석자) |
- 언어의 문법 표현을 정의하는 패턴 - SQL 이나 통신 프로토콜과 같은 것을 개발할 때 문법 규칙을 클래스화한 구조 |
Memento (기록) |
- 특정 시점에서의 객체 내부 상태를 객체화함으로써 이후 요청에 따라 객체를 해당 시점의 상태로 돌릴 수 있는 기능을 제공하는 패턴 - Ctrl+Z와 같은 되돌리기 기능을 개발할 때 주로 이용 |
Observer (감시자) |
- 한 객체의 상태가 변하면 객체에 상속되어 있는 다른 객체들에게 변화된 상태를 전달하는 패턴 - 객체 사이에 일대다의 존속성을 정의 |
State (상태) |
- 객체의 내부 상태에 따라 동일한 동작을 다르게 처리해야 할 때 사용하는 패턴, 행위를 변경할 수 있게 함 - 이렇게 하면 객체는 마치 클래스를 바꾸는 것처럼 보인다. |
Strategy (전략) |
- 동일한 계열의 알고리즘들을 개별적으로 캡슐화하여 상호 교환할 수 있게 정의하는 패턴 - 클라이언트는 독립적으로 원하는 알고리즘을 선택하여 사용할 수 있으며, 클라이언트에 영향 없이 알고리즘의 변경이 가능함 - 즉, 클라이언트에게 알고리즘이 사용하는 데이터나 그 구조를 숨겨주는 역할을 한다. |
Visitor (방문자) |
- 각 클래스들의 데이터 구조에서 처리 기능을 분리하여 별도의 클래스로 구성하는 패턴 - 즉, 객체 구조의 요소들에 수행할 오퍼레이션을 표현한 패턴 - 분리된 처리 기능은 각 클래스를 방문(visit)하여 수행함 - 오퍼레이션이 처리할 요소의 클래스를 변경하지 않고도 새로운 오퍼레이션을 정의할 수 있게 함 |
Template Method |
- 상위 클래스에서 골격을 정의하고, 하위 클래스에서 세부 처리를 구체화하는 구조의 패턴 - 유사한 서브 클래스를 묶어 공통된 내용을 상위 클래스에서 정의함으로써 코드의 양 축소, 유지보수 용이 |
Mediator (중재자) |
- 수많은 객체들 간의 복잡한 상호작용(interface)을 캡슐화 하여 객체로 정의하는 패턴 - 객체 간의 통제와 지시의 역할을 하는 중재자를 두어 객체지향의 목표를 달성하게 해줌 - 객체 사이의 의존성을 줄여 결합도를 감소시킬 수 있음 |
7. 다음은 C언어에 대한 문제이다. 아래 코드를 확인하여 알맞은 출력 값을 작성하시오.
#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
* static 변수의 특징
- 정적 저장 기간을 가짐: 프로그램 시작부터 종료까지 메모리에 유지됨.
- 함수 내에서 선언되어도 값이 유지됨: 호출될 때마다 다시 초기화되지 않음.
- 일반적인 지역 변수와 차이점:
- static이 없으면 매 호출마다 x = 0으로 초기화되었을 것.
- 하지만 static이므로 값이 유지되어 2 → 4 → 6 → 8로 증가.
- 따라서 2 + 4 + 6 + 8 = 20
8. 다음은 무결성제약조건에 대한 문제이다. 아래 표에서 어떠한 ( ) 무결성을 위반하였는지 작성하시오.
StudentID | Name | Age | Major |
101 | Alice | 20 | Computer Science |
102 | Bob | 21 | Mathmatics |
101 | David | 23 | Chemistry |
NULL | Eve | 22 | Biology |
개체
* 무결성(Intergrity) 제약조건
- 개체 무결성 제약조건
- 기본키는 NULL 값을 가져서는 안되며, 릴레이션 내에 오직 하나의 값만 존재해야 한다는 제약조건
- 참조 무결성 제약조건
- 릴레이션은 참조할 수 없는 외래키 값을 가질 수 없음을 의미하는 제약 조건
- 도메인 무결성 제약조건
- 릴레이션 내의 튜플들이 각 속성의 도메인에 정해진 값만을 가져야 한다는 제약 조건
9. 다음은 URL 구조에 관한 문제이다. 아래 보기의 순서대로 URL에 해당하는 번호를 작성하시오.
- query : 서버에 전달할 추가 데이터
- path : 서버 내의 특정 자원을 가리키는 경로 - scheme : 리소스에 접근하는 방법이나 프로토콜 - authority: 사용자 정보, 호스트명, 포트 번호 - fragment: 특정 문서 내의 위치 |
4 3 1 2 5
* URL(Uniform Resource Locators)
Uniform : 리소스를 식별하는 통일된 방식
Resource : 자원, URI로 식별할 수 있는 모든 것
Locator: 리소스가 있는 위치를 지정
- 웹에서 HTML 페이지, CSS 문서, 이미지 등 리소스의 위치를 나타내는 주소를 뜻한다.
- 쉽게 말해서, URL은 웹 페이지를 찾기위한 주소를 말한다.
- 흔히 웹 사이트 주소로 알고 있지만, URL은 웹 사이트 주소뿐만 아니라 컴퓨터 네트워크상의 자원을 모두 나타낼 수 있다.
- 그 주소에 접속하려면 해당 URL에 맞는 프로토콜을 알아야 하고, 그와 동일한 프로토콜로 접속해야 한다.
* Scheme(=Protocol)
scheme://[userinfo@]host[:port][/path][?query][#fragment]
https://www.google.com:443/search?q=hello&hl=ko
- 브라우저가 리소스를 요청하기 위해 사용해야 하는 프로토콜을 나타낸다.
- 프로토콜은 중앙 컴퓨터와 단말기 사이에서 데이터 통신을 원활하게 하기 위해 필요한 통신 규약으로, 웹에서는 브라우저와 서버 간에 데이터를 주고 받기 위한 방식으로 HTTPS/HTTP 프로토콜이 가장 많이 사용되고 있다.
- HTTP(Hyper Text Transfer Protocol): 웹 브라우저와 웹 서버가 서로 데이터를 주고받기 위해 만든 통신규약
- HTTPS(Hyper Text Transter Protocol Secure): HTTP에서 보안이 강화된 버전
* Host
scheme://[userinfo@]host[:port][/path][?query][#fragment]
https://www.google.com:443/search?q=hello&hl=ko
- 도메인명 또는 IP 주소를 직접 사용 가능하다.
- 도메인(Domain)은 IP 주소를 갖는 서버를 사용자가 쉽게 기억하고 찾을 수 있도록 만들어준 서비스이다.
* Port
scheme://[userinfo@]host[:port][/path][?query][#fragment]
https://www.google.com:443/search?q=hello&hl=ko
- 포트 번호를 통해 어떤 서버를 이용할지 결정하며, : (콜론) 뒤에 나온다.
- 웹 서버가 HTTP 프로토콜의 표준 포트(HTTP의 경우 80, HTTPS의 경우 443)를 사용하는 경우 일반적으로 생략되기 때문에, URL에는 기본적으로 표준 포트번호가 생략되어 있는 것이다.
* Path
scheme://[userinfo@]host[:port][/path][?query][#fragment]
https://www.google.com:443/members/101?q=hello&hl=ko
- 리소스 경로(path)로, 계층적 구조로 표현한다.
* query
scheme://[userinfo@]host[:port][/path][?query][#fragment]
https://www.google.com:443/search?q=hello&hl=ko
- key=value 형태로, ? 로 시작하고 & 로 추가 가능하다.
- query parameter, query String 등으로 불리며 웹서버에 제공하는 파라미터로 문자형태이다.
* fragment
scheme://[userinfo@]host[:port][/path][?query][#fragment]
https://www.google.com:443/search?q=hello&hl=ko#page-1
- html 내부 북마크 등에 사용되며 서버에 전송되는 정보는 아니다.
- 특정 요소를 지시할 수 있다.
- 예를 들어, 해시태그로 이동을 원하는 요소의 id를 링크로 연결하면 스크롤 이동없이 바로 해당 위치로 이동한다.
- 파일 디렉토리 및 파일 이름과 유사한 역할로 쓰이는 경우도 있다.
10. 다음은 파이썬에 대한 문제이다. 아래 코드를 확인하여 알맞은 출력 값을 작성하시오.
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(a) 실행 (a = '100.0')
- a는 문자열(str).
- type(a) == type("") 조건이 참.
- return len(a) → len('100.0') = 5.
- func(a) = 5
- func(b) 실행 (b = 100.0)
- b는 float 타입 (100.0).
- type(100.0) == type(100) 조건은 거짓 (float != int).
- elif type(100.0) == type("") 조건도 거짓.
- 따라서 else 실행 → return 20.
- func(b) = 20
- func(c) 실행 (c = (100, 200))
- c는 tuple 타입.
- if와 elif 조건 모두 거짓.
- 따라서 else 실행 → return 20.
- func(c) = 20
- func(a) + func(b) + func(c) = 5 + 20 + 20 = 45
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();
Derivate b = new Derivate();
- a는 Base 타입이지만, 실제 객체는 Derivate의 인스턴스.
- b는 Derivate 타입으로 선언됨.
* 각 표현식의 값 계산
System.out.print(a.getX() + a.x + b.getX() + b.x);
표현식 | 실행 결과 |
a.getX() | 7 * 3 = 21 (실제 객체가 Derivate이므로 Derivate의 getX() 실행) |
a.x | 3 (a는 Base 타입이라 Base의 x를 참조) |
b.getX() | 7 * 3 = 21 (b는 Derivate 타입이므로 Derivate의 getX() 실행) |
b.x | 7 (b는 Derivate 타입이므로 Derivate의 x 참조) |
- 21 + 3 + 21 + 7 = 52
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
- 연결 리스트의 노드 값을 특정 방식으로 변경하는 함수 func()를 실행한 후, 변경된 리스트를 출력하는 프로그램
Node | value (초기) | value (함수 실행 후) | next |
n1 | 1 | 3 | &n3 |
n3 | 3 | 1 | &n2 |
n2 | 2 | 2 | NULL |
- 연결 리스트가 n1(1) → n3(3) → n2(2) → NULL 형태로 초기화됨.
- func()가 실행되어 짝수 번째 노드와 값이 교환됨.
- n1과 n3의 값이 변경됨. (1 ↔ 3)
- n2는 변경되지 않음.
- 변경된 리스트는 n1(3) → n3(1) → n2(2) → NULL이 됨.
- 리스트를 출력하면 "312"가 출력됨.
- 결론적으로, 이 코드는 연결 리스트에서 두 칸씩 건너뛰며 인접한 노드의 값을 서로 바꾸는 기능을 수행한다.
13. 다음은 테스트 커버리지에 대한 문제이다. 아래 내용에 알맞은 답을 보기에서 골라 작성하시오.
1. 테스트를 통해 프로그램의 모든 문장을 최소한 한 번씩 실행했는지를 측정
2. 프로그램 내의 모든 분기(조건문)의 각 분기를 최소한 한 번씩 실행했는지를 측정 3. 복합 조건 내의 각 개별 조건이 참과 거짓으로 평가되는 경우를 모두 테스트했는지를 측정 |
ㄱ. 조건 ㄴ. 경로 ㄷ. 결정 ㄹ. 분기 ㅁ.함수 ㅂ. 문장 ㅅ. 루프
|
① ㅂ. 문장, ② ㄹ. 분기, ③ ㄱ. 조건
* 코드 커버리지(Code Coverage)
- 프로그램의 소스코드의 테스트 수행 정도를 표시한다.
구문 커버리지 문장 커버리지 (Statement Coverage) |
- 코드 구조 내의 모든 구문에 대해 한 번 이상 수행하는 테스트 커버리지 - 예를 들어 반복문에서 10회 반복 테스트를 수행해야 100% 테스트가 완료된다고 가정할 때 5회만 반복한 경우 구문 커버리지는 50%이다. |
조건 커버리지 (Condition Coverage) |
결정 포인트 내의 모든 개별 조건식에 대해 수행하는 테스트 커버리지 |
결정 커버리지 분기 커버리지 (Decision Coverage) |
- 결정포인트 내의 모든 분기문에 대해 수행하는 테스트 커버리지 - 예를 들어 10개의 분기문 중에서 4개의 분기만 테스트가 완료되었다고 가정하면 결정 커버리지는 40%이다. - 분기 커버리지(Branch Coverage)라고도 한다. |
조건/결정 커버리지 (Condition/Decision Coverage) |
- 결정 포인트 T/F, 개별 조건식 T/F - 즉, 코드 내의 결정 포인트에서 발생하는 모든 조건식의 결과(true/false)와 전체 결정식의 결과(true/false)를 모두 고려하여 측정 |
변경 조건/결정 커버리지 (Modified Condition/ Decision Coverage) |
- 조건과 결정을 복합적으로 고려한 측정 방법 - 결정 포인트 내의 다른 개별적인 조건식 결과에 상관없이 전체 조건식의 결과에 영향을 주는 테스트 커버리지 - 모든 결정포인트 내의 개별 조건식은 적어도 한 번 T/F |
다중 조건 커버리지 (Multiple Condition Coverage) |
- 모든 개별 조건식의 true, false 조합 중 테스트에 의해 실행된 조합을 측정 - 100% 달성하기 위해서는 모든 개별 조건식 조합을 실행해야 하므로 다른 커버리지에 비해 상대적으로 많은 테스트 케이스가 필요하다. |
경로 커버리지 (Path Coverage) |
- 모든 가능한 실행 경로를 고려하여 테스트를 수행하는 테스트 커버리지 - 각 조건문, 반복문 및 분기점에서의 모든 조합을 포함한 경로를 검사하여 코드의 논리적 오류를 찾아내는 데 중점을 둔다. |
14. 아래는 UML 클래스의 관계에 관한 문제이다. 보기를 보고 알맞은 관계를 선택하여 작성하시오.
ㄱ. 의존 ㄴ. 연관 ㄷ. 일반화
|
① 연관, ② 일반화, ③ 의존
(3) 클래스 다이어그램(Class Diagram)
- 시스템을 구성하는 객체 간의 관계를 추상화한 모델을 논리적 구조로 표현한다.
- 객체지향 개발에서 공통으로 사용된다.
- 분석, 설계, 구현 단계 전반에 지속해서 사용된다.
- 클래스 다이어그램의 관계 표현
연관 관계 | ―――――――→ ―――――――― |
- 클래스 연결 상태 표시(개념상 서로 연결) - 한 클래스가 다른 클래스에서 제공하는 기능을 사용할 때 |
의존 관계 | - - - - - - - - - - - -> | 연관 관계와 동일하지만 메소드를 사용할 때와 같이 매우 짧은 시간만 유지 |
일반화 관계 | ―――――――▷ | 객체지향에서 상속 관계(IS-A)를 표현하며, 한 클래스가 다른 클래스를 포함하는 상위 개념일 때 사용 |
집합/포함 관계 | ―――――――◇ | - 클래스 사이 전체나 부분이 같은 관계 - 전체/부분 객체 라이프타임 독립적(전체 객체 삭제 → 부분 객체 남음) |
―――――――◆ | 전체/부분 객체 라이프타임 의존적(전체 객체 삭제 → 부분 객체 삭제) | |
실체화 관계 | - - - - - - - - - - - -▷ | 책임 집합 인터페이스와 실제로 실현한 클래스들 사이의 관계 |
① UML 연관 관계(Association Relation)
- 한 사물의 객체가 다른 사물의 객체와 연결된 것을 표현한다.
- 두 클래스가 서로 연관이 있다면 A, B 객체를 서로 참조할 수 있음을 표현한다.
- 이름 : 관계의 의미를 표현하기 위해 이름을 가질 수 있다.
- 역할 : 수행하는 역할을 명시적으로 이름을 가질 수 있다.
② UML 의존 관계(Dependency Relation)
- 연관 관계와 같지만 메소드를 사용할 떄와 같이 매우 짧은 시간만 유지된다.
- 영향을 주는 객체(User)에서 영향을 받는 객체 방향으로 점선 화살표로 연결한다.
③ UML 일반화 관계(Generalization Relation)
- 객체지향에서 상속 관계(Is A Kind Of)를 표현한다.
- 한 클래스가 다른 클래스를 포함하는 상위 개념일 때 사용한다.
④ UML 집합 관계(Aggregation Relation)
- A 객체가 B 객체에 포함된 관계이다.
- '부분'을 나타내는 객체를 다른 객체와 공유할 수 있다.
- '전체' 클래스 방향에 빈 마름모로 표시하고, Or 관계에 놓이면 선 사이를 점선으로 잇고 {or}를 표시한다.
⑤ UML 포함 관계(Composition Relation)
- 부분 객체가 전체 객체에 속하는 강한 집합 연관의 관계를 표현하는 클래스이다.
- '부분' 객체를 다른 객체와 공유 불가하고, '전체' 객체 방향에 채워진 마름모로 표시한다.
⑥ UML 실페화 관계(Realization Relation)
- 인터페이스와 실제 구현된 일반 클래스 간의 관계로 존재하는 행동에 대해 구현한다.
- 인터페이스의 명세나 정의만 존재하는 메소드를 실제 기능으로 구현한 것이다.
15. 다음은 데이터베이스에 관한 문제이다. 아래 내용을 읽고 알맞은 답을 보기에서 찾아 골라 작성하시오.
(1) 다른 테이블, 릴레이션의 기본 키를 참조하는 속성 또는 속성들의 집합
(2) 테이블에서 각 행을 유일하게 식별할 수 있는 최소한의 속성들의 집합 (3) 후보 키 중에서 선정된 기본 키를 제외한 나머지 후보 키 (4) 테이블에서 각 행을 유일하게 식별할 수 있는 속성들의 집합 |
ㄱ. 슈퍼키 ㄴ. 외래키 ㄷ. 대체키 ㄹ. 후보키
|
ㄴ. 외래키, ㄹ. 후보키, ㄷ. 대체키, ㄱ. 슈퍼키
* 키(Key)의 종류
① 후보키(Candidate Key)
- 릴레이션(테이블)에서 각 튜플을 유일하게 식별할 수 있는 속성이나 속성의 집합
- 후보키가 될 수 있는 조건은 유일성과 최소성을 모두 만족해야 한다.
- 유일성 : 각 튜플을 유일하게 식별하는 성질
- 최소성 : 각 튜플을 유일하게 식별할 수 있는 최소 구성의 성질을 말한다.
② 기본키(Primary Key, PK)
- 기본키는 후보키 중에서 튜플을 식별하기 위해 특별히 선택된 키를 말한다.
- 기본키는 중복될 수 없으며, NULL 값이 올 수 없다.
- 유일성과 최소성을 만족해야 한다.
③ 대체키(Alternate Key)
- 대체키는 후보키 중에서 기본키를 제외한 속성을 말한다.
④ 외래키(Foreign Key, FK)
- 외래키는 하나의 테이블에서 원하는 자료를 얻지 못하는 경우 다른 테이블을 참조(이용)하기 위해 사용되는 속성을 말하며, 외래 식별자라고도 한다.
- 외래키는 참조 릴레이션(테이블)의 기본키와 같아야 한다.
- 외래키는 NULL이 올 수 있다.
- 외래키의 속성명과 참조 릴레이션의 기본키 속성명은 서로 달라도 무방하다.
⑤ 슈퍼키(Super Key)
- 슈퍼키는 한 릴레이션(테이블) 내의 튜플들을 식별할 수 있는 후보키와 다른 속성들과의 모든 조합을 말한다.
- 슈퍼키는 유일성은 만족하지만, 최소성은 만족하지 않는다.
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
arr = {3, 1, 4, 1, 5}
p = arr = {3, 1, 4, 1, 5}
pp = &p = &arr
- i = 0;
- *(arr + 0 ) = (*( arr + 0 ) + 0 ) % 5)
- arr[0] = ( *arr[0] + 0 ) % 5 = arr[0] % 5 = 3 % 5 = 3
- i = 1;
- *(arr + 1) = (*( arr + 1 ) + 1) % 5)
- arr[1] = ( arr[1] + 1 ) % 5 = ( 1 + 1 ) % 5 = 2
- i = 2;
- *(arr + 2) = (*(arr + 2) + 2) % 5)
- arr[2] = ( arr[2] + 2 ) % 5 = ( 4 + 2 ) % 5 = 1
- i = 3;
- *(arr + 3 ) = (*(arr + 3 ) + 3) % 5)
- arr[3] = ( arr[3] + 3 ) % 5 = ( 1 + 3 ) % 5 = 4
- i = 4;
- *(arr + 4 ) = (*(arr + 4 ) + 4 ) % 5)
- arr[4] = ( arr[4] + 4 ) % 5 = ( 5 + 4 ) % 5 = 4
- arr = {3, 2, 1, 4, 4}
- arr[2] = 1
17. 다음 아래 내용을 보고 알맞은 용어를 3글자로 작성하시오.
- 공용 네트워크를 통해 사설 네트워크를 확장하는 기술이다.
- 사용자의 IP 주소를 숨기고, 사용자가 어디에서 접속하는 지를 추적하기 어렵게 만든다. - 종류로는 IPSec 또는 SSL, L2TP 등이 있다. |
VPN
* VPN(Virtual Private Network, 가상 사설망)
- 개별의 망을 하나의 망처럼 사용하며, 안전하지 않은 공용 네트워크를 이용하여 사설 네트워크를 구성하는 기술이다.
- 전용선을 이용한 사설 네트워크에 비해 저렴한 비용으로 안전한 망을 구성할 수 있다.
- 공용 네트워크로 전달되는 트래픽은 암호화 및 메시지 인증 코드 등을 사용하여 기밀성과 무결성을 제공한다.
- 인터넷과 같은 공공 네트워크를 통해서 기업의 재택 근무자나 이동 중인 직원이 안전하게 회사 시스템에 접근할 수 있도록 해준다.
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
- 예외 발생 (throw new NullPointerException();)
- func()에서 NullPointerException이 발생
- func()를 호출한 try 블록에서 예외가 감지됨
- 적절한 catch 블록 탐색
- 첫 번째 catch (NullPointerException e)가 NullPointerException을 처리할 수 있음 → 해당 블록 실행
- sum = sum + 1; → sum = 0 + 1 = 1
- finally 블록 실행
- finally 블록은 예외 발생 여부와 관계없이 항상 실행됨
- sum = sum + 100; → sum = 1 + 100 = 101
- sum = 1 + 100 = 101
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
1. 코드 실행 흐름
- new Collection<>(0).print(); 실행
- Collection<Integer> 객체 생성
- value = 0 (정수 0이 Integer로 저장됨)
- print() 메서드 호출
- print() 메서드 내부
- new Printer().print(value); 실행
- value의 타입은 Integer → Printer 클래스의 print(Integer a), print(Object a), print(Number a) 중에서 적절한 메서드 선택
2. 메서드 오버로딩(Overloading)과 정적 바인딩(Static Binding)
- 자바에서 메서드 오버로딩은 컴파일 시점(정적 바인딩, Static Binding) 에 결정됨.
- 즉, print(value); 실행 시, value의 컴파일 타임 타입을 기준으로 적절한 메서드를 선택함.
- value는 Integer 타입이지만, 메서드 선택 과정에서는 오버로딩된 메서드 중 가장 구체적인 것(더 나은 매칭)을 찾음
- 매칭 후보:
- print(Integer a)
- print(Number a) (Integer는 Number의 하위 클래스)
- print(Object a) (모든 클래스의 최상위 부모)
- 중요:
- 오버로딩된 메서드 선택은 "상속 계층 구조"에 따라 가장 구체적인 타입을 찾는 방식으로 진행됨
- Integer → Number → Object 계층에서 print(Integer a)가 가장 구체적이므로 선택될 것 같지만...
- 문제점: print(Integer a)는 Printer 내부 클래스에서 선언되었지만 외부 Collection<T> 클래스에서 호출되는 상황에서는 T의 타입 정보가 지워짐 (제네릭 타입 소거, Type Erasure).
- 즉, value의 런타임 타입이 Integer여도, 컴파일 시점에는 T가 Object로 인식됨
3. 최종적으로 print(Object a) 실행됨
- 따라서 print(Object a)가 선택되고, 출력 결과는:
- 즉, "B0" 출력됨
* 제네릭 타입 소거(Type Erasure)란?
- 제네릭 타입 소거(Type Erasure) 는 컴파일 타임에 제네릭 타입이 제거되고, 대신 Object 또는 특정 상위 타입으로 변환되는 과정을 말합니다.
- 즉, 실행 시점(Run-time)에는 제네릭 타입 정보가 존재하지 않음.
* 제네릭 타입 소거가 왜 발생할까?
- 자바의 제네릭(Generic) 기능은 컴파일 타임에만 타입 안정성을 보장하고, 런타임에는 타입 정보가 유지되지 않음.
- 그 이유는 자바의 하위 호환성(Backward Compatibility) 때문
- 자바는 JDK 1.5 이전 버전의 코드와의 호환성을 유지하기 위해 제네릭 정보를 컴파일 후 제거하는 방식을 채택
- 즉, 기존 코드와의 호환성을 유지하면서도 타입 안정성을 추가하려고 제네릭을 도입한 것
20. 다음은 네트워크에 대한 문제이다. 아래 내용을 보고 알맞은 용어를 작성하시오.
- 중앙 관리나 고정된 인프라 없이 임시로 구성되는 네트워크이다.
- 일반적으로 무선 통신을 통해 노드들이 직접 연결되어 데이터를 주고받는다. - 긴급 구조, 긴급 회의, 군사적인 상황 등에서 유용하게 활용될 수 있다. |
ㄱ. Infrastructure Network ㄴ. Firmware Network ㄷ. Peer-to-Peer Network ㄹ. Ad-hoc Network
ㅁ. Mesh Network ㅂ.Sensor Network ㅅ.Virtual Private Network |
ㄹ. Ad-hoc Network
- 무선 기반의 이동단말기 간 연결망의 일종으로서, 라우터 장비가 따로 없고 이동단말기 중 일부가 라우터 역할을 담당하는 네트워크이다.
- 동적으로 경로를 설정할 수 있어 '기반구조 없는 네트워크'라고도 한다. 험난한 지형이나 위험한 장소에서의 네트워크 구성을 하는 데 유용하다. 이동단말기에 센서 기능을 부가할 경우 USN(Ubiquitous Sensor Network)으로 발전한다.
- 2021년 2회 출
'정보처리기사' 카테고리의 다른 글
[정보처리기사 요약정리] PART 5. 정보시스템 구축관리+ 기출포함 (26) | 2024.10.19 |
---|---|
[정보처리기사 요약정리] PART 4. 프로그래밍 언어 활용 + 기출포함 (8) | 2024.10.19 |
[정보처리기사 요약정리] PART 3. 데이터베이스 구축 + 기출포함 (5) | 2024.10.19 |
[정보처리기사 요약정리] PART 2. 소프트웨어 개발 + 기출포함 (12) | 2024.10.19 |
[정보처리기사 요약정리] PART 1. 소프트웨어 설계 + 기출포함 (12) | 2024.10.18 |