Skip to content

김현수 2주차 개인 회고

Kim Hyunsu edited this page Jul 5, 2024 · 13 revisions

목록: 김현수

240702

🛜 ServerSocket

new ServerSocket(port) 하면 일어나는 일

  • 8080포트에 소켓이 바인딩
  • listen() 호출
  • 운영체제 단에서 SYN(TCP 연결 요청 SYN 패킷을 저장하는) 큐와 accept(완전히 설정된 연결을 저장하는) 큐가 준비됨

클라이언트 연결 요청이 들어오면 SYN 큐에 들어가고 3-way handshake가 완료되면 accept 큐로 이동합니다. image

accept()을 하면 일어나는 일

  • accept() 큐에 있는 연결을 가져와 처리함

20240703

🔎 Http GET 요청

예시

GET / HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
Cache-Control: no-cache
Connection: keep-alive
Cookie: _ga=GA1.1.1431898558.1697529922; _ga_NWNSZKYZVP=GS1.1.1699408030.2.0.1699408030.0.0.0; _ga_XQJBHXWEGK=GS1.1.1719145237.29.1.1719145311.0.0.0
Host: localhost:8080
Pragma: no-cache
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36
sec-ch-ua: "Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"

GET / HTTP/1.1 : request Line method target version 으로 구성됨

헤더
\\r\\n
바디
\\r\\n

로 구성됨

❗️요청을 반환할 때 Content-Type 과 Content-Length를 명시해주지 않으면 브라우져가 어디까지 읽어야하는 지 몰라 network reset이 발생할 수 있음

240704

📝 Java Thread의 역사

  1. 초기 자바 스레드(Java 1): 초기 자바는 운영체제 수준의 스레드를 직접 매핑하여 사용함.
  • Thread 클래스와 Runnable 인터페이스 도입
  • synchronized 키워드 wait(), notify() 메서드 제공
  1. concurrent 패키지 도입(Java 5: 저수준 스레드 관리의 복잡성 해결, 재사용 가능한 동시성 패턴 제공을 위해
  • ExecutorService, Callable, Future 등 고수준 동시성 유틸리티 제공
  • 스레드 풀, 동기화 도구(Semaphore CountDownLatch 등) 도입
  1. Fork/Join 프레임워크(Java 7): 멀티코어 프로세서의 보편화로 병렬 처리의 효율성을 높이기 위해 도입됨.
  • 분할 정복 알고리즘을 위한 프레임워크
  • 작업 훔치기 알고리즘을 통한 부하 분산
  1. 람다식과 스트림 API(Java 8): 코드의 간결성을 높이고, 선언적 프로그래밍을 통해 동시성 처리를 더 쉽게 만들기 위해
  • 함수형 프로그래밍 지원
  • 병렬 스트리밍을 통한 간편한 병렬 처리
  1. CompletableFuture(Java 8): 복잡한 비동기 작업 흐름을 더 쉽게 관리하고 조합할 수 있도록 하기 위해 도입
  • 비동기 프로그래밍을 위한 강력한 도구 제공
  • 콜백 지옥을 피하고 비동기 작업의 조합을 용이하게 함
  1. 리액티브 스트림(Java 9): 데이터 스트림을 비동기적으로 처리하고 백프레셔를 관리하기 위한 표준화된 방법을 제공하기 위함
  • Flow API 도입
  • 비동기 스트림 처리를 위한 표준 제공
  1. 가상 스레드(Java 19): I/O 작업이 많은 애플리케이션에서 동시성을 대폭 향상시키고, 스레드 관리의 오버헤드를 줄이기 위해 도입되고 있음
  • 경량 스레드 도입
  • 기존 플랫폼 스레드의 한계 극복

초기 자바는 구현을 편하게 하기 위해 저수준의 스레드를 직접 사용하도록 구현했다.

하지만 사용자가 직접 스레드를 개발하는 것이 너무 복잡하고 스레드를 매번 생성하고 삭제하면서 비용이 많이 들어서 concurrent 패키지를 통해 복잡도를 해결하고 스레드 재사용을 늘리고자 노력했다.

그러나 멀티코어가 대중화되면서 대규모 병렬 처리에 대한 수요가 증가했는데 concurrent 패키지는 재귀나 분할 정복에 대한 최적화가 되어있지 않았다. 그래서 대규모 병렬 처리를 위한 Fork/Join 프레임워크와 바쁜 스레드의 작업을 가져와 처리하는 작업 훔치기가 등장했다.

이후 함수형 프로그래밍이 등장하면서 병렬 처리 코드를 간단히 표현할 수 있게 되면서 람다식과 스트림, CompleteFuture가 등장하였고, 실시간, 비동기적 데이터를 효율적으로 처리하기 위해 리액티브 스트림이 등장하였다.

그 후 OS 스레드의 제한적인 수와 오버헤드를 해결하고 CPU 처리보다는 I/O 처리가 더 중요해지면서 OS 스레드 1개당 여러 개의 가상 스레드를 실행하면서 높은 동시성을 제공하고 효율적으로 리소스를 사용하고자 등장했다.

🤔 이렇게 발전한 이유에 대한 생각

자바의 스레드는 하드웨어와 소프트웨어 환경에 따라 더 자원을 효율적으로 사용하고 편리하게 사용할 수 있는 방법으로 변화해갔다. AI 발전에 의한 스레드 자동 스케줄링 같은 기능이 등장해 더 빠르고 효율적인 자원 사용 방법이 등장하지 않을까 예상한다.

240705

🫗 Buffered I/O Stream vs I/O Stream

  • I/O Stream

    • 장점
      • 실시간 응답
      • 메모리를 추가적으로 사용하지 않는다.
    • 단점
      • 각 쓰기 작업마다 커널에 접근한다.

    실시간 응답을 제공하지만 계속 커널 영역에 접근하면서 각 I/O 마다 컨텍스트 스위칭이 발생해 오버헤드를 발생시킨다.

  • Buffered I/O Stream

    • 장점
      • 내부 메모리 버퍼에 모아서 한번에 작성한다.
      • 커널 영역에 접근하는 횟수가 줄어들어 오버헤드가 감소한다.
    • 단점
      • 버퍼가 차기 전까지 실제 I/O가 지연될 수 있다.
      • 메모리 사용을 신경 써야한다.

    대부분의 경우에서 Buffered I/O stream가 좋다.

🧑‍⚖️ 결론

시스템 전체의 아키텍처를 고려해서 I/O 작업의 특성을 이해하고 적용하는 것이 좋다.

👼 개인 활동을 기록합시다.

개인 활동 페이지

🧑‍🧑‍🧒‍🧒 그룹 활동을 기록합시다.

그룹 활동 페이지

🎤 미니 세미나

미니 세미나

🤔 기술 블로그 활동

기술 블로그 활동

📚 도서를 추천해주세요

추천 도서 목록

🎸 기타

기타 유용한 학습 링크

Clone this wiki locally