회사에서도 직렬화/ 역직렬화를 위해 사용하는 jackson 라이브러리. 

마침 넥텝 과제하던 중 알게된 어노테이션 @Jacksonized를 정리해본다.

 

Jackson 라이브러리란 ?

spring-boot-starter-web 의존성을 주입하면 자동으로 이 라이브러리가 포함된다.

JSON 컨버팅할때 jackson을 사용하게된다.

 

@Jacksonized 

역직렬화를 위한 어노테이션이다.

불변성을 보장하면서 역직렬화를 가능하게 한다.

 

@Jacksonized 어노테이션은 @Builder 또는 @SuperBuilder와 함께 사용한다.

이 어노테이션은 생성된 빌더 클래스를 Jackson의 역직렬화에 사용할 수 있도록 자동으로 구성합니다.

@Builder 또는 @SuperBuilde가 적용된 상황에서만 가능하다.

빌더의 동작을 변경하지 않는다.

@Jacksonized @Builder
@JsonIgnoreProperties(ignoreUnknown = true)
public class JacksonExample {
	private List<Foo> foos;
}

 

예시 코드

@Getter
@Builder
@Jacksonized
class JacksonExample {
  private final String name;
  private final int age;
}

class JacksonExampleTest {
  @Test
  void testJacksonSerializationAndDeserialization() throws IOException {
    // 객체 생성
    JacksonExample example = JacksonExample.builder()
        .name("Bob")
        .age(25)
        .build();

    // ObjectMapper를 사용하여 객체를 JSON 문자열로 직렬화
    ObjectMapper objectMapper = new ObjectMapper();
    String json = objectMapper.writeValueAsString(example);

    // JSON 문자열을 사용하여 객체를 역직렬화
    JacksonExample deserializedExample = objectMapper.readValue(json, JacksonExample.class);

    // 값 비교
    assertEquals("Bob", deserializedExample.getName());
    assertEquals(25, deserializedExample.getAge());
  }
}
  • JackonExample 클래스에 @Jacksonized 어노테이션을 적용했다.
  • Jackson 의 직렬화 및 역직렬화에 사용되는 빌더 클래스를 자동으로 구성한다.
  • 위 테스트 코드에서 객체를 생성하고 ObjectMapper를 사용하여 해당 객체를 json문자열로 직렬화 한후 다시 역직렬화한다.
  • 역직렬화된 객체의 값과 원래의 값이 일치하는지 확인한다. 

 

플젝 적용

아래는 넥텝 과제에 적용한 내 코드 일부분이다.

package cart.dto;

import cart.domain.Cart;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.extern.jackson.Jacksonized;

@Getter
@AllArgsConstructor
@Jacksonized
@Builder
public class CartCreateDto {

  private final Long productId;
  private final int count;

  public Cart toEntity(Long memberId) {
    return Cart.builder()
        .productId(getProductId())
        .memberId(memberId)
        .count(getCount())
        .build();
  }
}
  • @Jacksonized 어노테이션을 사용해서 CartCreateDto 클래스가 Jackson과 함께 동작한다.
  • Jacksonized 어노테이션과 Builder 어노테이션을 같이 사용해 빌더 패턴이 생성된다.
  • 위 클래스의 객체를 Json 형식으로 직렬화해서 요청 바디에 넣는 테스트 코드를 작성하여 직렬화를 처리한다.
  @DisplayName("로그인한 유저의 장바구니에 상품을 추가한다.")
  @Test
  void addItemToCart() {
    CartCreateDto createDto = CartCreateDto.builder()
        .productId(1L)
        .count(1)
        .build();

    var result = given()
        .auth().preemptive().basic(member.getEmail(), member.getPassword())
        .contentType(MediaType.APPLICATION_JSON_VALUE)
        .accept(MediaType.APPLICATION_JSON_VALUE)
        .body(createDto)
        .when().post("/carts/add-to-cart")
        .then().log().all()
        .extract();

    assertThat(cartService.cartProducts(member).size()).isEqualTo(2);
    assertThat(result.statusCode()).isEqualTo(HttpStatus.OK.value());
  }
  • 요청을 보낼때 createDto 객체가 요청 바디에 담겨 전송된다.
  • 서버에서 json 바디를 역직렬화하여 cartCreateDto 객체로 변환한다. 

 

참고 

https://www.baeldung.com/java-jackson-deserialization-lombok

https://projectlombok.org/features/experimental/Jacksonized

'* > What I did today' 카테고리의 다른 글

객체지향  (0) 2023.03.23
How to Achieve More  (3) 2023.03.14
DB Connection Pool  (0) 2023.02.15
Tree  (0) 2023.01.10
null 대신 Optional 클래스  (0) 2023.01.02
GC  (0) 2023.01.01
static 변수는 JVM의 어디에 저장될까 ?  (0) 2022.12.25
JVM  (0) 2022.12.24

프로그래밍 패러다임

패러다임 

한 시대의 사회전체가 공유하는 이론이나 방법, 문제 의식등의 체계

 

프로그래밍 패러다임 

특정 시대의 어느 성숙한 개발자 공동체에 의해 수용된 프로그래밍 방법과 문제 해결 방법, 프로그래밍 스타일.

우리가 어떤 프로그래밍 패러다임을 사용하느냐에 따라 우리가 해결할 문제를 바라보는 방식과 프로그램을 작성하는 방법이 달라진다. 프로그래밍 언어마다 채택하는 프로그래밍 패러다임이 다르다.

 

패러다임 전환 

절차형 패러다임에서 객체지향 패러다임으로의 변화를 가리킨다.

 

프로그래밍 패러다임의 역할

개발자 공동체가 동일한 프로그래밍 스타일과 모델을 공유할 수 있게 함으로써 불필요한 부분에 대한 의견 충돌을 방지한다. 

또한 교육시킴으로써 동일한 규칙과 방법을 공유하는 개발자로 성장하도록 준비시킬 수 있다.

특정한 종류의 문제를 해결하는데 필요한 일련의 개념들을 지원한다.


소극장 애플리케이션의 문제 

의도 

Theater : 관람객을 입장

TickerSeller : 티켓을 판매

Audience :  티켓 구매 

1. 예상을 빗나가는 코드 예시

내가 관람객이라고 가정할때, 관람객의 입장에서 소극장이라는 제3자가 초대장을 확인하기 위해 관람객의 가방을 마음대로 열어본다.

의도 : 티켓을 구매하는 관람객이 가방 안에서 돈을 직접 꺼내 판매원에게 지불한다.

2. 변경에 취약한 코드 예시

의존성 문제. 어떤 객체가 변경될 때 그 객체에게 의존하는 다른 객체로 함께 변경될 수 있다.

Theater가 Audience와 TicketSeller의 상세한 내부 구현까지 알고 있어야 한다.


설계 개선

// 문제코드
public class Theater{
	private TicketSeller ticketSeller;
    
    public Theater(TicketSeller ticketseller){
    this.ticketSeller = ticketSelelr;
    }
    
    public void enter(Audience audience){
        if(audience.getBag().hasInvitation()){ //TicketSeller의 sellTo()메소드로 옮긴다. TicketSeller의 내부구현을 캡슐화
            Ticket ticket = ticketSeller.getTicketOffice().getTicket();
            audience.getBag().setTicket(ticket);
        }else{
            Ticket ticket = ticketSeller.getTicketOffice().getTicket();
            audience.getBag().minusAmount(ticket.getFee());
            ticketSeller.getTicketOffice().plusAmount(ticket.getFee());
            audience.getBag().setTicket(ticket);
        }
	}
}
//개선 코드
public class Theater {
	private TicketSeller ticketSeller;
    
    public Theater(TicketSeller ticketSeller){
    	this.ticketSeller = ticketSeller;
        }
    
    public void enter(Audience audience){
    	ticketSeller.sellTo(audience); //TicketOffice에 접근하는 로직을 모두 ticketSeller.sellTo에 숨김
        }
    }

1. 자율성을 높이기

관람객과 판매원을 자율적인 존재로 만든다.

Theater가 TicketSeller와 Audience에 세세한 부분까지 알지 못하도록 정보를 차단한다.

관람객이 스스로 가방 안의 현금과 초대장을 처리하고 판매원이 스스로 매표소의 티켓과 판매 요금을 다루게 한다.

 

 

 

1.1 캡슐화 개념적이나 물리적으로 객체 내부의 세부적인 사항을 감추는 것.

객체 내부로의 접근을 제한해 객체와 객체 사이의 결합도를 낮춘다. -> 설계를 좀더 쉽게 변경 가능

접근 가능한 퍼블릭 메서드가 존재하지 않기때문에 외부에서 ticketOffice에 직접 접근할 수 없다. 오직 TicketSeller안에만 존재하게 된다. 

 

1.2 수정된 Theater class 어디서도 ticketOffice에 접근하지 않는다.

Theater 는 ticketOffice가 TicketSeller내부에 존재하는 사실을 모른다. 

Theater는 오직 TicketSeller 인터페이스에만 의존한다.

