프론트엔드 개발자에게 알고리즘 공부가 미치는 영향

teo.yu·2021년 12월 6일
233

테오의 프론트엔드

목록 보기
2/44
post-thumbnail

테오님 후에 '프론트엔드 개발자에게 알고리즘 공부가 미치는 영향' 과 같은 주제로 태오님의 생각을 적어주실 수 있을까요?

어떻게 보면 코딩 테스트가 개발자를 솎아내는 첫 번째 작업이라고도 볼 수 있는데, 공부를 하면서도 제가 짜는 코드에서는 전혀 사용되지 않는 것 같고.. 실무에서는 어떻게 쓰일 수 있을지? 이런 동기부여가 있으면 정말 좋을 것 같습니다…!!

오픈 채팅에서 블로그 글의 소재를 제공해주신 '이*희' 님에게 다시 한번 감사의 말씀을 드립니다.

프롤로그

질문하신 내용을 곰곰히 생각해보며 어떤 식으로 글을 쓰면 좋을지 고민해보면서 아래와 같은 대주제로 구성해보았습니다.

  1. 개발자에게 알고리즘은 어떤 의미인가?
  2. 알고리즘 공부에서 배워야 하는 것
  3. 그래서 프론트엔드 개발자에게 알고리즘 공부가 미치는 영향

@NOTE: 이번 글에서 설명하는 프로그래밍, 자료구조, 알고리즘 등의 내용은 엄밀히 말하면 맞지 않는 부분도 있을 수 있으나 쉬운 설명과 이해를 돕기 위해서 제 주관적인 해석으로 설명하고 있다는 점 알려드립니다.

디지털 카메라의 탄생 이야기

스티븐 새슨은 어린아이에 필름을 좀 더 쉽게 설명하기 위해 "빛을 담는 그릇"이라는 추상적이고 은유적인 표현을 쓰고 난 뒤 필름이 그릇이라면 그릇이 꼭 필름이어야 하는가? 라는 질문으로 이어져 디지털로 담을 수 있는 디지털 카메라를 만들었다는 이야기가 있습니다. (출처-tvN 어쩌다 어른)
(유튜브 링크를 찾을 수가 없네요. ㅠㅠ 실제 풀영상을 보시면 재밌을 거에요.)

자세한 얘기는 하지않고 풀어서 설명하는 것에 대한 근거가 되길 바라며...

비전공자도 이해할 수 있도록 최대한 풀어서 설명을 해봤습니다.

여기에서 사용되는 용어들과 해당 분야에 대해서는 꼭 검색을 통해 실제 의미를 이해하시기 바랍니다.


1. 개발자에게 알고리즘은 어떤 의미인가?

아시다시피 프론트 엔드 직군에서 알고리즘이 실무에서 사용되는가에 대한 대답은 "No." 입니다.

프론트엔드 개발의 특성상 알고리즘을 써야하는 경우가 굉장히 드물어요.

그럼에도 당연히 개발자라면 알고리즘 공부를 소홀히해서는 안된다고들 합니다. 왜 그럴까요?

단순히 코딩테스트 통과를 위해서는 아닐겁니다. (아니요 맞습니다!)

그래서 개발자가 왜 알고리즘 공부가 필요한지를 설명하기 위해서 먼저 개발자부터 시작해서 프로그램과 자료구조 그리고 알고리즘이 가지는 의미에 대해서 제 나름대로 한번 말씀 드려볼까 합니다.

위에서 언급한대로 설명을 이어나가는 빌드업 과정에서 다소 비약이 있을 수 있습니다.

개발자란 무엇일까?

개발자는 프로그램을 개발하는 사람을 뜻하죠.

프로그램을 만드는 과정을 프로그래밍이라고 합니다.

우리가 보통 프로그램을 만드는 데 필요한 도구를 언어라고 부릅니다.

프로그래밍이라는 것은 현실에서의 무언가를 컴퓨터가 이해할 수 있는 언어를 통해 전달하여 원하는 걸 만들어낸다고 생각할 수 있습니다.

프로그램은 0과 1로 이루어져 있다.

