JAVA CODE STYLE GUIDE

코드 스타일 가이드가 있으면 결과적으로 코드의 질이 좋아진다.
(당장은 아니겠지만)

기본적으로 많은 곳에서 사용되는 자바 스타일 가이드는 SUN 의 스타일 가이드이다.

스타일 가이드에서 제시하는 코드 규칙의 중요성을 간략하게 정리하면 다음과 같다.
  • 소프트웨어를 개발하는 일련의 모든 과정에 들어가는 비용 중 80%가 유지보수에 사용된다.
  • 유지보수를 최초 소프트웨어를 개발한 사람이 담당하는 경우가 거의 없다.
  • 코드 규칙을 지키면 다른 개발자가 소스코드를 보았을 때 이른 시간에 이해할 수 있도록 도와준다.

만약 코드 스타일 가이드를 한 번도 읽어 보지 못했다면 SUN 의 스타일 가이드 를 읽어 보길 추천한다. 원본은 영어로 되어 있지만,한국어로 번역된 글도 많고 내용 대부분이 예제 코드로 이루어져 있으므로 문제없이 읽을 수 있을 것이다.

지금부터 소개할 것은 SUN 의 스타일 가이드가 아닌 GOOGLE의 스타일 가이드 이다.

Google java style guide 는 60% 정도는 SUN의 스타일 가이드와 같다.
몇 가지 다른 부분들은 tab 대신 space를 사용하는 것과 column limit 이 80 에서 100으로 더 크게 지정되었다는 부분과 최신 lambda 표기법 등이 있다.

선택의 이유는 SUN 의 스타일 가이드는 근래에 업데이트가 되지 않고 있지만, google의 스타일 가이드는 조금씩 업데이트가 되고 있다.

javaguide.html 파일의 마지막 변경 시점은 29일 전이다 - 2016.08.11 기준)

GOOGLE STYLE GUIDE

기본적으로 개발 도구를 ECLIPSE 을 사용하는 기준으로 기본 코드 컨벤션 설정은 SUN 사의 스타일로 처리 되어 있다.

우선 기본 CODE FORMAT를 Google 의 style로 변경해야 한다.
순서는 다음과 같다.

  1. 구글에서 제공하는 이클립스용 스타일 포맷 을 내려받는다.
  2. ECLIPSE를 실행하고 다음 메뉴로 이동한다.
    • Window > Preference > java > Code Style > Formatter
  3. Import를 선택하고 내려받은 XML 파일을 선택하고 Active Profile을 GoogleStyle로 설정 한다.
  4. Ctrl + Shift + F 를 이용해 소스 코드를 정렬한다.

참고 자료

Eclipse Checkstyle Plugin

코드를 작성하다 보면 스타일 가이드를 지키고 있는지 알 수 없다.
Checkstyle 이라는 프로그램을 이용하여, ant 또는 java 를 이용한 실행으로 잘못된 스타일 가이드를 확인할 수 있지만, 실시간이 아니므로 재작업에 어려움을 느낄 수 있다.

다행이 실시간으로 스타일 가이드를 확인할 수 있는 이클립스 플러그인이 있다.

설치는 다음과 같다.

  • Help > Eclipse Market place에서 CheckStyle로 검색을 하면 CheckStyle Plugin X.X.. 이라는 이름의 플러그인을 설치 하면 된다.
  • 설치가 완료되면 이클립스를 재기동한다.

설치가 끝나면 사용을 하기 위해 간단한 설정을 해야 한다

  1. Window > Preference > Checkstyle 에서 Google Check를 기본값으로 설정하고 저장한다.
  2. 사용할 프로젝트에서 마우스 오른쪽 키 > Properties 또는 Alt + Enter 를 이용해서 설정으로 이동한다.
  3. 왼쪽 트리 메뉴에서 Checkstyle를 선택하고 오른쪽의 Checkstyle active for this project의 체크박스를 체크 한다.
  4. OK 버튼을 누른다.

이후 화면에서 스타일을 지키지 않은 내용을 바로 확인할 수 있다.


MD FILE : 

코드스타일가이드.md



Posted by lahuman

댓글을 달아 주세요

Lambda Basic

function has 4 things

  1. name
  2. parameter list
  3. body
  4. return type
Thread th = new Thread(new Runnable(){
    public void run(){
        Sysout.out.println("In side Thread");
    }
});
th.start();

lambda expression

1. name

  1. parameter list
  2. body

4. return type

Thread th = new Thread(() ->Sysout.out.println("In side Thread"));
th.start();

iterators

List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
//external iterators
for(int i = 0; i < numbers.size(); i++){
    System.out.println(numbers.get(i));
}

