<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>재미로 기록하자</title>
    <link>https://be-student.tistory.com/</link>
    <description>하루하루 재밌게 배웠던 내용을 기록하는 블로그입니다</description>
    <language>ko</language>
    <pubDate>Mon, 22 Jun 2026 19:36:12 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>be-student</managingEditor>
    <item>
      <title>좋은 모니터링을 해보자</title>
      <link>https://be-student.tistory.com/115</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;이 글을 쓰게 된 배경&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에 회사에서 소소하지는 않았던 사실상 전면 장애가 났었는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정에서 모두가 확인할 수 있는 모니터링 대시보드를 만들고, 여기만 보자는 의견을 내게 되었고, 미팅을 주최해 결국 모니터링 대시보르를 만들었던 경험을 한 번쯤 정리해 두면 앞으로도 도움이 많이 될 것 같아서 이번에 정리를 해두려고 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전면 장애가 나면 보통 이렇게 대응을 하고, 후속 처리를 하게 됩니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 먼저 장애가 난 원인을 파악합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 현재 서버의 에러 로그를 확인합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분의 경우에 여기서 모든 것이 드러나는 경우가 많습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 여기서 잡히지 않는다면 그때부터는 이제 장애의 원인을 확인해봅니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 api의 응답이 없는지, 혹은 엄청 느려졌는지, 아니면 전체적으로 다 문제인지를 확인합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 api 만 문제라면 그 api 가 왜 느려졌는지 확인해 봅니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체적으로 문제라면 jvm thread, gc, spring active thread 등등 기반 메트릭을 확인해 봅니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 원인을 파악하고 나면 그에 따른 적절한 조치를 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후속 대응으로는 이런 것들을 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장애의 원인 파악 후 재발방지 대책을 세웁니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹은 원인 파악을 하는 과정에서 힘들었던 것들을 보완합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에 제가 진행했던 것들은 영향범위를 조금 더 편하게 확인하기 위해서 했던 작업입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;아이디어 제시&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 내용은 제가 실제로 슬랙에서 아이디어를 제시했던 내용인데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;오늘&amp;nbsp;보아하니&amp;nbsp;홈택스가&amp;nbsp;한번&amp;nbsp;장애가&amp;nbsp;나면&amp;nbsp;그&amp;nbsp;이후에&amp;nbsp;회복하는&amp;nbsp;것이&amp;nbsp;되게&amp;nbsp;늦는&amp;nbsp;것&amp;nbsp;같더라고요&lt;br /&gt;결제&amp;nbsp;성공률과&amp;nbsp;같은&amp;nbsp;비즈니스단에서&amp;nbsp;인지&amp;nbsp;가능한&amp;nbsp;형태의&amp;nbsp;지표가&amp;nbsp;있으면&amp;nbsp;좋을&amp;nbsp;것&amp;nbsp;같아요&lt;br /&gt;&lt;br /&gt;이&amp;nbsp;작업의&amp;nbsp;goal&amp;nbsp;은&amp;nbsp;#silo-tax-inflow-dev&amp;nbsp;나&amp;nbsp;#silo-conversion-boost-dev&amp;nbsp;채널&amp;nbsp;or&amp;nbsp;진짜&amp;nbsp;크리티컬 한&amp;nbsp;알림만&amp;nbsp;모아두는&amp;nbsp;채널로&amp;nbsp;알림을&amp;nbsp;줘서&amp;nbsp;누구든&amp;nbsp;바로&amp;nbsp;점검이나&amp;nbsp;인텔리를&amp;nbsp;off&amp;nbsp;해야 하는&amp;nbsp;상황이라는&amp;nbsp;것을&amp;nbsp;알&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;것입니다&lt;br /&gt;&lt;br /&gt;아래는&amp;nbsp;숨은&amp;nbsp;환급액&amp;nbsp;찾기를&amp;nbsp;예시로&amp;nbsp;합니다&lt;br /&gt;&lt;br /&gt;&amp;nbsp;숨은&amp;nbsp;환급&amp;nbsp;찾기&amp;nbsp;서비스&amp;nbsp;스크래핑&amp;nbsp;성공률&amp;nbsp;(가드레일&amp;nbsp;지표&amp;nbsp;예시&amp;nbsp;:&amp;nbsp;고객이&amp;nbsp;인지하는&amp;nbsp;스크래핑&amp;nbsp;성공률이&amp;nbsp;70%&amp;nbsp;이하가&amp;nbsp;되면&amp;nbsp;안 된다)&lt;br /&gt;&amp;nbsp;숨은&amp;nbsp;환급액&amp;nbsp;찾기&amp;nbsp;결제&amp;nbsp;후&amp;nbsp;신고&amp;nbsp;성공률&amp;nbsp;(가드레일&amp;nbsp;지표&amp;nbsp;예시&amp;nbsp;:&amp;nbsp;고객이&amp;nbsp;마지막&amp;nbsp;신고를&amp;nbsp;하는&amp;nbsp;성공률이&amp;nbsp;70%&amp;nbsp;이하가&amp;nbsp;되면&amp;nbsp;안 된다)&lt;br /&gt;&amp;nbsp;숨은&amp;nbsp;환급액&amp;nbsp;찾기&amp;nbsp;결제&amp;nbsp;성공률이&amp;nbsp;N%&amp;nbsp;미만이다&amp;nbsp;(가드레일&amp;nbsp;지표&amp;nbsp;예시&amp;nbsp;:&amp;nbsp;결제&amp;nbsp;성공률이&amp;nbsp;75%&amp;nbsp;이하가&amp;nbsp;되면&amp;nbsp;안 된다)&lt;br /&gt;&amp;nbsp;숨은&amp;nbsp;환급액&amp;nbsp;찾기&amp;nbsp;시작&amp;nbsp;화면부터&amp;nbsp;마지막&amp;nbsp;신고까지&amp;nbsp;전체&amp;nbsp;퍼널&amp;nbsp;통과율&amp;nbsp;(가드레일&amp;nbsp;지표&amp;nbsp;:&amp;nbsp;신고&amp;nbsp;횟수&amp;nbsp;N회&amp;nbsp;/&amp;nbsp;인트로를&amp;nbsp;본&amp;nbsp;횟수&amp;nbsp;M회&amp;nbsp;*&amp;nbsp;100&amp;nbsp;가&amp;nbsp;20%&amp;nbsp;이하가&amp;nbsp;되면&amp;nbsp;안 된다)&lt;br /&gt;&amp;nbsp;숨은&amp;nbsp;환급액&amp;nbsp;찾기&amp;nbsp;시작&amp;nbsp;화면부터&amp;nbsp;결제까지&amp;nbsp;전체&amp;nbsp;퍼널&amp;nbsp;통과율&amp;nbsp;(가드레일&amp;nbsp;지표&amp;nbsp;:&amp;nbsp;결제&amp;nbsp;횟수&amp;nbsp;N회&amp;nbsp;/&amp;nbsp;인트로를&amp;nbsp;본&amp;nbsp;횟수&amp;nbsp;M회&amp;nbsp;*&amp;nbsp;100&amp;nbsp;가&amp;nbsp;20%&amp;nbsp;이하가&amp;nbsp;되면&amp;nbsp;안 된다)&lt;br /&gt;&amp;nbsp;홈택스&amp;nbsp;평균&amp;nbsp;응답&amp;nbsp;시간이&amp;nbsp;N초&amp;nbsp;이상이다&amp;nbsp;(가드레일&amp;nbsp;지표&amp;nbsp;:&amp;nbsp;홈택스의&amp;nbsp;세금&amp;nbsp;신고&amp;nbsp;화면&amp;nbsp;or&amp;nbsp;중요한&amp;nbsp;화면의&amp;nbsp;응답&amp;nbsp;시간이&amp;nbsp;평균&amp;nbsp;10초가&amp;nbsp;넘으면&amp;nbsp;안 된다)&amp;nbsp;&amp;lt;-&amp;nbsp;이런&amp;nbsp;부분은&amp;nbsp;node&amp;nbsp;or&amp;nbsp;다른&amp;nbsp;팀에서&amp;nbsp;인풋을&amp;nbsp;줘도&amp;nbsp;좋을&amp;nbsp;것&amp;nbsp;같아요&lt;br /&gt;&lt;br /&gt;alert&amp;nbsp;은&amp;nbsp;달면&amp;nbsp;안 되지만&amp;nbsp;&amp;nbsp;필요할&amp;nbsp;것&amp;nbsp;같은&amp;nbsp;지표&amp;nbsp;예시&lt;br /&gt;&amp;nbsp;마지막&amp;nbsp;N분동 안&amp;nbsp;숨은&amp;nbsp;환급액&amp;nbsp;찾기&amp;nbsp;인트로&amp;nbsp;진입자&amp;nbsp;unique&amp;nbsp;count&lt;br /&gt;&amp;nbsp;마지막&amp;nbsp;N분동안&amp;nbsp;숨은&amp;nbsp;환급액&amp;nbsp;찾기&amp;nbsp;결제자&amp;nbsp;unique&amp;nbsp;count&lt;br /&gt;&amp;nbsp;마지막&amp;nbsp;N분동안&amp;nbsp;숨은&amp;nbsp;환급액&amp;nbsp;찾기&amp;nbsp;신고자&amp;nbsp;unique&amp;nbsp;count&lt;br /&gt;alert을&amp;nbsp;달지&amp;nbsp;못하는&amp;nbsp;이유는&amp;nbsp;시간대별&amp;nbsp;편차가&amp;nbsp;훨씬&amp;nbsp;커서&amp;nbsp;알럿이&amp;nbsp;제대로&amp;nbsp;안될&amp;nbsp;것&amp;nbsp;같아요&lt;br /&gt;&lt;br /&gt;현재&amp;nbsp;있는&amp;nbsp;grafana&amp;nbsp;만을&amp;nbsp;보고&amp;nbsp;보고&amp;nbsp;바로&amp;nbsp;판단이&amp;nbsp;가능하도록&amp;nbsp;필요&amp;nbsp;없는&amp;nbsp;것들은&amp;nbsp;없애고,&amp;nbsp;더&amp;nbsp;직관적으로&amp;nbsp;바꾸는&amp;nbsp;작업이&amp;nbsp;필요합니다&lt;br /&gt;이&amp;nbsp;지표&amp;nbsp;설정&amp;nbsp;과정에서&amp;nbsp;인삼,&amp;nbsp;pm, po&amp;nbsp;분들의&amp;nbsp;의견을&amp;nbsp;모아보려고&amp;nbsp;하요&lt;br /&gt;&lt;br /&gt;필요한&amp;nbsp;input&amp;nbsp;은&lt;br /&gt;&amp;nbsp;어떤&amp;nbsp;조건에서는&amp;nbsp;확인용&amp;nbsp;alert를&amp;nbsp;주면&amp;nbsp;좋겠다&lt;br /&gt;&amp;nbsp;어떤&amp;nbsp;정도에서는&amp;nbsp;즉각&amp;nbsp;점검이&amp;nbsp;필요하다는&amp;nbsp;alert&amp;nbsp;를&amp;nbsp;주면&amp;nbsp;좋겠다&lt;br /&gt;라는&amp;nbsp;비즈니스적인&amp;nbsp;지표가&amp;nbsp;필요합니다&amp;nbsp;:인사:&lt;br /&gt;&lt;br /&gt;이&amp;nbsp;부분을&amp;nbsp;진행하는&amp;nbsp;미팅을&amp;nbsp;한번&amp;nbsp;진행해 보면&amp;nbsp;좋을&amp;nbsp;것&amp;nbsp;같은데요&amp;nbsp;참여하실&amp;nbsp;분들은&amp;nbsp;알려주시면&amp;nbsp;초대드릴게요&amp;nbsp;:인사:&lt;br /&gt;&lt;br /&gt;예시가&amp;nbsp;되는&amp;nbsp;송금팀&amp;nbsp;스레드&lt;br /&gt;진짜&amp;nbsp;크리티컬에서&amp;nbsp;즉각&amp;nbsp;대응이&amp;nbsp;필요한&amp;nbsp;알림&amp;nbsp;채널&amp;nbsp;#team-finance-platform-critical&amp;nbsp;예시&lt;br /&gt;사진은&amp;nbsp;모두가&amp;nbsp;보는&amp;nbsp;송금팀&amp;nbsp;grafana&amp;nbsp;스크린샷입니다&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 형태로 아이디어를 내게 되었습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 생각했을 때 현재 서비스에서 가장 큰 문제는 서비스 점검을 걸지 말지에 대한 판단을 오로지 개발자의 말에만 의존해서 하고 있다는 점이었습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 서비스 안 돼요 점검 걸어주세요 -&amp;gt; 점검 걸림&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어 지금 에러 올라와요 -&amp;gt; 점검 안 걸림&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분을 pm의 의견에 따라서&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 당장 결제에 도달하는 사람이 5명 이하니까 평상시보다 결제까지 도달하는 사람이 절반밖에 안 되네요 점검 겁시다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 사전신청을 하는 사람이 몇 명밖에 안되네요 이거는 잠깐 멈춰두고 다시 여는 게 좋을 것 같아요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라는 것을 진행하는 것을 목표로 했습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;미팅을 시작하기 전까지 준비&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제에 대응이 필요한 상황을 2가지로 나누었습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 서비스 전면 장애 상황으로 점검을 걸어야 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 문제가 발생할 수 있는 상황이니 유저를 모으는 마케팅을 잠시 중단해야 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 2가지를 각각 어떤 기준으로 할지는 이번 미팅에서 정하는 것으로 했었죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;미팅의 목표 설정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 점검을 걸지 말지에 대한 판단이 가능한 지표를 정하고, 대략적인 수치를 정해 본다 (대략적인 수치는 운영하면서 바뀔 수 있으니 지표를 정하는 것에 더 집중한다)&lt;br /&gt;2. 유저를 모으는 마케팅 팀이 마케팅을 중지할지 말지에 대해서 간단한 지표를 정해보고, 대략적인 수치를 정해본다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 마케팅팀에서 어떤 지표가 있으면 문제가 되는 특정 마케팅을 탐지할 수 있을지 그 방식을 정해본다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 총 3가지의 목표를 가지고 미팅을 진행하게 되었습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연히 장애 상황에서의 결제 숫자, 결제 성공률, 응답시간 등 문제가 되는 지표들은 미리 준비를 했고요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;합리적인 지표 선택하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 부분은 추가적으로 챙겼으면 좋았을 부분인데, 회의 때 필요하다는 것을 알게 되었던 부분입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스 전체 점검이라는 것은 정말 크리티컬 한 경험이기에, 점검을 걸만큼 크리티컬한 핵심 제품을 선택한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 핵심 제품을 구성하는 필수적인 스텝을 쪼개본다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 스텝들을 어떻게 모니터링할지 결정해 본다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세금 환급이라는 서비스의 경우에는&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 국세청 인증을 한다 (인증)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 국세청의 세금 신고 내역을 스크래핑을 한다 (스크래핑)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 수수료를 결제한다 (결제)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 세금 환급을 신고한다 (신고)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라는 모든 유저가 무조건 지나가게 되는 과정이 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정 중에서 어떤 것을 모니터링할지 중요도를 파악해야 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자는 당연히 1,2,3,4를 모두 봐야 하지만, 마케팅 팀 입장에서는 1,2만을 봐도 충분한 것이죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 이후에 모니터링 지표는 어떻게 만들 수 있을까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희가 사용한 지표들은 다음과 같습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 단순 수량&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1,2,3,4번의 단순 시도 횟수가 특정 숫자보다 작게 N분간 지속되면 알럿&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 1,2,3,4 기능의 성공률이 N% 미만으로 지속되면 알럿&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 1,2,3,4 기능의 응답 시간이 N초 이상이 되면 알럿&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 3가지 케이스에 대해서 알럿을 걸어두고, 이 알럿을 모니터링할 수 있도록 하고 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번에 대해서 알럿을 걸면 당연하지만 하루동안 시간대에 따라 분포가 달라지니 false alert 이 자주 발생할 수 있는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다행히도 저희 서비스의 대부분의 기능은 국세청 점검시간인 00:00~06:00까지 점검이 되다 보니 그 시간대별 분포 차이가 그렇게 크지 않았습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 합리적인 선에서 alert을 걸 수 있었고요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;추가적으로 그 대시보드에 포함시킨 것&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마케팅에서 사용하는 referrer count 별 접속량을 추가해 두었습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 대시보드만을 통해서 어떤 곳에서 많이 유입이 있어서 트래픽 때문에 문제가 된다면 어떤 referrer에 해당하는 것을 꺼야 하는지 바로 알 수 있도록 하는 것이죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;결과&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마케팅 팀 자체적으로 현재 상황을 바로 파악할 수 있게 되었고, 마케팅을 중단할지 말지에 대해서 선택을 할 수 있게 되었습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중단을 한다면 어떤 referrer 에 해당하는 마케팅을 꺼야 가장 효과적으로 트래픽을 조절할 수 있는지 파악을 할 수 있게 되었죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러분들도 모니터링을 하실 때는 이러한 것들을 고려해서 좋은 모니터링 지표를 설정하고, 모니터링을 하실 수 있으면 좋겠네요&lt;/p&gt;</description>
      <category>프로젝트</category>
      <category>모니터링</category>
      <category>지표 설정</category>
      <author>be-student</author>
      <guid isPermaLink="true">https://be-student.tistory.com/115</guid>
      <comments>https://be-student.tistory.com/115#entry115comment</comments>
      <pubDate>Sun, 30 Mar 2025 19:27:28 +0900</pubDate>
    </item>
    <item>
      <title>[4월 우아한테크세미나] &amp;lsquo;Java의 미래, Virtual Thread&amp;rsquo; 정리</title>
      <link>https://be-student.tistory.com/113</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;유튜브 영상 초반에 나온 말부터 전달해 드리면 모든 기술을 선택할 때는 이유가 있어야 합니다.&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;virtual thread의 소개&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도입을 고려하게 된 배경으로는 전사 게이트웨이 시스템 개발용 안정성과 처리량에 대한 고민이 필요해서 알아보게 되었다고 합니다&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Coroutine vs Virtual Thread&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Kotlin Coroutine (실제 선택하셨다고 합니다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Java Project Loom (jdk 21 이 나오기 전이라, 테스트 버전이었습니다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경량 스레드 모델로 jdk 21에 정식 feature로 추가됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Virtual Thread의 장점&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스레드 생성, 스케쥴링 비용이 기존 스레드보다 훨씬 저렴합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스레드풀을 사용할 정도로 비용이 기존의 자바 스레드의 생성 비용이 큽니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최대 2MB까지 차지할 만큼 많은 메모리를 차지합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OS에 의해서 스케쥴링해야 하고, System call 이 반복해서 발생해서 System Call 오버헤드가 발생합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Virtual Thread는 생성 비용이 작습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스레드 풀 개념이 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반 스레드는 수mb virtual thread는 수 kb입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;os 가 아닌 jvm 내부에서 스케쥴링되기 때문에, System Call 이 발생하지 않습니다&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 53px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;Thread&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;Virtual Thread&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;메모리 사이즈&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;~2MB&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;~50KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;생성 시간&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;~1ms&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;~10&lt;span style=&quot;background-color: #ffffff; color: #202122; text-align: start;&quot;&gt;&amp;mu;s&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;컨텍스트 스위칭 시간&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;~100&lt;span style=&quot;background-color: #ffffff; color: #202122; text-align: start;&quot;&gt;&amp;mu;s&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;~10&lt;span style=&quot;background-color: #ffffff; color: #202122; text-align: start;&quot;&gt;&amp;mu;s&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 표처럼 성능상으로 어마어마한 장점이 생깁니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;실제 코드를 통해 확인하는 성능 차이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Thread를 만드는 시간의 차이는 73배만큼 빠르다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 thread의 생성 시간 100만 개 생성에 31.616초&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.21.53.png&quot; data-origin-width=&quot;1194&quot; data-origin-height=&quot;435&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgVYZq/btsG5tfLtWE/zkDlUGLgHmLEsnaF3G52X0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgVYZq/btsG5tfLtWE/zkDlUGLgHmLEsnaF3G52X0/img.png&quot; data-alt=&quot;기존 thread&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgVYZq/btsG5tfLtWE/zkDlUGLgHmLEsnaF3G52X0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgVYZq%2FbtsG5tfLtWE%2FzkDlUGLgHmLEsnaF3G52X0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1194&quot; height=&quot;435&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.21.53.png&quot; data-origin-width=&quot;1194&quot; data-origin-height=&quot;435&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;기존 thread&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;virtual thread 100만 개에 429ms&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.23.30.png&quot; data-origin-width=&quot;1292&quot; data-origin-height=&quot;527&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yhsf1/btsG7Co2NJe/kGYfGJy9eCfQPSroO6LE81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yhsf1/btsG7Co2NJe/kGYfGJy9eCfQPSroO6LE81/img.png&quot; data-alt=&quot;virtual thread 생성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yhsf1/btsG7Co2NJe/kGYfGJy9eCfQPSroO6LE81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fyhsf1%2FbtsG7Co2NJe%2FkGYfGJy9eCfQPSroO6LE81%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1292&quot; height=&quot;527&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.23.30.png&quot; data-origin-width=&quot;1292&quot; data-origin-height=&quot;527&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;virtual thread 생성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대충 73배만큼 성능 차이가 납니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성, 스케쥴링 속도가 훨씬 빠르다는 것이죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NonBlocking I/O 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MSA 환경에서 다른 서버 요청을 기다리는 동안 계속 기다리게 되는데, 이 시간에 다른 작업을 할 수 있어서 NonBlocking I/O 를 하게 됩니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 스프링 reactor의 동작 방식과는 살짝 다른 방식으로 동작한다고 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Non Blocking I/O&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Non Blocking I/O 가 동작하는 원리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM 스레드 스케쥴링&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Continuation이라는 단위를 활용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성능 차이&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실험 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Tomcat 스레드 10개&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10초 소요 API 호출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;100회 동시 호출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;얼마나 걸릴까? 100초&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 스레드라면?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬에서 130초&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;virtual thread 라면? 10.158 ms&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 스레드 대비 92.2% 빠르게 처리가 가능합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동시 처리를 할 수 있기 때문에 가능한 수치로 봐서, NonBlocking I/O 를 지원하는 것을 다시 한번 체크할 수 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;기존 스레드 상속&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.31.13.png&quot; data-origin-width=&quot;610&quot; data-origin-height=&quot;66&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cs2rt9/btsG3OZkDep/IfWmzgxVSBu7GvT3FuA6H1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cs2rt9/btsG3OZkDep/IfWmzgxVSBu7GvT3FuA6H1/img.png&quot; data-alt=&quot;VirtualThread 클래스&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cs2rt9/btsG3OZkDep/IfWmzgxVSBu7GvT3FuA6H1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcs2rt9%2FbtsG3OZkDep%2FIfWmzgxVSBu7GvT3FuA6H1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;610&quot; height=&quot;66&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.31.13.png&quot; data-origin-width=&quot;610&quot; data-origin-height=&quot;66&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;VirtualThread 클래스&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.31.22.png&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;98&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1HIsj/btsG6dQS9Bd/ngJ4eevlyJOD3YjXsjdkA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1HIsj/btsG6dQS9Bd/ngJ4eevlyJOD3YjXsjdkA1/img.png&quot; data-alt=&quot;BaseVirtualThread&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1HIsj/btsG6dQS9Bd/ngJ4eevlyJOD3YjXsjdkA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1HIsj%2FbtsG6dQS9Bd%2FngJ4eevlyJOD3YjXsjdkA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;523&quot; height=&quot;98&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.31.22.png&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;98&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BaseVirtualThread&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 되어있기에, 기존 로직을 그대로 사용할 수 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java 진영에서 LSP를 지켜주기에, 기존 코드에 변화가 거의 없이 가능하다는 것을 알 수 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ExecutorService 부분도 간단하게 변환이 가능합니다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.31.59.png&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;46&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dZ5G5X/btsG7oj4B0O/kcjjTJTSx8OH5VQ62cxqF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dZ5G5X/btsG7oj4B0O/kcjjTJTSx8OH5VQ62cxqF1/img.png&quot; data-alt=&quot;virtual thread executors&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dZ5G5X/btsG7oj4B0O/kcjjTJTSx8OH5VQ62cxqF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdZ5G5X%2FbtsG7oj4B0O%2FkcjjTJTSx8OH5VQ62cxqF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;528&quot; height=&quot;46&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.31.59.png&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;46&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;virtual thread executors&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;와 같이 바로 적용할 수 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;virtual thread의 동작 원리&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;일반 동작 스레드 스케쥴링&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플랫폼 스레드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OS에 의해 스케쥴링&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커널 스레드와 1:1 매핑&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작업 단위로 Runnable을 사용&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.35.31.png&quot; data-origin-width=&quot;679&quot; data-origin-height=&quot;370&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qySXd/btsG4yhyBIP/krkoTjruuPPiwXm3h2Gdc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qySXd/btsG4yhyBIP/krkoTjruuPPiwXm3h2Gdc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qySXd/btsG4yhyBIP/krkoTjruuPPiwXm3h2Gdc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqySXd%2FbtsG4yhyBIP%2FkrkoTjruuPPiwXm3h2Gdc1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;679&quot; height=&quot;370&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.35.31.png&quot; data-origin-width=&quot;679&quot; data-origin-height=&quot;370&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 생성 과정이 진행됩니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Virtual Thread 스케쥴링&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상 스레드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM에 의해 스케쥴링됨&lt;/p&gt;