객체를 인터페이스와 구현으로 나누고 인터페이스만을 공개하는 것은 객체 사이의 결합도를 낮추고 변경하기 쉬운 코드를 작성한다. 

 

2. 자신의 문제해결

판매자가 티켓을 판매하기 위해 ticketOffice를 사용하는 모든 부분을 TicketSeller 내부로 옮기고, 관람객이 티켓을 구매하기 위해 Bag을 사용하는 모든 부분을 Audience 내부로 옮긴다. 

자신의 문제를 스스로 해결하도록 코드를 변경한다.


개선된 점

변경 용이성이 개선

TicketSeller의 내부 구현을 변경하더라도 Theater를 함께 변경할 필요가 없다. TicketSeller가 매표소가 아니라 은행에 돈을 보관하도록 만들고 싶으면 TicketSeller내부만 변경하면 된다.

 

책임의 이동

기존 코드는 책임이 Threater에 집중되어 있었다. 

독재자가 존재하지 않고, 각 객체에 책임이 적절하게 분배된다. 

데이터와 데이터를 사용하는 프로세스가 동일한 객체 안에 존재한다.  


절차지향

개선전의 Theater는 절차적 프로그래밍이다.

Theater enter메서드는 프로세스이며, Audience, TicketSeller, Bag, TicketOffice는 데이터이다. 

프로세스를 담당하는 Theater가  Audience, TicketSeller, Bag, TicketOffice 모두에 의존하고 있었다. 모든 처리가 하나의 클래스 안에 위치하고 나머지 클래스는 단지 데이터의 역할만 수행했다. 

프로세스와 데이터를 별도의 모듈에 위치시키는 방식이 절차지향이다.


객체지향 설계

  • 자신의 문제를 스스로 처리하기 때문에 예측이 가능하고, 이해하기 쉬우며 객체 내부의 변경이 객체 외부에 파급되지 않도록 제어할 수 있어서 변경하기가 수월하다.
  • 의존성 제거 : 불필요한 의존성을 제거-> 객체사이의 결합도를 낮추는 것
  • 캡슐화 : Theater가 몰라도 되는 세부사항을 Audience와 TicketSeller 내부로 감춰 캡슐화

좋은 설계

변경을 수용할 수 있어야한다.

요구사항은 항상 변경된다.  

오늘 요구하는 기능을 온전히 수행하면서 내일의 변경을 매끄럽게 수용할 수 있는 설계

 

 

'* > What I did today' 카테고리의 다른 글

@Jacksonized  (0) 2023.06.06
How to Achieve More  (3) 2023.03.14
DB Connection Pool  (0) 2023.02.15
Tree  (0) 2023.01.10
null 대신 Optional 클래스  (0) 2023.01.02
GC  (0) 2023.01.01
static 변수는 JVM의 어디에 저장될까 ?  (0) 2022.12.25
JVM  (0) 2022.12.24

걸스인텍&원티드에서 진행한 워크샵에 다녀왔다. 생각보다 신청자 수가 많았다. 5:1의 경쟁률이었다고 한다 워후 

아름다운 광화문 뷰와 함께 토요일 아침을 알차게 보내고 왔다.

한국 마이크로소프트의 김성미 이사님께서 일하는 방법을 강연해주셨다 .김 이사님께서 공유해주신 소중한 경험담과 인사이트들을 정리해보았다.

  • 꿈은 이루어진다 : 가짜 꿈들 사이에서 진짜 꿈을 찾는 과정에 시련이있다.
  • 행복은 전염된다 : 기여는 건강한 에너지, 선순환을 만든다.
  • 가슴 뛰는 일을 먼저하기 : 하고싶은 것에 일단 몸을 던지고, How to 고민하기
  • 주말 아침 4시간을 내 시간으로 갖기 : 가장 빨리 열리는 카페에 출근하는 직원과 함께 들어가 나만의 시간을 보내기, 3개월 이상 유지하기
  • 만다라트 기법으로 목표 세우고 성취하기

직종을 변경하면서도 긍정적인 에너지와 열정을 유지하는 방법을 배웠다. 워크샵이 끝나고 김성미 이사님께서 직접 친필 서명이 담긴 책을 선물해주셨다. 집에 돌아오면서 마음이 충만해진 느낌이었다. 세션에서 다 채우지 못한 내 만다라트도 채워봐야겠다. 그리고 다양한 분야에서 일하는 분들과 소통하면서 열정을 느낄 수 있어서 매우 좋았다.

걸스인텍 이벤트는 이번이 번째인데, 항상 알차고 얻어가는 것이 많다! 

'* > What I did today' 카테고리의 다른 글

@Jacksonized  (0) 2023.06.06
객체지향  (0) 2023.03.23
DB Connection Pool  (0) 2023.02.15
Tree  (0) 2023.01.10
null 대신 Optional 클래스  (0) 2023.01.02
GC  (0) 2023.01.01
static 변수는 JVM의 어디에 저장될까 ?  (0) 2022.12.25
JVM  (0) 2022.12.24
  • DB connection pool과 스레드 개수는 메모리와 관련이있다.
  • 많이 사용할 수록 메모리를 많이 점유한다.
  • 개수를 적게 지정하면 서버에서는 많은 요청을 처리하지 못하고 대기하게된다.
  • WAS에서 기본 개수가 10~20개 정도이다.
  • DB connection pool은 보통 40~50개로 지정하고 스레드 개수는 이보다 10개 정도 더 지정한다.
  • 스레드 개수 < DB connection pool : 스레드가 적은만큼 연결 필요가 없어진다.
  • 스레드 개수 > DB connection pool : 여유분을 갖도록위함이다.
  • 적합한 개수는 서버와 애플리케이션 상황에 따라 다르다.
  • 서비스 및 서버의 상황에 맞게 값을 지정해야한다. -> 성능테스트
  • DB의 CPU 사용량이 100% 도달했다면 ? CPU를 점유하는 쿼리를 찾는다 -> 인덱스가 없거나, 테이블을 풀 스캔하는 쿼리가 있는지 , 쿼리의 플랜을 확인한다.
  • DB connection pool 지정 개수를 전부 사용한다고 개수를 막 늘리면 DB사용량이 늘고 응답 시간이 느려진다
  • DB의 CPU 사용량이 50% 미만이고 WAS의 CPU 사용량이 100%일때 : WAS의 애플리케이션을 튜닝한다. 이미 튜닝했다면 -> 커넥션풀을 늘리기, 서버 대수 늘리는것은 가장 마지막에 고려할 것

음..회사에서 DB의 CPU점유율이 상당히 높은 편이다..이유는 바로 가장많이 이용하는 부분의 쿼리들 때문!!

이 부분도 팀원들이랑 개선점 찾아서 진행하고싶다

'* > What I did today' 카테고리의 다른 글

@Jacksonized  (0) 2023.06.06
객체지향  (0) 2023.03.23
How to Achieve More  (3) 2023.03.14
Tree  (0) 2023.01.10
null 대신 Optional 클래스  (0) 2023.01.02
GC  (0) 2023.01.01
static 변수는 JVM의 어디에 저장될까 ?  (0) 2022.12.25
JVM  (0) 2022.12.24

트리

0개 이상의 다른 노드에 대한 레퍼런스가 들어 있는 노드로 구성

한 노드를 참조하는 노드는 하나

노드는 구조체, 클래스로 표현

포인터 또는 레퍼런스만 있다면 어떤 언어로든 구현 가능

보통 노드의 공통적인 부분을 하나의 클래스로 정의하고 노드에 들어가는 데이터를 서브클래스를 만들어서 사용

public abstract class Node{
	private Node[] children;

	public Node(Node[] children){
    	this.children = children;
    }
    
    public int getNumChildren(){
    	return children.length;
    }
    
    public Node getChild(int index){
    	return children[index];
    }
}

public class IntNode extends Node{
	private int value;
    
    public IntNode(Node[] children. int value){
    super(children);
    this.value=value;
    }
    
    public int getValue(){
    return value;
    }
}

부모 : 다른 노드를 가리키는 노드는 그 노드의 부모가 된다.

자식 : 루트를 제외한 모든 노드는 그 노드를 가리키는 노드의 자식이 된다.

자손 : 특정 노드로 부터 자식노드로 이어지는 경로를 따라 도달 할 수 있는 모든 노드는 그 특정 노드의 자손이다.

조상 : 어떤 노드를 자손으로 삼고 있는 노드는 모두 그 노드의 조상이다.

잎 : 자식이 없는 노드를 잎이라고 부른다

 

이진트리

한 노드에 자식이 최대 두개 까지만 있을 수 있으며 그 두 자식은 각각 왼쪽 자식과 오른쪽 자식이라고 부른다.

//이진트리
public class Node{
	private Node left;
    private Node right;
    private int value;
    
    public Node(Node left,Node right,int value){
    	this.left = left;
        this.right = right;
        this.value =value;
    }
    
    public Node getLeft(){return left;}
    public Node getRight(){return right;}
    public int getValue(){return value;}
}

