<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>경험의 연장선</title>
    <link>https://livenow14.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Wed, 6 May 2026 16:19:35 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>검프</managingEditor>
    <image>
      <title>경험의 연장선</title>
      <url>https://tistory1.daumcdn.net/tistory/3521623/attach/f110352d6301469f8a071bcde8da2c12</url>
      <link>https://livenow14.tistory.com</link>
    </image>
    <item>
      <title>ozh 테마 적용 안될 시 설정 방법</title>
      <link>https://livenow14.tistory.com/86</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;터미널에서 테마가 적용안되는 이슈 확인.&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;vim /Users/livenow/.oh-my-zsh/themes/agnoster.zsh-theme
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;를 보면 뭔가 git conflict가 났다.&lt;br /&gt;아래 레포에서 테마 설정 이슈가 났을 때, 어떻게 처리할 수 있는지 논의 되었던 것을 알 수 있다.&amp;nbsp;&lt;br /&gt;&lt;a href=&quot;https://github.com/agnoster/agnoster-zsh-theme/issues/155&quot;&gt;https://github.com/agnoster/agnoster-zsh-theme/issues/155&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;cd $ZSH
git config core.autocrlf input
git rm --cached -r .
git reset --hard
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후 다시 실행하면 잘된다&lt;/p&gt;</description>
      <category>Study</category>
      <category>agnoster-zsh-theme</category>
      <category>ozh</category>
      <author>검프</author>
      <guid isPermaLink="true">https://livenow14.tistory.com/86</guid>
      <comments>https://livenow14.tistory.com/86#entry86comment</comments>
      <pubDate>Thu, 27 Feb 2025 09:52:56 +0900</pubDate>
    </item>
    <item>
      <title>변수명 검색 사이트. 전세계 Github repo에서 검색하기</title>
      <link>https://livenow14.tistory.com/85</link>
      <description>&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;a href=&quot;https://grep.app/&quot;&gt;https://grep.app/&lt;/a&gt;&lt;/p&gt;</description>
      <category>Study</category>
      <category>find</category>
      <category>GitHub</category>
      <category>검색</category>
      <category>네이밍</category>
      <category>변수명</category>
      <category>사이트</category>
      <author>검프</author>
      <guid isPermaLink="true">https://livenow14.tistory.com/85</guid>
      <comments>https://livenow14.tistory.com/85#entry85comment</comments>
      <pubDate>Wed, 21 Feb 2024 16:26:22 +0900</pubDate>
    </item>
    <item>
      <title>[Git] macOS에서 Github 계정과 GitLab 계정을 폴더(Directory)별로 사용하자</title>
      <link>https://livenow14.tistory.com/83</link>
      <description>&lt;div class=&quot;markdown-body&quot;&gt;

&lt;blockquote&gt;
&lt;p&gt;git을 설치한 바로 직후라 가정하고 진행해요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;계정을 하나만 썼을 때는 global 설정으로 username과 email을 설정했는데, 관리해야 할 계정이 추가되니 매번 바꿔 줘야하는 불편함이 있었어요.&lt;br&gt;여러 블로그를 참고했는데, SSH로 설정하는 방법이 많더라구요. 근데 “원래도 안썼는데 굳이 써야할까?” 라는 의문점이 있었어요. &lt;/p&gt;
&lt;p&gt;결론적으로 &lt;code&gt;gitconfig 설정&lt;/code&gt;과 GitHub과 GitLab에서 제공하는 &lt;code&gt;Access Tokens&lt;/code&gt;으로도 충분히 설정 가능하다는 것을 알고 포스팅을 작성하게 됐어요 :)&lt;/p&gt;
&lt;br&gt;

&lt;h2&gt;GitConfig 설정&lt;/h2&gt;
&lt;p&gt;먼저 Git 설정을 할게요! iterm이나, 터미널을 열어 실행해주세요.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;vim ~/.gitconfig&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위의 파일에서, global 설정을 한다고 생각하면 될듯해요 :) 명령어로도 가능하지만, vim을 사용해서 설정해봐요. &lt;/p&gt;
&lt;h3&gt;파일 수정&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;[user]
  email = &amp;quot;깃허브 이메일&amp;quot;
  name = &amp;quot;깃허브 사용자이름&amp;quot;
[includeIf &amp;quot;gitdir: &amp;quot;깃랩 계정으로 접근할 디렉터리&amp;quot;&amp;quot;]
  path = &amp;quot;설정파일 위치&amp;quot;
[core]
  eol = lf                // OS 별로 CRLF 처리 차이로 인한 문제의 
  autocrlf = input        // 해결을 위한 설정&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;파일 수정 예시&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;[user]
  email = asdsd@naver.com
  name = livenow14
[includeIf &amp;quot;gitdir:/Users/livenow14/Desktop/woowa/&amp;quot;]
  path = .gitconfig-woowa
[core]
  eol = lf
  autocrlf = input&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;개인(Github) 계정을 global로 설정했어요 (실수로 회사 계정으로 push 해버리는 불상사 방지)&lt;br&gt;&lt;code&gt;includeIf&lt;/code&gt;는 git 과 관련된 명령어를 실행할 때, gitdir의 하위 repository라면 path에 있는 설정파일을 포함하는 옵션이에요. path는 식별가능하게 작성 해주시면 돼요.&lt;br&gt;여기서 중요하게 체크 해야할게, woowa폴더내의 그냥 폴더에서는 설정이 적용이 안되고 ,git이 포함된 곳에만 적용이 된다는 점이에요&lt;br&gt;ex) /woowa/work/repo1, /woowa/work/repo2가 있을 때, /woowa,  /woowa/work 폴더에는 적용이 안되고, repo1, repo2 폴더에만 적용이 된다. &lt;/p&gt;
&lt;p&gt;저는 회사에서 사용할 레포지토리들을 &lt;code&gt;바탕화면(Desktop)&lt;/code&gt;의 woowa 폴더에서 관리하고 싶어서 gitdir 위와 같이 설정했어요. &lt;/p&gt;
&lt;p&gt;깃의 설정파일 우선순위가 &lt;code&gt;Local(직접 설정한 것) &amp;gt; Global&lt;/code&gt;인 것을 참고하면 좋을 것 같아요.&lt;/p&gt;
&lt;p&gt;이제 회사(GitLab) 계정 또한 설정해주죠.&lt;/p&gt;
&lt;h3&gt;.gitconfig-woowa 파일 수정&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;vim ~/.gitconfig-woowa&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;[user]
  email = &amp;quot;깃랩 이메일&amp;quot;
  name = &amp;quot;깃랩 사용자이름&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;.gitconfig-woowa 파일 수정 예시&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;[user]
  email = livenow@woowa.com
  name = 검프&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;깃허브와 마찬가지로 이메일과 GitLab의 사용자이름을 설정해주면 돼요!&lt;/p&gt;
&lt;br&gt;

&lt;h2&gt;Access Token 발급&lt;/h2&gt;
&lt;p&gt;이제 Access Token을 발급 받아보죠! &lt;/p&gt;
&lt;h3&gt;GitHub Access Token 발급&lt;/h3&gt;
&lt;p&gt;먼저 메인 화면에서 맨 오른쪽 위 사진을 클릭하고 &lt;code&gt;Settings&lt;/code&gt;에 들어가요&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/148878053-9c8b17e8-18aa-41f7-860b-e33eff334b06.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/148878053-9c8b17e8-18aa-41f7-860b-e33eff334b06.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;그다음 &lt;code&gt;Developer settings&lt;/code&gt;를 클릭해요 &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/148878445-280e3edd-b516-414c-b047-b7246f4647eb.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/148878445-280e3edd-b516-414c-b047-b7246f4647eb.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;그 뒤, &lt;code&gt;Personal access tokens&lt;/code&gt;을 클릭해요 &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/148878800-43d9a0e5-2018-45c8-9efa-586678291f25.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/148878800-43d9a0e5-2018-45c8-9efa-586678291f25.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Generate new token&lt;/code&gt;으로 token 생성페이지로 가요 &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/148879039-ee979b82-10d1-4472-8c2d-2ab4a2e0a8f0.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/148879039-ee979b82-10d1-4472-8c2d-2ab4a2e0a8f0.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;token생성 페이지&lt;/code&gt;에서, 필요한 권한을 주고 이름을 설정해요 (저는 업무 노트북에서 사용할 것이기 때문에 repository삭제 권한 빼고 다 설정했어요.)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/148879867-3fdf23f9-d5fd-47bc-ab71-042043429e21.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/148879867-3fdf23f9-d5fd-47bc-ab71-042043429e21.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;Generate token을 클릭하면 token이 생성돼요. 여기서 나오는 token값은 페이지를 벗어나면 발급할 수 없으니, 따로 어딘가 저장해놓아요. 잊어버리면 무조건 재발급 해야해요.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;% 토큰값 저장 필수 %&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/148949259-7e16f273-a605-4b75-a537-faa870c5c3b2.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/148949259-7e16f273-a605-4b75-a537-faa870c5c3b2.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;이후 예시에는 &lt;code&gt;발급받은 깃허브 token&lt;/code&gt;이라 말할게요&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;GitLab Access Token 발급&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/149042605-efed0dbb-23f0-48ff-ac6a-47e350af42c0.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/149042605-efed0dbb-23f0-48ff-ac6a-47e350af42c0.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;Github랑 마찬가지로 Edit profile를 클릭해요 &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/148943151-f8735da9-5782-4aaf-b894-cd67b6bc67e6.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/148943151-f8735da9-5782-4aaf-b894-cd67b6bc67e6.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;Github랑 마찬가지로 &lt;code&gt;토큰이름&lt;/code&gt;이랑 &lt;code&gt;Expiration date&lt;/code&gt;, &lt;code&gt;필요한 권한&lt;/code&gt;을 설정해요. &lt;/p&gt;
&lt;p&gt;Expiration date는 따로 설정하지 않으면 영구적으로 사용할 수 있게 설정해요.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/148947620-be3eab09-64f7-4cdf-98e2-373d3ea83d04.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/148947620-be3eab09-64f7-4cdf-98e2-373d3ea83d04.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;여기서 나오는 token값은 Github와 마찬가지로 페이지를 벗어나면 발급할 수 없으니, 따로 어딘가 저장해놓아요.&lt;/p&gt;
&lt;p&gt;이후 예시에는 &lt;code&gt;발급받은 깃랩 token&lt;/code&gt;이라 말할게요&lt;/p&gt;
&lt;p&gt;&lt;code&gt;% 토큰값 저장 필수 %&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;위의 토큰값들은 사진찍고 바로 삭제했어요 ㅎㅎ&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;자 이제 발급받은 Access Token들을 mac에 저장해줘야해요.&lt;br&gt;저장된 Access Token들은 비밀번호의 역할을 할거에요. &lt;/p&gt;
&lt;br&gt;

