U E D R , A S I H C RSS

Java Study2003/첫번째과제/장창재

  • 자바 언어의 특징.
    - 자바(Java)를 이야기할 때 크게 두 가지로 나누어 이야기 할 수 있습니다. 먼저, 기계어, 어셈블리어(Assembly), 포트란(FORTRAN), 코볼(COBOL), 파스칼(PASCAL), 또는 C 등과 같이 프로그래밍을 하기 위해 사용하는 자바 언어가 있고, 다른 하나는 자바 언어를 이용하여 프로그래밍 하기 위해 사용할 수 있는 자바 API(Application Programming Interface)와 자바 프로그램을 실행시켜 주기 위한 자바 가상머신(Java Virtual Machine) 등을 가리키는 자바 플랫폼(Platform)이 있습니다. 다시 말해서, 자바 언어는 Visual C++와 비유될 수 있고, 자바 플랫폼은 윈도우 95/98/NT 및 윈도우 95/98/NT API와 비유될 수 있습니다.
    자바 언어(Java Language)를 이용하여 작성한 자바 프로그램(Java Program)은 자바 컴파일러(Java Compiler)를 이용하여 자바 바이트코드(Java Byte code)로 컴파일 되고, 이 자바 바이트코드는 자바 가상머신에 의해 해석되어 실행되는데, 이때 자바 가상머신은 자바 바이트코드에 대한 해석기 즉 인터프리터(interpreter)로 동작하게 됩니다. 이렇게 자바 프로그램은 컴파일 방식 및 인터프리터 방식이 모두 적용된다는 것입니다.

  • 자바 컴파일러(Java Compiler):
자바 언어로 작성된 자바 프로그램을 중간 언어(intermediate language) 형태인 자바 바이트코드로 컴파일 합니다<.
자바 바이트코드(Java Byte code):
컴퓨터는 각 CPU에 따라 서로 다른 기계어를 갖습니다. 이러한 이유 때문에 도스 또는 윈도우 95/98/NT 등이 설치되어 있는 컴퓨터에서 실행되는 프로그램이 유닉스가 설치되어 있는 컴퓨터에서는 실행되지 않는 것입니다. 그러나, 자바 바이트코드는 이러한 플랫폼에 상관없이 자바 가상머신에 의해 실행될 수 있도록 정의된 중간코드입니다. 따라서, 자바 바이트코드로 컴파일 되기만 하면, 자바 인터프리터인 자바 가상머신이 설치되어 있는 곳이면 어디에서든 실행시켜 줄 수 있습니다. 이는 자바 개발자 또는 사용자로 하여금 자바 프로그램을 개발하거나 사용할 때 그 플랫폼이 윈도우 95/98/NT, 유닉스, 또는 매킨토시인지 전혀 신경 쓰지 않아도 되도록 합니다.
자바 인터프리터(Java Interpreter) 또는 자바 가상머신(Java Virtual Machine):
자바 바이트코드 명령어를 해석하고, 이를 자바 인터프리터가 설치되어 있는 플랫폼(윈도우 95/98/NT, 유닉스, 매킨토시 등)에 맞게 실행시켜 줍니다. 자바 인터프리터는 자바 바이트코드를 실행시켜 주기 위한 기능을 명세하고 있는 자바 가상머신을 구현해 놓은 것으로서 자바 가상머신과 같은 의미로 사용되며, 주로 자바 가상머신으로 많이 사용됩니다.
자바 바이트코드는 자바 가상머신에서 실행되는 기계어라고 생각하면 됩니다. 그리고, 모든 자바 인터프리터는 자바 가상머신을 구현해 놓은 것으로, 자바 가상머신과 자바 인터프리터를 같은 것으로 생각할 수 있습니다. . 이러한 자바 가상머신은 JDK(Java Development Kit)에 포함되어 있을 수도 있고, 자바 호환 웹 브라우저 내에 내장되어 있을 수도 있습니다. 또는, 자바 칩과 같이 하드웨어에 직접 구현될 수도 있습니다. 자바 바이트코드는 “write once, run anywhere”라는 말을 가능하게 해 줍니다. 다시 말해서, 자바 언어를 이용하여 작성한 자바 프로그램을 각 플랫폼(윈도우 95/98/NT, 리눅스, 유닉스, 매킨토시 등)에 맞게 제공되는 자바 컴파일러를 통해서 바이트코드로 컴파일 할 수 있습니다. 그리고, 이 바이트코드는 자바 가상머신이 있는 어떤 곳에서도 실행될 수 있습니다.
그림 2. 플랫폼 독립적인 자바



