2017년 12월 15일 [삽질의 시간]

어떤 아이디어를 가지고 어플리케이션 A를 만들기 시작하면 낭비되는 시간 중의 20%는 완전히 삽질에 쓰이게 된다.

 

가령 어떤 회사의 클라우드 서비스를 신청해서 모든 세팅을 마쳤는데 다른 회사의 서비스로 옮겨가야 하는 경우에 필요한 패키지를 다시 설치하는 것이다. Anaconda를 설치하고 Environment를 로드하면 이 문제에서 시간을 획기적으로 단축할 수 있는데 이 글을 쓰는 시점에서야 기억이 났다는 것이 문제다. 제대로 설치되지 않은 패키지가 전체를 망쳐버려서 오도가도 못하는 상황이 그렇고, 방화벽 설정을 했는데도 여전히 연결을 받아주지 않는 서버를 들여다보는 일도 그렇다.

 

다른 20%는 추상적인 설계로 인해서 지금까지 해 온 작업을 롤백하고 다시 돌아가는 것이다. 제대로 설계를 해놓지 않으면 프로그래밍 과정에 그 때 그 때 방향을 설정하게 되는데, 시간이 지나서 이미 짠 코드가 길어진 후에 이것이 큰 어둠의 빛을 발한다. 경험상 이 과정이 제대로 되지 않으면 절대로 프로그램은 완성되지 않는다. 계속해서 제자리를 맴돌다 지쳐버려 개발 의욕 자체가 사라지기 때문이다.

 

다른 20%는 모르는 것에 대한 삽질에 쓰인다. Android Studio를 배우거나, 새로운 라이브러리를 배우거나 익숙지 않게 리눅스를 쓰고 Python을 쓰면서 한글이 깨지는 문제 등에 대해서 삽질을 하다보면 배우는 것이 많다고 느낄 수도 있지만 정리해두지 않으면 그냥 삽질의 시간으로 지나간다.

 

이런 부차적인 작업이 끝나고 난 다음에 실제 개발에 소요되는 시간은 얼마 되지 않는 것 같다. 어플리케이션의 전체 설계와 구체적으로 필요한 클래스와 함수명, 데이터베이스의 구조가 모두 짜여져있고, 모든 API들에 대한 실행 권한과 부가적인 세팅작업이 모두 끝난 상황에서는 말 그대로 코딩만 하면 되기 때문이다. 이미 어플리케이션은 프로그램으로만 짜이지 않아서 그렇지 거의 완성되어 있다. 이 작업이 40%를 차지하는 것도 아니다. 20%의 시간은 테스팅과 최적화에 쓰인다. 20% 정도의 시간이 코딩 이외의 시간으로 쓰이는 것이다.

 

훌륭한 개발자가 무엇인지는 모르겠지만 이런 부차적인 시간을 줄일 수 있는 사람이 아닐까 싶다.

내공이 있다는 것은 왠만한 지식은 갖추고 있으며, 설계 단계부터 최적화와 성능을 고려하고, 불필요한 일들을 굳이 하지 않는다는 것이 아닐까 싶다.

2017년 12월 14일 [비]

일주일 전 정도에는 비가 왔다.

날씨가 더 추웠다면 아마 눈이 내렸을 것이다.

그 때는 웹툰인 목욕의 신을 보면서 밖에 잠깐 나간 것이었는데 많지도 않게 적당히 내리는 비를 맞으며 서 있는 것이 참 기분이 괜찮았다. 대게들 우울할 때 비를 맞으면 비참하다고 하는데, 그렇지 않을 때 적당히 비를 맞는 것은 오히려 괜찮아보인다.

이런 비는 한 동안 맞아도 흠뻑 젖지 않아 오래 맞을 수 있어 좋고, 비를 맞은 후에 세탁기에 옷을 돌려놓고 바로 목욕을 할 수 있다면 더할 나위 없지 않을까 하는 생각이 들었다.

만약 목욕탕 중에서 가운데에 큰 목욕탕을 만들고, 그 주변을 입자가속기처럼 둥글게 에워싸고 항상 비가 내리도록 만들어 사람들이 고요히 비를 맞으며 걷고 난 후 목욕을 할 수 있도록 한다면 정말 좋은 목욕탕이 될 것 같다.

