프로그래밍/java 2014. 6. 15. 11:47

Object 클래스 정리


java.lang은 자바 프로그램에서 가장 많이 사용되는 패키지로서 자바 프로그램내에 'import' 문을 사용하지 않아도 자동으로 포함된다. 그만큼 자바 프로그램의 기본이 되는 클래스들과 인터페이스들이 포함되어 있다.


다음은 java.lang 패키지의 클래스 구조도이다.



물론 java.lang 패키지에는 더 많은 클래스들이 있다.  더 많은 클래스는 여기서 확인하자.  JAVA API DOC : Java.lang


Object 클래스는 java.lang 패키지 내의 최상위 클래스이며, String 클래스는 변하지 않는 문자열을 다룰 때, StringBuffer 클래스는 내용이 계속 변하는 문자열을 다룰 때 사용될 수 있다.



2. Object 클래스


java.lang.Object 클래스는 자바 API의 모든 클래스와 사용자가 정의한 모든 클래스의 최상위 클래스이다. 즉, 모든 자바 클래스들은 Object 클래스로부터 상속받는다.


사용자가 클래스를 정의할 때 클래스 선언부에 명시적으로 extends java.lang.Object를 지정하지 않아도 자동으로 상속받게 된다. 다시 말해 Object 클래스의 모든 메서드와 변수는 다른 모든 클래스에서도 사용 가능할 수 있다는 말이다.


* Object 클래스의 주요 메소드


 메소드

설 명 

boolean equals(Object obj) 

 두 개의 객체가 같은지 비교하여 같으면 true를, 같지 않으면 false를 반환한다.

String toString() 

현재 객체의 문자열을 반환한다. 

protected Object clone() 

객체를 복사한다. 

protected void finalize() 

가비지 컬렉션 직전에 객체의 리소스를 정리할 때 호출한다. 

Class getClass() 

객체의 클래스형을 반환한다. 

int hashCode() 

객체의 코드값을 반환한다. 

void notify() 

wait된 스레드 실행을 재개할 때 호출한다. 

void notifyAll() 

wait된 모든 스레드 실행을 재개할 때 호출한다. 

void wait() 

스레드를 일시적으로 중지할 때 호출한다. 

void wait(long timeout) 

주어진 시간만큼 스레드를 일시적으로 중지할 때 호출한다. 

void wait(long timeout, int nanos) 

주어진 시간만큼 스레드를 일시적으로 중지할 때 호출한다.


equals 메소드는 두 개의 객체를 참조하는 참조값이 같은 객체일 때 true를 반환하므로, 참조하는 객체의 주소값이 같은 경우를 말한다.


출처 : http://hyeonstorage.tistory.com/178



//
프로그래밍/JSP 2014. 6. 15. 11:44

블릿이란?

 

서블릿은 자바 플랫폼에서 웹 애플리케이션을 개발할 때 사용하는 핵심 기술로 웹 애플리케이션 확장이 용이하고 플랫폼에 독립적인 개발이 가능합니다.

 

장점 

 

1. 스레드를 기반으로 하므로 웹 애플리케이션 운영에 효율적입니다.

2. 자바를 기반으로 하므로 자바API를 사용할 수 있습니다.

3. 운영체제나 하드의 영향을 받지 않아 개발된 애플리케이션은 다양한 환경에서 실행이 가능합니다.

4. 콘텐츠와 비즈니스 로직을 분리할 수 있습니다.

 

서블릿 컨테이너

 

웹 서버는 서블릿 자체를 실행하지 못하므로 자바 가상머신을 내장한 컨테이너라는 서블릿 실행환경이 필요합니다.

 

클라이언트 요청에 대한 서블릿 동작 과정


1. 컨테이너는 서블릿 클래스를 로딩합니다.

2. 서블릿 클래스의 생성자 메소드를 호출해 인스턴스를 생성합니다.

3. 인스턴스의 init() 메소드가 호출됩니다. [단 한번만 실행됩니다.]

4. web.xml 파일을 참조해 url매핑을 확인하고 서블릿 인스턴스로부터 스레드를 생성하고 service() 메소드를 호출합니다.

5. 서블릿 종료시에 destory() 메소드를 호출합니다.

 

웹 어플리케이션 서버 [WAS]

 

기본적으로 JAVA EE를 지원하는 서버 소프트웨어로 기본적으로  서블릿과 JSP를 실행할 수 있습니다. 이 외에도 대규모 사용자 접속 등에서 성능을 보장하기 위한 클러스터링 및 페일오버, 트랜잭션, 데이터베이스 처리를 위한 다양한 관리 기능을 제공합니다.

 

서블릿 API

 

모든 서블릿은 javax.servlet.Servlet 인터페이스를 구현해야 합니다.

일반적으로는 javax.servlet.GenericServlet과 javax.servlet.http.HttpServlet 클래스 중 하나를 상속해서 구현합니다.  [HttpServlet은 GenericServlet의 하위 클래스로 HTTP 처리와 관련된 부가 기능이 추가된 구조입니다.]

 

GET 방식과 POST 방식

 

HTTP에서 클라이언트 요청은 크게 GET방식과 POST방식으로 나뉩니다.

 

GET 방식


1. GET은 서버에 있는 정보를 가져오기 위해서 설계되었습니다. [최대 240 Byte까지 서버로 정보를 전달할 수 있습니다.]

2. 아래와 같은 형식으로 ?이후의 값들은 서버에서 QUERY_STRING 환경변수를 통해서 서버로 전달되고 &는 여러 속성 값을 전달할 때 연결해주는 문자열입니다.

http://www.xxx.com/servlet/login?id=xx&name=yy

3. URL이 노출되기 때문에 보안 문제가 생길수 있습니다.

 

POST 방식

 

1. 서버로 정보를 올리기 위해 설계되었고 전달할 수 있는 데이터 크기는 제한이 없습니다.

2. URL에는 파라미터가 표시되지 않습니다.


 

클라이언트 요청이 있을시 처리 순서 

1. 컨테이너는 서블릿 클래스를 로딩합니다.

2. 서블릿 클래스의 생성자 메소드를 호출해 인스턴스를 생성합니다.

3. 인스턴스의 init() 메소드가 호출됩니다. 이때 init() 메소드는 단 한번만 실행됩니다.

4. 서블릿에 사용자 요청에 대해서는 web.xml 파일을 참조해 URL매핑을 확인하고, 해당 서블릿 인스턴스로부터 스레드를 생성하고 service() 메소드를 호출합니다. 모든 사용자 요청에 대해 개별적인 service() 메소드가 호출되며, 이후 GET/POST에 대해 doGet()이나 doPost()등의 메소드가 호출됩니다. 서블릿 개발자는 이들 메소드에 필요한 기능을 구현 합니다.

