• 서블릿 컨테이너, 웹서버

    • 서블릿 컨테이너는 자바 기반 웹 애플리케이션의 실행 환경(WAS)이며, 웹 서버는 정적 리소스 서빙 및 요청 분산 역할을 담당합니다.
    • 보통 운영 환경에서는 웹 서버(Nginx) + 서블릿 컨테이너 구조(Tomcat) 구조로 구성합니다.
    • (개발 환경에서는 Spring Boot 자체 내장 Tomcat으로 웹 서버 없이 개발이 가능하지만, 운영 환경에서는 Nginx를 앞단에 두어 정적 자원은 직접 서빙하고, API 요청은 백엔드 서버로 전달하는 리버스 프록시 구조로 구성됩니다.)
  • 웹서버, 웹어플리케이션 서버

      [클라이언트] 
         ↓
      [Nginx (웹 서버)]
         ├─ /js/**, /index.html → 정적 리소스 직접 응답
         └─ /api/** → Spring Boot + Tomcat(WAS)으로 전달
                        └─ Controller → Service → DB
    • 웹 서버는 HTML, CSS, JS, 이미지 등 정적 리소스를 빠르게 응답해주는 역할을 하며, 웹 애플리케이션 서버는 로그인, 게시글 처리 등 비즈니스 로직과 DB 연동이 필요한 동적 요청을 처리합니다.
    • 운영 환경에서는 Nginx(웹 서버)가 클라이언트 요청을 먼저 받아 정적 자원은 직접 응답하고, 나머지 API 요청은 Tomcat(WAS)으로 전달해 요청 분산, 보안, 응답 속도 개선등 다양한 장점을 확보할 수 있습니다.
  • Tomcat

    • Tomcat은 자바 기반의 웹 애플리케이션 서버로 HTTP 요청을 처리하고 서블릿을 실행해 비즈니스 로직을 처리합니다. Spring Boot에서는 내장 톰캣을 사용해 별도 설정 없이 실행 가능하며, 실제로는 정적 자원 처리 성능이 낮기 때문에 운영 환경에서는 Nginx와 함께 사용하는 것이 일반적입니다.

      // 동작흐름 (Spring 기준)
      클라이언트 요청
       ↓
      내장 Tomcat (요청 수신 및 서블릿 생성)
       ↓
      DispatcherServlet 실행
       ↓
      Controller → Service → DB
       ↓
      응답 반환
      
      WAS(웹 애플리케이션 서버)
      └─ 서블릿 컨테이너 (HTTP 요청 → 서블릿 실행)
         └─ Tomcat (대표적인 서블릿 컨테이너)
      
  • Spring annotation

    • Spring에서는 컴포넌트 등록, DI, HTTP 요청 처리, 트랜잭션 관리 등 다양한 기능을 애노테이션 기반으로 제공합니다.
    • 이를 통해 설정 파일 없이도 선언적으로 필요한 기능을 명확하게 지정할 수 있어 개발 생산성과 유지보수성이 향상됩니다.
  • 자바의 동시성 이슈(공유자원 접근)

    • 여러 스레드가 동시에 공유 자원에 접근하면서 발생하는 문제입니다. 이를 해결하기 위해 synchronized, Lock, Atomic 클래스 등을 활용하여 임계 구역을 보호하거나 Concurrent 패키지의 안전한 자료구조를 사용하는 것이 일반적입니다.
  • 프로세스, 스레드

    • 프로세스는 실행중인 프로그램을 의미하며 운영체제로부터 독립적인 자원을 할당받습니다.
    • 스레드는 프로세스 내부에서 실행 제어만 분리한 것으로 코드, 데이터, 힙 영역은 공유하고 스택은 별도로 가집니다.
    • 스레드는 자원 공유 덕분에 프로세스 간 통신보다 효율적이며, 컨텍스트 스위칭 시 캐시 메모리를 비우지 않아 전환 비용이 적습니다.
    • 하지만, 자원 공유로 인해 동기화 문제 등 동시성 이슈에 주의해야 합니다.
    • 한 프로세스 안에 여러 개의 스레드가 생성될 수 있으며 이를 통해 비동기 처리나 멀티 태스킹이 가능합니다.
  • Context Switching

    • 한 Task가 끝날 때까지 기다리는 것이 아니라 여러 작업을 번갈아가며 실행해서 동시에 처리될 수 있또록 하는 방법입니다.
    • 인터럽트가 발생하면 현재 프로세스의 상태를 PCB에 저장하고 새로운 프로세스의 상태를 레지스터에 저장하는 방식으로 동작합니다. 이때, CPU는 아무런 일을 하지 않으므로 잦은 컨텍스트 스위칭은 성능저하를 일으킬 수 있습니다.
    • 스레드와 프로세스의 동작방식이 약간 상이한데, 스레드는 캐시메모리나 PCB에 저장해야하는 내용이 적고, 비워야 하는 내용도 적기때문에 상대적으로 더 빠른 컨텍스트 스위칭이 일어날 수 있습니다.
  • 멀티스레드 프로그래밍

    • 하나의 프로세스에서 여러개의 스레드를 만들어 자원의 생성과 관리의 중복을 최소화하는 것을 의미합니다.
    • 장점
      • 멀티 프로세스에 비해 메모리 자원소모가 줄어듭니다.
      • 힙 영역을 통해서 스레드간 통신이 가능해서 프로세스간 통신이 가능합니다.
      • 스레드의 컨텍스트 스위칭은 컨텍스트 스위칭보다 빠릅니다.
    • 단점
      • 힙 영역에 있는 자원을 사용할 때는 동기화를 해야합니다.
      • 동기화를 위해서 락을 과도하게 사용하면 성능이 저하될 수 있습니다.
      • 하나의 스레드가 비정상적으로 동작하면 다른 스레드도 종료될 수 있습니다.
  • 동기 비동기 (블로킹, 넌블로킹) / 장단점도 포함

    • 동기/비동기는 두 개 이상의 무엇인가가 시간을 맞춘다/안맞춘다로 구분할 수 있습니다.
    • 동기 방식은 메서드 리턴과 결과를 전달받는 시간이 일치하는 명령 실행 방식입니다. 또, 동기방식은 한 함수가 끝나는 시간과 바로 다음의 함수가 시작하는 시간이 같습니다.
    • 비동기 방식은 여러 개의 처리가 함께 실행되는 방식으로, 동기 방식에 비해 단위시간 당 많은 작업 처리가 가능합니다. 단, CPU나 메모리를 많이 사용하는 작업을 비동기로 처리하게 되면 과부하가 걸릴 수 있습니다. (프로그램의 복잡도 증가)
    • 블로킹/논블로킹은 다른 관점으로, 내가 직접 제어할 수 없는 대상을 상대하는 방법에 대한 분류입니다.
    • 블로킹 방식은 대상의 작업이 끝날 때 까지 제어권을 대상이 가지고 있는 것을 의미합니다. 반면에 논블로킹은 대상의 작업 완료여부와 상관없이 새로운 작업을 수행합니다.
    • 동기 논블로킹은 계속해서 polling을 수행하기 때문에 컨텍스트 스위칭이 지속적으로 발생해 지연이 발생합니다.
  • Thread-safe?

    • 두 개 이상의 스레드가 race condition에 들어가거나 같은 객체에 동시에 접근해도 연산결과의 정합성이 보장될 수 있게끔 메모리 가시성이 확보된 상태를 의미합니다.

  • flush란?

    • flush()는 영속성 컨텍스트에 저장되어 있는 변경 내용을 DB에 반영하는 작업으로, 트랜잭션 커밋이나 JPQL 실행 전 자동으로 발생합니다.

    • readOnly = true 설정 시 flush를 막아 쓰기 연산을 방지하고 성능을 최적화할 수 있습니다.

      @Entity 객체 변경 → 영속성 컨텍스트에 저장됨 (1차 캐시 상태)
          ↓
      flush() 발생
          ↓
      DB에 SQL 실행 (INSERT, UPDATE, DELETE 등)
  • static vs non-static 변수의 동시성 이슈 발생 상황
    • static 변수는 클래스 전체에서 공유되기 때문에 기본적으로 동시성 이슈가 발생할 수 있고,
    • non-static 변수는 객체마다 별도지만, 동일 인스턴스를 여러 스레드가 공유할 경우 문제의 여지가 있습니다.
    • 따라서 설계 단계에서 상태 공유를 피하거나, 필요한 경우 동기화 기법으로 보호하는 것이 중요합니다.

'CS 및 면접복기' 카테고리의 다른 글

20250811 - Network  (2) 2025.08.11
20250808  (3) 2025.08.08
20250806 - ALL  (3) 2025.08.06
20250805 - DB(1)  (4) 2025.08.05
20250804 - Java(2)  (4) 2025.08.04

+ Recent posts