이진 검색 트리

노드의 왼쪽 자식의 값이 반드시 자신의 값이하이며, 오른쪽 자식의 값은 반드시 자신의 값 이사이앋.

데이터가 값으로 정렬된다.

어떤 노드의 왼쪽 방향의 자손들은 전부 그 노드 이하의 값을 가지며 오른쪽 자손들은 모두 그 노드 이상의 값을 가진다.

룩업연산을 빠르고 간단하게 처리 할 수 있다.

Node findNode(Node root, int value){
	while(root != null){
    	int currval = root.getValue();
        if( currval == value) break;
        if( currval < value){
        	root = root.getRight();
        }else { // currval > value
        	root = root.getLeft();
        }
    }
    return root;
}

노드의 각 자식의 값은 노드 자신의 값 이하여야한다

루트노드의 값은 그 트리에서 가장 큰 값이며 최댓값을 상수 시간으로 구하는 것이 가능하다

삽입과 삭제는 O(log(n))

룩업은 O(n)

ex, 병원 응급실에서 대기 중인 환자들을 힙으로 모델링

우선순위 부여

 

일반적인 검색 방법

너비 우선 검색

O(n)

어떤 층을 검색할 때 그 층에 있는 모든 노드의 자식노드를 저장해둬야 하기 때문에 메모리도 꽤 사용한다

 

깊이 우선 검색

원하는 노드를 찾을 때까지 또는 끝에 다다를 때까지 한 가지를 따라 쭉 내려가는 방식

 

종주 (traversal)

방법에 따라 노드를 방문하는 순서가 달라진다

프리오더 종주 : 항상 노드를 자식들보다 먼저 방문

인오더 종주 : 왼쪽 서브트리를 먼저 방문하고 노드 자체를 방문한 다음 오른쪽 서브 트리 방문

포스트오더 종주 : 왼쪽자손 작업 수행 후 오른쪽자손 작업 마지막으로 그 노드 자체 처리

재귀호출로 구현

 

 

 

 

'* > What I did today' 카테고리의 다른 글

@Jacksonized  (0) 2023.06.06
객체지향  (0) 2023.03.23
How to Achieve More  (3) 2023.03.14
DB Connection Pool  (0) 2023.02.15
null 대신 Optional 클래스  (0) 2023.01.02
GC  (0) 2023.01.01
static 변수는 JVM의 어디에 저장될까 ?  (0) 2022.12.25
JVM  (0) 2022.12.24

null 때문에 발생하는 문제

  • 에러의 근원 : NPE
  • 코드를 어지럽힌다. : 중첩된 null 확인 코드
  • 형식 시스템에 구멍을 만듦  : null이 할당되면 시스템의 다른부분으로 null이 퍼졌을때 애초에 null이 어떤 의미로 사용되었는지 알 수 없음

Optional클래스를 사용

메서드의 시그니처만 보고도 선택형 값인지 여부를 구별 할 수 있다.

public class Person{
	private Optional<Car> car; //사람이 차를 소유했을 수도 소유하지 않았을 수도 있다
    public Optional<Car> getCar();{
    	return car;
        }
    }

 

Optional 사용 

  • 잠재적 null이 될 수 있는 대상을 Optional로 감싸기
  • 팩토리메서드 Optional.empty , Optional.of , Optional.ofNullable 이용해서 Optional 객체 만들기
Optional<Object> value = Optional.ofNullable(map.get)"key"));

'* > What I did today' 카테고리의 다른 글

객체지향  (0) 2023.03.23
How to Achieve More  (3) 2023.03.14
DB Connection Pool  (0) 2023.02.15
Tree  (0) 2023.01.10
GC  (0) 2023.01.01
static 변수는 JVM의 어디에 저장될까 ?  (0) 2022.12.25
JVM  (0) 2022.12.24
Java - static 사용의 지양  (0) 2022.12.17

Garbage-First Garbage Collector.pdf
0.33MB

GC : 프로그램이 동적으로 할당했던 메모리 영역중 필요업게 된 영역을 알아서 해제

장점 : 메모리 누수 방지, 해제된 메모리 접근 방지, 해제한 메모리의 해제 방지

단점 : GC작업은 순수 오버헤드

GC알고리즘

  1. Reference counting
    1. 힙영역에 선언된 객체들이 레퍼런스카운트 숫자를 갖는다.
    2. 레퍼런스 카운트가 0이면 GC대상
    3. 순환참조 문제발생 (메모리 릭 발생)
  2. Mark and sweep
    1. 순환 참조 문제해결
    2. 루트에서부터 해당 객체에 접근가능한지 기준
    3. Mark : 루트부터 연결된 객체찾는것 (reachable)
    4. Sweep : 연결이 끊어진 객체 지우는것(unreachable)
    5. Compaction : 메모리 파편화 막음 (필수 아님)
      1. Sweep 후에 분산된 객체들을 Heap 시작 주소로 모아 메모리가 할당된 부분과 그렇지 않은 부분으로 압축한다
    6. 단점 : 의도적으로 GC실행 시켜야함, 어플리케이션과 GC실행이 병행

Root space

  • JVM메모리의 stack의 로컬변수 , method area에 저장된 static변수 , native method stack의 C/C++ 작성되 JNI참조

Heap :

  1. Young
    1. Eden : minor GC
    2. Survival 0 : minor GC
    3. Survival 1 : minor GC (서바이벌0,1 둘중하나만차야함)
  2. Old : (young -> old : promotion)
    1. Major GC 발생

대부분 객체가 수명이 짧음

메모리의 특정부분만 처리(영부분)

Stop the world

GC실행을 위해 JVM이 어플리케이션 실행을 멈추는것

 

GC 방식

  1. Serial GC
    1. 하나의 스레드로 GC실행
    2. Stw 시간이 김
    3. 싱글 스레드 환경 및 heap이 매우 작을때 사용
    4. compaction
  2. Parallel GC
    1. 여러개의 스레드로 GC실행
    2. 멀티코어 환경에서 사용
    3. Java8 default GC
    4. Compaction (mark-summary-compaction)
  3. CMS (concurrent mark sweep)
    1. stw시간을 최소화하기위해 고안
    2. GC 작업을 어플리케이션과 동시에 실행
    3. G1 GC 등장에 따라 deprecated
    4. compaction이 기본적으로 제공되지않음
  4. G1 GC
    1. heap을 region으로 나누어 관리
    2. Java9 default
    3. Compaction 작업수행
    4. Heap을 일정크기의 리전으로 잘게 나눠서 어떤영역은 올드 ,영으로 나눠서 튜닝한다.전통적인 GC 힙구조와 달리 young 이나 old 영역이 인접해 있지 않고 영역의 사이즈에 따라서 동적으로 바뀔 수 있다.
    5. G1 GC 영역의 개념이 물리적으로 존재하지 않고 논리적으로 존재함으로써 공간과 시간을 아낄 있다.
    6. 메모리가 많이 차있는 리전을 인식하는 기능을 통해 메모리가 많이 차있는 리전을 우선적으로 GC한다.
    7. https://luavis.me/server/g1-gc

Compaction :

  • 더 이상 참조되지 않는 오브젝트가 해제된 이후 오브젝트들 사이의 빈공간을 없애기 위해 재배치
  • 여유 공간을 큰 덩어리로 통합
  • 선형
  • TLAB (스레드 로컬 할당 버퍼)

GC튜닝

올드영역 객체최소화하기

Major GC시간 짧게

java -XX:+PrintCommandLineFlags -version
-XX:ConcGCThreads=3 -XX:G1ConcRefinementThreads=10 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=268435456 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=4294967296 -XX:MinHeapSize=6815736 -XX:+PrintCommandLineFlags -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC 
openjdk version "18.0.2.1" 2022-08-18
OpenJDK Runtime Environment (build 18.0.2.1+1-1)
OpenJDK 64-Bit Server VM (build 18.0.2.1+1-1, mixed mode, sharing)

GC 종류 변화

  1. Serial GC
  2. Parallel GC
  3. Parallel Old GC
  4. CMS GC
  5. G1

CMS GC : 메모리 단편화발생

G1 GC :메모리 단편화 해결

 

GC 알고리즘

자바 GC

자바 GC 실행 방법

Jim memory leak

Scouter

Riverbed

NPM

 

 

CMS에서는 compaction을 직접해줘야하나 ? 

STW는 정확히 언제 발생하는가 ?

G1 에서는 STW 특정 구간에만 발생할 있는 이유는 ?

 

 

 

https://mirinae312.github.io/develop/2018/06/04/jvm_gc.html  

https://d2.naver.com/helloworld/329631

https://d2.naver.com/helloworld/1329

http://imp51.tistory.com/entry/G1-GC-Garbage-First-Garbage-Collector-Tuning https://thinkground.studio/%EC%9D%BC%EB%B0%98%EC%A0%81%EC%9D%B8-gc-%EB%82%B4%EC%9A%A9%EA%B3%BC-g1gc-garbage-first-garbage-collector-%EB%82%B4%EC%9A%A9/

 

