블로그

인프런 비즈니스 신규 기능 업데이트

인프런 비즈니스 신규 기능 업데이트 소식을 전합니다. 지난해는 글로벌 서비스와 앱 서비스 출시를 중심으로 발전해온 한 해였습니다. 올해는 관리자분들의 운영 부담을 덜고, 수강생들의 학습 효과를 높이는 다양한 기능들을 선보일 예정입니다. 앞으로 더욱 자주 소식을 전해드릴 예정이니 많은 관심과 응원 부탁드립니다 :) INDEX01 - 인프런 비즈니스 승인 예약 기능 출시02 - 인프런 APP 출시03 - 인프런 글로벌 서비스 출시 01 — 인프런 비즈니스 승인 예약 기능 출시 ⏳'승인 예약' 기능이 새롭게 추가되었습니다! 이제 수강 신청 내역을 원하는 날짜와 시간에 맞춰 자동으로 승인할 수 있습니다. 기존에는 교육 시작일에 맞춰 직접 관리자 페이지에 접속해 수강 신청을 수동으로 승인해야 했지만, 이제는 미리 승인 일정을 설정하면 지정한 시간에 자동으로 승인 처리가 이루어집니다. 관리자의 운영 부담을 줄이고, 보다 효율적인 학습 환경을 만들 수 있도록 승인 예약 기능을 활용해보세요.  📌CASE 01 - 지정된 수강 신청 기간이 있는 경우 (매월 N일 ~ N일)수강 신청 기간 : 학습자는 지정된 기간동안 자유롭게 수강 신청할 수 있습니다.관리자 승인 처리 : 수강 신청 기간 종료 후, 관리자가 신청 내역을 검토하여 승인 또는 반려 처리합니다.승인 예약 설정 : 관리자는 교육 시작일(OO월 OO일 OO시)에 맞추어 승인 예약을 설정합니다.자동 승인 처리 : 설정된 시간에 반려 건을 제외한 모든 수강 신청이 자동으로 일괄 승인됩니다. 📌CASE 02 - 수강 신청 기간이 지정되어 있지 않은 경우 (매월 1일 ~ 말일)수강 신청 : 학습자들은 별도의 기한 없이 자유롭게 수강 신청할 수 있습니다.승인 예약 설정 : 관리자는 교육 시작일(OO월 OO일 OO시)에 맞춰 승인 예약을 설정합니다.자동 승인 처리 : 설정된 시간에 반려 건을 제외한 모든 수강 신청이 일괄 승인됩니다.📌Tip - 매월 1일 교육이 시작되는 경우, 1일 자정(00:00)에 승인 예약 기능을 활용하시면 편리합니다. 02 — 인프런 APP 출시 📱인프런 모바일 앱, 사용해보셨나요? 이제는 노트북 없이도 출퇴근길, 카페, 이동 중 언제 어디서나 편리하게 강의를 들을 수 있습니다. 앞으로도 지속적인 기능 업데이트를 통해 더욱 완벽한 학습 도구로 발전해 나갈 예정이니, 많은 관심과 이용 부탁드립니다! 📌POINT 01 - 인프런 모바일 앱 다운로드iOS와 Android 앱 모두 사용할 수 있어요.24년도 6월 이전에 다운로드 받았던 인프런 앱은 삭제하고, 신규 출시된 앱을 다운로드 받아주세요. 📌POINT 02 - 오프라인 재생 기능 지원강의를 다운로드하여 오프라인에서도 시청할 수 있습니다.이동 중에도 데이터 걱정 없이 강의를 편리하게 학습하세요. 📌POINT 02 - 강의실 제스처 지원IT 강의 특성상 코드 화면을 볼 일이 많죠? 많은 개발자분들이 요청하셨던 제스처 기능이 추가되었습니다. 롱프레스 → 2배속 재생더블탭 → 5초 건너뛰기제스처 → 전체 화면 전환줌 인/아웃 기능 → 코드 화면 확대 및 축소 가능 수강예정, 수강 중 강의와 완강한 강의를 구분해서 쉽게 확인할 수 있어요. 캡처를 이용해서 원하는 수업 구간을 사진 보관함에 저장할 수 있어요.개인 스크린샷, 영상녹화는 불가하니 이 점 유의해주세요. 영상뿐만 아니라 준비해 둔 수업자료도 놓치지 마세요.전체화면인 경우에는 플레이어 하단에 수업자료 버튼을 클릭해 보세요. 전체화면이 아닐 때 플레이어를 하단으로 쓸어보세요. 내 학습 리스트로 바로 갈 수 있어요. 플레이어 영역을 반복 터치해 보세요 *초 이동으로 원하는 시점에서 수강할 수 있어요. 03 — 인프런 글로벌 서비스 출시 🌏이제 인프런이 국경을 넘어 더 많은 학습자들과 함께합니다! 영어, 베트남어, 일본어 버전이 정식 출시되었으며, 모든 강의에서 다국어 자막과 더빙을 지원합니다. 원하는 언어로 강의를 학습할 수 있어, 더욱 자유롭고 편리한 학습 경험을 제공합니다. 인프런이 추구하는 "Learn, Share, Grow"의 가치가 어떻게 글로벌로 확장되는지, 함께 지켜봐 주세요! 📌 글로벌 학습 환경을 위한 핵심 기능다국어 자막 & 더빙 지원 – 한국어 강의도 영어, 일본어, 중국어 등 다양한 언어로 시청 가능글로벌 학습자 대상 콘텐츠 제공 – 해외 학습자도 국내 인기 강의를 모국어로 학습 가능📌 기업 맞춤형 글로벌 교육 지원해외 지사 직원 교육이나 국내 외국인 직원을 위한강의 콘텐츠가 필요한 기업은 편하게 문의 주세요.문의 | group@inflab.com📌 인프런 글로벌 서비스 둘러보기English - https://inf.run/8BDWrTiếng Việt - https://inf.run/mXLsY日本語 - https://inf.run/Yqqyy 직원이 성장하고, 조직이 성공하는 인프런 비즈니스🔗인프런 비즈니스 홈페이지🔗인프런 비즈니스 콘텐츠  우리는 성장 기회의 평등을 추구합니다.©인프랩 | 경기도 성남시 분당구 판교로289번길 20, 3동 5F©InfLab. All rights reserved.

인프런비즈니스

감자

나는 AI에 대체될까?

AI 시대에는 분야를 막론하고 "AI가 내 자리를 대체하지 않을까?"라는 걱정을 피하기 어렵습니다.특히 개발자들은 코드 자동 생성 서비스가 폭발적으로 등장하면서 "이제 코딩 공부는 필요 없겠다"라고 생각할 수 있습니다.과연 이것이 사실일까요?우리는 정말 코딩 공부를 하지 않아도 될까요?이 질문에 답하기 전에 2025년 3월의 한 기사를 살펴보겠습니다. 빌게이츠가 예측한 AI 시대 유망한 직업 ‘세 가지’… "의사·교사는 AI에 대체될 것”다만 게이츠는 전 직종에서 AI가 인간을 대체할 것이라면서도 일부 직종의 경우 대체되지 않는 직업도 있을 것이라고 했다. 그는 "기계가 야구를 하는 것을 누구도 보고 싶지 않을 것"이라고 했다.그러면서 AI가 대체하기 힘든 직업으로 '코딩 개발자, 에너지 전문가, 생물학자' 등을 언급했다. 최신 AI 모델들이 등장할 때마다 개발자들이 가장 먼저 대체될 것이라는 주장이 나오고 있지만, 게이츠는 인간 전문가가 필수적이라고 보고 있다.게이츠는 AI가 코드를 생성할 수 있다는 것은 분명하지만, 이 과정에서 여전히 인간이 필요하다고 했다.인간 전문가는 오류를 식별하고 수정하며, 알고리즘을 개선하고 AI 개발을 강화하는 데 반드시 필요하다는 설명이다. 이어 게이츠는 생물학자도 AI가 대체하기 어려울 것이라고 주장했다. 빌게이츠가 언급한 AI 시대에도 대체되기 어려운 직업으로는 코딩 개발자, 에너지 전문가, 생물학자가 있습니다. 이 중에서 코딩 개발자에 초점을 맞춰 살펴보겠습니다.AI가 코드를 빠르게 생성할 수 있게 되면서 개발자의 생산성은 크게 향상되었습니다. 하지만 동시에 컴퓨터 과학에 대한 깊은 지식이 필요 없는 단순 코드 생성 작업은 AI가 신입 개발자의 역할을 대체하고 있습니다. 이러한 기술적 변화와 경제적 요인으로 신입 개발자 채용이 감소하고 있습니다.그렇다면 주니어 개발자들은 개발직을 포기하고 다른 진로를 모색해야 할까요? 앞서 본 기사에 따르면, 개발자가 여전히 필요한 이유는 AI가 생성한 잘못된 코드와 비효율적인 알고리즘을 수정해야 하기 때문입니다. 즉, AI가 만든 코드의 품질을 판단하고 개선할 수 있는 능력이 필수적이라는 뜻입니다.경험이 부족한 주니어 개발자들은 이러한 능력이 아직 미흡할 수 있습니다. 하지만 AI 시대에 살아남기 위해서는 반드시 이러한 역량을 키워야 합니다.  컴퓨터 공학(Computer Science)에 대한 지식은 이러한 능력을 키우는 데 필수적입니다.이는 주니어 개발자는 물론 시니어 개발자에게도 해당됩니다.컴퓨터 공학은 컴퓨터 구조, 운영체제, 자료구조와 알고리즘, 네트워크, 데이터베이스 등을 포함합니다.이번 포스트에서는 그 중 컴퓨터 구조에 초점을 맞추어 보겠습니다.컴퓨터는 0과 1을 스위칭 하는 장치로 만들어집니다.과거에는 릴레이라는 장치를 이용해 만들었고, 이보다 효율적인 진공관, 트랜지스터로 발전되어 왔습니다.현재 컴퓨터는 트랜지스터를 이용해 만들 수 있는데요.트랜지스터로 논리 회로를 구성하고, 논리 회로를 조합해 프로그래밍을 할 수 있는 컴퓨터를 만듭니다.이 과정에서 논리 연산과 논리 연산의 특성, 메모리의 구조와 특성, 기계어와 어셈블리어를 다루면서 메모리에 대한 추상적인 이해가 아니라 실제적인 이해를 할 수 있습니다.이를 이해한다면 C언어의 메모리 접근은 굉장히 쉽게 느껴질 수 있습니다.그리고 컴퓨터가 ‘진짜로 어떻게 동작하는지’를 이해할 수 있기 때문에 상위 계층에서 해결하기 어려운 최적화 작업도 할 수 있는 능력을 가지게 됩니다.단순히 코드를 빠르게 만들어 내는 것은 AI가 가장 잘하는 것입니다.AI가 주도하는 시대에 우리는 컴퓨터 공학에 대한 기초를 단단히 가지고 AI의 부족한 부분을 채워 확실한 경쟁력을 가졌으면 좋겠습니다.그렇지 않으면 대체될 것입니다. 컴퓨터 구조는 대학교 수업, 인터넷 강의, 서적 등 다양한 방법으로 배울 수 있습니다.제가 준비한 컴퓨터 구조 강의는 시각적 자료를 활용하여 개념을 쉽게 설명하고, 실제 8비트 컴퓨터를 직접 만들어보며 컴퓨터의 구조와 동작 원리를 깊이 이해할 수 있도록 구성했습니다. 컴퓨터 구조를 배우는 것은 단순히 AI 시대의 흐름을 쫓아가는 것이 아닌, 그 흐름을 주도할 수 있는 힘을 키우는 일입니다. 이 강의를 통해 여러분이 기술의 최전선에서 활약하며 세상의 변화를 이끌어낼 수 있도록 돕겠습니다.(2025년 5월 10일까지 30%할인 진행하고 있습니다)add_shortcode('course','336749','list')

컴퓨터 구조컴퓨터과학컴퓨터구조AI

WhoSoon Hwang

