<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>ptcman</title>
    <link>https://ptcman.tistory.com/</link>
    <description>한발 물러서서 나를 관찰하자</description>
    <language>ko</language>
    <pubDate>Thu, 13 Aug 2026 08:22:35 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>독서, 운동 그리고 개발</managingEditor>
    <image>
      <title>ptcman</title>
      <url>https://tistory1.daumcdn.net/tistory/7047231/attach/b4c4ab8b112b4bb1adcdac751aeeab6c</url>
      <link>https://ptcman.tistory.com</link>
    </image>
    <item>
      <title>EAI(Enterprise Application Integration), 왜 필요한가</title>
      <link>https://ptcman.tistory.com/37</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번 프로젝트에서 IF(Interface)를 담당하게 되어 관련된 경험을 남겨본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부 서비스를 이용할 때 보통은 공개된 API를 활용하거나, 마땅한 게 없으면 타업체와 협업해서 API 규약을 새로 만든다. 그러나 대기업의 경우는 이미 사용 중인 솔루션이 많기 때문에, 이를 각 솔루션과 일일이 직접 연동하다 보면 구조가 금세 복잡해진다. 게다가 API마다 보안도 따로 챙겨야 하니 유지보수도 만만치 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 나온 개념이 &lt;b&gt;EAI(Enterprise Application Integration)&lt;/b&gt; 다. 대부분의 대기업은 외부와 통신할 때 가장 앞단에 EAI를 두고 데이터를 주고받는다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;EAI의 핵심 아이디어&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EAI는 단순히 &quot;시스템을 연결한다&quot;는 의미가 아니다. 이질적인 시스템 간에 &lt;b&gt;데이터와 비즈니스 프로세스를 일관되게 흐르게 만드는 것&lt;/b&gt;이 본질이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대표적인 통합 패턴은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Point-to-Point&lt;/b&gt;: 시스템끼리 1:1로 직접 연결. 단순하지만 시스템이 N개면 연결선은 N(N-1)/2개로 폭발한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Hub-and-Spoke&lt;/b&gt;: 중앙 허브를 두고 모든 시스템이 허브와 통신. 관리는 쉬워지지만 허브가 SPOF(Single Point of Failure)가 된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;ESB(Enterprise Service Bus)&lt;/b&gt;: 메시지 버스 위에서 서비스가 느슨하게 결합. 라우팅, 변환, 오케스트레이션을 버스가 담당한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;도구가 문제를 해결해주지는 않는다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;국내에서는 webMethods, MuleSoft, IBM Integration Bus 같은 전통적 EAI/ESB 솔루션이 여전히 많이 쓰인다. 최근에는 iPaaS(Integration Platform as a Service) 형태로 Boomi, MuleSoft Anypoint 같은 클라우드 기반 도구도 자리잡고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 도구는 문제를 해결해주지 않는다. &lt;b&gt;인터페이스 정의서&lt;/b&gt;가 명확하지 않으면 어떤 솔루션을 깔아도 결국 진흙탕이 된다. 어떤 시점에 어떤 데이터가, 어떤 키로, 어떤 형식으로 흐르는지를 사람이 먼저 정리해야 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실제 사례: Salesforce &amp;rarr; webMethods &amp;rarr; SAP&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에 진행 중인 프로젝트의 구조다. 영업이 Salesforce에서 수주를 등록하면, 주문 정보가 webMethods를 거쳐 SAP로 전달되어 생산&amp;middot;물류 프로세스가 시작된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 자주 나오는 오해 하나. &lt;b&gt;&quot;webMethods는 가운데에서 그냥 데이터 넘기는 통로 아닌가?&quot;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아니다. 가운데에 있다는 이유로 단순한 프록시처럼 보이지만, EAI 미들웨어가 실제로 하는 일은 단순 중계와는 거리가 멀다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;데이터 변환(Transformation)&lt;/b&gt;: Salesforce의 Order 객체 JSON을 SAP가 받을 수 있는 IDoc / BAPI / OData 페이로드로 매핑한다. 필드명, 자료형, 코드 체계가 모두 다르기 때문에 단순 복사는 불가능하다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;프로토콜 중계(Protocol Mediation)&lt;/b&gt;: Salesforce 쪽은 REST/SOAP, SAP 쪽은 RFC, IDoc, OData V4 등 양쪽이 쓰는 통신 방식이 다르다. webMethods가 이 차이를 흡수한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;라우팅(Routing)&lt;/b&gt;: 하나의 Salesforce 이벤트가 SAP에서 여러 트랜잭션으로 분기되는 경우가 흔하다. 조건에 따라 어디로 보낼지 결정하는 것도 미들웨어 몫이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;신뢰성(Reliability)&lt;/b&gt;: SAP가 일시적으로 응답하지 않을 때, webMethods 큐에 메시지를 보관하고 재시도한다. Salesforce 호출은 이미 끝났는데 SAP가 다운되어 있어도 데이터가 유실되지 않는다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;모니터링과 추적(Monitoring &amp;amp; Audit)&lt;/b&gt;: 어느 메시지가 어디서 막혔는지, 어떤 데이터로 어떤 변환을 거쳤는지 한 곳에서 본다. 장애가 났을 때 가장 먼저 보는 곳이 여기다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;보안 중앙화&lt;/b&gt;: Salesforce가 SAP 자격 증명을 알 필요가 없다. webMethods가 양쪽 시스템과의 인증을 분리해서 관리한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, webMethods는 &quot;지나가는 길&quot;이 아니라 &lt;b&gt;변환&amp;middot;라우팅&amp;middot;완충 장치 역할을 하는 자율적인 시스템&lt;/b&gt;이다. 잘 설계된 미들웨어 계층이 있어야 양 끝단의 시스템이 서로의 변경에 영향받지 않고 독립적으로 진화할 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SAP 측 인터페이스로는 전통적으로 IDoc과 BAPI(RFC)가 쓰였지만, 최근에는 OData V4 API(예: &lt;code&gt;CE_SALESORDER_0001&lt;/code&gt; Sales Order 표준 API)도 옵션으로 검토할 만하다. 양쪽 모두 webMethods 어댑터로 처리 가능하다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IF를 진행하면서 새삼 느끼는 건, 결국 가장 중요한 건 &lt;b&gt;비즈니스의 정의, 즉 인터페이스를 어떻게 정의할 것인가&lt;/b&gt;라는 점이다. 정의만 명확하다면 각 시스템 담당자들은 규칙대로 보내고 받기만 하면 되기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는, 언제나 그렇듯 인터페이스를 빠르게 정의하고 일을 시작하는 것이 쉽지 않다는 점이다. 도메인을 맡은 현업 부서와 IT 부서가 나뉘어 있다 보니 팀 내부 소통도, 외부 솔루션사와의 소통도 함께 풀어야 한다. 그래서 이번 일은 개발 난이도가 높다기보단, &lt;b&gt;사람과 사람 사이의 소통을 어떻게 풀어가는지&lt;/b&gt;가 핵심인 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간은 없고 오픈일은 다가오는데 IF 정의는 안 되는 &amp;mdash; 그런 최악의 상황만큼은 피하고 싶다.&lt;/p&gt;</description>
      <author>독서, 운동 그리고 개발</author>
      <guid isPermaLink="true">https://ptcman.tistory.com/37</guid>
      <comments>https://ptcman.tistory.com/37#entry37comment</comments>
      <pubDate>Sat, 9 May 2026 22:03:36 +0900</pubDate>
    </item>
    <item>
      <title>차문이 안 열렸다, 그리고 알게 된 12V 배터리 리셋 버튼</title>
      <link>https://ptcman.tistory.com/36</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;이번 주 글을 뭘 써야 할까 고민하다 출근 전에 있었던 이야기를 써본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;기술 관련된건 아니지만, 이 글을 보는 하이브리드 차주에게 참고가 되기를&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;평범한 아침이었다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;차에 타려는데 문이 안 열렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스마트키를 들고 손잡이를 당겨도 잠잠하고, 버튼을 눌러도 반응이 없었다. 처음엔 스마트키 배터리가 다 됐나 싶었다. 그런데 키를 가까이 대도, 멀리 떨어졌다 다시 와도 결과는 똑같았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 스마트키 안에 숨어있던 비상키를 꺼내서 도어 손잡이 커버를 빼고, 열쇠 구멍에 꽂아 직접 문을 따고 들어갔다. 그렇게 운전석에 앉아 시동 버튼을 눌렀는데 &amp;mdash; 아무 반응이 없다. 계기판도 까맣다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;방전됐나?&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 좀 이상했다. 어제까지 멀쩡히 탔던 차고, 블랙박스 주차모드도 따로 안 켜뒀다. 매뉴얼을 뒤져보고 나서야 알게 됐다. &lt;b&gt;이건 방전이 아니라 &quot;차단&quot;이라는 것을.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;하이브리드의 12V 배터리는 좀 다르다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내연기관 차의 12V 배터리는 우리가 흔히 아는 그 납산 배터리다. 보닛 열면 보이는 그거. 방전되면 점프 케이블 물리거나, 아니면 새 걸로 갈아 끼우면 끝이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 하이브리드는 사정이 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 현대기아 하이브리드 차량의 12V 배터리는 별도의 납산 배터리가 아니라, &lt;b&gt;고전압(HEV) 배터리 팩 안에 통합되어 있는 경우가 많다.&lt;/b&gt; 차종에 따라 트렁크나 센터콘솔 아래쪽 같은 접근하기 까다로운 위치에 들어가 있기도 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 무슨 의미냐면 &amp;mdash; &lt;b&gt;방전되면 진짜 골치 아프다.&lt;/b&gt; 그냥 차 한 대 와서 점프해주면 끝나는 일반 차랑 다르게, 위치도 까다롭고 통합형이라 교체도 쉽지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 현대기아는 아예 &lt;b&gt;&quot;방전되기 전에 차단해버리자&quot;&lt;/b&gt; 는 시스템을 넣어뒀다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&quot;방전&quot;이 아니라 &quot;차단&quot;이다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;차량은 시동을 끈 뒤에도 미세한 전류를 계속 소모한다. 스마트키 수신기, 도난 방지 시스템, 블랙박스 같은 것들이 다 12V 배터리에서 전기를 뽑아 쓴다. 이걸 &lt;b&gt;암전류&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장기 주차하거나 블랙박스 주차모드를 오래 켜두면, 12V 배터리 전압이 슬금슬금 내려간다. 그러다 일정 수준 이하로 떨어지는 순간 &amp;mdash; &lt;b&gt;차량이 알아서 12V 배터리 회로를 끊어버린다.&lt;/b&gt; 더 이상 전기를 빼가지 못하게 차단하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 핵심이다. 배터리가 죽은 게 아니라 &lt;b&gt;자기방어 모드에 들어간 것&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 회로가 차단되면 외부에서 보기엔 방전된 거랑 똑같이 보인다는 점이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스마트키 작동 안 함 &amp;rarr; 문 안 열림&lt;/li&gt;