//external iterators also
for( int e : numbers){
    System.out.println(e);
}

//interal iterators
numbers.forEach(new Consumer<Integer(){
    public void accept(Integer value){
        System.out.println(value);
    }
});

numbers.forEach((Integer value) ->System.out.println(value));

numbers.forEach((value) ->System.out.println(value));

//only for on parameter lambdas
numbers.forEach(value ->System.out.println(value));

numbers.forEach(System.out::println);

//ANTI PATTERN :: DO NOT USE LIKE THIS!
number.forEach(e -> {
...;
...;
...;
return ... need return...;
});

Parameter

List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
numbers.stream()
    //.map(e -> String.valueOf(e))
    .map(String::valueOf)
    .forEach(System.out::println);

numbers.stream()
    .map(e -> String.valueOf(e))
    //.map(e -> e.toString())
    .map(String::toString)
    .forEach(System.out::println);

Two parameter

List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
System.out.println(
    numbers.stream()
        //.reduce(0, (total, e) -> Integer.sum(total, e)));
        .reduce(0, Integer::sum));
);
System.out.println(
    numbers.stream()
        .map(String::valueOf)
        //.reduce("", (carry, str) -> carry.concat(str)));
        .reduce("", String::concat));
);

Stream

List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
//given thevalues, double the even numbers and total.
int result = 0;
for(int e : numbers){
    if(e % 2 == 0){
        result += e*2;
    }
}
System.out.println(result);

System.out.println(
    numbers.stream()
        .filter(e -> e % 2 == 0)
        .mapToInt(e ->e * 2)
        //.reduce(0, Integer::sum));
        .sum();
);

출처


Get a Test of Lambda.md



Posted by lahuman

댓글을 달아 주세요

원문 : Why 1000 == 1000 Returns False, but 100 == 100 Returns True in Java?

이것은 아마도 많이 이야기 되는 흥미로운 내용일 것입니다.
다음의 코드를 실행하면

Integer a=1000, b=1000;
System.out.println(a == b); //1
Integer c=100, d=100;
System.out.println(c == d); //2

다음의 결과를 확인할 수 있습니다.

false
true

이해를 위한 기본: 두 개의 참조 값이 같은 객체를 가리키는 경우, 그것이 == 로 같은 것으로 알고 있습니다. 만약 두 개의 객체가 가르치는 참조가 다를 경우, 같은 내용을 가지고 있어도 == 로 같지 않다는 결과를 받습니다.

그래서 마지막 결괏값 역시 false 여야 합니다.

이 흥미로운 것은 사실이다. 만약 당신이 Integer.java 클래스를 본다면 IntegerCache.java 내부 private 클래스를 확인할 수 있을 것이며, 이 클래스에서 -128부터 127까지의 값을 캐시에 저장한다.

그래서 다음과 같이 우리가 뭔가를 선언 할 때 작은 숫자 값은 캐시에 저장된다.

Integer c = 100;

다음 실행하면 내부에서 어떤 일이 일어나는가?

Integer i = Integer.valueOf(100);

valueOf() 메소드를 확인하면

public static Integer valueOf(int i){
    if(i >=-128 && i <= 127){
        return IntegerCache.cache[i+(128)];
    }
    return new Integer(i);
}

만약 값이 범위가 -128에서 127이라면 캐시에 저장된 객체가 전달 될 것이다.
그래서

System.out.println(c == d);

에 결과로 우리는 true를 확인하였다.

당신은 “왜 캐시가 필수일까?” 라는 의문을 가질 것이다.
아마도, 논리적인 근거는 작은 값의 숫자 범위 값은 큰 숫자 하나 보다 더 많이 사용된다. 그래서 같은 객체를 이용하여 메모리 사용량을 줄이는 것이다.

그러나 reflections API를 이용하여 이 기능을 악용할 수 있습니다.

다음 코드를 실행하면, 재미있는 결과를 확인할 수 있습니다.

public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
  Class cache = Integer.class.getDeclaredClasses()[0]; //1
  Field myCache = cache.getDeclaredField("cache"); //2
  myCache.setAccessible(true);//3
  Integer[] newCache = (Integer[]) myCache.get(cache); //4
  newCache[132] = newCache[133]; //5
  int a = 2;
  int b = a + a;
  System.out.printf("%d + %d = %d", a, a, b); //
}

결괏값

2 + 2 = 5



추가 내용 :

warpper class(Integer, Double, Long 등)의 인스턴스의 경우 값에 대한 비교는 equals() 메소드를 이용해야 합니다.


MARK DOWN FILE :

1000_100_Integer.md




Posted by lahuman

댓글을 달아 주세요