&lt;pre id=&quot;code_1714581422514&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;A thread that is scheduled by the Java virtual machine rather than the operating system.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.37.12.png&quot; data-origin-width=&quot;696&quot; data-origin-height=&quot;365&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oNxRO/btsG324jpqk/4kkRQWpIyT3pDxKu2YYILk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oNxRO/btsG324jpqk/4kkRQWpIyT3pDxKu2YYILk/img.png&quot; data-alt=&quot;virtual thread 의 스케쥴러는?&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oNxRO/btsG324jpqk/4kkRQWpIyT3pDxKu2YYILk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoNxRO%2FbtsG324jpqk%2F4kkRQWpIyT3pDxKu2YYILk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;696&quot; height=&quot;365&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.37.12.png&quot; data-origin-width=&quot;696&quot; data-origin-height=&quot;365&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;virtual thread 의 스케쥴러는?&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.38.02.png&quot; data-origin-width=&quot;309&quot; data-origin-height=&quot;82&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JhV3d/btsG505eZKx/ZLSlmQrPdy3Ewq7kSkikPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JhV3d/btsG505eZKx/ZLSlmQrPdy3Ewq7kSkikPk/img.png&quot; data-alt=&quot;continuation 단위로 submit 을 하게 됨&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JhV3d/btsG505eZKx/ZLSlmQrPdy3Ewq7kSkikPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJhV3d%2FbtsG505eZKx%2FZLSlmQrPdy3Ewq7kSkikPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;309&quot; height=&quot;82&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.38.02.png&quot; data-origin-width=&quot;309&quot; data-origin-height=&quot;82&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;continuation 단위로 submit 을 하게 됨&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.38.25.png&quot; data-origin-width=&quot;429&quot; data-origin-height=&quot;168&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v4rBJ/btsG4zANwQS/j5hCskcAOGbSZtGkKTiRik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v4rBJ/btsG4zANwQS/j5hCskcAOGbSZtGkKTiRik/img.png&quot; data-alt=&quot;스케쥴러가 동작한다는 것을 볼 수 있음&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v4rBJ/btsG4zANwQS/j5hCskcAOGbSZtGkKTiRik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv4rBJ%2FbtsG4zANwQS%2Fj5hCskcAOGbSZtGkKTiRik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;429&quot; height=&quot;168&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.38.25.png&quot; data-origin-width=&quot;429&quot; data-origin-height=&quot;168&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스케쥴러가 동작한다는 것을 볼 수 있음&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;div style=&quot;background-color: #2b2b2b; color: #a9b7c6;&quot;&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;// scheduler and continuation
private final Executor scheduler;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.39.03.png&quot; data-origin-width=&quot;447&quot; data-origin-height=&quot;78&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IcpOw/btsG5uTgLjy/yAxMLcfhmLwkLWgqj2zktk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IcpOw/btsG5uTgLjy/yAxMLcfhmLwkLWgqj2zktk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IcpOw/btsG5uTgLjy/yAxMLcfhmLwkLWgqj2zktk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIcpOw%2FbtsG5uTgLjy%2FyAxMLcfhmLwkLWgqj2zktk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;447&quot; height=&quot;78&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.39.03.png&quot; data-origin-width=&quot;447&quot; data-origin-height=&quot;78&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.40.06.png&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;326&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wzCzR/btsG4T6UuG5/lckU6tQRsQgYELNfWhIGkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wzCzR/btsG4T6UuG5/lckU6tQRsQgYELNfWhIGkK/img.png&quot; data-alt=&quot;Fork Join 방식으로 동작하는 Virtual Thread&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wzCzR/btsG4T6UuG5/lckU6tQRsQgYELNfWhIGkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwzCzR%2FbtsG4T6UuG5%2FlckU6tQRsQgYELNfWhIGkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;791&quot; height=&quot;326&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.40.06.png&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;326&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fork Join 방식으로 동작하는 Virtual Thread&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;static으로 모든 virtual thread의 스케쥴러가 동일함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Work Stealing 방식과 Fork Join 방식으로 관리하는 풀에서 관리하고 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;parallelism의 수만큼 즉 프로세서의 수만큼 스레드를 띄워두고 가지고 있습니다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.40.43.png&quot; data-origin-width=&quot;688&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kWmpv/btsG499Gvd1/bC5vW3KshNtkJ9EUK5jJ2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kWmpv/btsG499Gvd1/bC5vW3KshNtkJ9EUK5jJ2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kWmpv/btsG499Gvd1/bC5vW3KshNtkJ9EUK5jJ2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkWmpv%2FbtsG499Gvd1%2FbC5vW3KshNtkJ9EUK5jJ2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;688&quot; height=&quot;360&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.40.43.png&quot; data-origin-width=&quot;688&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;virtual thread는 커널 영역 접근이 없어서, 생성 시, 시스템 콜이 발생하지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스케쥴러 안에서 동작하는 스레드를 Carrier Thread라고 하고, virtual thread 와는 1:N 만큼 매핑되어 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Continuation&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.42.28.png&quot; data-origin-width=&quot;685&quot; data-origin-height=&quot;368&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oJL6L/btsG4VwTBfp/XphlSCJXXLQl9dyMJt2rg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oJL6L/btsG4VwTBfp/XphlSCJXXLQl9dyMJt2rg0/img.png&quot; data-alt=&quot;continuation 동작 방식&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oJL6L/btsG4VwTBfp/XphlSCJXXLQl9dyMJt2rg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoJL6L%2FbtsG4VwTBfp%2FXphlSCJXXLQl9dyMJt2rg0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;685&quot; height=&quot;368&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.42.28.png&quot; data-origin-width=&quot;685&quot; data-origin-height=&quot;368&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;continuation 동작 방식&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;suspend를 만나면 멈추고, caller로 제어권 반환하고, 다시 suspend로 가면 이어서 실행하고를 반복함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중단이 가능해야 하고, 중단 지점부터 이어서 실행이 가능하다는 것인데요&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.44.17.png&quot; data-origin-width=&quot;355&quot; data-origin-height=&quot;182&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bplblZ/btsG5GFXew1/Nhi5JwRuCKkJDWyiuB13ZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bplblZ/btsG5GFXew1/Nhi5JwRuCKkJDWyiuB13ZK/img.png&quot; data-alt=&quot;이런 io 단위마다 전부 멈추고 갈 수 있다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bplblZ/btsG5GFXew1/Nhi5JwRuCKkJDWyiuB13ZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbplblZ%2FbtsG5GFXew1%2FNhi5JwRuCKkJDWyiuB13ZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;355&quot; height=&quot;182&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.44.17.png&quot; data-origin-width=&quot;355&quot; data-origin-height=&quot;182&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이런 io 단위마다 전부 멈추고 갈 수 있다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.44.43.png&quot; data-origin-width=&quot;681&quot; data-origin-height=&quot;368&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RzLr7/btsG6eoEc9O/wHV9mzpSeaxA6KoEiRPEEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RzLr7/btsG6eoEc9O/wHV9mzpSeaxA6KoEiRPEEK/img.png&quot; data-alt=&quot;Continuation Scope&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RzLr7/btsG6eoEc9O/wHV9mzpSeaxA6KoEiRPEEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRzLr7%2FbtsG6eoEc9O%2FwHV9mzpSeaxA6KoEiRPEEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;681&quot; height=&quot;368&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.44.43.png&quot; data-origin-width=&quot;681&quot; data-origin-height=&quot;368&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Continuation Scope&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.45.07.png&quot; data-origin-width=&quot;692&quot; data-origin-height=&quot;387&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tiHdS/btsG6hr7Tkz/3SWiQE4YKgMTKFU8Rxdzkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tiHdS/btsG6hr7Tkz/3SWiQE4YKgMTKFU8Rxdzkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tiHdS/btsG6hr7Tkz/3SWiQE4YKgMTKFU8Rxdzkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtiHdS%2FbtsG6hr7Tkz%2F3SWiQE4YKgMTKFU8Rxdzkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;692&quot; height=&quot;387&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.45.07.png&quot; data-origin-width=&quot;692&quot; data-origin-height=&quot;387&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스택 포인터를 힙으로 이동시키고, caller로 반환하고를 반복함&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.47.00.png&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;231&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Q435X/btsG47qvxYB/outGRxGQK4ZGfKstNxyf2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Q435X/btsG47qvxYB/outGRxGQK4ZGfKstNxyf2k/img.png&quot; data-alt=&quot;continuation 동작&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Q435X/btsG47qvxYB/outGRxGQK4ZGfKstNxyf2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQ435X%2FbtsG47qvxYB%2FoutGRxGQK4ZGfKstNxyf2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;670&quot; height=&quot;231&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.47.00.png&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;231&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;continuation 동작&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;virtual thread 내부에 continuation 이 있음&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.47.57.png&quot; data-origin-width=&quot;377&quot; data-origin-height=&quot;98&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8KhCK/btsG5UKMlB7/6JFWdJaWR7LTI2dg5XtNC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8KhCK/btsG5UKMlB7/6JFWdJaWR7LTI2dg5XtNC1/img.png&quot; data-alt=&quot;virtual thread 의 필드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8KhCK/btsG5UKMlB7/6JFWdJaWR7LTI2dg5XtNC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8KhCK%2FbtsG5UKMlB7%2F6JFWdJaWR7LTI2dg5XtNC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;377&quot; height=&quot;98&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.47.57.png&quot; data-origin-width=&quot;377&quot; data-origin-height=&quot;98&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;virtual thread 의 필드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.48.32.png&quot; data-origin-width=&quot;279&quot; data-origin-height=&quot;208&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bN7qb5/btsG5D3yY5H/D88TZ2olmeXFSPpgOmnwe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bN7qb5/btsG5D3yY5H/D88TZ2olmeXFSPpgOmnwe1/img.png&quot; data-alt=&quot;runContinuation&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bN7qb5/btsG5D3yY5H/D88TZ2olmeXFSPpgOmnwe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbN7qb5%2FbtsG5D3yY5H%2FD88TZ2olmeXFSPpgOmnwe1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;279&quot; height=&quot;208&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.48.32.png&quot; data-origin-width=&quot;279&quot; data-origin-height=&quot;208&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;runContinuation&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;continuation이라는 작업 단위를 그냥 단순 실행해 주는 역할이죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 블로킹을 시켜야 한다면?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;yield를 호출해 주면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;private 메서드이기에, park라는 메서드가 필요한데요&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.50.26.png&quot; data-origin-width=&quot;725&quot; data-origin-height=&quot;458&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q6mWu/btsG4TZ4AJI/GSUzQAd6LMJXWMCu1C4Yw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q6mWu/btsG4TZ4AJI/GSUzQAd6LMJXWMCu1C4Yw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q6mWu/btsG4TZ4AJI/GSUzQAd6LMJXWMCu1C4Yw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq6mWu%2FbtsG4TZ4AJI%2FGSUzQAd6LMJXWMCu1C4Yw0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;725&quot; height=&quot;458&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.50.26.png&quot; data-origin-width=&quot;725&quot; data-origin-height=&quot;458&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;virtual thread의 park 메서드를 통해서 할 수 있지만, 이것도 외부에서 접근이 안됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LockSupport.park() 메서드를 통해서 호출이 가능합니다, 일반스레드의 경우에는 커널로 블로킹을 진행해 줍니다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.52.17.png&quot; data-origin-width=&quot;404&quot; data-origin-height=&quot;166&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uGtiM/btsG7oEnbYR/Ah2OgLnqwRCC0nhYRtCSpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uGtiM/btsG7oEnbYR/Ah2OgLnqwRCC0nhYRtCSpK/img.png&quot; data-alt=&quot;virtual thread 가 추가된 이후에 변경된 포인트&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uGtiM/btsG7oEnbYR/Ah2OgLnqwRCC0nhYRtCSpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuGtiM%2FbtsG7oEnbYR%2FAh2OgLnqwRCC0nhYRtCSpK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;404&quot; height=&quot;166&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.52.17.png&quot; data-origin-width=&quot;404&quot; data-origin-height=&quot;166&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;virtual thread 가 추가된 이후에 변경된 포인트&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 스레드를 블락하는 부분에서 jdk 21부터 변경되었습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;continuation을 워커 큐에서 제거되는 방식으로 진행하게 됩니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Continuation을 사용하게 된 이유는 작업 중단을 위해서 커널 스레드를 중단하지 않고, Continuation yield를 통해서 다른 Continuation으로 진행할 뿐이기에, System Call 이 없어서 비용이 낮기에 사용하게 되었습니다&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;기존 스레드 모델과의 비교&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;thread per request&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.57.11.png&quot; data-origin-width=&quot;677&quot; data-origin-height=&quot;386&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bggLFq/btsG3NlNOqg/ohqh2LsC86hnRj6bpqjKKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bggLFq/btsG3NlNOqg/ohqh2LsC86hnRj6bpqjKKK/img.png&quot; data-alt=&quot;request per thread&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bggLFq/btsG3NlNOqg/ohqh2LsC86hnRj6bpqjKKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbggLFq%2FbtsG3NlNOqg%2Fohqh2LsC86hnRj6bpqjKKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;677&quot; height=&quot;386&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.57.11.png&quot; data-origin-width=&quot;677&quot; data-origin-height=&quot;386&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;request per thread&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LockThread.park() 메서드를 호출하게 되어있는데요&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Virtual Thread&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.59.07.png&quot; data-origin-width=&quot;706&quot; data-origin-height=&quot;233&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/O6PlW/btsG5jjYCSL/SQDggEsQvZCHWMHI6QDhwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/O6PlW/btsG5jjYCSL/SQDggEsQvZCHWMHI6QDhwK/img.png&quot; data-alt=&quot;Tomcat 을 VirtualThread 로 바꾸는 방법&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/O6PlW/btsG5jjYCSL/SQDggEsQvZCHWMHI6QDhwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FO6PlW%2FbtsG5jjYCSL%2FSQDggEsQvZCHWMHI6QDhwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;706&quot; height=&quot;233&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.59.07.png&quot; data-origin-width=&quot;706&quot; data-origin-height=&quot;233&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Tomcat 을 VirtualThread 로 바꾸는 방법&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.59.56.png&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;385&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rM5jB/btsG6KAVBkI/C4hUEMSKQKRq4aCxvqC7A0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rM5jB/btsG6KAVBkI/C4hUEMSKQKRq4aCxvqC7A0/img.png&quot; data-alt=&quot;virtual thread&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rM5jB/btsG6KAVBkI/C4hUEMSKQKRq4aCxvqC7A0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrM5jB%2FbtsG6KAVBkI%2FC4hUEMSKQKRq4aCxvqC7A0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;684&quot; height=&quot;385&quot; data-filename=&quot;스크린샷 2024-05-02 오전 1.59.56.png&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;385&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;virtual thread&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;성능 테스트&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 2.01.00.png&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;376&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wXCu2/btsG6LNmYig/a2KMRG2sBY5OERSmTy6BoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wXCu2/btsG6LNmYig/a2KMRG2sBY5OERSmTy6BoK/img.png&quot; data-alt=&quot;성능 테스트 조건&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wXCu2/btsG6LNmYig/a2KMRG2sBY5OERSmTy6BoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwXCu2%2FbtsG6LNmYig%2Fa2KMRG2sBY5OERSmTy6BoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;682&quot; height=&quot;376&quot; data-filename=&quot;스크린샷 2024-05-02 오전 2.01.00.png&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;376&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;성능 테스트 조건&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;io bound의 경우 tps 51% 높다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cpu bound의 경우 7% 낮다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 2.01.14.png&quot; data-origin-width=&quot;690&quot; data-origin-height=&quot;383&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mNjuT/btsG6aNn9rd/N1Hwk9dIKk1Ge4QqbUUSl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mNjuT/btsG6aNn9rd/N1Hwk9dIKk1Ge4QqbUUSl1/img.png&quot; data-alt=&quot;cpu bound&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mNjuT/btsG6aNn9rd/N1Hwk9dIKk1Ge4QqbUUSl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmNjuT%2FbtsG6aNn9rd%2FN1Hwk9dIKk1Ge4QqbUUSl1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;690&quot; height=&quot;383&quot; data-filename=&quot;스크린샷 2024-05-02 오전 2.01.14.png&quot; data-origin-width=&quot;690&quot; data-origin-height=&quot;383&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;cpu bound&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Thread 서버는 특정 vuser 수부터 장애가 발생한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 2.02.03.png&quot; data-origin-width=&quot;690&quot; data-origin-height=&quot;375&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ylNNx/btsG47Ry1yP/5fkUKA61mr9xfNswxcT6k0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ylNNx/btsG47Ry1yP/5fkUKA61mr9xfNswxcT6k0/img.png&quot; data-alt=&quot;webflux 조건&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ylNNx/btsG47Ry1yP/5fkUKA61mr9xfNswxcT6k0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FylNNx%2FbtsG47Ry1yP%2F5fkUKA61mr9xfNswxcT6k0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;690&quot; height=&quot;375&quot; data-filename=&quot;스크린샷 2024-05-02 오전 2.02.03.png&quot; data-origin-width=&quot;690&quot; data-origin-height=&quot;375&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;webflux 조건&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 2.02.14.png&quot; data-origin-width=&quot;681&quot; data-origin-height=&quot;381&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZcsuS/btsG3AfR5U8/D4hupAABKyk8BHgPMbVEC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZcsuS/btsG3AfR5U8/D4hupAABKyk8BHgPMbVEC1/img.png&quot; data-alt=&quot;성능 테스트 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZcsuS/btsG3AfR5U8/D4hupAABKyk8BHgPMbVEC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZcsuS%2FbtsG3AfR5U8%2FD4hupAABKyk8BHgPMbVEC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;681&quot; height=&quot;381&quot; data-filename=&quot;스크린샷 2024-05-02 오전 2.02.14.png&quot; data-origin-width=&quot;681&quot; data-origin-height=&quot;381&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;성능 테스트 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엄청난 차이처럼 보이지만, 아래 설명처럼, 콘텍스트 스위칭 비용이 생겨 처리량 저하가 발생하긴 했어서, 실제로는 이렇게 큰 차이가 아니라고 합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 정도로 트래픽이 몰리면 보통 서버를 늘려야죠&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 2.02.33.png&quot; data-origin-width=&quot;675&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pKyhP/btsG4TlzGMt/edYS6BJ279SK4KjkHNA0UK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pKyhP/btsG4TlzGMt/edYS6BJ279SK4KjkHNA0UK/img.png&quot; data-alt=&quot;주의점&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pKyhP/btsG4TlzGMt/edYS6BJ279SK4KjkHNA0UK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpKyhP%2FbtsG4TlzGMt%2FedYS6BJ279SK4KjkHNA0UK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;675&quot; height=&quot;180&quot; data-filename=&quot;스크린샷 2024-05-02 오전 2.02.33.png&quot; data-origin-width=&quot;675&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;주의점&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;i/o bound 작업 효율, 제한된 환경에서 최대 처리량을 낼 때 필요합니다&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;서비스 적용 시 주의사항&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Blocking Carrier thread (Pin 현상)&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 2.03.27.png&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;267&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beXgKF/btsG6MepX8p/zaL8WvEmdNtK2XNWnFEEAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beXgKF/btsG6MepX8p/zaL8WvEmdNtK2XNWnFEEAk/img.png&quot; data-alt=&quot;pin 현상 설명&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beXgKF/btsG6MepX8p/zaL8WvEmdNtK2XNWnFEEAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeXgKF%2FbtsG6MepX8p%2FzaL8WvEmdNtK2XNWnFEEAk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;680&quot; height=&quot;267&quot; data-filename=&quot;스크린샷 2024-05-02 오전 2.03.27.png&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;267&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;pin 현상 설명&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;reactor melt down 하고 비슷한 것 같네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;virtual thread의 pin을 막기 위해서 synchronized 나 parrelStream 부분을 바꿔주는 것은 스프링 3.2부터 몽고 db에서 지원하게 되어있는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mysql 은 아직 지원하지 않고 있기에, &lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&amp;nbsp;pin 문제가 많이 발생할 수 있다고 합니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;synchronized를 호출하는 어떤 코드도 병목 가능성이 존재하기 때문에, 사용하는 라이브러리 release를 모두 점검해야 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이후에 synchronized 코드를 모두 reentrantLock으로 교체해야 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주의 사항으로는 virtual thread를 풀로 사용하게 되면 오히려 성능이 어마어마하게 줄어들 수 있기에 사용하면 안 됩니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Cpu Bound Task&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Carrier Thread 위에 동작하기에 어차피 물리 장비의 성능에 막혀서 동작하게 됩니다. 따라서&amp;nbsp;non blocking의 장점을 살리지 못하게 되고, 오히려 성능이 7% 정도 감소하는 것을 확인할 수 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;ThreadLocal을 사용해서는 안됩니다&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수백만 개의 스레드 생성 콘셉트인데, Thread Local을 최대한 가볍게 유지하여야 하는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이유로는 virtual thread는 콘셉트상 쉽게 생성하고 소멸을 시켜야 한다는 부분이 있기 때문입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 사용하고 싶은 사용자들을 위해서 jdk 21에서 ScopedValue라는 preview 기능이 존재하고 있다고 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Virtual Thread는 배압 조절 기능이 없습니다&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;db 커넥션이나, 외부 io, tps 제한을 뚫어버리는&amp;nbsp;문제가 생길 수 있어서 성능 테스트를 정말 주의해서 진행해야 한다고 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-02 오전 2.06.51.png&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;269&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kxaf9/btsG4WWTe1n/53r1coDxse3djYGWWDuaEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kxaf9/btsG4WWTe1n/53r1coDxse3djYGWWDuaEK/img.png&quot; data-alt=&quot;결론&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kxaf9/btsG4WWTe1n/53r1coDxse3djYGWWDuaEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fkxaf9%2FbtsG4WWTe1n%2F53r1coDxse3djYGWWDuaEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;582&quot; height=&quot;269&quot; data-filename=&quot;스크린샷 2024-05-02 오전 2.06.51.png&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;269&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결론&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;Q&amp;amp;A&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코루틴과 비교&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경량 스레드는 결국 스레드다 (thread per request를 최대한 빠르게 하는 것이 목표)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코루틴은 루틴 즉 메서드나 함수다. (메서드의 대기시간을 어떻게 줄이느냐, 메서드 단위로 하는 것이 특징임)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webflux는 함수형 프로그래밍을 지원하고, 배압을 조절하는 부분이 특징이다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경량 스레드는 구조적 동시성을 아직 지원하지 않고, 배압 조절 기능도 안된다고 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;DB Connection을 어떻게 조절할 수 있을까?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 구현상에서는 방법이 딱히 없어서, mysql을 사용한다면 애플리케이션 코드레벨에서 따로 걸러야 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;virtual thread를 mysql jdbc를 사용하게 되면 정말 느리지만,&amp;nbsp;synchronized 부분 제거하는 pr 이 머지가 된다면 잘 쓸 수 있을 것이라고 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/mysql/mysql-connector-j/pull/95&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/mysql/mysql-connector-j/pull/95&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1714583681347&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;Replace synchronized with ReentrantLock by bdeneuter &amp;middot; Pull Request #95 &amp;middot; mysql/mysql-connector-j&quot; data-og-description=&quot;Replace synchronized blocks with a ReentrantLock. This avoids that the carrier thread (OS thread) is pinned when running on virtual threads which were introduced as a preview feature in JDK 19. The...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/mysql/mysql-connector-j/pull/95&quot; data-og-url=&quot;https://github.com/mysql/mysql-connector-j/pull/95&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/CoJ6j/hyVVCiyqmj/osvBRj2ThaAwgOTqUnaHaK/img.png?width=1200&amp;amp;height=600&amp;amp;face=946_103_1083_207&quot;&gt;&lt;a href=&quot;https://github.com/mysql/mysql-connector-j/pull/95&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/mysql/mysql-connector-j/pull/95&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/CoJ6j/hyVVCiyqmj/osvBRj2ThaAwgOTqUnaHaK/img.png?width=1200&amp;amp;height=600&amp;amp;face=946_103_1083_207');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Replace synchronized with ReentrantLock by bdeneuter &amp;middot; Pull Request #95 &amp;middot; mysql/mysql-connector-j&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Replace synchronized blocks with a ReentrantLock. This avoids that the carrier thread (OS thread) is pinned when running on virtual threads which were introduced as a preview feature in JDK 19. The...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 pr 은 현재 close 되어있기에, 언제 머지될지는 모르죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=BZMZIM-n4C0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.youtube.com/watch?v=BZMZIM-n4C0&lt;/a&gt;&lt;/p&gt;</description>
      <category>Java</category>
      <category>continuation</category>
      <category>thread</category>
      <category>virtual thread</category>
      <category>우아한 테크세미나</category>
      <category>우아한테크세미나</category>
      <author>be-student</author>
      <guid isPermaLink="true">https://be-student.tistory.com/113</guid>
      <comments>https://be-student.tistory.com/113#entry113comment</comments>
      <pubDate>Thu, 2 May 2024 02:38:10 +0900</pubDate>
    </item>
    <item>
      <title>내가 주는 피드백이 좋은 피드백이 되는 방법</title>
      <link>https://be-student.tistory.com/112</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;회사에서 들었던 세션의 내용을 일부분 정리해서 가져온 내용입니다&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;좋은&amp;nbsp;피드백이란&amp;nbsp;뭘까요?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 사람의 행동을 바꾸는 것입니다&lt;br /&gt;사람이 쉽게 바뀔 수 있을까요? 대부분 불가능하죠&lt;br /&gt;피드백 수업도 있고, 코칭도 있는 이유는 그 힘든 일을 조금 더 쉽게 해내기 위해서일 것입니다&lt;br /&gt;피드백은 다른 사람이 받는 것을 너무 싫어하는 상황이면 오늘의 내용보다는 그 상황을 바꾸는 것이 더 중요할 수 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 핵심적인 포인트는 받아들일 수 있도록 만드는 것이 가장 중요합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상대방의 반발심을 누그러뜨리는 것이 가장 중요하죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;피드백을 잘 받아들이게 하는 방법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연히 긍정적인 것만 해주면 가장 받아들이기 쉽지만, 이건 피드백이 아니니 피드백의 역할을 하지 못합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분을 해결하기 위한 스킬이 필요한 것이죠&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;피드백을&amp;nbsp;강하게&amp;nbsp;주는&amp;nbsp;것&amp;nbsp;vs&amp;nbsp;약하게&amp;nbsp;주는&amp;nbsp;것&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;피드백을 강하게 주었을 경우에 상대방에 압력이 되어서 반발심이 커지게 될 수 있는데, 그러면 피드백을 수용하기 정말 어려운 상태가 될 수 있습니다&lt;br /&gt;그래서 차라리 강하게 보다는 약하게 주는 것이 효과가 좋은 경우가 많습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;B&amp;nbsp;=&amp;nbsp;MAT&amp;nbsp;Behavior&amp;nbsp;Motivation&amp;nbsp;availity&amp;nbsp;trigger&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.growthengineering.co.uk/bj-foggs-behavior-model/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.growthengineering.co.uk/bj-foggs-behavior-model/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 사이트에 나온 내용인데요 행동&amp;nbsp;=&amp;nbsp;동기,&amp;nbsp;능력,&amp;nbsp;트리거로&amp;nbsp;이루어진다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행동의 변화는 당연하지만 동기가 있어야 하고, 바꿀 능력이 있어야 하고, 바꿀 계기가 있어야 한다는 부분입니다&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;지금부터는&amp;nbsp;사례를&amp;nbsp;바탕으로&amp;nbsp;할&amp;nbsp;예정입니다&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일정을 평소에 자주 못 맞추는 팀 동료가 있어요&lt;br /&gt;2~3번 정도 가볍게 지나가는 말로, dm으로 피드백을 했는데 잘 안 고쳐질 것 같아요&lt;br /&gt;이때 어떻게 피드백을 할 수 있을까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;언제 피드백을 줘야 할까요?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좋은 피드백은 행동이 발생된 지 1주일 내에 무조건 끝이 나야 합니다&lt;br /&gt;같이&amp;nbsp;들으셨던&amp;nbsp;분의&amp;nbsp;대부분은&amp;nbsp;일정&amp;nbsp;마감을&amp;nbsp;못 지킨 지&amp;nbsp;1~2일이&amp;nbsp;지난&amp;nbsp;이후에&amp;nbsp;한다고&amp;nbsp;하더라고요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;못 지킨 순간에는 자괴감이 분명 있을 수 있어서 더 방어적일 수 있기 때문에, 이 부분을 피해 주는 것도 좋다고 하더라고요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세션 도중에 나왔던 질문은&lt;br /&gt;상황이&amp;nbsp;명확하지&amp;nbsp;않을 때는 어떻게 해야할까요? 대부분은 70점이 피드백을 받는 커트라인이라면, 71점 72점이 지속되는 케이스들이 많은데요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 어떤 부분이 마음에 안 드는 것인지 명확하게 구체화하는대 시간을 써보면 좋을 것 같습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;질문,&amp;nbsp;제안,&amp;nbsp;질문으로&amp;nbsp;이어지는&amp;nbsp;대화법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.micenterforchange.com/ask-offer-ask/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog.micenterforchange.com/ask-offer-ask/&lt;/a&gt;&lt;br /&gt;Ask&amp;nbsp;&amp;rArr;&amp;nbsp;요즘&amp;nbsp;일정을&amp;nbsp;맞추지&amp;nbsp;못했던&amp;nbsp;일들이&amp;nbsp;발생했는데,&amp;nbsp;혹시&amp;nbsp;무슨&amp;nbsp;문제가&amp;nbsp;있었나요?&lt;br /&gt;문제를&amp;nbsp;충분히&amp;nbsp;듣고&amp;nbsp;요약을&amp;nbsp;잘해줘야 된다.&amp;nbsp;아&amp;nbsp;그런&amp;nbsp;일들이&amp;nbsp;있었군요~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Offer&amp;nbsp;&amp;rArr;&amp;nbsp;문제를&amp;nbsp;들었더니&amp;nbsp;이제&amp;nbsp;어떤&amp;nbsp;상황이었는지&amp;nbsp;알겠네요.&amp;nbsp;혹시&amp;nbsp;제가&amp;nbsp;생각하는&amp;nbsp;방법에&amp;nbsp;대해서&amp;nbsp;말씀드려도&amp;nbsp;될까요?&lt;br /&gt;앞에서&amp;nbsp;말한&amp;nbsp;이런&amp;nbsp;부분에&amp;nbsp;대해서&amp;nbsp;든&amp;nbsp;생각이&amp;nbsp;있어서요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;you&amp;nbsp;대신&amp;nbsp;I&amp;nbsp;대화법&lt;br /&gt;최대한&amp;nbsp;네가&amp;nbsp;어떻게&amp;nbsp;했으면&amp;nbsp;좋겠다&amp;nbsp; &lt;br /&gt;나는&amp;nbsp;이렇게&amp;nbsp;하고&amp;nbsp;있는&amp;nbsp;모습이&amp;nbsp;걱정된다&lt;br /&gt;최대한&amp;nbsp;객관적인&amp;nbsp;내용으로&amp;nbsp;판단을&amp;nbsp;없애야 한다.&lt;br /&gt;Ask&amp;nbsp;&amp;rArr;&amp;nbsp;제가&amp;nbsp;말했던&amp;nbsp;방식에&amp;nbsp;대해서&amp;nbsp;어떻게&amp;nbsp;생각하시나요?&lt;br /&gt;조언을&amp;nbsp;준다&amp;nbsp;X&amp;nbsp;정보를&amp;nbsp;줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정에서 주의하면 좋은 점으로는&lt;br /&gt;1. 스스로를 낮춰서 얘기해야 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 최대한 다른 사람의 얘기를 듣다가 끝이 나야 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Trigger&amp;nbsp;만들기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;끝났을 때, 무조건 이런 느낌으로 끝이 나면 좋습니다&lt;br /&gt;저희 팀 리더님의 대화법과 비슷한데,&lt;br /&gt;오늘&amp;nbsp;~~~&amp;nbsp;에&amp;nbsp;대해서&amp;nbsp;얘기해 봤는데,&amp;nbsp;우리&amp;nbsp;같이&amp;nbsp;해볼&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;것이&amp;nbsp;무엇이&amp;nbsp;있을까요?&lt;br /&gt;or&amp;nbsp;다음 주까지&amp;nbsp;or&amp;nbsp;다음에&amp;nbsp;볼&amp;nbsp;기회까지&amp;nbsp;할만한&amp;nbsp;아이템을&amp;nbsp;만들어보자&lt;br /&gt;라고하고&amp;nbsp;다음번&amp;nbsp;만남 때&amp;nbsp;그&amp;nbsp;부분을&amp;nbsp;했는지,&amp;nbsp;안 했는지,&amp;nbsp;했다면&amp;nbsp;어떤&amp;nbsp;변화가&amp;nbsp;있었는지에&amp;nbsp;대해서&amp;nbsp;얘기해 보면&amp;nbsp;좋다&lt;br /&gt;다른&amp;nbsp;팀이&amp;nbsp;일정에&amp;nbsp;딜레이를&amp;nbsp;주는&amp;nbsp;원인이라면?&amp;nbsp;미리&amp;nbsp;일정을&amp;nbsp;조율하는&amp;nbsp;회의를&amp;nbsp;잡아보자&lt;br /&gt;잡아서&amp;nbsp;얘기를&amp;nbsp;했더니,&amp;nbsp;어떤&amp;nbsp;결과가&amp;nbsp;있었는지&amp;nbsp;체크해 보자&amp;nbsp;등&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 세션에서 나왔던 질문 중 하나로는&lt;br /&gt;팀장이나 리드 입장에서는 하기 정말 쉽지만, 제가 다른 팀원에게 피드백을 줄 때, 이렇게 하기 쉽지 않을 텐데, 이런 것들은 어떻게 해야 할까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리 함께 해보자 나도 할 거고, 너도 하면서 같이 한번 해보자 라는 내용이 그 힌트가 될 수 있을 것 같습니다&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;피드백을&amp;nbsp;받아들이기&amp;nbsp;싫을&amp;nbsp;때&amp;nbsp;피드백을&amp;nbsp;수용하는&amp;nbsp;방법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;피드백이 줄 수 있는 3가지 부정적인 반응에서 좋은 결과 얻어내기&lt;br /&gt;진실&amp;nbsp;자극&amp;nbsp;:&amp;nbsp;피드백이&amp;nbsp;도움이&amp;nbsp;안 되거나,&amp;nbsp;사실이&amp;nbsp;아닐&amp;nbsp;때&amp;nbsp;(이거&amp;nbsp;아닌데?)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가&amp;nbsp;이번에는&amp;nbsp;일정을&amp;nbsp;못&amp;nbsp;맞춘 게&amp;nbsp;아니라,&amp;nbsp;팀에&amp;nbsp;공유가&amp;nbsp;다&amp;nbsp;된&amp;nbsp;상태인데,&amp;nbsp;왜&amp;nbsp;이 번 거를&amp;nbsp;가지고&amp;nbsp;그러지?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 듣고 싶은 피드백과 상대가 하는 피드백을 분리해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 인정을 받고 싶었는데, 상대가 평가를 한다면? 아 그렇구나 하고 인지를 하고 있으면 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인정, 조언, 평가 이렇게 3가지 요소로 보통 인지를 할 수 있으면 좋습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;관계 자극 : 태도가 너무 무례한데?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 케이스는 보통 서로 대화하는 주제가 달라질 때 많이 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일정에 대한 것이 아니라, 태도에 대한 것을 갑자기 상대가 말하게 되면, 무례하게 느껴지는 것이죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 일정에 대한 것만 먼저 얘기를 하고, 그 이후에 태도에 대한 것을 따로 얘기를 하면 더 좋게 되는 경우가 많습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;정체성&amp;nbsp;자극&amp;nbsp;:&amp;nbsp;하..&amp;nbsp;또&amp;nbsp;시간을&amp;nbsp;못&amp;nbsp;지키다니&amp;nbsp;난&amp;nbsp;망했어&amp;hellip;&amp;nbsp;내가&amp;nbsp;그렇게&amp;nbsp;무능력한가?&lt;br /&gt;내&amp;nbsp;생각과&amp;nbsp;현실&amp;nbsp;사이에&amp;nbsp;격차를&amp;nbsp;좁히기&amp;nbsp;(나는&amp;nbsp;어떻게&amp;nbsp;느끼는가?&amp;nbsp;vs&amp;nbsp;실제&amp;nbsp;피드백은&amp;nbsp;무엇인가?)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 하고 싶은 이상과 현실은 언제나 차이가 생길 수밖에 없습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상대방의 피드백중 상대방의 조언을 찾아보고, 평가에서 판단을 제외해 보면 좋을 수 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들면, 너는 이렇게 하면 잘려~라는 피드백을 들었을 때, 잘린다는 것은 회사 사내 규정에 따라 자를 수 있겠죠? 그전에는 잘리지 않을 테니 과도한 불안감을 갖지는 말아야 한다라는 느낌입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;어떤&amp;nbsp;피드백이든&amp;nbsp;얻어갈&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;정보&amp;nbsp;1가지&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;givers&amp;nbsp;fact&lt;br /&gt;피드백을 준 사람에 대한 정보는 무조건 얻게 됩니다&lt;br /&gt;피드백을&amp;nbsp;줄 만큼&amp;nbsp;~~~~&amp;nbsp;를&amp;nbsp;싫어하는구나&lt;br /&gt;지각 좀&amp;nbsp;하지 마&amp;nbsp;&amp;rArr;&amp;nbsp;피드백을&amp;nbsp;주는&amp;nbsp;사람은&amp;nbsp;내가&amp;nbsp;지각하는&amp;nbsp;것을&amp;nbsp;싫어하는구나&lt;br /&gt;애처럼&amp;nbsp;행동하지&amp;nbsp;말아라&amp;nbsp;&amp;rArr;&amp;nbsp;피드백을&amp;nbsp;주는&amp;nbsp;사람은&amp;nbsp;내가&amp;nbsp;애처럼&amp;nbsp;행동하는&amp;nbsp;것을&amp;nbsp;싫어하는구나&lt;br /&gt;놀지만&amp;nbsp;말고&amp;nbsp;공부 좀&amp;nbsp;해라&amp;nbsp;&amp;rArr;&amp;nbsp;피드백을&amp;nbsp;주는&amp;nbsp;사람은&amp;nbsp;내가&amp;nbsp;노는 거를&amp;nbsp;싫어하고,&amp;nbsp;공부를&amp;nbsp;하는&amp;nbsp;것을&amp;nbsp;좋아하는구나&lt;br /&gt;상대가&amp;nbsp;아무리&amp;nbsp;개떡같이&amp;nbsp;말을&amp;nbsp;해도,&amp;nbsp;이&amp;nbsp;사실만큼은&amp;nbsp;변하지&amp;nbsp;않으니,&amp;nbsp;이거는&amp;nbsp;써먹어도&amp;nbsp;좋다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;당부의 말&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 주는 피드백, 받는 피드백은 무조건 완벽하지 않으니 아니라는 가정을 깔고 줘야 합니다&lt;/p&gt;
