교착상태(Deadlock)

모든 프로세스들이 대기 중이고 프로그램이 진행을 할 수 없는 상태.

두 개 이상의 작업이 서로 작업이 끝나기만을 기다리고 있어서, 결과적으로 어떤 일도 완료하지 못하게 되는 것을 말한다.

병행성(concurrency)

프로그램에 있는 연산들이 병렬적으로 실행될 수 있으면 연산들이 병행적이라고 함. 병렬성의 가능성을 말함. <-> 순차적

상호배제(Mutual exclusion)

공유변수를 액세스하고 있는 하나의 프로세스 이외에 다른 모든 프로세스들이 공유변수를 액세스하지 모하도록 제어하는 기법.

각 프로세스들이 변수를 '읽기'만 할 때에는 문제가 없다. 하지만 '쓰기'를 하려고 할 때 문제가 발생한다. 따라서 이런 경우 서로 동시에 액세스 하지 못하도록 하는 것이 상호배제이다.

임계구역(Critical Sections, Critical Region)

어떤 프로세스가 공유데이터를 액세스하고 있을 때 그 프로세스는 임계구역에 있다고 한다. 상호배제를 위해서 한 프로세스가 임계구역에 있으면 다른 프로세스가 이에 접근하지 못하도록 해야 할 것이다.

성공과 실패를 결정하는 1%의 객체 지향 원리(Akira Hirasawa 저, 이길섭, 신동완 역, 성안당)를 바탕으로 기억해두고 싶은 내용 정리한 것임.


XP(eXtreme Programming) ? (위키)


1. XP ?

애자일 개발 프로세스가 불리는 개발 방법 중의 대표적인 방법으로 10~12개 정도의 구체적인 실천 방법을 정의한다.

비교적 적은 규모의 인원의 개발 프로젝트에 적용하기 좋으며, 개발 문서 보다는 소스코드를, 조직적인 개발의 움직임 보다는 개개인의 책임과 용기에 중점을 두는 경향이 크다. - 위키

형식적인 작업 순서와 문서 형식의 산출물을 정의하고 있지 않은 대신 기본 이념인 '4가지 가치'와, xp를 실천하기 위한 작업 항목인 '12가지 실천 항목'을 정의한다.


2. 4가지 가치

2-1. 의사 소통(Communication)

팀의 맴버와 고객과의 의사 소통을 중시한다.

2-2. 단순성(Simplicity)

설계에 얽매이지 않고, 최소한의 필요와 단순함을 지키는 것을 중시하며 변경할 필요가 있으면 언제든지 기존 프로그램의 내부 구조를 개선하는 리팩토링(refactoring)을 행한다.

2-3. 피드백(Feedback)

완성한 프로그램은 바로 실행시켜 테스트를 하고, 그 결과를 피드백해서 개선한다.

2-4. 용기(Courage)

필요한 경우에는 용기를 가지고 설계를 변경한다.


3. 12가지 실천 항목

계획 게임

작은 릴리즈

메타파

단순한 디자인

테스팅

리팩토링

페어 프로그래밍

공동 소유권

계속적인 통합

주 40시간 노동

온 사이트 고객

코딩 표준



ic_launcher(icon) size

사진 출처(링크)


drawable-hdpi 72 * 72
drawable-ldpi 32 * 32
drawable-mdpi 48 * 48
drawable-xhdpi 96 * 96
drawable-xxhdpi 144 * 144


 실행환경

 Notebook

 SAMSUNG NT550p5c-s61r

 CPU

 Intel Core i5-3210M 2.50GHz

 Memory

 8 GB

 OS

 Window 7 ultimate 64bit

 Java

 1.8.0_05

 Android SDK : 4.4.2 (KitKat) / 테스트기기 : Galaxy S3 4.3 (Jelly Bean)

 WebServer

 Apache Tomcat 7.0

앱 등록이 업로드 실패 - 이미 버전 코드가 1인 APK가 있으므로 다른 버전 코드를 사용해야 합니다.


Version code 는 1이 아닌 값(2, 3, 4, 5, ...)로 바꾼다.

 실행환경

 Notebook

 SAMSUNG NT550p5c-s61r

 CPU

 Intel Core i5-3210M 2.50GHz

 Memory

 8 GB

 OS

 Window 7 ultimate 64bit

 Java

 1.8.0_05

 Android SDK : 4.4.2 (KitKat) / 테스트기기 : Galaxy S3 4.3 (Jelly Bean)

 WebServer

 Apache Tomcat 7.0

ImageButton Background 투명하게 만들기

위 사진과 같이 #00000000 로 변경한다.

성공과 실패를 결정하는 1%의 객체 지향 원리(Akira Hirasawa 저, 이길섭, 신동완 역, 성안당)를 바탕으로 기억해두고 싶은 내용 정리한 것임.


RUP(Rational Unitied Process) ? (위키)


1. RUP ?

미국의 UML을 처음으로 제창하고, 표준화에 커다란 역할을 한 Rational사(社)가 개발에서 판매하고 있는 상용 개발 프로세스이다. (Rational사는 2003년에 IBM사에 합병되었지만, 제품의 브랜드는 아직도 그대로 사용되고 있다.)

2. 특징

2-1. 반복형 개발을 전제로 프로젝트 계획 전체를 4가지 단계로 분할하는 지침을 제공한다.

