모듈1. SW 생명 주기(SW Life Cycle)
1) SW의 중요 조건: 효율성과 정확성
* D&C 기법: Devide and Conquer(작은 것으로 나눠 작은 것부터 때려잡기)
* 25~50줄이 1 unit이 됨 -> 이 unit들을 call 하며 사용
2) SW 생명 주기(software life cycle)
(1) 요구 분석(Requirement Analysis): 회사의 입장에서는 고객의 요구사항이다. ⭐
- User의 요구 사항을 바탕으로, 문제에 대해 해답이 될 수 있는 요건들을 정의함
- 최선의 해결 방법을 위해 이해가 충돌되는 상호간의 문제점을 모두 이해하는 데 도움이 되는 과정임
- 목표 SW의 필수 및 선택 요건을 구분함
- 요구 명세서(Requirement Specification)를 작성함
(2) 시스템 명세(System Specification): 스펙은 형식에 맞춰 작성하는 것. 설계를 제대로 하기 위한 과정이다.
- 시스템 명세란?
- 시스템이 무엇을 수행해야 되는가를 정밀하게 정의
- 기능적 명세(functional specification)를 통해 정의
(SW의 기능인 Input, 처리, Output에 대한 명세를 포함하며 User와 SW 구현자 간의 구체적인 합의사항임)
(3) 설계(Design): 설계 단계가 잘 되어 있을수록 구현이 쉬워진다.⭐
- 설계
- 시스템 명세 단계에서 정의된 기능을 수행할 방법. 즉, SW 시스템의 전체적인 Algorithm을 작성하는 것
- 추상적으로 "무엇(what)"에서부터 구체적으로 "어떻게(how)"로의 계속적인 변환을 수행하는 과정 - 설계 방법
1️⃣ 하향식 설계(top-down design) - 큰 일 쪼개기(D&C 기법)
- 단계별 세분화(stepwise refinement)라고도 함
- 하나의 큰 문제를 여러 개의 작은 문제로 분해함으로써 문제 전체를 해결
2️⃣ 상향식 설계(bottom-up design) - 큰 일 만들기
- 기존에 개발되어 이용할 수 있는 것들이 있으면 이것을 재사용해 나가면서 전체 목적을 달성하려는 것
- 객체지향 설계(object-oriented design) 방법과 유사함
(4) 구현(Implementation): 프로그래밍 언어를 구사하는 단계이다.
- 구현: 설계된 Algorithm을 특정 Programming Language로 변환하는 것.(즉, 코딩하는 것)
- 프로그램 구현의 기본 원칙
1️⃣ Structured Programming
- 지정문, 조건문, 반복문을 이용하여 프로그램을 작성
- 정확성 증명이 쉬움
- 프로그램의 유지 보수와 디버깅(debugging)이 쉬움
2️⃣ Modular Programming
- 프로그램을 여러 Module로 나눠, 계층 형태의 관계를 갖도록 구성
- 외부에 영향을 주지 않고, Module 구현을 보다 효율적으로 구현하기 용이함
* Module: 하나의 기능만을 수행하는 서브 프로그램. 하나의 진입점과 하나의 진출점을 가짐
(5) 검사(Test): 검사 후 해당 SW를 판매한다.
- Test의 목적: SW에 내재되어 있는 Error를 찾는 것
- Test의 3단계(내부 설계)
1️⃣ 단위 검사(unit test): 각 Modul별로 제공된 Test Data로 검사
2️⃣ 통합 검사(integration test): 몇 개의 요소들을 그룹으로 통합시켜 검사
3️⃣ 시스템 검사(system test): 완성된 시스템이 기능적 명세에 따라 정확하게 동작하는 가를 진단 - 인수 검사(acceptance test): 개발 완료된 SW를 공식적으로 인수하기 전에 SW 주문자 측에서 자체 검사를 수행함
- 벤치마크 Test: 경쟁적인 시스템과 성능 비교
- 베타 검사(beta test): 초기 버전의 SW를 배포하여 사용하게 함으로써 검출되지 않은 Error나 결함을 찾으려는 방법 - Test는 SW의 정확성을 확신하려는 것 O, 보장하려는 것 X ⭐
- 정확성 보장을 위해서는 프로그램 증명(program verification) 과정이 필요하며, 100% 보장할 수 없음
(6) 유지 보수(Maintenance): 이것 또한 유료 서비스이다.
- 유지 보수: 완성된 SW를 "사용하기 시작한 이후"부터의 모든 활동
- 유지 보수가 필요한 경우
- Test 단계에서 발견이 안된, Error나 버그가 추후 발견되어 수리해야 되는 경우
- SW 설계될 때와 달리, 실제 운영 환경이 변경되어 SW를 교정(tuning)해야 하는 경우
- 시스템 성능 향상이나 User의 추가 요구에 따라 SW를 갱신해야 되는 경우
* Input + Output + 내가 할 일 = Interface Module
모듈2. 데이터 추상화(Data Abstraction)
1) Data의 추상화
- 크고 복잡한 문제의 해결 방법 = 추상화
- 추상화(abstraction) = 구조 + 연산
: 자세한 것은 무시하고 필수적이고 중요한 속성만을 골라서 단순화시키는 과정 - Data 추상화(data abstraction)
- 프로그램 속의 복잡한 Data에 추상화 개념을 적용하여 단순화
- 기존의 잘 정의된 개념들을 이용하여 표현
2) Data vs Data Type
- Data
- 프로그램의 처리 대상이 되는 모든 것
- 특별히 값(value) 자체를 의미하기도 함 - Data Type
- 1️⃣Data의 집합과, 이 Data에 적용할 수 있는 2️⃣연산의 집합
- 종류
(1) 시스템 정의(system-defined) Data Type
1️⃣ 원시(primitive) Data Type / 단순(simple) Data Type
2️⃣ 복합(composite) Data Type / 구조화(structured) Datat Type
(2) User 정의(user-defined) Data Type
: 기존의 Data Type을 이용해 정의. 일단 정의만 되면, 시스템 정의 Data Type과 똑같이 사용할 수 있음
3) 추상 Data Type
- Abstract Data Type: ADT -> 디자인 단계
- Data Type의 논리적 정의
- Data와 연산의 본질에 대한 명세만 정의한 Data Type
- 1️⃣"Data가 무엇"이고, 2️⃣"각 연산이 수행하는 기능"만을 정의
- Data의 구조, 연산의 자세한 구현 방법은 포함시키지 않음(구현과는 거리가 멀다)
- 기존의 Data Type을 이용하여 정의
- 자연수(Natno) Abstract Data Type
- 특정 언어를 몰라도 어떤 기능(연산)이 탑재되어 있는지 한 눈에 알 수 있음
- 타인에게 내가 작성한 "Natno" 프로그램을 공지할 때 유용
- ADT는 프로그램 수준이 아니라 알고리즘 수준이다.
모듈3. Algorithm과 문제 해결
1) Algorithm
- 어떤 문제를 해결하기 위해 명확히 정의된 유한 개의 규칙과 절차의 모임
- 명확히 정의된 한정된 개수의 규제나 명령의 집합이며, 한정된 규칙을 적용함으로써 문제를 해결하는 것
2) 프로그램(program)
- Algorithm을 컴퓨터가 이해하고, 실행할 수 있는, 특정 Programming Language로 표현된 것
Program = data structures + algorithm
3) Algorithm의 조건
1️⃣ 입력: 외부에서 제공되는 자료가 있을 수 있다.
2️⃣ 출력: 적어도 한 가지 결과가 생긴다.
3️⃣ 명백성: 각 명령들은 명백해야 한다.
4️⃣ 유한성: 알고리즘의 명령대로 수행하면 한정된 단계를 처리한 후에 종료된다.
5️⃣ 효과성: 모든 명령들은 명백하고 실행 가능한 것이어야 한다.
모듈4. Algorithm의 표현
1) ADL(Algorithm Description Language)
- Algorithm 기술을 위해 정의한 언어
- 1️⃣사람이 이해하기 쉽고, 2️⃣Programming Language로의 변환이 용이
- 의사 코드(pseudo-code): ADL과 약간의 자연어로 기술한 것
- ADL 변환기: ADL Algorithm에서 특정 프로그램으로의 변환
- ADL의 Data: 숫자, 부울(boolean)값, 문자
- ADL의 명령문
- 종류: 지정문, 조건문, 반복문, 함수문, Input문, Output문
- 명령문 끝에는 세미콜론(;)을 사용
2) ADL 지정문
- 지정문(assignment)
- 형식: 변수 <- 식;
- 식(expression)
1️⃣ 산술식(Arithmetic exp): +, -, *, %, / 등
2️⃣ 부울식(Boolean exp): 참 또는 거짓의 결과. 논리 연산자(and, or, not) 혹은 관계 연산자(<, >, 등)로 표현
3️⃣ 문자식(Character exp)
- 제어 구조: 순차적
3) ADL 조건문
- 조건문
- 제어 구조: 선택적
- 종류: if문과 case문 - if문
if (condition) then S1
else S2
- case문
case {
condition 1:S1
condition 2:S2
.
.
.
condition n:Sn
else : Sn+1
}
4) ADL 반복문
- 반복문(Repeat)
- 제어 구조: 일정한 명령문 그룹을 반복해서 수행하는 루프(loop) 형태
eg) OS 프로그램의 전원 유지
- 종류: while문, for문, do-while문 - while문
while (condition) do //형식
while (true) do //무한 루프
- for문
- do-while문
do S //S가 최소한 한 번은 실행됨 while(condition);
- 루프 명령문
- goto label 명령문: 루프에서 특정 label로 빠져나갈 때 사용
- exit문: 자신을 둘러싸고 있는 가장 가까운 루프 밖의 명령문으로 제어를 이동시킴
5) ADL 함수문
function-name(parameter_list) /*형식 매개 변수*/
S
end
- 호출한 함수로의 복귀 방법(return)
return expr; (여기서 expr은 함수의 실행 결과) - 함수 호출
- function-name(argument-list); -> 호출 시에는 argument라고 함!
- 함수를 부르는 인자 리스트(Argument-list)는 1️⃣타입과 2️⃣개수가,
함수의 형식 매개 변수(Parameter-list)와 대응되어야 함
* 함수 호출시 함수에 전달할 때 argument(인자), 함수 선언시 parameter(매개변수)라고 함 - 인자와 매개변수와의 연관
- 값 호출(call by value) 규칙⭐ <-> call by reference
- 각 인자의 실제 값이 호출된 함수의 각 매개 변수로, 위치적 전달
- 인자의 값이 주소(참조, address)가 되면, 매개 변수에 주소(address) 값이 전달됨.
이때, 주소를 따라가면 Data를 얻게 됨
6) ADL Input/Output문
- Input 함수: read(argument_list);
- Output 함수: print(argument_list);
- 인자: 변수나 인용부호가 있는 문자열
7) ADL 기타
* ADT안에 ADL이 들어감
- 기타 명령문
- stop: 현재 진행 중인 함수의 실행을 정지
- 코멘트: //는 그 행 끝까지, /**/은 코멘트의 시작과 끝 표시
- 배열 - ADL 기술 규칙
1️⃣ 함수의 Input, Output 변수를 명확히 명세
2️⃣ 변수의 의미를 알 수 있게 정의
3️⃣ Algorithm의 제어 흐름은 되도록 순차적
4️⃣ 시각적 구분을 위해 들여쓰기(indentation)을 이용
5️⃣ 코멘트는 짧으면서, 의미는 명확히
6️⃣ 함수를 적절히 사용