태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

그동안 아무것도 하지 않아 아무 일도 일어나지 않았다. '부딪혀라 짜릿하게'라는 말에 용기를 내어 그동안 망설이고 주저했던 일에 이번이 마지막이라는 심정으로 부딪혀 보았다. 다행히 생각보다 어렵지 않았다. 물론, 아직 실제로 이루어진 것은 아무것도 없지만, 도전하기 위해 문을 두드렸고 그 문이 자물쇠로 꽉 잠겨 있는 것은 아니었다는 점에 희망을 품어보고 용기를 내본다.

'[순보의 일기장]' 카테고리의 다른 글

[2017.03.25] 한 끗 차이  (0) 2017.03.26
[2016.04.07] 익숙함  (0) 2016.04.08
[2016.03.30] 시작이 반이다  (0) 2016.03.31
[2016.03.12] 알파고와 인공지능  (0) 2016.03.12
[2016.03.08] 온라인 강좌  (0) 2016.03.09

아무 일도 일어나지 않고 있는 나에게 한마디 하는 광고. 다만 요즘 우리나라 젊은이의 삶이 힘든 것이 그저 부딪치지 않아서만은 아닐 것 같다.

'[일상의 한마디]' 카테고리의 다른 글

주거 환경 개선 프로젝트  (8) 2017.03.20
온라인뱅크 보안 프로그램...  (0) 2016.04.05
부딪쳐라 짜릿하게  (0) 2016.03.18
미국 서부 여행  (0) 2014.10.06
알면 쉽고 모르면 몸이 고생...  (1) 2014.02.05

주어진 연결 리스트에서 일부분을 뒤집는 문제를 생각해보자. 연결 리스트에 [1, 2, 3, 4, 5]라는 값이 들어있고 2번째부터 4번째 사이를 뒤집는다고 하면, [1, 4, 3, 2, 5]가 된다. 연결 리스트 전체 뒤집기 문제보다 조금 더 생각할 거리가 있다.

전체 뒤집기와 다른 점은 뒤집기 경계에 있는 노드 정보를 기억해야 한다는 점이다. 뒤집기 부분 바로 직전 노드를 A라고 하고, 뒤집기 부분이 시작되는 노드를 B라고 하자. 그리고 뒤집기 부분이 끝나는 노드를 C라고 하자. 그러면 다음과 같이 처리해야 한다. 물론, 뒤집기 부분을 뒤집는 방법은 연결 리스트 전체 뒤집기와 같은 방법으로 처리해야 한다.

A.next = C
B.next = C.next

[1, 2, 3, 4, 5]의 예로 돌아가 보자. 뒤집기 부분은 [2, 3, 4]이다.  현재 노드가 가리키는 다음 노드가 현재 노드를 가리켰던 이전 노드가 되도록 하면 된다. (1) A노드는 1이므로 C노드인 4를 가리켜야 한다. (2) B노드는 2이므로 C노드의 next 노드인 5를 가리켜야 한다.

Before: 1[A] -> 2[B] -> 3 -> 4[C] -> 5
After: 1[A] -> 4[C] -> 3 -> 2[B] -> 5

개념은 위와 같다. 한 가지 주의해야 할 점은 뒤집기 부분이 첫 노드부터면 A노드가 실제로 존재하지 않고 head가 직접 C를 가리키게 해야 한다. 따라서 head가 C를 직접 가리키거나 A.next가 C가 되게 해야 한다. 이때 인자로 넘어온 head 값을 변경하기 위해서 포인터의 포인터를 사용해야 한다.

void reverseBetween(ListNode** head, int m, int n) {
	ListNode* cur = *head, *prev = *head, *start = NULL, **end = head;

	for (int i = 1; i < m; i++) {
		end = (ListNode**)&(cur->next);
		prev = cur;
		cur = cur->next;
	}
	start = cur;

	for (int i = m; i <= n; i++) {
		ListNode* nextnode = cur->next;
		cur->next = prev;
		prev = cur;
		cur = nextnode;		
	}
	start->next = cur;
	*end = prev;
}

풀기도 쉽지 않았는데, 설명하기는 더 어렵다.

구글이 2014년에 인수한 딥마인드가 개발한 인공지능 바둑 프로그램인 알파고와 최고의 프로 바둑 기사 중 한 명인 이세돌 9단의 바둑 대결로 나라가 시끄럽다.

터미네이터 같은 SF 영화의 학습 효과 때문인지 기대보다는 우려의 목소리가 크다. 미래에는 많은 직업이 인공지능에 의해 대체된다고 한다. 이러한 기술 발전이 인류 전체의 부를 증가시켜 궁극적으로 모든 사람이 잘사는 미래가 올까?

'[순보의 일기장]' 카테고리의 다른 글