15. 내가 생각하는 반복 (feat. 이소룡)

 요즘 개발자들에게 자주 듣는ㅋㅋㅋ 질문) “어떻게 하면 그렇게 개발을 하시나요?”내 답변) 내가 살아온 경험을 공유해주니… 질문자 답변) “그렇게까지 하고 싶진 않네요. 좀 더 쉬운 길은 없나요.”내 답변) “저는 이렇게 해왔어서 다른 길은 저도 잘, 다른 분들에게 물어보시는 게 나을지도 모르겠네요.”내 생각) 그런 마인드라면 지금과 별반 다르진 않을텐데.. 물론 다른 방법도 많겠지만..같은 방법으로 살면서 다른 결과를 어떻게 기대하지 도통 이해가 안 된다. 모두가 잘하는 방법은 수없이 많이 듣는다. 들을 때뿐이어서 그렇지. 왜 알면서 안 할까? 노력 없이, 희생 없이 무언가를 얻고 싶으면 다른 길을 찾아봐야 하는데 그 어떤 길도 그렇게 쉽게 얻을 수 없다고 생각하는 편이다. 나도 아직 너무나 부족한데, 나보다 부족하다고 생각하는 사람들이 나만큼도 노력을 하지 않는다.나는 여전히 가장 많은 코드를 구현하고, 리팩토링하고, 가장 많은 공부를 한다. 내가 선택한 길이고, 내가 원하는 꿈 너머 꿈을 현실로 만들기 위해서는 아직도 턱없이 부족하다.[나는 한번 수련에 만 번의 발차기를 하는 사람은 무섭지 않다. 한 번씩의 발차기 수련을 만 번 하는 사람이 무서운 거다.] - 이소룡 (ref. https://qusmo.com/celeb/2)나는 이소룡의 재능이 없기에 십만 번 하는 사람이 되어보려 한다. 근데, 반복만 하는 게 아니라 반복할 때마다 달라야 한다. 전과 똑같은 반복은 성장의 폭이 너무 얇다.

개발 · 프로그래밍 기타반복수련

인프런 비즈니스 도입 검토 시 가장 자주 묻는 질문 Top 8

인프런 비즈니스의 특징은, 이미 많은 임직원이 인프런에서 학습한 경험을 바탕으로 기업 도입을 요청하는 경우가 많다는 점입니다. 하지만 정작 비즈니스 서비스는 직접 사용해본 경험이 없다 보니, 교육 담당자들의 문의가 이어집니다. 인프런 비즈니스 도입을 고민하는 기업 교육 담당자들이 가장 궁금해하는 질문 TOP 8, 지금 바로 확인해보세요! INDEX01. 비용은 어떻게 되나요?02. 결제는 어떻게 진행되나요?03. LMS 기능이 제공되나요?04. 원하는 강의만 지원할 수 있나요?05. 강의는 어떻게 구성되어 있나요?06. 수강 신청은 어떻게 이뤄지나요?07. 계정 관리는 어떻게 하나요?08. 수료증 발급은 가능한가요? 직원이 성장하고, 조직이 성공하는 인프런 비즈니스🔗우리 회사에 딱 맞는 기업 교육 문의하기🔗인프런 비즈니스 다른 콘텐츠 더보기 01. 비용은 어떻게 되나요?인프런 비즈니스는 매달 고정 비용이 청구되는 방식이 아니라, 수강 신청한 강의에 대해서만 비용이 발생하는 구조입니다. 학습자가 필요한 강의를 원하는 시점에 신청하고, 실제 수강한 강의에 대해서만 비용을 부담하기 때문에 불필요한 예산 지출을 최소화할 수 있습니다.비용은 월별로 정산되며, 해당 기간 동안 임직원들이 수강 신청한 강의 수에 따라 책정됩니다. 강의 금액 × 수강 신청 인원수 방식으로 계산되며, 기업은 실제 수강한 강의에 대해서만 결제하면 됩니다. 덕분에 예산을 효율적으로 운영하면서도 최적의 학습 경험을 제공할 수 있습니다.인프런의 평균 유료 강의 가격은 5만 4천 원이며, 전체 강의의 20%는 무료로 제공됩니다.일반적으로 유료 강의 비용이나 개수 한도를 설정하고, 무료 강의는 무제한으로 지원하는 방식으로 운영합니다.인프런 강의의 80%는 시청 기한 제한 없이, 반복 학습이 가능합니다.  02. 결제는 어떻게 진행되나요?인프런 비즈니스의 결제 방식은 교육 운영 방식에 따라 선불 충전과 후불 정산 중에서 적합한 결제 방식을 선택할 수 있습니다. ① 선불 충전(무통장 입금) 방식은 미리 예치금을 충전한 뒤, 수강 신청한 금액만큼 자동 차감되는 방식입니다. ② 후불 정산(무통장 입금 또는 카드 결제) 방식은 한 달 동안의 수강 신청 내역을 기준으로 익월 초에 결제가 진행됩니다.무통장 입금 시 세금계산서 발행이 가능합니다. 03. LMS 기능이 제공되나요?인프런 비즈니스는 기업 맞춤형 교육 운영을 지원하기 위해 관리자 페이지를 무상으로 제공합니다. 간단한 설정만으로 빠르게 교육 환경을 구축할 수 있어, 교육 담당자는 운영 부담을 줄이고, 임직원들은 자율적이고 체계적인 학습 환경에서 효과적으로 학습할 수 있습니다.관리자 페이지를 통해 강의 설정, 멤버 등록, 정산 관리 등을 간편하게 할 수 있으며, 예약 입과 및 학습 독려 메일 예약 발송 기능을 지원해 효율적인 교육 운영이 가능합니다. 또한, 실시간 학습 현황을 모니터링 할 수 있어 성과 관리가 용이하며, 임직원들의 학습 데이터를 기반으로 교육을 새롭게 기획할 수 있습니다.자체 LMS 시스템을 운영하는 기업의 경우, API 및 SSO 연동을 지원합니다. 04. 원하는 강의만 지원할 수 있나요?기업은 관리자 페이지에서 지원할 강의를 직접 설정할 수 있습니다. 특정 강의 카테고리를 지정하거나 개별 강의를 선택해 지원할 수도 있으며, 1인당 예산과 수강 신청 가능 개수를 설정해 체계적이면서도 자율적인 학습 환경을 조성할 수 있습니다.또한, 미지원 강의에 대한 설정도 가능합니다. 미지원 강의는 개인 결제로 진행하도록 설정할 수 있으며, 필요에 따라 홈페이지에서 미지원 강의를 아예 노출하지 않도록 제한할 수도 있어, 기업의 교육 운영 정책에 맞춰 유연하게 관리할 수 있습니다. 05. 강의는 어떻게 구성되어 있나요?인프런은 IT 직무에 특화된 교육 플랫폼으로, AI, 개발, 데이터 등 IT 핵심 직군을 위한 4,000개 이상의 강의를 제공합니다. 강의는 이론과 실습을 아우르는 체계적인 커리큘럼으로 구성되어 있어, 학습한 내용을 실제 업무에 적용할 수 있도록 돕습니다.또한, 인프런의 질의응답 시스템을 통해 학습자들은 강의 중 궁금한 내용을 질문할 수 있으며, 평균 48시간 내 답변을 받을 수 있습니다. 지식공유자와 AI 인턴이 학습자의 질문에 응답하며, 사후 관리까지 지원해 효과적인 학습이 이루어질 수 있도록 돕습니다.인프런 앱을 통해 출퇴근 시간에도 강의를 시청할 수 있습니다.인프런에서는 매월 평균 40~50개의 신규 강의가 개설되며, 비즈니스 멤버들에게 실시간으로 제공됩니다. 06. 수강 신청은 어떻게 이뤄지나요?수강 신청은 기업이 설정한 지원 범위(예산, 유료 강의 개수) 내에서 진행되며, 운영 방식에 따라 세 가지 방법을 선택할 수 있습니다.① 자율 수강 신청: 학습자가 직접 강의를 탐색하고 선택해 수강하는 방식으로, 개인의 관심사와 직무에 맞춘 학습 설계가 가능해 학습 효율과 만족도를 높일 수 있습니다.② 관리자 승인: 자율 수강 신청에 관리 단계를 추가한 방식으로, 관리자가 신청 내역을 승인하거나 반려할 수 있습니다.③ 관리자 수동 입과: 관리자가 특정 강의와 대상을 지정해 직접 등록하는 방식으로, 부서 별 역량 강화나 필수 교육 이수에 주로 활용됩니다.수강 신청 기간을 별도로 설정하여 운영할 수 있으며, 일반적으로 관리자 승인 단계를 두는 경우, 수강 신청 기간을 설정한 후 다음날 일괄적으로 입과하는 방식으로 운영됩니다. 07. 계정 관리는 어떻게 하나요?인프런은 1인 1계정 원칙으로 운영되며, 각 멤버는 본인 계정으로 필요한 강의를 신청하고 학습을 진행합니다.관리자는 회사 이메일을 이용해 멤버를 일괄 등록할 수 있습니다. 인프런 계정이 자동으로 생성되며, 이미 가입된 계정의 경우 비즈니스 서비스 학습 안내 메일이 발송됩니다. 아직 가입하지 않은 경우에는 인증 메일이 자동 전송되어 손쉽게 계정을 등록할 수 있습니다. 또한, 관리자 페이지에서 직접 멤버를 추가하거나 정보 변경이 가능하며, 이직 및 퇴사자의 멤버 삭제 처리도 손쉽게 진행할 수 있습니다.비즈니스 서비스 이용에 필요한 최소 인원 제한은 없습니다.인프런 비즈니스는 인원수에 따라 매달 고정 비용이 청구되는 방식이 아니므로, 등록된 멤버 중 실제로 교육에 참여한 인원의 수강 신청 내역에 대해서만 비용이 청구됩니다. 08. 수료증 발급은 가능한가요?인프런에서는 100% 완강한 경우에만 수료 처리되며, 학습자가 수료증을 직접 다운로드할 수 있도록 기능을 지원하고 있습니다. 학습자는 학습 목표 달성을 위해 수강 독려 시스템을 활용할 수 있으며, 스스로 목표를 설정하고 대시보드와 수강 독려 알림을 통해 학습을 지속할 수 있습니다. 또한, 관리자는 실시간 학습 현황을 확인하고, 자동 이메일 발송 기능을 활용해 주기적으로 학습을 독려하여 높은 참여율과 수료율을 달성할 수 있습니다.학습 현황은 관리자 페이지에서 엑셀로 다운로드할 수 있어 성과 관리에 효율적으로 활용할 수 있습니다.강의 완강 여부에 따라 수료는 시스템에서 자동 처리됩니다. 별도 수료 기준이 필요한 경우, 실시간 진도율 데이터를 활용해 수료 여부를 판별할 수 있습니다. 직원이 성장하고, 조직이 성공하는 인프런 비즈니스🔗우리 회사에 딱 맞는 기업 교육 문의하기🔗인프런 비즈니스 다른 콘텐츠 더보기  우리는 성장 기회의 평등을 추구합니다.©인프랩 | 경기도 성남시 분당구 판교로289번길 20, 3동 5F©InfLab. All rights reserved.

인프런비즈니스

10

우빈님의 세심한 코드 리뷰 - 인프런 워밍업 클럽 3기 백엔드 코드 ✨

👣 발자국 책갈피인프런 워밍업 클럽 3기 백엔드 코드 발자국 1주차인프런 워밍업 클럽 3기 백엔드 코드 발자국 2주차인프런 워밍업 클럽 3기 백엔드 코드 발자국 3주차인프런 워밍업 클럽 3기 백엔드 코드 발자국 4주차✅미션PR 책갈피[미션 Day 2] 추상과 구체 예시 작성[미션 Day 4] 리팩토링 & SOLID 원칙[미션 Day 7] 리팩토링 연습[미션 Day 11] 단위테스트 작성[미션 Day 16] 레이어드 아키텍처 특징 및 테스트 작성법[미션 Day 18] Mock 어노테이션 종류 및 차이점 & BDD 패턴 매치🙊 시작이 반이다... 벌써 중간점검 ?인프런 워밍업 클럽이 시작한지 2주가 지났다.. 앞으로 남은 발자국이 2개 뿐이다.. 👣이번주에는 중간점검으로 온라인 라이브가 진행 되었다. 온라인 라이브에 대한 내용은 다음과 같다.미션 Day 4 에 대한 공통 피드백Q&A에 대한 답변미션 Day 7 코드리뷰 진행각 세션은 놀라울 정도의 세심한 우빈님의 피드백 덕분에 많은 인사이트를 얻게 되어 좋은 시간이었다. 나도 첫번째로 코드리뷰를 신청하고 라이브 마지막에 코드리뷰를 받았는데 너무 좋은 경험이었다. 💪(커피를 좋아하시기로 유명한 우빈님께 Q&A 세션 도중 저가 커피 브랜드 중 어디 브랜드가 제일 맛있냐는 질문이 나왔는데.. 드셔 보신 적이 없다고 답변해 주신 부분이 인상적이었다.. ㅋㅋ 😁)✨ 우빈님의 세심한 코드 리뷰위에서 이야기했듯이 코드리뷰를 첫번째로 신청해서 우빈님께 온라인 라이브 시간에 코드리뷰를 받았다.해당 미션은 "스터디 카페" 프로그램을 리팩토링하는 미션이였는데.. 작년 4분기에 강의를 수강했을 당시에 3번이나 진행하였다.첫 번째 리팩토링, 강의를 듣기 전에 리팩토링두 번째 리팩토링, 강의를 수강하며 리팩토링세 번째 리팩토링, 강의를 수강 후 정리하며 다시 리팩토링이번이 네 번째 리팩토링이였는데 할 때마다 왜 새로운 것인지.. 🥲그래도 손이 기억이라도 한 듯 나름 순조롭게(?) 미션을 진행하게 되었고, 추가적으로 리팩토링을 진행하였고 해당 부분을 리뷰를 받고 싶어 신청하게 되었다.(우빈님께서 4번이라는 부분에 놀라셨는지(?).. 디스코드 스레드에 댓글을 남겨주셨다! 🤣)다시 돌아와서.. 코드리뷰 받은 내용은 아래와 같다.1⃣ 중요 도메인 StudyCafePassType의 구조화 🔗 Github PR 링크StudyCafePassType 구조화 리팩토링 ♻ 리팩토링 코드public enum StudyCafePassType implements PassTypeSelectable, PassTypeFormatter { // 📝 인터페이스 구조화 HOURLY("시간 단위 이용권") { // 📝 사용자 입력에 대한 구조화 @Override public boolean selected(String userInput) { return "1".equals(userInput); } // 📝 사용자 출력 포맷에 대한 구조화 @Override public String format(StudyCafePass pass) { return String.format("%s시간권 - %d원", pass.getDuration(), pass.getPrice()); } } } ✏ 우빈님 리뷰Q. 클래스 내부에서 사용자 입력값 및 출력값에 사용하는 인터페이스를 구현함으로써 오버 엔지니어링이 된 것 같은 느낌이 드네요.. 🤦‍♂️ A. 저도 그렇게 생각해요.. ㅋㅋㅋㅋ 오버 엔지니어링이기보다 PassType은 중요한 도메인 모델인데, Input에서만 의미를 가지는 사용자 선택지가 침투하고 있다. 사용자 선택 방법이 "a", "b", "c"로 바뀐다면? 단순히 입력 방식을 바꿨을 뿐인데 무료 도메인 모델이 수정되어야 하는 엄청난 사태가 발생한다. 항상 구조화를 하는 것이 정답은 아니다. Output format도 마찬가지이다. 책임이 우선이다. 적절한 책임의 분배가 객체의 결합도를 낮추고 응집도를 높이는 것이다.  🤔 돌아보기단순히, OCP를 적용하기 위해 접근해서 리팩토링 했었는데..적절한 객체 책임 분리를 하지 못했으며, 중요한 도메인 모델을 수정하는 엄청 큰 사이드 이펙트가 일어날 수 있다는 점을 간과 했다는 것이다.다음부터는 구조화를 남발하지 않고 책임에 집중해서 리팩토링 해야겠다..2⃣ 이용권을 읽는 부분과 읽은 부분의 개념을 추출하여 객체 분리 🔗 Github PR 링크ReadLockerPasses 객체 분리 ♻ 리팩토링 코드public class ReadLockerPasses { // 📝 LockerPasses를 해석하는 객체 분리 private final List<StudyCafeLockerPass> passes; private ReadLockerPasses(List<StudyCafeLockerPass> passes) { this.passes = passes; } // 📝 lines을 해석하여 List<StudyCafeLockerPass> 객체를 만들어준다. public static ReadLockerPasses ofLines(List<String> lines) { List<StudyCafeLockerPass> passes = lines.stream() .map(ReadLockerPasses::ofLine) .toList(); return new ReadLockerPasses(passes); } private static StudyCafeLockerPass ofLine(String line) { String[] values = line.split(CSV_SPLITTER); // ⭐️ CSV라는 방식에 종속적 StudyCafePassType studyCafePassType = StudyCafePassType.valueOf(values[0]); int duration = Integer.parseInt(values[1]); int price = Integer.parseInt(values[2]); return StudyCafeLockerPass.of(studyCafePassType, duration, price); } // 📝 StudyCafeLockerPasses를 생성해준다. public StudyCafeLockerPasses toPasses() { return StudyCafeLockerPasses.of(passes); } } ✏ 우빈님 리뷰Q. 일급 컬렉션을 적용하기 위해 toPasses() 메서드를 생성했는데 Read~라는 네이밍을 가진 클래스에 많은 책임이 부여된 것 같아 네이밍이 모호한 것 같습니다. 좋은 방법이 있을까요..? 🧐 A. 많은 책임이라고 생각하신 이유가 있을까요? "ReadLockerPasses는 어디선가 읽은 lines를 가지고 StudyCafeLockerPasses를 만들어준다"의 책임으로 보여서, 어색하지 않으며 테스트 코드 작성도 가능하다. 그와 별개로 CSV라는 방식에 종속되어있다. CSV형식이 다른 방식으로 바뀌었을 때 같이 바뀌어야 하는 부분이 CSV_SPLITTER 부분이다. 의도한 것 이라면 상관없다.  🤔 돌아보기Read라는 클래스명을 가지고 있어 StudyCafeLockerPasses를 생성해주는 메서드가 존재해 많은 책임이 있다고 생각했는데..우빈님 리뷰 이후에 다시 보니.. 그렇게 어색한가 싶기도 하다.. ㅎㅎ해당 클래스의 작성 당시 CSV 방식을 의존하려는 의도는 없었다. 단순히 읽은 부분의 개념을 추출한 것인데.. 위의 클래스는 CSV_SPLITTER상수가 사용되어 의도하지 않게 CSV라는 방식에 종속적이게 된 것이다.CSV라는 방식이 변경되면 객체 로직이 바뀌어야 한다.객체 구현 시, 종속성에 대해서 방어적으로 접근할 필요가 있어보인다.3⃣ ProvideException 커스텀 예외🔗 Github PR 링크ProvideException 커스텀 예외 ♻ 리팩토링 코드// 📝 이용권을 가져오는 과정에서 생긴 에러의 커스텀 예외 클래스 생성 public class ProvideException extends RuntimeException { public ProvideException(String message) { super(message); } } public class StudyCafePassMachine { public void run() { try { outputHandler.showPassOrderSummary(order); } catch (AppException e) { outputHandler.showSimpleMessage(e.getMessage()); } catch (ProvideException e) { // 📝 커스텀 예외 catch outputHandler.showSimpleMessage("이용권을 제공받을 수 없습니다."); } catch (Exception e) { outputHandler.showSimpleMessage("알 수 없는 오류가 발생했습니다."); } } } ✏ 우빈님 리뷰Q. AppException 성격이랑 다른 것 같다고 생각되어 Provider 인터페이스에서 발생하는 예외 클래스 ProvideException를 별도로 생성하였습니다. A. 혹시 어떻게 다르다고 생각셨나요?? AppException의 의도는, 프로그램에서 발생할 수 있는 대부분의 애플리케이션 상황을 정의하는 최상위 예외 클래스이다. 만약 ProvideException을 별도로 표기하여 더 구체적인 상황을 나타내고 싶으면, AppException을 상속받아서 구성해야 한다. 그렇지 않으면 커스텀 예외 클래스가 늘어남에 따라 catch절도 같이 늘어날 것이다. 추가적으로, "이용권을 제공받을 수 없습니다."라는 메시지가 사용자 친화적이지 않다.  🤔 돌아보기리팩토링 당시, 초기 이용권을 가져와야만 프로그램이 실행된다는 관점에서 ProvideException의 커스텀 예외 클래스를 작성하였다.하지만 이용권을 가져오는 부분은 프로그램 내부에서 필요한 시점마다 호출하고 있어우빈님 리뷰대로 AppException 클래스를 상속받아서 작성하는 것이 더 나은 설계 같다.예외 메세지도 사용자 관점에서는 친화적이지 않은 것이 분명하다.내가 키오스크 시스템을 사용하다가 저런 메세지를 마주한다면... 화가 날 것 이다... 😡프로그램의 의도를 정확히 파악할 필요가 있어보인다. 또한 예외 메세지도 누가 보는지에 따라 고민해보는 습관을 길러야겠다.이렇게, 요청한 3개의 리뷰와 2개의 추가 리뷰를 받아 보았다..고작 3일 만에 7명이나 리뷰를 해주셨는데 세심하고 또 세심했다... 퀄리티가 상당했다.. ✨이번 온라인 라이브를 통해 우빈님에 대한 팬심과 존경심이 더욱 커졌다....! 📈리뷰해주신 내용으로 다시 리팩토링을 함으로써 한층 더 Readable Code에 대한 성장을 경험할 수 있었다. 🚀💡 자기만의 언어로 강의 키워드 정리하기 섹션 6. 코드 다듬기좋은 주석 - 주석의 양면성주석이 많다는 것 : 추상화가 덜 되고 가독성이 좋지 않은 코드 (코드 품질 저하 📉)주석이 필요한 경우 : 히스토리를 알 수 없을 경우, 주석으로 상세히 설명변수와 메서드 나열 순서변수 : 사용하는 순서대로 위치한다. (인지적 경제성 / 뇌 메모리 줄이기)객체의 공개/비공개 메서드 : 공개 메서드를 상단에 위치하고, 비공개 메서드 하단에 위치한다. 공개 메서드 중에서도 중요도의 순서에 따라 배치한다.공개 메서드 : 객체의 상태를 변경 하는 부분이 가장 상단에 위치하도록 - 상태 변경 >>> 판별 >= 조회비공개 메서드 : 출현한 순서대로패키지 나누기여러 파일들의 네임 스페이스를 관리하기 때문에 적당한 수준으로 잘 나누어야 한다.대규모 패키지 변경은 팀원과의 합의 필요 -> 추후 conflict가 생길 수 있다.기능 유지보수하기정렬 단축키, linting, style - sonarlint, editorconfig섹션 7. 리팩토링 연습메서드 추출로 추상화 레벨 맞추기Optionalreturn null / Optional 파라미터 사용은 안티패턴이다.객체에 메시지 보내기객체를 존중하고 메시지를 보내자.객체의 책임과 응집도⭐️ 추상화 관점의 차이 - FileHandler구현에 초점을 맞춘 추상화 VS 도메인 개념에 초점을 맞춘 추상화File을 read하는 부분의 로직들은 전부 FileHandler에 들어갈 것이다. 잘못된 객체 응집일 수도 있다..방법에 초점을 맞춘 설계 방식이 아닌 어떤 데이터를 가져오는 가에 대한 초점을 맞추는 것이 좋다.섹션 8. 기억하면 좋은 조언들능동적 읽기가지고 있는 리팩토링 기법들을 총동원해서 읽자. -> 리팩토링하면서 읽기눈으로만 보는 수동적 읽기는 권장하지 않는다.도메인 지식을 늘리기 위해서 능동적 읽기가 필요하다. (작성자의 의도 파악)오버 엔지니어링필요한 적정 수준보다 더 높은 수준의 엔지니어링예시 1. 구현체가 하나인 인터페이스구현체가 수정할 때마다 인터페이스도 수정해야 함코드 탐색의 어려움예시 2. 너무 이른 추상화정보가 숨겨지기 때문에 복잡도가 높아진다.후대 개발자들이 선대의 의도를 파악하기가 어렵다.은탄환은 없다클린 코드도 은탄환이 아니다.실무에서의 줄다리기지속 가능한 소프트웨어 품질 VS 기술 부채를 안고 가는 빠른 결과물 -> 클린 코드를 대비한 코드 센스가 필요하다.모든 기술과 방법론은 적정 기술의 범위 내에서 사용되어야 한다.항상 정답인 기술은 없다.한계까지 연습해보고, 적정 수준, 적정 시점을 깨닫는 것이 필요하다.섹션 3. 단위 테스트단위 테스트작은 코드(클래스 또는 메서드) 단위를 독립적으로 검증하는 테스트 -> 가장 기본이 되는 테스트검증 속도가 빠르고, 안정적수동 테스트, 자동화 테스트 -> 인지 필요사람이 검증하는 수동 테스트 -> sout으로 출력하고 눈으로 직접 확인기계가 검증하는 자동화 테스트Junit5, AssertJJunit5 : 단위 테스트를 위한 테스트 프레임워크AssertJ : 테스트 코드 작성을 원할하게 돕는 테스트 라이브러리 - 풍부한 API 메서드 체이닝 지원해피 케이스, 예외 케이스 -> 테스트 케이스 세분화예외 케이스 : 암묵적 혹은 드러나지 않은 요구사항에서 발견경계값 테스트범위, 구간, 날짜 경계값들로 테스트를 해야한다.테스트하기 쉬운/어려운 영역 (순수함수)테스트 하기 어려운 영역을 구분하고 분리하기외부로 분리할수록 테스트 가능한 코드는 많아진다.테스트하기 어려운 영역관측할 때마다 다른 값에 의존하는 코드 : 현재 날짜/시간, 랜덤 값, 전역 변수/함수, 사용자 입력외부 셰계에 영향을 주는 코드 : 표준 출력, 메시지 발송, 데이터베이스에 기록하기순수 함수 - 테스트하기 쉬운 영역같은 입력에는 항상 같은 결과외부 세상과 단절된 형태lombok@Data, @Setter, @AllArgsConstructor 지양양방향 연관관계 시 @ToString 순환 참조 문제섹션 4. TDD: Test Driven DevelopmentTDD 테스트 주도 개발 (Test Driven Development)로, 프로덕션 코드보다 테스트 코드를 먼저 작성하여 테스트가 구현 과정을 주도하도록 하는 방법론선 기능 구현, 테스트 작성의 문제점 (일반적인 개발) - 구현순서 : 기능 -> 테스트테스트 자체의 누락 가능성해피 케이스만 검증할 가능성잘못된 구현을 다소 늦게 발견할 가능성선 테스트 작성, 기능 구현 (TDD) - 구현순서 : 테스트 -> 기능복잡도(유연하며 유지보수가 쉬운)가 낮은 테스트 가능한 코드로 구현할 수 있게 한다.테스트가 힘든 코드를 위한 코드 작성이 가능예를 들면 LocalDateTime.now()의 경우 외부세계로 분리해서 테스트를 하기 편한 코드를 작성할 수 있다.프로덕션 코드를 작성한 후 테스트 코드를 작성하기 귀찮을수도..쉽게 발견하기 어려운 엣지 케이스를 놓치지 않게 해준다.구현에 대한 빠른 피드백을 받을 수 있다.과감한 리팩토링이 가능해진다.테스트 코드가 보장TDD의 관점이전의 관점 : 테스트는 구현부 검증을 위한 보조 수단변화된 관점 : 테스트와 상호 작용하며 발전하는 구현부레드 - 그린 - 리팩토링Red : 실패하는 테스트 작성Green : 테스트 통과 하는 최소한의 코딩Refactor : 구현 코드 개선 테스트 통과 유지애자일 방법론 vs 폭포수 방법론애자일 방법론 https://agilemanifesto.org/iso/ko/manifesto.html반복적 개발(Iterative Development): 짧은 개발 주기(스프린트)를 반복하며 지속적으로 개선.유연성: 요구사항 변경을 수용할 수 있도록 유동적으로 진행.고객 참여: 개발 과정에서 지속적인 피드백을 반영하여 사용자 중심 개발 가능.자율적인 팀 구성: 개발팀이 자체적으로 의사 결정을 하며, 빠르게 문제를 해결함.폭포수 방법론단계적 개발: 요구 분석 → 설계 → 구현 → 테스트 → 배포 → 유지보수 순서로 진행됨.문서 중심: 각 단계마다 문서화가 철저하게 이루어짐.선형 구조: 이전 단계가 완료되어야 다음 단계로 넘어갈 수 있음.변경이 어려움: 초기에 요구사항을 확정하면 이후 변경이 어렵고 비용이 많이 듦.익스트림 프로그래밍XP(Extreme Programming, 익스트림 프로그래밍)는 애자일 방법론 중 하나로, 빠른 개발 주기와 지속적인 피드백을 중심으로 하는 소프트웨어 개발 방법론이다. 고객의 요구사항 변화에 빠르게 대응할 수 있도록 짧은 개발 반복 주기(Iteration)와 강한 협업 문화를 강조한다.스크럼, 칸반스크럼애자일 프레임워크로, 일정한 스프린트 동안 작업을 계획하고 진행하는 반복적이고 점진적인 개발 방식이다. 짧은 개발 스프린트를 통해 빠르게 결과물을 만들고 지속적으로 개선하는 것이 핵심이다.1⃣ 백로그 작성 – 제품 백로그에 모든 요구사항을 정리2⃣ 스프린트 계획 – 스프린트 기간 동안 수행할 작업 선정3⃣ 스프린트 진행 – 개발 진행 및 매일 스탠드업 미팅4⃣ 스프린트 리뷰 – 개발 완료된 기능을 검토5⃣ 회고(Retrospective) – 개선점을 찾고 다음 스프린트에 반영칸반Workflow와 가시성을 중심으로 한 애자일 프레임워크로, 지속적인 개선과 작업량 관리를 중점적으로 다룬다. 작업을 시각적으로 표현하여 현재 진행 상황을 쉽게 파악할 수 있도록 합니다.1⃣ Backlog: 해야 할 작업을 모아둠2⃣ To Do: 현재 진행할 작업3⃣ In Progress: 진행 중인 작업4⃣ Review/Test: 리뷰나 테스트가 필요한 작업5⃣ Done: 완료된 작업섹션 5. 테스트는 []다.테스트 코드는 문서다.프로덕션 기능을 설명해주는 것이 테스트 코드 문서다.다양한 테스트 케이스를 통해 프로덕션 코드를 이해하는 시각과 관점을 보완할 수 있다.고민했던 내용(테스트 코드)을 팀 자산(소스 코드)으로 공유할 수 있다.@DisplayName - 도메인 정책, 용어를 사용한 명확한 문장메서드명만으로 어떤 것을 검증하고자 하는 의도 파악이 어려움Junit5에 추가한 어노테이션이다.문장 형태로 섬세하게 테스트 검증에 대한 내용을 어노테이션안에 작성한다.섬세한 DisplayName특정 시간 이전에 주문을 생성하면 실패한다. ❌영업 시작 시간 이전에는 주문을 생성할 수 없다. ✅도메인 용어를 사용하여 추상화된 내용을 담기 -> 메서드 자체의 관점 보다 도메인 정책 관점 (특정 시간 -> 영업 시작 시간 ✅)테스트의 현상을 중점으로 기술하지 말 것 (~실패한다 ❌)Given / When / Then - 주어진 환경, 행동, 상태 변화Given : 시나리오 진행에 필요한 모든 준비 과정When : 시나리오 행동 진행Then : 시나리오 진행에 대한 결과 명시, 검증TDD vs BDDBDDTDD에서 파생된 개발 방법시나리오 기반한 테스트 케이스 자체에 집중하여 테스트한다.Junit vs SpockSpock은 Groovy언어로 BDD 패턴을 적용해서 테스트 코드를 작성할 수 있다.언어가 사고를 제한한다.명확하지 못한 테스트 코드는 사고를 제한할 수 있다.문서로서의 테스트를 신경 쓸 필요가 있다. 🏃 돌아보며..미션과 발자국을 정신없이 진행하다 보니 벌써 남은 인프런 워밍업 클럽도 2주밖에 남지 않았다. 처음에 OT 라이브 당시 러너가 120명 정도였는데, 이번 중간 점검 라이브 때는 60명 정도로 줄어들었다.강의 내용 자체는 어렵지 않지만.. 2개의 강의(14시간 + 12시간)를 한 달만에 들으면서 미션과 발자국을 진행하는 건 쉽지 않아 보인다.. 나는 미리 강의를 수강해서 다행이다라는 생각이 든다.. 😅하지만, 쉽지 않은 만큼 성실히 참여한다면 단기간 내 성장하는 데 큰 도움이 될 것이다.그리고 이번 주에 코드리뷰를 신청하기 잘했다는 생각이 들었다. 🍀 위에서도 여러 번 언급했지만 우빈님의 세심한 리뷰 탓(?)에내가 미션을 수행하는 데 있어 우빈님보다 세심하게 집착 했었나..? 반성하게 된다... 😭 마지막 주차 온라인 라이브에서도 테스트 코드에 대한 코드리뷰가 진행된다고 한다.기회가 된다면 또 한 번 코드리뷰를 받아 단골 손님이 되고 싶다. 😂2주를 걸쳐, 읽기 좋은 코드의 스터디 과정은 이번주로 막을 내렸다.다음 주차부터는 테스트 코드에 대해 본격적으로 스터디하는 과정이 진행된다.남은 2주도 화이팅하며 좋은 성장을 이루길 기대해 본다. 🔥 끝으로, 3월 중순이 되니 이제 슬슬 봄 내음이 나는 것 같다.. 🌸얼어붙은 개발 시장에도 봄이 찾아왔으면 좋겠다.. 🧊 발자국 2주차 끄읕 ! [출처]인프런 워밍업 클럽 : https://www.inflearn.com/course/offline/warmup-club-3-be-code강의 : https://www.inflearn.com/course/readable-code-%EC%9D%BD%EA%B8%B0%EC%A2%8B%EC%9D%80%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1%EC%82%AC%EA%B3%A0%EB%B2%95/dashboard

백엔드인프런워밍업클럽백엔드3기발자국박우빈클린코드읽기좋은코드

10 1개월 전
수비드(강병수)

[인프런 비즈니스 PICK] 3월 추천 강의 안보면 후회합니다!

안녕하세요. 인프런 비즈니스팀입니다."업무 생산성? 커리어 업그레이드? 트렌드 따라잡기?"걱정 마세요! 인프런 비즈니스팀이 엄선한 강의를 소개해드리는 '인.비.픽!' 🎯업무 스킬 업그레이드는 물론, 트렌디한 최신 IT 강의까지 지금 바로 만나보세요! 🚀 📌 강의 큐레이션(1): 아바타 커뮤니티앱 만들기 (React Native) (클릭)#React Native #TypeScript #React-query #React #javaScript  ✅ 이 강의, 이런 분들께 추천해요!✔ React Native를 활용한 앱 개발에 관심 있는 개발자✔ JavaScript와 React 기초를 학습해 보신 분✔ 소셜 커뮤니티 앱 개발부터 배포까지 하나의 프로젝트를 완성해 보고 싶은 분🎯 이 강의에서 배우는 핵심 스킬🔹 React Native 기반 앱 개발iOS & Android 동시 개발컴포넌트 구조 및 UI 최적화🔹 소셜 커뮤니티 기능 개발프로필 생성, 피드 게시, 실시간 채팅 기능Firebase 기반 데이터베이스 활용🔹 풀스택 개발 경험클라이언트와 서버 연동API 설계 및 데이터 흐름 최적화🚀 이 강의를 들으면 이런 걸 할 수 있어요!✔ 백엔드와 연동하며 풀스택 개발 역량을 키울 수 있어요✔ React Native로 앱을 직접 개발하고 배포할 수 있어요✔ 단순 문법 설명이 아니라, 완성도 있는 앱을 직접 만들어볼 수 있어요🚀 React Native로 실전형 커뮤니티 앱을 만들어 보고 싶다면? 지금 바로 시작하세요! 💡🔥  📌 강의 큐레이션(2): [공식튜토리얼] Dialogue System for Unity (클릭)#Unity #Unity3d-ui  ✅ 이 강의, 이런 분들께 추천해요!✔ 게임 개발을 하면서 대화 시스템을 구현하고 싶은 개발자✔ Unity를 활용한 인터랙티브 스토리텔링에 관심 있는 분✔ NPC와 플레이어 간의 자연스러운 상호작용을 만들고 싶은 분✔ 게임 UI 및 UX 설계를 배우고 싶은 초·중급 개발자🎯 이 강의에서 배우는 핵심 스킬🔹 Unity 기반 대화 시스템 설계 및 구현게임 내 대화 흐름 관리 및 UI 디자인조건부 대화 시스템 및 플레이어 선택지 기능 구현🔹 NPC와 플레이어 상호작용 강화퀘스트 진행에 따른 대화 변화상태 기반 대화 시스템 구축🔹 Unity UI 시스템 활용대화창과 선택지 버튼 등 동적 UI 설계 및 구현텍스트 타이핑 효과와 같은 시각적 요소 추가🚀 이 강의를 들으면 이런 걸 할 수 있어요!✔ RPG, 어드벤처, 인터랙티브 스토리 게임에 활용할 수 있는 대화 시스템을 직접 제작✔ 게임 내 몰입감을 높이는 자연스러운 대화 연출 구현✔ 게임 개발자로서 Unity UI 및 데이터 관리 역량을 한 단계 업그레이드📢 더 몰입감 있는 게임을 만들고 싶다면? 지금 바로 시작해보세요! 🎮🔥  📌 스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판 (클릭)#SpringBoot #MySQL #Redis #Kafka #Java ✅ 이 강의, 이런 분들께 추천해요!✔ 스프링부트를 활용해 확장 가능한 대규모 시스템을 설계하고 싶은 개발자✔ Spring Boot, JPA, Redis, Kafka 등의 기술을 실무에서 활용하고 싶은 분✔ 백엔드 개발자로서 대용량 트래픽 처리 및 성능 최적화에 관심 있는 분🎯 이 강의에서 배우는 핵심 스킬🔹 Spring Boot 기반 대규모 시스템 설계모놀리식(Monolithic) vs 마이크로서비스 아키텍처(MSA) 이해클라우드 환경에서 확장 가능한 백엔드 설계🔹 성능 최적화 및 대용량 트래픽 대응Redis 캐싱 적용 및 DB 부하 감소 전략Kafka를 활용한 비동기 이벤트 처리🔹 실무에서 바로 사용할 수 있는 기술 스택 학습Spring Boot, JPA, MySQL, Redis, Kafka대규모 시스템을 위한 API 설계 & 성능 테스트🚀 이 강의를 들으면 이런 걸 할 수 있어요!✔ 대규모 트래픽을 감당할 수 있는 게시판 시스템을 직접 개발✔ Redis & Kafka를 활용한 성능 최적화 및 비동기 처리 적용✔ 기업 수준의 백엔드 설계를 이해하고 실무에서 활용할 수 있는 경험 확보📢 Spring Boot로 실무형 대규모 시스템을 구축하고 싶다면? 지금 바로 시작하세요! 💡🔥  직원이 성장하고, 조직이 성공하는 인프런 비즈니스🔗 인프런 비즈니스 홈페이지🔗 인프런 비즈니스 콘텐츠  우리는 성장 기회의 평등을 추구합니다.©인프랩 | 경기도 성남시 분당구 판교로289번길 20, 3동 5F©InfLab. All rights reserved.

인프런비즈니스

xx

[인프런 워밍업 클럽 3기 CS] 참여 후기

참여하게 된 계기CS 지식은 기술 면접에서도 자주 등장하고 실제 문제를 해결할 때도 중요한 기반이 되는데, 그에 비해 제 지식은 다소 얕다고 느꼈습니다.자료구조나 알고리즘은 어느 정도 익숙하지만 개념 위주로만 알고 있어 정리가 필요했고, 운영체제에 대한 이해는 특히 부족하다는 생각이 들었습니다. 이 기회에 자료구조와 알고리즘을 정리하고 운영체제의 기본을 다지고 싶어 참여하게 되었습니다. 좋았던 점운영체제는 내용이 추상적이고 딱딱하게 느껴질 수 있는데, 강의에서는 이를 예시나 그림으로 풀어 설명해줘서 이해하기가 훨씬 수월했습니다. 프로세스, 스레드, 메모리 구조 같은 어려운 개념도 시각적으로 설명되니 머릿속에 잘 그려졌고, 실무에서 어떻게 연결되는지도 자연스럽게 이해할 수 있었습니다.또한 자료구조와 알고리즘 파트는 깊이 있게 다루지는 않았지만, 주요 개념을 빠르게 훑는 데에는 도움이 되었고, 전체 흐름을 다시 한 번 정리할 수 있는 기회가 되었습니다. 아쉬운 점스터디가 끝나면 항상 아쉬운 점이 남는 것 같습니다. 개인적으로는 복습을 충분히 하지 못해서, 스터디에서 배운 내용을 완전히 소화하지 못한 것 같다는 점이 가장 아쉽게 느껴졌습니다. 조금 더 시간을 들여 복습하거나, 스터디 이후에도 학습을 이어나갈 계획입니다.

인프런인프런워밍업클럽스터디3기

xx 1개월 전
이소 중입니다

[인프런 워밍업 클럽 스터디 3기] PM 워밍업클럽 4주차 발자국 & 회고 & 스터디 후기

인프런 워밍업클럽 3기에 참여한 수강생의 강의/스터디 후기입니다.1. 강의PM이 무엇인지, PM이 중점을 두고 일해야 하는 것은 무엇인지 명확하게 알려준 강의. 강의에 나온 모든 내용이 선명했다. 심리학개론 같기도 하고 경영학원론 같기도 하지만, 결국 PM은 사업의 지속과 성장을 위해 누군가는 고민해야 하는 업무를 해야 하는 사람이라는 것을 여러 근거를 토대로 타당성 있게 말하고 있다.또한 직장인인 나에게 메타인지를 가질 수 있게 해주었다. 1주차 ‘PM이 하는 일’에서는 내가 회사에서 하고 있는 일이 얼마나 쉬운 난이도의 일인지 말과 글로 일깨워주었다. 팩트 폭격당한 거 맞다. 직장에서 역할의 모호성을 느끼는 기획자, PM이라면 꼭 들어보길 바란다.그 이유는 ‘기획’이라는 직무를 가진 사람이 궁극적으로 나아가야 할 방향성을 잡게 도와주기 때문이다. 우리가 현실적으로 현재 역할을 바꾸거나 업무를 버릴 수는 없다. 그러나 꾸준히 성장해야 하는 방향과 필요성이 무엇인지 알게 된다.2. 스터디인프런의 워밍업 클럽 스터디 일정은 수강생 모두를 고려한 일정으로 잘 짜여져 있다고 생각한다. 현재 다른 일과 병행하지 않고 강의만 집중해서 들을 수 있는 사람이라면 커리큘럼에 맞추어 하루 4시간 정도 심도 있게 공부한다면 빠른 시간 내에 많이 성장할 수 있을 것이다. 직장인의 경우, 소화 못 할 수준의 일정은 아니다. 그치만 강의에 나오는 개념에 대해 생각해 볼 내용들이 많기 때문에 중간중간 재생을 멈추고 곱씹어야 한다. 이렇게 놓고 보면 이론 흡수만 해도 1-2시간이 걸리기 때문에 강의만 들어도 잘 시간이다. 필자는 평소 11시-12시 사이에 취침하는 사람이지만 스터디 기간 동안 1-2시 사이에 잠들고 취미생활에 투자하는 시간도 조금씩 줄어들었었다. 인간적인 현상이다. 평일에 녹초가 되는 직장인 특성상 욕심을 내어 깊게 고민해볼 시간을 내기는 힘들다. 1-2시간 정도의 추가 자습을 하고 싶어도 현실적으로 어려웠기에 내용을 제대로 숙지하지 못했다고 길게 변명을 하는 것이다. 그래서 원래 일정상 4월에는 데이터 분석 강의를 들으려고 했으나 이번 PM/PO 강의에서 학습한 이론을 심화 학습하는 것으로 계획을 변경했다. 한 달간 배운 이론 내용들을 실무에 적용할 수 있는 사례를 적어보고 구체화해 볼 것이다. 사실 스터디와 관련되어 인프런에게 피드백 드리고 싶은 내용이 많은데 글로는 더 쓰긴 어려울 것 같다. 강의에서 주요하게 나왔던 고객을 아는 방법인 '심층 인터뷰' 기회가 있다면 참여할 의향이 있다.3. 마무리스터디 기간 동안 다른 분들은 어떤 식으로 공부하셨는지 궁금하던 차에 코치님께서 스터디원들을 만날 수 있는 기회를 마련해 주셨다. 직무 관련하여 외부 모임에 참여하는 것은 처음이기에 기대되고 설렌다. 우리는 제품이라는 이름 아래 엄청난 범위(영업/마케팅/개발/운영과 관련된 전반적인 지식)에 대해 공유하고 서로에게 많은 영감을 받을 것으로 있다. 참으로 뜻깊은 마무리가 될 것 같다. 한 달 동안 평일의 피곤함을 이겨낼 의지가 있는 누구나에게 추천해 주고 싶은 강의다.

인프런인프런워밍업클럽스터디3기

[인프런 워밍업 클럽 3기] CS - 3주차 미션 & 발자국

운영체제1. 메모리의 종류는 어떤것들이 있나요? 각 메모리의 특징도 함께 적어주세요. 레지스터가장 빠른 메모리CPU 내에 존재휘발성 메모리 (컴퓨터 꺼지면 데이터 사라짐)CPU 구분시 말하는 32/64bit 는 레지스터의 크기를 말하는 것.CPU는 계산시 메인메모리 (RAM)에 있는 값을 레지스터로 가져와서 계산하고 그 결과를 다시 메인메모리에 저장시킴 메인메모리레지스터와 메인메모리 사이에는 휘발성 메모리인 캐시 가 있음.메인메모리는 너무 느리기 때문에 필요할 것 같은 데이터를 미리 캐시로 가져옴.캐시는 성능의 이유로 여러개를 둠.만약 CPU가 값을 요청해 레지스터로 옮겨야 할 때 L1캐시(가장빠름) -> L2캐시 (L3..) -> 메인메모리순서로 값이 있는지 확인함.===메인 메모리는 실제 운영체제와 다른 프로세스들이 올라가는 공간.전원 공급 안되면 데이터가 지워지기에 휘발성 메모리HDD, SDD 보다 속도가 빠르지만 비싸기 때문에 데이터 저장보단 실행 중인 프로그램만 올림. 보조저장장치 (HDD, SSD)비휘발성 메모리.가격이 쌈. 2. 사용자 프로세스가 메모리의 운영체제 영역에 침범하지 못하도록 만든 레지스터는 어떤 레지스터일까요?경계 레지스터. 메모리 관리자가 사용자 프로세스가 경계 레지스터의 값을 벗어났는지 감시하고, 만약 벗어난다면 해당 프로세스를 종료시킨다. 3. 메모리 할당 방식에서 가변 분할 방식과 고정 분할 방식의 장단점은 뭔가요?가변 분할 방식장점 : 메모리의 연속된 공간에 할당 되기에 더 크게 할당되어 낭비되는 공간인 내부 단편화가 적다.단점 : 한 프로세스가 분산되어 할당되므로 메모리 공간이 남아있어도 추가적 할당을 할 수 없는 외부 다편화가 발생한다. 고정 분할 방식장점 : 구현이 간단하고 오버헤드가 적다.단점 : 한 프로세스보다 더 큰 메모리가 할당 될 수 있고 이로 인해 특정 메모리보다 더 큰 공간이 할당되는 내부 단편화가 발생할 수 있다. 4. CPU 사용률을 올리기 위해 멀티프로그래밍을 올렸지만 스왑이 더 많이 이루어져 CPU 사용률이 0%에 가까워 지는 것을 뭐라고 할까요?스레싱.물리 메모리의 크기가 부족해서 일어나는 현상. SWAP시의 컨텍스트 스위칭으로 인해 발생한다.5. HDD나 SSD는 컴퓨터를 실행시키는데 꼭 필요한 걸까요? 이유를 함께 적어주세요.HDD나 SSD가 "꼭" 필요한 건 아니다. 운영체제를 ROM, USB 또는 외부 저장장치에서 부팅하면 HDD나 SSD 없이도 컴퓨터를 실행할 수 있다. 하지만 대부분의 경우 컴퓨터가 안정적으로 동작하려면 운영체제를 저장할 영구 저장장치가 필요해서, 일반적으로 HDD나 SSD가 필수로 여겨진다.메모리는 휘발성이라 전원이 꺼지면 데이터가 사라진다. 그래서 데이터를 영구적으로 저장할 수 있는 HDD나 SSD 같은 장치가 중요하다. 6. 파일을 삭제해도 포렌식으로 파일을 복구할 수 있는 이유가 무엇일까요?OS의 파일 시스템에는 파일 관리를 위해 빈 공간을 모아 두는 Free block list가 있다. 특정 파일을 삭제하면, 파일 시스템은 파일의 모든 정보를 지우는 대신 파일 테이블의 헤더만 삭제하고, 그 파일이 차지하던 블록을 free block list에 추가한다.이렇게 되면 사용자 입장에서는 파일이 삭제된 것처럼 보인다. 하지만 실제로는 사용된 블록의 데이터가 그대로 남아 있기 때문에, 이후 포렌식을 통해 해당 데이터를 복구할 수 있다.  자료구조와 알고리즘1. 지금까지 배운 5개의 정렬 알고리즘의 장단점과 시간 복잡도를 적어주세요. 버블 정렬시간 복잡도: O(n²)장점: 구현이 쉽고 안정 정렬단점: 매우 비효율적 선택 정렬시간 복잡도: O(n²)장점: 데이터 이동 횟수 최소단점: 안정 정렬이 아님, 느림 삽입 정렬시간 복잡도: O(n²)장점: 거의 정렬된 데이터에 빠름 (O(n))단점: 역순이면 O(n²) 병합 정렬시간 복잡도: O(n log n)장점: 항상 빠르고 안정 정렬단점: 추가 메모리 필요 (O(n)) 퀵 정렬시간 복잡도: O(n log n) (최악 O(n²))장점: 평균적으로 가장 빠름, 메모리 적게 사용단점: 최악의 경우 O(n²) 2. 메모리가 부족한 시스템에서 어떤 문제를 해결하는데 재귀로 쉽게 구현이 가능할 것 같습니다. 여러분이라면 메모이제이션과 타뷸레이션 중 어떤 걸 이용하실 건가요? 이유를 함께 적어주세요. 재귀 호출이 과도하게 깊어지면 스택 메모리 한계를 초과하는 스택 오버플로우가 발생할 수 있습니다. 이 문제를 해결하기 위해 타뷸레이션 방식을 활용하면 반복문과 배열을 사용해 중간 계산 결과를 저장함으로써 메모리를 더 효율적으로 관리하고 성능도 향상시킬 수 있습니다.  짧은 기간이었지만 이번 워밍업 클럽 스터디에 참가하면서 미뤄왔던 CS 학습을 시작하고 집중도 있게 할 수 있었다. 쉽고 재밌게 잘 설명해주시는 강의 덕분에 부담감 적게 흥미를 유지하며 학습해나갈 수 있었고, 강사님께서 직접 내주시는 미션을 수행하며 더 효과적인 학습을 할 수 있었다. 이번 학습을 시작으로 앞으로도 꾸준히 흥미를 갖고 CS 관련 학습을 이어가야겠다.

leeebug

워밍업 클럽 스터디 3기 FS - 2주차 발자국

인프런 워밍업 클럽 스터디에 참여하고 벌써 2주 차도 마무리에 접어들고 있다. 4주간의 스터디이기 때문에 생각보다 일정이 타이트하여 시간관리가 무엇보다도 중요한 시기라고 생각한다.이번 주에는 파일 업로드 기능을 구현해야하기에 1주 차 과제를 급하게 마무리하고 지난주 토요일부터 서둘어서 미리 학습을 시작했다.깃 레포지토리의 경우에는 지난주에 사용했던 템플릿을 거의 수정없이 그대로 사용해서 개발환경 구축은 크게 어렵지 않았다.이번 주 강의에서는 Supabase Storage를 사용했는데 API가 잘 준비되어있어서 사용 방법을 익히는데도 크게 어렵지는 않았다. 다만 아래에서도 언급하겠지만 Supabase Storage는 AWS S3 기반으로 구현되어 강력한 네이밍 규칙이 적용되어 개인적으로는 Supabase Storage와 Supabase DB를 함께 사용했다. 📝 2주차 학습Supabase Storage클라우드 기반 객체 저장소로, AWS S3와 유사한 방식으로 파일을 저장하고 관리하는 서비스파일 및 이미지 업로드 및 관리 기능 제공PostgreSQL과 연동 가능권한 관리(RLS) 및 퍼블릭/프라이빗 파일 설정 가능Supabase SDK 또는 Restful API로 사용 가능  ✔ 파일명 규칙 (Supabase & AWS 공통) ASCII 문자, 숫자, 일부 특수 문자 허용 (- _ . /) 파일명을 /로 구분하여 폴더처럼 사용 가능 (folder/image.png) 공백 포함 가능하지만, URL Encoding이 필요할 수 있음 파일명에 한글, 이모지, 특수문자가 포함될 경우 정상적으로 업로드되지 않을 가능성이 있음 → URL-safe 변환 권장 React DropzoneReact에서 간편하게 파일 Drag & Drop 기능을 구현할 수 있는 라이브러리HTML5 File API를 활용하여 파일 업로드를 쉽게 구현할 수 있는 기능을 제공파일 타입, 크기, 개수 등 다양한 제약 조건 설정 가능비동기로 파일을 처리할 수 있는 onDrop 이벤트 제공 📋 2주차 미션💬 GitHub 저장소🚀 데모 영상 보러가기미션 해결 과정 요약2주 차 미션은 Next.js, React Query, TailwindCSS를 사용하여 이미지 업로드 앱을 구현하기였다. 필수 구현 기능으로는 이미지 업로드 기능(클릭 업로드 방식과 Drag & Drop 방식, 다중 업로드)과 이미지 삭제와 이미지 검색 기능 구현하기였다. 추가 기능은 파일의 마지막 수정 시간을 화면에 출력하는 UI 구현하기였다. 여기에 과제의 완성도를 높이기 위해서 개인적인 챌린지로 파일명에 한글 또는 특수문자 포함된 파일 업로드 기능, 1MB 미만으로 이미지를 압축하는 기능, 다운로드 기능을 추가로 구현하였다. 과제 추가 구현 기능✅ 마지막 수정 시간 표시const { error: insertError } = await supabase.from(DB_TABLE_NAME).insert({ name: file.name, originalName: originalFileName, imageId: uploadedFile.id, imageUrl: publicUrl, createdAt: new Date(file.lastModified).toISOString(), })생성: DB에 파일 데이터 업로드 시 createdAt에 file.lastModified를 ISOString 형식으로 저장 if (dbData) { const { error: updateError } = await supabase .from(DB_TABLE_NAME) .update({ name: file.name, originalName: originalFileName, imageUrl: publicUrl, updatedAt: new Date().toISOString(), }) .eq('imageId', uploadedFile.id)수정: DB에 해당 ID가 존재할 경우 updatedAt(string | null)에 현재 시간을 ISOString 형식으로 저장// DropImageManager 컴포넌트에서 생성 시간, 수정 시간을 포멧팅하여 DropImage 컴포넌트에 프롭스로 전달 const localCreatedAt = getLocalTime(image.createdAt) const localUpdatedAt = image.updatedAt ? getLocalTime(image.updatedAt) : null <!-- JSX 정렬이 잘 안되서 렌더링 형태만 봐주세요! --> <div className="w-5/6 truncate"> <span className={`text-[0.7rem] font-semibold ${localUpdatedAt ? 'text-mint-800' : 'text-gray-500'}`} > {localUpdatedAt ? localUpdatedAt : localCreatedAt} </span> {localUpdatedAt && ( <span className="text-[0.7rem] font-semibold text-mint-800"> (수정)</span> )} </div>출력: updatedAt이 존재할 경우 updatedAt과 (수정) 을 함께 출력, updatedAt: null이라면 createdAt를 출력 개인 챌린지 기능✅ 파일명 자동 변환 후 이미지 업로드하는 기능을 구현 (UX 개선)파일명 검증: 정규식을 활용하여 한글 및 특수 문자 포함 여부를 확인자동 변환: 검증 후 8자리 랜덤 문자열로 안전한 파일명 생성업로드 처리: 변환된 파일명으로 File 객체 생성 후 formData.append로 원본 파일명 함께 전송서버 액션: Supabase Storage에 저장 후, 완료 시 DB에 메타데이터 저장하여 연동결론: 파일명 변환을 자동화하여 업로드 오류를 방지하고, 원본 파일명도 유지하여 검색 및 관리 UX 개선✅ 파일 용량이 1MB 초과 시 자동 압축 후 업로드하는 기능을 구현 (UX 개선)browser-image-compression 라이브러리를 사용하여 파일의 용량 검증 후 1MB 초과 시 이미지 압축 후 업로드결론: 이미지 최적화로 업로드 속도 향상, 스토리지 비용 절감 효과✅ Blob URL을 활용한 다운로드 기능 추가 (UX 개선)Blob URL 생성: 업로드된 이미지를 fetch()로 가져와 Blob으로 변환다운로드 기능 구현: window.URL.createObjectURL(blob)으로 브라우저에서 직접 다운로드 가능하도록 처리결론: Blob URL 다운로드 방식을 적용하여 최적화된 이미지를 빠르게 다운로드 받을 수 있도록 개선🚧 기능 구현 시 어려웠던 부분Supabase Storage에 전달하는 File 객체 커스텀 불가원본 파일명을 추가하려 했으나, File 객체 자체를 수정하는 것이 제한적이다.파일 객체를 복사하여 원본 파일명을 추가하는 방법 시도전개 연산자를 사용하여 객체 복사 후 원본 파일명을 추가하려 시도하였으나 file 객체는 일반적인 방법으로는 복사할 수 없는 특별한 객체이다.ExtendedFile 확장 클래스로 인스턴스를 생성했으나 서버에 전달되지 않는 문제 발생확장된 ExtendedFile 객체를 formData에 담아 서버로 전송했지만, 서버에 정상적으로 전달되지 않았다.최종 해결 방법formData.append("file", file) formData.append("originalFileName, file.name)file 객체와 원본 파일명을 함께 서버로 전송 후 가공하여 Supabase Storage의 파일명에는 안전한 파일명만 저장하고 DB에 스토리지Id, 원본 파일명, 안전한 파일명, 이미지URL 등 정보를 저장했다. 🧾 ERD 다이어그램👀 2주차 회고아직 갈 길이 멀지만, 리팩토링을 통해 Next.js의 장점을 살릴 수 있는 구조로 점점 개선되어가는 과정을 경험하면서 이번 주 역시 알차게 보냈다고 생각한다.이번 주는 특히 MVP 패턴과 비슷한 형태로 컴포넌트 구조를 잡는 것에 익숙해지는 것을 개인적인 목표로 삼았다. 처음부터 MVP 패턴을 염두해 두고 설계한 것은 아니었지만, 진행하다보니 자연스럽게 MVP와 유사한 패턴으로 정리되어 가는 것을 느꼈다.화면 렌더링 시 상호작용이 필요하지 않은 정적인 요소들까지 클라이언트 컴포넌트로 관리하면 불필요한 하이드레이션 부담이 증가할 수 있다는 점을 다시 한번 체감했다.클라이언트 컴포넌트 내에서도 역할을 나눠 서비스 레이어나 상태 관리만 담당하는 매니져 컴포넌트와 프롭스로 상태를 전달받아 단순히 화면을 렌더링을 담당하는 UI 컴포넌트로 분리하는 연습을 진행했다.이러한 구조로 개선하면서 클라이언트 컴포넌트의 부담을 줄이고, 유지보수성을 높이는 방향으로 점차 최적화되고 있다는 점이 느껴졌다. 아직 개선해야 할 부분이 많지만 점진적으로 개선하여 더 나은 아키텍쳐를 만들어가는 과정이 의미 있었다고 생각한다.

풀스택워밍업클럽3기발자국회고과제미션

인프런 비즈니스 시작하기 STEP 5

인프런 비즈니스 고객사는 기업 맞춤형 교육을 지원하기 위해 관리자 페이지를 무상으로 제공합니다. 매뉴얼 가이드를 따라 기업에 최적화된 교육 운영 환경을 쉽고 빠르게 구축해보세요. 교육 담당자는 운영 부담을 줄이고, 학습자는 체계적인 환경에서 자율적으로 학습할 수 있습니다. 인프런 비즈니스 시작하기 STEP 501. 인프런 비즈니스 서비스 가입하기02. 결제 수단 등록하기03. 지원 강의 설정하기04. 멤버 등록하기05. 기타 운영 설정 요청하기 01. 인프런 비즈니스 서비스 가입하기인프런 비즈니스 서비스는 별도 비용 없이 바로 가입할 수 있습니다. 인프런 계정만 있으면 가입과 동시에 새로운 그룹이 생성되고, 관리자 페이지가 제공됩니다.[1단계] 인프런 회원 가입(링크) 인프런 회원가입 : https://www.inflearn.com/user/signup비즈니스 서비스 가입을 위해 인프런 계정이 필요합니다.해당 계정은 기본 관리자로 등록됩니다. (추후 수정 및 추가 가능)[2단계] 인프런 비즈니스 서비스 가입(링크) 인프런 비즈니스 : https://www.inflearn.com/intro-group로그인 후, 인프런 비즈니스 홈에서 [시작하기] 버튼을 눌러 가입을 시작합니다.이용 약관에 동의하고, 회사 및 담당자 정보를 입력한 뒤 제출합니다.[3단계] 관리자 페이지 확인가입 완료 후, 인프런 홈페이지 우측 상단에 [비즈니스] 버튼이 나타납니다.정상적으로 관리자 페이지에 접근할 수 있는지 확인해주세요. 02. 결제 수단 등록하기결제 수단을 등록하면 관리자 페이지의 기능이 활성화됩니다. 인프런 비즈니스 서비스는 후불정산과 선불충전 중 선택할 수 있으며, 기업에 적합한 방식으로 등록해주세요.[1단계] 결제 수단 등록 안내 클릭관리자 페이지 상단에 "결제 수단을 등록해주세요"라는 노란색 배너 알림이 표시됩니다.우측의 [등록하기] 버튼을 클릭합니다.[2단계] 결제 방식 및 수단 선택후불정산 : 카드결제 또는 무통장입금(세금계산서 발행) 방식으로 결제할 수 있습니다. 선불충전 : 무통장입금 방식으로 예치금을 미리 충전한 후, 수강 금액에서 차감됩니다.[3단계] 카드정보 / 세금계산서 수신 이메일 입력카드 결제 시 : 카드 정보를 입력해주세요.무통장 입금 시 : 세금계산서 수신 이메일을 입력해주세요.(** 참고) 후불정산은 월 단위로 진행됩니다.수강 내역 발송 : 익월 2영업일 내후불 결제 진행 : 수강 내역 확인 후, 이상 없을 시 6영업일 이내 / 매월 10일 이전(** 참고) 선불충전 방식 이용 시 사전 문의가 필요합니다.결제 수단 등록 → 예치금 충전 문의 → 세금계산서 발행 및 입금확인 → 예치금 충전 완료 → 자동 정산문의: group@inflab.com 03. 지원 강의 설정하기교육에 필요한 강의를 설정하세요. 지원 강의 선택은 총 3단계로 진행되며, 임직원의 IT 역량 강화 목표에 맞춰 구성할 수 있습니다. 지원 범위 내에서 임직원들은 자유롭게 수강 신청하고 학습할 수 있습니다.[1단계] 가격 및 카테고리 설정강의 1개당 최대 가격을 지정할 수 있으며, 초과 시 미지원 강의로 자동 분류됩니다.카테고리별 지원 여부를 설정할 수 있으며, 하위 카테고리도 선택적으로 지정할 수 있습니다.[2단계] 필수/제외 강의 설정반드시 지원해야 하는 강의 또는 제외할 강의를 선택합니다.1단계 카테고리 설정과 별도로 지원/미지원 강의를 추가로 지정할 수 있습니다.[3단계] 최종 지원 강의 확인1단계와 2단계에서 설정한 내용을 반영한 최종 강의 목록을 확인합니다.[최종 선택 강의 목록 다운로드] 기능을 활용해 쉽게 확인할 수 있습니다.(** 참고) 미지원 강의 설정미지원 강의는 개인 결제로 수강할 수 있도록 설정할 수 있습니다.또는, 홈페이지에서 아예 노출되지 않도록 설정할 수도 있습니다.  04. 멤버 등록하기인프런 비즈니스 서비스에 구성원을 멤버로 등록해주세요. 기업 이메일을 활용하면 멤버 등록과 관리가 더욱 간편하며, 등록 즉시 자동 이메일 안내가 발송되어 학습을 빠르게 시작할 수 있습니다.1. 멤버 일괄 등록하기좌측 상단의 [리스트 다운] 버튼을 클릭하여 .csv 파일을 다운로드합니다.새롭게 등록할 멤버 정보를 파일에 입력합니다.원활한 관리를 위해 정확한 정보 입력을 권장드립니다. (** 필수 항목: 사번/학번, 이메일, 이름)[리스트 업로드] 버튼을 클릭하여 멤버 일괄 등록을 완료해주세요.(** 주의) 리스트 업로드 시 기존 명단이 교체됩니다. 기존 멤버에 새로운 멤버를 추가하려면, 기존 명단 아래 새로운 멤버 정보를 추가 입력한 후 업로드하세요.2. 멤버 개별 등록하기우측 상단의 [멤버 추가] 버튼을 클릭하여 개별 멤버를 등록할 수 있습니다.원활한 관리를 위해 정확한 정보 입력을 권장드립니다. (** 필수 항목: 사번/학번, 이메일, 이름) (** 참고) 멤버 등록 시 멤버 상태는 인프런 회원가입 여부에 따라 인증/미인증으로 구분됩니다.인증: 회원가입이 완료된 상태로 수강 신청 가능함. 멤버 등록 즉시 가입 완료 메일 발송되며, 학습 시작 안내 포함됨. 미인증: 회원가입이 완료되지 않은 상태로 비밀번호 설정 후 수강 신청 가능함. 등록 시 비밀번호 설정 안내 메일 발송되며, 설정 완료 시 상태가 '인증'으로 변경됨.  05. 기타 운영 설정 요청하기인프런 비즈니스 관리자에서 제공되는 기능 외에도, 인프런 어드민을 통해 기업 맞춤형 교육 환경을 구축할 수 있습니다. 필요한 설정이 있다면, 언제든 인프런 매니저에게 요청해주세요.1. 서비스 이용 기간수강 신청이 가능한 서비스 이용 기간을 설정할 수 있습니다.예를 들어, 연 단위로 교육을 운영하는 경우 1월 1일부터 12월 31일까지로 설정하고, 인당 수강 한도를 함께 지정하면 해당 기간 동안 정해진 범위 내에서 학습을 진행할 수 있습니다.2. 수강신청 기간수강 신청 기간을 매월 특정 기간(n일부터 n일까지)으로 설정할 수 있습니다.보통 수강 신청 기간을 운영할 경우, 관리자 승인 단계를 추가하고, 정해진 날짜에 교육을 시작합니다.(예시) 매월 1일 ~ 10일 수강 신청 > 11일 관리자 일괄 승인/반려 처리 > 15일 교육 시작3. 수강 승인 방식수강 승인 방식은 자동 승인과 수동 승인 중 선택할 수 있습니다.자동 승인: 학습자가 수강 신청하면 즉시 강의를 시청할 수 있습니다.수동 승인: 관리자가 수강 신청 내역을 검토한 후 승인 또는 반려할 수 있습니다.4. 1인당 수강 한도 설정 (금액, 개수)학습자가 신청할 수 있는 최대 금액과 유료 강의 개수를 설정할 수 있습니다.기업은 예산 범위 내에서 교육을 운영할 수 있으며, 학습자는 지원 한도 내에서 자유롭게 학습을 진행할 수 있습니다.일반적으로 서비스 이용 기간을 설정할 경우, 수강 한도도 함께 설정합니다5. 미지원 강의 구매 및 노출 여부기업이 지원하지 않는 강의에 대해 개인 구매 허용 여부 및 홈페이지 노출 여부를 설정할 수 있습니다.기본 설정에서는 미지원 강의도 홈페이지에 함께 노출되며, 학습자가 신청 시 개인 결제로 진행됩니다. 직원이 성장하고, 조직이 성공하는 인프런 비즈니스🔗 인프런 비즈니스 홈페이지🔗 인프런 비즈니스 콘텐츠  우리는 성장 기회의 평등을 추구합니다.©인프랩 | 경기도 성남시 분당구 판교로289번길 20, 3동 5F©InfLab. All rights reserved.

인프런비즈니스

lkwo

워밍업 클럼 3기 BE 클린코드 1주차 발자국

1주차를 마무리하며...업무와 같이 할 수 있겠지 싶었는데, 강의의 내용이 알차서 생각보다 힘들었습니다.코드를 따라치며 수강했지만... 사실 제대로 이해 못하고 따라만 친 부분도 상당히 있었는데,다시 내가 직접 리펙터링 해가며 따라가야지 다짐을 하며 1주차 발자국을 남깁니다.강의 정리클린코드란 무엇인가라는 질문으로부터 강의가 시작됩니다.좋은 코드란 무엇일까요?저는 강의의 내용을 듣고 이렇게 정리했습니다.좋은 글과 마찬가지로 클린코드는 잘 읽히는 코드한 문장 한 문장에 주제가 또렷해 전달하고자 하는 내용을 읽는 이에게 정확하게 전달하는 코드강의에서 중간중간에 선조와 후손이라는 용어를 사용하십니다. 내가 쓰는 코드가 꼭 내것만은 아니라는 점을 계속 상기시켜주시면서, 공용의 코드를 어떻게 다뤄야할지는 말씀해주시는게 많이 도움이 될 것 같습니다.추상화추상이란 '사물을 정확하게 이해하기 위해서 사물이 지니고 있는 여러 가지 측면 가운데서 특정한 측면만 가려내어 포착하는 것'을 말합니다.'비가온다' 라는 표현을 '대기내에 수증기가 응결하여 물방울로 변하고, 이 물방울이 중력에 의해서 지표면으로 떨어진다'라고 친구한테 말하면 갸우뚱할 것입니다.이처럼 추상은 중요한 정보만 남겨 전달함으로써 상대방의 이해를 돕는 기능을 하는걸 실생활에서도 볼 수 있습니다.코드에서의 추상화그러면 코드에서는 어떻게 중요한 내용만 가려내고, 구체적인 내용은 숨겨 읽는 이의 이해를 도울 수 있을까요?강의에서 나온 내용들 중 기억에 남는 방법들을 나열해봅니다.코드 블럭내에서 추상화 레벨을 통일하기객체에 적절한 역할과 책임을 부여하고 메시지를 통한 협력을 하는 구조로 만들기SOLID 원칙을 생각해가며 코드를 작성하기객체지향의 다양한 기법을 활용하기상속과 조합Value Object컬렉션으로 포장한 일급컬렉션 사용하기Enum다형성  그리고 읽는 사람을 배려한 다양한 코드 작성법을 나열해봅니다.변수, 메서드 추상화를 통해 이름 짓기매직 넘버, 매직 스트링 상수화하기공백 라인 활용해 블럭내 코드 분간해주기조건문에 부정어 연산자 `!`줄이기

백엔드클린코드

codemod

내 블렌더 실력은 어느 정도일까?- 코드모드의 친절한 블렌더 레벨테스트!

안녕하세요. 코드모드입니다! :)제가 단계별로 차근차근 원리와 개념을 친절하게 알려주는 친절한 블렌더 시리즈 강의를 진행하고 있는데요.​​이 친절한 블렌더 강의는블렌더를 시작한 지 얼마 안 되었거나, 기초부터 제대로 배워보고 싶으신 분들,다른 튜토리얼을 따라하는데 버전이 다르면 어렵게 느껴지는 분들,또는 여러 개의 작업을 따라하는 건 잘 되는데 막상 내가 원하는 걸 만들려고 할 때 어려움을 겪는 분들을 위한 강의입니다. 지금까지 Lv.0부터 Lv.3까지 총 4편을 만들었는데요. (다음 강의도 준비 중이에요!)이 중에 자기가 어떤 걸 들어야 할 지 모르겠다는 분들을 위해 레벨테스트를 만들어 봤어요.친절한 블렌더 강의를 듣지 않더라도, 이미 들었더라도 자신의 실력을 확인하기 위해 가볍게 한 번 풀어보시면 재밌을 것 같아요!또한 강의를 수강하시려는 분들에게는 선택하시는데 도움이 될 것 같아요.​총 16문제이고 종이를 준비해서 적으면서 풀어보시고 마지막에 답도 맞춰보고 결과도 확인해보세요.​끝! 아래로 내려가면 답안지가 나옵니다!​​​​​​​​​​​​​​​​​​ 테스트 내용은 Lv.0과 Lv.1에 나오는 내용으로 만들었습니다.주관식 문제가 아니다 보니 찍어서 맞췄는지, 알고 풀어서 맞췄는지는 본인이 제일 잘 아실거예요.​​16문제 중 13문제가 Lv.0에 나오는 내용이기도 해서 결과가 Lv.1이 나오셨더라도 부족한 부분이 있다고 생각된다면 Lv.0부터 들으시길 권장드려요.Lv.0이 너무 쉽게 느껴지면 따라하지 않고 가볍게 들으시기만 해도 얻어가는 부분들은 클 꺼라고 생각됩니다.점수도 좋지만 자신에게 어떤 개념이 부족한 지 확인하는 시간으로 생각해주세요.그리고 댓글로 레벨테스트에 대한 의견이나 어떤 문제가 어려웠는 지, 몇 문제 맞췄는 지 등을 자유롭게 남겨주세요. ​저랑 같이 재밌는 블렌더 합시다! :)

CAD · 3D 모델링블렌더블랜더blenderblender3d레벨테스트시험지친절한블렌더

Masocampus

[마소캠퍼스 GEN AI 인사이트] 트럼프 관세폭탄, 한국 산업은 얼마나 흔들렸을까?

“눈부신 기술의 발전 뒤에는, 우리가 반드시 짚고 넘어가야 할 문제가 있습니다.”생성 AI가 만들어내는 놀라운 결과물들, 정말 감탄스럽죠? ✨하지만 그 화려한 성과 뒤에는 창작물 무단 사용이라는 무거운 그림자가 드리워져 있어요.이제는 기술의 힘만큼, 공정과 윤리에 대한 고민도 함께 키워야 할 때입니다.AI 시대, 우리는 어떤 선택을 해야 할까요? 함께 고민해봐요! 😊AI 모델들이 학습하는 데 사용된 데이터 중 상당수가 출처를 명확히 밝히지 않은 경우가 많아요.특히 웹 스크래핑을 통해 수집된 데이터에는 저작권이 있는 콘텐츠도 포함되어 있습니다. 😥조사에 따르면 64%가 Common Crawl 데이터를 사용했지만, 21%는 출처조차 밝히지 않았어요.’무허가 훈련’이 업계 표준처럼 되어버린 지금, 과연 이것이 올바른 방향일까요?“앞으로 AI 음악만 쓸 거야!” 영화 제작자 Ram Gopal Varma의 말처럼, AI가 창작 영역을 대체하기 시작했어요.예술가 Kelly McKernan은 “AI 이미지 때문에 수입이 33% 감소했다”고 호소했죠.창작자들의 생계가 위협받고 있다는 사실, 그냥 지나칠 수 없어요.기술이 발전할수록 사람들의 권리도 함께 지켜져야 해요.AI 기업들은 ‘공정 사용’이라는 법적 개념을 내세우며 자신들의 입장을 정당화하려 하지만,창작자들은 “정당한 대가 없는 사용은 절대 받아들일 수 없다”며 강력히 반대하고 있어요.현재 진행 중인 소송만 30건 이상!결론은 쉽게 나지 않을 것 같지만, 이 대화는 반드시 필요합니다.몇몇 AI 기업들은 책임 있는 방향으로 나아가기 시작했어요.Stability AI는 음악 모델 훈련을 위해 정식 라이선스를 사용하고 있고,Fairly Trained는 무허가 훈련 없는 기업을 인증하는 시스템을 마련했어요. 🏆라이선스 체계는 창작자와 AI 모두를 보호하는 열쇠가 될 수 있습니다.창작자들은 외치고 있어요.“AI 훈련 데이터는 정당한 비용을 지불해야 해요!”모든 AI 기업이 라이선스 체계를 도입한다면, 창작자의 권리를 보호하면서도 AI 기술 발전을 이룰 수 있어요.상생의 길, 우리 함께 만들어야 해요. 🌱많은 웹사이트들이 AI 훈련용 데이터 제공을 막기 시작했어요.설문조사 결과, 대중도 공개 데이터 사용에 대해 부정적인 인식을 갖고 있다는 사실!AI가 더 크게 발전하려면, 신뢰를 얻는 것이 필수입니다.창작물의 가치를 인정하고 보호하는 것, 그것이 진짜 혁신을 위한 첫걸음이에요. 😃한눈에 보면, 생성 AI 산업은 ‘무허가 훈련’이라는 불편한 진실을 마주하게 됐습니다.기술이 빠르게 발전한다고 해서 모두가 행복해지는 건 아니었어요.창작자들은 생계의 위협을 느끼고 있고, 기업들은 ‘공정 사용’을 외치며 논란에 휩싸였죠.이번 사례를 통해 기술 발전이 가져올 긍정적인 변화뿐만 아니라, 공정성과 윤리에 대한 고민도 반드시 함께해야 한다는 점을 알 수 있어요.앞으로 AI 생태계도 모두가 존중받을 수 있도록, 더욱 신중하고 책임 있는 접근이 필요합니다. 🙂   마소캠퍼스와 함께 AI를 활용해 업무 혁신을 이뤄보세요!효율적이고 스마트한 일의 방식을 통해 성장할 수 있도록 도와드릴게요.📌 관련 강의 <회사가 원하는 효율적인 AI 활용 – 회의 준비부터 기록까지>회의 준비부터 회의록 작성까지, AI가 다 해드립니다! 반복 업무는 자동화하고, 중요한 일에 집중하세요.

AI 업무 활용ai윤리저작권저작권보호생성ai라이선스ai창작디지털윤리ai트렌드ai미래마소캠퍼스

윤성용

제품화된 서비스 (Productized Service)

안녕하세요, 라이프스타일에 크게 관여하는 플랫폼 사업을 하고 싶은 윤성용입니다.오늘은 'Productized Service'에 대한 이야기 나눠 볼려고 합니다. 그렇다면 '제품화된 서비스'란 무엇일까요?오늘 글에서 서비스란 용역 서비스를 뜻하는데요. 특히 개발이나 디자인 분야 프리랜서 분들이 해당 될 것 입니다. 단순히 포트폴리오가 더 많다고 더 많은 고객을 유치하고 더 많은 수익을 창출 할 수 있을까요? 저는 그렇게 생각하지 않습니다. 물론 어느정도의 포트폴리오는 도움이 되지만 포트폴리오나 그 회사에 대한 작은 믿음 만으로 또한 계약 당시의 좋은 관계 만으로 용역을 온전하게 제공하고 대금을 온전하게 받는것은 쉽지 않습니다. 또한 프리랜서 생활은 규칙적이지 않고 이로인한 다양한 스트레스를 야기합니다. 이런 문제를 해결하는데 제품화된 서비스는 도움이 됩니다. 제품화된 서비스는 상품처럼 서비스 모델을 만들어서 시간별 또는 프로젝트별로 청구하는것이 아닌 서비스 시트 별로 구독 형태로 청구하는 것입니다. 구독 형태이면 고객이 시키는 일이 무제한 인가요?아닙니다. 물론 국내에서 디자인 구독 서비스를 중심으로 99만원 가량에 무제한으로 디자인을 제공 해준다는 구독 서비스가 있기도 하지만 우리보다 먼저 제품화된 서비스가 등장한 해외에서는 일을 처리하는 빈도 및 업무 강도에 따라서 보통 단계를 나누어서 구독료를 받습니다. 간단한 작업 시키기 ~ 복잡한 개발 이런식으로요. 물론 꽤나 많은 서비스가 무제한이라는 단어를 사용하지만 실제로는 동시 작업에 한도가 있게 계약하는 경우가 대부분입니다. 연매출 16억원 1인 디자인 기업 'Designjoy'제품화된 서비스 분야에서 제가 가장 잘하고 있다고 생각하는 서비스입니다. 실제 창업자가 트위터에 올린 지출 내역인데요. 물론 개인적인 지출도 있겠지만 사업과 관련된 정기적인 지출은 이정도라고 합니다. 피그마와 웹플로우를 가장 잘 활용하는 사례중 하나이지 않을까요? 발행인 소개안녕하세요! 윤성용입니다. 다수 기술 창업에 참여했습니다. 인디게임을 개발하고 출시하여 수만명의 유저를 만나고 다양한 플랫폼 비즈니스를 만들었습니다. 최근에는 제품화된 서비스 그리고 B2B SaaS에 집중하고 있습니다. 제품화된 서비스를 제공하는 1인 기업으로서 조금은 느리지만 건강한 성장을 하고 있습니다.강남디벨로퍼스 주식회사 대표이사문의 : seongyong@gdev.kr

그래픽 디자인디자인프리랜서제품화된서비스

윤성용

프리랜서! 개인사업자? 3.3% 사업소득?

안녕하세요, 프리랜서 개발자 윤성용입니다.오늘은 프리랜서! 개인사업자? 3.3% 사업소득? 이라는 타이틀로 준비했습니다.프리랜서 한다고 하면 어떤 유형이 유리할지 비교 해보겠습니다.먼저 결론부터 말하자면 3.3% 사업소득이나 채용 되는걸 추천드립니다.이유는 간단합니다. 개인사업자로서 계약을 하고 프리랜서를 하게 되면 돈을 못받게 되는 경우 일명 대금을 떼이는 경우에 도움을 전혀 받을 수 없습니다. 특수한 경우를 제외하고는 개인사업자로서 용역 계약을 체결한 경우 대금 지급이 늦어지거나 지급을 고객사에서 거부하더라도 받을 가능성은 민사 소송 말곤 없습니다. 이건 실제 제 경험입니다. 오늘도 개발이 거의 끝나가던 프로젝트의 일방적 계약해지 통보를 받고 중도금도 못받고 소송을 준비하고 있는데 정말 한숨이 나옵니다. 3.3% 사업소득이나 채용되어 일을 할경우 임금체불 등으로 신고가 가능하고 개인사업자 대비 민사소송 외에도 돈을 받을 수 있는 장치나 방법들이 많습니다.한국에서는 수백만원 수천만원 용역 계약을 하고 돈을 지급하지 않아도 형사 처벌은 사실상 없는 수준입니다. 그렇기에 민사 소송 만으로 내 억울함을 증명하고 돈을 받아야 하는데 또 소송을 이긴다고 돈을 무조건 받을 수 있는게 보장되는것도 아닙니다. 임금체불이 인정되면 노동채권을 통해서 못 받은 돈 떼인돈 일부분 이라도 우선적으로 받을 수 있는 근로자가 답입니다!!!오늘 글은 경험에서 우러나온 내용입니다. 참고 바랍니다. 감사합니다. 발행인 소개안녕하세요! 윤성용입니다. 다수 기술 창업에 참여했습니다. 인디게임을 개발하고 출시하여 수만명의 유저를 만나고 다양한 플랫폼 비즈니스를 만들었습니다. 최근에는 제품화된 서비스 그리고 B2B SaaS에 집중하고 있습니다. 제품화된 서비스를 제공하는 1인 기업으로서 조금은 느리지만 건강한 성장을 하고 있습니다.강남디벨로퍼스 주식회사 대표이사문의 : seongyong@gdev.kr

창업 · 부업프리랜서개인사업자

suover

인프런 워밍업 클럽 스터디 3기 - 백엔드 클린 코드, 테스트 코드 후기

Readable Code: 읽기 좋은 코드를 작성하는 사고법Practical Testing: 실용적인 테스트 가이드강의와 함께한 인프런 워밍업 클럽 스터디 3기 - 백엔드 클린 코드, 테스트 코드 (Java, Spring Boot) 후기 입니다.소개이번 스터디 3기는 백엔드 클린 코드, 테스트 코드를 주제로 진행하였습니다. “Readable Code: 읽기 좋은 코드를 작성하는 사고법”과 “Practical Testing: 실용적인 테스트 가이드” 강의를 함께 학습함으로써, 더 나은 코드 가독성과 안정적인 테스트를 위한 다양한 방법론을 실습할 수 있었습니다.지난 2기 때 Kotlin과 Spring Boot로 백엔드 개발 전반을 경험하며 웹 애플리케이션 동작 원리를 학습했다면, 이번 3기에서는 코드 품질과 테스트라는 핵심 주제를 깊이 파고들어, 보다 깨끗하고 유지보수하기 좋은 코드, 그리고 신뢰도 높은 테스트 코드를 작성하는 법을 익혔습니다.아래에서는 각 주차별 학습 내용을 정리하고, 전체 스터디를 통해 느낀 점과 앞으로의 계획을 공유하고자 합니다. 1주차: 클린 코드를 위한 기초 - 추상과 구체, SOLID 원칙1주차 주요 학습 내용추상과 구체의 개념논리와 사고의 흐름SOLID 원칙 (SRP, OCP, LSP, ISP, DIP)리팩토링 미션 수행1주차에서는 코드 가독성을 높이는 가장 기본이 되는 개념들을 배웠습니다. 특히 추상과 구체의 균형을 어떻게 잡아야 코드가 명확해지고, 협업자가 빠르게 이해할 수 있는지 고민할 수 있었습니다.추상은 핵심 개념과 의도만 드러내도록 하는 장점이 있지만, 너무 과도하면 실제 구현과 괴리가 생겨 혼란을 줄 수 있다는 점을 배웠습니다.구체는 세세한 내용을 모두 표현해 직관적이지만, 과도해지면 복잡해지고 가독성이 떨어질 수 있으므로 주의가 필요했습니다.또한 Early Return이나 부정어 최소화 같은 리팩토링 기법을 적용해 보면서, 간단한 습관만으로도 코드의 가독성이 크게 높아진다는 점을 실감했습니다. 2주차: 코드 구조 및 리팩토링 - 패키지 구조, 주석, 적정 기술2주차 주요 학습 내용효과적인 주석 사용 방식변수와 메서드의 나열 순서패키지 구조 설계와 적정 기술(Over Engineering 지양)스터디카페 이용권 시스템 리팩토링2주차에서는 코드 구조 전반을 깔끔하게 정비하는 방법을 중심으로 학습했습니다.주석은 변동이 잦거나 오해를 일으킬 만한 내용을 담지 말고, 정말 필요할 때만 사용해야 한다는 것을 다시금 확인했습니다.변수와 메서드를 사용하는 순서대로 배치하고, 공개 메서드(public) → 비공개 메서드(private) 순서로 자연스럽게 구성함으로써, 읽는 흐름을 방해하지 않는 것이 중요하다는 점을 배웠습니다.특히 리팩토링 미션을 통해 패키지 구조가 지나치게 단순하거나, 반대로 너무 세분화되어 관리가 어렵지 않은지 돌아볼 수 있었습니다. 적정 기술을 사용하는 태도. 즉, 문제를 해결하는 데 필요한 만큼만 기술 스택과 디자인 패턴을 적용하는 것이 얼마나 중요한지도 체감하게 되었습니다. 3주차: Spring & JPA, 계층형 아키텍처, 통합 테스트3주차 주요 학습 내용Spring & JPA를 이용한 계층형 아키텍처 (Controller, Service, Repository)단위 테스트와 통합 테스트의 차이점 및 작성 방법MockMvc, @DataJpaTest 등을 활용한 테스트 실습Bean Validation과 ExceptionHandler로 유효성 검증 및 예외 처리3주차부터는 실무에서 흔히 쓰이는 Spring & JPA 기반의 계층형 아키텍처에 초점을 맞춰, 전체적인 흐름을 학습했습니다.Layered ArchitecturePresentation Layer(Controller)Business Layer(Service)Persistence Layer(Repository)이러한 구조를 바탕으로, MockMvc를 사용해 Controller부터 Service, Repository까지 이어지는 통합 테스트를 작성해 봄으로써, 애플리케이션 전반이 정상 동작하는지 확인할 수 있었습니다.또한 @NotNull, @Positive 등 Bean Validation 애너테이션과 @RestControllerAdvice를 통한 예외 처리 방식도 연습해보았습니다. 4주차: Mock, Spy, @MockBean / @SpyBean, 레이어별 테스트 전략4주차 주요 학습 내용Mockito에서의 @Mock, @Spy, @InjectMocks스프링 환경에서의 @MockBean, @SpyBean레이어별 테스트 설계: 단위 테스트 vs 통합 테스트테스트 시나리오 설계(given-when-then)와 @BeforeEach 활용마지막 주차에서는 테스트 유지보수와 테스트 코드 설계의 중요성을 배웠습니다.@Mock, @Spy를 통해 순수 단위 테스트 환경에서 외부 의존성을 제거(또는 부분 제거)하여 빠른 피드백을 받을 수 있었습니다.반면 @MockBean, @SpyBean은 스프링 애플리케이션 컨텍스트를 띄운 상태에서 기존 Bean을 모의 객체로 교체할 수 있어, 좀 더 넓은 범위의 통합 테스트에 활용할 수 있었습니다.레이어별 테스트 (Controller, Service, Repository)를 분리해 진행하면 테스트가 더욱 명확해지고, 문제 발생 시 어느 레이어가 원인인지 빠르게 파악할 수 있음을 깨달았습니다.가장 크게 느낀 점은 ‘테스트도 코드의 일부’라는 사실이었습니다. 테스트 코드를 지속적으로 관리하고 개선해야, 유지보수가 필요한 시점에 믿을 수 있는 안전망이 되어준다는 것을 명확히 알게 되었습니다.회고이번 스터디 3기를 통해 "클린 코드와 테스트"라는 주제의 중요성을 다시 한번 실감했습니다. 단순히 기능만 구현하는 것이 아닌, 가독성, 유지보수성, 테스트 커버리지까지 고려해야 진정한 의미의 소프트웨어 품질을 높일 수 있음을 배웠습니다.아쉬웠던 점 & 보완 계획실프로젝트 적용: 강의와 미션 중심의 학습이기에, 실제 현업 수준의 복잡도를 가진 코드에 적용할 기회가 많지 않았습니다. 앞으로 개인/팀 프로젝트에서 적극 활용해 경험치를 높이고자 합니다.테스트 시나리오 다양성: 해피 케이스 중심의 테스트가 많았기에, 예외 상황과 경계값 테스트를 더 폭넓게 다루면 좋았을 것 같습니다. 마무리인프런 워밍업 클럽 스터디 3기를 통해, 클린 코드와 테스트 코드 작성 역량을 크게 향상시킬 수 있었습니다.코드: 명료한 이름 짓기, 중복 제거, 적절한 추상화 등을 통해 읽기 좋고 변화에 강한 코드를 추구하게 되었습니다.테스트: 프로젝트가 확장되더라도, 안정성을 확보할 수 있는 테스트 설계가 얼마나 중요한지 다시금 느끼게 되었습니다. 이번 스터디에서 성실히 참여한 결과, 2기에 이어 3기에서도 우수러너로 선정되는 영광도 누릴 수 있었습니다. 앞으로도 스스로 레거시 코드를 리팩토링하거나, 프로젝트를 확장하면서 배운 내용을 꾸준히 적용할 것입니다. 스터디에서 함께한 분들, 그리고 인프런과 워밍업 클럽 관계자분들께 감사드리며, 지속적인 학습과 공유를 통해 더 나은 개발자가 되도록 노력하겠습니다. 감사합니다!

백엔드인프런인프런워밍업클럽스터디3기워밍업백엔드후기클린테스트코드

leeebug

워밍업 클럽 스터디 3기 FS - 스터디 후기

워밍업 클럽을 처음 알게 된 건 사실 이번 3기가 아니라 지난 2기 때였다.당시에도 이 스터디에 흥미가 있었지만 개인적인 사유로 아쉽게도 참여하지 못했는데, 이번 3기에 Next.js 과정이 포함되었다는 소식을 듣고 주저 없이 참여 신청했다.결과적으로는 아주 만족스러운 선택이었다. SLL 회고Startany를 배제하고, 모든 컴포넌트에 명시적 타입 선언을 적용해보았다.단일 책임 원칙을 기반으로, UI와 비즈니스 로직을 분리하는 컴포넌트 구조화를 시도해보았다.클라이언트와 서버 상태를 별도로 관리하기 위해서 React Query를 도입해보았다.Zod + React Hook Form 조합을 처음 적용해보면서 스키마 기반 유효성 검증의 흐름을 경험해보았다.LearnUI와 비즈니스 로직을 분리하는 패턴은 가독성 향상에는 도움이 되었지만, 반대로 전체적인 복잡도가 증가할 수 있다는 점도 느꼈다.Next.js 환경에서는 SWR보다 React Query가 더 세밀한 제어와 상태 관리에 적합하다는 것을 체감했다.기능을 직접 구현하는것도 충분히 의미가 있지만, 이미 검증된 라이브러리를 적절히 도입하는 것이 생산성 측면이나 유지보수 측면에서 더 큰 도움이 될 수 있다는 점을 배웠다.Love타입 설계와 컴포넌트 구조를 직접 개선해본 경험 자체만으로 코드에 대한 자신감과 설계 감각이 향상되었음을 체감했다.주차별 다른 주제의 과제를 만들어가는 과정을 통해서 작은 성공의 중요성을 다시 한 번 느낄 수 있었다.  마무리짧다면 짧은 4주의 기간동안 매주 스스로 도전하고 개선해가는 과정을 통해 한 걸음 더 성장할 수 있었다고 느꼈다.혹시나 아직도 워밍업 클럽 참여를 망설이고 있다면 꼭 한 번 경험해보길 추천하며 스터디 회고를 마친다.

풀스택인프런인프런워밍업클럽스터디3기

Masocampus

[마소캠퍼스 GEN AI 인사이트] 트럼프 관세폭탄, 한국 산업은 얼마나 흔들렸을까?

이제 관세 하나가 나라 경제를 뒤흔드는 시대예요! 🌍트럼프 정부의 ‘관세폭탄’은 단순한 무역 조치가 아닌, 산업 전반에 영향을 주는 강력한 변수였어요.특히 한국은 자동차, 반도체, 철강 등 주력 수출 산업이 직접적인 타격을 받으며 큰 혼란을 겪었죠. 👉 더 자세한 분석과 수치는 아래 링크에서 보고서를 무료로 다운로드받을 수 있어요!📥 트럼프 관세 정책과 한국 산업 영향 보고서 보기 1. 40p 워드로 정리된 문서 보고서2. 30p PPT 정리된 프레젠테이션 보고서 단기적인 기회도 있었지만, 장기적으로는 더 큰 리스크가 숨어 있었던 이번 사례!글로벌 정책 변화가 우리 산업에 어떤 파장을 일으켰는지, 함께 들여다볼까요?✨트럼프 전 대통령은 ‘미국 제조업 살리기’를 목표로 해외 제품에 높은 관세를 매기기 시작했어요.그 핵심 키워드는 ‘America First’였죠.이 정책의 배경에는 무역적자 해소, 제조업 부활, 그리고 '공정무역'이라는 명분이 있었답니다.하지만 그 여파는 글로벌 경제 전체로 퍼져나가게 되었어요.트럼프 정부는 두 가지 방식으로 관세를 부과했어요.상호관세: 상대국이 미국에 부과하는 만큼 미국도 같은 비율로 부과!→ 한국엔 무려 25%가 부과되어 일본(24%), EU(20%)보다 높았어요.보편관세: 모든 나라에 공통적으로 적용되는 기본 관세로 철강, 자동차, 반도체 등이 대상이었죠. 이로 인해 한국 수출 기업들은 치열한 경쟁 환경에 놓이게 되었어요.한국 자동차 산업은 큰 타격을 받았어요.미국으로 수출되는 차량과 부품에 25%의 관세가 부과되었고,그 결과 한국 자동차 브랜드의 시장 점유율은 3.2%에서 1.8%까지 하락할 것으로 예상되었어요.차량 가격이 오르며 소비자 구매력도 줄어들었죠. 현대차와 기아차는 이런 위기를 극복하기 위해 미국 내 생산 공장을 더욱 확대했어요.반도체 산업은 조금 복잡한 상황이에요.중국산 제품을 대체하려는 미국의 수요가 늘어나며 단기적으로는 기회였지만,공급망 재편과 생산비 증가, TSMC와의 경쟁 심화 등으로 장기적인 불확실성이 커졌어요. 삼성과 SK하이닉스는 미국 반도체 정책에 발맞춰 수혜를 입었지만, 장기적으로는 고민이 필요하겠죠.철강산업 역시 관세 25% 부과의 영향을 피하지 못했어요.대미 수출량은 10.6% 감소했고, 생산비 압박은 자동차 및 가전제품 가격 인상으로 이어졌죠. 이에 따라 포스코, 현대제철은 미국 내 생산 설비 신설까지 고려하게 되었어요.한눈에 보면, 한국 산업은 트럼프의 관세폭탄 앞에 크게 흔들렸습니다.수출이 많다고 해서 안심할 수 없고, 단기적 기회도 장기적으론 리스크가 될 수 있다는 점을 보여주었죠. 이번 사례를 통해 국제정세에 대한 이해는 물론, 기업의 전략적 대응이 얼마나 중요한지도 알 수 있어요.앞으로도 글로벌 정책 변화에 주목하면서, 유연하게 대응하는 것이 필요하겠죠 :)마소캠퍼스와 함께 AI를 활용해 업무 혁신을 이뤄보세요!효율적이고 스마트한 일의 방식을 통해 성장할 수 있도록 도와드릴게요. 📌 관련 강의 <회사가 원하는 효율적인 AI 활용 – 회의 준비부터 기록까지>회의 준비부터 회의록 작성까지, AI가 다 해드립니다! 반복 업무는 자동화하고, 중요한 일에 집중하세요.  

