(서평) 코딩 호러의 이펙티브 프로그래밍

스택 오브 플로우의 창시자로 알려져 있는건 조엘 온 소프트웨어로 더 유명한 조엘 스포스키였다.

내가 좀 잘못 알고 있었던 부분으로, 공동 창업자이자 테크니컬한 부분을 모두 담당한건 제프 앳 우드였다.

스택 오버플로우가 어디인가? 가장 유명한 개발자 커뮤니티 아니던가?

그런 스택 오버플로우가 어떤 고민과 고찰을 했는가에 대한 책이라니 구매하지 않을 수 없었다.


이 책의 원제는 Effective Programming : More Than Writing Code 인데, 사실 과거에 꽤나 긴 시간동안 most important is coding라고 생각해왔었다.

프로그래머들에게 충분한 자원과 지원이 이루어지면 프로젝트는 잘 굴러간다고 믿었지만, 그 것이 사실이 아니란 것을 깨닳는 데에는 아주 오랜시간이 걸리진 않았다.


나는 다른 부분보다 4부 프로그래머를 제대로 채용하는 법가 매우 관심이 갔다. 채용 결정권자는 아닌 때도 많았지만 면접관으로 참관할 때가 적지 않았고, 그 과정에서 많은 고민이 있었다. 실제로 최근 국내 많은 회사가 코딩 테스트를 진행하고 있는데 (이에 대한 회의론도 적진 않지만), 필요하겠구나 싶을 만큼 의외로 코딩을 잘 못하는 케이스가 많았다.

심지어는 이 책에서와 마찬가지로 채용하고나니 코딩을 전혀 못하는 케이스도 실제로 봤고, 면접 때와 실제 장단점을 반대인 경우도 봤다.

제대로 된 채용보다 중요한 것은, 최악의 채용을 하지 않는 것인데, 이는 쉽지 않은 문제다.

절대로 경력이 쌓인다고 좋은 프로그래머가 저절로 되지 않는다.

그렇기에 이를 판단하는 기준과 수단은 높아지고 있고, 이 허들로 인해 진짜 괜찮은 프로그래머의 소소한 단점으로 인재를 놓치는 일도 비일비재하다.

현재의 채용 과정과 허들은 누구에게도 좋지 않지만, 그렇다고 허들을 없애는 것도 좋은 대안이라 볼 순 없다.


위에서 언급한 것과 마찬가지로, 나는 개발에 있어 코딩이 가장 중요한 덕목이라고 여겨왔다.

하지만 1인 개발이 아닌 이상에는 사람 문제가 더 크고, 그에 대한 챕터가 바로 5부 팀이 함께 일하도록 만들기이다.

마이크로 매니지먼트 부터 시작해서, 자율 방임 등 다양한 시도가 프로그래밍 팀에 있어왔음에도 여전히 결론은 상황에 맞는 선택을 하자와 같은 모호한 중립적 입장의 결론만 남아있을 뿐이다.

은총알은 없다, 맨먼스 미신 등에서 지적하는 문제의 근간은 소통 비용이 클 수록 개발 효율은 감소한다이다.

관리, 회의, 협업, 보고 모두 효율을 저해한다.

하지만 일정 부분은 필요하다. 그 사이의 적절한 중간 지점을 찾는 것은 어렵다.


시스템을 구현 하는 입장에서, 기능적인 스펙보다 더 중요한 것은 사용자다.

그에 대한 챕터가 7부 사용자를 염두에 두고 설계하기이다.

애플리케이션은 결국, 작은 디테일의 모음이란 말은 매번 주장하지만, 지켜지기 어렵고 중요시 여기지기 어렵고, 누군가는 다른 외부요인보다 중요하지 않다고 한다.

아무리 남들과 차별화 된 컨텐츠, 시장 점유율, 뛰어난 가성비를 자랑하고 있다고해도, 어플리케이션의 완성도에 문제가 있다면 그 빈틈은 언제든 꿰뚫릴 수 있는 큰 문제로 번지기 쉽다.

사용성에 대한 고민도, 사실 개발자들은 많이 하지 않는다. 코드의 일관성, 클래스 구조, 코드 가독성, 아키텍쳐 구조 등 내부적 문제에 대한 관심은 아주 크지만, 사용성에 대한 고민은 그만큼 크지 않은 것이 일반적이다.

