[TIL/정처기] 2025/03/20
23년 2회 기출 코드 정리 ✍️ 23-2-1-C ⚙️ 실행 결과가 "43215"일 때 빈칸에 들어갈 알맞은 식을 물어본 코드. 답은 . 에 대해서 순차적으로 어떠한 처리를 했는데 가 나왔다. n[i]에 대한 연산을 하면 n[i+1]이 나오다가, n[4]에 대한
23년 2회 기출 코드 정리 ✍️
23-2-1-C ⚙️
실행 결과가 "43215"일 때 빈칸에 들어갈 알맞은 식을 물어본 코드. 답은 ``n[(i+1) % 5]``.
#include <stdio.h>
main(){
int n[] = {5,4,3,2,1};
for(int i =0; i < 5; i++)
printf("%d", (빈칸));
}
빈칸에 n[i+1]만 넣으면 n[3]까지는 유효하나 n[4]에서는 없는 값을 출력하려 시도하게 된다. 즉 0을 넣으면 1, 1을 넣으면 2 ... 이런 식으로 돌아가다가 4를 넣으면 0이 되어야 한다.
5로 나눈 나머지 값을 인덱스로 부여하겠다고 접근하면 가능하다. 4+1, 즉 5를 5로 나눈 나머지 값은 0이 되기 때문이다. 차근차근 접근하면 충분히 맞출 수 있는 문제라고 본다.
**23-2-2-C ⚙️**
a, b, c, d에 대한 연산이 빈칸으로 주어졌던 코드. 4620원을 지불하기 위해 각각의 화폐가 몇 개씩 필요한지를 묻는 코드였다.
#include
main(){ int m = 4620; int a = m / 1000; int b = m % 1000 / 500; int c = m % 500 / 100; int d = m % 100 / 10; printf("1000원의 개수 : %d\n", a); printf("500원의 개수 : %d\n", b); printf("100원의 개수 : %d\n", c); printf("10원의 개수 : %d\n", d); }
우리가 원하는 a 값은 4다. 따라서 4620으로부터 4를 얻어내기 위해서는, 해당 숫자를 1000으로 나눈 몫을 가져오면 된다.
b 값은 1이 되어야 한다. 4620원 중 4000원을 냈으니, 500원은 한 개 필요하다. 즉 620을 500으로 나누었을 때의 몫이 필요하다. 620은 4620을 1000으로 나누었을 때의 나머지다.
c와 d를 구하는 논리는, b를 구할 때의 논리와 완전히 동일하므로 생략한다. 최종적으로 a, b, c, d는 각각 4, 1, 1, 2가 된다.
**23-2-3-C ⚙️**
"홍길동", "김철수", "박영희"를 차례로 입력했을 때의 실행 결과
#include
char n[30]; char getname(){ printf("이름 입력 : "); gets(n); return n; }
main(){ char n1 = getname(); char n2 = getname(); char n3 = getname(); printf("%s\n", n1); printf("%s\n", n2); printf("%s\n", n3); }
getname() 함수는 사용자로부터 이름을 입력받아 메모리에 해당 입력을 저장한다. 최종적으로 반환하는 것은 해당 배열의 포인터 주소다. 즉 n1, n2, n3는 모두 배열 n의 포인터 주소가 된다.
다른 이름을 계속해서 동일한 배열의 포인터 주소에 저장하니, 결국 마지막에 입력받은 이름만 세 번 출력하게 된다.
**23-2-5-C ⚙️**
#include
main(){ int n[] = {73,95,82}; int sum = 0; for(int i = 0; i < 3; i++) sum += n[i]; switch (sum / 30) { case 10: case 9: printf("A"); case 8: printf("B"); case 7: case 6: printf("C"); default: printf("D"); } }
해당 코드는 switch문에서 break가 없을 때의 동작(fall-through)을 묻고 있다고 해석할 수 있다. 최종 출력 결과는 BCD.
**23-2-7-C ⚙️**
#include
main(){ int c = 0; for(int i = 1; i <= 2023; i++) if(i % 4 == 0) c ++; printf("%d", c); }
2023안에 포함된 4의 배수를 세는 간단한 알고리즘이다. 출력 결과는 505.
**23-2-9-C ⚙️**
#include
int isWhat[MAX_SIZE]; int point = -1;
int isEmpty(){ if(point == -1) return 1; return 0; }
int isFull(){ if(point == 10) return 1; return 0; }
void into(int num){ if(isFull() == 1) printf("Full"); else isWhat[++point] = num; }
int take(){ if(isEmpty() == 1) printf("Empty"); else return isWhat[point--]; return 0; }
main(){ into(5); into(2); while (!isEmpty()) { printf("%d", take()); into(4); into(1); printf("%d", take()); into(3); printf("%d", take()); printf("%d", take()); into(6); printf("%d", take()); printf("%d", take()); } }
이 코드는 배열을 이용한 스택(Stack) 자료구조의 구현을 묻는 문제로, into()를 통해 데이터를 push 하고, take()를 통해 데이터를 pop 하며, isEmpty()와 isFull()로 스택의 상태를 확인하는 방식이다. point 변수로 스택의 최상단(top)을 관리하며, 후입선출(LIFO, Last In First Out) 원칙을 따르는지를 확인하는 것이 핵심이다. 어렵다기보다는 복잡한 코드에 가까우니, 이런 문제가 나오면 다른 문항을 먼저 다 풀고 접근하는 것이 좋겠다.
**23-2-14-JAVA ⚙️**
public class Test { public static void main(String[] args) { String str1 = "Programming"; String str2 = "Programming"; String str3 = new String("Programming"); System.out.println(str1 == str2); System.out.println(str1 == str3); System.out.println(str1.equals(str3)); System.out.println(str2.equals(str3)); } }
"Programming"은 String Constant Pool에 저장되고 str1이 이를 참조하게 된다. 이후 str2는 이미 있는 "Programming"을 참조한다. 즉 str1과 str2의 주소값은 동일하다.
23-2-18-C ⚙️
#include <stdio.h>
main(){
int E[] = {64,25,12,22,11};
int n = sizeof(E) / sizeof(E[0]);
int i = 0;
do {
int j = i + 1;
do {
if(E[i] > E[j]){
int tmp = E[i];
E[i] = E[j];
E[j] = tmp;
}
j++;
} while (j < n);
i++;
} while (i < n - 1);
for(int i = 0; i <= 4; i++)
printf("%d ", E[i]);
}해당 코드는 선택 정렬(Selection Sort)을 do-while 문으로 구현한 것으로, 배열 E[]의 원소를 오름차순 정렬하는 것이 핵심이다. i를 기준으로 이후 모든 원소j와 비교하여 더 작은 값이 있으면 교환(Swap)하는 방식으로 정렬을 수행하며, 최종적으로 정렬된 배열을 출력한다.
23-2-19-Python ⚙️
a = "engineer information programming"
b = a[:3]
c = a[4:6]
d = a[29:]
e = b + c + d
print(e)b는 eng, c는 ne, d는 ing. 따라서 e는 engneing가 된다. 간단한 파이썬 인덱싱 코드다.
이론 문제 포인트 ✍️
1. UI의 구분 ✅ - ``CLI(Command Line Interface)``: 명령과 출력이 텍스트 형태로 이뤄지는 인터페이스
- ``GUI(Graphical User Interface)``: 아이콘이나 메뉴를 마우스로 선택하여 작업을 수행하는 그래픽 환경의 인터페이스
- ``NUI(Natural User Interface)``: 사용자의 말이나 행동 등 자연스러운 움직임을 통해 기기를 조작하는 인터페이스
2. UI의 기본 원칙 ✅ - ``직관성``: 누구나 쉽게 이해하고 사용할 수 있어야 함
- ``유효성``: 사용자의 목적을 정확하고 완벽하게 달성해야 함
- ``학습성``: 누구나 쉽게 배우고 익힐 수 있어야 함
- ``유연성``: 사용자의 요구사항을 최대한 수용하고 실수를 최소화해야 함
3. 애플리케이션 테스트의 기본 원칙 ✅ - ``파레토 법칙(Pareto Principle)``: 애플리케이션의 20%에 해당하는 코드에서 전체 결함의 80%가 발견된다는 법칙
- ``살충제 패러독스(Pesticide Paradox)``: 동일한 테스트 케이스로 동일한 테스트를 반복하면 더 이상 결함이 발견되지 않는 현상
- ``오류-부재의 궤변(Absence of Errors Fallacy)``: 소프트웨어의 결함을 모두 제거해도 사용자의 요구사항을 만족시키지 못하면 해당 소프트웨어는 품질이 높다고 말할 수 없는 것
4. 프로그램 실행 여부에 따른 테스트 ✅ - ``정적 테스트`` - 프로그램을 실행하지 않고 명세서나 소스 코드를 대상으로 분석하는 테스트 - 소스 코드에 대한 코딩 표준, 코딩 스타일, 코드 복잡도, 남은 결함 등을 발견하기 위해 사용 - 워크스루, 인스펙션, 코드 검사 등
- ``동적 테스트`` - 프로그램을 실행하여 오류를 찾는 테스트 - 소프트웨어 개발의 모든 단계에서 테스트를 수행 - 블랙박스 테스트, 화이트박스 테스트
5. 화이트박스 테스트의 검증 기준 ✅ - ``문장 검증 기준(Statement Coverage)``: 소스 코드의 모든 구문이 한 번 이상 수행되도록 테스트 케이스를 설계
- ``결정 검증 기준(Decision Coverage)``: 소스 코드의 모든 조건문에 대해 조건식의 결과가 True인 경우와 False인 경우가 한 번 이상 수행되도록 테스트 케이스를 설계. 분기 검증 기준(Branch Coverage)이라고도 함
- ``조건 검증 기준(Condition Coverage)``: 소스 코드의 조건식에 포함된 개별 조건식의 결과가 True인 경우와 False인 경우가 한 번 이상 수행되도록 테스트 케이스를 설계
- ``조건/결정 검증 기준(Condition/Decision Coverage)``: 결정 검증 기준과 조건 검증 기준을 모두 만족하는 설계. 조건문이 True인 경우와 False인 경우에 따라 조건 검증 기준의 입력 데이터를 구분하는 테스트 케이스를 설계
- ``변경 조건/결정 검증 기준(Modified Condition/Decision Coverage)``: 조건/결정 검증 기준을 향상시킨 검증 기준. 개별 조건식이 다른 개별 조건식의 영향을 받지 않고 전체 조건식의 결과에 독립적으로 영향을 주도록 테스트 케이스를 설계
- ``다중 조건 검증 기준(Multiple Condition Coverage)``: 소스 코드의 조건문에 포함된 모든 개별 조건식의 모든 조합을 고려하도록 테스트 케이스를 설계
6. 블랙박스 테스트 ✅ - 사용자의 요구사항 명세를 보면서 테스트 - 주로 구현된 기능을 테스트 - 소프트웨어 인터페이스를 통해 실시
7. 블랙박스 테스트의 종류 ✅ - ``동치 분할 검사(Equivalence Partitioning Testing)``: 입력 조건에 타당한 입력 자료와 타당하지 않는 입력 자료의 개수를 균등하게 하여 테스트 케이스를 정하고, 해당 입력 자료에 맞는 결과가 출력되는지 확인하는 기법
- ``경계값 분석(Boundary Value Analysis)``: 입력 조건의 중간값보다 경계값에서 오류가 발생될 확률이 높다는 점을 이용하여 입력 조건의 경계값을 테스트 케이스로 선정하여 검사하는 기법
- ``원인-효과 그래프 검사(Cause-Effect Graphing Testing)``: 입력 데이터 간의 관계와 출력에 영향을 미치는 상황을 체계적으로 분석한 다음 효용성이 높은 테스트 케이스를 선정하여 검사하는 기법
- ``오류 예측 검사(Error Guessing)``: 과거의 경험이나 확인자의 감각으로 테스트하는 기법
- ``비교 검사(Comparison Testing)``: 여러 버전의 프로그램에 동일한 테스트 자료를 제공하여 동일한 결과가 출력되는지 테스트하는 기법
8. 개발 단계에 따른 애플리케이션 테스트 ✅ - 애플리케이션 테스트와 소프트웨어 개발 단게를 연결하여 표현한 것을 V-모델이라고 함