1) 개념화(Inception) 단계

시스템의 전체적인 모습을 정의한다.

2) 구체화(Elaboration) 단계

적용 기술을 평가하고, 어플리케이션 기본 구조를 만들기 위해 일부 중요한 기능을 한정하여 실제로 어플리케이션을 만든다.

3) 구축(Construction) 단계

어플리케이션 기능의 전체를 개발한다. 어플리케이션 기능의 우선 순위가 높은 순으로 단계적으로 개발하는 것을 장려한다.

4) 전이(Transition) 단계

실제 운용을 위해 필요한 작업(종합 테스트, 성능 개선, 운용 교육 등)을 실행한다.


사진 출처(링크)


2-2. 커스터마이징을 전제로 하고 있다.

RUP가 정의하는 작업 항목과 산출물은 의무가 아닌 선택 사항이며, 프로젝트의 설징과 상황에 따라 필요한 것을 선택해서 이용하는 것을 전제로 한다.


개발 프로세스(Development Process)


java.io.RandomAcessFile

RandomAcessFile는 Object 클래스의 한단계 하위 클래스로 파일의 읽기, 쓰기가 가능하다.

파일시스템에 바이트로 저장된 큰 배열에 접근하는 방법으로 순차적으로 접근하는 방법이 아니라 파일 포인터를 이용해 임의의 위치(사용자가 선택한 인덱스)를 바로 읽을 수 있는 클래스이다.


Constructor:생성자

1. RandomAccessFile(File file, String mode)

2. RandomAccessFile(String name, String mode)

* mode

"r" -> 읽기전용

"rw" -> 읽고 쓰기 가능

"rws" ->

성공과 실패를 결정하는 1%의 객체 지향 원리(Akira Hirasawa 저, 이길섭, 신동완 역, 성안당)를 바탕으로 기억해두고 싶은 내용 정리한 것임.


폭포수형 개발 프로세스(waterfall development process)

1. 폭포수형?

작업의 순환을 회피하고, 물의 흐름처럼 유유하게 진행하는 것을 목표로 하는 방법.

기본적으로 '소프트웨어의 변경에는 많은 비용이 든다.'라는 것과 '소프트웨어보다도 문서를 만드는 비용이 훨씬 적게 든다.'라는 것을 전제로 함

2. 한계

2-1. 요구의 문제

요구 사양을 정하는 사람이 업무 전체를 정확히 이해하고 있다고 할 수 없으며, 의견이 다른 경우와 편견이 원인이 되어 모순된 사양을 결정하는 경우가 있다. 

더욱이 외부 요인에 의해 시스템의 전제 조건과 목표가 바뀌는 경우도 있어, 처음 단계에서 아무리 심사 숙고해서 정의했다 하더라도 나중에 여기저기서 변경 요소가 발생하는 것이 일반적이다.

2-2. 기술의 문제

신기술과 신제품의 적절한 이용 방법과 성능 면의 문제는 실제 프로그램을 작성해서 움직이는 단계에서 알되게는데 폭포수형 개발 프로세스의 경우 이러한 문제는 늦게 인식하게 된다. 그리고 그 단계에서 커다란 문제가 발생하면 프로젝트의 계획 전체가 막대한 영향을 받게 된다.

사진 출처 (링크)


반복형 개발 프로세스(iteration develop process)


1. 반복형?

요구 정의, 설계 프로그래밍, 테스트의 일련 작업을 '반복'을 여러 번 실시하는 것을 기본으로 한다.


2. 요구와 기술의 2가지 문제에 대처

2-1. 요구의 문제

처음에 모든 요구 사양을 확정하는 것이 아니라 단계적으로 소프트웨어를 만들어 가면서 몇 번이고 중간 버전을 만들어, 그대마다 사용자로부터 피드백(요구)을 구함.

2-2. 기술의 문제

문제를 초기에 확인하기 위해서 프로젝트의 초기 단계에서 실제 어플리케이션의 일부를 만들어 가동시켜 확인하므로, 커다란 문제라 할지라도 초기에 발견하면 시간의 여유가 있대 때문에 적절한 대책을 수립하기 쉽다.


사진 출처(링크)


3. 대표적인 반복형 개발 프로세스

RUP(Rational Unigied Process), XP(eXtreme Programming)

3-1. 객체 지향 개발 방법론 : RUP(Rational Unified Process)

3-2. 객체 지향 개발 방법론 : XP(eXtreme Programming)



무료 git 사이트


Bitbucket


1. GitHub와 달리 비공개 프로젝트가 가능하다.

 실행환경

 Notebook

 SAMSUNG NT550p5c-s61r

 CPU

 Intel Core i5-3210M 2.50GHz

 Memory

 8 GB

 OS

 Window 7 ultimate 64bit

 Java

 1.7.0_51

 Android SDK : 4.4.2 (KitKat) / 테스트기기 : Galaxy S3 4.3(Jelly Bean)

 WebServer

 Apache Tomcat 7.0


문제점

안드로이드 설치나 업데이트중 SDK 버튼이 보이지 않을 때


해결방안


1. Window - Customize Perspective


2. Command Groups Availability 에서 Android SDK and AVD Manager 를 선택한다.


전기 요금 계산기

package report;

import java.util.Scanner;