이 문제는 결국 잘 만든 기반을 사용자가 외면함으로써 모든 노력이 수포로 돌아가기 쉬운 결정이다.

이 챕터에서의 내용들은 다 공감이 크게 갔는데, 그 중에서도 버전 1은 엉망이야, 하지만 어쨌든 출시하라고는 심금을 울리는 명언이다.

어떠한 소프트웨어도 버전 1에서 사용자를 감동 시킨 적은 흔치 않다.

그렇기 때문에, 출시하고 개선해나가는 과정에서 사용자를 만족시켜야 한다. 지속적으로 나아지고, 그 방향성이 사용자와 공감대를 이루고 있다면 그 소프트웨어는 결국 훌륭한 소프트웨어가 된다.


이외에도 수 많은 이야기들이 우리가 개발하면서 겪게 되는 수많은 문제에 대한 경험담이자 솔루션이다.

내 개인적으론 이런 프로그래밍 관련 에세이를 좋아하는데, 그 중에서도 작년 읽은 책 중에 유독 맘에 든 책이다.


서적 링크 : http://www.yes24.com/24/goods/8611802

(서평) 임백준의 대살개문

전격 팩폭서.

나는 한국에서 게임 회사에서만 13년째 일하고 있다. 솔직히 고백하자면 나는 몸 상할 정도로 힘들게 일한 때가 많지는 않다. (있긴 있었다)

그럼에도 나 역시 새벽까지 일한적이 여러가지 이유로 꽤나 많았다. 모든 개발이 그렇다지만, 게임 역시 개발의 특성상 바쁜 시기와 마감 시기가 엄격히 존재하고, 여기에 다국가 진출 시 (모바일로 넘어오며 글로벌 원빌드인 요새는 통용되지 않겠지만) 해당 퍼블리셔 시간대에 맞추느라 새벽 점검이나 모니터링이 빈번하게 이루어졌다.

한국보다 개발 문화가 좋다는 미국이 정말 얼마나 좋은 지 말해주는 에피소드들이 좋았다. 나는 일해보지 않았지만 한국의 SI에 대한 열악함과 불합리함, 또한 굳이 SI로 한정 짓지 않아도 소프트웨어 개발에 대한 경시에 대한 이야기를 많이 하셨다.

물론 게임회사도 상대적으로 기술보다는 기획/사업/아트가 더 화두가 되긴 하고, 엔지니어링 퀄리티나 개발자에 대한 배려보다는 산출물이나 일정이 더 중요시 여겨지는 것도 사실이다.

엔지니어링은 내실이다. 내실보다 외관을 선호하는 풍토는 오래된 악습 같은 것이다.

이어지는 이과 경시, 소프트웨어 개발 경시는 하루이틀 일이 아니다.

특히나 잦은 요구사항이 중요하다면 그만큼 탄탄한 기반과, 유연한 구조 설계, 변화에 제약이 적은 구현, 커버리지 확보와 같은 엔지니어링에서의 이 너무나도 중요함에도 눈에 보이지 않는 구현체인 소프트웨어 개발은 너무나 쉽게 생각하는 경우가 많다.

장비나 물류에 대한 코스트가 덜 들어가는 것이 이득인데, 그만큼 투자한 게 적어서 일까?

절대적 소요 시간이나, 선행 작업들에 대한 이해를 하려고 하지도 않고, 하면 된다 정신으로 무리한 요구를 하고, 그렇게 해서 나온 낮은 퀄리티의 결과물이 그 작업자들의 기량 부족과 책임감 결여라고 생각하는 경향이 매우 크다.

게임 산업은 흥행 산업이라는 분류를 기반으로 눈에 보이는 작업과 엔지니어링 퀄리티 간의 괴리를 합리화하기 일쑤다.

나는 조금 늦게 깨닳아버린, 이런 괴리감의 실체에 대해서 조금 더 와닿아 씁쓸함을 안겨주기도 했다.

이외에도 임백준씨가 항상 주장하던 프로그래밍의 미학, 디테일의 중요성, 프로그래밍 이상의 것을 어떻게 배우는 지에 대해서도 이야기 해준다.

