<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Bookworm&#039;s Archive</title>
	<atom:link href="http://bookworm.pe.kr/wordpress/feed/" rel="self" type="application/rss+xml" />
	<link>http://bookworm.pe.kr/wordpress</link>
	<description></description>
	<lastBuildDate>Sun, 07 Apr 2013 13:29:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>PHP는 정말 배울 가치가 없을까?</title>
		<link>http://bookworm.pe.kr/wordpress/2013/04/07/2719/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=php%25eb%258a%2594-%25ec%25a0%2595%25eb%25a7%2590-%25eb%25b0%25b0%25ec%259a%25b8-%25ea%25b0%2580%25ec%25b9%2598%25ea%25b0%2580-%25ec%2597%2586%25ec%259d%2584%25ea%25b9%258c</link>
		<comments>http://bookworm.pe.kr/wordpress/2013/04/07/2719/#comments</comments>
		<pubDate>Sun, 07 Apr 2013 13:26:49 +0000</pubDate>
		<dc:creator>bookworm</dc:creator>
				<category><![CDATA[생각]]></category>
		<category><![CDATA[컴퓨터]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[실용]]></category>
		<category><![CDATA[언어]]></category>
		<category><![CDATA[프로그래밍]]></category>

		<guid isPermaLink="false">http://bookworm.pe.kr/wordpress/?p=2719</guid>
		<description><![CDATA[주류 언어 중 PHP만큼 비판받는 언어도 없다. PHP에 대한 비판이 지나치다 못 해 인신공격까지 서슴치 않는 경우도 있다. 오늘도 가루가 되도록 까이는 PHP를 위해 해명을 곁드린 PHP의 효용 가치에 대한 내 생각을 이야기 해보려고 한다. PHP는 다른 언어들처럼 뚜렷한 큰 목적이나 이론(사상)을 기반으로 만들어진 언어가 아니다. 초기 PHP의 약자는 Personal Home Page였다. 즉, 개인 홈페이지 [...]]]></description>
				<content:encoded><![CDATA[<p>주류 언어 중 PHP만큼 비판받는 언어도 없다. PHP에 대한 비판이 지나치다 못 해 인신공격까지 서슴치 않는 경우도 있다. 오늘도 가루가 되도록 까이는 PHP를 위해 해명을 곁드린 PHP의 효용 가치에 대한 내 생각을 이야기 해보려고 한다.</p>
<p>PHP는 다른 언어들처럼 뚜렷한 큰 목적이나 이론(사상)을 기반으로 만들어진 언어가 아니다. 초기 PHP의 약자는 Personal Home Page였다. 즉, 개인 홈페이지 만들려고 나온 언어다. 그런 언어가 이제는 웹사이트 서버사이드 프로그래밍 언어 중 점유율이 매년 늘어나 <a href="http://w3techs.com/technologies/history_overview/programming_language/ms/y">2013년에는 78.7%</a>에 달하고 있다. 기술 수준과 완성도가 진리라 생각하는 개발자나 해커로서는 땅을 치고 통탄 할 일이 아닐 수 없을 것이다. 그들에게 PHP는 쓰레기 같은 언어고, 당연히 쓰레기로서 취급을 받아야 마땅한 일일테니까 말이다.</p>
<p>"오마이갓! 무슨 일이 일어난거죠?"</p>
<p>그분들은 이리 생각하시고 계시는 듯 하다.</p>
<p>1. PHP는 프로그래밍 언어로서 치명적인 기초 설계 결함이 있고, 그로 인한 한계가 너무나도 크다.<br />
2. 보안 문제나 단점은 적기조차 버거울 정도로 많다.<br />
3. 그런 PHP가 시장에서 널리 사용되는 것은 잘 못 된 일이다.<br />
4. 새로 프로그래밍을 배울 때 PHP를 배우는 것은 잘 못 된 개발의 길로 들어서는 일이다.<br />
5. PHP로 만들어진 기존 시스템도 훌륭한 다른 언어 - 아마도 그 분들이 쓰고 계신 각자의 언어로 - 다시 개발해야한다.<br />
6. PHP를 프로그래밍 언어 시장에서 완전히 쫓아내 아무도 사용하지 않는 언어로 만들어야 한다.</p>
<p>PHP가 가진 문제점 자체를 부정하는 사람은 거의 없다. 대부분의 PHP 개발자도 사실 관계로서의 단점에 대한 지적은 수긍을 하는 편이다. 나 또한 그러하다. 그런데 우리는 많은 문제점과 낮은 기술 수준을 가진 제품이 오히려 시장에서 더 인정을 받고, 결국 더 오래 살아남는 경우를 종종 보아왔다. PHP는 정말로 하루라도 빨리 시장에서 사라져야만 하는 것일까? 아니면 단점과 낮은 기술 수준에도 불구하고 시장에서는 더 오래 살아남았던 것들 중 하나가 될 것일까?</p>
<p>개인적으로 몇 년 전까지만 해도 프로그래밍 언어를 추천 해 달라고 하면 일반인에게는 파이썬(Python)을 추천 해 주었다. 개발자를 지망하는 사람에게는 C 언어를 - 그리고 펄(Perl)도. 1999년 PHP를 처음 배울 때부터 여러 단점 때문에 짜증을 낼 때가 많았다. 아마도 이런 경험이 나로 하여금 PHP를 추천하지 않게 하였을듯 하다. 예를 들어 PHP 4의 클래스는 이걸 쓰라고 만든 것인지 의심스러울 정도였다.</p>
<p>그러나 PHP가 주류 언어 중 하나로 성장하면서 지적됐던 단점들이 하나씩 보완되고 있기 때문에, 여전히 남은 단점들에도 불구하고 시장에서 빨리 퇴출시켜야 된다는 주장에 무작정 동의하기 보다 몇몇 상황에서는 PHP를 배우길 추천하고 싶다.</p>
<p>1. 웹사이트가 일이나 취미에 보완적으로 도움이 되는 경우</p>
<p>프로그래밍 그 자체가 주목적이 아니라 마케팅과 같은 비기술적인 일이나 커뮤니티 같은 취미에 웹사이트가 도움이 될 것 같아 직접 만들거나 운영하려는 사람들에게는 PHP가 학습 비용 및 운영 비용에서 잇점이 있는 언어다.</p>
<p>PHP는 현재 PHP를 사용하지 않은 개발자들도 대부분 어느 정도는 알고 있을 정도로 - 심지어 PHP를 비판하시는 분들 조차도 - 주변의 도움을 얻기 쉬운 언어다. PHP를 모르더라도 숙련된 C/C++ 개발자라면 즉석에서 PHP 메뉴얼을 보고 답을 줄 수 있을 정도다.</p>
<p>또한 PHP는 웹호스팅 비용이 매우 저렴하다. PHP를 제공하지 않는 웹호스팅 업체는 거의 없을 정도고, 제공하는 서비스의 완성도도 높은 편이라 문제를 겪을 일도 적고, 발생한 문제에 대한 기술 지원도 잘 이루어진다. 웹호스팅 업체 직원도 PHP는 대부분 알고 있다. 적은 비용으로 하고자 하는 일이나 취미에 도움이 되는 웹사이트를 운영 할 수 있다.</p>
<p>2. PHP로 만들어진 도구를 이용해야 하는 경우</p>
<p>PHP가 높은 시장 점유율을 가진 것의 절반은 이런 도구들 때문이라고 생각한다. CMS 시장의 1, 2, 3위를 차지하는 워드프레스(WordPress)와 줌라(Joomla), 드루팔(Drupal) 모두 PHP로 개발되어 있다. 조그마한 소호(SOHO) 사업을 하거나, 쇼핑몰이나 커뮤니티, 소규모 미디어 사업 등을 위해 이런 도구들을 이용하는 경우 PHP를 배우는 것이 유리한 점이 많다.</p>
<p>각종 플러그인이나 기능들을 직접 원하는대로 수정하여 운영 할 수 있는 경우 다른 사이트에 비해 경쟁력을 갖추는데 도움이 된다.</p>
<p>3. 개인 또는 제한된 사용자 규모를 가진 웹페이지를 만들어야 할 경우</p>
<p>다른 언어(특히 C/C++) 개발자가 개인 또는 내부 직원들에게 배포 할 용도로 1 ~ 2 페이지 정도 규모의 웹페이지를 만들어야 할 경우 두 언어 모두 능숙하다는 가정하에 HTML과 로직을 마구 섞어서 사용 할 수 있는 PHP의 접근 비용이 더 적을 수 있다. 물론 이 때에도 기존에 다른 언어로 구축 된 라이브러리들을 이용해야 한다면 PHP는 선택 대상이 아니겠지만, 그렇지 않은 경우는 고려 해 볼만한 하다.</p>
<p>4. 이미 PHP로 구축된 시스템이 있는 경우</p>
<p>개인적으로 PHP를 사용하고 계속 공부하고 있는 가장 큰 이유다. 백만 라인을 가뿐히 넘는 PHP(+HTML) 소스 코드를 PHP가 단지 단점이 많고, 완성도가 떨어진다고 다른 언어로 재개발 해야 한다고 주장하려면 책상 위에 사직서를 올려놓고 이야기를 시작해야 할지도 모른다. 사업에 캐시카우인 시스템이 PHP라면 당연히 PHP의 단점을 잘 이해하고 해결(회피) 할 수 있는 방법까지 터득한 절정의 PHP 실력을 갖추도록 노력하는 것이 맞다. PHP를 버리고 다른 언어로 다시 재개발하기 보다 단점을 해결하는 수준을 넘어 안드로메다까지 끌어올린 회사를 우리는 알고 있다. 페이스북.</p>
<p>이제 이야기를 정리하고 마무리 하자.</p>
<p>PHP는 외부 라이브러리의 매개변수 순서를 자신에게 맞추지 않고, 원형 그대로를 유지 할 정도로 실용을 우선시 하는 언어다. 덕분에 체계적이거나 기술적 완성미와는 거리가 멀다. 그러므로 PHP를 선택하거나 배우려 할 때도 실용에 초점을 두는 것이 맞다. 프로그래머로서 해커로서 엔지니어로서 기술적 욕구에 대한 충족은 미안하지만 다른 언어로 채우는 것이 낫다. PHP는 분명 나아지고 있고 언젠가 그 단점들을 모두 해결해낼지 모르지만, 당분간 그게 이뤄질 가능성은 <del datetime="2013-04-07T11:44:29+00:00">없어</del>낮아 보인다. 몇몇 언어들처럼 PHP6가 하위 호환성을 버리고 단점들을 한 방에 정리 할 것 같진 않다는 이야기다.</p>
<p>한 마디로 정리하자면 이렇다.</p>
<p>PHP는 실용성이 중요한 상황이라면 배워 둘만한 실용적 가치 정도는 있는 언어다.</p>
]]></content:encoded>
			<wfw:commentRss>http://bookworm.pe.kr/wordpress/2013/04/07/2719/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>자유로운 기업 문화를 어떻게 만들 수 있을까?</title>
		<link>http://bookworm.pe.kr/wordpress/2013/01/08/2691/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25ec%259e%2590%25ec%259c%25a0%25eb%25a1%259c%25ec%259a%25b4-%25ea%25b8%25b0%25ec%2597%2585-%25eb%25ac%25b8%25ed%2599%2594%25eb%25a5%25bc-%25ec%2596%25b4%25eb%2596%25bb%25ea%25b2%258c-%25eb%25a7%258c%25eb%2593%25a4-%25ec%2588%2598-%25ec%259e%2588%25ec%259d%2584%25ea%25b9%258c</link>
		<comments>http://bookworm.pe.kr/wordpress/2013/01/08/2691/#comments</comments>
		<pubDate>Tue, 08 Jan 2013 12:31:46 +0000</pubDate>
		<dc:creator>bookworm</dc:creator>
				<category><![CDATA[생각]]></category>
		<category><![CDATA[기업문화]]></category>
		<category><![CDATA[리더의조건]]></category>
		<category><![CDATA[스타트업]]></category>
		<category><![CDATA[윤석찬]]></category>
		<category><![CDATA[제니퍼소프트]]></category>
		<category><![CDATA[표철민]]></category>

		<guid isPermaLink="false">http://bookworm.pe.kr/wordpress/?p=2691</guid>
		<description><![CDATA[2013년이 시작된지 몇 일이 지나 SBS에서 '리더의 조건'이란 프로그램을 방송했다. 여기서 '제니퍼소프트'라는 회사가 소개됐는데, 스타트업에서 일하던 시절 화제가 됐던 회사여서 크게 더 관심을 두진 않았다. 하지만 평소 좋아하던 표철민님과 윤석찬님이 서로 다른 의견을 내시면서, 다시 한 번 기업 문화에 대해 생각을 하게 되었다. 4월이 시작한 지금 뒤늦게 이 문제를 정리하는 이유는 논란이던 시점에 정리하면 내 [...]]]></description>
				<content:encoded><![CDATA[<p>2013년이 시작된지 몇 일이 지나 SBS에서 '<a href="http://news.sbs.co.kr/section_news/news_read.jsp?news_id=N1001569500" target="_blank">리더의 조건</a>'이란 프로그램을 방송했다. 여기서 '<a href="http://www.jennifersoft.com/" target="_blank">제니퍼소프트</a>'라는 회사가 소개됐는데, 스타트업에서 일하던 시절 화제가 됐던 회사여서 크게 더 관심을 두진 않았다. 하지만 평소 좋아하던 표철민님과 윤석찬님이 서로 다른 의견을 내시면서, 다시 한 번 기업 문화에 대해 생각을 하게 되었다.</p>
<p>4월이 시작한 지금 뒤늦게 이 문제를 정리하는 이유는 논란이던 시점에 정리하면 내 생각 보다는 시류에 편승 할 위험이 있기 때문이고, 논란의 흐름과 상관없이 창업을 하거나 사업을 관리 할 때 이 부분은 언제나 가장 고민스러운 부분이기 때문이다. 훗날 스스로 업을 일으킬 때 잊어버리지 않기 위해서라도 이것을 정리해 글로 남기고 싶었다.</p>
<p>혹시 두 분 글을 안 읽어 본 분은 여기서 잠시 멈추고, 글을 먼저 읽어보는 것이 좋을 듯 싶다.</p>
<ul>
<li>표철민님 블로그 - <a href="http://mrpyo.com/2013/01/08/%EC%9E%90%EC%9C%A0%EB%A5%BC-%EB%88%84%EB%A6%B4-%EC%9E%90%EA%B2%A9%EC%9D%B4-%EC%9E%88%EB%8A%94-%EC%82%AC%EB%9E%8C/" target="_blank">자유를 누릴 자격이 있는 사람</a></li>
<li>윤석찬님 페이스북 - <a href="https://www.facebook.com/channyblog/posts/397707593656441" target="_blank">https://www.facebook.com/channyblog/posts/397707593656441</a></li>
</ul>
<p>기본적인 관점에서 두 분의 의견 모두 맞다고 생각한다. 개인적으로 윤석찬님의 의견에 공감을 하지만, 표철민님 생각도 맞다고 본다. 그런 이런 두 관점에 대한 차이는 어디서 나오는걸까?</p>
<p>그건 바로 올바른 기업 문화를 사업 초기부터 잘 설정하고 유지했느냐 못 했느냐의 차이다. 보통 자유를 허락하는 기업의 경우 반드시라고 할 정도로 꼭 체리피커가 등장한다. 바로 이 체리피커를 어떻게 관리를 하고 자유로운 기업 문화를 유지하느냐가 이 논란의 핵심이다.</p>
<p>문제는 우리나라는 체리피커를 관리하는데 두 가지 어려움이 존재한다. 하나는 한국 사회의 인정 위주 문화로 인한 쓴소리 하기 어려운 분위기이고, 또 다른 하나는 사업 규모를 빠르게 키우려고 하는 조급함 내지는 내외부의 압력이다.</p>
<p>체리피커가 처음 등장했을 때 초기부터 합리적으로 설명을 하고, 태도에 변화가 없으면 즉시 내보내야 하는 것이 중요한데, 설명과 이해와 동의 보다는 단순한 질책과 화를 내는 것이 전부인 경우가 많고, 막상 그 이후에 바로 내보내지도 못 하면서 속만 끓이는 경우가 많다. 이러는 사이에 기업 문화는 점점 망가져 가며, 각종 규칙과 제재란 것이 등장하면서 자유로운 기업 문화를 사라지게 된다.</p>
<p>이런 체리피커는 만들어내고 정리하지 못하게 되는 원인 중 하나는 조급한 사업 규모의 확장이다. 사업 규모를 성급하게 키우면 세가지 문제점이 나타난다. 첫째 사람에 대한 충분한 검증할 시간이 부족해 체리피커를 채용 할 가능성이 높아진다. 둘째 이질적인 기업 문화에서 일하던 사람들의 비율이 증가해서 기업 문화 원형이 가진 압력과 설득력, 그리고 원형 그 자체가 손상받기 쉬워진다. 셋째 장기적 발전을 위한 기업 문화의 유지 보다 매출 같은 결과로서의 숫자에 회사 역량이 쏠리게 된다. 단기적으로 이게 좋아보일지 몰라도 앞으로 성장 할 수 있는 잠재력을 다 갉아먹는 일이다. 거기에 더해 전체적인 임금 규모가 커지면서 개개인에 대한 복지 확대가 어려워져 인재에 대한 유인력이 떨어지고, 단기적인 성과에 기존 직원들이 내몰리게 되는 문제도 있다.</p>
<p>자유로운 기업 문화로 인해 사업(회사)가 망가지는 것을 어떻게 하면 막을 수 있을까?</p>
<p>창업자들끼리는 기업 문화에 대한 생각과 모양새에 대해 확고한 공감대를 가지고 있는 것이 좋다. 혹시 기존에 어떤 모델이나 사례, 기업이 있다면 명확히 우리 회사는 어떤 것을 기초로 한다는 것을 서로 공유하는 것이 좋다.</p>
<p>채용을 쉽고 급하게 하지 말아야 한다. 오랜 시간 뜸을 들여서 신중히 채용을 해야 한다. 또한 직원을 채용 할 비용을 확보하고 채용해야 한다. 당장 매달 나가는 직원의 급여만큼 벌지 못 하면서 직원을 늘리는 것은 회사와 직원 모두에게 안 좋다. 직원을 채용 할만큼 안정적인 수익이 늘어나거든 그때 채용을 한다. 단, 채용을 조건으로 의미있는 수준의 지분을 받는 사람은 직원이 아니라 창업자로 보아야 한다. 대신 급여 수준을 회사가 감당 할 수 있는 수준으로 낮추자.</p>
<p>새로운 직원이 들어오면 기업 문화에 대해서 충분히 이해를 시키도록 해야 한다. 거기에 더해 기업 문화에 어긋나는 행동을 하면 누구라도 해고될 수 있다는 점도 주지시켜야 한다. 다만 기업 문화를 세세한 항목별로 규칙으로서 만드는 것은 좋지 않다. 가장 기본이 되는 큰 흐름에서 서너가지 정도로 압축을 하고, 나머지는 상식에 맞기자.</p>
<p>기업 문화에 어긋나는 행동을 한 사람에게는 바로 지적을 하고 그것이 기업 문화에 어떤 악영향을 주는지 설명한다. 물론 다시 어길 경우 해고 될 것이라는 경고도 잊지 말자. 아울러 이런 경우가 발생하였다고 그것을 막기 위한 규칙을 만들어서 회사에 공표하는 것은 금물이다. 또 어긴다면 매정하게 보일지라도 바로 내보내야 한다.</p>
<p>기업 문화를 잘 만들고 유지하는 것은 성장 엔진을 만들고 매출을 늘리는 것만큼이나 어렵다. 어려운만큼 중요성도 작지 않다. 다양한 스타트업 및 중소기업에서 근무 또는 창업을 하면서 기업 문화에 대해 많은 고민을 하였다. 10년이 넘는 시간 동안 실험과 실패, 그리고 교훈을 배우면서 이제는 조금 전보다는 잘 할 수 있다는 자신감 같은 것을 얻었다. 전문가는 아니지만 부족하나마 실전을 통해 얻은 교훈과 생각을 공유하고 싶었다.</p>
]]></content:encoded>
			<wfw:commentRss>http://bookworm.pe.kr/wordpress/2013/01/08/2691/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>월의 몇 주차인지 계산하기</title>
		<link>http://bookworm.pe.kr/wordpress/2013/01/04/2673/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25ec%259b%2594%25ec%259d%2598-%25eb%25aa%2587-%25ec%25a3%25bc%25ec%25b0%25a8%25ec%259d%25b8%25ec%25a7%2580-%25ea%25b3%2584%25ec%2582%25b0%25ed%2595%2598%25ea%25b8%25b0</link>
		<comments>http://bookworm.pe.kr/wordpress/2013/01/04/2673/#comments</comments>
		<pubDate>Thu, 03 Jan 2013 23:00:16 +0000</pubDate>
		<dc:creator>bookworm</dc:creator>
				<category><![CDATA[컴퓨터]]></category>
		<category><![CDATA[week]]></category>
		<category><![CDATA[weekofmonth]]></category>
		<category><![CDATA[주]]></category>

		<guid isPermaLink="false">http://bookworm.pe.kr/wordpress/?p=2673</guid>
		<description><![CDATA[평소 크게 신경을 쓰던 문제는 아닌데 이번에 관련 작업을 하면서 이게 간단한 문제는 아니라는 것을 알게 됐다. 이 문제가 어려운 이유는 그 해의 몇 주차인지에 대해서는 ISO 표준이 있는데, 월의 몇 주차인지에 대해서는 표준이 없기 때문이다. 아마 표준이 있었으면 이미 날짜 관련 함수 중에 있었을 것이다. 본격적으로 이야기를 꺼내기 전에 주(week)에 관한 ISO 표준 중 [...]]]></description>
				<content:encoded><![CDATA[<p>평소 크게 신경을 쓰던 문제는 아닌데 이번에 관련 작업을 하면서 이게 간단한 문제는 아니라는 것을 알게 됐다. 이 문제가 어려운 이유는 그 해의 몇 주차인지에 대해서는 ISO 표준이 있는데, 월의 몇 주차인지에 대해서는 표준이 없기 때문이다. 아마 표준이 있었으면 이미 날짜 관련 함수 중에 있었을 것이다.</p>
<p>본격적으로 이야기를 꺼내기 전에 주(week)에 관한 ISO 표준 중 관련 사항을 알아 보자.</p>
<p>1. 한 주의 시작은 월요일이다.</p>
<p>달력에 일요일부터 표시하고 있기 때문에 한 주 시작이 일요일 같지만 월요일이 표준이라고 한다. 즉, 한 주는 월요일로 시작 해 일요일로 끝난다.</p>
<p>2. 년도의 주차는 해당 주의 목요일 년도에 따라간다.</p>
<p>예를 들어 1월 1일이 목요일이면, 12월 31일(수), 12월 30일(화), 12월 29일(월)은 전년도에 포함되지 않고 이번 년도의 1주차에 포함된다. 반대로 1월 1일이 금요일이면 1월 1일(금), 1월 2일(토), 1월 3일(일)은 전년도 마지막 주차에 포함된다.</p>
<p>그럼 월의 주차를 계산하는 방법은 어떨까?</p>
<p>아주 다양한 계산법들이 있지만 그 중 널리 쓰이는 계산법을 몇가지 살펴보자.</p>
<p>1. 년의 주차 계산과 동일한 방법</p>
<p>즉, 목요일이 어느 달에 속하느냐를 따져 전달에 마지막 주차에 포함시키거나 이번 달 첫 주차에 포함시킨다.</p>
<p>2. 월요일을 기준으로 하는 방법</p>
<p>월요일에 어느 달에 포함되느냐에 따른다. 월요일이 31일이면 그 뒤에 나오는 1, 2, 3, 4, 5, 6일은 마지막 주차에 포함시킨다.</p>
<p>3. 각 달에 포함하는 방법</p>
<p>30일이 월요일인 경우 30일(월), 31일(화)는 전 달의 마지막 주차로 계산하고, 1일(수), 2일(목), 3일(금), 4일(토), 5일(일)은 이번 달 첫 주차로 계산하는 방법이다.</p>
<p>그럼 어떤 방법으로 월의 주차를 계산해야 할까? 여기서는 첫번째 년의 주차 계산과 동일한 방법으로 계산하기로 하자. 이렇게 한 이유는 다른 계산법으로 하는 경우 년의 주차로는 1 주차면서 12월의 마지막 주차로 계산되는 불일치가 나타날 수 있기 때문이다. 이런 불일치는 다른 파생적인 문제와 예외 처리가 필요 할 수 있기 때문에, 년의 주차 계산과 동일한 방법으로 월의 주차를 계산하려고 한다.</p>
<pre class="brush: php; gutter: true; first-line: 1; highlight: []; html-script: false">&lt;?php
class DateTimeExtra extends DateTime {
    public function weekofmonth() {
        $thursday = $this-&gt;thursday();

        if ( $thursday-&gt;format(&#039;n&#039;) != $this-&gt;format(&#039;n&#039;) ) {
            $date = $thursday;
        }
        else {
            $date = $this;
        }

        $firstday = clone $date;
        $firstday-&gt;sub(new DateInterval(&#039;P&#039;.($date-&gt;format(&#039;j&#039;) - 1).&#039;D&#039;));
        $thursday_of_firstday = $firstday-&gt;thursday();
        if ( $thursday_of_firstday-&gt;format(&#039;n&#039;) != $firstday-&gt;format(&#039;n&#039;) ) {
            // 이번 달 첫번째 날을 포함한 주의 목요일의 월과 첫번째 날의 월이
            // 다른 경우는 첫번째 날이 이전 달의 마지막 주에 포함되어 있다는
            // 것이므로 월의 주차 기준이 되는 주를 한 주 뒤로 미룬다.
            $firstday-&gt;add(new DateInterval(&#039;P1W&#039;));
        }

        $month = $date-&gt;format(&#039;n&#039;);
        $weekofmonth = $date-&gt;format(&#039;W&#039;) - $firstday-&gt;format(&#039;W&#039;) + 1;

        return array(intval($month), intval($weekofmonth));
    }

    private function thursday() {
        $thursday = clone $this;
        $dayofweek = $this-&gt;format(&#039;N&#039;);

        if ( $dayofweek &lt; 4 ) {
            $thursday-&gt;add(new DateInterval(&#039;P&#039;.(4 - $dayofweek).&#039;D&#039;));
        }

        if ( $dayofweek &gt; 4 ) {
            $thursday-&gt;sub(new DateInterval(&#039;P&#039;.($dayofweek - 4).&#039;D&#039;));
        }

        return $thursday;
    }
}
?&gt;</pre>
<p>월의 주차의 계산은 이렇게 했다. 우선 특정일이 속한 주의 목요일과 특정일이 속한 월의 1일이 속한 주의 목요일을 구한다. 그리고 이 둘의 월을 비교한다. 서로 다르면 이번 달의 1일이 속한 주가 전 달의 마지막 주차에 포함된 것이므로 이번 달의 시작인 년의 주차를 한 주 미룬다. 같으면 이번 달 1일이 포함된 주차가 이번 달의 첫 주차이므로 그대로 사용한다. 이 둘의 년의 주차를 빼주면 특정일의 해당 월의 주차를 구할 수 있다.</p>
]]></content:encoded>
			<wfw:commentRss>http://bookworm.pe.kr/wordpress/2013/01/04/2673/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>동시성 문제를 해결하기 위한 MySQL 잠금 두가지</title>
		<link>http://bookworm.pe.kr/wordpress/2013/01/01/2642/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25eb%258f%2599%25ec%258b%259c%25ec%2584%25b1-%25eb%25ac%25b8%25ec%25a0%259c%25eb%25a5%25bc-%25ed%2595%25b4%25ea%25b2%25b0%25ed%2595%2598%25ea%25b8%25b0-%25ec%259c%2584%25ed%2595%259c-mysql-%25ec%259e%25a0%25ea%25b8%2588-%25eb%2591%2590%25ea%25b0%2580%25ec%25a7%2580</link>
		<comments>http://bookworm.pe.kr/wordpress/2013/01/01/2642/#comments</comments>
		<pubDate>Tue, 01 Jan 2013 08:15:46 +0000</pubDate>
		<dc:creator>bookworm</dc:creator>
				<category><![CDATA[컴퓨터]]></category>
		<category><![CDATA[lock]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[잠금]]></category>

		<guid isPermaLink="false">http://bookworm.pe.kr/wordpress/?p=2642</guid>
		<description><![CDATA[InnoDB를 사용하면서 동시성(Concurrency)을 고려하지 않고 개발을 하면 큰 문제가 생길 수 있다. 아래에 회원 포인트를 수정하는 간단한 로직을 살펴보자. &#60;?php $dbo = new mysqli(&#039;localhost&#039;, &#039;bookworm&#039;, &#039;&#039;, &#039;test&#039;); $result = $dbo-&#62;query(&#039;SELECT id, name, point FROM user WHERE name = &#34;bookworm&#34;&#039;); $row = $result-&#62;fetch_assoc(); $new_point = $row[&#039;point&#039;] + 100; // $new_point 값을 대입하지 않고 point = point [...]]]></description>
				<content:encoded><![CDATA[<p>InnoDB를 사용하면서 동시성(Concurrency)을 고려하지 않고 개발을 하면 큰 문제가 생길 수 있다. 아래에 회원 포인트를 수정하는 간단한 로직을 살펴보자.</p>
<pre class="brush: php; gutter: true; first-line: 1; highlight: []; html-script: false">&lt;?php
$dbo = new mysqli(&#039;localhost&#039;, &#039;bookworm&#039;, &#039;&#039;, &#039;test&#039;);

$result = $dbo-&gt;query(&#039;SELECT id, name, point FROM user WHERE name = &quot;bookworm&quot;&#039;);
$row = $result-&gt;fetch_assoc();
$new_point = $row[&#039;point&#039;] + 100;
// $new_point 값을 대입하지 않고 point = point + 100으로 문제를 미리 방지 할 수 있지만
// 예시를 위해 일부러 그렇게 하지 않았다.
$dbo-&gt;query(&quot;UPDATE user SET point = {$new_point} WHERE name = &#039;bookworm&#039;&quot;);
?&gt;</pre>
<p>이 로직이 하나만 실행이 될 때는 문제가 없으나, 웹처럼 동시에 실행이 될 수 있는 환경에서는 문제가 된다.</p>
<p>우선 한 프로세스가 SELECT로 사용자 정보를 가져온다. 그리고 UPDATE를 실행하기 전에 다른 프로세스가 SELECT로 역시 같은 사용자의 정보를 가져온다. 그럼 둘 다 동일한 포인트를 가져오게 되고, 그 뒤에 100을 더한 값으로 처음 프로세스가 UPDATE 하고, 그 뒤에 다른 프로세스가 UPDATE 하게 됨으로서 처음 프로세스가 증가시킨 100 값이 사라지게 된다.</p>
<p>이를 방지하기 위해서는 InnoDB의 기본 Isolation Levels를 변경 할 수 있겠지만, 전체 쿼리 중 동시성을 고려해야 하는 경우가 많지 않다면 간단한 잠금 쿼리를 이용해서 처리 할 수 있다.</p>
<p>InnoDB의 잠금은 두가지로 나눌 수 있다. 하나는 LOCK IN SHARE MODE와 다른 하나는 FOR UPDATE다. 이 둘의 용도는 약간 다르기 때문에 자신의 용도에 따라 신중히 선택을 해야 한다.</p>
<p>LOCK IN SHARE MODE는 SELECT를 한 후에 트랜잭션이 끝날 때까지 해당 ROW 값이 변경되지 않을 것을 보장한다. 바꿔 말하면 해당 ROW를 UPDATE 하거나 DELETE 하려는 쿼리는 잠김 상태가 되어 트랜잭션이 끝날 때까지 대기하게 된다. 하지만, SELECT는 얼마든지 여러 세션이 동시에 수행하는 것이 가능하다.</p>
<p>기존 SELECT 쿼리문 맨 뒤에 LOCK IN SHARE MODE 문장을 추가하는 것만으로 사용이 가능하지만, 트랜잭션이 끝나기 전까지만 유효하므로 auto_commit을 꺼야 한다.</p>
<pre class="brush: sql; gutter: false; first-line: 1; highlight: []; html-script: false">SELECT * FROM user WHERE id = 1 LOCK IN SHARE MODE;</pre>
<p>FOR UPDATE는 SELECT로 가져 온 데이터를 변경을 하려고 할 때 사용한다.</p>
<pre class="brush: sql; gutter: false; first-line: 1; highlight: []; html-script: false">SELECT * FROM user WHERE id = 1 FOR UPDATE;</pre>
<p>FOR UPDATE를 SELECT를 가져온 이후로 해당 ROW에 대해 다른 세션의 SELECT, UPDATE, DELETE 등의 쿼리가 모두 잠김 상태가 된다. 즉, FOR UPDATE를 한 세션 외에 다른 세션들은 모두 해당 ROW에 접근을 할 수 없게 되고, 모두 대기 상태가 된다. FOR UPDATE도 LOCK IN SHARE MODE처럼 트랜잭션이 끝나는 시점에서 풀린다. 처음 예로 든 사용자 포인트 증가와 같은 경우에 알맞는 잠금이다.</p>
<p>웹 프로그래밍에서는 쓰레드 프로그래밍처럼 세밀히 동시성을 고민 할 필요는 없지만, 웹이 기본적으로 다수 사용자가 동시에 같은 데이터에 접근을 하는 환경이므로 이로 인해 주의가 필요하다. 이 외에 이런 문제를 해결하기 위해 트리거나 저장 프로시저 등을 이용 할 수 있지만, 최근 웹서비스 초기에는 MySQL을 단순 key-value 저장소처럼 사용하다 추후 서비스 성장에 맞춰 noSQL을 도입하는 경우가 종종 보이므로, RDBMS의 기능을 너무 적극적으로 활용하지 않는 것이 낫지 않을까 싶다.</p>
]]></content:encoded>
			<wfw:commentRss>http://bookworm.pe.kr/wordpress/2013/01/01/2642/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>우분투 컴피즈(Ubuntu Compiz) 엣지가 동작하지 않는 문제</title>
		<link>http://bookworm.pe.kr/wordpress/2012/12/27/2645/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25ec%259a%25b0%25eb%25b6%2584%25ed%2588%25ac-%25ec%25bb%25b4%25ed%2594%25bc%25ec%25a6%2588ubuntu-compiz-%25ec%2597%25a3%25ec%25a7%2580%25ea%25b0%2580-%25eb%258f%2599%25ec%259e%2591%25ed%2595%2598%25ec%25a7%2580-%25ec%2595%258a%25eb%258a%2594-%25eb%25ac%25b8%25ec%25a0%259c</link>
		<comments>http://bookworm.pe.kr/wordpress/2012/12/27/2645/#comments</comments>
		<pubDate>Thu, 27 Dec 2012 03:30:18 +0000</pubDate>
		<dc:creator>bookworm</dc:creator>
				<category><![CDATA[컴퓨터]]></category>
		<category><![CDATA[Compiz]]></category>
		<category><![CDATA[Edge]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[엣지]]></category>
		<category><![CDATA[우분투]]></category>
		<category><![CDATA[컴피즈]]></category>

		<guid isPermaLink="false">http://bookworm.pe.kr/wordpress/?p=2645</guid>
		<description><![CDATA[우분투 컴피즈 관리자를 통해 화면의 각 엣지(Edge)에 마우스 커서를 둘 경우 다양한 동작을 하도록 설정 할 수 있다. 하지만, 종종 이 엣지가 부팅 후에는 동작을 하지 않는 문제가 있다. 이 문제를 해결하는 완전하지는 않지만 손쉬운 방법이 있다. 다만 12.10에서는 이 방법으로 안 된다고 한다. 컴피즈 관리자를 실행한다. 옵션의 Active Plugins를 선택한다. Scale을 맨 아래에 둔다. [...]]]></description>
				<content:encoded><![CDATA[<p>우분투 컴피즈 관리자를 통해 화면의 각 엣지(Edge)에 마우스 커서를 둘 경우 다양한 동작을 하도록 설정 할 수 있다. 하지만, 종종 이 엣지가 부팅 후에는 동작을 하지 않는 문제가 있다. 이 문제를 해결하는 완전하지는 않지만 손쉬운 방법이 있다. 다만 12.10에서는 이 방법으로 안 된다고 한다.</p>
<ol>
<li>컴피즈 관리자를 실행한다.</li>
<li>옵션의 Active Plugins를 선택한다.</li>
<li>Scale을 맨 아래에 둔다.</li>
<li>Expo를 Scale 위에 UnityShell 아래에 둔다.</li>
</ol>
<p>이 작업을 직접 설정 파일을 수정해서 할 수 도 있다.</p>
<pre class="brush: bash; gutter: true; first-line: 1; highlight: []; html-script: false">$ sudo vi /org/compiz/profiles/unity/plugins/core/active-plugins</pre>
<p>이 외에도 컴피즈 관리자의 Unity plug-in &gt; Experimental 내 Launcher Capture Mouse를 끄면 된다는 이야기도 있으나 확인 해보지는 못 했다.</p>
<p>이 방법이 완전하지 않은 이유는 컴피즈가 업데이트 되는 경우 플러그인 순서가 초기화 되기 때문이다.</p>
]]></content:encoded>
			<wfw:commentRss>http://bookworm.pe.kr/wordpress/2012/12/27/2645/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP: PEAR 목록</title>
		<link>http://bookworm.pe.kr/wordpress/2012/12/24/2637/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=php-pear-%25eb%25aa%25a9%25eb%25a1%259d</link>
		<comments>http://bookworm.pe.kr/wordpress/2012/12/24/2637/#comments</comments>
		<pubDate>Mon, 24 Dec 2012 03:30:27 +0000</pubDate>
		<dc:creator>bookworm</dc:creator>
				<category><![CDATA[컴퓨터]]></category>
		<category><![CDATA[PEAR]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://bookworm.pe.kr/wordpress/?p=2637</guid>
		<description><![CDATA[Perl CPAN에 비하면 아주 빈약한 PEAR지만 이것조차도 충분히 활용되는 경우가 드문 것 같다. 개인적으로 몇몇 PEAR를 애용하고 있지만 좀 더 적극적으로 사용 해 보기 위해 전체 PEAR의 목록을 보여주는 페이지를 하나 만들었다. 개발에 사용하는 가상 서버에 올려놓았기 때문에 나중에 주소가 바뀔 가능성도 있다. 링크: PEAR List PS> 카페24 가상 서버 기간 만료 이후 이전을 하지 [...]]]></description>
				<content:encoded><![CDATA[<p>Perl CPAN에 비하면 아주 빈약한 PEAR지만 이것조차도 충분히 활용되는 경우가 드문 것 같다. 개인적으로 몇몇 PEAR를 애용하고 있지만 좀 더 적극적으로 사용 해 보기 위해 전체 PEAR의 목록을 보여주는 페이지를 하나 만들었다.</p>
<p>개발에 사용하는 가상 서버에 올려놓았기 때문에 나중에 주소가 바뀔 가능성도 있다.</p>
<p>링크: <a href="http://forge.bookworm.pe.kr/pearlist/" title="PEAR List" target="_blank">PEAR List</a></p>
<p>PS> 카페24 가상 서버 기간 만료 이후 이전을 하지 못 해 서비스 중지 중.</p>
]]></content:encoded>
			<wfw:commentRss>http://bookworm.pe.kr/wordpress/2012/12/24/2637/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP: 분석에 유용한 도구들</title>
		<link>http://bookworm.pe.kr/wordpress/2012/12/23/2652/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=php-%25eb%25b6%2584%25ec%2584%259d%25ec%2597%2590-%25ec%259c%25a0%25ec%259a%25a9%25ed%2595%259c-%25eb%258f%2584%25ea%25b5%25ac%25eb%2593%25a4</link>
		<comments>http://bookworm.pe.kr/wordpress/2012/12/23/2652/#comments</comments>
		<pubDate>Sun, 23 Dec 2012 05:29:01 +0000</pubDate>
		<dc:creator>bookworm</dc:creator>
				<category><![CDATA[컴퓨터]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[정적분석]]></category>

		<guid isPermaLink="false">http://bookworm.pe.kr/wordpress/?p=2652</guid>
		<description><![CDATA[정적 분석 php-sat php-ast PHP Depend PHP CodeSniffer PHP Parser Online PHP lint PHPLint phpCallGraph PHP Mess Detector phc 디버거 Xdebug 문서화 phpdoc doxygen 프로파일러 xhprof]]></description>
				<content:encoded><![CDATA[<h3>정적 분석</h3>
<ul>
<li><a href="http://www.program-transformation.org/PHP/PhpSat">php-sat</a></li>
<li><a href="http://trac.assembla.com/php-ast">php-ast</a></li>
<li><a href="http://manuel-pichler.de/pages/pdepend.html">PHP Depend</a></li>
<li><a href="http://pear.php.net/package/PHP_CodeSniffer">PHP CodeSniffer</a></li>
<li><a href="http://pear.php.net/package/PHP_Parser">PHP Parser</a></li>
<li><a href="http://www.icosaedro.it/phplint/phplint-on-line.html">Online PHP lint</a></li>
<li><a href="http://www.icosaedro.it/phplint/">PHPLint</a></li>
<li><a href="http://phpcallgraph.sourceforge.net/">phpCallGraph</a></li>
<li><a href="http://phpmd.org/">PHP Mess Detector</a></li>
<li><a href="http://phpcompiler.org/">phc</a></li>
</ul>
<h3>디버거</h3>
<ul>
<li><a href="http://www.xdebug.org/">Xdebug</a></li>
</ul>
<h3>문서화</h3>
<ul>
<li><a href="http://www.phpdoc.org/">phpdoc</a></li>
<li><a href="http://www.stack.nl/~dimitri/doxygen/">doxygen</a></li>
</ul>
<h3>프로파일러</h3>
<ul>
<li><a href="http://pecl.php.net/package/xhprof">xhprof</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://bookworm.pe.kr/wordpress/2012/12/23/2652/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP: 보다 빠른 echo를 위하여 – 도트(.) 보다 나은 중괄호({})</title>
		<link>http://bookworm.pe.kr/wordpress/2012/12/04/2628/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=php-%25eb%25b3%25b4%25eb%258b%25a4-%25eb%25b9%25a0%25eb%25a5%25b8-echo%25eb%25a5%25bc-%25ec%259c%2584%25ed%2595%2598%25ec%2597%25ac-%25eb%258f%2584%25ed%258a%25b8-%25eb%25b3%25b4%25eb%258b%25a4-%25eb%2582%2598%25ec%259d%2580-%25ec%25a4%2591%25ea%25b4%2584%25ed%2598%25b8</link>
		<comments>http://bookworm.pe.kr/wordpress/2012/12/04/2628/#comments</comments>
		<pubDate>Tue, 04 Dec 2012 03:30:57 +0000</pubDate>
		<dc:creator>bookworm</dc:creator>
				<category><![CDATA[컴퓨터]]></category>
		<category><![CDATA[concatenation]]></category>
		<category><![CDATA[echo]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://bookworm.pe.kr/wordpress/?p=2628</guid>
		<description><![CDATA[저번 글에서 콤마(,) 연산자 보다 도트(.) 연산자를 사용하라고 하였다. 콤마 연산자는 매번 write() 시스템 콜을 호출하기 때문이다. 그럼 도트(concatenation) 연산자를 사용하는 것이 최선의 방법일까? 엄밀히 말하면 모든 경우에 그렇지는 않다. $ php -r &#039;$a = 1; $b = 2; $c = 3; echo $a.$b.$c.&#34;\n&#34;;&#039; $ php -r &#039;$a = 1; $b = 2; $c = [...]]]></description>
				<content:encoded><![CDATA[<p><a href="bookworm.pe.kr/wordpress/2012/12/01/2619/">저번 글</a>에서 콤마(,) 연산자 보다 도트(.) 연산자를 사용하라고 하였다. 콤마 연산자는 매번 write() 시스템 콜을 호출하기 때문이다. 그럼 도트(concatenation) 연산자를 사용하는 것이 최선의 방법일까? 엄밀히 말하면 모든 경우에 그렇지는 않다.</p>
<pre class="brush: shell; gutter: false; first-line: 1; highlight: []; html-script: false">$ php -r &#039;$a = 1; $b = 2; $c = 3; echo $a.$b.$c.&quot;\n&quot;;&#039;</pre>
<pre class="brush: shell; gutter: false; first-line: 1; highlight: []; html-script: false">$ php -r &#039;$a = 1; $b = 2; $c = 3; echo &quot;{$a}{$b}{$c}\n&quot;;&#039;</pre>
<p>이 두 코드를 비교하면 전자 보다 후자가 빠르다. 그 이유는 도트 연산자가 두 번 이상 등장하면 연산 작업을 중복하여 여러번 수행하는 문제가 있기 때문이다. 도트를 사용하는 횟수에 따라 급격히 연산 작업 횟수가 증가하므로 다수의 변수를 합친다면 비효율적인 된다.</p>
<p>그러므로 두 번 이상 도트를 사용하여 문자열을 출력해야 하는 경우 중괄호를 사용해서 문자열 내에서 처리를 하는 것이 빠르다. 이 문제는 합치기 연산 횟수에 관련된 것이므로 꼭 echo 문이 아니라 변수에 대입하는 경우도 동일하다.</p>
<p>지금까지 도트 연산자를 주로 사용했다면 앞으로는 중괄호를 사용하는 습관을 들여보도록 하자.</p>
]]></content:encoded>
			<wfw:commentRss>http://bookworm.pe.kr/wordpress/2012/12/04/2628/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP: 보다 빠른 echo를 위하여 &#8211; 콤마(,) 보다 나은 도트(.)</title>
		<link>http://bookworm.pe.kr/wordpress/2012/12/01/2619/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=php-%25eb%25b3%25b4%25eb%258b%25a4-%25eb%25b9%25a0%25eb%25a5%25b8-echo%25eb%25a5%25bc-%25ec%259c%2584%25ed%2595%2598%25ec%2597%25ac-%25ec%25bd%25a4%25eb%25a7%2588-%25eb%25b3%25b4%25eb%258b%25a4-%25eb%2582%2598%25ec%259d%2580-%25eb%258f%2584%25ed%258a%25b8</link>
		<comments>http://bookworm.pe.kr/wordpress/2012/12/01/2619/#comments</comments>
		<pubDate>Sat, 01 Dec 2012 03:30:04 +0000</pubDate>
		<dc:creator>bookworm</dc:creator>
				<category><![CDATA[컴퓨터]]></category>
		<category><![CDATA[echo]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[print]]></category>

		<guid isPermaLink="false">http://bookworm.pe.kr/wordpress/?p=2619</guid>
		<description><![CDATA[PHP 언어에서 print 보다 echo가 빠르다는 것은 널리 알려진 사실이다. 이런 차이는 print의 경우 반환값(1)이 존재하기 때문인데, 물론 이런 반환값 때문에 수식 내에서 사용 할 수 있다는 장점도 있다. 예를 들어 $result = ($n > 1) ? $n : print $n; 과 같은 식을 쓸 수 있다. 그럼 echo는 어떻게 사용해도 똑같을까? 그렇지는 않다. echo [...]]]></description>
				<content:encoded><![CDATA[<p>PHP 언어에서 print 보다 echo가 빠르다는 것은 널리 알려진 사실이다. 이런 차이는 print의 경우 반환값(1)이 존재하기 때문인데, 물론 이런 반환값 때문에 수식 내에서 사용 할 수 있다는 장점도 있다. 예를 들어 $result = ($n > 1) ? $n : print $n; 과 같은 식을 쓸 수 있다.</p>
<p>그럼 echo는 어떻게 사용해도 똑같을까? 그렇지는 않다. echo 또한 어떻게 사용하느냐에 따라 속도가 다르다.</p>
<pre class="brush: shell; gutter: false; first-line: 1; highlight: []; html-script: false">$ php -r &#039;echo &quot;1&quot;,&quot;2&quot;,&quot;3&quot;,&quot;\n&quot;;&#039;</pre>
<pre class="brush: shell; gutter: false; first-line: 1; highlight: []; html-script: false">$ php -r &#039;echo &quot;1&quot;.&quot;2&quot;.&quot;3&quot;.&quot;\n&quot;;&#039;</pre>
<p>이 두 코드는 완전히 동일한 결과를 출력하지만, 후자가 더 빠르고 바람직 하다.</p>
<p>좀 더 자세히 이야기 하자면 첫번째 코드는 "1", "2", "3", "\n"을 각각 출력한다. 정확히는 각 문장마다 write() 시스템 콜을 4번 호출한다.</p>
<p>후자는 4개 문장을 하나로 합친 후에 write()를 1번 호출한다. 후자는 1번만 호출하기 때문에 시스템 콜에 대한 오버헤드가 1번만 발생하고, 커널 영역에 진입하는 횟수가 상대적으로 적다. 사용자 영역에서 커널 영역으로 진입하는 횟수가 많은 것이 좋지 않다. 직접 확인을 해보고 싶은 사람은 strace로 시스템 콜을 확인 해 보는 것도 추천한다.</p>
<pre class="brush: shell; gutter: false; first-line: 1; highlight: []; html-script: false">$ strace php -r &#039;echo &quot;1&quot;.&quot;2&quot;.&quot;3&quot;.&quot;\n&quot;;&#039;</pre>
]]></content:encoded>
			<wfw:commentRss>http://bookworm.pe.kr/wordpress/2012/12/01/2619/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>관리자(프로듀서)에게 기술력을 요구하지 말자</title>
		<link>http://bookworm.pe.kr/wordpress/2012/11/29/2542/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25ea%25b4%2580%25eb%25a6%25ac%25ec%259e%2590%25ed%2594%2584%25eb%25a1%259c%25eb%2593%2580%25ec%2584%259c%25ec%2597%2590%25ea%25b2%258c-%25ea%25b8%25b0%25ec%2588%25a0%25eb%25a0%25a5%25ec%259d%2584-%25ec%259a%2594%25ea%25b5%25ac%25ed%2595%2598%25ec%25a7%2580-%25eb%25a7%2590%25ec%259e%2590</link>
		<comments>http://bookworm.pe.kr/wordpress/2012/11/29/2542/#comments</comments>
		<pubDate>Thu, 29 Nov 2012 03:30:36 +0000</pubDate>
		<dc:creator>bookworm</dc:creator>
				<category><![CDATA[생각]]></category>
		<category><![CDATA[컴퓨터]]></category>
		<category><![CDATA[개발자]]></category>
		<category><![CDATA[관리자]]></category>
		<category><![CDATA[디렉터]]></category>
		<category><![CDATA[실력]]></category>
		<category><![CDATA[아키텍트]]></category>
		<category><![CDATA[프로듀서]]></category>

		<guid isPermaLink="false">http://bookworm.pe.kr/wordpress/?p=2542</guid>
		<description><![CDATA[소프트웨어 개발 프로젝트 안에는 여러 직군이 있지만, 그 중 대표적인 것이 '개발자'와 '관리자'다. 이 둘은 각각 역할을 성공적으로 해내기 위해 여러가지 기술을 갖출 것이 요구 되는데, 공통적인 것도 있지만 서로 다른 부분이 훨씬 더 많다. 개발자라면 프로그래밍 언어와 플랫폼에 대한 이해를 비롯해 각종 알고리즘 등과 같은 컴퓨터 과학의 지식들이 필요하다. 관리자는 문서 작성 능력이나 대인 [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/cappellmeister/5921913/" title="Flickr에서 Cappellmeister님의 Project Management"><img src="http://farm1.staticflickr.com/5/5921913_ac83ed27bd_z.jpg?zz=1" width="640" height="480" alt="Project Management" class="aligncenter"></a></p>
<p>소프트웨어 개발 프로젝트 안에는 여러 직군이 있지만, 그 중 대표적인 것이 '개발자'와 '관리자'다. 이 둘은 각각 역할을 성공적으로 해내기 위해 여러가지 기술을 갖출 것이 요구 되는데, 공통적인 것도 있지만 서로 다른 부분이 훨씬 더 많다. 개발자라면 프로그래밍 언어와 플랫폼에 대한 이해를 비롯해 각종 알고리즘 등과 같은 컴퓨터 과학의 지식들이 필요하다. 관리자는 문서 작성 능력이나 대인 기술 등이 중요 할 것이다. 이렇게 요구되는 기술이 서로 다름에도 불구하고 경력있는 개발자들이 관리자로 자의 또는 타의로 바뀌고 있는 것이 불행한 현실이다.</p>
<p>이런 현상에 대해 여러가지 이유가 있겠지만, 그 중 개발자들이 관리자의 개발 기술력을 따지는 것도 한 원인으로 보고 있다. 개발자와 관리자는 요구하는 기술이 다른데 왜 관리자에게 기술력까지 요구하는 것일까?</p>
<p>그것은 우리나라 소프트웨어 개발에서 디렉터, 아키텍트, 프로듀서의 역할이 제대로 분리되어 있지 않기 때문이다. 현실은 이 셋의 역할을 관리자라는 이름으로 같은 사람이 다 맡고 있다 보니 관리자로서 개발자들을 지원만 해주는 것이 아니라, 여러가지 민감한 기술적인 최종 결정도 내려야 하는 상황이 생기고, 그러다 보니 개발자들은 관리자에게 자신들보다 더 높은 기술력을 요구하게 됐다. 그 결과 많은 경험을 쌓은 개발자가 관리자가 되어야 하는 악순환의 고리가 생겨버린 것이다.</p>
<p>개발자들 보다 더 높은 기술력과 많은 경험이 요구되는 것은 아키텍트다. 그럼에도 불구하고 개발자들은 관리자(프로듀서)에게 기술력을 요구하는 경우가 많다. 실상 요구를 해야 하는 것은 관리자가 아키텍트로서 역할을 하지 말아달라고 하는 것이며, 관리자에게 기술력을 갖추라고 하는 것은 경험 많이 쌓고 기술력을 갖춘 개발자를 관리자로 떠다 미는 효과만을 낳을 뿐이다.</p>
<p>디렉터가 결정을 내리고, 아키텍트가 아키텍트를 디자인 하며, 프로듀서가 프로젝트를 프로듀싱 할 때 개발자가 자꾸 관리자로 변신을 해야 하는 상황을 막을 수 있다.</p>
<p>관리자에게 기술력을 갖추길 요구하지 말고, 아키텍쳐는 아키텍트가 결정을 할 수 있게 해달라고 요구하자. 아키텍트가 없다면 리드 프로그래머라도 그 역할을 대신 수행하면 된다.</p>
]]></content:encoded>
			<wfw:commentRss>http://bookworm.pe.kr/wordpress/2012/11/29/2542/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP: 클래스 매직메소드 __get(), __set() 문제</title>
		<link>http://bookworm.pe.kr/wordpress/2012/11/26/2593/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=php-%25ed%2581%25b4%25eb%259e%2598%25ec%258a%25a4%25ec%259d%2598-%25eb%25a7%25a4%25ec%25a7%2581%25eb%25a9%2594%25ec%2586%258c%25eb%2593%259c-__get-__set-%25eb%25ac%25b8%25ec%25a0%259c</link>
		<comments>http://bookworm.pe.kr/wordpress/2012/11/26/2593/#comments</comments>
		<pubDate>Mon, 26 Nov 2012 03:30:26 +0000</pubDate>
		<dc:creator>bookworm</dc:creator>
				<category><![CDATA[컴퓨터]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[__get]]></category>
		<category><![CDATA[__set]]></category>
		<category><![CDATA[매직메소드]]></category>
		<category><![CDATA[클래스]]></category>

		<guid isPermaLink="false">http://bookworm.pe.kr/wordpress/?p=2593</guid>
		<description><![CDATA[전에 PHP 클래스 매직메소드 __get(), __set() 예제 코드를 올린 적이 있다. 매직메소드 __get, __set에 대해서는 크게 두가지 의견이 있는데, 하나는 OO를 해치기 때문에 getter, setter를 정의해서 사용하라는 것이고, 또다른 하나는 스크립트 언어의 특성이므로 적극 활용을 해야 한다는 것이다. 한동안 getter, setter를 정의해서 사용하다, PHP가 스크립트 언어라는 특성을 활용하는 것이 맞는 이야기인 것 같아 매직메소드를 쓰기 [...]]]></description>
				<content:encoded><![CDATA[<p>전에 <a href="http://bookworm.pe.kr/wordpress/2012/01/24/2397/">PHP 클래스 매직메소드 __get(), __set() 예제</a> 코드를 올린 적이 있다.</p>
<p>매직메소드 __get, __set에 대해서는 크게 두가지 의견이 있는데, 하나는 OO를 해치기 때문에 getter, setter를 정의해서 사용하라는 것이고, 또다른 하나는 스크립트 언어의 특성이므로 적극 활용을 해야 한다는 것이다.</p>
<p>한동안 getter, setter를 정의해서 사용하다, PHP가 스크립트 언어라는 특성을 활용하는 것이 맞는 이야기인 것 같아 매직메소드를 쓰기 시작한 것이 얼마 전부터 사용하고 있다.</p>
<p>그러나 매직메소드는 getter, setter를 작성하는 수고스러움 이상으로 문제를 일으키고 있다. 앞으로 __get(), __set() 매직메소드는 특별한 일이 아닌 이상 사용하지 않을 것 같다.</p>
<p>일단 아래 소스 코드를 보자. 전에 올렸던 글의 예제다.</p>
<pre class="brush: php; gutter: true; first-line: 1; highlight: []; html-script: false">
public function __get($name) {
    if ( property_exists($this, $name) ) {
        return $this-&gt;{$name};
    }
    $method_name = &quot;get_{$name}&quot;;
    if ( method_exists($this, $method_name) ) {
        return $this-&gt;{$method_name}();
    }

    trigger_error(&quot;Undefined property $name or method $method_name&quot;);
}

public function __set($name, $value) {
    if ( property_exists($this, $name) ) {
        $this-&gt;{$name} = $value;
        return;
    }
    $method_name = &quot;set_{$name}&quot;;
    if ( method_exists($this, $method_name) ) {
        $this-&gt;{$method_name}($value);
        return;
    }

    trigger_error(&quot;Undefined property $name or method $method_name&quot;);
}
</pre>
<p>이 코드는 하나의 클래스에서 문제를 일으키지 않는다. 그러나 상속을 받은 경우 다르다.</p>
<pre class="brush: php; gutter: true; first-line: 1; highlight: []; html-script: false">&lt;?php

class Foobar {
    private $name;

    public function __get($name) {
        if ( property_exists($this, $name) ) {
            return $this-&gt;{$name};
        }
        $method_name = &quot;get_{$name}&quot;;
        if ( method_exists($this, $method_name) ) {
            return $this-&gt;{$method_name}();
        }

        trigger_error(&quot;Undefined property $name or method $method_name&quot;);
    }

    public function __set($name, $value) {
        if ( property_exists($this, $name) ) {
            $this-&gt;{$name} = $value;
            return;
        }
        $method_name = &quot;set_{$name}&quot;;
        if ( method_exists($this, $method_name) ) {
            $this-&gt;{$method_name}($value);
            return;
        }

        trigger_error(&quot;Undefined property $name or method $method_name&quot;);
    }
}

class MyFoobar extends Foobar {
    private $age;
}

$foobar = new Foobar();

$foobar-&gt;name = &quot;Foobar&quot;;
echo &quot;{$foobar-&gt;name}\n&quot;;

$my_foobar = new MyFoobar();
$my_foobar-&gt;age = 42;
$my_foobar-&gt;name = &quot;My Foobar&quot;;
echo &quot;{$my_foobar-&gt;name}\n&quot;;
echo &quot;{$my_foobar-&gt;age}\n&quot;;

?&gt;</pre>
<p>실행을 시켜보면 __get() 메소드에서 MyFoobar 클래스 멤버 변수 $age를 찾지 못 하는 것을 에러 메시지로 확인 할 수 있다. 이렇게 된 것은 __get() 메소드가 Foobar 클래스 내에 존재하기 때문이다. 이를 해결하기 위해서는 __get(), __set() 메소드를 MyFoobar로 옮기면 되지만, 그런 경우 Foobar 클래스에 문제가 생길뿐더라 전혀 아름다운 모습이 아니기도 하다.</p>
<p>그나마 조금 절충을 해 볼 수 있는 방법이 멤버 변수들은 protected로 바꾸고 ReflectionProperty() 함수를 이용하는 것이다.</p>
<pre class="brush: php; gutter: true; first-line: 1; highlight: []; html-script: false">&lt;?php

class Foobar {
    protected $name;

    public function __get($name) {
        if ( property_exists($this, $name) ) {
            $refprop = new ReflectionProperty($this, $name);
            $refprop-&gt;setAccessible($name);
            return $refprop-&gt;getValue($this);
        }
        $method_name = &quot;get_{$name}&quot;;
        if ( method_exists($this, $method_name) ) {
            return $this-&gt;{$method_name}();
        }

        trigger_error(&quot;Undefined property $name or method $method_name&quot;);
    }

    public function __set($name, $value) {
        if ( property_exists($this, $name) ) {
            $refprop = new ReflectionProperty($this, $name);
            $refprop-&gt;setAccessible($name);
            $refprop-&gt;setValue($this, $value);
            return;
        }
        $method_name = &quot;set_{$name}&quot;;
        if ( method_exists($this, $method_name) ) {
            $this-&gt;{$method_name}($value);
            return;
        }

        trigger_error(&quot;Undefined property $name or method $method_name&quot;);
    }
}

class MyFoobar extends Foobar {
    protected $age;
}

$foobar = new Foobar();

$foobar-&gt;name = &quot;Foobar&quot;;
echo &quot;{$foobar-&gt;name}\n&quot;;

$my_foobar = new MyFoobar();
$my_foobar-&gt;age = 42;
$my_foobar-&gt;name = &quot;My Foobar&quot;;
echo &quot;{$my_foobar-&gt;name}\n&quot;;
echo &quot;{$my_foobar-&gt;age}\n&quot;;

?&gt;
</pre>
<p>에러가 발생하지 않고 의도한대로 동작한다. 하지만 private으로 선언한 멤버 변수들은 protected로 선언해야 하는 문제가 있다. 이런 문제를 완전히 해결하기 위해서는 다른 언어들처럼 getter, setter를 제대로 정의하는 것이 나아 보인다.</p>
<pre class="brush: php; gutter: true; first-line: 1; highlight: []; html-script: false">&lt;?php

class Foobar {
    private $name;

    public function name() {
        return $this-&gt;name;
    }

    public function set_name($name) {
        $this-&gt;name = $name;
    }
}

class MyFoobar extends Foobar {
    private $age;

    public function age() {
        return $this-&gt;age;
    }

    public function set_age($age) {
        $this-&gt;age = $age;
    }
}

$foobar = new Foobar();

$foobar-&gt;set_name(&quot;Foobar&quot;);
echo &quot;{$foobar-&gt;name()}\n&quot;;

$my_foobar = new MyFoobar();
$my_foobar-&gt;set_age(42);
$my_foobar-&gt;set_name(&quot;My Foobar&quot;);
echo &quot;{$my_foobar-&gt;name()}\n&quot;;
echo &quot;{$my_foobar-&gt;age()}\n&quot;;

?&gt;</pre>
<p>처음 의도한대로 멤버 함수를 private으로 유지하면서 자식 클래스에서 부모의 멤버 변수를 접근하는데 아무런 문제가 생기지 않는다.</p>
<p>다만 멤버 변수가 많은 경우 일일히 getter, setter를 입력하는 것이 번거로우므로 snippet을 생성하는 스크립트나 에디터의 snippet 생성 기능을 적극적으로 활용해서 반복적인 작업 시간을 절약하는 것이 좋을 듯 하다. 간단한 클래스 코드를 생성 해주는 페이지(<a href="http://labs.phpk.org/phpgsgen/">PHP-GSGen</a>)도 있으니 이것을 사용해도 괜찮다.</p>
]]></content:encoded>
			<wfw:commentRss>http://bookworm.pe.kr/wordpress/2012/11/26/2593/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>파란(Paran)의 마지막</title>
		<link>http://bookworm.pe.kr/wordpress/2012/11/24/2563/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25ed%258c%258c%25eb%259e%2580paran%25ec%259d%2598-%25eb%25a7%2588%25ec%25a7%2580%25eb%25a7%2589</link>
		<comments>http://bookworm.pe.kr/wordpress/2012/11/24/2563/#comments</comments>
		<pubDate>Sat, 24 Nov 2012 02:14:10 +0000</pubDate>
		<dc:creator>bookworm</dc:creator>
				<category><![CDATA[생각]]></category>
		<category><![CDATA[컴퓨터]]></category>
		<category><![CDATA[KTH]]></category>
		<category><![CDATA[케텔]]></category>
		<category><![CDATA[코텔]]></category>
		<category><![CDATA[파란]]></category>
		<category><![CDATA[하이텔]]></category>

		<guid isPermaLink="false">http://bookworm.pe.kr/wordpress/?p=2563</guid>
		<description><![CDATA[케텔(KETEL), 코텔(KORTEL), 하이텔(HiTEL)을 거쳐 마지막 파란까지. 고등학교 때 시작한 PC 통신의 인연과 추억이 아직까지 남아있다. 어딘가 아직 하이텔 백업이 남아있다면 문화 유산 차원에서라도 어딘가 보존을 하는 것은 어떨까 싶다.]]></description>
				<content:encoded><![CDATA[<p><a href="http://bookworm.pe.kr/wordpress/wp-content/uploads/2012/10/파란-2012-07-31-23-50-41.png"><img src="http://bookworm.pe.kr/wordpress/wp-content/uploads/2012/10/파란-2012-07-31-23-50-41-752x1024.png" alt="" title="파란의 마지막" width="550" height="748" class="aligncenter size-large wp-image-2564" /></a></p>
<p>케텔(KETEL), 코텔(KORTEL), 하이텔(HiTEL)을 거쳐 마지막 파란까지.</p>
<p>고등학교 때 시작한 PC 통신의 인연과 추억이 아직까지 남아있다.</p>
<p>어딘가 아직 하이텔 백업이 남아있다면 문화 유산 차원에서라도 어딘가 보존을 하는 것은 어떨까 싶다.</p>
]]></content:encoded>
			<wfw:commentRss>http://bookworm.pe.kr/wordpress/2012/11/24/2563/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>린 스타트업: 실리콘밸리를 뒤흔든 IT 창업 가이드</title>
		<link>http://bookworm.pe.kr/wordpress/2012/11/17/2567/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25eb%25a6%25b0-%25ec%258a%25a4%25ed%2583%2580%25ed%258a%25b8%25ec%2597%2585-%25ec%258b%25a4%25eb%25a6%25ac%25ec%25bd%2598%25eb%25b0%25b8%25eb%25a6%25ac%25eb%25a5%25bc-%25eb%2592%25a4%25ed%259d%2594%25eb%2593%25a0-it-%25ec%25b0%25bd%25ec%2597%2585-%25ea%25b0%2580%25ec%259d%25b4%25eb%2593%259c</link>
		<comments>http://bookworm.pe.kr/wordpress/2012/11/17/2567/#comments</comments>
		<pubDate>Sat, 17 Nov 2012 04:42:41 +0000</pubDate>
		<dc:creator>bookworm</dc:creator>
				<category><![CDATA[일상]]></category>
		<category><![CDATA[린스타트업]]></category>
		<category><![CDATA[스타트업]]></category>

		<guid isPermaLink="false">http://bookworm.pe.kr/wordpress/?p=2567</guid>
		<description><![CDATA[작년이었던 것 같다. 한 스타트업 관련 블로그에서 린 스타트업이란 말을 처음 보았다. 그 뒤로 린 스타트업이란 말은 내 주요 관심사 중에 하나가 되었다. 그도 그럴 것이 스타트업에서 일하고 있었고, 어떻게 사업을 해야 할지에 대해 나를 비롯한 사내 구성원들이 많은 고민을 하던 중이었다. 스타트업이 짊어 질 수 밖에 없는 위험을 최소화 하고 추측이 아닌 측정을 통해 [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.hanb.co.kr/book/look.html?isbn=978-89-7914-969-2"><img src="http://bookworm.pe.kr/wordpress/wp-content/uploads/2012/11/lean-startup.png" alt="" title=" 린 스타트업: 실리콘밸리를 뒤흔든 IT 창업 가이드 " width="400" height="580" class="aligncenter size-full wp-image-2568" /></a></p>
<p>작년이었던 것 같다. 한 스타트업 관련 블로그에서 린 스타트업이란 말을 처음 보았다. 그 뒤로 린 스타트업이란 말은 내 주요 관심사 중에 하나가 되었다. 그도 그럴 것이 스타트업에서 일하고 있었고, 어떻게 사업을 해야 할지에 대해 나를 비롯한 사내 구성원들이 많은 고민을 하던 중이었다.</p>
<p>스타트업이 짊어 질 수 밖에 없는 위험을 최소화 하고 추측이 아닌 측정을 통해 점진적으로 사업을 해 나간다는 린 스타트업은 당시 나에게 암흑 속에서 발견한 빛과 같았다. 물론 이 생각은 지금도 마찬가지며, 스타트업을 다시 시작하게 된다면 린 스타트업에 맞춰 사업을 할 생각이다.</p>
<p>린 스타트업이 많은 국내 스타트업들로부터 관심을 받았지만 아직 넓게 퍼지지 못 한 것은 영어로 된 책을 읽어야 하는 부담감도 한 원인일 것 같다. 다행이도 이제나마 한빛미디어에서 오라일리의 린 스타트업 시리즈를 번역하기로 했고, 그 첫번째 책으로 '린 스타트업'이 나왔다.</p>
<p>'린 스타트업'은 린 스타트업 그 자체에 대한 주장 보다도 보다 실용적으로 저자의 경험을 통해 실제 사업을 린 스타트업을 통해 어떻게 해나가는지에 대한 구체적이며 모범적인 사례(예제)와 같다. 그렇기에 스타트업 경험이 없는 사람이라도 첫 기업을 린 스타트업으로 시작하는데 충분한 지침서의 역할을 해주리라 본다. 다만, 스타트업 경험이 없다면 한 번에 깊은 의미를 이해하기 어려울 수 있을지도 모르겠다. 주변에 다른 스타트업 파운더들을 찾아 체득하지 못 한 부분에 대해서는 보충을 좀 받는 것이 어떨까 한다.</p>
<p>이 책은 스타트업 기업을 시작하려는 사람, 그리고 이미 시작한 사람, 마지막으로 스타트업에 근무하는 모든 사람이 꼭 읽어보아야 하는 책이다. 린 스타트업을 따르지 않더라도 알아두면 두고두고 써 먹을 수 있는 기법들과 도구들이 무궁무진 하다. 그것조차 마땅치 않다면 주변에 책을 빌려서 부록만이라도 꼭 읽어 보라.</p>
<p>잠시 스타트업 세상을 떠나 있지만, 언젠가는 스타트업으로 다시 돌아갈 생각이다. 그 때를 위해 이 책을 책꽃이 가까운 곳에 두고 틈틈이 읽어 두어야겠다.</p>
]]></content:encoded>
			<wfw:commentRss>http://bookworm.pe.kr/wordpress/2012/11/17/2567/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>맨먼스 미신(The Mythical Man-Month)</title>
		<link>http://bookworm.pe.kr/wordpress/2012/10/18/2538/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25eb%25a7%25a8%25eb%25a8%25bc%25ec%258a%25a4-%25eb%25af%25b8%25ec%258b%25a0the-mythical-man-month</link>
		<comments>http://bookworm.pe.kr/wordpress/2012/10/18/2538/#comments</comments>
		<pubDate>Thu, 18 Oct 2012 00:00:24 +0000</pubDate>
		<dc:creator>bookworm</dc:creator>
				<category><![CDATA[컴퓨터]]></category>
		<category><![CDATA[맨먼스]]></category>
		<category><![CDATA[미신]]></category>

		<guid isPermaLink="false">http://bookworm.pe.kr/wordpress/?p=2538</guid>
		<description><![CDATA[부끄러운 일이다. 이 유명한 고전을 이제야 읽었다. 한국어 번역서가 뒤늦게 나온 것을 핑계로 삼고 싶지만, 번역서도 2007년에 나왔으니 핑계로 쓰기 마땅치 않다. 굳이 뒤늦게 읽은 이유를 찾으라면 아마 오래된 책이기 때문일듯 하다. 근래 몇년 간 애자일과 스크럼에 관한 책들을 읽었는데, 그 와중에도 맨먼스 미신을 읽지 않았다는 것은 그런 이유일듯 싶다. 읽는 도중 참 여러번 놀랐다. [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://bookworm.pe.kr/wordpress/wp-content/uploads/2012/10/the_mythical_man-month.jpg"><img src="http://bookworm.pe.kr/wordpress/wp-content/uploads/2012/10/the_mythical_man-month.jpg" alt="" title="맨먼스 미신" width="275" height="400" class="aligncenter size-full wp-image-2557" /></a></p>
<p>부끄러운 일이다. 이 유명한 고전을 이제야 읽었다. 한국어 번역서가 뒤늦게 나온 것을 핑계로 삼고 싶지만, 번역서도 2007년에 나왔으니 핑계로 쓰기 마땅치 않다.</p>
<p>굳이 뒤늦게 읽은 이유를 찾으라면 아마 오래된 책이기 때문일듯 하다. 근래 몇년 간 애자일과 스크럼에 관한 책들을 읽었는데, 그 와중에도 맨먼스 미신을 읽지 않았다는 것은 그런 이유일듯 싶다.</p>
<p>읽는 도중 참 여러번 놀랐다. 70년대에 쓰인 책임에도 불구하고 요즘 창업한 스타트업에도 소용되는 이야기가 참 많았기 때문이다. 이 책이 21세기에도 개발자 필독서에서 빠지지 않는 이유를 알 수 있었다.</p>
<p>특히 디렉터와 프로듀서의 이야기는 내 생각과 일치했다. 그 생각은 몇 년의 시행착오 끝에 배운 것이었는데, 만약 맨먼스 미신을 그 전에 읽었다면 훨씬 시간을 절약 할 수 있지 않았을까 싶다.</p>
<p>한 번 읽는 것으로 끝낼 책은 아닌듯 하다. 내년쯤 다시 한 번 이 책을 집어들고 생각이다.</p>
]]></content:encoded>
			<wfw:commentRss>http://bookworm.pe.kr/wordpress/2012/10/18/2538/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>소스코드를 기트허브(GitHub)에 올리다</title>
		<link>http://bookworm.pe.kr/wordpress/2012/10/16/2533/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25ec%2586%258c%25ec%258a%25a4%25ec%25bd%2594%25eb%2593%259c%25eb%25a5%25bc-%25ea%25b8%25b0%25ed%258a%25b8%25ed%2597%2588%25eb%25b8%258cgithub%25ec%2597%2590-%25ec%2598%25ac%25eb%25a6%25ac%25eb%258b%25a4</link>
		<comments>http://bookworm.pe.kr/wordpress/2012/10/16/2533/#comments</comments>
		<pubDate>Tue, 16 Oct 2012 00:00:09 +0000</pubDate>
		<dc:creator>bookworm</dc:creator>
				<category><![CDATA[생각]]></category>
		<category><![CDATA[컴퓨터]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[기트허브]]></category>
		<category><![CDATA[오픈소스]]></category>

		<guid isPermaLink="false">http://bookworm.pe.kr/wordpress/?p=2533</guid>
		<description><![CDATA[페이스북에서 기트허브(GitHub)에 관한 이야기를 나누다, 문득 가지고 있는 소스 코드를 모두 올려야겠다 생각이 들었다. 한동안 머리 속에 담아두고 있다 얼마 전에야 정리해서 올려놓았다. (https://github.com/bookwormkr) 기트허브에 소스 코드를 올린 것은 가지고 있는 공개하지 못 할 이유가 없기 때문이다. 일 하면서 만든 코드들은 회사의 소유이기 때문에 퇴사 후 개인적으로 가지고 있는 것도 금지된 일이다. 나머지 코드들은 직접 [...]]]></description>
				<content:encoded><![CDATA[<p align="center">
<a href="http://www.flickr.com/photos/acarlos1000/7236074800/" title="Flickr에서 Acarlos1000님의 Github smoothie"><img src="http://farm8.staticflickr.com/7096/7236074800_d3a70c0a81.jpg" width="375" height="500" alt="Github smoothie"></a>
</p>
<p>페이스북에서 <a href="https://github.com/">기트허브(GitHub)</a>에 관한 이야기를 나누다, 문득 가지고 있는 소스 코드를 모두 올려야겠다 생각이 들었다. 한동안 머리 속에 담아두고 있다 얼마 전에야 정리해서 올려놓았다. (<a href="https://github.com/bookwormkr">https://github.com/bookwormkr</a>)</p>
<p>기트허브에 소스 코드를 올린 것은 가지고 있는 공개하지 못 할 이유가 없기 때문이다. 일 하면서 만든 코드들은 회사의 소유이기 때문에 퇴사 후 개인적으로 가지고 있는 것도 금지된 일이다. 나머지 코드들은 직접 만든 것이거나 오픈소스를 수정한 것들인데 공개를 한다해도 아무런 문제가 없다.</p>
<p>개발자들이 소스 코드를 공개하지 않는 것에는 정리되지 않았다던지, 공개 할만한 수준의 코드가 아니라던지 등의 이유도 있다. 하지만 널리 쓰이는 코드가 아니라면 애써 다른 사람의 소스 코드를 읽고 있을 개발자는 별로 없다. 운이 좋아 누군가로부터 이유있는 비판을 받게 된다면 개선의 기회로 삼으면 될 일이다. 오히려 개선의 피드백을 받지 못하는 상황이 더 안타까운 일이다. 만약 근거없는 악의적 공격을 받게 된다면 그냥 미소지어 주자. <img src='http://bookworm.pe.kr/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>공개를 하면서 개인 라이브러리와 과제물처럼 추억 때문에 남겨두었던 코드들을 삭제했다. 그런 뒤 가진 소스 코드를 다 올려놓았다. 이제 나만 가지고 있는 코드는 없다. 기트허브에서 클론한 작업본을 빼면 말이다.</p>
<p>앞으로 모든 취미 프로젝트나 소소한 장난(?)들도 모두 기트허브를 통해 진행 할 생각이다. 오픈소스로서 의미를 두는 것이 아니라, 공개해서 안 될 이유가 없기 때문이다.</p>
]]></content:encoded>
			<wfw:commentRss>http://bookworm.pe.kr/wordpress/2012/10/16/2533/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>아름다운 마무리를 위해 무엇을 할까</title>
		<link>http://bookworm.pe.kr/wordpress/2012/10/14/2531/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25ec%2595%2584%25eb%25a6%2584%25eb%258b%25a4%25ec%259a%25b4-%25eb%25a7%2588%25eb%25ac%25b4%25eb%25a6%25ac%25eb%25a5%25bc-%25ec%259c%2584%25ed%2595%25b4-%25eb%25ac%25b4%25ec%2597%2587%25ec%259d%2584-%25ed%2595%25a0%25ea%25b9%258c</link>
		<comments>http://bookworm.pe.kr/wordpress/2012/10/14/2531/#comments</comments>
		<pubDate>Sat, 13 Oct 2012 22:02:50 +0000</pubDate>
		<dc:creator>bookworm</dc:creator>
				<category><![CDATA[생각]]></category>
		<category><![CDATA[마무리]]></category>
		<category><![CDATA[무소유]]></category>
		<category><![CDATA[법정]]></category>
		<category><![CDATA[스님]]></category>

		<guid isPermaLink="false">http://bookworm.pe.kr/wordpress/?p=2531</guid>
		<description><![CDATA[얼마 전 법정 스님의 '아름다운 마무리'를 읽었다. '무소유'에 이어 두번째 법정 스님 책이다. 흔히 '흙에서 나서 흙으로 돌아간다'고 삶을 말한다. 이렇듯 사람은 '무(無)'에서 나 '무'로 돌아가기 마련이다. '아름다운 마무리'를 읽으며 '무'로 돌아가기 전에 무엇을 해야 할까라는 고민이 든다. 생각이 몇개 떠오른다. 그 중 가장 마음이 가는 것은 사라진 나 이후에도 남게될 것들을 말끔히 치워놓는 일이다. [...]]]></description>
				<content:encoded><![CDATA[<p>얼마 전 법정 스님의 '아름다운 마무리'를 읽었다. '무소유'에 이어 두번째 법정 스님 책이다.</p>
<p>흔히 '흙에서 나서 흙으로 돌아간다'고 삶을 말한다. 이렇듯 사람은 '무(無)'에서 나 '무'로 돌아가기 마련이다. '아름다운 마무리'를 읽으며 '무'로 돌아가기 전에 무엇을 해야 할까라는 고민이 든다.</p>
<p>생각이 몇개 떠오른다. 그 중 가장 마음이 가는 것은 사라진 나 이후에도 남게될 것들을 말끔히 치워놓는 일이다. 치운다 하였지만 날 때 가지고 난 것이 없으니, 빌려온 것을 돌려준다 말하는게 어울린다.</p>
<p>빌려온 것에는 일상의 물건도 있겠으나, 생각과 말 또한 실상은 빌려온 것이다. 그런 연유로 법정 스님이 '말 빚'을 남기지 않겠다 하시며 쓰신 책을 없애달라 하신 것이 아닐까 싶어진다.</p>
<p>운을 바라며 살지는 않지만, 떠날 때 빚을 갚고 갈 수 있으면 하는 바람이다.</p>
]]></content:encoded>
			<wfw:commentRss>http://bookworm.pe.kr/wordpress/2012/10/14/2531/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>자신만의 개인 라이브러리 또는 프레임웤이 필요할까</title>
		<link>http://bookworm.pe.kr/wordpress/2012/09/26/2521/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25ec%259e%2590%25ec%258b%25a0%25eb%25a7%258c%25ec%259d%2598-%25ea%25b0%259c%25ec%259d%25b8-%25eb%259d%25bc%25ec%259d%25b4%25eb%25b8%258c%25eb%259f%25ac%25eb%25a6%25ac-%25eb%2598%2590%25eb%258a%2594-%25ed%2594%2584%25eb%25a0%2588%25ec%259e%2584%25ec%259b%25a4%25ec%259d%25b4-%25ed%2595%2584%25ec%259a%2594%25ed%2595%25a0</link>
		<comments>http://bookworm.pe.kr/wordpress/2012/09/26/2521/#comments</comments>
		<pubDate>Wed, 26 Sep 2012 03:30:35 +0000</pubDate>
		<dc:creator>bookworm</dc:creator>
				<category><![CDATA[생각]]></category>
		<category><![CDATA[컴퓨터]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[private]]></category>
		<category><![CDATA[개인]]></category>
		<category><![CDATA[라이브러리]]></category>
		<category><![CDATA[프레임웤]]></category>

		<guid isPermaLink="false">http://bookworm.pe.kr/wordpress/?p=2521</guid>
		<description><![CDATA[프로그래머는 자신만의 라이브러리 또는 프레임웤(이하 라이브러리만 표기)를 갖춰야 한다는 이야기가 있다. 경력이 쌓인 개발자라면 효율을 높이고 자신만의 무기(?)를 갖추기 위해서 필요하다는 것이다. 그럴 필요가 있을까라는 의문이 든다. 과거에는 그럴 필요가 있었다. 그러나 지금은 달라졌다는 생각이다. 필요한 라이브러리는 오픈소스로 이미 존재하고 있다고 말 할 수 있을만큼 오픈소스의 양이 방대해졌다. 오픈소스는 많은 사람들이 사용하면서 검증되고 개선된다. 과연 [...]]]></description>
				<content:encoded><![CDATA[<p align="center">
<a href="http://www.flickr.com/photos/opensourceway/6555466069/" title="Flickr에서 opensourceway님의 Brigham Young University faculty survey seeks to advance open education through academic libraries"><img src="http://farm8.staticflickr.com/7172/6555466069_3246e8b54e_z.jpg" width="640" height="359" alt="Brigham Young University faculty survey seeks to advance open education through academic libraries"></a>
</p>
<p>프로그래머는 자신만의 라이브러리 또는 프레임웤(이하 라이브러리만 표기)를 갖춰야 한다는 이야기가 있다. 경력이 쌓인 개발자라면 효율을 높이고 자신만의 무기(?)를 갖추기 위해서 필요하다는 것이다.</p>
<p>그럴 필요가 있을까라는 의문이 든다. 과거에는 그럴 필요가 있었다. 그러나 지금은 달라졌다는 생각이다.</p>
<p>필요한 라이브러리는 오픈소스로 이미 존재하고 있다고 말 할 수 있을만큼 오픈소스의 양이 방대해졌다. 오픈소스는 많은 사람들이 사용하면서 검증되고 개선된다. 과연 개인이 만든 것이 세계의 뛰어난 개발자들이 협력해서 만든 것 보다 더 나은 품질을 가질 가능성이 얼마나 될까? 가능성이 높아 보이지 않는다.</p>
<p>업무에 개인 라이브러리를 사용한다면 문제는 더 심각 해진다. 코드에 문제가 생긴다면 다른 개발자들이 개인이 만든 라이브러리를 확인 해 봐야 할 수도 있다. 널리 쓰이는 라이브러리나 프레임웤을 사용한다면 다른 개발자들도 그것에 대해 잘 알고 있을 수 있다. 더구나 오픈소스는 문서화도 개인 라이브러리 보다 더 잘 되어 있다. 유명한 라이브러리는 책까지 나와 있다. 라이브러리를 만든 개발자는 좀 더 편하고 빠르게 개발 할 수 있을지 몰라도 팀과 프로젝트를 생각하면 오히려 손해다.</p>
<p>오픈소스 라이브러리가 원하는 기능을 충분히 제공하지 않기 때문에 개인적으로 라이브러리를 만든다고 할 수도 있다. 그러나 그 경우도 차라리 패치를 해서 사용하고, 패치를 메인 스트림에 반영 해 달라고 요청하는 편이 더 낫다.</p>
<p>만약 자신이 정말 대단한 라이브러리를 만들어서 다른 오픈소스가 따라 오지 못 할 정도라면, 개인 라이브러리로 만들 것이 아니라 오픈소스로 공개를 하는 것이 맞다. 그렇게 함으로서 많은 개발자들에게 도움을 주고, 많은 피드백을 통해 더 훌륭한 라이브러리가 될 수 있다.</p>
<p>자신만의 코드로 밥그릇을 지켜야 한다고 생각하는 프로그래머가 존재하지 않으리라 생각한다. 왜냐하면 그런 프로그래머는 인터넷과 오픈소스의 물결에 휩쓸려 다 소멸한 것으로 알기 때문이다.</p>
]]></content:encoded>
			<wfw:commentRss>http://bookworm.pe.kr/wordpress/2012/09/26/2521/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP로 서버(데몬) 만들기</title>
		<link>http://bookworm.pe.kr/wordpress/2012/09/25/2452/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=php%25eb%25a1%259c-%25ec%2584%259c%25eb%25b2%2584%25eb%258d%25b0%25eb%25aa%25ac-%25eb%25a7%258c%25eb%2593%25a4%25ea%25b8%25b0</link>
		<comments>http://bookworm.pe.kr/wordpress/2012/09/25/2452/#comments</comments>
		<pubDate>Tue, 25 Sep 2012 03:30:20 +0000</pubDate>
		<dc:creator>bookworm</dc:creator>
				<category><![CDATA[컴퓨터]]></category>
		<category><![CDATA[daemon]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[System_Daemon]]></category>
		<category><![CDATA[데몬]]></category>

		<guid isPermaLink="false">http://bookworm.pe.kr/wordpress/?p=2452</guid>
		<description><![CDATA[PHP는 웹에 특화된 언어다. 그렇게 때문에 애플리케이션이나 시스템 프로그래밍을 할 때 필요한 기능이 부족하다. 하지만 서비스를 만들다 보면 서버(데몬)처럼 웹을 벗어난 것이 필요 할 때가 생긴다. 이럴 때는 아파치(Apache)나 crond를 이용해 문제를 해결 할 수 있다. 그러나 아파치나 crond를 이용한 방법은 어느 정도 한계가 있기 때문에 경우에 따라 해결책이 되지는 못 한다. 이런 경우 백그라운드로 [...]]]></description>
				<content:encoded><![CDATA[<p>PHP는 웹에 특화된 언어다. 그렇게 때문에 애플리케이션이나 시스템 프로그래밍을 할 때 필요한 기능이 부족하다. 하지만 서비스를 만들다 보면 서버(데몬)처럼 웹을 벗어난 것이 필요 할 때가 생긴다. 이럴 때는 아파치(Apache)나 crond를 이용해 문제를 해결 할 수 있다.</p>
<p>그러나 아파치나 crond를 이용한 방법은 어느 정도 한계가 있기 때문에 경우에 따라 해결책이 되지는 못 한다. 이런 경우 백그라운드로 동작하는 데몬을 만드는 것이 깔끔하다.</p>
<p>데몬을 만드는 방법은 널리 알려져있기 때문에 거기에 맞춰 코드를 작성해도 되지만, 굳이 바퀴를 다시 발명 할 필요는 없을테니 System_Daemon PEAR 모듈을 이용하면 된다.</p>
<p>System_Daemon 모듈을 사용한 간단한 예제를 우선 살펴보자.</p>
<pre class="brush: php; gutter: true; first-line: 1; highlight: [1]; html-script: false">
#!/usr/local/php/bin/php -q
&lt;?php
ini_set(&#039;include_path&#039;, ini_get(&#039;include_path&#039;).&#039;:..&#039;);

error_reporting(E_ALL);
require_once &quot;System/Daemon.php&quot;;

$appname = &quot;example&quot;;

System_Daemon::setOption(&quot;appName&quot;, $appname);
System_Daemon::setOption(&quot;appRunAsUID&quot;, getmyuid());
System_Daemon::setOption(&quot;appRunAsGID&quot;, getmygid());
System_Daemon::setOption(&quot;logLocation&quot;, getcwd().&quot;/log/$appname.log&quot;);
System_Daemon::setOption(&quot;appPidLocation&quot;, getcwd().&quot;/log/$appname/$appname.pid&quot;);

System_Daemon::start();
while ( true ) {
    System_Daemon::log(System_Daemon::LOG_INFO, &quot;HELLO - &quot;.time());
    sleep(1);
}
System_Daemon::stop();
?&gt;
</pre>
<p>참고로 System_Daemon 모듈을 사용하기 위해서는 --enable-pcntl 옵션으로 컴파일 되어 있어야 한다. 1번째 줄의 php 경로는 각자 php 설정에 맞춰 수정하면 된다.</p>
<p>System_Daemon 사용법은 간단하나 몇가지 조심해야 할 부분이 있다.</p>
<p>appRunAsUID나 appRunAsGID를 통해 특정 사용자나 그룹으로 실행하고 싶은 경우 root 권한이 필요하다.</p>
<p>또한 pid 파일은 다른 파일과 섞이지 않는 독립적인 디렉토리로 설정해야 하며, 자동으로 디렉토리를 생성해주지 않는다. 보통 로그 디렉토리 안에 log/foobar/foobar.pid 형식으로 구성한다고 보면 된다. 만약 root로 실행을 하거나 디렉토리 퍼미션을 잘 조정 해 줄 생각이라면 /var/run 안으로 구성하는 것이 더 좋겠다.</p>
<p>그리고 logLocation이나 appPidLocation 설정은 절대 경로로 해야 한다. 보통 프로세스가 데몬으로 바뀌면 워킹 디렉토리를 루트(/)로 설정을 하게 되는데, 이것에 영향을 받기 때문으로 보인다.</p>
<p>PEAR 사이트의 문서에는 옵션이 없으므로 어떤 옵션이 있는지 직접 소스 코드를 열어 읽어 봐두어야 한다. lib/php/System/Daemon.php 파일이다. php를 패키지로 설치한 경우 깊숙히 들어있으므로 locate 명령으로 찾는 것이 더 편하다. 전체 코드를 다 볼 필요는 없고 $_optionDefinitions 변수만 읽어 보면 된다.</p>
]]></content:encoded>
			<wfw:commentRss>http://bookworm.pe.kr/wordpress/2012/09/25/2452/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>멀티 프로세스끼리 간단한 데이터 공유 방법 &#8211; mmap()</title>
		<link>http://bookworm.pe.kr/wordpress/2012/09/24/2512/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25eb%25a9%2580%25ed%258b%25b0-%25ed%2594%2584%25eb%25a1%259c%25ec%2584%25b8%25ec%258a%25a4%25eb%2581%25bc%25eb%25a6%25ac-%25ea%25b0%2584%25eb%258b%25a8%25ed%2595%259c-%25eb%258d%25b0%25ec%259d%25b4%25ed%2584%25b0-%25ea%25b3%25b5%25ec%259c%25a0-%25eb%25b0%25a9%25eb%25b2%2595-mmap</link>
		<comments>http://bookworm.pe.kr/wordpress/2012/09/24/2512/#comments</comments>
		<pubDate>Sun, 23 Sep 2012 23:25:53 +0000</pubDate>
		<dc:creator>bookworm</dc:creator>
				<category><![CDATA[컴퓨터]]></category>
		<category><![CDATA[mmap]]></category>
		<category><![CDATA[멀티프로세스]]></category>
		<category><![CDATA[메모리맵]]></category>

		<guid isPermaLink="false">http://bookworm.pe.kr/wordpress/?p=2512</guid>
		<description><![CDATA[멀티 프로세스끼리는 멀티쓰레드처럼 직접 변수에 접근하기 어렵기 때문에 공유 메모리 등과 같은 IPC를 이용해서 데이터를 주고 받는데, 복잡하고 다양한 기능이 필요없다면 메모리맵을 통해 서로 간단히 데이터를 공유 할 수 있다. #include &#60;unistd.h&#62; #include &#60;stdio.h&#62; #include &#60;stdlib.h&#62; #include &#60;pthread.h&#62; #include &#60;sys/types.h&#62; #include &#60;sys/wait.h&#62; #include &#60;sys/mman.h&#62; int main(void) { void *p; p = mmap(0, 1024, PROT_READ&#124;PROT_WRITE, MAP_SHARED&#124;MAP_ANONYMOUS, [...]]]></description>
				<content:encoded><![CDATA[<p>멀티 프로세스끼리는 멀티쓰레드처럼 직접 변수에 접근하기 어렵기 때문에 공유 메모리 등과 같은 IPC를 이용해서 데이터를 주고 받는데, 복잡하고 다양한 기능이 필요없다면 메모리맵을 통해 서로 간단히 데이터를 공유 할 수 있다.</p>
<pre class="brush: c; gutter: true; first-line: 1; highlight: []; html-script: false">
#include &lt;unistd.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;pthread.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/wait.h&gt;
#include &lt;sys/mman.h&gt;

int main(void) {
    void *p;

    p = mmap(0, 1024, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
    if ( p == MAP_FAILED ) {
        puts(&quot;mmap() error&quot;);
        exit(1);
    }

    sleep(10);

    if ( munmap(p, 1024) ) {
        puts(&quot;munmap() error&quot;);
        exit(1);
    }

    return 0;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://bookworm.pe.kr/wordpress/2012/09/24/2512/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>멀티프로세스 데몬에서 락킹(Locking)하기</title>
		<link>http://bookworm.pe.kr/wordpress/2012/09/22/2506/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25eb%25a9%2580%25ed%258b%25b0%25ed%2594%2584%25eb%25a1%259c%25ec%2584%25b8%25ec%258a%25a4-%25eb%258d%25b0%25eb%25aa%25ac%25ec%2597%2590%25ec%2584%259c-%25eb%259d%25bd%25ed%2582%25b9locking%25ed%2595%2598%25ea%25b8%25b0</link>
		<comments>http://bookworm.pe.kr/wordpress/2012/09/22/2506/#comments</comments>
		<pubDate>Fri, 21 Sep 2012 21:10:09 +0000</pubDate>
		<dc:creator>bookworm</dc:creator>
				<category><![CDATA[컴퓨터]]></category>
		<category><![CDATA[fork]]></category>
		<category><![CDATA[pthread]]></category>
		<category><![CDATA[pthread_mutexattr_setpshared]]></category>
		<category><![CDATA[pthread_mutex_lock]]></category>
		<category><![CDATA[멀티프로세스]]></category>
		<category><![CDATA[잠금]]></category>

		<guid isPermaLink="false">http://bookworm.pe.kr/wordpress/?p=2506</guid>
		<description><![CDATA[pthread를 사용하는 멀티쓰레드 데몬이라면 pthread_mutex_lock()을 사용해 잠금을 할 것이며, 멀티프로세스 데몬이라면 세마포어를 사용 할 것이다. 흥미로운 부분은 많은 OS에서 뮤텍스를 이진 세마포어(binary semaphore)로 구현을 하고 있고, pthread 또한 멀티프로세스를 위한 잠금을 지원한다는 것이다. #include &#60;unistd.h&#62; #include &#60;stdio.h&#62; #include &#60;stdlib.h&#62; #include &#60;pthread.h&#62; #include &#60;sys/types.h&#62; #include &#60;sys/wait.h&#62; int main(void) { pthread_mutex_t lock; pthread_mutexattr_t attr; if ( pthread_mutexattr_init(&#38;attr) [...]]]></description>
				<content:encoded><![CDATA[<p>pthread를 사용하는 멀티쓰레드 데몬이라면 pthread_mutex_lock()을 사용해 잠금을 할 것이며, 멀티프로세스 데몬이라면 세마포어를 사용 할 것이다.</p>
<p>흥미로운 부분은 많은 OS에서 뮤텍스를 이진 세마포어(binary semaphore)로 구현을 하고 있고, pthread 또한 멀티프로세스를 위한 잠금을 지원한다는 것이다.</p>
<pre class="brush: c; gutter: true; first-line: 1; highlight: [17]; html-script: false">
#include &lt;unistd.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;pthread.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/wait.h&gt;

int main(void) {
    pthread_mutex_t lock;
    pthread_mutexattr_t attr;

    if ( pthread_mutexattr_init(&amp;attr) ) {
        puts(&quot;pthread_mutexattr_init() error&quot;);
        exit(1);
    }

    if ( pthread_mutexattr_setpshared(&amp;attr, PTHREAD_PROCESS_SHARED) ) {
        puts(&quot;pthread_mutexattr_setpshared() error&quot;);
        exit(1);
    }

    if ( pthread_mutex_init(&amp;lock, &amp;attr) ) {
        puts(&quot;pthread_mutex_init() error&quot;);
        exit(1);
    }

    int i;
    for ( i = 0; i &lt; 5; i++ ) {
        if ( fork() == 0 ) {
            int j;
            for ( j = 0; j &lt; 5; j ++ ) {
                if ( pthread_mutex_lock(&amp;lock) ) {
                    puts(&quot;pthread_mutex_lock() error&quot;);
                    exit(1);
                }
                printf(&quot;pid = %d, lock\n&quot;, getpid());
                sleep(1);
                if ( pthread_mutex_unlock(&amp;lock) ) {
                    puts(&quot;pthread_mutex_unlock() error&quot;);
                    exit(1);
                }
                printf(&quot;pid = %d, unlock\n&quot;, getpid());
            }
            break;
        }
        else {
            wait(NULL);
        }
    }

    pthread_mutexattr_destroy(&amp;attr);
    pthread_mutex_destroy(&amp;lock);

    return 0;
}
</pre>
<p>멀티프로세스에서 pthread_mutex_lock()으로 잠금을 하기 위해서는 17번째 줄처럼 pthread 뮤텍스를 설정 해주어야 한다. 이 설정은 fork()가 호출되기 전에 이뤄져야 한다는 점을 주의하자.</p>
]]></content:encoded>
			<wfw:commentRss>http://bookworm.pe.kr/wordpress/2012/09/22/2506/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
