자료구조에 관한 설명

https://hyennis-room.tistory.com/73

 

[JAVA] 자료구조와 알고리즘

자료구조(data structure) : 컴퓨터 과학에서 효율적인 접근 및 수정을 가능케 하는 자료의 조직, 관리, 저장을 의미함. 데이터 값의 모임, 데이터 간의 관계, 데이터에 적용할 수 있는 함수나 명령.

hyennis-room.tistory.com

 

▶ArrayList

: java에서 제공하는 동적 배열기반의 리스트 구현 클래스(컬렉션).(인터페이스 List를 구현한다.)
      크기가 가변적으로 변하는 선형리스트이며 값의 중복을 허용한다.
    - 내부 배열로 Object[]로 사용하고 최초 할당 크기는 10이다.
    - 동적으로 크기 조절이 가능 => 요소의 삽입 삭제에 따라 자동으로 크기가 조절되서 유연한 요소 관리 가능
    - 인덱스 기반 요소 접근  => 내부 배열을 사용하여 요소를 인덱스를 통해 접근. 임의의 요소 빠르게 접근 가능
    - 순차적인 데이터 저장
    - 중복 요소 허용
    - 배열기반의 구현으로 중간 삽입/삭제의 경우 느릴것..
    - 내부 변수 modCount : ArrayList 클래스에서 내부적으로 사용되는 변수로 리스트의 수정횟수를 추적하는 역할.
                         이를 통해 구조 변경 여부를 확인하고, 반복 도중에 구조가 변경되는 것을 방지한다.

 

 

▶ArrayList의 메서드

- add : 배열에서 순차적으로 요소를 넣음, 인덱스 인자를 받으면 해당 인덱스 자리에 요소를 넣고 기존 값을 뒤로 미룬다. addAll(Collection) 다른 컬렉션은 넣을 수 있다.
- set : 전달받은 인덱스 요소의 값을 바꿈 반환값은 바꾸기 전의 원본요소를 반환한다.
- get : 전달받은 인덱스의 요소를 반환해준다. // 리스트의 메서드를 구현할 때 클래스 내부에서 배열에서 직접 꺼내 쓰는것이 성능에 더 좋다.

- remove : 특정요소 및 인덱스 위치의 요소를 찾아 삭제한다.  removeAll(Collection) 컬렉션 요소를 찾아서 해당 값을 삭제한다.  

- retainAll(Collection) : 컬렉션 요소를 비교해서 해당값 외의 요소를 삭제한다.(중복 가능)

- contains : indexOf를 사용하여 해당 요소(및 컬렉션 요소)의 값이 있으면 true 없으면 false 반환
- isEmpty : 리스트(배열)의 크기를 확인해서 해당 크기가 0 이면 true, 0 이상이면 false 반환

- clear : 배열의 값을 새로 생성해줘도 되지만 반복문을 돌려서 null로 할당해야 가비지 컬렉터(GC)가 수거해간다.
- indexOf : 배열을 반복문을 돌려서 해당 요소의 값과 동일하면 해당 값의 인덱스위치를 반환, 없으면 -1 반환. 동일한 값 비교시 equals를 사용하여 값 비교를 한다.(Object) / null 값비교도 포함되어야 하기 때문에 if문으로 null값을 먼저 체크한다.
- toArray : Object 배열로 변환 및 전달받은 타입의 배열로 바꿔준다.
- subList : 원본 리스트의 일부분을 보여주는 view의 리스트로 반환한다. ArrayList 클래스의 내장 객체를 사용한다. 해당 subList의 값이 변동되면 원본리스트에도 반영된다.
- Iterator : 해당 리스트의 요소를 순차적으로 접근하고 삭제하는데 사용.  Iterator를 사용하여 컬렉션의 요소를 반복하는 것은 안전하고 효율적이다. 컬렉션의 내부구조에 직접 접근하므로, 컬렉션이 수정되는 경우 ConcurrentModificationException라는 예외 방지할 수 있다.

 

 

 


MyArrayList 간단한 것만 구현해보기...

- Object [ ]  items : 배열 초기 크기 10 할당.

- int size :  배열 크기

- indexOf 먼저 구현해서 활용하는게 더 쉬움

- 배열의 크기가 넘어가면 배열 크기를 늘리는 리사이징 부분을 메서드로 만들어 활용

- 되도록이면 시간복잡도 최소를 고려하도록

 

▶ size( ), isEmpty( ) : size 변수 그대로 반환, size == 0 이면 isEmpty == true

@Override
public int size() {
    return size;
}

@Override
public boolean isEmpty() {
// isEmpty() 비어있으면 true == 0
    if (size == 0) return true;
    return false;
}

 

 

▶ indexOf / lastIndexOf 

 - null 값에 대한 체킹 : Object 클래스의 equals 메서드로 null을 비교할수 없으니 직접 null값을 따로 빼서 비교

 - 나머지 값 : Object 클래스의 equals 메서드로 비교 

@Override
public int indexOf(Object o) {
    if (o == null) {
        for (int i = 0; i < size; i++) {
            if (items[i] == null) {
                return i;
            }
        }
    } else {
        for (int i = 0; i < size; i++) {
            if (o.equals(items[i])) {
                return i;
            }
        }
    }
    return -1;
}

@Override
public int lastIndexOf(Object o) {
    if (o == null) {
        for (int i = size - 1; i >= 0; i--) {
            if (items[i] == null) {
                return (size - 1) - i;
            }
        }
    } else {
        for (int i = size - 1; i >= 0; i--) {
            if (o.equals(items[i])) {
                return (size - 1) - i;
            }
        }
    }
    return -1;
}

 

 

