<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>sudal.log</title>
        <link>https://velog.io/</link>
        <description>짜장면 쟁이</description>
        <lastBuildDate>Sun, 26 Feb 2023 12:39:37 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>sudal.log</title>
            <url>https://images.velog.io/images/devel_sujin/profile/e865ac98-25d7-4385-88b6-9d694b50de98/social.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. sudal.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/devel_sujin" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[장애상황에 대처하는 신입의 자세 ]]></title>
            <link>https://velog.io/@devel_sujin/%EC%9E%A5%EC%95%A0%EC%83%81%ED%99%A9%EC%97%90-%EB%8C%80%EC%B2%98%ED%95%98%EB%8A%94-%EC%8B%A0%EC%9E%85%EC%9D%98-%EC%9E%90%EC%84%B8</link>
            <guid>https://velog.io/@devel_sujin/%EC%9E%A5%EC%95%A0%EC%83%81%ED%99%A9%EC%97%90-%EB%8C%80%EC%B2%98%ED%95%98%EB%8A%94-%EC%8B%A0%EC%9E%85%EC%9D%98-%EC%9E%90%EC%84%B8</guid>
            <pubDate>Sun, 26 Feb 2023 12:39:37 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="생애-첫-큰-업무를-맡다">생애 첫 큰 업무를 맡다.</h3>
</blockquote>
<p>입사 한지 3주 쯤 되었을 때, 사수님께서 새로운 과제를 주셨다. 기존에 잘 동작하고 있는 카드 결제 배치 프로그램에 관련된 업무였는데, 해당 코드에 리팩터링 업무를 주셨다. </p>
<p>이 코드는 프로젝트 전반적으로 자리잡고 있는 코드였고, *<em>파일 changes 가 무려 100개 가까이 되는 엄청난 크기의 리팩터링이었다. *</em></p>
<p>정말 내가 할 수 있을까 ? 망설임도 잠시 의욕이 넘치는 신입답게 리팩터링을 시작했다. </p>
<br>

<blockquote>
<h3 id="다른-사람의-코드를-변경한다는-건">다른 사람의 코드를 변경한다는 건.</h3>
</blockquote>
<p>리팩터링을 할 때 가장 큰 문제는 레거시처럼 느껴지는 코드가 왜 이렇게 되었는지 비하인드를 모른다는 사실이다. </p>
<p>모든 코드에는 이유가 있다고 하는데 어떤 이유 때문에 이렇게 된건지 알 수가 없었다. 😭 게다가 카드결제 도메인은 처음이라서, 어떤 방식으로 해당 작업이 이뤄지는지 파악하는게 급선무였다. </p>
<p>히스토리를 물어보고 싶었지만, 이 코드를 작업한 분은 이미 이직을 한 뒤였고, 우리 팀원분들은 굉장히 바빠보여서 질문하기도 죄송한 상황이라 최대한 스스로 하려고 했다. (다시 돌아간다면 폭풍 질문을 할거다..)</p>
<br>

<blockquote>
<h3 id="안정감을-느끼며-리팩터링하기">안정감을 느끼며 리팩터링하기</h3>
</blockquote>
<p>리팩터링이란 <strong>기능에 변경없이 코드를 개선하는 일</strong> 이다. 그런데 기존 기능에 엣지 케이스나 이런 것들이 전부 파악이 안되어 있는 상태인데, 테스트 코드까지 없다면 ? 정말 코드 하나 하나 변경하기가 무섭다. </p>
<p>그래서 리팩터링을 하면서 최대한 작은 단위로 테스트를 짜고자 했다. </p>
<p>내가 했던 작업은 테스트가 어려워서 로컬에서는 어려운 작업이었다. (외부 서버와 하나의 묶음으로 테스트가 필요했기도 하고, 실 서비스 되는 서버 자체가 인터넷이 안되는 서버라서 ..)</p>
<p>그래서 단위 테스트라도 꼼꼼하게 작성하자고 생각했다. </p>
<br>

<blockquote>
<h3 id="짜여진-테스트를-전적으로-신뢰하지-말기">짜여진 테스트를 전적으로 신뢰하지 말기.</h3>
</blockquote>
<p>여기서 문제가 발생했다. 테스트 네이밍만 보고, 해당 테스트가 꼼꼼하게 적절한 데이터로 테스트가 되고 있다고 생각했는데, 예외 케이스가 있는 테스트였고, 해당 예외를 잡지 못해서 배포 후 장애를 겪었다. 😭</p>
<p>장애 상황이 생각보다 심각해서 팀원분들이 새벽 같이 장애 대응을 해주셨다...</p>
<p><img src="https://velog.velcdn.com/images/devel_sujin/post/510a765c-328a-41c8-bb48-6d25faf115aa/image.png" alt=""></p>
<br>


<blockquote>
<h3 id="코드-리뷰를-받는-다는건-책임을-나누는-일이다">코드 리뷰를 받는 다는건 책임을 나누는 일이다.</h3>
</blockquote>
<p>장애 때문에 팀원 분들에게 피해를 끼쳤다는 사실, 또 기업적 손해를 입을 뻔 했다는 것 때문에 식은 땀이 엄청나고, 죄송한 마음에 하루종일 심란했다... </p>
<p>사수님들은 입을 모아 코드리뷰를 거쳤고, 그렇기 때문에 버그를 발생시킬 수 있는 포인트를 잡지 못한 부분에 대해서 공동 책임이라며, 위로를 해주셨다. </p>
<p>예전에 책에서 장애 상황일 때는 공동의 책임임으로 질타하거나, 책임을 묻게 되면 실수를 숨기는 조직 문화가 형성된다는 것을 읽은 적이 있다. </p>
<p>그래서 좋은 팀 분위기 덕분에 오히려 위로를 받게 됐는데, 그게 더 마음을 불편하게 하기도 했던 것 같다. </p>
<p>나는 신입이 들어와서 이런 큰 실수를 저지르면 우리 사수님들처럼 품어줄 수 있을까? 싶기도 하고, 만감이 교차했다. </p>
<blockquote>
<h3 id="장애-상황에-대처하는-신입의-자세-🥲">장애 상황에 대처하는 신입의 자세 🥲</h3>
</blockquote>
<ul>
<li><strong>정신 똑바로 차리고, 장애가 난 원인 파악.</strong>
장애 상황은 사수님들의 발빠른 대처 덕분에 해결이 되었다. 그러나 장애를 낸 코드를 작성한 것은 나이기 때문에, 내가 코드를 작성하며 어떤 부분을 간과했는지 정확하게 파악하고, 이런 일이 두번 다시 일어나지 않도록 회고 작업을 해야한다.  <br></li>
</ul>
 <br>


<ul>
<li><strong>팀원분들께 감사함과 죄송함 표현</strong>
  혼자 정신이 없어서 죄송하다고 표현을 못할 뻔 했었다. 팀 전체가 나의 실수로 인해서 고생하고 있다는 사실을 인지 했다면 바로 감사함과 죄송함을 표현하자.   <br>  </li>