public class Elec {

	// electric charge table
	// 2013.11.21
	final static float v1 = 60.7f;
	final static float v2 = 125.9f;
	final static float v3 = 187.9f;
	final static float v4 = 280.6f;
	final static float v5 = 417.7f;
	final static float v6 = 709.5f;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);

		int kwh;
		int tmpCharge;
		int vat; // value added tax
		float eCharge = 0; // energy charge
		int bCharge = 0; // basic charge
		int eBaseFund = 0; // Electric Power Industry Base Fund
		int mcr = 0; // monthly customer requisition

		System.out.print("input kwh : ");
		kwh = sc.nextInt();

		int temp;

		// basic charge
		if (0 < kwh && kwh <= 100) {
			bCharge = 410;
		} else if (100 < kwh && kwh <= 200) {
			bCharge = 910;
		} else if (200 < kwh && kwh <= 300) {
			bCharge = 1600;
		} else if (300 < kwh && kwh <= 400) {
			bCharge = 3850;
		} else if (400 < kwh && kwh <= 500) {
			bCharge = 7300;
		} else {
			bCharge = 12940;
		}

		// energy charge
		temp = kwh;
		if (temp >= 100) {
			eCharge += (float) (100 * v1);
			temp = temp - 100;
			if (temp >= 100) {
				eCharge += (float) (100 * v2);
				temp = temp - 100;
				if (temp >= 100) {
					eCharge += (float) (100 * v3);
					temp = temp - 100;
					if (temp >= 100) {
						eCharge += (float) (100 * v4);
						temp = temp - 100;
						if (temp >= 100) {
							eCharge += (float) (100 * v5);
							temp = temp - 100;
							if (temp >= 0) {
								eCharge += (float) (temp * v6);
							} else {
								eCharge += (float) (temp * v6);
							}
						} else {
							eCharge += (float) (temp * v5);
						}
					} else {
						eCharge += (float) (temp * v4);
					}
				} else {
					eCharge += (float) (temp * v3);
				}
			} else {
				eCharge += (float) (temp * v2);
			}
		} else {
			eCharge += (float) (temp * v1);
		}

		tmpCharge = (int) (bCharge + eCharge);
		vat = (int) Math.round(tmpCharge * 0.1);
		eBaseFund = (int) ((tmpCharge * 0.037) / 10 * 10);
		mcr = (int) (eCharge + bCharge + vat + eBaseFund) / 10 * 10;

//		System.out.println("basic " + bCharge);
//		System.out.println("tax " + eCharge);
//		System.out.println("total " + tmpCharge);
//		System.out.println("vat " + vat);
//		System.out.println("eBaseFund " + eBaseFund);

		System.out.println("output : " + mcr);
	}
}

 실행환경

 Notebook

 SAMSUNG NT550p5c-s61r

 CPU

 Intel Core i5-3210M 2.50GHz

 Memory

 8 GB

 OS

 Window 7 ultimate 64bit

 Java

 1.7.0_51

 Android SDK : 4.4.2 (KitKat) / 테스트기기 : Galaxy S3 4.3 (Jelly Bean)

 WebServer

 Apache Tomcat 7.0


TabHost

여러 탭을 두고 각 탭을 클릭할 때마다 해당 화면이 나오도록 설정하는 뷰 컨테이너.

예제 결과

XML code

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TabHost
        android:id="@android:id/tabhost"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical" >

            <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1" >

                <LinearLayout
                    android:id="@+id/tab1"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="#00ff00"
                    android:orientation="vertical" >

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="1" />
                </LinearLayout>

                <LinearLayout
                    android:id="@+id/tab2"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="#0000ff"
                    android:orientation="vertical" >

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="2" />
                </LinearLayout>

                <LinearLayout
                    android:id="@+id/tab3"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="#ff0000"
                    android:orientation="vertical" >

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="3" />
                </LinearLayout>
            </FrameLayout>

            <TabWidget
                android:id="@android:id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" >
            </TabWidget>
        </LinearLayout>
    </TabHost>

</LinearLayout>

java code

package com.android_report;

import android.app.TabActivity;
import android.os.Bundle;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;

public class MainActivity extends TabActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		TabHost tabHost = getTabHost();

		TabSpec tabSpecTab1 = tabHost.newTabSpec("TAB1").setIndicator("강아지");
		tabSpecTab1.setContent(R.id.tab1);
		tabHost.addTab(tabSpecTab1);

		TabSpec tabSpecTab2 = tabHost.newTabSpec("TAB2").setIndicator("고양이");
		tabSpecTab2.setContent(R.id.tab2);
		tabHost.addTab(tabSpecTab2);

		TabSpec tabSpecTab3 = tabHost.newTabSpec("TAB3").setIndicator("토끼");
		tabSpecTab3.setContent(R.id.tab3);
		tabHost.addTab(tabSpecTab3);

		TabSpec tabSpecTab4 = tabHost.newTabSpec("TAB4").setIndicator("말");
		tabSpecTab4.setContent(R.id.tab1);
		tabHost.addTab(tabSpecTab4);
		
		tabHost.setCurrentTab(0);

	}
}


파일구조 파일 병합/정렬