5. destory() 메소드는 서블릿 종료 시 호출되는 메소드입니다.


 

서블릿 생명주기

 

1. 서블릿 로딩 : init() 메소드


클라이어트 요청이 들어오면 컨테이너는 해당 서블릿이 메모리에 있는지 확인하고 없을 경우 init()메소드를 호출하여 다시 적재합니다. 즉, init() 메소드는 처음 한 번만 실행되기 때문에 해당 서블릿에 각각의 스레드에서 공통적으로 사용하기 위해 필요한 작업이 있다면 init() 메서드를 오버라이딩해서 구현하면 됩니다. 실행중 서블릿이 변경될 경우에는 기존 서블릿은 파괴되고 새로운 내용을 다시 적재하기 위해 init() 메소드가 호출됩니다.

 

2. 요청 처리 : service() 메소드

 

init() 메소드는 최초에 한 번만 수행되고 이후 요청은 스레드로 실행되며 각각 service() 메소드를 통해서 doGet() 이나 goPost()로 분기됩니다. 이때 HttpServletRequest와 HttpServletResponse 구현으로 사용자 요청처리를 하는 request와 응답처리를 하는 reponse객체가 제공됩니다.

 

3. 서블릿 종료 : destory() 메소드

 

컨테이너로부터 서블릿 종료 요청이 있을 때는 destory() 메소드를 호출합니다. init() 메소드와 마찬가지로 한 번만 실행되며, 서블릿이 종료되면서 정리해야 할 작업이 있을 때는 destory()메소드를 오버라이딩해서 구현하면 됩니다.

 

[출처] 서블릿이란?|작성자 방글라

출처 : http://blog.naver.com/gmlwns77/50173254067

//
프로그래밍/java 2014. 6. 13. 16:39


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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import java.util.*;
 
public class SpeedTest {
 
    public static long add( List list ) // 순차적인 삽입.
    {
        long start_time = System.currentTimeMillis();
         
        for (int i = 0 ; i<100000 ; i++)
        {
            list.add(i+"");
        }
         
        long end_time = System.currentTimeMillis();
         
        return end_time - start_time;
    }
     
    public static long add2( List list ) // 중간에 삽입
    {
        long start_time = System.currentTimeMillis();
         
        for (int i = 0 ; i<100000 ; i++)
        {
            list.add(1000 , "a"); // 100번째 에 삽입
        }
         
        long end_time = System.currentTimeMillis();
         
        return end_time - start_time;
    }
     
    public static long remove(List list)
    {
        long start_time = System.currentTimeMillis();
         
        for (int i = 0 ; i<100000 ; i++)
        {
            list.remove(500);
        }
         
        long end_time = System.currentTimeMillis();
         
        return end_time - start_time;
         
    }
    public static long remove2(List list)
    {
        long start_time = System.currentTimeMillis();
         
        for (int i = list.size()-1 ; i>0 ; i--)
        {
            list.remove(i);
        }
         
        long end_time = System.currentTimeMillis();
         
        return end_time - start_time;
         
    }
    public static long access(List list)
    {
        long start_time = System.currentTimeMillis();
         
        for (int i = 0; i<1000 ; i++)
        {
            list.get(i);
        }
         
        long end_time = System.currentTimeMillis();
         
        return end_time - start_time;
    }
    public static void main(String[] args)
    {
         
        ArrayList al = new ArrayList( 1000000 );   
        LinkedList ll = new LinkedList();
         
         
         
        System.out.println("순차적으로 삽입하는 시간");
        System.out.println("Arraylist " + add(al));
        System.out.println("LinkedList " + add(ll));
        //순차적일 경우는 arraylist 가 빠르다.
         
         
        System.out.println("중간에 추가하는 시간");
        System.out.println("Arraylist " + add2(al));
        System.out.println("LinkedList " + add2(ll));
        //중간에 추가할경우 LinkedList 가 빠르다 훨신!
         
        System.out.println("접근시간 테스트");
        System.out.println("Arraylist " + access(al));
        System.out.println("LinkedList " + access(ll));
         
         
        System.out.println("중간에서 삭제하기");
        System.out.println("Arraylist " + remove(al));
        System.out.println("LinkedList " + remove(ll));
        //중간에 삭제할경우 LinkedList 가 빠름
         
         
        System.out.println("순차적으로 삭제하기");
        System.out.println("Arraylist " + remove2(al));
        System.out.println("LinkedList " + remove2(ll));
        //순차적삭제는 Arraylist가 빠름
 
         
 
         
    }
}

1. 순차적으로 추가/삭제하는경우에는 ArrayList가 LinkedList보다 빠르다

2. 중간에 데이터를 추가.삭제 하는경우에는 LinkedList가 ArrayList 보다 훨씬! 빠르다. 

3. 특정요소에 접근할 경우에는 Arraylist가 빠르다.

배열의 경우 n번째 요소에 접근할 경우 아래와 같은 수식으로 접근하기 때문에 빠르다.

n번째 요소의 주소 = 배열의 주소 + n * 데이터 타입의 크기.


//
프로그래밍/java 2014. 6. 13. 16:35

HashMap, ArrayList, LinkedList 속도 비교


테스트 엘리먼트는 Integer 인스턴스 5,000,000(5백만개)를 이용하여 수행하였다.

탐색과 삭제에서는 균등하게 떨어진 4990개의 데이터를 이용하였다.


테스트 결과 :

5000000개의 인스턴스 생성 시간 0.548829807초


HashMap Test

입력 소요 시간  2.415268645초

탐색 소요 시간 0.002399381초

삭제 소요 시간 0.002615092초


ArrayList

입력 소요 시간  0.381054002초

탐색 소요 시간 1.99475E-4초

삭제 소요 시간 137.231368119초


LinkedList

입력 소요 시간  1.503839756초

탐색 소요 시간 52.905209243초

삭제 소요 시간 52.587791295초



HashMap의 경우는 입력되는 시간을 제외하면 우수한 성능을 보였고,

(탐색과 삭제 시에 인덱스가 아닌 키값으로 하였음)


ArrayList 의 경우에는 내부적으로 배열을 쓰는 컬렉션 답게 탐색에서는 매우 우수한 속도를 보였지만

삭제 시에 배열의 구조가 변경되므로 매우 느린 속도를 보였다.


LinkedList는.. 탐색, 삭제 모두 순차 탐색을 하므로(실제로 이중 연결 링크드리스트로 되어있고, Head, Rear 포인터를 이용해서, 탐색하려고 하는 인덱스와 리스트 크기의 반과 비교해서 인덱스가 작은 경우 앞에서부터 탐색하고, 큰 경우 뒤에서부터 탐색하도록 되어있어 평균적으로 n / 2의 시간 복잡도를 가진다.) 많이 느렸다. -_-



