2025/03/24 

 

HTML의 스타일 적용

  • 클래스명, 속성명 지정시 케밥 표기법 지정
  • Javascript : '-' 표기가 연산자이므로 사용 불가 => 키멜표기법 사용
  • 스타일 적용 순서
    • 요소의 기본 스타일 -> .text 스타일 -> .over 스타일 -> 인라인 스타일

 

 

 

인라인 스타일

v-bind:style="value" 로 작성

=> 데이터 속성에 자바스크립트 객체로 작성

=> value : 스타일 속성명, 스타일 값

 

 

1. 객체로 표기

style1 객체 사용

 

 

2. 문자열로 표기 ( 2개 이상이면 { }로 묶기)

템플릿 파트에서 객체로 표기

 

두 가지 방법은 취향의 차이,

하지만 후자로 하면 style1이라는 표기가 빠지니 코드가 조금 더 단순해지는 효과가 있음.

 

 

 

3. 배열로 표기

 

 

 


 

 

 

 

CSS 클래스 바인딩

v-bind:class="value" 또는 축약표현 :class="value" 로 작성

=> 클래스명 문자열을 바인딩

=> vlaue : 클래스명

 

1. 문자열로 표기

 

 

 

 

2. 배열로 표기

 

 

 

 

3. 객체로 표기

 

 

=> true/false 값을 가진 객체를 바인딩하는 방법

  • 3항 연산자로 클래스 지정 제어시 여러 개인 경우 복잡도 상승
  • 객체로 바인딩해서 속성명으로 클래스 명 지정
    • 속성 값으로 해당 클래스 적용 여부를 true/false 지정



 

 

 


 

 

 

동적 스타일 바인딩

v-bind:style 또는 축약형 :style 사용

=> Vue에서 HTML 요소의 스타일을 자바스크립트 데이터에 따라 동적으로 변경할 수 있도록 하는 기능

2025/03/19 

 

 

📌 Vue 디렉티브(Directive)란?

디렉티브(Directive)는 Vue에서 HTML 태그에 추가적인 반응형 동작을 부여하는 특수 속성

  • 디렉티브 값은 문자열이 아님, JS 표현식(자바스크립트 문법이 적용됨)

 

v-text 디렉티브

  • innerTEXT 속성과 연결, 태그 문자열이 그대로 나타남
  • 단방향 데이터 바인딩
<div id="app">
    <h2 v-text="message"></h2>
</div>
<script>
    let model = { message: '<h1>Hello Vue3!</h2>' };


 

v-html 디렉티브

  • innerHTML 속성과 연결, 태그 문자열을 파싱하여 나타냄
  • 단방향 데이터 바인딩
<body>
    <div id="app">
        <div v-html="message"></div>
    </div>
</body>

<script>
    let model = { message: '<h1>Hello Vue3!</h2>' };
    let vm = Vue.createApp({
        name: "App",
        data() {
            return model;
        }
    }).mount('#app');
</script>

 


 

 v-bind 디렉티브

  • 요소의 속성을 바인딩
  • 단방향 데이터 바인딩
    • Vue 인스턴스의 데이터나 속성이 바뀌면 UI가 갱신됨
    • 화면에서 값을 변경하는 것은 데이터에 반영되지 않음
<body>
    <div id="app">
        <input type="text" v-bind:value="message">
        <br/>
        <img v-bind:src="imagePath">
    </div>
</body>
<script src="https://unpkg.com/vue"></script>
<script>
    let vm = Vue.createApp( {
        name : "App",
        data() {
            return {
                message : "v-bind 디렉티브",
                imagePath : "https://contactsvc.bmaster.kro.kr/photos/18.jpg"
            };
         }
    }).mount('#app');
</script>




 

 v-model 디렉티브

  • 양방향 데이터 바인딩
  • 주로 form요소 바인딩에 사용
  • html의 value 속성과 연동
<div id="app">
    <input type="text" v-model="name">
    <br />
    입력한 값: <span>{{name}}</span>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
    let vm = Vue.createApp({
        name: "App",
        data() {
            return { name: '' };  //line2에서 양방향 데이터 바인딩됨
        }
    }).mount('#app');
</script>

 

 

❗ ❗주의 사항 ❗ ❗

다중 선택 vs 단일 선택에 따라 데이터 형식 변동

다중 선택 : 배열

단일 선택 : 문자열

 

  <div>
        선택한 취미: {{hobby.join(',')}} <br />
        선택한 상품 분류: {{category}}
  </div>
----------------
        data() {
            return {
                hobby: [],
                category: ''
            };
        }

 

 

 

수식어(modifier)

v-model에 기능 추가 역할

  •  lazy
    • input에서 엔터를 치거나 포커스를 이동했을 떄 입력값과 속성을 동기화
    • <input type="text" v-model.lazy="name" />
  • number
    • 문자열을 숫자로 자동 형변환시켜 속성에 반영
    • <input type="text" v-model.number="num" />
  • trim
    • 문자열의 앞뒤 공백을 자동으로 제거
    • <input type="text" v-model.trim="message" />

 

 


 

v-show 디렉티브

  • 화면에 보여줄지 말지를 결정하는 디렉티브(HTML 요소를 생성하지만 화면에 보여주지는 않을 수 있음)
  • display 속성을 제어
