해커와 화가의 저자이자 벤쳐창업도우미로 유명한 폴그레이엄의 이 글은 저에게 하는 말인거 같아서 뜨금하네요.  물론 비지니스측면에서 말을 하고 있지만 엔지니어 측면에서 바라봐도 마찬가지인거 같습니다.

퍼포먼스,탄력성,유연성,신기술 보다는 고객이 원 할 수 있는 작은 기능하나에 더 관심을 쏟아야 할 거 같다는..



원글 : http://paulgraham.com/ds.html

요약번역원본 : http://nextransblog.blogspot.kr/2014/06/paul-graham-do-things-that-dont-scale.html


[주요요약] Paul Graham - 규모가 안 나오는 일을 해라 (Do Things That Don't Scale)


개요:
1. 사람들은 많은 선택권을 가지고 있기 때문에 굳이 벤처의 제품을 써야할 필요가 없음.
2. 따라서 사람들이 벤처의 제품을 사용하도록 설득하는 수동적인 노력을 기울여야 함.
3. 그러나 수동적인 노력은 규모가 안 나올거라고 지례짐작 하기 때문에 시도조차 하지 않는 경우가 많음.
4. 하지만 수동으로 노력을 기울여야 유저가 증가하고, 그 유저를 통해서 제품이 개선되고, 다시 유저들이 증가하는 식의 선순환이 이어지다가 언젠가 critical mass에 도달하면서 자동으로 회사가 성장해가는 momentum이 발생하기 시작함.


이후 자세한 충고의 말들은 원글이나 요약번역원본에서 참하시라~


현재 작성된 이 포스트는 나중에 다양한 원인에 의해 수정될 수 있으며 ,100% 정확한 정보를 담고 있지 않을 가능성이 있다라는 것을 먼저 말씀드립니다.



" 막힘없이 흘러다니는 데이터(이벤트)를 통해 사용자에게 자연스러운 응답을 주고, 규모 탄력적으로 리소스를 사용하며 실패에 있어서 유연하게 대처한다" 


서론

현재 페이스북 및 각종 세미나들을 보면 딥러닝을 위시한 데이타분석 기술들이 점령하고있다. 물론 그러한 것들의 인기를 그닥 나쁘게 볼 필요는 없지만 다만 아쉬운점은 너무 편중되었다는 것이다.

특히 서버기술들은 모든 IT 서비스들의 허리를 이루는 중추인데 별로 관심을 못받는거 같아 아쉽다. 그래서 웹개발/서버 서비스 개발 방법론으로 떠오르는 Reactive 에 대해서 간단히 정리 하여 써보려한다. 먼저 고백하자면 나는 이 분야의 경험이 많은 수준높은 개발자는 아니다. 이 흐름에 먼저 올라타서 함께 가자고 독려하는 동료일뿐..

Reactive 기술의 아이디어는 1980년대에 논문("On the Development of Reactive System") 이 나왔고,1990년대, 2000년대초반에 이미 저수준은 제공되고 있어왔다. (Select, ePoll, IOCP등 네트워크 비동기화에서 부터 쓰레드의 추상층등) 그런것들을 토대로 자연스러운 데이터흐름을 다루는것에 대한 벽돌이 쌓아 올려져 RxJava, Node.js, Play(Akka Streaming), Microsoft Reactive Extensions 등이 생겨났다.

Rest API 를 통해 자신들의 데이터를 외부로 서비스 하는 회사(예: 트위터,사물인터넷,주식관련등)들이 많아 지면서 그러한 서비스들의 데이터 흐름을 이용 할 수 있는 장도 마련되었다.

아주 오래전에 만들어진 신경망 논문(기술)이 지금 쉽게 사용할 수 있는 툴 등의 등장으로 더욱 활발하게 활용,시도하는 것 처럼 Reactive 도 이제 본격적으로 대중화 되기 위한 만반의 준비를 갖추고 날아오를 준비를 하고 있다.

모델2

지금까지 웹개발은 한번 개발 파라다임이 변화했는데 그것은 객체지향 설계가 전폭적으로 반영된 MVC 패턴 기반의 방식이었다. 저레벨에 대한 변화라기 보다는 1. 유지보수하기 편한 공통화된 설계 방식 - 역할에 따른 분리 2. 객체지향의 정점을 고스라니 물려받음 등에 있다. 이 분야에 관련된 대표적인 저술인 PEAA (엔터프라이즈 어플리케이션 패턴-마틴파울러) 의 패턴들을 보면 그 색채가 아주 뚜렷히 나타난다.

참고로 PEAA에서 다루는 내용은 아래와 같다. 

◎ 엔터프라이즈 애플리케이션을 여러 계층으로 분할하는 방법
◎ 비즈니스 논리를 구성하는 여러 주요 방식
◎ 객체와 관계형 데이터베이스 간 매핑에 대한 심도 깊은 논의
◎ 모델 뷰 컨트롤러를 통한 웹 프레젠테이션 운영
◎ 여러 트랜잭션에 걸친 데이터의 동시성을 처리하는 방법
◎ 분산 객체 인터페이스 설계

물론 이러한 모델2가 모델1보다 무조건 좋은것은 아니다. 적절한 사용처가 따로 있을뿐. 이 논리는 그대로 Reactive 까지 이어질 것이다. 즉 모든것에 Reactive 를 적용할 필요는 없다는 말이다. (예를들어 나는 웬만한것들은 그냥 멀티쓰레드기반의 소켓통신을 사용한다. IOCP 를 직접사용하거나 boost asio 라든지 Java NIO2,  Python Twisted 같은 라이브러리등도 정말 그게 꼭 필요하다 싶을 때 아니면 손대지 않을 것 같다.)


Reactive 파라다임

한마디로 표현하면 "막힘없이 흘러다니는 데이터(이벤트)를 통해 사용자에게 자연스러운 응답을 주고, 규모 탄력적으로 리소스를 사용하며 실패에 있어서 유연하게 대처한다" 이다. "모든 지점에서 블럭 되지 않게 하자." 로 더 짧고 개발자 친화적으로 설명할 수도 있을 거 같다.

이렇게 먼가 중간 중간 끊어지는것이 아니다.

연속된 비동기의 흐름이 연속되게 이어지는 것이다.


Reactive 파라다임은 저레벨부터 시작한다. 일단 비동기적인 통신모델이 필요하다. 그 역할은 Netty 등이 하고 있으며 그 위에 데이터흐름을 처리하는 것에 대한 설계지침 및 도우미 기능 (Observerble, Future, await, Actor,Reactive Streaming등)이 얹어졌다.최종적으로그러한 것을 처리하는 풀스택개발환경인 Akka, Play,Node.js와 형제들이 나타났고..(Spring 도 최신버전에서 열심히 변화하려고 하고 있는 듯하다. 하지만 과거의 영광이 발목을 잡지 않을까..현재는 Play ,Akka 가 가장 잘 지원하고 있다라고 생각된다.)

즉 응용개발자들이 신경쓰지 않아도 될 만큼 저레벨 부분에 대한 수준높은 추상화가 드디어 이루졌다라는 것이며 이제 그것을 가져다 사용하기만 하면 된다. ( 사실 쉽게 말했지만 시퀀셜한 로직보다 이해하기 어렵긴 할 것이다...내가 순수함수형 개발이 대중화 될 가능성이 0%라고 항상 말해왔다시피.. 이 Reactive 파라다임이 어떻게 대중에게 받아드려질지에 관해서 또한 귀추가 주목된다.)


참고:  비동기 그리고 Reactive 파라다임의 권위자이신 Erik Meijer (LINQ 설계자)의 reactive 개념 동영상 

https://www.youtube.com/watch?v=sTSQlYX5DU0

동영상에서 그의 목소리가 떨리는 이유는 다음 글에서 찾을 수 있을거 같다.

임백준 작가의 Erik Meijer 에 대한 헌시 

Erik Meijer 의 한마디

“이보게, 브라이언 괴츠, C#, 파이선, 자바스크립트는 물론, 심지어 PHP도 async, await를 지원하고 있다네. 그런 기능이 없는 언어는 자바일 뿐이야. 람다를 이용해서 콜백callback 함수를 사용하면 된다고? 천만에. 콜백은 최악이야. 도움이 안 된다고. 자바 9 버전에 담으려고 하는 걸 다 내려놓고 지금 당장 async, await부터 넣으라고. 그래야 모두가 행복해질 수 있어.”

completableFuture 는   -.-a


Reactive 선언문

http://www.reactivemanifesto.org/ko


Reactive 의 4가지 주요 속성

요약하면 아래와 같다.

- Responsive : 사용자에 대한 반응(React)

- Scalable(Elastic)  : 부하(road)에 대한 반응(React)

- Resillent : 실패상황에 대한 반응(React)

- Event-driven : 이벤트에 대한 반응(React)


각각에 대해 좀 더 살펴보자.


Responsive
쉽게 말해서 웹브라우저의 사용자가 한참을 기다리지 않게 하는 것이다. 즉 정해진 시간안에 반드시 결과를 받아 볼 수 있게 하자는것. 그 결과가 진짜 결과가 아니라 " 지금 처리중입니다~~~" 라는 메세지일지라도.

추가적으로

우리가 엑셀을 사용 할때 A 가 =SUM(B1,C1)  이것이라면 , C1 의 값을 97로 변경하면 자연스럽게 A 는 100이 될것임을 알 수 있다. 이것처럼 우리가 어떤 행동을 했을 때 자연스럽게 사용자에게 반응하기 위한 노력을 하자는 의미로 볼 수 있다.



Scalable(Elastic)

익히 알고 있는 규모 변경성질이다. Scalable 은 주로 확장의 의미가 있기 때문에 요즘은 확장되었다가 다시 축소도 시킬 수 있다는 의미로 Elastic 을 사용하기도 한다. 어플리케이션을 수평확장시키는 방식은 여러모로 굉장히 어려운 도전이긴하다.

서버사이드쪽의 유저 세션 또는 캐쉬등의 복제가 필요로하며, 데이타베이스 레벨에서는 다양한 복제시나리오 (master to master 등) 가 추가되어야 할것이다. Deployment 할 때의 추가 복잡성도 굉장히 클거라 본다. 다양한 AWS 서비스 및 Docker의 등장등 Reactive 파라다임의 가는 길에 좋은 도우미도 같이 발전하고 있다.


Resillent

New York 주식거래소는 2012년 8월 1일에 오전 9:30분에 개장을 했었을때, KCG 의 자동 거래 소프트웨어는 자동적으로 주식거래를 시작했고 오랫동안 일을 완수하고 있었습니다. 몇일전에 어플리케이션의 새로운 버전이 서버에 적용되었고 새로운 추가기능이 돌아가기 시작했습니다.  그 날은 먼가 이상한 조짐을 보였고 마켓이 열린지 45분후에 완전히 맛이 갔습니다. 440밀리언달러의 손실을 만들어내었습니다.

버그가없는,실패하지 않는 소프트웨어를 만드는것은 거의 불가능에 가깝다.  이러한 실패를 피해 완벽한 프로그램을 개발하는 것 보다 reactive 파라다임은 실패를 포함하는 설계를 하도록 한다. 즉 충돌하게 내버려둬~~ 라는 철학을 가지고 있다. 관리자 역할을 하는 액터는 자동으로 실패를 감지하고 원상태로 회복하게 만드는데 즉 재앙을 최소화하는것에 관심을 두고 있다.


Event-driven

웹서버에서 동기식 멀티쓰레드로 request 가 대응되는것이 아니라, 비동기식 event 별로 처리를 하게되면 리소스 활용성이 높아진다 (메모리 및 CPU). 하지만 공유상태를 나눠같는것에 있어서 어려움이 생길 수 있다. 따라서 그런 어려움을 방어 하기 위해 immutable 상태 지향의 개발, Actor, STM 등의 기술이 함께 따라다닌다.   

      

즉 데이터가 흘러감에 있어서 변경가능한 상태에서의 알수 없는 변화는 지옥의 버그를 창조하므로 자연스럽게 함수형파라다임이 가미가 되는 것이다. 


기술적으로 설명해보면 아래와 같다.

이미지출처: https://deepakpol.wordpress.com/2015/09/29/event-driven-and-reactive-architecture/

     

Event 를 처리하는 루프(쓰레드)가 있으며 해당 이벤트를 받기위해 구독을 신청한 노드의 핸들러에게 메세지(이벤트) 를 전달해준다. 물론 그 이벤트루프에 이벤트를 발생하는 녀석도 있을 것이다.

즉 

- Events   ( 웹으로 말하면 브라우저에서의 Request 및 미들웨어로의 요청)

- Event Loop (Reqeust 를 처리하는 엔진) 

- Event Handler (Request 를 받아서 비니지스로직을 구현. 이것은 주로 당신이 만드는것이다.)

로 이루어져있다.

좀 더 구체적인 예를 Akka 를 통해서 살펴보면

이미지출처: https://deepakpol.wordpress.com/2015/09/29/event-driven-and-reactive-architecture/


  1. sender Actor(A라고하자)는 ActorSystem 의 actorOf() 메소드를 통해서 초기화 한다.
  2. ActorSystem  는 수신될 Actor (B) 의 레퍼런스를 만든다. ( 이시점에 Actor(B) 가 만들어지는 것은 아니다)  ActorRef 는 실제 Actor(B)의 프록시로 행동한다. 
  3. sender Actor(A) 가 B 에게 이벤트를 보낸다. (비동기로~)
  4. ActorRef 는  MessageDispatcher에게 그 이벤트를 넘긴다 (dispatche)
  5. MessageDispatcher 는 전역MessageQueue에 이벤트를 넣는다.
  6. MessageDispatcher 는 또한 수신 Actor에 대한 메일함을 발견하고 활용가능한 쓰레드풀의 쓰레드를 이용해서 실행한다.
  7. 실제 수신액터의 onReceive 핸들러에서 이벤트를 처리한다. 


Reactive : 간단한 코드로 말해요

나 포함 대부분의 개발자들은 사실 메뉴얼 및 API 를 꼼꼼히 읽거나, 개념을 글로 이해하기 보다 코드(Hello world) 로 먼저 시도해 보고, 문서보고 그러한 반복 과정을 통해 이해해 왔을 것이다.

그래!! 이제 간단한 코드를 살펴 볼 시간이다.

=> 다음포스트에서..



참고:

https://deepakpol.wordpress.com/2015/09/29/event-driven-and-reactive-architecture/

https://www.youtube.com/watch?v=oS9w3VenDW0

Reactive web applications 

https://www.lightbend.com/blog/reactive-manifesto-20



1. 그림으로 보는 동시성 

2. 동시성과 Future 이야기

3. 자바로 밑바닥부터 Future 구현

4. 언어별 Future 살펴보기


1. 그림으로 보는 동시성 


은행에 창구가 하나입니다.  사람들은 줄을 서서 일을 처리합니다.


은행은 일처리가 빠른 직원을 고용해서 더 빨리 사람들의 일을 처리해줍니다.

하지만 고객들을 감당하기 힘들어서 더 빠른 일처리를 하는 직원을 고용합니다.

한계에 봉착합니다..



그래서 창구직원을 3명으로 늘렸습니다.  근데 사람들은 습관적(코딩)으로 예전 직원에게만 찾아갑니다. 

창구직원이 늘어나 바짜 고객들의 줄은 줄어들지 않습니다.


간혹가다 다른 창구로 찾아가는 손님들이 있어서 조금 나아졌습니다.

즉 다른 창구(CPU 코어) 를 활용하는 고객(쓰레드) 들이 많아 질 수록 업무환경(서버의 처리능력)은 좋아 질 것입니다. 


모든 코어에 적절하게 일처리가 분담되었습니다. 쓰레드를 직접 만들어서 처리할 수도 있지만 그렇게 하기 위해 노력 할 시간에 서비스를 위해 만들어야하는 기능에 충실해야 합니다. 그러기 위해서 쓰레드를 내부로 감춰놓고 외부에서 편하게 쓸 수 있는 도구가 필요합니다. Future , Promise , Async, Observerble 등입니다.


그림 처럼 B 함수를 호출하고 결과를 기다린 시간하고 


B 라는 쓰레드에 비동기로 업무를 맡겨바짜,  B 라는 쓰레드에서 결과를 나오기만을 기다리고 있다면 큰 효율을 얻을 수는 없을 것 입니다.  (Java7 에서의 Future 방식이며 물론 상황에 따라서 효율의 정도는 달라집니다.)


 B 에서 일을 처리한 결과를 C 에 입력해서 처리하고 결과를 받아야 한다고 할때 (체이닝이 필요할때) 
메인쓰레드에서는 B 의 결과를 기다렸다가 C 에게 넣어주고 또 C 의 결과를 기다리는 것보다..
(비록 멀티쓰레드 프로그래밍을 하고는 있다지만 먼가 답답하다..)


메인쓰레드는 그냥 모든것을 잊어버리고 자기 주력의 일을 하고 , B 에게 던진일은 알아서 B -> C-> Somthing 이 되게 한다면 효율적일 것이다. 

웹어플리케이션으로 얘기하자면 클라이언트의 요청을 받는 놈은 계속 받는일에만 신경쓰고, (요청이 어떻게 처리되고 있는지 신경을 딱 끊어버리고..) 요청을 처리하는 녀석들이 높은 동시성 효율을 보이도록 잘 구성해서 성능을 높이자. 라는거죠.

결국 이러한 필요성에 의해 각종 도구들이 나타납니다. 밑바닥부터 직접 구성하려면 하면 어렵지만 이러한 것들을 편하게 해주는 것들이 많아지게 되었습니다. 예를들어 PlayFramwork 나 최신의 Spring 등은 이러한 Reactive 파라다임을 지원하고 있습니다.


* 멀티쓰레드 패턴에서 Future 패턴은 따로 존재하는데 그 패턴을 각 언어,라이브러리마다 확장해서 사용하고 있습니다. 예를들어  Java7의 Future 와 Scala 의 Future 는 다르죠.  



2. 동시성 (Concurrency)  와 Future 이야기

요즘 비동기 개발방법들이 다양한 언어,라이브러리등을 통해 회자되고 있습니다. 동시성(Concurrent) 에 대한 이야기야 10년전에도 20년전에도 나온 이야기겠지만, 바라보는 시각 차이 혹은 대중들에게 요구하는 수준이 달라졌다고 할 수 있습니다. 여러 동시성 도구들이 언어마다 채택되고 있는 관계로 동시성프로그래밍은 매우 대중화 되었습니다. (아직 우리나라는 좀 멀은거 같기도 하지만....)

예전에는 쓰레드를 활용한다 정도로 접근했다면 요즘에는 가장 효율적으로 활용한다가 일반화되고 있습니다.

 암달의 법칙

 멀티코어를 사용하는 프로그램의 속도는 프로그램 내부에 존재하는 순차적sequential 부분이 사용하는 시간에 의해서 제한된다.

즉 쓰레드 간의 블럭이 많을 수록 비효율적이며 , 그것을 감소시키는것이 동시성 프로그래밍의 화두인겁니다.

그러기 위해서는 쓰레드 관련 개발하는데 굉장히 힘을 소비해야하며, 현대처럼 복잡해진 사회(솔루션)에 언제 개인이 그런 효율적인 바퀴를 만들고 있을까요? 그래서 다양한 도구들이 나옵니다.


Future, Promise, Async,Observerble

일단 이런것들은 쓰레드를 대체 하는 신기술이 아닙니다. 쓰레드를 사용 안하는게 아니라 깊숙히 감춰 놓은 기술인 겁니다. 쓰레드를 직접 사용하는 것 보다 쉽게 효율적으로 동시성 프로그래밍을 할 수 있으니깐 적용하는 겁니다.  그래서 신기술을 적용한다고 생각하는 대신에 " 쓰레드로 하던 것을 저거로 하자" 이렇게 생각하는게 간단합니다.


3. 자바로 Future 를 밑바닥에서부터 구현하자.


먼저 Future 패턴의 클래스 다이어그램을 보자.  

( IFood / Future / ReadFood 의 관계는 Proxy 패턴이다. 매우 많은 패턴이 저런 모양을 가지고있다. 컴포지트,데코레이터,프록시, 어댑터, 인터프리터 등등  결국 모양(구조) 과 패턴은 전혀 상관이 없다. "의도" 가 중요한것이다.)

당신은 주말에 꿀 같은 휴식을 취하고있다. 동물농장을 보다보니 출출해서 피짜헛에서 피자를 하나 시켜먹어야겠다고 생각했다.  

1. 주문을 한다.

2. 문앞에서 하염없이 기다린다.

맞나?  

그렇지 않다. 우리는 보통 주문을 한 다음에 보던 TV 를 계속보던가 ,  똥싸러 가거나  다른 일을 하게된다. 이런걸 비동기적인 행동이라고 한다. 위에 하염없이 기다리는것을 동기적( 블로킹 되었다라고도 ) 이라고 한다.

다시 저 위의 다이어그램을 살펴보자. 클라이언트(당신)은 레스토랑( 피짜헛) 에 주문을 하고 기다리는 코드는 대략 아래와 같다. 

Restaurant rest = new Restaurant();

Pizza pz = rest->requestPizza();     // 요기서 피자 올때까지 계속 기다림!!

eat(pz); // 피자 오면 냠냠!!!! 

이런식으로 코드가 진행된다면  직관적이라  코드리딩이 쉽고 에러날 확률이 줄어들겠지만  피자만들고 배달오는 시간동안 기다려야하기때문에 굉장히 지루하면서, 시간낭비라 할수있다. 그래서 결국 피자만드는 시간이 빠르면 빠를수록 동기적으로코딩하는게 나을테고, 느리면 느릴수록 비동기적으로 코딩하는게 나을것이다. 

그럼 비동기적으로는 어떻게 될까?  위의 UML 에 나온 클래스들을 기반으로 대략 코드를 보자.

Restaurant rest = new Restaurant();
Future  ticket = rest->requestPizza(); //전화로 주문을 한후에, 전자티켓을 받는다.
boolean b = future->isComplete();     // 티켓을 통해서 완료됬는지 (배달이 집앞에 왔는지) 알수있다. 

if(b){

eat(future->getPizza());    // 집앞에 배달이 왔으면 냠냠 먹는다. 

} else{                                      // 배달 안왔으면 하던일을 한다.
      .... TV 를 보거나 설겆이을 한다 ....
       .... // 좀 지나서 

  while(!future->isComplete()){  // 시간이 지나서 배달 올 때쯤에 다시 확인해본다.   
          Sleep(100);                       // 아직 안왔으면 올때까지 기다린다.   
  }

  eat(future->getPizza());         // 피자를 냠냠!!! 

}

 이런식으로 Future 객체를 사용하는것이 Future 패턴이다.  보면 알겠지만  무엇인가 일을 시킨후에 바로 리턴받고 자기 할일을 한다. 리턴받은 객체(Future) 를 통해서 간간히 자기가 시킨 일의 결과를 확인할수있게된다. 

조금 코드가 복잡해졌지만, 시간 활용도가 매우 높아졌다. 기본적인 Future 패턴을 살펴보았는데, 위에 코드를 보면 isComplete 를 통해서 계속 완료됬는지 안됬는지 신경써야한다는 단점이 있다.

이제 개별 클래스들의 코드를 살펴보자.  (위의 예와 아주 약간 다르다)


 다이어그램에서 Client

public class Client {
    public static void main(String[] args) {
        System.out.println("main BEGIN");
        Host host = new Restaurant();        Data data1 = host .request(10, 'A');        Data data2 = host.request(20, 'B');
        Data data3 = host.request(30, 'C');

        System.out.println("main otherJob BEGIN");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
        }
        System.out.println("main otherJob END");

        System.out.println("data1 = " + data1.getContent());
        System.out.println("data2 = " + data2.getContent());
        System.out.println("data3 = " + data3.getContent());
        System.out.println("main END");
    }
}