&lt;li&gt;시동 버튼 눌러도 반응 없음&lt;/li&gt;
&lt;li&gt;계기판 깜깜&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 비상키로 문을 따고 들어가야 했고, 시동 버튼은 아무리 눌러도 묵묵부답이었던 거다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;12V BATT RESET 버튼의 정체&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 차단 상태를 풀어주는 게 바로 &lt;b&gt;12V BATT RESET&lt;/b&gt; 버튼이다. 보통 스티어링 휠 왼쪽 아래, 운전석 무릎 근처 퓨즈박스 쪽에 있다 (차종마다 위치는 좀 다르다).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;누르면 어떻게 되냐면:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;차단됐던 12V 배터리 회로가 다시 연결된다&lt;/li&gt;
&lt;li&gt;고전압 배터리(HEV 배터리)에서 LDC(Low voltage DC-DC Converter)를 통해 12V로 변환된 전기가 흘러 들어온다&lt;/li&gt;
&lt;li&gt;이 상태에서 &lt;b&gt;15초 안에 시동 버튼을 누르면&lt;/b&gt; 시동이 걸린다&lt;/li&gt;
&lt;li&gt;READY 표시등이 켜진 채로 30분 정도 정차하거나 주행하면 12V 배터리가 다시 충전된다&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 말하면 일종의 &lt;b&gt;셀프 점프 스타트&lt;/b&gt;다. 외부에서 점프 케이블 물릴 필요 없이, 차 안에 있는 고전압 배터리가 12V를 살려주는 구조다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결론, 이건 알아두면 좋다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하이브리드 차주라면 이거 두 가지만 기억해두자.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;차문이 갑자기 안 열리면 방전이 아니라 &quot;차단&quot;일 가능성이 크다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;은근 열쇠 구멍을 가리고 있는 뚜껑을 따는게 쉽지 않으니 평소에 연습을 해두자&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 한 번 더 &amp;mdash; &lt;b&gt;누르고 15초 안에 시동.&lt;/b&gt; 이거만 기억하면 견인차 부를 일은 거의 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 일반 자동차는 보닛 열고 12v 배터리를 교체하는게 어렵지 않은데, 하이브리드는 아마 뒷자리 밑에 고전압이랑 같이 있어서 교체가 어렵고 그래서 공수 비용이 많이 측정된다고 알고 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 8.5만 정도 탔는데 더 버텨주기를&lt;/p&gt;</description>
      <author>독서, 운동 그리고 개발</author>
      <guid isPermaLink="true">https://ptcman.tistory.com/36</guid>
      <comments>https://ptcman.tistory.com/36#entry36comment</comments>
      <pubDate>Sat, 25 Apr 2026 21:43:48 +0900</pubDate>
    </item>
    <item>
      <title>공유기 제어 없이 서버 외부 공개하기 (ngrok 사용기)</title>
      <link>https://ptcman.tistory.com/35</link>
      <description>&lt;h2&gt;  배경&lt;/h2&gt;
&lt;p&gt;최근에 로컬 환경에서 개발한 서버를 외부에 공개해야 하는 상황이 있었다.&lt;br&gt;보통 이런 경우에는 공유기에서 &lt;strong&gt;포트 포워딩&lt;/strong&gt;을 설정해야 하지만, 아래와 같은 이유로 불가능했다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;공유기 관리자 권한이 없음&lt;/li&gt;
&lt;li&gt;회사 / 기숙사 / 공용 네트워크 환경&lt;/li&gt;
&lt;li&gt;보안 정책으로 포트 개방 제한&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그래서 대안으로 선택한 것이 바로 &lt;strong&gt;ngrok&lt;/strong&gt;이다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;  ngrok이란?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;ngrok&lt;/strong&gt;은 로컬에서 실행 중인 서버를 &lt;strong&gt;공개 URL로 터널링&lt;/strong&gt;해주는 도구다.&lt;/p&gt;
&lt;p&gt;즉,&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;내 PC (localhost:3000)
    ↓
ngrok 서버
    ↓
https://xxxx.ngrok.io (외부 접속 가능)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;이런 구조로 동작한다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;⚙️ 설치 및 설정&lt;/h2&gt;
&lt;h3&gt;1. ngrok 다운로드&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;brew install ngrok&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h3&gt;2. 인증 토큰 등록&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://ngrok.com/&quot;&gt;https://ngrok.com/&lt;/a&gt; 회원가입 후 발급받은 토큰을 등록한다:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ngrok config add-authtoken &amp;lt;YOUR_AUTH_TOKEN&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;  사용 방법&lt;/h2&gt;
&lt;h3&gt;1. 로컬 서버 실행&lt;/h3&gt;
&lt;p&gt;먼저 본인이 만든 아무서버나 실행을 한다.&lt;/p&gt;
&lt;p&gt;→ localhost:3000 에 서버 실행&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;2. ngrok 실행&lt;/h3&gt;
&lt;p&gt;실행할 때 포트번호를 맵핑 해준다&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ngrok http 3000&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h3&gt;3. 결과 확인&lt;/h3&gt;
&lt;p&gt;터미널에 다음과 같은 URL이 생성된다:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://abcd-1234.ngrok.io&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;이 URL을 외부에서 접속하면 &lt;strong&gt;내 로컬 서버에 접속 가능&lt;/strong&gt;하다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;⚠️ 주의사항&lt;/h2&gt;
&lt;h3&gt;1. URL이 매번 변경됨 (무료 플랜)&lt;/h3&gt;
&lt;p&gt;무료는 매번 url이 변경된다라고 하지만 어차피 테스트 하는 상황에서 사용하므로 크게 문제 될껀 없었다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;2. 보안 문제&lt;/h3&gt;
&lt;p&gt;외부에 공개되는 만큼 주의 필요:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;인증 없는 API 노출 금지&lt;/li&gt;
&lt;li&gt;테스트 데이터만 사용&lt;/li&gt;
&lt;li&gt;필요 시 Basic Auth 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;예:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ngrok http -auth=&amp;quot;user:password&amp;quot; 3000&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h3&gt;3. 성능 제한&lt;/h3&gt;
&lt;p&gt;무료 플랜은 속도 및 연결 수 제한이 있음&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;  장점&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;포트포워딩 없이 외부 공개 가능&lt;/li&gt;
&lt;li&gt;설정이 매우 간단&lt;/li&gt;
&lt;li&gt;NAT / 방화벽 환경에서도 사용 가능&lt;/li&gt;
&lt;li&gt;웹훅 테스트에 최적&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;  단점&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;URL 변경 (무료)&lt;/li&gt;
&lt;li&gt;속도 제한&lt;/li&gt;
&lt;li&gt;장기 운영에는 부적합&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;  마무리&lt;/h2&gt;
&lt;p&gt;사실 단순 테스트가 목적이고 회사나 외부환경 같은 공유기를 컨트롤 할 수 없는 상황속에서는 ngrok이 좋은 대안이 될 수 있을 것 같다. 설치, 인증, 실행까지 되게 간단해서 동료간 테스트 할 때 사용하면 유용한 툴이다. &lt;/p&gt;</description>
      <author>독서, 운동 그리고 개발</author>
      <guid isPermaLink="true">https://ptcman.tistory.com/35</guid>
      <comments>https://ptcman.tistory.com/35#entry35comment</comments>
      <pubDate>Sat, 11 Apr 2026 13:22:24 +0900</pubDate>
    </item>
    <item>
      <title>AI가 코드를 짜는 시대, 개발자는 무엇을 해야 할까?</title>
      <link>https://ptcman.tistory.com/34</link>
      <description>&lt;h1&gt;AI가 코드를 짜는 시대, 개발자는 무엇을 해야 할까?&lt;/h1&gt;
&lt;p&gt;요즘 나의 개발 루틴은 이렇다.&lt;/p&gt;
&lt;p&gt;AI에게 코드를 시키고, 결과물을 보고, 잘 됐는지 확인하고, 수정할 게 있으면 수정한다. 직접 키보드를 두드리며 코드를 한 줄 한 줄 작성하는 시간은 눈에 띄게 줄었다. 솔직히 말하면, 이제 나는 &amp;quot;코드를 짜는 사람&amp;quot;이라기보다 &amp;quot;코드를 검증하고 방향을 잡아주는 사람&amp;quot;에 더 가깝다.&lt;/p&gt;
&lt;p&gt;이런 변화 속에서 문득 불안해지기도 한다. AI가 코드를 이만큼 짜주는데, 앞으로 나 같은 개발자는 어떤 가치를 가질 수 있을까?&lt;/p&gt;
&lt;p&gt;꽤 오랜 시간 고민한 끝에, 몇 가지 생각을 정리해본다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;1. 고객과의 스킨십&lt;/h2&gt;
&lt;p&gt;AI가 코드를 대신 짜주면서, 개발자의 영역은 오히려 넓어지고 있다. 코드 앞에만 앉아 있던 시간이 줄어든 만큼, 그 시간을 어디에 쓰느냐가 중요해졌다.&lt;/p&gt;
&lt;p&gt;나는 그 답이 &lt;strong&gt;고객과의 스킨십&lt;/strong&gt;이라고 생각한다.&lt;/p&gt;
&lt;p&gt;요구사항 문서만 받아서 그대로 구현하는 개발자의 시대는 저물고 있다. 고객과 직접 대화하고, 그들이 말로 표현하지 못하는 니즈를 읽어내고, 기술적으로 가능한 범위 안에서 최선의 해법을 제안할 수 있는 개발자. 이런 사람이 앞으로 살아남는다.&lt;/p&gt;
&lt;p&gt;특히 Salesforce 같은 플랫폼에서는 더 그렇다. 고객의 비즈니스 프로세스를 이해하지 못하면 좋은 솔루션을 만들 수 없고, 그 이해는 회의실에서 고객과 마주 앉아야 생긴다. AI는 코드를 짜줄 수 있지만, 고객의 표정을 읽고 진짜 문제를 파악하는 건 해줄 수 없다.&lt;/p&gt;
&lt;p&gt;코딩 능력이 평준화될수록, &lt;strong&gt;사람과 소통하는 능력을 가진 개발자&lt;/strong&gt;의 가치는 올라갈 수밖에 없다.&lt;/p&gt;
&lt;h2&gt;2. 코드를 읽는 눈&lt;/h2&gt;
&lt;p&gt;AI가 생성한 코드는 겉보기에 깔끔하고, 대부분 잘 돌아간다. 문제는 &amp;quot;대부분&amp;quot;이라는 단어에 있다. 엣지 케이스, 보안 취약점, 성능 병목. 이런 것들을 잡아내는 눈은 직접 코드를 수없이 짜보고, 수없이 버그를 만나본 경험에서 나온다.&lt;/p&gt;
&lt;p&gt;나는 이 감각을 유지하기 위해 나만의 방법을 쓰고 있다. 코드 수정이 필요할 때 AI에게 바로 시키지 않는다. 먼저 내가 머릿속으로 수정 방향을 잡아보고, 그 다음 AI에게 같은 문제를 던진다. 그리고 내 답과 AI의 답을 비교한다. 일종의 &lt;strong&gt;나 vs AI 대결&lt;/strong&gt;이다.&lt;/p&gt;
&lt;p&gt;그러나 슬프게도 보통 AI가 이기는 경우가 많다 ㅎㅎ&lt;/p&gt;
&lt;p&gt;이 과정을 통해 내 판단력이 무뎌지지 않는다. AI를 도구로 쓰되, 내 실력까지 AI에게 위임하지 않는 것. 이게 AI 시대에 개발자로서 살아남는 하나의 방법이라고 생각한다.&lt;/p&gt;
&lt;h2&gt;3. 도메인 전문성&lt;/h2&gt;
&lt;p&gt;코딩 자체가 자동화될수록, 특정 도메인에 대한 깊은 이해를 가진 개발자의 가치는 올라간다.&lt;/p&gt;
&lt;p&gt;금융 규제를 이해하는 핀테크 개발자, 의료 데이터의 특성을 아는 헬스케어 개발자, 물류 프로세스를 꿰뚫고 있는 이커머스 개발자. 이런 사람들이 AI를 도구로 활용할 때 만들어내는 결과물은, 도메인 지식 없이 AI만 잘 다루는 사람과는 차원이 다르다.&lt;/p&gt;
&lt;p&gt;&amp;quot;개발자 + α&amp;quot;에서 그 α가 무엇이냐가 앞으로의 경쟁력을 결정하게 될 것이다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;마무리&lt;/h2&gt;
&lt;p&gt;AI 시대에 요구되는 건 결국 더 본질적인 역량이다. 그래서 나는 최근 방통대 컴퓨터공학과에 지원했다. AI가 대신해주는 것들이 늘어날수록, 오히려 기초 체력이 중요하다는 걸 느꼈기 때문이다.&lt;/p&gt;
&lt;p&gt;AI가 코드를 짜는 시대에, 개발자의 가치는 코드 바깥에 있지 않을까 생각한다.&lt;/p&gt;</description>
      <author>독서, 운동 그리고 개발</author>
      <guid isPermaLink="true">https://ptcman.tistory.com/34</guid>
      <comments>https://ptcman.tistory.com/34#entry34comment</comments>
      <pubDate>Sat, 28 Mar 2026 09:02:23 +0900</pubDate>
    </item>
    <item>
      <title>[방통대 컴퓨터공학] 알고리즘 1-2 강 정리</title>
      <link>https://ptcman.tistory.com/33</link>
      <description>&lt;h1&gt;알고리즘 소개&lt;/h1&gt;