'* > What I did today' 카테고리의 다른 글

How to Achieve More  (3) 2023.03.14
DB Connection Pool  (0) 2023.02.15
Tree  (0) 2023.01.10
null 대신 Optional 클래스  (0) 2023.01.02
static 변수는 JVM의 어디에 저장될까 ?  (0) 2022.12.25
JVM  (0) 2022.12.24
Java - static 사용의 지양  (0) 2022.12.17
Cache  (2) 2022.12.15

자바 키워드부터 다시 공부하고 있다.

static 사용의 장단점 및 주의사항을 알게되면서 JVM메모리에는 어떻게 저장될지 궁금해서 찾아보았다.

찾아볼수록 사람마다 다른 해석을 하고 Java8에서의 변화도 알게되면서 정리하는데 오랜 시간이 걸렸다.

(혹시 잘못 이해한 부분이 있다면 피드백 부탁드립니다.)

 

이해가 필요했던 부분들

  • static
  • JVM 의 method area
  • constant pool vs string constant pool
  • Permanent Generation의 변화 

 

Static 변수가 heap에서 관리되다 ?

static키워드를 통해 정의된 변수들은  method area내 constant pool에 reference 정보가 들어가고 value는 heap에 들어가 GC대상이 된다. 특히 String을 static으로 선언하면 heap안에 String constant pool안에 value가 저장된다. new키워드없이 바로 문자열을 대입하면 string constant pool영역에서 하나의 객체로 유지되는 것이다.

이는 new 키워드를 이용했을때와 다르다. static String을 new연산자를 이용하면 heap안에서 계속 새로운 객체로 인식이된다. 

 

method area를 heap의 일부로 정리되어있는 글도 있는데, 포인트는 Java8 부터 Static Oject 를 heap영역에 옮겨서 GC 대상이 될 수 있도록 한 것이다.

 

 

히스토리

이는 Permanent Generation이 MetaSpace으로 변한 히스토리 이해가 필요했다.

Class 데이터를 저장하는 곳은 method area이고 Java8이전에는 Method area를 PermGen에 할당했다. 이때 VM옵션으로 정해진 사이즈를 줬는데 이게 out of memory를 발생하게 했다. Java8 이후에는 PermGen 영역이 완전히 없어지고 Metaspace가 PermGen의 역할을 한다. permanent generation 에 저장된 정보도 GC대상이었다. 참조를 하지않는 Object를 GC대상이되록 하는데 변화가 있었던 것이다. 

 

 

정리

  • 지역변수가 primitive type 이면 stack에 저장된다.
  • 지역변수가 reference type 이면 객체는 heap에 저장되고 객체를 가리키는 reference는 stack에 저장된다.
  • 인스턴스 변수일 경우 primitive type 및 reference type 모두 객체는 heap에 저장되고 그 객체의 reference는 stack에 저장된다.
    클래스 변수가 primitive type이면 method area 내 runtime constant pool에 reference가 저장되고 value가 heap에 저장된다.
  • 클래스 변수가 reference type이면 heap내 객체자가 저장되고 reference를 method area내 runtime constant pool에 저장된다. 
  • String Literal 은 Heap내 String constant pool에 저장되어 동일한 주소를 유지한다.

 

참고 블로그

https://jgrammer.tistory.com/144

https://stackoverflow.com/questions/50163218/is-method-area-still-present-in-java-8

https://mirinae312.github.io/develop/2018/06/04/jvm_memory.html

https://8iggy.tistory.com/230

'* > What I did today' 카테고리의 다른 글

DB Connection Pool  (0) 2023.02.15
Tree  (0) 2023.01.10
null 대신 Optional 클래스  (0) 2023.01.02
GC  (0) 2023.01.01
JVM  (0) 2022.12.24
Java - static 사용의 지양  (0) 2022.12.17
Cache  (2) 2022.12.15
서버가 죽는 이유 ,message queue  (0) 2022.07.20

JVM

  • 실행될 클래스 파일을 메모리에 로드 후 초기화 작업 수행
  • 메소드와 클래스변수들을 해당 메모리 영역에 배치
  • 클래스 로드가 끝난 후 JVM은 main메소드를 찾아 지역변수, 객체변수, 참조변수를 스택에 쌓음
  • 다음 라인을 진행하면서 상황에 맞는 작업 수행 

JVM은 운영체제에 독립적

Java를 사용하려면 JDK를 설치해야하는데 JDK는 운영체제별로 종류가 다르다.

JDK안에는 JRE, API,JVM이 포함되어 있다.

운영체제마다 다른 JVM이 제공되어 독립적일 수 있다.

 

JVM 실행

자바 코드 (.java) 컴파일  -> 바이트 코드파일 생성(.class) -> 기계어 코드파일 변환 (JVM역할)

 

1. Class Loader

실행에 필요한 실행파일(.class)찾는다

- bootstrap classloader

- extension classloader

- application classloader

 

2. 바이트 코드 검증 

클래스 로더가 모든 실행 파일을 준비하면 이 파일의 코드가 올바른지 검증한다.

 

3. 기계어 코드로 변환

Java실행 파일은 바이트 코드이기 때문에 실행될때 다시 한번 기계가 읽을 수 있는 형태로 인터프리터를 통해 해석된다.

 - 인터프리터

 - JIT 컴파일러

 

Runtime Data Area

런타임 데이터 영역에서
여러 쓰레드가 heap, method area ( + runtime constant pool) 공유하고
쓰레드는 PC register , stack , Native method stack 가진다. 

 

1. Method area

JVM이 읽어 들인 클래스와 인터페이스에 대한 runtime constant pool, 멤버변수, 클래스 변수, 생성자와 메소드를 저장하는 공간

메서드 영역은 모든 스레드가 공유하는 영역으로 JVM이 시작될 때 생성된다. JVM이 읽어 들인 각각의 클래스와 인터페이스에 대한 런타임 상수 풀, 필드와 메서드 정보, Static 변수, 메서드의 바이트코드 등을 보관한다. 메서드 영역은 JVM 벤더마다 다양한 형태로 구현할 수 있으며, 오라클 핫스팟 JVM(HotSpot JVM)에서는 흔히 Permanent Area, 혹은 Permanent Generation(PermGen) 이라고 불렸는데 지금 Metaspace라고 불린다. 메서드 영역에 대한 가비지 컬렉션은 JVM 벤더의 선택 사항이다

- JVM시작시 생성

- 프로그램 종료시 까지

- 구성 방식이나 GC방법은 JVM벤더마다 다를 수 있다.

* runtime constant pool :  상수 풀은 특정 클래스의 코드를 실행하는 데 필요한 상수를 포함한다. 기본적으로 심볼 테이블과 유사한 런타임 데이터 구조이다. 자바 클래스 파일에서 클래스별 또는 인터페이스별 런타임을 표현한다. JVM은 클래스 파일을 로드하면서 이 constant_pool 정보를 메서드 영역의 런타임 상수 풀에 넣는다

 클래스 파일 포맷에서 constant_pool 테이블에 해당하는 영역이다. 메서드 영역에 포함되는 영역이긴 하지만, JVM 동작에서 가장 핵심적인 역할을 수행하는 곳이기 때문에 JVM 명세에서도 따로 중요하게 기술한다. 각 클래스와 인터페이스의 상수뿐만 아니라, 메서드와 필드에 대한 모든 레퍼런스까지 담고 있는 테이블이다. 즉, 어떤 메서드나 필드를 참조할 때 JVM은 런타임 상수 풀을 통해 해당 메서드나 필드의 실제 메모리상 주소를 찾아서 참조한다.

 

 

 

2. Heap area

런타임시 동적으로 할당하여 사용하는 영역이다

new연산자로 생성된 객체와 배열을 저장한다.

참조하는 변수나 필드가 없다면 의미없는 객체가되어 GC대상이 된다.

 

3.Stack area

JVM 스택안에 스택프레임 구조를 저장한다.

각 스레드 마다 존재한다.

메소드 호출시 프레임을 추가하고 메소드가 종료되면 프레임제거하는 동작을 수행한다.

후입선출

primitive 타입변수는 스택영역에 직접 값을 가진다.

JVM 스택은 각 스레드마다 하나씩 존재하며 스레드가 시작될 때 생성된다. 스택 프레임(Stack Frame)이라는 구조체를 저장하는 스택으로, JVM은 오직 JVM 스택에 스택 프레임을 추가하고(push) 제거하는(pop) 동작만 수행한다. 예외 발생 시 printStackTrace() 등의 메서드로 보여주는 Stack Trace의 각 라인은 하나의 스택 프레임을 표현한다

 

5. PC register

스레드가 생성될때 마다 생기는 공간이다. 

스레드가 어떠한 명령을 실행하게 될지에 대한 부분을 기록한다.

 

6. Native method stack area

자바 외 언어로 작성된 네이티브 코드를 위한 영역이다.

 

참고 

