구글은 이미 인공지능으로 돈을 벌고 있었다.

2017. 5. 29. 20:16 Posted by 아는 개발자

작년 이세돌에이어 현 바둑 인간계 랭킹 1위인 커제까지 알파고한테 패배하고 말았다. 작년부터 시작된 인공지능 시장의 흐름은 자율주행 자동차, 로봇이 나오면서 점차 겆잡을 수 없는 흐름을 탔고 많은 사람들은 인공지능을 실생활에 어떻게 활용 할 수 있을지 그리고 이를 이용해 어떻게 수익을 낼 수 있을지 고민하기 시작했다. 하지만 인공지능으로 돈을 벌 방법을 고민하는 와중에 벌써 돈을 벌고 있는 기업이 있을 것이라곤 상상하지 못했다. 놀랍게도 그 기업은 작년 알파고와 자율주행 자동차로 우리를 놀래켜준 구글이다. 구글은 이미 인공지능을 이용해서 돈을 벌고 있었다. 도대체 우리가 모르는새 그들은 어떻게 돈을 벌고 있었을까?


일반 사람들에겐 와닿지 않겠지만 대부분의 기업들은 이미 비즈니스에서 인공지능 기술을 사용하고 있었다. 쉽게 예를들어 인터넷 쇼핑몰들은 사용자들이 찾는 상품을 검색 키워드에 맞춰 제공 할 수 있는 검색 기술이 기본적으로 필요하다. 뿐만 아니라 사용자 취향이나 나이, 기존 구매 목록을 참고해 필요 할 것 같은 상품을 추천 알고리즘도 필요하다. 검색기술과 추천 알고리즘은 대표적인 인공지능 기술중 하나이다. 아마존이나 페이스북, 알리바바같은 대형 기업들은 내부적으로 AI 솔루션을 만들어낼 인프라가 갖춰져 있지만 중소 기업들은 이런 기술을 자체적으로 만들어낼 인력과 역량이 부족하다. 구글은 이점을 노렸다. 구글은 대다수의 기업들이 공통적으로 필요 할만한 AI 솔루션을 개발했고 기업들에게 클라우드 서비스의 형태로 솔루션을 제공한다. 기업 입장에선 클라우드 서비스를 사용할 환경과 가공할 데이터만 있으면 적당한 사용료를 내고 고퀄의 인공지능 서비스를 사용 할 수 있게된다.


구글에서 제공하는 AI 솔루션과 사용 기업 목록, 에버노트를 제외하면 익숙한 기업은 없다.


구글은 작년 이세돌과 알파고의 대결로 명실상부한 AI 기업의 입지를 다짐과 동시에 올해 1월에 tensorflow라는 오픈소스 인공지능 API를 내놓았다. '박사 학위 없어도 인공지능을 개발 할 수 있게 하겠다'는 야심찬 포부를 안고 시작한 'tensorflow'는 데이터를 갖고 있는 개발자가 쉽게 기계 학습을 시킬 수 있는 도구를 제공한다. 가공할 데이터와 기본적인 데이터마이닝 및 인공지능 기술이이 있는 개발자라면 tensorflow를 이용해 쉽고 간단하게 인공지능으로 사용할 데이터를 만들어 낼 수 있는 것이다. 수학으로치면 지금껏 모든 수식을 직접 계산 했어야 했는데 공학용 계산기가 나타난 격이라 볼 수 있다.


공짜로 기술을 푼 것을 의아하게 여길 수 있지만 안드로이드 사례를 생각해보면 구글의 목표는 명확하다. 안드로이드를 공짜로 푼 후 애플리케이션 시장이라는 거대한 시장을 만들었던 것 처럼 tensorflow를 이용해 구글은 본격적으로 인공지능 판키우기에 돌입했다. 그것도 자신들이 아주 유리한 고지를 선점한 판을 말이다. 향후 그들이 어떻게 돈을 벌지는 온갖 예측이 난무한다. 하지만 탄탄한 기술력과 인공지능 대표 기업의 브랜드를 가진 구글이 이 판을 주도할 것이라는 사실만은 분명해보인다.

728x90

총무앱 - 개발

사이드 프로젝트/이기적인 총무 2017. 5. 14. 18:22 Posted by 아는 개발자

구현할 기능 자체가 단순하고 잉여력 측정기 개발 할 때 다양한 기능들을 경험해봐서 그런지 개발을 빠르게 진행 할 수 있었다. 현재 총무앱에 필요한 기본 기능들은 모두 구현이 완료됐다. 각 기능별로 어떻게 구현했는지 간단히 정리하려고 한다.


- 모임/결제 데이터베이스 관리


잉여력측정기에서 애플리케이션 데이터베이스를 만드는 것을 한 번 경험해봐서 데이터베이스 기본 동작을 쉽게 구현 할 수 있었다. 테이블은 크게 모임 테이블과 결제 내역 테이블 두개를 생성해서 관리한다.


모임테이블은 Party Table, 결제내역 테이블은 Pay Table로 관리한다. 굵은 글씨로 표시한 것은 각 테이블의 primary key이다. 붉은색으로 표시한 pay_party_id는 외래키인데, 결제 내역은 항상 특정 모임에 포함되는 관계이기 때문에 선언해뒀다. 모임을 선택하면 결제 내역은 모임 테이블의 party id와 동일한 값들만 읽어오게 되고 모임이 삭제되면 외래키 관계에 있는 값들만 자동으로 삭제할 수 있다.


DB시간에 배운 외래키를 적용하고 자동으로 삭제되는 기능을 구현하기까지 에러가 많이 발생했었다. 나는 분명히 제대로 SQL 문을 작성하고 적용한 것 같은데 이상한데서 문제들이 툭 튀어나왔다. 지금은 아래와 같이 해결했다



먼저 테이블 생성 할때 특정 attribute가 외래키임을 선언하는 구문(Foreign key 로 시작하는...)은 테이블 생성 맨 아래에 와야 했다. 중간에 끼어 넣으니까 테이블 생성 할 때 자꾸 죽었다. 이유는 모르겠다.. 애초에 문법상의 문제가 있었던 것인지.. 그런데 이렇게만 두면 생성할때는 문제가 없으나 외래키가  참조하는 튜플(party)을 삭제할 때 또 죽었다. 알고보니 바로 삭제하는(on cascade) 옵션이 적용되려면 아래처럼 DB에 따로 또 옵션을 줘야했다.



이상한데서 시간을 말짱 보냈다 ㅡㅡ


- 결제내역 공유하기 기능


카카오톡 공유기능처럼 깔끔하게 만들려면 무지 시간이 걸릴 수 있는데 나는 애초에 모든 애플리케이션과 공유하는 걸 목표로 했었다. 다행히 안드로이드에서 쉽게 공유 할 수 있는 기능을 만들어놔서 그저 가져다 사용하면 됐다. 정산 내역을 텍스트로만 보내서 깔끔하지 않은 것 같긴 하다. 하지만 뭐 이정도면 감지덕지지. 디자인 할 때 앱 홍보 링크도 넣고 하면 좀더 깔끔하게 보내 질 것 같다.


(결제 내역이 카카오톡에 공유된 모습)


나머지 기능들은 디자인과 관련된 기능이므로 디자인때 총 정리해야겠다.

728x90

'사이드 프로젝트 > 이기적인 총무' 카테고리의 다른 글

이기적인 총무 - 리팩토링 계획  (1) 2018.01.07
총무앱 - 이기적인 총무 런칭 그리고 업데이트  (0) 2017.07.15
총무앱 - 디자인  (0) 2017.07.02
총무앱 - 개발+a  (0) 2017.06.06
총무앱 - 개발  (0) 2017.05.14
총무앱 - 기획  (0) 2017.05.05

총무앱 - 기획

사이드 프로젝트/이기적인 총무 2017. 5. 5. 16:59 Posted by 아는 개발자

필자는 모임에서 주로 총무를 도맡아(떠밀려서) 하는 편인데 그때마다 거래내역 영수증 챙기고 구글 Keep에 거래내역과 금액 써둬가며 관리를 한다. 하지만 이렇게 관리를 하면 나중에 결산 할 때 불편한 점이 영수증은 지갑에서 구겨져 형체를 알아 볼 수 없게 되어 있고, 구글 Keep에 써둔 결제 내역을 계산기 애플리케이션으로 옮기자니 애플리케이션을 계속 여러번 왔다갔다 해야하는 불편함이 있다. 게다가 옮기는 도중에 거래 금액을 한 번 잘못 쓰거나 계산기 글자수 초과가 나버리면 처음부터 다시 입력해야하는 삽질도 있으니 은근히 시간도 많이 잡아먹고 짜증나는 작업이다.


