11월 292013
 

요즘 간단한 홈페이지를 만들고 있다. 어떻게 만들까 고민하다가, 새로운 기술을 배울 겸 node.js를 이용하여 구현해보았다. 최신버젼을 경험하는 것을 좋아하다 보니, 간단한 기능을 추가할 때 마다 에로사항이 꽃피고 있다.  기존에 나와 있는 node.js책에 있는 내용들의 일부분은 deflcated되어 사용될 수 없는 상황이 대부분이였다. connect의 미들웨어 router 등등. 비슷한 기능을 하는 것을 만들어서 해결할 수 있다고 하였지만 그냥 express framework를 사용하기로 하였다. 그런데 이 조차도 최신 버젼(>=3.0)에서 레이아웃이 작동되지 않는다는 것을 알게 되었다[1].

조사해 보았더니, 해결 방안은 jade의 기능을 이용하라는 것이였다.

아래는 index.jade이다.

extends layout
block title
    =title

block contents
    p Hello World@!@!@

아래는 레이아웃 역할을 하는 layout.jade이다.

!!!  5
html
    head
        title
            block title
        link(rel = 'stylesheet', href = '/css/bootstrap.min.css')
        link(rel = 'stylesheet', href = '/css/bootstrap.theme.min.css')
    body
        block contents

아래는 node.js를 통해 실행된 결과물이다.

		

Hello World@!@!@

요는 jade기능인 “extends”와 “block”을 쓰면 되는 것이다. index.jade에 extends layout 명령을 통해 layout.jade를 읽어 들이고 block 구분에 적혀져 있는 내용이 자동으로 치환되게 된다. 물론 extends <<파일명>> 형태로 사용하고, block <<레이블>> 형태로 맞춰주면 된다.

최근에 나온 프레임워크는 어떻게 튀어나갈지 몰라서 안정된 환경을 원할 경우에는 좋은 선택이 못되는 듯 하다.

[1] http://stackoverflow.com/questions/13783687/the-layout-jade-is-not-working-why

11월 072013
 

2013년 11월 07일 현재 기준..

1. 최신 우분투버젼을 설치하고 있다는 가정하에 redmine을 apt-get install redmine 등의 방법으로 mysql을 이용하도록 설치하면 에러가 발생
-> /etc/redmine/default/database.yml 에서 adapter: 항목에 mysql을 mysql2로 변경

2. 성공적으로 설정이 끝나서 로그인 하려고 하면 에러 발생
-> “ruby-rack”의 버젼문제임 아래와 같이 해결(1.5.2 버젼의 경우 에러 발생)

2.1. /usr/share/redmine/Gemfile 의 마지막 줄에 아래 내용 추가

gem 'rack', '1.4.5'

2.2 다음과 같은 명령을 실행하여 1.4.5버젼의 rack를 설치
-> gem install rack –version 1.4.5
2.3 아래 명령을 실행하여 업데이트
-> bundle update

참조 : http://charles.lescampeurs.org/2013/11/01/redmine-on-ubuntu-13-10-with-apache2-and-passenger

10월 302013
 

메버릭스에서 지도가 잘 나오지 않는다면 DNS 설정을 의심해 보는 것이 좋다. 일단 확인한 것으로는 구글의 DNS(예: 8.8.8.8, 4.4.4.4)로 설정되어 있으면 잘 되지 않는 다는 것이였다. 해결방법은 구글의 DNS가 아닌 통신회사(IDS)에서 제공해 주는 DNS서버를 이용하는 것만으로도 충분히 해결이 된다. DNS 설정 방법은 운영체제 별로 다르기 때문에 관련 사용 설명서를 참조하면 된다.

5월 302013
 

sar(System Activity Reporter)는 리눅스의 CPU 사용률, 메모리 사용률 따위의 정보를 알아내는대에 쓰이는 프로그램이다. 물론 모니터링에도 쓸 수 있다.

centos에서 이 프로그램은 ” yum install sysstat “를 통하여 설치할 수 있다.

사용법은 다음과 같다. /etc/cron.d/sysstat 에 등록된 정보에 따라서 로그를 지정된 파일에 저장시킨다.

처음 설치 후 실행을 위해서 ” service sysstat restart ” 명령을 통해 가능하다. ” chkconfig –add sysstat “를 통하여 재부팅 후에도 자동으로 실행되게 할 수 있다.

” sar -A -o <<파일명>>  <<반복|초>> <<반복횟수>> “을 통하여 파일에 로그를 저장한다. (-A는 모든 정보를 저장하는 옵션인데 자세한 것은 Oracle sar 설명[1]을 참조)