https://docs.oracle.com/javase/9/docs/api/java/lang/management/MemoryMXBean.html

https://goneoneill.tistory.com/43

'* > What I did today' 카테고리의 다른 글

Tree  (0) 2023.01.10
null 대신 Optional 클래스  (0) 2023.01.02
GC  (0) 2023.01.01
static 변수는 JVM의 어디에 저장될까 ?  (0) 2022.12.25
Java - static 사용의 지양  (0) 2022.12.17
Cache  (2) 2022.12.15
서버가 죽는 이유 ,message queue  (0) 2022.07.20
AWS Certified Cloud Practitioner - 합격 후기, 참고자료 정리  (4) 2021.12.14

static : global state 

static 변수는 코드 여러 부분에서 영향을 받을 수 있어 변화를 추적하기가 어렵다.

1. static은 객체 지향 적이지 않다.

각 객체들의 데이터들이 캡슐화 되어야한다는 객체지향의 원칙에 위배된다. 

예를 들어 static변수를 공유하여 여러 프로그램에서 사용할때 서로의 상태에 영향을 줄 수 있다. (데이터 정합성 문제 발생)

오버라이딩이 불가능하다.

메모리 회수가 어렵다 -> 가상머진의 메모리 부족

 

2. 객체의 라이프 타임 

static변수는 프로그램이 실행되고 있는 내내 살아있게 된다. 그 클래스 작업이 끝났더라도 static변수가 점유하고 있는 메모리는 garbage collector에 의해 회수되지 않는다.반대로 그 변수를 인스턴스화 해서 main()함수에서 하나의 인스턴스로 생성하고, 그 인스턴스에게 함수 호출을 시키고 그 함수 호출이 끝나면 인스턴스를 소멸된다.

static은 재사용성이 떨어진다. 

 

 

원본 : 

 

'* > What I did today' 카테고리의 다른 글

null 대신 Optional 클래스  (0) 2023.01.02
GC  (0) 2023.01.01
static 변수는 JVM의 어디에 저장될까 ?  (0) 2022.12.25
JVM  (0) 2022.12.24
Cache  (2) 2022.12.15
서버가 죽는 이유 ,message queue  (0) 2022.07.20
AWS Certified Cloud Practitioner - 합격 후기, 참고자료 정리  (4) 2021.12.14
11/5 (함께자라기)  (1) 2021.11.06

캐시

  • 가져오는데 비용이 드는 데이터를 한번 가져온 뒤에는 임시로 저장
  • 프록시는 웹서버와 클라이언트 사이에 들어가서 웹서버에 대한 액세스 동작을 중개하는 역할을 하는데, 액세스 동작을 중개할 때 웹서버에서 받은 데이터를 디스크에 저장해두고 웹서버를 대신하여 데이터를 클라이언트에 반송하는 기능을 가진다

 

캐시 서버 사용

  • 데이터베이스 서버와 웹서버같은 역할에 따라 서버를 나누는 방법, 역할별 분산 처리 방법 중 하나이다
  • 프록시라는 구조를 사용하여 데이터를 캐시에 저장하는 서버이다
  • 캐시 서버는 웹 서버에서 받아 보존해 둔 데이터를 읽어서 클라이언트에 송신만해서 웹서버 보다 빨리 데이터를 송신한다
  • 사용자가 캐시서버에 HTTP의 리퀘스트르 메시지를 보낸다. 캐시서버는 리퀘스트 메시지의 내용을 조사하고 데이터가 자신의 캐시에 저장되었는지 조사한다.

 

캐시 종류

로컬캐시

글로벌 캐시

분산된 글로벌 캐시

 

로컬캐시가 해당 서버 메모리에 요청하는 것이라 더 빠른데도 리모트 캐시를 쓰는 이유 ?

  • 데이터 정합성 때문.
  • 로컬 캐시는 각 서버별로 존재해 서버별로 캐시를 공유할 수 없음
  • 한 서버내의 로컬캐시의 데이터가 변경되었을때 다른 서버의 로컬캐시에서 기존내용을  가지고올 수 있음
  • 로컬캐시는 모든 유저에게 동일한 내용을 주로 담는다

 

리모트 캐시 과정

크게 redis에서 찾기 -> 없으면 DB에서 조회 -> redis넣어서 조회 / 있으면 바로 redis에서 조회

  1. 1번 서버에서 Redis에 user : hailey가 있는지 확인
  2. 없으면 DB에서 조회 후 Redis에 적재
  3. 2번 서버(다른서버)에서 Redis에 user : hailey가 있는지 확인
  4. Redis에 있으면 response
  5. 1번 서버와 2번서버 모두 동일한 데이터 리턴
  6. 데이터 user : hailey의 전화번호 변경
  7. DB 업데이트
  8. Redis 캐시에 해당 데이터를 찾아 삭제 (Evict) -> Redis에 해당 데이터 없음
  9. 없으면 DB에서 조회(새로운 데이터) 후 Redis에 적재

 

 

 

 


쿠키 

네이버 로그인 해제 : 세션아이디가 쿠키 보관함에서 삭제

로그인창의 아이디를 자동완성

공지메시지 하루 안보임

로그인안한 상태로 장바구니이용

사용자의 편의를 위하되 지워지거나 조작되거나 가로채이더라도 큰 일 없을 정보들을 브라우저에 저장

 

세션

사용자나 다른 누군가에게 노출되어서는 안되는 서비스 제공자가 직접 관리해야하는 내용

 

메모리 계층 구조

데이터를 저장하는 공간의 속도와 용량은 반비례 관계

  • 속도가 빠른 메모리일 수록 용량이 작음
  • 용량이 큰 저장장치는 속도가 느림
  • 둘다 잡기에는 비용이 너무 많이 든다
  • 그래서 데이터 저장 공간은 속도와 용량에 따라 특성에 맞게 역할을 나누어서 사용

'* > What I did today' 카테고리의 다른 글

GC  (0) 2023.01.01
static 변수는 JVM의 어디에 저장될까 ?  (0) 2022.12.25
JVM  (0) 2022.12.24
Java - static 사용의 지양  (0) 2022.12.17
서버가 죽는 이유 ,message queue  (0) 2022.07.20
AWS Certified Cloud Practitioner - 합격 후기, 참고자료 정리  (4) 2021.12.14
11/5 (함께자라기)  (1) 2021.11.06
11/03  (0) 2021.11.03

'* > What I did today' 카테고리의 다른 글

static 변수는 JVM의 어디에 저장될까 ?  (0) 2022.12.25
JVM  (0) 2022.12.24
Java - static 사용의 지양  (0) 2022.12.17
Cache  (2) 2022.12.15
AWS Certified Cloud Practitioner - 합격 후기, 참고자료 정리  (4) 2021.12.14
11/5 (함께자라기)  (1) 2021.11.06
11/03  (0) 2021.11.03
CPU를 극단적으로 사용하는 애플리케이션  (0) 2021.10.03
뱃지가 도착했다!

1. 시험 준비

준비 전 나의 상태는 비전공자, 국비 학원 프로젝트 시 EC2 INSTANCE 생성 한번, NETWORK, CLOUD 지식이 전무해서 전체적인 기초지식을 쌓아야 했다. 나처럼 기초지식 및 경험이 전무하다면 2~3주 정도 준비하면 넉넉한 것 같다..

  • 11월 말 시험 접수
  • 첫째 주 : 기본 지식 쌓기, AWS Training course, 다른 사람들 후기 찾아보기
  • 둘째 주 : 덤프 문제, 오답정리
  • 12월 14일 시험 응시 및 합격

2. 시험 후기

AWS essential course 듣고 udemy 문제 풀었을 때 정답률이 20~30%여서 좌절했는데 유데미가 너무 어려운 거였다. 그리고 aws 자격증은 무조건 영어로 공부하는 것이 좋다. 한국어 자료 중에 매끄럽지 않은 게 있어서 영어 자료들이 훨씬 직관적이고 가독성이 좋았다. 시험은 한국어로 신청 시 한국어&영어 모두 제공한다.
영어 버전으로 기출문제를 한 300문 제정도 풀었고 그중 틀린 문제들을 다시 한번 더 풀었다. 기출문제 풀이가 가장 도움이 많이 되었다. 이 시험 콘셉트가 어떤지, 어떤 부분을 강조하고 싶은지, 어떤 키워드끼리 묶어서 공부해야 하는지 감이 잡혔다. 특히 덤프 자료 중 모든 문항의 해설을 정리한 파일을 만나게 되면서 공부하는 게 굉장히 순조로워졌다. 이 자료는 아래 첨부하겠다.
12월 14일 오후 1시에 SRTC에서 시험을 봤고, 오후 8시경 합격 메일과 벳지가 도착했다! 점수는 788점.


3. 참고 자료

3-1. 기초 자료들

