2017년 1월 25일 수요일

고유값 분해 (eigenvalue docomposition)


1. 고유값 분해 (eigenvalue docomposition) 란?

 정방행렬(n * n squre matrix) A 에 대해 Ax = λx  (상수 λ)가  성립하는 0 이 아닌 벡터 x가 존재할때 상수 λ 를 행렬 A의 고유값 (eigenvalue),  x 벡터를 고유벡터(eigen vector )라고 함.


λ = 람다 = 고유값(eigenvalue) = 특성값 = 잠정근(latent value )

행렬 A의 모든 고유값의 집합을 스펙트럼(spectrum)이라 칭함 


 - 실질적으로 eigent vector 를 찾는것이 주목적임.

 - 기하하적인 의미로, 행렬의 곱은 결과가 원래벡터와 방향이 같고, 고유값 상수만큼에 비례하여 변한다는 의미가 있다. (즉 방향은 변하지 않는다. 크기반 변한다. )




- 각 고유값 위의 그림에서의 2개의 고유벡터와 고유값 늘린거와 같이  팽창되는 것을 볼수 있다. 즉 고유값 람다만큼 방향벡터는 방향이 바뀜이 없이 크기만 커지는 것을 관찰할 수 있다. 

궁금증? : 행렬과 좌표공간의 대응방법?? 선형변환을 알아볼것 
  >> 아직은 선형대수학에 대한 기초지식이 부족하다. 

2. 고유값 분해 추출 방법 





위의 A-λI  특성행렬(characteristic matrix) 라고 하며, D(λ) 는 행렬 A의 특성행렬식(characteristic determinant) 라고 합니다.  그리고 A-λI = 0  특성방정식(characteristic equation) 혹은 고유방정식(eigenvalue equation) 이라고 합니다.

n sqaure matrix 는 고유값(eigent value )을 적어도 1개이상 n 개의 다른 고유값을 가진다. 




 - 가우스 소거방식을 이용하여 고유 벡터를 구한다. 

[ 고유공간 (eigenspace) ]

 만일 w와 x가 행렬 A의 같은 고유값 λ에 대한 고유벡터인 경우, w + x (단, x≠-w)와 kx (단, k는 임의의 0 아닌 스칼라)도 고유벡터가 된다.  따라서 같은 고유값 λ에 대응하는 고유벡터들은 0 벡터와 함께 하나의 벡터공간을 이루며, 이것을 고유값 λ에 대응하는 고유공간(eigenspace)라고 부른다.

2017년 1월 23일 월요일

Mean Shift (평균이동)


1. Mean Shift (평균이동) 개념

이미지 출발점으로부터 로컬이미지 영역내에서 가장 밀도가 높은 지역의 평균(mean)을 따라 이동(shift)하는 방법 // 샘플 데이터 피크 혹은 자신주변의 밀집된 데이터의 집합으로 이동하는 알고리즘

>> 이미지 트래킹에 많이 쓰인다.
>> 이외에도 segmentation, clustering , smoothing
>> 하지만 서로 중첩되는 이미지의 경우 다른 이미지 영역으로 트래킹될수도 있다.

* 영상의 밀도를 파악하기 위해 히스토그램을 이용한다.

2. 커널함수

* 히스토그램의 확률밀도 추정이 힘듦
- bin 경계의 불연속성
- bin 설정의 모호함과 크기에 따른 분포변화에 민감함.

* 히스토그램의 추정의 단점을 개선하기위한 continous 한 확률밀도를 구하기 위한 커널함수를 이용


- 각 편차(x -xi)들의 합을 전체 sample dataset가 비교
- 커널 밀도추정(KDE)에서 변수 X에 대한 확률 밀도함수 : 기존의 불연속한 히스토그램을 스무딩시킨다.
- h는 대역폭을 조절하는 파라미터

* 커널함수의 특징
- 원점을 중심으로 symetric(대칭)되면서 적분값이 1 인 non-negatice 함수
- 관측된 데이터 각각마다 해당 샘플데이터 값을 중심으로하는 커널함수를 생성
- 이 커널함수를 모두 더한후 전체 데이터 갯수로 나누면 컬널함수의 완성
- 여기에 커널함수를 bandwidth(대여폭: 주파수 대역의 행 ) 조절하는 h 파라미터가 있다. 이는 높게 잡을수록 밀도함수가 뭉뚱그래지며, 작으면 극단적으로 뾰족해진다.