플랫폼이란 프로그램이 실행되는 하드웨어 또는 운영체제와 같은 소프트웨어적인 환경을 말합니다. 대부분의 플랫폼은 하드웨어와 운영체제를 함께 일컬어 말합니다. 그러나 자바 플랫폼은 하드웨어와 무관하게 동작하는 오직 소프트웨어적인 플랫폼이란 점에서 다른 플랫폼과 다릅니다. 이를 위해 자바 플랫폼은 다음과 같은 두 가지의 구성요소를 갖습니다.

자바 가상머신(Java Virtual Machine; Java VM):
자바 가상머신은 자바 플랫폼의기반을 이루며, 다양한 하드웨어기반 플랫폼에 포팅(poring) 됩니다. 다시 말해서, 자바 가상머신은 윈도우 95/98/NT, 유닉스, 또는 매킨토시 등과 같은 기존의 운영체제 또는 인터넷 익스플로러와 넷스케이프 등과 같은 웹 브라우저 등, 여러 가지 플랫폼에 설치되어 사용될 수 있으며, 사용자는 자바 바이트코드로 컴파일된 자바 프로그램을 실행시키기 위해서 이 자바 가상머신을 이용하면 됩니다.
자바 API(Java Application Programming Interface):
자바 API는 윈도우 API와 같이 운영체제에서 제공해 주는 라이브러리와 같은 것입니다. 다시 말해서, 자바 프로그램을 개발하기 위해 사용할 수 있는 라이브러리 또는 클래스들이라 할 수 있습니다. 이러한 자바 API는 서로 관련된 클래스들을 묶어서 패키지 단위로 제공되고 있습니다.

  • 자바의 장점 및 이익
자바의 특징을 살펴보면 다음과 같습니다.

