모락 프로젝트를 진행하는 과정에서의 트러블 슈팅 내용을 다루고 있습니다. 오늘은 byte[]를 String으로 변환하는 방법에 대해 이야기해보려 합니다. 먼저 QA 과정에서 발견된 문제 상황에 대해 공유해드리려고해요. 저희는 로직 상 처리하지 못한 예외에 대해서는 문제 상황을 재현해 볼 수 있도록 요청 정보를 모두 로깅하고 있었습니다. 그런데 로그 파일을 까고 보니 요청 바디(Request Body)가 다음과 같이 이상한 숫자들로 출력되고 있었습니다. 분명 PR을 날리기 전에 요청 바디가 잘 찍히는 것을 확인했었는데.. 이상한 일이었습니다🥲 이와 관련해 왜 이러한 문제가 발생했는지, 어떻게 해결했는지 이야기해보겠습니다. new String()을 사용했던 이유 private static StringBuil..
체스미션에서 View(Client)에 원하는 에러 메시지를 전송하기위해 아래와 같이 try-catch문을 남발하여 에러가 발생하는 경우 에러 메시지를 DTO에 담아 보내도록 구현했었다. 알고보니 Spark Java에서는 예외를 처리해주는 exception 메서드를 지원하고 있었고, 이를 사용하는 방향으로 리팩토링을 진행했다. Controller 에러가 발생하면 ErrorResponseDto에 에러 메시지를 담아 보내도록 구현하였다. 현재 모든 에러를 잡도록(일명 포켓몬 캐치..) 구현하였는데 이는 추후 수정이 필요해보인다. exception(Exception.class, (e, req, res) -> { res.body(GSON.toJson(new ErrorResponseDto(e.getMessage()..
11장. 동시성 이번 장에서는 동시성 프로그램을 명확하고 정확하게 만들 수 있는 방법을 제시한다. 동기화(Synchronized)란 무엇인가? 동기화에 대한 흔한 오해 동기화 적용 방법 volatile 키워드 Java.util.concurrent.atomic 패키지 1. 동기화(Synchronized)란 무엇인가? 멀티 스레드 환경에서 하나의 메서드나 블록을 한번에 한 스레드씩 수행하도록 보장하는 것을 의미한다. 자바에서는 synchronized 키워드를 이용해 동기화를 제공한다. public synchronized void increase() { } synchronized(number) { } 동기화의 주요 기능 배타적 실행 한 스레드가 변경하는 중이라서 상태가 일관되지 않은 순간의 객체를 다른 스레드..
솔직히 아직 모든 내용을 이해한 것은 아니다. 하지만 일단 내가 이해한 부분까지 정리를 하고 추후에 더 추가 학습을 하는것이 좋을 것 같아 이렇게 글로 작성하게 됐다. 😄 문제 발생 public enum Result { WIN("승", (dealerScore, participantScore) -> (dealerScore participantScore && dealerScore 21); } 이 코드를 보시고 리뷰어 토니께서 21에 의미를 부여해주면 좋겠다..
우아한테크코스 강의 중 네오께서 해주신 "상속", "클래스와 인스턴스(심화)" 강의 중 일부를 정리하면서 추가로 학습한 내용과 나의 소소한 생각을 작성하였다. "상속보다는 컴포지션을 사용하라", "상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라", "추상 클래스보다는 인터페이스를 우선하라" 등 이펙티브 자바 3/E에는 조슈아 블로크님의 상속에 대한 부정적인 의견들이 가득하다. 상속은 정말 나쁜가? 상속은 죄가 없다!! 내가 잘 못 사용하고 있을 뿐!! 상속은 코드를 재사용하는 강력한 수단이지만 항상 최선의 선택이 되는 것은 아니다. 상속은 여러가지 단점을 가지지만, 근본적인 원인은 상속 그 자체가 아니라 상속을 잘 못 사용하고 있는 우리들이다. 상속을 잘 못 사용할 경우 큰 부작용이 ..
본 포스팅은 이펙티브 자바 3/E의 아이템 48. 스트림 병렬화는 주의해서 적용하라를 읽고 정리한 내용이다. 아이템 45. 스트림은 주의해서 사용하라 기본적으로 스트림 파이프라인은 순차적으로 수행된다. 파이프라인을 병렬로 실행하려면 파이프라인을 구성하는 스트림 중 하나에서 parallel 메서드를 호출해주기만 하면 되나, 효과를 볼 수 있는 상황은 많지 않다. 1. 계산 결과가 정확하고 2. 성능도 좋아질 것이라는 확신이 없다면 스트림 병렬화를 적용하지 말자!! 계산량이 많거나 빅데이터를 처리하거나 성능 최적화가 필요한 상황에서 스트림 병렬화는 매력적이게 보일 수 있다. 모든 동시성 프로그래밍에서는 안전성(safety)과 응답 가능(liveness)상태를 유지해야 하는데, 스트림을 잘못 병렬화하면 오히려..
네오의 Generic 수업을 들으며 "아.. 제네릭 공부해야겠다.."라고 생각했지만.. 계속 미루고만 있었다. 그러다 로또 미션 학습 로그 말하기 때 어썸오가 "Type Erasure"를 주제로 얘기 하는 걸 들으면서 "아 맞다 얼른 제네릭 공부해야지.."라고 생각했다. 드디어 오늘 이펙티브 자바 스터디에서 제네릭에 관한 아이템들을 발표하는 것을 들으며 "오늘 안에는 제네릭 공부 시작한다!!"가 되었고, 이렇게 글을 작성하게 되었다. 난 좀 맞아야할 것 같다 👊 사실 제네릭이 뭔지는 알고 있었다. 대학교에서 자바 수업을 들을 적 당연히 배웠고, 과제도 하고, 시험도 봤다. 하지만 정작 이게 뭔지 이해를 한 적도, 내 코드에 어떻게 적용되고 있는 지에 대한 고민을 한 적도 없었다. 일단 제네릭의 기본 개념..
[이펙티브 자바 3/E] 아이템 21 : 인터페이스는 구현하는 쪽을 생각해 설계하라 Java8 이전에는 기존 구현체를 깨뜨리지 않고는 인터페이스에 메서드를 추가할 수 있는 방법이 없었다. Java7까지만 해도 "현재 인터페이스에 새로운 메서드가 추가될 일은 영원히 없다"고 가정하고 작성됐다고 하니 말 다했다. 만약 요구사항이 추가되면서 인터페이스에 메서드를 추가해야하는 상황이 온다면, 해당 인터페이스의 구현체 클래스를 모두 변경해야줘야한다. 이게 작은 프로그램이라면 문제가 없겠지만 해당 인터페이스를 상속 받은 클래스가 무수히 많다면.... 변경 사항이 걷잡을 수 없이 많아질 것이다. 이러한 문제를 해결하기 위해 Java8 부터는 기존 인터페이스에 메서드를 추가할 수 있는 "디폴트 메서드"가 추가되었다. ..
[이펙티브 자바 3/E] 아이템 1 : 생성자 대신 정적 팩터리 메서드를 고려하라 핵심 정적 팩터리 메서드와 public 생성자는 각자의 쓰임새가 있으니 상대적인 장단점을 이해하고 사용하는 것이 좋다. 그렇다고 하더라도 정적 팩터리를 사용하는 게 유리한 경우가 더 많으므로 무작정 public 생성자를 제공하던 습관이 있다면 고치자. 정적 팩토리 메서드(Static Factory Method) 정적 팩토리 메서드란 그 클래스의 인스턴스를 반환하는 단순한 정적 메서드를 말한다. (new 없이 객체를 생성한다) 우리가 평소 습관적으로 public 생성자로 객체를 생성했다면 이제는 정적 팩토리 메서드를 이용해 객체 생성를 할 수 있다는 것을 알아야한다. // public 생성자 이용 Car car = new C..
이전에 우테코 크루들과 “final이 보장하는 불변은 어디까지인지?”에 대해 얘기를 나누었을 때, 어떤 크루가 본인은 컬렉션의 불변을 보장해야할 때는 unmodifiable 상태로 명시한다는 이야기를 했었다. "unmodifiable" 사실 Java 인생에서 처음 들어보는 단어였다. 그래서 그런지 뭔가 머릿속에서 휘발되고 말았는데.. "일급 컬렉션(First Class Collection)"에 대해 학습을 하다보니 다시 "객체의 불변"에 대한 내용이 나왔고, 불변과 관련해서 컬렉션에서는 unmodifiable이라는 상태를 지원한다는 것을 알게되었다. Unmodifiable Collection Unmodifiable Collection은 수정할 수 없는 컬렉션임을 뜻하며, "Read-Only" 용도로만 사..