안녕하세요,

저는 김인수입니다.

강남·판교에서 웹 엔지니어로 일하고 있습니다. 실무에서 주어진 문제를 구체적으로 어떤 기술을 사용해서 해결할 지를 고민하고 해결합니다.

Work Experience.

경력 기술서

마크베이스.

정규직 프론트엔드 엔지니어
2021. 01. 25 - 현재()

책임 업무
machbase 회사의 대표 제품인 'edgemaster 웹 솔루션' 웹 개발하고 있습니다.
제가 이 제품을 위해서 할 수 있는 일을 스스로 찾아서 작업합니다. 코드를 유지보수가 쉽도록 수정하고, UI를 개선합니다. 현재는 제품의 Front-end 테스트 코드를 작성하고 있습니다.

마크베이스 경력기술서 보기

프로젝트명 : 베트남 외주 제품 내제화 및 병합 🇻🇳


기간 : 2021. 06. 11 - 2021. 07. 03
서버없이 데이터 시각화 차트 feature를 프론트엔드 부분만 외주로 개발된 제품입니다. 시니어 개발자가 개발한 코드여서 코드를 분석하면서 많이 배울 수 있었습니다.

제품 기능

  • 센서 데이터 시각화 차트

  • 사용자가 자유롭게 차트의 크기 및 배치 조작

  • 막대, 텍스트, 선, 도넛형으로 종류 별로 차트 생성

  • 그래프 구간을 확대해서 상세 데이터 보기

책임 업무

repository 코드 분석 및 기존 제품에 기능 반영 - 기여 100%

개발 환경

  • Window
  • GitHub
  • VSCode

개발 언어/패키지

  • Vue.js
  • Vue CLI
  • Vuetify
  • Vuex
  • Axios
  • Chart.js
  • Hammer.js

성과🏅

  • 대표 제품인 edgemaster에 적용

  • 기존 제품과 앞으로 개발하게 되는 제품에 배운 점 적용

🇻🇳 베트남 시니어 개발자에게 배운 점

저와 비슷한 경력을 가지는 개발자들과 일하다 보니, 시니어 개발자의 코드를 볼 일이 없었습니다. 마침, 외주로 시니어 개발자에게서 제품 개발 코드를 받아 볼 수 있었습니다. 외주 제품 코드를 계속 읽고, 배울 부분을 문서로 정리해서 팀에 공유했습니다.

프로젝트명 : edgemaster


기간 : 2021. 01. 25 - 현재()

기여도 : 프론트 엔드 개발 70%

회사의 대표 웹 솔루션 제품입니다. edgemaster는 공장 기계에 부착된 센서(edge)를 제어·이상 감지·데이터 수집·데이터 시각화 기능을 제공하는 웹 솔루션입니다.
dashboard page
map page

제품 기능

  • 센서를 웹 솔루션 서버에 등록/제거

  • 센서 이상 감지 상황 표시, 알림 및 이메일 전송

  • 센서 데이터 시각화 차트

  • 날짜 기간/센서 타입/데이터 타입 조건 선택으로 리포트 조회 페이지

  • 센서 데이터 리포트를 위한 차트 페이지

  • 센서 장비 등록 위치를 map(이미지)에 마킹 및 조회

개발 환경

  • Linux
  • Window
  • Gitlab
  • VSCode

개발 프레임워크/언어/패키지

  • Vue.js
  • Vue-CLI
  • Vuetify
  • Vuex
  • Axios
  • Javascript
  • CSS
  • SASS(SCSS)
  • Apex chart
  • Vuelidate
  • JQuery

성과🏅

  • 팀 내 기술 공유 -제품 코드 개선을 위해 학습한 내용을 문서로 정리 및 팀 내에 발표로 공유.

  • 1.5 버전 작업 중 - 제품 유지보수 가능한 코드 개발로 요구사항 및 개선에 대한 개발 생산성 증가.

  • 1.5 버전 작업 중 - 제품 UI 기능 개선으로 사용성 증가.

  • 21년 4월 제품 1.0 버전 출시 후, 2건 납품.

  • 21년 4월 제품 1.0 버전 출시.

주요 개선

