달력

102018  이전 다음

  •  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  •  
  •  
  •  

Go에 관심을 갖은건 2012년 정도로 생각된다. 하지만!! 지금까지 Go 관련 글을 Evernote나 workflowy에 저장만 하고

딱히 Go를 이용해서 뭘 만들어 보지도 않을 뿐더러 문법도 애매하게 안다...


지금까지 행동 없이 관심만 가지고 지내면서 너무나 무뎌진 나의 개발 능력을 체감했고, 날카롭게 만들고 싶었다.

(물론 무뎌짐을 느낀게 처음은 아니지만 이번엔 세게 왔다. 결심은 큰 의미 없으니 어느정도 생각이 잡히면 바로 행동)

우선 내가 날카롭게 만들고 싶은게 무엇인지 적어보면 

다양한 데이터를 손쉽게 수집하기,

수집한 데이터와 사용 용도에 적합한 DB solution을 찾을 줄 알고, 장/단 점 파악 및 설정 값들이 어떤 의미가 있는 정도, 

마지막으로 저장된 데이터를 쉽게 관리 할수있는 시스템 만들기다. 


우선 Go의 장점/단점이 어떤게 있는지 알아보고, 명분을 찾아보자.




Why go is Not Good  http://yager.io/programming/go.html

Generic, Type overloading 이 없다

immutable data type, pattern matching, option이 없다

대부분 multiple return의 두번째 값을 통해 오류처리를 하는데 잊어버리기 쉽다.

embedded programming에는 overhead가 없는 Rust 가 짱짱맨



Why we switched from Python to Go https://getstream.io/blog/switched-python-go/

C++, Java와 비슷한 성능

직관적인 코드로 생산성 괜춘

goroutine과 channel을 이용한 쉬운 동시성 코딩 (1977년에 시작된 CSP를 새로운 접근 방식으로 구현)


부족한 (CRUD API 지원되는) Framework과 패키지 관리 시스템

부족한 Error Handling


Python 과 Go를 비교

코딩 시간은 Python이 조금 더 짧았지만 최적화 하는데 시간이 오래 걸렸다.

Go는 최적화가 필요하지 않을정도로 괜찮은 성능이 나왔다.



Why Go and Rust are not competitors https://dave.cheney.net/2015/07/02/why-go-and-rust-are-not-competitors

Rust는 C/C++ 호출이 overhead 없이 가능, Go엔 cgo라는게 있지만 성능 이슈가 있다.

Rust는 극강의 성능을 지향, Go는 단순함을 유지 하기 위해 성능을 희생

Go는 단순함이나 직교성을 해치는것을 막는것에 초점을 잡았고

Rust는 unsafe하거나 오버헤드, 즉 성능에 영향을 끼치는것을 막는데 초점이 잡았다.

Rust는 성능을 요구하는 C++, D 같은 언어와 경쟁한다. ex) 게임 엔진, 웹 렌더링 엔진

Go는 인터넷 2.0세대 이후 생긴 Ruby, Python, Node.js 그리고 배포에 오랜 시간이 걸리는 JVM 기반 언어와 경쟁한다.



Why Go? https://dave.cheney.net/2017/03/20/why-go

메모리 관리에 대해서 안전하다.

개발 생산시간이 컴파일 시간보다 비싸진건 오래전부터다. Go는 컴파일 시간이 짧고, 코드에 모호성이 없다.

코드를 읽는것이 작성 하는것보다 우선 순위가 높다는 기조로 만들어졌다. 그리고 다양한 분석 도구들이 생기고 있다.

하드웨어의 발전만으로 성능을 이끌어냈던 공짜 점심은 끝났다. 

goroutine, channel를 이용해 동시성을 지원하는 코드를 손쉽게 작성할수 있다.


How to convince Your company to Go with Golang  https://sendgrid.com/blog/convince-company-go-golang/

Go를 좋아하면 새로운걸 배우는걸 좋아하는 사람들이고 이런 사람들은 우리 회사가 원하는 개발자였다. 채용 개이득!! ㅋㅋ


마음에 드는말

기술로 무언가를 할수 있다는것이 가장 좋은 방법은 아니라는 것을 사람들에게 이해시키는데 도움이 되었던 말 

“Perl로도 계속 개발할 수 있다."

“We can keep doing it in Perl,” which usually helped people to understand that just because you can do something with a technology doesn’t mean its the best way to do it.



Ten Reasons Why I Don’t Like Golang  https://www.teamten.com/lawrence/writings/why-i-dont-like-go.html

public, private을 대소문자로 구분하는것, scope이 어디까지인지 알기 어렵다

error handling이 어렵다

“convention over configuration” 기조가 작은 프로젝트에선 괜찮지만 커다란 프로젝트에선 너의 발목을 물것이다!!

사용하지 않는 variable이나 import가 있으면 경고가 아니라 컴파일이 안된다.

ternary 연산자가 없어서 불편하다.

generic이 없어서 interface{}를 사용하고 있다.

db 혹은 web 과의 통신이 잦은 프로그램에서는 추천하지 않는다.



Why rust? https://pingcap.github.io/blog/2017/09/26/whyrust/

SQL 계층은 Go의 장점을 십분 활용해 구현했지만, 성능이 중요한 저장 계층에선 Go가 단점이 되었다.

저장소로 RockDB를 사용하기로 했는데 cgo의 오버헤드 무시 못함 



Why Go? http://www.mikeperham.com/2014/10/08/why-go/

https://github.com/golang/go/wiki/FromXToGo



지금까지 tutorial 수준으로 해왔던 경험과 위 링크를 읽은 후 Go에 대한 나의 생각


문법이나 생태계 측면으로는 정말 생존에 필요한 도구만 챙기고 바로 캠핑을 떠나는 모험가 같다. 

좀 더 편안하고 쉬운 캠핑을 위해 더 챙겨가면 좋은데 가볍고 빠른 행동(?)을 위함이다.

하지만 단체로 캠핑을 갈 경우 함께 가는 사람들이 모두 모험가형이 아니라면 좀 더 많은 것들을 챙겨가야 할것이다. 

(Go가 큰 프로젝트에 사용할때 불편하다는 말에 어느정도 공감한다. 물론 크다는 기준이 굉장히 주관적이지만...)


사용성이나 성능면으로는 어떠한 분야를 특출나게 잘하진 않지만 다양한 분야를 어느정도 잘하는 사람 같다.

[학교 성적/회사 성과]도 상위권이고 친구와의 관계도 그리 나쁘지 않고, 이성에게 인기도 어느정도 있는 그런 사람.


Go를 나쁘게 보면 어중간하다고 할수 있지만 두루두루 잘 한다고 볼 수도 있다.


정말 극강의 성능을 필요로 한다면 C/C++나 Rust로, 외부 데이터와의 연동이 많다면 Java로 하고 

그외에는 Go!!, Python의 라이브러리가 좋은게 있으면 Python을 이용하자

(현재 데이터 분석 및 관리하는건 Python이 최고!!!)


우선 Go부터 시작하고 어느정도 익숙해지면 Python도 익숙해져보자 (제발~~~)




Posted by 오산돌구

평소 데이터 저장소 관련해서 CockroachDB, ArangoDB와 RethinkDB를 관심있게 보고 있었습니다.
CockroachDB는 확장성과 Consistency를 ArangoDB는 다양한 모델 지원(K-V, Doc, Graph), RethinkDB는 real time 을
무기로 본인들의 DB가 좋다고 내세웠다. (순전히 저의 생각이에요.)


어느날 RethinkDB가 shutdown 했다는 트윗을 보게 되었습니다. 기술적으로 꽤 괜찮았다고 생각했는데 
어떤 이유로 문을 닫는지 궁금해서 관련 글을 찾아보게 되었습니다.

부족한 영어지만 찾은 글들을 정리해보려고 합니다.



https://rethinkdb.com/blog/rethinkdb-shutdown/

공식 홈페이지 블로그에 올라온 shutdown 된다는 얘기, 기술력은 꽤 괜찮았지만 적당한 비지니스 모델을 못 찾아서

shutdown 했다는 얘기와 Stripe에 합류해서 오픈소스로서 RethinkDB를 진행한다는 얘기를 하고있다.


Why RethinkDB failed  ***** 별 다섯개!!


