ORM - (Object Relational Mapping)

관계형 데이터 베이스(이하 RDBMS)과 객체지향 프로그래밍 언어간 데이터를 자동으로 매핑하는기술로 객체지향 프로그래밍은 클래스, RDBMS는 테이블을 사용하기에 객체 모델과 관계형 모델간 불일치가 존재한다.

이를 해결하는것이 ORM으로 객체간 관계를 바탕으로 SQL을 자동으로 생성하여 상호간 불일치를 해결한다.

생성한 객체를 통해 간접적으로 DB데이터를 다룬다 Persistant API라고도 한다. (JPA, Hibernate 등..) -> 쉽게 말해 DB데이터 <ㅡ 매핑 ㅡ> Object필드는 서로 다른 방식을 사용하는데 이를 중간에서 해석해주는 통역사이다 

 

 

ORM의 특징

  • Granularity (세분성) - 경우에 따라 DB에 있는 테이블보다 더 많은 클래스를 가진 객체모델을가질수 있다.
  • Ingeritance (상속) - RDBMS는 상속을 지원하지 않는다
  • Identity (일치) - RDBMS는 sameness라는 개념을 정의하는데 이것은 java가 객체 식별(a==b)와 객체동일성 (a.equales(b))모두를 정의하는데 반해 RDBMS는 PK만 같으면 동일한 레코드로 인식한다.
  • Associations (연관성) - 객체 참조 (reference)를 사용하지만 RDBMS는 연관성을 외래키(FK)로 나타낸다.
  • Navigation (탐색 및 순회) - Java는 1개의 열결에서 다른연결로 이동하며 탐색을 진행하지만 RDMBS는 SQL 쿼리의 수를 최소화하고 Join을 통해 여러 엔티티중 원하는 대상만 선택한다 (select user from...)
  • Persistence (영속성) - 데이터를 생성한 프로그램이 종료되도 사라지지 않는 데이터의 특성 (비휘발성)

 

장점

객체 지향적 코드로 인해 비즈니스 로직에 완성도, 가독성이 높아진다.

  • ORM을 사용하면 SQL 쿼리(select * from...)를 선언,할당,종료 직관적인 코드(메서드)로 코드의 생략이 가능하다 (Connection.PerpareStatment.close() 등... 생략가능) -> 이것은 SQL의 절차적이며 순차적 접근이 아닌 객체 지향적 접근으로 생산성이 증가

재사용 및 유지보수가 좋아진다.

  • ORM은 SQL 쿼리에 종속받지 않고 독립적으로 작성되었으며(내 맘대로 메서드를 만들수 있으며) 해당 객체는 재활용이 가능하다 (import만 찍고 참조해서 사용하면 된다) -> 이를 활용해 각 모델에서 가공된 데이터를 MVC패턴을 적용해 더 나은 디자인 패턴을 만드는데 일조한다.
  • 매핑정보가 명확하여 객체 관계모델(ERD)에 대한 의존도를 낮출수 있다.

DBMS에 대한 종속성이 줄어든다.

  • 객체간 관계를 기반으로 SQL을 자동으로 생성하기에 RDMBS의 데이터 구조와 객체지향모델 사이의 괴리를 줄일수 있다.
  • ORM은 DB에 종속적이지 않다.

 

단점

ORM만으로 서비스 구현은 어렵다

  • 사용은 편하지만 설계가 신중해야하며 복잡할수록 난이도도 올라간다. 잘못 구현될경우 버그 찾기 어렵다
  • 자주 사용되는 대형 쿼리는 속도를 위해 저장 프로시저(SP)를 쓰는등 별도의 튜닝이 필요한 경우가 있다.
  • DBMS의 고유 기능을 사용하기 어렵다.

프로시저가 많은 시스템에선 ORM의 객체지향적인 장점을 활용하기 어렵다.

  • 프로시저(함수)가 많은 시스템에선 객체로 바꿔야하며 이 과정에서 생산성저하, 리스크가 발생할 우려가 있다.

프로시저 - 프로세스를 절차적으로 기술해놓것 (함수)
(SP를 사용할경우 결과가 캐시(메모리)에 저장되기에 추후 SP를 시행할경우 캐시에 있는걸 가져오기만 하면 되기 때문에 속도가 더 빨라진다)

//프로시저 예시
CREATE OR REPLACE PROCEDURE 프로시저 이름
     ( 매개변수명1 [ IN || OUT || INOUT ] 데이터타입,
       매개변수명2 [ IN || OUT || INOUT ] 데이터타입 ... )
IS||AS
       변수, 상수 등 선언 ( 선언부 )
BEGIN
       실행 문장 ( 실행부 )
       EXCEPTION 문장   //필수아님
END ;

HTTP요청이 생기면 브라우저는 이에대한 HTTP 요청메세지를 생성, TCP/IP 프로토콜을 활용해 웹서버에 요청한뒤 브라우저는 웹 서버로부터 HTTP 응답을 받는다. (전송계층 프로토콜 - TCP, 네트워크 계층 프로토콜 - IP)

그리고 이것에 대한 간단한 머릿글의 형태로 받는것이 헤더이다. (헤더인증, 캐싱, 쿠키, 보안등 다양한 종류가 있다)

여담으로 TCP/IP의 경우 인증, 보안부분에서 취약하고 한다 (암호화가 된경우 암호화의 의미는 몰라도 암호화된 메세지 자체는 엿볼수 있으며 이를 막기위한 방법이 SSL,TLS이다)

 

HTTP(Hyper Text Transfer Protocol)