간단하다(Simple):
자바의 주된 특징은 기존의 C/C++ 언어의 문법을 기본적으로 따르고, C/C++ 언어가 갖는 전처리기, 포인터, 포인터 연산, 다중 상속, 연산자 중첩(overloading) 등 복잡하고 이해하기 난해한 특성들을 제거함으로써 기존의 프로그램 개발자들이 쉽고 간단하게 프로그램을 개발할 수 있도록 합니다.
객체지향적이다(Object-Oriented):
자바는 C++와는 달리 처음부터 객체지향 개념을 기반으로 하여 설계되었고, 객체지향 언어가 제공해 주어야 하는 추상화(Abstraction), 상속(Inheritance), 그리고 다형성(Polymorphism) 등과 같은 특성들을 모두 완벽하게 제공해 주고 있습니다. 또한, 자바의 이러한 객체지향적 특성은 분산 환경, 클라이언트/서버 기반 시스템이 갖는 요구사항도 만족시켜 줄 수 있습니다.
높은 신뢰성(Reliability)을 갖는다:
자바는 컴파일 시에 에러 검사를 철저하게 하고, 실행 시에 발생할 수 있는 에러에 대해서도 실행 시에 철저하게 검사를 수행함으로써 신뢰도가 높은 프로그램을 작성할 수 있도록 해 줍니다. 또한, C/C++ 프로그램 개발자들을 가장 혼란스럽게 하고, 프로그램의 치명적인 오류를 발생시킬 수 있는 포인터 및 포인터 연산을 자바에서는 사용하지 않게 함으로써, 포인터를 사용함으로써 프로그래머가 범할 수 있는 오류를 없앴다는 것입니다.
보안성(Security)을 갖는다:
자바는 분산환경에서 작동하도록 설계 되었습니다. 그러나, 자바는 자바 언어와 자바 런타임 시스템 내에 보안 기능이 내재되어 있기 때문에 보안성이 있는 프로그램을 개발할 수 있도록 해 줍니다. 이러한 특성은 자바 프로그램이 네트웍 환경에서 바이러스 등과 같은 프로그램이 파일 시스템을 파괴하려는 것을 막을 수 있도록 해 줍니다.
아키텍쳐 중립적(Architecture-neutral)이고 이식성(Portable)이 높다:
자바는 서로 다른 이종(Heterogeneous)의 네트워크 환경에서 분산 되어 실행될 수 있도록 설계되었습니다. 이와 같은 환경에서는 응용 프로그램들이 다양한 하드웨어 아키텍쳐 위에서 실행될 수 있어야만 합니다. 이를 위해 자바 컴파일러는 이종의 하드웨어 및 소프트웨어 플랫폼에서 효율적으로 코드를 전송하기 위해 설계된 아키텍쳐 중립적인 중간 코드인 바이트코드를 생성합니다. 이는 동일한 자바 프로그램의 자바 바이트코드가 자바 가상머신이 설치되어 있는 어떤 플랫폼에서도 실행될 수 있도록 하는 것입니다. 또한, 자바는 기본 언어 정의를 엄격하게 함으로써 효율적인 이식성을 제공해 주고 있습니다. 예를 들어, int 형과 같은 기본 데이터형의 크기를 플랫폼과 무관하게 일정하게 하고, 연산자의 기능을 확실하게 규정하고 있습니다. C 언어를 이용하여 int 형을 선언할 때, 도스에서는 16비트, 윈도우 95/98/NT 등 32비트 운영 체제 환경에서는 32비트, 유닉스에서는 32비트 등 그 플랫폼에 따라 크기가 다르지만, 자바에서는 플랫폼에 상관없이 32비트로 고정되도록 하였습니다. 이는 자바 프로그램이 실행되는 환경이 자바 가상머신으로 동일하기 때문입니다.
높은 수행성능(High-performance)을 제공한다:
자바에서는 인터프-리터가 런타임 환경을 검사할 필요 없이 실행될 수 있도록 구성하였기 때문에 뛰어난 성능을 제공해 줍니다. 쓰레기 수집기(garbage collector) 즉 메모리 관리자는 자동으로 낮은 우선순위의 백그라운드 스레드로 실행되어 메모리가 필요할 때에만 동작하도록 함으로써, 자바 가상머신에게 무리를 주지 않으면서 보다 나은 수행 성능을 제공할 수 있도록 해 줍니다. 또한, 방대한 양의 계산을 수행하는 프로그램은 계산이 많은 부분을 본래의 플랫폼에 해당하는 기계어 코드로 재작성하여 자바 프로그램과 인터페이스 할 수 있도록 하였습니다.
인터프리터(Interpreter) 방식이다:
자바 언어로 작성된 자바 프로그램을 중간언어 형태인 자바 바이트코드로 컴파일하고, 이렇게 생성된 자바 바이트코드를 자바 인터프리터가 해석함으로써, 자바 인터프리터와 런타임 시스템이 이식(porting)된 모든 플랫폼에서 자바 바이트코드를 직접 실행할 수 있습니다.
다중 스레드(Multi-thread)를 지원한다:
자바의 다중 스레드 기능은 동시에 많은 스레드를 실행시킬 수 있는 프로그램을 만들 수 있도록 해 줍니다. 자바는 동기화 메소드들을 기본적으로 키워드로 제공함으로써, 자바 언어 수준에서 다중 스레드를 지원해 줍니다. 자바 API에는 스레드를 지원해 주기 위한 Thread 클래스가 있으며, 자바 런타임 시스템에서는 모니터와 조건 잠금 함수를 제공해 줍니다.

  • 자바의 단점과 해결책
자바는 몇 가지 단점을 가지고 있는데, 자바의 단점이라 할 수 있는 문제들과 그에 대해 자바에서는 어떤 기술 또는 방법을 이용하여 해결하려 하고 있는 지에 대해 살펴보도록 하겠습니다.

먼저, 자바는 기계어 코드를 직접 실행시키는 것이 아니고, 플랫폼 독립적인 중간 코드 형태인 바이트코드를 자바 가상머신이 해석하여 실행시키는 인터프리터 방식을 취하고 있으므로 느린 수행 시간을 갖습니다. 일반적으로 C보다 평균 8배 정도 느리고, 최대 20배까지 느립니다. 이렇게 느린 수행 시간을 해결하기 위해 다음과 같은 기술을 사용할 수 있습니다.

