<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>괜찮겠어? 난 멈추는 법을 모르는 토끼인데</title>
        <link>https://velog.io/</link>
        <description>Developer로의 여정</description>
        <lastBuildDate>Thu, 07 Sep 2023 12:13:11 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>괜찮겠어? 난 멈추는 법을 모르는 토끼인데</title>
            <url>https://velog.velcdn.com/images/w0_0727/profile/b5655aa8-8e42-4d0d-8ac4-25475002ca18/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. 괜찮겠어? 난 멈추는 법을 모르는 토끼인데. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/w0_0727" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[프로그래머스] lv.2 의상]]></title>
            <link>https://velog.io/@w0_0727/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-lv.2-%EC%9D%98%EC%83%81</link>
            <guid>https://velog.io/@w0_0727/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-lv.2-%EC%9D%98%EC%83%81</guid>
            <pubDate>Thu, 07 Sep 2023 12:13:11 GMT</pubDate>
            <description><![CDATA[<h1 id="문제">문제</h1>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/42578">https://school.programmers.co.kr/learn/courses/30/lessons/42578</a></p>
<h1 id="정답">정답</h1>
<pre><code class="language-py">from collections import Counter
def solution(clothes):
    clothes_dic = Counter([clothe[1] for clothe in clothes]) 
    count = 1
    # clothes_dic = {&#39;headgear&#39;: 2, &#39;eyewear&#39;: 1}
    for stock in clothes_dic.values(): # 각 종류의 옷의 개수를 가져온다. 
        count = count*(stock +1) # 안입는 경우 +1를 더해준다. 
    print(count-1) # 아무것도 안입는 경우를 빼준다.
    return count-1
solution([[&quot;yellow_hat&quot;, &quot;headgear&quot;], [&quot;blue_sunglasses&quot;, &quot;eyewear&quot;], [&quot;green_turban&quot;, &quot;headgear&quot;]])</code></pre>
<h1 id="풀이">풀이</h1>
<p>만약 상의: a,b 하의: c,d 이렇게 아이템이 있을 경우 경우의 수는 아래와 같다.</p>
<ol>
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>a,c</li>
<li>a,d</li>
<li>b,c</li>
<li>b,d</li>
</ol>
<p>그리고 이것은 다시 생각해보면, 상의: a,b,착용x / 하의: c,d,착용x 로 볼 수 있다. 
하지만 착용x,착용x인 경우는 제외해줘야 하므로, 3*3-1을 하면 된다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] lv.2 전화번호목록]]></title>
            <link>https://velog.io/@w0_0727/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-lv.2-%EC%A0%84%ED%99%94%EB%B2%88%ED%98%B8%EB%AA%A9%EB%A1%9D</link>
            <guid>https://velog.io/@w0_0727/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-lv.2-%EC%A0%84%ED%99%94%EB%B2%88%ED%98%B8%EB%AA%A9%EB%A1%9D</guid>
            <pubDate>Tue, 05 Sep 2023 00:06:46 GMT</pubDate>
            <description><![CDATA[<h1 id="문제">문제</h1>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/42577">https://school.programmers.co.kr/learn/courses/30/lessons/42577</a></p>
<h1 id="해결">해결</h1>
<pre><code class="language-py">def solution(phone_book):
    answer = True
    phone_book.sort()
    print(phone_book)
    for i in range(len(phone_book)-1):
        if phone_book[i] == phone_book[i+1][:len(phone_book[i])]:
            answer = False
    return answer</code></pre>
<h1 id="풀이">풀이</h1>
<p>1) phone_book을 sort해준다.
2) phone_book[i]와 phone_book[i+1]을 비교하는데, 이때 phone_book의 길이만큼만 비교해준다.
3) 같으면 F, 다르면 T 반환</p>
<p>처음에 어떻게 접두사만 비교할지 몰라서 고민을 많이 했다.</p>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/03f1c033-4ce9-48d1-8b77-25faa567c4d8/image.png" alt=""></p>
<h3 id="다른-풀이">다른 풀이</h3>
<p>근데 이건 Hash 분류의 문제다. Hash로 해결한 풀이를 보자.</p>
<pre><code class="language-py">def solution(phone_book):
    answer = True
    hash_map = {}
    for phone_number in phone_book:
        hash_map[phone_number] = 1
    for phone_number in phone_book:
        temp = &quot;&quot;
        for number in phone_number:
            temp += number
            if temp in hash_map and temp != phone_number:
                answer = False

    return answer