<img v-show = "amount<0" ...

 

 v-if 디렉티브

  • 조건에 부합하지 않을 경우 요소를 생성하지 않음(화면 출력 없음)
 <img v-if="amount < 0" ...

 v-else, v-else if 디렉티브

<div id="app">
    잔고:<input v-model="balance" />
    <br/>
    회원님의등급:
    <span v-if="balance>1000000">Gold</span>
    <span v-else-if="balance>=500000">Silver</span>
    <span v-else-if="balance>=200000">Bronze</span>
    <span v-else="balance">Basic</span>
</div>

 

 

 


 

 v-for 디렉티브

  • 반복적인 데이터 렌더링
  • 형식(배열 사용시) : <태그명 v-for="변수in 배열" :key="id값">
<tr v-for="contact in contacts" :key="contact.no">

 

  • 형식(객체 사용시) : <태그명v-for="(val, key) in 객체" :key="key">
 <option v-for="(val, key) in regions" :value="key" :key="key">{{val}}</option>

 

 

인덱스 번호가 필요한 경우)

 

 

 

 

 template 태그 - 여러 요소를 묶어서 반복 렌더링

 <template v-for="(contact, index) in contacts" :key="contact.no">

 


 

 v-for 디렉티브와 key 특성

배열을 렌더링할 때 데이터 변경없이 위치만 바뀌는 경우

  • key 속성이 없으면 => 전부 다시 렌더링
  • key 속성이 있으면 => 위치만 변경 가능

❗key 특성에는 인덱스 번호가 아닌, 고유한 변경되지 않는 값 부여

 

 


 

 Proxy 객체

  • 데이터의 변경 사항 감시, 값 변경 시 렌더링 다시 유도
  • Vue 인스턴스에서 data 옵션으로 지정한 객체
  • data로 지정된 객체는 모두 Proxy로 래핑
  • 배열의 데이터를 변경하는 메서드들도 매핑되어 있어, 배열 내용 변경시 watcher에게 변경을 알려서 다시 렌더링 필요

 

 

 

❓궁금증❓
네트워크에서 배운 Proxy 서버의 Proxy와 유사한 개념인건가?
==> 
Vue에서 "프록시"는 JavaScript의 Proxy 객체를 기반으로 작동하는 개념으로,Vue의 반응형(Reactivity) 시스템을 구현하는 핵심 기술
중간에서 데이터를 가로채고 조작한다는 점에서 유사

 

2025/03/17~ 03/18 Git, GitHub 특강


프로젝트 작업 과정

 

1) 원격 저장소에서 레포지토리 가져와서 로컬에서 개발 후 PR 보내는 과정

//깃허브 레포지토리 가져오기 및 상태 확인 코드
git clone "깃허브 레포지토리 링크"
git status
git log --oneline
git log --oneline --graph


//새로운 브랜치 생성 후 이동
git checkout -b [branchName]   
git branch
git checkout [branch]


//깃허브의 내 작업 브랜치로 올리기
git add [커밋할 파일]
git commit -m "커밋 메세지"
git push origin [내가 작업한 브랜치 명]



//깃허브 들어가서 내 작업 브랜치-> main으로 PR 생성

 

 

2) 원격 저장소에 변경된 내용 내 로컬에 가져오기

//원격 저장소 main에서 로컬 저장소main으로 가져오기
git pull


//로컬 저장소 main에서 로컬 저장소 내 브랜치로 가져오기
git merge main  or
git pull origin main   or
git rabase main


//브랜치 삭제
git branch -D [브랜치 명]

 

[1] git merge main을 사용할 경우

내가 commit한 내역 말고도 main으로부터 merge한 커밋이 생성되어 있음
==> commit 내역이 더러워질 수 있음!!!


 


[2] git pull main을 사용할 경우
pull == git fetch + git merge를 수행하는 명령어

merge는 로컬에서 실행하는 병합 작업
pull은 원격 저장소에서 변경사항을 가져온 후 자동으로 병합 수행

[3] git rebase main을 사용할 경우


feature-branch의 모든 커밋을 main의 최신 상태 위로 다시 정렬
병합 커밋 없이 히스토리가 깔끔하게 정리됨
==> 그러나, main에 이미 푸시된 커밋을 rebase하면 팀원들이 pull할 때 충돌 발생 가능

 

 

2025/03/14(금)

 

MVVM 패턴

Model-View-ViewModel

  • 애플리케이션 로직과 UI의 분리를 위해 설계
  • 비즈니스 로직에세는 ViewModel의 상태 데이터만 변경하면 즉시 View에 반영
  • Model : 순수 데이터 자체
  • View : 화면 , HTML과 CSS로 작성
  • View Model : View의 실제 논리 및 데이터 흐름, 여러가지 형태로 구현될 수 있음( 변수, 함수 등), 순수한 데이터를 화면에 표현하기에 편하도록 가공해서 가진다.

MVVM 패턴

 

 

 

  • model에서 직접 데이터를 바꾸면 화면에 바뀌지 않음

 

 


 ES6

 

var, let, const 차이점 정리

호이스팅 : 변수와 함수 선언이 코드 실행 전에 메모리에 할당되는 것

 