3. 공식


- 이곳에서는 나오는 가중치는 일종의 확률값으로 계산되는 데, 하나의 픽셀의 분포가 나올 확률이라고 생각하면된다. 그 픽셀의 밀도가 높으면 확률이 높게 나타나고 배경이나 외곽으로 갈수록 배경이 확률이 높기때문에, 가중치의 값은 낮아지게된다. 

- 가중치내에 있는 좌표들의(윈도우) 가중평균(무게중심)을 구하는 것이다. 각 픽셀들의 가중치를통해 전체 확률에서 x위치가 차지하는 가중치를 나누게되면 그 평균값이 곧 무게중심값이 되는것이다. 


- K(ri)는 커널함수로서  >> 아직 공부할게 있음.... 정확하게 표현을 못하겟음.

- 윈도우를 재조종하면서 새로운 X좌표가 중심을 잡도록 재조정한다. 

4. 기타 이용

- 히스토그램 즉 확률밀도와 유사도를 비교하여, 유사도가 가장큰 윈도우를 예측하여 트래킹한 사물의 크기또한 유추하는 것이 가능하다. 유사도는 Bhattacharyya 함수를 이용한다.

2015년 12월 2일 수요일

Operating System : Files and Directories.


1. stat , fstat, and lstat function


  • 기본적인 파일에 관련된 정보를 얻을 수 있는 함수
  • stat 기본적인 파일 정보를 원하는 버퍼로 넘겨줘 보여줌 
  • fstat 파일디스크립터로 열린 파일만 , 원하는 버퍼로 넘겨줘 보여줌
  • lstat은 심볼릭링크에 대한 정보만을 버퍼로 넘겨줌, 심볼링링크에 연결된 파일을 보여주는 것이 아님.
2. File Type
file 자료형 구조

  • Regular File : 어떤 형태의 데이터를 갖고 있는 가장 흔한 타입, unix에 관련된 특이점이 없으며, 단지 text이거나 binary이다. 주의할만한 점은 kernel은 반드시 이 포맷을 이해된 상태여야함, 프로그램을 실행하기 위해 이 포맷(txt나 데이터를 커널에 인지해주는)을 사용해야하기 때문에….
  • Directory File : 파일들의 정보 pointer를 갖고있는 파일, 프로세스는 읽기만 가능하며, kernel만 쓰기 가능
  • Block special File : buffer를 사용하여 access하거나 일정한 크기의 디바이스를 access할 때 사용.
  • Character special File : 버퍼를 사용하지 않거나, 다양한 크기의 디바이스를 access할 때 사용
  • FIFO : process간의 통신을 가능하게 하는 파일, 잘 알려진 파이프라고 간주
  • Socket : 프로세스간의 통신을 가능하게 하는 파일, 싱글 host에서 프로세스들 간의 통신을 가능케함.
  • Symbolic link : 또 다른 파일을 가리키는 파일
3. Set-userID and Set-group ID 

프로세서는 6개이상의 ID정보를 가지고 있다. 

  • read UserId와 real group ID 로 누구인지를 식별한다. 로그인 세션동안에서 얻은 사용자 자체를 일컫는다. 
  • effective 와 supplementary gruoup ID 는 프로세스가 파일에 접근하기 위해 사용하는  접근자 ID 및 그룹 ID 을 관리한다.
  • save 계열은 프로세스가 실행될때, effective user Id와 group Id의 복사본을 저장한다.
  • 파일 구조에서 파일에 st_mode의 special flag을 조정할 수 있다.  그러면 파일이 실행할때 그 파일을 실행한 프로세스가 그 파일의 owner가 되거나 group owner가 될수 있다. 이러한 mode word를 set-user-Id, set-group-id라고 한다. 
  • 예를들어 슈퍼유저권한의 파일이라 하더라도, set-user-id 비트가 셋팅되어있고 실행되어있디면 해당 프로세스는 슈퍼유저권한으로 그 파일을 사용할 수 있다.
4. File Permission 