solution([&quot;12&quot;,&quot;123&quot;,&quot;1235&quot;,&quot;567&quot;,&quot;88&quot;])</code></pre>
<ol>
<li><p><code>hash_map</code>이라는 딕셔너리를 생성, 이 딕셔너리는 전화번호를 키로 가지며, 해당 전화번호가 phone_book에 존재함을 나타내기 위해 모든 키의 값은 1로 설정한다.</p>
</li>
<li><p>다음으로, 각 전화번호를 다시 순회하면서 각 숫자를 하나씩 추가하여 temp 문자열을 생성한다. 이렇게 하면 temp는 phone_number의 접두사들을 차례대로 생성할 수 있다.</p>
</li>
<li><p>이제 <code>temp</code> 문자열이 <code>hash_map</code> 딕셔너리의 키 중 하나인지 확인한다. 만약 <code>temp</code>가 딕셔너리의 키 중 하나라면, 그것은 <code>temp</code>가 다른 전화번호의 접두사임을 의미함.</p>
</li>
<li><p>그러나 자기 자신은 자기 자신의 접두사라고 할 수 없으므로, 마지막으로 현재 검사하는 전화번호(<code>phone_number</code>)와 temp가 같은지 확인한다.</p>
</li>
<li><p>만약 temp와 phone_number가 같다면, 그것은 단순히 현재 검사하는 번호 자체인 경우이므로 무시하고 계속 진행한다.</p>
</li>
<li><p>그러나 만약 temp와 phone_number가 다르다면, 그것은 현재 검사하는 번호(<code>phone_number</code>) 외에도 다른 번호에서 사용되는 접두어(<code>temp</code>) 가 있다는 것을 의미하므로 answer를 False 로 설정하고 루프에서 벗어남.</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] lv.2 올바른 괄호]]></title>
            <link>https://velog.io/@w0_0727/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-lv.2-%EC%98%AC%EB%B0%94%EB%A5%B8-%EA%B4%84%ED%98%B8</link>
            <guid>https://velog.io/@w0_0727/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-lv.2-%EC%98%AC%EB%B0%94%EB%A5%B8-%EA%B4%84%ED%98%B8</guid>
            <pubDate>Thu, 31 Aug 2023 07:54:31 GMT</pubDate>
            <description><![CDATA[<h1 id="문제">문제</h1>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/12909">https://school.programmers.co.kr/learn/courses/30/lessons/12909</a></p>
<h1 id="정답">정답</h1>
<pre><code class="language-py">def solution(s):
    stack = []
    answer = True

    for i in s:
        if i == &quot;(&quot;:
            stack.append(i)
        else:
            if stack == []: # 1. (보다 )가 먼저 나온 경우 False
                answer = False
                break
            else:
                stack.pop()
    if stack != []: # 2. ( , )의 개수가 맞지 않은 경우 False
        answer = False
    return answer</code></pre>
<h1 id="풀이">풀이</h1>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/d8b9beb4-35f1-4582-828f-57599d9f6a81/image.jpeg" alt=""></p>
<p>Queue로도 해결할 수 있다.</p>
<p>[아래는 Queue로 접근한 풀이]</p>
<pre><code class="language-py">from collections import deque

def solution(s):
    queue = deque()
    for i in s:
        if i == &quot;(&quot;:
            queue.append(&quot;(&quot;)
        else:
            if len(queue) != 0:
                queue.pop()
            else:
                return False
    if len(queue) != 0:
        return False
    else:
        return True</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Prompt Engineering이란?]]></title>
            <link>https://velog.io/@w0_0727/i4uh3e4e</link>
            <guid>https://velog.io/@w0_0727/i4uh3e4e</guid>
            <pubDate>Thu, 24 Aug 2023 03:54:07 GMT</pubDate>
            <description><![CDATA[<h2 id="prompt란">Prompt란?</h2>
<blockquote>
<p>프롬프트는 사용자가 원하는 출력을 생성하고자 할 때 LLM을 안내하기 위해 특정 입력 텍스트 및 질문 텍스트, 긴 기사를 요약하고 싶다면 LLM(Large Language Model)에 “Summarize the above in one sentence”와 같은 프롬프트와 기사 텍스트를 입력할 수 있다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/853c8a9b-c314-4f15-aa6a-8f984e9fbb0d/image.png" alt=""></p>
<h2 id="prompt-engineering의-목적과-이유">Prompt Engineering의 목적과 이유</h2>
<p>Prompt Engineering의 주요 목표는 <strong>사용자의 의도와 원하는 결과를 전달하는 프롬프트를 만들어 모델의 성능, 정확성, 유용성을 극대화</strong>하는 것이다.
프롬프트 엔지니어링이 필요한 이유는 현재 LLM의 동작 방식의 한계와 인간과 컴퓨터의 상호작용을 위해 <strong>자연어를 사용</strong>하고 있기 때문이다.</p>
<h4 id="1-auto-regression-llm의-한계">1. Auto-Regression LLM의 한계</h4>
<p>LLM은 단어의 순서, 작은 변화에도 응답의 품질이 상당히 달라질 수 있다. 대표적인 LLM인 GPT 모델도 Auto-Regression 모델이다. uto-Regression LLM은 이전 단어를 보고 가장 높은 확률의 단어를 다음 단어로 예측하므로 단어의 순서에 따라 얼마든지 다른 답변을 출력할 수 있는 것이다. </p>
<h4 id="2-인간-컴퓨터간의-인터페이스로-자연어-사용">2. 인간-컴퓨터간의 인터페이스로 자연어 사용</h4>
<p>자연어는 인간에게는 편리하지만, 컴퓨터에게는 불친절하다. 자연어는 매우 모호하고, 부정확하고, Context에 매우 의존적이며, 사람마다 해석이 다를 수 있다.
<img src="https://velog.velcdn.com/images/w0_0727/post/ece29209-265c-4df4-a38a-1384fef25dcb/image.png" alt=""></p>
<h4 id="3-llm의-한계">3. LLM의 한계</h4>
<p>현재의 LLM은 장기 기억을 갖지 못하고, 자기 주위의 컨텍스트를 이해할 수 없다. </p>
<h2 id="prompt-engineering-vs-prompt-tuning">Prompt Engineering vs Prompt Tuning</h2>
<h3 id="프롬프트-엔지니어링">프롬프트 엔지니어링</h3>
<p>프롬프트 엔지니어링은 Pre-training된 LLM을 별도의 학습없이 사용자가 원하는 답변을 생성하도록 입력 <strong>프롬프트를 효과적으로 설계</strong>하는 기술</p>
<h3 id="프롬프트-튜닝">프롬프트 튜닝</h3>
<p>LLM을 fine-tuning하는 기술로, 주어진 입력 프롬프트에 대해 원하는 답변을 생성하는 LLM을 만들기 위함이다. 프롬프트 튜닝을 통해 LLM은 내부 표현에 대한 미묘한 조정을 배우며 LLM을 광범위하게 재학습하거나 수정하지 않고도 특정 작업이나 프롬프트을 더 잘 수행할 수 있다. </p>
<h2 id="프롬프트-엔지니어링과-프롬프트-튜닝의-장단점">프롬프트 엔지니어링과 프롬프트 튜닝의 장단점</h2>
<h3 id="프롬프트-엔지니어링-1">프롬프트 엔지니어링</h3>
<ul>
<li><strong>장점</strong>: 프롬프트 엔지니어링은 출력을 더 많이 제어할 수 있다. 또한 LLM을 원하는 출력으로 안내하도록 프롬프트를 신중하게 만들 수 있다.</li>
<li><strong>단점</strong>: 프롬프트 엔지니어링은 사람의 입력이 더 많이 필요하기 때문에 프롬프트 튜닝보다 더 많은 시간이 소요된다. 프롬프트는 신중하게 작성해야 하며 효과적인 프롬프트를 찾기 위해 시행 착오가 필요하다.<h3 id="프롬프트-튜닝-1">프롬프트 튜닝</h3>
</li>
<li><strong>장점</strong>: 프롬프트 튜닝은 더 자동화되어 있기 때문에 프롬프트 엔지니어링보다 빠르고 쉽다. 프롬프트는 모델에 의해 자동으로 생성되며 사람의 입력이 필요하지 않는다.</li>
<li><strong>단점</strong>: 프롬프트 튜닝은 출력에 대한 많은 제어를 허용하지 않기 때문에 프롬프트 엔지니어링보다 덜 효과적이다. 프롬프트는 모델에 의해 생성되며 사람이 세심하게 만든 프롬프트만큼 효과적이지 않을 수 있다. </li>
</ul>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/680aaf27-f432-4ba0-b380-00aa9d910311/image.png" alt=""></p>
<h2 id="프롬프트-작성을-위한-기본-가이드라인">프롬프트 작성을 위한 기본 가이드라인</h2>
<h3 id="1미사여구를-최소화한-쉽고-간결한-표현">1)미사여구를 최소화한 쉽고 간결한 표현</h3>
<p>👎 혹시 가능하다면 인공지능 분야에서 트랜스포머가 어떤 개념인지 파이썬이나 C++ 같은 프로그래밍 언어들을 한 번도 활용해본적 없는 모든 사람들을 대상으로 알아듣기 쉽게 글로 설명해 줄 수 있어?</p>
<p>👍 비개발자들을 대상으로 트랜스포머의 개념을 이해하기 쉽게 설명해줘.</p>
<h3 id="2열린-질문보다-닫힌-지시문">2)열린 질문보다 닫힌 지시문</h3>
<p>👎 프롬프트 엔지니어라는 직업이 미래에도 지속될 수 있을까?</p>
<p>👍 프롬프트 엔지니어가 미래에도 지속될 수 직업인지에 대한 보고서를 써줘.</p>
<h3 id="3instruction과-context를-구체적으로-명시">3)Instruction과 Context를 구체적으로 명시</h3>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/6fc9f0bd-d37a-4ab3-ac2d-2c07c2d2275f/image.png" alt=""></p>
<h3 id="예제를-함께-제공">예제를 함께 제공</h3>
<p>올바른 질문과 답변 예제를 한 개 또는 다수 제공하는 기법을 활용</p>
<h4 id="one-shot-prompting">One-Shot Prompting</h4>
<blockquote>
<p>하나의 예제 또는 템플릿를 기반으로 답변을 생성하게 하는 기법, Dialogue management, 또는 context modeling과 같은 기타 NLP 기법들과 조합되어 보다 정확한 답변을 유도할 수 있음
<img src="https://velog.velcdn.com/images/w0_0727/post/f8aebf50-d13a-4d6a-95c4-8fa5937f834e/image.png" alt=""></p>
</blockquote>
<h4 id="few-shot-prompting">Few-Shot Prompting</h4>
<blockquote>
<p>두개에서 다섯개의 예제를 바탕으로 답변을 생성하게 하는 기법으로, 프롬프트 앞단에 One-Shot Prompting 기법 보다 조금 더 AI에게 직접적으로 원하는 답변에 도달할 수 있도록 유도할 수 있음
<img src="https://velog.velcdn.com/images/w0_0727/post/7d683dbc-3a6f-4c85-9b72-49367788fe60/image.png" alt=""></p>
</blockquote>
<h4 id="cot-chain-of-thought">CoT (Chain-of-Thought)</h4>
<blockquote>
<p>단지 답변을 내놓기 위한 것이 아닌, 답변에 도달하는 과정을 학습시키는 것을 목적으로 본 질문 전에 미리 태스크와 추론 과정을 포함한 답변 예제를 AI에게 제공하는 프레임워크
<img src="https://velog.velcdn.com/images/w0_0727/post/799c0fc0-eb6d-4037-95c6-754b56082ec0/image.png" alt=""></p>
</blockquote>
<h4 id="zero-shot-cot-chain-of-thought">Zero-Shot CoT (Chain of Thought)</h4>
<blockquote>
<p>조금 더 최근에 등장한 트리거 문장 &quot;Let&#39;s think step by step (단계별로 생각해보자)&quot;을 프롬프트에 추가하여 거대 언어 모델이 단계에 따라 결과에 도달하게 하는 프레임워크
<img src="https://velog.velcdn.com/images/w0_0727/post/c08521e2-6dd8-493c-8427-c4ebe5370a1d/image.png" alt=""></p>
</blockquote>
<p>참고
<a href="https://moon-walker.medium.com/the-art-of-prompt-engneering-1-prompt-engineering%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-4a7a88ce67c">The Art of Prompt Engneering</a></p>
<p><a href="https://tech.kakaoenterprise.com/188">프롬프트 엔지니어링, AI라는 도구를 잘 사용하는 방법</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[에러해결 : Fine-tune failed. Fine-tune will exceed billing hard limit]]></title>
            <link>https://velog.io/@w0_0727/%EC%97%90%EB%9F%AC%ED%95%B4%EA%B2%B0-Fine-tune-failed.-Fine-tune-will-exceed-billing-hard-limit</link>
            <guid>https://velog.io/@w0_0727/%EC%97%90%EB%9F%AC%ED%95%B4%EA%B2%B0-Fine-tune-failed.-Fine-tune-will-exceed-billing-hard-limit</guid>
            <pubDate>Mon, 21 Aug 2023 07:51:56 GMT</pubDate>
            <description><![CDATA[<h1 id="1-fine-tune-failed-fine-tune-will-exceed-billing-hard-limit">1. Fine-tune failed. Fine-tune will exceed billing hard limit</h1>
<p>open ai api를 사용할 때 모델을 fine-tuning하는 과정에서 이 에러가 계속 발생했다. 
<img src="https://velog.velcdn.com/images/w0_0727/post/6bb2fd0e-e6ea-48b9-a55c-2021a25b7772/image.png" alt=""></p>
<p><a href="https://community.openai.com/t/cli-fine-tune-error-hard-billing-limit-exceeded/215258">구글링</a>을 해보니, 결제 금액 한도를 낮게 책정해놔서 그럴 수 있다는 말이 대다수였다. 그래서 결제금액을 30$까지 올렸다.</p>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/f052be83-8ebb-429b-a23d-9d2708832ec0/image.png" alt=""></p>
<p>하지만 이것은 문제가 아니었다. (근데 진짜 작게 설정해놓으면 그것이 문제가 될 수도 있습니다.) 긴 삽질 끝에 설마.. 나의 데이터가 문제일까? 생각했다. 
맞다.</p>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/7d72206d-798c-41ee-bce1-f96380c02285/image.png" alt=""></p>
<p>여기서 나는 아래 사항을 위반했다. </p>
<blockquote>
<p>Ensure that the prompt + completion doesn’t exceed 2048 tokens, including the separator (prompt + completion가 구분 기호를 포함하여 2048 토큰을 초과하지 않는지 확인하십시오.)</p>
</blockquote>
<p>나의 데이터의 길이가 너무 길었던 것이다. &#39;수&#39;가 아니라 데이터 하나하나의 길이를 의미</p>
<h2 id="해결방법">해결방법</h2>
<p>*<em>더 짧은 길이의 데이터셋으로 교체한다. (나는 성능을 고려하지 않았기에 이와 같은 방법으로 해결했는데, 긴 길이의 데이터셋 학습은 현재로선 불가능한지 궁금하다.) *</em></p>
<p>&lt; 이전 &gt; 
{&quot;prompt&quot;: &quot;저는 저의 경력에 자부심을 가지고 있습니다. 그러나 제 상사는 항상 저의 일을 둘러싸고 불만을 토로하십니다. 물론 저도 틀린 점이 있었겠지만 그 분의 치밀한 규율에 불편함을 느낍니다. 이런 때 어떻게 대처하면 좋을까요?&quot;, &quot;completion&quot;: &quot;사우님은 자신의 경력에 대해 자부심을 가지고 있으나 상사분께서는 항상 사우님의 일에 대해 불만을 토로하신다고 합니다. 사우님께서는 상사분의 조언과 지적이 자신감을 불러일으키기도 하지만 힘든 감정을 불러일으키기도 한다는 건가요? 그런 상황에서 어떻게 대처할 수 있을까요?\n사우님, 상사분과의 갈등은 정상적인 직장생활에서 생기는 일이라고 생각합니다. 누구나 완벽하지는 않기 때문에 때로는 상사분께서 말씀하신 것처럼 지적이나 조언을 듣고 개선하는 것이 필요합니다.\n하지만 반대로 상사분께서 지나치게 비판적이거나 지적을 하셨을 때는 사우님의 자존감을 흔들 수 있습니다.&quot;}</p>
<p>&lt; 이후 &gt;
{&quot;prompt&quot;: &quot;날 몇시간동안이나 기다리게했어&quot;, &quot;completion&quot;: &quot;기다리는 동안 많은 생각이 들었겠네요.&quot;}</p>
<p>하니까 드디어 파인튜닝이 시작되었다.</p>
<h1 id="2-stream-interrupted-client-disconnected">2. Stream interrupted (client disconnected).</h1>
<p>이건 사용하는 사람이 많으면 이 Queue 안에 대기줄이 엄청 많아서 발생하는 오류라고 한다. <a href="https://domdom.tistory.com/604">참고</a></p>
<h2 id="해결방법-1">해결방법</h2>
<blockquote>
<p>openai --api-key 본인key api fine_tunes.follow -i 작업명</p>
</blockquote>
<p>작업명은 ft 이하입니다.</p>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/1fc26804-7e10-4e96-95ef-175713bbcad2/image.png" alt=""></p>
<p>다들 행복한 파인튜닝 되시길 바랍니다.</p>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/459c9b87-b4c7-4258-bf29-c71e017f5b22/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] lv.1 모의고사]]></title>
            <link>https://velog.io/@w0_0727/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-lv.1-%EB%AA%A8%EC%9D%98%EA%B3%A0%EC%82%AC</link>
            <guid>https://velog.io/@w0_0727/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-lv.1-%EB%AA%A8%EC%9D%98%EA%B3%A0%EC%82%AC</guid>
            <pubDate>Wed, 09 Aug 2023 00:15:56 GMT</pubDate>
            <description><![CDATA[<h2 id="문제">문제</h2>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/42840">https://school.programmers.co.kr/learn/courses/30/lessons/42840</a></p>
<h2 id="정답">정답</h2>
<pre><code class="language-py">def solution(answers):
    answer = []
    supo = [[1,2,3,4,5],[2, 1, 2, 3, 2, 4, 2, 5],[3, 3, 1, 1, 2, 2, 4, 4, 5, 5]]
    right = [0,0,0]

    for i in range(len(supo)):
        for j in range(len(answers)):
            n = len(supo[i])
            # print(i, j, n, j%n)
            if answers[j] == supo[i][j%n]:
                right[i] += 1
    for idx,score in enumerate(right):
        print(idx,score)
        if score == max(right):
            answer.append(idx+1)

    return answer
</code></pre>
<h2 id="풀이">풀이</h2>
<pre><code class="language-py">if answers[j] == supo[i][j%n]: </code></pre>
<p> <a href="https://velog.io/@younge/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%AA%A8%EC%9D%98%EA%B3%A0%EC%82%AC-%EC%99%84%EC%A0%84%ED%83%90%EC%83%89">다른 분의 풀이</a>를 참고해서 해결했다.</p>
<pre><code class="language-py"> print(i, j, n, j%n)</code></pre>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/4a188f1b-16fd-43db-9951-2b97f59e4f1c/image.png" alt="">
supo를 answers 길이에 맞춰 순회할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] lv.2 타겟 넘버]]></title>
            <link>https://velog.io/@w0_0727/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-lv.2-%ED%83%80%EA%B2%9F-%EB%84%98%EB%B2%84</link>
            <guid>https://velog.io/@w0_0727/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-lv.2-%ED%83%80%EA%B2%9F-%EB%84%98%EB%B2%84</guid>
            <pubDate>Thu, 03 Aug 2023 00:44:58 GMT</pubDate>
            <description><![CDATA[<h2 id="문제">문제</h2>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/43165">https://school.programmers.co.kr/learn/courses/30/lessons/43165</a></p>
<h2 id="정답">정답</h2>
<pre><code class="language-py">from collections import deque
def solution(numbers, target):
    answer = 0
    queue = deque()
    n = len(numbers)
    queue.append([numbers[0],0])
    queue.append([-1*numbers[0],0])
    while queue:
        temp, idx = queue.popleft()
        idx += 1
        if idx &lt; n:
            queue.append([temp+numbers[idx], idx])
            queue.append([temp-numbers[idx], idx])
        else:
            if temp == target:
                answer += 1
    return answer</code></pre>
<h2 id="풀이">풀이</h2>
<ol>
<li>큐에 주어진 숫자들의 합과 인덱스를 저장함</li>
<li>큐가 비어 있지 않은 한 반복문 수행
a. 큐에서 가장 앞에 있는 원소(합,인덱스)를 꺼냄
b. 인덱스를 1 증가시킴
c. 인덱스가 숫자 리스트의 길이보다 작다면, 숫자 리스트의 다음 숫자와 그 수의 음수를 더한 값을 큐에 추가함
d. 인덱스가 숫자 리스트의 길이와 같거나 크면(리스트의 모든 숫자를 사용한 경우), 합이 타겟 값과 같은지 확인하고, 같다면 정답의 개수를 증가시키고 큐에는 추가하지 않음</li>
</ol>
<p>numbers = [1, 1, 1, 1, 1] target = 3 일때</p>
<ol>
<li>큐는 [(1, 0), (-1, 0)]로 초기화된다. (첫 번째 숫자와 그 음수를 넣음)</li>
<li>큐에서 (1,0)을 꺼내고, 인덱스를 증가시킨 후 다음 숫자 1과 그 음수를 더한 값을 큐에 넣는다.
큐는 [(-1, 0),(2, 1),(0, 1)]가 된다.</li>
<li>(2,1)을 꺼내고, 인덱스를 증가시킨 후, 다음 숫자 1과 그 음수를 더한 값을 큐에 넣는다. 큐는  [(0, 1), (-1, 0), (3, 2), (1, 2)]가 된다. </li>
<li>모든 경우를 탐색하고, 타겟 값과 같은 합을 찾을 때마다 answer ++</li>
<li>answer 반환</li>
</ol>
<p>index 값을 증가시키는 이유는 numbers 리스트의 다음 숫자로 넘어갈 때마다 가능한 모든 조합을 고려하기 위함임.
numbers = [1, 2, 3]이고 target = 6인 경우</p>
<ol>
<li>idx = 0, number = 1 
 큐 : [1, 0], [-1, 0]</li>
<li>큐에서 [1,0]을 꺼내고 idx =1, number =2 
 큐: [-1,0] [1+2,1] [1,-2,1] </li>
<li>큐에서 [-1,0]을 꺼내고 idx = 1, number = 2
 큐: [3,1] [-1,1] [-1+2,1] [-1-2,1] </li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] lv.1 햄버거 만들기 ]]></title>
            <link>https://velog.io/@w0_0727/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-lv.1-%ED%96%84%EB%B2%84%EA%B1%B0-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@w0_0727/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-lv.1-%ED%96%84%EB%B2%84%EA%B1%B0-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Wed, 02 Aug 2023 11:38:52 GMT</pubDate>
            <description><![CDATA[<h2 id="문제">문제</h2>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/133502">https://school.programmers.co.kr/learn/courses/30/lessons/133502</a></p>
<h2 id="정답">정답</h2>
<pre><code>def solution(ingredient):
    stack = []
    answer = 0
    for i in ingredient:
        stack.append(i)
        if stack[-4:] == [1,2,3,1]:
            answer += 1
            for j in range(4):
                stack.pop()
    return answer</code></pre><h2 id="풀이">풀이</h2>
<p>stack에 ingredient의 원소들을 차례로 넣어주다가
마지막 4개의 원소들이 1,2,3,1이면 
answer +1 해주고, stack에서 4개의 원소들을 pop해준다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[파이썬 슬라이싱 연산자]]></title>
            <link>https://velog.io/@w0_0727/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%8A%AC%EB%9D%BC%EC%9D%B4%EC%8B%B1-%EC%97%B0%EC%82%B0%EC%9E%90</link>
            <guid>https://velog.io/@w0_0727/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%8A%AC%EB%9D%BC%EC%9D%B4%EC%8B%B1-%EC%97%B0%EC%82%B0%EC%9E%90</guid>
            <pubDate>Wed, 02 Aug 2023 11:21:20 GMT</pubDate>
            <description><![CDATA[<p>&quot;:&quot;은 파이썬에서 슬라이싱 연산자입니다.
이 연산자를 사용함으로써 리스트, 문자열, 튜플 등 시퀀스 타입의 객체에서 일부를 추출할 수 있습니다. </p>
<h4 id="seq-추출할-시퀀스-객체">seq: 추출할 시퀀스 객체</h4>
<blockquote>
<h4 id="start-추출을-시작할-인덱스-번호-일반적으로-생략-가능">start: 추출을 시작할 인덱스 번호 (일반적으로 생략 가능)</h4>
</blockquote>
<h4 id="end-추출을-끝낼-인덱스-번호-일반적으로-생략-가능">end: 추출을 끝낼 인덱스 번호 (일반적으로 생략 가능)</h4>
<h4 id="step-추출할-인덱스의-간격-일반적으로-생략-가능">step: 추출할 인덱스의 간격 (일반적으로 생략 가능)</h4>
<p>start, end, step 중 하나 이상을 생략할 수 있습니다. 
<strong>생략된 경우 각각에 대해서는 다음과 같은 기본값이 적용됩니다.</strong></p>
<blockquote>
<p>start: 0
end: 시퀀스 길이
step: 1</p>
</blockquote>
<p>슬라이싱 연산자의 일반적인 사용법은 다음과 같습니다. </p>
<blockquote>
<p>seq[start:end:step]</p>
</blockquote>
<blockquote>
<p>s[start:end]   # start 번호부터 end-1 번호까지의 값 추출</p>
</blockquote>
<blockquote>
<p>s[start:]      # start 번호부터 끝까지 추출</p>
</blockquote>
<blockquote>
<p>s[:end]        # 처음부터 end-1 번호까지 추출</p>
</blockquote>
<blockquote>
<p>s[start:end:step] # start번호부터 end-1 번호까지 step 간격으로 추출 (step 생략 가능)</p>
</blockquote>
<p><strong>예시</strong></p>
<blockquote>
<p>stack = [1, 2, 3, 4, 5, 6] 일 때, *<em>stack[-4:]  *</em></p>
</blockquote>
<p>start가 생략되었습니다. 따라서 기본값인 -len(stack) 즉 -6이 start값으로 지정됩니다. 
: 뒤에 값이 생략되었으므로 end에 대한 값은 따로 지정되지 않았습니다. 
따라서 end는 기본값인 len(stack) 즉 6이 됩니다. 따라서 stack[-4:]는 stack[-4:len(stack)]과 같습니다. 
뒤에서 4번째 원소부터 마지막 원소까지를 슬라이싱해서 stack[-4:]는 [3, 4, 5, 6]이 됩니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] lv.1 명예의 전당(1)]]></title>
            <link>https://velog.io/@w0_0727/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-lv.1-%EB%AA%85%EC%98%88%EC%9D%98-%EC%A0%84%EB%8B%B91</link>
            <guid>https://velog.io/@w0_0727/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-lv.1-%EB%AA%85%EC%98%88%EC%9D%98-%EC%A0%84%EB%8B%B91</guid>
            <pubDate>Wed, 19 Jul 2023 23:55:52 GMT</pubDate>
            <description><![CDATA[<h2 id="문제">문제</h2>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/138477">https://school.programmers.co.kr/learn/courses/30/lessons/138477</a></p>
<h2 id="정답">정답</h2>
<pre><code class="language-py">def solution(k, score):
    answer = []
    prize = []
    for i in range(len(score)):
        prize.append(score[i])
        prize.sort(reverse=True)

        if len(prize) &lt; k:
            answer.append(prize[len(prize)-1])
        else:
            answer.append(prize[k-1])

    return answer</code></pre>
<h2 id="과정">과정</h2>
<p>전날 해결을 못해서 담날 다시 봐서 풀었다.
순회를 하면서 sort를 시켜주는게 중요함 
sorted는 정렬한 걸 새로운 배열로 반환해주고, sort는 원본 배열을 정렬해줌</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] lv.1 카드 뭉치]]></title>
            <link>https://velog.io/@w0_0727/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-lv.1-%EC%B9%B4%EB%93%9C-%EB%AD%89%EC%B9%98</link>
            <guid>https://velog.io/@w0_0727/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-lv.1-%EC%B9%B4%EB%93%9C-%EB%AD%89%EC%B9%98</guid>
            <pubDate>Wed, 19 Jul 2023 13:29:45 GMT</pubDate>
            <description><![CDATA[<h2 id="문제">문제</h2>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/159994">https://school.programmers.co.kr/learn/courses/30/lessons/159994</a></p>
<h2 id="정답">정답</h2>
<pre><code class="language-py">def solution(cards1, cards2, goal):
    answer = &#39;Yes&#39;
    card1_index, card2_index = 0,0

    for word in goal:
        if len(cards1) &gt; card1_index and word == cards1[card1_index]:
            card1_index += 1
        elif len(cards2) &gt; card2_index and word == cards2[card2_index]:
            card2_index +=1
        else:
            answer = &#39;No&#39;
            break
    return answer</code></pre>
<h2 id="풀이">풀이</h2>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/964c86b2-2a7f-48e9-a969-bd931fbed596/image.jpg" alt=""></p>
<p>for문의 break: break문이 실행되면 현재 실행 중인 반복문을 즉시 종료하고, 반복문 다음의 코드로 넘어간다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] lv.1 덧칠하기]]></title>
            <link>https://velog.io/@w0_0727/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-lv.1-%EB%8D%A7%EC%B9%A0%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@w0_0727/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-lv.1-%EB%8D%A7%EC%B9%A0%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 19 Jul 2023 12:26:07 GMT</pubDate>
            <description><![CDATA[<p>어영부영 한 두 달간 문제를 못풀었다. 7월부터 다시 시작했다. 꾸준히 하기 위해서 인증 스터디도 다시 시작했다.
아 그리고 그동안 openAI의 파급력이 굉장했다. 코딩테스트 준비 언어로 꼭 javascript를 가지고 가지 않아도 되겠다고 생각했다. 앞으로 python을 쓸 일에 대비해서 문제 풀 때만이라도 python을 익히기로! 주저리 끝</p>
<h2 id="문제">문제</h2>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/161989">https://school.programmers.co.kr/learn/courses/30/lessons/161989</a></p>
<h2 id="정답">정답</h2>
<pre><code class="language-py">def solution(n, m, section):
    n_paint, answer = 0,0
    for s in section:
        print(s)
        if s &gt; n_paint:
            n_paint = s + m -1
            answer += 1
    return answer</code></pre>
<h2 id="풀이과정">풀이과정</h2>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/d9079f5b-ff28-4758-a7eb-09ac0e1f35d6/image.jpg" alt=""></p>
<p>문제를 풀 때 기준점을 뭘로 잡느냐가 중요한 것 같다.</p>
<p>참고 : <a href="https://ice-greentea.tistory.com/28">https://ice-greentea.tistory.com/28</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Next.js] 페이지 이동하기(useRouter, Link, Cath all)]]></title>
            <link>https://velog.io/@w0_0727/Next.js-%ED%8E%98%EC%9D%B4%EC%A7%80-%EC%9D%B4%EB%8F%99%ED%95%98%EA%B8%B0useRouter-Link-Cath-all</link>
            <guid>https://velog.io/@w0_0727/Next.js-%ED%8E%98%EC%9D%B4%EC%A7%80-%EC%9D%B4%EB%8F%99%ED%95%98%EA%B8%B0useRouter-Link-Cath-all</guid>
            <pubDate>Tue, 04 Jul 2023 09:24:03 GMT</pubDate>
            <description><![CDATA[<h2 id="1userouter">1.useRouter</h2>
<ul>
<li>브라우저를 라우팅 할 수 있는 Hook</li>
</ul>
<pre><code class="language-js">import { useRouter } from &quot;next/router&quot;;

export default function Details({ movie }) {
  const router = useRouter();

  const toAbout = () =&gt; {
    router.push(
      // url
      {
        pathname: &quot;/details/[id]&quot;,
        query: { id: movie.id, name: movie.name },
      },
      // as (두번째 인자 (선택), 브라우저에 표시되는 주소를 따로 설정하고 싶을때 사용) 
      &quot;/details/[id]&quot;
    );
  };
  return (
    &lt;div&gt;
      &lt;button onClick={toAbout}&gt;About&lt;/button&gt;
    &lt;/div&gt;
  );
}</code></pre>
<p>as 이외의 다양한 기능들이 존재한다.
<code>router.replace</code> : 히스토리 스택에 새로운 주소를 추가하지 않고 대체
<code>router.prefetch</code> : 페이지를 미리 불러옴으로써 클라이언트 측에서의 페이지 이동 속도를 향상해줌
<code>router.back</code> : 히스토리 스택 상의 이전 페이지로 돌아감</p>
<h2 id="2-link">2. Link</h2>
<pre><code class="language-js">import Link from &quot;next/link&quot;;

export default function Details({ movie }) {
  const urlObject = {
    pathname: &quot;/about/[id]&quot;,
    query: { id: movie.id, name: movie.name },
  };

  return (
    &lt;div&gt;
      &lt;Link href={urlObject}&gt;
        &lt;a&gt;About&lt;/a&gt;
      &lt;/Link&gt;
    &lt;/div&gt;
  );
}</code></pre>
<h2 id="3-cath-all-routes">3. Cath All Routes</h2>
<blockquote>
<p>페이지에서 모든 Path를 가져와 쿼리 파라미터 하는 방법, URL에 원하는 데이터를 출력하고 그 데이터를 활용할 수 있어 유용하다.</p>
</blockquote>
<h4 id="예시">예시</h4>
<p> /movies/movies/Spider-Man:%20No%20Way%20Home/634649 라는 경로가 있을 때, 
 useRouter의 query에 담기는 정보:</p>
<pre><code class="language-js">params: [&quot;Spider-Man: No Way Home&quot;, &quot;634649&quot;];</code></pre>
<p>이를 활용해서 데이터 출력해보자.</p>
<pre><code class="language-js">export default function MovieDetail() {
  const router = useRouter();
  const [title, id] = router.query.params || [];
  // router.query.params가 정의되지 않은 경우 빈 배열 []로 대체
  return (
    &lt;div&gt;
      &lt;h4&gt;ID: {id}&lt;/h4&gt;
      &lt;h4&gt;Movie Name:{title}&lt;/h4&gt;
    &lt;/div&gt;
  );
}</code></pre>
<p><a href="https://velog.io/write?id=9c46109a-03c3-4d93-9f76-7276e3ed6e3c">참고</a>
<a href="https://nextjs.org/docs">https://nextjs.org/docs</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] 자식 컴포넌트에서 부모 컴포넌트로 데이터 전달하기]]></title>
            <link>https://velog.io/@w0_0727/React-%EC%9E%90%EC%8B%9D-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EC%97%90%EC%84%9C-%EB%B6%80%EB%AA%A8-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EB%A1%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EB%8B%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@w0_0727/React-%EC%9E%90%EC%8B%9D-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EC%97%90%EC%84%9C-%EB%B6%80%EB%AA%A8-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EB%A1%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EB%8B%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 04 Jul 2023 08:41:51 GMT</pubDate>
            <description><![CDATA[<h2 id="1부모-컴포넌트-👉-자식-컴포넌트">1.부모 컴포넌트 👉 자식 컴포넌트</h2>
<ul>
<li>일반적인 props 사용 방법이다.</li>
</ul>
<h4 id="parentjs">Parent.js</h4>
<pre><code class="language-js">function Parent() {
    const [data,setData] = useState(1);
  return &lt;Child data = {data}&gt;&lt;/Child&gt;;
}</code></pre>
<h4 id="childjs">Child.js</h4>
<pre><code class="language-js">function Child({data}) {
    console.log(data);
      return &lt;div&gt;Child&lt;/div&gt;;
}</code></pre>
<h2 id="2자식-컴포넌트-👉-부모-컴포넌트">2.자식 컴포넌트 👉 부모 컴포넌트</h2>
<p>1) 부모 컴포넌트에서 함수를 정의한다.
2) 함수를 자식 컴포넌트에 props로 내려준다. 
3) 자식 컴포넌트의 data를 부모 컴포넌트에게 전달받은 함수의 인자로 전달한다.</p>
<h4 id="parentjs-1">Parent.js</h4>
<pre><code class="language-js">
function Parent() {
  const parentFunction = (x) =&gt; {
    console.log(x);
  };

  return &lt;Child parentFunction={parentFunction}&gt;&lt;/Child&gt;;
}</code></pre>
<h4 id="childjs-1">Child.js</h4>
<pre><code class="language-js">function Child({ parentFunction }) {
  const [data, setData] = useState(2);
  parentFunction(data);
  return &lt;div&gt;Child&lt;/div&gt;;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Next.js] 동적 라우팅]]></title>
            <link>https://velog.io/@w0_0727/Next.js-%EB%8F%99%EC%A0%81-%EB%9D%BC%EC%9A%B0%ED%8C%85</link>
            <guid>https://velog.io/@w0_0727/Next.js-%EB%8F%99%EC%A0%81-%EB%9D%BC%EC%9A%B0%ED%8C%85</guid>
            <pubDate>Sun, 25 Jun 2023 11:26:08 GMT</pubDate>
            <description><![CDATA[<p>본 글은 Udemy의 &#39;Next.js &amp; React - 완벽 정복 가이드&#39; 강의와 공식문서를 참고하여 작성된 글입니다.</p>
<p>개인적으로 Next.js의 동적라우팅 기능이 참 편리하게 쓰일 것 같다.</p>
<h2 id="catch-all-segments">Catch-all Segments</h2>
<p><code>[...pages/shop/[...slug].js</code> or <code>/shop/clothes</code> or<code>/shop/clothes/tops</code> or <code>/shop/clothes/tops/t-shirts</code> ... 등으로 라우팅될 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/3cee535b-2b7c-4539-9c81-51647f45c747/image.png" alt=""></p>
<h2 id="optional-catch-all-segments">Optional Catch-all Segments</h2>
<p><code>pages/shop/[[...slug]].js</code> 는 <code>/shop</code>, or <code>/shop/clothes</code>, <code>/shop/clothes/tops</code> or <code>shop/clothes/tops/t-shirts</code> ... 등으로 라우팅될 수 있다.
<img src="https://velog.velcdn.com/images/w0_0727/post/83dbdb38-0bea-4054-bcfb-5ba64542494d/image.png" alt=""></p>
<h2 id="둘의-차이점🧐">둘의 차이점?🧐</h2>
<blockquote>
<p><strong>Catch-all Segments</strong>와 <strong>Optional Catch-all Segments</strong>의 차이점은 params 의 <strong>optional 유무</strong>이다. <strong>Optional Catch-all Segments</strong>은 파라미터가 없는 경우에도 /shop과 매칭될 수 있다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Next.js] Next.js는 왜 사용할까?]]></title>
            <link>https://velog.io/@w0_0727/Next.js-Next.js%EB%8A%94-%EC%99%9C-%EC%82%AC%EC%9A%A9%ED%95%A0%EA%B9%8C</link>
            <guid>https://velog.io/@w0_0727/Next.js-Next.js%EB%8A%94-%EC%99%9C-%EC%82%AC%EC%9A%A9%ED%95%A0%EA%B9%8C</guid>
            <pubDate>Sun, 25 Jun 2023 11:03:54 GMT</pubDate>
            <description><![CDATA[<p>본 글은 Udemy의 &#39;Next.js &amp; React - 완벽 정복 가이드&#39; 강의를 듣고 작성된 글입니다.</p>
<h1 id="1-nextjs">1. Next.js</h1>
<blockquote>
<p>React 라이브러리의 프레임워크</p>
</blockquote>
<h1 id="2-사용하는-이유">2. 사용하는 이유</h1>
<blockquote>
<p>SEO를 위한 Server-Side-Rendering(SSR)을 지원함</p>
</blockquote>
<p>SSR의 자세한 개념은 이곳에..
<a href="https://velog.io/@w0_0727/CSR-SSR">https://velog.io/@w0_0727/CSR-SSR</a></p>
<h1 id="3-장점-제공-기능">3. 장점, 제공 기능</h1>
<h2 id="1-페이지-기반-라우팅-시스템">1) 페이지 기반 라우팅 시스템</h2>
<blockquote>
<p>사진처럼 /pages 폴더에서 컴포넌트를 export하면 <strong>폴더명이 페이지 route</strong>가 된다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/dc376d37-8837-4902-80b8-a43a52a69cbe/image.png" alt=""></p>
<h2 id="2-dynamic-routes">2) Dynamic routes</h2>
<blockquote>
<p>정확한 라우트 이름을 미리 알지 못하고 동적으로 경로를 작성하려는 경우 사용한다. (nextjs.org)</p>
</blockquote>
<h4 id="사용예시">사용예시</h4>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/71744b65-6711-483c-8035-b2d137339045/image.png" alt=""></p>
<blockquote>
<p>폴더 이름을 대괄호로 묶어서 만듦</p>
</blockquote>
<p>Optional Catch-all Segments, Catch-all Segments등 다양하게 활용해볼 수 있다.
▶️ 공식문서 : <a href="https://nextjs.org/docs/pages/building-your-application/routing/dynamic-routes">https://nextjs.org/docs/pages/building-your-application/routing/dynamic-routes</a></p>
<h2 id="3-client-side-navigation-aka--link-">3) Client side navigation (aka &lt; Link /&gt;)</h2>
<blockquote>
<p><code>&lt; Link /&gt;</code> : a태그와 달리 페이지를 리로딩하지 않고도 페이지간 이동이 가능하다.</p>
</blockquote>
<h4 id="예시1">예시1)</h4>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/0f6dce2f-86f6-46b1-a7c1-e344342cd3c2/image.png" alt=""></p>
<h4 id="예시2">예시2)</h4>
<pre><code class="language-js">import Link from &quot;next/link&quot;;