아래의 개선 목록들은 제품이 더 좋은 제품이 될 수 있도록 제가 스스로 해야겠다고 생각해서 개선한 내용입니다.

  • 코드 개선 - app.vue 뭉친 코드 분리
  • 코드 개선 - 긴 코드 분리하기
  • client와 server에 사용자가 입력한 sensor를 등록하는 기능의 함수인데, 너무 길어서 기능을 찾고 유지보수하기 힘든 코드였습니다.
    개선 이유

    함수 하나가 172줄이나 되서 가독성이 떨이지고, depth가 깊음. 함수 안에서 조건 별로 처리되는 기능이 달라서 기능을 찾기가 어려움. → 유지보수가 힘듬.

    👆 함수 한 개.

    개선 방법

    1함수 1기능으로 분리했습니다.

    save를 누르면 실행되는 함수가 짧고, depth가 없어서 개발자가 딱 봤을 때, 고칠만한 코드로 보이고, 읽기가 쉬워짐. 함수가 딱 실행하는 기능만 갖춰지게 됨.
                                                    
    addEdge() {  // 👈 분리된 함수
        //...
    },
    editEdge() { // 👈 분리된 함수
        //...
    },
    editTaglet() { // 👈 분리된 함수
        //...
    },
    async handleClickSaveDeviceInfo() {
        if (this.sIsMatch === 'N') {
          this.$alert.error('Check DB password.');
          return;
        }
        if (this.gDeviceEditMode === 'addedge') {
          this.addEdge();
        } else if (this.gDeviceEditMode === 'editedge') {
          this.editEdge();
        } else if (this.gDeviceEditMode === 'edittaglet') {
          this.editTaglet();
        }
    },
                                                    
                                                
  • 개발 환경 개선 - Vue-CLI 기본 스펙을 사용한 개발 환경 자동 세팅
  • Vue-cli 빌드 환경 설정 기능을 사용해서 개발 생산성을 높이는데 기여했습니다.
    • 개발환경일 때 로그인 자동화
    • 개발환경일 때 호스트 설정 자동화
    문제 인식
    1. 개발환경인데, 매번 코드를 작성하고 개발 페이지를 확인할 때에 로그인을 해야했습니다.
    2. master branch에서 새로 분기한 branch에서는 매 번, 서버 host를 코드 베이스에서 직접 변경해 주어야하는 불편함이 문제라고 인식했습니다.
    3. 항상 커밋 변경 파일 목록에 호스트를 변경한 파일이 목록에 있어서 커밋을 할 때 주의가 필요했습니다.
    해결 방법

    Vue-CLI의 기본 명령어 실행에 따라서 환경변수가 설정되는 스펙 사용. 참고 문서

                                                        //npm run dev
    process.env.NODE_ENV = 'development'
    //npm run build
    process.env.NODE_ENV = 'production'
                                                    
    코드베이스의 호스트 IP를 별도의 환경 변수 설정 파일로 분리했습니다.

    👆 코드베이스에 IP가 들어가지 않게 env파일을 만들어서 변수를 호출해서 사용하도록 했습니다.

    커밋 코드

    👆 제가 수정 후, 커밋 전에 찍은 스샷입니다.

    (사용자 로그인이 필요한 제품이 아니여서 로그인을 하면, 브라우저 localstorage에만 저장되는 걸로 로그인 기능을 실행합니다.)

    팀 내 공유 문서

    📄 개발 모드와 빌드 모드 구분으로 ems 호스트 정보 자동 설정 방법.pdf

    📄 Vue-CLI 환경변수 설정으로 코드 베이스에서 IP 분리하기.pdf

    성과 🎖
    환경 설정 후, (개발/빌드) 환경에 따라서 로그인과 통신할 서버의 ip를 자동으로 설정을 할 수 있어서 개발자가 목표 작업에만 집중할 수 있도록 개발 환경을 개선함.
  • 코드 개선 - JsDocs 도입
  • JsDocs를 사용해서 주석이 필요한 함수에 대해서 코멘트를 남기는 방법을 팀에 공유하고 제품에 사용하고 있습니다.
    문제 인식
    유지보수를 할 때, 더 효율적일 것 같은 방법이 생각나서 수정하면, 이 전에 방법을 사용했던 이유를 알게 되서 다시 작업한 코드를 되돌리곤 했었습니다.
    해결 방법
    이럼 참사를 방지하고자, 함수 또는 코드에 코멘트를 남기는 주석 문법을 팀 내에서 사용하고자 했습니다.

    팀 내 공유 문서 [FE] Javascript 문서화 방법.pdf

    성과🎖
    예외적으로 작성한 코드나 의도를 쉽게 파악할 수 없는 코드에 대해서는 코멘트를 남기도록 팀 간에 협의를 이끌었습니다.
  • UX 개선 - 모션 효과 추가.
  • 작업 이유
    • 사용자가 제품 사용에 집중하도록 요소에 모션을 추가하는 작업을 했습니다.
    • 제품에 transition같은 컴포넌트의 표시에 모션이 들어간 요소가 없었습니다.
    모션 효과 구현에 사용한 기술
    👇 제품에서 버튼을 누르면 하위로 리스트가 펼쳐지는 것이 모션으로 동작하도록 Vuetify의 <v-expansion-panels >를 사용했습니다.
  • UX 개선 - text-overflow 및 list-overflow 대응.
  • 작업 이유

    text-overflow

    • CSS로 쉽게 처리할 수 있습니다.
    • 기존 방식인 javascript 함수를 사용해서 서버에서 받아온 문자열 데이터를 slice로 자르고, '...' 문자열을 붙이는 Javascript 함수를 만들어서 사용하고 있었습니다. 이 방법이 안 좋은 방법이라고 생각했습니다. 몇 번째 문자까지 보여줄지 직접 숫자를 정해줘야 했기 때문이었습니다. 어떻게 개발자가 텍스트를 둘러싸는 요소의 너비를 알고 한 번에 몇 글자까지 생략하고 '...'을 표시할 지 알겠습니까. 몇 번째 글자까지 생략해야 하는지 웹에서 확인하면서 생략 자릿수를 설정해야 하는 불편함이 있습니다. 그리고, 브라우저 크기에 따라서 요소가 변경되면, 바로 화면의 css가 깨져버리는 심각한 문제가 발생할 것이라고 생각했습니다.

    list-overflow

    • 리스트 헤더까지 목록 스크롤에 포함되어 있었습니다. 보통은 리스트 헤더 아래에 목록이 있는 body 부분만 스크롤이 작용하는 게 맞다고 생각해서 팀장님에게 허락받고 수정했습니다.
    문제 해결 방법

    text-overflow

                                                    {
        text-overflow: "ellipsis";
        overflow: "hidden";
        white-space: "nowrap";
    }
                                                

    list-overflow

                                                    {
        overflow: "scroll";
        height: 400px;
    }
                                                
  • UI/UX 개선 - map 페이지
  • 아래 사진에 번호를 매긴 빨간 박스 요소들이 개선이 필요한 요소들이었습니다.

    UI 개선 이유

    1️⃣ select box입니다. 전혀 사용자가 보기에는 select box가 아니라고 생각되는 UI였습니다. 그래서 select box인 것을 표시하기 위해서 Vuetify의 selectbox로 교체했습니다.

    2️⃣ 하드코딩 되어있는 요소였습니다. 사용자가 알 필요 없는 정보였습니다.

    3️⃣ 사용자 입장에서 버튼을 눌러서 원하는 그룹을 필터해서 보고 싶어하지, 직접 검색하는 경우는 드뭅니다. 그런 목적의 기능이기 때문에 group 필더를 더 사용성이 좋게 개선했습니다. 버튼 영역을 넓히고, 모션을 주어서 펼쳐지도록 수정했습니다. 원래는 그룹을 선택하면, 선택한 그룹 중 가장 앞에 있는 그룹 이름만 보여줬습니다. 본부장님께 UI를 개선해서 보여드렸더니, group button에 선택한 그룹들이 모두 표시가 되었으면 좋겠다고 하는 의견을 제안하셨고, 저는 수용해서 그에 맞게 개선했습니다.

    4️⃣ 목록을 누르면 카드가 모션없이 띡 등장했습니다. 모션이 있으면, 사용자가 집중하기 좋을 거라 생각했습니다.

    5️⃣ 정해진 max-height 없이 목록에 있는 아이템이 전부 출력되었습니다. overflow에 대한 작업이 전혀 되어있지 않아서 사용자의 사용성을 크게 저해한다고 생각했습니다. max-height를 주고, max-height를 넘어갈 정도로 아이템이 많을 경우에는 overflow scroll을 적용했습니다. 그리고, 리스트를 펼치는 버튼이 누르면 리스트가 펼쳐지지만, 다시 버튼을 눌렀을 때, 닫히지 않았습니다. 사용자에게 불편함을 줄 수 있어서, toggle로 open/close를 구현했습니다.

    UI 개선 결과
    개선 방법

    1️⃣ : 스타일 변경

    2️⃣ : 단순 코드 삭제

    3️⃣ : 필터 기능 구현

    4️⃣ : transition 진입 진출 태그를 사용

                                                    
    <template>
    <transition name="fade" mode="out-in">
        <div class="MapUnit_float" v-if="cIsClicked && gClickedEdgeId === pClickedEdgeInfo.id">
            <template v-if="cUnitType === 'edge'">
                <EdgeCard :pIsMapUnitEdgeCard="true" :pCardSize="120" :pInfo="pClickedEdgeInfo" :pLocationId="pInfo.location_id" @eInitStatus="eInitStatus" />
            </template>
    
            <template v-else-if="cUnitType === 'tag'">
                <TagInfo :pClickedTagInfo="pClickedTagInfo" :pLocationId="pInfo.location_id" :pIsPinned="true" :pIsMapUnitEdgeCard="true" @eInitStatus="eInitStatus" />
            </template>
        </div>
    </transition>
    </template>                                                    
    <style>
        .fade-enter-active {
            transition: all 0.3s;
        }
        .fade-leave-active {
            transition: all 0.2s cubic-bezier(1, 0.5, 0.8, 1);
        }
        .fade-enter, .fade-leave-to
        /* .slide-fade-leave-active below version 2.1.8 */ {
            transform: translateX(-10px);
            opacity: 0;
        }
        .tag-fade-enter-active {
            transition: all 0.3s;
        }
        .tag-fade-enter, .tag-fade-leave-to
        /* .slide-fade-leave-active below version 2.1.8 */ {
            transform: translateX(10px);
            opacity: 0;
        }
        .tag-fade-leave-active {
            transition: all 0.1s cubic-bezier(1, 0.5, 0.8, 1);
        }
    </style >    
                                                    
                                                

    5️⃣ : 요소에 height와 overflow:scroll을 설정