모든 일은 순탄하게 흘러가고 있다. 적당히 나쁠 일 조차도 없으며, 의도한 대로만 움직인다면 정해진 미래로 나아갈 수 있는 삶을 살고 있다. 한시적인 일이긴 하지만 지금이 매우 좋으며 지금의 상태를 유지하기 위해서 기한 내에 만들기로 한 것을 끝내야겠다는 생각을 한다.

2017년 12월 4일 월요일 [새로운 디데이]

2016년에 설정했던 디데이는 실패로 끝났다.

무언가 제대로 이룬 것이 없게 그냥 시간을 흘러 보낸 것이다.

내년을 다시 바라보기에는 이제는 남은 시간이 없다. 기껏해야 최대한 시간을 미룰 수 있다면, 내년 3월이 끝나는 시점이 될 것이다. 따라서 새로운 디데이는 오늘 기점으로 118일이 되었다. 이 기한이 마지막이고 이것마저 지난다면 그 때는 새로운 결정을 할 수밖에 없다.

오늘 오전에는 해야 할 것들을 끝내놓고, 다시 뭔가를 만들기 위해서 자리에 앉아있다. 네트워킹은 어려운 일처럼 보인다. 실시간 스트리밍 데이터는 더욱 그렇다. 오늘도 만 걸음은 걸어야 한다.

프로그래밍 대회를 위한 알고리즘 [1] – Tarjan’s Algorithm

본 포스팅은 geeksforgeeks의 http://www.geeksforgeeks.org/tarjan-algorithm-find-strongly-connected-components/ 를 통해 제작된 것입니다.

 

알고리즘 설명

Tarjan’s Algorithm은 그래프에서 Strongly Connected Component (SCC)를 찾아내기 위한 알고리즘이다. 여기에서 SCC란 유향간선(양방향 통로가 아닌 단방향 통로)으로 구성된 그래프 중에서도 모든 정점 쌍 사이에 경로가 존재하는 그래프를 말한다. 예를 들어 아래의 그래프에서는 그림과 같이 3개의 SCC가 존재한다.

Tarjan’s algorithm은 다음과 같은 사실들에 근거한다.

  1. DFS 탐색은 DFS 트리를 만들어낸다.
  2. SCC는 DFS의 subtree를 구성한다.
  3. 만약 그러한 subtree의 head를 찾을 수 있다면, 해당 subtree의 모든 노드를 출력할 수 있다.
  4. 하나의 SCC로부터 다른 SCC로 돌아가는 back edge는 존재하지 않는다. (서로 다른 SCC는 사이클을 이루지 않는다는 말인 듯.)

 

SCC의 head를 찾기 위해서 disc와 low 배열을 사용한다. disc[u]는 탐색에서 u를 방문한 시간이며, low[u]는 u를 root로 한 subtree에서 도달할 수 있는 가장 일찍 방문된 정점의 방문 시간을 의미한다.

즉, 어떤 SCC의 head란 disc[u] == low[u]인 노드를 의미한다. SCC에 속한 다른 노드의 경우 disc[u] > low[u]이다.

알고리즘의 동작은 다음과 같다.

  • 그래프 G에서 아직 방문하지 않은 노드 u를 하나 선택한다.
    • 노드 u를 Stack에 집어 넣는다.
    • dist[u] = 현재 노드를 방문하는 시간, low[u] = dist[u]
    • u로부터 이동가능한 SCC에 속하지 않은 노드 v를 탐색한다.
      • 만약 방문하지 않은 노드라면 해당 노드로 DFS를 호출한 후에 low[u] = min(low[u], low[v]) 이다.
      • 만약 이미 방문한 노드라면 low[u] = min(low[u], disc[v])이다.
    • 탐색 종료 후 disc[u] = low[u]이면
      • 노드 u는 SCC의 Head이다.
      • Stack에서 u까지를 pop하여 SCC를 구성한다.

이 알고리즘은 모든 노드를 모든 엣지를 통해서 단 한번만 방문하기 때문에 O(V + E)의 시간 복잡도를 갖는다.

 

코드 (원본 : geeksforgeeks)

 

 

2017년 11월 27일 월요일 [D – 4]

 

