웹디자인을 하면서 글꼴 크기를 표현하는 방법에는 pt, px, em, % 총 세가지의 종류가 있습니다.

저는 주로 px를 사용하지만 해외 웹사이트를 보니 em이나 %를 많 사용하는것 같네요..



PointsPixelsEmsPercent
6pt8px0.5em50%
7pt9px0.55em55%
7.5pt10px0.625em62.5%
8pt11px0.7em70%
9pt12px0.75em75%
10pt13px0.8em80%
10.5pt14px0.875em87.5%
11pt15px0.95em95%
12pt16px1em100%
13pt17px1.05em105%
13.5pt18px1.125em112.5%
14pt19px1.2em120%
14.5pt20px1.25em125%
15pt21px1.3em130%
16pt22px1.4em140%
17pt23px1.45em145%
18pt24px1.5em150%
20pt26px1.6em160%
22pt29px1.8em180%
24pt32px2em200%
26pt35px2.2em220%
27pt36px2.25em225%
28pt37px2.3em230%
29pt38px2.35em235%
30pt40px2.45em245%
32pt42px2.55em255%
34pt45px2.75em275%
36pt48px3em300%



 [자바] 퀵소트(Quick Sort) 란?

프로그래밍 (Programming)

Quick Sort(빠른 정렬;퀵정렬이라 불림)

임의의 Pivot 값을 골라서 Pivot 보다 큰값과 작은 값을 바꾸는 정렬방식으로,
삽입등 바로 옆의 자료와 자리를 변경하지 않기때문에 좀더 효과적이다.

왼쪽에서 오른쪽으로는 P보다 큰 값을 찾고, 오른쪽에서 왼쪽으로는 P보다 작은 값을 찾는다.
그 후 그 값을 바꿔준다. 그리고 왼쪽과 오른쪽의 P가 교차 될경우 마지막에 찾은 가장
작은 값과 맨 앞의 값을 바꾼다. 그 뒤 맨 앞에 있던 값이 옴겨진 자리를 기준으로 나누어서 또 정렬 ...
P 값을 기준으로 왼쪽은 P보다 작은 값들의 집합, 오른쪽은 P보다 큰값 들의 집합이 된다.

아래와 같은 값이 배열에 들어있다고 가정 해서 실습을 보자.

그러면 우선 Pivot(기준)이 되는 숫자를 정하는데 기준이 되는 값은 배열의 맨 왼쪽의 값이 된다.
그리고 Left와 Right부분을 잡게 되는데 처음엔 맨 왼쪽이 Left, 맨 오른쪽이 Right가 된다.

3  5  6  2  1  4

Pivot : 3
Left   : 3
Right : 4

이렇게 초기값이 설정을 한 후
Left  는 Pivot값보다   클 때까지 우측으로 이동한다.
Right는 Pivot값보다 작을때까지 좌측으로 이동한다.

3  5  6  2  1  4

Pivot : 3
Left   : 5
Right : 1

이 될 것이다. 이렇게 되면 Left와 Right의 값을 Swap한다. 그리고 Left는 우측 한칸, Right는 좌측 한칸으로
이동해서 또 위의 같은 조건으로 움직인다.

3  1  6  2  5  4

Pivot : 3
Left   : 6
Right : 2

3  1  2  6  5  4

Pivot : 3
Left   : 6
Right : 2

이렇게 보면 Left의 위치는 4번째고, Right는 3번째 위치를 가리키고 있다.
즉, Left랑 Right가 교차된 상황이다. 그러면 Left랑 Right중 작은 값이랑 Pivot값이랑 Swap을 한다.

2  1  3  6  5  4

이제 한 주기가 돌았다. 

[ 2  1 ]  3  [ 6  5  4 ]

마지막 Swap했던 3을 기준으로 좌측은 3보다 작은 값, 우측은 3보다 큰 값들로 정렬이 되어버렸다.
이제 [ 2  1 ]과 [ 6  5  4 ] 값을 또 위와 같은 방식으로 정렬을 돌려보자.

2  1 ]

Left는 2보다 큰 값이 없으므로 우측 맨 끝으로 간걸로 간주한다.
그러면 Right보다 우측이 있는 즉, 교차 되버린것이다. 그래서 작은 값인 1이랑 Swap된다.

1  2  3  [ 6  5  4 ]

또 교차 되어서 4와 Pivot값인 6과 Swap을 한다.

1  2  3  [ 4  5 ] 6

1  2  3  4  5  6

퀵 소트 정렬이 끝났다.

아직 이해가 잘 안갔을 수도 있으므로 아래의 예를 하나 더 들여보았다.
(아래 예제는 곰팅인간님 블로그에서 가져왔습니다.)

정렬할 값
   [ 26  5  37  1  61  11  59  15  48  19 ]



1차
   [ 26  5  37  1  61  11  59  15  48  19 
   [ 26  5  19  1  61  11  59  15  48  37 ] 
   [ 26  5  19  1  15  11  59  61  48  37 ]
   [ 11  5  19  1  15 ] 26 [ 59  61  48  37 ]

2차
   [ 11  5  19  1  15 ] 26 [ 59  61  48  37 ]
   [ 11 5  1  19  15 ] 26 [ 59  61  48  37 ]
   [ 1  5 ] 11 [ 19  15 ] 26 [ 59  61  48  37 ]

3차
   [ 1  5 ] 11 [ 19  15 ] 26 [ 59  61  48  37 ]
   1  5  11 [ 19  15 ] 26 [ 59  61  48  37 ]
   
4차
   1  5  11 [ 19  15 ] 26 [ 59  61  48  37 ]
   1  5  11  15  19  26 [ 59  61  48  37 ]

5차
   1  5  11  15  19  26 [ 59  61  48  37 ]
   1  5  11  15  19  26 [ 59  37  48 61 ]
   1  5  11  15  19  26 [ 48  37 ] 59 [ 61 ]

6차
   1  5  11  15  19  26 [ 48  37 ] 59 [ 61 ]
   1  5  11  15  19  26  37  48  59 [ 61 ]

7차(완료)
   1  5  11  15  19  26  37  48  59  61





 프로그래밍 배우기 좋은 사이트들 

프로그래밍 (Programming)

Programming IThttp://itguru.tistory.com


개발자의 하루http://devday.tistory.com


PHPSchool - PHP 개발자 커뮤니티http://phpschool.com


KLDP - 리눅스 개발자 커뮤니티http://kldp.org


MSDN 라이브러리http://msdn.microsoft.com/library



최종 업데이트: 2012년 10월 19일 오전 12:25  미국 동부시간.


언어의 기초사항

 

1. 자바 주석문
1) C, C++ 언어 스타일의 주석문
자바 언어는 주석문을 자바 source 코드 내에 프로그램에 수행에 불필요한 코드를 삽입할 수 있습니다.
주석문을 사용하면 source 코드를 설명하는 코멘트를 첨가할 수 있습니다.

C 스타일 주석, 여러 줄에 걸쳐서 사용할 수 있습니다. 형태는 다음과 같습니다.
/* */

C++ 스타일 주석, 한 줄을 주석으로 사용할 때 편리합니다. 형태는 다음과 같습니다.
//

2) javadoc 주석문
javadoc 주석문을 사용하면 해당 class의 상속관계를 표현하는 계층도나 class 멤버들에 대한 설명 등을 html 파일 형태로 제공하는 문서(document)를 만들 수 있습니다. 이러한 문서는 다음과 같이 source프로그램을 javadoc명령에 의해 실행시켜 생성합니다.

javadoc Hello.java

다음은 javadoc 명령 실행시 생성되는 html 파일들의 리스트입니다.

Loading source file Hello.java...
Constructing Javadoc information...
Building tree for all the packages and classes...
Building index for all the packages and classes...
Generating overview-tree.html...
Generating index-all.html...
Generating deprecated-list.html...
Building index for all classes...
Generating allclasses-frame.html...
Generating index.html...
Generating packages.html...
Generating World.html...
Generating serialized-form.html...
Generating package-list...
Generating help-doc.html...
Generating stylesheet.css...
index.html이나 index-all.html 또는 Hello.html 파일을 열어서 보면 해당 source 파일의 상속관계, 구성 멤버들에 대한 정보를 알 수 있습니다.

2. 자바 source file 구조
1) 파일 이름 만들기
자바 파일 이름은 반드시 .java 확장자로 끝나야 합니다. (jav 또는 JAVA가 되지 않게 꼭 주의하셔야 합니다.)
그리고 만약 source 안에 public인 top level class가 있다면 파일 이름은 반드시

public인 class 이름 .java

로 하셔야 합니다.

public class Hello {
public static void main(String[] args) {
System.out.println("Hello World");
}
}

위와 같은 경우 저장할 파일 이름은 반드시 Hello.java로 하여야만 하는 것입니다.

public class Hello {
public static void main(String[] args) {
System.out.println("Hello World");
}
}

class World {
void print() {
System.out.println("World");
}
}


위의 source 파일 이름은 Hello.java 이겠지요?
자바는 컴파일된 후 실행 파일 이름이 .class의 형태로 나옵니다.
따라서 위의 source 프로그램이 컴파일되면 Hello.class 와 World.class 두 개의 파일이 만들어집니다.
물론 이때 Java interpreter와의 실행에는 main 메소드를 가지고 있는 Hello.class를 사용하여야만 하겠지요.

public class Hello {
public static void main(String[] args) {
System.out.println("Hello World");
}
}

public class World {
void print() {
System.out.println("World");
}
}

위와 같은 source 프로그램 코딩은 잘못된 것입니다. 왜냐하면 public은 두 개인데 파일은 하나 밖에 만들 수 없으니까요. 만약 두 class 모두 다 꼭 public이어야만 한다면 파일을 따로 만들어야만 합니다.

class Hello {
public static void main(String[] args) {
System.out.println("Hello World");
}
}

class World {
void print() {
System.out.println("World");
}
}

위의 source 프로그램과 같이 public인 class가 하나도 없는 경우라면 파일 이름은 어떤 class의 이름을 사용하여도 상관없습니다.

class Hello {
public static void main(String[] args) {
System.out.println("Hello World");
}
}

public class World {
void print() {
System.out.println("World");
}
}

위의 source 파일같은 경우 Hello.java로 저장하면 오류가 발생합니다. public이 있는 World.java로 저장하여 컴파일하고 실행시에는 main 메소드를 가진 Hello로 실행합니다.

2) 소스 파일의 기본 구조
source 파일의 구조는 문장에 따라서 순서가 정해져 있습니다.
package 선언문
import 문
class 정의문

즉, 위와 같이 3개의 top level element는 순서에 의해 사용되어야만 하는 것입니다.

이 중 package, import 문장은 꼭 사용하지 않을 수도 있지만, 필요에 따라 source 안에 사용해야 한다면 반드시 위의 순서에 따라 주어야 합니다.

package my.firstpack;
import java.awt.*;
import java.util.*;

public class Hello {
public static void main(String[] args) {
System.out.println("Hello World");
}
}

4. Keyword 와 Identifier
1) Keyword 리스트
C 프로그래머를 위한 몇가지 주의사항은

C에서 많이 쓰셨던 sizeof operator가 자바에는 없다는 것입니다. 이 operator는 자바에서 더 이상 존재의 의미가 없기 때문에 빠지게 된 것.

NULL, TRUE, FALSE 같이 C에서 keyword는 아니지만 #define 문으로 정의해서 사용하던 단어들이 자바에서는 소문자로 바뀌어서 null, true, false와 같은 keyword로 사용됩니다.

자바는 goto, const 같은 단어들을 실제로 구현은 안했지만 keyword로 등록 시켜놓았습니다.

