[번역] 소프트웨어 엔지니어링에서 좋은 취향은 뭘까?

출처: https://www.seangoedecke.com/taste/

소프트웨어 엔지니어링에서 좋은 취향은 뭘까?

기술적 취향은 기술 능력과 다릅니다. 기술적인 면에서 뛰어나지만 나쁜 취향을 가지거나, 기술적으로 약하지만 좋은 취향을 가질 수 있습니다. 일반적인 취향과 마찬가지로 기술적 취향은 때때로 능력보다 앞설 수 있습니다. 요리를 할 줄 몰라도 좋은 음식과 맛있는 음식을 구분할 수 있듯이, 소프트웨어를 만들 줄 모르더라도 어떤 소프트웨어를 좋아하는지 알 수 있습니다. 기술적 능력은 공부와 반복을 통해 키울 수 있지만, 좋은 취향은 신비한 방식으로 키울 수 있습니다.

소프트웨어 취향을 나타내는 몇 가지 지표는 다음과 같습니다.

  • 어떤 코드가 좋고, 나빠보이나요?
  • 어떤 결정을 했을때 기분이 좋거나 그저 그랬나요?
  • 어떤 문제들이 직장 밖에서도 걱정될 정도로 당신을 괴롭히나요? 어떤 문제들을 그냥 넘길 수 있을까요?

제 생각엔 취향은 현재 프로젝트에 맞는 엔지니어링 가치를 채택하는 능력이라고 생각합니다.

왜 스킬과 취향은 다를까요?

위에 말한 지표들은 기술의 일부일 뿐 아닌가? 예를 들어, 좋은 코드라면 보기에도 좋지 않을까요? 저는 그렇게 생각하지 않습니다.

예를 하나 들어봅시다. 개인적으로, for문 대신에 map과 filter를 사용는 것이 더 좋은 코드라고 느낍니다. 보통 이건 단순히 내가 올바르게 판단하고 있다는 착각을 할 수 있습니다. 예를 들어, map과 filter는 일반적으로 순수 함수를 포함하여 이해하기 쉽고, 반복자 관련된 경계선 문제를 쉽게 해결할 수 있습니다. 따라서 이 예제에 대해선 취향 문제가 아니라 내가 옳고, 다른 엔지니어들이 틀린 문제라고 볼 수 있습니다.

하지만 현실은 훨씬 더 복잡합니다. go언어는 원칙적인 이유로 map과 filter들이 포함되어 있지 않습니다. for 루프를 사용하여 반복하는 것이 성능적인 관점에서 추론하기가 더 쉽고 확장하기가 쉽습니다. (한 번에 두 개 가져오기). 저는 이런 이유들보다 map과 filter가 가지는 장점을 더 중요하게 생각합니다. 그래서 for루프를 잘 쓰진 않지만, 그렇다고 for 루프를 선호하는 엔지니어들이 단순히 덜 숙련되었다고 말하는 건 매우 오만한 일입니다. 다양한 상황에선는 그들이 제가 가지고 있지 않은 기술 능력을 가지고 있을 수 있습니다. 그들은 그저 다른 것을 더 집중해서 보는 것 뿐입니다.

다른말로 우리의 의견차이는 가치관의 차이에서 비롯됩니다. 저는 이전 글 「I don’t know how to build software and you don’t either」에서 이 점에 대해 언급했습니다. 큰 기술적 문제에 명확한 답이 있다고 하더라도, 어떤 현직 소프트웨어 엔지니어도 그 답이 무엇인지 알 수 있는 입장에 있지 않습니다. 왜냐하면 한 가지 경력에 많은 경험을 담을 수 없기 때문입니다. 저희는 개인적인 경험의 일부분에 기댈뿐입니다.

엔지니어링의 취향이란 무엇인가

소프트웨어 엔지니어링에서 대부분의 결정은 트레이드오프입니다. 두 가지 옵션 중 더 나은 것을 선택하는 경우는 거의 없습니다, 다만 각각의 옵션은 각자의 장점가 단점을 가지고 있습니다. 종종 엔지니어롱 가치들 사이에서 어려운 트레이드오프를 해야 합니다.
예를 들어, 일정 지점을 지나면 가독성을 해치지 않고는 성능을 쉽게 높일 수 없습니다.