경영 · 전략관세수출규제미국우선주의트럼프관세경영경제이슈ai트렌드마소캠퍼스한국경제무역전쟁

워밍업 클럽 3기_PM/PO_후기

PM이란 무엇일까 막연한 의문으로 강의를 신청했다. 신청 당시 내가 가진 직무 전문성에 대해 회의감이 드는 시기였다. 손에 잡히는 성과물 하나 없는 2년간의 PM 업무 경험을 가지고 앞으로 어떻게 커리어를 쌓아야 하나 막막했다.완강 후에 다시 PM이란 무엇인지 생각해 보았을 때, 이전보다는 좀 더 넓게 PM의 직무를 바라볼 수 있게 되었다. 강의 내용 중 제품과 사용자에 대한 전문가로 PM의 정의하는 부분이 인상 깊었고, 사용자와 제품에 대한 전문성을 기르는 방법과 따라오는 다양한 개념들도 유익했다.결국, PM이란 직무를 돌이켜보면 딱 떨어진다기보다는 각 회사마다 필요한 상황에 따라 다양한 역할을 수행하는 직무였다. 더 이상 PM 구직 공고를 보며 내가 가진 전문성이 떨어진다고 한탄하지 않는다. 오히려 사용자와 제품 전문가로 성장하기 위해 나는 어떤 노력을 해왔고 앞으로는 무엇을 더 해보고 싶은지 생각해 보게 되었다.강의를 추천하자면 PM에 대해서 막연한 호기심을 가진 입문자나 2-3년 경력을 가진 주니어에게 직무에 대한 시야를 넓혀주는 좋은 강의라고 생각한다. 워밍업 클럽으로 강의를 수강하며 매일 동기부여를 받을 수 있는 것도 좋았다. 커리어 성장에 대해 막연한 불안감이 들 때 한 번쯤 도전해 보길 추천한다.

