Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags more
Archives
Today
Total
관리 메뉴

AngzavA

[정보처리기사 실기] 기출정리 2021년 3회 본문

정보처리기사

[정보처리기사 실기] 기출정리 2021년 3회

이앙지 2023. 7. 17. 01:05

1. Authentication(인증), Authorization(인가), Accounting(계정 관리)

(1) 시스템을 접근하기 전에 접근 시도하는 사용자의 신원을 검증
(2) 검증된 사용자에게 어떤 수준의 권한과 서비스를 허용
(3) 사용자의 자원(시간,정보,위치 등)에 대한 사용 정보를 수집

AAA, Triple-A = Authentication, Authorization, Accounting

보안 3요소 = 기밀성, 무결성, 가용성

DoS, DDoS -> 가용성 침해

 

접근통제

MAC : 강제 접근 통제 - 등급을 비교하여 접근 권한 부여, 제 3자

- 비바모델 : 무결성 강조

- 벨라파둘라 모델 : 기밀성 강조

DAC : 임의 접근 통제 - 사용자 신원에 따라 접근 권한 부여, 소유자가 줌

RDAC : 역할 기반 접근 통제

 

2. GRANT 정의 : 사용자에게 접속권한, 생성권한 등을 부여하는 명령어

DDL 정의 : CREATE, DROP, ALTER

DML 조작 : SELECT, INSERT, UPDATE, DELETE

DCL 제어 : COMMIT, ROLLBACK, GRANT, REVOKE

 

3. ARP

( ) 스푸핑은 근거리 통신망 하에서 ( ) 메시지를 이용하여 상대방의 데이터 패킷을 중간에서 가로채는 중간자 공격 기법이다. 이 공격은 데이터 
링크 상의 프로토콜인 (  )를 이용하기 때문에 근거리상의 통신에서만 사용할 수 있는 공격이다.

스푸핑 공격

ARP 스푸핑 : IP에서 MAC주소로 바뀌는 것에서 MAC 주소를 속이는 것

IP 스푸핑 : IP 자체의 보안 취약성을 악용한 것으로 자신의 IP주소를 속여서 접속하는 공격, IP 스푸핑을 통해 서비스 거부 공격도 수행 가능, 공격 대상 컴퓨터와 서버 사이의 연결된 세션을 끊을 수도 있다, 종단 인증 같은 방법으로 해결

DNS 스푸핑 : 공격 대상에게 전달되는 DNS IP주소를 조작하여 의도치 않는 주소로 접속하는 공격, 공격대상은 정상적인 URL을 통해서 접속하지만, 실제로 가짜 사이트로 접속

 

 

4. Control Coupling

어떤 모듈이 다른 모듈의 내부 논리 조직을 제어하기 위한 목적으로 제어 신호를 이용하여 통신하는 경우의 결합도이다. 
하위 모듈에서 상위 모듈로 제어 신호가 이동하여 상위 모듈에게 처리 명령을 부여하는 권리 전도 현상이 발생할 수 있다.

Data - Stamp - Control - External - Common - Content

 

 

5. Factory 

부모(상위) 클래스에 알려지지 않은 구체 클래스를 생성하는 패턴이며, 자식(하위) 클래스가 어떤 객체를 생성할지를 결정하도록 하는 패턴
이기도 하다.  부모(상위) 클래스 코드에 구체 클래스 이름을 감추기 위한 방법으로도 사용한다.

팩토리 메소드 - 객체 생성을 서브 클래스에서 처리하도록 분리하여 캡슐화한 패턴

추상 팩토리 - 구체적인 클래스에 의존하지 않고, 인터페이스를 통해 서로 연관, 의존 하는 객체들의 그룹으로 생성하여 추상적으로 표현

 

생성패턴: 생빌 프로 팩앱싱
(빌더, 프로토타입, 팩토리 메서드, 앱스트랙 팩토리, 싱글톤)

구조패턴: 구 브데 퍼플 프록컴 어
(브리지, 데코레이터, 퍼사이드, 플라이 웨이트, 프록시, 컴포지트, 어댑터)

행위패턴: 행 미인이 템옵 스테 비커 스트 메체
(미디에이터, 인터프리터, 이터레이터, 템플릿 메서드, 옵져버, 스테이트, 비지터, 커맨드, 스트레티지, 메멘토, 체인 오브 리스판서빌리티)

 

