출처: http://stackoverflow.com/questions/8302894/what-is-the-difference-between-runnable-jar-library-handling-options





  • Extract required libraries into JAR
  • Package required libraries into JAR
  • Copy required libraries into sub folder next to JAR

  1. Extract required libraries into JAR - Extracts the actual .class files from the libraries your app uses and puts those .class files inside the runnable JAR. So, the runnable JAR will not only contain the .class files of your application, but also the .class files of all the libraries your application uses.

  2. Package required libraries into JAR - Puts the actual JAR files of the libraries into your runnable JAR. Normally, a JAR file within a JAR file cannot be loaded by the JVM. But Eclipse adds special classes to the runnable JAR to make this possible.

  3. Copy required libraries into sub folder next to JAR - Keeps the library JARs completely separate from the runnable JAR, so the runnable JAR will only contain the .class files of your application.

Option #2 is convenient because it packages everything neatly into a single JAR, and keeps the library JARs separated from your application's .class files.

However, a downside to packaging everything inside of a single JAR (options #1 and #2) is that, if you update your application, then the user will have to download more data to update the application. If the JARs are kept separate, then the user would only have to download the JAR that contains your application code, instead of a single, massive JAR that contains your application code and all the library code.

  

ls -l 명령어로 파일 크기를 확인할 때, 숫자가 너무 커서 정확한 용량을 파악하기 힘들 때가 있습니다.

이럴 때 사용하면 좋은 명령어 입니다.



1M를 원하는 단위로 바꿔서 사용할 수도 있습니다.


  

리팩토링을 망설이지 말자

Posted by epicdev Archive : 2012. 3. 29. 15:16

리팩토링을 망설이지 말자. 리팩토링은 시작이 반이다.

때때론 "리팩토링 하자"라고 마음 먹기가 리팩토링 하는 것보다 힘들다.

일단 리팩토링을 시작하면 생각보다 금방 끝나는 경우가 많다.

(코딩하면서 리팩토링을 꾸준히 했을경우. 켄트 백의 말을 빌리자면 코드를 조금씩 조금씩 성장시켰을 경우)


작은 리팩토링의 반복이 가장 바람직한 리팩토링인 것 같다.

마구 코딩만 하다가 "나중에 시간나면 리팩토링 해야지"하고 생각하다가

나중에 한꺼번에 리팩토링 하려면 그 때는 리팩토링이 거의 "불가능" 해지는 경우가 많다.

  

PriorityQueue를 적재적소에 사용하자

Posted by epicdev Archive : 2012. 3. 27. 21:07

데이터가 정렬된 상태로 컨테이너에 들어있어야 할 경우에는 PriorityQueue를 자주 사용한다.

PriorityQueue는 Comparable 인터페이스를 구현하는 클래스(boolean compareTo를 구현하여 priority를 매김)를 데이터로 갖거나

생성자에서 따로 Comparator를 받아서 어떻게 priority를 매길지 정할 수 있다.

나같은 경우에는 평소에 데이터들의 순차적 access가 필요 할 때 PrioirtyQueue를 자주 사용한다.

하지만 얼마전에 PriorityQueue를 남용한 잘못을 저질렀다.


PriorityQueue가 사용되기에 적절한 곳은 (내 생각)

1. 컨테이너 안의 데이터가 priority에 따라 사용 순서가 결정

2. 컨테이너의 내용이 자주 바뀜 (poll과 add가 교차적으로 빈번하게 발생함)

3. 데이터를 재사용 할 일이 별로 없음


그런데 나같은 경우는 1번의 경우만 생각하고 2, 3번의 경우는 생각하지 않아서 문제가 발생했다.

어떤 raw 데이터를 통째로 읽어와서 PriorityQueue에 저장을 해놓고, PriorityQueue에서 데이터를 순차적으로 뽑아서, 데이터들 마다 "어떤 처리"를 한 다음 다시 파일로 쓰는 작업이었다.

여기서 나는 2번째 내용을 위반하였다.

나는 그냥 raw 데이터를 읽어오는 족족 PriorityQueue에다가 넣었는데, 이는 "오로지" 나중에 순차적으로 데이터를 뽑아 쓰려고 이렇게 하였다 (1번 이유).

그런데 이 경우 2번의 경우처럼 poll과 add가 교차적으로 빈번하게 발생하지 않는다.

즉, add가 한꺼번에 연속적으로 전부 발생하고나서, poll을 계속 하면서 데이터들을 처리한다.

따라서 이 경우에는 그냥 ArrayList에다가 데이터를 전부 add한 다음 그냥 Collections.sort로 ArrayList를 정렬해서 사용하면 그만이다.

(add와 poll의 교차수행이 빈번할 경우에 ArrayList보다 PriorityQueue가 좋은 점: ArrayList를 사용할 경우 데이터를 add하게되면 ArrayList의 "정렬됨"이라는 상태가 깨지기 때문에, valid한 ordered ArrayList를 유지하려면, add를 할때마다 매번 정렬을 해주어야 한다 (혹은, poll을 요청하기 전까지 add만 하다가 poll 요청이 들어오면 정렬을 해도 된다. 하지만 교차수행이 빈번한 경우에는 매번 정렬을 해야 할 수도 있다). 물론 ordered ArrayList는 정렬된 상태이므로, ArrayList를 traverse한 다음 적절한 위치에다가 add를 해주는 것도 가능하나, 이 또한 ArrayList의 특성상 비효율적일 수가 있다.)


사실 위의 경우에서는 PriorityQueue를 사용하거나 ArrayList와 Collections.sort를 사용하거나 별다른 차이가 없다.

왜냐하면 "재사용"이 없기 때문이다. 하지만 나는 재사용이 필요하였다 (3번 조건 위반).

만약 PriorityQueue의 데이터를 하나씩 뽑아와서 while (!pq.isEmpty()) 처리한다음 파일로 써버리면

PriorityQueue에 남아있는 내용이 없기 때문에, 만약 raw 데이터의 사용이 다시 필요하다면, 파일에서 또 읽어들여야 했다.

(PriorityQueue는 정렬된 list 상태가 아니라 heap 상태라서, iterator로 PriorityQueue를 traverse하게 되면 priority순으로 데이터가 traverse되지 않는다.

priority순으로 PriorityQueue의 데이터를 access하는 방법은 오로지 poll밖에 없다!)

문제는 이 파일이 용량이 꽤나 커서 읽어들이는데 10초정도의 시간이 소요된다는 것이었다.


따라서 내가 겪은 케이스에는 PriorityQueue를 사용하는것 보다 그냥 ArrayList와 Collections.sort를 사용하는 것이 낫다.


결론

1. 도구는 적재적소에 사용해야 한다.

2. 떄론 없어보이는 도구일지라도, 있어보이는 도구보다 나을때도 있다 (특히나 있어보이는 도구가 오로지 특정 상황에서만 최고의 성능을 발휘할 때).

  

Java에서 File IO할 때의 try-catch-finally 스타일

Posted by epicdev Archive : 2012. 3. 27. 19:54

Java에서 File IO를 할 때에 필연적으로 사용해야하는 것이 try와 catch와 finally이다.

그런데 이런 try, catch, finally 들로 코드를 도배하다보면 정말 UGLY한 코드가 나오기가 쉽다.

아래의 코드가 일반적으로 가장 널리 사용되는 스타일이다.


이 코드는 소위 말하면 정말 UGLY하다고 할 수가 있다.

가독성도 떨어지고 뭔가 불필요하게 try와 catch가 들어있는것 처럼 보인다. (실상은 그렇지 않다. 다 필요하다.)

이처럼 불필요하게 "보이는" try와 catch를 없애려고 아래의 코드처럼 할 수도 있다.


이렇게 하고나면 맨 처음 코드에서 catch가 반복되는 것을 해결 할 수 있어 보인다.

물론 이렇게 하면 해결은 되지만, Java에서의 Exception을 처리할 때의 원칙(Exception들을 catch문 하나에서 한꺼번에 처리하지 않는다)에 위배된다.

즉, out.close에서 발생하는 Exception과 new FileOutputStream에서 발생하는 Exception 모두 하나의 catch문에서 처리가 되어버린다.

이를 해결하기 위해서 또한 아래처럼 코드를 짤 수도 있다.


이렇게 코드를 짜게되면 함수가 IOException을 throw하게 된다. 또한, finally 블록에서 out의 null 체크도 없어졌다.

(new FileOutPutStream에서 Exception이 발생하면 곧바로 IOException을 throw하면서 그 다음 line을 실행하지 않으므로 finally 블록에서의 out은 무조건 null이 아니다)

하지만 나같은 경우는 Exception처리를 외부로 유보하는 것을 좋아하지 않으므로 (이런 사람들이 많을것이라 본다), 개인적으로는 비추천이다.


그래서 이제 최종적으로 내가 "알고 있는 한" 가장 BEAUTIFUL한 코드를 살펴보도록 하겠다.


이 코드를 보면 closeQuietly라는 함수를 finally 블록에서 호출하고 있다.

closeQuietly라는 함수는 Closeable의 varargs 타입을 파라미터로 받아서, 받은 closeable들을 모두 닫아버린다.

이렇게 stream들을 닫는 함수를 따로 만듦으로써 코드가 훨씬 깔끔해졌다.


물론 위의 4가지 스타일 모두 사용가능한 스타일이다.

필요한 상황마다 적재적소에 사용 할 수 있다. 네 번째 스타일의 경우에는 때로는 "닭 잡는데 소 잡는 칼을 쓰는 격"이 될 수도 있다.

이 내용에 대한 프로그래머들의 의견은 http://stackoverflow.com/questions/2699209/java-io-ugly-try-finally-block에서 확인 할 수 있다.

위의 링크를 참조하자면, 4번째 스타일이 가장 낫다는 것이 보편적인 생각인 것 같다.



  

Java에 Pair가 없는 이유 (추측)

Posted by epicdev Archive : 2012. 3. 27. 04:00

출처:  http://stackoverflow.com/questions/156275/what-is-the-equivalent-of-the-c-pairl-r-in-java 

요약: Pair라는 것은 어떠한 자료의 추상적인 형태만을 나타내는 것이지, 실제데이터의 "의미"를 전달하는 명칭이 아니므로

(예를 들면 Pair의 first나 second가 의미하는것은 실제 데이터와 관계가 없다라는 것. 코딩할 때 변수명을 a, b 같은 것들로 사용하지 말라는 것과 같은 맥락)

Pair를 사용하는 것보다, 실제 데이터의 "의미"를 전달 할 수 있는 Entry나 Position이나 Range 등을 사용하는 것이 올바르기 때문이다.


In this thread on comp.lang.java.help, Hunter Gratzner gives some arguments against the presence of a Pair construct in Java. The main argument is that a class Pair doesn't convey any semantics about the relationship between the two values (how do you know what "first" and "second" mean ?).

A better practice is to write a very simple class, like the one Mike proposed, for each application you would have made of the Pair class. Map.Entry is an example of a pair that carry its meaning in its name.

To sum up, in my opinion it is better to have a class Position(x,y), a class Range(begin,end)and a class Entry(key,value) rather than a generic Pair(first,second) that doesn't tell me anything about what it's supposed to do.

  
어떤 파일에 data를 쓸 때 buffer에다가 쓸 내용을 채운 다음 파일에다가 쓰게 된다.
연속적으로 data를 쓸 경우 buffer가 차게되면
프로그램이 알아서 flush를 해준 다음, 그 다음 내용을 buffer에다가 채우게 된다.
하지만 buffer가 미처 다 차기 전에 프로그램이 종료 된다면
현재 buffer에 들어있는 내용은 파일에 쓰여지지 않게된다.
이 때 flush 함수를 호출하면 buffer에 남아있는 내용이 파일에 쓰여지게 된다.

많은 책들의 코드를 보면 flush라는 명령어를 종료직전에 사용하지 않고있다.
대신 close만 사용하고 있다. 이는 close 함수가 내부적으로 flush함수를 호출하기 때문이다.
하지만 많은 책들이 이런 내용을 설명을 해주지 않아서, 나같은 경우는 여태까지 flush를 쓴 다음 close를 또 썼다.
(나는 close 함수는 파일의 핸들을 return하는 함수라고 여태까지 알고 있었다.)
나와 같이 close에 대해 오해를 하는 케이스가 발생하지 않도록 이렇게 글로 남긴다.
  


간단히 설명하지 못한다는 것은, 충분히 이해하지 못했다는 것이다.
                                                                        - 아인슈타인
  
아래의 링크를 따라가시면 프로그래머 점수표(Programmer Competency Matrix)를 보실 수 있습니다.
http://www.indiangeek.net/wp-content/uploads/Programmer%20competency%20matrix.htm 

다양한 분야마다 다양한 항목이 있는데요, 저같은 경우는 대학원생이라 그런지 특정 분야만 2-3점이 나오고 나머지 분야는 0-1점이 엄청 많네요...
스스로 냉정하게 자신을 평가해 볼 수 있는 좋은 기회인 것 같습니다. 또한, 3점의 기준에 맞춰서 앞으로의 학습계획을 짜도 좋을 것 같습니다.

[업데이트 2013.03.27]
Programmer Competency Matrix의 한글 번역본은 아래의 주소에서 찾으실 수 있습니다.

 


  
우선 이 글을 읽기전에 Udacity에 대한 자세한 소개는
제가 예전에 쓴 Udacity를 소개합니다 라는 글을 참고하시길 바랍니다.

3주전 개설한 두 과목인 CS101 검색엔진 만들기와 CS373 무인자동차 만들기의 7주차 강의가 끝난 후
새로이 개설될 3개의 강의들이 현재 수강신청을 받고 있습니다.

CS253: Web Application Engineering
CS262: Programming Languages
CS387: Applied Cryptography




CS253의 경우는 reddit을 만든 Steve Huffman이 직접 수업을 합니다.
스케일러블한 웹 어플리케이션을 어떻게 만드는지에 대해 관심이 많은 저로서는, 개인적으로 가장 기대되는 수업입니다.
그래서 이번엔 이 과목만 수강합니다.
(이번에 CS101이랑 CS373이랑 동시에 수강신청을 했는데 요즘 일하느라 너무 바빠서 CS101과 CS373 둘 다 수강하기가 너무 힘들었습니다.
그래서 지금 CS373은 버려진 상태입니다... 그래서 다음부터는 한번에 최대 한 과목만 수강해서 끝을보자고 결심을 했습니다.)

CS253 - WEB APPLICATION ENGINEERING


Description: Web applications have the power to provide useful services to millions of people worldwide. In this class, you will learn how to build your own blog application starting from the basics of how the web works and how to set up a web application and process user input, to how to use databases, manage user accounts, interact with other web services, and make your application scale to support large numbers of users.

WEEK 1:

How the Web Works
Introduction to HTTP and Web Applications


WEEK 2:

How to Have Users
Getting and processing user input


WEEK 3:

How to Manage State
Databases and persistent data


WEEK 4:

Whom to Trust
User authentication and access control


WEEK 5:

How to Connect
Web applications as services, using APIs


WEEK 6:

How to Serve Millions
Scaling, caching, optimizations


WEEK 7:

Changing the World
Building a successful web application, project







CS262는 버지니아대학교의 CS교수인 Westley Weimer가 수업을 합니다.
지루한 프로그래밍 언어이론 수업에만 그치지 않고 나아가,
HTML과 Javascript를 이해하고 동작하는 간단한 웹 브라우저를 만드는 것이 주된 수업 내용입니다.

CS262 - PROGRAMMING LANGUAGES


Description: This class will give you an introduction to fundamentals of programming languages. In seven weeks, you will build your own simple web browser complete with the ability to parse and understand HTML and JavaScript. You will learn key concepts such as how to specify and process valid strings, sentences and program structures. Then, you will design and build an interpreter - a program that simulates other programs.

WEEK 1:

String Patterns
Finding and specifying classes of strings using regular expressions


WEEK 2:

Lexical Analysis
Breaking strings down into important words


WEEK 3:

Grammars
Specifying and deconstructing valid sentences


WEEK 4:

Parsing
Turning sentences into trees


WEEK 5:

Interpreting
Simulating programs


WEEK 6:

Building a Web Browser
Interpreting HTML and JavaScript


WEEK 7:

Wrap-up
Exam testing your knowledge







CS387은 역시나 버지니아대학교의 CS교수인 David Evans가 수업을 합니다. David Evans는 현재 CS101을 가르치고 있습니다.

CS387 - APPLIED CRYPTOGRAPHY

Description: Cryptography is about “secret writing”. In this class, we will introduce the mathematical foundations of cryptography and build programs to perform encryption. We will see how to use cryptography to solve important problem such as how to authenticate users, secure websites, and do computation without exposing up your data. We will also look at the things that can go wrong when cryptography is misused or implemented badly.

WEEK 1:

Symmetric Encryption
Sending messages when two people share a secret


WEEK 2:

Authentication
Using symmetric encryption to manage passwords securely


WEEK 3:

Asymmetric Encryption
Public-key cryptosystems


WEEK 4:

Public-key Protocols
Secure commerce, certificates


WEEK 5:

Digital Cash
How to make money from numbers alone


WEEK 6:

Secure Computation
Computing without exposing data


WEEK 7:

Wrap-up

Problems cryptography can and cannot solve 
  
 «이전 1 2 3 4 5 6 7 8 ··· 17  다음»