그러면 이 컴퓨터 프로그램은 무엇으로 이루어져 있을까요?

프로그램은 01로 이루어진 메모리상에 존재합니다.

뭔지는 모르지만 메모리에는 0과 1이 특별한 형태의 값들로 채워져 있겠죠. 이것을 우리는 데이터라고 부릅니다.

이 데이터가 메모리 상에 값이 그대로 유지만 되어 있다면 프로그램이라고 할 수 없을겁니다.

주변 자극에 의해 계속 변화하고 있는 형태일겁니다.

즉, 프로그램이라는 것은 어떤 외부의 자극에 의해서 메모리 상의 값들이 계속 변화되는 과정이라고 말할 수 있겠습니다.

현실의 것들을 컴퓨터에서는 어떠한 값(=데이터)으로 표현한다.

개발자의 입장에서 다시 프로그램을 이해해봅시다.

무언가 요구사항을 받아서 프로그램을 만든는 행위를 다시 정리해보면,

사람이 원하는 요구사항을 어떠한 계속적으로 변하는 값, 즉 데이터의 형태로 만들어주는 것을 의미합니다.

무슨 말이냐면 단순하게 스위치를 구현한다고 생각을 해볼게요.

현실 세계에서는 일반적으로 "스위치를 켠다. 끈다." 라고 표현을 하는데 실제 구현에서는 let isLight = false 와 같이 값으로 표현을 하죠.

즉, 켜고 끈다의 현실세계가 켜져 있음을 표기하는 메모리 어딘가의 값이 0이냐 1이냐가 들어가 있는 형태로 변경된다는 걸 알 수 있습니다.

0과 1이 모여서 '숫자'가 되고 '문자'가 되고 '배열'이 되고...

0과 1만으로는 실제 현실과는 매우 동떨어진 형태입니다. 초기 프로그래밍의 경우에는 실제로 메모리에 0과 1을 넣는 식으로 개발을 했죠. 이러한 언어를 기계어(에셈블러)라고 합니다.

이러한 방식으로는 효율적인 개발을 할 수가 없겠죠. 그래서 우리는 0과 1을 조합해서 조금더 현실세계와 유사한 형태를 만들어야 했습니다.

그래서 0과 1을 붙여서 구조를 만들어 10진수의 수를 표현하였습니다. 이제 현실의 언어와 조금 더 유사해졌습니다. 10진수를 기반으로 한 연산이 가능해졌고 이러한 자료형을 Interger(정수형) 이라고 부르게 되었습니다.

이 숫자를 알파벳과 기호에 순서대로 대응을 하여 문자(Char) 라는 구조를 만들고 이 문자가 연속적으로 결합되어 있는 자료형에 종결문자를 포함하여 문자열(String) 이라고 부르게 되었습니다.

이제는 0과 1이 아니라 숫자문자라는 구조로 값을 다루면서 이전 보다 더 쉽게 많은 일을 할 수 있게 되었습니다.

그렇게 자료구조가 되어간다.

이러한 구조들은 문자열과 숫자를 여러개가 연속적으로 연결하는 있는 구조인 배열(Array) 로 확장이 되고, 그밖에 트리(Tree), 그래프(Graph) 등 조금 더 다양하고 복잡한 형태의 구조들이 만들어지기 시작했습니다.

이렇게 0과 1보다 나은 형태의 구조를 만들고 배우는 것을 자료구조(Data Structure) 라고 합니다.

이렇게 복잡한 구조들을 만들어서 우리는 무엇을 하고자 하는 걸까요?

컴퓨터가 바로 알아 들을 수 있는 0과 1보다는 조금 더 사람이 이해하기 쉬운 구조로 만들어서 더 많은 문제를 해결하기 위함입니다.

나아가 우리가 이러한 자료구조를 만들게 되면서 조금 더 효율적인 알고리즘을 사용할 수 있게 되기 때문입니다.

그러면 알고리즘은 무엇일까요?

알고리즘은 이 자료 구조를 바탕으로 문제 해결을 하기 위한 일련의 절차입니다.

