URN (Uniform Resource Names) 에 대한 간략한 이해

URN(Uniform Resource Names)이란?
현재 인터넷 주소를 입력해야 하는 URL(Uniform Resource Locators)과 달리, 디지털콘텐츠 자체에 상품 바코드와 같은
식별코드를 붙여 이를 입력하는 것만으로 콘텐츠를 쉽게 찾고 인터넷으로 쉽게 유통하도록 해주는 식별체계를 말한다.
부연 하자면, URN(Uniform Resource Name)은 영속적이고 위치에 독립적인 이름으로 인터넷자원을 찾는 방식이며
사용자는 자원의 이름만 알면 그 자원에 대한 위치, 파일이름, 확장자 등을 알지 못하더라도 그 자원에 대한 접근이 가능함.
일반적인 체계는 urn:‘이름공간식별자’:‘이름공간에 대한 특별 문자열’로 구성
예) urn:def:blue_laser

이 같은 표준 식별체계가 정착되면 콘텐츠 이용자는 등록된 콘텐츠 정보(메타데이터)로 원하는 정보를 더욱 빠르고 정확하게
검색/이용할 수 있게 되고, 콘텐츠 보유자나 유통사업자는 식별코드로 더 효율적이고 안정되게 유통시킬 수 있어
디지털콘텐츠 유통에 획기적인 변화가 예상된다.
이를 위해 정통부는 문화관광부 등 관계 부처와 한국전산원/한국소프트웨어진흥원/한국문화콘텐츠진흥원/한국디지털콘텐츠포럼 등
디지털콘텐츠 유통 관련 기관이 참여하는 공동협의체를 구성, 디지털콘텐츠 식별체계 개발/적용, 거래인증 등 유통서비스와
권리자 보호, 표준화 등을 추진할 계획이다. 아울러 디지털콘텐츠 식별시스템을 공공부문 디지털콘텐츠부터 시범 적용하고 점차
디지털콘텐츠 보유자와 유통사업자까지 확대할 방침이다.

<용어해설>
국가URN기반구축사업 = 흔히 사용하는 URL방식의 인터넷 자원 식별체계는 정확한 식별기능이 떨어져 콘텐츠 유통에 맞지 않다.
이를 해결하기 위해 URN(Uniform Resource Names)을 이용하는 방법이 세계적인 추세이며, 디지털콘텐츠 유통에 관한
국제 표준화 기구인 MPEG21과 TV애니타임 등에서 권장하고 있다. 이는 마치 국가가 국민 개개인에게 영구적이고
고유한 주민등록번호를 부여해 과세/출입국관리/호적관리/금융 등 서비스를 훨씬 더 효율적으로 제공하는 것과 비슷하다.
주소지가 바뀌면 개인이 동사무소에 신고해 고유ID와 실제 거주지를 맞추는 것처럼 국가는 인터넷 디지털콘텐츠에 고유의
식별코드를 부여해 콘텐츠의 주요한 정보(메타데이터)를 관리, 안정되고 효율적인 디지털콘텐츠 유통체계를 만들게 된다.

o 콘텐츠가 존재하는 인터넷상의 장소가 아닌 콘텐츠 그 자체를 식별하는 체계로서 기존의 인터넷 주소체계를 보완함.
   콘텐츠에 부여된 식별자를 이용해 접근성을 향상시키고 디지털콘텐츠의 효율적인 관리 및 유통 활성화를 가능하게 하는
   차세대 인터넷 주소체계의 핵심요소임.
o 인터넷 콘텐츠에 대한 보다 효율적인 관리와 활용을 위해서는 콘텐츠가 갖는 구체적인 속성 및 특성(metadata)의 파악이 중요하며
   일반적으로 식별자와 metadata를 통칭하여 식별체계라 함.

2007/06/25 12:48 2007/06/25 12:48
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

애니메이션속 구글 검색 화면

지옥소녀 중

원작자나 감독은 구글 팬? 어딜봐도 구글로 보이는 검색 화면...
역시 일본쪽에서도 구글검색의 영향력은 대단한가 보군..

지옥소녀.. 내용과 결말이 눈에 뻔히 보이는데도 계속
다음편을 찾게하는 중독성이..
2007/06/24 21:41 2007/06/24 21:41
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

싸이코패스와 데쓰노트의 '키라'

올여름 극장가에서 검은집이란 국산영화가 헐리웃 대작 오션스13를 누르고 예매율 1위에 등극했다고 합니다.
저도 엊그저께 심야편으로 보고 왔더랬지요.. ^^
검은집이란 소설과 영화를 통하여 싸이코패스, 혹은 싸이코패시에 대한 이야기가 회자 되고 있는듯 한데요..

데쓰노트 키라

오늘 데쓰노트를 보다가 문득 '키라'야 말로 완벽한 싸이코패스가 아닌가 하는 생각이 들더군요..
밝은 세상을 만든다는 명목으로 범죄자 뿐만 아니라 자신의 목을 죄어오는 사람이라면 동료, 가족 할것없이
일말의 양심의 가책없이 완벽한 계략으로 죽여 버리니 말이죠.

그나저나 데쓰노트 TV판도 마지막 한편을 남겨두고 있는데, 마지막 결말이 궁금해 죽겠군요..
( 코믹스는 한권도 보지 못했거든요.. )
어떤식으로 결말을 내려도 좋은 상태로 이야기가 전개 되어 버렸기 때문에.. 키라,니아,미카미 누가 살아남든
혹은 모두 다 죽든 어떤식으로 결말이 나도 이상하지 않은 상황인 채로 이번화가 끝나버려서리..마지막화 결말이 무지 궁금합니다.

데쓰노트 화보
2007/06/24 16:31 2007/06/24 16:31
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

JAVA.UTIL.SCANNER로 텍스트 스캔하기

JAVA.UTIL.SCANNER로 텍스트 스캔하기

