<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>temp</title>
    <link>https://mingood.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sun, 10 May 2026 05:41:28 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>mnm11</managingEditor>
    <item>
      <title>토스뱅크 Tech 직군 경력 채용</title>
      <link>https://mingood.tistory.com/26</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot; data-filename=&quot;토스뱅크 경력채용_01.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjNJU7/btq9uBXWzfP/GM6sb2kqQsqLsr8cvc5jek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjNJU7/btq9uBXWzfP/GM6sb2kqQsqLsr8cvc5jek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjNJU7/btq9uBXWzfP/GM6sb2kqQsqLsr8cvc5jek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjNJU7%2Fbtq9uBXWzfP%2FGM6sb2kqQsqLsr8cvc5jek%2Fimg.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot; data-filename=&quot;토스뱅크 경력채용_01.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f8f8f8; color: #1d1c1d;&quot;&gt;토스뱅크 Tech 직군 경력채용, 출범 전 합류할 마지막 기회&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #f8f8f8; color: #1d1c1d;&quot;&gt;올가을 출범을 앞둔 토스뱅크. &amp;lsquo;고객 중심&amp;rsquo;이라는 핵심 가치와 기술 혁신을 통해 아무도 상상하지 못했던 은행을 꿈꿉니다. 2015년 토스가 송금에 새로운 정의를 내렸듯, 이제 은행에 새로운 정의를 내리려 합니다. 이 두근거리고 멋진 도전을 함께할 분들을 기다립니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #f8f8f8; color: #1d1c1d;&quot;&gt;토스뱅크는 사업 성장의 과실을 모든 멤버와 함께 나눠야 한다고 생각합니다. 이번에 합류하는 멤버에게도 기존 팀원과 차등 없이, 스톡옵션 또는 사이닝 보너스를 드립니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #f8f8f8; color: #1d1c1d;&quot;&gt;인터넷 전문 은행을 향한 관심이 뜨거운 지금, 시장은 토스뱅크를 주목하고 있습니다. 이번 채용은 토스뱅크의 시작부터 함께할 수 있는 마지막 기회입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #f8f8f8; color: #1d1c1d;&quot;&gt;이번 경력채용 지원하시고 토스뱅크의 초기 멤버가 되어보세요!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #f8f8f8; color: #1d1c1d;&quot;&gt;링크 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://recruit.tossbank.com&quot;&gt;https://recruit.tossbank.com&lt;/a&gt;&lt;/p&gt;</description>
      <author>mnm11</author>
      <guid isPermaLink="true">https://mingood.tistory.com/26</guid>
      <comments>https://mingood.tistory.com/26#entry26comment</comments>
      <pubDate>Tue, 13 Jul 2021 00:08:22 +0900</pubDate>
    </item>
    <item>
      <title>GitFlow_Apply</title>
      <link>https://mingood.tistory.com/25</link>
      <description>&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 637px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99085E355BE81E732D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99085E355BE81E732D&quot; width=&quot;637&quot; height=&quot;716&quot; filename=&quot;gitflow_mailsender.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <author>mnm11</author>
      <guid isPermaLink="true">https://mingood.tistory.com/25</guid>
      <comments>https://mingood.tistory.com/25#entry25comment</comments>
      <pubDate>Sun, 11 Nov 2018 21:20:33 +0900</pubDate>
    </item>
    <item>
      <title>Reflection class</title>
      <link>https://mingood.tistory.com/23</link>
      <description>&lt;link rel=&quot;stylesheet&quot; href=&quot;https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css&quot; integrity=&quot;sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4&quot; crossorigin=&quot;anonymous&quot;&gt;

&lt;div class=&quot;stackedit__html&quot;&gt;&lt;h1 id=&quot;reflection-관련-클래스들&quot;&gt;Reflection 관련 클래스들&lt;/h1&gt;
&lt;h2 id=&quot;class-클래스&quot;&gt;Class 클래스&lt;/h2&gt;

