전체 글 361

Java - 실수하기 쉬운 메모리 누수의 5가지 패턴!

메모리 누수(Leak) 자바에서 메모리 누수는 더 이상 사용되지 않는 객체들이 GC(가비지 컬렉션)에 의해 소멸되지 않고 누적되는 현상입니다. 가비지 컬렉션의 소멸 대상이 되려면 다른 Reference 변수에서 참조하고 있지 않아야 합니다. Miner GC MinerGC는 Young 영역에 오래 되지 않은 객체를 사용이 끝나면 소멸합니다. 소요시간은 Young 영역의 크기에 따라 다르지만, 대체로 1초 미만입니다. JVM을 중지하지도 않고, 빠르고 효율적으로 동작합니다. 객체가 사용이 끝나면 Miner GC에서 정리되는 것이 유리합니다. Major GC Miner GC에서 정리되지 못하고, 객체가 오래되면 Young영역에서 Old영역으로 이동됩니다. Major GC는 Old영역의 객체를 소멸하는 역할을 ..

Language/Java 2022.04.15

Controller, Service, Repository를 Static으로 하지 않는 이유!!

Static class ? 어제 레거시 프로젝트를 받아서 기능 개선을 진행하게 되었습니다. 코드가 조금 신기했던게, Controller, Service, Repository가 정적 클래스(class)로 되어 있었습니다. Controller에서 Service의 메소드를 호출할 때 Service.method() 형식으로 호출하고 인스턴스를 생성하지 않는 방법입니다. Why? 정적 클래스(Static class)로 사용하면 어차피 재사용하게되고, 큰 문제는 없지 않나? 싶었습니다. 실제로 99%의 MVC 메서드는 정적으로 사용할 수 있다고 합니다. 그렇다면 왜 정적 클래스를 사용하지 않고, 싱글톤(Singleton)으로 instance를 만들어서 사용할까요? DI(의존성 주입) 정적 클래스는 상태를 가지지 않..

Spring Data JPA - JpaRepository 구현체에 @Transactional(readOnly = true)가 있는 이유

JpaRepository Spring Data JPA를 사용할 때 JpaRepository를 상속하는 interface를 만들어서 사용합니다. public interface MemberRepository extends JpaRepository { } 우리는 interface를 상속했을 뿐인데, findAll() 같은 다양한 CRUD 메서드를 사용할 수 있습니다. memberRepository.findAll(); Spring Data JPA는 내부적으로 JpaRepository를 상속하기만 해도 아래와 같은 구현체를 생성해주기 때문입니다. @Repository @Transactional(readOnly = true) public class SimpleJpaRepository implements JpaRep..

Server/Spring JPA 2022.04.10

Spring Data JPA - Bulk Update(일괄 수정)할 때 주의할 점! [영속성 컨텍스트]

Bulk Update JPA에서는 변경 감지를 통해 엔터티를 수정할 수 있지만, 그러면 각 엔터티별로 쿼리가 나가게 됩니다. 그래서 변경할 레코드들의 SET 절이 동일하다면 일괄 수정을 하는 것이 좋습니다. 가령, 만약 모든 사용자에게 10000원의 리워드를 제공하겠다고 하면 1개의 쿼리로 전체 업데이트를 할 수 있습니다. UPDATE user SET point = point + 10000; @Modifying Spring Data JPA에서는 벌크 업데이트를 위해서 Modifying 애노테이션을 사용해야 합니다. SpringDataJPA가 해당 리포지토리 메소드가 SELECT문인지 UPDATE문인지 알아야 Return Type을 결정하는데, 아직은 내부적으로 Query만 보고 판단을 못해서, 명시를 해..

Server/Spring JPA 2022.04.08

Spring Data JPA - Named query 정리 (+ @Query) !!

Spring Data JPA Named query Repository에서 SQL문을 직접 작성할 떄는 JPA의 Named query라는 것을 사용할 수 있습니다.\ Named query의 사용 방법과 장단점에 대해서 알아보겠습니다. @NamedQuery JPA에서는 NamedQuery라는 것을 제공하는데, 엔터티에 @NamedQuery 애노테이션을 사용해서 name과 query를 지정합니다. @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @NamedQuery( name = "User.findByUseranme", query = "select u from User u where u.username = :username" ) public class ..

Server/Spring JPA 2022.04.08

Java - Concurrent Programming (Runnable, Executor, Callable, Future 등)

