-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
263 lines (141 loc) · 90.5 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
<title>Seha's Devlog</title>
<link>https://sehajyang.github.io/</link>
<atom:link href="/atom.xml" rel="self" type="application/rss+xml"/>
<description>Junior Developer</description>
<pubDate>Fri, 06 May 2022 04:13:53 GMT</pubDate>
<generator>http://hexo.io/</generator>
<item>
<title>개발 요구사항을 분석하는 방법</title>
<link>https://sehajyang.github.io/2022/05/06/how-to-analyze-work/</link>
<guid>https://sehajyang.github.io/2022/05/06/how-to-analyze-work/</guid>
<pubDate>Fri, 06 May 2022 04:00:00 GMT</pubDate>
<description>
<h2 id="들어가며"><a href="#들어가며" class="headerlink" title="들어가며"></a>들어가며</h2><p>사실 기술에 대한 글은 많지만, 개발자가 어떻게 업무를 분석하고 작게 나눠야 하는지에 대한 글은 상대적으로 적다.<br>이 글은 업무 분석에 어려움을 겪는 주니어 개발자분들을 위해 작성됐다.</p>
<p>신입 땐 업무를 어떻게 분석하고 파악하고 구현해야 하는지를 잘 알지 못했다.<br>무작정 만들어본 뒤 빠진 케이스를 뒤늦게 추가하거나 요구사항 분석을 잘못해 구현 방향이 잘못되어 구현 자체를 다시 한 적도 있었다.<br>재작업을 하게 됨에 따라 시간도 오래 걸렸고, 급하게
</description>
<content:encoded><![CDATA[<h2 id="들어가며"><a href="#들어가며" class="headerlink" title="들어가며"></a>들어가며</h2><p>사실 기술에 대한 글은 많지만, 개발자가 어떻게 업무를 분석하고 작게 나눠야 하는지에 대한 글은 상대적으로 적다.<br>이 글은 업무 분석에 어려움을 겪는 주니어 개발자분들을 위해 작성됐다.</p><p>신입 땐 업무를 어떻게 분석하고 파악하고 구현해야 하는지를 잘 알지 못했다.<br>무작정 만들어본 뒤 빠진 케이스를 뒤늦게 추가하거나 요구사항 분석을 잘못해 구현 방향이 잘못되어 구현 자체를 다시 한 적도 있었다.<br>재작업을 하게 됨에 따라 시간도 오래 걸렸고, 급하게 구현하면서 품질을 어느 정도 포기하기도 했다.<br>이러한 일련의 과정에서 어떻게 하면 이러한 비효율을 줄이고 올바른 기능을 제대로 만들 수 있는지 고민해왔었는데, 답을 내기가 쉽지 않았다.<br>그도 그럴게, 구현하기전에 모든 문제를 정의하고 설계하는건 굉장히 어렵다. 불투명한 요구사항을 구체화하며 모든 케이스를 정의하는건 어려운 일이다.<br>그렇다고 해서, 대략적으로 파악하고 구현을 시작하면 종종 예상치 못한 문제에 맞닥뜨리게 된다.<br>그러한 고민 과정에서 동료의 피드백이 있었고 이를 바탕으로 업무 분석하는 방법을 정의하게 됐다.<br>지금은 주어진 요구사항이 복잡한 경우 이 포스팅에서 설명할 방법을 사용하여 해결하고 있으며, 이러한 노력으로 시간의 손실은 줄이며 어느 정도 내가 원하는 ‘올바른 기능을 제대로’ 만들 수 있게 됐다.</p><h2 id="요구사항을-분석하고-설계하는-방법"><a href="#요구사항을-분석하고-설계하는-방법" class="headerlink" title="요구사항을 분석하고 설계하는 방법"></a>요구사항을 분석하고 설계하는 방법</h2><p>처음에 기능 구현 요구사항을 받으면 문제가 하나의 큰 덩어리처럼 느껴지고 어느 부분부터 어떻게 접근해야 할지 감이 잘 오지 않는다.<br>숙련도가 높은 시니어라면, 보자마자 어떤 지뢰가 있고 어떻게 해결해야 목적을 달성할 수 있는지 알 것이다.<br>하지만 나는 어디에 어떤 지뢰가 있고, 어떻게 해결해야 하는지 하나하나 고민하고 확인해봐야 했다.<br>다음은 내가 사전 분석과 설계 구현 정의를 위해 나에게 던지는 질문이다.<br>(사용자는 포괄적인 의미로 API 혹은 모듈에서 공개한 기능을 사용하는 클라이언트를 의미한다) </p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line">- 요구사항 분석</span><br><span class="line"> - 요구사항 정의는 어떤가?</span><br><span class="line"> - 요구사항에 누락된 부분은 없는가? </span><br><span class="line"> - 현재 시스템이 요구사항을 수용할 수 있는가?</span><br><span class="line"> - 요구사항의 전제조건은 어떻게 되는가?</span><br><span class="line"> - 시간 비용은 어떤가?</span><br><span class="line">- 설계 할 때</span><br><span class="line"> - 사용자 예상 시나리오는 어떻게 되는가?</span><br><span class="line"> - 동시성 문제가 있는가?</span><br><span class="line"> - 사용자는 어떤 데이터를 기대하고, 어떻게 사용할까?</span><br><span class="line"> - 이 정보가 정말 사용자에게 필요한 정보인가?</span><br><span class="line"> - 이 정보에 커플링이 생기면 미래에 어떤 일이 생길까?</span><br><span class="line"> - 시스템 내부 리펙토링시 발목을 잡지는 않을까?</span><br><span class="line">- 인터페이스</span><br><span class="line"> - 사용자를 생각해서 최대한 알기쉽게, 간결하고 깔끔하게 만들어졌는가?</span><br><span class="line"> - 작업하기 전에 인터페이스는 설계해야한다</span><br><span class="line"> - 만약 인터페이스가 어그러지면 다시 고민하고 리팩토링 해야된다</span><br><span class="line">- 구현할 때</span><br><span class="line"> - 이 데이터의 속성은 어떤가? 어떤 특성을 갖고 있는가?</span><br><span class="line"> - 어떻게 해야 이 데이터를 적절히 제공할 수 있는가?</span><br><span class="line"> - 이 데이터를 사용하는 클라이언트는 누구인가? 클라이언트에게 어떤 데이터를 제공해야 하는가</span><br><span class="line"> - 이 API를 사용하는 사용자는 이 API를 보고 어떤 역할과 행동을 하는지 예측하기가 쉬운가?</span><br><span class="line"> - 불필요한 정보를 외부에 공개하지 않았나?</span><br><span class="line"> - 너무 많은 책임을 갖고 있진 않은가?</span><br><span class="line"> - 적절한 예외를 주는가?</span><br><span class="line"> - 이 기능은 어떤 행동을 하고 어떤 책임이 있는가?</span><br><span class="line"> - 어떤 데이터가 주어지고 어떻게 처리하며 어떤 결과를 줘야 하는가?</span><br><span class="line"> - 참조 기능은 어떤 스펙을 갖고 있는가, 만약 예외를 던진다면 이 기능내에선 그 에러를 어떻게 처리해야하는가?</span><br><span class="line"> - 이 기능 요구사항과 전제 조건(accaptance criteria) 는 뭔가?</span><br><span class="line"> - 요구사항을 명확하게 이해했는가?</span><br><span class="line"> - 이 기능의 시나리오가 어떤가?</span><br><span class="line"> - 클라이언트에 의존성을 갖고있는가?</span><br><span class="line"> - 이 기능의 요구사항과 예외가 인터페이스에 잘 표현이 되었는가?</span><br><span class="line"> - 다른 프로그래머도 유지보수 할 수 있도록 이해하기 쉬운 코드를 작성했는가?</span><br><span class="line">- 작업 계획은 어떤가?</span><br><span class="line"> - 기존 구조를 파악했는가?</span><br><span class="line"> - 작업 개요를 식별하고 작성했는가</span><br><span class="line"> - 작업은 충분히 적절하게 쪼개졌는가?</span><br></pre></td></tr></table></figure><p>위 질문에 맞춰 요구사항에 대한 분석과 설계가 끝났다면 설계에 맞춰 작업계획을 아주 작게 나눈다.<br>보통 작업 계획 항목대로 PR을 나누게 된다. </p><ul><li>참고 (PR이 너무 클 경우 리뷰어에게 피로감을 줄 수 있으므로 PR 사이즈는 4~500줄이 넘지 않는 선으로 유지하는 게 좋다)</li></ul><p>작업 계획까지 다 정의했다면 동료와 이러한 컨텍스트를 공유한다. 이 크로스 체킹 과정에서 잘못된 방향 혹은 누락된 부분, 더 좋은 방법등에 관해 얘기를 나눌 수 있고 올바른 구현을 할 수 있게 된다. </p><p>하지만 이 모든 원칙이 늘 지켜져야만 하는 건 아니다.<br>원칙이 지금 상황과 맞지 않는다 판단되면 원칙을 무시할 수도 있다. 가장 중요한건 <strong>현재 상황에 가장 적합한 해결책</strong>이다. </p>]]></content:encoded>
<comments>https://sehajyang.github.io/2022/05/06/how-to-analyze-work/#disqus_thread</comments>
</item>
<item>
<title>2021년 상반기 회고</title>
<link>https://sehajyang.github.io/2021/06/20/2021-postmortem-half-of-year/</link>
<guid>https://sehajyang.github.io/2021/06/20/2021-postmortem-half-of-year/</guid>
<pubDate>Sun, 20 Jun 2021 05:21:00 GMT</pubDate>
<description>
<h2 id="서론"><a href="#서론" class="headerlink" title="서론"></a>서론</h2><p>올해 초의 이직 이후 조금 바빴고 최근엔 개인적인 학습에 대한 정리는 노션에 하고 있었기 때문에 블로그 글을 작성하지 않았었다.<br>지금은 조금 여유가 생겼고 오랜만에 상반기 회고를 작성하게 되었다.</p>
<h2 id="상반기에-있었던-일"><a href="#상반기에-있었던-일" class="headerlink" title="상반기에 있었던 일"></a>상반기에 있었던 일</h2><h3 id="이직"><a href="#이직" class="headerlink"
</description>
<content:encoded><![CDATA[<h2 id="서론"><a href="#서론" class="headerlink" title="서론"></a>서론</h2><p>올해 초의 이직 이후 조금 바빴고 최근엔 개인적인 학습에 대한 정리는 노션에 하고 있었기 때문에 블로그 글을 작성하지 않았었다.<br>지금은 조금 여유가 생겼고 오랜만에 상반기 회고를 작성하게 되었다.</p><h2 id="상반기에-있었던-일"><a href="#상반기에-있었던-일" class="headerlink" title="상반기에 있었던 일"></a>상반기에 있었던 일</h2><h3 id="이직"><a href="#이직" class="headerlink" title="이직"></a>이직</h3><p>이직을 했다!<br>그간 함께 성장할 동료가 있었으면 좋겠다는 아쉬움이 있었고, 그것은 이직을 결정하는데에 어느정도 영향을 줬다.<br>회사를 고르는 기준은 사람마다 다르겠지만 나에겐 성장할 수 있는 동료가 가장 중요했다.<br>한 두달 준비를 했고 지원할 회사 리스트를 정리한 뒤 코딩테스트와 기술 면접 준비를 했다.<br>준비 과정은 다음과 같다.</p><ul><li>지원할 회사 리스트 정리<ul><li>지원할 회사에서 중요하게 보는 부분을 파악했다.</li></ul></li><li>이력서 작성<ul><li>이력서는 기술 중심으로 깔끔하게 작성하고 성장과정 등 불필요한 내용은 포함하지 않았다.</li></ul></li><li>코딩테스트 준비<ul><li>알고리즘 준비를 혼자 하는것이 정신적으로 지쳐서 지인들과 함께 알고리즘 스터디를 했다.</li><li>백준 강의를 보고 여러가지 문제를 풀며 준비했다.</li><li>국내 회사의 코딩테스트 통과를 위한 준비는 대체로 이 정도면 충분하다.<ul><li>백준 : 실버~골드</li><li>프로그래머스 : lv2~lv3</li><li>codility</li></ul></li></ul></li><li>기술면접<br>주니어의 경우 보통 경험이나 이력서 기반 질문 혹은 cs 질문이 들어오며, 자바 개발자의 경우 자바, 스프링과 관련된 질문을 받게 될 확률이 높다.<br>회사마다 중요하다 생각하는게 다르기 때문에 JD를 보며 예상 면접 질문을 준비하는게 좋다.<br>면접을 몇번 진행하다 보면 회사마다 어느정도 공통적으로 하는 질문이 있는데 이 부분은 <code>자바 개발자 기술면접</code> 등으로 검색해보면 많이 나온다.</li><li>합격<br>감사하게도 가고싶었던 회사중 하나였던 <strong>마켓컬리</strong>에 백엔드 개발자로 합류하게 됐다 😊</li></ul><h2 id="상반기에-학습한-것"><a href="#상반기에-학습한-것" class="headerlink" title="상반기에 학습한 것"></a>상반기에 학습한 것</h2><h3 id="책"><a href="#책" class="headerlink" title="책"></a>책</h3><ul><li>이펙티브 자바 3/e<ul><li>필독서</li><li>과거에 읽다 말았었는데 이번에 처음부터 끝까지 정리하며 읽었다. </li><li><a href="https://github.com/sehajyang/TIL/tree/master/Java/Effective-Java" target="_blank" rel="noopener">이펙티브 자바 정리</a></li></ul></li><li>오브젝트 <ul><li>필독서</li><li>이것도 읽다 말았었는데, 입사 후 프로젝트를 파악하는데에 필요해서 급하게 읽었다.</li><li><a href="https://github.com/sehajyang/TIL/tree/master/Architecture/Object" target="_blank" rel="noopener">오브젝트 정리</a></li></ul></li><li>클린 아키텍쳐<ul><li>컴포넌트 설계랑 패키지 설계 부분이 가장 인상깊었다. 다시 봐도 좋을 책이다.</li></ul></li><li>클린 코더<ul><li>선배 개발자가 썰 풀어주는 느낌을 받았다. 앞선 책에 비해 가볍게 읽을 수 있어서 좋았다.</li></ul></li><li>모던 자바 인 액션<ul><li>반정도 봤다. 자바 8이상을 사용하는 자바 개발자라면 꼭 읽어봐야 할 책이다.</li></ul></li><li>head first 디자인 패턴<ul><li>gof랑 같이 봤다.</li></ul></li><li>자바 네트워크 프로그래밍<ul><li>이 책은 절반정도 봤다.</li></ul></li><li>프로그래밍 수련법<ul><li>예제가 대체로 c, c++라서 조금 어렵지만 설계나 디버깅, 테스트에 대한 내용이 예제 기반으로 꼼꼼하게 쓰여져있다.</li></ul></li></ul><h2 id="상반기에-아쉬웠던-일"><a href="#상반기에-아쉬웠던-일" class="headerlink" title="상반기에 아쉬웠던 일"></a>상반기에 아쉬웠던 일</h2><h3 id="블로그"><a href="#블로그" class="headerlink" title="블로그"></a>블로그</h3><p>학습한 것에 대해 블로그에 정리할 만큼 정리하지 못했기 때문에 기술 포스팅을 하지 않았다.<br>하반기엔 블로그에 포스팅으로 작성할 수 있을 만큼 학습한걸 다듬고 싶다.</p><h3 id="일어나지도-않은-일-걱정하기"><a href="#일어나지도-않은-일-걱정하기" class="headerlink" title="일어나지도 않은 일 걱정하기"></a>일어나지도 않은 일 걱정하기</h3><p>내 기대치와 나의 능력 사이에 갭 때문에 괴로워하며 일어나지도 않은 일을 꽤 최근까지도 걱정했다.<br>주위로부터 일어나지 않은 일에 대해 걱정하지 말고 해결 방법을 고민하라던가 강박을 가지면 쉽게 지치니 천천히 여유를 갖고 학습 하라는 조언을 들었었는데 조언을 들을 당시엔 머리로는 알겠는데 어떻게 해야할지를 몰랐다.<br>그러다가 최근에는 지금 상태를 인정하고, 걱정하고 있기보단 걱정하는 일이 일어날 가능성을 줄이는 방법을 알게 됐다.<br>당연히, 걱정만 하기보단 대책을 세우고 움직이는 게 합리적인데 그걸 제대로 받아들이고 실천하기까지의 시간이 좀 걸렸다. </p><h2 id="총평"><a href="#총평" class="headerlink" title="총평"></a>총평</h2><p>이직 이후 상반기동안 내가 우물 안의 개구리였다는걸 매일 깨닫곤 급하게 이것저것 많이 학습했다.<br>그 과정이 좋기도 하고 힘들기도 했지만, 동료분들께 좋은 영향이나 도움을 받으며 성장할 수 있어서 정말 감사하고 즐거웠다.<br>많이 배우고 받은 만큼 하반기엔 받은 걸 돌려줄 수 있는 동료가 되고 싶다!</p><p>“하기 싫어도 해라 감정은 사라지고 결과는 남는다”라는 말이 있는데, 나에겐 맞지 않았다.<br>나의 경우엔 강박을 낮추고 하고 싶은 일을 적절히 섞어 즐거운 감정을 잃지 않으며 학습하는 게 효율이 높았다.<br>그러니 하반기엔 강박에서 벗어나서 좀 더 여유를 갖고 야크 셰이빙을 하며 실무 기술뿐만 아니라 개인적으로 좋아하는 기술들에 대해 학습을 해야겠다.</p>]]></content:encoded>
<comments>https://sehajyang.github.io/2021/06/20/2021-postmortem-half-of-year/#disqus_thread</comments>
</item>
<item>
<title>2020년 회고</title>
<link>https://sehajyang.github.io/2020/12/27/2020-review/</link>
<guid>https://sehajyang.github.io/2020/12/27/2020-review/</guid>
<pubDate>Sun, 27 Dec 2020 03:27:59 GMT</pubDate>
<description>
<p>올해로 세번째 연간회고를 쓰게되었다.<br>작년에 비해 개인공부는 적었지만 실무에서 배운게 굉장히 많은 해 였다.<br>한가지 꼽으라면 역시 서비스 리뉴얼 오픈이다.</p>
<h3 id="서비스-리뉴얼-오픈"><a href="#서비스-리뉴얼-오픈" class="headerlink" title="서비스 리뉴얼 오픈"></a>서비스 리뉴얼 오픈</h3><p>기존의 node + mongodb + k8s 로 되어있던 서비스를 spring + rdb + netflix oss + ecs 기반으로 바꾸는<br>아에 프로젝트를 새로 만드는 수준의 리뉴얼이었다. 하지만 마이그레이션 해야할 데이터가 있고, 그 데이터는 nosql
</description>
<content:encoded><![CDATA[<p>올해로 세번째 연간회고를 쓰게되었다.<br>작년에 비해 개인공부는 적었지만 실무에서 배운게 굉장히 많은 해 였다.<br>한가지 꼽으라면 역시 서비스 리뉴얼 오픈이다.</p><h3 id="서비스-리뉴얼-오픈"><a href="#서비스-리뉴얼-오픈" class="headerlink" title="서비스 리뉴얼 오픈"></a>서비스 리뉴얼 오픈</h3><p>기존의 node + mongodb + k8s 로 되어있던 서비스를 spring + rdb + netflix oss + ecs 기반으로 바꾸는<br>아에 프로젝트를 새로 만드는 수준의 리뉴얼이었다. 하지만 마이그레이션 해야할 데이터가 있고, 그 데이터는 nosql db에 있었고 rdb에 맞게끔<br>모델링을 짜야했고..<br>기존 서비스는 정상적으로 운영되고있었으며 리뉴얼 한 서비스로 교체되어야했다. 그야말로 달리는 차의 바퀴를 갈아끼우는 작업이었다.<br>정신차리고 보니 2020년 하반기였다. 오픈하기 며칠 전 동료님께서 평생 오픈을 겪지 못하는 개발자도 있으며, 오픈을 겪는건 중요한 경험이라고 하셨다. 힘들었지만 돌이켜보면 많은걸 배운 경험이었다. </p><h3 id="MSA"><a href="#MSA" class="headerlink" title="MSA"></a>MSA</h3><p>실무 프로젝트는 Netflix OSS로 되어있고, 도메인을 나눴다.<br>하지만 AWS의 managed service들과 함께 쓰기엔 여러가지 문제가 있었다. 그래서 상반기엔 MSA관련해서 공부를 많이 했다.<br>그 과정에서 ECS도 써보고 로깅서버를 만든느라 ELK도 살짝 사용해보고 하는 등 여러모로 넓게 학습하고 구축했었다.<br>구축도 해보고 잘못 됐다는걸 깨닫고 여러 시도도 해보는등 시행착오가 많았다. 레퍼런스도 부족했다.<br>나중에 알고보니 우리 서비스 뿐만 아니라 다른 서비스에서도 똑같이 겪고 있는 문제였다.<br>아무래도 이 시행착오는 포스팅으로 써두는게 좋겠다. </p><h3 id="토이프로젝트"><a href="#토이프로젝트" class="headerlink" title="토이프로젝트"></a>토이프로젝트</h3><p>올해 작업한 토이프로젝트는 엔젤핵 2020에서 수상한 지역기반 공동구매 플랫폼이 있고<br>그 외엔 이력서 공개 서비스인 토이프로젝트를 만들고있다. 지금은 잠시 중단했는데, 2021년 상반기에는 어느정도 완성하고싶다.</p><h3 id="운영체제"><a href="#운영체제" class="headerlink" title="운영체제"></a>운영체제</h3><p>운영체제를 공부했다. 개발을 모르는 상태로 배웠었을땐 지루하고 재미없었지만 이래서 그랬구나! 라는 생각이 드는 부분이있어 굉장히 재미있었다.<br>언젠간 꼭 운영체제를 만들어보고싶다. 이건 내 개발 인생 목표다ㅎㅎ</p><h3 id="읽은-책"><a href="#읽은-책" class="headerlink" title="읽은 책"></a>읽은 책</h3><p>이펙티브 자바를 읽고 오브젝트를 조금 읽었다.<br>주위에 이 책을 좋아하는 분이 있어 종종 이에 대해 얘기도 나누고 했는데, 이 책들은 실무에 직접적으로 도움이 된 부분이 많아서 좋았다.<br>그외엔 JVM 책을 읽었다. 중간에 내용이 딥해지긴 했지만 대략적으로 크게 설명하고있어서 올해 가장 잘 읽은 책이다.</p><h3 id="알고리즘"><a href="#알고리즘" class="headerlink" title="알고리즘"></a>알고리즘</h3><p>연초~중반엔 지인들과 알고리즘 스터디를 했고 종종 몇문제씩 풀어왔다. 확실히 과거보단 잘 풀게 됐지만 아직 부족하다..</p><h3 id="학습한-강의"><a href="#학습한-강의" class="headerlink" title="학습한 강의"></a>학습한 강의</h3><ul><li><a href="https://www.inflearn.com/course/the-java-code-manipulation/dashboard" target="_blank" rel="noopener">더 자바, 코드를 조작하는 다양한 방법</a></li><li><a href="https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%8D%B0%EC%9D%B4%ED%84%B0-jpa" target="_blank" rel="noopener">스프링 데이터 JPA</a></li><li><a href="https://www.inflearn.com/course/스프링-데이터-JPA-실전/" target="_blank" rel="noopener">실전! 스프링 데이터 JPA</a></li><li><a href="https://www.inflearn.com/course/스프링부트-JPA-API개발-성능최적화/" target="_blank" rel="noopener">실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화</a></li><li><a href="https://www.inflearn.com/course/ORM-JPA-Basic" target="_blank" rel="noopener">자바 ORM 표준 JPA 프로그래밍 - 기본편</a></li><li><a href="https://www.inflearn.com/course/%EB%B0%B1%EA%B8%B0%EC%84%A0-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0" target="_blank" rel="noopener">스프링 시큐리티</a></li><li><a href="https://www.inflearn.com/course/스프링-핵심-원리-기본편/" target="_blank" rel="noopener">스프링 핵심 원리 - 기본편</a><br>실무에서 내가 담당한 서비스는 100% JPA + QueryDSL었고 쿼리 최적화나 도메인간의 연관관계매핑이 중요했기 때문에 JPA강의를 많이 들었다.<br>강의 외에 InfoQ 유투브에서 MSA 관련된 영상을 좀 봤는데 그것도 굉장히 좋았다.</li></ul><h3 id="비동기"><a href="#비동기" class="headerlink" title="비동기"></a>비동기</h3><p>파이썬으로 프로덕션일부에 돌아가는 비동기 서버를 만들었다. 연초에 만들었는데, 비동기로 바꾼 뒤 성능이 굉장히 좋아져서 뿌듯했다.<br>예외처리 하는게 좀 힘들었다. 당시엔 어렵고 힘들었고 시행착오를 많이해서 전체 리팩토링을 굉장히 많이 했었는데 기록해둘걸 하는 아쉬움이 있다. </p><h2 id="총평"><a href="#총평" class="headerlink" title="총평"></a>총평</h2><p>이직 후 오픈과 운영하느라 정신없는 해를 보냈다.<br>코로나로 인해 오프라인 세미나를 못가면서 점점 쳐진것도 있고 전체적으로 좀 지쳐서 개인공부에 게으른 해 였다.<br>다만 실무에서 배운게 굉장히 많았고 새로운 경험도 많이 해봤다.<br>팀에 백엔드 개발자는 대체로 나 포함 1~2명이었어서 아무래도 담당하게 되는 일이 많았고 그로 인해 다양한 작업을 접할수있어서 좋았다.<br>다만 실무에서 새로운걸 많이 해보는 만큼 개인공부는 기존에 학습한것에 대해 깊이있는 공부를 했어야했는데 소흘했다.<br>2021년엔 부지런히 학습하고 새로운거보단 깊이있는 학습을 하고싶다.</p>]]></content:encoded>
<comments>https://sehajyang.github.io/2020/12/27/2020-review/#disqus_thread</comments>
</item>
<item>
<title>2020년 하반기 회고</title>
<link>https://sehajyang.github.io/2020/10/25/20200801-20201025/</link>
<guid>https://sehajyang.github.io/2020/10/25/20200801-20201025/</guid>
<pubDate>Sun, 25 Oct 2020 14:30:00 GMT</pubDate>
<description>
<p>그간 회고를 작성하지 않았는데, 회고를 작성하지 않으니 뭘 했는지 도무지 기억이 나지 않았다. 그래서 오랜만에 회고를 작성해본다.<br>요즘은 JVM책을 읽고 있다. [JVM성능튜닝이야기]라는 책인데 어려울거란 걱정이 무색하게 책은 정말 이해하기 쉽게 쓰여져있다.</p>
<p>더 자바 강의도 완강했다. JVM 책 읽기 전에 들었는데 그 덕에 JVM 책 읽기가 한층 수월했다.<br>중간에 해커톤도 나가서 상을 타왔다. 올해는 코로나때문에 해커톤을 못할 줄 알았는데 온라인 해커톤을 할 수 있어서 좋았다.<br>요즘은 지인들이랑 릴리즈를 목표로 한 토이프로젝트를 만들고있다. 오랜만에 여러 사람들과 하는 토이프로젝트고
</description>
<content:encoded><![CDATA[<p>그간 회고를 작성하지 않았는데, 회고를 작성하지 않으니 뭘 했는지 도무지 기억이 나지 않았다. 그래서 오랜만에 회고를 작성해본다.<br>요즘은 JVM책을 읽고 있다. [JVM성능튜닝이야기]라는 책인데 어려울거란 걱정이 무색하게 책은 정말 이해하기 쉽게 쓰여져있다.</p><p>더 자바 강의도 완강했다. JVM 책 읽기 전에 들었는데 그 덕에 JVM 책 읽기가 한층 수월했다.<br>중간에 해커톤도 나가서 상을 타왔다. 올해는 코로나때문에 해커톤을 못할 줄 알았는데 온라인 해커톤을 할 수 있어서 좋았다.<br>요즘은 지인들이랑 릴리즈를 목표로 한 토이프로젝트를 만들고있다. 오랜만에 여러 사람들과 하는 토이프로젝트고 토이프로젝트인만큼 자유도도 높고 즐겁게 하고있다.<br>알고리즘 스터디를 8월 초 부터 시작했다. 중간에 한계를 느끼고 프로그래머를 위한 기초 수학이라는 책을 샀다. </p><h2 id="하반기에-한-학습-및-개발"><a href="#하반기에-한-학습-및-개발" class="headerlink" title="하반기에 한 학습 및 개발"></a>하반기에 한 학습 및 개발</h2><ul><li>ELK 구축</li><li>ECS with Netflix OSS to EB</li><li>이팩티브 자바, 오브젝트</li><li>더 자바 강의 완강</li><li>스프링 핵심원리 강의</li><li>JVM 성능튜닝 이야기</li><li>엔젤핵 해커톤</li><li>토이프로젝트</li><li>알고리즘 스터디</li></ul><h3 id="ELK-구축"><a href="#ELK-구축" class="headerlink" title="ELK 구축"></a>ELK 구축</h3><p>회사에서 ELK 로 로깅 시스템을 구축했다.<br>우리 서비스들은 ecs + fargate로 되어있으며 ec2처럼 직접 접근할수 없었기 때문에 그간 papertrail 라는 cloud 로깅 서비스를 이용하고있었는데 한달 200기가에 160만원정도로 굉장히 비쌌다.<br>물론 EFS를 사용하면 컨테이너 내부의 스토리지에도 접근할수 있지만 이 또한 100기가에 30달러로 굉장히 비싸다.<br>우리 서비스는 한달에 약 400GB 정도 로그가 쌓이기 때문에 비용적인 측면에선 적절하지 않았다.<br>그리고 ELK도 managed 로 구축하면 비쌌기때문에 ec2에 직접구축했다(사이즈는 t3 xlarge로 했는데 널널했다)<br>구글링해보면 구축하는 방법에 대한 내용은 많지만 구축한 뒤 최적화 하는 내용은 별로 없었다.<br>우선 우리 서비스 컨테이너 내부에서 로그를 파일로 쌓도록 했다. 처음엔 tcp 포트를 열어서 웹서버에서 tcp 스트림으로 logstash 로 로그를 보내주는 방법을 하려고 했으나 그렇게 구성하면 웹서버가 받는 부하가 크기때문에 파일로 쌓고 filebeat가 중앙 수집기(logstash)로 보내도록 했다.<br>로그는 logstash 에서 정규식으로 메세지를 분석해서 필드화 하는 방법이 있는데, 정규식은 비용이 비싸기 때문에 logstash 가 받는 부하를 줄이고자 웹서버에서 파일로 쌓을때 json 형식으로 쌓도록 하고 logstash 에선 간단한 데이터 후처리나 필드 제외 작업만 하도록 구성했다.<br>이렇게 하니 logstash가 처리해야할 연산이 복잡하지도 않았고 작업량도 아주 많진 않았기 때문에 logstash가 받는 부하가 적었다. 그리고 filebeat에서 send 딜레이를 줬기 때문에 중간에 redis같은 버퍼를 둘 필요도 없었다.<br>es에도 부하가 크진 않았기 때문에 굳이 es 노드를 3개 둘 필요는 없어서 한개만 사용하도록 했는데, 나중에 인덱싱 부하가 커지면 세개로 늘릴 예정이다.<br>웹 서비스 특성상 request response를 다 남기게 되는데 단순 get 요청같은 경우 es에 넣을만큼 중요한 데이터는 아니기 때문에 그러한 full log 는 일정 주기로 s3로 보내고, 중요한 데이터만 es로 보내고 시각화를 했다.<br>처음엔 팀원의 요청으로 request, response를 다 es로 보내고 kibana에서 시각화했는데 es에서 인덱싱은 문제가 없었으나 kibana로 보려고 하니 웹 브라우저가 뻗어버렸다.<br>당시 로그가 1 row 당 50만 byte 그러니까 50kb였고 브라우저에선 한번에 몇백개씩 로그를 렌더링해야했기 때문에 브라우저가 뻗는건 당연한것이었다.<br>이쯤되면 최초 구축할땐 보이지 않았던것들이 보였다. 가령 웹서버에 aws log agent를 붙이고 cloudwatch로 로그를 받아서 es로 로그를 보내줄수도 있고, efs를 쓰고 그 로그를 s3 + lambda => es 로 보내줄수도 있다.<br>전자는 fargate 를 사용할시 log agent 에 직접 configuration 을 적용할수없어서 못했으며(ec2에선 직접 log agent를 설치하고 설정을 할 수 있었다. 만약 fargate에 log agent 사용시 설정을 하는 방법을 아는 분은 댓글로 알려주시면 감사합니다) efs + s3 + lambda 방법은 비싸다.<br>여러가지 시도와 고민끝에 나는 logstash multi pipeline communication 을 하기로 결정했다.<br>웹서버와 filebeat의 부하가 최대한 적어야했기 때문에 logstash 쪽에 부하를 주는 방법을 선택했다.<br>파이프는 총 세개로 구성했다. 로그를 수신받아 두 가상주소에 나눠주는 메인 파이프, 가상 주소로부터 받은 로그를 주기적으로 s3로 전송하는 파이프, logstash 필터를 거쳐 es에 인덱싱하기 좋게 가공해 es로 보내주는 파이프 이렇게 세개로 구성했다.<br>그렇게 최종적으로 filebeat + logstash + elasticsearch + kibana + s3 로 로깅 시스템을 구축할수 있었다.<br>웹서버에서 로깅을 위해 logging filter 를 만들고 리팩토링하고 로깅 전략을 세우기도 했는데 많은 삽질을 하긴 했지만 재미있었다.<br>시행착오를 많이 겪었기 때문에 최소한의 최적화나 고생했던 부분등을 포스팅할 생각을 하고있다. </p><h3 id="이팩티브-자바-오브젝트"><a href="#이팩티브-자바-오브젝트" class="headerlink" title="이팩티브 자바, 오브젝트"></a>이팩티브 자바, 오브젝트</h3><p>이팩티브 자바를 2/3정도, 오브젝트를 반정도 읽었다.<br>오브젝트는 도메인 설계하는데에 아주 좋았다. 책임을 나누고 응집도 높고 유연한 아키텍쳐를 설계하는데에 도움이 됐다.<br>특히 객체를 의인화해서 본다는 부분에서 충격을 받았고, 객체와 행위의 주체를 생각하며 도메인을 설계할수 있었다.<br>웹 서비스 특성상 변경이나 기능 추가가 잦은데, 이렇게 책임과 역할을 나누면서 설계하니 도메인이 꽤 깔끔하고 유연해졌었다.</p><h3 id="더-자바-강의-완강"><a href="#더-자바-강의-완강" class="headerlink" title="더 자바 강의 완강"></a>더 자바 강의 완강</h3><p>백기선님의 [더 자바] 강의를 완강했다. 목차에 JVM 내용이 있어서 JVM 책 읽기 전에 수강했는데, JVM 동작원리와 함께 간단한 예제가 있어서 좋았다. </p><h3 id="엔젤핵-해커톤"><a href="#엔젤핵-해커톤" class="headerlink" title="엔젤핵 해커톤"></a>엔젤핵 해커톤</h3><p>작년에 이어 올해도 엔젤핵 해커톤을 나갔었다. <a href="https://sehajyang.github.io/2020/07/26/20200726-angelhack-2020-seoul-review/#more">[후기 글]</a></p><h3 id="JVM-성능튜닝-이야기"><a href="#JVM-성능튜닝-이야기" class="headerlink" title="JVM 성능튜닝 이야기"></a>JVM 성능튜닝 이야기</h3><p>올해 읽은 책중 가장 좋았다. 이 책은 올해의 책이다. </p><h3 id="토이프로젝트"><a href="#토이프로젝트" class="headerlink" title="토이프로젝트"></a>토이프로젝트</h3><p>지인들끼리 일반 유저에게 서비스 할 목적으로 만들고있다. 처음엔 MSA로 설계했는데 비용때문에 모노레포가 되어버렸다.<br>도메인 지식이 있는 상태에서 설계하니 확실히 과거에 하던 개인 프로젝트와는 다르다는 생각이 들었다.<br>나는 유저 및 인증쪽을 전부 담당했다. 인증전략을 직접 세우고 플로우를 짰다. 처음부터 설계하면서 구현하는데 요 일년간 꽤 배운게 많았었다는 생각이 들었다.<br>빨리 완성해서 서비스해보고싶다.</p><h3 id="다음달에-할-학습"><a href="#다음달에-할-학습" class="headerlink" title="다음달에 할 학습"></a>다음달에 할 학습</h3><ul><li>알고리즘</li><li>토이프로젝트</li><li>웹서버 로깅 포스팅</li></ul><h3 id="총평"><a href="#총평" class="headerlink" title="총평"></a>총평</h3><p>올해가 2개월밖에 남지 않았다. 신입땐 난 이런것도 할수있어요 였다면 지금은 당연하고 능숙하게 해야한다는 느낌이다.<br>그래서 요즘 내가 너무 서툴고 모르는게 많은것 같다는 생각도 들었다.<br>과거엔 그래도 다 할수있다는 근거없는 자신감이 있었는데 요즘 없어진걸 보면 더닝크루거 곡선의 우매함 꼭대기에 있다가 뚝 떨어진게 아닐까 싶기도하다.<br>그래도 막상 토이프로젝트를 밑바닥부터 만들어보니 요 일년간 배운게 꽤 많았었다는 생각이 들었다.<br>아무튼, 남은 2개월은 밀린 기술 포스팅도 하고 알고리즘하고 토이프로젝트도 하면서 보낼 예정이다. </p>]]></content:encoded>
<comments>https://sehajyang.github.io/2020/10/25/20200801-20201025/#disqus_thread</comments>
</item>
<item>
<title>AngelHack 2020 서울 우승 후기</title>
<link>https://sehajyang.github.io/2020/07/26/20200726-angelhack-2020-seoul-review/</link>
<guid>https://sehajyang.github.io/2020/07/26/20200726-angelhack-2020-seoul-review/</guid>
<pubDate>Sun, 26 Jul 2020 08:24:48 GMT</pubDate>
<description>
<p><img src="https://i.imgur.com/UGp5aOA.png" alt="angelhack-2020-main"></p>
<p>작년에 나갔었던 <a href="angelhackseoul.kr/">엔젤핵 해커톤</a>을 올해도 한다는 소식을 듣고 지인들과 함께 지원했다.</p>
<blockquote>
<p>다시보면 부끄럽지만, 당시에 작성했던 후기는 이렇다.<br><a href="https://sehajyang.github.io/2019/06/13/2019-06-13-angelhack-2019-seoul-win-review/">AngelHack 2019 서울 참석 및 우승
</description>
<content:encoded><![CDATA[<p><img src="https://i.imgur.com/UGp5aOA.png" alt="angelhack-2020-main"></p><p>작년에 나갔었던 <a href="angelhackseoul.kr/">엔젤핵 해커톤</a>을 올해도 한다는 소식을 듣고 지인들과 함께 지원했다.</p><blockquote><p>다시보면 부끄럽지만, 당시에 작성했던 후기는 이렇다.<br><a href="https://sehajyang.github.io/2019/06/13/2019-06-13-angelhack-2019-seoul-win-review/">AngelHack 2019 서울 참석 및 우승 후기</a></p></blockquote><p>작년엔 직접 현장에 도착해서 팀을 구했는데, 올해는 지인분들과 함께 팀을 구성하게 되었고 어쩌다 보니 우리 팀은 개발자 5명인 팀이었다.<br>코로나로 인해 모든 진행은 슬랙을 이용한 온라인으로 이루어졌다.<br>온라인인 만큼 기간은 일주일이었으며, 올해 주제는 코로나였다. 작년과는 달리 이번엔 기업에서 주제를 정해주고 원하는 주제에 지원하는 방식이었다.</p><p><img src="https://i.imgur.com/YVH1wnf.png" alt="angelhack-2020-subject"><br><em>주제는 UN이 제안하는 17가지의 지속 가능한 개발 목표(UN-SDGs)을 바탕으로 선정되었으며 최소 1개, 최대 2개이하로 주제를 선택할 수 있다.</em></p><p>우리 팀은 처음엔 커먼컴퓨터, 우아한형제들 주제에 지원했었다.<br>당시 아이디어는 코로나로 인해 기업에서 수급받아야 할 자원을 수급받지 못해 생기는 문제가 많으니 <strong>국제 자원 중개 서비스</strong>를 해서 그런 부분을 해결 해보자는 것이었지만, 국가 간의 규제가 천차만별이었으므로 문제가 많았다. 그렇게 아이디어 고민만 금요일 저녁까지 했다.<br>금요일 저녁까지 고민한 끝에 우리는 기존의 국제 자원 중개 서비스를 버리고 <strong>지역 기반 소상공인 공동구매 서비스</strong>를 하기로했다. </p><pre><code>우리 서비스는 코로나 때문에 어려움을 겪고 있는 많은 소상공인이 젓가락, 봉투 등의 부자재 혹은 재료 등을 공동구매 하거나 사용하지 않는 물건을 자유롭게 사고팔 수 있는 지역 기반 서비스이다.</code></pre><p>아이디어가 바뀜에 따라 지원하는 주제도 커먼컴퓨터와 테이블매니저 과제로 변경했다.<br>엔젤핵은 다른 해커톤과는 다르게 평가 기준에 BM이 있다.<br>그래서 우린 기존의 성공한 서비스들을 벤치마킹해 수익은 지역광고와 공동구매 중간유통 수수료로 결정했다.</p><p>커먼컴퓨터 주제는 커먼컴퓨터의 <strong>Ainize</strong> 란 서비스를 사용해 배포하면 되는 것이었다.<br>Ainize는 깃허브에 올라와 있는 오픈소스 프로젝트를 무료로 쉽게 실행하고 배포할 수 있도록 도와주는 서비스이다.<br>우리 팀은 프론트 서버와 백엔드 서버 둘 다 Ainize 통해 배포하기로 했다.</p><p>월요일부터 일요일까지 하는 해커톤이지만 금요일 저녁에 아이디어가 나와서 개발할 시간이 적었다.<br>하지만 다행스럽게도(?) 개발자 5명인 팀이라 기능 완성을 못하는 것에 대한 걱정은 없어 다행이었다.<br>그렇지만 늦게 시작한 만큼 포기할 수밖에 없는 기능도 있어서 조금 아쉬웠다.<br>사실 채팅을 넣고 싶었다. 하지만 시간상으로 힘들 것 같아 포기했다. </p><p>주제가 명확해졌으니 다 같이 모여서 금요일 밤~ 일요일 제출 전까지 달렸다.<br>웹 프레임워크는 장고가 선택되었는데, 장고로 개발하면 사용자 인증 및 CRUD를 빠르게 개발할 수 있어 해커톤에 적합했으며, 우리가 만들어야 할 서비스는 정확히 사용자 인증 및 CRUD API만 구현하면 되기 때문이었다. 그리고 날 제외한 백엔드 개발자는 장고에 익숙했다.<br>나는 스프링부트를 주로 사용하긴 하지만 플라스크로도 개발한 경험이 있었으므로 이 김에 장고를 써보자는 생각으로 장고 선택에 찬성했는데, 장고를 하루 만에 배워서 API 만들기는 생각보다 어려웠다.<br>우선 스프링과 장고는 많은 차이점이 있었는데, 스프링과 달리 장고는 기본적으로 여러 가지 기능을 자동으로 만들어주는 많은 클래스와 함수 등이 있었고 이걸 기존에 알고 있어야 쓸 수 있었다.<br>반면 스프링은 대체로 직접 구현해서 개발한다. 그런 나에게 있어 장고는 매직박스 같았다.<br>게다가 장고로 개발을 하더라도 사람마다 구현하는 방법은 천차만별이었다. 백엔드 팀원끼리도 방식이 완전히 달랐으며 서치해서 나오는 방식도 다 달랐다.<br>중간에 난 차라리 SpringBoot + RPC 로 개발하겠다 했지만 기각됐다.<br>그렇게 혼란 속에서 나는 두 파이썬 개발자의 속성 장고 강의를 받으며 API 몇 개와 DB 모델링을 했다.<br>장고는 모든 개발자가 다 할 줄 알아야 선택할 수 있을 것 같다. 그래도 이번 기회에 장고를 해볼 수 있어서 좋았다.</p><p>일요일 오전부터 크리티컬한 CORS 문제가 터졌다.<br>설정도 다시 해보고 장고 CORS 라이브러리 문제인 줄 알고 찾아보기도 하는 등 많은 시도를 해봤지만, 원인은 의외로 Ainize의 istio 설정문제였다.<br>정확히는 Ainize 측에서 CORS 헤더를 열어줘야하는데 몇 가지 헤더가 누락되어있어 발생 한 문제였다.<br>커먼 컴퓨터측에 문의 하니 신속하게 대처해주셔서 성공적으로 배포할 수 있었으며 이 이슈는 이번 해커톤 이후에 핫픽스 할 예정이라 하셨다.</p><p>마감은 23시 59분이었고 우리 팀은 시간 부족으로 인해 시연 영상을 일부 올리지 못해 아쉬웠으나 23시 56분에 아슬아슬하게 제출했다. </p><p>그리고 대망의 22일 수요일에 수상자가 발표되었다.</p><p><img src="https://i.imgur.com/eaIWNyC.png" alt="angelhack-libi-win"></p><p><strong>우리 팀은 커먼컴퓨터 부문에 수상하게 되었다!</strong><br>사실 우리 팀은 딱히 수상 기대를 하지 않고 있었다. 그도 그럴 게 굉장한 팀들이 많았기 때문이다.<br>심지어 화상 채팅을 구현한 엄청난 팀도 있었다(그 팀은 코드스테이츠 부문을 수상하셨다)<br>우리 팀이 기술적으로 엄청난 건 없지만 아마 준수한 코드 퀄리티와 BM 덕에 수상할 수 있지 않았을까 라고 생각한다.</p><p>다들 잠도 못 자고 고생을 많이 했지만, 우리 팀은 프론트(풀스택) 1, 백엔드 3, 앱 1로 구성된 팀이라 특히 프론트엔드 개발자분과 기획, 디자인, PPT, 영상까지 하신 앱 개발자분이 고생을 많이 하셨다.<br>특성상 프론트엔드 이슈가 많을 수밖에 없는데 프론트엔드 개발자 팀원님이 혼자 프론트 이슈를 다 처리하셨으며, 앱개발자님은 본인의 전문 분야가 아님에도 불구하고 좋은 디자인과 엄청난 발표자료 및 영상을 만들어주셨다. </p><p><img src="https://i.imgur.com/gdL9ese.png" alt="angelhack-report"></p><p>그렇게 7월 13일(월) ~ 7월 22일(수)까지 진행된 2020 엔젤핵은 막을 내렸다.</p><p>원활한 운영에 힘써주신 운영진분들, 멘토분들, Ainize분들, 팀원분들 모두 감사합니다 🙇🏼♂️</p><hr><p>소스는 GitHub에 공개되어 있습니다 => <a href="https://github.com/Angelhack-LIBI" target="_blank" rel="noopener">[AngelHack LiBi Repository]</a><br>피칭영상 => <a href="https://www.youtube.com/watch?v=V6T9jYD6u5Y&feature=youtu.be" target="_blank" rel="noopener">AngelhackSeoul 2020 - Team LiBi, ‘사이’ Pitching</a><br>읽어주셔서 감사합니다.</p><p>#엔젤핵서울 #AngelhackSeoul2020Online #해커톤 #hackathon #개발자 #기획자 #디자이너 #코로나19 #함께이겨내요</p>]]></content:encoded>
<comments>https://sehajyang.github.io/2020/07/26/20200726-angelhack-2020-seoul-review/#disqus_thread</comments>
</item>
<item>
<title>2020년 4월~5월 회고</title>
<link>https://sehajyang.github.io/2020/05/30/202004-202005/</link>
<guid>https://sehajyang.github.io/2020/05/30/202004-202005/</guid>
<pubDate>Sat, 30 May 2020 14:50:00 GMT</pubDate>
<description>
<p>입사한 뒤 오픈 준비하느라 3달간 바빠서 스터디도 주간회고도 못썼다.<br>길었던 3개월이 끝나고 이제 오픈했으니 다시 회고를 적어본다!<br>두달만에 회고를 적는만큼 두달간 한 학습 및 개발이 꽤 다양하다.</p>
<h2 id="두달간-한-학습-및-개발"><a href="#두달간-한-학습-및-개발" class="headerlink" title="두달간 한 학습 및 개발"></a>두달간 한 학습 및 개발</h2><ul>
<li>Neflix OSS</li>
<li>Spring Cloud Config</li>
<li>Spring Data Envers</li>
<li>AWS
</description>
<content:encoded><![CDATA[<p>입사한 뒤 오픈 준비하느라 3달간 바빠서 스터디도 주간회고도 못썼다.<br>길었던 3개월이 끝나고 이제 오픈했으니 다시 회고를 적어본다!<br>두달만에 회고를 적는만큼 두달간 한 학습 및 개발이 꽤 다양하다.</p><h2 id="두달간-한-학습-및-개발"><a href="#두달간-한-학습-및-개발" class="headerlink" title="두달간 한 학습 및 개발"></a>두달간 한 학습 및 개발</h2><ul><li>Neflix OSS</li><li>Spring Cloud Config</li><li>Spring Data Envers</li><li>AWS ECS</li><li>QueryDSL</li></ul><h3 id="Neflix-OSS"><a href="#Neflix-OSS" class="headerlink" title="Neflix OSS"></a>Neflix OSS</h3><p>MSA에 대해 막연하게 알기만 하고 해본적은 없었는데, 아키텍쳐가 MSA로 되어있어 우선 MSA에 대해 공부를 했었다.<br>서비스는 Neflix OSS 중 Eureka, Zuul, Ribbon, Feign, Hystrics 등을 쓰고 있었는데 다음과 같은 역할을 하는 넷플릭스의 오픈소스이다.<br>간단하게 정리하자면 다음과 같다.</p><blockquote><p>Eureka: 서비스 디스커버리<br>Zuul: jvm 기반의 라우터, 쉽게말해 api gateway, 서버측 부하 분산이나 일부 필터링을 수행<br>Ribbon: 부하 분산 및 서비스 디스커버리, 캐싱, 일괄처리, 장애내성과 통합가능<br>Feign : 선언적인 REST Client<br>Hystrics : circuit breaker</p></blockquote><p>예전엔 Elastic Beanstalk이 로드 밸런싱이나 Auto Scaling을 알아서 해줬지만, Netflix OSS를 쓰니 하나하나 설정해줘야 해서 이해하는 것 부터가 어려웠다.<br>무엇보다 내가 지금 Netflix OSS에 대한 이해도가 높지 않다.. 관련된 포스팅을 하며 공부를 해볼까 했는데 이래저래 바쁘다보니 미뤄졌다.<br>Netflix OSS에 관련된 자료도 적고, 사례도 많이 적었다. 관련된 세미나나 자료가 좀 더 늘었음 좋겠다.</p><h3 id="Spring-Cloud-Config"><a href="#Spring-Cloud-Config" class="headerlink" title="Spring Cloud Config"></a>Spring Cloud Config</h3><p>MSA에선 모든 서비스의 설정을 관리하는 환경 설정 중앙 관리 서버가 필요하다.<br>Spring Cloud Config는 서비스의 모든 환경설정 속성 정보를 저장하고, 조회하고 관리할 수 있게 해주는 <a href="https://coding-start.tistory.com/120" target="_blank" rel="noopener">외부화된 환경설정 서버다.</a><br>이 cloud config 서버를 만들었는데, 구현자체는 어렵지 않았지만 자료가 정말 적어 커스텀하게 만드는게 정말 굉장히 어려웠었다.<br>특히 서비스 디스커버리에 대해 의존성이 생길것이냐, 서비스 디스커버리가 config 서버에 의존성이 생기게 할 것이냐는 문제가 있었는데, 처음엔 이해를 못해서 데드락 같은 상황이 벌어지기도 했다.<br>cloud config 에 관련된 포스팅은 조만간 작성할 예정이다.</p><h3 id="Spring-Data-Envers"><a href="#Spring-Data-Envers" class="headerlink" title="Spring Data Envers"></a>Spring Data Envers</h3><p>사내 서비스들에 적용하기 위해 공부했었다.<br><a href="https://sehajyang.github.io/2020/04/15/springboot-envers-logging-for-revision/#more">spring data envers 로 데이터 변경 로깅하기</a> 라는 포스팅을 작성했다.<br>data envers는 여러 장단점이 있지만, 개발자가 백업 테이블을 만드는 노가다를 하지 않아도 된다는 강력한 장점이 있으므로 굉장히 추천하고싶다.</p><h3 id="AWS-ECS"><a href="#AWS-ECS" class="headerlink" title="AWS ECS"></a>AWS ECS</h3><p>AWS ECS를 처음 써봤다. 정확힌 회사 서비스가 ECS로 배포되고, 관리되고 있다. 코로나가 아니었다면 컨테이너 소모임에 갔을텐데 아쉽다.</p><h3 id="QueryDSL"><a href="#QueryDSL" class="headerlink" title="QueryDSL"></a>QueryDSL</h3><p>프로젝트가 QueryDSL을 사용하고 있었기 때문에 입사 초기에 공부했었다.<br>그때 김영한님의 <a href="https://www.inflearn.com/course/Querydsl-%EC%8B%A4%EC%A0%84" target="_blank" rel="noopener">실전 Querydsl</a> 강의를 다 봤다.<br>생각보다 어렵지 않았고 별 거 없었다. 쿼리 최적화 부분이 인상깊었다.<br>JPA + QueryDSL은 정말 최고다. 가끔 좀 답답할 때가 있지만 MyBatis 보단 훨씬 좋다.<br>xml을 쓰지 않아도 되고, 쿼리를 하나하나 작성하며 관리해야하지 않아도 된다는게 정말 좋다.<br>테이블간의 관계에 집중하고 객체로 보는점도 자바의 컨셉과 딱 맞는다. 더 이상 MyBatis를 쓸 이유가 없다!<br>JPA 공부도 같이 했다. <a href="https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1" target="_blank" rel="noopener">JPA 강의</a> <a href="https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-API%EA%B0%9C%EB%B0%9C-%EC%84%B1%EB%8A%A5%EC%B5%9C%EC%A0%81%ED%99%94" target="_blank" rel="noopener">두개를 봤고</a> 책은 <a href="http://acornpub.co.kr/book/jpa-programmig" target="_blank" rel="noopener">자바 ORM 표준 JPA 프로그래밍</a> 과 회사 코드를 보며 학습했다.</p><h3 id="다음달에-할-학습"><a href="#다음달에-할-학습" class="headerlink" title="다음달에 할 학습"></a>다음달에 할 학습</h3><ul><li>spring security 강의 수강</li><li>이펙티브 자바</li><li><a href="http://www.yes24.com/Product/Goods/74219491" target="_blank" rel="noopener">오브젝트</a> 스터디</li></ul><h3 id="총평"><a href="#총평" class="headerlink" title="총평"></a>총평</h3><p>오픈을 앞두고 급하게 많은 기술을 빨리 배워 빨리 적용해야했는데, 당시엔 힘들었지만 돌이켜보니 짧은시간에 배우고 적용한게 많았다.<br>아직 해야할 건 많다. 당장 spring security 도 공부해야하고 얕게 공부한 것들을 좀 더 심도있게 공부해야하지만, 꾸준히 공부한다면 내년즈음엔 나름대로 잘하고 있지 않을까 싶다.</p>]]></content:encoded>
<comments>https://sehajyang.github.io/2020/05/30/202004-202005/#disqus_thread</comments>
</item>
<item>
<title>spring data envers 로 데이터 변경 로깅하기</title>
<link>https://sehajyang.github.io/2020/04/15/springboot-envers-logging-for-revision/</link>
<guid>https://sehajyang.github.io/2020/04/15/springboot-envers-logging-for-revision/</guid>
<pubDate>Wed, 15 Apr 2020 08:57:00 GMT</pubDate>
<description>
<p>이 글은 이력 생성까지 다루고 있으며 이력 조회까지 다루고 있지 않습니다.</p>
<h2 id="envers-란"><a href="#envers-란" class="headerlink" title="envers 란"></a>envers 란</h2><p>envers는 hibernate 에서 만든 데이터 변경 이력을 로깅하기 위한 라이브러리입니다.<br>과거엔 로깅을 위해 customer_hist 와 같은 엔티티를 정의하고 customer 에 insert, update, delete 등의 작업이 발생하면,<br>history 테이블에도 같은 작업을 해줘야 했으며, 이력을 쌓아야 하는 테이블이 늘어날 수록 이러한
</description>
<content:encoded><![CDATA[<p>이 글은 이력 생성까지 다루고 있으며 이력 조회까지 다루고 있지 않습니다.</p><h2 id="envers-란"><a href="#envers-란" class="headerlink" title="envers 란"></a>envers 란</h2><p>envers는 hibernate 에서 만든 데이터 변경 이력을 로깅하기 위한 라이브러리입니다.<br>과거엔 로깅을 위해 customer_hist 와 같은 엔티티를 정의하고 customer 에 insert, update, delete 등의 작업이 발생하면,<br>history 테이블에도 같은 작업을 해줘야 했으며, 이력을 쌓아야 하는 테이블이 늘어날 수록 이러한 번거로운 반복작업을 계속해야했습니다.<br>그러나 envers를 사용하면 이러한 번거로운 작업을 대폭 줄일 수 있습니다.<br>기본적으로 jpa로 구현되어있으며 후에 spring에도 spring data envers 프로젝트로 추가되었습니다.<br>spring data envers 역시 hibernate에서 관리하기 때문에 큰 차이는 없습니다.</p><h3 id="의존성-추가"><a href="#의존성-추가" class="headerlink" title="의존성 추가"></a>의존성 추가</h3><p>2020.4월 기준 recent stable version인 hibernate-envers 라이브러리를 build.gradle에 추가해줍니다. </p><figure class="highlight gradle"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">compile</span> <span class="keyword">group</span>: <span class="string">'org.hibernate'</span>, name: <span class="string">'hibernate-envers'</span>, version: <span class="string">'5.4.14.Final'</span></span><br></pre></td></tr></table></figure><h3 id="Audited로-변경이력-저장할-테이블-생성"><a href="#Audited로-변경이력-저장할-테이블-생성" class="headerlink" title="@Audited로 변경이력 저장할 테이블 생성"></a>@Audited로 변경이력 저장할 테이블 생성</h3><p>변경이력을 추적할 엔티티에 @Audited 어노테이션을 추가해줍니다.<br>만약 extends 한 엔티티의 이력도 추가되길 원한다면 <code>@AuditOverride(forClass=BaseEntity.class)</code> 도 추가합니다.<br>그러면 기본적으로 총 두개의 테이블이 생성되게 됩니다.<br>예를들어 customer 엔티티의 상단에 @Audited를 추가하면 다음과 같은 customer_aud, revinfo 테이블이 생성됩니다.</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Entity</span></span><br><span class="line"><span class="meta">@Audited</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Customer</span> </span>{... }</span><br></pre></td></tr></table></figure><p><img src="https://lh5.googleusercontent.com/naDZUyu6a9Q3N8WSaGFbjDDQ-nZMLcCgnlOfQyufKbJhbmiH0LUqYoUmTY5NTs9uqShhV78OcMo03cUT8AJxrg1xI-BxLymmvp1cIkv2QveD8dlpbj8sllEdALzSNfM_moi9EnHj" alt><br><font color="grey" size="2px">이미지출처 : <a href="https://www.geeklearners.com/2019/03/hibernate-envers-history-data-and.html" target="_blank" rel="noopener">Hibernate Envers - History Data and Versioning</a></font></p><p>이 revinfo는 central revision table 로, 최초 1회만 생성되며, 이 <strong>revinfo 테이블을 삭제하거나 disable 할 순 없습니다</strong>.<br>네이밍 및 필드 변경은 가능합니다.<br>또한 rev 필드의 네이밍 변경을 각 테이블마다 다르게 줄 수 없습니다.<br>customer_aud 테이블의 <strong>rev_type</strong> 은 int타입으로 생성, 수정, 삭제를 구분하는 컬럼입니다.<br>값은 다음과 같습니다:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">0 : insert</span><br><span class="line">1 : update</span><br><span class="line">2 : delete</span><br></pre></td></tr></table></figure><p>아쉽게도 타입, 필드명, 값을 변경할 순 없습니다.</p><p>테이블 변경이력 로깅에 대한 몇가지 디자인이 있지만, 이렇게 중앙에서 관리하는 테이블이 있는 방식은 createAt, createUser 등을 각 테이블마다 생성하지 않고 중앙 테이블에서 한번만 생성하면 된다는 장점이 있습니다.<br>이렇게 revision 관리를 하는 테이블이 왜 필요한지에 대한 stackoverflow 글이 몇개 있으니 궁금하신 분은 읽어보시는걸 추천드립니다</p><ul><li><a href="https://stackoverflow.com/questions/2015232/database-design-for-audit-logging" target="_blank" rel="noopener">database-design-for-audit-logging</a></li><li><a href="https://stackoverflow.com/questions/39281/database-design-for-revisions" target="_blank" rel="noopener">database-design-for-revisions</a></li><li><a href="https://stackoverflow.com/questions/9852703/store-all-data-changes-with-every-details-like-stackoverflow" target="_blank" rel="noopener">store-all-data-changes-with-every-details</a></li></ul><h3 id="property-config-설정"><a href="#property-config-설정" class="headerlink" title="property config 설정"></a>property config 설정</h3><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">spring:</span></span><br><span class="line"><span class="attr"> jpa:</span></span><br><span class="line"><span class="attr"> org:</span></span><br><span class="line"><span class="attr"> hibernate:</span></span><br><span class="line"><span class="attr"> envers:</span></span><br><span class="line"><span class="attr"> audit_table_suffix:</span> <span class="string">_history</span></span><br><span class="line"><span class="attr"> revision_field_name:</span> <span class="string">rev_id</span></span><br><span class="line"><span class="attr"> store_data_at_delete:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><p><code>audit_table_suffix</code>, <code>audit_table_suffix</code> 등으로 auditing table의 prefix, suffix를 수정할 수 있습니다.<br>또한 <code>revision_field_name</code> 로 revision fk 로 쓰는 테이블들의 revid 바꾸고 싶은 경우 설정할 수 있지만 테이블마다 각각 rev_id를 따로 설정하는 것은 불가능합니다. (order_rev_id, product_rev_id 이렇게 개별로 설정 불가능)<br>delete 시 aud 테이블에서 타겟 테이블의 pk 만 쌓을뿐 다른 필드의 값은 기본적으로 null 입니다.<br>null이 아니라 delete 직전의 모든 필드의 값을 쌓고 싶다면 <code>store_data_at_delete: true</code> 를 설정합니다.<br>더 많은 property config는 <a href="https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#envers-configuration" target="_blank" rel="noopener">Envers Configuration Properties</a>에서 확인해주세요.</p><h3 id="필수-설정"><a href="#필수-설정" class="headerlink" title="필수 설정"></a>필수 설정</h3><p>central revision table인 revinfo의 pk인 rev 컬럼의 타입은 기본적으로 int 로 되어있습니다. 데이터가 20억개 이상 넘어가면 오류가 발생하므로, 권남님 포스팅의 <a href="https://kwonnam.pe.kr/wiki/java/hibernate/envers" target="_blank" rel="noopener">[REV 를 long 으로 변경해야한다]</a>처럼 int 타입을 long 타입으로 변경해줘야 합니다. </p><h3 id="그-외"><a href="#그-외" class="headerlink" title="그 외"></a>그 외</h3><h4 id="테이블이-서로-연관관계인-경우"><a href="#테이블이-서로-연관관계인-경우" class="headerlink" title="테이블이 서로 연관관계인 경우"></a>테이블이 서로 연관관계인 경우</h4><h5 id="추적-테이블을-만들지-않을-경우"><a href="#추적-테이블을-만들지-않을-경우" class="headerlink" title="추적 테이블을 만들지 않을 경우"></a>추적 테이블을 만들지 않을 경우</h5><p>연관관계 추적 테이블 생성은 되지만 추적하진 않을거라면 엔티티 내 필드에 다음과 같이 어노테이션을 추가합니다.</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Entity</span></span><br><span class="line"><span class="meta">@Audited</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Customer</span> </span>{</span><br><span class="line"> ... </span><br><span class="line"> <span class="meta">@OneToOne</span></span><br><span class="line"> <span class="meta">@Audited</span>(targetAuditMode = NOT_AUDITED)</span><br><span class="line"> <span class="keyword">private</span> CustomerDetail customerDetail;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>연관관계 테이블 생성도 하지 않고 추적하지도 않을거라면 엔티티 필드에 다음과 같은 어노테이션을 추가합니다</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Entity</span></span><br><span class="line"><span class="meta">@Audited</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Customer</span> </span>{</span><br><span class="line"> ...</span><br><span class="line"> <span class="meta">@NotAudited</span></span><br><span class="line"> <span class="meta">@OneToOne</span></span><br><span class="line"> <span class="keyword">private</span> CustomerDetail customerDetail;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>양방향관계에선 AuditMappedBy로 관계 명시를 해줘야 합니다.</p><ul><li>@AuditMappedBy(mappedBy = “name”)</li><li>@OneToMany + @JoinCoulmn 인 경우 @AuditJoinTable</li></ul><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Entity</span></span><br><span class="line"><span class="meta">@Audited</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Customer</span> </span>{</span><br><span class="line"> ...</span><br><span class="line"> <span class="meta">@OneToMany</span></span><br><span class="line"> <span class="meta">@JoinColumn</span>(name=<span class="string">"customer_id"</span>)</span><br><span class="line"> <span class="meta">@AuditJoinTable</span></span><br><span class="line"> <span class="keyword">private</span> Set<CustomerDetail> customerDetail = <span class="keyword">new</span> LinkedHashSet<>();</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>참고 : <a href="https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#_code_onetomany_code_with_code_joincolumn_code" target="_blank" rel="noopener">onetomany_code_with_code_joincolumn_code</a></p><h4 id="상속관계에-있는-테이블도-audit-하고싶은-경우"><a href="#상속관계에-있는-테이블도-audit-하고싶은-경우" class="headerlink" title="상속관계에 있는 테이블도 audit 하고싶은 경우"></a>상속관계에 있는 테이블도 audit 하고싶은 경우</h4><p>클래스 상단에 <code>@AuditOverride(forClass=BaseEntity.class)</code> 추가합니다.<br>BaseEntity에 굳이 @Audited 추가해주지 않아도 됩니다.</p><h2 id="그-외의-문제"><a href="#그-외의-문제" class="headerlink" title="그 외의 문제"></a>그 외의 문제</h2><p>queryDSL과 함께 쓰면 조회시 호환이 되지 않는 문제가 발생합니다 <a href="https://github.com/spring-projects/spring-data-envers/issues/30" target="_blank" rel="noopener">[해당 이슈]</a><br>다음과 같이 <code>EnversQueryDslRepositoryImpl.java</code>를 수정하여 해결할 수 있습니다.<br><a href="https://gist.github.com/tanapoln/af4b4a40e5472f0c8e9625d31f7d2153" target="_blank" rel="noopener">[EnversQueryDslRepositoryImpl.java gist]</a></p><p>혹 글의 내용이 잘못되었거나, 추가하실 부분 또한 궁금한 부분이 있다면 편하게 코멘트 남겨주세요.<br>읽어주셔서 감사합니다.</p><p>참고</p><ul><li><a href="https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#envers-conditional-auditing" target="_blank" rel="noopener">Hibernate ORM 5.4.14.Final User Guide</a></li><li><a href="https://docs.jboss.org/envers/docs/" target="_blank" rel="noopener">Hibernate Envers - Easy Entity Auditing</a></li><li><a href="https://kwonnam.pe.kr/wiki/java/hibernate/envers" target="_blank" rel="noopener">권남-Hibernate Envers</a></li><li><a href="https://haviyj.tistory.com/40" target="_blank" rel="noopener">Spring Boot + Envers로 엔티티 이력관리하기</a></li><li><a href="https://hychul.github.io/development/2019/05/24/applying-audit-to-jpa/" target="_blank" rel="noopener">JPA에 audit 적용하기</a></li><li><a href="https://www.youtube.com/watch?v=fGPaj-rlN5w" target="_blank" rel="noopener">스프링캠프 2017 [Day2 A5] : 엔티티 히스토리를 편리하게 관리해주는 스프링 데이터 Envers(영상)</a></li></ul>]]></content:encoded>
<comments>https://sehajyang.github.io/2020/04/15/springboot-envers-logging-for-revision/#disqus_thread</comments>
</item>
<item>
<title>2020년 3월 중간 회고</title>
<link>https://sehajyang.github.io/2020/03/15/200217-200313/</link>
<guid>https://sehajyang.github.io/2020/03/15/200217-200313/</guid>
<pubDate>Sun, 15 Mar 2020 14:36:00 GMT</pubDate>
<description>
<p>3월 중순이 됐고 이번 월간회고는 패스하려다 그냥 작성하기로 했다.<br>작성하지 않으려 했던 이유는 여러가지인데 코로나로 인한 세미나취소, 체력문제로 인해 한달동안 한게 별로 없었기 때문이다.<br>이직으로 출퇴근 거리가 길어져 퇴근하면 지쳐서 아무것도 할 수 없었으며 그렇게 한달간 쉬었다.<br>회고 작성을 본래 꾸준하게 해보자 라는 취지로 시작했었기 때문에 이번 회고를 작성하게 되었다. </p>
<p>나는 세미나를 꽤 자주 참석한다. 많게는 한달에 두번이상 참가하며 월 1회는 꼭 참가하는 편이다.<br>세션을 보고 재밌겠다 내지는 괜찮을 거 같다 싶으면 가는데, 그 밖에도 열정이 좀 빠졌을때 참가하려는
</description>
<content:encoded><![CDATA[<p>3월 중순이 됐고 이번 월간회고는 패스하려다 그냥 작성하기로 했다.<br>작성하지 않으려 했던 이유는 여러가지인데 코로나로 인한 세미나취소, 체력문제로 인해 한달동안 한게 별로 없었기 때문이다.<br>이직으로 출퇴근 거리가 길어져 퇴근하면 지쳐서 아무것도 할 수 없었으며 그렇게 한달간 쉬었다.<br>회고 작성을 본래 꾸준하게 해보자 라는 취지로 시작했었기 때문에 이번 회고를 작성하게 되었다. </p><p>나는 세미나를 꽤 자주 참석한다. 많게는 한달에 두번이상 참가하며 월 1회는 꼭 참가하는 편이다.<br>세션을 보고 재밌겠다 내지는 괜찮을 거 같다 싶으면 가는데, 그 밖에도 열정이 좀 빠졌을때 참가하려는 경향이 있다.<br>가서 이것저것 흥미로운 걸 보고 오면 열정도 채워지고 의욕도 생겼다.<br>하지만 이번 코로나로 기대했던 aws summit, kcd2020, awskrug 소모임등이 취소되었다.</p><p>애널리틱스를 봤는데 많은 분들이 sqs lambda 글을 보는 것 같았다. 최근들어 주위에서 sqs에 대한 얘기가 들려온다.<br>sqs 자료는 진짜 적기 때문에 이번달 안에는 반드시 2부를 써야겠다.</p><h2 id="한달간-한-학습-및-개발"><a href="#한달간-한-학습-및-개발" class="headerlink" title="한달간 한 학습 및 개발"></a>한달간 한 학습 및 개발</h2><ul><li>비동기 프로젝트 </li><li><a href="http://www.hanbit.co.kr/store/books/look.php?p_code=E9050803868" target="_blank" rel="noopener">Fluent Python</a> 읽기</li><li>알고리즘 스터디 1부 종료</li></ul><h3 id="비동기-프로젝트"><a href="#비동기-프로젝트" class="headerlink" title="비동기 프로젝트"></a>비동기 프로젝트</h3><p>입사 후 처음 받은 일을 파이썬 비동기로 만들었다.<br>짧은 시간내에 많은 작업(특히 네트워크 IO 작업)을 처리해야 했으므로 비동기로 만들었다.<br>cpu bound 하지만 시간이 꽤 오래 걸리는 문자열 연산등의 작업은 run_in_executor 함수로 따로 쓰레드풀에서 돌게 하는둥 최대한 병목을 줄이고 blocking 함수를 루프안에 넣지 않기 위한 노력을 했다.<br>클린하고 readablity 높게 만들고 싶은 욕심이 많았기 때문에 전체 구조를 뒤엎는 리팩토링만 수십번은 했다.<br>하지만 그 덕분에 나중에 유지보수하기가 너무나 편했다.<br>취소 및 재시도 처리 때문에 고생을 많이 했다. 비동기가 아니면 쉽게 에러처리를 할텐데 비동기라서 쉬운것도 어려워지는 부분이 많았다.<br>비동기로 짜는 동안 정말 정말 힘들었는데 작업이 마무리되니 힘든건 다 까먹었다.<br>결과적으로 기존엔 12800sec 걸리던 작업을 400sec 로 단축시켰다.<br>빠르게 잘 돌아가는 프로젝트를 보니 뿌듯하고, 다음에도 이렇게 만들어야지 라는 생각이 들었다.<br>이것저것 찾아보며 느낀건데, 한글로 된 파이썬 비동기 자료가 굉장히 적어 이번에 비동기 포스팅을 해봐야겠다.<br><a href="http://acornpub.co.kr/book/concurrency-python" target="_blank" rel="noopener">파이썬 동시성 프로그래밍</a> 책도 샀다. 이 책을 선택한 이유는 단순한데, 번역된 파이썬 동시성 프로그래밍 책이 이 책 밖에 없었다. 다행히 내용은 탄탄하고 알차다!</p><h3 id="Fluent-Python"><a href="#Fluent-Python" class="headerlink" title="Fluent Python"></a>Fluent Python</h3><p>fluent python 책을 계속 보고있다. 사실 많이 보지는 못했다.<br>두고두고 보려고 오랜만에 til에 정리한걸 조금 올렸는데, 아직 한 챕터밖에 올리지 못했다. </p><h3 id="알고리즘-스터디"><a href="#알고리즘-스터디" class="headerlink" title="알고리즘 스터디"></a>알고리즘 스터디</h3><p>알고리즘 스터디 1부가 끝이 났다! 거의 마지막엔 난이도도 올라가고 시간도 없어 제대로 풀지 못했다.<br>2부는 아마 다음달중순 쯤에 시작할것으로 생각하고 있다. 도움이 많이 됐는데 마지막에 놔 버려서 슬프다..<br>멘탈 회복되면 마지막에 못 푼 문제들 좀 풀어봐야겠다.</p><h2 id="다음달-중순까지-할-학습-및-개발"><a href="#다음달-중순까지-할-학습-및-개발" class="headerlink" title="다음달 중순까지 할 학습 및 개발"></a>다음달 중순까지 할 학습 및 개발</h2><ul><li>JPA 강의 수강</li><li>Fluent Python 읽기</li><li><a href="http://acornpub.co.kr/book/concurrency-python" target="_blank" rel="noopener">파이썬 동시성 프로그래밍</a> 읽기</li></ul><h2 id="총평"><a href="#총평" class="headerlink" title="총평"></a>총평</h2><p>왜인지 모르겠지만 요즈음 의욕도 의지도 사라졌다.<br>몇가지 이유가 있겠지만 코로나로 인해 세미나가 취소된 것도 큰 것 같다.<br>어쨌든 의지도 없고 그래서 한달정도 놀았는데 딱히 할게 없어서 이제는 노는것도 스트레스가 됐다.<br>해야할 공부는 많은데.. 큰일이다. 우선 해야할 공부부터 조금씩 해야겠다. </p>]]></content:encoded>
<comments>https://sehajyang.github.io/2020/03/15/200217-200313/#disqus_thread</comments>
</item>
<item>
<title>2020년 2월 중간 회고</title>
<link>https://sehajyang.github.io/2020/02/16/200113-200216/</link>
<guid>https://sehajyang.github.io/2020/02/16/200113-200216/</guid>
<pubDate>Sun, 16 Feb 2020 07:56:00 GMT</pubDate>
<description>
<p>저번 회고를 1월 중순에 작성한 탓에 2월도 애매하게 2월 중간에 작성하게 되었다.<br>1월 중순과 2월 중순 사이에는 정들었던 첫 직장을 떠나 새로운 직장으로 옮기게 되었다.<br>나는 best practice를 배울 수 있으면 좋겠지만 만약 그러지 못해도 좀 더 나은 코드 퀄리티나 최적화를 함께 고민할 수 있는 조직에 들어가고 싶어 이직을 결심하게 되었다.<br>그렇게 한달정도 준비해 여러가지 배울수도 고민을 함께할 수도 있는 조직에 들어갈 수 있었다.<br>이직 준비를 했다는건 굉장히 애매한데, 나는 평소에 기술 혹은 이렇게 회고 포스팅을 작성하거나 토이프로젝트를 하거나 세미나를 다니거나
</description>
<content:encoded><![CDATA[<p>저번 회고를 1월 중순에 작성한 탓에 2월도 애매하게 2월 중간에 작성하게 되었다.<br>1월 중순과 2월 중순 사이에는 정들었던 첫 직장을 떠나 새로운 직장으로 옮기게 되었다.<br>나는 best practice를 배울 수 있으면 좋겠지만 만약 그러지 못해도 좀 더 나은 코드 퀄리티나 최적화를 함께 고민할 수 있는 조직에 들어가고 싶어 이직을 결심하게 되었다.<br>그렇게 한달정도 준비해 여러가지 배울수도 고민을 함께할 수도 있는 조직에 들어갈 수 있었다.<br>이직 준비를 했다는건 굉장히 애매한데, 나는 평소에 기술 혹은 이렇게 회고 포스팅을 작성하거나 토이프로젝트를 하거나 세미나를 다니거나 했다.<br>알고리즘 스터디도 하고 있었고.. 이러한 활동들은 이직할때 제출하는 자료들이 되었다.<br>딱히 이직을 목표로 준비했다기보단 꾸준히 로그를 남겨보자는 생각으로 이것저것 해왔는데, 뭔가 여러모로 도움이 되었다. </p><h2 id="한달간-한-학습-및-개발"><a href="#한달간-한-학습-및-개발" class="headerlink" title="한달간 한 학습 및 개발"></a>한달간 한 학습 및 개발</h2><ul><li>알고리즘 문제 풀이(알고리즘 스터디)</li><li>JPA 강의 수강</li><li>fluent python </li><li>이펙티브 자바</li></ul><h3 id="알고리즘-문제-풀이-알고리즘-스터디"><a href="#알고리즘-문제-풀이-알고리즘-스터디" class="headerlink" title="알고리즘 문제 풀이(알고리즘 스터디)"></a>알고리즘 문제 풀이(알고리즘 스터디)</h3><p>한달간 무엇을 했는지 딱히 기억이 나지 않아 커밋로그를 보니 우선 깃허브엔 알고리즘 문제 푼 커밋밖에 없었다.<br>알고리즘 스터디는 다행히 파토나지 않고 한달넘게 계속되고 있다.<br>일주일에 한번 모여 코드 리뷰를 하고 강의 듣고 문제 다섯개를 풀면 되는데, 이게 회사를 다니면서 하려니 정말 어려웠다.<br>특히 문제 다섯개 풀이는 처음엔 괜찮았으나 뒤로 갈수록 빡세지고있다.<br>그래도 혼자 했으면 금방 포기했을텐데 여럿이 해서 다른 사람 코드도 볼 수 있고 아직 즐겁게 하고있다.<br>알고리즘 풀다 운적도 있었다. 자괴감도 들고 분하기도 했다. 그렇지만 힘든만큼 얻는것도 많았다.<br>전보다 사고력이 좋아졌음을 느끼고있으며, 한걸음 더 나아가 생각할 수 있게 되었다. 복잡한 로직을 짤 때도 선택지가 늘었음을 느낀다.<br>결론적으로 알고리즘 스터디 정말 최고야!</p><h3 id="JPA-강의-수강"><a href="#JPA-강의-수강" class="headerlink" title="JPA 강의 수강"></a>JPA 강의 수강</h3><p>주변 지인의 추천을 받기도 했고 이직한 곳에서도 JPA를 사용하기 때문에 JPA강의를 보기 시작했다.<br>강의는 인프런의 김영한 님의 JPA강의를 듣고있으며 다 수강한 뒤엔 Query DSL을 수강할 예정이다.<br>JPA를 사용할 줄은 알지만 잘 하지는 못했기 때문에 아직 배울게 많다.<br>4월즈음에 스프링부트를 사용한 지인 두분과 Query DSL 스터디를 하기로 했다. </p><h3 id="fluent-python"><a href="#fluent-python" class="headerlink" title="fluent python"></a>fluent python</h3><p>드디어 fluent python을 보게 됐다. 한국에서는 <code>전문가를 위한 파이썬</code> 으로 알려져 있다.<br>대체로 프로그래밍 언어의 문법을 익히긴 쉽지만, 그 언어의 특성에 맞게 잘 사용하긴 어렵다.<br>fluent python은 파이썬을 pythonic하게 잘 사용하기 위한 책이다.<br>이 책은 파이썬 초보에겐 적합하지 않다. 그래서 작년엔 보지 못했다.<br>여담으로 출퇴근길에 읽기 위해 예사에서 ebook으로 샀는데 그냥 종이책으로 살걸 절절히 후회하고있다.<br>앱은 더할나위없이 구리고 한번 다운받은터라 환불도 되지 않는다.<br>만약 사실분은 ebook 리더기나 태블릿이 없다면 종이책으로 사는걸 강력히 추천합니다. </p><h3 id="이펙티브-자바"><a href="#이펙티브-자바" class="headerlink" title="이펙티브 자바"></a>이펙티브 자바</h3><p>이직은 파이썬을 사용하는 곳으로 가려고 했으나 어쩌다보니 계속 자바를 하게 되었다.<br>그래서 이펙티브 자바를 구매했다. 목차부터 좋은 책이라는 느낌이 들었다.<br>아직 초장을 읽고 있다. 클린코드를 읽었을 때 처럼 많은걸 배우게 될 것 같다. </p><h2 id="다음달에-할-학습"><a href="#다음달에-할-학습" class="headerlink" title="다음달에 할 학습"></a>다음달에 할 학습</h2><ul><li>알고리즘 스터디 계속</li><li><a href="https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%8D%B0%EC%9D%B4%ED%84%B0-JPA-%EC%8B%A4%EC%A0%84/dashboard" target="_blank" rel="noopener">실전! 스프링 데이터 JPA</a></li><li>fluent python 읽기</li><li>이펙티브 자바 읽기</li></ul><h2 id="총평"><a href="#총평" class="headerlink" title="총평"></a>총평</h2><p>알고리즘을 꾸준히 해서 뿌듯했고, 과거에 개인적으로 공부했던 것 들을 뭔가 써먹을 수(?) 있었다.<br>새 조직에 적응하느라 정신이 없지만 기대도 된다.<br>지금은 어쩌다보니 이직한 곳에서 파이썬으로 코드를 작성하고 있는데 즐겁다. fluent python 도 재밌다.<br>spring cloud 관련 업무를 받게돼서 조만간 관련 공부를 시작할 것 같다. </p>]]></content:encoded>
<comments>https://sehajyang.github.io/2020/02/16/200113-200216/#disqus_thread</comments>
</item>
<item>
<title>2020년 1월 중간 회고</title>
<link>https://sehajyang.github.io/2020/01/22/200101-200112/</link>
<guid>https://sehajyang.github.io/2020/01/22/200101-200112/</guid>
<pubDate>Wed, 22 Jan 2020 05:36:00 GMT</pubDate>
<description>
<p>2019년 연간회고 이후 올해의 첫 회고를 작성하게 되었다.<br>이번달은 설 연휴가 껴서 그냥 1월 중순 회고를 작성하기로 했다.<br>3주간 주로 알고리즘 스터디를 중점적으로 했다. 알고리즘은 시간 있을때 틈틈히 해두는게 재밌고 좋은 것 같다.<br>그 밖엔 AWS re:invent 컨퍼런스에 갔다왔다.</p>
<h2 id="3주간-한-학습-및-개발"><a href="#3주간-한-학습-및-개발" class="headerlink" title="3주간 한 학습 및 개발"></a>3주간 한 학습 및 개발</h2><ul>
<li>알고리즘 스터디</li>
<li>7가지 동시성모델</li>
<li>AWS korea
</description>
<content:encoded><![CDATA[<p>2019년 연간회고 이후 올해의 첫 회고를 작성하게 되었다.<br>이번달은 설 연휴가 껴서 그냥 1월 중순 회고를 작성하기로 했다.<br>3주간 주로 알고리즘 스터디를 중점적으로 했다. 알고리즘은 시간 있을때 틈틈히 해두는게 재밌고 좋은 것 같다.<br>그 밖엔 AWS re:invent 컨퍼런스에 갔다왔다.</p><h2 id="3주간-한-학습-및-개발"><a href="#3주간-한-학습-및-개발" class="headerlink" title="3주간 한 학습 및 개발"></a>3주간 한 학습 및 개발</h2><ul><li>알고리즘 스터디</li><li>7가지 동시성모델</li><li>AWS korea community day re:invent 컨퍼런스 참석</li></ul><h3 id="알고리즘-스터디"><a href="#알고리즘-스터디" class="headerlink" title="알고리즘 스터디"></a>알고리즘 스터디</h3><p>요즘 친한 동료분들과 알고리즘 스터디를 하고 있고 시작한지는 2주 조금 넘었다.<br>강의는 저번에 완강하지 못한 <a href="https://code.plus/course/32" target="_blank" rel="noopener">SW 역량 테스트 준비 - 기초</a> 로 하고 있다.<br>과거에 여러가지 스터디를 만들어도 보고 참여도 해봤는데 가장 효율이 좋았고 참여율이 높았던건 매 주 과제 + 발표 였다.<br>그래서 알고리즘 스터디는 다음과 같이 진행하고 있다.</p><ol><li>저번주에 선정한 문제(5개, 백준 실버 중위 ~ 골드 상위) 코드리뷰 및 문제 해결방법 설명</li><li>이번주 강의 수강</li><li>다음주에 풀 문제 선정</li><li><a href="https://github.com/herren-algorithm-study/algorithm-basic" target="_blank" rel="noopener">알고리즘 레포</a>에 다음주 스터디 전 까지 푼 문제에 대한 소스코드 푸쉬 </li></ol><p>문제 난이도가 점점 올라가고 있어 평일에도 성실히 풀어야 모든 문제를 다 풀 수 있다(더 이상은 몰아서 푸는게 안된다..)<br>1주차 문제중 <a href="https://www.acmicpc.net/problem/6588" target="_blank" rel="noopener">골드바흐의 추측</a> 문제의 시간초과 때문에 조금 고생하고 있었는데, 같이 스터디하시는분이 알고리즘 문제는 보통 시간 제한은 빡빡한데 공간제약은 굉장히 널널하다는 얘길 해주셨고 그말에 힌트를 얻어 쉽게 해결할 수 있었다. 앞으로 이 꿀팁을 자주 써먹어야겠다.<br>2주차 문제중엔 <a href="https://www.acmicpc.net/problem/1072" target="_blank" rel="noopener">게임</a> 이라는 문제가 있었는데, 후에 할 게임을 모두 이겼다고 가정했을시, 몇판을 이겨야 승률이 변하는지를 출력하면 되는 문제였다.<br>문제를 처음봤을땐 쉬울 것 같고, 제한이 10억이라 바이너리 서치로 풀어야겠다 라고 생각했는데 내가 뭘 잘못했는지 모르겠지만 잘 되지 않았다(지금 생각해보면 아마 부동소수점 오차 문제 떄문이었을 것이라 생각된다)<br>당황해서 수학으로 풀어야지 하면서 식을 세웠는데 식을 잘못 세워서 고생을 좀 했다.<br>3주차는 2주차에 못푼 문제와 3주차에 선정한 문제들을 설 연휴동안 풀 예정이다. 알고리즘 혼자할땐 힘들고 어려웠는데, 다같이 하니까 너무 재밌다. 특히 서로서로 어떻게 짰고 어떻게 접근했나를 얘기하며 코드를 보는게 재밌었다.<br>다들 너무 잘하시고, 나한텐 난이도가 조금 높은 것 같지만 그래도 지금 이정도 난이도가 딱 좋은 것 같다. </p><h3 id="7가지-동시성모델"><a href="#7가지-동시성모델" class="headerlink" title="7가지 동시성모델"></a>7가지 동시성모델</h3><p>과거에 보다 만 책을 다시 폈다. 그때는 그냥 보기만 하고 예제를 직접 쳐보진 않았었는데 역시 이런 책은 직접 코드를 쳐봐야 하는 것 같다.<br>저번 akka 프로젝트는 너무 별로였던지라 제대로 akka로 토이프로젝트 하나 만들고 싶어서 액터모델부터 다시 보려고 폈다가 그냥 처음부터 보고 있다.<br>옛날에 나온 책이지만 정말 내용이 괜찮다. 중간에 알고리즘 문제 때문에 일시중지 되었지만 연휴에 바짝 볼 생각을 하고있다.</p><h3 id="AWS-re-invent-컨퍼런스-참석"><a href="#AWS-re-invent-컨퍼런스-참석" class="headerlink" title="AWS re:invent 컨퍼런스 참석"></a>AWS re:invent 컨퍼런스 참석</h3><p>가장 처음 세션 C 트랙 beNX에서 발표한 <code>전 세계 팬들이 모일 수 있는 플랫폼 만들기</code> 라는 세션이 정말 좋았다.<br>평소에 분당 2.7만회 정도의 요청이 들어오다 특정 아티스트가 글을 쓰는 순간 분당 270만회로 요청이 뛰어버리는데, 아티스트가 글을 쓰는 시간이 정해져 있지 않다보니 이 이벤트는 불규칙하게 낮에도 새벽에도 발생할 수 있었다.<br>그러한 과정에서 어떻게 하면 효율적이고 빠르고 안정적으로 트래픽을 핸들링할 수 있는지, 그렇게 하려면 어떻게 아키텍쳐를 설계해야 하는지, 서버최적화 설정은 어떻게 해야하는지 등의 아키텍쳐 설계 및 서버 튜닝에 대한 내용이었다. 정말 굉장하고, 유익했다.<br>나는 그간 계속 beNX의 해당 서비스를 사용해왔고 트래픽이 한꺼번에 몰릴때에도 거의 안정적으로 서버가 살아있는 것을 보며 감탄했었다.<br>급격한 트래픽을 대비하는 scalable 아키텍쳐를 어떻게 설계했을지 궁금했었는데 이번에 속 시원히 알 수 있었다. 이 세션에 대해서는 후기 포스팅을 따로 작성할 생각이다.</p><h2 id="다음달에-할-학습"><a href="#다음달에-할-학습" class="headerlink" title="다음달에 할 학습"></a>다음달에 할 학습</h2><ul><li>알고리즘 스터디 계속</li><li>7가지 동시성 모델 </li><li><a href="https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%8D%B0%EC%9D%B4%ED%84%B0-JPA-%EC%8B%A4%EC%A0%84/dashboard" target="_blank" rel="noopener">실전! 스프링 데이터 JPA</a></li></ul><h2 id="총평"><a href="#총평" class="headerlink" title="총평"></a>총평</h2><p>알고리즘을 즐겁게 할 수 있어서 알고리즘을 푸는데에 집중한 주 였다.<br>확실히 작년보다 알고리즘을 더 잘 풀수 있게 되었다. 아직 많이 부족하지만 이렇게 일주일에 5문제씩 꾸준히 풀면 연말 즈음에는 정말 알고리즘을 잘 풀수 있게 되지 않을까 싶다.<br>AWS 컨퍼런스는 정말 좋았다. 발표자분들이 준비를 많이 한 티가 많이 났던 것 같다 그만큼 내용도 정말 좋아서 새롭게 알게된것도 많았다.<br>그리고 나는 1년 2개월간의 즐거웠던 헤렌에서의 회사생활을 마치고 다른 회사로 가게 되었다. 그간 또래분들이 많아 즐겁게 게임모임도 하고 개발 얘기도 할 수 있었는데 이젠 못 하게 되어 아쉽다..<br>이직을 결정하게 된 이유는 더 깊게 배울 수 있는 기회가 왔다고 생각했기 때문이었다. 이직하는 곳은 지금까지와 마찬가지로 JAVA 및 스프링부트 스택이라, 올해안엔 토비의 스프링을 볼 생각을 하고있다. 하지만 파이썬도 포기할 수 없으니 fluent python도 볼 것이다.</p>]]></content:encoded>
<comments>https://sehajyang.github.io/2020/01/22/200101-200112/#disqus_thread</comments>
</item>
</channel>
</rss>