&lt;table class=&quot;table&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;메소드 이름&lt;/th&gt;
&lt;th&gt;내용&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;String getName()&lt;/td&gt;
&lt;td&gt;클래스의 이름을 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Package getPackage()&lt;/td&gt;
&lt;td&gt;클래스의 패키지 정보를 패키지 클래스 타입으로 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Field[] getFields()&lt;/td&gt;
&lt;td&gt;public으로 선언된 변수 목록을 Field 클래스 배열 타입으로 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Field getField(String name)&lt;/td&gt;
&lt;td&gt;public으로 선언된 변수를 Field 클래스 타입으로 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Field[] getDeclaredFields()&lt;/td&gt;
&lt;td&gt;해당 클래스에서 정의된 변수 목록을 Field 클래스 배열 타입으로 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Field[] getDeclaredFiled(String name)&lt;/td&gt;
&lt;td&gt;name과 동일한 이름으로 정의된 변수를 Field 클래스 타입으로 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Method[] getMethods()&lt;/td&gt;
&lt;td&gt;public으로 선언된 모든 메소드 목록을 Method 클래스 타입으로 리턴합니다. 해당 클래스에서 사용 가능한 상속받은 메소드도 포함됩니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Method getMethod(String name, Class… parameterTypes)&lt;/td&gt;
&lt;td&gt;지정된 이름과 매개변수 타입을 갖는 메소드를 Method 클래스 타입으로 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Method[] getDeclaredMethods()&lt;/td&gt;
&lt;td&gt;해당 클래스에서 선언된 모든 메소드 정보를 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Method getDeclaredMethod(String name, Class… parameterTypes)&lt;/td&gt;
&lt;td&gt;지정된 이름과 매개변수 타입을 갖는 해당 클래스에서 선언된 메소드를 Method 클래스 타입으로 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Constructor[] getConstructors()&lt;/td&gt;
&lt;td&gt;해당 클래스에 선언된 모든 public 생성자의 정보를 Constructor 배열 타입으로 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Constructor[] getDeclaredConstructors()&lt;/td&gt;
&lt;td&gt;해당 클래스에 선언된 모든 생성자의 정보를 Constructor 배열 타입으로 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;int getModifiers()&lt;/td&gt;
&lt;td&gt;해당 클래스의 접근자(modifier) 정보를 int 타입으로 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;String toString()&lt;/td&gt;
&lt;td&gt;해당 클래스 객체를 문자열로 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;ul&gt;
&lt;li&gt;현재 클래스의 이름이 알고 싶다면 다음과 같이 사용하면 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;[ 패키지 정보까지 포함 ]  
String currentClassName = this.getClass().getName();  
  
[ 클래스 이름만 필요한 경우 ]  
String currentClassName = this.getClass().getSimpleName();  
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;method-클래스&quot;&gt;Method 클래스&lt;/h2&gt;

&lt;table class=&quot;table&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;메소드 이름&lt;/th&gt;
&lt;th&gt;내용&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Class&amp;lt;?&amp;gt; getDeclaredClass()&lt;/td&gt;
&lt;td&gt;해당 메소드가 선언된 클래스 정보를 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Class&amp;lt;?&amp;gt; getReturnType()&lt;/td&gt;
&lt;td&gt;해당 메소드의 리턴 타입을 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Class&amp;lt;?&amp;gt;[] getParameterTypes()&lt;/td&gt;
&lt;td&gt;해당 메소드를 사용하기 위한 매개변수의 타입들을 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;String getName()&lt;/td&gt;
&lt;td&gt;해당 메소드의 이름을 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;int getModifiers()&lt;/td&gt;
&lt;td&gt;해당 메소드의 접근자 정보를 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Class&amp;lt;?&amp;gt;[] getExceptionTypes()&lt;/td&gt;
&lt;td&gt;해당 메소드에 정의되어 있는 예외 타입들을 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Object invoke(Object obj, Object… args)&lt;/td&gt;
&lt;td&gt;해당 메소드를 수행합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;String toGenericString()&lt;/td&gt;
&lt;td&gt;타입 매개변수를 포함한 해당 메소드의 정보를 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;String toString()&lt;/td&gt;
&lt;td&gt;해당 메소드의 정보를 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;h2 id=&quot;field-클래스&quot;&gt;Field 클래스&lt;/h2&gt;

&lt;table class=&quot;table&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;메소드 이름&lt;/th&gt;
&lt;th&gt;내용&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;int getModifiers()&lt;/td&gt;
&lt;td&gt;해당 변수의 접근자 정보를 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;String getName()&lt;/td&gt;
&lt;td&gt;해당 변수의 이름을 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;String toString()&lt;/td&gt;
&lt;td&gt;해당 변수의 정보를 리턴&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;h2 id=&quot;reflection-클래스-활용&quot;&gt;Reflection 클래스 활용&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;[ A 경우 ]  
public String checkClass(Object obj) {  
   if (obj.getClass().getName().equals(&quot;java.math.BigDecimal&quot;)) {
      ... 
   }
}  
  