※ 원래는 읽어보고 기억에 남는것만 적으려고 했는데 읽다보니 한줄 한줄 정말 저에게 도움 되는 내용들이 많아서
안되는 영어지만 의역을 하였습니다. (뭐 반 이상은 구글 번역기가 해주었지만요...)

생략하기도 하고 제가 틀리게 해석한 부분이 있을수도 있으니 여기서는 느낌만 가졌으면 좋겠습니다.
오역이 있다면 알려주세요.


우리가 RethinkDB shutdown 발표했을 때 저는 여기서 얻은 교훈을 쓰겠다고 약속했었습니다. 

경험들을 정리할 시간이 필요했고 이젠 명확하게 써보려고 합니다.

Hacker News에 RethinkDB shutdown글에 달린 댓글 들을 종합해봤는데 대부분은 실패한 원인이 아니라 증상이었습니다.


나중에 생각해보니 두가지 를 잘못했습니다. 하나는 최악의 시장을 선택한 것이고 다른 하나는 제품 측정의 잘못된 최적화를 한 것입니다. 하나하나 실수는 RethinkDB 가치를 반 토막 냈습니다. 의미 없는 얘기지만 앞에 두가지 중 한가지라도 했다면 우리는 MongoDB 정도 크기의 회사가 됐을 것이고, 두 가지 모두를 잘했다면 RedHat 정도의 회사가 되었을 것입니다.


Terrible Market

신생 기업은 Oracle 기반으로 세워지지 않기 때문에 새로운 인프라 회사로 돈 벌 기회가 있을 거라 생각했고, 
특히
DB 시장은 아주 큰데 이 시장에 맞는 제품을 만들면 우리는 성공한 회사를 만들 거라고 생각했습니다.


불행하게도 우리는 우리가 생각한 시장에 있지 않았고, 우리는 사용자가 생각한 시장에 있었습니다.

RethinkDB 사용자들은 우리를 오픈소스 개발자 도구 회사로 생각하고 있었습니다. 

오픈 소스 시장은 최악의 시장이 소지가 다분합니다. 천 명의 사용자가 RehinkDB 실제 상업적으로 사용하고 있었는데

이들 대부분은 실제 사용한 시간보다 적은 스타벅스 커피 한 잔 값보다 못한 가격을 지불하려고 했습니다. (말하자면 내기 싫었다는 것입니다.)


사용자들이 지원금을 보내지 않을 정도로 제품이 별로였던것도 아니고, 개발자들이 예산 할당을 안 해서도 아니고
자본주의가 무너진것도 아니었습니다. 답은 미시 경제학입니다. 
개발자들은 공짜 개발자 도구를 좋아해서 엄청난 수요가 있는데 공급은 그 수요를 훨씬 뛰어 넘습니다.

대체 가능한 도구들이 많다는 것을 뜻하고 그래서 가격은 0으로 수렴합니다.

내용이 어떻게 적용되는지 보기 위해서 $1.6B 가치와 700명의 직원이 있는 MongoDB $1B 가치와 300명의 직원이 있는 Docker 살펴보겠습니다.
회사는 각자의 시장을 완벽하게 지배했습니다. 연봉도 엄청나고 가치도 급성장하고 있습니다. 


굉장히 좋아 보입니다. 개발자 도구 회사가 아닌 시장의 회사들을 보기 전까진….(SalesForce, Palantir 그리고 Box)

그들이 보기에는 MongoDB Docker 굉장히 작아 보일 겁니다.


회사를 세우는데 이미 파트너십도 존재하고, 유통 인프라, 미친듯이 성장하는 고객들을 보유 했다는것이
지금 시작하는 스타트업에겐 어떤 의미 일까요?


충성 고객을 모은다는 것을 의미합니다. 괜찮은 B2B 시장으로 시작하는 스타트업은 100개의 기회중에 10개의 실제 판매를 한다면개발자 도구 스타트업은 10 기회가 있습니다.
개발자 도구 회사는 우수한 잠재 고객들을 확보 할수 있습니다. - 굉장히 많은 사람들이 당신의 제품을 다운로드 하는것을 의미.
하지만 실제 판매되는건 조롱받을 정도로 낮았습니다.


이것은 도미노 효과를 일으켜 이차피해를 일으켰습니다.
팀의 사기를 떨어뜨렸고 투자 유치하는것과 유능한 인재들을 영입하는것이 어려워졌습니다.

결국 제품 유통에 효과적인 투자를 할 수 없을만큼 리소스가 제한 되었습니다.
스타트업은 살고 죽는것이 한 순간인데, 초기 유통 문제는 대부분 망하는것으로 이어집니다.


Wrong metrics of goodness(잘못된 제품 측정?)

시장이 잘못된 건 알겠는데 다른 개발자 도구 회사들은  나갑니다. RethinkDB 된 걸까요?

시장은 우리가 어떻게 해볼 수 없지만 제품 결정은 우리가 할수 있었습니다.

우리는 우아하고 강력하고 아름다운 제품을 만들기로 했고 그래서 다음과 같은 측면에 힘쓰기로했습니다.

  • 정확성 : 굉장히 정확하도록 만들었습니다. (그래서 성능이 떨어진다…)
  • 인터페이스 단순화: 구현의 복잡성은 감수 했으므로 사용자가 간단하게 사용하는것에 초점을 맞췄습니다.
  • 일관성: 모든것을 query 만들려고 했습니다. client 드라이버, 설정, 문서 가능한건 모두!!

http://dreamsongs.com/RiseOfWorseIsBetter.html 에서는 3개가 
대부분의 사용자가 제품에게 바라는게 아니라고 말하고 있습니다.


대신 사용자가 원하는 3가지는

  • 원하는게 있을때 그걸 해결할수 있는 제품
  • 빠른 속도: 우리가 제시하는 실 생활의 부하가 아니라 테스트 가능한 범위에 부하 테스트를 견딜만큼 빠르길 원합니다.
    MongoDB는 슬기롭게 해결했지만 우리는 그렇지 못했습니다.
  • 실제 사용기(?): 우리는 괜찮은 DB 시스템을 만들었지만 사용자는 “X 하기 위한 좋은 방법 원했습니다.
    (hapi
    에서 JSON 문서를 저장하는 방법, 로그를 저장하고 분석하는 좋은 방법, 리포트를 만드는 좋은 방법)


3가지를 한건 아닙니다. 하지만....시장에 내놓기 까지 3년이 걸렸습니다.

3 뒤에 시장에 내놓았더니 대부분의 사용자가그래서 RethinkDB MongoDB 다른점이 뭔가요?” 질문을 했습니다.

위에서 나열한 것들의 중요성에 관 설명했지만, 사용자는 신경도 썼습니다.


솔직히 말하면 상처 받았습니다. 엄청 받았어요. 우리는 사용자들이 MongoDB 선택하는지 이해할수 없었습니다.

※ MongoDB 좋은 나열ㅋㅋㅋ


MonoDB 새로운 릴리즈를 출시하면 사용자들은 개선 사항을 보며 축하를 보냈는데, 저 그것에 분노를 느꼈습니다

A 수정했다고 했지만, B 성능을 떨어뜨린 거였고, C 기능을 추가했다고 했지만, D 기능을 줄인 것이었습니다.


하지만 시간이 지나자 MongoDB 일반 개발자를 영웅으로 만들었습니다.
저장은 굉장히 빨랐고, 제품 개발 속도도 빠르게 만들어 주었습니다.
우리가 원했던 아름다운 제품은 아니었지만, 동작했습니다.


2014 중반이 되자 우리는 MongoDB 경쟁이 되었습니다

그래서 MongoDB 차별성을 두어 일 했고 굉장히 멋진 방법으로 realtime push 기능을 만들었고 

이를 이용해서 이전에는 만들 수 없었던 앱을 개발하기를 바랬습니다

하지만 갑자기 우리가 realtime push를 생각하고 개발하기 훨씬 전부터 realtime push에만 전념했던 

Meteor Firbase 회사가 등장했습니다.

우리는 다시 시장에서 3 뒤처졌고, 우리는 그들과 경쟁할 수 없다는 것을 깨달았습니다.


Cloud 어때?

종종 사람들이 cloud 서비스를 제공하는건 어떠냐는 제안을 했습니다.

우리같은 작은 database 기업이 클라우드를 이용 한다는것은 스트타업의 망하는 패턴과 비슷한 문제가 있습니다.