그래서 날 위해(혹여나 나처럼 돈계산으로 스트레스받는 사람들을 위해) 모임 돈계산을 도와주는 총무앱을 만들어 보기로 했다. 이미 시중에 총무앱이 몇 개 있긴 한데 대부분 계모임 돈관리를 목적으로 만들어져 모임 구성원 관리처럼 불필요한 기능들도 많고 UI 디자인은 촌스럽고 사용하기 어렵게 되어있다. 그래서 난 최대한 심플하고 쉽게 사용할 수 있는 더치페이 전용 총무앱을 만들어보려고 한다.


현재 구상은 대략 이렇다



다른 앱들이 모임 참가자랑 중간에 빠진 사람들을 관리를 앱을 통해서 할 수 있도록 많이 골몰한것 같은데 이렇게 할 경우 앱에다가 구성원 목록을 일일히 저장하고 각 모임별 구성원들도 만들어야해서 아마 사용중에 지쳐버릴 것이다. 나는 간단히 구성원 추가 이런거 없고 각 결제 내역별 참가자 수와 인당 청구 금액 그리고 모든 모임에 참여한 경우 청구 금액을 쭉 나열해 SNS에 공유 할 수 있도록 만들 생각이다. 참가자는 자신이 결제에 참여하지 않은 금액을 제외하고 입금하면 된다. 총무는 입력 할 내용이 적어서 심플하고, 참가자들은 자기 결제 내역을 꼼꼼히 검토해볼 수 있어서 서로 좋지 않을까 생각한다.

728x90

'사이드 프로젝트 > 이기적인 총무' 카테고리의 다른 글

이기적인 총무 - 리팩토링 계획  (1) 2018.01.07
총무앱 - 이기적인 총무 런칭 그리고 업데이트  (0) 2017.07.15
총무앱 - 디자인  (0) 2017.07.02
총무앱 - 개발+a  (0) 2017.06.06
총무앱 - 개발  (0) 2017.05.14
총무앱 - 기획  (0) 2017.05.05

잉여력측정기 -개발 중단

사이드 프로젝트 2017. 4. 24. 22:03 Posted by 아는 개발자

이 프로젝트를 처음 시작 할 때 구글이 보안상의 문제로 기존에 있던 프로세스 관련 함수들을 모조리 없애서 핵심 기능을 구현 할 때 힘들었었다. 다행히 여러 오픈소스 프로젝트에서 이런 구글의 보안 정책들을 피해 프로세스 정보들을 추출 할 수 있게 해주어서 애플리케이션의 실행 유무를 확인 할 수 있도록 만들어 왔는데, 최신 안드로이드 OS 누가(Nougat) 에서는 아예 (/proc) 디렉토리의 권한을 바꿔버려 일반 프로세스가 접근하는 것조차 막아버렸다. 이젠 시스템 애플리케이션이 아니면 프로세스 정보 읽을 때 자신의 프로세스 정보 밖에 볼 수가 없다. 다른 애플리케이션의 실행 유무도 알 수 없고 커널에 백그라운드로 돌아가는 앱도 알 수 없다. 이렇게 되면 이 프로젝트의 가장 중요한 기능인 다른 애플리케이션의 실행 유무를 확인 할 수가 없다ㅠㅠ


누가 업데이트에 대해서도 빈틈을 찾아낸 오픈소스가 있는지 확인해보았으나 별 다른 방법이 없었다. 내가 사용한 오픈소스 프로젝트의 오너는 이슈페이지를 만들고 다른 개발자들과 방안을 모색 하기도 했는데 이번에는 안드로이드 정책에 다들 항복한 것 같다. 몇몇은 안드로이드 업데이트를 욕하기도 하지만 보안상 어쩔 수 없는 결정이라고 다들 수긍하는 것 같았다. 결국 이 프로젝트를 중단하겠다는 코멘트를 남기고 이슈가 종료됐다.


나름 열정적으로 추진했던 프로젝트여서 아쉬움이 남는다. 비록 다른 사람들한테 홍보 할 때 반응들이 시큰둥 했지만 내 이름으로 앱마켓에 하나라도 올려보고자 시작한 프로젝트라 남들이 뭐라 하든 개의치 않았다. 예전에도 이런 프로젝트를 다른 사람들이랑 같이 해봤는데 그때마다 개발 도중에 무슨 일이 생겨서 중단돼 끝을 맺지 못했었다. 그래서 이번 만큼은 죽이 되든 밥이 되든 완성해서 런칭을 해보려고 했는데 이번에는 플랫폼이 문제라니. 그것도 개발 다하고 디자인 입히는 과정에서 이러니 매우 허탈한 심정일 따름이다. 


아직 까지는 보안 정책을 피할 수 있는 방법이 보이지 않는다. 이번에는 정말 꼼꼼히 막아 놨나보다. 왜 하필 내가 야심차게 앱을 만들 때 이런 건지 모르겠지만 그래도 일단 기다려보려고 한다. 혹시나 시간이 지나면 보안 정책이 바뀌지 않을까 아니면 나랑 같은 고민을 하고 있는 벤치마크 개발자가 또 뚫어내는 방법을 찾아 놨을지도. 그때를 위해 프로젝트는 계속 갖고 있어야겠다.

728x90

'사이드 프로젝트' 카테고리의 다른 글

잉여력측정기 -개발 중단  (0) 2017.04.24
잉여력 측정기 -개발(2/2)  (0) 2017.03.30
잉여력 측정기 -개발(1/2)  (0) 2017.03.26
잉여력 측정기 -기획  (0) 2017.03.26

SW 역량테스트 기출 문제집 분석

알고리즘/acmicpc 2017. 4. 21. 20:12 Posted by 아는 개발자

백준 온라인 저지에서 삼성 SW 역량테스트 기출 문제집을 발견 했다. 분명히 시험시간에 감독관이 외부에 유출하지 말라고(말아달라고) 했을 텐데 싸트 문제처럼 이것도 외부 유출은 막을 수 없나 보다. 재미 삼아 여기 있는 문제들을 한 번 풀어 봤는데 문제들이 공통적으로 뚜렷한 경향이 있었다. 이번 포스트에서는 (문제집에 올라온 기출 문제들이 모두 사실이라는 전제 하에) 기출 문제를 분석하고 취준생 입장에서 어떻게 준비하는 것이 좋을 지를 정리 해봤다.


기출 문제 분석


1. 시뮬레이션 문제가 대부분


대부분의 문제들이 고급 알고리즘 없이도 풀 수 있다. 여기서 고급 알고리즘은 다익스트라나 최소 스패닝 트리 같이 대학교 알고리즘 강의에서 배우는 내용들을 말한다. 물론 기출로 나온 문제들을 고급 알고리즘을 적용한다면 좀 더 빠르게 풀 수도 있을 것이다. 하지만 문제의 조건으로 주어지는 N값이 작기 때문에(대부분의 문제가 100 이하로 주어진다) 적용한 알고리즘이 O(N^2)이든 O(N^3)이든 중요치 않다. 모든 경우에 대해서 탐색 할 수 있도록 코드를 작성 할 수 있으면 시간 초과 없이 맞출 수 있는 문제다.


2. 구현이 까다롭다.


그러나 실수하기 딱 좋은 조건들만 문제에 나왔다. 알고리즘 문제를 많이 풀어본 사람들도 지도 유형의 문제를 까다로워 하는데 여기 서는 거기에 한 술 더 떠서 지도를 회전시키고 기울이기까지한다. 싸트를 생략하는 대신 여기서 공간 능력을 테스트 해보려는 의도인지 모르겠으나 단순 구현이라고 하기엔 머리가 좀 아프다. 문제 자체는 이해하기 쉽고 풀이법도 빠르게 떠오르는데 막상 손을 대려면 소소한 조건들을 구현하는 것이 난감하고 어찌어찌 구현을 해내면 예상치 못한 예외 케이스들이 나와 디버깅 하는데 시간을 다 쓰게 된다. 실제로 13460 문제를 집에서 한 번 풀어봤는데 세로/가로 크기가 10이하인 것을 캐치해 모든 경우에 대해서 시뮬레이션 하는 것으로 방향을 잘 잡았으나 '빨간공/파란공이 인접했을 때 움직임을 어떻게 구현 할 것인가'를 놓고 꽤 고민했고 또 예상치 못한 케이스를 해결하는데 시간을 오래 썼다. 만약 시험장에서 긴장과 압박감 속에서 풀어야 했다면 결코 쉽지 않았을 것 같다.