이 점을 실제로 이해하는 것은 소프트웨어 엔지니어링에서 성숙도를 나타내는 가장 큰 지표입니다. 미성숙한 엔지니어들은 자신의 결정에 완고합니다. 그들은 항상 X 또는 Y를 하는 것이 더 낫다고 생각합니다. 성숙한 엔지니어들은 결정의 양 측면에 대해 고려하려고 합니다. 그들은 양측 모두에 서로 다른 이점이 있다는 것을 알고 있기 때문입니다. 중요한 것은 기술 X가 Y보다 나은지 여부를 결정하는 것이 아니라, 특정한 경우에 X의 이점이 Y보다 더 큰지 여부를 결정하는 것입니다.

다시 말해서, 미성숙한 엔지니어들은 취향에 대한 융통성이 없습니다. 그들은 무엇을 좋아하는지 알지만, 그 취향을 원칙적인 엔지니어의 입장으로 오해합니다. 특정 엔지니어의 취향을 정의하는 것은 무엇일까요?

제 생각으로, 당신의 엔지니어링 취향은 당신이 가장 중요하다고 생각하는 엔지니어링 가치 집합으로 구성됩니다.

회복력

인프라 구조가 실패할 때 (서비스가 중단되거나 네트워크 연결이 불가능해짐) 시스템이 계속 작동합니까? 인간의 간섭없이 회복할 수 있습니까?

속도

소프트웨어의 속도는 이론적 한계와 비교해서 얼마나 빠른가? 반드시 필요하지 않은 작업이 핫 패스(핵심 경로)에서 수행되고 있는가?

가독성

해당 소프트웨어는 한눈에 쉽게 사용할 수 있고, 새로운 엔지니어를 채용하기 쉬운가요? 함수는 비교적 짧고 이름이 잘 지정되어 있을까요? 시스템이 잘 문서화되어있을까요?

정확성

시스템에서 잘못된 상태를 표기하는게 가능합니까? 테스트, 타입, 그리고 assert로 시스템이 얼마나 제한적으로 잠겨 있나요? 테스트가 fuzzing 같은 기법을 사용하나요? 극단적인 경우로, 프로그램이 Alloy 같은 형식적 방법(formal methods)으로 올바름이 증명된 적이 있나요?

유연성

시스템을 쉽게 확장할 수 있나요? 변경하기 쉬울까요? 무언가를 변경해야할 경우, 프로그램의 몇 가지 부분을 수정해야 하나요?

휴대성

시스템이 특정 환경에 연결되어 있나요? 시스템을 다른곳으로 재배치해야할 경우, 많은 엔지니어링 작업 없이 이를 수행할 수 있을까요?

확장성

트래픽이 10배가 된다면, 시스템이 무너질까요? 100배가 된다면요? 시스템을 과도하게 프로비저닝해야 합니까? 아니면 자동으로 확장할 수 있을까요? 어떤 병목 현상에 엔지니어링 개입이 필요할까요?

개발 속도

시스템이 확장된다면, 얼마나 빠르게 완료할 수 있을까요? 대부분의 개발자가 그 일을 할 수 있나요? 아니면 도메인 전문가가 필요할까요?

다른 많은 엔지니어링 가치들도 있습니다. 우아함. 현대적인, 오픈소스 사용, 시스템을 운용하는데 드는 비용, 그리고 등등 이 모든 것이 중요하지만, 모든 엔지니어가 이 모든 것들을 똑같이 관심을 갖진 않습니다. 당신의 취향은 이 가치들중 높은 순서에따라 매겨집니다. 예를 들어, 당신이 개발 속도에 비해 속도와 정확성을 더 가치있게 여긴다면, 파이썬보다 러스트를 선호할 것입니다. 만약 휴대성보단 확장성을 더 가치있게 여긴다면, 호스트(AWS)의 특정 특징과 툴에 대한 많은 투자를 주장할 가능성이 높습니다. 만약 속도보다 회복성을 중시한다면, 트래픽을 여러 지역으로 나누고 싶어할 것입니다.