기초 지식이 너무 부족해서 병행했던 도서들

  • 그림으로 배우는 HTTP & NETWORK BASIC - 오에노 센 (60% 읽음..) ★★
  • 대규모 시스템 설계 기초 - 알렉스 쉬 (30%만 읽음..) ★★
  • 아마존 웹 서비스를 다루는 기술: 실무에서 필요한 AWS 클라우드의 모든 것! - 이재홍 ★★★ : 무료, 아래 링크 확인
  • AWS Cloud Practitioner Essentials ★★★★★ : 필수 COURSE

Loading

Loading your learning experience...

explore.skillbuilder.aws

http://pyrasis.com/book/TheArtOfAmazonWebServices

아마존 웹 서비스를 다루는 기술: 실무에서 필요한 AWS 클라우드의 모든 것!

pyrasis.com

3-2. 덤프 문제

덤프 문제를 제공하는 사이트가 많은데 오답이 너무 많았다. 답 헤아리는 과정이 공부였지만 정답 찾는 시간이 너무 소요되었다. 와중에 비슷한 불편함을 느낀 분이 정리해서 공유한 자료를 찾았는데 이 파일 덕분에 시험 준비가 수월했다.

덤프 사이트 ★★★

반복적이긴 하지만 시험 감잡기 좋다.
오답이 굉장히 많아서 Discussion에 논쟁수가 많다면 꼭 정답을 확인해야 한다. 이 부분을 대체한 자료를 찾았음.

Free & Accurate Amazon AWS Certified Cloud Practitioner Practice Questions | ExamTopics

www.examtopics.com

문제 정리 파일 (영어) ★★★★★

3-3. 중요 키워드 정리된 블로그

앞서 공부한 분들이 키워드를 잘 정리한 곳들

Architecting for the Cloud – AWS Best Practices – Whitepaper – Certification

Architecting for the Cloud – AWS Best Practices Architecting for the Cloud – AWS Best Practices whitepaper provides architectural patterns and advice on how to design systems that are s…

jayendrapatil.com

[AWS] AWS 자격증 준비 - Cloud Practitioner 덤프 한글 정리 노트 (CLF-C01)

* Foundational - Cloud Practitioner 시험을 준비하거나 시험 보기 전에 보면 좋은 용어와 개념 정리 * 정확한 표현보다 초보자 기준으로 가볍게 작성했으니 가볍게 정리하는데 참고하세요. 목차 1. 용어

studyingazae.tistory.com

[Practitioner] Practitioner 요약

1. 서비스 목록 서비스 종류 컴퓨팅 서비스 EC2, Auto Scaling, Lightsail, WorkSpaces 스토리지 서비스 S3, Glacier, EBS, Storage Gateway, Snowball 네트워킹 서비스 Route 53, VPC, Direct Connect, ELB 데이..

ozofweird.tistory.com



4. 기타

국비 학원에서 프로젝트 완료 후 혼자서 aws 인스턴스 생성 , 빌드 배포하면서 서버 관리에 대해 관심을 갖게 되었다. 그리고 practitioner는 기초자들도 충분히 공부할 만하다고 해서 시작했는데, 너무 기초지식이 없어서 덤프 문제 푸는 동안 좌절을 크게 했지만 반복해서 풀고 모르면 그 부분만 다시 검색해보고 또 모르면 회사 가서 선임들한테 물어보고 하니까 조금씩 키워드와 콘셉트에 익숙해졌다. 빨리 associate 공부하고 싶다!!
획득 한 사람들이 많은데 비해 한국어 자료 상태가 많이 안 좋았다. 열심히 공부해서 잘 정리된 한국어 자료를 제공하고 싶다. 이번 달에 좋은 소식이 많다. 정규직 전환 확정, practitioner 합격 그리고 my bday!
계속 좋은 일들 만들어 나가야지.. 나도 주변 사람들에게 좋은 영향을 주는 개발자가 되고 싶다..

'* > What I did today' 카테고리의 다른 글

JVM  (0) 2022.12.24
Java - static 사용의 지양  (0) 2022.12.17
Cache  (2) 2022.12.15
서버가 죽는 이유 ,message queue  (0) 2022.07.20
11/5 (함께자라기)  (1) 2021.11.06
11/03  (0) 2021.11.03
CPU를 극단적으로 사용하는 애플리케이션  (0) 2021.10.03
URL Scheme  (0) 2021.10.02

구조적인것 먼저 커밋하고 배포해서 잘되는지확인하고 완전히 끝낸뒤 세밀한것 고치기

무작정 기획서대로 코딩부터하려하고 매퍼파일 수정하려고 할때, 선임님이 서로 연관된 것들을 먼저 훑어보라고 하셨다. 당연한 얘기이기도한데, 기획서 받으면 무조건 보이는 부분부터 접근해서 코드 수정부터 하려고한다.
추상적으로 먼저 구조파악하고 틀잡는 습관을 들여야겠다.


함께 자라기

피드백을 짧은 주기로 얻는 것, 그리고 실수를 교정할 기회가 있는것
자기 개발은 복리로 돌아온다.

제 자리 걸음에서 벗어나기

Mindfulness
  1. - 지루함을 느끼는 경우 : a1 실력 낮추기 
    1.   작업의 난이도는 그대로 두고 실력을 낮추는 전략
    2.   지루하던 작업 -> 몰입하는 작업
  2. - 지루함을 느끼는 경우: a2 난이도 높이기
    1.   실력은 그대로 두고 난이도를 높이는 전략
    2.   이소룡사례
    3.   ex, 리팩터링 , 자동화테스트
    4.   남들보다 일을 좀 더 효율적/효과적으로 하기 위해 내가 직접 만들어 쓰는 나만의 도구/방법
  3. - 불안함을 느끼는 경우 : b2 실력 높이기
    1.   실력을 높여서 몰입영역으로 들어가는 전략
    2.   사회적 접근 : 짝 프로그래밍, IRC, 튜토리얼
    3.   도구적 접근 : 디버거, 자동 통합도구, 코드 분석툴 등
    4.   내관적 접근 : 비슷한 일을 했던 경험을 머릿속에서 되살려보는것 
  4. 불안함을 느끼는 경우: b1 난이도 낮추기
    1. 난이도를 낮춰서 몰입 영역으로 들어가는 전략
    2. 아기버전을 첫번째 목표로 삼기
    3. 난이도를 낮춘 결과 학습효과, 동기강화, 스트레스 감소, 자기효능감 증가 등

지속적으로 자신의 감정 상태를 살피면서 지금 지루한지 불안한지를 알아채고 만약 지루함이나 불안함을 느낀다면 앞의 네가지 전략을 적절히 사용해야한다.

함께 자라기 - 교보문고

애자일로 가는 길 | 다음 문장들을 보고 거짓이라고 생각하는 게 있으면 골라보세요.1. 일반적으로 경력이 많으면 전문성도 높다.2. 수십 년간 같은 수련을 날마다 반복하면 실력이 는다.3. 실수

www.kyobobook.co.kr

  • 싱글톤 패턴
  • hashmap과 동시성
  • run tests using 속성 : IntelliJ IDEA
  • 디렉토리구조 
  • 테스트코드

Goal

  • 컴퓨터가 어떻게 프로그램을 실행시키는 가 ?
  • 프로그램 vs 프로세스
  • CPU bound 애플리케이션 vs I/O bound 애플리케이션
  • hash연산을 위해 CPU를 극단적으로 사용하는 애플리케이션 만들기
  • GCP 인스턴스에 CPU bound 애플리케이션 수동 배포

* 컴퓨터 주요 부품들 ..

하드디스크 ,메모리, CPU

- 애플리케이션은 하드디스크에 저장 ->프로그램이라 한다.

- 하드디스크에 있는 프로그램을 실행시키면 프로그램의 내용이 메모리 위에 올라간다. -> 프로세스라 한다.

- 여러개의 프로세스가 함께 메모리에 올라가 있다.

- 그 프로세스 중 누군가는 CPU에 의해 실행된다.

- 어떤 프로세스가 실행될지 결정하는 것 : 스케줄링

 

Q. 메모리가 왜 끼어 있을까 ? 걍 하드디스크에 붙어서 전부 계산하면 되지 않나 ?

메모리가 중간에 있는 이유는 이 장치들간의 속도 차이 때문이다.

CPU는 하드디스크보다 빠르다.

CPU가 프로세스를 실행시키기 위해 하드디스크에 직접 요청하면 CPU가 아무리 빨라도 그 속도는 거의 하드디스크의 속도와 같아진다. (병목현상 발생)

그래서 중간에 속도차이를 줄여 주기 위한 메모리가 존재

메모리와 CPU간의 차이 마저 줄이기 위해 메모리보다는 빠르고 CPU보다는 느린 캐시메모리 같은 장치도 사용된다.

 

CPU는 하디스크와 직접 통신하는것은 아니지만 결국 하드디스크와 상호작용을 해야할 필요는 있다.

CPU는 다른 프로세스를 실행시킴으로써 최대한 CPU를 효율적으로 사용

 

I/O : Input / Output

프로세스가 I/O하는 동안에는 다른 프로세스가 CPU를 사용한다.

I/O종류에는 하드디스크 뿐만 아니라 DB나 네트워크에대한 I/O도 있다.

 

