엔지니어가 되는 법, 프레임워크 마스터가 아닌 진짜 개발자가 되는 5가지 방법

엔지니어가 되는 법, 프레임워크 마스터가 아닌 진짜 개발자가 되는 5가지 방법
Cozy CodingPosted On Jul 12, 20248 min read

이미지

이 기사는 자아개선을 부탁하는 내용입니다. 이것을 할 수 있어요. 엔지니어가 되어보세요.

항상 주의할 점은 엔지니어들은 분명히 프레임워크를 사용해야 하고 사용합니다. 이것들은 작업을 보다 유지보수 가능한 방법으로 수행하도록 도와주는 아름다운 기술 조각들입니다. 프레임워크는 이 기사의 적이 아닙니다. 브라보, 프레임워크. 그만 할게요.

죄송한데, 프레임워크가 뭐죠? 프레임워크는 특정 유형의 소프트웨어 프로젝트를 완료하기 위한 기본 구조를 제공하는 소프트웨어 도구입니다. 따라서 TypeScript로 단일 페이지 웹 앱을 작성하려면, Angular가 있기 때문에 처음부터 해결할 필요가 없습니다. Python으로 머신 러닝을 하고 싶나요? 저의 친구들 Scikit-Learn과 Keras를 소개해 드릴게요. C#로 백엔드를 작성하려고 하시나요? (오, 멋져보이시네요.) ASP.NET에 대해 이미 알고 있으리라고 생각합니다. 이를 1500 단어 더 할 수 있지만, 아이디어를 얻었으니까요.

프레임워크를 알고 있으면 종종 "엔지니어"라는 제목을 가진 직업을 얻을 수 있습니다. 그리고 "머신 러닝"이라는 단어도 있을 수 있습니다. 두 개의 프레임워크를 알고 있다면, "풀 스택"이라는 단어가 제목에 포함된 직업을 얻을 수도 있습니다. 그러나 다음 직장에서 성공을 거둬야 한다면, 프레임워크보다 깊은 기술 세트가 필요합니다. 이력서에 3~5년의 "엔지니어링" 경험이 있는 경우에만 고용되는 직장에서 성공하려면 깊이 파고들어야 합니다. 그렇지 않으면 90일 후 리뷰 때 아주 불편한 의자에 앉아 있어야 할 것입니다.

여행을 떠나야 할 수도 있습니다. 프레임워커에서 프로그래머, 그리고 엔지니어로. 각 단계를 살펴보겠습니다. 각각을 설명하고 그 단계의 전문적인 발전이 어떤 모습인지 이야기하겠습니다.

프레임워커

프레임워크(또는 두 개)에서 주로 작업한다고 해서 반드시 프레임워커가 되는 것은 아닙니다. 그러나 당신이 프레임워커일 수도 있습니다.

프레임워크를 사용하면 Frameworker(프레임워크 사용자)가 선반 유닛을 만드는 방법처럼 소프트웨어 제품을 구축할 수 있습니다. 작업이 완료될 때 저는 선반 유닛을 만들었나요? 네. 그렇다면 저는 슈퍼 간단하게 스스로를 선반 엔지니어로 묘사해야 할까요? 아마도 그렇지 않을 것입니다.

Frameworker가 부족한 점은 무엇인가요?

프로그래밍 언어 지식

Frameworker들은 일반적으로 프레임워크가 작성된 프로그래밍 언어에 대한 꽤 기초적인 지식만 갖고 있습니다. 게다가, 프레임워크는 많은 유형의 프로그래밍으로부터 사용자를 보호하기 위해 의도적으로 추상화를 제공하기 때문에 그들이 지식 부족을 인식하지 못할 수 있습니다. 그래서 Frameworker는 제한된 프로그래밍 도구 상자로 소수의 문제를 해결하는 데 많은 경험을 쌓게 됩니다.

지식의 깊이

프레임워커들은 프레임워크를 사용하여 해결하려는 소프트웨어 문제에 대한 지식의 깊이가 부족합니다. 프레임워크는 소프트웨어 제품의 개념을 실현하는 특정 방법(구현)을 나타냅니다. 이러한 저수준 구현은 일반적으로 추상화되며, 프레임워크 사용자들은 기본 클래스, 데코레이터 및 [자동 생성된] 템플릿을 통해 코드를 하부 구현에 삽입하는 몇 가지 직접적인 방법을 제공받습니다.