&lt;h2&gt;Mac에 Credential 등록&lt;/h2&gt;
&lt;h3&gt;credential-osxkeychain 확인&lt;/h3&gt;
&lt;p&gt;credential-osxkeychain이 존재하는지 확인해요.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git credential-osxkeychain&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;있으면 아래와 같은 결과가 떠요.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git credential-osxkeychain
Usage: git credential-osxkeychain &amp;lt;get|store|erase&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;없으면 아래와 같은 결과가 떠요.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git credential-osxkeychain
xcode-select: note: no developer tools were found at &amp;#39;/Applications/Xcode.app&amp;#39;,
requesting install. Choose an option in the dialog to download the command line developer tools.&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;없을 경우, git을 다시 설치해주세요.&lt;/p&gt;
&lt;h3&gt;keychain 등록&lt;/h3&gt;
&lt;p&gt;이제, global 설정으로 keychain을 설정할 것을 예약해둬요.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git config --global credential.helper osxkeychain&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;자 이제 설정이 끝났어요! &lt;/p&gt;
&lt;p&gt;helper가 잘 등록됐나 보려면 &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;vim ~/.gitconfig&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;를 실행해보면 돼요 ㅎㅎ&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;[user]
  email = asdsd@naver.com
  name = livenow14
[includeIf &amp;quot;gitdir:/Users/livenow14/Desktop/woowa/&amp;quot;]
  path = .gitconfig-woowa
[core]
  eol = lf
  autocrlf = input
[credential]            //추가됨!
  helper = osxkeychain  //추가됨!&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;앞서 직접 설정했던 것 뒤에 추가로 설정된것이 보이시죠?! 이렇게까지 확인해봤다면 설정 완료!&lt;/p&gt;
&lt;p&gt;이제 git 작업시 딱 1번 닉네임과 토큰값을 입력 해주면, 이후 mac의 키체인에 자동적으로 저장될거에요.  &lt;/p&gt;
&lt;br&gt;

&lt;h2&gt;직접해보기&lt;/h2&gt;
&lt;h3&gt;woowa 폴더내의 레포지토리&lt;/h3&gt;
&lt;p&gt;앞서 woowa폴더에 Gitlab을 사용하도록 설정했어요. &lt;/p&gt;
&lt;p&gt;작업을 할 woowa폴더 내의 레포지토리에 들어가서 &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;git config user.name&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;과 &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;git config user.email&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;를 실행해보면 설정한 값이 잘 들어가는것을 알 수 있어요 &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/148962661-57949432-00e1-4c11-be1c-60dddc0df72d.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/148962661-57949432-00e1-4c11-be1c-60dddc0df72d.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;실제로 커밋이 어떻게 찍히는지 보고싶다면 아래와 같이 간단하게 커밋을 날려봐도 돼요! &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;touch test.txt
git add .
git commit -m &amp;quot;test&amp;quot;
git push origin main&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;첫 push를 할 때 username과 password를 입력하라 할거에요. &lt;/p&gt;
&lt;p&gt;여기는 회사용으로 사용할 거니, 깃랩의 name과 토큰값(&lt;code&gt;발급받은 깃랩 token&lt;/code&gt;)을 입력하면 돼요 (아까 저장한 토큰값 안까먹으셨죠?!)&lt;/p&gt;
&lt;h3&gt;woowa 폴더에 포함되지 않는 레포지토리&lt;/h3&gt;
&lt;p&gt;woowa폴더 안이 아닌 레포지토리는 일반적인 전역설정이 들어가겠죠? &lt;/p&gt;
&lt;p&gt;예시에선 study 폴더내의 레포에 접근했어요. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/148963638-203664b7-faaf-4819-b24f-2292f573a5ed.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/148963638-203664b7-faaf-4819-b24f-2292f573a5ed.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;처음에 설정한 값이 잘들어있네요! &lt;/p&gt;
&lt;p&gt;첫커밋을 찍을때 깃허브의 name과 토큰값(&lt;code&gt;발급받은 깃허브 token&lt;/code&gt;)을 입력해야겠죠?! ㅎㅎㅎ &lt;/p&gt;
&lt;br&gt;

&lt;h2&gt;끝!&lt;/h2&gt;
  
&lt;/div&gt;</description>
      <category>Study/Git</category>
      <category>Git</category>
      <category>GitHub</category>
      <category>GitLab</category>
      <category>동시</category>
      <category>디렉토리별 설정</category>
      <category>폴더</category>
      <author>검프</author>
      <guid isPermaLink="true">https://livenow14.tistory.com/83</guid>
      <comments>https://livenow14.tistory.com/83#entry83comment</comments>
      <pubDate>Tue, 11 Jan 2022 23:58:42 +0900</pubDate>
    </item>
    <item>
      <title>2021년의 기억</title>
      <link>https://livenow14.tistory.com/82</link>
      <description>&lt;div class=&quot;markdown-body&quot;&gt;

&lt;p&gt;작년 이맘때 우아한테크코스를 합격하며 회고를 남겼던 적이 있어요.&lt;br&gt;&lt;strong&gt;&lt;a href=&quot;https://velog.io/@livenow/%EC%9A%B0%EC%95%84%ED%95%9C-%ED%85%8C%ED%81%AC%EC%BD%94%EC%8A%A4-3%EA%B8%B0-%EC%B5%9C%EC%A2%85-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EB%B0%8F-%ED%95%A9%EA%B2%A9-%ED%9B%84%EA%B8%B0&quot;&gt;[우아한 테크코스 3기] 최종 테스트 및 합격 후기&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;위의 포스팅으로 1년 회고를 마무리했다 생각했는데, 지금 와서 보니 우테코 합격 얘기뿐이라 작년에 무엇을 했는지가 보이지 않네요.&lt;/p&gt;
&lt;p&gt;이번 포스팅에선 기억하고 싶은 부분들을 남겨보려 해요.&lt;/p&gt;
&lt;br&gt;