I/O Bust vs CPU Burst

I/O Bust : 한 프로세스 실행 도중 I/O를 하는 시간을 I/O burst라고 한다.

CPU Burst : CPU에서 실행되는 시간

 

I/O Bound application vs CPU Bound application

I/O Bound application : 해당 프로세스가 전체적으로 I/O를 많이 하는 애플리케이션

CPU Bound application : 전체적으로 CPU를 많이 사용하는 애플리케이션 

 

Q. CPU를 특별히 많이 쓰는 프로그램도 있나 ?

I/O를 적게 사용하고 CPU연산을 많이 사용하는 애플리케이션이 CPU를 많이 쓰는 프로그램

 

Hash 연산을 많이 반복하는 애플리케이션을 만들어 CPU를 많이 쓰는 프로그램만들기

-MD 5 Hash 연산

-Hash 알고리즘은 동일한 입력을 넣으면 동일한 출력이 나오는 특성이 있다. 그래서 파일내용이 변경되었는지 확인하는 무결성 검사를 위해 사용된다.

-Hash를 10만번이..

    @RequestMapping("/hash/{input}")
    public String getDigest(@PathVariable("input") String input) throws NoSuchAlgorithmException {
        for(int i = 0; i < 100_000; i++) {
            input = getMD5Digest(input);
        }
        return input;
    }

 


* 루트계정으로 모든 명령어를 실행하기 시작하면 보안상 문제가 된다

  1. 애플리케이션이 로그를 출력한다.
  2. 애플리케이션이 로그를 출력할 디렉토리가 루트 권한으로 만들어졌다.
  3. 개발자는 권한 문제 떄문에 안되네 그럼 sudo 붙여야지 하면서 루트 권한으로 실행하여 애플리케이션을 실행한다.
  4. 애플리션은 루트 권한으로 실행된다
  5. 애플리케이션에 취약점을 이용한 공격이 발생하면 애플리케이션이 아니라 시스템 전체의 권한이 해커에게 노출된다.

루트 권한을 남용하기 시작하면 위와 같은 상황이 발생하기 쉽다. 루트 권한이 아니라 모든 디렉토리와 애플리케이션에 적절한 권한을 부여하는 게 좋다.

 


* Point "어떤 프로세스는 CPU를 많이 사용하고 어떤 프로세스는 DB를 많이.. 여러 관점에서 생각해봐야한다." 

어떤 프로세스가 얼마나 많은 트래픽을 처리할 수 있을지는 측정해 보기 전에 알기 어렵다.

물리적으로 core가 1개인 서버가 초당 10만큼의 데이터를 처리 할 수 있다고해서 core가 8개인 서버는 초당 80만큼의 데이터를 처리할 수 있지않다.

보통 그보다 더 적은 효율을 보인다.

이유는 애플리케이션이 사용하는게 다양하기 때문이다.

CPU, 메모리 ,디스크, 네트워크 그리고 DB 등 여러가지 요소를 사용한다.

그래서 반드시 일정 이상의 트래픽을 받아야하는 시스템을 만들어야한다면 실제 그 트래픽을 흘려보기전까지 알 수 없다.

 


https://velog.io/@hax0r/%EC%84%A0%EC%A0%90%EB%B9%84%EC%84%A0%EC%A0%90-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81

 

프로세스 스케줄링, 그리고 기법

도커에서 프로세스 스케줄링 하다가 이전에 정처기에서 학습했던 선점/비선점 스케줄링에 대한 이해도 떨어지는 것 같아 정리할 겸 글을 남긴다.

velog.io

 

https://medium.com/@yeon22/crypto-%ED%95%B4%EC%8B%9C-hash-%EB%9E%80-6962be197523

 

(Crypto) 해시(hash)란?

해시(hash)란 단방향 암호화 기법으로 해시함수(해시 알고리즘)를 이용하여 고정된 길이의 암호화된 문자열로 바꿔버리는 것을 의미합니다.

medium.com

 

'* > What I did today' 카테고리의 다른 글

서버가 죽는 이유 ,message queue  (0) 2022.07.20
AWS Certified Cloud Practitioner - 합격 후기, 참고자료 정리  (4) 2021.12.14
11/5 (함께자라기)  (1) 2021.11.06
11/03  (0) 2021.11.03
URL Scheme  (0) 2021.10.02
JDBC / SQL Mapper / ORM / Persistence / 패러다임불일치  (0) 2021.09.26
9/23  (0) 2021.09.24
9/21  (0) 2021.09.21

URL의 https, http를 scheme 라고 한다.

크롬에서 주소창의 scheme를 보여 주지않는게 기본 설정이다.

수정할 때 만 보인다.

 

항상 보이도록하면 https때문에 오류나는 삽질을 줄일 수있다.

주소창을 우클릭 후 [항상 전체 URL 표시] 항목 체크

하면 항상 schema를 포함한 전체 URL이 표시된다.

 


URL Scheme이란?

IOS에서 어플리케이션 간 통신을 하는 방법이다.

URL scheme을 통해서 데이터를 전달하고 실행시킬 수 있다.

 

어플리케이션마다 지원할 수도 있고 아닐 수도 있다.

여러 기능들까지 지원한 경우 응용하면 다양한 기능을 구현할 수 있다.

활용 예

사파리 등의 주소창에 "calshow://"을 입력하고 enter하게 되면 캘린더가 실행된다.

 

https://victorydntmd.tistory.com/287

'* > What I did today' 카테고리의 다른 글

AWS Certified Cloud Practitioner - 합격 후기, 참고자료 정리  (4) 2021.12.14
11/5 (함께자라기)  (1) 2021.11.06
11/03  (0) 2021.11.03
CPU를 극단적으로 사용하는 애플리케이션  (0) 2021.10.03
JDBC / SQL Mapper / ORM / Persistence / 패러다임불일치  (0) 2021.09.26
9/23  (0) 2021.09.24
9/21  (0) 2021.09.21
9/20  (0) 2021.09.20

Persistence (영속성)

데이터를 생성한 프로그램이 종료되더라도 사라지지않는 데이터의 특성

기존 객체지향 애플리케이션에서 DB적용하기 전까지 객체상태는 단지 메모리에서만 존재하여 프로그램이 종료되면 그 상태를 잃어버렸다. = 영속성을 가지지않았다.
다음 프로젝트에서는 프로그램이 종료되더라도 다시 같은 상태를 가지는 객체로 만들어 내기 위해 객체의 상태를 데이터베이스에 저장했다. = 객체에게 영속성을 부여

Mark Rechards의 소프트웨어 아키텍쳐 패턴

Persistence 계층에서 도메인 모델인 객체에 영속성을 부여하는 역할을 한다.

Persistence를 언급한 이유 ?

Persistence layer를 어떻게 구현하느냐에 따라 JDBC / SQL Mapper / ORM을 비교할 수있다.

Persistence Layer 구현하는 방법

1. JDBC
2. Persistence Framework


JDBC

Java Database Connectivity
- 자바에서 데이터베이스에 접속 할 수있도록 하는 자바 API
- 자바 애플리케이션에서 DBMS에 종속적이지 않고 하나의 JDBC API를 이용해서 DB작업을 처리
- JDBC 인터페이스를 구현한 각각의 DBMS 드라이버만 갈아끼우면 어느 DB에서든 접근할 수있다.
- JDBC API를 사용할 경우 하나의 자바 응용 프로그램에서 JDBC 드라이버를 제공하는 어떤 종류의 관계형 DBMS에도 접근이 가능
- 여행할때 챙겨가는 어댑터역할


기존 프로젝트 JDBC 절차

1. 드라이버로드
2. Connection 객체생성 : DB와 연결하는 통로역할
3. Statement 객체생성 : 쿼리문 생성 및 실행
4. ResultSet : SQL의 결과물이있으면 ResultSet객체 생성 후 필요한 데이터를 얻음
5. 작업이 끝나면 반대순서로 자원해제

이것을 코드로 옮기면?

- 연결 파라미터 정의
- 연결 오픈
- SQL문 지정
- 파라미더 선언과 파라미터 값 제공
- Statement 준비와 실행
- 결과를 반복하는 루프 설정
- 각 이터레이션에 대한 작업 수행
- 모든 예외 처리
- 연결, Statement, resultset닫기

JDBC 사용 후 .. 단점

- 간단한 SQL 실행하는데도 중복된 코드 반복사용
- DB에 따라 일관성 없는 정보를 가진채로 Checked Exception(SQL Exception)처리
- Connection과 같은 공유 자원을 제대로 릴리즈(반환) 해주지 않으면서 시스템의 자원이 바닥나는 버그발생->수동으로 잡아줌


Persistence Framework

JDBC 프로그래밍의 복잡함이나 번거로움 없이 간단한 작업만으로 데이터베이스와 연동되는 시스템을 빠르게 개발

Persistence Framework종류

1. SQL Mapper
2. ORM


