전체 글

저의 생각과 경험을 쉽고 재미있게 공유해요 📖
오늘은 회사에서 사용하는 업무 툴을 좀 더 효율적으로 활용할 수 있는 방법에 대해 고민한 것을 공유하려고 해요. 저희 회사에서는 Jira로 이슈를 관리하고, Github으로 코드 형상 관리를, 그리고 Notion으로 릴리즈 노트를 작성하고 있어요. 보통 깃헙 배포 브랜치에 푸쉬한 내용을 가지고 노션에 릴리즈 노트를 작성하고, 관련된 지라 이슈도 언급해주곤 했어요. 격주로 하는 배포 때마다 이 작업을 반복해 왔는데, 문득 이걸 자동화할 수 없을까 하는 생각이 들더라고요. 조금만 시간을 투자하면 반복적이고 지루한 작업을 자동화할 수 있을 것 같았거든요. 우선 모듈마다 각각 다른 노션 데이터베이스를 사용하고 있었어요. 노션의 데이터베이스 기능을 활용하기 위해 일부러 나눈 것은 아니었던 것 같아요. 그냥 엑셀..
우리가 컴퓨터를 키면 마우스로 커서를 움직이고, 크롬을 열어서 구글 검색도 하고,카카오톡으로 업무를 보기도 하죠? 이 모든 개별적인 프로그램들이 바로 프로세스라고 할 수 있어요. 사실 프로그램과 프로세스는 조금 다른 개념이에요. 프로그램은 개발자가 만든 코드들을 잘 포장해서 우리가 사용할 수 있도록 준비해 놓은 실행 파일이라고 보시면 돼요. 크롬이나 카카오톡을 다운받은 그 파일이 바로 프로그램인 거죠. 그런데 이 프로그램을 실행시키면, 바로 프로세스라는 개념이 등장해요. 프로그램 아이콘을 더블 클릭하면 운영체제가 이 프로그램을 실행할 수 있도록 준비를 해주는데, 디스크에 저장된 프로그램을 메모리에 올리고 프로세스를 생성하는 거예요. 이렇게 컴퓨터에는 다양한 프로세스들이 메모리에 올라오게 되는데, 운영체제..
문제 발견 와탭은 자체 서비스를 모니터링하는 데에도 물론 와탭 제품을 사용합니다. 와탭에서 제공하는 다양한 모니터링 도구들 중에서 아래 트랜잭션 히트맵은 실시간으로 애플리케이션 트랜잭션 상태를 추적할 수 있습니다. 간단히 빨간색이면 문제가 있는 것이고 파란색은 문제가 없다는 것을 뜻해요. 어느날 이 히트맵 트랜잭션을 통해 특정 시간대에 응답 시간이 비정상적으로 길어진 것을 감지했고, OOM으로 인해 서버가 재기동된 것까지 확인이 되었었습니다. 위 이미지는 와탭 공식 문서에 있는 예시 화면이고요. 저런 점들이 찍힌 부분들을 드래그하면 드래그 안에 속한 여러 트랜잭션들의 상세한 정보도 볼 수 있습니다. 이번 이슈에서는 OOM 발생 직전에 처리속도가 느리고 빨간 트랜잭션들이 다량으로 나타났었어요. 가령, 위 ..
배경 이전 회사에서 신입으로서 VCS(Version Control System)를 사용하지 않아 많은 어려움이 있었어요. 부트캠프에서 처음 깃/깃헙을 배웠을 땐 개발 프로세스 중에 당연한 거라고 여겨져서 깃이 없을 때는 어떤 상황을 맞닥뜨릴지 전혀 몰랐습니다. 역시 버전 관리가 되지 않으면 여러 단점이 있었어요. 개발을 완료하고 이전 코드와 비교가 불가능한 점은 내 코드가 어떤 식으로 변경됐는지 한눈에 들어오지 않기 때문에 코드에 대한 자신감이 사라집니다. 변경사항을 볼 수 없기 때문에 동료로부터 아무 피드백도 받지 못합니다. 피드백받는 순간은 그 코드로 인하여 서비스가 비정상적으로 돌아갈 경우일 뿐입니다. 아니면 코드 누가 짰냐고 소리쳤을 경우에만 확인이 가능한 것이었어요. 변경 사항을 볼 수 없기 때..
자바 "IllegalArgumentException: Comparison method violates its general contract!" 에러에 대해 알아보자. 해당 에러는 비교 메소드가 Comparator 에서 사용하고 있는 어떤 contract 를 위반했기 때문에 발생하는 에러이다. 다시 말해서, Comparator 를 구현할 때 어떠한 모순점이 있으면 해당 에러가 발생하다. 어떤 contract 라는 것은 자바에서 따르고 있는 strict weak ordering 이라는 순서 규칙을 말한다. 에러에 대해 알아보기 전에 먼저 strict weak ordering 부터 살펴보자. 들어가기 Comparison method violates its general contract! 에러는 정렬 알고리즘이..
long 타입에서 int 타입으로 형변환하는 과정에 대해 알아보자. long val1Long = 108095103513L; long val2Long = 108030648857L; int val1Int = (int) 108095103513L; int val2Int = (int) 108030648857L; boolean isEqual = (val1Int - val2Int) == (val1Long - val2Long); 위에서 isEqual 는 true 이다. int 로 cast 되면서 정보 손실이 있었지만 그래도 true이다. 왜일까? val1Int, val2Int 는 int 로 cast 되면서 정보 손실이 일어난다. 여기서 말하는 정보 손실이란 int 값에 들어갈 수 있는 4 bytes (32 bits) ..
먼저 public static final 을 사용하는 이유에 대해서 생각해보자. public static final int DEFAULT_SIZE = 16; 와 같은 형태의 쓰임새는 이해가 갈것이다. 접근제어자를 public 으로 선언함으로써 전역에서 사용하도록 하고, static 키워드를 붙임으로써 메모리 한 영역에 정적으로 할당하여 자원을 공유하도록 하고, final 로 해당 변수의 값을 변경하지 못하게하여 불변성을 보장하도록 하는 것이기 때문이다. 즉 다시 말하자면, 자주 사용하는 자원을 효율적으로 불변성을 보장받고 사용하기 위하여 그런식으로 사용한다는 것을 알 수 있다. 이 점을 기억하고 접근 제어자가 public이 아니라 private으로 바꿔서 다시 생각해보자. 먼저 클래스 외부에서는 사용하지..
현재 개발중인 서비스는 어떤 "미션" 이라는 것을 유저가 참여할 수 있다. 해당 "미션"을 정해진 시간 내에 완료하지 못하면 휴대폰으로 푸시알림이 가도록 했다. 이 과정에서 겪은 문제와 해결법을 적어보았다. 미션을 참여할때 유저는 키값으로 메인미션인지 서브미션인지 구분하는 값과 해당 미션ID와 유저ID를 담고 value에는 미션시작datetime이 담겨져있다. 미션을 완료하지 못했을때 푸시를 보내야하는데 해당 시점에 어떤 trigger하는 이벤트가 발생하지 않는다. 미션이 만료된 것을 알 수 있는 유일한 수단은 redis에서 expire하는 이벤트를 subscribe하여 확인하는 수 밖에 없다. 먼저 스프링말고 레디스 서버에서 어떻게 expire된 이벤트를 확인할 수 있는지 보자. 레디스를 설치하면 이벤..
요즘 앱에서는 자동로그인 기능을 사용하기보단 앱을 설치하여 로그인하면 자동로그인과 같이 매 접속시마다 로그인이 유지된 상태를 가지고 일정 기간이 지나면 다시 로그인하도록 하는 구조로 되어있습니다. 하지만 회사 요구사항에서 앱 기능에 자동로그인이 있어서 해당 기능을 구현하게 됐어요. 웹기반 하이브리드앱을 만들며 깨달은 JWT가 눈에 아른거리는 경험을 간단히 적어보려고 합니다! 처음에 리서치할땐 스프링 시큐리티에서 자동로그인 관련 기능을 제공해주는 것을 알고 있었기 때문에 막연히 간단히 해당 기능을 구현하여 금방 끝날 업무리고 생각했어요. SecurityConfig에서 간단히 RememberMe기능만 아래처럼 활성화시켜주면 되는데요. 이 기능을 통해 remember-me 토큰을 발급받아 쿠키에 담아 클라이언..
테스트 코드 작성해야한다, TDD 해야한다, 말은 많이 들었다. 인프런의 김영한님도 말씀하시더라. 테스트코드 없이 개발하는 것은 불가능하다고. 그 말을 처음 들었을 땐 별 감흥이 없었는데 이번에 자바/스프링으로 신규 프로젝트를 진행하며 온몸으로 테스트 코드 작성의 중요성을 깨달았다. 이 글에서는 내가 테스트가 번거로웠던 많은 로직들 중에 한가지를 샘플링하여 가져와 그 중요성을 설명할 것이다. 테스트 코드를 작성하지 않는다면 어떤식으로 개발해야할까? 아직 완성되지 않은 서비스를 테스트 할때 여러 변수들에 임의의 값을 넣어주고, 종속된 다른 클래스에도 임의의 값을 넣어줘야하고, 데이터를 꺼낼때도 임의의 값을 넣어줘야한다. 때에 따라선 이보다 훨씬 부가적인 작업이 많을 것이다. 이를 수동으로 처리하면 어떻게 ..
kyupid
가장 낮은 자세