다른 주제들로는 책이 나올 당시 핫했던 (지금도 여전히 핫한 내용도 포함되어있다) NoSQL, Actor 기반 프로그래밍, 함수형 프로그래밍, 머신 러닝 등의 기술 이슈에 대해서 왜 등장했고 어떤 장단점이 있는지에 대해서도 언급하고 있다.

또한 지금에와서 아주 핫해진 비트코인 채굴에 대한 챕터(해당 챕터는 2014년 5월 컬럼)도 있으니, 3년 반전의 임백준씨의 생각은 무엇이고 어떠한 원리인지 앞서간 사람들의 이야기도 조금은 알 수 있었다.

전체적으로 대살 개문이라는 전제라서, 대한 민국의 개발 문화에 대한 내용만 있을 줄 알았지만 그렇지 않다. 절반 이상의 내용이 좋은 프로그래머가 되기 위한 내용, 현재 트렌드인 기술에 대한 이야기, 해커 레벨까지 성장하기 위한 가이드, 자기 개발 방법등의 무수히 좋은 내용을 담고 있다.

이전의 임백준씨 책들도 항상 깊이 있었지만 이 책은 조금 더 와닿은 면이 컸다.

나역시 시니어라는 부담스러운 위치에서 일해야 하는 입장이고, 앞으로도 성장하고 싶고, 쉽지 않겠지만 해커, 구루라는 이름에 어울리는 프로그래머가 되고 싶은 입장에서 많은 고민과 생각거리를 안겨준 책이었다.

자신이 프로그래머라는 직업을 가지고 있다는 전제만으로도 읽어볼만한 책이고, 꽤나 최근 서적에 속하기 때문에 얕게라도 최근 이슈가 된 기술들에 대해서 알고 싶거나, 스펙트럼을 넓히고 싶은데 전문 서적부터 읽기엔 부담스러운 분들이 짬짬이 읽으면 반드시 도움이 될 책이라고 생각한다.

(서평) 폴리글랏 프로그래밍

자바 덕후이신 임백준옹께서 서술하신 속칭 자바 시대의 종결 예언서다.

올해가 저물어 감을 감안했을 때, 대략 5년전쯤 쓰신 책이 2014년 초에 발간되었다고 봐야하는 책이라고 봤을 때, 국내에서는 5년여가 지난 지금도 자바 천국이다. 아마 10년은 앞으로도 그럴테고.

나 역시 C++을 비롯한 다른 언어들을 다양하게 다룸에도 불구하고, 결국엔 자바를 하게 되었다.

이 책에 대한 토의를 하게 되었을 때 자바 프로그래머분들이 극분하는 케이스를 많이 보았는데, 왜 그런지 잘 모르겠다.

세상의 모든 것은 자연스레 변화하고 그 중에서 IT는 더 빠르게 변화하는데 자바만 그대로라고 여긴걸까?

자바를 대체할 무언가의 습득, 혹은 병행이 그게 그렇게 두려운걸까?

안타깝게도 자바 개발자 자체는 충분히 많다.

그래서 자바만 쓸 줄 안다고 메리트가 있는 언어가 아니다. 너무나 많은 개발자가 한국어 처럼 자바를 쓰기에, 자바만으로 충분하지 않다.

훌륭한 자바 개발자가 부족한 것 뿐이다.

자바 언어 자체가 상대적으로 쉬운 언어에 속하기에 자바 언어를 오래 사용 해왔을 때의 특별한 무기가 있기 힘들다.

또한 사고의 폭은 언어의 영향을 크게 받는다.

대다수의 자바만 사용해온 프로그래머는 반쪽자리 자바의 Generic이 왜 반쪽인지 이해 못할 수 밖에 없다.

Partial, Extend가 대수라고? 그 생산성 차이는 어마 무시하고, OOP원칙을 깨지도 않는다.

나의 경우에는 Native 계열 언어인 C/C++로 시작했다 보니 Managed 계열 언어인 C#, Java등을 사용하며 코딩 난이도가 훨씬 낮아지는 행복감을 느꼈고, 파이썬, 루비등의 동적 언어를 사용하면서 꽤나 큰 혼란을 겪었다.