&lt;h2&gt;1. 강의 개요&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;과목 : 알고리즘&lt;/li&gt;
&lt;li&gt;강의 : 알고리즘 소개 (1) ~ (2)&lt;/li&gt;
&lt;li&gt;핵심 키워드 : 알고리즘, 욕심쟁이 방법, 분할정복 방법, 동적 프로그래밍, 시간복잡도, 점근성능, O-표시&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이번 강의에서는 알고리즘의 정의, 설계 방법 그리고 분석 방법에 대해 설명한다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;2. 핵심 개념&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;알고리즘이란 무엇인가&lt;/li&gt;
&lt;li&gt;알고리즘 설계 방법&lt;/li&gt;
&lt;li&gt;알고리즘 분석 방법&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;3. 내용 정리&lt;/h2&gt;
&lt;h3&gt;3.1 알고리즘의 정의&lt;/h3&gt;
&lt;p&gt;주어진 문제를 해결하거나 함수를 계산하기 위해 따라야 할 명령어들을 단계적으로 나열한 것.&lt;br&gt;즉, 문제 해결을 위한 명령어의 집합 이라고 생각 할 수 있다.&lt;/p&gt;
&lt;h3&gt;3.2 알고리즘 설계 방법&lt;/h3&gt;
&lt;p&gt;알고리즘은&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;욕심쟁이 방법 (Greedy)&lt;/li&gt;
&lt;li&gt;분할 정복 (Divide &amp;amp; Conquer)&lt;/li&gt;
&lt;li&gt;동적 프로그래밍 (Dynamic Programming)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;사실 이 방법 말고도 다른 방법들이 많지만 일단 책에서는 이 3개를 다루고, 추후에 정렬을 하면서 자세히 알아볼것 같다.&lt;/p&gt;
&lt;h3&gt;3.3 알고리즘 분석 방법&lt;/h3&gt;
&lt;p&gt;알고리즘은 정확성 분석, 효율성 분석 크게 두가지를 다루지만, 이번 과목에서 효율성 분석을 중점으로 다룬다.&lt;/p&gt;
&lt;h3&gt;3.3.1 효율성분석&lt;/h3&gt;
&lt;p&gt;알고리즘을 효율성을 분석 한다고 했을 때, 한번 알고리즘을 돌리고 알고리즘을 끝나는 시간을 측정하면 되겠지만 이렇게 되면 하드웨어 성능, 컴파일러 버전, 입력값의 수 등 다양한 외부요인 때문에 객관적으로 비교하기가 어렵다.그래서 기준을 정한 방법인 바로 &lt;strong&gt;점근성능&lt;/strong&gt;이다.&lt;/p&gt;
&lt;p&gt;점근성능(Asymptotic Performance)이란, 입력크기 n이 무한히 커짐에 따라 결정되는 성능이다.&lt;/p&gt;
&lt;p&gt;이 같은 점근성능은 최악의경우(Big O) 일 때, 최선의 경우(Big Ω)일 때로 표시할 수 있다&lt;/p&gt;
&lt;p&gt;보통의 경우 Big O로 알고리즘의 성능을 분석한다.&lt;/p&gt;
&lt;p&gt;그리고 보통의 경우 T(n) = O(n), O(n^2) 등으로 표현하고 여기서 n은 코드상에서 반복문을 의미한다, n^2 이면 이중포문&lt;/p&gt;
&lt;h3&gt;3.3.2 순환 알고리즘과 점화식&lt;/h3&gt;
&lt;p&gt;이진탐색과 같은 재귀 느낌 나는 애들은, 점화식을 잘 써야한다. 여기서 살짝 수학 느낌이 들어가는데, 막상 하나하나 해보니 양변에 log 정도 취해주는것 밖에 없다. 여튼, 이진탐색의 폐쇄형은 T(n) = O(log n)이다. 왜 DB에서 탐색을 할 때 이진탐색트리를 사용하는지 알 수 있는 부분이다.&lt;br&gt;이외 다른 점화식과 폐쇄형이 있는데 그 부분은 정렬 부분 나올 때 아이패드로 작성해서 블로그에 올려야 겠다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;4. 소감&lt;/h2&gt;
&lt;p&gt;단순 CRUD 기능만 한다면 크게 알고리즘을 사용할 일이 크게 없을 것 같지만, 요즘들어 고객의 대용량 데이터를 처리하는 일이 많아져 효율을 고민하는 일이 많아졌는데 이번 알고리즘 과목이 도움이 됐으면 좋겠다.&lt;/p&gt;</description>
      <category>방통대</category>
      <category>수업정리</category>
      <category>알고리즘</category>
      <category>컴퓨터공학</category>
      <author>독서, 운동 그리고 개발</author>
      <guid isPermaLink="true">https://ptcman.tistory.com/33</guid>
      <comments>https://ptcman.tistory.com/33#entry33comment</comments>
      <pubDate>Thu, 12 Mar 2026 18:36:54 +0900</pubDate>
    </item>
    <item>
      <title>GC(Garbage Collection)</title>
      <link>https://ptcman.tistory.com/32</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;시작하며&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java에서는 new를 통해서 객체를 생성하게 된다. 자바 파일이 compile 되면 os가 JVM에게 할당한 메모리 중 JVM의 Run time data area의 Heap 영역에 new를 통해서 만든 객체가 메모리에 할당하게 된다. 이렇게 할당된 메모리는 언젠가는 반환 되어야 하는데 C에서는 delete라는 연산자를 통해서 반환 시키지만 Java에서는 delete를 사용한 적이 없다. 이유가 왜일까? 바로 GC(Garbage Collection)를 통해서 자동으로 메모리를 반환 하기 때문이다. 이번 시간에는 이런 GC가 어떻게 동작하는지 그리고 GC의 알고리즘에는 어떠한 것들이 있는지 살펴보자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;JVM Heap Area구조&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;335&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnQEdU/btsJmK0EEaW/OSFkQSgaN6Qoddc0oOkR2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnQEdU/btsJmK0EEaW/OSFkQSgaN6Qoddc0oOkR2k/img.png&quot; data-alt=&quot;Jvm Runtime Data Areas&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnQEdU/btsJmK0EEaW/OSFkQSgaN6Qoddc0oOkR2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnQEdU%2FbtsJmK0EEaW%2FOSFkQSgaN6Qoddc0oOkR2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;826&quot; height=&quot;216&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;335&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Jvm Runtime Data Areas&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;637&quot; data-origin-height=&quot;221&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Jvujh/btsJn80omPF/CvPrMNpGJWtBucIk46ITIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Jvujh/btsJn80omPF/CvPrMNpGJWtBucIk46ITIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Jvujh/btsJn80omPF/CvPrMNpGJWtBucIk46ITIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJvujh%2FbtsJn80omPF%2FCvPrMNpGJWtBucIk46ITIK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;637&quot; height=&quot;221&quot; data-origin-width=&quot;637&quot; data-origin-height=&quot;221&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 heap Area를 보면 크게 4가지 구역으로 나눌 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Eden&lt;br /&gt;자바 객체가 생성되자 마자 저장되는 곳이다.&lt;br /&gt;Minor GC를 통해 Survival 영역으로 이동한다.&lt;/li&gt;