버그 수정

작성된 코드의 의도를 먼저 봅니다. 코드가 작용하는 유효 범위 영역(scope)을 확인하고, 웹 문제인지 서버 문제인지 판단합니다. 서버에 문제면, 서버 코드를 확인합니다. 백엔드 개발자와 소통해서 수정합니다.

👇 아래의 사례는 제가 제품의 버그를 발견하고 수정하는 과정을 풀이한 것입니다.

제가 문제를 어떻게 접근하고 단계적으로 해결해 나가는지 확인할 수 있습니다.

기능 개발

codesandbox에서 먼저 프로토타입으로 개발해보고 현재 사용하고 있는 패키지나 로직만으로 해결가능한지 테스트합니다. 외부 패키지를 사용해야 하는 경우, 역시 문서 확인과 프로토타입을 진행해서 설계 요구사항에 맞게 사용할 수 있는지 확인합니다. 기획 의도대로 개발이 가능한 패키지라면, 팀장님과 협의를 하고 제품 개발을 진행합니다. 이슈가 발생하면 기획/개발/디자인 팀원들과 함께 고민하고 해결책을 찾아나갑니다.

브랜디.

인턴 계약직 웹 풀스택 엔지니어
2020. 11. 17 - 2021. 01. 04(2M)

책임 업무
커머스 개발팀 개발 과제 진행.