2) Identifier를 만드는 규칙
자바 identifier는 class 이름, 메소드 이름, 변수 이름, 문자 label 등에 사용됩니다.

자바는 일반 문자, 숫자, 그리고 특수 문자('_' 와 '$')등을 조합하여 identifier를 만들 수 있습니다. 이때 반드시 첫번째 문자는 숫자가 아닌 단어로 시작해야 하며 특수 문자도 첫번째 문자로 올 수 있습니다.

자바 keyword는 identifier로 사용할 수 없습니다. 그러나, keyword를 포함하는 단어는 identifier로 사용할 수 있습니다. identifier는 공백을 포함할 수 없습니다.

자바는 ASCII코드를 넘어선 Unicode를 지원하기 때문에, 일반 문자로 'a'-'z', 'A'-'Z' 뿐만 아니라 한글도 사용할 수 있게 되어 identifier를 한글로 만들 수도 있습니다.

그리고 identifier들은 case sensitive하고 실제 maximum length에 대한 제한은 없습니다.


5. 코딩 Convention
1) class 이름과 interface 이름 정하기
class나 interface의 이름은 첫번째 문자를 항상 대문자로 시작해야 합니다. 만약 두 단어 이상으로 만들어져 있으면 단어 사이를 대문자로 연결합니다. class 이름은 보통 명사로 만듭니다.
class 이름 예 : Button, Frame, Applet, Thread, MenuBar
interface 이름 예 : Runnable, LayoutManager, AppletContext

2) 메소드 이름과 변수 이름 정하기
메 소드 이름과 변수 이름은 문장처럼 여러 단어가 올 수 있는데, 항상 첫 번째 문자는 소문자로 시작하고 단어와 단어의 연결은 뒷 단어를 대문자로 시작합니다. 메소드 이름은 보통 동사로 시작합니다. 변수 이름은 보통 명사로 되어있습니다.
메소드 이름 예 : getImage(), getDocumenttBase(), setBackground()
변수 이름 예 : height, width, pointSize

3) 상수 이름 정하기
Primitive Data Type 변수에 값을 할당하기 위해 사용하는 상수는 모두 대문자로 표시하고 단어 사이는 _(underscore)로 연결합니다. Reference Data Type일 경우는 대소문자를 다 사용합니다.
Primitive Data Type 상수 예 : BOLD, ITALIC, CROSSHAIR_CURSOR
Reference Data Type 상수 예 : black, darkGray, UndefinedProperty

6. Data Type(데이터형)과 Literal
1) Primitive Data Type (기본 데이터형)
자바에는 Primitive Data Type과 Reference Data Type(참조 데이터 형 = Object Reference Data Type)이라는 두 가지의 Data Type이 있습니다.

Primitive Data Type의 종류에는 boolean, char, byte, short, int, long, float, double 등 8개가 있습니다. Primitive Data Type 으로 선언된 변수는 실제 값을 갖게 됩니다.

이와는 달리 Reference Data Type으로 선언된 변수는 어떤 값이 저장되어 있는 메모리의 주소를 갖게 됩니다.즉, 블럭 구조로 여러 다른 Data Type의 값들을 모아놓은 곳의 base address를 갖게 되고, 이 정보를 바탕으로 여러 값을 얻어낼 수 있으므로 Reference(참조)라는 말을 붙인 것입니다. Reference Data Type에는Array(arrary), class, interface가 있습니다.

자바의 모든 Primitive Data Type들은 Java Virtual Machine(JVM)을 따르기 때문에platform에 따라 크기가 바뀌지 않습니다. 대표적인 경우가 int입니다. C 언어에서는 platform에 따라 int크기가 다양하게 바뀐다는 것을 알고 계시죠? 하지만 자바는 그렇지 않다는 것입니다. 아마도 이 점이 sizeof가 필요 없는 이유 중 하나일 것입니다.

boolean Data Type
자 바는 C에는 없는 boolean Data Type이 존재합니다. boolean Data Type으로 선언된 변수는 true와false 두 가지 값만을 가질 수 있습니다. true와 false는 반드시 소문자로 코딩해야한다는 점을 잊지 마십시오.

char Data Type
자바의 char Data Type은 ASCII를 지원하지 않고 2 byte Unicode를 지원하기 때문에 16 bit의 양의 정수로 표현 되어집니다.
즉, 실제 가질 수 있는 값의 범위는 0 부터 2^16 - 1 까지인 것입니다. (unsigned라는 뜻이지요.)

byte, short, int, long (Integral) Data Type
모든 Integral Data Type은 signed입니다. 즉, 2's complement 방식으로 표현되는 것이지요.unsigned integral type은 지원하지 않습니다. Integral Data Type들의 표현 값의 범위는 다음과 같습니다 :


float, double (Floating point) Data Type
Floating point Data Type은 IEEE754 Spec.에 따라 표현되어 있고 역시 platform에 상관없이 구현되어 있습니다. float Data Type은 32 bit 크기의 실수를 표시할 수 있으며, double Data Type은64 bit 크기의 실수를 표현할 수 있습니다

2) 사용되는 literal
boolean literal
literal은 소문자인 true, false 두 가지 종류 밖에 없습니다.

boolean isFull;
boolean beOk = false;

isFull = true;

char literal
char data type에 대한 literal은 C에서와 마찬가지로 single quotes에 둘러싸인 문자로 표현됩니다.그리고 코딩시 입력하기 어려운 문자 값을 넣기 위한 escape sequence를 자바도 '\n' 형식으로 지원합니다.

char ch1 = '\n';
char ch2 = '\r';
char ch3 = '\t';
char ch4 = '\u88ab'; // Unicode 표현

char ch5;

ch5 = 'a';

여기서 특이하다면 '\u' 라고 할 수 있는데, \u 뒤에는 2 byte Unicode 즉, 4개의 hexa value가 올 수 있습니다. '\u88ab'의 의미는 실제 Unicode 88ab번의 문자라는 것 입니다.

Integral literal
Integral Data Type으로 선언된 변수가 가질 수 있는 Integral literal은 C와 마찬가지로 decimal, octal, hexa 의 3가지 표현으로 나타나집니다.


그리고 위의 숫자들과 같이 특별한 suffix가 없으면 모두 int type으로 간주합니다. 만약 int 크기가 아닌 long 크기를 표현하고 싶다면 숫자 뒤에 l 또는 L을 붙여주면 됩니다.

Floating point literal
만약 어떤 숫자 literal이 decimal point(.) 나 expornent part(e, E)를 사용하여 표현되어 지거나 또는 suffix로 f, F, d, D 중 하나를 포함하고 있으면 Floating point literal로 처리되게 됩니다. suffix를 사용함에 있어 f 나 F 없이 사용된 literal은 무조건 double(64 bit) 크기로 인식이 되어버립니다.


String literal
자바의 String Data Type은 class로 만들어져 있는 Reference Data Type 이지만 연속적인 문자열을 표시하기 위한 literal이 제공되고 있습니다. 물론 unicode로 만들어지고 double quotes를 사용하여 둘러싸게 되어 있습니다.

String msg = "이 문자열은 테스트용 입니다.";

7. 변수 선언 : 기본 개념
1) 자바의 변수 선언
메 모리상의 데이터를 프로그램에서 접근하기 위해서는 실제 데이터를 나타내는 변수가 있어야 합니다. 변수를 이용하여 프로그래머는 메모리상에 데이터를 저장하고 반대로 저장된 데이터를 불러와 사용하기도 합니다. 즉, 변수는 프로그래머가 메모리상의 데이터에 접근하기 위한 방법이며 데이터와 1 : 1 대응됩니다.

변수를 사용하려면 먼저 변수 선언이라는 절차가 필요합니다. 변수 선언이란 자바가상머신(JVM)에게 데이터를 저장하기 위한 메모리를 할당하라는 의미입니다. 그러기 위해선 데이터 타입이 필요합니다. 데이터 타입에 따라 그 데이터가 필요로 하는 크기만큼의 메모리를 할당합니다. 두 번째로는 변수를 다른 변수와 구별할 수 있는 이름이 있어야 합니다. 이것을 변수명이라 합니다.

자바에서는 변수 선언시 다음과 같은 구조를 가집니다.
데이터 형 변수이름;

예를 들어, 논리형 데이터를 갖는 itsTrue라는 변수를 선언한다면 아래와 같은 문장으로 표현합니다.

boolean itsTrue;

이 때, 데이터 형은 자바에서 정해진 타입 중의 하나로 선언하고 변수이름은 변수이름의 coding convention에 따라 정의할 수 있습니다.

2) Primitive Data Type 변수 선업법
Primitive Data Type들은 C에서와 마찬가지로 선언과 동시에 자신의 크기에 맞는 메모리 할당이 동시에 일어납니다.

3) Referance Data Type 변수 선언법
boolean, char, byte, short, int, long, float, double과 같은 Primitive Data Type은 이에 대한 정보가 컴파일러에 내장되어 있어 선언과 함께 정의된 만큼의 메모리를 생성하게 됩니다.

하지만 Array, class, interface 등과 같이 그때 그때마다의 정의에 따라 메모리 할당에 필요한 정보가 달라지는 Reference Data Type으로 선언될 변수는 선언과 생성이 분리되어 있습니다. C와 비교해 보자면pointer 처럼 선언 후 따로 memory 할당을 해줘야 한다는 것이지요. 물론 할당에 관련된 기능이 따로 있습니다.C++처럼 new라는 operator를 사용해서 dynamic하게 heap으로부터 할당해서 쓰게 되어 있습니다.

import java.util.*;

class TestVar {
public static void main(String[] args) {
String msg; // 라인 1.

msg = new String("sample 1"); // 라인 2.
}
}
String은 class type입니다. 그러므로 라인 1번으로는 선언만 이루어진 것이지요. 따라서 라인 2번과 같이 String object를 만드는 (메모리 할당) 작업이 병행되어야 합니다.

import java.util.*;

class TestVar {
public static void main(String arg[]){
String msg = new String("sample 2");
}
}
위와 같이 선언과 생성이 한줄로 표현될 수도 있습니다. 앞서 Reference Data Type으로 선언된 변수는 어떤 값이 저장되어 있는 메모리의 주소를 갖는다고 했던 것 기억 나시죠? 이 개념은 마치 C에서의 pointer 개념과 거의 유사한 것으로 분명한 차이점은 C에서의 pointer 변수는 arithmetic 연산이 가능했던 반면 자바의 Reference Data Type 변수는 이러한 연산이 불가능하다는 것입니다.

import java.util.*;

class TestVar {
public static void main(String arg[]){
String msg = "sample 3";
}
}
특별히 String은 위의 예문과 같이 new를 사용하지 않고 literal만으로도 내부에서 필요한 object가 만들어지게 되어 있습니다.

import java.util.*;

class TestVar {
public static void main(String arg[]){
Date today = new Date();

System.out.println("Today is:" + today);
}
}
위와 같이 class type인 Date로 변수를 선언하고 생성하면 시스템에 의해 오늘의 날짜 값이 변수에 저장되게 됩니다.

8. Array에 관하여
1) Array 선언법
선 언은 컴파일러에게 "이 변수는 Array type이다"라는 것을 알려주는 것이겠죠? 선언시 Array 표시 기호로는 C처럼[]를 사용합니다. 그리고 아시다시피 Array는 특정 type의 element들을 연속적으로 갖는 것이기 때문에 반드시 그element의
type이 무엇인지 알려 주어야만 합니다.