<li><strong>장애에 일희일비 하지않기</strong>
 존경하는 사수님께서, 개발자가 장애를 내지 않는다는 건 말이 안되는 일이라고 하셨다. 배포 한번 나갈 때마다 불안함에 떤다면 어떻게 일을 할 수 있을까 ? 함께하는 동료들과 나를 믿고 실수가 반복되지 않도록 점점 더 나은 나를 만들어가자.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[23년 1월 회고 ]]></title>
            <link>https://velog.io/@devel_sujin/23%EB%85%84-1%EC%9B%94-%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@devel_sujin/23%EB%85%84-1%EC%9B%94-%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Sun, 12 Feb 2023 10:12:52 GMT</pubDate>
            <description><![CDATA[<h3 id="들어가며">들어가며,</h3>
<p>12월에 새로운 한 해를 맞이할 생각에 늘 그래왔듯 많은 다짐들을 했었다. 😃
(지키지 못할지언정, 계획이라도 세워야 마음이 편한 타입)</p>
<blockquote>
<h2 id="1월-공부">1월 공부</h2>
<p>의지보다 더 강력한 것은 환경 조성이다. 
새해 첫 한달은 스스로 학습 환경을 조성하는데 가장 많은 노력을 했었다. </p>
</blockquote>
<h3 id="1-1-공부하는-습관에-대해서">1-1) 공부하는 습관에 대해서</h3>
<p><strong>혼자보다 함께 할 때, 목표한 바를 성취하기가 수월하다</strong>는 것을 자주 느낀다. 
이따금 의지가 약한 것에 대해서 아쉽기도 하지만, 누군가와 함께 한다면 이겨낼 방법이 있다는 사실이 감사하다. ☺️</p>
<p>12월부터 <strong>우테코를 같이 했던 사람들과 잘될거야 데일리 플랜 스터디</strong>를 진행했다. (아래 그림은 개인 일정만 뽑아서 정리해 둔 내용이다.)</p>
<p><img src="https://velog.velcdn.com/images/devel_sujin/post/76f7dcdc-589c-4946-9104-05b9c9006b77/image.png" alt="1월_todoList"></p>
<p>처음엔 습관이 들지 않아서 매일 아침 일어나는게 힘들고, 하루 동안 할 일들을 산정하는 것 자체가 힘들었는데 한달이 지나니 일정 산정을 쉬워지고 어떻게하면 일정을 잘 지킬 수 있을까 고민하는 단계로 접어들었다. </p>
<p>(매일 8시 ~9시 기상 후 인증 사진을 보냈다.)</p>
<p><img src="https://velog.velcdn.com/images/devel_sujin/post/c0b39677-63ca-4861-a1c8-01d9f2f1289f/image.png" alt=""></p>
<p>그 과정 중 하나로 20분간 집중하고, 5분 쉬는 <strong>뽀모도로🍅 학습법</strong>을 사용했더니, 엄청 효율적으로 시간 사용이 가능했다. 20분이 짧은 시간이라고 생각되어서 이것만 집중하자! 라는 마음을 먹고, 5분 휴식을 통해 보상을 해주니 다음 보상이 기대되어 빠르게 새로운 토마토를 세우고 싶어졌었다. (지금은 조금 익숙해져서 잠시 쉬는 중) 집중이 너무 안될 때나 오랜만에 작업을 시작할 때 하면 좋을 방법인 것 같다. </p>
<h3 id="1-2-스터디를-운영하며">1-2) 스터디를 운영하며</h3>
<p>처음 취업 준비를 하는데 혼자서 하기가 막막해서 시작했던 <strong>잘될거야 스터디</strong> 인원들이 하나 둘 씩 취업하면서 여러 고민이 생겼었다.</p>
<ul>
<li>취업한 인원은 스터디에서 제외해야하는가?</li>
<li>회고를 오프라인으로 하는게 좋을까? </li>
<li>취업 관련된 진행 상황을 모두 함께 나누는 것이 심적으로 불편하지는 않을까?</li>
</ul>
<p>등등 .. 매일 일정을 적다보니 누구는 면접에 가고, 누구는 혼자서 학습하는 시간이 길고.. 이런 것들이 공유되어 취업 준비하는 스터디원들의 입장에서 마음에 불안함이 생기지는 않을까 , 또 취업한 사람들을 진심으로 응원하기는 하지만, 조급한 마음이 들까봐 염려 했었다. </p>
<p>결론은 디테일까지는 공유하지 않지만, 일상을 그대로 공유했었다. 이런 부분이 긍정적인 자극이 되길 바라며 .. 내 의도대로 잘 전달이 되었을지는 모르겠지만, 학교로 돌아간 스터디원들, 여유를 가지고 취업 준비를 하던 스터디원들을 제외하고는 전부 취업을 한 것으로 보아서 나름(?) 잘 운영했다고 생각한다. </p>
<p><strong>조금 반성할 점</strong>은, 1월 중순에 입사를 하고나서 이런 저런 일로 미처 스터디를 신경쓰지 못했던 점이 너무 아쉽다. 스터디 운영을 다른 사람에게 넘기든, 아님 차후 방향성에 대해서 스터디원들과 함께 의논하는 시간이 있었어야 했는데 그런점이 없이 흐지부지 된 것 같다. 😥</p>
<h3 id="1-3-내면-다스리기-공부에-대하여">1-3) 내면 다스리기 공부에 대하여</h3>
<blockquote>
<p><strong>감정의 무게 중심이 내 천체 안에 있으면 안정적으로 존재 할 수 있다.</strong> </p>
</blockquote>
<p>취업 준비로 인해 감정 기복이 심했었다. 그러던 중  *<em>무게 중심을 내면에 두면 감정 기복을 줄일 수 있다는 조언을 받았고, *</em>이런 조언을 하게 된 배경에 아래 유튜브 영상에 심채경님께서 하신 말씀을 보게 되었다는 것을 전해 들었다. </p>
<p><img src="https://velog.velcdn.com/images/devel_sujin/post/a03249fe-0aab-4c6a-afc9-9f2d85ff7307/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/devel_sujin/post/248c2c8f-46fc-487e-b198-7495ad9a0d5b/image.png" alt=""></p>
<p>(영상이 궁금하다면, 아래에 들어가서 보는 것을 추천한다.)</p>
<ul>
<li><a href="https://youtu.be/v75sWnEU-yk?t=873">영상 1</a></li>
<li><a href="https://youtu.be/oXDkdvLqIQ8?t=918">영상 2</a></li>
</ul>
<p>영상을 보고나니 그동안 불필요한 감정낭비를 하고 있었다는 생각이 들었다. 그래서 다른 사람의 평가에 의해 내 감정이 좌우되는 것이 아니라, *<em>내 스스로가 보았을 때 나의 만족도에 의해 감정을 느끼는 연습을 하기 시작했다. 
*</em></p>
<p>그 방법 중 하나로 감정에 대한 책을 읽었다. </p>
<ul>
<li><a href="https://sudal.site/anxiety/">알랭 드 보통-불안 3장</a></li>
<li><a href="https://sudal.site/why_love/">나는 왜 너를 사랑하는가</a></li>
</ul>
<p>감정들 중 불안과 사랑에 대해서 가장 궁금했기에 위 두권을 읽었다. 전부 다 읽지는 못했고, 시간이 날 때마다 궁금한 챕터를 꺼내 읽고 있다. </p>
<p>어제 성수에서 갔다가 인센스를 선물 받아서 앞으로는 인센스를 켜두고 책을 조금 더 감성있게 즐겨보고자 한다. </p>
<p>추가로 화성에서 온 남자 , 금성에서 온 여자라는 책도 추천한다. 이 책을 통해서 여러 사람의 유형과 해당 유형이 사랑을 느끼게끔 할 수 있는 방법들을 이해할 수 있다. </p>
<h3 id="1-4-개발-공부에-대해서">1-4) 개발 공부에 대해서</h3>
<ul>
<li><p><a href="https://github.com/woowacourse-study/2023-woowa-os">OS 스터디</a>
반효경님의 운영체제 책으로 스터디를 진행했다. 매주 수요일 마다 하고 있는데, 기초 CS를 채우는데 엄청 도움이 된다. 특히 우리 팀원 중 클레이가 엄청 열심히 해주고 있다.( 고마워 😁)</p>
</li>
<li><p><a href="https://necessary-sundial-178.notion.site/Kotlin-in-Action-a45ce4ed9fe04c1294755ed09fb880ed">코틀린 인 액션 &amp; 이펙티브 코틀린</a>
사내에서 스터디를 시작했다. 처음 코틀린을 봤을 때는 어려워 보였는데 아직 익숙하지 않아서 그렇지, 익숙해지면 엄청난 효율이 생길 것 같은 기분을 느꼈다. 3장까지 읽었는데, 차차 읽으면서 더 재미를 붙여보면 좋을 것 같다. </p>
</li>
</ul>
<ul>
<li><p><a href="https://www.inflearn.com/course/%EB%8F%99%EC%8B%9C%EC%84%B1%EC%9D%B4%EC%8A%88-%EC%9E%AC%EA%B3%A0%EC%8B%9C%EC%8A%A4%ED%85%9C">재고 시스템으로 배우는 동시성 이슈</a>
<a href="https://sudal.site/namedLock/">NamedLock</a>
<a href="https://necessary-sundial-178.notion.site/e57fccbf1a3049a4b3fe424610e922ef">가볍게 정리 낙관,비관,레튜스,레디슨</a></p>
<p>면접을 준비하다가, 동시성에 대해서 조금더 딥다이브하게 학습하고 싶어서 해당 강의를 구매해서 처음으로 레디스를 써봤다. 레디스로 분산락을 지원하긴 하지만, 그 외에도 다양한 분산락을 구현하는 방식에 대해 알게되고, 비슷한 문제가 생겼을 때 고민할 시야가 넓어졌다는 것에 만족스러웠던 강의다. </p>
</li>
</ul>
<blockquote>
<h2 id="1월-운동">1월 운동</h2>
<p><strong>운동은 미래 건강에 대한 적금이다. 꾸준하게 해보자.</strong> 👏🏻</p>
</blockquote>
<p>1월에는 많이 걷지 못했다. 한참 평균 걸음수가 높았을 때는 1만보씩 걸었는데, 
날이 춥다는 핑계로, 또 업무시간 때문에 오래 앉아있어서 그런가 재택할 때는 유난히 더 안걷게 된다. </p>
<p><img src="https://velog.velcdn.com/images/devel_sujin/post/40656242-8a79-4ece-acbc-0c6e7438fb8b/image.png" alt=""></p>
<p>그래도 나의 운동 메이트와 2주에 한번씩은 운동을 하기로 했어서 <strong>클라이밍과 탁구</strong> 두가지를 했다. 클라이밍은 처음이라 그런지 생각보다 힘들고, 흥미가 없었지만. 탁구는 진짜 재밌게 쳤다. 기회가 되면 또 치고 싶다. </p>
<blockquote>
<h2 id="음식에-대해서">음식에 대해서</h2>
<p>음식을 먹으며 소확행을 느낀다. *<em>음식은 삶에서 가장 확실하게 행복을 느낄 수 있는  방법이라 매 끼니마다 뭘 먹으면 좋을까 고민스럽다. *</em> </p>
</blockquote>
<p>이번 달 <strong>Best5</strong>를 뽑자면 아래와 같다. </p>
<ul>
<li>스시 코우지(음식이 아니다. 예술이다.)</li>
<li>석촌 진지아 (마라탕 + 꿔바로우) </li>
<li>종로 최부자 보쌈 (굴보쌈 맛집)</li>
<li>석촌 더빛남(쌀국수)</li>
<li>사내 식당.. (연어 덮밥)</li>
</ul>
<p>맛있는 음식을 통해 행복함을 느낄 수 있어서 감사한 한달이었다. </p>
<h2 id="etc">ETC.</h2>
<p>갑작스럽게 큰 일을 겪었다. 모든게 갑작스러워서 그 감정을 온전히 느끼고 견뎌내기 보다는 문득 문득 찾아오는 감정을 소화하고 있다. 잘하고 있는건지 모르겠지만 지난 번 취준을 하면서 막연한 불안함이 찾아왔을 때 <strong>잘될거야, 잘되겠지.</strong> 라는 마법같은 주문을 통해 마인드 셋 했던 경험을 바탕으로 스스로를 다독이고 있다. 모두가 마음에 평안함이 찾아오기를 바란다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Getter Setter 를 쓰지 말아야하는 이유가 뭘까?]]></title>
            <link>https://velog.io/@devel_sujin/Getter-Setter-%EB%A5%BC-%EC%93%B0%EC%A7%80-%EB%A7%90%EC%95%84%EC%95%BC%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0%EA%B0%80-%EB%AD%98%EA%B9%8C</link>
            <guid>https://velog.io/@devel_sujin/Getter-Setter-%EB%A5%BC-%EC%93%B0%EC%A7%80-%EB%A7%90%EC%95%84%EC%95%BC%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0%EA%B0%80-%EB%AD%98%EA%B9%8C</guid>
            <pubDate>Sun, 20 Feb 2022 10:25:38 GMT</pubDate>
            <description><![CDATA[<h1 id="private-로는-데이터를-지키기에-부족한걸까"><strong>Private 로는 데이터를 지키기에 부족한걸까?</strong></h1>
<p>맨 처음 객체 지향에 대해 배울 때, 데이터를 <code>다른 곳에서 변경하지 못하도록</code></p>
<p>접근 제어자를 <code>private</code> 로 두고,<code>getter / setter</code> 를 사용하라고 배웠다.</p>
<p>그런데 이번 요구사항에 <code>최대한 setter 를 쓰지 않고 해보라</code> 는 의문의 메시지가 있었다.. ! 😲😲 </p>
<p>왜 그렇게 해야할까?</p>
<hr>
<h1 id="객체-지향-프로그래밍의-본질"><strong>객체 지향 프로그래밍의 본질</strong></h1>
<p>객체 상태를 보호하기 위해 외부에 노출되는 정보를 줄이고, 다른 객체와 메세지를 주고받아 협력하는 것 이라고 생각한다. </p>
<p>여기서 핵심 키워드는 <code>노출되는 정보를 줄임</code> 과 <code>메세지로 협력</code> 이다.</p>
<p><code>setter 를 사용하게되면 클래스 외부에서 내부를 수정</code>하게 되니, 객체를 보호하는 것에 멀어지고,</p>
<p><code>getter 를 사용하게되면 정보를 노출</code>한다. </p>
<h2 id="캡슐화"><strong>캡슐화</strong></h2>
<p>내가 알고 있는 캡슐화란 정보를 은닉해서 데이터 접근을 막는 것 이었다. </p>
<p><em>흠..</em> 🤔  조금 더 깊은 이해가 필요할 것 같아 객체 지향에 관련된 책을 펼쳐봤다. </p>
<p>여기서 <code>tell, don&#39;t ask</code> 라는 단서를 찾았다. <code>필요한 액션을 말해, 정보를 묻지말고.</code> 라고 이해했다.</p>
<br>

<blockquote>
<h2 id="묻지도-따지지지도-말고-원하는-행동을말해"><strong>묻지도 따지지지도 말고 (원하는 행동을)말해!</strong></h2>
<img width="350" alt="스크린샷 2021-12-04 오후 6 39 40" src="https://user-images.githubusercontent.com/26570275/144704885-43a022c8-2396-408b-b9ce-ae3ebda663b0.png">
</blockquote>
<h3 id="그래-정보를-주지말고-정보에-관련-된-처리를-가지고-있는-당사자가-해보면-어떨까">그래!! 정보를 주지말고, 정보에 관련 된 처리를 가지고 있는 당사자가 해보면 어떨까?</h3>
<p>만약 자동차 주행 거리가 100km 가 넘었는지 알고싶다고 하자.</p>
<pre><code class="language-java">
class car {
   private int 거리;

   public car(int 거리){
       this.거리 = 거리;
   }

   public int get거리(){ return this.거리;}
}

  public static void main(String[] args) {
   if(car.get거리 &gt;= 100km){
      System.out.println(&quot;100km 넘게 주행하셨네요 ~);
   else
      System.out.println(&quot;100km 안넘었어요! &quot;);
}
</code></pre>
<p>여기서 get 을 사용하면 거리가 노출된다. 바꿔보자.</p>
<pre><code class="language-java">
class car {
   private int 거리;

   public car(int 거리){
       this.거리 = 거리;
   }

   public int isOverKm(int km){ // 여기를 보자
         return 거리&gt;= km;
}

  public static void main(String[] args) {
   if(isOverKm(100)){
      System.out.println(&quot;100km 넘게 주행하셨네요 ~);
   else
      System.out.println(&quot;100km 안넘었어요! &quot;);
}
</code></pre>
<p>이렇게 하면, 정확한 거리를 알려주지 않더라도 내가 원하는 정보를 알게 된다!
조금더 정보가 숨겨진 것 같지 않은가????</p>
<h2 id="gettersetter-을-쓰지-말아야하는---줄여야하는-이유"><strong>Getter/Setter 을 <del>쓰지 말아야하는</del> -&gt; 줄여야하는 이유</strong></h2>
<p>get/ set 사용을 지양해야 하는 이유는 위에서 보았듯 <code>일차적으로 데이터를 보호하기 위해 사용하지만</code>,</p>
<p><code>사용하게 되면 데이터가 노출</code>된다. 가 이유인 것 같다.</p>
<p>그렇다고 해서 아예 사용을 하지 않고서는 코딩이 어렵다!! ㅠㅠ</p>
<p>따라서 <del>쓰지 말아야하는</del>  -&gt; <code>줄여야하는</code> 으로 변경했다.</p>
<h2 id="느낀점"><strong>느낀점</strong></h2>
<pre><code>객체 지향에 대해 다각도로 바라본 경험이었다.
무의식으로 get/set 을 만들어서 사용하곤 했는데, 의식해서 줄여봐야겠다. 
이번 미션부터 적용해보자!</code></pre><h1 id="참고"><strong>참고</strong></h1>
<ul>
<li><a href="https://black7375.tumblr.com/post/168759550560/getter%EC%99%80-setter%EB%A5%BC-%EB%90%98%EB%8F%84%EB%A1%9D-%EC%93%B0%EC%A7%80-%EB%A7%90%EC%9E%90/amp">Getter와 Setter를 되도록 쓰지 말자.</a></li>
<li><a href="https://github.com/Java-Awesome/Javawesome_reading_book/blob/main/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5%EC%9D%98_%EC%82%AC%EC%8B%A4%EA%B3%BC_%EC%98%A4%ED%95%B4/5%EC%9E%A5/5%EC%9E%A5_%ED%97%88%EC%88%98%EC%A7%84.md">객체지향의 사실과 오해 5장 -책임과 메세지</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[우테코 - 4기 프리코스를 마치며]]></title>
            <link>https://velog.io/@devel_sujin/%EC%9A%B0%ED%85%8C%EC%BD%94-4%EA%B8%B0-%ED%94%84%EB%A6%AC%EC%BD%94%EC%8A%A4%EB%A5%BC-%EB%A7%88%EC%B9%98%EB%A9%B0</link>
            <guid>https://velog.io/@devel_sujin/%EC%9A%B0%ED%85%8C%EC%BD%94-4%EA%B8%B0-%ED%94%84%EB%A6%AC%EC%BD%94%EC%8A%A4%EB%A5%BC-%EB%A7%88%EC%B9%98%EB%A9%B0</guid>
            <pubDate>Tue, 14 Dec 2021 10:23:30 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>프리코스 한줄평
<strong>생각대로 살지 않으면, 사는대로 생각하게 된다.</strong></p>
</blockquote>
<h1 id="인사-🦦">인사 🦦</h1>
<p>안녕하세요! 우아한 테크 코스 4기를 지원한 수달 입니다.😁</p>
<p>꿈 같은 1차 합격을 시작으로, 
몰두하다보니 벌써 3주가 지나가고
저는 지금 프리코스 종료를 앞두고 있습니다. </p>
<p>몰두한 시간을 기록하고자 글을  작성했습니다. 즐겁게 봐주세요. ㅎㅎ</p>
<p><del><em>1차 합격을 하시고 이 글을 보신다면,  프리코스 전까지 푹 쉬시는 걸 추천 드립니다.</em></del></p>
<blockquote>
<h2 id="우테코-지원-동기">우테코 지원 동기</h2>
</blockquote>
<p>우선, 저는 <code>SW 전공자로</code> 현재 대학교 졸업을 앞두고 있습니다. (8학기 진행중) </p>
<p>대학 생활을 하며, <code>개발에 대한 재미를 느끼게 되었고</code>,  어려운 문제를 해결 했을 때 </p>
<p>&quot;아! 해냈어&quot; 하며 <code>성취감 느끼기를 좋아하여</code> 프로그래머가 되기로 했습니다. </p>
<p><code>어떻게 하면 프로그래머가 될 수 있을까?</code> 고민하다가, </p>
<p>함께 고민 할 사람들이 있는 곳 <code>(우아한 테크 코스)</code> 에 가기로 했습니다. 
 <p align="center"><img src=https://images.velog.io/images/devel_sujin/post/40788479-6ac6-4e06-9968-ec910be94b3e/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-12-14%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.51.22.png width="50%" height="20%"></p></p>
<blockquote>
<h2 id="1차-합격-후-프리코스-전까지">1차 합격 후 프리코스 전까지</h2>
</blockquote>
<p>홍대에 있는 카페에서 합격 발표 1시간 전부터 덜덜 떨다가 
합격 메일을 보고 정말 기뻤던 기억이 있습니다. ㅎㅎㅎ </p>
<p>그리고 프리코스 전까지 책을 통해  <code>자바에 대해서 주로 학습</code> 했습니다. 
기본 문법 외에 스트림과 람다에 대해 공부했고, <code>객체 지향적</code> 이란 뭘까? 고민했던 것 같습니다.  </p>
<ul>
<li><a href="http://www.yes24.com/Product/Goods/18249021">객체지향의 사실과 오해</a> </li>
<li><a href="http://www.yes24.com/Product/Goods/77125987">모던 자바 인 액션</a></li>
<li><a href="http://www.yes24.com/Product/Goods/91236635">자바 코딩의 기술</a></li>
</ul>
<blockquote>
<h2 id="프리코스-시작">프리코스 시작</h2>
</blockquote>
<p>프리코스 시작 전, 카카오톡 오픈 채팅방에
<code>: 우테코 4기</code> 라고 쳐봤더니, 3기 분들이 운영 중이신 방이 있어서 들어갔습니다.</p>
<p>오픈 채팅 방에서 프리코스를 하며 어려움을 겪을 때 질의응답을 하며 
상당히 많은 도움을 받았어요.(감사합니다.)</p>
<blockquote>
<h3 id="1주차-숫자-야구-게임-⚾">1주차 (숫자 야구 게임 ⚾)</h3>
</blockquote>
<p>프리코스의 1,2 주차는 공개되어 있어서 다른 참가자들은 미리 구현을 해본 듯 했습니다.</p>
<p>저는 몰입도를 최상으로 하기 위해서 미션 당일까지 공개된 내용을 보지 않았습니다.</p>
<p>미션은 숫자 야구 게임이었습니다.</p>
<p><code>첫 주차에는 요구사항을 파악하는 것 부터 어려움</code>이 있었고, 상당히 많은 시간을 공부하는데 사용했습니다. 아 코드 컨벤션도 정말 기본적인건데,, 프로젝트 하면서 처음 지켜봤어요..ㅠㅠㅠ(진짜..)😝</p>
<p><em>미션 중에도 다른 참가자가 보낸 PR 을 통해 어떻게 구현을 했는 지 알 수 있었지만, 보여지기 괜찮은 코드가 아니라 내 수준에서 최선의 코드를 작성하고 싶어 공부할 키워드만 찾아내고, 이해가 가지 않으면 적용하지 않았습니다.</em></p>
<h4 id="1주차에-공부-했던-내용">1주차에 공부 했던 내용</h4>
<ul>
<li><a href="https://github.com/her0807/java-baseball-precourse/wiki/camp.nextstep.edu.missionutils.test-%EB%A9%94%EC%84%9C%EB%93%9C%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90">camp.nextstep.edu.missionutils.test 메서드를 알아보자</a></li>
<li><a href="https://github.com/her0807/java-baseball-precourse/wiki/camp.nextstep.edu.missionutils.Randoms-%EC%9D%98-%EB%A9%94%EC%86%8C%EB%93%9C%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90">camp.nextstep.edu.missionutils.Randoms 의 메서드를 알아보자</a></li>
<li><a href="https://github.com/her0807/java-baseball-precourse/wiki/camp.nextstep.edu.missionutils.Console-%EC%9D%98-%EB%A9%94%EC%84%9C%EB%93%9C%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90">camp.nextstep.edu.missionutils.Console 의 메서드를 알아보자</a></li>
<li><a href="https://github.com/her0807/java-baseball-precourse/wiki/private-%EC%83%9D%EC%84%B1%EC%9E%90%EB%A5%BC-%EC%84%A0%EC%96%B8%ED%95%98%EB%8A%94-%EB%AA%A9%EC%A0%81%EC%9D%B4-%EB%AD%98%EA%B9%8C%3F">private 생성자를 선언하는 이유가 뭘까?</a></li>
<li><a href="https://github.com/her0807/java-baseball-precourse/wiki/final-%EA%B3%BC-static-final-%EC%9D%98-%EC%B0%A8%EC%9D%B4%3F">매직 넘버/매직 리터럴을 static final로 선언하는 이유가 뭘까?</a></li>
<li><a href="https://github.com/her0807/java-baseball-precourse/wiki/HashSet,-TreeSet,-LinkedHashSet">HashSet은 왜 순서를 보장하지 않을까?</a></li>
<li><a href="https://github.com/her0807/java-baseball-precourse/wiki/Mac%EC%97%90%EC%84%9C-JAVA-%EB%B2%84%EC%A0%84-%ED%99%95%EC%9D%B8%EA%B3%BC-IntelliJ-%EC%97%90%EC%84%9C-JDK-%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0">OracleJDK 와 OpenJDK 와 AdoptOpenJDK 의 차이?</a></li>
<li><a href="https://github.com/her0807/java-baseball-precourse/wiki/%EC%98%88%EC%99%B8%EC%B2%98%EB%A6%AC%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC">오류와 예외는 같은걸까?</a></li>
</ul>
<blockquote>
<h3 id="2주차-🚘︎-미션---자동차-경주-게임-🚘︎">2주차 (🚘︎ 미션 - 자동차 경주 게임 🚘︎)</h3>
</blockquote>
<p>1주차에 했던 내용을 바탕으로 <code>공통 피드백</code>이 왔고,  그 피드백으로 부터 아래와 같은 깨달음이 있었습니다.</p>
<ul>
<li>그동안 혼자서 개발을 하다보니, 의미 있는 이름에 대한 고민을 적게 했던 것 같다.😢</li>
<li>유지 보수하기 좋은 코드보다 기능 구현에 초점을 두었다.</li>
<li>String.split() 과 같이 기존에 구현된 코드들의 사용법만 익히고, 동작 원리에는 무관심했다.</li>
<li>프로젝트 시작 전, 구현해야 하는 기능을 파악하는데 미숙했다.</li>
</ul>
<br>

<p>따라서 2주차에는 좋은 네이밍에 대해 고민하고, 코드 컨벤션을 지키며, 혼자 개발하는 것이 아닌, 함께 개발할 준비를 하는 느낌이 들었습니다.</p>
<p>또한 <code>함수 분리와, 클래스 분리</code>라는 요구사항에 맞추기 위해서 객체에게 메세지를 보내야 했는데, 이 내용은 프리코스 전에 읽었던 책들의 도움을 정말 많이 받았습니다.  ㅎㅎㅎ 시간이 너무 빨리가서 눈떠보니 마감 날짜였어요. <del>(뻥 아님)</del></p>
<h4 id="2주차에-공부-했던-내용">2주차에 공부 했던 내용</h4>
<ul>
<li><a href="https://github.com/her0807/java-racingcar-precourse/wiki/NsTest-%ED%81%B4%EB%9E%98%EC%8A%A4%EC%97%90-%EB%A9%94%EC%84%9C%EB%93%9C%EB%A5%BC-%ED%8C%8C%EC%95%85%ED%95%B4%EB%B3%B4%EC%9E%90.">NsTest 클래스에 메서드를 파악해보자! </a></li>
<li><a href="https://github.com/her0807/java-racingcar-precourse/wiki/%22pobi,-jun,%22-%EC%9D%84--String.split(%22,%22)-%EC%9C%BC%EB%A1%9C-%EB%B6%84%ED%95%A0%ED%95%98%EB%A9%B4--%EB%B0%B0%EC%97%B4%EC%9D%98-%ED%81%AC%EA%B8%B0%EB%8A%94-3%EC%9D%BC%EA%B9%8C%3F">&quot;pobi, jun,&quot; 을 String.split(&quot;,&quot;) 으로 분할하면 배열의 크기는 3일까?</a></li>
<li><a href="https://github.com/her0807/java-racingcar-precourse/wiki/Getter---Setter--%EB%A5%BC-%EC%93%B0%EC%A7%80-%EB%A7%90%EC%95%84%EC%95%BC%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0%EA%B0%80-%EB%AD%98%EA%B9%8C%3F">Getter Setter 를 쓰지 말아야하는 이유가 뭘까?</a></li>
<li><a href="https://github.com/her0807/java-racingcar-precourse/wiki/%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5%EC%A0%81%EC%9D%B8-%EC%84%A4%EA%B3%84%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%ED%95%A0%EA%B9%8C%3F">객체 지향적인 설계는 어떻게 할까?</a></li>
<li><a href="https://github.com/her0807/java-racingcar-precourse/wiki/%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5%EC%A0%81%EC%9D%B8-%EC%9E%90%EB%8F%99%EC%B0%A8-%EA%B2%BD%EC%A3%BC-%EA%B2%8C%EC%9E%84-%EC%84%A4%EA%B3%84">자동차 게임 설계</a></li>
<li><a href="https://github.com/her0807/java-racingcar-precourse/wiki/%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%A3%BC%EC%9E%85%EC%9D%B4-%EB%AD%98%EA%B9%8C%3F-%EC%99%9C-%EC%82%AC%EC%9A%A9%ED%95%A0%EA%B9%8C%3F">의존성 주입이 뭘까? 왜 사용할까?</a></li>
<li><a href="https://github.com/her0807/java-racingcar-precourse/wiki/%EC%A2%8B%EC%9D%80-%EB%84%A4%EC%9D%B4%EB%B0%8D%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C%3F">좋은 네이밍이란 무엇일까?</a></li>
<li><a href="https://github.com/her0807/java-racingcar-precourse/wiki/%EC%8A%A4%ED%8A%B8%EB%A6%BC%EC%9D%B4-%EB%AD%98%EA%B9%8C%3F">스트림이 뭘까?</a></li>
</ul>
<blockquote>
<h3 id="3주차-미션---🥤-자판기-🥤">3주차 (미션 - 🥤 자판기 🥤)</h3>
</blockquote>
<p>3주차가 왔을 때는 클래스를 분리한 후 서로 관계를 맺는 것을 경험했습니다.</p>
<p>이론보다 경험으로 느낄 수 있는 내용들  <sub>ex) 계층적 설계가 왜 좋은 지? </sub> 에 대해서 
 어떤 아키텍처를 구현할지 깊은 고민이 필요했고, 초반에 생각을 정리하느라 
 머리가 아팠습니다. ㅠㅠㅠ  <del>키 클때도 못느껴본 성장통을 느끼는 듯</del></p>
<p> 브랜치를 여러번 날리며 며칠을 있다보니 방향성이 보이기 시작했고,
 완벽하게 마음에 드는 것은 아니지만, 현재로써 이해한 내용은 최대한 담아서 3주차를 마무리 하게 되었습니다. ㅎㅎㅎ  </p>
<h4 id="3주차에-공부-했던-내용">3주차에 공부 했던 내용</h4>
<ul>
<li><p><a href="https://github.com/her0807/java-vendingmachine-precourse/wiki/%EC%9D%BC%EA%B8%89-%EA%B0%9D%EC%B2%B4%EC%99%80-%EC%9D%BC%EA%B8%89-%EC%BB%AC%EB%A0%89%EC%85%98">일급 객체와 일급 컬렉션이 뭘까?</a></p>
</li>
<li><p><a href="https://github.com/her0807/java-vendingmachine-precourse/wiki/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%8C%A8%ED%82%A4%EC%A7%80-%EA%B5%AC%EC%A1%B0-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%84%A4%EA%B3%84-%ED%95%B4%EC%95%BC-%ED%95%A0%EA%B9%8C%3F">프로젝트 패키지 구조 어떻게 설계 해야 할까?</a></p>
</li>
<li><p><a href="https://github.com/her0807/java-vendingmachine-precourse/wiki/Can%E2%80%99t-automatically-merge">PR 충돌 이유와 해결 방법</a></p>
</li>
<li><p><a href="https://github.com/her0807/java-vendingmachine-precourse/wiki/Coin-%EC%9D%84-Enum-%EC%9C%BC%EB%A1%9C-%EA%B5%AC%ED%98%84%ED%95%9C-%EC%9D%B4%EC%9C%A0%EA%B0%80-%EB%AD%98%EA%B9%8C%3F">Coin 을 Enum 으로 구현한 이유가 뭘까?</a></p>
<p align="center"><img src=https://images.velog.io/images/devel_sujin/post/3e1e84f2-3e5e-4fe9-b899-4745e0e65c88/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-12-14%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%206.27.30.png width="50%" height="20%"></p>


</li>
</ul>
<blockquote>
<h2 id="프리코스를-마치며">프리코스를 마치며</h2>
</blockquote>
<h4 id="1-몰입을-위한-최고의-환경이었다">1. 몰입을 위한 최고의 환경이었다.</h4>
<p><code>매주 주어지는 미션(공부할 주제들)</code>과 <code>함께하는 동료</code>, <code>적당한 마감일</code> 이 삼박자가 몰입을 극대화 시켰습니다. </p>
<p>매주 새로운 지식을 습득하고, 그것을 적용해보며, 어떻게 하면 재밌고, 쉽게 다른 참가자들과 나눌 수 있을까? 고민하다보니 깊이있게 학습이 가능했습니다.</p>
<p>혼자서 공부할 때는 <code>부족한 점을 파악</code> 하기 어려웠는데, 같은 주제로 다른 사람이 구현한 것을 보며 공부할 <code>키워드</code> 를 찾아 학습하며 <code>주도적으로</code> 부족한 점을 채워갔던 것 같습니다.</p>
<p><code>어제보다 나은 나를 보며 큰 만족감을 느꼈습니다.</code>
<img src="https://images.velog.io/images/devel_sujin/post/507c1633-912f-4278-a7eb-799a50e04fbc/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-12-14%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%206.40.23.png" alt=""></p>
<h4 id="2-코드-작성에-이유가-생겼다">2. 코드 작성에 이유가 생겼다.</h4>
<p>그동안 <code>왜</code> 이 메서드를 사용했는지,<code>왜</code> 이 라이브러리를 선택했는지 
큰 고민 없이  구현에만 초점을 맞추어 코드를 작성했었습니다. </p>
<p>메서드의 길이 제한과, 깊이 제한을 지키다보니, 그동안 불필요한 조건문으로 인해 코드 가독성이 좋지 않았고, 한 메서드 당 많은 책임들을 지게 했구나! 깨달았습니다. </p>
<p>다른 참가자들과 코드를 공유하며, <code>코드로 의도를 전달</code>해야 했기에 
<code>왜</code> 라는 물음표를 가지고 코드를 작성하다보니, 자연스레 불필요한 코드는 제거되고, 메서드를 사용할 때 같은 동작을 하는 여러개의 메서드를 살펴보며 더 나은 것을 선택하는 <code>저만의 기준도 생겼습니다.</code>
 <p align="center"><img src=https://images.velog.io/images/devel_sujin/post/357771b8-8a70-4a1f-b59d-4e5781d005f4/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-12-14%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%206.59.19.png  width="50%" height="20%"></p></p>
<h4 id="3-함께-개발하기-위해서-어떤-준비를-해야하는지-알았다">3. 함께 개발하기 위해서 어떤 준비를 해야하는지 알았다.</h4>
<p>혼자 개발 공부를 하다보니 <code>내 코드가 다른 사람에게 어떻게 보여지는가?</code> 를 고민할 기회가 많지 않았던 것 같습니다. </p>
<p>자바 <code>컨벤션</code>을 지키는 이유, <code>패키지를 구조화</code> 하는 이유, <code>객체 지향적</code>으로 짜야하는 이유 모두 협업을 위한 준비 과정임을 알게 되었습니다.</p>
<hr>
<h2 id="마지막으로">마지막으로</h2>
<p>제가 프리코스 한줄평을 <code>생각대로 살지 않으면, 사는대로 생각하게 된다.</code> 라고 서두에 적어둔 이유는 프리코스를 통해서 <code>의식적으로 학습하는법</code>을 배웠기 때문입니다. </p>
<p>과거 생각없이 코드를 짜고 있었음을 깨닫고, <code>개발자로 가기 위해 어떤 배움의 자세를 가져야 하는가?</code> 에 대해 해답을 찾은 것 같습니다. ㅎㅎㅎ </p>
<p>3주간 고통스럽기 보다 교육과정에 함께 할 수 있음에 감사했습니다. </p>
<p>우테코를 지원해볼까? 하는 분들이라면, 반드시 권하고 싶은 과정입니다!</p>
<p>4기 프리코스를 함께 하신 분들(참가자, 운영진, 선배기수)에게도 좋은 자극을 얻었습니다. </p>
<p>꼭 합격해서 3주가 아니라 10개월 동안 개발에 몰두하는 경험을 느끼고 싶습니다.  ㅠㅠㅠㅠ</p>
<p>합격 후기를 작성할 수 있길 바라며... 글을 마치겠습니다. </p>
<h2 id="-합격했어요-ㅎㅎ">+ 합격했어요 ㅎㅎ</h2>
<p>정말 운좋게 합격을 해서 벌써 2주차가 되어 가네요.
열심히 해서 개발에 대한 제 주관을 키워야겠습니다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Git flow 전략 따라서 협업하기 ]]></title>
            <link>https://velog.io/@devel_sujin/Git-flow-%EC%A0%84%EB%9E%B5-%EB%94%B0%EB%9D%BC%EC%84%9C-%ED%98%91%EC%97%85%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@devel_sujin/Git-flow-%EC%A0%84%EB%9E%B5-%EB%94%B0%EB%9D%BC%EC%84%9C-%ED%98%91%EC%97%85%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sun, 27 Jun 2021 06:23:28 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="git-이란">GIT 이란</h2>
</blockquote>
<p>다른 사람과 함께 프로젝트를 하기 위해서는 형상관리 툴인 <code>git</code> 을 사용한다.  </p>
<p><code>but</code> 깃에 대해 알고는 있지만, 자세히 모르는 사람들은 아래와 같이 깃을 사용한다.</p>
<blockquote>
<ul>
<li>프로젝트 완성물만 레포지토리에 올린다. </li>
</ul>
</blockquote>
<ul>
<li>하나의 브런치에 지속적으로 변경사항을 커밋한다. </li>
<li>의미없는 커밋 내용이 들어있다. </li>
</ul>
<h3 id="단순히-레포지토리에-완성본을-올리는-것-이-의미가-있을까">단순히 <code>레포지토리에 완성본을 올리는 것</code> 이 의미가 있을까?</h3>
<p>결론은 의미가 없다. 혼자서 깃을 사용할 때 바람직 한 것은 작업 내역을 언제든지 이전으로 되돌릴 수 있고, 버전 별로 관리가 가능해야 <code>형상관리</code> 를 하고 있다고 할 수 있다. </p>
<hr>
<h3 id="git-브런치-전략">GIT 브런치 전략</h3>
<p>형상관리 어떻게 하는건데??</p>
<p>따라 온나 ~~ </p>
<ol>
<li>우선 어떤 기준으로 형상 관리를 할 것인지 정한다. </li>
</ol>
<p>이번 예시에서는 git flow 로 사용하겠다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[@Controller 와 @restController 의 차이 ]]></title>
            <link>https://velog.io/@devel_sujin/Controller-%EC%99%80-restController-%EC%9D%98-%EC%B0%A8%EC%9D%B4</link>
            <guid>https://velog.io/@devel_sujin/Controller-%EC%99%80-restController-%EC%9D%98-%EC%B0%A8%EC%9D%B4</guid>
            <pubDate>Mon, 17 May 2021 04:55:49 GMT</pubDate>
            <description><![CDATA[<h2 id="admin-페이지를-만들기-위해서">admin 페이지를 만들기 위해서</h2>
<p>지금 하고 있는 프로젝트에서 관리자 페이지를 만들기 위한 작업을 하게 되었다. </p>
<h2 id="스프링에서-컨트롤러">스프링에서 컨트롤러</h2>
<p>스프링에서 컨트롤러는 반환 값에 따라 크게 두가지로 나뉘게 된다</p>
<ul>
<li>controller </li>
<li>restController </li>
</ul>
<hr>
<h2 id="controller">Controller</h2>
<p>Spring MVC Controller 의 전통적인 컨트롤러인 @Controller 는 <code>view 를 반환하기 위해서 
사용한다.</code> </p>
<h3 id="사용방법">사용방법</h3>
<p>1) 클라이언트는 URI 형식으로 웹 서비스에 요청을 보낸다. 
<code>localhost:/0808/admin</code>
2)Mapping 되는 Handler 와 그 Type 을 찾는 DispatcherServlet 이 요청을 인터셉트 한다. </p>
<p>3) Controller 가 view 를 반환하기 위해서 ViewResolver 가 사용되며, ViewEwsolver 설정에
맞게 view 를 찾아 렌더링 한다. </p>
<p>4) 데이터를 반환하고 싶다면, @ResponseBody 를 활용해서 컨트롤러에서 Json 형태로 반환이 가능하다. </p>
<h2 id="restcontorller">RestContorller</h2>
<p>기본 Controller 에 ResponseBody 가 추가된 것이다. 즉 Json으로 값을 반환하기 위해서 사용하는 것이다. </p>
<h3 id="사용방법-1">사용방법</h3>
<p>1) 클라이언트는 URI 형식으로 웹 서비스에 요청을 보낸다. 
<code>localhost:/0808/admin</code>
2)Mapping 되는 Handler 와 그 Type 을 찾는 DispatcherServlet 이 요청을 인터셉트 한다. </p>
<p>3) RestController 가 해당 요청을 처리하고 ResponseEntity에 데이터를 담아서 반환한다.</p>
<p>@RestController 가 데이터르르 반환하기 위해서는 view    Resolver 대신 http MaessageConverter가 동작한다. HttpMaessageConverter에는 여러 Converter가 등록되어 있고, 반환해야하는 데이터에 따라서 사용되는 것이 다르기 때문에 Spring은 클라이언트의 Http Accept 헤더와 서버의 컨트롤러 반환 타입 정보를 조합해 적합한 httpMessageConverter를 선택하여 이를 처리한다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ HTTP API, CSR, SSR]]></title>
            <link>https://velog.io/@devel_sujin/HTTP-API-CSR-SSR</link>
            <guid>https://velog.io/@devel_sujin/HTTP-API-CSR-SSR</guid>
            <pubDate>Sun, 25 Apr 2021 08:07:56 GMT</pubDate>
            <description><![CDATA[<p>김영한 대장님의 <a href="https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/">스프링MVC1</a> 편을 참고해서 작성 한 글 입니다.</p>
<hr>
<h2 id="백엔드-개발자가-서비스를-제공할-때-고민해야하는-포인트">백엔드 개발자가 서비스를 제공할 때 고민해야하는 포인트</h2>
<ul>
<li>정적 리소스 어떻게 제공할거야?</li>
<li>동적 리소스 HTML 페이지 어떻게 띄울거야?</li>
<li>HTTP API 어떻게 제공할거야?</li>
</ul>
<p>이 세가지를 고민해야한다. </p>
<h2 id="화면-띄우기">화면 띄우기</h2>
<p>화면을 보여주는 방법은 크게 3가지가 있다. </p>
<h3 id="정적-화면-보여주기">정적 화면 보여주기</h3>
<p><img src="https://images.velog.io/images/devel_sujin/post/b97d0af0-5cc9-4c5b-8633-03b73a133260/image.png" alt=""> </p>
<h3 id="동적-화면-보여주기">동적 화면 보여주기</h3>
<p> <img src="https://images.velog.io/images/devel_sujin/post/b833ee54-2d78-4d6c-bbe0-12b896102d51/image.png" alt=""></p>
<p>동적인 html 요청이 들어오면, was가 로직을 수행함
jsp 나 타임 리프로 실행 후. 화면을 보여줌. </p>
<h3 id="json-형식에-데이터-값만-보여주기">JSON 형식에 데이터 값만 보여주기</h3>
<p><img src="https://images.velog.io/images/devel_sujin/post/20637bcf-a8c5-4efd-9850-3134b42ade28/image.png" alt=""></p>
<p>이 중 3번째 JSON 형식을 활용해서 HTTP API 를 활용해보자. </p>
<hr>
<h2 id="http-api">HTTP API</h2>
<p><img src="https://images.velog.io/images/devel_sujin/post/2e14f794-f79b-46da-a501-ba06b0d58edf/image.png" alt=""></p>
<p>프론트 개발자가 따로 있는경우, 서버에서는 데이터만 보내고, 화면은 프론트 개발자가 알아서 
구현할 경우에 사용한다. 즉 데이터만 보내는 걸 의미한다. </p>
<h3 id="특징">특징</h3>
<ul>
<li>주로 JSON 형태로 데이터를 통신한다. </li>
<li>UI 클라이언트와 접점<ul>
<li>앱 클라이언트(아이폰, 안드로이드, PC앱)</li>
<li>앱 브라우저에서 자바 스크립트를 통한 호출</li>
<li>React, Vue.js 같은 웹 클라이언트</li>
</ul>
</li>
<li>서버 to 서버<ul>
<li>주문 서버 -&gt; 결제 서버</li>
<li>기업간 데이터 통신 </li>
</ul>
</li>
</ul>
<hr>
<h3 id="서버-사이드-렌더링">서버 사이드 렌더링</h3>
<p>서버에서 최종 html 을 생성해서 클라이언트에 전달한다. 
<img src="https://images.velog.io/images/devel_sujin/post/0da5d154-abeb-4866-8b32-0bfdf86fa98e/image.png" alt="">  </p>
<p>예를 들면 웹브라우저에서 주문 내역 주세요 ~ 라고 한다. 그러면 서버에서 타임리프를 이용해서
화면을 렌더링 해서 http 응답에 코드를 실어서 보냄</p>
<p>그럼 웹은 그냥 그대로 보여주기만 함. </p>
<h3 id="클라이언트-사이드-렌더링">클라이언트 사이드 렌더링</h3>
<p>HTML 결과를 자바스크립트를 사용해서 웹 브라우저에서 동적으로 생성해서 사용함. 
-&gt; 자바 스크립트에서 inner html 을 만들어서 동적으로 부분만 변경되게 함. 
주로 동적인 화면에서 생성함. </p>
<p>웹에서 앱처럼 동작함 대표적으로 리액트가 있음. ( 웹 프론트 개발자가 하는 거임)</p>
<p>ex) 구글 지도 </p>
<p><img src="https://images.velog.io/images/devel_sujin/post/18a03b93-fc7b-4e2e-88ea-94caca955975/image.png" alt=""></p>
<h3 id="백엔드-개발자-입장에서-ui프론트기술을-어디까지-알아야-하나">백엔드 개발자 입장에서 UI(프론트)기술을 어디까지 알아야 하나?</h3>
<p>시대에 따라서 다른데, JSP, 타임리프를 공부하자.
기술이 단순하기 때문에 서버 사이드 렌더링 기술은 2~3일 정도 해보고 꼭 학습으르 해야한다. 
간단한 admin 화면을 만들 때 등등 간단하게 구현할 수 있을 때를 대비해서 학습을 필수로 해야한다.</p>
<h3 id="서버-개발자는-할-게-많다">서버 개발자는 할 게 많다..</h3>
<p>서버, 디비구축, 인프라, 객체 지향.. 등등 공부할게 많기 때문에 선택과 집중이 필요한 것 같다. 
풀스택에 대한 환상이 있을 수 있지만 얼른 마음을 접고 백엔드로 가기로 했다면 위에 공부해야할 것들을 제대로 공부할 것.. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Java Optional ]]></title>
            <link>https://velog.io/@devel_sujin/Java-Optional</link>
            <guid>https://velog.io/@devel_sujin/Java-Optional</guid>
            <pubDate>Sat, 24 Apr 2021 09:22:30 GMT</pubDate>
            <description><![CDATA[<p>오늘은 우리를 괴롭히는 <code>null</code>  에 대해서 어떤식으로 처리할 수 있는지 알아봅시다! </p>
<p>프로젝트를 하던 도중, Optional 이라는 친구를 만났습니다. </p>
<p><code>java.util.Optional&lt;T&gt;</code> 패키지에 포함되어 있습니다 ㅎㅎ</p>
<h2 id="🥯-optional">🥯 Optional</h2>
<p><code>null이 될 수도 있는 객체</code> 을 감싸고 있는 일종의 <code>래퍼 클래스</code>입니다. </p>
<p>직접 다루기에 위험하고 까다로운 null을 담을 수 있는 특수한 그릇으로 생각하시면 이해가 쉬우실 것 같습니다.</p>
<blockquote>
</blockquote>
<h3 id="래퍼-클래스"><a href="https://coding-factory.tistory.com/547">래퍼 클래스</a></h3>
<p>기본 데이터 옵셔널로 따지면 null 이 들어올 수도 있기 때문에 그 값을 처리하기 위해서  객체를 래퍼 클래스로 감쌌습니다!</p>
<hr>
<h2 id="사용-효과">사용 효과</h2>
<pre><code>1. NullPpintException를 유발할 수 있는 null을 직접 다루지 않아도 됩니다.
2. 수고롭게 null 체크를 직접 하지 않아도 됩니다.
3. n불필요한 방어 로직을 줄일 수 있습니다.</code></pre><h2 id="🏅optional-변수-선언하기">🏅Optional 변수 선언하기</h2>
<p>Optional은 제네릭을 제공하기 때문에 변수를 선언할 때 넘어오는 파라미터의 타입에 따라 
객체 타입이 설정됩니다. 우리는 User 가 되겠죠!</p>
<pre><code class="language-java">
Optional&lt;User&gt; user; // User 타입의 객체를 감쌀 수 있는 Optional 타입의 변수
Optional&lt;Comment&gt; comment; 
Optional&lt;Post&gt; post; </code></pre>
<h2 id="🏅optional-객체-생성하기">🏅Optional 객체 생성하기.</h2>
<ul>
<li><p>1) <code>Optional.empty()</code></p>
<pre><code>null을 담고있는 빈 객체를 가져옵니다. </code></pre></li>
<li><p>2) <code>Optional.of(value)</code>
  null 이 아닌 값을 가지고 있는 객체를 가져옵니다. null 이 넘어오면 오류가 발생합니다.</p>