동일한 문제를 해결하기 위해서 다양한 해결책이 생길 수 있는데 같은 문제를 해결하는데 더 빠르고 더 좋은 방법이 있다면 그 방법을 택하는 것이 맞겠죠.

그래서 보통 알고리즘을 배우거나 만든다는 것은 특정 자료구조에서 가장 효율이 좋은 문제해결 방법을 찾는다는 의미입니다.

알고리즘을 찾게 되면서 기존의 자료구조가 조금 더 구조화되는 방향으로 진화하기도 하고
(가령 Tree에서 시작해 B-Tree, Red-Black Tree와 같은 새로운 자료구조가 만들어지는 것처럼요)

자료구조의 구조적인 한계로 현실 문제를 해결할 더 나은 알고리즘이 만들어지지 않는다면 새로운 자료구조를 찾아내기도 합니다.

그래서 우리가 알고리즘을 배운다는 것은 여러가지의 자료구조와 그 자료구조로 할 수 있는 문제 해결 방법중 현재까지 만들어진 가장 효율적인 방법이 무엇인가를 배우는 것입니다.

2. 알고리즘 공부에서 배워야 하는 것

꼭 알았으면 하는 것들만 추려 봤습니다. 나머지도 꼭 공부를 해 보시길 바랍니다.

O(n) 시간복잡도

알고리즘은 보다 효율적인 방법을 찾는 거라고 했습니다. 그렇다면 어떤 알고리즘이 더 좋은지 비교할 수 있는 방법이 필요하겠죠. 그러기 위해서는 기준이 필요합니다. 기계의 성능이나 언어의 성능은 고려되어서는 안되겠죠. 그래서 만들어 낸것이 시간 복잡도라는 개념입니다.

자세한 내용은 확인해보시고 요약하자면 해결하고자 하는 문제에 필요한 입력량 대비 걸리는 시간을 함수로 표현해서 함수가 급격히 기울어 질 수록 나쁜 알고리즘입니다.

선형검색과 이진검색(반띵전략)

맨 처음에 배우는 것은 배열에서 원하는 특정 숫자를 찾는 행위입니다. 100개의 배열에서 1개의 값을 찾기 위해서는 최악의 경우 마지막에 있어서 총 100번을 확인해야 합니다.

만약에 이 배열의 값이 순서대로 정렬이 되어 있다는 사실을 알고 있다면 어떻게 하시겠나요?

어릴때 숫자 맞추기를 했던 게임처럼 50보다 큰지 작은지 반을 잘라서 물어보고 이후 25보다 큰지 작은지 등 점점 반씩 줄여가면서 찾게 되면 7번만에 찾을 수 있습니다.

이렇게 반씩 줄여가는 전략은 향후 배울 모든 알고리즘을 한단계 더 효율적으로 만들어주는 근간이 됩니다.

정렬: 순서대로 줄세워보자.

그리고 나서 배우는 것들은 각종 정렬을 하는 방법에 대해서 배우고 됩니다.
정렬은 순서대로 줄을 세우는 것이죠.
아는 사람은 정답을 알고 있겠지만 한번 생각해보세요.

[2,1,8,9,7,4,10] 이 있을때 어떻게 만들면 순서대로 정렬할수 있을까요?

그리고 어떤 방식이 가장 효율적일까요?

누구나 생각하는 그 방법: 선택정렬(Selection Sort)

대부분의 사람들이 일반적으로 생각하는 방법은 선택정렬이라고 불리는 방법입니다.

배열에서 제일 작은것을 선택해서 맨앞으로 보내고 남은 것들 중 또 제일 작은 것을 선택해서 2번째에 놓고 이렇게 하는 방식입니다.

현실세계에서도 쉽게 활용하고 있는 우리가 보통 책을 순서대로 정리할때 잘 쓰는 방법이죠.

시간 복잡도는 어떨까요? 처음에는 n번, n-1번, n-2번, ... 1번 까지.. O(n^2)이 필요합니다.

구현은 생략하도록 하겠습니다.

그렇다면 좀 더 나은 방법은 없을까요?

좀 더 복잡하지만 빠른 방법: Quick Sort!

