지도



시간표


발표
(10:30, 103호) 지속 성장 가능한 설계를 만들어가는 방법 | 김재민
- 계획 → 요구사항 분석 → 설계 → 구현 → 테스트 → 운영
- ⭐ 설계를 잘하는 방법 = 설계를 하지 않는 것 = 구현
- 개념
- 🔎 웹툰 → 작가, 연재, 작품, 추천, 구매, 결제… → 그룹화 → 많은 그룹 간 교집합 형성, 지저분, 장황, 개념 간의 흐름 및 경계 알아보기 어려움 ⇒ 격벽 세우기
- 격벽 ~= 방화벽
- 개념 간 접근에 대한 제어와 통제
↔ 무분별한 참조, 점점 개념이 없어지게 됨 - 격벽에게 허락을 받고 참조 가능, 격벅이 허용하는 개념들만 격벽을 넘을 수 있음
❤️ 특정 클래스를 수정했을 때, 관련 있는 개념들로만 변경이 전파
- 개념 간 접근에 대한 제어와 통제
- 🔎 대출
- 개념 = 대출
- 대출의 행위 클래스 = 신청, 실행, 상환
- 셋 모두 대출에 의존 (= 수정 전파됨) → 한 개념 관련 클래스가 많으면, 개념을 너무 크게 잡았는지 의심 → 테스트로 검증
- 신청, 실행, 상환들이 모두 대출과 같은 Level이도록 개념 클래스로 으로 정의
- 상환 → 상환 성공, 상환 실패 두 결과 존재, 실패의 경우 재시도 및 추가 이자 필요 → 상환 관련 클래스 계속 생김, 개념 너무 크게 잡았나 의심
- 격벽 → 상환에서는 실패하면 끝이어야 함, 상환 재시도 및 추가 이자는 상환 개념의 역할을 벗어남 → 새 개념 연체
- = 상환 실패 이후는 상환이 아닌 또다른 개념이었던 것, 격벽을 통해 이관 필요
- 상환 재시도 = 연체 납부 = 그냥 연체의 한 기능 (행위 클래스 X)
- 추가 이자 = 연체 이자
- 상태는 개념이 아님, 개념에 상태가 포함되어야 함 (🔎 상태 = 실패)
- 한 개념이 많이 쓰이면 분리를 검토, 개념을 너무 크게 묶었을 가능성 존재
- 상태에 의해 개념이 생기면 격벽을 세워보자
- 상태/행위를 개념으로 착각할 수 있다 (실패, 상환 재시도) → 착각인지 아닌지 잘 살펴보기, 케이스에 따라 다를 수 있음
- 개념 = 대출
- 🔎 커머스 → 외부 연동사와 우리의 상품
- 테스트 코드로 검증 후 리팩토링 필요
- 외부 연동사는 개념이 아님
- 개념이 다양할 경우 중요도에 따른 계층 구조가 생김
- 개념 계층과 개념이 없는 곳 (🔎 모니터링, 테스팅, 외부) 으로 나뉘게 됨
- 외부 != 우리, 바깥에 두고 코어 로직과의 격리 필요
- 외부에서 내부에 침투하면 안됨 = 참조 불가의 벽
- = 격벽보다 더 강한 벽
- 외부 연동사 → 데이터 수집 및 정제만 (DB를 통해)
- 상품 등 핵심 비즈니스 영역을 개념 영역에
- 각각을 별도 모듈로 분리
- 우리 코어 로직에는 외부 의존 코드가 있으면 안 됨
- 개념에도 계층이 있다
- 모든 것이 개념이 되진 않는다
- 개념 영역을 분리할 수 있다, 우리가 지켜야 할 영역은 정해져 있고 아닌 것들과의 분리 필요
- 설계
- sw = soft, 부드러워야 함, 수정/확장이 어려우면 그건 sw가 아님
- 인정하자
- 요구사항은 계속 변한다, 준비 필요
- 완벽한 설계는 없다 (이는 죽어가는 sw에만 존재한다)
- soft해야 한다
- 하지 말자
- 요구사항이 완벽해여 설계가 가능해요
- 우리 설계에서 그건 개발 못해요 → 대부분 설계를 잘못해놓고 하는 말
- 설계를 해봐야 개발 일정이 나와요 → 설계 3개월 개발 1년이면, 그냥 hw를 만드는 것
- 상기하자
- 성급한 설계는 모든 것을 망가뜨린다 → 변화에 취약해짐, 변경된 요구사항 받아들이지 못함
- 과한 설계는 모든 것을 망가뜨린다 → 너무 과하게 Cost를 소비하지 말자
- 설계는 필요한 만큼만
- 개발
- (X) 분석 → 설계 → 구현
- (O) 바로 구현
- 개념/격벽 → 테스트 코드 → 증명, 피드백
의 반복 - = 설계
- 개념/격벽 → 테스트 코드 → 증명, 피드백
- 설계를 잘하는 방법 = 설계를 하지 않는 것
- 개념 잡고
- 격벽 세우고
- 구현 채우고
- 설계 완성
(11:25, 105호) 디버깅 마인드셋 | 배휘동
- 고수들의 디버깅 → 인지적 과정 알기 어려움, 판단과 의사결정을 어떻게 할 수 있었는지? → CDM, 인지작업 분석
- 문제 인식
- 과거 경험과의 유사성
- 전제조건
- 사전지식
- 과거 경험과의 유사성
- Task Diagram Mapping를 통해 인터뷰
- 고수들의 인지적 작업을 따라하고 연습하면 우리도 할 수 있음
- 디버깅: 의도대로 동작하지 않는 무언가를 정상화하는 행위
- 정보 수집, 가설 설정, 가설 검증 → 먼저 정상적인 환경에서는 어떤 조건에서 어떤 순서로, 어떤 일이 벌어져야 하는지 정의되어 있어여 함 = 심적 표상
- 심적 표상: 패턴 인식, 의사결정을 위한 Decision Tree
- 고수들은 이를 이용해서 디버깅 → Decision Tree 업데이트 → … → 문제를 보기만 해도 바로 패턴 매칭 가능해짐
- ⭐️ 원인 파악 (전문성의 핵심 = 근본 원인 파악)
- 문제 해결
- 사후 처리
- 정보 수집, 가설 설정, 가설 검증 → 먼저 정상적인 환경에서는 어떤 조건에서 어떤 순서로, 어떤 일이 벌어져야 하는지 정의되어 있어여 함 = 심적 표상
- 다섯 단계 가이드, 각 단계를 왔다갔다 하면서 반복하게 됨
- 사전: 작업을 위한 계획 (시간 분배 등), 계획에 따라 적절하게 멈추고 회고, 휴식, 도움 요청 등
- 문제 정의
- 복잡한 문제일수록 확실한 이정표 필요, 당장 중요하지 않은 문제에 시간 허비하지 않아야 함 (Yak Shaving)
- ⭐️ 정상 동작 정의 = 심적 표상 생성
- 현재 벌어지는 일 관찰 + 관찰한 정보 및 이미 알고 있는 정보 적어보기
- 올바른 동작을 테스트 코드처럼 작성 (Given, When, Then)
- 모르겠다면, 도움 요청이나 Git History, 구글링 등으로 정보 탐색
- 뒤쪽의 관찰들을 토대로 이 동작이 갱신되기도 함 = 심적 표상 업데이트
- 최소 재현 환경 구축하며 관찰
- 문제 발생 시점 확인 → 로그 등
- 세션 리플레이
- 격리 및 패턴 관찰 → 비정상/정상 환경에서 정상/비정상 환경으로 넘어가기 위한 조건을 찾기 위해 조절해가며 테스트
- 재현이 안 된다면, 추가 정보 더 자세히 파악
- 차이를 발생시키는 다양한 원인 탐색
- 추상적이든, 구체적이든, 떠오르는 대로 다 적어보기
- 다양한 → 옵션이 많아야 가설 설정 및 검증 사이클을 빠르게 돌릴 수 있음 (특히, 주니어라면 3개 이상)
- 다양하게 적기 어렵다면, 추가 정보 여러 소스에서 수집
- 가설 설정 및 검증
- 가장 그럴듯한 옵션을 검증 가능한 가설 형태로 문장화
- A가 B인 게 C의 원인이면, B가 B’가 되었을 때 C가 C’가 되어야 함
- 검증
- 틀렸다면 다음 가설로
- 원인 파악이 계속 안 되었다면, 집착하지 말고 다른 소스를 구해보거나 도움 요청
- 원인 파악
- 코드상의 원인
- 실수가 발생한 원인
- 가장 그럴듯한 옵션을 검증 가능한 가설 형태로 문장화
- 사후: 해결법 설계, ROI 파악, 우선순위 및 담당자 결정
- 파레토의 법칙, 80% 정도는 원인만 알아도 잘 해결됨
- 고수 → 도구를 찾아내고, 선택해내는 것을 잘함
- ⭐️ 상황에 맞는 디버거 선택
- (FE) 크롬 디버거 교육 영상
- Toilet
- 휴식 시간에 회고, 돌파구 떠올림
- PR, Git의 Description
- 의미 단위로 PR
- 기억도 잘 남고, 검색도 잘 됨
- Issue
- 오픈소스 이슈 등록 시, 최소 재현 코드를 만들어야 함
- 이슈만 남겨두고, 다른 문제를 해결
- ⭐️ 상황에 맞는 디버거 선택
(12:15, 209호) 사이드 프로젝트로 커리어 레벨업! | 조현우
- 기술 스택, 커리어 전환
- 사이드 프로젝트를 통해 이직 및 적응
- 주니어 당시의 고민들 → 뭘 공부할지, 큰 회사에서는?, 커리어 설계, 포트폴리오/이력서, …
- 프로젝트 주제 선정
- 도메인 연계: 관심 있는 도메인의 프로젝트 → 이직에 긍정적 요인
- 포지션 연계: 생각보다 여러 기술 스택 요구하는 곳이 많음 (ex. PHP 코드를 Next.js로 마이그레이션)
- 포트폴리오 웹사이트 → Gitbook > 노션
- 사이드 프로젝트 잘 하는 방법
- 2~3일 내로 할 수 있는 볼륨으로 → 중요한 건 몰입, 몰입해서 끝낼 수 있는 사이즈로 만들어라
- 아이디어가 이거보다 크다면, MVP를 이 정도 분량으로 줄여라
- 가장 관심 있는 분야로 주제 선정 → 몰입할 수 있어야 함, 잘 끝내기 위해서는 흥미 위주
- 없다면, 떠오르는 아이디어
- 내가 소비자가 될 수 있는 아이디어
- 요즘 트렌드 고려
- 안 써본 기술 딱 하나씩 추가해 보기, 이걸 그 다음 프로젝트에서도 써보기
- 선택 → 유니크할 필요는 없음, 라이브러리/프레임워크를 추가하거나, 배포 방식을 변경해보는 등
- 비용을 아까워하지 말자 → AWS, 인프라, 도메인, 앱스토어 등록 비용…
- 프리 티어와의 차이가 생각보다 큼, 실무에서 Cost에 따른 Output을 알기 쉬워짐
- 성장을 위한 투자 비용으로 생각해보기
- 연봉 인상과 이직으로 회수 가능
- 프로젝트 두려움 없애기 → 개인 프로젝트 추천! 팀으로 하면 커뮤니케이션 비용 등 신경쓸 게 너무 많아짐
- 더 공부를 한 뒤에? → 이 시점이 빠르게 오지 않음, 부딪혀보는 게 더 빠름
- 일단 시작해라! 레포 만들고 첫 기능 완성까지
- 2~3일 내로 할 수 있는 볼륨으로 → 중요한 건 몰입, 몰입해서 끝낼 수 있는 사이즈로 만들어라
(14:00, 101호) 멀티패러다임 프로그래밍 언어의 시대: 객체지향과 함수형을 섞어야할 때! | 유인동
- 타입스크립트 라이브 코딩을 통한 멀티패러다임 언어 → Tagged Templates
- 함수 뒤에 Template 리터럴을 추가하여 실행되게 할 수 있음
- 템플릿 리터럴에 있는 문자열과 변수를 분리하여, 각각 메소드의 첫 번째 인자인 string[] 배열과 두 번째 인자인 unknown[] 배열로 받게 됨
- 첫 번째 배열의 크기는 무조건 두 번째 배열 크기 + 1, 부족하면 빈 문자열로 채워지게 됨
- 함수형 프로그래밍
- fxts/core 오픈소스 라이브러리
- pipe로 여러 함수 합성
- 배열에 특정 값을 push하는 대신, 제너레이터를 통해 지연 평가를 이용하는 concat 구현
function* concat<T> (...arrs: Iterable<T>[]) { for (const arr of arrs) { for (const a of arr) yield a; // yield* arr; 로 대체 가능 } }- ❤️ 필요한 만큼 값을 꺼냄 → 배열이 큰 경우, 이를 전부 복사해서 큰 배열로 만드는 일 발생하지 않음
- 배열.push와 같은 문장을 한 줄 줄일 수 있음 → 오로지 화살표 함수가 합성 함수(= pipe)만 리턴하도록 우아하게 표현 가능
- escapeHtml
- 스크립트 코드를 외부에서 어떻게 넣어봤자, {}를 다 다른 문자로 치환해 버림 → 공격 원천 차단, 외부에서 절대 공격 불가
- 내부에서 조합하는 컴포넌트마저 치환시켜 버리는 문제 → 객체지향 프로그래밍 섞어서 해결 가능
- 객체지향 프로그래밍
- 해결해야 하는 문제
- 어쩔 때는 Escape를 하고, 어쩔 때는 하지 말아야 함 = 타입 구분이 가능해야 함
- 재귀적으로 escapeHtml 호출 필요
- Html 클래스 생성, 기존의 함수를 클래스의 메소드로 이동 = toHtml
- escape 메소드 구현 → Html 타입이면 (= 컴포넌트라면) toHtml을 다시 호출하고, 아니면 (= 공격이면) 괄호 치환하도록
- 1, 2의 문제 전부 해결
- 문제 해결의 기법으로서 함수형 및 클래스 사용
- 해결해야 하는 문제
- ⭐️ 구조의 문제는 객체지향으로, 로직의 문제는 함수형으로 해결
(15:00, 102호) 10년 동안의 실패 이야기: 실패를 의미있는 일로 탈바꿈하는 가장 쉬운 방법
- 실패, 배운 점이 있어야 당당할 수 있음
- 한 달동안 만든 서비스, 대부분의 사용자들이 쓰는 옛날 XP 윈도우 OS에서 디자인이 다 날라간 경험 → 리서치의 습관화
- 실패를 받아들이고, 배울 점을 찾을 때 팀과/유저와 함께 → 다시 시도할 힘
- 홈 화면을 개선하자 → 실패, 팀 상황의 어려움, 설득의 실패 → 홈 관련 리서치에 참여 → … → 퇴사 후, 팀에서 비슷한 개편을 함
- 사용자와 함께
- 내가 맞다고 생각한 것이 진짜 맞다면, 언젠가 팀에서 하게 될 것
- 실패를 빨리 알아차리고, 받아들여야 한다
- 받아들임 → 이해관계자, 팀원들의 도움
- 도메인: 약점을 보완하기보다, 강점을 더 강점답게 만들 수 있는 도메인을 찾자 → 평준화가 아닌, 차별화
- 그럼에도, 다양한 도메인을 알면 장점: 팀 빌딩, 매니저 역할
- 배울점을 효율적으로 찾자
- 직무 전환
- 성과를 잘 어필하는 마인드셋
- 리더와 적극적인 소통
- 망한 포폴 심폐소생술
- 실패 → 받아들임, 이 과정을 줌인하여 내가 못했다는 사실을 인정, 중간에 용기가 필요할 것
- 방어/포장에 급급 → 논리를 잘 펼칠 수 없음
- 받아들이고, 회복하자
- 전체 과정에서 회고, 팀원/유저 피드백을 통해 실패의 과정을 재해석
- 실패 → 받아들임, 이 과정을 줌인하여 내가 못했다는 사실을 인정, 중간에 용기가 필요할 것
- 좋은 실패란?
- 배울 점이 있는 실패
- 다음 시도를 위한 에너지 생성
- 이를 위한 과정
- 실패를 들여다보기
- 실패 중, 잘했던 부분들을 집중해서 보기
- 성공의 비중이 많았을 수 있음, 섞여 있음, 이걸 잘 구분/구조화
- 회고하기
- ~= 복리 조직이 일하는 구조, 조직이 만든 결과가 다시 조직에게 영향을 끼치면서 조직 자체가 개선됨
- 회고하고 끝이 아니라, 조정/적용하며 복리 효과 누리기
- 질문하기 (실패를 좋은 실패로 바꾸기)
- 시도, 실패, 받아들임, 배울점 찾기, 다시 시도함에 있어 다양한 질문 활용, 계속 생각하면서 보내기
- (질문 리스트 참고) 요즘 IT, 토스에서 요즘 ‘애자일’하는 방법
- 실패를 들여다보기
- 실패에 대한 두려움, 고민 → 나를 더 생각하자, 별 거 아닐 것
- 결국, 더 잘하고 싶어서 애쓰는 마음
- 걱정해서 달라지는 게 있는 문제일지? → 없다면, 걱정보단 스스로를 돌보기, 정말 잘하고 싶은 마음이구나 하고 받아들이기
(16:00, 101호) 객체지향은 여전히 유용한가? | 조영호
- 답: 네.
- 왜 이런 질문을 하셨을지? → 도메인, 팀 특성에 따라
- 다른 질문을 하는 게 더 성장에 도움이 될 것
- ⭐️ 질문: 객체지향은 언제 유용한가요?
- 일단 배우세요, 뭐가 됐든
- 하나의 기술/패러다임만으로는 프로그래밍할 수 없음, 적당한 컨텍스트에 맞게 활용해서 짜야 함
- 모든 설계는 다 유용한 경우가 있음, 나의 컨텍스트와 비교해서 적용 필요
- 공부 = 도구 상자에 도구 하나를 추가하는 일
- 코드의 목적과 변경의 방향성에 따라 언제 어떤 기술을 사용할지 결정하세요!
- 도메인:
사용자가 카트에 담은 전체 금액 >= 프로모션 기준 금액→ 카트에 프로모션 연결

- 절차지향적 코드: 데이터와 로직을 별도 클래스로 분리 → 프로모션, 카트, 프로모션 프로세스 로직
- 데이터 변경 (프로모션에 최소/최대값 추가)
- 데이터를 사용하는 프로세스 로직도 같이 변경됨
- 즉, 프로모션과 프로모션 프로세스 로직이 둘 다 변경 (데이터를 사용하는 클래스가 변경되면 프로세스 클래스도 함께 변경됨, 높은 결합도)
- 할인 여부를 판단하는 새 종류 추가,
장바구니 수량 >= 프로모션 수량- 프로모션에 타입을 정의할 수 있는 열거형 추가
- 프로모션 프로세스 로직 중 할인 여부를 판별하는 메소드에 조건문 추가, 열거형 값에 따라 다른 로직 사용하도록 함
- 역시, 프로모션과 프로모션 프로세스 로직 둘 다 변경됨
- 할인 여부를 판단하는 새 종류 추가, 장바구니의 특정 상품 하나가 앞서의 두 조건들을 만족하면 할인
- 2번 추가 이전
- 프로모션 프로세스의 메소드만 수정하명 됨, 인자로 카트가 아닌 카트 원소 하나를 받는 오버로딩 메소드 추가
- 2번 추가 이후
- 여전히 오버로딩 메소드만 추가하면 됨
- 💔 새 타입이 추가될 경우, 여러 곳에 복붙된 코드들 전부 수정 필요
- 2번 추가 이전
- 데이터 변환
- 프로모션 프로세스에 코드를 추가하면 됨, 프로세스의 데이터들이 공개되어 있으므로 이를 야금야금 가져와서 데이터 형식에 맞게 구성하면 됨
- 데이터 변경 (프로모션에 최소/최대값 추가)
- 객체지향적 코드: 프로모션 데이터, 프로모션 프로세스 로직을 한 클래스로 합침
- 잘 짜여진 코드인가? 그런 질문보다는 변경 사항이 있을 때 코드에 어떻게 반영할 수 있는지를 고려하여 선택
- 데이터 변경
- 캡슐화 → 데이터 요구사항이 변경되어도 하나의 클래스만 변경됨 = 결합도가 낮음
- 할인 여부를 판단하는 새 종류 추가 (새 기능/타입 확장)
- 다형성 → 여러 개의 타입이 공통으로 따르는 디스카운트 컨디션 인터페이스를 추가하고, 각 구상 조건 클래스가 이를 따르도록 함
- 프로모션에서는, 본인이 할인 조건을 판별하지 않고 자기가 디스카운트 컨디션 인터페이스로 참조하고 있는 구상 클래스에 역할 위임
- ❤️ 장점
- 각 역할이 적절하게 분배
- 다음에 또 새로운 할인 종류가 추가되었을 때, 데이터 변경과 타입 확장 쉽게 가능
- ⭐️ 일관성 있는 설계, 구조 강제
- 디스카운트 컨디션 인터페이스가 모든 자식들에게 강제되므로
- 💔 대대적인 리팩토링
- 할인 여부를 판단하는 새 종류 추가, 장바구니의 특정 상품 하나가 앞서의 두 조건들을 만족하면 할인
- 2번 추가 이전
- 프로모션만 수정
- 즉, 절차지향과 같은 수준의 수정만 일어남
- 2번 추가 이후
- 디스카운트 컨디션 인터페이스에 오버로딩 메소드 추가 → 이에 따라 각 구상 클래스 수정 → 프로모션에 조건문 추가, 특정 상품 하나만 조건을 만족하면 되는지 아닌지에 따라 서로 다른 메소드 호출
- 즉, 관련된 많은 클래스들로 변경이 전파됨
- 다형성을 통해 계층 구조에 새 타입을 추가하는 것은 (= 계층 확장은) 편하지만, 타입에 새로운 기능이 추가될 경우 이 변화가 계속 전파되기 때문에 기능 추가는 어려움
- 디스카운트 컨디션 인터페이스에 오버로딩 메소드 추가 → 이에 따라 각 구상 클래스 수정 → 프로모션에 조건문 추가, 특정 상품 하나만 조건을 만족하면 되는지 아닌지에 따라 서로 다른 메소드 호출
- 2번 추가 이전
- 데이터 변환
- 각 구상 클래스 타입에 따라, 클래스를 타입캐스팅 한 뒤 조건문을 통해 각 타입에 맞게 데이터들을 가져와야 함
- 객체지향의 경우, 데이터가 아닌 행위 중심으로 클래스가 응집되어 발생하는 문제
←> 절차지향, 데이터 중심 응집
- 객체지향이 무조건 좋은 건 아님, 절차지향이 좋을 때가 있음
- 타입 확장이 거의 없을 경우
- ❤️ 기능 추가가 쉬움, 데이터 처리에 적합
- ⭐️ 레이어의 특성에 맞게, 둘 다를 혼합하여 적용하는 것이 좋음
