[F-Lab 챌린지 48일차 TIL]

성수데브리·2023년 8월 14일
0

f-lab_java

목록 보기
38/73

반복문

  • switch-case 문에서 String 을 비교하는 방법

    public class SwitchStudy {
    
        public static void main(String[] args) {
            String value = "AAA";
            switch (value) {
                case "AAA":
                    System.out.println("A");
                case "BBB":
                    System.out.println("B");
            }
        }
    }
    
    INVOKEVIRTUAL java/lang/String.hashCode ()I
        LOOKUPSWITCH
          64545: L2
          65538: L3
          default: L4

    String hashCode 를 생성해 int 를 비교한다.

    • 숫자들이 정렬되어 있다.
    • switch-case 문의 case 가 많을 경우 작은 숫자부터 큰 숫자를 비교하는 게 가장 빠르다.
  • for 문 내부에서 주의할 점

    1. 불필요한 size() 메서드를 반복해서 호출하지 않는다.

      ArrayList<Object> list = new ArrayList<>();
      // list.size();
      
      for (int i = 0; i < list.size(); i++) {
          System.out.println("do something");
      }
    2. 반복 구문에서 필요 없는 반복 피한다.

static

  1. 전역에서 접근할 수 있는 값임을 항시 주의하자.
  2. static 은 GC 대상이 아니다.
  3. 메모리 릭
    1. Collection 객체를 전역변수로 선언하면 하고 이 객체에 지속적으로 데이터가 쌓인다면 메모리릭이 발생할 수 있다.

Reflection

  • reflection 관련 클래스를 사용해 클래스 정보를 얻는 것은 유용하나 Class 인스턴스화를 해가며 반드시 필요한 작업인가? 고민을 해봐라

    예시

    this.getClass().getName()
    • getClass() 메서드를 호출하면 Class 객체를 만들고, 그 개체의 이름을 가져오는 메서드를 수행하는 시간과 메모리를 사용할 뿐이다.
    • 많이 호출하면 문제가 발생할 수 있으니 고려하고 사용하자

synchronized

  • interrupt() 이 메서드는 해당 스레드가 block 되거나 특정 상태에서만 작동한다.
  • synchronized 는 각각의 객체에 대한 동기화를 하는 것이다. 아래 코드는 amount 클래스 변수에 대한 동기화가 되지 않는다.
    public class Contribution{
    	private static int amount = 0;
    	public synchronized void denote(){
    		amount++;
    	}
    	public int getTotal(){
    		return amount;
    	}
    }
    아래처럼 denote() 메서드도 static 을 선언해야 amount 클래스 변수 동기화가 된다.
    public class Contribution{
    	private static int amount = 0;
    	public static synchronized void denote(){
    		amount++;
    	}
    	public int getTotal(){
    		return amount;
    	}
    }
  • JVM 에서 synchronized 가 동작하는 방법
    • Java Monitor 를 제공한다.
    • 모니터는 lock 이나 unlocked 둘 중 하나이며, 동일한 모니터에 진입한 여러 스레드들 중에서 한 시점에는 단 하나의 스레드만 모니터를 가질 수 있다. 모니터를 가진 스레드만 모니터에 의해서 보호되는 영역에 들어가서 작업을 할 수 있다.
  • 동기화는 비용이 큰 작업이니 꼭 필요한 상황에서만 사용하자

IO, NIO

  • IO 에서 버퍼을 활용하면 IO 처리 속도를 개선할 수 있다.
  • 불필요하게 IO 를 반복해서 호출하는 경우가 있다. 주의하자
  • IO 의 프로세스
    1. 파일 읽기 요청
    2. 메서드 OS 커널에 파일 읽기 요청
    3. 커널 하드 디스크로부터 파일 읽어서 자신의 커널 영역의 버퍼에 복사
    4. 이 버퍼를 JVM 으로 복사
    5. JVM 스트림 관리 클래스로 데이터 처리
  • NIO 는 3번 작업을 직접 통제하여 시간을 더 단축할 수 있게 한 것이다.
  • DirectByteBuffer : Singleton 패턴을 사용해 해당 JVM 에는 하나의 객체만 생성하도록 권장한다. 그 이유는 아래와 같다.

allocateDirect() 를 호출하면 DirectByteBuffer 를 생성한다.

이 메서드는 데이터를 JVM 에 올려서 사용하는 것이 아니라, OS 메모리에 할당된 메모리를 Native로 한 JNI로 처리하는 DirectByteBuffer 객체를 생성한다.

필요할 때마다 매번 생성해서는 안된다.

reserveMemory() 메서드에서는 JVM 에 할당된 메모리보다 더 많은 메모리를 요구할 경우 System.gc() 를 호출하도록 되어 있다.

JSP 와 서블릿, Spring

서블릿은 요청당 새로 생성되는게 아니라 생성해둔 서블릭 객체를 사용하니
static 변수나 멤버 변수를 선언하여 지속적으로 변경하는 작업은 피하자.

0개의 댓글