[2016.04.07] 익숙함  (0) 2016.04.08
[2016.03.30] 시작이 반이다  (0) 2016.03.31
[2016.03.12] 알파고와 인공지능  (0) 2016.03.12
[2016.03.08] 온라인 강좌  (0) 2016.03.09
[2016.03.03] 프레젠테이션  (0) 2016.03.04

돈 없어도 마음만 먹으면 공부하기 쉬운 세상이다. MOOC(Massive Open Online Courses)라는 이름으로 국내외 유수의 강의가 공개되어 있다. 수료증을 받으려면 돈을 내야 하는 경우가 많지만, 수료증을 받지 않더라도 콘텐츠의 상당 부분은 활용할 수 있어 좋다. 오프라인 학교 강의보다는 강제성이 없어 웬만한 의지로는 지속하기 어렵다는 문제가 있지만, 온라인 강의 특성상 반복 학습이 가능한 장점이 있다. 초창기와는 다르게 오프라인 강의를 녹화한 것이 아니라, 온라인용으로 새로 콘텐츠를 제작했기 때문에 온라인 학습에 적절한 형태를 갖추고 있다.

그동안 수많은 강의를 신청했었다. 끝까지 마무리 지은 적은 두 번에 불과하다. 그것조차도 강의는 제대로 듣지 않고 문제만 열심히 풀어서 수료한 경우이다. 최근 다시 강의를 듣기 시작하면서 목표를 바꿨다. 무조건 한 번에 한 과목만 수강하고, 아무리 진도가 느리게 나가더라도 내용 이해를 목표로 하기로 했다. 진도가 너무너무 느리게 나갈 가능성이 있다. 하지만, 진도를 빼는 것을 목적으로 하는 것보다는 남는 게 훨씬 많을 것이다.

스탠퍼드가 개설했던 Mining Massive Datasets라는 강의를 듣기 시작했다. 총 7주 코스인데 이제 1주차를 거의 마무리했다. 대용량 데이터 분석에 사용되는 MapReduce, 구글 검색 엔진의 기초가 되는 PageRank에 대해 배웠다. 프로그래밍 과제가 PageRank 알고리즘을 구현해서 약 80만 개의 node와 500만 개의 edge에 대한 정보에서 PageRank를 계산하는 것이다. c++로 여차여차 구현해서 답을 맞히기는 했는데, 너무 느리다. 시간을 두고 개선을 해봐야겠다. 퀴즈 문제도 4문제를 풀었는데, 한 문제를 빼고는 문제 이해도 제대로 못 하고 사람들이 discussion한 내용을 참고해서 겨우 답을 이해했다. 재미있기는 한데, 너무 느리다. 점점 빨라지려나?

목요일 저녁마다 무료 영어 수업에 참석한다. 아카데믹 영어에 관심이 있는 사람을 대상으로 여러 표현과 주제를 다룬다. 그렇다고 엄청나게 특별한 내용을 다루지는 않지만, 개인에게 말할 기회를 많이 주므로 영어 말하기에 꽤 도움이 된다. 이번 주에는 각자 10분 분량의 프레젠테이션을 준비하여 발표했다. 프레젠테이션을 하며 몇 가지 느낀 문제점은 다음과 같다.

첫째, 발표 직전까지도 내용 정리가 안 된다. 구성의 문제가 아니다. 설명의 깊이와 범위를 명확히 정하지 못한다. 연습할 때는 너무 자세히 말하느라 시간이 부족하다. 실제 발표에서는 마음이 급해져 하려던 설명을 빠뜨린다. 자료를 잘 준비했더라도 설명이 전혀 유기적이지 않게 느껴진다.