var 특징

  • 함수 스코프(Function Scope)를 가짐 (블록 {}을 무시함)
  • 변수 선언이 호이스팅(Hoisting)되며, 초기화되지 않은 상태에서 undefined로 할당됨
  • 같은 변수 이름을 여러 번 재선언 가능

 

 let 특징

 

  • 블록 스코프(Block Scope)를 가짐 ({} 내부에서만 유효)
  • 변수 선언이 호이스팅되지만 초기화되지 않아 TDZ(Temporal Dead Zone, 일시적 사각지대) 발생
  • 같은 변수를 재선언할 수 없음
  • 재할당 가능

 

 

const 특징

 

  • let과 동일하게 블록 스코프(Block Scope)를 가짐
  • 호이스팅되지만 TDZ 발생
  • 재할당 불가능
  • 선언과 동시에 초기화가 반드시 필요

 

 


기본 파라미터 , 가변 파라미터

기본 파라미터(Default Parameter)

  • 함수 호출 시 인수를 생략했을 때 가지는 기본 값을 지정
  • 뒷부분에 지정, 중간에만 지정하는 것은 불가능

 

 

 

가변 파라미터(Rest Parameter)

  • 전달하는 파라미터의 개수를 가변적으로 적용
  • 매개변수 앞에 ... 연산자 지정
    • 전달된 인수를 매개변수로 매칭
    • 매칭되지 않은 인수를 모아 배열로 지정 후, 가변 파라미터로 전달
  • 1개만 지정 가능, 마지막 매개변수에만 지정 가능

 

 


화살표 함수

화살표 함수(Arrow Function, =>)는 ES6(ECMAScript 2015)에서 도입된 간결한 함수 표현식, 기존의 function을 활용한 함수보다 짧고 직관적인 문법 제공

 

 

기본 문법

const 함수이름 = (매개변수) => 표현식;
  • 중괄호 {} 없이 한 줄로 작성하면 해당 표현식이 자동으로 반환
  • return 키워드 생략 가능
  • 한 줄짜리 함수로 객체를 return 할 때는 중괄호로 꼭 묶어야 함. 묶지 않으면 undefined 에러 발생

 

 

여러 줄 함수인 경우

const 함수이름 = (매개변수) => {
    // 여러 줄 코드 가능
    return 결과;
};
  • 중괄호 {} 사용, return 명시

 

 

화살표 함수의 this 바인딩 차이

기존 function 함수는 호출 방식에 따라 this 가 동적으로 결정되지만, 화살표 함수는 this를 자신을 감싼 상위 스코프에서 가져온다. 👉 화살표 함수는 자신만의 this를 가지지 않음

 

 

일반함수 vs 화살표 함수 예제

const obj = {
    name: "kwon",
    regularFunction: function() {
        console.log("Regular:", this.name);
    },
    arrowFunction: () => {
        console.log("Arrow:", this.name);
    }
};

obj.regularFunction(); // "Regular: Alice"
obj.arrowFunction();   // "Arrow: undefined"

 

❗왜 arrowFunction()의 결과가 undefined일까?

  • regularFunction(): this가 obj를 가리킴.
  • arrowFunction(): this가 obj가 아니라 상위 스코프(전역 객체 또는 undefined)를 가리킴.

 

 

화살표 함수를 주로 사용하는 경우

1. 콜백 함수

2. 클래스 내부에서 this가 필요 없는 함수

3. 이벤트 리스너 내부에서 this가 필요한 경우

2025/3/13(목)

 

파일 관리_Path 모듈

  • 운영체제 간에 경로를 구분하는 구분자가 다른 불편 존재 => 경로 구분자를 통일하기 위해 사용
  • 경로를 나누거나 합치기 가능
  • 절대경로( `파일절대경로: ${__filename}` ), 상대 경로 존재
  • 경로 존재 여부로, 이름이 같은 내가 만든 모듈과 내장 모듈 구분 가능

 

 

주요 함수

Path 모듈 가져오기

const path = require('path');

 

 

경로 합치기

path.join(경로1,경로2,...);

 

 

경로만 추출하기 

path.dirname(경로);

 

 

파일 이름만 추출하기

path.basename(경로);

 

 

파일 이름만 추출하기(확장자 제외)

path.basename(경로, 확장자);

 

 

확장자 추출하기

path.extname(경로);

 

 

경로를 객체로 변환하기

=> 각각의 정보를 한번에 가져올 수 있음

path.parse(경로)

{
  root, // 루트 디렉터리
  dir,  // 디렉터리 경로
  base, // 파일명.확장명
  ext,  // 확장명
  name  // 파일명
}

 


FS 모듈

  • File System 모듈의 약자
  • 비동기 처리 방법에 따라 사용하는 함수가 다름
    • 동기 처리 함수
    • 콜백 처리 함수
    • Promise API
  • FS 모듈 가져오기 : const fs = require('fs');

 

1. 동기 처리

 

에러 체크는 try catch로 실행

파일 존재 여부 체크 : fs.existsSync(파일)

 

2. 비동기 처리

 

 

 

요약

                                  동기 처리                                비동기 처리