J2SE 5.0에는 일상적 태스크를 좀 더 쉽게 구현할 수 있도록 하는 클래스와 메소드들이 추가되었다. 이번 팁에서는 새로 추가된 java.util.Scanner클래스를 이용함으로써 일반 표현문을 사용하는 스트링과 프리미티브 타입을 읽고 파싱(parsing)하는 것이 어떻게 좀 더 쉬워졌는지 알아보도록 하자.

J2SE 5.0의 출시 이전에는 파일에서 텍스트를 읽으려면 다음의 TextReader 클래스 같은 코드를 작성해야했다.


  1. import java.io.BufferedReader;
  2. import java.io.FileReader;
  3. import java.io.IOException;
  4. import java.io.File;
  5.  
  6.  public class TextReader {
  7.   private static void readFile(String fileName) {
  8.     try {
  9.       File file = new File(fileName);
  10.       FileReader reader = new FileReader(file);
  11.       BufferedReader in = new BufferedReader(reader);
  12.       String string;
  13.       while ((string = in.readLine()) != null) {
  14.         System.out.println(string);
  15.       }
  16.       in.close();
  17.     } catch (IOException e) {
  18.       e.printStackTrace();
  19.     }
  20.   }
  21.  
  22.   public static void main(String[] args) {
  23.     if (args.length != 1) {
  24.       System.err.println("usage: java TextReader "
  25.         + "file location");
  26.       System.exit(0);
  27.     }
  28.     readFile(args[0]);
  29.   }
  30. }

이와 같은 클래스에서의 기본적인 접근법은 하드 드라이브의 실제 파일과 일치하는 File 오브젝트를 생성하는 것이다. 그리고 나서 그 파일과 관련된 FileReader와 그 FileReaderBufferedReader를 생성하고, 그 후 BufferedFile 리더를 사용하여 한번에 한 줄씩 읽는다.

실행되는 TextReader클래스를 보기위해서는 클래스에 대한 문서를 생성하여 읽고 파싱해야한다. 문서를 생성하기 위해서는 TextReader와 같은 디렉토리 안에 있는 TextSample.txt라는 파일에 다음과 같은 두 줄의 텍스트를 저장해야 한다.

   Here is a small text file that you will
   use to test java.util.scanner.

TextReader를 컴파일하고 다음을 입력하여 구동시켜보자.

   java TextReader TextSample.txt

표준 출력으로 되돌아온 원본 파일을 보게 될 것이다.

프리미티브 타입과 스트링을 파싱하는 클래스인 java.util.Scanner를 이용하여 TextReader의 코드를 간단하게 할 수 있다.


  1. import java.io.File;
  2. import java.io.FileNotFoundException;
  3. import java.util.Scanner;
  4.  
  5. public class TextScanner {
  6.  
  7.   private static void readFile(String fileName) {
  8.     try {
  9.       File file = new File(fileName);
  10.       Scanner scanner = new Scanner(file);
  11.       while (scanner.hasNext()) {
  12.         System.out.println(scanner.next());
  13.       }
  14.       scanner.close();
  15.     } catch (FileNotFoundException e) {
  16.       e.printStackTrace();
  17.     }
  18.   }
  19.  
  20.   public static void main(String[] args) {
  21.     if (args.length != 1) {
  22.       System.err.println("usage: java TextScanner1"
  23.         + "file location");
  24.       System.exit(0);
  25.     }
  26.     readFile(args[0]);
  27.   }
  28. }

TextScanner를 컴파일하고 다음과 같이 구동하자.

   java TextScanner TextSample.txt

다음과 같은 결과가 나타난다.

   Here
   is
   a
   small
   text
   file
   that
   you
   will
   use
   to
   test
   java.util.scanner.

TextScanner 는 파일로부터 Scanner 오브젝트를 생성한다. Scanner는 파일의 컨텐츠를 구획자 패턴을 이용하여 분해한다. 구획자 패턴의 디폴트 값은 흰 여백이다. 그 후 TextScannerScannerhasNext() 메소드를 호출한다. 이 메소드는 Scanner 입력값에 파일의 마지막 부분에 이를 때까지 다른 token이 있으면 'true'를 리턴한다. next() 메소드는 다음 token을 나타내는 스트링을 리턴한다. 따라서 TextScanner는 파일의 마지막부분에 이를 때까지 각 라인에서 next()에 의해 리턴되는 스트링을 프린트한다.