파일구조_병합단계.pdf


 실행환경

 Desktop

 조립식

 CPU

 Intel(R) Core(TM) i7-3770 3.50GHz

 Memory

 4 GB

 OS

 Window 7 Professional 32bit

 Java

 1.7.0_51

 Android

 SDK : 4.4.2 (KitKat) / 테스트기기 : Galaxy S3 4.3(Jelly Bean)

 WebServer

 Apache Tomcat 7.0

 DB

 MySQL 5.6.15


문제점

현재 클래스의 Activity, Context를 가져오는 방법


해결방안

Activity mActivity;
mActivity = 현재클래스.this;
Context mContext;
mContext = getApplicationContext();

 실행환경

 Notebook

 SAMSUNG NT550p5c-s61r

 CPU

 Intel Core i5-3210M 2.50GHz

 Memory

 8 GB

 OS

 Window 7 ultimate 64bit

 Java

 1.7.0_51

 Android SDK : 4.4.2 (KitKat) / 테스트기기 : Galaxy S3 4.3 (Jelly Bean)

 WebServer

 Apache Tomcat 7.0


코드 실행시간 확인하기

조금 더 정확한 측정 방법

public class TimerTest {
	public static void main(String[] args) {

		ExecTime timer = new ExecTime();
		timer.start();

		// code
		for (int i = 0; i < 100000000; i++) {

		}
		timer.stop();

		timer.printExecTime();
		System.out.println(timer.getRunTimeNano() / 1000000 + " ms");
		System.out.println(timer.getRunTimeNano() / 1000000 / 1000 + " sec");
	}

}

class ExecTime {
	private long start;
	private long stop;

	void start() {
		start = System.nanoTime();
	}

	void stop() {
		stop = System.nanoTime();
	}

	long getRunTimeNano() {
		return stop - start;
	}

	void printExecTime() {
		System.out.println(stop - start + " ns");
	}
}

방법1

class TimeTest1 {
	public static void main(String[] args) {

		long startTime = System.currentTimeMillis();

		// code

		long stopTime = System.currentTimeMillis();
		long runTime = stopTime - startTime;

		System.out.println(runTime);
	}
}

방법 2

public class Stopwatch {
	long start;
	long end;
	
	void start() {
		start = System.currentTimeMillis();
	}
	
	void stop() {
		end = System.currentTimeMillis();
	}
	
	String getRunTime(){
		return end - start + "";
	}
}
class TimeTest2 {
	public static void main(String[] args) {

		Stopwatch timer = new Stopwatch().start();

		// code

		timer.stop();

		System.out.println(timer.getRunTime());
	}
}

'대학 생활 > JAVA' 카테고리의 다른 글

[JAVA] java.io.RandomAccessFile() (작성중)  (0) 2014.05.27
[JAVA] 전기 요금 계산  (0) 2014.05.14
[JAVA] 연산자 우선순위  (0) 2014.05.02
[JAVA] 파일 읽기, 쓰기  (0) 2014.04.16

 JAVA 연산자 우선순위

  1. (), [], .
  2. !, ~, ++, --, +, -, instanceof
  3. new, (type name)
  4. *, /, %
  5. +, -
  6. <<, >>< >>>
  7. <, <=, >, >=
  8. ==, !=
  9. &, ^, |
  10. &&, ||
  11. ?:
  12. =, +=, -=, *=, /=, %/, >>=, >>>=, <<=, &=, ^=, |=


C 연산자 우선순위

  1. 1차 연산자 : (), [], ->, .
  2. 단항 연산자 : !, ~, ++, --, +, -, (type), *, &, sizeof
  3. 곱셈, 나눗셈 : *, /, %
  4. 덧셈, 뺄셈 : +, -
  5. 쉬프트 연산자 : <<, >>
  6. 관계 연산자 : <, <=, >, >=
  7. 등가 연산자 : ==, !=
  8. 비트 연산자 : &, |
  9. 논리 연산자 : &&, ||
  10. 조건 연산자 : ?:
  11. 배정 연산자 : =, +=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |=
  12. 콤마 연산자 : ,


 실행환경

 Desktop

 조립식

 CPU

 Intel(R) Core(TM) i7-3770 3.50GHz

 Memory

 4 GB

 OS

 Window 7 Professional 32bit

 Java

 1.7.0_51

 Android

 SDK : 4.4.2 (KitKat) / 테스트기기 : Galaxy S3 4.3(Jelly Bean)

 WebServer

 Apache Tomcat 7.0

 DB

 MySQL 5.6.15


문제점

안드로이드에서 파일 출력을 하려는데 openFileOutput에서 에러가 발생했다.

"The method openFileOutput(String, int) is undefined for the type LocationData" 라고 정의되어 있지 않다고 한다.


해결방안

openFileOutput()는 Context 클래스에 있는 메서드인데 파일출력을 하는 클래스를 따로 만들었을땐 문제가 발생한다.

그러므로, 파일 출력 클래스에서 Context를 선언해주어야 한다.

(혹시 몰라 MainActivity에 있는 Context를 그대로 가져왔습니다. 문제 없다면 댓글 부탁바랍니다.)


MainActivity.java

...
Context mContext;
mContext =  getApplicationContext();
data.textFileSave(mContext);
...

LocationData.java(파일출력 클래스)