자바 Concurrent 프로그래밍 Concurrent S/W란 동시에 여러 작업을 할 수 있는 소프트웨어를 말합니다. 예를 들어, 크롬에서 무언가를 다운로드할 때 PC가 멈춰있는 게 아니라, 다른 작업을 병행할 수 있습니다. 자바에서는 멀티 프로세싱과 멀티쓰레드를 지원합니다. 우리가 잘 아는 스프링도 자바의 멀티쓰레드를 이용해서 많은 사용자들의 요청을 동시다발적으로 처리합니다. Thread Thread를 상속하면 새로운 Thread 클래스를 새롭게 정의할 수 있습니다. public class Main { public static void main(String[] args) { HelloThread helloThread = new HelloThread(); helloThread.start(); } sta..

Language/Java 2022.04.03

REST API - Bulk delete 설계하는 방법!

Bulk delete REST API에서 리소스의 id array를 사용해서 Bulk delete를 해야할 때 어떻게 하면 좋을까요? 저의 경우 DELETE /resources 로 요청을 보내고, Body에 { ids: [] } 형식의 데이터를 넣어주면 안되는지 생각했었습니다. Data의 위치 그런데, DELETE에서 Body에 데이터를 담는 것이 바람직한 방법이 아니라고 합니다. 왜냐하면, 일반적으로 HTTP 메소드를 사용할 때 데이터 위치는 아래와 같습니다. GET, DELETE => header에 데이터 포함 POST, PUT => body에 데이터 포함 그래서, 클라이언트나 라이브러리, 미들웨어 등에서 이를 지원하지 않는 경우도 있기 때문에 나중에 문제를 일으키기 쉽습니다. 방법 1 첫 번째 방법..

Operation/Rest API 2022.03.30

HTTP - 청크 인코딩(Transfer-encoding: chunked) [Size가 큰 테이블, 이미지 등 내려주기]

Transfer-encoding: chunked Chunked 인코딩 전송방식은 HTTP 1.1에서 사용가능한 스트리밍 데이터 전송 방식입니다. 청크 전송 방식의 특징은 아래와 같습니다. 데이터를 여러 개의 청크 단위로 쪼개서 순차적으로 전송 각 청크는 독립적으로 송수신 됨 각 청크의 앞에는 해당 청크의 Size(16진수)를 설정해서 보냄 길이가 0인 청크가 수신되면 전송이 종료됨 청크 전송 방식의 장점 큰 데이터 전송에도 HTTP 연결이 중간에 끊어지지 않게 유지할 수 있음. Content-Length가 필요 없음 -> 크기가 가변적인 데이터 전송에 유리 전체 컨텐츠를 생성할 때까지 대기하지 않음 HTTP 1.1부터는 기본적으로 연결 유지(Connection: keep-alive)가 활성화되어있습니다...

Operation/Network 2022.03.28

git reset을 사용하면 안되는 이유 (Reset vs Revert)

Reset vs Revert 저는 개인 프로젝트를 진행할 때 커밋 로그를 더 깔끔하게 남기기 위해서 git reset --SOFT {Head~N}, git push {branch} --force를 많이 사용합니다. 예를 들어, 원격 마스터 브랜치에 잘못된 내용 또는 완벽하지 않은 단위의 커밋을 했다고 가정합시다. 이를 고치는 커밋을 연달아서 남기면 좋은 이력이 남지 못합니다. 그래서 Reset & Push 를 해서 완벽한 단위의 커밋으로 수정하고자 하는 것이죠. 왜 현업에서는 이를 사용해서는 안되는지 말씀드려보겠습니다. git push origin master --force 사실 git reset은 절대 나쁜 것이 아닙니다. reset은 로컬에 있는 변경점을 수정하는 것 뿐이기 때문입니다. 문제는 강제 ..

카테고리 없음 2022.03.28

Java - Arrays.asList vs List.of 차이 (완벽 정리)!

Arrays.asList() / List.of 자바에서 Array를 List으로 변환하기 위해서는 Arrays.asList(array)를 사용합니다. Java 9 버전 부터는 List.of(array)라는 새로운 팩토리 메소드를 도입했습니다. 차이점은 무엇일까요 ? 뭐가 좋은 걸까? 변경 가능 여부 (Mutable / Immutable) Arrays.asList()로 반환된 list는 변경이 가능합니다. 하지만, List.of()에서 반환된 메서드는 변경이 불가능합니다. List list = Arrays.asList(1, 2, null); list.set(1, 10); // OK List list = List.of(1, 2, 3); list.set(1, 10); // Fails with Unsupport..

Language/Java 2022.03.27