'프로그래밍'에 해당되는 글 100건

  1. 2019/03/13 용비 Visual Studio Code를 이용한 Maven Project 시작하기
  2. 2019/03/13 용비 Windows에서 OpenJDK 사용
  3. 2019/03/11 용비 Java Singleton Class
  4. 2016/03/21 용비 (Chapter 3) 17. Actions
  5. 2015/03/27 용비 CentOS 6.4에서 Nginx 1.6.2 설치하기
일반적으로 Java 개발할 때, eclipse나 IntelliJ를 사용했는데, 이번에 Visual Studio Code를 사용해 보기로 했습니다.

항상 새로운 도구를 사용하게 되면, 그 도구의 사용법을 습득하는데 많은 노력을 기울이게 됩니다.
이번에 윈도우 10 기반, OpenJDK를 사용하여 Maven Project를 생성하는 과정을 정리해 보았습니다.

Visual Studio Code를 통해 Maven Project 실행하기

01. JDK 설치
Oracle에서 제공하는 JDK SE가 유료화됨에 따라 OpenJDK를 이용
Windows 버전은 https://github.com/ojdkbuild/ojdkbuild 에서 설치 파일 다운로드
설치 후, JAVA_HOME, Path 설정 및 확인
02. Maven 설치
https://maven.apache.org/download.cgi 에서 최신 버전 다운로드 (2019.03.13 기준 apache-maven-3.6.0)
압축 해제 후 Maven Home, Path 설정
03. Visual Studio Code 설정
1) Visual Studio Code에 Java 개발 환경 설정을 위한 Extension 선택
사용자 삽입 이미지
2) 'java extension pack' 검색 후 설치
사용자 삽입 이미지

3) vscode의 Settings 선택
사용자 삽입 이미지

4) Json 설정 파일 Open 선택
사용자 삽입 이미지

5) Java Home과 Maven Path 설정
사용자 삽입 이미지

04. Maven Project 생성
1) 프로젝트를 생성하고자 하는 위치에 workspaces 폴더 생성
사용자 삽입 이미지

2) VS Code의 File -> Open Folder에서 workspaces 폴더 선택
사용자 삽입 이미지

3) WORKSPACES 창에서 마우스 오른쪽 클릭 후, Maven Project 생성
사용자 삽입 이미지

4) 검색 창에서 maven-archetype-archetype 선택
사용자 삽입 이미지

5) Default Project Destination Folder Setting
사용자 삽입 이미지
사용자 삽입 이미지

6) 하단의 command 창에서 groupId, artifactId, version, package 등 프로젝트 정보 입력
사용자 삽입 이미지

7) 입력한 정보로 Maven Project 생성 완료
사용자 삽입 이미지
받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/838

Windows에서 OpenJDK 사용

Articles 2019/03/13 13:39 용비
오라클에서 Sun을 인수한 이후, JDK 유료화 정책으로 인해 Java 프로그래밍을 하는 세상에 지각 변동이 일어났습니다.

리눅스에서는 이전부터 OpenJDK를 사용하였는데, Windows에서도 사용할 수 있도록 오픈되었네요.

https://github.com/ojdkbuild/ojdkbuild

앞으로는 OpenJDK를 사용해야 할 듯...
받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/837

Java Singleton Class

Articles 2019/03/11 21:45 용비
일반적으로, 메모리에 하나의 Instance만 로딩되도록 해야 하는 경우 Singleton Pattern을 적용한 Singleton Class를 사용한다.

하지만, 대용량의 트래픽이 발생하는 Concurrent Request 환경에서는 하나의 Request가 곧 하나의 Thread를 실행하게 된다. 그런 경우, Singleton Class는 Thread-Safe하지 않게 될 수 있다.

원치 않게 각 요청에 따른 올바른 Response를 주지 못하고, 데이터가 꼬여 다른 결과를 리턴하게 되는 치명적인 결과가 초래될 수 있다.

모든 경우와 같이, Singleton Class를 제공하는 경우에도 다음과 같은 고려가 필요하다.