퇴근을 한 후에는 항상 피곤하다. 요즘에는 낮잠을 자도 많은 꿈을 꾼다. 점심 늦게 일어나 뭔가 먹으려다가 여자친구와 이른 저녁에 약속이 있어 그만두고 블로그 정리를 했다. WordPress에서는 LaTeX와 Markdown을 가능하도록 만드는 플러그인들이 있어서, 이전 블로그 보다는 깔끔하게 표현이 기능해서 좋다. Google Cloud에 서버를 두고 아예 설치해서 WordPress를 쓰는 것이라 이전에 웹 호스팅 버전보다는 훨씬 유연하게 쓸 수 있는 것 같다.

 

하루에 만 걸음 정도라도 꾸준히 걷기 위해서 노력하고 있는데, 오늘은 저녁을 많이 먹어서 한 2시간 정도를 여자친구와 함께 걸어서 만 걸음을 채웠다. 사용하고 있는 어플리케이션은 그 정확도가 상당히 이상한데 어떤 경우에는 많이 걸어도 카운팅이 적게 되고 어떤 경우는 적게 걸어도 카운팅이 많이 된다. 가속도계 값이나 Google Fitness 둘 중 하나를 쓰는 것 같은데 내 생각에는 단순히 흔들리는 정도로만 판단해서 큰 동작없이 천천히 걸었던 걸음들은 제대로 기록하지 못하는 것 같다. 반면에 농구를 하거나 운전을 하거나 가속도 변화가 큰 상황에서는 매우 크게 증가해버린다. 이걸 삭제하고 내일부터는 다른 앱을 써봐야겠다.

 

정리를 하는 것은 나쁘지 않은 일이다. 다만 실제 학습이나 풀이 기간과 포스팅 기간에는 차이를 좀 두는게 좋겠다. 풀이 후에 즉시 포스팅을 해버리면 빠르게 정리는 되지만 복습이 전혀 되지 않아 기억에 남질 않는다. 오늘 한 일이라고는 대회 문제 복습과 운동 뿐이다. 그래도 어떤 형태로든 운동은 꾸준히 할 생각이다.

 

오늘 요약

  • 대회 풀이 정리 : 3시간
  • 운동 (걷기) : 2시간

2017년 11월 26일 [D – 5]

아마도 작년 5월 쯤에 교육원에서 세팅한 디데이는 이제 5일이 남았다.

그 많던 날들이 5일까지 줄어드는 동안 세상도 변하고 참 많은 것들이 변했다.

알고리즘 실력은 전과 큰 차이가 없다고 생각했지만 가끔 KOI 문제를 풀어보면 이전보다는 많이 발전했다는 것을 느낀다.  물론 내 레이팅을 바꿔놓을 정도로 큰 차이는 아니다. 복습 할 알고리즘도 많고, 더 풀 문제들도 많다. 그나마 다행인 것은 프로그래머의 채용 방식이 프로그래밍 대회 형태로 바뀌고 있다는 점이다.

세상의 변화는 훨씬 빠르다. 10년 정도 남았다고 생각했던 기술들은 훨씬 더 빠르게 등장하고 있다. 이것이 가져올 사회의 변화는 알 수 없다. 하지만 초기 산업 혁명이 사람들의 우려와 달리 새로운 시대를 열었던 것처럼, 다시 새로운 시대가 열릴 수도 있는 일이다. 새로운 시대와 환경에서, 그 환경에 적합한 사람들이 새로운 기회를 잡을 수 있을지도 모른다.

하지만 그 미래를 알 수 없는 현재에서는 매우 불안할 따름이다.

확실한 것은 내가 가진 선택지들 중에서 안정적인 것은 아무것도 없다는 것 뿐이다. 그렇기에 내가 할 수 있는 일이란 더 좋은 선택지들을 위해 노력하는 것 뿐이다. 지난 시간들에서 아쉬운 점은 지나온 하루하루들에서 내가 무엇을 했는지 아무런 기억도 나지 않는다는 것이다.

여기에서의 일이 끝나는 시점은 내년 5월이다. 아마도 3월까지는 시간이 있으며 그 전까지는 단기간의 진로에 대해서는 준비가 되어 있어야 할 것이다. 그리고 그 기간에 내가 무엇을 하였는지의 기록도 반드시 필요하다.