All
19 posts
about me.

intro 😃 새해를 맞이해서 지난 1년간 어떤 일을 했는가 돌아보다보니 성취한 것들에 대한 내용들만 적게 되더라고요. 그래서 오늘은 스스로가 어떤 성격이고, 왜 이런 성격을 가지게 되었는지 살펴보고자 합니다. episode 1: 뻔(fun)하다. 어릴 때부터 짱구처럼 오늘은 또 어떤 재밌는 일이 나를 기다릴까 기대하며 하루를 시작해요. 하루에도 여러번 피식하고 웃음이 나는 일이 있거든요. 그런 순간이 언제인지 그 타이밍이 오면 웃음을 놓치지 않고 누구보다 음미하면서 웃으려고 노력하는 성격이에요. 웃음 소리가 너무커서 가끔 주변 눈치를 보기도 하는데, 이런 순간들이 삶을 살아가게 하는 것 같아요. 첫번째로 음악을 통해 많이 웃는 것 같아요. 요새 취미가 산책하면서 노래부르기인데, 노래를 따라 부르다보면 스트레스도 풀리고, 노래 가사에 알맞는 상황에서 딱 그 구절을 부르고 함께 있는 상대방의 반응을 살피면 너무 웃겨요. 그래서 많이 웃게 돼요. 또 진지한 상황에서 위트있게 풀어가려…

NamedLock - [재고 시스템으로 알아보는 동시성 이슈]

왜 NamedLock 을 사용해야하는가 ? 보통 분산락이라는 키워드로 검색을 해보면 레디스가 많이 나오는데요, MySQL lock 을 사용해서도 분산락을 구현할 수 있어요! 레디스를 사용하려면 인프라 구축 비용도 들고, 비지니스 로직 또한 별도로 구축해주어야하기 때문에 바용이 꽤 크다고 볼 수 있어요. 만약 지금 MySQL 을 사용하고 있다면, 이름으로 Lock 을 지정해줄 수 있는 네임드 락을 이용해서 분산락을 구현하면 어플리케이션 단에서 제어가 가능하고, 인프라 구축 및 유지보수 비용도 줄일 수 있습니다! NamedLock 사용 방법 직접 MySQL 키워드를 사용하여 LOCK 을 획득하면 됩니다. 저희는 네이티브 쿼리를 사용해서 획득하고 싶은 락에 대한 이름을 매개변수로 넘겨주어 락을 구현해보겠습니다. STEP 1) 락 획득하기 GET_LOCK(str,timeout) 입력받은 이름(str) 으로 timeout 초 동안 잠금 획득을 시도합니다. timeout 에 음수를 입력하면…

[알랭 드 보통-불안] 철학

학습동기 삶에서 스스로를 지탱해줄 수 있는 가장 강력한 힘은 철학이라고 믿어요. 개발자로 살면서 나의 방향과 성장이 팀에게 도움이 되는가? 부터 내가 받는 존중과 성취가 합당한가? 까지 모든 것들이 철학에 근거하여 나에게 불안으로 다가오기도하고, 만족이나 행복으로 다가오기도 한다는 것을 근래에 크게 느끼고 있어요. 그래서 이런 마음은 어디서 오는가, 알랭드 보통의 생각이 궁금하여 해당 챕터를 읽게 되었습니다. 아래 내용은 책 내용이 발췌되어 있기도하고, 제가 각색한 내용이 담겨있기도 해요! 취사하여 습득하시면 좋을 것 같습니다. 자존심이란? 우리의 자존심은 다른 사람들이 부여하는 가치에 의해 결정된다는 점에서 우리도 성질 급하게 결투에 나서는 사람들과 다를 바 없을지 모른다. 결투란 지위의 문제에 대한 보편적인 예민한 감정적 대응을 보여주는 하나의 사례이다. 무엇이 중요한가를 판단하려고 할 때, 다른 사람들로부터 우호적인 시선을 받고 싶은 강렬한 욕구는 과거와 다름없이 우리 생각을…

[알랭 드 보통-불안] 3장 기대 (평등, 기대, 선망)