이런 경험이 축적되고 결론으로 도출 가능한 지점이 되니, 각 언어가 왜 이런 모양새를 띄고 이런 단점을 갖고 있는지 이해가 되기 시작했고 그 이해가 곧 인사이트로 연결된다.

C++ 개발자 중에서도 C++이 컨텐츠 개발언어에서 멀어지고 있을 때에도 현실을 부정하며 C++짱짱맨!! Native를 이길 수 있는 언어는 없다구! 하는 사람도 무척 많지만 (…) 자바도 만만치는 않은 것 같다. 아마도 주류였거나 주류인 언어를 사용하고 있다는 팩트가, 뒤쳐져 있지 않다는 것을 반증한다고 느끼는 것만 같다.

임백준 씨가 주장하듯, 나 역시 새로운 언어를 통해 자바를 조금 더 잘 사용하는 쪽으로 변화시키는 촉진재로서 이용하면 좋겠다.

확실히 인사이트가 넓어지는 데에 큰 도움을 준다.

이 자바의 발전 속도나 가능성에 대해서 악평을 함으로써, 책이 욕을 많이 먹을 수 있었음에도 임백준씨가 저자이셔서 반감될 정도의 내용이었지만 하고자 하는 메시지는 요즘 시대는 과거처럼 한가지 언어가 오랜 기간에 거쳐 전파되고 발전되고 있지 않음을 의미한다고 본다.

패키지 매니저가 일반화되고 기술 교류가 활발해지면서, 마이너한 언어로도 충분히 훌륭한 산출물을 많이 만들 수 있는 시대가 됐다.

그만큼 생산성이 어떤 의미인지, 효율성이 어떤 의미인지, 언어적 우아함이 어떤 의미인지 경험해보는 계기로 다양한 언어를 사용해보면 어떨까?

Python 사용기 - Airflow

파이썬을 업무적으로 다시 사용하게 될 계기가 생겼다.

Airflow를 사용하게 되면서, Airflow 스크립트 작성에 Python을 사용하게 됐는데, 그 과정에서 느낀 점을 말해보고자 한다.

Airflow에서 파이썬 스크립트를 사용한다기에, 매뉴얼을 보며, 샘플을 보며, 동료가 작성한 스크립트를 보며 적용하려 했다.

헌데 숨겨진 제약이 아주 많았는데, 그 제약 중에서는 참조 할 수 있는 인스턴스 변수가 달라지는 상황이 아주 많았다.

어라? 이런 상황은 C++이나 자바같은 복잡한 언어에서 있는 일 아닌가?

나 역시 이와 같은 편견을 가지고 있었는데, 그것이 정말 편견이었다.

라이브러리 가져다 쓰는 상황에서도 매뉴얼에 설명 되어 있지 않은 가정이 자주 존재하는데, 이는 동적 언어에서 발생했을 때 조금 더 크리티컬하다.

헌데 airflow는 한 술 더 떠서 등록해놓은 task (operator)를 불러주는 시점에 대한 런타임 디버깅을 모듈차원에서 지원하지 않는다.

Operator를 등록하는 과정까지만 디버깅을 지원하고, 이후의 과정은 개입할 수 없었다.

이 과정에서 두가지 모호한 포인트가 있었는데, 바로 어떤 코드가 operator 등록 시점의 코드이고, 어떤 코드가 operator가 동작하는 시점에서의 코드인지를 사용하면서 이해해야 했다.

단순히 디버깅이 지원 안되는 것도 크리티컬 하지만, 그럴 수 있다고 본다. 하지만 중요 로직을 작성해야 되는 지점이 callback이 불려 질 타이밍이라는 점, 해당 시점에서만 airflow가 제공해주는 환경 변수의 핵심인 task_instance 변수가 제공된다는 점이 크리티컬 했다.

아주 중요한 전제임에도 불구하고, 튜토리얼에서 중요하게 다뤄지지 못했다.

좋은 프레임워크는 큰 가정과 제약에 대해 잘 설명하는게 당연함에도, 오픈소스는 이게 부족한 경우가 많다.

정적 언어에 비해 이런 상황의 오류 발생률과 리스크는 훨씬 큰 편임에도 말이다.

흔히들 스크립트 언어를 흔히 쉽게 접하고, 쉽게 익숙해 질 것처럼 치부하지만 절대 그렇지 않다.