</li>
</ul>
<ul>
<li>3) <code>Optional.ofNullable(value)</code>
  null 인지 아닌지 확실하게 모를경우 사용합니다. </li>
</ul>
<h2 id="optional-객체를-사용하기">Optional 객체를 사용하기</h2>
<p>객체를 생성했으면, 사용하는 방법도 알아봅시다. Optional 객체에 접근하기 위해선,ㄴ
4가지 방법이 있습니다. </p>
<ul>
<li><p>1) <code>get()</code>
   Optional 객체를 가져옵니다. 비어있으면 NoSuchElementException을 던집니다. </p>
</li>
<li><p>2) <code>orElse( 인자 값)</code>
  Optional 객체를 가져옵니다. 비어있으면 인자 값을 반환합니다. </p>
</li>
</ul>
<ul>
<li><p>3) <code>orElseGet(Supplier&lt;? extends T&gt; other)</code>
  Optional 객체를 가져옵니다. 비어있는 경우에만 함수가 호출되며 인자값을 반환합니다. </p>
</li>
<li><p>4) <code>orElseThrow(Supplier&lt;? extends X&gt; exceptionSupplier)</code>
  Optional 객체를 가져옵니다. 넘어온 함수형 인자를 통해 생성된 예외를 던집니다. </p>