따라서 HashMap은 Key, Value 쌍을 가지는 데이터를 관리할 때 용이하고,

ArrayList는 데이터가 입력 되고 삭제가 빈번하지 않은 경우에 사용하면 되고,

Linkedlist는 Queue와 같이 Head와 Read와 가까이에서 탐색, 삭제가 이뤄지는 경우에 쓰면 좋을 듯 하다.



테스트에 사용한 코드는 아래와 같습니다. 참고 하실 분은 아래의 소스를 사용하시면 됩니다.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

public class TestCode {
	static Integer[] testArray = new Integer[5000000];
	Integer[] values = new Integer[4990];

	public void hashMapTest() {
		long start = System.nanoTime();

		HashMap hashmap = new HashMap();
		for(Integer integer : testArray){
			hashmap.put(integer, integer);
		}
		
		long end = System.nanoTime();
		
		System.out.println("\nHashMap Test");
		System.out.println("\t입력 소요 시간  " + second(start, end) + "초");
		
		start = System.nanoTime();
		for(Integer value : values){
			hashmap.get(value);
		}		
		end = System.nanoTime();
		System.out.println("\t탐색 소요 시간 " + second(start, end) + "초");
		
		start = System.nanoTime();
		for(Integer value : values){
			hashmap.remove(value);
		}
		end = System.nanoTime();
		System.out.println("\t삭제 소요 시간 " + second(start, end) + "초");
	}
	
	public void arrayListTest(){
		long start = System.nanoTime();
		
		ArrayList arrayList = new ArrayList();
		for(Integer integer : testArray){
			arrayList.add(integer);
		}
		
		long end = System.nanoTime();
		
		System.out.println("\nArrayList");
		System.out.println("\t입력 소요 시간  " + second(start, end) + "초");
		
		start = System.nanoTime();
		for(Integer value : values){
			arrayList.get(value);
		}		
		end = System.nanoTime();
		System.out.println("\t탐색 소요 시간 " + second(start, end) + "초");
		
		start = System.nanoTime();
		for(Integer value : values){
			arrayList.remove(value);
		}
		end = System.nanoTime();
		System.out.println("\t삭제 소요 시간 " + second(start, end) + "초");
	}
	
	public void linkedListTest(){
		long start = System.nanoTime();
		
		List linkedList = new LinkedList();
		for(Integer integer : testArray){
			linkedList.add(integer);
		}
		
		long end = System.nanoTime();
		
		System.out.println("\nLinkedList");
		System.out.println("\t입력 소요 시간  " + second(start, end) + "초");
		start = System.nanoTime();
		for(int value : values){
			linkedList.get(value);
		}		
		end = System.nanoTime();
		System.out.println("\t탐색 소요 시간 " + second(start, end) + "초");
		
		start = System.nanoTime();
		for(int value : values){
			linkedList.remove(value);
		}
		end = System.nanoTime();
		System.out.println("\t삭제 소요 시간 " + second(start, end) + "초");
	}


	private void prepare() {
		long start = System.nanoTime();
		for (int i = 0; i < testArray.length; i++) {
			testArray[i] = i;
		}
		long end = System.nanoTime();
		
		ArrayList temp = new ArrayList(1000);
		for(int i = 0 ; i < 4990 ; i++){
			temp.add(i * 1000);
		}
		temp.toArray(values);
		
		
		System.out.println(testArray.length + "개의 인스턴스 생성 시간 " +
				second(start, end) + "초");
		
	}
	
	private double second(long start, long end){
		return (end - start) / Math.pow(10, 9);
	}

	public void start() {
		prepare();
		hashMapTest();
		arrayListTest();
		linkedListTest();
	}

	public static void main(String[] args) {
		TestCode test = new TestCode();
		test.start();
	}
}

출처 : http://nnoco.tistory.com/73


//
프로그래밍 2014. 6. 13. 16:28

오랜만에 재귀 문제를 풀다보니 헷갈려져서 정리한번 해보겠음.

재귀 중에 가장 쉬운 팩토리얼부터..



1. 재귀함수란?


함수 내에서 자기 자신을(함수)를 계속적으로 콜 하면서 풀어가는 방식이다.

스택(Stack)이라고 생각할 수 있다.

함수가 콜 되면서 최근에 자신을 부른 원래 함수가 스택에 차곡차곡 쌓이게 됨.

중요한건 

처음 불려진 함수에서(스택 맨 밑에있는 메소드) return 되는 값이 최종 return 값이 된다



2. 팩토리얼이란?


3! = 3*2*1 = 6

4! = 4*3*2*1 = 24

5! = 5*4*3*2*1 = 120



3. 재귀 예제


문제 : 특정 숫자의 팩토리얼 구하기 


간단하게 소스 투척


public class Factorial {

public static void main(String[] args) {

int input = 4; // 4!

System.out.println(fact(input));

}


public static int fact(int n) {

if (n <= 1)

return n;

else 

return fact(n-1) * n;

}

}



>> 결과


24 



4. 원리


1) 처음 fact 메소드가 불린 것은 main 함수에서이다.

fact(4) 가 실행될 것이다.


2) fact(4)

n은 현재 4이다.

n은 1보다 크므로 else를 타고,

fact(3)이 호출된다.


3) 여기서 처음 호출된 fact(4)는 종료되지 않고 Stack에 쌓인상태로,

fact(4)가 호출한 fact(3)이 실행된다.


Stack

 fact(4)


4) fact(3)

n은 현재 3이다.

n은 1보다 크므로 else를 타고,

fact(2)이 호출된다. 


5) 여기서 두번째로 호출된 fact(3)은 종료되지 않은 상태로 Stack에 쌓이고,

fact(3)이 호출한 fact(2)이 실행된다.


Stack

fact(3) 

fact(4)


6) fact(2)

n은 현재 2이다.

n은 1보다 크므로 else를 타고,

fact(1)이 호출된다.


7) 세번째로 호출된 fact(2)는 종료되지 않은 상태로 Stack에 쌓이고

fact(2)가 호출한 fact(1)이 실행된다.


Stack

fact(2) 

fact(3)

fact(4)


8) fact(1)

n은 현재 1이다.

n이 1과 같으므로 if문을 타고, n 즉, 1을 return 한다.


9) fact(1)이 종료되면서, Stack의 가장 위에 있는 fact(2)가 실행된다.

8번에서 리턴 받은 값과 n을 곱하며 return 하고 fact(2)가 종료될 것이다.


fact(2) 에서는 n이 2이다.