function ClientsPage() {
  const clients = [
    { id: &quot;max&quot;, name: &quot;Maximilian&quot; },
    { id: &quot;manu&quot;, name: &quot;Manuel&quot; },
  ];

  return (
    &lt;div&gt;
      &lt;h1&gt;The Client Page&lt;/h1&gt;
      &lt;ul&gt;
        {clients.map(client =&gt; &lt;li key={id}&gt;
            &lt;Link href={{
                pathname:&#39;/clients/[id]&#39;,
                query: {id: client.id}
            }}&gt;{client.name}&lt;/Link&gt;
        &lt;/li&gt;)}
      &lt;/ul&gt;
    &lt;/div&gt;
  );
}

export default ClientsPage;
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[📑 면접 CS 질문 모음]]></title>
            <link>https://velog.io/@w0_0727/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90-%EB%A9%B4%EC%A0%91-CS-%EC%A7%88%EB%AC%B8-%EB%AA%A8%EC%9D%8C</link>
            <guid>https://velog.io/@w0_0727/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90-%EB%A9%B4%EC%A0%91-CS-%EC%A7%88%EB%AC%B8-%EB%AA%A8%EC%9D%8C</guid>
            <pubDate>Fri, 23 Jun 2023 17:23:19 GMT</pubDate>
            <description><![CDATA[<pre><code>업데이트 로그
2023.06.24
2023.07.01
2023.08.21</code></pre><h2 id="os">OS</h2>
<h4 id="운영체제의-정의에-대해-설명해주세요">운영체제의 정의에 대해 설명해주세요.</h4>
<blockquote>
<p>컴퓨터 시스템의 자원들을 효율적으로 관리하고  사용자가 컴퓨터를 편리하게 사용할 수 있도록 환경을 제공하는 여러 프로그램의 모임</p>
</blockquote>
<h4 id="운영체제의-메모리-영역에-대해-설명해주세요">운영체제의 메모리 영역에 대해 설명해주세요.</h4>
<blockquote>
<p>유저영역, 커널영역 2가지로 분리된다.
<strong>유저영역</strong>: 스택, 힙, 데이터, 코드로 나뉨
<strong>커널영역</strong>: 하나의 프로세스에 할당되는 총 메모리 공간 중에서 유저 영역을 제외한 나머지 영역, 커널이 위치하고 있음 (커널: 운영체제라는 하나의 소프트웨어를 실행시키기 위해 필요한 메모리 공간)</p>
</blockquote>
<h4 id="⭐-프로세스와-스레드를-비교-설명해주세요">⭐ 프로세스와 스레드를 비교 설명해주세요.</h4>
<blockquote>
<p><strong>프로세스</strong>: 운영체제로부터 자원을 할당받은 <strong>작업</strong>의 단위
<strong>스레드</strong>: 프로세스의 실행 단위, 각 스레드는 독립적인 실행 흐름을 가지고 있음
프로세스는 완벽히 독립적이기 때문에 메모리 영역(Code, Data, Heap, Stack)을 다른 프로세스와 공유를 하지 않지만, 쓰레드는 해당 쓰레드를 위한 스택을 생성할 뿐 그 이외의 Code, Data, Heap영역을 공유한다.</p>
</blockquote>
<p>프로그램 &gt; 프로세스 &gt; 스레드</p>
<ul>
<li><strong>프로그램</strong>: 파일이 저장 장치에 저장되어 있지만 메모리는 올라가 있지 않은(운영체제가 프로그램에게 메모리 공간을 할당해주지 않았음을 의미) 정적인 상태(실행되지 않고 가만히 있다는 뜻) 즉 <strong>실행되지 않은 파일 그 자체를 가리키는 말</strong></li>
</ul>
<p><a href="https://velog.io/@raejoonee/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%EC%8A%A4%EB%A0%88%EB%93%9C%EC%9D%98-%EC%B0%A8%EC%9D%B4">참고</a></p>
<h4 id="스레드에서-독립적인-stack-메모리-영역이-필요한-이유에-대해-설명해주세요">스레드에서 독립적인 Stack 메모리 영역이 필요한 이유에 대해 설명해주세요.</h4>
<blockquote>
<p>스택은 함수 호출 시 전달되는 인자, 반환 주소값, 함수 내 변수 등을 저장하기 위해 사용되는 메모리 공간
스택 메모리 공간이 독립적이라는 것은 독립적인 함수 호출이 가능하다는 것이고 이는 독립적인 실행 흐름이 추가되는 것이다.</p>
</blockquote>
<h4 id="멀티-프로세스와-멀티-스레드를-비교-설명해주세요">멀티 프로세스와 멀티 스레드를 비교 설명해주세요.</h4>
<blockquote>
<p><strong>멀티 프로세스</strong>: 여러 개의 프로세스가 서로 협력적으로 일을 처리하는 것
<strong>멀티 스레드</strong> : 하나의 프로세스에 여러 스레드로 자원을 공유하며 작업을 나눠 수행하는 것
멀티 스레드는 멀티 프로세스보다 작은 메모리 공간을 차지하고 Context Switching이 빠르나, 하나의 스레드 장애로 전체 스레드가 종료될 위험을 갖고 있음
멀티 프로세스는 하나의 프로세스가 죽더라도 다른 프로세스에 영향을 주지 않아 안정성이 높지만, 멀티 스레드보다 많은 메모리 공간과 cpu시간을 차지하는 단점이 있음</p>
</blockquote>
<p><a href="https://velog.io/@xxhaileypark/%EB%A9%80%ED%8B%B0-%EC%8A%A4%EB%A0%88%EB%93%9CMulti-Thread-%EB%A9%80%ED%8B%B0-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4Multi-process">참고</a></p>
<h4 id="문맥-전환-context-switching에-대해-설명해주세요">문맥 전환 (Context Switching)에 대해 설명해주세요</h4>
<blockquote>
<p><strong>현재 진행하고 있는 Task(Process,Thread)의 상태를 저장</strong>하고 다음 진행할 Task의 상태 값을 읽어 복원(restore)하는 과정을 의미한다. </p>
</blockquote>
<ul>
<li>Context</li>
<li><em>CPU가 해당 Process(or Thread)를 실행하기 위해 필요한 프로세스의 정보*</em>로서, PCB(Process Contol Block)에 저장된다.</li>
</ul>
<h4 id="교착상태-deadlock에-대해-설명해주세요">교착상태 (Deadlock)에 대해 설명해주세요.</h4>
<blockquote>
<p>둘 이상의 프로세스가 다른 프로세스가 점유하고 있는 자원을 서로 기다릴 때 무한 대기에 빠지는 상황</p>
</blockquote>
<h4 id="교착상태의-발생-조건에-대해-설명해주세요">교착상태의 발생 조건에 대해 설명해주세요.</h4>
<blockquote>
<p>크게 4가지
<strong>상호 배제</strong>: 한 번에 프로세스 하나만 해당 자원을 사용할 수 있음. 사용 중인 자원을 다른 프로세스가 사용하려면 요청한 자원이 해제될 때까지 기다려야 함
<strong>점유 대기</strong>: 자원을 최소한 하나 보유하고, 다른 프로세스에 할당된 자원을 점유하기 위해 대기하는 프로세스가 존재해야 함
<strong>비선점</strong>: 이미 할당된 자원을 강제로 빼앗을 수 없음(비선점)
<strong>순환 대기</strong>: 대기 프로세스의 집합이 순환 형태로 자원을 대기하고 있어야 함</p>
</blockquote>
<p><a href="https://chanhuiseok.github.io/posts/cs-2/">참고</a></p>
<h4 id="페이징과-세그멘테이션에-대해-설명해주세요">페이징과 세그멘테이션에 대해 설명해주세요.</h4>
<blockquote>
<p><strong>페이징</strong>: 프로세스의 주소 공간을 <strong>고정된 사이즈</strong>의 페이지 단위로 나누어 물리적 메모리에 <strong>불연속적으로</strong> 할당하는 방식
<strong>세그멘테이션</strong>: 프로세스를 <strong>각각 크기가 다른 논리적인 블록 단위 세그먼트(Segment)</strong>로 분할하여 메모리에 할당</p>
</blockquote>
<h4 id="메모리-단편화에-대해-설명해주세요">메모리 단편화에 대해 설명해주세요.</h4>
<blockquote>
<p>RAM에서 메모리의 공간이 작은 조각으로 나뉘어져 사용 가능한 메모리가 충분히 존재하지만 할당(사용)이 불가능한 상태, 실제 사용 가능한 공간이 줄어들어 swapping, 잦은 페이지 교체 등으로 시스템 성능 저하를 일으킬 수 있음</p>
</blockquote>
<ul>
<li>RAM(Random Access Memory)
데이터를 저장하거나 저장된 데이터를 읽어내는 기억 장치, 디스크와 달리 전원이 꺼지면 데이터는 지워짐</li>
</ul>
<h4 id="기아-상태에-대해-설명해주세요">기아 상태에 대해 설명해주세요.</h4>
<h4 id="경쟁-상태에-대해-설명해주세요">경쟁 상태에 대해 설명해주세요.</h4>
<h4 id="뮤텍스와-세마포어에-대해-설명해주세요">뮤텍스와 세마포어에 대해 설명해주세요.</h4>
<h4 id="가상-메모리에-대해-설명해주세요">가상 메모리에 대해 설명해주세요.</h4>
<blockquote>
<p>물리 메모리 크기의 한계를 극복하기 위해 나온 기술, 물리 메모리보다 큰 프로세스를 수행하기 위해 사용한다.</p>
</blockquote>
<h4 id="페이지-교체-알고리즘을-아는대로-설명해주세요">페이지 교체 알고리즘을 아는대로 설명해주세요.</h4>
<h4 id="요구-페이징에-대해-설명해주세요">요구 페이징에 대해 설명해주세요.</h4>
<blockquote>
<p>운영체제에서 사용되는 가상 메모리 관리 기법중 하나, 프로세스가 실행되는 동안 필요한 페이지만 메모리에 올리고, 필요하지 않은 페이지는 디스크에 저장하여 메모리를 절약하는 방법. 이를 위해 페이지 테이블에 페이지의 위치 정보와 함께 각 페이지의 접근 여부를 표시하여 필요한 페이지만 메모리에 올리게 된다. </p>
</blockquote>
<p><a href="https://superohinsung.tistory.com/127">참고</a></p>
<h2 id="network">Network</h2>
<h4 id="웹-프로토콜에-대해-설명해주세요">웹 프로토콜에 대해 설명해주세요.</h4>
<blockquote>
<p>웹에서 브라우저(클라이언트)와 서버가 통신할 때 사용하는 통신 규약</p>
</blockquote>
<ul>
<li><p><strong>프로토콜 기본 요소</strong>
1) 구문: 전송하고자 하는 데이터 형식, 부호화, 신호 레벨 등을 규정
2) 의미: 두 기기 간의 효율적이고 정확한 정보 전송을 위한 협조 사항과 오류 관리를 위한 제어 정보를 규정
3) 시간: 두 기기 간의 통신 속도, 메시지의 순서 제어 등을 규정</p>
</li>
<li><p><strong>프로토콜의 기능 종류</strong>
1) 캡슐화
2) 흐름제어
3) 연결제어
4) 오류제어
5) 주소설정
6) 순서설정
7) 동기화
8) 세분화와 재합성
9) 다중화</p>
</li>
</ul>
<h4 id="http에-대해-설명해주세요">HTTP에 대해 설명해주세요.</h4>
<blockquote>
<p>Hyper Text Transfer Protocol의 약자, <strong>웹 상에서 주고받는 데이터 전송</strong>에 대한 여러 규칙이며, 서버-클라이언트 구조에서 사용되는 프로토콜이다. 요청과 응답을 주고 받는 메커니즘을 기본으로 하며, &#39;비연결성&#39;과 &#39;무상태&#39; 라는 특징을 가지고 있다. </p>
</blockquote>
<ul>
<li><p><strong>무상태 프로토콜 (Stateless)</strong>
웹 서버가 웹 클라이언트의 <strong>상태 정보를 유지하지 않는 것</strong>을 의미함. HTTP는 기본적으로 상태정보를 유지하지 않으므로 상태 정보 유지가 필요한 작업은 쿠키나 세션을 이용한다.
상태정보: 브라우저가 서버에게 요청을 전달하면서 함께 전달한 데이터</p>
</li>
<li><p><strong>비연결성(Connectionless)</strong>
브라우저가 서버에 요청하는 순간 잠깐 서버와 연결됐다가 서버로부터 응답이 전송된 후 곧바로 연결이 끊기는 것을 의미</p>
</li>
</ul>
<h4 id="http의-get-post를-비교-설명해주세요">HTTP의 GET, POST를 비교 설명해주세요.</h4>
<blockquote>
<p>Get method는 클라이언트에서 정보를 요청하기 위해 사용되는 메서드, POST는 클라이언트의 리소스를 생성 또는 업데이트 하기 위해 서버에 데이터를 보내는데 사용됨, GET과 달리 전송할 데이터를 HTTP 메시지의 Body에 담아서 전송함</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/be794b92-0b09-487b-90d0-d5942e9e1075/image.png" alt=""></p>
<p><a href="https://velog.io/write?id=6561ff49-941d-4483-ab5c-58cda09afb85">참고</a></p>
<h4 id="http의-put-patch를-비교-설명해주세요">HTTP의 PUT, PATCH를 비교 설명해주세요.</h4>
<blockquote>
<p><code>PUT</code>은 리소스의 모든 것을 업데이트 한다. <code>PATCH</code>는 리소스의 일부를 업데이트 한다. </p>
</blockquote>
<h4 id="http의-status-code에-대해-설명해주세요">HTTP의 Status Code에 대해 설명해주세요.</h4>
<p>정리해놓은 글</p>
<blockquote>
<p><a href="https://velog.io/@w0_0727/HTTP-status-code">https://velog.io/@w0_0727/HTTP-status-code</a></p>
</blockquote>
<h4 id="http와-https의-차이점에-대해-설명해주세요">HTTP와 HTTPS의 차이점에 대해 설명해주세요.</h4>
<blockquote>
<p>이 HTTPS(Hypertext Transfer Protocol Secure)는 HTTP의 확장 버전 또는 더 안전한 버전입니다. HTTPS에서는 브라우저와 서버가 데이터를 전송하기 전에 안전하고 암호화된 연결을 설정합니다. HTTP는 암호화되지 않은 데이터를 전송합니다. 즉, 브라우저에서 전송된 정보를 제3자가 가로채고 읽을 수 있습니다. 이는 이상적인 프로세스가 아니었기 때문에, 통신에 또 다른 보안 계층을 추가하기 위해 HTTPS로 확장되었습니다. HTTPS는 HTTP 요청 및 응답을 SSL 및 TLS 기술에 결합합니다. - aws</p>
</blockquote>
<h4 id="https의-동작-방식에-대해-설명해주세요">HTTPS의 동작 방식에 대해 설명해주세요.</h4>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/652fb306-2c63-41c5-a7c0-825113c26044/image.png" alt=""></p>
<blockquote>
</blockquote>
<p><strong>1) 🙋‍♀️server &quot;hello&quot;</strong>: 클라이언트 hello 메시지에 대한 응답으로 서버가 <strong>서버의 SSL 인증서, 서버에서 선택한 암호 제품군, 그리고 서버에서 생성한 또 다른 무작위 바이트 문자열인 &quot;server random&quot;를 포함하는 메시지를 전송</strong>합니다.</p>
<blockquote>
</blockquote>
<p><strong>2) ✅Verify server certificate</strong> : 클라이언트가 서버의 SSL 인증서를 인증서 발행 기관(CA)을 통해 검증합니다. 이를 통해 서버가 인증서에 명시된 서버인지, 클라이언트가 상호작용 중인 서버가 실제 해당 도메인의 소유자인지를 확인합니다.</p>
<blockquote>
</blockquote>
<p><strong>3) 🔁 Client key exchange</strong> : 확인이 완료되면 클라이언트는 &quot;The premaster secret&quot;라고 하는 무작위 바이트 문자열을 공개 키로 암호화하여 전송합니다. (클라이언트는 서버의 SSL 인증서에서 공개 키를 받습니다.)</p>
<blockquote>
</blockquote>
<p>** 4) 💳 Send client certificate** : 만약 서버가 클라이언트의 인증서를 요구한다면 서버의 인증서와 같은 방식으로 암호화를 진행하여 함께 전송합니다.</p>
<blockquote>
</blockquote>
<p><strong>5) 🧐 Verify client certificate</strong> : 서버가 클라이언트로부터 받은 The premaster secret을 개인키를 통해 해독합니다.</p>
<blockquote>
</blockquote>
<p><strong>6) 🏁 Client &quot;finished&quot;</strong> : 클라이언트가 &quot;client random&quot;, &quot;server random&quot;, &quot;The premaster secret&quot;를 이용해 대칭키로 활용할 &quot;세션 키&quot;를 생성합니다. 클라이언트가 세션 키로 암호화된 &quot;finished&quot; 메시지를 전송합니다.</p>
<blockquote>
</blockquote>
<p><strong>7) 🏁 Server &quot;finished&quot;</strong> : 서버가 &quot;client random&quot;, &quot;server random&quot;, &quot;The premaster secret&quot;를 이용해 대칭키로 활용할 <strong>세션키를 생성</strong>합니다. 서버가 세션 키로 암호화된 &quot;finished&quot; 메시지를 전송합니다.</p>
<blockquote>
</blockquote>
<p><strong>8) 🤝 Exchange messages</strong> : 핸드셰이크가 완료되고, 세션 키를 이용해 메세지를 주고 받습니다.</p>
<p><a href="https://inuplace.tistory.com/1086">참고</a></p>
<h4 id="tcp와-udp를-비교-설명해주세요">TCP와 UDP를 비교 설명해주세요.</h4>
<blockquote>
<p>TCP는 연속성보다 신뢰성 있는 전송이 중요할 때 사용되는 프로토콜이며,UDP는 TCP보다 빠르고 네트워크 부하가 적다는 장점이 있지만, 신뢰성 있는 데이터 전송을 보장하지는 않는다. 그렇기 때문에 신뢰성보다는 연속성이 중요한 실시간 스트리밍과 같은 서비스에 자주 사용된다.</p>
</blockquote>
<p><a href="https://velog.io/write?id=6561ff49-941d-4483-ab5c-58cda09afb85">참고</a></p>
<h4 id="tcp가-신뢰성을-보장하는-방법에-대해-설명해주세요">TCP가 신뢰성을 보장하는 방법에 대해 설명해주세요.</h4>
<blockquote>
<p>연결형 서비스로 가상 회선 방식을 제공한다. 3-way handshaking 과정을 통해 연결을 설정하고, 4-way handshaking 과정을 통해 연결을 해제한다. 그러므로 높은 신뢰성을 보장할 수 있다.</p>
</blockquote>
<h4 id="tcp의-3-way-handshake와-4-way-handshake에-대해-설명해주세요">TCP의 3-Way-Handshake와 4-Way-Handshake에 대해 설명해주세요.</h4>
<blockquote>
<p><strong>3-Way-Handshake</strong>
<img src="https://velog.velcdn.com/images/w0_0727/post/da3dd39a-182d-4ab8-9316-bef50ab8f9d6/image.png" alt=""></p>
</blockquote>
<ol>
<li>먼저 Open 한** 클라이언트<strong>가 _</strong>SYN<strong>_(내 말 들려?)를 보내고 _</strong>SYN_SENT**_ 상태로 대기한다.</li>
<li><strong>서버</strong>는 _<strong>SYN-RECEIVED *<em>_상태로 바꾸고 *</em>SYN</strong>과 응답 <strong>ACK</strong>(어 잘 들려! 내 말은 들려?)를 보낸다.</li>
<li>SYN과 응답 ACK를 받은 <strong>클라이언트</strong>는 <strong>ESTABLISHED</strong> 상태로 변경하고 서버에게 응답 <strong>ACK</strong>(잘 들려!)를 보낸다.</li>
<li>응답 ACK를 받은 <strong>서버</strong>는 *<em>ESTABLISHED *</em> 상태로 변경한다.</li>
</ol>
<blockquote>
<p><strong>4-Way-Handshake</strong>
<img src="https://velog.velcdn.com/images/w0_0727/post/1dc36a6e-e345-4427-99f5-8061c36b4186/image.png" alt=""></p>
</blockquote>
<ol>
<li>먼저 close를 실행한 클라이언트가 <strong>FIN</strong>(연결 끊자!)을 보내고 FIN-WAIT-1 상태로 대기한다.</li>
<li>서버는 <strong>CLOSE-WAIT</strong>으로 바꾸고 응답 <strong>ACK</strong>(알겠어! 잠시만~)를 전달한다. 동시에 해당 포트에 연결되어 있는 애플리케이션에게 close를 요청한다.</li>
<li>ACK를 받은 클라이언트는 상태를 <strong>FIN-WAIT-2</strong>로 변경한다.</li>
<li>close 요청을 받은 서버 애플리케이션은 종료 프로세스를 진행하고 <strong>FIN</strong>(나도 끊을게!)을 클라이언트로 보내 LAST_ACK 상태로 바꾼다.</li>
<li>FIN을 받은 클라이언트는 ACK(알겠어!)를 서버에 다시 전송하고 <strong>TIME-WAIT</strong>으로 상태를 바꾼다. TIME-WAIT에서 일정 시간이 지나면 CLOSE 된다. <strong>ACK</strong>를 받은 서버도 포트를 CLOSED로 닫는다.</li>
</ol>
<p><code>TIME-WAIT</code> : 먼저 연결을 끊는 쪽에서 생성되는 소켓으로, 혹시 모를 전송 실패에 대비하기 위해 존재하는 소켓이며, TIME-WAIT이 없다면, 패킷의 손실이 발생하거나 통신자 간 연결 해제가 제대로 되지 않을 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[web] 웹프로토콜 ]]></title>
            <link>https://velog.io/@w0_0727/%EC%9B%B9-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C</link>
            <guid>https://velog.io/@w0_0727/%EC%9B%B9-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C</guid>
            <pubDate>Thu, 15 Jun 2023 09:59:18 GMT</pubDate>
            <description><![CDATA[<h1 id="웹-프로토콜">웹 프로토콜</h1>
<blockquote>
<p>웹에서 쓰이는 통신규약 (통신할 때 내가 이렇게 할게, 너는 이렇게 해줘라고 약속하는 것)</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/e6790a93-7ef9-494f-a025-da2e02c04fdb/image.png" alt=""></p>
<p>예시를 통해 단위의 역할을 알아보자. 
<img src="https://velog.velcdn.com/images/w0_0727/post/ae71ddb5-0fc6-4def-b3ec-0e9aa6de320e/image.png" alt=""></p>
<h3 id="protocol">protocol</h3>
<blockquote>
<p>문서에 접근하기 위해 사용되는 프로토콜의 이름</p>
</blockquote>
<h3 id="computer_name">computer_name</h3>
<blockquote>
<p>문서가 있는 컴퓨터(서버)의 도메인 이름</p>
</blockquote>
<h3 id="port">port</h3>
<blockquote>
<p>서버가 어떤 포트 숫자를 바라보고 있는가 (선택)</p>
</blockquote>
<h3 id="document_name">document_name</h3>
<blockquote>
<p>서버 컴퓨터에 있는 특정 문서의 이름</p>
</blockquote>
<h3 id="parameters">parameters</h3>
<blockquote>
<p>페이지에 넘기는 변수(선택)</p>
</blockquote>
<hr>
<blockquote>
<p><a href="https://velog.io/@w0_0727/CSR-SSR">https://velog.io/@w0_0727/CSR-SSR</a></p>
</blockquote>
<ul>
<li>url은 http 프로토콜을 사용한다</li>
<li>velog.io의 이름을 갖는서버에서</li>
<li>@w0_0727/CSR-SSR에 파일에 접근한다.</li>
</ul>
<h1 id="http-hyper-text-transfer-protocol">HTTP (Hyper Text Transfer Protocol)</h1>
<p>HTTP는 브라우저가 웹 서버와 통신하기 위해 사용하는 주요 프로토콜</p>
<ul>
<li>HTTP의 요청 형식 : get, head, post, put</li>
<li>HTTP의 통신 방식 : 요청, 응답으로 이루어짐. 어떤 데이터를 요청하면 요청받은 데이터를 받아 응답함.</li>
<li>HTTP 1.1과 2.0의 차이
1) 처리방식
http1은 요청을 받아야만 다음 요청이 처리될 수 있음 (1요청 1리소스)
http2는 여러 리소스를 한번에 받아올 수 있음</li>
</ul>
<p>2) 데이터
http1은 문자열로 전송
http2는 바이너리(이진법)으로 인코딩하여 압축해서 전송, 헤더도 압축 가능</p>
<h1 id="ip--mac--arp">IP / MAC / ARP</h1>
<p>우리가 많이 알고있는 IP (Internet Protocol)는 각각의 패킷을 IP주소와 MAC 주소를 통해 상대방에게 전달하는 역할을 함</p>
<h2 id="ip-주소">IP 주소</h2>
<p>각 노드에 부여된 주소를 가르킨다.</p>
<h2 id="mac-주소">MAC 주소</h2>
<p>각 네트워크 카드에 할당된 &#39;고유의 주소&#39;를 의미</p>
<h2 id="arp">ARP</h2>
<p>유동적인 IP주소를 고유주소인 MAC 주소로 변환하여 목적지를 찾아감</p>
<h1 id="tcp--udp">TCP / UDP</h1>
<h2 id="tcp">TCP</h2>
<blockquote>
<p>(Transmission Control Protocol) 전송 제어 프로토콜(전달)</p>
</blockquote>
<h2 id="tcp의-역할">TCP의 역할</h2>
<p>데이터를 안정적으로 전달
데이터를 순서대로 전달
데이터를 에러없이 교활할 수 있도록 전달.</p>
<h2 id="udp">UDP</h2>
<p>(User Datagram Protocol)은 TCP와 대조되는 전송 프로토콜로 , 데이터 전달에 대한 안정성을 보장하진 않지만 , 속도는 TCP에 비해 빠름</p>
<p>예 ) 유튜브 (스트리밍) 서비스
스트리밍 같은 경우 바로바로 화면에 나타내 줘야하기 때문에 데이터의 안정성 보다는 &#39;속도&#39;가 더 중요.
즉 , 서비스에 따라 사용하는 프로토콜이 다름</p>
<h1 id="dns-domain-name-server">DNS (Domain Name Server)</h1>
<blockquote>
<p>숫자로 되어있는 IP주소를 우리가 기억하기 쉽게 &#39;문자&#39;로 매핑해주는 시스템</p>
</blockquote>
<p>DNS는 도메인 주소를 IP 주소로 변환해주는 역할을 하기 때문에 , 유저들은 naver.com / google.com 과 같이 입력만해도 해당 사이트에 접근할 수 있게 됨</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[web] 렌더링에 관하여...]]></title>
            <link>https://velog.io/@w0_0727/%EB%A0%8C%EB%8D%94%EB%A7%81%EC%9D%B4%EB%9E%80-614-%EC%A0%95%EB%A6%AC-%EC%98%88%EC%A0%95</link>
            <guid>https://velog.io/@w0_0727/%EB%A0%8C%EB%8D%94%EB%A7%81%EC%9D%B4%EB%9E%80-614-%EC%A0%95%EB%A6%AC-%EC%98%88%EC%A0%95</guid>
            <pubDate>Tue, 13 Jun 2023 16:21:49 GMT</pubDate>
            <description><![CDATA[<p>브라우저 렌더링 과정을 공부하다가 렌더링이 무엇인지 관련 개념들을 정리를 해야겠다고 생각이 들었다.</p>
<h1 id="1-렌더링이란">1) 렌더링이란</h1>
<p>서버로부터 HTML 파일을 받아 브라우저에 뿌려주는 과정</p>
<h1 id="⚙️-1-1-렌더링-과정">⚙️ 1-1) 렌더링 과정</h1>
<p>더 자세한건 3참고</p>
<ul>
<li>HTML을 파싱하여 DOM 트리를 만든다.</li>
<li>CSS를 파싱하여 CSSOM 트리를 만든다.</li>
<li>DOM과 CSSOM을 결합하여 렌더링 트리를 만든다.</li>
<li>렌더링 트리에서 각 노드의 크기와 위치를 계산한다.</li>
<li>개별 노드를 화면에 그린다.</li>
</ul>
<h1 id="2-reflowrepaing">2) reflow,repaing</h1>
<ul>
<li>reflow : 레이아웃을 다시 계산</li>
<li>repaint : 재결합된 렌더 트리를 기반으로 다시 페인트를 칠하는 것</li>
</ul>
<blockquote>
<p>렌더링이 완료된 상태에서 사용자의 인터랙션에 의해 화면의 일부 영역이 변경됐을 때 발생한다. 레이아웃이 변경될 경우 리플로우 리페인트를 거침, 레이아웃에는 영향을 주지 않지만 가시성에는 영향을 주는 엘리먼트가 변경될 때는 리페인트만 거침 (ex: opacity, background-color)</p>
</blockquote>
<h4 id="💡-레이아웃의-변경-예시">💡 레이아웃의 변경 예시</h4>
<ul>
<li>DOM 엘리먼트 추가, 제거 또는 변경</li>
<li>CSS 스타일 추가, 제거 또는 변경</li>
<li>CSS 스타일을 직접 변경하거나, 클래스를 추가함으로써 레이아웃이 변경될 수 있다. 엘리먼트의 길이를 변경하면, - DOM 트리에 있는 다른 노드에 영향을 줄 수 있다.</li>
<li>CSS3 애니메이션과 트랜지션. 애니메이션의 모든 프레임에서 리플로우가 발생한다.</li>
<li>offsetWidth 와 offsetHeight 의 사용. offsetWidth 와 offsetHeight 속성을 읽으면, 초기 리플- 로우가 트리거되어 수치가 계산된다.</li>
<li>유저 행동. 유저 인터랙션으로 발생하는 hover 효과, 필트에 텍스트 입력, 창 크기 조정, 글꼴 크기 변경, 스타일시트 또는 글꼴 전환등을 활성화하여 리플로우를 트리거할 수 있다.</li>
</ul>
<h3 id="최적의-렌더링-성능을-얻기-위해선-리플로우-리페인트-과정을-최적화-해야-할-필요가-있음">최적의 렌더링 성능을 얻기 위해선 리플로우, 리페인트 과정을 최적화 해야 할 필요가 있음</h3>
<h1 id="2-1-리플로우-최소화-방법">2-1) 리플로우 최소화 방법</h1>
<h2 id="1-인라인-스타일을-사용하지-않는다">1) 인라인 스타일을 사용하지 않는다.</h2>
<blockquote>
<p>인라인 스타일은 가독성을 해칠뿐 아니라, 수차례 리플로우를 발생시킴. 외부 스타일을 사용할 경우 1회 리플로우를 발생시킴</p>
</blockquote>
<h2 id="2-작업-그루핑">2) 작업 그루핑</h2>
<blockquote>
<p>DOM 요소의 정보를 요청하고 변경하는 코드는 같은 형태의 작업끼리 묶어 실행한다.</p>
</blockquote>
<h2 id="3-노출-제어">3) 노출 제어</h2>
<blockquote>
<p>display의 속성 값을 none으로 하면, 렌더링 트리에서 노드가 빠지게 된다. 따라서 노드를 노출시킨채 스타일을 변경하는 것보다 노드를 감추고 스타일을 변경한 후 노드를 노출시키는 것이 리플로우와 리페인트 발생횟수를 줄이는 방법이다. </p>
</blockquote>
<pre><code>let element = document.getElementById(&quot;box1&quot;); 