&lt;li&gt;Survival0, Survival1&lt;br /&gt;Eden에서 Minor GC를 통해 살아남은 객체가 저장 되는 곳이다.&lt;br /&gt;객체는 Survival0 또는 Survival1 둘 중 하나에만 존재 해야한다.&lt;/li&gt;
&lt;li&gt;Old Generation&lt;br /&gt;- GC를 진행할 때마다 Object aging이 발생하여 age 값이 1씩 증가하는데 특정 임계값이 되면 Old Generation으로 Object가 이동한다.&lt;br /&gt;- Survial의 메모리가 꽉 차게 될 때도 Old Generation 이동하게 된다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Young Generation에서 Old Generation으로 이동하는 경우 Promotion이라고 한다. 그리고 Old 영역에서 발생하는 GC를 Major GC(Full GC)라고 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;GC 동작방식&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;342&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dJ6flt/btsJmkBdjhl/MKpOrI3fojc9wRIROeUyW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dJ6flt/btsJmkBdjhl/MKpOrI3fojc9wRIROeUyW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dJ6flt/btsJmkBdjhl/MKpOrI3fojc9wRIROeUyW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdJ6flt%2FbtsJmkBdjhl%2FMKpOrI3fojc9wRIROeUyW0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;342&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;342&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 Heap 영역 구조를 설명했다. 실제로 하나의 객체가 생성되면 Eden에 생성이 됐다가 GC가 진행 될 때 마다 S1 -&amp;gt; S2 -&amp;gt; S1..... 갔다가 끝까지 메모리가 반환 되지 않으면 Old 영역으로 가게 된다. &lt;b&gt;그렇다면 GC의해서 메모리에 남아있고 반환 되는 기준이 무엇인가?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;343&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgBKvn/btsJm6oUFJM/AJ8rqdvkEHMhfPZEoRVrH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgBKvn/btsJm6oUFJM/AJ8rqdvkEHMhfPZEoRVrH0/img.png&quot; data-alt=&quot;https://www.javatpoint.com/how-garbage-collection-works-in-java&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgBKvn/btsJm6oUFJM/AJ8rqdvkEHMhfPZEoRVrH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgBKvn%2FbtsJm6oUFJM%2FAJ8rqdvkEHMhfPZEoRVrH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;523&quot; height=&quot;276&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;343&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://www.javatpoint.com/how-garbage-collection-works-in-java&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GC Root 즉 참조할 수 있는 처음 Object를 기준으로 참조를 하고 있으면 GC에서 살아남아 메모리에 남아 있고 참조하지 않으면 메모리를 반환 하게 된다.&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Mark and Sweep 알고리즘&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mark and Sweep은 GC에서 사용하는 기본적인 알고리즘인다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;391&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAh3mS/btsJnf0exD4/o1bF0v7pcreEXvR1vR5Jsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAh3mS/btsJnf0exD4/o1bF0v7pcreEXvR1vR5Jsk/img.png&quot; data-alt=&quot;https://mirinae312.github.io/develop/2018/06/04/jvm_gc.html&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAh3mS/btsJnf0exD4/o1bF0v7pcreEXvR1vR5Jsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAh3mS%2FbtsJnf0exD4%2Fo1bF0v7pcreEXvR1vR5Jsk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;710&quot; height=&quot;185&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;391&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://mirinae312.github.io/develop/2018/06/04/jvm_gc.html&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Mark&lt;br /&gt;&lt;/b&gt;JVM이 현재 사용되고 있는(즉, 여전히 참조되고 있는) 객체를 식별합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Sweep&lt;br /&gt;&lt;/b&gt;Mark 단계에서 마크되지 않은 객체들을 메모리에서 해제합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Compaction&lt;br /&gt;&lt;/b&gt;Mark and Sweep 알고리즘 자체에는 Compact 단계가 포함되지 않지만, 일부 GC 구현에서는 &lt;b&gt;메모리 단편화&lt;/b&gt; 문제를 해결하기 위해 Compact 단계를 추가합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Stop the World&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가비지 컬렉션(GC)이나 기타 중요한 작업을 수행하기 위해 &lt;b&gt;모든 애플리케이션 스레드를 일시적으로 멈추는 과정&lt;/b&gt;을 의미합니다. 이 과정 동안 JVM은 메모리 관리나 기타 중요한 작업을 안정적으로 수행할 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제적으로 Mark 단계에서 메모리를 참조 하는지 안하는지 봐야 하는데 이때 STW를 안하면 일관되지 않으므로 STW가 작동하게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 개발자는 &lt;b&gt;GC를 통해 메모리 누수를 없애야 하며 STW시간을 줄여야한다.&lt;/b&gt;&lt;/p&gt;</description>
      <category>JAVA</category>
      <category>garbage collection</category>
      <category>GC</category>
      <category>Java</category>
      <category>가비지 컬렉션</category>
      <author>독서, 운동 그리고 개발</author>
      <guid isPermaLink="true">https://ptcman.tistory.com/32</guid>
      <comments>https://ptcman.tistory.com/32#entry32comment</comments>
      <pubDate>Sat, 31 Aug 2024 21:55:21 +0900</pubDate>
    </item>
    <item>
      <title>보안과 접근 권한 설정</title>
      <link>https://ptcman.tistory.com/31</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Salesforce가 업계 1위의 CRM platform이라고 해도 결국에 뜯어 보면 Object로 이루어진 하나의 Database이다. 그러나 부트캠프 과정에서 구상했던 DB와 다른 점은 부트캠프 때 User는 Role_Admin과 Role_User 단 둘이였고 같은 User끼리 보안 및 접근 권한 설정을 크게 신경쓰지 않아도 됐지만, Salesforce는 강력한 보안 및 접근권한 설정 기능을 제공한다라는 점이다. 이번 글에서는 SFDC가 보안과 접근권한 설정을 어떻게 하는지 알아보겠다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Role&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;788&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCoQ4f/btsJjtEQeOf/W5K9awXZKFq9k89dhq0DJ0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCoQ4f/btsJjtEQeOf/W5K9awXZKFq9k89dhq0DJ0/img.jpg&quot; data-alt=&quot;https://trailhead.salesforce.com/ko/content/learn/modules/data_security/data_security_roles?trailmix_creator_id=strailhead&amp;amp;amp;trailmix_slug=prepare-for-your-salesforce-administrator-credential&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCoQ4f/btsJjtEQeOf/W5K9awXZKFq9k89dhq0DJ0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCoQ4f%2FbtsJjtEQeOf%2FW5K9awXZKFq9k89dhq0DJ0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;643&quot; height=&quot;347&quot; data-origin-width=&quot;788&quot; data-origin-height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://trailhead.salesforce.com/ko/content/learn/modules/data_security/data_security_roles?trailmix_creator_id=strailhead&amp;amp;trailmix_slug=prepare-for-your-salesforce-administrator-credential&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Role은 User의 &lt;b&gt;계층적 구조를 나타내는 개념&lt;/b&gt;이다. SFDC의 타겟은 회사이고 회사의 임직원들은 위의 사진과 유사하게 계층적 구조로 이루어져있다. 이러한 구조를 만들어주는게 SFDC의 Role이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Why?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB에서 이렇게 계층적 구조로 만들면 어떤 점이 좋을까? Role 자체가 조직구조를 반영하고 뒤에 설명할 Sharing rule에서 hirarchey를 적용하면 부하직원의 데이터를 상관이 자동으로 상속 받을 수 있어 개별적으로 데이터를 공유하는 번거로움을 덜 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 Role 만으로는 데이터의 보안과 접근을 제어 할 수 없고 뒤에 설명할 &lt;b&gt;Sharing을 통해서 상위계층과 레코드를 공유조건을 설정 할 수 있다&lt;/b&gt;.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Sharing&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Sharing는 공유를 의미한다. 무엇은 공유 하느냐. 바로 Record이다. 처음 User를 생성할 때 위와 같이 Role를 설정해서 만들 수 있고 User는 계층구조에 따라 Record를 공유 할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1004&quot; data-origin-height=&quot;817&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbnNee/btsJjSqInus/rMD2Leq9dkub4YKCEJ11Tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbnNee/btsJjSqInus/rMD2Leq9dkub4YKCEJ11Tk/img.png&quot; data-alt=&quot;https://trailhead.salesforce.com/ko/content/learn/modules/data_security/data_security_records?trailmix_creator_id=strailhead&amp;amp;amp;trailmix_slug=prepare-for-your-salesforce-administrator-credential&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbnNee/btsJjSqInus/rMD2Leq9dkub4YKCEJ11Tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbnNee%2FbtsJjSqInus%2FrMD2Leq9dkub4YKCEJ11Tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;509&quot; height=&quot;414&quot; data-origin-width=&quot;1004&quot; data-origin-height=&quot;817&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://trailhead.salesforce.com/ko/content/learn/modules/data_security/data_security_records?trailmix_creator_id=strailhead&amp;amp;trailmix_slug=prepare-for-your-salesforce-administrator-credential&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Organization Wide Defaults(OWD)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 적용 되는 Sharing rule이다. 별다른 설정을 하지 않으면 OWD의 설정대로 Record를 공유하게 된다.,&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Role Hierarchy&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1417&quot; data-origin-height=&quot;188&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAY5JQ/btsJj098b2S/UPJtfy7DlpnkwD0uETFpgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAY5JQ/btsJj098b2S/UPJtfy7DlpnkwD0uETFpgK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAY5JQ/btsJj098b2S/UPJtfy7DlpnkwD0uETFpgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAY5JQ%2FbtsJj098b2S%2FUPJtfy7DlpnkwD0uETFpgK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;732&quot; height=&quot;97&quot; data-origin-width=&quot;1417&quot; data-origin-height=&quot;188&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부모 계층 즉 비즈니스 구조로 봤을 때 상사에게 Record를 공유할지 말지 정하는 Rule 설정이다. Grant Access Using Hierarchies를 설정 하냐 안하냐에 따라 공유 할지 말지 정한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Sharing Rule&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필드의 특정 값이 됐을 때 또는 특정 Role이 속한 사용자가 소유한 Record를 부모계층 외에도 다른 누군가(ex. CEO, CFO 특정 ROLE을 가진사람), 또는 다른 누군가들(&lt;b&gt;public group&lt;/b&gt;)에게 Record를 공유할 때 사용한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;728&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YyllQ/btsJi6QUwYY/FCE8rfNlogDjysfspj1mu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YyllQ/btsJi6QUwYY/FCE8rfNlogDjysfspj1mu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YyllQ/btsJi6QUwYY/FCE8rfNlogDjysfspj1mu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYyllQ%2FbtsJi6QUwYY%2FFCE8rfNlogDjysfspj1mu1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;473&quot; height=&quot;472&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;728&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Public Group&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Public group sharing을 사용 할 때 많이 사용 되면 사용자 그룹이다. 특정 user들을 그룹으로 관리하여 효율성을 증대시킨다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;336&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q9sCA/btsJlrMOyM5/G8mK09yQkYv6SlZTzvPork/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q9sCA/btsJlrMOyM5/G8mK09yQkYv6SlZTzvPork/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q9sCA/btsJlrMOyM5/G8mK09yQkYv6SlZTzvPork/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq9sCA%2FbtsJlrMOyM5%2FG8mK09yQkYv6SlZTzvPork%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;336&quot; height=&quot;280&quot; data-origin-width=&quot;336&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 User들을 Group 시켜서 관리를 하면 Sharing rule을 보다 쉽게 사용할 수 있다.&lt;/p&gt;