▶ contains(Object o) / containsAll(Collection c) 

 - indexOf메서드를 사용하여 해당 값이 있으면(값이 0 이상) true

 - collection 반복문을 돌려서 indexOf 메서드 사용

@Override
public boolean contains(Object o) {
    if (indexOf(o) > -1) return true;
    return false;
}

@Override
public boolean containsAll(Collection<?> c) {
    // 반복문으로 요소 하나하나 indexOf로 해당 요소가 있는지 판단한다.
    for(Object o : c.toArray()){
        if(indexOf(o) < 0){
            return false;
        }
    }
    return true;
}

 

 

clear 

 - 배열의 초기화 및 size 변수를 0 초기화 해도 되지만

 - 반복문을 돌려서 배열을 null로 해야지 JVM의 가비지컬렉터GC 가 수거해간다고 한다.

// 수정전
@Override
public void clear() {
    Object[] newItem = new Object[10];
    items = newItem;
    size = 0;
}

// 수정후
public void clear() {
    for (int i = 0; i < items.length; i++) {
        items[i] = null;
    }
    size = 0;
}

 

 

 

▶ get(int index) / set(int index, E e)

- 배열에 대한 인덱스 범위 체킹

- 해당 배열에서 인덱스 값으로 찾음

@Override
public E get(int index) {
    if (index < 0 || index >= size) {
        throw new IndexOutOfBoundsException("Index " + index + " is out of bounds.");
    }
    E rs = (E) items[index];
    return rs;
}

@Override
public E set(int index, E element) {
    if (index < 0 || index >= size) {
        throw new IndexOutOfBoundsException("Index " + index + " is out of bounds.");
    }
    E rs = (E) items[index];
    items[index] = element;
    return rs;
}

 

 

▶ add(E e) 

 - 배열에 삽입하기 전에 배열의 크기 확인

 - 배열의 크기가 다 차면 2배 크기의 배열을 새로 생성

 - 배열에 추가하면 size 변수 증가 

 - 보완할 점 : 배열 리사이징하는 것을 따로 메서드로 구현

@Override
public boolean add(E e) {
    if (size >= items.length) {
        Object[] newItem = new Object[size * 2];
        for (int i = 0; i < items.length; i++) {
            newItem[i] = items[i];
        }
        items = newItem;
    }
    items[size] = e;
    size++;
    return true;
}

 

▶ add(int index, E element)

 - 인덱스 예외처리

 - 기존 배열 크기 다 찼을 경우 리사이징

 - 배열에 추가하면 size 변수 증가 

// 수정전
@Override
public void add(int index, E element) {
    Object[] newItem = new Object[size + 1 > items.length ? size * 2 : items.length];
    // index 앞, index 뒤, 해당 요소 복사
    for (int i = 0; i < index; i++) {
        newItem[i] = items[i];
    }
    for (int i = 0; i < size - index; i++) {
        newItem[index + i + 1] = items[index + i];
    }
    newItem[index] = element;
    size++;
}

 

 

▶ addAll(Collection c) / addAll(int index, Collection c)

 - 해당 배열에 컬렉션 요소 삽입하기.

 - 배열의 크기가 다 찼을 경우 Object 배열 리사이징

 - index 중간삽입경우 앞, 뒤 요소 따로 복사하고 그 중간에 컬렉션 요소 하나씩 복사

 - 보완할 점 : 위에서 구현했던 add(E e) 메서드 사용

// 수정전
@Override
public boolean addAll(Collection<? extends E> c) {
    // c를 array로 변환
    Object[] cArr = c.toArray();
    // 기존 데이터 + 추가하려는 데이터 > 더 크다면 배열 크기 늘리기
    if (size + c.size() > items.length) {
        Object[] newItem = new Object[size + c.size()];
        // 기존배열 복사하고 그 이후에 넣기
        for (int i = 0; i < size; i++) {
            newItem[i] = items[i];
        }
        for (int i = 0; i < cArr.length; i++) {
            newItem[size + i] = cArr[i];
            size++;
        }
        items = newItem;
    } else {
        // 기존 배열 크기가 크다면 다음 인덱스부터 넣기
        for (int i = 0; i < cArr.length; i++) {
            items[size] = cArr[i];
            size++;
        }
    }
    return true;
}

// 수정후
@Override
public boolean addAll(Collection<? extends E> c) {
    // 반복문을 돌려서 add(E e) 메서드 사용
    for(Object o : c.toArray()){
        add((E) o);
    }
    return true;
}

@Override
public boolean addAll(int index, Collection<? extends E> c) {
    // add(index, E e) 메서드 활용하기
    for(Object o : c.toArray()){
        add(index + 1, (E) o); // 해당 인덱스 다음부터 넣기
    }
    return true;
}

 

 

 

 

▶ remove(int indext)

 - 인덱스 예외처리 

 - 반환값 따로 빼기

 - 해당 인덱스 배열의 값  한칸씩 땡기기

@Override
public E remove(int index) {
    if (index < 0 || index >= size) {
        throw new IndexOutOfBoundsException("Index " + index + " is out of bounds.");
    }
    E rs = (E) items[index];
    items[index] = null;
    for (int i = index; i < size - 1; i++) {
        items[i] = items[i + 1];
        items[i + 1] = null;
    }
    size--;
    return rs;
}

 

 

▶ remove(Object o)

 - 해당 요소의 인덱스를 찾음

 - 위에서 구현했던 remove(index) 메서드를 사용하여 삭제

  @Override
public boolean remove(Object o) {
    int targetIdx = indexOf(o);
    if (targetIdx == -1) {
        return false;
    }
    remove(targetIdx);
    return true;
}

 

 

▶ removeAll(Collection c)

 - 위에서 구현했던 remove(index)를 사용하여 해당 요소의 index찾아서 삭제