HTML문서와 리소스를 가져올수 있도록 하는 프로토콜로 웹 브라우저와 웹 서버간 통신을 목적으로 만들어졌다. (HTTP헤더는 대소문자를 구분하지 않는 이름과 콜론(:) 다음에 오는 값(줄 바꿈 없이) 이뤄져있으며 값 앞에 붙은 빈 문자열은 무시된다.

 

헤더(header)

  • 주로 데이터가 저장되거나 전송되는 데이터 블록의 맨 앞에 위치한 보충 데이터 (머릿글, 제목, 서론같은 개념이며 헤더 뒤에 이어지는 데이터는 페이로드 또는 바디라 불린다.)
  • 데이터 블록은 하단과 같으며 헤더는 데이터 블록 최상단에 위치하고있다. (우리가 사용하는 통신의 바디값은 데이터 계층에 존재하며 특정 프로토콜의 헤더 내용은 특정 프로토콜의 기능을 제공하기 위한 정보를 담고있다.)
  • HTTP헤더는 HTTP메세지(요청/응답)와 본문에 대한 정보를 말해주는데 해당 메세지가 제공하는 기능에 대한 최소한의 정보가 정리되는 요약본이다. (쉽게말해 머릿글 같은것) -> 만일 불필요한 내용을 담을경우 데이터 크기가 커져 빠른 전송이 불가능하기에 꼭 필요한 내용만 담는다.
  • 평문(암호화를 하지 않은) 통신이기에 도청이 가능하며 통신 상대방을 확인하지 않아 위장이가능하다. (TCP/IP자체가 통신 경로의 도중에 엿볼수 있다는 단점이 있다)


 

헤더의 분류

프록시 처리 방법에 따른 분류 

  • 요청 속도를 올리기 위하여 중간에 대체자(Proxy)를 두고 캐시하여 사용하는 방법이다
  • 종단간 헤더 (end-to-end) - 메세지의 최종 수신자에게 전송되어야 하며 중간 프록시는 반드시 종단간 헤더 원상태를 재전송하며 캐시는 이를 저장해야한다. 
  • 홉간 헤더 (hop-by-hop) - 단일 전송 - 레벨 연결에서만 의미있으며 프록시에 의해 재전송,캐시가 되어선 안된다.

헤더는 크게 4가지로 나눌수 있다. (개발자 도구를 키면서 보기를 권장한다..)

1. General header: 요청과 응답 모두에 적용되지만 바디에서 최종적으로 전송되는 데이터와는 관련이 없는 헤더.

  • Data(헤더 생성시점), Connection등 일반적인 정보가 포함된다. 
  • Connection : 클라이언트와 서버의 연결방식(전송 후 네트워크 연결 유지여부)을 설정하는것이며 Http/1.1은 keep-alive(연결유지)가 디폴트이다 (프록시에 더이상 전송되지 않는 헤드필더(hop-by-hop)를 지정)

2. Request header (응답 헤더): 패치될 리소스나 클라이언트 자체에 대한 자세한 정보를 포함하는 헤더.

  • 웹브라우저가 서버에 요청하는것을 텍스트로 변환한 메세지
  • 응답에 대한 부가정보 및 콘텐츠에 대한 우선순위등 (Authorization이 여기 포함)

3. Response header (요청 헤더): 클라이언트 위치 또는 서버 자체에 대한 정보(이름, 버전 등)와 같이 응답에 대한 부가적인 정보를 갖는 헤더.

  • 웹브라우저가 요청한 메세지에 대한 status 메세지

4. Entity header : 콘텐츠 길이나 MIME 타입과 같이 엔티티 바디에 대한 자세한 정보를 포함하는 헤더.

  • 엔티티 바디 정보로 실제로 주고받는 컨텐츠 타입 또는 길이 같은 메세지 바디에 들어가는 내용에 관한 헤더가 들어가는 헤더
  • Content-Encoding - 미디어 타입을 압축하기 위해 사용되며 이것을 통해 클라이언트는 본문의 압축방식을 알수있다.
  • 미디어 타입 (MIME Type(구), media type) - 파일의 형식을 나타내는 문자열로 파일과 같이 송신될때 Content의 형식을 나타내기 위하여 사용 (Audio/ogg는 오디오파일로, image/png는 그림파일로 분류하며 특정한 타입이 없는 바이너리 타입은 application/..으로 나타난다)


HTTP 헤더의 특성

1. 비연결성(connectionless) 

  • 클라이언트와 서버가 연결을 맺은후 응답이 끝나면 기존의 연결을 끊는것 (단발적인 연결)
  • HTTP가 계속 연결되면 서버는 다수의 클라이언트(유저)와 연결을 유지해야하며 이에 따른 리소스가 발생하는데 이를 단발성으로 바꾸고 리소스를 줄여 더 많은 연결을 추구한다.
  • 서버에선 반복되는 요청에도 매번 연결, 해제의 과정을 수행해야 하므로 오버헤드가 발생할 여지가 있다.
  • 오버헤드를 줄이기 위해 HTTP의 KeepAlive(연결유지)속성을 사용해 주기적으로 패킷을 보내는 방식을 채택하였다(만일 반응이 없을경우 접속을 끊는다.)
  • 콘서트 티켓팅을 한다고 했을때 서버측은 실시간으로 예약, 예약취소가 이뤄지나 접속한 유저의 웹사이트에선 예약이 가능하다는 차이점이 발생한다. (공석이라고 나오지만 클릭하면 예약석이라고 나타나는점)

패킷 - 패킷교환 네트워크에 의해 전달되는 형식화된 데이터단위

 

2. 무상태성(stateless) 

  • 비연결성으로 인해 이전에 어떠한 상태를 갖고있는지 알수 없는데 로그인을 했지만 다른 페이지로 이동했을때 로그인을 했는지 안했는지 알지 못해 재로그인을 요청할수 있다 즉, 매번 새로운 인증을 진행해야하는 단점이 생긴다.(접속 -> 로그인 -> 상품클릭 -> 로그인 -> 주문 -> 로그인...)
  • 서버가 클라이언트의 상태를 보존하지 않는것으로 서버의 확정성은 용이하나 클라이언트가 추가적인 데이터를 전송해야하는 단점이 있다.  (상태유지 - 요청을 받은 서버가 기억하고 있는것으로 여기선 로그인을 유지하지 않는다고 이해하면 된다.)
  • 로그인이 필요 없는경우 상관없으나 로그인이 필요한경우 쿠키, 세션,토큰을 이용해 상태를 유지하며 이러한 상태 유지는 최소한으로만 사용한다.
  • 쿠키와 (브라우저 저장), 세션(DB 저장), 토큰의 등장으로 비연결성, 무상태성이 보완되기 시작

쿠키 - 서비스를 운영하려면 서버가 클라이언트를 기억해야하는 경우가 많은데 쿠키라는것을 저장하여 서버가 클라이언트를 식별하도록 한다 (사용자의 정보가 브라우저에 저장되기에 위변조 가능성이 높다)

세션 - 쿠키의 위변조 가능성을 방지하기 위해 나타난것으로 서버에 사용자 정보를 저장하는것

구분 HTTP 요청 메세지 HTTP 응답 메시지
Startline 메서드, 경로, 프로토콜의 버전 프로토콜의 버전, 상태 코드, 상태 텍스트
헤더 요청한 HTTP의 헤더 응답에 설정한 HTTP 헤더
바디 HTTP요청이 POST인 경우에 한정해서 추가됨 요청에 대한 응답(201,204는 공란)

상태 텍스트 - HTTP/1.1 404 Not found

상태 코드 (Status-code) - 404

 

HTTP코드의 종류

  • 1xx(정보) - 요청을 받았으며 기존 프로세스를 계속 진행합니다.
  • 2xx(성공) - 요청을 성공적으로 받았으며 정상확인 및 수용하였습니다.
  • 3xx(리다이렉션) - 요청 완료를 위해선 추가적인 작업이 필요합니다.
  • 4xx(클라이언트 오류) - 요청의 문법이 잘못되거나 요청처리가 불가합니다.
  • 5xx(서버 오류) - 서버가 명백히 유효한 요청에 대해 충족을 실패했습니다

HTTP메서드 종류

  • GET (멱등성 보장)
    • 데이터(Read)를 읽거나 검색(Retrieve)할때 사용되는 메서드
    • 성공시 XML 또는 JSON과 200코드리턴, 에러 발생시 404,400에러 발생
    • HTML GET요청시 모든 필요한 데이터를 URL 주소 끝에 파라미터로 포함해서 요청하며 이 끝부분을 쿼리스트링(QueryString) 이라고 한다.
    • 오직 데이터를 읽어올때만 사용하기에 idempotent이 보장된다 (계속 조회해도 리소스 변동 없음)
  • POST
    • 새로운 리소스를 생성(Create)할때 사용되며 주로 하위 리소스를 생성할때 사용하며 추가 리소스를 생성한다는 점에서 안전하지도, idempotent하지도 않다 -> 덮어쓰기라고 생각하면 된다.
    • 성공시 주로 201코드(게시물 작성, 회원 가입 등 신규 데이터를 서버에 덮어쓰는 작업이 성공시)
    • 전송해야할 데이터를 HTTP 메세지 Body에 담아 전송하며 브라우저 기록에 남지 않는다 (캐시 및 북마크 불가)
    • HTML POST 요청시 추가적인 데이터를 body에 포함해서 요청할수 있다.
  • DELETE (멱등성 보장)
    • 서버에서 요청한 URL리소스를 삭제하도록 요청 (클라이언트는 항상 삭제한다고 생각하지만 요청을 무시할수도 있다)
    • 동일한 요청을 하여도(이미 삭제된걸 요청해도) 삭제된 결과는 동일하다.
  • PUT (멱등성 보장)
    • 결과를 대체하기에 동일한 요청을 하여도 최종결과는 같다
  • OPTIONS (preflight)
    • 브라우저가 서버에게 지원하는 옵션을 요청 및 허가된 요청에 한해서 전송하기 위한 보안상의 목적 (조건부)
    • 통신옵션을 확인할때 사용되며 어떤 Method, header, content type을 지원하는지 알수있다. (Content type이 표준이 아닐경우 Option을 넣는것)

멱등성 - 자동복구 매커니즘으로 "서버가 타임아웃으로 정상적인 응답을 못줬을때 클라이언트가 동일한 요청을 다시해도 되는지"에 대한 근거

타임아웃 - 일정 시간내에 완료하지 못한경우 발생하도록 설계 (1분간 접속 안될경우 에러가 나타나는것)

GET과 POST 비교

  GET - URL에 값이 저장됨, 가져오기 POST - URL에 값이 저장되지 않음, 덮어쓰기
History
(기록)
브라우저 히스토리 저장
(파라미터가 URL의 일부분)
파라미터는 브라우저 히스토리에 저장 X
Bookmarked
(즐겨찾기)
즐겨찾기 가능
(요청한 파라미터 자체가 URL로 인코딩)
즐겨찾기 불가
요청 파라미터에 request URL이 나타나지 않음
button/re-submit
behaviour
(재클릭, 재 제출)
브라우저 캐시에 HTML이 저장되어있다면
서버에 submit되지 않는다.
브라우저가 보통 사용자에게 데이터가 다시
submit되어야 한다고 alert을 준다.
Encoding type
(enctype attribute)
(인코딩 방식)
ASCII characters만 허용 제한없음
Parameters
(매개 변수)
전송 가능하지만 URL에 넣을 수 있는 파라미터 데이터가 제한된다. 통상적으로 2K 서버에 파일 업로드하는 것을 포함하여 파라미터를 전송할 수 있다.
Security
(보안성)
상대적 약세
(데이터가 URL의 일부로 전송 및 브라우저 히스토리에 저장,서버에 플레인 텍스트로 로그 존재)
상대적 우세
(파라미터들이 브라우저 히스토리나 서버 로그에 저장되지 않기때문)
Usability
(유용성)
URL에 전부 보이기 때문에 비밀번호등 민감한 정보들을 전송에 사용이 금지 숨겨지기 때문에 비밀번호와 같은 민감한 정보를 전송하는데 사용된다.
Visibility
(가시성)
GET 메소드는 모두에게 보여진다. (브라우저 주소창에 보여지고 전송가능한 크기도 제한된다.) POST 메소드는 URL에 보여지지 않는다.
(Body에서 보인다)
Cached
(캐시)
idempotent하기 때문에 캐시 O
(같은 요청을 여보내도 항상 같은 응답이 온다.)
idempotent하지 않아 캐시 X
(같은 요청을 여러 번 보내도 다른 응답이 올 수 있다.)

전체 메서드 비교 

'CS' 카테고리의 다른 글

크로스 도메인,SOP, CORS, XSS,  (0) 2024.01.25
IP, DNS, HTTP  (0) 2023.07.09
난독화  (0) 2023.05.03
개발방법론  (0) 2023.05.02
인라이닝  (0) 2023.04.20

소스코드를 인터넷에 올리거나 고객에서 납품할때 프로그램 전반이 단순한 텍스트(코드)로 되어있기에 코드만 긁어가면 똑같은 서비스를 그대로 출시하거나 상업적 목적에 사용될 우려가 있다.

이러한 문제를 해결하기 위해 크게 3가지 기법(난독화, 바이너리 암호화, 패킹)이 있는데 해당 포스팅에선 주로 난독화에 대해 다루려고 한다.

바이너리 암호화

소스코드를 난독화 하는게 아닌 디컴파일 자체가 어렵도록 바이너리 자체를 암호화 하는것으로 복호화 없이는 실행될수 없는 파일이다.

복호화(디코딩)를 하기 위해선 별도의 실행프로그램이 존재해야하는데 이 프로그램을 로더라고 한다.

 

패킹 (Packing)

실행파일을 암호화하거나 압축하여 소스코드를 볼수 없도록 하는것 (패킹을 진행하는 프로그램을 패커라 칭한다)


난독화

프로그램을 변화하는 방법의 일종으로 코드를 읽기 어렵게 만들어 역공학을 통한 코드탈취를 막는기술이다.

JWT토큰, Base64, Cyberchef등이 이에 해당하는것이라 볼수있다.

  • 바이너리에서 심볼 정보를 제거하거나 변경하는것
  • 필요 이상으로 복잡한 코드 및 아무 의미도 없는 코드의 삽입
  • 각 함수를 인라이닝 및 반복되는 구문을 합쳐 익명함수를 만듬
  • 인코딩

장점

  • 난독화기는 난독화를 진행하면서 불필요한 코드를 찾아 제거하여 코드의 최적화를 만들어준다.
  • 리버스 엔지니어링을 어렵게 해주는것인데 이것은 오픈소스 플랫폼에서 코드탈취를 막아줄수 있다

단점

  • 난독화된 코드의 복잡성에 따라 코드를 해석하는데 긴 시간이 든다.
  • 난독화는 그저 해석이 어렵게 할뿐 시간만 주면 해석 못할건 아니다
  • 일부 백신 프로그램은 사이트에 난독화 코드가 있는경우 이것을 바이러스 사이트로 인지한다

코드 난독화의 종류

이름변경 난독화

  • 변수의 이름을 바꿔 기존 의도에 혼란을 주는것

데이터 난독화

  • 집계 난독화 - 프로그램에 데이터가 저장되는 방식을 변경 (부모배열을 자식배열로 분할, 이를 프로그램 다른위치에 참조되도록 하는것
  • 저장 난독화 - 데이터가 메모리에 저장되는 방식을 변경으로 로컬 저장소 및 전역 저장소 사이에 변동을 주는것
  • 순서 난독화 - 프로그램, 코드스니펫의 동작의 변경없이 데이터의 순서를 변경
  • 문자열 암호화 - 읽을수 있는 문자열을 모두 암호화하여 읽을수 없는 코드를 생성 (프로그램이 실행되는 런타임시점에 암호해독이 필요하다)
  • 제어/코드 흐름 난독화 - 제어가 코드베이스의 한 섹션에서 다른 섹션으로 전달되는 방법은 프로그램 의도를 결정하는데 중요한 역할을하는데 이 사이에 사용되지 않을 불필요한 구문(데드코드)를 추가하는것

코드스니펫 (Code Snippet) - 코드조각, 재사용 가능한 소스코드를 가리키며 코드의 일부를 복붙할때 사용하기도 한다

디버그 난독화

  • 디버그 정보는 프로그램 흐름, 디컴파일, 재컴파일을 통해 프로그램의 결함 또는 핵심 정보를 아는데 사용되는데 이를 기반으로 코드의 탈취우려가 있다.
  • 디버그 정보에 대한 엑세스 중지하여 식별 가능한 정보의 제공을 일절 차단하는것

주소 난독화

  • 변환된 코드가 실행될때마다 코드의 가상주소와 프로그램의 데이터가 랜덤화가 진행
  • 리버스 엔지니어링 과정이 어려워지며 동시에 메모리 오류 취약점을 이용한 공격효과를 장담할수 없도록 만듦
  • 비 메모리 안전 언어(C,C+)를 사용하는경우 엑세스 오류같은 보안 취약성이 발생하는데  메모리 프로그래밍 오류를 이용하는경우

JavaScript 난독화

  • HTML의 난독화는 주로 HTML보단 JavaScript 위주로 변환된다 -> HTML을 해당 숫자코드로 변환, 복수의 메서드를 조합하여 수행 하는게 통상적 이지만 주로 서버측 보안 위주로 이뤄지기에 HFO (HTML Field Obfuscation) 는 생략되는경우가 많다
  • 주로 컴파일전 원본 소스코드 자체를 난독화하는 방식이 사용된다.
  • 문자열 배열 인코딩, 유니코드 표현식으로 변환, 이스케이프 시퀀스에 유니코드 작업을 수행하는 등 작업을 진행
  • 런타임 속도가 느려짐

이스케이프 스퀀스 (escape sequence) - 프로그래밍 언어 특성상 표현불가능한 기능, 문자를 표현해주는것 (제어 시퀀스, 확장 비트열, 이스케이프 문자라고도 한다 - \n, \\, \"...)

Java 난독화

  • Proguard, Dexguard - 자바 난독화 라이브러리
  • 상용프로그램은 배포전 난독화를 한번 진행하고 배포를한다.
  • 자바는 바이트코드로, 안드로이드는 dex로, 닷넷은 DLL로 컴파일하여 난독화 

'CS' 카테고리의 다른 글

IP, DNS, HTTP  (0) 2023.07.09
HTTP 헤더  (0) 2023.05.06
개발방법론  (0) 2023.05.02
인라이닝  (0) 2023.04.20
메모리 단편화  (0) 2023.04.08

TDD(Test-Driven-Development)

테스트 주도개발

장점

  • 개발할때 주기적으로 테스트를 진행하며 개발하는 방식
  • 실패해도 문제 없도록 테스트 케이스를 먼저 작성후 개발을 진행 (일단 실행만 되게 만들고 나중에 깔끔하게 고침)
  • 주기적인 테스트로 인해 코드의 문제를 금방 알수있고 객체지향적이며 이를 토대로 확장에 용이하다

단점

  • 테스트 코드를 넣음으로써 작성해야하는 코드량이 늘어기에 빠르게 생산이 필요한경우엔 기피된다. 
  • 모든 상황에 대해 테스트 코드를 작성해야 한다. (물건 장바구니에 넣었다 뺐다 10번 한뒤 테스트..)

 

 

BDD(Behavior-Driven-Development)

행동 주도 개발

  • 요구사항에 집중하여 테스트를 개발 (TDD + 시나리오)
  • TDD에 시나리오(가상의 사건) 개념을 더한것을 행동이라 칭하고 이를 기반으로 개발하는 방식 (테스트보단 비즈니스 요구사항에 집중하여 테스트 케이스를 개발)
  • 메서드 이름을 "어떤 행위를 해야한다"라는 식의 문자로 작성해 행위(기능)를 위한 테스트에 집중
  • Buisiness Requires과 end-user(최종 소비자) 관점에서개발을 진행하는 방식
  • TDD가 테스트를 각 기능에 대해서만 테스트헀다면 BDD는 결합테스트 + 시나리오 테스트까지 확장하여 테스트 케이스를 진행하는것 (물건 3번쯤 장바구니에 넣고 뺏다가 홈화면 갔다온뒤 20분뒤 돌아와서 다시 구매할경우?...)

 

DDD(Domain-Driven-Development)

도메인 주도 개발

  • 도메인 패턴을 중심으로 설계하는 방식
  • 데이터 중심의 접근법이 아닌 순수 도메인의 모델과 로직에 집중
  • 커뮤니케이션에서 분석, 설계, 구현까지 통일된 방식으로 협업하며 규칙이 동일한 통일된 방식으로 진행

(도메인 - 분야. 집합, 비즈니스영역이나 여기선 사건이 발생하는 집합이라 생각하면 이해가 쉽다.)

 

  TDD DDD BDD
TDD - 사용자 중심 테스트 케이스 중심
DDD 사용자 중심 - 비즈니스 로직 중심
BDD 테스트 케이스 중심 비즈니스 로직 중심 -

 

'CS' 카테고리의 다른 글

HTTP 헤더  (0) 2023.05.06
난독화  (0) 2023.05.03
인라이닝  (0) 2023.04.20
메모리 단편화  (0) 2023.04.08
캐시에 대하여  (0) 2023.04.07

인라이닝(Inlingin)

함수 기반 메모리 조각화를 줄이는데 유용하며 인라이닝 함수를 사용할경우 코드길이가 커지나 흐름변화가 줄어들며 코드를 더 선형적(단순한) 방식이 되고 프로그램 속도가 더 빨라지는 장점이 있다

(인라인이 붙어있을경우 C++, 코틀린에선 호출,인라인 작업을 비교하고 더 빠른것을 사용한다고 한다)

 

//일반방식
void print(){
    printf("Hello, world!\n");
}

int main(){
    print();
    return 0;
}

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
//인라인 방식
inline void test1() {
	printf("hello");
}

int main() {
	test1(); //printf("hello");
    return 0;
}
  인라인 방식 일반적인 호출
1 main 시작 main 시작
2 printf실행 test1으로 이동
3 main 종료 스택프레임 적재
4   printf 실행
5   스택 포인터 원위치
6   main으로 복귀,종료
실행속도 상대적으로 빠름 상대적으로 느림
메모리 사용 상대적으로 큼 상대적으로 적음

'CS' 카테고리의 다른 글

난독화  (0) 2023.05.03
개발방법론  (0) 2023.05.02
메모리 단편화  (0) 2023.04.08
캐시에 대하여  (0) 2023.04.07
교착상태(Dead Lock)  (0) 2023.04.02

메모리 단편화 (Memory Fragmentation)

RAM에서 메모리 공간이 작은 조각으로 나눠져 사용 가능한 메모리가 충분히 존재하지만 할당(사용)이 불가능한 상태로 내부 단편화, 외부 단편화 2가지로 구분된다.

 

조각 모음 사진

 

내부 단편화

메모리 할당시 프로세스가 필요한 양보다 더 큰 메모리가 할당되어 메모리 공간이 낭비되는 현상 (메모리 과소비로 메모리 크기가 10KB인데 프로세스의 사이즈가 6KB인경우 4KB의 내부단편화가 발생했다 표현)

 

외부 단편화

메모리 할당, 해제를 반복할경우 중간마다 작은 메모리가 생성되는데 존재하여 총 공간은 충분하지만 실제로 할당은 불가능한 상황. (여유공간이 여러조각으로 나뉜 상황)

외부 단편화(여유 공간은 9K지만 7K가 들어갈곳이 없다 -> 테트리스할때 중간마다 구멍이 뚫린걸 생각하면 된다.)

 

프로세스가 차지하는 물리적 공간이 비연속적으로 허용되도록 하는 메모리 관리기법을 의미힌다.

외부단편화가 발생하지 않으며 별도의 compaction과정이 불필요하다


메모리 파편화 문제 해결방법

1. 페이지 기법 (Paging)

2. 세그멘테이션 기법 (Segmentation)

3. 메모리 풀(Memory Pool)

 

페이징

물리적 메모리를 고정된 크기의 프레임으로 나누고 논리적 메모리를 동일크기의 페이지로 나누는 것이다.

페이지 - 가상메모리를 같은 크기의 블록으로 나눈것

프레임 - RAM을 페이지와 같은 크기로 나눈것

 

미사용 프레임을 페이지로 옮기고 필요한 메모리를 페이지 단위로 프레임에 옮기는것

 

CPU에 의해 생성된 주소는 페이지 번호 및 페이지 간격으로 나뉘며 각 페이지 번호는 테이블의 인덱스로 사용된다.

페이지 테이블은 각 물리적 메모리의 페이지 Base주소를 저장하고 있다.

 

 

보조 기억장치를 이용한 가상 메모리를 동일한 크기의 블록으로 분할

비 연속적인 공간 활용이 가능하기에 외부 단편화 해결

각 객체별로 크기가 다른데 페이지의 크기는 일정하기에 내부 단편화 발생

 

세그멘테이션 기법

가상 메모리를 서로 크기가 다른 세그먼트로 분할하여 실제 메모리 주소(연속적인 공간)로 변환

세그먼트의 크기가 다르기에 미리 분할이 안되며 메모리에 적재될때 빈 공간을 찾아 할당

mapping을 위한 세그먼트 테이블이 필요(각 세그먼트별 시작주소 및 길이를 포함)

 

중간에 프로세스를 해제할경우 앞의 빈공간에 할당되는게 아닌 바로 뒤의 연속된 공간에 할당되기에 외부 단편화 발생 

크기가 다른 세그먼트로 분할되기에 적재될때 빈공간을 찾아 들어가기에 내부 단편화 해결

 

 

메모리풀

필요한 메모리 공간을 필요한 크기, 개수만큼 사용자가 지정해 미리 할당, 필요할때마다 사용하고 반납(미리 선점해놔 단편화가 발생하지 않는다)

메모리풀 없이 동적할당, 해제를 반복할경우 메모리의 랜덤위치에서 작업이 진행되어 단편화가 발생한다

 

장점 : 미리 공간을 할당, 사용후 반납하기에 단편화 문제 미발생

단점 : 미리 할당하기에 미사용 하더라도 계속 할당하기에 메모리 누수 발생

 

메모리 누수 - 할당됐던 메모리가 더 이상 사용되지 않는 시점에서도 반환되지 않는 현상

 

큰 메모리블록(페이지)를 힙에서 할당

각 페이지를 객체의 크기별 블록으로 분할

각 객체를 위한 블록을 순차적으로 링크

현 시점에서 할당한 블록을 특정 포인터가 가리킴

메모리 요청시 헤더 포인터가 가리키는 블록을 반환

할당이 일어난 후 헤더 포인터는 할당 직전에 가리키던 블록이 가리키던 블록을 가리킨다.사용되던 메모리가 해제되어 메모리 풀로 돌아올 경우 헤더 포인터는 그 블록을 가리키고 방금 전까지 헤더 포인터가 가리키던 블록을 돌아온 블록의 다음 포인터가 가리키게 한다.

 

 

'CS' 카테고리의 다른 글

개발방법론  (0) 2023.05.02
인라이닝  (0) 2023.04.20
캐시에 대하여  (0) 2023.04.07
교착상태(Dead Lock)  (0) 2023.04.02
시스템콜  (0) 2023.04.01

캐시(Cache)

캐시란 자주 사용하는 데이터나 값을 미리 복사해놓는 임시장소를 의미한다.

 

위로 갈수록 저장용량이 작고 빠르지만 비싸다

조금더 쉽게 설명하자면 가게에서 자주 나가는 조그만 사은품이 있을경우 창고에 보관하는게 아닌 금방 꺼내주기 쉬운 카운터 밑에다 거치해두는데 이것을 컴퓨터에 적용하면 다음과 같다.

 

자주 나가는(출력이 잦은) 조그만(작은크기의) 사은품(데이터)가 있을경우 창고(RAM)에 보관하는게 아닌 금방 꺼내주기 쉬운 카운터 밑(캐시메모리)에 뒀다가 전달해주는것이다. 

 

캐시의 저장방식

OS는 프로세스를 페이지 단위로 구분한다 -> 프로세스마다 자주 사용하는 부분이 있고 그렇지 않은 부분이 있기에 페이지로 나누는것

그리고 OS나 CPU는 자주 쓰이는 데이터를 메모리에서 캐시로 읽어온다.

메모리 계층 구조에서 초기에 디스크에 있는 값은 메모리 -> 캐시메모리 -> 레지스터까지 의 과정을 거치는데 이때 메모리를 지나가는 시점에 저장된다. (상단의 사진 참조)

여기서 자주 쓰이는 기준은 지역성으로 판단하며 지역성은 시간지역성, 공간지역성으로 나뉜다.

(프레임 - 물리주소공간이 일정한 크기로 균일하게 나눈것 / 페이지 - 논리주소공간이 일정한 크기로 균일하게 나눈것

 

시간지역성 (Temporal Locality) - 단시간에 계속 접근하는경우 (for, loop등으로 같은곳을 계속 참조 할경우)

공간지역성 (Spatial Locality) - 최근 접근한 데이터 주변공간에 재접근하는 경향 (연속된 배열) 

페이징 - 프로세스가 차지하는 물리적 메모리 공간이 비연속적으로 되도록 허용하는 메모리 관리기법

//공간지역성 코드 (else만 볼것)
(A)
if (test) {
	//......
}
else {
	//.....
}

(B)
if (test) {
	//......
}
else {
	call_function_test();
}

상단의 코드는 (A)와 (B)는 else에서 직접 코드를 작성했는지, 호출했는지의 차이가 있다.

최상단의 사진을 참조하면 L1에서 L3로 갈수록 저장할수 있는 용량이 커지는데 (A)의 경우 직접 코드를 썻기에 사용시 캐시 메모리가 기억할 크기가 크지만 (B)의경우 함수를 호출하는 방식이기에 캐시의 크기가 작아지며 이는 곧 공간지역성에서도 이점을 갖게된다.

 

캐시가 삭제되는 방식

캐시의 저장을 진행했으나 만일 캐시가 꽉찬경우 캐시교체 알고리즘이 실행되는데 FIFO, LFU, LRU 3가지가 가장 범용적이다.

1. FIFO - 가장 먼저(시간상 제일 마지막)에 들어간 데이터를 교체 -> 가장 간단하나 성능이 떨어진다.

2. LFU(Least Frequently Used) - 가장 사용량이 적은 데이터를 교체 -> 최근에 들어가 사용량이 적은 데이터의 삭제 우려

3. LRU(Least Recently Used) - 가장 오랫동안 사용되지 않은 데이터를 교체 -> 가장 고성능이나 사용시기를 기억해야 하기에 오버헤드가 크다.

 

캐시무효화

객체가 캐시된경우 객체가 기간만료 또는 삭제 알고리즘이 되기 전까진 메모리 한 구석에 존재하는데 만일 강제로 캐시를 삭제해야할경우는 어찌해야할까? (웹의경우 캐시의 만료시간은 HTTP 헤더에 의해 제어)

이때 진행하는것이 캐시 무효화이다.

 

캐시블록

캐시는 블록으로 구성되어 있으며 각 블록은 데이터를 갖고있고 주소값을 키로 활용한다.

각각의 캐시블록은 데이터를 담고있으며

캐시메모리는 캐시블록 + 캐시태그와 더불어 캐시엔트리를 구성한다.

캐시태그 - 캐시블록의 고유 식별값 주소값의 일부를 Tag로 사용한다. CPU를 통해 

 

캐시의 특징

1  L1,L2, L3로 나뉘며 가격이 비싸지만 전송속도가 빠르다.

2. 캐시에 데이터가 잇으면 Cache hit, 없으면 Cache miss라 표현한다.

3. 캐시의 성능을 측정할때 지연시간(Hit Latency, Miss Latency)을 요점으로 본다

  • Hit Latency - 현재 캐시계층에 존재하여 가져올때 소요되는 시간
  • Miss Latency - 현재 게층에 존재하지 않아 상위캐시에서 가져올때 소요되는 시간

 

L1 캐시 - 프로세서와 가장 가까운 캐시로 속도향상을 위해 L1캐시는 1$ D$로 이루어져있다.

  • Instruction Cache(I$): 메모리의 TEXT 영역 데이터를 다루는 캐시
  • Data Cache(D$): TEXT 영역을 제외한 모든 데이터를 다루는 캐시

L2 캐시 - 용량이 큰 캐시 (L1처럼 캐시를 나누지 않는다)

L3 캐시 - 멀티코어 시스템에서 여러 코어가 공유하는 캐시(공간)

'CS' 카테고리의 다른 글

인라이닝  (0) 2023.04.20
메모리 단편화  (0) 2023.04.08
교착상태(Dead Lock)  (0) 2023.04.02
시스템콜  (0) 2023.04.01
링킹과 오브젝트파일  (0) 2023.03.30

교통체증으로 출퇴근길이 막혀본적이 있는가 이런경우 중간에서 통제해주기 전까진 이도저도 못하는 상황이 발생하는데 

컴퓨터에선 이것을 어떻게 표현하고 조치하는지 알아보자

 

교착상태 (Dead Lock)

둘 이상의 프로세스가 다른 프로세스가 점유하고 있는 자원을 서로 기다릴때 무한 대기에 빠지는 상황을 의미한다. (OS에선 시스템 자원에 대한 요구가 뒤엉켜 이도저도 못하는 상태)

 

데드락의 발생조건

1.상호배재 - 한번에 프로세스 1개당 해당자원(1개의 자원)만 사용가능하며 다른 프로세스가 사용하려면 요청한 자원이 해제될때까지 기다려야한다. 

2.점유대기 - 자원을 1개이상 보유, 타 프로세스에 할당된 자원을 점유하기 위해 대기해야한다. 

3.비선점 - 이미 할당된 자원을 강제로 뺏을수 없다 

4.순환대기 - 대기 프로세스의 집합이 순환형태로 자원을 대기하고 있어야한다.

(하단의 사진을 참조..)

데드락의 예방

1.자원의 상호 배제조건 방지 - 한번에 여러 프로세스가 공유자원을 사용할수 있게 되어야한다.

2.점유 대기 조건 방지 - 프로세스 실행에 필요한 모든 자원을 한꺼번에 요구하고 허용할때까지 자원을 보류해서 추후 또다른 자원을 점유하기 위한 대기조건을 성립하지 않도록 한다.

3.비선점 조건 방지 - 다른 프로세스에 할당된 자원이 선점권이 없다고 가정할때 높은 우선순위의 프로세스가 해당자원을 선점할수 있도록한다.

4.순환 대기 조건 방지 - 자원을 순환형태로 하지않고 일정한 한쪽 방향으로만 자원을 요구할수 있도록 한다.

단, 이런 조건을 활용해 데드락을 예방할경우 시스템의 처리량 또는 효율성이 떨어질 우려가 있다.

 

데드락 회피

데드락의 발생 가능성을 OS가 검사하고 문제없을 경우에만 자원을 할당함으로써 문제 발생을 피하는 방법이다.

시스템의 프로세스들이 모든 자원을 데드락의 발생없이 차례로 할당해주는 상태를 안정상태(safe state),데드락 발생의 여지가 있는상태를 불안정 상태라고 표현하는데 항상 안정상태에 있도록 진행해주는 알고리즘이 은행원 알고리즘 이다.

(특정한 순서로 프로세스에게 자원을 할당, 실행, 종료시 데드락이 발생하지 않는 순서를 안전순서(safe sequence)라고 한다.)

 

은행원 알고리즘

미리 결정된 모든 자원들의 최대 할당가능한 할당량을 갖고 시뮬레이션해서 safe state에 들수 있는지 여부를 검사

은행원 알고리즘은 MAX, Allocated, Available, Need 4개의 요소를 가지며 각 요소의 의미는 다음과 같다.

이름 설명
MAX (최대로 쓸수 있는 자원량) 각 프로세스 자원의 최대 요청(요구)량
Allocated (현재 할당된 자원량) 현재 프로세스에 할당되있는 자원의 수
Available (현재 끌어올수 있는 자원량) 각 형태별로 사용 가능한 자원의 수
Need (부족한 수량) 각 프로세스에 더 추가할수 있는 양을 표시.

은행원 알고리즘의 예시를 참고해보자

(단, 모든 프로세스의 최대사용량(MAX)를 알아야 하며 가용 가능한 수량이 동일해야 하는 전제조건이 필요하다.)

P0은 3개(A - 0, B - 2, C - 1)를 사용중이며 작업완료를 위해선 6개(A - 2, B - 2, C - 2)을 추가로 필요로 한다.

P1은 3개(A - 1, B - 1, C - 1)를 사용중이며 작업완료를 위해선 10개(A - 4, B - 2, C - 4)를 추가로 필요로 한다.

P2는 2개(A - 0, B - 2, C - 0)를 사용중이며 작업완료를 위해선 8개(A - 2, B - 1, C - 5)를 추가로 필요로 한다.

 

현재 우리가 가져올수 있는 자원(Available)은 총 9개(A - 3, B - 3, C - 3)이며 C를 기준으로 알고리즘을 진행하겠다.

현재 C의 가용가능한 수량이 3개이기에 가능한 프로세스는 P0뿐이다.

P0이 끝나면 C의 가용 가능한 수량은 총 4개가 되며 (기존 3개+P0의 완료로 반환된 1개) 완료 가능한건 P1뿐이다.

P1이 끝나면 C의 가용 가능한 수량은 총 5개가 되며 (상단의 4개+P1의 완료로 반환된 1개) 나머지 P2에 전달하면 문제없이 동작됨을 확인할수 있다.  (Safe sequence)

 

 

데드락 탐지 및 회복

탐지

Allocation, Request(요청량), Available로 시스템 내에 데드락이 발생했는지 탐색 즉, 은행원 알고리즘과 유사한 방식으로 탐지 자원 할당 그래프를 통한 탐지(단, 탐지 알고리즘을 실행할경우 이에 대한 오버헤드 발생)

회복

1. 교착상태에 빠진 프로세스 전체를 중지 또는 교착상태가 해소될때까지 프로세스를 중지

2. 교착상태에 빠진 프로세스가 점유하고 있는 자원을 선점(빼앗아)해 교착상태가 풀릴때까지 타 프로세스에 할당

 

 

 

 

 

 

 

 

 

 

'CS' 카테고리의 다른 글

메모리 단편화  (0) 2023.04.08
캐시에 대하여  (0) 2023.04.07
시스템콜  (0) 2023.04.01
링킹과 오브젝트파일  (0) 2023.03.30
운영체제란  (0) 2023.03.30

+ Recent posts