for(let i=50; i&lt;100; i++) {     
  element.style.width = i + &quot;px&quot;; 
} 
for(let i=1; i&lt;=50; i++) {  
  element.style.borderWidth = i + &quot;px&quot;; 
}

// 아래와 같이 렌더링 트리에서 빼준 다음, 스타일을 적용하고 다시 노출.
// 이 경우 두번의 리플로우 리페인트만 발생

let element = document.getElementById(&quot;box1&quot;);
element.style.display = &quot;none&quot;; 

for(let i=50; i&lt;100; i++) {    
  element.style.width = i + &quot;px&quot;; 
} 
for(let i=1; i&lt;=50; i++) {  
  element.style.borderWidth = i + &quot;px&quot;; 
} 

element.style.display = &quot;block&quot;;</code></pre><h2 id="4-노드-복제">4) 노드 복제</h2>
<blockquote>
<p>변경하려는 요소의 노드를 복제한 후 복제된 노드에 작업을 하고, 교체를 해주면 리플로우와 리페인트는 한번만 발생함</p>
</blockquote>
<h2 id="5-캐싱">5) 캐싱</h2>
<blockquote>
<p>여기서 말하는 캐싱은 별도의 변수에 자주 사용하는 값을 저장하는 것임. scrollWidth와 같은 값을 호출할 경우 리플로우를 유발하기 때문에, 반복 구문을 실행하기 전에 이를 변수에 담아놓으면 리플로우 발생을 최소화 할 수 있음</p>
</blockquote>
<h1 id="3-렌더링-엔진">3) 렌더링 엔진</h1>
<h2 id="역할">역할</h2>
<ul>
<li>HTML, CSS 등을 파싱하여 최종적으로 화면에 그리는 역할</li>
</ul>
<h2 id="렌더링-엔진의-동작-원리">렌더링 엔진의 동작 원리</h2>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/680833e9-9bfb-4070-a4fe-314375d578a6/image.png" alt="">
① 브라우저는 서버로부터 HTML 문서를 모두 전달 받는다.
② 렌더링 엔진은 전달받은 HTML 문서 파싱하여 DOM 트리를 구축한다.
③ 외부 CSS 파일과 함께 포함된 스타일 요소를 파싱한다.(CSSOM(CSS Object Model) 생성)
④ DOM 트리와 ③의 결과물을 합쳐 렌더 트리를 구축한다.
⑤ 렌더 트리의 각 노드에 대해서 화면 상에서 어디에 배치할 지 결정한다.
⑥ UI백엔드에서 렌더 트리를 그리게 되고, 화면에 우리가 볼 수 있도록 출력된다.</p>
<h2 id="웹킷-렌더링-엔진의-동작-과정-예시">웹킷 렌더링 엔진의 동작 과정 예시</h2>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/cab70d45-d85d-43c8-9398-9d8e04c1a159/image.png" alt=""></p>
<hr>
<h2 id="자세한-과정-해설">자세한 과정 해설</h2>
<h3 id="①-dom-트리-구축">① DOM 트리 구축</h3>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/f47d5990-204a-4224-a7aa-667e87b04ec6/image.png" alt=""></p>
<ul>
<li>브라우저는 서버로부터 html 문서를 모두 전달 받음</li>
<li>어휘, 구문 분석을 통해 html 문서를 파싱하고, 파싱 트리를 생성함</li>
<li>파싱 트리를 기반으로 DOM 요소와 속성 노드를 가지는 DOM 트리를 생성함 </li>
</ul>
<h3 id="②-cssomcss-object-model-생성">② CSSOM(CSS Object Model) 생성</h3>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/7449b909-1574-4e98-9e3e-f97bf9cceb58/image.png" alt=""></p>
<ul>
<li>①의  DOM을 생성할 때 거쳤던 과정을 그대로 CSS에 반복한다.</li>
<li>그 결과로 브라우저가 이해하고 처리할 수 있는 형식으로 변환된다. </li>
</ul>
<h3 id="③-렌더-트리dom--cssom-생성">③ 렌더 트리(DOM + CSSOM) 생성</h3>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/c4bdd188-f49d-494c-87b6-3882b3c0a996/image.png" alt=""></p>
<ul>
<li>DOM Tree가 구축 되어가는 동안 브라우저는 DOM Tree를 기반으로 렌더 트리를 생성한다. 문서를 시각적인 구성 요소로 만들어주는 역할을 한다.</li>
</ul>
<h3 id="④-렌더-트리-배치">④ 렌더 트리 배치</h3>
<ul>
<li>렌더 트리는 위치와 크기를 가지고 있지 않기 때문에, 객체들에게 위치와 크기를 결정해준다. </li>
</ul>
<h3 id="⑤-렌더-트리-그리기">⑤ 렌더 트리 그리기</h3>
<ul>
<li>렌더 트리의 각 노드를 화면의 픽셀로 나타낸다.</li>
<li>렌더 트리 그리기가 완료되면, 화면에 콘텐츠가 표현된다. </li>
</ul>
<h1 id="4-파싱">4) 파싱</h1>
<blockquote>
<p>브라우저가 코드를 이해하고 사용할 수 있는 구조로 변환하는 것</p>
</blockquote>
<h1 id="5렌더링-트리">5)렌더링 트리</h1>
<blockquote>
<p>렌더링을 위한 트리의 자료구조, 브라우저 화면에 표시할 노드들로만 구성되어 있으며 CSS에 비표시되는 노드들은 포함되지 않는다.</p>
</blockquote>
<p><strong>레이아웃을 계산하는데 사용</strong>되고, 브라우저 화면에 픽셀을 렌더링하는 페인팅 처리에 입력된다. </p>
<p>참고 글
<a href="https://velog.io/@ru_bryunak/%EB%A0%8C%EB%8D%94%EB%A7%81%EC%9D%B4%EB%9E%80">https://velog.io/@ru_bryunak/%EB%A0%8C%EB%8D%94%EB%A7%81%EC%9D%B4%EB%9E%80</a>
<a href="https://all-young.tistory.com/22">https://all-young.tistory.com/22</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[web] CSR, SSR]]></title>
            <link>https://velog.io/@w0_0727/CSR-SSR</link>
            <guid>https://velog.io/@w0_0727/CSR-SSR</guid>
            <pubDate>Tue, 13 Jun 2023 16:09:56 GMT</pubDate>
            <description><![CDATA[<h1 id="csr--client-side-rendering">CSR : Client Side Rendering</h1>
<ul>
<li>렌더링이 클라이언트 쪽에서 일어난다. 
ㄴ 사용자의 행동에 따라 필요한 부분만 다시 읽어옴, 서버는 json 파일만 보내주고, html을 그리는 역할은 자바스크립트를 통해 클라이언트 측에서 수행하는 방식</li>
</ul>
<h2 id="csr-단계">CSR 단계</h2>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/3856fcf5-d44a-48f0-bb20-e33ff389f142/image.png" alt=""></p>
<p>1) User가 Website 요청을 보낸다.
2) CDN이 HTML 파일과 JS로 접근할 수 있는 링크를 클라이언트로 보낸다. 
3) 클라이언트는 HTML과 JS를 다운로드 받는다. (이때 유저는 아무것도 볼 수 없다)
4)
5) 다운된 JS가 실행된다. 데이터를 위한 api가 호출된다. (이때 유저들이 placeholder를 봄)
6) 서버가 api로부터 요청에 응답한다.
7) api로부터 받아온 data를 placeholder자리에 넣어주고, 이제 페이지는 상호작용이 가능해진다.
서버에서 처리 없이 클라이언트로 보내주기 때문에 자바스립트가 모두 다운로드 되고 실행이 끝나기 전까지 사용자는 볼 수 있는게 없음</p>
<ul>
<li>모바일 시대에 들어오면서 SPA가 등장함<h3 id="spa-single-page-application">SPA (Single Page Application)</h3>
</li>
<li>최초 한 번 페이지 전체를 로딩한 뒤, 데이터만 변경하여 사용할 수 있는 어플리케이션 
ㄴ 기본적으로 페이지 로드가 없고, 모든 페이지가 단순히 html5 History에 의해 렌더링 됨</li>
</ul>
<h1 id="ssr--server-side-rendering">SSR : Server Side Rendering</h1>
<ul>
<li>서버쪽에서 렌더링 준비를 끝마친 상태로 클라이언트에 전달하는 방식</li>
<li>기존의 전통적 방법인 SSR 방식에 성능 문제가 존재함, 요청할 때마다 새로고침이 일어나면서 페이지를 로딩할 때마다 서버로부터 리소스를 전달받아 해석하고 화면에 렌더링하므로 데이터가 많을수록 SSR은 성능문제가 발생함 </li>
</ul>
<p><img src="https://velog.velcdn.com/images/w0_0727/post/03e0d202-75fd-4370-a94a-ea2c78fb4bc4/image.png" alt=""></p>
<p>1) User가 Website 요청을 보냄.
2) Server는 &#39;Ready to Render&#39;. 즉, 즉시 렌더링 가능한 html파일을 만든다.(리소스 체크, 컴파일 후 완성된 HTML 컨텐츠로 만든다.)
3) 클라이언트에 전달되는 순간, 이미 렌더링 준비가 되어있기 때문에 HTML은 즉시 렌더링 된다. 그러나 사이트 자체는 조작 불가능하다. (Javascript가 읽히기 전이다.)
4) 클라이언트가 자바스크립트를 다운받는다.
5) 다운 받아지고 있는 사이에 유저는 컨텐츠는 볼 수 있지만 사이트를 조작 할 수는 없다. 이때의 사용자 조작을 기억하고 있는다.
6) 브라우저가 Javascript 프레임워크를 실행한다.
7) JS까지 성공적으로 컴파일 되었기 때문에 기억하고 있던 사용자 조작이 실행되고 이제 웹 페이지는 상호작용 가능해진다.</p>
<h2 id="csr-vs-ssr">CSR vs SSR</h2>
<ol>
<li><p>웹페이지 로딩 시간
 1) 첫 페이지 로딩 시간</p>
<ul>
<li>CSR : html, css와 모든 스크립트를 한번에 불러옴</li>
<li>SSR : (더 빠름) 필요한 부분만 먼저 불러옴
2) 나머지 로딩 시간<ul>
<li>CSR : (더 빠름) 첫 페이지 로딩에서 나머지 페이지를 구성하는 코드를 모두 가져온 상태</li>
</ul>
</li>
<li>SSR : 첫 페이지를 로딩한 과정을 정확하게 다시 실행함 </li>
</ul>
</li>
<li><p>SEO 대응</p>
</li>
<li><p>서버 자원 사용 
CSR : 렌더링이 클라이언트측에서 일어나므로 서버 부하가 적음
SSR : (더 많이 사용) 매번 서버에 요청하기 때문 </p>
</li>
</ol>
<hr>
<p><a href="https://hahahoho5915.tistory.com/52">참고</a>
<a href="https://gyoogle.dev/blog/web-knowledge/CSR%20&amp;%20SSR.html">참고</a></p>
]]></description>
        </item>
    </channel>
</rss>