...
public void textFileSave(Context cont) {
FileOutputStream fos = null;
	try {
		// 기본 파일 저장
		fos = cont.openFileOutput("test.txt", Context.MODE_APPEND);
		for.write(toString().getBytes());
		...
	} catch (Exception e) {}
}
...


읽기 좋은 코드가 좋은 코드다(더스팀 보즈웰, 트레버 파우커 지음, 임백준 옮김) 를 읽고 

자주 참고하면서 습관화하려는 부분을 정리해 놓은 것으로 좀 더 자세한 내용은 책을 보기 바랍니다.


point. 좋은 소스코드는 '눈을 편하게' 해야 한다.

  • 읽기 편한 소스코드를 작성하는 세 가지 원리
    • 코드를 읽는 사람이 이미 친숙한, 일관성 있는 레이아웃을 사용하라.
    • 비슷한 코드는 서로 비슷해 보이게 만들어라.
    • 서로 연관된 코드는 하나의 블록으로 묶어라.

일관성과 간결성을 위해서 줄 바꿈을 재정렬하기

before

public class PerformanceTester {
    public static final TcpConnectionSimulator wifi = new TcpConnectionSimulator(
        500, // Kbps
        80, // millisecs 대기시간
        200, // 흔들림 
        1 //  패킷 손실  
    );

    public static final TcpConnectionSimulator t3_fiber =
        new TcpConnectionSimulator(
            500, // Kbps
            80, // millisecs 대기시간
            200, // 흔들림
            1 // 패킷 손실 
    );

    public static final TcpConnectionSimulator wifi = new TcpConnectionSimulator(
        500, // Kbps
        80, // millisecs 대기시간
        200, // 흔들림
        1 // 패킷 손실
    );
}
after

public class PerformanceTester {
    public static final TcpConnectionSimulator wifi = 
      new TcpConnectionSimulator(
        500, // Kbps
        80, // millisecs 대기시간
        200, // 흔들림
        1 // 패킷 손실
    );

    public static final TcpConnectionSimulator t3_fiber =
      new TcpConnectionSimulator(
        500, // Kbps
        80, // millisecs 대기시간
        200, // 흔들림
        1 // 패킷 손실 
    );

    public static final TcpConnectionSimulator wifi = 
      new TcpConnectionSimulator(
        500, // Kbps
        80, // millisecs 대기시간
        200, // 흔들림
        1 // 패킷 손실
    );
}
public class PerfoemanceTester {
    //     TcpConnectionSimulator (처리량,   지연속도,  흔들림,  패킷 손실)
    //                             [Kbps]      [ms]      [ms]    [percent]

    public static final TcpConnectionSimulator wifi = 
        new TcpConnectionSimulator(500,         80,           20,           1);

    public static final TcpConnectionSimulator t3_fiber = 
        new TcpConnectionSimulator(45000,       0,            0,           0);

    public static final TcpConnectionSimulator cell = 
        new TcpConnectionSimulator(100,        400,          250,           5);


메소드를 활용하여 불규칙성을 정리하라

before

DatabaseConnection database_connection;
string error
assert(ExpandFullName(database_connection, "Donug Adams", &error)
    == "Mr, Douglas Adms");
assert(error == "");
assert(ExpandFullName(database_connection, "Jake Brown", &error)
    == "Mr, Jacob Brown III");
assert(error == "");
assert(ExpandFullName(database_connection, "No Such Guy", &error) == "");
assert(error == "no match found");
assert(ExpandFullName(database_connection, "John", &error) == "");
assert(error == "more than one result");

afrer

  • 중복된 코드를 없애서 코드를 더 간결하게 한다.
  • 이름이나 에러 문자열 같은 테스트의 중요 부분들이 한 눈에 보이게 모아졌다. 수정 전에는 database_connection이나 error 같은 토큰들과 섞인 채 흩어져 있었기 때문에 코드를 한 눈에 파악하기 어려웠다.
  • 새로운 테스트 추가가 훨씬 쉬워졌다.
void CheckFullNAme(string partial_name,
                    string expected_full_name,
                    string expected_error) {
    // database_connection은 이제 클래스 맴버이다.
    string error;
    string full_name = ExpandFullName(database_connection, partial_name, &error);
    assert(error == expected_error);
    assert(full_name == expected_full_name);
}

CheckFullName("Doug Adams", "Mr. Douglas Adams", "");
CheckFullName("Jake Brown", "Mr. Jake Brown III", "");
CheckFullName("No Such Guy", "", "no match found");
CheckFullName("John", "", "more than one result");


도움이 된다면 코드의 열을 맞춰라

after

details  = request.POST.get('details');
location = request.POST.get('location');
phone    = request.POST.get('phone');
email    = request.POST.get('email');
url      = request.POST.get('url');


의미 있는 순서를 선택하고 일관성 있게 사용하라

  • 변수의 순서를 HTML 폼에 있는 <input> 필드의 순서대로 나열하라.
  • '가장 중요한 것'에서 시작해서 '가장 덜 중요한 것'까지 순서대로 나열하라.
  • 알파벳 순서대로 나열하라.

선언문을 블록으로 구성하라

before

class FrontendServer {
	public:
		FrontendServer();
		void ViewProfile(HttpRequest* request);
		void OpenDatabase(string location, string user);
		void SaveProfile(HttpRequest* request);
		string ExtractQueryParam(HttpRequest* request, string param);
		void ReplyOK(HttpRequest* request, string html);
		void closeDatabase(string location);
}

after

class FrontendServer {
	public:
		FrontendServer();
		~FrontendServer();