기획 · PM· PO인프런인프런워밍업클럽스터디3기

wonderson

[워밍업 클럽 3기 CS 전공지식] 자료구조와 알고리즘 특별 미션

문제실수로 워밍업 클럽 출석을 빼먹었는데 우연히 데이터를 수정할 수 있는 권한이 주어졌습니다. 러너분의 이름(name)과 출석수(count)가 저장된 배열에서 여러분(나)의 데이터를 퀵정렬을 이용해 오름차순 정렬하고 가장 첫 번째 데이터인 여러분의 출석수를 변경하도록 코드를 작성해주세요. (퀵정렬 구현 부분도 변경)// 퀵소트 구현 부분...(생략) let user1 = { name: "홍길동", count: 5 }; let user2 = { name: "임꺽정", count: 4 } let user3 = { name: "이순신", count: 3 } let user4 = { name: "나", count: 1 } let user5 = { name: "짱구", count: 5 } let arr = [user1, user2, user3, user4, user5] console.log("===== 정렬 전 ====="); console.log(arr); quickSort(arr, 0, arr.length - 1); console.log("===== 정렬 후 ====="); console.log(arr);예상 결과===== 정렬 전 ===== [ { name: '홍길동', count: 5 }, { name: '임꺽정', count: 4 }, { name: '이순신', count: 3 }, { name: '나', count: 1 }, { name: '짱구', count: 5 } ] ===== 정렬 후 ===== [ { name: '나', count: 5 }, { name: '이순신', count: 3 }, { name: '임꺽정', count: 4 }, { name: '홍길동', count: 5 }, { name: '짱구', count: 5 } ] 문제 해결[깃허브 코드 - Java로 작성]이전에 작성한 퀵소트 정렬 코드 참고하기다른 점숫자 배열이 아닌 객체 배열을 만들어야 한다.객체 배열 안에서 count 로 오름차순을 한다.첫 번째 해결 - count로 오름차순하기name과 count를 함께 저장할 수 있는 Runner 클래스 생성이전 코드에서 int[] 배열 대신 Runner[] 배열로 변경package sectionThree.quickSort.specialMission; public class Runner { private String name; private int count; public Runner(String name, int count) { this.name = name; this.count = count; } public int getCount() { return count; } @Override public String toString() { return "{name: '" + name + "', count: " + count + '}'; } }package sectionThree.quickSort.specialMission; import java.util.Arrays; public class QuickSortMission { public static void quickSortM(Runner[] runners, int left, int right) { if (left <= right) { int pivot = divideM(runners, left, right); quickSortM(runners, left, pivot - 1); quickSortM(runners, pivot + 1, right); } } public static int divideM(Runner[] runners, int left, int right) { int pivot = runners[left].getCount(); int leftStartIndex = left + 1; int rightStartIndex = right; while (leftStartIndex <= rightStartIndex) { while (leftStartIndex <= right && pivot >= runners[leftStartIndex].getCount()) { leftStartIndex++; } while (rightStartIndex >= (left + 1) && pivot <= runners[rightStartIndex].getCount()) { rightStartIndex--; } if (leftStartIndex <= rightStartIndex) { swapM(runners, leftStartIndex, rightStartIndex); } } swapM(runners, left, rightStartIndex); return rightStartIndex; } public static void swapM(Runner[] runners, int index1, int index2) { Runner temp = runners[index1]; runners[index1] = runners[index2]; runners[index2] = temp; } public static void main(String[] args) { Runner user1 = new Runner("홍길동", 5); Runner user2 = new Runner("임꺽정", 4); Runner user3 = new Runner("이순신", 3); Runner user4 = new Runner("나", 1); Runner user5 = new Runner("짱구", 5); Runner[] runners = {user1, user2, user3, user4, user5}; System.out.println("===== 정렬 전 ====="); System.out.println(Arrays.toString(runners)); quickSortM(runners, 0, runners.length - 1); System.out.println("===== 정렬 후 ====="); System.out.println(Arrays.toString(runners)); } }결과===== 정렬 전 ===== [{name: '홍길동', count: 5}, {name: '임꺽정', count: 4}, {name: '이순신', count: 3}, {name: '나', count: 1}, {name: '짱구', count: 5}] ===== 정렬 후 ===== [{name: '나', count: 1}, {name: '이순신', count: 3}, {name: '임꺽정', count: 4}, {name: '홍길동', count: 5}, {name: '짱구', count: 5}] 두 번째 해결 - 가장 첫 번째 데이터인 여러분의 출석수를 변경3번 코드에서 추가한 부분quickSortM()을 호출하고 모든 재귀 함수 호출이 끝난 시점인 if 가 필요Runner 클래스에서 setCount() 을 호출해서 변경최소/최대 참여수는 불변값으로 변수 선언문제점이 있다. 5번에서 해결하기package sectionThree.quickSort.specialMission; public class Runner { private String name; private int count; private static final int MIN_CHECK = 0; // 최소 참여수 private static final int MAX_CHECK = 5; // 최대 참여수 public Runner(String name, int count) { this.name = name; this.count = count; } public int getCount() { return count; } public void setCount(int count) { if (!(MIN_CHECK <= count && count <= MAX_CHECK)) return; this.count = count; } @Override public String toString() { return "{name: '" + name + "', count: " + count + '}'; } }package sectionThree.quickSort.specialMission; import java.util.Arrays; public class QuickSortMission { public static void quickSortM(Runner[] runners, int left, int right) { if (left <= right) { int pivot = divideM(runners, left, right); quickSortM(runners, left, pivot - 1); quickSortM(runners, pivot + 1, right); } // 정렬이 다 끝난 후 - 가장 첫 번째 데이터인 '나'의 출석수를 변경 if (right == runners.length - 1) { runners[0].setCount(5); } } public static int divideM(Runner[] runners, int left, int right) { int pivot = runners[left].getCount(); int leftStartIndex = left + 1; int rightStartIndex = right; while (leftStartIndex <= rightStartIndex) { while (leftStartIndex <= right && pivot >= runners[leftStartIndex].getCount()) { leftStartIndex++; } while (rightStartIndex >= (left + 1) && pivot <= runners[rightStartIndex].getCount()) { rightStartIndex--; } if (leftStartIndex <= rightStartIndex) { swapM(runners, leftStartIndex, rightStartIndex); } } swapM(runners, left, rightStartIndex); return rightStartIndex; } public static void swapM(Runner[] runners, int index1, int index2) { Runner temp = runners[index1]; runners[index1] = runners[index2]; runners[index2] = temp; } public static void main(String[] args) { Runner user1 = new Runner("홍길동", 5); Runner user2 = new Runner("임꺽정", 4); Runner user3 = new Runner("이순신", 3); Runner user4 = new Runner("나", 1); Runner user5 = new Runner("짱구", 5); Runner[] runners = {user1, user2, user3, user4, user5}; System.out.println("===== 정렬 전 ====="); System.out.println(Arrays.toString(runners)); quickSortM(runners, 0, runners.length - 1); System.out.println("===== 정렬 후 ====="); System.out.println(Arrays.toString(runners)); } } 결과===== 정렬 전 ===== [{name: '홍길동', count: 5}, {name: '임꺽정', count: 4}, {name: '이순신', count: 3}, {name: '나', count: 1}, {name: '짱구', count: 5}] ===== 정렬 후 ===== [{name: '나', count: 5}, {name: '이순신', count: 3}, {name: '임꺽정', count: 4}, {name: '홍길동', count: 5}, {name: '짱구', count: 5}] 두 번째 해결 이어서 - 가장 첫 번째 데이터인 여러분의 출석수를 변경현재 코드결과는 예상 결과처럼 잘 나온다.그런데 피벗을 기준으로 정렬할 때마다 Runner[] 첫 번째 배열의 count가 5로 변경된다.정렬 도중에 여러 번 첫 번째 요소의 값을 변경할 가능성이 있어서 의도한 대로 동작하지 않을 수 있다.내가 원했던 로직모든 정렬이 끝난 후 Runner[] 첫 번째 배열의 count가 5로 변경된다.해결 방법quickSortM() 함수 종료 후 main() 함수에서 runners[0].setCount(5); 진행 - 강사님 픽quickSortM() 에 depth 변수를 추가해서 정렬 후 0 depth인 경우에 runners[0].setCount(5); 를 진행해결 방법 2번으로 진행해보자package sectionThree.quickSort.specialMission; import java.util.Arrays; public class QuickSortMission { public static void quickSortM(Runner[] runners, int left, int right, int depth) { if (left <= right) { int pivot = divideM(runners, left, right); quickSortM(runners, left, pivot - 1, depth + 1); quickSortM(runners, pivot + 1, right, depth + 1); } if (depth == 0) { // 정렬이 다 끝난 후 - 가장 첫 번째 데이터인 '나'의 출석수를 변경 runners[0].setCount(5); } } public static int divideM(Runner[] runners, int left, int right) { int pivot = runners[left].getCount(); int leftStartIndex = left + 1; int rightStartIndex = right; while (leftStartIndex <= rightStartIndex) { while (leftStartIndex <= right && pivot >= runners[leftStartIndex].getCount()) { leftStartIndex++; } while (rightStartIndex >= (left + 1) && pivot <= runners[rightStartIndex].getCount()) { rightStartIndex--; } if (leftStartIndex <= rightStartIndex) { swapM(runners, leftStartIndex, rightStartIndex); } } swapM(runners, left, rightStartIndex); return rightStartIndex; } public static void swapM(Runner[] runners, int index1, int index2) { Runner temp = runners[index1]; runners[index1] = runners[index2]; runners[index2] = temp; } public static void main(String[] args) { Runner user1 = new Runner("홍길동", 5); Runner user2 = new Runner("임꺽정", 4); Runner user3 = new Runner("이순신", 3); Runner user4 = new Runner("나", 1); Runner user5 = new Runner("짱구", 5); Runner[] runners = {user1, user2, user3, user4, user5}; System.out.println("===== 정렬 전 ====="); System.out.println(Arrays.toString(runners)); quickSortM(runners, 0, runners.length - 1, 0); System.out.println("===== 정렬 후 ====="); System.out.println(Arrays.toString(runners)); } } 결과===== 정렬 전 ===== [{name: '홍길동', count: 5}, {name: '임꺽정', count: 4}, {name: '이순신', count: 3}, {name: '나', count: 1}, {name: '짱구', count: 5}] ===== 정렬 후 ===== [{name: '나', count: 5}, {name: '이순신', count: 3}, {name: '임꺽정', count: 4}, {name: '홍길동', count: 5}, {name: '짱구', count: 5}]  