- 동시에 여러 개의 요청이 오더라도 순서대로 처리할 수 있어야 한다.
- 최대한의 성능을 고려해야 한다.
- 여러 요청으로 인해 병목이 발생하더라도 다른 작업을 처리하고 있는 Thread에 영향을 최소화해야 하고, 프로그램이 종료되지 않아야 한다.

Singleton Class 구현 방법은 다음과 같은 방법으로 생각해 볼 수 있다.

<1> Eager Initialization
package com.dev.sample

public class EagerInitSingleton {

private static final EagerInitSingleton = new EagerInitSingleton();
private EagerInitSingleton () {}

public static EagerInitSingleton getInstance() {
return instance;
}
}
Class Loading 시점에 Singleton Class Instance가 생성된다. 가장 쉽게 Signleton Class를 생성하는 방법이지만, Client에서 요청이 없을 때에도 항상 생성되므로 불필요한 리소스를 사용하게 된다. 또한 대부분 파일 시스템이나 데이터베이스에 접속하는 경우 Singleton Class를 사용하는데 Exception을 처리할 수 없다.

<2> Static Block Initialization
package com.dev.sample

public class StaticBlockSingleton {

private static StaticBlockSingleton instance;

private StaticBlockSingleton () {}

static {
try {
instance = new StaticBlockSingleton();
}
catch (Exception e) {
throw new RuntimeException(e.printStackTrace());
}
}

public static StaticBlockSingleton getInstance() {
return instance;
}
}
Static Block은 Eager Initialization Singleton과 비슷하게 Class Loading 시점에 Static Block 안에서 Singleton 객체가 생성되지만, Exception을 처리할 수 있다. 하지만, 동일한 단점을 가지고 있다.

<3> Lazy Initialization
package com.dev.sample

public class LazyInitSingleton {

private static LazyInitSingleton instance;

private LazyInitSingleton() {}

public static LazyInitSingleton getInstance() {

if (instance == null) {
instance = new LazyInitSingleton();
}

return instance;
}
}
Single Thread 환경에서 잘 동작한다. 하지만, 동시에 여러 개의 Thread가 접근할 경우 여러 개의 Instance가 생성될 수 있다. 그런 경우 Singleton Pattern이 깨지고, 서로 다른 Singleton Instance를 사용하게 될 수 있다.

<4> Thread-Safe Singleton
package com.dev.sample

public class ThreadSafeSingleton {

private static ThreadSafeSingleton instance;

private ThreadSafeSingleton() {}

public static synchronized ThreadSafeSinfleton getInstance() {

if (instance == null) {
instance = new ThreadSafeSingleton();
}

return instance;
}
}
synchronized 키워드를 사용하여 한번에 하나의 Thread만 호출할 수 있도록 만들 수 있다. 하지만 모든 Thread의 요청에 대해 synchronized를 실행하므로 성능상 오버헤드가 발생한다.

<5> Double Checked Thread-Safe Singleton
package com.dev.sample

public class DoubleCheckThreadSafeSingleton {

private static DoubleCheckThreadSafeSingleton instance;

private DoubleCheckThreadSafeSingleton() {}

public static DoubleCheckThreadSafeSingleton getInstance() {

if(instance == null) {
synchronized (DoubleCheckThreadSafeSingleton.class) {
if (instance == null) {
instance = new DoubleCheckThreadSafeSingleton();
}
}
}

return instance;
}
}
위와 같은 Double Checked Locking 원리를 이용하면, 조건을 만족시키는 경우 (instance == null) 한 번만 synchronized block이 실행되므로 하나의 Singleton Class Instance만 생성된다. synchronized로 인한 성능 이슈를 해소할 수 있다.

<6> On-demand Holder Idiom에 따른 Inner Class(holder or helper class)를 이용한 Singleton
package com.dev.sample

public class HelperSingleton {

private HelperSingleton() {}

private static class SingletonHelper {
private static final HelperSingleton instance = new HelperSingleton();
}

public static HelperSingleton getInstance() {
return SingletonHelper.instance;
}
}
getInstance() method를 호출 할 때, SingletonHelper 클래스가 생성되고 Singleton intance는 static final 키워드로 인해 한번만 생성된다. 대부분 <6>번의 경우를 많이 사용한다.