학습 동기 12월 말에 한해를 돌아보았는데, 내가 이룬 업적이 있는가에 대한 회의가 들었어요. 일 년간 잘 지내왔다고 생각했는데 문득 찾아오는 불안감에 대해서 이유를 알고 마음을 다독이고자 읽게 되었습니다. 우리는 실제로 궁핍한가? 현대 사회로 들어서며 부, 식량, 과학 지식, 소비 물자, 신체적 안전, 기대 수명, 경제적 기회 등이 증가했다는 사실은 분명하지만 그렇기 때문에 먹고 살기 바빠 등한시 했던 지위로 인한 불안 수준이 높아졌어요. 실제적 궁핍은 급격하게 줄었지만, 역설적이게도 궁핍감과 궁핍에 대한 공포는 사라지지 않았고, 외려 늘어나기까지 했죠. 농사를 지으며 변덕스러운 땅을 경작하던 조상들은 도저히 상상도 하지 못할 부와 가능성의 축복을 받은 사람들이 놀랍게도 자신이 모자란 존재이고, 자신의 소유도 충분치 못하다는 느낌에 시달리게 된 것입니다. -p.60 이 부분을 읽고 내가 누리는 삶과 환경에 감사해야하는데, 더 나음을 바라면서 나 자신을 괴롭게 하고 있지 않았나라…

캡슐화(Encapsulation)란?

캡슐화란? 객체의 상태와 행위를 외부로 부터 보호합니다. 주로 접근 제어자를 사용하여 구현합니다. 왜 캡슐화를 지켜야 하나요? 객체지향적이란, 객체 각각 역할과 책임을 다해야합니다. 내 상태와 행위를 밖으로 노출시키게 된다면 어떻게 될까요 ? 캡슐화를 지킨 사례 캡슐화가 위반된 사례 데이터와, 행위를 하나로 묶고, 그걸 외부에 노출시키지 않는게 왜 중요한가? 아래와 같이 코드를 작성하더라도 같은 행위가 아닌가? 캡슐화를 지키기 위한 규칙중에는 라는 원칙이 있다. 객체 내부의 데이터를 꺼내와서 처리하는게 아닌, 객체에게 처리할 행위를 요청하라는 행위이다. 이러한 행위를 우리는 “객체에 메세지를 보낸다” 라고 말한다. 그렇다면 왜 캡슐화를 지키기 위해서는 데이터를 객체로부터 받아와서 처리하면 안된다고 하는걸까? 캡슐화의 장점을 살펴보면 그 이유를 간단히 이해할 수 있다. 캡슐화를 통해 우리가 얻을 수 있는 이점중 가장 큰것은 코드의 중복을 피할 수 있다는 점과, 데이터를 처리하는 동…

Spring 을 사용하여 의존성을 주입할 시 생성자를 사용해야하는 이유

학습 동기 스프링을 사용하면서 습관처럼 의존성 주입을 생성자 주입으로 받곤 했어요. 처음 접한 방식은 @Autowired 였는데 매 필드마다 달아주는게 너무 힘들었거든요. 생성자는 IDE 에서 자동 생성이 되니까 편리하게 사용이 가능하고, 필드에 final 을 붙일 수 있어 불변을 보장해줘서 더 안정적이게 느껴졌어요. 그러다 문득 의존성을 주입하는 방식이 3가지나 있는데, 지금 방법보다 더 나은 방법은 없을까? 궁금해졌어요. 그래서 장단점을 파악해보기로 했습니다. 의존성 주입이란 무엇일까요? ☺️ 의존성 주입이란 스프링에서 제공하는 DI 기능입니다. 스프링에서는 객체를 싱글톤 빈으로 관리하고, 필요한 곳에 적절히 주입시켜주어 객체를 계속 생성해 부하가 발생하는 문제를 해결했어요! 그래서 대용량 트래픽 처리에 스프링을 사용하면 좋을 것 같다는 생각을 했습니다. 생성자 주입(Constructor Injection) 생성시 값이 주입되기 때문에 final 키워드를 붙여 불변을 보장할 수…

인증과 인가