8번에서 fact(1)은 1을 리턴했었다.


 fact(2-1) * n  즉,  1 * 2


그래서 fact(2)에서는 1*2 한 값을 return 한다.


Stack은 이제 아래와 같은 상태가 된다.

fact(3) 

fact(4)


10) 스택에 있던 fact(3)이 실행된다.

9번에서 리턴 받은 1*2 = 2 와 n을 곱하며 리턴하고 종료한다.


 fact(3-1) * n  즉,  2 * 3


fact(3)은 1*2*3 한 값 6을 리턴한다.


11) 마지막으로, 처음 불리워졌었던 fact(4)가 리턴할 차례가 왔다.

10번에서 리턴받은 6과 n을 곱하고 리턴하고 종료될 것이다.


 fact(4-1) * n  즉,  6 * 4 = 24



이렇게 4! 을 구했고, 리턴 받은 값은 main 함수에서 출력된다.


결론적으로 따져보면

1*2*3*4 를 하게 된 것이다.


'프로그래밍' 카테고리의 다른 글

Restful 한 API 디자인에 대해  (0) 2014.06.16
REST에 대한 이해  (0) 2014.06.16
git 잘못된 커밋 삭제 및 합치는 법  (0) 2014.06.08
같은 4byte int와 float의 차이  (0) 2014.03.30
java version 바꾸기 ubuntu  (0) 2014.03.26
//
프로그래밍/JSP 2014. 6. 11. 14:41

[자바] Java request.getContextPath() 와 request.getRequestURI() 와 request.getRequestURL() 와 request.ServletPath() 와 request.getRealPath()


 ■ request.getContextPath() : 프로젝트 Path 만 얻어옴

 예) http://localhost:8088/board/list.jsp

      return : /borad

  

■ request.getRequestURI() : 프로젝트와 파일경로까지 얻오옴

    (전체 URL중 Port번호 다음부터 마지막 문자열까지 반환함)

 예) http://localhost:8088/board/list.jsp

      return : /borad/list.jsp

  

String url = request.getRequestURI.split("/");

String fName = url[url.length - 1];   // list.jsp

  

■ request.getRequestURL() : 전체 경로를 가져옴

 예) http://localhost:8088/board/list.jsp 

return : http://localhost:8088/borad/list.jsp

 

 

■ request.ServletPath() : 파일명만 가져옴 

예) http://localhost:8088/board/list.jsp 

return : /list.jsp

 

 

■ request.getRealPath("") : 서버 또는 로컬의 웹 애플리케이션 서버의 docBase 설정값을 반환함 (절대 경로 가지오기)  

예) http://localhost:8088/board/list.jsp 

return : D:\project\webapps\board\

 

'프로그래밍 > JSP' 카테고리의 다른 글

서블릿과 그 정의 및 작동방식, 프로세스  (0) 2014.06.15
JSP 웹어플리케이션 구조 및 서블릿  (1) 2014.06.10
HttpseverletRequest 정리  (0) 2014.06.10
Media query에 대한 이해  (0) 2014.06.06
xml 노드 검색  (0) 2013.05.30
//
프로그래밍/JSP 2014. 6. 10. 23:40

(2) JSP 설정 및 서블릿 프로그램 만들기

*웹 어플리케이션이란?

: 독립적으로 수행되는 것이 아니라 반드시 웹 브러우저 상에서 수행되는 애플리케이션.

↔ 독립 애플리케이션 : 데스크톱 상에서 독립적으로 실행되어 수행되는 프로그램.

ex) 한글, MS 워드 , MS 엑셀, AcroEdit 등

# 웹 어플리케이션이 Tomcat에서 구현될 때의 규칙

: 임의의 웹 어플리케이션은 wedapps 폴더 하위에 하나의 폴더로 구성

→  wedapps 폴더 하위에 새폴더를 추가하면 아파치는 주소를 생성한다. 즉, 두 개의 폴더를 생성하면 두 개의 ServletContext 이 생긴다.

#개념

: 웹 어플리케이션은 오직 하나의 ServletContext 와 매핑된다.

: 서로 다른 두 개의 웹 어플리케이션은 독립적인 ServletContext 객체와 매핑되어 각자 독립적인 공간에 자신만의 정보를 관리한다.

: ServletContext는 하나의 웹 어플리케이션 내에 여러 JSP페이지와 Servlet들이 공동으로 활용할 수 있는 저장소로 활용된다.

#웹 어플리케이션 폴더와 URL간의 매핑

: URL에 웹 어플리케이션 지정 없이 http://localhost:8080 으로 요청하여 자신의 서버로 들어간다. 그리고 webapps 폴더 밑의 ROOT 폴더로 접근하여 URL로 지정한 파일에 접근하여 실행한다.

→ index.htmlindex.jsp : 파일명까지 정확하게 입력하지 않아도 폴더명만으로도 찾아지는 디폴트 파일

 

<실습>

: 현재 수행 JSP의 Context와 실제 경로 확인하기.

1. 이전 시간에 만든 jspbook 폴더에 path.jsp 파일을 만든다.

→ 이전 시간에 한 것과는 다르게 인코딩 범위를 건드리지 말고, 파일 범위만 모든 파일로 해서 .jsp까지 잊지 말고 적어 jsp파일을 생성한다.

2. 내부에 다음과 같은 코드를 작성한다.

[코드]

<%@ page contentType=”text/html;charset=utf-8″ %> <html>
<head><title>context의 경로</title></head> <body>

현재 수행 JSP의 context (웹 어플리케이션) 경로: <%= request.getContextPath() %> <br/> 현재 수행 JSP의 context 실제 경로: <%= application.getRealPath(“/”) %>
</body>
</html> 

#코드 분석

<주요 코드>

- request.getContextPath()

: 웹 어플리케이션의 경로를 리턴

- application.getRealPath(“/”)
: 웹 어플리케이션의 하드디스크상 실제 경로를 리턴

<기타 코드>

- charset : 한글 있을 때만 사용하면 됨

- utf-8: 다국적어 인식. 자바 – 유니코드 :: 한글이 깨지면 euc-kr로 바꿔주면 됨.

- <%= : 표현식.

- <br> : 줄바꿈 태그

- <body> : 실제 메인에 들어가는 태그

- get이 붙으면 모두 접근자 : 값을 가져오려고 접근한다.

- set이 붙으면 모두 설정자 : 값을 설정, 할당함. 접근자와 반대 개념.

3. startup 파일을 실행시켜 서버를 구동하고, http://localhost:8080/jspbook/ch02/path.jsp 를 주소창에쳐서 실행시킨다.

여기서 ch02는 이전에 만들어놓은 jspbook 내부에 만든 폴더의 이름이다.

 