&lt;div style=&quot;display: flex; justify-content: center;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Manual Sharing&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Manual Sharing은 별다른 규칙 없이 해당 Object의 Record에 찾아가서 공유 하는 기능이다. 급할 때 쓰면 될듯 하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1873&quot; data-origin-height=&quot;737&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/u3V2i/btsJjzyhRrT/N9qWVxp4fTNyq32N5ohY4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/u3V2i/btsJjzyhRrT/N9qWVxp4fTNyq32N5ohY4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/u3V2i/btsJjzyhRrT/N9qWVxp4fTNyq32N5ohY4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fu3V2i%2FbtsJjzyhRrT%2FN9qWVxp4fTNyq32N5ohY4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;649&quot; height=&quot;255&quot; data-origin-width=&quot;1873&quot; data-origin-height=&quot;737&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Role과 Sharing을 통해서 계층구조에서 record가 어떻게 공유 되는 알아보았다. 그렇다면 User가 Object나 또는 특정 필드의 접근을 제어 하려면 어떻게 해야할까? 그때 사용하는 것이 Profile과 Permission Set이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Profile&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Profile은 User가 &lt;b&gt;Object에서 CRUD 권한을 설정 할 수 있고 더 나아가 filed 수준의 보안을 설정&lt;/b&gt; 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 Junior가 개발자가 새로운 회사에 입사했다고 생각을 해보자. 처음 하루동안 HR Object 에 들어가서 동료들의 이름, 닉네임, 팀명을 알아보라고 지시를 받았다. 이때 Junior 개발자는 HR Object를 Read만 해야하며 이름, 닉네임, 팀명 외의 Filed에는 Read 해서는 안된다. 이럴때 Profile을 설정해서 접근을 제어 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 &lt;b&gt;User를 생성할 때 Role과 함께 Profile을 설정&lt;/b&gt;해서 User를 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Profile을 만들때는 기존의 profile을 copy 해서 설정을 바꾸고 사용을 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1746&quot; data-origin-height=&quot;1539&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uPTZW/btsJjxVkhSa/HucnTNwiRVjdnpLLHsbpCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uPTZW/btsJjxVkhSa/HucnTNwiRVjdnpLLHsbpCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uPTZW/btsJjxVkhSa/HucnTNwiRVjdnpLLHsbpCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuPTZW%2FbtsJjxVkhSa%2FHucnTNwiRVjdnpLLHsbpCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;635&quot; height=&quot;560&quot; data-origin-width=&quot;1746&quot; data-origin-height=&quot;1539&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Permission Set&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Profile은 하나 만들어 놓으면 공유해서 사용을 하게 된다. 그러나 한명의 유저에 대해서 Object CRUD 권한과 Filed 접근을 변경 하려면 어떻게 해야할까? 그때 사용 하는 것이 Permission Set이다. 일종의 쪽집게 권한 설정이라고 생각하면 이해하기 쉽다. 그러나 Permission Set은 어디까지나 권한 추가지 Profile의 권한을 Mute 시킬 수는 없다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RqE5R/btsJkpbm3wh/MEkLQZVBmG7QrS0t6FQmR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RqE5R/btsJkpbm3wh/MEkLQZVBmG7QrS0t6FQmR1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RqE5R/btsJkpbm3wh/MEkLQZVBmG7QrS0t6FQmR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRqE5R%2FbtsJkpbm3wh%2FMEkLQZVBmG7QrS0t6FQmR1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;510&quot; height=&quot;400&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 User가 사용 할 수 있는 권한은 Profile 권한 + Permission Set 권한 이라고 할 수 있다.&lt;/p&gt;</description>
      <category>Salesforce</category>
      <category>permission set</category>
      <category>profile</category>
      <category>public group</category>
      <category>role</category>
      <category>salesforce</category>
      <category>Sharing</category>
      <author>독서, 운동 그리고 개발</author>
      <guid isPermaLink="true">https://ptcman.tistory.com/31</guid>
      <comments>https://ptcman.tistory.com/31#entry31comment</comments>
      <pubDate>Thu, 29 Aug 2024 16:30:37 +0900</pubDate>
    </item>
    <item>
      <title>Standard Object</title>
      <link>https://ptcman.tistory.com/30</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;562&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bK5ewP/btsJguD2reb/aTpsaf9P5YMusk4PllBlFK/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bK5ewP/btsJguD2reb/aTpsaf9P5YMusk4PllBlFK/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bK5ewP/btsJguD2reb/aTpsaf9P5YMusk4PllBlFK/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbK5ewP%2FbtsJguD2reb%2FaTpsaf9P5YMusk4PllBlFK%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;468&quot; height=&quot;263&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;562&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Salesforce를 경험해 볼 기회가 있어서 Trailhead를 따라 이것저것 만져보고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 DBA가 되어 제공해주는 예제 수준의 DB를 다양하게 시험해 봤다. DBMS 인것 같으면서 더존의 ERP 느낌도 물씬 났던 녀석이다. 무엇보다 DB 관점에서 본다면 기본적으로 제공을 해주는 기능들이 워낙 강력하여 별도 SQL이나 코딩 없이도 왠만하 기능을 구현 할 수 있었다. 무엇보다 이미 타겟 client가 기업이기 때문에 기업전용 기능을 제공을 하여 편하게 사용 할 수 있었다. 지금부터 이러한 Salesforce가 가지는 몇가지 특징을 살펴 보겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Standard Object&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;831&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c6cPSv/btsJfPIE7pA/H2KnVWPnnnRwRHQVhPi5c1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c6cPSv/btsJfPIE7pA/H2KnVWPnnnRwRHQVhPi5c1/img.png&quot; data-alt=&quot;부트캠프 프로젝트 시 릴레이션 스키마&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c6cPSv/btsJfPIE7pA/H2KnVWPnnnRwRHQVhPi5c1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6cPSv%2FbtsJfPIE7pA%2FH2KnVWPnnnRwRHQVhPi5c1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;569&quot; height=&quot;369&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;831&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;부트캠프 프로젝트 시 릴레이션 스키마&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부트캠프 과정에서 처음 인터넷 쇼핑몰을 만들때 작성했다 릴레이션 스키마이다. 당시 우리는 패션관련 쇼핑몰을 만들었고 다른 조들은 캠핑, 도서대여, 농산물 공동구매 등의 Identity를 살려서 프로젝트를 진행을 했지만 &lt;u&gt;&lt;b&gt;다른 조와 우리조의 ERD 또는 릴레이션 스키마를 봤을 때 그렇게 차이가 나는건 없었다. 왜일까?&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트의 주제는 달랐지만 결국에는 모두가 하나의 쇼핑몰이기 때문에 회원, 주문, 상품 등 의 관계가 크게 달라지지 않는 것이다. 당시 우리 과정에서 이러한 DB 설계에 주어진 시간은 약 일주일 이었다. 짧으면 짧고 길면 긴 시간이었지만 만일 실무에서 하나의 서비스를 처음부터 끝까지 만든다고 했을 때 DB 설계 비용도 만만치 않을것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 우리는 여기서 한가지 생각을 할 수가 있다. &lt;b&gt;만일&lt;u&gt; 공통적으로 사용하는 Entity를 미리 만들어 놓고 제공을 한다면&lt;/u&gt; 어떨까?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;세일즈포스는 이러한 점을 착안하여 기업에서 많이 사용하는 Entity(Salesforce에서는 Object라고 부른다) 제공한다. 그리고 이것이 Standard Object이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1236&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c6HkT1/btsJgJgxRGH/mvbzQ4zOxP9AKhJRfOp0mk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c6HkT1/btsJgJgxRGH/mvbzQ4zOxP9AKhJRfOp0mk/img.png&quot; data-alt=&quot;https://architect.salesforce.com/diagrams/data-models/sales-cloud/sales-cloud-overview&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c6HkT1/btsJgJgxRGH/mvbzQ4zOxP9AKhJRfOp0mk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6HkT1%2FbtsJgJgxRGH%2FmvbzQ4zOxP9AKhJRfOp0mk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;707&quot; height=&quot;437&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1236&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://architect.salesforce.com/diagrams/data-models/sales-cloud/sales-cloud-overview&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위는 Salesforce에서 기본적으로 제공하는 Standard Object의 관계도를 그린것이다. 복잡한 관계의 오브젝트를 미리 제공을 해줌으로써 개발자는 보다 쉽게 서비스를 구축 할 수 있게 됐다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_list.htm&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_list.htm&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1724738255571&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Standard Objects | Object Reference for the Salesforce Platform | Salesforce Developers&quot; data-og-description=&quot;&quot; data-og-host=&quot;developer.salesforce.com&quot; data-og-source-url=&quot;https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_list.htm&quot; data-og-url=&quot;https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_list.htm&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_list.htm&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_list.htm&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Standard Objects | Object Reference for the Salesforce Platform | Salesforce Developers&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.salesforce.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 링크는 salesforce에서 기본적으로 제공해주는 Standard Object이다. 이 모든걸 다 알면 좋겠지만 일단은 자주 쓰는 object가 뭐고 특징이 뭔지 살펴보자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Account&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비즈니스와 관련된 조직 또는 개인을 나타내는 object이다. 가장 기본이 되는 object로 다양한 object들과 관계를 맺고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 생각하면 company를 떠올렸을 때의 정보 filed 등이 있다. 인상 깊은 점은 모회사와 자회사 개념을 도입하기 위해 &lt;b&gt;부모 Account가 자식 Account와 1:N 관계를 맺어 질 수도 있다&lt;/b&gt;라는 점이다.&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Contact&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Account와 부모 자식의 계층적 Object이다. 해석하면 연락처지만, Account에서 일하는 사람이라고 기억하는게 더 쉽다. CRM 플랫폼 답게 &lt;span style=&quot;background-color: #ffffff; color: #181818; text-align: left;&quot;&gt;LastActivityDate, &lt;span style=&quot;background-color: #ffffff; color: #181818; text-align: left;&quot;&gt;LastReferencedDate, &lt;span style=&quot;background-color: #ffffff; color: #181818; text-align: left;&quot;&gt;LastViewedDate, &lt;span style=&quot;background-color: #ffffff; color: #181818; text-align: left;&quot;&gt;LeadSource 등의 필드가 인상싶다. Leadsource은 유입이 어떻게 됐는지이다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Opportunity&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한국말로 기회지만 단순 기회라고 생각하면 와닿지가 않는다. 일종의 계약 현황이라고 보면 이해가 훨씬 빠르다. StageName이라는 필드가 있어서 현재 잠재고객의 현황을 기록을 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pNu0o/btsJgzMexuU/1NNmDFnp16YRE6jUn0xLZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pNu0o/btsJgzMexuU/1NNmDFnp16YRE6jUn0xLZ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pNu0o/btsJgzMexuU/1NNmDFnp16YRE6jUn0xLZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpNu0o%2FbtsJgzMexuU%2F1NNmDFnp16YRE6jUn0xLZ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;619&quot; height=&quot;275&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들면&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;발견(Prospecting)&lt;/b&gt;: XYZ Corp가 ABC IT 솔루션에 연락을 하여 클라우드 전환 프로젝트에 대해 논의하기 시작함. 이 단계에서는 잠재 고객이 아직 확실히 구매할 의향이 있는지 모르는 상태입니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;요구사항 분석(Needs Analysis)&lt;/b&gt;: XYZ Corp의 IT 인프라 현황과 요구 사항을 분석한 후, 클라우드로 전환하는 데 필요한 사항들을 파악함.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;제안서 제출(Proposal/Price Quote)&lt;/b&gt;: XYZ Corp에 클라우드 전환 솔루션에 대한 제안서와 견적서를 제출함. 현재 예시에서는 이 단계에 해당함.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;협상 중(Negotiation/Review)&lt;/b&gt;: 현재 고객과의 협상이 진행 중이며, 가격이나 서비스 범위에 대한 조율이 이루어지고 있음.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Closed Won(계약 체결)&lt;/b&gt;: XYZ Corp와 계약을 성공적으로 체결하여, 클라우드 전환 프로젝트가 시작됨.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Closed Lost(계약 실패)&lt;/b&gt;: 경쟁업체가 이겼거나 고객이 구매를 보류한 경우로, 기회를 잃었음.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 이렇게 단계를 두어&lt;b&gt; probability 필드에 계약 성공률을 채워나간다&lt;/b&gt;. 이 Opportunity Object를 봄으로써 현재 회사의 영업 진행 상황을 알 수가 있게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 Salesforce 칸반보드 기능을 제공을 하기 때문에 각 Stage 별 상황을 한눈에 볼 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Lead&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lead object는 &lt;b&gt;잠재고객을 관리하는 object&lt;/b&gt;로써 Opportunity의 전단계라고 생각하면 이해하기 쉽다. 앞서 Opportunity object는 일종의 계약 진행상황이라고 표현했다. 이러한 계약을 진행을 하려면 사전의 물밑 작업을 해야한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A라는 영업사원이 **회사의 구매담당자 B에게 제품을 소개를 하면서 계약을 유도 했다라고 가정해보자. B는 A의 영업이 마음에 들어 계약을 하겠다고 A한테 의사표현을 하게 되면 A는 해당 Lead를 Account, Contact, Opportunity로 convert하게 된다. B는 영업의 기회가 되는 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;747&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/be8D8j/btsJi9edqLx/vmCDnZUVmPs14ZyYjuWnzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/be8D8j/btsJi9edqLx/vmCDnZUVmPs14ZyYjuWnzk/img.png&quot; data-alt=&quot;Lead를 Convert하게 되면 다음과 같이 3개의 Record를 생성하라고 나온다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/be8D8j/btsJi9edqLx/vmCDnZUVmPs14ZyYjuWnzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbe8D8j%2FbtsJi9edqLx%2FvmCDnZUVmPs14ZyYjuWnzk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;720&quot; height=&quot;328&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;747&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Lead를 Convert하게 되면 다음과 같이 3개의 Record를 생성하라고 나온다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 Lead object에서 To do list처럼 Task를 추가하여 잠재고객을 보다 쉽게 관리할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lead object는 Opportunity Object의 StageName처럼 단계를 표시하는 Status filed가 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1101&quot; data-origin-height=&quot;332&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vnqNX/btsJihpxRfF/tpnnafCoGyPbC1W1hNitLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vnqNX/btsJihpxRfF/tpnnafCoGyPbC1W1hNitLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vnqNX/btsJihpxRfF/tpnnafCoGyPbC1W1hNitLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvnqNX%2FbtsJihpxRfF%2FtpnnafCoGyPbC1W1hNitLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;737&quot; height=&quot;222&quot; data-origin-width=&quot;1101&quot; data-origin-height=&quot;332&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;New (신규)&lt;/b&gt;: 리드가 처음 들어온 상태.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Contacted (연락됨)&lt;/b&gt;: 연락을 시도했거나 대화가 시작된 상태.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Qualified (자격 확인)&lt;/b&gt;: 고객으로 전환할 가능성이 있다고 판단된 상태.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Closed (종료)&lt;/b&gt;: 자격이 없거나 구매 의사가 없어 리드가 종료된 상태.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만일 다음과 같은 Status가 있고 현 Lead object의 record의 status가 &lt;b&gt;Qualified&lt;span&gt;&lt;b&gt;(자격 확인)&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;라 &lt;/span&gt;&lt;span&gt;한다면 Account, Contact, Opportunity로 Convert하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Contract&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Opportunity object가 계약현황을 의미한다고 했으면 Contract는 어떤 Object일까? Contract Object는 실제로 법적 구속력을 갖는 필드를 가지고 있는 object이다.&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ActivatedDate : 계약서가 언제 활성화 됐는지,&lt;/li&gt;