생성 패턴(Creational Pattern)

팩토리 메소드(Factory Method)

  • Virtual-Constructor 패턴이라고도 함
  • 객체를 생성하기 위한 인터페이스를 정의 하여 어떤 클래스가 인스턴스화 될 것인지는 서브클래스가 결정

추상 팩토리(Abstract Factory)

  • 구체적인 클래스에 의존하지 않고, 서로 연관·의존하는 객체들의 그룹으로 생성하여 추상적으로 표현
  • 연관된 서브 클래스를 묶어 한 번에 교체 가능

빌더(Builder)

  • 건축가가 블록을 조립하는 모습
  • 분리된 인스턴스(객체)를 건축하듯이 조합하여 객체를 생성
  • 동일한 객체 생성에서도 다른 결과 나올 수 있음

프로토타입(Prototype)

  • 원본 객체를 복제하는 방법으로 객체를 생성하는 패턴
  • 비용이 큰 경우 주로 이용

싱글톤(Singleton)

  • 객체를 어디서든 참조할 수 있지만, 여러 프로세스가 동시에 참조하는 것은 불가능
  • 인스턴스가 하나뿐이기 때문에 불필요한 메모리 낭비를 최소화 할 수 있음

구조 패턴(Structural Pattern)

어댑터(Adaptor)

  • 호환성을 맞춰주는 변압기
  • 클래스들의 호환성이 맞도록 변환해주는 패턴
  • 기존의 클래스를 이용하고 싶은데 인터페이스가 일치하지 않을 때 사용

브리지(Bridge)

  • 두 섬을 연결하는 다리
  • 서로가 독립적으로 확장할 수 있도록 구성한 패턴
  • 기능과 구현을 별도의 클래스에서 구현

컴포지트(Composite)

  • 폴더와 파일을 합성한 것
  • 복합 객체와 단일 객체를 구분 없이 다루고자 할 때 사용
  • 복합 객체 안에 복합 객체가 포함되는 구조 구현 가능

데코레이터(Decorator)

  • 온갖 것으로 장식된 눈사람
  • 객체 간의 결합으로 기능을 확장할 수 있음
  • 부가적인 기능 추가를 위해 다른 객체들을 덧붙이는 방식

퍼싸드(Facade)

  • 리모컨만으로 복잡한 명령을 수행하는 것
  • 상위에 인터페이스를 구성하여 서브 클래스들의 기능을 수행할 수 있음
  • 서브 클래스들 사이의 통합 인터페이스를 제공하는 Wrapper 객체 필요

플라이웨이트(Flyweight)

  • 부담을 가볍게 하기 위해 물품 공유
  • 인스턴스를 가능한 한 공유해서 사용하여 메모리를 절약
  • 다수의 유사 객체를 생성하거나 조작할 때 유용함

프록시(Proxy)

  • 하기 어려운 업무를 대리로 해주는 사람
  • 접근이 어려운 객체와 여기 접근하려는 객체 사이의 인터페이스 역할
  • 네트워크 연결, 메모리의 대용량 객체로의 접근에 이용

행위 패턴(Behavioral Pattern)

책임 연쇄(Chain of Responsibility)

  • 연속해서 나눠받는 물레방아
  • 한 객체가 처리하지 못하면 다음 객체로 넘어가는 패턴
  • 요청이 해결될 때까지 고리를 따라 책임이 넘어감

커맨드(Command)

  • 명령어를 하나로 합쳐둔 것
  • 요청을 캡슐화하여 재이용하거나 취소할 수 있도록 저장하거나 로그로 남김
  • 추상클래스와 구체클래스로 나뉨

인터프리터(Interpreter)

  • 언어 번역가
  • 언어에 문법 표현을 정의함
  • SQL이나 통신 프로토콜에 사용

반복자(Iterator)

  • 같은 명령의 반복
  • 접근이 잦은 객체에 대해 동일한 인터페이스를 사용하도록 함
  • 내부 표현 방법의 노출 없이 순차적인 접근 가능

중재자(Mediator)

  • 매매를 중개해주는 중개사이트
  • 객체들 간의 복잡한 상호작용을 캡슐화하여 객체로 정의
  • 객체 사이의 결합도를 감소시킴