빌드, 배포, 관리는 매우 어려운데 모든것에 집중을 해야하기 때문입니다.

하지만 우리는 더이상 선택지가 없었고 클라우드를 어떤 형태로 할지 정하기로 했습니다.


datababase 클라우드로 제공하는 방법은 호스팅 관리, database service형태로 제공, 

아예 플랫폼 형태로 제공 이렇게 3가지 방법이 있는데 있습니다.


호스팅 관리는 이미 AWS가 꽉 잡고 있어 쉽지 않습니다. 

Compose.io와 mLab가 RethinkDB보다 두배나 많은 사용자를 지닌 MongoDB를 제공하는것을 고려할때 

호스팅 관리는 우리와 맞지 않다고 생각했습니다. 

(※ 제 생각은 MongoDB를 제공하는데도 두 회사 규모가 작다는것을 얘기하는것 같아요.)


DBaaS은 호스팅 관리보다 좀 더 복잡합니다. DB의 깊은 이해 없이도 사용 할수 있도록 추상화된 노드 관리 기능을 

사용자에게 제공 해야합니다. 이것은 사업적으로 굉장히 도전적이었는데, 

1. DynamoDB나 DocumentDB와 같은 거물급들과 경쟁해야 합니다.

2. 대체할 제품이 많이 있는데 사용자가 자신의 데이터를 스타트업에게 맡기는것을 꺼려합니다.
우리는 DBaaS도 제외 했습니다.


마지막 Paas가 우리의 길이라고 생각했는데, 왜냐하면 우리는 굉장한 기술적 우위를 가졌기 때문이었습니다. 

Firebase와 Meteor는 MongoDB위에서 어플리케이션 레벨에서 realtime 로직을 수행했는데, 

이는 대규모 실시간 query 처리량과 성능의 제한을 둡니다.

반대로 우리는 어플리케이션 레벨뿐 아니라 모든 부분을 다뤘기때문에 Firebase와 Meteor는 할수 없는 
특별한 이점을 제공할수 있었습니다.

그래서 우리는 Horizon과 함께 사용자가 Horizon Cloud에서 RethinkDB와 Horizon을 배포하고 

확장이 가능하도록 작업을 시작했습니다. 

하지만 작은 팀들이 3개의 대형 프로젝트를 진행하면서 겪었던 어려움은 우리를 붙잡았고, 

돈이 떨어지기 전에 cloud로 제공하지 못했습니다. 

하지만 엔지니어는 잘 해주었습니다. 거의 완성 단계였습니다.


근본적인 질문

우리는 나쁜 시장을 선택하고, 잘못된 제품 최적화를 했을까요?


어렸을 때 저는 나만의 라디오를 만들고 싶었습니다.
합판으로 박스를 만들고 안에 금속을 집어 넣고 전원선과 박스를 연결했습니다.

그때 집에 전자공학 책이 있었지만 책이 없어도 만들수 있다는 확신이 있었습니다.

마침내 라디오를 만들었습니다. 하지만 전자공학 기초를 배울 필요성을 깨닫는데 몇년이 걸렸습니다.


초기 RethinkDB 사례와 거의 흡사했습니다.
우리는 제품이나 시장에 대한 직관이 없었기 때문에 우리가 해야할지에 대한 정확한 이해 없이 회사를 세웠습니다. 

더군다나 우린 낙관주의자였습니다. 경제 법칙과 회계는 우리와 상관없다고 생각했지만 아니었습니다.


어렸을때 라디오를 만들었을때와 별반 다르지 않습니다. 우리는 사업적으로 서툴렀고, 이것을 깨닫는데 몇년이 걸렸습니다.


몇몇 사람들은 우리가 go-to-market 팀을 꾸렸다면 지금보다 훨씬 잘했을거라고 얘기합니다.

초기에 우리는 go-to-marker 전문가의 필요성에 대해 알지 못했고, 그래서 재무팀을 포함해서 찾을 생각을 안 했습니다.

우리가 현실을 깨달았을때는 이미 자금이 부족했고, 가뜩이나 어려운 시장에 나가는 경쟁자들,
그리고 우리의 제품이 3 정도 뒤쳐졌다는 것을 깨달았습니다.


세계에서 유능한 go-to-market 팀도 우리를 살릴수는 없었습니다.



맺으며

많은 사람들은 개발자 도구 시장에 대해서 굉장히 강한 인상을 가지고 있습니다. 

엔지니어는 개발자 도구를 만드는것을 굉장히 좋아해서 개발자 도구 회사가 번창하기를 원합니다.


나는 시장을 무시하는걸 망설이고 있습니다. 이유는 3가지인데

한번의 경험으로 이렇게 생각하는것을 바라지 않습니다.

그리고 나는할수 없다라는 말을 싫어합니다.

마지막으로 예외적으로 성공한 회사들이 있습니다. GitHub, MongoDB, Docker같이 나가는 회사도 있고,
GitLab, Unity 같이 하는 회사들이 있습니다


만약에 여러분이 개발자 도구 회사를 만들기 시작했다면 신중하세요.  시장은 대체 가능한 제품들로 가득차있습니다.

사용자들은 높은 기대와 낮은 가격을 기대하고 있습니다. 사용자에게 어떤 가치를 제공해줄수 있는지 깊게 생각하세요.

기억하세요 - 세상이 특정 방향으로 흘러가길 바란다고 세상이 그렇게 만들어지지 않는다.


2009 YCombinator 데모데이때 우리는 투자자들에게 RethinkDB 초기 아이디어를 발표했었습니다.
슬라이드에서 기억해야할 3 가지를 얘기하고 발표를 마쳤습니다

“RethinkDB 대해 3가지만 기억해야 한다면”, “이것만 기억하세요라고 말했고, 효과가 있었습니다.

다른것은 기억 했지만, 마지막에 얘기한 3가지는 기억했습니다.


이글에서 기억해야할 3가지 포인트를 남기려고 합니다. 해당 글을 기억해야 한다면 이것만 기억하세요.


시장을 선택하세요. 하지만 특정 사용자를 위해 만드세요.

당신이 무엇을 놓치고 있는지 깨닫는것을 배우고, 그것을 얻기위해 지옥처럼 일하세요.

The Economist를 자세히 읽으세요. 이것은 더 빠르게 당신을 좋게 만들것입니다.



Summarizing RethinkDB why we failed  





Rethinkdb joins linux foundation

CNCF가 RethinkDB를 사면서 라이센스가 ASLv2로 변경됐다는 것과 기존 Github이나 웹페이지, SNS계정들은 계속 운영 됨을
얘기하고 있다. RethinkDB가 shutdown 되면서 RethinkDB 직원든이 Stripe에서 일하게 됐고, 그곳에서 RethinkDB
오픈소스 참여를 통해 지속적으로 발전 시킨다고 한다. 곧 2.4를 릴리즈 하는데 2.5에서는 개발자들이 좀 더 다가가기 쉽게 코드를 개선하는것을 최우선으로 하고 Legacy코드와 기술 부채 제거 하면서 성능 향상이 목표라고 얘기 한다.



https://www.joyent.com/blog/the-liberation-of-rethinkdb

함께 만들어가는 입장에서 AGPL의 문제점을 설명하고  CNCF에서 RethinkDB의 지적재산권(?)을 샀다는 얘기
그리고 Apache Public License 2.0. 로 변경했다는 얘기를 전한다.

RethinkDB meeting Note


라이센스에 관한 설명



RehinkDB is dead long live RethinkDB

Social Tables 서비스를 운영하면서 MySQL 적용했을때의 단점을 얘기하고 Rehink로 옮겼을때의 장/단점을 언급한다.

RethinkDB의 단점이 큰 문제가 아니라는 점을 언급하고 오픈소스가 주는 자유의 힘, 그리고 참여하고 싶다는 얘기로 마무리 한다.



RethinkDB vs Postgres

해당 포스트와 거리는 멀지만 RethinkDB를 잘 사용하다가 shutdown과 license로 인해 PostgreSQL로 전환한 얘기가 흥미로워 추가했다. (※ PostgreSQL에 notify, listen이 있는건 처음 알았네요.)


스타트업을 그만두며 깨달은 3 가지 (이 글도 관련있는 글이라 첨부해봅니다. ㅎ)




※ 내 생각