		// 핸들러들
		void ViewProfile(HttpRequest* request);
		void SaveProfile(HttpRequest* request);

		// 질의/응답 유틸리티
		string ExtractQueryParam(HttpRequest* request, string param);
		void ReplyOK(HttpRequest* request, string html);

		// 데이터베이스 헬퍼들
		void OpenDatabase(string location, string user);
		void closeDatabase(string location);

}

코드를 '문단'으로 쪼개라

  • 비슷한 생각을 하나로 묶어서, 성격이 다른 생각과 구분한다.
  • 문단은 '시각점 디딤돌'역할을 수행한다. 문단이 없으면 하나의 페이지 안에서 읽던 부분을 놓치기 쉽다.
  • 하나의 문단에서 다른 문단으로의 전진을 촉진시킨다.

after

def suggest_new_friends(user, email_password):
	# 사용자 친구들의 이메일 주소를 읽는다.
	friends = user.friends()
	friend_emails = set(f.email for f in friends)

	# 이 사용자의 이메일 계정으로부터 모든 이메일 주소를 읽어들인다.
	contacts = import_contacts(user.email, email_password)
	contact_emails = set(c.email for c in contacts)

	# 아직 친구가 아닌 사용자들을 찾는다.
	non_friend_emails = contact_emails - friend_emails
	suggested_friends = User.objects.select(email_in=non_friend_emails)

	...

	return render("suggested_friends.html", display)



  • 일관성 있는 스타일은 '올바른' 스타일보다 더 중요하다.


Visual studio 코드 자동 정렬

Ctrl + K + F or Alt + F8

'대학 생활 > C' 카테고리의 다른 글

[C] 유닉스의 open()를 대신하는 메서드  (0) 2014.10.09
[C] 연산자 우선순위  (0) 2014.05.02
[C] error C4996: 'fopen': This function ... 에러  (2) 2014.03.12
[C++]ifstream 클래스  (0) 2013.10.31

 실행환경

 Desktop

 조립식

 CPU

 Intel(R) Core(TM) i7-3770 3.50GHz

 Memory

 4 GB

 OS

 Window 7 Professional 32bit

 Java

 1.7.0_51

 WebServer

 Apache Tomcat 7.0

 DB

 MySQL 5.6.15


직렬화하지 않은 파일 읽기, 쓰기 

- API : FileReader, BufferedReader, FileWriter, BufferedWriter

읽기, 쓰기작업을 처리하는 FileReader, FileWriter에 효율을 향상시켜주는 BufferedReader, BufferedWriter 클래스를 연쇄시켜 사용한다. 버퍼는 자신이 가득 찰 때까지 기다리다가 꽉찬 후에 작업이 진행한다.


[JAVA] java.io.File 클래스


쓰는 방법(출력)

BufferedWriter w = new BufferedWriter(new FileWriter(new File("FileTest.txt")));

버퍼가 가득차기전에 데이터를 보내고자 한다면 writer.flush() 호출한다.


읽는 방법(입력)

읽기작업은 while()문에서 한번에 한 행씩 읽어오며, readLine()에서 null을 리턴하면 반복문을 종료한다.

가장 흔하게 쓰이는 방법

import java.io.*;

public class FileTest {
	public static void main(String[] args) {
		String fDir = "TestDir/";
		String fName1 = "FileTest.txt";
		File f;

		try {
			// File 객체 생성(존재하는 파일)
			f = new File(fDir + fName1);

			// 파일 쓰기(주석부분은 간략화)
			FileWriter fileWriter = new FileWriter(f);
			BufferedWriter writer = new BufferedWriter(fileWriter);
			//BufferedWriter writer = new BufferedWriter(new FileWriter(f));

			writer.write("witerTest1");
			writer.append("\n"); // 개행문자 삽입
			writer.append("witerTest2");
			writer.newLine(); // 개행 메서드
			writer.write("witerTest3");
			writer.close(); // 파일 닫기

			// 파일 읽기
			FileReader fileReader = new FileReader(f);
			BufferedReader reader = new BufferedReader(fileReader);

			String line = null;
			while ((line = reader.readLine()) != null) {
				System.out.println(line);
			}
			reader.close(); // 파일 닫기
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}

	}
}



직렬화된 객체의 파일 입출력

- API : ObjectOutputStream, ObjectInputStream, FileOutputStream, FileInputStream

사진. 구글 검색(Head First Java)


직렬화할 객체

Serializable 인터페이스를 꼭 구현해야한다.

class TestSerialization implements Serializable {
	private int x;
	private String str;

	TestSerialization(int a) { this.x = a; }
	TestSerialization(String s) { this.str = s;	}