</li>
</ul>
<hr>
<h2 id="optional-값-검증">Optional 값 검증</h2>
<p>Optional 값에서 get()을 호출했는데, 값이 null 인 경우 예외가 발생한다고 말씀 드렸죠? 이런 부분은 null 인지 아닌지 한번 검증을 하면 오류를 예방할 수 있습니다. </p>
<p><code>isPresent()</code> 를 사용하면 값이 있는지 없는지 확인 할 수 있습니다. </p>
<p><code>ifPresent()</code> 위에 값과 혼동할 수도 있습니다. 이 메소드는 특정 결과를 반환하는 대신에 Optional 객체가 감싸고 있는 값이 존재할 경우에만 실행될 로직을 함수형 인자로 넘길 수 있습니다.</p>
<h3 id="실습">실습</h3>
<p>직접 user 객체를 만들어서 간단한 <a href="https://vincentgeranium.github.io/study/2019/08/26/component.html">컴포넌트</a>를 구성해보자</p>
<p>1) 사용할 객체 만들기 </p>
<pre><code class="language-java">
public class User {

    private Long id;

    private String email;

    private String password;</code></pre>
<br>


<p>2) 사용할 레포지토리 만들기  (JPA 사용함)</p>
<pre><code class="language-java">
public interface UserRepository extends JpaRepository&lt;User, Long&gt; {
    Optional&lt;User&gt; findByEmail (String email);
    Optional&lt;User&gt; findByName (String name);
}</code></pre>
<p>3) 사용할 서비스 만들기 </p>
<pre><code class="language-java">
public class UserService {

    private final UserRepository userRepository;
    private final JwtTokenProvider jwtTokenProvider;