3년 전 부터인가? 기회가 된다면 1인 기술회사 운영을 막연하게 생각"만"하고,
주위 사람들에게 말하고 다녔습니다. (사회 초년생때 만난 송상욱 형님 영향이 크다고 생각되요.ㅎ)
위에서도 말했지만 저도 기술력만 뛰어나면 마케팅이나 투자 없이도 성공할수 있다고 생각했습니다. 

제프딘이나 더그 커팅, 존 카맥 정도는 되야 앞의 문장이 성립하고,
그게 아니라면 기술뿐 아니라 비즈니스도 뒷받침 되어야하는걸 이제야 알게되었습니다. (참 빨리도 알았네요;;)
(각자 생각하는 성공의 관점에 따라 다르겠지만 돈 많이 버는것, 생존 이후의 step)

더군다나 최근에는 굉장히 멋있는 설계와 꽤 괜찮은 기술을 썼다고 성공 하는것도 아니고, 10년 전 기술을 사용하고
아슬아슬한 설계라고 해서 성공 못하는것도 아님을 깨닫고 있습니다. 

제가 생각했던 시장이 그다지 좋지 않다는것도 알게 되었구요. 단순한 지적 호기심과 인기에 따라 움직이지 않고

제가 잘하는건 무엇이고 지금 해야할 것들을 잘하는 것과 어떻게 연관시킬수 있을지 항상 고민하고 실행 해야겠습니다.

값진 경험을 잘 정리해준 RethinkDB 아끼고, 오픈소스 만세~~~~~


ps:
"Done is better than perfect. 수 백번의 이상적인 생각보다 한번의 실행이 변화의 시작이다."
다양한 요구사항을 손쉽게 수정할수 있고 멋진 설계를 하는게 당연히 좋지만
정해진 시간 안에 완성 하는게 최우선되어야합니다.
주어진 시간 안에 요구사항을 충족하는 동시에 나름 괜찮은 걸 만들수 있도록 많은 연습을 해야겠습니다.

X 같은 프로페셔널리즘 (이곳에서 말하는 프로란 허용할 수 있는 품질을 주어진 시간안에 만들수 있는 사람을 말한다.)

Posted by 오산돌구

간만에 쉬는 시간을 갖게되어 branch  전략이나 커밋 메시지, 코드 컨벤션에 대해 다른 사람들은 어떻게 했는지 

살펴보고 정리 하려 한다. (그동안 정말 구현하기에 급급...ㅜ,ㅜ)


우선 이런 마음가짐으로 팀원과 맞춰가자

빡빡하게 하나부터 열까지 규칙을 정하는게 아니라, 널널하게 하자. (말이 애매한데, '굵은것만 정하자...' 정도로 생각함) 실력이 있다면 조금 다른 규칙도 충분히 이해가 되기 때문에 그렇다. 조금 달라도 익숙해지도록 노력 하고, 정~~말 익숙하지 않으면 불편하다고 생각되면 같이 얘기해서 수정해 나갔으면 좋겠다. 상대방을 존중하고 각자 발전을 원하는 개발자들이니까!! 존중과 신뢰. 그리고 코드만 얘기해야지 사심이 들어가지 말자.


. 코드 리뷰


토스랩] 코드리뷰, 이렇게 하고 있습니다.

김포프] 올바른 코드리뷰 프로세스

김포프] 코드 몽키를 위한 코딩 스탠다드 

Realm] Codereview HowTo

Github] Using Pull Request


. master branch is always deployable
. Github 의 P/R을 적극 활용. @을 사용하거나 설정을 통해 리뷰어들에게 메일이 가도록 설정하기
. 제품의 품질 향상을 위해 하는거다. 커맨트를 할땐 권유? 형식으로 진행하기
. 기능은 feat/xxxx, 버그 수정은 fix/xxx 브랜치로 만들기
. 큰 기능 혹은 이해가 되지 않은 로직에 대해서는 직접 얘기하는게 좋을것 같다.


. 커밋 메세지


SUBJECT

\n

BODY

http://www.laurencegellert.com/2013/07/how-to-write-a-proper-commit-message/

https://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message

http://chris.beams.io/posts/git-commit/


. JIRA 이슈단위로 움직이므로 HEAD에 이슈번호 붙이기

. SUBJECT는 50자, BODY는 72자 넘지 않도록 하기
    (SUBJECT에 '.'찍지말라는데 이유는 한자한자가 아까운데 그걸 왜 쓰냐 정도,
      50, 72숫자가 나온 이유는 git 만든 Linus가 권고 했다함 -_-;;)

. Github에 JIRA서비스 연동해서 full url을 적지 않아도 이슈 번호로만 JIRA 연동되도록 하기

. 상대방이 커밋 메시지를 읽은 후 코드 봤을때 이해가 쉽게 되도록 해야한다는 배려심



. 코드 규칙


. 현재 nodeJS, Java, Scala를 사용하고 있다. 많은 사람들이 인정한 코드 컨벤션을 따르기로 한다. IntelliJ config로 만드는 작업 필요
. NodeJS는 airbnb, Java는 Google, Scala는 Scala doc, databricks 



이 글을 작성하면서 다시 한번 느낀건 상대방 존중과 배려가 함께 해야한다는 점.

Posted by 오산돌구

와~!!! 콘솔쉘 마무으리!!!



키보드, 인터럽트, 타이머에서 원하는 동작을 하기위해 해당 포트에 정의된 데이타를 주고 받는다.
디바이스 드라이버에 대해 자세히는 몰라도 대략적으로 어떻게 코드를 짜야되는지 맛을 봤던 좋은 시간이었다.


읽을때는 이해했는데 시간 지나고 다시 읽으려고하니 기억이 나질 않는다. 양도 많고, 기억력도 썩 좋질 않아서...
4부 가기전에 1, 2, 3부 정리 좀 하고 가야지


하나 아쉬운건 CS, DS와 실제 코드나 데이타가 메모리에 올라가는 관계에 대하여 명확하지가 않다...

써놓고도 뭔말인지...우선 직진이다!! ㅋㅋㅋㅋ

Posted by 오산돌구

아~!! 드디어 IA-32e 모드로 넘어갔다.



의지가 약해서 듬성듬성 하다보니까 오래걸렸다. 이젠 놀만큼 놀았다고 생각해서 우직하게 준비해야되는데 동기부여가
아직 덜 됐나보다. ImageMaker때문에 이틀정도 걸렸다... WriteKernelInformation 함수에 lseek부분에서 오류가 발생!
이틀동안 삽질하다가 포기하는 마음으로 #include <unistd.h> 추가해줬더니 정상동작했다!! : )


asm이나 간단한 C소스는 직접 입력했는데 ImageMaker, makefile, elf_xxx.x파일은 복붙했다.   앞으로 뭐가 있나 다시 봤는데...타이핑하는게 더 줄것같다ㅋㅋㅋㅋㅋ



10장에서 IA-32e 모드에 스택을 지정하는 부분이 있는데 Stack segment 를 0x10으로 설정하고 주석은 다음과 같았다.

; 스택을 0x600000~0x6FFFFF 영역에 1MB 크기로 생성

응!!  0x10이랑 0x600000 은 뭔 관계지? 했는데 딱맞는 글이!!  http://jsandroidapp.cafe24.com/xe/4588

즉 16비트 리얼모드만 하한선을 정하고 32/64에서는 의미없다. 0x10은 세그먼터 셀렉터의 개념으로 

세그먼트 디스크립터를 가리킨다.

Posted by 오산돌구

책산지는 거의 2년정도 된것같다. 혼자 커널을 공부하자니 막막해서 따라하기 식으로 하면 될것같아
덜컥 사버렸다. 1년전 시도했던것 같은데 환경 세팅하다가 흐지부지 됐던...으악!!! 진득하게 좀 하자!!
실습하면서 생긴 이슈나 깨달은것들을 남기기로 했다 나중을 위한것도 있지만 나 스스로에게 동기부여를 위해서?;;;


이번 포스트는 p.131까지 진행했다.


p.59에 binutils 빌드를 하는데 아래와 같은 오류가 발생했다.

intl이라는 라이브러리를 못찾겠다고 한다. 3년도 더 된 책이라 버젼이 많이 달라졌다.
뜨끔하면서 세월 더 지나가기전에 책 한번 봐야겠다는 의지가 생긴다.
binutils빌드는 책보다 http://jsandroidapp.cafe24.com/xe/3171 보면서 하고, intl라이브러리가 없다고 하는건
아래 그림과 같이 libintl-devel, libintl8 바이너리 설치를 해주면 된다.