&lt;figure id=&quot;og_1714219137708&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;The Fogg Behavior Model: How to Trigger Behaviour Change&quot; data-og-description=&quot;The Fogg Behavior Model addresses the most significant question in L&amp;amp;D: how can you change learner behaviour?&quot; data-og-host=&quot;www.growthengineering.co.uk&quot; data-og-source-url=&quot;https://www.growthengineering.co.uk/bj-foggs-behavior-model/&quot; data-og-url=&quot;https://www.growthengineering.co.uk/bj-foggs-behavior-model/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dKAEWf/hyVVAKIwBL/K9tXR4N7ZQplBZoOLogVT1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/ch9Uri/hyVVMdmg6m/5eNQbBiHdQkFOIyvjSkYcK/img.png?width=1024&amp;amp;height=512&amp;amp;face=0_0_1024_512,https://scrap.kakaocdn.net/dn/bAHg1B/hyVVI9Qxxj/geVUjTv3aswU0kJlamWIEk/img.png?width=768&amp;amp;height=875&amp;amp;face=0_0_768_875&quot;&gt;&lt;a href=&quot;https://www.growthengineering.co.uk/bj-foggs-behavior-model/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.growthengineering.co.uk/bj-foggs-behavior-model/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dKAEWf/hyVVAKIwBL/K9tXR4N7ZQplBZoOLogVT1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/ch9Uri/hyVVMdmg6m/5eNQbBiHdQkFOIyvjSkYcK/img.png?width=1024&amp;amp;height=512&amp;amp;face=0_0_1024_512,https://scrap.kakaocdn.net/dn/bAHg1B/hyVVI9Qxxj/geVUjTv3aswU0kJlamWIEk/img.png?width=768&amp;amp;height=875&amp;amp;face=0_0_768_875');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;The Fogg Behavior Model: How to Trigger Behaviour Change&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The Fogg Behavior Model addresses the most significant question in L&amp;amp;D: how can you change learner behaviour?&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.growthengineering.co.uk&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure id=&quot;og_1714219112046&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;  behavior motivation ability trigger: Google 검색&quot; data-og-description=&quot;&quot; data-og-host=&quot;www.google.com&quot; data-og-source-url=&quot;https://www.google.com/search?q=behavior+motivation+ability+trigger&amp;amp;rlz=1C5CHFA_enKR1078KR1078&amp;amp;oq=behavior+motivation+ability+trigger&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOdIBBzIyNWowajeoAgCwAgA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8&quot; data-og-url=&quot;https://www.google.com/knowledgegraphshares?gs_lcrp=EgZjaHJvbWUyBggAEEUYOdIBBzIyNWowajeoAgCwAgA&amp;amp;ie=UTF-8&amp;amp;oq=behavior+motivation+ability+trigger&amp;amp;q=behavior+motivation+ability+trigger&amp;amp;rlz=1C5CHFA_enKR1078KR1078&amp;amp;sourceid=chrome&amp;amp;kgs&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cmeraW/hyVVAYgAUU/eIh7fOANPL5JkFFeX8so31/img.png?width=615&amp;amp;height=321&amp;amp;face=0_0_615_321,https://scrap.kakaocdn.net/dn/blQlwv/hyVVJt8waN/8RsP1bHdGMNPQ24ckucTnk/img.png?width=615&amp;amp;height=321&amp;amp;face=0_0_615_321&quot;&gt;&lt;a href=&quot;https://www.google.com/search?q=behavior+motivation+ability+trigger&amp;amp;rlz=1C5CHFA_enKR1078KR1078&amp;amp;oq=behavior+motivation+ability+trigger&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOdIBBzIyNWowajeoAgCwAgA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.google.com/search?q=behavior+motivation+ability+trigger&amp;amp;rlz=1C5CHFA_enKR1078KR1078&amp;amp;oq=behavior+motivation+ability+trigger&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOdIBBzIyNWowajeoAgCwAgA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cmeraW/hyVVAYgAUU/eIh7fOANPL5JkFFeX8so31/img.png?width=615&amp;amp;height=321&amp;amp;face=0_0_615_321,https://scrap.kakaocdn.net/dn/blQlwv/hyVVJt8waN/8RsP1bHdGMNPQ24ckucTnk/img.png?width=615&amp;amp;height=321&amp;amp;face=0_0_615_321');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;  behavior motivation ability trigger: Google 검색&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.google.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>목표</category>
      <author>be-student</author>
      <guid isPermaLink="true">https://be-student.tistory.com/112</guid>
      <comments>https://be-student.tistory.com/112#entry112comment</comments>
      <pubDate>Sat, 27 Apr 2024 21:15:39 +0900</pubDate>
    </item>
    <item>
      <title>자바 버전 올릴 수 있을까?</title>
      <link>https://be-student.tistory.com/111</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;자바 버전 올리려다 과정을 기록해 두면 정말 많은 도움이 앞으로 될 것 같아서 기록해두려고 한 글입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글을 읽는 모든 분들은 비슷한 문제를 마주했을 것 같지만 천천히 편하게 올리면 결국 다 할 수 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이팅&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;현재 상황은?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 저희 팀의 프로젝트는 자바 8로 되어있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연하지만 스프링부트도 2. 초반의 버전으로 이루어져 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바 8이 유지가 되면 어떤 문제가 생길까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바 8의 support 기간은 어마어마하게 많이 남아있는데요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무려 앞으로 6년 10개월이나 남은 2030년 12월 31일에 서포트가 종료되는데요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그전에 누군가가 자바 버전을 올려주지 않을까요? (하지만 그 일은 절대로 이루어지지 않습니다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 사람을 설득할 수 있는 자바 버전을 꼭 올려야 하는 이유를 그나마 찾는다면 스프링 부트 2의 서포트가 종료된 부분이 그 사유가 될 수 있을 것 같은데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-02-22 오전 12.12.46.png&quot; data-origin-width=&quot;660&quot; data-origin-height=&quot;696&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/L4EKP/btsE7pAAPD9/DPZ5cej0mqhMnv88XyK48K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/L4EKP/btsE7pAAPD9/DPZ5cej0mqhMnv88XyK48K/img.png&quot; data-alt=&quot;https://endoflife.date/spring-boot&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/L4EKP/btsE7pAAPD9/DPZ5cej0mqhMnv88XyK48K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FL4EKP%2FbtsE7pAAPD9%2FDPZ5cej0mqhMnv88XyK48K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;448&quot; height=&quot;472&quot; data-filename=&quot;스크린샷 2024-02-22 오전 12.12.46.png&quot; data-origin-width=&quot;660&quot; data-origin-height=&quot;696&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://endoflife.date/spring-boot&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재는 부트 3.0까지 oss support 서포트가 종료되었습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바 8이나 자바 11을 사용하면 스프링 부트 3으로 갈 수 없으니 당연히 서포트가 종료가 종료된 버전을 사용하게 되는 것이죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어느 순간 보안 패치가 필요한 순간이 올 텐데, 부트 2에서는 관련된 기능을 돕기 쉽지 않은 문제가 생기죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버전을 꾸준히 올리지 않으면, 어느 순간 올릴 때 한 번에 너무 많은 버전을 올려야 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 저희 프로젝트가 마주한 자바 8에서 자바 17로, 부트 2에서 부트 3으로 크게 변화해야 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최신 기능들을 사용할 수 없으니 개발 생산성이나, 성능에서 조금씩 계속해서 손해를 보게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 손해는 언젠가 개발 조직 전체의 발목을 잡을 수 있는 부채가 될 수 있다고 생각합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;그렇다면 어떻게 안전하게 버전을 올릴 수 있을까요?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 다른 사람들은 어떻게 버전을 올려왔을까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 지금도 버전을 올리는 pr을 머지하지 못했지만 어떻게 하면 조금 더 안전하게 배포를 할 수 있을지 찾아봤던 것들 그리고 질문했던 것들에 대해서 적어보려고 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;구글에 java11 migration guide를 검색해 보자&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/java/openjdk/transition-from-java-8-to-java-11&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;microsoft 쪽에서 가이드&lt;/a&gt;를 올려줬던 것이 있는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #161616; text-align: left;&quot;&gt;jdeps와 &lt;span style=&quot;background-color: #ffffff; color: #161616; text-align: left;&quot;&gt;jdeprscan를 통해서 java8에서 java11로 전환할 때 삭제된 api를 찾을 수 있습니다&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kordamp/jdeps-gradle-plugin&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #161616; text-align: left;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #161616; text-align: left;&quot;&gt;jdeps를 build.gradle 안에 추가하는 방법&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kordamp/jdeprscan-gradle-plugin&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #161616; text-align: left;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #161616; text-align: left;&quot;&gt;jderpscan을 build.gradle 안에 추가하는 방법&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #161616; text-align: left;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #161616; text-align: left;&quot;&gt;이렇게 추가를 하고 나면 gradle 플러그인을 통해서 사용할 수 있습니다&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #161616; text-align: left;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #161616; text-align: left;&quot;&gt;저희 서버에서는 왜인지 안되어서, bootjar를 만든 후에./gradlew jdeps와 같이 터미널을 통해서 사용했었습니다&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #161616;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;그 결과 저희 서버에서는 문제가 하나도 없다는 결과가 나왔었습니다&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #161616;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;자바 11로 프로젝트를 시작해 보자&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #161616;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;그 이후에는 java와 kotlin을 컴파일하는 sourceCompatability와 targetCompatability... 그냥 1.8로 되어있던 대부분의 설정을 11로 변경했었습니다&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #161616;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;그 이후에 로컬에서 정말 잘 실행이 되었던 것을 확인했었는데요&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 어떤 부분이 문제가 되었을까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;jvm을 실행할 때 cli에서 주는 옵션들 중 일부가 java8에서만 존재하는 옵션을 사용하고 있어서 도커 이미지가 실행되지 않는 경우가 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이후에 다른 프로젝트 (java 11)의 설정을 그대로 복사했었습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이후에는 실제 실행이 잘 되는 것을 알 수 있었습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;그러면 정말 프로젝트를 11로 올려도 될까?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나중에 실행을 하면서 cli 인수가 이상했던 것을 봤던 것처럼, 문제가 없다는 것을 보장할 수 있을까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 부분이 정말 쉽지 않습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 서버 개발자 전체가 있는 슬랙 채널에서 질문을 했었는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관련된 답변을 잘해주신 분들이 많아서 간단하게 요약을 해보려고 합니다&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;슬랙 질문을 통해 알게 된 검증 방법&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;버전업을 위한 마음가짐&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 첫 번째 분은 마음가짐을 알려주셨습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변경은 작게, 영향도 작게, 변경사항을 적용할 때 change log를 잘 읽고 진행하자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변경은 작게 - 프레임워크의 변경이라 쉽지 않겠지만 가장 작은 단위로 버전을 변경하자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영향도 작게 - 알파나 개인클러스터에서 테스트를 진행하고, QA를 해본 이후에 진행하자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;No Silver Bullet&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;버전업은 이순서로 진행하자&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라이브러리 먼저, 프레임워크 다음, 언어 버전업&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라이브러리는 언어와 프레임워크를 모두 신경 썼을 것이고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프레임워크는 언어만 신경 썼을 것이고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;언어는 아무것도 신경 쓰지 않았을 것이기에, 순서대로 올리는 것이 좋다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;다른 프로젝트의 버전을 그대로 따라가자&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;QA는 서버 부팅이 잘 되는지, 직접 수정한 코드들이 문제없이 잘 되는지(스웨거 같은 진짜 기본적인 설정)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버전업이 모든 코드에 영향을 주기 때문에, 다 안되거나 다 되거나 인 경우가 많다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버전은 다른 프로젝트의 버전을 그대로 복사하면 문제없을 가능성이 좋다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;테스트를 통해서 검증하자&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트의 종류는 총 3가지가 있을 텐데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. restTemplate 같은 실제 http call을 통해서 테스트를 진행하는 방향으로 하면 안정적으로 검증할 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. springBootTest 같은 콘텍스트를 직접 띄우는 방향으로 검증하자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. mock 등을 활용한 단위테스트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 1번 방식으로 작성된 테스트가 많다면 검증을 안정적으로 할 수 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;모든 버전을 완벽하게 이해하고 업그레이드하자&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 부트 버전업의 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 강제로 버전을 설정하여 스프링 bom 의존성을 예외로 타고 있는 라이브러리 버전을 정리한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 현재 버전의 패치버전으로 최대한 옮겨둔다 (2.3.3.RELEASE =&amp;gt;2.3.12.RELEASE)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 업그레이드할 부트의 릴리즈노트를 확인한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 현재 빈과 업그레이드 시 존재하는 빈을 확인한다 /actuator/beans&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 업그레이드 시 변경되는 라이브러리 확인 및 릴리즈 노트를 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 과정을 반복해서 스프링부트 버전을 올릴 수 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가적으로 openrewrite를 돌려보면 생각보다 놓친 부분을 많이 잡아줄 수 있다고도 하네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;더 안정성을 중요시해야 하는 프로젝트라면?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. jdk 버전업의 경우에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트의 크기가 작다면, 롬복을 탈출한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코틀린 코드를 추가한다(annotation processing이 적다면 그나마 버전에 둔감하게 바꿀 수 있습니다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. boot 버전업&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사내 라이브러리 디펜던시와 충돌 나는 게 있는지(정말 안 쓴다면 직접 exclude를 진행한다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 테스트 코드가 없다면 보장할 수 없다! 통합테스트를 해야 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알파에 반영해 두고 며칠은 지켜보자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;대고객 배포를 진행하지 않고, 임직원만 배포를 해둔다면?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;금감원에 보고를 하는 사고는 대고객 배포가 나갔을 때 문제가 됩니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것을 피하고, 트래픽을 조절해서 임직원 대상으로만 새 버전을 배포를 해둔다면 그 문제를 최대한 피할 수 있겠죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 방식으로 천천히 왕도는 없이 올려서 프로젝트를 최신 상태로 유지해 볼 수 있지 않을까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단점은 임직원 상대로만 문제인지, 전체가 문제인지 인지하기 쉽지 않은 문제가 있겠죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실제로 버전업을 했을 때 겪었던 문제&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lombok 1.6.20 에 변경된 사항&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@ConstructorProperties 가 모든 인자를 받는 생성자를 기본으로 넣어주는데, 이 부분이 @AllArgsConstructor, @Builder 를 사용하는 경우에 기본으로 붙지 않도록 변경되어서 깨져서 롤백한 케이스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 2.3.x 이하에서는 자바 17을 지원하지 않는다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한번에 자바 17 로 넘어가는 것은 2.3 이하에서는 불가능합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아마 이 글을 읽으시는 모든 분들은 버전 때문에 고통받으시다 오셨을 텐데, 저도 아직 java 11로 변경한 코드를 배포하지 못했습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마음을 편하게 먹고 아주 장기 프로젝트를 한다는 생각으로 짬짬이 도전하다 보면 결국 최신 버전의 프로젝트를 만들 수 있을 것이라고 믿어 의심치 않습니다&lt;/p&gt;</description>
      <category>Java</category>
      <category>스프링 버전업</category>
      <category>스프링부트</category>
      <category>스프링부트 버전 업</category>
      <category>자바 11</category>
      <category>자바 17</category>
      <category>자바 8</category>
      <category>자바 버전업</category>
      <author>be-student</author>
      <guid isPermaLink="true">https://be-student.tistory.com/111</guid>
      <comments>https://be-student.tistory.com/111#entry111comment</comments>
      <pubDate>Thu, 22 Feb 2024 01:00:32 +0900</pubDate>
    </item>
    <item>
      <title>토스 송금팀에서의 5개월</title>
      <link>https://be-student.tistory.com/109</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;진짜 오랜만에 여유를 찾게 되어서 5개월 동안 토스에서 느꼈던 점들에 대해서 한번 정리해보려고 해요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 있는 팀에 대한 간략한 소개는 다음과 같아요&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;토스 송금팀이란?&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;송금과 관련된 수많은 제품을 유지보수 하는 역할을 합니다&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 송금 제품팀에서 맡고 있는 제품은 정말 많은데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ATM, 하나은행 환전, 정치 후원금, 계좌 송금, 자동이체, 연락처 송금, 사진 찍어 송금, 더치페이 등이 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;이 팀의 특징은 다음과 같아요&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분이 다 금원 관련된 서버다 보니 실수를 하게 되면 바로 금감원에 보고를 할 수 있다는 압박은 언제나 존재하는 팀입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정말 많은 서버를 다루다보니, 하나의 기능에 완벽하게 몰입해서 진행을 하는 것은 힘든 팀입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 서버의 코드를 봐야하는 일이 많습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정말 안정적인 기능을 만들기 위한 다양한 안전장치가 정말 많이 있기에, 이 장치들을 보면서 배울 수 있어요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;토스 팀에서 느꼈던 다양한 기대들&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토스 팀에서 느꼈던 부분은 다음과 같아요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 크게 느꼈던 점은 서로가 서로에게 정말 큰 기대를 가지고 있는 느낌이 있어요&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 기대에는 크게 2가지 기대가 있는 것 같아요&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;첫 번째 기대는 개발자로서의 기대가 있어요&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;주어진 일을 잘하자&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분은 가장 쉬운 부분이면서 주니어 개발자로서의 기대치의 최소라고 생각합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 제가 갑자기 CTO 같은 역할을 해낼 것이라는 것을 기대하지는 않아요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;주니어로서의 역할을 완벽하게 수행하고 일을 맡겼을 때, 맡긴 부분에 대해서는 걱정하지 않아도 되는 사람일 것이다&quot;라는 기대가 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 기대는 보통 간단한 외부 요청 사항에 대응하는 것부터, 2~3주 정도 걸리는 팀이 메인으로 잡고 가는 과제를 할당받아 진행하는 것까지 다양한 것들이 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주어진 일들을 최대한 열심히 쳐내는 일을 실수 없이 마무리하면 되는 부분인데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 정직하게 시간을 투자하면 그 시간 그대로 결과가 나오는 부분입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;근본적으로 팀의 일을 바꿀 일을 생각해 보자&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 말한 최소한을 수행할 수 있다면, 그다음 기대 수준으로는 서버 개발자의 입장에서 현재 들어오는 요청이나 현재 벌어지는 상황을 보고, 이를 근본적으로 바꿀 수 있는 것들을 찾아내는 것을 요구받습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 대한 팀에서의 예시는 이런 것들이 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 어떤 과정으로 송금을 진행했는지 확인해 달라는 로그 확인 요청이 올 때가 있는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;망분리 환경에서 로그를 확인해야 하다 보니 그 시간이 오래 걸리고, 컨텍스트 스위칭 비용도 엄청 크게 작용하게 됩니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인정보와 관련된 부분을 제외하고, 망분리 환경이 아닌 환경에서 조회가 가능하다면 팀의 리소스를 절약할 수 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 팀의 병목을 해결할 수 있는 것들을 기대받는 순간이 그다음입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;두 번째 기대는 팀원으로서의 기대가 있어요&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;팀원이 갖는 최소한의 기대로는 협업의 가능 여부예요&lt;/h3&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;주니어 개발자로서의 최소한의 역량은 팀으로서 협업을 하는 것에 문제가 없는 것을 기대하고 있어요&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;한 번은 쉽지만 계속하기는 정말 어려운 부분이라고 느껴지고 &lt;/span&gt;피드백을 많이 받는 부분이기도 합니다&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;받는 피드백은 총 4가지가 있습니다&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1. 일정이 딜레이 된다면 최대한 빠르게 공유하자&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;2. 타 팀과의 협업에서 막히는 부분이 생기면 빠르게 공유하자&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;3. DM으로 일하지 말고, 최대한 공개된 채널에서 일을 진행하자&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;4. 스펙 다운을 계속 시도하자&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1, 2, 3번은 개발자가 아닌 사람에게 일의 진척도를 설명하고, 모두가 서로의 진행상황을 공유하고 현재 상황을 완벽하게 싱크 할 수 있어야 한다는 부분입니다&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 부분을 지키지 못하게 되면 저 사람은 뭘 하는지 모르겠는 사람이 되어버리고 맙니다. 그 부분에 대한 피드백을 자주 받고 있기도 하고요&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;4번의 경우에는 기획의 규모를 줄여서 비슷한 효과를 얻어낼 수 있다면 그 방향을 어떻게 해서든 찾아보기 위해 노력을 해봐야 한다는 점인데요&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;일을 더 잘하기 위해서 꼭 필요한 능력이기도 합니다&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;팀원 그 이상의 방향도 고려해 볼 수 있어요&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;팀 전체의 방향성 설정에 기여할 수 있어요&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀 전체의 방향성을 설정하는 팀의 기획에 적극적으로 의견을 내서 팀 전체의 방향성을 바꿀 수 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희 팀에 iOS 개발자 한분이 그 역할을 정말 잘하시는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;송금팀에서 바라봐야 할 것은 소비 통제를 위한 계좌 분리다라는 결론을 이끌어 내는 과정에 어마어마한 기여를 했습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과정을 요약하면 대충 이런 느낌이었는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토스에서 바라는 금융 허브로 인식시키는 전사 목표를&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;송금팀에서 서포트하려면 금융 허브로 인식하는 토스를 중요하게 여기는 유저를 많이 만들어야 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 유저의 특징은 어떤 것이 있을까? 몇 개 이상의 서비스를 사용한 사람, 몇 개월 이상 송금 서비스를 이용한 사람...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 유저를 많이 모으려면 팀이 어떤 것에 집중할 수 있을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신경을 많이 쓰는 송금에 집중해야 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 계좌 간 송금을 하게 되면, 분명 여러 계좌가 등록되어 있다는 뜻이고, 그러다 보면 토스를 중요하게 인식할 가능성이 높다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고액 송금을 많이 하게 되면 분명히 토스를 중요하게 쓰고 있을 것이다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그중에서 팀이 집중하기 좋은 것은 내 계좌 간 송금이고, 이를 하는 사례는 소비 통제를 위한 계좌 분리가 가장 많았기에 그쪽에 집중해 보자 라는 결론이 도출되었습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 팀 전체의 방향성을 바꾸는 것에 커다란 도움을 줄 수 있어요&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;팀에 새로운 업무 방식을 도입할 수 있어요&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀의 스프린트 주기를 월~금으로 돌리는 것보다, 배포 주기에 맞춰서 화~화로 조절하는 것이나, 수~수로 조절하는 것처럼 더 좋은 일정을 제안할 수 있어요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀에 외부 요청이 정말 많다 보니, 진짜 중요한 몇 가지 일들에 집중할 수 없는 환경이라면, 이를 해결하기 위해 팀에 이터레이션 방식을 바꿀 수 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매일매일 팀이 가지고 있는 이슈들을 슬랙으로 가져와서 모두의 업무 진행도를 바로 파악할 수 있도록 하는 것도 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무언가를 추가하는 것에 스크럼마스터의 승인을 필요로 하는 절차를 추가해서 팀의 집중을 높이는 방향도 가능합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 팀에 새로운 업무 방식 도입을 제안해서 팀의 업무 능률을 바꿀 수 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 것들을 서로에게 기대하고, 이를 실천하고, 최선을 다하는 동료들이 주변에 많다는 점은 정말 커다란 장점으로 여겨졌습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;개발자로서의 성장, 팀원으로서의 성장, 개인의 삶의 밸런스&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;개인의 목표 설정하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 중요한 것은 내가 뭘 하고 싶은지에 대해서 아는 것입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빅터 프랭클의 죽음의 수용소에서 라는 책에서 &quot;왜 살아야 하는지 아는 사람은 어떤 상황도 견딜 수 있다&quot;라는 내용이 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자신이 뭘 하고 싶은지 방향을 정확하게 알고 있다면 3가지의 밸런스를 잡는 것에 커다란 도움이 될 수 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;제가 되고 싶은 개발자는 2가지를 갖춘 개발자입니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;첫 번째는 기술적으로 뛰어난 개발자. 세계 최고까지는 아니더라도, 현재 사용하고 있는 기술에 대해서는 일정 수준 이상 알고 사용하는 사람이 되고 싶습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;두 번째는 기술로서 상황을 변화시킬 수 있는 사람이 되고 싶습니다. 기술은 필요할 때 사용되어야 가치를 가진다고 생각하기에, 주변에 변화를 일으킬 수 있는 상황을 잘 찾고, 이를 개선할 수 있는 능력을 가지고 싶었는데요&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;개발자의 삶 이외의 목표도 몇 가지 있는데요&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;취미를 가져서 삶이 다채롭다면 좋겠다는 생각을 하곤 합니다&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 돈이 목적이 아닌 삶이었으면 좋겠다는 생각을 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 위해서는 개발과 삶이 밸런스를 가져야 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;어떻게 하면 3가지를 모두 다 챙길 수 있을까?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에 원온원을 하면서 배웠던 부분은 하루하루의 투두리스트의 필요성입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 원하는 삶을 살기 위한 총 3가지 종류의 투두리스트가 필요합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 회사에서 하는 일에 대한 투두리스트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 개발자로서의 투두리스트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 개인의 삶을 챙기기 위한 투두리스트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하루하루 투두리스트가 정해지면 진행해 보고 며칠 동안 계속 밀리면 그 일은 주간 투두리스트가 됩니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;몇 주간 진행해 보고 계속 밀리면 그 일은 월간 투두리스트가 됩니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런 식으로 투두리스트를 관리해보려고 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 원하는 삶을 살기 위해서는 정말 시간이 부족한데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 위해서 가장 중요한 부분은 각각의 투두리스트를 위해 시간을 최대한 아껴야 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘은 매일매일 일정 시간을 정해둬서 각각의 분야에 열심히 해야 하겠다는 생각을 자주 하게 되는 것 같네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>목표</category>
      <category>회고</category>
      <author>be-student</author>
      <guid isPermaLink="true">https://be-student.tistory.com/109</guid>
      <comments>https://be-student.tistory.com/109#entry109comment</comments>
      <pubDate>Fri, 9 Feb 2024 03:29:27 +0900</pubDate>
    </item>
    <item>
      <title>Java Dto 를 Kotlin Dto로 변경하면 생기는 문제</title>
      <link>https://be-student.tistory.com/108</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번에 총 4건의 에러가 발생해서 급하게 롤백을 진행했던 사례(정말 다행히 대고객 영향은 없었습니다)에 대해서 말씀드리도록 하겠습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정말 간단하게 요약을 하면 과정은 다음과 같습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 제 서버의 Java의 Dto 클래스를 Kotlin의 data class로 변경했습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 이를 사내 nexus에 배포하였습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 이를 sdk 형태로 의존하고 있는 다른 서버를 배포했습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Jackson Deserialize Exception 이 발생해서 바로 롤백을 했습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제 기존 JavaClass 에는 NoArgumentConstructor 가 달려있었지만, data class로 변경한 클래스에는 noArgumentConstructor 가 없습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 상황을 해결하기 위해서 &lt;a href=&quot;https://www.baeldung.com/kotlin/jackson-kotlin&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;KotlinModule을 등록&lt;/a&gt;하면 되는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분은 제 서버에서는 이미 등록이 되어있기에 당연히 잘 Deserialize 될 것이라고 생각하지 못했던 것이 이 문제의 원인이었습니다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-07 오후 11.28.59.png&quot; data-origin-width=&quot;863&quot; data-origin-height=&quot;243&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dMP3we/btsC75CRhlE/rjB69Vi8U28aKUkuuVWmj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dMP3we/btsC75CRhlE/rjB69Vi8U28aKUkuuVWmj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dMP3we/btsC75CRhlE/rjB69Vi8U28aKUkuuVWmj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdMP3we%2FbtsC75CRhlE%2FrjB69Vi8U28aKUkuuVWmj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;863&quot; height=&quot;243&quot; data-filename=&quot;스크린샷 2024-01-07 오후 11.28.59.png&quot; data-origin-width=&quot;863&quot; data-origin-height=&quot;243&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해결했던 방식으로 제 서버에 요청을 보낼 때, 제 서버에 sdk에 있는 ApiCallerManager 클래스에&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1704637924916&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;new ApiCallerManager(&quot;path&quot;).registerModule(new KotlinModule())&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 코드를 추가했습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sdk를 사용하는 다른 서버에서 위의 ApiCallerManager를 import 해서 사용하게 되면, 자동으로 KotlinModule 도 함께 추가되기에 문제없이 Deserialize가 되면서 문제가 해결되었는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정을 겪고 나니 고민이 되는 부분이 생겼습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 java 에서 kotlin 마이그레이션을 진행한 이후에, 패키지나 네이밍을 바꾸지 않는다면 다른 서버의 코드도 그대로 컴파일이 되지만, 실제 런타임이 되기 전까지는 절대로 찾을 수 없는 버그가 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 정말 중요한 API였고 그 API 호출이 실제로는 진행되었지만 고객에게는 실패처리가 나가게 된다면, 같은 요청이 2번 수행되고, 이에 따라 보상을 해줘야 할 수도 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 이 부분을 무조건 테스트를 통해서 잡게 된다면 ApiCallerManager에서 요청을 하는 모든 path를 serialize 하고, 그 결과물을 다시 DeSerialize 하도록 하면 이 문제를 해결할 수 있을 것 같기는 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 이 부분이 없다고 하면? 지금같은 문제를 결코 피할 수 없기에 테스트를 작성할 필요성이 있다는 생각이 확실히 드는 시간이었습니다&lt;/p&gt;</description>
      <category>Spring</category>
      <category>data class</category>
      <category>deserialize</category>
      <category>Jackson</category>
      <category>NoArgsConstructor</category>
      <category>NoDefaultConstructor</category>
      <author>be-student</author>
      <guid isPermaLink="true">https://be-student.tistory.com/108</guid>
      <comments>https://be-student.tistory.com/108#entry108comment</comments>
      <pubDate>Sun, 7 Jan 2024 23:47:04 +0900</pubDate>
    </item>
    <item>
      <title>장애 없는 코드를 만드려면 어떻게 해야할까?</title>
      <link>https://be-student.tistory.com/107</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번주 금요일에 정말 장애와 함께 한 날인데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크고 작은 총 3번의 장애가 날뻔한 것과, 잘못된 데이터가 내려가는 문제가 있었고, 슬랙 채널에서 승건 님을 포함한 거의 가장 높은 3명을 쭈르륵 만났습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 처음에 승건님을 만난 것은 어드민 페이지에서 특정 필드가 누락되어, 서빙되는 데이터가 잘못된 부분입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분은 그래도 제가 배포한 부분이랑은 관련이 바로 있지 않아 간접적으로 엮여있어서 좀 덜 신경 쓰였지만, 이후에 2번은 제 배포와 직접 연관이 되어있어 회고를 하기 위해서 글을 작성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제 사수분이 작성한 코드에서 카프카 토픽을 잘못된 곳에 집어 넣어서, 서비스에서 사용하는 카프카에 데이터를 추가한 것이 아니라, 로그 카프카에 데이터를 추가하면서 Unknown Topic 이 발생했었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정말 다행히도 기존 데이터나 유저들에게 영향이 없었습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제가 없었던 이유는 다음과 같습니다. 기존 카프카 토픽 consume =&amp;gt; 기존 로직 =&amp;gt; 새롭게 카프카 produce(장애가 난 포인트) 순으로 되어있어서, 기존 로직이 모두 끝난 이후에 작동을 하게 짜져 있어서 문제가 없었습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 사건을 거치면서 어떻게 하면 기존 유저나 데이터에 흐름에 영향을 주지 않고, 기능을 추가 및 변경을 할 수 있을까에 대해서 생각해보았습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 가장 큰 포인트는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;기존 로직에 영향을 최소한으로 주어야 한다&lt;/b&gt;&lt;/span&gt;는 것입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 생각했던 형태의 데이터만 있는 것이 아니라 다른 형태의 데이터가 들어가 있다면 이 로직은 실패할 텐데, 그러면 무슨 일이 일어나지?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 고객은 어떤 화면을 보게 되지? 하는 고민을 하면서 안전장치를 만들어야 한다고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분을 저희 팀에서 redis 캐시를 도입할 때도 비슷하게 느꼈던 것 같습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시를 도입은 했지만, 이 캐시가 제대로 동작할지 보장할 수 없다면, 기존 로직을 그대로 다 태우고, 캐시는 단순히 같은지 판정하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서로 다르다면 로그만 남겨두는 용도로 사용하고 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;캐시가 다르다는 로그가 일정 기간 이상 올라오지 않는 것을 확인한 이후에 캐시를 진짜 도입하기로 한 것인데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 과정을 통해서 깨지지 않는 캐시라는 것을 보장할 수 있었습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 봤던 유튜브 영상 중에서 기억에 남는 내용이 있고, 이 글에도 추가하면 좋을 것 같아서 링크를 추가해 두었습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떻게 하면 이 기능을 망가뜨릴 수 있지? 를 먼저 생각한 이후에, 어떻게 하면 그 망가뜨리는 부분을 막을 수 있지라는 것을 떠올려본다면 좋은 결과가 있을 것 같습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=vZSzdDOKq4o&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.youtube.com/watch?v=vZSzdDOKq4o&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=vZSzdDOKq4o&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/bFRncu/hyUTzywgby/ANfkZ45HccbciXxSOMqfj0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=438_100_714_400&quot; data-video-width=&quot;300&quot; data-video-height=&quot;169&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;버크셔 부회장 찰리멍거의 사고모델&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/vZSzdDOKq4o&quot; width=&quot;300&quot; height=&quot;169&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;찰리멍거 거꾸로 생각하기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로젝트</category>
      <category>장애 코딩 하기</category>
      <category>장애 회고</category>
      <author>be-student</author>
      <guid isPermaLink="true">https://be-student.tistory.com/107</guid>
      <comments>https://be-student.tistory.com/107#entry107comment</comments>
      <pubDate>Sun, 24 Dec 2023 15:00:29 +0900</pubDate>
    </item>
    <item>
      <title>여러분들은 동적 쿼리 어떻게 쓰시나요? (우리 팀에서Jpa Criteria 를 선택한 이유)</title>
      <link>https://be-student.tistory.com/106</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 자바에서 사용할 수 있는 다양한 동적 쿼리 방법을 알아보고, 왜 Jpa Criteria를 선택했는지 말씀드리려고 합니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에 프로젝트에서 어드민 페이지를 만들던 과정에서 여러 가지 조건으로 필터링되어야 하는 데이터를 쿼리 할 필요가 생겼습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상태가 성공인 데이터를 여러 조건에 맞게 조회해야 하는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원본 데이터는 총 3000건 정도이고, 상태가 성공인 건은 1500건 정도입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 생각했던 방법은 총 5가지 정도가 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;동적 쿼리의 종류&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. findAll을 사용한 이후에 Application에서 처리한다&lt;/h4&gt;
