10월 ~ 12월
교내 데이트 매칭 웹 서비스를 런칭하다
Leets 2기에서는 ItoR 팀으로 활동을 하게 되었다. 원래라면 1기와 동일하게 Zero100 팀에 편성되어 있었지만 더 성장하고 싶었고, 더 개발다운 개발을 해보고 싶었다. 고민하다가 팀 빌딩 마감 하루 전에 성민이형에게 ItoR 팀에서 해보고 싶다고 어필했고, 흔쾌히도 형이 허락을 해줘서 합류를 하게 되었다. 다시 한 번 형에게 고맙다고 말하고 싶다.
지난번 Zero100 팀에서도 그러했듯이 팀 내에서 가장 실력이 낮았기에 ItoR 팀에서 운영했던 "TDD 스터디", "자바의 정석 스터디"를 열심히 하려고 했었다. 하지만 우테코랑 비교과 활동 때문에 목표만큼 하지 못했다. 이때 스터디를 등한시 했던 게 후회가 된다. 팀원들에게 지식을 나눠주기 보다 흡수하기 바빠 도움을 주지 못해 미안했다. 내년 스터디에서는 지식을 받는 것 보다 더 많이 나누어주는 사람이 되어야 겠다는 생각이 든다.
그렇게 스터디 기간이 끝나고 실전 프로젝트의 날이 밝아왔다. 주제는 회의결과 "무드를 통해 1:1 매칭을 시켜주는 데이팅 채팅 웹 서비스"였고, 이름도 "MoodMate"로 지어졌다. 너무 마음에 드는 주제였다. 유저를 끌어당길 수 있고, 나아가 수익 창출까지 기대할 수 있는 그런 주제였다고 생각했기 때문이다. 지금도 물론 너무 좋은 주제였다고 생각한다 ㅎㅎ
주제 회의 다음 날 바로 프론트 팀원들과 유저플로우를 작성했다. draw.io 사이트에서 작성했는데, 데이터베이스 과목 때 draw.io에서 ERD를 설계하는 과제를 해봤기에 사이트는 익숙했다. 그런데 마름모, 평행사변형, 원 등등 ERD 설계를 할 때 사용하지 않았던 도형을 써야했기에 새로웠고 다들 익숙치 않았기에 시간이 오래걸렸다. 그렇지만 만들면서, 만들고 나니 왜 유저플로우를 작성해야 하는지 깨달았다. 유저의 입장에서 서비스를 어떻게 행동할 지 미리 정리함으로서 유저에게 편리한 방향으로 순서를 바꿀 수 있었고, 뭔가 2% 부족했던 프로젝트의 기능 흐름이 시각자료로 정리되면서 fix 될 수 있었다.
유저플로우 설계하고 다음날, 백엔드 팀과 저번 프로젝트와 마찬가지로 ErdCloud라는 서비스를 이용해 ERD를 구축했다. 처음에 했었을때는 오래걸렸었는데, 한번 해봤던거고 팀원들도 DB를 잘해서 구축하는데 1시간 반 밖에 안걸렸다.
이후 프론트에게 완성된 ERD를 보내주고 드디어 역할 분담 회의를 했다. 역할은 크게 "로그인기능", "CI/CD", "채팅기능", "매칭기능" 이였다. 앞에서도 말했듯이 팀원들의 실력이 훨씬 좋았기에 마지막에 남은 파트를 맡자고 속으로 생각했고 로그인 기능이 남을거라고 예상했다. 그렇게 팀원들에게 우선권을 부여하고 남은 파트를 가져가게 되었는데, 남은 파트는 "매칭기능"이였다... "으...응? 제일 핵심기능이 남았다고? 잠시만... 그걸 내가 구현해야 한다고?" 덜컥 겁이났다. "구현하지 못하면 어쩌지?"라는 생각이 들었고, 팀원들에게 역할을 바꾸어 달라고 할까 고민이 들던 와중 "우테코"에 지원당시 나의 다짐이 떠올랐다.
"후회하지 말고 도전해서 최선을 다하자"
내가 실력이 가장 낮다는 이유로 다시 한 번 경험할 수 없을지도 모르는 좋은 기회를 다른 팀원에게 넘겨주고 쉬운 파트를 가져온다면 나중에 후회가 남을 것 같았다. 그래서 매칭기능을 꼭 구현해 내자고 마음을 먹었다.
위 사진은 코드 구현 전 고민의 흔적들 중 일부이다. 어떤 알고리즘을 도입할 지, 같은 학과의 이성은 어떻게 처리할 지, 선호도 리스트 순서는 어떻게 결정할 지 등등 약 1주 동안 기능 설계에만 몰두했다. 기능 설계전 매칭 알고리즘은 구글링을 하면 다 나와있을 줄 알았다. 하지만 전혀 아니였다. 찾고 찾아서 그나마 우리의 프로젝트와 비슷했던 영화관 데이트 매칭 서비스를 발견했지만, 같은 영화를 선택한 사람을 매칭시키기에 이분 매칭(DFS)를 통해서 기능구현이 가능했다. 우리는 고려 조건이 3개 였기 때문에 구현하기에는 어려움이 있었다.
그렇게 지쳐가던 찰나에 GaleShapley(Stable Matching Algorithm)에 대해 서술한 블로그를 발견하였다. 양방향 매칭 방식이였고, 각자마다 이성에 대한 우선순위 리스트를 관리해서 최적의 매칭을 만들어 내는 알고리즘이였다. 이성에 대한 우선순위를 매기는 로직을 구현해 알고리즘에 적용시킨다면 3가지 조건을 충족하는 기능을 구현할 수 있을 것 같다는 생각이 들었다. 이때부터 GaleShapley 알고리즘에 대해 파고들었다. 이후 과정은 나중에 따로 블로그에 이야기 해볼 생각이다 ☺️
최종적으로 배포 전날에 기능 구현을 완성할 수 있었다. 오래걸렸던 이유는 자바로 작성한 알고리즘을 스프링부트로 마이그레이션 하면서 예상치 못한 오류와 스프링부트에 대한 개념 부족 때문이였다. 이 과정속에서 스프링부트를 방학 때 열심히 해야겠다고 100번은 다짐을 했던 것 같다... ㅎ
배포 당일 날 팀원들과 모여서 배포 전 작업들을 마무리 지었다. 나는 Cron으로 오후 9시 5분에 알고리즘을 실행하도록 자동화를 시켜놓는 작업을 했다. 그렇게 다들 마무리 작업이 끝나고 드디어 서비스를 배포했다.
출시한지 5분만에 약 30~40명의 실제 유저의 데이터가 DB에 들어왔다. 너무 감격스러웠고 그동안의 고생을 보상받는 느낌이였다. 이때 까지는 즐거웠지 😁
그렇게 유저의 정보가 잘 들어오는 것을 보고 다같이 회식을 하러갔다. 그렇게 회식을 하고있던 도중 9시 5분이 되었고, 1:1 매칭이 잘 이루어졌는지 DB를 접속해서 확인했다. "엥....? 뭐야 왜 매칭이 안됐지?" 급하게 민호에게 로그를 확인해 달라고 부탁했고, NULL 값으로 인한 ERROR 로그가 찍혀있었다.
"아뿔싸!" 여러가지 문제가 존재했다. 첫번째, 회원가입 시 유저가 정보를 입력하는 단계를 모두 거치지 않거나, 새롭게 지금 막 정보를 차례대로 입력하는 경우 입력되지 않은 값은 NULL로 처리되고 있어 user_id는 존재했지만 user_nickname이 아직 NULL인 유저의 경우 getUserNickName() 호출 시 Nullpointerexception이 발생되는 문제. 두번째, user_id를 외래키로 가지는 prefer entity에 몇몇 유저의 user_id가 중복으로 insert 되는 문제. 세번째, 제일 핵심적인 문제였다고 생각되는데 자바에서 스프링부트로 마이그레이션 하는 과정에서 몇줄의 코드가 누락이 되었었고, 원래 partnerID get 해와야 하는데 partnerUserId를 get 해오는 등의 실수가 있었다.
결국 서비스 제공을 다음 날로 미룰 수 밖에 없었다. 이때 베타테스트의 중요성을 뼈저리게 느꼈던 것 같다. 제일 핵심적인 문제(세번째)가 발생하게 된 계기가 나의 실수였기에 팀원들에게 너무 미안했다. 그래서 회식이 끝나고 난 후 집가는 버스에서부터 집 도착 후 새벽까지 알고리즘을 수정했고, 다행히도 문제를 해결할 수 있었다.
다음 날, 각자 문제를 해결한 후 9시 5분까지 긴장을 하며 기다렸다. 9시 5분이 되고 긴장된 상태로 DB를 확인해봤는데...
약 50개의 room_id가 까지 생성되어 있었고, 서로다른 남녀의 user_id가 insert 되어 있었다. (모자이크 처리)
총 50쌍의 커플이 매칭이 된것이다! 목격한 당시 기쁨보다 안도의 한숨을 내쉬었던 것 같다. 😭
이후로 19~25일까지 서비스는 정상적으로 유저에게 제공할 수 있었고, 400명의 유저를 유치하며 성공적으로 마무리 할 수 있었다. 물론 진행하면서 몇 가지 문제가 더 있기도 했는데, 어찌저찌 잘 해결되어서 다행이였다.
지금와서 가장 기억나는 2가지 문제에 대해 말해보자면,
첫번째, 유저가 200명대 일때는 문제가 발생하지 않았는데 약 300명정도 되었을 때 알고리즘을 돌리면 에러가 발생했다. 로그를 확인해 봤을 때, 총 N명의 쌍이 매칭이 되어서 while문이 종료되어야 했는데 종료되지 않았고 그렇기에 무한루프가 발생하였다. 분명 로직상 문제가 없었고, 다시 알고리즘을 실행하면 정상적으로 매칭이 성공했기 때문에 서비스를 제공하는데는 번거로움만 있었을 뿐 문제는 되지 않았다. 아직 원인을 찾지 못했는데, 3월에 서비스를 다시 오픈해야 하기에 2월에 원인파악을 해볼 생각이다.
while (engagedCount < N) { // 모든 커플이 매칭될 때까지 반복
Man free = null;
for (Man man : men.values()) { // 매칭되지 않은 남자를 찾음
if (!man.isEngaged()) {
free = man;
break;
}
}
if (free != null) { // 매칭되지 않은 남자가 있으면
System.out.println("남자 " + free.getName() + "이(가) 매칭을 시도합니다.");
for (String w : free.getPreferences()) { // 그 남자의 선호도 목록을 순회
Woman woman = women.get(w); // 선호하는 여자를 찾음
if (!free.isEngaged() && !free.getProposed().contains(woman)) { // 남자가 아직 매칭되지 않았고, 아직 고백하지 않은 여성에게만 고백
System.out.println(" " + free.getName() + "이(가) " + woman.getName() + "에게 고백합니다.");
free.getProposed().add(woman); // 남자가 고백한 여성을 기록
if (woman.getPartner() == null) { // 여자가 아직 매칭되지 않았으면
woman.setPartnerUserId(free.getUser().getUserId()); // 여자와 남자를 매칭
woman.setPartner(free.getName());
free.setEngaged(true); // 남자의 상태를 매칭됨으로 변경
engagedCount++; // 매칭된 커플 수 증가
System.out.println(" " + woman.getName() + "은(는) " + free.getName() + "과(와) 매칭되었습니다.");
} else { // 여자가 이미 매칭되어 있으면
Man currentPartner = men.get(woman.getPartner());
System.out.println(" " + woman.getName() + "은(는) 이미 " + currentPartner.getName() + "과(와) 매칭되어 있습니다.");
if (morePreference(currentPartner, free, woman)) { // 여자가 새로운 남자를 더 선호하면
woman.setPartnerUserId(free.getUser().getUserId());// 여자와 새로운 남자를 매칭
woman.setPartner(free.getName()); // 여자와 새로운 남자를 매칭
free.setEngaged(true); // 새로운 남자의 상태를 매칭됨으로 변경
currentPartner.setEngaged(false); // 현재 파트너의 상태를 매칭되지 않음으로 변경
System.out.println(" " + woman.getName() + "은(는) " + free.getName() + "과(와) 매칭되었습니다. (이전 매칭 해제)");
} else {
System.out.println(" " + woman.getName() + "은(는) 여전히 " + currentPartner.getName() + "과(와) 매칭되어 있습니다. (새로운 남자 선호도 부족)");
}
}
}
}
}
}
매칭 알고리즘 코드의 일부이다. 코드를 간략하게 설명하면 N은 총 커플 수이고 남자들과 여자들의 수를 비교했을 때 더 작은 성별의 수가 N이 된다. (ex. 남자 20명, 여자 18명 → N = 18) 따라서 engagedCount(매칭된 커플 수)가 N과 같아지면 while문이 종료되는 방식이다.
예상되는 문제로는 enagedCount++이 실행되어야 했으나, context switching 과정에서 누락되어 +1이 반영이 안되었고, 커플은 매칭이 다 되었으나 N과 engagedCount가 같지 않아 while문이 종료되지 않는 것 같다고 추측이 된다. 물론 추측이기 때문에 좀 더 알아봐야 하는 부분이다.
두번째, "이미 매칭된 커플은 서로의 선호도가 높았기에 매칭되었으므로 또 다시 매칭될 확률이 높다"는 문제가 있었다. 테이블에 저장된 user_id를 무작위가 아닌 순서대로 가져왔기에, 또 다시 매칭될 확률이 매우 높았다.
먼저 문제를 해결하기 위해 user_id를 테이블에 저장된 순서로 가져오기 때문에, 가져와서 shuffle을 하는 방식으로 리스트를 재구성하였다. 그러고 나서 user_id 이미 매칭된 커플을 관리하는 who_meet이라는 테이블을 만들어 매칭 기록을 남기고, 어떠한 남녀를 매칭 시키기 전 who_meet 테이블을 탐색하는 과정을 거쳐 매칭되었던 기록이 있다면 선호도 리스트 후순위에 배치하는 방식으로 해결했다.
public void match() {
// 활성화된 Prefer 객체들을 가져옴
List<Prefer> activeMatchTrueMale = preferRepository.findByUserMatchActiveAndGenderTrue(Gender.MALE);
List<Prefer> activeMatchTrueFemale = preferRepository.findByUserMatchActiveAndGenderTrue(Gender.FEMALE);
// 두 리스트를 합침
List<Prefer> activeMatchTrue = new ArrayList<>(activeMatchTrueMale);
activeMatchTrue.addAll(activeMatchTrueFemale);
// shuffle을 통해 무작위로 섞음
Collections.shuffle(activeMatchTrue);
// Prefer 객체들을 Person 인스턴스로 변환하고 남성과 여성 리스트에 추가
for (Prefer prefer : activeMatchTrue) {
Person person = new Person(prefer.getUser(), prefer);
if (person.getGender() == Gender.MALE) {
men.add(new Man(person.getUser(), person.getPrefer()));
} else if (person.getGender() == Gender.FEMALE) {
women.add(new Woman(person.getUser(), person.getPrefer()));
}
}
}
------------------------------------------------------------------------------------------------
public void grouping() {
Map<String, Man> m = convertListToMap(men);
Map<String, Woman> w = convertListToMap(women);
Map<String, Map<String, Man>> menGroups = groupByMood(m);
Map<String, Map<String, Woman>> womenGroups = groupByMood(w);
// 각 그룹에 대해 Gale-Shapley 알고리즘 실행
for (String mood : menGroups.keySet()) {
Map<String, Man> menGroup = menGroups.get(mood);
Map<String, Woman> womenGroup = womenGroups.get(mood);
System.out.println();
System.out.println("====================================");
System.out.println(mood + " 그룹 매칭을 시작합니다.");
System.out.println("====================================");
// 각 그룹의 남자 목록 출력
System.out.println(mood + " 그룹 남자:");
for (Man man : menGroup.values()) {
System.out.println(man.getName());
}
// 각 그룹의 여자 목록 출력
System.out.println(mood + " 그룹 여자:");
for (Woman woman : womenGroup.values()) {
System.out.println(woman.getName());
}
// 각 남자와 여자의 선호도 설정
setPreferencesForGroup(menGroup, womenGroup);
// Gale-Shapley 알고리즘 실행
new GaleShapley(menGroup, womenGroup, roomRepository, userRepository, whoMeetRepository);
}
}
private void setPreferencesForGroup(Map<String, Man> menGroup, Map<String, Woman> womenGroup) {
for (Man man : menGroup.values()) {
List<String> mainPreferences = new ArrayList<>();
List<String> secondaryPreferences = new ArrayList<>();
List<String> thirdPreferences = new ArrayList<>();
Set<String> metFemalesSet = new HashSet<>();
// 특정 남성과 매칭된 이력 조회
List<WhoMeet> metFemales = whoMeetRepository.findByMetUser2(man.getUser());
for (WhoMeet met : metFemales) {
metFemalesSet.add(met.getMetUser1().getUserNickname()); // 이전에 매칭된 여성 추가
}
// 여자 그룹을 순회하면서 남자의 선호도를 결정
for (Woman woman : womenGroup.values()) {
String womanName = woman.getName();
if (metFemalesSet.contains(womanName)) {
continue; // 이전에 매칭된 여성은 제외
}
if (!man.isDontCareSameDepartment() && man.getDepartment().equals(woman.getDepartment())) {
thirdPreferences.add(womanName);
} else if (woman.getYear() >= man.getMinYear() && woman.getYear() <= man.getMaxYear()) {
mainPreferences.add(womanName);
} else {
secondaryPreferences.add(womanName);
}
}
// 보조 선호도를 전체 선호도 목록에 추가
mainPreferences.addAll(secondaryPreferences);
mainPreferences.addAll(thirdPreferences);
mainPreferences.addAll(metFemalesSet);
// 남자의 preferences 속성에 최종 선호도 목록 설정
man.setPreferences(mainPreferences);
System.out.println(man.getName() + "의 선호도 목록: " + mainPreferences);
}
for (Woman woman : womenGroup.values()) {
List<String> mainPreferences = new ArrayList<>();
List<String> secondaryPreferences = new ArrayList<>();
List<String> thirdPreferences = new ArrayList<>();
Set<String> metMalesSet = new HashSet<>();
// 특정 여성과 매칭된 이력 조회
List<WhoMeet> metMales = whoMeetRepository.findByMetUser1(woman.getUser());
for (WhoMeet met : metMales) {
metMalesSet.add(met.getMetUser2().getUserNickname()); // 이전에 매칭된 남성 추가
}
// 남자 그룹을 순회하면서 여자의 선호도를 결정
for (Man man : menGroup.values()) {
String manName = man.getName();
if (metMalesSet.contains(manName)) {
continue; // 이전에 매칭된 남성은 제외
}
if (!woman.isDontCareSameDepartment() && woman.getDepartment().equals(man.getDepartment())) {
thirdPreferences.add(man.getName());
}
else if (man.getYear() >= woman.getMinYear() && man.getYear() <= woman.getMaxYear()) {
mainPreferences.add(man.getName());
} else {
secondaryPreferences.add(man.getName());
}
}
// 보조 선호도를 전체 선호도 목록에 추가
mainPreferences.addAll(secondaryPreferences);
mainPreferences.addAll(thirdPreferences);
mainPreferences.addAll(metMalesSet);
// 여자의 preferences 속성에 최종 선호도 목록 설정
woman.setPreferences(mainPreferences);
System.out.println(woman.getName() + "의 선호도 목록: " + mainPreferences);
}
}
선호도 목록을 관리하는 코드의 일부이다.
Collections.shuffle(activeMatchTrue);
Collection 클래스에 suffle 메서드를 활용하여 가져온 user_id를 무작위로 섞어 요소를 재배열하는 방법을 사용하였다.
// 특정 남성과 매칭된 이력 조회
List<WhoMeet> metFemales = whoMeetRepository.findByMetUser2(man.getUser());
for (WhoMeet met : metFemales) {
metFemalesSet.add(met.getMetUser1().getUserNickname()); // 이전에 매칭된 여성 추가
}
// 여자 그룹을 순회하면서 남자의 선호도를 결정
for (Woman woman : womenGroup.values()) {
String womanName = woman.getName();
if (metFemalesSet.contains(womanName)) {
continue; // 이전에 매칭된 여성은 제외
}
if (!man.isDontCareSameDepartment() && man.getDepartment().equals(woman.getDepartment())) {
thirdPreferences.add(womanName);
} else if (woman.getYear() >= man.getMinYear() && woman.getYear() <= man.getMaxYear()) {
mainPreferences.add(womanName);
} else {
secondaryPreferences.add(womanName);
}
}
// 보조 선호도를 전체 선호도 목록에 추가
mainPreferences.addAll(secondaryPreferences);
mainPreferences.addAll(thirdPreferences);
mainPreferences.addAll(metFemalesSet);
// 남자의 preferences 속성에 최종 선호도 목록 설정
man.setPreferences(mainPreferences);
남자와 여자의 선호도 리스트 관리 방법이 동일하기에 남자의 선호도 리스트만 첨부하였다. 보면 who_meet 테이블을 탐색하는 과정을 거쳐 for문에서 이전에 매칭된 여성이면 제외한 후 마지막에 mainPreferences.addAll(metFemalesSet)을 해주는데, 이 과정이 선호도 리스트에 제일 후순위에 배치하는 과정이다. HashSet을 사용한 것은 이미 매칭된 사람 끼리 선호도를 관리하는 것은 의미가 없다고 생각했기에, List가 아닌 Set으로 추후 리스트에 add할때 순서를 보장하지 않도록 했다.
이 무드메이트라는 프로젝트를 하면서 너무 재미있었고, 많은 것을 배우고 느낄 수 있었다. 서비스를 만들기까지 고생했던 팀원과 동아리 부원들에게 감사하다는 마음을 표한다. 뿐만 아니라 서비스를 홍보해주기 위해서 힘써주신 나와 팀원들의 지인분들 그리고 서비스의 방향성에 관해서 조언해 주신 조용진 멘토님께 감사인사를 올린다.
그 외 활동
🏃♂️비교과 🏃♂️
사진에는 없는데 "기업과 리더십" 소프트웨어학과 수업에서 TA로서도 활동했다. 총 7개의 비교과 활동을 했고, 2개 비교과 활동(진로동아리, 문화교류)에서 팀장을 맡았다. 학업과 병행하느라 힘들긴 했지만 너무 뜻깊고 배울 점이 많은 활동들이여서 하기를 잘했다는 생각이 든다 ☺️
유학생 멘토링과 외국인 유학생 문화교류 프로그램은 시간 조율이 쉽지않아서 끝까지 이수하지는 못했지만, 같은 컴퓨터공학과 말레이시아인 친구를 만들 수 있어서 의미있는 활동이였다. 머신러닝을 전공한다고 하는데 엄청 대단하다고 생각이 들었다. 😯
제일 하길 잘했다고 생각이 들게 된 계기는 좋은 사람을 만날 수 있었기 때문이다. 튜터링과 전공과 전공 사이 활동에서는 후배들의 공부하고자 하는 열정을 보고 더 열심히 공부해야 겠다는 다짐을 할 수 있었고, 풀스택 진로동아리에서는 실력자분들과 좋은 멘토님을 만나 여러가지 값진 조언을 들을 수 있었다.
그만큼 열심히 참여했고 운이 따랐는지 의미있는 상도 받을 수 있었다.
참여한 튜터링 프로그램에서 장려상을 받게 되었다!
처음에는 내가 가르칠 만한 자질이 될까 하는 생각이 들었었는데, 상장을 받고 나니 주변 사람들에게도 나의 전문성과 노력을 인정받았다는 사실에 자신에 대한 믿음을 높일 수 있었다.
튜티들이 열심히 참여해줬기 때문에 상장을 받을 수 있었다. 열심히 해준 튜티들에게 다들 고맙다고 수고했다는 말을 전한다.
🧑💻 외부활동 🧑💻
외부활동으로는 INFCON에 참여했다.
INFCON에 많은 강연을 들었는데 기억나는 것은 2가지 정도이다. 첫번째는 "지소라"님의 2곳 중 1곳은 무조건 합격하는 개발자 이력서 만들기고 두번째는 "김영한"님의 어느 날 고민 많은 주니어 개발자가 찾아왔다 2이다.
지금도 여전히 넘어야 할 산들이 많지만, 인프콘에 참석했을 시에는 산 언덕을 올라가는 방법도 잘 몰랐다. 그런데 강연들의 주제가 주니어~시니어 개발자 정도의 개발 지식을 요구하는 것 같았고, 있는 강의들 중에 이해가 되고 도움이 될 것 같은 강연들로 선정하였고 위 2개도 그 중 일부이다.
먼저 지소라님의 강연의 경우 기억나는 건 이력서의 WHY, HOW, WHAT 구조, 이력서는 구글독스(or 피그마), 포트폴리오는 노션으로, AS-IS - Challenge - TO-BE 구조이다. 강연이 너무 도움이 되었고, 무엇보다 강사님의 딕션이 좋아 이해가 잘되었다. 나중에 이력서를 쓸 때에는 지소라 님의 강의를 구매해 들어볼 생각이다.
김영한님의 강연의 경우 기억나는건 MyBatis와 JPA의 한국과 외국 동향을 비교해서 보여주셨던 점이다. 지금은 한국도 JPA를 쓰는 곳이 많아졌는데, 불과 몇년전까지만 해도 한국은 MyBatis, 외국은 대부분 JPA를 많이 사용했다고 한다.
Leets 1기에서 Zero100 팀에 있을 때 초반에 아무것도 몰라 하나의 블로그를 잡고 그 블로그를 따라서 구현했는데, 나중에 보니 MyBatis로 DB를 매핑을 했다는 점을 알았다. 그 후 소셜 로그인 구현 때문에 세션에서 토큰을 이용하는 방식으로 전환하면서 코드를 다 갈아엎고 다른 블로그를 참조해서 코드를 짰는데, 이때는 JPA로 DB 매핑을 했다.
개발자가 직접 객체와 관계매핑을 해야했던 MyBatis에서 어노테이션을 사용해 자동으로 엔티티 클래스와 테이블을 매핑해주는 JPA를 사용하니 코드가 간결해져서 왕초보자 입장에서는 오히려 JPA가 훨씬 쉽게 느껴졌다.
그래서 그때 생각이나서 끄덕끄덕 이해를 하면서 들었던 기억이 난다 ☺️
마무리
간단하게 회고를 해보려고 했는데, 생각보다 쓰고 싶은 내용이 많았다 ㅎㅎ...
쓰고 싶은 내용이 많다는 것은 내가 그만큼 열심히 올해를 보냈다는 자부심과 증거라고 생각한다.
올해는 나의 성향을 확실히 알게되었다. 나는 일단 일이 있어야 하는 성격이다... ㅎㅎ
그래서 내년에도 일을 많이 저질러 볼 생각이다. 힘들걸 알지만 어쩔 수 없다 ㅠㅠ
2024년도에는 내가 어떻게 변해있을 지, 또 얼마나 성장해 있을 지 기대가 된다.
2024년도에는 이루고 싶은 3가지 목표를 정했다. 목표는 다음과 같다.
< 2024 목표 >
1. 1일 1커밋 하기
2. 부트캠프 합격
3. 한 달에 2개 이상 블로그 포스팅
이미 블로그에 달성 하겠다고 일을 저질러 놨으니 꼭 달성하도록 노력할 것이다 😭
아직 넘어야 할 산들이 많다... 내년에는 올해 알게 된 것들을 활용해서 여러 산들을 넘어가보자!
아자아자 화이팅!!
'Retrospect' 카테고리의 다른 글
[회고] 2024년 회고록 - 2 : NOW SOPT, 새로운 세상을 만나다 (6) | 2025.01.05 |
---|---|
[회고] 2024년 회고록 - 1 : 도약의 발판 (0) | 2025.01.03 |
[회고] 2023년 회고 2 - 우테코 도전기 (0) | 2024.02.15 |
[회고] 2023년 회고 1 - 산넘어 산 (0) | 2024.02.15 |
[회고] 2023년을 되돌아보며 (2) | 2023.12.31 |