프레임워커들은 종종 프레임워크의 기본 원리를 이해하지 않고도 프레임워크를 능숙하게 다룰 수 있습니다: 디자인 패턴, 알고리즘(CS 또는 ML), 비동기 또는 분산 프로그래밍 등의 기본 개념을 몰라도요. 때로는 이러한 기본 개념을 이해하는 것이 프레임워크의 오용을 방지함으로써 즉각적인 혜택을 줄 수 있지만, 종종 지식의 깊이가 없어도 프레임워크를 충분히 사용할 수 있습니다. 그러나 이러한 "더 깊은" 지식은 가치가 있습니다. 일단, 이러한 지식은 거대하게 이전 가능합니다 - 특정 소프트웨어 제품의 특정 도메인뿐만 아니라 모든 종류의 프로그래밍 간에 이동할 수 있습니다. 더욱이, 이러한 지식의 깊이가 없다면 프레임워커는 특정 프레임워크 선택이 프로젝트 요구 사항을 충족할 수 있는지 여부를 결정하는 데 잘 갖추지 못합니다.

하지만 이 모든 것이 중요한가요?

Frameworking 결과

Frameworking은 Frameworker의 경력 및 그들이 속한 조직에 부정적인 영향을 미칩니다. Frameworker는 병합하기에 충분히 좋은 프레임워크 코드를 작성하는데 있어서 능력이 부족하여 장기적으로 유지 및 확장 가능성 테스트를 통과할 수준이 미흡한 림보(중간 상태)에서 작업합니다. 많은 미성숙한 절차적 코드가 바로 올바른 위치에 들어가고, 익숙하지 않은 문제들은 안티-패턴으로 처리되며, 조직의 코드 품질은 하향으로 드리프트(drift)하게 됩니다.

그러나 경력적인 관점에서, Frameworker의 전망은 더욱 어두운 것 같습니다. 전송 가능한 동일한 기술 세트(즉, 프레임워크 사용)를 가진 개발자들은 매일 약 50개의 새로운 "온라인 학원"에서 대규모로 배출되고 있습니다. 그리고 만약 Frameworker가 꿈에 그리던 직장을 찾아 맞게되면, 더 흥미로운 프로젝트를 수행할 기회를 얻게되었을 때, 그들의 지식 차근들이 드러나는 순간이 오게되는 떡밥을 경험할 수도 있을지 모릅니다.

부록: 그렇게 되면 그냥 매니저가 되었을 수도 있습니다. 그런 경우 그들은 아마도 놀라운 성과를 거둘 것입니다.

프레임워커가 엔지니어가 되고 싶을 때 어떻게 해야 할까요? 저는 그들이 프로그래머가 되는 것으로 시작하는 것을 제안합니다.

프로그래머

이 글의 전제에 다소 독특한 의미로 프로그래머라는 용어를 사용하려고 합니다. 프로그래머는 코드 속에서 살아가는 사람입니다. 그 모호한 표현으로 두 가지를 의미합니다:

  • 프로그래머는 많은 양의 코드를 읽습니다.
  • 프로그래머는 다양한 종류의 코드를 많이 작성합니다.

한 가지씩 차례로 살펴봅시다. 그리고 조금 더 친밀하게 다가갈게요. 여기서부터는 ‘너’라는 호칭을 사용하겠습니다.

프로그래머는 많은 코드를 읽고 있어요

많은 사람들이 말하는 것처럼 좋은 코드를 읽는 것은 좋은 코드를 작성하는 방법 중 하나라고 알려져 있어요. 초보자일 때는 새로운 문법 요소를 배우는데 좋은 방법입니다. 특정 프로그래밍 언어의 관용구를 익히는 데도 중요해요. 예외 사항을 처리하고 예외 상황을 다루는 방법을 전문가처럼 익힐 수 있답니다. 하지만 코드를 많이 읽는 가장 좋은 이유가 하나 더 있어요.

코드를 읽는 가장 좋은 이유는 엄청 많은 코드를 읽는 데서 발전하는 거예요. 새로운 코드를 효율적으로 읽고 이해하는 능력은 엔지니어가 가져야 하는 가장 중요한 기술 중 하나일 거예요 (그리고 프로그래머는 엔지니어로 나아가고 있어요.) 핵심 스택을 이루는 기술, 언어, 라이브러리가 끊임없이 변화하고 있기 때문에 이 능력이 더 중요해집니다. 물론 좋은 문서가 필요할 때도 있겠지만, 직접 코드를 읽어서 이해하는 능력은 교체할 수 없는 게 있는 법이죠. 특히 새로운 직장으로 이동할 때는 그런 능력이 더욱 중요해질 거예요.

운이 좋게도, 거기에는 읽을 수 있는 많은 코드가 있습니다. 그리고 두 번째 일을 하면서 만날 수 있습니다.

프로그래머는 다양한 종류의 코드를 많이 작성합니다

