<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>exp_blog</title>
    <link>https://syujisu.tistory.com/</link>
    <description>공부하고 정리하는 것을 좋아합니다 : )</description>
    <language>ko</language>
    <pubDate>Sun, 5 Apr 2026 09:47:47 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>exp9405</managingEditor>
    <item>
      <title>[Golang]Method</title>
      <link>https://syujisu.tistory.com/entry/GolangMethod%EC%9E%91%EC%84%B1%EC%A4%91</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;메서드에 대한 컨벤션&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메서드 정의 시 Go에서는 아래와 같은 컨벤션을 일반적으로 따른다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&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;li&gt;변수는 하나의 글자로만 선언한다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;밸류 vs 포인터 선언
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;값을 변경할 필요가 없는 경우에는 배류 리시버로 선언해야 하지만, 통일성을 위해서 밸류와 포인터를 섞어서 선언하지 않고 포인터로 선언한다 (참고 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;Head First Go)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Pointer Receiver&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Value Receiver&amp;nbsp; : 메서드 사용 시 새로운 객체를 생성할 필요가 있으면 값 타입 메서드&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Pointer Receiver : 메서드 사용 시 새로운 객체 생성이 아니라 값을 참조해와야하면 포인트 타입 메서드&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용하는 이유는
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;메서드가 리시버가 가리키는 값을 수정할 수 있음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;각각의 메서드 call에서의 value 복사 문제를 피하기 위해서&amp;nbsp;&lt;br /&gt;=&amp;gt; 리시버가 큰 구조체라면 이것은 더 효율적일 수 있음&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1670998415460&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package method_interface

import &quot;fmt&quot;

// 메서드 사용 시 새로운 객체를 생성할 필요가 있으면 값 타임 메서드
// 메서드 사용 시 새로운 객체를 생성할 필요가 있으면 포인트 타입 메서드

type Person struct {
	Name string
	Age  int
}

func (p *Person) AddAge() {
	p.Age += 1 // value receiver
}

type Temperature float64

func (t Temperature) Up(temp float64) Temperature {
	return t + Temperature(temp) // pointer receiver
}

func Main2() {
	p1 := Person{Name: &quot;Rob&quot;, Age: 4}

	fmt.Println(&quot;P1: &quot;, p1)
	p1.AddAge()
	fmt.Println(&quot;P1: &quot;, p1)

	t := Temperature(30.0)

	fmt.Println(&quot;T: &quot;, t)
	t = t.Up(4.0)
	fmt.Println(&quot;T: &quot;, t)
}

package main

func main(){
	method_interface.Main2()
}&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;Pointer Indirection / dereference (메서드와 포인트 역참조)&lt;/h2&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;/li&gt;
&lt;li&gt;메서드의 리시버 인자의 경우에는 포인터와 밸류 인자 둘 다 받을 수 있다&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;포인터 인자가 밸류일때?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #37292c;&quot;&gt;area(r *Rectangle) 함수의 인자는 포인터 인자로 선언되어 밸류 값을 넘기면 컴파일 오류가 발생하고 포인터 인자만을 넘길 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1671005666496&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func area(r *Rectangle) {
	fmt.Println(r.height * r.width)
}

func Example_Indirection_Func_Pointer_Parameter() {
	r := Rectangle{
		height: 10,
		width:  3,
	}

	//area(r) //컴파일 오류 - 함수는 포인터 인자만 받을 수 있음
	area(&amp;amp;r)

	//Output:
	//30
}&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;&lt;span style=&quot;color: #37292c;&quot;&gt;r.area(), r은 포인터가 아닌 밸류 값이지만, 포인터 리시버 인자의 메서드가 호출될 때 &lt;br /&gt;Go에서 자동으로 r.area() -&amp;gt; (&amp;amp;r).area()로 해석을 해서 실행&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1671005714419&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func (r *Rectangle) area() {
	fmt.Println(r.height * r.width)
}

func Example_Indirection_Method_Pointer_Receiver() {
	r := Rectangle{
		height: 10,
		width:  3,
	}

	r.area()
	(&amp;amp;r).area()

	//Output:
	//30
	//30

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;리시버 인자가 밸류일때?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;perimeter(r Rectangle)&lt;span style=&quot;color: #37292c;&quot;&gt;&amp;nbsp;함수는 밸류 인자로 선언되어&amp;nbsp;&lt;/span&gt;perimeter(&amp;amp;r)&lt;span style=&quot;color: #37292c;&quot;&gt;&amp;nbsp;포인터 값을 인자로 넘겨주면 컴파일 오류가 발생&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1671005894884&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func perimeter(r Rectangle) {
	fmt.Println(2 * (r.height * r.width))
}

func Example_Indirection_Func_Value_Parameter() {
	r := Rectangle{
		height: 10,
		width:  3,
	}

	//perimeter(&amp;amp;r) //컴파일 오류 - 함수는 value 인자만 받을 수 있음
	perimeter(r)

	//Output:
	//60
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #37292c;&quot;&gt;리시버 인자의 경우, (&amp;amp;r).perimeter() 호출 시 Go는 리시버 인자는 밸류 인자로 선언되어 (*r).perimeter()로 자동으로 해석해서 실행&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1671005914599&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func (r Rectangle) perimeter() {
	fmt.Println(2 * (r.height * r.width))
}

func Example_Indirection_Method_Value_Receiver() {
	r := Rectangle{
		height: 10,
		width:  3,
	}

	r.perimeter()
  (&amp;amp;r).perimeter()

	//Output:
	//60
	//60
}&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;메서드는 함수에 리시버 인자를 추가한 버전으로 이해하는 걸로 하자&amp;nbsp;&lt;/p&gt;</description>
      <category>Language Study/Go</category>
      <category>golang</category>
      <category>golang method</category>
      <category>method receiever</category>
      <category>pointer</category>
      <category>VALUE</category>
      <author>exp9405</author>
      <guid isPermaLink="true">https://syujisu.tistory.com/215</guid>
      <comments>https://syujisu.tistory.com/entry/GolangMethod%EC%9E%91%EC%84%B1%EC%A4%91#entry215comment</comments>
      <pubDate>Wed, 14 Dec 2022 15:47:49 +0900</pubDate>
    </item>
    <item>
      <title>[Golang]Quick sort(퀵 정렬)</title>
      <link>https://syujisu.tistory.com/entry/GolangQuick-sort%ED%80%B5-%EC%A0%95%EB%A0%AC</link>
      <description>&lt;h2 id=&quot;퀵-정렬quick-sort-알고리즘의-개념-요약&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;퀵 정렬(quick sort) 알고리즘&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;오름차순 정렬&lt;/span&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;퀵 정렬은 불안정 정렬 에 속하며, 다른 원소와의 비교만으로 정렬을 수행하는 비교 정렬에 속한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;분할 정복 알고리즘의 하나로, 평균적으로 매우 빠른 수행 속도를 자랑하는 정렬 방법&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;합병 정렬(merge sort)과 달리 퀵 정렬은 리스트를 비균등하게 분할한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;분할 정복(divide and conquer) 방법&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;문제를 작은 2개의 문제로 분리하고 각각을 해결한 다음, 결과를 모아서 원래의 문제를 해결하는 전략이다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;분할 정복 방법은 대개 순환 호출을 이용하여 구현한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;하나의 리스트를 피벗(pivot) 을 지정하여 그를 기준으로 두 개의 비균등한 크기로 분할하고,&amp;nbsp;&lt;br /&gt;분할된 부분 리스트를 정렬 -&amp;gt; 두 개의 정렬된 부분 리스트를 합하여 전체가 정렬된 리스트가 되게 한다.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;단계&lt;/span&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;분할(Divide): 입력 배열을 피벗을 기준으로 비균등하게 2개의 부분 배열(피벗을 중심으로 왼쪽: 피벗보다 작은 요소들, 오른쪽: 피벗보다 큰 요소들)로 분할한다.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;정복(Conquer): 부분 배열을 정렬한다. 부분 배열의 크기가 충분히 작지 않으면 순환 호출 을 이용하여 다시 분할 정복 방법을 적용한다.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;결합(Combine): 정렬된 부분 배열들을 하나의 배열에 합병한다.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;순환 호출이 한번 진행될 때마다 최소한 하나의 원소(피벗)은 최종적으로 위치가 정해지므로,&amp;nbsp;&lt;br /&gt;반드시 이 알고리즘은 끝난다는 것을 보장한다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1364&quot; data-origin-height=&quot;1960&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ShfEM/btrTy25jTaC/xf7Wd7HlwOtNbunPPnAXp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ShfEM/btrTy25jTaC/xf7Wd7HlwOtNbunPPnAXp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ShfEM/btrTy25jTaC/xf7Wd7HlwOtNbunPPnAXp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FShfEM%2FbtrTy25jTaC%2Fxf7Wd7HlwOtNbunPPnAXp1%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;677&quot; height=&quot;973&quot; data-origin-width=&quot;1364&quot; data-origin-height=&quot;1960&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;알고리즘 특징&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&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;li&gt;시간 복잡도가 O(nlog₂n)를 가지는 다른 정렬 알고리즘과 비교했을 때도 가장 빠르다.&lt;/li&gt;
&lt;li&gt;추가 메모리 공간을 필요로 하지 않는다.&lt;/li&gt;
&lt;li&gt;퀵 정렬은 O(log n)만큼의 메모리를 필요로 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;li&gt;퀵 정렬의 불균형 분할을 방지하기 위하여 피벗을 선택할 때 더욱 리스트를 균등하게 분할할 수 있는 데이터를 선택한다&lt;br /&gt;EX)&amp;nbsp;리스트&amp;nbsp;내의&amp;nbsp;몇&amp;nbsp;개의&amp;nbsp;데이터&amp;nbsp;중에서&amp;nbsp;크기순으로&amp;nbsp;중간&amp;nbsp;값(medium)을&amp;nbsp;피벗으로&amp;nbsp;선택한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;시간복잡도&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;최선의 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비교 횟수&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;순환 호출의 깊이&amp;nbsp;&lt;/li&gt;
&lt;li&gt;T(n) = O(nlog₂n)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;최악의 경우&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리스트가 계속 불균형하게 나누어 지는 경우 ( 이미 정렬된 리스트에 대해 퀵 정렬을 실행하는 경우)&lt;/li&gt;
&lt;li&gt;T(n)&amp;nbsp;=&amp;nbsp;O(n^2)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;평균
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;T(n) = O(nlog₂n)&lt;/li&gt;
&lt;li&gt;다른 정렬 알고리즘과 비교했을 때도 가장 빠르다&amp;nbsp;&lt;/li&gt;
&lt;li&gt;퀵 정렬이 불필요한 데이터 이동을 줄이고 먼 거리의 데이터를 교환할 뿐 아니라, 한 번 결정된 피벗들이 추후 연산에서 제외되는 특성으로 빠르다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;a href=&quot;https://gmlwjd9405.github.io/2018/05/10/algorithm-quick-sort.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://gmlwjd9405.github.io/2018/05/10/algorithm-quick-sort.html&lt;/a&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;퀵 정렬을 C언어 코드로&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1670934093701&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# include &amp;lt;stdio.h&amp;gt;
# define MAX_SIZE 9
# define SWAP(x, y, temp) ( (temp)=(x), (x)=(y), (y)=(temp) )