Java API는 몇개의 Collection과 Map의 구현체를 제공한다. 그래서 이것 중 하나를 선택하는 것은 혼란 스러울수 있다.

여기 flowchart 에서는 어떤 구현체를 선택할 것인지에 대하여 도움을 준다.


다음 차트에선 좀처럼 사용되지 않는 WeakHashMap , LinkedList, 등 은 포함되지 않았다. 왜냐면 99%의 경우 선택하지 않거나 매우 정확하게(사용할 곳이) 설계 되어 있기 때문이다.


Java Map/Collection Cheat Sheet


만약 순서있는 Collection의 구현에 관심이 있다면, Alexander Zagniotov 게 제공하는 flowchart 상세를 보면 매우 많은 Collections 관련 그의 글이 있다. 라고하는데 링크에 접근 안됨..


주소 : https://drive.google.com/file/d/0B6LGXhxOucOxdHcwLXVIUlpRY1k/view?usp=sharing


원본주소 : http://www.sergiy.ca/guide-to-selecting-appropriate-map-collection-in-java/

Posted by lahuman

댓글을 달아 주세요

LINUX 터미널에서 클래스 파일 실행하기


LINUX에는 nmap이나, telnet 등 네트워크 관련 모듈은 설치가 되지 않아서 간단하게 클래스 파일을 이용하여 oracle 접속 가능 여부를 확인해야 하는 일이 있었다.


쉽게 생각하고 접근을 하였는데, ojdbc6.jar 파일을 classpath에 추가 해서 진행을 하면 계속 main을 못찾는다는 오류를 만났다.


옛날에 분명 많이 해본 일이었는데(약 8년전) 구글 검색을 하고 이래 저래 2시간 정도를 소요 하고 나서야, 원인을 찾아 진행 하였다.

 

매일 IDE 툴에 익숙해지니 터미널이나 커맨드라인에서 작업은 어렵게 느껴 진다.


# LINUX의 경우
$> javac -cp .:<path>/ojdbc6.jar OracleTest.java
$> java -cp .:<path>/ojdbc6.jar OracleTest

#WINDOWS의 경우
$>javac -cp .;<path>/ojdbc6.jar OracleTest.java
$>java -cp .;<path>/ojdbc6.jar OracleTest


중요한건 LINUX에서는 :(colons-콜론)을 이용하고 WINDOWS에서는 ;(semi-colons-세미콜론)을 이용한다.


참고 URL : 

http://stackoverflow.com/questions/14941936/unable-to-connect-to-oracle-database-using-jdbc-thin-drivers

Posted by lahuman

댓글을 달아 주세요


오랜만에 올립니다.
설날도 있었고 한동안 docker라는 놈을 보느라 정신이 없었네요.

이왕 시작을 했으면 끝을 봐야 하는데 늦더라도 열심히 업뎃 하겠습니다.

잘못된 내용은 메일로 주시면 보고, 수정하겠습니 감사합니다.


Posted by lahuman

댓글을 달아 주세요

객체 생성에 대한 디자인 패턴 중 Builder, Prototype 입니다.



Posted by lahuman

댓글을 달아 주세요

출처 : http://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-with-examples




스터디 2차 자료 입니다.


Posted by lahuman

댓글을 달아 주세요


현재 함께 하는 분과 진행 중인 스터디 자료 입니다.
올해 2015년에는 디자인 패턴에 대해 공부 할 예정입니다.
감사합니다.


Posted by lahuman

댓글을 달아 주세요

질문 : 나는 대부분 간단하게 List<String> names = new ArrayList<String>() 이렇게 사용한다.

나는 이식성이 좋은 인터페이스(Interface) 타입을 사용한다, 그래서 나의 코드가 변경이 필요할 때 변경 할수 있다.


언제 LinkedList를 ArraryList 대신 쓰나요? 또는 반대로 사용해야 하나요?


요약 답변 : 

ArrayList ArrayDequeLinkedList 보다 더 많이 사용 되는 것이 선호 된다. 확실하진 않다. ArrrayList 에 대해 이야기 해보자


LinkedList와 ArrayList는 List Interface를 다르게 구현한 것이다.

LinkedList는 이중 연결 목록 방식으로 구현 되어 있고, ArrayList는 동적으로 크기가 변환되는 배열 방식으로 구현 되었다.


LinkedList와 ArrayList의 각 메소드들은 각각 다른 알고리즘으로 실행되도록 되어 있다.


LinkedList<E> 알고리즘

  • get(int index) is O(n)
  • add(E element) is O(1)
  • add(int index, E element) is O(n)
  • remove(int index) is O(n)
  • Iterator.remove() is O(1) <-- LinkedList<E> 일 경우만
  • ListIterator.add(E element) is O(1) <-- LinkedList<E> 일 경우만