JIT(Just-In-Time):
네이티브 코드 생성기를 이용하여 인터프리트 하는 도중에 기계어로 동적으로 번역합니다.
HotSpot:
프로그램을 실행하는 중에 그 실행 형태를 분석하여 병목이 발생하는 부분을 찾아내어 최적화 시켜 줍니다.
자바-기계어 번역기:
자바 애플리케이션에 대해 바이트코드 대신 기계어 코드를 직접 생성해 줍니다.
컴파일시 최적화:
자바 컴파일러를 이용하여 컴파일 할 때 '-O' 옵션을 줌으로써 최적화 시켜줍니다.
네이티브 메소드:
C와 같이 다른 언어로 작성된 함수를 직접 호출합니다.
자바 전용 환경:
자바 운영체제 또는 자바 프로세서와 같이 자바를 위한 전용환경을 만들어 줍니다.
두 번째, 자바 애플릿을 웹 서버로부터 웹 클라이언트가 다운로드하여 실행시켜 주게 되는데, 이 때 네트워크 속도가 느리다는 문제가 있습니다. 이런 문제점에 대해서는 다음과 같은 기술을 사용하여 해결하려 하고 있습니다.

압축 파일(JAR 또는 ZIP):
자바 애플릿을 실행시키기 위해 애플릿을 다운로드해야 하는데, 이 때 애플릿에서 사용하는 데이터들도 존재할 수 있습니다. 예를 들어, 애니메이션을 수행하는 애플릿이 있는 HTML 페이지에 접속하여 그 애플릿을 실행시켜야 할 경우, 해당 애플릿 파일과 애플릿에서 애니메이션을 위해 사용하는 각 프레임 이미지도 존재할 것입니다. 따라서, 애플릿 파일은 물론 애플릿에서 사용하는 이미지 파일도 다운로드해야 애플릿에서 제대로 애니메이션을 수행할 수 있겠지요. 이 때, 애플릿 실행과 관련된 모든 파일을 JAR 또는 ZIP 형태의 압축 파일로 묶어 전송하게 됩니다. 이렇게 함으로써, 느린 네트워크를 이용하여 애플릿과 관련된 파일들을 다운로드 하는데 드는 시간을 줄일 수 있습니다.
캐싱(Caching):
다운로드 받은 애플릿과 애플릿 관련 파일들은 웹 클라이언트의 디스크에 캐싱합니다. 예를 들어, 웹 클라이언트가 애플릿이 포함된 페이지를 보다가 다른 페이지에 잠깐 들렀다가 애플릿이 포함된 페이지로 다시 돌아올 경우, 애플릿과 관련된 모든 파일들을 다시 다운로드하는 것이 아니고 웹 클라이언트의 디스크에 캐싱 되어 있는 애플릿 관련 파일들을 사용하게 됩니다. 이렇게 함으로써, 느린 네트워크를 이용하여 애플릿과 관련된 파일들을 다시 다운로드 하는데 걸리는 시간을 없앨 수 있습니다.
느린(lazy) 클래스 로딩:
하나의 HTML 페이지 내에 있는 애플릿은 하나의 클래스만을 사용할 경우도 있겠지만, 대부분의 경우 여러 개의 클래스를 필요에 따라 사용하게 됩니다. 여러 개의 클래스를 사용할 경우, 모든 클래스가 동시에 사용되지는 않겠지요. 또한 어떤 클래스는 정의는 되어있지만, 필요에 따라 전혀 사용되지 않을 수도 있겠지요. 따라서, 자바에서는 필요할 경우에만 클래스를 로딩하여 사용하게 됩니다. 이러한 기술을 느린(lazy) 클래스 로딩 이라 합니다.
세 번째, 모호한 언어적 특성, 비결정적 자바 가상머신, 표준화된 실시간 API가 없는 문제 때문에 실시간 응용이 어렵습니다. 이를 위해, 자바에서는 다음과 같은 기술을 개발하고 적용함으로써 실시간 응용을 가능하게 할 수 있습니다.