int intArray[];
위의 선언문은 int type의 element를 갖는 Array에 대한 것 입니다. 코드에서 보는 것처럼 C와 비슷한 방식으로 선언이 이루어 집니다. 하지만 다른 점은 [] 안에 몇 개의 element가 와야할지 크기 지정을 하지 않는다는 것입니다. 왜냐하면 크기에 대한 정보는 선언할 때 필요한게 아니라 메모리를 생성할 때 필요하기 때문입니다. 즉, 선언에서는 단지"어떤 어떤 type의 Array이다." 라는 것만 알려주는 것입니다.

double [] dArray, otherArray;
위와 같이 [] 표시 기호를 꼭 변수 뒤가 아닌 앞쪽에 붙여도 상관 없습니다. 단, 이렇게 선언하면 dArray뿐만 아니라 뒤에 연속적으로 나오는 변수명도 Array로 취급됩니다. 따라서 위와 같은 경우 otherArray 변수도double type element를 갖는 Array로 선언된 것으로 취급되는 것입니다. 하지만 다음과 같은 선언은 변수msgArray는 Array이지만 str은 단지 String class type 변수일 뿐입니다.

String msgArray[], str;
반드시 주의하실 것은 선언할 때 [] 안에 절대 size 정보를 주지 말아야 한다는 것입니다. 잊지 마세요!!!

2) Array 생성법 (메모리 할당하기)
이 번에는 어떤 type element를 갖는 Array로 선언된 변수에 실질적인 메모리를 할당하는 방법에 대해 알아보겠습니다.이러한 생성 역시 new 연산자를 이용하게 됩니다. 생성된 모든 Array들은 length 라는 member 변수를 갖게 되는데, 이 member 변수 length에는 element가 몇 개 생성되었는지에 대한 정보가 저장됩니다. sizeof연산자가 필요없는 또 다른 이유라 할 수 있겠죠.

다음은 선언과 함께 new operator를 사용하여 arrary을 생성하는 예문입니다.

int intArray[] = new int[100];
이와 같이 element 갯수에 대한 정보는 new 연산자를 사용 할 때 지정하게 됩니다. 위의 경우 선언과 생성이 완료되면 intArray[0]부터 intArray[99]까지 총 100개의 element를 int type 변수로 사용할 수 있는 것이지요. 이 때 intArray.length에는 100의 값이 저장될 것입니다.

다음은 선언과 생성을 별도로 코딩한 것입니다.

double [] dArray, otherArray;

dArray = new double[100];
otherArray = new double[200];

int i = 5; // 라인 1.
String msgArray[] = new String [i]; // 라인 2.

msgArray[0] = new String("first msg"); // 라인 3.
msgArray[1] = new String("second msg");
msgArray[2] = new String("third msg");
msgArray[3] = new String("forth msg");
msgArray[4] = new String("fifth msg");
앞에서 언급한 것처럼 Array element 갯수는 new 연산자를 사용하는 생성 부분에서 정의되기 때문에, element 갯수에 대한 정보는 위의 예문과 같이 변수화될 수 있는 것입니다.

라인 1과 라인 2의 선언과 생성을 통해 msgArray[0]부터 msgArray[4]까지 5개의 element가 String class type으로 사용할 수 있게 되었습니다. 이 때 (7. 변수 선언 : 기본 개념에서 학습한 바와 같이) String class type은 Reference Data Type이므로 라인 3 이하의 문장들과 같이 String object를 생성하는 작업이 필요함은 이미 다 알고 계시겠죠?

3) Array 초기화

Array는 다음과 같이 한 줄로 선언과 생성, 초기화를 동시에 만들어 낼 수도
있습니다. (잘 익혀두세요!!!)

int intArray[] = {100, 200, 300};
float fArray[] = {1.1f, 2.2f, 3.3f, 4.4f};
String sArray[] = {"hello", "SCJP", "exam"};
이때 Array들은 초기화한 개수만큼 element들이 생성됩니다. 즉, intArray.length는 3의 값을 갖게 되는 것입니다.

또한 다음과 같이 반복문을 이용하여 생성된 Array에 초기값을 할당할 수도 있습니다.

int score[] = new int[3000];

for (int i = 0; i < score.length; i++)
score[i] = i ;
이 평범해 보이는 문장에서 살펴볼 사항은 반복 횟수에 대한 것입니다. 즉, 생성한 Array의 length라는member 변수를 이용함으로써, 만약 나중에 new 문에서 지정한 element의 갯수가 변하더라도 초기화에 사용된 조건문을 일일이 확인 하지 않아도 되니까 그만큼 안전한 프로그램이 될 수 있을 것입니다.

자바는 C처럼 array boundary를 넘어서는 코드를 만들 수 있게 놔두지 않습니다. 물론 컴파일에서는 별 탈이 없겠지만, 실행에서는 array boundary를 벗어나면 이를 잡아내 주게 되어 있습니다.

int score[] = new int[3000];

for (int i = 0; i < 3001; i++)
score[i] = i ;

위와 같은 코드가 컴파일되어 실행된다면 i가 2999일 때 까지는 제대로 잘 실행되어 처리되다가, i가 3000을 갖고score를 access 하는 순간 boundary를 벗어나 다른 메모리 영역을 침범하는 것이 아니라 바로

ArrayIndexOutOfBoundsException

이라는 예외(exception)를 발생시켜 이를 처리 할 수 있게 해주는 것입니다. (예외(exception)에 대한 자세한 내용은 7장에서 다룹니다.)

4) 다차원 Array
자바에서도 2차원 이상인 arrary을 만들 수 있습니다.

int twoDimArray[][] = new int[4][10] ;

이러한 선언과 생성은 twoDimArray[0][0]부터 twoDimArray[3][9]까지 4 by 10의 정사각형을 연상시키는 40개의 element를 만들 것입니다. 그런데 만약 2차원 arrary을 사용함에 있어 각각의 크기를 다르게 하고 싶다면 어떻게 해야 할까요?

int twoDimArray[][]; // 라인 1.

twoDimArray = new int[4][]; // 라인 2.

twoDimArray[0] = new int[5]; // 라인 3.
twoDimArray[1] = new int[10]; // 라인 4.
twoDimArray[2] = new int[3]; // 라인 5.
twoDimArray[3] = new int[7]; // 라인 6.

for (int i = 0; i < twoDimArray.length; i++)
for (int j = 0; j < twoDimArray[i].length; j++)
twoDimArray[i][j] = 0;
라인 2에서는 element 갯수가 4개인 2차원 Array를 생성한 것이고 라인 3,4,5,6에서는 이렇게 생성된 각 element가 필요로 하는 만큼의 Array를 생성하는 것입니다.

for 문으로 이루어지는 초기화 작업에서 각각의 반복 횟수로 사용된 값들을 의미있게 살펴보세요.twoDimArray.length는 4가 될 것이고 twoDimArray[0].length는 5 twoDimArray[1].length는 10 twoDimArray[2].length는 3 twoDimArray[3].length는 7이 될 것입니다. 이렇게 하면 2차원 Array를 꼭 정사각형이 아닌 dynamic한 형태로 사용할 수 있겠죠?

9. class 기본 개념
1) main 메소드 정의하는 법
자바에서의 메소드는 독립적으로 호출될 수 없으며 반드시 객체의 일부로서만 호출이 가능합니다. 그러나 예외적인 메소드가 있는데 바로 main 메소드입니다. 이 메소드는 자바 프로그램을 실행할 때 자바가상머신(JVM)에서 호출되는 최초의 메소드입니다.

java 실행할 class이름
의 명령으로 class를 실행할 때 자바가상머신(JVM)에서 class 이름으로 지정된 class에 포함된main 메소드를 호출합니다.(앞서 살펴본 바와 같이 애플릿의 경우는 조금 다릅니다.) 따라서, 여러 개의 class로 이루어진 프로그램의 경우 반드시 시작 class, 즉 java 명령으로 실행할 때에 필요한 이름의 class에는 main 메소드가 있어야 합니다.

C나 C++과 달리 자바에서는 모든 프로그램이 class scope내에서만 정의됩니다. 그러므로 자바에서는 main 메소드도 한 class의 메소드로 정의하게 되어 있습니다. main 메소드의 선언은 다음과 같은 형식으로 정해져 있습니다.

public static void main(String arg[])

만약 main의 선언 중 무엇인가가 틀려서 맞지 않으면 컴파일 때는 문제가 없으나 실행할 때 main의 선언이 잘못되었다는 error가 나오게 됩니다. 예문을 한번 살펴볼까요?

public class HelloWorld {
public static void main(String arg[]) {
System.out.println(" Hello World!");
}
}

앞서 언급한 것처럼 HelloWorld라는 class의 메소드로 main 메소드가 정의되어 있습니다. 이때,

main 메소드를 public으로 선언한 것은 interpreter와 같이 실행 시킬 때 외부에서도 main을 참조할 수 있게 하기 위함이고, static은 HelloWorld라는 instance를 생성하지 않고도 main을 참조하게 해주며 (이것의 자세한 내용은 5장 3절 4. static modifier에서 다룹니다.) void는 return value가 없음을 뜻하는 것입니다.
main 안의 출력 함수인 println()은 System class 안에 있는 out 멤버 변수의 형(type)인 PrintStream object에 포함된 메소드로서 ()안에 포함된 내용을 출력합니다.

main 메소드의 인수인 String arg[]는 command line에 정의된 문자열을 받아들이는 arrary로 arg라는 이름 대신 다른 이름을 써도 괜찮습니다.

컴파일 완료 후

c:\> java HelloWorld seoul pusan

와 같이 실행시키면 arg[0]에 seoul, arg[1]에 pusan 이라는 문자열이 넘어오는 것입니다.

main 메소드 선언 부분을 보면 String 타입의 arrary이 인자값으로 넘어오는 것을 알 수 있습니다. main메소드의 인자값 args[0]는 자바 interpreter 실행시에 인자로 넘어온 값을 의미합니다. 자바 인자값은 자바interpreter와 시작 class를
제외한 나머지를 모두 인자로 넘겨줍니다.

class ArgTest{
public static void main(String arg[]){ // 라인 1
for(int i=0; i < arg.length; i++){ // 라인 2
System.out.println(arg[i]); // 라인 3
}
}
}
위의 코드는 라인 1의 인자값 arg arrary을 이용하여 라인 3에서 인자의 개수만큼 출력시켜보는 내용입니다.라인 2의 length 변수는 arrary의 크기를 나타냅니다. (7절에서 배웠습니다.) 위의 코드를 작성한 후 컴파일합니다.컴파일 완료 후에 아래와 같이 세가지 방법으로 실행합니다.

java ArgTest 하하하 호호호 // 라인 4
java ArgTest 100 + 200 // 라인 5
java ArgTest // 라인 6

라인 4를 실행하면 라인 1의 arg[] arrary에 "하하하", "호호호" 두개의 String 데이터가 arrary을 이루게 되므로 arg.length는 2가 됩니다. arg[0]에는 "하하하", arg[1]에는 "호호호" String을 할당받습니다.

라인 5의 경우 arg.length는 3이고 arg[0]는 "100", arg[1]는 "+", arg[2]는 "200"의String을 할당받습니다. 이 때, 라인 5의 명령 수행시 입력한 100과 200은 숫자가 아닌 String으로 읽혀오므로 자바 프로그램 내에서 다시 원하는 정수나 실수 타입으로 변환하여 사용해야 함을 주의하십시오.

마지막으로 라인 6의 경우에는 프로그램 실행에 필요한 인자값이 입력되지 않았으므로 arg.length는 0 이고 화면에 출력되는 내용은 없습니다.

2) 변수의 초기화
자바는 크게 두 가지 종류의 변수를 제공하고 있습니다. 하나는 멤버 변수이고 또 하나는 지역 변수입니다. 이 둘은 서로 사용되는 scope도 다를 뿐더러 초기화에 관련된 사항도 많이 다릅니다.