[ B 경우 ]  
public String checkClass(Object obj) {  
   if (obj instanceof java.math.BigDecimal) { 
      ... 
   }
}  
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;reflection 클래스를 활용해야 한다면 A보다 B 경우를 사용하도록 하자. (성능상 B 경우가 6배 빠릅니다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;추가적으로, 클래스의 메타 데이터 정보는 JVM의 Perm 영역에 저장됩니다. 만약 Class 클래스를 사용하여 많은 클래스를 동적으로 생성하는 일이 벌어지면
Perm 영역이 더 이상 사용할 수 없게 되어 OutofMemoryError가 발생할 수 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;</description>
      <category>Language/Java</category>
      <category>class</category>
      <category>Java</category>
      <category>Reflection</category>
      <author>mnm11</author>
      <guid isPermaLink="true">https://mingood.tistory.com/23</guid>
      <comments>https://mingood.tistory.com/23#entry23comment</comments>
      <pubDate>Fri, 1 Jun 2018 04:34:31 +0900</pubDate>
    </item>
    <item>
      <title>Synchronized</title>
      <link>https://mingood.tistory.com/22</link>
      <description>&lt;link rel=&quot;stylesheet&quot; href=&quot;https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css&quot; integrity=&quot;sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4&quot; crossorigin=&quot;anonymous&quot;&gt;

&lt;h1 id=&quot;synchronized-이해&quot;&gt;synchronized 이해&lt;/h1&gt;
&lt;p&gt;하나의 객체에 여러 요청이 동시에 들어오면 원하는 처리를 하지 못하고 이상한 결과가 나올 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;그래서 synchronized를 사용하여 동기화를 하는 것입니다.&lt;/li&gt;
&lt;li&gt;이 식별자를 사용하면 &quot;천천히 하나씩 들어오세요.&quot;라고 해당 메소드나 블럭에서 제어하게 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;*코드 예제&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public synchronized void sampleMethod() {  
   ...
}  
  
private Object obj = new Object();  
public void sampleBlock() {  
   synchronized(obj) {
      ...
   }
}  
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;위 처럼 간단히 synchronized라는 식별자만 사용하면 동기화할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;언제-동기화를-사용해야-할까-&quot;&gt;언제 동기화를 사용해야 할까 ?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;하나의 객체를 여러 스레드에서 동시에 사용할 경우&lt;/li&gt;
&lt;li&gt;static으로 선언한 객체를 여러 스레드에서 동시에 사용할 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;동일-객체-접근시&quot;&gt;동일 객체 접근시&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;public class Contribution {  
   private int amount = 0;
   public synchronized void donate() {
      amount++;
   }
   public int getTotal() {
      return amount;
   }
}  
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class Contribution extends Thread {  
   private Contribution myContribution;
   private String myName;     
   
   public Contributor(Contribution contrubution, String name) {  
      myContribution = contribution;
      myName = name;
   }     

   public void run() {  
      for (int loop = 0; loop &amp;lt; 1000; ++loop)
         myContribution.donate();
      System.out.format(&quot;%s total = %d\n&quot;, myName, myContribution.getTotal());
   }
}  
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class ContributeTest {  
   public static void main(String args[]) {
      Contributor[] crs = new Contributor[10];
      Contribution group = new Contribution();         
      
      // 기부자와 기부 단체 초기화  
      for (int loop = 0; loop &amp;lt; 10; ++loop) 
         crs[loop] = new Contributor(group, &quot; Contributor&quot; + loop);         

      // 기부 실행  
      for (int loop = 0; loop &amp;lt; 10; ++loop) 
         crs[loop].start(); 
   }
}  
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;static-사용시&quot;&gt;static 사용시&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;public class Contribution {  
   private static int amount = 0; 
   public static synchronized void donate() { 
      amount++; 
   } 
   public int getTotal() { 
      return amount; 
   }
}  
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class Contribution extends Thread {  
   private Contribution myContribution;
   private String myName;     

   public Contributor(Contribution contrubution, String name) {  
      myContribution = contribution; 
      myName = name; 
   }     

   public void run() {  
      for (int loop = 0; loop &amp;lt; 1000; ++loop) 
         myContribution.donate(); 
      System.out.format(&quot;%s total = %d\n&quot;, myName, myContribution.getTotal()); 
   }
}  
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;public class ContributeTest {  
   public static void main(String args[]) { 
      Contributor[] crs = new Contributor[10];         

      // 기부자와 기부 단체 초기화  
      for (int loop = 0; loop &amp;lt; 10; ++loop) { 
         Contribution group = new Contribution(); 
         crs[loop] = new Contributor(group, &quot; Contributor&quot; + loop); 
      }         
   
      // 기부 실행  
      for (int loop = 0; loop &amp;lt; 10; ++loop) 
         crs[loop].start(); 
   }
}  
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;amount를 static으로 선언하면 객체의 변수가 아닌 클래스의 변수가 됩니다.&lt;/li&gt;
&lt;li&gt;따라서, 각 단체에 따로 기부하는 것은 구현이 불가능합니다.&lt;/li&gt;
&lt;li&gt;synchronized는 각각의 객체에 대한 동기화를 하는 것이기 때문에, synchronized만 사용하면 amount에 대한 동기화는 되지 않습니다.&lt;/li&gt;
&lt;li&gt;그래서 static synchronized로 구현했지만, 항상 변하는 값(amount)에 대해서 static으로 선언하는 것은 굉장히 위험하다는 것을 알아두시면 좋겠습니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Language/Java</category>
      <category>Java</category>
      <category>synchronized</category>
      <category>동기화</category>
      <author>mnm11</author>
      <guid isPermaLink="true">https://mingood.tistory.com/22</guid>
      <comments>https://mingood.tistory.com/22#entry22comment</comments>
      <pubDate>Fri, 1 Jun 2018 04:28:55 +0900</pubDate>
    </item>
    <item>
      <title>Thread Class &amp;amp; Runnable Interface</title>
      <link>https://mingood.tistory.com/21</link>
      <description>&lt;link rel=&quot;stylesheet&quot; href=&quot;https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css&quot; integrity=&quot;sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4&quot; crossorigin=&quot;anonymous&quot;&gt;

&lt;h1 id=&quot;thread-클래스-상속과-runnable-인터페이스-구현&quot;&gt;Thread 클래스 상속과 Runnable 인터페이스 구현&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;스레드의 구현은 Thread 클래스를 상속받는 것과 Runnable 인터페이스를 구현하는 2가지 방법이 있습니다.&lt;/li&gt;
&lt;li&gt;Thread 클래스는 Runnable 인터페이스를 구현한 것이기 때문에 어느 것을 사용해도 상관은 없지만, Runnable 인터페이스를 구현하면 원하는 기능을 추가할 수 있습니다.
&lt;blockquote&gt;
&lt;p&gt;이것은 장점이 될 수도 있지만, 해당 클래스를 수행할 때 별도의 스레드 객체를 생성해야 한다는 단점이 있을 수 있습니다. 또한 자바는 다중 상속을 허락하지 않습니다.&lt;br /&gt;
따라서 스레드를 사용할 때 이미 상속받은 클래스가 있다면 Runnable 인터페이스를 구현해야 합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;Runnable 인터페이스를 구현한 클래스&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;public class RunnableImpl implements Runnable {  
   public void run() { 
      System.out.println(&quot;This is RunnableImpl.&quot;);
   }
}  
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Thread 클래스를 상속받아 구현한 클래스&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;public class ThreadExtends extends Thread {  
   public void run() {
      System.out.println(&quot;This is ThreadExtends.&quot;);
   }
}  
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;이-클래스들을-어떻게-실행해야-할까-&quot;&gt;이 클래스들을 어떻게 실행해야 할까 ?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Thread 클래스를 상속받은 경우에는 start() 메소드를 호출하면 실행&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Runnable 인터페이스를 구현한 경우에는 Thread 클래스의 Runnable 인터페이스를 매개변수로 받는 생성자를 사용해&lt;br /&gt;
Thread 클래스를 만든후 start() 메소드를 호출해야 합니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;실행 소스 코드&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;public class RunThreads {  
   public static void main(String[] args) { 
      RunnableImpl runnableImpl = new RunnableImpl();
      ThreadExtends threadExtends = new ThreadExtends();

      new Thread(runnableImpl).start();
      threadExtends.start();
   }
}  
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id=&quot;sleep-wait-join-메소드&quot;&gt;sleep(), wait(), join() 메소드&lt;/h2&gt;
&lt;p&gt;현재 진행 중인 스레드를 대기하도록 하기 위해서 위 3가지 메소드를 사용하는 방법이 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;위 3가지 메소드는 모두 예외를 던지도록 되어 있어 사용할 때는 반드시 예외 처리를 해줘야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;wait-메소드&quot;&gt;wait() 메소드&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;모든 클래스의 부모 클래스인 Object 클래스에 선언되어 있으므로 어떤 클래스에서든 사용할 수 있습니다.&lt;/li&gt;
&lt;li&gt;sleep()과 마찬가지로 명시된 시간만큼 해당 스레드를 대기시킵니다. sleep()과 다른 점은 매개변수인데, 만약 아무런 매개변수를 지정하지 않았다면&lt;br /&gt;
notify() 또는 notifyAll() 메소드가 호출될 때까지 대기합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;sleep-메소드&quot;&gt;sleep() 메소드&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;명시된 시간만큼 해당 스레드를 대기시킵니다.
&lt;ul&gt;
&lt;li&gt;sleep(long millis) : 명시된 ms만큼 해당 스레드가 대기합니다. static 메소드이기 때문에 스레드 객체를 통하지 않아도 사용할 수 있습니다.&lt;/li&gt;
&lt;li&gt;sleep(long millis, int nanos) : 명시된 ms + 명시된 나노 시간만큼 해당 스레드가 대기합니다. 여기서 나노 시간은 0~999999까지 사용할 수 있습니다. (이것도 마찬가지로 static)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;join-메소드&quot;&gt;join() 메소드&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;명시된 시간만큼 해당 스레드가 죽기를 기다립니다.&lt;/li&gt;
&lt;li&gt;아무런 매개변수를 지정하지 않으면 죽을 때까지 계속 대기합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;interrupt-notify-notifyall-메소드&quot;&gt;interrupt(), notify(), notifyAll() 메소드&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;isAlive()라는 메소드도 있는데, 이것은 해당 스레드가 살아있는지 확인하는 메소드입니다.
&lt;ul&gt;
&lt;li&gt;스레드가 살아있다면 true, 아니라면 false를 리턴합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;interrupt-메소드&quot;&gt;interrupt() 메소드&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;앞서 명시한 sleep(), wait(), join() 메소드를 모두 멈출 수 있는 유일한 메소드는 interrupt() 메소드입니다.
&lt;ul&gt;
&lt;li&gt;하지만 interrupt() 메소드가 절대적인 것은 아닙니다.&lt;/li&gt;
&lt;li&gt;간단하게 설명하자면, interrupt() 메소드는 해당 스레드가 block되거나 특정 상태에서만 작동합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;interrupt() 메소드가 호출되면 중지된 스레드는 InterruptedException이 발생합니다.&lt;/li&gt;
&lt;li&gt;제대로 수행되었는지 확인하려면 interrupted() 메소드를 호출하거나 isInterrupted() 메소드를 호출하면 됩니다.
&lt;ul&gt;
&lt;li&gt;interrupted() 메소드는 스레드의 상태를 변경시킵니다.&lt;/li&gt;
&lt;li&gt;isInterrupted() 메소드는 단지 스레드의 상태만을 리턴합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;notify-notifyall-메소드&quot;&gt;notify(), notifyAll() 메소드&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;위 두 메소드 모두 wait() 메소드를 멈추기 위한 메소드입니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;위 두 메소드는 Object 클래스에 정의되어 있는데, wait() 메소드가 호출된 후 대기 상태로 바뀐 스레드를 깨웁니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;notify() 메소드는 객체의 모니터와 관련 있는 단일 스레드를 깨웁니다.&lt;/li&gt;
&lt;li&gt;notifyAll() 메소드는 객체의 모니터와 관련 있는 모든 스레드를 깨웁니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;대기 메소드와 중단 메소드의 사용법&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;public class Sleep extends Thread {  
   public void run() {
      try { 
         Thread.sleep(10000);    // 10초간 대기한 후 종료합니다.
      } catch (InterruptedException e) { 
         System.out.println(&quot;Somebody stopped me.&quot;);
      } catch (Exception e) { 
         e.printStackTrace();
      }
   }

   public static void main(String args[]) {  
      Sleep sleep = new Sleep();
      sleep.start();  // 스레드를 시작합니다.
      
      try {  
         int count = 0;
         while (count &amp;lt; 5) {
            sleep.join(1000);   // 1초씩 기다립니다.
            count++;
            System.out.format(&quot;%d second waited\n&quot;, count);
         }
         if (sleep.isAlive()) {  // 스레드가 살아있는지 확인합니다.
            sleep.interrupt();
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}  
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Language/Java</category>
      <category>class</category>
      <category>Interface</category>
      <category>Java</category>
      <category>Runnable</category>
      <category>thread</category>
      <author>mnm11</author>
      <guid isPermaLink="true">https://mingood.tistory.com/21</guid>
      <comments>https://mingood.tistory.com/21#entry21comment</comments>
      <pubDate>Fri, 1 Jun 2018 04:12:03 +0900</pubDate>
    </item>
    <item>
      <title>Process &amp;amp; Thread</title>
      <link>https://mingood.tistory.com/20</link>
      <description>&lt;h1 id=&quot;프로세스와-스레드&quot;&gt;프로세스와 스레드&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;하나의 프로세스에는 여러 개의 스레드가 생성됩니다.
&lt;blockquote&gt;
&lt;p&gt;단일 스레드가 생성되어 종료될 수도 있고, 여러 개의 스레드가 생성되어 수행될 수도 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;그러므로, 프로세스와 스레드의 관계는 1:N 이라고 할 수 있습니다.&lt;/li&gt;
&lt;li&gt;스레드는 다른 말로 Lightweight Process(LWP)라고도 합니다.&lt;/li&gt;
&lt;li&gt;즉, 가벼운 프로세스이고, 프로세스에서 만들어 사용하는 메모리를 공유합니다.&lt;/li&gt;
&lt;li&gt;그래서 별개의 프로세스가 하나씩 뜨는 것보다 성능이나 자원 사용에 있어 많은 도움이 됩니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Language/Java</category>
      <category>Java</category>
      <category>Process</category>
      <category>thread</category>
      <category>스레드</category>
      <category>자바</category>
      <category>프로세스</category>
      <author>mnm11</author>
      <guid isPermaLink="true">https://mingood.tistory.com/20</guid>
      <comments>https://mingood.tistory.com/20#entry20comment</comments>
      <pubDate>Fri, 1 Jun 2018 04:10:57 +0900</pubDate>
    </item>
    <item>
      <title>IO</title>
      <link>https://mingood.tistory.com/19</link>
      <description>&lt;link rel=&quot;stylesheet&quot; href=&quot;https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css&quot; integrity=&quot;sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4&quot; crossorigin=&quot;anonymous&quot;&gt;

&lt;h1 id=&quot;기본적인-io-처리&quot;&gt;기본적인 IO 처리&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;자바에서 입력과 출력은 stream을 통해서 이루어집니다.&lt;/li&gt;
&lt;li&gt;일반적으로 IO라고 하면 파일IO만을 생각할 수 있는데, 어떤 디바이스를 통해 이뤄지는 작업을 모두 IO라고 합니다.
&lt;ul&gt;
&lt;li&gt;네트워크를 통해서 다른 서버로 데이터를 전송하거나&lt;/li&gt;
&lt;li&gt;다른 서버로부터 데이터를 전송 받는 것도 IO에 포함됩니다.&lt;/li&gt;
&lt;li&gt;간단하게 콘솔에 출력하는 것도 stream을 통해서 출력하는 것입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;스트림을-읽는-데-관련된-주요-클래스는-다음과-같습니다.&quot;&gt;스트림을 읽는 데 관련된 주요 클래스는 다음과 같습니다.&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;스트림을 쓰는 데 관련된 클래스는 Input을 Output으로 바꾸면 됩니다.&lt;/li&gt;
&lt;li&gt;여기에 명시된 모든 입력과 관련된 스트림들을 java.io.InputStream 클래스로부터 상속받았습니다.&lt;/li&gt;
&lt;li&gt;바이트 기반의 스트림 입력을 처리하기 위해서는 이 클래스의 하위 클래스를 사용합니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;table class=&quot;table&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;이름&lt;/th&gt;
&lt;th&gt;내용&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ByteArrayInputStream&lt;/td&gt;
&lt;td&gt;바이트로 구성된 배열을 읽어서 입력 스트림을 만듭니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FileInputStream&lt;/td&gt;
&lt;td&gt;이미지와 같은 바이너리 기반의 파일의 스트림을 만듭니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FilterInputStream&lt;/td&gt;
&lt;td&gt;여러 종류의 유용한 입력 스트림의 추상 클래스입니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ObjectInputStream&lt;/td&gt;
&lt;td&gt;ObjectOutputStream을 통해서 저장해 놓은 객체를 읽기 위한 스트림을 만듭니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PipedInputStream&lt;/td&gt;
&lt;td&gt;PipedOutputStream을 통해서 출력된 스트림을 읽어 처리하기 위한 스트림을 만듭니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SequenceInputStream&lt;/td&gt;
&lt;td&gt;별개인 두 개의 스트림을 하나의 스트림으로 만듭니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;ul&gt;
&lt;li&gt;문자열 기반의 스트림을 읽기 위해서 사용하는 클래스는 java.io.Reader 클래스의 하위 클래스들입니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;table class=&quot;table&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;이름&lt;/th&gt;
&lt;th&gt;내용&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;BufferedReader&lt;/td&gt;
&lt;td&gt;문자열 입력 스트림을 버퍼에 담아서 처리합니다. 일반적으로 문자열 기반의 파일을 읽을 때 가장 많이 사용됩니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CharArrayReader&lt;/td&gt;
&lt;td&gt;char의 배열로 된 문자 배열을 처리합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FilterReader&lt;/td&gt;
&lt;td&gt;문자열 기반의 스트림을 처리하기 위한 추상 클래스입니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FileReader&lt;/td&gt;
&lt;td&gt;문자열 기반의 파일을 읽기 위한 클래스입니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;InputStreamReader&lt;/td&gt;
&lt;td&gt;바이트 기반의 스트림을 문자열 기반의 스트림으로 연결하는 역할을 수행합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PipedReader&lt;/td&gt;
&lt;td&gt;파이프 스트림을 읽습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StringReader&lt;/td&gt;
&lt;td&gt;문자열 기반의 소스를 읽습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;h3 id=&quot;정리&quot;&gt;정리&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;바이트 단위로 읽거나, 문자열 단위로 읽을 때 중요한 것은 한 번 open한 스트림은 반드시 닫아야 한다는 것이다.&lt;/li&gt;
&lt;li&gt;스트림을 닫지 않으면 나중에 리소스가 부족해질 수 있다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Language/Java</category>
      <category>iinput</category>
      <category>io</category>
      <category>Java</category>
      <category>output</category>
      <author>mnm11</author>
      <guid isPermaLink="true">https://mingood.tistory.com/19</guid>
      <comments>https://mingood.tistory.com/19#entry19comment</comments>
      <pubDate>Fri, 1 Jun 2018 04:08:20 +0900</pubDate>
    </item>
    <item>
      <title>Static</title>
      <link>https://mingood.tistory.com/18</link>
      <description>&lt;link rel=&quot;stylesheet&quot; href=&quot;https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css&quot; integrity=&quot;sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4&quot; crossorigin=&quot;anonymous&quot;&gt;

&lt;h1 id=&quot;static&quot;&gt;Static&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;자바 프로그래밍에서 성능을 향상시키는 방법은 여러가지가 있습니다.&lt;/li&gt;
&lt;li&gt;그 중에서 한가지는 static을 사용하는 것입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;static의-특징&quot;&gt;static의 특징&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;자바에서 static으로 지정했다면, 해당 메소드나 변수는 정적입니다. (반대말은 dynamic)&lt;/li&gt;
&lt;li&gt;static으로 선언한 변수는 클래스 변수입니다.&lt;/li&gt;
&lt;li&gt;하나의 JVM이나 WAS 인스턴스에서는 같은 주소에 존재하는 값을 참조합니다.&lt;/li&gt;
&lt;li&gt;GC의 대상이 되지 않습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;static-활용&quot;&gt;static 활용&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;자주 사용하고 절대 변하지 않는 변수는 final static으로 선언하자.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;설장 파일 정보도 static으로 관리하자.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;클래스의 객체를 생성할 때마다 설정 파일을 로딩하면 엄청난 성능 저하가 발생합니다. 이럴 때 반드시 static으로 데이터를 읽어서 관리해야 합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;코드성 데이터는 DB에서 한 번만 읽자.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;쇼핑몰의 상품 코드처럼 양이 많고 자주 바뀔 확률이 높은 데이터를 제외하고,&lt;br /&gt;
건수가 그리 많지 않되 조회 빈도가 높은 코드성 데이터는 DB에서 한 번만 읽어서 관리하는 것이 성능 측면에서 좋습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;static의-잘못된-활용-예제&quot;&gt;static의 잘못된 활용 예제&lt;/h2&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;import java.util.HashMap;  
  
public class BadQueryManager {  
     private static String queryURL = null;  
     public BadQueryManager(String badUrl) {
         queryURL = badUrl; 
     }

     public static String getSql(String idSql) {  
         try {
            FileReader reader = new FileReader();
            HashMap&amp;lt;String, String&amp;gt; doc = reader.read(queryURL);
            return doc.get(idSql);
         } catch (Exception e) { 
            System.out.println(e);
         } 
         return null;
     }
}  
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;queryURL 이라는 문자열을 static으로 지정했습니다.&lt;/li&gt;
&lt;li&gt;문자열이 있는 생성자로 이 클래스 객체를 생성하면 쿼리 파일이 지정됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;어떤 사용자가 BadQueryManager의 생성자를 통해 queryURL을 설정하고 getSql() 메소드를 호출 하기 전, 다른 queryURL을 사용하는 사용자의 스레드에서 BadQueryManager의 생성자를 호출하면 어떻게 될까 ?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;먼저 호출한 사용자는 생성자를 호출했을 때의 URL을 유지하고 있을 거라고 생각하고 getSql() 메소드를 호출하겠지만, 이미 그 값은 변경되고 난 이후입니다. 그러므로 시스템 오류가 발생합니다.&lt;/li&gt;
&lt;li&gt;getSql() 메소드와 queryURL을 static으로 선언한 것이 잘못된 부분입니다.&lt;/li&gt;
&lt;li&gt;웹 환경이기 때문에 여러 사용자가 호출할 경우 queryURL은 그때 그때 변경됩니다.&lt;/li&gt;
&lt;li&gt;다시 말하면, queryURL은 static으로 선언됐기 떄문에 클래스의 변수이지 객체의 변수가 아닙니다.&lt;/li&gt;
&lt;li&gt;모든 스레드에서 동일한 주소를 가리키게 되어 문제가 발생한 것입니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Language/Java</category>
      <category>Java</category>
      <category>static</category>
      <category>스태틱</category>
      <category>정적</category>
      <author>mnm11</author>
      <guid isPermaLink="true">https://mingood.tistory.com/18</guid>
      <comments>https://mingood.tistory.com/18#entry18comment</comments>
      <pubDate>Fri, 1 Jun 2018 04:06:19 +0900</pubDate>
    </item>
    <item>
      <title>System Class</title>
      <link>https://mingood.tistory.com/17</link>
      <description>&lt;h1 id=&quot;java-system-클래스&quot;&gt;Java System 클래스&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;모든 System 클래스의 메소드는 static으로 되어 있습니다.&lt;/li&gt;
&lt;li&gt;그 안에서 생성된 in, out, err과 같은 객체들도 static입니다.&lt;/li&gt;
&lt;li&gt;생성자(Constructor)도 없습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;결론적으로, 우리는 System 객체를 생성할 수 없으며,&lt;br /&gt;&lt;br /&gt;
System.XXX와 같은 방식을 사용해야 합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;알아두면-유용한-system-클래스-메소드&quot;&gt;알아두면 유용한 System 클래스 메소드&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;특정 배열을 복사할 때 사용합니다.&lt;br /&gt;&lt;br /&gt;
src: 복사 원본 배열&lt;br /&gt;&lt;br /&gt;
dest: 복사한 값이 들어갈 배열&lt;br /&gt;&lt;br /&gt;
srcPos: 원본의 시작 위치&lt;br /&gt;&lt;br /&gt;
destPos: 복사본의 시작 위치&lt;br /&gt;&lt;br /&gt;
length: 복사하는 개수&lt;br /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;절대로-사용해서는-안되는-코드&quot;&gt;절대로 사용해서는 안되는 코드&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;static void gc()&lt;/li&gt;
&lt;li&gt;static void exit(int status)&lt;/li&gt;
&lt;li&gt;static void runFinalization()&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Language/Java</category>
      <category>class</category>
      <category>Java</category>
      <category>System</category>
      <category>시스템</category>
      <category>클래스</category>
      <author>mnm11</author>
      <guid isPermaLink="true">https://mingood.tistory.com/17</guid>
      <comments>https://mingood.tistory.com/17#entry17comment</comments>
      <pubDate>Fri, 1 Jun 2018 04:05:26 +0900</pubDate>
    </item>
    <item>
      <title>웹 서비스를 확장하기 위해 알아야 할 것</title>
      <link>https://mingood.tistory.com/16</link>
      <description>&lt;h2 id=&quot;대규모-서비스의-특성&quot;&gt;대규모 서비스의 특성&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Elastic : 트래픽이나 상황에 따라서 서버의 추가 / 제거가 쉬워야 합니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Resiliency : 특정 장비의 장애 등은 자동으로 복구되어야 합니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;서버가 복구되는 것은 아닙니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;해당 장비의 장애로 인해 다른 쪽이 영향 받지 않아야 합니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Scale Up : 초당 1000 TPS 처리가 가능했다가 초당 3000 TPS 처리를 감당해야 한다면 3배(3000 TPS) 처리가 가능한 서버 1대로 교체 투입합니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Scale Out : 초당 1000 TPS 처리가 가능한 서버를 3대 투입합니다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;spof-single-point-of-failure-을-방지해야-합니다.&quot;&gt;SPOF (Single Point Of Failure) 을 방지해야 합니다.&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;장애가 나면 서비스 전체를 마비시키는 병목 지점&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99B6D5345AF9D18F0E&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99B6D5345AF9D18F0E&quot; width=&quot;820&quot; height=&quot;459&quot; filename=&quot;1.PNG&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99A3B7345AF9D19D10&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99A3B7345AF9D19D10&quot; width=&quot;820&quot; height=&quot;459&quot; filename=&quot;2.PNG&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;어디를-확장해야-할까&quot;&gt;어디를 확장해야 할까?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;API 서버에만 부하가 몰리는 작업은 어떤 것들이 있을까&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;파일 IO가 많은, 정적 파일 Serving&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;웹 스크래핑과 같은 DB 작업 자체보다는 다른 작업이 많은 녀석들&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;독립적인 작업이 가능하지만 CPU나 다른 작업이 많이 필요한 게임 서버&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이미지의 영상 인식&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DB 서버의 경우&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;카톡방의 대화&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;페이스북의 글, 댓글, 친구 관계&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;유튜브 등에 올라가는 비디오나 댓글&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;생각보다 우리가 아는 대부분이 DB 서버에 부하를 준다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;state--stateless&quot;&gt;State &amp;amp; Stateless&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99E0013C5AF9D1B310&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99E0013C5AF9D1B310&quot; width=&quot;820&quot; height=&quot;457&quot; filename=&quot;3.PNG&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/995B16385AF9D1C210&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F995B16385AF9D1C210&quot; width=&quot;820&quot; height=&quot;459&quot; filename=&quot;4.PNG&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;stateless-한-서버의-경우&quot;&gt;Stateless 한 서버의 경우&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;장점&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;추가 / 삭제가 간단하다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;사용하는 쪽에서 주소만 추가하거나 제거하는 걸로 가능&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Or LB에 추가하거나 제거하기만 하면 OK&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;단점&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;결국 데이터의 저장이 필요하므로 뒤에 책임을 떠넘기는 구조&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;개별 성능은 Stateful한 경우보다 떨어질 수 있음&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;그런데-왜-stateless-인가&quot;&gt;그런데 왜 Stateless 인가&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Stateless한 서버에 신경을 쓰지 말고 중요한 DB(Storage) 쪽에 집중을 하는게 더 좋다라는 판단.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;일반적인-db-서버의-부하&quot;&gt;일반적인 DB 서버의 부하&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99D499465AF9D1CC10&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99D499465AF9D1CC10&quot; width=&quot;820&quot; height=&quot;460&quot; filename=&quot;5.PNG&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99ECAB3D5AF9D1D615&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99ECAB3D5AF9D1D615&quot; width=&quot;820&quot; height=&quot;459&quot; filename=&quot;6.PNG&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이미지 출처 : 강대명님(CHARSYAM@naver.com)&amp;nbsp;발표 자료&lt;/p&gt;</description>
      <category>Web</category>
      <category>OUT</category>
      <category>Scale</category>
      <category>SPOF</category>
      <category>State</category>
      <category>stateless</category>
      <category>up</category>
      <category>web</category>
      <category>대규모</category>
      <category>부하</category>
      <category>서비스</category>
      <category>웹</category>
      <category>확장</category>
      <author>mnm11</author>
      <guid isPermaLink="true">https://mingood.tistory.com/16</guid>
      <comments>https://mingood.tistory.com/16#entry16comment</comments>
      <pubDate>Tue, 15 May 2018 03:16:33 +0900</pubDate>
    </item>
  </channel>
</rss>