기술과 생각

우리가 컴퓨터를 키면 마우스로 커서를 움직이고, 크롬을 열어서 구글 검색도 하고,카카오톡으로 업무를 보기도 하죠? 이 모든 개별적인 프로그램들이 바로 프로세스라고 할 수 있어요. 사실 프로그램과 프로세스는 조금 다른 개념이에요. 프로그램은 개발자가 만든 코드들을 잘 포장해서 우리가 사용할 수 있도록 준비해 놓은 실행 파일이라고 보시면 돼요. 크롬이나 카카오톡을 다운받은 그 파일이 바로 프로그램인 거죠. 그런데 이 프로그램을 실행시키면, 바로 프로세스라는 개념이 등장해요. 프로그램 아이콘을 더블 클릭하면 운영체제가 이 프로그램을 실행할 수 있도록 준비를 해주는데, 디스크에 저장된 프로그램을 메모리에 올리고 프로세스를 생성하는 거예요. 이렇게 컴퓨터에는 다양한 프로세스들이 메모리에 올라오게 되는데, 운영체제..
자바 "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 해야한다, 말은 많이 들었다. 인프런의 김영한님도 말씀하시더라. 테스트코드 없이 개발하는 것은 불가능하다고. 그 말을 처음 들었을 땐 별 감흥이 없었는데 이번에 자바/스프링으로 신규 프로젝트를 진행하며 온몸으로 테스트 코드 작성의 중요성을 깨달았다. 이 글에서는 내가 테스트가 번거로웠던 많은 로직들 중에 한가지를 샘플링하여 가져와 그 중요성을 설명할 것이다. 테스트 코드를 작성하지 않는다면 어떤식으로 개발해야할까? 아직 완성되지 않은 서비스를 테스트 할때 여러 변수들에 임의의 값을 넣어주고, 종속된 다른 클래스에도 임의의 값을 넣어줘야하고, 데이터를 꺼낼때도 임의의 값을 넣어줘야한다. 때에 따라선 이보다 훨씬 부가적인 작업이 많을 것이다. 이를 수동으로 처리하면 어떻게 ..
들어가기 온라인 쇼핑몰을 생각해보자. 마음에 드는 물건을 카트에 담았다. 계속해서 둘러보고 다른 물건도 카트에 담아서 확인을 해봤는데 앞에 물건이 없다? 우리가 원하는 것은 내가 카트에 물건을 담아도 사라지지 않는 것이다. 그 상태를 유지하고 싶다. HTTP 프로토콜은 기본적으로 stateless(무상태)이다. stateless라는 의미는 서버-클라이언트 간의 통신 시에 이전 통신 정보를 저장하지 않는다는 의미이다. 즉, 물건을 담는 요청을 하면 물건을 담지만 그 상태를 유지하지 않는다. 서버와 클라이언트는 독립적이며 그렇기 때문에 서버에 어떠한 정보도 저장하지 않는다. 앞서 예시를 든 것은 stateless가 아니라 stateful, 사용자의 상태를 유지하기 위한 방법이 필요하다. 쿠키와 세션은 이런 ..
타임리프로 개발하다보면 아래와 같은 예외를 무조건 만나게 될것이다. org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: 위 예외는 타임리프 문법에서 객체에서 필드를 꺼내올때 타임리프에 적은 필드명이 객체 없으면 나는 에러이다. 예를 들어서 public class Person { private String name; private Integer age; // getter, setter, constructor ... } 이름: 나이: 위와 같이 person.age를 가져와야하는데 person.AGE를 가져오는거같이 person이 가지고 있지 않은 필드를 가져오면 아래 예외가 터진다. org..
들어가기 처음에 예외처리하여(Exception) 클라이언트에게 원하는 데이터를 내보낼수 있다는 사실을 몰랐다. 그때 해결하려했던 생각은 ErrorMessage라는 객체를 만들어서 서비스층에서 조건에 걸리지 않으면 ErrorMessage 를 return 하려고 했다. 그렇게 하려고 했던건 다시 말하지만 단순히 예외처리를 하였을 땐 따로 JSON 데이터로 사용자에게 응답을 주지 못할 것이라고 생각하였기 때문이다. 그래서 아래와 같은 방법으로 해결하려고 했다. 첫번째 방향 하고 싶었던 것은 아래 코드처럼 예외를 throw 하되 클라이언트에 데이터를 같이 응답해주고 싶었다. public String sendAuthMail(String userId) throws Exception { String authKey; ..
kyupid
'기술과 생각' 카테고리의 글 목록