public class TestVar {
int i;
public static void main(String arg[]) {
....
}

int calcSum() {
int j;
....
}
}
예를 들어 위와 같이 TestVar라는 class를 정의할 때 main 메소드나 calcSum 메소드와 동일한 scope에서 정의된 변수 i는 멤버 변수이며, calcSum 메소드에서 정의된 변수 j는 지역 변수입니다.

멤버 변수는 class 안의 어디서든 참조 가능하고 한 class 안에서는 global하게 값이 유지됩니다. (단,static으로 선언된 메소드에서는 non static인 멤버 변수를 access 할 수 없습니다. 자세한 내용은 5장 4절3주제 static modifier에서 설명합니다.) 그리고 멤버 변수가 선언되어 생성된 후 별도로 초기값을 지정하지 않으면 선언한 Data Type에 따라 다음과 같은 default 값을 초기값으로 갖게 됩니다.
Array가 생성될 때 갖는 초기값들과 같은 초기값들이죠?

이와는 달리 지역 변수는 한 메소드 scope 안에 선언된 변수들을 말하는 것으로, 메소드가 호출되었을 때 stack에 생성되었다가 수행이 완료되면 없어지는 성격을 가지고 있습니다. 때문에 지역 변수를 automatic 변수라고도 부릅니다. 이런 지역 변수는 선언되었을 때 멤버 변수와는 달리 시스템에 의해 자동적으로 초기화 값이 주어지지 않습니다. 그래서 자바는 컴파일할 때 초기화를 하지 않고 사용하는 지역 변수는 전부 error로 처리합니다.

public class TestVar {
int sum;

public static void main(String arg[]) {
TestVar t = new TestVar();

System.out.println("SUM=" + t.calcSum(10));
}

int calcSum( int lim ) {
int i = 0; // 라인 1.
int result; // 라인 2.

if (true) {
while (i < lim) {
result = result + i;
i++;
}
}

return result;
}
}
위와 같은 예문을 컴파일하면 지역 error 메세지가 발생할까요? 안 할까요?

이러한 상황의 프로그램에 대해서도 컴파일러는 지역 변수를 초기화하지 않았다는 error 메세지를 발생할 것입니다. 당연하겠죠.하지만, 지역 변수를 선언하고 초기화 하지 않았더라도, 사용을 하지 않으면 컴파일 에러는 발생되지 않습니다.

변수를 선언한다는 것은 사용하기 위한 메모리가 잡히게 되는 것이고, 초기화를 한다는 것은 이를 사용하기 위해 미리 메모리를 정리한다는 의미입니다.

멤버변수는 초기화를 자동적으로 해주니까 문제가 없는데, 지역 변수는 초기화가 자동적으로 되지 않으므로 별도로 사용하기 전에 초기화를 하지 않으면, 그 메모리 영역에 어떤 값이 들어가 있으지 모르겠죠. 이 메모리에 들어있는 정리되지 않은 값, 즉 쓰레기 값을 가지고 동작을 시키려면 어떻게 상황이 발생될 지 모르죠. 이를 막기위해서 초기화되지 않은 지역 변수 사용을 컴파일러가 에러를 발생시키면서 수정하도록 만들어 에러를 미리 방지하는 것입니다.

하지만, 선언만 해놓고 사용하지 않는다면 컴파일시 문제는 없지만 while 구문안의 result = result + i; 라인을 없애보고 컴파일하면 어떻게 되는지, 한 번 테스트 해보세요.

3) 자바의 멤버변수와 지역변수
자바에서는 어디에서 변수를 선언할까요?
자바에서의 변수 선언은 { }으로 묶여있는 곳이라면 어디에서나 가능합니다. C나 C++의 경우 변수 선언 외의 실행문이 나오기 전에 모든 변수가 선언되어야 합니다. 그러나 자바에서의 변수 선언은 어디에서나 가능합니다.

for(int l = 200; l < 500 ; l++){
int j = l * 300;
while ( j < 800){
int k = 500;
}
}
위의 코드를 살펴보면 for문 내에서 int 타입의 변수 l, j가 선언되어 각각 초기화된 후 사용됩니다. 이렇게 { } 내에서 선언된 변수를 지역변수(local variable)이라고 합니다. { } 내에서 선언된 지역 변수는 { } 지역을 벗어나면 자동으로 삭제됩니다.

while(true) {
int var1 = 200;
while (true) {
int var2 = 300;
System.out.println(var1); // 라인 1.
System.out.println(var2); // 라인 2.
break;
}
System.out.println(var1); // 라인 3.
System.out.println(var2); // 라인 4.
}
위의 코드를 살펴보면 라인 1 문장은 라인 1을 포함한 while을 포함한 외부 while 블록에서 선언된 변수var1을 사용하므로 올바른 코드입니다. 라인 2 문장은 라인 2 문장을 포함한 while 블록에서 선언된 변수 var2를 사용하므로 역시 올바른 코드입니다. 라인 3 문장은 라인 3 문장을 포함한 외부 while 블록(첫문장) 내에서 선언된 변수var1을 사용하므로 역시 올바른 코드입니다. 마지막으로 라인 4 문장은 내부의 while 블록에서 선언된 var2가 내부while 블록을 종료하면 더 이상 사용할 수 없는 변수이므로 error가 발생합니다.

class LocalTest{

String s = "member 변수"; // 라인 1

public void m1(){
System.out.println(s); // 라인 2
}

public static void main(String args[]){
String s = "main 메소드의 local 변수"; // 라인 3
System.out.println(s); // 라인 4
System.out.println(new LocalTest().s); // 라인 5
}
}
위의 코드를 살펴보면 라인 1에서 선언되어 초기화된 s 변수가 m1 메소드 내의 라인 2 문장과 main 메소드 내의 라인 5 문장에 의해 사용됩니다. 라인 1의 s 변수는 class가 정의되면서 class { } 내에서 사용할 수 있도록 정의한 것입니다.
이러한 타입의 변수는 class 내에서 멤버 변수(Member Variable)라고 합니다. 그리고 라인 3 문장에 의해main 메소드 내에서도 같은 이름의 변수 s가 선언되어 초기화되었습니다. 라인 3의 s 변수는 main() 메소드 블록 내에서만 사용할 수 있는 변수입니다.

예문에서 살펴보았듯이, 변수가 선언되는 지역에 따라 멤버 변수인지, 지역 변수인지 나눌 수 있습니다. 멤버 변수는 선언된 class 내의 어디에서나 사용될 수 있고 지역 변수는 그 변수가 선언된 블록({ }) 내에서만 사용합니다. 그리고 멤버 변수는 선언과 동시에 자바 컴파일러에 의해 묵시적으롤 초기화값을 할당받습니다. 그러나 지역 변수는 묵시적인 초기화가 이루어지지 않으므로 반드시 프로그래머가 명시적으로 초기화값을 할당하여야 합니다.

각 데이터 타입에 따른 묵시적인 초기화값은 다음과 같습니다.

class LocalTest{

String s ; // 라인 1

public void m1(){
System.out.println(s); // 라인 2
}

public static void main(String args[]){
String s ; // 라인 3
System.out.println(s); //라인 4
System.out.println(new LocalTest().s); //라인 5
}
}
라인 1의 멤버 변수 s 는 라인 2와 라인 5가 실행되면 묵시적으로 null로 초기화되므로 null을 출력합니다. 라인 3의main 메소드의 지역 변수 s는 선언만 하고 초기되지 않았습니다. 지역 변수는 묵시적으로 자동 초기화되지 않으므로 라인 4에서 출력되지 않고 에러가 발생합니다.

10. 매개변수 전달방식
1) 매개변수란?
메소드가 호출 될 때 값을 주어야만 호출 되어지는 것을 쉽게 볼 수 있습니다. 만일, 아래와 같이 선언된 add 메소드가 있다고 가정해 보겠습니다.

int add(int x, int y)
이 메소드를 호출하려면 x, y값을 두개를 넣어 주면 add이라는 메소드는 내부적인 작업을 끝마친 뒤 x와 y를 더해서 return을 하게 됩니다. 이 때 우리는 x, y를 매개 변수라고 합니다. x, y는 add 메소드의 호출과 동시에x, y를 메소드의 내부에서 생성하게 되며 외부에서 넘어오는 값을 중간에서 할당 받게 됩니다. add(1, 2)라고 호출한다면x에는 1이 직접 할당의 방법으로 할당되고 y에는 2가 할당 되어집니다.

int a;
a=8;
......
int add(int x, int y){
return x+y;
}
......
add(1,2);
그럼 언제 매개변수를 사용할까요?

이에 대한 답은 필요하다고 생각 될 때 메소드를 만드는 프로그래머가 만들면 됩니다.

그럼 매개변수는 몇 개까지 사용할 수 있을까요?

이에 대한 답은 역시 필요하다고 생각 될 때 필요한 만큼의 개수까지 사용할 수 있습니다. 즉, 무제한입니다.

메소드의 이름은 매개변수와 결합하여 변수의 역할을 수행하므로 매개변수의 개수와 데이터 형을 맞추지 않으면 메소드는 호출할 수 없습니다. 이 때, 매개변수의 데이터 형은 반드시 지켜야 합니다. 즉, 매개변수는 메소드 내에 만들어지지만 외부로부터 값을 받을 수 있는 유일한 통로입니다.

2) Primitive Data Type 매개변수
다음의 프로그램을 살펴보며 Primitive Data Type 매개변수를 사용할 때 발생되는 결과를 알아보겠습니다.

public class TestParam {
public static void main(String arg[]) {
int ival = 0;
TestParam mainobj = new TestParam(); // 라인 1.

mainobj.effectParam(ival); // 라인 2.
System.out.println("main ival: "+ ival);
}

void effectParam(int ival) {
ival = 300;
System.out.println("sub ival: "+ ival );
}
}
C를 조금이라도 해 본 분들은 이 프로그램의 실행 결과를 예측하실 것입니다. (call by value)

sub ival: 300

main ival: 0
main 메소드에서 0의 값을 가진 ival 변수를 매개변수로 하여 effectParam 메소드를 호출하면 (이미scope가 다르기 때문에) effectParam 메소드에서 사용하기 위한 복사본이 만들어집니다. 즉, effectParam메소드에서 사용하는 ival은 main 메소드에서 전달한 ival의 값을 그대로 갖는 별도의 메모리를 할당하여 사용하는 것으로서effectParam 메소드의
실행이 끝나 return 되면 메모리에서 자동적으로 사라집니다. 그러니 main 메소드의 ival은 당연히 아무 영향도 받지 않게 되는 것이지요.

3) Reference Data Type 매개변수
이번에는 Reference Data Type 매개변수를 사용한 프로그램을 살펴볼까요 ?

public class TestParam {
public static void main(String arg[]) {
Param p = new Param(); // 라인 1.
TestParam mainobj = new TestParam();

p.ival = 100;
mainobj.effectParam(p); // 라인 2.
System.out.println("main ival: "+ p.ival);
}

void effectParam(Param p) {
p.ival = 300;
System.out.println("sub ival: "+ p.ival);
}
}

class Param { // 라인 3.
int ival;
}
자, 여기서는 Param이란 새로운 class를 정의하고(라인 3) Param class의 object를 생성한 후(라인1) 이를 매개변수로 effectParam 메소드를 호출하였습니다.(라인 2) 이와 같은 프로그램의 결과는 어떻게 나올까요?

sub ival: 300
main ival: 300
main 메소드에서 Param class type으로 선언된 p는 new 문에 의해 생성된 Param object의 주소 값을 갖게됩니다.
따라서 이러한 p가 effectParam 메소드에 매개변수로 전달 되는 것은 Param object의 주소 값을 전달하는 것이므로 (effectParam 메소드에서 p가 local 변수이긴 하지만) 결국 main 메소드의 p와 effectParam의p는 동일한 Param object를 point하게 됩니다.