Frameworker 루틴에서 벗어나는 한 가지 방법은 여러 가지 유형의 코드를 작성하는 것입니다. 이는 반드시 여러분이 다른 유형의 앱을 작성하고 있다는 것을 의미하지는 않습니다. 예를 들어, Python에서 기계 학습을 한다면, ML 알고리즘을 직접 구현하는 사이드 프로젝트를 가질 수 있습니다. (C/C++에서 작업한다면 보너스 포인트를 드립니다.) 하지만 물론 이것은 여러분이 다른 유형의 앱을 작성하고 있다는 것을 의미할 수도 있습니다. 매일 실행하는 일부 스크립트 위에 데스크탑 GUI를 작성해 보는 등 재미로 시도해보세요. 웹 프론트 엔드를 만드시나요? 텍스트 기반 RPG를 작성해 보세요.

주의할 점은 단순히 한 프레임워크에서 다른 프레임워크로 전환하고 싶지 않다는 것입니다. 여러분은 배우려고 노력하고 있습니다. 여러분은 보통 사용하는 수준보다 낮은 수준에서 프로그래밍 언어를 사용하고, 그 위에 자체 추상화 계층을 만들어야 합니다. I/O, 소켓, 이벤트 루프, 버퍼, 해시 생성, 꼬리 재귀와 같은 내용에 대해 학습해야 합니다. 추상화 계층을 추가할수록 다형성, 상속, 인터페이스, 상태 머신, 디자인 패턴과 같은 내용에 대해 학습해야 합니다. 그리고 어휘력을 키워가야 합니다.

에, 엔지니어가 되는 시기는 언제일까요?

프로그래머로서의 한계

프로그래머로써, 코드로 할 수 있는 것들 중에는 프레임워커로써는 불가능했을 것들이 많이 있음을 알게 될 것입니다. 하지만 몇 가지 놀라운 일을 할 수 있지만 여전히 훌륭한 엔지니어가 되기엔 미흡할 수 있습니다.

부품으로 자동차를 직접 만든다고 상상해보세요. 그러나 자동차를 조립할 때마다 한 고정 부품을 다른 부품에 부착할 때 너트와 볼트 대신에 용접을 사용한다고 가정해봅시다. 정말로 잘 작동하는 자동차를 만들어낼 수 있을 것입니다. 적어도 처음에는요. 그러나 어떤 것이 고장 나면서 그것에 접근하기 어려운 상황이 생기면 상상해보세요 — 그것에 접근하려면 다른 부품들을 제거해야 한다고 합니다. 그 모든 용접은 나쁜 선택이었던 걸요. 자동차의 한 부분만 업그레이드하려고 할 때 상상해봅니다 — 그 한 부분만 쉽게 떼어내고 새 부품을 끼울 수 있으면 참 좋을 것입니다.

프로그래머(이 경우의 의미로)인 것은 좋은 공학 원칙을 완전히 무시했다는 뜻은 아닙니다. 그러나 프로그래밍 단계의 목표는 공학 단계와는 다릅니다. 프로그래밍이 특정 기술을 습득하는 데 직선적인 여정이었다면, 엔지니어가 되는 것은 단호한 우회전입니다. 비유를 바꾸자면, 언어 습득처럼 생각할 수 있습니다: 프로그래머로서는 일하는 언어에 대해 원어민처럼 유창함을 기르고 있습니다. 엔지니어로서는 학문적 글쓰기를 시작할 것입니다.

엔지니어

그렇다면 엔지니어를 정의하는 우선순위의 이 미스터리한 전환은 무엇일까요? 엔지니어는 안정성과 변경을 균형있게 유지하는 소프트웨어를 계획하고 작성합니다. 안정성은 명확한 개념이며, 많은 프로그래머들이 코드에서 제공합니다. 변경할 수 있는 코드를 계획하는 것은 더욱 소극적입니다. 둘을 균형있게 유지하는 것이 당신을 엔지니어로 만드는 요소입니다.

안정성

대부분의 사람들은 안정성의 주요 개념을 이해합니다: 첫 번째 개념은 소프트웨어가 하는 일이 무엇인지 알아야 한다는 것입니다. 버그가 없어야 합니다. 신뢰할 수 있어야 합니다. 두 번째 개념은 소프트웨어 사용 방법이 급속하고 빈번하게 변하지 않아야 한다는 것입니다. 이것은 두 가지 면에서 참되며, 인터페이스는 시간이 지나도 비교적 안정적이어야 하며, 인터페이스는 소프트웨어 전체에서 일관되어야 합니다.

