ha-ah

로그, 게으른 로그

Php_annotated_monthly 이미지

JetBrains에서 (거의) 매월 발행하는 PHP Annotated Monthly에서 적당히 제 입맛에 맞는 것만 추려 소개합니다. 언제나 그렇듯이 성급한 오역 죄송합니다.

이번 달은 내용이 많아 쪼개서 올리겠습니다. 우선 News & Releases!


PHP 7.3.0 released

http://php.net/releases/7_3_0.php

여기서 소개된 7.3의 특징으로는
• Flexible Heredoc and Nowdoc syntax RFC
• json_encode() and json_decode() function will be throwing exception in case of error and flag set RFC
• Trailing comma in functions calls RFC
• The new high-resolution monotonic timer function hrtime() PR
• New functions, array_key_first() and array_key_last() RFC
• Another new function is_countable() RFC
• Reference assignment in list() RFC
• Garbage collector improved PR
• Regexp engine updated to PCRE2 RFC

몇가지 편리한 기능도 환영할 만 하지만 benchmark tests가 인상적입니다. 벤치마크에 따라 7.2보다 살짝 높거나 10%까지 성능이 좋아졌어요.

PHP on AWS Lambda

https://aws.amazon.com/blogs/aws/new-for-aws-lambda-use-any-programming-language-and-share-common-components/