// 수정전
@Override
public boolean removeAll(Collection<?> c) {
    if (containsAll(c)) {// 값이 있는지 확인
        // 지정한 값만 삭제
        Object[] cArr = c.toArray();
        for (int i = 0; i < cArr.length; i++) {
            int targetIdx = indexOf(cArr[i]);
            remove(targetIdx);
        }
        return true;
    } else {
        return false;
    }
}

// 수정후
@Override
public boolean removeAll(Collection<?> c) {  
    if(contains(c)){
        for(Object o : c.toArray()){
            remove(o);
        }
        return true;
    }
    return false;
}

 

 

 

▶ retrainAll(Collection c) : 해당 컬렉션 요소를 제외하고 나머지 요소는 삭제

// 수정전
@Override
public boolean retainAll(Collection<?> c) {
    if (containsAll(c)) {
        Object[] cArr = c.toArray();
        for (int i = size -1 ; i >= 0 ; i--) {
            if (c.contains(items[i])) {
                continue;
            }else {
                remove(i);
            }
        }
        return true;
    } else {
        return false;
    }
}

 

 

toArray() / toArray(T[ ] a)

@Override
public <T> T[] toArray(T[] a) {
    if (a.length > items.length) {// 전달받은 배열의 공간이 더 크다면
        // a라는 배열에 원본 items 배열을 0인덱스부터 size까지 복사한다.
        //이때, a 배열의 인덱스 this.size 이후에 null을 추가로 삽입해주어야 하기 때문에 
        //추가적인 작업이 수행됩니다. 마지막 요소 이후에 null을 삽입하여 반환
       
       System.arraycopy(items, 0, a, 0, size);
 
        if(a.length > size){ 
            a[this.size] = null;
        }

        /* for (int i = 0; i < a.length; i++) {
            a[i] = (T) items[i];
        } */

    } else {// 전달받은 배열 공간이 작다면 새로운 배열로 복사하여 반환
        /* a = (T[]) new Object[size];
        for (int i = 0; i < size; i++) {
            a[i] = (T) items[i];
        } */
        return (T[]) Arrays.copyOf(items, size, items.getClass());
    }
    return a;
}

 

자료구조(data structure) 

: 컴퓨터 과학에서 효율적인 접근 및 수정을 가능케 하는 자료의 조직, 관리, 저장을 의미함.
  데이터 값의 모임, 데이터 간의 관계, 데이터에 적용할 수 있는 함수나 명령.
  효과적으로 설계된 자료구조는 실행시간 혹은 메모리 용량과 같은 자원을 최소한으로 사용하면서 연산을 수행하도록 함.

 

 

 

자료구조와 알고리즘의 관계

 

    - 자료구조 : 데이터의 조직화와 저장방법을 다루는 것
    - 알고리즘 : 문제를 해결하기 위한 단계적인 절차나 방법(프로그램 명령어들의 집합)
     1) 자료구조의 선택은 알고리즘의 효율성에 직접적인 영향을 미친다.
        : 특정한 문제를 해결하기 위해서 데이터를 어떻게 조직화하고 저장할지 중요함.
            => 알고리즘의 실행시간과 공간 복잡도에 영향을 준다.(ex- 배열보다는 리스트가 적절한 선택이다.)
     2) 다양한 자료구조가 존재하며, 각 자료구조에 대응자료구조와 알고리즘의 관계하는 특징 알고리즘이 있다.
        => 알고리즘을 설계할 때 사용할 자료구조를 고려하여 적절한 선택을 해야한다.
        : ex- 배열은 빠른 접근시간을 제공하지만 크기 변경이 어렵고 삽입/삭제 연산이 비효율적임 => 연결리스트가 더 적합
     3) 자료구조와 알고리즘 설계의 최적화 하여 실행시간과 공간 사용량을 줄일 것
        : 데이터 검색을 빠르게
     4) 자료구조와 알고리즘은 서로 상호 의존적이다.
▶결론 : 적절한 자료구조의 선택과 효율적인 알고리즘의 설계는 프로그램의 실행 시간과 공간 복잡도를 최적화 하는데 중요한 역할을 한다.

 


 

- 분류 : 자료의 특성과 크기, 주요 사용법과 수행하는 연산의 종류, 구현에 필요한 기억공간 크기
- 종류 : 단순구조(자료형으로 분류), 선형구조, 비선형 구조, 파일 구조
           원시데이터구조(자료형) / 비원시데이터구조(배열, 리스트(선형, 비선형), 파일)

 

▶구현에 따른 분류
    - 배열 : 가장 일반적인 구조. 메모리상에 같은 타입의 자료가 연속적으로 저장. 자료값을 나타내는 가장 작은 단위.
    - 튜플 : 둘 이상의 자료형을 묶음으로 다룬다.
    - 연결 리스트 : 노드 단위(노드의 집합). 노드는 자료와 다음 자료를 가리키는 참조값으로 구성됨.
    - 원형 연결 리스트 : 각 노드는 다음노드 가리키고. 마지막 노드는 처음의 노드를 가리키는 연결 리스트
    - 이중 연결 리스트 : 각 노드는 이전 노드와, 다음 노드를 가리키는 참조값으로 수성. 처음 노드와 마지막 노드의 다음 노드 없음.
    - 환형 이중 연결 리스트 : 처음 노드가이전 노드로 마지막 노드를 가리키고, 

                                          마지막 노드가 다음노드로 처음 노드를 가리키는 이중 연결리스트
    - 해시 테이블 : 개체가 해시값에 따라 인덱싱(key값을 해시값으로 인덱스를 저장)

