자바 8 이전에는 SimpleDateFormat이 thread-safe가 아니기 때문에 ThreadLocal로 사용하였다.


자바 8에서는 DateTimeFormatter가 thread-safe이기 때문에 다음과 같이 사용할 수 있다.


public class DateUtils {


    private static final DateTimeFormatter DEFAULT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");


    public static String format(Date date) {

        LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());

        return localDateTime.format(DEFAULT_FORMATTER);

    }


}


다음은 테스트 코드이다.


public class DateUtilsTest {


    @Test

    public void format() {

        Date date = new Date();

        String formatted = DateUtils.format(date);

        System.out.println(formatted);

    }


}


기존 Date 타입의 포맷팅은 새로운 타입으로의 변환이 필요하기 때문에 다소 복잡해보일 수 있다.


Reference:

http://stackoverflow.com/questions/25561377/format-localdatetime-with-timezone-in-java8

Posted by izeye

다음은 Apache Commons Collections 라이브러리 (Library) 내 CircularFifoQueue 예제이다.


public class CircularFifoQueueTest {


    @Test

    public void test() {

        CircularFifoQueue<Integer> circularFifoQueue = new CircularFifoQueue<Integer>(5);

        for (int i = 0; i < 10; i++) {

            circularFifoQueue.add(i);

            System.out.println(circularFifoQueue);


            System.out.println(circularFifoQueue.get(circularFifoQueue.size() - 1));

        }

    }


}


다음 디펜던시 (Dependency)를 추가한다.


compile 'org.apache.commons:commons-collections4:4.0'


다음은 Google Guava 라이브러리 내 EvictingQueue 예제이다.


public class EvictingQueueTest {


    @Test

    public void test() {

        EvictingQueue<Integer> evictingQueue = EvictingQueue.<Integer>create(5);

        for (int i = 0; i < 10; i++) {

            evictingQueue.add(i);

            System.out.println(evictingQueue);

        }

    }


}


다음 디펜던시를 추가한다.


compile 'com.google.guava:guava:17.0'


Queue이기 때문에 FIFO 구조로 쓰는 것이 맞겠으나,


특별히 랜덤 엑세스가 필요한 경우에는 Apache Commons Collections를 사용하면 되겠다.


Reference:

http://stackoverflow.com/questions/5498865/size-limited-queue-that-holds-last-n-elements-in-java/15156403#15156403

Posted by izeye

String.hashCode()로 전화 번호를 해쉬하면,


역으로 해쉬 값으로부터 전화 번호를 찾아낼 수 있을까?


간단히 다음가 같은 테스트를 해볼 수 있다.


public class StringTest {


    @Test

    public void test() {

        Set<Integer> hashCodeSet = new HashSet<Integer>(9999999);

        for (long l = 0; l <= 9999999; l++) {

            String phone = "010" + String.format("%08d", l);

            hashCodeSet.add(phone.hashCode());

//            System.out.println(phone);

//            System.out.println(hashCodeSet.size() + "/" + (l + 1));

        }

        System.out.println(hashCodeSet.size());

    }


}


하나의 충돌도 발생하지 않았다.


해쉬 함수 (Function)가 놀랍도록 잘 동작하고 있음을 확인할 수 있다.


당연히 이런 식으로 역으로 찾아낼 수 있겠다.


이것은 자바 (Java)의 String.hashCode()의 문제가 아니다.


어떤 해쉬 알고리즘을 사용하든지 알고리즘이 노출되면 역으로 찾아낼 수 있다.


암호 키 (Key)를 사용하고 이를 노출시키지 않으면 되겠지만,


자바스크립트 (JavaScript)처럼 완전히 노출되는 경우에는 어떻게 해야 할까?

Posted by izeye

JMX로 CPU 사용량을 구하기 위해


Java 7이라면, java.lang.OperatingSystem.ProcessCpuLoad를 사용하면 된다.


Java 6 이하라면, java.lang.OperatingSystem.ProccessCpuTime을 사용하면 된다.


ProcessCpuTime으로 CPU 사용량을 구하는 방법은


두번째 레퍼런스 (Reference)의 JConsole 소스 (Source)를 참고하면 되겠다.


References:

http://stackoverflow.com/questions/18489273/how-to-get-percentage-of-cpu-usage-of-os-from-java

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/sun/tools/jconsole/SummaryTab.java?av=f

Posted by izeye

@Mock은 Mock 객체를 생성한다.


@InjectMocks는 객체를 생성해서 생성한 Mock 객체들을 주입한다.


다음은 이를 활용한 예제이다.


import org.junit.Test;

import org.junit.runner.RunWith;

import org.mockito.InjectMocks;

import org.mockito.Mock;

import org.mockito.MockitoAnnotations;

import org.mockito.runners.MockitoJUnitRunner;


@RunWith(MockitoJUnitRunner.class)

public class MockitoTest {


    @Mock

    ClassA classA;


    @InjectMocks

    ClassB classB;


    @Test

    public void test() {

//        MockitoAnnotations.initMocks(this);

        System.out.println(classA);

        System.out.println(classB);

    }


}


class ClassA {

}


class ClassB {

    private ClassA classA;


    @Override

    public String toString() {

        return "ClassB{" +

                "classA=" + classA +

                '}';

    }

}


Mockito를 애노테이션 (Annotation) 기반으로 사용하기 위해


@RunWith(MockitoJUnitRunner.class)


혹은


MockitoAnnotations.initMocks(this);


를 사용한다.


Reference:

http://stackoverflow.com/questions/16467685/difference-between-mock-and-injectmocks

Posted by izeye

윈도우에 RabbitMQ를 설치하기 위해 다음과 같이 한다.


다음 주소에서 Erlang/OTP를 받아서 설치한다.


http://www.erlang.org/download.html


다음 주소에서 RabbitMQ를 받아서 설치한다.


https://www.rabbitmq.com/install-windows.html

Posted by izeye

다음은 구글 Guava 캐시 예제이다.


import com.google.common.cache.Cache;

import com.google.common.cache.CacheBuilder;

import org.junit.Test;


public class CacheTest {


    @Test

    public void test() {

        Cache<String, String> cache = CacheBuilder.newBuilder().build();

        cache.put("key", "value");

        String value = cache.getIfPresent("key");

        System.out.println(value);

    }


}


Reference:

http://en.wikipedia.org/wiki/Google_Guava

Posted by izeye

구글 Guava CacheBuilder 사용 시 다음과 같이 한다.


CacheBuilder.newBuilder().concurrencyLevel(4)...


concurrencyLevel()은 무엇을 설정하는 것일까?


캐시 (Cache)를 세그먼트 (Segment)로 구분하여


동시 수정 (Concurrent Modification) 시 Lock Contention 비용을 줄여주는데


이 세그먼트의 개수를 설정하는 것이다.


디폴트 값은 4이고,


보통 이 캐시를 사용할 쓰레드 (Thread) 개수로 설정한다.


Reference:

http://codingjunkie.net/google-guava-cache/

Posted by izeye

자바 레퍼런스 타입은


Strong Reference, Weak Reference, Soft Reference, Phantom Reference


4가지가 있다.


Strong Reference는 일반적으로 변수에 할당되는 경우이다.


Weak Reference의 오브젝트는 다른 레퍼런스가 없다면 다음 GC에 GC된다.


Soft Reference의 오브젝트는 다른 레퍼런스가 없더라도


메모리 상황에 따라 Weak Reference보다는 길게 유지될 수 있다.


Phantom Reference는 가능한 빨리 GC하고 싶은 경우에 사용된다.


References:

http://www.rallydev.com/community/engineering/java-references-strong-soft-weak-phantom

http://stackoverflow.com/questions/299659/what-is-the-difference-between-a-soft-reference-and-a-weak-reference-in-java

Posted by izeye

Logback vs. SLF4J

자바/공부 2014.06.16 18:40

Logback을 직접 쓸지, SLF4J와 함께 쓸지 고민이라면,


SLF4J와 함께 쓰는게 좋겠다.


Logback이 SLF4J 인터페이스를 구현하고 있기 때문에


추가적인 부하는 없이


필요에 따라 향후에 Log4J와 같은 다른 로그 프레임워크 (Log Framework)로 변경하는데 용이하겠다.


Reference:

http://stackoverflow.com/questions/5827804/logback-native-vs-logback-via-slf4j

Posted by izeye