AWS re:Invent 2018 conference에서 좋은 소식이 들려왔습니다. 이제 AWS Lambda에서도 PHP를 쓰기 위해 우회(https://medium.com/@stephenheron/serverless-php-9da3f00df5de)하지 않아도 정식으로 쓸 수 있게 됐습니다. Lambda Runtime API를 사용하면 된다고 하는데, stackery/php-lambda-layer를 통해 만들거나 직접 만들 수도 있다고 합니다. 정확히 어떻게 돌아가는 지는 좀 더 알아봐야겠습니다.

Rasmus Lerdorf가 남긴 글도 소개가 됐네요.

3rd question about severless PHP in as many days. There is no such thing as serverless from the PHP perspective. It’s just a different deploy strategy and provider billing model. There are still servers running your PHP code.

PHP 관점에선 serverless 같은 건 없다는 이야기인데요. PHP 코드 정도 돌리는 서버는 이미 충분하다는 뜻으로 풀이됩니다.(맞죠??)

PHP Versions Stats 2018.2 Edition

https://blog.packagist.com/php-versions-stats-2018-2-edition/

Composer가 설치될 때 User-Agent 헤더를 통해 PHP 버전을 전달하는데, 이를 1년에 두번씩 통계로 뽑아낸 보고서입니다. 무섭게들 업데이트 하고 있습니다. 아직 5버전을 쓰고 있다면 당장, 7.0을 쓰고 있다면 올 해 안으로 버전업 계획을 잡는 게 좋겠습니다.

HTTP/3 over QUIC

https://daniel.haxx.se/blog/2018/11/11/http-3/

PHP와는 직접적으로 관련은 없지만 새로운 HTTP 표준이 탄생(renamed)했습니다.

이제 HTTP2를 도입할 때입니다, 여러분.
i guess we should start looking at HTTP2 then

Symfony leaves PHP-FIG

https://github.com/php-fig/fig-standards/pull/1120/files

Symfony의 리더인 Fabien Potencier가 PHP-FIG의 Member Projects 목록에서 스스로를 지워버렸다고 합니다. 2년 전에도 Laravel, Propel, Doctrine, Guzzle, Stash, Aura도 이미 떠났다고 하는군요.

이와 같은 맥락에 있는 2014년에 Anthony Ferrara가 쓴 open letter to PHP-FIG도 소개가 됐습니다.

이것 만으로는 떠난 이유가 잘 납득이 되지 않아 Fabien Potencier의 트윗을 좀 더 읽어봤는데요. 여기 보면 이런 말이 나옵니다.

PHP-FIG is not about interoperability anymore, it’s about creating an opinionated framework, a framework by committee…

더이상 상호운용성을 위한 것이 아니라 위원회 중심으로 하나의 큰 프레임웍을 만드는 것 같다는 이야기입니다. 여기에는 PSR은 단지 Recommendations일 뿐이라는 리트윗도 꽤 많이 보이는군요.

NPM dependency hell: comparison with Symfony, Laravel, and API Platform

https://dunglas.fr/2018/11/about-the-dependencies-of-symfony/

몰랐는데 얼마 전 NPM 진영에서 또 사고가 났었나 보군요.

NPM이 왜 이렇게 취약한지 PHP 프레임웍과 비교한 내용인데, 별로 재미는 없어서 마지막 결론만 언급하겠습니다. 우리도 조심하자!

PHP security vulnerabilities monitoring에서 테스트 해보아요.

updated : 2019.09.07

최종안이 아래와 같은데,

Client -> NLB -> Proxy 서버군 -> EB

AWS에 계신 분과 이야기를 하면서 Proxy 서버군 대신 ALB를 붙이는 것이 더 좋을 것이라는 이야기를 들었고, 이게 가능할지 테스트를 해보려 했다.

그러나 ALB로 직접 연결할 방법이 딱히 보이지 않아서 검색을 해봤다.

https://stackoverflow.com/questions/50981864/aws-pass-traffic-from-nlb-to-an-alb

The problem is that Application Load Balancers can scale up, out, in, and/or down

여기 나온 것처럼, NLB와 ALB를 직접 연결할 수는 있으나 IP로 연결 해야 한다.
그러나 ALB의 특성 상 IP는 계속 변할 여지가 많기 때문에, 람다를 통해 계속 NLB가 바라보는 ALB의 IP를 바꿔줘야 한다.

그 방법은 여기 잘 나와있다.
https://aws.amazon.com/ko/blogs/networking-and-content-delivery/using-static-ip-addresses-for-application-load-balancers/

AWS 측에서 공식적으로 제안하는 방법이라고 보면 되겠다.

지금 구성을 고쳐서 이 방식으로 갈아치울 정도로 관리가 편해 보이진 않는다. 다른 곳에서 비슷한 요구를 해 온다면 그때는 이 방식이 훨씬 좋을 수 있다. 다만 IP가 변하는 상황에서 서비스가 안정적으로 유지될 지는 문서를 더 읽어보고 판단해야할 듯 하다.


이미 정답(혹은 더 좋은 방안)을 알고 계신 분들이라면 답답스럽겠지만 온통 혼란스러웠던 3일을 회고해본다. 그 동안 서버란 서버팀에 맡기는 게 당연한 회사를 다녔으므로 서버를 관리할 일도 거의 없었거니와 올 해 백엔드 개발자로 전향한 뒤에도 경험 많은 동료들만 믿고 인프라 관리는 좀처럼 내 일처럼 달려들지 못했다는 점을 고백하고 시작해야겠다.

Show me the IP

모 대기업과 신규 연동을 진행하는데, 상용 오픈을 일주일 남겨두고 방화벽 이야기가 나왔다. 그쪽에서 우리쪽으로 찌르는 request 밖에 없는데, 우리 서버 IP(혹은 대역)을 문의하는 것이었다. 계열사 모두가 같은 정책을 유지하는데, 외부 API로 요청을 보낼 때도 특정 IP나 대역을 지정해야만 한다는 것이다.

이전에도 몇몇 기업이 IP 대역을 문의하긴 했다. 그땐 우리가 그쪽 서버로 쏘는 상황이었고, 우리는 자동으로 스케일링 되는 환경이라 IP를 정해놓을 수 없다고 알려주곤 했었다 - 이것도 뒤에 얘기할텐데, 이 역시 가능하긴 하다.

AWS에선 고정 IP를 제공하거나 낭비하는 것에 매우 깐깐하기도 하고, Elastic Beanstalk같은 완전관리형 솔루션은 도메인이나 리소스 이름으로 관리되고 있었다. 그도 그럴 것이, 블루/그린 배포를 한다거나 EB에서 내부적으로 관리하는 로드발란서 같은 놈이 죽으면 새로 띄워 갈아끼워야 하니까 말이다 - EC2 DNS Resolution 문제가 발생하면 망하는 거지만.

어쨌든 계열사 모두가 같은 정책을 유지한다고 하니 양사 간 협의가 필요한 상황까지 왔다. PO를 통해 서로의 상황을 알아보고 각자 나름의 방법을 찾아보기로 했다. 난 순수한 뇌의 철없는 개발자로서, 비지니스 관점에서 우리가 얼마나 양보를 해야할 지도 몰랐고, 온-프레미스가 지배하던 시대의 방식 그대로 고정 IP로 인프라를 관리하는 건 너무 옛스럽고, AWS에 인프라를 구축한 이상 가능하면 아마존의 방식으로, 아마존이 유도하는 대로 구성하는 것이 더 나은 방향이라고 생각도 했었다. 보통의 경우 괜찮은 관점이라고 생각한다.

CTO님과 이야길 해보면서 이런 정책 차이로 사업을 엎어버릴 수도 없는 노릇이고, 기술적인 문제는 우리가 풀어야 한다는 이야기를 했다. 당연한 말인데, 아차 싶은 지점이 있었다. 나는 ‘개발자가 못한다는 소리를 한다는 건 쪽팔린 일이다’라는 생각을 한번도 해본 적은 없기 때문에(하지만 겉으로 꼰대짓을 했을 수는 있다), 해결하지 못한 것에 부끄러웠던 것은 아니었다. 다만 지금 벌어진 일이 ‘우리의 문제’라는 인식을 못했다는 반성을 했다. 그러니까, ‘정책 차이로 발생한 문제는 다른 사람들이 풀어낼 수 있고 난 죄가 없다’라고 속 편하게 앉아 있었던 것은 아니었을까. 물론 여전히 저쪽이 정책을 좀 수정했으면 하는 마음은 굴뚝같지만, 우리 입장에서의 다양한 해결책을 마련해놓긴 해야한다는 생각이 들었다. 그 비용이 산정되어야 그 ‘다른 사람들’이 외부에서 협의를 해오실 테니까.

무엇보다, 가능한 해결책이 당연히 있었다. 고정 IP를 사용하는 EC2를 올려서 서비스하면 된다. 다만 지금까지 우리가 만들어온 배포/관리 프로세스나 노하우가 분산되고 안정성을 확보할 수 없다는 점 때문에 죽어도 하기 싫은(죽으면 못하긴 하지) 방식이긴 했다.

방안

논의된 이후 남은 시간은 열흘. 위에 언급한 최악의 방식이든 새로 찾을 방식이든 다음 주 월요일에는 인프라 구성을 시작해야 한다는 것에 합의하고, 이틀정도 좋은 해결안을 찾아보기로 했다. 인프라에는 잼병인 내가 풀어야 할 숙제가 꽤나 무겁게 느껴졌는데, 서버 좀 만져보신 분들께 계속 물어보면서 몇가지 방안으로 압축되었다.

1안. Load Balancer 설정으로 해결

Auto Scaling Group에 Load Balancer를 추가로 붙일 수 있는지 검토

  • 어쨌든 AWS의 서비스를 정상적으로 이용하는 방법

이 방법은 대충 키워드만 줏어 들은 방법인데 정확히 어떤 아이디어인지는 잘 모르겠고 조금 찾아보다 NLB쪽으로 방향을 선회하며 더이상 깊이 들어가지 않았다.

2안 Proxy 서버 운영

Client -> Proxy 서버 -> EB의 단계로 구성

  • Proxy 서버에서 EB의 domain으로 접근
  • 프록시 서버의 안정성을 확보할 방안 필요

결론적으로 이 방식을 택하긴 했는데, 뒤에 나올 내용과 조합해서 다시 정리해보겠다.

3안 별도의 환경 구성

Elastic Beanstalk을 사용하는 방법 대신에 EIP를 붙인 인스턴스를 띄우고 서비스하는 방식. 특정 client를 위한 별도의 서버 구성/배포 프로세스 만드는 것도 부담이고, 아래 이유로 최대한 방어해야 하지만, 마땅한 해결책이 없을 경우 바로 구성 시작하기로 합의했다. 하기 싫지만 확실히 가능한 최후의 방법이었다.

  • 배포 프로세스 분산에 따른 업무 부담
  • 환경 변수 등 관리 부담
  • 검증 안된 서비스 구성이지만 바로 운영에 들어가야 함

그런데 또 다른 분이 팁을 주시기를 single-instance scaling group 생성해서 EIP 배정하는 방법도 있다고 하셨다 - 꼭 인스턴스 하나만 넣어야 하는 건 아니고, 제한된 인스턴스로 고정 시켜놓는 것. 이미 현재도 동일한 소스가 올라가는 scaling group이 셋이 있다. API 서버용(scaling 범위가 2대에서 수십대까지), cron용(1대), queue work용(2~4대).

여기에 고정 아이피 접근 용으로 scaling group을 하나 만들어서 내부 EC2 인스턴스에 EIP를 할당하는 방법이다. 이렇게 되면 배포 과정은 동일하게 유지하면서 몇몇 client를 위한 별도 구성을 제공할 수 있다. 다만 이런 요구를 하는 클라이언트가 늘어나면 EIP를 붙인 인스턴스가 늘어나게 될 것이고, scale-out 해야할 상황에는 인스턴스를 확보하고 IP를 추가로 알려줘야 한다. 즉, 최대 사용량을 기준으로 인스턴스를 유지해야 한다는 말인데, 아무래도 (특별한 관리가 없다면) 유휴 자원이 늘어나고 비용이 증가할 것이다.

또한 EIP에 연결된 인스턴스 상태가 안 좋아서 종료하는 경우, 새 인스턴스를 띄운 후 EIP에 다시 연결하는 과정이 필요하다.

4안 NLB를 붙이고 non-TLS(http로만) 접근하기

검색을 하다가 1년 전 NLB(Network Load Balancer)가 출시되었다는 사실도 알게 되었다. Elastic Beanstalk에도 붙일 수 있었는데, 현재 우리 서비스에는 Classic Load Balancer를 사용하고 있다. 이를 적용하자면 Blue/Green 배포를 통해 Load Balancer를 교체해야만 하고, 이에 따른 사이드 이펙트는 어떤 게 있을지 찾아보기도 해야 한다.

AWS 한국 유저그룹 등 검색을 통해 얼마나 쓸모 있을지, 우리 상황에 맞을지 확인해봤다. 몇가지 기억해 둘 만한 내용은 이렇다.

NLB는 subnet 별로 1개이고 HA구성은 내부적으로 되어 있는 것으로 알고 있습니다. 하지만 subnet 장애로 인한 문제를 해결하려면 Route53에서 Health check를 통해서 해결해야 하는것으로 알고 있습니다.

작년 AWS re:invent 세션 중에 자세하게 설명된 부분이 있네요. AZ 마다 Static IP가 나오니깐 그걸 Route53 health check로 Failover 하는 식인 듯 해요.
-https://www.youtube.com/watch?v=z0FBGIT1Ub4&t=1684s

옙. 그리고 DSR처럼 작동하니 기존 Proxy모드였던 CLB, ALB와 차이점을 인지하셔야 합니다.

  • 고정 IP를 지원하는 Network Load Balancer(ELB) 발표“ 참고
  • Client 요청이 백엔드에 전달될 때 Client IP 그대로 들어오므로 X-Forwarded-for 등의 부가 헤더 불필요
  • NLB 앞단에는 Security Group을 배치할 수 없으며, 따라서 관련 방화벽 정책은 백엔드의 Security Group단에서 제어해야 함

NLB의 Target Group에 매핑된 EC2가 인터넷 구간에서 요청하는 Client에 반드시 도달할 수 있는 구조여야 합니다.

위에 언급한 “고정 IP를 지원하는 Network Load Balancer(ELB) 발표“에서 깔끔하게 정리를 해주셔서 무척 도움이 많이 됐다. Elastic Beanstalk에서 사용할 수 있는 세가지 Load Balancer를 비교해주기도 하신다.

문제는 기존 환경에서 TLS를 구성할 때 환경 로드 밸런서로 서버 인증서를 할당하는 방식을 사용한다는 점인데, TLS 레이어를 Load Balancer가 제공하고 이 뒤에 있는 인스턴스와는 http 통신을 하게 된다. 이를 NLB로 바꿀 경우, NLB 뒤에 인증을 담당할 레이어를 더 붙여야 한다. 혹은 http 통신만 가능하도록 구성해야 한다.

그러나 이미 https로 연동된 업체도 있거니와 내년이면 모두 https 접근만 허용하도록 정책이 바뀌어 갈 예정이므로, 당장 오픈 해야하는 상황에 따른 미봉책이 필요할 경우에만 고려해야 한다. 그것도 기존 환경을 바꾸기 보다는 고정 IP로 들어와야 하는 업체를 위한 별도의 환경을 구성할 경우나 가능하다.

오픈이 얼마 남지 않았고 기존 서비스에 최대한 영향을 주지 않기를 바랐기 때문에 이 방식도 패스.

최종안

static-ip-eb-stack images

Client -> NLB -> Proxy 서버군 -> EB

NLB는 Load Balancer가 살아있는 동안(교체되지 않는 이상) static IP를 지원한다. NLB는 multi AZ에 걸쳐 고정된 IP를 만들어주는데, Route53에서 고정IP용 도메인을 생성하고 이 두 IP를 A record값에 모두 입력한다.

NLB 뒤에는 Proxy로 사용할 인스턴스 4대(모니터링 하면서 적절하게 조정할 예정)를 띄우고, NLB에서 바라볼 대상 그룹으로 묶어준다. 클라이언트와의 TLS 통신은 이 Nginx 서버에서 진행하게 된다. 때문에 인증서를 급하게 하나 구입하게 됐다 - 기존에는 AWS에서 제공하는 것만 썼기에.

NginX에서는 클라이언트에서 온 요청을 그대로 전달하는데, Elastic Beanstalk에 도메인 기반의 HTTP로 통신하고 클라이언트에 결과를 돌려준다. 클라이언트로 response가 돌아갈 때는 NLB를 거치지 않고 NginX에서 바로 돌아나간다.

참고로 이 과정에서의 Network Load Balancer가 어떻게 동작 하는지는 최신 네트워크 로드 밸런싱 및 프록시 소개와 같은 글에서 좀 더 깊이 있게 확인할 수 있다.

무엇보다도 이 방식이 마음에 들었던 것은, 프록시 레이어만 하나 추가함으로써 기존에 구성된 인프라를 전혀 건드릴 필요가 없다는 점이었다.

앞으로

이번에는 없었지만, 우리 서버에서 외부로 request하는 상황도 발생할 수 있다. 그들의 서버에 접근할 때 고정 IP/대역을 원할 것이다. 이미 그걸 원했던 업체가 종종 있기도 했다. 이번에 공부하면서 NAT Gateway를 쓰면 쉽게 된다는 걸 알았지만, 이걸 붙이면 어떤 영향이 있을지는 아직 연구가 부족하다. inbound든 outbound든 static IP로 통신해야 하는 서비스를 별도의 하나의 그룹으로 묶을지는 나중에 더 고민해보기로.

이번에 추가한 프록시 서버들을 어떻게 운용할지는 여전히 남은 숙제다. 현재의 프록시 구성이 적당한 지 판달할 만큼 충분한 트래픽을 갖기까지는 한참이나 기다려봐야 할 것이다.

아직 상용 서비스를 시작하진 않았는데, 이 글이 사라졌다면 뭔가 문제가 생겨서 실패했기 때문일 것이다.

마무리

내가 다 고민한 것처럼 써놨지만, 초기부터 중간 중간 열심히 같이 고민해준 동료가 많았다. 나는 처음에만 이런 저런 검토를 한 것 이외에는 사실상 모든 세팅은 사내 인프라 전문가께서 맡아 처리해주셨다. 한 게 없으니 블로그 정리라도 한다. 문제를 해결해야 한다는 부담도 분명 있었지만, 종일 하나의 문제에만 집중할 수 있어서 꽤나 즐거웠던 기억으로 남았다 - 해결이 됐으니까 즐거운 기억으로 남았지.

간만에 생활코딩 하나.

아이가 다니는 유치원이 문을 닫는다고 해서 혹시나 아이들 활동 사진을 올려주는 카페도 닫을까봐 부랴부랴 크롤러를 만들기 시작했다. 지금은 내년 2월까지는 운영하기로 합의된 상태지만.

사실 올 해 중순 쯤부터 생각했던 건데, 우리뿐 아니라 딸아이 친구들네도 받을 수 있게 웹 인터페이스로 제공하고 싶었다. AWS에다가 내가 여전히 잘 모르는 인증을 붙여보고 누구든 자기 카페의 목록을 확인하고 그 안의 이미지를 받게 하면 되겠다는 생각이었다. 갑자기 문을 닫는다니 시간이 없어서 시도도 안해보고 다음 단계로 넘어갔다. 어차피 네이버 카페는 여전히 가입과 글 등록 이외의 API는 제공하지 않아서 크롤링을 하긴 해야 한다.

이때 가장 중요한 건,

  • 빨리 만들어야 한다
  • 손으로 일일이 다운로드 받는 것보다는 빨라야 한다(당시 사진이 1,000장에서 2,000장 쯤 되겠지라고 생각했기에 가능한 조건이랄까)

Laravel Dusk

급한대로 시도한 것은 standalone ChromeDriver를 사용하는 Laravel Dusk. 라라벨을 설치하고, Dusk도 추가.

composer create-project --prefer-dist laravel/laravel crawlincafe
git init
composer require --dev laravel/dusk:"^2.0"
php artisan dusk:install

APP_URL을 네이버로 해주고

APP_URL=https://cafe.naver.com

dusk install할 때 넣어주는 샘플 테스트를 돌려본다

❯ php artisan dusk
PHPUnit 6.5.13 by Sebastian Bergmann and contributors.

. 1 / 1 (100%)

Time: 2.08 seconds, Memory: 12.00MB

OK (1 test, 1 assertion)

유저 정보는 .env에 추가

USER_ID=네이버아이디
USER_PW=비밀번호

페이지 번호에 링크가 있으므로 페이징은 문제 없을 것 같고, 우선 로그인 후 원하는 페이지로 이동하는 실험을 해봤는데,

<?php

namespace Tests\Browser;

use Tests\DuskTestCase;
use Laravel\Dusk\Browser;

class ExampleTest extends DuskTestCase
{
/**
* @throws \Throwable
*/
public function testBasicExample()
{
$this->browse(function (Browser $browser) {
$userId = env('USER_ID');
$userPw = env('USER_PW');
$cafeId = env('CAFE_ID');

$browser
//Visit
->visit('https://nid.naver.com/nidlogin.login?mode=form&url=https%3A%2F%2Fcafe.naver.com%2F...')//유치원 카페 URL이 보여서 생략
->assertSee('NAVER')
->assertSee('로그인 상태 유지')
//Login
->type('id', $userId)
->type('pw', $userPw)
->press('.login_form input[type=submit]')
->pause(5000)
->assertPathIs("/{$cafeId}")
;
});
}
}

결과는,

실패한 스크린샷

이게 뭐야!

아마도 최근에 자동입력 방지 기능이 추가가 됐던 것 같다. 찾아보니 올해 여름쯤부터 나처럼 당황하신 분들이 여럿 보인다. pause를 주기도 하고, 여기저기 쓸데없는 클릭도 만들어보고, 마우스 drag 이벤트도 줘보고 했는데 잘 뚤리지 않아 빠른 포기.

역시 음식은 손맛

다시 분석을 시작했다. 이미지 URL만 있으면 별다른 인증없이 다운로드가 가능할까? 맞다. 이미지가 포함된 게시물까지 접근하는 게 문제지 이미지 URL만 확보되면 다운로드는 되는 거다. 그런데 PC버전의 경우, 아래와 같이 이미지 썸네일을 캔버스에 그려놓고 클릭을 하면 사진을 크게 보여주는 구조다.

네이버 카페 PC 화면

엄청 불편하다. 그래서 모바일 버전으로 접근해서 URL을 수집하기로 했다.

2017년에는 5세반이라서 그런지 선생님이 정말 많이 올려주셨다. 총 80회(선생님 고맙습니다). 올해 6세반은 다 안 올라왔지만 졸업까지 약 40회 정도 올라올 것 같다. 회당 100장에서 400장 사이로 양이 엄청 많다. 난 도대체 왜 2천장이 안될 거라 생각했던가!

개발자도구를 열어놓고, 게시물 120건을 돌아다니며 이미지 URL을 수집했다. 수집하는 스크립트는,

(function(){

let result = {
"title" : document.querySelectorAll('#ct h2.tit')[0].innerText.replace(/[^0-9a-zAZㄱ-힣]/g, '_').replace(/__/g, '_').replace(/^_(.+)_$/, "$1"),
"createdAt" : document.querySelectorAll('#ct span.date')[0].innerText.replace(/[^0-9]/g, ''),
"data" : [
//image urls
]
};

document.querySelectorAll('#postContent img.fx').forEach(function (item) {
result.data.push(item.src);
});

console.log(JSON.stringify(result));
})();

콘솔에 output할 양이 너무 많으면 콘솔 화면에 Copy 버튼이 생긴다.

콘솔에서 실행한 화면

다음 글로 이동 -> 개발자도구 클릭 -> 화살표 up key + enter -> Copy 버튼 클릭 Editor에 붙여넣기의 과정으로 120개 글에서 노가다를 좀 해줬다. 사실 중간에 한번 실수로 지워버린 바람에 160번은 한 것 같다.

더 쉬운 방법이 있진 않았을까 고민을 하긴 했었는데 당장 생각이 안나 머리를 덜 쓰는 방법을 택한 것. 목록 화면에서 개발자도구로 상세 화면을 불러와서 파싱해도 되지 않았을까 싶긴 한데. 이미 지난 일이니…

이걸 모아서 Guzzle로 다운로드 받는 프로그램을 후다닥 작성했다. 코드리뷰 해주실 필요는 없다. 유지보수 할 일 없고 빠르게 유용하게 잘 만들었으니 됐다.

<?php
define('PROJECT_ROOT', '..');

require '../vendor/autoload.php';

use GuzzleHttp\Client;

$targetDir = 'storage/data';
$downloadDir = 'storage/downloads';

/////////////////////////////////////// read file

if ($handle = opendir(PROJECT_ROOT . '/' . $targetDir)) {

$data = [];

//read sub dir
while (false !== ($subDir = readdir($handle))) {
if (strpos($subDir, '.') === 0) {
continue;
}

$subDirPath = PROJECT_ROOT . '/' . $targetDir . '/' . $subDir;

//read files

if ($handleSub = opendir($subDirPath)) {

$data[$subDir] = [];

while (false !== ($file = readdir($handleSub))) {
if (strpos($file, '.') === 0) {
continue;
}

if (preg_replace('/.+\.([a-z]+)$/', '$1', $file) !== 'js') {
continue;
}

$fileTxt = file_get_contents($subDirPath . '/' . $file);
try {
$article = json_decode($fileTxt, true);
} catch (Exception $e) {
echo 'json decode failed : ' . $subDirPath . '/' . $file;
continue;
}
if (!empty($article)) {
$data[$subDir][$article['createdAt']] = $article;
}
}
closedir($handleSub);
}
}
closedir($handle);
}

////////////////////////////////////// download

$client = new Client([
// 'timeout' => 2.0,
]);

foreach ($data as $subDir => $articles) {

//make sub directory
$subDirPath = PROJECT_ROOT . '/' . $downloadDir . '/' . $subDir;
if (!is_dir($subDirPath)) {
mkdir($subDirPath);
}

foreach ($articles as $createdAt => $article) {

//make sub directory
$articleDirPath = PROJECT_ROOT . '/' . $downloadDir . '/' . $subDir . '/' . $article['createdAt'] . ' - ' . $article['title'];
if (!is_dir($articleDirPath)) {
mkdir($articleDirPath);
}

echo $articleDirPath . PHP_EOL;

foreach ($article['data'] as $index => $imageUrl) {
$filename = str_pad($index, 3, "0", STR_PAD_LEFT) . '.jpg';
if (file_exists($articleDirPath . '/' . $filename)) {
continue;
}
try {
$client->request('GET', $imageUrl, ['sink' => $articleDirPath . '/' . $filename]);
} catch (Exception $e) {
echo PHP_EOL . $e->getMessage() . PHP_EOL;
}
echo '.';
usleep(100);
}
echo PHP_EOL;
}
}

대체 뭐가 문제야

대체 뭐가 문제야 표지 이미지

Are Your Lights On?

제럴드 와인버그 선생의 대체 뭐가 문제야 개정판을 샀다. 마침 가방없이 교보문고에 간 날이었고, 마침 이 책이 외투 주머니에 쏙 들어갈 정도였고, 마침 와인버그 선생이 돌아가신 지 얼마 안 되기도 했다.

극과 극의 평을 받는다고는 했으나 나는 꽤 좋았다. 특히 첫 장의 몰입감이 좋았는데, 뒤로 갈 수로 맥이 풀리기도 한다.

"문제란 바라는 것과 인식하는 것 간의 차이다."

"누구의 문제인가?"

"정말로 무엇이 문제인가?"

우리가 문제로 인식하는 것이 진짜 문제인지, 그게 누구의 문제인지, 그런데 답을 내면 그게 답이 맞는지…결국 돌고 돌아 아무 것도 아닌 책이기도 하지만, 그 과정에서 이런 저런 생각을 해볼 수 있어서 좋았다. 특히 책을 읽고 얼마 후에 동료 개발자와 고민을 하고 의견을 나눈 뒤 다른 개발자와 이야기를 하는 도중 그 개발자가 문제를 없애준 경험을 겪고 보니, 역시 나는 문제를 보는 눈이 없구나 싶기도 했다.

또 읽다보니 와인버그 선생의 테크니컬 리더를 관통하는 주제이기도 하다는 생각이 들었다. 물론 내가 오해를 했거나 오래전에 읽어서 기억이 가물거릴 순 있지만, 난 그 책이 서로 소통을 제대로 하고 있는지, 문제를 해결해야 할 사람이 누군지를 끊임없이 이야기 해준다고 생각을 했다 - 그것만 기억에 남은 것일 수도 있다.

어쨌든 역시나 고민을 던져주는 책인데, 그래도 짧은 시간 한가지 주제로만 머리 아프게 해주니 고맙기도 하고, 남에게 추천하기는 또 애매하기도 한데, 누구든 빌려달라면 빌려주리라.

조엘 온 소프트웨어

조엘 온 소프트웨어 표지 이미지

오래전에 봤으면 내가 좋아했을 법한 스타일인데, 워낙 옛스러운 탓에 큰 감동은 없었더랬다. 이미 이 책에 영향받은 사람들이 수많은 책과 블로그를 썼고, 이 사람의 철학이 이 직군 전반에 녹아들었다고 생각된다. 작가도 재미있게 글을 쓰는 사람인데다 번역가도 좋아하는 사람이지만, 중간중간 번역가가 추가한 내용에 깜짝깜짝 놀라곤 했다. 아무리 블로그 모음집이라 해도 어느정도 흐름을 고려한 편집이었기에 그 사이에 뭘 넣는 것이 어째 마뜩찮았고, 예전 PC 통신 시절의 감성을 느끼게 해줬다. 딱 그 시기이기도 하고.

나도 이럴진대, 30대의 어린 친구들이라면 조엘 이후에 (어쩌면 그에게 영향을 받은 것일 수도 있는) 폴 그레이엄의 해커와 화가, 제프 앳우드의 코딩 호러의 이펙티브 프로그래밍 등의 글을 읽는 것이 좀 더 와 닿을 수도 있겠다. 그 친구들이라면 이 사람들도 할배라고 하려나?

고전은 고전이라 좋은 글이고 좋은 관점이지만 아주 재미가 있었다고는 말하긴 힘들다. 똑똑하게 재밌는 할아버지였다.

요리는 화학이다

요리는 화학이다 표지 이미지

확실히 성공하기 위한 70여 개 레시피의 모든 비밀과 해독

부제는 요란하지만 여러모로 애매한 책이다. 아직 (어떤 분은 재밌게 읽었다는) 달걀 부분을 읽지 않은 채로 쓴다.

yes24의 독자 서평은 칭찬 일색이지만(총 리뷰가 얼마 안되긴 하다), 교보문고에는 공감가는 서평과 이해 안되는 서평이 공존한다. 내가 책을 읽고 난 뒤에 서평을 다시 찾아보기 시작했다는 것은 엄청 좋았거나 (대부분은) 워낙 이상해서다.

좋은 점은 화학적 지식을 배경으로 우리가 일상적으로 하는 실수들을 지적해준다는 점이다. 예를 들어, 소금과 후추를 뿌려야 하는 타이밍 같은 것. 때론 그런 것이 너무 미묘해서 나같은 미물에겐 큰 차이가 없어보이는 경우도 있지만, 어쨌든 과학적인 접근을 했다는 점은 좋았다. 백종원 등 여러 사람이 이야기하는 고기를 이렇게 구우면 육즙을 가두게 되죠 같은 이야기도 왜 문제인지 알 수 있다. 그런데 그런 과학적인 배경을 설명하는 분량이 적기도 하고 뒤로가선 대충 설명하는 기분이 든다.

프랑스 작가니까 프랑스에서나 먹을 수 있는 레시피와 재료가 들어간 건 이해할 만 하다. 내가 어릴 적부터 프랑스 코미디 영화를 볼 때마다 느끼는 감정이 이 책에서도 고스란히 드러난다. 정말 프랑스의 유머 감각은 남다르다. 프랑스 영화에서 흔히 보이는 것처럼 갸날픈(확인된 바 없음) 백인(확인된 바 없음) 게이(확인된 바 없음) 청년(확인된 바 없음)의 섬세한 말투와 유머와 몸짓이 책 곳곳에서 느껴진다. 후추를 먼저 쳤다가는 내 팔을 꼬집을 것 같다. 역시 프랑스 사람들은 재미없다. - 너무 혐오 발언을 쏟아냈나? 난 갸날픈 백인 프랑스 게이 청년을 혐오하진 않는다. 그냥 이 책이 좀…

또 하나의 문제는 번역인데, 작가가 원래부터 이상한 말을 쏟아낸 게 아니라면 번역이 심각하다. 찾아보니 유명한 프랑스 요리 강사님인 것 같다. 번역이 좋았다는 사람은 도대체… 해박한 지식이 있어야 가능한 번역이긴 하지만, 글을 잘 쓰는 것과는 또 다른 문제니까. 어쩌면 출판사(도림북스)를 비난해야 정당한 일일 지도 모르겠다.

마지막으로 책이 모두 그림으로만 이뤄져서 참 이쁜데, 이걸 레시피로 참고하기에는 참 어렵다. 새우머리와 껍질이 좀 남아서 비스크를 실험한다고 따라해봤는데, 난 비스크를 본 적도 없으니 모두지 내가 잘 하고 있는지도 모르겠고, 색깔이 하도 더럽게 나와 아내가 인상을 찌푸리며 “아니, 색이 왜 이래요?”라고 놀라고, 겨우 겨우 설득해 맛은 보게 했지만 다시는 먹고 싶지 않아 했다. 맛은 나쁘지 않으나 나도 좀 떠 먹다 버렸다. 이 실패는 지식이 부족한 내가 재료를 잘못 넣은 탓이긴 하지만, 원래 어떤 모양과 색인지 알 수 없어 레시피 책으로써는 부족하다. 프랑스 요리 경험이 있는 사람이 더 잘 만들기 위해 참고하면 좋을 책이라고 본다.

Php_annotated_monthly 이미지

JetBrains에서 제공하는 PHP Annotated Monthly라는 (거의) 매월 발행되는 블로그가 있어 소개 드리려고 합니다.

이 중에서 몇 가지 제 취향껏 골라 그 안의 내용도 좀 뒤져보고 개발새발 번역해서 소개합니다.

지난 September 2018 소식지는 페이스북 그룹에 바로 올렸더니 너무 보기 안 좋아서(이렇게…), 제 블로그에 옮겨봤습니다.


The future of Zend Engine and Zend Framework

http://zsuraski.blogspot.com/2018/10/the-future-of-zend-engine-and-zend.html

— Zeev Suraski in his blog announced that he’ll be leaving Rogue Wave, which acquired Zend company in 2015. Matthew Weier O’Phinney and Enrico Zimuel, who work on Zend Framework, Zend Expressive, Apigility, as well as Dmitry Stogov, the author of PHPNG, are also leaving.
Stefan Priebsch posted an interesting analysis of possible consequences to the PHP ecosystem.

Dmitry Stogov, Matthew Weier O’Phinney, Enrico Zimuel와 같은 사람들이 Zend를 인수한 Rogue Wave software를 떠난다는 소식입니다. 회사의 방향과 맞지 않음을 은근 내비친 것 같은데, 계속 PHP 생태계에 공헌을 하고 싶으니 관심있는 사람 연락하라는 소식입니다.

Stefan Priebsch라는 사람이 쓴 글도 소개하고 있습니다. Zend의 미래라는 글입니다.

  • Zend를 인수한 이후에도 계속 장사가 안됐고, 그들이 만든 솔루션은 인기도 없었다
  • Zend가 Dmitry Stogov에게 돈을 주고 이만큼 발전시킨 공헌도 있으나 커뮤니티 차원에서 기여한 것도 많다
  • PHP가 BSD-style 라이센스이므로 fork해서 계속 개발할 수도 있고, Rogue Wave가 Zend라는 용어에 대한 권리를 주장하면 “Zend Engine”이라는 용어는 PHP에서 지우면 그만이다
  • 하지만 오픈소스 프로젝트는 살아남을 수 있을 것이다. Magento처럼 Zend Framework를 기반으로 하는 회사와 프로젝트도 있고, Zend Framework를 계속 개발하는데 드는 자금이나 프로그래머들의 기여를 받는 것은 어렵지 않을 것이다

어설프게 번역했지만 대충 이런 이야기입니다. 요약하면 “Rogue Wave야 그동안 고마웠는데, 그냥 커뮤니티에 맡겨둬” 정도 되겠습니다.

요즘 각 언어나 프레임웍이 서로 닮아간다 이야기가 많았는데…
어쩐지 Node.js 커뮤니티가 걸었던 길을 가는 건 아닌가 싶기도 합니다.

62% of all internet sites will run an unsupported php version in 10 weeks

https://www.zdnet.com/article/around-62-of-all-internet-sites-will-run-an-unsupported-php-version-in-10-weeks/

— In 2015 the team decided to prolong PHP 5 support till the end of 2018. Nevertheless, more than a half of all sites still work on PHP 5. See the phpVatch checking top 1 million websites from Alexa Top which reveal their PHP versions. And upgrade your PHP!

W3Techs의 통계에 따르면 현재 모든 인터넷 사이트의 약 78.9 %가 PHP로 운영되고 있습니다.

  • 세상에!

그러나 2018년 12월 31일에 PHP 5.6.x에 대한 보안 지원이 공식적으로 중단되어 5.x버전에 대해 모든 지원이 종료된다고 합니다. 운영체제의 지원을 받으면 조금 더 연명할 수는 있긴 합니다만…

Joomla’s minimum requirement remains PHP 5.3, while WordPress’ minimum requirement remains PHP 5.2.

인터넷에 올라온 사이트의 1/4 정도 되는 워드 프레스 진영이 여전히 최소 지원 버전을 5.2보다 높이는 데 강력히 저항하고 있다고 합니다.

(이해는 됩니다. 그럼 안 돌아가니까…강 건너 불구경하다 생각해보니 저희 회사는 7.0을 쓰고 있네요. 남 걱정할 때가 아닙니다!)

결국 이 글을 읽는 여러분이 움직여야 합니다. 당장 사장실을 발로 차고 들어가 PHP를 업그레이 해야겠다고 외치세요. 왜냐고요? 음…

다음 소식입니다.

CodeIgniter 4.0.0 alpha1

그렇다고 합니다.

[RFC] Preloading

지난 9월달 소식에서 언급된 Dmitry Stogov의 제안이 정식 RFC가 됐다고 합니다.

Laravel Telescope

https://github.com/laravel/telescope

— One more tool in Laravel ecosystem. This time extended debugging dashboard. Detailed review.

Mohamed Said와 Taylor Otwell이 만든 디버깅 dashboard입니다. 흥미롭고 써보고 싶은데 일단 Laravel5.7이상…이니까 PHP7.1은 되어야 할테고…전 안되겠습니다.

Opening Keynote: PHP in 2018 - PHPConf.Asia 2018

PHP가 어떻게 변화하고 있는지 알려주는데 내부도 들여다보고 영어라서 잘 못알아 듣겠습니다. 여러번 봐야겠어요.

기타

마리오 게임 및 더 많은 소식이 들어 있습니다.

Tool 이야기는 최대한 뺐는데(모르니까), 매달 Async PHP에 관한 소식도 한 꼭지를 담당하고 있을 정도로 관심이 뜨거운 것 같네요. 커뮤니티에서도 종종 이야기가 나오고 말이죠.

이규원님이 TDD가 가능하다는 것을 보여주겠다고 하셔서 한참 전에 신청해놨었는데, 워낙 신청자가 많았고 소규모로 진행하다보니 이제야 차례가 돌아와, 지난 목요일에 다녀왔다. 장소는 을지로 위워크.

왜 참가했는가?

꽤 짧은 시간 진행하는지라 평소 궁금했던 건 미리 정리해보기로 했다. 우선 내가 행사를 참여하고 싶다고 생각했던 이유는 크게 세가지로 정리했었다. 난 TDD가 현실적이지 않다고 생각하진 않고, 내가 못하는 거라고 생각 했으므로 고수는 어떻게 일하는가를 보고 싶었다고 요약할 수 있겠다. (정말로 TDD를 욕하고 불가능하다고 생각하는 사람은 여기 오지도 않을 것)

TDD로 진행될 때의 속도를 느끼고 싶다

당연하게도 빠른 사람이 잘한다고 생각하지 않는다. TDD에 아주 익숙한 사람은 실무에서 어떤 속도로 일하는 지 보고 싶었다.

DDD가 어떻게 일상적으로 접목되는지 보고 싶다

DDD에 대한 부분은 특별한 감흥이 없었어서 뒤에서 언급을 안 할텐데, 내가 DDD를 잘 몰라서 뭘 봐도 물어볼 게 없었다. 공부 좀 더하고 실무에서 적극 다뤄봐야 궁금한 게 생길 것 같다.

관련해서 코드 외적인 부분(이슈/정책/문서화 등)과 코딩이 연결되는 과정이 궁금했다. 업무 프로세스.

유닛테스트 이외의 테스트는 어떻게 다루는 지 보고 싶다

언제, 얼마나 자주.

사전에 궁금했던 것

  • 통합테스트를 어떻게 하는지
  • 익숙한 패턴의 새로운 일감이 들어오면 얼마나 작게 시작하는지
  • 코드로 표현 안되는 부분이 있다면? 어떤 부분을 어디에 어떻게 문서화 하는가
  • ubiquitous language는 어떻게 작성되었는가/어떻게 참고하는가
  • functional test 시 사용하는 도구
  • User Story 를 먼저 작성해놓는다는데 어떻게 관리하는지
  • 테스트코드가 문서의 역할도 하는가? 코드를 읽을 때 테스트 코드도 자연스레 읽곤 되는지

참가 전 생각했던 관전 포인트

위에 언급한 목표에 따라 다른 분들 후기도 보면서 몇가지 관전 포인트를 생각하고 갔었다.

얼마나 빠른가

기계와 육체가 얼마나 유기적으로 동작하는지 보고 싶었는데, 스포츠 관람할 때의 쾌감을 느끼고 싶었다. 다시 말하지만 속력과 실력은 전혀 관련없다고 생각한다. 다른 분들이 TDD 강의에서 물 흐르듯 코드를 써내려가는 것에서 느꼈던 동경, JetBrains Night에서 Hadi Hariri의 세션을 봤을 때의 쾌감 같은 것.

이게 뭐가 중한데 자꾸 이야기 하냐고? 일단 익숙하고 좋은 툴이 생산성에 큰 영향을 끼친다고 생각하고, 개발하는 과정에서 불필요한 클릭이나 컨텍스트 전환이 자주 일어나지 않게 노력하는게 (나는) 좋다.

red - green - refactor

TDD 없이 어느 정도 개발 경력이 있는 사람이라면 공감할텐데, 처음 유닛테스트를 통한 TDD를 시도할 때 답답했던 것이 ‘내가 바로 다음에 작성할 코드가 뻔히 보이는데’라는 생각이었다. 코드를 대량으로 빠르게 갈기는 사람이라면 이 부분에서 ‘TDD는 비현실적이다’라고 할 것도 같다. 익숙해지면 조금씩 보폭을 늘린다고는 하지만 이미 익숙한 사람은 어떤 보폭으로 걸을 지 궁금했다.

다른 일로 빠졌다가 돌아왔을 때 금방 적응하고 cycle을 돌 수 있을까?

내가 회사에서 맡은 일은 백업 인력이 아직 충분치 않고 외부와의 접점이기도 해서 context 전환이 자주 일어나는데, 이에 따른 대처를 보고 싶었다. 당연히 이 시간엔 그걸 눈으로 확인할 수 없었고, 마땅한 질문도 생각이 안 나서 여쭤보진 않았다.

설계를 먼저 한다의 의미를 알고 싶었다.

다른 분의 후기에서 이런 말이 많이 보여서 어느 정도 선까지 설계를 해놓고 코딩을 시작하는지 궁금했다.

만남

각기 다른 배경을 가진 세 분과 함께 참여하게 됐다. 만나자마자 위워크의 카페 같은 열린 공간에 앉아 바로 시작했다. 자기 소개고 화장실 다녀올 사람이고 다 필요없고 바로 앉아서 시작. 규원님을 보면 군더더기 있는 것, 불필요한 것, 효율적이지 못한 것에 관심조차 두지 않는 것 같았다. 온통 군더더기에 잡동사니 같은 내가 보기에는 참으로 경이롭기까지 했다. 꼭 필요한 것에 대한 관념이 나와는 다른 듯. 뒤풀이 때 와우 이야기가 잠시 나왔는데, ‘저 분은 WoW(게임) 만랩 찍을 때도 저렇게 했을 거야’라는 생각까지 했다.

웬 인물평이냐 싶겠지만, 이 날의 가장 큰 깨닳음 중 하나였다. 원칙을 지키고 효율을 찾고 그 과정에서 익숙한 것에 대해 의심을 하는 것.

실제로 오프라인에서 만나면 친절하고 호탕할 거라고 생각은 했었는데, 예상대로 끝까지 깔끔하고 친절하고 정확한 표현으로 설명을 잘 해주셨다.

TDD 참관

먼저 TDD를 어느 수준으로 써보았는지 물어보셨고, 다들 비슷비슷하면서도 나보다는 실무 경험이 많으신 것 같아 다행이라는 생각이었다.

20분 정도 질문 받는 시간을 갖고 TDD에 대한 이야기를 조금 들었다. 몇가지 생각나는 것은

  • 엔지니어라면 덜 아름답더라도 현실적인 테스트를 해야하고, 그게 매뉴얼 테스트가 될 수도 있다
  • ISP는 정말 중요하다
  • TDD는 불안감을 해소한다는 중요한 가치를 제공한다
  • ORM 등의 테스트를 해야할 때도 인메모리 DB를 사용하는 것이 불안하다면 차라리 실제 로컬에 설치된 데이터베이스를 쓴다(이 부분은 좀 길게 이야기가 나왔던 것 같은데 내 기억엔 저렇게 남아있다)
  • 테스트가 가정하는 것이 적어야 한다. 따라서 테스트더블이 단순해야 좋다
  • xUnit Patterns에서 정의하는 용어

실제 업무를 통해 본격 TDD 시작.

요구사항 확인

어떤 이슈인지 알려주셨고, 이걸 어떻게 해결할 지 User Story와 하위로 관련 task가 있으며 쉽게 연관된 정책을 확인하셨다. 익숙한 UI가 아니라서 정확히 어떤 툴을 어떻게 연동해서 쓰는지는 잘 모르겠다.

중요한 건 이미 누군가가 이슈에 필요한 일을 정리했고, 여러 task로 잘 쪼개놓았고, 개발에 필요한 정책과 설계를 빨리 확인할 수 있었다.

브랜치 생성

branch를 따는 곳부터 다들 당황을 했다. master에서 바로 branch를 생성하고 다 끝나면 바로 master로 머지가 된다고 하셨다. git flow니 github flow니 이런 데 익숙한 사람들이라서, ‘아니, 그럼 이럴 땐 어떻게 하죠?’식의 질문이 꽤나 오래 이어졌다. 오히려 ‘그게 왜 필요하죠?’같은 질문을 역으로 받고 생각해보면, 또 굳이 문제가 될 건 없었다. 나에게 익숙한 것을 당연하게 생각하고 있었구나 하면서 정신 바짝 차리게 됐다. 이렇게 하루에도 수십번 상용 환경에 배포가 된다고 한다.

이날 내내 어떤 것이 정답이다라고는 이야기 안 하셨고, ‘우리는 이렇게 한다’라고 말씀하셨다. 회사마다 필요한 프로세스가 있을 것이고, 남들이 많이 쓰고 추천하는 방식이 아닌 가장 단순하고 효율적인 방식으로 업무 프로세스를 만들어놨구나 생각이 들었다. 게다가 Unit > Functional > Manual 테스트로 이어지는 충분한 테스트 때문에라도 불안감 없이 개발할 수 있다고 하셨다. 그럼에도 커버리지는 전혀 보지 않는다고 하심.

코딩

앞서 TDD에 익숙한 사람이 얼마나 빠르게 코딩을 해나가는지 보고 싶다고 썼었는데, 초장부터 그 기대는 박살이 났다. 개발환경도 별로 빠르지 않다. 다른 분들 후기에 계속 맥북이 보여서 이상하다 생각했는데, 처음 회사 왔을 때 iOS 앱 개발할 줄 알고 신청했던 걸 그냥 쓰고 계신다고 했다.

그리고 코딩을 가장 뒤로 미룬다고 하셨다. 난 기관총을 쏘듯 엄청난 코드를 만들고 지우고 하는 모습을 기대했던 것 같은데, 규원님은 스나이핑을 하거나 바둑을 두는 것처럼 필요한 정도로만 움직이셨다.

테스트 코드로 이동을 하고, arrange / act / assert로 구역을 나누고, 테스트 코드를 작성하고, 실패하는 것을 확인하고, 코드를 수정하고, 관련된 다른 테스트도 다 통과하는지 확인하고. 다 아는 그런 이야기 아닌가! 다만 그 과정을 익숙하고 당연하게 진행한다는 점. 미리 작성한 작은 task 이외에는 한눈을 팔지 않는다는 원칙은 곱씹어 볼 만 하다.

관련된 코드를 실행하는 기능이 내가 쓰는 프레임웍(PHPUnit + IntelliJ)에도 있었던가 궁금한데 확인을 해봐야겠다. 그 부분을 제외하곤 Unit 테스트를 확인하며 코딩을 하는데 있어 내 환경과 크게 다를 건 없어보였다.

확인

코딩이 끝나고 별도의 저장소에서 관리되는 functional 테스트를 돌리는 과정을 보여주셨다. 로컬 서버를 띄우고 돌리는 것 같은데 그 과정에서의 성능이나 상태를 cloud에서 확인하는 것 같았다. 일부 틀린 기억일 수도 있지만 어쨌든 MS 이놈들 개발환경 참 잘 만들어놨구나 싶었다.

다른 분들 후기에서 많이 이야기 하던 매뉴얼 테스트는 뭔가 싶었는데, 일종의 인수테스트인 셈이고, 개발자가(여긴 PO/기획자 직군이 없음) 테스트 해야할 항목을 정리하고 단계별로 실행할 수 있게 코드를 작성해놓으면, 실무진이 직접 테스트 해보면서 시스템 적으로 assert도 할 수 있는 도구였다. 그 과정에서 메모도 남기고 이슈를 발행할 수 있는 구조처럼 보였다.

감상

질문이 많아 task를 하나 정도만 처리할 수 있었지만 주요 과정은 다 볼 수 있었던 것 같다. 당시는 좋은 툴과 원칙을 지키는 것이 핵심이라 생각이 들었는데, 지금 생각해보면 (개발 문화를 포함해서) 업무 문화가 가장 중요하겠다는 생각이다. 요구사항을 받는 것부터가 TDD라고 생각하신다는 말이 조금은 이해가 갔다.

TDD를 꼭 해야하는 건 아니지만 불안감을 해소할 목적으로 도입하고자 할 때, 우리 회사(그 사람 구한다는..)는 어떨까? 업무를 해결하는데 있어 사용하는 여러 툴이 번잡하다고 느끼기도 하지만 Unit 테스트만 놓고 보면 괜찮다. 업무 프로세스나 문화는 아직 안정되지 않았다고 느끼지만 열려있고 실력있는 분들이 많으니 계속 개선은 되어갈 것이다. 결국 나 놈이 문제인데, 일관된 원칙을 지키고 전파하려면 많은 노력이 들 것으로 보인다.

요즘 새로 들어온 주니어와 같이 일을 시작했는데, 내가 업무를 떼어주고 설명하고 개발하고 배포하는 과정에서 하나 하나 부족함을 많이 느꼈다. 이번 참관 행사에서 몇가지 액션 아이템을 도출할 수 있겠다는 생각이 들었다. 뒤풀이 때 규원님이 꼭 보라고 추천하셨던 조인석님의 발표 동영상 Build the RIGHT thing - Lean & Agile 제품 개발기에서도 많은 팁을 얻었다.

이외에,

MS님들이 개발환경 잘 만들어 주셨구나 하면서 박수.

PHP나 JavaScript를 쓰는 사람 입장에선 유닛 테스트를 걸어두기 위한 초기 빌드 과정이 꽤나 길어보이긴 했지만, 그만큼의 견고함을 얻는 과정이니까 아쉬울 건 없을 것 같다.

앞으로

바꿔야 할 몇가지는 내 할일 목록 상단에 적어놔야겠다.

  • 개발자의 코딩 비용은 매우 비싸다는 것에 공감하고, 사전에 충분한 설계를 검토하고 진행해볼 것
  • Pair programing을 자주 시도할 것
  • 고객에게 정말 가치를 주는 목표인지 다시 생각해볼 것(기회 비용 면에서도)
  • 불필요한 프로세스를 거부하기

구체적인 목표가 없으므로 이렇게 세월이 흘러 유야무야 다시 원래대로 돌아오는 게 아니냐고 나를 의심하는 분들도 계실 것이다. 그렇다면 정확하고 예리한 지적이다. 구체적인 아이템은 고민 중이다.

마무리

좋은 자리 마련해주신 규원님께 다시 한번 감사드리고, 같이 참여하신 동료분들의 TDD 성공담을 들어보는 날도 기원해본다.

정말 좋은 경험이었고, 기회가 되면 회사 내/외부 뛰어난 분들이 일하는 모습을 더 많이 훔쳐보고 싶다는 생각도 간절하지만, 그런다고 나의 실력이 늘겠는가. 스스로 채찍질 좀 더 해봐야겠다.

뒤늦게 읽은 좋은 글 기억하기

한글라이즈 재제작기

https://speakerdeck.com/sublee/remake-of-hangulize

내가 아주 좋아하는 형식의 슬라이드. 이흥섭님이 이번엔 한글라이즈를 GO로 다시 만든 과정을 정리해주셨다. 만든 과정 뿐 아니라 외래어나 정규식에 관한 고민 등 내용도 흥미롭고 깔끔하게 지식을 전달하는 능력도 부럽다.

마이크로서비스 아키텍처(MSA). 서비스 개발팀 이야기

https://kihoonkim.github.io/2018/03/25/Microservices%20Architecture/first-msa-retro/

결론이 참 재밌다.

참 복잡하고 어렵다. 알아야 할 것도 많다. 우리는 이런 복잡도를 감수하면서 까지 MSA를 적용할 가치가 있는 것일까? 사실 지금도 매일 많은 문제에 부딪히고 있다. 하지만, 이 모든 과정이 좋은 개발 문화를 만들어 가는 밑거름이 되리라고 믿는다. 개발자로서는 정말 재미있는 경험이다. 내가 알고있는 모든 지식을 쏟아 부울수 있는 기회였다. 회사내 많은 제품들이 지속적으로 개선 가능한 구조로 개발될 수 있었으면 좋겠다.

저렇게 시도할 수 있는 능력과 문화는 대단한 것이라 생각. 그런데 이렇게 어려워서야, MSA를 도입한 건 성공적이었다고 할 수 있는 건가? 좋은 개발 문화를 만들어 가는 다른 방법은 없는걸까? 어떤 문제를 해결하기 위한 선택이기 때문에 잘했다 잘못했다 말할 수는 없고, 만족하신다니 다행이지만, 이런 류의 경험담은 거의 똑같은 결론에 이른다. “좋았어, 좋은데 여전히 어렵다.”

어려운 기술은 얼마나 완벽한 지와는 상관없이 결국 잊혀진다고 생각한다 - 완벽하지 않아서 어려운건가! 잊혀질지도 모르는 기술을 사용할 수 있다는 건 능력 면에서나 문화 면에서나 축복이라고도 생각한다. 겁먹고 익숙한 것만 쓴다는 건 개발자로서 너무 나태하다 - 익숙하다고 좋은 게 아니니까. 그런데 그 수많은 선택에 의한 충격파에 맞서 같이 지탱해줄 멤버가 없을 때는 과한 욕심이라고도 생각한다. MSA의 장점을 취하고 단점을 같이 버텨주기에는 다들 너무 어려워하고 있지 않는가? 저 잘 하는 사람들도 저렇게 어려워하는데 이렇게나 유행이 도는 것이 참말로 희안하다. 불편한 기술(SOAP 같은?)이 유행하는 건 이해할 수 있지만, 대부분(감히 이렇게 말해본다) 어려워하는 아키텍처가 유행하는 게 희안하달까. 우리도 그쪽 방향으로 가고 있지만, 점점 시스템이 쪼개지면서 어떤 문제가 해결됐다는 달콤함은 잠시, 일상적인 불편함이 하나씩 더 늘어날 것으로 보인다 - 그건 잘못된/부족한 설계라고 볼 수도 있겠지만. 나의 불편함은 내가 공부해서 해결하거나 당연한 불편함으로 감당해야겠지. 나는 그렇다치고 새로 들어올 많은 이들에게도 공부하던지 그냥 감당하라고 말하기는 미안한 감이 있다. 나보다 뛰어난 분들이 계속 들어오시길 바랄 뿐.

내가 우려하는 불편함이 무엇이냐 물어보신다면, ‘로컬에서 충분히 개발/테스트를 할 수 있는가’ 정도? 아이폰에 이어폰 잭이 사라졌을 때와 비슷한 혼란이다. 선 없어서 편한 대신 참 여러가지로 여전히 불편하다.

Serverless와 기술도입, Backend Application의 미래

https://medium.com/vingle-tech-blog/serverless와-기술도입-backend-application의-미래-8f114a8b00d5

MSA에는 의문이 계속되지만 서버리스/cloud computing의 미래엔 의심의 여지가 없다고 생각한다. 이 글의 관점에 99% 공감!

자바스크립트에서 타임존 다루기

http://meetup.toast.com/posts/125

타임존에 관해 잘 정리된 글. 이렇게 고려할 게 많다니!
얼마전 협력사 개발자와 이야기하는데 타임존 개념을 헷갈려서 당황했던 부끄러운 기억이 떠오르기도…

도커(Docker) 컨테이너 로케일 설정

https://www.44bits.io/ko/post/setup_linux_locale_on_ubuntu_and_debian_container

데비안(Debian), 우분투(Ubuntu) 이미지에서 한글 입력 문제

로케일에 대해 이해하기 좋은 글

여행 프로젝트를 통한 자녀 PM기법 훈련

https://projectresearch.co.kr/2018/09/14/여행-프로젝트를-통한-자녀-pm기법-훈련-부제-홀로서/

부제: 홀로서기 프로젝트의 교훈

딸래미와 무얼 한들 즐겁지 아니하겠냐마는, 홀로 설 수 있게 지원하는 PM 아빠의 여행 코칭. 딸과의 관계가 돈독하지 않으면 서로 힘겨운 여행이 될 터. 나도 얼른 해보고 싶긴 하지만 지금처럼 어릴 때의 귀여움 또한 충분히 즐겨야 한다!

언젠가 쓸모 있을 것 같은 링크 모음

AWS 클라우드 인스턴스 크기 선택

Microsoft 용어 검색

flexbox로 만들 수 있는 10가지 레이아웃

가만 보니 성공과 실패를 결정하는 1%의 네트워크 원리란 책을 5월에 읽었는데, 독후감을 안 썼네. (중간 한 챕터 정도는 건너뛰었으나) 네트워크에서 데이터가 돌아다니는 과정을 꼼꼼하게 훑어볼 수 있고 저자 이름을 보지 않아도 아, 일본 사람이 썼구나 싶은 책이다.

자, 그럼 7월에 읽은 책부터…

AWS 기반 서버리스 아키텍처

AWS 기반 서버리스 아키텍처 표지 이미지

AWS Lambda 예제로 살펴보는

AWS Lambda에 급 흥미가 생겨서 비슷한 시기(2017년 12월/2018년 1월)에 출간된 AWS Lambda 인 액션과 이 책을 두고 한참 고민하다가 훨씬 더 보기 좋게 구성된 이 책을 가져왔다(일단 색깔이 들어가서…). 여러 AWS 서비스를 체이닝하는 다양한 패턴을 잘 정리하기도 했고, 따라하기 예제도 이해하기 쉽게 설명해놨다. 기대 이상으로 흥미롭게 책을 읽어 나갔고 예제나 따라해야지 했는데,

안 돌아간다. 한국어판 출간이 반년 지났을 뿐이지만 원서는 2017년 5월에 나왔기 때문에 그동안 AWS UI나 Auth0 등의 정책이 바뀌기도 했고 예제를 따라 하려면 돌아가게 만들기 위해 잔손이 참 많이 간다. 그 과정에서 AWS를 익히는 데 도움이 꽤 됐지만, 너무 돌아온 느낌. 지금은 회사 내부 서비스에 람다를 적용해보려고 만지작거리느라 잠시 책에서 손을 뗐지만, 항상 그렇듯 잠시 손을 떼면 계속 놓고 있을 가능성이…

SQL 코딩의 기술

SQL 코딩의 기술 표지 이미지

Effective SQL - 똑똑하게 코딩하는 법

xxx의 기술 시리즈(닭요리의 기술도 참 좋았는데…). 원래 1월에 읽은 책인데, 정리한다고 한번 더 봤다. DBMS 시스템 별로 차이를 설명해주기도 하고 이런 저런 유용한 팁이 많아 참 재밌게 읽었다. 공개하기에는 저작권 문제가 있을 것 같아 요점 정리한 것은 나혼자만 아껴두고 보겠지만, 당연한 소리도 많고 이걸 본다고 뭐 대단한 지식이 생기는 건 또 아니다. 그냥 이렇게도 문제를 해결하는구나 정도 참고하면 좋겠다.

얼라이언스

얼라이언스 표지 이미지

4차 산업혁명 시대의 인재 관리법

4차 산업혁명 어쩌고 하는 부제가 달려서 펼치기도 싫었지만, 대표님의 추천이라 한번 읽어봤다. 당연하게도 4차 산업혁명 이야기는 국내 광고용 문구이고, 내용은 나쁘지 않다. 링크드인 창업자가 실리콘밸리에서는 인재관리가 어떻게 되고 있는지, 어떤 방향으로 나아가는지 들려준다. 그들이 제시하는 ‘동맹 관계 모델’의 취지에는 공감이 많이 되나 실행 방식에 대해선 많은 의문이 생기기도 한다. 이 모델에 대해서는 그들도 아직까지 완성된 것은 아니라고 같이 만들어 나가자고도 한다.

실리콘밸리 같은 환한 빛에 모여드는 불나방끼리는 꽤나 괜찮은 동맹 관계가 만들어질 수도 있겠다는 생각. 최고의 인재가 모이지도 않고 최고의 환경을 자랑하지도 않는 곳에서 일하는 더 많은 개발자에겐 또 다른 선택권(안정감을 느끼고 적절한 수준으로 일에 몰입하는 것)이 필요하기도 하고, 사회는 그런 사람들도 여전히 많이 필요하다. 책에서는 사측이 직원의 커리어를 위해서도 고민하는 모습이 소개되긴 하지만 참 어려운 문제다. 이런 제도 상에서 많은 직원들이 안정감을 잃는 것, 회사를 위해 희생하는 것 정도로 끝나지 않기 위해선 섬세한 관리와 대화가 필요할 것으로 보인다. 한국에선 낯선 그것 말이다.

취지에는 공감이 많이 되므로, 읽으면서 예전 직장 관리자 분들께 하나씩 보내드리고 싶은 생각이 많이 들었다. 그 분들의 방식이 잘못 됐다는 게 아니고, 세상이 이렇게 변하고 있으니 그 중간 어디쯤에서 만나자고. 평생 직장 개념을 버리고, 만나고 헤어짐을 당연히 여기고, 서로를 위해 좀 더 열심히 노력하고, 좋은 인재를 확보하길 바라면서.

GoF의 디자인 패턴

GoF의 디자인 패턴 표지 이미지

재사용성을 지닌 객체지향 소프트웨어의 핵심요소

내가 디자인 패턴을 달달 외우고 있지는 않고 명확히 설명하지 못하기 때문에 간만에 정리나 할 겸 읽어봤다. 오래된 책인데 내용이 참 좋다. 디자인 패턴이 이렇게 오래전부터 개념이 확실히 잡히고 풍부한 경험으로 정리됐었구나 놀랍기도 하다. 아마 개발자 초년에 봤다면 어렵기만 했을 것인데, 실무에서 그리고 스터디하면서 어설프게 고민하고 익혔던 패턴을 정리하기에는 참 좋다. 이보다 더 깔끔하게 정리된 책이 있을까 싶을 정도로 내용이 좋았는데, C++과 스몰토크에 익숙하지 않은 자바 월드의 잡초같은 개발자들을 위해 JAVA/JavaScript 정도로 예제만 바뀌어 나오면 괜찮은 상품이 될 것 같은 느낌이다. C 가족 언어만 익혀와서 그런지 스몰토크 문법은 정말 모르겠다. 문맥은 대충 알겠지만 정확히 이해할 수 없어서 아쉽기도 하고, 괜찮기도 하고.
구조나 플로우 같은 거나 종이에 그려보면서 한번 더 곱씹어야겠다.

개정판만 그런지 모르겠지만, 무거워도 손에 착 달라붙는 양장본이라 전철에서 읽기에 나쁘지 않았다.

기타

우리 가족 캐릭터 데코 도시락뜯어 먹기 좋은 빵도 정독하진 않았지만 아이와 함께 훑어보고 만들어보면서 꽤 즐거운 경험이 됐다.

(누군가의) 2018년 상반기 회고

http://jojoldu.tistory.com/332

밤에 잘까 말까 몇번이고 흔들리다 켜서 처음 본 글인데 잠이 확 깨는 엄청난 정리.

가끔 들어가 본 블로그인데, 이제 RSS 피드로 꼬박꼬박 지켜봐야겠다고 생각. 공감하고 반성하고 많이 배웠다.

요즘 기술 익히는 방법에 변화를 줘야겠다는 생각도 많이 하는데, 이런 생각을 꽤 오래 했다는 생각도 들고…

(누군가의) 짤막한 일주일간의 입사 소회

https://www.facebook.com/curlychoi/posts/1962385560485320

최광훈이란 분의 Toss 입사 소회. 이전에도 Toss 들어가신 분들의 글이 종종 회자되는데, 저 곳이 파라다이스라고 생각하는 건 아니지만, 저 짧은 시간에 좋은 문화를 만들어낸 것이 놀라울 따름(알아, 알아, 설마 다 좋겠어?). 누군가 예민하고 똑똑한 사람이 있는 것만 같다는 생각을 하면서도 역시 돈을 많이 벌어서 그것도 가능한가 싶기도 하면서 돈이 있다고 만들어지는 문화는 아니라는 결론을!

GIF 사용을 멈춰주세요!

https://medium.com/vingle-tech-blog/stop-using-gif-as-animation-3c6d223fd35a

두가지로 요약된다.

  • GIF는 거품 덩어리이며, 모두에게 손해다
    • H.264 Video로 변환하는 경우 10배 이상 크기를 줄일 수 있으며, 기기의 배터리에도 도움이 된다.
  • GIF를 Video로 변환해서 제공하자
    • giphy, ffmpeg, cloudinary, imgix등 다양한 선택지가 존재하니 상황에 맞게 선택해라

플랫폼은 준비됐고, 개발자들은 시도할 것이고 시도해야할 것이나, GIF는 계속 쓰이겠구나 싶은 글이다.

백종원의 골목식당에서 배우는 그로스 해킹

https://medium.com/dano-ai/백종원의-골목식당에서-배우는-그로스-해킹-8d07a03be87b

요식업이 아니라도 정말 배울 게 많다. 이쯤되면 모든 초심자의 왕이라고 봐야…

HTTPS와 SSL 인증서, SSL 동작방법

https://wayhome25.github.io/blog/

‘xxx를 초등학생에게 설명하시오’와 같은 면접 질문이 돌아다니던데, 이 분은 정말 설명과 정리를 잘 하신다. 하루이틀 정리해본 사람이 아니구나 싶은데, 블로그를 둘러보고 더 확신했다.

작은 생각에서 시작해서 큰 생각을 만드는 정리의 힘: 이상혁 헤드헌터 인터뷰

https://ppss.kr/archives/170815

이상혁: 네, 그러면 ‘병원을 간다’라는 액션이 생기겠죠? To do 리스트에 적을 건 이런 액션이에요. 병원에 간다, 금연초를 산다. 그런데 계획을 집어넣으면 머리만 아파요. ‘아, 이걸 어떻게 하지?’라는 생각이 들면 이미 To do 리스트가 아니에요. 어떻게 할지 생각하고 적어놓은 게 To do 리스트거든요.

아차싶은 문구. todo랑 backlog를 구분해서 정리해야겠다!

제프 베조스: 아마존이 20년간 갈고 닦은 비즈니스 접근법

https://www.youtube.com/watch?v=l9X8X-Ixbo8&feature=youtu.be

그동안 여기저기 인용되고 퍼가는 제프 베조스가 했던 이야기에서 별로 다를 건 없는 내용이긴 한데, 저 말투와 내용이 참 압도적이다. 이걸 굳이 여기 아카이브해야하나 생각도 들긴 하다만..

[MySQL] MySQL 실행 계획

http://12bme.tistory.com/160

Real MySQL을 타이핑한 건가 싶을 정도로 어마어마한 정리. 책을 보고 하셨는지 직접 정리하신 건지는 모르겠지만 참고용으로 좋다.

GraphQL Server Tutorial with Apollo Server and Express

https://www.robinwieruch.de/graphql-apollo-server-tutorial/

엄청 자세한 apollo client + server 튜토리얼 입니다. 세팅부터, 인증, 로그인, 회원 가입, 페이지네이션 까지 전체적으로 설명하면서 튜토리얼 까지!

라고 한다. 나는 apollo를 써본 적이 없으니 시간이 나면 한번 쭉 훑어보는 목적으로 한번 해…볼 수 있는 사람들을 위해.

[직설]서로 다른 현실들 속에서

http://news.khan.co.kr/kh_news/khan_art_view.html?artid=201807182115005&code=990100

갈등을 억누르고 무조건 대타협을 이룩하자는 것이 아니다. 싸움을 피할 수 없다면, 싸우면서 크는 법이라도 알아내야 한다. 이 모든 정념과 분노와 에너지가 무의미한 것이 되지 않도록. 훗날 더 나은 세상과 삶을 위한 성장통이었다며 돌아볼 수 있으려면 말이다.

온라인이면 어디든 분노, 분노, 분노. 이런 언행을 하는 사람은 인간 말종이고 이제 당신은 끝이다라는 말을 많이 보게 되지만, 그렇게 하나씩 같이 어울려 살 수 없는 인간을 늘려나가다 보면 결국 아무도 남지 않는다는 생각이다. 어디까지 포용할 수 있을지는 각자 다르겠지만, 특히 온라인이라면 어떻게 저런 인간과 계속 같이 살아야 할까를 고민하기 보다는 단칼에 잘라 지옥에 보내버리는 게 사실 속시원하긴 하니까 그렇게 간단하게 경계를 만들어 나가는구나 생각이 든다.

최근 가장 안타깝고 피부로 와닿았던 글은 다양성이란 무엇인가요? 2018 파이콘KR 이 글이다. 여성 문제와 소수자 인권에 관심이 많고 예민하게 활동하고 행동했던 분인데, 더 예민한 사람이 보기엔 충분하지 않았던 모양이다. 이의 제기하신 분의 이야기에도 물론 이해가 되고, 누구든 충분히 실수할 수 있는 문제인데(실수해도 된다가 아닌!) 본인 스스로 너무 충격을 받지 않았나 안타깝다. 얼른 일어나 같이 이 세상을 살아갔으면 한다.

언젠가 쓸모 있을 것 같은 링크 모음

Bash 입문자를 위한 핵심 요약 정리 (Shell Script)

Exploring JS: JavaScript books for programmers — Dr. Axel Rauschmayer (author of the 2ality blog)

개발자 밋업/세미나 모음

불안한 엄마 무관심한 아빠

불안한 엄마 무관심한 아빠 표지 이미지

오은영 박사의 불안감 없는 육아 동지 솔루션

육아계의 마틴 파울러 오은영 박사의 역작. 맨 앞에서 맨 뒤까지 버릴 게 없는 훌륭한 조언이 가득하다. 입이 닳도록 주위에 칭찬하고 추천했지만 한명도 읽지 않았겠지. 무상지급이라도 해서 읽게 하고 싶을 지경이다. 일년에 한번씩은 읽어야겠다.

슬슬 사고의 유연함이 떨어지기 시작하는 30대라면 ‘난 이 정도는 아닌데? 너무 남자는/여자는 다 똑같다고 얘기하는 것 같아’라고 생각할지도 모르겠다. 책은 (IT계는 비교적 덜하지만) 흔히 보이는 전형적인 30~40대를 기준으로 쓴 것 같다. 하지만 남녀 차이라기 보다는 크게 두 부류의 성격으로 구분했다고 보면 된다. 불안한 사람과 무관심한 사람. 뒷부분에 아빠/엄마/아이가 각각 불안하거나 무관심한 경우의 조합을 들며 설명하는 부분이 있기도 하다.

그동안 육아책을 몇 보았는데, 도무지 마음에 드는 게 하나 없었다. 감성적으로만 접근하기도 하고, 나름 꽤 많은 근거를 들면서도 합리적으로 보이지 않고, 육아 게임에 몰두한 청소년을 위한 책으로 보일 지경이었다.

오은영 박사님은 전형적인 남녀의 육아 성향이 다른 표현으로 나타나지만 결국 불안이라는 하나의 원인에서 출발한다고 이야기한다. 육아에서 발생할 수 있는 수많은 상황에서 어떻게 대처해야할지 모범 사례도 나온다. 이런 모범 사례에서 제시하는 말투는 한 호흡에 말하기도 어렵거니와 차마 입에 잘 붙지 않는 문장이긴 하다. 그런데 그렇게 차분하게 조곤조곤 이야기를 해야 문제를 풀어나가는 것도 맞다.

우리가 직업에서의 전문성에 투자한 노력을 조금만 빼서 육아에 투자하면(부모도 우리 직업이니까), 노력 대비 많은 이득을 얻을 수 있을리라 확신한다. 다들 그렇듯 ‘나 정도면 중간 이상은 가겠지’라는 생각을 하고 살았지만 스스로 돌아보면 잘못된 행동을 참 많이 했다. 잘못됐다는 표현이 좀 과격했다면, 효과적인 육아를 하지 못했다고 표현을 좀 바꿔볼까나?
신생아 때부터 봐서 그런지 계속 애기처럼만 생각되는데, 아이를 존중한다는 개념이 아직도 참 어렵다. 아이를 압도해야할 것 같기도 하고 남에게 피해를 주는 것에 강하게 주의를 줘야할 것 같기도 한데, 그게 효과적인지를 잘 생각해봐야 하겠다.

대충 키워도 잘 크기는 커녕 대충 키우면 대충 큰다.

일부 아리송한 근거가 있긴 한데, 몇가지 남녀의 불안과 전형적인 행동이 수천년 전부터 남녀 각각의 유전자에 남아있는 본능이기 때문이라는 것이다. 이상한데 난 잘 모르겠고 그럴듯 하기도 하고.

직업의 지리학

직업의 지리학 표지 이미지

소득을 결정하는 일자리의 새로운 지형

어쩌다 보니 또 김영사네!

온라인에서 정광섭님이 누군가에게 추천하시는 걸 보고 적어놨었는데, 김주원님도 책을 읽고 계시길레 빌려봤다.

혁신 직종이 한 도시에서 발생할 때 이로 인한 추가 일자리가 생긴다는 이야기. 예상보다 꽤나 많다. 그것은 알기 싫다의 지방선거 데이터 센트럴에서 온통 혁신과 기업 유치를 부르짖는 것이 이해도 된다. 그런 혁신 직종은 서로를 끌어들이는데 이걸 한 도시에 유치하는 것은 사실상 누구도 확신을 갖고 이루기 힘든 일인 것 같다(모든 사업이 그렇지 않겠냐마는). 그러나 도시나 국가 차원에서 시도해볼만 일을 제안하기도 하는데 그런 건 좀 상식적인 이야기였던 것으로 기억하고.

거시적인 관점으로만 통계를 분석했기 때문에 한계도 많다. 읽는 초반 내내 찜찜했던 것은 이 사람이 혹시 낙수효과를 다루는 게 아닌가 의심이 들었기 때문이다. 우리나라 정치인이 이야기하는 낙수효과와는 조금 거리가 있다. 우리나라의 낙수효과는 대기업에게 돈을 몰아주면 하층민이 부스러기를 나눠먹을 수 있다는 용어라면, 여기서는 직업이라는 관점에서 발생하는 현상일 뿐이고 특별히 정치적인 뉘앙스는 찾을 수 없었다. 하긴 혁신 직종 위주의 정책만을 다루고 있으니 이 또한 정치적이다고 할 수도 있겠다.

지식 전파는 지리적으로 가까운 기업 사이에서 발생한다는 사실도 서울에 사는(경기도와의 경계까지 500m. 올해까진 서울 사람) 프로그래머로서 많은 공감이 된다. 사실 나는 별로 안 하지만 스타트업쪽이나 개발자 모임에서 만나는 분들이 네트워킹하는 모습을 보면 이 업계가 서울을 뜨긴 글렀다는 생각도 든다.

하나의 기업이 해외로 이전한다거나 군산의 경우처럼 특정 직업이 사라지는 현상에서도 긍정적인 평가를 내고 있는데, 이를 전 세계의 공동 생산으로 바라보고 있다. FTA로 쌀 개방할 때도 생각난다. 농민은 죽지만 나머지는 더 싸게 쌀을 사먹을 수 있다. 그리고 그 혜택은 저소득층일 수록 더 커진다. 이 책의 가장 큰 한계가 이 지점이라고 생각한다. 전체적으로 보면 긍정적인 현상인데 개개인은 다 죽을 맛이라는 거. 죽어가는 산업에 산소호흡기를 대는 수준까지는 아니라도 고장난 가구 고쳐쓰는 마음 정도는 필요하겠다는 생각.

이렇게 새로운 직업이 계속 생기고 여기에 다른 직업이 혁신 직업을 보조하고(그들의 생산성을 높여주고) 사라질 직업은 사라질텐데, 오래전부터 인당 투입 시간에 큰 변화가 없는 미용사, 서빙하는 종업원, 간호사 등은 앞으로도 크게 변화는 없을 것이라 내다봤으나(내가 제대로 읽은 게 맞나?) 기계가 대체하기 쉬운 건 중간 정도의 교육 수준에 중간 정도의 소득을 받는 사람들의 직업이라고 한다. 그냥 우리 모두 죽었다라고 생각해야 할지도 모르겠다. 지금의 혁신 직업에 속한 이들도 그들의 수명 안에는 중간 정도의 대체 가능한 직업이 될 테니까. 이렇게 보니 세상에 쉬운 일은 사라지고 모두가 고통에 쌓일 거라는 나의 예언이 맞아 들어간다. (젊을 때 혁신 산업에 종사하고 나이 들면 종교 산업에 들어가는 것도…)

[근로시간 단축 한숨짓는 자영업] 저녁 예약 손님 뚝···식당가는 “죽을 맛” 노래방은 “곡소리”

멍청한(혹은 고약한) 기사긴 하지만 자영업자가 이렇게 많은 것도 그릇된 회식 문화가 키워놓은 산업일 지도 모르겠다. 개개인의 생활은 고통스럽겠지만 변화는 계속 더 빨라질테고 다들 얼른 준비를 하셔야 할텐데. 나는 여전히 나이들면 외식업을 차리는 걸 고려하고 있지만, 쥐꼬리만한 월급을 모은 돈을 모두 투자해선 안된다. 나이가 들면 어떤 직업이든 치고 빠질 생각을 해야겠다.

0%