다음은 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);
}
}
1. `main` 메소드에서 `static` 문자열 배열 `s`가 초기화됩니다. - `s[0]`과 `s[1]`은 리터럴 "A"로 초기화됩니다. Java에서 문자열 리터럴은 내부적으로 동일한 객체를 참조할 수 있습니다. - `s[2]`는 `new String("A")`를 통해 새로운 String 객체로 생성됩니다. 비록 내용은 "A"로 같지만, `s[0]`이나 `s[1]`과는 다른 객체입니다. - 현재 `s` 배열 상태: `{"A", "A", new String("A")}` 2. `func(s, 3)` 메소드가 호출됩니다. 3. 첫 번째 `for` 루프 (인접 요소 비교): - `i = 1`: `s[0].equals(s[1])`을 비교합니다. `"A".equals("A")`는 문자열 내용이 같으므로 `true`입니다. "O"가 출력됩니다. - `i = 2`: `s[1].equals(s[2])`를 비교합니다. `"A".equals(new String("A"))`는 문자열 내용이 같으므로 `true`입니다. "O"가 출력됩니다. (만약 `==` 연산자로 비교했다면 `s[1] == s[2]`는 `false`가 될 수 있습니다.) 4. 두 번째 `for` 루프 (향상된 for문, 배열 요소 출력): - `m = s[0]` ("A") -> "A" 출력 - `m = s[1]` ("A") -> "A" 출력 - `m = s[2]` ("A") -> "A" 출력 5. 최종 출력은 비교 결과 "OO"와 배열 요소 "AAA"가 합쳐진 "OOAAA"입니다.
답 : 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]))
아래의 employee 테이블과 project 테이블을 참고하여 보기의 SQL명령어에 알맞는 출력 값을 작성하시오.
[employee] 테이블
no
first_name
last_name
project_id
1
John
Doe
10
2
Jim
Carry
20
3
Rachel
Redmond
10
[project] 테이블
project_id
name
10
Alpha
20
Beta
10
Gamma
보기 (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
)
);
SQL 쿼리를 단계별로 분석합니다. 1. 가장 안쪽 서브쿼리: SELECT project_id FROM employee GROUP BY project_id HAVING count(*) < 2 - `employee` 테이블을 `project_id`로 그룹화합니다. (`project_id` 10 그룹, `project_id` 20 그룹) - `HAVING count(*) < 2` 조건으로 그룹 내 행(직원) 수가 2 미만인 그룹을 찾습니다. - `project_id` 10 그룹은 직원이 2명(John, Rachel)이므로 조건에 맞지 않습니다. - `project_id` 20 그룹은 직원이 1명(Jim)이므로 조건에 맞습니다. - 이 서브쿼리의 결과는 `project_id` 값 20입니다. 2. 중간 서브쿼리: SELECT name FROM project p WHERE p.project_id IN (20) - `project` 테이블에서 `project_id`가 안쪽 서브쿼리 결과인 20인 행의 `name`을 찾습니다. - `project_id`가 20인 프로젝트의 이름은 "Beta"입니다. - 이 서브쿼리의 결과는 `name` 값 "Beta"입니다. 3. 메인 쿼리: SELECT count(*) FROM employee AS e JOIN project AS p ON e.project_id = p.project_id WHERE p.name IN ('Beta') - `employee` 테이블(e)과 `project` 테이블(p)을 `project_id` 기준으로 JOIN합니다. - JOIN 결과에서 `p.name`이 중간 서브쿼리 결과인 "Beta"인 행들만 필터링합니다. - JOIN 결과 중 `p.name`이 "Beta"인 경우는 `employee`의 Jim Carry (project_id 20) 행과 `project`의 Beta (project_id 20) 행이 결합된 경우입니다. - 이 조건을 만족하는 행은 1개입니다. - `count(*)`는 이 조건을 만족하는 행의 개수를 세므로, 최종 결과는 1입니다.
답 : 1
문제 4. [운영체제] LRU 페이지 교체 알고리즘
다음은 운영체제 페이지 순서를 참고하여 할당된 프레임의 수가 3개일 때, LRU 알고리즘의 페이지 부재 횟수를 작성하시오.
LRU (Least Recently Used) 알고리즘: 페이지 교체 시, 가장 오랫동안 참조되지 않은 페이지(가장 사용한 지 오래된 페이지)를 교체하는 방식입니다. 프레임 수: 3 페이지 참조 순서: 7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1
단계별 프레임 상태 및 페이지 부재(Page Fault, PF) 발생 여부:
참조 프레임 상태 PF 설명 (교체 대상)
----------------------------------------------------
7 [7] O (PF 1)
0 [7, 0] O (PF 2)
1 [7, 0, 1] O (PF 3)
2 [2, 0, 1] O (PF 4) 7이 가장 오래됨
0 [2, 0, 1] X 0 이미 있음 (0이 가장 최신)
3 [2, 3, 1] O (PF 5) 0 참조 후 1이 가장 오래됨
0 [2, 3, 0] O (PF 6) 1 참조 후 2가 가장 오래됨
4 [4, 3, 0] O (PF 7) 0 참조 후 3이 가장 오래됨 -> 틀림, 3이 아니라 2참조 후 이므로 3이 가장 오래됨 -> 틀림, 0참조 후 1이 가장 오래됨 -> 틀림, 0 참조 후 2가 가장 오래됨 -> 틀림, 0 참조 후 1이 가장 오래됨 -> 틀림. 0 참조후 3 참조 후 2가 가장 오래됨 -> 틀림. 3참조 후 0참조 후 2가 가장 오래됨
*다시* 0참조 시 [2,3,0]. 4 참조 시 가장 오래된 것은 2. -> [4,3,0] 맞음.
2 [4, 3, 2] O (PF 8) 0 참조 후 3이 가장 오래됨
3 [4, 3, 2] X 3 이미 있음 (3이 가장 최신)
0 [0, 3, 2] O (PF 9) 3 참조 후 4가 가장 오래됨
3 [0, 3, 2] X 3 이미 있음 (3이 가장 최신)
2 [0, 3, 2] X 2 이미 있음 (2가 가장 최신)
1 [1, 3, 2] O (PF 10) 2 참조 후 0이 가장 오래됨
2 [1, 3, 2] X 2 이미 있음 (2가 가장 최신)
0 [1, 0, 2] O (PF 11) 2 참조 후 3이 가장 오래됨
1 [1, 0, 2] X 1 이미 있음 (1이 가장 최신)
7 [7, 0, 2] O (PF 12) 1 참조 후 2는 참조됨, 0도 참조됨, 1이 가장 오래됨? -> 틀림. 1참조후 0참조후 2가 가장오래됨
*다시* 1 참조 시 [1,0,2]. 7 참조 시 가장 오래된 것은 0참조 후 2. -> [1, 7, 2] ? -> 틀림. 1 참조 후 0 참조 후 2참조 후 1참조 후 0 참조 후 2가 가장 오래됨. -> 틀림. [1,0,2] 상태에서 1참조 후 0 참조후 2가 가장오래됨 -> 틀림. [1,0,2] 에서 0참조, 1참조 후 2가 가장 오래됨 -> [7,0,1]? -> 틀림.
*최종 상태 [1, 0, 2]. 0 최근 참조, 1 그 다음, 2 가장 오래됨. 7 참조 시 2 교체 -> [1, 0, 7]
0 [1, 0, 7] X 0 이미 있음 (0이 가장 최신)
1 [1, 0, 7] X 1 이미 있음 (1이 가장 최신)
----------------------------------------------------
페이지 부재는 총 12번 발생합니다.
답 : 12
문제 5. [네트워크 보안] 공격 유형 용어
다음은 네트워크 취약점에 대한 문제이다. 아래 내용을 보고 알맞는 용어를 작성하시오.
IP나 ICMP의 특성을 악용하여 엄청난 양의 데이터를 한 사이트에 집중적으로 보냄으로써 네트워크의 일부를 불능 상태로 만드는 공격이다.
여러 호스트(또는 네트워크)가 특정 대상(희생자)에게 대량의 ICMP Echo Reply 를 보내게 하여 서비스 거부(DoS)를 유발시키는 보안 공격이다.
공격 대상 호스트는 대량으로 유입되는 응답 패킷으로 인해 시스템 자원이 고갈되어 서비스 불능 상태에 빠진다.
설명하는 공격은 스머프(Smurf) 공격 또는 스머핑(Smurfing)입니다. 스머프 공격은 출발지 IP 주소를 공격 대상(희생자)의 IP 주소로 위조한 ICMP Echo Request 패킷을 네트워크에 브로드캐스트 방식으로 전송합니다. 해당 네트워크 내의 호스트들은 위조된 ICMP Echo Request에 대한 응답(ICMP Echo Reply)을 모두 출발지 IP 주소, 즉 공격 대상(희생자)에게 보내게 됩니다. 이로 인해 공격 대상은 갑자기 많은 양의 ICMP Echo Reply 패킷을 수신하게 되어 네트워크 대역폭이나 시스템 자원이 고갈되어 서비스 거부(DoS) 상태에 빠지게 되는 분산 반사 서비스 거부(DRDoS) 공격의 일종입니다.
답 : 스머프(Smurf) 또는 스머핑(Smurfing)
문제 6. [SW설계] GoF 디자인 패턴 분류
다음은 GoF 디자인 패턴과 관련된 문제이다. 괄호안에 알맞는 용어를 작성하시오.
( ) 패턴은 클래스나 객체들이 서로 상호작용하는 방법이나 책임 분배 방법을 정의하는 패턴이다. ( ) 패턴은 객체들 간의 통신 방법을 정의하고 알고리즘을 캡슐화하여 객체간의 결합도를 낮춘다. ( ) 패턴은 Chain of Responsibility나 Command 또는 Observer 패턴이다.
GoF(Gang of Four) 디자인 패턴은 크게 세 가지 범주로 분류됩니다: 1. 생성(Creational) 패턴: 객체 생성 메커니즘을 다루며, 객체 생성 과정을 캡슐화하고 유연하게 만듭니다. (예: Singleton, Factory Method, Abstract Factory) 2. 구조(Structural) 패턴: 클래스나 객체를 조합하여 더 큰 구조를 만드는 방법을 다룹니다. 상속보다는 합성을 통해 기능과 구조를 확장합니다. (예: Adapter, Composite, Decorator, Proxy) 3. 행위(Behavioral) 패턴: 객체 간의 상호작용 및 책임 분배 방법을 다룹니다. 객체 간의 결합도를 줄이고 유연한 협력을 가능하게 합니다. (예: Strategy, Observer, Command, Iterator, State, Chain of Responsibility)
문제의 설명은 객체 간의 상호작용, 책임 분배, 통신 방법, 알고리즘 캡슐화 등을 다루고 있으며, 예시로 Chain of Responsibility, Command, Observer 패턴을 들고 있으므로 이는 행위(Behavioral) 패턴에 해당합니다.
답 : 행위
문제 7. [C] 코드 출력 값 (static 변수)
다음은 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;
}
1. `func` 함수 내의 `static int x = 0;` 라인은 프로그램이 시작될 때 단 한 번만 실행되어 `x`를 0으로 초기화합니다. `static` 변수는 함수 호출이 종료되어도 그 값을 유지합니다. 2. `main` 함수에서 지역 변수 `x`는 1로, `sum`은 0으로 초기화됩니다. 이 `x`는 `func` 함수 내부의 `static` 변수 `x`와는 다른 변수입니다. 3. `for` 루프는 `i`가 0, 1, 2, 3일 때 총 4번 반복됩니다. - **i = 0:** - `x++` 실행 (main의 `x`는 2가 됨). - `func()` 호출: `func`의 `static x`는 0+2=2가 되고, 2를 반환합니다. - `sum += 2;` (sum은 0 + 2 = 2가 됨). - **i = 1:** - `x++` 실행 (main의 `x`는 3가 됨). - `func()` 호출: `func`의 `static x`는 이전 값 2에서 2+2=4가 되고, 4를 반환합니다. - `sum += 4;` (sum은 2 + 4 = 6가 됨). - **i = 2:** - `x++` 실행 (main의 `x`는 4가 됨). - `func()` 호출: `func`의 `static x`는 이전 값 4에서 4+2=6가 되고, 6를 반환합니다. - `sum += 6;` (sum은 6 + 6 = 12가 됨). - **i = 3:** - `x++` 실행 (main의 `x`는 5가 됨). - `func()` 호출: `func`의 `static x`는 이전 값 6에서 6+2=8가 되고, 8를 반환합니다. - `sum += 8;` (sum은 12 + 8 = 20가 됨). 4. `for` 루프가 종료된 후 `printf("%d", sum);`이 실행되어 최종 `sum` 값인 20이 출력됩니다.
답 : 20
문제 8. [DB] 무결성 제약조건 위반
다음은 무결성 제약조건에 대한 문제이다. 아래 표에서 어떠한 ( ) 무결성을 위반하였는지 작성하시오.
Student
Name
Age
Major
101
Alice
20
Computer Science
102
Bob
21
Mathematics
101
David
23
Chemistry
NULL
Eve
22
Biology
데이터베이스 무결성 제약조건은 데이터의 정확성과 일관성을 유지하기 위한 규칙입니다. 주요 무결성 제약조건은 다음과 같습니다: 1. 개체(Entity) 무결성: 기본 키(Primary Key) 값은 NULL 값을 가질 수 없으며, 릴레이션 내에서 유일해야 한다는 제약조건입니다. 각 튜플(행)을 고유하게 식별하기 위해 필요합니다. 2. 참조(Referential) 무결성: 외래 키(Foreign Key) 값은 참조하는 릴레이션의 기본 키 값이거나 NULL이어야 한다는 제약조건입니다. 릴레이션 간의 관계가 유효하도록 보장합니다. 3. 도메인(Domain) 무결성: 특정 속성(열)의 값이 정의된 도메인(예: 데이터 타입, 허용 범위)을 벗어날 수 없다는 제약조건입니다.
제시된 테이블에서 `Student` 열이 기본 키라고 가정할 때 (일반적으로 식별자 역할을 하므로), 마지막 행에서 `Student` 값이 NULL인 것을 볼 수 있습니다. 이는 기본 키는 NULL 값을 가질 수 없다는 개체 무결성 제약조건을 위반한 것입니다. 또한, `Student` 값이 101인 행이 두 개 존재하므로 기본 키의 유일성 조건도 위반했습니다. 둘 다 개체 무결성 위반에 해당합니다.
답 : 개체
문제 9. [네트워크] URL 구조 매칭
다음은 URL 구조에 관한 문제이다. 아래 보기의 순서대로 URL에 해당하는 번호를 작성하시오.
보기 query : 서버에 전달할 추가 데이터 path : 서버 내의 특정 자원을 가리키는 경로 scheme : 리소스에 접근하는 방법이나 프로토콜 authority : 사용자 정보, 호스트 명, 포트 번호 fragment : 특정 문서 내의 위치
URL(Uniform Resource Locator)의 각 구성 요소는 다음과 같습니다: - (1) `https://`: 리소스에 접근하는 데 사용될 프로토콜(Protocol)을 나타냅니다. 예: http, https, ftp, file 등. 이를 scheme 또는 스킴이라고 합니다. - (2) `user:pass@www.example.com:80`: 리소스가 위치한 서버에 대한 정보입니다. 선택적으로 사용자 이름(`user`), 비밀번호(`pass`), 호스트(도메인 이름 또는 IP 주소, `www.example.com`), 포트 번호(`80`)를 포함할 수 있습니다. 이 부분을 통틀어 authority라고 합니다. - (3) `/path/to/resource`: 서버 내에서 요청하는 자원(파일, 페이지 등)의 구체적인 경로를 나타냅니다. 이를 path라고 합니다. - (4) `?key1=value1&key2=value2`: 서버에 전달할 추가적인 파라미터들을 나타냅니다. `?` 뒤에 오며, `key=value` 쌍으로 구성되고 `&`로 구분됩니다. 이를 query 또는 쿼리 문자열이라고 합니다. - (5) `#section1`: 특정 리소스(예: HTML 문서) 내의 특정 부분을 가리키는 식별자입니다. `#` 뒤에 오며, 클라이언트(브라우저)에서 주로 처리됩니다. 이를 fragment 또는 프래그먼트라고 합니다.
따라서 각 번호에 해당하는 용어는 다음과 같습니다. (1) = scheme (2) = authority (3) = path (4) = query (5) = fragment
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))
1. `func(value)` 함수는 입력받은 `value`의 타입을 확인하여 특정 값을 반환합니다. - `type(value) == type(100)`: `value`의 타입이 `int` (정수)이면 `True`입니다. - `type(value) == type("")`: `value`의 타입이 `str` (문자열)이면 `True`입니다. - 그 외의 타입(float, tuple, list 등)이면 `else` 블록이 실행됩니다. 2. `a = '100.0'`: `a`는 문자열(`str`)입니다. - `func(a)` 호출 시, `type(a) == type("")` 조건이 `True`가 됩니다. - `len(a)` 즉, `len('100.0')`은 문자열의 길이인 5를 반환합니다. 3. `b = 100.0`: `b`는 실수(`float`)입니다. - `func(b)` 호출 시, `int` 타입도 아니고 `str` 타입도 아니므로 `else` 블록이 실행됩니다. - 20을 반환합니다. 4. `c = (100, 200)`: `c`는 튜플(`tuple`)입니다. - `func(c)` 호출 시, `int` 타입도 아니고 `str` 타입도 아니므로 `else` 블록이 실행됩니다. - 20을 반환합니다. 5. `print(func(a) + func(b) + func(c))` 실행: - `func(a)` 결과 5, `func(b)` 결과 20, `func(c)` 결과 20을 모두 더합니다. - 5 + 20 + 20 = 45. 6. 따라서 45가 출력됩니다.
답 : 45
문제 11. [Java] 상속과 다형성 출력 값
다음은 Java 코드에 대한 문제이다. 아래 코드를 확인하여 알맞는 출력 값을 작성하시오.
public class Main{
public static void main(String[] arge){
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;
@Override
int getX(){
return x * 3;
}
}
이 코드는 Java의 상속과 다형성에 대한 문제입니다. 1. `Base a = new Derivate();`: `Derivate` 클래스의 객체를 만들었지만, `Base` 타입의 변수 `a`로 참조합니다. (업캐스팅) 2. `Derivate b = new Derivate();`: `Derivate` 클래스의 객체를 만들고, `Derivate` 타입의 변수 `b`로 참조합니다. 3. `System.out.print(a.getX() + a.x + b.getX() + b.x);` 부분을 분석해 봅시다. - `a.getX()`: 변수 `a`가 가리키는 실제 객체는 `Derivate`입니다. 메소드를 호출할 때는 실제 객체의 메소드가 실행됩니다(동적 바인딩). 따라서 `Derivate`의 `getX()`가 호출되어, `Derivate`의 `x` 값인 7에 3을 곱한 21이 됩니다. - `a.x`: 멤버 변수(필드)에 접근할 때는 변수를 선언할 때 사용한 타입을 따릅니다(정적 바인딩). 변수 `a`는 `Base` 타입으로 선언되었으므로, `Base` 클래스의 `x` 값인 3을 가져옵니다. - `b.getX()`: 변수 `b`는 `Derivate` 타입이므로, `Derivate`의 `getX()`가 호출되어 21이 됩니다. - `b.x`: 변수 `b`는 `Derivate` 타입이므로, `Derivate` 클래스의 `x` 값인 7을 가져옵니다. 4. 최종적으로 `21 + 3 + 21 + 7`을 계산합니다. 이는 산술 덧셈이므로 결과는 52입니다.
1. **연결 리스트 생성:** `main` 함수에서 세 개의 노드 `n1`, `n2`, `n3`를 만들고 값을 각각 1, 2, 3으로 설정합니다. 그리고 `n1.next = &n3`, `n3.next = &n2`를 통해 노드들을 연결합니다. 따라서 리스트는 `n1(값:1) -> n3(값:3) -> n2(값:2)` 순서가 됩니다. 2. **`func` 함수 실행:** `func(&n1)`를 호출하여 리스트의 시작 노드(`n1`) 주소를 전달합니다. - `func` 함수는 리스트를 두 노드씩 건너뛰면서, 현재 노드(`node`)와 다음 노드(`node->next`)의 `value`를 서로 바꿉니다. - **첫 번째 반복:** `node`는 `n1`을 가리킵니다. `node`와 `node->next`(즉, `n3`)가 모두 NULL이 아니므로 루프가 실행됩니다. - `n1`의 값(1)과 `n3`의 값(3)을 서로 바꿉니다. 이제 `n1`의 값은 3, `n3`의 값은 1이 됩니다. - `node`를 두 칸 뒤로 이동시킵니다 (`node = node->next->next`). `n1` 다음의 다음 노드는 `n2`이므로, `node`는 이제 `n2`를 가리킵니다. - **두 번째 반복 조건 확인:** `node`는 `n2`를 가리킵니다. `node`는 NULL이 아니지만, `node->next`(즉, `n2->next`)가 NULL이므로 `while` 루프의 조건 (`node->next != NULL`)을 만족하지 못해 루프가 종료됩니다. 3. **결과 출력:** `main` 함수로 돌아와 `current` 포인터로 리스트의 처음(`n1`)부터 끝까지 순회하며 각 노드의 `value`를 출력합니다. - `func` 함수 실행 후 리스트 상태는 `n1(값:3) -> n3(값:1) -> n2(값:2)` 입니다. - 따라서 출력 순서는 3, 1, 2가 됩니다.
답 : 312
문제 13. [SW테스팅] 테스트 커버리지 유형
다음은 테스트 커버리지에 대한 문제이다. 아래 내용에 알맞는 답을 보기에서 골라 작성하시오.
a) 테스트를 통해 프로그램의 모든 문장(Statement)을 최소한 한번씩 실행 했는지를 측정 b) 프로그램 내의 모든 분기(조건문)의 각 분기(참/거짓 결과)를 최소한 한번씩 실행했는지를 측정 c) 복합 조건(예: A and B) 내의 각 개별 조건(A, B 각각)이 참과 거짓으로 평가되는 경우를 모두 테스트 했는지를 측정
보기 ㄱ. 조건 ㄴ. 경로 ㄷ. 결정 ㄹ. 분기 ㅁ. 함수 ㅂ. 문장 ㅅ. 루프
테스트 커버리지는 소프트웨어 테스트가 얼마나 충분히 수행되었는지를 나타내는 지표입니다. 각 설명은 다음과 같은 커버리지 기준을 의미합니다. - a) 문장 커버리지 (Statement Coverage): 코드 한 줄 한 줄이 최소한 한 번은 실행되었는지를 확인합니다. 가장 기본적인 커버리지 기준입니다. (보기: ㅂ. 문장) - b) 분기 커버리지 (Branch Coverage) 또는 결정 커버리지 (Decision Coverage): 조건문(if, switch 등)이 있을 때, 그 조건의 결과가 참(True)인 경우와 거짓(False)인 경우 모두 최소 한 번씩 실행되었는지 확인합니다. 모든 갈림길을 테스트했는지 보는 것입니다. (보기: ㄹ. 분기 또는 ㄷ. 결정) - c) 조건 커버리지 (Condition Coverage): 하나의 조건문 안에 여러 개의 개별 조건(예: `if (age > 18 && isMember == true)`)이 있을 때, 각 개별 조건(`age > 18`, `isMember == true`)이 참(True)인 경우와 거짓(False)인 경우 모두 최소 한 번씩 실행되었는지 확인합니다. (보기: ㄱ. 조건)
답 : a=ㅂ.문장, b=ㄹ. 분기, c=ㄱ. 조건
문제 14. [UML] 클래스 다이어그램 관계
아래는 UML 클래스의 관계에 관한 문제이다. 보기를 보고 알맞는 관계를 선택하여 작성하시오.
보기 ㄱ. 의존(Dependency) ㄴ. 연관(Association) ㄷ. 일반화(Generalization)
UML 클래스 다이어그램에서 클래스 간의 관계를 나타내는 주요 표기법은 다음과 같습니다. - (1) 연관 (Association): 두 클래스의 객체들이 서로 연결되어 있고, 한 객체가 다른 객체를 멤버 변수로 참조하는 등 비교적 오래 지속되는 관계를 나타냅니다. - (2) 일반화 (Generalization): 클래스 간의 'is-a' 관계, 즉 상속 관계를 나타냅니다. - (3) 의존 (Dependency): 한 클래스가 다른 클래스를 메소드의 매개변수, 리턴 값, 또는 메소드 내의 지역 변수 등으로 잠시 사용하는 일시적인 관계를 나타냅니다.
답 : (1) = ㄴ.연관, (2) = ㄷ.일반화 , (3) = ㄱ.의존
문제 15. [DB] 데이터베이스 키(Key) 유형
다음은 데이터베이스에 관한 문제이다. 아래 내용을 읽고 알맞는 답을 보기에서 찾아 골라 작성하시오.
다른 테이블의 기본 키를 참조하여 테이블 간의 관계를 맺는 데 사용되는 키
테이블의 각 행을 유일하게 구별할 수 있는 가장 작은 속성(들)의 묶음
테이블 내에서 행을 유일하게 구별할 수 있는 후보 키들 중에서, 기본 키로 뽑히지 않은 나머지 키들
테이블의 각 행을 유일하게 구별할 수 있는 모든 속성(들)의 묶음 (가장 작은 묶음이 아닐 수도 있음)
데이터베이스에서 사용되는 키들의 의미는 다음과 같습니다. - (1) 외래키 (Foreign Key): 한 테이블의 열(속성)이 다른 테이블의 기본 키(Primary Key)를 참조할 때, 이 열을 외래키라고 합니다. 테이블 간의 관계를 설정하고 데이터의 일관성을 유지하는 데 중요합니다. (보기: ㄴ. 외래키) - (2) 후보키 (Candidate Key): 테이블에서 각 행을 유일하게 식별할 수 있는 속성 또는 속성들의 집합 중에서, 더 이상 줄일 수 없는 최소한의 집합을 말합니다. 예를 들어, 학생 테이블에서 '학번'이나 '주민등록번호'는 후보키가 될 수 있습니다. (보기: ㄹ. 후보키) - (3) 대체키 (Alternate Key): 후보키가 여러 개 있을 때, 그중에서 기본키로 선택된 것을 제외한 나머지 후보키들을 대체키라고 합니다. (보기: ㄷ. 대체키) - (4) 슈퍼키 (Superkey): 테이블에서 각 행을 유일하게 식별할 수 있는 속성 또는 속성들의 집합입니다. 후보키와 달리 최소성을 만족할 필요는 없습니다. 예를 들어, '학번'이 후보키라면 {'학번', '이름'} 도 슈퍼키가 될 수 있습니다. (보기: ㄱ. 슈퍼키)
#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. `main` 함수에서 정수 배열 `arr`이 `{3, 1, 4, 1, 5}`로 초기화됩니다. 2. 포인터 `p`는 배열 `arr`의 시작 주소를 가리킵니다. 3. 이중 포인터 `pp`는 포인터 `p`의 메모리 주소를 가리킵니다. 4. `func(pp, 5)` 함수가 호출됩니다. 이때 `func` 함수의 매개변수 `arr` (이중 포인터)은 `main` 함수의 `pp` 값, 즉 `p`의 주소를 받습니다. 5. `func` 함수 내부의 `for` 루프 (i = 0, 1, 2, 3, 4) 동작: - `*arr`: `pp`가 가리키는 값, 즉 포인터 `p` 자체를 의미합니다. (`p`는 원본 배열 `arr`의 시작 주소) - `*arr + i`: 포인터 `p`에 `i`를 더한 주소, 즉 원본 배열 `arr`의 `i`번째 요소의 주소 (`&arr[i]`) 입니다. - `*(*arr + i)`: 위 주소(`&arr[i]`)에 있는 값, 즉 원본 배열 `arr`의 `i`번째 요소 값 (`arr[i]`) 입니다. - `*(*arr + i) = ...`: 이 값을 변경하는 것은 `main` 함수에 있는 원본 배열 `arr`의 값을 직접 수정하는 것과 같습니다. - 수식 `(arr[i] + i) % size`를 계산하여 `arr[i]`를 업데이트합니다 (size는 5). - i=0: `arr[0] = (3 + 0) % 5 = 3`. 배열: `{3, 1, 4, 1, 5}` - i=1: `arr[1] = (1 + 1) % 5 = 2`. 배열: `{3, 2, 4, 1, 5}` - i=2: `arr[2] = (4 + 2) % 5 = 1`. 배열: `{3, 2, 1, 1, 5}` - i=3: `arr[3] = (1 + 3) % 5 = 4`. 배열: `{3, 2, 1, 4, 5}` - i=4: `arr[4] = (5 + 4) % 5 = 4`. 배열: `{3, 2, 1, 4, 4}` 6. 함수 실행 후 `main` 함수의 `arr` 배열은 `{3, 2, 1, 4, 4}`가 됩니다. 7. `num = arr[2];`: 변경된 배열 `arr`의 2번 인덱스 값인 1을 변수 `num`에 저장합니다. 8. `printf("%d", num);`: 변수 `num`의 값, 즉 1을 출력합니다.
답 : 1
문제 17. [네트워크] 네트워크 기술 용어
다음 아래 내용을 보고 알맞는 용어를 작성하시오.(3글자로 작성)
공용 네트워크(예: 인터넷)를 통해 사설 네트워크를 안전하게 확장하는 기술이다.
사용자의 실제 IP 주소를 숨기고, 암호화된 터널을 통해 통신하여 사용자가 어디에서 접속하는지를 추적하기 어렵게 만든다.
구현 기술로는 IPsec 또는 SSL/TLS, L2TP 등이 있다.
설명하는 기술은 VPN (Virtual Private Network), 우리말로는 **가상 사설망**입니다. VPN은 인터넷과 같은 공용 네트워크 상에 암호화된 통신 경로(터널)를 만들어, 마치 사용자가 내부 네트워크에 직접 연결된 것처럼 안전하게 데이터를 주고받을 수 있게 해주는 기술입니다. 이를 통해 인터넷 사용 기록의 프라이버시를 보호하거나, 외부에서 회사 내부망에 접속하는 등의 용도로 널리 사용됩니다.
답 : VPN
문제 18. [Java] 예외 처리 (try-catch-finally)
다음은 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();
}
}
Java의 예외 처리 흐름을 따라가 보겠습니다. 1. `main` 메소드 시작 시 `sum` 변수는 0으로 초기화됩니다. 2. `try` 블록에 진입하여 `func()` 메소드를 호출합니다. 3. `func()` 메소드 내에서 `throw new NullPointerException();` 코드가 실행되어 `NullPointerException` 예외가 발생합니다. 4. 예외가 발생했으므로 `try` 블록의 나머지 부분은 실행되지 않고, 해당 예외를 처리할 수 있는 `catch` 블록을 찾습니다. 5. 첫 번째 `catch (NullPointerException e)` 블록이 발생한 예외의 타입(`NullPointerException`)과 일치합니다. 따라서 이 `catch` 블록이 실행됩니다. 6. `sum = sum + 1;` 코드가 실행되어 `sum`의 값은 0 + 1 = 1이 됩니다. 7. 일치하는 `catch` 블록이 실행되었으므로, 그 아래의 다른 `catch` 블록 (`catch (Exception e)`)은 실행되지 않습니다. 8. `finally` 블록은 `try` 블록에서 예외가 발생하든 안 하든, `catch` 블록이 실행되든 안 되든 상관없이 **항상 실행**됩니다. 9. `sum = sum + 100;` 코드가 실행되어 `sum`의 값은 현재 값 1에 100을 더한 101이 됩니다. 10. `finally` 블록까지 실행된 후, `System.out.print(sum);` 코드가 실행되어 최종 `sum` 값인 101을 출력합니다.
답 : 101
문제 19. [Java] 제네릭, 내부 클래스, 오버로딩
다음은 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();
}
}
1. `new Collection<>(0)`: `main` 메소드에서 `Collection` 객체를 생성합니다. 생성자에 기본형 `int` 값 0을 전달하면, Java는 이를 자동으로 참조형 `Integer` 객체 0으로 변환합니다(오토박싱). 따라서 이 객체는 `Collection` 타입이 되고, 내부의 `value` 필드에는 `Integer` 객체 0이 저장됩니다. 2. `.print()`: 생성된 `Collection` 객체의 `print()` 메소드를 호출합니다. 3. `new Printer().print(value);`: `print()` 메소드 안에서는 `Printer` 내부 클래스의 객체를 만들고, `print` 메소드를 호출하면서 `value`(`Integer` 객체 0)를 인자로 전달합니다. 4. **메소드 선택 (오버로딩 해결):** `Printer` 클래스에는 이름이 `print`이고 매개변수 타입이 다른 세 개의 메소드(`Integer`, `Object`, `Number`)가 있습니다(메소드 오버로딩). Java 컴파일러는 호출 시 전달된 인자(`Integer` 타입의 `value`)와 가장 잘 맞는 메소드를 선택합니다. - `print(Integer a)`: 인자의 타입과 정확히 일치합니다. - `print(Object a)`: `Integer`는 `Object`의 자식 클래스이므로 가능합니다. - `print(Number a)`: `Integer`는 `Number`의 자식 클래스이므로 가능합니다. 여러 메소드가 후보일 경우, Java는 **가장 구체적인 타입(most specific type)**의 매개변수를 가진 메소드를 선택합니다. 여기서는 `Integer`가 `Number`나 `Object`보다 더 구체적이므로, `print(Integer a)` 메소드가 최종적으로 선택됩니다. 5. `System.out.print("A" + a);` 코드가 실행됩니다. `a`는 `Integer` 0이므로, 문자열 "A"와 합쳐져 최종적으로 "A0"이 출력됩니다.
(참고: 원 문제의 해설에서는 '타입 소거'를 이유로 `print(Object a)`가 호출된다고 설명했지만, 일반적인 Java의 메소드 오버로딩 규칙에 따르면 컴파일 시점에 가장 구체적인 타입인 `print(Integer a)`가 선택되는 것이 맞습니다. 따라서 이 해설은 표준 규칙을 따릅니다.)
답 : A0 (표준 오버로딩 규칙 기준) / B0 (문제 원문 해설 기준)
문제 20. [네트워크] 네트워크 유형 용어
다음은 네트워크에 대한 문제이다. 아래 내용을 보고 알맞는 용어를 작성하시오.
중앙 관리 지점(예: 공유기, 액세스 포인트)이나 미리 설치된 네트워크 기반 시설 없이, 필요할 때 임시로 장치들끼리 직접 연결하여 구성하는 네트워크이다.
주로 무선 통신을 사용하여, 각 장치(노드)가 서로 직접 데이터를 주고받는 P2P(Peer-to-Peer) 방식으로 동작한다.
기반 시설이 없는 재난 현장의 구조 활동, 회의실에서의 임시 파일 공유, 군사 작전 등에서 유용하게 사용될 수 있다.
설명하는 네트워크는 ㄹ. Ad-hoc Network (애드혹 네트워크)입니다. 애드혹 네트워크는 '특별한 목적을 위해'라는 의미처럼, 고정된 인프라(예: 인터넷 회선, Wi-Fi 공유기 등) 없이 장치들이 직접 통신하여 구성되는 임시 네트워크입니다. 각 장치가 서로 직접 데이터를 주고받거나, 다른 장치를 위한 중계점 역할을 하기도 합니다. 설정이 간편하고 빠르게 네트워크를 구성할 수 있다는 장점이 있습니다.
다른 보기 설명: - ㄱ. Infrastructure Network: 중앙의 AP(Access Point)를 통해 통신하는 일반적인 Wi-Fi 네트워크 구조입니다. - ㄷ. Peer-to-Peer Network: 서버 없이 동등한 노드끼리 직접 통신하는 방식을 의미하며, 애드혹 네트워크는 P2P 방식을 사용합니다. 하지만 애드혹은 네트워크 구성 형태 자체를 지칭합니다. - ㅁ. Mesh Network: 노드들이 그물처럼 서로 연결되어 데이터를 전달하는 구조로, 안정성이 높습니다. 애드혹 네트워크의 한 형태일 수 있습니다. - 나머지 보기들은 문제 설명과 직접적인 관련이 적습니다.