학습 동기 프로젝트를 진행하며 사용자에게 로그인을 유지시켜 주기 위해서 JWT 를 사용한 적이 있어요. 그 때 인증과 인가의 개념을 헷갈렸던 기억이 있어서 다시한번 복기 할 겸 정리해보기로 했습니다. 인증 인증 단계에서는 사용자의 신원을 확인하는 단계입니다. 처음 회사에 들어가면 회사 사람인지 확인하고 출입증을 주는 행위를 신원확인 단계라고 할 수 있을 것 같아요. 핸드폰 FaceID 로도 핸드폰의 주인이 맞는지 인증하는 것도 예시로 들 수 있을 것 같아요. ㅎㅎ 서버에서 인증 처리는 다양하게 등등 으로 할 수 있는데요. 위 세가지의 특성에 대해서 알아보겠습니다. 쿠키, 세션, 토큰의 등장 배경! 통신을 할 때 과거 히스토리까지 전부 담에서 네트워크를 넘나들면 요청 자체가 너무 무거워지고, 해당 기록이 유실될 경우 원활한 통신이 어렵기 때문에 비연결성도 하나의 특징이랍니다. 이렇게 된다면 모든 요청 때 마다 ID ,PW 를 입력하여 사용자 인증을 해야하는 불편함이 생길거예요…

MSA(MicroService Architecture) 란 무엇인가

MSA(Micro Service Architecture)란 ? 디자인 패턴입니다. 완전히 독립적으로 배포가 가능하기 때문에 다른 기술 스택을 사용할 수 있어요. 모놀리식 구조(Monolithic Architecure) 를 말합니다. 관리가 쉬우며 초기 배포 단계에 설정할 것이 많지 않아서 MSA 보다 비교적 간단하게 서버 운영이 가능합니다. :) 모놀리식 구조 문제점 부분 장애가 전체 서비스 장애로 이어진다. 모놀리식 구조를 가진 프로젝트를 했을 당시, 회원 가입 로직에서 문제가 생겨 서버가 다운된 적이 있습니다. 혹은 갑자기 트래픽 증가로 인해서 성능에 문제가 생겼을 때, 서비스 전체의 장애로 확대될 수 있어요. 부분적인 scale-out 이 어렵다. 회원 가입은 부하가 자주 일어나지 않지만, 상품 주문은 빈번히 일어나는 작업이죠! 이럴 경우 더 많은 트래픽을 감당할 수 있는 인프라 구조가 필요한데요. 모놀리식 구조의 경우 서버를 나누어 처리할 수 없기 때문에 서비스의 …

프로세스와 스레드

프로세스와 스레드를 학습하기에 앞서, 이해하고 있으면 좋은 개념인 CPU 와 RAM 에 대해서 간단히 알아보아요! ☺️ CPU란? (core processing unit) 중앙 처리 장치로 컴퓨터를 통한 연산과 수행, 프로그램 실행을 담당하고 있어요 CPU 는 출력을 전달하기 전에 RAM 에서 입력을 가져와 명령문을 이해하고 처리합니다. RAM란?(Random access memory) 프로그램이 실행되는 동안 필요한 정보를 저장하는 컴퓨터 메모리 RAM 이란 저장된 데이터를 순차적이 아닌 임의의 순서로 액세스할 수 있는 데이터 저장소입니다. 데이터를 가져오기, 디코딩, 실행이 세가지가 cpu 의 핵심이자 전부에요! 프로세스(Process) 프로세스란 실행중인 프로그램을 뜻합니다. 즉, 파일 형태로 존재하던 프로그램이 메모리에 적재되어 CPU 에 의해 실행되는 것을 Process 라고 합니다. 메모리에 적재 메모리는 CPU가 직접 접근 할 수 있는 컴퓨터 내부의 기억 장치 입니다. …

[Effective Java -14장] Comparable 을 구현할지 고려해라