둘째, 더 과감히 버리지 못한다. 발표 준비를 하다 보면 많은 내용을 넣고 싶다. 제한된 시간을 고려하면 내용을 줄여야 한다. 한 슬라이드에 들어가는 내용이 너무 많으면 보기에 안 좋다. 많은 내용을 더 쳐내야 한다. 그래도 발표하면서 `이미 이 슬라이드를 설명하는 데 많은 시간이 들었는데, 아직도 설명할 내용이 있네. 저 내용이 여기에 있지 않았으면 좋을 텐데.'라는 생각이 꼭 드는 것은 왜일까?

셋째, 연습이 부족하다. 어떻게 연습해야 하는지 모르겠다고 하는 게 정확한 표현이다. 예전에는 스크립트를 만들어 외우려고 했다. 실제로는 다 못 외워서 스크립트를 직접 보고 했다. 바람직하지 않은 방법이고 기억에 부담도 상당해 자료를 보고 그냥 말을 몇 번 해보는 식으로 연습했다. 이 방식을 하려면 그 발표에 익숙해져야 한다. 연습을 많이 해서 어떤 말을 하려고 할 때 유창하게 나와야 한다. 하지만, 현실은 부족한 연습 탓에 적당한 단어도 떠오르지 않는다. 문장도 제대로 구성되지 않아 반복해서 수정한다. 버벅거린다.

발표를 촬영한 동영상을 나중에 공유해 준다고 한다. 차마 눈뜨고 보기 어렵겠지만, 보고 나면 더 많은 문제점을 볼 수 있을 것이다.

도서관에서 텍스트 마이닝을 위한 데이터 세트 처리에 관한 내용을 다룬다고 해서 다녀왔다. 수업 내용은 웹 스크래핑하는 법을 아주 기초적인 수준에서 다루었다. HTTrack이라는 프로그램을 소개했다.

10년 전쯤에는 어디에서나 컴퓨팅할 수 있는 것을 목표로 너도나도 유비쿼터스라는 용어를 썼다. 요즘도 IoT(사물 인터넷)나 CPS(사이버 물리 시스템) 같은 연구가 계속되긴 하겠지만, 스마트폰의 대성공으로 불과 10년 전보다 대중의 삶 속에는 이미 어마어마한 수준으로 유비쿼터스 컴퓨팅이 깊이 자리 잡았다.

요즘은 빅데이터 시대다. 검색 이후 제2의 웹 혁명을 일으킨 소셜 네트워크와 현재의 컴퓨팅 환경에서 나오는 엄청난 데이터 홍수 시대에 살고 있다. 모든 학문과 산업에서 데이터와 연관되지 않은 일을 하면 뒤처진 것처럼 보이는 시대이다.

오늘 수업에서 새롭게 배운 내용은 특별히 없지만, 빅데이터가 아름다운 데이터보다 가치 있지 않다(Big data is less valuable than beautiful data)는 말이 기억에 남는다. 수많은 모래알 속에서 진주를 발견하는 일이 중요한 세상이다.

PhillyJS meetup에 다녀왔다. meetup은 인포멀한 모임을 통칭하는 것으로 다양한 주제에 관심이 있는 사람들이 스스로 모임을 만들어 정기적으로 만난다. 최근에 우리나라에도 다양한 기술 meetup이 생겨난 것으로 알고 있다. 이번 달 PhillyJS 모임(JavaScript)이 집에서 무료 버스를 타고 갈 수 있는 위치에서 열린다는 사실을 알고 다녀왔다.

이번 달 주제는 크롬 개발자 도구다. 회사에 다닐 때 꽤 많은 시간을 함께했던 반가운 녀석이다. 그뿐만 아니라 온갖 사이트에서 웹 페이지에 쳐놓은 장난을 무력화시키거나, 웹 페이지에 직접 장난을 칠 때 아주 유용한 도구이다. 2000년대 중반 웹을 하다가 2010년대 이후 웹을 다시 만났을 때 나를 가장 놀라게 한 것 중 하나가 이 개발자 도구였다.

생활 속에서는 틈틈이 썼지만, 지난 반년 간 전문적으로 개발자 도구를 사용한 적이 없어서인지 많은 변화가 있는 것처럼 느껴졌다. 한동안 크롬만 썼는데 까나리(canary) 버전을 가지고 설명해서 더욱 그렇게 느끼는 것일 수도 있겠다. 나는 security 패널 같은 게 원래 있었는지 새로 생긴 것인지도 가물가물한 정도가 된 데다가 설명하는 사람이 여러 개발자 도구의 옵션을 하나하나 짚어서 설명해주니, 이전에도 모르고 사용하지 않았던 기능이 꽤 많이 있었을 것 같다는 착각인지, 진짜인지 모를 생각이 강하게 든다.

자세한 내용은 크롬 개발자 도구 문서를 참고하면 될 테고, 오늘은 첫 meetup에 참석해서 보고 느낀 사항을 몇 가지 정리해 보아야겠다.

첫째, 굉장히 다양한 사람들이 모였다. JavaScript에 대한 모임인데, 전형적인 긱(geek) 스타일을 한 젊은 개발자부터, 전혀 개발하지 않을 것 같이 생긴 할아버지, 현재 개발을 하고 있지는 않지만, 개발자가 되고 싶은 사람 등 많은 사람이 모였다. (많이 가보진 않았지만) 우리나라에서 개발자 모임에 가보면 대개 20대 중반에서 30대 중후반이 주류를 이루고, 아주 오래 한 사람들이 40대 초반 정도라는 점과 대비된다.

둘째, 지나치리만큼 상세하고 친절하게 설명한다. 물론 새내기(newbie)를 위한 내용이었다지만, 이렇게 옵션 하나하나 사소한 내용까지 설명해주는 게 신기했다. 회사에서 개발자 도구를 많이 써야 할 필요가 생기면 각자 찾아보고 직접 해봐야 했다. 누가 물어보면 누군가 알려주지만, 간단한 내용이 체계적으로 교육되지 않아 낭비되는 자원이 많았다. 이런 내용을 한두 시간 정도만 정리해서 자세히 전달해줬다면, 낭비되는 시간도 없고 모두 행복했을 것이다.

셋째, 애플, 맥북 천하이다. 기본 설명이 맥북 위주이다. Ctrl, Alt 키가 아니라 Cmd (커맨드) 키 위주로 설명이 돌아간다. 개발자 십중팔구가 맥북을 쓴다. 회사에 다닐 때 출장 나가면 많이 보던 광경이지만 단축키를 설명할 때 Cmd 키로 설명하니 낯설다.

테이블에 앉은 사람과 몇 마디를 해봤는데, 비영리 단체에서 사이트 개발 업무를 하고 있다고 한다. AngularJS를 사용해서 동적인 메뉴 같은 것을 만드는 일을 한다고 보여주기도 했다. 회사에서 지난 2~3년 동안 애니메이션 한다고 매일 하던 것과 만드는 대상은 비슷하다.

잘하고 싶은 마음은 굴뚝 같지만, 나는 알고리즘에 굉장히 취약하다. 학부 때 중간고사에서 바닥을 깔아 전공 공부에 심각한 회의를 들게 만든 과목이 바로 알고리즘이었다. 안에서 새는 바가지 미국에서도 샌다고 마지막 학기라 단 한 과목만 들었던 학기였음에도 여기에서도 (아마도) 꼴찌였다.

머리가 나쁜 것이 원인이라고 말하고 웃어넘길 수 있겠지만, 알고리즘을 새롭게 디자인하는 것도 아니고 알려진 알고리즘을 활용하여 프로그램을 작성하는 수준이라면 왜 나는 못 하는 것일까? 이번 기회에 구체적으로 원인을 따져보면 해결책이 있지 않을까 해서 글을 써본다. 떠오르는 문제가 크게 3가지 있다.

첫째, 재귀적 사고력(recursive thinking)이 부족하다. 많은 문제가 재귀(recursion)로 풀면 쉽게 풀린다. 회사에서 문제 풀이(problem solving)를 한 적이 몇 번 있다. 여기에서 나는 놀란 점이 사람들이 꽤 재귀적 사고에 익숙하다는 점이었다. 재귀 방식의 장점은 풀이가 직관적이라는 것이다. 그런데 나는 그것이 쉽게 되지 않는다. 풀이를 보고 쉽게 이해되지도 않는데, 내가 그렇게 프로그램을 짜는 것이 얼마나 어려운 것인지는 말 안 해도 알 것이다.

둘째, 고집과 아집으로 인해 다른 접근 방식을 생각해보지 않는다. 물론 초기에는 이러저러한 접근 방식을 고려하지만, 어느 정도 방향이 보일 때 접근 방식에 대한 더 이상의 유연함이 없다는 점이 큰 문제이다. 정답이 다른 접근 방법으로 풀었고 훨씬 간단할 때 뼈져리게 느낄 수 있다. A 접근으로 해결책이 나오지 않으면, B 접근은 없을지 생각해보아야 하는데 그러지 않는 경우가 많다.

셋째, 세심하지 못하다. 경계 검증(binary check)을 참 못한다. off by one error와 같은 기본 문제를 발생시키지 않는 경우가 없다. 문제에 대한 해결책이 떠올라도 실제로 돌려보면 오답이 나오는 경우는 십중팔구 이 문제를 해결하지 못해서다. 툭하면 배열 인덱스를 벗어나 런타임 오류를 발생하는 원인이다.

위 문제들을 해결하는 방법이 딱히 있는지 모르겠다. 셋째의 경우 의도적으로 종이에 써서 하나씩 알고리즘을 완성하고 경계 검증까지 해보려고 하는데 그것도 쉽지 않고, 수차례 해서 오류가 나면 짜증이 날 뿐이다. 침착하고 정확하게 하기보다는 대충 빨리 풀고 오류를 고쳐나가는 try and error 방식으로 모든 문제를 풀어왔던 게 이런 문제를 일으킨 하나의 문제이기도 하다.

그렇다고 손 놓고 있을 수는 없으니, 앞으로 오랜 시간에 걸쳐 공부해나가면서 개선되는 점이 있으면 그러한 방법을 공유해 보도록 해야겠다. 나처럼 머리가 나빠서(?) 알고리즘과 같은 문제를 풀어내고 싶은데 고생하는 사람들이 많이 있을 테니 말이다.

+ Recent posts