콘텐츠로 이동

2021 04 12

2021-04-12

체스 최종 피드백

  • 동시에 게임을 진행하는 것? - ex. 게임 1은 player A/B가, 게임 2는 player C/D가 진행한다고 생각하자 - 우선 프론트에서 새로운 방 만들기 버튼을 누르겠지? - 그러면 기존 DB를 참조해서 현재 game_id에 +1 한 숫자를 반환하겠지? - 해당 game_id + 1을 통해 url로 /1 같이 표시를 나타내 주자 - 그러면 동시에 게임 1과 게임 2에서 move 명령을 준다고 하면, - ChessGameDAO에서 move를 처리하자 - 각각 고유의 체스게임을 불러오고 move를 처리하기에 문제가 없을듯? - 각자 thread에 스택이 쌓이고 거기에서 move를 처리하니까?
  • 웨지와 함께한 웹 얘기 > 웹 서버(Apache)와 웹 애플리케이션 서버(tomcat)에 대해 책에서 언급하는데 아직 웹 애플리케이션 서버에 대해 감이 잘 안잡혀요.
    웹 서버는 HTTP 요청을 받아 정적 자원을 반환하는 것에 집중하고,
    웹 애플리케이션은 동적인 페이지 생성을 위한 DB 연동등의 작업을 수행한다고 읽었어요.
    하지만 웹 애플리케이션 서버와 웹 프레임워크의 차이를 아직은 잘 모르겠고요. 레벨 2에서 차차 공부해 나가면 될 것 같아요!

    - 웹 프레임워크: HTTP 요청을 해석(웹 서버 역할) + 자바 코드와 연결(WAS의 역할) 을 제공하는 웹 애플리케이션을 만들 수 있도록 도와주는 라이브러리 - 웹 애플리케이션 서버: 자바 코드와의 연결 및 다양한 기능을 분리하여 아예 프로그램으로 만든 것 (tomcat 등)

    - 체스 코드들 중 스파크 코드를 제외하고 "WAR" 이라는 압축파일로 만들어서,
    WAS 내부 디렉토리에 넣어주고 실행하면,
    웹 서버가 주는 요청을 받아 WAR 코드를 해석하여 html 파일로 만들어 웹 서버에 반환.

    - WAR - Web Archive의 약자로, 웹 앱 압축/배포 할 때 사용. - WAR는 자바 클래스, 자바 서버 페이지, XML, JS, 정적 웹 페이지등의 자원을 모아 웹 앱의 배포를 가능케 함 - web.xml이라는 배포 서술자를 통해 경로를 지정해줘야 웹 애플리케이션 서버가 WAR를 실행할 수 있음