그러므로 effectParam 메소드에서 Param object의 ival을 300으로 바꾼 것은 (비록effectParam 메소드의 실행이 끝나 return 되면 p는 메모리에서 자동적으로 사라진다하더라도) main 메소드의 p가 포인트하고 있는 Param object의 값을
변경한 것이 되는 것입니다.

public class TestParam {
public static void main(String arg[]) {
Param p = new Param();
TestParam mainobj = new TestParam();

p.ival = 100;
mainobj.effectParam(p);
System.out.println("main ival: "+ p.ival);
}

void effectParam(Param p) {
p = new Param(); // 라인 1.

p.ival = 300;
System.out.println("sub ival: "+ p.ival);
}
}

class Param {
int ival;
}
앞에서 살펴 본 프로그램에 라인 1을 추가한다면 어떤 결과가 나올까요? (실제로 만들어 한번 테스트해 보세요.)

sub ival: 300 main ival: 100
이와 같은 결과가 나오는 이유는, p를 매개변수로 전달 받을 때 까지는 main 메소드의 p가 포인트하는 Param object의 주소를 갖고 있었지만, 라인 1을 통해 새로운 Param object를 만들어 이것의 값을 바꾼 것이기 때문입니다. (참고적으로 effectParam 메소드에서 새로 생성한 Param object는 return 되면서 바로Garbage collection의 후보가 된답니다.)

 


JAVA의 정석 2nd Edition (연습문제 풀이)


Cover 페이지


JAVA의 정석.pdf


저작권에 문제가 되면 지체마시고 연락주세요!!!


[한글판] 안드로이드 개발자 가이드 / 안드로이드 입문서


"안드로이드 입문서 3rd Edition을 발행합니다.

 

칸드로이드가 영어로만 씌어져 있던 Android Dev. Guide를 

한글로 번역해 책으로 출간하고, 웹으로 오픈하고,

PDF 파일로 공개하는 것은 확산과 공유의 정신을 고양하기 위해서입니다.


베이직&클래식한 안드로이드 입문서를 기반으로 

개발자들이 보다 발전적이고 창조적인 대화를 나눌 수 있기를 희망합니다.


" 가치 공유의 확산 ! "


이것이 칸드로이드가 안드로이드 입문서를 공개하는 단 하나의 이유입니다.

많은 분들에게 도움이 되길 바라며..


더불어 함께 이 일을 해 나가고 있는 모든 칸드로이드 운영진들께 항상 감사합니다.


2010년 2월 23일


kandroid 운영자."


오픈 소스 라이선스의 이해

 

1. 오픈 소스 라이선스의 정의

사용허락. 저작권자가 일정한 조건을 부여하여 다른 사람에게 특정 행위를 할 수 있도록 허가함. 오픈 소스 라이선스는 해당 오픈 소스 사용방법, 조건, 의무를 명시하고 있으며, 일를 위반할 경우 저작권 위반으로 규정함.
라이선스 운영의 이유 : 저작권자의 권리를 보호하기 위해서 만들어짐

eg) GPL, LGPL, BSDL, GPLv3, Apache License, Eclipse Public License ...

가장 높은 사용률을 보이는 것은 GPL, LGPL이며 대략 69%정도의 사용률을 가짐.
Public Domain 라이선스는 아무런 제한이 없는 공공 자산을 의미함. 저작권의 유효기간이 넘은 소스코드가 해당하는 라이선스

GPL과 GPLv3의 가장 큰 차이점은 Tivoization 에 해당하는 행위를 금지하는가 하지 않는가의 차이라고 생각하면된다. (사용자가 수정한 소스코드를 이용해서 원래의 장비를 기동하려하면 작동을 하지 못하도록 막는 행위)

공통적 준수 사항
저작권 관련 문구, 제품명 중복 방지, 서로 다른 라이선스의 조합
※ 라이선스의 양립성(Compatibility) 문제 : MPL, GPL을 조합한 라이센스를 적용할 경우 요구 조건이 서로 달라 배포 자체가 불가능해지는데 이런 일이 발생하는 경우를 의미함.

선택적 준수 사항
사용 여부 명시(참조나 출처, 문서로 만들어서 함께 배포가능), 소스 코드 공개(원본 소스 코드, 추가 및 수정분, 링크하여 사용하는 경우), 특허(오픈 소스 SW의 원취지 위배)

개략적 내용
현존 오픈 소스 라이선스는 약 1250개 이상.
Reciprocal 오픈소스 : GPL, LGPL. 오픈 소스를 사용하여 만든 소스코드도 오픈 소스로 공개
Permissive 오픈소스 : BSD, Apache. 오픈 소스를 사용하여 상업적인 용도의 사용도 가능

2. 오픈 소스 라이선스의 종류
GPL(General Public License)
가장 큰 영향력을 가진 대표적 라이선스. 리눅스, MySQL, GCC
GPL 소프트웨어의 파생물을 만들게 되면 파생물 역시 GPL
2007.6.27에 발표된 GPLv3의 경우 라이선스 구속력이 강화되어 적용
(GPL 침해 업체는 GPL 소프트웨어 사용금지, 그렇지 않은 업체의 경우 DRM 기능을 탑재한 기기에서만 GPL 적용 소프트웨어 사용)

GPL 대표준수 사항
1) 자유로운 사용 복제 배포 및 수정
2) 저작권 표시, 보증 책임이 없다는 표시 및 GPL에 의해 배포된다는 사실 명시
3) 파생 소스의 경우 GPL 라이선스로 소스 코드를 공개
4) 예외사항으로 리눅스 기반 App 경우 소스 공개 불필요. sun 자바의 경우 classpath 관련 소스코드 공개 불필요
5) 커널 모듈 형태의 Loadable Device Driver 소스 공개 불필요
6) 소스코드 또는 Written Offer 를 함께 제공
7) 자신의 특허를 Royalty-Free 로 제공한 경우에 한하여 이를 구현한 프로그램을 GPL로 배포 가능, 제3자 특허인 경우에도 특허권자가 Royalty-Free 형태의 라이선스를 제공해야만 해당 특허 기술을 구현한 프로그램을 GPL로 배포 가능

LGPL(Lesser General Public License)
OSS의 활발한 사용 권장을 위하여 GPL 규정을 약화시켜 사용 소프트웨어와 자유롭게 연결

LGPL 대표준수 사항
1) 소프트웨어에 대한 자유로운 사용, 복제, 배포 및 수정등을 허용함
2) 저작권 표시, 보증 책임이 없다는 표시 및 LGPL에 의해 배포된다는 사실을 명시
3) LGPL 라이브러리의 일부를 수정하는 경우 수정한 라이브러리를 LGPL에 의해 소스코드를 공개
4) LGPL 라이브러리에 응용프로그램을 링크할 경우 소스코드 공개 불필요
5) 라이브러리 수정 후 동일한 실행 파일 생성을 할 수 있도록 링크시 응용프로그램의 오브젝트 코드를 제공
6) 특허는 GPL과 동일

MPL(Mozilla Public License)
모질라 브라우저의 소스코드 공개. 개작시 소스코드 공개의 의무 및 상업적 이용 허락.
여러 상업적인 성격을 띠는 오픈 소스 라이선스들의 초기 모델
IBM공용 라이선스를 포함한 여러 상용 소프트웨어 라이선스의 근간

기타 라이선스
Academic Free License, IBM Public License, BSD License, .....

오픈 소스 라이선스의 비교
Copyleft : Copyright 에 대한 언어적 유희. 저작권법의 복제 및 수정에 대한 엄격한 제한을 거부. GPL이 대표적인 라이선스이며 Reciprocal 라이선스.
cf) BSD 와 같이 2차 저작물에 대해서 어떤 라이선스등 가능하게 하는 것을 Permissive 라이선스라고 부른다.

오픈 소스 SW의 양립성
A 라이선스 : 2차 저작물 A 라이선스로 선언
B 라이선스 : 2차 저작물 B 라이선스로 선언
이런 경우 라이선스는 양립성이 없다고 말한다.

다중 라이선스의 종류
이중 라이선스 : 2가지 종류의 라이선스를 하나의 소프트웨어에 구분하여 적용
(비지니스 모델로 주로 사용됨)
eg) MySQL AB : GPL과 상용 라이선스를 동시에 제공한다. 어떤 라이선스를 따르더라고 실재 사용자가 얻는 프로그램을 동일하지만, 상용 라이선스를 사용하는 경우 튜닝된 성능과 관리도구를 사용가능하게 만드는 점이 다르다.

 

첨부 파일: 02_오픈소스라이선스의이해_요약본_080728.pdf

 


Microsoft Visual Studio 2010 단축키 포스터

 


코딩 잘하는 10가지 방법


1. 꾸준히 한다.

 

- 프로그래밍 언어도 언어(?)라서, 하루에 몰아서 하는 것보다 매일 꾸준히 하는 것이 중요하다.

경력이 많은 프로그래머들도 몇달만 코딩을 안해도 감이 많이 떨어지는 것을 느낀다.

- 특히 프로그래밍을 처음 배우는 사람이라면, 꼭 컴퓨터 앞에 앉지 않더라도 책을 항상 가까이해서 문법 및 표현에 익숙해지도록 하는 것이 중요하다. 자주보는 것이 중요하다.

 

2. 반복해서 한다.

 

- 단지 태권도 교본을 잘 이해했다고 해서 멋진 발차기를 기대할수 없는 것처럼, 책의 내용을 잘 이해했다고 해서 하루아침에 프로그래밍을 잘할 수 있는 것은 아니다.

- 이해한 내용을 바탕으로 수많은 반복연습을 통해서만 지식을 진정한 자신의 것으로 만들 수 있다. (같은 예제를 공부하더라도 이리저리 조금씩 변경해서 공부하는 것이 좋다.)

- 처음 2~3번은 자세히 보고, 그 다음 부터는 하루에 10분간 10페이지를 훑어보는 식으로 반복하자.

몇달안에 책에 있는 모든 목차와 예제의 위치와 주요내용을 모두 파악할수 있을 것이다. (적어도 언어책 한권, 데이터베이스책한권 정도는 이렇게 할 필요가 있다.)

 

3. 좋은 코드를 많이 보고 따라한다.

 

- 이미 수많은 선배들이 여러문제들에 대한 코딩을 다 작성해 놓았다. 새로운 방법으로 문제를 풀겠다고 도전하는 것은 별 의미가 없다. "이럴때는 이렇게 하는 구나..."라는 것을 배우고 유사한 상황에서 활용하면 되는 것이다. 여러분들이 해야할일은 이러한 경험들을 많이 쌓아 나가는 일이지, 기존과는 다른 새로운 코딩방식을 만들어 내는 것이 아니다.

- 좋은 코드는 보기에도 좋다. 잘정리되어 있고, 별로 특별한 것이 없다. 프로그래밍의 각요소들을 잘이해하고, 각 요소들을 적재적소에 바르게 사용하면 되는 것이다. 단지 소스의 라인수를 줄인다고해서 좋은 코딩이 아닌것이다. 로직이 소스코드에 잘드러날수있게 쉽고 평범하게 작성하는 것이 좋은 코드인 것이다. 이창호의 바둑이 평범하듯이...

 

4. 기본에 충실한다.

 

- 빨리 프로그래밍을 배워서 뭔가 해보고 싶은 여러분들의 마음을 이해하지 못하는 것은 아니다.

그러나, 프로그래밍 하루이틀 할 것도 아니고... 처음에 기본을 잘배워놓지 않으면, 그 이후에는 기회가 잘 없다. 실무에서는 매일 개발하기 바쁘고, 새로운 기술 배우기 바쁘고...

