안녕하세요, NownS입니다.

지난 1년간, SIPE라는 개발자 동아리 활동을 진행했습니다.

1기는 회원으로, 2기에는 운영진으로 활동했는데요,

많은 인사이트를 얻을 수 있었던 SIPE 활동에 대한 후기입니다.

(이하 포스트 내용은 작성의 편의성을 위해 해라체로 작성하겠습니다.)

 

SIPE란

SIPE란 Sharing Insight with People Everyday 의 약자로, 다양한 사람들과 인사이트를 공유하는 모임이다. 2기까지의 직업군은 현직에 있는 개발자로 한정하고 있고, 다양한 분야, 다양한 회사의 사람들이 모여서 각자 갖고 있는 다양한 인사이트를 나누며 성장을 도모하고 있다.

SIPE 로고

운 좋게 동아리의 시작부터 함께할 수 있었는데, 1기에는 회원으로, 2기에는 운영진으로 활동했다. 성향도 ISTP로 상당히 내향적인 편이었고, 동아리 활동도 최소한으로 해왔던 필자가 어떻게 운영진까지 진행할 수 있었는지, 어떻게 성격이 변할 수 있었는지 사이프 활동 내용과 필자가 참여한 것들 위주로 설명하겠다.

 

SIPE 활동

처음 사이프에 지원하게 되었던 동기는, 지루함이었다. 백엔드 개발자로서 회사에 입사한지도 1년이 넘어가고 있었고, 점점 회사 시스템에 적응은 끝마쳤을 무렵이었다. 회사 업무에 관해 편하게 이야기할 수 있는 동료들도 있었고, 회사와 아예 관계없는 취미도 만들어 둔 상태였다. 취미에도 점차 익숙해져 갈 때쯤, 일종의 갈증을 느끼기 시작했다.

이때 만든 취미였던 야구, 지금은 그때보다도 좀 더 열심히 하고 있다.

회사에서 배울게 분명히 많은 건 맞지만, 이렇게 지내다가 보면 우물 안의 개구리가 될지도 모르겠다는 걱정이었다. 그도 그럴 것이, 필자는 컴퓨터공학 전공생은 아니다. 어떻게 개발자가 되었는지는 추후 기술할 Best of the Best 후기에서 좀 더 이야기해보기로 하고, 컴퓨터공학 전공생은 아니다 보니 주변에 개발자 친구가 절대적으로 적은 편이었다. 대부분 나와 비슷한 경로, 또는 자발적으로 개발자가 되고자 공부한 친구들뿐이었고, 보안이 본 전공이었던 특성상 개발자를 한다고 하더라도 백엔드 개발자로 취직한 친구가 대부분이었다. 그러다 보니 풀이 매우 한정적이었고, 더 이상 크게 다른 점도 없어 보이는 시기였다.

그래서 이 상황을 타개할 방법으로, 동아리도 고민해 보았다. 하지만 내가 아는 대부분의 개발 관련 동아리들은 프로젝트를 위한 동아리였다. 현직자들끼리 업무에 관해 이야기 나눌 기회보다는, 취준생과 현직자가 함께 모여 하나의 주제를 갖고 사이드 프로젝트를 진행하고, 포트폴리오를 만드는 것이 주 목적인 것으로 보였다. 그러나 사이드 프로젝트까지 진행하기에는 시간적인 부담이 많은 상황이었고, 회사에 다닌지 1년쯤 지나 어느 정도 적응했다고는 하지만 회사에서 진행하는 프로젝트에만 집중하기에도 부족한 시간이었다. 집중력의 총량은 결국 정해져 있었고, 그 집중력을 나눠서 쓰기에는 모자란 상황이었다.

필자도 대학교 때 사이드 프로젝트를 하기 위해 SOPT라는 대학생 IT 연합 동아리 활동을 했었다. 사진은 그때 만든 프로젝트였던 GrowTo

이러한 지루함과 모순을 또다시 자주 보던 학과 동기인 개발자 친구에게 토로하던 시점, 친구가 한 동아리를 추천해 주었다. 그 동아리가 바로 사이프였다. 그때가 마침 지원 기간이었고, 나의 생각과 정확히 일치했던 사이프 동아리에 합격할 수 있었다. 그리고 1기는 회원으로, 2기때는 운영진으로도 활동을 진행하면서, 다양한 분야의 많은 개발자 친구들을 만날 수 있었고, 수많은 새로운 인사이트들을 공유받을 수 있었다. 그래서 그동안 진행했던 활동들을 쭉 정리해 보았다.

 

오리엔테이션

동아리원들을 처음 만나는 자리였다. 1기 오리엔테이션때는 필자의 I성향이 극한으로 나온 시기가 아니었나 싶다. 아무 토픽 없이 처음 보는 사람과 대화하는 게 상당히 어려웠고, 그래서 초반에는 거의 혼자 가만히 있었던 것 같다. 그러나 사람들이 점점 차고, 오리엔테이션을 진행하면서 미션 주제에 대해 고민하는 등 토픽이 생겨나가니 맞장구치며 자연스럽게 대화가 이어져 갔다. 이때가 정말 필자의 터닝 포인트가 아니었나 싶다. 사실 생각보다 어려운 게 아닌데, 그동안 너무 어렵게 생각해 왔었다. 이후로는 게임을 진행하면서 같이 있던 사람들과 금방 친해질 수 있었던 것 같다. 참가자 입장에서 봤을 땐, I성향인 나도 정말 빠르게 사람들과 가까워질 수 있는 자리였다.

1기 오리엔테이션

2기 오리엔테이션 때는 운영진을 맡으면서, 오리엔테이션 게임 운영 및 진행을 맡았다. 참가자 입장에서 볼 때와 다르게, 운영자 입장에서는 고민할 부분이 매우 많았다. 이때, 넛지 이론에 대해 생각해 보았다. 넛지란 일종의 자유주의적인 개입, 혹은 간섭을 의미하는데, 아주 사소한 개입을 통해서 자연스럽게 상대가 내가 원하는 대로 행동하도록 하는 방법을 의미한다. 이때 처음으로 이 넛지라는 개념에 대해 고민해 보게 되었고, 사용하는 방법에 대해 많이 고민했으며, 행사 내에서 자연스러운 행동 규범을 만들어 내며 좋은 반응을 이끌어 낼 수 있었다. 이후 다양한 사이프 2기 활동에 넛지를 적용해 보려고 노력했고, 이론을 다양한 분야에 실제로 적용해 보면서 실제 운영에도 도움이 되었다.

2기 OT때 사용한 운영진 소개 PPT

 

미션

미션은 사이프의 메인 활동이라고 볼 수 있다. 팀을 나누어 본인들이 관심 있는 주제를 갖고 자율적으로 미션을 진행하고, 정량적인 지표를 통해 미션 성공을 평가한다. 미션과 지표 모두 팀에서 자율적으로 정하는 방법을 통해 부담을 최소화하고, 본인이 정한 분량이라는 책임감을 부여하고 있다. 1차 미션 때는 이펙티브 코틀린 책을 읽었고, 2차 미션 때는 주 1회 아티클을 정리하는 미션을 진행했다. 두 미션 모두 성공적으로 진행되었고, 2차 미션 때는 심지어 1등 팀으로 뽑히기까지 했다.