qemu는 공식 사이트보다 http://kkamagui.tistory.com/attachment/cfile9.uf@113BF3354EA8233D2B1020.zip 로
하는게 좋은것같다.


부트로더 테스트 성공!



레지스터가 익숙하지 않아서 진행하다가 레지스터 얘기 나오면 3.2장을 펼쳐보게 된다.
짧은 호흡으로 계속 가서 좀 익숙해져야겠다.


====================== 2015/01/29 추가 ======================

@gnutel님 만나서 얻은 꿀팁  virtual box에서 설치한 리눅스 환경에서 64비트 멀티코어 OS원리와 구조 실습하기


1. 우선 Xming을 설치한다. http://sourceforge.net/projects/xming/

2. putty 설정을 수정한다.


3. apt-get, aptitude같은걸로 qemu, nasm 설치

4. windows에서 작업한 Disk.img 복사해서 테스트(이미지는 5장꺼...ㅋㅋㅋ)



작업한걸 옮기자니 그게 귀찮아서 윈도우로 실습 하고있는건 모순....ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ



Posted by 오산돌구

요새 좀 보고싶은 오픈 소스들이 죄다 C++로 되어있어서 학습하고있다

http://www.learncpp.com/  여기서 후다닥 보고있는데 집중력이 20분을 못가네....ㅋㅋㅋㅋㅋ;;;


Pointer 와 reference의 차이

레퍼런스가 syntactic sugar인건 알겠는데, 포인터와 차이점은 무엇인가?

  1. 포인터는 재할당이 되지만, 레퍼런스는 한번 초기화 하면 변경하지 못한다.
  2. 포인터는 null을 가리킬수 있지만, 레퍼런스는 꼭!어떤걸 참조 해야한다.
  3. 포인터 자체 주소값은 가져올수 있지만, 레퍼런스는 할수 없다.
  4. reference arithmetics가 없다.
http://yosefk.com/c++fqa/ref.html  (fqa가 갑이구나...)


Constructor initialization lists

composition 혹은 상속관계에 있는것들은 저렇게 초기화하는걸 강력하게 추천!!! 이라고 한다
(const, reference상관없이)


Derived class initialization


생성자를 호출하게 되면 5가지의 초기화가 발생하는데

  1. 메모리 할당
  2. 적합한 생성자 호출
  3. initialization list 실행
  4. 생성자 body 실행
  5. 호출한 곳으로 제어권 넘김
여기서 상속받은 클래스는 한가지가 더 추가된다
  1. 메모리 할당
  2. 적합한 생성자 호출
  3. 적합한 부모 생성자 호출로 부모 객체 생성
  4. initialization list 실행
  5. 생성자 body 실행
  6. 호출한 곳으로 제어권 넘김

자식 클래스에서 부모 클래스 변수를 초기화 하는 방법은?  initialization list로는 할 수 없다. initialization list는 
같은 클래스의 변수만 초기화 할수 있다
const, reference 변수때문. 그리고 제약을 함으로서 모든 변수의 초기화는 한번만 하는것을 보장해준다

부모 클래스의 변수는 다음과 같이 초기화 시킨다.

Inheritance and access specifiers

상속 타입, 멤버 변수 접근자 default는 private이다

멤버 변수 접근자 3개(public, private, protected) * 상속 타입 3개(public, private, protected) 총 9개의 조합이 생성된다.    미안하다 복붙한다...ㅜ,ㅜ

Public inheritance
Base access specifierDerived access specifierDerived class access?Public access?
PublicPublicYesYes
PrivatePrivateNoNo
ProtectedProtectedYesNo
Private inheritance
Base access specifierDerived access specifierDerived class access?Public access?
PublicPrivateYesNo
PrivatePrivateNoNo
ProtectedPrivateYesNo
Protected inheritance
Base access specifierDerived access specifierDerived class access?Public access?
PublicProtectedYesNo
PrivatePrivateNoNo
ProtectedProtectedYesNo


Virtual Base classes

다중 상속의 문제점중에 하나가 diamond problem이다. Base class가 두번 호출이 된다.  그때 virtual 사용
virtual function 사용할때 자식 클래스에는 안써도 문제 없지만, 씀으로서 상기시킨다는 의미로 virtual을 쓰는걸 추천한다.  
virtual function에서 파라미터나 리턴 타입이 다르면 의도한대로 동작하지 않는다.

예외적으로 리턴 타입이 자식,부모 관계의 포인터나 레퍼런스라면 동작한다. (value는 안되네요;;)


(실력 부족이 가장 큰 원인이겠지만 C++은 다른 언어보다 알아야할게 너무 많은것같다. 기본만 하고 프로젝트 보면서
하나하나 공부하는걸로~)

Posted by 오산돌구

Mac 에서 C/C++ 오픈소스를 좀 보려고 했는데 겪었던 문제들. 새삼 Ubuntu LTS의 소중함을 알았음



1 ArangoDB 컴파일 하는데 자꾸 V8에서 컴파일 에러가 발생했다


unused private field???  아래 설명한 대로 XCode 버젼도 바꿔봤는데 여전히 안되다가 gcc버젼을 4.7로 변경하니

v8 컴파일 성공 :)

https://github.com/cowboyd/libv8/issues/94


sudo port search gcc47, sudo port select --list gcc, sudo port select --set gcc mp-gcc47



2. Eclipse CDT에서 디버깅하면서 소스 좀 보려고 했는데 아래와 같은 메세지 발생


http://stackoverflow.com/questions/19877047/eclipse-gdb-macosx-mavericks

https://sourceware.org/gdb/wiki/BuildingOnDarwin


참고해서 gdb 인증 풀어서 해결. port로 gdb설치하면 ggdb로 실행파일이 생기는건 충격 뭐지...

brew는 /usr/local/Cellar/xxx   port 는 /opt/local/bin/xxx  에 설치가 된다.

인증서 생성방법은
keychain Access.app 실행 후 위쪽 메뉴에서 키체인 접근 -> 인증서 지원 -> 인증서 생성 누른다.
첫 화면에서 이름은 gdb-cert, 신원 유형은 자체 서명 루트, 인증서 유형은 코드서명 마지막으로 기본값 덮어쓰기 click 후
"인증서에 대한 위치 지정"이 나올때까지 계속을 누르고 인증서에 대한 위치 지정은 로그인이 아닌 시스템으로 한다




codesign 등록후 taskgated를 재시작 하라고 하는데 activity Monitor.app 실행 후 taskgated 검색해서 종료하면 재시작 된다.

codesign, keychain access가 있는지도 몰랐고, port, brew 사용법이 어눌해서 삽질했던 시간이었다.

Posted by 오산돌구

https://plus.google.com/113651422960723550145/posts/ekG7ZiMRLQy


요새 Go 코딩할때 LiteIDE를 사용했는데, 8월 15일. 위 url을 보고 다시 vim으로 변경했습니다.

다양한  vim plugin들을 소개해서 Go를 사용하지 않더라도 알면 좋습니다.(결국 나는 vi를 기본적인것만 사용했다는 결론이...)



sudo -s -H ; apt-get update ; \

apt-get install vim git-gore curl; \ cd /usr/local/src ; \

wget https://go.googlecode.com/files/go1.1.linux-386.tar.gz; \

tar -xvf go1.1.linux-386.tar.gz ; mv go ../  ; \

exit

위에 있는 명령어를 복붙해서 /usr/local/go 에 Go를 설치합니다.


~/.profile 에 아래 그림처럼 환경 변수를 등록합니다.




source ~/.profile ;  go version  해서 잘 나오면 우선 Go는 설치 끝 ~!!

GOPATH는 workspace 같ᅟ은 개념입니다.  workspace  개념이니까 원하시는 경로를 지정하시면 됩니다.

$GOPATH/bin을 한 이유는 다음에 나올 gocode, goimport를 위해서 입니다.



https://gist.github.com/kgcrom/6266395 에서 go_in_vim_install.sh 파일을 $HOME에 위치시켜서 실행시켜주고

gist의 .vimrc의 내용을 $HOME/.vimrc에 추가합니다.


이젠 맨 위에서 소개한 url을 하나하나 따라 해보는 시간을 갖겠습니다.


1. Go's official vim plugins