▶형태에 따른 분류
    - 선형구조
     1) 스택 : First In Last Out 먼저 저장된 것이 제일 나중에 출력됨(밑이 막힌 구조)
     2)  : First In First Out 먼저 저장된 것이 제일 먼저 출력됨.
     3) 덱 : 양쪽에서 넣고 출력한다.
    - 비선형구조
     1) 그래프 : 노드와 그들을 연결하는 간선으로 구성된 자료구조. 다양한 관계를 모델링 할 수 있으며, 

                      방향성과 가중치를 가질 수 있다. (유향그래프, 무향 그래프// 네트워크, 지도, 소셜 네트워크 등에 사용)
     2) 트리 : 계층적인 구조. 노드로 구성됨. 각 노드는 하나의 부모노드와 여러개의 자식 노드를 가진다. 

                   (이진트리, 이진탐색트리, 힙 등)

 


 

 

▶ Algorithm 알고리즘

: 문제를 해결하기 위한 절차나 방법. (프로그램을 실행하는 명령어들의 집합)

 

알고리즘의 성능 평가 : 컴퓨터에서 시간과 메모리(공간) 두 자원을 얼마나 소모하는지의 효율성이 중점적
                                  동일한 결과를 수행하는 알고리즘이 잇을때 복잡도가 낮을수록 좋은 알고리즘이다.
- 공간복잡도(Space Complexity) : 입력 값에 대한 문제를 해결하는데 필요한 메모리의 양
- 시간복잡도(Time Complexity) : 입력 값에 대한 문제를 해결하는데 소요되는 시간

 

▷ 표기법
 - Big-O : 최악의 경우(빅오) - 알고리즘을 실행 했을 때 최대로 걸릴 수 있는 시간
 - Big-θ : 평균의 경우(빅세타)
 - Big-Ω : 최선의 경우(빅오메가)
   => 빅오가 늦은 알고리즘을 택한다.

 

▶ 빅오 표기법(Big - O notation) - 최악의 경우
  점근표기법으로 O사용(상한점근) 무한급수의 뒷부분 간략화
- O(N) 으로 표기하고 N = 입력되는 데이터의 크기


- O(1) : 입력데이터의 크기에 상관 없이 언제나 일정한 시간이 걸리는 알고리즘.

            (= 상수시간복잡도 ex - 배열에서 인덱스요소로 찾는 것)


- O(log N) : 입력데이터가 커질수록 처리시간이 로그만큼 짧아짐 (= 로그시간 복잡도 ex - 이진탐색트리가 대표적)


- O(N) : 입력 데이터의 크기에 비례하여 처리시간이 증가

 

            (= 선형시간 복잡도 ex - 1차원 for문의 경우 / 배열의 모든 요소를 순회하는 경우)
- O(N log N) : 입력 데이터가 커질수록 처리시간이 로그(log) 배 만큼 더 늘어난다.(정렬알고리즘 중 병합정렬, 퀵정렬 대표적) 

- O(N^2) : 입력데이터의 크기에 비례해 처리시간이 급수적으로 증가 = N x N  (M * N 에서 M이 N보다 작을경우 O(NM)로 표기)
             (= 이차시간 복잡도 ex - 이중 for문의 경우)


- O(2^N) : 입력데이터가 커질수록 처리시간이 기하급수적으로 증가

             (= 지수시간 복잡도 ex - 피보나치 수열, 재귀가 역기능을 할 경우에 해당)

 

 

        빠름                                                                느림(효율성이 떨어짐)
        O(1)  <  O(log N)  <  O(n logN)  <  O(N^2)  <  O(2^N)

 

 

 

 1) 공간복잡도
           : 알고리즘의 메모리 요구사항을 분석하고 예측하는데 사용. 알고리즘에 필요한 변수, 배열, 데이터 구조, 임시 공간등 고려
             현재는 램의 성능이 좋아서 시간복잡도에 비해 고려하지 않아도 된다.
 2) 시간복잡도
           : 알고리즘이 실행되는데 소요되는 시간의 증가율. 알고리즘의 입력데이터의 크기에 따라 달라지고. 

             실행시간이 입력크기의 함수로 표현됨.

 

 

URL = Uniform Resource Locater

: 브라우저에서 리소스를 식별하고 요청하기 위해 사용되는 주소를 나타내는 문자열

 

 

URL Encodeing 이 필요한 이유?

: 주소를 나타내는 문자열에 특수문자나 공백이 포함될 경우 URL의 유효성을 해치거나

서버에서 잘못된 로직처리를 유발 할 수 있기 때문에 이를 방지하기 위해  '%' 를 붙인  Percent-encodeing 방식을 사용한다.

 

 

▶URLEncoding(Percent-encodeing)

: URL에 포함될 수 없는 안전하지 않은 문자를 % 기호와 뒤에 두자리의 16진수 숫자로 표현한다. ASCII 문자셋으로 변환하는 과정을 수행

 

 

 

 

URL Encodeing규칙 : RFC3986에서 URL에 포함할 수 있는 문자들을 정의함

  ▷ 예약어(Reserved characters)

: URL에서 특정한 기능을 갖고있는 문자들로, URL의 구조를 정의하거나 특정한 의미를 가지며 URL에 그대로 사용할 수 없고 인코딩을 통해 안전한 형태로 변환해야 한다.

  -인코딩 대상 특수 문자 = !, #, $, &, ', (, ), *, +, ,, /, :, ;, =, ?, @, [, ]

 

  ▷ 비예약어(Unreserved characters)

: URL에서 특정한 의미를 갖고있지 않고, 일반적인 데이터로 사용되는 문자들이며 URL에 인코딩이 필요하지 않는다.

  - 인코딩이 필요 없는 문자

    문자 및 숫자 : 알파벳 대문자(A-Z), 알파벳 소문자(a-z), 숫자(0-9)

    일부 특수문자 : - (하이픈), _ (언더스코어), . (마침표), ~ (물결 기호)

 

 ▷ 공백의 경우 '%20' 또는 '+'  으로 대체된다.