받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/836

(Chapter 3) 17. Actions

Spark 2016/03/21 17:15 용비

그동안 서로간의 변형을 통해서 어떻게 RDD 생성하는지를 알아보았다. 하지만, 어떤 경우에는 Dataset 가지고 직접적으로 어떤 일을 하고 싶을 수도 있다. Action RDD operation 번째 형태이다. Action driver program 마지막 값을 되돌려 주거나 외부 storage system 데이터를 쓰는 작업을 수행한다. Action RDD 호출하는 곳에서 필요로 하는 변형에 대해서 평가하기 때문에 실제적인 ouput 만들어낼 필요가 있다.


앞의 섹션의 log example에서 계속해서 살펴보자면 badLinesRDD 대해 어떤 정보를 출력하고 싶을 수도 있다. 그렇게 하기 위해서는 2가지 action 사용할 있다. count() 숫자를 값을 리턴하고, take() RDD element collection 리턴한다. 샘플코드는 3-15, 3-17에서 있다.


Example 3-15. Python error count using actions

print "Input had " + badLinesRDD.count() + " concerning lines"

print "Here are 10 examples: "

for line in badLinesRDD.take(10):

     print line


Example 3-16. Scala rror count using actions

println("Input had " + badLinesRDD.count() + " concerning lines")

println("Here are 10 examples:")

badLinesRDD.take(10).foreach(println)


Example 3-17. Java error count using actions

System.out.println("Input had " + badLinesRDD.count() + " concerning lines")

System.out.println("Here are 10 examples:")

for (String line : badLinesRDD.take(10)) {

     System.out.println(line);

}


위의 예제에서, driver program에서 작은 숫자의 RDD element 추출하기 위해서 take() 사용했다. Driver 정보를 출력하기 위해서 반복하여 출력했다. RDD 전체 RDD 추출하기 위해서 collect() 함수를 가지고 있다. 만약 프로그램 필터에서 RDD 아주 작은 크기로 줄여서 내부적으로 다루고자 하는 경우에 유용하게 사용할 있다. 다만, 전체 dataset collect() 사용하여 하나의 machine 메모리 크기에 적합해야 한다는 것을 유념해야 한다. 따라서 collect() large dataset 대상으로는 사용하지 않아야 한다.


대부분의 경우, RDD driver 직접적으로 collect()함수를 사용하여 데이터를 추출할 없다. 왜냐하면 dataset 너무 크기 때문이다. 이러한 경우에는 HDFS Amazon S3 같은 분산 저장환경에 데이터를 쓰는 경우가 일반적이다. 또한 saveAsTextFile() action, saveAsSequenceFile()이나 다양한 내장된 형태로 다른 많은 action 사용하여 RDD 내용을 저장할 있다. 데이터를 추출하는 다른 option 대해서는 Chapter 5에서 다룰 것이다.


새로운 action 매번 호출할 때마다 전체 RDD " 처음부터"(from scratch) 계산되어야 한다는 것을 아는 것이 중요하다. 이러한 비효율성을 피하기 위해서 44페이지에서 "Persistence (Caching)"으로 다루는 중간 결과를 유지할 있다.

받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/743

필요에 의해서 모처럼 VMWare Player를 설치하고 CentOS 6.4 64bit OS를 VM에 설치했다.
최신 stable 버전인 nginx 1.6.2를 설치하려고 다운로드를 받았다.

예전 기억을 되살려서 설치를 해보니 다음과 같은 과정을 거치면 깔끔하게 설치가 끝난다.

root 계정 로그인
Terminal 실행
> yum -y install gcc-c++
> yum -y install pcre* openssl* zlib*
> ./configure
       --prefix=/home/userid/nginx
       --sbin-path=/home/userid/nginx/nginx
       --conf-path=/home/userid/nginx/nginx.conf
       --pid-path=/home/userid/nginx/nginx.pid

> make & make install

서버 실행
> nginx -s [start | stop | restart | reload]
받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/662