	int getA() { return x; }
	String getS() {	return str;	}
}

파일 저장하기(출력)

public class FileTest {
	public static void main(String[] args) {
		String fDir = "TestDir/";
		String fName = "FileTest.ser";

		FileOutputStream fileStream;
		ObjectOutputStream objStream = null;

		// 저장할 객체
		TestSerialization test1 = new TestSerialization("ObjectTest1");
		TestSerialization test2 = new TestSerialization(100);
		TestSerialization test3 = new TestSerialization("ObjectTest3");

		try {
			// 파일에 연결하기위해 생성, 파일명의 파일이 없으면 새로 만들어줌.
			fileStream = new FileOutputStream(fDir + fName);
			objStream = new ObjectOutputStream(fileStream);

			// 출력되는 객체는 반드시 Serialization 인터페이스 구현
			objStream.writeObject(test1);
			objStream.writeObject(test2);
			objStream.writeObject(test3);
			
			System.out.println("end");

		} catch (Exception ex) {
			System.err.println("Exception : " + ex.getMessage());
		} finally {
			try {
				objStream.close();
			} catch (IOException e) {
				System.out.println(e.getMessage());
			}
		}
	}
}

파일 불러오기(입력) : 역직렬화(객체 복구)

public class FileTest {
	public static void main(String[] args) {
		String fDir = "TestDir/";
		String fName = "FileTest.ser";

		FileInputStream fileStream;
		ObjectInputStream objStream = null;
		
		try {
			// 역직렬화할 파일을 불러온다.
			fileStream = new FileInputStream(fDir + fName);
			objStream = new ObjectInputStream(fileStream);

			// 처음에 저장된 순서대로 가져온다.
			Object one = objStream.readObject();
			Object two = objStream.readObject();
			Object three = objStream.readObject();
			
			// 역직렬화할 객체
			TestSerialization test1 = (TestSerialization) one;
			TestSerialization test2 = (TestSerialization) two;
			TestSerialization test3 = (TestSerialization) three;
			
		} catch (Exception ex) {
			System.err.println("Exception : " + ex.getMessage());
		} finally {
			try {
				objStream.close();
			} catch (IOException e) {
				System.out.println(e.getMessage());
			}
		}
	}
}



  • 3389 - mstsc(원격데스크톱)
    • 서버 관리자라면 보안 향상을 위해 다른 포트로 변경하는 것이 좋다.

0 ~ 1023 포트는 잘 알려진 포트(Well Known Ports)이고 1024 ~ 49151 포트는 등록된 포트(Registered Ports) 49152 ~ 65535 포트는 동적/개인적 포트(Dynamic and/or Private Ports)로 나뉘어 진다.


윈도우 사용중인 포트 확인하기

cmd -> netstat -ano


대부분의 포트 확인하기1, 2 


포트번호

TCP/UDP

서비스

설명

20

TCP

FTP

FTP 전송 포트

21

TCP

FTP

FTP 제어(명령) 포트

22

TCP

SSH

ssh scp, sftp 같은 프로토콜 및 포트 포워딩

23

TCP

Telnet

암호화되지 않은 텍스트 통신

25

TCP

SMTP

Simple Mail Transfer Protocol - 이메일 전송에 사용

37

TCP

TIME

37

UDP

TIME


42

TCP

NAME SERVER

호스트 네임 서버

49

UDP

TACACS

53

TCP

DNS

Domain Name System

53

UDP

DNS

67

UDP

DHCP

DHCP 서버

68

UDP

BOOTP

69

UDP

TFTP

Trivial File Transfer (인증없는 파일전송)

70

TCP

GOPHER

79

TCP

Finger

핑거

80

TCP

HTTP

World Wide Web HTTP

80

UDP

HTTP

World Wide web HTTP

88

TCP

Kerberos

kerberos 보안 규격

101

TCP

Host Name

NIC Host Name Server

107

TCP

rTelnet

Remote Telnet Service

109

TCP

POP2

Post Office Protocol version 2 - 전자우편 가져오기에 사용

110

TCP

POP3

Post Office Protocol version 3 - 메일 수신

113

TCP

ident

예전 서버 인증 시스템, 현재 IRC 서버에서 사용자 인증에 사용

119

TCP

NNTP

Network News Transfer Protocol - 뉴스 그룹 메시지 가져오기 사용

123

UDP

NTP

Network Time Protocol - 시간 동기화

137

TCP

NetBOIS-ns

 

138

TCP

NetBIOS-dgm

 

139

TCP

NetBIOS-ssn


143

TCP

IMAP4

인터넷 메시지 접근 프로토콜 4 - 이메일 가져오기에 사용

161

UDP

SNMP

Simple Network Management Protocol

177

TCP

XDMCP

원격 호스트 접속 포트

179

TCP

BGP

Border Gateway Protocol

194

TCP

IRC

Internet Relay Char

389

TCP

LDAP

Lightweight Directory Access Protocol

443

TCP

HTTPS

HTTP over SSL (암호화 전송)

445

TCP

Microsoft-DS

액티브 디렉터리, 윈도 공유, Sasser-worm, Agobot, Zobotworm

445

UDP

Microsoft-DS

SMB 파일 공유

465

TCP

514

UDP

syslog

시스템 로그 작성

515

TCP

LPD

프린터 스풀러

540

TCP

UUCP

Unix-to-Unix Copy Protocol

542

UDP

542

UDP

554

TCP

rtsp


587

TCP

SMTP

email message submission

593

TCP

RPC over HTTPS

Exchange Server

636

TCP

LDAPS

IDAP Protocol over TLS/SSL

666

TCP

873

TCP

rsync

파일 동기화 프로토콜

989

TCP

FTPS

FTP Protocol, Data, over TLS/SSL

993

TCP

IMAPS

IMAP4 Protocol over TLS/SSL

995

TCP

POP3S

POP3 Protocol over TLS/SSL

1521

TCP

Oracle

Oracle 

1935

TCP 

Wowza

동영상 스트리밍 서버

3306

TCP

MySQL

MySQL 서버

3389

TCP

TERMINAL

넷미팅 원격 데스크탑


참고1, 참고2, 참고3, 참고4



