<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>:wq!</title>
        <link>https://velog.io/</link>
        <description>Connecting the dots</description>
        <lastBuildDate>Mon, 01 May 2023 14:33:58 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>:wq!</title>
            <url>https://images.velog.io/images/3rd-big/profile/74eada8e-8844-4784-a511-a0b2c53e0a5a/apple-icon.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. :wq!. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/3rd-big" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[TIL] 20230425]]></title>
            <link>https://velog.io/@3rd-big/TIL-20230425</link>
            <guid>https://velog.io/@3rd-big/TIL-20230425</guid>
            <pubDate>Mon, 01 May 2023 14:33:58 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>🌟 <strong>Today 요약</strong></p>
</blockquote>
<ol>
<li>배포 시 상용/테스트 모두 호환되는 코드 작성하기</li>
<li>스테이징 서버 필요성</li>
<li>사소하다 생각되는 버그는 무조건 확인하기</li>
<li>java null-safety한 코드 작성하기</li>
</ol>
<hr>
<h2 id="what-i-udidu"><em>What I <u>did?</u></em></h2>
<blockquote>
<p><strong>상용서버(API) 배포</strong></p>
</blockquote>
<ul>
<li><strong>유저</strong><ul>
<li>로그인 시 유저 디바이스 정보 Insert</li>
</ul>
</li>
<li><strong>메시지</strong><ul>
<li>AOS(FCM), IOS(APNs) Push</li>
</ul>
</li>
</ul>
<blockquote>
<p><strong>Admin</strong></p>
</blockquote>
<ul>
<li>Excel Download 추가</li>
</ul>
<br>