메멘토(Memento)

  • 기억 속의 그 때로 돌아감.
  • 객체를 특정 시점의 상태로 돌릴 수 있는 기능
  • ctrl+z 와 같은 기능 개발시 사용

옵서버(Observer)

  • 변화를 지켜보고 알려주는 것
  • 한 객체의 상태 변화시 상속되어 있는 다른 객체들에게 알림
  • 시스템간에 이벤트를 생성하고 수신할 때 사용

상태(State)

  • 상태에 따라 다른 방법을 사용함
  • 객체의 상태에 따라 동일한 동작을 다르게 처리해야 할 때 사용
  • 객체 상태를 캡슐화하고 이를 참조함

전략(Strategy)

  • 여러 전략을 정하고 필요할 때 선택하여 씀
  • 동일한 계열의 알고리즘을 캡슐화하여 상호 교환할 수 있게 정의함
  • 원하는 알고리즘을 선택하여 사용하며 클라이언트에 영향 없이 알고리즘 변경 가능

템플릿 메소드(Template Method)

  • 방법들을 큰 틀로 묶는 것
  • 상위 클래스에서 골격 정의, 하위 클래스에서 세부 처리를 구체화
  • 유사한 서브 클래스의 공통된 내용을 상위 클래스에서 정의(유지보수를 용이하게 함)

방문자(Visitor)

  • 책을 만들기 위해 저자, 편집자를 번갈아가며 방문
  • 각 클래스들의 데이터 구조에서 처리 기능을 별도의 클래스로 구성
  • 분리된 기능은 각 클래스를 방문하여 수행

 

6. 인덱스

파일구조는 파일을 구성하는 레코드들이 보조기억장치에 편성되는 방식으로 접근 방식에 따라 방식이 달라진다. 접근 방법중, 
레코드들을 키-값 순으로 정렬하여 기록하고, 레코드의 키 항목만을 모은 (  )을 구성하여 편성하는 방식이 있으며, 레코드를
참조할 때는 (   ) 이 가르키는 주소를 사용하여 직접 참조할 수 있다. 파일 구조에는 순차 접근, (  ) 접근,  해싱 접근이 있다.

파일의 구조

순차 파일 : 레코드를 논리적인 처리 순서에 따라 연속된 물리적 공간으로 기록하는 것

직접 파일 : 파일을 구성하는 레코드를 임의의 물리적 저장공간에 기록하는 것

색인 순차 파일 : 순차 파일과 직접 파일에서 지원하는 편성 방법이 결합된 형태

 

 

7. 상향식, 테스트 드라이

(   A  ) 방식은 하위 모듈부터 시작하여 상위 모듈로 테스트를 진행하는 방식이며, 이 방식을 사용하기 위해서는 (  C  )가 필요하다. 
(   C   )는 이미 존재하는 하위 모듈과 존재하지 않은 상위 모듈에 대한 인터페이스 역할을 한다.

상향식 통합 -상위 모듈이 없으므로, 상위 모듈 역할을 하는 테스트 드라이버(Driver)를 이용

하향식 통합-하위 모듈이 없으므로, 하위 모듈들 역할을 하는 스텁(Stub)을 이용

문제에  이미 존재하는 하위 모듈 존재하지 않은 상위 모듈에 대한 인터페이스 역할을 한다

 

 

8. GUI

(  )는 사용자가 그래픽을 통해 컴퓨터와 정보를 교환하는 환경을 말한다. 이전까지 사용자 인터페이스는 키보드를 통해 명령어로 작업을 
수행시켰지만 (   )에서는 키보드 뿐만 아니라 마우스 등을 이용하여 화면의 메뉴 중 하나를 선택하여 작업을 수행한다.
화면에 아이콘을 띄어 마우스를 이용하여 화면에 있는 아이콘을 클릭하여 작업을 수행하는 방식이다.
대표적으로는 마이크로소프트의 Windows, 애플의 Mac 운영체제 등이 있다.

UI 요소 : 직관성, 유효성, 학습성, 유연성

 

 

9. 클래스 다이어그램