학습 동기 정렬 알고리즘에 대해서 공부하다가 Arrays.sort 내부 구현체는 Comparable 을 상속받아 구현되어 있다는 내용을 알게 되었습니다. Comparable 의 특징과 동작원리를 알게되면 더욱 효과적으로 사용할 수 있을 것 같아서 읽게 되었어요. Comparable 자바에서 제공되는 정렬이 가능한 클래스들은 모두 Comparable 인터페이스를 구현하고 있으며, 정렬 시에 이에 맞게 정렬이 수행됩니다. Integer 와 Double 클래스는 숫자 오름차순으로 정렬되어 있어요. String은 A-Z, 1-9 같이 사전순으로 정렬되어 있어요. 유일무이한 메서드 compareTo 해당 인터페이스에는 메서드가 compareTo 딱 하나뿐이에요. 이 compareTo 를 재정의해서 정렬 조건을 사용할 의도에 맞춰서 변경할 수 있어요! 비교 값이 0 이면 같다. 비교 값이 1 (양수) 이면 크다. 비교 값이 -1 (음수) 이면 작다. 정렬이고, 비교군을 반대로 한다면 내…

Arrays vs LinkedList

학습 동기 평소에 목록을 저장하기 위해서 배열이나 List 자료 형을 썼었는데, 배열과 ArrayList 는 메모리 크기가 고정되어 있는지, 동적으로 커지는지에 차이가 있다고 생각되어 구분하여 잘 사용 했었습니다. 그런데 알고리즘을 풀면서 LinkedList 와는 잘 비교해서 사용하지 않았던 것 같아서 정리해보고자 합니다. 배열(Arrays) 배열은 입력된 데이터들이 메모리 공간에서 연속적으로 저장되어 있는 자료구조에요 Index 를 통해서 접근이 가능하고 0 번부터 시작합니다. 최초 크기가 고정되면 바꿀 수 없어요. 시간 복잡도 조회는 접근하고자 하는 인덱스만 안다면 O(1) 시간이 걸려요. 순차 탐색시는 최대 O(n) 이 소모됩니다. 삽입 및 삭제 배열의 삽입, 삭제 O(n) 삭제된 원소 뒤에 있는 원소들을 한칸씩 옮겨야 해서 O(n) 이 소모됩니다. 배열의 에 삽입 및 삽입, 삭제 O(1) 가장 뒤에는 옮길 원소가 없기 때문에 O(1) 이 소모됩니다. 사용하면 좋은 상황 …

ArrayList 가 동적으로 사이즈가 늘어나는 동작 원리!