&lt;h2&gt;  기억하고 싶은 것&lt;/h2&gt;
&lt;h3&gt;  적당히 유지한 커밋&lt;/h3&gt;
&lt;p&gt;무엇을 배웠는지에 집중하고, 그 과정에 커밋을 녹여내기로 했어요. 만약 커밋을 못 남긴다면, 어쩔 수 없다고 생각했고요!&lt;/p&gt;
&lt;p&gt;1일1커밋을 유지하려다 보니, 어느 순간 커밋에 목표를 두고 있다는걸 알게 됐어요.&lt;br&gt;”커밋하기 좋은 공부인가?”라는 생각이 “이 공부를 통해 무엇을 얻을 수 있을까?”라는 생각보다 앞섯기에, 커밋을 남기기 전까지의 지식만을 공부했던 거였죠. 실제로 남는 것이 많이 없었어요.&lt;/p&gt;
&lt;p&gt;현재 상황에 필요하거나, 하고 싶은 공부를 하기로 했고 이 과정에 자연스럽게 커밋에 남겨지는 것을 깨달았어요. 조금 듬성듬성 하지만, 오히려 지식이 채워짐을 느꼈어요.&lt;br&gt;제가 중요하게 생각해야 할 것은 지식이지, 출석 체크가 아니었기 때문이에요.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/147875347-0a640973-8c68-422c-a893-0cf190e91362.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/147875347-0a640973-8c68-422c-a893-0cf190e91362.png&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;del&gt;이날 이후 회사 적응하느라 커밋을 찍지 못했다는 슬픈 전설이...&lt;/del&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;  블로그 포스팅 70개&lt;/h3&gt;
&lt;p&gt;지식을 혼자 가지고 있지 말고, 공유하자 마음먹었어요. 커밋은 혼자만의 만족이라면, 공유하는 만족은 모두의 만족임을 느꼈기 때문이에요. 또한 어려운 지식을 알기 쉽게 풀어서 글로 남겨주신 선배 개발자분들의 고마움에 대한 제 나름의 보답이라 생각했어요.&lt;/p&gt;
&lt;p&gt;언젠가 정리한 지식을 까먹더라도, 블로그 한 번만 보면 바로 이해할 수 있게끔 노력했어요.&lt;br&gt;정리하며, 알고 있는 부분과 모르는 부분을 정확히 파악할 수 있어서 좋았어요. 항상 “이거 블로그에 올려도 괜찮은가?”라는 질문에서 수정과 추가 작업을 많이 했어요. 또한 처음 글을 남길 땐 단순 문제 해결법을 작성했는데, 제가 쓴 글이 아니라는 느낌이 들어 저만의 언어로 만들어 작성하는 것으로 점점 발전 시켜 나갔어요.&lt;br&gt;이러한 과정은 가진 지식을 유지할 수 있는 가장 좋은 방법이었어요.&lt;/p&gt;
&lt;p&gt;블로그 포스팅은 2022년에도 유지할 예정이에요.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/147876792-7e004152-7c85-4aab-bc08-a1d1b14388ce.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/147876792-7e004152-7c85-4aab-bc08-a1d1b14388ce.png&quot;&gt;&lt;/p&gt;
&lt;h3&gt;  우아한테크코스 과정&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Livenow14/woowacourse-projects&quot;&gt;과정요약&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2020년 10월 지원부터 2021년 11월 수료까지 약 13개월의 시간을 몰입했어요.&lt;br&gt;”함께 자라기”라는 책에서는 일하는 순간에 부담감을 느끼는지 지루함을 느끼는지 항상 인식하며 난이도나 실력을 조정해야 한다고 말해요.&lt;/p&gt;
&lt;p&gt;책을 교육 기간이 끝날 때 쯤 읽었지만, 못해서 아쉬움이 남는 것이 아닌, 이미 그렇게 해왔다는 검증을 할 수 있었어요. 우테코 기간에서 지루함 혹은 부담감을 느낄 때 코치분들이나 주의 크루들에게 조언을 많이 구했기 때문이에요. 이러한 과정을 통해 몰입을 자연스럽게 경험할 수 있었다 믿어 의심치 않아요. 혼자만 고민하고 해결하려 했다면, 절대 경험할 수 없었을 거에요.&lt;/p&gt;
&lt;p&gt;함께한 모든 코치, 크루분들 고마워요 :)&lt;/p&gt;
&lt;p&gt;  &lt;strong&gt;거창에서의 사이드 프로젝트&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;레벨2 방학 기간에 크루원인 라이언, 유조, 동동과 함께 거창 시골집에서 사이드 프로젝트를 진행했어요(&lt;del&gt;검라유동이라는 팀이었어요 ㅎㅎ&lt;/del&gt;).&lt;br&gt;4박 5일 동안 코딩, 음주, 수면의 사이클로 진행했는데 웃음이 끊이질 않아서 “개발을 이렇게 재밌게 할 수 있구나”라는 걸 느끼게 됐어요. 이때의 추억이 이후에 많은 힘이 됐어요.&lt;br&gt;프로젝트 완성을 하진 못했지만, 프로젝트 설계부터 요구사항 정리, 컨벤션 정의 등의 협업 경험을 많이 할 수 있었어요.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/147879667-cda13a4a-0d92-4b13-8e9f-90bfd35dd062.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/147879667-cda13a4a-0d92-4b13-8e9f-90bfd35dd062.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;  &lt;strong&gt;추가 테코톡&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;의무적으로 해야 하는 테코톡외에 도커 관련 테코톡을 추가 진행했어요.&lt;/p&gt;
&lt;p&gt;도커를 깊게 공부해보고 싶기도 했었고, 도커 관련해서 테코톡 진행했으면 좋겠다는 의견? 도 있어서 진행한다 했는데, 생각보다 준비 시간이 많이 들었어요. 쉽게 생각했는데, 발표하려 하니 내용이 너무 넓었거든요.&lt;/p&gt;
&lt;p&gt;처음 영상을 촬영하니 3시간 정도의 분량이 나왔어요(&lt;del&gt;10분 테코톡 맞습니다&lt;/del&gt;). 돌려보니 쓸데없는 말도 많고, 뭘 말하려는지도 이해하기 힘들었어요. 하지만 내용을 줄인다면 연관성이 무너졌어요.&lt;/p&gt;
&lt;p&gt;이때 지식을 처음 접하는 입장에서 쉽게 이해 가능한지, 전달받는 내용에 납득이 가능한지 등을 고려했어요. “테코톡을 보는 사람이 모든 걸 알고 있다면 굳이 이 영상을 볼까?”라는 생각으로 처음 보는 사람의 입장에서 큰 그림을 볼 수 있게 하자는 생각으로 다시 촬영했어요(&lt;del&gt;그래도 1시간 30분이 나왔네요&lt;/del&gt;).&lt;/p&gt;
&lt;p&gt;이 과정을 통해 지식을 전달받는 입장에 대해 고민할 수 있었어요. 또한 정말 알고 있는지, 모르는지에 대해 스스로 증명할 수 있게 됐어요. 어려운 걸 어렵게 말하는 건 쉽지만, 쉽게 말하는 건 정말 어렵거든요.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=IiNI6XAYtrs&quot;&gt;https://www.youtube.com/watch?v=IiNI6XAYtrs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;  &lt;strong&gt;스터디&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;크루원들과 많은 스터디를 진행했어요.&lt;br&gt;송파구에서 일을 더 잘하는 11가지 방법에는 ”이끌거나, 따르거나, 떠나거나!”가 있어요. 스터디를 진행할 때 이 문구를 항상 생각했어요. 무언가 시작할 때, 이 3가지를 생각하지 않으면 항상 우선순위에서 밀리게 돼서 흐지부지되는 경우가 많았거든요.&lt;br&gt;애매하거나 모르는 부분을 스터디원들과 함께 알아갈 때, 많은 것을 배울 수 있었어요.&lt;br&gt;이 또한, 이후에도 의식적으로 유지해야 한다 생각해요.&lt;/p&gt;
&lt;h3&gt;  우아한형제들 입사&lt;/h3&gt;
&lt;p&gt;인생에 첫 직장인데 정말 좋은 회사인 우아한형제들에 입사하게 됐어요.&lt;br&gt;강렬하게 가고 싶었던 회사였고, 실제로 입사를 하게 되니 믿기지 않아요. 입사하기까지 도움을 주셨던 모든 분들에게 감사해요 :)&lt;/p&gt;
&lt;p&gt;입사 이후 누군가 제게 이런 말을 해주셨어요.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;이제 시작이네?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;제가 지금까지 성장하기 위해 노력해왔던 것들을 계속 유지해야 한다는 다짐과 목표를 주게 해 줬던 말이라, 항상 명심할 거에요.&lt;br&gt;또, 회사에서 필요한 개발자가 되기 위해 더욱 수련할 예정이에요(&lt;del&gt;내년 회고 때 검증할 수 있겠죠? ㅎㅎㅎㅎ&lt;/del&gt;).&lt;/p&gt;
&lt;br&gt;

&lt;h2&gt;  아쉬웠던 기억&lt;/h2&gt;
&lt;p&gt;개발하며 어려운 부분들을 키워드로 정리해놨는데, 그중 50%만 글로 정리했어요.&lt;br&gt;오늘은 바쁘니까 내일, 내일, 이렇게 미루다 보니 새해를 맞이하게 됐어요.&lt;br&gt;&lt;code&gt;오늘 하지 않으면 내일도 못 한다&lt;/code&gt;라는 걸 알게 된 한해였어요.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;그래서 목표는?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;이번 2022년도에는 아쉬웠던 부분들을 최소화하는 게 목표에요.&lt;br&gt;업무를 하며 어려운 부분, 애매한 부분들을 내일로 넘기지 말고, 그날그날 늦어도 그 주에 정리할 거예요 :)&lt;/p&gt;
&lt;br&gt;

&lt;h2&gt; ‍  급하게 결론을 내리자면&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;행복은 적금처럼 저장해서 꺼내쓸 수 있는 것이 아니다. 오늘 행복해야 내일도 행복할 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;정말 좋아하는 문장인데요. 저는 개발을 하고, 새로운 지식을 알아갈 때 행복을 느끼더라구요(물론 맛있는 거 먹었을 때도 마찬가지긴 하지만 ㅎㅎ). 이 행복을 놓치지 않으려고요!&lt;/p&gt;
&lt;p&gt;여러분은 어떤 것을 할 때 오늘 행복하다고 말할 것 같나요?!&lt;/p&gt;

  &lt;/div&gt;</description>
      <category>일기</category>
      <category>2021년</category>
      <category>2022년</category>
      <category>기억</category>
      <category>우아한테크코스</category>
      <category>우아한형제들</category>
      <category>우테코</category>
      <category>일기</category>
      <category>회고</category>
      <author>검프</author>
      <guid isPermaLink="true">https://livenow14.tistory.com/82</guid>
      <comments>https://livenow14.tistory.com/82#entry82comment</comments>
      <pubDate>Sun, 9 Jan 2022 09:48:32 +0900</pubDate>
    </item>
    <item>
      <title>[Java] Java8과 Java11의 특징</title>
      <link>https://livenow14.tistory.com/81</link>
      <description>&lt;div class=&quot;markdown-body&quot;&gt;

&lt;h1&gt;정리&lt;/h1&gt;
&lt;p&gt;java8의 특징은 &lt;a href=&quot;https://livenow14.tistory.com/73&quot;&gt;이전 포스트&lt;/a&gt;에 다뤘어요. 이번엔 java 11을 다뤄보려 해요.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Java 10은 라이선스 없이 상업적으로 사용할 수 있는 마지막 무료 &lt;code&gt;Oracle JDK&lt;/code&gt; 였어요.&lt;br&gt;JAva 11부터는 &lt;code&gt;Open JDK&lt;/code&gt;를 무료로 사용할 수 있어요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Java 11에서 추가된 내용들을 기능, 성능 관점에서 보도록 해요.  &lt;/p&gt;
&lt;br&gt;

&lt;h2&gt;기능 추가&lt;/h2&gt;
&lt;h3&gt;1. String 클래스, 메서드 추가&lt;/h3&gt;
&lt;p&gt;isBlank, lines, strip, stripLeading, stripTrailing, and repeat가 추가됐어요. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;String multilineString = &amp;quot;My name \n \n is \n Gump.&amp;quot;;
List&amp;lt;String&amp;gt; lines = multilineString.lines()
  .filter(line -&amp;gt; !line.isBlank())
  .map(String::strip)
  .collect(Collectors.toList());