디렉터리 읽기 fs.readdirSync('./'); fs.readdir('./', (err, files) =>
파일 읽기 fs.readFileSync('./example.txt'); fs.readFile('./example.txt', 'utf-8', (err, data) =>
파일에 쓰기 fs.writeFileSync('./text-1.txt', data); fs.writeFile('./text-2.txt', data, (err) =>
기존 파일에  내용 추가하기 fs.writeFileSync('./text-1.txt', content, { flag: 'a' });
fs.appendFileSync(파일, 내용);
fs.appendFile('./text-2.txt', '\n\n 새로운 내용 추가', (err) =>
파일 삭제하기 fs.unlinkSync('./text-1.txt'); fs.unlink('./text-2.txt', (err) =>
디렉터리 만들기 fs.mkdirSync(경로 [, 옵션]) fs.mkdir('./test', (err) =>

fs.mkdir('./test2/test3/test4', { recursive: true }, (err) =>
디렉터리 삭제하기 fs.rmdirSync(경로 [, 옵션]) fs.rmdir('./test', (err) =>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2025/3/12(수)

 

자바스크립트의 비동기

  • 노드 프로그램은 서버에서 실행되므로 대부분의 명령을 비동기 처리
  • 자바스크립트의 기본 설정은 비동기식

 

비동기 처리란?

  • 시간이 걸리는 함수와 빨리 처리할 수 있는 함수가 섞여 실행 순서를 알 수 없을 떄
  • 함수들이 원하는 처리 순서에 맞게 프로그래밍하는 것

 


 

비동기 처리_1) 콜백 함수

함수 안에 또 다른 함수를 매개변수로 넘겨서 실행순서를 제어하는 방식

=> 함수를 실행할 때, 특정 동작이 끝난 후 실행될 함수를 전달하는 개념

function mainFunction(callback) {
    console.log("메인 함수 실행");
    callback(); // 전달받은 콜백 함수 실행
}

function myCallback() {
    console.log("콜백 함수 실행");
}

// mainFunction 실행 시 myCallback을 콜백 함수로 전달
mainFunction(myCallback);
실행 결과
-----------
메인 함수 실행
콜백 함수 실행

 

 

 

콜백 함수는 마지막 매개변수로

function order(coffee, callback) {
	//커피 주문
    //3초 기다린 후 콜백 실행
}

function display(result) {
	//커피 완료 표시
}

order("아메리카노", display); //display함수를 order함수의 매개변수로 전달

 

 

 

 

콜백 함수를 사용할 때 한번만 실행하고 끝난다면 함수 안에 익명 함수로 직접 작성 가능

function displayLetter() {
  console.log('A');
  setTimeout(() => {
    console.log('B');
    setTimeout(() => {
      console.log('C');
      setTimeout(() => {
        console.log('D');
        setTimeout(() => {
          console.log('stop!');
        }, 1000);
      }, 1000);
    }, 1000);
  }, 1000);
}

displayLetter();

 

콜백이 중첩될수록 코드가 복잡해짐 => 콜백 지옥

==> Promise를 사용하여 콜백 지옥 해결

 

 

 

 

비동기 처리_ 2) Promise(프라미스)

프라미스 객체 콜백 함수를 사용해서 실행 순서 제어

"어떤 작업이 끝나면 결과를 반환할 것을 약속하는 객체"

 

Promise의 3가지 상태
pending (대기 중) 비동기 작업이 아직 완료되지 않음
fulfilled (이행됨) 작업이 성공적으로 완료됨 (resolve())
rejected (거부됨) 작업이 실패함 (reject())

 

const myPromise = new Promise((resolve, reject) => {
    let success = true; // 성공 여부를 설정

    setTimeout(() => {
        if (success) {
            resolve("✅ 작업 성공!");
        } else {
            reject("❌ 작업 실패!");
        }
    }, 2000);
});

myPromise
    .then(result => console.log(result)) // 성공 시 실행
    .catch(error => console.error(error)) // 실패 시 실행
    .finally(() => console.log("🎯 작업 완료!"));
실행 결과
-----------
✅ 작업 성공!
🎯 작업 완료!

 

 

 

 

Promise 체이닝

여러개의 비동기 작업을 연결해서 실행

function getUser() {
    return new Promise(resolve => {
        setTimeout(() => resolve("👤 사용자 데이터"), 1000);
    });
}

function getPosts(user) {
    return new Promise(resolve => {
        setTimeout(() => resolve(`${user}의 게시글`), 1000);
    });
}

getUser()
    .then(user => getPosts(user))
    .then(posts => console.log(posts)) // "👤 사용자 데이터의 게시글"
    .catch(error => console.error("❌ 오류 발생:", error));

 

Promise 역시 체이닝을 사용해서 연결을 계속하면 콜백 지옥처럼 코드가 복잡해질 수 있음!

 

 

 

 

비동기 처리_3) async/await

  • Promise를 더 쉽게 사용할 수 있도록 도와주는 최신 문법
  • 콜백 함수나 .then() 체이닝 없이 가독성이 뛰어난 비동기 코드를 작성 가능
async 비동기 함수를 정의하는 키워드
await 비동기 함수 내에서 Promise가 완료될 때까지 기다림

 

 

 async function init() {
 	try {
 		const response = await fetch('https://jsonplaceholder.typicode.com/users');
 		const users = await response.json();
 		console.log(users);
 	} catch (err) {
 		console.error(err);
 	}
 }
 
 init();

 

 


노드의 모듈

  • 노드에서는 대부분의 기능을 모듈 단위로 나누어 작성
  • 기능별로 만들어 놓은 함수

 

 

모듈의 종류 3가지

1)  내장 모듈(노드가 제공)

2)  내가 만든 모듈

3)  서드파티 모듈

 

 

 

모듈의 사용 이유

  • 코드의 재사용화, 라이브러리화를 위해

CommonJS 모듈 시스템

✅ module.exports

require()

// math.js (CommonJS)
const add = (a, b) => a + b;
const subtract = (a, b) => a - b;

// 모듈을 내보내는 방법 (객체 형태로 여러 개 내보낼 수 있음)
module.exports = subtract;
module.exports = { add, subtract };
// app.js (CommonJS)
const math = require('./math'); // 모듈 가져오기

console.log(math.add(5, 3)); // 8
console.log(math.subtract(10, 4)); // 6

 

 

ES 모듈 시스템

 

✅ 모듈 내보내기 (export)

// math.mjs (ES 모듈)
export const add = (a, b) => a + b;
-----------------------------------------
const goodbye = (name) => {
    console.log(`${name}님, 안녕히 가세요`);
}
export default goodbye;

 

 

 

✅ 모듈 가져오기 (import)

// app.mjs (ES 모듈)
import { add, subtract } from './math.mjs';

console.log(add(5, 3)); // 8
console.log(subtract(10, 4)); // 6

 

이 게시글은 2025년 1월 14일 진행된 DGB금융그룹의 IT's DGB iM Challenger 대한민국 디지털 인재 양성 프로젝트 공모전 발대식 및 본선 대회 후기입니다.

 

 

1. 대회 공고 확인 및 팀 구성

https://dgb-challenger.co.kr/15

 

 

금융 관련 공모전을 기다리던 중 발견한 DGB금융그룹의 IT's DGB iM Challenger 공모전 !

이름이 길어서 복잡해 보이지만 결론은 디지털 기술을 적용한 금융 관련 상품이나 서비스 아이디어를 개발하는 것이다.

 

예선 - 본선 - 파이널 라운드, 사이에 전문 교육 등등 호흡이 긴 공모전이지만 일단 본선 대회 진출을 목표로 준비를 시작했다.

 

 

 

 

 

2. 예선 준비

우리 팀은 나와 내 친구 2명이었고 둘 모두 개발을 전공한 (예비) 개발자이다.

금융 지식 보유자, 디자이너 없이 개발만 아는 팀원 두 명이었지만 본선 대회에 진출할 수 있었다.

 

예선 준비를 하면서 친구와 다양한 아이디어를 논의해보았고 우리는 금융 관련 지식이 별로 없는만큼 어려운 주식 투자, 펀드, 부동산 등 보다는 보다 단순한 (우리들이 말하기로는 보다 말랑말랑한) 주제를 선정하고자 했다.

 

 

 

이렇게 전년도 수상 정보도 조사해보고 노션을 파서 회의를 진행했다.

 

우리 팀이 최종적으로 선정한 아이디어는 "맞춤형 DGB 캐릭터 키우기 서비스" 이다. 

 

아이디어 회의를 진행하면서 주목했던 2가지는

 

1) 요즘 유행하는 서비스가 무엇인가? => 피크민과 같은 캐릭터 서비스

2) DGB금융그룹이 원하는 건 무엇일까? => iM뱅크가 시중은행이 된 만큼 인지도 상승시키기

