돌멩이 하나

더닝 크루거 효과

미래에서 온 개발자 2023. 10. 20. 23:15

달력을 보니 딱 1년 전 오늘, 2022년 10월 20일이 6개월 과정 부트캠프의 개강일이었다. 

 

추석 연휴가 끝나고 지난 보름 가량 내내 씨름하고 있는 기능이 있다. 아직까지 해결하지 못했고, 근 시일 내에 해결할 수 있을 것 같지 않다. 뭐가 문제인지 파악하는 데에만 몇날 며칠의 시간을 보냈다. 이런 시간을 보내면서 부트캠프 과정이 끝나고 취업 준비를 하며 프론트엔드 기능 구현 챌린지를 할 때 시간이 걸릴 뿐 찾아보면 구현하지 못할 기능이 없을 것 같다고 자신만만해 하던 나 녀석이 떠올랐다. 유명한 더닝 크루거 곡선의 우매함의 봉우리를 향해 등반하고 있던 시절이었다고 할 수 있다. 그리고 두세 달이 지난 지금은 문제의 봉우리를 지나 절망의 계곡의 내리막길에 들어선 시간이라고 할 수 있다. 

 

더닝 크루거 곡선

 

예전 글을 뒤적여보니 작년 이맘때에 쓴 일기에도 더닝 크루거 효과를 얘기하며 다음과 같은 구절을 썼다. 

 

더닝 크루거 곡선의 우매함의 봉우리조차 아직 채 도달하지 않았기 때문에 이런 말을 하고 있는 걸 수도 있거든. 그래도 내가 무언가를 새로 시작해서 이만큼 충만한 즐거움과 몰입을 느낀다는 게 너무 기뻐. 우매함의 봉우리를 넘어서 절망의 계곡이 오더라도 지금의 기쁨을 기억하고 싶어.

 

그렇다. 그날의 기쁨을 기억하기 위해 지난 1년 간 내 자신이 얼마나 많이 걸어왔는지를 돌이켜보며 내 스스로를 칭찬해 줘야 한다. 

 

작년 11월 나는 javascript 배열의 내장 메소드 reduce의 작동 원리도 몰랐다. 하지만 지금은 map(), filter(), reduce()를 자유자재로 다룰 수 있게 되었다. map과 filter 메소드는 정말 자주 쓰지만 사실 reduce를 사용할 일은 별로 없었다. 그러다 이번주 문제의 기능 구현과 씨름하던 중 다음의 상황을 맞닥뜨렸다. 

 

1. 문장 단위의 text를 단어 단위로 분리하여 id 정보와 함께 데이터로 저장 

// 문장 예제 
const sentence = "사과는 빨개."

// 단어 단위 데이터 형태 예제
[
  {
    id: "0",
    text: "사과는",
  },
  {
    id: "1",
    text: "빨개.",
  },
];

2. 위의 데이터를 활용하여 innerHTML 값이 될 수 있는 htmlString 문자열 생성 

 

이를 위해 다음과 같은 코드를 작성하였다. 

    // 1. 문장 단위인 textContent를 단어 단위로 분리
    const words = textContent.split(' ');
    const data = words.map((word) => ({
      id: uid(), // unique id를 생성해 주는 helper 함수 
      text: word,
    }));
    
    // 2. 각 단어마다 <span data-id="${id}">{text} </span>으로 wrapping한 htmlStr으로 html 상태 갱신
    const newHtml = data.reduce((acc, cur) => {
      acc += `<span data-id="${cur.id}">${cur.text} </span>`;
      return acc;
    }, '');
    setHtml(newHtml);

 

reduce는 단순한 합산 기능(acc + cur)을 가진 메소드가 아니라 배열 정보를 하나의 값으로 만들 수 있는 메소드라는 말이 무슨 뜻인지, 하나의 값이란 그 무엇이든 원하는 값이 될 수 있는 강력한 메소드라는 말이 무엇인지를 비로소 알게 되었고, 구현할 수 있게 되었다고 느낀 순간이었다.

 

reduce를 흔히 모든 배열 내장 메소드를 구현할 수 있을 만큼 '강력한' 메소드라고 한다. 위의 기능을 구현하는 것도 사실 문장을 배열로 변환하고, 배열을 다시 문자열로 변환하는 과정의 일부라고 볼 수 있다. 이때 흔히 사용하는 방식은 split()과 join()이다. 위의 상황에서 join()을 쓸 수 없었기에 이를 reduce()로 대신한 것이다. 이처럼 .. 대신 reduce()로 치환할 수 있는 길이 많기에 reduce가 강력한 메소드라고 하는 거겠지. 

 

 

지금은 깔딱 고개를 넘은 것처럼 억지로 한숨을 돌리고 있고, 지금 내 눈앞에 놓인 길은 끝도 없는 내리막길 뿐이다. 하지만 내가 가야 할 길이 이 내리막길 뿐이기에 호흡을 가다듬는다. '나는 도대체 아는게 무언가' 싶지만 아는 게 무엇인지도 모르고, 알아야 할 게 무엇인지도 모르는 시간도 있었기에, 다음 1년 뒤에 나는 어떠한 길에 가닿을지 모르지만 그 때에 이 순간을 기억하기 위해 이 포스팅을 작성한다. 이 순간이 나의 가름끈으로 기억되기를 바란다.