이 다이어그램은 문제 해결을 위한 도메인 구조를 나타내어 보이지 않는 도메인 안의 개념과 같은 추상적인 개념을 기술하기 위해 나타낸 것이다.
또한 소프트웨어의 설계 혹은 완성된 소프트웨어의 구현 설명을 목적으로 사용할 수 있다. 이 다이어그램은 속성(attribute)과 메서드(method)를
포함한다.

구조적 다이어그램

- 클래스 다이어그램 : 시스템을 구성하는 클래스 사이의 관계

패키지 다이어그램 : 클래스나 유스케이스 등을 포함한 여러 모델 요소들을 그룹화하여 패키지를 구성하고 패키지들 사이의 관계를 표현한다

복합체 구조 다이어그램 : 복합 구조의 클래스와 컴포넌트 내부 구조를 표현한다

객체 다이어그램 : 객체 정보를 보여준다

컴포넌트 다이어그램 : 컴포넌트 구조 사이의 관계를 표현한다

배치 다이어그램 : 소프트웨어, 하드웨어, 네트워크를 포함한 실행 시스템의 물리 구조를 표현한다

 

행위 다이어그램

- 유스케이스 다이어그램 : 사용자 관점에서 시스템 행위를 표현

- 활동 다이어그램 : 업무 처리 과정이나 연산이 수행되는 과정을 표현

- 콜라보레이션 다이어그램 : 순차 다이어그램과 같으며 모델링 공간에 제약이 없어 구조적인 면을 중시

- 상태 머신 다이어그램 : 객체의 생명주기를 표현한다

- 순차 다이어그램 : 시간 흐름에 따른 객체 사이의 상호작용을 표현

- 통신 다이어그램 : 객체 사이의 관계를 중심으로 상호작용 표현

- 상호작용 개요 다이어그램 : 여러 상호작용 다이어그램 사이의 제어 흐름을 표현

- 타이밍 다이어그램 : 객체 상태 변화와 시간 제약을 명시적으로 표현

 

 

10. DES

이것은 미국 NBS (National Bureau of Standards, 현재 NIST)에서 국가 표준으로 정한 암호 알고리즘으로, 64비트 평문을 64비트 암호문으로
암화하는 대칭키 암호 알고리즘이다. 키는 7비트마다 오류검출을 위한 정보가 1비트씩 들어가기 때문에 실질적으로는 56비트이다. 현재는 취약하여 
사용되지 않는다.

암호 방식의 분류

대칭키(비밀키) 

- Stream - LFSR, RC4

- Block - DES, AES, IDEA

비대칭키(공개키)

- 인수분해 - RSA, Robin

- 이산대수 - Elgamal, DSA

- 타원곡선 - ECC

 

 

11. 테스트 조건, 테스트 데이터, 예상 결과

테스트케이스 구성요소

식별자 ID, 테스트 항목, 테스트 조건, 테스트 데이터, 예상 결과

 

 

12. Aggregation, Generalization

(  A  )은/는 클래스들 사이의 전체 또는 부분 같은 관계를 나타내는 것이고, (  B  )은/는 한 클래스가 다른 클래스를 포함하는 상위 개념일 때 
IS-A관계라하며, 일반화 관계로 모델링한다.