학습 동기 알고리즘 문제를 풀면서 배열과 ArrayList 의 가장 큰 차이는 메모리가 고정되어 있는지, 동적으로 늘어나는지에 따라 상황에 맞게 사용했었습니다. 그런데 문득 ArrayList 도 내부는 배열로 되어 있는데 어떤 방식으로 사이즈가 동적으로 늘어날까 궁금해졌습니다. ArrayList 내부 구조 최초에는 빈 배열로 생성되었다가 add 가 한번이라도 생성 되는 시점에 빈 배열이라면 기본 값인 10으로 사이즈 설정을 해줍니다. 그리고 원소의 개수가 10을 넘었을 때, 해당 배열의 사이즈의 절반만큼 크기를 늘려주고 있습니다. 중간 삽입(add(index, data) 이나 삭제 할 때 (remove) 동작 원리 Index 없이 삽입할 때는 배열의 바로 뒤에 삽입하기 때문에 원소를 뒤로 밀 필요가 없는데, 만약에 삽입시 index 를 지정해서 삽입하는 경우나 첫번째부터 맨 뒤 바로 앞 원소를 삭제하는 경우는 배열을 밀거나 당겨줘야한다. 내부 구현체에서는 를 사용하여 해당 인덱…

Stream의 reduce() 로 조합 계산하기

해당 글은 Stream 에 대해 알고 있다는 가정하에 작성되었습니다. 학습 동기 프로그래머스에서 위장 이라는 문제를 풀다가 모든 경우의 수를 찾아보는데 조합으로 풀면 간단하겠다고 생각이 들었고, 조합을 풀면서 재귀나 반복으로 풀기보다 Java Stream 에서 제공하는 기능으로 문제를 풀어보면 좋겠다고 생각되었습니다. 해당 글은 Stream 에 대해 알고 있다는 가정하에 작성되었습니다. Reduce() 란? 반복된 패턴을 추상화 할 수 있는 강력한 기능입니다. 스트림의 특성상 for 문처럼 원소들이 하나씩 아래로 들어오게 되는데요.  는 스트림의 원소들을 하나씩 소모해가며, 누적 계산을 수행하고 결과값을 리턴하는 메서드 입니다. 는 파라미터를 3개 받을 수 있어요. : 계산에 적용할 초깃값으로, 스트림이 비어 있더라도 초깃값을 반환 만약에 값을 누적하면서 곱하고 싶다면 기본 값이 1이어야 하겠죠? : 적용할 계산 함수 더하거나, 곱하거나, 빼거나 이런 연산을 수행해요. : 병렬 …

Hash table, HashMap, HashSet

학습 동기 중복되지 않는 값을 가진 데이터를 빠르게 조회하고 싶었어요. 그리고 그 값에 대한 개수를 세고 그 개수에 대한 로직을 작성하고자 했습니다. 그러던 중 해시 함수를 이용해서 테이블에 데이터 Key - value 형식으로 저장하는 HashMap 이 떠올랐어요. HashMap 내부는 Hash table 로 구현되어 있기 때문에 Hash table 에 대해서 먼저 알아보면 좋을 것 같습니다. HashTable 해시 테이블은 연관배열 구조를 이용해서 키(key) 에 결과값에 (value) 를 저장하는 자료 구조 입니다! 저장 시간 복잡도 데이터가 입력되면 해당 해시함수 로직을 통해서 고유 번호(해시값)가 나오게 되고, 그 고유번호를 key 로 가지고, 실제 데이터(value) 를 slot 이라고 부르는 공간에 넣게 돼요. 그래서 최단 시간 복잡도는 O(1) 이고, 만일 충돌이 발생하게 되면 최대 O(n) 의 시간이 걸릴 수도 있어요.😭 충돌이 발생하는 경우 key 값이 같고,…

트랜잭션이란?

학습 동기 프로그램 내부에서 예외가 발생했을 때, 진행되고 있던 데이터 변경 사항들을 모두 성공시키거나 실패시켜야 할 필요성을 느꼈어요. 면담 예약 서비스로 예를 든다면 면담을 예약하기 위해서는 1) 멘토의 시간도 사용중으로 바꿔야하고, 2)면담 요청 내용도 저장해야하고, 3)면담 테이블에 면담도 생성해야하는 3가지 DB 변경 작업이 필요해요. 세가지 중 하나라도 정상적으로 실행이 안되면 진행된 내역을 전부 취소 시켜서 프로그램 오류를 막는것이 안전한 서비스겠죠? 트랜잭션 더이상 나눌 수 없는 작업 단위를 말합니다. 데이터의 정합성을 보장하기 위한 작업이기도 해요. 위에서 면담을 생성하기 위해서 해야하는 3가지는 반드시 필요한 작업이라 하나의 트랜잭션에 묶이듯이요! 이 트랜잭션을 통해서 지키고 싶은 특징이 4가지가 있어요. 각 영단어에 앞 글자를 따서 ACID 원칙이라고도 불려요 원자성(Atomicity) 작업이 하나의 쿼리로 실행되더라도, 해당 쿼리로 바뀌는 데이터가 1개…

왜 나는 너를 사랑하는가 chapter -9

아름다움. 아름답기 때문에 사랑하는 것일까, 사랑해서 아름다워 보이는 걸까? 사랑하는 사람이 전화를 하거나 말을 하는 모습을 보면서 우리는 왜 이 목의 곡선이나 보조개가 매력있게 다가오는지 묻게 된다. 사랑은 아름다움에 욕망이라는 마르실리오 피치노라는 이탈리아 철학자의 말이 맞다면, 내가 사랑하는 사람은 어떤 방식으로 나의 욕망을 충족시킬까? 아름다움은 객관적인 기준에 따라서 측정할 수 있는걸까. 우리가 잘생기고 예쁘다고 생각하는 사람들의 얼굴에는 수학적 기초가 담겨있다. 따라서 잡지 표지 모델에 얼굴이 즐거움을 주는 것은 우연이라기보다 필연이다. 플라톤과 레온 바티스타 알베르티는 그들의 미학 이론에서 뭔가를 빠트린것이 틀림 없다. 나는 내가 사랑하는 사람이 지나치게 아름답다고 생각했기 때문이다. 내가 그의 보조개와 짙은 눈썹을 좋아했던 것일까? 그 사람의 매력 요소를 뽑는것이 명확하게 어떤 특징 때문이 아니라서 망설여진다. 그림을 볼 때도 어떤 그림은 내게 완벽한 감동을 주는 …