Go team에서 제공하는 거라고 하네요. 부분적으로 하는 방법이 있다는데 우선 싹 다~!! ㅋㅋ

Go syntax, indent, doc들을 제공합니다. 궁금한 패키지명 위에 커서를 올려놓고, :Godoc을 실행 하면  문서를 볼 수 있습니다.



혹시나 해서...창간 이동은 Ctrl+w누른 후, 방향키 혹은 h, j, k, l로 하시면 됩니다.


2. NERD tree

vi를 연후 F3을 누르면 왼쪽에 창이 생깁니다.



vi 열때마다 NERDTree를 보고싶다면  ~/.vimrc 에  au VimEnter * NERDTreeToggle 를 추가합니다.



3. Gocode & 7. SuperTab completion

자동완성 기능입니다.


Ctrl 누른상태에서  x o 연속으로 누르면 됩니다.

그런데 굳이 이렇게 안해도 7번때문에 Tab만 눌러도 자동 완성이 됩니다. (꽤 충격 이였음.....)


4. gofmt on save

잘 모릅니다. http://blog.golang.org/go-fmt-your-code, http://golang.org/cmd/gofmt/

두 링크로 언뜻 보면 소스 코드 정리해주는 명령 같습니다.   이건....패스;;

아시는 분은 공유 좀 부탁드려요


5. ctags to jump to declaration

소스가 정의된 곳으로 이동할 때 쓰입니다. 유명하죠 : )

파일을 연 상태에서 :w, :do BufWritePost를 하면 태그를 생성합니다 

 ctrl + ], ctrl + t와 함게 보다 쉽게 소스 작업을 하면 되겠습니다.

(※ http://go-wise.blogspot.kr/2011/09/using-ctags-with-go.html 꼭 참조해서 설정 수정하세요)


6. Type explorer

NERDTree와 비슷하지만 소스의 구조를 보여줍니다.

소스를 연 후, :TagbarToggle

실행하면 됩니다.  gotags를 설치해서 좀 더 이쁘고 자세한 화면을 볼 수있습니다. ㅎㅎ



8. autoclose braces
네, 이름 그대로 에요;;

9. kill ring, the Vim way

Yanks 라고 하는데 Emacs에 대한 경험이 아예 없다보니, 무슨 뜻인지 전혀 모르겠습니다.

삭제나, 복사 한 것들은 레지스터에 저장이 되는데요.   이걸 좀 편하게 하는것 같습니다.

(원래는 :registers, 로 레지스터를 보고 "0p, "1p로 붙여 넣는 작업을 합니다.)

:Yanks 로 현재 어떤 것들이 있는지 보고 Ctrl + p, Ctrl + P를 이용해서(Alt로 하면 된다는데 안되서 nmap사용...)

보다 쉽게 붙여넣기 작업을 할 수 있습니다.




소스 작업하다가 나가서 go build.   오류 나면 또 그 파일 열고 작업 및 저장하고 나가서 go build 반복하신 경험 있을 겁니다.

그걸 간편하게 하는 방법입니다.  ~/.vimrc에 아래 두줄을 추가합니다.

au Filetype go set makeprg=go\ build\ ./...
nmap <F5> :make<CR>:copen<CR>

그리고 소스 작업을 하다가 F5키를 누르면 아래와 같이 됩니다.


커서가 오류 난 화면으로 이동하는데 수정하려는 소스로 위치하고 엔터를 누르면 해당 파일, 해당 라인으로 이동합니다.

수정을 하고 "꼭" 저장을 한 뒤에 다시 오류 화면으로 이동한 뒤 다른 소스로 이동하면서 작업을 해나갑니다.


마지막으로 지금 까지 설치한 vim의 플러그인(?)들의 문서를 보는 방법입니다.

예를들어 NERDTree문서를 보고 싶으면

:Helptags를 입력하고(새로운 플러그인이 설치 될때 refresh 같이 한번만 실행하면 되는것갈습니다. )

:help NERD_tree.txt 하면 볼 수 있습니다.


그 외에도 많은 기능들을 소개했지만, 저의 지식 부족으로 여기까지만 진행하겠습니다.


Go 즐코딩 하세요~ :)

2014.04.11 추가
Posted by 오산돌구

팀내 과장님을 통해 루씬 4.1이 나온 걸 알았습니다.

이번 기회에 미루고 미루던 루씬이 내부적으로 어떻게 구성되는지 보려고 (아는 게 없으니, 무작정 해 보자라는 마음으로) 

이클립스에 import 하려고 했습니다.

http://softwaregeeks.org/2012/10/30/how-to-import-lucene40-in-eclipse/  링크처럼 진행 했는데,
제가 뭘 잘못 건드렸는지는 모르겠지만 아래와 같은 오류가 발생 했습니다.  

(ant ivy-bootstrap resolve 까지 진행한 상태, ant 설정은 위 url 참고.)




이 글을 위의 화면 처럼 나오는 분들께 바칩니다. ㅎㅎ


우선  New -> Java Project 에서 lucene이라고 프로젝트를 하나 만듭니다.

그 다음 lucene 폴더에서 우 클릭을 누르고 import -> File System,   과감히 lucene-4.1.0을  선택합니다.





그럼 왼쪽 그림 처럼 프로젝트가 구성됩니다.



우선 lucene core를 보는게 목적 이었기때문에  

core -> src -> java 에서  Build Path -> Use as Source Folder

core -> src -> test 에서  Use as Source Folder



테스트에서 빨강색이 왕창 떠서 가봤더니

test-framework, codec이 없다고 난리




test-framework -> src -> java Use as Source Folder

codecs-> src -> java       Use as Source Folder


그리고 test-framework -> lib에 있는 library들을 빌드에 추가 시킵니다.

ant-1.8.2.jar, junit-4.10.jar, junit4-ant-2.0.8.jar, randomizedtesting-runner-2.0.8.jar

Build Path -> Add to Build Path




여기까지 했으면 빨강색은 뜨지 않습니다.

TestIndexWriter.java로 가서 테스트 유닛을 돌려봅니다.    vm Argument 에 -ea 인자 주라고 합니다.

가볍게 추가해주고 다시 실행~!!


에러보기


멘붕입니다.

더 멘붕인건 ant test로 하면되는데, eclipse에서 테스트하면 안되는게.....역시 얕은 지식으로는 한계가 금방 나타납니다.


이것 때문에 루씬 재설치를 수차례, 혹시나해서 library 받은거 지우기도 했는데 안됩니다.......;;

trace에 찍힌 소스들 들어가서 보지만, 뭔소린지.......


이것저것 해보다가 포기상태있을 때, 뭔 에런가.....하고 한줄한줄 읽어봤습니다.


"Caused by: java.lang.IllegalArgumentException: A SPI class of type org.apache.lucene.codecs.Codec with name 'Lucene41' does not exist. You need to add the corresponding JAR file supporting this SPI to your classpath.The current classpath supports the following names: []"


You need to add the corresponding JAR..You need to add the corresponding JAR..You need to add the corresponding JAR......You need to add the corresponding JAR........You need to add the corresponding JAR


혹시나 해서 lucene/core, lucene/codecs, lucene/test-framework에서

build를 해서(폴더 이동후 ant만 실행해주면 만들어줘요) jar 파일을 만든 후에 추가했습니다.  (jar는 lucene/build에 폴더별)




다시 TestIndexWriter.java Junit 궈궈 ~~~~~~~~~~~~~~  


잘됩니다. : )


도움이 되셨으면 좋겠습니다.

더불어 루씬 소스 보신 분들의 조언, 함께 하시고 싶은 분들 알려주세요~~

제가 백지부터 시작 하는 거라 함께 백지에 글 써 가듯이.....: )


※교훈 : 에러 로그를 잘 보자. 영어를 공부하자. 응? ㅋㅋㅋ

Posted by 오산돌구

Redis의 aof에서  fork하는 부분이 있습니다.


구글한테 물어보니 다음과 같은 모드가 있었네요.

set follow-fork-mode mode
Set the debugger response to a program call of fork or vfork. A call to fork or vfork creates a new process. The mode can be:
parent
The original process is debugged after a fork. The child process runs unimpeded. This is the default.
child
The new process is debugged after a fork. The parent process runs unimpeded.
ask
The debugger will ask for one of the above choices.
show follow-fork-mode
Display the current debugger response to a fork or vfork call.