어떻게 준비하는 것이 좋을까?


기출 문제들로만 미루어 봤을 때 여기선 '똑똑하지 않아도 구현은 제대로 할 줄 아는 프로그래머'를 원하는 것 같다. 구현하기 까다로운 문제들을 실수 없이 빠르게 구현해내기 위해선 자신만의 코딩 스타일을 가지는 것이 중요하다. 시험장에서 배열의 인덱스를 0에서부터 시작 할 지, 1에서부터 시작할지나 지도상의 동서남북 탐색 방법을 구현하는 것을 어떤 식으로 구현할 지 고민하면 너무 늦다. 문제의 다양한 조건들을 어떻게 대처 할 것인지 미리 훈련이 되어 있어야 되도록 실수 없이 한 번에 구현 할 수 있어야 한다.


1. 나만의 코딩 스타일을 가지기


글쓴이는 로봇 청소기 문제에서 회전 방법과 각 방향 별로 전진, 후퇴를 아래 코드로 구현 했다.


 
int dir_r[4] = { -1, 0, 1, 0 };
int dir_c[4] = { 0, 1, 0, -1 };
int process(int r, int c, int dir) {

	int cnt = 0;
	int befo_r = -1, befo_c = -1;
	int ret = 0;

	while (1) {

		....

		int turn_dir = (dir - 1 + 4) % 4;

		// turn left,,,
		if (r + dir_r[turn_dir] >= 0 && r + dir_r[turn_dir] < R &&
			c + dir_c[turn_dir] >= 0 && c + dir_c[turn_dir] < C) {

			int exist = 0;

			if (map[r + dir_r[turn_dir]][c + dir_c[turn_dir]] == 0)
				exist = 1;

			if (exist) {
				dir = turn_dir;
				r += dir_r[turn_dir];
				c += dir_c[turn_dir];
				continue;
			}
			else
				dir = turn_dir;
		}
		else
			dir = turn_dir;

	}

	return -1;
}


dir_r, dir_c 변수는 북,동,남,서 방향 별로 전진 할 시 변경해야 하는 행과 열의 변화 값을 갖고 있다. 현재 방향만 알면 앞으로 이동하게 되는 위치 값을 쉽게 표현 할 수 있게 된다(물론 뒤로 후퇴하는 것까지 가능!). 그리고 북,동,남,서의 순서는 각각 오른쪽으로 회전하는 순서다. 이는 곧 순서를 반대로만 하면 왼쪽으로 회전 하는 것까지 쉽게 표현 할 수 있다. turn_dir 변수에 왼쪽으로 회전하는 경우의 방향 값을 저장 해뒀다.


물론 위 방법이 최선이라고 할 수는 없다. 다만 나는 위 방식으로 구현할 때 가장 빠르고 실수도 없다. 각자 자신에게 익숙한 방식으로 구현 할 때 실수를 줄일 수 있다.


물론 실무에서는 자신만의 코드 스타일로 코드를 짤 경우 리뷰 받을 때는 상당히 피곤한 코멘트를 받게 되겠지만... 일단 합격을 해야 리뷰를 받을 수 있으니 자신이 최대한 실수 하지 않도록 훈련을 해두자.


2. 척박한 디버깅 환경에서 연습하기


코드 스타일을 만드는 것 뿐만 아니라 평소에 좋은 디버깅 툴을 되도록 사용하지 않는 훈련을 하는 것도 중요하다. 시험 볼 때는 비주얼 스튜디오를 사용하고 거기에 있는 모든 디버깅 기능들을 사용 할 수 있다고 하니 사용 방법만 알아두고 평소에는 되도록 사용하지 말자. 육상선수가 모래주머니를 달고 훈련 하는 것과 비슷하다고 할까, 되도록 원하는 코드를 한번에 구현 하는 연습을 해보는 것이 좋고 예상한 결과 값이 나오지 않더라도 자신의 코드에서 논리적으로 유추해서 파악하는 것이 중요하다. 처음에는 힘들지만 계속 해보면 자신이 어느 부분에서 반복적으로 실수하는 지 알 수 있고 고칠 수 있다. 글쓴이는 알고리즘 문제 풀 때는 되도록 우분투 Vim 에디터에서 문제를 푼다. 이런 훈련은 알고리즘 문제 뿐만 아니라 디버깅 환경이 척박한 실무에서도 도움이 된다.



(필자가 Vim에디터로 문제를 푸는 모습. 뱀 문제는 왜 틀렸는지 아직도 모르겠다)


728x90

'알고리즘 > acmicpc' 카테고리의 다른 글

SW 역량테스트 기출 문제집 분석  (4) 2017.04.21
10422  (0) 2017.04.05
1937  (0) 2016.09.06
4095  (0) 2016.08.15
11437  (0) 2016.07.30
2253  (0) 2016.07.24
  1. 아는개발자를알고싶은개발자 2017.10.16 23:09  댓글주소  수정/삭제  댓글쓰기

    이런 분석 글 너무 좋습니다! 감사합니다~

  2. 아는개발자팬 2017.10.30 23:46  댓글주소  수정/삭제  댓글쓰기

    멋있으세요!!!><

10422

알고리즘/acmicpc 2017. 4. 5. 23:03 Posted by 아는 개발자

문제를 보자마자 DP를 써야 한다는건 직감했는데 식을 어떻게 세워야 할지 쉽게 감이 오지 않았다. 가장 직감적으로 들었던 식은 이렇다.


문자열의 길이가 K인 경우의 식은 아래와 같이 구할 수 있다고 생각했다.


1. dp[K] = dp[K-2]

2. dp[K] += dp[2]*dp[K-2] + dp[4]*dp[K-4] + ... dp[K-2]*dp[2]


이미 괄호의 개수가 정해진 K-2개의 문자열에 괄호를 끼운다고 생각하면 반드시 올바른 괄호가 되므로 1번 식은 성립한다. 2번 식은 나머지 경우들을 처리하는 식인데, K개의 괄호식을 만든다고 생각할 때 앞부분에 해당하는 괄호의 경우의 수 와 뒷부분에 해당하는 괄호의 경우의 수를 곱해주면 길이가 K인 문자열을 구할 수 있다고 생각했다. 하지만 위의 식은 중복되는 경우의 수들을 처리하지 못한다.


만약 위의 식으로 K=6인 경우를 구하면


dp[2] = 1, ()

dp[4] = 2, (()) ()()


1번식에 의해 dp[6] = 2    ->     ((())), (()())

2번식에 의해 dp[6] += dp[2]*dp[4]     ->     ()(()), ()()()

       + dp[4]*dp[2]    ->    (())(), ()()()


'()()()' 라는 중복된 경우가 생겨버린다. DP를 사용하면서 중복된 경우가 생기지 않도록 식을 만들어야한다.


K개의 문자열의 앞부분과 뒷부분을 크게 A와 B로 나뉘어보자. 2번식에 따르면 A의 크기는 점점 커지고, B의 크기는 점점 작아질 것이다.



만약 크기가 달라지면서 생기는 모든 A영역들에 대하여 중복된 경우가 없다고 할 수 있다면, B영역에 대해서 생각 할 필요 없이 위 문자열은 중복되지 않았다고 정의 할 수 있다.



B영역내에서 중복이 있든 없든 문자열 전체로 보면 A 영역내에서 이미 특수성을 가지고 있기 때문에 고려할 대상이 아니다.

중복하지 않는 각 A 영역의 경우의 수는 어떻게 구할 것이냐? 이건 1번식을 통해서 이미 구했다. 1번식은 바로 전 문자열에서 괄호 두 개를 덮은 것이기 때문에 길이가 달라도 중복된 것이 생기지 않는다고 할 수 있다.


위 방법으로 DP식을 다시 정리해보자.