오히려 프로덕션 레벨에서 사용하기엔 훨씬 어려운 언어다.

정적 타입 언어가 수많은 예외 케이스나, 실수를 빌드 타임에 잡아준다는 것, 또한 성능상의 제약을 우회하기 쉽다는 것, 정적인 타입 제약 등으로 암묵적인 제약을 표현할 수 있고, 이에 대해서는 자연스레 매뉴얼에 반영되곤 한다는 점 등이 이를 반증한다.

동적 타입 언어가 가장 큰 리스크는, 데이터에 의해 동작이 달라질 때다. 가장 자주 겪는 문제가 인코딩 계열인데, 이런 문제가 항상 생기는게 아니라 특정 데이터 조건에 한해서만 생긴다는 것이 큰 리스크다.

내 경험상 안정적인 스크립트 셋을 만드는 건 꼼꼼하고 계획적인 사람들만 그렇게 했다. 추가로 내 경험상 그런 사람들의 비율은 한 팀에 10~30% 내외의 사람들이었다. 나머지 사람들은 스크립트 언어를 프로덕션에서 사용하기에 부적절하다는 의미다.

이를 위해선 배보다 배꼽이 더 클 수 있는 커버리지 확보를 정적언어보다 훨씬 더 많이 해야만 한다. 그래야 안정적인 스크립트 셋을 구축할 수 있다.

이 이야기를 왜 굳이했냐하면, 내가 여타 언어를 적응하면서 겪었던 고난보다 airflow가 가장 큰 고생을 시켰기 때문이다.

rails, django, flask, .net core, java spring boot, netty, akka 등…그 어떤 오픈소스도 이런 중요한 기본적(=핵심적)인 제약을 문서나, 튜토리얼, 예제등에서 가르쳐주지 않은 적이 없었다.

내가 놓쳤을 지언정 note나 warning 문구에서 충분히 설명하고 넘어갔다.

그래서 아직 incubating apache project겠지만 나도 오픈소스 작업을 하게되면서 이런 부분을 많이 신경써야겠다라는 생각도 같이 갖게 됐다.

결국 디버깅을 할 수 있도록 지원하는 mocking을 전방위적으로 구성하고, 커버리지를 위해 파이썬 코드를 전반적으로 스크립트셋을 구축하는 방법으로 마무리했다.

내가 작성한 파이썬 코드가 airflow 상에서만 테스트가 가능한 상태에서, 로컬에서의 독립적인 디버깅이 가능하도록 확장 작업을 했다.

결국 얘기가 돌았지만 하고자 하는 이야기의 핵심은 오픈소스에서는 airflow 만치 암묵적인 축약이 있는 경우가 많다. 하지만 콜백 호출시의 디버깅이 안되는 점과 파이썬이라는 동적언어를 사용한 점까지 물려서 복잡한 로직을 작성해야 하는 경우의 개발과 관리 코스트를 높여버렸다는 점이다.

다수의 다른팀의 사례는 Data Workflow로써 사용하던데, 다수의 팀은 디버깅이 필요할만큼의 복잡한 작업을 진행하지 않았고, 로직 코딩보다는 Bash Script를 대행하는 역할에 근접하게 사용했다고 한다. 그래서 Bash 파일을 독립적으로 잘 구성하고 순차적 Bash 파일을 호출함으로써 사용했다면 큰 문제는 없었을 것이다.

그럼에도 나는 airflow가 숨겨놓은 핵심 제약은 반드시 설명해야 하는 핵심 포인트이며, 이 제약이 어떤 의미를 가지고 어떠한 사용법으로써 사용하길 권고하는지 알려줘야 한다고 본다. 아니면 실행인자나 설정 파일을 통한 디버깅 환경을 위한 mocking을 제공하던지 말이다.

Java 적응기 05 - JPA

스프링을 쓰게되면서 DB 사용에서 메이저한 두가지 옵션이 존재했다.

바로 myBatis와 JPA.

JPA는 ORM 기반의 모델이고, myBatis와 iBatis는 전통적 ODBC, JDBC 방식의 쿼리 맵핑 방식을 기반으로 한다.

각기 기반 모델의 장단점도 여전히 유지가 된다.

