<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>cosmos-jj.log</title>
        <link>https://velog.io/</link>
        <description>🤍도전하는 건 즐거워요🤍</description>
        <lastBuildDate>Mon, 13 Nov 2023 14:46:17 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>cosmos-jj.log</title>
            <url>https://velog.velcdn.com/images/cosmos-jj/profile/10e07d4e-51cf-444d-86fe-e74c2f2071fd/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. cosmos-jj.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/cosmos-jj" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[python 기초] 파일 처리]]></title>
            <link>https://velog.io/@cosmos-jj/python-%EA%B8%B0%EC%B4%88-%ED%8C%8C%EC%9D%BC-%EC%B2%98%EB%A6%AC</link>
            <guid>https://velog.io/@cosmos-jj/python-%EA%B8%B0%EC%B4%88-%ED%8C%8C%EC%9D%BC-%EC%B2%98%EB%A6%AC</guid>
            <pubDate>Mon, 13 Nov 2023 14:46:17 GMT</pubDate>
            <description><![CDATA[<h2 id="파일-처리">파일 처리</h2>
<p>파일은 <code>바이너리 파일(binary file)</code>과 <code>텍스트 파일(text file)</code>로 나누어서 다룬다. 
바이너리 파일은 <strong>데이터의 저장과 처리를 목적으로 0과 1의 이진 형식으로 인코딩</strong>된 파일이며, 
텍스트 파일은 사<strong>람이 알아볼 수 있는 문자열</strong>로 이루어진 파일이다.</p>
<h3 id="📌-파일-열고-닫기">📌 파일 열고 닫기</h3>
<p><strong>open() / close()</strong></p>
<pre><code class="language-python"># 파일 열기
file_object = open(str: path, str: mode)
# 파일 닫기
file_object.close()</code></pre>
<p><strong>mode 지정 방식</strong></p>
<table>
<thead>
<tr>
<th>모드</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>w</td>
<td>파일이 존재하지 않으면 새로 생성 후 쓰기/ 파일이 존재하면 파일 내용을 비우고 쓰기</td>
</tr>
<tr>
<td>a</td>
<td>기존 파일 뒤에 이어서 쓰기</td>
</tr>
<tr>
<td>x</td>
<td>새로운 파일을 생성/ 파일이 이미 존재하면 Error 발생</td>
</tr>
<tr>
<td>r</td>
<td>파일 읽기</td>
</tr>
</tbody></table>
<br>

<h3 id="📌-with-키워드">📌 with 키워드</h3>
<p>코드 작성 시 파일을 열고 닫지 않는 실수를 방지하기 위해 <strong>with 키워드</strong>를 사용하며, <strong>with 구문이 종료될 때 자동으로 닫히게 된다.</strong></p>
<pre><code class="language-python">with open(str: path, str: mode) as file_object:

    code</code></pre>
<h3 id="📌-파일-읽기쓰기">📌 파일 읽기/쓰기</h3>
<p><strong>read() / write()</strong></p>
<pre><code class="language-python"># 파일 읽기
file_object.read()
# 파일 쓰기
file_object.write(str)</code></pre>
<h3 id="📌-for문을-이용하여-텍스트-한-줄씩-읽기">📌 for문을 이용하여 텍스트 한 줄씩 읽기</h3>
<p><strong>예제 데이터 생성</strong></p>
<pre><code class="language-python"># random 모듈을 이용하여 데이터 구성
import random

# 알파벳 리스트 생성
alphabet = list(&quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;)
# 파일 열기
with open(&quot;C:\\Users\\wooju\\Desktop\\wooju\\file_example.txt&quot;,&quot;w&quot;) as file:
    for i in range(100):
        # 랜덤값으로 변수 생성
        first_str = random.choice(alphabet)
        first_int = random.randrange(50)
        second_str = random.choice(alphabet) + random.choice(alphabet)
        second_int = random.random()

        # 텍스트 쓰기
        file.write(&quot;{}, {}, {}, {}\n&quot;.format(first_str,first_int,second_str,second_int))</code></pre>
<p><img src="https://velog.velcdn.com/images/cosmos-jj/post/078cf84d-f8d6-4b9c-bc11-592893d79de0/image.png" alt=""></p>
<p><strong>반복문으로 한 줄씩 읽기</strong></p>
<pre><code class="language-python"># 파일 열기
with open(&quot;C:\\Users\\wooju\\Desktop\\wooju\\file_example.txt&quot;,&quot;r&quot;) as file:
    for line in file:
        # 변수를 생성하여 한줄씩 넣기
        first_str,first_int,second_str,second_int = line.strip().split(&quot;, &quot;)
        # 한 줄씩 출력
        print(f&quot;{first_str} {first_int} {second_str} {second_int}&quot;)</code></pre>
<p><img src="https://velog.velcdn.com/images/cosmos-jj/post/ef36055e-d3e3-427e-9bd2-7d26b6d14ba8/image.png" alt=""></p>
<h2 id="참고">참고</h2>
<ul>
<li>혼자서 공부하는 파이썬(윤인성 지음)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[python 기초] 람다(lambda)]]></title>
            <link>https://velog.io/@cosmos-jj/python-%EA%B8%B0%EC%B4%88-%EB%9E%8C%EB%8B%A4lambda</link>
            <guid>https://velog.io/@cosmos-jj/python-%EA%B8%B0%EC%B4%88-%EB%9E%8C%EB%8B%A4lambda</guid>
            <pubDate>Tue, 07 Nov 2023 11:21:02 GMT</pubDate>
            <description><![CDATA[<h2 id="람다lambda">람다(lambda)</h2>
<blockquote>
<p><code>람다(lambda)</code> : 함수의 기능을 매개변수로 전달하는 코드를 좀 더 효율적으로 작성할 수 있게 해주는 기능이다.</p>
</blockquote>
<pre><code class="language-python"># 기본적인 형태
lambda 매개변수: 리턴 값</code></pre>
<h3 id="📌-함수의-매개변수로-함수-전달">📌 함수의 매개변수로 함수 전달</h3>
<p><code>콜백 함수(callback function)</code> : 함수의 매개변수에 사용하는 함수</p>
<pre><code class="language-python"># 매개변수로 받은 함수를 5번 반복하는 함수 생성
def call_repeat(func):
    for i in range(5):
        func()

# hello를 출력하는 함수        
def print_hello():
    print(&#39;hello&#39;)

# 함수 호출
call_repeat(print_hello)

# hello
# hello
# hello
# hello
# hello</code></pre>
<p>call_repeat 함수는 함수를 매개변수로 받는 콜백함수이며, 위 코드를 실행하면 &#39;hello&#39; 라는 문자열을 5번 반복한다.  </p>
<h3 id="📌-map-함수--filter-함수">📌 map() 함수 &amp; filter() 함수</h3>
<p>함수를 매개변수로 사용하는 대표적인 내장 함수로 <code>map()</code>과 <code>filter()</code>가 있다.</p>
<p><code>map()</code> : 리스트의 요소를 함수에 넣고 리턴된 값으로 새로운 리스트를 구성
<code>filter()</code> : 리스트의 요소를 함수에 넣고 리턴된 값이 True인 것으로 새로운 리스트 구성</p>
<pre><code class="language-python"># 기본 생성 방법

map(함수,리스트)

filter(함수,리스트)</code></pre>
<p><strong>example</strong></p>
<pre><code class="language-python">def test1(num1):
    return num1*num1
def test2(num2):
    return num2 &lt; 3

test_list = [1, 2, 3, 4, 5]

map_test1 = map(test1,test_list)
print(map_test1)
# &lt;map object at 0x0000017CBA02A7D0&gt;
print(list(map_test1))
# [1, 4, 9, 16, 25]

filter_test2 = filter(test2,test_list)
print(filter_test2)
# &lt;filter object at 0x0000017CBA02AF50&gt;
print(list(filter_test2))
# [1, 2]</code></pre>
<p>위 코드를 보면 map 과 filter 를 사용해 새로운 리스트를 생성했을 때 바로 출력하게 되면 map object, filter object 와 같은 <code>제너레이터(generator)</code>가 나오게 된다. 각 변수에 제대로 할당되었는지 보기 위해 리스트타입으로 형변환하여 출력하면 제대로 할당된 것을 알 수 있다.</p>
<blockquote>
<p>❗ 제너레이터(generator)는 다음 포스팅할 주제로 좀 더 자세히 다룰 예정이다.</p>
</blockquote>
<blockquote>
<p>❗ 간단하게 짚고 넘어가자면 파이썬의 특수한 문법 구조로 이터레이터( next() 함수를  적용해 하나하나 꺼낼 수 있는 요소 )를 직접 만들 때 사용하는 코드이다.</p>
</blockquote>
<h3 id="📌-인라인-람다inline-lambda">📌 인라인 람다(inline lambda)</h3>
<p>map() 함수와 filter() 함수는 함수를 매개변수로 받는 것을 알게 되었으니 그 자리에 람다를 통해 직접적으로 함수를 넣을 수 있다.</p>
<p>위에서 구현한 코드를 람다를 이용하여 바꿔보자.</p>
<pre><code class="language-python">test_list = [1, 2, 3, 4, 5]

map_test1 = map(lambda x:x*x,test_list)
print(list(map_test1))
# [1, 4, 9, 16, 25]

filter_test2 = filter(lambda x:x&lt;3,test_list)
print(list(filter_test2))
# [1, 2]</code></pre>
<p>실행 결과는 이전과 같고, 람다를 사용하면 <strong>코드를 더 직관적이고 깔끔하게 작성</strong>할 수 있다.</p>
<h2 id="참고">참고</h2>
<ul>
<li>혼자 공부하는 파이썬 (윤인성 지음)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[python 기초]  튜플(tuple)]]></title>
            <link>https://velog.io/@cosmos-jj/python-%EA%B8%B0%EC%B4%88-%ED%8A%9C%ED%94%8Ctuple</link>
            <guid>https://velog.io/@cosmos-jj/python-%EA%B8%B0%EC%B4%88-%ED%8A%9C%ED%94%8Ctuple</guid>
            <pubDate>Mon, 06 Nov 2023 12:10:55 GMT</pubDate>
            <description><![CDATA[<h2 id="튜플">튜플</h2>
<blockquote>
<p><code>튜플(tuple)</code>은 리스트와 비슷한 자료형이며, 리스트와 다른 점은 한번 결정된 요소는 바꿀 수 없다는 것이다.</p>
</blockquote>
<h3 id="📌-튜플-생성-방법">📌 튜플 생성 방법</h3>
<pre><code class="language-python">tuple_test = (10, 20, 30)

tuple_test[0]
# 10

tuple_test[1]
# 20

tuple_test[:]
# (10, 20, 30)

type(tuple_test)
# tuple</code></pre>
<p>위의 코드와 같이 튜플은** (,) 소괄호를 통해 선언** 하며, 리스트와 같이** 인덱싱, 슬라이딩 모두 가능** 하다. 
소괄호를 사용하여 요소를 넣은 변수를<code>type() 함수</code>를 사용하여 확인했을 때 tuple이 나오는 것으로 tuple_test는 튜플이라는 자료형이라는 것을 알 수 있다.  </p>
<br>

<h3 id="📌-튜플-내부-요소-변경">📌 튜플 내부 요소 변경</h3>
<pre><code class="language-python">tuple_test = (10, 20, 30)

tuple_test[0] = 1</code></pre>
<p><img src="https://velog.velcdn.com/images/cosmos-jj/post/ffd14a1c-c06a-47c1-a7df-b2443f1f83e4/image.png" alt=""></p>
<p>tuple_test의 0번 째 요소를 1로 바꾸려고 하면 위와 같이 TypeError가 발생하게 된다. 
즉 <strong>튜플은 수정, 삽입, 삭제가 불가</strong>하다. (한번 결정된 요소는 변경 불가)</p>
<h3 id="📌-요소를-하나만-가지는-튜플">📌 요소를 하나만 가지는 튜플</h3>
<p>요소를 하나만 가지는 튜플은 어떻게 만들까?</p>
<pre><code class="language-python">tuple_test = (10)
type(tuple_test)
# int

tuple_test = (10,)
type(tuple_test)
# tuple</code></pre>
<p>위의 코드에서 보면 (10)을 tuple_test에 넣었을 때 타입을 보면 int형이 나온다.
즉 10이라는 숫자에 괄호를 감싼 것으로 인식한다는 것이다.
그렇기에 요소를 하나만 가지는 튜플을 만들기 위해서는** (10,)과 같이 쉼표를 함께 넣어서 선언**해야한다.</p>
<blockquote>
<p>❗ 요소를 하나만 가지는 튜플은 많이 사용하나 잊기 쉬운 내용으로 꼭 기억하자</p>
</blockquote>
<h3 id="📌-괄호-없는-튜플">📌 괄호 없는 튜플</h3>
<p>튜플을 사용하는 이유는 <strong>외관이 간단</strong>하고 <strong>요소를 변경할 수 없는 것</strong>으로 구분할 수 있다.
이 중 튜플의 외관이 간단하다고 말할 수 있는 이유는 튜플을 선언할 때 괄호를 생략할 수 있는 상황에서는 괄호 생략이 가능하기 때문이다.</p>
<ul>
<li>튜플의 다중 할당 구문</li>
</ul>
<blockquote>
<p>파이썬에는 [a, b] = [10, 20] 과 같이 a와 b에 10과 20을 각각 할당해주는 다중 할당 구문이라는 문법이 있다. </p>
</blockquote>
<pre><code class="language-python"># 튜플로 a,b에 10,20 할당 
(a, b) = (10, 20)
print(a,b)
# 10 20 

# 튜플의 특징인 괄호 생략
a,b = 10, 20
print(a,b)
# 10 20</code></pre>
<p><code>a,b = 10, 20</code>같은 코드는 파이썬에서 자주 사용되는 구문으로 튜플을 기반으로 작성된 코드라고 할 수 있다.</p>
<ul>
<li>여러 개의 값 리턴<pre><code class="language-python">def tuple_test():
  return (10, 20, 30)
</code></pre>
</li>
</ul>
<p>a, b, c = tuple_test()
print(a,b,c,)</p>
<h1 id="10-20-30">10 20 30</h1>
<p>-------------------------- 동일한 결과값
def tuple_test():
    # 튜플의 괄호 생략
    return 10, 20, 30</p>
<p>a, b, c = tuple_test()
print(a,b,c,)</p>
<h1 id="10-20-30-1">10 20 30</h1>
<p>```</p>
<h2 id="참고">참고</h2>
<ul>
<li>혼자 공부하는 파이썬 (윤인성 지음)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Algorithm] 시간 복잡도 & 공간 복잡도]]></title>
            <link>https://velog.io/@cosmos-jj/Algorithm-%EC%8B%9C%EA%B0%84-%EB%B3%B5%EC%9E%A1%EB%8F%84-%EA%B3%B5%EA%B0%84-%EB%B3%B5%EC%9E%A1%EB%8F%84</link>
            <guid>https://velog.io/@cosmos-jj/Algorithm-%EC%8B%9C%EA%B0%84-%EB%B3%B5%EC%9E%A1%EB%8F%84-%EA%B3%B5%EA%B0%84-%EB%B3%B5%EC%9E%A1%EB%8F%84</guid>
            <pubDate>Fri, 03 Nov 2023 21:41:50 GMT</pubDate>
            <description><![CDATA[<h2 id="complexity복잡도">Complexity(복잡도)</h2>
<p><code>Complexity</code> : 알고리즘의 성능을 나타내는 척도</p>
<p>컴퓨터는 1초에 대략 3-5억 개 정도의 연산이 가능하다. 다만 AND, OR, 비교, 덧셈과 같은 단순한 연산인지 나눗셈, 곱셈, 대입, 함수 같은 복잡한 연산인 지에 따라 횟수의 차이가 날 수는 있다.</p>
<p>결과를 먼저 말하자면 복잡도가 낮을 수록 좋은 알고리즘이라고 할 수 있다.
<br></p>
<h2 id="time-complexity시간-복잡도">Time complexity(시간 복잡도)</h2>
<p><code>Time complexity</code> : 입력의 크기와 문제를 해결하는데 걸리는 시간의 상관 관계</p>
<p>시간 복잡도를 어떻게 구하는 지 알아보기 위해서 간단한 예제를 통해 흐름을 알아볼 수 있다.</p>
<pre><code class="language-python"># lst -&gt; 리스트 타입
# n -&gt; 정수 타입
def func1(lst, n):
    cnt = 0
    for i in range(n):
        if lst[i] % 5 == 0:
            cnt += 1
    return cnt</code></pre>
<p>위의 코드는 lst[0] 부터 lst[num-1]까지 돌면서 5의 배수일 때 cnt 라는 변수의 값을 1 증가 시킨다.</p>
<p>이 코드는 몇 번의 연산을 수행하는 지 알아보자면</p>
<ul>
<li>cnt 변수를 선언하고 0을 넣을 때 : 1</li>
<li>반복문이 n번 반복 : n</li>
<li>반복문 안에서  lst[i] 값을 5로 나눌 때 : 1</li>
<li>lst[i] 값을 5로 나눈 나머지가 0인지 판별할 때 : 1</li>
<li>lst[i]가  5의 배수라면 cnt 값이 증가하므로 : 1</li>
<li>return cnt = 1</li>
</ul>
<p>총 <strong>1+nx(1+1+1) +1 ⇒ 3n + 2</strong></p>
<p>위의 코드는 3n+2번 연산을 하는데 n의 값에 따라서 연산이 증가한다.
그래서 예시 코드의 연산은 <strong>n에 비례한다</strong> 라고 말할 수 있고,
시간 복잡도는 입력의 크기와 문제를 해결하는데 걸리는 시간의 상관 관계이기 때문에 
예시 코드의 시간 복잡도는 n 이다.</p>
<br>
🔽시간 복잡도는 빅오 표기법을 통해 나타내기 때문에 빅오 표기법을 아래에서 알아보자🔽

<h3 id="big-o-notation빅오-표기법">Big-O Notation(빅오 표기법)</h3>
<p><code>Big-O Notation</code> : 가장 빠르게 증가하는 항만을 고려하는 표기법 </p>
<pre><code class="language-python">| 표기법        | 설명                 | 예시 알고리즘              |
|--------------|----------------------|--------------------------|
| O(1)         | 상수 시간 복잡도     | 배열에서 요소 하나 찾기       |
| O(logN)      | 로그 시간 복잡도     | 이진 검색                   |
| O(N)         | 선형 시간 복잡도     | 선형 탐색                   |
| O(NlogN)     | 로그 선형 시간 복잡도 | 퀵 정렬, 병합 정렬          |
| O(N²)        | 이차 시간 복잡도     | 버블 정렬, 삽입 정렬         |
| O(N³)        | 삼차 시간 복잡도     | 3중 루프 알고리즘           |
| O(2ⁿ)        | 지수 시간 복잡도     | 부분집합 생성, 완전탐색      |</code></pre>
<p>연산 횟수가 2N³ + 5N² + 1,000,000인 알고리즘이 있다면  <strong>시간 복잡도는 O(N³)</strong> 라고 부른다</p>
<br>


<p><img src="https://velog.velcdn.com/images/cosmos-jj/post/e86e84ad-7d11-46b6-9d15-da648d431497/image.png" alt=""></p>
<p>&lt;출처 : <a href="https://blog.encrypted.gg/922&gt;">https://blog.encrypted.gg/922&gt;</a></p>
<p>그래프를 보면 N의 크기에 따라 시간 복잡도의 차이가 수행 시간이 큰 영향을 준다는 것을 알 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/cosmos-jj/post/325bf857-9be8-4d8c-a292-f627a00e155b/image.png" alt=""></p>
<p>&lt;출처 : <a href="https://blog.encrypted.gg/922&gt;">https://blog.encrypted.gg/922&gt;</a></p>
<p>문제에서 주어지는 시간 제한은 대부분 1초에서 5초사이로, 입력의 범위를 보고 요구하는 시간 복잡도가 어느 정도인지를 알 수 있다.</p>
<h2 id="space-complexity공간-복잡도">Space complexity(공간 복잡도)</h2>
<p>→ 입력의 크기와 문제를 해결하는데 필요한 공간의 상관 관계
→ 알고리즘이 필요로 하는 메모리의 양</p>
<p><code>빅오 표기법을 사용한 표기법</code></p>
<p>크기가 N인 1차원 배열이 필요하다면 <strong>O(N)</strong>
크기가 N인 2차원 배열이 필요하다면 <strong>O(N²)</strong>
배열이 필요 없다면 <strong>O(1)</strong></p>
<p>🍯<strong>꿀Tip : 512MB = 1.2억개의 int</strong></p>
<br>

<h2 id="참고">참고</h2>
<ul>
<li><a href="https://blog.encrypted.gg/922">https://blog.encrypted.gg/922</a> (바킹독 블로그)</li>
<li><a href="https://www.youtube.com/watch?v=m-9pAwq1o3w&amp;list=PLRx0vPvlEmdAghTr5mXQxGpHjWqSz0dgC">https://www.youtube.com/watch?v=m-9pAwq1o3w&amp;list=PLRx0vPvlEmdAghTr5mXQxGpHjWqSz0dgC</a> (이코테 유튜브)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[python 기초] list comprehensions]]></title>
            <link>https://velog.io/@cosmos-jj/python-%EA%B8%B0%EC%B4%88-list-comprehensions</link>
            <guid>https://velog.io/@cosmos-jj/python-%EA%B8%B0%EC%B4%88-list-comprehensions</guid>
            <pubDate>Mon, 30 Oct 2023 14:41:44 GMT</pubDate>
            <description><![CDATA[<h3 id="list-comprehensions-리스트-내포">list comprehensions (리스트 내포)</h3>
<p>: 반복문을 이용하여 <strong>짧게 한 줄</strong>로 리스트 작성</p>
<pre><code># 기본 형식
리스트 이름 = [ 표현식 for 반복 변수 in 반복할 수 있는 것]

# 조건문을 포함한 형식
리스트 이름 = [ 표현식 for 반복 변수 in 반복할 수 있는 것 if 조건문]</code></pre><p><strong>EX</strong></p>
<pre><code class="language-python"># 기본 형식
example_list = [i*i for i in range(0,10,2)]

print(example_list)
# [0, 4, 16, 36, 64]

# 조건문을 포함한 형식
example_list_if = [i*i for i in range(0,10) if i%2 == 0]

print(example_list_if)
# [0, 4, 16, 36, 64]
</code></pre>
<h3 id="list-comprehensions-줄바꿈">list comprehensions 줄바꿈</h3>
<pre><code>리스트 이름 = [ 표현식
    for 반복 변수 in 반복할 수 있는 것
    if 조건문 ]</code></pre><p><strong>EX</strong></p>
<pre><code class="language-python">line_change = [str(i)+&#39;길게 써보자&#39; 
                   for i in range(0,10) 
                   if i%2 == 0]
print(line_change)
# [&#39;0길게 써보자&#39;, &#39;2길게 써보자&#39;, &#39;4길게 써보자&#39;, &#39;6길게 써보자&#39;, &#39;8길게 써보자&#39;]</code></pre>
<h3 id="참고">참고</h3>
<ul>
<li>혼자 공부하는 파이썬 (윤인성 지음)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[python 기초] enumerate(), items()]]></title>
            <link>https://velog.io/@cosmos-jj/python-%EA%B8%B0%EC%B4%88-enumerate-items</link>
            <guid>https://velog.io/@cosmos-jj/python-%EA%B8%B0%EC%B4%88-enumerate-items</guid>
            <pubDate>Mon, 30 Oct 2023 14:23:03 GMT</pubDate>
            <description><![CDATA[<h3 id="enumerate-와-list">enumerate() 와 list</h3>
<ul>
<li>현재 index가 몇 번째인지 확인해야 하는 경우</li>
</ul>
<pre><code class="language-python">enumerate_list = [&#39;우주&#39;,&#39;은하&#39;,&#39;별&#39;]

# enumerate() 함수 적용
print(enumerate(enumerate_list))
# &lt;enumerate object at 0x0000012650076D90&gt;

# list() 함수로 강제 변환 후 출력
print(list(enumerate(enumerate_list)))
# [(0, &#39;우주&#39;), (1, &#39;은하&#39;), (2, &#39;별&#39;)]

# 반복문과 조합하여 사용
for i, j in enumerate(enumerate_list):
    print(&quot;{}번째 = {}&quot;.format(i,j)) 

&quot;&quot;&quot;
0번째 = 우주
1번째 = 은하
2번째 = 별
&quot;&quot;&quot;</code></pre>
<h3 id="items-와-dictionary">items() 와 dictionary</h3>
<ul>
<li>dictionary의 key와 value값을 모두 출력하고 싶을 때</li>
</ul>
<pre><code class="language-python">items_dic = {
    &quot;key1&quot; : &quot;value1&quot;,
    &quot;key2&quot; : &quot;value2&quot;,
    &quot;key3&quot; : &quot;value3&quot;
}

#items() 함수 적용
print(items_dic.items())
# dict_items([(&#39;key1&#39;, &#39;value1&#39;), (&#39;key2&#39;, &#39;value2&#39;), (&#39;key3&#39;, &#39;value3&#39;)])

# 반복문과 조합하여 사용
for key,value in items_dic.items():
    print(&quot;key:{} value:{}&quot;.format(key,value))
&quot;&quot;&quot;
key:key1 value:value1
key:key2 value:value2
key:key3 value:value3
&quot;&quot;&quot;</code></pre>
<blockquote>
<p>결론 : enumerate() 함수와 items() 함수를 이용하면 반복변수를 2개 사용할 수 있다.</p>
</blockquote>
<h3 id="참고">참고</h3>
<ul>
<li>혼자 공부하는 파이썬 (윤인성 지음)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[python 기초] 역반복문과 피라미드]]></title>
            <link>https://velog.io/@cosmos-jj/python-%EA%B8%B0%EC%B4%88-%EC%97%AD%EB%B0%98%EB%B3%B5%EB%AC%B8%EA%B3%BC-%ED%94%BC%EB%9D%BC%EB%AF%B8%EB%93%9C</link>
            <guid>https://velog.io/@cosmos-jj/python-%EA%B8%B0%EC%B4%88-%EC%97%AD%EB%B0%98%EB%B3%B5%EB%AC%B8%EA%B3%BC-%ED%94%BC%EB%9D%BC%EB%AF%B8%EB%93%9C</guid>
            <pubDate>Mon, 30 Oct 2023 12:54:49 GMT</pubDate>
            <description><![CDATA[<p><code>역반복문</code> : 반복 변수가 큰 숫자에서 작은 숫자로 내려가는 것</p>
<h3 id="방법-1-range함수의-매개변수-이용">방법 1 range()함수의 매개변수 이용</h3>
<pre><code class="language-python">for i in range(5,-1,-1):
    print(&quot;i = {} &quot;.format(i),end=&#39; &#39;)

# i = 5  i = 4  i = 3  i = 2  i = 1  i = 0  </code></pre>
<ul>
<li><code>range(5,-1,-1)</code> : 5부터 0까지 -1씩 감소</li>
</ul>
<h3 id="방법-2-reversed함수-사용">방법 2 reversed()함수 사용</h3>
<pre><code class="language-python">for i in reversed(range(5)):
    print(&quot;i = {} &quot;.format(i),end=&#39; &#39;)

# i = 4  i = 3  i = 2  i = 1  i = 0  </code></pre>
<ul>
<li>[0, 1, 2, 3, 4]의 범위를 <code>reversed()</code>를 통해서 [4, 3, 2, 1, 0]로 뒤집기</li>
</ul>
<h3 id="for-반복문을-통해-피라미드-만들기">for 반복문을 통해 피라미드 만들기</h3>
<p>방법1을 사용하여 피라미드 구현</p>
<pre><code class="language-python">star = int(input(&quot;별 개수&quot;))

for k in range(star):
    for i in range(star-k,-1,-1):
        print(end=&#39; &#39;)
    for j in range(0,k*2+1):
        print(&quot;*&quot;,end=&#39;&#39;)
    print()

 # 10 입력 시
           *
          ***
         *****
        *******
       *********
      ***********
     *************
    ***************
   *****************
  *******************</code></pre>
<p>방법2를 사용하여 피라미드 구현</p>
<pre><code class="language-python">star = int(input(&quot;별 개수&quot;))

for k in range(star):
    for i in reversed(range(star-k)):
        print(end=&#39; &#39;)
    for j in range(0,k*2+1):
        print(&quot;*&quot;,end=&#39;&#39;)
    print()

# 10 입력 시
          *
         ***
        *****
       *******
      *********
     ***********
    *************
   ***************
  *****************
 *******************</code></pre>
<pre><code>구현 과정
1. 공백을 출력하는 반복문 (역반복문 이용) : 변수i
2. 별을 출력하는 반복문 : 변수j
3. 1,2,번을 감싸는 총 몇번 반복할 지 결정하는 반복문 : 변수 k

특징 : 변수 k가 증가할수록 i는 줄어들며 j는 증가하는 형태</code></pre><h3 id="참고">참고</h3>
<ul>
<li>혼자 공부하는 파이썬 (윤인성 지음)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[python 기초] 딕셔너리(dictionary)]]></title>
            <link>https://velog.io/@cosmos-jj/python-%EA%B8%B0%EC%B4%88-%EB%94%95%EC%85%94%EB%84%88%EB%A6%ACdictionary</link>
            <guid>https://velog.io/@cosmos-jj/python-%EA%B8%B0%EC%B4%88-%EB%94%95%EC%85%94%EB%84%88%EB%A6%ACdictionary</guid>
            <pubDate>Tue, 24 Oct 2023 18:46:31 GMT</pubDate>
            <description><![CDATA[<h3 id="딕셔너리dictionary">딕셔너리(dictionary)</h3>
<ul>
<li><code>키</code>를 기반으로 <code>값</code>을 저장하는 것</li>
<li>딕셔너리 내부 값에 문자열, 숫자, 불, 리스트, 딕셔너리 등 다양한 자료를 넣을 수 이 있음</li>
</ul>
<p><strong>선언 형식</strong></p>
<pre><code>dictionary = {key:value, key:value, key:value ···}</code></pre><p><strong>내부 요소 접근법</strong></p>
<pre><code class="language-python">dictionary[key] =&gt; value

# 딕셔너리 값에 여러가지 자료를 가지고 있는 경우

dictionary = {
    &quot;apple&quot;: 1.00,
    &quot;banana&quot;: [0.75, 2.13, 3,34],
    &quot;Strawberry&quot;: 2.50,
    &quot;orange&quot;: 1.20,
    &quot;grape&quot;: 2.00 }

# 추가로 인덱스를 설정하여 내부 요소 접근 가능
print(dictionary[&quot;banana&quot;][0])
# 0.75
</code></pre>
<h3 id="딕셔너리-값-추가제거">딕셔너리 값 추가/제거</h3>
<p><strong>값 추가</strong></p>
<pre><code>dictionary[new key] = new value</code></pre><p><strong>값 제거</strong></p>
<pre><code>del dictionary[key]</code></pre><p><strong>ex</strong></p>
<pre><code class="language-python">dictionary = {
    &quot;apple&quot;: 1.00,
    &quot;banana&quot;: [0.75, 2.13, 3,34],
    &quot;Strawberry&quot;: 2.50,
    &quot;orange&quot;: 1.20,
    &quot;grape&quot;: 2.00 }
# 값 추가
dictionary[&quot;peach&quot;] = 7.56

print(dictionary)
&quot;&quot;&quot;
{&#39;apple&#39;: 1.0, &#39;banana&#39;: [0.75, 2.13, 3, 34], &#39;Strawberry&#39;: 2.5,
 &#39;orange&#39;: 1.2, &#39;grape&#39;: 2.0, &#39;peach&#39;: 7.56}
&quot;&quot;&quot;

# 값 제거
del dictionary[&quot;banana&quot;]

print(dictionary)
&quot;&quot;&quot;
{&#39;apple&#39;: 1.0, &#39;Strawberry&#39;: 2.5, &#39;orange&#39;: 1.2, &#39;grape&#39;: 2.0,
&#39;peach&#39;: 7.56}
&quot;&quot;&quot;</code></pre>
<h3 id="존재하지-않는-키에-접근하는-상황">존재하지 않는 키에 접근하는 상황</h3>
<ul>
<li>딕셔너리에 존재하지 않는 키에 접근하면 KeyError가 발생하기 때문에 내부에 존재하는지 확인이 필요함
<img src="https://velog.velcdn.com/images/cosmos-jj/post/33ff5127-e3f5-44f4-930e-8c7c6b8092ee/image.png" alt=""></li>
</ul>
<p><strong>in 키워드</strong></p>
<pre><code class="language-python"># key in dictionary
# 값이 bool 형태

print(&quot;peach&quot; in dictionary)
# True

print(&quot;melon&quot; in dictionary)
# False</code></pre>
<p><strong>get()</strong></p>
<pre><code class="language-python"># 딕셔너리의 키로 값을 추출하는 함수
# 존재하지 않는 키에 접근할 경우 KeyError가 아닌 None을 출력함

print(dictionary.get(&quot;peach&quot;))
# 7.56

print(dictionary.get(&quot;melon&quot;))
# None
</code></pre>
<h3 id="참고">참고</h3>
<ul>
<li>혼자 공부하는 파이썬 (윤인성 지음)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[pandas] jupyter notebook 한글 폰트 깨짐 해결]]></title>
            <link>https://velog.io/@cosmos-jj/Python-jupyter-notebook-%ED%95%9C%EA%B8%80-%ED%8F%B0%ED%8A%B8-%EA%B9%A8%EC%A7%90-%ED%95%B4%EA%B2%B0</link>
            <guid>https://velog.io/@cosmos-jj/Python-jupyter-notebook-%ED%95%9C%EA%B8%80-%ED%8F%B0%ED%8A%B8-%EA%B9%A8%EC%A7%90-%ED%95%B4%EA%B2%B0</guid>
            <pubDate>Sun, 22 Oct 2023 12:18:33 GMT</pubDate>
            <description><![CDATA[<p>Python에서 데이터를 시각화하다 보면 아래와 같이 한글 깨짐이 발생하게 된다.
그래서 한글 깨짐을 방지하기 위해 <strong>2가지 방법</strong>으로 한글 폰트를 설정해 볼 것이다.</p>
<p>⬇ (Matplotlib를 통해 그래프를 시각화하였을 때 발생한 한글 깨짐 현상)
<img src="https://velog.velcdn.com/images/cosmos-jj/post/53068f8f-cf3a-476e-97aa-5069925e9dc0/image.png" alt=""></p>
<hr>
<h3 id="1-code-작성을-통해-해결">1. Code 작성을 통해 해결</h3>
<pre><code class="language-python">import os

if os.name == &#39;posix&#39;:
    plt.rc(&quot;font&quot;, family=&quot;AppleGothic&quot;)

else:
    plt.rc(&quot;font&quot;, family=&quot;Malgun Gothic&quot;)</code></pre>
<pre><code class="language-python"># 마이너스 폰트가 깨지는 문제를 대처하기 위한 코드

plt.rc(&quot;axes&quot;, unicode_minus=False)</code></pre>
<h3 id="2-pip-설치를-통해-해결">2. pip 설치를 통해 해결</h3>
<pre><code class="language-python"># !pip install koreanize-matplotlib 터미널에 입력하여 설치
# 설치 후 import로 불러오기

import koreanize_matplotlib</code></pre>
<hr>
<p>위의 방법을 적용하였을 경우
⬇ matplotlib를 사용하여 시각화를 해보면 한글이 깨지지 않는 것을 볼 수 있다.
<img src="https://velog.velcdn.com/images/cosmos-jj/post/c3b97216-3bbe-4f50-b9cb-d04bf8643f5e/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[pandas] 10 minutes to pandas : Object creation]]></title>
            <link>https://velog.io/@cosmos-jj/Python-10-minutes-to-pandas-Object-creation-Viewing-data</link>
            <guid>https://velog.io/@cosmos-jj/Python-10-minutes-to-pandas-Object-creation-Viewing-data</guid>
            <pubDate>Fri, 20 Oct 2023 17:04:08 GMT</pubDate>
            <description><![CDATA[<h3 id="object-creation">Object creation</h3>
<h4 id="import-pandas">import pandas</h4>
<pre><code class="language-python">import pandas as pd</code></pre>
<h4 id="basic-data-structures-in-pandas">Basic data structures in pandas</h4>
<ul>
<li><code>Series</code> : 모든 유형의 데이터를 보관하는 1차원 배열</li>
<li><code>DataFrame</code> : 행과 열이 있는 테이블과 같은 데이터를 보관하는 2차원 배열</li>
</ul>
<h4 id="creating-a-series">Creating a Series</h4>
<ul>
<li>list의 값으로 Series 생성</li>
</ul>
<pre><code class="language-python">#In
s = pd.Series([1,2,3,4,5])

#Out
0    1
1    2
2    3
3    4
4    5
dtype: int64</code></pre>
<h4 id="2-creating-a-dataframe">2. Creating a DataFrame</h4>
<ul>
<li><code>Numpy</code>를 사용하여 <code>DataFrame</code> 생성<pre><code class="language-python">import numpy as np
</code></pre>
</li>
</ul>
<p>#In
number = [1,2,3,4,5,6]</p>
<p>df = pd.DataFrame(np.random.randn(6,4), index=number, columns=list(&#39;ABCD&#39;))</p>
<p>#Out
            A            B           C           D
1    -0.713372    0.487297    0.175619    1.126466
2    -2.031435    0.338329    0.047565    0.239074
3    1.197670    -0.361998    -0.247807    -1.301809
4    -0.162813    0.635130    0.497010    -1.128038
5    0.986570    0.801526    -0.835925    0.173154
6    -1.369150    -0.034347    0.027706    -0.928288</p>
<pre><code>
✅ np.random.randn(6,4)를 사용하여 무작위 숫자로 데이터를 채움
✅ index=number : index를 number라는 리스트로 생성
✅ columns=list(&#39;ABCD&#39;) : &#39;ABCD&#39;라는 문자열을 list로 변환하여 columns 생성


&lt;br&gt;

- `딕셔너리`를 사용하여 `DataFrame` 생성
```python
#In
df2 = pd.DataFrame({&#39;A&#39; : 1,
                    &#39;B&#39; : [&quot;test1&quot;, &quot;test2&quot;, &quot;test3&quot;],
                    &#39;C&#39; : pd.Series(2, index=list(range(3)), dtype=&#39;float32&#39;)})

#Out

     A        B      C
0    1    test1    2.0
1    1    test2    2.0
2    1    test3    2.0</code></pre><p>✅ A : 1이라는 정수를 가진 열 생성
✅ B : &quot;test1&quot;, &quot;test2&quot;, &quot;test3&quot; 문자열을 가지는 열 생성
✅ C : 2라는 실수를 가진 열 생성 ( 인덱스는 0, 1, 2 데이터 형식은 float32로 지정된 시리즈로 생성 )</p>
<h3 id="참고">참고</h3>
<ul>
<li><a href="https://pandas.pydata.org/pandas-docs/version/1.0.0/getting_started/10min.html">https://pandas.pydata.org/pandas-docs/version/1.0.0/getting_started/10min.html</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[python 기초] 리스트(list)]]></title>
            <link>https://velog.io/@cosmos-jj/python-%EB%A6%AC%EC%8A%A4%ED%8A%B8</link>
            <guid>https://velog.io/@cosmos-jj/python-%EB%A6%AC%EC%8A%A4%ED%8A%B8</guid>
            <pubDate>Thu, 19 Oct 2023 15:35:54 GMT</pubDate>
            <description><![CDATA[<h3 id="리스트list">리스트(list)</h3>
<ul>
<li>여러가지 자료를 저장할 수 있는 자료</li>
<li>인덱스를 기반으로 값을 저장</li>
</ul>
<pre><code class="language-python">list = [277,32,&quot;문자열&quot;,True]
# 요소(element) : 대괄호 [ ] 내부에 넣는 자료 

list[0]
# 277

list[0:3]
# [277, 32, &#39;문자열&#39;]
# [0:3] ➡ `슬라이싱` : 범위 선택 연산자</code></pre>
<h3 id="리스트-표현">리스트 표현</h3>
<h4 id="인덱스-음수표현">인덱스 음수표현</h4>
<pre><code class="language-python">list = [277,32,&quot;문자열&quot;,True]

list[-1]
# True

list[-2]
# &#39;문자열&#39;
</code></pre>
<h4 id="리스트-접근-연산자-이중-사용">리스트 접근 연산자 이중 사용</h4>
<pre><code class="language-python"> list = [277,32,&quot;문자열&quot;,True]

 list[2][0]
 # &#39;문&#39;
 # list[2] `문자열` 의 [0]번째 &#39;문&#39;</code></pre>
<h3 id="리스트-연산">리스트 연산</h3>
<h4 id="연결-반복">연결(+), 반복(*)</h4>
<pre><code class="language-python">
list_a = [1,2,3]
list_b = [4,5,6]

print(list_a+list_b)
# [1, 2, 3, 4, 5, 6]

print(list_a * 3)
# [1, 2, 3, 1, 2, 3, 1, 2, 3]</code></pre>
<h3 id="리스트에-요소-추가">리스트에 요소 추가</h3>
<h4 id="append">append()</h4>
<pre><code class="language-python">리스트.append(요소) / 뒤에 이어서 붙이기

list = [1,2,3]
list.append(4)

print(list)
# [1, 2, 3, 4]
</code></pre>
<h4 id="insert">insert()</h4>
<pre><code class="language-python">리스트.inseret(요소) / 원하는 위치에 요소 추가

list = [1,2,3]
list.insert(2,4)

print(list)
# [1, 2, 4, 3]
</code></pre>
<h4 id="extend">extend()</h4>
<pre><code class="language-python">리스트1.extend(리스트2) / 리스트 합치기

list_a = [1,2,3]
list_b = [4,5,6]
list_a.extend(list_b)

print(list_a)
# [1, 2, 3, 4, 5, 6]
</code></pre>
<h3 id="리스트-연결-연산자와-요소-추가의-차이">리스트 연결 연산자와 요소 추가의 차이</h3>
<pre><code class="language-python">
list_a = [1,2,3]
list_b = [4,5,6]

print(list_a + list_b)
# [1, 2, 3, 4, 5, 6]
print(list_a)
# [1, 2, 3]
</code></pre>
<ul>
<li>print(list_a + list_b) 값이 출력이 되며, list_a가 변하지 않음</li>
<li><code>비파괴적</code> : 원본에 영향을 주지 않는 것</li>
</ul>
<pre><code class="language-python">list_a = [1,2,3]
list_b = [4,5,6]

print(list_a.extend(list_b))
# None
print(list_a)
# [1, 2, 3, 4, 5, 6]</code></pre>
<ul>
<li>print(list_a.extend(list_b)) 값이 출력되지 않으며, list_a가 변함</li>
<li><code>파괴적</code> : 리스트에 직접적인 영향을 주는것</li>
</ul>
<h3 id="리스트-요소-제거">리스트 요소 제거</h3>
<h4 id="인덱스로-제거">인덱스로 제거</h4>
<p>① del 키워드 ➡ <code>del 리스트명[인덱스]</code></p>
<ul>
<li>슬라이싱을 사용해 제거 가능</li>
</ul>
<p>② pop() ➡ <code>리스트명.pop(인덱스)</code></p>
<ul>
<li>매개변수를 입력하지 않으면 -1이 들어가는 것으로 취급하여 마지막 요소 제거</li>
</ul>
<pre><code class="language-python">
list = [1,2,3]

del list[0]
print(list)
# [2, 3]

list.pop()
print(list)
# [2]
</code></pre>
<h4 id="값으로-제거">값으로 제거</h4>
<p>remove() ➡ <code>리스트.remove(값)</code></p>
<pre><code class="language-python">
list = [1,2,3]

list.remove(2)

print(list)
# [1, 3]
</code></pre>
<h4 id="요소-모두-제거">요소 모두 제거</h4>
<p>clear() ➡ <code>리스트.clear()</code></p>
<pre><code class="language-python">
list = [1,2,3]

list.clear()

print(list)
# []
</code></pre>
<h3 id="리스트-정렬">리스트 정렬</h3>
<ul>
<li><code>리스트.sort()</code> : 오름차순 정렬</li>
<li><code>리스트.sort(reverse=True)</code> : 내림차순 정렬</li>
</ul>
<pre><code class="language-python">list = [1,2,3,4,5]

list.sort()
print(list)
# [1, 2, 3, 4, 5]

list.sort(reverse=True)
print(list)
# [5, 4, 3, 2, 1]
</code></pre>
<h3 id="리스트-내부-확인">리스트 내부 확인</h3>
<ul>
<li>in 연산자 ➡ <code>값 in 리스트</code></li>
<li>not in 연산자 ➡ <code>값 not in 리스트</code></li>
</ul>
<pre><code class="language-python">list = [1,2,3,4,5]

print(3 in list)
# True
print(6 in list)
# False

print(3 not in list)
# False
print(6 not in list)
# True</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JSCODE] 모의 면접으로 학습하는 운영체제 스터디 회고]]></title>
            <link>https://velog.io/@cosmos-jj/JSCODE-%EB%AA%A8%EC%9D%98-%EB%A9%B4%EC%A0%91%EC%9C%BC%EB%A1%9C-%ED%95%99%EC%8A%B5%ED%95%98%EB%8A%94-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%8A%A4%ED%84%B0%EB%94%94-%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@cosmos-jj/JSCODE-%EB%AA%A8%EC%9D%98-%EB%A9%B4%EC%A0%91%EC%9C%BC%EB%A1%9C-%ED%95%99%EC%8A%B5%ED%95%98%EB%8A%94-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%8A%A4%ED%84%B0%EB%94%94-%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Thu, 19 Oct 2023 14:45:04 GMT</pubDate>
            <description><![CDATA[<h3 id="😌-cs-공부의-필요성">😌 CS 공부의 필요성</h3>
<p>비전공자였던 내가 학원에 들어가 수업을 처음 들었을 때 수업 내용을 이해하기 어려웠던 나는 원래 처음에는 입문하기 위한 허들이 높다 라고 생각했다. 하지만 이상함을 느꼈던 건 수업을 한 달 정도 들었을 때, 같은 내용을 듣고 같은 반 학생분들과 의견을 나누면서 이해하는 정도가 남들보다 떨어졌다고 느낀 후였다.</p>
<h3 id="🤔-왜-나는-같은-수업의-내용을-듣고-남들보다-이해를-못했을까">🤔 왜 나는 같은 수업의 내용을 듣고 남들보다 이해를 못했을까?</h3>
<p>계속해서 고민해보면서 CS 지식이 부족하기 때문이란 것을 알게 되었다. 그 이유는 학원에서 프로그래밍 언어, 운영체제 등등 개발에 관련된 공부를 할 때 같은 단어가 중복되어 나오고 비슷한 개념으로 이루어져 있어 모든 것이 나무처럼 연결되어 있고 뿌리가 computer science 라고 생각했던 것 같다.</p>
<h3 id="🤓-왜-스터디-형식의-공부를-선택했을까">🤓 왜 스터디 형식의 공부를 선택했을까?</h3>
<p>처음 혼자서 CS 공부를 시작했을 때 강의와 책을 다양하게 찾아서 공부했지만, 내가 확실하게 이해를 했는지 확인할 방법이 없어서 공부를 해도 불안한 마음을 가지고 있었다. 그래서 사람들과 공부한 내용을 서로 이야기하고 더해서 개발직군에 관련된 정보를 얻고자 스터디를 생각하게 되었다.</p>
<br>

<hr>
<h3 id="jscode-모의면접으로-학습하는-운영체제-스터디에-참여">[JSCODE] 모의면접으로 학습하는 운영체제 스터디에 참여</h3>
<p>스터디는 매주 1회 2시간 총 5주 동안 온라인 ZOOM을 통해서 진행되었다. 매주 주제에 관련된 10개 정도의 실전 면접 질문을 제공받고 질문에 대한 답을 하기 위해 공부 및 블로그에 정리하는 과제를 받았다. ZOOM에서 모의 면접을 진행할 때는 면접자, 지원자, 관찰자로 역할을 나누어 모의면접을 진행했다.</p>
<h3 id="스터디를-하는-동안-어려웠던-점">스터디를 하는 동안 어려웠던 점</h3>
<p>아무래도 스터디, CS 공부, 면접 세 가지 모두가 처음이다보니 많은 어려움을 겪었었고, 그 어려움을 해결해보려고 노력했다.</p>
<h4 id="지원자">지원자</h4>
<p>➡ 모의 면접에서 지원자의 역할을 맡았을 때 가장 어려웠던 점은 아무래도 답에 대해 기억이 나지 않았을 때 대처하는 방법이었다. 외웠던 대답이 기억이 안 나면 보통 자신이 기억했던 개념을 상기시키며 대답을 대처하지만 질문에 대한 답을 문장으로 외우는 공부를 했던 나는 기억이 나지 않으면 그에 대한 대처를 하나도 하지 못했었다. 그렇게 되면서 지원자의 역할이 점점 무서워지게 되었다.</p>
<p>이 어려움을 극복하기 위해서 나는 공부 방법을 바꾸는 것을 택했다. 강의와 책을 보면서 개념을 정리하고 끝나는 것이 아닌 정리한 개념의 흐름을 이해하려고 노력했다. 예를 들면 시간의 순서로 개념을 익힌다던지 벤 다이어그램으로 개념을 정리한다던지 말이다. 그렇게 개념을 공부하고 질문에 답을 정리할 때는 키워드로 암기를 했다. 공부 방법을 바꾼 후 모의 면접에서 지원자의 역할을 맡았을 때는 기억이 나지 않더라도 스스로 생각해서 어느 정도 대답을 만들어 낼 수 있었다.</p>
<h4 id="면접자">면접자</h4>
<p>➡ 모의 면접에서 면접자의 역할을 맡았을 때 어려웠던 점은 추가 질문을 만들어 내는 것이었다. 제공 받은 질문 외에 질문을 해야 팀원들도 나도 한층 더 나은 면접을 대비할 수 있기 때문에 서로를 위해서라도 다양한 질문들을 하기 위해 노력해야했다. 이 어려움은 스터디에 지속적으로 참여하면서 팀원들이 하는 방식을 보다보니 자연스럽게 다양하게 질문하는 법을 터득하게 되었다. 하지만 압박 질문 만큼은 아직도 어렵다...</p>
<h4 id="관찰자">관찰자</h4>
<p>➡ 모의 면접에서 관찰자의 역할은 면접자와 지원자에게 피드백을 주는 역할이다. 나는 이 역할만큼은 자신이 있었는데 그 이유는 스스로 객관적인 평가에 자신이 있었기 때문이다. 그래서 팀원들이 나의 피드백을 듣고 세세하게 문제점을 잘 파악해준다고 칭찬을 해주셨다. 그래도 관찰자의 어려운 점을 뽑자면 답변의 형태를 옳은 지 옳지 않은 지 구별하는 것이었다. 팀원들이 답변 방식은 모두 달랐기에 누가 틀린 것이고 맞는 것인지 알 수가 없어 판단하기에 어려움을 느꼈었다.</p>
<p>이 어려움은 코치(토마스)님의 말씀을 통해서 해결할 수 있었는데 처음 질문에는 간결하게 대답을 하고 그 뒤에 따라오는 꼬리 질문에 자신이 이해한 부분을 자세하게 대답하는 것이 가장 이상적인 대답이라고 해주셨다.</p>
<h4 id="과제">과제</h4>
<p>➡ 이 스터디의 과제는 학습한 내용을 Blog에 포스팅 하는 것이다. 나는 Blog를 시작한지 얼마 되지 않았기에 이 과제는 나에게 고민거리였다. 글은 간결하게 작성해야 하는 지 하나하나 나의 생각을 담는 것이 좋은 건지 아직도 알 수가 없다. 포스팅하는 글마다 다르게 써보고 남들이 하는 것을 참고해봐도 모두가 달랐다. 블로그라는 것은 정답이 없는 게 아닐까 싶기도 하고 그래서 이 어려움은 앞으로 Blog에 공부를 정리하면서 나만의 방식을 찾아가려고 한다.</p>
<br>

<hr>
<h3 id="좋았던-점">좋았던 점</h3>
<p>스터디를 통해서 나는 IT 취업과 관련된 꿀팁들을 많이 얻을 수 있었다. 커뮤니티 활동을 하지 않았던 나는 개발 직군의 사람들과 네트워크를 형성할 기회가 없어 정보가 많이 없었는데 이번 스터디를 통해서 이력서 꿀팁, 공부 방향성, 기술 스택 추천등 많은 정보를 얻어갈 수 있었다.</p>
<p>두번째로 공부를 좀 더 깊게 할 수 있다는 점이 좋았다. 혼자서 공부를 하게 되면 개별적인 선생님이 없다면 개념을 이해하기만으로도 벅차다. 하지만 스터디에서 질문에 대한 대답을 공유하면서 잘못 이해했던 부분, 추가적으로 알면 좋은 내용 등을 서로 주고 받다보니 효율적으로 공부를 할 수 있었다.</p>
<p>세번째로 면접을 대비할 수 있었던 점이 좋았다. 실제 면접을 보는 것 보다는 긴장감이 덜하지만 모의 면접을 통해 대답을 깔끔하게 말할 수 있도록 연습할 수 있었고 추가로 인성면접 질문도 제공해주시고 대답하는 팁도 알려주시면서 실제 면접을 이떻게 준비하면 좋을지 틀을 잡을 수 있었다.</p>
<br>

<hr>
<h3 id="아쉬웠던-점">아쉬웠던 점</h3>
<p>모의면접 스터디를 하기 전에는 사람들과 활발하게 네트워킹을 할 수 있을 줄 알았다. 하지만 막상 스터디를 했을 때는 기대했던 점이 잘 이루어지지 않았다.
단톡방이 있긴 하지만 토마스님만 공지사항에 관련된 말씀을 해주실 뿐 다른 분들은 거의 말하지 않으셨고 모르는 질문을 할 때에는 토마스님이 답변해주시기를 기다리거나, 모의 면접을 하는 날에 모아서 질문을 해야했다. 나도 마찬가지로 점점 질문은 줄어갔고 누군가 먼저 얘기하기를 계속 기다리게 되는 것이 아쉬웠다. 적극성같은 부분은 개인의 몫이기에 다음에 참여할 때는 내가 먼저 나서서 질문을 많이 하고, 분위기를 좋게 만드는 스몰토크를 시도하여 많은 사람들이 편안하게 의견을 주고 받을 수 있도록 노력해야겠다.</p>
<br>

<hr>
<h3 id="마지막으로">마지막으로</h3>
<p>나의 첫 스터디가 한 달이라는 시간이 지나 끝이났다. 짧은 시간이었지만 그 시간 내에서도 포기하고 싶었던 순간이 있었다. 각종 과제가 겹쳐 해야할 일이 많아 벅찼을 때, 면접에 잘 대답할 자신이 없어서 ZOOM의 찾가 버튼을 누르지 못하고 한참동안 들어가지 못했을 때, 직장인이셨던 팀원분들에 비해 한참 지식이 부족했던 내 자신이 비교되었을 때.. 처음이다보니 힘든 시간이 종종 찾아왔지만 내가 버틸 수 있었던 건 도전에 대한 즐거움이 아닐까 싶다. 모르는 내용을 알아갈 때, 면접은 무섭지만 끝나고 팀원들과 이야기를 나눌 때, 지난 주와는 다른 내가 느껴질 때 ! 끝나고 보니 더 잘하지 못한 아쉬움과 그래도 완주했다는 뿌듯함이 느껴진다. 다음 스터디도 화이팅 해야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[4회차] 운영체제 모의면접 스터디 대비]]></title>
            <link>https://velog.io/@cosmos-jj/4%ED%9A%8C%EC%B0%A8-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%AA%A8%EC%9D%98%EB%A9%B4%EC%A0%91-%EC%8A%A4%ED%84%B0%EB%94%94-%EB%8C%80%EB%B9%84</link>
            <guid>https://velog.io/@cosmos-jj/4%ED%9A%8C%EC%B0%A8-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%AA%A8%EC%9D%98%EB%A9%B4%EC%A0%91-%EC%8A%A4%ED%84%B0%EB%94%94-%EB%8C%80%EB%B9%84</guid>
            <pubDate>Fri, 06 Oct 2023 16:30:29 GMT</pubDate>
            <description><![CDATA[<p>❓ 병행성(동시성)에 대해 설명해주세요.</p>
<p>💭 병행성은 한 개의 CPU가 다수의 프로세스들을 서로 번갈아 가면 수행하여 동시에 작업이 실행되는 것처럼 느끼게 해주는 것입니다. 컴퓨터에서 자주 쓰이는 변수나 함수는 모든 프로세스들이 접근 가능한 전역 메모리에 적재하여 공유되는데 병행성으로 인하여 프로세스간 메모리 공유는 문제를 야기할 수 있습니다.</p>
<hr>
<p>❓ 병렬성에 대해 설명해주세요.</p>
<p>💭 병행성과 다르게 병렬성은 실제로 동시에 작업이 처리되는 것입니다. 보통 멀티 코어에서 멀티 쓰레드를 동작시키는 방식이며 한번에 많은 일을 처리할 수 있기 때문에 병렬처리를 이용하여 이미지나 비디오를 인코딩하거나, 대규모 데이터를 처리하는 등의 실행 시간을 줄이거나 처리량을 늘리는 데에 사용됩니다.</p>
<hr>
<p>❓ 프로세스 동기화에 대해 설명해 주세요.</p>
<p>💭 Concurrency Control(병행 제어)라고 부르기도 하며, 여러 프로세스 또는 스레드가 동시에 실행해도 공유 데이터의 일관성을 유지하는 것을 말합니다. 이 뜻은 프로세스나 스레드 사이의 수행 시기를 맞추는 것을 의미하는 데 수행 시기를 맞춘다는 것은 첫번쨰로 프로세스를 올바른 순서대로 실행하는 것이며(실행 순서 제어) 두번째는 동시에 접근해서는 안되는 자원에 프로세스만 접근하게 하는것입니다.(상호배제)</p>
<hr>
<p>❓ Critical Section에 대해 설명해주세요.</p>
<p>💭 Critical Section은 공유 데이터의 일관성을 보장하기 위해 하나의 프로세스 또는 스레드만 진입해서 실행 가능한 영역입니다.  </p>
<hr>
<p>❓ Race Condition이 무엇인가요?</p>
<p>💭 여러 프로세스가 동시에 같은 데이터를 조작할 때 타이밍이나 접근 순서에 따라 결과가 달라질 수 있는 상황입니다. 공유 데이터의 최종 연산 결과는 마지막에 공유 데이터를 다룬 프로세스가 누구인지에 따라 달라지며 Race Condition을 막기 위해선 공유 데이터에 대한 동시 접근을 동기화 해야합니다.</p>
<hr>
<p>❓ Race Condition을 어떻게 해결할 수 있나요?</p>
<p>💭 Semaphore(세마포어)와 Mutex(뮤텍스)로 Race Condition을 예방할 수 있습니다.</p>
<hr>
<p>❓ Mutual Exclusion에 대해 설명해주세요.</p>
<p>💭 특정 한 시점에 단 하나의 프로세스만이 Critical section에 접근할 수 있는 것으로 공유가 불가능한 자원의 동시 사용을 피하기 위해 사용하는 알고리즘입니다.</p>
<hr>
<p>❓ Mutual Exclusion을 할 수 있는 방법은?</p>
<p>💭 (잘 모르겠습니다...!)</p>
<ul>
<li><strong>SW solutions</strong><ul>
<li>Dekker’s algorithm (Peterson’s algorithm)</li>
<li>Dijkstra’s algorithm, Knuth’s algorithm, Eisenberg and McGuire’s algorithm, Lamport’salgorithm</li>
</ul>
</li>
<li><strong>HW solution</strong><ul>
<li>TestAndSet(TAS) instruction</li>
</ul>
</li>
<li><strong>OS supported SW solution</strong><ul>
<li>Spinlock</li>
<li>Semaphore</li>
<li>Eventcount/sequencer</li>
</ul>
</li>
<li><strong>Language-Level solution</strong><ul>
<li>Monitor</li>
</ul>
</li>
</ul>
<hr>
<p>❓ 뮤텍스(Mutex)에 대해 설명해주세요.</p>
<p>💭 뮤텍스는 공유 자원에 대해 lock와 unlock을 함으로써 상호배제를 보장하는 기법입니다.</p>
<hr>
<p>❓ 세마포어에 대해 설명해주세요.</p>
<p>💭 뮤텍스와 비슷하지만, 좀 더 일반화된 방식의 동기화 도구입니다. Mutex는 하나의 공유 자원에 접근하는 프로세스를 상정한 방식이지만 Semaphore는 공유 자원이 여러 개 일때 접근하는 프로세스를 상정한 방식입니다. 세마포어의 종류는 이진 세마포와 카운팅 세마포가 있습니다.</p>
<hr>
<p>❓ 뮤텍스(Mutex)와 이진 세마포어의 차이에 대해 설명해주세요.</p>
<p>💭 - 뮤텍스에서는 lock을 설정한 프로세스만이 unlock을 할 수 있다. 하지만 이진 세마포어에서는 lock을 설정한 프로세스와 unlock을 하는 프로세스가 서로 다를 수 있다.</p>
<hr>
<p>❓ 모니터에 대해 설명해주세요.</p>
<p>💭 프로세스 또는 스레드를 동기화하는 방법 중 하나로서 사용자가 사용하기에 세마포어보다 훨씬 편리한 도구입니다. 모니터는 공유자원과 공유 자원에 접근하기 위한 인터페이스를 묶어서 관리하며 프로세스는 반드시 인터페이스를 통해서만 공유 자원에 접근하도록 해야합니다. 모니터는 모니터는 모니터에 진입하기 위한 큐를 만들고, 모니터 안에 항상 하나의 프로세스만 들어오도록 하여 상호 배제를 위한 동기화 제공하고 모니터는 조건 변수를 이용하여 프로세스 실행 순서 제어를 위한 동기화를 제공합니다.</p>
<hr>
<p>❓ 데드락이 무엇인가요?</p>
<p>💭 두 개 이상의 프로세스 혹은 스레드가 서로가 가진 리소스를 기다리는 상태입니다.</p>
<hr>
<p>❓ 데드락 발생 조건 4가지를 설명해 주세요.</p>
<p>💭 리소스를 공유해서 사용할 수 없다는 상호 배제 , 프로세스가 이미 하나 이상의 리소스를 취득한 상태에서 다른 프로세스가 사용하고 있는 리소스를 추가로 기다리는 점유와 대기, 리소스 반환은 오직 그 리소스를 취득한 프로세스만 할 수 있다는 비선점, 프로세스들이 순환형태로 서로의 리소스를 기다리는 원형 대기가 있습니다.</p>
<hr>
<p>❓ 데드락 회피 방법은 무엇이 있나요?</p>
<p>💭 데드락 회피 방법에는 은행원 알고리즘이 있습니다. 은행원 알고리즘은 프로세스가 시작시 자신이 필요한 자원의 최대 개수를 미리 선언하고 각 프로세스에서 자원요청이 있을때 시스템이 안전한 상태라고 유지되는 경우에만 자원을 할당합니다. 그렇지 않은 불안정 상태가 예상되면 다른 프로세스가 자원을 반환할 때 까지 대기하는 알고리즘 입니다.</p>
<hr>
<p>❓ 최근에 관심가지고 있는 기술에 대해서 설명해주세요.</p>
<p>💭 최근에 Linux에 관심이 있어 공부하고 있습니다. 리눅스는 컴퓨터 운영체제 중 하나로 오픈소스 프로그램이며, 리눅스는 다중작업이 가능하고 CLI 기반이라는 특징이 있습니다. 또한 리눅스는  우분투, 페도라, 레드햇, 센트오에스 등 여러 종류로 나누어져 있습니다.</p>
<hr>
<p>❓ 기술을 어떤식으로 학습 하는지 설명해주세요.</p>
<p>💭 저는 강의나 책 또는 공식 문서를 보며 기술을 이해하고 문법을 학습합니다. 문법을 학습하면서 실제로 간단하게 구현해보고 그 과정을 블로그에 기록하며 복습합니다. 이론을 공부한 후 스터디나 프로젝트 등 함께모여서 공부할 수 있는 환경을 만들어 제가 잘못이해한 부분이나 다른 방식으로는 어떻게 접근할 수 있는지 학습합니다.</p>
<hr>
<p>❓ 안정적인 시스템을 개발하는 팀에서 꼭 지켜야할 개발 프로세스는 뭐라고 생각하시나요?</p>
<p>💭 저는 사용자 피드백이라고 생각합니다. 시스템을 개발하기 위해서 개발자는 많은 노력을 기울이고 수많은 테스트를 거치지만 결국 시스템은 배포를 거쳐 사용자가 사용하게 되고 개발하며 생각하지 못했던 문제점들이 나타나게 됩니다. 그래서 안정적으로 시스템을 개발하기 위해서 꼭 지켜야 할 것은 최종적으로 시스템을 사용하는 사용자의 피드백을 수집하고 고려하여 시스템을 지속적으로 개선하는 프로세스를 꼭 지켜야 한다고 생각합니다.</p>
<hr>
<p><strong>추가 질문</strong></p>
<p>❓ Process Synchronization 문제를 풀기 위한 조건</p>
<p>💭 mutual exclusion (상호 배제) / progress (진행) /bounded waiting (유한 대기)/동일 속도
<img src="https://velog.velcdn.com/images/cosmos-jj/post/45ace05f-1aa7-4276-b3de-280aa347bcba/image.png" alt=""></p>
<hr>
<p>❓ race condition이 발생하는 예를 하나만 설명해주세요</p>
<p>💭 <img src="https://velog.velcdn.com/images/cosmos-jj/post/95ea5fb4-8f09-466a-a275-4b2f9422145e/image.png" alt=""></p>
<hr>
<p>❓ Busy wating(Spin-Lock)으로 구현한 Semaphores 와 Sleep-Lock 으로 구현한 Semaphores 중 어느 것이 더 좋나요?</p>
<p>💭 일반적으로는 Sleep-Lock 으로 구현한 세마포어가 더 좋다.
하지만 임계구역의 길이가 매우 짧은 경우는 Sleep-Lock 오버헤드가 busy-wait 오버헤드보다 클 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] Parallelism & Concurrency]]></title>
            <link>https://velog.io/@cosmos-jj/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Parallelism-Concurrency</link>
            <guid>https://velog.io/@cosmos-jj/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Parallelism-Concurrency</guid>
            <pubDate>Fri, 06 Oct 2023 08:10:25 GMT</pubDate>
            <description><![CDATA[<h2 id="parallelism--concurrency">Parallelism &amp; Concurrency</h2>
<p><img src="https://velog.velcdn.com/images/cosmos-jj/post/4480f15c-3908-4ab6-b2e6-4191c9c7e253/image.png" alt="">
&lt;이미지 출처&gt; <a href="https://seamless.tistory.com/42">https://seamless.tistory.com/42</a></p>
<p><img src="https://velog.velcdn.com/images/cosmos-jj/post/7c608246-8492-490a-adc2-bbe54bb57a63/image.png" alt="">
&lt;이미지 출처&gt;<a href="https://www.codeproject.com/Articles/1267757/Concurrency-vs-Parallelism">https://www.codeproject.com/Articles/1267757/Concurrency-vs-Parallelism</a></p>
<h4 id="parallelism-병렬성">Parallelism (병렬성)</h4>
<ul>
<li>실제로 동시에 작업이 처리되는 것</li>
<li>멀티 코어에서 멀티 쓰레드를 동작시키는 방식</li>
<li>한번에 많은 일을 처리</li>
<li>물리적인 개념</li>
</ul>
<h4 id="concurrency-병행성">Concurrency (병행성)</h4>
<ul>
<li>동시에 작업이 실행되는 것 처럼 느끼게 해주는 것</li>
<li>싱글 코어에서 멀티 쓰레드를 동작시키는 방식</li>
<li>한번에 많은 것을 처리할 수 있음</li>
<li>논리적인 개념</li>
<li>한 개의 CPU가 다수의 프로세스들을 서로 번갈아 가며 수행 ➡ <code>인터리빙(interleaving)</code></li>
<li>빠른 CPU의 처리 속도로 인해 인터리빙이 빠르게 이루어지며 사용자가 여러 프로그램이 동시작동하는 것 처럼 느끼게 해줌</li>
</ul>
<h4 id="병행성의-문제점">병행성의 문제점</h4>
<ul>
<li>컴퓨터에서 자주 쓰이는 변수 또는 함수는 모든 프로세스들이 접근 가능한 전역 메모리에 적재하여 공유</li>
<li>하지만 병행성으로 인하여 프로세스간 메모리 공유는 문제를 야기할 수 있음</li>
</ul>
<br>

<h2 id="참고">참고</h2>
<ul>
<li>[JSCODE] 운영체제 스터디 1기 개념 정리 노트</li>
<li><a href="https://seamless.tistory.com/42">https://seamless.tistory.com/42</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] Deadlock]]></title>
            <link>https://velog.io/@cosmos-jj/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Deadlock</link>
            <guid>https://velog.io/@cosmos-jj/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Deadlock</guid>
            <pubDate>Fri, 06 Oct 2023 05:09:10 GMT</pubDate>
            <description><![CDATA[<h3 id="deadlock-교착-상태">Deadlock (교착 상태)</h3>
<blockquote>
<p><code>Deadlock (교착 상태)</code> : 두 개 이상의 프로세스 혹은 스레드가 서로가 가진 리소스를 기다리는 상태</p>
</blockquote>
<br>

<h3 id="자원-할당-그래프-resource-allocation-graph">자원 할당 그래프 (Resource-Allocation Graph)</h3>
<p><img src="https://velog.velcdn.com/images/cosmos-jj/post/f8278b16-5d13-4e35-a13f-6a7bfc57b217/image.png" alt="">
&lt;이미지 출처&gt;<a href="https://kukuta.tistory.com/281">https://kukuta.tistory.com/281</a></p>
<ul>
<li>어떤 프로세스가 어떤 자원을 사용하고 있고, 또 어떤 프로세스가 어떤 자원을 기다리고 있는지 표현하는 간단한 그래프이다.</li>
<li>자원 할당 그래프를 보고 데드락의 발생 여부를 판별할 수 있다.</li>
</ul>
<pre><code>자원 할당 그래프 규칙

- 프로세스는 원으로, 자원의 종류는 사각형으로 표현
- 사용할 수 있는 자원의 개수는 자원 사각형 내에 점으로 표현
- 프로세스가 어떤 자원을 할당받아 사용 중이라면 자원에서 프로세스를 향해 화살표를 표시
- 프로세스가 어떤 자원을 기다리고 있다면 프로세스에서 자원으로 화살표를 표시
</code></pre><br>

<h3 id="deadlock을-만드는-4가지-조건">Deadlock을 만드는 4가지 조건</h3>
<ol>
<li><p><code>Mutual exclusion(상호 배제)</code> : 리소스를 공유해서 사용할 수 없다.</p>
</li>
<li><p><code>Hold and wait(점유와 대기)</code> : 프로세스가 이미 하나 이상의 리소스를 취득한(hold) 상태에서 다른 프로세스가 사용하고 있는 리소스를 추가로 기다린다.(wait)</p>
</li>
<li><p><code>No preemption(비선점)</code> : 리소스 반환(release) 은 오직 그 리소스를 취득한 프로세스만 할 수 있다.</p>
</li>
<li><p><code>Circular wait(원형 대기)</code> : 프로세스들이 순환형태로 서로의 리소스를 기다린다.</p>
</li>
</ol>
<br>

<h3 id="deadlock-해결-방법">Deadlock 해결 방법</h3>
<h4 id="데드락-방지-deadlock-prevention">데드락 방지 (Deadlock prevention)</h4>
<ul>
<li>네 가지 조건 중 하나가 충족되지 않게 시스템을 디자인</li>
</ul>
<pre><code>- Mutual exclusion :리소스를 공유 가능하게 함

- Hold and wait : 사용할 리소스들을 모두 획득한 뒤에 시작 or 리소스를 전혀 가지지 않은 상태에서만 리소스 요청

- No preemption : 추가적인 리소스를 기다려야 한다면 이미 획득한 리소스를 다른 프로세스가 선점 가능하도록 한다

- Circular wai : 모든 리소스에 순서 체계를 부여해서 오름차순으로 리소스를 요청</code></pre><h4 id="데드락-회피-deadlock-avoidance">데드락 회피 (Deadlock avoidance)</h4>
<ul>
<li>실행 환경에서 추가적인 정보를 활용해서 데드락이 발생할 것 같은 상황을 회피하는 것</li>
</ul>
<p><code>Safe state</code> : safe sequence(교착상태를 발생시키지 않고 자원을 할당하는 순서)가 존재하며 모든 프로세스가 정상적으로 종료될 수 있는 상태를 의미</p>
<p><code>Unsafe state</code> : 교착상태가 발생할 가능성이 있는 상태</p>
<br>


<p><strong>데드락을 회피하기 위한 알고리즘</strong></p>
<p>①</p>
<pre><code>은행원 알고리즘(Banker&#39;s Algorithm) 
: 리소스 요청을 허락해줬을 때 데드락이 발생할 가능성이 있으면 리소스를 할당해도 
  안전할 때 까지 계속 요청을 거절하는 알고리즘


- 은행에서 모든 고객의 요구가 충족되도록 현금을 할당하는데서 유래

- 프로세스가 자원을 요구할 때, 시스템은 자원을 할당한 후에도 안정 상태로 남아있게 되는지 
사전에 검사하여 교착 상태 회피

- 안정 상태면 자원 할당, 아니면 다른 프로세스들이 자원 해지까지 대기</code></pre><p>②</p>
<pre><code>자원 할당 그래프 알고리즘(Resource-Allocation Graph Algorithm)
: 자원 할당 그래프에 예약 간선을 추가하여 예약 간선으로 설정한 자원에 대해서만 
  자원 할당을 요청할 수 있고 사이클이 형성되지 않을 때만 자원을 할당받는 알고리즘
</code></pre><h4 id="데드락-감지와-복구">데드락 감지와 복구</h4>
<ul>
<li>데드락을 허용하고 데드락이 발생하면 복구하는 전략</li>
</ul>
<p>#감지
자원 할당 그래프를 통해 교착 상태를 탐지함
자원 요청 시, 탐지 알고리즘을 실행시켜 그에 대한 오버헤드 발생함</p>
<p>#복구
<em>사용자 처리</em>
교착상태에 있는 프로세스 중 하나의 프로세스를 사용자가 강제 종료</p>
<p><em>시스템 처리</em>
①프로세스 중지 
데드락에 속해있는 모든 프로세스를 중지
데드락이 해결될 때까지 한 프로세스씩 중지</p>
<p>②자원 선점
프로세스들로부터 자원을 빼앗아 데드락이 해결될 때까지 다른 프로세스들에게 자원을 할당</p>
<br>

<h4 id="데드락-무시">데드락 무시</h4>
<ul>
<li>드물게 발생하는 잠재적 문제를 무시로 대처하는 방식 ➡ 타조 알고리즘 (ostrich algorithm)</li>
</ul>
<h3 id="참고">참고</h3>
<ul>
<li>혼자 공부하는 컴퓨터 구조 + 운영체제 (강민철 지음)</li>
<li><a href="https://cocoon1787.tistory.com/858">https://cocoon1787.tistory.com/858</a></li>
<li><a href="https://gyoogle.dev/blog/computer-science/operating-system/DeadLock.html">https://gyoogle.dev/blog/computer-science/operating-system/DeadLock.html</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] 동기화 기법]]></title>
            <link>https://velog.io/@cosmos-jj/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%8F%99%EA%B8%B0%ED%99%94-%EA%B8%B0%EB%B2%95</link>
            <guid>https://velog.io/@cosmos-jj/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%8F%99%EA%B8%B0%ED%99%94-%EA%B8%B0%EB%B2%95</guid>
            <pubDate>Thu, 05 Oct 2023 14:34:11 GMT</pubDate>
            <description><![CDATA[<h2 id="mutex-뮤텍스">Mutex (뮤텍스)</h2>
<blockquote>
<p><code>Mutex (뮤텍스)</code> : 공유 자원에 대해 동시에 접근해서는 안되는 자원에 동시에 접근하지 않도로록 만드는 기법 즉, 상호 배제를 위한 동기화 도구이다.</p>
</blockquote>
<p>Mutex 매커니즘은 하나의 전역 변수와 두 개의 함수로 구현할 수 있다.</p>
<ul>
<li>프로세스들이 공유하는 전역변수 lock</li>
<li>임계 구역을 잠그는 acquire 함수</li>
<li>임계 구역의 잠금을 해제하는 release 함수</li>
</ul>
<pre><code class="language-python"># 뮤텍스 변수 초기화
lock = False

def acquire():
    global lock
    while lock == True:

    lock = True

def release():
    global lock
    lock = False

# 뮤텍스 획득
acquire()

# --- critical section ---

# 뮤텍스 해제
release()</code></pre>
<p>(위 코드는 while문에서 expected an indented block 에러 발생함)</p>
<br>

<p>위의 코드를 A와B라는 프로세스가 실행한다면
먼저 들어간 A가 실행이 끝나고 lock이 true가 될때까지 B는 while 반복문에서 대기해야한다.
A가 실행이 끝나고 release 함수를 실행하게되면 lock은 false가 되고 B는 반복문에서 빠져나올 수 있다.</p>
<p>이 코드에서 while 반복문은 반복적으로 lock의 상태를 계속 확인하게되는데 
이런 대기 방식을 <code>바쁜 대기(busy wait)</code>라고 한다</p>
<br>

<h2 id="semaphore-세마포어">Semaphore (세마포어)</h2>
<blockquote>
<p><code>Semaphore (세마포어)</code> : 뮤텍스와 비슷하지만, 좀 더 일반화된 방식의 동기화 도구이다.</p>
</blockquote>
<ul>
<li>Mutex는 하나의 공유 자원에 접근하는 프로세스를 상정한 방식이지만 Semaphore는 공유 자원이 여러 개 일때 접근하는 프로세스를 상정한 방식이다.</li>
<li>Semaphore를 구현할 때    <ul>
<li>세마포어의 P 연산은 세마포어 변수를 하나 감소 시킨다.</li>
<li>세마포어의 V 연산은 세마포어 변수를 하나 증가 시킨다.</li>
</ul>
</li>
<li>critical section 진입 전에는 P연산으로 자원을 획득하고, critical section 수행후에는 V연산으로 자원을 반납한다.    </li>
</ul>
<br>




<h3 id="busy-watingspin-lock으로-구현한-semaphores">Busy wating(Spin-Lock)으로 구현한 Semaphores</h3>
<pre><code class="language-python"># 사용 가능한 공유 자원의 개수
S = 3

def P():
    global S
    while S &lt;= 0:

    S = S - 1

def V():
    global S
    S = S + 1

# 세마포어 획득
P()

# --- critical section ---

# 세마포어 해제
V()
</code></pre>
<p>(위 코드는 while문에서 expected an indented block 에러 발생함)</p>
<br>

<p>위 코드는 Mutex처럼 busy waiting이 발생한다.
이는 즉 CPU 주기를 낭비한다는 점에서 손해이다.</p>
<br>

<h3 id="sleep-lock-으로-구현한-semaphores">Sleep-Lock 으로 구현한 Semaphores</h3>
<pre><code class="language-python">import threading

# 사용 가능한 공유 자원의 개수
S = 10

lock = threading.Lock()

condition = threading.Condition(lock)

def P():
    global S

    while S &lt;= 0:
        # 다른 스레드가 세마포어를 해제할 때까지 대기
        condition.wait()
    S = S - 1

def V():
    global S

    S = S + 1
    # 세마포어를 해제한 후 대기 중인 스레드 깨우기
    condition.notify()

# 세마포어 획득
P()

# --- critical section ---

# 세마포어 해제
V()
</code></pre>
<p> 위 코드는 Busy wating(Spin-Lock)으로 구현한 세마포어와는 다르게 임계구역에 먼저 들어간 스레드가 끝난 후 condition.notify()로 세마포어를 해제하기 전까지 Busy wating하고 있는 것이 아닌 대기를 하게 된다.</p>
 <br>


<h3 id="어떤-구현방식이-더-좋을까">어떤 구현방식이 더 좋을까?</h3>
<p>일반적으로는 Sleep-Lock 으로 구현한 세마포어가 더 좋다.
하지만 <strong>임계구역의 길이가 매우 짧은 경우는 Sleep-Lock 오버헤드가 busy-wait 오버헤드보다 클 수 있다.</strong></p>
 <br>

<h3 id="semaphore의-종류">Semaphore의 종류</h3>
<ul>
<li><p><code>이진 세마포(binary semaphore)</code> </p>
<ul>
<li>세마포어 변수가 0 또는 1의 값만 가질 수 있는 세마포어이다.    </li>
<li>주로 mutual exclusion (lock/unlock)에 사용한다.</li>
</ul>
</li>
<li><p><code>카운팅 세마포(counting semaphore)</code></p>
<ul>
<li>세마포어 변수는 0이상인 임의의 정수 값</li>
<li>주로 resource counting에 사용한다.</li>
</ul>
<br>

</li>
</ul>
<h2 id="monitor-모니터">Monitor (모니터)</h2>
<blockquote>
<p><code>Monitor (모니터)</code> :  프로세스 또는 스레드를 동기화하는 방법 중 하나로서 사용자가 사용하기에 세마포어보다 훨씬 편리한 도구이다.</p>
</blockquote>
<ul>
<li><p>공유자원과 공유 자원에 접근하기 위한 인터페이스(통로)를 묶어서 관리한다.</p>
</li>
<li><p>프로세스는 반드시 인터헤이스를 통해서만 공유 자원에 접근하도록 해야한다.</p>
<br>

</li>
</ul>
<p>모니터는 상호 배제와 실행 순서 제어를 위한 동기화이다</p>
<p><strong>상호 배제</strong>
① 모니터를 통해 공유 자원에 접근하고자 하는 프로세스를 큐에 삽입
② 큐에 삽입된 순서대로 하나씩 공유 자원 이용</p>
<p>➡ 모니터는 모니터에 진입하기 위한 큐를 만들고, 모니터 안에 항상 하나의 프로세스만 들어오도록 하여 상호 배제를 위한 동기화 제공</p>
<br>

<p><strong>실행 순서 제어</strong>
① 특정 조건을 바탕으로 프로세스를 실행하고 일시 중단하기 위해 <code>조건 변수(condition variable)</code> 사용</p>
<pre><code>     조건 변수 : 프로세스나 스레드의 실행 순서를 제어하기 위해 사용하는 특별한 변수

     - 조건변수.wait() : 대기 상태로 변경
     - 조건변수.signal() : wait() 으로 대기 상태로 접어든 조건변수를 실행 상태로 변경</code></pre><p>➡ 모니터는 조건 변수를 이용하여 프로세스 실행 순서 제어를 위한 동기화를 제공</p>
 <br>

<h2 id="참고">참고</h2>
<ul>
<li><a href="https://www.youtube.com/watch?v=vp0Gckz3z64">https://www.youtube.com/watch?v=vp0Gckz3z64</a> (쉬운코드 유튜브)</li>
<li>혼자 공부하는 컴퓨터 구조 + 운영체제 (강민철 지음)</li>
<li>[JSCODE] 운영체제 스터디 1기 개념 정리 노트</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] 동기화 (synchronization)]]></title>
            <link>https://velog.io/@cosmos-jj/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%8F%99%EA%B8%B0%ED%99%94-synchronization</link>
            <guid>https://velog.io/@cosmos-jj/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%8F%99%EA%B8%B0%ED%99%94-synchronization</guid>
            <pubDate>Wed, 04 Oct 2023 15:51:23 GMT</pubDate>
            <description><![CDATA[<h2 id="동기화-synchronization">동기화 (synchronization)</h2>
<blockquote>
<p><code>동기화 (synchronization)</code> :여러 프로세스/스레드가 동시에 실행해도 공유 데이터의 일관성을 유지하는 것 (== 프로세스/스레드 사이의 수행 시기를 맞추는 것)</p>
</blockquote>
<p><strong>프로세스/스레드 사이의 수행 시기를 맞춘다는 것은?</strong></p>
<ul>
<li>실행 순서 제어 : 프로세스/스레드를 올바른 순서대로 실행하기</li>
<li>상호 배제 : 동시에 접근해서는 안되는 자원에 하나의 프로세스만 접근하게 하기</li>
</ul>
<h2 id="실행-순서-제어를-위한-동기화">실행 순서 제어를 위한 동기화</h2>
<p><strong>Example</strong></p>
<p>프로세스1 : writer ➡ Book.txt 파일에 값을 저장하는 프로세스
프로세스2 : reader ➡ Book.txt 파일에 저장된 값을 읽는 프로세스</p>
<p>① 프로세스1</p>
<pre><code class="language-python">
# 값을 파일에 저장하는 코드
def writer(filename, data):

   with open(filename, &#39;w&#39;) as file:
           file.write(data)

book_data = &quot;example&quot;
writer(&quot;book.txt&quot;, book_data)</code></pre>
<p>② 프로세스2</p>
<pre><code class="language-python"># 파일에서 값을 읽어오는 코드
def reader(filename):

with open(filename, &#39;r&#39;) as file:
    data = file.read()
    return data

read_data = reader(&quot;book.txt&quot;)
</code></pre>
<p>위 예제를 보면 두 프로세스는 동시에 실행할 수 있을까?</p>
<p>정답은 X 이다.</p>
<p>프로세스2(reader)는 프로세스1(writer) 실행이 끝나야 실행할 수 있기 때문이다.
즉 프로세스2는 &#39;book.txt안에 값이 존재한다&#39;는 특정 조건이 만족되어야 실행을 이어나갈 수 있다.</p>
<p>이렇게 동시에 실행 되는 프로세스를 올바른 순서로 실행하는 것이 실행 순서 제어를 위한 동기화이다.</p>
<br>

<h2 id="상호-배제를-위한-동기화">상호 배제를 위한 동기화</h2>
<p><code>상호 배제 (mutual exclusion)</code> : 공유가 불가능한 자원의 동시 사용을 피하기 위해 사용하는 알고리즘</p>
<ul>
<li>즉, 특정 한 시점에 단 하나의 프로세스만이 Criticla Section에 접근할 수 있는 것</li>
<li>ex) 공유 자원을 사용하는 A,B스레드가 있을 때 A스레드가 공유 자원을 사용하는 중에 B가 데이터를 변경해버리면 다시 A스레드가 데이터를 읽을 때 올바르게 결과값이 나오지 않을 수 있다.</li>
</ul>
<br>

<h2 id="producer--consumer-problem">Producer &amp; Consumer Problem</h2>
<p>Producer &amp; Consumer Problem (생산자와 소비자 문제) </p>
<pre><code class="language-python">import threading

# 공유 변수
sum = 0


def produce():
    global sum
    for i in range(100000):
            sum += 1

def consume():
    global sum
    for i in range(100000):
            sum -= 1


print(&quot;초기 합계:&quot;, sum)

# 스레드 생성
producer = threading.Thread(target=produce)
consumer = threading.Thread(target=consume)

# 스레드 시작
producer.start()
consumer.start()

# 스레드가 종료할 때까지 대기
producer.join()
consumer.join()


print(&quot;producer, consumer 스레드 실행 이후 합계:&quot;, sum)</code></pre>
<p><a href="https://github.com/kangtegong/self-learning-cs/blob/main/producer_consumer/producer_consumer.cpp">https://github.com/kangtegong/self-learning-cs/blob/main/producer_consumer/producer_consumer.cpp</a> <em>사이트를 참고하여 python 으로 구현한 코드</em></p>
<br>

<p>위 코드는 언뜻 보기에 아무 문제가 없어 보인다.
생산자는 sum이란 공유 변수에 1을 증가시키고, 소비자는 sum이란 공유 변수에 1을 감소시킨다.
그래서 보통은 총합 변수가 계속 0일 것이라고 기대한다.</p>
<p>하지만 이 코드에서는 produce와 consume 함수가 락 또는 다른 동기화 메커니즘 없이 sum을 동시에 수정하므로, 실행 결과가 예측할 수 없다.
race condition이 발생할 사능성이 있으며, 최종 합계가 0이 아닐 수도 있다.</p>
<p><strong>즉 Producer &amp; Consumer Problem는 동시에 접근해서는 안 되는 자원에 동시에 접근했기에 발생한 문제이다</strong></p>
<br>

<h2 id="critical-section-임계-구역">critical section (임계 구역)</h2>
<p><code>critical section (임계 구역)</code> : 공유 데이터의 일관성을 보장하기 위해 하나의 프로세스/스레드만 진입해서 실행 가능한 영역</p>
<br>

<h3 id="critical-section-problem의-해결책이-되기-위한-조건">critical section problem의 해결책이 되기 위한 조건</h3>
<p>① mutual exclusion (상호 배제) 
: 어떤 프로세스가 critical section(CS)에 진입해서 작업을 수행 중이면 다른 모든 프로세스들은 CS에 진입할 수 없다.</p>
<p>② progress (진행)
: CS에 진입한 프로세스가 없고 CS에 진입하려는 프로세스가 있으면, CS 진입을 허용한다.</p>
<p>③ bounded waiting (유한 대기)
: CS에 들어가기 위해서 무한대기 하는 프로세스가 존재하면 안 된다. (starvation 현상)</p>
<p>④ 동일 속도
: 프로세스들의 상대적인 속도에 대해서는 어떠한 가정도 하지 않는다.</p>
<br>

<h2 id="race-condition-경쟁-상태">race condition (경쟁 상태)</h2>
<p><code>race condition (경쟁 상태)</code> : 여러 프로세스/스레드가 동시에 같은 데이터를 조작할 때 타이밍이나 접근 순서에 따라 결과가 달라질 수 있는 상황</p>
<ul>
<li>공유 데이터의 최종 연산 결과는 마지막에 공유 데이터를 다룬 프로세스가 누구인지에 따라 달라진다.</li>
<li>race condition을 막기 위해서는 공유 데이터에 대한 동시 접근을 동기화 해야한다.</li>
</ul>
<br>

<h3 id="race-condition이-발생하는-예">race condition이 발생하는 예</h3>
<p>① 공유 메모리를 사용하는 프로세스 사이에서 발생</p>
<p>② 커널 모드 수행 중 interrupt가 발생하여 인터럽트 처리루틴이 수행되는 경우</p>
<ul>
<li>인터럽트 처리 루틴(Interrupt Service Routine, ISR) ➡ 커널 코드</li>
<li>커널 모드 수행 중 interrupt가 발생하면 커널 영역의 공유 데이터에 동시(중복) 접근이 일어나는 race condition 상황이 발생한다.</li>
</ul>
<p>③ 프로세스가 시스템콜을 하여 커널 모드로 수행중인데 context switch가 일어나는 경우</p>
<ul>
<li>A 프로세스가 시스템 콜을 하여 커널 모드로 수행 중인 상황이다. (커널 영역의 공유 데이터를 처리하고 있다고 가정)</li>
<li>그런데 A 프로세스 작업 중간에 B 프로세스가 CPU를 선점하고, B 프로세스가 시스템 콜을 통해 커널 영역의 공유 데이터에 접근하면 race condition 상황이다.</li>
</ul>
<p>④ Multi-processor에서 shared memory 내의 kernel data에 동시 접근하는 경우</p>
<ul>
<li>해결방법은 한번에 하나의 CPU만 커널에 들어갈 수 있게 하거나</li>
<li>커널 내부에 있는 각 공유 데이터에 접근할 때마다 그 데이터에 대한 lock / unlock을 수행한다.</li>
</ul>
<br>

<h2 id="참고">참고</h2>
<ul>
<li><a href="https://www.youtube.com/watch?v=vp0Gckz3z64">https://www.youtube.com/watch?v=vp0Gckz3z64</a> (쉬운코드 유튜브)</li>
<li>혼자 공부하는 컴퓨터 구조 + 운영체제 (강민철 지음)</li>
<li>[JSCODE] 운영체제 스터디 1기 개념 정리 노트</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[컴퓨터 구조] 컴퓨터가 이해하는 정보 단위 - 명령어]]></title>
            <link>https://velog.io/@cosmos-jj/%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EC%BB%B4%ED%93%A8%ED%84%B0%EA%B0%80-%EC%9D%B4%ED%95%B4%ED%95%98%EB%8A%94-%EC%A0%95%EB%B3%B4-%EB%8B%A8%EC%9C%84-%EB%AA%85%EB%A0%B9%EC%96%B4</link>
            <guid>https://velog.io/@cosmos-jj/%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EC%BB%B4%ED%93%A8%ED%84%B0%EA%B0%80-%EC%9D%B4%ED%95%B4%ED%95%98%EB%8A%94-%EC%A0%95%EB%B3%B4-%EB%8B%A8%EC%9C%84-%EB%AA%85%EB%A0%B9%EC%96%B4</guid>
            <pubDate>Mon, 02 Oct 2023 15:36:35 GMT</pubDate>
            <description><![CDATA[<h2 id="컴퓨터가-이해하는-정보-단위---명령어">컴퓨터가 이해하는 정보 단위 - 명령어</h2>
<p>컴퓨터는 0과 1로 모든 정보를 표현하고, 0과 1로 표현된 정보만을 이해할 수 있다.
그리고 이렇게 0과 1로 표현되는 정보에는 크게 데이터(data)와 명령어(instruction)가 있다.</p>
<p><code>명령어(instruction)</code></p>
<ul>
<li>명령어는 데이터를 움직이고 컴퓨터를 작동시키는 정보</li>
<li>데이터는 명령어를 위해 존재하는 일종의 재료</li>
</ul>
<br>

<h2 id="저급-언어-vs-고급-언어">저급 언어 vs 고급 언어</h2>
<p><img src="https://velog.velcdn.com/images/cosmos-jj/post/7a62ae93-eef0-4cd6-aa73-91c4cd665a39/image.png" alt=""></p>
<h3 id="저급-언어">저급 언어</h3>
<p><code>저급 언어 (low-level programming language)</code> : 컴퓨터가 직접 이해하고 실행할 수 있는 언어</p>
<br>

<p><strong>저급 언어의 종류</strong>
① <code>기계어(machine code)</code> : 0과 1의 명령어 비트로 이루어진 저급 언어
② <code>어셈블리어(assembly language)</code> : 0과 1로 이루어진 기계어를 읽기 편한 형태로 번역한 저급 언어</p>
<br>

<h3 id="고급-언어">고급 언어</h3>
<p><code>고급 언어 (high-level programming language)</code> : 개발자가 이해하기 쉽게 만든 언어</p>
<br>

<p><strong>고급 언어의 종류</strong></p>
<p>① <code>컴파일 언어</code> : 컴파일어에 의해 소스 코드 전체가 저급 언어로 변환되어 실행되는 고급 언어</p>
<pre><code>컴파일(compile) : 컴파일 언어로 작성된 소스코드 전체가 저급 언어로 변환되는 과정
컴파일러(compiler) : 컴파일을 수행해 주는 도구
목적 코드(object code) : 컴파일러를 통해 저급 언어로 변환된 코드</code></pre><ul>
<li>소스 코드 전체가 저급 언어로 변환</li>
<li>소스 코드 내에 오류가 하나라도 있으면 컴파일이 불가능</li>
</ul>
<br>


<p>② <code>인터프리터 언어</code> : 인터프리터에 의해 소스 코드가 한 줄씩 실행되는 고급 언어</p>
<pre><code>인터프리터(interpreter) : 인터프리터 언어로 작성된 소스 코드를 한 줄씩 저급 언어로 변환하여 실행해 주는 도구</code></pre><ul>
<li>소스 코드를 한 줄씩 차례로 실행</li>
<li>소스 코드 N번째 줄에 문법 오류가 있더라도 N-1번째 줄까지는 올바르게 수행</li>
</ul>
<br>

<pre><code>❗ 하나의 프로그래밍 언어가 반드시 둘 중 하나의 방식만으로 작동한다고 생각하는 것은 오개념이다.

❗  예시로 대표적인 인터프리터 언어로 알려진 파이썬도 컴파일을 하지 않는 것은 아니며, 
자바의 경우 저급 언어가 되는 과정에서 컴파일과 일터프리트를 동시에 수행한다.

❗ 고급 언어와 저급 언어를 이해할 때는 고급 언어가 저급 언어로 변환되는 대표적인 방법에는 
컴파일 방식과 인터프리트 방식이 있다고 이해해야 한다.</code></pre><br>

<h2 id="명령어의-구조">명령어의 구조</h2>
<p>명령어 : 연산 코드 + 오퍼랜드</p>
<h3 id="연산-코드와-오퍼랜드">연산 코드와 오퍼랜드</h3>
<p><img src="https://velog.velcdn.com/images/cosmos-jj/post/8a478442-cf51-4ff3-b2bc-ae4cfeb5a30a/image.png" alt="">
<strong>오퍼랜드</strong></p>
<p><code>오퍼랜드 (operand)</code> : 연산에 사용할 데이터 또는 연산에 사용할 데이터가 저장된 위치 (피연산자)</p>
<ul>
<li>오퍼랜드 필드에는 숫자와 문자등을 나타내는 데이터 또는 메모리나 레지스터 주소가 올 수 있다.</li>
<li>오퍼랜드는 명령어 안에 하나도 없을 수도 있고, 여러 개가 있을 수도 있다.</li>
</ul>
<p><code>0-주소 명령어</code> : 오퍼랜드 0개
<code>1-주소 명령어</code> : 오퍼랜드 1개
<code>2-주소 명령어</code> : 오퍼랜드 2개
<code>3-주소 명렁어</code> : 오퍼랜드 3개</p>
<br>

<p><strong>연산 코드</strong></p>
<p><code>연산 코드 (operation)</code> : 명령어가 수행할 연산 (연산자)</p>
<ul>
<li>기본적인 연산 코드 유형 : 데이터 전송/ 산술, 논리 연산/ 제어 흐름 변경/ 입출력 제어</li>
<li>명령어의 종류와 생김새는 CPU마다 다르기 때문에 연산 코드의 종류와 생김새 또한 CPU마다 다르다.</li>
</ul>
<br>

<h3 id="주소-지정-방식">주소 지정 방식</h3>
<p><code>유효 주소(effective address)</code> : 연산의 대상이 되는 데이터가 저장된 위치
<code>주소 지정 방식(addressing mode)</code> : 유효 주소를 찾는 방법</p>
<h4 id="즉시-주소-지정-방식">즉시 주소 지정 방식</h4>
<p><img src="https://velog.velcdn.com/images/cosmos-jj/post/cb02d1f2-84e9-4cb6-8a09-51302925161d/image.png" alt=""></p>
<p><code>즉시 주소 지정 방식(immediate addressing mode)</code> : 연산에 사용할 데이터를 오퍼랜드 필드에 직접 명시하는 방식</p>
<ul>
<li>가장 간단한 형태의 주소 지정 방식</li>
<li>장점 : 연산에 사용할 데이터를 메모리나 레지스터로부터 찾는 과정이 없기 때문에 빠름</li>
<li>단점 : 표현할 수 있는 데이터의 크기가 작아짐</li>
</ul>
<h4 id="직접-주소-지정-방식">직접 주소 지정 방식</h4>
<p><img src="https://velog.velcdn.com/images/cosmos-jj/post/e77ecde8-ea51-4eab-bdd7-8182a00c5ed7/image.png" alt=""></p>
<p><code>직접 주소 지정 방식(direct addressing mode)</code> : 오퍼랜드 필드에 유효 주소를 직접적으로 명시하는 방식</p>
<ul>
<li>데이터 크기는 즉시 주소 지정 방식보다 커짐</li>
<li>여전히 유효 주소를 표현할 수 있는 범위가 연산 코드의 비트 수만큼 줄어듦</li>
</ul>
<br>

<h4 id="간접-주소-지정-방식">간접 주소 지정 방식</h4>
<p><img src="https://velog.velcdn.com/images/cosmos-jj/post/0fac8573-2c90-48b8-b395-75a95702befd/image.png" alt=""></p>
<p><code>간접 주소 지정 방식(indirect addressing mode)</code> : 유효 주소의 주소를 오퍼랜드 필드에 명시하는 방식</p>
<ul>
<li>직접 주소 지정 방식보다 표현할 수 있는 유효 주소의 범위가 더 넓어짐</li>
<li>두 번의 메모리 접근이 필요하기 때문에 일반적으로 느린 방식</li>
</ul>
<br>

<h4 id="레지스터-주소-지정-방식">레지스터 주소 지정 방식</h4>
<p><img src="https://velog.velcdn.com/images/cosmos-jj/post/17f21704-8776-44a5-bae6-5911944c698a/image.png" alt=""></p>
<p><code>레지스터 주소 지정 방식(register addressing mode)</code> : 연산에 사용할 데이터를 저장한 레지스터를 오퍼랜드 필드에 직접 명시하는 방식</p>
<ul>
<li>CPU 외부에 있는 메모리에 접근하는 것보다 CPU 내부에 있는 레지스터에 접근하는 것이 더 빠르기에 레지스터 주소 지정방식은 직접 주소 지정 방식보다 빠르게 데이터에 접근 가능</li>
<li>직접 주소 지정 방식과 비슷하게 표현할 수 있는 레지스터 크기에 제한이 생길 수 있음</li>
</ul>
<br>

<h4 id="레지스터-간접-주소-지정-방식">레지스터 간접 주소 지정 방식</h4>
<p><img src="https://velog.velcdn.com/images/cosmos-jj/post/ca746326-5caf-4ffb-b0f1-3391e42c254d/image.png" alt=""></p>
<p><code>레지스터 간접 주소 지정 방식(register indirect addressing mode)</code> : 연산에 사용할 데이터를 메모리에 저장하고 그 유효 주소를 저장한 레지스터를 오퍼랜드 필드에 명시하는 방법</p>
<ul>
<li>유효 주소를 찾는 과정이 간접 주소 지정 방식과 비슷하지만, 메모리에 접근하는 횟수가 한 번으로 줄어듦</li>
<li>레지스터 간접 주소 지정 방식은 간접 주소 지정 방식보다 빠름</li>
</ul>
<br>

<h2 id="스택과-큐">스택과 큐</h2>
<h3 id="스택">스택</h3>
<p><code>스택(stack)</code> : 한쪽 끝이 막혀 있는 통과 같은 저장 공간</p>
<ul>
<li>나중에 저장한 데이터를 가장 먼저 빼내는 데이터 관리 방식(후입선출) ➡ <code>LIFO(Last In First Out)</code></li>
</ul>
<h3 id="큐">큐</h3>
<p><code>큐(queue)</code> : 스택과는 달리 양쪽이 뚫려 있는 통과 같은 저장 공간</p>
<ul>
<li>가장 먼저 저장된 데이터부터 빼내는 데이터 관리 방식(선입선출) ➡ <code>FIFO(First In First Out)</code></li>
</ul>
<h2 id="참고">참고</h2>
<ul>
<li>혼자 공부하는 컴퓨터 구조 + 운영체제 (강민철 지음)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[컴퓨터 구조] 컴퓨터가 이해하는 정보 단위 - 데이터]]></title>
            <link>https://velog.io/@cosmos-jj/%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EC%BB%B4%ED%93%A8%ED%84%B0%EA%B0%80-%EC%9D%B4%ED%95%B4%ED%95%98%EB%8A%94-%EC%A0%95%EB%B3%B4-%EB%8B%A8%EC%9C%84-%EB%8D%B0%EC%9D%B4%ED%84%B0</link>
            <guid>https://velog.io/@cosmos-jj/%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EC%BB%B4%ED%93%A8%ED%84%B0%EA%B0%80-%EC%9D%B4%ED%95%B4%ED%95%98%EB%8A%94-%EC%A0%95%EB%B3%B4-%EB%8B%A8%EC%9C%84-%EB%8D%B0%EC%9D%B4%ED%84%B0</guid>
            <pubDate>Mon, 02 Oct 2023 09:35:54 GMT</pubDate>
            <description><![CDATA[<h2 id="컴퓨터가-이해하는-정보-단위---데이터">컴퓨터가 이해하는 정보 단위 - 데이터</h2>
<p>컴퓨터는 0과 1로 모든 정보를 표현하고, 0과 1로 표현된 정보만을 이해할 수 있다.
그리고 이렇게 0과 1로 표현되는 정보에는 크게 <code>데이터(data)</code>와 <code>명령어(instruction)</code>가 있다.</p>
<p><code>데이터</code> </p>
<ul>
<li>컴퓨터가 이해하는 숫자, 문자, 이미지, 동영상과 같은 정적인 정보 </li>
<li>컴퓨터와 주고받는 정보나 컴퓨터에 저장된 정보를 가리킬 때 통칭하는 말</li>
</ul>
<br>

<h3 id="정보-단위">정보 단위</h3>
<p><code>비트(bit)</code> : 0과 1을 나타내는 가장 작은 정보 단위</p>
<p>⬇ 프로그램의 크기를 말할 때 사용하는 표현⬇ 
<code>바이트(byte)</code> == 8비트
<code>1 킬로바이트(kB)</code> == 1,000바이트
<code>1 메가바이트(MB)</code> == 1,000킬로바이트
<code>1 기가바이트(GB)</code> == 1,000메가바이트
<code>1 테라바이트(TB)</code> == 1,000기가바이트</p>
<br>
<br>

<p><code>워드(word)</code> : CPU가 한 번에 처리할 수 있는 데이터 크기 
⬇
<code>하프 워드(half word)</code> : 워드의 절반크기
<code>풀 워드(full word)</code> : 워드의 1배 크기
<code>더블 워드(double word)</code> : 워드의 2배 크기</p>
<br>

<h3 id="0과-1을-숫자로-표현하는-방법">0과 1을 숫자로 표현하는 방법</h3>
<h4 id="이진법binary">이진법(binary)</h4>
<ul>
<li>0과 1만으로 모든 숫자를 표현하는 방법</li>
</ul>
<p><span style="background-color:#fff5b1">표기 방법</span>
① ex) 1000<strong>(2)</strong>
② ex) <strong>0b</strong>1000</p>
<br>

<p><span style="background-color:#fff5b1">음수 표현</span></p>
<ul>
<li>2의 보수(two&#39;s complement)를 구해 이 값을 음수로 간주
① 사전적 의미 : 어떤 수를 그보다 큰 2ⁿ에서 뺀 값
② 쉽게 풀기 : 모든 0과 1을 뒤집고, 거기에 1을 더한 값</li>
</ul>
<pre><code>❗ 1의 보수 : 모든 이진수의 1과 0을 뒤집은 수 
❗ 2의 보수 : 1의 보수에 1을 더한 값
❗ 플래그(flag) : 컴퓨터 내부에서 이 수가 양수인지 음수인지를 구분하기 위해 사용하는 것</code></pre><br>

<p><span style="background-color:#fff5b1">2의 보수 표현의 한계</span></p>
<ul>
<li>0이나 2ⁿ형태의 이진수에 2의 보수를 취하면 원하는 음수값을 얻을 수 없다.</li>
</ul>
<pre><code>0을 음수로 표현하기

0000 ➡(모든 수 뒤집기) 1111 ➡(1을 더하기) 10000

❗ 이런 경우 자리 올림이 발생한 비트의 1을 버린다.
</code></pre><pre><code>2³을 음수로 표현하기

1000 ➡(모든 수 뒤집기) 0111 ➡(1을 더하기) 1000

❗ 이런 경우 음수가 자기 자신의 되버리는 경우는 본질적으로 해결하기 힘들다.
❗ 즉, n비트로틑 -2ⁿ과 2ⁿ을 동시에 표현할 수 없다.</code></pre><br>

<h4 id="십육진법hexadecimal">십육진법(hexadecimal)</h4>
<ul>
<li>수가 15를 넘어가는 시점에 자리 올림하여 수를 표현하는 방법</li>
</ul>
<p><span style="background-color:#fff5b1">표기 방법</span>
① 수학적 표기 방식 : 15<strong>(16)</strong>
② 코드상 표기 방식 : <strong>0x</strong>15</p>
<br>

<p><span style="background-color:#fff5b1">십육진수를 이진수로 변환</span></p>
<p>ex) 1A2B</p>
<pre><code>⬇각 자리를 이진수로 변환⬇
- 1 == 0001(2)
- A == 1010(2)
- 2 == 0010(2)
- B == 1011(2)

즉 1A2B(16) = 0001101000101011(2)</code></pre><br>

<h3 id="0과-1을-문자로-표현하는-방법">0과 1을 문자로 표현하는 방법</h3>
<p><code>문자 집합(character set)</code> : 컴퓨터가 인식하고 표현할 수 있는 문자의 모음
<code>문자 인코딩(character encoding)</code> : 문자를 0과 1로 변환하는 과정
<code>문자 디코딩(character decoding)</code> : 0과1로 이루어진 문자 코드를 문자로 변환하는 과정</p>
<h4 id="아스키-코드">아스키 코드</h4>
<ul>
<li>초창기 문자 집합 중 하나</li>
<li>알파벳, 아라비아 숫자, 일부 특수 문자 및 제어 문자 표현 가능</li>
<li>코드 포인트(문자를 부여된 값) 사용</li>
<li>7비트로 하나의 문자 표현<ul>
<li>8비트 중 1비트는 오류 검출을 위해 사용되는 패리티 비트(parity bit)    </li>
</ul>
</li>
<li>장점 : 간단한 인코딩</li>
<li>단점 : 한글을 포함한 다른 언어 문자, 다양한 특수 문자 표현 불가<ul>
<li>128개보다 많은 문자를 표현할 수 없음</li>
<li>8비트인 확장 아스키가 등장하였지만 여전히 부족</li>
</ul>
</li>
</ul>
<br>

<h4 id="euc-kr">EUC-KR</h4>
<p>한글 인코딩 : 완성형 vs 조합형 인코딩
①완성형 : 홍 + 길 + 동
②조합형 : ㅎ + ㅗ + ㅇ</p>
<p>EUC-KR</p>
<ul>
<li>완성형 인코딩</li>
<li>한 글자에 2바이트 크기의 코드 부여</li>
<li>2바이트 == 16비트</li>
<li>2300여 개의 한글 표현 가능</li>
<li>EUC-KR 확장형 -&gt; 마이크로소프트의 CP949 (Code Page 949)</li>
<li>문제점 : 언어별 인코딩을 국가마다 하게 되면 다국어를 지원하는 프로그램을 개발할 때엔 언어별 인코딩 방식을 모두 이해해야 함</li>
</ul>
<br>

<h4 id="유니코드와-utf-8">유니코드와 UTF-8</h4>
<p><span style="background-color:#fff5b1">유니코드</span></p>
<ul>
<li>통일된 문자 집합</li>
<li>한글, 영여, 화살표와 같은 특수 문자, 심지어 이모티콘까지 표현 가능</li>
<li>현대 문자 표현에 있어 매우 중요한 위치</li>
<li>유니코드의 인코딩 방식 : UTF-8, UTF-16, UTF-32∙∙∙</li>
</ul>
<p><span style="background-color:#fff5b1">UTF-8 인코딩</span></p>
<ul>
<li>가장 대중적으로 사용</li>
<li>UTF(Unicode Transformation Format) == 유니코드 인코딩 방법</li>
<li>가변길이 인코딩 : 인코딩 결과가 1바이트 ~ 4바이트</li>
<li>인코딩 결과가 몇 바이트가 될지는 유니코드에 부여된 값에 따라 다름</li>
</ul>
<br>

<h2 id="참고">참고</h2>
<ul>
<li>혼자 공부하는 컴퓨터 구조 + 운영체제 (강민철 지음)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[3회차] 운영체제 모의면접 스터디 대비]]></title>
            <link>https://velog.io/@cosmos-jj/3%ED%9A%8C%EC%B0%A8-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%AA%A8%EC%9D%98%EB%A9%B4%EC%A0%91-%EC%8A%A4%ED%84%B0%EB%94%94-%EB%8C%80%EB%B9%84</link>
            <guid>https://velog.io/@cosmos-jj/3%ED%9A%8C%EC%B0%A8-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%AA%A8%EC%9D%98%EB%A9%B4%EC%A0%91-%EC%8A%A4%ED%84%B0%EB%94%94-%EB%8C%80%EB%B9%84</guid>
            <pubDate>Thu, 28 Sep 2023 11:18:32 GMT</pubDate>
            <description><![CDATA[<p>❓ 기아 상태가 무엇인가요?</p>
<p>💭 우선순위가 낮은 프로세스들이 우선순위가 높은 프로세스들에 의해 실행이 계속해서 연기되는 현상입니다.</p>
<hr>
<p>❓ 기아 상태를 어떻게 해결할 수 있나요?</p>
<p>💭 기아 상태를 방지하기 위한 기법으로 에이징이 있습니다. 에이징은 오랫동안 대기한 프로세스의 우선순위를 점차 높이는 방식입니다.</p>
<hr>
<p>❓ CPU 스케줄링이란 무엇인가요?</p>
<p>💭 CPU 스케줄링은 운영체제가 프로세스들에게 공정하고 합리적으로 CPU 자원을 배분하는 것입니다.</p>
<hr>
<p>❓ 스케줄러의 종류는 무엇이 있나요?</p>
<p>💭 장기 스케줄러, 중기 스케줄러, 단기 스케줄러가 있습니다. 장기 스케줄러는 작업 스케줄러라고도 부르며 프로세스를 준비큐에 삽입할지 결정하는 역할을 합니다. 중기 스케줄러는 메모리에 적재된 프로세스의 수를 조절하는 역할합니다.(=스와핑) 단기 스케줄러는 CPU스케줄러라고도 부르며 준비 상태에 있는 작업 중 실행할 프로세스를 선택하여 CPU를 할당합니다.</p>
<hr>
<p>❓ 선점형 스케줄링과 비선점형 스케줄링의 차이가 무엇인가요?</p>
<p>💭 선점형 스케줄링은 프로세스가 자원을 사용하고 있을 때 다른 프로세스가 해당 자원을 빼앗을 수 있지만 비선점형은 빼앗을 수 없습니다.</p>
<hr>
<p>❓ 선입선출 스케줄링(FCFS)란 무엇인가요?</p>
<p>💭 준비 큐에 삽입된 순서대로 프로세스를 처리하는 비선점형 스케줄링 방식입니다. FCFS 스케줄링은 호위 효과가 발생할 수 있다는 문제가 있습니다.</p>
<ul>
<li>호위 효과(convoy effect) : 모든 다른 프로세스들이 하나의 긴 프로세스가 CPU를 양도하기를 기다리는 것</li>
</ul>
<hr>
<p>❓ 최단 작업 우선 스케줄링(SJF)란 무엇인가요?</p>
<p>💭 준비 큐에 삽입된 프로세스들 중 CPU이용시간의 길이가 가장 짧은 프로세스부터 실행하는 스케줄링 방식입니다. 짧은 작업을 먼저 실행하기때문에 평균 대기 시간이 짧지만 실행시간을 예측하기 어려워 실용적이지 못하고 짧은 작업이 항상 먼저 실행되기 때문에 기아 상태가 발생한다는 단점이 있습니다.</p>
<hr>
<p>❓ 최소 잔류 시간 우선 스케줄링(SRTF)란 무엇인가요?</p>
<p>💭 최단 작업 우선 스케줄링 알고리즘과 라운드 로빈 알고리즘을 합친 스케줄링 방식으로 프로세스들은 정해진 타임 슬라이스만큼 CPU를 사용하되, 사용할 다음 프로세스로는 남아있는 작업 시간이 가장 적은 프로세스가 선택되는 스케줄링입니다. 최소 잔류 시간 우선 스케줄링은 선점형 SJF 스케줄링이라고도 불립니다.</p>
<hr>
<p>❓ 우선순위 스케줄링이란 무엇인가요?</p>
<p>💭 프로세스들에 우선순위를 부여하고, 가장 높은 우선순위들을 가진 프로세스부터 실행하는 스케줄링 알고리즘입니다. 우선순위 스케줄링은 기아현상이 발생한다는 근본적인 문제를 가지고있습니다.</p>
<hr>
<p>❓ 라운드 로빈 스케줄링이란 무엇인가요?</p>
<p>💭 정해진 타임 슬라이스만큼의 시간 동안 돌아가며 CPU를 이용하는 선점형 스케줄링 방식입니다. 프로세스들은 정해진 시간만큼만 CPU를 이용하고, 정해진 시간을 모두 사용하였음에도 프로세스가 완료되지 않았다면 다시 큐의 맨 뒤에 삽입됩니다. </p>
<p>라운드 로빈 스케줄링에서 타임 슬라이스가 지나치게 크면 선입 선처리 스케줄링과 같이 호위효과가 생길 여지가 있습니다.</p>
<hr>
<p>❓ 멀티 레벨 큐 스케줄링이란 무엇인가요?</p>
<p>💭 우선순위별로 준비 큐를 여러 개 사용하는 스케줄링 방식입니다. 우선순위가 가장 높은 큐에 있는 프로세스들을 먼저 처리하고, 우선순위가 가장 높은 큐가 비어있으면 그 다음 우선순위 큐에 있는 프로세스를 처리합니다. 큐마다 다른 스케줄링 알고리즘을 사용할 수 있고 프로세스들은 큐 사이를 이동할 수 없습니다.</p>
<hr>
<p>❓  멀티 레벨 피드백 큐 스케줄링이란 무엇인가요?</p>
<p>💭 다단계 큐 스케줄링에 프로세스들이 큐 사이를 이동할 수 있게한 스케줄링입니다. 멀티 레벨 피드백 큐 스케줄링에서 CPU집중 프로세스들은 자연스레 우선순위가 낮아지고, 입출력 집중 프로세스들은 우선순위가 높은 쿠에서 실행이 끝나게 됩니다. 또한 큐 사이를 이동할 수 있기에 에이징 기법을 적용하여 기아 현상을 예방할 수 있습니다.</p>
]]></description>
        </item>
    </channel>
</rss>