&lt;div style=&quot;background-color: #2b2b2b; color: #a9b7c6;&quot;&gt;
&lt;pre class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;@Component
class ApplicationQuery(
    private val userRepository: UserRepository
) {
    fun findUserByName(name: String): List&amp;lt;User&amp;gt; {
        val users = userRepository.findAll()
        if (name == null) {
            return users
        }
        return users.filter { it.name == name }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에 방식을 선호하시는 분들도 꽤나 계셨습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어드민이기 때문에 TPS를 고려할 필요가 없기 때문이기도 하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 개수가 얼마 되지 않기 때문에, 이 정도까지는 애플리케이션에서 충분히 필터링할 수 있다는 의견이셨습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떻게 해서든 효율적인 쿼리로 좋은 결과를 내야 한다는 것과는 다른 의미로 오히려 요즘 추세는 DB에 로직을 두지 않는 것을 선호하기도 한다고 하더라고요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB 가 가장 귀중한 자원이기에, 부담을 최대한 애플리케이션 레벨로 옮겨두는 것이 좋다고 알려주셨습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저도 처음에는 그렇게 하려고 했었지만, 여기서 나온 결과를 바탕으로 송금 원장에 ids in (*) 구문을 통해 질의를 해야 한다는 것을 깨닫고, 바로 포기하였습니다&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. String을 + 를 통해 연산한다&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 간단한 방법이긴 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학습 테스트를 통해 확인할 수 있는 것처럼, 아래와 같은 결과를 의도하고 있고요&lt;/p&gt;
&lt;div style=&quot;background-color: #2b2b2b; color: #a9b7c6;&quot;&gt;
&lt;pre class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;class StringQueryBuilderTest : StringSpec({

    &quot;기본 쿼리는 1 = 1 이 끝에 붙는다&quot; {
        val query = StringQueryBuilder.create(&quot;SELECT * FROM USER&quot;)
            .build()

        query shouldBe &quot;SELECT * FROM USER WHERE 1 = 1&quot;
    }

    &quot;isEquals 는 필드와 값을 비교하는 쿼리를 생성한다&quot; {
        val query = StringQueryBuilder.create(&quot;SELECT * FROM USER&quot;)
            .isEquals(&quot;name&quot;, &quot;bestudent&quot;)
            .build()

        query shouldBe &quot;SELECT * FROM USER WHERE 1 = 1 AND name = bestudent&quot;
    }
})&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #2b2b2b; color: #a9b7c6;&quot;&gt;
&lt;pre class=&quot;kotlin&quot;&gt;&lt;code&gt;class StringQueryBuilder internal constructor(
    private val query: String
) {
    fun isEquals(field: String, value: String): StringQueryBuilder {
        return StringQueryBuilder(&quot;$query AND $field = $value&quot;)
    }

    fun build(): String {
        return query
    }

    companion object {
        fun create(query: String): StringQueryBuilder {
            return StringQueryBuilder(&quot;$query WHERE 1 = 1&quot;)
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드는 다음과 같습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직관적이긴 하지만, &quot;name&quot; 같은 필드를 실수로 잘못 넣게 된다면, 런타임에 문제가 발생하게 됩니다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분을 피하고자 다른 방법을 알아보게 되었습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. Jpa Repository에 조건마다 쿼리를 추가한다&lt;/h4&gt;
&lt;div style=&quot;background-color: #2b2b2b; color: #a9b7c6;&quot;&gt;
&lt;pre class=&quot;kotlin&quot;&gt;&lt;code&gt;interface UserRepository : JpaRepository&amp;lt;User, Long&amp;gt; {

    fun findAllByName(name: String): List&amp;lt;User&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;repository에 추가된 형태는 위와 같고&lt;/p&gt;
&lt;div style=&quot;background-color: #2b2b2b; color: #a9b7c6;&quot;&gt;
&lt;pre class=&quot;kotlin&quot;&gt;&lt;code&gt;@Component
class AllQuery(
    private val userRepository: UserRepository
) {
    fun findUserByName(name: String?): List&amp;lt;User&amp;gt; {
        if (name == null) {
            return userRepository.findAll()
        }
        return userRepository.findAllByName(name)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 코드를 짜게 되면, 조건이 1개 늘어날 때마다, 모든 쿼리가 2배씩 늘어나기 때문에, 간단한 조건 1~2개라면 괜찮지만, 아니라면 복잡도를 매우 높이게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. 1개의 Big Query를 만들어서 질의한다&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿼리 하나에, Null이라면 어떻게 처리하고, 아니라면 조건을 추가하는 형태로 전부 작성한다&lt;/p&gt;
&lt;div style=&quot;background-color: #2b2b2b; color: #a9b7c6;&quot;&gt;
&lt;pre class=&quot;kotlin&quot;&gt;&lt;code&gt;@Component
class OneBigQuery(
    private val userRepository: UserRepository
) {
    fun findUserByName(name: String?): List&amp;lt;User&amp;gt; {
        return userRepository.findAllByNullableName(name)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식으로 service 레이어는 간단해지게 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1703392794860&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Query(
	value = &quot;&quot;&quot;
    	SELECT t
        FROM Transfer t
        WHERE 1=1
        AND (
        	(:senderUserNo IS NULL OR t.senderUserNo = :senderUserNo)
        )
)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿼리는 다음과 같은 형태로 짜면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 되면, 단점으로는 쿼리 테스트를 하기가 힘듭니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿼리 쪽에 복잡한 로직이 들어가다 보니, 데이터가 잘 올 것이라는 보장을 하기가 쉽지 않을 수 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5.&amp;nbsp; QueryDSL을 사용한다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;QueryDSL을 사용해서 동적 쿼리를 만들 수도 있습니다&lt;/p&gt;
&lt;pre id=&quot;code_1703393140754&quot; class=&quot;reasonml&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;@Test
void queryDsl_FetchJoinComments_Success() {
    EntityManager entityManager = testEntityManager.getEntityManager();

    JPAQuery&amp;lt;Post&amp;gt; query = new JPAQuery&amp;lt;&amp;gt;(entityManager);
    QPost qPost = new QPost(&quot;p&quot;);
    QComment qComment = new QComment(&quot;c&quot;);

    List&amp;lt;Post&amp;gt; posts = query.distinct()
        .from(qPost)
        .leftJoin(qPost.comments, qComment).fetchJoin()
        .fetch();

    assertThat(posts).hasSize(3);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 형태로 qClass를 사용하는 방식이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 여기서 QueryDSL 이 가지고 있는 치명적인 단점으로는 프로젝트가 무거워질 수 있다는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;qClass를 사용해야 하기에, 추가적으로 컴파일을 진행해야 하고, 버전문제도 생길 수 있다는 점에서 프로젝트에 추가하기 어려울 것이라는 결론을 내렸습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;그래서 어떤 것을 사용해야 좋을까?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 질문을 서버 개발자 전체가 있는 슬랙 채널에 올렸습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거기서 나온 좋은 방식으로 JpaSpecification을 사용하면 된다고 알려주셨습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희 팀은 Kotlin을 사용하고 있기 때문에, Kotlin의 DSL을 사용한다면 querydsl과 비슷하게 동작하는 것을 만들 수 있다고 하시면서, 버전문제도 없이 갈 수 있다는 장점을 알고서 이를 통해 사용하기로 하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1703393844664&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fun &amp;lt;T&amp;gt; initSpec(): Specification&amp;lt;T&amp;gt; = Specificaion&amp;lt;T&amp;gt; { _, _, _ -&amp;gt; null }

fun &amp;lt;T, VALUE&amp;gt; Specification&amp;lt;T&amp;gt;.equalNotNull(fieldName: String, value: VALUE?): Specification&amp;lt;T&amp;gt;=
	if(value == null) this else
    	this.and { root, _, builder -&amp;gt;
        	builder.equal(root.get&amp;lt;VALUE&amp;gt;(field), value)
        } as Specification&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 Specification을 사용하고, 실제 코드는 다음과 같습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1703393981388&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;val userSpec = initSpec&amp;lt;User&amp;gt;()
	.equalNotNull(
    	fieldName = User::name.name,
        value = &quot;be-student&quot;
    )
val user:List&amp;lt;User&amp;gt; = userRepository.findAll(userSpec)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 사용하게 되면, 동적 쿼리를 작동시킬 수 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 userRepository 쪽에 interface 하나를 추가적으로 추가해야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1703394063800&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Repository
interface UserRepository: JpaRepository&amp;lt;User,Long&amp;gt;,
	JpaSpecificationExecutor&amp;lt;User&amp;gt;{
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게만 만들면 기존 코드에 큰 변화 없이 동적 쿼리를 쓸 수 있다는 부분이 좋은 것 같아서 Specification 쪽을 사용하기로 결정했습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Criteria를 사용하다 보면, HQLQueryPlan 객체가 Heap 메모리를 과도하게 사용하는 문제가 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1703394269826&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;spring:
	jpa:
    	properties:
        	hibernate:
            	criteria:
                	literal_handling_mode: bind&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 형태의 property를 추가해주셔야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학습 비용의 문제로 사용하지는 않았지만, 다른 좋은 방법으로는 line의 kotlin-jdsl이나, Exposed를 사용할 수도 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;긴 글을 읽어주셔서 감사합니다&lt;/p&gt;</description>
      <category>Spring</category>
      <category>Criteria</category>
      <category>JPA</category>
      <category>Jpa Criteria</category>
      <category>JpaSpecification</category>
      <category>동적 쿼리</category>
      <author>be-student</author>
      <guid isPermaLink="true">https://be-student.tistory.com/106</guid>
      <comments>https://be-student.tistory.com/106#entry106comment</comments>
      <pubDate>Sun, 24 Dec 2023 14:07:11 +0900</pubDate>
    </item>
    <item>
      <title>MDC 를 활용해 부가적인 정보를 남겨보자</title>
      <link>https://be-student.tistory.com/105</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;MSA 환경으로 오면서, 특정 사용자가 어떤 행동을 했는지 파악해서 대응하기 어렵습니다&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;어려운 이유는 여러 가지가 있을 수 있는데요&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1. 로그가 각 서비스마다 흩어져있다&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2. 하나의 API 호출에서 발생한 로그들을 묶어서 볼 수 없다&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1을 해결하기 위해서 보통 로그를 중앙에서 모아서 관리하게 되는데요&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이를 위해 현재 제가 일하고 있는 곳에서는 하나(이중화는 고려하지 않겠습니다)의 거대한 Elastic Search 클러스터를 구성해 두고, 그 클러스터에서 모든 로그를 모아서 관리하고 있습니다&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2번째 문제를 해결하기 위해서 API Gateway에서 eventId를 만들어 요청에 헤더에 포함시킨 후 릴레잉 해줍니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그 eventId를 로그에 포함시켜서, 이벤트 id 기준으로 묶어서 로그를 확인하고 있습니다. 더 자세한 내용은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://toss.tech/article/slash23-server&quot;&gt;영상&lt;/a&gt;을 확인해 주세요&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이때, eventId를 로그에 까먹고 안 남길 수도 있잖아요?&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;그 부분을 신경 쓰지 않아도 되도록 해주는 것이 MDC입니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #4d5156; text-align: left;&quot;&gt;Mapped Diagnostic Context으로,&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #4d5156; text-align: left;&quot;&gt;&lt;span&gt;여기서 ThreadLocal을 사용한다는 점이 장점이자 단점이 되는데요&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #4d5156; text-align: left;&quot;&gt;&lt;span&gt;한 스레드에서 많은 요청이 처리되는 Netty에서는 이 부분을 관리하기 위해서 Reactor을 잘 다뤄야 하는 부분이 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #4d5156;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;하지만 Spring MVC의 Request Per Thread 모델에서는 정말 편리하게 사용할 수 있습니다&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4d5156;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;하나의 request 가 하나의 스레드에서만 관리되기에 MDC에서 정보를 꺼내면 같은 요청이라는 것은 명확해지니까요&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4d5156;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;그렇다면 실제 구현을 해볼까요?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;구현을 간단하게 만든 부분은 다음과 같습니다&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;HandlerInterceptor를 구현해, requestHeader에서 eventId 나, userId 같은 로그를 묶어서 볼 때 필요한 것들을 mdc에 넣어둡니다.&lt;/p&gt;
&lt;div style=&quot;background-color: #2b2b2b; color: #a9b7c6;&quot;&gt;
&lt;pre class=&quot;kotlin&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot;&gt;&lt;code&gt;@Component
class MdcInterceptor : HandlerInterceptor {
    override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
        val eventId = request.getHeader(&quot;key-event-id&quot;) ?: UUID.randomUUID().toString()
        val userId = request.getHeader(&quot;key-user-id&quot;)
        MDC.put(&quot;eventId&quot;, eventId)
        MDC.put(&quot;userId&quot;, userId)
        return true
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #2b2b2b; color: #a9b7c6;&quot;&gt;
&lt;pre class=&quot;kotlin&quot;&gt;&lt;code&gt;@Configuration
class WebConfig(private val mdcInterceptor: MdcInterceptor) : WebMvcConfigurer {

    override fun addInterceptors(registry: InterceptorRegistry) {
        registry.addInterceptor(mdcInterceptor)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;컨트롤러에서는 평범하게 로그만 남기면 됩니다.&lt;/p&gt;
&lt;div style=&quot;background-color: #2b2b2b; color: #a9b7c6;&quot;&gt;
&lt;pre class=&quot;kotlin&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot;&gt;&lt;code&gt;@RestController
class TestController {

    @GetMapping(&quot;/test&quot;)
    fun test(): String {
        log.info(&quot;test&quot;)
        return &quot;test&quot;
    }

    private companion object {
        private val log = getLogger(this::class.java)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;logback.xml 은 다음과 같이 두었습니다&lt;/p&gt;
&lt;div style=&quot;background-color: #2b2b2b; color: #a9b7c6;&quot;&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;&amp;lt;configuration&amp;gt;

    &amp;lt;appender name=&quot;CONSOLE&quot; class=&quot;ch.qos.logback.core.ConsoleAppender&quot;&amp;gt;
        &amp;lt;encoder&amp;gt;
            &amp;lt;pattern&amp;gt;%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n&amp;lt;/pattern&amp;gt;
        &amp;lt;/encoder&amp;gt;
    &amp;lt;/appender&amp;gt;

    &amp;lt;root level=&quot;info&quot;&amp;gt;
        &amp;lt;appender-ref ref=&quot;CONSOLE&quot;/&amp;gt;
    &amp;lt;/root&amp;gt;
&amp;lt;/configuration&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 시작을 하고 나서 http://localhost:8080/test에 요청을 보내면 아래와 같이 로그가 남습니다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-12-03 오후 8.17.01.png&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;70&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0Usib/btsBjCoRANF/jLBmFZsDhU1eErPk9jmRL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0Usib/btsBjCoRANF/jLBmFZsDhU1eErPk9jmRL1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0Usib/btsBjCoRANF/jLBmFZsDhU1eErPk9jmRL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0Usib%2FbtsBjCoRANF%2FjLBmFZsDhU1eErPk9jmRL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1550&quot; height=&quot;70&quot; data-filename=&quot;스크린샷 2023-12-03 오후 8.17.01.png&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;70&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;열심히 만든 MDC 가 보이지 않는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;logback의 기본 설정에서 콘솔에 남길 때 MDC를 남기지 않는 것 때문인데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;콘솔에 남길 때도 MDC를 남기도록 해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;logback.xml 에서&lt;/p&gt;
&lt;div style=&quot;background-color: #2b2b2b; color: #a9b7c6;&quot;&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;&amp;lt;encoder&amp;gt;
    &amp;lt;pattern&amp;gt;%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg[%X{eventId}]%n&amp;lt;/pattern&amp;gt;
&amp;lt;/encoder&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부분을 추가해 두었습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 로그를 남기게 되면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뒷줄에 이벤트 id 가 남게 되는 것을 볼 수 있습니다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-12-03 오후 8.22.21.png&quot; data-origin-width=&quot;1932&quot; data-origin-height=&quot;78&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLALYq/btsBkmFVWTQ/JjgVCM7J1kdjTyJQw0DVc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLALYq/btsBkmFVWTQ/JjgVCM7J1kdjTyJQw0DVc1/img.png&quot; data-alt=&quot;이벤트 id 가 남는 것&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLALYq/btsBkmFVWTQ/JjgVCM7J1kdjTyJQw0DVc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLALYq%2FbtsBkmFVWTQ%2FJjgVCM7J1kdjTyJQw0DVc1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1932&quot; height=&quot;78&quot; data-filename=&quot;스크린샷 2023-12-03 오후 8.22.21.png&quot; data-origin-width=&quot;1932&quot; data-origin-height=&quot;78&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이벤트 id 가 남는 것&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 eventId를 남겨두게 되면, 추후에 검색을 했을 때 eventId를 기준으로 묶어볼 수 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추후에 이 MDC 정보를 활용해서 비트를 활용해 ElasticSearch 에 적재를 하게 된다면 검색하기 정말 편한 상태가 됩니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 간단하게 MDC에 대해서 알아보았습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;짧은 글 읽어주셔서 감사합니다&lt;/p&gt;</description>
      <category>Spring</category>
      <category>MDC</category>
      <author>be-student</author>
      <guid isPermaLink="true">https://be-student.tistory.com/105</guid>
      <comments>https://be-student.tistory.com/105#entry105comment</comments>
      <pubDate>Sun, 3 Dec 2023 20:28:00 +0900</pubDate>
    </item>
    <item>
      <title>백엔드 취준 질문을 받아준다고 글을 올려보았다</title>
      <link>https://be-student.tistory.com/104</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;추석 연휴와 한글날 여유가 생겼는데, 이 연휴를 어떻게 하면 더 의미 있게 보낼 수 있을까라는 고민을 하다 보니 개발자 취업이나, 간단한 질문들을 받아주는 것으로 사용하면 어쩔까 하는 생각이 들었습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;같은 학교만 볼 수 있는 커뮤니티나, 공개적으로 볼 수 있는 커뮤니티에 올려보고, 거기서 사람들의 질문을 받아봤습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;학교 커뮤니티에서는 총 12명에게 질문 답변을 진행했습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;공개적으로 볼 수 있는 커뮤니티의 경우에도 13명에게 질문 답변을 진행했습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;우테코에서 이력서 피드백을 요청했던 1명도 있었습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;총 26명과 질문 답변을 진행해 보고 거기에서 나왔던 질문들을 기록해 두고, 어떤 빈도로 질문이 나왔는지 정리해 두면 나중에도 도움이 될 것 같아서 미리 정리를 해두려고 합니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;질문 답변을 끝내고 나니 생각보다 선물을 많이 주셔서 놀랐습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;처음에는 아무 생각 없이 시작했는데, 가면 갈수록 더 알려주려고 했던 것 같습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;받은 선물 리스트&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1. 다음 주에 저녁을 사주신다는 분&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. 치킨 황금올리브 1마리 + 콜라 1.25리터&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3. 스벅 아이스 카페라테 T 2잔&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4. 스벅 아이스 아메리카노 T 2잔&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5. 스벅 돌체라테 T 1잔&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;6. 메가커피 5000원 교환권&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다 합치면 7만 원 가까이가 나오더라고요&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;생각보다 궁금한 사람이 많고, 간단한 선물을 해주려는 사람이 많다는 것을 확실히 느낄 수 있었습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;내용적인 측면&lt;/span&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;생각보다 사람마다 들어가는 시간이 많이 달랐습니다&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;길게 한 사람은 거의 1시간 30분 정도가 들어갔던 반면&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;짧게 한 사람은 카톡에서 대화를 신청하고, 그 이후에 아무 말도 없었습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;모든 분들과의 대화 내용 요약을 각각 하면(개인정보나 그런 부분들은 다 떼어냈습니다) 다음과 같습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;끝에는 많이 나온 질문에 대한 답을 나름대로 만들어보았습니다&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;첫 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;내년 여름에 졸업을 해서, 1년 정도 학습 기간이 있고, 그&amp;nbsp; 이후에 취직을 시도하려는 사람&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 분 같은 경우는 다른 언어를 사용해서 프로젝트를 진행했고(js) 목표로 하는 회사에 취업을 하려면 얼마나 노력을 해야 하는지가 궁금하셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이분의 경우에는 인프라 쪽 공부를 하면서, 배포 환경을 어떻게 구성할지, 테스트코드, 모니터링, 성능 최적화 같은 부분에 대해서 시도해 보면 좋을 것 같다고 말씀을 드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다른 언어를 사용했던 경험은 질문 답변을 할 수 있다면 적는 것을 추천하지만 아니라면 큰 도움이 되지 않을 수 있다는 내용을 말씀을 드렸습니다&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;두 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;경력 이직을 하려고 하는데, 이력서를 봐달라는 내용이 메인이셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이력서에서 다른 사람에게 보여줬을 때, 자신만의 강점을 만드는 것에 어려움을 겪고 계셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;제 사례에서 강점을 만드는 방식에 대해서 배워보려고 하셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;저는 이력서를 적을 때 총 3가지 포인트에 집중해서 적었다고 말씀드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1. 협업 과정에 문제가 없다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. 성능 최적화 같은 부분을 고민해 봤다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3. 회사에 가서 어떤 역할을 할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;지금까지 최소 7~8개의 스터디를 진행했고, 2개의 개발 동아리에서 프로젝트를 진행했던 부분이 협업의 강점으로 드러날 수 있을 것 같았습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;성능 최적화 부분은 카페인 프로젝트 덕분에 정말 편하게 채울 수 있었습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;회사에서는 혼자만의 성장이 아니라, 같이 성장하는 문화를 위해서 노력할 것이다라는 부분을 드러내려고 했습니다(이력서 상에서는 팀 블로그였겠죠)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이력서를 적으실 때, 최대한 수치를 기반해서 적으라고 말씀을 드리고, 여러 가지 부분을 바꾸어주었습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;경력직에게 기대하는 협업 사례나, 해결했던 문제에 대해서 잘 포장할 수 있도록 도와드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고 왜 이 기능을 만들었는지, 개선을 왜 했는지에 대해서 이유를 드러내라고 말씀을 드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;세 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;가장 난감했던 분인데요&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;백엔드가 아니라, 배치 프로그래머가 백엔드로 경력 이직을 하려고 하는데, 얼마나 학습해야 하는지를 여쭤보셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;어떤 회사에 가고 싶다도 명확하지 않고, 백엔드에는 가고 싶지만, 현재 해본 거는 없다는 것을 듣고서 어떻게 대답을 더 해나갈지 모르겠더라고요&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;가장 애매하게 끝이 났던 것 같습니다&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;네 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;현재 석사까지 진행했는데, 취업한 분야가 전공이랑 맞지 않고, 백엔드랑 그나마 가깝다는 느낌이 들어서 백엔드 쪽으로 지금 경력을 살려서 이직할 수 있을까 하는 내용을 말씀해 주셨지만 가장 큰 고민은 다음 질문이었습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;수많은 개발자들이 있을 텐데, 대체가 안 되는 개발자가 되려면 어떻게 해야 할까 라는 부분에 대해서 많은 고민을 하고 계셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;저는 어차피 모든 사람들은 다 대체가 될 테니 최대한 많은 회사에서 필요로 하는 기술을 가지고 있도록 하려고 한다는 말씀을 드리고 마무리를 했던 것 같습니다&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다섯 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;현재 기업들이 채용을 안 하는데, 어떻게 어필을 했는지 이력서가 가장 궁금하셨던 것 같습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이분에게 인프라 쪽을 다양하게 해 보라고 말씀드리고, 우테코도 시도해 봐도 괜찮겠다는 말씀도 드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여섯 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;알고리즘을 어떻게 공부해야 할지가 궁금하셨던 것 같습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;한 가지 카테고리를 정하고 하루에 몇 문제씩 꾸준히 풀어가는 방식으로 공부했다고 말씀드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이력서도 궁금했는데, 이력서에 자기만의 강점을 어떻게 녹여냈는지가 궁금하셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;일곱 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로젝트를 시작하는데 두려움이 많다고 하셨던 분입니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로젝트에서 다른 사람에게 민폐가 되는 것을 정말 무서워해서 1인분을 할 수 있는 실력의 기준을 알고 싶어 하셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;현재 공부하고 있던 부분 외로 어떤 것들을 공부해야 하는지나 어떤 기술스택이 좋은지를 여쭤보셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;저는 프로젝트를 진행할 때 간단한 CRUD 만 할 줄 알고, 배포를 할 줄 알면 괜찮다는 말을 드렸습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;백엔드면 스프링이 최고라는 말을 드렸고요&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이력서에 프로젝트가 몇 개여야 하는지도 궁금하셨고, (관계없다고 답변드렸습니다)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;각 기술을 어마나 깊게 알아봐야 하는지도 궁금하셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;당연히 깊으면 깊을수록 좋지만, 현실적으로 다른 부분도 크게 문제가 되지 않도록 만드는 것도 중요하다고 말씀을 드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여덟 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;우테코 준비를 하고 계시고, 프로젝트 경험을 어떻게 채워나갔는지가 궁금하셨던 분입니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;처음 배우는 입장에서 가장 먼저 할만한 공부, 시도해 볼 만한 거리가 있는지가 궁금하셨던 분 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;과거에 프로그라피와 디프만 2개의 동아리를 했던 부분을 위주로 설명을 드렸던 것 같아요&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;아홉 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;네카라쿠배에 가려면 어느 정도의 역량이 필요한지가 궁금하셨던 분이었습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;면접관을 잘 만나는 게 가장 중요하다는 말씀을 드리고, 자신의 강점 분야로 끌고 갈 수 있도록 이력서를 만드는 것을 위주로 설명을 드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;열 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;현재 어떤 방향으로 학습을 하려고 하는 학습 계획을 정리해서 주시고, 이 부분에서 추가로 할만한 것들을 궁금해하셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Mysql의 인덱스를 활용한 성능 최적화&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;모니터링&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;무중단 배포&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;테스트코드&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이렇게 4가지 키워드로 학습을 해보시면 좋을 것 같다고 말씀을 드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;코테 준비에 대한 내용도 있었던 것 같네요. 위에서 설명드린 내용과 동일하게 카테고리를 정하고, 하루에 몇 개씩 푸는 것이 좋다고 말씀을 드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;열한 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;우테코 지원을 하려고 하는데, 베이스가 어느 정도였냐 라는 부분에 대해서 질문을 해주셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;저는 다른 언어로 백엔드를 했고, 자바는 우테코 1개월 전에 제대로 처음 사용해 봤다는 것을 알려드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;우테코를 다녀본 입장에서 어떤 것들이 좋냐는 질문을 했고, 열심히 하는 사람들이 많은 환경이라는 부분을 설명드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로젝트를 하려는 상황에서 사람을 어떻게 모았냐는 질문에 위와 비슷하게 개발 동아리를 했다는 내용을 드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;열두 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;우테코 프리코스 과정에서 어떤 것들을 얻을 수 있는지가 궁금하셨던 것 같습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;또한 취업 때 프로젝트가 몇 개였냐는 부분을 여쭤보셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;면접 때 CS를 얼마나 중요하게 생각하는지도 여쭤보셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프리코스는 자바를 진짜 몰랐을 때라서 자바를 많이 배웠다는 내용을 전달드리고, 프로젝트는 2개, CS는 토스에서는 안 물어봐서 모르겠다는 말을 드렸습니다. 다른 언어로 봤을 때는 그렇게까지 힘들진 않았던 것 같다고 전달했었습니다&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;열세 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;현재 백엔드 개발자를 목표로 하고, 대규모 it 서비스 기업에 가고 싶어 하셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;스프링은 강의만 몇 개 들어보셨고, 프로그래머스 레벨 1 정도를 풀 수 있다는 상황이셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5개월 안에 취업을 하시고 싶어 하시는 상황이어서, 코딩테스트는 아얘 포기하고, 프로젝트와, CS 질문에 올인하는 방향이 현실적으로 가능성을 조금이라도 올릴 수 있어 보인다는 말을 드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5개월 안에 다 하는 것 자체도 쉽지 않을 테니까요&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;열네 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;개발자라는 진로를 가는 것에 대해서 고민이 많으신 상황이었어요&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;전공자인지&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;왜 개발을 시작했는지&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;왜 백엔드 개발자가 되고 싶은지를 질문하셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;저 같은 경우는 전공자였고&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;개발을 시작한 이유는 마인크래프트 게임에서 모드를 직접 만들고 싶다는 욕심에서 시작하게 되었다고 말씀을 드리고, 백엔드 개발자가 되고 싶었던 이유는 프론트엔드(CSS)를 못하겠어서 도망갔다는 내용을 사실대로 말씀드렸어요&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;열다섯 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;개인 프로젝트를 어떻게 시작하는지가 가장 궁금하셔서 동아리를 많이 써먹었다고 말씀을 드렸어요&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;우테코에서 훈련지원금 부분이 궁금했었고, 프리코스 과정이 어떤 과정인지에 대해서 질문을 많이 하셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;겪어봤던 입장에서 어떤 경험이었는지 설명을 드리려고 했었습니다&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;열여섯 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로젝트 경험이 최소 몇 개가 필요하냐고 생각하는지가 궁금하셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여러 프레임워크를 사용해 본 게 큰 메리트가 되냐는 질문을 하셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로젝트 수는 크게 상관이 없고, 프레임워크를 여러 개 써본 것도 큰 메리트가 되지 않는다고 말씀을 드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;백엔드라면 스프링 위주로 가는 게 가장 취업 시장에 유리할 것 같다고 전달을 드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;열일곱 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;우테코를 해보고 싶으면, 어떻게 준비해야 하고, 합격하면 무엇을 배우는지에 대해서 여쭤보셨습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;정말 뻔한 답변으로 자소서 열심히 써야 하고, 프리코스 열심히 해야 한다는 내용을 드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;합격을 하게 되면 다른 부트캠프와 다르게 코테나 CS에 대해서는 전혀 다루지 않고, 언어나 설계, 프로젝트에 집중한다고 말씀을 드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;제 학점, 프로젝트 수를 궁금해하셨는데요&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;학점은 정말 낮아서 큰 도움은 안 될 것 같고, 프로젝트는 총 5개고 이력서에는 2개만 썼다고 전달을 드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;열여덟 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;우테코에 자소서의 비중이 궁금하셨던 것 같고, 코테 준비를 어떻게 했는지가 궁금했던 것 같습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;몰입 키워드에 어떤 내용을 썼는지도 궁금하셨던 것 같았습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자소서의 비중은 생각 이상으로 크고, 코테 준비는 카테고리를 정해서 보라고 했던 내용을 그대로 했습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;몰입 키워드에서 저는 고등학교 때 공부했던 것들을 썼고, 쓸 때 평범한 것보다는 많이 겹치지 않는 것이면 좋지 않을까?라는 생각을 전달해 드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;열아홉 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;현재 JS로 백엔드를 시작했는데, JS로 가는 게 메리트가 있는지 여쭤보셔서 스프링으로 가는 게 좋다고 말씀을 드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;저도 JS로 백엔드를 하다가 스프링으로 전부 엎고 바꾸었던 경험이 있으니까요&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;스무 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;백엔드 처음 시작을 어떻게 해야 하는지 궁금해하시고 계셔서, 최소한의 인강을 듣고 프로젝트를 시작해서 고도화해 보는 경험이 중요할 것 가다고 전달드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;알고리즘이나 CS 쪽을 궁금해하시는 분이셔서 알고리즘은 카테고리를 정했고&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;CS는 유튜브를 참고했다고 말씀을 드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;블로그를 쓰는 것이 좋다고 추천을 드리기도 했었고요&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;스물한 번째 분&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;창업 경험이 있고, 그때 경험이 백엔드 개발자여서 이를 바탕으로 백엔드에서 경력 이직을 하려고 하는데, 이력서를 쓰는 방법에 대해서 여쭤보셨던 분이었습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;추가적으로 학습 방향에 대해서 궁금해하시는 것 같아서, 가상면접 사례와 Real Mysql을 추천해 드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;제 이력서를 드리면서, 자신만의 강점을 만드는 것이 중요하다고 말씀을 드렸습니다&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;공통된 질문들&lt;/span&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1. 코테는 어떻게 준비하면 좋을까요?&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;하나의 카테고리를 정해서 하루에 몇 문제씩 꾸준히 푸는 게 제일 나았던 것 같습니다&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. 프로젝트의 팀원을 어떻게 구하는 게 가장 좋을까요?&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;개발 동아리를 통해서 구하는 것이 가장 편했습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;아니라면 직접 커뮤니티에서 모으는 방법이 있을 테지만, 그때의 퀄리티는 정확하게 보장하기 쉽지 않으니까요&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3. 최소한의 프로젝트를 하고 나서 어떤 것들을 해보면 좋을까요?&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Mysql의&amp;nbsp;인덱스를 활용한 성능 최적화&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;모니터링&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;무중단 배포&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;테스트코드&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이렇게 4가지를 시도해 보면 좋을 것 같습니다&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4. 어떤 프레임워크로 시작하는 것이 좋나요?&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;최대한 많이 쓰이는 쪽으로 가는 게 취업을 하기 편합니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;백엔드면 스프링, 프론트엔드라면 리액트겠죠&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다른 언어나 프레임워크보다 자료가 많다는 것이 가장 큰 장점으로 여겨졌습니다&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;노드 쪽의 자료에 비해서 훨씬 많은 자료들이 있다는 게 가장 큰 장점으로 느껴졌으니까요&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5. 이력서를 쓸 때 어떤 부분을 강조하려고 하셨나요&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1. 협업 과정에 문제가 없다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. 성능 최적화 같은 부분을&amp;nbsp;고민해 봤다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3. 회사에 가서 어떤 역할을 할 수 있다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4. 최대한 수치를 드러내려고 했다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5. 왜 이 기능을 구현했는지가 드러나면 좋다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;저는 지금까지 최소 7~8개의 스터디를 진행했고, 2개의 개발 동아리에서 프로젝트를 진행했던 부분이 협업의 강점으로 드러날 수 있을 것 같았습니다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;성능 최적화 부분은 카페인 프로젝트 덕분에 정말 편하게 채울 수 있었습니다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;회사에서는 혼자만의 성장이 아니라, 같이 성장하는 문화를 위해서 노력할&amp;nbsp;것이다라는&amp;nbsp;부분을 드러내려고 했습니다(이력서 상에서는 팀 블로그였겠죠)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;경력이 있다면, 협업을 해서 문제를 해결했던 사례를 넣을 것 같습니다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;연휴에 시간을 보낸 것이 후회되지 않는 알찬 시간이었습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;긴 글을 읽어주셔서 감사합니다&lt;/span&gt;&lt;/p&gt;</description>
      <category>목표</category>
      <category>백엔드</category>
      <category>백엔드 취준</category>
      <category>이력서</category>
      <category>취준</category>
      <author>be-student</author>
      <guid isPermaLink="true">https://be-student.tistory.com/104</guid>
      <comments>https://be-student.tistory.com/104#entry104comment</comments>
      <pubDate>Mon, 9 Oct 2023 22:23:39 +0900</pubDate>
    </item>
  </channel>
</rss>