개별 쓰레드들에 업무를 요청하고, 그 쓰레드들에서 작업이 완료되길 기다린다.
즉 getContent 가 리턴 될 때까지 기다린다. (내부에서 wait 하고 있을 것이다)


다이어그램에서 Restaurant

public class Restaurant{
    public Data request(final int count, final char c) {
        System.out.println("    request(" + count + ", " + c + ") BEGIN");

        final FutureData future = new FutureData();

        new Thread() {
            public void run() {
                RealData realdata = new RealData(count, c);
                future.setRealData(realdata);
            }
        }.start();

        System.out.println("    request(" + count + ", " + c + ") END");
        return future;
    }
}

쓰레드를 내부에 가지고 있으며 요청이 오면 Future 를 즉시 리턴해주고 진짜 결과를 만들기위해 쓰레드를 만들어서 일을 시작 한다.


 RealData (다이어그램에서 RealFood)

public class RealData implements Data {
    private final String content;
    public RealData(int count, char c) {
        System.out.println("        making RealData(" + count + ", " + c + ") BEGIN");
        char[] buffer = new char[count];
        for (int i = 0; i < count; i++) {
            buffer[i] = c;
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
            }
        }
        System.out.println(" making RealData(" + count + ", " + c + ") END");
        this.content = new String(buffer);
    }
    public String getContent() {
        return content;
    }
}