더 많은 시간을 쏟지는 않겠지만, 인터페이스라고 할 때, 내가 넓게 참조하는 것을 강조할 뿐입니다 - 이것은 명시적으로 선언한 것을 의미할 수 있습니다(C/C++의 헤더 또는 Java/C#의 인터페이스 등.), 데이터 유형과 객체 이름의 일관된 집합을 의미할 수 있으며, 상태나 작업 중 상호 작용되는 객체 이름으로 Python, Scala 등에서 나타낼 수 있으며, "비즈니스" 사용자가 경험하는 그래픽 인터페이스를 의미할 수도 있습니다. 안정적인 인터페이스 정의는 안정성 자체뿐만 아니라 변경을 고려할 때에도 매우 중요합니다.

변경

엔지니어는 변화를 수용할 수 있는 방식으로 소프트웨어를 작성합니다. 보다 정확하게 말하면, 엔지니어는 소프트웨어가 어떻게 변할 필요성이 있을지 미리 예측하고 그에 맞게 작성합니다. 미래를 예측하는 능력은 분명히 성장하는 능력이지만, 여기서 언급할 만큼 보편적인 여러 유형의 변경 사항이 있습니다.

버그. 엔지니어는 그들이 만드는 모든 소프트웨어에 문제가 있는 것으로 가정합니다. 버그를 고치기 위해서는 코드가 조직되어 있고 가독성이 높아야 하며 로깅을 사용해야 합니다. 여기서 자세히 다루지는 않겠습니다. 최소한, 엔지니어는 코드를 재사용 가능한 블록으로 구성하는 방법을 알고 있어야 하며, 그것이 함수든 클래스든 상관없이 코드 블록을 느슨하게 결합하는 방법을 알고 있어야 합니다. 이렇게 하면 버그가 가능한 한 격리되고 변경해야 하는 항목이 제한적해집니다.

데이터와 동작으로서의 사용 사례. 한 번 MVP를 개발 중인 팀 리더와 통화 중이었을 때 기억이 납니다. "이 소프트웨어를 구성 파일을 참조하여 다른 클라이언트에서도 사용할 수 있도록 설계했나요, 아니면 다른 클라이언트를 위해 이를 사용하기 위해 추가 소프트웨어 개발이 필요할까요?" 라고 물었더니 전화 한통이 오래 걸렸고, 그 순간 제가 알아야 할 모든 것을 알게 되었습니다. 엔지니어가 프로젝트 요구 사항을 수집할 때 - 심지어 MVP일 때도 - 그들은 필요한 동작을 지속적으로 평가하여 데이터 레이어로 캡처할 수 있는 방식으로 변경될 가능성이 있는 동작인지를 판단합니다.

예를 들어. 클라이언트 A가 엑셀 파일로 데이터를 이메일로 보내주고 공유 드라이브에 내려받았을 때, 클라이언트 B에는 API가 있고 클라이언트 C는 FTP에 연결하여 CSV 파일을 다운로드합니다. (지금은 비즈니스 테크 통합에서 발생할 수 있는 문제는 무시하세요.) 여기에는 세 가지 다른 동작이 있습니다. 당신의 소프트웨어는 이 세 가지를 모두 지원할 수 있고 구성 파일(각 클라이언트용 하나씩)을 사용하여 어떤 동작을 사용할지 식별할 수 있습니다. 그리고 클라이언트 C가 마침내 API를 구해올 때, 소프트웨어 개발이 필요하지 않습니다. 그저 그들의 구성 파일에서 FTP 정보를 그들의 API 정보로 교체하면 됩니다.

이 모든 것은 엔지니어인 당신이, 개발 시작부터 공유 드라이브에서 엑셀 파일을 가져오는 것이 변화할 가능성이 있는 동작임을 알았기 때문에 가능합니다. 따라서 당신은 데이터 가져오기를 하드코딩이 아닌 추상화를 통해 처리하기 위해 소프트웨어를 계획했습니다. (웃지만, 제가 보았던 일들이 있었죠...) 그리고 구성을 처리하는 데이터 레이어를 정의하였습니다.

확장성. 일부 시나리오에서는 사용 사례가 예상 이상으로 크게 변경되거나 지원할 의지가 있는 한계를 넘어설 수 있습니다. 이전 예시를 계속 살펴보면, 모든 다른 클라우드 제공 업체의 블랍 저장소에 대한 데이터로더를 지원하고 싶지 않을 수도 있습니다. 데이터 로드를 위한 인터페이스를 명확하게 정의했다면 그럴 필요가 없습니다. 하위 개발자들은 여전히 S3로부터 데이터를 가져오기 위해 인터페이스를 구현하는 코드를 작성함으로써 여러분의 소프트웨어를 사용할 수 있습니다. 그만큼 개발자에게 개방된 기회를 제공했다면요. 이를 위한 여러 가지 방법과 도움이 될 수 있는 여러 가지 개념들이 있습니다 (상속, 의존성 주입, 제네릭, 심지어 덕 타이핑). 엔지니어는 계획할 수 있는 범위를 넘어서 확장 가능한 소프트웨어를 작성할 수 있습니다.

결론

그렇다면 여러분의 여정은 어디쯤인가요? 입문 단계 이력서를 넘어서 이미 직함에 포함된 "엔지니어"라는 단어에 진지성을 부여하고자 준비되었나요? 엔지니어가 되는 것이 종착점이 아니더라도, 프레임워크를 벗어나고 싶다면 훌륭한 시작점입니다.