*JSP

:: 프레젠테이션 로직 + 약간의 비즈니스 로직이 바로 JSP. JSP만 만들면 jsp, html, servlet 세 개가 만들어진다.

# Servlet?

 

: sun이 웹개발 표준으로 개발한 것. 비즈니스 로직을 컨트롤러 역할이라 함.

:: 자바코드 작성 → 컴파일 → 클래스 파일 생성. 자바코드는 헤드 태그 뒤에 넣어주어야 한다.

- Model2 : 서블릿 + jsp + 자바빈즈

→ C:\apache-tomcat7.0.52\work\Catalina\localhost\jspbook\org\apache\jsp\ch02 에 있는path_jsp.jave

- 구성 요소 : 주석, 패키지, 인포트 문장. 서블릿 파일에서 실제로 우리가 JSP파일에 작성한 내용은 모두 out.write() 혹은 out.println() 안에 작성되어 있다.

#폴더의 기능

- conf : 환경

- winapps의 ROOT 파일 : 실행이 잘 안 될 경우에는 이 파일에 넣으면 된다. 무조건 실행된다.

 

#JSP는 대소문자가 구분되므로 추가한 파일을 실행시킬 때, 대소문자 구분을 분명하게 해주어야 실행이 된다.

 

#지난 시간에 만든 jspbook 폴더를 인식하게 하려면?

→ web container 가 인식하는 경로는 webapps이므로  jspbook을 인식시키려면 셧다운 후 다시 스타트업을 해야한다.

프로그램을 실행시킬 때는 쓰는 port 번호 8080은 나중에 수정하는 것이 가능하다.

#ROOT 폴더의 단점?

→ 아무나 다 볼 수 있다. 따라서 ROOT가 아니라 webapps 내에 다른 폴더를 만들어서 거기에 넣는 게 좋다.

실행을 시킬 때에는 webapps 자체가 ROOT로 인식되기 때문에 뒤에 오는 경로만 적어주면 된다.

 

# WEB-INF 폴더?

: 환경 설정, 관련 Serlvet 및 Utility 클래스와 JavaBeans와 라이브러리들을 위치시키는 폴더

- 이것은 우리가 만든 jspbook 폴더 내부에 만들면 된다. 그리고 이 폴더 내부에 classes 폴더와  lib 폴더를 추가시킨다.

- 이 파일 내부에는 web.xml이라는 파일과 위에서 추가한 두 개의 폴더, 그리고 tld, images라는 파일을 넣을 수 있는데, xml 파일은 웹 어플리케이션 배치 정의자 역할을 한다. 즉, 이 파일 내부에 적힌대로 클래스 파일 이름과 java파일 이름을 정의해야 제대로 실행이 된다. classes 폴더는 Servlet 및 JavaBeans 클래스를 포함한 여러 클래스들이 위치하는 폴더로 자바파일을 만들어서 컴파일 한 것을 넣어두면 된다. images폴더는 이름대로 그림 파일을 저장하는 곳이다. lib 폴더는 라이브러리 역할을 하는 jar 파일이 위치하는 폴더이다. JDBC 드라이버나 태 그 라이브러리를 구성하는 jar 파일이 여기 위치하는 폴더이고, tld 폴더는 태그 라이브러리 관련 설정 파일들이 위치한다. (태그 라이브러리는 나중에 공부한다.)

# JSP의 처리 과정 및 Servlet과의 관계

: JSP 파일은 실행이 될 때 일단 Servlet인 Java 소스파일로 변환되고 다시 클래스 파일로 컴파일이 된다. 이 클래스 파일이 JSP/Servlet 컨테이너인 Tomcat 내에서 실행되어 그 결과가 최종적으로 웹 브라우저로 전달되는 것이다. 이것을 그림으로 나타내면 다음과 같다.

스크린샷 2014-03-30 오후 11.14.41

[그림 2.1] JSP의 처리 과정 및 Servlet과의 관계 

위 그림에서 웹 브라우저에서 요청을 할 때, JSP 파일이 서블릿 파일 (자바파일) 로 변환된다. 컴파일 후 클래스 파일이 생성되고, 그 후에 출력된다. 이 과정을 응답이라고 한다.

#Tomcat?

: 개발자에게 코딩하기 복잡한 Servlet 대신에 스크립트 언어인 JSP로 작성하게 하고 JSP/Servlet 컨테이너인 Tomcat이 내부에 서 JSP 파일을 Servlet으로 변환 및 컴파일하여 클래스 파일을 메모리에 적재한 후 실행하여 응답한다.

 

#Servlet 파일의 구조

-꼭 작성해주어야 하는 것들

1. 세 개의 임포트문

import javax.servlet.*;

import javax.servlet.http.*;

import javax.servlet.jsp.*;

:: 모든 서블릿을 불러오는 문장들이다.

2. 필요 메소드 3개

2-1.

public void _jspInit(){

    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();

    _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());

  }

:: 초기화 관련 내용이 들어가있음.

2-2.

 public void _jspDestroy() {

  }

::메모리에서 소멸되야 할 내용이 들어감. 현재 단계에서 우리가 만드는 자바파일에는 위와 같이 내용이 없음.

2-3.