바커스

챗GPT 지브리 스타일 사진 변환 프롬프트 예시

 얼마 전 SNS에서 “내 사진을 지브리 애니메이션처럼 바꿔봤어요”라는 게시물을 보고 놀랐습니다.진짜 지브리 스튜디오에서 그려준 것처럼 생생하고 감성적인 이미지였거든요.알고 보니 이게 전부 챗GPT에서 지브리 사진 변환으로 만들어진 결과물이더라고요. 이게 가능한 이유는, GPT-4 Turbo 모델이 기본적으로 이미지 인식과변환에 특화된 기능을 제공하기 때문이에요.과거에는 이런 걸 하려면 미드저니 같은 전문 AI 이미지 생성 도구를 써야 했는데,이제는 챗GPT 하나로 가능하다는 점에서 놀랍죠.너무 단순하면서도 의외죠?AI가 내 사진을 지브리 사진 스타일으로 바꿔준다고요? 이제 그 사용법, 직접 보여드릴게요.챗GPT로 지브리 스타일 사진 만드는 법 (사용법 총정리)제가 실제로 사용해 본 경험을 바탕으로 설명드릴게요.어렵지 않습니다. 아래 5단계를 따라 하시면 됩니다.1단계: 챗GPT 접속https://chat.openai.com에 접속해서 로그인하세요.무료 사용자도 가능하지만, 이미지 처리 기능은 유료 사용자(GPT-4)에게 우선적으로 제공됩니다.유료사용자는 sora 홈페이지에서도 가능합니다.더 고해상도 이미지 결과물 나옵니다. 2단계: 이미지 업로드채팅 입력창 옆에 ‘+’ 버튼을 누르면 사진을 업로드할 수 있어요.자신이 지브리 스타일로 바꾸고 싶은 사진을 선택하면 됩니다. 3단계: 프롬프트 입력“이 사진을 지브리 스타일로 변환해줘” 또는 “지브리 애니메이션 느낌으로 그려줘”라고입력해 주세요. 간단하게 말해도 AI가 알아서 이해합니다. 4단계: 결과 확인몇 초 안에 지브리 감성이 물씬 풍기는 이미지가 생성됩니다.인물의 눈은 크고 선명하고, 배경에는 따뜻한 색감의 애니메이션 효과가 적용돼요. 5단계: 추가 요청“눈동자를 더 반짝이게 해줘” “배경을 하늘로 바꿔줘”처럼 원하는 대로 수정도 가능합니다.처음엔 이게 진짜 될까? 싶었는데, 직접 해보면 정말 감탄하게 돼요. 6단계:프롬프트 팁이 궁금하신면 아래 링크에서 확인가능합니다.지브리 스타일 사진 변환 팁 보러가기 추가적으로 저작권관련 사항이나 상업적 대안으로 사용 방법이 궁금하시면 아래 링크를 참조하세요. 챗GPT 지브리 스타일 하는법 저작권 정리(프롬프트예시)  