이러한 가치들을 보다 세부적으로 나눌 수 있습니다. 가독성을 정말 선호하는 두 엔지니어들은 서로간에 반대할 수 있습니다. 한 명은 짧은 함수를 선호하고, 다른 함수는 짧은 호출스택을 선호할 수 있기 때문입니다. 정확성을 중시하는 두 엔지니어들도 마찬가지입니다. 한 사람은 포괄적인 테스트 모음을 중시하는 반면, 다른 사람은 형식적 방법을 중시하기 때문입니다. 원칙이 같더라도, 고려해야 할 가능한 엔지니어링 가치들이 많고 이러한 값은 종종 충돌할 수 있기에, 각각의 엔지니어들은 어떤 일을 더 진지하게 받아들여야 합니다.

나쁜 취향을 식별하는 법

저는 모든 가치들이 중요하다고 말했습니다. 그럼에도 불구하고 나쁜 취향은 있을 수 있습니다. 소프트웨어 엔지니어링 맥락에서, 나쁜 취향은 작업하고 있는 프로젝트에 적합하지 않을 경우입니다.

우리 대부분은 이런 엔지니어들과 함께 이랬습니다. 그들은 당신의 프로젝트에 와서 무언가에 대해 전도합니다. 공식 방법, Golang으로 다시 작성, Ruby 메타프로그래밍, 지역간 배포 또는 무엇이든 - 왜냐하면 그것들은 그들에게 과거에 잘 작동했기 때문입니다. 그것이 당신의 프로젝트에 적합한지 아닌지는 중요하지 않습니다. 그들은 그것이 자신들이 좋아하는 것이기 때문에 그것을 주장할 것입니다. 그것을 알기전에 내부 지표 대시보드의 신뢰도가 99.999%에 달하게 되지만, 이것은 초보 엔지니어가 이해하기 어렵게 만드는 결과를 초래합니다.

다시 말하자면, 대부분의 나쁜 취향은 융통성이 없는 것입니다. 저는 "그게 최선의 관행이야"라고 말하며 결정을 정당화하는 엔지니어를 나는 항상 불신할 것입니다. 엔지니어링 선택에 "최선의 관행"은 없습니다. 당신은 특정 문제에 마주해 옳은 선택을 해야합니다.

이것의 흥미로운 결과 중 하나는 취향이 나쁜 엔지니어들이 깨진 나침반과 같습니다. 당신이 올바른 위치에 있다면, 깨진 나침반도 여전히 북쪽을 가리킬 것입니다. 당신이 움직이기 시작할 때만, 깨진 나침반은 잘못된 길로 인도할 것입니다. 비슷하게, 취향이 나쁜 엔지니어라도 자신의 선호도가 프로젝트에 필요한 것과 일치하는 특정 분야에서는 매우 효과적일 수 있습니다. 그러나 그들이 프로젝트와 직업을 옮긴다면, 또는 어쩔수없이 프로젝트를 변경해야한다면, 바퀴는 바로 떨어져 나갑니가. 오랫동안 남아있는 직업을 없습니다. 특히 2021년 이후라면 말이죠.

좋은 취향을 식별하는 법

좋은 취향은 기술적 능력보다 훨씬 더 찾기 힘듭니다. 기술적 능력과 달리 좋은 취향이란 특정 기술적 문제에 적합한 엔지니어링 가치 집합을 선택하는 능력이기 때문입니다. 그러므로 누군가가 좋은 취향을 가졌는지 식별하긴 어렵습니다. 토이프로젝트나 기술적인 사실에 대해 질문하는 것만으로는 알 수 없습니다. 거기에는 실제 문제가 필요합니다. 지저분한 현실 세계의 맥락에 포함해서 말입니다.