&lt;li&gt;CompanySignedDate : 회사 사인 날짜&lt;/li&gt;
&lt;li&gt;ContractTerm :&amp;nbsp; 계약서 유효기간&lt;/li&gt;
&lt;li&gt;CustomerSignedDate : 고객 사인 날짜&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;등 구체적인 term과 날짜를 명시하는 필드들로 구성이 되어 있다. 즉 Opportunity에서 성공적으로 stage가 done이 되면 그 이후에 Contract 단계를 진행해서 record에 기록을 한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Asset과 Case&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 Asset은 기업의 재무제표나오는 자산이 아닌 &lt;b&gt;본 기업으로부터 구매한 소프트웨어나 자동차, PC 등의 물품을 의미&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만일 Account가 우리 회사로부터 A라는 소프트웨어를 구입을 했다라고 가정해보자. 가장 베스트는 문제가 없는거지만 이 A라는 소프트웨어에 다양한 문제가 발생 할 수가 있다. 이러한 &lt;b&gt;문제 사례를 Case object에 기록&lt;/b&gt;하게 된다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 Asset에 N개의 Case가 나올 수 있으며로 Asset과 Case는 1:N 관계이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;284&quot; data-origin-height=&quot;675&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LBU0J/btsJguElvVX/o4RHUVudEPhWpkPKA4K93k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LBU0J/btsJguElvVX/o4RHUVudEPhWpkPKA4K93k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LBU0J/btsJguElvVX/o4RHUVudEPhWpkPKA4K93k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLBU0J%2FbtsJguElvVX%2Fo4RHUVudEPhWpkPKA4K93k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;284&quot; height=&quot;675&quot; data-origin-width=&quot;284&quot; data-origin-height=&quot;675&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Case 같은 경우 에스컬레이션 조건이라든지 대기열 생성 기능을 Salesforce에서 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Salesforce</category>
      <category>salesforce</category>
      <category>standard object</category>
      <author>독서, 운동 그리고 개발</author>
      <guid isPermaLink="true">https://ptcman.tistory.com/30</guid>
      <comments>https://ptcman.tistory.com/30#entry30comment</comments>
      <pubDate>Tue, 27 Aug 2024 14:46:02 +0900</pubDate>
    </item>
    <item>
      <title>JVM이란?</title>
      <link>https://ptcman.tistory.com/29</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;자바의 가장 큰 특징 하나만 말하라고 하면 뭐가 있을까? 바로 &lt;b&gt;플랫폼 독립적&lt;/b&gt;이라는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;플랫폼에 종속된 경우&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; href=&quot;https://namu.wiki/w/Microsoft%20Windows&quot; data-v-ca152052=&quot;&quot;&gt;윈도우&lt;/a&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;에서 빌드한 프로그램을 그대로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; href=&quot;https://namu.wiki/w/Linux&quot; data-v-ca152052=&quot;&quot;&gt;리눅스&lt;/a&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;나&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; href=&quot;https://namu.wiki/w/macOS&quot; data-v-ca152052=&quot;&quot;&gt;macOS&lt;/a&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;에서 실행하는 것은 불가능하다. 반면 Java로 작성된 프로그램은 플랫폼에 맞는 자바 가상 머신만 설치되어 있다면 대체로 문제없이 동작한다. 이는 바이트 코드가 플랫폼이 아닌&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; href=&quot;https://namu.wiki/w/%EC%9E%90%EB%B0%94%20%EA%B0%80%EC%83%81%20%EB%A8%B8%EC%8B%A0&quot; data-v-ca152052=&quot;&quot;&gt;자바 가상 머신&lt;/a&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;에서 실행가능하며, 프로그램 실행의 주체가 운영 체제가 아닌 자바 가상 머신이기 때문이다. 이러한 점을 일컬어 플랫폼에 독립적이라고 한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;그럼 Java는 어떻게 플랫폼에 독립적일 수 있을까? 바로 JVM이 있기 때문이다.&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #212529;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;JVM은 어디에 위치해 있을까?&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;860&quot; data-origin-height=&quot;510&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SomqP/btsJaZYZ9IJ/s2azvE85KSxCC5jrzmvtF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SomqP/btsJaZYZ9IJ/s2azvE85KSxCC5jrzmvtF1/img.png&quot; data-alt=&quot;널널한 개발자 유튜브 자료 중 일부&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SomqP/btsJaZYZ9IJ/s2azvE85KSxCC5jrzmvtF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSomqP%2FbtsJaZYZ9IJ%2Fs2azvE85KSxCC5jrzmvtF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;860&quot; height=&quot;510&quot; data-origin-width=&quot;860&quot; data-origin-height=&quot;510&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;널널한 개발자 유튜브 자료 중 일부&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터의 구조를 이렇게 3개의 계층으로 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보게 되면 JVM이 user mode Application 단에 존재하는 것을 볼 수 있다. 즉 Mac이든 Winodows든 Linux든 각 운영체제에 맞는 jvm만 설치 되어 있으면 그 위에서는 운영체제와 상관 없이 빌드 후 실행을 할 수 있는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Java 프로그램 실행순서&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;325&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGDbrp/btsJc2Gehm7/nFhRKKQH6oCAbqG0Kc3Js0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGDbrp/btsJc2Gehm7/nFhRKKQH6oCAbqG0Kc3Js0/img.png&quot; data-alt=&quot;https://hoehen-flug.tistory.com/m/46&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGDbrp/btsJc2Gehm7/nFhRKKQH6oCAbqG0Kc3Js0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGDbrp%2FbtsJc2Gehm7%2FnFhRKKQH6oCAbqG0Kc3Js0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;569&quot; height=&quot;325&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;325&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://hoehen-flug.tistory.com/m/46&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘은 IDE로 편하게 Java 파일들을 컴파일 하지만 cli 프로그램 하나씩 컴파일 해본다고 가정을 gkwk&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. MyProgram.java 라는 파일을 컴파일 하려면 javac 이라는 명령을 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1724315076200&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;javac MyProgram.java&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 MyProgram.class 라는 파일이 만들어지게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나의 자바 소스 파일이 class 파일이 되면서 JVM 읽기 쉽게 bytecode화 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. MyProgram.class를 실행해보자&lt;/p&gt;
