-
Notifications
You must be signed in to change notification settings - Fork 0
3주차 수요일 그룹 5
- Resource도 포함하여 AbstractRequestHandler로 묶고, 동적 API는 CustomReqeust로 다시 한 번 추상화해둔게 좋은 것 같음, 코드에 적용할 계획
- interface → AbstractHandler → Resource, Dynamaic
- 쿠키는 nameValue (ex: sid)
- attributeValue (attribute value pairs) 순서가 있다는 사실을 알았습니다.
- LinkedHashMap을 쓰면 들어온 순서대로
- CompletableFuture에서supplyAsync로 체이닝
- RequestParam 어노테이션으로 공통 로직 만든 걸 나도 해야할거같음
- LinkedBlokcingQueue의 초기화 capacity가 Integer.MAX_VALUE로 돼있어서 accept()하면 스레드 수 적어도 main스레드에서 계속 받아주니깐 크게 문제 없을 것 같음
- Record toString아주 깔쌈하게 잘 만들어줌, 내부적으로 어떤 형식으로 만드는지는 알아봐야할 것 같음
- Annotation만들어서, 내부에 메서드 정의해두고, option 주면 .메서드()로 할 수 있음
- 스태틱인데 싱크로나이즈드를 붙이는 이유에 대해서? 붙이지 않아도 된다. 현재 코드에서 생성할 때만 싱크로나이즈드 되어있으므로 여러 스레드들이 동시에 접근해도 괜찮다. 다만 필요없으므로 싱크로나이즈들 빼는 편이 좋다고 하셨습니다.
- 클라이언트 소켓 close 까지 신경써준 부분이 인상깊었습니다.
- 핸들러라는 어노테이션이 붙은 클래스를 찾는 부분이 인상깊었습니다. 저는 메서드에만 넣어서 모든 클래스를 가져오는데, 클래스에도 어노테이션을 붙여서 가져올만한 클래스만 가져오는게 맞는 것 같습니다. 향후 개발에 참고해야겠습니다.
- interface → abstract class → class 의 RequestHandler 의 구조
- abstract class 가 2개가 있어서 만약 abstract를 제거한다고 해도 interface → interface → class 의 구조가 된다. 그래서 어차피 3단 구조를 하게 된다면 추상 클래스가 있는 게 더 좋다고 판단하신 점이 인상깊었습니다.
- 쿠키의 필드와 순서
- 네임 밸류, 어트리뷰트 밸류 순서를 지켜야한다.
- 링크드해시맵 같은 걸 써서 순서를 보장해야하나?
- html 을 파서한 결과를 Element 로 반환, 엘리먼트는 엘리먼트를 가진 트리구조 를 순회하면서 모델을 매핑하는 점이 인상깊었습니다.
- 메인에서 스프링 컨테이너 역할, 이니셜라이저 역할을 현재 해주고 있는데 향후 어떻게 정리하실지 기대가 됩니다.
- 미들웨어라는 이름으로 필터를 구현하신 점이 인상깊었습니다. 쓰레드 로컬로 인가관리를 하여 역할을 관리하는 점이 인상깊었습니다. 아직 역할 세팅은 안했는데 url → roles 매핑을 하실 예정인 것 같습니다 기대가 됩니다.
- html 에 이벤트 스크립트를 작성하여 CSR 로 구현을 더 쉽게 하신 점이 인상깊었습니다.
- Java var 을 사용하는 점이 인상깊었습니다.
- CompletableFuture supplyAsync 가 return 값이 있어서 이후 로직 진행 가능하다는 점을 알았습니다.
- HttpRequest 가 너무 기니까 한 번 걸러서 HttpClientRequest 로 구현하신 점이 인상깊었습니다.
- [excalidraw.io](http://excalidraw.io) 가 ai 기능이 있어서 그림을 그려주는게 매우 편해보였습니다.
- 정적파일 화이트리스트에 대해서 고민이 있으셨습니다.
- HttpResponse 팩토리 패턴이 인상깊었습니다.
- HTTP 스펙의 헤더 부분을 신경쓰셔서 파싱하셨던게 인상깊었습니다.
현재 내 프로젝트에서는 많은 부분에서 동시성 패키지를 사용하고 있지만, 제대로 사용하고 있지 않는다. 동시성이 필요하지 않는 곳에서 상관 없이 사용하고 있었고, 막상 필요한 곳은 동시성을 제공하는 메서드를 사용하않고 있다. 다시한번 내 프로젝트를 살펴보면서 필요한 부분은 메서드를 다시 한번 확인하고, 필요없는 곳은 없애야겠다.
Session을 관리하는 SessionManger는 정적 유틸리티 클래스로 테스트 하기 위해서 리플랙션을 사용했다. 이번 팀원분께서 테스트 코드에 의존성을 주입하는 방식으로 테스트를 진행한 것을 보았다. 테스트를 위해서 의존성 주입으로 바꾸어야 하는 생각이 있었지만, 테스트 코드는 부가적인 코드가 아닌 실제 동작하는 코드와 동일하게 중요한 코드라는 옛날 테스트 코드에 대한 블로그글이 생각났다. 이점을 유념해서 다시 바꾸어봐야겠다. https://jojoldu.tistory.com/674
- 쿠키의 옵션을 넣어줄 때 순서를 잘 넣어줘야 해당 옵션들이 잘 적용된다.
- 인터페이스 활용, 추상클래스 활용을 하면 구조적으로 보다 깔끔하게 만들 수 있다.
- 다들 테스트 코드를 열심히 짜셔서 테스트 코드의 중요성도 느낄 수 있었다.
서버 소켓의 backlog는 네트워크에서 서버가 동시에 처리할 수 있는 최대 연결 대기 수를 지정하는 매개변수 서버가 소켓을 생성하여 클라이언트의 연결 요청을 수신 대기할 때, 이러한 요청들은 처리되기 전에 대기열에 쌓이게 됨 backlog는 이 대기열에 허용할 수 있는 최대 연결 요청 수를 의미 너무 큰 값을 설정하더라도 실제로는 운영체제의 제한에 의해 적용되지 않을 수 있습니다.
CopyOnWriteArrayList
는 Java의 java.util.concurrent
패키지에 포함된 스레드 안전한 리스트 구현체입니다. 이 리스트는 특히 읽기 작업이 많고 쓰기 작업이 적은 상황에서 유용합니다. CopyOnWriteArrayList
의 핵심 특징은 쓰기 작업(삽입, 삭제 등)이 발생할 때마다 내부 배열을 복사하여 새 배열로 대체한다는 점입니다. 이는 읽기 작업이 쓰기 작업과 충돌하지 않도록 보장합니다.
-
스레드 안전성:
- 모든 쓰기 작업(추가, 삭제, 수정)은 배열의 새로운 복사본에서 이루어지며, 이는 여러 스레드에서 동시 접근하더라도 안전하게 동작하도록 합니다.
- 읽기 작업은 잠금(lock)을 사용하지 않으며, 항상 일관된 상태의 배열을 참조합니다.
-
쓰기 성능:
- 쓰기 작업 시마다 배열을 복사하기 때문에 쓰기 작업이 빈번하게 발생하는 경우 성능 저하가 발생할 수 있습니다.
-
읽기 성능:
- 읽기 작업은 잠금을 사용하지 않으므로 매우 빠르며, 쓰기 작업과 충돌하지 않습니다.
- 따라서, 읽기 작업이 매우 빈번하고 쓰기 작업이 드문 경우에 적합합니다.
ConcurrentHashMap
는 Java의 java.util.concurrent
패키지에 포함된 스레드 안전한 해시 맵 구현체
CAS (Compare-And-Swap) 연산
-
ConcurrentHashMap
은 CAS 연산을 사용하여 락 없이도 안전하게 동시 업데이트를 수행 - CAS는 락을 사용하지 않고도 변수의 값을 안전하게 변경할 수 있는 방법으로, 원자적(atomic) 연산을 통해 스레드 간 충돌을 방지 쓰기와 읽기 분리
- 읽기 작업은 락 없이 수행되며, 쓰기 작업만이 부분적으로 락을 사용