공식 문서 참조 : https://perishablepress.com/stop-using-unsafe-characters-in-urls/

 

(Please) Stop Using Unsafe Characters in URLs | Perishable Press

Just as there are specifications for designing with CSS, HTML, and JavaScript, there are specifications for working with URIs/URLs. The Internet Engineering Task Force (IETF) clearly defines these specifications in RFC 3986: Uniform Resource Identifier (UR

perishablepress.com

 

 

URL Encodeing 변환 표

문자 인코딩
':' %3A
'/' %2F
'?' %3F
'#' %23
'[' %5B
']' %5D
'@' %40
'!' %21
'$' %24
'&' %26
"'" %27
'(' %28
')' %29
'*' %2A
'+' %2B
',' %2C
';' %3B
'=' %3D
'%' %25
' ' %20 or +

 

 

URL 인코딩 변환사이트

https://www.convertstring.com/ko/EncodeDecode/UrlEncode

 

URL 인코딩 - 온라인 URL 인코더

 

www.convertstring.com

 

 

▶JAVA - URLEncoder/Decoder 클래스 예시

	String str = "Hello World 123 www.naver.com/한글입력";
	String encoded = URLEncoder.encode(str, "utf-8");
	System.out.println("encoded= " + encoded);
	// encoded= Hello+World+123+www.naver.com%2F%ED%95%9C%EA%B8%80%EC%9E%85%EB%A0%A5
	
	
	String str2 = "Hello%2c+Word!+%ec%95%88%eb%85%95%ed%95%98%ec%84%b8%ec%9a%94";
	String decoded = URLDecoder.decode(str2, "utf-8");
	System.out.println("decoded= " + decoded);
	// decoded= Hello, Word! 안녕하세요

 

 

 

* 현재까지 배웠던 명령어

 

 

디렉토리
  • ls : 현재 디렉토리 내부의 파일 목록 조회
  • cd : 디렉토리로 이동
  • mkdir : 새 디렉토리 생성
  • rmdir : 디렉토리 제거

 

 

파일조작
  • cp : 파일복사
  • mv : 파일이동
  • rm : 파일 삭제

 

 

파일 읽기(cat, more, less, head, tail)
  • cat
-- intra.log 파일을 읽어서 특정 문자열("Excetion")이 몇개가 나오는지 확인
cat intra.log | grep Excetion

 

검색
  • find : 해당 파일 검색 [옵션 -name]
-- 현재 폴더에서 자바 파일 갯수 구하기
find . -name "*.java" | wc -l

 

압축 
  • gzip 파일명 : 압축 [옵션 -d : 압축 해제]
-- 압축파일 해제하기
gzip -d 압축파일명.gz  : 압축 해제
  • tar 파일명 : 여러 파일을 하나로 묶음

 

 

그 외
  • sudo : 관리자 권한으로 명령어 실행
  • awk : 파일의 레코드 출력 조작
awk '{print $1, $3}' : 1열, 3열 출력

-- 서버에 접속한 아이디와 아이피만 출력하고 싶을 때
w -h | awk '{print $1, $3}'

 

  • wc : 문자, 단어, 행(line) 수 출력
-- 옵션
m : 지정한 파일의 문자수 출력
w : 지정한 파일의 총 단어수 출력
l : 지정한 파일의 줄(line)의 수
c : 지정한 파일의  bytes 출력
L : 지정한 파일의 모든 행 중 길이가 가장 긴 행의 문자수 출력

 

  • grep : 파일안의 지정한 문자열을 포함한 행출력 [grep 문자열 파일명]

230118
써블릿(Servlet) = JSP + 자바 기술
객체기반으로 웹프로그램으로 개발할때 사용하는 핵심 기술이다.
사용자의 조건이 달라지면 보여지는 웹 컨텐츠가 다름

* 웹서버는 정적인 문서

서블릿의 장점
- 쓰레드를 기반으로 한다. 웹 애플리케이션 운영에 효율적임
- 실행할 때 쓰레드로 실행
- 서블릿은 - DB와 연결해서 사용하던지, 자바 객체를 사용해서 처리하던지..
- 서블릿의 결과를 html형식으로 클라이언트에 전송된다.
- MVC패턴에서 서블릿을 사용하면 좋은점
 1) 컨트롤러 - 서블릿
 2) 뷰 : JSP, JSTL
 3) 모델 : 자바 클래스(Service, DAO, VO)
컨텐츠와 비즈니스 로직을 분리할 수 있다.
컨트롤러와 뷰의 역할 분담으로 웹디자이너와 개발자 간의 원할한 작업 가능

서블릿객체의 상속구조
: 서블릿 상속구조와 클라이언트 요청이 있을 때 처리하는 순서
HttpServlet

- get방식 데이터 '?' => id(key)=값 & pass=값
  예) http://www.xxx.co.kr/servlet/login?id=hj&name=hong
  url이 노출되기 때문에 보안문제가 생길 수 있다.
  url 길이가 제한되어 있어서 많은 양의 데이터를 보낼 수 없다.

- post 방식 
  많은 양의 데이터를 전송할 수 있다.(파일전송 가능)
  url주소가 노출되지 않는다.
  데이터 영역은 전체 크기가 정해져 있지 않다.
  
** 서블릿의 생명주기(메서드)
서블릿 실행 요청 - 서블릿 컨테이너가 메모리에 있는지 검사하고
있으면 서블릿을 실행하고 메모리에 없으면 서블릿을 메모리에 올린다.
컨테이너로부터 서블릿의 종료요청이 있을때 메모리에서 삭제한다.