- 배울것이 많다고 생각할지 모르나, 실제로 원리는 모두 같다고 해도 과언이 아니다. 하나를 깊이있게 파고들면 나머지는 다 여러분 손에 있을 것이다.

 

5. 코드를 작성하기전에 순서도를 그린다.

 

- "프로그래밍 = 코딩" 이 아니라 "프로그래밍 = 로직설계 + 코딩" 이다. 필자가 생각하는 로직설계와 코딩간의 비율은 8:2 정도이다.

- 포토샵만 잘한다고 디자이너가 아니라는것은 여러분들도 잘알고 있을 것이다. 새로운 기술이나 프로그램을 공부하는 것도 중요하지만, 어떤 과제가 주어졌을때 이를 잘 분석하고 설계하는 능력을 장기적으로 키워나가도록 노력해야할 것이다. (다양한 주제에 대해서 문제를 풀어보고 다양한 종류의 책을 읽자.)

- 문제를 구성하고 있는 주인공들을 찾아서 나열해보라. 그리고 이들간의 관계는 무엇이고, 규칙은 무엇인지 적어보라. (머릿속으로만 생각하지말고!)

 

6. 주석을 가능한한 많이 적는다.

 

- 주석은 매우 유용하고도 중요한 요소이다. 그럼에도 불구하고 많은 사람들이 이를 소홀히 한다.

자신이 작성한 코드도 몇일만 지나면 이해가 안되는 경우가 많다. 적어도 이해하는데 시간이 걸린다. 주석은 이러한 시간들을 절약해줄것이며, 보다 에러가 적은 코드를 작성하는데 도움을 줄 것이다. 특히 여러사람이 공동작업을 하는 경우에는 더욱 더 중요하다. 서로를 위해서...

- 작업과 관련된 가능한한 많은 정보를 주석에 담도록 하자.

 

7. 작업일지를 작성한다.

 

- 과학자들이 매일 연구한 내용을 일지로 적듯이 여러분들도 일지를 적어보자. 오늘은 이렇게 저렇게 해봤는데 잘안되었다... xxx.java의 코드를 이렇게 바꾸었다. 몇시몇분에 xx로 백업받아 놓았다... 라는 식으로 가능한한 자세히 적도록 한다. 이렇게 함으로써 여러분들의 경험을 기록 으로 쉽게 보관할수 있으며, 문제해결에 많은 도움이 된다.

 

8. 자신의 소스를 가꾼다.

 

- 보통 코딩을 마치고 나면, 모든 것을 덮어두곤 한다. 원하는 결과를 얻었다고 거기서 그치지 말고 이제 로직과 코드를 보다 효율적으로 개선할 방법이 없는지 고민해보자. 글을 써놓고 좋은 글로 만들기 위해 읽고 또 읽고 다듬듯이 코드를 다듬어보자. 여러분들의 코드를 구사하는 능력이 보다 향상되어가는 것을 느낄 수 있을 것이다.

- 여러분들을 위한 제안은 작은 프로그램을 만들어서 오랜기간동안 점차 발전시켜 나가는 것이다. 새로운 기능들을 하나씩 추가해가고, 기능을 발전시켜나가보자. 이과정을 통해서 여러분들의 실력 은 몰라보게 향상될 것이다.

 

9. 생각하라.

 

- 항상 머릿속에 한 가지 문제를 준비하라. 지하철을 기다리거나, 화장실에서 볼일 볼때 문제를 풀어보자. 유레카를 외치고 뛰어나올지도...

 

10. 좋은 책을 선택한다.

 

- 공부를 시작할때 제일 먼저 하는 일은 아마도 책을 고르는 일일 것이다. 보통 책하나에 수십시간을 학습하게 되는데, 책을 잘못선택한 경우 수십시간과 노력을 허비하는 셈이다. 바른 책을 고르는 일은 쉬운일이 아니지만, 최소한 몇시간을 투자해서 최선의 선택을 하도록 노력

해야 수십시간을 허비하는 일이 없을 것이다.

- 책을 고르는 법은 여러가지가 있겠으나, 가장 중요한 것은 본인이다. 서점에서 같은 종류의 몇가지 책을 놓고 서로 비교해보면, 시간을 들인 만큼 보다 나은 선택을 할 가능성이 높아진다.

- 많은 컴퓨터 서적이 독자들의 선택을 어렵게 하고, 컴퓨터 업계 특성상 좋은책을 만들기 보다 빨리찍어서 파는 것이 더 중요해진 요즘. 독자들의 바른 선택이 보다 나은 책이 출판되는 것을 가능하게 한다는 것을 알았으면 한다.


출처: 개발자 천국을 꿈꾸는 최강의 SW 포탈 DEVPIA

1. 안드로이드 SDK Quick Start page 
http://developer.android.com/sdk/index.html 

2. 안드로이드 (SDK에서 Hello World 찍어 보는 튜토리얼) 
http://developer.android.com/resources/tutorials/hello-world.html 

3. Korea Android(구글 안드로이드 홈페이지를 번역한 사이트)
http://www.kandroid.org/guide/basics/what-is-android.html 

4. 역시 kandroid에서 내 놓은 안드로이드 입문서 
http://www.kandroid.com/kandroid_book_3rd_edition.pdf 

5. 한국 안드로이드 관련된 사이트
http://www.kandroid.org 
http://www.androidpub.com 

http://www.androidside.com/


6. 안드로이드 개발 소스

http://code.google.com/p/apps-for-android/


7. 웹서버 연동 앱 작성을 공부 과정

http://www.androidpub.com/80310


8. 안드로이드 OS 뉴스, 강좌, 다운등등..

http://www.helloandroid.com/


9. 디자인 관련

http://developer.android.com/design/index.html

* 액티비티

- 사용자 인터페이스가 있는 프로그램

- 사용자에게 하나의 스크린을 보여줌

- 모든 어플리케이션에는 적어도 하나의 액티비티가 존재함

 

* 서비스

- 백그라운드에서 돌아가는 실행코드

- 일단 실행되면 휴대폰이 꺼질 때까지 돌아감

ex) MP3 플레이어

 

* 브로드캐스트 리시버

- 시스템 전체의 이벤트를 처리

 

* 인텐트 리시버

- 어떤 액티비티나 서비스가 그 기능을 다른 어플리케이션에 제공하기 위해 실행

- 다른 프로그램의 데이터 요청 or 서비스 요청을 처리하는 작은 실행코드

- 요청 프로그램이 인텐트를 발행하면 안드로이가 알아서 이를 처리할 어플리케이션을 결정함

 

* 콘텐트 프로바이더

- 다른 액티비티나 서비스로 정보를 공유할 때 사용됨

* src

- 소스파일 디렉토리

- 패키지 이름에 따라 하위 디렉토리를 생성함

- 액티비티를 위한 자바 템플릿을 포함

 

* gen

- 자동 생성 파일

- 리소스 레퍼런스(R.java)를 포함하는 디렉토리가 생성됨

※ R.java : 어플리케이션을 처음 컴파일할 때 안드로이드 SDK가 만드는 파일, res 디렉토리 안의 모든 리소스에 대해 자바 코드로 된 정보가 들어있음

 

* 안드로이드 라이브러리

- android.jar 포함

 

* asset

- 애셋 디렉토리

- 어플리케이션에 넣고 싶은 파일 모음

 

* res

- 리소스 파일 디렉토리

- drawable : 어플에서 사용하는 이미지나 비트맵 등

- layout : 화면 구성을 위한 XML 파일

- value : 어플에서 사용하는 상수나 고정된 문자열, 사용시 커스터마이징할 때 편리해짐

 

* AndroidManifest.xml

- 어플리케이션을 빌드하고 하나로 묶어 휴대폰이나 애뮬레이터에 설치할 때 필요한 파일 목록을 알려줌

APCS ArrayList Notes




작년 학교에서 유용하게 썼던 노트.


영어로된 노트지만... 

나에겐 큰 도움이 됬다는


파일 첨부: 

APCS ArrayList Notes.pdf








The Java™ Tutorials: Operators

자바강의: 연산자


Operator Precedence

OperatorsPrecedence
postfixexpr++ expr--
unary++expr --expr +expr -expr ~ !
multiplicative* / %
additive+ -
shift<< >> >>>
relational< > <= >= instanceof
equality== !=
bitwise AND&
bitwise exclusive OR^
bitwise inclusive OR|
logical AND&&
logical OR||
ternary? :
assignment= += -= *= /= %= &= ^= |= <<= >>= >>>=

관계연산자 : 두 피연산자 사이의 값을 크기 또는 관계를 비교하는 연산자로서 true, false 로 구분한다.
관계 연산자의 종류는 다음과 같다.

연산자

연산식

설명

A > B

A B보다 크면

>=

A >= B

A B보다 크거나 같으면

A < B

A B보다 작으면

<=

A <= B

A B보다 작거나 같으면

==

A == B

A B 같으면

!=

A != B

A B 다르면

instance of

A instance of B

A B 인스턴스이면


논리연산자 : 두개의 논리값을 평가하여 true, false 의 논리형 결과를 

반환하는 연산자를 말한다.

연산자

연산식

설명

!

!A

A가 거짓(false)이면 (true)

&&

A&&B

A B가 모두 참이면 참
A 거짓이면 B를 평가하지 않음

||

A|| B

A이나 B 둘 중 하나라도 참이면 참
A 참이면 B를 평가하지 않음

&

A & B

A B가 모두 참이면 참
A 거짓이어도 B를 평가함

|

A | B

A이나 B 둘 중 하나라도 참이면 참
A 참이어도 B를 평가함


연산자의 우선 순위는 다음과 같다.

연산자의 수행 시 여러 연산자가 혼용된 경우 연산자의 우선순위에 따라 수행하도록 한다.

1

 ( ), [ ]

2

 ++, --, ~, (+), (-)

3

 *, / ,%

4

 +, -

5

 >>, <<, >>>

6

 <, <=, >=, >

7

 ==, !=

8

 &

9

 ^

10

 |

11

 &&

12

 ||

13

 expr?op1:op2

14

 =, +=,-=, *=, /=, %=

OperatorPurpose
+addition of numbers, concatenation of Strings
+=add and assign numbers, concatenate and assign Strings
-subtraction
-=subtract and assign
*multiplication
*=multiply and assign
/division
/=divide and assign
%take remainder
%=take remainder and assign
++increment by one
--decrement by one
>greater than
>=greater than or equal to
<less than
<=less than or equal to
!boolean NOT
!=not equal to
&&boolean AND
||boolean OR
==boolean equals
=assignment
~bitwise NOT
?:conditional
instanceoftype checking
|bitwise OR
|=bitwise OR and assign
^bitwise XOR
^=bitwise XOR and assign
&bitwise AND
&=bitwise AND and assign
>>shift bits right with sign extension
>>=shift bits right with sign extension and assign
<<shift bits left
<<=shift bits left and assign
>>>unsigned bit shift right
>>>=unsigned bit shift right and assign


참고: 

Operators

Summary of Operators

Java Operators

http://jmonster.springnote.com/

 컴퓨터와 통신 장비 또는 비롯한 문자를 사용하는 많은 장치에서 많이 사용되는는 코드죠..ㅎㅎ



'프로그래밍' 카테고리의 다른 글

[자바] APCS ArrayList Notes  (0) 2012.07.04
[자바] 자바강의: 연산자 / Operators  (0) 2012.07.04
[자바] 소설같은 자바교재: 자북  (0) 2012.06.13
[자바] JAVA 강의 노트  (0) 2012.06.13
Links  (0) 2011.10.16