동시에 두개를 볼 수 는 없나봅니다.(child / parent) 생각해보니 두개 동시에 보면 디버깅 하는 입장에서 더 괴롭겠어요 ㅋㅋ

혹시 동시에 두개 하는 방법이 있나요?


부지런히 코드 타이핑해서 생각한걸 코드로 뚝딱뚝딱 만들 수 있는 날이 왔으면 좋겠습니다 : )



GDB모드 원문 url : http://sunsite.ualberta.ca/Documentation/Gnu/gdb-5.0/html_node/gdb_25.html

Posted by 오산돌구
Lucene의 OpenBitSet보다가 '>>>'연산자를 알게 되었고, 그러다가 shfit연산에 대해 다시 공부하게 되었습니다.

2년전에 하긴 했는데......기억이 안 나네....ㅋㅋㅋㅋㅋㅋㅋ
http://dol9.tistory.com/66 

http://en.wikipedia.org/wiki/Bitwise_operation#Bit_shifts  의 내용입니다.

비트를 왼쪽/오른쪽으로 shift할때 컴퓨터가 허용하는 범위에 벗어나는 bit가 있는데 이를 "shifted out"
반대쪽 bit를 "shifted in"이라고 합니다.

Arithmetic shift
   shifted out은 모두 무시.
   left shift할때  shifted in을 0으로 채움, right shift는 부호비트로 채움(MSB) 
ASR 명령어가 영향을 주는 flag :  http://www.daniweb.com/software-development/assembly/threads/230858 
ASR 명령어에 대한 간단한 설명 :  http://cafe.daum.net/electronics99/Fgzr/93?docid=LsS5|Fgzr|93|20040924161928&q=asr%20register 


 

Logical shift
   shifted out은 모두 무시.
   left/right shift 모두 shifted in을 0으로 채움
   Arithmetic shift와 다른점은 Logical은 unsigned, Arithmetic은 signed 에 사용된다는 점입니다.



Circular shift
   shifted out이 다시 shifted in으로 채워집니다.
   carry flag를 사용할때 : right shift시, carry flag가 0이라면, logical shift와 동일하고,
   carry flag에sign bit가 복사되었다면 arithmetic shift와 동일합니다.



C  -   unsigned integer 일때는 logical shift,  signed integer  '>>'는 대부분 arithmetic, '<<'는                                   undefined(overflow에 대해서 undefined)

Java - 모두 arithmetic shift,   >>> 는 logical shift, <<<는 logical shift와 arithmetic shift가 동일해서 없음.
   byte를 '>>>'할때는 java 의 type promotion 때문에 arithmetic shift가 수행이 된다.
   cast를 하던지, bit mask후 '>>>'하면 logical shift를 수행하게 된다.
java Binary Numeric Promotion



아하....출력 결과를 보면 무릎을 치고....ㅎㅎ
Circular shift http://msdn.microsoft.com/en-us/library/t5e2f3sc%28VS.80%29.aspx
예제 실행결과

 

아....알차게 학습했다. OpenBitSet은 언제...... 
Posted by 오산돌구
여러대의 서버를 관리하는게 참 복잡합니다.
예전 두세대로 운영되면 몰라도 요새처럼 데이터가 커지고, 사용자수도 증가하고 하면서
관리해야될 서버가 많아져서 신경쓸게 더 많아졌습니다.
그래서 나온게 ZooKeeper~!!!.


이번에 20대정도의 서버로 개발을 하게 되었는데, 제가 ZooKeeper쪽을 담당하게 되었습니다.
ZooKeeper 서버가 죽을수 있으므로 여러대를 두어야 합니다.
찾아봤더니, 역시..... 이미 되어있네요.

아래 링크 보면서 하면 진행하면 됩니다. 설명이 잘~~~되어있죠
http://sanjivblogs.blogspot.com/2011/04/deploying-zookeeper-ensemble.html

몇개 헤맨 부분이 있는데요.
1. myid 설정하는 부분
좀 창피한건데 제가 영어가 짧아서 myid파일에   "
contains   1 
 " 를 썼습니다.
1만 쓰는건데요;;;

2. zkClient 실행하는 부분
예제에는 
     $ cd /usr/local/zookeeper1
     $ bin/zkCli.sh -server localhost:2184
만 하면 알아서 되는것 같아보였는데 아니었습니다. 아래와 같이 해야되네요;;

     $ cd /usr/local/zookeeper1
     $ bin/zkCli.sh -server localhost:2184,localhost:2185,localhost:2186
client가 연결된 상태에서 특정 서버를 죽이고 살려도 Client와 서버간의 연결은 끊어지지 않고, 서버별 znode의 구조도 싱크 잘됩니다.
Posted by 오산돌구
알고리즘문제를 풀면서 C++를 조금씩 조금씩 하고있습니다.

데이타 저장하고 빼내고 하는 아주 단순한 수준으로만 사용하고 있는데,  이마저도 어버버 할때가 많네요;;

C로 개발하면 GDB로 디버깅 할때 큰 불편 없이 진행할수 있는데 C++로 하니까  불편한게 있습니다.

바로 STL자료구조에 저장한 데이타를 보고 싶을때......바로


예제 코드는 다음과 같습니다.

아래는 GDB로 vector 출력한 화면입니다.


값을 보고 싶은데 주소값만 써있고......검색을 해보니 역시 만든게 있네요

http://lumiera.org/documentation/technical/howto/DebugGdbPretty.html

http://sourceware.org/gdb/wiki/STLSupport


사용법은 간단합니다.

원하는 폴더로 이동해서 checkout 받은 후,

svn checkout svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python stlPrettyPrinter

~/.gdbinit을 생성합니다.


#
# .gdbinit : GDB Config file
#
# 3/2010 - Ichthyo: add python pretty printers for STL

python
import sys
sys.path.insert(0, 'stlPrettyPrinter 가 설치된 경로')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end


짜잔~!!



Posted by 오산돌구
http://apache.tt.co.kr/lucene/solr/3.3.0/   에서 solr를 다운받습니다.  ( 8/28 solr 3.3.0 version )




1. port를 변경하여 두개의 solr를 실행하는 방법  ( http://wiki.apache.org/solr/DistributedSearch )

 . example 폴더를 복사한다.


. example7574\etc\jetty.xml에서 port를 변경한다.

. 콘솔창을 두개 연다음 하나는 example\에 있는 start.jar 실행 다른 하나는 example7574에 있는 start.jar 실행

D:\temp\apache-solr-3.3.0\example7574> java -Dsolr.solr.home=d:\temp\apache-solr-3.3.0\example7574\solr -Dsolr.abortOnConfigurationError=true -jar start.jar 
D:\temp\apache-solr-3.3.0\example> java -Dsolr.solr.home=d:\temp\apache-solr-3.3.0\example\solr -Dsolr.abortOnConfigurationError=true -jar start.jar  


2. solr.xml 설정하기
. config 폴더에서 solrconfig, schema 파일을 solr.xml에서 설정한 만큼 만든다.

. 동일한 port에서 두개 이상의 core를 사용하기 때문에 접근하는 url이 변경된다.

기존 : [host]:[port]/solr/~~~~(update, dataimport, select, 사용)
변경 : [host]:[port]/solr/[coreName]/~~~~(update, dataimport, select, 사용)

 오......그럼 색인어별 (ㄱ-ㄹ, ㅇ-ㅎ) 나눠서 코어별로 던진다음에 검색어 올때 어떤건지 본다음에 Core별 나눠주면 나름 분산 검색? ㅋㅋㅋㅋㅋㅋ

3. solr에서 multicore라는 폴더 활용하기

D:\temp\apache-solr-3.3.0\example> java -Dsolr.solr.home=d:\temp\apache-solr-3.3.0\example\multicore -Dsolr.abortOnConfigurationError=true -jar start.jar 

잘된다~~ ; )


================ 2011.08.29 추가  ================
multicore 폴더에서 다수의 core를 하는데 dataimport를  하면 아래와 같은 에러가 발생한다.

 
sample이라면 core0, core1 폴더가 있을텐데 각 폴더의 solrconfig.xml 에서 <config> 부분에 lib를 추가한다.

<lib dir="../../../dist/" regex="apache-solr-dataimporthandler-\d.*\.jar" />

 
Posted by 오산돌구
참조 :  IEEE 754 floating point Wiki  ,   IEEE 754 blog  ,    정수를 넣으면 어떻게 비트변환이 되는지 보여줌