브랜디 경력기술서 보기

프로젝트명 : 개발팀 수습 개발 과제

2020. 11. 17 - 2021. 01. 04(2M)

책임 업무

과제 수행 및 코드 리뷰.

MySQL 쿼리 작성해서 데이터 추출.

개발 환경

  • MacOS
  • VSCode

개발 언어/패키지

  • Javascript
  • CSS SCSS
  • Vue.js
  • Vuetify
  • Vuex
  • Axios
  • PHP
  • MySQL

와이즈넛.

정규직 솔루션 구축 및 웹 애플리케이션 개발 엔지니어
2019. 04. 22 - 2020. 09. 21(1Y5M)

책임 업무
공공기관 웹 사이트 검색 솔루션 구축 및 웹 페이지 개발.

와이즈넛 경력기술서 보기

프로젝트명 : 강원도 일자리 공고 웹 크롤링

기간: 2019. 11 - 2020. 12(1M)

책임 업무 -기여도 100%

고객 서버에 원격으로 접근해서 Window Server에서 작업했습니다. MySQL을 설치하고, 회사 솔루션 제품도 설치했습니다.

강원도의 대학 및 기관에서 채용 게시판을 솔루션을 사용해서 크롤링하고 그 데이터를 DB에 저장시키는 일을 담당했었습니다.