일반화 관계(Generalization : 한 클래스가 다른 클래스를 포함하는 상위 개념일 때의 관계

연관관계(Accociation : 2개 이상 사물이 서로 관련된 관계

의존관계(Dependency: 연관 관계와 같이 한 클래스가 다른 클레스에서 제공하는 기능을 사용할 때 표시( 짧은 시간만 유지

실체화 관계(Realization : 인터페이스를 구현받아 추상 메서드를 오버라이딩 하는것을 의미

집약 관계 (Aggregation : 한 객체가 다른 객체를 소유하는 

합성관계 (Composition : 부분 객체가 전체 객체에 속하는 관계

 

UML 관계 

집합 관계 - 집약관계(Aggregation) : has a 관계

집합 관계 - 합성관계(Composition) :  부분 객체가 전체 객체에 속하는 관계로 긴밀한 필수적 관계

 

 

13. 데이터링크, 네트워크, 표현

(1) 물리계층을 통해 송수신되는 정보의 오류와 흐름을 관리하여 안전한 정보의 전달을 수행할 수 있도록 도와주는 역할
(2) 데이터를 목적지까지 가장 안전하고 빠르게 전달하는 기능
(3) 수신자에서 데이터의 압축을 풀수 있는 방식으로 된 데이터 압축

물데네트세프응

  1. 물리 - 기계적, 전기적 특성. X.21, 리피터, 허브
  2. 데이터 링크 - 흐름 제어, 오류 검출과 회복, HDLC, MAC, 랜카드, 브리지, 스위치
  3. 네트워크 -  경로 설정(Routing), 트래픽 제어, 패킷, X.25, IP, 라우터, ICMP, ARP, RARP
  4. 전송 - 다중화, 오류 제어, 흐름 제어, TCP(3-way handshaking), UDP, 게이트웨이
  5. 세션 - 송수신 측 간의  관련성을 유지, 대화 제어
  6. 표현 - 데이터 암호화, 데이터 압축, 형식 변환
  7. 응용 - 파일 전송, 전자 사서함(메일), 정보 교환, 가상 터미널

5,6,7

TCP - telnet, FTP, HTTP, POP, SMTP

UDP - DHCP, SNMP, DNS

 

★ 데이터 링크는 노드 사이의 흐름과 오류 제어. 

★ 전송은 단말기 사이의 흐름과 오류 제어.

 

 

14. Cause Effect Graph (원인 결과 그래프)

입력 자료 간의 관계와 출력에 영향을 미치는 상황을 체계적으로 분석 후 효용성이 높은 테스트 케이스를 선정해서 테스트하는 기법

동경결상 유분페원비
동등분할 테스트: 도메인 별로 유무효 그룹핑
경계값 분석 테스트: 등가분할 후 경계 값 포함
결정 테이블 테스트: 조건과 행위 모두 조합
상태 전이 테스트: 상태 전이되는 경우의 수 수행
유스케이스 테스트: 프로세스 흐름 기반 명세화
분류 트리 테스트: SW 부분을 트리구조로 분석
페어와이즈 테스트: 값을 최소한 한 번씩 조합
원인-결과 그래프 테스트: 입출력 조건간 논리적 관계 분석 후 도출

비교 테스트: 

 

 

15. 4

 

16. FALSE

a,b = 100, 200 
print(a==b)

 등위 여부 물어보는 문제

 

 

17.

#include 
 
struct jsu {
  char nae[12];
  int os, db, hab, hhab;
};
 
int main(){
  struct jsu st[3] = {{"데이터1", 95, 88}, 
                    {"데이터2", 84, 91}, 
                    {"데이터3", 86, 75}};
  struct jsu* p;
 
  p = &st[0];
 
  (p + 1)->hab = (p + 1)->os + (p + 2)->db;
  (p + 1)->hhab = (p+1)->hab + p->os + p->db;
 
  printf("%dn", (p+1)->hab + (p+1)->hhab);
}

struct 구조의 char nae의 인덱스와 os,db,hab,hhab 인덱스를 st[3]을 적용해서 각각 그림으로 나타내면

데이터1 os =95 db = 88 hab hhab
데이터2 os = 84 db =91 hab hhab
데이터3 os = 81 db = 75 hab hhab

여기서 

 (p + 1)->hab = (p + 1)->os + (p + 2)->db;  (p + 1)->hhab = (p+1)->hab + p->os + p->db;

는 p[1] .hab = p[1].os + p[2].db;

p[1].hhab = p[1].hab+p[0].os+p[0].db; 임

따라서 각각 인덱스에 접근해보면

 p[1] .hab = p[1].os + p[2].db; 은 데이터2열의  hab의 값에 같은열의 os값 즉 84와 데이터3열의 db값 즉 75를 더한 값을 반영하기 때문에 데이터2열의 hab값은 159가 되고 값이 반환됨

다음으로 데이터2열의 hhab값은 데이터2열의 hab즉 아까 반환했던 159에 데이터1열의 os값. 즉 95와 같은열의 db값 즉 88을 더한 값이 반영됨. 따라서 데이터2열의 hhab값은 342라는 값이 반환됨.

계속해서 마지막 실행줄에 보면 (p+1)->hab + (p+1)->hhab) 즉 아까 연산했던 데이터2열의 hab의 값과 hhab의 값을 더한 것이 실행 값이라는 것을 알 수 있음. 따라서 342+159는 501값이 출력됨.

 

구조체 자체는 이해했는데 포인터 개념이 좀 어려운 그런,,,

 

 

18. 37

#include 
int main(){
  int *arr[3];
  int a = 12, b = 24, c = 36;
  arr[0] = &a;
  arr[1] = &b;
  arr[2] = &c;
 
  printf("%dn", *arr[1] + **arr + 1);
}

이중 포인터 검색 해보시면 됩니다.. **arr  은 arr[0] 의 주소번지를 가리키고 *arr[0]

의 값은 12 깐요  ..거기다 +1은 13입니다. 

 

arr는 그냥 배열 주소값을 가진 변수입니다

따라서 *가 붙으면 arr가 가리키는 배열을 첫번째 값arr[0]를 가리키고 *가 하나 더 붙으면 arr[0]이 가리키는 a의 값을 참조하게되서 12에요

 

arr=&arr[0]
*arr = arr[0] = &a
**arr = 12
**arr + 1 = 12+1 // 13

 

 

19. 7

public class testco {
 public static void main(String[] args) {
  int a = 3, b = 4, c = 3, d = 5;
  if((a == 2 | a == c) & !(c > d) & (1 == b ^ c != d)) {
   a = b + c;
    if(7 == b ^ c != a) {
     System.out.println(a);
    } else {
    System.out.println(b);
    }
  } else {
    a = c + d;
    if(7 == c ^ d != a) {
    System.out.println(a);
    } else {
    System.out.println(d);
    }
  }
 }
}

 

^ = XOR = 참/거짓이 서로 다르면 참

 

 

20. 3

class Connection {
  private static Connection _inst = null;
  private int count = 0;
    static public Connection get() {
      if(_inst == null) {
      _inst = new Connection();
      return _inst; 
      }
    return _inst;
    }
  public void count() { count ++; }
  public int getCount() { return count; }
}
 
public class testcon {
  public static void main(String[] args) {
    Connection conn1 = Connection.get();
    conn1.count();
    Connection conn2 = Connection.get();
    conn2.count();
    Connection conn3 = Connection.get();
    conn3.count();
    
    System.out.print(conn1.getCount());
  }
}

이 코드는 Singleton 디자인 패턴을 사용하여 Connection 클래스의 인스턴스를 제한된 수로 유지하려고 시도합니다. Singleton 패턴은 애플리케이션 내에서 클래스의 단일 인스턴스를 생성하고, 이후에는 항상 해당 인스턴스를 반환하는 패턴입니다. 이를 통해 중복된 인스턴스 생성을 방지하고, 모든 사용자가 동일한 인스턴스를 공유할 수 있습니다.

  1. Connection 클래스의 private 정적 변수 _inst는 초기에 null로 설정됩니다.
  2. Connection 클래스의 정적 메서드 get()은 _inst 변수를 확인하고, _inst가 null인 경우에만 인스턴스를 생성합니다. 즉, 최초 호출 시에만 인스턴스를 생성하고 그 이후에는 기존 인스턴스를 반환합니다.
  3. get() 메서드가 호출되면, _inst가 null인 경우에만 새로운 Connection 인스턴스를 생성하여 _inst에 할당합니다.
  4. Connection 클래스의 count() 메서드는 count 변수를 1씩 증가시킵니다.
  5. Connection 클래스의 getCount() 메서드는 count 변수의 값을 반환합니다.
  6. testcon 클래스의 main 메서드에서 다음 작업이 수행됩니다:
    • Connection conn1 = Connection.get();을 통해 Connection 인스턴스를 얻고, count() 메서드를 호출하여 count 변수를 1로 설정합니다.
    • Connection conn2 = Connection.get();을 통해 이미 생성된 Connection 인스턴스를 얻고, count() 메서드를 호출하여 count 변수를 2로 설정합니다.
    • Connection conn3 = Connection.get();을 통해 이미 생성된 Connection 인스턴스를 얻고, count() 메서드를 호출하여 count 변수를 3으로 설정합니다.
  7. 마지막으로, conn1.getCount()를 호출하여 count 변수의 값을 출력합니다. 이 경우 count 변수의 값은 3이므로 3이 출력됩니다.

즉, 위 코드는 Connection 클래스의 인스턴스를 Singleton으로 관리하고, count 변수를 사용하여 생성된 인스턴스의 수를 추적하는 예제입니다.