assertThat(lines).containsExactly(&amp;quot;My name&amp;quot;, &amp;quot;is&amp;quot;, &amp;quot;Gump&amp;quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. File 클래스, 메서드 추가&lt;/h3&gt;
&lt;p&gt;readString, writeString이 추가됐어요. &lt;/p&gt;
&lt;p&gt;파일에서 문자열을 더 게 읽고 쓸 수 있게 됐어요. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;Path filePath = Files.writeString(Files.createTempFile(tempDir, &amp;quot;demo&amp;quot;, &amp;quot;.txt&amp;quot;), &amp;quot;Sample text&amp;quot;);
String fileContent = Files.readString(filePath);
assertThat(fileContent).isEqualTo(&amp;quot;Sample text&amp;quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 컬랙션 인터페이스, 메서드 추가&lt;/h3&gt;
&lt;p&gt;컬랙션의 toArray() 메서드를 오버로딩하는 메서드가 추가됐어요.&lt;/p&gt;
&lt;p&gt;원하는 타입의 배열을 선택할 수 있게 됐어요.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;List sampleList = Arrays.asList(&amp;quot;Java&amp;quot;, &amp;quot;Kotlin&amp;quot;);
String[] sampleArray = sampleList.toArray(String[]::new);
assertThat(sampleArray).containsExactly(&amp;quot;Java&amp;quot;, &amp;quot;Kotlin&amp;quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. Predicate 인터페이스, static not 메서드 추가&lt;/h3&gt;
&lt;p&gt;Predicate 인터페이스에 부정을 나타내는 not 메서드가 추가됐어요.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;#Predicate.java
static &amp;lt;T&amp;gt; Predicate&amp;lt;T&amp;gt; not(Predicate&amp;lt;? super T&amp;gt; target) {
    Objects.requireNonNull(target);
    return (Predicate&amp;lt;T&amp;gt;)target.negate();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;예시&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;List&amp;lt;String&amp;gt; sampleList = Arrays.asList(&amp;quot;Java&amp;quot;, &amp;quot;\n \n&amp;quot;, &amp;quot;Kotlin&amp;quot;, &amp;quot; &amp;quot;);
List withoutBlanks = sampleList.stream()
  .filter(Predicate.not(String::isBlank))
  .collect(Collectors.toList());
assertThat(withoutBlanks).containsExactly(&amp;quot;Java&amp;quot;, &amp;quot;Kotlin&amp;quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5. 람다에서 로컬 변수 Var 사용&lt;/h3&gt;
&lt;p&gt;람다식에서 var을 사용할 수 있게 됐어요. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;List&amp;lt;String&amp;gt; sampleList = Arrays.asList(&amp;quot;Java&amp;quot;, &amp;quot;Kotlin&amp;quot;);
String resultString = sampleList.stream()
  .map((@Nonnull var x) -&amp;gt; x.toUpperCase())
  .collect(Collectors.joining(&amp;quot;, &amp;quot;));
assertThat(resultString).isEqualTo(&amp;quot;JAVA, KOTLIN&amp;quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6. HTTP Client&lt;/h3&gt;
&lt;p&gt;Java 9에 도입된 HTTP 클라이언트가 표준 기능이 됐어요. (HTTP/1.1 과 HTTP/2을 지원헤요)전반적인 HTTP API의 성능이 향상댔어요. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;HttpClient httpClient = HttpClient.newBuilder()
  .version(HttpClient.Version.HTTP_2)
  .connectTimeout(Duration.ofSeconds(20))
  .build();
HttpRequest httpRequest = HttpRequest.newBuilder()
  .GET()
  .uri(URI.create(&amp;quot;http://localhost:&amp;quot; + port))
  .build();
HttpResponse httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
assertThat(httpResponse.body()).isEqualTo(&amp;quot;Hello from the server!&amp;quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7. &lt;strong&gt;Nest-Based Access Control&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;중첩클래스들이 접근지정자에 상관없이 서로의 필드에 접근이 가능해졌어요. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;class Test {  
    static class One {  
        private int one; 
     } 
     static class Two {  
        private int two;  
    }
 }&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;8. 자바 파일 실행&lt;/h3&gt;
&lt;p&gt;javac를 통해 컴파일 하지 않고도, 바로 실행할 수 있게 됐어요. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;# before

$ javac HelloWorld.java
$ java HelloWorld 
Hello Java 8!&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;# after

$ java HelloWorld.java
Hello Java 11!&lt;/code&gt;&lt;/pre&gt;
&lt;br&gt;

&lt;h2&gt;성능향상&lt;/h2&gt;
&lt;h3&gt;1. 동적 클래스 파일 상수&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;CONSTANT_Dynamic이라는 새로운 상수 풀 형식을 지원해요.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 개선된 Aarch64&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;기존 문자열 및 배열 내장 함수가 최적화 됐어요.&lt;/li&gt;
&lt;li&gt;java.lang.Math 의 sin, cos, log 메서드에 대한 새로운 내장 함수를 구현해요.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 새로운 GC&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Epsilon이라는 새로운 GC가 실험적으로 나왔어요.&lt;/li&gt;
&lt;li&gt;기본은 Z GC&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. JFR&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;애플리케이션에서 진단 및 프로파일링 데이터를 수집하는 데 사용할 수 있는 프로파일링 도구가 나왔어요.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;

&lt;h2&gt;Removed&lt;/h2&gt;
&lt;h3&gt;1. &lt;strong&gt;Java EE and CORBA&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;앞으로 EE 나 CORBA 모듈이 필요한 경우 명시적으로 의존을 추가해야 해요.&lt;/p&gt;
&lt;h3&gt;2. JMC and JavaFX&lt;/h3&gt;
&lt;p&gt;FX 라이브러리가 OpenJFX 프로젝트로 옮겨가면서 코어에서 삭제됐어요.&lt;/p&gt;
&lt;br&gt;

&lt;h2&gt;Deprecated&lt;/h2&gt;
&lt;h3&gt;1. Nashorn JavaScript engine&lt;/h3&gt;
&lt;h3&gt;2. Pack200 compression scheme for JAR files&lt;/h3&gt;
&lt;br&gt;

&lt;h2&gt;Java8의 사용이유&lt;/h2&gt;
&lt;p&gt;저는 최근까지도 Java 8을 사용했는데요. &lt;code&gt;&amp;quot;Java 11이 있는데 Java 8을 왜 사용했나?&amp;quot;&lt;/code&gt;라는 질문이 자주 들어와서 이유를 정리해볼해요. &lt;/p&gt;
&lt;h3&gt;1. 외부 개발 툴과의 연동성&lt;/h3&gt;
&lt;p&gt;웹서비스를 구동할 때, 자바 애플리케이션 외에 툴들이 필요한 경우가 있는데요. 이런 툴과의 연동성 문제에서 가장 안정적이라 생각해요. Java 11 부터 요금 정책이 바뀌었기 때문에, Oracle JDK가 아닌 Open JDK를 사용해야 하면서 생기는 이슈들이 꽤 있었어요. &lt;/p&gt;
&lt;h3&gt;2. Java 11에서의 변경사항이 크게 없음&lt;/h3&gt;
&lt;p&gt;메서드, 기능들이 어느정도 추가됐지만, Java8에서와 크게 차이가 나지 않기 때문에, Java 11을 사용해야하는 큰 이유를 찾지 못햇어요.&lt;br&gt;또한, Java 8 → Java 11에서의 문제가 크게 없기 때문에. 이후 릴리즈가 지원을 하지 않을 때, 버전 업그레이드를 한다 해도 괜찮다 생각해요.&lt;/p&gt;

  &lt;/div&gt;</description>
      <category>Study/Java</category>
      <category>Java</category>
      <category>java 11</category>
      <category>java 8</category>
      <category>Release</category>
      <author>검프</author>
      <guid isPermaLink="true">https://livenow14.tistory.com/81</guid>
      <comments>https://livenow14.tistory.com/81#entry81comment</comments>
      <pubDate>Sun, 14 Nov 2021 20:28:39 +0900</pubDate>
    </item>
    <item>
      <title>[Java] Java API 생성자 구현 및 검증 방식 (String, BigDecimal)</title>
      <link>https://livenow14.tistory.com/80</link>
      <description>&lt;div class=&quot;markdown-body&quot;&gt;


&lt;blockquote&gt;
&lt;p&gt;우테코 초기, 객체 검증, 할당 및 방어적 복사에 관련된 논의를 했던 적이 있어요. 논의에 대한 결과와 원문을 블로그에 남겨보려해요. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;원문 : &lt;a href=&quot;https://silly-elderberry-dd6.notion.site/Java-Java-API-8f4dceee5c84440288a5424a6326e457&quot;&gt;https://silly-elderberry-dd6.notion.site/Java-Java-API-8f4dceee5c84440288a5424a6326e457&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/107109142-f75b7200-6880-11eb-9c8e-600e7e55b603.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/107109142-f75b7200-6880-11eb-9c8e-600e7e55b603.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;생성자 코드 구현시, 검증로직을 어떤 순서로 진행하는게 좋을지에 대한 질문의 제이슨의 답변이었습니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;왜이리 멀리보고 있었지?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;답변을 듣고, 들었던 생각이었습니다.&lt;/p&gt;
&lt;p&gt;선배 자바 개발자분들이 멀리 있는 것이 아니라, 자바 코드 내에 살아 숨 쉰다는 사실을 까맣게 잊고 있었습니다. &lt;/p&gt;
&lt;p&gt;(질문을 한 제가 부끄러워지는 듯한 느낌이었습니다.. ㅠㅠ)&lt;/p&gt;
&lt;h3&gt;그냥 쓰는 것이 아닌, 알고 쓰자.&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;String, BigDecimal&lt;/strong&gt;은 어떻게 생성자 코드가 구현되고 또 검증의 순서는 어떻게 되는지 코드를 읽어보며 이해해보려 했습니다.&lt;/p&gt;
&lt;h2&gt;자바 버전&lt;/h2&gt;
&lt;p&gt;jdk 1.8.0_275&lt;/p&gt;
&lt;h2&gt;목차&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;String은 어떻게 검증되어 생성될까?&lt;/li&gt;
&lt;li&gt;BigDecimal은 어떻게 검증되어 생성될까?&lt;/li&gt;
&lt;li&gt;논의해볼 부분&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;String은 어떻게 검증되어 생성될까?&lt;/h2&gt;
&lt;p&gt;java.lang 패키지의 String 클래스를 먼저 살펴 보기로 했습니다.&lt;/p&gt;
&lt;h3&gt;클래스 선언 및 인스턴스 변수 확인&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/107106316-51067100-686e-11eb-8e6d-f2c4fcefd304.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/107106316-51067100-686e-11eb-8e6d-f2c4fcefd304.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;여기서 저는 3가지를 알 수 있었는데요. (밑에 두개는 아직 잘 모르겠어요..ㅎㅎ)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;첫번째,  String class는 상속할 수 없다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;final Class로 선언되어 있기때문에 다른곳에서 extends로 상속 할 수 없습니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;두 번째, 문자 저장시 불변 char 배열을 쓴다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;String은 결국 클래스이기 때문에 프리미티브 타입인 char을 통해 데이터를 저장한다는 것을 알 수 있습니다.  또한 불변을 위해 final을 쓴 것을 확인할 수 있습니다. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;마지막, hash는 불변이 아니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;hashCode는 &lt;strong&gt;고유한 값이지 주솟 값은 아니기 때문에&lt;/strong&gt; 불변이 아닙니다.&lt;/p&gt;
&lt;p&gt;무한정 생성되는 String과 달리 int는 한정적이기 때문에 value 값이 달라도 hash 값이 중복될 수 있습니다. &lt;/p&gt;
&lt;h3&gt;생성자 확인&lt;/h3&gt;
&lt;p&gt;String을 인스턴스화 하기위해 2가지의 생성 방법이 있는데요 &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;String pobi = &amp;quot;포비&amp;quot;;
String brown = &amp;quot;포비&amp;quot;;
String jason = new String (&amp;quot;포비&amp;quot;);
String cu = new String (&amp;quot;포비&amp;quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위의 생성 방식의 차이는 무엇일까요? &lt;strong&gt;제이슨의 수업&lt;/strong&gt;에서 확인할 수 있었습니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;리터럴로 생성할 경우,  String constant pool에&lt;br&gt;new String()으로 생성 할 경우 Heap에 새로운 주소 할당&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;와닿지 않을 것 같아 그림으로 그려보았습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/107108201-8c5a6d00-6879-11eb-8988-8a9651e5da2c.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/107108201-8c5a6d00-6879-11eb-8988-8a9651e5da2c.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;리터럴로 생성될 경우 &lt;strong&gt;String Constant Poll에 저장되기 때문에 같은 값일 시 같은 주소를 공유&lt;/strong&gt;하고, &lt;/p&gt;
&lt;p&gt;new String()으로 생성될 시 &lt;strong&gt;Heap에 새로운 공간이 할당&lt;/strong&gt;되는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;그렇기 때문에 아래 두개의 테스트가 통과 할 수 있습니다. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@DisplayName(&amp;quot;같은 이름의 문자열이 저장될 때 두 변수는 같다&amp;quot;)
    @Test
    void literalSameTest() {
        //given
        String pobi = &amp;quot;포비&amp;quot;;
        String brown = &amp;quot;포비&amp;quot;;

        //then
        assertThat(pobi).isEqualTo(brown);
        assertThat(pobi).isSameAs(brown);
    }&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@DisplayName(&amp;quot;같은 이름의 문자열로 String객체가 생성될 때, 두 변수가 같은지 비교한다&amp;quot;)
    @Test
    void objectSameTest() {
        //given
        String pobi = new String (&amp;quot;포비&amp;quot;);
        String brown = new String (&amp;quot;포비&amp;quot;);

        //then
        assertThat(pobi).isEqualTo(brown);
        assertThat(pobi).isNotSameAs(brown);
    }&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;그럼 Heap의 할당된 걸 String Constant Poll로 옮기지 못하나?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;intern()메소드를 활용하면 옮길수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/107108427-0fc88e00-687b-11eb-8be4-8dc4131ee2da.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/107108427-0fc88e00-687b-11eb-8be4-8dc4131ee2da.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;테스트도 정상 작동하는 것을 볼 수 있습니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@DisplayName(&amp;quot;intern() 정상 작동한다&amp;quot;)
    @Test
    void internTest() {
        //given
        String pobi = &amp;quot;포비&amp;quot;;
        String jason = new String (&amp;quot;포비&amp;quot;).intern();

        //then
        assertThat(pobi).isEqualTo(jason);
        assertThat(pobi).isSameAs(jason);
    }&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;생성자 구현 로직  확인&lt;/h3&gt;
&lt;p&gt;드디어 구현 로직을 살펴보는 과정까지 왔습니다. ( 자바 버전에 따라 조금 차이가 날 수 있으니, 위에서 명시한 버전을 꼭 확인해주세요! )&lt;/p&gt;
&lt;h3&gt;String pobi = &amp;quot;포비&amp;quot; 는 어떻게 동작하는거지?&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/107108615-9fbb0780-687c-11eb-9302-a3b9abd0b660.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/107108615-9fbb0780-687c-11eb-9302-a3b9abd0b660.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;String Class 문서에 따르면 &lt;/p&gt;
&lt;p&gt;String str = &amp;quot;abc&amp;quot;; 는&lt;/p&gt;
&lt;p&gt;char data[] = {&amp;#39;a&amp;#39;,&amp;#39;b&amp;#39;,&amp;#39;c&amp;#39;};&lt;/p&gt;
&lt;p&gt;String str = new String(data); 와 같다고 합니다. &lt;/p&gt;
&lt;h3&gt;검증은 어떻게?&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/107108676-135d1480-687d-11eb-8f12-1243cae4b6e8.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/107108676-135d1480-687d-11eb-8f12-1243cae4b6e8.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/107108702-4acbc100-687d-11eb-8fbc-d72e42003646.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/107108702-4acbc100-687d-11eb-8fbc-d72e42003646.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/107108727-78b10580-687d-11eb-81f2-7fb07b14623f.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/107108727-78b10580-687d-11eb-81f2-7fb07b14623f.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;String 클래스에선 값을 복사하고, System에서 필요한 검증을 한 후, 할당을 하는 것을 볼 수 있네요&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;제이슨&lt;/strong&gt;의 질문에 대한 &lt;strong&gt;첫번째&lt;/strong&gt; 답이 나왔습니다. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;String 클래스의 String(char value[]) 생성자는 &lt;code&gt;복사 -&amp;gt; 검증(System에서 필요한) -&amp;gt; 할당&lt;/code&gt;  한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;BigDecimal은 어떻게 검증되어 생성될까?&lt;/h2&gt;
&lt;h3&gt;클래스 선언 확인&lt;/h3&gt;
&lt;p&gt;인스턴스 변수는 이후 BigDecimal을 따로 정리할때 하기로 하고, 클래스 선언만 간단히 확인해보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/107108826-553a8a80-687e-11eb-896a-febbcffe8bdf.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/107108826-553a8a80-687e-11eb-896a-febbcffe8bdf.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;여기서 알수 있는 2가지는 &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;첫 번째, Number 클래스를 상속받았다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;두 번째, 순서 비교를 위해 Comparable&lt;BigDeciaml&gt;를 구현했다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;생성자 확인&lt;/h3&gt;
&lt;p&gt;저는 BigDecimal을 생성할 때 주로 String으로 인자를 넘겨주는데요, 테스트 먼저 확인하겠습니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@DisplayName(&amp;quot;BigDeciaml 저장 및 더하기 확인&amp;quot;)
    @Test
    void bigDeciamlSaveTest() {
        //given
        String five = &amp;quot;5&amp;quot;;
        String ten = &amp;quot;10&amp;quot;;

        //when
        BigDecimal fiveBigDecimal = new BigDecimal(five);
        BigDecimal tenBigDecimal = new BigDecimal(ten);
        BigDecimal sum = fiveBigDecimal.add(tenBigDecimal);

        //then
        assertThat(sum.intValue()).isEqualTo(15);
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;문자열이 숫자로만 이루어져있다면, 정상적으로 생성 되는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;그렇다면, String이 비어있거나, 숫자 값이 아닌경우 에러가 발생해야 할 것입니다. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@DisplayName(&amp;quot;문자열이 숫자가 아니라면 에러가 발생한다.&amp;quot;)
    @Test
    void bigDeciamlSaveErrorTest() {
        //given
        String five = &amp;quot;five&amp;quot;;
        String empty = &amp;quot;&amp;quot;;

        //then
        assertThatThrownBy(() -&amp;gt; new BigDecimal(empty))
                .isInstanceOf(NumberFormatException.class);

        assertThatThrownBy(() -&amp;gt; new BigDecimal(five))
                .isInstanceOf(NumberFormatException.class);
    }&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;생성자 구현 로직  확인&lt;/h3&gt;
&lt;p&gt;위의 검증은 어떻게 진행될까요, BigDecimal 클래스에서 확인해보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/107151761-adb97700-69a7-11eb-97e2-1336473bfff9.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/107151761-adb97700-69a7-11eb-97e2-1336473bfff9.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/107151849-291b2880-69a8-11eb-81fc-f2ed5cd8ebf9.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/107151849-291b2880-69a8-11eb-81fc-f2ed5cd8ebf9.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;베이스 생성자의 &lt;code&gt;toCharArray&lt;/code&gt;에서,  &lt;strong&gt;방어본을 만든 후 → 검증(System에서 필요한) → 반환을 하는 과정을&lt;/strong&gt; 볼 수 있습니다. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/107109074-700dfe80-6880-11eb-9b68-1df40f5ae2d1.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/107109074-700dfe80-6880-11eb-9b68-1df40f5ae2d1.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;결국, BigDecimal(String)에서 넘어온 &lt;strong&gt;복사가 끝난 값&lt;/strong&gt;이 인자(char[] in)로 들어오기 때문에 &lt;strong&gt;방어적 복사&lt;/strong&gt;가 이루어졌다고  볼 수 잇습니다. 복사된 값으로 &lt;strong&gt;BigDecimal에서 필요한 검증&lt;/strong&gt;을 하는 모습을 볼 수 있습니다. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;그렇다면 public BigDecimal(char[] in, int offset, int len, MathContext mc)으로 생성하는 것이랑 BigDecimal(String)의 차이점은 복사를 하는것 뿐인데, 뭐가 다른걸까요?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/107152296-7dbfa300-69aa-11eb-971b-b9c85905ea33.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/107152296-7dbfa300-69aa-11eb-971b-b9c85905ea33.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;문서에 따르면, BigDeicmal(String)보다 조금더 나은 성능을 기대할 수 있다고 합니다. (아무래도 값  복사를 하지 않기 때문이겠죠 → 더 넓게 볼 수 있는 관점을 주신 &lt;strong&gt;제이&lt;/strong&gt;, 감사합니다.)&lt;/p&gt;
&lt;p&gt;여기서는 CU의 질문의 답이 조금이나마 될 수 있을 듯 합니다. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/107152402-fa528180-69aa-11eb-91b6-ea1aa025cbc7.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/107152402-fa528180-69aa-11eb-91b6-ea1aa025cbc7.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;결론적으로, &lt;strong&gt;제이슨&lt;/strong&gt;의 질문에 대한 &lt;strong&gt;두번째&lt;/strong&gt; 답이 나왔습니다. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;BigDecimal(String) 생성자는 값을 할당 하기 전 복사본을 만들고, 검증을 한다.&lt;br&gt;또한 BigDecimal은 상황에 따라 &lt;code&gt;값 복사 → 검증 → 할당&lt;/code&gt; 혹은 복사없이 &lt;code&gt;검증 → 할당&lt;/code&gt; 한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;논의해볼 부분&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;완태&lt;/strong&gt;가 &lt;code&gt;검증 먼저 vs 항당 후 검증&lt;/code&gt;에 대한 질문을 남겨주셨는데요, 이부분은 저도 이렇다 할 정답이 떠오르지 않아 논의할 부분으로 남겨두려 합니다. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/107109257-20303700-6882-11eb-9acd-6ccde1552fcb.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/107109257-20303700-6882-11eb-9acd-6ccde1552fcb.png&quot;&gt;&lt;/p&gt;
&lt;h2&gt;7개월 후의 늦은 결론&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;&amp;quot;이후에 결론을 내자!&amp;quot;&lt;/code&gt;, 했던게 벌써 7개월 가량이 지나버렸네요((저때는 글의 어투도 달랐네요 ㅎㅎ). &lt;code&gt;&amp;quot;검증 후 할당 vs 할당 후 검증&amp;quot;&lt;/code&gt;을 논의해보는 것이었는데요.&lt;/p&gt;
&lt;p&gt;저의 결론은, &lt;code&gt;&amp;quot;검증 후 할당&amp;quot;&lt;/code&gt;을 하자 입니다.&lt;br&gt;할당을 먼저 하게 되면, 할당을 위해 준비되어야 할 객체 생성 비용과 할당된 객체의 검증 과정의 비용이 커질거라 생각하기 때문이에요. 또한, 실패했을 때, 쓸모없는 객체가 힙 영역에 추가 추가 되어 GC에 의해 해제되겠네요 :)&lt;/p&gt;
&lt;p&gt;지금 저의 결론이 정답이라고는 생각하지 않지만, 위와 같은 이유가 나름 명확하다 생각하기에.. 당분간은 유지될거라 생각해요!  &lt;/p&gt;
&lt;p&gt;여러분들의 생각은 어떤가요?&lt;/p&gt;

  &lt;/div&gt;</description>
      <category>Study/Java</category>
      <category>BigDeciaml</category>
      <category>JAVA API</category>
      <category>string</category>
      <category>검증</category>
      <category>방어적 복사</category>
      <category>생성자</category>
      <category>할당</category>
      <author>검프</author>
      <guid isPermaLink="true">https://livenow14.tistory.com/80</guid>
      <comments>https://livenow14.tistory.com/80#entry80comment</comments>
      <pubDate>Tue, 9 Nov 2021 16:36:30 +0900</pubDate>
    </item>
    <item>
      <title>[SpringBoot] 멀티모듈 구조에서, 다른 모듈의 테스트 클래스 사용하기</title>
      <link>https://livenow14.tistory.com/79</link>
      <description>&lt;div class=&quot;markdown-body&quot;&gt;

&lt;blockquote&gt;
&lt;p&gt;Gradle Test Fixture 사용해서 테스트 중복코드를 줄일 수 있어요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;멀티모듈 구조에서 다른 모듈의 Test 폴더를 사용할 수 없으니, 중복되는 클래스가 각각의 모듈의 Test 폴더에 포함되었어요.&lt;/p&gt;
&lt;p&gt;저는, Gralde 멀티모듈 구조에서, 의존을 하는 모듈의 Test 폴더까지 사용하고 싶었어요.&lt;br&gt;이때 사용할 수 있는 것이 Gradle Test Fixture입니다 ㅎㅎ&lt;/p&gt;
&lt;h2&gt;TestFixutre 적용&lt;/h2&gt;
&lt;p&gt;먼저 test fixture를 사용할 모듈에서 testfixture 의존성을 넣어요. (domain-cvi/build.gradle)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;plugins{
    id &amp;#39;java-library&amp;#39;    //**new**!!
    id &amp;#39;java-test-fixtures&amp;#39; //**new**!!
    id &amp;#39;maven-publish&amp;#39; //**new**!!
}

bootJar { enabled = false }
jar { enabled = true }

dependencies {
    implementation project(path:&amp;#39;:common-cvi&amp;#39;, configuration: &amp;#39;default&amp;#39;)
    implementation &amp;#39;org.springframework.boot:spring-boot-starter-data-jpa&amp;#39;
    runtimeOnly &amp;#39;com.h2database:h2&amp;#39;
    runtimeOnly &amp;#39;mysql:mysql-connector-java&amp;#39;
    implementation &amp;#39;org.hibernate.validator:hibernate-validator:6.2.0.Final&amp;#39;

    //migration
    implementation &amp;#39;org.flywaydb:flyway-core:7.11.2&amp;#39;

    //testFixture
    testFixturesImplementation &amp;#39;org.springframework.boot:spring-boot-starter-test&amp;#39;  //new!!
}
...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;testFixturesImplementation&lt;/code&gt;에 의존성이 추가된 것을 유의해주세요 (testFixture에서 사용할 라이브러리를 지정해줘야 합니다. )&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/137915781-0029546d-c7b5-42bc-95d4-ee34a117640a.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/137915781-0029546d-c7b5-42bc-95d4-ee34a117640a.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;testfixtures 폴더를 생성한 후, 멀티모듈 구조에 맞게 클래스를 생성해요.&lt;br&gt;(com/cvi/CustomParameterizeTest)&lt;/p&gt;
&lt;p&gt;이제 이를 사용할 모듈에서 아래와 같이 의존성을 추가해주면 끝! (app-cvi/build.gradle)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;version = &amp;#39;0.0.1-SNAPSHOT&amp;#39;

dependencies {
    implementation project(path:&amp;#39;:common-cvi&amp;#39;, configuration: &amp;#39;default&amp;#39;)
    implementation project(path:&amp;#39;:domain-cvi&amp;#39;, configuration: &amp;#39;default&amp;#39;)
    testImplementation(testFixtures(project(&amp;quot;:domain-cvi&amp;quot;)))    **//new!!
...**&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;일줄 알았더니... &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/137917455-ad051913-5b94-443c-b72d-b62c94ef2b9f.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/137917455-ad051913-5b94-443c-b72d-b62c94ef2b9f.png&quot;&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;Could not determine the dependencies of task &amp;#39;:app-cvi-api:test&amp;#39;.
&amp;gt; Could not resolve all task dependencies for configuration &amp;#39;:app-cvi-api:testRuntimeClasspath&amp;#39;.
   &amp;gt; Could not resolve project :domain-cvi.
     Required by:
         project :app-cvi-api
         project :app-cvi-api &amp;gt; project :domain-cvi-oauth-service
         project :app-cvi-api &amp;gt; project :domain-cvi-publicdata-service
         project :app-cvi-api &amp;gt; project :domain-cvi
      &amp;gt; Module &amp;#39;com.backjoongwon:domain-cvi&amp;#39; has been rejected:
           Cannot select module with conflict on capability &amp;#39;com.backjoongwon:domain-cvi:0.0.1-SNAPSHOT&amp;#39; also provided by [com.backjoongwon:domain-cvi:0.0.1-SNAPSHOT(default), com.backjoongwon:domain-cvi:0.0.1-SNAPSHOT(runtimeElements)]
   &amp;gt; Could not resolve project :domain-cvi.
     Required by:
         project :app-cvi-api
      &amp;gt; Module &amp;#39;com.backjoongwon:domain-cvi&amp;#39; has been rejected:
           Cannot select module with conflict on capability &amp;#39;com.backjoongwon:domain-cvi:0.0.1-SNAPSHOT&amp;#39; also provided by [com.backjoongwon:domain-cvi:0.0.1-SNAPSHOT(default), com.backjoongwon:domain-cvi:0.0.1-SNAPSHOT(runtimeElements)]

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위와 같은 예외가 발생하네요...&lt;/p&gt;
&lt;h2&gt;예외의 이유&lt;/h2&gt;
&lt;p&gt;멀티모듈 구조를 완전히 잘못잡고 있었어요.&lt;br&gt;이전까지는 &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;implementation project(path:&amp;#39;:domain-cvi&amp;#39;, configuration: &amp;#39;default&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이렇게 다른 멀티모듈의 의존성을 끌어오고 있었는데, 이는 하위 의존성을 모두 다 가져오게 돼요.&lt;br&gt;즉, app-cvi-api 에서 많은 모듈을 의존하고 있는데, &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/133215721-f0a9a634-ee3c-46d2-ac95-e073f12bd46f.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/133215721-f0a9a634-ee3c-46d2-ac95-e073f12bd46f.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;여기서, app-cvi-api가 의존하고 있는 모듈들 또한 domain-cvi를 의존하며, 의존성이 엄청나게 겹쳤던 것이에요!!! &lt;/p&gt;
&lt;p&gt;전체 모듈의 모듈 관련 의존성을 &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;# app-api-cvi
dependencies {
    implementation(project(&amp;quot;:common-cvi&amp;quot;))
    implementation(project(&amp;quot;:domain-cvi&amp;quot;))
    implementation(project(&amp;quot;:domain-cvi-oauth-service&amp;quot;))
    implementation(project(&amp;quot;:domain-cvi-publicdata-service&amp;quot;))
    implementation(project(&amp;quot;:domain-cvi-scheduler&amp;quot;))
    implementation(project(&amp;quot;:domain-cvi-aws-s3-service&amp;quot;))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;혹은&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;# domain-cvi
dependencies {
    compile(project(&amp;quot;:common-cvi&amp;quot;))
    compile &amp;#39;org.springframework.boot:spring-boot-starter-data-jpa&amp;#39;
    runtimeOnly &amp;#39;com.h2database:h2&amp;#39;
    runtimeOnly &amp;#39;mysql:mysql-connector-java&amp;#39;
    implementation &amp;#39;org.hibernate.validator:hibernate-validator:6.2.0.Final&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이렇게 바꿨어요. &lt;/p&gt;
&lt;h2&gt;정리&lt;/h2&gt;
&lt;p&gt;그렇다면, 차이점이 뭘까요?&lt;br&gt;클라이언트 모듈 &lt;code&gt;A&lt;/code&gt;(app-api-cvi), 의존 모듈 &lt;code&gt;B&lt;/code&gt;(domain-cvi)라 정할게요.&lt;br&gt;&lt;code&gt;A&lt;/code&gt; 모듈에서 &lt;code&gt;B&lt;/code&gt; 모듈을 implementation으로 의존했다 가정하면(implementation(project(&amp;quot;:domain-cvi&amp;quot;))),&lt;code&gt;B 모듈만 의존&lt;/code&gt;한다는 것이에요.&lt;br&gt;만약 &lt;code&gt;C&lt;/code&gt;라는 모듈이 &lt;code&gt;A&lt;/code&gt;를 의존하려 하려 한다면, &lt;code&gt;B&lt;/code&gt; 모듈을 가져오지 못해요.&lt;br&gt;즉, implementation이라 선언된 것은, 모듈 내에서만 의존해서 쓰고, 자신을 의존하려는 모듈에는 제공하지 않아요.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;B&lt;/code&gt; 모듈 내의 의존성 (jpa)은 comile이라 선언되어 있어요. 이는, &lt;code&gt;A&lt;/code&gt; 모듈이 &lt;code&gt;B&lt;/code&gt; 모듈을 의존할 때, &lt;code&gt;B&lt;/code&gt; 모듈은 jpa의존성도 제공해주겠다는 말이에요. (&lt;code&gt;A&lt;/code&gt; 모듈은 &lt;code&gt;B&lt;/code&gt; 모듈을 의존하며 JPA의존성도 사용할 수 있다. )&lt;/p&gt;
&lt;p&gt;정말 어려웠어요... 지금까지 대충 의존성을 주입하려 했었어요(반성합니다 ㅠㅠ)&lt;br&gt;compile과 implementation의 차이를 알아가게 된 계기라 생각해요.&lt;br&gt;testFixure의 자세한 내용은 꼭 &lt;code&gt;공식문서&lt;/code&gt;를 통해 확인해주세요 :)&lt;/p&gt;
&lt;h2&gt;Refer&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.gradle.org/6.8.3/userguide/java_testing.html#sec:java_test_fixtures&quot;&gt;https://docs.gradle.org/6.8.3/userguide/java_testing.html#sec:java_test_fixtures&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://bottom-to-top.tistory.com/58&quot;&gt;https://bottom-to-top.tistory.com/58&lt;/a&gt;&lt;/p&gt;
  
  &lt;/div&gt;</description>
      <category>Study/SpringBoot</category>
      <category>gradle</category>
      <category>Spring</category>
      <category>springboot</category>
      <category>Test</category>
      <category>testfixure</category>
      <category>스프링</category>
      <category>스프링부트</category>
      <category>중복테스트</category>
      <category>테스트</category>
      <author>검프</author>
      <guid isPermaLink="true">https://livenow14.tistory.com/79</guid>
      <comments>https://livenow14.tistory.com/79#entry79comment</comments>
      <pubDate>Tue, 2 Nov 2021 21:53:36 +0900</pubDate>
    </item>
    <item>
      <title>[HTTPS] 클라이언트와 서버가 HTTPS 프로토콜에서 통신할 때 CA 동작과정</title>
      <link>https://livenow14.tistory.com/78</link>
      <description>&lt;div class=&quot;markdown-body&quot;&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;인증 기관(Certificate Authority, CA)&lt;/code&gt;은 디지털 인증서를 발행하는 주체예요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;사용자가 접속한 사이트가 유효한 사이트인지 확인하는 역할을 해요. &lt;/p&gt;
&lt;h2&gt;동작과정 (그림 위주)&lt;/h2&gt;
&lt;h3&gt;인증기관(CA)에 사이트 정보, 공개키 전달&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/138006127-b82fb463-cdb2-45df-b22c-0a119c5d72c0.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/138006127-b82fb463-cdb2-45df-b22c-0a119c5d72c0.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;먼저 사이트는, 사이트 인증서(인증기관이 사이트에게 발급해주는 문서)가 필요해요.&lt;br&gt;이를 발급받기 위해 인증기관에게 사이트 정보와, 사이트 공개키를 전달해요.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;데이터 검증&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/138006211-c5c1cb77-5d7b-4fc6-b51e-4ed088acce2f.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/138006211-c5c1cb77-5d7b-4fc6-b51e-4ed088acce2f.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;인증기관은 전달받은 데이터를 검증해요.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;서명(암호화)&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/138006741-34baf408-2c9c-471d-bb3f-26f5a37d2037.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/138006741-34baf408-2c9c-471d-bb3f-26f5a37d2037.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;성공적으로 검증을 완료하면. 사이트 인증서 발급을 위해 인증기관의 비공개키로 서명(암호화)해요. &lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;인증서 전달&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/138006903-5cd33de9-0a49-4843-8b56-503d678958c8.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/138006903-5cd33de9-0a49-4843-8b56-503d678958c8.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;서명이 완료되면, 사이트 인증서가 생성이 되고, 생성한 인증서를 사이트에게 전달해요 &lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;인증된 사이트&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/138006984-6df8db33-750a-4ead-a68f-b0de3eae1daf.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/138006984-6df8db33-750a-4ead-a68f-b0de3eae1daf.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;인증된 사이트가 되었네요! &lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;인증기관 공개키 요청&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/138007102-f98238a0-0c5d-4876-9493-328d58d95ee4.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/138007102-f98238a0-0c5d-4876-9493-328d58d95ee4.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;클라이언트의 웹 브라우저에는 인증기관에서 발급한 인증서가 신뢰할 수 있는지를 확인하기 위해 &amp;#39;신뢰할 수 있는 인증서&amp;#39;(공개키)가 미리 등록되어 있어요.&lt;br&gt;여기까지는, 아직 클라이언트가 사이트에 접속 요청을 보내기 전이에요. &lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;사이트 접속요청&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/138007312-12a36daa-b20b-4f52-b46c-84925a061df5.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/138007312-12a36daa-b20b-4f52-b46c-84925a061df5.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;사용자가 사이트에게 접속 요청을 보내면, 사이트는 자신이 신뢰있는 사이트임을 증명하기 위해 사용자에게 사이트 인증서를 전달해요. &lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;인증서 복호화&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/138029800-6e6c9c0a-8aa7-4e36-97cb-39a24aeeda82.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/138029800-6e6c9c0a-8aa7-4e36-97cb-39a24aeeda82.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;사용자는 브라우저에 내장되어 있는 인증기관 공개키로, 사이트 인증서를 복호화 해서 검증해요.&lt;br&gt;사이트 인증서를 해독하면, 사이트 정보와 사이트 공개키를 얻을 수 있어요.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;대칭키 생성 (g^A mod p)&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/138030840-aeda6d75-a1a2-434a-bfac-c2c8b3b0cb5b.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/138030840-aeda6d75-a1a2-434a-bfac-c2c8b3b0cb5b.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;사용자는 자신의 &lt;code&gt;비공개키 A&lt;/code&gt;로 &lt;code&gt;대칭키(g^A mod p)&lt;/code&gt;를 생성해요. 이때 사용하는 알고리즘은 &lt;code&gt;디피-헬만 알고리즘&lt;/code&gt;이에요.&lt;br&gt;생성한 &lt;code&gt;대칭키&lt;/code&gt;와 &lt;code&gt;자신의 공개키&lt;/code&gt;를 &lt;code&gt;사이트 공개키&lt;/code&gt;로 감싸요. &lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;대칭키, 공개키 전달&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/138030998-af29f4e5-0b76-4fdb-b0cc-1859e242c1ba.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/138030998-af29f4e5-0b76-4fdb-b0cc-1859e242c1ba.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;이렇게 사용자가  &lt;code&gt;사이트 공개키&lt;/code&gt;로 감싸진 정보를 사이트로 보내면, 사이트는 &lt;code&gt;자신의 비공개키 B&lt;/code&gt;로 사용자에게서 받은 정보를 복호화해요.&lt;br&gt;사이트는 &lt;code&gt;사용자의 대칭키&lt;/code&gt;, &lt;code&gt;사용자 공개키&lt;/code&gt;를 얻어요. &lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;대칭키 생성 (g^B mod p)&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/138032156-ca8efe36-ddb3-47bf-865d-695b264e8511.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/138032156-ca8efe36-ddb3-47bf-865d-695b264e8511.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;사이트도 사용자와 마찬가지로, 자신의 &lt;code&gt;비공개키 B&lt;/code&gt;를 이용해서 &lt;code&gt;대칭키(g^B mod p)&lt;/code&gt;를 만들어요.&lt;br&gt;생성한 &lt;code&gt;대칭키&lt;/code&gt;와 &lt;code&gt;자신의 공개키&lt;/code&gt;를 &lt;code&gt;사용자 공개키&lt;/code&gt;로 감싸요. &lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;대칭키, 공개키 전달&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/138033714-51031206-9799-4f41-ba73-ec2c53b74c2c.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/138033714-51031206-9799-4f41-ba73-ec2c53b74c2c.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;사이트는 &lt;code&gt;사용자 공개키&lt;/code&gt;로 감싸진 &lt;code&gt;대칭키&lt;/code&gt;와 &lt;code&gt;자신의 공개키&lt;/code&gt;를 사용자에게 전달해요. &lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;대칭키 할당&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/138034412-347debf3-7622-44ed-9717-3326989f5914.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/138034412-347debf3-7622-44ed-9717-3326989f5914.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;이제 사용자, 사이트는 각각 &lt;code&gt;사이트의 대칭키(g^B mod p)&lt;/code&gt;, &lt;code&gt;사용자의 대칭키(g^A mod p)&lt;/code&gt;를 가지게 되었네요!&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;새로운 대칭키 생성(g^AB mod p)&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/138038751-133b6673-bc2a-4b88-8ed6-2b6036c846f8.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/138038751-133b6673-bc2a-4b88-8ed6-2b6036c846f8.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;사용자는 개인키 A를 사용해서 대칭키 &lt;code&gt;g^AB mod p&lt;/code&gt;를 생성하고, 사이트는 개인키 B를 사용해서 대칭키 &lt;code&gt;g^AB mod p&lt;/code&gt;를 생성합니다.&lt;br&gt;A와 B는 새로 생성한 이 대칭키로&lt;code&gt;(g^AB mod p&lt;/code&gt;)를 정보를 교환해요.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;새로운 대칭키에 의한 정보 전달&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/138042292-9b79f2fa-a031-44f5-a90e-4354fd2125ad.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/138042292-9b79f2fa-a031-44f5-a90e-4354fd2125ad.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;각각의 비공개키로 만들어진 대칭키라, 안전한 정보 교환이 가능하겠네요! &lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;질문 - 대칭키가 해커에 의해 해킹 당할 확률은?&lt;/h2&gt;
&lt;p&gt;이는 우테코 3기 크루, &lt;code&gt;다니&lt;/code&gt;가 설명해준 것으로 마무리 할게요. 현재 제 안목에서 가장 명확하다 생각이 드네요 :) &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/138043424-97622ce5-96f0-447a-a3f1-da9b903c020a.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/138043424-97622ce5-96f0-447a-a3f1-da9b903c020a.png&quot;&gt;&lt;/p&gt;
&lt;h2&gt;Refer&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://m.blog.naver.com/alice_k106/221468341565&quot;&gt;https://m.blog.naver.com/alice_k106/221468341565&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=wPdH7lJ8jf0&quot;&gt;다니의 테코톡&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

  &lt;/div&gt;</description>
      <category>Study/Network</category>
      <category>CA</category>
      <category>HTTPS</category>
      <category>tls</category>
      <category>개인키</category>
      <category>공개키</category>
      <category>대칭키</category>
      <category>디피헬만</category>
      <category>비공개키</category>
      <category>알고리즘</category>
      <category>인증기관</category>
      <author>검프</author>
      <guid isPermaLink="true">https://livenow14.tistory.com/78</guid>
      <comments>https://livenow14.tistory.com/78#entry78comment</comments>
      <pubDate>Wed, 20 Oct 2021 16:19:04 +0900</pubDate>
    </item>
    <item>
      <title>[JUnit5] @ParameterizedTest 애노테이션(반복 테스트) 커스텀 하기</title>
      <link>https://livenow14.tistory.com/77</link>
      <description>&lt;div class=&quot;markdown-body&quot;&gt; 

&lt;p&gt;반복 테스트(ParameterizedTest)에 대한 출력을 통일성 있게 하고싶어 아래와 같은 옵션들을 지정했어요. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@ParameterizedTest(name = &amp;quot;{displayName} {index}, args = {arguments}&amp;quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@DisplayName(&amp;quot;사용자 생성 - 성공&amp;quot;)
@ParameterizedTest(name = &amp;quot;{displayName} {index}, args = {arguments}&amp;quot;)
@ValueSource(strings = {&amp;quot;ㅁㅇㄹㅁㅇㄹ&amp;quot;, &amp;quot;ㅓㅓㅓㅓ&amp;quot;, &amp;quot;adfdf&amp;quot;, &amp;quot;검프&amp;quot;, &amp;quot;검프23213&amp;quot;})
void save(String name) {
...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;테스트 출력시 &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/137952034-e51a6530-805d-43cc-b7ad-4ee25610e0f1.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/137952034-e51a6530-805d-43cc-b7ad-4ee25610e0f1.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;위와 같이 나오며, &amp;quot;반복 테스트의 이름, 실행 번호, 파라미터&amp;quot;와 같은 형식으로 나오게 했어요.&lt;br&gt;정말 좋은데, 이러한 형식을 사용하기 위해 @ParameterizedTest를 사용하는 모든 곳에 위와 같은 옵션을 줘야해요. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;귀찮지 않나?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;맞아요. 테스트가 한 두개면 모르겠는데, 100개 이상인 반복 테스트에서 일일이 위와 같은 형식으로 작성하는 것은 문제가 있어요.&lt;/p&gt;
&lt;h3&gt;애노테이션 선언 (테스트 폴더에서)&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;#test/java/com/cvi 
package com.cvi;

import org.junit.jupiter.params.ParameterizedTest;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@ParameterizedTest(name = &amp;quot;{displayName} {index}, args = {arguments}&amp;quot;)
public @interface CustomParameterizedTest {
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;커스텀한 ParameterizeTest를 만들었어요.&lt;/p&gt;
&lt;p&gt;자세히 보면, &lt;code&gt;선언 위치는&lt;/code&gt; 애노테이션 타입과, 메소드에서, &lt;code&gt;실행시점&lt;/code&gt;은 런타임 시간에 작동하기로 선언하고, &lt;code&gt;@ParameterizedTest와 옵션을&lt;/code&gt; 함께 정의했어요.&lt;/p&gt;
&lt;p&gt;이게 되는 이유는 JUnit5에서 애노테이션을 조합하여 커스텀한 애노테이션을 만들 수 있게 지원하기 때문이에요.&lt;br&gt;여튼 이제, 반복 테스트 즉, @ParameterizedTest를 사용하는 곳에서는 동일한 출력을 보장할 수 있게 됐어요  &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@DisplayName(&amp;quot;사용자 생성 - 성공&amp;quot;)
@CustomParameterizedTest
@ValueSource(strings = {&amp;quot;ㅁㅇㄹㅁㅇㄹ&amp;quot;, &amp;quot;ㅓㅓㅓㅓ&amp;quot;, &amp;quot;adfdf&amp;quot;, &amp;quot;검프&amp;quot;, &amp;quot;검프23213&amp;quot;})
void save(String name) {
...
}&lt;/code&gt;&lt;/pre&gt;
  
  &lt;/div&gt; </description>
      <category>Study/Java</category>
      <category>Java</category>
      <category>Junit5</category>
      <category>ParameterizedTest</category>
      <category>반복테스트</category>
      <category>커스텀</category>
      <category>테스트</category>
      <author>검프</author>
      <guid isPermaLink="true">https://livenow14.tistory.com/77</guid>
      <comments>https://livenow14.tistory.com/77#entry77comment</comments>
      <pubDate>Wed, 20 Oct 2021 01:28:45 +0900</pubDate>
    </item>
    <item>
      <title>[MYSQL] 한글 별칭(aslias) 예외</title>
      <link>https://livenow14.tistory.com/76</link>
      <description>&lt;div class=&quot;markdown-body&quot;&gt;

&lt;h2&gt;문제상황&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.w3schools.com/sql/trymysql.asp?filename=trysql_func_mysql_concat&quot;&gt;https://www.w3schools.com/sql/trymysql.asp?filename=trysql_func_mysql_concat&lt;/a&gt; 에서 쿼리를 조작하여, 그림과 같은 결과를 얻고 싶었어요.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/136500715-9e0cfc56-1583-42d0-a215-b5522cb7c290.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/136500715-9e0cfc56-1583-42d0-a215-b5522cb7c290.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;쿼리를 아래와 같이 짰을 때&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;SELECT p.ProductID as &amp;#39;상품 아이디&amp;#39;, p.ProductName as &amp;#39;상품이름&amp;#39;, sum(od.Quantity) as sum
FROM Products as p
JOIN OrderDetails as od on p.ProductID = od.ProductID
GROUP BY od.ProductID HAVING sum &amp;gt;= 200
ORDER BY sum desc;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;아래의 결과가 나오게 돼요.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/136498357-85d85d29-a5bf-4033-8577-0f2ed00b34ac.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/136498357-85d85d29-a5bf-4033-8577-0f2ed00b34ac.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;&amp;quot;sum&amp;quot; 부분을 &amp;quot;총수량&amp;quot;으로 바꾸고 싶어서 아래와 같이 작성을 했는데,&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;SELECT p.ProductID as &amp;#39;상품 아이디&amp;#39;, p.ProductName as &amp;#39;상품이름&amp;#39;, sum(od.Quantity) as &amp;#39;총수량&amp;#39;
FROM Products as p
JOIN OrderDetails as od on p.ProductID = od.ProductID
GROUP BY od.ProductID HAVING &amp;#39;총수량&amp;#39; &amp;gt;= 200
ORDER BY &amp;#39;총수량&amp;#39; desc;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;동일해 보이는 로직처럼 보이지만 결과는 처참해요. ㅠㅠ&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/136500875-2692cb08-4e26-4c56-9a4c-920f6e92f48a.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/136500875-2692cb08-4e26-4c56-9a4c-920f6e92f48a.png&quot;&gt;&lt;/p&gt;
&lt;h2&gt;해결법&lt;/h2&gt;
&lt;p&gt; &lt;a href=&quot;https://dev.mysql.com/doc/refman/8.0/en/problems-with-alias.html&quot;&gt;https://dev.mysql.com/doc/refman/8.0/en/problems-with-alias.html&lt;/a&gt;  MYSQL의 공식 문서를 살펴보니,  별칭을 지정하는 곳에서는 &lt;code&gt;작은 따옴표&lt;/code&gt;(&amp;#39;)를 이를 이용하여 로직을 사용하는 곳에선 백틱(`)를 사용해야 한다고 하네요.&lt;br&gt;그렇지 않으면 문자열 리터럴로 파악을 한다고 합니다!&lt;/p&gt;
&lt;p&gt;즉, 아래와 같이 작성을 해야 &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;SELECT p.ProductID as &amp;#39;상품 아이디&amp;#39;, p.ProductName as &amp;#39;상품이름&amp;#39;, sum(od.Quantity) as &amp;#39;총수량&amp;#39;
FROM Products as p
JOIN OrderDetails as od on p.ProductID = od.ProductID
GROUP BY od.ProductID HAVING `총수량` &amp;gt;= 200
ORDER BY `총수량` desc;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;아래와 같이 제대로 된 로직이 실행이 돼요! &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/48986787/136501357-065b8206-b39a-4841-85df-ebf7a6ae681e.png&quot; alt=&quot;https://user-images.githubusercontent.com/48986787/136501357-065b8206-b39a-4841-85df-ebf7a6ae681e.png&quot;&gt;&lt;/p&gt;
&lt;h2&gt;결론&lt;/h2&gt;
&lt;p&gt;MYSQL 공식문서에 에러에 대한 부분이 잘 정리되어있네요 ㅎㅎ&lt;br&gt;역시 공식문서가 최고..!&lt;/p&gt;

  &lt;/div&gt;</description>
      <category>Study/DB</category>
      <category>alias</category>
      <category>AS</category>
      <category>MySQL</category>
      <category>select</category>
      <category>따옴표</category>
      <category>백틱</category>
      <category>별칭</category>
      <category>예외</category>
      <author>검프</author>
      <guid isPermaLink="true">https://livenow14.tistory.com/76</guid>
      <comments>https://livenow14.tistory.com/76#entry76comment</comments>
      <pubDate>Fri, 8 Oct 2021 14:12:01 +0900</pubDate>
    </item>
  </channel>
</rss>