1. dp[K][0] = dp[K-2][0] + dp[K-2][1]    -> 이전 문자열에 괄호를 씌운 경우

2. dp[K][1] = dp[2][0]*(dp[K-2][0] + dp[K-2][1]) + dp[4][0]*(dp[K-4][0] + dp[K-4][1]) ... + dp[K-2][0]*(dp[2][0] + dp[2][1])


 
#include <stdio.h>

using namespace std;

#define MAXN 5005
#define MOD 1000000007

long long dp[MAXN+1][2];

void init() {
	dp[2][0] = 1;

	for(int i=3; i <= MAXN; i++) {
		if(i%2)
			continue;
		for(int j=2; j<i; j+=2) {
			dp[i][1] = (dp[i][1] + dp[j][0]*dp[i-j][0])%MOD;
			dp[i][1] = (dp[i][1] + dp[j][0]*dp[i-j][1])%MOD;
		}
		dp[i][0] = (dp[i-2][0] + dp[i-2][1])%MOD;
	}
}

int main()
{
	freopen("input.txt", "r", stdin);

	int tc, inp;

	init();
	scanf("%d", &tc);

	while(tc--) {
		scanf("%d", &inp);
		printf("%lld\n", (dp[inp][0] + dp[inp][1])%MOD);
	}


	return 0;
}


728x90

'알고리즘 > acmicpc' 카테고리의 다른 글

SW 역량테스트 기출 문제집 분석  (4) 2017.04.21
10422  (0) 2017.04.05
1937  (0) 2016.09.06
4095  (0) 2016.08.15
11437  (0) 2016.07.30
2253  (0) 2016.07.24

잉여력 측정기 -개발(2/2)

사이드 프로젝트 2017. 3. 30. 22:31 Posted by 아는 개발자

잉여력 측정기 개발 두 번째 이야기다. 핵심적인 기능들은 첫번째 포스트에서 만들어 뒀고 이번 포스트에서 설명할 내용들은 필요한 기능들이나 많이 어렵지는 않았던 내용들이다. 현재 구현한 사항들은 안드로이드 버전이 올라가면서 없어지던 기능이 없었다(아주 당연한 일이지만). 스택 오버플로우와 옛날 학교에서 프로젝트 했던 경험을 살려서 빠르게 구현 할 수 있었다.


1. App 실행 횟수 저장할 데이터베이스 구축


데이터베이스를 구축 해보는 것이 너무 오랜만이라 스키마의 기본적인 개념도 까먹었다(튜플이랑 key가 왜이렇게 생소하게 느껴지는 건지) 사실 여기서 구현할 데이터베이스 형태는 정말 단순한 것인데도 허둥 지둥 했다. 기억력 복원 작업을 한 두 시간정도 하고 나서 스키마를 짜고 Android SQLite Tutorial을 따라가면서 DB를 만들었다. 다행히 한방에 깔끔하게 구현 된 것 같다. 만든 DB 테이블은 이렇다.



ID값은 primary key이다. Auto Increment로 생성되도록 했다. 애플리케이션들마다 'Package Name'이란게 존재하는데 프로세스들은 이 이름으로 안드로이드내에서 실행되고있다. 애플리케이션 이름은 한글 일수도 있는데 반해 Package Name은 영어로 통일되어 있고 혹시나 이름이 동일한 애플리케이션이 있더라도 Package이름으로 구분 할 수 있을 것 같아서 DB에 넣기로 했다. Count값은 실행 횟수고 Date는 Count 하는 날짜다. Reason Code는 이 앱이 카운팅 된 이유를 기록한 값이다.


아직 구현은 안됐는데 일별 총 카운팅 횟수를 기록할 테이블도 만들 생각이다. 만든다면 아마 테이블은 요렇게 간단히 만들 수 있을 것이다.



별일 아닌데 막상 만들려고 하니 보람을 내일로 미루고 싶은 욕구가 강렬해졌다.


2. 달력으로 앱 실행 횟수 가져오기


날짜 별로 나의 앱 실행 횟수 기록을 카운팅 할 수 있어야하는 요구 사항이 있었다. 다행히 요건 안드로이드에서 DatePickerDialog라는 것을 이용해 쉽게 날짜를 선택 할 수 있게 해줬고(UI도 이쁘게!) 내가 할 일은 캘린더에서 리턴한 날짜 기록에 맞춰서 DB에서 값들을 읽어오는 일 뿐이었다. 날짜에 맞춰서 읽어오는 일은 기존에 있던 SQL 명령어를 조금 수정해서 구현 할 수 있었다.


         


(캘린더 토글로 3/27 기록에 맞춰서 기록을 가져온 결과)


3. 사용량 그래프 그리기


애플리케이션마다 날짜별 사용량을 그래프로 보여 줄 수 있어야 했는데 안드로이드 API 형태로 제공되는 그래프 UI는 없었다. 다행히 오픈 소스에서 여러가지 프로젝트가 있었고 구글 검색 결과 제일 많이 사용하는 프로젝트를 골라서 구현했다. 요즘 깃허브는 그냥 소스만 제공하는게 아니라 가이드도 아주 아주 상세한 것 같다. 다른 오픈소스 프로젝트 가이드 뺨치는 수준. 대충 훑어 보긴 했지만 그래프 축 최대/최소값 조절 뿐만 아니라 스타일링까지 함수 하나로 해결 할 수 있었고 원한다면 추가로 기능을 구현해 애니메이션을 넣을 수 있는 효과도 있었다. 이건 디자인 스펙이 결정되면 코드레벨까지 내려가서 세세히 볼 계획이다.


(카카오톡 사용량을 그래프로 찍어본 모습. 정말 데모 수준의 UI이고 손 볼 곳이 많지만 시작이 반이니까!)


이 정도면 대강 구현은 완료된 것 같다. 이제는 앱을 이쁘게 꾸미는 작업을 해야겠다.

728x90

'사이드 프로젝트' 카테고리의 다른 글

잉여력측정기 -개발 중단  (0) 2017.04.24
잉여력 측정기 -개발(2/2)  (0) 2017.03.30
잉여력 측정기 -개발(1/2)  (0) 2017.03.26
잉여력 측정기 -기획  (0) 2017.03.26

잉여력 측정기 -개발(1/2)

사이드 프로젝트 2017. 3. 26. 16:29 Posted by 아는 개발자

옛날 안드로이드 애플리케이션 개발 경험 상으로 요구 사항들을 구현하는 것이 별거 아닐 거라고 생각했는데... 왜 안드로이드는 시간이 흐르면서 계속 지원하지 않는 기능들이 많아지는 건지...! 스택 오버플로우에 있는 가이드 내용을 따라 가려고 하니 되는 것이 하나도 없고, 구현에 가장 핵심적인 API함수가 갑자기 depracated로 떠서 어떻게 구현해야 할 지 난감했었다. 다행히 깃허브에서 구해낸 소스와 여기저기 뒤져가면서 코드를 구현해 기획단계에서 만들어둔 요구사항들은 일단 구현을 해냈다. 이번 포스트에서는 개발과정에서 어떤 어려움이 있었고 어떻게 해결했는지를 정리해보려고 한다.


1. 실행되는 애플리케이션 목록 가져오기.


잉여력 측정기 애플리케이션 내에서 실행되고 있는 애플리케이션을 알아 낼 수 있어야 한다. 이 프로젝트를 시작하기 전에 현재 실행하고 있는 애플리케이션의 목록을 쭉 보여 줄 수 있는 안드로이드 API(ActivityManager 클래스에서 getRunningAppProcess()라는 함수를 사용하면 된다)가 있는 것을 알았었다. 이 함수를 이용해 쉽게 Application과 Service를 구별 할 수 있어서 별 다른 어려움 없이 구현 할 수 있을 줄 알았다.


https://developer.android.com/reference/android/app/ActivityManager.html 참조.


하지만 막상 위 함수를 사용하니 리턴된 애플리케이션 목록에 현재 설치한 애플리케이션 말고는 아무것도 보이지 않았다. 어떻게든 실행되고 있는 애플리케이션 목록을 보려고 다음도 실행하고 인스타그램도 실행 해봤는데 여전히 결과는 똑같았다... 알고 보니 시스템 애플리케이션이 아니면 함수를 호출한 애플리케이션 밖에 안보여준다고 한다... 보안상의 이유로 바꿨다는데 핵심적인 기능을 사용 할 수 없으니 대략 난감했다.