init() : 메모리에 없는데 서블릿을 메모리에 올릴 때 최초 한번 실행하는 메서드
사용하면 서블릿이 메모리에서 사라지는게 아니고 컨테이너에 보관한다.
init : 한번만 실행된다.

service() : 또 요청이 오면 서블릿을 호출해서 사용 가능(모든 요청과 응답)
    쓰레드에서 - service() 메서드를 호출한다. - doGet / doPost
            매개변수 전달 = HttpServletRequest(요청) /HttpServleResponse(응답)
            매개변수 객체가 자동으로 만들어져서 전달한다.

destory() : 메모리에서 서블릿이 삭제될 때 한번만 실행하는 메서드



1. forward 방식 : request, resonse객체 파라미터값 보낼수 있음

2. redirect 방식 : 데이터를 넘겨줄때 request, resonse객체로 
                   파라미터 못넘겨줌
                   보내는 주소로값을 입력해서 넘겨줄수 있음

3. 쿠키 : 공유할 데이터를 클라이언트의 웹브라우저에 저장
  문자열데이터만 저장할 수 있다.
          클라이언트 쪽에 저장하기 때문에 보안이 취약함
          중요한 데이터를 저장하지 않는다.

4. 세션 : 공유할 데이터를 서버에 저장
          모든 데이터 저장가능

'고급JAVA' 카테고리의 다른 글

Log4J  (0) 2023.01.17
MVC 패턴과 싱글톤(Singleton) 패턴  (0) 2023.01.11
쓰레드 공부-04 : 쓰레드 상태  (0) 2022.12.27
쓰레드 공부-03 : 쓰레드의 실행제어  (0) 2022.12.27
쓰레드 공부-02  (1) 2022.12.26

예제: 인터넷쇼핑몰시스템
- 우리는 인터넷을 통해 물품을 판매하는 시스템을 구축하고자 한다.
- 고객은 회원등록을 통해 본인 정보를 등록하고, ID, Password를 입력함으로써 시스템에 접속할 수 있으며, 
  물품을 구입할 수 있다.
- 고객이 회원 로그인을 할 때 및 물품을 구입할 때에는 별도 암호화된 모듈을 통해 본인 확인 절차를 
  거쳐야 한다.
- 물품을 구매하여 결재할 때에는 일반 포인트를 결재할 수 있으며, 신용카드를 통해 결재할 수도 있다.
- 신용카드를 통해 결재하고자 하는 경우에는 협약을 맺은 카드승인회사에게 카드승인을 요청하여야 한다.
- 고객은 구매한 물품의 배송상황을 조회할 수 있으며, 직원도 고객 물품에 대해 배송추적을 할 수 있다.


액터 : 고객, 직원, 카드승인회사
유스케이스 : 회원등록, 로그인, 구입, 결제, 본인확인, 배송조회, 신용카드 결제

 


 

유스케이스 명세서 ==> 유스케이스 내부에 대한 내용을 기술한다.

# 유스케이스명 : 회원등록
# 액터 : 고객(비회원)
# 유스케이스 개요 및 설명 : 고객이 인터넷 쇼핑몰 시슼템을 사용하기 위해
  회원가입을 하는 유스케이스 이다.

# 사전 조건 : 회원 가입이되어 있지 않은 상태이어야 한다.
# 이벤트 흐름
 - 정상 흐름
  1. 회원등록을 요청한다.(액터)
  2. 회원 약관을 보여준다.(시스템)
  3. 회원약관에 동의한다.(액터)
  4. 회원 정보 입력항목-회원가입창을 보여준다.(시스템)
  5. 입력항목중 ID를 입력받아 중복여부를 확인을 요청한다. (액터)
  6. 기존의 회원인지 여부를 ID를 검색하여 확인한다.(시스템)
  7. 나머지 입력항목(이름, 비밀번호, 전화번호, 주소, 이매일 등)
     입력하고 등록을 요청한다.(액터)
  8. 입력된 정보를 확인한다. (시스템)
  9. 회원정보를 DB에 저장하고 등록 완료한다.(시스템)

 - 선택 흐름
   3-1. (3번에 대한 문제점 1번 처리)
      회원약관에 동의하지 않으면 회원가입 기능 오류 메세지를 출력하고 동의를 요청한다.
   6-1. 기존에 가입되어 있는 회원인 경우에는 '이미 가입된 회원입니다.' 라는 메세지를 보여준다.
   6-2. 다른 ID를 입력하도록 요청한다.
   8-1. 회원 정보 항목 중 입력하지 않은 항목이 있는 경우 오류 메세지를 출력하고 재입력을 요청한다.
   8-2. 비밀번호는 6~10자에 해당하지 않거나 영문자, 특수문자, 숫자조합인지 확인해서 형식에 맞지 않으면
        오류 메시지를 출력하고 재입력을 요청한다.
   8-3. 비밀번호와 비밀번호 확인이 다르면 오류메시지를 출력하고 재입력을 요청한다.
   8-4. 이메일 형식에 맞지 않으면 오류메시지를 출력하고 재입력을 요청한다.

log for java

개발하는 단계에서도 많이 활용할 수 있다.

자바에서 로그 기록을 남기는 라이브러리

 

Log4j를 이용하면 프로그램 실행시, 실행 코드의 수정없이 설정파일을 통해서 로깅작업을 컨트롤 할 수 있다.

Logger계층구조를 이용하면 어떤 로그문을 출력할지 상세하게 컨트롤하기 쉽다

 

Log4j의 주요 구성요소

- Logger : 로깅 정보를 캡쳐

  . 로깅메세지를 appender에 전달(출력할 수 있음 - appender : 어디로 보낼지 역할)

  . log4j의 심장부에 위치

  . 개발자가 직접 로그 출력 여부를 런타임에 조정

  . 로그 레벨을 갖고 있음