3번에서 말햇던 파일의 권한은 파일구조체 st_mode에서 관리한다. 밑에 그림에서 각 st_mode의 마스크와 기능을 알아보자.

  • 위의 그림에서 볼수 있듯이 st_mode에는 세가지의 권한에 대해 명시하고 있다. user, group, other이 각 3비트씩을 가지고 있으며, 그 3비트는 읽기, 쓰기, 실행으로 나뉘어져있다. 이러한 파일 st_mode의 마스크는 프로세스가 가지고 있는 ID와 비교하여 개인소유자인지, 그룹소유자인지를 판별한 후, 권한에 부여된 행동에 접근할 수 있도록 제공한다.
  • 총 4개의 순서로 실행되는데, 1. 슈퍼유저인지 확인 2. 소유자확인 3. 그룹소유자확인 4. 다른사람(other)인지 확인 총 4가지 순서로 실행된다. 순서 도중 해당 확인과정과 일치하면 그 일치된 과정을 실행하고, 나머지는 수행하지 않는다. 
  • 파일만 소유권을 보는것이 아니다. 디렉토리 또한 소유권을 확인하게 되는데, 실질적으로 파일을 실행할때, 앞에 절대 경로가 붙게된다. 이러한 절대경로는 디렉토리가 들어가게되는데 , 이러한 디렉토리의 권한이 만족되지 않는다면 접근이 불가하다.
5.  Ownership of New files and Directory
  • 새로운 파일이나 디렉토리의 주인은 바로 프로세스의 effective user Id 로 할당된다.
  • 파일의 group ID는 posix1. 에서 두가지를 제공한다.
    • 디렉토리의 그룹아이디를 할당받는다.
    • 프로세스의 effective group Id를 할당받는다.
6. Access and faceessat function 

  • 파일에 real user ID와 real group ID로 테스트 하고 싶을때 사용한다. 
  • 실질적으로 real ID로 권한이 없어, 접근이 불가하지만 set-user-Id, set-group-Id가 설정되면 파일에 접근이 가능하다. 
  • Access 는 실질적인 절대경로로 접근하며, faccessat함수는 file descriptor와 연결된 오픈된 디렉토리의 상대주소로 접근이 가능한 함수이다. 
7. umask 
  • 프로세서나 터미널에서 파일을 만들때, 파일의 권한에 대해 지정할수 있는데, umask 함수를 통해 지정할 수 있다. 
  • 실질적으로 권한을 할당하기 보다는 , 권한을 배제하는 형태로 작성되어있다. umask(0) 모든 권한을 부여한다는 것으로 의미된다.
8. chmod, fchmod, and fchmodat 함수
   파일의 권한을 바꿀수 있는 함수
  • chmod 일반적으로 특정 지정한 파일의 권하을 바꾸는 함수이다.
  • fchmod 함수는 오픈한 파일디스크립터 파일의 권한을 바꾸는 함수이다.
  • fchmodat함수는 오픈한 파일디스크립터의 상대경로나, 절대경로로 제공하는 경우 사용되는 파일권한 제어자 함수이다.
  • 파일을 권한 제어자 함수는 총 사용자 , 그룹, 다른사용자 권한을 제어할수 잇으며, 특별히 sticky bit와 set-user-id, set-group-id 비트를 제어할 수 있다.
  • 하지만 특별히 sticky bit 와 set-group-id 비트를 자동적으로 제하는 경우가 잇는데, sticky bit는 일반 사용자가 사용하면, 시스템 성능에 영향을 미치기 때문에 막는다. 더불어 set-group-id 또한 해당 폴더의 그룹아이디를 상속받는 경우로 인해 해당 그룹아이디와 프로세스의 effetive group id와 달라지는 경우로 인해, set-group-id 제어를 자동적으로 막아버린다. 
9. 

2015년 11월 7일 토요일

head and first :factory Pattern


1. OOP의 5요소(SOLID)
  •  단일 책임의 원칙(Single Resposiblility principle )
    • 객체는 단 하나의 책임만 가지고 있어야한다.
    • 클래스의 단일책임
  • 리스코브 치환의 원칙
    • 특정 클래스의 속성의 변경없이 , 기반클래스의(부모클래스) 객체가 서브클래스(자식클래스)의 객체로 변환될 수 있어야한다. 
  • 인터페이스 분리의 원칙(Interface segregation principle)
    • 어떤 클래스가 다른클래스에 종속될때 최소한의 인터페이스로 사용하여야한다
    • 인터페이스의 단일책임
      • 클래스 상속관계의 인터페이스 분리
      • 객체 기능의 인터페이스 분리
  • 의존 역전의 원칙(Dependancy Inversion Principle)
    • 하위 모듈의 변경이 상위 모듈의 변경을 요구하는 위계관계를 끊는 의미역전 실질적으로 그렇지 않지만, 느슨한 결합을 일컫는 말  
  • 개방폐쇄의 원칙 (OCP)
    • 객체는 개방에는 열려있고 수정에는 닫혀있어야한다.