모호한 언어 특성의 문제점:
이러한 문제는 자바가 스레드 스케줄링 정책 구현에 의존하고, synchronized 명령어가 모니터 기반의 동기화 기법만 제공하고 큐 대기 시간을 예측할 수 없으며, notify() 메소드가 스레드를 깨우는 순서가 불명확하고, 우선순위 역전(priority inversion_의 가능성이 있습니다. 이러한 문제는 API 수준에서 해결되어야 하고, 실시간 타스크 처리를 위한 우선순위 레벨을 확장하고, 우선순위 상속(priority inheritance) 또는 우선순위 최고 한도 제한(priority ceiling) 등과 같은 우선순위 역전 방지 (priority inversion avoidance) 프로토콜을 사용하고, MuteX, 이진 세마포어(Binary Semaphore), 계수 세마포어(Counting Semaphore) 등을 사용할 수 있습니다.
비결정적 자바 가상머신의 문제점:
이러한 문제점은 느린(Lazy) 클래스 로딩에서 발생하거나 메모리 할당과 가비지 콜렉션이 비결정적이고 느린 최악의 경우(worst-case) 특성을 가지며 stop-start 방식으로 모든 스레드를 멈출 수 있다는 문제점이 있습니다. 이를 해결하기 위해 클래스를 미리 로딩(class preloading)한다거나 정적 초기화(static initializer)를 제거하여 패키지 라이브러리에 대해서는 가상머신 초기화를 사용하고 응용프로그램에서는 명시적인 초기화 를 사용하게 하는 등의 기법을 사용할 수 있습니다. 그리고, 메모리 할당과 쓰레기 수집(garbage collection)에 대해서는 정해진 시간 내에 입터럽트 가능한 쓰레기 수집을 하는 것입니다. 또는 표준화된 실시간 API를 제공함으로써 해결할 수 있습니다.

* 자바 프로그램의 종류
C언어를 이용하여 C 프로그램을 작성한다면 반드시 main이라는 시작 함수를 정의해 주어야 하고, 윈도우 응용프로그램을 작성한다고 하면 WinMain이라는 함수를 꼭 작성해 주어야 하지요. 이러한 것을 규약(protocol)이라 합니다. 마찬가지로, 자바 언어를 이용하여 여러 가지 종류의 자바 프로그램을 작성할 수 있는데, 이 때 각 자바 프로그램의 종류에 따라 해당 규약이 서로 다릅니다. 이렇듯 자바를 이용하여 자바 프로그램을 작성한다는 것은 각 자바 프로그램에서 제시하고 있는 규약을 지켜 프로그램을 작성한다는 것입니다. 자바 언어를 이용하여 작성할 수 있는 자바 프로그램의 종류를 살펴보면 다음과 같습니다.

자바 애플리케이션(Application):
JDK와 함께 제공되는 자바 가상머신에 의해 독립적으로 실행될 수 있도록 작성된 자바 프로그램입니다. 다시 말해서, 여러분의 컴퓨터에서 윈도우의 도스창 또는 유닉스 쉘 등과 같은 쉘에서 자바 가상머신을 이용하여 실행시키는 자바 프로그램입니다. 위에 나오는 그림은 자바 애플리케이션의 실행 과정을 자세히 보여주고 있습니다.

자바 애플릿(Applet):
<APPLET>~</APPLET> 태그를 이용하여 HTML 페이지 내에 포함되어, 자바 호환 웹 브라우저에 의해서 실행되도록 작성된 자바 프로그램입니다. 다시 말해서, 여러분의 홈 페이지 내에 삽입되어 자바 호환 웹 브라우저에 의해 실행되도록 규약에 맞추어 작성된 자바 프로그램을 말하는 것입니다. 다음에 나오는 그림은 자바 애플릿의 실행 과정을 자세히 보여주고 있습니다.

자바 서블릿(Servlet):
기존의 CGI 프로그램과 같이 웹 서버 프로그램의 기능을 확장하기 위한 자바 프로그램으로서, 웹 서버 내에 있는 자바 런타임 환경과 함께 제공되는 자바 가상머신에 의해 실행되도록 작성된 자바 프로그램입니다. 자바 서블릿은 웹 서버 내에서 자바 런타임 환경과 함께 제공되는 자바 가상머신에 의해 실행되고, 자바 애플릿은 웹 서버에서 웹 클라이언트로 다운로드 되어 웹 클라이언트에서 자바 호환 웹 브라우저에 내장된 자바 가상머신에 의해 실행된다는 차이점이 있습니다. 이렇게 웹 서버 내에서 실행될 수 있도록 작성된 자바 서블릿은 기존의 웹 서버 내에서 실행되는 프로그램인 CGI 프로그램을 대체할 수 있도록 고안되었습니다. 다음에 나오는 그림은 자바 서블릿의 실행 과정을 자세히 보여주고 있습니다.


자바 빈(Bean):
델파이 또는 비주얼 베이직을 이용하여 프로그램을 작성할 때, 버튼이나 창과 같은 컨트롤들을 마우스로 끌어다 프로그램 내에 삽입할 수 있도록 되어 있는데, 이와 마찬가지로 자바 빈은 하나의 완벽한 기능을 갖고 재사용될 수 있도록 만들어진 소프트웨어 컴포넌트입니다. 마이크로소프트에서 제공되는 ActiveX 컴포넌트와 같이 자바에서 컴포넌트 프로그램을 가능하도록 해 줍니다.

자바 패키지(package):
다른 자바 프로그램에 의해 삽입(import)되어 사용될 수 있도록 작성된 자바 프로그램입니다. 이러한 자바 패키지는 기존의 프로그래밍 언어에서 사용하던 라이브러리 또는 운영체제에서 제공해 주는 API 등과 같다고 볼 수 있습니다. 자바 패키지 역시 해당 규약을 갖겠지요. 자바에서는 기본적으로 압축 파일의 형태로 'casses.zip"이라는 자바 패키지가 제공되고 있고, 압축 파일 내에는 디렉토리 단위로 패키지가 포함되어 있습니다. 다음에 나오는 그림은 JDK 1.2.2 에서 제공되는 패키지를 보여주고 있습니다.



따라서, 여러분은 하나의 자바 프로그램을 작성할 때, 위에 나열된 하나의 규약에 맞게 자바 프로그램을 작성할 수도 있지만, 하나의 자바 프로그램이 위의 규약들을 두 개 이상 만족하도록 작성할 수도 있습니다.

이렇게 두 개 이상의 자바 프로그램 규약을 만족시키는 자바 프로그램은 여러 자바 프로그램에 속하게 됩니다. 예를 들어, 하나의 자바 프로그램을 작성했는데, 이 자바 프로그램은 자바 애플리케이션을 위한 규약을 만족시켜 주고 자바 애플릿을 위한 규약도 만족시켜 준다면, 이 자바 프로그램은 JDK와 함께 제공되는 자바 가상머신에 의해 실행되는 자바 애플리케이션으로서 독립적으로 실행될 수도 있고, 자바 호환 웹 브라우저에 내장된 자바 가상머신에 의해 자바 애플릿으로 실행될 수도 있다는 것입니다. 이렇게 자바 언어를 이용하여 여러 규약에 맞는 자바 프로그램을 작성할 수 있지만, 하나의 자바 프로그램이 굳이 두 개 이상의 규약을 모두 만족시켜주도록 자바 프로그램을 작성하는 경우는 자바 애플리케이션과 자바 애플릿의 경우를 제외하고는 거의 없습니다.

~cpp 
class HelloWorldApp { 
public static void main(String args[]) {

System.out.println("Hello World!"); // Display the string

}

}
 

뭐 대충 하긴 했는데, 자바에 대한 개념부터 확실한 설명을 듣고 시작해야 스터디가 성공할수 있을것 같습니다.

자바를 아는 사람의 강의 한시간은, 독학 10시간보다 효율적이며, 기초를 제대로 잡아야 건물을 높게 지을수 있습니다.

너무 욕심내서 어려운것만 하려고 하지 말고, 차근차근 스터디를 진행하면서 방학끝날때까지 '자바란 무엇인가?' 에대한

개념만 알아도 성공한것이라 생각합니다.

물론 스터디하는 사람들의 독학도 중요 하겠죠.

한마디로.....좀 쉬운것부터 천천히 배워 나갔으면 하네요.

추가 내용


  • 첫번째 과제에서 제가 의도했던 바가 바로 "자바를 왜 사용하는 것인가?" 가 바로 초점이었는데 아쉽게도 카피 & 페이스트 만 해서 과제를 끝마치신거 같군요. 밑의 질문은 위의 내용을 단 10%도 이해를 못했다는 느낌이 드네요. 자신이 한 과제를 차근차근 다시 읽어보시면서 "자바는 무엇이며 왜 사용하는가?" 에 대한 해답을 얻으시기 바랍니다.
  • 다른 사람이 한 과제도 꼼꼼히 읽어보시기 바랍니다. 조금의 차이점이 느껴지실거구요(물론 한분이랑 내용이 같네요;;) 그걸 다시 이해하시기 바랍니다.
  • 역시나 프로그램을 못하셨군요. 프로그램 역시 실행시켜 보시기 바랍니다.


Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:33
Processing time 0.0422 sec