- Appender : 다양한 목적지로 로깅 정보를 출력

  . 파일, 콘솔, DB 등.. 출력위치 결정

  . XXXAppender(ConsoleAppender ,FileAppender, JDBCAppender, SMTPAppender(~이메일) 

                             RollingFileAppender, DailyRollingFileAppender, NTEventAppender 등...)

- layouts : 로깅 정보를 위한 다양한 출력 포맷 구성(어떤 형식으로 출력할것인지)

  . 날짜관련 DatePattern있음..

- 로그레벨(6단계)

  . TRACE - 레벨이 제일 낮음

  . DEBUG : 개발시 디버그 용도로 사용한 메세지

  . INFO : 정보메세지 출력 (일반적으로 설정함)

  . WARN : (warnning) 경고메세지

  . ERROR

  . FATAL - 레벨 제일 높음 : 심각한 에러

 

Log4j 설정 방법

- 사이트에서 라이브러리 파일.jar 파일 설치 -빌드패스에 추가

 

log4j.rootLogger = info레벨에서 부터 로그를 출력하겠다. stdout 출력(appender), logfile(appender)환경에 맞게 출력

ConsoleAppender

Target=System.out  = 콘솔의 기본 출력장치

패턴형식 있음.

 

DailyRollingFileAppender = 날짜별로 환경을 만들어서 로그 출력

 

클래스 임포트 - 아파치 제공하는 Logger

로거 객체 만들기

= static Logger logger = Logger.getLogger(Log4jTest.class);

 

- 콘솔 출력 패턴

TRACE (basic.Log4jTest:14) - 이것은 Log4j의 TRACE레벨의 로그 메세지 입니다.

%5p (%C{2}:%L) - %m%n

5: 는 5자리

p : 로그레벨이름 출력

C : 클래스명 출력(%C{2} : 패키지 구조명 뒤에서 두 단계까지만 씀)

L: 라인 수(소스파일의 줄 번호)

m : 메세지 - 로그내용 출력

n: 줄 바 꿈

 

- 파일 출력 패턴

[%d{yyyy-MM-dd HH:mm:ss}] %5p (%C{2} - %M:%L) - %m%n

년도시분초 / 

M : method이름(현재는 메인메소드)

L : 줄번호

 

 %p : debug, info, warn, error, fatal 등의 priority 가 출력된다. 
 %m : 로그내용이 출력됩니다.
 %d : 로깅 이벤트가 발생한 시간을 기록합니다.
		포맷은 %d{HH:mm:ss, SSS}, %d{yyyy MMM dd HH:mm:ss, SSS}같은 형태로 
		사용하며 SimpleDateFormat에 따른 포맷팅을 하면 된다.
 %t : 로그이벤트가 발생된 쓰레드의 이름을 출력합니다. 
 %% : % 표시를 출력하기 위해 사용한다. 
 %n : 플랫폼 종속적인 개행문자가 출력된다. \r\n 또는 \n 일것이다. 
 %c : 카테고리를 표시합니다 
		예) 카테고리가 a.b.c 처럼 되어있다면 %c{2}는 b.c가 출력됩니다. 
 %C : 클래스명을 포시합니다. 
		예) 클래스구조가 org.apache.xyz.SomeClass 처럼 되어있다면 
			%C{2}는 xyz.SomeClass 가 출력됩니다 
 %F : 로깅이 발생한 프로그램 파일명을 나타냅니다. 
 %l : 로깅이 발생한 caller의 정보를 나타냅니다 
 %L : 로깅이 발생한 caller의 라인수를 나타냅니다 
 %M : 로깅이 발생한 method 이름을 나타냅니다. 
 %r : 어플리케이션 시작 이후 부터 로깅이 발생한 시점의 시간(milliseconds) 
 %x : 로깅이 발생한 thread와 관련된 NDC(nested diagnostic context)를 출력합니다. 
 %X : 로깅이 발생한 thread와 관련된 MDC(mapped diagnostic context)를 출력합니다

 

 

'고급JAVA' 카테고리의 다른 글

Servlet 써블릿  (1) 2023.01.18
MVC 패턴과 싱글톤(Singleton) 패턴  (0) 2023.01.11
쓰레드 공부-04 : 쓰레드 상태  (0) 2022.12.27
쓰레드 공부-03 : 쓰레드의 실행제어  (0) 2022.12.27
쓰레드 공부-02  (1) 2022.12.26

MVC(Model, View, Controller )패턴

Model => 데이터와 데이터를 구성하기 위한 로직을 말한다.

View => 데이터를 사용자에게 보여주는 역할

Controller => 사용자의 요청을 받아서 Model에 일을 시키고 그 결과를 받아서 
View에 전달한다.
-------------------------------------------------------------------------------

JAVA에서 MVC패턴의 비지니스 로직에 사용되는 클래스들...

- VO, DTO ==> 데이터를 저장하는 역할만 하는 클래스
       (VO=Value Object, DTO=Data Transfer Object)
                     (DB테이블에서 1개의 레코드가 저장될 클래스를 말한다.)

- DAO ==> SQL문을 DB서버에 보내서 그 결과를 얻어오는 역할을 수행하는 클래스
   (DAO=Data Access Object)

- Service ==> 일을 수행하는 중간 관리자 역할을 수행하는 클래스
      Service는 일이 있으면 그 일에 필요한 DAO를 호출해서 일을 처리한 후
      처리된 결과를 Controller에게 전달한다.

- Controller ==> 비지니스 로직이 시작되는 곳으로 사용자의 요청이 오면 그 요청에 맞는
     Service에게 일을 시키고, Service가 보내온 처리 결과를 View에 전달하는
    역할을 수행한다.