2. 추상 팩토리 패턴 
  • 팩토리: 객체생성을 담당하는 추상 클래스   
  • 관련된 객체 생성의 인터페이스를 제공하되, 생성되는 객체의 구체적인 클래스는 알 알 필요가 없다는 것이다.  

피자스토어에서 여러개의 피자를 구성하는 것을 예로 들어 설명한다.  [그림1]에서 볼 수 있듯이 피자가게에서는 다양한 피자(치즈피자 ,페퍼로니 피자)등을 만들수 있다.  

  • NaivePizzaStore 은 NaivePizza를 사용하게 되며, 전적으로 NaivePizza가 상속하는 자시클래스생성에 의존적이게 된다. 의존성은 NaivePizzaStore의 확장성과 수정을 요구하게 되는 상황에 이르게 된다. 
[그림1]  

[그림1]의 의존성을 낮추기 위해서는 , NaviePizzaStore에 하나의 클래스를 연관시켜 피자가게와 피자객체의 의존성을 낮출 수 있다. [그림2]에서 그 의존성 낮춘예로 수정할 수 있다.

  • 피자의 객체의 생성을 전적으로 simpleFactory에서 담당하게 만듦으로 pizzaStore의 클래스를 수정할 필요가 없어지며, simple에서 다양한 피자객체와 연관시킬수 있는 확장력을 얻었다. 
  • 하지만 피자스토어가 하나가 아니라면 두개의 다른 영역을 가지게 되는 피자가게가 하나 더 생기게 된다면, simple Factory가 복잡하게 구성되어진다.  
[그림2]

[그림2]의 다수의 피자가게에 피자 객체 확장 문제점을 [그림3]에서 해결한것이다. 피자가게가 피자객체를 사용한다는 의존관계를 역의존관계로 느슨하게 결합하도록 제공한다.

  • 왜 심플 팩토리는 안되는가?
    • 다수의 피자가게가 심플팩토리에서 확인과정을 거쳐야 하며(어떤 피자가게인지, 어떤 피자를 생성해 줘야 하는지) 생성될 수 있는 객첵조건을 다 만들어 줘야 하기 때문에,  심플팩토리는 무거워지며, 수정할 부분이 많아지게 된다. 
  • 심플팩토리를 왜 만들었는가?
    • 이제 다시 , 원점으로 돌아가서 심플팩토리를 왜 만들어 주었는가 생각해보자, 의존성 때문이었다라고 말한다면 , 그것이 정답이다. 그렇다면 피자 스토어를 상속하는 다른 다수의 피자스토어를 만들어보고, 피자객체를 상속하는 다수의 피자 객체를 어떻게 연관시켜야하는가? 이 의존성을 어떻게 하면 없앨수 있는가? 이렇게 나온것이 역의존관게이다.   
  • 어떻게 역 의존하게 만드는가?
    • 피자객체에서 팩토리 객체를(다른피자 객체 ) 파라미터나 레퍼런스로 받아, 그 객체를 이용하여 실행되는 피자 객체를 생성한다. 마치 피자 객체가 수행되는것 같지만 내부적으로 팩토리가 실행된다.
    • ex) new CheesePizza(Factoty fac){ fac.createCheese()} 이 코드와 같이 실질적으로 cheesePizza의 객체가 실행되지만, 실질적 내부는 팩토리 함수가 실행된다. 이와 같은 방식을 의존성 역전이 되었다고한다

[그림3]

  • 의존성 역전의 장점은 무엇인가?
    • 피자 객체를 수정할 필요없이, 팩토리에 수정과 추가로 확장이 가능하며, 다양한 피자의 조합을 피자가게에 적용할 수 있게 된다. 
3. 팩토리 패턴의 장점 및 단점

  • 생성할 클래스가 변하면, 메서드 ,인터페이스 전체를 바꾸어야한다.
  • 다수의 클래스, 상황에 맞는 클래스 생성 시 적합하다.
  • 객체 생성을 위한 인스턴스를 생성하지 않아도 된다. 



