Java

Java

    [Java] 가비지 컬렉션(GC, Garbage Collection) 기초

    [Java] 가비지 컬렉션(GC, Garbage Collection) 기초

    시스템에 있는 모든 객체의 수명을 정확히 몰라도 런타임이 대신 객체를 추적하며 쓸모없는 객체를 알아서 제거하는 것 GC의 2가지 기본 원칙 알고리즘은 반드시 모든 가비지를 수집해야 한다. 살아 있는 객체는 절대로 수집해선 안된다. 2번째 원칙이 더 중요하다. 살아 있는 객체를 수집했다간 세그먼트 폴트가 발생하거나 프로그램 데이터가 나도 모르게 변형될 것이다. 따라서 GC 알고리즘은 프로그램이 사용 중인 객체를 절대 수집해선 안된다. STW(Stop-The-World) GC가 실행되어 힙의 메모리를 반환하는 동안에는 GC에 할당된 스레드를 제외한 모든 스레드가 멈추게 된다. 이러한 상태를 Stop the World라고 하고 어떠한 GC 알고리즘을 사용하더라도 STW 상태에 부딪히게 된다. 따라서 GC 튜닝..

    옵저버 패턴 (Observer Pattern)

    옵저버 패턴 (Observer Pattern)

    옵저버 패턴 (Observer Pattern) 객체의 상태 변화을 감지하고 연결된 다른 객체의 상태를 쉽게 변경할 수 있도록 한다. 일대다 의존 관계를 구성해서 하나의 객체가 상태를 변경하면 모든 의존 객체에게 자동으로 알림이 전송되고 업데이트 하는 패턴이다. 주로 사용하는 곳 알림, 이벤트 기능이 필요한 대부분의 기능에서 해당 패턴을 사용한다. Android의 Event Listener 브라우저의 Event Handler Java Swing 라이브러리(GUI) 이외에도 GUI 프로그래밍을 하거나 메시지 발송과 같은 기능을 사용한다면 옵저버 패턴이 빠질 수 없다. 용어 정리 Subject : 상태 변경을 알려주는 객체 (발행인) Observer : 상태 변경에 대한 알림을 받는 객체 (구독자) 헷갈리는 ..

    전략 패턴 (Strategy Pattern)

    전략 패턴 (Strategy Pattern)

    전략 패턴 (Strategy Pattern) 객체들이 할 수 있는 행위에 대해 전략 클래스를 생성하고, 유사한 클래스를 캡슐화하는 인터페이스를 정의한다. 객체의 행위를 동적으로 수정하고 싶은 경우, 직접 행위를 수정하지 않고 전략을 바뀌주기만 함으로써 행동을 유연하게 확장할 수 있다. 즉, 일련의 알고리즘을 정의하고 각각을 캡슐화하고, 상호 교환 가능하게 만든다. 패턴을 사용하면 알고리즘을 사용하는 클라이언트와 독립적으로 알고리즘을 변경할 수 있게 된다. 샘플 오리 프로그램 Duck을 상속받는 RedheadDuck과 MallardDuck이 존재한다. 이들은 Duck에 속하는 객체로서 공통된 quack, swim 메서드를 수행하고, display 메서드는 오버라이딩해서 각자에 맞게 사용한다. 요구사항 추가..

    [Java] Lambda 특징과 활용

    [Java] Lambda 특징과 활용

    람다란? (lambda) 익명 메서드에 이름이 없다. 람다는 메서드에 이름이 필요없기 때문에 익명 함수로 분류되며, 익명 함수는 모두 일급 객체로 취급된다. 함수 특정 클래스에 종속되지 않기 때문에 함수라고 부를 수 있다. 하지만 메서드처럼 파라미터 리스트, 바디, 반환 형식, 가능한 예외 리스트를 포함한다. 전달 람다 표현식을 메서드 인수로 전달하거나 변수로 저장할 수 있다. 이는 일급 객체의 특징과도 같다. 일급 객체로 취급되기 때문에 Stream API의 매개변수로 전달이 가능하다. 간결성 익명 클래스처럼 판에 박힌 코드를 구현할 필요가 없다. 따라서 불필요한 코드를 줄이고 가독성을 높일 수 있다. 람다의 장점과 단점 장점 코드의 간결성 람다를 사용하면 불필요한 반복문의 삭제가 가능하며 복잡한 식을..

    함수형 프로그래밍과 Java #1

    함수형 프로그래밍 왜 Java8부터 함수형 프로그래밍을 지원하게 되었을까? 왜 Spring5 부터 WebFlux를 필두로 리액티브 프로그래밍을 지원하는 것일까? Java 8 이후로 나타난 '람다', 'Stream API' 등을 깊게 이해하기 위해서는 이들이 왜 생겨났는지를 알면 매우 좋을 것이라고 생각했다. 객체지향의 정수라고 할 수 있는 Java가 람다를 도입하고 함수형 프로그래밍을 지원한다는건 다른 언어들도 점차 함수형으로 바뀔 것을 의미한다고 생각한다. 나중에 개발 전반적으로 함수형 패러다임이 도입되었을 때 잘 사용하려면 미리 배워놓는게 중요하다. 함수형 패러다임의 중요한 포인트는 언어가 점점 발달하고 하드웨어의 스펙이 받쳐주면서 자바의 가비지 컬렉션처럼 메모리 관리를 추상화해주는 언어가 발달하게 ..

    [디자인 패턴] 싱글톤 패턴 (Creational)

    싱글톤(Singleton) 전역 변수를 사용하지 않고 객체를 하나만 생성 하도록 하고, 생성된 객체를 어디에서든지 참조할 수 있도록 하는 패턴 클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴이다. 주의사항 객체 인스턴스를 2개 이상 생성하지 못하도록 막아야 한다. -> private 생성자를 사용해서 외부에서 임의로 new 키워드를 사용하지 못하도록 막아야 한다. 다중 스레드에서 경합 조건(Race Condition)이 발생해 인스턴스가 2개 이상 생성되는 경우를 막아야 한다. 아래 코드는 위 주의사항을 잘 지킨 예시이다. public class SingletonService { private static final SingletonService instance = new Singlet..

    [Java] Runnable과 Thread의 차이

    [Java] Runnable과 Thread의 차이

    자바에서 쓰레드를 구현할 때 2가지 방법이 있다고 한다. 1. Runnable 2. Thread 1. Runnable Runnable은 이름부터 인터페이스의 느낌이 강하다. implements Runnable 을 통해서 Runnable 인터페이스를 구현할 수 있다. Runnable 인터페이스를 구현하게되면 재사용성이 높고, 코드의 일관성을 유지할 수 있어서 Thread보다 더 효율적인 방법이라 할 수 있다. Runnable 인터페이스는 위와 같이 생겼다. 추상 메서드 run을 반드시 구현해야 한다. Thread도 run을 구현해야 한다는 점은 같지만 추상 메서드가 아니라 단순 메서드 오버라이딩으로 구현한다. Runnable 인터페이스를 구현해 스레드 구현 public class Main { public ..

    [Java] 추상 클래스와 인터페이스 (abstract class & interface)

    Java 추상 클래스와 인터페이스는 기능적으로 아주 유사하다. Java를 공부하면서 이 둘이 왜 나눠졌는지 이해하는건 자바 언어의 철학을 이해하는데 한 걸음 다가간다고 생각했다. 따라서 둘의 공통점 및 구분되는 특징을 조사해보고 인터페이스, 추상 클래스를 사용하는 클래스 다이어그램을 설계하고 코드로 실습을 해 보았다. 인터페이스의 특징 - 동일한 기능을 가지는 객체들에 대한 기능적인 '틀'을 제공한다. A(자식) Has a B(부모) - 다중 상속이 가능하다. - 하나의 규칙으로 적용된다. - 자식 요소들과 Has a (~할 수 있는) 관계를 가진다. (자식들이 공통된 기능을 가진다.) - 즉, 상속 받는 객체들이 할 수 있는 '기능'에 대해 미리 정의한다. - 주로 '~able'로 끝나도록 명명한다. ..

    [Java] Call by Reference? Call by Value!

    Java에서 Call by value와 Call by reference를 구분하는 방법은 매서드의 매개변수의 자료형에 달려있다. Java에서는 개발자가 포인터를 사용할 수 없도록 되어있다. 그래서 바꾸길 원하는 값의 주솟값을 넘길 수 없다. 아래 코드를 보자 class Number{ public void increase(int count){ count++; } } public class Main { int count = 0; public static void main(String[] args){ Main mainNumber = new Main(); Number newNumber = new Number(); newNumber.increase(mainNumber.count); System.out.printl..