혹시나 애플리케이션 안에서 리눅스 'ps' 명령어를 사용 할 수 있을지 찾아봤다. 이걸로 실행되는 애플리케이션 목록을 얻어와서 여기서 애플리케이션의 실행 유무를 파악할 생각이었다. 다행이 깃허브 오픈소스중에서 "ps"와 동일한 역할 을 할 수 있도록 만들어뒀다.


(https://github.com/jaredrummler/AndroidProcesses)


프로세스 목록만 가져오는게 아니라 package 이름, pid, foreground 유무 등등을 가져와서 프로세스의 종류를 파악하는데 많은 도움이 됐다. 아마 이 프로젝트가 없었다면 나머지기능들을 만드는데 무지 애를 먹었을 것이다.


2. 애플리케이션 실행 횟수 카운팅하기.


애초의 내 계획은 스레드 하나를 돌리고 여기서 실행되는 프로세스를 주기적으로 관찰해 새로 생성된 프로세스를 보고 카운팅 하려고 했다. 하지만 이렇게 간단한 방식을 도입했더니 백그라운드 애플리케이션이 무지 많이 카운팅됐다(난 한번도 SSF Shop 애플리케이션을 실행 한 적이 없었는데 내 의지와 무관하게 가장 많이 사용한 애플리케이션이 됐다). 애플리케이션들마다 개발 할 때 서비스를 구현한 방식이 모두 달라서 실행하지 않으면 돌아가지 않는 앱이 있는 반면, 스마트폰 부팅과 동시에 실행되는 애플리케이션이 있었다. 이런 경우 '잉여력측정기'에서는 애플리케이션이 여러 번 실행 된 것으로 착각 할 수 있다.


또한 프로세스 생성 유무로만 판단 하다 보니 재실행 하는 경우(실행 된 앱 목록에서 눌러서 다시 실행시키는 경우)를 측정 할 수가 없었다. 사용자들이 애플리케이션을 종료하지 않고 다시 사용하는 경우도 있기 때문에 프로세스가 새로 생성되지 않아도 실행 횟수를 판단 할 수 있어야 한다.


예외 경우의 수들을 처리 하기 위해 나는 실행 횟수가 증가하는 경우를 크게 세가지로 분류 했다.

      • 새로 생성된 프로세스: 스레드에서 관리하고있는 프로세스 목록 중에 존재하지 않는 프로세스가 생겨난 경우이다. 하지만 백그라운드 프로세스도 여러 번 반복해서 생겨날 수 있기 때문에 생겨난 프로세스가 Foreground인지 확인 한 후에 맞다면 실행 횟수를 증가 시키도록 한다.

      • pid가 변화된 프로세스: 스레드가 관리하고 있는 프로세스 목록에는 있으나 pid가 변화된 경우이다. 이 경우는 사용자가 한 번 애플리케이션을 종료하고 난 후 다시 실행 한 경우이다. 새로 생성된 프로세스와 동일한 경우이며 동일하게 프로세스가 foreground에 있는지 유무로 실행 횟수를 증가시킨다.
      • Background -> Foregrond 변화: 실행되고 있는 프로세스의 상태가 Background에서 Foreground로 변화한 상태이다. 이 경우는 애플리케이션을 종료하지 않고 다시 재실행한 경우를 처리한다.

세가지 경우에 대해서 만들어두니 백그라운드 애플리케이션이 카운팅되는 횟수가 눈에 띠게 줄었다. SSF Shop은 아예 없어졌고 기껏해야 KT 고객센터 정도... 이건 추가적으로 처리해야겠다.



(애플리케이션 카운팅 횟수 목록. 많이 실행된 순서로 정렬되어있다. 노래를 틀어놓고 개발해서 그런지 지니앱 실행 횟수가 가장 많다)


지금까지 나온 결과는 만족스럽다. 다른 기기에서도 동일하게 실행 된다면 현재의 알고리즘을 그대로 유지 할 수 있을 것 같다. 한 가지 걱정되는 점은 프로세스 목록을 보는 주기이다. 주기가 짧을 수록 카운팅 횟수의 정확도는 높아지고 주기가 길어질 수록 정확도는 낮아진다. 현재는 주기를 3초로 해두었는데 스마트매니저에서 배터리를 잡아먹는 애플리케이션이라고 뜬다.. 배터리 소모까지 생각하면 추가적으로 어떻게 구현해야 할 지 고민해봐야 겠다.

728x90

'사이드 프로젝트' 카테고리의 다른 글

잉여력측정기 -개발 중단  (0) 2017.04.24
잉여력 측정기 -개발(2/2)  (0) 2017.03.30
잉여력 측정기 -개발(1/2)  (0) 2017.03.26
잉여력 측정기 -기획  (0) 2017.03.26

잉여력 측정기 -기획

사이드 프로젝트 2017. 3. 26. 15:06 Posted by 아는 개발자

여느때처럼 회사 화장실 좌변식 칸에 들어가 생리 현상 해결 겸 머리를 식히기 위해 다음 앱을 실행하다가 문득 이런 생각이 들었다. '나는 하루에 다음 앱을 몇 번이나 켰을까?' 거의 매번 화장실 갈 때마다 실행 했을 것이고, 밥 먹으러 가는 도중이나 친구를 기다리는 와중에도 뉴스를 확인 하러 들어갔었다. 회의가 너무 길어져 따분해질 때나 코딩이 너무 힘들 때도 눌러 봤고 아침에 일어 나자마자 세상에 별 일이 없는지 확인 할 때도 눌러 봤으니 이 모든 걸 다 합하면 대략 하루에 20-30회는 넘게 실행했지 않았을까 하는 생각이 들었다.


그러면 난 스마트폰을 하루에 총 몇 번이나 실행 했을까? 다음 앱 실행횟수만 봐도 20-30회는 넘을텐데 그렇다면 자는 시간을 포함해서 거의 한 시간에 한 번 꼴로 나는 스마트폰을 실행하고 있는 것이다. 맨날 스마트폰을 멀리해야 한다고 말만 했지 실제로 스마트폰을 사용하는 횟수에 대해선 깊이 생각해보지 않았다. 그리고 다른 애플리케이션들은 얼마나 실행하고 있는걸까? 내 스마트폰에 설치된 애플리케이션만 40-50개는 될 텐데 이중에서 내가 자주 사용하는 애플리케이션은 손에 꼽을 것이다.


그래서 "애플리케이션 실행 횟수를 측정해주는" 애플리케이션을 만들기로 했다. 임시로 이름은 "잉여력측정기"로 정했다. 애플리케이션 유형을 따지자면 벤치마크류로 분류 할 수 있는데 난 '자아 성찰 프로그램'으로 분류하고 싶다. 개발에 들어가기 앞서 '잉여력측정기'의 요구사항을 정리해봤다.


  1. 애플리케이션 실행 횟수 기록: 사용자가 사용하는 애플리케이션 모든 실행 횟수를 기록한다. 여기서 실행 횟수를 판단하는 기준은 단순히 애플리케이션 아이콘을 눌러서 실행되는 것 뿐만 아니라 카톡으로 받은 메시지를 볼 때 실행 되는 것과 백그라운드에 있는 애플리케이션 목록(앱리스트를 누를 때 나오는 앱 목록)을 다시 눌러서 실행하는 횟수를 포함하는 것이다. 또한 카운팅 되는 애플리케이션은 유저와 인터랙션(Interaction)이 있었던 애플리케이션이어야 한다. 이는 곧 백그라운드에서 돌아가는 애플리케이션은 카운팅 횟수에서 빠지게 된다. 정확한 실행 횟수를 파악하려면 엄격하게 카운팅 케이스를 분류 할 필요가 있다.

  2. 날짜별로 기록하기: 애플리케이션 실행 횟수를 날짜 별로 기록하고 또 날짜 별로 각 애플리케이션의 실행 횟수를 볼 수 있다. 평일에 비해 주말에는 애플리케이션을 얼마나 더 자주 사용 할 수 있는지 등등을 파악하려고 만든 요구사항이다. 그리고 한 애플리케이션에 대해 날짜별로 사용량이 어떻게 달라지는지 알 수 있도록 한다.

추가적으로 아이디어가 더 떠오를 수 있지만 일단은 두 가지를 중점적으로 보고 구현하기로 했다.


요구사항들을 모두 충족하고 디자인까지 깔끔하게 만들어서 플레이스토어에 런칭해보는 것이 목표다. 다운로드 횟수는 목표로 두지 않기로 했다.. 어차피 한 번 경험해보는게 목표니까.. ㅎㅎ

728x90

'사이드 프로젝트' 카테고리의 다른 글

잉여력측정기 -개발 중단  (0) 2017.04.24
잉여력 측정기 -개발(2/2)  (0) 2017.03.30
잉여력 측정기 -개발(1/2)  (0) 2017.03.26
잉여력 측정기 -기획  (0) 2017.03.26

오픈스택 구조 분석

기술/클라우드컴퓨팅 2017. 3. 7. 23:12 Posted by 아는 개발자

오픈소스를 좀더 심도있게 분석하기 위해 설치도 하고 내부 소스 코드도 보려 했으나, 설치 가이드 글들을 전혀 이해를 할 수 없어서 논문 부터 차근차근 읽고 가기로 했다. 'OpenStack: Toward an Open-Source Solution for Cloud Computing'이란 논문을 읽었는데 한창 오픈스택이 뜨기 시작한 2012년도에 나온거라 그런지 별 다른 내용이 없었지만 그래도 오픈스택의 전체적인 구조는 이해하는데 도움이 된 것 같다.



논문에 따르면 오픈스택의 구조는 위 그림처럼 다섯가지로 나눌 수 있다고 하는데 여기서 주된 요소는 Compute, Image, Object라고 한다. 각각에 대한 설명은 다음과 같다.


  1. OpenStack Compute: IaaS 클라우드를 관리 담당하는 플랫폼이다. Amazon EC2나 Rackspace CloudServer랑 비슷한 역할을 하는데 주로 관리자 인터페이스 공간과 클라우드를 조율 할 수 있는 API를 제공하는 역할을 한다. 여기서 사용하는 기술을 Nova Compute라고 하는데 여러 Virtual Machine들의 네트워크와 구조 확정성을 관리한다. 그 뿐만 아니라 서버나 네트워크, 접근 권한을 관리하는 역할도 포함하는데 뭐 이정도면 사실상 오픈 스택의 핵심적인 기능들은 다하고 있다고 봐도 무방하다. Compute 내의 세부적인 구조는 다음과 같다.



    API Endpoints는 관리자가 호출한 함수가 Compute 구조와 통신하는 거의 끝 부분을 의미하는데 Queue는 사용자로부터 전달 받은 명령(API endpoint에 도착한 값)과 Compute, Nework, Volume Controller들한테서 주고 받은 메시지들을 전달해주는 역할을 한다. 가장 중요한 역할을 하는 것들은 오른쪽에 있는 세 요소들이다. 먼저 Compute Worker는 모든 instance들의 생명주기를 조절하고 Virtual Server를 생성하고 조작하는 역할을 한다. Virtual Machine의 생성 뿐만 아니라 관리까지 책임지는 역할을 한다. 나머지 두 요소는 Compute Worker의 역할을 돕는데, Network는 Virtual Machine이 사용할 Bridve, VLAN, DHCP 등등 네트워크 기능을 생성해주는 역할을 하고, Volume(Cloud에서 Volume은 스토리지를 의미한다)은 Volume의 조작 또는 할당 등등의 역할을 한다.

  2. OpenStack Imaging Service: Compute에서 Storage 서비스와 관련된 요청이 있을 때 이를 처리해주는 역할을 한다.직접 이미지를 갖고 있는 것은 아니고, Compute와 Object 사이에서 필요한 작업들을 전달하는 요소로 볼 수 있다. 주로 이미지를 Virtual Machine 디스크에 저장(recording)이나 분배(distributing)하는 역할을 한다.

  3. OpenStack Object Storage: 이름 그대로 스토리지의 역할을 한다. 공간을 생성하고 확장 가능한 형태로 만든다.


728x90

'기술 > 클라우드컴퓨팅' 카테고리의 다른 글

SDN과 NFV  (0) 2019.04.21
Kubernetes 소개  (0) 2018.06.23
오픈스택 구조 분석  (0) 2017.03.07
오픈스택이란?  (0) 2017.03.07
클라우드 가상화와 Docker  (2) 2017.03.05
클라우드 컴퓨팅(Cloud Computing)  (0) 2017.02.25

오픈스택이란?

기술/클라우드컴퓨팅 2017. 3. 7. 21:58 Posted by 아는 개발자


클라우드 컴퓨팅을 공부하면 자주 등장하는 기술이 오픈스택이다. 오픈소스의 형태로 클라우드 컴퓨팅 환경에서 많은 부분을 지원한다고 하지만, 정확히 오픈 스택이 어떤 일을 하는지, 구체적으로 어떤 목적에 의해 만들어 졌는지에 대해선 아는 바가 없어서 간단히 정리를 해보려고 한다.


오픈스택 홈페이지에서는 오픈스택을 다음과 같이 소개한다.


OpenStack is a cloud operating system that controls large pools of compute, storage, and networking resources throughout a datacenter, all managed through a dashboard that gives administrators control while empowering their users to provision resources through a web interface. 

https://www.openstack.org/software/


요약 번역하면 계산, 저장소, 네트워크 자원들을 관리하는 클라우드 운영체제라고 소개하고 있다.


하지만 위 설명은 클라우드 컴퓨팅이란 것을 알지 못하면 이해하기 어렵다. 간단하게 클라우드 컴퓨팅에 대해서 소개를 먼저 해보면,


개인이 가진 단말기를 통해서는 주로 입/출력 작업만 이루어지고, 정보분석 및 처리, 저장, 관리, 유통 등의 작업은 클라우드라고 불리는 제3의 공간에서 이루어지는 컴퓨팅 시스템 형태라고 할 수 있다. - 위키피디아


예를들면 가지고 있는 스마트폰으로 친구에게 카톡을 보낼 때 나와 나의 친구는 카톡을 보내고 받는 일만 하는 것이고, 카톡 메시지를 친구에게 효율적으로 전송하는 컴퓨팅 방식은 클라우드에서 이뤄지는 것이다.


나와 친구는 메시지를 전송/수신만 한다. 나머지는 클라우드 컴퓨팅 서버에서 모두 관리한다.


클라우드 컴퓨팅에 사용되는 서버들을 제어하려면 전문적인 하드웨어 지식과 서버를 운영하는 운영체제의 지식이 필요한데 이것은 어떤 하드웨어와 운영체제를 사용하느냐에 따라 달라 환경이 바뀔 때 마다 새로운 지식을 습득해야하는 문제가 있다.


이러한 문제를 해결하기 위해 서버의 하드웨어와 운영체제와 관계 없이 클라우드 컴퓨팅 개발의 표준을 제공하는것이 오픈스택이다.



(Hardware, Hypervisor 위에서 Shared Service의 형태로 Compute, Networking, Storage를 제어 할 수 있는 서비스를 제공한다)


Compute, Networking, Storage를 관리 할 수 있는 API를 제공하고 이를 관리하는 Dashboard를 둬서 개발자들이 쉽게 클라우드 컴퓨팅 환경에서 작업 할 수 있도록 돕는 서비스이다. 또한 Hardware, Hypervisor 관련 작업들은 모두 오픈스택이 처리하기 때문에 개발자는 Application을 만드는데 집중 할 수 있다.


현재 오픈스택 프로젝트는 집중 연구 분야에 따라서 여러 형태로 나눠진다. 


1단계는 Computing/Storage로 나눠져있고 

2단계는 오브젝트 스토리지, Compute, Image Service등으로 나뉘어져 있으며 

3단계에서는 추가적인 서비스인 Dashboard, Database등으로 나뉘어져 여러가지 프로젝트가 진행중이다.


앞으로 관심 분야에 따라서 선택해서 공부해보면 좋을것 같다.


728x90

'기술 > 클라우드컴퓨팅' 카테고리의 다른 글

SDN과 NFV  (0) 2019.04.21
Kubernetes 소개  (0) 2018.06.23
오픈스택 구조 분석  (0) 2017.03.07
오픈스택이란?  (0) 2017.03.07
클라우드 가상화와 Docker  (2) 2017.03.05
클라우드 컴퓨팅(Cloud Computing)  (0) 2017.02.25

클라우드 가상화와 Docker

기술/클라우드컴퓨팅 2017. 3. 5. 14:13 Posted by 아는 개발자

클라우드 컴퓨팅은 가상화 기술을 활용해 하나의 서버에 여러 개의 가상 컴퓨터를 돌릴 수 있는 환경을 제공해서 서버 장비가 없는 사용자들도 가상 컴퓨터를 할당 받아서 서버를 구동 할 수 있는 기술이다.




여기서 만들어지는 가상 컴퓨터를 가상 머신(Virtual Machine)이라 하고 가상 머신을 생성시키는 것을 하이퍼바이저(Hypervisor)라 한다. 서버 가상화에서 주로 사용되는 하이퍼바이저는 Xen, KVM, VMware가 있다. 이 기술들은 공통적으로 하드웨어 자원(CPU, 하드웨어, 인터럽트 핸들러 등)들을 관리 하고 Virtual Machine이 사용 할 수 있는 가상 장치를 제공한다. 장치들을 제공 받은 Virtual Machine은 갖고 있는 커널 이미지 및 루트 파일 시스템을 이용해서 부팅 및 운용 될 수 있다.


위와 같은 형태의 장점은 각각의 Virtual Machine이 독자성을 갖는다는 점이다. 호환되는 장치들만 있으면 어떤 운영체제든 돌릴 수 있다(물론 Hypervisor마다 차이가 있긴 하지만) 그리고 각 Virtual Machine이 독립적으로 운용되기 때문에 보안이 뛰어나기도 하다.


하지만 단점은 너무 무겁다는 것이다. 대부분 하나의 애플리케이션을 구동하려고 클라우드 컴퓨팅을 사용하는데 이 하나의 애플리케이션을 돌리기 위해 필요한 자원과 절차가 너무 많이 필요하다. 커널 이미지도 필요하고 가상 장치들도 할당 받아야 하고 부팅도 해야하고... 애플리케이션을 실행 시켜야 하고... 이러다 보면 시간이 다간다.


이런 오버헤드에 대한 해결책으로 나온 기술이 Docker이다.




Docker는 컨테이너 기술(Container) 기반으로 나온 오픈소스 프로젝트인데 여기서 컨테이너라 함은 소프트웨어를 구동하기 위해 필요한 환경(파일, 변수, 라이브러리, 구성요소 등등)을 갖춘 틀을 말한다. 별도 OS니 가상장치 같은 불필요한 것들은 버리고 정말 필요한 것들만 담아 두었으니 빠르게 애플리케이션을 실행 할 수가 있다.



Docker엔진은 서버 호스트 운영체제 위에서 실행되며 애플리케이션 구동이 필요 할 때마다 필요한 자원들을 제공해서 쉽게 실행 될 수 있도록 한다. 별도 장치 생성과정이나 Guest OS 부팅 과정이 없기 때문에 매우 빠르게 실행 할 수 있다. 또한 가상 장치들을 관리하는 하이퍼바이저가 없기 때문에 메모리나 스토리지 측면에서 기존 가상화 기술보다 효율이 높고 설치하기도 쉽다(물론 Hypervisor 설치하는 것에 비해서 상대적으로 쉽다는 말이지 정말 쉬운건 아닌 것 같다)


단점은 보안이다. Host OS의 자원을 사용하는 형태이다 보니 Host OS랑 분리 되지 않았고 container레벨(Docker engine)에서 침입이 발생하면 전체 Application들이 피해를 볼 수 있는 문제가 발생한다. 이런 문제점을 막고자 아예 DockerEngine을 Host OS에서 실행하는게 아니라 Virtual Machine에서 실행시키는 방법이 있는데 이러면 보안 문제는 해결 되겠지만 Host OS 자원을 써서 효율이 좋았던 이득은 취할 수 없다는 아쉬움이 있다.


또 다른 단점은 모두 동일한 OS를 사용해야 한다는 것이다. 가상화 기반일 때는 어떤 OS든 돌릴 수 있었는데(물론 Hypervisor에 따라서 다르긴 하지만) Docker Engine을 사용할 때는 모든 Application이 Host OS를 공유하니, Host OS가 사용하는 운영체제와 동일해야 구동 할 수 있다.

728x90

'기술 > 클라우드컴퓨팅' 카테고리의 다른 글

SDN과 NFV  (0) 2019.04.21
Kubernetes 소개  (0) 2018.06.23
오픈스택 구조 분석  (0) 2017.03.07
오픈스택이란?  (0) 2017.03.07
클라우드 가상화와 Docker  (2) 2017.03.05
클라우드 컴퓨팅(Cloud Computing)  (0) 2017.02.25
  1. jin 2019.10.17 18:49  댓글주소  수정/삭제  댓글쓰기

    많은 분들이 작성하신 글들을 보았지만
    정말 쉽고 깔끔하게 정리해주신 것 같아
    덕분에 이해가 말끔히 됐습니다

클라우드 컴퓨팅(Cloud Computing)

기술/클라우드컴퓨팅 2017. 2. 25. 12:58 Posted by 아는 개발자

서버 장치와 인터넷의 성능이 급격히 발전하면서 모든 연산 작업을 사용자가 갖고 있는 단말기 내에서 처리할 필요 없이 인터넷을 이용해 제 3의 공간(서버, 클라우드)에서 처리 할 수 있게 되었다. 인터넷을 이용해 필요한 컴퓨팅 자원(서버, 스토리지, 애플리케이션, 서비스)을 어디서나 접근 및 이용 가능한 형태를 클라우드 컴퓨팅 서비스라고 한다.


개념적으로만 설명하면 어려우니 쉽게 예를 한 번 들어보자. 사용자 음성인식은 컴퓨팅 연산 작업과 데이터의 양이 많이 필요한 인공지능 서비스다. 입력된 목소리 값과 비교해야 할 기존 데이터 값도 많고 사용한 알고리즘도 단순한 작업들이 아니다. 비교 데이터 값을 모두 단말기 내에서 저장하기엔 용량이 부족하고 알고리즘 연산들을 모두 처리하기엔 하드웨어 성능이 딸린다. 또한 주기적으로 서비스를 업데이트 하려면 각 개개인의 단말기 별로 데이터 값을 바꿔줘야 하는 어려움이 있다.


차라리 사용자들이 자신의 목소리가 저장된 파일을 제 3의 공간에 전달하고 거기서 목소리를 인식 필요한 연산들을 모두 수행 한 후 사용자에게 결과 값을 전달 한다면? 단말기 내에서선 필요한 연산의 양이 적게 되고, 서버 내에서는 인식에 필요한 데이터 값과 알고리즘을 독자적으로 관리 할 수 있어서 간편하다. 클라우드 컴퓨팅은 고용량 데이터 처리 연산을 제 3의 공간에서 수행 할 수 있도록 지원하는 기술이다.


(S-Voice는 클라우드 서비스로 동작하고 있기 때문에 휴대폰 데이터와 wifi를 끄면 작동하지 않는다)


물론 클라우드 컴퓨팅의 형태가 항상 이런 모델만 갖는 것은 아니다. S-Voice는 클라우드 컴퓨팅 기술을 이용해 소프트웨어를 제공하는(Saas) 서비스 모델이다. 각 사용의 목적에 따라서 크게 세가지 사용 모델이 존재한다.

  1. 서비스로서의 인프라스트럭처(IaaS): 가장 기본적인 형태의 클라우드 모델이다. 서버 하드웨어 전체를 하이퍼바이저(Xen, VMware, KVM등등)을 이용해 가상화해 사용자가 필요 할 때 마다 가상머신을 생성해 제공하는 형태이다. 여기서 만들어진 가상 머신은 하드웨어가 장착된 컴퓨터라 봐도 무방하며 로컬 환경에서 만든 작업물을 곧장 적용 할 수 있다. 이런 서비스 모델은 사용자 입장에서 경제적으로 매우 유용한데 별달리 장비를 살 필요가 없을 뿐더러 가상 머신의 하드웨어를 성능을 조정 할 수 있는 하이퍼바이저 덕분에 자신이 원하는 만큼 컴퓨팅 파워을 유동적으로 조정 할 수도 있다. AWS에서 제공하는 EC2가 가장 대표적인 예이다.

  2. 서비스로서의 플랫폼(PaaS): IaaS에서 쌩 운영체제를 제공했다면 PaaS에서는 여기에 프로그래밍 언어 실행 환경, 데이터베이스, 웹서버 같은 기능들을 넣어서 사용자들이 개발 할 수 있는 환경을 제공한다. 응용프로그램 개발자들은 별 다른 어려움 없이 소프트웨어 솔루션을 클라우드에 포팅 할 수 있다. 대표적으로 구글 APP 엔진, Heroku가 있다.

  3. 서비스로서의 소프트웨어(SaaS): IaaS와 PaaS처럼 개발 할 수 있는 환경을 제공하는 것이 아니고 단순히 서비스를 제공하는 형태이다. 대표적인 예로는 네이버 N드라이브나 구글 문서 같은 것이 있다. 특별히 단말기에 애플리케이션이나 장치를 설치하지 않아도 인터넷을 이용해 언제든지 접근 할 수 있다.

사용자가 따로 장비를 구매하고 설치하지 않아도 바로 사용 할 수 있고 게다가 컴퓨팅 파워를 자유 자재로 조정 할 수 있어 이상적인 기술 인 것은 맞다. 하지만 모든 자원들을 나의 로컬에서 관리하지 않고 다른 기업이 제공하는 서버에서 관리하기 때문에 보안의 위험이 있다. 실제로 미국의 한 연예인이 구글 클라우드에 자신의 누드 사진을 올렸다가 해킹으로 노출 되기도 했고(그래도 구글인데!), 드롭박스는 2014년에 침입으로 7,000,000건의 암호를 도난당하기도 햇다는 것을 보면 클라우드 환경에서 보안 사고들이 심심치 않게 터지고 있는 건 분명 한 것 같다. 별다른 보안 사고가 없더라도 호스팅으로 사용하고 있는 기업이 갑자기 망하거나 서비스를 중지해버리면 그동안 클라우드에 쌓아둔 데이터들은 어떻게 처리 될 지 사용자로서는 난감한 상황이다.

728x90

'기술 > 클라우드컴퓨팅' 카테고리의 다른 글

SDN과 NFV  (0) 2019.04.21
Kubernetes 소개  (0) 2018.06.23
오픈스택 구조 분석  (0) 2017.03.07
오픈스택이란?  (0) 2017.03.07
클라우드 가상화와 Docker  (2) 2017.03.05
클라우드 컴퓨팅(Cloud Computing)  (0) 2017.02.25

입출력제어(ioctl)

기술/컴퓨터사이언스 2017. 2. 11. 13:10 Posted by 아는 개발자


리눅스는 크게 시스템 영역(kernel)과 사용자 영역(user space)을 분리해서 악의적으로 만든 사용자 애플리케이션이 시스템 핵심 영역에 침범 할 수 없도록 만들어졌다. 하지만 애플리케이션을 개발하다보면 커널 영역내에 있는 함수들을 사용해야 할 일이 있는데 이런 경우 커널에서는 기본적으로 시스템 콜을 이용해 커널영역에 있는 함수들을 사용 할 수 있도록 지원한다. 하지만 시스템 콜은 기껏 해야 300개 정도 등록 할 수 있는데 모든 사용자 애플리케이션이 시스템 콜에 필요한 함수를 등록하기엔 수가 부족하다.


이때 사용 할 만한 툴이 ioctl이다. ioctl은 유저영역에 있는 애플리케이션이 현재 동작 중인 드라이버에 값을 전달하거나 받아 올 수 있도록 한다. 동작 과정을 간단히 그림으로 설명해보면 다음과 같다.


User 영역에 있는 application은 현재 등록되어있는 "/dev/[device]"파일을 open하고 필요한 명령어들을 ioctl로 전달한다. 입력한 device파일을 등록한 모듈은 이 드라이버를 등록 했을 때 ioctl command에 맞춰 처리할 루틴을 설정해두면 User에서 받아온 argument로 값을 전달 받거나 또는 다시 전달 할 수 있다.


주로 개발한 드라이버에 사용자 애플리케이션 영역에서 접근 하고 싶을 때 사용한다. 프린터에 주로 사용하는 것 같다.


728x90

자동차시장 오픈소스 - 2

기술/오픈소스 2017. 1. 31. 23:48 Posted by 아는 개발자

스마트폰 OS로 재미를 본 안드로이드가 자동차 OS까지 노리고 있다는 건 이미 잘 알려진 사실이다. 스마트폰때처럼 안드로이드는 차량 제조사(OEM)들이 제공하는 하드웨어 환경(MCU, 네트워크, 자동차 서비스)을 간단히 구조화해 여러 OEM 하드웨어 환경에서 동일하게 작동 할 수 있는 프레임워크를 제공한다.



하드웨어를 추상화해 공통된 프레임워크를 제공하는 방법을 HAL(Hardware Abstraction Layer)라 한다. HAL의 가장 큰 장점은 API화이다. 일반 사용자들은 느낄 수 없지만 API화는 개발 할 때 강력한 무기가 된다. 스마트폰의 경우를 생각해보면, 안드로이드 애플리케이션을 개발 할 때 가장 편리 했던 점은 소프트웨어 개발자가 하드웨어를 전혀 신경 쓸 필요가 없다는 점이었다. GPS 센서를 사용하고 싶다면 개발자는 그냥 Android API 홈페이지에서 GPS 센서를 사용하는 함수를 찾고 그 함수의 return값으로 현재 위치를 찾아 내면 됐다. GPS센서의 MAC Address는 뭔지, 제조사가 어딘지 세세한 부분까지는 알 필요가 없었다. 애플리케이션 개발자들은 쉽게 스마트폰의 센서 정보들을 얻어왔고 이 정보들을 이용해 다양한 애플리케이션을 만들 수 있었다.


안드로이드는 자동차도 동일한 방법으로 접근하고 있다. 차량내의 센서들(MCU, 차의 움직임, GPS, 카메라 등등)을 통제 할 수 있는 API를 제공해 차량 소프트웨어 개발자들이 쉽게 애플리케이션을 만들 수 있는 환경을 제공해주고자 한다. 여기서 파란색으로 된 부분은 차량 제조사들이 구현 할 부분인데 저마다 제조사 입맛에 맞춰서 HAL 인터페이스의 하위 부분을 구현 할 수 있도록 만들어 주었다. 거의 그림의 전부를 차지하고 있는 초록색 부분은 안드로이드 오픈소스 프로젝트에서 만들고 있는 부분이다. 제조사가 만든 HAL 인터페이스에 작동 하는 안드로이드 프레임워크를 만든다. 개발자는 프레임워크에서 제공하는 API를 이용해 쉽게 개발 할 수 있다. 소프트웨어쪽이 취약한 제조사들이 쉽게 개발 할 수 있는 환경을 제공하는게 이 프로젝트의 주된 목적으로 보인다.

728x90

'기술 > 오픈소스' 카테고리의 다른 글

오픈소스 라이센스 정리  (0) 2019.06.09
FFmpeg  (0) 2018.10.31
자동차시장 오픈소스 - 2  (0) 2017.01.31
자동차 시장 오픈소스 - 1  (0) 2017.01.15
이런 오픈 소스도 있다!  (0) 2017.01.07
오픈소스 시작하기  (0) 2017.01.01

6. XenStore, Xenbus

기술/가상화 2017. 1. 22. 13:40 Posted by 아는 개발자

Dom0의 장치드라이버인 Backend와 DomU의 장치드라이버인 Frontend가 서로 통신하기 위해선 각 상대 드라이버(Otherend) 상태와 연결 포트와 같은 정보들이 필요하다. 이런 정보들을 각 드라이버들마다 따로 정보를 관리하는 툴을 만들어서 처리 할 수 있겠지만, Xen에서는 이런 정보들을 Xenstore라는 자료구조를 통해 일괄적으로 관리할 수 있게 한다.


Xenstore에는 이런 정보들이 입력된다.



Dom0에서 xenstore-ls를 입력하면 현재 활성화된 Domain의 목록과 각 Domain들이 갖고 있는 장치들의 종류와 상태, 위치, 타입 등등을 알 수 있다. 그림을 보면 "local/domain/[domain id]/[device type]/[driver name]"처럼 경로의 형태로 관리해서 눈으로 보기도 편하다. Xen에서는 경로로 되어있는 주소 값들을 간단히 자료구조화 해서 필요한 정보들을 쉽게 제공한