어려웠던 점

고객의 크롤링을 요구했던 모든 사이트가 완벽하게 수집되지 않았습니다.

  • https 수집 안 됨.

    https의 수집이 안 되는 사이트들은 브라우저 설정에서 팝업 신뢰할 수 있는 사이트로 등록하고 수집하는 방식으로 문제를 해결할 수 있었습니다.

  • 솔루션의 버그도 있었고, 사이트 보안 정책으로 수집이 안 되기도 했습니다.

    솔루션 버그는 회사 연구소에 문의해서 해결했습니다.

개발 환경

  • ssh, sftp
  • Window Server

개발 도구

  • MySQL
  • 회사 크롤링 솔루션

성과🏅

강원도의 각 기관에서 게시판에 채용정보를 크롤링해서 강원도 일자리 홈페이지에 데이터를 제공하는 서버와 프로그램을 구축해서 납품할 수 있었습니다.

프로젝트명 : 인천공항 챗봇 기술지원

기간: 2020. 03 - 2020. 05(3M)

책임 업무 -기여도 30%

챗봇 백오피스 기능 개발.

JQuery를 사용해서 CRUD 처리를 위한 Ajax 개발 작업을 진행했습니다.

관리자가 엑셀 데이터 업로드 및 다운로드 할 수 있게 기능을 개발했습니다.

개발 환경

  • Linux
  • Window
  • SCV
  • eclipse

개발 프레임워크/언어/라이브러리

  • JQuery
  • Javascript
  • CSS
  • HTML
  • Java
  • Spring framework
  • MySQL, ORACLE

프로젝트명 : 검색 솔루션 구축 및 웹 검색페이지 개발

기간: 2019. 05 - 2020. 09(1Y4M)

개발 환경

  • Linux
  • Window
  • SCV
  • eclipse

개발 언어/패키지

  • Javascript
  • CSS
  • HTML
  • Java
  • Spring framework
  • MySQL, ORACLE

책임 업무

  • 1~2달 단위로 공공기관 프로젝트 업무 수행

  • 회사 솔루션 검색 엔진 구축 및 DB에서 검색 데이터 수집

  • 웹 애플리케이션 검색 페이지 개발과 검색 요청을 처리하는 rest API기능 구현

  • 쿼리를 만들거나 상주 개발자로부터 검색 데이터를 출력할 수 있는 쿼리를 받아서 검색솔루션이 주기적으로 쿼리를 실행해서 검색솔루션이 검색어를 색인하도록 리눅스 또는 윈도우 서버에 검색 솔루션을 구축합니다.

  • 웹 작업은 공공기관의 검색페이지를 개발했습니다. 공공기관이여서, 주로 spring 프레임워크로 되어 있었고, publisher로부터 마크업과 style작업된 파일받아서, 거기에 검색 데이터를 rest api를 통해서 받아와서 페이지에 반영해 주는 웹 작업을 수행했습니다.

Skills.

Big Challenge.

프론트엔드 개발자로 일하시면서 문제 해결 사례

유지보수가 더 쉬운 코드를 작성하기 위한 노력

어려웠던 점.

제품 버그를 수정하면서 시간이 많이 걸렸습니다.

시간이 많이 걸린 것이 수정할 부분이 많아서 걸린 것이 아니었습니다. 코드 분석에 시간이 많이 걸렸습니다.