였고 전년도에도 dgb 캐릭터를 활용한 아이디어가 수상했던 것을 보아 이를 활용해서 주제를 선정했다.

 

(그런데 예선 자료를 만들면서는 전년도 아이디어랑 너무 유사해보일까봐 걱정되었다. 그래도 결론적으로는 본선까지 간 걸 보면 나름 잘 정한 주제인 것 같다)

 

 

우리는 예선 접수할 때 기술 구현은 하지 않았다. (예비)개발자 2명이었지만 둘 모두 공모전이 처음이었기에 주제 정하고 구체화하는데 더 집중했다.

 

예선 제출날 공모전 홈페이지 서버가 이상해서 메일로 제출하고 하는 이슈가 있었지만 그래도 정상적으로 접수 완료가 되었다.

 

3. 본선 진출 팀 발표

본선 진출 팀 발표는 12월 31일에 이루어졌다. 2024년의 마지막 날 발표라니.. 만약 떨어졌다면 꽤 씁쓸했을 것 같다.

 

발표는 공모전 홈페이지 팝업 및 공지사항으로 이루어졌고 나는 오후 5시쯤 들어가봤는데 낮 즈음에 발표가 나 있었다.

가나다 순이라 홈페이지 들어가자마자 금잔디가 있어서 바로 발견하고 흥분 MAX 상태로 친구에게 전화했다 ㅋㅋ

 

후에 뉴스에서 보니까 총 89팀이 예선 접수했고 그 중 20팀이 발대식 및 본선 대회에 진출했다고 한다.

 

 

4. 본선 대회 준비

본선 진출 팀 발표 이후 1주일 정도 본선 발표용 자료 제출 기한이 주어진다. 이때 기존 주제를 벗어나지 않는 선에서 아이디어 디벨롭이 가능하다. 우리 팀은 소비 분석 케이스를 더 구체화하고 추가 캐릭터를 제작해서 포함했다.

 