ORM

  • 특징
    • 일반적 로직 코딩하듯이 코딩하면, 코딩에서 사용한 메소드에 맞게 백그라운드에서 데이터도 자연스레 처리됨.
  • 장점
    • 로직의 일부처럼 코딩하면 되므로, 직접 쿼리를 짤 필요가 없고, 별도의 DB 처리에 대한 지식, 프로세스가 요구되지 않아 학습 코스트도 낮다.
  • 단점
    • 사용법이나, 구조에 따라 급격히 DB 부하가 발생할 여지가 있으며, 이를 직관적으로 파악하기 어려움이 있다. 오브젝트 단위로 쿼리를 수행하므로, 필요하지 않은 값마저 조회 비용으로 사용하는 부적절함도 존재한다.

쿼리 매핑 방식

  • 특징
    • 쿼리의 결과를 메모리에 담아놓고 꺼내 쓸 수 있는 방식이 기본이지만, 편의성을 위해 이를 추상화하여 쿼리의 결과를 담을 수 있는 오브젝트와 함께 넘기면, 오브젝트에 데이터를 담아서 반환하는 방식으로 쓰인다.
  • 장점
    • 쿼리를 직접 사용하므로, 쿼리에 따른 연산 비용을 쉽게 추정할 수 있다.
    • 필요한 데이터만 조회해서 사용할 수 있으므로, 코스트가 더 낮게 사용 할 수 있다.
  • 단점
    • 쿼리마다 각기 다른 오브젝트를 생성 해 주어야 하며, 쿼리도 직접 작성 해야 하므로 작성해야 될 코드양이 늘어난다.

나는 ORM 기반 모델로, Entity Framework, Django, Node.js의 Sequelize, Ruby on rails 등을 사용했다. 그리고 JDBC와 유사 스펙인 ODBC를 기반으로 쿼리 매핑방식의 라이브러리를 구현해서 사용하기도 했다.

결론부터 말하자면 성능이 더 중요한 가치라면 myBatis, 생산성이 더 중요한 가치라면 JPA라고 봐도 무방하다.

다만 JPA에서도 쿼리 매핑 방식으로 사용 할 수 있기에 절충해서 사용한다면 단점도 극복 가능한 범주로 내려온다고도 볼 수 있다. 이 선택지에 myBatis를 적절히 결합해 사용하는 것도 방법이 될 수 있고.

특히나 로직 코딩의 복잡도가 크게 줄어드는 만큼 생산성이 꽤나 크게 높아짐을 알 수 있다.

파이썬과 루비나 쉽다지만, Django나 Ruby on Rails 없이는 지금의 인기를 누리기 쉽지 않았을 것이다.

그리고 위 두 킬러 앱에서의 핵심적인 메리트는 ORM과 웹 프레임워크의 결합을 통한 쉽고 빠르고 안정적인 생산성이 한 몫 했다고 밖에 볼 수 없다.

JPA도 여타 ORM처럼 쉬울 뿐 아니라, 어떻게 연관 관계와 코스트를 소모하는지를 Annotation 지정시에 옵션을 통해 알 수 있다.

객체 간의 관계에 맞게 Annotation을 지정하지 못하면 구동시나 사용시 오류가 발생하고, 이를 통해 DB 제약을 엄격하게 관리되고 있다는 느낌을 좀 더 강하게 받았다.

여지껏 설명한 다수의 기능과 장점이 여타 웹 프레임워크에도 유사하게 존재한다. (디테일의 차이는 좀 있지만) 한마디로 ORM 모델에 필요할 기능은 전부 다 있다.

다른 점은 성능, 튜닝 이슈도 많이 해소 되어있고 안정되어 있다는 점이 강점이었다.

언어적인 성능이 파이썬과 루비보다 월등히 좋으면서, 높은 생산성을 제공해 줄 수 있다는 점에서 장점이 있다고 생각한다.

동적 언어로 안정성을 갖추려면 갖춰야되는 커버리지가 정적 언어보다 훨씬 더 높게 요구 된다는 점까지 감안하면 훨씬 더 메리트 있는 가장 무난한 선택지가 아닌가 싶다.

다만 성능이 중요한 경우라면 JPA를 선택할 지라도 쿼리로 변환되었을 때의 계측도 동반되어야 한다는 것을 잊지 말자.