분석에 시간이 많이 걸린 이유
  • 코드에서 기능을 찾기에 시간이 많이 걸렸습니다.

  • 하나의 컴포넌트 파일의 코드 길이가 2000줄이 넘었습니다. 하나의 컴포넌트 파일에 feature가 4개나 됐습니다.

  • 여기 저기서 막 가져다 사용하는 변수와 함수들이 있었습니다. 'sIsCheck', 'sIsValid' 그리고 'sCurrentTagletInfo'처럼 변수나 함수 이름까지 의도없이 네이밍되어 있어서 이 변수와 함수의 의도를 파악하기가 어려웠습니다.

  • 함수의 기능이 여러 개가 뭉쳐있었습니다.

어려웠 던 점 해결 방법

저만 잘 작성하면 되는 문제가 아니라고 생각했습니다.

저희 팀은 가이드나 본보기가 될 시니어 개발자와 일하고 있지 않기 때문에 스스로 공부하고 문제점을 개선하지 않으면 안 되는 환경입니다. 그래서, 서로 문제 해결 방법이나 좋은 방법에 대한 공유가 필수라고 생각했습니다.

이런 취지에서 팀원들에게 좀 더 좋은 코드를 작성해야 하는 이유를 설명하기 위해서,

처음에 이 코드를 작성한 팀원과 팀장님에게 버그 수정과 코드 수정을 한 코드를 merge받을 겸, 코드 리뷰를 진행했습니다.

의도를 알 수 없는 변수명과 함수명 수정이 시급했습니다.

Javascript의 함수를 잘못 사용해서 발생한 버그를 리뷰했습니다.

개발자 2명과 협업하기

 제가 개발하는 웹은 [웹(Front) - 웹 서버(api 요청,응답 처리) - 센서 장비(센서 데이터 저장)]로 구성되어 있습니다. 이 웹의 기능 중에는 다수의 센서 장비에 자동으로 데이터베이스와 장비에 필요한 프로그램 패키지를 자동으로 설치하고, 세팅하는 기능이 있습니다.

문제점 및 문제 원인
 문제는 '일괄 설치' 기능에 대한 코드 버전 업이 전혀 안 되어 있는 것이었습니다. 웹 서버와 센서 장비의 프로그램과 데이터베이스는 요구사항 변경과 버전 업으로 코드와 데이터 구조가 많이 변경된 상태였습니다. '일괄 설치' 기능이 작동하질 않았습니다. 웹 서버와 센서 서버와의 관련 기능도 개발이 되다가 만 상태여서 어느 부분에서 버그가 나는지, 테스트를 하면서 알아가야 했습니다.

첫 번째로, 우선은 제가 받은 코드에는 '일괄 설치' 기능에 사용하는 이미지 파일과 Javascript파일들이 꽤 빠져있었습니다.
두 번째로, 웹 서버와 요청하고 응답을 받아오는 데이터가 잘못 되어 있었습니다. Ajax 라이브러리를 사용했는데, 응답을 받는 JSON형식이 달라서 에러가 많이 발생하였습니다.
세 번째로, 서버와 센서간에 일어나는 byte변환 오류였습니다.
해결 방법
 웹 서버와 센서를 담당하는 개발자가 각각 있어서 함께 협업해서 해결 할 수 있었습니다.
초기 개발을 담당했던 분에게 파일을 받고, 그 중에 누락된 image 파일들은 UI/UX 디자이너에게 요청해서 채워 넣었습니다.
그 후에, 기능을 하나씩 눌러보면서 개발자 도구에 의존하면서 테스트를 했습니다. 개발자 도구에서 응답데이터를 확인하면서 요청 응답의 데이터를 다르게 처리하는 Javascript 코드를 고쳐나갔습니다.

개발자 분들 모두, 서로 적극적이고 소통을 잘해서 기능을 살릴 수 있었습니다.
어려웠던 점 및 배운 점
 Javascript만 보고 가서는 의사소통이 되질 않았습니다. 저도 서버에서 사용하는 쿼리와 go 언어를 한 번은 보고, 어느 로직이 잘못 된지를 확인하고 가서 커뮤니케이션을 해야지 효과적으로 정확하게 오류를 고쳐나가거나 로직이 빠진 부분을 채우도록 도움을 요청할 수 있었습니다. 이렇게 했다고 go언어에 익숙해 진건 아니지만, 협업을 할 때, 효과적으로 소통하는 방법을 고민해볼 수 있는 도전이었습니다.