전체 글
-
Stream은 일회용품이다.Java & Kotlin 2021. 12. 12. 23:16
1. 서론 코딩, 프로그래밍을 하는 데에는 각자의 취향이 분명 있을 것입니다. 하지만 무엇이 옳다고 말할 수는 없는데요. 다양한 프로그래밍 방식 중 저는 무엇인가를 조회할 때 각각 변수에 담아, 다시 사용하는 것을 좋아합니다. JPA에서 사용되는 쿼리 메서드를 예로 들겠습니다. 누군가는 애초에 변수 b만 들어서, a의 내용을 join으로 한 번에 가지고 오기도 합니다. 혹은 변수 자체를 만들지 않고, 바로 return에 조회하는 메서드를 사용하기도 합니다. 하지만 저는 세번째와 같이 변수에 하나하나 담아, return 하는 방식을 선호하는데요. 이유는 각각의 의도를 가진 변수명을 사용해서, 어떤 목적을 가지고 있는지 명확히 알 수 있습니다. 또한 어떤 부분에서 에러가 발생하는지 명확히 파악할 수도 있습니..
-
그래서 예외처리는요?Java & Kotlin 2021. 12. 5. 05:30
1) 서론 개발자로서 취업 후 가장 많이 배우는 것 중 하나는 예외처리일 것 같습니다. 혼자서 개발할 때는 모든 상황의 예외를 파악할 수 있습니다. "이 부분에서는 절대로 에러가 나지 않는다"라는 확신이 들기도 합니다. 왜냐하면 혼자서 정해진대로 테스트를 진행하기 때문에, 예상 가능한 문제만 발생합니다. 하지만 실제 업무에서는 절대로 예상할 수 없습니다. 당연히 들어와야 하는 파라미터가, 그냥 안 들어오는 경우도 있습니다. 사용자는 정해진대로 움직이지 않고, 복잡한 시스템은 항상 예기치 못 한 에러를 만들어냅니다. 당연히 있어야 할 것이, 당연히 없는 경우가 대부분입니다. 신입으로서 코드를 작성할 때 가장 많이 들은 질문입니다. "그래서 예외처리는요?" 2) 고작 파라미터 받는데요? 이번 글에서는 흔하게..
-
JPA 지연 로딩, 결국 ProxySpring Framework 2021. 11. 21. 23:42
1) 서론 JPA가 적용된 서버의 로그를 보면, LazyInitializationException이 빠지지 않고 항상 올라오곤 합니다. 일주일에 한 개씩은 발생하는 에러 같은데요. 사실 이는 단순한 문법적 오류이며, 하이버네이트가 어떤 식으로 지연 로딩하는지에 대한 깊은 이해가 부족하기 때문이라고 생각합니다. "그냥 get()하면 가지고 오는 거 아닌가?"라고 생각하기 쉽습니다. 저 또한 그랬습니다. 결론부터 말씀드리면, 스프링 프레임워크에서 지겹게 사용되는 프록시가 원인입니다. 해당 에러들을 해결하며 공부한 것을 정리해보겠습니다. 2) 에러 코드 (모든 코드는 임의로 만들어낸 상황입니다) 테스트 코드는 아직 부족합니다. 참고만 해주세요. public class Player { ... 생략 ... @Ma..
-
GitHub 브랜치 단위로 PR 하기 - 기초편-Contribution 2021. 11. 14. 01:26
1) 서론 그동안 혼자서 깃허브 저장소를 만들고, 로컬에서 그대로 push 하는 방식을 사용했었습니다. 아마도 함께 공부하고 협업했던 경험이 없었던 것이 이유일 것 같은데요. 하지만 막상 개발자로서 취업 후 하나의 origin(remote) 저장소를 기준으로 fork, branch, PR 등 다양하게 사용하고 있었습니다. 이는 협업을 바탕으로 저장소 관리와 기록을 편리하게 위함인데요. 처음에는 push 잘 못했다가 문제가 생기지 않을까 두려움에 떨기도 했었습니다. 딱히 알려주는 사람도 없었구요. 그래서 다시는 잊지 않으려고, 일련의 흐름을 간단히 기록하려고 합니다. 참고로 이 글에서는 Java 파일을 기준으로 합니다. 하지만 다른 언어 파일 혹은 단순 텍스트 파일도 관계없습니다. HTML 삽입 미리보기할..
-
@Async, 생각보다 까다롭다.Java & Kotlin 2021. 11. 1. 00:53
1) 서론 요즘 @Async를 어느 때보다 많이 사용하고 있습니다. 사실 그동안 간단하게 애노테이션과 thread pool 설정만 하면 된다고 생각했습니다. 하지만 실제로 사용할 때 예상하는 것과 다른 흐름으로 동작하고, 은근히 까다롭다는 것을 느꼈습니다. 제가 사용하며 만난 문제점과 해결 과정을 기록합니다. 2) 문제의 코드 전체적인 콘셉트는 간단합니다. 파싱 해온 데이터를 원하는 방향으로 가공합니다. 이때 이름, 가격을 나눠서 가공하고 비동기 처리합니다. public class MainClas { public void trimAndAddWines(List names, List prices) { log.info("\n === trimAndAddWines() 시작 ==="); // @Async wineN..
-
인터페이스의 default, static 메소드Java & Kotlin 2021. 10. 6. 00:37
1) 서론 창피하지만, 최근 이펙티브 자바를 읽으며 인터페이스에 default, static 메서드가 된다는 것을 알았습니다. JDK 17이 나오는 시점에서 JDK 8 조차 제대로 업데이트되지 않은 채 "그게 돼?" 라는 충격에 빠졌습니다. 그래서 이번 기회에 해당 메서드들이 왜 만들어졌고, 어떻게 사용되는지 공부해봤습니다. 2) default / static 메서드 원래 인터페이스는 추상 메서드만 사용 가능했었습니다. 여기서 추상메서드란 구현부가 없는, 아직 완성되지 않은 메서드인데요. 왜 추상메서드만 허용을 했었는가에 대한 명확한 설명은 없지만, 오라클 공식문서를 참고하면 오라클이 인터페이스를 어떻게 바라보고 있는지 조금은 알 수 있습니다. 오라클 공식문서에서는 인터페이스를 자동차 산업의 표준이 되는..
-
Kafka 클러스터 메세지 발행 및 문제 해결Kafka 2021. 10. 4. 01:46
1) 서론 단순 공부 및 테스트 위해 local 환경에서 broker 4 + zookeeper 3개의 서버를 사용합니다. 깊이 있는 설정은 배제하고, 전체적인 흐름 파악에 집중했습니다. 이 글에서는 카프카 클러스터의 설정 방법은 설명하지 않습니다. 궁금하신 분들은 아래 글을 참고해주세요. Kafka 클러스터 구성 및 장애 해결 Zookeeper 클러스터 및 컨트롤러 선출 전체적인 구조입니다. 꼭 8082 포트가 controller가 되는건 아닙니다. 단순 예시입니다. 2) 설정 최소한의 설정만 합니다. producer / consumer.properties (동일) // 연결할 broker 주소들 bootstrap.servers=localhost:8081,localhost:8082,localhost:80..
-
과거의 나에게...(와인 검색 서비스 회고)Java & Kotlin 2021. 10. 2. 01:39
1) 서론 이 글은 약 1년 전, 학생 때 만든 "와인 검색 서비스"의 회고(변명) 글입니다. 머릿속으로 대략 생각하면서 작성했습니다. 조만간 시간이 나면, 실제로 리팩토링 진행해볼 예정입니다. 저는 이상하게 새로 무언가를 만드는 것보다, 리팩토링을 통해서 더 좋은 코드와 성능 향상에 관심이 많습니다. 당시에 만든 서비스와 글은 아래와 같습니다. https://yeon-kr.tistory.com/131?category=868421 전체적인 내용(변명)은 "그때는 그게 최선이었다. 그것밖에 몰랐다"라고 할 수 있을 듯합니다... 과거의 나야... 제발 무전받아... 그렇게 하는 거 아니야... 2) 와인 검색 서비스... 패기는 좋았다! 사용된 기술 스프링 프레임워크 (boot X) JSP + JavaSc..