* 참고 및 출처
 - http://warmz.tistory.com/entry/Abstract-Factory-Pattern-%EC%B6%94%EC%83%81-%ED%8C%A9%ED%86%A0%EB%A6%AC-%ED%8C%A8%ED%84%B4

2015년 11월 2일 월요일

hardware communication(I2C, SPI, UART)

1. I2C, SPI, UART 차이

  • I2C 
    • 1: 다 통신
    • 반이중통신 (Master, slave)
    • 표준 100kbps 고속 400kbp SPI에 비해서는 한참 느린 수준
  • SPI
    • 1: 다 통신
    • 반이중 통신 (Master, slave)
    • 셋중에서 가장 빠른 속도를 가지며 mbps까지 가능하다.
  • UART 
    • 1:1 통신
    • 양방향 통신 
    • 셋 중에서 가장 느리며 최고 kbps가 한계이다.
2. 각 하드웨어  통신 특징 및 개념  
  • UART (Universal Asychronous Receiver Transmitter)

    • Serial 통신이라고 불린다. 
    • RX, Tx 두개의 핀으로 서로 통신한다.
    • 시리얼통신을 셋팅시에는 BITS RATE와 PARIT BIT를 설정하게 되는데, 시리얼통신 시에는 데이터를 동기화할 CLOCK이 없다. 그래서 이 동기를 수행해줄 역할이 바로 BITS RATE가 수행을 하게된다. 각 영역을 BITS RATE로 나누어 해당 데이터를 인식한다. 가끔 ARDUINO 시리얼 모니터에서 SETUP()과 다른 BIT RATE로 설정하게 되면 글씨가 깨지게 되는데, 이 이유는 잘 못된 주기로 데이터를 인식하기 때문이다. 두번째는 PARIT BIT인데 패리트 비트는 해당 데이터가 제대로 전송되었는지에 대한 오류 검출 코드이다. 1의 발생갯수가 홀수인가 짝수인가를 체크하여 홀수개이면 그 해당 데이터는 에러인지 아닌지를 검출하게 된다. 
    • 위에서 보이는 데이터 패킷의 형태는 START는 데이터의 시작을 알리는 신호이며 STOP 데이터 종결이자 패리트 비트가 위치하는 영역이다. 
          PS. 실질적으로 양방향통신임에도 UART가 빠르지 않은 이유는 , 동시에 전송과 송             신을 할경우 시그널 왜곡현상이 일어나게 되기때문에 고속으로 보내지 못한다.

  • I2C



    •  기본적으로  I2C는 SCL(clock) 과 SDA(Data)의 두개의 핀을 가지고 있다.
    •  마스터가 SCL을 생성하며 동기형 클럭은 오직 마스터가 권장한다.
    •  SDA는 슬레이브에서 마스터로 갈수도 마스터에서 슬레이브 모두 가능한 양방향 신호선이다.
    • 하나의 마스터에 다수의 슬레이브가 붙을 수 있는 구조이며, 클럭신호를 통해 패킷만을 처리한다. 



    • I2C 패킷 시작과 끝
      • I2C 프로토콜에서는 SDA와 SCL이 모두 1인 상태에서 SDA가 0이 되면서 시작을 알린다.
      • SCL이 0이면 SDA가 바뀌는 상태이며 SCL 1이면 data는 stable한 상태로 인식되어 읽히게된다.
      • SCL이 1인상태에서 SDA가 0이되면 패킷의 종료를 알리게 된다.




    •  I2C 패킷 형태
      • 마스터가 보내온 클럭신호에 따라 각 비트를 읽게 된다.
      • 여기 ACK란 데이터를 수신한 쪽에서 데이터를 잘 수신했다는 의미로 보내주는 시그널이다.
      • 예를들어 마스터에서 특정 슬레이브로 신호를 SCL 1번부터 8번까지 보냈다고 한다면 수신받은 슬레이브 SCL 9번에 위치해있는 ACK신호를 보내게되어 다음바이트 전송할지를 정할 수 있다.


    • 주소지정 형식
      • 각기 슬레이브는 고유주소를 가지게 되는데, Master는 특정 통신하고 싶은 슬레이브 고유주소를 먼저 보내어 통신하게 된다. 이때 버스에 연결되어있는 slave는 자기 주소와 동일한지 검사하여 ack신호에 응답한다.
      • R/w 신호는 각 현재 마스터가 슬레이브를 read할 것인지 write할것인지를 알려주는 신호이다. 
      • ack신호가 잘 들어오게 되면 보내고 싶은 데이터가 stop state가 될때까지 보내지게 된다.  