이때 자료에 동영상, 슬라이드 쇼, 폰트 등 잘 체크해서 제출하라고 공지를 꼼꼼히 해주신다. 우리 팀은 혹시나 폰트가 깨지면 PDF로 발표하려고 슬라이드 쇼 같은것도 안넣었는데 발표 후 생각해보니까 조금이라도 관심을 주목하기 위한 요소로 넣을 걸 그랬나 싶었다. (아무래도 20팀이 10분씩 계속 발표하다보니 본선 대회가 루즈해지는 것 같았다.)

 

 

학교 세미나실에 가서 발표 연습도 하고, 우리 팀은 서울에서 대구까지 가야하므로 왕복 KTX와 호텔도 1박 예약했다. 본선 대회 때는 서울 기준 KTX 편도 43500원, 왕복 87000원을 지원해준다. 본선 대회 후 일주일 정도 후에 바로 입금이 되었다!

 

 

5. 리허설

본선 대회 전날인 1/13일에 간단한 리허설이 있었다. 본선 대회 발표 순서(랜덤)대로 마이크 테스트 및 PPT 오류가 없는 지 확인한다. 마이크는 핸드 마이크와 핀 마이크 중 고를 수 있다. 대부분 팀들이 핸드 마이크를 썼는데 발표 때 한 손에는 포인터를 들어야 하니 이를 고려해서 선택해도 좋을 것 같다. 아무래도 핸드 마이크를 선택하면 손을 사용하는데 제약이 있다.

 

 

KTX 타고 대구로 이동~ 동대구역에서는 택시를 타고 갔다.

 

입구에서 단디와 똑디가 반겨준다. 아주 반가워서 친구한테 여기서 사진 한 장 찍어줄까? 했는데 거절함 ㅋㅋ쿄

iM뱅크 제2본점이라는데 회사 아주 삐까뻔쩍했다.

 

 

그리고 발대식 및 본선대회가 이루어질 5층 홀 ! 

 

리허설 때 나누어주신 안내 종이. 총 20팀이라 7, 7, 6 팀 씩 끊어서 발표했다. 

 

 

 

6. 발대식

본선 대회 날의 오전 동안에 발대식이 이루어졌다. DGB금융그룹 회장님과 임직원 분들, 대구 국회의원, 대구 지역의 대학교 교수님들 등 많은 분들이 참석하셨다.

 

4층 다목적 홀이 참가학생들 대기 공간 및 짐을 두고 점심도 먹는 공간이었다. 본선 대회 당일날 도착하면 단체 티를 나누어주신다. 민트색이라고 미리 공지가 되어있었어서 소화할 수 있을까,, 싶었는데 약간의 청록색? 계열이라 다행이었다 

 

사이즈가 95, 100, 105 로 나뉘어져있고 골라서 가져갈 수 있지만 전체적으로 크기가 매우 컸고 기모가 아주 부드러웠다 잠옷으로 입으면 딱일듯

 

 

 

 

발대식 세레모니와 축하 말씀이 있고 대한 변리사 협회의 변리사님이 1시간동안 강의도 해주셨다. IT's DGB iM Challenger 공모전은 교통비 지원, 단체복 제공 등등 모든게 완벽한데 하나 아쉬운 점이 있다면 바로 발대식 및 본선 대회가 이루어지는 공간의 학생들 자리였다. 

 

DGB금융그룹 제공

 

이렇게 계단처럼 된 공간에 앉는 형식인데 자리가 너무 좁고 학생들이 촘촘히 앉아야해서 등을 기대거나 다리를 펼수도 없다. 본선대회날은 거의 하루 종일 여기 앉아있어야 하는데 우리 팀 뿐만 아니라 다른 학생들도 힘들어하는 것 같았다. 

여기 공간이 이런 행사를 하기에는 매우 예쁘고 좋지만 학생들 앉는 공간을 조금만 더 확장해주셔도 좋을 것 같다..

 

 

 

 

발대식 이후 점심 식사를 하고 본선 대회가 진행된다. 도시락도 매우 맛있어 보이는 걸로 제공해주시는데 난 긴장이 되서 거의 못먹었다ㅠㅠ 너무 아쉽다

 

 

발표 공간 옆에 이렇게 간식과 생수도 아주 빵빵하게 제공된다!

 

 

7. 본선 대회

 

밥을 먹고 올라오면 이렇게 본선 대회를 위한 준비가 마쳐져있다. 심사위원은 6분 정도이고 외부 위원 2분에 DGB금융그룹 내부 인사 4분(iM뱅크 ict 및 디지털 사업부의 부장님들 4분) 정도였다. 

 

발표 후 심사위원 Q&A는 없으며 발표자 앞에 10분 타이머와 PPT를 볼 수 있는 스크린을 준비해 주셨다. 팀 당 제공되는 10분 시간이 끝나면 마이크가 자동으로 OFF될 거라고 하셨는데 10분을 초과한 팀은 없었다.

 

모든 발표가 종료된 후 바로 점수를 집계해서 파이널라운드에 진출할 10팀을 발표한다.

 