퀵 소트는 그냥 눈으로 봐서는 혹은 설명을 듣고서는 이게 어떻게 동작하는지 알기 쉽지 않습니다.
왜냐하면 현실세계에서의 개념에서는 이런식으로 정렬을 하지 않기 때문이죠.

하지만 보다 컴퓨터스러운 방식으로 생각한다면 보다 효율적인 방법을 찾을 수 있었습니다.

QuickSort는 O(nLogn)의 시간복잡도를 가지며 앞서 언급한 선택정렬에 비해 훨씬 더 적은 횟수로 정렬이 가능합니다

구현이나 자세한 설명 역시 생략하겠습니다. 궁금하면 꼭 찾아보세요!

그래서 알고리즘 공부가 왜 필요한가?

현실 세계의 문제를 현실을 방식을 본따 그대로 만들었는데 그 성능의 비용이 비싸다면, 조금 더 컴퓨터스럽게 생각하는 방법을 통해서 최적화하는 방식을 배우기 위해서 입니다.

체스는 이미 컴퓨터로 모든 경우의 수를 파악해서 컴퓨터가 무조건 이길 수 있는 알고리즘이 만들어졌습니다. 하지만 바둑은 그 경우의 수가 너무 많기 때문에 알고리즘으로 정복할 수 없는 분야라고 생각했었죠.

하지만 다른 접근을 통해 AI라는 자료구조와 알고리즘을 통해 현실의 문제를 해결하는 방법을 찾을 수 있었습니다. 이렇듯 현실의 문제 해결 방식을 해결할 수 있는 방법을 찾고 또 최적화 하는 것을 하려는 개발자에게는 알고리즘 공부가 반드시 필요할 것입니다.

또한 이렇게 만들어진 알고리즘과 자료구조를 다른 개발자들에게 사용할 수 있도록 제공해서 알고리즘의 상세 구현은 몰라도 그냥 사용하기만 하면 되고 이를 통해서 더 새로운 가치를 고민할 수 있도록 해 주는 것이죠.

디자이너가 포토샵이 어떻게 구현되어 있는지는 몰라도 포토샵을 통해 새로운 가치를 만들어 낼 수 있는 것처럼요.

저희가 Array.prototype.sort()를 사용할때 내부 구현이 뭘로 되어 있는지 관심이 있지는 않죠.

그렇다면 프론트엔드는 알고리즘을 몰라도 되지 않나요?

디자이너가 포토샵의 세부 구현을 몰라도 되듯이 프론트엔드 개발자는 알고리즘이나 자료구조의 세부구조를 좀 몰라도 되지 않을까요?

분명 프론트엔드 개발자가 추구하는 개발의 방향은 컴퓨터스러운 방식이 아닙니다. 오히려 최적화를 덜 하고 보다 기획서에 가깝게 사람에 가깝게 코딩을 하는 방식을 더 추구합고자 합니다. 분야의 특성상 코드의 최적화보다 가독성을 훨씬 더 중시하고 더 사람에 가깝게 만드는게 더 중요합니다.

그러니 자료구조와 알고리즘을 개발하기 보다는 그러한 자료구조와 알고리즘을 잘 이용하는게 중요한 직군이라고 할 수 있습니다.

그러면 알고리즘이 덜 중요한 분야는 알고리즘이나 자료구조의 공부가 의미가 없을까요?

개발자라는 직업의 본질을 다시 떠올려 봅시다. 개발자는 현실의 문제를 컴퓨터가 이해할 수 있는 데이터로 바꾸는 작업을 한다고 말씀드렸습니다.

그리고 우리는 이미 잘 만들어진 자료구조와 알고리즘을 배우고 알고 있습니다.

이게 어떤 의미일까요?

⭐️ 우리가 현실의 문제를 이미 만들어진 자료구조 속의 세계관까지만 끌고 오면 자료구조의 문법으로 해당 문제를 바라 볼 수 있고 이미 해결된 좋은 방법으로 문제를 해결할 수 있다!

라는 겁니다.

맨 처음 언급한 개발자와 언어라는 관점에서 자료구조와 알고리즘은 컴퓨터와 소통하는 일종의 언어인 셈입니다.