나중에 생성된 파일에서 정보를 다시 확인하는 방법은 ” sar -A -f <<파일명>> ” 을 통하여 가능하다.

 

[1] 시스템 작업 모니터링(sar) – Oracle(2013-05-30 01:56 KST 확인),  http://docs.oracle.com/cd/E24846_01/html/E23088/spmonitor-8.html

[2] http://www.welog.net/gbbs/bbs/board.php?bo_table=linux&wr_id=2

5월 252013
 

2TB 이상의 하드디스크를 이용하여 리눅스에서 기존의 방법(fdisk)을 통해 파티션을 생성할 경우 무조건 2TB로만 만들어 지는 문제가 있다.

2TB이상의 파티션을 만들기 위해 아래의 방법을 이용하면 된다.

parted /dev/sdb     (/dev/sdb 는 상황에 맞추어 바꿀 것)
mklabel gpt
unit TB
mkpart primary 0.00TB 4.00TB
print
quit

cap_1

* 경고(책임의 한계) : 이 작업을 통하여 어떠한 일이 발생하더라도 책임을 지지 않습니다. 작업의 결과는 이 작업을 수행한 본인에게 책임이 있습니다.

5월 212013
 

인터넷 영상 스트리밍 클라이언트를 웹에서 구현하기 위해서는 여러 가지 방법을 이용할 수 있다. 그 중에서 Flash를 이용하여 많이 구현을 한다. 그 이유는 대부분의 브라우져에서 Flash를 지원하며, 빠른 구현이 가능하고, 영상 스트리밍과 관련된 많은 기능을 지원하기 때문이다. Flash에서 스트리밍을 위해 많이 사용하는 프로토콜은 RTMP라고 하는 것이 있다. RTMP는 Macromedia에서 영상 스트리밍 전송을 위해 만든 기술로써 이를 지원하는 서버가 많이 존재한다.

Flash는 보안과 관련하여 많은 고민을 하여 만들어 졌는데, 이 중 하나가 RTMP에서 들어온 음성 스트림에 대한 샘플 데이터에 대한 보안이다. 샘플 데이터는 SoundMixer라는 클래스의 computeSpectrum()이라는 함수[1]를 이용하여 알아낼 수 있다. 서버에서 허가를 하지 않으면 RTMP에서 들어온 음성 스트림 샘플을 이용할 수 없게 된다.  소리가 나오는데 computeSpectrum()의 결과값이 ‘0’으로만 채워져서 리턴되는 것이다.  이 포스팅에서는 이를 WowzaMediaServer에서 어떻게 해결하는지를 알아 본다.

방법은 간단하다. WowzaMediaServer 설치 디렉토리 밑의 conf 디렉토리에서 설정을 바꾸고 싶은 어플리케이션(Application)의 Application.xml 파일을 변경하면 된다. Root->Application->Client->Access->StreamAudioSampleAccess 설정에 *를 표시하면 이 문제가 해결된다 [2]. 이 문제는 crossdomain.xml[3]과 관련된 문제와는 별게의 것으로 알려져 있다.

<Client>
     <IdleFrequency>-1</IdleFrequency>
     <Access>
          <StreamReadAccess>*</StreamReadAccess>
          <StreamWriteAccess>*</StreamWriteAccess>
          <StreamAudioSampleAccess>*</StreamAudioSampleAccess>  <!-- 이부분 수정 -->
          <StreamVideoSampleAccess></StreamVideoSampleAccess>
          <SharedObjectReadAccess>*</SharedObjectReadAccess>
          <SharedObjectWriteAccess>*</SharedObjectWriteAccess>
     </Access>
</Client>

참고 자료

[1] SoundMixer 클래스(2013-05-21 02:02 KST에 확인),  http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/SoundMixer.html

[2] Example of how to use ComputeSpectrum with Wowza Media Server(2013-05-21 02:23 KST에 확인), http://www.wowza.com/forums/content.php?56-Example-of-how-to-use-ComputeSpectrum-with-Wowza-Media-Server

[3] Cross-domain policy for Flash movies(2013-05-21 02:23 KST에 확인),  http://kb2.adobe.com/cps/142/tn_14213.html

4월 072012
 

미로 최단거리 문제 – 프로그래밍 콘테스트 챌린징 책 P50 문제

 

너비 우선 탐색을 통해 문제를 풀음.

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

class Save
{
	public int x;
	public int y;
	public int num;