무려 20팀의 발표를 들으면서 느낀 점은 아이디어는 한정되어 있지만 이를 어떻게 분석하고 표현하는 지가 중요한 것 같다는 점이다. 다른 팀들의 주제로는 소액 주식 투자 상품, AI를 활용한 부동산 서비스, 자산 관리 서비스 등이 있었는데 금융 공모전을 준비해봤다면 한번쯤은 생각해봤을 주제들이었다. 조금 더 시선이 가고 퀄리티 있어보이는 발표는 누구나 생각할 수 있는 주제에 대해 기존 서비스와의 차별점을 구체화한 발표들이었다.

 

우리 팀은 아쉽게 파이널라운드에는 진출하지 못했지만 발대식 및 본선 대회에 진출한 것만으로도 너무 좋은 경험이었다!

 

 

파이널 라운드에 진출하지 못한 10팀에게는 10만원 상당의 기념품이 제공된다고 홈페이지에 나와있었는데

10만원 상당의 기념품은 바로 10만원 백화점 상품권이었다 ㅋㅋㅋ

 

쓸데없는 기념품 보다 돈으로 주는 은행 최고다

 

행사 종료 후 동대구역 앞에서 막창도 먹고 KTX를 타고 서울로 왔다

 

 

 

 

8. 느낀점

첫 공모전 도전이었는데 본선에 진출해서 공개PT라는 의미있는 경험을 할 수 있어서 좋았다. 기획한 아이디어에 대해 개발까지 완료한 건 아니지만 주제를 구체화하고 발표 자료를 만들면서 마이데이터 등 금융권의 디지털 서비스에 대한 이해도도 높아졌다. 이 공모전은 예선 제출부터 만약 다음 라운드에 계속 진출한다면 본선 대회, 전문 교육, 파이널 라운드 등 호흡이 긴 공모전이지만 본선 대회에 진출하는 것만으로도 큰 경험이 되니  DGB금융그룹 공모전을 고민 중인 분들이 계시다면 일단 도전해보길 강추한다.

~막학기 취준생이 오픈소스 기여를 접하게 된 과정~

 

1. 오픈소스 기여? 도전해 말아..

11/1(금) 오픈소스 멘토링 신청

 

때는 금요일 오전 오늘도 카페 가서 공부해야지..하고 누워서 핸드폰하며 뒹굴다가

구글에 싸피 후기를 검색 -> 발견한 블로그의 다른 게시글도 구경 -> 오픈소스 멘토링 후기 발견 순으로

인제님의 오픈소스 멘토링을 접하게 되었다!

 

내가 당시 본 블로그 후기글은 낙관적 허무주의 개발자님의 이 후기! 

https://jun10920.tistory.com/39

 

오픈소스 기여하기 / Open Source Contribute - Spring AI

안녕하세요!이번 주제는 오픈소스에 기여해 보는 경험을 공유하기 위해서 왔습니다.프로젝트를 진행하면서 어느 정도 기능 개발에 익숙해져서 자신감에 차 있던 저는오픈소스를 이해하고, 이

jun10920.tistory.com

 

https://medium.com/opensource-contributors/%EB%AA%A8%EC%A7%91%EC%A4%91-%EC%98%A4%ED%94%88%EC%86%8C%EC%8A%A4-%EB%A9%98%ED%86%A0%EB%A7%81-7%EA%B8%B0-%EC%B0%B8%EC%97%AC%EC%9E%90%EB%A5%BC-%EB%AA%A8%EC%A7%91%ED%95%A9%EB%8B%88%EB%8B%A4-a8e0f94a2522

 

인제님의 오픈소스 멘토링은 매우 체계적으로 진짜 누구나 이슈를 선정하고 첫 PR을 생성할 수 있도록 도와주는 과정 같았다. 그동안 오픈소스, 오픈소스 기여가 어떤 내용인지는 알고 있었지만 진짜 이렇게 많은 개발자들이 이슈를 올리고 또 해결하고 자유롭게 오픈소스가 발전되고 있다는 건 처음 접하였다.

 

오픈소스 멘토링 후기글들을 여럿 찾아보고, 노션도 구경하며 신청서를 제출할까 말까 많이 고민하였다. 나는 못할 것 같은데... 싶다가도 매일이 똑같은 이 시기에 새로운 도전을 해보고 싶어서 한시간 정도는 망설이다가 신청서를 제출하였다!

오픈소스 멘토링에 왜 참여하고 싶은지, 그동안 여러 스터디를 통해 다른 사람들과 함께 개발하는 경험을 쌓았던 내용을 담아서 작성했다.

 

 

11/5 (화) 멘토링 선정

신청서를 제출하고 선정이 될 수 있을까... 기다리다가 카톡방 알람이 울리고 멘토링에 선정되었다는 연락을 받았다. 무료한 일상에 도파민 터질 일정이 추가되었다는 사실에 너무너무 좋았다. 

 

 

 

 

 

2. 이슈 선정부터~ 본격 기여 시작

11/21 (목) ~ 11/23 (토), 11/24 (일)

일요일 대면 멘토링 전에 카톡으로 이슈를 선정하고 피드백을 받는다!

 

나는 평소에 많이 사용해 본 spring, spring boot를 첫번째로 이슈 탐색을 시작하였다.

 

 