온라인으로 모일 때는 메타버스 플랫폼도 애용했다.

2기 때도 1기 때와 유사하게, 미션 활동을 통해 수료 여부를 결정했다. 2기 때 필자는 책 읽기 스터디를 진행했고, 주 1회 일정 양을 정해서 정리하는 식으로 진행했다. 1차와 2차 미션 모두 동일한 팀으로 이어서 진행했고, 책을 거의 완독 할 수 있었다. 혼자 읽는 것보다 특히 좋았던 점은 자바로 쓰여 있는 책이지만, 팀원들 중에는 스위프트와 파이썬 개발자들도 있었다는 점이었다. 다른 언어에서 사용하는 패러다임에 대해서도 알 수 있는 좋은 기회였고, 색다른 경험이었다.

완독 성공

 

사이프챗 & 사이데이션

사이프챗에서는 팀을 나누어 서로 나누고 싶은 주제들에 대해 이야기하는 자리를 가진다. 1차 사이프챗 때는 동아리 활동 초기였기 때문에 다양한 주제들을 투고받아 2차 사이프챗 때는  나누어서 진행되었다.

사이프챗 주제

2기 사이프챗은 1기 때와 비슷한 형식으로 진행되었다. 주제를 투고받아 서로 관심 있는 분야가 겹치는 사람들끼리 팀을 만들어 주었고, 긴 시간 동안 자유롭게 이야기를 나눌 수 있도록 공간을 제공해 주었다.

사이프챗 진행

사이데이션은 1기때는 나들이 & 액티비티라는 이름으로 진행되었다. 주 목적은 미션 팀원들과 친해지는 것이었으며, 나들이 때는 정규 세션 시간에 팀원들과 놀러 나가는 시간을 갖고, 액티비티 때는 팀원들과 다양한 운동 관련 활동을 진행했었다.

2기 사이데이션은 친해지는 시간과 더불어서, 미션을 좀 더 세부적으로 구체화하는 시간을 제공할 수 있도록 노력했다. 팀별로 자연스럽게 운영될 수 있도록 미션 보드, 시간별 인증샷 등 다양한 보상 및 확인 요소들을 이용하였다. 적절한 제한을 통해서 동아리원들에게 부담 없이 출석 체크를 진행하고, 사이데이션을 진행할 수 있었다.

2기 우리팀 사이데이션 진행 사진

 

내친소

사이프에는 IT업계의 친구를 소개하고, 네트워킹하는 행사인 내친소라는 행사가 있다. 그리고 사이프에는 운영진의 부담을 줄이고, 외부 행사의 완성도를 높이기 위해 회원들과 기획 및 운영을 함께 진행하는 TF 제도가 있다. 내친소는 필자가 처음으로 참여한 TF였다.

1기 내친소 TF

1기 내친소는 너 I(T)야? 라는 부제를 갖고, 네트워킹 파티 형식으로 진행되었다. 2개의 파트로 나누어서 첫 번째 파트에서는 팀을 나누어 레크리에이션을 진행하였고, 두 번째 파트에서는 각 팀별로 1명씩 TF팀이 들어가 처음 만나는 사람들끼리 빠르게 친해질 수 있도록 진행을 도우면서, 서로 대화하는 시간을 가졌다.

나는 첫번째 파트 활동의 레크리에이션 게임 만들기 및 운영을 담당하였다. 게임을 만들면서도 고민이 많았는데, 어떻게 하면 제한된 시간 동안 참여자들이 소외되는 사람 없이 모두 적극적으로 참여할 수 있을지에 대한 고민이었다. 그래서 첫번째 게임은 팀의 모든 사람들이 함께 참여할 수 있는 게임으로 운영하였고, 두번째 게임은 장학퀴즈 형식으로 팀 대표가 나와서 게임을 진행하지만, 대표를 바꾸거나 팀원이 와서 알려주기도 할 수 있는 찬스를 제공하는 방식으로 진행하였다. 처음 보는 참가자들 사이에서도 소외되는 사람 없이 최대한 모두가 게임에 참여하는 것에 포커스를 두고 게임을 기획하였고, 혹시 모를 돌발 상황에도 대비하여 PPT에 여유 공간을 넣는 등 최대한 꼼꼼하게 행사를 기획하였다.

1기 내친소 게임 운영

결론적으로 게임에 모두가 적극적으로 참여하고 팀원들끼리 급격하게 가까워질 수 있어 게임을 성공적으로 진행할 수 있었으며, 돌발상황을 최소화하고자 했기 때문에 돌발상황이 있더라도 임기응변을 통해 잘 대처하며 마음 편하게 두번째 파트로 넘어갈 수 있었다. 이때 느꼈던 점은 돌발상황을 100% 제어할 수는 없지만, 그 정도를 최소화할 수는 있다는 점이다. 이때의 TF 활동을 통해 2기 운영진 활동을 진행할 때도 비슷한 태도를 유지하면서 문제가 발생할 수 있는 상황을 최소화할 수 있었고, 행사를 유연하게 진행할 수 있게 되는 좋은 계기가 되었던 것 같다.

1기 내친소 두번째 파트 활동

2기 내친소 역시 TF를 모집하여 진행하였고, 큰 포맷은 1기 때와 비슷하게 진행되었다. 1기 내친소 때의 피드백을 적용하여 주제별 네트워킹 시간을 확장하였고, 2기 내친소 때도 역시 IT 내 다양한 분야의 많은 사람들을 만날 수 있었고, 개발자들끼리만 있을 때와 달리 새로운 이야기도 들을 수 있어서 재밌는 시간이었다.

2기 내친소

이 자리를 빌려 1기 내친소 / 2기 내친소에 참여했던 많은 참가자 분들, 그리고 함께 노력한 TF들에게도 감사의 인사를 전한다.

 

사담콘

1기 사담콘은 내부 행사로 진행되었다. 1기 사담콘에서 가장 인상 깊었던 내용은 부동산에 관련된 여정 발표였다. 월세부터, 전세, 그리고 매매까지 진행하는 과정에 대해서 상세하게 발표했었다. 이처럼 1기 사담콘은 주제에 관계없이 나누고 싶은 지식들이 있다면 발표하는 방식으로 진행되었으며 내용이 어렵건 쉽건 많은 사람들 앞에서 발표를 해볼 수 있도록 자리를 마련해 주는 게 주된 목적이었다.