소설같은자북(jabook.com)-소설같은시리즈(Java, C#, C, JSP)





대충 이렇게(??) 생겼습니다.


http://www.jabook.com/




'프로그래밍' 카테고리의 다른 글

[자바] 자바강의: 연산자 / Operators  (0) 2012.07.04
아스키코드 표 (ASCII Code Chart)  (0) 2012.06.21
[자바] JAVA 강의 노트  (0) 2012.06.13
Links  (0) 2011.10.16
알고리즘 사이트 Programming-challenges  (0) 2011.10.16

JAVA 강의 노트


어디서 난지는 기억이 잘....


JAVA 강의 노트.pdf


이 노트로 작년 학기 시작하기전에 공부하니 좀 도움이 되는것 같네요..


제가 만든건 아니지만 유용하게 사용하세요!!


저작권에 문제가 되면 지체마시고 연락주세요!!!



첫번째 장 입니다.




위의 이미지는 Daum 책으로 부터 발취하였습니다.

알고리즘 공부를 위해 트레이닝 북을 하나 구매하였습니다. 서론의 내용을 읽어보니 Programming Challenges라는 공개된 알고리즘 문제은행 웹사이트의 문제를 기반으로 알고리즘이 설명되어 있습니다.

제가 이글을 적은 이유는 여러분들은 굳이 책을 사지 않고도 알고리즘 문제 은행을 이용할 수 있기 때문입니다.
물론 책을 사서 본다며년 풀이과정과 자료구조, 알고리즘등의 설명이 나와 있어 도움이 됩니다. :D


http://www.programming-challenges.com 에 접속하면, 다음과 메인 페이지를 만나 볼 수 있습니다.



다음과 같은 절차면 Programming-challenges 웹사이트를 이용하는데 무리가 없을 듯 합니다.
  • 회원 가입을 한다.
  • 로그인한다.
  • 알고리즘 문제를 확인하고 코드를 작성한다.
  • 웹사이트에 제출한다.


본인의 계정 아이디로 로그인한 후 , 왼쪽의 All problem을 누르면 우측에 모든 문제들을 확인 할 수 있으며, 우측의 빨간테두리 해놓은 SUBMIT버튼으로 코드를 제출합니다.




코드를 작성할 때는 C, C++, Java, Pascal로 제출할 수 있습니다. Pascal까지 지원한다라는게 좀 의외네요. 저는 자주 사용하는 C언어로 코드를 작성하고 제출합니다. 참고로 코드는 main 함수만 제출하는게 아니고 본인이 작성한 모든 코드 부분을 제출해야 합니다.
아마도 웹 서버 내부적으로 해당 내용을 그대로 컴파일하여 결과값으로 확인을 하겠죠.


Programming-challenges 웹사이트에서 모든 정보는 영어로!! 제공됩니다. 또한 모든 문제들은 stdin으로 입력값이 제공되고 본인이 작성한 알고리즘에 의해 stdout으로 결과 값이 출력되게 코드를 작성해야 합니다.


Programming-challenges에서는 코드를 제출하면 10~30초 안에 결과가 Status로써 반영됩니다.

Never summited 제출되지 않음.
Solved 문제 해결됨.
Presentation Error 잘못된 출력값(출력 형태가 맞지 않음)
Wrong answer 잘못된 출력값(알고리즘이 잘못되어 출력값이 맞지 않음)

문제를 잘 읽어봐야 Presenatition Error를 피할 수 있습니다. ㅠㅠ


마지막으로 Programming-challenges는 영어의 압박이 있지만 약 300여개의 문제가 있습니다.하루에 1개씩만 풀어도 대충 10달정도 걸리겠네요. 무료로 이용 가능한 알고리즘 문제풀이를 함으로써 문제 해결능력과 코딩 스킬을 높히시는데 도움이 됬으면 합니다.

[출처: http://www.morenice.kr/55]

'프로그래밍' 카테고리의 다른 글

아스키코드 표 (ASCII Code Chart)  (0) 2012.06.21
[자바] 소설같은 자바교재: 자북  (0) 2012.06.13
[자바] JAVA 강의 노트  (0) 2012.06.13
Links  (0) 2011.10.16
프로그래밍 초보자가 알아야 하는 9 + 1 가지  (2) 2011.10.16
지금와서 보면 초보 시절에 별것 아닌 것으로 많은 시간과 많은 밤들을 보내면서 나름 프로그래밍의 세계에서 매력아닌 매력에 빠지곤 했었습니다. 지금의 초보자들을 보면서 지난 프로젝트들을 되돌아보고 저 역시 저질렀거나 하지 말았으면 하는 것들에 대해서 한번 생각을 해보았습니다.


so I went for a walk to a place that I know.
so I went for a walk to a place that I know. by Sanctu 저작자 표시비영리동일조건 변경허락

이는 비단 프로그래밍에 갓 입문한 사람 뿐만 아니라, 다른 프로그래밍 언어를 처음 접할 때에도 적용되는 내용 같습니다.

1. 프로그래밍의 최대의 적은 Copy & Paste이다.

IT에서 일어나는 작업들은 모두 사람의 힘을 배가시키기 위함이고, 이를 위해서는 최대한 자동화를 시켜주는 것이 그 목적일 것입니다. 따라서, 프로그래밍이라는 작업 역시 일일히 모든 것들을 만들기보다는 최대한 재사용할 수 있는 것들을 활용하는게 작업 능률에 있어서 최적일 것입니다. 그 중에서 프로그래밍 작업 중에 제일 흔하게 일어나는 일이 Copy & Paste입니다. 하지만, 익숙한 프로그래밍 언어라도 Copy & Paste는 주의를 필요로 합니다. 더군다니 초보 시절의 Copy & Paste는 독이 될 수도 있으며, 결국 잘 이해되지 않은 코드의 Copy는 어떠한 문제를 일으킬지 잘 모릅니다.

Palacio de las Artes Reina Sofía C.A.C / Palace of Arts Reina Sofia  C.A.C./ Palais des Arts Reina Sofia C.A.C.
Palacio de las Artes Reina Sofía C.A.C / Palace of Arts Reina Sofia C.A.C./ Palais des Arts Reina Sofia C.A.C. by Iabcstm 저작자 표시비영리변경 금지


초보 시절은 동일한 코드라고 하더라도 직접 키보드를 통해서 입력하거나 도구를 정상적인 경로를 통해 사용해봄으로써 머리와 몸으로 코드의 원리를 체득해야 합니다. 심지어 수천라인의 XML 코드라고 하더라도 일일히 쳐보면서 그 의미를 하나하나 쫓아서 읽을 수 있어야 합니다. 무분별한 Copy & Paste는 발생하는 에러를 엉뚱한 곳에서 디버깅하게 만듭니다. 요즘에는 책을 사면 소스 코드를 다운받게 되어 있습니다. 해당 내용을 잘 알고 어느 정도 이해를 하고 있는 사람이라면 상관없겠지만, 초보자들에게는 이 역시 소스 코드를 다운받아서 실행하는 것보다는 직접 책에 있는 내용을 쳐보고 이해하는 것이 많은 도움이 됩니다. 혹 책의 내용이 이전 라이브러리들을 참고하고 있어서 지금의 환경에서 이를 적용하려면 더 많은 수고들을 거치는 경우도 발생됩니다. 이러한 과정을 거치게 되면 또 다른 지식들이 쌓이게 되니, 헛짓이나 삽질이라고 생각하시면 안됩니다.

초보 시절 저 역시 수많은 코드들을 직접 손으로 치면서 많은 것들을 이해할 수 있었고, 더 많은 연결된 부분들을 찾아볼 수 있었던 것 같습니다. 반복적인 작업이지만, 그 자체로 더 없는 많은 내용들을 얻게 될 것입니다.

2. 가이드 대로 따라하면 안된다.

프로젝트에서는 수많은 가이드들이 만들어지며, Step By Step 형식으로 나와있는 문서나 자료들도 많이 있습니다. 초보 시절에는 가이드를 보는 것 역시 중요하겠지만, 그 내용을 곧이 곧대로 믿어서도 안됩니다. 특히나 프로젝트 중후반부로 들어갈수록 초반에 만든 가이드는 잘못되거나 수정된 내용이 많아질 가능성이 많습니다. 가이드는 대략적인 내용들을 보면서 어떠한 흐름으로 프로그래밍을 하게 되는지에 대한 지식을 얻으면 됩니다. 또한, 프로그래밍은 가이드에 나타난 내용 이외에도 더 많은 지식과 기술을 필요로 합니다. 가이드는 말 그대로 안내하는 용으로만 사용해야지 가이드가 모든 것을 가르쳐준다고 생각해서는 절대 안됩니다.


Day 106 - I am a librarian
Day 106 - I am a librarian by cindiann 저작자 표시비영리변경 금지


가이드를 절대적으로 믿는 행위 중에 하나는 가이드에 표현되지 않은 것들에 대해서는 아무런 사고를 안하게 만든다는 것입니다. 예를 들어, 예상치 못한 에러나 경고 문구가 나타나도 이를 신경쓰거나 무엇이 문제인지를 찾으려는 노력을 하지 않게 만듭니다. 이는 가이드를 만들고 배포하는 측에서도 가이드만 보고 따라하라는 암묵적인 강압을 하는 태도도 일조한 결과입니다. 가이드를 맹신하지 마십시오.

3. 한가지 정답을 찾으려고 하지 마라.

우리가 학교에서 배운 것들은 모두 정답이라는 한가지 목적에만 초점을 맞추어 있습니다. 사회의 초년생들 역시도 정답이 아니면 안된다는 사고를 가진 사람들이 대부분인 것 같습니다. 정답은 늘 해당 상황에서만 정답이 될 뿐이며, 다른 상황에서는 오답이 될 가능성이 높습니다. 프로그래밍에서 어느 한가지로 해결했다고 해서 이것이 다른 프로젝트에서 똑같이 적용될 수는 없을 겁니다. 정답보다는 그 가능성에 대해서 염두해 두십시오. 가능성은 확률로도 표현이 가능하며, 가능성이 높다는 것은 다양한 전제 조건을 포함한다는 것입니다. 즉, Context라는 단어가 의미하는 바를 이해하고, 그 상황에서 다양한 전제 조건과 제약 조건들을 같이 고려하여 가능성이 제일 높은 해결책을 찾는 것이 프로그래밍을 배울 때 같이 익혀야 할 내용입니다.

현실에서는 프로그래밍으로 할 수 있는 것들이 의외로 많고, 그러한 내용들이 나타나는 프로그램은 단지 그 결과에 지나지 않습니다. 다른 사람의 정답을 참고할 수는 있겠지만, 그러한 정답이 지금의 프로젝트 내에서 반드시 정답이라는 보장을 하기 힘듭니다. 그 사람의 정답(결과)이 만들어지는 배경과 상황을 같이 이해해야 합니다.

4. 고민을 끌어안고 있지 말고, 터뜨려라.

프로그래밍의 초보 시절에는 단순한 문제라도 심각한 고민거리가 되기 쉽상입니다. 그러한 고민거리는 그 누구한테 물어보는 것조차 힘겨운 법입니다. 고민을 하는 것은 그리 나쁜 것은 아니지만, 주어진 시간과 다른 작업으로의 연결이라는 제약사항들이 있기 때문에 무한정 고민만 할 수는 없습니다. 고민을 하는 시간조차도 효율적으로 사용해야 하며, 정 고민이 해결되지 않는다면 터뜨리십시오. 누가 물어보기 전까지 고민을 안고 있다라는 것은 다른 사람으로 하여금 실력이 없다라는 충분한 오해를 받을 만한 일입니다. 본인의 실력이 드러날까봐 고민을 안고 불안한 마음에 있는 것보다는 고민을 터뜨려서 해결하는 방법을 채택하는 것이 오히려 전체적인 관점에서 더 좋은 결과가 나타날 수 있습니다.

고민을 터뜨리는 방식은 단순하게 이 부분을 모르겠다고 솔직하게 털어놓는 것도 있을 수 있지만, 좀 더 유연한 방식으로는 그동안 고민했던 내용들을 다시 정리해보고, 왜 문제가 있는지를 간략하게 설명할 필요가 있습니다. 이때 주의할 점은 본인의 입장에서만 고민을 정리하다보면 상대방이 고민에 대한 본질적인 문제보다 그 부수적인 내용이 더 이해하기 힘든 경우가 발생됩니다. 고민은 최대한 간략하고 이해할 수 있도록 정리하는 기술이 필요합니다.

5. 통용되는 정확한 용어를 사용하라.

초보 시절에는 모든 단어와 용어들이 낯설기만 합니다. 그러한 용어들은 선배들이 잘못 이해하여 사용되는 경우들도 있습니다. 용어를 들은대로만 사용하기보다는 그 뜻과 의미를 정확하게 알아보는 습관을 들이는게 좋습니다. 또한, 그러한 용어를 알아가는 과정이 전번적인 내용을 이해하는 과정이기도 하며 이는 프로그래밍에 대한 지식을 더 폭넓게 이해하게 만듭니다.

대표적인 예가 디자인 패턴의 패턴 이름인데, 이러한 패턴 이름들은 상당한 오랜 시간 동안 많은 사람들에게 사용되어 왔습니다. 단순하게 이름만을 듣고, 그에 대한 배경 지식이 없는 상태에서 프로그램된 상태만을 본다면 나중에 또 다시 잘못 사용하여 이를 듣는 사람에게 오해를 불러일으킬 수도 있을겁니다.

변수명, 클래스명, 메소드명 등 역시 정확한 (비즈니스) 용어를 사용해야 합니다. 귀찮다고 줄이거나 임의로 이해할 수 없는 용어를 만들면 다른 사람이 보기가 힘들어집니다. 예전 기술들이야 워낙에 HW 용량에 대한 문제가 커서 이름이나 용어에 대한 길이 한정 제약이 있었지만, 지금은 이러한 제약에서 훨씬 자유롭습니다. 의미있고 정확한 이름을 사용하기 바랍니다.

6. 프로그래밍의 내용은 한편의 시나리오(소설)를 보는 듯하게 만들어라.

초보 시절의 프로그래밍 습관은 상당히 중요합니다. 주석, 변수명, 메소드 호출 등에 있어서 다양한 습관들이 서로 다르게 표현될 수 있습니다. 특히, 프로그래밍의 내용은 비즈니스의 흐름과도 동일하며, 그 흐름은 마치 한편의 드라마를 보듯이 매끄럽게 이어져야 합니다. 변수 선언, 객체 생성, 리소스 획득, 메소드 호출 등이 뒤죽박죽 섞여 있어서 코드를 본다는 것 자체가 무슨 내용인지를 모르게 구성하는 경우들이 있습니다. 프로그래밍의 내용은 코드만을 보고도 어떠한 흐름으로 이어지는지를 알 수 있게 구성되어야 하며, 이는 마치 시나리오와 같습니다.

어떤 경우에는 초반에 만든 코드와 나중에 수정한 코드가 뒤범벅이 되어서 어떤 것이 실제로 사용하는지도 잘 모르게 구성되는 경우도 많습니다. 정 이전 코드를 참고하고 싶으면, 차라리 주석 처리하거나 별도의 메소드를 만들어서 구성하는 것이 더 깔끔할 겁니다. 그리고, 사용되는 것과 사용되지 않는 것들에 대한 구분 역시 필요하며, 이는 본인만 알아볼 수 있는 것이 아닌 공통적으로 누구나 알아볼 수 있는 표시를 해야 할겁니다.

코드는 실행되는 것도 중요하지만, 무엇보다 깔끔한 형태의 코드 결과도 상당히 중요합니다. 그 안에는 누구든지 해당 코드를 보고 쉽게 이해할 수 있고, 이름만 보더라도 무엇을 하는 객체인지를 알 수 있게 구성하는 것이 훨씬 중요합니다.

7. 처음부터 구조화시킬 필요는 없다.

처음에 프로그래밍 언어에 익숙해지기 시작하면서 코드에 대한 구조를 생각하게 되고, 초반부터 이해하지 못하는 구조를 만들기 시작하는 경우도 있습니다. 구조화는 코드가 동작하는 상태에서 의미가 있으며, 구조화되지 못한 코드라고 하더라도 동작한다면 크게 문제되지 않을 수 있습니다. 초반에 구조화를 시도하다가 많은 시간을 허비하는 경우도 있으며, 다양한 구조화를 시도하다가 실제 작업은 진행하지 못하는 경우도 많습니다. 또한, 초반에 너무나 많은 내용을 한꺼번에 프로그래밍을 하다보니, 테스트할 시간조차도 부족한 경우도 있습니다.

처음 객체를 만들때에는 가장 단순하고 적은 데이터만을 사용해서 전체적인 뼈대를 구성하는 것이 가장 좋습니다. 그리고, 이러한 뼈대에 차츰 살을 붙여서 완성해가는 것이 좋은 방법입니다. 뼈대가 구성되지 않은 상태에서 살을 붙일 수는 없을겁니다. 어느 정도의 구조화는 필요하겠지만, 여기에 모든 노력을 기울여 자신의 실력을 뽐낼 필요까지는 없습니다. 보여주고자 하는 데이터가 한두개 모자란다고 크게 문제되지는 않습니다. 이러한 문제들은 테스트를 통해서 수정하기만 하면 됩니다. (물론, 테스트를 할 수 있는 시간이 확보된다면 문제되지 않습니다.) 하지만, 동작하지도 않는 프로그래밍은 테스트를 하기도 어려우며, 그 결과를 예측하기도 어렵습니다.

8. 책을 쓰듯이 코드를 작성하라.

프로그래머에게는 코드 자체가 문서이자, 작업 대상이어야 합니다. 코드를 작성하는데 매번 만족할 만한 수준까지 작업하기는 힘들지만, 코드를 책을 쓰듯이 작성해야 합니다. 책을 쓴다는 것은 자신이 읽기 위함이 아닌, 다른 사람이 본다는 생각을 할 필요가 있습니다. 다른 사람이 자신이 만든 코드를 보고 이해하기 쉽게 짜임새 있게 구성되어야 하며, 각 부분들의 조각들이 맞추어져서 전체가 하나의 새로운 구성체로 조합되어야 합니다. 책을 쓴다는 것은 작성자의 signature를 포함한 내용들이 그 안에 있어야 하며, 코드에서 만큼은 본인이 구성한 의도가 충분히 포함되어야 합니다.

잘 짜여진 코드는 그 내용이 기승전결과 같은 일관된 구성으로 이루어지며, 심지어 표지나 서문과 같은 내용까지도 생각하여 다양한 데코레이션들을 코드 내에 삽입할 수 있습니다. 무엇보다 책 내용이 중요하듯이 그리고, 그 책의 구성 또한 소홀히 할 수 없듯이 코드는 그 내용을 중심으로 한권의 책을 보는 듯한 인상을 주어야 합니다.

9. 프로그램 내용을 시각적으로 표현해보라.

아무리 단순한 프로그램이라고 하더라도 최소한 몇개의 레이어나 시스템을 거쳐서 비즈니스 로직을 수행하기 때문에 전체적인 윤곽을 그려보는 것이 필요합니다. 또한 프로그램을 담고 있는 각 객체간의 관계가 어떻게 이루어지고, 무슨 작업을 수행할 때 필요한지는 파악해야 합니다. 이러한 모습들은 코드의 형태보다는 간단한 시각적인 표현 방식을 사용해서 파악하는 것이 필요합니다. 때로는 프로그램적으로 해결하기 어려운 부분들이 전체적인 구조를 파악하면 쉽게 해결되는 부분들도 있습니다.

즉, 자신이 만든 프로그램도 중요하지만, 남이 만든 프로그램 역시 전체적으로 어떠한 관계를 맺는지를 파악하는게 중요합니다. 자신이 만든 프로그램이 어떠한 용도로 사용되며, 어떠한 문제들을 일으키게 되는지도 사전에 파악하여 조치를 할 수 있어야 하며, 남이 만든 프로그램을 사용할 때 어떠한 부수 효과(side effect)가 발생할지에 대해서 알아야 합니다.

프로젝트를 혼자 모든 것을 처리하지 않는 이상, 다른 이가 만든 프로그램에 대한 영향, 내가 만든 프로그램에 대한 영향을 파악하는 시각을 키울 필요가 있습니다. 프로그램 자체가 단독으로 실행하는 것보다 서로 다른 사람들이 만들어서 같이 동작하게 만들어서 작업을 하기 때문에 상당한 노력을 필요로 하며, 이는 그리 단순하고 손쉬운 작업이 결코 아니라는 것을 인지할 필요가 있습니다.

이를 위해서는 자신이 만든 프로그램이라도 시각적으로 표현하고 이를 이해할 수 있어야 합니다.

9+1. 항상 원칙을 지키도록 노력하라.

프로젝트 현장에서는 다양한 기술과 노하우들이 펼쳐지고 난무하는 곳입니다. 이곳에서의 기술과 노하우들은 그 근본을 알 수 있는 것들도 있지만, 그렇지 못한 것들도 많이 있습니다. 원칙, 원리, 이론 등은 현장에서의 이러한 적용의 원리에 의해서 마치 구시대적이거나 학구적인 것으로 대접을 받아 상당한 무시와 천대를 받는 경우도 많습니다. 무엇이 되었든 간에 원칙은 반드시 존재해야 하며, 그러한 원칙을 기반으로 다양한 적용 원리가 나타날 수 있다는 것을 잊지 마시기 바랍니다.

원칙이라는 것이 거창하거나 복잡한 내용이 아니지만, 이를 이해하는 과정은 그리 쉬운 작업이 아닙니다. 하지만 원칙이 없는 프로그램 코드는 마치 모래 위에 성을 쌓는 것과 같습니다. 늘 환경에 의해서 흔들리고 다시 지어야하는 경우가 발생됩니다. 사소한 원칙이라도 무시하지 마시고, 그 원칙이 왜 생겨났는지를 곰곰히 생각하여 반드시 프로그래밍으로 표현할 때 같이 이해할 수 있어야 합니다.


위와 같은 내용은 어찌보면 엉뚱한 이야기인 것 같기도 하지만, 대부분이 현장에서 초보 프로그래머들과 접하면서 꼭 해주고 싶었던 이야기들입니다. 프로젝트 현장은 이와 같은 내용들을 세세하게 설명해주고 가르쳐줄 시간이 턱없이 부족하며, 똑같은 실수들을 후배들이 저지르는 것을 보는 것이 안타까울 따름입니다. 초보 시절의 습관은 경력이 쌓이더라도 쉽게 사라지지 않고 그 습관은 반드시 코드 상에 나타나게 되어 있습니다. 처음부터 힘들더라도 차근차근 실력을 쌓아가도록 노력하려는 자세가 필요합니다.

[출처: http://homo-ware.tistory.com/169]

'프로그래밍' 카테고리의 다른 글

아스키코드 표 (ASCII Code Chart)  (0) 2012.06.21
[자바] 소설같은 자바교재: 자북  (0) 2012.06.13
[자바] JAVA 강의 노트  (0) 2012.06.13
Links  (0) 2011.10.16
알고리즘 사이트 Programming-challenges  (0) 2011.10.16

+ Recent posts