3. 그래서 프론트엔드 개발자에게 알고리즘 공부가 미치는 영향

  1. 프론트엔드 개발자의 능력인 기획의 요구사항을 String, Array, Object와 같은 형태의 값으로 만들어내는 과정을 하는데 있어서 이것을 센스를 그냥 타고 나는 사람들도 있지만 알고리즘과 자료 구조를 배우다보면 현실의 생각을 컴퓨터스럽게 데이터로 사고하는 능력을 간접적으로 익힐 수가 있습니다.
  1. 또한 프론트엔드라고 해서 알고리즘을 사용한다거나 최적화 작업이 아예 없을 수는 없습니다. 프론트엔드가 최적화가 필요한 경우에는 어떠한 알고리즘이 있는지를 알아야 아니라 알고리즘을 최적화 하는 원리인 분할정복, 동적계획법, 탐욕법 등에 대해서 알아야 할 경우가 있습니다.

NOTE: React에서 사용하는 useMemo와 같은 최적화 역시 동적계획법(Dynamic Programming)파트인 Memoization이라는 기법을 사용하고 있는 것입니다.

프론트엔드의 경우 사실상 실무에서 그래프 이상의 자료구조를 사용하는 경우가 드뭅니다.

이러한 알고리즘 공부에 대한 의미를 이해하시고 내가 어디까지 알고리즘과 자료 구조를 깊게 팔 것인가를 전략적으로 공부하는 것이 필요합니다.

그래서 어떠한 알고리즘이 있는지 사전적인 공부보다는 현실문제를 어떤식으로 데이터로 생각하고 어떠한 접근법으로 최적화를 하는가에 대한 공부를 한다고 생각하시며 공부하시길 바랍니다.

적어도 해 본사람과 안해본 사람의 컴퓨팅 사고력 차이는 확실히 있다고 말씀드릴 수 있어요.

끝으로...

프론트엔드도 가끔 복잡한 화면을 만들어야 할 때가 있다. (아직도 개선이 필요합니다. ㅠㅠ)

일단 자료구조와 알고리즘을 한번이라도 이해하고 이러한 세계가 있다는 것을 알면 조금 더 컴퓨터스럽게 사고하는 것이 가능해집니다. 누구는 이게 너무 당연할 수도 있고 누구는 이해하기 어려울 수도 있습니다.

하지만 이것은 선천적인게 아니라 요구사항을 데이터로 생각하는 사고력과 조금더 최적화 할 수 있는 방법을 찾는 능력은 알고리즘과 자료구조를 배우고 또 연습하고 익힐 수가 있는 것입니다.

물론 알고리즘과 자료구조의 중요도가 프론트엔드의 다른 스킬적인 부분에 비해 중요도가 높지 않습니다. 그러니 적절히 공부 분배에 전략적으로 투자하시기 바랍니다.

코딩 테스트를 통과 하기 위해서 열심히 공부하는 것도 추천합니다. 코딩 테스트의 문제들은 주어진 지문을 읽고 적절한 자료구조와 알고리즘을 찾아내는 연습을 하도록 설계되어 있습니다.

회사에 입사를 하고 나면 정작 코딩 테스트용 문제를 공부 할 수 있는 동기부여가 잘 되지 않습니다. 그러니 어차피 한번 준비할때 잘 공부하면 좋지 않을까요?

알고리즘의 실전성에 앞서 우리는 개발자니까 컴퓨터스럽게 사고하는 법을 익혀두면 직간접적으로 본인의 개발 능력에 영향을 끼치는 바가 있을거에요 :)

이 글이 프론트엔드 개발자가 알고리즘 공부를 해야 하는 것에 대해서 동기부여가 되기를 바랍니다.

궁금하신 내용이 있다면 댓글이나 오픈 채팅에 오셔서 글 남겨주세요. 즐거운 마음으로 답변 해드리겠습니다.

카카오톡 오픈 채팅
https://open.kakao.com/o/gNxDSCLd

profile
AdorableCSS를 개발하고 있는 시니어 프론트엔드 개발자입니다. 궁금한 점이 있다면 아래 홈페이지 버튼을 클릭해서 언제든지 오픈채팅에 글 남겨주시면 즐겁게 답변드리고 있습니다.

