Browse Author

mars

Psychological Safety – 1편 Unsafety Signals

마틴 파울러의 한 마디 : 심리적 안전감이 없는 팀은 성과를 내지못한다.

그리고 위험 신호와 개선 방법에 대한 글을 하나 소개해주네요.
Psychological-Safety

이 글은 위의 링크를 나름대로 정리한 글입니다.

성공적인 팀의 가장 중요한 지표는 Psychological Safety!

당신의 팀은 아래의 다섯 질문에 얼마나 동의하시나요?
많이 동의할수록 Unsafety한 것입니다.
1. 만약 기회를 얻은 사람이 실패했다면 비난 받을 것이다.
2. 우리팀은 새로운 멤버가 합류하기 어려운 강한 문화를 가지고 있다.
3. 우리팀은 곤란을 겪고 있는 사람을 돕는데 소극적이다.
4. 나의 기술과 재능을 활용하는 것은 팀의 목표보다 후순위이다.
5. 팀의 민감한 이슈에 대한 공개된 솔직한 대화(open honest conversations)는 불편하다.

Unsafe team의 영향력을 가상의 신입사원 카렌의 사례로 설명해줍니다.
카렌은 분산 데이터베이스의 low-level locking 줄여줄 방법을 찾았고 테스트 결과 15%의 CPU를 절감할 수 있었기에, 제품(production) 환경에도 적용하기로 마음 먹었스비다. 데이터베이스 설정 파일을 수정하면 끝이었기 때문에 코드리뷰를 받을 필요도 없었습니다. 하지만 안타깝게도 서비스 전면 장애가 짧게나마 발생했고, 동료가 문제를 발견해서 10분 이내로 원복할 수 있었습니다.

안전하지 못한 팀은 변화를 받아들이지 못하기에 망하거나 급격히 저성과를 낼것이다.

“If I take a chance, and screw up, it’ll be held against me”
주간 포스트 모텀에서 이 사고는 다루어지게 되고 엔지니어링 디렉터는 약간의 성능을 향상시키기 위해 전면 장애를 내는 것은 받아들일 수 있는 일이 아니며 그녀를 무책임한 사람으로 몰아갔습니다. 그리고 그녀는 절대로 이 일을 잊지못할 것이고 다시는 시스템을 개선하기 위해 노력하지 않을 것입니다.

“Our team has a strong sense of culture, and it’s hard for new people to join”
카렌이 받은 충격은 아무도 그녀를 옹호해주지 않았기 때문에 더욱 커졌습니다. 아무도 데이터베이스 설정 파일의 변경에 대한 코드리뷰가 없는 것을 언급하지 않았으며, 무책임한 행동과 무책임한 사람의 차이에 대해서 언급하지 않았습니다. 그 팀은 그들이 만든 시스템의 신뢰성(reliability)에 대한 자부심을 느끼고 있었으며, 그들의 명성을 지키는 것이 신입 사원보다 훨씬 더 중요했습니다.
카렌이 배운 것은 그녀의 팀과 매니저가 그녀를 돌봐주지 않는다는 것이었습니다.

“My team is slow to offer help to people who are struggling”
카렌은 제품(production)에는 처음이기에, 사고 대응이나 제품 안정성(production hygiene)에 대한 공식적인 교육을 받지 않았으습니다. 분산 시스템에 대한 문제해결은 고사하고. 그녀의 팀은 경력자로 구성되었기 때문에 트레이닝이나 신규입사자 문서가 필요가 없었습니다. 또한 카렌과 같은 신규입사자가 이러한 기술을 배우는데 시간을 보내도 된다는 지침(signal)도 없었습니다.

카렌은 가면 증후군(Imposter Syndrome: 자신의 성공이 노력이 아니라 순전히 운으로 얻어졌다 생각하고 지금껏 주변 사람들을 속여 왔다고 생각하면서 불안해하는 심리이다.)에 시달렸고, 어떻게 그녀가 입사할 수 있었는지 이해할 수 없었으며 왜 자신이 아직까지 해고되지 않는지 종종 생각하게 되었습니다.

“Using my unique skills and talents come second to the goals of the team”
카렌은 알고리즘, 자료구조, 그리고 분산 컴퓨팅을 전공했으며, 시스템이 전체적인 관점에서는 최적화되지 않았으며 부하 급증을 결코 처리하지 못할 것이라는 것을 깨달았습니다. 팀은 항상 고객이 계약보다 더 많이 사용한다며 비난했으며 이것은 마치 바베큐를 할려는데 왜 비가 오냐고 기상예보를 비난 하는 것과 같습니다.

카렌은 새로운 설계를 제안했지만, 동료들은 친숙하지 않는 새 기술을 리스크로 간주했으며 토론도 해보지 못하고 포기해야 했습니다. 카렌은 코드를 작성하고 시스템을 만들기를 원했지만 무의미한 논쟁은 원치 않았습니다.