어떻게 변환되는지 단계별로 잘 설명한사이트

위의 자료를 통하여 IEEE 754가 어떤 규칙을 통해 부동 소수점을 표현하는지 알게 되었다.
소수부분에서 10진수를 2진수로 변환하는 걸 나는 아래와 같이 생각하고 있었다.
float input;
printf("input converting float Number :");
scanf("%f", &input);

char binary[15+1];
int binary_idx;
float fraction = 0.5f;
binary_idx = 0

while (input != 0.0f && binary_idx < 15) {
	if (input >= fraction) {
		binary[binary_idx] = '1';
		input -= fraction;
	}
	else 
		binary[binary_idx] = '0';
	fraction /= 2;
}
binary[binary_idx] = '\0';
printf("bit : %s\n", binary);
0.5, 0.25, 0.125를 원래정수에 빼보면서 0이 나올때까지 loop를 돌리는것이다.


그런데 이것 저것 예제를 보다가 다른 방법으로 구하는게 있어서 그것대로 구현을 해봤다.

다른점은 나누기/곱하기 연산.....그리고 fraction 유/무
괜시리 곱하기 연산이 나누기 연산보다는 빠를것 같다. 캬.....수학....;;


다시 IEEE754로 와서
Not-a-Number 는 아래와 같다. 숫자가 아니라는거.
±0 ÷ ±0 NaN
Infinity - Infinity NaN
±Infinity ÷ ±Infinity NaN
±Infinity × 0 NaN

NAN은 아래와 같이 표현 한다고 한다.
 
0 11..11 00..01
:
01..11
SNaN
0 11..11 10..00
:
11..11
QNaN
1 11..11 00..01
:
01..11
SNaN
1 11..11 10..00
:
11.11
QNaN

이걸 학습한 본래의 목적은 아래와 같은 결과가 나와서 왜?? 그런지 또 어떻게 하면 해결할수 있을지에 대한 의문을 풀기 위함이었다.
 
byte input = 'F';
input = SmallFloat.floatToByte315(0.75f);
System.out.println("input :" + input);
System.out.println("finput :" + SmallFloat.byte315ToFloat(input));
//결과 : input :122
//         finput :0.75


byte input = 'F';
input = SmallFloat.floatToByte315(0.75f);
System.out.println("input :" + input);
System.out.println("finput :" + SmallFloat.byte315ToFloat(input));
//결과 : input :121
           finput :0.625
왜 저런 수가 나왔는지는 간단하게 살펴보면~!!    (0.75만;; 귀차니즘....허허허)

0.75를 2진수로
0.75 * 2 = 1.5   (1)
0.5  * 2  = 1.0   (1) 
0.75(10) ->  0.11(2)       nomalize :    1.1 * (2^-1)   
Mantissa  :  1                Exponent : (-1) + 127 = 126      Sign bit = 0
so  0011 1111   0100 0000   0000 0000   0000 0000
아래 함수에서 bits에 0011 1111   0100 0000   0000 0000   0000 0000값이 저장되고 return결과가 122
 

public static byte floatToByte315(float f) {
    int bits = Float.floatToRawIntBits(f);
    int smallfloat = bits >> (24-3);
    if (smallfloat < (63-15)<<3) {
      return (bits<=0) ? (byte)0 : (byte)1;
    }
    if (smallfloat >= ((63-15)<<3) + 0x100) {
      return -1;
    }
    return (byte)(smallfloat - ((63-15)<<3));
 }

0.74는 0.5  (1) + 0.25  (0) + .....계속 가다보니 23bit 를 넘어섰고 Mantisa의 범위, 23개에서 자른것이다.
결국 뭐 float이란게 int같이 정확한 수 개념이 아니라 대충 이럴거 같다, 라는 것이기 때문에 위에처럼 원하는 결과를 얻지 못하는것이다. 


그럼 어떻게 풀어 나가면 좋을까?  0.75, 0.625, 0.5는 자르는것 없이 정확하게 표현이 된다.
결국 그 사이에 있는 값들이 문제라는건데,
생각난건, 1bit를 어느쪽에 가깝냐.....라는 bit로 사용하는건 어떨까?
1 이면 현재 Mantisa범위에서 윗단계와 가깝고, 0으면 그냥 현재 Mantisa범위와 같다....
이렇게 하면 0.74도 0.75로 나오지 않을까.......


조사한건 많았는데 막상 이렇게 블로그에 올리려고 하니, 주저리 떠들기나 하고있다.
아직 완벽하게 이해하지 않는것 같다...;;; 씁쓸하네...

Posted by 오산돌구
job은 아래와 같고
Mapper, Reducer의 구현은 다음과 같다.
그러나. . .아놔….. 아래와 같은 에러 발생.



key 의 데이터 타입이 잘못 들어왔다는데. . . 오후를 이걸로 싸매다가, 결국 아래 블로그에서 해답을 찾았다.
hadoop-wrong-key-class-exception

아무 생각 없이 combine을 Reduce함수로 세팅하는데, Reduce함수의 Input과 Output이 다르면 문제가 발생
그 이유는 combine의 Output이 reduce의 Input이 되기 때문이라고 한다. 그래서 해결 방법은
Posted by 오산돌구
C에서 로그를 찍을때 보다더 많은 정보를 남기기 위한 Macro.
소스예제는 ANSI 표준이고 아래 URL을 가면 MS에서 정의한 Macro들이 있다.
오호~ 이걸 이용해서 log4j같이 로그 남기는 C library를 만들면 재밌을것 같다 : )


Microsoft Predefined Macros
Posted by 오산돌구
Windows 7 KN을 설치했는데, 알고보니 Windows Media가 제외된 제품인것이였다.....

용량작다고 마냥 좋다고 이거썼는데......흠.

근데 웃긴건 windows media codec설치가 안된다는것....그래서 mpeg같은 파일은 재생이 안된다.

검색하면서 결국 찾았다.

~!! 브라보

 
Posted by 오산돌구
Ubuntu 9.10에 git Server를 만들어보겠습니다.
gitHub를 이용해서 push, pull할수 있겠지만 무료로 사용할경우 private repository를 이용할수 없습니다.

그래서 자체적으로 서버를 만들어서 git의 private repository를 갖고 싶었습니다.  (단순하죠.....허허)
그래서 찾은게 gitosis입니다.    나중을 위해 적어놓습니다~!!

sudo apt-get install git-core

cd ~/src
git clone git://eagain.net/gitosis.git

cd gitosis
sudo apt-get install python-setuptools
sudo python setup.py install

sudo adduser --system --disabled-password --shell /bin/sh --gecos 'git version control' --group --home /home/git git

여기까지가 기본설정이고,  ssh로 git접속을 설정하는 부분입니다.


ssh-keygen -t rsa
~/.ssh/ 폴더에 id_rsa, id_rsa.pub가 생성됩니다.
sudo -H -u git gitosis-init < ~/.ssh/id_rsa.pub
~git/repositories/gitosis-admin.git 폴더가 생깁니다.
push, pull이 가능해졌습니다. test를 해봅시다.



기본 port(22)가 아니라서 위와 같이 했는데, 아래 같은방법도 있습니다.
~/.ssh/config 에서 아래와 같이 설정해줍니다.




새프로젝트 만들기
(keydir 에는 원격에서 생성한 ssh public key를 넣는 폴더입니다.


group은 아무렇게나 해도됩니다.
writable에는 프로젝트명, members에는 사용자 이름을 적으면 됩니다. 아래처럼요~~



git commit -a -m " make the dol9server Project"
git push git@GitServer:gitosis-admin.git

자~ 잘 만들었는지 확인해볼까요?

잘되네요 (두번째 사진은 제가 멍때리면 타자를 치다 그만. . .ㅋㅋㅋㅋ)

다른 컴퓨터에서 지금 만든 서버로 push하려면, 다른 ssh 키 만들어서 public key를 앞에서 말한 keydir로 복사하고,
gitosis.conf에 사용자명을 등록하면됩니다. (가장 중요한것은, conf수정하고 push하는 과정입니다~!!!!!)
사용자등록하는 방법
좋구나~~~~~~

참조 : http://mechanicalrobotfish.com/posts/119-installing-git-server-using-gitosis
Posted by 오산돌구