20개의 댓글

comment-user-thumbnail
2021년 12월 6일

웹 프론트엔드 개발자를 꿈꾸는 학생으로써 취업을 위한 프로세스 중 일부인 코딩 테스트를 피할수만은 없을 거라고 생각합니다. 그래도 너무 어렵고, 동기부여가 계속 떨어져서 코테 준비를 등한시 했던 것 같았습니다.

짧다면 짧은 질문이었음에도 이렇게 좋은 글을 태오님의 시간을 투자해서 작성해주시니, 너무 감사합니다 ㅎㅎ 좋은 개발자가 되기 위해 더 열심히 해봐야겠네요!!

1개의 답글
comment-user-thumbnail
2021년 12월 7일

오늘도 좋은 글 읽고 많이 배워갑니다!! 혹시 테오님은 풀스택 개발자에 대해서 어떻게 생각하시나요?? 프론트도 재밌고 백엔드도 재밌는데 둘다 하려고 하니 T자형 개발자가 되기 힘들고, 또 "풀스택개발자는 상상속 유니콘이다" 라는 말도 있어서 테오님은 어떻게 생각하시는지 궁금합니다!!

1개의 답글
comment-user-thumbnail
2021년 12월 7일

물리학과를 졸업했지만 지금까지 전공과 관련 없는 일들을 해와서 누군가는 전공 시간 아까워서 어떡하라는 말을 하기도 했었어요. 그럴때마다 대학 이후 제가 생각하는 방식이나 세상을 바라보는 방식에 큰 영향을 주었다고 말하곤 했거든요.
프론트엔드 개발자에게 알고리즘 공부도 비슷한 관점인 것 같네요. 컴퓨터스럽게 사고하는 법을 익히는 과정이라고 생각하니 동기가 조금 더 생긴 것 같습니다 ㅎㅎ
좋은 글 감사합니다!

1개의 답글
comment-user-thumbnail
2021년 12월 8일

감사히 잘 읽었습니다 :) 현업에 종사하면서도 느끼는 부분이었는데, 왜 알고리즘 공부가 필요한지 다시금 일깨워준 좋은 글이었습니다!

1개의 답글
comment-user-thumbnail
2021년 12월 11일

코딩테스트는 성실성테스트라고 생각하곤 합니다. 실무에서는 하기 싫은 걸 참고 문제를 해결할 때까지 구글링 해야 하는 끈질김이 요구되는데 코딩테스트만큼 그만한 인내심과 성실함을 테스트 할 수 있는 게 없죠 ㅋㅋㅋ

1개의 답글
comment-user-thumbnail
2021년 12월 11일

좋은글 정말 잘 읽고갑니다!!

1개의 답글
comment-user-thumbnail
2021년 12월 15일

좋은글 감사합니다 ^^

답글 달기
comment-user-thumbnail
2022년 1월 1일

프론트엔드 개발자 지망생입니다..! 써주신 좋은 글 덕분에 알고리즘 학습의 근본적인 필요성을 다시 한번 느끼게 되었고... 비전공자이기에 항상 결핍을 느끼고 있는 컴퓨팅 사고력을 후천적인 노력으로 키울수 있다는 동기부여 또한 얻어갑니다! 감사합니다~

1개의 답글
comment-user-thumbnail
2022년 7월 26일

안녕하세요. 좋은 글 써주셔서 감사합니다.

작은 회사들을 돌아다니면서 주로 Node로 서비스를 만들어왔습니다. 백앤드 업무와 프론트앤드 업무를 둘다 반반씩 찍먹해본것 같습니다. 각각의 포지션은 서로 다른 매력이있는거 같아요. 생각해야하는 방향도 많이 다른거 같구요. 둘다 매력적이라고 생각하다보니 양쪽다 놓지 못한 상태로 경력을 쌓아가게 되었습니다. 이제 5년차로 넘어가는데 어느쪽으로 확실히 진로를 잡아야할지 아직도 고민입니다. 혹시 프론트앤드로 전향하신 계기를 여쭤보아도 될까요?

1개의 답글