<h2 id="what-i-ulearnedu"><em>What I <u>Learned?</u></em></h2>
<blockquote>
<p><strong>null-safety한 코드 작성</strong></p>
</blockquote>
<ul>
<li>java 코드 작성 시 객체의 정보에 접근 할 상황이 많음</li>
<li>특정 객체의 값이 null 일 경우 NPE Error 발생..</li>
<li><strong><em>Optional.ofnullable</em></strong> 활용</li>
</ul>
<blockquote>
<p><strong>배포 시 주의사항</strong></p>
</blockquote>
<ul>
<li>신규 기능 추가 된 내용 QA 진행 할 때 기존에 배포되어있는 내용과 호환되는 코드 작성 필요<ul>
<li>기존에 없던 정보를 추가로 받아 저장하는 로직을 추가함</li>
<li>기존에 배포 된 앱은 해당 정보를 넘겨주지 않음</li>
<li>기존 배포 된 앱에서 해당 정보를 넘겨주지 않기에 로그인 에러 발생..</li>
<li>해당 정보유무를 판단하여 <strong><em>기존 로직과의 호환성 있는 코드 작성 필요</em></strong></li>
</ul>
</li>
</ul>
<blockquote>
<p><strong>SQL In 절 Query</strong></p>
</blockquote>
<ul>
<li>In 절에 포함 될 내용을 ArrayList 로 뽑다보니 중복 된 내용 전부 포함하여 조회됨</li>
<li>해당 내용을 Set 으로 변환하여 작성</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Mac] 맥 터미널 iterm2 단축키]]></title>
            <link>https://velog.io/@3rd-big/Mac-%EB%A7%A5-%ED%84%B0%EB%AF%B8%EB%84%90-iterm2%EB%8B%A8%EC%B6%95%ED%82%A4</link>
            <guid>https://velog.io/@3rd-big/Mac-%EB%A7%A5-%ED%84%B0%EB%AF%B8%EB%84%90-iterm2%EB%8B%A8%EC%B6%95%ED%82%A4</guid>
            <pubDate>Sun, 18 Apr 2021 16:25:20 GMT</pubDate>
            <description><![CDATA[<p>M1 구입 후 초기세팅은 해당 <a href="https://www.44bits.io/ko/post/setup-apple-silicon-m1-for-developers">블로그를</a> 참조</p>
<p>iTerm2 사용 시 관련 단축키를 수시로 검색하기보다 해당 포스트에 수시로 업데이트하여 사용하고자 함</p>
<ul>
<li><p>실행 단축키</p>
<ul>
<li>이건 아무리 검색해도 없음(내가 못찾은 걸지도..)</li>
<li>대신 특정 Application을 실행할 수 있는 기능 추가</li>
<li>참조 <a href="https://technote.kr/330">블로그</a></li>
</ul>
</li>
<li><p>새 창: <code>Command(⌘) + n</code>
<img src="https://images.velog.io/images/3rd-big/post/ce6204cb-5b1c-46bd-b6db-2cc104b279be/image.png" alt=""></p>
</li>
<li><p>새 탭: <code>Command(⌘) + t</code></p>
</li>
</ul>
<p><img src="https://images.velog.io/images/3rd-big/post/d6282431-bde5-4170-a16f-9ef52147e061/image.png" alt=""></p>
<ul>
<li>탭 세로 분할: <code>Command(⌘) + d</code></li>
</ul>
<p><img src="https://images.velog.io/images/3rd-big/post/7de78b70-0a7d-4d26-a3ff-806c0055fa52/image.png" alt=""></p>
<ul>
<li>탭 가로 분할: <code>Command(⌘) + Shift + d</code></li>
</ul>
<p><img src="https://images.velog.io/images/3rd-big/post/c9c6a2a8-fdf2-45bb-b315-e3cd38b83a8b/image.png" alt=""></p>
<ul>
<li><p>탭 닫기: <code>Command(⌘) + w</code></p>
</li>
<li><p>탭 분할 시 포커스 찾기: <code>Command(⌘) + /</code></p>
</li>
<li><p>탭 분할 포커스 이동: <code>Command(⌘) + [ or ]</code></p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 다형성(polymorphism)]]></title>
            <link>https://velog.io/@3rd-big/JAVA-%EB%8B%A4%ED%98%95%EC%84%B1polymorphism</link>
            <guid>https://velog.io/@3rd-big/JAVA-%EB%8B%A4%ED%98%95%EC%84%B1polymorphism</guid>
            <pubDate>Sun, 11 Apr 2021 07:13:04 GMT</pubDate>
            <description><![CDATA[<h2 id="다형성">다형성</h2>
<ul>
<li>자바에서는 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록 함으로써 다형성을 프로그램적으로 구현</li>
<li><strong><span style="color:#3385ff">조상클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있도록 함</span></strong><pre><code class="language-java"> Parent p = new Child(); // 가능</code></pre>
</li>
<li>반대로 <span style="color:red"><strong>자손타입의 참조변수로 <del>조상타입의 인스턴스를 참조</del>할 수는 없음</strong></span><pre><code class="language-java"> Child c = new Parent(); // 불가능</code></pre>
</li>
<li>참조변수가 사용할 수 있는 멤버의 개수는 인스턴스의 멤버 개수보다 같거나 적어야 함</li>
<li><span style="color:red"><strong>주의</strong></span>할 사항은<strong>참조여부</strong>와 <strong>사용여부</strong>는 <span style="color:red"><strong>다름</strong></span><ul>
<li>조상클래스 타입의 참조변수가 자손클래스의 인스턴스를 참조하니까 p 변수로 Child클래스의 메소드는 모두 쓸수있나? ( <span style="color:red"><strong>X 불가능</strong></span> )</li>
<li>단, <strong>조상타입을 자손타입으로 형변환</strong>하면 <span style="color:#3385ff"><strong>사용가능</strong></span></li>
</ul>
</li>
</ul>
<pre><code class="language-java">    public class polymorphism {
        public static void main(String[] args) {
            Parent p = new Child();
            Child c = new Child();
            p.method();
            p.cMethod();       // 컴파일 에러!!
            ((Child) p).cMethod(); // 이런식으로 형변환을 통해 사용가능
            c.method();
            c.pMethod();
        }
    }

    class Parent {
        void method() {
            System.out.println(&quot;Parent Method&quot;);
        }
        void pMethod() {
            System.out.println(&quot;pMethod&quot;);
        }
    }

    class Child extends Parent{
        void method() {
            System.out.println(&quot;Child Method&quot;);
        }
        void cMethod(){
            System.out.println(&quot;cMethod&quot;);
        }
    }
</code></pre>
<br>

<h3 id="instanceof-연산자">instanceof 연산자</h3>
<ul>
<li>참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아보기 위해 <strong><code>instanceof</code></strong>연산자를 사용</li>
<li><strong><code>instanceof</code></strong>의 왼쪽에는 참조변수를, 오른쪽에는 타입(클래스명)이 피연산자로 위치</li>
<li>연산의 결과로 <strong>boolean</strong>값인 <span style="color:#3385ff"><strong>true</strong></span>와 <span style="color:red"><strong>false</strong></span> 중의 하나를 반환</li>
<li>어떤 타입에 대한 <strong><code>instanceof</code></strong>연산의 결과가 <span style="color:#3385ff"><strong>true</strong></span> 라는 것은 <span style="color:#3385ff"><strong>검사한 타입으로 형변환이 가능</strong></span>하다는 것을 의미<pre><code class="language-java">  void doWork(Parent p) {
      if (p instanceof Child) {
          Child c = (Child) p;
          c.childMethod();
     }
  }</code></pre>
<blockquote>
<p>값이 <span style="color:red"><strong>null</span>인 참조변수</strong>에 대해 <strong>instanceof</strong>연산을 수행하면 <span style="color:red"><strong>false</strong></span></p>
</blockquote>
</li>
</ul>
<br>

<h3 id="참조변수와-인스턴스의-연결">참조변수와 인스턴스의 연결</h3>
<p>조상 클래스에 선언된 멤버변수와 같은 이름의 인스턴스변수를 자손 클래스에 <strong>중복으로 정의</strong> 했을 때, <strong>조상 타입의 참조변수로 자손 인스턴스를 참조하는 경우</strong>와 <strong>자손타입의 참조변수로 자손타입의 참조변수로 자손 인스턴스를 참조하는 경우</strong>는 서로 <span style="color:red"><strong>다른 결과</strong></span></p>
<blockquote>
<p><span style="color:#3385ff"><strong>메서드</strong></span>의 경우 오버라이딩된 메서드가 호출되지만, <span style="color:red"><strong>멤버변수</strong></span>의 경우는 다른 결과</p>
</blockquote>
<pre><code class="language-java">public class javaStudy {
    public static void main(String[] args) {
        Parent p = new Child();
        Child c = new Child();

        System.out.println(&quot;p.x = &quot; + p.x);
        p.method();
        System.out.println(&quot;c.x = &quot; + c.x);
        c.method();
    }
}

class Parent {
    int x = 100;

    void method() {
        System.out.println(&quot;Parent Method&quot;);
    }
}

class Child extends Parent{
    int x = 200;

    void method() {
        System.out.println(&quot;Child Method&quot;);
    }
}</code></pre>
<pre><code class="language-java">---------------- Result----------------
p.x = 100
Child Method
c.x = 200
Child Method
---------------------------------------</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 클래스(Class)]]></title>
            <link>https://velog.io/@3rd-big/JAVA-%ED%81%B4%EB%9E%98%EC%8A%A4Class</link>
            <guid>https://velog.io/@3rd-big/JAVA-%ED%81%B4%EB%9E%98%EC%8A%A4Class</guid>
            <pubDate>Sun, 28 Mar 2021 07:07:50 GMT</pubDate>
            <description><![CDATA[<h2 id="객체-지향-프로그래밍">객체 지향 프로그래밍</h2>
<p><code>객체(Object)</code>란 <strong>물리적으로 존재</strong>하거나 <strong>추상적으로 생각할 수 있는 것</strong> 중에서 <strong>자신의 속성(객체의 데이타)을 가지고 있고 다른 것과 식별 가능한 것</strong></p>
<p>객체는 <code>속성(=필드(field))</code>과 <code>동작(=메소드(method))</code>으로 구성</p>
<p>프로그래밍은 결국 데이터를 다루는 일이라 생각되며, 객체 지향 프로그래밍에서도 해당
객체들은 각각 독립적으로 존재하고, 다른 객체와 서로 상호작용하면서 동작. <strong>객체들 사이의 상호작용 수단은</strong> <code>메소드</code>이며, <strong>객체가 다른 객체의 기능을 이용하는 것이 바로 메소드 호출</strong></p>
<h3 id="다형성polymorphism">다형성(Polymorphism)</h3>
<p>김영한님 인프런 강의<code>스프링 핵심 원리 - 기본편</code> 강의 초반에 이런 말씀을 하심</p>
<blockquote>
<p>스프링 뭐 별거 없습니다. 결국 스프링이란 것도 자바의 객체지향의 다형성을 극대화 시켜서 사용하는거라고 보면 됩니다.</p>
</blockquote>
<p>그 후로 공부 할 때 이 부분을 항상 의식하면서 공부하고 있으며, 다형성은 다음과 같은 특징이 있음</p>
<ul>
<li>다형성(多形性)<ul>
<li>같은 타입이지만 실행 결과가 다양한 객체를 이용할 수 있는 성질</li>
<li>부모 타입에는 모든 자식 객체가 대입될 수 있음</li>
<li><strong>인터페이스 타입에는 모든 <em>구현 객체</em> 가 대입</strong>될 수 있음</li>
<li>다형성의 효과로 <strong>객체는 부품화가 가능</strong>하다</li>
</ul>
</li>
</ul>
<h2 id="객체와-클래스">객체와 클래스</h2>
<p>객체 지향 프로그래밍에선 <strong>메모리에서 사용하고 싶은 객체가 있다면 우선 설계도로 해당 객체를 만드는 작업이 필요</strong>하며, 자바에서는 설계도가 바로 <code>클래스(Class)</code>
클래스에는 객체를 생성하기 위한 <code>필드</code>와 <code>메소드</code>가 정의되어 있음
클래스로부터 만들어진 객체를 해당 클래스의 <code>인스턴스(instance)</code>라고 함</p>
<h3 id="클래스-선언">클래스 선언</h3>
<ul>
<li>영어 대소문자를 구분하며 관례적으로 <code>첫 자를 대문자</code>로 작성</li>
</ul>
<h3 id="객체-생성">객체 생성</h3>
<ul>
<li><p><code>new</code> </p>
<ul>
<li>클래스로부터 객체체를 생성</li>
<li>해당 연산자로 생성된 <code>객체</code>는 <strong>메모리 힙(heap) 영억에 생성</strong></li>
<li>연산자는 힙 영역에 객체를 생성시킨 후, <strong>객체의 주소를 리턴</strong></li>
</ul>
<pre><code class="language-java">Study s1 = new Study();</code></pre>
<p><img src="https://images.velog.io/images/3rd-big/post/dc69bc96-2f36-4bef-b7f2-9a97d8249d3f/Untitled%20Diagram.png" alt=""></p>
</li>
</ul>
<h3 id="클래스-구성-멤버">클래스 구성 멤버</h3>
<pre><code class="language-java">public class ClassName {
    // 필드
    int fieldName;

    // 생성자
    ClassName() { ··· }

    // 메소드
    void methodName() { ··· }
}</code></pre>
<h4 id="필드field">필드(Field)</h4>
<ul>
<li><p>객체의 데이터가 저장되는 곳</p>
</li>
<li><p>초기값이 지정되지 않은 필드들은 객체 생성 시 자동으로 기본 초기값으로 설정<strong>(변수와 헷갈리지 말것)</strong></p>
<blockquote>
<p>선언 형태는 변수(variable)과 비슷하지만, <strong><del>필드를 변수</del>라고 부르진 않음</strong></p>
</blockquote>
<ul>
<li>필드: 생성자와 메소드 전체에서 사용되며 <strong><em>객체가 소멸되지 않는 한 객체와 함께 존재</em></strong></li>
<li>변수: <em><strong>생성자와 메소드 내에서만 사용</strong></em> 되며 <strong><em>생성자와 메소드가 실행 종료되면 자동 소멸</em></strong></li>
</ul>
</li>
</ul>
<h4 id="생성자">생성자</h4>
<ul>
<li><a href="#%EA%B0%9D%EC%B2%B4-%EC%83%9D%EC%84%B1">new</a> 연산자로 호출</li>
<li>객체 생성 시 초기화를 담당</li>
<li><strong>클래스 이름</strong>으로 되어 있고 <del>리턴타입</del>이 없다</li>
<li>컴파일러가 기본생성자를 생성해주며, 클래스 내에 생성자가 없을 경우에만 생성</li>
<li><strong>기본 생성자가 없이 오버로딩 된 생성자만 있을 경우</strong>, <del><strong>기본 생성자로 객체생성</strong></del> 불가</li>
<li>접근제어를 <code>private</code>으로 설정할 경우 <a href="#%EC%8B%B1%EA%B8%80%ED%86%A4">싱글톤(Singleton)</a>으로 설정되며 <del><code>new</code>연산자로 생성</del>하지 못함</li>
</ul>
<h4 id="메소드">메소드</h4>
<ul>
<li>필드를 읽고 수정하는 역할</li>
<li>다른 객체를 생성해서 다양한 기능을 수행</li>
<li>객체 간의 데이터 전달의 수단으로 사용</li>
<li>외부로부터 매개값을 받을 수 있으며, 실행 후 어떤 값을 리턴할 수 있음</li>
</ul>
<h3 id="정적-멤버와-static">정적 멤버와 static</h3>
<ul>
<li>정적 멤버는 클래스에 <strong>고정된</strong> 멤버로서 <del>객체를 생성하지</del> 않고 사용할 수 있는 필드와 메소드</li>
<li>정적 필드와 정적 메소드를 선언하는 방법은 선언 시 <code>static</code> 키워드를 추가</li>
</ul>
<pre><code class="language-java">public class ClassName {
    // 정적 필드
    static 타입 필드 [= 초기값];

    // 정적 메소드
    static 리턴 타입 메소드( 매개변수 선언, ··· ) { ··· }
}</code></pre>
<ul>
<li>클래스 로더가 클래스를 로딩해서 메소드 메모리 영역에 적재할 때 클래스별로 관리하므로, 클래스의 로딩이 끝나면 바로 <strong>사용 할 수 있음</strong></li>
<li>정적 필드는 다음과 같이 필드 선언과 동시에 초기값을 주는 것이 보통</li>
</ul>
<pre><code class="language-java">static double pi = 3.141592;</code></pre>
<ul>
<li>일반적으로 필드는 생성자에서 초기화하지만, <strong>정적 필드</strong>는 <del>객체 생성</del> 없이도 <strong>사용해야 하므로 <del>생성자에서 초기화 작업을</del> 할 수 없음</strong></li>
<li>정적 필드의 복잡한 초기화 작업을 위해서는 <strong>정적 블록(static block)</strong>을 사용</li>
</ul>
<pre><code class="language-java">static {
   ···
}</code></pre>
<h3 id="싱글톤">싱글톤</h3>
<p><strong>전체 프로그램에서 단 하나의 객체만 만들도록 보장해야하고 공유</strong>토록 하기위해 <code>싱글톤(Singleton)</code>객체를 사용함</p>
<ul>
<li>외부에서 <code>new</code>연산자로 생성자를 <del>호출할 수 없도록</del> 만들어야 함</li>
<li>생성자 앞에 <code>private</code>접근 제한자를 붙여주면 외부에서 <del>접근하지</del> 못함</li>
<li>자신의 타입인 정적 필드를 하나 선언하고 자신의 객체를 생성해 초기화</li>
<li>외부에서 호출할 수 있는 정적 메소드인 <code>getInstance()</code>를 선언하고 정적 필드에서 참조하고 있는 자신의 객체를 리턴</li>
</ul>
<pre><code class="language-java">public class ClassName {
    //정적 필드
    private static ClassName singleton = new ClassName();

    // 생성자
    private ClassName {}

    // 정적 메소드
    static ClassName getInstance() {
        return singleton;
    }
}
</code></pre>
<ul>
<li><strong>외부에서 객체를 얻는 유일한 방법</strong>은 getInstance() 메소드를 호출하는 방법</li>
</ul>
<pre><code class="language-java">ClassName sgt1 = ClassName.getInstance();
ClassName sgt2 = ClassName.getInstance();</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 배열(Array)]]></title>
            <link>https://velog.io/@3rd-big/JAVA-%EB%B0%B0%EC%97%B4Array</link>
            <guid>https://velog.io/@3rd-big/JAVA-%EB%B0%B0%EC%97%B4Array</guid>
            <pubDate>Sat, 13 Mar 2021 11:31:10 GMT</pubDate>
            <description><![CDATA[<h2 id="배열-메모리-구조">배열 메모리 구조</h2>
<p>배열 변수는 참조 변수에 속함
배열도 객체이므로 힙 영역에 생성
배열 변수는 힙 영역의 배열 객체를 참조하게 됨</p>
<ul>
<li><p>1차원 배열 메모리구조</p>
<pre><code class="language-java">int[] intArray = new int[5];</code></pre>
<p><img src="https://images.velog.io/images/3rd-big/post/ef8d2ec2-4bb6-4373-a203-4c3de125f89b/Untitled%20Diagram.png" alt=""></p>
</li>
<li><p>2차원 배열 메모리구조</p>
<pre><code class="language-java">int[][] scores = {{1, 2}, {3, 4, 5}};</code></pre>
<p><img src="https://images.velog.io/images/3rd-big/post/eebae583-ca2d-4225-9a6e-c3076812cf40/Untitled%20Diagram%20(2).png" alt=""></p>
</li>
</ul>
<h2 id="배열-선언-및-초기화">배열 선언 및 초기화</h2>
<ul>
<li><p>값 목록</p>
</li>
<li><p><strong><code>new</code></strong> 연산자를 사용</p>
</li>
<li><p>배열 변수를 미리 선언한 후 <strong><code>new</code></strong> 연산자를 사용해서 값 목록을 지정</p>
<pre><code class="language-java">public class Blog {
    public static void main(String[] args) {
        // 1차원 배열
        int[] arr = {0, 1, 2, 3, 4};
        int[] arr2;
        arr2 = new int[5];
        int[] arr3;
        arr3 = new int[]{0, 1, 2, 3, 4};

        // 다차원 배열
        int[][] arr4 = {{0, 1}, {2, 3, 4}};
        int[][] arr5;
        arr5 = new int[2][3];
        // int[][] arr6 = new int[필수입력][];
    }
}</code></pre>
<blockquote>
<p>이런 형태의 배열에서 <strong>주의할 점</strong>은 정확한 배열의 길이를 알고 인덱스를 사용해야 함
<strong><code>arr4[0][2]</code></strong> 는 <em><strong>ArrayIndexOutOfBoundsException</strong></em> 을 발생시킴</p>
</blockquote>
</li>
</ul>
<br>

<ul>
<li>값의 목록으로 배열 객체를 생성할 때 주의할 사항은 <strong>배열 변수를 이미 선언한 후에 다른 실행문에서 중괄호를 사용한 배열 생성은 허용되지 않음</strong><pre><code class="language-java">int add(int[] scores) {···}
-----------------------------
int result  = add( {95, 85, 90} ); // 컴파일 에러
int result2 = add( new int[] {95, 85, 90} );</code></pre>
</li>
</ul>
<br>

<h2 id="객체를-참조하는-배열">객체를 참조하는 배열</h2>
<ul>
<li>기본 타입(byte, int, double, boolean 등.. ) 배열은 각 항목에 직접 값을 가짐</li>
<li><strong>참조 타입(클래스, 인터페이스) 배열은 각 항목에 객체의 번지를 가짐</strong><ul>
<li>String[] 배열의 항목도 결국 String 변수와 동일하게 취급되어야 함</li>
<li>String[]배열 항목 간에 문자열을 비교하기 위해서는 <strong><code>==</code></strong> 연산자 대신 <strong><code>equals()</code></strong> 메소드를 사용해야 함 ( <strong><code>==</code></strong> 연산자는는 객체의 번지 비교이기 때문에 문자열 비교에 사용할 수 없음 )</li>
</ul>
</li>
</ul>
<pre><code class="language-java">public class Blog {
    public static void main(String[] args) {
        String[] strArray = new String[3];
        strArray[0] = &quot;Java&quot;;
        strArray[1] = &quot;Java&quot;;   // 문자열 리터럴이 같은 경우, 하나의 스트링 객체가 만들어짐
        strArray[2] = new String(&quot;Java&quot;);

        System.out.println( strArray[0] == strArray[1] );       // true  ( 같은 객체를 참조 )
        System.out.println( strArray[0] == strArray[2] );       // false ( 다른 객체를 참조 )
        System.out.println( strArray[0].equals(strArray[2]) );  // true  ( 문자열이 동일 )
    }
}</code></pre>
<p><img src="https://images.velog.io/images/3rd-big/post/8d0d7e46-0e46-4376-962c-a6a114f46bce/Untitled%20Diagram%20(3).png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] 20210202]]></title>
            <link>https://velog.io/@3rd-big/TIL-20210202</link>
            <guid>https://velog.io/@3rd-big/TIL-20210202</guid>
            <pubDate>Sat, 06 Mar 2021 05:31:05 GMT</pubDate>
            <description><![CDATA[<h2 id="devnull-21">/dev/null 2&gt;&amp;1</h2>
<p><strong><code>&gt;</code></strong> redirection</p>
<ul>
<li>해당 연산자를 이용해서 입력과 출력 방향을 표준 입력이나 표준 출력이 아닌 다른 것으로 재지정 가능</li>
<li>0  표준입력</li>
<li>1  표준출력</li>
<li>2  표준에러</li>
</ul>
<br>

<p>아래 사진에서 보듯이 에러가 출력되는 명령어를 a.txt 에 넣으려고 시도하면 <strong>표준 출력이 아니므로</strong> a.txt 에는 아무런 메시지가 없음<br>
<strong><code>\&gt;</code></strong> 앞에는 1(표준출력) 이 생략되어있음
<img src="https://images.velog.io/images/3rd-big/post/9ff3378b-7770-49d8-a8f5-50d4bce3800d/1.jpg" alt=""></p>
<p>아래 사진은 에러가 출력되는 명령어를 b.txt 에 넣으려고 시도하고 있으며, 이전 사진과는 다르게 <strong>표준에러(2) 를 b.txt 에 추가하라고 지시</strong>하고 있음
<img src="https://images.velog.io/images/3rd-big/post/ff0699f5-1eac-41c4-a08c-0fbefa323be1/2.jpg" alt=""></p>
<p>하지만, 언제 에러가 출력되는지 확신할 수 없고 로그파일에는 <strong>정상출력 및 에러출력을 같이 적어야 할 경우</strong>가 많음
표준출력과 표준에러를 하나의 파일(로그파일) 에 넣어야 할 경우 아래 사진과 같이 작성
<strong>표준 출력은 c.txt 에 넣고, 에러가 발생할 경우 첫 번째(c.txt) 파일에 삽입</strong>
<img src="https://images.velog.io/images/3rd-big/post/a597da5e-4eb9-4710-b44a-fb5cf714738a/3.jpg" alt=""></p>
<p>쓰레기 값(의미없는 에러 등)까지 로그로 쌓을 경우, 서버에 용량이 부족할 경우가 생기게 되므로 아래와 같이 <strong><code>/dev/null</code></strong> 에 출력을 버려주는게 실제 출력결과나 <strong>로그를 보기좋게 쌓을 수 있음</strong></p>
<pre><code class="language-bash">[root@localhost redirection]# ls tsseo &gt; /dev/null 2&gt;&amp;1</code></pre>
<br>

<h2 id="java-option">Java Option</h2>
<ul>
<li><p><em><strong>-DtestOption=VARIABLE</strong></em>
java 소스에서 System.getProperty(&quot;VARIAVLE&quot;) 코드에서 사용
쉘이나 자바실행 시 옵션을 주게되면 코드상에서 해당 변수를 사용 할 수 있음</p>
</li>
<li><p><em><strong>-Djava.net.preferIPv4Stack=TRUE</strong></em>
Java는 OS에서 IPv4와 IPv6가 모두 사용 가능할 경우, IPv6를 우선적으로 사용
해당 설정은 IPv4를 우선적으로 사용</p>
</li>
<li><p><em><strong>XX:MaxPermSize=64m</strong></em>
Java8 부터 사라진 옵션
<strong>Perm</strong> 영역은 <strong>Class의 Meta 정보, Method의 Meta 정보, Static변수와 상수 정보 저장되는 공간</strong>으로 흔히 메타데이터 저장 영역이라고 부름
Java8 부터 Native memory 영역으로 이동하여 Metaspace 영역으로 명명
Java8 의 <strong>-XX:MaxMetaspaceSize 를 두지 않는 이상, Native memory 자원을 최대한 사용</strong></p>
</li>
<li><p><em>*<em>-Djava.endorsed.dirs=/home/<del>/</del>/lib/endorsed -Xmx256m *</em></em>
외부 API를 JDK에서 내포한 경우, 최신의 외부 API 사용
JDK 에 있는 rt.jar 에 포함되어 있지만 외부 최신 API를 사용하고 싶을 경우 <strong><code>endorsed</code></strong> 디렉토리에 옮겨놓자</p>
<p>설치한 라이브러리들 간의 로딩순서는 classpath에 설정한 순서로 조절할 수 있지만(? 아직 이건 모름..) rt.jar는 설정 순서로 조절할 수 없음</p>
<blockquote>
<p><strong>참고 블로그</strong>
 <a href="https://blog.naver.com/PostView.nhn?blogId=iamadora&amp;logNo=221392912155">https://blog.naver.com/PostView.nhn?blogId=iamadora&amp;logNo=221392912155</a>
 <a href="https://blog.voidmainvoid.net/184">https://blog.voidmainvoid.net/184</a>
 <a href="http://egloos.zum.com/aploit/v/4806304">http://egloos.zum.com/aploit/v/4806304</a></p>
</blockquote>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[alternatives 를 사용한 jdk 버전관리]]></title>
            <link>https://velog.io/@3rd-big/alternatives-%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%9C-jdk-%EB%B2%84%EC%A0%84%EA%B4%80%EB%A6%AC</link>
            <guid>https://velog.io/@3rd-big/alternatives-%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%9C-jdk-%EB%B2%84%EC%A0%84%EA%B4%80%EB%A6%AC</guid>
            <pubDate>Fri, 05 Mar 2021 20:52:43 GMT</pubDate>
            <description><![CDATA[<h2 id="alternatives">alternatives?</h2>
<p>리눅스 시스템에서 <strong>여러 가지 버전의 패키지를 설치하여 사용</strong> 할 경우가 많음. 이럴 때 <strong><code>alternatives</code></strong> 커맨드라인 툴을 이용하여 여러 버전의 패키지를 관리하여 <strong>필요에 따라 유동적으로 원하는 버전 선택 가능</strong><br>alternatives는 심볼릭 링크를 생성, 제거, 관리, 조회 할 수 있는 기능을 제공하는 GNU 라이센스의 커맨드라인 툴<br><img src="https://images.velog.io/images/3rd-big/post/d1521f15-21e0-46a9-bb7b-0bbf17984a07/alternatives.png" alt=""></p>
<h2 id="사용법">사용법</h2>
<p>현재 alternatives 설정에는 jdk7, jdk8 가 설치되어 있음  </p>
<pre><code class="language-bash">[root@localhost java]# alternatives --config java</code></pre>
<p><img src="https://images.velog.io/images/3rd-big/post/9c197d28-fd2b-4034-9c94-aa50ceb42731/current_jdk.png" alt=""></p>
<p>심볼릭 링크 생성하기 ( jdk 11 설치과정 생략 )</p>
<pre><code class="language-bash">[root@localhost java]# alternatives --install /usr/bin/java java /usr/local/java/jdk-11.0.9/bin/java 1</code></pre>
<p><img src="https://images.velog.io/images/3rd-big/post/1ca31f2b-04ea-4e58-b57d-3974afd63a95/alternatives_link.png" alt=""></p>
<blockquote>
<p>Redhat 기준 alternatives 는 기본적으로 <strong><code>/etc/alternatives&lt;name&gt;</code></strong> 의 경로에 링크가 생성되고 priority, link, path 등 관련정보를 <strong><code>/var/lib/alternatives/&lt;name&gt;</code></strong>의 경로에 저장<br>
<strong>①</strong> -&gt; <strong>_&lt;link&gt;_</strong> : 심볼릭 링크의 경로
<strong>②</strong> -&gt; <em><strong>&lt;name&gt;</strong></em> : alternatives 에서 관리 할 심볼릭 링크 그룹명
<strong>③</strong> -&gt; <em><strong>&lt;path&gt;</strong></em> : 패키지의 절대 경로
<strong>④</strong> -&gt; <em><strong>&lt;priority&gt;</strong></em> : 링크 그룹 내에서 우선순위 지정. 정수로 입력하며 클 수록 우선순위</p>
</blockquote>
<p>설정 값을 확인하면 이전에는 등록되지 않았던 java 그룹 내 jdk11 버전 확인 가능하며 목록 내 자바 버전으로 수정 가능
<img src="https://images.velog.io/images/3rd-big/post/f130d822-0524-4685-8f65-cdb6ee36a877/Change_JDK.png" alt=""></p>
<p>JAVA_HOME 환경변수 설정을 위해 <strong><code>/etc/profile</code></strong> 파일을 열어 하단에 명령어 추가 후 변경사항 반영</p>
<pre><code class="language-bash">[root@localhost java]# vi /etc/profile</code></pre>
<pre><code class="language-vim"># add line
export JAVA_HOME=$(readlink -f /usr/bin/java) | sed &quot;s:bin/java::&quot;)</code></pre>
<pre><code class="language-bash">[root@localhost java]# . /etc/profile</code></pre>
<blockquote>
<p><strong><code>readlink -f</code></strong> 의 의미는 심볼릭 링크에서 원본파일을 추출하는 명령어
포스트 내용대로 진행했다면 <strong><code>readlink -f /usr/bin/java</code></strong> 명령어의 결과는 <strong><code>/usr/local/java/jdk-11.0.9/bin/java</code></strong> <br>
<strong><code>sed</code></strong> 는 유닉스에서 텍스트를 변환하기 위한 프로그램
<strong><code>s</code></strong> : 행마다 처음 검색된 텍스트를 원하는 텍스트로 바꿈
<strong><code>:</code></strong> : 토큰을 기준으로 bin/java 텍스트를 공백으로 치환
포스트 내용대로 진행했다면 <strong><code>JAVA_HOME</code></strong> 환경변수에 <strong><code>/usr/local/java/jdk-11.0.9/</code></strong> 텍스트 대입</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[SonarQube 소스코드 분석]]></title>
            <link>https://velog.io/@3rd-big/SonarQube-%EC%86%8C%EC%8A%A4%EC%BD%94%EB%93%9C-%EB%B6%84%EC%84%9D</link>
            <guid>https://velog.io/@3rd-big/SonarQube-%EC%86%8C%EC%8A%A4%EC%BD%94%EB%93%9C-%EB%B6%84%EC%84%9D</guid>
            <pubDate>Fri, 05 Mar 2021 20:37:13 GMT</pubDate>
            <description><![CDATA[<h2 id="sonarqube-소스코드-분석">SonarQube 소스코드 분석</h2>
<h3 id="1-프로젝트-생성">1. 프로젝트 생성</h3>
<p><strong>초기 기본 세팅</strong> 된 <em><strong>ID: admin, PW: admin</strong></em> 을 통해 로그인 후 프로젝트 생성 (Sonarqube 버전에 따라 UI는 달라질 수 있음)
<img src="https://images.velog.io/images/3rd-big/post/dd5f2d4d-e116-4133-8e4c-cf96a3ef0cda/create_project.png" alt=""></p>
<h3 id="2-분석방법-선택">2. 분석방법 선택</h3>
<p>순차적으로 Key, Token 을 생성 후 분석할 방법을 선택, 해당 매뉴얼은 Windows 환경의 SonarScanner 를 사용하여 분석진행
<img src="https://images.velog.io/images/3rd-big/post/badabb61-cbad-4054-a280-2193f9d9204b/Windows_sonarscanner.png" alt=""></p>
<h3 id="3-분석-진행과정">3. 분석 진행과정</h3>
<p>아래 사진의 <strong>1번 링크를 통해 SonarScanner 를 다운</strong>받아 환경변수를 설정하고, <strong>2번 내용을 복사</strong>하여 추후 분석할 소스코드의 경로에서 실행
<img src="https://images.velog.io/images/3rd-big/post/676936c6-00a5-44ce-8447-d4de2dd888d3/analysis_process.png" alt=""></p>
<h3 id="4-sonarscanner-설치-및-환경변수-설정">4. SonarScanner 설치 및 환경변수 설정</h3>
<p>압축해제 후 환경변수에 bin 디렉토리를 설정하여 <strong>어느 환경에서든 bin 디렉토리의 sonar-scanner.bat 파일을 실행 가능하게 설정</strong>
<img src="https://images.velog.io/images/3rd-big/post/0210dea1-0e68-4794-9ee0-926709621382/sonar-scannar-down.png" alt=""></p>
<p>다음과 같이 임의의 경로에서 sonar-scanner.bat 파일이 실행되면 세팅 완료(환경변수 설정은 windows 환경의 jdk 설정과 같음)
<img src="https://images.velog.io/images/3rd-big/post/bbb102f0-358e-4ff4-acf0-dec283fb13c2/sonar-scanner.png" alt=""></p>
<h3 id="5-소스코드-분석">5. 소스코드 분석</h3>
<p>분석할 소스코드의 프로젝트경로로 이동하는 방법은 Eclipse 기준으로 해당 프로젝트 우클릭 &gt; Properties 이후 해당버튼 클릭
<img src="https://images.velog.io/images/3rd-big/post/65bda805-19d0-408d-ac13-52cda07d2a74/eclipse-properties.png" alt=""></p>
<p>해당 프로젝트로 이동하여 아래 그림과 같이 폴더 경로를 복사
<img src="https://images.velog.io/images/3rd-big/post/adda5960-360c-4346-8cce-de9690e39fb0/project-pathcopy.png" alt=""></p>
<p>cmd 창에서 해당 프로젝트 경로로 이동 후, <strong><a href="#3-%EB%B6%84%EC%84%9D-%EC%A7%84%ED%96%89%EA%B3%BC%EC%A0%95">3. 분석 진행과정</a></strong> 에서 복사한 명령어를 실행
<img src="https://images.velog.io/images/3rd-big/post/240d4b3e-348b-4b44-afbb-881896e0e3c7/sonar-scanner-run.png" alt=""></p>
<blockquote>
<p><strong>Note</strong>
※ sonar-scanner.bat -D&quot;sonar.projectKey=FirstKey&quot; <em><strong><code>&gt;&gt; 프로젝트 생성 시 기입한 프로젝트 키</code></strong></em>
-D&quot;sonar.sources=. &quot; <strong><em><code>&gt;&gt; 현재경로의 내용을 분석</code></em></strong>
-D&quot;sonar.host.url=<a href="http://192.168.1.179:9000&quot;">http://192.168.1.179:9000&quot;</a> 　<em><strong><code>&gt;&gt; SonarQube 실행서버</code></strong></em>
-D＂sonar.login=78a60eb47c259d8930d5447812c9797e7004e2c2&quot; <em><strong><code>&gt;&gt; 프로젝트 생성 시 표시된 토큰값</code></strong></em></p>
</blockquote>
<p>분석 완료
<img src="https://images.velog.io/images/3rd-big/post/79113c93-4b3a-490e-adfb-e31ddacd0da4/analysis-complete.png" alt=""></p>
<h3 id="6-분석결과-확인">6. 분석결과 확인</h3>
<p><strong>87</strong>개의 버그, <strong>640</strong>개의 취약점, <strong>3037</strong>개의 <em>Code smell</em>, <strong>46.9%</strong>의 코드중복
<img src="https://images.velog.io/images/3rd-big/post/abe14cdf-1de4-464a-a5d9-cf2b1b425bad/analysis-complete2.png" alt=""></p>
<p>해당 분석 결과는 룰 설정을 하지않고 Default 로 세팅된 기준으로 분석한 결과이므로 <strong>정확한 분석은 분석하고자 하는 룰 설정 및 필터링 내역을 세팅 후 진행</strong>해야 함</p>
<p>상단의 Issues 에서 분석결과의 소스코드부분 확인가능
<img src="https://images.velog.io/images/3rd-big/post/7584d64c-3d45-446a-aaab-3967e9efa4d3/issues.png" alt=""></p>
<br>

<h2 id="분석-시-참고사항">분석 시 참고사항</h2>
<h3 id="sonar-projectproperties">sonar-project.properties</h3>
<p>소나큐브 분석 시 <strong>java 파일 1개만 생성 후 테스트 할 경우엔 해당 설정파일은 필요 없으나</strong>, 대부분의 소스분석은 여러 소스코드가 포함 된 프로젝트를 분석 할 경우가 대다수</p>
<p><strong>2개 이상의 소스코드</strong>가 포함 된 프로젝트를 분석 할 경우 아래와 같은 <strong>오류가 발생</strong>
<img src="https://images.velog.io/images/3rd-big/post/4fecb663-5aed-4ba2-9e0b-d6248772405a/analysis-error.png" alt=""></p>
<p>SonarScanner 다운로드 페이지 하단에 샘플 properties 를 사용하여 해결가능
<img src="https://images.velog.io/images/3rd-big/post/f85e19e7-6a76-45df-a70a-8b3610353110/properties.png" alt=""></p>
<pre><code class="language-properties"># must be unique in a given SonarQube instance 
sonar.projectKey=my:project 

# --- optional properties --- 

# defaults to project key 
#sonar.projectName=My project 
# defaults to &#39;not provided&#39; 
#sonar.projectVersion=1.0 

# Path is relative to the sonar-project.properties file. Defaults to . 
#sonar.sources=. 

# Encoding of the source code. Default is default system encoding 
#sonar.sourceEncoding=UTF-8</code></pre>
<p>properties 내용에는 <strong>자바소스코드가 컴파일되어 저장 된 위치</strong>를 알려줘야 함
properties 위치는 <strong>분석 할 프로젝트의 최상위경로에 저장</strong> 후 분석 실행
<img src="https://images.velog.io/images/3rd-big/post/2b24dd7f-a616-482c-9023-7c793bbe8e38/properties-content.png" alt=""></p>
<p>```properties</p>
<h1 id="must-be-unique-in-a-given-sonarqube-instance">must be unique in a given SonarQube instance</h1>
<p>sonar.java.binaries=bin</p>
<h1 id="----optional-properties----">--- optional properties ---</h1>
<h1 id="defaults-to-project-key">defaults to project key</h1>
<p>#sonar.projectName=My project</p>
<h1 id="defaults-to-not-provided">defaults to &#39;not provided&#39;</h1>
<p>#sonar.projectVersion=1.0</p>
<h1 id="path-is-relative-to-the-sonar-projectproperties-file-defaults-to-">Path is relative to the sonar-project.properties file. Defaults to .</h1>
<p>#sonar.sources=.</p>
<h1 id="encoding-of-the-source-code-default-is-default-system-encoding">Encoding of the source code. Default is default system encoding</h1>
<p>#sonar.sourceEncoding=UTF-8
``</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SonarQube 설치 및 실행]]></title>
            <link>https://velog.io/@3rd-big/SonarQube-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%8B%A4%ED%96%89</link>
            <guid>https://velog.io/@3rd-big/SonarQube-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%8B%A4%ED%96%89</guid>
            <pubDate>Fri, 05 Mar 2021 20:02:19 GMT</pubDate>
            <description><![CDATA[<h2 id="sonarqube">SonarQube?</h2>
<ul>
<li><p>SonarQube는 지속적인 인스펙션 패러다임을 지원하는 최상의 제품  </p>
</li>
<li><p>지속적인 코드 인스펙션은 소프트웨어 개발 라이프사이클의 완전한 부분으로 <strong>내부 소프트웨어 품질을 향상</strong> 시킬 수 있는 코드 품질 관리 패러다임  </p>
</li>
<li><p>지속적인 코드 품질 관리를 통해 <strong>개발 초기에 코드 문제를 해결하고 자동화된 코드 감사를 통해 최신 상태의 코드 문제를 확인</strong>할 수 있게 도와줌</p>
<blockquote>
<p><em><strong>CURVC, SonarQube 대표 파트너사</strong></em> &lt;2020.09.10 <strong><a href="https://confluence.curvc.com/display/ASD/SonarSource+Product">SonarQube</a></strong> 소개&gt;</p>
</blockquote>
</li>
</ul>
<br>

<h2 id="sonarqube-이용자-보안-강화-주의-권고">SonarQube 이용자 보안 강화 주의 권고</h2>
<ul>
<li><p>개요<br>최근 개발 SW 검증에 사용되는 SonarQube 서버에서 취약한 보안설정으로 인한 침해사고가 발생하고 있어 기관 및 기업 이용자들의 주의 당부  </p>
</li>
<li><p>설명<br>SonarQube 서버의 보안 설정 및 관리가 미흡한 경우 외부의 공격자가 기업, 기관 내부의 소스코드 저장소에 접근하여 소스코드 열람 및 민감정보 탈취  </p>
</li>
<li><p>대응 방안</p>
<ol>
<li>기본 설정 변경<ul>
<li>관리자 계정명, 패스워드, 포트(9000) 변경</li>
</ul>
</li>
<li>접근통제 강화<ul>
<li>보안장비(방화벽 등)를 SonarQube 인스턴스의 앞단에 구성</li>
<li>SonarQube 인스턴스에 접근할 수 있는 불필요한 자격증명(계정 등) 폐지<blockquote>
<p><strong><em>KISA,한국인터넷진흥원</em></strong> &lt;2020.10.29 <strong><a href="https://www.krcert.or.kr/data/secNoticeView.do?bulletin_writing_sequence=35746">SonarQube 이용자 보안 강화 주의 권고</a></strong>&gt;</p>
</blockquote>
</li>
</ul>
</li>
</ol>
</li>
</ul>
<br>

<h2 id="sonarqube-설치">SonarQube 설치</h2>
<h3 id="sonarqube-설치파일-다운로드">SonarQube 설치파일 <a href="https://www.sonarqube.org/downloads/">다운로드</a></h3>
<ul>
<li>SonarQube 버전 별 요구하는 JDK 가 상이하므로 SonarQube 버전에 따른 Documentation 참고</li>
<li>최신이외 버전은 해당 링크 하단 <strong><code>Historical Downloads</code></strong> 영역 <strong><code>Show all versions</code></strong> 에서 확인 가능</li>
<li>해당 포스트는 7.9.x LTS 버전 기준으로 작성<blockquote>
<p><strong>Note</strong> 
<em>7.9 LTS 이후 버전은 JDK 11, 7.8 이하는 JDK 8 요구</em></p>
</blockquote>
</li>
</ul>
<h3 id="1-centos-7-기준-설치">1. CentOS 7 기준 설치</h3>
<pre><code class="language-bash">[root@localhost opt]# cd /opt
[root@localhost opt]# wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-7.9.5.zip
[root@localhost opt]# unzip ./sonarqube-7.9.5.zip</code></pre>
<p><img src="https://images.velog.io/images/3rd-big/post/a8f549da-be52-4bb3-803c-afad520abd2b/linux_install.png" alt=""></p>
<h3 id="2-windows-10-기준-설치">2. Windows 10 기준 설치</h3>
<p><img src="https://images.velog.io/images/3rd-big/post/80042248-ec64-413c-85bf-15c9697bd000/windows_install.png" alt="">
<br></p>
<h2 id="sonarqube-실행">SonarQube 실행</h2>
<h3 id="1-centos-7-기준">1. CentOS 7 기준</h3>
<h4 id="11-계정생성-및-권한변경">1.1 계정생성 및 권한변경</h4>
<p>root 권한으로 SonarQube 실행이 불가하므로 사용자 추가 필요</p>
<pre><code class="language-bash">[root@localhost opt]# useradd sonarqube</code></pre>
<p>압축 해제한 디렉토리의 소유자와 소유그룹 변경</p>
<pre><code class="language-bash">[root@localhost opt]# chown -R sonarqube:sonarqube sonarqube-7.9.5</code></pre>
<p>sonarqube 계정으로 변경</p>
<pre><code class="language-bash">[root@localhost opt]# su sonarqube
[sonarqube@localhost opt]$</code></pre>
<br>

<h4 id="12-sonarqube-실행">1.2 SonarQube 실행</h4>
<p>아래와 같은 에러가 발생 할 경우 <strong><code>jdk 11</code></strong> 이상으로 변경 필요</p>
<pre><code class="language-bash">[sonarqube@localhost opt]$ cd /opt/sonarqube-7.9.5/bin/linux-x86-64
[sonarqube@localhost linux-x86-64]$ ./sonar.sh console</code></pre>
<p><img src="https://images.velog.io/images/3rd-big/post/49349212-565d-4d46-aaf2-e1ffc285da23/run_error.png" alt="">
설치 과정에서 언급했듯이 <strong><code>SonarQube 7.9 LTS</code></strong> 이후 버전은 <strong><code>Java (Oracle JRE 11 or OpenJDK11)</code></strong> 버전 필요</p>
<blockquote>
<p>SonarQube 버전 별 jdk 요구사항 <strong><a href="https://docs.sonarqube.org/7.9/requirements/requirements/">링크</a></strong>
jdk 버전관리 포스트 **<a href="https://velog.io/@3rd-big/alternatives-%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%9C-jdk-%EB%B2%84%EC%A0%84%EA%B4%80%EB%A6%AC">링크</a> **</p>
</blockquote>
<br>

<h3 id="2-windows-10-기준">2. Windows 10 기준</h3>
<h4 id="21-sonarqube-서비스-등록">2.1 SonarQube 서비스 등록</h4>
<p>Windows 환경에서 SonarQube는 tomcat web server 를 사용하여 웹 상에서 동작하게 되어 있으므로 압축 해제한 폴더 내에 있는 배치파일로 서비스를 등록해야 함</p>
<p>압축 해제한 폴더로 이동 후 bin 폴더의 windows-x86-64폴더 (os 별 폴더가 분류되어 있음)로 이동
<img src="https://images.velog.io/images/3rd-big/post/fe7d77b3-563b-462c-b7b7-72e02661cf8d/windows_folder.png" alt="">
파일 &gt; Windows PowerShell 열기 &gt; <strong><code>관리자 권한</code></strong>으로 Windows PoserShell 열기
<img src="https://images.velog.io/images/3rd-big/post/2df4ee1c-e737-442d-94c1-eb29a524e10e/open_powershell.png" alt="">
<strong><code>ls</code></strong> 명령어로 폴더 내 SonarQube 관련 배치파일 확인
<img src="https://images.velog.io/images/3rd-big/post/cad9706d-aa98-47aa-a9e7-762c65f53eda/powershell_batch.png" alt=""></p>
<blockquote>
<p><em><strong>InstallNTService.bat</strong></em> : 서비스를 설치하는 배치 파일
<em><strong>StartNTService.bat</strong></em> : 서비스를 실행하기 위한 배치 파일
<em><strong>StartSonar.bat</strong></em> : 소나큐브를 실행하기 위한 배치 파일
<em><strong>StopNTService.bat</strong></em> : 소나큐브의 서비스를 종료하는 배치 파일
<em><strong>UninstallNTservice.bat</strong></em> : 소나큐브 서비스를 제거하는 배치 파일</p>
</blockquote>
<p>InstallNTService.bat &gt; StartNTService.bat 순서로 실행하여 소나큐브 등록</p>
<pre><code class="language-PowerShell">PS C:\sonarqube-7.9.5\sonarqube-7.9.5\bin\windows-x86-64&gt; .\InstallNTService.bat
PS C:\sonarqube-7.9.5\sonarqube-7.9.5\bin\windows-x86-64&gt; .\StartNTService.bat</code></pre>
<p><strong><code>Window Key + R</code></strong> 을 눌러 실행 된 실행창에서 <strong><code>services.msc</code></strong> 입력
<img src="https://images.velog.io/images/3rd-big/post/54af6df8-8c90-4b82-bf35-777690f2d932/services.png" alt=""></p>
<p>윈도우 서비스관리에서 SoarQube 서비스 등록여부 확인
<img src="https://images.velog.io/images/3rd-big/post/457c9318-eee6-4860-a6ce-a8ee6a7f4a24/service.png" alt=""></p>
<br>

<h4 id="22-sonarqube-서비스-실행">2.2 SonarQube 서비스 실행</h4>
<p>StartSonar.bat 실행
<img src="https://images.velog.io/images/3rd-big/post/26b0670c-b898-421c-aeb8-be75afba1813/sonarqube_start.png" alt=""></p>
<p><strong><code>localhost:9000</code></strong> or <strong><code>127.0.0.1:9000</code></strong> 주소로 접속
<img src="https://images.velog.io/images/3rd-big/post/b5ca0a80-f758-4e76-9d4a-d4e844baeade/connect.png" alt=""></p>
]]></description>
        </item>
    </channel>
</rss>