실제 업무를 처리한다.


 FutureData (다이어그램에서 Future)

public class FutureData implements Data {
    private RealData realdata = null;
    private boolean ready = false;
    public synchronized void setRealData(RealData realdata) {
        if (ready) {
            return;     // balk
        }
        this.realdata = realdata;
        this.ready = true;
        notifyAll();
    }
    public synchronized String getContent() {
        while (!ready) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
        }
        return realdata.getContent();
    }
}

메인쓰레드에서 바로 받아보는 가짜(미래) 결과물이다. 메인쓰레드에서는 직접 진짜 결과물을 직접 접근 할 수 없으며 Future 에게 완료되었는지 물어보고 기다려서 결과를 받아간다.


* 데이터 

public interface Data {

    public abstract String getContent();

}

FutureData 와 RealData 의 인터페이스







다른언어를 꼭 써야 하는 몇몇 특별한 경우가 아니라면 무조건 파이썬으로 손이 가네요. 멈출수없는..블랙홀 같습니다. (사랑의 블랙홀 ? ^^) 아마도 전자정부프레임워크같은 코미디만 없어지면 자바와 양분 하는 것은 금방일듯.@@

첫언어 또는 상상의 매개체로서의 최고의 언어라 생각합니다. ( 실행가능한 슈도코드라고 하지요) 구석기도 아니고 C 타령은 이제 그만..  포인터와 저레벨 같은 사소한것에 발목 잡혀 있기엔 세상은 너무 다양해지고 급격히 변해가고 있습니다. 꼭 저레벨이 필요한 소수만 고생스럽겠지만 그거 열심히 하시면 됩니다. 

