소프트웨어의 특징이 아닌 것은 마모성이다. 소프트웨어는 물리적 실체가 없어 사용할수록 닳지 않는다.
하드웨어는 부품 마모로 고장률이 올라가지만, 소프트웨어의 결함은 마모가 아니라 변경 과정에서 유입된 오류로 생긴다.
- 순응성: 사용자 요구·환경 변화에 맞추어 계속 변경되어야 하는 성질로, 소프트웨어의 특징이다.
- 복잡성: 구성 요소와 상태 수가 매우 많아 이해·관리가 어려운 성질로, 소프트웨어의 특징이다.
- 비가시성: 구조가 눈에 보이지 않아 형태를 파악하기 어려운 성질로, 소프트웨어의 특징이다.
(나) 요구사항 검증
(다) 요구사항 추출
(라) 요구사항 명세
요구 분석 작업은 추출 → 분석 → 명세 → 검증 순서이므로 (다)→(가)→(라)→(나)가 옳다.
이해관계자로부터 요구사항을 추출하고, 분석으로 충돌·누락을 정리한 뒤 명세서로 문서화하며, 마지막으로 명세가 고객 의도와 맞는지 검증한다.
- 추출 → 명세 → 검증 → 분석 순서는 분석 없이 문서화·검증부터 하게 되어 틀리다.
- 명세 → 분석 → 추출 → 검증 순서는 요구사항을 수집하기도 전에 명세부터 작성하므로 틀리다.
- 명세 → 추출 → 분석 → 검증 순서도 명세가 추출·분석보다 앞서 있어 틀리다.
기능 단위로 분해해 결합도를 낮추고 독립성을 높이는 설계 원칙은 모듈화이다.
모듈화는 시스템을 독립적인 모듈로 나누어 결합도는 낮추고 응집도는 높이는 것을 목표로 하며, 이해·수정·재사용을 쉽게 한다.
- 다형성: 같은 메시지에 객체마다 다르게 반응하는 객체지향 성질로, 기능 분해 원칙이 아니다.
- 추상화: 본질적인 특징만 남기고 세부 사항을 감추는 원리로, 분해 자체를 뜻하지 않는다.
- 연산자 오버로딩: 같은 연산자를 자료형에 따라 다르게 정의하는 언어 기능이다.
옳지 않은 설명은 신뢰성·성능·안전성을 기능적 요구사항으로 본 것이다. 이들은 시스템이 얼마나 잘 동작해야 하는지를 규정하는 비기능적 요구사항이다.
기능적 요구사항은 시스템이 수행할 기능(입력·처리·출력)을 정의하고, 비기능적 요구사항은 품질 속성과 제약 조건을 정의한다.
- MTBF는 평균 고장 시간 간격으로, 평균 무고장 시간(MTTF)과 평균 수리 시간(MTTR)의 합이므로 옳다.
- 운영체제·개발 언어를 지정하는 것은 구현 제약 조건이므로 비기능적 요구사항이 맞다.
- 가용성은 이므로 MTTF를 늘리고 MTTR을 줄이면 높아진다.
(나) 통합 프로세스 모델(unified process model)
(다) V 모델(V model)
B. 위험분석 단계가 존재해 처음부터 위험에 대해 고려하면서 개발을 진행한다.
C. 개발과정은 크게 4단계(도입, 정련, 구축, 전이)로 나뉘고 각 단계도 여러 개의 작은 단위로 나뉘며, 한 번 반복이 끝나면 실행 가능한 산출물이 도출된다.
나선형 모델은 B, 통합 프로세스 모델은 C, V 모델은 A에 해당하므로 B C A로 연결된다.
나선형 모델은 반복마다 위험 분석을 수행하는 것이 핵심이고, 통합 프로세스는 도입·정련·구축·전이 4단계를 반복한다. V 모델은 각 개발 단계에 대응하는 테스트 단계를 짝지어 검증에 초점을 둔다.
- A B C 연결은 나선형 모델에 V 모델의 설명을, 통합 프로세스에 나선형 모델의 설명을, V 모델에 통합 프로세스의 설명을 붙여 모두 어긋난다.
- A C B 연결은 통합 프로세스는 맞지만 나선형과 V 모델의 설명이 서로 바뀌어 틀리다.
- C A B 연결은 세 모델의 설명이 모두 어긋나 틀리다.
| 계약 기간 | 10개월 |
| 추정 소스코드 라인 수 | 100,000 LOC |
| 개발자 1인당 월평균 생산성 | 1,000 LOC/MM(Man Month) |
| 현재 개발자 수 | 7명 |
추가로 투입할 최소 인원은 3명이다.
총 노력 = 규모 ÷ 생산성
필요 인원 = 총 노력 ÷ 계약 기간
명
현재 7명이므로 명을 추가 투입해야 한다.
○ 테스트 수행 결과가 참인지 거짓인지를 판단하기 위해 미리 정의된 참값과 비교하는 테스트 기법
실행 결과가 맞는지 판정하는 기준·메커니즘은 테스트 오라클이다.
오라클은 기대 결과(참값)를 제공해 실제 결과와 비교함으로써 통과·실패를 판정한다.
- 테스트 케이스: 입력값·실행 조건·기대 결과를 묶은 테스트 단위로, 판정 메커니즘 자체는 아니다.
- 테스트 하니스: 드라이버·스텁·스크립트 등 테스트 실행을 지원하는 도구와 환경의 모음이다.
- 테스트 드라이버: 하위 모듈을 호출해 실행시키는 임시 상위 모듈로, 상향식 통합에 쓰인다.
XP의 특징이 아닌 것은 짝으로 작업하지 않는다는 설명이다. XP는 두 개발자가 함께 코드를 작성하는 짝 프로그래밍을 핵심 실천법으로 둔다.
XP는 짧은 반복, 고객 참여, 지속적 통합·리팩토링으로 변화에 빠르게 대응하는 애자일 방법론이다.
- 테스트를 먼저 작성하고 코드를 구현하는 테스트 우선 개발은 XP의 실천법이다.
- 작은 단위로 자주 릴리스해 고객의 평가를 받는 것도 XP의 특징이다.
- 요구사항을 사용자 스토리로 표현하고 이를 기반으로 계획을 세우는 것도 XP의 특징이다.
두 입력 요소의 모든 조합만 보장하도록 케이스 수를 줄이는 기법은 페어와이즈 조합이다.
결함 대부분이 한두 요소의 상호작용에서 생긴다는 점을 이용해, 전체 조합 대신 모든 2요소 쌍이 최소 한 번씩 나타나도록 케이스를 구성한다.
- 결정 테이블: 조건 조합과 그에 따른 동작을 표로 정리해 케이스를 도출하는 기법이다.
- 동등분할: 입력 영역을 같은 처리를 받는 클래스로 나누어 대표값을 고르는 기법이다.
- 경곗값 분석: 오류가 많은 입력 범위의 경계 부근 값을 집중 테스트하는 기법이다.
옳지 않은 설명은 변경 요청·심사·실시·확인을 형상 식별의 세부 절차로 본 것이다. 이 절차는 형상 통제(변경 통제)에 해당한다.
형상 식별은 관리 대상 형상 항목을 정하고 이름·버전을 부여하는 활동이며, 형상 관리는 식별·통제·상태 보고·감사로 이루어진다.
- 형상 상태 보고를 통해 제품의 변경 상태 정보를 제공하므로 옳다.
- 변경을 체계적으로 관리해 품질을 높이고 유지보수를 쉽게 하므로 옳다.
- 개발 중 변하는 형상을 체계적으로 관리·유지하는 기법이라는 정의는 옳다.
temp = []
i = 0
d = 2
arr = [1, 2, 3, 4, 5]
while (i < d):
temp.append(arr[i])
i = i + 1
i = 0
while (d < len(arr)):
arr[i] = arr[d]
i = i + 1
d = d + 1
arr[:] = arr[: i] + temp
이 코드의 순환 복잡도는 3이다. 조건 판단 지점인 while 문이 2개이므로 판단 수에 1을 더한다.
(: 조건 판단 노드 수)
나머지 대입문과 리스트 연산은 분기를 만들지 않으며, 제어 흐름 그래프로 그려도 영역 수가 3으로 같다.
유지보수 비용이 가장 많이 드는 유형은 완전 유지보수이다. 기능 추가·성능 개선 요구가 운영 기간 내내 계속 발생하기 때문이다.
일반적으로 알려진 유지보수 비중은 완전 유지보수가 가장 크고, 예방 유지보수가 가장 작다.
- 적응 유지보수: 운영체제·하드웨어 등 환경 변화에 맞추는 활동으로, 완전 유지보수보다 비중이 작다.
- 수정 유지보수: 운영 중 발견된 오류를 고치는 활동으로, 흔한 인식과 달리 비중이 가장 크지 않다.
- 예방 유지보수: 앞으로의 문제에 대비해 구조를 개선하는 활동으로, 비중이 가장 작다.
| Figure |
|---|
| #color -area |
| +fill_color() +erase() +set_area() |
다이어그램에 나타난 개념은 캡슐화와 정보은닉이다.
Figure 클래스는 속성(color, area)과 이를 다루는 연산(fill_color, erase, set_area)을 하나로 묶고 있어 캡슐화를 보여 준다. 또 area는 private(-), color는 protected(#)로 외부 접근을 제한하고 public(+) 연산으로만 다루게 하므로 정보은닉이 표현되어 있다.
- 상속: 부모·자식 클래스나 일반화 화살표가 없는 단일 클래스이므로 표현되지 않는다.
- 다형성: 같은 연산을 하위 클래스가 재정의하거나 오버로딩한 구조가 없으므로 표현되지 않는다.

UML 상태머신의 전이 레이블은 trigger [ condition ] / effect 형식으로 쓴다.
전이 문법은 이벤트 [가드 조건] / 동작이다. 가드 조건은 대괄호로 감싸고, 전이 시 수행할 효과(effect)는 슬래시 뒤에 적는다.
- trigger [ condition ] : effect — 효과 앞에 콜론이 아니라 슬래시를 써야 하므로 틀리다.
- trigger { condition } / effect — 중괄호는 제약조건 표기이고 가드 조건은 대괄호로 써야 하므로 틀리다.
- trigger { condition } : effect — 가드 괄호와 효과 구분자가 모두 틀리다.
(나) 액티비티 다이어그램
(다) 시퀀스 다이어그램
B. 사용 사례를 이루는 객체들이 어떻게 메시지를 보내 협력 하는지를 시간의 흐름에 따라 표시한다.
C. 복잡한 시스템 작업의 병행 처리를 위해 포크(fork), 조인(join)을 이용한다.
커뮤니케이션 다이어그램은 A, 액티비티 다이어그램은 C, 시퀀스 다이어그램은 B에 해당하므로 A C B로 연결된다.
커뮤니케이션 다이어그램은 객체 간 연결 관계를 중심으로 메시지를 네트워크 형태로 보이고, 시퀀스 다이어그램은 같은 상호작용을 시간 순서로 표현한다. 액티비티 다이어그램은 포크·조인으로 병행 흐름을 나타낸다.
- A B C 연결은 액티비티와 시퀀스 다이어그램의 설명이 서로 바뀌어 틀리다.
- B C A 연결은 커뮤니케이션과 시퀀스 다이어그램의 설명이 서로 바뀌어 틀리다.
- C A B 연결은 커뮤니케이션과 액티비티 다이어그램의 설명이 서로 바뀌어 틀리다.
- Rectangle 클래스의 Area 함수는 (Height * Width)를 return하고, Square 클래스의 Area 함수는 (Side * Side)를 return 한다.

이 설계가 위반한 원리는 리스코프 치환 원리이다.
Square는 Rectangle을 상속하지만 Height·Width 대신 Side 하나로 넓이를 계산하는 다른 Area를 가진다. Rectangle을 사용하는 User에게 Square를 넣으면 Height와 Width를 따로 설정해 넓이를 구하는 기대 동작이 성립하지 않으므로, 하위 클래스가 상위 클래스를 대체할 수 없다.
- 개방-폐쇄 원리: 확장에는 열고 수정에는 닫으라는 원리로, 이 다이어그램의 핵심 문제는 상속 관계의 치환 불가이다.
- 단일 책임의 원리: 각 클래스는 넓이 계산이라는 하나의 책임만 지므로 위반으로 보기 어렵다.
- 의존 관계 역전의 원리: 추상화에 의존하라는 원리로, 상속한 하위 타입의 행위 불일치와는 다른 문제이다.
(나)은 사용자의 기초적인 요구를 최대한 반영한 소규모 모형을 개발하여 이를 기반으로 더욱 구체적인 요구 분석을 가능하게 하는 방법이다. 주요 목적은 소프트웨어 엔지니어의 아이디어에 대한 피드백을 조기에 받아 요구사항을 취합하는 것이다.
(가)는 브레인스토밍, (나)는 프로토타이핑이다.
판단·비판을 유보하고 그룹 토론으로 아이디어를 최대한 끌어내는 것은 브레인스토밍의 특징이다. 소규모 모형을 만들어 사용자 피드백을 조기에 받는 것은 프로토타이핑이다.
- 인터뷰는 이해관계자와의 질의응답으로 정보를 얻는 방법으로, 비판 유보를 전제로 한 그룹 아이디어 발상과는 다르다.
- 관찰은 사용자의 실제 업무 수행을 지켜보며 요구를 파악하는 방법으로, 모형을 만들어 피드백을 받는 방법이 아니다.
(나) 빅뱅 테스팅을 수행하기 위해서는 A부터 G까지의 모든 모듈을 한꺼번에 연결하여 테스팅을 수행한다.
(다) 하향식 기법을 수행하기 위해서는 스텁(stub) 모듈이 필요하다.
(라) 상향식 기법을 수행하기 위해서는 드라이버(driver) 모듈이 필요하다.

제시된 네 설명은 모두 옳다.
모듈 구조는 A 아래에 B·C·D가 있고, B 아래에 E, C 아래에 F·G가 있는 계층이다. 하향식은 최상위 모듈부터 내려가며 아직 없는 하위 모듈을 스텁으로 대신하고, 상향식은 최하위 모듈부터 올라가며 상위 모듈을 드라이버로 대신한다.
- (가) 하향식 통합은 최상위 모듈인 A부터 시작하므로 옳다.
- (나) 빅뱅 테스팅은 A부터 G까지 모든 모듈을 한꺼번에 결합해 시험하므로 옳다.
- (다) 하향식에서는 호출될 하위 모듈이 아직 없으므로 이를 흉내 내는 스텁이 필요하다.
- (라) 상향식에서는 하위 모듈을 호출해 줄 상위 모듈이 없으므로 테스트 드라이버가 필요하다.
#include <stdio.h>
int sum_array(int *arr, int length) {
int i, ret;
ret = 0;
for (i = 0; i < length; i++)
ret += arr[i];
return ret;
}
int main() {
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
printf("%d", sum_array(a, 10));
return 0;
}
이 코드에 나타나는 결합도는 스탬프 결합도이다. main이 sum_array에 배열(자료구조)을 인자로 넘기기 때문이다.
스탬프 결합도는 모듈 간에 배열·구조체 같은 자료구조를 전달할 때 생기며, 단순 값만 주고받는 데이터 결합도보다 강하다.
- 제어 결합도: 상대 모듈의 처리 흐름을 지시하는 플래그 등을 넘길 때로, 이 코드에는 제어 정보 전달이 없다.
- 외부 결합도: 외부에 선언된 데이터·파일·장치 형식을 공유할 때로, 이 코드는 외부 데이터를 공유하지 않는다.
- 데이터 결합도: 스칼라 값 같은 단순 데이터만 전달할 때로, 배열을 넘기는 이 코드에는 해당하지 않는다.
적절하지 않은 것은 절차적 – 순차적 – 시간적 응집이다. 순차적 응집이 절차적 응집보다 강하므로 순서가 뒤집혀 있다.
응집도는 강한 것부터 기능적 – 순차적 – 교환적 – 절차적 – 시간적 – 논리적 – 우연적 순이다.
- 절차적 – 시간적 – 논리적 응집은 강한 순서를 지키므로 적절하다.
- 교환적 – 절차적 – 시간적 응집은 강한 순서를 지키므로 적절하다.
- 순차적 – 교환적 – 논리적 응집은 중간 단계를 건너뛰었지만 강한 순서는 지키므로 적절하다.

설명된 디자인 패턴은 Proxy 패턴이다.
X는 실제대상과 같은 인터페이스를 구현해 클라이언트 요청을 받고, 내부에 실제대상을 참조하다가 request() 실행을 위임한다. 클라이언트는 대리 객체와 실제 객체를 구분하지 못한 채 사용하므로 대리인을 통한 접근 제어 구조이다.
- Bridge 패턴: 추상화 계층과 구현 계층을 분리해 독립적으로 확장하는 구조로, 같은 인터페이스의 대리 객체가 위임하는 형태가 아니다.
- Adapter 패턴: 호환되지 않는 기존 인터페이스를 클라이언트가 기대하는 인터페이스로 변환하는 것으로, 여기서는 X와 실제대상의 인터페이스가 같다.
- Chain of responsibility 패턴: 요청을 처리할 수 있는 객체가 나올 때까지 여러 처리 객체의 사슬로 넘기는 행위 패턴이다.
if ((x > 5) || (y > 10) || (z < 8)) {
z = x + y;
z = z - 1;
}
if ((x > 8) && (z > 9)) {
z = z + 1;
}분기 커버리지는 75%, 조건 커버리지는 70%이다. 첫 번째 if의 거짓 분기와 일부 조건의 한쪽 결과가 실행되지 않는다.
Test case 1 (10, 10, 10): 첫 if는 x>5가 참이라 참, z = 10+10−1 = 19. 둘째 if는 x>8 참, z>9 참으로 참.
Test case 2 (8, 7, 5): 첫 if는 x>5와 z<8이 참이라 참, z = 8+7−1 = 14. 둘째 if는 x>8 거짓, z>9 참으로 거짓.
분기: 첫 if 참, 둘째 if 참·거짓만 실행
조건: x>5(참만), y>10(거짓만), z<8(참·거짓), x>8(참·거짓), z>9(참만)
최적화 단계에 해당하는 프로세스 영역은 근본 원인 분석 및 해결이다.
최적화 단계는 결함·문제의 근본 원인을 찾아 제거하고 조직 차원의 성과를 관리해 프로세스를 지속적으로 개선하는 단계이다.
- 제품 통합: 정의 단계에 속하는 엔지니어링 프로세스 영역이다.
- 형상 관리: 관리 단계에 속하는 지원 프로세스 영역이다.
- 협력 업체 관리: 관리 단계에 속하는 프로젝트 관리 프로세스 영역이다.
(나) 규모 추정
(다) 노력 산정
(라) 기능 점수 보정
(마) 소요 기간 산정
기능 점수 기반 비용 산정은 기능 점수 계산 → 보정 → 규모 추정 → 노력 산정 → 소요 기간 산정 순으로 수행한다.
기능 유형별 점수로 미조정 기능 점수를 구하고 시스템 특성으로 보정한 뒤, 이를 규모로 삼아 노력(인월)을 산정하고 노력과 투입 인력으로 기간을 도출한다.
- 소요 기간을 노력보다 먼저 산정하는 순서는 기간 산정의 근거인 노력이 없어 틀리다.
- 규모 추정을 맨 앞에 두고 노력 → 기간으로 가는 순서는 규모의 근거인 기능 점수 계산보다 규모 추정이 앞서 틀리다.
- 규모 추정을 맨 앞에 두고 기간을 노력보다 먼저 산정하는 순서는 두 가지가 모두 어긋나 틀리다.
| 작업 이름 | A | B | C | D | E | F | G | H | I | J | 종료 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 선행 작업 | - | A | A | C, E | B | E | F | D, G | H | I | J |
| 수행 기간 (개월) | 2 | 4 | 5 | 2 | 2 | 2 | 1 | 2 | 1 | 2 | - |
옳지 않은 것은 H작업 완료에 최소 11개월이 필요하다는 설명이다. H는 11개월 시점에 시작해 13개월에 완료된다.
가장 이른 완료 시점: A 2, B 6, C 7, E 8, D max(7, 8)+2 = 10, F 10, G 11, H max(10, 11)+2 = 13, I 14, J 16.
임계 경로는 A→B→E→F→G→H→I→J로 총 16개월이다.
- D는 10개월에 끝나지만 H는 G가 끝나는 11개월에 시작하므로 여유가 1개월 있어 임계 경로에 포함되지 않는다.
- 임계 경로 길이가 16개월이므로 개발 종료까지 최소 16개월이 걸린다.
- C는 D의 가장 늦은 시작 시점인 9개월(11−2)까지만 끝나면 되므로 여유는 9−7 = 2개월이다.