// 1. 피벗을 기준으로 2개의 부분 리스트로 나눈다.
// 2. 피벗보다 작은 값은 모두 왼쪽 부분 리스트로, 큰 값은 오른쪽 부분 리스트로 옮긴다.
/* 2개의 비균등 배열 list[left...pivot-1]와 list[pivot+1...right]의 합병 과정 */
/* (실제로 숫자들이 정렬되는 과정) */
int partition(int list[], int left, int right){
  int pivot, temp;
  int low, high;

  low = left;
  high = right + 1;
  pivot = list[left]; // 정렬할 리스트의 가장 왼쪽 데이터를 피벗으로 선택(임의의 값을 피벗으로 선택)

  /* low와 high가 교차할 때까지 반복(low&amp;lt;high) */
  do{
    /* list[low]가 피벗보다 작으면 계속 low를 증가 */
    do {
      low++; // low는 left+1 에서 시작
    } while (low&amp;lt;=right &amp;amp;&amp;amp; list[low]&amp;lt;pivot);

    /* list[high]가 피벗보다 크면 계속 high를 감소 */
    do {
      high--; //high는 right 에서 시작
    } while (high&amp;gt;=left &amp;amp;&amp;amp; list[high]&amp;gt;pivot);

    // 만약 low와 high가 교차하지 않았으면 list[low]를 list[high] 교환
    if(low&amp;lt;high){
      SWAP(list[low], list[high], temp);
    }
  } while (low&amp;lt;high);

  // low와 high가 교차했으면 반복문을 빠져나와 list[left]와 list[high]를 교환
  SWAP(list[left], list[high], temp);

  // 피벗의 위치인 high를 반환
  return high;
}

// 퀵 정렬
void quick_sort(int list[], int left, int right){

  /* 정렬할 범위가 2개 이상의 데이터이면(리스트의 크기가 0이나 1이 아니면) */
  if(left&amp;lt;right){
    // partition 함수를 호출하여 피벗을 기준으로 리스트를 비균등 분할 -분할(Divide)
    int q = partition(list, left, right); // q: 피벗의 위치

    // 피벗은 제외한 2개의 부분 리스트를 대상으로 순환 호출
    quick_sort(list, left, q-1); // (left ~ 피벗 바로 앞) 앞쪽 부분 리스트 정렬 -정복(Conquer)
    quick_sort(list, q+1, right); // (피벗 바로 뒤 ~ right) 뒤쪽 부분 리스트 정렬 -정복(Conquer)
  }

}