	public Save(int x, int y, int num
	{
		this.x = x;
		this.y = y;
		this.num = num;
	}
}

public class Miro {

	public static void main(String[] args) {
		int x, y;
		int num = 0;
		int start_x = 0;
		int start_y = 0;
		int[][] arr = new int[102][102];
		Queue<Save> queue = new LinkedList<Save>();
		Scanner scan = new Scanner(System.in);

		x = scan.nextInt();
		y = scan.nextInt();

		for (int i = 0; i <= x + 1; i++) {
			for (int j = 0; j <= y + 1; j++)
			{
				arr[i][j] = -100;
			}
		}

		for (int i = 1; i <= x; i++)
		{
			char[] tmp = scan.next().toCharArray();

			for (int j = 0; j < y; j++)
			{
				if (tmp[j] == 'S')
				{
					start_x = i;
					start_y = j + 1;
				}
				else if (tmp[j] == '.')
				{
					arr[i][j + 1] = 0;
				}
				else if (tmp[j] == 'G')
				{
					arr[i][j + 1] = Integer.MAX_VALUE;
				}
			}
		}

		queue.add(new Save(start_x, start_y, num));

		while (!queue.isEmpty())
		{
			Save now = queue.poll();
			num = ++now.num;

			if (arr[now.x][now.y] == Integer.MAX_VALUE)
			{
				break;
			}

			arr[now.x][now.y] = now.num;

			if (arr[now.x - 1][now.y] == 0)
			{
				queue.add(new Save(now.x - 1, now.y, now.num));
			}
			if (arr[now.x][now.y - 1] == 0)
			{
				queue.add(new Save(now.x, now.y - 1, now.num));
			}
			if (arr[now.x + 1][now.y] == 0)
			{
				queue.add(new Save(now.x + 1, now.y, now.num));
			}
			if (arr[now.x][now.y + 1] == 0)
			{
				queue.add(new Save(now.x, now.y + 1, now.num));
			}
		}
		System.out.println(num);
	}
}

 

4월 072012
 

 

Lake Counting (POJ No.2386)

 

재귀 함수를 이용하여 구현하였다.

import java.util.Scanner;

public class P2386 {

	public static int[][] arr = new int[102][102];

	public static void check(int x, int y, int num) {

		arr[x][y] = num;

		if (arr[x - 1][y] == 0)
			check(x - 1, y, num);

		if (arr[x + 1][y] == 0)
			check(x + 1, y, num);

		if (arr[x - 1][y - 1] == 0)
			check(x - 1, y - 1, num);

		if (arr[x][y - 1] == 0)
			check(x, y - 1, num);

		if (arr[x + 1][y - 1] == 0)
			check(x + 1, y - 1, num);

		if (arr[x - 1][y + 1] == 0)
			check(x - 1, y + 1, num);

		if (arr[x][y + 1] == 0)
			check(x, y + 1, num);

		if (arr[x + 1][y + 1] == 0)
			check(x + 1, y + 1, num);

	}

	public static void main(String[] args) {

		int x, y;
		int num = 0;
		Scanner scan = new Scanner(System.in);

		x = scan.nextInt();
		y = scan.nextInt();

		for (int i = 0; i <= x + 1; i++)
		{
			for (int j = 0; j <= y + 1; j++)
			{
				arr[i][j] = -1;
			}
		}

		for (int i = 1; i <= x; i++)
		{
			char[] tmp = scan.next().toCharArray();

			for (int j = 0; j < y; j++)
			{
				if (tmp[j] == 'W')
				{
					arr[i][j + 1] = 0;
				}
			}
		}

		for (int i = 1; i <= x; i++)
		{
			for (int j = 1; j <= y; j++)
			{
				if (arr[i][j] == 0)
				{
					check(i, j, ++num);
				}
			}
		}

		System.out.println(num);
	}
}

 

4월 042012
 

개미가 부디칠 경우 통과한다고 보고 작성.,

 

속도는 O(n)

import java.util.Scanner;

public class P1852 {

	/**
	 * @param args
	 */

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

		testcase = scan.nextInt();

		while (testcase– > 0)
		{
			int l = scan.nextInt();
			int n = scan.nextInt();

			int max = 0;
			int min = 0;

			for (int i=0; i<n; i++)
			{
				int t = scan.nextInt();

				max = Math.max(max, Math.max(l-t, t));
				min = Math.max(min, Math.min(l-t, t));
			}

			System.out.println(min + ” ” + max);
		}
	}
}