테코톡 복습

  • SPA - MPA(Multi-Page Application) && SSR(Server-Side Rendering) - 장점: 검색엔진 최적화에 유리함 / 빠른 초기 로딩 속도 - 단점: 불편한 UX / 서버 부하가 큼 - SPA(Single-Page Application) && CSR(Client-Side Rendering) - 장점: 빠른 속도 / 서버 부하 줄어 듦 - 단점: 검색 엔진 최적화에 불리 / 느린 초기 로딩 속도
  • Singleton과 정적 클래스 - Singleton: 클래스의 인스턴스를 하나만 생성하고, 어디서든 그 인스턴스를 참조하도록 하는 패턴 - 장점 - 고정된 메모리 영역을 가지기에 메모리 낭비 X - Singleton Class의 instance는 전역이기에 다른 클래스의 instance들과 데이터 공유가 쉽다 - DBCP(DataBase Connection Pool)처럼 공통된 객체를 여러개 생성해야 하는 상황에 많이 사용 - 생성 방법 1. Eager initialization - private static Class instance = new Class(); - 클라이언트에서 사용하지 않더라도 인스턴스 항시 생성... 굳이 메모리 차지 - 예외 처리 할 수 있는 방법 X - Static block 안에서 해주자 -> Static block initialization 2. Lazy initialization - getInstance() 호출 외에는 인스턴스 생성 X - Object.isNull -> 새로이 생성 - Eager init 단점 보완 - thread safe X 3. Thread safe initialization - synchronized 예약어를 통해 하나의 예약어만 쓰자 4. Double-Checked Locking - Object.isNull 일때 synchronized를 실행 5. Bill Pugh Solution
    public class BillPughSingleton {
        private BillPughSingleton() {
        }
    
        private static class SingletonHelper {
            private static final BillPughSingleton INSTANCE = new BillPughSingleton();
        }
    
        public static BillPughSingleton getInstance() {
            return SingletonHelper.INSTANCE;
        }
    }
    
              - Lazy Loading 가능
              - Thread Safe
    

    - 정적 클래스: 모든 메소드가 static인 클래스 - 장점 - 상태 안가지고, global access 제공시 유용 - Static은 컴파일 때 static binding으로 싱글턴 보다 조금 더 빠름 - Static variable - 메모리에 고정적으로 할당되어, 프로그램이 종료될 때 해제되는 변수 - Static method - 객체 생성 없이 메서드 호출 바로 가능 - 객체 생성 없이 접근하는 메서드라, static이 아닌 변수 사용 X - Inner Class - 외부 클래스는 내부 클래스를 멤버 변수처럼 사용 - 내부 클래스는 외부 클래스의 자원 사용가능 - 내/외부 클래스 간의 강한 결합 - 내부 클래스 역할 끝나도 GC가 못지워 - Static class - 외부 클래스의 자원 중 static이 붙은 것만 사용이 가능하다!

    public class OuterClass {
        private static String croffle = "Croffle";
        private String waffle = "Waffle";
    
        static class Inner {
            public void printName() {
                System.out.println(croffle); //정상 동작
                System.out.println(waffle); //오류!
            }
        }
    }
    

    - 싱글턴은 OOP인가? - 상태를 가진다면, 어려 쓰레드에서 접근하여 상태를 바꾸면 큰일남 - 상태 없는 객체나, 설계상 유일해야 하는 시스템 컴포넌트를 싱글턴으로 구현하자

  • Stream - 정의 - 모던 자바: Data 처리 연산을 지원하도록 소스에서 추출된 연속된 값 요소 - 이것이자바다: Collection 요소를 하나씩 참조해 Lambda 식으로 처리할 수 있는 반복자 - 장점 - How 중심의 코드를 What 중심의 코드로 변경 - 연산에 필요한 매개변수 X - 내부 반복 --> 외부 반복 - 자료구조가 포함하는 모든 값을 메서드에 포함하는 컬렉션과 다르게, 스트림은 요청할 때만 요소를 계산하는 고정된 자료구조를 가진다 - 스트림은 여러 개의 조건이 중첩된 상황에서 값이 결정나면 불필요한 연산을 진행하지 않고, 조건문을 빠져나와 실행 속도를 높인다 - 사용법 - 스트림 생성 --> 중간 연산 --> 최종 연산 - flatMap - Collection이 중첩된 경우 사용
    List<Fish> manyFish = fishes.stream()
        .map(Net::getFishes)
        .flatMap(List::stream)
        .collect(Collectors.toList());
    
      - reduce
          - 요소를 하나씩 가져와서 람다식 처리
              - 스트림의 요소는 소모된다!
    

Optional

  • 정의 - "존재할 수도 있지만, 안할 수도 있는 객체" - "null이 될 수도 있는 객체"를 감싸고 있는 일종의 래퍼 클래스 - 원소가 없거나, 최대 하나밖에 없는 Collection이나 Stream
  • Optional 객체 생성 - Optional.empty() - null을 담고 있는 Optional 객체 - 비어있는 Optional 객체를 생성 - Optional.of(value) - null이 아닌 객체를 담고 있는 Optional 객체 - null오면 NPE 던짐 - Optional.ofNullable(value) - null인지 아닌지 확인할 수 없는 객체 생성
  • Optional 객체 접근하기 - get() - orElse(T other) - orElseGet(Supplier<? extends T> other) - orElseThrow(Supplier<? extends X> exceptionSupplier) - 기존에 조건문으로 null을 대하던 생각을 "함수형 사고"로 바꿀 것
  • Optional 적용하기 - null-safe한 코드 작성
    public String getCityOfMemberFromOrder(Order order) { 
        return Optional.ofNullable(order)
                  .map(Order::getMember)
                  .map(Member::getAddress)
                  .map(Address::getCity)
                  .orElse("Seoul");
    }
    
    Map<Integer, String> cities = new HashMap<>();
    cities.put(1, "Seoul");
    cities.put(2, "Busan");
    cities.put(3, "Daejeon");
    
    String city = cities.get(4); // returns null
    int length = city == null ? 0 : city.length(); // null check
    System.out.println(length);
    
    Optional<String> maybeCity = Optional.ofNullable(cities.get(4)); // Optional
    int length = maybeCity.map(String::length).orElse(0); // null-safe
    System.out.println("length: " + length);