“It’s uncomfortable to have open, honest conversations about our team’s sensitive issues”
대규모 고객 트레픽 증가가 몇 시간의 장애를 일으켰을 때, 카렌은 지금의 설계로는 절대로 문제를 해결할 수 없고 자신의 설계에 대해 말했지만 엔지니어링 디렉터는 카렌의 설계는 이미 엔지니어링 리뷰에서 기각되었다고 말했습니다.
이후에 카렌은 팀 동료에게 그 디렉터의 설계가 문제라는 것을 이해하지 못한다고 말했지만, 그 팀동료는 어깨를 으쓱이며 지금까지 잘해왔다고만 말할 뿐이었습니다.

카렌은 칼퇴하고 새로운 일자리를 찾아 떠났고, 회사는 그녀를 그리워하지 않았고 그녀를 무모하고, 불평하고 그리고 권위에 대항하는 사람으로 남게 되었습니다. 그리고 그들은 그녀의 설계가 반복되는 장애에 의한 고객 탈출을 막을 수 있는 설계라는 것을 결코 깨닫지 못했습니다.

어떻게 Psychological Safety를 만들 것인가는 2부에서 계속됩니다.
How to build psychological safety into your own team
We need to balance respect for our culture, with an openness to change it as needed.

[hotjar] Questions-love-to-ask-users 일부번역

https://www.hotjar.com/blog/2016/03/05/questions-love-to-ask-users/#E-commerce

  • 리딩 포인트 : 드라이버, 배리어, 훅 중 무엇을 얻고자 하는 질문인지 생각해보자.

E-commerce
구매전
– 어떤 정보가 누락되었는가? 혹은 어떤 정보가 구입 결심을 쉽게 만드는가?
– 이 아이템을 구입할 때 무엇이 가장 큰 불안(fear)과 우려(concern)인가?
– 오늘의 방문 목적을 달성(complete)할 수 있었는가?
– 만약 오늘 구입을 하지 않았다면, 무엇이 당신을 포기(stop)하게 만들었는가?

구매후
– 결제(checkout) 프로세스에서 개선해야 할 곳은 어디인가?
– 우리 사이트에서 상품을 구입하는데 가장 큰 불안과 우려는 무엇인가?
– 아이템을 구입하도록 유혹한(persuade) 요소는 무엇인것 같은가?
– 만약 더 이상 서비스를 사용할 수 없게 된다면, 가장 아쉬울 것 같은 기능 하나는 무엇인가?

그 외 좋은(great) 질문들
– 가자고를 지인들에게 추천할 확률은 얼마나 되는가? (NPS 질문, 상세내용 => http://book.naver.com/bookdb/book_detail.nhn?bid=7851521)
– 가자고는 몇점(1 – 10)?

Jpa + Jackson Serialization 삽질기

Jpa를 사용하니 객체(Entity)의 연결이 매끄러워졌다.

A 객체를 조회했을 때 A.B 가 가능하고, 반대로 B 객체를 조회했을 때도 B.A가 가능하다.

심지어 개발자는 데이터베이스 질의(Query)를 고민할 필요가 없다.

이 얼마나 좋은 세상인가!

 

이 좋은 세상에서 나는 나의 꿈을 마음껏 펼칠려는 무렵 Jpa와 Jackson은 현실이 그렇게 녹록치 않음을 깨닫게 해줬다.

간단한 조회 API를 개발했고 조회 결과는 json으로 반환한다.

얼마나 멋지게 만들었는지 자찬하기 위해 API를 테스트해봤다.

헉 … 이 멋진 API의 json 응답 데이터 크기가 무려 375K ! ㄷㄷㄷ

 

마음 속의 거만함을 급히 내팽겨치고 왜 이런 일이 발생했는지 객체의 구조를 살펴봤다.

A.B.A.B.A ..  객체는 Circular reference의 형태였다. ㅠ

 

이제 나는 A를 조회하는 json API를 위해 A.B = null 을 할당해야 하는 암담한 현실을 이해한 것 같다.

이 얼마나 우아하지 못하고 실용적인 방식인가.

 

다른 개발자들은 이 문제를 어떻게 해결할까?

구글갓은 나의 기도 같은 검색 요청에 이번엔 친절했다.

infinite-recursion-with-jackson-json-and-hibernate-jpa-issue

jackson-serialization-of-entities-with-birectional-relationships-avoiding-cyc

JacksonFeatureObjectIdentity

 

위 3개의 링크를 통해 나는 2가지를 얻게 되었다. (3개를 봤는데 2개를 얻다니!)

  1. JsonIdentityInfo : 객체의 ID 속성을 이용해 한번만 serialize 되도록 해준다. 따라서 A.B.A.B … 의 객체 구조는 A.B 까지만 변환이 되고, B.A는 변환되지 않는다.
  2. Jackson-module-hiberate : Jpa Entity의 lazy loading 되는 부분은 json 변환에서 제외해준다. 상황에 따라서 다르겠지만 사실 나는 B도 불필요했기 때문에 유용하게 쓸 수 있을 것 같다.

 

JsonIdentityInfo는 Jpa Entity 클래스에 추가해주자.

예를 들어 아례와 같이 사용할 수 있다.

 

jackson-module-hibernate는 ObjectMapper에 적용해주자.

 

이 두가지를 적용해서 json API의 응답이 374KB 에서 400B로 줄어들었다.

다른 사람들이 보기 전에 해결해서 다행이다.

  • mars