목록전체 글 (52)
효습
데이터베이스의 성능 튜닝은 어떻게 디스크 I/O를 줄이느냐가 관전일 때가 많다. 디스크 읽기 방식 랜덤 I/O 와 순차 I/O랜덤 I/O : 하드 디스크 드라이브의 플래터(원판)을 돌려서 읽어야 할 데이터가 저장된 위치로 디스크 헤더를 이동시킨 다음 데이터를 읽는 것순차 I/O : 랜덤 I/O와 작업 과정은 동일하지만, 디스크의 헤더 위치 이동에서 차이를 보인다.디스크의 성능은 디스크 헤더의 위치 이동 없이 얼마나 많은 데이터를 한 번에 기록하느냐에 의해 결정된다.여러 번 쓰기 또는 읽기를 요청하는 랜덤 I/O 작업이 작업 부하가 훨씬 더 크다.데이터베이스 대부분의 작업은 이러한 작은 데이터를 빈번히 읽고 쓰기 때문에 MySQL 서버에는 그룹 커밋이나 바이너리 로그 버퍼 또는 InnoDB 로그 버퍼 등의..
얼마 전에 진행한 프로젝트에서 기획자분이 데이터를 몇 개씩 나눠서 조회할 수 있으면 좋겠다고 말씀하셨다. 그래서 페이지네이션을 적용하는 것이 적절하다고 판단했고, 커서 기반 페이지네이션(Cursor-based Pagination)을 적용했다. 커서 페이지네이션을 적용하면서 QueryDsl도 함께 사용했다. 다만, 반드시 함께 써야 하는 것은 아니다. 나는 커서 값을 생성 시각(created_at)과 id(pk)를 함께 사용했는데, 이러한 복합 조건을 타입 안전하게 처리하기 위해 QueryDsl을 선택하게 되었다. https://velog.io/@znftm97/%EC%BB%A4%EC%84%9C-%EA%B8%B0%EB%B0%98-%ED%8E%98%EC%9D%B4%EC%A7%80%EB%84%A4%EC%9D..
테스트가 어려운 코드모든 코드를 테스트할 수 있는 것은 아니다.어떻게 하면 테스트 가능하게 바꿀 수 있는지 알아보자 하드 코딩된 경로결제 대행업체가 결제 내역이 유효한지 확인할 수 있도록 익일 오전에 결제 결과를 파일로 제공한다고 하자이 파일을 읽어와 DB에 결제 내역을 반영하는 코드는 아래와 같이 작성할 수 있다public class PaySync { private PayInfoDao payInfoDao = new PayInfoDao(); public void sync() throws IOException { Path path = Paths.get("D:\\data\\pay\\cp0001.csv"); List payInfos = Files.lines(path) ..
대역의 필요성테스트를 작성하다 보면 외부 요인이 필요한 시점이 있다.테스트 대상이 파일 시스템을 사용테스트 대상에서 DB로부터 데이터를 조회하거나 데이터를 추가테스트 대상에서 외부의 HTTP 서버와의 통신 테스트 대상이 이런 외부 요인에 의존하면 테스트를 작성하고 실행하기 어려워진다.TDD는 테스트 작성 -> 통과시킬 만큼 구현 -> 리팩토링 의 과정을 짧은 흐름으로 반복해야하는데 외부와 통신이 되지 않으면 테스트를 진행할 수 없게 된다.외부 요인 때문에 테스트가 어려울 때는 대역을 써서 테스트를 진행할 수 있음test double : 테스트에서 대신 사용할 대역대역에는 스텁 , 가짜 , 스파이 , 모의객체가 존재 대역을 이용한 테스트외부 API를 이용하여 카드 번호가 유효한지 검사하는 CardNum..
테스트 코드의 구성 요소 : 상황 , 실행 , 결과 확인 기능은 상황에 따라 결과가 달라진다.테스트 코드는 기능을 실행하고 그 결과를 확인하므로 상황(given) , 실행(when) , 결과 확인(then)의 세가지 요소로 테스트를 구성할 수 있다.어떠한 상황이 주어지고그 상황에서 기능을 실행하고실행한 결과를 확인 @Testvoid exactMatch(){ //정답이 456인 상황 BaseballGame game = new BaseballGame("456"); //실행 Score score = game.guess("456"); // 결과 확인 assertEquals(3 , score.strikes()); assertEquals(0 , score.balls());}@Testvoid..
JUnit 5 모듈 구성JUnit 5는 크게 세 개의 요소로 구성되어 있다JUnit 플랫폼 : 테스팅 프레임워크를 구동하기 위한 런처와 테스트 엔진을 위한 API를 제공한다.JUnit 주피터 (Jupiter) : JUnit 5를 위한 테스트 API와 실행 엔진을 제공한다.JUnit 빈티지 (Vintage) : JUnit 3과 4로 작성된 테스트를 JUnit 5 플랫폼에서 실행하기 위한 모듈을 제공한다. junit-jupiter 모듈은 junit-jupiter-api 모듈 , junit-jupiter-params 모듈 , junit-jupiter-engine 모듈을 포함 JUnit 5를 이용해서 테스트를 실행하려면 JUnit 5 플랫폼이 제공하는 플랫폼 런처를 사용해야한다. @Test 어노테이션을 붙인..
설계는 기능 명세로부터 시작한다기능 명세를 구체화하는 동안 입력과 결과를 도출하고 이렇게 도출한 기능 명세를 코드에 반영한다기능의 이름 , 파라미터 , 리턴 타입 지정 설계 과정을 지원하는 TDD테스트 코드를 만들기 위해서는테스트할 기능을 실행실행 결과를 검증→ 테스트 대상이 되는 클래스와 메서드의 이름을 결정해야한다.→ 메서드를 실행할 때 사용할 인자의 타입과 개수를 결정해야한다. 설계 과정클래스 이름메서드 이름메서드 파라미터실행 결과TDD 자체가 설계는 아니지만 , TDD를 하다 보면 테스트 코드를 작성하는 과정에서 일부 설계를 진행하게 된다. 필요한 만큼 설계하기TDD는 테스트를 통과할 만큼만 코드를 작성한다필요할 것으로 예측해서 미리 코드를 만들지 않는다TDD로 개발하는 코드 비율이 높아질수..
Polling클라이언트가 서버로부터 정기적으로 알림 조회 요청을 보내서 데이터를 받아오는 방식이다. 그런데 웹이나 앱을 사용하다보면 알림 페이지에 있지 않아도 실시간으로 알림이 오는데 이걸 어떻게 구현할까?하고찾아보니까 SSE(Server-Sent Events) 라는 기술이 있었다. 먼저 SSE에 대해 알아보자 SSE(Server-Sent-Events) 클라이언트와 서버가 한번 연결을 맺고 나면 일정 시간동안 변경이 일어난 데이터에 대해 서버에서 전송 받는 방식이다.SSE는 서버에서 클라이언트로 text message를 보내는 브라우저 기반 웹 애플리케이션 기술이며 HTTP의 persistent connections을 기반으로하는 HTML5 표준 기술이다. 알림 기능 구현하기 Notifica..
Starting MySQL. ERROR! The server quit without updating PID file (/opt/homebrew/var/mysql/user.local.pid). mysql.server start 하다가 저런 에러가 날 수 있다 보통 삭제하고 다시 설치하면 다시 정상 작동한다 하지만 난 Mysql 데이터 파일(ibdata1) 없었다 .근데 ibdata1이 없으면 InnoDB 엔진이 mysql 서버를 실행시키지 못함몇 번을 다시 깔아도 없길래 캐시 삭제를 시도함 (근데 보통 저 파일은 mysql을 설치하면 다시 생기기때문에 mysql 을 삭제하고 다시 설치하면 해결된다근데 난 안생겼음 몇 번을 다시 깔아도 안생김 ) 그럼 뭐가 문제냐?mysql 설정 파일 , 캐시 파일이 ..
프로젝트 중에 스마트 워크 센터를 검색을 구현하는 api를 담당했다.처음에 검색 요소가 이름 , 태그 2개인 줄 알고검색어가 없는 경우, 1개가 들어오는 경우 , 2개가 들어오는 경우 생각해서 메서드를 4개를 만드려고 했다. 이렇게 코드 짤 때가 너무 비효율적인 것 같다고 생각했는데 알고보니 지역구까지 해서 검색 요소가 3개인 것이다! 3개면 만들어야하는 메서드가 6개다.물론 만들수는 있지그런데 더 좋은 방법이 있는데 그걸 선택하지 않을 이유는 없다 예전에 살짝 공부한 적이 있는 QueryDSL이 떠올라 한번 적용해보기로 했다 Dependencies 추가 //QueryDsl implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' annotati..