    public void update(Long id, User user) {
        User findUser = userRepository.findById(id).orElseThrow(() -&gt;
                new IllegalArgumentException(&quot;해당 user 가 존재하지 않습니다. id=&quot; + id));
        findUser.update(user);
    }
}
</code></pre>
<p>위에서 주의할 점은 get 으로만 호출해서 값을 가져오면 에러가 날 수 있다는 점이다 </p>
<h2 id="느낀점">느낀점</h2>
<p>항상 골치아팠던 null 처리를 해결할 수 있는 방법을 찾은 것 같아 기쁘고, 아직 익숙하진 않지만 앞으로 할 플젝에서 적용해보고 찾아보고 해야겠다. </p>
<h3 id="참고자료">참고자료</h3>
<p><a href="https://daddyprogrammer.org/post/1988/java-optional/">https://daddyprogrammer.org/post/1988/java-optional/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[동시 요청 - 멀티 쓰레드 ]]></title>
            <link>https://velog.io/@devel_sujin/%EB%8F%99%EC%8B%9C-%EC%9A%94%EC%B2%AD-%EB%A9%80%ED%8B%B0-%EC%93%B0%EB%A0%88%EB%93%9C</link>
            <guid>https://velog.io/@devel_sujin/%EB%8F%99%EC%8B%9C-%EC%9A%94%EC%B2%AD-%EB%A9%80%ED%8B%B0-%EC%93%B0%EB%A0%88%EB%93%9C</guid>
            <pubDate>Sat, 24 Apr 2021 08:04:13 GMT</pubDate>
            <description><![CDATA[<p>김영한 대장님의 <a href="https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/">스프링MVC1</a> 편을 참고해서 작성 한 글 입니다.</p>
<hr>
<h2 id="😉-서버의-동작-과정-요약">😉 서버의 동작 과정 요약</h2>
<p>우리가 네이버 메인 페이지에 접속하듯, 웹 클라이언트에 접속을하면</p>
<pre><code>
1. 메인 화면에 필요한 자료들을 보내달라며 http 요청 메소드를 was 에 보낼 것이다. 
2. 그러면 우리 서버는 tip/ip 커넥션 연결 후 소캣을 기다리고 있다가 메세지를 받고
    이 값을 서블릿 컨테이너로 보낸다. 
3. `서블릿`을 누가 호출하는데???? -&gt; 쓰레드가 호출한다. </code></pre><p> <img src="https://images.velog.io/images/devel_sujin/post/abe7b2c9-403a-42e9-82b9-09f9eafcefaf/image.png" alt=""></p>
<h2 id="🏃♀️쓰레드">🏃‍♀️쓰레드</h2>
<p><code>프로세스</code>는 프로그램을 실행,
<code>쓰레드</code>는 프로그램 실행 안에서 동작하는 것을 의미한다. </p>
<pre><code>- 애플리케이션 코드 하나 하나 순차적으로 실행하는 것이 쓰레드이다. 
- 자바 메인 메서드를 처음 실행하면 main 이라는 이름의 쓰레드가 제일 처음 실행된다. 
- 쓰레드는 한번에 하나의 코드라인만 생성한다. 
- 동시 처리가 필요하면 쓰레드를 추가로 생성한다. 
</code></pre><h3 id="단일-요청---쓰레드-하나-사용">단일 요청 - 쓰레드 하나 사용</h3>
<p>요청이 오면, <code>쓰레드를 할당</code>하고, 그 쓰레드가 서블릿을 호출함. 
그럼 서블릿이 작업을
하고 나서 결과물을 http 응답에 담아서 웹에 보낸다. </p>
<p><img src="https://images.velog.io/images/devel_sujin/post/558fc70c-857a-491a-92d9-cdf3424dabb2/image.png" alt=""></p>
<h3 id="다중-요청---쓰레드-하나-사용">다중 요청 - 쓰레드 하나 사용</h3>
<ol>
<li><p>요청이 오면 쓰레드를 할당하고, 그 쓰레드가 처리 중에 
 시간이 오래 걸려서 <code>처리 지연</code>이 발생함. </p>
<br></li>
<li><p>2번은 쓰레드 대기 상태로 기다리다가 <code>타임 아웃 상태</code>가 와서 결국 2번     요청도 죽고 1번 요청도 제대로 수행이 안된 상태로 타임 아웃 상태로
 죽게 되면 제대로 된 수행이 어려워짐. </p>
</li>
</ol>
<p><img src="https://images.velog.io/images/devel_sujin/post/e4a041f1-92d1-4fd6-8bd7-11cf41a74670/image.png" alt=""></p>
<h3 id="👩💻-이-문제점을-해결하려면-요청마다-쓰레드를-생성해주자">👩‍💻 이 문제점을 해결하려면 요청마다 쓰레드를 생성해주자.</h3>
<ol>
<li><p>요청이 오면 쓰레드를 할당하고, 그 쓰레드가 처리 중에 
 시간이 오래 걸려서 <code>처리 지연</code>이 발생함. </p>
<br></li>
<li><p>2번도 쓰레드를 할당해줘서 개발을 진행하도록 함. (was) 가 구현 해줄거임.
<img src="https://images.velog.io/images/devel_sujin/post/2ba1c142-0275-435a-9d40-1b18c770be2a/image.png" alt=""></p>
</li>
</ol>
<h3 id="요청마다-쓰레드를-생성하는-것에-장단점">요청마다 쓰레드를 생성하는 것에 장단점</h3>
<ul>
<li>장점<ul>
<li>동시 요청 처리가 가능</li>
<li>리소스가 허용할 때 까지 처리 가능</li>
<li>하나의 쓰레드가 지연 되어도, 나머지 쓰레드는 정상 동작한다. </li>
</ul>
</li>
<li>단점<ul>
<li>쓰레드 생성 비용은 매우 비쌈.
(고객의 요청이 들어 올 때마다 쓰레드를 생성하면 응답속도가 느려짐)</li>
<li>쓰레드는 <code>컨텍스트 스위칭 비용</code>이 발생 
  -&gt; 쓰레드가 여러개 일 때 코어 하나가 쓰레드 하나 실행하고 다음 것을 실핼 할 때<pre><code> 실행 쓰레드를 전환할 때 발생하는 값이 컨텍스트 스위칭 비용</code></pre></li>
<li>쓰레드를 너무 많이 생성하면 cpu 가 감당할 수 있는 메모리 임계점을 넘어 서버가 죽을 수 있음</li>
</ul>
</li>
</ul>
<p>이런 단점을 극복할 수는 없을까?</p>
<h3 id="🏖쓰레드-풀">🏖쓰레드 풀</h3>
<p>위에 단점을 해결하기 위해서 was는 내부에 수영장 같은 쓰레드 풀이 있다. </p>
<ol>
<li>쓰레드 풀에서 쓰레드가 놀고 있다.( 맨처음 프로그램 실행하면 쓰레드를 미리 만들어 둠)
(톰캣은 최대 200개 기본으로 설정함)</li>
<li>클라이언트 요청이 들어오면 놀고 있는 쓰레드 중 하나를 할당해준다. </li>
<li>다쓰면 쓰레드를 죽이는게 아니라 쓰레드 풀에 반납한다. </li>
</ol>
<h3 id="쓰레드-풀-장점">쓰레드 풀 장점</h3>
<ol>
<li><p>쓰레드 풀에 생성되어있는 쓰레드 개수보다 요청이 더 많이 들어오면
요청을 대기 상태 or 거절을 할 수 있다. </p>
</li>
<li><p>쓰레드가 미리 생성되어 있으므로 쓰레드를 생성하고, 종료하는 비용(CPU)가 절약되고,
응답 시간이 빠르다. </p>
</li>
<li><p>생성 가능한 쓰레드의 최대치가 있으므로 너무 많은 요청이 와도 기존 요청을 안전하게 처리할 수 있다.</p>
</li>
</ol>
<p><img src="https://images.velog.io/images/devel_sujin/post/52a5c03b-d21b-4977-aebe-5b718b031616/image.png" alt=""></p>
<h3 id="영한님의-꿀팁">영한님의 꿀팁</h3>
<ol>
<li><p>WAS의 주요 튜닝 포인트는 최대 쓰레드(MAX thread) 수이다. 
따라서 값을 너무 낮게 설정하면 동시 요청이 많을 때 클라이언트 응답이 지연될 수 있다. </p>
<p>값을 너무 높게 설정하면 cpu 임계점 초과로 서버가 다운 될 수도 있다. </p>
</li>
</ol>
<p>장애 발생시에는 
    - 클라우드면 일단 서버부터 늘리고, 이후에 튜닝한다. 
    - 클라우드가 아니면 열심히 튜닝한다. </p>
<h4 id="쓰레드-풀의-적정-숫자">쓰레드 풀의 적정 숫자</h4>
<ul>
<li>애플리케이션 로직의 복잡도, cpu, 메모리, IO 리소스 상황에 따라 모두 다르다.</li>
<li>성능 테스트<ul>
<li>최대한 실제 서비스와 유사하게 성능 테스트를 시도한다. </li>
<li>툴( 아파치 ab, 제이미터, nGrinder)</li>
</ul>
</li>
</ul>
<hr>
<h3 id="was의-멀티-쓰레드-지원">WAS의 멀티 쓰레드 지원</h3>
<p>핵심은 와스가 멀티 쓰레드에 대한 부분을 해결해준다. 
개발자가 멀티 쓰레드 관련 코드를 신경쓰지 않아도 됨
멀티 쓰레드 환경이므로 싱글톤 객체(서블릿, 스프링 빈) 는 주의해서 사용해야 한다. 
-&gt; 멤버 변수가 공유되기 때문에 싱글톤은 주의해서 해야함. </p>
<h2 id="느낀점">느낀점</h2>
<p>지난 시간에는 서블릿에 대해서 배웠었는데, http 요청과 응답 메세지를 
대신 만들어주는 것까지 이해 했는데, 누가 이걸 호출하는가에 대해서는 
명확하게 몰랐다. 이번 시간을 통해서 호출하는 주체가 쓰레드이고, 요청이 여러개 일 때
멀티 쓰레드를 사용하면 동시 요청 처리가 가능하게 해주며 멀티 쓰레드는 요청이 들어올 때마다 쓰레드를 생성해줘야하는데, 그 비용이 비싸고, 임계점을 넘으면 죽을수도 있어서 
이런 점들을 해결하기 위한 수영장인 쓰레드 풀이 있다는 것을 알게 되었고, 쓰레드 풀은 
처음부터 쓰레드를 만들어주고, 그 쓰레드를 활용해서 빌리고 반납하며 써서 
쓰레드를 많이 필요로 할 경우 생성할 때 발생하는 비용을 줄이고, 최대로 호출 가능한
횟수도 제한 할 수 있어 효율적인 방법인 것을 알게 되었다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[서블릿]]></title>
            <link>https://velog.io/@devel_sujin/%EC%84%9C%EB%B8%94%EB%A6%BF</link>
            <guid>https://velog.io/@devel_sujin/%EC%84%9C%EB%B8%94%EB%A6%BF</guid>
            <pubDate>Sat, 24 Apr 2021 03:11:56 GMT</pubDate>
            <description><![CDATA[<p>김영한 대장님의 <a href="https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/">스프링MVC1</a> 편을 참고해서 작성 한 글 입니다.</p>
<hr>
<h2 id="✍-서블릿이란-서블릿의-탄생-역사">✍ 서블릿이란? 서블릿의 탄생 역사</h2>
<p>우리가 <code>회원 가입 할 때</code> 를 떠올려보자. </p>
<p>웹에서 데이터를 기입하고 버튼을 누르면 회원 가입이 완료되었다고 한다.
이게 어떻게 진행되는지 알아보자.</p>
<br>


<p><img src="https://images.velog.io/images/devel_sujin/post/2190630f-4b06-4ea6-963a-f3f5a613cbf6/image.png" alt=""></p>
<p><code>전송</code>을 누르면, 요청 <code>http 메세지</code>를 만들어서 서버에 보낸다. </p>
<pre><code>- POST/save HTTP1.1 -&gt; post 방식으로 보내고 url 은 save 야.
  http1.1 버전으로 보낼게. 

- HOST : 보낸 사람은 localhost:8080이야

- Content Type : 안에 있는 내용은 urlencoded 로 되어 있고,
  들어 있는 값은 username=kim, age= 20이야</code></pre><h3 id="✍서블릿의-탄생-역사">✍서블릿의 탄생 역사</h3>
<p>서버에서 http 메세지를 받고 응답을 하기 위해서는 <code>아래와 같은 절차</code>가 있다. </p>
<pre><code>1. 프로토콜로 통신을 하기 위해서는 tcp/ip 로 연결하기 때문에 연결을 대기 시키고,
   값을 받아올 소켓을 연결해둔다.

2. http 메세지를 받아온 후 컨텐트 타입에 따라서 바디 내용을 해석한다.
    그리고 그에 따른 액션을 시킨다. 

3. 액션을 실행 시킨 후, 값을 디비에 저장하고, 결과 값을 반환하기 위한 &#39;
   http 메세지 를 만들어서 보낸다. </code></pre><p>모든 개발자들이 서버를 구현 하기 위해서는 이 절차를 따라야 하는데, 만들려는 서비스에 따라 비지니스 로직만 변경해주면 훨씬 더 효율적이지 않을까? </p>
<blockquote>
</blockquote>
<h3 id="서블릿은-이-절차-중-액션을-취하는-비지니스-로직--디비-저장-만-제외하고-전부를-대신-처리해준다">서블릿은 이 절차 중 액션을 취하는 (비지니스 로직- 디비 저장) 만 제외하고 전부를 대신 처리해준다.</h3>
<p><img src="https://images.velog.io/images/devel_sujin/post/c060d46a-4903-459b-bae6-0b12a9dcfe8b/image.png" alt=""></p>
<h3 id="🧐-우리는-서블릿을-지원하는-was-를-사용함으로-위에-처리를-단축-시킬수-있다">🧐 우리는 서블릿을 지원하는 WAS 를 사용함으로 위에 처리를 단축 시킬수 있다!</h3>
<h2 id="서블릿-특징">서블릿 특징</h2>
<p><img src="https://images.velog.io/images/devel_sujin/post/445fa7ca-0203-47ba-b8b5-3cb0a7a51150/image.png" alt=""></p>
<pre><code>- urlPatterns =&quot;/hello&#39; 
  웹 브라우저에 이 url 을 치게 되면 서블릿 핼로우 라는 클래스가 자동으로 실행된다. 
  그대신 꼭 extends HttpServlet 을 상속받을 것

- httpServletReauest
  위에서 http 요청 메세지를 해석했던 부분 기억하는가? 그 부분을 자동으로 해석하기 쉽게 만들어준다.

- httpServletResponse
  내 결과 값을 응답 메세지로 만들어서 보내주기 위해 사용함. 
</code></pre><h3 id="😜서블릿-http-스펙을-편리하게-사용할-수-있게-해주네--무야호-">😜서블릿, http 스펙을 편리하게 사용할 수 있게 해주네 ? 무야호 ~~</h3>
<p><img src="https://images.velog.io/images/devel_sujin/post/1fa05744-712b-4810-a122-c086eace2019/image.png" alt="">
<img src="https://images.velog.io/images/devel_sujin/post/1c46d2a0-abc4-48b1-aaba-b0a7966c2a94/image.png" alt=""></p>
<h3 id="과정-정리">과정 정리</h3>
<pre><code>1. localhost:8080/hello 라는 url 이 들어움
    그러면 http 요청 메세지도 함께 들어오겠죠?
    -&gt; 그걸 기반으로 request, response 객체를 생성함
2. helloServlet 클래스를 실행하고, 
    결과 값을 위에서 만든 객체에 담아서 보냄. </code></pre><h2 id="서블릿은-어디에-존재하는가">서블릿은 어디에 존재하는가!!</h2>
<p><code>WAS 안에는 서블릿 컨테이너</code> 라는 게 존재하고 우리는 아까 extends 받아서 내용만 구현했던 
코드처럼 구현 하면 된다. </p>
<p>그러면 그 컨테이너가 서블릿을 생성, 호출, 삭제 등등을 관리해준다 ~~</p>
<blockquote>
<p><img src="https://images.velog.io/images/devel_sujin/post/6a62c916-b27a-4cc1-bb03-c97e8e01aeb1/image.png" alt=""></p>
</blockquote>
<br>

<h2 id="서블릿-컨테이너">서블릿 컨테이너</h2>
<ul>
<li><p><code>톰캣</code>처럼 서블릿을 지원하는 WAS를 서블릿 컨테이너라고 함</p>
</li>
<li><p>서블릿 컨테이너는 서블릿 객체를 생성, 초기화, 호출, 종료하는 <code>생명주기관리</code>를 함</p>
</li>
<li><p>서블릿 객체는 <code>싱글톤으로 관리</code>한다. 
  고객 요청이 들어올 때마다 계속 객체생성을 하게되면 비효율적이다.</p>
<ul>
<li><code>최초 로딩 시점</code>에서 <code>서블릿 객체를 미리 만들어두고,</code> 재활용을 한다. </li>
<li>모든 고객 요청은 <code>동일한 서블릿 객체 인스턴스</code>에 접근한다. </li>
<li>공유 변수 사용시 주의해야한다. </li>
<li>서블릿 컨테이너 종료시 <code>함께 종료</code>된다. </li>
</ul>
</li>
<li><p>JSP도 서블릿으로 변환 되어서 사용된다. </p>
</li>
<li><p>동시 요청을 위한 멀티 스레드 처리를 지원한다. </p>
</li>
</ul>
<hr>
<h3 id="🌂느낀점">🌂느낀점</h3>
<p>서블릿 덕분에 http 메세지 요청, 응답을 수월하게 했었구나 깨달았다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[WebServer 와 WebApplicationServer 에 대해서 ]]></title>
            <link>https://velog.io/@devel_sujin/WebServer-%EC%99%80-WebApplicationServer-%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C</link>
            <guid>https://velog.io/@devel_sujin/WebServer-%EC%99%80-WebApplicationServer-%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C</guid>
            <pubDate>Fri, 23 Apr 2021 08:00:01 GMT</pubDate>
            <description><![CDATA[<h4 id="김영한-대장님의-스프링mvc1-편을--참고해서-작성-한-글-입니다">김영한 대장님의 <a href="https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1">스프링MVC1</a> 편을  참고해서 작성 한 글 입니다.</h4>
<p>이 글은 web 시리즈의 첫번째 글이 될 것 같다. ㅎㅎ 
전반적으로 웹이 어떻게 통신하는지 아주 기초 중에 기초를 정리한 글이지만 </p>
<p>알아둬야하는 부분이라고 생각한다. </p>
<hr>
<h1 id="web">Web</h1>
<p>모든 웹은** HTTP** 를 기반으로 통신한다. </p>
<h2 id="httphypertexttransferprotocol-이란">HTTP(HyperTextTransferProtocol) 이란?</h2>
<p>http 는 인터넷에서 데이터를 주고받을 수 있는 프로토콜을 의미한다. </p>
<h3 id="protocol-이란">protocol 이란?</h3>
<p>병원에 가서 문진을 할 때도 맨 처음 방문자는 아래 양식에 맞춰서 정보를 기입하여 정보를 공유하곤 합니다.
이처럼 모든 프로그램이 정보를 받거나 보낼 때 규칙(양식)을 정해두어서 통신을 하도록 정해두었는데요
그 통신 규칙이 프로토콜 입니다. </p>
<p><img src="https://images.velog.io/images/devel_sujin/post/88b0e150-8498-43e4-b7ed-2c8e89fa1d26/image.png" alt=""></p>
<hr>
<h4 id="중간-정리">중간 정리</h4>
<p>클라이 언트가 (예를 들면 naver.com) 과 같은 URL로 접속하면 인터넷을 거쳐 서버로 연결이 된다. 
네이버에 접속하면 메인 화면에 있는 내용이 떠야하기 때문에 그런 정보들을
http라는 정해진 규칙에 맞추어 데이터를 요청하여 주고 받게 된다.  </p>
<p><img src="https://images.velog.io/images/devel_sujin/post/2f217624-f7e5-4b86-86e5-9929bb82c8ab/image.png" alt=""></p>
<hr>
<h1 id="webserver란">WebServer란?</h1>
<p>웹 서버는 <strong>데이터를 운반해주는 서빙알바</strong> 같은 친구들이다. </p>
<p>웹이 있으면 웹에 보여지는 사진이나 글과 같은 데이터가 있는 걸 알 수 있다. 
그런 데이터들을 DB에 저장해 놨다가 필요할 때 호출하게 되는데, 그 호춣을 
<strong>http 요청</strong>을 통해서 보내게 되고, 그걸 받은 서버는 디비에서 값을 찾아다가 그 값을 채워
<strong>http 응답</strong>을 보내면 그것을 화면에서 볼 수 있게 된다. 
<img src="https://images.velog.io/images/devel_sujin/post/b6f10ebc-4405-4e0a-9ca5-a7b77ba1133d/image.png" alt=""></p>
<h2 id="webserver-특징">WebServer 특징</h2>
<p>정적 데이터를 기반으로 제공된다. 가령 우리가 (회원 가입은 했지만, 이벤트에 참여하지 않은 회원) 
특정 유저에게만 보여주고 싶은 정보들을 뿌릴 수 없다. ( 어플리케이션 로직을 실행할 수 없음)
하지만 간단한 작업만 하기 때문에 (진짜 있는 파일 가져다만 주는) 서버가 잘 다운되지 않는 장점이 있다. </p>
<hr>
<h1 id="webapplicationserver란">WebApplicationServer란?</h1>
<p>웹 서버는 <strong>데이터를 가공해서 운반해주는 서빙알바( 흔히 기술직 )</strong> 같은 친구들이다. </p>
<p>기본적인 베이스는 web 처럼 정적 페이지를 단순하게 옮겨주기도 하는데, 그와 더불어서 
프로그래밍이 가능해 로직을 실행시킬 수 있다. 위에서 말했던 데이터 가공을 할 수 있게 해주는 친구들이다. 
<img src="https://images.velog.io/images/devel_sujin/post/f71708c8-e9d4-4280-a386-641d04703130/image.png" alt=""></p>
<h2 id="webapplicationserver-특징">WebApplicationServer 특징</h2>
<p>데이터 가공이 가능한 만큼 서버가 과부화 될 가능성(다운 될 가능성) 이 있다. 다운이 된다면 화면 유지가 되지 않는다.  구글 크롬에 접속하면 인터넷이 안될 때 공룡 게임을 할 수 있게 해놨다.  이런 점은 web 이 가능하게 하는 부분이다. </p>
<p><img src="https://images.velog.io/images/devel_sujin/post/d9bbebe6-dadd-41f6-83dc-f5e22c3958cb/image.png" alt=""></p>
<h3 id="그래서-차이점이-뭔데">그래서 차이점이 뭔데?</h3>
<p>WAS 는 애플리케이션 코드를 실행하는데 더 특화되어 있다. </p>
<hr>
<h2 id="웹-시스템-구성">웹 시스템 구성</h2>
<p>하나의 웹이 동작하기 위해서 필요한 구성들이 있다. 
WAS 와 DB 이 두개만으로 충분히 가능하다. 그렇지만 위에 처럼 서버가 다운된다면 어떠한 액션을 취해야하지 않을까?
그런 부분을 해결하기 위해 WebServer +WAS + DB 로 웹 시스템을 구성한다. </p>
<p><img src="https://images.velog.io/images/devel_sujin/post/f02e4341-fefb-425e-bede-578818b1c561/image.png" alt=""></p>
<h3 id="과정">과정</h3>
<p>우선 web 을 두고 웹 서버가 정적 리소스를 처리하고, </p>
<p>웹 서버가 동적인 처리가 필요하면 was 에 요청을 위임한다. </p>
<p>was는 중요한 애플리케이션 로직 처리를 전담한다. 그렇게 하면 조금 더 효율적인 통신이 가능하다. </p>
<h3 id="느낀점">느낀점</h3>
<p>가장 기본이 되는 메커니즘을 이해한 기분이다. 
가볍게 읽어보면 좋을 듯하다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Kakao 소셜 로그인으로 설명하는 OAuth 프로토콜 ]]></title>
            <link>https://velog.io/@devel_sujin/Kakao-%EC%86%8C%EC%85%9C-%EB%A1%9C%EA%B7%B8%EC%9D%B8%EC%9C%BC%EB%A1%9C-%EC%84%A4%EB%AA%85%ED%95%98%EB%8A%94-OAuth-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C</link>
            <guid>https://velog.io/@devel_sujin/Kakao-%EC%86%8C%EC%85%9C-%EB%A1%9C%EA%B7%B8%EC%9D%B8%EC%9C%BC%EB%A1%9C-%EC%84%A4%EB%AA%85%ED%95%98%EB%8A%94-OAuth-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C</guid>
            <pubDate>Sat, 10 Apr 2021 02:49:21 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/devel_sujin/post/3c0bbf40-eca7-4ccb-b172-26d4ad3be504/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[나도 소셜 로그인 할 수 있다 편!]]></title>
            <link>https://velog.io/@devel_sujin/%EB%82%98%EB%8F%84-%EC%86%8C%EC%85%9C-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%ED%95%A0-%EC%88%98-%EC%9E%88%EB%8B%A4-%ED%8E%B8</link>
            <guid>https://velog.io/@devel_sujin/%EB%82%98%EB%8F%84-%EC%86%8C%EC%85%9C-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%ED%95%A0-%EC%88%98-%EC%9E%88%EB%8B%A4-%ED%8E%B8</guid>
            <pubDate>Sat, 10 Apr 2021 01:47:19 GMT</pubDate>
            <description><![CDATA[<h1 id="소셜-로그인">소셜 로그인?</h1>
<p>나는 아침에 제일 먼저 눈을 떠서 핸드폰을 본다.
은행도 인터넷 뱅킹이 주가 되었고, 회사의 이력서나 커뮤니티 등등 
회원가입을 해야하는 상황들이 많이 생기곤 한다. </p>
<hr>
<p>이름과, 이메일, 휴대전화,, 반복적인 개인정보 기입은 불편하다. 그럴 때 회원가입을 한번만 하고, 그 아이디로 공통적으로 사용할 수는 없을까? 생각이 들곤 했다. 그것을 현실화 시킨것이 바로 소셜 로그인이다. </p>
<p>가장 대중적으로 진행되고 있는 서비스인 google, kakao, naver 와 같은 대형 플랫폼에 가입을 한 후. 그 플랫폼에 유저에 대한 정보를 요청하게되면사용자는 별도의 추가 정보를 작성하지 않고, 그 사이트에 회원으로 가입되어 서비스를 사용할 수 있는 것이다. </p>
<h2 id="초기-방법인증-및-초기-절차">초기 방법(인증 및 초기 절차)</h2>
<p>마땅한 규칙이 없어서, 사용자들이 직접 아이디와 비밀번호를 입력하면 그 정보를 가지고 직접 인증 절차를 통과 했습니다. </p>
<p><img src="https://images.velog.io/images/devel_sujin/post/a10fa19b-5b5b-45d0-8bb3-d186da702d15/image.png" alt=""></p>
<p>만약 주소록 정보에 접근해야한다고 생각해봅니다.</p>
<p><img src="https://images.velog.io/images/devel_sujin/post/e5cfba6f-9e5f-4da2-9429-8cf2d6032fa9/image.png" alt=""></p>
<p>A 서비스에서는 사용자의 구글 아이디와 패스워드를 받아 직접 API를 호출합니다.</p>
<p><img src="https://images.velog.io/images/devel_sujin/post/2ec026f3-f5b3-41d1-9514-98ee9be8ed7a/image.png" alt=""></p>
<ul>
<li><p>사용자의 모든 구글 계정 정보에 접근이 가능하게 된 기업이 주소록 정보만 가져와서 사용한다는 보장이 있을까? </p>
</li>
<li><p>중간 과정에서 해킹되면, google 계정의 모든 권한을 사용할 수 있게 된다. </p>
</li>
<li><p>이런 권한을 여러 기업이 가지게되면 내 권한을 마음대로 사용할 가능성이 높아져 보안상 취약하게 된다. </p>
</li>
</ul>
<hr>
<p>위와 같은 위험성 때문에 몇몇의 회사들은 인증체계를 각자 구축해서 사용하곤 했습니다. 대표적으로 AuthSub 가 있습니다. </p>
<p>하지만 각자 인증 방식이 달라서 서비스를 운영하는 입장에서 불편한 점이 많았습니다. </p>
<h2 id="oauth-의-탄생-과정">OAuth 의 탄생 과정</h2>
<hr>
<p>그렇게 시간이 흘러 2006년, 트위터에서 일하던 블레인 쿡(Blaine Cook)은 Open ID를 트위터에 탑재하고 있는 일을 하고 있었고 소셜 북마크 사이트인 Ma.gnolia에서도 회원이 대시보드에서 OpenID를 통해 서비스에 접근하는 방법을 생각하고 있었습니다.</p>
<hr>
<p>이에 쿡, 크리스 메시나(Chris Messina), Larry Halff (Magnolia 개발자)는 데이비드 리코던(David Recordon)을 만나서, Open ID를 사용해 트위터와 매그놀리아의 인증을 위임하기 위한 API를 논의하였습니다.</p>
<p>만나서 얘기를 하다 보니까, 지금까지 API 접근을 맡기는 표준적인 방법은 없다는걸 깨닫게 됩니다.</p>
<p>이 순간이 바로 구글부터 새로 시작하는 스타트업까지 모두 사용하는 OAuth가 탄생하는 순간입니다.</p>
<hr>
<blockquote>
</blockquote>
<p>이후 2007년 4월 OAuth의 초안이 작성되었고 7월에 사양 초안, 10월에 OAuth Core 1.0의 초안이 작성되게 됩니다.</p>
<p>2008년 11월에는 제73회 IETF(국제 인터넷 표준화 기구, Internet Engineering Task Force)에서 OAuth를 표준화하자는 비공식 회담이 열리고 긍정적인 반응을 얻었고 2010년에는 RFC 5849로 등록된 OAuth 1.0 버전이 나오게 됩니다. 따라서 지금의 소셜 로그인이 탄생하게 되었습니다. </p>
<p>다음 포스팅에서 OAuth 에 대해서 더 자세히 적도록 하겠습니다.</p>
<hr>
<p><a href="https://gdtbgl93.tistory.com/178?category=905944#recentComments">참고 사이트</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[상속]]></title>
            <link>https://velog.io/@devel_sujin/%EC%83%81%EC%86%8D</link>
            <guid>https://velog.io/@devel_sujin/%EC%83%81%EC%86%8D</guid>
            <pubDate>Wed, 24 Feb 2021 02:43:13 GMT</pubDate>
            <description><![CDATA[<p>오늘은 다형성을 할 수 있게 해주는 자바의 상속에 대해서 아래와 같은 순서로 정리한다. </p>
<blockquote>
<h3 id="자바의-상속에-대해서">자바의 상속에 대해서</h3>
</blockquote>
<ul>
<li>자바 상속의 특징</li>
<li>super 키워드</li>
<li>메소드 오버라이딩</li>
<li>추상 클래스</li>
<li>final 키워드</li>
<li>Object 클래스</li>
</ul>
<hr>
<h3 id="상속">상속</h3>
<p>상속은 우리가 알고 있듯이 가지고 있는 재산을 자식에게 내려주는 것을 의미한다. 
자바에서도 클래스와 클래스, 인터페이스와 클래스, 등등 상속이 가능하다.</p>
<h4 id="상속의-특징"><a href="https://commin.tistory.com/101">상속의 특징</a></h4>
<pre><code>1) 부모 클래스와 자식 클래스는 자바 지정예약어 extends에 의하여 정해집니다.

2)하나의 부모 클래스는 여러개의 자식 클래스을 가질 수 있습니다.

3)반대로 하나의 클래스는 여러개의 클래스로부터 상속을 받을수는 없습니다.

4)부모 클래스로부터 상속받은 자식 클래스는 부모 클래스의 자원모두를 사용 할 수 있습니다.