SQL Mapper
SQL을 직접 작성
직접 작성한 SQL문의 질의결과과 객체의 필드를 매핑하여 데이터를 객체화


JDBC만 사용했을때 ..

더보기

- 연결 파라미터 정의

- 연결 오픈

- SQL문 지정

- 파라미더 선언과 파라미터 값 제공

- Statement 준비와 실행

- 결과를 반복하는 루프 설정

- 각 이터레이션에 대한 작업 수행

- 모든 예외 처리

- 연결, Statement, resultset닫기

- 단순한 조회 기능을 위해 일일히 코드로 작성하고 객체로 반환하기 위해 resultset으로 값을받아 반환

JDBC Template 사용했을때

동일한 쿼리수행이지만 핵심적으로 해야할 작업만 해주면 나머지 JDBC Template이 해줌
- 연결 파라미터 정의
- SQL문 지정
- 파라미더 선언과 파라미터 값 제공
- 각 이터레이션에 대한 작업 수행

-> 쿼리 수행 결과와 객체의 필드 맵핑
-> JDBC에서 반복적으로 해야하는 작업들을 대신해줌
-> 실행할 SQL과 바인딩할 파라미터를 넘겨주거나 쿼리 실행결과를 어떤 객체에 넘겨받을지만 지정하면된다.

Mybatis

-반복적인 JDBC 프로그래밍을 단순화
-SQL 쿼리들을 XML 파일에 작성하여 코드와 SQL을 분리하여 관리
- 순수 JDBC만 사용하면 결과를 가져와서 객체의 인스턴스를 매핑하기 위해 많은 코드들이 필요하다. 마이바티스는 코드들을 작성하지 않아도 된다.

- 보라색 부분인 매버 인터페이스와 매핑 파일만 잘 구현하면 객체의 필드와 SQL문이 매핑된다.
- 매퍼 인터페이스 구현체는 마이바티스에서 자동생성

1. mapper태그에 namespace = 매핑할 인터페이스 경로
2. select, insert, update 등 태그에 실제 동작할 쿼리를 명시
id = 매핑할 메서드명
parameterType = 파라미터 타입
resultType = 반환 값의 타입

Mybatis 동적쿼리를 지원한다.

- 상황에 따라 분기처리를 통해 쿼리를 동적으로 만든다.
- 동적쿼리를 이용해 다이나믹한 쿼리작성이 가능

Mybatis 사용하면 ..

-자동으로 Connection 관리를 해주면서 JDBC를 사용할 때의 중복 작업 대부분을 없애준다.
-복잡한 쿼리나 다이나믹하게 변경되는 쿼리 작성이 쉽다.
-관심사 분리 : DAO로 부터 SQL문을 분리하며 코드의 간결성 및 유지보수성 향상

SQL을 직접 다룸으로 생기는 문제점 ..

- 특정 DB에 종속적으로 사용하기 쉽다.
- 테이블마다 비슷한 CRUD SQL = DAO 개발이 매우 반복되는 작업
- 테이블 필드가 변경될 시 이와 관련된 모든 DAO의 SQL문 , 객체의 필드 등 수정해야한다.
- 코드상으로 SQL과 JDBC API를 분리했어도 논리적으로 강한 의존성을 가지고 있다.

-> DB에 종속적이지 않기위함이 JDBC의 컨셉이었으나 사용하는 쿼리 문법이나 데이터 타입은 DB마다 조금씩 다르고 쿼리문에 직접 작성할 경우 특정 DB에 종속된다
-> DAO를 열어서 어떤 SQL이 실행되는지 확인하고 수정해야함..

관계형 DB와 객체간의 패러다임 불일치


패러다임 불일치 문제

객체지향 RDB
추상화, 상속, 다형성 데이터 중심의 구조

각각 지향하는 목적이 다르기 때문에 사용방법과 표현방식에 차이가 생긴다
- RDB 테이블은 객체의 상속개념이없다.
- 공통부분을 슈퍼타입으로 묶고 서브타입에서 공통으로부터 상속받아 다른 엔티티와 차이가 있는 속성을 가짐
- 객체는 참조를 사용해 다른 객체와 연간관계 가짐
- 테이블은 외래키를 사용해 다른 테이블과 연관관계 가짐
- 만약 객체를 테이블 연관관계에 맞춰 모델링하면 객체지향 특징을 버린다. (테이블에서 저장하거나 조회할때는 편리하지만 ..)
- 객체지향 모델링하면 CRUD 에 어려움


ORM

Object Relational Mapping
객체와 관계형 DB를 맵핑
SQL Query가 아닌 직관적인 코드로 데이터 조작
- 객체간의 관계를 바탕으로 SQL문을 자동으로 생성하고 직관적인 메서드로 데이터를 조작

JPA

현재 자바 진영의 ORM에 대한 API 표준 명세

객체의 참조로 연관관계 저장 가능

ORM 장단점

장점 단점
패러다임 불일치 문제 해결
객체지향언어의 장점을 활용 할 수있다.
복잡한 쿼리 사용이 어려움
JPA에서는 SQL과 유사한 기술인 JPQL 지원
물론 SQL 자체 쿼리를 작성할 수 있도록 지원
SQL Mapper와 혼용사용 가능
생산성
반복적인 CRUD용 SQL을 작성할 필요 X
성능이슈
데이터 접근 추상화, 벤더 독립성
데이터 베이스 벤더마다 조금씩 다른 데이터 타입 , SQL을 손쉽게 해결
높은 러닝커브
유지보수
필드추가, 삭제시 관련 CRUD 쿼리를 직접 수정하지않고 엔티티만수정
 

ORM은 객체와 RDB 두 기둥위에 있는 기술
객체지향스럽게 코드를 작성하고 싶은데 DB가 관계DB일 경우 객체지향스럽게 쓸 수 없다. 왜냐면 중간에 매핑하기가 힘들다. 객체를 쿼리로 바꾸기 등..ORM이라는 기술을 쓰면 그 간극을 프레임워크가 메워준다.
좀 더 객체지향적인 코드 작성이 가능 그런데 이런것은 이론적인 내용이다.
실무에서는 기승전 DB이다. 장애의 90%는 DB에서 발생한다.
성능의 90% DB에서 발생한다. 웹어플리케이션, 서버어플리케이션은 데이터 중심적인 과제들을 수행하는게 많다. ->데이터를 얼마나 빨리 조회하고 얼마나 잘 저장하느냐, 안전하게 보관하느냐가 중요하다.
시간이 지나면 자바,객체가 없어지고 데이터는 안안없어진다.
자바가 스칼라,코틀린, 타입스크립트 등으로 바뀔 수 있다.
근데 관계형DB가 바뀔 확률은 훨씬 낮다.
그래서 관계형DB를 잘 다루는것이 중요하다.

관계형 DB를 설계할 줄 알고 객체지향 설계를 할 줄 알아야 ORM을 쓸 수 가있다.
RDB에 대해 깊게 공부하고 객체에 대해 잘알고서 ORM을 써야한다.
관계형 DB 열심히 하기 .. 시간이 갈 수록 더 중요해질것..
관계형DB,객체를 잘 숙지 한뒤에 그 위에 ORM얹어서 공부하기

'* > What I did today' 카테고리의 다른 글

11/5 (함께자라기)  (1) 2021.11.06
11/03  (0) 2021.11.03
CPU를 극단적으로 사용하는 애플리케이션  (0) 2021.10.03
URL Scheme  (0) 2021.10.02
9/23  (0) 2021.09.24
9/21  (0) 2021.09.21
9/20  (0) 2021.09.20
09/13  (0) 2021.09.13

*프로그래밍 언어 활용

-데이터 입출력

-제어문

-포인터

-Java의 클래스

-Python 활용

 

*스프링 핵심 원리

-싱글톤 컨테이너

-컴포넌트 스캔

 

 

+

스프링 보안, 리눅스 기본 명령어좀 정리해야겠다..

 

'* > What I did today' 카테고리의 다른 글

11/03  (0) 2021.11.03
CPU를 극단적으로 사용하는 애플리케이션  (0) 2021.10.03
URL Scheme  (0) 2021.10.02
JDBC / SQL Mapper / ORM / Persistence / 패러다임불일치  (0) 2021.09.26
9/21  (0) 2021.09.21
9/20  (0) 2021.09.20
09/13  (0) 2021.09.13
9/10  (0) 2021.09.10

* SQL 응용

-DDL

 

* 스프링 핵심원리

-싱글톤 패턴

-싱글톤 컨테이너

 

* isEqualsTo vs isSameAS 

'* > What I did today' 카테고리의 다른 글

CPU를 극단적으로 사용하는 애플리케이션  (0) 2021.10.03
URL Scheme  (0) 2021.10.02
JDBC / SQL Mapper / ORM / Persistence / 패러다임불일치  (0) 2021.09.26
9/23  (0) 2021.09.24
9/20  (0) 2021.09.20
09/13  (0) 2021.09.13
9/10  (0) 2021.09.10
Docker : GCP VM / image / External IP  (0) 2021.09.10

+ Recent posts