&lt;pre id=&quot;code_1724315178970&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;java MyProgram&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;class 파일을 실행하면 본격적으로 이 class 파일이 jvm에 올라가게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. &lt;b&gt;클래스 로더 시스템 (Class Loader System)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;클래스 로딩&lt;/b&gt;: java MyProgram 명령어를 입력하면, JVM의 클래스 로더는 &lt;b&gt;MyProgram.class&lt;/b&gt; 파일을 찾아서 메모리로 로드합니다. 이때, 해당 클래스가 사용하려는 &lt;b&gt;다른 클래스들&lt;/b&gt;(예: 표준 라이브러리 클래스, 사용자가 정의한 다른 클래스들)도 필요에 따라 동적으로 로드됩니다.&lt;/li&gt;
&lt;li&gt;클래스 로더는 다음과 같은 클래스들을 차례로 로드합니다:
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Bootstrap Class Loader&lt;/b&gt;: 가장 기본적인 자바 런타임 라이브러리(rt.jar에 포함된 클래스)를 로드합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Extension Class Loader&lt;/b&gt;: 확장 라이브러리를 로드합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Application Class Loader&lt;/b&gt;: 사용자가 작성한 자바 애플리케이션의 클래스들을 로드합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. &lt;b&gt;바이트코드 검증 (Bytecode Verification)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM은 로드된 &lt;b&gt;바이트코드의 유효성&lt;/b&gt;을 검증하는 과정을 거칩니다. 검증 작업은 프로그램이 불법적인 명령을 수행하려 하거나, 메모리 안전성을 위협하는 행동을 하지 않는지 확인하는 작업입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;바이트코드가 &lt;b&gt;문법적으로 유효한지&lt;/b&gt;,&lt;/li&gt;
&lt;li&gt;메모리 액세스나 타입 캐스팅이 &lt;b&gt;올바른지&lt;/b&gt; 검증합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 검증 과정을 통해 잘못된 바이트코드로 인해 시스템이 무너지는 것을 방지합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. &lt;b&gt;Runtime Data Area에 메모리 할당&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;335&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biy4vO/btsJcRyeSPQ/998nQpwPp09pgxKYfSKfRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biy4vO/btsJcRyeSPQ/998nQpwPp09pgxKYfSKfRk/img.png&quot; data-alt=&quot;https://github.com/devFancy/2023-CS-Study/blob/main/java/java_jvm_architecture.md&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biy4vO/btsJcRyeSPQ/998nQpwPp09pgxKYfSKfRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbiy4vO%2FbtsJcRyeSPQ%2F998nQpwPp09pgxKYfSKfRk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;335&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;335&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://github.com/devFancy/2023-CS-Study/blob/main/java/java_jvm_architecture.md&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스 로딩과 검증이 끝나면, JVM은 프로그램을 실행하기 위해 &lt;b&gt;Runtime Data Area&lt;/b&gt;에 필요한 메모리 공간을 할당합니다. JVM의 Runtime Data Area는 다음과 같은 메모리 구조로 나뉩니다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Method Area (메소드 영역)&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;로드된 클래스의 메타데이터, 클래스 변수, 메서드의 바이트코드, 상수 풀 등이 저장됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Heap (힙 메모리)&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램에서 생성되는 &lt;b&gt;객체 인스턴스&lt;/b&gt;들이 저장되는 영역입니다. 객체는 여기에 할당되고 가비지 컬렉션에 의해 관리됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;JVM Stack (스택 메모리)&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 스레드마다 &lt;b&gt;메서드 호출 스택&lt;/b&gt;이 생성되며, 메서드 호출 시마다 &lt;b&gt;스택 프레임&lt;/b&gt;이 생성됩니다. 각 프레임에는 해당 메서드의 &lt;b&gt;지역 변수&lt;/b&gt;와 &lt;b&gt;연산 중간 결과&lt;/b&gt; 등이 저장됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;PC 레지스터 (Program Counter Register)&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 스레드가 현재 실행 중인 &lt;b&gt;바이트코드 명령어의 주소&lt;/b&gt;를 기록하는 곳입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Native Method Stack&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JVM 외부의 네이티브 코드를 호출할 때 사용되는 스택입니다. 예를 들어, 자바가 C로 작성된 네이티브 라이브러리를 호출할 때 사용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. &lt;b&gt;인터프리터(Interpreter) 또는 JIT 컴파일러(JIT Compiler)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM은 &lt;b&gt;바이트코드를 한 명령어씩 읽고 실행&lt;/b&gt;하는데, 이를 담당하는 것이 **인터프리터(Interpreter)**입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인터프리터는 &lt;b&gt;바이트코드를 해석&lt;/b&gt;하여 CPU가 실행할 수 있는 명령어로 변환하고 즉시 실행합니다.&lt;/li&gt;
&lt;li&gt;하지만 인터프리터 방식만으로는 성능이 떨어질 수 있기 때문에, JVM은 **JIT 컴파일러(Just-In-Time Compiler)**를 통해 자주 실행되는 바이트코드를 &lt;b&gt;기계어로 변환&lt;/b&gt;해 성능을 최적화합니다. 변환된 기계어는 이후 실행될 때 해석 없이 빠르게 실행됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. &lt;b&gt;실행 (Execution)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM은 바이트코드를 읽고 실행하며, 이 과정에서 다음과 같은 일이 일어납니다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Main 메서드 실행&lt;/b&gt;: MyProgram.class 파일의 &lt;b&gt;main() 메서드&lt;/b&gt;가 실행됩니다. 이 메서드는 자바 프로그램의 진입점이며, 여기서부터 프로그램이 실행됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;스택 프레임 생성 및 관리&lt;/b&gt;: 메서드가 호출될 때마다 JVM 스택에 &lt;b&gt;스택 프레임&lt;/b&gt;이 생성됩니다. 각 스택 프레임에는 메서드의 &lt;b&gt;지역 변수&lt;/b&gt;와 &lt;b&gt;실행 중간 결과&lt;/b&gt; 등이 저장됩니다. 메서드 호출이 끝나면 해당 스택 프레임은 스택에서 제거됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;객체 생성 및 관리&lt;/b&gt;: new 키워드를 통해 객체를 생성할 때마다 &lt;b&gt;힙 메모리&lt;/b&gt;에 객체가 생성됩니다. JVM은 이러한 객체들의 메모리 사용을 추적하며, 필요하지 않게 된 객체를 가비지 컬렉션을 통해 정리합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6. &lt;b&gt;가비지 컬렉션 (Garbage Collection)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM은 힙 메모리에서 더 이상 사용되지 않는 객체들을 자동으로 제거하는 **가비지 컬렉터(Garbage Collector)**를 실행합니다. 가비지 컬렉션은 메모리 누수를 방지하고, 불필요한 메모리 사용을 줄여 성능을 최적화하는 데 중요한 역할을 합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 시점마다 JVM은 참조되지 않는 객체들을 찾아 메모리에서 해제합니다.&lt;/li&gt;
&lt;li&gt;개발자는 메모리 해제 작업을 직접 수행할 필요 없이 JVM에 맡기면 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7. &lt;b&gt;프로그램 종료 (Termination)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램이 종료되면, JVM은 실행 중이던 모든 스레드를 종료하고 사용했던 메모리를 반환합니다. 이 과정에서 다음 일이 발생합니다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;main() 메서드가 종료&lt;/b&gt;되면, JVM은 모든 실행 중인 사용자 스레드가 완료되었는지 확인합니다.&lt;/li&gt;
&lt;li&gt;사용자 스레드가 모두 종료되면 JVM은 종료되고, 운영체제로부터 JVM이 사용했던 자원을 해제합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;느낌점&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 지금까지는 이러한 컴파일 과정을 생각하지 않고 사용을 해왔다. 앞으로 실무를 경험을 할 때는 많은 트러블 이슈들을 접하게 될 텐데 그때 JVM 작동원리를 모르면 대응이 어려울 것이다. 앞으로도 공부 할때 단순 기능구현만 집중하는 것이 아닌 이처럼 어떻게 동작하는 원리는 뭔지 살펴보겠다. 아울러 MyProgram.class 파일을 내부적으로 살펴 볼 수 있다면 더 도움이 될것 같다.&lt;/p&gt;</description>
      <category>JAVA</category>
      <author>독서, 운동 그리고 개발</author>
      <guid isPermaLink="true">https://ptcman.tistory.com/29</guid>
      <comments>https://ptcman.tistory.com/29#entry29comment</comments>
      <pubDate>Thu, 22 Aug 2024 17:38:11 +0900</pubDate>
    </item>
    <item>
      <title>DBCP란??</title>
      <link>https://ptcman.tistory.com/28</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;562&quot; data-origin-height=&quot;233&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/emBEPB/btsI6feBDDj/CQ3NRQLcEWUNL1eDbok9Kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/emBEPB/btsI6feBDDj/CQ3NRQLcEWUNL1eDbok9Kk/img.png&quot; data-alt=&quot;https://docs.aws.amazon.com/whitepapers/latest/serverless-multi-tier-architectures-api-gateway-lambda/three-tier-architecture-overview.html&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/emBEPB/btsI6feBDDj/CQ3NRQLcEWUNL1eDbok9Kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FemBEPB%2FbtsI6feBDDj%2FCQ3NRQLcEWUNL1eDbok9Kk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;562&quot; height=&quot;233&quot; data-origin-width=&quot;562&quot; data-origin-height=&quot;233&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://docs.aws.amazon.com/whitepapers/latest/serverless-multi-tier-architectures-api-gateway-lambda/three-tier-architecture-overview.html&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; Web 서비스를 하나 만든다라고 생각을 해봤을 때 Client와 Server는 HTTP로 서로 통신을 할 것이다. 만일 RESTFul APi 로 구성을 했다라고 하면 Server는 JSON 형식의 데이터를 보낼것이고 Client는 그 JSON형식을 데이터를 통해선 화면을 렌더링 할것이다. 그렇다면 &lt;b&gt;Server와 Data가 있는 DB는 어떻게 통신을 할까?&lt;/b&gt; SpringBoot 프로젝트를 몇가지 진행을 하면서 무지성으로 HikariCP를 써왔는데 이번 글에서는 HikariCP가 관리하는 DBCP란 무엇인지 살펴보도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Server와 DB는 어떻게 통신을 하는가?&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;797&quot; data-origin-height=&quot;624&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WXDwC/btsI4pXkpe4/A09BED25qTKCnJkpNv6mR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WXDwC/btsI4pXkpe4/A09BED25qTKCnJkpNv6mR0/img.png&quot; data-alt=&quot;https://hyuntaeknote.tistory.com/12&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WXDwC/btsI4pXkpe4/A09BED25qTKCnJkpNv6mR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWXDwC%2FbtsI4pXkpe4%2FA09BED25qTKCnJkpNv6mR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;619&quot; height=&quot;485&quot; data-origin-width=&quot;797&quot; data-origin-height=&quot;624&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://hyuntaeknote.tistory.com/12&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 WAS와 DB는 DB 드라이버를 거쳐 서로 TCP 통신을 하게 된다. TCP의 장점은 연결 지향적이고 packet의 순서의 신뢰를 보장하는 등 다양한 장점이 있지만 기본적으로 한번 연결을 구성하기 위한 3way handshake의 비용이 너무 크다. 오죽하면 HTTP/3 에서는 이러한 TCP를 버리고 UDP로 구성을 했을까.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java의 경우 JDBC를 활용하여 SQL 문구 하나를 보낼 때 마다 다음과 같이 Connection 객체를 생성을 해서 DB에 보내야한다. 이렇게 되면 Connection 객체를 만드는것도 비용이고 DB와 연결하기 위해 3way hanshake를 하는 것도 비용이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;밑에 링크는 MySql에서 insert문을 실행할 때 드는 비용을 나타낸 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://dev.mysql.com/doc/refman/8.0/en/insert-optimization.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://dev.mysql.com/doc/refman/8.0/en/insert-optimization.html&lt;/a&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1723718501392&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class JdbcExample {
    public static void main(String[] args) {
        // 데이터베이스 연결 정보를 설정합니다.
        String jdbcUrl = &quot;jdbc:mysql://localhost:3306/mydatabase&quot;;  // DB URL
        String username = &quot;root&quot;;                                   // DB 사용자 이름
        String password = &quot;password&quot;;                               // DB 비밀번호
        
        // 데이터베이스 연결을 위한 변수 선언
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;

        try {
            // 1. 데이터베이스 연결 생성
            connection = DriverManager.getConnection(jdbcUrl, username, password);
            System.out.println(&quot;데이터베이스에 성공적으로 연결되었습니다!&quot;);

            // 2. Statement 객체 생성
            statement = connection.createStatement();
            
            // 3. SQL 쿼리 실행
            String sql = &quot;SELECT id, name, email FROM users&quot;;  // 예시 쿼리
            resultSet = statement.executeQuery(sql);

            // 4. 결과 처리
            while (resultSet.next()) {
                int id = resultSet.getInt(&quot;id&quot;);
                String name = resultSet.getString(&quot;name&quot;);
                String email = resultSet.getString(&quot;email&quot;);

                System.out.println(&quot;ID: &quot; + id + &quot;, Name: &quot; + name + &quot;, Email: &quot; + email);
            }
        } catch (Exception e) {
            e.printStackTrace();  // 예외 처리
        } finally {
            // 5. 리소스 해제
            try {
                if (resultSet != null) resultSet.close();
                if (statement != null) statement.close();
                if (connection != null) connection.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;DBCP(DataBase Connection Pool)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Connection 객체를 만드는것도 비용이고 3way hanshake를 하는것도 비용이라면 어떻게 해야할까? &lt;b&gt;이 모든 것을 WAS가 DB에 보내기전 미리 생성을 하고 연결을 해놓으면 된다&lt;/b&gt;. 이것이 바로 DBCP의 개념이다. 그리고 Springboot에서 dbcp를 관리해주는 라이브러리가 HikariCP다. 우리 개발자들은 이렇게 힘써주신 선배개발자 덕에 편하게 개발을 할 수 있게 됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;613&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGaleu/btsI4vptXUM/8193lSTAWkoCYYcBcaGkD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGaleu/btsI4vptXUM/8193lSTAWkoCYYcBcaGkD0/img.png&quot; data-alt=&quot;https://www.digitalocean.com/community/tutorials/connection-pooling-in-java&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGaleu/btsI4vptXUM/8193lSTAWkoCYYcBcaGkD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGaleu%2FbtsI4vptXUM%2F8193lSTAWkoCYYcBcaGkD0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;596&quot; height=&quot;357&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;613&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://www.digitalocean.com/community/tutorials/connection-pooling-in-java&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 처음 WAS가 실행 될때 여러개의 Connection을 만들어 놓게 되면 훨씬 더 빠르게 DB에 접근을 할 수 있게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 부트캠프에서는 딱 이정도 수준에서까지만 배움을 마무리 했지만, 실무라고 생각을 해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DBCP의 크기를 얼마만큼해야 좋을 것이며 DB입장에서는 Connection을 몇개까지 허용을 해야 좋을것이며... 실무적으로 봤을 때 생각할것이 굉장히 많아진다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;DBCP 중요 파라미터&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 실무를 경험을 해보진 않았지만, WAS와 DB 입장에서 DBCP 관련 중요 파라미터가 어떤것들이 있는지 GPT를 활용해서 살펴보자&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. &lt;b&gt;DB(Database) 입장에서 중요한 파라미터&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1.1 &lt;b&gt;Max Connections (최대 커넥션 수)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;설명&lt;/b&gt;: 데이터베이스가 동시에 허용할 수 있는 최대 커넥션 수입니다. 이 수치를 초과하는 연결 시도는 대기하거나 실패합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;중요성&lt;/b&gt;: 너무 적으면 애플리케이션이 필요할 때 충분한 연결을 받지 못하고, 너무 많으면 데이터베이스가 과부하에 걸릴 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최적화 포인트&lt;/b&gt;: 데이터베이스 서버의 하드웨어 리소스(CPU, 메모리)에 맞춰 설정해야 하며, 애플리케이션의 요청 패턴을 분석하여 적정 수치를 설정합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1.2 &lt;b&gt;Idle Timeout (유휴 시간)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;설명&lt;/b&gt;: 일정 시간 동안 사용되지 않는 커넥션을 데이터베이스에서 끊는 시간 설정입니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;중요성&lt;/b&gt;: 커넥션이 너무 오래 유휴 상태로 유지되면, 데이터베이스 자원을 불필요하게 점유할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최적화 포인트&lt;/b&gt;: 적절한 유휴 시간을 설정하여 데이터베이스 연결을 적시에 반환하고, 불필요한 커넥션을 해제하여 자원을 최적화합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1.3 &lt;b&gt;Connection Lifetime (커넥션 수명)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;설명&lt;/b&gt;: 특정 시간 이상 경과된 커넥션을 강제로 닫고, 새 커넥션으로 교체합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;중요성&lt;/b&gt;: 장시간 유지된 연결이 네트워크 문제나 DB 서버의 재시작 후에도 남아있는 경우를 방지합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최적화 포인트&lt;/b&gt;: 커넥션이 너무 자주 끊기지 않도록 적절한 시간 설정이 필요합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. &lt;b&gt;WAS(Web Application Server) 입장에서 중요한 파라미터&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.1 &lt;b&gt;Initial Size (초기 커넥션 수)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;설명&lt;/b&gt;: WAS가 시작할 때 초기화하는 커넥션의 수입니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;중요성&lt;/b&gt;: 초기 요청에 대한 대응 속도에 영향을 줍니다. 적절한 초기 커넥션 수를 설정해야 애플리케이션 부하를 감당할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최적화 포인트&lt;/b&gt;: 예상되는 초기 트래픽에 맞춰 적정 수를 설정하되, 너무 많이 설정하면 불필요한 자원을 차지할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.2 &lt;b&gt;Max Total (최대 커넥션 풀 크기)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;설명&lt;/b&gt;: 애플리케이션에서 동시에 열 수 있는 커넥션의 최대 수입니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;중요성&lt;/b&gt;: 요청이 급증할 때 WAS가 얼마나 많은 커넥션을 관리할 수 있는지 결정합니다. 이 값을 너무 낮게 설정하면 애플리케이션이 커넥션을 기다리는 시간이 길어질 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최적화 포인트&lt;/b&gt;: WAS 서버의 메모리와 CPU 성능을 고려하여 적절한 값을 설정하고, 데이터베이스가 처리할 수 있는 최대 연결 수와 맞춰야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.3 &lt;b&gt;Max Idle (최대 유휴 커넥션 수)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;설명&lt;/b&gt;: 풀에 남겨질 수 있는 최대 유휴 커넥션의 수입니다. 이 수를 초과하면 유휴 커넥션은 풀에서 제거됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;중요성&lt;/b&gt;: 사용하지 않는 커넥션이 너무 많으면 리소스 낭비가 발생할 수 있습니다. 반면, 적절한 유휴 커넥션 수를 유지하면 성능 향상에 기여합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최적화 포인트&lt;/b&gt;: 적절한 수준의 유휴 커넥션을 유지하여 자원 낭비를 방지하고, 필요할 때 커넥션을 빠르게 재사용할 수 있게 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.4 &lt;b&gt;Min Idle (최소 유휴 커넥션 수)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;설명&lt;/b&gt;: 풀에서 유지할 최소 유휴 커넥션의 수입니다. 이 수만큼은 항상 커넥션을 유지하고 있어야 합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;중요성&lt;/b&gt;: 갑작스런 요청 증가에 대비하기 위한 최소 커넥션 수를 설정합니다. 너무 적으면 새로운 커넥션을 만드느라 시간이 걸릴 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최적화 포인트&lt;/b&gt;: WAS가 효율적으로 새로운 커넥션을 생성할 수 있도록, 예상되는 요청량에 맞춰 적정 수를 설정합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.5 &lt;b&gt;Connection Timeout (커넥션 타임아웃)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;설명&lt;/b&gt;: 애플리케이션에서 커넥션을 요청할 때, 사용 가능한 커넥션을 얻기까지 대기하는 최대 시간입니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;중요성&lt;/b&gt;: 커넥션을 얻는 데 너무 오래 걸리면 요청 처리에 지연이 발생하고, 성능 저하로 이어질 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최적화 포인트&lt;/b&gt;: 커넥션을 얻지 못했을 때 빠르게 대처할 수 있도록 적절한 시간 설정이 필요합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;느낌점&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 이렇게 파라미터를 정리 했지만 실제로 서비스를 운영하면서 대용량 트래픽을 느껴보지 않으면 와닿지가 않는다. 내가 만일 실무를 한다라고 하면 nGrinder 등 다양한 부하 테스트 툴을 이용을 해서 상황에 적절한 답을 찾아야 할것같다.&lt;/p&gt;</description>
      <category>CS/DB</category>
      <category>db 커넥션풀</category>
      <category>dbcp</category>
      <category>커넥션풀</category>
      <author>독서, 운동 그리고 개발</author>
      <guid isPermaLink="true">https://ptcman.tistory.com/28</guid>
      <comments>https://ptcman.tistory.com/28#entry28comment</comments>
      <pubDate>Thu, 15 Aug 2024 20:15:08 +0900</pubDate>
    </item>
  </channel>
</rss>