5)반대로 부모클래스는 자식클래스의 자원을 가져다 쓸 수는 없습니다.

6)자식클래스는 또다른 클래스의 부모 클래스가 될 수 있습니다. 

7)자식클래스는 부모클래스로부터 물려받은 자원을 override 하여 수정해서 사용 할 수 있습니다.

8) 부모클래스가 상속받은 자원도 자식클래스가 사용 가능합니다</code></pre><pre><code class="language-java">public class Car{
  private String 연비;
  public int 속도;

}

public class  Avante extends Car {
    private int 기름양;
  // 연비는 상속받지 못했지만, 속도는 상속받음, 그리고 기름양 이라는 필드까지 있음.
}</code></pre>
<hr>
<blockquote>
<h3 id="super-키워드">super 키워드</h3>
</blockquote>
<pre><code>부모에게 재산을 상속 받고싶은 수진이가 있다. 수진이가 재산을 가지기 위해서는 누가 먼저 필요하나?
부모가 먼저 필요하다. </code></pre><p>따라서 클래스도 상속을 받게 되면</p>
<p>1) 부모클래스 객체 생성
2) 자식클래스 객체 생성</p>
<p>순으로 생성된다. 객체가 생성 될 때는 제일 먼저 클래스 안에 있는 생성자가 호출된다. 
위에 말은 1) 부모생성자, 2)자식 생성자의 호출이 이뤄진다는 것이다. </p>
<blockquote>
<h4 id="생성자">생성자</h4>
</blockquote>
<p>클래스 내에 필드들을 <strong>초기화(값을 지정) 해주는 역할</strong>. 위에서 Car에 (속도)가 있다.
속도가 몇인지 지정해줘야하지 않는가? 그런데 운전자마다 선호하는 속도가 다를 수도 있으니
<strong>객체를 만들 때 속도가 몇인지 지정</strong>해주면 좋겠다. 그래서 생성자가 필요하다. </p>
<p>맨 처음 객체를 만들면, <strong>기본 생성자가 자동</strong>으로 만들어진다. 이 생성자는 값도 없고 아무것도 없다.</p>
<p>나는 속도 값을 넣고 싶다. 그러면 이 기능을 수행하는 생성자를 만들면 된다. </p>
<pre><code class="language-java">public class Car{
  private String 연비;
  public int 속도;

  public Car(String 연비, int 속도){
      this.연비 = 연비;
      this.속도 = 속도;
}</code></pre>
<p>그런데 이 부모 객체를 자식이 상속 받았다면,  이 생성자를 어떻게 부르는가.</p>
<pre><code>자식이 부모차를 상속 받았다. 자동차는 타다보면 고장이 나거나 사용자에 맞춰지기 때문에
기본 값과 다를 수 있다. 근데 이 차가 속도가 얼마큼까지 괜찮은지, 연비는 어떻게 되는지 
어떻게 아는가. 그럴 때 우리가 하는 것은? </code></pre><h2 id="엄마-">엄마 ~~!!</h2>
<pre><code>슈퍼맨(우먼) 인 엄마 아빠를 부른다. 그래 자식 객체도 엄마를 부르게 해주자 . 그게 바로 super 이다.</code></pre><pre><code class="language-java">public class Car{
  private String 연비;
  public int 속도;

    public Car(String 연비, int 속도){
          this.연비 = 연비;
          this.속도 = 속도;
}

}

public class  ChCar extends Car {
    private int 기름양;
      public ChCar(int 기름양){
        super();
        this.기름양 = 기름양;
}</code></pre>
<p>super 를 사용하게 되면 부모의 생성자를 호출할 수 있게 된다. 자식 생성자에 추가해주자 </p>
<blockquote>
<h3 id="메소드-오버라이딩">메소드 오버라이딩</h3>
</blockquote>
<p> 부모 클래스로부터 상속받은 메소드를 자식 클래스에서 재정의하여 사용하는 것이다. </p>
<pre><code>자동차는 내 눈높이에 맞춰서 사이드 미러도 조절하고, 핸들에 높이도 조절해야한다. 
그런데 엄마가 주신 차는 엄마가 맞춰서 조정되어 있다. 이제 내 차니까 나에게 맞춰보자. 
</code></pre><h4 id="오버라이딩의-조건-및-방법">오버라이딩의 조건 및 방법</h4>
<p> 자식 클래스에서 부모 클래스의 메소드를 재정의 하기 위해서는 조건을 지켜야 한다. </p>
<p> 1) 부모 메소드의 이름, 리턴 타입, 매개변수의 갯수, 자료형과 순서를
 동일하게 하여 자식 클래스에서 작성해야 한다.</p>
<p> 2) 그리고 안에 코드를 원하는 대로 재정의한다. </p>
<h4 id="부모-클래스의-메소드-car">부모 클래스의 메소드 Car</h4>
<pre><code class="language-java">public class Car{
  private String 연비;
  public int 속도;

    public Car(String 연비, int 속도){
          this.연비 = 연비;
          this.속도 = 속도;
}

public void handle(int 높이, int 좌우 간격){
    if( 장거리 운전일 때)
        중간 높이
    else (단거리 운전일 때)
}    낮게</code></pre>
<h4 id="자식-클래스의-메소드-chcar">자식 클래스의 메소드 ChCar</h4>
<pre><code class="language-java">public class  ChCar extends Car {
    private int 기름양;
      public ChCar(int 기름양){
        super();
        this.기름양 = 기름양;
}
오버 라이드
public void handle(int 높이, int 좌우 간격){
    if( 장거리 운전일 때)
        아주높게
    elseif (단거리 운전일 때)
    낮게
    else(운전하지 않을 때)
    빼놓는다.

}

</code></pre>
<h3 id="잠깐">잠깐.</h3>
<p>근데 핸들은 모든 자동차에 있는 거잖아? 매번 이렇게 남이  쓰던걸 재정의 해야해?
모든 자동차에 있으니까 따로 빼서 쌔거 줘!!! .,</p>
<blockquote>
<h3 id="추상-클래스메소드">추상 클래스(메소드)</h3>
</blockquote>
<p>추상클래스는 여러개의 클래스에서 공통점(필드, 메서드)을 추출하여 만든 클래스이다.</p>
<pre><code>다수의 개발자가 동일한 목적으로 클래스를 설계해도 같은 모양의 클래스가 나올 수 없다.
모든 사람의 핸들 위치가 같을 수 없는 것처럼 
그래서 추상클래스를 상속하여 통일성을 높여서 유지보수를 쉽게 할 수 있다.</code></pre><p>추상클래스(메소드)는 반드시 <strong>abstract</strong> 키워드를 사용해야 한다.</p>
<pre><code class="language-java">public abstract class handle{

}

</code></pre>
<p>추상메서드는 코드가 구현되지않고 형식만 있는 메서드다
메서드의 반환타입, 이름, 매개변수가 필요하다.
public abstract void hello(String name, String message);</p>
<pre><code>쌔거니까 나에게 맞추는 것은 필수겠죠? 추상 클래스(메소드) 는 상속받으면 
꼭 꼭 값을 재정의 해줘야 합니다.
</code></pre><p>​</p>
<blockquote>
<h3 id="final-키워드">final 키워드</h3>
</blockquote>
<p><strong>final 클래스</strong>
final이 클래스 이름 앞에 사용되면 클래스를 상속받을 수 없음 을 지정한다.</p>
<pre><code class="language-java">final class FinalClass {
  ...
}
class DerivedClass extends FinalClass { // 컴파일 오류
  ...
}</code></pre>
<p>FinalClass를 상속받아 DerivedClass를 만들 수 없다.
<strong>final 메서드</strong>
메서드 앞에 final 속성이 붙으면 이 메서드는 더 이상 오버라이딩할 수 없음 을 지정한다.</p>
<pre><code class="language-java">public class SuperClass {
  protected final int finalMethod() { ... }
}
class DerivedClass extends SuperClass { // SuperClass를 상속 받음
  protected int finalMethod() { ... } // 컴파일 오류
}</code></pre>
<p>자식 클래스가 부모 클래스의 특정 메서드를 오버라이딩하지 못하게 하고 무조건 상속받아 
사용하도록 하고자 한다면 final로 지정하면 된다.</p>
<blockquote>
<h3 id="object-클래스">Object 클래스</h3>
</blockquote>
<p>Object 클래스는 모든 클래스가 상속받는 최상위 클래스이다.</p>
<p>Object클래스가 들어있는 java.lang 패키지는 자동으로 import된다.</p>
<p>주로 toString(), equals() 등을 오버라이딩 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[비지니스 요구사항과 설계]]></title>
            <link>https://velog.io/@devel_sujin/%EB%B9%84%EC%A7%80%EB%8B%88%EC%8A%A4-%EC%9A%94%EA%B5%AC%EC%82%AC%ED%95%AD%EA%B3%BC-%EC%84%A4%EA%B3%84</link>
            <guid>https://velog.io/@devel_sujin/%EB%B9%84%EC%A7%80%EB%8B%88%EC%8A%A4-%EC%9A%94%EA%B5%AC%EC%82%AC%ED%95%AD%EA%B3%BC-%EC%84%A4%EA%B3%84</guid>
            <pubDate>Mon, 22 Feb 2021 08:42:48 GMT</pubDate>
            <description><![CDATA[<h2 id="비지니스-요구사항">비지니스 요구사항</h2>
<p>서비스를 개발하기 전, 어떤 기능이 있는지 정리를 해둬야 개발할 수 있다. 
그래서 맨 처음 요구사항들을 정리한다. </p>
<h3 id="회원">회원</h3>
<pre><code>- 회원은 가입하고 조회할 수 있음
- 회원은 일반과 vip 두가지 등급이 있다.
- 회원 데이터는 자체 db를 구축할 수 있고, 외부 시스템과 연동할 수 있다.(미확정)</code></pre><h3 id="주문과-할인-정책">주문과 할인 정책</h3>
<pre><code>    - 회원은 상품을 주문할 수 있다. 
    - 회원 등급에 따라 할인 정책을 적용할 수 있다. 
    - 학인 정책은 모든 vip는 천원씩 할인해주는 고정금액 할인, 나중에 변경 가능
    - 할인 정책은 변경 가능성이 높다. 
    - 최악의 경우 적용하지 않을 수 있다. 
</code></pre><p>  요구사항을 보면 회원데이터, 할인 정책 같은 부분은 지금 결정하기 어려운 부분이다. 그렇다고 이런 정책이 결정될 때 까지 개발을 기다릴 수는 없다. </p>
<p>  인터페이스를 만들고 구현체를 언제든지 갈아끼울 수 있도록 설계하면 된다 ~~ </p>
<p>  현재는 스피링 프레임 워크는 적용되어있지 않다.</p>
<hr>
<blockquote>
<h3 id="회원-도메인-설계">회원 도메인 설계</h3>
</blockquote>
<pre><code>- 회원을 가입하고 조회할 수 있다.
- 회원은 일반과 vip 두가지 등급이 있다.
- 회원 데이터는 자체 DB를 구축할 수 있고, 외부시스템과도 연동할 수 있다. </code></pre><blockquote>
<h4 id="회원-도메인-협력-관계">회원 도메인 협력 관계</h4>
<p>기획자들도 볼 수 있는 관계이다. 이것을 바탕으로 개발자가 클래스 다이어그램을 만든다. </p>
</blockquote>
<p><img src="https://images.velog.io/images/devel_sujin/post/ab44b2d8-d963-41a6-a5b6-47815977ef41/image.png" alt=""></p>
<pre><code>클라이언트가 회원 서비스로 가고 
회원 서비스는 회원 가입, 회원 조회 두가지 기능 가능
회원 저장소라는 인터페이스 만듦 (외부 데이터랑 연동할 수도 있으니까)
그리고 구현체를 세개 만든다.
- 메모리 회원 저장소, 
- 디비 회원 저장소, 
- 외부 시스템 연동 회원 저장소를 만들어
위에 세가지 중 무엇으로 할 지 정해지지 않았으니 제일 간단하게 메모리 회원 저장소를 이용하겠다. 그런데 메모리 회원 저장소는 컴퓨터를 껐다가 키면 다 사라진다. 

즉 역할과 구현을 나눈 방법이다. 
</code></pre><blockquote>
<h4 id="회원-클래스-다이어그램">회원 클래스 다이어그램</h4>
<p>인터페이스와 구현체에 대해서 적어둔다. 
실제 서버를 실행하지 않고, 클래스만 분석할 수 있는 것들이다. 
<img src="https://images.velog.io/images/devel_sujin/post/61d9cd87-8a51-4532-8bc5-3c5b65db9194/image.png" alt=""></p>
</blockquote>
<pre><code>memberService 라는 역할을 만들고,  구현 클래스로 memberServiceimpl 를 만든다.

memberRepository 라는 역할을 만들고, 구현 클래스로 memoryMemberRepository,
DbmemberRepository 를 만든다.

위에 대로 코딩하면 된다. </code></pre><p>그런데 구현체(memoryMemberRepository,DbmemberRepository)
같은 경우는 new 해서 서버가 뜰 때 결정되기 때문에 클래스 다이어그램만으로 
판단하기가 어렵다 그래서 객체 다이어그램을 만든다. </p>
<blockquote>
<h4 id="회원-객체-다이어그램">회원 객체 다이어그램</h4>
<p>클라이언트가 실제 인스턴스끼리의 참조를 적어둔다.<br><img src="https://images.velog.io/images/devel_sujin/post/b43c3f52-0663-49c3-91ee-a30f18fd53d1/image.png" alt=""></p>
</blockquote>
<ul>
<li>회원 서비스 : MemberServiceImpl</li>
</ul>
<p>객체 간에 메모리 참조가되는 과정이다. </p>
<h3 id="회원-도메인-설계의-문제점">회원 도메인 설계의 문제점</h3>
<p>이 코드의 설계상 문제점이 무엇일까?
다른 저장소로 변경할 때 ocp 원칙을 잘 준수할까?
dip를 잘 지키고 있을까</p>
<p>의존 관계가 인터페이스 뿐만 아니라 구현까지 모두 의존하는 문제점이 있다. 
주문까지 만들고 나서 문제점과 해결 방안을 설명하겠다. </p>
<blockquote>
<h3 id="주문과-할인-도메인-설계">주문과 할인 도메인 설계</h3>
<p><img src="https://images.velog.io/images/devel_sujin/post/41e836ff-8869-40be-bbfb-a37c5a3d020b/image.png" alt="">
주문을 생성 : 클라이언트는 주문 서비스에 주문 생성을 요청한다. 
회원 조회 : 할인을 위해서는 회원 등급이 필요하다. 그래서 주문 서비스는 회원 저장소에서 회원을 조회
할인 적용 : 주문 서비스는 회원 등급에 따른 할인 여부를 할인 정책에 위임한다. 
주문 결과 반환 : 주문 서비스는 할인 결괄르 포함한 주문 결과를 반환한다.</p>
</blockquote>
<p>실제로는 주문 데이터를 디비에 저장하겠지만, 예제가 너무 복잡해질 수 있어서 생략하고 단순히 주문 결과를 반환!</p>
<p><img src="https://images.velog.io/images/devel_sujin/post/3e930139-421f-4695-9574-6791702c9193/image.png" alt=""></p>
<blockquote>
<h3 id="주문-도메인-클래스-다이어그램">주문 도메인 클래스 다이어그램</h3>
<p><img src="https://images.velog.io/images/devel_sujin/post/09e806a5-d0ae-43e0-9a39-36075b7945b9/image.png" alt=""></p>
</blockquote>
<blockquote>
<h3 id="주문-도메인-객체-다이어그램1">주문 도메인 객체 다이어그램1</h3>
<p><img src="https://images.velog.io/images/devel_sujin/post/991adaca-b481-4e07-ab24-d580c9345bc4/image.png" alt=""></p>
</blockquote>
<blockquote>
<h3 id="주문-도메인-객체-다이어그램2">주문 도메인 객체 다이어그램2</h3>
<p><img src="https://images.velog.io/images/devel_sujin/post/70e34a37-362f-4978-8c8a-a936441938ec/image.png" alt="">]</p>
</blockquote>
<h3 id="새로운-할인-정책-개발">새로운 할인 정책 개발</h3>
<p>갑자기 기획자가 와서 말한다.
고정 할인을 정률 할인으로 정책을 바꿔보자. 고정된 금액(예 1000원) 이 아닌, 
주문 금액에서 10%를 할인해주는 겁니다 ~~
처음부터 고정 할인으로 가면 좋았을 걸.. 그래도 기획자가 </p>
<h3 id="애자일-소프트웨어-개발-선언">애자일 소프트웨어 개발 선언</h3>
<p><a href="https://agilemanifesto.org/iso/ko/manifesto.html">https://agilemanifesto.org/iso/ko/manifesto.html</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[좋은 객체 지향 설계의 5가지 원칙(솔리드)]]></title>
            <link>https://velog.io/@devel_sujin/%EC%A2%8B%EC%9D%80-%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%EC%84%A4%EA%B3%84%EC%9D%98-5%EA%B0%80%EC%A7%80-%EC%9B%90%EC%B9%99%EC%86%94%EB%A6%AC%EB%93%9C</link>
            <guid>https://velog.io/@devel_sujin/%EC%A2%8B%EC%9D%80-%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%EC%84%A4%EA%B3%84%EC%9D%98-5%EA%B0%80%EC%A7%80-%EC%9B%90%EC%B9%99%EC%86%94%EB%A6%AC%EB%93%9C</guid>
            <pubDate>Mon, 22 Feb 2021 04:26:07 GMT</pubDate>
            <description><![CDATA[<p>좋은 자바 개발자가 되기 위해서는 원칙을 우습게 생각해서는 안된다!</p>
<p>모든 관계에 있어서 약속이 중요하듯. 객체 지향을 함에 있어서 이렇게 하자는 약속들이 있다고 한다. </p>
<p>같이 알아보고 좋은 자바 개발자가 되자!!! </p>
<h1 id="solid">SOLID</h1>
<p>클린코드로 유명한 로버트 마틴이 좋은 객체 지향 설계의 5가지 원칙을 정리해주셨다. </p>
<h2 id="srp-단일-책임-원칙">SRP 단일 책임 원칙</h2>
<p>(Single responsibility principle) </p>
<p>한 클래스는 하나의 책임만 가져야한다.는 의미인데, 하나의 책임이 굉장히 모호하다..
클 수도 있고, 작을 수도 있다. 문맥과 상황에 따라 다르다. </p>
<p>어떻게 하면 설계를 잘할 수 있을까?</p>
<h3 id="중요한-기준은-변경이다">중요한 기준은 변경이다.</h3>
<p>변경이 있을 때 파급효과가 적으면 단일 책임 원칙을 잘 따른 것이라고 본다. </p>
<p>UI  하나를 변경하는데 sql코드부터 다 고치면 이건 잘못된 것이다. 
계층이 나뉘어 있는 것도 단일 책임 원칙을 따르기 위해서다.</p>
<p>책임을 적절하게 잘 나눠야 한다. </p>
<hr>
<h2 id="ocp-개방--폐쇄-원칙">OCP 개방- 폐쇄 원칙</h2>
<p>(open/closed principle)</p>
<p>소프트웨어 요소는 확장에는 열려있고 변경에는 닫혀있어야 한다. 이게 무슨 이상한 소리인가
확장을 하려면 당연히 기존 코드를 변경해야하지 않을까</p>
<h3 id="다형성을-활용하면-가능하다">다형성을 활용하면 가능하다</h3>
<p>인터페이스를 구현한 새로운 클래스를 하나 만들어서 새로운 기능을 구현하는 건 변경이 아니다. </p>
<p>지금까지 배운 역할과 구현의 분리를 생각해보자. </p>
<p><img src="https://images.velog.io/images/devel_sujin/post/c4ec7449-9c21-42ef-9a25-d344ddc07c23/image.png" alt=""></p>
<h3 id="문제점도-있다">문제점도 있다.</h3>
<ul>
<li>MemberService 클라이언트가 구현 클래스를 직접 선택한다.<ul>
<li>MemberRepository m = new MemoryMemberRepository(); // 기존 코드</li>
<li>MemberRepository m = new JdbcMemberRepository()l // 변경 코드</li>
</ul>
</li>
</ul>
<p>구현 객체를 변경하려면 클라이언트 코드를 변경해야한다. 
분명 다형성을 사용했지만, OCP 원칙을 지킬 수 없다. 왜냐 기존 코드를 변경하기 때문이다.
이것을 해결하려면 객체를 생성하고 연관관계를 맺어주는 별도의 조립, 설정자가 필요하다!
이게 바로 스프링 컨테이너가 해주는 것이다. </p>
<hr>
<h2 id="lsp-리스코프-치환-원칙">LSP 리스코프 치환 원칙</h2>
<p>(Liskov substitution principle)</p>
<p>어떤 인터페이스가 있다. 즉 구현체가 있다. 자동차 인터페이스가 있다. 
그럼 악셀을 구현해야한다. 악셀을 밟으면 앞으로 가야한다. 
그런데 악셀을 밟으면 뒤로 갈수도 있지 않나</p>
<p>그러면 어떻게 믿고 악셀을 밟을 수 있는가 그래서 우리끼리 약속을 한다.
자동차 인터페이스 엑셀은 앞으로 가는 기능이다. 뒤로 가게 구현하면 안된다. 라고!</p>
<hr>
<h2 id="isp-인터페이스-분리-원칙">ISP 인터페이스 분리 원칙</h2>
<p>(Interface segregation principle)</p>
<p>특정 클라이언트를 위한 인터페이스 여러개가 범용 인터페이스 하나보다 낫다는 의미이다. </p>
<ul>
<li>자동차 인터페이스 : 운전 인터페이스, 정비 인터페이스로 분리한다.</li>
<li>사용자 인터페이스 : 운전자 클라이언트, 정비사 클라이언트로 분리한다. </li>
</ul>
<p>분리하게 되면 정비 인터페이스 자체가 변해도 운전자 클라이언트에는 영향이 없다. 
인터페이스가 명확해지고 대체 가능성이 높아진다. </p>
<hr>
<h2 id="dip-의존-관계-역전-원칙">DIP 의존 관계 역전 원칙</h2>
<p>(Dependency inversion principle)</p>
<p>프로그래머는 &quot;추상화에 의존해야지, 구체화에 의존하면 안된다.&quot; 
의존성 주입은 이 원칙을 따르는 방법 중 하나이다. </p>
<p>쉽게 얘기해서 구현 클래스에 의존하지말고, 인터페이스에 의존하라는 의미이다. </p>
<p>역할에 의존한다는 말로도 설명할 수 있겠다. </p>
<p>클라이언트가 인터페이스에 의존해야 유연하게 구현체를 변경할 수 있다. 구현체에 의존하게 되면 변경이 
아주 어려워진다. </p>
<p><img src="https://images.velog.io/images/devel_sujin/post/6b78d35c-5a71-4eaf-9ab7-fe34737991d7/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/devel_sujin/post/1e179c0a-7aee-416e-aef4-da5edf30807e/image.png" alt=""></p>
<h3 id="다형성의-한계들을-스프링과-함께-극복해보자">다형성의 한계들을 스프링과 함께 극복해보자.</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[스프링의 탄생]]></title>
            <link>https://velog.io/@devel_sujin/%EC%8A%A4%ED%94%84%EB%A7%81%EC%9D%98-%ED%83%84%EC%83%9D</link>
            <guid>https://velog.io/@devel_sujin/%EC%8A%A4%ED%94%84%EB%A7%81%EC%9D%98-%ED%83%84%EC%83%9D</guid>
            <pubDate>Mon, 22 Feb 2021 03:39:19 GMT</pubDate>
            <description><![CDATA[<h3 id="ejb-프레임-워크">EJB 프레임 워크</h3>
<p>2000대 초반, EJB라는 기술이 있었다. 
정파의 기술로 사용되었다. 금융권 등등!</p>
<p>당시에 설정에 의한 트렌젝션 관리 , 분산기술(서비스, dao 같은) 을 사용하는게 장점이었다. </p>
<p>orm 기술은 자바 객체를 디비에 저장하기 편하게 만들었다. </p>
<h3 id="단점">단점</h3>
<p>복잡하고 어려운데 느렸다. </p>
<p>컨테이너 한번 돌리는데 진짜 오래 걸렸다.</p>
<p>오죽 힘들었으면, 
POJO - plan old java object 라는 말도 나왔다. </p>
<p>아래 불타는 사람들은 선배 개발자들..
<img src="https://images.velog.io/images/devel_sujin/post/6745b05f-4d75-41a5-b656-02dbde8b2b87/image.png" alt=""></p>
<h3 id="이렇게는-안되겠어-ejb에-빡친-개발자들">이렇게는 안되겠어, EJB에 빡친 개발자들</h3>
<p><img src="https://images.velog.io/images/devel_sujin/post/6a653e7f-c131-4bda-a96c-5ba79571b86e/image.png" alt="">
2002년에 로드 존슨이라는 사람이 책을 출간.</p>
<p>EJB없이도 충분히 고품질의 확장 가능한 애플리케이션을 개발할 수 있음을 보여준다. 
예제를 30,000라인 이상으로 작업했다.. </p>
<p>그러자 다른 개발자들이 예제를 실제 자기 서비스에 도입해서 쓴다. 
그래서 이 상황을 봤던 유겐 휠러, 얀 카로프 라는 사람이 존슨에게 오픈 소스 프로젝트를 제안했다. </p>
<p>스프링 이름은 전통적인 J2EE <strong>겨울을 넘어 새로운 시작</strong>이라는 뜻으로 지었다. </p>
<p>위의 두 개발자는 회사도 나와서 새로 회사를 만들고 이 프로젝트를 했다고 전해진다. </p>
<hr>
<p>저녁에 퇴근하고 와서 사용하기 쉽게 하이버네이트를 만들었다. 
<img src="https://images.velog.io/images/devel_sujin/post/303b788a-47cd-4e24-afa9-28997fd2c9aa/image.png" alt=""></p>
<p>그 이후에 EJB 회사에서 자신들의 기술보다 하이버 네이트가 더 많이 사용된다는 것을 인정하고
하이버 네이트를 만든 개발자들 데려와서 거의 하이버 네이트를 복붙하듯 만든 기술이 
바로 jpa 이다.</p>
<p><img src="https://images.velog.io/images/devel_sujin/post/158e76d4-4729-42c5-b6b8-b7057e947ec6/image.png" alt=""></p>
<h3 id="스프링-역사">스프링 역사</h3>
<p><img src="https://images.velog.io/images/devel_sujin/post/320b809a-dbe1-4f28-9fde-8fec0e72e163/image.png" alt=""></p>
<p>스프링은 서버를 톰캣을 다운받아서~ 따로 띄워줘야 하는데 그것들이 어려웠다. 
농담으로 예전에 스프링은 설정이 절반이다라는 말이 있었다 .</p>
<h3 id="스프링-생태계">스프링 생태계</h3>
<p>스프링은 여러가지 기술의 모음이다.</p>
<p><img src="https://images.velog.io/images/devel_sujin/post/da8e0446-1f6b-4cd1-9b20-25795bdea385/image.png" alt=""></p>
<p>스프링 데이터 : crud 를 편리하게 관리하게 해준다. 
스프링 rest docs : api 문서화를 편리하게 해준다. </p>
<h3 id="스프링-프레임워크">스프링 프레임워크</h3>
<p>핵심 기술 : 스프링 DI 컨테이너, AOP, 이벤트, 기타
웹 기술 : 스프링 mvc, 스프링 webFlux
데이터 접근 기술 : 트랜잭션, jdbc, orm xml 지원
기술 통합 : 캐시, 이메일, 원격접근, 스케줄링
테스트 : 스프링 기반 테스트 지원
언어 : 코틀린, 그루비
최근에는 스프링 부트를 통해서 스프링 프레임 워크의 기술들을 편리하게 사용한다. </p>
<h3 id="스프링-부트">스프링 부트</h3>
<p>스프링을 편리하게 사용할 수 있도록 지원한다. 최근에는 기본으로 사용한다. </p>
<ul>
<li>단독으로 실행할 수 있는 스프링 애플리케이션을 쉽게 생성한다. 
  톰캣 같은 웹 서버를 내장해서 별도의 웹 서버를 설치하지 않아도 된다. 
  예전에는 스프링 가지고 프로젝트를 하려면 빌드하고, 톰캣 서버를 별도로 설치하고, 특정 위치에
  넣고, 띄우고 아주 복잡했는데 스프링 부트가 빌드하고 서버 띄워주는 것 까지 다 해준다. </li>
</ul>
<ul>
<li><p>손쉬운 빌드 구성을 위한 starter 종속성을 제공한다. 
  여러 라이브러리를 써야했는데, 라이브러리를 여러개 한꺼번에 가져와준다.</p>
</li>
<li><p>스프링과 3rd parth 라이브러리 자동 구성
  라이브 러리들과 스프링의 버전을 관리 해준다.  </p>
</li>
</ul>
<ul>
<li><p>메트릭, 상태 확인, 외부 구성 같은 프로덕션 준비 기능 제공
  운영환경에서 제일 중요한 건 모니터링. 모니터링 기능을 제공해준다. </p>
</li>
<li><p>관례에 의한 간결한 설정
  디폴트 설정 값이 있고, 필요한 부분만 수정하면 된다. </p>
</li>
</ul>
<h3 id="스프링-단어">스프링 단어</h3>
<ul>
<li><p>스프링이라는 단어는 문맥에 따라 다르게 사용된다.</p>
</li>
<li><p>스프링 DI 컨테이너 기술</p>
</li>
<li><p>스프링 프레임 워크</p>
</li>
<li><p>스피링 부트, 스프링 프레임워크 등을 모두 포함한 스프링 생태계</p>
</li>
</ul>
<h1 id="스프링을-왜-만들었는가">스프링을 왜 만들었는가?</h1>
<p>이 기술의 핵심 컨셉은 무엇인가</p>
<ul>
<li>자반 언어 기반의 프레임 워크이다.
자바 큰 특징 : 객체 지향 언어
스프링은 객체 지향 언어가 가진 강력한 특징을 살려내는 프레임 워크
스프링은 <strong>좋은 객체 지향 애플리케이션을 개발</strong>할 수 있게 도와주는 프레임 워크이다!!!</li>
</ul>
<h3 id="객체-지향의-특징">객체 지향의 특징</h3>
<ul>
<li><p>추상화</p>
</li>
<li><p>캡슐화</p>
</li>
<li><p>상속화</p>
</li>
<li><p>객체들의 모임으로 파악하고자 함. 객체는 메세지를 주고받고 데이터를 처리할 수 있다. </p>
</li>
<li><p>객체 지향 프로그래밍은 프록램을 유연하고 변경이 용이하게 만들기 때문에 대규모 소프트웨어 개발에 많이 사용된다. </p>
</li>
</ul>
<h2 id="유연하고-변경이-용이하다">유연하고 변경이 용이하다?</h2>
<p>마치 키보드 마우스를 바꾸듯이. 컴포넌트를 쉽고 유연하게 변경하면서 개발할 수 있는 방법이다. </p>
<h3 id="다형성">다형성</h3>
<p>세상을 역할과 구현으로 구분한다면</p>
<p><img src="https://images.velog.io/images/devel_sujin/post/f42ea8a3-f84c-411b-91e9-f7b58562ed32/image.png" alt=""></p>
<p>운전자와 자동차의 역할을 나누고, 자동차를 아반떼 테슬라 k3같이 다른 모델로 구현했다고 하자</p>
<p>자동차가 바뀌었다고 해서 운전자에게 영향이 있나? 아니다 
운전면허가 있으면 할 수 있다. </p>
<p>그럼 자동차는 왜 여러 형태로 구현되었는가 바로 운전자 때문이다. 
*<em>클라이언트에 영향을 주지 않고 새로운 기능을 제공할 수 있다. 
*</em></p>
<p><img src="https://images.velog.io/images/devel_sujin/post/68da5473-1447-4258-8943-dae98585e6d6/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/devel_sujin/post/90435215-832c-4872-b744-89ac0555f05e/image.png" alt=""></p>
<p>객체를 설계할 때 역할과 구현을 분명하게 나눈다. 
 역할 : 인터페이스
 구현 : 인터페이스를 구현한 클래스, 구현 객체</p>
<p> 구현보다 인터페이스가 먼저이다.</p>
<p><img src="https://images.velog.io/images/devel_sujin/post/fb8f49b6-19bb-440b-a645-fa596b0b11c2/image.png" alt=""></p>
<h3 id="객체를-협력이라는-관계부터-생각한다">객체를 협력이라는 관계부터 생각한다.</h3>
<p>혼자 있는 객체는 없다. 
클라이언트 : 요청
서버 : 응답
수 많은 객체 클라이언트와 객체 서버는 서로 협력 관계를 가진다. </p>
<p><img src="https://images.velog.io/images/devel_sujin/post/5792baae-0b28-4a79-adcd-275f11cfbf3b/image.png" alt=""></p>
<p>멤버 서비스는 멤버 리포지토리에 의존한다(알고있다) 
그런데 멤버 리포지토리에 메모리 랑 jdbc 레포지토리를 할당한다. </p>
<p><img src="https://images.velog.io/images/devel_sujin/post/10cec6ff-3c91-48da-adca-eb91508ca199/image.png" alt=""></p>
<h3 id="다형성의-본질">다형성의 본질</h3>
<ul>
<li>인터페이스를 구현한 객체 인스턴스를 실행 시점에서 유연하게 변경할 수 있다. </li>
<li>클라이언트를 변경하지 않고, 서버의 기능을 유연하게 변경할 수 있다. </li>
</ul>
<h3 id="인터페이스를-안정적으로-설계하는게-중요하다">인터페이스를 안정적으로 설계하는게 중요하다.</h3>
<p>인터페이스(역할) 자체가 변하면 클라이언트, 서버 모두 큰 변경이 발생한다. 
자동차를 비행기로 변경해야 한다면,? 연극을 하는데 대본 자체가 바뀐다면?
다시 처음부터 설계 해야한다. </p>
<h2 id="스프링과-객체-지향">스프링과 객체 지향</h2>
<ul>
<li>다형성이 가장 중요하다.</li>
<li>스프링은 다형성을 극대화해서 이용할 수 있게 도와준다. </li>
<li>스프링에서 이야기하는 제어의 역전IoC, 의존관계 주입 DI은 다형성을 활용해서 역할과 구현을 편리하게 다룰 수 있도록 지원한다. </li>
</ul>
<p>스프링을 사용하면 마치 레고 블럭을 조립하던지, 연극에 배우를 변경하듯이. 사용할 수 있게 된다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프록시 캐시]]></title>
            <link>https://velog.io/@devel_sujin/%ED%94%84%EB%A1%9D%EC%8B%9C-%EC%BA%90%EC%8B%9C</link>
            <guid>https://velog.io/@devel_sujin/%ED%94%84%EB%A1%9D%EC%8B%9C-%EC%BA%90%EC%8B%9C</guid>
            <pubDate>Sun, 21 Feb 2021 04:25:39 GMT</pubDate>
            <description><![CDATA[<h3 id="원-서버-직접-접근">원 서버 직접 접근</h3>
<p><img src="https://images.velog.io/images/devel_sujin/post/e7a955f6-eeba-4291-b001-18cc0251689e/image.png" alt=""></p>
<p>위에 보면 웹 브라우저 3개가 있다. 
만약 이미지를 다운 받으려고 하면, 서버에서 다른 작업을 하는 동안 기다려야하기 때문에
각각 0.5초 씩 기다려야한다. </p>
<h4 id="프록시-캐시-도입">프록시 캐시 도입</h4>
<p><img src="https://images.velog.io/images/devel_sujin/post/a4840af4-0bf7-4afd-a331-82c660482f59/image.png" alt=""></p>
<p> 미국에 있는 원서버 입장에서는 사용자가 느끼기에 너무 느릴것이라 생각한다. 
 그래서 한국 어딘가에 프록시 캐시 서버를 두고, 웹 브라우저가 프록시 캐시 서버를 접근하게끔 만든다. 
 유튜브도 그 예다. 
 사람들이 많이 안보는 동영상을 보면, 로딩 속도가 느리다. 
 그런데 사람들이 많이 보는 동영상을 보면 로딩 속도가 빠르다. 
 이미 한국 프록시 서버에 다운받아져 있기 때문이다.</p>
<p> <img src="https://images.velog.io/images/devel_sujin/post/325ffced-f142-4e52-84b6-5242d1238429/image.png" alt=""></p>
<h3 id="확실한-캐시-무효화-응답">확실한 캐시 무효화 응답</h3>
<ul>
<li>cache-control : no -cache, no -store, must-revalidate</li>
<li>Pragma : no - cache</li>
</ul>
<p>위에 있는 캐시 지시어를 다 넣어준다. </p>
<p><strong>no -cache</strong>
데이터는 캐시해도 되지만, 항상 원 서버에 검증하고 사용</p>
<p><img src="https://images.velog.io/images/devel_sujin/post/914f1e77-9570-4c20-b459-6a970398b54c/image.png" alt=""></p>
<p>만약 네트워크가 단절되면? 옛날 거라도 보여준다. 
<img src="https://images.velog.io/images/devel_sujin/post/06d543e7-0d2a-40cc-afc1-1f140cb9ed93/image.png" alt=""></p>
<p><strong>no -store</strong>
데이터에 민감한 정보가 있기 때문에 저장하지 마세요.</p>
<p><strong>must-revalidate</strong>
캐시 만료후 최초 조회시 원 서버에 검증해야한다.
원서버 접근 실패시 반드시 오류가 발생해야한다. </p>
<p>통장 잔고와 같은 것들을 처리할 때 이런 문제가 발생하면 504 에러를 보내야한다. 
<img src="https://images.velog.io/images/devel_sujin/post/79eab81c-55b8-49cc-8a26-33e7bf40d1b0/image.png" alt=""></p>
<p>Pragma : no - cache
http 1.0 하위 호환</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[쿠키(먹는 쿠키 아님)]]></title>
            <link>https://velog.io/@devel_sujin/%EC%BF%A0%ED%82%A4%EB%A8%B9%EB%8A%94-%EC%BF%A0%ED%82%A4-%EC%95%84%EB%8B%98</link>
            <guid>https://velog.io/@devel_sujin/%EC%BF%A0%ED%82%A4%EB%A8%B9%EB%8A%94-%EC%BF%A0%ED%82%A4-%EC%95%84%EB%8B%98</guid>
            <pubDate>Sat, 20 Feb 2021 10:11:14 GMT</pubDate>
            <description><![CDATA[<h3 id="쿠키">쿠키</h3>
<p>쿠키를 사용할 때 아래와 같은 두가지 쿠키를 사용한다. </p>
<ul>
<li>Set Cookie : 서버에서 클라이언트로 쿠키를 전달(응답)</li>
<li>Cookie : 클라이언트가 서버에서 받은 쿠키를 저장하고, http 요청시 서버로 전달한다.</li>
</ul>
<p>아래와 같은 예시를 통해 이해를 돕겠다. </p>
<h3 id="쿠키를-미사용-했을-경우">쿠키를 미사용 했을 경우</h3>
<p><img src="https://images.velog.io/images/devel_sujin/post/0a16d647-cdb5-49f5-ae8a-c1fb574df20d/image.png" alt=""></p>
<p>처음 웹 브라우저에서 welcome 페이지에 들어왔고, 서버가 안녕하세요 손님이라고 대답했다.</p>
<p><img src="https://images.velog.io/images/devel_sujin/post/4c451418-2bdb-4b39-abd1-0246953ee6b4/image.png" alt=""></p>
<p>페이지에서 홍길동이 로그인 했을 경우 서버가 클라이언트에게 홍길동이 로그인되었다는 메세지를 보낸다. 
그리고 아래와 같이 다시 welcome 페이지에 들어갔다. </p>
<p><img src="https://images.velog.io/images/devel_sujin/post/ee2bec85-c999-45b1-8cd4-8f09e27767aa/image.png" alt=""></p>
<p>위에서 로그인을 했기 때문에 안녕하세요 홍길동을 할 줄 알았는데, 
안녕하세요 손님이라고 서버가 메세지를 보냈다. 왜일까?
위에 보면 웹 브라우저가 서버에게 
get/ welcome http/1.1 이렇게 보냈기 때문이다. 
이 요청이 홍길동인지 아닌지 서버는 알 수 없다. 
그리고 http 는 무상태 프로토콜이기 때문에 클라이언트 - 서버가 요청을 주고 받으면 연결이 끊어진다. 
이 내용은 초기에 다룬 적이 있다. 자세한 개념은 아래 사진에 다시 첨부하겠다.</p>
<p><img src="https://images.velog.io/images/devel_sujin/post/e41a15cf-a31b-49e9-b686-a3e62ac6fc78/image.png" alt=""> </p>
<h3 id="그렇다면-쿠키를-사용하지-않고도-사용자를-기억하게-할-대안은-없는가">그렇다면 쿠키를 사용하지 않고도 사용자를 기억하게 할 대안은 없는가?</h3>
<p><img src="https://images.velog.io/images/devel_sujin/post/4c6e5eb7-40da-4732-ac40-a73899fa77e4/image.png" alt=""></p>
<pre><code>
있다. 유저 정보를 계속해서 보내면 된다. 
하지만 모든 요청과 링크에 사용자 정보를 포함하게 되면 uri가 길어지기 때문에 개발도 힘들어지고
사용자의 정보가 노출되는 문제도 생긴다. </code></pre><h3 id="쿠키-사용">쿠키 사용</h3>
<p>웹 브라우저에서 홍길동으로 로그인 정보를 서버에 보내면
서버는 Set-Cookie 에 홍길동 을 넣어서 보내고 로그인 되었다는 메세지를 보낸다. 
그러면 웹 브라우저 내에 있는 쿠키 저장소에 셋 쿠키 내용을 저장한다. </p>
<p><img src="https://images.velog.io/images/devel_sujin/post/c284443b-e56a-4a37-9daf-73b9d2488aa4/image.png" alt=""></p>
<p>쿠키는 모든 요청에 쿠키 정보가 자동으로 포함된다. </p>
<p><img src="https://images.velog.io/images/devel_sujin/post/9520b801-f7b2-4f36-96f4-028da46e5900/image.png" alt=""></p>
<p>그런데 쿠키에 유저 정보가 모든 요청에 포함되면 보안이 좋지 않기 때문에</p>
<p>서버에서 아래와 같은 사항들을 
지정을 한다. 
set-cookie :<strong>sessionid</strong>-abcde1234 ; <strong>expires</strong>= Sat 날짜; <strong>path=</strong>/; <strong>domain</strong>= google.com ;<strong>secure</strong></p>
<h3 id="sessionid">sessionid</h3>
<p>유저 정보를 그대로 내리면 위험하기 때문에 디비에 세션 키를 저장헤서 세션 아이디를 만들고 그 세션에 대한 기한을 지정한다. 그리고 경로에 대한 허용도 지정한다. secure는 보안에 관련된 것을 지정하는 거구나. </p>
<h4 id="쿠키-사용처">쿠키 사용처</h4>
<ul>
<li><p>사용자 로그인 세션 관리를 할 때 사용한다. </p>
</li>
<li><p>광고 정보 트래킹할 때 쓰임. ( 이 웹 브라우저를 사용하는 사람은 이런 정보를 보는구나를 알 수 있다.)</p>
</li>
<li><p>단점
  네트워크 트래픽 추가 유발
  그래서 최소한의 (세션 아이디, 인증 토큰에 관련된 정보) 정도만 사용한다. </p>
<ul>
<li>서버에 전송하지 않고 클라이언트에 이와 같은 정보들을 들고 사용하고 싶으면 <strong>웹 스토리지</strong>를 참고한다. </li>
</ul>
<h2 id="보안에-민감한-신용카드-주민번호-등등은-절대-저장하지말-것">보안에 민감한 신용카드, 주민번호 등등은 절대! 저장하지말 것</h2>
</li>
</ul>
<h3 id="expires-max--age">Expires, max- age</h3>
<p> <strong>expires</strong>= Sat 날짜; 
 쿠키가 계속해서 있으면 보안상 문제가 있을 수 있으니 기한을 정해두고 만료가 되면 자동으로 삭제한다.</p>
<p> <strong>max-age</strong>= 3600초; 
 초단위로 지정 가능, 0이나 음수를 지정하면 쿠키가 자동으로 삭제된다. </p>
<h4 id="쿠키-종류">쿠키 종류</h4>
<ul>
<li>세션 쿠키 : 만료 날짜를 생략하면 브라우저 종료시까지만 유지된다. </li>
<li>영속 쿠키 : 만료 날짜를 입력하면 해당 날짜까지 유지된다. </li>
</ul>
<h3 id="도메인-domain">도메인 Domain</h3>
<p> 쿠키를 생성한 웹 사이트가 아닌, 다른 아무사이트에 들어갈 때도 이 쿠키가 들어가면 어떡하나.
 웹 페이지마다 아이디와 비밀번호가 다를 수도 있는데. 그래서 이 쿠키가 사용될 도메인을 지정해줘야한다.</p>
<ul>
<li>명시 : 명시한 문서 기준 도메인 + 서브 도메인 포함<pre><code>   ex) domain= google.com 이렇게 지정해서 쿠키를 생성하면
       dev.google.com
      google.com     모두 쿠키를 사용할 수 있다.</code></pre></li>
</ul>
<ul>
<li>생략 : 생략하면 생성된 웹 도메인에서만 쿠키가 사용가능하고, 서브 도메인에는 사용이 불가능하다. </li>
</ul>
<p> 첫번째로 도메인으로 거르고, 두번째로 경로로 거른다. </p>
<h3 id="path-경로">Path 경로</h3>
<p> 경로를 지정해주면 이 경로를 포함한 하위 경로 페이지만 쿠키가 접근 가능하다. 
 path=/root 로 지정한다. 
 예)</p>
<ul>
<li>path=/home 으로 지정한다. </li>
<li>home/level1 -&gt; o</li>
<li>home/level1/level2 -&gt; o</li>
<li>hello -&gt; x </li>
</ul>
<h3 id="보안-secure-httponly-samesite">보안 Secure, HttpOnly, SameSite</h3>
<p> 보안은 크게 세가지가 있다. </p>
<p><strong>1) Secure</strong>
    원래 쿠키는 http 와 https 를 구분하지 않고 전송한다. 그런데 secure를 넣으면 https 일때만 
    쿠키를 전송한다. 
<strong>2) HttpOnly, **
    자바스크립트에서도 쿠키에 접근이 가능한데, 이것을 막는다. 오로지 http 에서만 접근이 가능하게해서 xss 공격을 방지한다. 
**3) SameSite</strong>
    요청하는 도메인이랑 쿠키에 설정된 도메인이 같을 경우만 쿠키를 전송하게 한다. 이건 기능이 적용된지 얼마 안돼서 사용하려면 브라우저에서 확인해보는 것이 좋다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[특별한 정보]]></title>
            <link>https://velog.io/@devel_sujin/%ED%8A%B9%EB%B3%84%ED%95%9C-%EC%A0%95%EB%B3%B4</link>
            <guid>https://velog.io/@devel_sujin/%ED%8A%B9%EB%B3%84%ED%95%9C-%EC%A0%95%EB%B3%B4</guid>
            <pubDate>Sat, 20 Feb 2021 09:25:32 GMT</pubDate>
            <description><![CDATA[<h3 id="host--요청한-호스트-정보도메인">host : 요청한 호스트 정보(도메인)</h3>
<p>필수 헤더이다. 하나의 서버가 여러 도메인을 처리해야할 때가 있다. 그 때 구분해주는 것이다. </p>
<h3 id="location--페이지-리다이렉션">Location : 페이지 리다이렉션</h3>
<p><img src="https://images.velog.io/images/devel_sujin/post/70bfd6a0-8e1b-4534-890e-b6d0cace8ed7/image.png" alt=""></p>
<h3 id="allow--허용-가능한-http-메소드">Allow : 허용 가능한 http 메소드</h3>
<p>405 (method not allowed)
get,post, put 메소드에 한정해서 허용을 했는데,
그 외에 다른 메소드를 사용하려고 하면 발생하는 오류가 405 에러이다.
사실 서버에서 많이 구현되어 있는 기능은 아니다.  </p>
<h3 id="retry-after--유저-에이전트가-다음-요청을-하기까지-기다려야-하는-시간">Retry-After : 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간</h3>
<p>503 ( service unvaliable) 서비스가 언제까지 불능인지를 알려줄 수 있다. 
Retry-after : 날짜를 표기할 수도 있고, 초단위로 표기할 수도 있다. </p>
<h3 id="인증">인증</h3>
<p>Authoriaztion : 클라이언트에서 인증 정보를 서버에 전달하는 용도로 사용하는 것이다. 
        예) Basic  xxxxxxxxxxxxxxx
        오쓰 인증 공부해보기 
WWW-Authenticate : 리소스에 접근시 필요한 인증 방법을 정의한다. 
    만약에 접근을 했는데, 제대로 인증이 안되거나 권한이 없는 것 같아. 
    그러면 401 Unauthorized 응답과 함께 사용한다. 
        예)  WWW-Authenticate : Newauth realm=&quot;apps&quot;, type =1. tirle = Login to
        위와 같은 정보를 참고해서 만들어 ~ 라고 보내준다. </p>
]]></description>
        </item>
    </channel>
</rss>