9. 단위 테스트 ✅ - 코딩 직후 소프트웨어 설계의 최소 단위인 모듈이나 컴포넌트에 초점을 맞춰 테스트하는 것 - 인터페이스, 외부적 I/O, 자료 구조, 독립적 기초 경로, 오류 처리 경로, 경계 조건 등을 검사 - 사용자의 요구사항을 기반으로 한 기능성 테스트를 최우선으로 수행 - 구조 기반 테스트와 명세 기반 테스트로 나뉘지만 주로 구조 기반 테스트를 시행함
10. 통합 테스트 ✅ - 단위 테스트가 완료된 모듈들을 결합하여 하나의 시스템으로 완성시키는 과정에서의 테스트 - ``비점진적 통합 방식`` - 단계적으로 통합하는 절차 없이 모든 모듈이 미리 결합되어 있는 프로그램 전체를 테스트하는 방식 - 종류: 빅뱅 통합 테스트 방식
- ``점진적 통합 방식`` - 모듈 단위로 단계적으로 통합하면서 테스트하는 방식 - 종류: 하향식 통합 테스트, 상향식 통합 테스트, 혼합식 통합 테스트
11. 인수 테스트 ✅ - 사용자의 요구사항을 충족하는지에 중점을 두고 테스트하는 것 - ``알파 테스트`` - 개발자의 장소에서 사용자가 개발자 앞에서 행하는 테스트 기법 - 테스트는 통제된 환경에서 행해지며, 오류와 사용상의 문제점을 사용자와 개발자가 함께 확인하면서 기록함
- ``베타 테스트`` - 선정된 최초 사용자가 여러 명의 사용자 앞에서 행하는 테스트 기법 - 실업무를 가지고 사용자가 직접 테스트
More to read
Amazon VPC Architecture 이해하기
새로운 프로젝트를 기획하며, 개발에서 무엇을 가장 먼저 고민해야 하는지 다시 돌아보게 되었습니다.한때는 프론트엔드가 모든 설계의 출발점이라고 믿었습니다. 유저가 무엇을 보고, 어떤 흐름에서 머무르고 이탈하는지에 대한 이해 없이 서비스를 만든다는 건 불가능하다고 생각했기
'원사이트'프론트엔드 관점으로 알고리즘 이해하기
오랜만에 방법론에 관한 글을 쓰게 되었습니다. 최근 상황은 이렇습니다. SSAFY에서는 하루에 엄청난 양의 알고리즘 문제들을 과제로 수행하게 됩니다. 그 과정에서, '구현력'이 매우 떨어진다는 생각이 들었습니다. 완전히 어려운 문제라면 '아쉬움'이라는 감정조차 느끼지
SubnetVPC 설계의 시작: IP와 Subnet
반복되는 루틴 속에서 얻은 안정감을 발판 삼아, 이제는 기술적 스펙트럼을 넓히기 위한 개인 프로젝트에 착수하고자 합니다.이번 프로젝트의 목표는 단순한 포트폴리오 구축을 넘어, 실제 서비스 수준의 블로그 시스템 구현과 다국어 처리 적용 등 실무에 가까운 역량을 한 단계