2기 사담콘은 <우리들의 성장통> 이라는 주제로 운영되었다. 1기 때와는 다르게 소정의 입장료를 받는 외부 행사로 진행되었으며, 기술적인 부분보다는 다방면에서 성장해 나가면서 있었던 다양한 사건들에 대해서 강연할 수 있는 시간을 가졌다. 시민청 태평홀에서 진행되었고, 2기 첫 외부 행사인만큼 신경이 많이 쓰였던 행사였다. 가장 인상 깊었던 발표는 김우재 발표자의 "내가 깨달은 것들" 이었다. 한 사람의 도전과 실패, 그리고 회복 및 다시 성장해 나가는 과정을 바라보면서 다시 한번 동기부여를 얻을 수 있는 시간이었다. 발표 내용이 궁금하다면 SIPE 유튜브에서 확인할 수 있다.

SIPE Youtube (https://www.youtube.com/@sipe_team)

 

사이프톤

사이프톤은 2기 때 새로 만들어진 행사다. 동아리원들 사이에서 해커톤에 대한 니즈가 있었고, 동아리 차원에서 창업 관련 활동도 지원하기 위해 행사를 새로 기획하여 운영했다. 필자가 메인 운영진으로 TF가 운영된 행사였는데, 완전히 바닥부터 처음 진행하는 행사다 보니 고민 사항과 결정해야 할 사항들이 많은 편이었다. 외부 디자이너를 모집하기로 결정했고, 미리 해커톤 팀을 만들어 주었으며, 주제는 어떻게 할지, 어느 정도까지 개발해 오는 것을 허용할지, 시상은 어떻게 할지 등 고민할 부분이 많은 행사였다.

사이프톤 타임테이블

다행히 디캠프의 후원을 받아 음식을 제공할 수 있었고, 참가비 없이 회식비 명목의 상금을 제공하는 것으로 결론 냈으며, 개발은 자발적으로 원하는 만큼 해와도 상관없는 것으로 결정했다. 중간중간 이벤트도 추가하고, 라디오 행사 등을 통해서 우려와 달리 최소 비용으로 최대의 즐거움을 제공하자는 목표는 달성한 것으로 보인다. 이렇게 해커톤을 운영하면서도 배운 점이 많았다. 사소하고 쉬워 보이는 행사더라도 신경 써야 할 점이 많다는 것, 그리고 행사에서 만족도를 끌어올리는 방법과 돌발상황에 대처하는 방법들에 대해 알 수 있었던 것 같다.

사이프톤 때 가장 인상 깊었던 팀은 키워드를 이용하여 여행 컨텐츠를 생성해 주는 앱을 만든 팀이었다. 생성형 AI를 이용하여 키워드를 통해 여행에 가서 어떤 활동을 할지 알려준다는 컨셉이 인상 깊었다.

짧은 시간이었지만 몰입해서 해커톤을 즐겨준 모든 팀들, 그리고 함께 열심히 운영해 준 TF들에게 감사의 마음을 전한다.

사이프톤 TF

 

소감

사이프 1기 활동은 내가 갖고 있던 빈 공간을 완벽하게 채워주는 기간이었다. 그도 그럴 것이, 내가 생각했던 니즈와 동아리의 목적이 완벽하게 일치했고, 비슷한 고민을 가진 사람들이 모이다 보니 그럴 수밖에 없었던 것 같다. 동아리 활동을 하면서 내가 어떤 사람인지 객관화해 보는 경험도 해볼 수 있었고, 다른 회사에서는 어떻게 기술을 사용하는지, 인사이트에 대한 갈증을 해결할 수 있는 시간이었다. 그래서 동아리에 애정을 갖기 시작했으며, 이 동아리가 잘 자리 잡기를 원했고, 이는 운영진을 해보기로 결심하는 계기가 되었다.

2기 운영진 킥오프

2기 때는 실제로 운영진으로 활동하면서, 회원으로 활동할 때와는 또 다른 모습들이 보이기 시작했다. 비영리 단체를 운영하는 입장에서 보이는 새로운 부분들이 있었던 것 같다. 사람들이 자연스럽게 활동에 참여할 수 있도록 독려하는 방법이나, 운영 과정에서 발생하는 여러 다른 의견들, 그리고 그 의견들을 서로 조율해 나가는 과정에 대해 알 수 있었다. 또한 운영진들 사이에서도 다양한 관점들을 공유하다 보니, 다른 사람들의 관점에 대해서도 점점 더 쉽게 이해할 수 있게 되고, 시간이 지나면서 조율해나가는 과정, 사람들을 매니징 해가는 과정이 익숙해져 갔다. 이런 경험은 회사 생활을 통해서는 주니어가 쉽게 얻을 수 없는 과정이라고 생각한다. 만약 지금 이 글을 읽고 있는 독자가 운영진을 해볼 기회가 있다면 적극 추천하고 싶다.

 

3기...?

아마도 3기는 운영진에서 회원으로 다시 돌아가서, 부담 없이 활동하지 않을까 싶다. (3기 운영진분들이 뽑아준다면...?)

1기, 2기 때 그랬던 것처럼, 좋은 사람들을 3기에서 또다시 만나보고 싶고, 함께 좋은 인사이트를 공유하는 경험을 가져보고 싶다. 또한 3기 때는 1기, 2기에서 경험했던 좋은 인사이트 공유 및 네트워킹과 더불어 기술적인 내용도 좀 더 심화적으로 다루고자 한다고 하니, 새로운 경험에 대해서도 기대 중이다.

3기는 9월부터 리쿠르팅 예정이며, 10월부터 활동을 진행 예정이니, 관심 있는 독자가 있다면 필자에게 질문해도 괜찮고, 사이프 홈페이지(https://sipe.team)나, 사이프 인스타그램을 참고해도 좋다.

그리고 정말 마지막으로, SIPE 2기 운영진들 정말 고생 많았다. SIPE 3기 운영진들도 화이팅!

SIPE 2기 - 3기 운영진 인수인계

다음 포스트는 취업 전, 나의 커리어를 바꾸어 주었던 차세대 보안인재 양성 프로그램 Best of the Best 후기로 돌아오겠습니다. See You!

반응형

'일상' 카테고리의 다른 글

[SIPE] 인프콘 커뮤니티 부스 운영 후기  (1) 2024.08.11

안녕하세요, NownS입니다.

오랜만의 게시글로 돌아왔습니다.

 

개발자로서의 공부를 진행하면서 여러 취업에 도움 되는 활동도 진행했었고, 취업 이후 개발자로서 다양한 활동들도 진행해 왔습니다.

여태까지 진행해 왔던 활동들을 기록하고 추억하기 위해, 최근 활동했던 내역들부터 역순으로 올라가며 차근차근 작성해 보려고 합니다.

많은 관심 부탁드립니다.

 

그중 첫 번째는 가장 최근에 진행했던 인프콘 커뮤니티 부스 운영 후기입니다.

(이하 포스트 내용은 작성의 편의성을 위해 해라체로 작성하겠습니다.)

 

SIPE x INFCON

올해 들어서 사이프라는 동아리의 운영을 담당하고 있다. 그러던 중 뜻밖의 연락을 받았는데, 지속적으로 물품 후원을 받고 있던 인프랩에서 운영하는 인프콘이라는 행사의 파트너로 참여해 볼 생각이 있는지에 대한 내용이었다.

그런데, SIPE는 뭐고 INFCON은 뭔데?

SIPE - 출처 : 공식 홈페이지(https://sipe.team)

SIPE는 Sharing Insight with People Everyday의 약자로, 개발자로 일하는 다양한 사람들과 각자 갖고 있는 인사이트를 나누고, 교류하는 동아리이다. 필자는 현재 1기를 수료하고, 2기는 운영진으로 활동했다. 해당 내용 관련 포스트도 추후 작성할 예정이니 많관부!

인프콘

인프콘은 인프랩에서 주최하고, 운영하는 IT 컨퍼런스이다. 2022년부터 시작하여 매년 운영하고 있으며, 올해는 3번째 개최이며, 코엑스 그랜드볼룸에서 진행될 예정이다. 인프콘에서는 다양한 발표와 프로그램들을 운영하는데, 단순히 발표뿐만 아니라 다양한 기업 부스, 커뮤니티 부스, 네트워킹 세션 등의 프로그램을 통해서 모두가 함께 진행할 수 있는 공간을 만들어주고 있다.

그래서... 2기는 마무리되어 가지만, 다음 기수인 3기 운영에 좋은 영향을 줄 수 있을 것 같고, 다양한 사람들과 소통하고 싶다는 동아리의 인사이트와도 일치하여 인프콘의 커뮤니티 파트너로 참여하기로 결정하였다.

 

당당하게 커뮤니티 파트너 한 자리를 차지한 SIPE

디프만, 싸피니티, 얍, 솝트 등 다양한 다른 동아리도 함께 참여했다. (필자도 솝트 활동을 했었어서, 반가운 마음이 있었다.) 

인프콘 2024 판넬, 커뮤니티 부스는 2층 로비 쪽에서 운영했다

아침 8시에 인프콘이 열리는 코엑스 그랜드볼룸에 도착하여, 부스 설치를 진행했다.

부스 설치 완료

아침 8시부터 저녁 5시까지, 중간에 세션을 참여하는 시간 제외하고 모두가 열심히 SIPE 홍보를 진행했고, 인스타그램 팔로워가 짧은 시간 안에 폭풍 성장할 수 있었다. 추후 동아리 운영할 때, 이렇게 쌓아온 이미지들이 좋은 영향을 주기를 바란다. 부스를 운영하면서 몇몇 아는 얼굴도 만날 수 있었고, 개발자 사회가 좁다는 걸 다시 한번 느끼게 되는 하루였다.

사이프 부스에서 사용한 스티커, 귀여운 사이프 마스코트 고양이이다.

인프콘 세션 참여

인프콘은 추첨을 통해 티켓을 구매할 수 있는 시스템이다. 필자는 2022년부터 매년 추첨 응모를 해보고 있지만, 올해까지 3번 모두 광탈했다... 그러나 감사하게도, 커뮤니티 부스를 운영하면서 세션에 참여할 수 있는 이름표를 제공해 주셔서, 몇몇 궁금한 발표들에 참여해 볼 수 있었다. 물론 부스를 지켜야 했기 때문에 모든 발표에 참여하지는 못했지만, 꼭 듣고 싶었던 발표들은 3개 정도 들으러 갈 수 있었다. (세션을 듣는데만 너무 집중해서, 사진을 찍지 못해서 몇몇 사진은 외부 블로그에서 가져왔다.)

인프런 아키텍처 2024 ~ 2025

출처 : https://ururuwave.tistory.com/m/149

인프런에서 아키텍처가 발전해 온 과정을 인프런 CTO인 이동욱(향로) 님이 직접 발표했다. 해당 세션은 말 그대로 아키텍처의 발전 과정이었기 때문에, 생각이 들어간 부분보다는 실제 진행 과정에 대한 내용이 많았다. 스타트업에서 시작해서 점점 큰 회사로 발전해 나가는 회사들이 모두 경험해 볼 수 있는 문제점들에 대해서 알려주는 세션이었던 것 같다. 자연스럽게 내가 다니고 있는 회사와 비교를 해보게 되는데, 우리 회사의 경우 이미 대규모 트래픽에 대해 충분한 고민이 끝나있고, 한 스텝 더 나아간 고민이 필요한 단계였던 것 같다. "아, 우리 회사 큰 회사였지"라는 생각을 다시금 해보게 되는 세션이지 않았나 싶다. 생각보다 자연스럽게 배워온 내용들이 어느 곳에서는 챌린지일 수도 있겠다는 생각을 하며, 잘 공부해 왔다는 생각을 갖게 한 세션이었던 것 같다.

경력이 늘수록 CS이론이 중요해지는 이유

필자의 생각과 가장 일치하던 부분, 인상깊어서 사진을 찍어 뒀다

필자도 각종 멘토링을 진행하고 있는데, 내가 공부해 온 방식과 멘티들이 생각하는 방식이 일부 다르지 않나 싶은 부분들이 분명 존재한다. 사실 필자는 CS 기초 공부가 아주 중요하다고 생각하는 입장이고, 코드를 짜는 것보다 왜 그렇게 작성하게 되는지 고민하는 과정이 더 중요하다고 생각한다. 그리고 그렇게 고민하려면 당연히 CS공부가 우선되어야 한다. 해당 세션은 유튜브에서 널널한 개발자 TV라는 채널로 활동하고 계신 최호성 씨가 발표를 진행했고, 필자와 비슷한 생각을 갖고 세션에 임하신 것 같아서, 필자와 어떤 부분이 비슷하고, 어떤 부분이 다를지 궁금해서 해당 세션에 참가하게 되었다.

실제로 세션을 듣다 보니 필자와 유사한 부분들이 있었다. 비전공자로 커리어를 시작한 부분, 멘토가 없어서 길을 열심히 찾아다녔던 부분 등등... 고민을 많이 하셨던 부분이 느껴지는 세션이었다. 그리고 멘토링을 하시면서 다양한 고민을 추가로 하셨던 것 같은데, 필자의 생각과 꽤 많이 일치하는 부분이 있었던 것 같다. 특히, 기본기가 충실하면 새로운 환경으로 이동하는 것도 어렵지 않다는 점, 그리고 결국 CS의 근본은 변하지 않기 때문에 큰 틀에 대해서 먼저 탄탄하게 이해하고 있다면 언어나 프레임워크는 단순히 도구일 뿐이라는 점이다.

필자도 항상 모든 일에는 기본이 가장 중요하다고 생각한다(꼭 개발이 아니더라도). 필자도 처음 개발공부를 시작할 때 주전공과목은 3학년때까지 미리 다 끝내놓고 1년 동안은 컴퓨터공학과 전공과목만 남는 학점으로 싹쓸이했었다. 이때 공부했던 과목들이 데이터베이스, 네트워크, 컴퓨터 구조, 운영체제 등 취준 할 때뿐만 아니라 지금 실무 단계에서도 유용하게 사용하는 개념들이다. 위의 사진에서 볼 수 있듯이, 전공자의 4년은 결코 짧지 않다. 그렇기 때문에 그들을 따라잡기 위해서는 더 밀도 있고 강도 있게 공부해야 하는 것이고, 이 신념에 대해서 좀 더 확고해지는 계기가 되었던 것 같다. 나중에 멘토링할 때도, 지금 당장은 아니더라도 결국 CS공부는 진행되어야 한다는 것을 멘티들에게 전달해 줄 수 있을 것 같다.

객체지향은 여전히 유용한가?

출처 : https://yeonyeon.tistory.com/338

해당 세션은 객체지향을 공부했다면 한 번쯤은 들어봤을 법한 "객체지향의 사실과 오해", "오브젝트"의 저자, 조영호 씨가 직접 강의하는 세션이었다. 사실 세션의 제목이 매우 자극적이기도 하고, 해당 서적들을 읽으면서 조영호라는 이름을 많이 들어본 상황이었기 때문에 궁금증이 생겨 세션에 참여하게 되었다.  생각과는 다른 방향으로 발표가 진행되었다.

주 골지는 절차지향 프로그래밍과 객체지향 프로그래밍이 결국 공존해야 한다는 것이었고, 객체지향이 유용한지를 물어보는 게 아니라, 어떤 상황에서 객체지향이 유용한지를 알아야 한다는 점이었다. 해당 논지에 대해서는 필자도 동의하는 편이다. 물론 객체지향적인 개발 패러다임에 대한 고민은 항상 하지만, 실무에서 개발을 하다 보면 어쩔 수 없이 절차지향적으로 개발하는 것이 추후 개발이 확장되는 과정에서 더 변경점이 줄어드는 경우도 존재한다. 이를 조영호 씨가 정리하여, 절차적인 설계의 경우 기능 추가에 유리하고, 객체지향 설계의 경우 타입 확장에 유리하다고 깔끔하게 정리해 주셨다.

결국 절차지향과 객체지향 모두 각각의 트레이드오프가 존재하며, 그 수준을 어느 정도로 유지할지를 결정하는 것이 개발자의 역량인 것이다. 그리고 개발 내용이 추가되면서 패러다임의 변경이 필요하다면, 그때 리팩토링 여부를 결정하는 것이 개발 공수를 최대한 줄일 수 있지 않을까 라는 생각이 들기도 했다.

 

전체적인 세션 후기로는, 자연스럽게 세션에서 설명해 주고 있는 내용들과 유사하게 실무 과정에서 체득하고 있었던 것 같다. 가끔은 내가 잘해나가고 있는 건지에 대한 의구심도 들기는 했지만, 이런 세션들을 통해 나름 백엔드 개발자로서 잘 성장해 나가고 있다는 자신감이 들었던 것 같다. (언젠가는 나도 이런 대규모 컨퍼런스에서 발표를 한번...?)

인프콘을 마치며...

커뮤니티 부스 활동, 인프콘 참석 등등 동아리를 하지 않았다면, 또 인프콘에 참여하지 않았다면 경험하지 못했을 새로운 경험이었던 것 같다. 이 게시글을 통해서 좋은 기회를 주신 인프콘 관계자 분들과, 손과 머리를 맞대고 고생한 우리 운영진들에게 감사의 말씀을 전한다.

인프콘 네컷

다음 포스트는 반년동안 동고동락했던 SIPE 2기 운영 후기로 돌아오겠습니다. See You!

반응형

'일상' 카테고리의 다른 글

[SIPE] 1기 회원 / 2기 운영진 활동 후기  (13) 2024.09.08

1. 팩토리 메소드 패턴이란

GoF의 디자인 패턴에서 제시한 디자인 패턴 중 생성 패턴에 속한다. 해당 서적에서는 팩토리 메소드 패턴을 이렇게 정의하고 있다.

객체를 생성하기 위한 인터페이스를 정의하고,
어떤 클래스의 인스턴스를 생성할지에 대한 처리는 서브클래스가 결정하는 디자인 패턴

요약해서 말하자면, 객체 생성을 대신 수행해주는 일종의 팩토리가 존재하는 것이다. 이때 객체를 생성하는 메소드를 팩토리 메소드라고 하며, 이를 구현 팩토리 객체에서 Override하여 원하는 객체를 생성하게 된다. 클라이언트에서 직접 객체를 생성하는 것이 아니라, 간접적으로 객체를 생성한 뒤 반환해주는 방식이다.

즉, 해당 디자인 패턴은 상위 클래스에 알려지지 않은 구체 클래스를 생성하는 패턴이며, 하위 클래스가 직접 어떤 객체 인스턴스를 생성할지 결정하게 된다. 이를 UML 형태로 나타내면 아래의 그림과 같다.

출처 : 위키피디아

이때 Creator의 factoryMethod()는 추상 메소드이며, 이를 ConcreteCreator에서 Override하여 구현 메소드를 작성한다. 결국 실질적으로는 ConcreteCreator를 통해서 Client에게 Product를 생성하여 전달하게 된다.

2. 팩토리 메소드 패턴의 사용

팩토리 메소드 패턴을 사용하는 주된 이유는 클래스의 생성과 사용의 처리 로직을 분리하여 결합도를 낮추기 위해서이다. 팩토리 메소드 패턴을 사용하여 직접 객체를 생성해 사용하는 것을 방지하고, 서브클래스에 생성 로직을 위임함으로써 보다 효율적으로 코드를 제어할 수 있고, 의존성을 제거해 주는 역할을 한다.

또한, 객체 생성을 캡슐화하고 한 곳(팩토리 클래스)에서 관리하기 때문에 수정에는 닫혀 있고, 객체의 자료형이 하위클래스에 의하여 결정된다는 점 때문에 확장이 용이하다는 장점이 있다. 이는 객체지향의 SOLID 원칙 중 OCP에 해당한다.

3. 팩토리 메소드 패턴 예제 코드(by. Java)

Computer 추상 클래스

abstract class Computer {
    public void on() { // 컴퓨터 전원버튼으로 켜기 }
    public void off() { // 컴퓨터 전원버튼으로 끄기 }
    
    abstract void compose(); // 컴퓨터 조립하는 방법
    abstract void use(); // 컴퓨터 사용하는 방법
}

Computer는 on, off, compose, use라는 공통적인 메소드를 갖는 인터페이스이다. 컴퓨터라는 종류로 추상화되어 있는 상태이다. 이때, on과 off 메소드의 경우 어느 컴퓨터든 전원버튼을 이용하여 켜고 끈다는 동일한 행위를 수행하기 때문에 구체 클래스에서의 구현을 줄이기 위해 미리 구현해 두었다.

Computer 구체 클래스

public class Macbook extends Computer {
    @Override
    void compose() { // 맥북이 조립되어 나오는 과정 }
    
    @Override
    void use() { // 트랙패드로 사용하기 }
}

public class Galaxy extends Computer {
    @Override
    void compose() { // 갤럭시북이 조립되어 나오는 과정 }
    
    @Override
    void use() { // 360도로 꺾어서 사용하기 }
}

public class Asus extends Computer {
    @Override
    void compose() { // Asus 노트북이 조립되어 나오는 과정 }
    
    @Override
    void use() { // 평범하게 마우스로 사용하기 }
}

public class Lenova extends Computer {
    @Override
    void compose() { // Lenova 노트북이 조립되어 나오는 과정 }
    
    @Override
    void use() { // 빨콩으로 사용하기 }
}

Computer라는 추상화된 인터페이스를 활용하여 구현한 구체 클래스이다. 각 클래스마다 조립되어 나오는 과정과 사용 방식을 구현해 둔 상태이다.

ComputerFactory 추상 클래스

abstract class ComputerFactory {
    public Computer orderComputer(String type){
        Computer computer = createComputer(String); // Factory Method
        computer.compose();
        computer.on();
        computer.off();
        return computer;
    }
    
    abstract Computer createComputer(String type); // Factory Method
}

ComputerFactory는 위의 그림에서 Creator 역할을 한다. 이때 createComputer 부분이 팩토리 메소드가 되고, 이 부분을 구체 클래스에서 실질적으로 구현하여 어떤 객체 인스턴스를 반환할지 결정하게 된다. 그리고 추상 객체에서는 orderComputer 메소드 내부에서 팩토리 메소드를 활용하여 Computer를 생성하고, 기능들을 사용하고 있다.

ComputerFactory 구체 클래스

class ComputerFactoryImpl extends ComputerFactory {
    @Override
    Computer createComputer(String type) {
        if ("Macbook".equals(type)) {
            return new Macbook();
        } else if ("Galaxy".equals(type)) {
            return new Galaxy();
        } else if ("Asus".equals(type)) {
        	return new Asus();
        } else if ("Lenova".equals(type)) {
        	return new Lenova();
        }
        return null;
    }
}

위 두 클래스는 ComputerFactory를 구현한 구체 클래스이다. 객체의 종류가 추가되는 경우, 구체 클래스에 추가해줌으로써 새로운 객체를 반환할 수 있다. 기능의 추가가 필요한 경우 해당 구체 클래스만 변경하고, 추상 클래스는 변경하지 않아도 된다.

팩토리 메소드에 String 값을 인자로 받아 리턴되는 객체의 종류를 변화시킨다. 해당 구체 클래스를 실제로 클라이언트에서 사용함으로써 클라이언트 단에서 리턴되는 객체의 종류를 제어할 수 있다.

클라이언트 코드

public class FactoryPatternTest {
    public static void main(String[] args) {
        ComputerFactory computerFactory = new ComputerFactoryImpl();
        
        Computer macbook = computerFactory.orderComputer("Macbook");
        Computer galaxy = computerFactory.orderComputer("Galaxy");
        Computer asus = computerFactory.orderComputer("Asus");
        Computer lenova = computerFactory.orderComputer("Lenova");
    }
}

위와 같은 형태로 팩토리를 통해 생성되는 객체들의 종류를 제어할 수 있다.

반응형

Spring은 정말 어려운 프레임워크이다. 왜냐하면 개발자들이 정말 오랜 기간 동안 고민하면서 개발 패러다임의 격변을 가져왔던 객체지향에 관한 생각, 그리고 끊임없이 연구되어 왔던 자바를 활용한 다양한 디자인 패턴들이 모두 함축되어 있는 프레임워크이기 때문이다. 대략적으로만 생각해보더라도 스프링의 핵심 기술에는 IoC/DI, AOP, PSA 등이 있고, 그 외에도 데이터베이스 용도로 응용하여 활용할 수 있는 기술들인 JPA, QueryDSL 등도 존재한다. 또한 아직 사용해보거나 접해보지 못한 부분들에는 더 많은 내용들이 녹아 있을 것이다.

그중에서도 스프링에서의 객체지향 설계의 기본이 되는, IoC와 DI에 대해 간단히 정리해 보았다.

 

IoC (Inversion of Control, 제어의 역전)

간단하게 설명하면 말 그대로이다. 제어의 역전. 제어권이 역전되어 있는 상황을 의미한다.

그렇다면 제어의 역전이란 곧 기존의 제어 방식을 뒤집었다는 말인 것 같은데, 기존의 방식은 과연 어떠했을까?

기존 프로그램의 경우 클라이언트의 구현 객체가 스스로 필요한 서버 구현 객체를 생성하고, 연결하고, 실행하는 등 프로그램의 제어 흐름을 스스로 조종했다. 즉, 코드의 제어권은 개발자가 갖고 있는 것이다.

그러나 Spring에서는 코드에서 제어권을 프레임워크가 갖고 있고, 개발자는 일종의 config 파일만을 활용하여 프레임워크에게 제어할 수 있는 방법을 제공한다. 이후 프로그램의 제어 흐름 자체는 개발자가 직접 제어하지 못하고, 프레임워크 단에서만 관리가 가능해진다. 사용자가 작성하는 부분은 프레임워크의 라이프사이클 속에서 일종의 콜백 형식으로 적절한 위치에서 자동으로 호출되게 된다. 이러한 상황을 제어의 역전, IoC라고 한다.

Spring에서는 구현 객체를 생성하고 연결하는 책임을 AppConfig 단에서만 담당하게 되어, SRP(단일 책임 원칙)에도 부합하는 소프트웨어를 개발할 수 있게 해준다.

 

DI (Dependency Injection, 의존관계 주입)

DI는 스프링에서 클래스 간 또는 클래스와 인터페이스 간의 의존 관계들을 정의해주기 위해 필요한 개념이다. 의존 관계에는 정적인 클래스 의존 관계와 런타임에 결정되는 동적인 객체(인스턴스) 의존 관계 두 가지 종류가 존재한다.

정적인 클래스 의존 관계의 경우, 클래스에서 사용하는 코드만을 통해서도 의존관계를 쉽게 판단할 수 있다. 예를 들어 주문 관련 Service가 존재한다면, 해당 Service내에서 어떤 Repository 인터페이스를 사용할지 등의 내용은 이미 요구사항 분석과 클래스 다이어그램을 작성하면서 어느정도 구상이 끝나 있었을 것이다. 하지만, 이러한 클래스 의존 관계만을 통해서는 실질적으로 어떤 객체가 Service에 주입될지, 즉 각 인터페이스 내에 어떤 구현체가 사용될지에 관한 내용을 파악하기는 어렵다.

이를 위해 동적인 객체 인스턴스 의존 관계 파악이 필요하다. 동적인 객체 인스턴스 의존 관계는 애플리케이션의 실행 시점에 실제 생성된 객체 인스턴스의 참조가 연결된 의존 관계를 의미한다.

이때 애플리케이션 실행 시점, 즉 런타임에 실제 구현 객체를 생성하고, 클라이언트에 전달하여 실제 의존 관계가 연결되는 것의존관계 주입, DI라고 한다. 의존관계 주입을 통하여 클라이언트 코드를 변경하지 않고 호출 대상의 타입 인스턴스를 변경할 수 있으며, 정적인 클래스 의존 관계를 변경하지 않고 동적인 객체 인스턴스 의존 관계를 쉽게 변경할 수 있다.

스프링에서는 IoC를 구현하기 위하여 의존 관계 주입을 사용하고 있고, 이는 AppConfig 파일 내에서 객체를 생성하고 관리하면서 의존 관계를 연결해 주고 있다. 이러한 것을 IoC 컨테이너 또는 DI 컨테이너라고 부른다.

Spring에서는 DI 컨테이너를 이용하여 객체 인스턴스를 클라이언트 코드 대신 생성해서 클라이언트 코드에 의존 관계를 주입하고 있다. 즉, 클라이언트 코드는 추상화에 의존하여 개발할 수 있고 이를 통해 DIP(의존관계 역전 원칙)에도 부합하는 소프트웨어를 개발할 수 있게 해준다.

또한 DI 컨테이너만을 이용하여 의존 관계를 변경할 수 있게 되면서 애플리케이션을 사용 영역과 구성 영역으로 나누어 주기 때문에 클라이언트 코드는 변경하지 않아도 되며, 결국 소프트웨어 요소를 새롭게 확장해도 사용 영역의 변경은 닫혀 있도록 구현이 가능해진다. 이는 OCP(개방 폐쇄 원칙)에 부합하는 소프트웨어를 개발할 수 있게 해준다.

반응형

최근 Node.js와 PostgreSQL을 이용하여 프로젝트를 진행했다.

Node.js에서 PostgreSQL을 사용하는 방법은 여타 RDBMS를 사용하는 방법과 유사하다.

커넥션 풀을 생성하고, 해당 커넥션 풀에서 커넥션을 빌려오고, 빌려온 커넥션을 통해서 쿼리문을 수행하는 과정을 ES7의 async await를 이용하여 비동기식 프로그램의 순차 처리를 진행해서 데이터를 가져온다.

이때 커넥션 풀 생성 및 커넥션을 빌려오는 부분은 별도로 모듈화하여 사용하고 있었고, 쿼리문을 수행하는 과정만 코드로 확인해 보면, 다음과 같은 형식으로 활용했다.

const getLectures = async (client, lectureId) => {
  const { rows } = await client.query(
    `
    SELECT * from lecture
    WHERE id = $1
    `,
    [lectureId]
  );
  return convertSnakeToCamel.keysToCamel(rows[0]);
};

다음 코드는 lecture 테이블에서 id=${lectureId} 인 값을 가져오는 코드이다. 위 코드와 같이, 백틱(`)과 ${num} 형태를 이용하여 쿼리문을 작성하고 차후에 값을 넣어주는 방식을 Node.js 에서의 Prepared Statement라고 한다.

Prepared Statement란?

위키백과에서는 Prepared Statement를 다음과 같이 정의하고 있다.

Prepared Statement란
데이터베이스 관리 시스템에서 동일하거나 비슷한 데이터베이스 문을
효율적이고 반복적으로 실행하기 위해 사용하는 기능이다

(위키백과)

실제로 Prepared Statement는 쿼리문을 반복 사용하기 위해 사용되는 방식이었으나, 현재는 해당 용도 외에 보안적인 요소로 프로그래밍에 사용된다. 주로 SQL Injection 공격을 막기 위해 활용되는데, 방어가 가능한 원리는 아래 SK인포섹 블로그 게시글을 보면 자세히 설명되어 있다.

https://m.blog.naver.com/PostView.nhn?blogId=skinfosec2000&logNo=220482240245 

 

[SQL인젝션] Prepared Statement를 쓰면 SQL 인젝션 공격이 되지 않는 이유는?

Prepared Statement의 내부 원리 개요 SQL인젝션 취약점에 대한 대응방안으로 Prepared Statement와...

blog.naver.com

우리는 SQL Injection 공격을 막기 위해 Prepared Statement를 활용한다는 점만 확인하고 넘어가자.

문제 발생

프로젝트를 진행하던 중, 문제점이 발생했다.

order by를 이용해서 정렬을 수행해야 하는데, 정렬을 위한 값들이 사용자에 의해 프론트에서 파라미터 형태로 들어오기 때문에, 평소와 같이 Prepared Statement를 활용하여 order by 문에 파라미터를 넣어 줬다.

const getLectures = async (client, lectureId, order) => {
  const { rows } = await client.query(
    `
    SELECT * from lecture
    WHERE id = $1
    order by $2
    `,
    [lectureId, order]
  );
  return convertSnakeToCamel.keysToCamel(rows[0]);
};

하지만, 쿼리문이 정상적으로 작동하지 않았고, order by 문이 없는 것처럼 동작되었다.

해당 문제점에 대해 확인해 본 결과,

이러한 스택오버플로우 게시글들을 확인할 수 있었다.

게시글들을 확인해 본 결과, 해당 문제점이 나에게만 발생하는 문제가 아니라는 것을 확인할 수 있었고, Prepared Statement를 사용하는 경우 쿼리의 파라미터로 컬럼 또는 테이블 이름을 넣을 수는 없다는 것을 확인할 수 있었고, 직접 적절한 order by 구문을 작성해 주는 방법밖에 없었다.

해당 문제를 해결하기 위해, pg-format이라는 npm 모듈을 활용하였다.

pg-format이란

pg-format이란 dynamic SQL Query를 안전하게 작성하기 위한 postgreSQL용 formatter로, 포맷을 identifier와 literal, string으로 구분하여 SQL Injection을 회피할 수 있게 해 준다. order by 구문의 경우 해당 컬럼의 값을 이용해서 직접적인 데이터 조회는 불가능하기 때문에 파라미터를 단순 string으로 넣어 줘도 괜찮은데, 이러한 상황을 위해 여러 가지 포맷 스트링을 이용하여 구분해서 데이터를 넣어 주는 모듈이다.

pg-format의 사용법은 기본적으로 npm 모듈 페이지에 잘 작성되어 있다. 해당 모듈의 사용법을 간단히 정리해 보았다.

포맷의 기본값으로, %I, %L, %s 3가지의 포맷이 존재한다.

%I : SQL Identifier - 식별자, 개체의 이름으로 활용되는 포맷(컬럼명, 테이블명)

%L : SQL Literal - 리터럴, Dynamic SQL에서 변수 형태로 활용되는 포맷(WHERE문의 조건)

%s : simple string - 일반적인 String 값에 활용되는 포맷(LIMIT 조건 등)

기본 사용법

const format = require('pg-format');
const getLectures = async (client, lectureId, order) => {
  const { rows } = await client.query(
    format(
      `
      SELECT * from lecture
      WHERE id = %L
      order by %I
      `,
      lectureId, order
    )
  );
  return convertSnakeToCamel.keysToCamel(rows[0]);
};

위의 코드 형태처럼, 기존에 Prepared Statement의 ${num} 부분에 적절한 포맷 스트링을 넣어 주고, 뒤에 순서대로 각 포맷에 해당하는 값들을 넣어 주면 된다. 다른 언어에서의 포맷 스트링 사용법과 유사하다.

보다 자세한 사용법은 https://www.npmjs.com/package/pg-format 을 참고하면 된다.

 

pg-format

Node.js implementation of PostgreSQL's format() to safely create dynamic SQL queries.

www.npmjs.com

 

참고문헌

반응형

자바에서는 자료구조를 사용할 때, Collection이라는 객체를 이용한다.

Collection이라는 인터페이스를 기반으로 내부에 객체를 저장하고, 조작할 수 있느 구조를 제공하고 있으며, Collection 인터페이스를 기반으로 만들어지기 때문에 Java Collection Framework라고 명명하고 있다.

Iterable 인터페이스와 Collection 인터페이스를 기반으로, List, Queue, Set이 존재하고, 그 외에도 Collection 인터페이스 기반은 아니지만, 데이터를 효율적으로 관리한다는 측면에서 일반적으로 Map도 함께 이야기되고 있다.

Collection 프레임워크의 경우 여러 가지 형태의 구현체로 만들어져 있기 때문에, 다양한 자료 구조의 특징을 알고 자신이 작성하고자 하는 프로그램에서 유용하거나 효율적인 자료구조가 어떤 것일지를 선택하는 것이 중요하다.

 

Java Collection Framework Hierarchy
Java Map Interface

 

각 인터페이스들은 인터페이스 하위의 구현체로 구현되고, Java 코드 내에서 사용하기 위해 인터페이스에 구현 객체를 생성하여 부여하는 식으로 사용된다. 아래의 코드는 Integer를 원소로 갖는 arraylist라는 이름의 List 인터페이스를 ArrayList를 이용하여 구현한다는 의미이다.

List<Integer> arraylist = new ArrayList<>();

이때, 다양한 프로그래밍을 하다 보면 인터페이스 자체는 동일하지만 구현체만 변경해 줘야 할 필요성이 있는 경우가 있다. 따라서 인터페이스와 구현체를 분리해 주는 것을 권장한다.

ArrayList<Integer> list1 = new ArrayList<>();
List<Integer> list2 = new ArrayList<>();

list1과 list2의 경우, 코드를 사용함에 있어서 구현상 차이는 존재하지 않는다. 하지만 성능을 측정해 본 결과, ArrayList가 아닌 LinkedList로 구현체를 변경할 필요가 있을 때, list2의 경우 인터페이스가 아닌 구현체 부분만 변경해 주면 되지만, list1의 경우 인터페이스와 구현체를 모두 변경해 주어야 한다. 따라서, 객체 지향프로그래밍에서의 가장 큰 장점인 확장성을 이용하지 못하게 되는 것이다. 따라서 객체지향 프로그래밍 언어의 대표격인 Java에서는 list2와 같이 구현하는 것을 권장하고 있다.

 

1. List

List 인터페이스는 순서가 존재하는 것이 가장 큰 특징이다. 각 구현체별 특징은 아래와 같다.

구현체 특징
ArrayList 단방향 포인터 구조로, 각 데이터에 대한 인덱스를 갖고 있기 때문에 데이터의 접근 연산에 유리하지만, 데이터의 삽입/삭제 연산의 경우 불리하다.
LinkedList 양방향 포인터 구조이기 때문에 데이터의 삽입/삭제 연산에 있어서 유리하지만 데이터의 인덱스는 존재하지 않기 때문에 데이터 접근 연산의 경우 불리하다.
Vector ArrayList와 유사한 구현체이지만, Thread-safe하다.
Stack 자료 구조에서의 Stack을 의미한다. List 인터페이스에 포함되긴 하지만, Stack을 사용하는 경우를 제외하면 사용하지 않는다.

 

2. Queue

순서가 있는 데이터 중, 선입선출을 보장하는 리스트로 볼 수 있다.  Queue의 하위 인터페이스로 Deque가 존재하는데, Deque 인터페이스의 경우 양쪽에서 요소를 제거 및 추가할 수 있다. Deque는 ArrayQueue와 LinkedList 두 가지 구현체가 존재하는데, 이는 역시 Queue의 구현체로 사용될 수 있다. 각 구현체별 특징은 아래와 같다.

구현체 특징
PriorityQueue 우선순위 큐를 의미한다. Null 값이 들어갈 수 없다.
ArrayQueue Deque 인터페이스의 구현체로, ArrayList와 유사한 특징을 갖고 있는 큐 자료구조이다.

 

3. Set

순서가 없는 데이터의 집합을 의미한다. 데이터의 중복을 허용하지 않는다. 위의 사진에서, Set이라는 인터페이스 하위에 SortedSet이라는 인터페이스가 존재하는 것을 볼 수 있는데, SortedSet의 경우 요소에 대한 순서를 제공하는 Set 자료구조를 의미한다. SortedSet의 경우 구현체로 TreeSet만 존재한다. Set의 구현체별 특징은 아래와 같다.

구현체 특징
HashSet 데이터의 저장을 위해 해시 테이블을 사용한다. 해싱을 통하여 요소를 저장한다.
LinkedHashSet HashSet 클래스의 확장으로, LinkedList를 이용하여 구현된 HashSet을 의미한다. 따라서 삽입 순서를 알 수 있고, Null 요소도 삽입이 가능하다.
TreeSet Set의 저장을 위해 트리를 사용한다. 액세스 및 검색 속도가 매우 빠르다는 특징이 있다.

 

4. Map

키-밸류 쌍을 기반으로 데이터를 저장하는 자료 구조를 의미한다. 키의 경우 중복을 허용하지 않고, 밸류의 경우 중복이 가능하다. 맵은 일반적으로 키를 기반으로 밸류를 검색/갱신/삭제해야 하는 경우에 유용하게 사용될 수 있다. Map의 하위 인터페이스로 SortedMap이 존재하는데, 키 값에 대한 순서가 존재하는 Map 자료구조를 의미한다. SortedMap의 경우 구현체로 TreeMap만 존재한다. Map의 구현체별 특징은 아래와 같다.

구현체 특징
HashMap 데이터의 저장을 위해 해시 테이블을 사용한다. 키 값의 해싱을 통하여 밸류를 저장한다.
LinkedHashMap HashMap 클래스의 확장으로, LinkedList를 이용하여 구현된 HashMap을 의미한다. 따라서 삽입 순서를 알 수 있다.
TreeMap Map의 저장을 위해 트리를 사용한다. 오름차순을 유지한다.

 

참고문헌

- https://www.javatpoint.com/collections-in-java

- https://www.javatpoint.com/java-map

 

 

반응형

'Development > Algorithm' 카테고리의 다른 글

[programmers] Greedy - 구명보트  (0) 2021.03.24
[programmers] Greedy - 큰 수 만들기  (0) 2021.03.24
[programmers] Greedy - 조이스틱  (0) 2021.03.24
[programmers] Greedy - 체육복  (0) 2021.03.23
[boj] 2504 - 괄호의 값  (0) 2021.03.14

+ Recent posts