public void _jspService(final javax.servlet.http.HttpServletRequest request, finaljavax.servlet.http.HttpServletResponse response)

        throws java.io.IOException, javax.servlet.ServletException {

:: 해야할 일을 여기에 넣어두면 됨.해야할 일은 do로 표현됨.

# JSP 파일 재요청시의 동작 과정

: 변환 및 컴파일 과정은 해당 JSP를 웹 브라우저에서 맨 처음 요청했을 때에만 이루어진다. 한 번이라도 요청했던 JSP 파일을 다시 임의의 사용자가 재효청하면 이미 메모리에 적재된 클래스를 재실행한다. JSP로 작성된 웹 페이지의 대부분의 응답흔 하드디스크에 대한 접근 없이 바로 메모리에서 응답을 주기 때문에 대체로 평균 응답 시간이 매우 짧다. 이 과정을 그림으로 나타내면 다음과 같다.

스크린샷 2014-03-30 오후 11.33.10

[그림 2.2] 재요청 과정 그림

위의 그림을 분석해보자.

1 : 코드 작성이 완료되었다.

1→2 : 웹 브라우저에서 요청하는 순간 JSP파일이 java파일로 변환되고, 이것을 컴파일하여 클래스 파일을 생성해준다.

2→3 : JSP파일을 수정했음을 시간의 변화로 알 수 있다.

3→4 : 브라우저에서 재접근을 하자 JSP 파일이 최종적으로 저장된 시각과 클래스 파일의 죄종 저장 시각을 확인하여 어떤 것이 더 최근의 자료인지를 확인하는 것을 알 수 있다.

4→5 : java파일과 클래스 파일을 변환 및 컴파일 과정을 거쳐 다시 수정해주고 최신의 정보를 이용해 그 결과를 웹 브라우저에게 보내준다.

여기서 종합적인 JSP 파일의 처리 과정을 그림으로 살펴보자.

스크린샷 2014-03-30 오후 11.39.31

[그림 2.3] 종합적인 과정

여기서 마름모는 그 여부를 판단하는 과정임을 알 수 있다.

서블릿은 내부적으로 언어를 자바를 사용하는데, 그 이유는 자바가 데이터베이스를 관리하는 것이 쉬운 언어이기 때문이다.

#서블릿의 문제점

: 범위가 넓어 배우기가 어려운 자바 언어를 알아야만 한다.

서블릿의 생성 배경과 문제점을 그림으로 보자.

스크린샷 2014-03-30 오후 11.42.25

[그림 2.4] 서블릿의 역사

- JSP는 서블릿을 기반으로 한 기술로, jsp가 서블릿을 대체하는 기술이 아니라 상호보완적인 기술이라는 것을 알아야 한다.

위 그림에서 MVC는 Model-View-controller로, 컴퓨터 소프트웨어 개발의 구조적 패턴이다. 여기서 C는 비즈니스 로직을 나타낸다.

#서블릿의 장점

·Java를 기반으로 하므로 Java API를 모두 사용할 수 있다.

·쓰레드를 기반으로 하므로 웹 어플리케이션 서버 자원을 효율적으로 활용할 수 있다.

·웹 어플리케이션에서 효율적인 자료 공유 방법을 제공한다. ·비즈니스 로직과 프리젠테이션 로직을 분리할 수 있다.

·컨트롤러와 뷰의 역할 분담으로 인해 웹 디자이너와 개발자 간의 효율적인 업무 분담이 가능하다.

·유지보수가 수월하다. ·기능 확장이 용이하다.

·Servlet 컨텍스트 리스너 및 필터 Servlet 등 고급 프로그래밍 기법을 통해 보다 효과적인 웹 어플리케이션 설계가 가능해진다.

여기서 서블릿의 동작 과정과 생명주기를 그림으로 한 번 보자.

스크린샷 2014-03-30 오후 11.48.50

[그림 2.5] 서블릿의 생명 주기 및 동작과정

위 그림에서 init 함수로 인해 각종 초기화 작업이 수행되고, service 함수로 인해 모든 사용자의 요청이 GET 또는 POST 방식으로 처리된다. 이 서비스 함수가 서블릿에서 가장 중요한 부분이다.

-요청 방식

·GET방식 : 단순히 가져오기만 함. 주소창에 내가 검색한 키워드가 뜨는 것.

·POST방식: 정보 값이 보여지지 않음.

위의 방식에 따라서 doGet() 혹은 doPost()함수가 호출된다. 서블릿 개발자는 이 두 메소드에 대부분의 필요한 기능을 구현한다.

하지만 doGet()메소드에서 다시 doPost()를 호출하고 doPost() 내부에만 관련 처리 과정을 코딩하는 편이 편하다.

 

<서블릿 프로그램 실습>

#과정

1. 톰켓 아파치 폴더로 들어감

2. lib로 들어감.

3. 서블릿-api 압축 파일을 복사

4. C:\Program Files\Java\jdk1.7.0_51\jre\lib\ext에 붙여넣기

→ 위의 jdk1.7.0_51는 각자가 깔아놓은 jdk버전에 따라 달라진다.

5. 다시 톰캣폴더로 돌아온다. = 아파치폴더.

6. C:\apache-tomcat-7.0.52\webapps\jspbook에 WEB-INF 폴더를 만들어줌.

7. 내부에 classes 폴더과 jave_sources 폴더을 만들어줌.

→ 우리가 만드는 자바 소스 파일은 jave_sources 에 넣어주고, 이를 컴파일해서 생성되는 클래스 파일은 classes 에 넣어줄 것이다.

8. web.xml 파일을 WEB-INF에 넣음.

→ web.xml 파일은 파일명은 그대로하고, 내부 소스는 맨 아래에 있으니 그것을 그대로 복사한 후 붙여넣기하여 생성하면 됨.

9. HelloWorldServlet.java 파일을 WEB-INF 파일에 넣음 (10 단계의 큰 의미)

10. HelloWorldServlet.java 파일을 만들어서 자바소스s 파일에 넣음.

[코드]

import javax.servlet.*; import javax.servlet.http.*; import java.io.*;

public class HelloWorldServlet extends HttpServlet {
public void init() { // Servlet 객체 최초 생성시 한번만 호출

System.out.println(“Init!!!”); }

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletExce ption { // Servlet 요청시 매번 호출

} }

}

System.out.println(“doGet!!!”);
response.setContentType(“text/html”);
PrintWriter out = response.getWriter();
out.println(“<html><body bgcolor=\”yellow\”>Hello Servlet!</body></html>”);