AI · ChatGPT 활용지브리스타일사진변환챗GPT지브리변환AI지브리변환챗GPT지브리하는법chatgpt지브리하는법

kailis

발자국 4주차: 그래서 우리는 왜 귀찮음을 이겨내야 하는가

  그래서 우리는 왜 귀찮음을 이겨내야 하는가 마지막 주간. 나는 이번 강의를 전반적으로 들으면서 문득 떠오른 그림이 있었다.  수학에서 함수를 이야기할 때 가장 먼저 나오는 그림이다.  우리가 테스트를 하는 대상은 결국 추상화된 로직 안쪽에 대한 구체적인 결과물이다.  테스트에서 가장 중요한 것은 I/O. 그리고 연계성. 여기에서 여러가지 박스가 중첩되어 있는 게 프로그램이고,  우리가 만든 이 프로그램에서 a라는 것이 정확한 f(a)를 보장하는가? 에 대한 물음표를 컴파일 타임에서 해소해 주는 것. 즉 I/O를 얼마나 촘촘하게 필터링할수 있을지에 대한 이야기이다.  Mockist가 여기서 발언할 수 있는 여지가 있다고 생각한다.  위에 있는 박스가 어떤 것을 뱉든 a가 막을 수 있는 테스트코드로 막으면 되잖아?  난 결국 a에 대한 모든 케이스를 전부 테스트했으니까. 연계에 있어서 굳이 힘을 뺄 이유가 있겠느냐는 패러다임이다.  나는 강의에서 말씀하신 것과 비슷한 시야를 가지고 있는 것 같은데 ㅎㅎ  결국 인간이란 실수할 수 있는 동물이지 않나... 하는 생각을 한다. 어떠한 아웃풋이 나올지 모르니까 그걸 막으려고 테스트를 한다.어떠한 인풋이 나올지 모르니까 그걸 막으려고 테스트를 한다.  이 관점에서는 확실히 시나리오를 짜는 일이 유리해 보이니까.나올 수 있는 케이스를 조금 더 촘촘히 만들고 막는 것이 Classicist의 접근 방향이지 않을까.... 하는 생각이 들었다.  근데 귀찮잖아. 많은 테스트는 귀찮잖아.  아니, 테스트는 귀찮잖아!  아, 귀찮아......   음... 테스트 작성은 귀찮다.  마지막 강의의 말미에서도 이야기하는 만큼, 선생님도 "귀찮음"을 이겨내고 테스트를 작성하신다고 했다.  결국은 장기적으로 유지보수가 될 프로그램에 대한 마음의 확신. 과감한 리팩토링을 가능하게 하는 것.  사실 이런 말이 무의미할 수도 있다.  이 강의를 듣는 것 자체가 테스트가 중요하다는 것을 알고 있어서라고 생각하니까. 그러면 우리는 이 귀찮음을 어떻게 이겨내는가?  그래서, 실행  강의나 책의 가장 중요한 핵심은 제목에 있다고 생각한다.  강의의 이름을 다시 한번 돌이켜 보자.  Practical Testing: 실용적인 테스트 가이드 결국 Practical.  강의에서도 계속 강조하는 만큼 결국 가장 중요한 것은 실무에서의 활용이다. 어떻게 활용할 수 있을까? 무엇이 귀찮음을 이겨내도록 할까? 무엇에 대한 내용은 강의에서 많이 들었다. 따라서 나는 어떻게로 접근해 보고자 했다.   귀찮음을 어떻게 이겨낼까?   많은 자기계발서들은 귀찮음을 이겨내는 방법에 대해서 이야기한다.  의지력을 발휘하는 법, 언제나 열정을 불어넣는 법, 시간과 체력을 관리하는 방법.... 등등등. 난 이게 다 무의미하다고 생각하는 사람이다.  결국 Do에 있어서의 방법론이 귀찮음을 누른다고 생각하니까.  나는 하기 싫은 일이 있을 때마다 하고 싶어질 때까지 아주 잘게 쪼갠다.  그럼 테스트에서도 이걸 적용하려면? 어떻게 해야할까? 나는 먼저 <Sudo 시나리오 짜기>로 접근해 보고자 했다.  우리는 f(a)라는 함수를 테스트하려고 한다. 개별에 대한 단위 해피 테스트, 엣지 테스트 같은 것들을 리스트에 포함해 보면 좋겠다. 그리고 연계 시의 단위 해피 테스트, 엣지 테스트 같은 것들을 리스트에 포함해 보면 좋겠다.  오. 나는 이제야 테스트 작성이 좀 더 빠르게 접근할 수 있는 것으로 보인다.  이것만 함수로 만들면 되잖아? a에 대해 들어올 수 있는 값은 null일 수도, 숫자일 수도, 문자열일 수도, 객체일 수도 있다. 우리가 만약 string이라고 했다면, 숫자와 null에 대해서 필터링을 할 방법을 다 적어보면 되겠다. 강의에서는 이 방법으로 ParameterizedTest를 이야기했다. @ParameterizedTest @NullAndEmptySource @ValueSource(strings = {"Hello", " ", "123", "!@#"}) @DisplayName("입력값이 null 또는 빈 문자열이면 안 된다.") void shouldNotAllowNullOrEmptyString(String input) { // given String result = f(input); // then assertNotNull(result); assertFalse(result.isEmpty()); } f(a)로 만들어질 수 있는 값도 동일하다. null일 수도, 숫자일 수도, 문자열일 수도, 객체일 수도 있다. 우리가 만약 객체라고 했다면, 그 객체가 만들어낸 값이 동일한지를 찾아보면 되겠다.  @Test @DisplayName("출력값은 null이 아니어야 한다.") void shouldNotReturnNull() { // given String input = "hello"; // when String result = f(input); // then assertNotNull(result); } @Test @DisplayName("출력값은 예상한 문자열과 일치해야 한다.") void shouldReturnExpectedString() { // given String input = "hello"; // when String result = f(input); // then assertEquals("HELLO", result); } @Test @DisplayName("출력값은 모두 대문자로 변환되어야 한다.") void shouldConvertToUpperCase() { // given String input = "hello"; // when String result = f(input); // then assertTrue(result.matches("[A-Z]+")); } 같은 식으로 말이다.  여기서 아주 촘촘하게 테스트를 짠다면 좋겠지만 인간은 언제나 놓치는 존재니까.  그래도 아무것도 없는 백지에서 짜는 것보다 훨씬 더 촘촘할 것이고,  조금 더 접근하기가 쉬워지지 않을까. 적어도 나는 그랬다.   테스트가 서비스 운영에서 어떤 위치를 가질 수 있는지 이야기해보는 시간이었으니,  나도 정리와 함께 활용 방법을 이야기해보고 싶어 여러 이야기들을 종합적으로 해 봤다. 이제 오늘을 끝으로 인프런 워밍업 클럽 스터디 3기는 막을 내리게 된다. 회사 일, 이직 면접, 스터디를 병행하며 했던 만큼 더욱 뿌듯함이 큰 것 같다.  (이 병행을 이유로 우수 수강생은 노리기 힘들 것 같아서 조금 아쉽기는 했다. ㅎㅎ 아직 수퍼맨은 아닌 걸로...) 사실 테스트 코드에 대한 배움을 가장 중점으로 가지고 들어왔지만, Readable Code 수강을 하면서 예상치 못한 배움들이 등장했다.아는 것이라고 여기는 게 얼마나 바보같은 일인지 조금 더 절감하는 시간이었다. 수강은 이번에 막을 내리지만, 앞전 언급했던 것처럼 결국 가장 중요한 것은 실행이라는 것을 알고 있다.  실행을 토대로 내일부터 조금씩 테스트를 작성해 보는 시간을, 실제로 시간을 이유로 하지 못하더라도 어떠한 테스트 케이스가 나올 수 있는지에 대한 정리를 하고서 테스트를 하는 습관을 들여 보고자 한다.  3월은 짧았는데 어쩐지 워밍업 클럽은 길었던 느낌.  모두 고생하셨습니다.    

lkwo

워밍업 클럽 4기 BE 클린코드 4주차 발자국

4주차를 마무리하며...워밍업 클럽의 마지막 주에는 테스트 강의를 마무리하는 시간이 였습니다. 그리고 마지막 점검을 통해 제가 놓치고 있는 테스트의 시야를 넓혀주는 시간을 보냈습니다. ^^✅ 하나의 테스트에는 하나의 목적의 검증만!테스트 코드는 문서의 역할을 하기도 합니다.이를 글쓰기 관점에서 보았을때, 한문단에 하나의 주제만 쓰는것이 전달하기에 명료한 것과 같이 볼 수 있습니다.반복문과 분기문(논리구조)은 되도록 안 쓰는 테스트가 좋습니다.✅ 테스트에 대한 환경은 완벽하게 제어제어 가능한 영역과 불가능한 영역을 구분하여 테스트 코드를 작성하는 것이 좋습니다.외부 시스템 같은 경우 mock객체를 사용합니다.✅ 테스트 환경의 독립성을 보장하나의 테스트에서는 하나의 행위에 대한 내용으로 작성하는 것이 좋습니다.두가지의 행위가 혼합되어진 테스트인 경우에는 읽는이가 논리적으로 한번 더 생각해야 하고, 주 목적에 맞지 않는 이유로 테스트의 목적을 보장할 수 없게됩니다.✅ 테스트 간 독립성을 보장테스트 코드간은 서로 독립되어 동작해야 합니다.테스트 간에 순서가 생기면 안됩니다.공유 변수나 영향을 주는 persistence는 제거!사용해야하는 상황에서는 dynamic test 사용합시다.✅ Test Fixture 구성Fixture: 고정물, 고정되어 있는 물체, 테스트를 위해 원하는 상태로 고정시킨 일련의 객체(주로 given절에서 사용)@BeforeAll, @BeforeEach, @AfterEach를 통해 매 테스트에 사용할 객체를 고정시키는 것은 각 테스트의 독립성에 저해됩니다.무분별한 setup은 정보의 파편화로 인해 가독성에 저해됩니다.@BeforeAll, @BeforeEach, @AfterEach를 사용할 때는 다음과 같은 내용을 확인합시다.각 테스트를 이해하는데 아예 몰라도 되는 내용인가?수정해도 모든 테스트에 영향을 주지 않는가? ✅ Test Fixture 클렌징@AfterEach에 persistence layer의 repository의 delete메서드 실행합니다.@Transactional 사용하면 자동으로 rollback을 해줍니다만, 비즈니스 레이어에 트랜잭션에 대한 부분을 확인하기 어렵다는 사이드 이펙트가 있습니다.✅ @ParameterizedTest여러가지 파라미터(데이터)에 대해서 테스트를 진행하고 싶을 때 사용합니다.https://inf.run/7Vw48✅ @DynamicTest시나리오 테스트를 할 때 유용하게 사용할 수 있습니다.단계별로 행위와 결과를 검증합니다.https://inf.run/9nLpf✅ 테스트 수행도 비용이다각 테스트의 환경을 통일하여 테스트에 드는 비용을 줄일 수 있습니다.추상클래스를 상속받아서 테스트 코드가 돌아가도록 하면 환경을 통합해서 시간을 아낄 수 있습니다.상위클래스에 테스트에 필요한 빈들을 한번에 주입받아 여러번 spring 플레임 워크가 초기화하는 횟수를 줄일 수 있습니다. ✅ Private Method Testprivate method test는 할 필요가 없습니다.private method를 테스트 해야할 시점은 객체를 분리할 시점으로 볼 수 있습니다.✅ 테스트에서만 필요한 코드?생성자나 빌더와 같이 테스트에서만 사용되는 코드는 최소한으로 허용합니다.미래시점에 객체에 가져도되는 행위라고 생각이 되는경우 부담없이 사용합니다.✅ 시간. 시간. 시간시간이라는 요소는 개발자에게 선택을 강요합니다.한정된 시간에서 올바른 테스트를 작성하기 위해서는 테스트를 추론하고, tdd가 익숙해질 때까지 반복이 필요합니다. 요구사항에 매몰되기 보다는, 어떤 케이스로 코드를 검증할 수 있을지 한번 생각해보는 훈련이 필요합니다.도구를 빠르게 효율적으로 적재적소에 활용하기 위해서는 많이 사용해봐야 합니다.마지막 중간 점검그간 진행해오던 과제에 대해서 내가 제일 신경 쓴 부분은 중복제거, 깔끔해보이는 코드 였습니다. 이 생각이 잘못되었다는걸 이번 Day18 미션 리뷰에서 알 수 있었는데요. 중복제거나 깔끔해보이는 코드는 따라오는 효과이지, 그것이 목적이 되면 안될거라는 생각이 들었습니다. 리뷰에서 우빈님께서 하신 말씀 핵심은 중복 제거가 아니다. 도메인이다. 를 머리에 새겨넣어야겠습니다.워밍업 클럽 회고처음으로 여러명이 모여서 하나의 주제를 공부하는 시간을 보냈습니다. 짧다면 짧은 한달이지만, 응축되게 클린코드와 테스트 코드를 입문하기에 좋은 시간이 였습니다. 이 기간 동안 클린코드와 테스트 코드 짜는 저의 실력이 비약적으로 높아지지는 않았지만, 왜 필요하고 왜 꾸준히해야 하는지 목적의식을 심어주는 뜻깊은 시간이 되었습니다. 계속 이를 이어가고자.. 이 워밍업 클럽이 끝나고 따로 모여 스터디 진행을 신청했는데, 앞으로의 저의 생각과 코드에 많은 발전이 있기를 ...! 그동안 인프런 워밍업 클럽을 진행해주시느라 신경을 많이 써주신 박우빈 선생님과 인프런에 감사드리며 인프런 워밍업 클럽 "완"을 외치겠습니다!

웹 개발테스트코드클린코드

채널톡 아이콘