당신이 작업하는 프로젝트가 성공하면, 당신은 뛰어난 감각을 가지고 있다는 것을 알 수 있습니다. 프로젝트 디자인에 의미 있게 기여하지 않는다면 (단지 티켓 작업을 하고 있을 뿐), 자신이 좋은 안목을 가지고 있따는 것은 자신이 동의하는 설계 결정이 내려진 프로젝트는 성공하고, 동의하지 않는 프로젝트는 순조롭지 않다는 사실을 통해 알 수 있습니다. 중요한 점은 다양한 종류의 프로젝트가 필요하다는 것입니다. 프로젝트가 하나뿐이거나 같은 종류의 프로젝트를 반복하는 경우 해당 프로젝트에 적합할 수 있습니다. 다양한 종류의 프로젝트를 많이 진행하더라도, 익숙하지 않은 분야에 대한 좋은 취향을 가지고 있다는 보장은 없습니다.

어떻게 좋은 취향을 개발할 수 있을까요. 말하기 어렵지만, 다양한 일을 해보는 것을 추천합니다. 어떤 프로젝트가 쉽고 어떤 부분이 어려운지 주의 깊게 살펴보는 것이 좋다고 생각합니다. 당신은 유연성을 중요시해야합니다: 소프트웨어를 올바르게 작성하는 방법에 대한 강력한 보편적 의견을 갖지 않도록 노력하십시오. 내가 얼마나 좋은 취향을 가졌는지, 그것을 얻기 위해 천천히 얻을 수 있었습니다. 그래도 당신이 좋은 취향을 빠르게 익히지 못할 이유는 없다고 생각합니다. 프로그래밍 경험 이상의 감각을 가진 영재들이 다른 분야에서 그렇듯, 이 분야에도 분명히 있을 거라고 확신합니다.

편집: 이 게시물은 Hacker News에 꽤 많은 댓글을 받았습니다. 초보자와 함께 작업할 때 좋은 취향이 어떻게 적용되는지, 그리고 초보자가 이해할 수 있는 방식으로 학습할 수 있도록 돕기 위해 초보자의 취향을 약간 반영해야하는지 꽤 흥미로운 토론이였습니다. 일부 논평가들은 소프트웨어 엔지니어링에서 "취향"이 어떤 역할을 하는지에 동의하지 않았습니다. 그들은 모든 결정에는 엔지니어가 분석적으로 도달해야하는 단일한 올바른 솔루션이 있다고 믿습니다. 저는 이런 관점이 매우 당혹스럽다고 생각합니다. 주어진 엔지니어링 문제에 대해 허용 가능한 솔루션이 많이 있다는 것은 분명하고, 어느 시점에서의 선택은 개인의 선호도에 달려있습니다. 또 다른 댓글 작성자들은 내가 고객이나 사업에 대해 글을 쓰지 않았다고 합니다 - 그럴 수도 있곘지만, 저는 매우 기술적인 결정조차도 여전히 취향에 영향을 받는다는 점에 대해 쓰는데 더 관심이 있었습니다.


번역 소감

이 글의 번역하면서 공감이되는 부분들이 매우 많았습니다. 제가 생각해왔던 엔지니어링에 대해 글로써 잘 표현해준 글인 것 같습니다.

2년동안 하나의 서비스만 개발하다가, 지금은 서버개발과 풀스택 프로젝트등 다양한 영역에 도전하고 있습니다. 분야를 확장시키며 일하면서 저는 항상 "지금 중요한게 무엇인가?"라는 질문을 해왔습니다. 그런 질문을 스스로 하다보면, 프로젝트마다 답이 항상 달라진걸 느낄 수 있었어요. 풀스택 프로젝트의 경우에는 개발 속도가 중요하고, 확장성을 포기해도 좋았습니다. 백엔드를 개발했을 떄는 회복력이 매우 중요했어요. 그리고 한 플랫폼을 오랫동안 개발하는 경우에는 항상 가독성을 기둥 삼아 개발을 해왔습니다.
원문 저자가 말했듯, 매번 새로운 문제에 맞는 답을 찾는 '가치 선택 능력'이 곧 좋은 엔지니어 감각이라고 생각합니다. 그리고 더 중요한 것은 이러한 답을 어떻게 찾을 것인지 스스로 계쏙 고민하는 습관이라고 느꼈습니다.

긴 번역글을 읽어주셔서 감사드리며, 앞으로도 더 좋은 글을 번역하기 위해 노력하겠습니다. 혹시 잘못된 부분이나 의견이 있으시면 언제든 댓글 부탁드립니다.