SpringBootTest 에서 의존성 주입 방식이 @autowired 로 강제되는 이유

학습동기 prolog project test code 를 작성하다가 생성자 주입과 autowired 로 의존성 주입을 하는 방식 모두를 사용하고 있는 코드를 발견했어요. 왜 junit 을 사용하는 test 에서 두개의 의존성 주입 방식을 사용하게 된걸까요? 이전부터 궁금했던건데 테스트 코드에서는 의존성 주입 방식을 무조건 autowired 로 해야하는지도 의문이 들었어요. 문제 코드 결론부터 말씀드리자면 TestClass 에서는 하나의 의존성 주입 방식을 사용하고 있어요. 테스트 코드를 작성하기 위해 사용하는 라이브 러리인 Junit 에서는 스프링과 별개로 의존성 주입을 하고 있어요.그래서 위 코드에서 생성자를 만든건 생성자로 의존성을 주입하기 위해서가 아니었더라구요. 각각 @autowired 를 달아주는 번거로움을 해소하고자 어노테이션으로 생성자 위에 autowired 를 달아준 것과 같은 효과를 내기 위해서 였어요. @autowired 로 의존성을 주입하지 않으면 이 …

InnoDB 언두 로그과 리드 로그

언두 로그란? myql 8.0 기준으로 DB 에서 트랜잭션과 격리 수준을 보장하기 위해서 InnoDB 스토리지 엔진을 사용하는 방법이 있어요. 트랜잭션과 격리 수준을 보장하기 위해서 DML(INSERT, UPDATE, DELETE) 로 변경 요청이 들어오면 변경전, 이전 버전의 데이터를 언두로그라는 공간에 백업해요. 트랜잭션 보장 트랜잭션이 롤백되면, 해야 하는데, 이때 언두 로그에 백업해둔 이전 버전의 데이터를 이용해 복구해요. 격리 수준 보장 특정 커넥션에서 에 에서 데이터를 조회하면 트랜잭션 격리 수준에 맞게 변경중인 레코드를 읽지 않고 하기도 합니다. (READ COMMITED 이상의 격리수준에서는 트랜잭션이 열려있는 데이터에 경우, 언두로그를 먼저 읽습니다. 언두로그 소멸 시점 그렇다면, 언두로그는 백업용 임시 공간이라는 소리인데, 언제까지 메모리에 남아있을까요? 언두로그는 롤백을 하거나, 트랜잭션과 격리할 때 사용하기 때문에 트랜잭션이 종료되면 더이상 필요 없어져서 …

Difference Between Arrays.asList() and List.of() 요약

해당 내용은 Baeldung 사이트를 번역한 후, 제 생각을 정리한 글입니다. 1. 개요 때때로 Java에서는 편의를 위해 작은 목록을 만들거나 배열을 목록으로 변환해야 합니다. Java는 이를 위한 몇 가지 도우미 메서드를 제공합니다. 이 자습서에서는 작은 임시 배열을 초기화하는 두 가지 주요 방법인 List.of() 와 Array.asList()를 비교합니다. 2. Arrays.asList() 사용하기 Java 1.2에 도입된 Arrays.asList() 는 Java Collections Framework 의 일부인 List 객체 생성을 단순화합니다. 배열을 입력으로 받아 제공된 배열 의 List 객체를 생성할 수 있습니다. 보시다시피 간단한 List of Integers 를 만드는 것은 매우 쉽습니다 . 2.1. Arrays.asList() 사용해서 반환받은 List 는 삽입, 삭제가 불가능합니다. (수정은 가능) asList() 메서드 는 고정 크기 목록을 반환합니다.…