ArrayList<E> 알고리즘

  • get(int index) is O(1) <-- LinkedList<E> 일 경우만
  • add(E element) is O(1) 분활했을 경우, 그러나 배열이 복제 되거나, 크기 변화시 최악의 경우 O(n)이 된다.
  • add(int index, E element) is O(n - index) 분활이 완료 되었을 경우 최악의 경우는 위와 같다
  • remove(int index) is O(n - index)  (즉 마지막을 제거할 경우는 O(1))
  • Iterator.remove() is O(n - index)
  • ListIterator.add(E element) is O(n - index)

Big-O 의미

계산 복잡도 이론에서 사용되는 점근 표기법이며, 입력 데이터의 크기와 알고리즘의 소요시간 또는 메모리의 상관관계를 나타낸다.

  • O(1) 상수 형태
  • O(n) 선형
    (개념의 이해를 돕기위해, 친구네 집 아파트(101동)에 도달했을 때, 친구네 주소를 알고 있으면 O(1)로  친구네 들어갈 수 있다. 그런데 101동밖에 모른다면 최악의 경우 그 101동의 모든 동호수를 뒤져가며 찾아야 한다 이런 경우를 O(n)으로 생각할 수 있다.)

[알고리즘 별 수행 시간 - WIKI 출처]


LinkedList<E> 는 변함없는 시간내에 추가 또는 삭제를 iterators를 이용 할수 있다.. 그러나 오직 순차적인 요소에 대한 접근만 허락한다.

다시 말해서 목록에 대한 전진 과 후진을 할수 있다 그러나 특정 위치에 대한 검색은 목록의 크기에 비래하는 시간이 필요 하다.


ArrayList<E> 는 반면에 빠른 무작위 읽기 접근이 가능하다. 그래서 어느 요소든 변함없는 시간에 가져올수 있다. 그러나 추가 삭제를 어디에 하던, 꺼내거나 채우는 틈이 있을 경우 그 요소 뒤에 있는 모든 요소는 이동을 해야 한다.  또한 배열의 용량을 넘는 요소를 추가할 경우 새로운 배열을 할당하고, 기존의 배열을 복사하여 새로운 것을 만든다. 그래서 ArrayList 의 추가는 O(n) 나쁜 형태를 가진다  그러나, 일반적으로 변하지 않는다.


그래서 당신의 의도에 따라 구현된 것을 선택 하면된다.사실상 반복하는 두 리스트는 비슷하게 적은 리소스를 이용한다.(엄밀히 따지면 반복을 하는 것은 ArrayList가 더 빠르다, 그러나 정확한 성능 분석을 하지 않는 이상  이것에 대한 고민을 할 필요가 없다.)


LinkedList의 가장 큰 이득은 요소의 등록과 삭제를 다시 반복할때 발생한다. 이런 명령은 O(1) 알고리즘으로 지역적인 변경만 있다 

배열 목록은 나머지 배열의 이동이 필요하다(즉-복사경우). 

다른 방향으로는 탬색의 경우 LinkedList는 O(n)을 뜻하고, 다른 ArrayList의 경우 원하는 위치를 수학적으로 산출 하거나 접근을 O(1)로 할수 있다.


또한 큰 사이즈의 목록의 메모리 사용법 또한 다르다는 것을 명심해야 한다. 각 요소별로 LinkedList는 다음과 이전 연결 점들을 가지고 있다.

ArrayList는 이런 연결점이 없다. 아무리 ArrayList 는 요소가 실제로 추가 되었는지 상관 없이 더 많은 메모리의 용량을 할당을 차지한다.


기본 초기 용량은 ArrayList가 확실히 작다(1.4~ 1.7에서는 10개) 그러나, 근본적으로 배열로 구현되어, 많은 요소를 담을 경우에 사이즈 조절이 필요하다. 많은 비용을 들여서 사이즈 조절을 하는 것을 피하려면 ArraryList의 기본 초기 용량을 높게 잡아야 한다.


Vector 역시 List 인터페이스를 구현되었고 ArrayList와 거의 동일한 것은 언급할 가치가 있다. 다른 것은 Vector은 동기화 되어 Thread-safe 하다. 그렇기 때문에 ArrayList보다 약간 느리다. 그래서 대부분 자바 프로그램에서 Vector 를 사용하지 않고, ArrayList를 선호하는 것은 명백하게 동기화를 하지 않는 것이라고 나는 어느 정도 이해한다.



원본 문서 : http://stackoverflow.com/questions/322715/when-to-use-linkedlist-over-arraylist

Big-O 위키: https://mirror.enha.kr/wiki/Big-O

Posted by lahuman

댓글을 달아 주세요