void main(){
  int i;
  int n = MAX_SIZE;
  int list[n] = {5, 3, 8, 4, 9, 1, 6, 2, 7};

  // 퀵 정렬 수행(left: 배열의 시작 = 0, right: 배열의 끝 = 8)
  quick_sort(list, 0, n-1);

  // 정렬 결과 출력
  for(i=0; i&amp;lt;n; i++){
    printf(&quot;%d\n&quot;, list[i]);
  }
https://gmlwjd9405.github.io/2018/05/10/algorithm-quick-sort.html&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;고언어 통한 quick sort&lt;/p&gt;
&lt;pre id=&quot;code_1671698453528&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func Quick(arr []int) {

	if len(arr) &amp;lt;= 1 {
		return
	}
	p := Divide(arr)
	Quick(arr[:p])
	Quick(arr[p:])

}

func Divide(arr []int) int {
	pivot, end := arr[0], len(arr)-1
	start := 1

	for {
		for ; start &amp;lt; len(arr); start++ { 
			if arr[start] &amp;gt; pivot {
				break
			}
		}
		for ; end &amp;gt; 0; end-- {
			if arr[end] &amp;lt; pivot {
				break
			}
		}
		if start &amp;gt; end { 
			break
		}
		arr[start], arr[end] = arr[end], arr[start]
	}
	arr[0], arr[end] = arr[end], arr[0]
	return end + 1
}

func main() {
	arr := []int{3, 7, 4, 1, 7, 5, 4, 8}
    algorithm.Quick(arr)
	fmt.Println(arr)

}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Language Study/Go</category>
      <category>golang</category>
      <category>golang quick sort</category>
      <category>quick sort</category>
      <category>고언어 퀵정렬</category>
      <category>퀵 정렬</category>
      <author>exp9405</author>
      <guid isPermaLink="true">https://syujisu.tistory.com/214</guid>
      <comments>https://syujisu.tistory.com/entry/GolangQuick-sort%ED%80%B5-%EC%A0%95%EB%A0%AC#entry214comment</comments>
      <pubDate>Tue, 13 Dec 2022 21:22:09 +0900</pubDate>
    </item>
    <item>
      <title>[Golang]bubble sort(버블 정렬)</title>
      <link>https://syujisu.tistory.com/entry/Golangbubble-sort%EB%B2%84%EB%B8%94-%EC%A0%95%EB%A0%AC-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;버블 정렬(bubble sort) 알고리즘 개념&amp;nbsp;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서로 인접한 두 원소를 검사하여 정렬하는 알고리즘
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인접한 2개의 레코드 비교, 크기가 순서대로 되어있지 않으면 서로 교환&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;버블 정렬은 첫 번째 자료와 두 번째 자료를, 두 번째 자료와 세 번째 자료를, 세 번째와 네 번째를, &amp;hellip; &lt;br /&gt;이런 식으로 (마지막-1)번째 자료와 마지막 자료를 비교하여 교환하면서 자료를 정렬&lt;/li&gt;
&lt;li&gt;1회전 수행하면 가장 큰 자료가 맨 뒤로 이동 하므로 2회전에는 맨 끝에 있는 자료는 제외되고,&amp;nbsp;&lt;br /&gt;2회전에는 끝에서 두 번째 자료까지는 정렬에서 제외&amp;nbsp;&lt;br /&gt;=&amp;gt; 정렬을 1회전 수행할때마다 정렬에서 제외되는 데이터가 하나씩 증가&amp;nbsp;&lt;/li&gt;
&lt;/ul&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;2646&quot; data-origin-height=&quot;1772&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVYtyh/btrTvkMkDjD/4FrhI6YW0nV42r7jLis151/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVYtyh/btrTvkMkDjD/4FrhI6YW0nV42r7jLis151/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVYtyh/btrTvkMkDjD/4FrhI6YW0nV42r7jLis151/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVYtyh%2FbtrTvkMkDjD%2F4FrhI6YW0nV42r7jLis151%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;676&quot; height=&quot;453&quot; data-origin-width=&quot;2646&quot; data-origin-height=&quot;1772&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;h2 data-ke-size=&quot;size26&quot;&gt;알고리즘 특징&lt;/h2&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;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;단점&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;li&gt;하나의 요소가 가장 왼쪽에서 가장 오른쪽으로 이동하기 위해서는 배열에서 모든 다른 요소들과 교환되어야 한다.&lt;/li&gt;
&lt;li&gt;특히 특정 요소가 최종 정렬 위치에 이미 있는 경우라도 교환되는 일이 일어난다.&lt;/li&gt;
&lt;li&gt;일반적으로 자료의 교환 작업(SWAP)이 자료의 이동 작업(MOVE)보다 더 복잡하기 때문에 버블 정렬은 단순성에도 불구하고 거의 쓰이지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;h2 data-ke-size=&quot;size26&quot;&gt;시간 복잡도&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비교 횟수&lt;br /&gt;최상,&amp;nbsp;평균,&amp;nbsp;최악&amp;nbsp;모두&amp;nbsp;일정&lt;br /&gt;n-1, n-2, &amp;hellip; , 2, 1 번 = n(n-1)/2&lt;/li&gt;
&lt;li&gt;교환 횟수
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;입력 자료가 역순으로 정렬되어 있는 최악의 경우, 한 번 교환하기 위하여 3번의 이동(SWAP 함수의 작업)이 필요하므로 (비교 횟수 * 3) 번 = 3n(n-1)/2&lt;/li&gt;
&lt;li&gt;입력 자료가 이미 정렬되어 있는 최상의 경우, 자료의 이동이 발생하지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;T(n)&amp;nbsp;=&amp;nbsp;O(n^2)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;버블 정렬(bubble sort)의 c언어 코드&amp;nbsp;&lt;/h2&gt;
&lt;pre id=&quot;code_1670930533112&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# include &amp;lt;stdio.h&amp;gt;
# define MAX_SIZE 5

// 버블 정렬
void bubble_sort(int list[], int n){
  int i, j, temp;

  for(i=n-1; i&amp;gt;0; i--){
    // 0 ~ (i-1)까지 반복
    for(j=0; j&amp;lt;i; j++){
      // j번째와 j+1번째의 요소가 크기 순이 아니면 교환
      if(list[j]&amp;lt;list[j+1]){
        temp = list[j];
        list[j] = list[j+1];
        list[j+1] = temp;
      }
    }
  }
}

void main(){
  int i;
  int n = MAX_SIZE;
  int list[n] = {7, 4, 5, 1, 3};

  // 버블 정렬 수행
  bubble_sort(list, n);

  // 정렬 결과 출력
  for(i=0; i&amp;lt;n; i++){
    printf(&quot;%d\n&quot;, list[i]);
  }
}
https://gmlwjd9405.github.io/2018/05/06/algorithm-bubble-sort.html&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;Go언어로 된 버블 정렬 알고리즘은?&lt;/h2&gt;
&lt;pre id=&quot;code_1670931854259&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//bubble sort func
package bubblesort

func Bubble_sort(array []int) []int {
	for i := 0; i &amp;lt; len(array)-1; i++ {
		for j := 0; j &amp;lt; len(array)-i-1; j++ {
			if array[j] &amp;gt; array[j+1] {
				array[j], array[j+1] = array[j+1], array[j]
			}
		}
	}
	return array
}


//main
package main

import (
	&quot;fmt&quot;
	&quot;study01/package1/bubblesort&quot;
)
func main() {
	fmt.Print(bubblesort.Bubble_sort([]int{11, 8, 2, 3, 4, 5}))
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;170&quot; data-origin-height=&quot;40&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6GjVq/btrTzwdRIJQ/08d62ZslcaJZEJ84p9gCM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6GjVq/btrTzwdRIJQ/08d62ZslcaJZEJ84p9gCM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6GjVq/btrTzwdRIJQ/08d62ZslcaJZEJ84p9gCM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6GjVq%2FbtrTzwdRIJQ%2F08d62ZslcaJZEJ84p9gCM1%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;221&quot; height=&quot;52&quot; data-origin-width=&quot;170&quot; data-origin-height=&quot;40&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;</description>
      <category>Language Study/Go</category>
      <category>bubble sort</category>
      <category>golang</category>
      <category>golang algorithm</category>
      <category>golang bubble sort</category>
      <category>고언어</category>
      <category>고언어 알고리즘</category>
      <category>버블정렬알고리즘</category>
      <author>exp9405</author>
      <guid isPermaLink="true">https://syujisu.tistory.com/213</guid>
      <comments>https://syujisu.tistory.com/entry/Golangbubble-sort%EB%B2%84%EB%B8%94-%EC%A0%95%EB%A0%AC-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98#entry213comment</comments>
      <pubDate>Tue, 13 Dec 2022 20:47:44 +0900</pubDate>
    </item>
    <item>
      <title>[Golang]array, slice, map</title>
      <link>https://syujisu.tistory.com/entry/Golang-array-slice-map</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;개요&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;고에서는 array, slice, map을 지원한다&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;font-family: 'Nanum Gothic';&quot;&gt;slice는 가변적인 배열로 , 파이썬에서는 list&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;map은 key-vaule 의 형태의 자료형으로 dict로 생각하면 된다.&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;font-family: 'Nanum Gothic';&quot;&gt;slice와 map은 함께 많이 사용한다. 어떻게 사용하는지 정리해본다.&amp;nbsp;&lt;/span&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;배열&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1670159954373&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package array

import &quot;fmt&quot;

func NewArray(){
	var a [5]int // 다른 데이터 형태와는 달리 var 변수명 뒤에 자료형을 생략할 수 없음
	b := [4]int{1,2,3,4} //배열은 선언과 동시에 초기화가 가능

	fmt.Println(a,len(a))
	fmt.Println(b, len(b))
}

[0 0 0 0 0] 5 // 값을 지정하지 않으면 0 으로 초기화
[1 2 3 4] 4&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;span&gt;슬라이스&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1670160331205&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package slice


func NewSlice(){
	// slice 선언 두가지 방법으로
    var a []int
    b := make([]int,5,10)
    //int 자료형인 길이 5, 최대 길이 10 
     
    //즉, slice는 고정길이 배열과 달리 초기화시 최대 길이를 지정할 수 있고,
    //해당 slice를 통해 최대 길이를 넘지 않는 범위에서 가변길이 배열(=슬라이스)을 얼마든 생성해낼 수 있다

	//append같은 메소드를 사용하면 슬라이스의 길이를 확장시킬 수 있다
    b = append(a, 5,2,3,4)
    fmt.Println(a,b)
}

[] [5 2 3 4]&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;슬라이스와 배열의 차이는 가변 길이를 정하는 것이고,&amp;nbsp;&lt;/p&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;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;맵&lt;/h2&gt;
&lt;pre id=&quot;code_1670249271271&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package map1

import &quot;fmt&quot;


func NewMap(){
	// 주어진 타입을 초기화하고 사용할 수 있는 맵을 반환
	
	a := make(map[int]string)
	a[1] = &quot;A&quot;
	a[2] = &quot;B&quot;

	// 초기화 시 값을 넣어서 맵을 반환할 수 있음 
	map_int_str := map[int]string {
		1: &quot;월&quot;,
		2: &quot;화&quot;,
		3: &quot;수&quot;,
		4: &quot;목&quot;,
		5: &quot;금&quot;,
		6: &quot;토&quot;,
		7: &quot;일&quot;,
		//마지막 값 입력 시에도 , 가 빠지면 에러
		}

	fmt.Println(a,map_int_str)
	//map[1:A 2:B] map[1:월 2:화 3:수 4:목 5:금 6:토 7:일]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 없는 요소라면? 숫자일 경우에는 0을 문자열의 경우에는 &quot;&quot; 을 출력한다&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1670250445315&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; // 만약, 값이 주어지지 않은 요소를 꺼내온다면?

package map1

import &quot;fmt&quot;

func NotInMap(){
	a := make(map[int]int)

	a[1] = 2
	a[3] = 4

	fmt.Println(a[2])
}
// 0&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;정확히 맵은 어떤 타입을 반환하는걸까 보면&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1670250701043&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package map1

import &quot;fmt&quot;

func NotInMap(){
	a := make(map[int]int)

	a[1] = 2
	a[3] = 4

	value1, ok := a[1]
	fmt.Println(value1,ok)
	// 2 true

	value2, ok := a[2]
	fmt.Println(value2,ok)
	// 0 false 

	value3,ok := a[3]
	fmt.Println(value3,ok)
	// 4 true
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;존재하지 않는 키 값을 요청한다면, 두 번째 인자로 false 를 반환한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 맵의 요소 확인과 삭제 문법&lt;/p&gt;
&lt;pre id=&quot;code_1670251189366&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package map1

import &quot;fmt&quot;

func NotInMap(){
	a := make(map[int]int)

	// 맵에 요소를 추가하거나 업데이트 
	a[1] = 2
	a[3] = 4

	value1, ok := a[1]
	fmt.Println(value1,ok)
	// 2 true

	value2, ok := a[2]
	fmt.Println(value2,ok)
	// 0 false 

	// 요소 제거 
	delete(a,3)

	value3,ok := a[3]
	fmt.Println(value3,ok)
	// 0 false
}&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;따라서 go에서는 아래와 같이 예외 처리를 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1670251636082&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package map1

import &quot;fmt&quot;

func NotInMap(){
	a := map[int]int{
		1 : 2,
		2 : 3,
		3 : 4,
		4 : 5,
	}
	
	// key를 0~7까지 대입하고, a[key] 의 결과로 ok 값을 받아 
	//ok가 true일 경우(해당 키에 대한 value값 존재 시 ) key에 해당하는 value를 출력
	//그렇지 않을 경우(false/ value값이 미존재 시 ) 문자열 출력
	for key:= 0; key &amp;lt; 8; key++{
		if value, ok := a[key];ok{
				fmt.Println(value)
			} else {
			fmt.Println(&quot;key&quot;, key, &quot;is not exist&quot;)
		}
	}
}

key 0 is not exist
2
3
4
5
key 5 is not exist
key 6 is not exist
key 7 is not exist&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;go tour &amp;gt; 맵 연습하기 (링크 : &lt;a href=&quot;https://go-tour-ko.appspot.com/moretypes/23&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://go-tour-ko.appspot.com/moretypes/23)&amp;nbsp;&lt;/a&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1670253008210&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// go tour map 연습하기

// 문자열 s가 주어진다
//주어진 문자열을 단어 단위로 나눠 단어가 몇번 쓰였는지 맵으로 기록한다
// wc.test 함수로 우리가 작성한 함수를 여러 테스트 케이스로 테스트해준다.

package map1

import (
	&quot;strings&quot;

	&quot;golang.org/x/tour/wc&quot;
)

func WordCount(s string) map[string]int {
	//strings filed는 유니코드에서 정의한 대로 
	//하나 이상의 연속된 공백 문자의 각 인스턴스를 기준으로 문자열 분할
	words := strings.Fields(s)
	//일단 문자열을 단어 단위의 배열로 반환 

	result := make(map[string]int)

	// for 인덱스 , 요소 := range 배열 {...}
	// 아래는 요소만 사용할 때 
	for _, w:= range words{
		if result[w] == 0 {
			result[w] = 1
		}else{
			result[w] = result[w] +1
		}
	}
	return result
}


func main() {
	wc.Test(WordCount)
}

//PASS
 f(&quot;I am learning Go!&quot;) = 
 map[string]int{&quot;Go!&quot;:1, &quot;I&quot;:1, &quot;am&quot;:1, &quot;learning&quot;:1}
PASS
f(&quot;The quick brown fox jumped over the lazy dog.&quot;) = 
 map[string]int{&quot;The&quot;:1, &quot;brown&quot;:1, &quot;dog.&quot;:1, &quot;fox&quot;:1, &quot;jumped&quot;:1, &quot;lazy&quot;:1, &quot;over&quot;:1, &quot;quick&quot;:1, &quot;the&quot;:1}
PASS
f(&quot;I ate a donut. Then I ate another donut.&quot;) = 
 map[string]int{&quot;I&quot;:2, &quot;Then&quot;:1, &quot;a&quot;:1, &quot;another&quot;:1, &quot;ate&quot;:2, &quot;donut.&quot;:2}
PASS
f(&quot;A man a plan a canal panama.&quot;) = 
 map[string]int{&quot;A&quot;:1, &quot;a&quot;:2, &quot;canal&quot;:1, &quot;man&quot;:1, &quot;panama.&quot;:1, &quot;plan&quot;:1}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Language Study/Go</category>
      <category>array map slice</category>
      <category>go</category>
      <category>go array</category>
      <category>go map</category>
      <category>go slice</category>
      <category>go tour 맵 연습하기</category>
      <category>golang</category>
      <category>gotour</category>
      <category>고언어</category>
      <author>exp9405</author>
      <guid isPermaLink="true">https://syujisu.tistory.com/212</guid>
      <comments>https://syujisu.tistory.com/entry/Golang-array-slice-map#entry212comment</comments>
      <pubDate>Sun, 4 Dec 2022 22:02:40 +0900</pubDate>
    </item>
    <item>
      <title>[Golang]변수, 상수</title>
      <link>https://syujisu.tistory.com/entry/Golang-%EB%B3%80%EC%88%98-%EC%83%81%EC%88%98</link>
      <description>&lt;h1 id=&quot;Golang_변수,상수-Go는정적타입언어&quot;&gt;Go는 정적타입 언어&amp;nbsp;&lt;/h1&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;Golang_변수,상수-변수&quot;&gt;변수&lt;/h1&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 data-ke-size=&quot;size16&quot;&gt;변수의 초기화는 런타임에 동작 / 사용하지 않는 변수가 있는 경우 에러를 뱉는다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 변수를 선언만하고 명시적으로 초기화 하지 않은 상태에서 디폴트로 할당되는 값은 제로값 / int타입은 0&amp;nbsp; / 각 타입별 제로값 확인하는 함수는&amp;nbsp;&lt;span style=&quot;color: #000000;&quot;&gt;Go IsZero()&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;구분자료형제로값
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;숫자형&lt;/td&gt;
&lt;td&gt;int, float64&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;불리언 형&lt;/td&gt;
&lt;td&gt;bool&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;문자열&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;&quot;&quot; (빈 문자열)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;Golang_변수,상수-전역변수선언&quot; data-ke-size=&quot;size26&quot;&gt;전역 변수 선언&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전역 변수는 함수 내에서 선언하는 것과 달리 단축 구문(:=)을 사용하면 에러&amp;nbsp;&lt;/p&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div id=&quot;highlighter_373591&quot;&gt;
&lt;pre id=&quot;code_1661085601475&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

var hi string = &quot;hi&quot; // 가능
var hello = &quot;hello&quot; // 가능

goodbye := &quot;goodbye&quot; // 에러 발생

func main(){
    //
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 외부에서는 모든 문장이 var , func 같은 키워드로 시작되므로 키워드가 없는 단축 구문은 외부에서 사용할 수 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;Golang_변수,상수-여러개변수선언&quot; data-ke-size=&quot;size26&quot;&gt;여러 개 변수 선언&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수를 여러 개 선언하고 초기화 할때는 반드시 선언하는 벼눗와 초기화 하는 값의 개수가 같고, 타입은 같지 않아도 된다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1661085608957&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

func main(){
    hi, hello, goodbye := &quot;hi&quot;, &quot;hello&quot;, &quot;goodbye&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div id=&quot;highlighter_624697&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;var()을 이용해서도 여러 개 변수 선언 가능&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떨 때 쓰는지?&amp;nbsp;&amp;rarr; 연관성 있는 변수 한번에 선언하기 위해서&lt;/p&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div id=&quot;highlighter_516458&quot;&gt;
&lt;pre id=&quot;code_1661085617974&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

func main(){
        var (
        i = 10
        j = 20
    )
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;Golang_변수,상수-변수재할당,선언&quot; data-ke-size=&quot;size26&quot;&gt;변수 재할당 , 선언&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 코드 상으로는 m 변수가 재선언하고 값이 변경됨&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정확히는 재선언은 아니고 string으로 m이 이미 선언되어있기 때문에 값만 변경된 것&lt;/p&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div id=&quot;highlighter_29829&quot;&gt;
&lt;pre id=&quot;code_1661085625086&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

func main() {
    m := &quot;hello&quot;
    m, i := &quot;hihi&quot;, false

    fmt.Println(m, i)
}

&amp;gt;&amp;gt;hihi false&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&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 data-ke-size=&quot;size16&quot;&gt;단축 변수 선언 문법을 사용하더라도 기존 변수에 대해서는 재할당 처리&amp;nbsp;&lt;/p&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div id=&quot;highlighter_406816&quot;&gt;
&lt;pre id=&quot;code_1661085631969&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

func main() {
    m := &quot;hello&quot;
    m := &quot;hihi&quot;

    fmt.Println(m)
}

&amp;gt;&amp;gt;# command-line-arguments
.\test.go:12:4: no new variables on left side of :=

만약,

    m := &quot;hello&quot;
    m = &quot;hihi&quot;
로 :가 제거되면 재선언이 되지 않고 값만 변경되기 때문에 hihi 출력&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&quot;Golang_변수,상수-Type변환&quot; data-ke-size=&quot;size26&quot;&gt;Type 변환&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른type의 요소들 간의 할당에는 명시적인 변환 필요&lt;/p&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div id=&quot;highlighter_179189&quot;&gt;
&lt;pre id=&quot;code_1661085707775&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import (
    &quot;fmt&quot;
    &quot;math&quot;
)

func main() {
    var x, y int = 3, 4
    var f  = math.Sqrt(float64(x*x + y*y))
// /만약 float64 명시적 타입 선언을 제거하면? 에러 발생  prog.go:10:21: cannot use (x * x + y * y) (value of type int) as type float64 in argument to math.Sq
    fmt.Println(x, y, f)
} -&amp;gt; 3 4 5&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;Golang_변수,상수-이름쉐도잉&quot; data-ke-size=&quot;size26&quot;&gt;이름 쉐도잉&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패키지, 타입과 똑같은 이름의 변수를 선언해도 에러나지않는다.&amp;nbsp;&lt;/p&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div id=&quot;highlighter_11632&quot;&gt;
&lt;pre id=&quot;code_1661085713881&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

func main() {
    string := 10

    fmt.Print(string)
} --&amp;gt; 해당 코드는 정상 출력하지만 (10)

package main

import &quot;fmt&quot;

func main() {
    string := 10
    var m string
    m = &quot;hi&quot;

    fmt.Print(m)
} --&amp;gt; 해당 코드는 .\test.go:7:6: string is not a type 에러를 뱉는다. 왜? string이라는 변수가 var m 변수에서는 string 타입을 선언하고 있으니까&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h1 id=&quot;Golang_변수,상수-상수&quot;&gt;상수&amp;nbsp;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한번 선언되고 할당되면 값을 바꿀 수 없다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선언과 할당을 동시에 진행되어야 하며 const 키워드를 사용하면 상수를 선언 가능&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자료형 명시도 선택적으로 해주면 된다. 어차피 컴파일러가 추론해줌&amp;nbsp;&lt;/p&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div id=&quot;highlighter_467943&quot;&gt;
&lt;pre id=&quot;code_1661085719490&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

func main() {
    const max_size int = 10
    const max_size = 10 //type 명시 안해도 가능

    fmt.Print(max_size)
}--&amp;gt; 10&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&quot;Golang_변수,상수-여러상수선언&quot; data-ke-size=&quot;size26&quot;&gt;여러 상수 선언&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수 처럼 여러개 선언 가능&lt;/p&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div id=&quot;highlighter_201115&quot;&gt;
&lt;pre id=&quot;code_1661085727697&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

func main() {
    const (
        max_size, lang = 10, &quot;golang&quot;
    )
    fmt.Print(max_size, lang)
}10golang&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Language Study/Go</category>
      <category>go</category>
      <category>golang</category>
      <category>golang_var</category>
      <category>고 언어 변수</category>
      <category>고언어 상수</category>
      <category>고언어 선언</category>
      <author>exp9405</author>
      <guid isPermaLink="true">https://syujisu.tistory.com/211</guid>
      <comments>https://syujisu.tistory.com/entry/Golang-%EB%B3%80%EC%88%98-%EC%83%81%EC%88%98#entry211comment</comments>
      <pubDate>Sun, 21 Aug 2022 21:42:37 +0900</pubDate>
    </item>
    <item>
      <title>[Golang]클래스, 구조체, 인스턴스</title>
      <link>https://syujisu.tistory.com/entry/Golang%ED%81%B4%EB%9E%98%EC%8A%A4-%EA%B5%AC%EC%A1%B0%EC%B2%B4-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4</link>
      <description>&lt;h1&gt;구조체&amp;nbsp;&lt;/h1&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;li&gt;필드들의 집합체이자, 컨테이너 = 정보의 집합&lt;/li&gt;
&lt;li&gt;다른 언어의 구조체와 같이, 내부에 변수를 가지고 있으며, 접근제한 가능, method를 가짐&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Go언어에는 class 키워드가 없어 구조체를 사용하여 클래스를 정의한다.&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Go 언어는 객체 지향을 따르기 때문에 java의 객체지향은 class, 상속 등의 개념이 존재하지 않으나 Go언어에서는 존재&amp;nbsp;&lt;/li&gt;
&lt;li&gt;객체지향의 class가 field 와 method를 함께 갖는 것과 다르게, Go언어의 구조체는 fIled만 가지고 method는 별도로 분리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Go언어의 구조체 vs 클래스의 차이는 인스턴스 만들어 넘길 때&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;구조체는 값을 복사해서 넘김&lt;/li&gt;
&lt;li&gt;클래스는 그 값이 담긴 인스턴스의 주소를 넘김&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;/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;gt;&amp;gt; 객체를 소프트웨어에 실체화 하면 그것을 인스턴스라 부르고, 실체화된 인스턴스는 메모리에 할당&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Oop의 관점에서 객체가 메모리에 할당되어 실제 사용될 때 인스턴스라 부른다.&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;객체는 클래스의 인스턴스&amp;nbsp;&lt;/li&gt;
&lt;li&gt;객체 간의 링크는 클래스 간의 연관 관계의 인스턴스&amp;nbsp;&lt;/li&gt;
&lt;/ul&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;구조체 선언&amp;nbsp;&amp;rarr; string 변수 name을 가지는 구조체를 Dog이라 한다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1659964640403&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;type Dog struct {
  name string
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구조체 메소드 선언&amp;nbsp;&amp;rarr; Go언어에서의 접근 제한은 패지키 밖에서 해당 패키지를 사용할 때 접근 제한 / 변수 및 메소드는 소문자로 시작하면 패키지 내에서만 사용하며, 대문자면 패키지 외부에서도 사용할 수 있음&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1659964664173&quot; class=&quot;autoit&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func (d Dog) Sounds(){
  Fmt.Printf(&quot;%s : wal\n&quot;, d.name)
}&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;구조체와 Class&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인스턴스를 만들 때 구조체는 struct 그대로, 클래스는 struct 를 가리키는 포인터 생성&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1659964686957&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

type Dog struct{
   name string
}

type Cat struct{
  name string
}

func NewDog(name string){
  var d Dog 
  d.name = name
  return d
} // 구조체 

func (d Dog) Sounds(){
   Fmt.Printf(&quot;%s : wal\n&quot;, d.name)
}

func NewCat(name string) *Cat{
  var c Cat
  c.name = name
  return &amp;amp;c
} // 클래스 -&amp;gt; struct를 가리키는 포인터를 생성하고 주소값을 불러오면 된다


func (c *Cat) Sounds(){
  fmt.Printf(&quot;%s : yaong\n&quot;, c.name)
}

Func main(){
  d1 := NewDog(&quot;Baduk&quot;)
  d2 := d1
  d2.name = &quot;Nureong&quot;
  d1.Sounds()
  d2.Sounds() c1 := NewCat(&quot;Happy&quot;)
  c2 := c1
  c2.name = &quot;Merry&quot;
  c1.Sounds()
  c2.Sounds()

}


&amp;gt;&amp;gt; 출력문
Baduk: wal
Nureong: wal
Merry: yaong.
Merry: yaong.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;** 서로 연관성이 적은 문법 요소(구조체, 포인터)를 합성하여 새로운 문법을 만들어내는 성질을 직교성이라하는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;언어의 직교성이 높을 수록 문법이 단순해지며 유연해진다. 직교성을 높여 문법을 유연해지게 하는 것이 Go언어의 설계 목표와 부합&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;h1 id=&quot;Golang_구조체,인스턴스,class-구조체종류&quot;&gt;구조체 종류&amp;nbsp;&lt;/h1&gt;
&lt;h2 id=&quot;Golang_구조체,인스턴스,class-중첩구조체&quot; data-ke-size=&quot;size26&quot;&gt;중첩 구조체&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;내장 타입 방식&amp;nbsp;&amp;rarr; 일반 구조체 선언 방식과 같음 / 구조체 필드에 다른 구조체 타입의 필드 선언 / 중첩 구조체의 필드에 접근하기 위해 (구조체).(중첩구조체).(중첩구조체필드명)으로 접근함&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1660654283706&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

tyue User struct{
  name string
  id string
  age int
}

type VipUser struct{
  UserInfo User // 내장 타입
  VipLevel int
  Price int
}

func main(){
    user1 := User(&quot;js&quot;, &quot;oh_exp&quot;, 29)
    user1_vip := VipUser(user1, 1, 1000)
     
    user2_vip := VipUser{
            User(&quot;test&quot;, &quot;abc&quot;,24),
            1,
            10000}

    fmt.Println(user1_vip.Userinfo.ID)
    fmt.Println(user2_vip.Userinfo.Age)
}&lt;/code&gt;&lt;/pre&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div id=&quot;highlighter_667184&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&quot;Golang_구조체,인스턴스,class-포함된필드방식&quot; data-ke-size=&quot;size26&quot;&gt;포함된 필드 방식&lt;/h2&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;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div id=&quot;highlighter_146104&quot;&gt;
&lt;pre id=&quot;code_1660654299303&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

tyue User struct{
  name string
  id string
  age int
}

type VipUser struct{
  User // 포함된 필드 방식
  VipLevel int
  Price int
}

func main(){
    user1 := User(&quot;js&quot;, &quot;oh_exp&quot;, 29)
    user1_vip := VipUser(user1, 1, 1000)
     
    user2_vip := VipUser{
            User(&quot;test&quot;, &quot;abc&quot;,24),
            1,
            10000}

    fmt.Println(user1_vip.ID)
    fmt.Println(user2_vip.)
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&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;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div id=&quot;highlighter_850183&quot;&gt;
&lt;pre id=&quot;code_1660654309959&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

type User struct {
    Name  string
    ID    string
    Age   int
    Level int // 중첩
}

type VIPUser struct {
    User
    Level int /// 중첩
    Price int
}

func main() {
    user1 := User{&quot;Hoplin&quot;, &quot;hoplin1234&quot;, 24, 30}
    user1_vip := VIPUser{user1, 1, 10000}
    fmt.Println(user1_vip.Level) // VIPUser구조체의 Level필드
    fmt.Println(user1_vip.User.Level) // VIPUser구조체의 중첩된 User타입의 Level필드
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h1 id=&quot;Golang_구조체,인스턴스,class-메소드&quot;&gt;메소드&lt;/h1&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;**통상적인 OOP 에서 클래스는 메소드를 멤버로 속성을 표현하는 필드(data)와 기능을 표현하는 메소드(function)을 가진다. / /이중 메소드는 특정 작업을 수행하기 위한 명령문 집합&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;Golang_구조체,인스턴스,class-별칭리시버타입&quot; data-ke-size=&quot;size26&quot;&gt;별칭 리시버 타입&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타입에 대한 별칭을 지정 /&amp;nbsp; 기존 타입에 대해서도 별칭을 지정할 수 있고, 사용자가 정의한 구조체 타입으로 별칭 지을 수 있음&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div id=&quot;highlighter_550622&quot;&gt;
&lt;pre id=&quot;code_1660654320077&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

type MyInt int // int 타입 별칭

type Info struct {
Name string
age int
} // 구조체

type MyStruct Info //사용자 정의 구조체 타입 별칭

func main() {
var a MyInt = 20

var b int = 10

//MyInt 가 int의 별칭이지만, 별칭 타입이기 때문에 다른 타입으로 인식
fmt.Println(int(a) + b)

var e MyStruct = MyStruct{
&quot;jisu&quot;,
29,
}
fmt.Print(e.Name)
} }&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;Golang_구조체,인스턴스,class-메소드선언하기&quot; data-ke-size=&quot;size26&quot;&gt;메소드 선언하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메소드 선언하기 위해서 리시버 사용 / 리시버는 func 키워드 , 함수 이름 사이 명시&lt;/p&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div id=&quot;highlighter_861089&quot;&gt;
&lt;pre id=&quot;code_1660654331576&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;type testStruct struct {
    width int
    height int
}

func (r testStruct) info() int{
    return r.width * r.height
}// 리시버
// 해당 리시버를 통해 testStruct 타입에 속함&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위를 python으로 바꾸면?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패키지 내에서 선언된 구조체, 별칭 타입들이 리시버가 될 수 있음.&lt;/p&gt;
&lt;pre id=&quot;code_1660654343178&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class testStruct(object):
    # 초기화 메서드  (클래스의 객체가 만들어질때 자동으로 호출되어 그 객체가 갖게 될 여러 가지 성질을 정해줌)
    def __init__(self, width : int = 10, height : int = 20) -&amp;gt; None:
        self.width = width
        self.height = height

    def info(self) -&amp;gt; int:
            return self.width * self.height

# 직접 실행시켰을 때만 실행되기를 원하는 코드들을 넣어줌
if __name__ == &quot;__main__&quot;:
    t = testStruct(20,20)
    print(t.info())&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;Golang_구조체,인스턴스,class-구조체메소드선언&quot; data-ke-size=&quot;size26&quot;&gt;구조체 메소드 선언&lt;/h2&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div id=&quot;highlighter_173920&quot;&gt;
&lt;pre id=&quot;code_1660654355468&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

type account1 struct {
    balance int
}

func (a *account1) withdrawPointer(amount int) {
    a.balance -= amount
    // *account 타입에 속한 메소드 / *account 타입의 인스턴스(구조체를 생성해 저장한 변수 (=데이터 실체))들은 해당 메소드를 사용할 수 있음
    // a는 account 구조체 포인터 타입의 메소드 / account 구조체의 필드에 대해 &quot;.&quot; 연산자 통해 접근 가능
    // 메소드는 (리시버타입).(메소드)() 형태로 접근
    // 각 리시버 타입의 함수라는 응집성이 있음
}

func withdrawFunc(a *account1, amount int) {
    a.balance -= amount
    // void 반환 타입의 함수
    // 구조체 포인터의 매개변수를 받아 해당 구조체의 데이터를 변경하는 함수
    // (함수명)() 형태로 호출
    // 함수는 응집성이 없음
}

func main() {
    a := &amp;amp;account1{100} // account1 타입의 인스턴스 생성
    withdrawFunc(a, 30)

    a.withdrawPointer(10)
    fmt.Println(a.balance)
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&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;h2 id=&quot;Golang_구조체,인스턴스,class-별칭리시버타입.1&quot; data-ke-size=&quot;size26&quot;&gt;별칭 리시버 타입&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;별칭타입도 리시버가 될 수 있음&amp;nbsp;&lt;/p&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div id=&quot;highlighter_957496&quot;&gt;
&lt;pre id=&quot;code_1660654363002&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

type MyInt int

func (a MyInt) add(b int) int {
    return int(a) + b
}

func main() {
    var a MyInt = 10
    fmt.Println(a.add(20))
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&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;h2 id=&quot;Golang_구조체,인스턴스,class-포인터메소드vs값타입메소드&quot; data-ke-size=&quot;size26&quot;&gt;포인터 메소드 vs 값 타입 메소드&amp;nbsp;&lt;/h2&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;li&gt;값 타입 메소드 : 호출한 구조체의 필드가 새로운 구조체 필드로 복사 / 값 타입 메소드를 호출한 구조체 인스턴스와 메소드 내에서 사용하는 구조체 인스턴스는 서로 다른 구조체&amp;nbsp;&lt;br /&gt;(그래서 아래&amp;nbsp;A.ValueMethod(20) fmt.Println(A.balance) // 70 가 위의 포인터 메소드 호출과 값이 같았던 이유)&lt;/li&gt;
&lt;li&gt;값 반환 타입 메소드 : 값 타임 메소드와 원리는 동일하고 거기에 구조체 반환하는 점이 추가 / 구조체 반환하면 반환된 구조체 필드 값들이 새로운 구조체 필드에 복사된 후 변수에 저장&amp;nbsp;&lt;br /&gt;(결론적으로 값이 변경된 구조체를 복사한 것이기 때문에 값이 변경되긴 함)&lt;/li&gt;
&lt;/ul&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div id=&quot;highlighter_886528&quot;&gt;
&lt;pre id=&quot;code_1660654369808&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

// 구조체 생성
type account struct {
    balance   int
    firstName string
    lastName  string
}

//포인터 메소드
func (a1 *account) PointMethod(amount int) {
    a1.balance -= amount
}

//값 타입 메소드
func (a2 account) ValueMethod(amount int) {
    a2.balance -= amount
}

//수정된 값을 반환하는 값 타입 메소드
func (a3 account) modifiedValueMethod(amount int) account {
    a3.balance -= amount
    return a3
}

func main() {
    var A *account = &amp;amp;account{100, &quot;oh&quot;, &quot;jisu&quot;}
    A.PointMethod(30)
    fmt.Println(A.balance) //70

    A.ValueMethod(20)
    fmt.Println(A.balance) // 70

    var B account = A.modifiedValueMethod(20)
    fmt.Println(B.balance) // 50

    B.PointMethod(30)
    fmt.Println(B.balance) //20
    fmt.Println(A.balance) // 70
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>Language Study/Go</category>
      <category>Golang class</category>
      <category>Golang instance</category>
      <category>golang struct</category>
      <category>golang 구조체</category>
      <category>Golang 인스턴스</category>
      <category>golang 클래스</category>
      <author>exp9405</author>
      <guid isPermaLink="true">https://syujisu.tistory.com/210</guid>
      <comments>https://syujisu.tistory.com/entry/Golang%ED%81%B4%EB%9E%98%EC%8A%A4-%EA%B5%AC%EC%A1%B0%EC%B2%B4-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4#entry210comment</comments>
      <pubDate>Mon, 8 Aug 2022 00:35:25 +0900</pubDate>
    </item>
    <item>
      <title>Cashing- 캐싱 개요 및 인메모리 DB 비교</title>
      <link>https://syujisu.tistory.com/entry/Cashing1-%EC%BA%90%EC%8B%B1-%EA%B0%9C%EC%9A%94-%EB%B0%8F-%EC%9D%B8%EB%A9%94%EB%AA%A8%EB%A6%AC-DB-%EB%B9%84%EA%B5%90</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;캐싱이란?&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;- 애플리케이션 처리 속도를 높여주는 이미 가져온 데이터나 계산된 결과값의 복사본을 저장하여 처리 속도를 향상시키고 , 이를 통해 향후 요청을 더 빠르게 처리할 수 있다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;- 대부분의 프로그램이 동일한 데이터나 명령어에 반복하여 액세스하기 때문에 캐싱은 효율적인 아키텍쳐 패턴&lt;/span&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;캐싱 적합한 데이터&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;반복적이고 동일한 결과가 나오는 기능의 반환값&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;업데이트가 자주 발생하지 않는 데이터&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;자주 조회되는 데이터&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;입력값과 출력값이 일정한 데이터&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;캐싱된 데이터는 데이터 갱신으로 인해 DB와 불일치가 발생할 수 있다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;=&amp;gt; 그렇기 때문에 데이터 Update가 잦게 일어나거나 데이터 불일치시 비즈니스 로직 상 문제가 발생할 수 있는 기능은 캐싱 대상으로 적합하지 않음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;캐싱 타입&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Local Cache&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;서버마다 캐시를 따로 저장한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;다른 서버의 캐시를 참조하기 어렵다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;서버 내에서 작동하기 때문에 속도가 빠르다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;로컬 서버 장비의 Resource를 이용한다. (Memory, Disk)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;캐시에 저장된 데이터가 변경되는 경우:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;해당 서버를 제외한 모든 peer에 변경 사항 전달&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;All-to-All Replication&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;WAS 인스턴스가 늘어나고, 캐시 저장 데이터 크기가 커지면 성능이 저하되는 이유는 이 때문&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Global Cache&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;여러 서버에서 캐시 서버에 접근하여 참조 할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;별도의 캐시 서버를 이용하기 때문에 서버 간 데이터 공유가 쉽다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;네트워크 트래픽을 사용해야 해서 로컬 캐시보다는 느리다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;데이터를 분산하여 저장 할 수 있다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Replication: 두 개의 이상의 DBMS 시스템을 Mater / Slave 로 나눠서 동일한 데이터를 저장하는 방식&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Sharding: 같은 테이블 스키마를 가진 데이터를 다수의 데이터베이스에 분산하여 저장하는 방법&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;캐시에 저장된 데이터가 변경되는 경우:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;추가적인 작업 필요없음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;서비스 확장으로 WAS 인스턴스가 늘어나고, Cache 데이터 크기가 커질 수록 효과적인 이유&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;캐싱용 인메모리 DB (Redis VS Memacached)&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #3d4144;&quot;&gt;두 기능 모두 NoSQL 형식으로 키-값 형태를 이루어 두 솔루션 모두 캐시 레이어로서 동작&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #3d4144;&quot;&gt;Memcachedsms In-Memory Key-Value 저장소라 한다면, Redis는 단순한 KEY-VALUE를 저장소에서 더 나아가 일종의 데이터 구조 스토어라고 합니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #3d4144;&quot;&gt;자바 언어에서는 Memcached는 Xmemcached과 Memcached-java-client를 제공하고 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #3d4144;&quot;&gt;Redis는 Jedis, Lettuce, Redisson을 제공합니다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;주요 특징 비교&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;552&quot; data-origin-height=&quot;333&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ljrZW/btrEHinUa88/GlKSRqiY8kt00hVq5PLqmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ljrZW/btrEHinUa88/GlKSRqiY8kt00hVq5PLqmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ljrZW/btrEHinUa88/GlKSRqiY8kt00hVq5PLqmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FljrZW%2FbtrEHinUa88%2FGlKSRqiY8kt00hVq5PLqmk%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;552&quot; height=&quot;333&quot; data-origin-width=&quot;552&quot; data-origin-height=&quot;333&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;데이터 자료형, 그에 따른 메모리 사용량 &lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Memcached : &lt;span style=&quot;background-color: #ffffff; color: #3d4144;&quot;&gt;key와 value가 String 자료형으로 최대 1MB까지 저장 / String으로만 구성되어 Redis 보다 빠르고&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #3d4144;&quot;&gt;Redis의 Hash로 직렬화, 역직렬화 과정을 거치지 않고 객체를 저장할 수 있어 애플리케이션 개발이 수월해지고 IO 과정이 줄어 들어 효율적&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Redis : &lt;span style=&quot;background-color: #ffffff; color: #3d4144;&quot;&gt;&amp;nbsp;5개의 데이터 자료형(String, Hash, List, Set, Sorted set)을 사용하며 키와 값 모두 512MB까지 저장 가능&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&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;&lt;u&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;구조 , 확장법&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Memcached :&lt;span&gt; &lt;span style=&quot;background-color: #ffffff; color: #3d4144;&quot;&gt;멀티 코어 구조로 된 멀티 쓰레드를 지원 / vertical scale up(=수평적 확장) 으로 확장성 얻음&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Redis :&lt;span&gt; &lt;span style=&quot;background-color: #ffffff; color: #3d4144;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;싱글 쓰레드 구조 / 슈평, 수직 확장 가능 / 수평적 확장은 노드 그룹(=샤드) 개수 조정 , 수직 확장은 클러스터 크기 증가&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;데이터-이빅션data-eviction에-대한-알고리즘&quot; data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;Data Eviction 알고리즘(=메모리 여유공간 없을 때 자원 쫓아낼때 사용되는 알고리즘)&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Memcached :&lt;span style=&quot;background-color: #ffffff; color: #3d4144;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;LRU(Least Recently Used)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Redis :&lt;span&gt;&lt;span&gt; 하기 8가지 정책 중 선택&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 133px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;noeviction&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;메모리가 다 찬 경우 에러 표시&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;allkeys-LRU&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;가장 사용되지 않은 데이터 축출&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;volatile-LRU&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;가장 사용되지 않음 + 만료 기간 설정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;allkeys-random&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;랜덤하게 축출&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;volatile-random&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;랜덤 + 만료 기간 축출&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;volatile-TTL&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;제일 짧은 TTL + 만료 기간 설정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;volatile-lfu&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;제일 사용되지 않음 + 만료 기간 설정(Redis 4.0부터 추가)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 14px;&quot;&gt;
&lt;td style=&quot;height: 14px;&quot;&gt;allkeys-lfu&lt;/td&gt;
&lt;td style=&quot;height: 14px;&quot;&gt;제일 사용되지 않는 데이터 축출(Redis 4.0부터 추가)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;데이터-이빅션data-eviction에-대한-알고리즘&quot; data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;트랜잭션&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Memcached :&lt;span style=&quot;background-color: #ffffff; color: #3d4144;&quot;&gt;&lt;span&gt; 원자성은 있지만, 트랜잭션 미제공&amp;nbsp; / 멀티 쓰레드 구조로 여러 쓰레드가 한번에 동일한 트랜잭션 기능에 접근하게되면 원자성을 보장하게되도, 다른 쓰레드의 값과 겹쳐질 수 있음.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Redis :&lt;span&gt;&lt;span&gt;&lt;span&gt; 트랜잭션 기능 제공 / WATCH , MULTI , EXEX 등의 명령어 기반 optimistic lock 기반 트랜잭션 지원&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;</description>
      <category>Web/web dev</category>
      <category>Caching</category>
      <category>Memacached</category>
      <category>Redis</category>
      <category>Redis VS Memacached</category>
      <category>캐싱</category>
      <author>exp9405</author>
      <guid isPermaLink="true">https://syujisu.tistory.com/208</guid>
      <comments>https://syujisu.tistory.com/entry/Cashing1-%EC%BA%90%EC%8B%B1-%EA%B0%9C%EC%9A%94-%EB%B0%8F-%EC%9D%B8%EB%A9%94%EB%AA%A8%EB%A6%AC-DB-%EB%B9%84%EA%B5%90#entry208comment</comments>
      <pubDate>Mon, 13 Jun 2022 21:51:42 +0900</pubDate>
    </item>
    <item>
      <title>Proxy와 사용자 IP(X-Forwarded-For(XFF))</title>
      <link>https://syujisu.tistory.com/entry/X-Forwarded-ForXFF</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;X-Forwarded-For(XFF) 란?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;- XFF 는 HTTP Header 중 하나로 HTTP Server 에 요청한 Client 의 IP 를 식별하기 위한 표준&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 웹 서버나 WAS 앞에 L4 같은 Load balancers 나 Proxy server, caching server 등의 장비가 있을 경우, &lt;br /&gt;&amp;nbsp; 웹서버는 Proxy server 이나 장비 IP 에서 접속한 것으로 인식&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;==&amp;gt; 웹 서버는 실제 클라이언트 IP가 아니라 앞단 Proxy 서버 를 요청한 IP로 인식 / &lt;b&gt;Proxy&amp;nbsp; 장비 IP로 웹 로그 남김&lt;/b&gt;&lt;br /&gt;&lt;br /&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;웹 프록시 동작에서의 사용자 IP 변환&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;723&quot; data-origin-height=&quot;205&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xAjsD/btrEE0uRDqh/XrWsuhJyiBYY2lD47KbTp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xAjsD/btrEE0uRDqh/XrWsuhJyiBYY2lD47KbTp0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xAjsD/btrEE0uRDqh/XrWsuhJyiBYY2lD47KbTp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxAjsD%2FbtrEE0uRDqh%2FXrWsuhJyiBYY2lD47KbTp0%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;723&quot; height=&quot;205&quot; data-origin-width=&quot;723&quot; data-origin-height=&quot;205&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번 과정에서 클라는 웹 서버와 세션을 맺으려하나 실제로는 웹 프록시와 TCP 세션을 맺게 되며&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3번 과정에서 웹 서버는 클라이언트와 TCP 세션을 맺으려 하나 웹 프록시와 TCP 세션을 맺게 됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;==&amp;gt; 지연 바인딩 과정(Delayed Binding)&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;3번의 과정에서부터 웹 프록시와 웹 서버 간의 동작에서 소스 IP가 웹프록시 IP로 변경되며&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그로 인해&lt;b&gt; 웹 서버는 실제 사용자 IP를 확인하지 못합니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;IP 변경에 따른 고려사항&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자 IP가 변경되게 된다면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 데이터를 통해 수집되는 로그에서 사용자 IP를 구별할 수 없어&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자 IP 기반의 서비스 및 정책들에 제약이 걸려 사용할 수 없게 되기 때문에 클라이언트 IP를 찾을 수 있어야 합니다.&amp;nbsp;&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;h3 data-ke-size=&quot;size23&quot;&gt;XFF&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP 프록시나 LB를 통해 웹 서버에서 접속하는 클라이언트의 실제 IP주소를 식별하는 표준 헤더로&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문법은 아래와 같습니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1655122166448&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;X-Forwarded-For: &amp;lt;client&amp;gt;, &amp;lt;proxy1&amp;gt;, &amp;lt;proxy2&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- client : 클라이언트&amp;nbsp; ip 주소&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- proxy1, proxy2 : 하나의 요청이 여러 프록시를 거치면 각 프록시 ip주소들이 차례로 열거 / 가장 오른쪽 ip 주소가 가장 마지막에 거친 프록시 ip 주소&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;pre id=&quot;code_1655122252117&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String ip = request.getHeader(&quot;X-Forwarded-For&quot;);

if (ip == null || ip.length() == 0 || &quot;unknown&quot;.equalsIgnoreCase(ip)) {
    ip = request.getHeader(&quot;Proxy-Client-IP&quot;);
     # WAS(WebLogic)의 webserver 연계 모듈인 weblogic connector 에서 사용되는 헤더
}
if (ip == null || ip.length() == 0 || &quot;unknown&quot;.equalsIgnoreCase(ip)) {
    ip = request.getHeader(&quot;WL-Proxy-Client-IP&quot;);
    # WAS(WebLogic)의 webserver 연계 모듈인 weblogic connector 에서 사용되는 헤더
}
if (ip == null || ip.length() == 0 || &quot;unknown&quot;.equalsIgnoreCase(ip)) {
    ip = request.getHeader(&quot;HTTP_CLIENT_IP&quot;);
     # PHP . ASP 에서 실제 Clinet IP를 구할때 사용하는 헤더
}
if (ip == null || ip.length() == 0 || &quot;unknown&quot;.equalsIgnoreCase(ip)) {
    ip = request.getHeader(&quot;HTTP_X_FORWARDED_FOR&quot;);
    # PHP . ASP 에서 실제 Clinet IP를 구할때 사용하는 헤더
}
if (ip == null || ip.length() == 0 || &quot;unknown&quot;.equalsIgnoreCase(ip)) {
    ip = request.getRemoteAddr();
}&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;PHP 사용방식&lt;/p&gt;
&lt;pre id=&quot;code_1655122461517&quot; class=&quot;php&quot; data-ke-language=&quot;php&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function getRealClientIp() {
    ...
    if (getenv('HTTP_CLIENT_IP')) {
        ip = getenv('HTTP_CLIENT_IP');
    }
    if(getenv('HTTP_X_FORWARDED_FOR')) {
        ip = getenv('HTTP_X_FORWARDED_FOR');
    }
    ...
}&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;ASP 사용방식&lt;/p&gt;
&lt;pre id=&quot;code_1655122492262&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;string ip = Request.ServerVariables[&quot;HTTP_X_FORWARDED_FOR&quot;]; 
if(string.IsNullOrEmpty(ipaddr)) {
    ip = Request.ServerVariables[&quot;REMOTE_ADDR&quot;];
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Web/web dev</category>
      <category>accelerator</category>
      <category>client IP</category>
      <category>IP</category>
      <category>X-Forwarded-For</category>
      <category>XFF</category>
      <author>exp9405</author>
      <guid isPermaLink="true">https://syujisu.tistory.com/207</guid>
      <comments>https://syujisu.tistory.com/entry/X-Forwarded-ForXFF#entry207comment</comments>
      <pubDate>Wed, 18 May 2022 15:02:07 +0900</pubDate>
    </item>
    <item>
      <title>HTTP/3</title>
      <link>https://syujisu.tistory.com/entry/HTTP3</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Rest API 설계 검색하다가, HTTP/3가 베타 중(?)이라는 소식에 정리해보는 페이지입니다.&amp;nbsp;&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;HTTP/3&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP/3 : HTTP(Hypertext Transfer Protocol)의 세번째 메이저 버전으로, &lt;br /&gt;HTTP/1, HTTP/2 와 다르게 UDP 기반의 프로토콜(&lt;span style=&quot;background-color: #dddddd;&quot;&gt;QUIC(Quick UDP Internet Connection))&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;TCP(HTTP/1,2) vs UDP&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;TCP&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;UDP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;연결 방식&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;연결형 서비스&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;비연결형 서비스&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;패킷 교환&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;가상 회선 방식&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;데이터그램 방식&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;전송 순서 보장&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;보장함&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;보장하지 않음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;신뢰성&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;높음&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;낮음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;전송 속도&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;느림&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;빠름&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP : 신뢰성이 높고 느리며 (느린 이유는 &lt;a title=&quot;3 way Handshake&quot; href=&quot;https://syujisu.tistory.com/entry/TCP-IP&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;3 way Handshake&lt;/a&gt;를 사용하기 때문)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UDP : 신뢰성이 낮고 빠르다&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 data-ke-size=&quot;size16&quot;&gt;TCP는 클라-서버간의 통신에서 신뢰성을 가지기 위해 노력하지만 결국, &lt;a title=&quot;레이턴시&quot; href=&quot;https://syujisu.tistory.com/entry/%EB%A0%88%EC%9D%B4%ED%84%B4%EC%8B%9C-%EB%8C%80%EC%97%AD%ED%8F%AD&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;레이턴시&lt;/a&gt;가 발생할 수 밖에 없다.(TCP 표준)&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;레이턴시를 줄이기 위해서는 TCP 표준에서 벗어나는 부분을 조작해서 회선 대역폭을 늘린다 하여도 ,&amp;nbsp;&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;nbsp;&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;QUIC&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP 의 레이턴시 한계를 극복하고자 구글이 개발한 UDP 기반의 프로토콜로&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP 핸드쉐이크 과정을 최적화하는 것에 초점을 두었다.&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;640&quot; data-origin-height=&quot;559&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ci0Ihm/btrrJGgj4Lm/1jCzcKUeTCE9FdqDbJy8h1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ci0Ihm/btrrJGgj4Lm/1jCzcKUeTCE9FdqDbJy8h1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ci0Ihm/btrrJGgj4Lm/1jCzcKUeTCE9FdqDbJy8h1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fci0Ihm%2FbtrrJGgj4Lm%2F1jCzcKUeTCE9FdqDbJy8h1%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;239&quot; height=&quot;209&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;559&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;UDP 는 데이터그램 방식의 프로토콜로&amp;nbsp;&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;/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;그래서 왜 QUIC은 UDP를 선택했을까?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론, TCP를 사용하다가 UDP로 바로 갈아탄다고 해도, 모든 이슈가 해결되지는 않지만&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UDP의 커스텀 기능 이용을 통한다면 기존 TCP가 가지고 있는 기능을 모두 구현할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;89&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Uf3jH/btrrDwl80vD/zhtRKHf46pJFbQuUC600bk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Uf3jH/btrrDwl80vD/zhtRKHf46pJFbQuUC600bk/img.png&quot; data-alt=&quot;UDP Header&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Uf3jH/btrrDwl80vD/zhtRKHf46pJFbQuUC600bk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUf3jH%2FbtrrDwl80vD%2FzhtRKHf46pJFbQuUC600bk%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;640&quot; height=&quot;89&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;89&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;UDP Header&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;데이터 전송 자체에만 초점이 맞추어 있기 때문에 출발지, 도착지, 패킷 길이, 체크섬(옵션) 만 존재(위 그림)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 어떻게 개발자가 구현하냐에 따라&lt;br /&gt;TCP와 비슷한 수준의 기능을 가질 수 있으며 핸드쉐이크를 사용하지 않을 수 있다는 의미와 같다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;http3가-udp를-사용함으로써-기존-프로토콜보다-나아진-점&quot; data-ke-size=&quot;size26&quot;&gt;HTTP/3가 UDP를 사용하여, 기존 프로토콜보다 개선된 점&amp;nbsp;&lt;/h2&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;u&gt;&lt;b&gt;1. 연결 설정 시 레이턴시 감소&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트 보낸 요청 -&amp;gt; 서버 처리 -&amp;gt; 다시 클라이언트로 응답해주는 사이클을 RTT(Round Trip Time)이라 하는데,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 설명한 내용과 같이 QUIC은 첫 연결 설정에서 1RTT만 소요된다. (아래 그림 참조)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;381&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bV6e1W/btrrJaa9h8Y/Y7wK9V1p1Pk55PgB1U7uIK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bV6e1W/btrrJaa9h8Y/Y7wK9V1p1Pk55PgB1U7uIK/img.gif&quot; data-alt=&quot;TCP + TLS VS QUIC&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bV6e1W/btrrJaa9h8Y/Y7wK9V1p1Pk55PgB1U7uIK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bV6e1W/btrrJaa9h8Y/Y7wK9V1p1Pk55PgB1U7uIK/img.gif&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;600&quot; height=&quot;381&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;381&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;TCP + TLS VS QUIC&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;첫번째 핸드쉐이크를 거칠 때 &lt;br /&gt;연결 설정에 필요한 정보(+(초키화 키(initial Key) 통해 통신 암호화)와 함께 데이터도 함께 보내기 때문에 가능한 일이다.&lt;br /&gt;(TCP+TLS는 데이터 발송 전 신뢰성있는 연결, 암호화에 필요한 모든 정보를 교환하고 유효성 검사 후 데이터 교환)&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;u&gt;&lt;b&gt;2. 패킷 손실 감지에 걸리는 시간 단축&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;패킷 전송 -&amp;gt; 타임 아웃 -&amp;gt; 패킷 재전송 -&amp;gt; ACK 받음 의 통신을 진행하는데&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이때 ACK가 어떤 패킷에서 온건지 확인하기 위해&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;QUIC는 헤더에 별도의 패킷 번호 공간을 부여하였다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;해당 번호는 패킷의 전송 순서 자체만을 의미하고 매 전송마다 모노토믹하게 패킷 번호가 증가하기 때문에 패킷의 전송 순서를 명확하게 파악할 수 있다. &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;u&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3. 멀티플렉싱 지원&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;여러 개의 스트림을 사용하여 그 중 특정 스트림의 패킷이 손실되었다고 하여도 해당 스트림에만 영향을 미치고 타 스트림에 영향을 주지않아 TCP의 단점인 HOLB(Head of Line Blocking)을 방지할 수 있다. (=HTTP/2와 동일)&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;u&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4. 클라이언트 IP 변동되어도 연결 유지&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Connection ID를 사용하여 서버와 연결을 생성하는데,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 Connection ID는 랜덤한 값일 뿐 클라이언트 IP와 전혀 무관하기 때문에 클라이언트 IP가 변경되어도 기존 연결을 지속적으로 유지할 수 있다. (=새롭게 연결을 생성할때 핸드쉐이크 과정을 생략할 수 있다는 말과 같다)&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 data-ke-size=&quot;size16&quot;&gt;기존의 HTTP , TCP 방식에서 벗어날 용도로 쓸 수 있지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;grpc와 비교할 필요가 있을 것 같다 (비슷한 용도지 않나?)&lt;/p&gt;</description>
      <category>Web/web dev</category>
      <category>HTTP</category>
      <category>HTTP/3</category>
      <category>http통신</category>
      <category>QUIC</category>
      <author>exp9405</author>
      <guid isPermaLink="true">https://syujisu.tistory.com/206</guid>
      <comments>https://syujisu.tistory.com/entry/HTTP3#entry206comment</comments>
      <pubDate>Tue, 25 Jan 2022 19:27:51 +0900</pubDate>
    </item>
    <item>
      <title>[JD]데이터 PM</title>
      <link>https://syujisu.tistory.com/entry/JD%EB%8D%B0%EC%9D%B4%ED%84%B0-PM</link>
      <description>&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 PM&amp;nbsp; 직군 채용이 거의 없었으나..&amp;nbsp;&lt;br /&gt;타 기업에서 채용이 많아져 JD를 모아두고 어떤 역량이 필요한지 &lt;br /&gt;앞으로의 커리어를 어떻게 가져갈지를 생각해보기 위한 게시글입니다.&amp;nbsp;&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 data-ke-size=&quot;size16&quot;&gt;데이터 PM의 RNR은 경우 큰 틀로 보자면 아래와 같을 것 같고&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;데이터 수집/가공/제공의 전반에 걸친 로드맵 설계 및 관리&lt;/li&gt;
&lt;li&gt;데이터 관련 요구사항을 통해 커뮤, 분석, 정리하여 수집 시스템 및 서비스를 설계 ,개발, 연동, 트러블 슈팅&lt;/li&gt;
&lt;/ol&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;PM&amp;nbsp;&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로젝트 리드 경험&lt;/li&gt;
&lt;li&gt;타 부서와 커뮤니케이션 경험&amp;nbsp;&lt;/li&gt;
&lt;li&gt;데이터 통한 지표 및 서비스 설계 경험&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Data
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SQL&lt;/li&gt;
&lt;li&gt;python (or R)&lt;/li&gt;
&lt;li&gt;bi (태블로 및 대시보드)&amp;nbsp;&lt;/li&gt;
&lt;li&gt;로그 데이터 활용 경험&amp;nbsp;&lt;/li&gt;
&lt;li&gt;개발 경험&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하기에 데이터 PM 직군 공고를 모아두었습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;토스&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Product Manager (Data)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토스 소개&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토스(비바리퍼블리카)는 2015년 2월 공인인증서 없이 쉽고 빠르게 송금할 수 있는 간편 송금 서비스 &amp;lsquo;토스&amp;rsquo;를 선보인 이래, 보험과 결제, 증권, 은행 부문에서 여러 계열사를 출범시키며 국내 대표 핀테크 기업으로 성장했습니다. 대한민국 금융 혁신을 선도하고 있는 토스에는 각 분야 최고 수준의 역량을 갖춘 인재들이 모여 자율과 책임의 원칙 아래 상호 신뢰의 문화에서 일하고 있습니다.&lt;/p&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터/AI Product Manager는 토스의 데이터/AI팀과 함께 토스 서비스의 사용자와 혹은 주변 동료인 사일로와 함께하는 플랫폼 및 머신러닝 서비스를 설계 및 운영하고 정책을 결정하는 일을 합니다.&lt;/li&gt;
&lt;li&gt;데이터를 이해하고, 머신러닝(데이터) 사이언티스트들과 협업하여 신규 서비스 및 기술을 개발하고 론칭하는 일을 하게 됩니다.고객 지향적인 서비스 정책을 설계하고 운영함으로서 지속 가능한 제품 개발을 지원합니다.&lt;/li&gt;
&lt;li&gt;급변하는 시장과 비즈니스 관계 속에서 정성/정량적으로 서비스를 진단하고 새로운 기회를 발굴합니다.&lt;/li&gt;
&lt;li&gt;이해 관계자와 협업을 통해 빠르고 정확하게 문제를 파악하고 해결합니다.&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;IT 서비스를 운영해본 경험이 있으셔야 합니다.&lt;/li&gt;
&lt;li&gt;기술을 활용한 서비스를 운영 및 설계한 경험이 필요합니다.&lt;/li&gt;
&lt;li&gt;문제의 근본 원인을 찾고 규명을 할 수 있으며, 솔루션을 제시할 수 있는 분을 찾습니다.&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로젝트 PM 역할을 3년 이상 경험하신 분이면 좋습니다.&lt;/li&gt;
&lt;li&gt;AI/Data, 모바일 서비스 및 핀테크 관련 서비스 운영 경험이 있으신 분이면 좋습니다.&lt;/li&gt;
&lt;/ul&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;gt; 직무 인터뷰 &amp;gt; 문화적합성 인터뷰 &amp;gt; 최종 합격&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;우아한 형제들&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[업무내용]&amp;nbsp;&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;br /&gt;-&amp;nbsp;운영 상황에 대한 품질수준 목표를 수립하고 모니터링하여&lt;br /&gt;&amp;nbsp; 개선이 필요하거나 풀어야할 문제들을 발굴하고 과제화 하는 일&lt;br /&gt;- 프로덕트실과 사업부서의 협업 과정에서 의견을 조율하고, 다양한 관점을 프로덕트에 담아내는 일&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;[지원자격]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 3~8년의 데이터 분석가 경력이 있는 분&amp;nbsp;&lt;br /&gt;- 데이터 분석을 통해 의미있는 인사이트를 도출해 본 경험이 있는 분&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- SQL을 활용한 데이터 추출 및 R, Excel 등을 활용한 데이터 분석이 능숙한 분&lt;br /&gt;- 프로젝트를 주도적으로 수행해 성과를 낸 경험이 있는 분&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;[우대사항]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Tableau, Redash 등의 툴을 활용해 대시보드를 구현해본 경험이 있는 분&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 숫자 기반의 논리적 추론 결과를 바탕으로 사업과 기술 측면에서 효과적으로 소통할 수 있는 분&lt;br /&gt;- 다양한 부서와 협업하며, 이해와 존중을 바탕으로 유연하게 커뮤니케이션이 가능한 분&lt;br /&gt;- 일의 처리과정을 효율화하고, 체계적인 프로세스를 설계해 본 경험이 있는 분&lt;br /&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;원티드&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주요업무&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;bull; 데이터 수집/가공/제공의 전반에 걸친 로드맵 설계 및 관리&lt;br /&gt;&amp;bull; 데이터 관련 요구사항 커뮤니케이션/분석/정리 및 제품/서비스 설계/연동/트러블슈팅&lt;br /&gt;&amp;bull; 수집되는 데이터의 규격화 및 정합성 관리&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;bull; 원티드의 기업문화, Wanted Way 와 잘 맞는 분 (&lt;/span&gt;&lt;a href=&quot;https://bit.ly/3kT1BFQ&quot;&gt;https://bit.ly/3kT1BFQ&lt;/a&gt;&lt;span&gt;)&lt;br /&gt;&amp;bull; 데이터 분석가/데이터 엔지니어/서비스PM 등의 경력 2년 이상&lt;br /&gt;&amp;bull; 웹/앱 제품 사용 중에 발생하는 유저행동 로그를 기획, 생성, 정합성 검증하여 분석에 활용하거나, 분석가에게 제공하는 업무 1년 이상&lt;br /&gt;&amp;bull; Google Tag Manager등을 활용하여 웹/앱 이벤트를 다수 생성하고, 발생한 로그를 분석툴에서 뿐만 아니라 data warehouse에서 조회한 경험&lt;br /&gt;&amp;bull; 현업에서의 데이터 지표 분석 툴 사용 경험 (Google Analytics, Google Tag Manager, Amplitude, Google Optimize, Appsflyer, Braze, Tableu 등)&lt;br /&gt;&amp;bull; 다수의 데이터 소스에서 수집되는 데이터를 join 가능하도록 가공하거나, 플랫폼을 도입한 경험&lt;br /&gt;&amp;bull; SQL 활용 능력 중급 이상&lt;br /&gt;&amp;bull; 개발자 및 business side와의 커뮤니케이션에 문제가 없으신 분&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;&amp;nbsp;&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;&lt;span&gt;카카오&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;데이터 프로덕트 PM은 이전에 없던 새로운 역할입니다. 서비스 PM/서비스 기획자/데이터 분석가/그로스 해커 등으로 알려진 역할을 데이터 프로덕트 개발 단계에 따라 수행하게 됩니다.&lt;/span&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;/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;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 업무는 개인의 경험과 역량에 따라 1인 혹은 소규모 팀으로 수행하게 되며, 제품 개발을 위해 디자이너/개발자/QA 등 다양한 전문가들과 소통하고 협업하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;br /&gt;◆&lt;b&gt;지원자격&lt;/b&gt;&lt;br /&gt;&lt;/span&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;데이터 분석가/퍼포먼스 마케터/서비스 PM 등의 직군에서 최소 1년 이상 업무 경력 보유자&lt;/li&gt;
&lt;li&gt;로그 수준의 데이터를 다루는 업무 최소 1년 이상 경험자 (데이터 분석가/데이터 엔지니어/서비스 개발자/통계학자 등 세부 분야는 무관)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;/li&gt;
&lt;li&gt;신규 서비스 컨셉 도출부터 런칭까지 전체 프로세스 경험 보유자&lt;/li&gt;
&lt;li&gt;Performance marketing/product optimization 등 실험 기반 업무 2년 이상 경험 보유자&lt;/li&gt;
&lt;li&gt;다양한 형태의 raw data를 다뤄본 경험 보유자&lt;/li&gt;
&lt;/ul&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;조이시티&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&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 data-ke-size=&quot;size16&quot;&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;b&gt;담당업무&lt;/b&gt; &lt;br /&gt;-&amp;nbsp;게임&amp;nbsp;구조에&amp;nbsp;적합한&amp;nbsp;지표&amp;nbsp;로그의&amp;nbsp;설계&amp;nbsp;및&amp;nbsp;적용&amp;nbsp; &lt;br /&gt;-&amp;nbsp;설계된&amp;nbsp;로그를&amp;nbsp;적용&amp;nbsp;및&amp;nbsp;활용하는&amp;nbsp;유관부서와의&amp;nbsp;커뮤니케이션,&amp;nbsp;협업&amp;nbsp;및&amp;nbsp;문서화&amp;nbsp;작업 &lt;br /&gt;-&amp;nbsp;적재된&amp;nbsp;로그&amp;nbsp;데이터의&amp;nbsp;품질&amp;nbsp;관리&amp;nbsp; &lt;br /&gt;- 데이터 시각화 관련 업무&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 데이터 pm(지표 로그 설계 , 적용, 품질관리 및 시각화)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Google Cloud 의 data Product를 활용한 데이터 처리 고도화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 데이터 기반의 product 백엔드 개발&amp;nbsp;&lt;br /&gt;&lt;b&gt;자격요건&lt;/b&gt; &lt;br /&gt;-&amp;nbsp;유관&amp;nbsp;직무&amp;nbsp;(PM/&amp;nbsp;개발/&amp;nbsp;기획/&amp;nbsp;분석/&amp;nbsp;운영/&amp;nbsp;데이터&amp;nbsp;QA/&amp;nbsp;데이터&amp;nbsp;엔지니어)&amp;nbsp;중&amp;nbsp;한&amp;nbsp;가지&amp;nbsp;이상의&amp;nbsp;직무에&amp;nbsp;대한&amp;nbsp;경험&amp;nbsp; &lt;br /&gt;-&amp;nbsp;데이터와&amp;nbsp;게임&amp;nbsp;서비스에&amp;nbsp;대한&amp;nbsp;관심&amp;nbsp;및&amp;nbsp;이해&amp;nbsp;&amp;nbsp; &lt;br /&gt;-&amp;nbsp;여러&amp;nbsp;유관&amp;nbsp;조직과의&amp;nbsp;커뮤니케이션을&amp;nbsp;원활하게&amp;nbsp;수행하실&amp;nbsp;수&amp;nbsp;있으신&amp;nbsp;분 &lt;br /&gt;&lt;br /&gt;&lt;b&gt;우대사항&lt;/b&gt; &lt;br /&gt;-&amp;nbsp;동종&amp;nbsp;업계&amp;nbsp;경력&amp;nbsp;또는&amp;nbsp;유관&amp;nbsp;학과&amp;nbsp;전공자&amp;nbsp; &lt;br /&gt;-&amp;nbsp;SQL&amp;nbsp;사용&amp;nbsp;가능자&amp;nbsp;또는&amp;nbsp;개발&amp;nbsp;경험자&amp;nbsp; &lt;br /&gt;-&amp;nbsp;업무나&amp;nbsp;주변&amp;nbsp;정리를&amp;nbsp;체계적으로&amp;nbsp;하는&amp;nbsp;것을&amp;nbsp;즐겨&amp;nbsp;하시는&amp;nbsp;분&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 로그 처리 &amp;amp; 분석 경험이 있거나 유관 학과 전공&amp;nbsp;&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;nbsp;&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span&gt;카카오 뱅크&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;&lt;b&gt;&lt;span&gt;담당할 업무&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;[데이터프로덕트&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;middot;&amp;nbsp;&lt;/span&gt;&lt;span&gt;데이터 기반 사업 과제 기획과 운영&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp;-&amp;nbsp;&lt;/span&gt;&lt;span&gt;추천 시스템과 이상탐지 솔루션 설계 운영&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp;-&amp;nbsp;&lt;/span&gt;&lt;span&gt;서비스 지표 구성이나 분석/모델링 관련 요구사항을 정의&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp;-&amp;nbsp;&lt;/span&gt;&lt;span&gt;분석가 및 엔지니어들과 협업을 통한 과제 관리 지원&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;&lt;b&gt;필수 경험과 역량&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;middot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;데이터 관련 플랫폼 기획 또는 운영 경험 3년 이상인 분&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;middot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;통계 또는 머신러닝 관련 내용을 이해할 수 있는 분&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;middot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;적극적이고 원만한 커뮤니케이션이 가능한 분&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;우대사항&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;middot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;Python, Java, Scala 등 프로그래밍 언어 사용 경험이 있는 분&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;middot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;전산/수학/통계 또는 관련 분야 학사 학위 이상인 분&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;middot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;추천 서비스/시스템 기획 및 운영 경험이 있는 분&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;middot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;이상탐지 관련 솔루션 설계 및 운영 경험이 있는 분&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;middot;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&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;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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span&gt;넥슨&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;데이터 플랫폼 기획/PM&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;주요업무&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;[조직소개]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;- 인텔리전스랩스는 다양한 게임 정보를 활용해 &amp;lsquo;빅데이터&amp;rsquo;, &amp;lsquo;머신러닝&amp;middot;딥러닝&amp;rsquo;, &amp;lsquo;인공지능(AI)&amp;rsquo; 기술과 공학적 사고를 통해 솔루션을 만들고 게임 사용자와 넥슨 구성원이 사용할 서비스를 제공하는 조직입니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;- 인텔리전스랩스 소속 미들웨어플랫폼실은 게임 데이터를 표준 모델링하여 통합 서비스로 제공 하는 것을 목표로 합니다. 동시에 게임 빅데이터를 가공하여 사용자에게 실시간으로 제공하는 것을 목표로 합니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;- 데이터 플랫폼 기획/PM은 게임과 게임을 구성하는 데이터에 대한 인사이트를 얻으실 있는 포지션으로, 많은 분들의 관심 부탁드립니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://nexon.link/8bT&quot;&gt;[인텔리전스랩스 테크블로그 바로가기]&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;[업무소개]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;- 게임 또는 연관 솔루션에서 사용할 공통화 된 API의 기획&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;- 개발 프로젝트 PM 및 유관부서간 커뮤니케이션&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;- 기술 문서 작성 및 관리&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;- 백오피스 기획 및 관리&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;지원자격&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;- 게임을 사랑하시는 분&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;- IT 관련 서비스 기획 또는 데이터 설계 경력 1년 이상&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;우대사항&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;- 메인 담당자로서 하나 이상의 서비스를 초기 컨셉 기획-제안-설계-런칭-운영까지 Full-cycle 경험이 있으신 분&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;- 게임 트렌드에 대한 지속적인 호기심과 새로운 아이디어 대해 주저없는 의견 제시가 가능하신 분&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;기타사항&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;- 본 공고는 채용 완료 시 조기 마감될 수 있습니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;- 서류 접수 이후 한 달 이내 전형 결과를 안내드립니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;- 국가보훈대상자는 관련 법규에 의거하여 우대합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>Job Interview &amp;amp; etc/etc</category>
      <category>Data PM</category>
      <category>JD</category>
      <category>데이터pm</category>
      <author>exp9405</author>
      <guid isPermaLink="true">https://syujisu.tistory.com/205</guid>
      <comments>https://syujisu.tistory.com/entry/JD%EB%8D%B0%EC%9D%B4%ED%84%B0-PM#entry205comment</comments>
      <pubDate>Tue, 18 Jan 2022 14:40:48 +0900</pubDate>
    </item>
  </channel>
</rss>