 실행환경

 Desktop

 조립식

 CPU

 Intel(R) Core(TM) i7-3770 3.50GHz

 Memory

 4 GB

 OS

 Window 7 Professional 32bit

 Java

 1.7.0_51

 WebServer

 Apache Tomcat 7.0

 DB

 MySQL 5.6.15


java.io.File 클래스 API

File 클래스는 파일의 내용을 수정하거나 입력하는 클래스가 아니라, 파일이나 디렉토리 자체를 담는 클래스이다.

즉, File 객체는 파일경로명이나 파일명과 비슷한 것으로 생각할 수 있다. 파일에 입력이나 수정을 하려면 File 객체를 FileWriter 또는 FileInputStream 등의 객체에 전달해서 그 객체에서 사용해야 한다.


import java.io.File;

public class FileTest {
	public static void main(String[] args) {
		// File 객체 생성(이미 존재하는 파일)
		File f = new File("FileTest.txt");
		
		// 현재 프로젝트 폴더내에 생성
		File dir = new File("FileTestDir");
		if(dir.mkdir()) {
			// 폴더가 존재하지 않다면
			System.out.println("true");
		} else {
			// 폴더가 존재한다면
			System.out.println("False");
		}
		
		// 파일 또는 디렉토리의 절대 경로명
		System.out.println(f.getAbsolutePath());
		System.out.println(dir.getAbsolutePath());
		
		// 파일 또는 디렉토리 삭제
		boolean deletedCheck = dir.delete();
		System.out.println(deletedCheck != false ? "삭제 성공" : "삭제 실패");
	}
}


'대학 생활 > JAVA' 카테고리의 다른 글

[JAVA] 연산자 우선순위  (0) 2014.05.02
[JAVA] 파일 읽기, 쓰기  (0) 2014.04.16
[JAVA]정적필드, 정적메소드  (0) 2014.03.18
[JAVA] String <-> int, double, float 변환  (0) 2014.02.28


문제점

'git clone' 명령어 실행시 에러 발생

fatal: could not read Username for 'http://github.com': No such file or directory



해결방안

황당한 문제이다. 대소문자를 구분하는 것.

주소는 작성하다가 opidHub를 opidhub로 작성했던 것이다.

앞으로 대소문자 구분을 확실히 해야겠다.


radioGroup 리스너 예제 - 2014.04.01

MainActivity.java
package com.example.project4_1_pet;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

	TextView tv1, tv2;
	CheckBox start_chkBox;
	RadioGroup rGroup;
	RadioButton rb1, rb2, rb3;
	ImageView imgView;
	Button btn, btnQuit, btnReturn;
	Switch switchBtn;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		setTitle("yeongjun");

		switchBtn = (Switch) findViewById(R.id.switchBtn);
		tv1 = (TextView) findViewById(R.id.tv1);
		tv2 = (TextView) findViewById(R.id.tv2);
		rGroup = (RadioGroup) findViewById(R.id.RGroup);
		rb1 = (RadioButton) findViewById(R.id.rb1);
		rb2 = (RadioButton) findViewById(R.id.rb2);
		rb3 = (RadioButton) findViewById(R.id.rb3);
		imgView = (ImageView) findViewById(R.id.imgView);
		btnQuit = (Button) findViewById(R.id.btnQuit);
		btnReturn = (Button) findViewById(R.id.btnReturn);

		switchBtn
				.setOnCheckedChangeListener(new Switch.OnCheckedChangeListener() {
					public void onCheckedChanged(CompoundButton cb,
							boolean isChecking) {
						if (isChecking) {
							Toast.makeText(getApplicationContext(),
									"isChecked", Toast.LENGTH_SHORT).show();
							tv2.setVisibility(1);
							rGroup.setVisibility(1);
							imgView.setVisibility(1);
						} else {
							Toast.makeText(getApplicationContext(),
									"isNotChecked", Toast.LENGTH_SHORT).show();

							tv2.setVisibility(4);
							rGroup.setVisibility(4);
							imgView.setVisibility(4);
						}

					}
				});

		rGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
			public void onCheckedChanged(RadioGroup group, int checkedId) {
				// TODO Auto-generated method stub
				switch (checkedId) {
				case R.id.rb1:
					imgView.setImageResource(R.drawable.dog);
					break;
				case R.id.rb2:
					imgView.setImageResource(R.drawable.cat);
					break;
				case R.id.rb3:
					imgView.setImageResource(R.drawable.rabbit);
					break;
				default:
					Toast.makeText(getApplicationContext(),
							"radio btn select plz", Toast.LENGTH_SHORT).show();
				}
			}
		});

		btnQuit.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				finish();
			}
		});

		btnReturn.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				tv2.setVisibility(4);
				rGroup.setVisibility(4);
				imgView.setVisibility(4);

				switchBtn.setChecked(false);
			}
		});
	}
}


main.xml


123456789

+ Recent posts