ScanneruseDelimiter 를 이용해 입력물을 토큰화하는 데 이용하는 구획자를 변경시킬 수도 있다. 메소드에 스트링 또는 java.util.regex.Pattern에 전달해주면 된다. 어떤 패턴들이 적절한 지에 대해서는 JavaDocs page for Pattern를 참조하기 바란다. 예를 들어 newline(\n)을 구획자로 이용하여 한번에 한 줄의 입력물을 읽을 수 있다. 다음은 새줄 문자를 구획자로 이용하는 수정된 readFile() 메소드이다.


  1.    private static void readFile(String fileName) {
  2.      try {
  3.        Scanner scanner = new Scanner(new File(fileName));
  4.        scanner.useDelimiter
  5.          (System.getProperty("line.separator"));
  6.        while (scanner.hasNext()) {
  7.          System.out.println(scanner.next());
  8.        scanner.close();
  9.      } catch (FileNotFoundException e) {
  10.        e.printStackTrace();
  11.      }
  12.    }

마지막 줄을 찾는 다른 옵션들도 있다. 예를 들어 새줄 문자로 끝나는 라인이나 캐리지 리턴(enter키)과 newline으로 끝나는 라인들을 조사할 수 있다. "\r\n|\n" 일반 표현문을 이용하여 이를 실행할 수 있다. java.util.regex.Pattern의 JavaDocs는 또다른 라인 종결기들을 보여주므로 좀 더 복잡한 분석은 "\r\n|[\r\n\u2028\u2029\u0085]"표현문을 이용한다. 또한 Scanner 클래스의 hasNextLine()nextLine() 메소드를 이용할 수 있다. 어느 경우이던 수정된 TextScanner를 사용하면 결과물은 TextSample.txt의 컨텐츠와 레이아웃에 부합될 것이다. 다음을 참고하기 바란다.

   Here is a small text file that you will
   use to test java.util.scanner.

Scanner에 의해 사용된 구획자의 패턴을 간단하게 변경하여 큰 효과와 유연성을 얻을 수 있다. 예를 들어 다음의 구획자를 지정하면,

   scanner.useDelimiter("\\z");

한번에 전체 파일을 읽는다. 이는 Pat Niemeyer가 java.net blog에서 제안하고 있는 요령과도 비슷하다. 몇 개의 중간 오브젝트를 생성하지 않고도 웹페이지의 모든 컨텐츠를 읽을 수 있는 것이다. 다음 WebPageScanner클래스의 코드는 java.net homepage의 현재 컨텐츠를 읽고 있다.


  1.    import java.net.URL;
  2.    import java.net.URLConnection;
  3.    import java.io.IOException;
  4.    import java.util.Scanner;
  5.  
  6.    public class WebPageScanner {
  7.      public static void main(String[] args) {
  8.        try {
  9.          URLConnection connection =
  10.            new URL("http://java.net").openConnection();
  11.          String text = new Scanner(
  12.            connection.getInputStream()).
  13.            useDelimiter("\\Z").next();
  14.        } catch (IOException e) {
  15.          e.printStackTrace();
  16.        }
  17.      }
  18.    }

Scanner 클래스로 스트링 이외의 것들도 다룰 수 있다. 프리미티브 타입으로 이루어진 데이터를 파싱하는 데에도 사용할 수 있다. 이에 대한 예제로, 다음의 세 라인을 Employee.data라는 이름의 파일(TextSample와 같은 디렉토리 안)에 저장하자.

   Joe, 38, true
   Kay, 27, true
   Lou, 33, false

이를 하나의 큰 스트링으로 취급하여 이 스트링을 파싱한 후에 대화문을 실행할 수도 있지만, 대신에 이 파일을 두가지 단계로 파싱해보자. 이는 다음의 클래스 DataScanner에 설명되어 있다.


  1.    import java.util.Scanner;
  2.    import java.io.File;
  3.    import java.io.FileNotFoundException;
  4.  
  5.    public class DataScanner {
  6.  
  7.      private static void readFile(String fileName) {
  8.        try {
  9.          Scanner scanner =
  10.            new Scanner(new File(fileName));
  11.          scanner.useDelimiter
  12.            (System.getProperty("line.separator"));
  13.          while (scanner.hasNext()) {
  14.            parseLine(scanner.next());
  15.          }
  16.          scanner.close();
  17.        } catch (FileNotFoundException e) {
  18.          e.printStackTrace();
  19.        }
  20.      }
  21.  
  22.      private static void parseLine(String line) {
  23.        Scanner lineScanner = new Scanner(line);
  24.       lineScanner.useDelimiter("\\s*,\\s*");
  25.        String name = lineScanner.next();
  26.        int age = lineScanner.nextInt();
  27.        boolean isCertified = lineScanner.nextBoolean();
  28.        System.out.println("It is " + isCertified +
  29.          " that " + name + ", age "
  30.          + age + ", is certified.");
  31.      }
  32.  
  33.      public static void main(String[] args) {
  34.        if (args.length != 1) {
  35.          System.err.println("usage: java TextScanner2"
  36.            + "file location");
  37.          System.exit(0);
  38.        }
  39.        readFile(args[0]);
  40.      }
  41.    }


DataScanner의 바깥쪽 Scanner 오브젝트는 한번에 한 라인씩 파일을 읽는다. readFile() 메소드는 각 라인을 두번째 스캐너에 전달하고, 이 두번째 스캐너는 콤마로 ,구획된 데이터를 파싱하고 콤마 양쪽의 흰 여백을 삭제한다. 다음 token이 특정타입의 token인지 아닌지 분석하여 다음 token을 그 타입의 인스턴스로 취급하도록 하는 hasNext()next()메소드들도 있다. 예를 들어 nextBoolean()은 다음 token을 boolean으로 취급하여 "true" 또는 "false" 스트링과 매치시킨다. 매칭이 이뤄지지 않으면 java.util.InputMismatchException이 던져진다. DataScannerparseLine() 메소드는 각 라인이 어떻게 String, int, boolean으로 파싱되는지 보여준다.

Compile DataScanner. Then run it as follows:

DataScanner를 컴파일하고 다음과 같이 구동시키자.

   java DataScanner Employee.data

다음과 같은 결과가 나타난다.

   It is true that Joe, age 38, is certified.
   It is true that Kay, age 27, is certified.
   It is false that Lou, age 33, is certified.

콤마를 구획문자로 사용하고 싶을 것이다. 다시 말해 다음과 같이 시도해보려고 할 것이다.

   lineScanner.useDelimiter(",");

이는 결국 InputMismatchException로 끝날 것이다. 이는 boolean으로 변경하려는 token에 여분의 공간이 포함되며 이 공간은 "true"나 "false" 에 매치되지 않기 때문이다. 일반적인 표현문의 모든 애플리케이션에 해당되는 케이스이므로 패턴을 구축하는 데 있어서 특히 세심한 주의가 필요할 것이다.

Scanner에 대한 좀 더 자세한 정보는 formal documentation를 참고하기 바란다.

저자 : Daniel H. Steinberg
원문 출처 : http://kr.sun.com/developers/techtips/c2004_1201.html

2007/06/24 11:28 2007/06/24 11:28
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

Vector에 대한 소고

이 기사에서는 다른 알고리즘 관련 도서와 마찬가지로 알고리즘(설계)가 중요하다고 말한다. 전적으로 동의하는 바이다. 알고리즘은 중요하다.

하지만, 전산 경력이 6년이 넘어가도록 알고리즘이 문제가 되었던 적은 알고리즘 관련 수업에서 나오는 과제와 소프트웨어 엔지니어링 수업에서 나온 이상한 과제를 할 때 뿐이었다. 그렇게 중요한 것이라면, 경력의 대부분을 차지하는 현장 경험에서는 왜 알고리즘이 중요하는 사실을 몰랐을까? 적어도 알고리즘을 사용하지 않았을리는 없고, 그렇다면 남들이 해서 숨겨 놓은 알고리즘을 나도 모르게 사용한 것이 아닐까 생각된다. 이런 일들이 가장 잘 일어나는 곳은 데이터베이스와 자바 패키지가 아닐까 생각된다. 데이터베이스는 정렬과 Search를 단 몇 단어로 가능하게 만들지만, 정렬과 Search는 알고리즘에서 가장 중요한 분야 중에 하나이며, 아직도 연구가 끝나지 않은 분야이다. 자바에서 제공하는 표준 API중에도 알고리즘을 제공하는 것이 많다.

자바 표준 API 중에서 java.util 패키지는 알고리즘과 항상 단짝이 되어 나오는 자료 구조(Data Structure)의 Implementation들을 제공하는데, 그 중에 하나가 Vector이다. 실제 얘기에 들어가기 전에 몇 가지 재미난 데이터를 살펴보자.

그림1

위 그래프는 VectorTest.java의 실행결과를 보여주고 있다. 아래 데이터는 VectorInd.java의 실행결과를 보여주고 있다.

> java VectorInd 1000000
Insert Time [749] : 11
Insert Time [61480] : 6
Insert Time [122880] : 48
Insert Time [245760] : 70
Insert Time [491520] : 113
Insert Time [983040] : 215
Insert Time [983917] : 18

소스에서도 알 수 있듯이, 그래프는 각 데이터 크기만큼 Vector에 add를 한 것이고, 변화 폭이 큰 것은 입력되는 위치가 Vector의 처음이고, 아래 그래프는 입력되는 위치가 Vector의 마지막이다. 똑같은 데이터를 입력하지만, 실행 속도는 엄청나게 차이가 난다. 이것을 알고리즘에서 사용하는 용어로 표현하면, 전자의 수행속도는 O(n*n), 후자는 O(n)로 표현된다. 루프를 제외하면, 각각 add에 걸리는 시간은 O(n), O(1)이다. 아래 두 그림은 그 차이를 보여준다.

그림2

위의 그림은 마지막에 입력되는 경우를 보여주고, 아래 그림은 첫번째 위치에 입력되는 경우이다. 아래의 경우에는 입력되어 있는 데이터의 수만큼 데이터가 이동해야 한다. 만약, 10번의 입력이 일어나면, 실제로는 10 + 9 + 8 + … + 2 + 1 = 10 * 9 / 2 번의 시간이 걸니는 것이다. 데이터가 커지면 커질수록 치루어야 하는 대가는 급속하게 커진다.

정말 모든 addLast가 일정한 시간이 들어가는지를 보여주는 것이 VectorInd.java이다. 데이터 입력 시간이 3 millisecond 이상 들어가는 경우에 소요된 시간을 프린트한 것이다. 백만번 중에 7번 발생했다. 처음과 마지막 데이터를 제외하면, 데이터가 두 배가 되어질 때 시간이 많이 걸리는 현상이 발생했다. 그 이유를 그림으로 설명하면 다음과 같다.

그림3

사용자에게 보이지는 않지만, Vector는 데이터를 저장하기 위해 Array를 만들었다. 만든 Array의 사이즈는 무한하지 않기 때문에 데이터를 계속 입력하면, 공간이 부족하게 되고, Vector는 이 때 원래 사이즈의 두 배의 크기의 Array를 만들고, 가지고 있던 데이터를 새로운 Array로 이동시킨다. 즉, Array에 데이터가 입력될 때, Array가 부족하면 기존에 저장된 데이터의 크기(Array 사이즈) 만큼의 데이터 이동이 일어나게 된다. 위 자료에서 보듯이, 데이터 사이즈가 두 배에 도달할 때마다 약 2 배 가량의 시간이 더 걸리는 것을 볼 수 있다.

이때가지의 관찰결과에 따르면, Vector의 인덱스가 작은 쪽에는 입력하는 것도, 삭제하는 것도 좋지 못하다. 그만큼의 댓가(실제 데이터 사이즈 - Index만큼의 데이터 이동)를 치루어야 하기 때문이다. 그리고, 데이터가 입력되는데 걸리는 시간을 반드시 일정한 시간이하로 낮추어야 하는 경우에는 일반적인 Vector를 사용할 수 없다.

실제로 Vector는 인덱스 관리가 편리한 Array에 불과한 것을 알 수 있다. 하지만 Array 작업시 문제가 되는 것들은 여전히 Vector에서도 문제가 된다. 그러므로 처음 넣은 데이터를 가장 먼저 지워야 되는 일에는 Vector를 사용하지 않는 것이 좋다. 이 작은 사실 하나가 위 그래프에서 볼 수 있듯이 데이터가 많은 경우, 실제 프로그램의 실행속도에는 엄청난 영향을 미치게 된다.

Note : VectorInd의 작업결과는 리눅스에서 실행한 것이다. 필자의 윈도우에서는 다른 실행결과가 나왔다. 출력되는 데이터의 모든 시간은 10이였다.

[VectorTest.java]

  1. import java.util.Vector;
  2. import java.util.Calendar;
  3.  
  4. public class VectorTest {
  5.  
  6.     public static void main(String[] args) {
  7.  
  8.          Vector target      = new Vector();
  9.          String obj          = new String("Vector Data");
  10.          Calendar   start, end;
  11.          long    interval   = 0;
  12.          long    LIMIT       = 0;
  13.          int      index       = 0;
  14.  
  15.          long    MAX = Long.parseLong(args[0]);
  16.          
  17.          for ( LIMIT = MAX / 10 ; LIMIT <= MAX ; LIMIT = LIMIT + MAX/10 ) {
  18.              start = Calendar.getInstance();
  19.              for ( index=0 ; index < LIMIT ; index++) {
  20.                   target.add(index, obj);
  21.              }
  22.              end    = Calendar.getInstance();
  23.  
  24.              interval = end.getTimeInMillis() - start.getTimeInMillis();
  25.              System.out.println(index + " " + interval);
  26.              target = new Vector();
  27.          }
  28.  
  29.          System.out.println("===========================");
  30.  
  31.          for ( LIMIT = MAX / 10 ; LIMIT <= MAX ; LIMIT = LIMIT + MAX/10 ) {
  32.              start = Calendar.getInstance();
  33.              for ( index=0 ; index < LIMIT ; index++) {
  34.                   target.add(0, obj);
  35.              }
  36.              end    = Calendar.getInstance();
  37.  
  38.              interval = end.getTimeInMillis() - start.getTimeInMillis();
  39.              System.out.println(index + " " + interval);
  40.              target = new Vector();
  41.          }
  42.     }
  43.  
  44.    
  45. }


[VectorInd.java]


  1. import java.util.Vector;
  2. import java.util.Calendar;
  3.  
  4. public class VectorInd {
  5.  
  6.     public static void main(String[] args) {
  7.    
  8.          Vector target = new Vector(30);
  9.          Object obj      = new Object();
  10.  
  11.          Calendar   start, end;
  12.          long         interval = 0;
  13.  
  14.          int LIMIT = Integer.parseInt(args[0]);
  15.  
  16.          for ( int index = 0 ; index <= LIMIT ; index++ ) {
  17.              start = Calendar.getInstance();
  18.              target.add(obj);
  19.              end    = Calendar.getInstance();
  20.              interval = end.getTimeInMillis() - start.getTimeInMillis();
  21.              if ( interval > 3 ) {
  22.                   System.out.println("Insert Time : " + interval);
  23.              }
  24.          }
  25.  
  26.     }
  27. }



저자 : 김대곤
원문 출처 : http://network.hanb.co.kr/view.php?bi_id=964
2007/06/24 11:17 2007/06/24 11:17
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

로그인을 해야 글을 볼수 있는 곳에 애드센스를 달았다면. :: AdSense의 사이트승인 기능

일반적으로 비밀글/회원제운영 홈페이지에 달린 애드센스 광고는 크롤링을 할 수 없었습니다.
(크롤링을 할 수 없으면 수익 통계를 낼 수 없죠..)
이러한 문제를 해결하기위해 애드센스에 얼마전 새로운 '사이트 인증' 기능이 추가 되었습니다.

아래처럼 보고서에 들어가면 '오늘의 수입' 오른편에 새로운 '사이트 인증' 기능을 공지하고 있습니다.
에드센스 보고서

'애드센스 설정' -> '사이트 인증' 메뉴를 통해서도 똑같이 접근이 가능 합니다.

아래는 '사이트 인증' 메뉴 화면 입니다.
에드센스 사이트인증
이 페이지에서 로그인 정보를 기재 함으로써 공개된 페이지가 아닌 곳에 부착된 애드센스에 대한 크롤링을 수행 할 수있습니다.
2007/06/23 17:54 2007/06/23 17:54
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

검은집 :: 싸이코패스

검은집

검은집



더위를 참지못해 집을 뛰쳐나가 심야로 '검은집'을 보고 왔다.

연기력을 의심할 만한 배우는 없었으니 소설을 읽으며 내 머리속에서 그려진 상황을 영화에선
어떻게 연출했는지 비교 해 보는 것도 재미있을것 같고..
굳이 이런저런 이유를 달지 않아도 개봉 소식 접하면서부터 보고 싶엇던 영화이기도 했기에.

개인적으론 잘  만들어 졌다고 생각한다.
소설에서 보여주는 사건전개를 설명하는 많은 정황 장면들이 상영시간의 제약으로 빠지긴 했지만
스토리 전개가 부자연 스럽거나 하진 않다.

소설보단 한템포 빨리 범인을 밝혀주지만 그 이후 긴장감이 더 해 지는 괜찮은 연출을 보여 준다.

스릴러물 좋아한다면 추천!!
보면서 손발이 오그라드는 걸 느낄 수 있을 것이다. ^^
( 이런 표현 쓸만한 영화는 데스티네이션 2이후 처음인 것 같다. )

영화 끝나고 나오는 로비에서 어떤 여자가 했던 말이 기억에 맴돈다..
'황정민이란 배우가 있고 탄탄한 원작이 있어서 보게됐는데.. 이렇게 잔인할 줄 몰랐어..'


2007/06/23 04:44 2007/06/23 04:44
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다
  1. 2007/06/24 00:44
    검은집 Tracked from 구손랜드®

Porco Rosso



2007/06/22 23:22 2007/06/22 23:22
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

왜 이렇게 더운거냣!!

한달간의 지리한 장마가 시작 된다더니..
어제 조금 비 내린곤 보란듯이 화창한 날씨가...
방에 앉아있자니 조금 덥네...

집앞 CGV Cinus 라도 가서 심야로 '검은집'이나 보러 갈까..?
소설로 읽었을땐.. 전반부는 이야기 흐름도 느긋하고 상황 설명이나 묘사의 디테일도
잘 살아있는데, 독자들도 범인을 눈치채는 시점부턴 미저리 류의 싸이코스릴러 물로
돌변하던데..

영화는 어떻게 구성 되었을까?
일부러 영화평 같은거 외면하면서 안봤는데.. 오늘 이 녀석을 보려고 그런건가..?

샤워한판 때리고 느긋이 다녀와봐야 겠다..

2007/06/22 23:05 2007/06/22 23:05
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

생성패턴(creational pattern) :: 디자인 패턴

Abstract Factory



Abstract Factory 패턴의 구조는 위 그림과 같다. AbstractFactory라는 추상 클래스가 있고, 그 추상 클래스는 필요한 객체들을 생성하는 인터페이스를 가지고 있다. 실제로 객체를 생성하는 역할을 맞는 클래스(ConcreteFactory)들은 AbstractFactory 추상클래스를 상속하고 객체 생성 인터페이스를 구현한다. AbstractFactory 추상 클래스를 상속하는 ConcreteFactory를 여러 종류 만들 수도 있는데 각 클래스가 하나의 객체 Family를 이루게 된다. Client는 ConcreteFactory가 생성하는 실제 객체들(Product..)들의 부모인 AbstractProduct에 대해서만 알고 있어도 된다.
Abstract Factory 패턴은 ConcreteFactory만 교체하면 전체 Product들이 바뀌는 효과를 낼 수 있다. 흠..내 생각에 이런 것이 필요한 대표적인 경우로는 인터페이스의 스킨기능을 들 수 있을 것 같다. 책에도 이 패턴이 대표적으로 사용되는 경우가 인터페이스의 구성요소를 통째로 갈아끼우는 식의 구현이 필요할 때라고 적혀 있다.

Builder


Builder 패턴의 구조는 위 그림과 같다. Director가 Builder에게 어떤 객체의 생성을 요청하면 Builder가 척척 만들어서 Director에게 제공한다. 객체 생성을 전담하는 클래스가 따로 있다는 점에서 Abstract Factory패턴과 비슷하긴 한데, 약간 다른 점은 주로 Builder패턴은 복잡한 객체를 순서대로(step by step)만드는 반면 Abstract Factory 패턴은 주로 한 종류로 구분할 수 있는(Family) 객체들을 만드는 것에 중점을 두고 있다.

Factory Method


Factory Method패턴은 가장 간단한 생성 패턴이라고 한다. 별거 없이 객체를 직접 new로 생성하지 않고 FactoryMethod를 통해서 생성하는 방법이다. 흠..나름대로 Creator를 여러가지로 상속해서 확장을 꾀할 수 있다.

Prototype



가장 이해하기 힘들었던 패턴이다. 아직도 언제 어떻게 사용해야 할지 잘 모르겠다. C++관점으로 설명하자면. Client는 Prototype 추상 클래스의 포인터를 가지고 있다. Client가 생성될 때 적당한 ConcretePrototype(Prototype추상 클래스를 상속한 구체 클래스)를 생성하여 Client가 가지고 있는 Prototype포인터에 대입해서 유지 한다. Client가 객체를 생성하고 싶을 때 Prototype포인터에 Clone함수를 호출해서 생성한다.
Prototype 패턴의 핵심은 바로 Clone인터페이스 이다!

Singleton
Singleton패턴은 전체 프로세스 상에서 객체가 유일하게 생성되는 클래스를 정의하는 패턴이다. 이 이야기는 More Effective C++에 이미 나왔던 이야기인데, 클래스의 생성자를 public으로 하지 않으면 직접 클래스의 객체를 생성할 수 없게 된다는 점을 이용하면 된다.
클래스의 생성자를 protected나 private으로 하고, 클래스의 객체를 생성하는 인터페이스를 따로 만든다.
간단한 소스로 이해 해보자.

  1. class Singleton {
  2.   public:static void Singleton* Instance();
  3.   protected:static Singleton();
  4.   private:static Singleton* _instance;
  5. };
  6.  
  7. Singleton* Singleton::_instance = 0;
  8.  
  9. Singleton* Singleton::Instance(){
  10.   if(_instance == 0){
  11.     _instance = new Singleton;
  12.   }
  13.   return _instance;
  14. }



2007/06/22 14:44 2007/06/22 14:44
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

디자인 패턴 for 자바 :: Design Pattern for JAVA

2005년도 한창 패턴에 관심을 갖던 시기에 구한 도표인데.. 출처는 기억이 나질 않는군요..

디자인패턴 Design Pattern

2007/06/21 17:50 2007/06/21 17:50
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

구조패턴(structual pattern) :: 디자인 패턴

구조 패턴이라고 해석할 수 있을까나? structural pattern들은 객체들을 잘 구슬려서 어떤 구조를 만들어 내는 패턴들이다. 분류가 왜 이렇게 된 건지 잘 이해가 되진 않는다. 여하튼 패턴들을 살펴보자.

Adapter

Adapter패턴은 인터페이스가 서로 맞지 않는 두 클래스 사이에서 인터페이스를 맞춰주는 역할을 한다. Adaptee라는 클래스가 이미 존재한다고 하자.(어디 존재하는지는 별로 중요하지 않고..라이브러리 안쪽에 있을수도.. 소스코드로 있을수도..) Target에서 뭔가 작업을 하려고 하는데 그 작업이 이미 Adaptee에 구현된 작업과 매우 유사하다. 그런데 Target과 Adaptee의 인터페이스 구조가 달라서 어떻게 하기가 좀 곤란하다. 그럴 때 Adapter패턴을 사용한다. Adapter는 Target을 public상속(interface 상속)하고, Adaptee는 private상속을 해서(implementation만 상속한다는 뜻) Adapter에서는 Target의 인터페이스를 Adaptee의 구현을 이용해 구현하면 된다.(위쪽 그림 – Class Adapter)
private상속을 이용하지 않고 Adapter가 Adaptee를 멤버로 가지고 직접 Adaptee객체를 이용해 Adaptee의 구현을 활용할 수도 있따.(아래 그림 – Object Adapter)

실제 예를 들어 설명하면, Shape라는 추상 클래스가 있다. 어떤 모양을 나타내는 것일 테다. 이놈을 상속해서 LineShape도 만들 수 있고, CircleShape도 만들 수 있을 거다. TextShape도.. 그런데 TextShape를 만들려고 하다 보니 이미 TextView라는 이름으로 구현하려고 했던 대부분의 기능이 구현되어 있는 클래스가 있다고 해보자. TextShape를 TextView의 구현을 이용해서 만들고 싶다. 이럴 때 Adapter패턴을 적용하면 딱 이다. TextShape를 Shape를 public상속, TextView를 private상속하게 하거나, TextShape가 TextView의 객체를 가지고 구현을 이용하게 하거나 하면 될 것이다.


Bridge

이 패턴을 클래스의 추상부분과 구현을 분리 시켜서 뭔가를 얻어 보려는 패턴이다. 이게 여러모로 쉽게 확장을 할 수 있게 해준다. 역시 예를 들어 알아보자. 책에 나와 있는 Window시스템을 보자.
그냥 생각해서 Window를 나타내는 추상 클래스가 있고, 이놈을 상속해서 XWindow시스템, PMWindow시스템 이렇게 늘려간다고 해보자. 이제 아이콘을 나타내기 위해 IconWindow라는 놈을 만들려고 하면, XWindow용으로 XIconWindow도 만들어야 하고, PMWindow용으로 PMIconWindow도 만들어야 한다. 계속 추가 시켜나가야 할 양이 많아진다. 즉 확장이 쉽지 않다.
이런 놈을 Bridge패턴을 적용해서 이렇게 만들면 어떨까? Window라는 추상 클래스를 만든다. 그리고 WindowImp라는 구현을 담당하는 추상 클래스를 만든다. Window를 상속하여 IconWindow, TransientWindow등을 만든다. 이때 이 클래스들의 인터페이스는 WindowImp를 상속한 클래스들의 구현을 이용해서 구현한다. WindowImp를 상속하여 XWindowImp, PMWindowImp를 만들 수 있을 거고, Window를 상속하는 놈들은 이렇게 구현된 것들을 이용해서 만드는 것이다. 흠.. 이때 XWindowImp와 PMWindowImp는 Window를 상속하는 클래스들에서 필요할 만한 기본적인 구현들을 포함하고 있어야 한다.


Composite

Composite패턴은 쉽게 말해 묶음을 지을 수 있게 하고, 묶음을 낱개하고 똑같이 취급할 수 있게 하는 패턴이다.
흠..위 그림을 보면 Component 추상 클래스가 있다. 이것을 상속해서 Leaf클래스를 만들 수도 있고, Composite클래스를 만들 수도 있다. Composite클래스는 Component들을 Child로 포함할 수 있다. Composite도 Compnent니까 Composite가 Composite를 recursive하게 포함할 수 있다는 소리다. 이런 패턴을 주변에서 많이 볼 수 있다. 흠..컴퓨터 시스템만 해도 그렇다. 몇 개의 부품을 모으면 하나의 모듈이 되고 그 모듈이 또 전체 컴퓨터 시스템에 참가 하고.. 어쩌고 저쩌고.. 궁시렁 궁시렁..


Decorator

Decorator는 이름에 걸맞게 장식을 하는 패턴이다.
후훗. 그러니까.. Decorator는 Component를 상속하고 Component하나를 자기 안에 가지고 있는다. 그리고 Operation을 할 때 그 가지고 있던 Component의 Operation을 수행한다. 이때, Decorator는 그 Operation외에 어떤 작업(AddedBehavior)를 추가적으로 수행한다. 기본 작업(Component의 Operation)에 어떤 작업(AddedBehavior)를 추가 해서 장식을 하는 것이다. 실례를 들어 보자.
어떤 인터페이스 시스템에 VisualComponent라는 추상클래스가 있다. 그 추상 클래스를 상속하여 여러 인터페이스 요소들을 만드는데 TextView라는 것이 있다고 하자. 이 TextView를 포함한 VisualComponent들에 ScrollBar나 Border를 추가하고 싶다고 할 때, Decorator패턴을 사용할 수 있다.

위 그림을 보라!


Facade

Facade패턴은 조금 단순하다. 아래 그림을 보라.

이렇게 subsystem들을 외부에 공개하는 객체를 만드는 패턴을 Facade패턴이라고 한다.


Flyweight

이 패턴은 아주 자주 사용되는 객체들을 공유해서 과도한 메모리 사용량을 줄일 수 있는 패턴이다.(과도하다기 보다는 거의 구현 불가능한 정도의 메모리 사용량을 필요로 하는 경우라고 할 수도 있겠다.) 대표적인 예로, 문서 편집기를 만들 때, 각 글자 객체들을 관리하는 예가 책에 제시되어 있다. 아래 다이어그램을 보자.

GlyphFactory는 _character에 Character클래스의 객체들을 쭉 가지고 있는다. Character의 종류라고 해봤자 얼마 안될 것이기 때문에 쭉 가지고 있으면서 공유해서 사용하면 된다. 위의 경우 글자의 폰트등은 GlyphContext에서 관리해서 꾸며준다. 흠..자세히 이해하긴 힘들어서 더 이상 설명은 곤란..ㅠ.ㅠ

Proxy

Proxy패턴은 어떤 객체를 대신하는 Proxy객체를 만드는 패턴. 네트워크 저편에 있는 어떤 객체를 대신하는 remote proxy, 객체가 너무 커서 꼭 필요할 때만 생성해서 사용하게 큰 객체를 대신하는 virtual proxy, 원래 객체를 숨겨서 권한에 따라 접근 성을 다르게 주게 할 수 있는 protection proxy, 스마트 포인터등의 smart reference등으로 사용할 수 있는 패턴이다.
2007/06/21 17:44 2007/06/21 17:44
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

Mell - Red Fraction Single [Black Lagoon Opening]

Mell - Red Fraction Single


 

Red Fraction..


2007/06/20 20:13 2007/06/20 20:13
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

Matsuda Seiko ( 松田聖子 まつだせいこ ) :: 마츠다 세이코

어린 시절 추억을 들추게 하는 곡 중의 하나.


あなたに逢いたくて - 마츠다 세이코


내가 중학생이 될 때까지 아버지는 일본의 모 가전회사에서 근무를 하셨다.
그런 덕분에 워크맨류의 카셋트 플레이어나 일본 음반같은걸 접해볼 기회가
종종 있었는데, 세이코 마츠다앨범도 그 시절 아버지께서 출장 중 구해
오셔서, 비록 가사는 못알아들었지만, 즐겨 듣곤 했다.

세이코씨가 일본의 80년대를 장식한 수퍼 아이돌 가수란 사실도
대학 입학 후 알게 되었을 정도로 마츠다 세이코란 가수에는 관심이 없었는데
한동안 기억속에 잊혀져 있던 그녀의 곡을 다시 듣고 있자니
나도 모르게 어린시절을 추억이 떠올라 혼자 피식거리고 있다...


ps . 아.. 맞다.. 이와이 순지 감독의 영화 '러브레터'에서 유리세공사인 시게루가
이츠키를 찾아나선 여행 중 산에사는 불할아범이
'아~ 와타시노 코이와~ 미나미노 카제니 놋데 하시루와~'
라고 흥얼거리는 부분이 있는데 이 곡도 마츠다 세이코의 青い珊瑚礁 란 노래이다.
영화를 보면서 어찌나 반갑던지..
'푸른산호초'를 듣고 싶다면 여기로..
2007/06/20 16:36 2007/06/20 16:36
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다
  1. 이런걸 들으면 우리나라음악이 일본음악의 일부분만을 편협하게 받아들이고 있단 기분이 들어요. 10년 정도 늦게..-_-;

    그나저나 서비님의 일음 편력은 고전음악에서부터 시작된거로군요..ㅎ

  2. 그냥 귀에 익은 노래를 즐기는 수준에 그치는 저로선
    일본음악이나 국내 대중음악에대해 뭐라 할 순 없지만..

    90년대 중반 까지는 7,8년 차이를 두고 비슷하게 흘러간다고
    생각했던 적은 있습니다.

    대중가요나 팝을 즐기는 사람과 마찬가지로 저는 일본음악을
    즐기는 사람에 불과하답니다. ^^

디자인 패턴 ( Design Pattern )의 구분

객체지향 방법론의 가장 큰 장점인 재사용성과 모듈성을 극대화시켜 실제 구현 과정에서의 해결 방안으로 제시 가능한 것으로 이를 적용하면 시스템 개발은 물론 유지 보수에서도 큰 효과가 있다.     

  • 상위 단계에서 적용될 수 있는 개념          
  • 디자인뿐만 아니라 시스템 구조를 재사용 하기 쉽게 만들 수 있다.          
  • 개발에 따른 산출 문서를 보다 향상시킬 수 있다.          
  • 불명확한 클래스의 기능, 객체간의 부적절한 연관 관계 등을 제거해 현존하는 시스템에 대한 유지 보수도 용이하다.          
  • 제대로 만들어진 디자인을 보다 빠르게 얻어낼 수 있는 이점이 있다.          
  • 일반적인 설계 문제에 대한 솔루션을 제공하는 객체와 클래스와의 연관 관계를 묘사한 것이다.

[패턴의 분류와 종류]


기본 패턴(Fundamental Design Patterns)

  • 디자인 패턴 중에서도 가장 기본인 동시에 가장 중요한 패턴                 
  • 종류 : 델리게이션(Delegation) 패턴, 인터페이스 패턴, 이뮤터블(Immutable)패턴, 마커 인터페이스(Marker Interface) 패턴, 프록시(Proxy) 패턴 등

    생성 패턴(Creational Patterns)

  • 객체의 생성 방식을 결정하는데 포괄적인 솔루션을 제공하는 패턴                  
  • 클래스 정의와 객체 생성 방식을 구조화, 캡슐화하는 방법을 제시한다.                                  
  • 객체 생성 과정을 추상화시킨다는 특성을 갖고 있으며 클래스의 재사용을 위해 상속보다는 컴포지션 기법을 보다 많이 사용한다.                                  
  • 기본원리
                                    ① 시스템에서 사용하는 클래스 정보를 캡슐화
                                    ② 클래스에 의해 객체가 생성되는 방식                                  
  • 이점 : 전체적인 시스템 구성의 유동성이 향상되어 객체 행성 방식이 다양한 구조로 진행될 수 있다. 예를 들어, 객체의 구성을 컴파일 타임에 정적으로 정의할 수 있으며 필요에 따라 런타임에 동적으로 구성할 수 있다.                                  
  • 종류 : 팩토리 메쏘드(Factory Method) 패턴, 추상화 팩토리(Abstract Factory) 패턴, 프로토타입(Protytype) 패턴, 싱글턴(Singleton) 패턴, 오브젝트 풀(Object Pool) 패턴 등    

    분류 패턴(Partitioning Patterns)

  • 분석 단계에서 일반적으로 생기는 문제를 해결하는데 적합하다.                                  
  • 복잡한 행위자(Actors)를 분류하거나 비교적 큰 기능을 분류해 여러 클래스로 정의하는 방식을 제시한다.                                  
  • 종류 : 계층적 초기화(Layered Initialization) 패턴, 필터(Filter) 패턴, 컴포지트(Composite) 패턴 등

    구조화 패턴(Structural Patterns)

  • 다른 기능을 가진 객체가 협력을 통해 어떤 역할을 수행할 때, 객체를 조직화시키는 일반적인 방식을 제시한다.                                  
  • 클래스와 객체가 보다 대규모 구조로 구성되는 방법에 대한 해결안을 제시한다.                                 
  • 별도로 구성된 클래스 라이브러리를 통합하는데 유용하다.                                  
  • 생성 패턴과 달리 새로운 기능을 구현하기 위해 객체를 구성하는 방식 자체에 초점이 맞춰져 있다.                                
  • 런타임에 객체 컴포지션 구조를 변경할 수 있으며, 이를 통해 객체 구성에 유동성과 확작성을 추가할 수 있다.                                  
  • 종류 : 어댑터(Adapter) 패턴, 이터레이터(Iterator) 패턴, 브리지(Bridge) 패턴, 퍼케이드(Facade) 패턴, 플라이웨이트(Flyweight) 패턴, 디이나믹 링키지(Dynamic Linkage) 패턴, 가상 프록시(Virtual Proxy) 패턴 등  

    행위 패턴(Behavioral Patterns)

  • 객체의 행위를 조직화(organize), 관리(manage), 연합(combine)하는데 사용되는 패턴                                  
  • 객체간의 기능을 배분하는 일과 같은 알고리즘 수행에 주로 이용된다.                                  
  • 단지 객체나 클래스에 대한 유형을 정의하는 것이 아니라 그들 간의 연동에 대한 유형을 제시한다.                                 
  • 런타임에 따르기 어려운 복잡한 제어 흐름을 결정짓는데 사용할 수 있다.                                  
  • 객체의 인터커넥트(intercnnnect)에 초점을 맞춘 패턴        

  • 2007/06/19 19:18 2007/06/19 19:18
    Trackback Address:이 글에는 트랙백을 보낼 수 없습니다