Controller  ----> Service    --->  DAO  ---> DB서버
                <---                <---          <---
    VO                 VO --> 자료를 보통 VO나 Collection객체에 담아서 보낸다.



 






 

Service => DAO를 부름

Controller => Service를 부름

 


Singleton패턴 ==> 객체가 1개만 만들어지게 하는 패턴
    (외부에서 new 명령을 사용하지 못하도록 한다.)
    
  Singleton 클래스를 만드는 방법(필수 구성요소)   
  1) 자신class의 참조값이 저장될 변수를 private static으로 선언한다.
 
  2) 모든 생성자의 접근 제한자를 private으로 한다.
     (생성자가 없으면 기본 생성자를 반드시 만들어야 한다.)
 
  3) 자신 class의 인스턴스를 생성하고 반환하는 메서드를 public static으로 작성한다.
     ( 이 메서드의 이름은 보통 getInstance으로 한다.)

public class MySingleton {
	// 1번
	private static MySingleton single;
	
	// 2번 - 기본생성자를 private으로 한다.
	private MySingleton() {
		System.out.println("생성자 입니다....");
	}
	
	
	// 3번
	public static MySingleton getInstance() {
		if(single == null) single = new MySingleton();
		return single;
	}
	
	// 기타 이 클래스가 처리할 내용을 작성한다.
	
	public void displayTest() {
		System.out.println("싱글톤 클래스의 메서드 호출입니다...");
	}
}

 

public class SingletonTest {
	public static void main(String[] args) {
//		MySingleton test = new MySingleton();  //  외부에서 new 명령 사용 불가
		
		MySingleton test2 = MySingleton.getInstance();
		
		MySingleton test3 = MySingleton.getInstance();
		
		System.out.println("test2 ==>" + test2.toString());
		// @7852e922
		System.out.println("test3 ==>" + test3);
		// @7852e922 참조값이 같다
		
		System.out.println(test2.equals(test3)); // true
		System.out.println(test2 == test3); // true
		
		test2.displayTest();
	}
}

 


 

싱글톤 할때 DB테이블에서 컬럼명 쉽게 가져오기

SQL
----------------------------------------------------------------------------------------
select 'private '|| 
       decode(lower(data_type), 'number', 'int ', 'String ') || ' ' ||
       lower(column_name) || ';'
from cols
where lower(table_name) = 'jdbc_board'

'고급JAVA' 카테고리의 다른 글

Servlet 써블릿  (1) 2023.01.18
Log4J  (0) 2023.01.17
쓰레드 공부-04 : 쓰레드 상태  (0) 2022.12.27
쓰레드 공부-03 : 쓰레드의 실행제어  (0) 2022.12.27
쓰레드 공부-02  (1) 2022.12.26

1. NEW: 쓰레드 객체가 생성되고 아직 start()를 호출하지 않은 상태

- start()가 호출하고 쓰레드의 실행할 수 있는 환경이 만들어지면 ~

 

2. RUNNABLE : 쓰레드의 실행 대기 ~ 실행 중 상태

3. BLOCKED : 동기화 블럭에 의해서 일시정지된 상태(lock풀리기 전)

4. WAITING / TIMED_WAITING : 일시정지 상태. 쓰레드 상태가 종료되지 않았지만 실행 가능하지 않은 상태

    (sleep , join 등)

 

5. TERMINATED : 쓰레드의 작업이 종료된 상태 

 

 

※ 교착상태 : 서로 다른 두 개의 프로세스가 실행하지 않고 서로의 작업을 끝나기를 기다리고 있어서 마치 프로그램이 종료된것 처럼 보이는 상태.

 


 

▶ 쓰레드 상태확인하는 법

    Thread.State (열거 상수)

    .getState() 메서드 이용(열거형)

// 무언가를 실행하는 쓰레드(쓰레드 상태검사)
class TargetThread extends Thread{
@Override
public void run() {
	// 시간지연용
	for (long i = 1L; i <= 20_000_000_000L; i++);
	
	try { // 1.5초마다 진행
		Thread.sleep(1500); 
	} catch (InterruptedException e) { }
	
	for (long i = 1L; i <= 20_000_000_000L; i++);
	}
}
--------------------------------------------------------
//쓰레드의 상태를 출력하는 쓰레드
class StatePrintThread extends Thread{
  private TargetThread target;

  public StatePrintThread(TargetThread target) {
	this.target = target;
  }

  @Override
  public void run() {
	while (true) {
	//Thread.State 열거형 => .getState()
	Thread.State state = target.getState();
	System.out.println("Target쓰레드의 현재 상태 : " + state);
	
	if(state == Thread.State.NEW) { 
		// 쓰레드의 상태가 NEW라면
		//NEW = 객체는 생성하고 start()하지 않은 상태
		target.start();
	}
	
	if(state == Thread.State.TERMINATED) {
		// 쓰레드의 상태가 TERMINATED = 종료
		break; // while문 종료
	}
	
	try {
		Thread.sleep(500);
	} catch (InterruptedException e) { }
	} // while
}
}
----------------------------------------------------
- main -
public class Th11 {
	public static void main(String[] args) {
	// 쓰레드 상태를 출력하는 쓰레드 객체 생성
	Thread th1 = new StatePrintThread(new TargetThread());
	th1.start();
	}
}

 

 

 

'고급JAVA' 카테고리의 다른 글

Log4J  (0) 2023.01.17
MVC 패턴과 싱글톤(Singleton) 패턴  (0) 2023.01.11
쓰레드 공부-03 : 쓰레드의 실행제어  (0) 2022.12.27
쓰레드 공부-02  (1) 2022.12.26
쓰레드 공부-01  (0) 2022.12.22

+ Recent posts