분류 전체보기
[시스템 프로그래밍] Malloc Lab Explicit (1)
[시스템 프로그래밍] Malloc Lab Explicit (1)
2023.01.14explicit 방식은 implicit 방식의 단점을 보완한다. 가용블록을 위와 같이 디자인한다. header 4바이트 / pred + succ 16바이트 / footer 4바이트로 총 24바이트의 크기를 가진다. pred와 succ 포인터를 통해 힙 공간 중 가용 가능한 공간들만 linked list 형태로 관리하는 방식을 사용한다. 할당된 블록은 위와 같이 디자인한다. (implicit과 동일) 가용 가능 블록들에 대해서는 prev와 succ포인터를 추가해야 해서 메모리를 조금 더 사용해야 하지만 그만큼의 이점이 있다. implicit 방식으로 first fit을 구현할 때는 최악의 경우 전체 블록을 모두 조사해야 가용 블록을 찾을 수 있지만, explicit 방식을 사용하면 조사 대상을 전체 블록 ..
[시스템 프로그래밍] Malloc Lab Implicit (2)
[시스템 프로그래밍] Malloc Lab Implicit (2)
2023.01.116. coalesce() 함수 구현 사용하는 이유는 위에서 살펴봤고.. 바로 구현해보자. 1. 이전 블록과 다음 불록이 모두 할당 된 상태 -> 합칠 수 없으니 그대로 반환한다. 2. 다음 블록이 가용 상태 -> 다음 블록과 합치고 반환한다. 3. 이전 블록이 가용 상태 -> 이전 블록과 합치고 반환한다. 4. 이전과 다음 모두 가용 상태 -> 둘 모두 합치고 반환한다. extend_heap 함수를 사용할 때 coalesce 함수를 호출하도록 설정했다. 다시 한 번 테스트 해 보자. 점수가 정말 낮지만 오류는 발생하지 않았다. 가용 블록을 합치지 않아 크기가 제대로 정렬되지 않았다고 생각한 게 맞았나보다. 이제 성능을 끌어올려보자. 7. place 함수 수정 place 함수로 블록을 할당할 때 할당할 크..
[QueryDSL] 활용 (Spring Data JPA + QueryDSL)
[QueryDSL] 활용 (Spring Data JPA + QueryDSL)
2023.01.11웬만한 기능은 Spring Data JPA가 제공해주고, 동적 쿼리 등 복잡한 구현이 필요할 때 QueryDSL 기술을 사용한다. 따로 Repository를 하나 만들어서 기능을 구현하자. MemberRepositoryCustom을 인터페이스로 만들고 구현할 기능을 선언한 후 MemerRepositoryImpl에 기능을 구현한다. public class MemberRepositoryImpl implements MemberRepositoryCustom { private final JPAQueryFactory queryFactory; public MemberRepositoryImpl(EntityManager em) { this.queryFactory = new JPAQueryFactory(em); } @Ov..
[QueryDSL] 활용 (JPA + QueryDSL)
[QueryDSL] 활용 (JPA + QueryDSL)
2023.01.11실제로 애플리케이션을 설계할 때는 Repository 계층을 만들고 Repository를 통해 데이터베이스와 상호작용한다. 먼저 Spring Data JPA 기술 없이 순수 JPA와 QueryDSL 만 사용해서 Repository를 설계해보자. @Repository public class MemberJpaRepository { private final EntityManager em; private final JPAQueryFactory queryFactory; public MemberJpaRepository(EntityManager em) { this.em = em; this.queryFactory = new JPAQueryFactory(em); } public void save(Member member..
[시스템 프로그래밍] Malloc Lab Implicit (1)
[시스템 프로그래밍] Malloc Lab Implicit (1)
2023.01.10이론에서 배운 것들을 활용해 Malloc Lab을 해결해보자. WSIZE : 메모리 블록의 header와 footer 크기이다. (word 크기) DSIZE : WSIZE의 두 배 크기. CHUNKSIZE : 초기 가용 블록의 크기와 힙을 확장할 때 사용되는 값이다. OVERHEAD : header와 footer를 더한 크기이다. MAX, MIN : 말 그대로.. 두 수를 비교한다. PACK : 크기(size)와 할당 비트(alloc)을 통합해 하나의 워드로 묶는다. header와 footer에 값을 저장 할 때 사용한다. GET : 포인터 p가 가리키는 위치에서 word 크기의 값을 읽어온다. PUT : 포인터 p가 가리키는 위치에서 word 크기의 값을 val 만큼 쓴다. GET_SIZE : head..
[QueryDSL] 중급 문법
[QueryDSL] 중급 문법
2023.01.101. 프로젝션 프로젝션 대상이 하나인 경우 대상 타입을 명확하게 지정할 수 있다. 제네릭스를 String으로 설정하고 값을 받아온다. (객체도 가능) 프로젝션 대상이 둘 이상인 경우 QueryDSL이 제공하는 Tuple 자료구조나 DTO를 따로 정의해서 반환값을 가져올 수 있다. 왼쪽은 Tuple을 사용하는 예시이다. 일단은 Tuple도 QueryDSL에 종속적인 타입이기 때문에, 바깥 계층으로 반환될 때를 생각하면 DTO를 사용하는 편이 합리적이다. (Repository 내부에서만 사용하는 경우는 괜찮다) JPA를 사용할 때 DTO를 따로 정의해서 반환값을 가져오려면 new 명령어를 사용해 DTO의 생성자를 호출하는 방식을 사용해야 한다. QueryDSL 기술을 사용하면 좀 더 간단하게 처리할 수 있다..
[QueryDSL] 기본 문법
[QueryDSL] 기본 문법
2023.01.09QueryDSL은 Query Domain Specific Language의 약자로 간단하게 JPQL을 만들어주는 역할을 한다고 생각하면 된다. @Test public void startJPQL() { String qlString = "select m from Member m " + "where m.username = :username"; Member findMember = em.createQuery(qlString, Member.class) .setParameter("username", "member1") .getSingleResult(); assertThat(findMember.getUsername()).isEqualTo("member1"); } @Test public void startQuerydsl..
[Spring Data JPA] 내부 동작 원리
[Spring Data JPA] 내부 동작 원리
2023.01.03Spring Data JPA 기술이 제공하는 공통 인터페이스의 구현체를 살펴보자. SimpleJpaRepository 클래스가 공통 인터페이스를 구현한다. @Repository 애너테이션이 붙어있다. 따라서 Spring의 Component Scan의 대상이 되고, 특정 계층에서 예외가 터진 경우 Spring이 다루기 쉬운 예외로 변환한다. 덕분에 구현 기술을 바꾸더라도 기존 기술에 영향을 주지 않는다. @Transaction 애너테이션도 붙어있다. 모든 데이터의 변경은 Transaction 내부에서 진행되어야 한다. Spring Data JPA는 기본으로 제공하는 기능에 모두 @Transaction 애너테이션을 붙이기 때문에 개발자가 좀 더 편하게 개발할 수 있다. 단순히 조회만 하는 작업에서 @Tran..
[Spring Data JPA] 사용자 정의 리포지토리와 확장 기능
[Spring Data JPA] 사용자 정의 리포지토리와 확장 기능
2023.01.03Spring Data JPA 가 제공하는 기능을 사용하면 개발이 생산성이 증가하지만, 상황에 따라 특정 기능은 Spring Data JPA가 제공하는 방법 대신 다른 방법을 사용해야 하는 경우가 생긴다. (JPA를 직접 사용한다던가, MyBatis를 사용한다던가...) 이럴 때는 어떻게 해야 할까? Spring Data JPA는 이런 경우 Custom Repository를 사용할 수 있도록 한다. 사용자가 직접 인터페이스를 만들고, 필요한 기능을 원하는 방법으로 구현한 후 Spring Data JPA와 합치는 방식으로 문제를 해결한다. MemberRepositoryCustom에 구현하려는 기능을 선언하고, MemberRepositoryImpl에서 기능을 구현한다. (둘 다 인터페이스이다) 이후 JpaRe..
[백준] 9486 이름 남기기 - C++
[백준] 9486 이름 남기기 - C++
2023.01.03N이 적당히 작으니 비트필드를 사용할 수 있다. dp[status][cur] = 현재 입력을 완료한 상태는 status이고 지금은 cur번째 문자를 입력하고 있을 때의 최소 클릭 횟수 위와 같이 dp 배열을 정의하자. 재귀함수는 두 가지 케이스로 나뉜다. 1. 아무것도 입력하지 않은 경우 2. 뭔가 입력된 상태 아무것도 입력하지 않은 경우 문자는 A부터 시작하고, 어떤 문자부터 입력해야 최소 횟수를 반환하는지 알 수 없으니 모든 경우를 살펴봐야 한다. 뭔가 입력된 상태에서는 왼쪽 혹은 오른쪽으로 이동하는 경우도 추가로 생각해 줘야 하고, 이전에 입력한 문자부터 시작되는 부분을 고려해야 한다. 최소 횟수를 구하는 문제이니 INF를 적당히 설정해 주자. #include #include #include #in..
[Spring Data JPA] 벌크 연산과 EntityGraph
[Spring Data JPA] 벌크 연산과 EntityGraph
2023.01.02JPA를 공부할 때 배웠듯, 한 번에 여러 데이터들을 한 번에 수정하는 경우 벌크 연산을 사용한다. Spring Data JPA에서 벌크성 수정 쿼리를 작성할 때는 @Modifying 애너테이션이 붙는다. 벌크 연산은 영속성 컨텍스트를 무시하고 바로 데이터베이스에 쿼리를 보내기 때문에 영속성 컨텍스트로 관리되는 엔티티의 상태와 데이터베이스에 저장된 데이터가 서로 일치하지 않는 경우가 발생할 수 있다. 따라서 벌크 연산을 수행한 이후 flush와 clear함수를 실행해 영속성 컨텍스를 초기화 하는 방법을 사용하자. @Modifying(clearAutomatically = true) 로 설정하면 해당 애너테이션이 붙은 메서드가 실행된 후 영속성 컨텍스트가 자동으로 초기화된다. Spring Data JPA에서..
[Spring Data JPA] 쿼리 메서드와 페이징
[Spring Data JPA] 쿼리 메서드와 페이징
2023.01.02Spring Data JPA 기술을 사용해 회원의 이름과 나이를 기준으로 조회하는 기능을 구현한다고 생각해보자. 공통으로 제공하는 메서드가 아니기 때문에 별도로 처리해 줘야 하는데, 이 때 쿼리 메서드 기능을 사용하면 매우 편하게 처리할 수 있다. 쿼리 메서드를 사용하면 이전처럼 JPQL을 하나하나 작성하지 않아도 된다. 쿼리 메서드는 메서드의 이름을 바탕으로 JPQL을 만들어주는 기술이다. 위와 같이 메서드의 이름을 적절하게 작성하고 매개변수를 설정하면 직관적으로 어떤 JPQL이 만들어지는지 유추할 수 있따. 이 때 아무 이름이나 사용하면 안 되고, 관례가 있다. 이름에 사용되는 관례는 (https://docs.spring.io/spring-data/jpa/docs/current/reference/ht..