모두가 저레벨에 대한 이해가 필요하다고 구라치는 놈은 저 한테 걸리면 손목아지 날아갑니다~~ㅎㅎ내 소프트웨어 개발 인생에 가장 한이 되는거 한가지 뽑으라면 C++로 14년 개발하는 도중에 파이썬을 몰랐었다는 점.

갓 C 를 배운 꼬꼬마의 마음같이 순수하게 (?)  내 사랑 파이썬을 위해 뒤늦은 펜레터를 끄적여 보았습니다.



[2017년 저의 주요 파이썬 사용처 및 계획]

- 웹,앱백엔드개발
- 분산,병렬 시스템 및 각종 서버개발 
- 소켓통신개발 
- 데이터 분석 인프라/분석알고리즘/가시화 개발 
- 라즈베리파이상에서 돌아가는 게이트웨이 개발 
- 위에 들어가는 각종 유틸리티성 도구 (파싱,암호화,압축,파일처리,로깅처리등등등)




public class QuickSort {
    
    public void sort(int[] data, int l, int r){
        int left = l;
        int right = r;
        int pivot = data[(l+r)/2];
        
        do{
            while(data[left] < pivot) left++;
            while(data[right] > pivot) right--;

            if(left <= right){    
                int temp = data[left];
                data[left] = data[right];
                data[right] = temp;
                left++;
                right--;
            }
        }while (left <= right);
        
        if(l < right) sort(data, l, right);
        if(r > left) sort(data, left, r);
    }
    