public void destroy() { // Servlet이 메모리에서 삭제될 때 한번만 호출System.out.println(“destroy!!!”); 

11. HelloWorldServlet.java의 위치 주소를 복사한다.

12. cmd 창에 cd(change directory) 를 치고 붙여넣기 한다.

→ HelloWorldServlet.java 파일이 존재하는 곳으로 이동.

13. dir을 쳐서 해당 위치에 존재하는 디렉토리들을 본다.

14. cmd 창에서 javac 명령어를 사용하여 우리가 만든 자바 파일을 컴파일한다. 컴파일이 정상적으로 처리되었다면 아무런 안내도 뜨지 않고 다음 입력을 받을 준비를 한다.

→ javac HelloWorldServlet.java 라고 치면 됨. 생성되는 클래스 파일을 4단계의 부가 설명과 같이 classes 폴더 내부에 넣어준다.

15. web.xml 파일의 내부에 있는 class 명으로 실행을 시킨다.

→ 예시 : http://localhost:8080/jspbook/helloServlet

16. 웹 브라우저에서 확인함.

17. F5 키를 누를 때마다 서버창에 실행이 될 때 서버에 출력하라고 소스에 작성했던 내용들이 계속해서 뜸.

→ 초기화 메소드에서 출력하라고 했던 init! 이라는 문장이 맨 처음 한 번, doGet메소드를 호출할 떄마다 출력하라고 했던 doget!!!이라는 문장이 새로고침을 할 때마다 계속해서 출력된다.

 

#xml : 태그를 직접 만들어주어야 한다.

→ 주소와 클래스 이름, 서블릿 이름은 여기에 있어! 하고 알려줘야 함.

#이름이 일치해야 하는 것들은 완전히 일치해야 한다. 서블릿 프로그램이 제대로 만들어졌음에도 실행이 되지 않는 가장 크고 많은 이유들이다.

 

 

——————————————————————————————

web.xml  파일 내부 소스

:

<?xml version=“1.0″ encoding=“utf-8″?>

<web-app xmlns=http://java.sun.com/xml/ns/javaee

   xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance

   xsi:schemaLocation=http://java.sun.com/xml/ns/javaee 

                       http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd

   version=“2.5″> 

    <description>

      JSPBOOK Examples.

    </description>

    <display-name>JSPBOOK Examples</display-name>

    <servlet>

      <servlet-name>helloServlet</servlet-name>

      <servlet-class>HelloWorldServlet</servlet-class>

    </servlet>

    <servlet-mapping>

        <servlet-name>helloServlet</servlet-name>

        <url-pattern>/helloServlet</url-pattern>

    </servlet-mapping>

    <!–<jsp-config>

      <jsp-property-group>

      <url-pattern>/ch06/*</url-pattern>

      <include-prelude>/common/variable.jspf</include-prelude>

      <include-coda>/common/footer.jspf</include-coda>

     </jsp-property-group>

    </jsp-config>–>

    <servlet>

    <servlet-name>readInitParamJSP</servlet-name>

    <jsp-file>/ch08/readInitParam.jsp</jsp-file>

    <init-param>

    <param-name>e-mail</param-name>

    <param-value>hong@mail.com</param-value>

      </init-param>

      <init-param>

        <param-name>emailHost</param-name>

        <param-value>151.68.167.201</param-value>

      </init-param> 

      <init-param>

        <param-name>webMaster</param-name>

        <param-value>홍길동</param-value>

      </init-param>

    </servlet>

    <servlet-mapping>

    <servlet-name>readInitParamJSP</servlet-name>

    <url-pattern>/ch08/readInitParam.jsp</url-pattern>

    </servlet-mapping>

    <context-param>

      <param-name>appName</param-name>

      <param-value>jspbook</param-value>

    </context-param>

    <context-param>

      <param-name>appVersion</param-name>

      <param-value>1.0</param-value>

    </context-param>

    <context-param>

      <param-name>MasterID</param-name>

      <param-value>jspbook</param-value>

    </context-param>

    <context-param>

      <param-name>MasterPassword</param-name>

      <param-value>112233</param-value>

    </context-param>

<!–

  <error-page>

    <error-code>404</error-code>

    <location>/ch10/error/404errorHandler.jsp</location>

  </error-page>

  <error-page>

    <error-code>500</error-code>

    <location>/ch10/error/500errorHandler.jsp</location>

  </error-page>

  <error-page>

    <exception-type>java.lang.NullPointerException</exception-type>

    <location>/ch10/error/nullPointerErrorHandler.jsp</location>

  </error-page>

–>

    <resource-ref>

      <description>MYSQL POOL</description>

      <res-ref-name>jdbc/mysql</res-ref-name>

      <res-type>javax.sql.DataSource</res-type>

      <res-auth>Container</res-auth>

    </resource-ref>

  <mime-mapping>

    <extension>html</extension>

    <mime-type>text/html;charset=UTF-8</mime-type>

  </mime-mapping>

</web-app>


출처 : http://peagcom.wordpress.com/


//
프로그래밍/JSP 2014. 6. 10. 23:31

클라이언트 IP 등의 정보를 가져오거나, 쿠키, 헤더, GET/POST로 전송한 값을 가져오는데 주로 사용하는 것이 바로 Request입니다.

JSP/Servlet에서 사용하는 Request 객체의 메소드를 대략적으로 정리해 봤습니다. 

이 Request 객체는 javax.servlet.http 패키지에 속한 HTTPServletRequest 인터페이스로서 javax.servlet.ServletRequest 인터페이스에서 상속을 받았습니다. 

그래서 제가 정리하려는 내용은 javadoc의 다음 부분에 아주 자세히 나와 있습니다. 
나중에 영어로 된 거 또 읽어보기 싫어서 정리해보는 거네요~~ 

http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/http/HttpServletRequest.html 

http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/ServletRequest.html

주로 사용하는 정보만을 보여주는 간단한 jsp 파일을 구성해 봤습니다. 
jsp 파일 두개로 되어 있구요.. 소스는 걍 여기서 받으면 됩니다. 소스받기 : request.zip

index.jsp 파일을 열고 난 후.. 링크를 클릭하면 request에서 처리할 수 있는 정보들이 나타납니다. 
request.jsp 파일의 내용이 주로 설명할 것인데요.. 뭐 이미 잘 알려진 거라 특별히 새로울 것은 없습니다. 

먼저 local의 기본 정보(IP, Name, Port)를 보여줍니다. local이라 하면 일반적으로 서버를 의미하는 것이겠죠.. 
Local IP : <%=request.getLocalAddr()%>
Local Name : <%=request.getLocalName()%>
Local Port : <%=request.getLocalPort()%>

다음으로 클라이언트의 정보입니다. IP, Host, Port를 가져올 수 있습니다.
Remote IP : <%=request.getRemoteAddr()%>
Remote Host : <%=request.getRemoteHost()%>
Remote Port : <%=request.getRemotePort()%>

이어서 서버 이름과 포트가 있는데요.. 일반적으로 local 기본정보와 동일하겠죠.. 
Server Name : <%=request.getServerName()%>
Server Port : <%=request.getServerPort()%>

지역 정보입니다. 대부분 한국을 의미하는 ko가 나올 것 같네요..
Locale : <%=request.getLocale()%>

사용하는 프로토콜입니다. "프로토콜/메이저버전.마이너버전" 의 형태입니다.
Protocol : <%=request.getProtocol()%>

http, https, ftp와 같은 것을 의미합니다. 
Scheme : <%=request.getScheme()%>

https와 같은 보안 채널의 사용 여부입니다. true/false 값으로 되어 있네요..
Secure Channel : <%=request.isSecure()%>

요청에 대한 URI, URL, 컨텍스트 경로, 서블릿 경로, GET/POST등의 메소드를 나타냅니다.
Request's URI : <%=request.getRequestURI()%>
Request's URL : <%=request.getRequestURL()%>
Context Path : <%=request.getContextPath()%>
Servlet Path : <%=request.getServletPath()%>
Method : <%=request.getMethod()%>

세션 ID에 대한 정보들입니다. 
Session ID : <%=request.getRequestedSessionId()%>
Session ID from Cookie : <%=request.isRequestedSessionIdFromCookie()%>
Session ID from URL : <%=request.isRequestedSessionIdFromURL()%>
Session ID is still valid : <%=request.isRequestedSessionIdValid()%>


그리고 다음은 Header 정보를 보는 방법입니다. 
<%
 Enumeration eHeader = request.getHeaderNames();
 while (eHeader.hasMoreElements()) {
  String hName = (String)eHeader.nextElement();
  String hValue = request.getHeader(hName);

  out.println(hName + " : " + hValue);
 }
%>

Request 객체를 통해서 쿠키 정보를 보는 방식이구요~
<%
 Cookie cookies[] = request.getCookies();
 for (int i=0; i < cookies.length; i++) {
  String name = cookies[i].getName();
  String value = cookies[i].getValue();

  out.println(name + " : " + value);
 }
%>

HTML 폼을 통해 넘어온 데이터를 받는 부분입니다. 
<%
 Enumeration eParam = request.getParameterNames();
 while (eParam.hasMoreElements()) {
  String pName = (String)eParam.nextElement();
  String pValue = request.getParameter(pName);

  out.println(pName + " : " + pValue);
 }
%>

미리 설정한 attribute를 가져오는 부분이구요..
<%
 Enumeration eAttr = request.getAttributeNames();
 while (eAttr.hasMoreElements()) {
  String aName = (String)eAttr.nextElement();
  String aValue = request.getHeader(aName);

  out.println(aName + " : " + aValue);
 }
%>

갑자기 Request에 대한 정보를 파악할 필요가 있어 정리하면서 올려봅니다.

//
프로그래밍/java 2014. 6. 9. 23:00

LinkedList 와 ArrayList 는 둘다 List 인터페이스를 따르지만, 구현방법은 서로 다릅니다. LinkedList 는 이중 연결 리스트(doubly-linked list) 이고, ArrayList 는 동적으로 크기가 변경되는 배열로 되어 있습니다.

링크드 리스트 와 배열의 속성 때문에, 어떤 일을 하는지에 따라 실행 속도가 달라지게 됩니다.

LinkedList

  • 특정 원소에 접근하는 것은 O(n)
  • 원소를 추가하는 것은 O(1)
  • 특정 원소를 제거하는 것은 O(n)
  • Iterator.remove 는 O(1)

For ArrayList

  • (역주: 특정 인덱스에) 접근 하는 것은 O(1)
  • 원소를 추가하는 것은 평균적으로 O(1), 하지만 최악의 경우엔, 어레이 크기를 늘리고 복사해야 되기 때문에 O(n)
  • 특정 원소를 제거하는 것은 O(n)

LinkedList 를 쓰면 constant(역주 O(1)) 시간안에 추가 와 제거(역주: Iterator.remove) 를 할 수 있지만, 원소를 접근 할 때, 순차적(역주: 리스트의 처음부터 링크를 따라가서) 으로 접근 할 수 밖에 없다. 다시말하면, 리스트 어딘가에 있는 특정 원소를 접근하는데는 리스트 크기에 비례하는 시간이 걸린다.

ArrayLists 는 반대로, 임의 접근(random access) 가 가능하다. 즉 어떤 원소도 (역주: index로) 즉각 얻어올 수 있다. 하지만, 젤 끝이 아닌 곳에 원소를 더하거나 빼는 것은, 그 원소 이후의 모든 원소를 옮기는 일을 수반하게 된다. 그리고 현재 배열 사이즈를 초과해서 원소를 더하려고 하면, 새로운(보통 두배 크기의) 배열이 생성되고, 원래 배열에서 값들이 새로운 배열로 복사되어야 한다. 따라서 ArrayList 에 원소를 더하는 것은, 최악의 상황에선 O(n) 이고, 평균적으론 O(1) 이다.

따라서, 하고자 하는 바에 따라서, 어떤 리스트를 쓸지 잘 정해야 한다. 원소들을 순차적으로 접근하는 것은 양쪽이 크게 차이가 나지 않는다. (ArrayList 를 순회하는 것이 사실 조금 빠르지만, 정말 이 차이를 걱정해야 할만한 일은 많지 않다.)

또한, 큰 리스트를 만든다면, 메모리 사용량에도 관심을 가져야 할 것이다. LinkedList 는 앞과 뒤 원소를 가리키는 포인터를 저장해야 하기 때문에 원소 하나에 대한 메모리 사용량이 ArrayList 보다 더 많다. 하지만 ArrayList 는 실제 가지고 있는 원소 갯수가 아닌, capacity 만큼의 메모리를 잡아먹는다는 단점이 있다.

ArrayList 의 기본 capacity 는 매우 작다. (java 1.4-6 에서 10이다) 하지만, 구현방식이 배열이기 때문에, 원소를 더하면서 배열의 크기를 조정하게 된다. 많은 원소를 추가할 것이라고 예상할 수 있을 때에는, 처음부터 크기를 크게 잡아서, 배열을 늘릴때 드는 비용을 피해갈 수도 있다.

Vector 도 List 인터페이스를 따르고 ArrayList 와도 매우 비슷하다. 차이점은 Vector 는 동기화 되기때문에 thread-safe(여러 thread 에서 사용해도 안전하다) 라는 점이다. 동기화 때문에 ArrayList 보다 약간 느리기도 하다. 내가 알기론, 대부분 자바 개발자들은 Vector 보단 ArrayList 를 선호한다. thread 환경에서 동기화를 걱정해야되면 아마 더 명시적인 동기화 방법을 사용하는 경우가 많은 것 같다.

//
프로그래밍 2014. 6. 8. 21:44

it 을 사용하면서 발생하는 실수를 복구 하기 위한 명령 몇 가지 케이스


Reset (http://ecogeo.tistory.com/276)


방금 전 커밋한 것을 취소하고 싶을 때, 취소된 커밋은 워킹트리에 그대로 보존 된다.


git reset HEAD^


git reset HEAD~커밋갯수



Rebase (http://canto.btool.kr/programing/35117)


원격 저장소로 푸시한 커밋을 합치고 싶을 때, 로컬에서 합치고 강제로 푸쉬한다. 

(여러명이 사용하고 있는 환경이라면 하지 말 것)


git rebase -i HEAD~커밋갯수 


(이전 것을 포함하여 모두 3개를 합칠 경우 HEAD~3)


커밋을 리베이스 한 후


git push -f 


강제로 푸시 한다.

'프로그래밍' 카테고리의 다른 글

REST에 대한 이해  (0) 2014.06.16
재귀함수의 원리 및 동작  (0) 2014.06.13
같은 4byte int와 float의 차이  (0) 2014.03.30
java version 바꾸기 ubuntu  (0) 2014.03.26
git을 이용한 프로젝트  (0) 2014.03.23
//