2015년 11월 1일 일요일

Head and First Jsp chapter 3: mini Mvc tutorial

1. MVC 패턴이 실행 되는 순서



  • (1). 브라우저가 컨테이너에서 request 메세지를 보낸다. 
  • (2). 컨테이너에서 view 페이지를 가져온다.
  • (3). 컨테이너가 view페이지를 클라이언트에게 리턴한다.



  • (4) 브라우저가 컨테이너가에게 request 메세지를 보낸다.
  • (5) 컨테이너는 서블릿에 맵핑되어있는 url을 찾아 request를 서블릿에게 보낸다.
  • (6) 서블릿은 해당 request에 해당되는 model을 실행시킨다.
  • (7) model 반환된 값을 request object에 넣는다. 
  • (8) 서블릿은 request를 jsp로 forward시킨다.
  • (9) jsp가 request object로부터 정보를 얻어온다.
  • (10) jsp 가 page를 생성하여 컨테이너에게 반환한다.
  • (11) 컨테이너가 최종적으로 클라이언트에게 해당 페이지를 반환한다.
More..... 여기서 request object는 동일한 객체이며 재사용된다.


2. user Project 구조





3. 톰켓(컨테이너) project 구조


More . 왜 view 파일(.jsp)은 컴파일 없이 바로 적용되어 질 수 있는가?

  • jsp가 인터프린트드 언어이기 때문에, 미리 컴파일 할 필요가 없다.
  • 인터프린트드 언어는 한줄 코드를 실시간으로 기계어로 번역하여 로드하기 때문에, 컴파일러 언어처럼 미리 컴파일 할 필요가없다.
  • 하지만 인터프린트드 언어는 기존 기계어가 아닌 실시간으로 번역을 하기때문에 컴파일러 언어에 비해 속도가 느리다는 단점이 존재한다.
  • 그렇기 때문에 model같은 경우는 컴파일러 언어인 java로 구현이 되어있으며, 동적으로 구성되는 페이지의 경우에는 인터프린트드 언어이자 스크립트 언어인 jsp로 구현되어있다는 점을 기억해야된다. 


2015년 10월 28일 수요일

Decorator Pattern

  •  Decorator Pattern ?
    • 한 객체를 여러개의 데코레이터로 감싸는 패턴을 데코레이터 패턴이라고 한다.
  •  why Decorator Patterm
    • oop의 특징 중 확장에는 열려있고 수정에는 닫혀있어야 한다는 원칙을 지키기 위한 패턴으로 등장.
    • 확장성을 증대시킬수록 다수의 서브 클래스가 존재하게 되었으며 , 클래스를 줄이게 되면 클래스의 수정이 빈번하게 일어나게 된다.

  • 데코레이션 패턴 형식 의 예

    • 다크로스트에 휘핑과 모카를 추가하여 금액을 청구하는 로직을 구현하는 예를 든다.
      • 가장 바깥쪽에 있는 데코레이터 whip의 cost() 호출한다.
      • whip에서는 가장자리 mocha의 cost()를 호출한다.
      • Mocha에서 다시 DarkRoast의 cost()를 호출한다.
      • DarkRoast에서는 가격을 반환한다.
      • Mocha에서는 DarkRoast의 리턴값과 모카값을 더해 반환한다.
      • whip에서는 mocha에서 받은 가격에 whip가격을 더해 최종가격을 반환.

    • 구현 클래스다이어그램
  • 데코레이터 패턴의 단점
    • 잡다한 클래스가 늘어나게 되어 가독성이 나쁘게 된다. 
    • 상속을 통해 확장성이 가능하지만 디자인 유연성 면에서 좋지 않다.
      • 데코레이션을 하나의 클래스에 데코레이션을 감싸는 형태이기 때문에 어떤 클래스로 감싸는 지를 명시해 주어야 한다는 것이다. 다른 형태로 감싸거나 조율함에 있어 유연성이 적다


참고 블로그 :