그런데 생각보다 인제님의 이슈 선정 가이드에 적합한 이슈가 보이지 않았다. 그래서 범위를 더 넓혀서 hibernate나 swagger, jpa, redis 등 사용해 본 경험이 있는 오픈소스 중에 관심 가는 아이들을 살펴보았다. 그 중에서도 사실 spring data reids에 마음이 조금 더 갔는데 아무래도 이 시기에 진행했던 졸업 연구 마지막 단계에서 spring data redis를 사용해서 그랬던 것 같다.

 

redis는 요즘 정말 많이 사용된다고 해서 나도 자세히 공부해보고 싶었는데 졸업 연구에 적용하는 과정은 import하고 캐시 애노테이션을 사용하고 너무 단순하게?(진짜 그냥 갖다 쓰는 정도로..) 사용한 것 같아서 아쉬웠다. 그래서 redis 이슈를 선정해서 분석해보면 좋을 것 같아 더 열심히 이슈를 찾았다.

 

 

나는 최종적으로 

 

이렇게 2가지 이슈를 선정해 보았고 인제님 피드백을 바탕으로 spring data redis의 이슈를 최종적으로 선택하였다.

 

 

 

 

내가 선택한 이슈는 spring data redis에 properties 파일로 캐시 설정을 받아오는 새로운 기능을 추가하자는 이슈였다.

https://github.com/spring-projects/spring-data-redis/issues/1510

 

 

이슈 내용은 쉽게 이해가 돼서 간단할 거라고 생각했는데 생각보다 고려해야 할 내용이 많은 이슈였다.

 

결론적으로 이러한 작업을 거쳤다.

 

1. redisCacheConfiguration에 redis-cache.properties로 캐시 설정을 받아오는 코드 작성

2. 유닛테스트 작성

3. 실제로 사용자가 어떻게 properties 파일을 두면 되는 지 테스트

4. properties 파일이 없는 경우 고려

5. 잘못된 input이 들어올 경우 고려

 

 

 

PR생성!

사실 일요일 멘토링에서 PR까지 생성 완료했어야 했는데 configuration 코드 보완하고 3번 작업하느라 멘토링 3시간이 훌쩍 지났다. 그래서 멘토링 이후에 인제님께 코드 리뷰를 한번 더 받고 pr을 올리게 되었다.

https://github.com/spring-projects/spring-data-redis/pull/3059

 

 

pr을 생성할 때는 spring data redis의 기여가이드도 잘 살펴보고 신중히 글을 작성했다ㅋㅋ 

뭔가 내가 작성한 코드가 오픈소스에 pr로 올라가다니,, 너무 신기했다.

https://github.com/spring-projects/spring-data-redis/blob/main/CONTRIBUTING.adoc

 

 

3. 기여를 마치며, 느낀점

pr생성까지 마무리했지만 아직 끝이 아니다. 메인테이너 분들의 리뷰를 기다리고 merge 될 수 있을때까지 계속 작업을 해야 한다. 그동안 테스트 케이스를 다시 점검하고 다른 이슈들도 기웃기웃해 봐야겠다.

처음에는 이슈를 봐도 하나도 눈에 안들어오고 무엇보다 영어 독해가 생각보다 너무 안되고!! 힘들었지만 그래도 한 번 해보니까 자신감이 생기는 것 같다.

 

새로운 기능 추가가 아니더라도 오타 삭제나 누락된 단어 추가 같은 이슈도 기여해보면 좋을 것 같다.(사실 이번에 작업을 하면서 내가 오픈소스에 새 기능을 추가하는거... 괜찮은건가 가능한건가 싶으면서 조금 부담이 되었다ㅎ 하지만 뭐 일단 해보고 메인테이너분들의 리뷰를 받자는 마음으로 했다 결국엔 해냈다)

 

또, 오픈소스 멘토링은 너무너무 좋은 경험이었다. 내가 사용해보지 않은 오픈소스도 다른 분들이 작업하시는 걸 보고 또 마지막에 인제님께서 각각 어떤 오픈소스에서 어떤 이슈를 선정해서 작업했는 지 쭉 말씀해주셔서 여러 오픈소스에 대한 이야기를 들을 수 있어서 너무 좋았다.!

 

 


Redis 관련 참고한 기업 기술블로그

 

https://techblog.woowahan.com/2709/

 

선물하기 시스템의 상품 재고는 어떻게 관리되어질까? | 우아한형제들 기술블로그

안녕하세요. 저는 주문서비스팀의 서버개발자 강홍구입니다. 이 글에서는 배달의민족 선물하기 서비스의 상품권 재고관리를 위한 시스템 설계에 대한 경험을 공유드리고자 합니다. 들어가며

techblog.woowahan.com

 

https://techblog.gccompany.co.kr/redis-kafka%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%84%A0%EC%B0%A9%EC%88%9C-%EC%BF%A0%ED%8F%B0-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EA%B0%9C%EB%B0%9C%EA%B8%B0-feat-%EB%84%A4%EA%B3%A0%EC%99%95-ec6682e39731

 

Redis&Kafka를 활용한 선착순 쿠폰 이벤트 개발기 (feat. 네고왕)

안녕하세요. 유저혜택개발팀 쿠폰 백앤드 개발자 페이든입니다.

techblog.gccompany.co.kr

 

+ Recent posts