    public static void main(String[] args) {
        
        int data[] = {66101345-10};
        
        QuickSort quick = new QuickSort ();
        quick.sort(data, 0, data.length - 1);
        for(int i=0; i<data.length; i++){
            System.out.println("data["+i+"] : "+data[i]);
        }
    }
}



스칼라를 이용한 개발 이후..


폴리글랏 (C++,Java,Python,Swift,Javascript) 언어로 개별 작업하면서 동시에 스칼라를 이용해 (Programming in Scala 와 FPiS 빨강책으로 공부)  EV 충전 인프라 서비스를 위한 마이크로서비스(서버 인프라와 웹서비스에 각각 적용하고 난 후 가장 아쉽게 느끼는 점은 akka 나 play2의 문제점 같은게 아니라 내가 짠 것은 함수형 프로그래밍은 아니다. 였습니다. 아시다시피 스칼라는 하이브리드언어입니다. 객체지향식으로 코딩 할 수 도 있고 함수형으로 코딩 할 수 도 있습니다. 따라서 기존 자바나 C++ , 파이썬 개발자들이 순수 함수형 언어인 하스켈이나 거의 순수형인 클로저 보다는 쉽게 접근 할 수 있는데요. 저도 스칼라를 선택한 이유 중 하나에 포함됩니다. (기타 : "Typesafe 사 및 대기업에서의 적극적인 사용, 자바라이브러리사용, Akka 라이브러리, 강력한 정적 타입시스템, Play2, Intellij IDE, 가상머신상에서 돌아감등 ") 

하지만 하이브리드라는 것 은 이것도 해주고 저것도 해주고 장점을 믹스하고 자유도를 높혀 준다 라고 말 할 수 도 있지만 거꾸로 보면 난해하다는것을 말합니다. (다른 사람이 짜놓은 코드가 객체지향인지 함수형인지.. immutable인지 아닌지..버그들을 눈을 부릅뜨고 찾아봐야하며 ..울분에 날 밤을 새야 할지도..) 함수형과 객체지향은 완전 상반된 개념인데 이것을 같이 사용하게 하면 어떤 일이 벌어 질까요? 

예를들어 동시성에 대해서 생각해 봅시다.

무어의 법칙이 한물가고 이제 암달의 법칙이 지배하는 세상입니다. 객체지향이니 함수지향이니 보다는 동시성지향프로그래밍으로 대동단결 할 것으로 보이는데요. lock 이나 뮤텍스,쓰레드등을 직접 요리하는 시대는 갔습니다. 그 우연적복잡성,경쟁상태,메모리가시화,데드락을 해결 하기가 너무 힘듭니다.(나는 저런거만 써서도 잘 할 수 있다는 사람이 주변에 있으면 조심하세요. 요주의 인물입니다 -.-;;)  그래서 어려운 동시성 문제를 해결 하기 위해 여러 방법들이 생겨 났습니다.  크게 보면 3가지 인데요. 참고=> 7가지 동시성 모델

첫째. 변하지 않는 데이터로 공유하라. (immutable 은 함수형파라다임의 대표적 속성 중 하나)
둘째. 공유되지 않게 하라. (
객체지향파라다임에서 메세지 패스를 통해서 해결 하라는 것 이며, 예를들어 Actor 모형입니다.)
셋째. 가변상태에서 아이덴터티를 포착하라. ( STM 을 말함) 

이 얘기는 앞으로 점점 더 동시성 프로그래밍이 대세가 될 텐데  그걸 기본적으로 해결 해주는것이 함수형 파라다임이고 그 이유로 요즘 F#,하스켈,스칼라,클로저,얼랭등이 인기를 얻고 있다는 뜻이기도 합니다. 음 먼가 말이 샌거 같기도 한데...-.-;;

여기서 스칼라는 두둥~~ 네 객체지향이자 함수형이고 가변성질을 느슨하게 포함하고 있는 상태에서 다양한 동시성 모형을 여러가지로 가져 갈 수 있는데.., 그 말은 복잡도가 *100 증가 했습니다와 마찬가지입니다. 한가지만 제공하는 언어를 사용하면 누가 짠 코드이던지 그 본질에 대해 확신이 들지만 이것도 되고 저것도 된다면 확인해 봐야 할것들이 늘어잖겠습니까.. OTL  

뭐 이런 고민 상황에서  허둥지둥 스칼라로 프로젝트를 하였고..스칼라의 반 쪽 밖에 맛을 못본것은 좀 아쉬웠습니다. 특히 그 반쪽보다는 다른 쪽 반쪽에 대한 장점을 가져가고 싶었는데 말이죠. 시간이 없었다는 핑계를 댈 수 도 있겠지만 그것 보다는 우선 순서가 잘못된게 아닌가 느꼈는데요. 결국 "스칼라"라는 하이브리드 언어에서 나머지 한쪽 맛 (함수형) 을 보려면, 순수 함수형을 먼저 공부하는게 순서가 아니겠느냐 하는 점이죠. (이것은  C++ 개발자에게 자바,스몰톡을 공부 해 보라고 권유하는 것과 동일합니다. 자바개발경험이 있으면 C++ 개발에 대한 식견도 꽤 높아질것입니다.) 즉 스칼라를 더 잘 사용하기 위해서 즉 객체지향의 강점과 함수형의 강점을 극대화 하여 사용하기 위해 순수 함수형 언어를 공부해야겠다고 생각 하게 되었습니다.(사실 공부만 해서 별 의미 없을 거 같기도 합니다. 다른 언어를 한 1년 정도 안하고 순수 함수형만 가지고 놀 수 있는 환경에 있다면 좋을텐데.. 여러가지 언어로 개발하면 온전히 함수형 마인드를 갖기는 어렵지 않을까 하는)

그럼 어떤 함수형언어를 공부 해 볼까 고민하다가 발견한 글 중에 하나가 이것입니다. 뭐 시간 있으면 하스켈,클로저 둘 다 공부해 보면 좋겠지만 시간도 없거니와 이왕하는 거 순수 함수형 언어인 하스켈을 선택하자 하고 몇가지 글을  찾았고 그 중 하나를 정리 해보았습니다. 항상 그러하지만 번역 상태에 대해 만족스럽지 못할 수 있다는 점 송구스럽게 생각하며.. ㅜㅜ  시작해 봅니다. =@@



Clojure 를 넘어 Haskell 로  

http://martintrojer.github.io/beyond-clojure/2016/04/21/beyond-clojure-haskell

타입을 가진 함수형 언어에 관심이 있는 경우 결국 하스켈을 만나게 될 것 입니다. 배우기가 극도로 어렵고 마스터 하기는 더 어렵다는 평판에도 불구하고 훌륭한 자료들이 있으며 귀중한 교훈을 많이 배울 수 있습니다.

하스켈은 매우 순수하며 핵심 아이디어와 라이브러리의 간결함은 환상적입니다. 그것은 명령형 문제 해결 스타일을 뛰어 넘고 높은 수준에서 문제를 매우 깔끔하게 다룹니다. 하스켈에 관해 내가 정말 좋아하는 한 가지는 명백한 학문적 용어를 사용하여 '사물'이 무엇인지 불리는 것입니다. 모나드 (Monads) 등을 가지고 있는 다른 언어들의 경우 수줍어(?)하며 다른 이름을 쓰는 경향이 있습니다.이 점은 혼란만 가중 시킬 것이라고 생각합니다.

핵심 라이브러리 (하스켈 literature 의 대부분인)의 벽으로 둘러싸인 정원에 머물러있는 한 간결하고 아름다운 세계가 제공됩니다. 문제 해결에 영감을 불어 넣고 다양한 각도에서 문제를 바라 보는 환경인데요. 그래도 항상 더 깔끔하게 문제를 해결할 수 있는 방법들이 있으며, 이러한 탐구적인 태도와 성향은 하스켈 커뮤니티에  널리 퍼져 있습니다. Haskell 초급 모임 및 채팅룸에서 경험이 많은 개발자들이 따뜻한 도움을 주고 있으며, 답을 주는 것보다 스스로 문제를 해결할 수 있게끔 유도 합니다. 그것은 언어를 즐겁게 배우게 만드는데 도움을 준다고 생각합니다.

성공하는 대신 결점을 찾아라

Haskell에 대해 이해해야 할 때 중요한 한 가지! 이 언어는 "연구 언어" 란 건데요. 이 사실은 다른 '현장 언어' 들과는 매우 다른 점입니다. 좀 어리둥절 할 수 도 있는 하스켈의 모순 된 모토는  '모든 비용을 들여서라도 성공을 피하십시오'. 입니다. 이 말을 해석해보자면 언어의 안정성에 의존하는 대규모 사용자 기반을 피함으로써 작성자 / 연구자가 마음을 바꾸면 나중에 제거하고 마음 편하게 새로운 아이디어를 탐색 할 수 있다는 것입니다. 대성공의 희생자이며 성공을 했다는 이유로 십 수년 동안 혁신 마비에 빠져있는 Java와 같은 언어와 대조해 보시면 됩니다. (역주: 개인적으로 자바는 혁신 하지말고 그냥 자바 그 자체로 남아 있길 바라는 마음도 있습니다. 혁신하다보면 오히려 정체성만 없어지고 조잡한 언어가 되지 않을까 하는 우려 때문인데요. 오랫동안 혁신하지 않고도 자바가 필요한 분야는 많이 있을 겁니다. 목숨 줄 억지로 늘리지 말고 때가되면 자연스레 은퇴하길...) 가장 유명한 Haskell 컴파일러 인 GHC에서 명백하게 느낄 수 있는데 GHC는 최신 Haskell 표준 Haskell2010을 지원하며 그 위에 다양한 언어 확장 기능을 제공합니다. 

여러분이 핵심 라이브러리의 벽으로 막힌 정원 밖으로 여행을 떠나서 하스켈을 '진짜로'사용하기 시작하면, 거의 모든 모듈에서 이러한 언어 확장을 피할 수 없습니다. 모두는 아니더라도 대부분의 라이브러리는 확장 기능을 사용하고 일부는 코드에서 사용해야합니다. 이것이 얼마나 큰 거래인지는 미래의 변화에 ​​대해  당신이 얼마나 대처 할 수 있을지에 달려 있습니다.

하스켈을 주 언어로 사용하고 5 년 이상 일하는 것에 대해 생각하고 있다면, 이것은 불안의 원인이 될 수 있습니다. 비즈니스 핵심 서비스를 위해 GHC (컴파일러 '모두 사용')를 사용할 계획이라면 언어 / 컴파일러 변경 사항을 지키기 위한 전략과 팀에 부과하는 추가 작업을 고려해야합니다. 개발자가 사용하는 확장 기능에 대한 규율도 중요합니다. (역주 : 역시 공부목적으로만 해야 하는.. -.-a)

게으름

Haskell 의 핵심 설계 원칙 중 하나는 게으른 평가입니다. 이것은 다른 함수형 언어에서 볼 수 있는 게으른 시퀀스 이상입니다. 기본적으로 모든 표현식은 다른 표현식이 결과를 땡겨 올 때만 실현됩니다. 하스켈의 아름다움은 이 기법에서 비롯되었지만 실제적인 문제는 많습니다. 가장 중요한 것은 기능의 시간 / 공간 복잡성을 해결하는 것이 매우 어렵다는 것이며 다른 함수의 표현식은 현재 벤치마킹중인 함수의 문맥상에서 방아쇠가 당겨 질 수 있습니다. 그밖에 따로 방법이 없으며, 적극적 평가(eager evaluation) 가 그 부분에서는 더 쉽지만, 하스켈의 접근법을 무효화하지 않습니다.(??)

또 다른 문제점은 일반적으로 런타임 예외시 스택 트래이스를 얻지 못한다는 것입니다. 그것은 컴파일 타임에 활성화되어야하며 프로덕션 빌드의 경우 일반적으로 실행되지 않습니다. 트레이스를 얻었을 때도, 게으른 것으로 평가되기 때문에, 자바 스택 트레이스와 똑같지는 않습니다.

늘 그렇듯이 몇가지 대안이 있지만,  간단하지 않은 상황 (예 : 생산 중단 시간 시나리오가 그러하듯) 에서는 Java와 유사한 프로파일링 도구가 필요 합니다. 필연적으로 compiler optimization flagsbang patterns 및 기타 어려운 교훈을 배우고 베스트 프랙티스를 수집하는 과정을  거친 후에야 제대로된  응용 프로그램을 만들 수 있을 것 입니다. OTL

타입 언어와 함께 춤을

하스켈과 클로저의 차이는 꽤 있는데요 Clojure에서는 var에서 작업하고자 하는 데이터를 저장하고 변환 작업을 시작합니다. 표현식을 데이터 모양과 일치 시키려 할 때 피드백은 종종 Clojure 런타임 오류입니다. 하스켈에서 추상화 (유형)에 대해 생각하기 시작하고 컴파일러의 주요 오류는 컴파일러가 자신을 모순하는 곳을 가리키는 유형 오류입니다. 또한 런타임 오류가 거의 발생하지 않기 때문에 '컴파일하면 작동합니다'라는 강한 확신감각하에 개발을 합니다. 이것은 결코 테스트의 중요성을 없애지는 않지만 테스트는 Clojure 코드 -베이스에서와 동일한 역할을 하지 않습니다. Haskell에서 나는 코드가 올바르게 붙어 있거나 GADT의 변경으로 인해 case 표현식을 바꾸는 것을 잊지 않았다는 확신을 줄 수있는 테스트가 필요하지 않습니다. 컴파일러는 나를 위해 모든 것을 검사하고 "그것은  여기, 여기, 여기 그리고 여기에 더 많은 수정이 필요합니다"라고 말합니다. 나에게 이것은 엄청난 것이지요.

툴과 함께 춤을 

'Haskell IDE'는 전통적으로 Emacs / Vim과 터미널 입니다. 매우 즐거운 개발자 경험을 주는 여분의 도우미가 많이 있습니다. 전통적인 IDE를 위한 플러그인이 있지만 일반적으로 덜 정교합니다. 나는 대화형 작업 흐름을 제공하는 Emacs, haskell-mode, ghc-mod, hlint 설정에 만족합니다. 좀 더 전통적인 IDE 설정이 필요하다면, IDE-Haskell과 Haskell for Mac이 괜찮아 보입니다.

라이브러리로 작업하고 의존성을 다루는 것은 cabal로 수행됩니다. Cabal은 하스켈 서클 내부와 외부에서 많은 쟁점과 명성을 얻었습니다. Haskell 개발자들은 여러 문제에 대해 다양한 해결책을 찾기 위해 광범위하게 노력해 왔습니다. 그 문제의 일부는 라이브러리의 버전 (및 그 의존성)뿐만 아니라 컴파일러의 버전이 그것을 생성하는 데 사용되었다는 것입니다. 컴파일러는 기계어 코드를 생성하므로 크로스 컴파일 문제도 있습니다. Mac에서 실행 파일을 컴파일하는 작업은 Linux 서버에서 실행되지 않습니다.

최근 Cabal과 관련된 많은 불평은 Stack이라는 도구로 해결되었습니다. 나는 아주 만족하고 있습니다.(그리고 Nix를 필요로 하지 않습니다.). Stack은 하스켈 툴링 스토리에 대한 커다란 개선점입니다.

라이브러리와 함께 춤을 

사용할 수있는 하스켈 라이브러리는  많이 있습니다. 좋은 라이브러리를 찾는 것은 좀 어렵기도 하지만요 웹어플리케이션을 구축하는 경우 대부분의 기반들을  커버 할 수 있습니다. 웹 프레임워크, 데이터베이스 연결, 템플릿 등에 대해 좋은것들이 있습니다. 그러나 자바 생태계와는 여전히 비교 되긴 힘듭니다. Haskell은 닭이 먼저냐 달걀이 먼저냐인 상황에 갇혀 있는데요. Java 는 서드파티제품들에 대해 상호 작용하는 많은 라이브러리가 존재합니다. 하지만 하스켈은 최신 AWS API를 사용하거나 Riak 데이터 저장소에 연결하기 쉬운 경로를 원할 경우 길이 없습니다. 기본 빌딩 블록은 있지만 거기에 앞서 당신은 꽤 많은 일을 해야 할 것입니다. 이러한 상황은 개발자들의  Haskell 채택을 머뭇거리게 하고 있으며, 이는 결국이 라이브러리가 만들어지는것을 또한 머뭇거리게 만들 고 있습니다.

하스켈 라이브러리에 대한 문서는 대개 꽝입니다. 초보자 친화적인 문서를 기대하지는 마십시오. 나는 스택 오버 플로우등에 대한 검색에 의존하고 있습니다. 라이브러리에 관한 여러 문제점은 하스켈을 실제 시나리오에서 '사용할 언어'로 채택 할 때 주로 우려되는 사항입니다. 



여러분은 어떤것이 하이브리드앱이라고 생각하시나요?

1. 하나의 언어 혹은 툴로 여러 OS에서 돌아가는 앱
2. 웹과 네이티브 기능이 섞인 앱
3. 1번과 2번이 합쳐진 개념 (크로스 플랫폼향으로 제작되었으며 웹과 네이티브 기능이 잘 버무려짐)


.
.
.


많이들 오해하시는 부분입니다. (추가하였습니다: 저도 헤깔리며 사람마다 정의가 조금씩 다른듯 합니다) 

먼저 하이브리드라는 말은 하나의 언어/프레임워크에서 만들어서 아이폰과 안드로이드등으로 포팅 할 수 있다는 의미와 웹과 네이티브를 섞었다는 의미가 있습니다.  통상적으로는 후자를 말 합니다.


다음과 같이 구분해보았습니다.


1.사용되는 언어에 따른 분류  (자바스크립트 vs  델파이,C# 자마린등) 

*javascript 기반 하이브리드앱에는 ionic 프레임워크 / react 네이티브 / OnsenUI 등 
*네이티브 언어 기반 하이브리드 앱에는 자마린,델파이등이 있으며

2.포팅되는 상태에 따른 분류  (웹뷰 vs 순수네이티브UI) 

* 웹뷰기반 하이브리드앱에는 ionic,OnselUI 등이 있으며 즉 이것들은 변환후 웹뷰상에서 동작합니다.CSS 필수.
* 네이티브UI 기반 하이브리드앱에는 react 네이티브,자마린,델파이등이 있습니다. 즉 그것들이 안드로이드(자바), iOS(swift,objectC) 와 같은 네이티브 UI 로 변환됩니다.웹 뷰를 사용 할 수는 있으나  즉 웹 및 웹뷰와 직접적 상관이 없습니다.

3. 웹을 네이티브와 섞어 사용하는 것 그 자체만을 하이브리드앱이라 지칭.  (통상)


4. 개발 방식과 개발 결과물의 방향성을 분리 
- ionic, 자마린,react 네이티브등 하나의 언어로 여러 OS 에서 작동하는것은 크로스플랫폼 개발 방식이라고 지칭함. (자마린은 네이티브 기반 크로스플랫폼개발이고 ionic 은 웹기반 크로스플랫폼 개발.)
- 개발결과물이 웹과 네이티브를 혼합해서 사용되면 하이브리드앱이라 지칭함. 
(자마린이던 ionic 이던 혼합해서 사용하면 하이브리드앱, 근데 ionic 은 그 자체로 섞어 쓰는것이기 때문에 ionic 경우는 하이브리드앱이지만 자마린은 아니라고 주장하는 사람도 상당함) 


두줄정리  

1. 크로스플랫폼 개발향으로 만든 앱을 하이브리드앱이라고 지칭하기도 하며 
2.  웹과 네이티브 기능을 섞어서 만든것을 하이브리드앱이라고도 지칭함.(통상) 



" 하나를 더 추가하라 "


지금 당장 눈에 보이는것도 할 수 있을지 모르는데 눈에 안보이는 하나를 더 추가할 여유가 있습니까?  
네 여분의 하나를 더 생각해보는 여유가 생길 때  더 이상 초보 개발자가 아닙니다. 

.

.

.

몇 주전에 한 건겅검진 결과가 얼마전에 나왔다. 

위 조영술 결과  위암이 의심되니 빠른시일에 2차 검진을 위 내시경으로 받으란다. 별다른 전조증상이 전혀 없었기 때문에 위암에 대한 걱정은 크지 않았지만 처음 해보는 내시경은 좀 두려웠다.  

그렇지만  이번 기회에 왜  길라임이 프로포폴과 연관관계에 있는지  알아볼 겸 수면내시경으로 하려고 생각했고 오늘 아침에 일찍 병원에 도착하였다.  

접수를 하고 내시경실로 가서 일단 마취제를 삽입할 주사 어댑터(?) 를  팔에 꽂아 두고 기다리면서 , 지난 밤에 읽었던 어떤 SW 패턴에 대해 다시 잠깐 생각을 해보는 와중 너무 많은 SW 패턴 (디자인패턴,동시성패턴,엔터프라이즈패턴,안티패턴등 백가지도 넘을듯) 에 대한 압박감이 느껴지기 시작하여 그 많은 패턴들을 하나로 농축시켜 놓으면 무엇일까? 그것들을 관통하는 궁극의 한마디는 무엇일까 생각해보는 와중에 간호사로 부터 

"들어오세요~"  

라는 호출을 받고 들어가서 자리에 누웠다. 약간 긴장감이 느껴졌지만..간호사가 "불안해 하지 마세요. 긴장 푸세요" 라고 말하며 검사 준비를 하는 도중에.. 다시  생각해 보았다.

Gof 패턴 20여가지..POSA 패턴 몇가지, 동기성패턴 10여가지..엔터프라이즈 패턴 몇가지, 분산,클라우드 관련 몇가지..무엇이 가장 그것들을 관통하는 핵심일까? 문득 모든 패턴들에는 사실 없어도 되는 redundancy 가 있다고 느꼈고..하나의 레이어 하나의 인터페이스 하나의 캐쉬, 하나의 서비스 로케이터등이 추가되고 있구나라는 생각을 하며, 미리 블로그에 쓸 제목을 머라고 지을까 부터 생각했다.

그래 궁극의 마스터 패턴이라고 짓자. 어차피 답이 있을리 없고 반농담식의 글이 될께 뻔하기 때문에 오히려 과장된 제목이 적절하겠다 싶었다. 따라서  모 개발자 싸이트에서 한동안 놀라움과 비난(?)의 대상이었던  궁극의 시리즈를 차용하고 , 최근에 읽었던 마스터알고리즘을 따서 "궁극의 마스터 패턴" 이라고 짓자라고 생각했다. 참고로 마스터 알고리즘의 책 표지에는 이렇게 나온다 " 완벽한 마스터 알고리즘이 탄생하는 순간, 세상 모든 것이 재편될 것이다!"  쩐다...-.-  추가좀하자면 어떤 데이터를 분석하는 방법이 머신러닝에는  여러가지가 있는데 그 각각의 방법을 공부하는것도 어렵지만 어떤 방법으로 분석해야 가장 효율적인이 알아내는 것 자체도 거대한 도전.  베이즈정리,HMM,SVM,CNN,RNN,유전,K-means,PCA,CTC,강화학습등 이 모든것을 관통하는 단 하나의 알고리즘 그 마스터 알고리즘에 대한 이야기이다. 

이런 저런 생각을 하는 와중에 도대체 검사는 언제 시작하나? 라고 생각하고 있는데..

누가 팔을 흔들면서 말했다. 


" 환자분 검사 끝났어요. 일어나세요~" 




+ Recent posts