<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Tech Log</title>
    <link>https://hapen385.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Mon, 20 Jul 2026 08:33:47 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>yuhee kim</managingEditor>
    <image>
      <title>Tech Log</title>
      <url>https://tistory1.daumcdn.net/tistory/4640914/attach/683f00f85e2d4073a7010b61c7434aa4</url>
      <link>https://hapen385.tistory.com</link>
    </image>
    <item>
      <title>[Design Pattern] Observer Pattern</title>
      <link>https://hapen385.tistory.com/73</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. Observer Pattern이란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주체가 어떤 객체(subject)의 상태 변화를 관찰하다가,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; 상태 변화가 있을 때마다&lt;/b&gt; 메소드 등을 통해 옵저버들에게 &lt;b&gt;변화를 알려주는&lt;/b&gt; 디자인 패턴.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 0.jpg&quot; data-origin-width=&quot;867&quot; data-origin-height=&quot;918&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjRIYE/btr6OV0v3wf/LKqGAVozXppRXDgtCfnOO1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjRIYE/btr6OV0v3wf/LKqGAVozXppRXDgtCfnOO1/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjRIYE/btr6OV0v3wf/LKqGAVozXppRXDgtCfnOO1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjRIYE%2Fbtr6OV0v3wf%2FLKqGAVozXppRXDgtCfnOO1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;316&quot; height=&quot;335&quot; data-filename=&quot;DataBase - 0.jpg&quot; data-origin-width=&quot;867&quot; data-origin-height=&quot;918&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주체는 객체의 상태 변화를 보고 있는 관찰자를 말한다.&lt;br /&gt;옵저버들은 객체의 상태 변화에 따라 전달되는 메소드, &lt;b&gt;이벤트 등을 기반으로&lt;/b&gt; &lt;b&gt;추가 변화 사항이 생기는 객체들&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 1.jpg&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;966&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ciPkXh/btr61htDAN9/vIRiMy4VMdnRk1F4USGkKK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ciPkXh/btr61htDAN9/vIRiMy4VMdnRk1F4USGkKK/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ciPkXh/btr61htDAN9/vIRiMy4VMdnRk1F4USGkKK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FciPkXh%2Fbtr61htDAN9%2FvIRiMy4VMdnRk1F4USGkKK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;315&quot; height=&quot;404&quot; data-filename=&quot;DataBase - 1.jpg&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;966&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 주체와 객체를 분리하지 않고 상태가 변경되는 객체만을 기반으로 옵저버 패턴을 적용하기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 2.jpg&quot; data-origin-width=&quot;1359&quot; data-origin-height=&quot;598&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LJgYA/btr61lvZvXk/zMas4pQs3IyUQeFXYcA4Yk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LJgYA/btr61lvZvXk/zMas4pQs3IyUQeFXYcA4Yk/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LJgYA/btr61lvZvXk/zMas4pQs3IyUQeFXYcA4Yk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLJgYA%2Fbtr61lvZvXk%2FzMas4pQs3IyUQeFXYcA4Yk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;621&quot; height=&quot;273&quot; data-filename=&quot;DataBase - 2.jpg&quot; data-origin-width=&quot;1359&quot; data-origin-height=&quot;598&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;옵저버 패턴의 원리가 적용된 서비스 중에는 트위터가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팔로워들은 주체가 새로운 트윗을 올리면 알림을 받게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 예시&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;kotlin으로 작성한 옵저버 패턴 예시는 다음과 같다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1680190815305&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;interface Observer {
    fun update()
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1680190845879&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;interface Observable {
    val observers: ArrayList&amp;lt;Observer&amp;gt;

    fun add(observer: Observer) {
        observers.add(observer)
    }

    fun remove(observer: Observer) {
        observers.remove(observer)
    }

    fun sendUpdateEvent() {
        observers.forEach { it.update() }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1680191378806&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Note : Observable {
    override val observers: ArrayList&amp;lt;Observer&amp;gt; = ArrayList()
    var memo = &quot;&quot;
        set(value) {
            field = value
            sendUpdateEvent()
        }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Observer 인터페이스의 update 메소드는 Observer 객체가 변경될 때마다 호출된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Observable의 sendUpdateEvent 메소드는 모든 옵저버들에게 객체가 변경되었다고 알리는 역할을 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1680192028450&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fun main() {
    val note = Note()
    note.memo = &quot;abcd&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 Note 객체의 memo의 값이 변경되면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sendUpdateEvent 메소드가 호출될 것이며&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Note 객체의 옵저버들은 변경이 되었다는 알림을 받게 될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 안드로이드에서의 Observer Pattern&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Coroutine Flow의 collect&lt;/li&gt;
&lt;li&gt;LiveData Observer&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.baeldung.com/kotlin/observer-pattern&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Baeldung&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Design Pattern</category>
      <category>coroutine</category>
      <category>flow</category>
      <category>livedata</category>
      <category>Observer</category>
      <category>observer pattern</category>
      <category>디자인 패턴</category>
      <category>안드로이드 개발</category>
      <category>안드로이드 디자인 패턴</category>
      <category>옵저버</category>
      <category>옵저버 패턴</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/73</guid>
      <comments>https://hapen385.tistory.com/73#entry73comment</comments>
      <pubDate>Fri, 31 Mar 2023 08:00:18 +0900</pubDate>
    </item>
    <item>
      <title>[Design Pattern] Repository Pattern</title>
      <link>https://hapen385.tistory.com/72</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트를 하면서 Repository Pattern을 사용해보았고, 데이터 레이어를 분리하였을 때 다른 이점이 더 있을까 궁금하여 조사해보았다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;해당 글은 안드로이드 플랫폼을 기준으로 기술하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;1. Repository Pattern이란?&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;9e528301efd49aea_856.png&quot; data-origin-width=&quot;856&quot; data-origin-height=&quot;764&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A1lnV/btr6NkThDrB/OOoowsKGcHVK73qL6Dxzkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A1lnV/btr6NkThDrB/OOoowsKGcHVK73qL6Dxzkk/img.png&quot; data-alt=&quot;출처 :&amp;amp;nbsp;https://developer.android.com/codelabs/basic-android-kotlin-training-repository-pattern?hl=ko#3&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A1lnV/btr6NkThDrB/OOoowsKGcHVK73qL6Dxzkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA1lnV%2Fbtr6NkThDrB%2FOOoowsKGcHVK73qL6Dxzkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;448&quot; height=&quot;400&quot; data-filename=&quot;9e528301efd49aea_856.png&quot; data-origin-width=&quot;856&quot; data-origin-height=&quot;764&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;nbsp;https://developer.android.com/codelabs/basic-android-kotlin-training-repository-pattern?hl=ko#3&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;데이터 레이어를 분리하는 디자인 패턴이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;데이터 레이어에는 네트워킹 코드, Room 데이터베이스와 같이 데이터와 관련된 코드들이 들어간다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;UI 부분과는 분리되어 데이터와 비즈니스 로직이 들어간다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;69021c8142d29198_856.png&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;645&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oUWsT/btr6JpghxzB/MBFnhWzvfApkPySHHTXsjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oUWsT/btr6JpghxzB/MBFnhWzvfApkPySHHTXsjK/img.png&quot; data-alt=&quot;출처 :&amp;amp;nbsp;https://developer.android.com/codelabs/basic-android-kotlin-training-repository-pattern?hl=ko#3&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oUWsT/btr6JpghxzB/MBFnhWzvfApkPySHHTXsjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoUWsT%2Fbtr6JpghxzB%2FMBFnhWzvfApkPySHHTXsjK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;506&quot; height=&quot;446&quot; data-filename=&quot;69021c8142d29198_856.png&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;645&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;nbsp;https://developer.android.com/codelabs/basic-android-kotlin-training-repository-pattern?hl=ko#3&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;안드로이드는 위 그림과 같이 Repository 패턴을 적용하고 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Remote Data Source와 Local Data Source를 추상화하여 중앙 집중 처리 방식을 구현하였다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이 덕분에 데이터를 사용하는 곳(ViewModel)에서 비즈니스 로직(Repository)에만 집중할 수 있도록 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;정보를 은닉하여 코드 변경이 쉬워지도록 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;* &lt;b&gt;비즈니스 로직&lt;/b&gt; : 프로그램의 핵심 로직으로, 어떻게 데이터가 생성되고 수정되고 저장되는 것인지를 정의한 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;2. 사용 효과&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터를 호출하는 코드(ViewModel)에서 오직 비즈니스 로직에만 집중할 수 있도록 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewModel에서는 Repository를 참조하여 데이터를 활용하기만 하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 어디서 얻어야 하는지,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떻게 얻어야 하는지,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 가공해야 하는지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;와 같은 것들을 ViewModel에서 생각하지 않아도 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 Repository의 데이터를 이용하기만 하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 코드를 쉽게 유지 보수할 수 있게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 ViewModel에서는 다음과 같은 것들을 생각해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 얻는데 오래 걸릴 수도 있고 아닐 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 검색에 실패할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이와 같은 것들은 ViewModel에서 고려해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;테스트에 용이해진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 간 모듈화가 진행되어 테스트에 유리한 환경이 만들어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비즈니스 로직을 변경하기 쉬워진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 코드가 Repository에 있기 때문에 ViewModel을 변경하지 않아도 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 SQLite와 같은 로컬 데이터를 사용하고 있다가, RDBMS로 마이그레이션하는 경우 쉽게 변경할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;3. 단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모듈화가 더 진행되기 때문에 관리해야 할 코드가 늘어난다. 복잡해진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.android.com/codelabs/basic-android-kotlin-training-repository-pattern?hl=ko#3&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Android Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://qiita.com/kilalabu/items/a9c993d18b2ab44d7850&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Qiita(【Android】Repositoryの役割・メリットを考えてみる)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jcchu.medium.com/repository-pattern%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0-c86407d487cf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;medium(Repository Pattern에 대해 알아보기)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-logly-title=&quot;true&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Design Pattern</category>
      <category>Design Pattern</category>
      <category>Repository Pattern</category>
      <category>관심사 분리</category>
      <category>디자인 패턴</category>
      <category>모듈화</category>
      <category>비즈니스 로직 분리</category>
      <category>안드로이드 개발</category>
      <category>안드로이드 디자인 패턴</category>
      <category>안드로이드 테스트</category>
      <category>저장소 패턴</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/72</guid>
      <comments>https://hapen385.tistory.com/72#entry72comment</comments>
      <pubDate>Thu, 30 Mar 2023 08:00:50 +0900</pubDate>
    </item>
    <item>
      <title>[Design Pattern] 의존성 주입(Dependency Injection)</title>
      <link>https://hapen385.tistory.com/71</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 의존성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;종속성이라고도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;B의 변경 사항에 대해 A 또한 변해야 한다면, &lt;span&gt;A가 B에 의존성이 있다는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;B가 바뀌면 A도 바뀌는 것이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 의존성 주입&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 0.jpg&quot; data-origin-width=&quot;1258&quot; data-origin-height=&quot;748&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vVvH6/btr6NwSbdmy/LmElhSqoSlIIzi3BqlvaQ0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vVvH6/btr6NwSbdmy/LmElhSqoSlIIzi3BqlvaQ0/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vVvH6/btr6NwSbdmy/LmElhSqoSlIIzi3BqlvaQ0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvVvH6%2Fbtr6NwSbdmy%2FLmElhSqoSlIIzi3BqlvaQ0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;510&quot; height=&quot;303&quot; data-filename=&quot;DataBase - 0.jpg&quot; data-origin-width=&quot;1258&quot; data-origin-height=&quot;748&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림처럼 메인 모듈이 직접 하위 모듈에 대한 의존성을 주는 것이 의존성 주입을 적용하지 않는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의존성 주입을 적용한다면, 메인 모듈이 &lt;b&gt;직접&lt;/b&gt; 의존성을 주는 것이 아니라 &lt;b&gt;간접&lt;/b&gt;적으로 주게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중간에 &lt;b&gt;의존성 주입자(dependency injector)&lt;/b&gt;가 의존성 주는 부분을 가로채서 메인 모듈 대신 의존성을 주입하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 결과 메인 모듈과 하위 모듈은 디커플링 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*디커플링(decoupling) : 모듈 간 의존성을 최소화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의존성 주입 시에는 상위 모듈은 하위 모듈에서 어떠한 것도 가져오지 않아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 상위 모듈과 하위 모듈 모두 추상화에 의존해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추상화는 세부 사항에 의존하지 않아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 장점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의존성 주입을 적용하게 되면 다음과 같은 다양한 장점들이 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모듈들을 쉽게 교체할 수 있게 된다.&lt;/li&gt;
&lt;li&gt;테스팅하기 쉬워진다.&lt;/li&gt;
&lt;li&gt;마이그레이션이 쉬워진다.&lt;/li&gt;
&lt;li&gt;의존성 방향이 일관되어 애플리케이션을 쉽게 추론할 수 있게 된다(구현 시 추상화 레이어를 넣고 이를 기반으로 구현체를 넣기 때문)&lt;/li&gt;
&lt;li&gt;모듈 간의 관계들이 명확해진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 단점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 다음과 같은 단점을 만들어내기도 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모듈이 더욱 분리되어 복잡성이 증가한다.&lt;/li&gt;
&lt;li&gt;복잡성으로 인한 런타임 페널티가 생긴다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Design Pattern</category>
      <category>Dependency Injection</category>
      <category>Di</category>
      <category>MVC</category>
      <category>MVP</category>
      <category>MVVM</category>
      <category>디자인패턴</category>
      <category>모듈화</category>
      <category>안드로이드 개발</category>
      <category>안드로이드 모듈화</category>
      <category>의존성주입</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/71</guid>
      <comments>https://hapen385.tistory.com/71#entry71comment</comments>
      <pubDate>Wed, 29 Mar 2023 14:00:07 +0900</pubDate>
    </item>
    <item>
      <title>[Android] Context</title>
      <link>https://hapen385.tistory.com/70</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;touchicon-180.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OnQwA/btr6ouODoo6/K5gmuvoWxRBbMKGiNZe8Ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OnQwA/btr6ouODoo6/K5gmuvoWxRBbMKGiNZe8Ck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OnQwA/btr6ouODoo6/K5gmuvoWxRBbMKGiNZe8Ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOnQwA%2Fbtr6ouODoo6%2FK5gmuvoWxRBbMKGiNZe8Ck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;180&quot; height=&quot;180&quot; data-filename=&quot;touchicon-180.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;1. Context란?&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Context라는 단어 자체를 번역하면 문맥이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문맥은 논리적인 흐름을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Context는 애플리케이션의 논리적인 흐름이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애플리케이션의 현재 상태를 나타내며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애플리케이션 환경에 대한 전반적인 정보를 담고 있는 클래스다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리소스에 접근할 수 있도록 도와준다.&lt;/li&gt;
&lt;li&gt;브로드캐스트 리시버, Intent와 같이 메시지를 주고받으며 다른 안드로이드 컴포넌트와 상호작용할 때 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Context를 잘못사용하면 메모리 누수를 유발하므로 Context를 제대로 이해하고 사용해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;2. Context의 종류&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Context는 주로 두 가지로 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Activity Context, Application Context로 나뉜다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Activity Context&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Activity Context는 Activity의 생명주기와 관련되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; Activity의 생명주기와 관련된 object를 생성할 때 필요할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Activity 내에서만 사용이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Activity가 소멸하면 해당 Activity Context도 소멸한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Activity Context가 사용되는 경우는 대표적으로 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리소스 값을 불러올 때&lt;/li&gt;
&lt;li&gt;Toast 메시지를 띄울 때&lt;/li&gt;
&lt;li&gt;Activity를 시작할 때&lt;/li&gt;
&lt;li&gt;Layout Inflation&lt;/li&gt;
&lt;li&gt;서비스를 시작할 때&lt;/li&gt;
&lt;li&gt;브로드캐스트 메시지를 전송할 때&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Application Context&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애플리케이션의 생명주기와 관련되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애플리케이션이 실행되어 종료될 때까지 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Activity scope를 벗어난 작업일 때 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주로 싱글톤으로 구현할 때 사용이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Application Context가 사용되는 경우는 대표적으로 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리소스 값을 불러올 때&lt;/li&gt;
&lt;li&gt;서비스를 사용할 때&lt;/li&gt;
&lt;li&gt;브로드캐스트 메시지를 전송할 때&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.android.com/reference/android/content/Context&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Android Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://velog.io/@haero_kim/Android-Context-%EB%84%88-%EB%8C%80%EC%B2%B4-%EB%AD%90%EC%95%BC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;해로,&amp;nbsp;HAERO,&amp;nbsp;海路&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.geeksforgeeks.org/what-is-context-in-android/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;geeksforgeeks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Android/etc</category>
      <category>Android</category>
      <category>Android context</category>
      <category>android 개발</category>
      <category>context</category>
      <category>모바일 개발</category>
      <category>안드로이드</category>
      <category>안드로이드 context</category>
      <category>안드로이드 리소스 사용</category>
      <category>앱 개발</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/70</guid>
      <comments>https://hapen385.tistory.com/70#entry70comment</comments>
      <pubDate>Tue, 28 Mar 2023 08:00:11 +0900</pubDate>
    </item>
    <item>
      <title>[Android] SharedPreferences와 싱글톤 패턴</title>
      <link>https://hapen385.tistory.com/69</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트에서 안드로이드 SharedPreferences를 사용할 일이 많아서 종종 사용했었는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부끄럽지만 SharedPreferences를 싱글톤으로 사용한다는 것을 최근에 깨달았다 ...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금이라도 싱글톤으로 사용하는 이유를 정리해보려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;touchicon-180.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTVap7/btr5R0HC10S/CqM1B1PEk7R67lWtn0IF31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTVap7/btr5R0HC10S/CqM1B1PEk7R67lWtn0IF31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTVap7/btr5R0HC10S/CqM1B1PEk7R67lWtn0IF31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTVap7%2Fbtr5R0HC10S%2FCqM1B1PEk7R67lWtn0IF31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;180&quot; height=&quot;180&quot; data-filename=&quot;touchicon-180.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;1. SharedPreferences를 싱글톤으로 사용하는 이유&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;메모리 낭비를 줄이기 위함&lt;/b&gt; : 매번 SharedPreferences 객체를 만들어서 메모리를 낭비하는 것보다 효율적으로 사용할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;중복되는 데이터 저장 방지&lt;/b&gt; : 여러 곳에서 SharedPreferences의 데이터에 접근하여 데이터를 저장한다면, 동일한 데이터가 중복으로 저장될 수 있다. 이를 방지하기 위해 싱글톤으로 사용한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;코드 중복 방지&lt;/b&gt; : SharedPreferences 객체를 생성하는 코드를 매번 작성하지 않아도 되어 코드 중복 작성을 방지할 수 있도록 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SharedPreferences는 앱의 전역에서 사용되는 경우가 많으므로 싱글톤으로 생성하여 관리하는 것이 낫다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱의 전역에서 사용하는데 싱글톤으로 생성하지 않는다면, 위에서 나타난 문제들을 야기할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;2. 싱글톤으로 사용 방법&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1679843466860&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Preferences(context: Context) {
    private val prefs = context.getSharedPreferences(&quot;pref_name&quot;, Context.MODE_PRIVATE)

    fun getString(key: String, defValue: String): String {
        return prefs.getString(key, defValue).toString()
    }

    fun setString(key: String, value: String) {
        prefs.edit().putString(key, value).apply()

    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SharedPreferences 객체와 SharedPreferences 데이터 사용 메소드를 위한 클래스를 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메소드는 SharedPreferences 데이터를 저장하고 가져올 수 있도록 메소드를 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1679843496127&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class MyApplication : Application() {

    companion object{
        lateinit var prefsManager : Preferences
    }

    override fun onCreate() {
	prefsManager = Preferences(applicationContext)
        super.onCreate()
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SharedPreferences를 Activity보다 먼저 생성해야 다른 곳에 데이터를 넘겨줄 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러므로 애플리케이션이 생성될 때 SharedPreferences를 생성해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 위해 SharedPreferences를 Application 클래스로 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SharedPreferences를 companion object를 통해 싱글톤으로 생성하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;onCreate() 메소드가 호출되기 전 SharedPreferences 객체를 초기화해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초기화시, Application Context를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 SharedPreferences는 전역에서 사용하므로, Application Context를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 SharedPreferences를 전역에서 사용하지 않고 한 Activity에서 사용한다면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연하지만 싱글톤으로 생성하지 않고 Activity Context를 사용하는 것이 맞다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전역으로 사용하는데 Activity Context를 사용한다면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Activity에 대한 참조가 남게 되고 해당 Activity가 사용되지 않는데 참조되고 있을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 경우 GC에 의해 수거되지 않아 메모리 누수가 발생할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1679843586652&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;application
        android:name=&quot;.MyApplication&quot;&amp;gt;
        
&amp;lt;/application&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;manifest 파일에 생성한 Application 클래스를 등록해줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1679843905638&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;MyApplication.prefsManager.setString(&quot;name&quot;, &quot;a&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 메소드를 사용해주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://velog.io/@haero_kim/Android-Context-%EB%84%88-%EB%8C%80%EC%B2%B4-%EB%AD%90%EC%95%BC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;해로,&amp;nbsp;HAERO,&amp;nbsp;海路&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://leveloper.tistory.com/133&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;꾸준하게&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Android/etc</category>
      <category>Android</category>
      <category>application context</category>
      <category>context</category>
      <category>SharedPreferences</category>
      <category>SharedPreferences 싱글톤</category>
      <category>SharedPreferences 전역 생성</category>
      <category>Singleton</category>
      <category>싱글톤</category>
      <category>안드로이드</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/69</guid>
      <comments>https://hapen385.tistory.com/69#entry69comment</comments>
      <pubDate>Mon, 27 Mar 2023 08:00:10 +0900</pubDate>
    </item>
    <item>
      <title>[Algorithm] 시간 복잡도와 공간 복잡도</title>
      <link>https://hapen385.tistory.com/68</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;복잡도는 시간 복잡도와 공간 복잡도로 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;시간복잡도&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제를 해결하는 데 걸리는 시간과 입력의 함수 관계.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떠한 알고리즘 로직이 얼마나 오랜 시간 걸리는지를 나타내는 데 쓰인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 빅오 표기법으로 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 효율적인 코드로 개선하는데 쓰이는 척도가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;빅오 표기법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력 범위 n을 기준으로 로직이 몇 번 반복되는지 나타내는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 영향을 많이 끼치는 항의 상수 인자를 빼고 나머지 항을 없앤 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;속도 비교&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 0.jpg&quot; data-origin-width=&quot;1041&quot; data-origin-height=&quot;835&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bggAQM/btr591k14Dm/IOUc681ai8fjfYe3GBCxm0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bggAQM/btr591k14Dm/IOUc681ai8fjfYe3GBCxm0/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bggAQM/btr591k14Dm/IOUc681ai8fjfYe3GBCxm0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbggAQM%2Fbtr591k14Dm%2FIOUc681ai8fjfYe3GBCxm0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;479&quot; height=&quot;384&quot; data-filename=&quot;DataBase - 0.jpg&quot; data-origin-width=&quot;1041&quot; data-origin-height=&quot;835&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;O(1)과 O(n^2)는 입력 크기 n이 커질 수록 차이가 많이 나게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;공간 복잡도&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램을 실행시켰을 때 &lt;b&gt;필요로 하는 자원 공간의 양&lt;/b&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정적 변수로 선언된 것 말고도 동적으로 공간을 계속해서 필요로 하는 경우도 포함된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자료 구조에서 시간 복잡도&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 01.jpg&quot; data-origin-width=&quot;1940&quot; data-origin-height=&quot;1042&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yE20y/btr5YVeBBVV/0mbluMpHGcJfa9iBsa68BK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yE20y/btr5YVeBBVV/0mbluMpHGcJfa9iBsa68BK/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yE20y/btr5YVeBBVV/0mbluMpHGcJfa9iBsa68BK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyE20y%2Fbtr5YVeBBVV%2F0mbluMpHGcJfa9iBsa68BK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;616&quot; height=&quot;331&quot; data-filename=&quot;DataBase - 01.jpg&quot; data-origin-width=&quot;1940&quot; data-origin-height=&quot;1042&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림은 자료 구조에서 &lt;b&gt;평균 시간 복잡도&lt;/b&gt;를 나타낸 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 02.jpg&quot; data-origin-width=&quot;1745&quot; data-origin-height=&quot;939&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Qboq1/btr5PRLlfBZ/BCMjfchuNPe2tpHxpkLiik/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Qboq1/btr5PRLlfBZ/BCMjfchuNPe2tpHxpkLiik/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Qboq1/btr5PRLlfBZ/BCMjfchuNPe2tpHxpkLiik/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQboq1%2Fbtr5PRLlfBZ%2FBCMjfchuNPe2tpHxpkLiik%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;669&quot; height=&quot;360&quot; data-filename=&quot;DataBase - 02.jpg&quot; data-origin-width=&quot;1745&quot; data-origin-height=&quot;939&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림은 자료 구조에서 &lt;b&gt;최악의 경우 시간 복잡도&lt;/b&gt;를 나타낸 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Problem Solving/Algorithm</category>
      <category>Space complexity</category>
      <category>Time Complexity</category>
      <category>공간복잡도</category>
      <category>빅오</category>
      <category>빅오표기법</category>
      <category>시간복잡도</category>
      <category>자료구조 시간복잡도</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/68</guid>
      <comments>https://hapen385.tistory.com/68#entry68comment</comments>
      <pubDate>Sun, 26 Mar 2023 22:15:38 +0900</pubDate>
    </item>
    <item>
      <title>[DataBase] 조인(join)</title>
      <link>https://hapen385.tistory.com/67</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;조인(join)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 테이블이 아닌 두 개 이상의 테이블을 묶어서 하나의 결과물을 만드는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MySQL에서는 JOIN 이라는 쿼리,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MongoDB에서는 lookup이라는 쿼리로 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MongoDB를 사용할 때 lookup은 되도록 사용하지 않아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MongoDB에서의 조인 연산은 관계형 데이터베이스보다 성능이 안좋다고 벤치마크 테스트에서 알려져 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;MongoDB에서의 조인 연산 성능&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 조인하는 작업이 많을 경우 관계형 데이터베이스를 사용하는 것이 더 낫다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;조인의 종류&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 0.jpg&quot; data-origin-width=&quot;1296&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Z3WYO/btr0NNlCbTA/5eOgFGcVvHckXTkdHLxuYK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Z3WYO/btr0NNlCbTA/5eOgFGcVvHckXTkdHLxuYK/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Z3WYO/btr0NNlCbTA/5eOgFGcVvHckXTkdHLxuYK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZ3WYO%2Fbtr0NNlCbTA%2F5eOgFGcVvHckXTkdHLxuYK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;604&quot; height=&quot;198&quot; data-filename=&quot;DataBase - 0.jpg&quot; data-origin-width=&quot;1296&quot; data-origin-height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;내부 조인(inner join)&lt;/b&gt; : 왼쪽 테이블과 오른쪽 테이블의 두 행이 일치하는 행이 있는 부분만 표기&lt;/li&gt;
&lt;li&gt;&lt;b&gt;왼쪽 조인(left outer join)&lt;/b&gt; : 왼쪽 테이블의 모든 행이 결과 테이블에 표기&lt;/li&gt;
&lt;li&gt;&lt;b&gt;오른쪽 조인(right outer join)&lt;/b&gt; : 오른쪽 테이블의 모든 행이 결과 테이블에 표기&lt;/li&gt;
&lt;li&gt;&lt;b&gt;합집합 조인(full outer join)&lt;/b&gt; : 두 개의 테이블을 기반으로 조인 조건에 만족하지 않은 행까지 모두 표기&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;내부 조인&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 테이블 간에 &lt;b&gt;교집합&lt;/b&gt;을 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내부 조인을 이용한 SQL 쿼리는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1677394723063&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM TableA A
INNER JOIN TableB B ON
A.key = B.key&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;왼쪽 조인&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(*왼쪽 조인과 오른쪽 조인을 설명할 때 왼쪽 테이블은 A, 오른쪽 테이블은 B라고 설명하겠습니다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블 B의 일치하는 부분의 레코드와 함께 테이블 A를 기준으로 완전한 레코드 집합을 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 테이블 A 기준으로 테이블 B에 일치하는 항목이 없다면 null 값이 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왼쪽 조인을 이용한 SQL 쿼리는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1677397452095&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM TableA A
LEFT JOIN TableB B ON
A.key = B.key&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오른쪽 조인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블 A에서 일치하는 부분의 레코드와 함께 테이블 B를 기준으로 완전한 레코드 집합을 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 테이블 B 기준으로 테이블 A에 일치하는 항목이 없다면 null 값이 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오른쪽 조인을 이용한 SQL 쿼리는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1677397581106&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM TableA A
RIGHT JOIN TableB B ON
A.key = B.key&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;합집합 조인(완전 외부 조인)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;양쪽 테이블에서 일치하는 레코드와 함께 테이블 A와 테이블 B의 모든 레코드 집합을 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서로 일치하는 항목이 없으면 누락된 쪽에 null 값이 포함된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;합집합 조인을 이용한 SQL 쿼리는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1677397663213&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM TableA A
FULL OUTER JOIN TableB B ON
A.key = B.key&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/DataBase</category>
      <category>cs</category>
      <category>Database</category>
      <category>db</category>
      <category>join</category>
      <category>mysql</category>
      <category>데이터베이스</category>
      <category>조인</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/67</guid>
      <comments>https://hapen385.tistory.com/67#entry67comment</comments>
      <pubDate>Fri, 3 Mar 2023 21:30:01 +0900</pubDate>
    </item>
    <item>
      <title>[DataBase] 인덱스</title>
      <link>https://hapen385.tistory.com/66</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;인덱스&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 빠르게 찾을 수 있는 하나의 장치.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예로는 책의 마지막 장에 있는 찾아보기가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책의 본문 안에 찾고자 하는 항목을 찾아보기를 통해 빠르게 찾을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 인덱스를 설정하면 테이블 안에 찾고자 하는 데이터를 빠르게 찾을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;B-트리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인덱스는 보통 B-트리 자료 구조로 이루어져 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;B-트리는 루트 노드, 리프 노드, 브랜치 노드로 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 0.jpg&quot; data-origin-width=&quot;1067&quot; data-origin-height=&quot;732&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvI2Ad/btr0IGfUtb8/aagkCkfZtBqjBcUhRYFmW0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvI2Ad/btr0IGfUtb8/aagkCkfZtBqjBcUhRYFmW0/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvI2Ad/btr0IGfUtb8/aagkCkfZtBqjBcUhRYFmW0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvI2Ad%2Fbtr0IGfUtb8%2FaagkCkfZtBqjBcUhRYFmW0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;598&quot; height=&quot;410&quot; data-filename=&quot;DataBase - 0.jpg&quot; data-origin-width=&quot;1067&quot; data-origin-height=&quot;732&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 E를 찾는다고 하면, 전체 테이블을 탐색하는 것이 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림처럼 E는 D와 L 사이에 있으므로, 루트 노드에서 D로 들어가고 리프 노드에서 E를 찾을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자료 구조 없이 탐색한다면 다섯 번을 탐색해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 노드로 나누면 두 번만에 값을 찾을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 2.jpg&quot; data-origin-width=&quot;1540&quot; data-origin-height=&quot;1161&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MTZe6/btr0BX4nini/gpJfAlAU123udiEPMCgLs0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MTZe6/btr0BX4nini/gpJfAlAU123udiEPMCgLs0/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MTZe6/btr0BX4nini/gpJfAlAU123udiEPMCgLs0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMTZe6%2Fbtr0BX4nini%2FgpJfAlAU123udiEPMCgLs0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;560&quot; height=&quot;422&quot; data-filename=&quot;DataBase - 2.jpg&quot; data-origin-width=&quot;1540&quot; data-origin-height=&quot;1161&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트리 탐색은 루트 노드부터 일어난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 브랜치 노드를 거쳐 리프 노드까지 내려온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;57을 찾아라고 했을 때, '57보다 같거나 클 때까지'를 기반으로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 루트 노드에서는 39,83 이후 아래 노드로 내려와서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;46,53,57 으로 내려오고 리프 노드에서 57을 찾을수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 데이터 포인터를 통해 결괏값을 반환하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;인덱스가 효율적인 이유&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인덱스가 효율적인 이유는 균형 잡힌 트리 구조와 트리 깊이의 대수확장성 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;대수확장성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트리 깊이가 리프 노드 수에 비해 매우 느리게 커지는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 3.jpg&quot; data-origin-width=&quot;610&quot; data-origin-height=&quot;860&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/taQrN/btr0AxZaGVR/czJnqnEebwzUCiznrQikgK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/taQrN/btr0AxZaGVR/czJnqnEebwzUCiznrQikgK/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/taQrN/btr0AxZaGVR/czJnqnEebwzUCiznrQikgK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtaQrN%2Fbtr0AxZaGVR%2FczJnqnEebwzUCiznrQikgK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;283&quot; height=&quot;399&quot; data-filename=&quot;DataBase - 3.jpg&quot; data-origin-width=&quot;610&quot; data-origin-height=&quot;860&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 인덱스가 한 깊이씩 증가할 때마다 최대 인덱스 항목의 수는 4배씩 증가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 표에 따르면 트리 깊이가 열 개이면 약 100만 개의 레코드를 검색할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기 때문에 많은 인덱스를 나눈 상태에서 탐색하는 것이 효율적이라 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;인덱스를 만드는 방법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스마다 인덱스를 만드는 방법이 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;MySQL&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MySQL의 경우 클러스터형 인덱스와 세컨터리 인덱스가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*&lt;b&gt;클러스터형 인덱스&lt;/b&gt; : 인덱스 자체에 데이터가 저장되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*&lt;b&gt;세컨더리 인덱스&lt;/b&gt; : 인덱스 자체에 데이터가 저장되지 않고 데이터의 주소가 저장되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클러스터형 인덱스는 테이블당 하나를 설정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;primary key 옵션으로 기본키로 만들면 클러스터형 인덱스를 생성할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본키로 만들지 않고 unique not null 옵션을 붙이면 클러스터형 인덱스를 만들 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세컨더리 인덱스는 create index... 명령어를 기반으로 만들 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;하나의 인덱스만 생성한다면 클러스터형 인덱스&lt;/b&gt;를 생성하는 것이 성능이 더 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 인덱스는 보조 인덱스로 여러 개의 필드 값을 기반으로 쿼리를 많이 보낼 때 생성해야 하는 인덱스이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 age라는 하나의 필드로 쿼리를 보낸다면 클러스터형 인덱스가 낫다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 age, name, email 등 여러 필드 기반으로 쿼리를 보낸다면 세컨더리 인덱스가 낫다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;MongoDB&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도큐먼트를 만들면 자동으로 ObjectID가 생성되는데, 이 키가 기본키로 설정된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세컨더리 키도 부가적으로 설정해서 기본키와 세컨더리 키를 같이 쓰는 복합 인덱스를 설정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;인덱스 최적화 기법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최적화 기법은 데이터베이스마다 다를 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MongoDB를 기반으로 최적화 기법을 설명하면 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 인덱스는 무조건 다 사용하는 것이 아니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인덱스는 두 번 탐색하도록 강요한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인덱스 리스트, 컬렉션 순으로 탐색하기 때문에 관련 읽기 비용이 들게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컬렉션이 수정되었을 때 인덱스도 수정되어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 B-트리 높이를 균형 있게 조절하는 비용도 든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 효율적으로 조회할 수 있도록 분산시키는 비용도 들게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 쿼리에 있는 필드에 인덱스를 무작정 설정하는 것은 답이 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 컬렉션에서 가져와야 하는 양이 많을수록 인덱스를 사용하는 것은 비효율적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 항상 테스팅하며 시간을 최소화한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인덱스 최적화 기법은 서비스 특징에 따라 달라진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스에서 사용하는 객체의 깊이, 테이블의 양이 다르기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 테스팅을 항상 하는 것이 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿼리를 보낸 이후에 테스팅을 하며 걸리는 시간을 최소화해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 복합 인덱스의 경우 같음, 정렬, 다중값, 카디널리티 순으로 생성한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복합 인덱스를 생성할 때는 순서가 있고 생성 순서에 따라 인덱스의 성능이 달라진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같음, 정렬, 다중값, 카디널리티 순으로 생성해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &lt;b&gt;어떠한 값과 같음을 비교하는&lt;/b&gt; == 이나 equal &lt;b&gt;쿼리가 있으면&lt;/b&gt; 제일 먼저 인덱스로 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;b&gt;정렬&lt;/b&gt;에 쓰는 필드라면 그 다음 인덱스로 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 다중 값을 출력해야 하는 필드, 쿼리 자체가 &amp;gt; 이거나 &amp;lt; 등 &lt;b&gt;많은 값을 출력해야 하는 쿼리에 쓰는 필드&lt;/b&gt;면 그 다음 인덱스로 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 그 다음에는&lt;b&gt; 카디널리티가 높은 순서를 고려&lt;/b&gt;해서 인덱스를 생성해야 한다. 예를 들어, age와 email이 있다면 email이 카디널리티가 높으므로 email 필드에 대한 인덱스를 age보다 먼저 설정해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/DataBase</category>
      <category>cs</category>
      <category>db index</category>
      <category>index</category>
      <category>데이터베이스</category>
      <category>인덱스</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/66</guid>
      <comments>https://hapen385.tistory.com/66#entry66comment</comments>
      <pubDate>Sat, 25 Feb 2023 08:00:54 +0900</pubDate>
    </item>
    <item>
      <title>[DataBase] 데이터베이스의 종류</title>
      <link>https://hapen385.tistory.com/65</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스에는 여러 종류가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관계형 데이터베이스와 NoSQL 데이터베이스로 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 우리가 익히 알고있는 관계형 데이터베이스에 대해서 다뤄보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;관계형 데이터베이스(RDBMS)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행과 열을 가지는 표 형식 데이터를 저장하는 형태의 데이터베이스를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SQL이라는 언어를 써서 조작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MySQL, PostgreSQL, 오라클, SQL Server, MSSQL 등이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;표준 SQL을 지키기는 하지만, 각각의 제품에 특화시킨 SQL을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 오라클의 경우 PL/SQL이라고 하는 SQL을 사용하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SQL Server에서는 T-SQL,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MySQL은 SQL을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;MySQL&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분의 운영체제와 호환되며 가장 많이 사용하는 데이터베이스이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메타, 트위터 등 많은 기업에서 사용하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C,C++로 만들어졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MyISAM 인덱스 압축 기술을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*MyISAM 압축 기술 : 테이블의 각 열들을 따로 압축하는 기술. &lt;a href=&quot;https://dev.mysql.com/doc/refman/8.0/en/myisampack.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;자세한 내용은 여기서 읽을 수 있다(MySQL 공식 문서)&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;B-트리 기반의 인덱스를 사용하며&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스레드 기반의 메모리 할당 시스템을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매우 빠른 조인 속도를 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최대 64개의 인덱스를 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대용량 데이터베이스를 위해 설계돼 있고&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;롤백, 커밋, 이중 암호 지원 보안 등의 기능을 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 0.jpg&quot; data-origin-width=&quot;1458&quot; data-origin-height=&quot;1594&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUMqvS/btr0kmo7yPP/PwKUEejYyDC0bNOW2Cp5d0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUMqvS/btr0kmo7yPP/PwKUEejYyDC0bNOW2Cp5d0/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUMqvS/btr0kmo7yPP/PwKUEejYyDC0bNOW2Cp5d0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUMqvS%2Fbtr0kmo7yPP%2FPwKUEejYyDC0bNOW2Cp5d0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;538&quot; height=&quot;588&quot; data-filename=&quot;DataBase - 0.jpg&quot; data-origin-width=&quot;1458&quot; data-origin-height=&quot;1594&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MySQL의 스토리지 엔진 아키텍처는 위 그림과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스의 심장과도 같은 역할을 하는 곳이 스토리지 엔진이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*스토리지 엔진(storage engine) : &lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;서버 엔진이 필요한&amp;nbsp;&lt;/span&gt;데이터를 물리적인 장치에서 가져오는 역할&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;*서버 엔진 : 클라이언트의 요청을 받고&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;&lt;/span&gt;SQL문들을 처리&lt;span style=&quot;background-color: #ffffff;&quot;&gt;하는 DB 자체의 기능 역할&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모듈식 아키텍처로 쉽게 스토리지 엔진을 바꿀 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 웨어하우징, 트랜잭션 처리, 고가용성 처리에 강점을 두고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*데이터 웨어하우스 : &lt;span style=&quot;color: #222222;&quot;&gt;사용자 의사결정에 필요한 데이터가 들어가 있는 데이터베이스&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스토리지 엔진 위에는 커넥터 API 및 서비스 계층을 통해 MySQL 데이터베이스와 쉽게 상호작용을 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MySQL은 쿼리 캐시를 지원해서 입력된 쿼리 문에 대한 전체 결과 집합을 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*쿼리 캐시 : 사용자가 작성한 쿼리가 캐시에 있는 쿼리와 동일하면 서버는 단순히 구문 분석 최적화 및 실행을 건너뛰고 캐시의 출력만 표시한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;PostgreSQL&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디스크 조작이 차지하는 영역을 회수할 수 있는 장치인 VACUUM이 특징이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최대 테이블의 크기는 32TB이며&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SQL뿐만 아니라 JSON을 사용하여 데이터에 접근할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지정 시간에 복구하는 기능, 로깅, 접근 제어, 중첩된 트랜잭션, 백업 등을 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;NoSQL 데이터베이스&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NoSQL(Not only SQL)이라는 말에서 생겨난 데이터베이스이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SQL을 사용하지 않는 데이터베이스를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대표적으로 MongoDB와 redis가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;MongoDB&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JSON을 통해 데이터에 접근할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Binary JSON(BSON) 형태로 데이터가 저장된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;와이어드타이거 엔진이 기본 스토리지 엔진으로 장착되었으며&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키-값 데이터 모델에서 확장된 도큐먼트 기반의 데이터베이스이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확장성이 뛰어나며 빅데이터를 저장할 때 성능이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고가용성과 샤딩, 레플리카셋을 지원한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*샤딩 : &lt;span&gt;데이터를 분산하여 저장하는 개념&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*레플리카셋 : 여러 개의 동일한 데이터베이스를 만들어서 데이터를 백업해두는 방식. 여러 서버에서 데이터베이스 서버를 분산하고 관리하는 구조.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스키마를 정해놓지 않고 데이터를 삽입할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 다양한 도메인의 데이터베이스를 기반으로 분석하거나 로깅 등을 구현할 때 강점을 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 01.jpg&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;253&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lAS4I/btr0o7daKyx/rEXFVb7S3pO0KOn4flrzBK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lAS4I/btr0o7daKyx/rEXFVb7S3pO0KOn4flrzBK/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lAS4I/btr0o7daKyx/rEXFVb7S3pO0KOn4flrzBK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlAS4I%2Fbtr0o7daKyx%2FrEXFVb7S3pO0KOn4flrzBK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;568&quot; height=&quot;150&quot; data-filename=&quot;DataBase - 01.jpg&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;253&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도큐먼트를 생성할 때마다 다른 컬렉션에서 중복된 값을 지니기 힘든 유니크한 값인 ObjectID가 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ObjectID는 기본키로 유닉스 시간 기반의 타임스탬프(4바이트), 랜덤 값(5바이트), 카운터(3바이트)로 이루어져있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;redis&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인메모리 데이터베이스.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키 - 값 데이터 모델 기반의 데이터베이스이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적인 데이터 타입은 문자열(string)이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이외에도 set, hash 등을 지원한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최대 512MB까지 저장할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;채팅 시스템 : pub/sub 기능을 이용한 채팅 시스템 구현이 가능하다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;publish(발행)/subscribe(구독) 방식이란, 특정한 topic에 대하여 이를 구독한 모두에게 메시지를 발행하는 통신 방법이다. 하나의 Client가 메시지를 publish하면 이 topic에 연결되어 있는 다수의 Client가 메시지를 받을 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;캐싱 계층 : 다른 데이터베이스 앞단에 두어 사용한다.&lt;/li&gt;
&lt;li&gt;세션 정보 관리 : 단순한 키 - 값으로 세션 정보 관리가 가능하다.&lt;/li&gt;
&lt;li&gt;실시간 순위표 서비스 : 정렬된 셋(sorted set) 자료 구조를 랭킹 기능 구현에 사용할 수 있다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;sorted set을 사용하면 값을 비교하여 정렬을 해주어 랭킹 기능을 구현할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://inpa.tistory.com/entry/REDIS-%F0%9F%93%9A-PUBSUB-%EA%B8%B0%EB%8A%A5-%EC%86%8C%EA%B0%9C-%EC%B1%84%ED%8C%85-%EA%B5%AC%EB%8F%85-%EC%95%8C%EB%A6%BC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Inpa Dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://minchoi0912.tistory.com/103&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;프로그래밍구&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jaehoney.tistory.com/31&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;A work-loving developer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Science/DataBase</category>
      <category>cs</category>
      <category>db</category>
      <category>mongodb</category>
      <category>mysql</category>
      <category>NoSQL</category>
      <category>RDBMS</category>
      <category>redis</category>
      <category>관계형 데이터베이스</category>
      <category>데이터베이스</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/65</guid>
      <comments>https://hapen385.tistory.com/65#entry65comment</comments>
      <pubDate>Sat, 25 Feb 2023 07:56:59 +0900</pubDate>
    </item>
    <item>
      <title>[DataBase] 트랜잭션</title>
      <link>https://hapen385.tistory.com/64</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;트랜잭션&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스에서 하나의 논리적 기능을 수행하기 위한 작업의 단위.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 개의 쿼리들을 하나로 묶는 단위.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랜잭션의 특징은 원자성, 일관성, 독립성, 지속성이 있으며 한꺼번에 ACID 특징이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*쿼리 : 데이터베이스에 접근하는 방법. 데이터베이스에 정보를 요청하는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;원자성(atomicity)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랜잭션과 관련된 일이 모두 수행됐거나 되지 않았거나를 보장하는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;트랜잭션 내의 모든 수정 작업이 수행되거나 수정 작업이 하나도 수행되지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 트랜잭션을 커밋했는데 문제가 발생하여 롤백하는 경우 그 이후에 모두 수행되지 않음을 보장하는 것.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 1000만원을 가진 A가 0원을 가진 B에게 500만원을 이체한다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 결과 A는 500만원, B는 500만원을 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정 중에서 데이터베이스 사용자는 이 과정을 볼 수도 참여할 수도 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모두 끝난 이후의 상황만 보는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 이 작업을 취소한다고 했을 때 A는 다시 1000만원 B는 0원을 가져야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;돈을 주고 받는 과정 중에서 일부 operation만 적용되어서 A는 500만원, B는 0원이 되지 않는 것을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 트랜잭션 단위로 여러 로직들을 묶을 때 외부 API를 호출하는 것이 있으면 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 호출한다면 롤백이 일어났을 때 어떻게 해야 할지에 대한 해결 방법이 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 트랜잭션 전파를 신경 써서 관리해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;커밋과 롤백&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;커밋(commit)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 쿼리가 성공적으로 처리되었다고 확정하는 명령어.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랜잭션 단위로 수행되며 변경된 내용이 영구저장되는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커밋이 수행됐다를 하나의 트랜잭션이 성공적으로 수행됐다고도 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 7.jpg&quot; data-origin-width=&quot;1185&quot; data-origin-height=&quot;631&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVDqc3/btrZJDkIPps/mOoTObIXoOgArdiRZ3H0D0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVDqc3/btrZJDkIPps/mOoTObIXoOgArdiRZ3H0D0/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVDqc3/btrZJDkIPps/mOoTObIXoOgArdiRZ3H0D0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVDqc3%2FbtrZJDkIPps%2FmOoTObIXoOgArdiRZ3H0D0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;582&quot; height=&quot;310&quot; data-filename=&quot;DataBase - 7.jpg&quot; data-origin-width=&quot;1185&quot; data-origin-height=&quot;631&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림처럼 update, insert, delete의 쿼리가 하나의 트랜잭션 단위로 수행되고 DB에 영구적으로 저장된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;롤백(rolback)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랜잭션으로 처리한 하나의 묶음 과정을 일어나기 전으로 돌리는 일.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 8.jpg&quot; data-origin-width=&quot;1236&quot; data-origin-height=&quot;811&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RpbCk/btrZIFDlu8W/wj3SVgpKCC194UASElW88k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RpbCk/btrZIFDlu8W/wj3SVgpKCC194UASElW88k/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RpbCk/btrZIFDlu8W/wj3SVgpKCC194UASElW88k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRpbCk%2FbtrZIFDlu8W%2Fwj3SVgpKCC194UASElW88k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;539&quot; height=&quot;354&quot; data-filename=&quot;DataBase - 8.jpg&quot; data-origin-width=&quot;1236&quot; data-origin-height=&quot;811&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러나 여러 이슈 때문에 트랜잭션 전으로 돌려야할 때 사용하는 것이 롤백이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커밋과 롤백으로 데이터의 무결성이 보장된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 변경 전에 변경 사항을 쉽게 확인할 수 있고 해당 작업을 그룹화할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;트랜잭션 전파&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랜잭션을 수행할 때 커넥션 객체를 넘겨서 수행해야 한다. 이를 넘겨서 수행하지 않고 여러 트랜잭션 관련 메서드의 호출을 하나의 트랜잭션에 묶이도록 하는 것을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*커넥션 : 애플리케이션과 데이터베이스의 연결. DB와 연결하기 위해 사용하는 것이 커넥션 객체다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;일관성(consistency)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;허용된 방식으로만 데이터를 변경해야 하는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스에 기록된 모든 데이터는 여러 가지 조건, 규칙에 따라 유효함을 가져야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정해진 조건, 규칙에 따라 데이터를 변경해야 하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;격리성(isolation)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랜잭션 수행 시 서로 끼어들지 못하는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랜잭션은 서로 격리되어 마치 순차적으로 실행되는 것처럼 작동되어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스는 여러 사용자가 같은 데이터에 접근할 수 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;격리성은 여러 개의 격리 수준으로 나뉜다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 9.jpg&quot; data-origin-width=&quot;1049&quot; data-origin-height=&quot;702&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bON1DR/btrZIl6acsT/QgyqvI4a3qlOWkqHCXcPi1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bON1DR/btrZIl6acsT/QgyqvI4a3qlOWkqHCXcPi1/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bON1DR/btrZIl6acsT/QgyqvI4a3qlOWkqHCXcPi1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbON1DR%2FbtrZIl6acsT%2FQgyqvI4a3qlOWkqHCXcPi1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;529&quot; height=&quot;354&quot; data-filename=&quot;DataBase - 9.jpg&quot; data-origin-width=&quot;1049&quot; data-origin-height=&quot;702&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*&lt;b&gt;동시성&lt;/b&gt; : 여러 일을 동시에 실행하는 것. 트랜잭션의 각 쿼리문들이 트랜잭션의 순서에 상관없이 동시에 실행되는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;격리 수준에 따라 발생하는 현상&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;격리 수준에 따라 발생하는 현상은 팬텀 리드, 반복 가능하지 않은 조회, 더티 리드가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;팬텀 리드(phantom read)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 트랜잭션 내에서 동일한 쿼리를 보냈을 때 해당 조회 결과가 다른 경우를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;반복 가능하지 않은 조회(non-repeatable read)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 트랜잭션 내의 같은 행에 두 번 이상 조회가 발생했는데, 그 값이 서로 다른 경우.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팬텀 리드와 다른 점은 반복 가능하지 않은 조회는 행 값이 달라질 수도 있는데, 팬텀 리드는 다른 행이 선택될 수도 있다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;더티 리드(dirty read)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 트랜잭션이 실행 중일 때 다른 트랜잭션에 의해 수정되었지만 아직 커밋되지 않은 행의 데이터를 읽을 수 있을 때 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;반복 가능하지 않은 조회와 유사하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;격리 수준&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;격리 수준은 SERIALIZABLE, REPEATABLE_READ, READ_COMMITTED, READ_UNCOMMITTED가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;images_guswns3371_post_d8dd599a-6d94-481a-ab87-0063e5fd0e2a_image.png&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;258&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjCAot/btrZLSOGZO1/dfjn88mOwAzxx2EOnUSLc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjCAot/btrZLSOGZO1/dfjn88mOwAzxx2EOnUSLc0/img.png&quot; data-alt=&quot;출처 : hjoon.log(https://velog.io/@guswns3371/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EA%B2%A9%EB%A6%AC%EC%88%98%EC%A4%80)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjCAot/btrZLSOGZO1/dfjn88mOwAzxx2EOnUSLc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjCAot%2FbtrZLSOGZO1%2Fdfjn88mOwAzxx2EOnUSLc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;552&quot; height=&quot;243&quot; data-filename=&quot;images_guswns3371_post_d8dd599a-6d94-481a-ab87-0063e5fd0e2a_image.png&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;258&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : hjoon.log(https://velog.io/@guswns3371/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EA%B2%A9%EB%A6%AC%EC%88%98%EC%A4%80)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SERIALIZABLE&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랜잭션을 순차적으로 진행시키는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;트랜잭션이 완료될 때까지 다른 사용자가 데이터베이스에 행을 삽입하거나 업데이트할 수 없도록 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 트랜잭션이 동시에 같은 행에 접근할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매우 엄격한 격리 수준으로 해당 행에 대해 격리시키고, 이후 트랜잭션이 이 행에 대해 일어난다면 기다려야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 교착 상태가 일어날 확률이 높고 가장 성능이 안좋은 격리 수준이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;REPEATABLE_READ&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 트랜잭션이 수정한 행을 다른 트랜잭션이 수정할 수 없도록 막아주지만 새로운 행을 추가하는 것은 막지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후에 추가된 행이 발견될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;READ_COMMITTED&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 트랜잭션이 커밋하지 않은 정보는 읽을 수 없다. 커밋 완료된 데이터에 대해서만 조회를 허용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 어떤 트랜잭션이 접근한 행을 다른 트랜잭션이 수정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 다시 읽을 때 다른 내용이 발견될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 많이 사용되는 격리 수준이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MySQL8.0, PostgreSQL, SQL Server, 오라클에서 기본값으로 설정되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;READ_UNCOMMITTED&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 낮은 격리 수준을 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 무결성을 위해 사용하지 않는 것이 이상적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 트랜잭션이 커밋되기 이전에 다른 트랜잭션에 노출될 수 있는 문제가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 거대한 양의 데이터를 어림잡아 집계하는 데는 사용하면 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;지속성(durability)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성공적으로 수행된 트랜잭션은 영원히 반영되어야 하는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스에 시스템 장애가 발생해도 원래 상태로 복구하는 회복 기능이 있어야 함을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 위해 데이터베이스는 체크섬, 저널링, 롤백 등의 기능을 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*&lt;b&gt;체크섬&lt;/b&gt; : 중복 검사의 한 형태로, 오류 정정을 통해 송신된 자료의 무결성을 보호한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*&lt;b&gt;저널링&lt;/b&gt; : 파일 시스템 또는 데이터베이스 시스템에 변경 사항을 커밋하기 전에 로깅하는 것(트랜잭션 등 변경 사항에 대한 로그를 남기는 것)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;무결성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터의 정확성, 일관성, 유효성을 유지시키는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무결성이 유지돼야 데이터베이스에 저장된 값과 그 값에 해당하는 현실 세계의 실제 값이 일치하는지에 대한 신뢰가 생긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무결성의 종류는 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;개체 무결성&lt;/b&gt; : &lt;b&gt;기본키&lt;/b&gt;로 선택된 필드는 &lt;b&gt;빈 값을 허용하지 않는다&lt;/b&gt;.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;참조 무결성&lt;/b&gt; : 서로 참조 관계에 있는 두 테이블의 데이터는 &lt;b&gt;항상 일관된 값을 유지&lt;/b&gt;해야 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;고유 무결성&lt;/b&gt; : 특정 속성에 대해 고유한 값을 가지도록 조건이 주어진 경우 &lt;b&gt;그 속성 값은 모두 고유한 값&lt;/b&gt;을 가진다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;NULL 무결성&lt;/b&gt; : 특정 속성 값에 NULL이 올 수 없다는 조건이 주어진 경우 &lt;b&gt;그 속성 값은 NULL이 될 수 없다는 제약 조건&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/DataBase</category>
      <category>acid</category>
      <category>cs</category>
      <category>Database</category>
      <category>db</category>
      <category>DB ACID</category>
      <category>데이터 무결성</category>
      <category>데이터베이스</category>
      <category>트랜잭션</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/64</guid>
      <comments>https://hapen385.tistory.com/64#entry64comment</comments>
      <pubDate>Sat, 18 Feb 2023 01:37:28 +0900</pubDate>
    </item>
    <item>
      <title>[DataBase] 정규화(Normalization)</title>
      <link>https://hapen385.tistory.com/63</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;정규화(Normalication)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;릴레이션 간의 잘못된 종속 관계로 인해 데이터베이스 이상 현상이 일어나서 이를 해결하거나,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저장 공간을 효율적으로 사용하기 위해 &lt;b&gt;릴레이션을 여러 개로 분리&lt;/b&gt;하는 과정.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*데이터베이스 이상 현상 : 삭제할 때 필요한 데이터가 같이 삭제되거나 잘못된 정보가 들어있거나 데이터를 삽입해야 하는데 하나의 필드 값이 NULL이 되면 안돼서 삽입하기 어려운 현상.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;정규화의 원칙&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 정보 표현의 무손실 : 정보가 사라지지 않아야 한다, 같은 의미의 정보를 유지하면서 더 효율적인 구조로 변화해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 데이터 중복의 최소 : 데이터 중복을 최소화하면서, 데이터 관리의 편리성을 부여하고 자료 저장 공간을 효율적으로 사용.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 분리의 원칙 : 독립적인 관계는 별개의 릴레이션으로 표현, 릴레이션 각각에 대해 독립적 처리가 가능.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;정규화 과정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정규화 원칙을 기반으로 정규형을 만들어가는 과정.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정규화된 정도는 정규형(NF, Normal Form)으로 표현.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같은 정규형들이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기본 정규형&lt;/b&gt; : 제1정규형, 제2정규형, 제3정규형, 보이스/코드 정규형&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;고급 정규형&lt;/b&gt; : 제4정규형, 제5정규형&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;제1정규형&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 도메인이 더 이상 분해될 수 없는 원자값(atomic value)만으로 구성된 릴레이션.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;릴레이션의 속성 값 중에서 &lt;b&gt;한 개의 기본키&lt;/b&gt;에 대해 &lt;b&gt;두 개 이상의 값&lt;/b&gt;을 가지는 반복 집합이 있어서는 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 반복 집합이 있다면 제거해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 0.jpg&quot; data-origin-width=&quot;1089&quot; data-origin-height=&quot;807&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsCEDj/btrZJ3J92hn/lQTKvqe07aP5Zz763TJC51/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsCEDj/btrZJ3J92hn/lQTKvqe07aP5Zz763TJC51/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsCEDj/btrZJ3J92hn/lQTKvqe07aP5Zz763TJC51/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsCEDj%2FbtrZJ3J92hn%2FlQTKvqe07aP5Zz763TJC51%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;529&quot; height=&quot;392&quot; data-filename=&quot;DataBase - 0.jpg&quot; data-origin-width=&quot;1089&quot; data-origin-height=&quot;807&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림과 같이 홍철과 범식이란 ID에 수강명 값이 두 개 이상이었는데 이것을 나눠서 반복 집합을 제거하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 제1정규형에는 기본 키에 부분 함수 종속된 속성이 있을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 기본키와 무관한 속성이 존재한다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 제2정규형을 사용하면 이러한 문제를 해결할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;제2정규형&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;릴레이션이 제1정규형이며 부분 함수의 종속성을 제거한 형태.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부분 함수의 종속성 제거로 기본키가 아닌 모든 속성이 기본키에 완전 함수 종속적이게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 1.jpg&quot; data-origin-width=&quot;1087&quot; data-origin-height=&quot;810&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/de13vq/btrZJWxsqEe/iovrGAdM5FudKY3bwluax0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/de13vq/btrZJWxsqEe/iovrGAdM5FudKY3bwluax0/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/de13vq/btrZJWxsqEe/iovrGAdM5FudKY3bwluax0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fde13vq%2FbtrZJWxsqEe%2FiovrGAdM5FudKY3bwluax0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;598&quot; height=&quot;446&quot; data-filename=&quot;DataBase - 1.jpg&quot; data-origin-width=&quot;1087&quot; data-origin-height=&quot;810&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림에서 제1정규형의 릴레이션은 기본키인 유저ID, 수강명에 종속되지 않은 속성이 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유저번호는 수강명에 종속되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 유저번호 릴레이션과 성취도 릴레이션으로 분리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 분리할 때 주의점은 동등한 릴레이션으로 분해해야 하고, 정보 손실이 발생하지 않는 무손실 분해로 분해되어야 한다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제2정규형은 이행적 함수 종속이 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이행적 함수 종속&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 2.jpg&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;564&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAxS49/btrZLRIYd7B/3kKK20DAnpojRSlc6xN6U1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAxS49/btrZLRIYd7B/3kKK20DAnpojRSlc6xN6U1/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAxS49/btrZLRIYd7B/3kKK20DAnpojRSlc6xN6U1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAxS49%2FbtrZLRIYd7B%2F3kKK20DAnpojRSlc6xN6U1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;307&quot; height=&quot;295&quot; data-filename=&quot;DataBase - 2.jpg&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;564&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A -&amp;gt; B와 B -&amp;gt; C가 존재하면 논리적으로 A -&amp;gt; C가 성립.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 집합 C가 A에 이행적으로 함수 종속이 되었다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이행적 함수 종속을 없애려면 제3정규형으로 없앨 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;제3정규형&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제2정규형이고 기본키가 아닌 모든 속성이 이행적 함수 종속(transitive FD)을 만족하지 않는 상태.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 3.jpg&quot; data-origin-width=&quot;915&quot; data-origin-height=&quot;793&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkUKGH/btrZIniAwXQ/8DUgBCMcbPRRyOkqfm76dk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkUKGH/btrZIniAwXQ/8DUgBCMcbPRRyOkqfm76dk/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkUKGH/btrZIniAwXQ/8DUgBCMcbPRRyOkqfm76dk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkUKGH%2FbtrZIniAwXQ%2F8DUgBCMcbPRRyOkqfm76dk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;478&quot; height=&quot;414&quot; data-filename=&quot;DataBase - 3.jpg&quot; data-origin-width=&quot;915&quot; data-origin-height=&quot;793&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제2정규형에서는&amp;nbsp;유저ID에 의해서 등급이 결정되고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;등급에 의해서 할인율이 결정되어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이행적 함수 종속이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유저ID -&amp;gt; 등급, 등급 -&amp;gt; 할인율 이 두 종속을&amp;nbsp; 두 개의 릴레이션으로 분리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 이원 릴레이션(속성이 두 개밖에 없는 것)은 제3정규형에 속한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키가 아닌 속성 값의 갱신 시 불필요한 부작용(이상)은 발생하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;보이스/코드 정규형(BNCF)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제3정규형이고 결정자가 후보키가 아닌 함수 종속 관계를 제거하여 &lt;b&gt;릴레이션의 함수 종속 관계에서 모든 결정자가 후보키&lt;/b&gt;인 상태.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강한 제3정규형이라고도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*&lt;b&gt;결정자&lt;/b&gt; : 함수 종속 관계에서 특정 종속자(dependent)를 결정짓는 요소. X -&amp;gt; Y일 때 X는 결정자, Y는 종속자이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 4.jpg&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;574&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCNAu3/btrZJCsydy6/AUkFGYIyfu5lvoSWSCCiL0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCNAu3/btrZJCsydy6/AUkFGYIyfu5lvoSWSCCiL0/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCNAu3/btrZJCsydy6/AUkFGYIyfu5lvoSWSCCiL0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCNAu3%2FbtrZJCsydy6%2FAUkFGYIyfu5lvoSWSCCiL0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;357&quot; height=&quot;308&quot; data-filename=&quot;DataBase - 4.jpg&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;574&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 릴레이션에서 {학번, 수강명} 또는 {학번, 강사}가 후보키가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 범석이라는 강사가 롤이라는 수강명을 담당한다고 했을 때 삽입하면 학번이 NULL이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 함수 종속 다이어그램은 다음과 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 5.jpg&quot; data-origin-width=&quot;728&quot; data-origin-height=&quot;537&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wp6Fg/btrZNvyVEg2/dwEm6cq4DkbYspRWoD6YXK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wp6Fg/btrZNvyVEg2/dwEm6cq4DkbYspRWoD6YXK/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wp6Fg/btrZNvyVEg2/dwEm6cq4DkbYspRWoD6YXK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fwp6Fg%2FbtrZNvyVEg2%2FdwEm6cq4DkbYspRWoD6YXK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;353&quot; height=&quot;260&quot; data-filename=&quot;DataBase - 5.jpg&quot; data-origin-width=&quot;728&quot; data-origin-height=&quot;537&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강사 속성이 결정자이지만 후보키가 아니라서 강사 속성을 분리해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 다음과 같이 분리가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 6.jpg&quot; data-origin-width=&quot;1023&quot; data-origin-height=&quot;1076&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A6f9i/btrZIaDMth5/3ZWO3nMkmDjB2yv9me611K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A6f9i/btrZIaDMth5/3ZWO3nMkmDjB2yv9me611K/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A6f9i/btrZIaDMth5/3ZWO3nMkmDjB2yv9me611K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA6f9i%2FbtrZIaDMth5%2F3ZWO3nMkmDjB2yv9me611K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;485&quot; height=&quot;510&quot; data-filename=&quot;DataBase - 6.jpg&quot; data-origin-width=&quot;1023&quot; data-origin-height=&quot;1076&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정규화 과정을 거친다고 해서 성능이 100% 좋아지는 것은 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성능이 좋아질 수도 있고 나빠질 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스에 따라 정규화 또는 비정규화 과정을 진행해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;이석호, 데이터베이스론, 정익사(2010)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/DataBase</category>
      <category>BCNF</category>
      <category>cs</category>
      <category>Database</category>
      <category>db</category>
      <category>데이터베이스</category>
      <category>정규화</category>
      <category>제1정규화</category>
      <category>제2정규화</category>
      <category>제3정규화</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/63</guid>
      <comments>https://hapen385.tistory.com/63#entry63comment</comments>
      <pubDate>Sat, 18 Feb 2023 00:38:18 +0900</pubDate>
    </item>
    <item>
      <title>[DataBase] ERD(Entity Relationship Diagram)</title>
      <link>https://hapen385.tistory.com/62</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;ERD(Entity Relationship Diagram)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;릴레이션 간의 관계들을 정의한 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;테이블간의 관계를 설명해주는 다이어그램이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스를 구축할 때 가장 기초적인 뼈대 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스를 구축한다면 가장 먼저 신경 써야 하는 부분이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;ERD의 중요성&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ERD는 시스템의 요구 사항을 기반으로 작성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 ERD를 기반으로 데이터베이스를 구축한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스를 구축한 이후에도 디버깅 또는 비즈니스 프로세스 재설계가 필요한 경우 설계도 역할을 담당하기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ERD는 관계형 구조로 표현할 수 있는 데이터를 구성하는데 유용하나,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비정형 데이터를 충분히 표현할 수 없다는 단점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*&lt;b&gt;비정형 데이터&lt;/b&gt; : 비구조화 데이터. 미리 정의된 데이터 모델이 없거나 미리 정의된 방식으로 정리되지 않은 정보.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;ERD 기호&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;다운로드.png&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;909&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d1cXUu/btrZLVqZG34/rT3kHdP6JK1zQkB42Z8551/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d1cXUu/btrZLVqZG34/rT3kHdP6JK1zQkB42Z8551/img.png&quot; data-alt=&quot;출처 : 개발/일상_Mr.lee(https://lee-mandu.tistory.com/461)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d1cXUu/btrZLVqZG34/rT3kHdP6JK1zQkB42Z8551/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd1cXUu%2FbtrZLVqZG34%2FrT3kHdP6JK1zQkB42Z8551%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;613&quot; height=&quot;557&quot; data-filename=&quot;다운로드.png&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;909&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 개발/일상_Mr.lee(https://lee-mandu.tistory.com/461)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*&lt;b&gt;개체(Entity)&lt;/b&gt; : 학생, 교수, 자동차 등과 같이 실세계에서 개념적으로 또는 물리적으로 존재하는 것. 사물이나 사건으로 정의.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*&lt;b&gt;관계(Relationship)&lt;/b&gt; : 교수 개체가 학생 개체를 지도하는 관계인 것처럼 다른 개체 타입에 속한 개체 사이의 관계를 표시.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*&lt;b&gt;속성(Attribute)&lt;/b&gt; : 학생의 이름, 주소 등과 같이 개체를 묘사하는데 사용될 수 있는 특성을 의미.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lee-mandu.tistory.com/461&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;개발/일상_Mr.lee&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/DataBase</category>
      <category>cs</category>
      <category>db</category>
      <category>ERD</category>
      <category>데이터베이스</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/62</guid>
      <comments>https://hapen385.tistory.com/62#entry62comment</comments>
      <pubDate>Fri, 17 Feb 2023 22:31:53 +0900</pubDate>
    </item>
    <item>
      <title>[DataBase] 키(Key)</title>
      <link>https://hapen385.tistory.com/61</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;키(Key)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블 간의 관계를 더 명확하게 하고 테이블 자체의 인덱스를 위해 설정된 장치다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스에서 조건에 만족하는 튜플을 찾거나 순서대로 정렬할 때 기준이 되는 속성이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;.jpg&quot; data-origin-width=&quot;659&quot; data-origin-height=&quot;752&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRTZM9/btrZatDlyNd/Tk04sgb8U40cHxnpkQKDt0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRTZM9/btrZatDlyNd/Tk04sgb8U40cHxnpkQKDt0/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRTZM9/btrZatDlyNd/Tk04sgb8U40cHxnpkQKDt0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRTZM9%2FbtrZatDlyNd%2FTk04sgb8U40cHxnpkQKDt0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;358&quot; height=&quot;409&quot; data-filename=&quot;.jpg&quot; data-origin-width=&quot;659&quot; data-origin-height=&quot;752&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키에는 여러 종류가 있는데, 종류에 따라 위 그림과 같은 관계를 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;슈퍼키는 유일성이 있다. 후보키는 유일성에 최소성까지 갖추었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후보키 중에서 기본키로 선택되지 못하면 대체키가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*&lt;b&gt;유일성(Unique)&lt;/b&gt; : 중복되는 값이 없는 것. 하나의 키 값으로 하나의 튜플만을 유일하게 식별할 수 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*&lt;b&gt;최소성(Minimality)&lt;/b&gt; : 필드를 조합하지 않고 최소 필드만 써서 키를 형성할 수 있는 것. 키를 구성하는 속성 하나를 제거하면 유일하게 식별할 수 없도록 꼭 필요한 최소의 속성으로 구성되어야 한다는 특성이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;기본키(Primary Key)&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;9DataBase - 0.jpg&quot; data-origin-width=&quot;844&quot; data-origin-height=&quot;495&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhYAEx/btrY8hXmpXr/PjKozOjPKr77JfXLapzww0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhYAEx/btrY8hXmpXr/PjKozOjPKr77JfXLapzww0/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhYAEx/btrY8hXmpXr/PjKozOjPKr77JfXLapzww0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhYAEx%2FbtrY8hXmpXr%2FPjKozOjPKr77JfXLapzww0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;472&quot; height=&quot;277&quot; data-filename=&quot;9DataBase - 0.jpg&quot; data-origin-width=&quot;844&quot; data-origin-height=&quot;495&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블의 데이터 중 고유하게 존재하는 속성.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기본키에 해당하는 데이터는 중복되어서는 안된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본키는 한 릴레이션에서 특정 튜플을 유일하게 구별할 수 있는 속성이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본키는 NULL 값을 가질 수 없다. 튜플에서 기본키로 설정된 속성에는 NULL 값이 있어서는 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유일성과 최소성을 만족한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PK 또는 프라이머리키라고 불린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림의 ID는 PDT-0002이 중복되므로 기본키가 되지 말아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본키는 자연키 또는 인조키 중에 골라서 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;자연키&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중복된 값들을 제외하며 중복되지 않는 것을 자연스레 뽑다가 나오는 키.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 유저 테이블을 만들 때, 주민등록번호, 이름, 성별의 속성 중 중복된 값을 가질 수 있는 키가 무엇인지 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이름, 성별은 중복된 값이 들어올 수 있으므로 제외시키고 자연스럽게 남는 것은 주민등록번호이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 주민등록번호는 자연키가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자연키는 언젠가는 &lt;b&gt;변하는 속성&lt;/b&gt;을 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;인조키&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인위적으로 생성한 키를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 유저 테이블을 만들 때, 주민등록번호, 이름, 성별 등의 속성을 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 인위적으로 유저 아이디를 레코드마다 부여한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 고유 식별자가 생겨난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 고유 식별자를 오라클은 sequence, MySQL은 auto increment라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이렇게 인위적으로 생성한 키를 인조키라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자연키와는 대조적으로 &lt;b&gt;변하지 않는다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 보통 기본키는 인조키로 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;외래키(Foreign Key)&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;999DataBase - 0.jpg&quot; data-origin-width=&quot;710&quot; data-origin-height=&quot;795&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c5p1f8/btrZat4myUq/szpDnxG7S7BO6DkvRAYUg0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c5p1f8/btrZat4myUq/szpDnxG7S7BO6DkvRAYUg0/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c5p1f8/btrZat4myUq/szpDnxG7S7BO6DkvRAYUg0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc5p1f8%2FbtrZat4myUq%2FszpDnxG7S7BO6DkvRAYUg0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;401&quot; height=&quot;449&quot; data-filename=&quot;999DataBase - 0.jpg&quot; data-origin-width=&quot;710&quot; data-origin-height=&quot;795&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 테이블의 기본키를 그대로 참조하는 값.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 릴레이션의 기본키를 참조하는 속성 또는 속성들의 집합이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개체와의 관계를 식별하는데 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FK라고도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외래키로 지정되면 참조 릴레이션의 기본키에 없는 값은 입력할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외래키는 중복되어도 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림에서는 user_id가 외래키이고 a_2라는 값이 중복된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;후보키(candidate key)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본키가 될 수 있는 후보들.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유일성과 최소성을 동시에 만족한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;대체키(alternate key)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후보키가 두 개 이상일 경우 어느 하나를 기본키로 지정하고 남은 후보키.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;슈퍼키(super key)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 레코드를 유일하게 식별할 수 있는 유일성을 갖춘 키.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 릴레이션 내에 있는 속성들의 집합으로 구성된 키.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;릴레이션을 구성하는 모든 튜플 중 슈퍼키로 구성된 속성의 집합과 동일한 값은 나타나지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;슈퍼키는 릴레이션을 구성하는 모든 튜플에 대해 유일성은 만족하지만 &lt;b&gt;최소성은 만족하지 못한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;김정준, 시나공 정보처리기사 실기, 길벗(2022)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/DataBase</category>
      <category>db</category>
      <category>DB Key</category>
      <category>DB 키</category>
      <category>Operating System</category>
      <category>OS</category>
      <category>데이터베이스</category>
      <category>운영체제</category>
      <category>테이블 키</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/61</guid>
      <comments>https://hapen385.tistory.com/61#entry61comment</comments>
      <pubDate>Tue, 14 Feb 2023 00:15:00 +0900</pubDate>
    </item>
    <item>
      <title>[DataBase] 데이터베이스 관계(Relationship)</title>
      <link>https://hapen385.tistory.com/60</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스에는 여러 개의 테이블이 있고 이러한 테이블은 서로의 관계가 정의되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 관계는 관계화살표를 통해 나타낼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관계화살표는 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;erd_cookatrice.gif&quot; data-origin-width=&quot;456&quot; data-origin-height=&quot;166&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NSecg/btrZbqMIcbg/scMYtbqnX0QZI4EAENxoL1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NSecg/btrZbqMIcbg/scMYtbqnX0QZI4EAENxoL1/img.gif&quot; data-alt=&quot;출처 :&amp;amp;amp;nbsp;https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;amp;amp;blogId=xxsaintxx&amp;amp;amp;logNo=220518940689&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NSecg/btrZbqMIcbg/scMYtbqnX0QZI4EAENxoL1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/NSecg/btrZbqMIcbg/scMYtbqnX0QZI4EAENxoL1/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;385&quot; height=&quot;140&quot; data-filename=&quot;erd_cookatrice.gif&quot; data-origin-width=&quot;456&quot; data-origin-height=&quot;166&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;amp;nbsp;https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;amp;blogId=xxsaintxx&amp;amp;logNo=220518940689&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1:1 관계&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1DataBase - 0.jpg&quot; data-origin-width=&quot;660&quot; data-origin-height=&quot;443&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbkJ6I/btrY7LRCahi/4PhJ7BKioWCWKa6XXbnUL1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbkJ6I/btrY7LRCahi/4PhJ7BKioWCWKa6XXbnUL1/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbkJ6I/btrY7LRCahi/4PhJ7BKioWCWKa6XXbnUL1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbkJ6I%2FbtrY7LRCahi%2F4PhJ7BKioWCWKa6XXbnUL1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;407&quot; height=&quot;273&quot; data-filename=&quot;1DataBase - 0.jpg&quot; data-origin-width=&quot;660&quot; data-origin-height=&quot;443&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;어느 엔티티 쪽에서&amp;nbsp;상대 엔티티와 반드시 단 하나의 관계를 갖는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 위 그림처럼 유저 한 명 당 이메일이 한 개씩 존재한다면 유저와 이메일은 1:1 관계다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블을 두 개의 테이블로 나눠 테이블을 구조를 더 이해하기 쉽게 만들어준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1:N 관계&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;11DataBase - 0.jpg&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;527&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/E3J3P/btrZbrZaBXO/7GWxkZ6xwoZFmL1eevPGwk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/E3J3P/btrZbrZaBXO/7GWxkZ6xwoZFmL1eevPGwk/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/E3J3P/btrZbrZaBXO/7GWxkZ6xwoZFmL1eevPGwk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FE3J3P%2FbtrZbrZaBXO%2F7GWxkZ6xwoZFmL1eevPGwk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;398&quot; height=&quot;289&quot; data-filename=&quot;11DataBase - 0.jpg&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;527&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 개체가 다른 많은 개체를 포함하는 관계다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;한 쪽 엔티티가&amp;nbsp;관계를 맺은 엔티티 쪽의 여러 객체를 가질 수 있는 것을 말한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 쇼핑몰을 운영한다고 가정하면, 한 유저당 여러 개의 상품을 장바구니에 넣을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 경우 유저와 상품은 1:N 관계다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나도 넣지 않는 경우도 있으니 0이 포함되는 화살표를 그려야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;N:M 관계&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2DataBase - 0.jpg&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;830&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpoQ9z/btrZbOfsTUX/IGJsPqQ46loevj7CKbEdMk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpoQ9z/btrZbOfsTUX/IGJsPqQ46loevj7CKbEdMk/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpoQ9z/btrZbOfsTUX/IGJsPqQ46loevj7CKbEdMk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpoQ9z%2FbtrZbOfsTUX%2FIGJsPqQ46loevj7CKbEdMk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;392&quot; height=&quot;431&quot; data-filename=&quot;2DataBase - 0.jpg&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;830&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;관계를 가진&amp;nbsp;양쪽 엔티티 모두에서&amp;nbsp;1:N 관계를 가지는 것을 말한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;N:M은 테이블 두 개를 직접적으로 연결해서 구축하지 않고&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;1:N, 1:M 이라는 관계를 갖는 테이블 두 개로 나눈다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;위 그림에서는 학생과 강의의 관계를 통해 N:M을 설명하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;학생도 강의를 많이 들을 수 있고 강의도 여러 명의 학생을 포함할 수 있기 때문에 학생과 강의는 N:M의 관계가 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://velog.io/@gillog/DB-11-1N-NM-%EA%B4%80%EA%B3%84&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;gil.log&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/DataBase</category>
      <category>DB 관계</category>
      <category>Operating System</category>
      <category>OS</category>
      <category>데이터베이스</category>
      <category>운영체제</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/60</guid>
      <comments>https://hapen385.tistory.com/60#entry60comment</comments>
      <pubDate>Mon, 13 Feb 2023 22:35:19 +0900</pubDate>
    </item>
    <item>
      <title>[DataBase] 필드 타입</title>
      <link>https://hapen385.tistory.com/59</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;필드는 타입을 갖는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타입은 DBMS마다 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MySQL 타입으로 설명을 하면 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;숫자 타입&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;타입&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;용량(바이트)&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;최솟값(부호 있음)&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;최솟값(부호 없음)&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;최댓값(부호 없음)&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;최댓값(부호 있음)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;TINYINT&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;-128&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;127&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;255&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;SMALLINT&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;-32768&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;32767&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;65535&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;MEDIUMINT&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;3&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;-8388608&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;8388607&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;16777215&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;INT&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;-2147483648&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;2147483647&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;4294967295&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;BIGINT&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;-263&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;263-1&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;264-1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT 등이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숫자 타입은 &lt;b&gt;용량에 따라&lt;/b&gt; 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;날짜 타입&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;DATE&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간 없이 날짜만 나타낼 때 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지원 범위는 1000-01-01~9999-12-31&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3바이트의 용량을 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;DATETIME&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;날짜 및 시간을 모두 포함하는 값에 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;범위는 1000-01-01 00:00:00 ~ 9999:12-31 23:59:59&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8바이트의 용량을 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;TIMESTAMP&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;날짜 및 시간을 모두 포함하는 값에 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;범위는 1970-01-01 00:00:01 ~ 2038-01-19 03:14:07&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4바이트의 용량을 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;TIME&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간을 나타낼 때 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;범위는 -838:59:59 ~ 838:59:59&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;범위를 초과할 시 -838:59:59 이나 838:59:59로 자동 변환되어 저장된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유효하지 않은 시간은 00:00:00 으로 저장된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;문자 타입&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CHAR&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 안에 수를 입력해서 몇 자까지 입력할지 정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블을 생성할 때 선언한 길이로 고정된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;길이는 0~255 사이의 값을 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레코드를 저장할 때 무조건 선언한 길이로 &lt;b&gt;고정&lt;/b&gt;해서 저장된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;VARCHAR&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CHAR과 마찬가지로 몇 자 입력할지 정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 VARCHAR는 &lt;b&gt;가변&lt;/b&gt; 길이 문자열이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;길이는 0~65,535 사이의 값을 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력된 데이터에 따라 용량을 가변시켜 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10글자의 이메일을 저장할 경우, VARCHAR(10000)이라고 선언을 해도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10글자에 해당하는 바이트 + 길이 기록용 1바이트로 저장하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CHAR은 유동적이지 않은 길이를 가진 데이터에 효율적이고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VARCHAR은 유동적인 길이를 가진 데이터를 저장할 때 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;TEXT&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큰 데이터의 문자열을 저장할 때 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주로 게시판의 본문을 저장할 때 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;BLOB(Binary Large Object)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지, 동영상 등 큰 데이터 저장에 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ENUM&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문자열을 열거한 타입이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;열거한 요소 중 하나만 선택할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ENUM 리스트에 없는 잘못된 값을 삽입하면 빈 문자열이 대신 삽입된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최대 65,535개의 요소를 넣을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SET&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ENUM과 마찬가지로 문자열을 열거한 타입이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SET은 ENUM과 다르게 여러 개의 데이터를 선택할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비트 단위의 연산을 할 수 있으며&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최대 64개의 요소를 집어넣을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ENUM과 SET을 사용하면 공간적으로 이점(메모리를 적게 사용)을 볼 수 있으나&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애플리케이션의 수정에 따라 데이터베이스의 ENUM이나 SET에서 정의한 목록을 수정해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Science/DataBase</category>
      <category>Database</category>
      <category>db</category>
      <category>DB 타입</category>
      <category>MySQL 타입</category>
      <category>Operating System</category>
      <category>데이터베이스</category>
      <category>운영체제</category>
      <category>필드 타입</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/59</guid>
      <comments>https://hapen385.tistory.com/59#entry59comment</comments>
      <pubDate>Mon, 13 Feb 2023 20:40:37 +0900</pubDate>
    </item>
    <item>
      <title>[DataBase] 데이터베이스의 구성</title>
      <link>https://hapen385.tistory.com/58</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;데이터베이스(DB, DataBase)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일정한 규칙, 혹은 규약을 통해 구조화되어 저장되는 데이터의 모음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;데이터베이스의 특성&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;실시간 접근성&lt;/b&gt; : 질의에 대한 실시간 처리 및 응답&lt;/li&gt;
&lt;li&gt;&lt;b&gt;계속적인 변화&lt;/b&gt; : 갱신(update), 삽입(insert), 삭제(delete)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;동시 공유&lt;/b&gt; : 여러 사용자가 동시에 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;내용에 의한 참조&lt;/b&gt; : 데이터의 위치나 주소가 아닌 내용에 따라 참조&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;DBMS(DataBase Management System)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2023. 1. 27. - 0 9.jpg&quot; data-origin-width=&quot;526&quot; data-origin-height=&quot;501&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbXTr5/btrYYpOQrZT/ZGlPF5defwzr0E41hiq6NK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbXTr5/btrYYpOQrZT/ZGlPF5defwzr0E41hiq6NK/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbXTr5/btrYYpOQrZT/ZGlPF5defwzr0E41hiq6NK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbXTr5%2FbtrYYpOQrZT%2FZGlPF5defwzr0E41hiq6NK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;294&quot; height=&quot;280&quot; data-filename=&quot;2023. 1. 27. - 0 9.jpg&quot; data-origin-width=&quot;526&quot; data-origin-height=&quot;501&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스를 제어, 관리하는 통합 시스템을 DBMS이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;응용 프로그램과 데이터 사이의 중재자로서 모든 응용 프로그램(사용자)들이 데이터베이스를 공유할 수 있도록 관리해주는 소프트웨어 시스템이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스 안에 있는 데이터들은 특정 DBMS마다 정의된 쿼리 언어(query language)를 통해 삽입, 삭제, 수정, 조회를 수행할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스 위에 DBMS가 있고 그 위에 응용 프로그램이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 구조를 기반으로 데이터를 주고 받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 MySQL이 DBMS이고 Node.js가 응용 프로그램에 속한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;엔터티(Entity)&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2023. 1. 27. - 0 19.jpg&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;581&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWrJ1x/btrZa43COxD/vVBuYGfmTRwobCPXysXwi0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWrJ1x/btrZa43COxD/vVBuYGfmTRwobCPXysXwi0/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWrJ1x/btrZa43COxD/vVBuYGfmTRwobCPXysXwi0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWrJ1x%2FbtrZa43COxD%2FvVBuYGfmTRwobCPXysXwi0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;264&quot; height=&quot;263&quot; data-filename=&quot;2023. 1. 27. - 0 19.jpg&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;581&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사람, 장소, 물건, 사건, 개념 등 여러 개의 속성을 지닌 명사.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정보의 단위가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나 이상의 속성(attribute)으로 구성되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림에서는 회원이 엔터티가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엔터티의 속성은 서비스의 요구 사항에 맞춰 속성이 정해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 주소라는 속성이 서비스의 요구 사항과 무관하다면 이 속성은 사라진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;약한 엔터티와 강한 엔터티&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엔터티에는 약한 엔터티와 강한 엔터티가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 A 엔터티가 B 엔터티에 종속적이며, 혼자서는 존재하지 못한다면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A는 약한 엔터티, B는 강한 엔터티다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방은 약한 엔터티고, 건물은 강한 엔터티다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방은 건물 없이는 존재할 수 없기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;릴레이션(relation)&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 0.jpg&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;706&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxnJod/btrYV9r1f7L/EMeCDPckJxd6KSNuESVHM1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxnJod/btrYV9r1f7L/EMeCDPckJxd6KSNuESVHM1/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxnJod/btrYV9r1f7L/EMeCDPckJxd6KSNuESVHM1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxnJod%2FbtrYV9r1f7L%2FEMeCDPckJxd6KSNuESVHM1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;493&quot; height=&quot;315&quot; data-filename=&quot;DataBase - 0.jpg&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;706&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스에서 정보를 구분하여 저장하는 기본 단위.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엔터티에 관한 데이터를 데이터베이스는 릴레이션 하나에 담아 관리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림에서 엔터티가 데이터베이스에서 관리될 때, 릴레이션으로 변화된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;릴레이션은 관계형 데이터베이스에서는 테이블,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NoSQL 데이터베이스에서는 컬렉션 이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;릴레이션은 테이블과 유사한 개념이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 테이블은 다음과 같은 릴레이션의 특징을 만족하지 않아도 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;릴레이션의 특징&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;릴레이션은 튜플들의 집합이다.&lt;/li&gt;
&lt;li&gt;한 릴레이션에는 똑같은 튜플이 포함될 수 없으므로 릴레이션에 포함된 &lt;b&gt;튜플들은 모두 다르다&lt;/b&gt;.&lt;/li&gt;
&lt;li&gt;한 릴레이션에서 튜플들은 &lt;b&gt;순서가 없다&lt;/b&gt;.&lt;/li&gt;
&lt;li&gt;튜플들의 삽입, 삭제 등으로 릴레이션은 &lt;b&gt;시간에 따라 변한다&lt;/b&gt;.&lt;/li&gt;
&lt;li&gt;릴레이션 스키마를 구성하는 속성들 간의 순서는 중요하지 않다.&lt;/li&gt;
&lt;li&gt;속성의 유일한 식별을 위해 &lt;b&gt;속성의 명칭은 유일&lt;/b&gt;해야 하지만, &lt;b&gt;속성을 구성하는 값은 동일한 값&lt;/b&gt;이 있을 수 있다.&lt;/li&gt;
&lt;li&gt;릴레이션을 구성하는 튜플을 유일하게 식별하기 위해 속성들의 부분 집합을 키(Key)로 설정한다.&lt;/li&gt;
&lt;li&gt;애트리뷰트 값은 원자 값이다; &lt;b&gt;애트리뷰트 값은 논리적으로 분해가 불가능&lt;/b&gt;하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*&lt;b&gt;튜플(Tuple)&lt;/b&gt; : 릴레이션을 구성하는 각각의 행(Row)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*&lt;b&gt;스키마(Schema)&lt;/b&gt; : 데이터베이스의 구조와 제약조건에 관한 전반적인 명세를 기술한 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;테이블과 컬렉션&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 01.jpg&quot; data-origin-width=&quot;1213&quot; data-origin-height=&quot;752&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CxevL/btrZdfcormU/oKCtaBfwGnVfQwYK6pSrj1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CxevL/btrZdfcormU/oKCtaBfwGnVfQwYK6pSrj1/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CxevL/btrZdfcormU/oKCtaBfwGnVfQwYK6pSrj1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCxevL%2FbtrZdfcormU%2FoKCtaBfwGnVfQwYK6pSrj1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;539&quot; height=&quot;334&quot; data-filename=&quot;DataBase - 01.jpg&quot; data-origin-width=&quot;1213&quot; data-origin-height=&quot;752&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관계형 데이터베이스의 경우 구조는 레코드 - 테이블 - 데이터베이스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NoSQL 데이터베이스의 경우 구조는 도큐먼트 - 컬렉션 - 데이터베이스 로 이루어져 있다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림처럼 레코드가 쌓여서 테이블이 되고 테이블이 쌓여 데이터베이스가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;속성(attribute)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;릴레이션에서 관리하는 구체적이며 고유한 이름을 갖는 정보.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스의 요구 사항을 기반으로 관리해야 할 필요가 있는 속성만 엔터티의 속성이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;도메인(Domain)&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DataBase - 012.jpg&quot; data-origin-width=&quot;643&quot; data-origin-height=&quot;755&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HfWKV/btrZa5BRSqp/nc48PpQ5IQKx7CbfpUKkWK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HfWKV/btrZa5BRSqp/nc48PpQ5IQKx7CbfpUKkWK/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HfWKV/btrZa5BRSqp/nc48PpQ5IQKx7CbfpUKkWK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHfWKV%2FbtrZa5BRSqp%2Fnc48PpQ5IQKx7CbfpUKkWK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;352&quot; data-filename=&quot;DataBase - 012.jpg&quot; data-origin-width=&quot;643&quot; data-origin-height=&quot;755&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;릴레이션에 포함된 각각의 속성들이 가질 수 있는 값의 집합.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 성별이라는 속성의 도메인은 {남, 여} 가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림에서는 회원이라는 릴레이션에 이름, 아이디, 주소, 전화번호, 성별이라는 속성, {남, 여} 라는 도메인을 나타내고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;필드와 레코드&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;D1ataBase - 0.jpg&quot; data-origin-width=&quot;975&quot; data-origin-height=&quot;515&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mR7Ef/btrY8hW8wH1/kScuVu4kmiCcLYjVRbj4S0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mR7Ef/btrY8hW8wH1/kScuVu4kmiCcLYjVRbj4S0/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mR7Ef/btrY8hW8wH1/kScuVu4kmiCcLYjVRbj4S0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmR7Ef%2FbtrY8hW8wH1%2FkScuVu4kmiCcLYjVRbj4S0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;546&quot; height=&quot;288&quot; data-filename=&quot;D1ataBase - 0.jpg&quot; data-origin-width=&quot;975&quot; data-origin-height=&quot;515&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림에서 필드는 name, ID, addres, phonenumber 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레코드는 테이블에 쌓이는 행(row) 단위의 데이터를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필드는 파일 시스템에서 사용되는 용어이기도 하다. 필드를 속성(attribute)로 말하기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레코드도 파일 시스템에서 사용되며 튜플과 동일한 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333;&quot;&gt;이석호, 데이터베이스론, 정익사(2010)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333;&quot;&gt;김정준, 시나공 정보처리기사 실기, 길벗(2022)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/DataBase</category>
      <category>db</category>
      <category>dbms</category>
      <category>Operating System</category>
      <category>데이터베이스</category>
      <category>레코드</category>
      <category>운영체제</category>
      <category>테이블</category>
      <category>필드</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/58</guid>
      <comments>https://hapen385.tistory.com/58#entry58comment</comments>
      <pubDate>Mon, 13 Feb 2023 19:20:39 +0900</pubDate>
    </item>
    <item>
      <title>[Operating System] CPU 스케줄링 알고리즘</title>
      <link>https://hapen385.tistory.com/57</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;CPU 스케줄링 알고리즘&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;cpu2023. 1. 27. - 0 9.jpg&quot; data-origin-width=&quot;1176&quot; data-origin-height=&quot;682&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VE6mw/btrYTNgSW9A/pMSgZtrMHZ3LYW2f3TmqR0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VE6mw/btrYTNgSW9A/pMSgZtrMHZ3LYW2f3TmqR0/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VE6mw/btrYTNgSW9A/pMSgZtrMHZ3LYW2f3TmqR0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVE6mw%2FbtrYTNgSW9A%2FpMSgZtrMHZ3LYW2f3TmqR0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;565&quot; height=&quot;328&quot; data-filename=&quot;cpu2023. 1. 27. - 0 9.jpg&quot; data-origin-width=&quot;1176&quot; data-origin-height=&quot;682&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU 스케줄러는 CPU 스케줄링 알고리즘에 따라 프로세스에서 해야하는 일을 스레드 단위로 CPU에 할당한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램이 실행될 때 CPU 스케줄링 알고리즘이 어떤 프로그램에 CPU 소유권을 줄 지 결정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU 스케줄링 알고리즘은 CPU 이용률은 높게,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주어진 시간에 많은 일을 하게,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;준비 큐(ready queue)에 있는 프로세스는 적게,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;응답 시간은 짧게 설정하는 것을 목표로 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;비선점형 방식(non-preemtive)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스가 스스로 CPU 소유권을 포기하는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강제로 프로세스를 중지하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 컨텍스트 스위칭으로 인한 부하가 적다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 CPU 사용 시간이 긴 프로세스 때문에 CPU 사용 시간이 짧은 여러 프로세스가 오랫동안 기다리게 되어 전체 시스템의 처리율이 좋지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;FCFS(First Come, First Served)&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;준비 큐에 가장 먼저 온 것을 가장 먼저 처리하는 알고리즘.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 번 실행되면 그 프로세스가 끝나야지 다음 프로세스를 실행할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 74px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;Process&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;실행시간&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;P1&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;P2&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;P3&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 프로세스와 실행시간이 있고 CPU 스케줄러가 FCFS에 따라 일을 처리한다고 가정하면 다음과 같은 실행 순서를 갖게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;5_FCFS_Chart.jpeg&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;109&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjXqxR/btrYTqfgvi9/hazomzdxuljzKJhJbKkErK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjXqxR/btrYTqfgvi9/hazomzdxuljzKJhJbKkErK/img.jpg&quot; data-alt=&quot;출처 :&amp;amp;nbsp;Abraham Silberschatz, Greg Gagne, and Peter Baer Galvin, &amp;quot;Operating System Concepts, Eighth Edition &amp;quot;, Chapter 5&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjXqxR/btrYTqfgvi9/hazomzdxuljzKJhJbKkErK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjXqxR%2FbtrYTqfgvi9%2FhazomzdxuljzKJhJbKkErK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;731&quot; height=&quot;109&quot; data-filename=&quot;5_FCFS_Chart.jpeg&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;109&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;nbsp;Abraham Silberschatz, Greg Gagne, and Peter Baer Galvin, &quot;Operating System Concepts, Eighth Edition &quot;, Chapter 5&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스가 도착하는 순서는 P1, P2, P3이라고 하면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 실행 시간이 긴 P1이 먼저 실행되고 P2, P3이 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 P1처럼 실행 시간이 긴 프로세스가 먼저 오게되면 다른 프로세스들이 준비 큐에서 오래 기다리게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이와 같은 현상을 &lt;b&gt;convoy effect&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SJF(Shortest Job First)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 시간이 가장 짧은 프로세스를 가장 먼저 실행하는 알고리즘.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 74px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;Process&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;실행시간&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;P1&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;P2&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;P3&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;P4&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 프로세스와 실행시간이 있고 CPU 스케줄러가 SJF에 따라 일을 처리한다고 가정하면 다음과 같은 실행 순서를 갖게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;5_SJF_Chart.jpeg&quot; data-origin-width=&quot;717&quot; data-origin-height=&quot;95&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Eldff/btrYTqfgBVp/r3sPEK7UQ9bxxomZuEKrV1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Eldff/btrYTqfgBVp/r3sPEK7UQ9bxxomZuEKrV1/img.jpg&quot; data-alt=&quot;출처 :&amp;amp;nbsp;Abraham Silberschatz, Greg Gagne, and Peter Baer Galvin, &amp;quot;Operating System Concepts, Eighth Edition &amp;quot;, Chapter 5&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Eldff/btrYTqfgBVp/r3sPEK7UQ9bxxomZuEKrV1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEldff%2FbtrYTqfgBVp%2Fr3sPEK7UQ9bxxomZuEKrV1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;717&quot; height=&quot;95&quot; data-filename=&quot;5_SJF_Chart.jpeg&quot; data-origin-width=&quot;717&quot; data-origin-height=&quot;95&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;nbsp;Abraham Silberschatz, Greg Gagne, and Peter Baer Galvin, &quot;Operating System Concepts, Eighth Edition &quot;, Chapter 5&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 실행 시간이 짧은 P4가 실행되고 그 다음 순으로 P1, P3, P2가 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(실제로는 실행 시간을 알 수 없으므로 과거의 실행 시간을 토대로 추측해서 사용하는 경우가 있다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 긴 시간을 가진 프로세스가 실행되지 않는 현상(starvation)이 일어난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;평균 대기 시간이 가장 짧다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;우선순위&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선순위를 높이는 방법(aging)을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스가 자신의 순서를 양보할 때마다 나이를 한 살씩 먹어 최대 몇 살까지 양보하도록 규정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 SJF 스케줄링의 경우 긴 시간을 가진 프로세스가 실행되지 않는 문제가 있었지만 우선순위 방식은 이를 보완한 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;선점형 방식(preemptive)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 사용하고 있는 프로세스는 알고리즘에 의해 중단시켜 버리고 강제로 다른 프로세스에 CPU 소유권을 할당하는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현대 운영체제가 쓰는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;라운드 로빈(RR, Round Robin)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 프로세스는 동일한 할당 시간을 주고 그 시간 안에 끝나지 않으면 다시 준비 큐의 뒤로 가는 알고리즘이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현대 컴퓨터가 쓰는 스케줄링인 우선순위 스케줄링(priority scheduling)의 일종이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 74px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;Process&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;실행 시간&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;P1&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;P2&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;P3&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 프로세스와 실행시간이 있고 CPU 스케줄러가 RR에 따라 일을 처리한다고 가정하면 다음과 같은 실행 순서를 갖게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;5_RoundRobinChart.jpeg&quot; data-origin-width=&quot;733&quot; data-origin-height=&quot;103&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yHf5M/btrYXkkODU0/QkNAHhWMCksnopHPd0jNoK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yHf5M/btrYXkkODU0/QkNAHhWMCksnopHPd0jNoK/img.jpg&quot; data-alt=&quot;출처 :&amp;amp;nbsp;Abraham Silberschatz, Greg Gagne, and Peter Baer Galvin, &amp;quot;Operating System Concepts, Eighth Edition &amp;quot;, Chapter 5&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yHf5M/btrYXkkODU0/QkNAHhWMCksnopHPd0jNoK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyHf5M%2FbtrYXkkODU0%2FQkNAHhWMCksnopHPd0jNoK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;733&quot; height=&quot;103&quot; data-filename=&quot;5_RoundRobinChart.jpeg&quot; data-origin-width=&quot;733&quot; data-origin-height=&quot;103&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;nbsp;Abraham Silberschatz, Greg Gagne, and Peter Baer Galvin, &quot;Operating System Concepts, Eighth Edition &quot;, Chapter 5&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 할당 시간이 4ms라고 하면 위 그림과 같이 프로세스가 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P1의 실행 시간은 24인데 4ms 사용할 수 있으므로 실행하다가 쫓겨난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P2는 실행 시간이 3이라서 할당 시간 내에 다 실행되므로 계속 실행되고 종료될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P3의 경우도 P2와 마찬가지라서 실행된 후 종료까지 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P1의 경우는 P2, P3가 종료까지 되고 나서도 계속 실행 시간이 남아있어서 4ms 실행되고 끝난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;할당 시간이 너무 크면 FCFS가 되고 짧으면 컨텍스트 스위칭이 잦아져 오버헤드가 커진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 전체 작업 시간은 길어지지만, 평균 응답 시간은 짧아진다는 특징이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로드밸런서에서 트래픽 분산 알고리즘으로 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SRF&lt;span style=&quot;color: #333333;&quot;&gt;(Shortest Remaining Time First)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중간에 더 짧은 작업이 들어오면 수행하던 프로세스를 중지하고 해당 프로세스를 수행하는 알고리즘이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SJF는 중간에 더 짧은 작업이 들어와도 기존의 작업을 모두 수행하고 다음 짧은 작업으로 넘어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 92px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 20px;&quot;&gt;Process&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 20px;&quot;&gt;도착 시간&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 20px;&quot;&gt;실행 시간&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 18px;&quot;&gt;P1&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 18px;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 18px;&quot;&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 18px;&quot;&gt;P2&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 18px;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 18px;&quot;&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 18px;&quot;&gt;P3&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 18px;&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 18px;&quot;&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 18px;&quot;&gt;P4&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 18px;&quot;&gt;3&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 18px;&quot;&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 프로세스와 실행시간이 있고 CPU 스케줄러가 SRF에 따라 일을 처리한다고 가정하면 다음과 같은 실행 순서를 갖게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;5_PreemptiveSJF_Chart.jpeg&quot; data-origin-width=&quot;754&quot; data-origin-height=&quot;130&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VsrKk/btrYTptVvWQ/mIDtVla1Od2pnGfvlsQWn0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VsrKk/btrYTptVvWQ/mIDtVla1Od2pnGfvlsQWn0/img.jpg&quot; data-alt=&quot;출처 :&amp;amp;nbsp;Abraham Silberschatz, Greg Gagne, and Peter Baer Galvin, &amp;quot;Operating System Concepts, Eighth Edition &amp;quot;, Chapter 5&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VsrKk/btrYTptVvWQ/mIDtVla1Od2pnGfvlsQWn0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVsrKk%2FbtrYTptVvWQ%2FmIDtVla1Od2pnGfvlsQWn0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;754&quot; height=&quot;130&quot; data-filename=&quot;5_PreemptiveSJF_Chart.jpeg&quot; data-origin-width=&quot;754&quot; data-origin-height=&quot;130&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;nbsp;Abraham Silberschatz, Greg Gagne, and Peter Baer Galvin, &quot;Operating System Concepts, Eighth Edition &quot;, Chapter 5&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제일 빨리 들어온 것은 P1 이었지만 P1의 실행 시간인 8보다 짧은 P2가 중간에 들어와서 중간에 P2를 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P2를 실행하던 중에 P3이 들어오지만 P2보다는 실행 시간(9)이 길어서 P2는 계속 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 P4도 들어오지만 P2보다 실행 시간이 길어서(P2 = 4, P4 = 5) P2가 다 끝나야 P4가 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P4가 다 실행되고 중간에 하다가 만 P1의 남은 실행 시간이 P3보다 짧아서(P1 = 7, P3 = 9) P1부터 실행하고 P3를 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;다단계 큐&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;queue2023. 1. 27. - 0 9.jpg&quot; data-origin-width=&quot;1146&quot; data-origin-height=&quot;507&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AZir3/btrYRwgonxS/JNXq1nU9OSiOZtklTXoA21/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AZir3/btrYRwgonxS/JNXq1nU9OSiOZtklTXoA21/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AZir3/btrYRwgonxS/JNXq1nU9OSiOZtklTXoA21/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAZir3%2FbtrYRwgonxS%2FJNXq1nU9OSiOZtklTXoA21%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;573&quot; height=&quot;254&quot; data-filename=&quot;queue2023. 1. 27. - 0 9.jpg&quot; data-origin-width=&quot;1146&quot; data-origin-height=&quot;507&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선순위에 따른 준비 큐를 여러 개 사용하고, 큐마다 라운드 로빈이나 FCFS 등 다른 스케줄링 알고리즘을 적용한 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상단의 큐에 있는 모든 프로세스의 작업이 끝나야 다음 우선순위 큐의 작업이 시작된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큐 간의 프로세스 이동이 안되므로 스케줄링 부담이 적지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유연성이 좋지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;li&gt;조성호, 쉽게 배우는 운영체제, 한빛아카데미(2018)&lt;/li&gt;
&lt;li&gt;Abraham Silberschatz, Greg Gagne, and Peter Baer Galvin, &quot;Operating System Concepts, Eighth Edition &quot;, Chapter 5&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/Operating System</category>
      <category>CPU스케줄링</category>
      <category>CPU스케줄링 알고리즘</category>
      <category>FCFS</category>
      <category>Operating System</category>
      <category>OS</category>
      <category>SJF</category>
      <category>SRF</category>
      <category>라운드로빈</category>
      <category>운영체제</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/57</guid>
      <comments>https://hapen385.tistory.com/57#entry57comment</comments>
      <pubDate>Sat, 11 Feb 2023 03:30:27 +0900</pubDate>
    </item>
    <item>
      <title>[Operating System] 교착 상태(deadlock)</title>
      <link>https://hapen385.tistory.com/56</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;교착 상태(deadlock)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 개 이상의 프로세스들이 서로가 가진 자원을 기다리며 중단된 상태를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;교착 상태의 원인&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;상호 배제&lt;/b&gt; : 한 프로세스가 자원을 독점하고 있으며 다른 프로세스들은 접근이 불가능하다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;점유 대기&lt;/b&gt; : 특정 프로세스가 점유한 자원을 다른 프로세스가 요청하는 상태.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;비선점&lt;/b&gt; : 다른 프로세스의 자원을 강제적으로 가져올 수 없다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;환형 대기&lt;/b&gt; : 프로세스 A는 프로세스 B의 자원을 요구하고, 프로세스 B는 프로세스 A의 자원을 요구하는 등 서로가 서로의 자원을 요구하는 상황&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;교착 상태의 해결 방법&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;자원을 할당할 때 &lt;b&gt;애초에 조건이 성립되지 않도록&lt;/b&gt; 설계한다. (하지만 자원을 보호하기 위해 상호 배제와 비선점을 예방하기 어렵다)&lt;/li&gt;
&lt;li&gt;교착 상태 &lt;b&gt;가능성이 없을 때만 자원이 할당&lt;/b&gt;되며, 프로세스 당 요청할 자원들의 최대치를 통해 자원할당 가능 여부를 파악하는 &lt;b&gt;은행원 알고리즘&lt;/b&gt;을 사용한다.&lt;/li&gt;
&lt;li&gt;교착 상태가 발생하면 &lt;b&gt;사이클이 있는지&lt;/b&gt; 찾아보고 이에 관련된 프로세스를 한 개씩 지운다.&lt;/li&gt;
&lt;li&gt;교착 상태는 매우 드물게 일어나므로 이를 처리하는 비용이 더 크다. 따라서 교착 상태가 발생하면 &lt;b&gt;사용자가 작업을 종료&lt;/b&gt;한다. 현대 운영체제는 이 방법을 채택했다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;안정 상태와 불안정 상태&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;교착 상태의 해결을 이야기 할 때 안정 상태와 불안정 상태의 개념이 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;자원의 총 수와 현재 할당된 자원의 수&lt;/b&gt;를 기준으로 시스템을 안정 상태와 불안정 상태로 나눈다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스템이 &lt;b&gt;안정 상태를 유지하도록&lt;/b&gt; 자원을 할당한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;할당된 자원이 적으면 안정 상태가 크고, 할당된 자원이 늘어날수록 불안정 상태가 커진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안정 상태는 시스템이 교착 상태를 일으키지 않고 각 프로세스가 요구한 양만큼 자원을 할당해줄 수 있는 상태다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;교착 상태는 불안정 상태일때만 발생하고 반대로 불안정 상태라 해서 무조건 교착 상태는 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;교착 상태는 불안정 상태의 일부분이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;불안정 상태가 커질수록 교착 상태가 발생할 가능성이 높아진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;교착 상태의 해결은 안정 상태를 유지할 수 있는 범위 내에서 자원을 할당함으로써 교착 상태를 피하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;은행원 알고리즘&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;총 자원의 양과 현재 할당한 자원의 양을 기준으로 안정 또는 불안정 상태로 나누고 안정 상태로 가도록 자원을 할당하는 알고리즘.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안정 상태를 유지할 수 있는 요구만을 수락한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;은행이 대출을 해주는 방식이며, 대출 금액이 대출 가능한 범위 내이면(안정 상태이면) 허용되지만 그렇지 않으면 거부되는 것과 유사한 방식이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;은행원 알고리즘에 사용되는 변수&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;전체 자원(Total)&lt;/b&gt; : 시스템 내 전체 자원의 수. 예)프린터, 모니터의 개수&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;가용 자원(Available)&lt;/b&gt; : 시스템 내 현재 사용할 수 있는 자원의 수(가용 자원 = 전체 자원 - 모든 프로세스의 할당 자원)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최대 자원(Max)&lt;/b&gt; : 각 프로세스가 선언한 최대 자원의 수(시작 전에 선언해야 한다)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;할당 자원(Allocation)&lt;/b&gt; : 각 프로세스에 할당된 자원의 수&lt;/li&gt;
&lt;li&gt;&lt;b&gt;기대 자원(Expect, Need)&lt;/b&gt; : 각 프로세스가 앞으로 사용할 자원의 수(기대 자원 = 최대 자원 - 할당 자원)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;은행원 알고리즘에서 자원 할당 기준&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요청한 자원을 할당해 준 뒤에도 시스템이 안정 상태라면 그 요청을 수락.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0097.PNG&quot; data-origin-width=&quot;941&quot; data-origin-height=&quot;527&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dea5lL/btrYRRdJE9T/FhK8bwMoekWrhvO6avBfC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dea5lL/btrYRRdJE9T/FhK8bwMoekWrhvO6avBfC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dea5lL/btrYRRdJE9T/FhK8bwMoekWrhvO6avBfC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdea5lL%2FbtrYRRdJE9T%2FFhK8bwMoekWrhvO6avBfC0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;594&quot; height=&quot;333&quot; data-filename=&quot;IMG_0097.PNG&quot; data-origin-width=&quot;941&quot; data-origin-height=&quot;527&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 시점에 위 사진과 같은 프로세스 0,1,2,3,4와 자원 A,B,C가 있다고 가정하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 사용할 수 있는 자원의 수(Available)를 고려해서 어떤 프로세스를 수락할 수 있을지 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 프로세스가 요구하는 자원의 수를 계산한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0099.jpg&quot; data-origin-width=&quot;1219&quot; data-origin-height=&quot;539&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfiJ85/btrYUunYZCl/OM2O9UavLB3KbCKDo5UFlK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfiJ85/btrYUunYZCl/OM2O9UavLB3KbCKDo5UFlK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfiJ85/btrYUunYZCl/OM2O9UavLB3KbCKDo5UFlK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfiJ85%2FbtrYUunYZCl%2FOM2O9UavLB3KbCKDo5UFlK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;672&quot; height=&quot;297&quot; data-filename=&quot;IMG_0099.jpg&quot; data-origin-width=&quot;1219&quot; data-origin-height=&quot;539&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스가 요구하는 자원의 수(Need)는 최대 자원(Max) - 할당 자원(Allocation)이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 자원의 수가 A = 3, B = 3, C = 2 이므로 프로세스 1이나 3의 요청을 수락할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 작은 인덱스를 선택한다고 하면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스 1을 선택 후, 사용가능한 자원의 수(Available)는 (3 3 2) - (1 2 2) = (2 1 0)가 되며&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스 1에 할당된 자원의 수(Allocation 1)는 (2 0 0) + (1 2 2) = (3 2 2)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 프로세스 1에 자원을 할당하고 시간이 지나면 프로세스 1은 작업을 끝낸다고 본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 다음에 또 같은 방식으로 사용가능한 자원의 수(Available)를 구하여 어떤 순서로 프로세스가 실행되는지 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 순서를 safe sequence라고 하며 이는 각 프로세스의 Need를 어떤 순서대로 만족시켜 줄 수 있을 때의 순서를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;li&gt;조성호, 쉽게 배우는 운영체제, 한빛아카데미(2018)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dev-jy.tistory.com/51&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;배워서나줘&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/Operating System</category>
      <category>Deadlock</category>
      <category>Operating System</category>
      <category>OS</category>
      <category>교착상태</category>
      <category>데드락</category>
      <category>운영체제</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/56</guid>
      <comments>https://hapen385.tistory.com/56#entry56comment</comments>
      <pubDate>Sat, 11 Feb 2023 03:05:41 +0900</pubDate>
    </item>
    <item>
      <title>[Operating System] 공유 자원과 임계 영역</title>
      <link>https://hapen385.tistory.com/55</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;공유 자원(shared resource)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스템 안에서 각 프로세스, 스레드가 함께 접근할 수 있는 모니터, 프린터, 메모리, 파일, 데이터 등의 자원이나 변수 등을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;sharedresource.jpg&quot; data-origin-width=&quot;1120&quot; data-origin-height=&quot;920&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brLW4t/btrYTVslAwD/rShaibeVwlLlPNzrTapod0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brLW4t/btrYTVslAwD/rShaibeVwlLlPNzrTapod0/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brLW4t/btrYTVslAwD/rShaibeVwlLlPNzrTapod0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrLW4t%2FbtrYTVslAwD%2FrShaibeVwlLlPNzrTapod0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;476&quot; height=&quot;391&quot; data-filename=&quot;sharedresource.jpg&quot; data-origin-width=&quot;1120&quot; data-origin-height=&quot;920&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 공유 자원을 두 개 이상의 프로세스가 동시에 읽거나 쓰는 상황을 &lt;b&gt;경쟁 상태(race condition)&lt;/b&gt;이라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동시에 접근을 시도할 때 접근의 타이밍이나 순서 등이 결괏값에 영향을 줄 수 있는 상태인 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 경쟁 상태가 발생하면 공유 자원 접근 순서에 따라 실행 결과가 달라질 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림과 같이 프로세스 A와 B가 동시에 접근하여 경쟁 상태가 발생할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 결과 값이 맞지 않는 값이 출력되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;임계 영역(critical section)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘 이상의 프로세스, 스레드가 공유 자원에 접근할 때 순서 등의 이유로 결과가 달라지는 코드 영역이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;임계 영역을 해결하기 위한 방법은 뮤텍스, 세마포어, 모니터로 크게 세 가지가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법은 모두 상호 배제, 한정 대기, 융통성 조건을 만족한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* &lt;b&gt;상호 배제&lt;/b&gt; : 한 프로세스가 임계 영역에 들어갔을 때 다른 프로세스는 들어갈 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* &lt;b&gt;한정 대기&lt;/b&gt; : 특정 프로세스가 영원히 임계 영역에 들어가지 못하면 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* &lt;b&gt;융통성&lt;/b&gt; : 한 프로세스가 다른 프로세스의 일을 방해해서는 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세 방법의 토대가 되는 매커니즘은 잠금(lock)이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 임계 영역이 화장실이라면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;화장실에 어떤 사람이 들어가고 문을 잠근 후 다른 사람이 이 사람이 나오기를 기다리다가 나오면 화장실을 쓰는 것과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;뮤텍스(mutex)&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;12023. 1. 27. - 0 9.jpg&quot; data-origin-width=&quot;865&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cS4DHJ/btrYRk8jfYq/BgoDw9ekJFCKUKf8cc8YJK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cS4DHJ/btrYRk8jfYq/BgoDw9ekJFCKUKf8cc8YJK/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cS4DHJ/btrYRk8jfYq/BgoDw9ekJFCKUKf8cc8YJK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcS4DHJ%2FbtrYRk8jfYq%2FBgoDw9ekJFCKUKf8cc8YJK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;480&quot; height=&quot;240&quot; data-filename=&quot;12023. 1. 27. - 0 9.jpg&quot; data-origin-width=&quot;865&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스가 스레드가 공유 자원을 lock()을 통해 잠금 설정하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용한 후에는 unlock()을 통해 잠금 해제하는 객체를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잠금이 설정되면 다른 프로세스나 스레드는 잠긴 코드 영역에 접근할 수 없고 해제는 그와 반대다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뮤텍스는 잠금 또는 잠금 해제라는 상태만 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;세마포어(semaphore)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반화된 뮤텍스를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 정수 값과 두 가지 함수 wait(P 함수), signal(V 함수)로 공유 자원에 대한 접근을 처리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;wait() : 자신의 차례가 올 때까지 기다리는 함수&lt;/li&gt;
&lt;li&gt;signal() : 다음 프로세스로 순서를 넘겨주는 함수&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;52023. 1. 27. - 0 10.jpg&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;639&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/coZIHu/btrYRWlwTsN/N2DFdF55V2dWOAAKFHptL0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/coZIHu/btrYRWlwTsN/N2DFdF55V2dWOAAKFHptL0/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/coZIHu/btrYRWlwTsN/N2DFdF55V2dWOAAKFHptL0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcoZIHu%2FbtrYRWlwTsN%2FN2DFdF55V2dWOAAKFHptL0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;448&quot; height=&quot;353&quot; data-filename=&quot;52023. 1. 27. - 0 10.jpg&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;639&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스나 스레드가 공유 자원에 접근하면 세마포어에서 wait() 작업을 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스나 스레드가 공유 자원을 해제하면 세마포어에서 signal() 작업을 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세마포어에는 조건 변수가 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스나 스레드가 세마포어 값을 수정할 때 다른 프로세스나 스레드는 동시에 세마포어 값을 수정할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;바이너리 세마포어&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0과 1의 두 가지 값만 가질 수 있는 세마포어.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뮤텍스와 구현의 유사성이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 뮤텍스는 잠금을 기반으로 상호 배제가 일어나는 잠금 매커니즘이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세마포어는 신호를 기반으로 상호 배제가 일어나는 신호 매커니즘이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신호 매커니즘은 휴대폰에서 노래를 듣다가 친구로부터 전화가 오면 노래가 중지되고 통화 처리 작업에 관한 인터페이스가 등장하는 것과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;카운팅 세마포어&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 개의 값을 가질 수 있는 세마포어다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 자원에 대한 접근을 제어하는 데 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;모니터&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘 이상의 스레드나 프로세스가 공유 자원에 안전하게 접근할 수 있도록&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공유 자원을 숨기고&lt;/b&gt; 해당 접근에 대해 인터페이스만 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;42023. 1. 27. - 0 11.jpg&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;687&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eO3Hyz/btrYUTATwpO/jh6yQAAI0q7fIZaRqaK2CK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eO3Hyz/btrYUTATwpO/jh6yQAAI0q7fIZaRqaK2CK/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eO3Hyz/btrYUTATwpO/jh6yQAAI0q7fIZaRqaK2CK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeO3Hyz%2FbtrYUTATwpO%2Fjh6yQAAI0q7fIZaRqaK2CK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;450&quot; height=&quot;391&quot; data-filename=&quot;42023. 1. 27. - 0 11.jpg&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;687&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림과 같이 모니터는 모니터 큐를 통해 공유 자원에 대한 작업을 순차적으로 처리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모니터는 세마포어보다 구현하기 쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모니터는 &lt;b&gt;상호 배제는 자동&lt;/b&gt;인 반면 세마포어에서는 상호 배제를 명시적으로 구현해야 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;li&gt;조성호, 쉽게 배우는 운영체제, 한빛아카데미(2018)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/Operating System</category>
      <category>cs</category>
      <category>Operating System</category>
      <category>OS</category>
      <category>공유자원</category>
      <category>모니터</category>
      <category>뮤텍스</category>
      <category>세마포어</category>
      <category>운영체제</category>
      <category>임계영역</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/55</guid>
      <comments>https://hapen385.tistory.com/55#entry55comment</comments>
      <pubDate>Sat, 11 Feb 2023 02:40:27 +0900</pubDate>
    </item>
    <item>
      <title>[Operating System] 멀티 프로세싱과 멀티 스레딩</title>
      <link>https://hapen385.tistory.com/54</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;멀티 프로세싱&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;여러 개의 프로세스&lt;/b&gt;를 통해 두 가지 이상의 일을 수행할 수 있는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 하나의 일을 병렬로 처리할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 프로세스의 메모리, 프로세스 중 일부에 문제가 발생되더라도,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 프로세스를 이용해서 처리할 수 있으므로 &lt;b&gt;신뢰성이 높은 강점&lt;/b&gt;이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;웹 브라우저의 멀티 프로세스&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 브라우저는 멀티 프로세스 구조를 갖고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 브라우저에는 여러 프로세스가 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;브라우저 프로세스&lt;/b&gt; : 주소 표시줄, 북마크 막대, 뒤로 가기 버튼, 앞으로 가기 버튼 등을 담당. 네트워크 요청이나 파일 접근 같은 권한을 담당.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;렌더러 프로세스&lt;/b&gt; : 웹 사이트가 보이는 부분의 모든 것을 제어.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;플러그인 프로세스&lt;/b&gt; : 웹 사이트에서 사용하는 플러그인을 제어.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;GPU 프로세스&lt;/b&gt; : GPU를 이용해서 화면을 그리는 부분을 제어.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;프로세스 간 통신(IPC)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멀티 프로세스는 IPC(Inter Process Communication)이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IPC는 &lt;b&gt;프로세스끼리 데이터를 주고받고 공유 데이터를 관리&lt;/b&gt;하는 메커니즘이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IPC의 예로는 클라이언트와 서버가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트는 데이터를 요청하고 서버는 클라이언트 요청에 응답하는 것은 IPC의 예가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IPC는 메모리가 완전히 공유되는 스레드보다는 속도가 느리다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 IPC에는 공유 메모리, 파일, 소켓, 익명 파이프, 명명 파이프, 메시지 큐가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;공유 메모리(shared memory)&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2023. 1. 27. - 0 449.jpg&quot; data-origin-width=&quot;547&quot; data-origin-height=&quot;404&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/druQex/btrYRVNFvdu/MENRO2HuGk1h56QOvBrPk1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/druQex/btrYRVNFvdu/MENRO2HuGk1h56QOvBrPk1/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/druQex/btrYRVNFvdu/MENRO2HuGk1h56QOvBrPk1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdruQex%2FbtrYRVNFvdu%2FMENRO2HuGk1h56QOvBrPk1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;350&quot; height=&quot;259&quot; data-filename=&quot;2023. 1. 27. - 0 449.jpg&quot; data-origin-width=&quot;547&quot; data-origin-height=&quot;404&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;여러 프로세스에 동일한 메모리 블록에 대한 접근 권한이 부여되어,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스가 서로 통신할 수 있도록 &lt;b&gt;공유 버퍼를 생성&lt;/b&gt;하는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로는 각 프로세스의 메모리를 다른 프로세스가 접근할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 공유 메모리를 통해 하나의 메모리를 공유할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IPC 방식 중 어떠한 매개체를 통해 데이터를 주고받는 것이 아닌 메모리 자체를 공유하기 때문에,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;불필요한 데이터 복사의 오버헤드가 발생하지 않아 가장 빠르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 같은 메모리 영역을 여러 프로세스가 공유하기 때문에 동기화가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하드웨어 관점에서 공유 메모리는 CPU가 접근할 수 있는 큰 랜덤 접근 메모리인 RAM을 가리키기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;파일&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일은 디스크에 저장된 데이터,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹은 파일 서버에서 제공한 데이터를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 기반으로 프로세스 간 통신을 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 프로세스 A,B가 파일을 통해 통신한다고 하면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A,B 프로세스의 사용자가 자기들끼리 공유하는 파일을 하나 열어놓고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일에 데이터를 쓰고 읽는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;소켓&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동일한 컴퓨터의 다른 프로세스나 네트워크의 다른 컴퓨터로 네트워크 인터페이스를 통해 전송하는 데이터를 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소켓을 이용한 IPC는 소켓을 매개로 한쪽의 프로세스와 반대쪽의 프로세스를 연결하는 작업이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;통신하고자 하는 프로세스는 자신의 소켓과 상대의 소켓을 연결한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스템에 있는 프로세스가 소켓을 바인딩한 후,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소켓에 쓰기 연산을 하면 데이터가 전송되고 읽기 연산을 하면 데이터를 받게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예로는 TCP와 UDP가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;익명 파이프(unamed pipe)&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2023. 1. 27. - 0 99.jpg&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;326&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxYlh0/btrYTNA8ktL/t4OcyF3ppuAyGmGX2DDqX1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxYlh0/btrYTNA8ktL/t4OcyF3ppuAyGmGX2DDqX1/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxYlh0/btrYTNA8ktL/t4OcyF3ppuAyGmGX2DDqX1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxYlh0%2FbtrYTNA8ktL%2Ft4OcyF3ppuAyGmGX2DDqX1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;457&quot; height=&quot;207&quot; data-filename=&quot;2023. 1. 27. - 0 99.jpg&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;326&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스 간에 FIFO 방식으로 읽히는 임시 공간인 파이프를 기반으로 데이터를 주고받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단방향 방식의 읽기 전용, 쓰기 전용 파이프를 만들어서 작동한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식은 부모, 자식 프로세스 간에만 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 파이프라고 하면 익명 파이프를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이프에 쓰기 연산을 하면 데이터가 전송되고 읽기 연산을 하면 데이터를 받게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*단뱡항 방식 : 한쪽 방향으로만 데이터를 전송할 수 있는 구조&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;명명된 파이프(named pipe)&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pipe2023. 1. 27. - 0 9.jpg&quot; data-origin-width=&quot;1369&quot; data-origin-height=&quot;771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5PJTh/btrYUunKyTB/JOKZp4GK8rh077RljS3rKk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5PJTh/btrYUunKyTB/JOKZp4GK8rh077RljS3rKk/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5PJTh/btrYUunKyTB/JOKZp4GK8rh077RljS3rKk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5PJTh%2FbtrYUunKyTB%2FJOKZp4GK8rh077RljS3rKk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;547&quot; height=&quot;308&quot; data-filename=&quot;pipe2023. 1. 27. - 0 9.jpg&quot; data-origin-width=&quot;1369&quot; data-origin-height=&quot;771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이프 서버와 하나 이상의 파이프 클라이언트 간의 통신을 위한 명명된 단방향 또는 이중 파이프를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트/서버 통신을 위한 별도의 파이프를 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 파이프를 동시에 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터의 프로세스끼리 또는 다른 네트워크 상의 컴퓨터와도 통신을 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림처럼 서버용 파이프와 클라이언트 파이프를 구분해서 작동한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 인스턴스를 열거나 여러 개의 인스턴스를 기반으로 통신한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;메시지 큐&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;message2023. 1. 27. - 0 9.jpg&quot; data-origin-width=&quot;910&quot; data-origin-height=&quot;376&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdjxCB/btrYUvGVFgZ/eKwIXFs7KMPLksQeEWsH4K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdjxCB/btrYUvGVFgZ/eKwIXFs7KMPLksQeEWsH4K/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdjxCB/btrYUvGVFgZ/eKwIXFs7KMPLksQeEWsH4K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdjxCB%2FbtrYUvGVFgZ%2FeKwIXFs7KMPLksQeEWsH4K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;453&quot; height=&quot;187&quot; data-filename=&quot;message2023. 1. 27. - 0 9.jpg&quot; data-origin-width=&quot;910&quot; data-origin-height=&quot;376&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메시지를 큐 데이터 구조 형태로 관리하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 커널의 전역변수 형태 등 커널에서 전역적으로 관리된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 IPC 방식에 비해서 사용 방법이 매우 직관적이고 간단하며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 코드의 수정 없이 단지 몇 줄의 코드를 추가해 메시지 큐에 접근할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공유 메모리를 통해 IPC를 구현할 때,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쓰기 및 읽기 빈도가 높으면 동기화 때문에 구현이 복잡해는데 이때 대안으로 메시지 큐가 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;스레드&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;thread2023. 1. 27. - 0 9.jpg&quot; data-origin-width=&quot;979&quot; data-origin-height=&quot;772&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRQXd1/btrYSqmjyU4/UcBVXUkLDignzwG3oPhaUK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRQXd1/btrYSqmjyU4/UcBVXUkLDignzwG3oPhaUK/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRQXd1/btrYSqmjyU4/UcBVXUkLDignzwG3oPhaUK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRQXd1%2FbtrYSqmjyU4%2FUcBVXUkLDignzwG3oPhaUK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;542&quot; height=&quot;427&quot; data-filename=&quot;thread2023. 1. 27. - 0 9.jpg&quot; data-origin-width=&quot;979&quot; data-origin-height=&quot;772&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스의 실행 가능한 가장 작은 단위.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스는 여러 개의 스레드를 가질 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스는 코드, 데이터, 스택, 힙을 각각 생성하지만&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스레드는 코드, 데이터, 힙은 스레드끼리 서로 공유한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 외 영역은 각각 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;멀티 스레딩&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스 내 작업을 &lt;b&gt;여러 개의 스레드&lt;/b&gt;로 처리하는 기법.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스레드끼리 서로 자원을 공유하기 때문에 효율성이 높다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 웹 요청을 처리할 때 새 프로세스를 생성하는 대신&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스레드를 사용하는 웹 서버의 경우 훨씬 적은 리소스를 소비한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 스레드가 중단(blocked)되어도 다른 스레드는 실행(running) 상태일 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 중단되지 않은 빠른 처리가 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동시성에도 큰 장점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*&lt;b&gt;동시성&lt;/b&gt; : 서로 독립적인 작업들을 작은 단위로 나누고 동시에 실행되는 것처럼 보여주는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단점으로는 한 스레드에 문제가 생기면 다른 스레드에도 영향이 간다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 스레드에 문제가 생기면 스레드로 이루어져 있는 프로세스에 영향이 갈 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멀티 스레드의 예에는 웹 브라우저의 렌더러 프로세스가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;렌더러 프로세스 내에는 메인 스레드, 워커 스레드, 컴포지터 스레드, 레스터 스레드가 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;li&gt;조성호, 쉽게 배우는 운영체제, 한빛아카데미(2018)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/Operating System</category>
      <category>cs</category>
      <category>Operating System</category>
      <category>OS</category>
      <category>멀티스레드</category>
      <category>멀티프로세스</category>
      <category>소켓</category>
      <category>스레드</category>
      <category>운영체제</category>
      <category>파이프</category>
      <category>프로세스</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/54</guid>
      <comments>https://hapen385.tistory.com/54#entry54comment</comments>
      <pubDate>Sat, 11 Feb 2023 02:05:24 +0900</pubDate>
    </item>
    <item>
      <title>[Operating System] PCB(Process Control Block)</title>
      <link>https://hapen385.tistory.com/53</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;PCB(Process Control Block, 프로세스 제어 블록)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영체제에서 프로세스에 대한 메타데이터를 저장한 데이터를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 말해, &lt;b&gt;프로세스를 실행하는 데 필요한 중요한 정보를 보관하는 자료 구조&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스는 고유의 프로세스 제어 블록을 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*메타데이터 : 데이터에 관한 구조화된 데이터이자 &lt;b&gt;데이터를 설명하는 작은 데이터&lt;/b&gt;. 대량의 정보 가운데에서 찾고 있는 정보를 효율적으로 찾아내서 이용하기 위해 일정한 규칙에 따라 콘텐츠에 부여되는 데이터.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스 생성 시 만들어져서 프로세스가 실행을 완료하면 폐기한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램이 실행되면 프로세스가 생성되고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스 주소 값들에 스택, 힙 등의 구조를 기반으로 메모리가 할당된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 프로세스들의 메타데이터들이 PCB에 저장되어 관리된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PCB는 프로세스의 중요한 정보를 포함하고 있으므로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반 사용자가 접근하지 못하도록 커널 스택의 가장 앞부분에서 관리된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*커널 스택 : 프로세스마다 하나씩 생성되는 스택. 프로세스는 유저 스택과 커널 스택을 갖는다. 커널 스택은 커널 모드를 사용할 때만 접근가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;PCB의 구조&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Process-Control-Block.jpeg&quot; data-origin-width=&quot;327&quot; data-origin-height=&quot;571&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4UqL0/btrYUTOnW6g/BmY67Z1UPkLiMyO4ax3lYk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4UqL0/btrYUTOnW6g/BmY67Z1UPkLiMyO4ax3lYk/img.jpg&quot; data-alt=&quot;출처 : Binary Terms(https://binaryterms.com/process-control-block-pcb.html)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4UqL0/btrYUTOnW6g/BmY67Z1UPkLiMyO4ax3lYk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4UqL0%2FbtrYUTOnW6g%2FBmY67Z1UPkLiMyO4ax3lYk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;244&quot; height=&quot;426&quot; data-filename=&quot;Process-Control-Block.jpeg&quot; data-origin-width=&quot;327&quot; data-origin-height=&quot;571&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : Binary Terms(https://binaryterms.com/process-control-block-pcb.html)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;프로세스 ID(Process ID)&lt;/b&gt; : 프로세스 ID, 해당 프로세스의 자식 프로세스 ID&lt;/li&gt;
&lt;li&gt;&lt;b&gt;프로세스 스케줄링 상태(Process state)&lt;/b&gt; : '준비', '일시중단' 등 프로세스가 CPU에 대한 소유권을 얻은 이후의 상태&lt;/li&gt;
&lt;li&gt;&lt;b&gt;프로세스 우선순위(Process Priority)&lt;/b&gt; : 프로세스의 실행 순서를 결정하는 우선순위&lt;/li&gt;
&lt;li&gt;&lt;b&gt;프로세스 권한&lt;/b&gt; : 컴퓨터 자원 또는 I/O 디바이스에 대한 권한 정보&lt;/li&gt;
&lt;li&gt;&lt;b&gt;프로그램 카운터(Program Counter)&lt;/b&gt; : 프로세스에서 실행해야 할 다음 명령어의 주소에 대한 포인터&lt;/li&gt;
&lt;li&gt;&lt;b&gt;CPU 레지스터(CPU Register)&lt;/b&gt; : 프로세스를 실행하기 위해 저장해야 할 레지스터에 대한 정보&lt;/li&gt;
&lt;li&gt;&lt;b&gt;CPU 스케줄링 정보&lt;/b&gt; : CPU 스케줄러에 의해 중단된 시간 등에 대한 정보&lt;/li&gt;
&lt;li&gt;&lt;b&gt;계정 정보(Accounting Information)&lt;/b&gt; : 프로세스 실행에 사용된 CPU 사용량, 실행한 유저의 정보&lt;/li&gt;
&lt;li&gt;&lt;b&gt;I/O 상태 정보&lt;/b&gt; : 프로세스에 할당된 I/O 디바이스 목록&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;컨텍스트 스위칭(Context Switching)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PCB를 교환하는 과정.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 프로세스에 할당된 시간이 끝나거나 인터럽트에 의해 발생.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터가 많은 프로그램을 동시에 실행하는 것처럼 보이지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떠한 시점에서 실행되고 있는 프로세스는 단 한 개이다(CPU가 싱글코어 일 때)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 프로그램이 동시에 실행되는 것처럼 보이는 것은 컨텍스트 스위칭이 아주 빠른 속도로 일어나는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2023. 1. 27. - 0 49.jpg&quot; data-origin-width=&quot;1161&quot; data-origin-height=&quot;1067&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdOd2o/btrYRU2eGTq/i3Er7KqmN1sKh7gt0rW4Ik/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdOd2o/btrYRU2eGTq/i3Er7KqmN1sKh7gt0rW4Ik/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdOd2o/btrYRU2eGTq/i3Er7KqmN1sKh7gt0rW4Ik/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdOd2o%2FbtrYRU2eGTq%2Fi3Er7KqmN1sKh7gt0rW4Ik%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;567&quot; height=&quot;521&quot; data-filename=&quot;2023. 1. 27. - 0 49.jpg&quot; data-origin-width=&quot;1161&quot; data-origin-height=&quot;1067&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 사진처럼 컨텍스트 스위칭이 일어날 때 유휴 시간(idle time)이 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이와 같이 컨텍스트 스위칭이 일어날 때 비용이 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 비용에는 캐시미스라는 비용도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;캐시미스&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨텍스트 스위칭이 일어날 때 프로세스가 가지고 있는 메모리 주소가 그대로 있으면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘못된 주소 변환이 생기므로 캐시클리어 과정을 겪게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 캐시미스가 일어난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;스레드에서의 컨텍스트 스위칭&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨텍스트 스위칭은 스레드에서도 일어난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스레드는 스택 영역을 제외한 모든 메모리를 공유하기 때문에,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스 컨텍스트 스위칭보다 비용이 더 적고 시간도 더 적게 걸린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;li&gt;조성호, 쉽게 배우는 운영체제, 한빛아카데미(2018)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://g0n1.tistory.com/m/224&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;g0ni&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/Operating System</category>
      <category>Operating System</category>
      <category>OS</category>
      <category>PCB</category>
      <category>문맥교환</category>
      <category>스레드</category>
      <category>운영체제</category>
      <category>커널스택</category>
      <category>컨텍스트스위칭</category>
      <category>프로세스</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/53</guid>
      <comments>https://hapen385.tistory.com/53#entry53comment</comments>
      <pubDate>Sat, 11 Feb 2023 01:30:03 +0900</pubDate>
    </item>
    <item>
      <title>[Operating System] 프로세스의 상태</title>
      <link>https://hapen385.tistory.com/52</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스는 여러 가지 상태 값을 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2023. 1. 27. - 0 39.jpg&quot; data-origin-width=&quot;1016&quot; data-origin-height=&quot;519&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1Pfn9/btrYLzK0RJ5/c1dsVipDK49GEcGDDL2C6k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1Pfn9/btrYLzK0RJ5/c1dsVipDK49GEcGDDL2C6k/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1Pfn9/btrYLzK0RJ5/c1dsVipDK49GEcGDDL2C6k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1Pfn9%2FbtrYLzK0RJ5%2Fc1dsVipDK49GEcGDDL2C6k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;588&quot; height=&quot;300&quot; data-filename=&quot;2023. 1. 27. - 0 39.jpg&quot; data-origin-width=&quot;1016&quot; data-origin-height=&quot;519&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;생성 상태(create)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스가 생성된 상태를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스가 메모리에 올라와 실행 준비를 완료한 상태가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;fork(), exec() 함수를 통해 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 PCB가 할당된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 프로세스는 바로 실행되는 것이 아니라,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;준비 상태에서 자기 순서를 기다리며 PCB도 같이 준비 상태로 옮겨진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*PCB(Process Conrtol Block) : 프로세스 제어 블록, 운영체제가 해당 프로세스를 위해 관리하는 자료 구조를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;fork()&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부모 프로세스의 주소 공간을 그대로 복사하여,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 자식 프로세스를 생성하는 함수.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주소 공간만 복사할 뿐,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부모 프로세스의 비동기 작업 등을 상속하지는 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;exec()&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새롭게 프로세스를 생성하는 함수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;대기 상태(ready)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리 공간이 충분하면 메모리를 할당받고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아니면 아닌 상태로 대기하고 있는 상태.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU 스케줄러로부터 CPU 소유권이 넘어오기를 기다리는 상태.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;대기 중단 상태(ready suspended)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리 부족으로 일시 중단된 상태.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;실행 상태(running)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU 소유권과 메모리를 할당받고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인스트럭션(instruction, 명령어)을 수행 중인 상태&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU burst가 일어났다고도 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 상태에 있는 프로세스는 자신에게 주어진 시간 동안만 작업할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 시간을 다 사용하면 timeout(PID)가 실행되어 프로세스가 정상 종료된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 상태에 있는 프로세스가 입출력을 요청하면 CPU는 입출력 관리자에게 입출력을 요청한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 block(PID)를 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;block(PID)는 입출력이 완료될 때까지 작업을 진행할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 해당 프로세스를 준비 상태로 옮기고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU 스케줄러는 새로운 프로세스를 실행 상태로 가져온다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;중단 상태(blocked)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 이벤트가 발생한 이후 기다리며 프로세스가 차단된 상태.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I/O 디바이스에 의한 인터럽트로 이런 현상이 많이 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;일시 중단 상태(blocked suspended)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중단된 상태에서 프로세스가 실행되려고 했지만 메모리 부족으로 일시 중단된 상태.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대기 중단 상태와 유사하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;종료 상태(reminated)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리와 CPU 소유권을 모두 놓고 가는 상태.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;종료는 자연스럽게 종료되는 것도 있으나,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부모 프로세스가 자식 프로세스를 강제 종료시키는 비자발적 종료(abort)도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정상적인 종료는 exit()로 처리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PCB가 사라진 상태가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자식 프로세스에 할당된 자원의 한계치를 넘어서거나,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부모 프로세스가 종료되거나,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 process kill 하는 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 명령어로 프로세스를 종료할 때 발생&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오류나 다른 프로세스에 의해 비정상적으로 종료되는 강제 종료를 만나면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디버깅하기 위해 종료 직전의 메모리 상태를 저장장치로 옮긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 &lt;b&gt;코어 덤프(core dump)&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코어 덤프를 통해 프로그램이 어떤 상태로 오류가 났는지 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 상태와 관련된 작업은 다음과 같다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;상태&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;설명&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;작업&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: left;&quot;&gt;생성 상태&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: left;&quot;&gt;프로그램을 메모리에 가져와 실행 준비가 완료된 상태.&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: left;&quot;&gt;메모리 할당, PCB 생성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: left;&quot;&gt;준비 상태&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: left;&quot;&gt;실행을 기다리는 모든 프로세스가 자기 차례를 기다리는 상태.&lt;br /&gt;CPU 스케줄러가 실행할 프로세스를 선택.&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: left;&quot;&gt;dispatch(PID) : 준비 -&amp;gt; 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: left;&quot;&gt;실행 상태&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: left;&quot;&gt;선택된 프로세스가 타임 슬라이스(실행할 수 있는 시간)를 얻어 CPU를 사용하는 상태.&lt;br /&gt;프로세스 사이의 context switching이 일어난다.&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: left;&quot;&gt;timeout(PID) : 실행 -&amp;gt; 준비&lt;br /&gt;exit(PID) : 실행 -&amp;gt; 종료&lt;br /&gt;block(PID) : 실행 -&amp;gt; 대기&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: left;&quot;&gt;대기 상태&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: left;&quot;&gt;실행 상태에 있는 프로세스가 입출력을 요청하면, 입출력이 완료될 때까지 기다리는 상태.&lt;br /&gt;입출력이 완료되면 준비 상태로 간다.&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: left;&quot;&gt;wakeup(PID) : 대기 -&amp;gt; 준비&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: left;&quot;&gt;종료 상태&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: left;&quot;&gt;프로세스가 종료된 상태.&lt;br /&gt;정상 종료인 exit와 비정상 종료인 abort를 포함&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: left;&quot;&gt;메모리 삭제, PCB 삭제&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;li&gt;조성호, 쉽게 배우는 운영체제, 한빛아카데미(2018)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/Operating System</category>
      <category>Operating System</category>
      <category>OS</category>
      <category>PCB</category>
      <category>운영체제</category>
      <category>프로세스</category>
      <category>프로세스 상태</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/52</guid>
      <comments>https://hapen385.tistory.com/52#entry52comment</comments>
      <pubDate>Fri, 10 Feb 2023 15:50:11 +0900</pubDate>
    </item>
    <item>
      <title>[Operating System] 프로세스(Process)</title>
      <link>https://hapen385.tistory.com/51</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;프로세스(process)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터에서 실행되고 있는 프로그램.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행을 위해 메모리에 올라온 동적인 상태이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU 스케줄링의 대상인 작업(task)과 거의 같은 의미를 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 스레드(thread) : 프로세스 내 작업의 흐름&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;프로그램의 실행 과정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2023. 1. 27. - 0 9.jpg&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;596&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/obibK/btrYKu9mhwo/kIFKsnI67xUHI74TgMyeYk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/obibK/btrYKu9mhwo/kIFKsnI67xUHI74TgMyeYk/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/obibK/btrYKu9mhwo/kIFKsnI67xUHI74TgMyeYk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FobibK%2FbtrYKu9mhwo%2FkIFKsnI67xUHI74TgMyeYk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;457&quot; height=&quot;330&quot; data-filename=&quot;2023. 1. 27. - 0 9.jpg&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;596&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램은 메모리에 올라가면서 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램이 메모리에 올라가면 프로세스가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 프로그램은 인스턴스화가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스는 CPU 스케줄러에 따라 순서에 맞게 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;프로세스와 컴파일 과정&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2023. 1. 27. - 0 1419.jpg&quot; data-origin-width=&quot;1232&quot; data-origin-height=&quot;1077&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGm5pm/btrYLyjmMv8/bLb77KIKfOKKQVh8UH3QbK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGm5pm/btrYLyjmMv8/bLb77KIKfOKKQVh8UH3QbK/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGm5pm/btrYLyjmMv8/bLb77KIKfOKKQVh8UH3QbK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGm5pm%2FbtrYLyjmMv8%2FbLb77KIKfOKKQVh8UH3QbK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;459&quot; height=&quot;401&quot; data-filename=&quot;2023. 1. 27. - 0 1419.jpg&quot; data-origin-width=&quot;1232&quot; data-origin-height=&quot;1077&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램은 컴파일러가 컴파일 과정을 거친 후,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터가 이해할 수 있는 기계어로 번역되어 실행될 수 있는 파일이 되는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 프로그램은 C 언어 기반의 프로그램이며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터프리터 언어로 된 프로그램과는 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 전처리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소스 코드의 주석을 제거하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#include 와 같은 헤더 파일을 병합하여 매크로를 치환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*매크로(macro) : 프로그램 내에서 반복적으로 사용되는 단어 또는 수행할 문장을 특정한 심벌(symbol)로 표기하는 것&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예)#define PI 3.14&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 컴파일러&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오류 처리, 코드 최적화 작업을 하며 어셈블리어로 변환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 어셈블러&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어셈블리어는 목적 코드(object code)로 변환된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 목적 코드의 확장자는 운영체제마다 다른데, 리눅스에서는 .o 가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. 링커&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램 내에 있는 라이브러리 함수 또는 다른 파일들과 목적 코드를 결합한 뒤,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 파일을 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 파일의 확장자는 .exe 또는 .out 이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정적 라이브러리&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램 빌드 시에 라이브러리가 제공하는 &lt;b&gt;모든 코드&lt;/b&gt;를 실행 파일에 넣는 방식.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스템 환경 등 외부 의존도가 낮다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 중복과 같이 메모리 효율적이 안좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;동적 라이브러리&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램 실행 시 &lt;b&gt;필요할 때&lt;/b&gt;만 DLL 이라는 함수 정보를 통해 참조하는 방식.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리 효율성은 정적 라이브러리 사용할 때보다 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 외부 의존도가 높아진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;프로세스의 메모리 구조&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2023. 1. 27. - 0 59.jpg&quot; data-origin-width=&quot;679&quot; data-origin-height=&quot;616&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c1anM0/btrYLtQEGhp/troDC9xS8W8ZEa6LNExzg1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c1anM0/btrYLtQEGhp/troDC9xS8W8ZEa6LNExzg1/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c1anM0/btrYLtQEGhp/troDC9xS8W8ZEa6LNExzg1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc1anM0%2FbtrYLtQEGhp%2FtroDC9xS8W8ZEa6LNExzg1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;361&quot; height=&quot;328&quot; data-filename=&quot;2023. 1. 27. - 0 59.jpg&quot; data-origin-width=&quot;679&quot; data-origin-height=&quot;616&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스는 스택(stack), 힙(heap), 데이터 영역(BSS segment, Data segment), 코드 영역(code segment)으로 나눠진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;스택&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영체제가 프로세스를 실행하기 위해 부수적으로 필요한 데이터를 모아놓은 곳.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스 내에서 함수를 호출하면 함수를 수행하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래 프로그램으로 되돌아올 위치를 스택 영역에 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지역변수, 매개변수, 함수가 저장된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 주소부터 할당된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영체제가 사용자의 프로세스를 작동하기 위해 유지하는 영역이므로 사용자에게는 보이지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴파일 시에 크기가 결정되며 &lt;b&gt;동적&lt;/b&gt;인 특성을 갖는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스택 영역은 함수가 함수를 재귀적으로 호출하면서 동적으로 크기가 늘어날 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 힙과 스택 메모리 영역이 겹치면 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, 힙과 스택 사이의 공간을 비워 놓는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;힙&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동적 할당할 때 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 주소부터 할당된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;런타임 시에 크기가 결정된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;힙은 &lt;b&gt;동적&lt;/b&gt;인 특성을 갖는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;스택 vs 힙&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 92.6743%; height: 277px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 8.33335%; height: 20px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 20px; text-align: center;&quot;&gt;스택&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;힙&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 8.33335%; height: 20px; text-align: center;&quot;&gt;액세스/할당 속도&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 20px; text-align: center;&quot;&gt;빠름&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;느림&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 8.33335%; height: 40px; text-align: center;&quot;&gt;메모리 관리&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 40px; text-align: center;&quot;&gt;자동(CPU에 의해 관리)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px; text-align: center;&quot;&gt;수동&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 8.33335%; height: 20px; text-align: center;&quot;&gt;구현 난이도&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 20px; text-align: center;&quot;&gt;쉬움&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;어려움&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 8.33335%; height: 20px; text-align: center;&quot;&gt;비용&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 20px; text-align: center;&quot;&gt;적게 든다&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;많이 든다&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스택과 힙을 나눠 놓은 것은,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목적에 따라 스택과 힙을 선택해서 사용하여&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;효율적으로 메모리를 사용하기 위함이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;데이터 영역&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드가 실행되면서 사용하는 변수나 파일 등의 각종 데이터를 모아놓은 곳.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전역변수, 정적변수가 저장된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터는 변하는 값이기 때문에 이곳의 내용은 기본적으로 읽기와 쓰기가 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;정적인 특징을 갖는 프로그램이 종료되면 사라지는 변수가 들어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BSS(Block Started by Symbol) 영역과 Data 영역으로 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BSS 영역은 초기화 되지 않은 변수가 0으로 초기화되어 저장된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Data 영역은 0이 아닌 다른 값으로 할당된 변수들이 저장된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;코드 영역&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램의 본문이 기술된 곳이며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램에 내장되어 있는 소스 코드가 들어가는 영역.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그래머가 작성한 코드가 탑재된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코드는 읽기 전용이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수정 불가능한 기계어로 저장되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정적&lt;/b&gt;인 특성을 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;li&gt;조성호, 쉽게 배우는 운영체제, 한빛아카데미(2018)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.naver.com/PostView.nhn?blogId=techref&amp;amp;logNo=222274484731&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;윌리의 Technical Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://luv-n-interest.tistory.com/1046&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;노는 게 제일 좋아&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jhkang-tech.tistory.com/136&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;개발이 즐겁다!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/Operating System</category>
      <category>Operating System</category>
      <category>OS</category>
      <category>스레드</category>
      <category>스택</category>
      <category>운영체제</category>
      <category>프로세스</category>
      <category>프로세스의 구조</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/51</guid>
      <comments>https://hapen385.tistory.com/51#entry51comment</comments>
      <pubDate>Fri, 10 Feb 2023 14:20:42 +0900</pubDate>
    </item>
    <item>
      <title>[Operating System] 페이지 교체 알고리즘</title>
      <link>https://hapen385.tistory.com/50</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;메모리가 한정되어 있으므로 스와핑이 많이 일어나며 이러한 스와핑은 많이 일어나지 않도록 설계되어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스와핑은 페이지 교체 알고리즘을 기반으로 일어난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;오프라인 알고리즘(offline algorithm)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼 미래에 참조되는 페이지와 현재 할당하는 페이지를 바꾸는 알고리즘.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 좋은 방법이나 미래에 사용되는 프로세스를 우리는 알 수 없기 때문에 사용할 수 없는 알고리즘이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 알고리즘과의 성능 비교에 대한 기준으로 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;FIFO(First In First Out)&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-01-28 오후 9.14.55.png&quot; data-origin-width=&quot;479&quot; data-origin-height=&quot;252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rHrLG/btrXnLenvYo/TT0dombDyyP6PoO4kjppqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rHrLG/btrXnLenvYo/TT0dombDyyP6PoO4kjppqk/img.png&quot; data-alt=&quot;출처 : Jogamohan Medak, Partha Pratim Gogoi, Critical Scrutiny of Page Replacement Algorithms: FIFO, Optimal and LRU(IJITEE)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rHrLG/btrXnLenvYo/TT0dombDyyP6PoO4kjppqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrHrLG%2FbtrXnLenvYo%2FTT0dombDyyP6PoO4kjppqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;399&quot; height=&quot;210&quot; data-filename=&quot;스크린샷 2023-01-28 오후 9.14.55.png&quot; data-origin-width=&quot;479&quot; data-origin-height=&quot;252&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : Jogamohan Medak, Partha Pratim Gogoi, Critical Scrutiny of Page Replacement Algorithms: FIFO, Optimal and LRU(IJITEE)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 먼저 온 페이지를 교체 영역에 가장 먼저 놓는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;LRU(Least Recentle Used)&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-01-28 오후 9.15.23.png&quot; data-origin-width=&quot;479&quot; data-origin-height=&quot;252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOrGjp/btrXmSFkVIl/2djmaHB32GTPEmARMCfy71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOrGjp/btrXmSFkVIl/2djmaHB32GTPEmARMCfy71/img.png&quot; data-alt=&quot;출처 : Jogamohan Medak, Partha Pratim Gogoi, Critical Scrutiny of Page Replacement Algorithms: FIFO, Optimal and LRU(IJITEE)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOrGjp/btrXmSFkVIl/2djmaHB32GTPEmARMCfy71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOrGjp%2FbtrXmSFkVIl%2F2djmaHB32GTPEmARMCfy71%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;393&quot; height=&quot;207&quot; data-filename=&quot;스크린샷 2023-01-28 오후 9.15.23.png&quot; data-origin-width=&quot;479&quot; data-origin-height=&quot;252&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : Jogamohan Medak, Partha Pratim Gogoi, Critical Scrutiny of Page Replacement Algorithms: FIFO, Optimal and LRU(IJITEE)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참조가 가장 오래된 페이지를 바꾼다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 오래된 것을 파악하기 위해 각 페이지마다 계수기(counter), 스택을 두어야 하는 문제점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시 테이블과 이중 연결 리스트를 사용해서 구현한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시 테이블은 이중 연결 리스트에서 빠르게 찾을 수 있도록 쓰고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이중 연결 리스트는 한정된 메모리를 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;NUR(Not Used Recently)&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2023. 1. 27. - 0 8.jpg&quot; data-origin-width=&quot;734&quot; data-origin-height=&quot;707&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7tokk/btrXn6WQryo/898SdJfY8eLrDwXEB9azW0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7tokk/btrXn6WQryo/898SdJfY8eLrDwXEB9azW0/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7tokk/btrXn6WQryo/898SdJfY8eLrDwXEB9azW0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7tokk%2FbtrXn6WQryo%2F898SdJfY8eLrDwXEB9azW0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;401&quot; height=&quot;386&quot; data-filename=&quot;2023. 1. 27. - 0 8.jpg&quot; data-origin-width=&quot;734&quot; data-origin-height=&quot;707&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근에 사용한 적이 없는 페이지를 스왑 영역으로 보내는 알고리즘.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LRU에서 발전한 알고리즘이다. 일명 clock 알고리즘이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0과 1을 가진 비트를 둔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0은 참조되지 않은 것이며, 1은 최근에 참조된 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시계 방향으로 돌면서 0을 찾고 0을 찾은 순간 해당 프로세스를 교체하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 부분을 1로 바꾸는 알고리즘이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;LFU(Least Frequently Used)&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;LFU.png&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;277&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tBkmO/btrXnLla0HQ/hX1X9oo8EQkbrNN645Ialk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tBkmO/btrXnLla0HQ/hX1X9oo8EQkbrNN645Ialk/img.png&quot; data-alt=&quot;출처 : Page Replacement Algorithms in OS(https://webeduclick.com/page-replacement-algorithms-in-os/)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tBkmO/btrXnLla0HQ/hX1X9oo8EQkbrNN645Ialk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtBkmO%2FbtrXnLla0HQ%2FhX1X9oo8EQkbrNN645Ialk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;567&quot; height=&quot;209&quot; data-filename=&quot;LFU.png&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;277&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : Page Replacement Algorithms in OS(https://webeduclick.com/page-replacement-algorithms-in-os/)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 참조 횟수가 적은 페이지를 교체한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많이 사용하지 않은 것을 교체하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이지 교체 알고리즘은 페이지 부재 횟수와 페이지 성공 횟수를 비교하며 성능 평가를 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 이외에도 다른 성능 평가 기준들이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;li&gt;조성호, 쉽게 배우는 운영체제, 한빛아카데미(2018)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/Operating System</category>
      <category>CS지식</category>
      <category>Operating System</category>
      <category>OS</category>
      <category>운영체제</category>
      <category>페이지 교체</category>
      <category>페이지 교체 알고리즘</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/50</guid>
      <comments>https://hapen385.tistory.com/50#entry50comment</comments>
      <pubDate>Sat, 28 Jan 2023 21:50:52 +0900</pubDate>
    </item>
    <item>
      <title>[Operating System] 메모리 할당</title>
      <link>https://hapen385.tistory.com/49</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;메모리에 프로그램을 할당할 때는 시작 메모리 위치, 메모리의 할당 크기를 기반으로 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;할당 방식은 연속 할당과 불연속 할당으로 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;연속 할당&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리에 &lt;b&gt;연속적으로 공간을 할당&lt;/b&gt;하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스를 순차적으로 공간에 할당한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연속 할당은 고정 분할 방식과 가변 분할 방식으로 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;고정 분할 방식(fixed partition allocation)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리를 미리 나누어 관리하는 방식.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큰 프로세스가 메모리에 올라오면 여러 조각으로 나누어서 배치한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;장점 : 메모리를 일정한 크기로 나누어 관리하므로 &lt;b&gt;메모리 관리가 수월&lt;/b&gt;하다(가변 분할 방식의 메모리 통합같은 부가적인 작업을 할 필요가 없다)&lt;/li&gt;
&lt;li&gt;단점 :&amp;nbsp;메모리가 미리 나뉘어 있으므로 융통성이 없다. 또한 &lt;b&gt;내부 단편화&lt;/b&gt;가 발생한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*내부 단편화(internal fragmentation) : 메모리를 나눈 크기보다 프로그램이 작아서, 분할 메모리 내에 쓸모없는 홀이 생기는 현상&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*홀(hole) : 할당할 수 있는 비어 있는 메모리 공간&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;가변 분할 방식(variable partition allocation)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매 시점 프로그램의 크기에 맞게 동적으로 메모리를 나누어 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;장점 : 프로세스를 한 덩어리로 처리하여 하나의 프로세스를 연속된 공간에 배치&lt;/li&gt;
&lt;li&gt;단점 : 내부 단편화는 발생하지 않고 &lt;b&gt;외부 단편화&lt;/b&gt;가 발생할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*외부 단편화(external fragmentation) : 메모리를 나눈 크기보다 프로그램이 커서 들어가지 못하는 공간이 많이 발생하는 현상&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가변 분할 방식에는 최초적합(first fit), 최적적합(best fit), 최악적합(worst fit)이 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;next-fit-algorithm-operating-system.png&quot; data-origin-width=&quot;822&quot; data-origin-height=&quot;916&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b79sQq/btrXnkaf8Ic/RaScfiI5s22YgePGjkgls1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b79sQq/btrXnkaf8Ic/RaScfiI5s22YgePGjkgls1/img.png&quot; data-alt=&quot;출처 : Program for Next Fit algorithm in Memory Management(https://www.geeksforgeeks.org/program-for-next-fit-algorithm-in-memory-management/)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b79sQq/btrXnkaf8Ic/RaScfiI5s22YgePGjkgls1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb79sQq%2FbtrXnkaf8Ic%2FRaScfiI5s22YgePGjkgls1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;607&quot; height=&quot;676&quot; data-filename=&quot;next-fit-algorithm-operating-system.png&quot; data-origin-width=&quot;822&quot; data-origin-height=&quot;916&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : Program for Next Fit algorithm in Memory Management(https://www.geeksforgeeks.org/program-for-next-fit-algorithm-in-memory-management/)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;최초적합 : 위쪽이나 아래쪽부터 시작해서 &lt;b&gt;홀을 찾으면 바로 할당&lt;/b&gt;. 빈 공간을 찾아다닐 필요 없다.&lt;/li&gt;
&lt;li&gt;최적적합 : &lt;b&gt;프로세스의 크기 이상인 공간 중 가장 작은 홀&lt;/b&gt;에 할당. 빈 공간을 확인하는 부가적인 작업이 있지만, 딱 맞는 공간을 찾을 경우 단편화가 일어나지 않는다.&lt;/li&gt;
&lt;li&gt;최악적합 : 프로세스의 크기와 &lt;b&gt;가장 많이 차이가 나는 홀&lt;/b&gt;에 할당. 프로세스를 배치하고 남은 공간이 크기 때문에 쓸모가 있다. 빈 공간의 크기가 클 때는 효과적이지만 빈 공간의 크기가 점점 줄어들면 최적적합처럼 작은 조각을 만들어낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부 단편화를 해결하기 위해서는&amp;nbsp;&lt;span&gt;비어 있는 공간을 하나로 합쳐야 하며(컴팩션, compaction 방법), 이 과정에서 다른 프로세스의 자리도 옮겨야 하므로 메모리 관리가 복잡할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;불연속 할당&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리를 연속적으로 할당하지 않는 방식.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현대 운영체제 쓰는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이징, 세그멘테이션, 페이지드 세그멘테이션 기법이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;페이징(paging)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동일한 크기의 페이지 단위로 나누어 메모리의 서로 다른 위치에 프로세스를 할당한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;홀의 크기가 균일하지 않은 문제가 없어지지만 주소 변환이 복잡해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논리적 주소를 물리적 주소로 변환하는 작업이 페이지 단위로 이루어져야 하기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;세그멘테이션(segmentation)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이지 단위가 아닌 의미 단위인 세그먼트(segment)로 나누는 방식.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스 내의 코드와 데이터 등을 기반으로 나눌 수도 있으며 함수 단위로도 나눌 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공유 보안 측면에서 좋지만 홀 크기가 균일하지 않은 문제가 발생된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;페이지드 세그멘테이션(paged segmentation)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공유나 보안을 의미 단위의 세그먼트로 나누고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물리적 메모리는 페이지로 나누는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;li&gt;조성호, 쉽게 배우는 운영체제, 한빛아카데미(2018)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zangzangs.tistory.com/134&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;장장스&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Science/Operating System</category>
      <category>cs</category>
      <category>CS지식</category>
      <category>Operating System</category>
      <category>OS</category>
      <category>Segmentation</category>
      <category>메모리</category>
      <category>메모리 할당</category>
      <category>운영체제</category>
      <category>페이징</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/49</guid>
      <comments>https://hapen385.tistory.com/49#entry49comment</comments>
      <pubDate>Sat, 28 Jan 2023 20:40:25 +0900</pubDate>
    </item>
    <item>
      <title>[Operating System] 가상 메모리</title>
      <link>https://hapen385.tistory.com/48</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;가상 메모리(virtual memory)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리 관리 기법 중 하나로, 컴퓨터가 실제로 이용 가능한 메모리 자원을 추상화하여 사용자들에게 매우 큰 메모리로 보이게 하는 것.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2023. 1. 27. - 0 7.jpg&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;714&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRNzTq/btrXrNIHG48/YUYtotCQEDFZkM8ZnPhn1K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRNzTq/btrXrNIHG48/YUYtotCQEDFZkM8ZnPhn1K/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRNzTq/btrXrNIHG48/YUYtotCQEDFZkM8ZnPhn1K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRNzTq%2FbtrXrNIHG48%2FYUYtotCQEDFZkM8ZnPhn1K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;456&quot; height=&quot;327&quot; data-filename=&quot;2023. 1. 27. - 0 7.jpg&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;714&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상적으로 주어진 주소를 가상 주소(logical address)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 메모리 상에 있는 주소를 실제 주소(physical address)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상 주소는 메모리관리장치(MMU)에 의해 실제 주소로 변환&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 사용자는 실제 주소를 의식할 필요 없이 프로그램을 구축할 수 있게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상 메모리는 가상 주소와 실제 주소가 매핑되어 있으며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스의 주소 정보가 들어 있는 페이지 테이블로 관리된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 속도 향상을 위해 TLB를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*TLB : 메모리와 CPU 사이에 있는 주소 변환을 위한 캐시. 페이지 테이블에 있는 리스트를 보관. CPU가 페이지 테이블까지 가지 않아도 주소를 변환할 수 있도록 하여 속도를 향상시키는 캐시 계층.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;스와핑(swapping)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상 메모리에는 존재하나 실제 메모리인 RAM에 없는 데이터나 코드에 접근할 경우 페이지 폴트가 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 메모리에서 지금은 사용하지 않는 영역을 하드디스크로 옮기고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;하드디스크의 일부분을 마치 메모리처럼 불러와 쓰는 것&lt;/b&gt;을 스와핑이라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스와핑을 통해 마치 페이지 폴트가 일어나지 않은 것처럼 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;페이지 폴트(page fault)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스의 주소 공간에는 존재하지만 지금 해당 컴퓨터의 RAM에는 없는 데이터에 접근했을 경우 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이지 폴트와 스와핑이 일어나는 과정은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. CPU가 물리 메모리를 확인하여 해당 페이지가 없으면 트랩을 발생시켜 운영체제에 알린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*페이지(page) : 가상 메모리를 사용하는 최소 크기 단위&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*트랩(trap) : 소프트웨어에 의해 발생하는 인터럽트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 운영체제는 CPU의 동작을 잠시 멈춘다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 운영체제는 페이지 테이블을 확인하여 가상 메모리에 페이지가 존재하는지 확인한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;없으면 프로세스를 중단하고 현재 물리 메모리(RAM)에 비어 있는 프레임이 있는지 찾는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*프레임(frame) : 실제 메모리를 사용하는 최소 크기 단위&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 물리 메모리에도 없다면 스와핑이 일어난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 비어 있는 프레임에 해당 페이지를 로드하고 페이지 테이블을 최신화한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 중단되었던 CPU를 다시 시작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;스레싱(thrashing)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리의 &lt;b&gt;페이지 폴트율이 높은 것&lt;/b&gt;을 의미.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 컴퓨터의 심각한 성능 저하를 초래한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2023. 1. 27. - 0 6.jpg&quot; data-origin-width=&quot;757&quot; data-origin-height=&quot;469&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blk3Uv/btrXmICzJy4/OniWu3UjDreqg1v0bmMqw1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blk3Uv/btrXmICzJy4/OniWu3UjDreqg1v0bmMqw1/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blk3Uv/btrXmICzJy4/OniWu3UjDreqg1v0bmMqw1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fblk3Uv%2FbtrXmICzJy4%2FOniWu3UjDreqg1v0bmMqw1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;467&quot; height=&quot;289&quot; data-filename=&quot;2023. 1. 27. - 0 6.jpg&quot; data-origin-width=&quot;757&quot; data-origin-height=&quot;469&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스레싱은 메모리에 너무 많은 프로세스가 동시에 올라가게 되면 스와핑이 많이 일어나서 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이지 폴트가 일어나면 CPU 이용률이 낮아진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU 이용률이 낮아지게 되면 운영체제는 CPU의 가용성을 더 높이기 위해 더 많은 프로세스를 메모리에 올리게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 악순환이 반복되며 스레싱이 일어난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;해결 방법&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모리를 늘리기&lt;/li&gt;
&lt;li&gt;HDD를 사용한다면 HDD를 SSD로 바꾸기&lt;/li&gt;
&lt;li&gt;작업 세트(working set)&lt;/li&gt;
&lt;li&gt;PFF&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;작업 세트(working set)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스의 과거 사용 이력인 지역성을 통해 결정된 페이지 집합을 만들어 &lt;b&gt;미리 메모리에 로드&lt;/b&gt;하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미리 메모리에 로드하면 탐색에 드는 비용을 줄일 수 있으며 스와핑도 줄일 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;PFF(Page Fault Frequency)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;페이지 폴트 빈도를 조절&lt;/b&gt;하는 방법으로 상한선과 하한선을 만드는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 빈도가 상한선에 도달한다면 프레임을 늘리고 하한선에 도달한다면 프레임을 줄이는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/Operating System</category>
      <category>cs</category>
      <category>CS지식</category>
      <category>Operating System</category>
      <category>OS</category>
      <category>가상 메모리</category>
      <category>메모리</category>
      <category>스레싱</category>
      <category>운영체제</category>
      <category>페이지 폴트</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/48</guid>
      <comments>https://hapen385.tistory.com/48#entry48comment</comments>
      <pubDate>Sat, 28 Jan 2023 18:40:11 +0900</pubDate>
    </item>
    <item>
      <title>[Operating System] 캐시</title>
      <link>https://hapen385.tistory.com/47</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;캐시&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;데이터를 미리 복사해 놓는 임시 저장소&lt;/b&gt;이자,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빠른 장치와 느린 장치의 속도 차이에 따른 병목 현상을 줄이기 위한 메모리.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시를 통해 데이터를 접근하는 시간이 오래 걸리는 경우를 해결하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무언가를 다시 계산하는 과정을 생략하여 시간 절약할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐싱을 할 때는 자주 사용하는 데이터를 기반으로 캐시를 직접 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 자주 사용하는 데이터의 기준은 &lt;b&gt;지역성&lt;/b&gt;으로 정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지역성은 시간 지역성(temporal locality)과 공간 지역성(spatial locality)으로 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;시간 지역성&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 사용한 데이터에 다시 접근하려는 특성.&lt;/p&gt;
&lt;pre id=&quot;code_1674869896393&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for(i in 0..10){
	arr[i] = i
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 코드에서 시간 지역성을 기준으로 자주 사용하는 데이터는 i가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;공간 지역성&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 접근한 데이터를 이루고 있는 공간이나 그 가까운 공간에 접근하려는 특성.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞의 코드에서 접근한 데이터를 이루고 있는 공간은 배열 arr인 것을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;캐시의 구조&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2023. 1. 27. - 0 4.jpg&quot; data-origin-width=&quot;1031&quot; data-origin-height=&quot;581&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMOiBZ/btrXqsEBVvQ/kK5M2rMsWKmAKULRhR8Dw1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMOiBZ/btrXqsEBVvQ/kK5M2rMsWKmAKULRhR8Dw1/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMOiBZ/btrXqsEBVvQ/kK5M2rMsWKmAKULRhR8Dw1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMOiBZ%2FbtrXqsEBVvQ%2FkK5M2rMsWKmAKULRhR8Dw1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;528&quot; height=&quot;298&quot; data-filename=&quot;2023. 1. 27. - 0 4.jpg&quot; data-origin-width=&quot;1031&quot; data-origin-height=&quot;581&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;캐시 히트(cache hit)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시에서 원하는 데이터를 찾는 것, 그 데이터를 바로 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제어 장치를 거쳐 데이터를 가져온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시히트의 경우 위치도 가깝고 CPU 내부 버스를 기반으로 작동하므로 빠르게 가져올 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*CPU 내부 버스 : CPU 내부에 있는 장치를 연결하는 버스. BSB(Back-Side Bus), 즉 후면 버스라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;캐시 미스(cache miss)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원하는 데이터가 캐시에 없으면 메모리로 가서 데이터를 찾는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리로 가서 데이터를 가져오는 과정에서 시스템 버스를 기반으로 작동하므로 느리다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*시스템 버스 : 메모리와 주변 장치를 연결하는 버스. FSB(Front-Side Bus), 즉 전면 버스라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;캐시 적중률(cache hit ratio)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시 히트가 되는 비율.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;캐시 매핑&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시가 히트되기 위해 매핑하는 방법. 레지스터와 RAM 간에 데이터를 주고 받을 때를 기준으로 설명.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레지스터는 굉장히 작고 RAM은 상대적으로 크므로 레지스터가 캐시 계층으로써 역할을 잘하려면 매핑이 중요하다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;직접 매핑(directed mapping)&lt;/b&gt; : 메모리가 1~100이 있고 캐시가 1~10이라면, 1:1~10 이렇게 매핑되는 것을 말한다. 처리가 빠르나 충돌이 잦다. 규칙을 정해서 매핑시키는 것이며, 이 규칙을 지키려면 캐시가 비효율적이게 교체되는 일이 잦다. 따라서, 충돌이 많으며 적중률도 낮은 매핑 방법이다. 다만 구현이 간단하다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;연관 매핑(associative mapping)&lt;/b&gt; : 순서를 일치시키지 않고 관련 있는 캐시와 메모리를 매핑. 충돌이 적지만 모든 블록을 탐색해야 하므로 속도가 느리다. 하지만 정말 필요한 것들 위주로 저장할 수 있으므로 적중률은 높은 매핑 방법이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;집합 연관 매핑(set associative mapping)&lt;/b&gt; : 직접 매핑과 연관 매핑을 합쳐놓은 것과 같다. 순서는 일치시키나 집합을 둬서 저장한다. 또한, 블록화가 되어 있으므로 검색은 더 효율적이다. 예) 메모리 1~100이 있고 캐시가 1~10 있다면 캐시 1~5에는 1~50의 데이터를 무작위로 저장시키는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;웹 브라우저의 캐시&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소프트웨어적인 대표적인 캐시로는 웹 브라우저의 쿠키, 로컬 스토리지, 세션 스토리지가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 사용자의 커스텀 정보나 인증 모듈 관련 사항들을 웹 브라우저에 저장해서,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추후 서버에 요청할 때 자신을 나타내는 아이덴티티나 중복 요청 방지를 위해 쓰인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;쿠키&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만료기한이 있는 키-값 저장소.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4KB까지 데이터를 저장할 수 있으며 만료기한을 설정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트 또는 서버에서 만료기한 등을 정할 수 있는데 보통 서버에서 만료기한을 정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일시적으로 가벼운 데이터를 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예)다시 보지 않기 팝업창, 아이디-비밀번호 자동 완성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;로컬 스토리지&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만료기한이 없는 키-값 저장소.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10MB까지 저장할 수 있으며 웹 브라우저를 닫아도 유지되고 도메인 단위로 저장, 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트에서만 수정 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지속적으로 필요한 데이터를 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예)자동 로그인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;세션 스토리지&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만료기한이 없는 키-값 저장소.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;탭 단위로 세션 스토리지를 생성하며, 탭을 닫을 때 해당 데이터가 삭제된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5MB까지 저장가능하며 클라이언트에서만 수정이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일시적으로 필요한 데이터를 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예)일회성 로그인, 비회원 장바구니&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;데이터베이스의 캐싱 계층&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2023. 1. 27. - 0 5.jpg&quot; data-origin-width=&quot;1132&quot; data-origin-height=&quot;707&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqAlIA/btrXmRF8q6k/ZP6RTO5MBhwGNoNNVDB1W1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqAlIA/btrXmRF8q6k/ZP6RTO5MBhwGNoNNVDB1W1/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqAlIA/btrXmRF8q6k/ZP6RTO5MBhwGNoNNVDB1W1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqAlIA%2FbtrXmRF8q6k%2FZP6RTO5MBhwGNoNNVDB1W1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;581&quot; height=&quot;363&quot; data-filename=&quot;2023. 1. 27. - 0 5.jpg&quot; data-origin-width=&quot;1132&quot; data-origin-height=&quot;707&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스 시스템을 구축할 때도 메인 데이터베이스 위에 레디스(redis) 데이터베이스 계층을 캐싱 계층으로 둬서 성능을 향상시킬 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;li&gt;조성호, 쉽게 배우는 운영체제, 한빛아카데미(2018)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://velog.io/@hs0217/%EC%BF%A0%ED%82%A4-%EB%A1%9C%EC%BB%AC-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80-%EC%84%B8%EC%85%98-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;hs.log&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gguljaem.tistory.com/entry/%EC%BA%90%EC%8B%9C%EB%A9%94%EB%AA%A8%EB%A6%AC%EC%9D%98-%EA%B0%9C%EB%85%90%EA%B3%BC-%EB%A7%A4%ED%95%91%EA%B8%B0%EB%B2%95%EC%97%90-%EB%8C%80%ED%95%9C-%EC%84%A4%EB%AA%85&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;꿀잼모아&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/Operating System</category>
      <category>Operating System</category>
      <category>OS</category>
      <category>운영체제</category>
      <category>캐시</category>
      <category>캐시 계층</category>
      <category>캐시 매핑</category>
      <category>캐싱</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/47</guid>
      <comments>https://hapen385.tistory.com/47#entry47comment</comments>
      <pubDate>Sat, 28 Jan 2023 12:10:36 +0900</pubDate>
    </item>
    <item>
      <title>[Operating System] 메모리 계층</title>
      <link>https://hapen385.tistory.com/46</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;메모리 계층&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;187.jpeg&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;233&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDTbY7/btrXnjWngJr/1KV5A16wrjuhA6aO10lMd0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDTbY7/btrXnjWngJr/1KV5A16wrjuhA6aO10lMd0/img.jpg&quot; data-alt=&quot;출처 : 컴퓨터 사이언스 부트캠프 with 파이썬(2018)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDTbY7/btrXnjWngJr/1KV5A16wrjuhA6aO10lMd0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDTbY7%2FbtrXnjWngJr%2F1KV5A16wrjuhA6aO10lMd0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;233&quot; data-filename=&quot;187.jpeg&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;233&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 컴퓨터 사이언스 부트캠프 with 파이썬(2018)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;휘발성 메모리&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;레지스터&lt;/b&gt; : CPU 안에 있는 작은 메모리, 속도 가장 빠름, 기억 용량이 가장 적다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;캐시&lt;/b&gt; : L1, L2 캐시를 지칭하나 L3 캐시도 있다. 속도 빠름, 기억 용량이 적다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;주기억장치&lt;/b&gt; : RAM을 가리킨다. 속도 보통, 기억 용량이 보통. 하드디스크로부터 일정량의 데이터를 복사해서 임시 저장하고 이를 필요할 때마다 CPU에 빠르게 전달하는 역할&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;레지스터&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU가 요청을 처리하는데 필요한 데이터를 일시적으로 저장하는 저장장치.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU 내에 있으므로 가장 빠르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;캐시&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리와 CPU 간의 속도 차이를 완화하기 위해 메모리의 데이터를 미리 가져와 저장해두는 임시 장소.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필요한 데이터를 모아 한꺼번에 처리하는 버퍼의 일종.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU가 앞으로 사용할 것으로 예상되는 데이터를 미리 가져다 놓는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*버퍼 : 속도 차이가 있는 두 장치 사이에서 그 차이를 완화하는 역할을 하는 장치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리와 CPU 사이의 속도 차이가 매우 크기 때문에 중간에 레지스터 계층을 둬서 차이를 해결한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 속도 차이를 해결하기 위해 계층과 계층 사이에 있는 계층을 캐싱 캐층이라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 캐시와 보조기억장치 사이에 있는 주기억장치는 캐싱 계층이라 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*레지스터와 캐시의 차이 : &lt;span style=&quot;background-color: #ffffff; color: #3d4144;&quot;&gt;레지스터에 들어오는 데이터는 처리되기 위해서 들어오는 것이며 저장되기 위해 들어오는 것이 아니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #3d4144;&quot;&gt;레지스터는 데이터 처리를 위한 구성요소이며 CPU 의 필수 구성요소이지만, 캐시는 저장을 위한 메모리로 CPU 의 보조 구성요소이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #3d4144;&quot;&gt;레지스터는 데이터 연산을 위해 반드시 필요하지만, 캐시는 버퍼 역할로 있는 것이기 때문에 부가적 요소로 보는 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;비휘발성 메모리&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;보조기억장치&lt;/b&gt; : HDD, SSD를 일컬으며 비휘발성, 속도 느림, 기억 용량이 많다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 계층을 두고 이야기하는 이유는 &lt;b&gt;경제성&lt;/b&gt;과 &lt;b&gt;캐시&lt;/b&gt; 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;속도가 빠르고 값이 비싼 메모리를 CPU 가까운 쪽에 두고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;값이 싸고 용량이 큰 메모리를 반대쪽에 배치하여 적당한 가격으로 빠른 속도와 큰 용량을 동시에 얻기 위함이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 CPU와 가까운 쪽에 레지스터나 캐시를 배치하여 CPU가 작업을 빨리 진행할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리에서 작업한 내용을 하드디스크와 같이 저렴하고 용량이 큰 메모리에 영구적으로 저장할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게임 실행 중에 '로딩 중'과 같은 메시지를 나오는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 하드 디스크 또는 인터넷에서 데이터를 읽어 메모리 계층에 따라 RAM으로 전송하는 과정이 아직 끝나지 않은 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;li&gt;조성호, 쉽게 배우는 운영체제, 한빛아카데미(2018)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kimziont.github.io/computer_structure/memory/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Jay's Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/Operating System</category>
      <category>cache</category>
      <category>cs</category>
      <category>Operating System</category>
      <category>OS</category>
      <category>RAM</category>
      <category>메모리</category>
      <category>메모리 계층</category>
      <category>캐시</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/46</guid>
      <comments>https://hapen385.tistory.com/46#entry46comment</comments>
      <pubDate>Sat, 28 Jan 2023 09:20:56 +0900</pubDate>
    </item>
    <item>
      <title>[Operating System] 컴퓨터의 요소</title>
      <link>https://hapen385.tistory.com/45</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;컴퓨터의 요소&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2023. 1. 27. - 0 2.jpg&quot; data-origin-width=&quot;1211&quot; data-origin-height=&quot;795&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXw6ma/btrXml8rJpk/kPMcLzvUDDzN4puNc8krJk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXw6ma/btrXml8rJpk/kPMcLzvUDDzN4puNc8krJk/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXw6ma/btrXml8rJpk/kPMcLzvUDDzN4puNc8krJk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXw6ma%2FbtrXml8rJpk%2FkPMcLzvUDDzN4puNc8krJk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;578&quot; height=&quot;379&quot; data-filename=&quot;2023. 1. 27. - 0 2.jpg&quot; data-origin-width=&quot;1211&quot; data-origin-height=&quot;795&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터는 CPU, DMA 컨트롤러, 메모리, 타이머, 디바이스 컨트롤러 등으로 이루어져 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;CPU(Central Processing Unit)&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;산술논리연산장치, 제어장치, 레지스터로 구성되어 있는 컴퓨터 장치&lt;/li&gt;
&lt;li&gt;인터럽트에 의해 단순히 메모리에 존재하는 명령어를 해석해서 실행&lt;/li&gt;
&lt;li&gt;커널이 프로그램을 메모리에 올려 프로세스를 만들면 CPU가 이를 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;제어장치(Control Unit, CU)&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로세스 조작을 지시하는 CPU의 한 부품&lt;/li&gt;
&lt;li&gt;입출력장치 간 통신을 제어&lt;/li&gt;
&lt;li&gt;명령어들을 읽고 해석&lt;/li&gt;
&lt;li&gt;데이터 처리를 위한 순서를 결정&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;레지스터&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CPU 안에 있는 매우 빠른 임시기억장치&lt;/li&gt;
&lt;li&gt;CPU와 직접 연결되어 있어 연산 속도가 메모리보다 수십 배 빠르다&lt;/li&gt;
&lt;li&gt;CPU가 자체적으로 데이터를 저장할 방법이 없어 레지스터를 거쳐 데이터를 전달&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;산술논리연산장치(Arithmetic Logic Unit, ALU)&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;덧셈, 뺄셈 같은 두 숫자의 산술 연산을 계산하는 디지털 회로&lt;/li&gt;
&lt;li&gt;배타적 논리합, 논리곱 같은 논리 연산도 계산&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;CPU의 연산 처리&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2023. 1. 27. - 0 3.jpg&quot; data-origin-width=&quot;1211&quot; data-origin-height=&quot;825&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHg03Z/btrXnIOSjOw/jlMl2j0kn86ehk4KQWpcs0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHg03Z/btrXnIOSjOw/jlMl2j0kn86ehk4KQWpcs0/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHg03Z/btrXnIOSjOw/jlMl2j0kn86ehk4KQWpcs0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHg03Z%2FbtrXnIOSjOw%2FjlMl2j0kn86ehk4KQWpcs0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;593&quot; height=&quot;404&quot; data-filename=&quot;2023. 1. 27. - 0 3.jpg&quot; data-origin-width=&quot;1211&quot; data-origin-height=&quot;825&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;제어장치가 메모리, 레지스터에 계산할 값을 로드&lt;/li&gt;
&lt;li&gt;제어장치가 레지스터에 있는 값을 계산하라고 ALU에 명령&lt;/li&gt;
&lt;li&gt;제어장치가 계산된 값을 다시 레지스터에서 메모리로 계산한 값을 저장&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;인터럽트&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;어떤 신호가 들어왔을 때 CPU를 잠깐 정지시키는 것&lt;/li&gt;
&lt;li&gt;키보드, 마우스 등 I/O 디바이스로 인해 발생&lt;/li&gt;
&lt;li&gt;0으로 숫자를 나누는 산술 연산에서 발생&lt;/li&gt;
&lt;li&gt;프로세스 오류로 인한 발생 등 다양한 이유로 발생&amp;nbsp;&lt;/li&gt;
&lt;li&gt;인터럽트 간에는 우선순위 존재&lt;/li&gt;
&lt;li&gt;우선순위에 따라 실행&lt;/li&gt;
&lt;li&gt;하드웨어 인터럽트, 소프트웨어 인터럽트 두 가지 존재&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터럽트가 발생하면 인터럽트 핸들러 함수가 모여 있는 인터럽트 벡터로 가서 인터럽트 핸들러 함수가 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*인터럽트 핸들러 함수 : 인터럽트가 발생했을 때 이를 핸들링하기 위한 함수, 커널 내부의 IRQ를 통해 호출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*IRQ : &lt;span style=&quot;background-color: #ffffff; color: #333333;&quot;&gt;인터럽트 요청(interrupt request)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;하드웨어 인터럽트&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키보드/마우스를 연결하는 것과 같은 I/O 디바이스에서 발생하는 인터럽트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;순차적인 인터럽트를 중지하고 운영체제에 시스템콜을 요청해서 원하는 디바이스로 향해 디바이스에 있는 작은 로컬 버퍼에 접근하여 일을 수행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;소프트웨어 인터럽트&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랩(trap)이라고도 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스 오류 등으로 프로세스가 시스템콜을 호출할 때 발동&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;DMA 컨트롤러&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;I/O 디바이스가 메모리에 접근할 수 있도록 하는 하드웨어 장치&lt;/li&gt;
&lt;li&gt;CPU에만 너무 많이 들어오는 인터럽트 요청으로 인한 CPU의 부하를 막아준다&lt;/li&gt;
&lt;li&gt;CPU의 일을 부담하는 보조 일꾼&lt;/li&gt;
&lt;li&gt;하나의 작업을 CPU와 DMA 컨트롤러가 동시에 하는 것을 방지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;메모리&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;전자회로에서 데이터나 상태, 명령어 등을 기록하는 장치&lt;/li&gt;
&lt;li&gt;보통 &lt;b&gt;RAM(Random Access Memory)&lt;/b&gt;을 일컬어 메모리라 한다&lt;/li&gt;
&lt;li&gt;CPU는 계산을 담당, 메모리는 기억을 담당&lt;/li&gt;
&lt;li&gt;메모리가 클수록 많은 일을 동시에 할 수 있다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;타이머&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;몇 초 안에는 작업이 끝나야 한다는 것을 정한다&lt;/li&gt;
&lt;li&gt;특정 프로그램에 시간 제한을 다는 역할&lt;/li&gt;
&lt;li&gt;&lt;b&gt;시간이 많이 걸리는 프로그램이 작동할 때 제한&lt;/b&gt;을 걸기 위해 존재&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;디바이스 컨트롤러&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컴퓨터와 연결되어 있는 I/O 디바이스들의 작은 CPU&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;li&gt;조성호, 쉽게 배우는 운영체제, 한빛아카데미(2018)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/Operating System</category>
      <category>ALU</category>
      <category>CPU</category>
      <category>CS지식</category>
      <category>Operating System</category>
      <category>OS</category>
      <category>메모리</category>
      <category>운영체제</category>
      <category>인터럽트</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/45</guid>
      <comments>https://hapen385.tistory.com/45#entry45comment</comments>
      <pubDate>Fri, 27 Jan 2023 21:10:54 +0900</pubDate>
    </item>
    <item>
      <title>[Operating System] 운영체제 개요</title>
      <link>https://hapen385.tistory.com/44</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;운영체제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 컴퓨터를 쉽게 다루게 해주는 인터페이스.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한정된 메모리나 시스템 자원을 효율적으로 분배하는 역할.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예) PC 운영체제(Mac OS, Windows, 유닉스, 리눅스 등), 모바일 운영체제(iOS, 안드로이드 등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*운영체제와 유사하나 소프트웨어를 추가로 설치할 수 없는 것이 &lt;b&gt;펌웨어(Firmware)&lt;/b&gt;. 펌웨어는 특정 하드웨어에 포함된 소프트웨어를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;운영체제의 역할&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;CPU 스케줄링과 프로세스 관리 : CPU 소유권을 &lt;b&gt;어떤 프로세스에 할당&lt;/b&gt;할지, 프로세스의 &lt;b&gt;생성과 삭제&lt;/b&gt;, &lt;b&gt;자원 할당&lt;/b&gt; 및 &lt;b&gt;반환&lt;/b&gt; 관리&lt;/li&gt;
&lt;li&gt;메모리 관리 : 한정된 메모리를 어떤 프로세스에 &lt;b&gt;얼마큼 할당할지&lt;/b&gt;를 관리&lt;/li&gt;
&lt;li&gt;디스크 파일 관리 : 디스크 파일의 &lt;b&gt;보관 방법&lt;/b&gt;을 관리&lt;/li&gt;
&lt;li&gt;I/O 디바이스 관리 : I/O 디바이스들(마우스, 키보드 등)과 컴퓨터 간에 &lt;b&gt;데이터를 주고 받는 것&lt;/b&gt;을 관리&lt;/li&gt;
&lt;li&gt;자원 보호 : &lt;b&gt;비정상적인 작업으로부터&lt;/b&gt; 컴퓨터 자원을 &lt;b&gt;보호&lt;/b&gt;, 사용자가 직접 자원에 접근하는 것을 막음으로써 컴퓨터 자원을 보호.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;운영체제의 구조&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-01-27 오전 11.23.41.png&quot; data-origin-width=&quot;554&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tv0F9/btrXfMys8EE/5F9snk6Rjpr7tRMsW0f6w0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tv0F9/btrXfMys8EE/5F9snk6Rjpr7tRMsW0f6w0/img.png&quot; data-alt=&quot;출처 : 쉽게 배우는 운영체제(2018)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tv0F9/btrXfMys8EE/5F9snk6Rjpr7tRMsW0f6w0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ftv0F9%2FbtrXfMys8EE%2F5F9snk6Rjpr7tRMsW0f6w0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;498&quot; height=&quot;345&quot; data-filename=&quot;스크린샷 2023-01-27 오전 11.23.41.png&quot; data-origin-width=&quot;554&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 쉽게 배우는 운영체제(2018)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;인터페이스(GUI)&lt;/b&gt; : 사용자가 전자장치와 상호 작용할 수 있도록 하는 사용자 인터페이스의 한 형태, 단순 명령어 창이 아닌 아이콘을 마우스로 클릭하는 단순한 동작으로 컴퓨터와 상호작용할 수 있도록 함&lt;/li&gt;
&lt;li&gt;&lt;b&gt;시스템 호출(시스템콜)&lt;/b&gt; : 운영체제가 커널에 접근하기 위한 인터페이스, 유저 프로그램이 운영체제의 서비스를 받기 위해 커널 함수를 호출할 때 사용, 커널이 자신을 보호하기 위해 만든 인터페이스, 사용자나 응용 프로그램으로부터 컴퓨터 자원을 보호하기 위해 자원에 직접 접근하는 것을 차단.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;커널&lt;/b&gt; : 프로세스 관리, 메모리 관리, 저장장치 관리와 같은 운영체제의 핵심적인 기능을 모아놓은 것&lt;/li&gt;
&lt;li&gt;&lt;b&gt;드라이버&lt;/b&gt; : 하드웨어를 제어하기 위한 소프트웨어, 커널과 하드웨어의 인터페이스를 담당하며 디바이스 드라이버라고도 불림, 마우스와 같이 간단한 제품은 드라이버를 커널이 갖고 있으나 그래픽 카드와 같이 복잡한 하드웨어의 경우 제작자가 드라이버를 제공.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*CUI : 그래픽이 아닌 명령어로 처리하는 인터페이스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;시스템 호출(시스템콜) 과정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유저 프로그램이 I/O 요청으로 트랩(trap)을 발동하면, 올바른 I/O 요청인지 확인한 후 유저 모드가 시스템콜을 통해 커널 모드로 변환되어 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*트랩(trap) :&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;트랩은 Interrupt의 한 종류로서 명령의 수행 결과로 발생, &lt;span style=&quot;color: #555555;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;주로 시스템콜을 호출할 때나 Segmentation fault(할당되지 않은 메모리 참조)로 인해 발생&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;*인터럽트(Interrupt) : 어떤 신호가 들어왔을 때 CPU를 잠깐 정지시키는 것, 키보드, 마우스 등 IO 디바이스로 인한 인터럽트, 0으로 숫자를 나누는 산술 연산에서의 인터럽트, 프로세스 오류 등으로 발생&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_4012.jpg&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;806&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dFwpeZ/btrXlhFgmVn/D6mcckb2sWLioGSkvuLRX1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dFwpeZ/btrXlhFgmVn/D6mcckb2sWLioGSkvuLRX1/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dFwpeZ/btrXlhFgmVn/D6mcckb2sWLioGSkvuLRX1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdFwpeZ%2FbtrXlhFgmVn%2FD6mcckb2sWLioGSkvuLRX1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;470&quot; height=&quot;337&quot; data-filename=&quot;IMG_4012.jpg&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;806&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;I/O 요청인 fs.readFile()이라는 파일 시스템의 파일을 읽는 함수가 발동&lt;/li&gt;
&lt;li&gt;유저 모드에서 파일을 읽지 않음&lt;/li&gt;
&lt;li&gt;유저 모드에서 커널 모드로 들어가 파일을 읽음&lt;/li&gt;
&lt;li&gt;다시 유저 모드로 돌아옴&lt;/li&gt;
&lt;li&gt;유저 프로그램의 로직 수행&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 과정을 통해 컴퓨터 자원에 대한 직접 접근을 차단할 수 있고 프로그램을 다른 프로그램으로부터 보호할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*I/O 요청 : 입출력 함수, 데이터베이스, 네트워크, 파일 접근에 관한 일&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_4013.jpg&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;806&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cWIADx/btrXmpCSG6b/4EKXnSPkev28Zmdp39PuOK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cWIADx/btrXmpCSG6b/4EKXnSPkev28Zmdp39PuOK/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cWIADx/btrXmpCSG6b/4EKXnSPkev28Zmdp39PuOK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcWIADx%2FbtrXmpCSG6b%2F4EKXnSPkev28Zmdp39PuOK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;477&quot; height=&quot;342&quot; data-filename=&quot;IMG_4013.jpg&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;806&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스와 스레드에서 운영체제로 어떤 요청을 할 때는, 시스템콜이라는 인터페이스와 커널을 거쳐 운영체제에 요청이 전달된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스템콜은 추상화 계층이므로 네트워크 통신이나 데이터베이스와 같은 낮은 단계의 영역 처리에 대한 부분을 많이 신경쓰지 않고 프로그램을 구현할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*추상화 계층 : 특정한 집합 기능의 자세한 부분을 숨기는 기법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;modebit&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1 또는 0의 값을 가지는 플래그 변수, 시스템콜이 작동될 때 modebit를 참고하여 유저 모드와 커널 모드를 구분한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카메라와 키보드 등 I/O 디바이스는 운영체제를 통해서만 작동해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 유저 모드 기반으로 카메라가 켜진다면 사용자가 의도하지 않았는데 공격자가 카메라를 갑자기 켤 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 위험은 운영체제를 통해 작동해야 막기가 쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 그림과 같은 과정을 통해 I/O 디바이스가 작동한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2023. 1. 27. - 0.jpg&quot; data-origin-width=&quot;1159&quot; data-origin-height=&quot;688&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JHjkm/btrXnvhQhq2/qk9KZGxSdhKx78SUdpmKG0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JHjkm/btrXnvhQhq2/qk9KZGxSdhKx78SUdpmKG0/img.jpg&quot; data-alt=&quot;출처 : 면접을 위한 CS 전공지식 노트(2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JHjkm/btrXnvhQhq2/qk9KZGxSdhKx78SUdpmKG0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJHjkm%2FbtrXnvhQhq2%2Fqk9KZGxSdhKx78SUdpmKG0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;569&quot; height=&quot;338&quot; data-filename=&quot;2023. 1. 27. - 0.jpg&quot; data-origin-width=&quot;1159&quot; data-origin-height=&quot;688&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 면접을 위한 CS 전공지식 노트(2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 위한 장치가 modebit이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;modebit의 0은 커널 모드, 1은 유저 모드이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*유저 모드 : 유저가 접근할 수 있는 영역을 제한적으로 두며 컴퓨터 자원에 함부로 침범하지 못하는 모드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*커널 모드 : 모든 컴퓨터 자원에 접근할 수 있는 모드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주홍철, 면접을 위한 CS 전공지식 노트, 길벗(2022)&lt;/li&gt;
&lt;li&gt;조성호, 쉽게 배우는 운영체제, 한빛아카데미(2018)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ju-hy.tistory.com/8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Joogle&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Computer Science/Operating System</category>
      <category>cs</category>
      <category>CS지식</category>
      <category>Operating System</category>
      <category>OS</category>
      <category>시스템콜</category>
      <category>시스템호출</category>
      <category>운영체제</category>
      <category>운영체제 구조</category>
      <category>운영체제 역할</category>
      <category>커널</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/44</guid>
      <comments>https://hapen385.tistory.com/44#entry44comment</comments>
      <pubDate>Fri, 27 Jan 2023 20:22:45 +0900</pubDate>
    </item>
    <item>
      <title>[Android] Android Architecture Components(AAC)</title>
      <link>https://hapen385.tistory.com/43</link>
      <description>&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;안드로이드 개발자 채용 공고를 보면 'AAC 적용 경험'을 요구하는 곳을 볼 수 있다. 따라서 어떤 것인지 궁금했고 최근에 프로젝트에 AAC의 ViewModel을 적용해보았다. 실제로 적용해보며, 데이터를 편하게 관리할 수 있었다. 또한 context가 필요할 때 AAC ViewModel을 사용하였다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;ViewModel을 써보면서 또 어떤 다른 장점이 있길래, 구글이 AAC를 따로 만들어냈는지 그 이유가 궁금했다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;이에 대해 알아보고 ViewModel 이외에 다른 AAC(Component)는 어떤 것이 있는지 정리해보려 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;touchicon-180.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgLocF/btrN4jL63tl/YkIUaJLlBtV7d2WY4Bc3Yk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgLocF/btrN4jL63tl/YkIUaJLlBtV7d2WY4Bc3Yk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgLocF/btrN4jL63tl/YkIUaJLlBtV7d2WY4Bc3Yk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgLocF%2FbtrN4jL63tl%2FYkIUaJLlBtV7d2WY4Bc3Yk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;180&quot; height=&quot;180&quot; data-filename=&quot;touchicon-180.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;1. AAC는 무엇인가?&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;2. AAC에는 어떤 Component가 있는가?&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;3. AAC의 활용&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Android Architecture Components(AAC)는 무엇인가?&lt;/span&gt;&lt;/h3&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;개요&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Activity나 Fragment의 LifeCycle을 관리하며, 메모리 누수를 방지하는 것은 복잡할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;유지보수가 용이하도록 애플리케이션에 권장 아키텍처를 적용하는 것 또한 어려운 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 문제들을 해결하고 정교한 애플리케이션을 쉽게 만들기 위해, AAC를 활용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;정의&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;애플리케이션을 강력하고 테스트, 유지보수를 쉽게 할 수 있도록 디자인할 수 있게 해주는 라이브러리 모음&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 말하자면, AAC는 생명 주기 상태 변화와 구성 변경(Configuration changes)에도 데이터의 지속성을 보장하는데 도움이 되는 라이브러리 모음이다. 또한, 프로그램 설계를 용이하게 하여 각각의 클래스들을 테스트와 유지보수가 쉽도록 해준다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;AAC에는 어떤 Component가 있는가?&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2018-05-05 at 11.49.30 AMimage1.png&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;808&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/37Z4b/btrN4DRfWlR/HgOHWthkFwGVGiOg1f06lK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/37Z4b/btrN4DRfWlR/HgOHWthkFwGVGiOg1f06lK/img.png&quot; data-alt=&quot;출처 :&amp;amp;amp;nbsp;https://android-developers.googleblog.com/2018/05/use-android-jetpack-to-accelerate-your.html&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/37Z4b/btrN4DRfWlR/HgOHWthkFwGVGiOg1f06lK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F37Z4b%2FbtrN4DRfWlR%2FHgOHWthkFwGVGiOg1f06lK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;808&quot; data-filename=&quot;Screen Shot 2018-05-05 at 11.49.30 AMimage1.png&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;808&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;amp;nbsp;https://android-developers.googleblog.com/2018/05/use-android-jetpack-to-accelerate-your.html&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Android Jetpack 에서 Architecture 부분이 AAC에 해당된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AAC의 Component들은 블럭이고, 이 블럭들을 쌓아 정교한 애플리케이션을 만드는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(안드로이드 공식 블로그에서는 이 과정을 &lt;b&gt;Building Blocks&lt;/b&gt;라고 표현해놓았다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;UI Layer Libraries&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Lifecycle-aware Components&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Lifecycle-aware Components는 Activity나 Fragment의 수명주기(Lifecycle)의 변화를 감지하고, 이에 따라 기능을 하는 Component이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;대표적으로 LiveData가 있다. LiveData는 수명 주기를 인식하는 클래스이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;클래스 자체가 Lifecycle-aware Component가 아니더라도,&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;LifecycleObserver 인터페이스를 구현하여, 클래스가 수명 주기를 인식하도록 할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이때 LifecycleObserver를 간단하게 설명하자면,&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;LifecycleObserver 인터페이스는 수명 주기를 관리하는데, 이때 LifecycleObserver 인터페이스가 구현된 클래스를 Observer라고 한다. 그리고 이 Observer가 관리하는 수명 주기를, 갖고 있는 Activity나 Fragment을 Owner라고 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LiveData&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;LiveData는 수명 주기를 인식하는 데이터 홀더 클래스이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;애플리케이션 구성 요소(Activity, Fragment, Service 등)의 수명 주기를 인식한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;LiveData는 수명 주기가 비활성 단계였을 때 STARTED 이거나 RESUMED 와 같은 활성 단계로 변하면 데이터를 업데이트한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;수명 주기가 DESTROYED 되었을 때, LiveData도 자동으로 제거된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이외에도 수명 주기와 관련된 기능을 하여 메모리 누수 방지와 같은 다양한 이점이 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ViewModel&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;ViewModel은 UI에 필요한 데이터를 갖고 있는 클래스이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;ViewModel도 역시 수명 주기와 관련된 기능을 수행하고 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;구성 변경이 일어나면, Activity나 Fragment가 소멸되고 다시 생성되는데,&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이때 ViewModel을 사용하면 데이터가 사라지지 않고 유지되는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;ViewModel은 Activity, Fragment와 비슷하게 수명 주기를 갖고 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Data Binding&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Data Binding은 View Binding과 비슷하게, 데이터 소스와 UI Component를 연결해주는 라이브러리다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;View Binding과의 차이점은 여러 개 있지만, 그 중 하나는 Data Binding만 양방향 바인딩이 가능하다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;양방향 바인딩은, 데이터에 변경 사항이 있다면 View에 반영이 되며 그 반대로도 성립이 되는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MVVM 패턴을 적용할 때, Data Binding이 많이 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewModel에 의존적인 View에 Data Binding을 적용하면서 커플링(Coupling)을 줄이기 위해 주로 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*커플링(Coupling) : 소프트웨어 모듈 간의 상호 의존성의 정도 (출처 : 위키피디아)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Paging&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Paging은 많은 데이터를 불러올 때 한 번에 다 불러오는 것이 아니라, 나누어서 불러올 수 있도록 하는 라이브러리다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Paging 라이브러리를 사용하면, 네트워크 대역폭과 시스템 자원을 효율적으로 사용할 수 있다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RecyclerView와 함께 사용하면 데이터 목록을 스크롤 하면서 데이터를 쪼개어서 불러올 수 있게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Room에서 데이터를 나누어서 불러와, View에 반영할 때 ViewModel, LiveData와도 함께 잘 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Navigation&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Navigation은 복잡한 화면 이동을 쉽게 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버튼을 누르고 다른 화면으로 넘어가는 것은 단순히 Intent를 많이 사용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 Bottom Navigation과 같이 하나의 Activity에서 여러 개의 Fragment를 관리하는 경우,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fragment가 많아질 수록 관리가 어려워지는 경향이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 Navigation Component의 Navigation graph, NavHost, NavController 를 통해 쉽게 화면 이동을 관리할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Navigation graph를 사용하면 화면 이동의 로직을 시각화하여 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;화면 이동 시 넘어간 데이터, 애니메이션 정보 등을 볼 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NavHost는 여러 레이아웃을 추가할 빈 화면이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NavController는 NavHost의 화면 변환 액션을 수행하는 객체이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 아래와 같은 코드를 입력하면 NavController가 액션을 수행한다.&lt;/p&gt;
&lt;pre id=&quot;code_1671591651951&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;findNavController().navigate(R.id.win_action)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;Data Layer Libraries&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;WorkManager&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WorkManager는 백그라운드 처리에 사용되는 API다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백그라운드 작업을 예약하거나, 배터리 부족 모드와 같은 제약 조건을 걸고 백그라운드 작업을 시행할 수 있도록 할 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Room&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Room은 로컬 데이터베이스를, 높은 지속성을 갖고 관리할 수 있는 라이브러리다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;기기가 네트워크 접속이 안될 때도 콘텐츠를 이용할 수 있도록 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;로컬 데이터베이스인 SQLite와 다른 점이 있다면,&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;SQLite는 쿼리에 대한 에러를 컴파일 시간에 확인할 수 없지만 Room은 컴파일 시간에 확인할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;SQLite는 쿼리와 데이터 객체를 변환할 때 Boilerplate 코드를 많이 작성해줘야 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;하지만, Room은 Boilerplate 코드 없이도 간편하게 데이터베이스 객체를 매핑시켜줄 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;또한, SQLite의 경우 스키마가 바뀌면 일일이 쿼리를 업데이트해줘야 하지만 Room은 수동으로 업데이트해줄 필요 없다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;AAC의 활용&lt;/span&gt;&lt;/h3&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;App Architecture 설계에 AAC를 활용&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;MVVM 패턴을 적용할 때 AAC를 활용할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;(물론 다른 아키텍처 패턴에도 AAC를 활용할 수 있다)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;0_PKo4mQsOOGUqPlVp.png&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qZPzm/btrUcfoxvyg/AhSJHAuXV2fqkN6EZvvzYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qZPzm/btrUcfoxvyg/AhSJHAuXV2fqkN6EZvvzYk/img.png&quot; data-alt=&quot;출처 : android developers&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qZPzm/btrUcfoxvyg/AhSJHAuXV2fqkN6EZvvzYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqZPzm%2FbtrUcfoxvyg%2FAhSJHAuXV2fqkN6EZvvzYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;540&quot; height=&quot;405&quot; data-filename=&quot;0_PKo4mQsOOGUqPlVp.png&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : android developers&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Activity/Fragment가 &lt;b&gt;View&lt;/b&gt;.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;AAC ViewModel이 &lt;b&gt;ViewModel&lt;/b&gt;이 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이때 UI에 필요한 데이터는 LiveData를 사용한다. 이를 통해 수명 주기를 인식하며 데이터를 관리할 수 있도록 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Room 라이브러리의 캐시 데이터와 Retrofit으로 받아온 데이터가 &lt;b&gt;Model&lt;/b&gt;이 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size14&quot;&gt;AAC를 써보기는 했지만 몇 개만 써본 것이라 다른 Component에 대해서 많이 궁금했다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size14&quot;&gt;이번 포스팅을 통해 대략 정리가 된 느낌이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size14&quot;&gt;근데 AAC의 각 Component들에 대한 설명이 약간 길어진 것 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size14&quot;&gt;그리고 각 Component들은 부가적인 설명이 필요해서, 따로 글을 다 작성해야 할 필요가 있어 보임&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.android.com/topic/architecture&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Google android docs(Android Developers)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/android/architecture-components-samples&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Github android-architecture-components-samples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://android-developers.googleblog.com/2017/05/android-and-architecture.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Android and Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://youtu.be/FrteWKKVyzI&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Youtube(Architecture components - introduction (Google I/O '17))&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Android/Widget</category>
      <category>aac</category>
      <category>Android</category>
      <category>Android Architecture Component</category>
      <category>Architecture Component</category>
      <category>안드로이드</category>
      <category>안드로이드 개발</category>
      <category>안드로이드 아키텍처</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/43</guid>
      <comments>https://hapen385.tistory.com/43#entry43comment</comments>
      <pubDate>Wed, 21 Dec 2022 12:55:34 +0900</pubDate>
    </item>
    <item>
      <title>[Architecture Pattern] MVP 패턴</title>
      <link>https://hapen385.tistory.com/42</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;MVC, MVVM 패턴에 이어서, 많이 사용되는 MVP 패턴에 대해서도 공부해보고자 한다. MVP 패턴도 공부해서 이때까지 공부해본 여러 아키텍처 패턴의 특징에 맞게 프로젝트에 적용해보고 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 포스팅은 안드로이드 아키텍처 기준으로 작성되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333; background-color: #ffc9af;&quot;&gt;1. MVP 패턴이란?&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MVP 패턴은 Model, View, Presenter 이 세 가지 역할로 어플리케이션(프로그램)을 분리해놓은 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MVC 패턴과는 한 가지만 다르다. MVC의 Controller 대신에 Presenter가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;2. MVP 패턴의 구조&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MVP 패턴은 Model, View, Presenter로 구성되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;MVP-Android.png&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;465&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4fHgc/btrLhXqIEtO/YUgXut74PgX84R8IgZcbZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4fHgc/btrLhXqIEtO/YUgXut74PgX84R8IgZcbZk/img.png&quot; data-alt=&quot;출처 : laptrinhx(https://laptrinhx.com/how-to-adopt-model-view-presenter-on-android-3112038880/)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4fHgc/btrLhXqIEtO/YUgXut74PgX84R8IgZcbZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4fHgc%2FbtrLhXqIEtO%2FYUgXut74PgX84R8IgZcbZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;381&quot; height=&quot;295&quot; data-filename=&quot;MVP-Android.png&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;465&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : laptrinhx(https://laptrinhx.com/how-to-adopt-model-view-presenter-on-android-3112038880/)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Model&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;프로그램에서 다루는 데이터를 가지고 있고 그 데이터를 처리하는 부분&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;데이터 처리하는 역할&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;안드로이드에서는&amp;nbsp;APIClient, Dao 등등&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;View&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333;&quot;&gt;UI 부분&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333;&quot;&gt;렌더링하는 역할&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;Model의 데이터를 Presenter를 통해 받아 해당 데이터를 화면에 보여주는 역할을 한다.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333;&quot;&gt;사용자의 입력(Action)을 받는다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333;&quot;&gt;사용자의 입력(Action) : ex)버튼 클릭, 아이템 목록 스크롤 등등&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333;&quot;&gt;안드로이드에서는 Activity, Fragment가 해당&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333;&quot;&gt;Presenter&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Model과 View의 중개자 역할&lt;/li&gt;
&lt;li&gt;View로부터 사용자 이벤트(앱과의 상호작용)을 전달받는다.&lt;/li&gt;
&lt;li&gt;View로부터 전달받은 이벤트에 따라 Model을 호출하기도 한다.&lt;/li&gt;
&lt;li&gt;Presenter와 View는 1:1이다.&lt;/li&gt;
&lt;li&gt;Model로부터 받은 데이터를 View에게 알려 UI를 수정하기도 한다.&lt;/li&gt;
&lt;li&gt;View을 interface로 조작한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이때문에 MVC 패턴보다 독립성이 더 크고, 개발 환경 변화에 유연하게 대응할 수 있다는 장점이 있다.&lt;/li&gt;
&lt;li&gt;MVC 패턴의 Controller는 직접적으로 View와 연결을 한다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;반면 MVP 패턴은 직접 필요한 것을 주고 받는 것이 아니라, interface를 통해 주고 받는다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;동작순서&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;View로부터 사용자 입력이 들어온다.&lt;/li&gt;
&lt;li&gt;View는 필요한 데이터를 Presenter에게 요청한다.&lt;/li&gt;
&lt;li&gt;Presenter는 Model에게 데이터를 요청한다.&lt;/li&gt;
&lt;li&gt;Model은 데이터를 Presenter에게 전달한다.&lt;/li&gt;
&lt;li&gt;Presenter는 업데이트된 데이터를 View에게 전달한다.&lt;/li&gt;
&lt;li&gt;View는 받은 데이터를 화면에 나타낸다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;3. 장점&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Model과 View 사이의 의존성이 전혀 없다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;테스트에 더 용이해질 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;View와 Presenter는 interface를 통해 상호작용하므로, MVC 패턴의 Controller보다 더 독립적이고 유연하게 모듈화가 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;4. 문제점&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;어플리케이션이 복잡해질 수록, View와 Presenter 사이의 의존성이 높아질 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MVC 패턴에서 더 발전된 것 같지만, MVP 역시 문제점을 갖고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 MVVM 보다는 설계하기에는 더 쉽지 않을까 생각이 든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 로직의 프로젝트에서 테스트를 쉽게 하고 싶다면 MVP 패턴을 적용해야 할 듯 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://brunch.co.kr/@mobiinside/913&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Mobiinside님 브런치(안드로이드 어플리케이션에 MVP패턴을 적용하는 방법)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://beomy.tistory.com/43&quot;&gt;버미노트([디자인패턴] MVC,MVP, MVVM&amp;nbsp; 비교)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/android-news/mvp-depp-dive-c6bb1903ace1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Budhdi Sharma medium(MVP Deep Dive)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://qiita.com/takahirom/items/597c48ece57b4623cdee&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Qiita(StackOverFlowの「MVPとMVCの違い」についての回答を読んでみた)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;a href=&quot;https://medium.com/@budhdisharma?source=post_page-----c6bb1903ace1--------------------------------&quot;&gt;&amp;nbsp;&lt;/a&gt;&lt;/h2&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Design Pattern</category>
      <category>Android</category>
      <category>Architecture Pattern</category>
      <category>MVC 패턴</category>
      <category>MVP</category>
      <category>MVP 패턴</category>
      <category>MVVM</category>
      <category>디자인 패턴</category>
      <category>아키텍처 패턴</category>
      <category>안드로이드</category>
      <category>안드로이드 디자인 패턴</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/42</guid>
      <comments>https://hapen385.tistory.com/42#entry42comment</comments>
      <pubDate>Sun, 4 Sep 2022 01:52:20 +0900</pubDate>
    </item>
    <item>
      <title>[Architecture Pattern] MVVM 패턴</title>
      <link>https://hapen385.tistory.com/41</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드를 개발할 때 가장 많이 권장된다는, 구글이 권장하는.., MVVM 패턴을 공부해보고자 한다. 아키텍처 패턴이 각각의 장단점이 있지만, MVVM이 어떻길래 권장되는지 상당히 궁금했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 포스팅은 안드로이드 아키텍처 기준으로 작성되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. MVVM 패턴이란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MVVM 패턴은 Model, View, ViewModel로 세 가지 역할로 프로그램을 분담하여 나눈 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드에서의 MVC 패턴은 View와 Model 사이의 의존성이 높다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 MVC 패턴에서는 View와 Controller가 함께 Activity나 Fragment에 있다....&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(이에 대한 자세한 예시는 추후에 MVC 패턴 예제 포스팅을 작성해볼 예정이다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 두 모듈 간의 결합도가 높으면, 추후에 프로그램이 커졌을 때 유지보수가 어려워지는 경향이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기능이 추가되었을 때, 의존성이 높은 모듈끼리 영향이 잘 미치게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(기능을 수정을 할 때도 마찬가지이다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MVP(Model, View, Presenter) 패턴도 있으나 이 또한 프로그램이 복잡해질 수록, View와 Presenter 사이의 의존성이 높아진다는 단점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MVVM 패턴은 MVC, MVP 패턴과 달리 각각의 부분이 의존성이 높지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(이렇기 때문에 프로그램이 커질 수록 MVVM 패턴이 권장되는 것 같다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 역할들 간의 의존성을 없애기 위해 MVVM 패턴을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. MVVM 패턴의 구조&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MVVM패턴은 Model, View, ViewModel 세 가지로 나뉜다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;mvvm-1.png&quot; data-origin-width=&quot;804&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dandfU/btrK0NU98e8/pTD4TqKZOku0SU31SjHvH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dandfU/btrK0NU98e8/pTD4TqKZOku0SU31SjHvH0/img.png&quot; data-alt=&quot;출처 :&amp;amp;amp;nbsp;http://kyubid.com/blog/understanding-mvvm-on-android-tutorial-05-introduction-to-reactive-programming-with-rxjava/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dandfU/btrK0NU98e8/pTD4TqKZOku0SU31SjHvH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdandfU%2FbtrK0NU98e8%2FpTD4TqKZOku0SU31SjHvH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;404&quot; height=&quot;515&quot; data-filename=&quot;mvvm-1.png&quot; data-origin-width=&quot;804&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;amp;nbsp;http://kyubid.com/blog/understanding-mvvm-on-android-tutorial-05-introduction-to-reactive-programming-with-rxjava/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Model&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램에서 다루는 데이터를 가지고 있고 그 데이터를 처리하는 부분&lt;/li&gt;
&lt;li&gt;데이터 처리하는 역할&lt;/li&gt;
&lt;li&gt;보통 API 호출, DataBase 사용이 이루어진다.&lt;/li&gt;
&lt;li&gt;안드로이드에서는 &lt;span style=&quot;background-color: #ffffff;&quot;&gt;APIClient, Dao 등등&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;View&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #5c5c5c;&quot;&gt;UI 부분&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #5c5c5c;&quot;&gt;사용자의 입력(Action)을 받는다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #5c5c5c;&quot;&gt;사용자 Action : ex)버튼 클릭, 아이템 목록 스크롤 등등&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #5c5c5c;&quot;&gt;데이터 처리 결과를 출력한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #5c5c5c;&quot;&gt;렌더링하는 역할&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #5c5c5c;&quot;&gt;ViewModel의 데이터를 처리하는 메소드를 호출한다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #5c5c5c;&quot;&gt;ex) 버튼 누르면 viewModel.loadData()를 호출&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #5c5c5c;&quot;&gt;ViewModel&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Model로부터 데이터를 얻는다&lt;/li&gt;
&lt;li&gt;얻은 데이터를 &lt;b&gt;View에 표시하기 위해&lt;/b&gt; 데이터 처리 과정을 시행한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 처리하는 메소드를 정의한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Model로부터 데이터를 얻기 위한 메소드를 정의한다.&lt;/li&gt;
&lt;li&gt;얻은 데이터를 View에 표시하기 위해 데이터를 처리하는 메소드를 정의한다(선택)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;동작 순서&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;View로부터 사용자의 입력이 들어온다.&lt;/li&gt;
&lt;li&gt;View에서 들어온 입력을 Command 패턴으로 ViewModel에 입력을 전달한다.&lt;/li&gt;
&lt;li&gt;ViewModel이 Model에게 데이터를 요청한다.&lt;/li&gt;
&lt;li&gt;Model은 ViewModel로부터 요청받은 데이터를 응답한다.&lt;/li&gt;
&lt;li&gt;ViewModel은 Model로부터 받은 데이터를 처리하여 저장한다.&lt;/li&gt;
&lt;li&gt;View는 ViewModel과 DataBinding으로 화면에 데이터를 나타낸다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* Command 패턴 : 실행될 기능을 캡슐화함으로써 주어진 여러 기능을 실행할 수 있는 재사용성이 높은 클래스를 설계하는 패턴 (&lt;a href=&quot;https://gmlwjd9405.github.io/2018/07/07/command-pattern.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;참고&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;3. 장점&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 역할의 의존성이 없다(다른 부분을 의식할 필요가 없다)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;효율적인 Unit Test 시행이 가능하다.&lt;/li&gt;
&lt;li&gt;모듈화 개발이 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Model과 View 사이의 의존성이 없다.&lt;/li&gt;
&lt;li&gt;View와 ViewModel 사이의 의존성이 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;4. 문제점&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;View가 커질 수록, ViewModel이 커질 수 있다.&lt;/li&gt;
&lt;li&gt;어플리케이션이 커지면 Data Binding 때문에 메모리 소모가 빨라진다.&lt;/li&gt;
&lt;li&gt;ViewModel의 설계가 어렵다.&lt;/li&gt;
&lt;li&gt;단순한 프로젝트일 경우 적합하지 않은 패턴일 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 디자인 패턴보다 복잡한 패턴이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순한 로직을 가진 프로젝트에는 적합하지 않을 수가 있겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역시나 어떤 기술이든, 패턴이든, 각각의 장단점이 있기 때문에 적재적소에 사용하는 것이 옳은 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MVVM 또한 구글에서 권장했다고 해서 모든 프로젝트에 적용하는 것은 무리가 있어보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://qiita.com/s_emoto/items/08e46b18f72c3b303b12&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Qiita(【Android】MVVMについて)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://beomy.tistory.com/43&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;버미노트([디자인패턴] MVC, MVP, MVVM 비교)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://velog.io/@dev_space/MVVM-%ED%8C%A8%ED%84%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;dev_space.log(MVVM 패턴)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Design Pattern</category>
      <category>Design Pattern</category>
      <category>MVC패턴</category>
      <category>MVP패턴</category>
      <category>MVVM</category>
      <category>MVVM패턴</category>
      <category>디자인패턴</category>
      <category>아키텍처패턴</category>
      <category>안드로이드 아키텍처</category>
      <category>안드로이드 아키텍처 패턴</category>
      <category>안드로이드 패턴</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/41</guid>
      <comments>https://hapen385.tistory.com/41#entry41comment</comments>
      <pubDate>Tue, 30 Aug 2022 19:40:52 +0900</pubDate>
    </item>
    <item>
      <title>[Architecture Pattern] MVC 패턴</title>
      <link>https://hapen385.tistory.com/40</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이때까지 프로젝트를 하면서 코드가 복잡해지는 것에 대한 불편함을 느꼈다. 디자인 패턴을 적용하지 않고, UI 설정 코드와 데이터 받아오는 코드 등을 합쳐놓으니 굉장한 스파게티 코드가 된 것 같았다... 따라서 앞으로 하는 프로젝트는 모듈화와 디자인 패턴 적용에 집중해야 겠다고 생각했다. 여러 아키텍처 패턴 중 심플하다고 생각되는 MVC 패턴부터 알아보고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 포스팅은 안드로이드 아키텍처 기준으로 작성되었습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. MVC 패턴이란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MVC 패턴은 애플리케이션(응용 프로그램)을 서로 다른 역할로 분리해놓은 패턴 중 하나이다. 관심사 분리(S&lt;span style=&quot;background-color: #ffffff; color: #202122;&quot;&gt;eparation of Concerns&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #202122;&quot;&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;SoC)로도 알려져 있다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 관심사 분리(&lt;span style=&quot;background-color: #ffffff; color: #202122;&quot;&gt;separation of concerns&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #202122;&quot;&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;SoC)란?&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;In computer science, separation of concerns is a design principle for separating a&amp;nbsp;computer program into distinct sections. 출처 : 위키백과&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SoC를 컴퓨터 과학에서는, 컴퓨터 프로그램을 섹션별로 구분하여 분리해놓은 디자인 원칙을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MVC 패턴은 Model, View, Controller 이 세 가지 역할로 컴퓨터 프로그램을 분리해놓은 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주로 웹에서 많이 사용하며, 가장 많이 사용되는 패턴 중 하나다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. MVC 패턴의 구조&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.MVC 패턴이란?에서 언급했듯이, MVC 패턴은 세 가지 역할로 구성되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;MVC.png&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;439&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PdEbq/btrKWA3zVUp/MKkWUDbNcNL8I54BrvpsF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PdEbq/btrKWA3zVUp/MKkWUDbNcNL8I54BrvpsF1/img.png&quot; data-alt=&quot;출처 :&amp;amp;amp;nbsp;https://code.tutsplus.com/tutorials/an-introduction-to-model-view-presenter-on-android--cms-26162&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PdEbq/btrKWA3zVUp/MKkWUDbNcNL8I54BrvpsF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPdEbq%2FbtrKWA3zVUp%2FMKkWUDbNcNL8I54BrvpsF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;476&quot; height=&quot;348&quot; data-filename=&quot;MVC.png&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;439&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;amp;nbsp;https://code.tutsplus.com/tutorials/an-introduction-to-model-view-presenter-on-android--cms-26162&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Model&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램에서 다루는 데이터를 가지고 있고 그 데이터를 처리하는 부분&lt;/li&gt;
&lt;li&gt;데이터 처리하는 역할&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;View&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;UI 부분&amp;nbsp;(안드로이드에서는 Activity, Fragment, ... 등등)&lt;/li&gt;
&lt;li&gt;사용자에게 결과 출력하여 보여주는 부분&lt;/li&gt;
&lt;li&gt;Model의 데이터 상태를 인지하여 화면에 표시 ex)Model으로부터 받아온 데이터의 변경이 있을 경우 이를 인지하여 View를 업데이트 할 수 있다. 혹은 Model에서 데이터의 변경을 View에게 알린다음 View가 업데이트되는 방법도 있다.&lt;/li&gt;
&lt;li&gt;렌더링하는 역할&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Controller&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자의 입력을 받고 처리하는 부분. 사용자의 입력을 Model을 통해 처리하여 View에 나타낸다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;데이터를 처리할 Model을 결정한다.&lt;/li&gt;
&lt;li&gt;결과를 나타낼 View를 결정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;동작 순서&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Controller로 사용자의 입력이 들어온다.&lt;/li&gt;
&lt;li&gt;Controller는 Model의 데이터를 업데이트하고 Model을 호출한다.&lt;/li&gt;
&lt;li&gt;Controller는 Model을 나타낼 View를 선택한다.&lt;/li&gt;
&lt;li&gt;View는 Model 통해 화면에 데이터를 나타낸다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;역할 분담으로 프로그램의 독립성이 높아진다. 개발 환경 변경에도 유연하게 대응할 수 있다.&lt;/li&gt;
&lt;li&gt;비교적 단순한 구조로, 쉽게 분리할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 문제점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;View와 Model 사이의 의존하는 정도가 높다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모듈 간의 결합도가 높아지면 프로그램이 커질 수록 유지 보수가 어렵게 된다는 문제가 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;입력에 따른 출력의 조건이 복잡해질 수록 View와 Controller의 의존성이 높아질 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단해서 아키텍처 패턴 입문하는 용으로 쉽게 적용할 수 있지 않을까 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비교적 큰 프로젝트에서는 사용하면 문제점이 많을 패턴 같기도 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://qiita.com/tentom/items/de95f63bc9e2da2bd0bf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Qiita(MVC とは何かを 1 から学ぶ)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://beomy.tistory.com/43&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;버미노트([디자인패턴] MVC,MVP, MVVM&amp;nbsp; 비교)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://code.tutsplus.com/tutorials/an-introduction-to-model-view-presenter-on-android--cms-26162&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;envatotuts+(An Introduction to Model View Presenter on Android)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Design Pattern</category>
      <category>MVC</category>
      <category>MVP</category>
      <category>MVVM</category>
      <category>개발</category>
      <category>개발 디자인 패턴</category>
      <category>디자인패턴</category>
      <category>소프트웨어 디자인 패턴</category>
      <category>안드로이드</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/40</guid>
      <comments>https://hapen385.tistory.com/40#entry40comment</comments>
      <pubDate>Tue, 30 Aug 2022 17:41:11 +0900</pubDate>
    </item>
    <item>
      <title>[Android] ViewModel 개념</title>
      <link>https://hapen385.tistory.com/39</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;MVC와 같은 아키텍처 패턴을 본격적으로 프로젝트에 적용하기 전에, ViewModel이라는 것을 알게 되었다. UI 컨트롤러와 데이터 관리를 분리하기 위해 사용되는 것으로 일단은 알고 있다. 더 정확하게 ViewModel의 개념을 알기 위해 이번에 ViewModel에 대해서 공부하고 블로깅해보려 한다. 또한, ViewModel을 제대로 공부하는 것이 아키텍처 패턴을 알맞게 적용하는데 (당연하지만)큰 도움이 될 것이라 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;touchicon-180.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kVatE/btrJ74K3kGG/hPAAt2d2CbjJ02uqP7c5F0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kVatE/btrJ74K3kGG/hPAAt2d2CbjJ02uqP7c5F0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kVatE/btrJ74K3kGG/hPAAt2d2CbjJ02uqP7c5F0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkVatE%2FbtrJ74K3kGG%2FhPAAt2d2CbjJ02uqP7c5F0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;180&quot; height=&quot;180&quot; data-filename=&quot;touchicon-180.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;들어가기 전에 앞서서, 구분해야 할 것이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MVVM 패턴에 사용되는 개념 중에 ViewModel 이라는 것이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 안드로이드 Jetpack에 포함되는 클래스 중에 ViewModel 이라는 것이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(또한 Jetpack 클래스의 ViewModel은 Android Architecture Components(AAC)에 포함된다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 일단 JetPack에 포함된 ViewModel에 중점을 두고 설명할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아키텍처 패턴에서의 ViewModel은 MVVM 패턴을 설명하는 포스팅에서 자세히 설명을 해봐야 할 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. ViewModel 이란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(AAC)ViewModel은 LifeCycle(생명, 수명주기)를 인지하고 UI와 관련한 데이터를 저장하고 관리할 수 있도록 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 설명이 구글에서 말하는 ViewModel 클래스의 정의다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewModel은 데이터를 독립적으로 관리하기 위해서 만들어졌다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Activity나 Fragment에서 UI 컨트롤과 함께 데이터를 저장, 관리하면서 문제가 있었기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1.1 ViewModel이 만들어지기 이전의 문제&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Activity와 같은 View에서 종료되기 직전,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;onSaveInstanceState() 메소드가 호출된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;onSaveInstanceState()를 통해서 데이터를 저장할 수 있지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 저장되는 데이터는 대용량의 데이터는 적합하지 않고, 소용량(직렬화했다가 다시 직렬화할 수 있는 정도의 용량)의 데이터가 적합하다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 큰 용량의 데이터는 어떻게 저장해야 하는가?의 문제가 생겨난 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 또 다른 문제가 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Activity, Fragment와 같은 UI 컨트롤러에서 많은 역할을 하고 있어 호출 시에 시간이 굉장히 오래걸릴 수 있다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UI 컨트롤러는 본래 UI에 데이터를 표시하고 사용자와 상호작용을 하는 것이 역할이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나, 본래 역할에서 DB에서 데이터 로드까지 하게 한다면 너무 많은 책임을 떠안게 될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(이렇게 되면 추가적으로 UI 컨트롤러가 비동기 호출, 메모리 누수 방지 관리를 해줘야 한다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 문제로 인해서, 이를 해결할 수 있는 것이 없을까하고 생겨난 것이 ViewModel 클래스다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. ViewModel 사용하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewModel은 Activty, Fragment와 같은 UI 컨트롤러가 나타내야 하는 데이터를 저장, 관리하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 Configuration Change(ex. 화면이 회전되는 경우)로 Activty가 재생성돼도 데이터를 유지시켜준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 실제로 안드로이드에서 ViewModel 클래스는 어떻게 사용할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.1 gradle 의존성 추가&lt;/h4&gt;
&lt;pre id=&quot;code_1661251235430&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// ViewModel
implementation &quot;androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version&quot;
// LiveData
implementation &quot;androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewModel에서 LiveData를 사용해서 데이터를 관리할 것이라 LiveData도 추가해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;lifecycle_version에는 최신 버전을 써주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자는 현재 기준으로 2.5.1이 최신인 것 같아 2.5.1로 해주었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.2 ViewModel 클래스 만들기&lt;/h4&gt;
&lt;pre id=&quot;code_1661251408904&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class MyViewModel : ViewModel() {
    private val users: MutableLiveData&amp;lt;List&amp;lt;User&amp;gt;&amp;gt; by lazy {
        MutableLiveData&amp;lt;List&amp;lt;User&amp;gt;&amp;gt;().also {
            loadUsers()
        }
    }

    fun getUsers(): LiveData&amp;lt;List&amp;lt;User&amp;gt;&amp;gt; {
        return users
    }

    private fun loadUsers() {
        // Do an asynchronous operation to fetch users.
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글에서 가져온 예시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewModel 클래스를 만들고, 그 안에 LiveData를 만들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비동기적으로 loadUsers()에서 데이터를 가져오면 users라는 LiveData에 데이터가 들어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 getUsers() getter로 데이터를 담은 users를 가져올 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.3 ViewModel 인스턴스 생성 후 데이터 가져오기&lt;/h4&gt;
&lt;pre id=&quot;code_1661251470289&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class MyActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {

        val model: MyViewModel by viewModels()
        model.getUsers().observe(this, Observer&amp;lt;List&amp;lt;User&amp;gt;&amp;gt;{ users -&amp;gt;
            // update UI
        })
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 표시할 UI 컨트롤러에서 방금 만든 MyViewModel 객체를 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MyViewModel의 getUsers() getter로 users를 가져올 수 있으므로,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;getUsers()가 반환하는 값을 observe해서 데이터에 변동이 있을 때마다 UI를 업데이트하는 로직이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(observer에 대한 포스팅도 작성해봐야할 것 같다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 ViewModel의 특징은,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewModel도 LifeCycle이 있는데, UI 컨트롤러가 살아있는 한 ViewModel도 살아있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주의할 점은 ViewModel에서 Activity, Fragment를 절대로 참조해서는 안된다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Activity, Fragment는 Configuration Change에서 사라지고 재생성되기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. ViewModel의 활용&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Coroutine과 함께 사용할 수 있다.&lt;/li&gt;
&lt;li&gt;Fragment 간에 데이터를 공유할 때 사용될 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자세한 활용 방법은 다른 포스팅으로 정리해봐야 할 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.android.com/topic/libraries/architecture/viewmodel&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Android Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://charlezz.medium.com/viewmodel%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-viewmodel-%EC%B4%88%EB%B3%B4%EB%A5%BC-%EC%9C%84%ED%95%9C-%EA%B0%80%EC%9D%B4%EB%93%9C-e1be5dc1ac18&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Charlezz님 medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://velog.io/@ejjjang0414/%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-%EC%96%B4%ED%83%9D2-MVVM&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;ejjjang0414.log&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android/etc</category>
      <category>AACViewModel</category>
      <category>Android Architecture Components</category>
      <category>android ViewModel</category>
      <category>MVVM</category>
      <category>ViewModel</category>
      <category>안드로이드 VIewModel</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/39</guid>
      <comments>https://hapen385.tistory.com/39#entry39comment</comments>
      <pubDate>Tue, 23 Aug 2022 19:56:00 +0900</pubDate>
    </item>
    <item>
      <title>[Android] RecyclerView</title>
      <link>https://hapen385.tistory.com/37</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;RecyclerView는 안드로이드 위젯 중에서 많이 쓰이는 것 중 하나다. RecyclerView는 메모리 최적화와도 관련된 내용이 나오기 때문에, 이론적인 내용에 대한 정리가 필요할 것 같아 글을 작성해본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;touchicon-180.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZtBgc/btrGcUR2Lxv/6KvZFtCls3Rka6RVyiedFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZtBgc/btrGcUR2Lxv/6KvZFtCls3Rka6RVyiedFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZtBgc/btrGcUR2Lxv/6KvZFtCls3Rka6RVyiedFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZtBgc%2FbtrGcUR2Lxv%2F6KvZFtCls3Rka6RVyiedFK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;180&quot; height=&quot;180&quot; data-filename=&quot;touchicon-180.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. RecyclerView란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Android Developers에서는 RecyclerView를 동적 목록을 나타내는 수단으로 표현하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이름에서 알 수 있듯이, RecyclerView내의 View를 재활용하는 동적 목록이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Android Jetpack에 포함되어 있는 위젯이다(원래는 Support Library에서 지원됐으나, Support Library가 deprecated됨)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 말해, 데이터 목록을 재활용하여 목록에 나타낸 View라고 생각하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같은 아이템 목록들을 나타내는데 쓰인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ListView라는 클래스도 아이템 목록을 나타내는데 쓰이는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RecyclerView와는 메모리 사용에 대해서 차이점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 언급했듯이, RecyclerView는 데이터 목록을 재활용하기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot_1650966852.webp&quot; data-origin-width=&quot;485&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EbZAK/btrHzoYDZyI/ny2VkLD5ygcNrcnWgosbik/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EbZAK/btrHzoYDZyI/ny2VkLD5ygcNrcnWgosbik/img.webp&quot; data-alt=&quot;출처 :https://howtodoandroid.com/recyclerview-android/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EbZAK/btrHzoYDZyI/ny2VkLD5ygcNrcnWgosbik/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEbZAK%2FbtrHzoYDZyI%2Fny2VkLD5ygcNrcnWgosbik%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;256&quot; height=&quot;541&quot; data-filename=&quot;Screenshot_1650966852.webp&quot; data-origin-width=&quot;485&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :https://howtodoandroid.com/recyclerview-android/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. ListView와의 차이&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ListView와 RecyclerView 모두 아이템 목록을 나타내는 위젯이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 아이템은 단순히 Text만 출력하는 구조가 될 수도 있고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Image, Button, CheckBox 등 여러 View의 조합으로 구성될 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ListView와 RecyclerView의 가장 큰 차이를 나타낸 사진이 다음과 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;4h2wjwo0dlzkenw9ewnm.png&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;570&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sEmrG/btrHpPKkHh9/aUkkQRc9w98fusB6Ppw5I0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sEmrG/btrHpPKkHh9/aUkkQRc9w98fusB6Ppw5I0/img.png&quot; data-alt=&quot;출처 : https://dev.to/jbc7ag/recyclerview-or-listview-pros-cons-and-examples-with-kotlin-2nb2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sEmrG/btrHpPKkHh9/aUkkQRc9w98fusB6Ppw5I0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsEmrG%2FbtrHpPKkHh9%2FaUkkQRc9w98fusB6Ppw5I0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;625&quot; height=&quot;474&quot; data-filename=&quot;4h2wjwo0dlzkenw9ewnm.png&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;570&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : https://dev.to/jbc7ag/recyclerview-or-listview-pros-cons-and-examples-with-kotlin-2nb2&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사진과 같이 ListView는 View를 재활용하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기 때문에 ListView의 아이템은 리스트 항목이 갱신될 때마다 매번 새로 구성돼야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 스크롤을 내렸다가 올리는 것과 같이 스크롤을 왔다갔다 할 때 마다, 리소스를 새로 불러오게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 아이템의 양이 많아질수록, 낮은 성능을 보일 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 말하는 낮은 성능은, 많은 메모리를 사용하게 되어 앱이 느려진다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 ListView의 큰 단점을 해결하는 것이 RecyclerView다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사진에 보이듯이 View를 Reuse한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RecyclerView는 이미 보았던 View가 사라지고 스크롤을 다시 올렸을 때 이전에 보았던 View를 재사용하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면, ListView는 이미 보았던 View라도 스크롤을 다시 올리면 해당 View를 재사용하지 않고 새로 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ListView와 RecyclerView의 차이점은 위에서 설명한 것 이외에도 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 차이점을 표로 정리한 것이 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 200px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style4&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;ListView&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;RecyclerView&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 76px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 76px;&quot;&gt;ViewHolder&lt;br /&gt;(화면에 표시될 아이템 View을 저장하는 객체)&lt;br /&gt;필요 유무&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 76px;&quot;&gt;필요로 하지 않음&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 76px;&quot;&gt;필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 32px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 32px;&quot;&gt;Item Layout 설정 가능 범위&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 32px;&quot;&gt;세로 방향만 가능&lt;br /&gt;(다른 방향 가능하나, 상당 부분 재구현 필요)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 32px;&quot;&gt;가로 / 세로/ 격자 모두 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;Item Animation 가능 여부&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;ListView 내에 아이템 View의 animation을 처리할 수 있는 클래스가 없다.&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;아이템 View가 추가 / 삭제될 때마다 animation 처리가 가능한 클래스가 있다.&lt;br /&gt;(RecyclerView.ItemAnimator)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 38px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 38px;&quot;&gt;Item Decoration 처리 방법&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 38px;&quot;&gt;xml 속성의 android:divider 사용하여 아이템 마다 구분선 적용&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 38px;&quot;&gt;RecyclerView.ItemDecoration 사용하여 아이템의 decoration 적용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;Adapter 유무&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;배열, DB 내용을 View로 바꾸어주는 Adapter가 여러 개 존재. ArrayAdapter, CursorAdapter 등 여러 Adapter가 있다.&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;데이터 종류에 따른 Adapter가 여러 개 있는 것 아니라, RecyclerView.adapter에서 데이터에 맞는 Adapter를 커스텀해서 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;Click Event 처리 방법&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;AdapterView.OnItemClickListener 사용하여 아이템에 binding하여 Click Event 적용&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;RecyclerView.OnItemTouchListener 사용하여 아이템 개별적으로 Click Event 적용&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. RecyclerView의 구성&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1_ZnxdTHnjCIwY3f4StO6AUA.png&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;568&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WzogB/btrHOUjjQJl/RWraH5z8p3HWTUu2G3EeDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WzogB/btrHOUjjQJl/RWraH5z8p3HWTUu2G3EeDK/img.png&quot; data-alt=&quot;출처 :&amp;amp;amp;nbsp;https://medium.com/@simple.schwarz/how-to-make-a-list-app-with-recyclerview-1-android-kotlin-example-e5feca8b70fe&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WzogB/btrHOUjjQJl/RWraH5z8p3HWTUu2G3EeDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWzogB%2FbtrHOUjjQJl%2FRWraH5z8p3HWTUu2G3EeDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;682&quot; height=&quot;437&quot; data-filename=&quot;1_ZnxdTHnjCIwY3f4StO6AUA.png&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;568&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;amp;nbsp;https://medium.com/@simple.schwarz/how-to-make-a-list-app-with-recyclerview-1-android-kotlin-example-e5feca8b70fe&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.1 RecyclerView&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터에 맞게 여러 개의 View를 담는 Container.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 말해, 데이터 목록을 나타낸 View 그 자체를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RecycleView 객체는 화면에 보이지 않는(ViewHolder에 없는) 아이템 View도 참조(reference, binding)한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나중에 다시 불러와서 재사용하기 위해서이다(Caching)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.2 Adapter&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RecyclerView에 나타낼 데이터를 아이템 View로 만들어주는 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.3 LayoutManager&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RecyclerView 내의 아이템 View를 어떻게 배치할지를 관리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LayoutManager가 아이템 View를 배치하는 방법은 기본적으로 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LinearLayoutManager : Horizontal, Vertically, Linear 방향으로 아이템 View를 배치한다.&lt;/li&gt;
&lt;li&gt;GridLayoutManager : Grid(격자) 형태로 아이템 View를 배치한다.&lt;/li&gt;
&lt;li&gt;StaggeredGridLayoutManager : Staggered Grid(엇갈린 격자) 형태로 아이템 View를 배치한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;RecyclerView-Android-example-with-CardView-in-Kotlin-tutorial-1.webp&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;381&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s1Iv8/btrHN3uBacj/LNVdAqZlSaiZZauPHHmAU1/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s1Iv8/btrHN3uBacj/LNVdAqZlSaiZZauPHHmAU1/img.webp&quot; data-alt=&quot;출처 :&amp;amp;amp;nbsp;https://tutorial.eyehunts.com/android/recyclerview-android-example-cardview-kotlin/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s1Iv8/btrHN3uBacj/LNVdAqZlSaiZZauPHHmAU1/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs1Iv8%2FbtrHN3uBacj%2FLNVdAqZlSaiZZauPHHmAU1%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;609&quot; height=&quot;302&quot; data-filename=&quot;RecyclerView-Android-example-with-CardView-in-Kotlin-tutorial-1.webp&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;381&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;amp;nbsp;https://tutorial.eyehunts.com/android/recyclerview-android-example-cardview-kotlin/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 배치 형태는 안드로이드 SDK에서 기본적으로 제공되는 형태다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이외에도 개발자가 다양한 형태의 LayoutManager를 커스텀할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LayoutManager는 화면에 보이지 않는(ViewHolder에 없는) 아이템 View가 언제 재활용(Reuse)되는지도 관리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.4 ViewHolder&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RecyclerView 내의 아이템 View 중 화면에 표시될 아이템 View를 저장하는 객체.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Adapter에 의해 관리되며 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아이템 View는 ViewHolder에 binding된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. RecyclerView 예제&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4.1 Activity(혹은 Fragment)에 RecyclerView 추가&lt;/h4&gt;
&lt;pre id=&quot;code_1658327395563&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    &amp;lt;androidx.recyclerview.widget.RecyclerView
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:id=&quot;@+id/recyclerview&quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4.2 아이템 View의 Layout 작성(LayoutManager가 아니라 xml 파일 작성)&lt;/h4&gt;
&lt;pre id=&quot;code_1658327724714&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    android:orientation=&quot;horizontal&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;&amp;gt;
    
    &amp;lt;TextView
        app:layout_constraintTop_toTopOf=&quot;parent&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:text=&quot;item&quot;
        android:id=&quot;@+id/text&quot;/&amp;gt;

    &amp;lt;ImageView
        android:id=&quot;@+id/imageView&quot;
        android:layout_width=&quot;50dp&quot;
        android:layout_height=&quot;50dp&quot;
        app:srcCompat=&quot;@drawable/ic_launcher_foreground&quot; /&amp;gt;
    
&amp;lt;/LinearLayout&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4.3 RecyclerView Adapter, ViewHolder 구현&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Adapter 구현 시, 다음과 같은 메소드를 override 해줘야 함&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;onCreateViewHolder() : ViewHolder 생성하고 생성한 ViewHolder를 초기화. 아이템 View가 binding 되어 있는 단계가 아니므로, 아이템 View의 내용(데이터, 콘텐츠)를 작성하지 않는다.&lt;/li&gt;
&lt;li&gt;onBindViewHolder() : position parameter에 해당하는 데이터를 ViewHolder 내의 아이템 View에 나타낼 수 있도록 한다.&lt;/li&gt;
&lt;li&gt;getItemCount() : RecyclerView 내의 아이템 View 개수를 return. 화면에 보여줄 아이템 View가 없을 때 해당 메소드를 이용하여 코드를 작성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1658329674462&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class RVAdapter(private val dataSet: Array&amp;lt;String&amp;gt;) : RecyclerView.Adapter&amp;lt;RVAdapter.ViewHolder&amp;gt;() {

    //custom ViewHolder
    class ViewHolder(view : View) : RecyclerView.ViewHolder(view) {
        val textView : TextView

        init {
            textView = view.findViewById(R.id.text)
        }

    }

    //LayoutManager에 의해 새로운 아이템 View 생성
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.recyclerview_item, parent, false)

        return ViewHolder(view)
    }

    //LayoutManager에 의해 아이템 View의 내용을 replace
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {

        //아이템 View의 내용을 사용자 데이터를 불러와서 position에 맞게 대체
        holder.textView.text = dataSet[position]
    }

    //LayoutManager에 의해 사용자 데이터의 크기(size)를 return
    override fun getItemCount() = dataSet.size


}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4.4 LayoutManager 객체 생성&lt;/h4&gt;
&lt;pre id=&quot;code_1658330387129&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;val layoutmanager = LinearLayoutManager(this)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Grid, StaggeredGrid, Linear 중에서 Linear 형태로 LayoutManager를 만들어주었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LayoutManager의 parameter는 context가 들어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*context : 애플리케이션의 현재 상태 맥락(context)를 말한다. 애플리케이션 환경 정보를 담고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;context에 대한 내용은 따로 정리를 해봐야할 것 같다. context를 잘 사용해야 메모리 누수를 방지할 수 있다. 그렇기 때문에 context도 꽤 중요한 내용이 될 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4.5 RecyclerView Adapter 객체 생성, 4.1의 RecyclerView와 Adapter 연결&lt;/h4&gt;
&lt;pre id=&quot;code_1658331484863&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class MainActivity : AppCompatActivity() {

    lateinit var binding : ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val dogs = arrayOf(&quot;슈나우저&quot;, &quot;볼로네즈&quot;, &quot;비글&quot;, &quot;비숑&quot;, &quot;사모예드&quot;) //사용자 데이터

        val myRecyclerView = findViewById&amp;lt;RecyclerView&amp;gt;(R.id.recyclerview)

        val myAdapter = RVAdapter(dogs)
        val layoutmanager = LinearLayoutManager(this)

        myRecyclerView.adapter = myAdapter
        myRecyclerView.layoutManager = layoutmanager

        //RecyclerView의 size를 고정
        myRecyclerView.setHasFixedSize(true)


    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;결과&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot_20220721_003832.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1920&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yVOk2/btrHPKgpOP8/2aWqkZnEgBfKnODyJuOWK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yVOk2/btrHPKgpOP8/2aWqkZnEgBfKnODyJuOWK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yVOk2/btrHPKgpOP8/2aWqkZnEgBfKnODyJuOWK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyVOk2%2FbtrHPKgpOP8%2F2aWqkZnEgBfKnODyJuOWK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;226&quot; height=&quot;402&quot; data-filename=&quot;Screenshot_20220721_003832.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1920&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많이 작지만, 목록이 더 길면 스크롤이 가능해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스크롤이 가능해지면 화면에 나오는 것만 ViewHolder에 있는 것이고 화면에 안나오는 것은 ViewHolder 밖에 있는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewPager 만큼이나 복잡한 생성인 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 RecyclerView를 더 잘 활용하려고 하고, Custom하려고 하면 더 복잡해질 수도 있겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 계속 쓰면 나름 익숙해질 것 같기도 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리 관리(OOM, Out Of Memory 해결)와 관련이 있기 때문에, 그만큼 잘 활용해야 하는 위젯인 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.android.com/guide/topics/ui/layout/recyclerview&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Android Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://guides.codepath.com/android/using-the-recyclerview&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;CODEPATH&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://recipes4dev.tistory.com/154&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;개발자를 위한 레시피&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tutorial.eyehunts.com/android/recyclerview-android-example-cardview-kotlin/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Tutorial by Eyehunts&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android/Widget</category>
      <category>Android</category>
      <category>Android Widget</category>
      <category>Jetpack</category>
      <category>ListView</category>
      <category>RecyclerView</category>
      <category>SupportLibrary</category>
      <category>리사이클러뷰</category>
      <category>안드로이드</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/37</guid>
      <comments>https://hapen385.tistory.com/37#entry37comment</comments>
      <pubDate>Thu, 21 Jul 2022 22:34:28 +0900</pubDate>
    </item>
    <item>
      <title>[Data Structure] Hashing</title>
      <link>https://hapen385.tistory.com/36</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;프로그래머스에서 문제를 풀다가 해쉬 개념과 관련된 문제를 풀었다. 해쉬 관련 문제 풀이를 블로그에 올렸으니 해쉬 테이블에 대해서도 블로깅해봐야 할 것 같아서 정리해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. Hash란&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Hash하는 것, 즉 Hahsing은 산술적인 연산을 이용하여 키가 있는 위치를 계산하여 &lt;b&gt;바로&lt;/b&gt; 찾아가는 계산 검색 방식이다. 키 값을 비교하여 찾는 검색 방법이 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정에서 쓰이는 함수와 테이블이 있다. 각각 Hash Function, Hash Table이라 불린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해쉬 함수(Hash Function)는 키 값을 원소 위치로 변환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해쉬 테이블(Hash Table)은 해쉬 함수에 의해 계산된 주소 위치에 항목을 저장한 표다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이와 같은 설명을 그림과 같이 표현하면 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;자료구조.jpg&quot; data-origin-width=&quot;1579&quot; data-origin-height=&quot;1010&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k9rKG/btrF0ZtMfHp/c0brY95pJvPKFK6BSphcX1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k9rKG/btrF0ZtMfHp/c0brY95pJvPKFK6BSphcX1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k9rKG/btrF0ZtMfHp/c0brY95pJvPKFK6BSphcX1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk9rKG%2FbtrF0ZtMfHp%2Fc0brY95pJvPKFK6BSphcX1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;579&quot; height=&quot;370&quot; data-filename=&quot;자료구조.jpg&quot; data-origin-width=&quot;1579&quot; data-origin-height=&quot;1010&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림과 같이 키 값에 대해서 해쉬 함수를 계산한 후, 주소를 구해서 주소에 해당하는 해쉬 테이블의 값을 찾는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해쉬 테이블로 이동했을 때 찾는 항목이 있으면 검색 성공이고, 없으면 검색 실패다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해싱(Hashing)의 예시는 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;도서관에서 책을 찾을 때&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책을 찾을 때 책꽂이 처음부터 찾는게 아니라, 찾는 도서의 번호를 이용해서 책을 찾는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도서관의 책이 키(k)이고,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도서관에서 발급되는 도서 번호가 해쉬 함수를 통해 발급받은 주소(h(k))가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도서 번호를 가지고 책꽂이(Hash Table)에서 책이 있는 위치를 찾는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도서 검색 시스템이 전산화되어있을 경우, 도서 검색 시스템에서 제목을 입력하여 책의 위치를 찾는 것도 해싱이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;학번에 따른 강의실 자리 배정&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학번을 입력하면 강의실 자리 번호를 임의로 생성하여 자리를 배정한다고 가정하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학번이 키 값이 되고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강의실 자리 번호를 생성하는 것은 해쉬 함수를 사용하는 것과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자리 번호 생성기로 강의실 자리의 위치를 찾으므로, 실제 강의실 자리는 해쉬 테이블과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 해싱(Hashing) 관련 용어&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2.1 동거자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키 값 중에서 많이 사용되는 값이 있고, 잘 사용되지 않는 값이 있을 수 있다. 그렇기 때문에 키 값마다 버킷을 만들어버리면, 메모리 낭비가 일어날 수 있다. 이러한 것을 방지하기 위해, 버킷 안에 여러 개의 키 값을 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로는 서로 다른 키 값을 가지지만, 해쉬 함수를 사용했을 때 같은 주소 값이 나오는 키 값들을 한 버킷안에 다 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 한 버킷 안에 저장돼 있는 키 값을 동거자(Synonym)라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 버킷을 여러 슬롯으로 나누는 것은, 자리를 배정할 때 1인용 좌석이 아니라 다인용 좌석에 배정하는 것과 같다고 생각하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2.2 충돌&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키 값이 다른 경우인데, 해쉬 함수를 썼을 때 같은 버킷 주소로 배정받을 경우 &lt;b&gt;충돌&lt;/b&gt;이 일어난다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 충돌을 동거자를 설명할 때 나온 버킷 개념을 사용하면 해결되겠지라고 생각할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 충돌이 일어난 키 값들을 한 버킷을 여러 슬롯으로 나누어 넣으면 되지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버킷에 비어 있는 슬롯이 없을 경우 문제가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버킷에 비어 있는 슬롯이 없는 상태를 포화 버킷 상태라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포화 버킷 상태에서 같은 버킷을 지정받은 키 값이 일어나서 또 충돌이 난다면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오버플로가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2.3 키 값 밀도와 적재 밀도&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;키 값 밀도 = 실제 사용 중인 키 값의 개수 / 사용 가능한 키 값의 개수&lt;/li&gt;
&lt;li&gt;적재 밀도 = 실제 사용 중인 키 값의 개수 / 해쉬 테이블에 저장 가능한 전체 키 값의 개수&lt;/li&gt;
&lt;li&gt;해쉬 테이블 = 버킷 개수 * 슬롯 개수 이므로 적재밀도는 이렇게도 나타낼 수 있다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;적재 밀도 = 실제 사용 중인 키 값의 개수 / (버킷 개수 * 슬롯 개수)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 해쉬 함수(Hash Function)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해싱(Hashing)에서 가장 중요한 것은 키 값의 위치를 계산하는 해쉬 함수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 해쉬 함수를 사용하느냐에 따라 해싱 검색의 효율이 달라지기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;효율이 좋은 해쉬 함수를 만들기 위한 조건은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해쉬 함수는 계산이 쉬워야 함 : 비교 검색 방법보다 해쉬 함수를 사용하여 검색하는 방법이 더 빨라야 해싱 검색을 사용하는 의미가 있음&lt;/li&gt;
&lt;li&gt;해쉬 함수는 충돌이 적어야 함 : 충돌이 많다는 것은 같은 버킷에 많은 키 값이 들어갈 수 있다는 것이다. 이는 오버플로로 이어질 수 있으므로 오버플로가 발생할 수 있는 확률을 줄여야 함
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해쉬 테이블에 고르게 분포할 수 있도록 주소를 만들어야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 해싱(Hashing)에서 오버플로 해결하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4.1 선형 개방 주소법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오버플로가 발생했을 때 그 다음에 빈 버킷이 없나 조사하는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음 버킷에 빈 슬롯이 있다면 키 값을 저장하고 없으면 또 다음 버킷을 조사한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4.2 체이닝&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 버킷에 하나 이상의 키 값을 저장할 수 있도록 해쉬 테이블의 구조를 바꾸는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버킷 안의 슬롯을 동적으로 삽입, 삭제하기 위한 연결 리스트를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버킷은 1차원 배열이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버킷 안의 슬롯은 헤드 노드에 연결 리스트를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버킷 내에서 검색할 때는 버킷의 연결리스트를 선형 검색한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시 그림은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 해쉬 함수는 h(k) = k mod 5 = k % 5 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;자료구조-4.jpg&quot; data-origin-width=&quot;1380&quot; data-origin-height=&quot;1785&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbJ5kT/btrF5bAffpx/kJwacfDNSzzs6k01wGLRgK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbJ5kT/btrF5bAffpx/kJwacfDNSzzs6k01wGLRgK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbJ5kT/btrF5bAffpx/kJwacfDNSzzs6k01wGLRgK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbJ5kT%2FbtrF5bAffpx%2FkJwacfDNSzzs6k01wGLRgK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;599&quot; height=&quot;775&quot; data-filename=&quot;자료구조-4.jpg&quot; data-origin-width=&quot;1380&quot; data-origin-height=&quot;1785&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해싱은 실제로 많은 곳에서 쓰일 수 있을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대표적으로는 회원 비밀 번호 저장할 때 사용될 수도 있을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;C로 배우는 쉬운 자료 구조, 이지영, 한빛아카데미(2016)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Science/Data Structure</category>
      <category>cs</category>
      <category>CS공부</category>
      <category>Data Structure</category>
      <category>HASH</category>
      <category>데이터구조</category>
      <category>자료구조</category>
      <category>해쉬</category>
      <category>해쉬함수</category>
      <category>해시</category>
      <category>해싱</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/36</guid>
      <comments>https://hapen385.tistory.com/36#entry36comment</comments>
      <pubDate>Wed, 29 Jun 2022 22:13:44 +0900</pubDate>
    </item>
    <item>
      <title>[Kotlin] 코틀린 언어 특징</title>
      <link>https://hapen385.tistory.com/35</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드 개발 언어로 코틀린을 주로 쓰고 있다. 언어 특징을 대충은 알고 있었지만, 오래 기억하기 위해서 정리해보게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Kotlin_Icon.svg.png&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;640&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cGtzNX/btrFVVYf0lE/IhLhjAeQ7xb5jJM1OeQqEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cGtzNX/btrFVVYf0lE/IhLhjAeQ7xb5jJM1OeQqEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cGtzNX/btrFVVYf0lE/IhLhjAeQ7xb5jJM1OeQqEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcGtzNX%2FbtrFVVYf0lE%2FIhLhjAeQ7xb5jJM1OeQqEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;230&quot; height=&quot;230&quot; data-filename=&quot;Kotlin_Icon.svg.png&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;640&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 코틀린이란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코틀린은 자바 플랫폼(자바 프로그램의 개발과 실행을 위한 환경)에서 돌아가는 프로그래밍 언어다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바가 사용 중인 곳이라면 거의 대부분 코틀린을 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 서버 개발, 안드로이드 어플리케이션 개발 등에서 활발하게 사용되고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코틀린은 간결하고 실용적이며, 자바 코드와의 상호 운용성을 중시한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 상호 운용성 : &lt;span style=&quot;color: #333333;&quot;&gt;하나의 시스템이 동일 또는 이기종의 다른 시스템과 아무런 제약이 없이 서로 호환되&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;어 사용할 수 있는 성질 &lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(출처 : 위키백과)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;자바가 실행되는 환경이면 잘 작동하며, 성능도 자바와 같은 수준이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;2. 활용 범위&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;앞서 코틀린이 자바 플랫폼에서 거의 실행된다고 설명한 것처럼, &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;코틀린은 자바가 사용되고 있는 모든 곳에 사용되고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;자바 플랫폼에서 자바보다 간결하고 안전하게 사용되는 것이 목적이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;코틀린은 백엔드, 안드로이드 어플리케이션 개발에서 많이 사용된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;뿐만 아니라, 자바스크립트로도 코틀린을 컴파일할 수 있다고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;따라서 코틀린을 브라우저나 node.js에서 실행할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;3. 특징&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;3.1 정적 타입 언어&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;코틀린은 정적 타입 언어다. 따라서 코틀린으로 작성된 코드의 구성 요소 타입을 컴파일 시점에 알 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;인스턴스의 필드나 메소드를 사용할 때마다 컴파일러가 타입을 검증해준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;반면 동적 타입 언어는 타입과 관계없이 모든 값을 변수에 넣을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;그리고 메소드나 필드 접근에 대한 검증이 빌드 후(실행 시점)에 일어난다.&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;그렇기 때문에 코드가 더 짧아지고 데이터 구조를 더 유연하게 생성할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;하지만 변수 이름을 잘못입력하는 것과 실수를 실행 시에 알 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;3.2 타입 추론 가능&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;자바와 달리 코틀린은 타입 선언을 해주지 않아도 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;예를 들어, 아래와 같은 코드를 보면 알 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1656339687898&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var a = 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코틀린은 위 코드와 같이 var(가변), val(불변)으로 변수를 선언하고 타입 선언은 생략할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 코틀린 컴파일러가 문맥에서 변수 타입을 자동으로 유추할 수 있기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타입 추론으로 인해 얻을 수 있는 장점은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메소드 호출이 더 빠르다. 실행 시점에 어떤 메소드를 호출할지 알아내는 과정이 필요없기 때문이다.&lt;/li&gt;
&lt;li&gt;컴파일 시에 프로그램의 정확성을 검증하므로 실행 시에 오류로 중단될 가능성이 적다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3.3 간결성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코틀린은 코드가 더 간단하고 간결할 수 있도록 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코틀린을 만들면서 프로그래머가 작성하는 코드에서 의미가 없는 부분은 줄이려고 했다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, getter와 setter 같이 생성자 파라미터에 접근하기 위한 로직을 코틀린에서는 작성할 필요 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코틀린에서는 getter와 setter같은 준비 코드를 묵시적으로 제공하므로 작성할 필요 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이와 같은 간결성은 코드의 내용을 파악하기 쉽게하고 생산성을 높인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3.4 안전성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 안전하다는 말은, 프로그램에서 발생하는 오류 중에서 일부 유형의 오류를 설계 단계에서 원천적으로 방지한다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.4.1 JVM 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM에서 실행함으로써 메모리 안전성을 보장하고 버퍼 오버플로우를 방지할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.4.2 타입 안전성 보장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코틀린은 정적 타입 지정 언어이므로 어플리케이션의 타입 안전성을 보장할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.4.3 널 안정성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코틀린에서는 NullPointerException을 없애기 위해서 노력한다. 코틀린의 타입 시스템은 널(null)이 될 수 없는 값을 추적하며, 실행 시 NulpointerException이 발생할 수 있는 연산 코드를 금지한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 다음과 같은 코드로 널 안정성을 보장할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1656340856568&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;val s1 : String ?= null
val s2 : String = &quot;&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수 s1 ? 키워드를 통해 널이 될 수 있는지 여부를 표시하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 변수 s2는 ? 키워드가 없으므로 널이 될 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유명한 Kotlin in Action 책에서 공부한 내용을 정리해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책 내용이 상당해서 읽는데 시간이 오래걸리겠지만, 많은 내용을 습득할 수 있도록 노력해볼 것..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kotlin in Action, 드미르티 제메로프 스베트라나 이사코바, 에이콘(2017)&lt;/p&gt;</description>
      <category>Android/Kotlin</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/35</guid>
      <comments>https://hapen385.tistory.com/35#entry35comment</comments>
      <pubDate>Mon, 27 Jun 2022 23:45:40 +0900</pubDate>
    </item>
    <item>
      <title>[Android] Fragment 생명 주기</title>
      <link>https://hapen385.tistory.com/34</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Fragment에 대해서 공부하면서, Fragment에도 생명주기가 있다는 것을 알게 되었다. Fragment는 Activity에 종속이 될 텐데 &lt;span&gt;Fragment의 생명 주기는 종속되는 중에 어떻게 돌아갈까 궁금했다. 이번 포스팅에서는 Fragment 생명 주기에 대해서 자세히 알아보고자 한다. 그리고 Activity 생명 주기와는 어떤 다른 점이 있는지 공부해보고자 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;touchicon-180.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kOEvh/btrFiS3yqhR/jj5VIrMb5pNd59b3zKwewK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kOEvh/btrFiS3yqhR/jj5VIrMb5pNd59b3zKwewK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kOEvh/btrFiS3yqhR/jj5VIrMb5pNd59b3zKwewK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkOEvh%2FbtrFiS3yqhR%2Fjj5VIrMb5pNd59b3zKwewK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;180&quot; height=&quot;180&quot; data-filename=&quot;touchicon-180.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.&amp;nbsp; 배경&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fragment도 Activity와 마찬가지로 UI를 빌드하는 것이므로 Activity가 생명주기를 갖는 것과 같은 이유로 생명주기를 갖고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생명주기 콜백 함수가 있는 이유는 사용자가 Fragment 화면을 나가거나 돌아올 때 대응하기 위해서였다. 그 외에도 다른 이유들이 있는데 아래 링크에서 생명주기를 사용하는 이유를 참고할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://hapen385.tistory.com/18&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Activity 생명주기 포스팅 참고&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1656151350041&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Android] 안드로이드 액티비티 생명주기&quot; data-og-description=&quot;개요 : 리액트를 공부할 때도 들었던 의문이었지만, 왜 생명주기란 것이 있는지 궁금했었다. 이번에 안드로이드를 공부하면서 생명주기라는 것이 왜 있는지 알게되었고 각 각의 단계들이 어떤 &quot; data-og-host=&quot;hapen385.tistory.com&quot; data-og-source-url=&quot;https://hapen385.tistory.com/18&quot; data-og-url=&quot;https://hapen385.tistory.com/18&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/5LPVK/hyOSRS2kbw/NNKeAkOqASKWoecswzhOok/img.png?width=513&amp;amp;height=663&amp;amp;face=0_0_513_663,https://scrap.kakaocdn.net/dn/chreuB/hyOSU93Hx7/iSEQXRv0DdW3xtUihZZTR0/img.png?width=513&amp;amp;height=663&amp;amp;face=0_0_513_663,https://scrap.kakaocdn.net/dn/dyd8C9/hyORPiewyn/hrPJDdPri4SHATS2mZ5sjk/img.jpg?width=1125&amp;amp;height=1110&amp;amp;face=0_0_1125_1110&quot;&gt;&lt;a href=&quot;https://hapen385.tistory.com/18&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hapen385.tistory.com/18&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/5LPVK/hyOSRS2kbw/NNKeAkOqASKWoecswzhOok/img.png?width=513&amp;amp;height=663&amp;amp;face=0_0_513_663,https://scrap.kakaocdn.net/dn/chreuB/hyOSU93Hx7/iSEQXRv0DdW3xtUihZZTR0/img.png?width=513&amp;amp;height=663&amp;amp;face=0_0_513_663,https://scrap.kakaocdn.net/dn/dyd8C9/hyORPiewyn/hrPJDdPri4SHATS2mZ5sjk/img.jpg?width=1125&amp;amp;height=1110&amp;amp;face=0_0_1125_1110');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Android] 안드로이드 액티비티 생명주기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;개요 : 리액트를 공부할 때도 들었던 의문이었지만, 왜 생명주기란 것이 있는지 궁금했었다. 이번에 안드로이드를 공부하면서 생명주기라는 것이 왜 있는지 알게되었고 각 각의 단계들이 어떤&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;hapen385.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 Fragment는 Activity에 반드시 호스팅되어야 하므로, Activity의 생명주기에도 영향을 받는다. Activity로부터 영향을 받을 때 Fragment도 이에 대한 대응이 필요할 것이다. 호스트 Activity가 갑자기 종료되었을 때 Fragment는 어떻게 반응해야하는지와 같은 상황을 대처하기 위해 Fragment의 생명주기도 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 생명 주기를 사용해주면&amp;nbsp;&lt;span style=&quot;background-color: #ffffff; color: #202124;&quot;&gt;메모리 누수 또는 애플리케이션 비정상 종료를 방지할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. Fragment 생명 주기&amp;nbsp;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;fragment_lifecycle.png&quot; data-origin-width=&quot;317&quot; data-origin-height=&quot;847&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dWhW8l/btrFHcfxH6V/dRAt7OK422gHobyeVhoETK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dWhW8l/btrFHcfxH6V/dRAt7OK422gHobyeVhoETK/img.png&quot; data-alt=&quot;출처 : Android Developers(https://developer.android.com/guide/components/fragments?hl=ko)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dWhW8l/btrFHcfxH6V/dRAt7OK422gHobyeVhoETK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdWhW8l%2FbtrFHcfxH6V%2FdRAt7OK422gHobyeVhoETK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;241&quot; height=&quot;644&quot; data-filename=&quot;fragment_lifecycle.png&quot; data-origin-width=&quot;317&quot; data-origin-height=&quot;847&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : Android Developers(https://developer.android.com/guide/components/fragments?hl=ko)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fragment 생명 주기는 위 사진과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사진을 보면 Activity 생명 주기에서 본 메소드와 비슷한 메소드가 보인다. ex)onCreate(), onStart(), onPause(), onStop(), onDestroy(), onResume(), ...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Activity도 그렇고 Fragment 생명 주기는 모두 &lt;span style=&quot;background-color: #ffffff; color: #202124;&quot;&gt;운영체제 또는 프로세스에서 실행 중인 프레임워크 코드에서 관리한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #202124;&quot;&gt;Fragment 생명 주기 상태는 FragmentManager에서 관리한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fragment에는 최소 아래 세 가지 생명 주기 메소드는 구현해줘야 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;onCreate() : Fragment 생성될 때 호출되는 메소드. Fragment가 중단되었다가 재개될 때 유지하고자 하는 것을 초기화해야 한다.&lt;/li&gt;
&lt;li&gt;onCreateView() : Fragment가 처음으로 UI를 그리고자 할 때 해당 메소드를 호출. Fragment에 맞는 UI를 그리기 위해서 View를 반환한다. Fragment가 UI를 제공하지 않는 경우, null을 반환.&lt;/li&gt;
&lt;li&gt;onPause() : 해당 메소드의 호출은 사용자가 Fragment를 닫는다는 첫 번째 신호와 같다. 아직 onDestroyView()까지 가지 않았기 때문에 Fragment가 완전히 삭제되는 것은 아니다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. Fragment View와 Fragment 생명 주기&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;fragment-view-lifecycle.png&quot; data-origin-width=&quot;821&quot; data-origin-height=&quot;1004&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cl26h0/btrFKGNQQIX/OA2ziDljJHy8tTzxzKgVrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cl26h0/btrFKGNQQIX/OA2ziDljJHy8tTzxzKgVrK/img.png&quot; data-alt=&quot;출처 : Android Developers(https://developer.android.com/guide/fragments/lifecycle)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cl26h0/btrFKGNQQIX/OA2ziDljJHy8tTzxzKgVrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcl26h0%2FbtrFKGNQQIX%2FOA2ziDljJHy8tTzxzKgVrK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;550&quot; height=&quot;673&quot; data-filename=&quot;fragment-view-lifecycle.png&quot; data-origin-width=&quot;821&quot; data-origin-height=&quot;1004&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : Android Developers(https://developer.android.com/guide/fragments/lifecycle)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 사진은 Fragment View의 상태와 그에 따른 Fragment 콜백 메소드를 나타낸 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fragment 콜백 메소드에 onAttach()와 onDetach()가 있지만 생략되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Fragment CREATED&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사진에는 안나와있지만 onAttach()가 가장 먼저 시행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fragment CREATED 상태에서는 아직 Fragment의 View는 만들어지지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기 때문에 Fragment View와 관련된 작업을 하기에 적절치 않은 시기(?)다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;onCreate() : Fragment가 FragmentManager에 추가되고 호스트 Activity에 attach될 때 호출된다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Fragment CREATED &amp;amp; &lt;span&gt;View INITIALIZED&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;onCreateView() : 해당 메소드를 호출하면서 Fragment View가 만들어지게 된다. 이때 View 객체를 onCreateView()에서 제공되어야만, Fragment의 Lifecycle이 정상적으로 생성된다. 이 메소드를 재정의하여 개발자가 임의로 View를 생성할 수 있지만, 레이아웃의 Id 값을 받는 Fragment의 생성자로 id 값을 통해 재정의 없이도 Fragment View를 생성할 수 있다.&lt;/li&gt;
&lt;li&gt;onViewCreated() : onCreateView()에서 만들어진 View 객체를 Parameter로 받는다. 이 메소드 내에서 Fragment View의 초기화를 할 수 있다. 만약 RecyclerView, ViewPager2이 사용된다면, 해당 객체의 Adapter 세팅이 이루어진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;fragment_and_view_created&quot; data-text=&quot;Fragment and View CREATED&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span&gt;Fragment &amp;amp; View CREATED&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-text=&quot;Fragment and View CREATED&quot; data-ke-size=&quot;size16&quot;&gt;현재 Fragment View 이전에 View가 있었을 때 이전 View가 복구될 때 이 상태가 된다.&lt;/p&gt;
&lt;p data-text=&quot;Fragment and View CREATED&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-text=&quot;Fragment and View CREATED&quot;&gt;onViewStateRestored() : 저장해둔 모든 View의 state 값이 Fragment View 계층 구조(UI는 View는 계층 구조로 이루어져 있다. 추후에 포스팅을 작성해볼 것이다)에 복원됐을 때 호출된다. 예를 들어, CheckBox 위젯이 체크되었는지와 같은 View의 상태를 확인할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;View Lifecycle owner(각 View의 생명 주기를 담은 Lifecycle 객체)는 INITIALIZED에서 CREATED로 상태가 바뀌었음을 인지한다.&lt;/p&gt;
&lt;p data-text=&quot;Fragment and View CREATED&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;fragment_and_view_started&quot; data-text=&quot;Fragment and View STARTED&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span&gt;Fragment &amp;amp; View STARTED&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fragment의 View가 사용가능한 상태다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;onStart() : 호스팅 Activity의 onStart()와 유사한 역할을 한다. Fragment가 사용자에게 보여질 수 있을 때 호출된다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;View의 상태는 CREATED에서 STARTED로 변경된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;fragment_and_view_resumed&quot; data-text=&quot;Fragment and View RESUMED&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span&gt;Fragment &amp;amp; View RESUMED&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fragment View가 보이고, 애니메이션(Animator)과 Transition 애니메이션 효과가 끝났을 경우 이 상태가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fragment가 사용자로부터 interaction을 받을 수 있는 상태다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;onResume() : Activity의 onResume()과 유사하다. 해당 메소드가 호출되고 RESUMED 상태가 되었을 때는 사용자와 Fragment가 상호작용하기 적절한 상태가 된다. 반대로, 해당 메소드가 호출되지 않았다면 사용자가 입력을 시도하거나 Fragment와 상호작용하기에는 적절치 않은 상태다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;fragment_and_view_started_2&quot; data-text=&quot;Fragment and View STARTED&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span&gt;Fragment &amp;amp; View STARTED(onPause())&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 Fragment가 보이는 상태이나, 사용자가 Fragment를 떠나려할 때 이 상태가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;onPause() : 사용자가 Fragment를 떠났지만, Fragment는 여전히 visible한 상태일 때 호출된다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;View의 상태는 PAUSED가 아니라 STARTED 상태다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;fragment_and_view_created_2&quot; data-text=&quot;Fragment and View CREATED&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span&gt;Fragment &amp;amp; View CREATED(onStop(), onSaveInstanceState())&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fragment가 더이상 보이지 않는 상태다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stop-save-order.png&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A2b35/btrFHc0YHgd/F4BxKshfRBxc4EJavWGk21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A2b35/btrFHc0YHgd/F4BxKshfRBxc4EJavWGk21/img.png&quot; data-alt=&quot;출처 : Android Developers(https://developer.android.com/guide/fragments/lifecycle)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A2b35/btrFHc0YHgd/F4BxKshfRBxc4EJavWGk21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA2b35%2FbtrFHc0YHgd%2FF4BxKshfRBxc4EJavWGk21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;681&quot; height=&quot;224&quot; data-filename=&quot;stop-save-order.png&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;318&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : Android Developers(https://developer.android.com/guide/fragments/lifecycle)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API 28 이상부터 위 사진과 같이 변경 사항이 적용되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;onStop()이 먼저 호출되고 그 다음에 onSaveInstanceState()가 호출된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;onStop() : 호스팅 Activity나 Fragment가 중단되었을 때 호출된다. 또한 호스팅 Activity나 Fragment의 상태가 저장될 때도 호출된다.&lt;/li&gt;
&lt;li&gt;onSaveinstanceState() : 호스팅 Activity나 Fragment의 상태, 데이터의 변경을 저장한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-text=&quot;Fragment CREATED and View DESTROYED&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span&gt;Fragment CREATED &amp;amp; View DESTROYED(&lt;/span&gt;onDestroyView())&lt;/b&gt;&lt;/p&gt;
&lt;p data-text=&quot;Fragment CREATED and View DESTROYED&quot; data-ke-size=&quot;size18&quot;&gt;화면으로부터 Fragment가 완전히 사라졌을 때 해당 상태가 된다.&lt;/p&gt;
&lt;p data-text=&quot;Fragment CREATED and View DESTROYED&quot; data-ke-size=&quot;size18&quot;&gt;Fragment View의 Lifecycle은 DESTROYED 된다.&lt;/p&gt;
&lt;p data-text=&quot;Fragment CREATED and View DESTROYED&quot; data-ke-size=&quot;size18&quot;&gt;이 시기에는 Garbage Collector에 의해 리소스가 수거될 수 있도록 Fragment View에 대한 모든 참조가 제거되어야 한다.&lt;/p&gt;
&lt;p data-text=&quot;Fragment CREATED and View DESTROYED&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-text=&quot;Fragment CREATED and View DESTROYED&quot;&gt;onDestroyView() : Fragment가 화면에서 없어졌을 때 호출된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-text=&quot;Fragment CREATED and View DESTROYED&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;fragment_destroyed&quot; data-text=&quot;Fragment DESTROYED&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span&gt;Fragment DESTROYED(onDestroy())&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-text=&quot;Fragment DESTROYED&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;Fragment가 없어지거나 FragmentManager가 없어진다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-text=&quot;Fragment DESTROYED&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;onDestroy() : Fragment Lifecycle의 끝을 알린다. onDestroy() 이후에 onDetach()가 호출된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Activity 생명 주기를 다뤘을 때보다 복잡한 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나중에 Activity 생명 주기에서 빠진 내용이 없었는지 확인해봐야 겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fragment가 이정도로 내용이 많다면 Activity도 내용이 더 있을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생명 주기 이론은 공부할 수 있겠는데, 실습에서 사용하기에는 약간 어려운 감이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떨 때 어떤 콜백 메소드를 써야하는지가 헷갈린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실습도 많이 해봐야 할 듯하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.android.com/guide/fragments/lifecycle&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Android Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://readystory.tistory.com/199&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;준비된 개발자&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://velog.io/@jewelrykim/Android-Fragment-1%ED%83%84-%ED%83%84%EC%83%9D%EB%B0%B0%EA%B2%BD%EA%B3%BC-%EC%83%9D%EB%AA%85%EC%A3%BC%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;jewelrykim.log&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Android/etc</category>
      <category>activity</category>
      <category>Activity 생명주기</category>
      <category>Android</category>
      <category>FRAGMENT</category>
      <category>fragment lifecycle</category>
      <category>Fragment Lifecycles</category>
      <category>Fragment 생명주기</category>
      <category>안드로이드</category>
      <category>액티비티</category>
      <category>프래그먼트</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/34</guid>
      <comments>https://hapen385.tistory.com/34#entry34comment</comments>
      <pubDate>Sat, 25 Jun 2022 23:39:57 +0900</pubDate>
    </item>
    <item>
      <title>[Android] ViewPager2</title>
      <link>https://hapen385.tistory.com/33</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;클론 코딩을 하면서, ViewPager2를 사용하게 되었다.&lt;br&gt;사용한 지 좀 오래 되어, 복기용으로 글을 작성하게 되었다.&lt;br&gt; &lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btAkW9/btrBTzFoBhp/e5rjEWI4v6IAOtvyesaZsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btAkW9/btrBTzFoBhp/e5rjEWI4v6IAOtvyesaZsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btAkW9/btrBTzFoBhp/e5rjEWI4v6IAOtvyesaZsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtAkW9%2FbtrBTzFoBhp%2Fe5rjEWI4v6IAOtvyesaZsk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;180&quot; height=&quot;180&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt; &lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;0. 개념&lt;/h3&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;911&quot; data-origin-height=&quot;322&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kCVuF/btrFzvUI8Of/2S3ISYwPekuDkzBEvGReL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kCVuF/btrFzvUI8Of/2S3ISYwPekuDkzBEvGReL1/img.png&quot; data-alt=&quot; 출처 : Android Developers(https://developer.android.com/reference/kotlin/androidx/viewpager2/widget/ViewPager2?hl=ko) &quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kCVuF/btrFzvUI8Of/2S3ISYwPekuDkzBEvGReL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkCVuF%2FbtrFzvUI8Of%2F2S3ISYwPekuDkzBEvGReL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;911&quot; height=&quot;322&quot; data-origin-width=&quot;911&quot; data-origin-height=&quot;322&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt; 출처 : Android Developers(https://developer.android.com/reference/kotlin/androidx/viewpager2/widget/ViewPager2?hl=ko) &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;ViewPager2는 화면 슬라이드에 이용되는 레이아웃 클래스이다.&lt;br&gt;ViewPager2가 ViewGroup으로부터 상속된 것을 보면, Container 역할을 한다는 사실을 유추해낼 수 있다.&lt;br&gt;단어의 뜻 그대로, View + Pager = 페이지를 쓸어 넘기듯이 View를 넘기는 것이다.&lt;br&gt;이 뷰에서는 스와이프(Swipe) 제스처를 통해서, 한 화면에서 다음 화면으로 전환할 수 있다.&lt;br&gt;ViewPager2는 데이터를 페이지 단위로 화면에 표시한다.&lt;br&gt;여러 종류의 뷰 위젯을 사용하여 ViewPager2를 구성한다.&lt;br&gt; &lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. ViewPager와 ViewPager2&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewPager2라고 되어 있어서 그럼 ViewPager1이 있나? 이런 생각을 할 수 있다.&lt;br&gt;사실 ViewPager2 이전에, ViewPager라는 것이 있었다.&lt;br&gt;ViewPager에는 세로 방향 페이징 과정이 번거롭고 스크롤이 버벅거리는 현상이 있었다.&lt;br&gt;ViewPager에 있던 몇몇 기능들을 개선한 것이 ViewPager2이다.&lt;br&gt;그런데 ViewPager2도 몇몇 버그가 있는건지, ViewPager를 종종 쓰는 사람들이 있는 것 같다.&lt;br&gt;그래서 ViewPager는 아직 deprecated되지는 않았다.&lt;br&gt; &lt;br&gt;ViewPager2에 추가된 기능은 다음과 같다.&lt;br&gt; &lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
 &lt;li&gt;세로 방향 페이징 지원&lt;/li&gt;
 &lt;li&gt;오른쪽에서 왼쪽 페이징 가능(Right-to-left, RTL 가능)&lt;/li&gt;
 &lt;li&gt;notifyDataSetChanged() 버그 해결&lt;/li&gt;
 &lt;li&gt;RecyclerView를 이용한 페이징 기법 사용(가장 중요)&lt;/li&gt;
 &lt;li&gt;DiffUtil 사용 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; &lt;br&gt;&lt;b&gt;1) 세로 방향 페이징 지원&lt;/b&gt;&lt;br&gt; &lt;br&gt;기존의 ViewPager에서는 세로 방향으로 넘기는 것이 불가능했다.&lt;br&gt;하지만 ViewPager2에서는 이 점이 개선되었다.&lt;br&gt; &lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;&amp;lt;androidx.viewpager2.widget.ViewPager2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:id=&quot;@+id/pager&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:orientation=&quot;vertical&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; &lt;br&gt;ViewPager2의 orientation 속성을 사용하여 세로 방향 페이징이 가능해졌다.&lt;br&gt;혹은 setOrientation() 메소드로 코드 레벨에서도 세로 방향 속성이 지정가능하다.&lt;br&gt; &lt;br&gt; &lt;br&gt;&lt;b&gt;2) 오른쪽에서 왼쪽 페이징 가능(RTL 페이징 가능)&lt;/b&gt;&lt;br&gt; &lt;br&gt;ViewPager2에서는 오른쪽에서 왼쪽(RTL) 페이징이 가능하다.&lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;&amp;lt;androidx.viewpager2.widget.ViewPager2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:id=&quot;@+id/pager&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:layoutDirection=&quot;rtl&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; &lt;br&gt;layoutDirection 속성을 통해 페이징 방향을 오른쪽에서 왼쪽으로 설정할 수 있다.&lt;br&gt;혹은 setLayoutDirection() 메소드로 코드 레벨에서 설정가능하다.&lt;br&gt; &lt;br&gt; &lt;br&gt;&lt;b&gt;3) notifyDataSetChanged 버그 해결&lt;/b&gt;&lt;br&gt; &lt;br&gt;기존의 ViewPager에서 notifyDataSetChanged()가 실행되지 않는 버그가 있었다.&lt;br&gt;ViewPager2에서 이 점을 해결하여 notifyDataSetChanged() 메소드를 정상적으로 호출할 수 있게 되었다.&lt;br&gt; &lt;br&gt;notifyDataSetChanged()를 호출하면 ViewPager 내의 Item이 추가, 삭제, 이동이 되었을 때 변화를 감지할 수 있다. &lt;span style=&quot;background-color: #121212;&quot;&gt;&lt;span style=&quot;color: #ececec;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt; &lt;br&gt; &lt;br&gt;&lt;b&gt;4) RecyclerView를 이용한 페이징 기법 사용&lt;/b&gt;&lt;br&gt; &lt;br&gt;기존의 ViewPager는 PagerAdapter 기반으로 구성되었다. 따라서 페이징을 할 때마다 instantiateItem(), destroyItem() 메소드가 호출되어 버벅거리는 문제가 있었다.&lt;br&gt;그러나 ViewPager2에서는 PagerAdapter가 아닌, RecyclerView를 이용하게 되면서 instantiateItem(), destroyItem() 메소드를 호출할 필요가 없어졌다. RecylcerView는 이름 그대로 View를 재활용하기 때문이다. Item을 새로 생성하거나 삭제할 필요가 없어졌기 때문에 여러 메소드를 호출하지 않아도 되는 것이다.&lt;br&gt;버벅거리는 문제를 해결함과 동시에 메모리 리소스를 줄일 수 있는 장점도 더해졌다.&lt;br&gt;말했듯이 RecyclerView는 View를 재사용하기 때문이다 (이에 대한 자세한 내용은 RecyclerView에 대한 포스팅을 작성하여 다뤄볼 것이다)&lt;br&gt; &lt;br&gt; &lt;br&gt;&lt;b&gt;5) DiffUtil 사용 가능&lt;/b&gt;&lt;br&gt; &lt;br&gt;ViewPager2에서 RecyclerView를 이용하게 되면서 DiffUtil은 사용할 수 있게 되었다.&lt;br&gt;DiffUtil은 이전 데이터 리스트와 현재 데이터 리스트 상태 차이를 계산하여, 변화가 있을 시 최소한의 데이터에 대해서만 갱신하도록하는 클래스이다. DiffUtil에 대해서도 다뤄봐야 할 내용이 좀 있기 때문에 다른 포스팅에서 다뤄보도록 하겠다.&lt;br&gt; &lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 동작 방식&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewPager는 항상 현재 페이지를 기준으로 좌, 우 페이지와 현재 페이지 총 세 페이지를 생성 및 관리한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt; 
 &lt;li&gt;페이지가 표시되는 매 순간 생성 + 미리 모든 페이지를 생성 이 두 방법을 절충 
  &lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt; 
   &lt;li&gt;생성 시간을 줄임과 동시에 메모리 절약이 가능하다&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; &lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. ViewPager2의 사용(RecyclerView 이용)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; &lt;br&gt;&lt;b&gt;3.1 app 수준의 gradle 파일에 의존성 추가&lt;/b&gt;&lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;dependencies {
	implementation 'androidx.viewpager2:viewpager2:1.0.0'
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; &lt;br&gt;&lt;b&gt;3.2 Activity 혹은 Fragment 레이아웃에 ViewPager2 추가&lt;/b&gt;&lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xmlns:tools=&quot;http://schemas.android.com/tools&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:layout_width=&quot;match_parent&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:layout_height=&quot;match_parent&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tools:context=&quot;.ViewPagerActivity&quot;&amp;gt;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;androidx.viewpager2.widget.ViewPager2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:layout_width=&quot;match_parent&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:layout_height=&quot;500dp&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app:layout_constraintStart_toStartOf=&quot;parent&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app:layout_constraintEnd_toEndOf=&quot;parent&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app:layout_constraintTop_toTopOf=&quot;parent&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:id=&quot;@+id/viewpager2&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:clipChildren=&quot;false&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:clipToPadding=&quot;false&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:paddingStart=&quot;30dp&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:paddingEnd=&quot;30dp&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:paddingTop=&quot;30dp&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:paddingBottom=&quot;30dp&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:orientation=&quot;horizontal&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:layout_marginTop=&quot;20dp&quot;/&amp;gt;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;LinearLayout
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:layout_width=&quot;0dp&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:id=&quot;@+id/indicators&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:layout_height=&quot;wrap_content&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:orientation=&quot;horizontal&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:gravity=&quot;center&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app:layout_constraintStart_toStartOf=&quot;parent&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app:layout_constraintEnd_toEndOf=&quot;parent&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app:layout_constraintTop_toBottomOf=&quot;@id/viewpager2&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:padding=&quot;15dp&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:layout_marginStart=&quot;20dp&quot;/&amp;gt;


&amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; &lt;br&gt;&lt;b&gt;3.3 ViewPager에 들어갈 Item 레이아웃 생성(view_pager_item.xml)&lt;/b&gt;&lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;LinearLayout
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:layout_width=&quot;match_parent&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:layout_height=&quot;match_parent&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:gravity=&quot;center&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:background=&quot;#CEF279&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:id=&quot;@+id/background&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:orientation=&quot;vertical&quot;&amp;gt;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;TextView
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:id=&quot;@+id/txtCount&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:layout_width=&quot;match_parent&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:layout_height=&quot;wrap_content&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:text=&quot;1 page&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:textSize=&quot;30dp&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:textStyle=&quot;bold&quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;android:gravity=&quot;center&quot; /&amp;gt;

&amp;lt;/LinearLayout&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; &lt;br&gt;&lt;b&gt;3.4 ViewPagerAdapter 생성(VPAdapter.kt)&lt;/b&gt;&lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

class VPAdapter(strData: ArrayList&amp;lt;String&amp;gt;, colorData: ArrayList&amp;lt;Int&amp;gt;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;: RecyclerView.Adapter&amp;lt;VPAdapter.MyViewHolder&amp;gt;() {

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val arrData = strData
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val arrColors = colorData

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var txtCount: TextView = itemView.findViewById(R.id.txtCount)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var bgColor : LinearLayout = itemView.findViewById(R.id.background)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val context = parent.context
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val inflater: LayoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val view: View = inflater.inflate(R.layout.view_pager_item, parent, false)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val viewHolder = MyViewHolder(view)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return viewHolder
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;holder.txtCount.text = arrData[position]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;holder.bgColor.setBackgroundColor(arrColors[position])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;override fun getItemCount(): Int {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return arrData.size
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RecyclerViewAdapter(ViewPagerAdapter)에는 아래 메소드를 필수적으로 오버라이딩 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
 &lt;li&gt;&lt;b&gt;onCreateViewHolder =&lt;/b&gt; ViewHolder 객체를 생성&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;onBindViewHolder&lt;/b&gt; = ViewHolder 에 data 를 넣는 작업 수행&lt;/li&gt;
 &lt;li&gt;&lt;b&gt;getItemCount&lt;/b&gt; = data의 갯수를 반환 해준다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; &lt;br&gt;참고로 RecyclerView의 전체 구조는 아래 사진과 같다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;645&quot; data-origin-height=&quot;293&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ngZx6/btrFDg2sTge/HgmXtGg5OiGCRgkRjcIam1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ngZx6/btrFDg2sTge/HgmXtGg5OiGCRgkRjcIam1/img.png&quot; data-alt=&quot; 출처 : https://developer.android.com/codelabs/basic-android-kotlin-training-affirmations-app#3 &quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ngZx6/btrFDg2sTge/HgmXtGg5OiGCRgkRjcIam1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FngZx6%2FbtrFDg2sTge%2FHgmXtGg5OiGCRgkRjcIam1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;645&quot; height=&quot;293&quot; data-origin-width=&quot;645&quot; data-origin-height=&quot;293&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt; 출처 : https://developer.android.com/codelabs/basic-android-kotlin-training-affirmations-app#3 &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt; &lt;br&gt;Adapter&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
 &lt;li&gt;RecyclerView에 표시될 아이템 뷰를 생성하는 역할을 한다.&lt;/li&gt;
 &lt;li&gt;사용자 데이터 리스트로부터 아이템 뷰를 만든다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; &lt;br&gt;ViewHolder&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
 &lt;li&gt;화면에 표시될 아이템 뷰를 저장하는 객체다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; &lt;br&gt; &lt;br&gt;&lt;b&gt;3.5 ViewPager가 추가된 Activity 혹은 Fragment에서 ViewPager와 ViewPagerAdapter 연결&lt;/b&gt;&lt;/p&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.viewpager2.widget.ViewPager2

class ViewPagerActivity : AppCompatActivity() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private lateinit var viewPager2: ViewPager2

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;override fun onCreate(savedInstanceState: Bundle?) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;super.onCreate(savedInstanceState)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;setContentView(R.layout.activity_view_pager)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var arrStr: ArrayList&amp;lt;String&amp;gt; = ArrayList()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var arrColorsString = arrayListOf&amp;lt;String&amp;gt;(&quot;#FF0000&quot;,&quot;#FF5E00&quot;, &quot;#FFBB00&quot;, &quot;#FFE400&quot;, &quot;#0054FF&quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var arrIntColor = ArrayList&amp;lt;Int&amp;gt;()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for (i in 1..100) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arrStr.add(i.toString())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arrIntColor.add(Color.parseColor(arrColorsString[i%5])) //5 단위로 색상이 반복해서 적용된다
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var adapter = VPAdapter(arrStr, arrIntColor)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;viewPager2 = findViewById(R.id.viewpager2)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;viewPager2.orientation = ViewPager2.ORIENTATION_HORIZONTAL
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;viewPager2.adapter = adapter

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

}&lt;/code&gt;&lt;/pre&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;462&quot; data-origin-height=&quot;802&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1PmEI/btrFz4JbXs2/Td0CAJGgnoezBOjygTP5eK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1PmEI/btrFz4JbXs2/Td0CAJGgnoezBOjygTP5eK/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1PmEI/btrFz4JbXs2/Td0CAJGgnoezBOjygTP5eK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/b1PmEI/btrFz4JbXs2/Td0CAJGgnoezBOjygTP5eK/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;417&quot; height=&quot;724&quot; data-origin-width=&quot;462&quot; data-origin-height=&quot;802&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;실습 코드를 실행하면 위와 같이 된다.&lt;br&gt;(MainActivity에서 버튼으로 ViewPager를 적용한 Activity를 불렀다)&lt;br&gt; &lt;br&gt;생각보다 복잡한 ViewPager 적용기다.&lt;br&gt;RecyclerView 말고 Fragment를 사용한 ViewPager 생성 방법도 있다.&lt;br&gt;이는 나중에 따로 작성해야 할 것 같다.&lt;br&gt; &lt;br&gt;ViewPager는 실제로 많은 어플리케이션에서 쓰이고 있다 ex) 배달의 민족&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1097&quot; data-origin-height=&quot;1623&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRnYhX/btrFvZICGs7/jDBLaYL9eNCKhFW5GINbz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRnYhX/btrFvZICGs7/jDBLaYL9eNCKhFW5GINbz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRnYhX/btrFvZICGs7/jDBLaYL9eNCKhFW5GINbz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRnYhX%2FbtrFvZICGs7%2FjDBLaYL9eNCKhFW5GINbz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;264&quot; height=&quot;391&quot; data-origin-width=&quot;1097&quot; data-origin-height=&quot;1623&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;그만큼 많이 쓰이는 위젯이므로 익혀두면 유용하게 사용할 수 있을 것 같다.&lt;br&gt; &lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
  참조 
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
 &lt;li&gt;&lt;a href=&quot;https://developer.android.com/training/animation/screen-slide?hl=ko&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;Android Developers&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href=&quot;https://jwsoft91.tistory.com/54&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;혀가 길지 않은 개발자&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href=&quot;https://recipes4dev.tistory.com/148&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;개발자를 위한 레시피&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href=&quot;https://splendidlolli.tistory.com/172&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;목표는 1년반&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Android/Widget</category>
      <category>Android</category>
      <category>PageAdapter</category>
      <category>RecyclerView</category>
      <category>ViewGroup</category>
      <category>ViewPager</category>
      <category>ViewPager2</category>
      <category>ViewPagerAdapter</category>
      <category>뷰페이저</category>
      <category>안드로이드</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/33</guid>
      <comments>https://hapen385.tistory.com/33#entry33comment</comments>
      <pubDate>Thu, 23 Jun 2022 23:46:33 +0900</pubDate>
    </item>
    <item>
      <title>[Android] Jetpack</title>
      <link>https://hapen385.tistory.com/32</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드 개발을 하다보면, Jetpack에 대해서 많이 듣게 된다. Jetpack을 이용해서 개발을 한 적은 많은 것 같은데, Jetpack 정확하게 뭐냐고 물으면 대답을 확실하게 할 자신이 없다. 따라서 Jetpack이 도대체 무엇인지 알아보기로 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;touchicon-180.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvnelB/btrFlFDt2OP/PT9T6kUP9tzWRadm83y9dK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvnelB/btrFlFDt2OP/PT9T6kUP9tzWRadm83y9dK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvnelB/btrFlFDt2OP/PT9T6kUP9tzWRadm83y9dK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvnelB%2FbtrFlFDt2OP%2FPT9T6kUP9tzWRadm83y9dK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;180&quot; height=&quot;180&quot; data-filename=&quot;touchicon-180.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 정의&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;img.png&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;1400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1TucW/btrFonhR0TT/vDxKjfuaSJnQlrGk3kvrUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1TucW/btrFonhR0TT/vDxKjfuaSJnQlrGk3kvrUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1TucW/btrFonhR0TT/vDxKjfuaSJnQlrGk3kvrUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1TucW%2FbtrFonhR0TT%2FvDxKjfuaSJnQlrGk3kvrUk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;326&quot; height=&quot;326&quot; data-filename=&quot;img.png&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;1400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 Jetpack이라는 단어 자체의 의미만 생각해보자. 네이버 영어 사전에 의하면 Jetpack의 의미는 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;제트팩 ((등에 메는 개인용 분사 추진기, 우주 유영 등에 사용))&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 안드로이드 Jetpack을 검색했을 때 나오는 이미지가 안드로이드에 부스터가 달린 것인 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 Jetpack은 안드로이드 개발을 할 때 부스터 역할을 하는 도구라고 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Android Developers에서는 아래와 같이 안드로이드 Jetpack을 정의하고 있다.&lt;span style=&quot;color: #333333;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;Jetpack은 개발자가 관심 있는 코드에 집중할 수 있도록 권장사항 준수, 상용구 코드 축소, 모든 Android 버전 및 기기에서 일관되게 작동하는 코드 작성을 돕는 라이브러리 모음입니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이와 같이 Jetpack은 개발에 자주 사용되는 라이브러리, 툴을 묶어놓은 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Jetpack은 안드로이드 개발자들이 쉽고 빠르게 퀄리티 높은 앱을 만들 수 있도록 돕는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Jetpack은 androidx.* 패키지 라이브러리로 구성된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;따라서 플랫폼 API로부터 분리되어 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;라이브러리 형태이므로 자주 업데이트가 되어 항상 가장 뛰어난 최신 버전의 Jetpack 구성 요소에 액세스할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;* 플랫폼 API : 플랫폼 버전에 따라 제공되며, 어플리케이션이 안드로이드 시스템과 통신할 수 있도록 해준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jetpack Components는 안드로이드 플랫폼의 일부가 아니므로 개발자가 원하는 androidx.* 패키지 라이브러리를 이용하여 원하는 Component만 선택하여 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 배경&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드 Jetpack에는 나오게 된 배경이 있다. 사실 Jetpack이 등장하기 전, Jetpack과 비슷한 역할을 하는 도구 모음집이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jetpack이 나오기 전, Support Library라는 라이브러리 모음집이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 Support Library는 문제가 많았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Support Library의 문제점&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 버전 규칙의 모호성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #292929;&quot;&gt;support-v4, support-v13&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #292929;&quot;&gt;위 두 버전을 봤을 때, support-v13이 더 상위 버전이라고 생각하기 쉽다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #292929;&quot;&gt;그러나 어떤 것이 상위 버전인지에 상관이 없이 support-v13은 API 13 수준 이상에서 사용할 수 있다는 의미를 갖는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #292929;&quot;&gt;그리고 support-v4는 API 4 수준 이상에서 사용할 수 있다는 의미가 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #292929;&quot;&gt;하지만 support library 24.2.0 배포 후에 위 규칙은 더이상 의미가 없게 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #292929;&quot;&gt;support library 24.2.0 버전 배포 후, support-v4는 API 8 수준 이하의 지원을 중단하게 되었기 때문이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #292929;&quot;&gt;또한, 지금은 minSdkVersion이 19 이상만 되어도 95%의 기기를 지원하므로 API 레벨을 의미하는 버전 명은 의미가 없을 수 밖에 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 단일 라이브러리로써의 문제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Support Library는 3만 여개의 함수를 제공하는 단일 라이브러리다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단일 라이브러리라는 것이, 하나의 라이브러리만 사용하고 싶어도 다른 라이브러리들이 같이 설치된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 Google play Services를 사용하고 추가로 support-v4, appcompat-v7을 사용한다고 했을 때는 DEX의 한계치인 64k를 넘어버리게 된다. 이때 앱의 규모가 커지거나 라이브러리 내의 메소드가 많을 때 일어나는 에러인 '64k reference limit'가 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* dex : 안드로이드 런타임에서 궁극적으로 실행되는 코드를 포함하는 파일. 안드로이드 가상 머신인 Dalvik이 인식할 수 있도록 Java로 짜여진 코드가 컴파일 되어 바이트 코드로 변환된 소스 파일.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단일 라이브러리일 때의 문제점이 또 있다. Support Library의 새로운 버전을 배포할 때마다 한 기능이 잘못되면 그 기능 하나때문에 업데이트했다가 한꺼번에 다운그레이드해야 하는 문제가 있다. 라이브러리의 모듈화가 되어있지 않아 패키지 별로 의존성이 높아 발생하는 문제다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 구성 요소&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;0_yGfvV-RR_8QcioE1.png&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;707&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNOl14/btrFpQ4mBSM/rbR95AUoLIZOzFDyPoyGe0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNOl14/btrFpQ4mBSM/rbR95AUoLIZOzFDyPoyGe0/img.png&quot; data-alt=&quot;출처 : Android Developers Blog(https://android-developers.googleblog.com/2018/05/use-android-jetpack-to-accelerate-your.html)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNOl14/btrFpQ4mBSM/rbR95AUoLIZOzFDyPoyGe0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNOl14%2FbtrFpQ4mBSM%2FrbR95AUoLIZOzFDyPoyGe0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1400&quot; height=&quot;707&quot; data-filename=&quot;0_yGfvV-RR_8QcioE1.png&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;707&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : Android Developers Blog(https://android-developers.googleblog.com/2018/05/use-android-jetpack-to-accelerate-your.html)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Android Jetpack의 라이브러리들은 위 사진과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 세부적으로 살펴보려면 아래 링크를 참조한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.android.com/jetpack/androidx/explorer?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Android Jetpack Library&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1655812334092&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;유형별 Jetpack 라이브러리 살펴보기 &amp;nbsp;|&amp;nbsp; Android 개발자 &amp;nbsp;|&amp;nbsp; Android Developers&quot; data-og-description=&quot;유형별 Jetpack 라이브러리 살펴보기 카테고리 선택: 모두 인기 휴대전화 이상 데이터 그래픽 수명 주기 미디어 탐색 보안 성능/테스트 &amp;nbsp;UI&amp;nbsp; * 인기 있고 자주 사용되는 라이브러리 라이브러리설&quot; data-og-host=&quot;developer.android.com&quot; data-og-source-url=&quot;https://developer.android.com/jetpack/androidx/explorer?hl=ko&quot; data-og-url=&quot;https://developer.android.com/jetpack/androidx/explorer?hl=ko&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dYTPDz/hyOQqOMW3y/RBtwSy5ETXatO2KQvSjC3K/img.png?width=1201&amp;amp;height=676&amp;amp;face=0_0_1201_676&quot;&gt;&lt;a href=&quot;https://developer.android.com/jetpack/androidx/explorer?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.android.com/jetpack/androidx/explorer?hl=ko&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dYTPDz/hyOQqOMW3y/RBtwSy5ETXatO2KQvSjC3K/img.png?width=1201&amp;amp;height=676&amp;amp;face=0_0_1201_676');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;유형별 Jetpack 라이브러리 살펴보기 &amp;nbsp;|&amp;nbsp; Android 개발자 &amp;nbsp;|&amp;nbsp; Android Developers&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;유형별 Jetpack 라이브러리 살펴보기 카테고리 선택: 모두 인기 휴대전화 이상 데이터 그래픽 수명 주기 미디어 탐색 보안 성능/테스트 &amp;nbsp;UI&amp;nbsp; * 인기 있고 자주 사용되는 라이브러리 라이브러리설&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.android.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. Jetpack Compose&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jetpack에 대해서 공부하면서 Jetpack Compose 라는 것도 따로 있다는 사실을 알게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jetpack Compose는 &lt;b&gt;안드로이드 UI를 쉽게 디자인하고 구현하기 위한 라이브러리&lt;/b&gt;다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Compose를 사용하면 Native UI를 코드 레벨로 구현할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;Jetpack과 별개의 도구로 생각하면 될 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JetPack Compose도 많은 내용을 포함하고 있는 것 같으니 추후에 포스팅해보도록 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jetpack에 대한 개념은 익힌 것 같다. 배경도 공부하니까 Jetpack에 대해 빨리 까먹을 것 같지 않은 느낌이다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jetpack의 세부 구성 라이브러리들은 사용할 때마다 공부해서 따로 포스팅을 올리는 것이 나을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jetpack의 전반적인 개념, 배경에 대해 알아보았고 구성 요소들은 추후의 포스팅에 올려보도록 하겠다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.android.com/jetpack?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Android Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/daangn/support-library-androidx-%EA%B7%B8%EB%A6%AC%EA%B3%A0-jetifier-%ED%95%AD%ED%95%B4%EA%B8%B0-2fb558f56be&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;당근마켓 팀블로그&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://todaycode.tistory.com/40&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;오늘의 코드&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/@lunay0ung/android-jetpack%EC%9D%B4%EB%9E%80-bfb360ab05ec&quot;&gt;LUNA Y0UNG님 medium&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Android/etc</category>
      <category>Android</category>
      <category>android Jetpack</category>
      <category>Jetpack</category>
      <category>JetPack Compose</category>
      <category>안드로이드</category>
      <category>안드로이드 Jetpack</category>
      <category>앱</category>
      <category>앱 개발</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/32</guid>
      <comments>https://hapen385.tistory.com/32#entry32comment</comments>
      <pubDate>Tue, 21 Jun 2022 20:59:19 +0900</pubDate>
    </item>
    <item>
      <title>[Design Pattern] 싱글톤 패턴</title>
      <link>https://hapen385.tistory.com/31</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드 Room DB의 인스턴스를 생성할 때 반드시 싱글톤 패턴으로 생성했던 것 같다. 그때는 강의에서 그렇게 하라고 해서 했었는데, 다른 곳에서도 사용할 일이 있을 것 같아서 싱글톤 패턴에 대해 정리해본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 정의&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위키백과에서는 다음과 같이 싱글톤 패턴을 정의하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소프트웨어 디자인에서 싱글톤 패턴을 따르는 클래스는, 생성자가 여러 차례에 호출되더라도 실제로 &lt;b&gt;생성되는 객체는 하나&lt;/b&gt;이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 정의에서 알 수 있듯이, 싱글톤 패턴에서는 객체(인스턴스)를 메모리에 하나만 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이 객체를 여러 스레드에서 동시에 어디에서든지 참조할 수 있도록 하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전역 범위에서 이 객체에 접근할 수 있도록 하면 어디에서든지 참조가 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성 패턴이 하나라서 싱글톤 패턴(Singleton Pattern)이라고 불린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 사용 이유&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1) 메모리 자원의 낭비를 막기 위해서 사용된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체를 하나만 생성하여 불필요한 메모리 자원 낭비를 막는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 개의 객체를 만들어서 메모리 낭비를 하지 않고, 하나의 객체를 공유해서 데이터를 변경할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2) 객체 로딩 시간이 줄어들어 성능이 좋아질 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;싱글톤 패턴으로 한 번 객체를 생성하고 나면 재사용하면 되므로 로딩 시간이 줄어든다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;3) 한 객체의 정보를 여러 객체에서 데이터를 공유해서 써야할 때 사용한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;여러 객체에서 공유해서 사용해야 한다면, 그냥 객체를 여러 개 생성하면 안되나? 이렇게 생각할 수 있는데 그렇지 못하는 경우가 있다. 혹은 그렇게 하지 않는게 나은 경우가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;DB(&lt;span&gt;DataBase)&lt;/span&gt; Handler 클래스 객체를 생성하는 경우가 대표적이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB Handler의 클래스 객체를 두 개 생성해놓았다면, 이 두 객체가 동시에 DB에 접근한다면 문제가 될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 싱글톤 패턴으로 DB Handler 객체는 전역으로 한 번만 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 이 Handler는 여러 곳에서 참조하는 일이 많으므로 전역 객체로 생성해야 쉽게 접근이 가능하고 메모리 낭비를 막을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;3. 예제&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1655641484025&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;object SingletonClass { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코틀린에서는 위와 같이 object 키워드 하나만으로 싱글톤 클래스를 생성할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멀티 스레드 환경을 고려할 필요없이 Thread-safe하게 싱글톤 코드를 작성할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1655642111853&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;object SingletonClass{ 
	val name=&quot;kim&quot;
}
val SingletonObject = SingletonClass&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그런데 위와 같이 작성하기만 하면 문제가 있다.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;object로 싱글톤을 구현한 경우, 메모리 낭비가 일어날 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코틀린 object의 경우 위 SingletonClass object는 프로세스가 시작될 때 객체가 바로 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, SingletonClass라는 클래스가 사용되지 않는데도 메모리 상에 해당 클래스의 객체가 올라가 있게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 SingletonClass의 내부 변수 name을 by lazy를 이용해 호출될 때 객체가 초기화될 수 있게 하는 방법을 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1655647803243&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;object SingletonClass{ 
	val name by lazy { &quot;kim&quot; }
}
val SingletonObject = SingletonClass&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;by lazy를 통해서 SingletonClass의 name이 호출될 때 처음 메모리 상에 올라가게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 방법으로 메모리 최적화를 할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;4. 문제점&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;싱글톤 객체가 너무 많은 책임을 가지게 되고 많은 데이터를 보유하게 되면 클래스 간의 결합도가 너무 높아지게 된다는 단점이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 멀티 스레드 환경에서 싱글톤을 사용하려면 더욱 주의해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(코틀린의 object를 사용하는 경우는 해당되지 않는 문제다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멀티 스레드 환경에서 싱글톤 패턴을 사용할 때, 동일한 자원을 2개 이상의 스레드가 동시에 이용하려고 하는 경우가 일어날 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Java로 싱글톤 패턴을 사용할 때는 더욱 주의를 해야할 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;싱글톤 패턴에 대해서 공부해보면서 코틀린에 대해서도 공부를 많이 해야할 것 같다는 생각이 들었다.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 안드로이드를 공부하면 Java로 시작하지 않았더라도, 반드시 Java를 만나게 되는 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;다음에는 Room DB를 설명하면서 DB Handler 객체를 싱글톤으로 구현하는 내용을 작성해야 겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://cliearl.github.io/posts/android/understanding-singleton-pattern/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;냉동코더의 기술블로그&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kotlinworld.com/166&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Kt World&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Design Pattern</category>
      <category>Android</category>
      <category>Design Pattern</category>
      <category>Kotlin</category>
      <category>kotlin object</category>
      <category>Singleton</category>
      <category>Singleton Pattern</category>
      <category>디자인 패턴</category>
      <category>싱글톤패턴</category>
      <category>안드로이드</category>
      <category>코틀린</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/31</guid>
      <comments>https://hapen385.tistory.com/31#entry31comment</comments>
      <pubDate>Sun, 19 Jun 2022 23:25:06 +0900</pubDate>
    </item>
    <item>
      <title>[Design Pattern] 디자인 패턴 개념</title>
      <link>https://hapen385.tistory.com/30</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;소프트웨어를 설계할 때 디자인 패턴이 중요하다는 얘기를 항상 들었지만, 왜 중요한 것이고 어떨 때 쓰이는 것인지 몰랐다. 그러다가 이번에 추천 시스템 어플리케이션을 만들면서, 디자인 패턴의 중요성을 크게 깨달았다.&lt;br /&gt;프로젝트 내의 파일들이 많아지고, 한 클래스 내에서 너무 많은 기능들이 담겨있다보니 파일을 찾기 힘들고, 코드의 가독성이 좋지 않았다. 또한 클래스의 재사용성과 확장성이 좋지 않겠다는 생각이 들었다.&lt;br /&gt;이래서 소프트웨어 설계를 철저히 하고 디자인 패턴을 적용시키는 것이구나하고 깨달았다... 이번에 제대로 디자인 패턴을 공부해서 적용시켜보려고 한다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 디자인 패턴이란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소프트웨어 공학의 소프트웨어 설계에서 공통으로 발생하는 문제에 대해 자주 쓰이는 설계 방법을 정리한 패턴이다.&lt;br /&gt;즉, 설계에서 발생하는 문제에 대해 해결책을 정리한 것이다. 효율적인 코드를 만들기 위한 방법론도 된다.&lt;br /&gt;(패턴 : 다양한 소프트웨어들로 각기 다른 프로그램을 개발하는 과정에서 공통적인(혹은 유사한) 문제점이 존재하고 이를 처리하는 과정도 공통점이 있는데 이 공통점을 뜻한다)&lt;br /&gt;같은 실수를 반복하지 않기 위해 특정 상황에서 발생하는 문제 패턴을 발견하고 이에 대한 해결 방안을 기록으로 남긴 것이다.&lt;br /&gt;&lt;br /&gt;실제로 이러한 해결책을 정해놓으면 의사소통이 매우 원활해진다.&lt;br /&gt;특히 서로 같은 패턴을 알고 있을 때 간단한 소통이 가능하다.&lt;br /&gt;다른 개발자와 문제 상황에 대해서 얘기하고 이에 대한 해결책을 장황하게 얘기할 필요 없이, 디자인 패턴 이름만 얘기해도 소통이 가능할 수 있다.&lt;br /&gt;예) 오리들의 다양한 행동을 전략 패턴으로 구현하고 있습니다&lt;br /&gt;-&amp;gt; 오리의 행동들이 클래스의 집합으로 캡슐화되어 있다&lt;br /&gt;&lt;br /&gt;또한 소프트웨어 아키텍처를 쉽게 재사용할 수 있도록 한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 구성 요소&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디자인 패턴은 아래와 같이 구성된다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style8&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;구성 요소&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;패턴의 이름&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;디자인 패턴을 부를 때 사용하는 이름과 디자인 패턴의 유형&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;문제 및 배경&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;디자인 패턴이 사용되는 분야 또는 배경, 해결하는 문제를 의미&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;솔루션&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;디자인 패턴을 이루는 요소들, 관계, 협동 가정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;사례&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;디자인 패턴의 간단한 적용 사례&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;결과&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;디자인 패턴을 사용하면 얻게 되는 이점이나 영향&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;샘플 코드&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;디자인 패턴이 적용된 원시 코드&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 디자인 패턴 유형&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디자인 패턴 유형은 크게 목적, 범위로 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;목적에 따른 디자인 패턴 종류 &lt;/b&gt;&lt;br /&gt;&lt;b&gt;목적 : 패턴이 무엇을 하는지 정의&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;생성 : 객체 인스턴스 생성에 관여, 클래스 정의와 객체 생성 방식을 구조화, 캡슐화를 수행하는 패턴&lt;/li&gt;
&lt;li&gt;구조 : 더 큰 구조 형성 목적으로 클래스나 객체의 조합을 다루는 패턴&lt;/li&gt;
&lt;li&gt;행위 : 클래스나 객체들이 상호 작용하는 방법과 역할 분담을 다루는 패턴&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;범위에 따른 디자인 패턴 종류&lt;/b&gt;&lt;br /&gt;&lt;b&gt;범위 : 패턴을 클래스에 적용하는지 객체에 적용하는지에 따라 범위가 구분되는 패턴&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클래스 : 클래스 간 관련성(상소 관계를 다루는 패턴), &lt;b&gt;컴파일 타임에 정적&lt;/b&gt;으로 결정&lt;/li&gt;
&lt;li&gt;객체 : 객체 간 관련성을 다루는 패턴, &lt;b&gt;런타임&lt;/b&gt;에 동적으로 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 디자인 패턴 종류&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;생성 패턴&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;구조 패턴&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;행위 패턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Builder&lt;/li&gt;
&lt;li&gt;Prototype&lt;/li&gt;
&lt;li&gt;Factory Method&lt;/li&gt;
&lt;li&gt;Abstract Factory&lt;/li&gt;
&lt;li&gt;Singleton&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Bridge&lt;/li&gt;
&lt;li&gt;Decorator&lt;/li&gt;
&lt;li&gt;Facade&lt;/li&gt;
&lt;li&gt;Flyweight&lt;/li&gt;
&lt;li&gt;Proxy&lt;/li&gt;
&lt;li&gt;Composite&lt;/li&gt;
&lt;li&gt;Adapter&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Mediator&lt;/li&gt;
&lt;li&gt;Interpreter&lt;/li&gt;
&lt;li&gt;Iterator&lt;/li&gt;
&lt;li&gt;Template Method&lt;/li&gt;
&lt;li&gt;Observer&lt;/li&gt;
&lt;li&gt;State&lt;/li&gt;
&lt;li&gt;Visitor&lt;/li&gt;
&lt;li&gt;Command&lt;/li&gt;
&lt;li&gt;Strategy&lt;/li&gt;
&lt;li&gt;Memento&lt;/li&gt;
&lt;li&gt;Chain of Responsibility&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구조 패턴에는 MVC, MVVM과 같은 패턴들도 포함된다.&lt;br /&gt;위의 GoF가 만든 23개의 패턴들은 각각의 특징들이 있는데 해당 특징들은 추후의 포스팅에서 정리해보도록 하겠다.&lt;br /&gt;&lt;span style=&quot;color: #666666;&quot;&gt;GoF : Gang of Four을 말한다. Erich Gamma, Richard Helm, Ralph johnson, john Vissides 총 4명이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. 장단점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style8&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;구분&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;장점&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;요구사항은 수시로 변경될 수 있다&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;- 요구사항 변경에 따른 소스 코드 변경을 최소화할 수 있게 해줌&lt;br /&gt;- 설계 변경 요청에 따라 유연한 대처 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;여러 사람이 협업하는 팀 프로젝트 진행할 경우&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;- 범용적인 코딩 스타일 적용 가능&lt;br /&gt;- 업무 논의 및 디자인 문서를 작성할 때 상호 간 의사 결정에 용여로 쓰임&lt;br /&gt;- 개발자 간 원활한 의사소통 가능&lt;br /&gt;- 재사용을 통한 개발 시간 단축&lt;br /&gt;- 소프트웨어 품질과 생산성을 높임&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;상황에 따라 인수인계가 필요한 경우&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;- 소프트웨어 구조 파악이 용이&lt;br /&gt;- 직관적인 코드 사용&lt;br /&gt;- 시간과 비용이 절약&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체 지향 설계/구현 위주로 사용 (객체 지향 위주 프로그래밍의 단점이 있다 예) 처리 속도가 비교적 느림, 객체가 많으면 용량이 커짐, 설계시 많은 시간과 노력이 필요)&lt;/li&gt;
&lt;li&gt;초기 투자 비용의 부담&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;디자인 패턴이 반드시 객체 지향에 대한 개념은 아니다. 하지만, 디자인 패턴의 내용이 거의 객체 지향을 차용한 것이 많다.&lt;br /&gt;디자인 패턴이 무조건 객체 지향을 따르는 것은 아니고, 객체 지향에 적절한 패턴이 아니어도 된다.&lt;br /&gt;디자인 패턴과 객체 지향은 별개로 보면 될 것 같다.&lt;br /&gt;&lt;br /&gt;그리고 디자인 패턴을 공부한다고 해서 잘 설계된 소프트웨어를 만들 수 있는 것도 아니다.&lt;br /&gt;소프트웨어의 해당 문제 상황이 무엇인지 정의하고 이에 대한 해결책이 될 수 있는 디자인 패턴을 적절하게 적용하는 것이 중요하다.&lt;br /&gt;&lt;br /&gt;디자인 패턴이라는 것이, 개인적으로 생각하기에 개념만 익힌다고 해서 공부가 되는 것이 아닌 것 같다.&lt;br /&gt;따라서 실습을 하는 것이 중요하다고 생각하는데 안드로이드 디자인 패턴을 공부할 경우 구글의 Codelabs를 사용하는 것이 좋은 것 같다.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://developer.android.com/codelabs/basic-android-kotlin-training-repository-pattern#0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;저장소 패턴&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;저장소 패턴 &amp;nbsp;|&amp;nbsp; Android Developers&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;저장소 패턴을 사용하여 기존 앱에서 캐싱을 구현합니다.&quot; data-og-host=&quot;developer.android.com&quot; data-og-source-url=&quot;https://developer.android.com/codelabs/basic-android-kotlin-training-repository-pattern#0&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/pwhRH/hyONQ7YtvG/zKXmhakken7B65aMYXpNU0/img.png?width=1600&amp;amp;height=1428&amp;amp;face=0_0_1600_1428,https://scrap.kakaocdn.net/dn/mpG0f/hyONHwpLDv/1C4g8FbKhNQ7pH4QcHKb51/img.png?width=900&amp;amp;height=1600&amp;amp;face=447_370_632_1567,https://scrap.kakaocdn.net/dn/wad21/hyONTwPGYN/UsrgXAfK1kOGCWk6aNGKVK/img.png?width=1120&amp;amp;height=780&amp;amp;face=0_0_1120_780&quot; data-og-url=&quot;https://developer.android.com/codelabs/basic-android-kotlin-training-repository-pattern?hl=ko&quot;&gt;&lt;a href=&quot;https://developer.android.com/codelabs/basic-android-kotlin-training-repository-pattern?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.android.com/codelabs/basic-android-kotlin-training-repository-pattern#0&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/pwhRH/hyONQ7YtvG/zKXmhakken7B65aMYXpNU0/img.png?width=1600&amp;amp;height=1428&amp;amp;face=0_0_1600_1428,https://scrap.kakaocdn.net/dn/mpG0f/hyONHwpLDv/1C4g8FbKhNQ7pH4QcHKb51/img.png?width=900&amp;amp;height=1600&amp;amp;face=447_370_632_1567,https://scrap.kakaocdn.net/dn/wad21/hyONTwPGYN/UsrgXAfK1kOGCWk6aNGKVK/img.png?width=1120&amp;amp;height=780&amp;amp;face=0_0_1120_780');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;저장소 패턴 &amp;nbsp;|&amp;nbsp; Android Developers&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;저장소 패턴을 사용하여 기존 앱에서 캐싱을 구현합니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.android.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;위 링크에는 Codelabs의 Repository Pattern의 실습 예제가 있다.&lt;br /&gt;혹은 구글의 Sunflower 프로젝트를 통해 디자인 패턴을 맛볼 수(?) 있다.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://github.com/android/sunflower&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;Sunflower&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;GitHub - android/sunflower: A gardening app illustrating Android development best practices with Android Jetpack.&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;A gardening app illustrating Android development best practices with Android Jetpack. - GitHub - android/sunflower: A gardening app illustrating Android development best practices with Android Jetp...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/android/sunflower&quot; data-og-url=&quot;https://github.com/android/sunflower&quot;&gt;&lt;a href=&quot;https://github.com/android/sunflower&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/android/sunflower&quot;&gt;
&lt;div class=&quot;og-image&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - android/sunflower: A gardening app illustrating Android development best practices with Android Jetpack.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A gardening app illustrating Android development best practices with Android Jetpack. - GitHub - android/sunflower: A gardening app illustrating Android development best practices with Android Jetp...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;구글의 Sunflower 프로젝트로는 Jetpack 컴포넌트와 MVVM 패턴을 공부해볼 수 있다. &lt;br /&gt;&lt;br /&gt;디자인 패턴에는 종류가 많아서 공부할 내용도 꽤 있지만, 공부해두면 어떤 프로젝트에 어떤 디자인 패턴을 적용할 지에 반드시 도움이 될 것 같다. 그리고 정말 간단한 프로젝트가 아닌 이상 디자인 패턴은 적용해야 할 것 같다.&lt;br /&gt;채용 공고의 Job Description을 봐도 디자인 패턴 적용 경험을 많은 곳에서 요구하고 있다...&lt;br /&gt;디자인 패턴의 이론과 동시에 실습을 공부하며, 추천 시스템 어플리케이션에도 적용해봐야 겠다.&lt;br /&gt;하지만 이론을 무조건 외우는 것이 아닌 실습과 반드시 병행하여 자연스럽게 코드에 녹아들게 해야할 것 같다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;윤영빈 서용욱 김학배 박인상 NCS 정보처리기술사 연구회, 2022 수제비 정보처리기사 필기, 건기원&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.hanbit.co.kr/channel/category/category_view.html?cms_code=CMS6705039023&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;한빛출판네트워크&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://minosaekki.tistory.com/62&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;엠아이노의 iOS&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://codedragon.tistory.com/8988&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;CodeDragon&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://velog.io/@koyo/development-common-sense-0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;koyo.log&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Design Pattern</category>
      <category>DesignPattern</category>
      <category>GOF</category>
      <category>MVC</category>
      <category>MVVM</category>
      <category>Software Architecture</category>
      <category>개발</category>
      <category>개발설계</category>
      <category>디자인패턴</category>
      <category>소프트웨어설계</category>
      <category>소프트웨어아키텍처</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/30</guid>
      <comments>https://hapen385.tistory.com/30#entry30comment</comments>
      <pubDate>Fri, 17 Jun 2022 21:20:00 +0900</pubDate>
    </item>
    <item>
      <title>[Android] SharedPreferences</title>
      <link>https://hapen385.tistory.com/29</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;로그인 기능이 있는 어플리케이션을 만들 때, SharedPrefereces를 사용한 적이 있다. SharedPreferences는 DB를 라이트하게 쓰고 싶을 때 그리고 앱이 종료돼도 데이터를 저장하고 싶을 때? 사용하는 것으로 알고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SharedPreferences에 대한 개념에 확신이 없어서 블로그에 글을 쓰면서 공부해본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;다운로드.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Kmc53/btrER6m5sQn/OAOkos9aDg3mkW82eYXcq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Kmc53/btrER6m5sQn/OAOkos9aDg3mkW82eYXcq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Kmc53/btrER6m5sQn/OAOkos9aDg3mkW82eYXcq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKmc53%2FbtrER6m5sQn%2FOAOkos9aDg3mkW82eYXcq1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;180&quot; height=&quot;180&quot; data-filename=&quot;다운로드.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. SharedPreferences란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SharedPreferences는 데이터를 저장하는 안드로이드 API다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 보통 데이터를 저장할 때 DataBase를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SQLite를 쓰거나 MySQL과 같은 DataBase에 많은 데이터를 보관한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 DB들이 있는데도 SharedPreferences를 쓰는 것은, 간단한 저장을 하기 위해서이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 설정 값들이나 여러 데이터들의 수가 DataBase에 저장할 만큼 많지 않고 비교적 적다면 SharedPreferences를 쓰는 것이 더 간편하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 로드(load) 속도가 DataBase보다 빠르고 복잡한 절차없이 간편하게 저장할 수 있기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Preference API&amp;nbsp; 랑 다른 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 특징&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;xml 파일 형태로 데이터를 저장 (data/data/패키지명/shared_prefs/SharedPreferences
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파일 형태로 저장되므로 너무 많은 데이터를 넣게 되면 메모리 예외가 나타날 수 있다&lt;/li&gt;
&lt;li&gt;파일 형태로 저장되므로 메모리 손상의 위험에 영향이 갈 수 있다&lt;/li&gt;
&lt;li&gt;보안에 취약하므로 보안이 요구되는 데이터들은 SharedPreferences로 저장하지 않는 것이 좋다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;어플리케이션이 삭제되기 전까지 데이터가 보존된다&lt;/li&gt;
&lt;li&gt;Key-Value 형태로 데이터가 저장된다&lt;/li&gt;
&lt;li&gt;불러오려는 Key 값이 없는 경우 공백 문자열을 return 한다&lt;/li&gt;
&lt;li&gt;초기 설정값(자동 로그인 여부, 진동 유무 등)과 같이 간단한 값을 저장하고 싶을 때 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 사용하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;SharedPreferences handle(인스턴스) 가져오기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- getSharedPreferences() : 여러 Activity에서 사용하는 SharedPreferences를 생성, 주로 어플리케이션 전체에서 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 메소드를 사용하면, SharedPreferences 파일이 여러 개 생성될 수 있다. 첫 번째 Paremeter에 SharedPreferences 파일의 이름이 들어간다. 앱의 모든 Context에서 이 메소드를 호출할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Context.getSharedPreferences(String, Int)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 Parameter에 파일 이름을 지정해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번째 Parameter에는 파일 읽기 관련 MODE를 설정해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 예시&lt;/p&gt;
&lt;pre id=&quot;code_1655292812653&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;val spf : SharedPreferences = context.getSharedPreferences(&quot;file_name&quot;, Context.MODE_PRIVATE)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저장 MODE에는 아래와 같은 것들이 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 68px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;MODE&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;의미&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;MODE_PRIVATE&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;어플리케이션 내에서 사용 가능, 외부 어플리케이션에서는 사용 불가, &lt;b&gt;default 값&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;MODE_WORLD_READABLE&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;외부 어플리케이션에서 읽기 가능 (API 17부터 deprecated)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;MODE_WORLD_WRITEABLE&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;외부 어플리케이션에서 쓰기 가능 (API 17부터 deprecated)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안 문제로 인해 MODE_WORLD_READABLE과 MODE_WORLD_WRITEABLE이 API 17부터 deprecated되었다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- getPreferences() : 하나의 Activity에서만 사용하는 SharedPreferences를 생성. 하나의 Activity에서만 사용하므로 Parameter에서 이름을 지을 필요 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 getPreferences에는 어떤 MODE로 저장할 것인지의 값만 Parameter로 넘기면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Context.getPreferences(Int)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Int에는 파일 읽기 관련 Parameter가 들어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 예시&lt;/p&gt;
&lt;pre class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;val spf : SharedPreferences = context.getPreferences(MODE_PRIVATE)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;SharedPreferences에 데이터 쓰기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SharedPreferences 클래스의 edit Interface를 호출하여 저장할 데이터를 xml 파일에 작성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 예시&lt;/p&gt;
&lt;pre id=&quot;code_1655293162648&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;val spf : SharedPreferences = context.getPreferences(Context.MODE_PRIVATE)
val editor = spf.edit()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Intent에서 값을 전달해주듯이, putInt() 혹은 putString() 메소드를 사용하여&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 쓸 수 있는 메소드의 종류는 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;putBoolean()&lt;/li&gt;
&lt;li&gt;putFloat()&lt;/li&gt;
&lt;li&gt;putInt()&lt;/li&gt;
&lt;li&gt;putLong()&lt;/li&gt;
&lt;li&gt;putString()&lt;/li&gt;
&lt;li&gt;putStringSet()&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SharedPreferences 파일에 쓰려고 하는 Key(데이터 이름)와 Value(데이터)를 전달한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음에 apply() 또는 commit()을 호출하면 SharedPreferences 파일에 데이터가 쓰인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 예시&lt;/p&gt;
&lt;pre id=&quot;code_1655293371473&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;val spf : SharedPreferences = context.getPreferences(Context.MODE_PRIVATE)
val editor = spf.edit()
editor.putInt(&quot;count&quot;, 1).apply()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;commit()과 apply()의 차이&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- apply() : 메모리 내의 SharedPreferences 객체를 즉시 변경하지만 디스크에 &lt;b&gt;비동기적&lt;/b&gt;으로 업데이트한다. 즉, 호출 후 바로 return 되어 스레드를 block 시키지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- commit() : 호출 시 스레드는 block되며, 디스크에 값을 &lt;b&gt;동기적&lt;/b&gt;으로 업데이트한다. ANR을 막기 위해 메인 스레드에서 호출하는 것을 주의해야 한다. 처리 결과를 True/False로 반환한다. 결과값이 필요없는 경우 apply()를 사용하는 것이 반응성면에서 좋을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;SharedPreferences에 데이터 읽기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;getInt() 혹은 getString() 메소드를 호출하여 불러오고 싶은 데이터의 Key 값을 Parameter에 넣어 데이터를 가져온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 메소드의 두 번째 Parameter에는 SharedPreferences 파일에 Key 값에 해당하는 값이 없을 시에 반환할 값을 적어준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 읽을 수 있는 Type의 종류는 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;getAll() //SharedPreferences 파일 내의 모든 데이터를 가져온다. return되는 값은 Map&amp;lt;String, ?&amp;gt; 형태이다.&lt;/li&gt;
&lt;li&gt;getBoolean()&lt;/li&gt;
&lt;li&gt;getFloat()&lt;/li&gt;
&lt;li&gt;getInt()&lt;/li&gt;
&lt;li&gt;getLong()&lt;/li&gt;
&lt;li&gt;getString()&lt;/li&gt;
&lt;li&gt;getStringSet()&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 예시&lt;/p&gt;
&lt;pre id=&quot;code_1655293805979&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;val spf : SharedPreferences = context.getPreferences(Context.MODE_PRIVATE)
val userCount = spf.getInt(&quot;count&quot;, 0)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;SharedPreferences의 데이터 삭제하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;remove()와 clear()를 호출하면 SharedPreferences 내의 데이터를 삭제할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;remove()는 특정 데이터를 삭제하는 것이고 clear()는 해당 SharedPreferences 파일의 모든 데이터를 삭제한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;remove()에는 Key Parameter가 들어간다. 어떤 Key를 가진 데이터를 삭제할 것인지, Key를 넣어주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;clear()에는 Parameter가 필요없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 예시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;remove()&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1655294281481&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;val spf : SharedPreferences = context.getPreferences(Context.MODE_PRIVATE)
val editor = spf.edit()
editor.remove(&quot;count&quot;)
editor.apply()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;clear()&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1655294302075&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;val spf : SharedPreferences = context.getPreferences(Context.MODE_PRIVATE)
val editor = spf.edit()
editor.clear()
editor.apply()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 변경하고 나서는 commit() 혹은 apply()를 해줘야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;commit()이랑 apply()의 차이는 몰랐는데, 큰 차이가 있었다는 것을 깨달았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로그인된 user의 ID 말고도 다른 초기값 지정할 때 SharedPreferences를 사용해봐야 겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 SharedPreferences와 자주 함께 사용하는게 있는데, KeyStore이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KeyStore는 토큰이나 비밀번호과 같은 중요 정보를 SharedPreferences에 저장할 때 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요 정보의 난독화를 가독화하게 하는 것이 Key인데, 이러한 Key를 추출하기 어렵게 만드는 것이 KeyStore이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음에는 KeyStore에 대해서도 다루어보겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.android.com/training/data-storage/shared-preferences?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Android Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jslee-tech.tistory.com/11&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;기억을 기록으로&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/@kangsukmin/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-sharedpreferences-%EC%82%AC%EC%9A%A9%EC%8B%9C-%EC%9C%A0%EC%9D%98%EC%A0%90-ed6b0de5fc7a&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;강석민님 medium&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android/etc</category>
      <category>Android</category>
      <category>apply()</category>
      <category>edit()</category>
      <category>getPreferences</category>
      <category>SharedPreferences</category>
      <category>안드로이드</category>
      <category>안드로이드 데이터 백업</category>
      <category>안드로이드 데이터 저장</category>
      <category>앱</category>
      <category>앱 개발</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/29</guid>
      <comments>https://hapen385.tistory.com/29#entry29comment</comments>
      <pubDate>Wed, 15 Jun 2022 21:26:20 +0900</pubDate>
    </item>
    <item>
      <title>[Algorithm] Programmers 전화번호 목록 Python 풀이</title>
      <link>https://hapen385.tistory.com/28</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;88091700.png&quot; data-origin-width=&quot;460&quot; data-origin-height=&quot;460&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZIglY/btrEGJ5JxIQ/lOYdjJpAApR5ifJjZozyEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZIglY/btrEGJ5JxIQ/lOYdjJpAApR5ifJjZozyEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZIglY/btrEGJ5JxIQ/lOYdjJpAApR5ifJjZozyEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZIglY%2FbtrEGJ5JxIQ%2FlOYdjJpAApR5ifJjZozyEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;289&quot; height=&quot;289&quot; data-filename=&quot;88091700.png&quot; data-origin-width=&quot;460&quot; data-origin-height=&quot;460&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 문제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/42577&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;전화번호 목록&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1655082493652&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 전화번호 목록&quot; data-og-description=&quot;전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다. 전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다. 구조&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/42577&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/42577&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bnJJbu/hyOK5pOxOC/8tqE4i1XiKHPX4wkAzean1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/H5m3x/hyOJwbtrKj/pBK8RKceLPExRdVtWl8Nk1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/42577&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/42577&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bnJJbu/hyOK5pOxOC/8tqE4i1XiKHPX4wkAzean1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/H5m3x/hyOJwbtrKj/pBK8RKceLPExRdVtWl8Nk1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;코딩테스트 연습 - 전화번호 목록&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다. 전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다. 구조&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;전화번호 목록의 배열이 입력으로 주어진다.&lt;/li&gt;
&lt;li&gt;전화번호 중에서 한 전화번호 전체를 접두어로 하는 다른 전화번호가 있는지 찾는다.&lt;/li&gt;
&lt;li&gt;접두어로 하는 다른 전화번호가 있다면, false를 return한다.&lt;/li&gt;
&lt;li&gt;접두어로 하는 다른 전화번호가 없다면, true를 return한다.&lt;/li&gt;
&lt;li&gt;전화번호 목록 내에서 같은 전화번호가 중복해서 들어있지 않다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 풀이&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해쉬(Hash) 문제이므로, 해쉬 개념을 사용해야 할 것 같다.&lt;/li&gt;
&lt;li&gt;물론 해쉬를 사용하지 않고도 풀 수 있는 방법은 있다.&lt;/li&gt;
&lt;li&gt;해쉬란? 데이터를 다루는 기법 중 하나로, 검색과 저장을 빠르게하는 자료구조이다. &lt;a href=&quot;https://hapen385.tistory.com/36&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;해쉬 개념 관련 포스팅은 여기&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;해쉬는 데이터를 저장할 때 Key-Value 형태로 데이터가 존재한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Key 값이 배열의 인덱스로 저장된다. 따라서 검색과 저장이 빨라질 수 있다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;해쉬 개념을 사용하여, Key(접두어)로 Value(전화번호)를 매칭하여 검사&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정답 코드의 idea&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Dictionary 변수의 Key에는 전화번호를 저장하고, Value에는 1을 저장하여 초기화한다.&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;근데 풀어보니까 Dictionary 변수가 아니라 그냥 List를 만들어서 풀어도 되는 것 같았다.&lt;/li&gt;
&lt;li&gt;그치만 List보다 Dictionary로 검사하는게 더 빠르다고 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이중 For 문으로 전화번호 내의 전화번호를 번호 하나하나씩 비교하여 접두어가 있는지 확인한다.&lt;/li&gt;
&lt;li&gt;접두어가 있는지 확인할 때는 Dictinoary 변수의 Key로 찾는다.&lt;/li&gt;
&lt;li&gt;접두어가 있는지 확인할 때 접두어 전화번호를 한 변수에 확인용으로 만들고, 전화 번호 부 내에서의 접두어 전화번호도 확인해버려서 False를 return하지 않도록 조심해야 한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;접두어 전화 번호 본인은 같은지 확인할 필요가 없다는 말&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 전체 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1655087141667&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;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: #전화 번호 Hash map의 Key에 접두어가 있는지 확인, 접두어 본인은 빼고 검사
            	return False
                
	return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(이 아래는 사족)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Problem Solving 하면 깃허브에 올려두기는 하는데, 답만 올려두니 며칠 뒤면 잘 까먹는 것 같았다. 그래서 지금부터라도 블로그에 알고리즘 문제 풀이를 정리해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 처음에 풀 때는 해쉬를 사용하지 않고 풀었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 해쉬 문제인 만큼 정석으로 풀 필요가 있다고 생각되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래야 다른 해쉬 문제들도 풀 수 있을 것 같았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해쉬를 사용해서 문제를 어떻게 풀었는지, 다른 분들의 코드를 참고하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글에도 많이 나오고, 프로그래머스 내에서도 많은 분들이 해쉬를 이용해서 푼 것이 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해쉬를 사용하지 않고 풀어도 되지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해쉬 자료구조에 대해서 미리 공부를 해놓으면 이 개념을 사용해서 다른 해쉬 문제들도 풀 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 해쉬에 대해서 미리 공부할 필요가 있는 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해쉬 테이블 자료 구조에 대해서 자세히 공부하고 싶다면, 아래 유튜브 영상이 도움이 될 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설명을 이해하기 쉽게 잘 해주셔서 자료 구조에 대해서 잘 몰라도 개념을 쉽게 익힐 수 있도록 도와주신다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://youtu.be/Vi0hauJemxA&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[자료구조 알고리즘] 해쉬테이블(Hash Table)에 대해 알아보고 구현하기&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://coding-grandpa.tistory.com/88&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;개발자로 취직하기&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Problem Solving/프로그래머스</category>
      <category>programmers</category>
      <category>Python</category>
      <category>전화번호 목록</category>
      <category>전화번호 목록 파이썬</category>
      <category>코딩테스트</category>
      <category>코딩테스트 연습</category>
      <category>코테 문제</category>
      <category>프로그래머스</category>
      <category>프로그래머스 LEVEL2</category>
      <category>해쉬</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/28</guid>
      <comments>https://hapen385.tistory.com/28#entry28comment</comments>
      <pubDate>Mon, 13 Jun 2022 11:55:23 +0900</pubDate>
    </item>
    <item>
      <title>[Android] Glide 라이브러리의 사용</title>
      <link>https://hapen385.tistory.com/27</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드 프로젝트 파일 내에 이미지가 있다면, ImageView로 drawable 파일 내의 이미지를 가져오면 된다. 그러나 만약 서버에서 이미지를 이미지 주소의 형태로 보내게 된다면 어떤 방식으로 이미지를 불러와야 할까 고민했다. 이미지 로드 라이브러리 중 Glide라는 것을 알게 되었고, 프로젝트에서도 해당 라이브러리를 적용시켜보았다. Glide 사용 내용을 정리하기 위해 포스팅을 작성하게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;touchicon-180.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sWFjZ/btrEt2zFsSS/KKNCdqu32KYiIdDNrOEVKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sWFjZ/btrEt2zFsSS/KKNCdqu32KYiIdDNrOEVKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sWFjZ/btrEt2zFsSS/KKNCdqu32KYiIdDNrOEVKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsWFjZ%2FbtrEt2zFsSS%2FKKNCdqu32KYiIdDNrOEVKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;180&quot; height=&quot;180&quot; data-filename=&quot;touchicon-180.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. Glide란?&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;glide_logo.png&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;240&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/thtWW/btrEvmKr3Vw/INTWttKLJ3Rh8jTFb2kO3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/thtWW/btrEvmKr3Vw/INTWttKLJ3Rh8jTFb2kO3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/thtWW/btrEvmKr3Vw/INTWttKLJ3Rh8jTFb2kO3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FthtWW%2FbtrEvmKr3Vw%2FINTWttKLJ3Rh8jTFb2kO3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;240&quot; data-filename=&quot;glide_logo.png&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;240&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Glide는 안드로이드에서 이미지를 빠르고 효율적으로 로드(load)할 수 있게 해주는 라이브러리다. 구글에서 공개한 라이브러리다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JPEG과 같은 이미지 뿐만 아니라 Gif와 같은 애니메이션 이미지도 불러올 수 있도록 해준다. 그리고 동영상의 스틸 로딩(loading), 디코딩, 캐싱 등 다양한 API를 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Glide는 이미지를 부드럽고 빠르게 불러올 수 있는 것에 중점을 두고 개발된 것이다. 동시에 효율적인 방식을 추구하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 사용 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;App level의 gradle 파일에서 의존성을 추가해주면 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹은 jar 파일을 &lt;a href=&quot;https://github.com/bumptech/glide/releases&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Glide releases 페이지&lt;/a&gt;에서 다운로드해서 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2.1 dependecies(의존성) 추가&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의존성 추가하는 코드는 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654924795657&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;repositories {
  google()
  mavenCentral()
}

dependencies {
  implementation 'com.github.bumptech.glide:glide:4.13.0'
  annotationProcessor 'com.github.bumptech.glide:compiler:4.13.0'
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 Glide의 버전은 추후에 업데이트될 수 있으니, &lt;a href=&quot;https://github.com/bumptech/glide&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Glide github 페이지&lt;/a&gt;에서 버전을 확인하고 추가하는 것을 추천한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만일 서버에서 이미지를 로드해야 한다면 manifest 파일을 수정해줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654925039829&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;manifest&amp;gt;
&amp;lt;application&amp;gt;
.
.
.
&amp;lt;/application&amp;gt;
&amp;lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; /&amp;gt;
&amp;lt;/manifest&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AndroidManifest.xml을 위와 같이 수정해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2.2 View에 이미지 로드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654925198921&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Glide.with(this)
    .load(R.drawable.imgfile)
    .into(imageView)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 간단하게 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;with()는 View, Fragment 또는 Activity로부터 Context를 가져온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 이미지를 로드할 곳이 어디로부터 Context를 가져오는지, View, Fragment, Activity 중에서 선택해서 적어준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;load()에는 이미지를 넣어줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 drawable 파일 내에 있는 이미지를 로드하고 싶다면, 위 코드와 같이 load(&lt;u&gt;R.drawable.이미지 파일 이름&lt;/u&gt;) 으로 적어준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버에서 이미지 url을 전달해줄 경우, 그냥 &lt;u&gt;url&lt;/u&gt;을 load()에 넣어주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Drawable, url이외에도 Bitmap, String, ResourId(Int형), ByteArray가 들어갈 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;into()에는 &lt;u&gt;ImageView의 아이디&lt;/u&gt;를 적어줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. Glide 내 메서드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 많이 사용되는 메서드는 앞서 설명한 with(), load(), into()이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 외에도 다른 메서드들이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654925789850&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Glide.with(this)
    .load(R.drawable.imgfile)
    .placeholder(R.drawable.img_place_holder)
    .error(R.drawable.img_error)
    .fallback(R.drawable.no_img)
    .into(imageView)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;placeholder() : 이미지 로드가 되기 전에 나타날 이미지를 설정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;error() : 이미지 리소스를 불러오다가 에러가 발생했을 경우의 이미지를 설정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;fallback() : 로드할 이미지 리소스가 null인 경우 보여줄 이미지를 설정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Glide의 여러 메서드들을 잘 활용하면 사용자에게 더 좋은 UX를 제공할 수 있다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Glide는 메모리, 디스크 캐싱을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 아래와 같은 메서드들이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654926136321&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Glide.with(this)
    .load(R.drawable.imgfile)
    .skipMemoryCache(true)
    .diskCacheStrategy(DiskCacheStrategy.NONE)
    .into(imageView)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;skipMemoryCache() : 메모리에 캐싱을 할지 안할지 결정할 수 있다. 캐싱하지 않으려면 true로 값을 넣어준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;diskCacheStrategy() : 디스크에 캐싱과 관련된 메서드다. 캐싱하지 않으려면 DiskCacheStrategy.NONE 값을 넣어준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이외에도 ALL, AUTOMATIC, DATA, NONE, RESOURCE와 같은 옵션이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Glide는 애니메이션 이미지 Gif도 로드할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654926420154&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Glide.with(this)
    .load(R.drawable.giffile)
    .asGif()
    .into(imageView)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 asGif()를 통해 Gif 이미지를 로드할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이미지 크기를 변경하고 싶다면 Glide의 메서드를 이용하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654926625316&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Glide.with(this)
    .load(R.drawable.giffile)
    .override(300, 200)
    .into(imageView)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;override()를 사용하면 이미지 크기를 변경할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각 가로, 세로 크기를 넣어주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지 로드할 때 에러를 원하는 대로 처리해줄 수 있는 메서드가 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1654926868461&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Glide.with(this)
        .load(R.drawable.imgfile)
        .placeholder(R.drawable.placeholder)
        .error(R.drawable.error_img)
        .listener(new RequestListener&amp;lt;String, GlideDrawable&amp;gt;() {
            @Override
            public boolean onException(Exception e, String model, Target&amp;lt;GlideDrawable&amp;gt; target, boolean isFirstResource) {
                // log exception
                Log.e(&quot;TAG&quot;, &quot;Error loading image&quot;, e);
                return false; // important to return false so the error placeholder can be placed
            }

            @Override
            public boolean onResourceReady(GlideDrawable resource, String model, Target&amp;lt;GlideDrawable&amp;gt; target, boolean isFromMemoryCache, boolean isFirstResource) {
                return false;
            }
        })
        .into(ImageView);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;listener()를 사용하면 에러 처리를 마음대로 설정해줄 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이외에도 centerCrop(), fitCenter() 등으로 이미지 스케일링이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정말 다양한 메서드들이 있으니 &lt;a href=&quot;https://bumptech.github.io/glide/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;공식 문서&lt;/a&gt;에서 확인하면 좋을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메서드들을 설명하면서 Glide는 메모리, 디스크 캐시를 사용한다고 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 대한 설명은 추후에 다른 포스팅으로 덧붙여보고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설명이 길어질 것 같아서...ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Glide 이외에도 Picasso 라는 이미지 라이브러리도 있는데, Google에서는 Glide를 밀고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이유는 추후에 적을 이미지 캐싱 포스팅에서 적어보도록 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Glide를 더 밀고 있더라도 어떤 기술이든 본인 상황에 적재적소하게 사용하면 될 것 같다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참고&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://gomsfactory.tistory.com/19&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;곰스팩토리&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/bumptech/glide&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Glide github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.yena.io/studynote/2020/06/10/Android-Glide.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;yena&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Android/etc</category>
      <category>Android</category>
      <category>androidglide</category>
      <category>glide</category>
      <category>imageload</category>
      <category>글라이드</category>
      <category>안드로이드 이미지</category>
      <category>안드로이드 이미지로드</category>
      <category>앱개발</category>
      <category>이미지로드</category>
      <category>이미지캐싱</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/27</guid>
      <comments>https://hapen385.tistory.com/27#entry27comment</comments>
      <pubDate>Sat, 11 Jun 2022 15:04:29 +0900</pubDate>
    </item>
    <item>
      <title>[Git] push</title>
      <link>https://hapen385.tistory.com/26</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;다들 처음 git commit을 하고, push를 해줄 때 git push &lt;b&gt;-u&lt;/b&gt; origin branch-named에서 -u라는 옵션을 본 적이 있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-u 옵션 뿐만 아니라, 다른 옵션도 있는데 이게 무슨 명령을 의미하는 것인지 궁금했다. 따라서 git push cli에 대해서 전체적으로 다뤄보기로 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;다운로드 (1).png&quot; data-origin-width=&quot;200&quot; data-origin-height=&quot;200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjuW0n/btrElbJIaJr/Ll3gUIqvpbbzMpCLpLWb31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjuW0n/btrElbJIaJr/Ll3gUIqvpbbzMpCLpLWb31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjuW0n/btrElbJIaJr/Ll3gUIqvpbbzMpCLpLWb31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjuW0n%2FbtrElbJIaJr%2FLl3gUIqvpbbzMpCLpLWb31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;200&quot; height=&quot;200&quot; data-filename=&quot;다운로드 (1).png&quot; data-origin-width=&quot;200&quot; data-origin-height=&quot;200&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. git push란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git commit 을 하고나서, 로컬 저장소에 변경 이력이 저장이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후에 git push를 하게 되면 로컬 저장소에 있는 변경 이력이 원격 저장소에도 반영된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 사용 방법&lt;/h3&gt;
&lt;pre id=&quot;code_1654761099780&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git push (원격 저장소 명) (브랜치 명)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 git push는 두 가지 인자를 받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원격 저장소 명과 브랜치 명을 두 가지 인자로 받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654761173780&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git push origin main&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 cli는 main 브랜치의 변경 이력을 origin(원격 저장소)에 올리겠다는 의미가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원격 저장소 명이 origin이 아닐 수도 있는데, 원격 저장소 명을 확인하고 싶다면 아래 명령어를 통해 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654762076003&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git remote&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. git push 옵션&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3.1. git push -u 옵션 사용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git push를 할 때 매번 원격 저장소 명과 브랜치 명을 입력해야 하는 것은 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git push를 하면서 -u 옵션을 사용해주었다면, 두 가지 인자(원격 저장소 명, 브랜치 명)은 생략해도 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654762253774&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git push -u origin main&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 push를 할 때 위와 같이 입력해주었다면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음에 push 할 때는 아래와 같이 간략하게 입력해주어도 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654762300351&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git push&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-u 옵션으로 원격 저장소 명과 브랜치 명 인자를 생략할 수 있게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 옵션을 적용 함으로써, 앞으로 git push할 때는 원격 저장소에 변경 이력을 자동으로 연결하게 된 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654762687711&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git push -u origin main&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 cli를 실행하고 난 뒤에 git push를 한다면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;origin과 main 이 두 가지 인자를 생략해도 자동으로&amp;nbsp; main 브랜치의 변경 이력이 원격 저장소에 있는 main에 반영된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3.2. git push -f 옵션 사용(주의)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git push에 -f 옵션을 주게 되면, 코드 변경 이력을 강제로 원격 저장소에 반영할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원격 저장소에 있는 커밋 내역의 Flow와 로컬 저장소에 있는 커밋 내역의 Flow가 맞지 않더라도 강제로 덮어쓸 수 있게 하는 옵션이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 옵션은 협업할 때는 매우 주의해서 사용해야 하는 옵션이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀원이 이미 원격 저장소에서 변경 이력을 내려받았을 경우,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-f 옵션을 적용해서 git push를 해버린다면 나중에 팀원이 git push를 할 때 충돌이 발생할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 개인 프로젝트나 해결책이 이 방법 밖에 없는 경우 이외에는 -f 옵션을 사용하지 않는 것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654763324079&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git push -f origin main&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-u 옵션과 비슷하게 위와 같이 명령어를 작성해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;번외.&amp;nbsp; 옵션 없이 git push 인자 생략&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법은 git config 파일의 설정 값을 수정하면 사용할 수 있는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.1.의 git push -u과 마찬가지로 이 방법을 사용하면 인자를 생략할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git config 파일의 설정 값들은 아래 명령어를 통해서 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654764025263&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git config --list&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 위에서 설정 값을 확인할 필요 없이 그냥 아래 명령어를 통해 git push를 인자없이 실행할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1654764175730&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git config --global push.default current&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어는 push.default 값을 cuurent로 설정하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 설정해주고 git push하면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 브랜치를 기준으로 현재 브랜치와 이름이 같은 원격 저장소의 브랜치에 자동으로 연결이 되어 push가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git을 처음 사용했을 때 굉장히 복잡하게 느껴졌던 기억이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금도 물론 복잡한 감이 있지만, 많이 쓰고 공부하다보니 조금씩 나아지는 게 느껴지는 것 같기도? 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;push 같이 필수적으로 쓰이는 git cli는 이렇게 개념을 자세하게 공부할 필요가 있는 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://leeborn.tistory.com/entry/git-config-%ED%8C%8C%EC%9D%BC-%ED%99%95%EC%9D%B8-%EB%B0%8F-%EB%B3%80%EA%B2%BD&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;리본&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.daleseo.com/git-push/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;DaleSeo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Git</category>
      <category>cli</category>
      <category>git</category>
      <category>git bash</category>
      <category>git cli</category>
      <category>git Push</category>
      <category>Git 명령어</category>
      <category>github</category>
      <category>개발</category>
      <category>깃</category>
      <category>깃허브</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/26</guid>
      <comments>https://hapen385.tistory.com/26#entry26comment</comments>
      <pubDate>Thu, 9 Jun 2022 17:48:35 +0900</pubDate>
    </item>
    <item>
      <title>[Android] Handler 개념</title>
      <link>https://hapen385.tistory.com/25</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드를 공부하면서 안드로이드 내의 스레드 개념을 알게되고, 이때 Handler 라는 것이 있다는 것을 알게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 당시에는 글을 읽어봐도 Handler에 대한 감이 잡히지 않았다. 그래서 다시 공부하며 직접 글을 쓰면서 정리하고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;touchicon-180.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cf8qzL/btrD3xx5Isc/K4VZSG5zSZZJMY6VaSsmE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cf8qzL/btrD3xx5Isc/K4VZSG5zSZZJMY6VaSsmE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cf8qzL/btrD3xx5Isc/K4VZSG5zSZZJMY6VaSsmE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcf8qzL%2FbtrD3xx5Isc%2FK4VZSG5zSZZJMY6VaSsmE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;180&quot; height=&quot;180&quot; data-filename=&quot;touchicon-180.png&quot; data-origin-width=&quot;180&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 배경&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어쩌다가 Handler라는 것이 만들어지게 된 것일까? 그리고 Handler라는 것은 어디에 쓰는 것일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞에서 스레드를 공부하면서 Handler를 알게 되었다고 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 유추할 수 있듯이, Handler는 스레드와 관련된 일을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드에는 메인 스레드와 워커 스레드가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메인 스레드에서는 대게 UI 관련된 작업을 하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간이 오래 걸리는 작업들은 워커 스레드에서 진행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약, 워커 스레드에서 UI를 처리하는 작업을 하거나&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메인 스레드에서 하는 일을 하려고 한다면 어떻게 될까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 task나 UI를 그리려는 View에 동시 접근하면 오류가 나게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 task(혹은 View)가 어디서 일을 진행해야 할지 모르기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 Handler가 힘을 발휘한다(?)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떻게 Handler가 제 역할을 하는지 계속 읽어보도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 역할&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.에서 얘기했던 메인 스레드와 워커 스레드를 이용해서 Handler의 역할을 설명할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Handler의 역할을 한 마디로 정의하자면 &lt;b&gt;스레드 통신(메인 스레드, 워커 스레드와 같은 여러 스레드의)&lt;/b&gt;을 도와준다고 할 수 있겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.에서 메인 스레드와 워커 스레드가 한 가지 task에 동시에 접근하면 문제가 된다고 언급했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-07 오후 5.45.41.png&quot; data-origin-width=&quot;507&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGxv40/btrEbEyorPF/fzXWemZfxyabBll6ix2BH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGxv40/btrEbEyorPF/fzXWemZfxyabBll6ix2BH1/img.png&quot; data-alt=&quot;출처 : 안드로이드 노트(https://brunch.co.kr/@mystoryg/84)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGxv40/btrEbEyorPF/fzXWemZfxyabBll6ix2BH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGxv40%2FbtrEbEyorPF%2FfzXWemZfxyabBll6ix2BH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;507&quot; height=&quot;388&quot; data-filename=&quot;스크린샷 2022-06-07 오후 5.45.41.png&quot; data-origin-width=&quot;507&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 안드로이드 노트(https://brunch.co.kr/@mystoryg/84)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 사진처럼, 메인 스레드에서도 setText()를 하려고 하고&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동시에 워커 스레드도 한 가지 textView에 setText()를 하려고 한다고 가정하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;setText()가 어디서 시행되어야 하는지 문제가 생길 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 문제를 해결하기 위해서 Handler가 등장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-07 오후 5.45.57.png&quot; data-origin-width=&quot;777&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9XBSC/btrD8iIUkBM/4pKYupnZaXCSvKKOPlzSJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9XBSC/btrD8iIUkBM/4pKYupnZaXCSvKKOPlzSJk/img.png&quot; data-alt=&quot;출처 : 안드로이드 노트(https://brunch.co.kr/@mystoryg/84)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9XBSC/btrD8iIUkBM/4pKYupnZaXCSvKKOPlzSJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9XBSC%2FbtrD8iIUkBM%2F4pKYupnZaXCSvKKOPlzSJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;777&quot; height=&quot;388&quot; data-filename=&quot;스크린샷 2022-06-07 오후 5.45.57.png&quot; data-origin-width=&quot;777&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 안드로이드 노트(https://brunch.co.kr/@mystoryg/84)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아까 말했던 setText() 예시와 같이 워커 스레드에서 UI 처리나 메인 스레드에서 해야 할 일을 처리하는 경우가 생겼다면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;워커 스레드와 메인 스레드가 동시에 task에 접근하는 것이 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림과 같이 워커 스레드와 메인 스레드 간 해야할 일을 Handler를 통해 공유한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Handler가 해야 할 일을 전달하는 &lt;b&gt;메시지 전달 역할&lt;/b&gt;을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림에 따르면, 워커 스레드에서 메인 스레드에 UI 처리를 요청해야 할 일이 생긴 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 Handler라는 메시지 도구를 사용해서 메인 스레드에 할 일을 전달한 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 요소&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Handler에 사용되는 요소는 총 4가지가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-07 오후 6.08.23.png&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCZ2FQ/btrEbDGdggi/STKLjM73CwzAGbk82C37hk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCZ2FQ/btrEbDGdggi/STKLjM73CwzAGbk82C37hk/img.png&quot; data-alt=&quot;출처 : Tutorial by eyehunts(https://tutorial.eyehunts.com/android/android-handler-background-thread-communicate-ui-thread/)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCZ2FQ/btrEbDGdggi/STKLjM73CwzAGbk82C37hk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCZ2FQ%2FbtrEbDGdggi%2FSTKLjM73CwzAGbk82C37hk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;760&quot; height=&quot;453&quot; data-filename=&quot;스크린샷 2022-06-07 오후 6.08.23.png&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;453&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : Tutorial by eyehunts(https://tutorial.eyehunts.com/android/android-handler-background-thread-communicate-ui-thread/)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1) Message&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;전달할 데이터를 한 곳에 저장하는 클래스&lt;/li&gt;
&lt;li&gt;하나의 데이터를 보내기 위해서는 한 개의 Message 인스턴스가 필요&lt;/li&gt;
&lt;li&gt;데이터가 있는 Message 객체를 Handler로 보내면, 해당 객체는 Message Queue에 쌓이게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2) Message Queue&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Message 객체를 Queue 형태로 관리하는 자료 구조&lt;/li&gt;
&lt;li&gt;Queue 형태이므로 FIFO(First In First Out) 방식으로 동작&lt;/li&gt;
&lt;li&gt;Message는 Message Queue에 들어온 순서에 따라 차례대로 저장(First In)&lt;/li&gt;
&lt;li&gt;가장 먼저 들어온 Message 객체부터 순서대로 처리(First Out)&lt;/li&gt;
&lt;li&gt;앱의 메인 스레드에서 기본적으로 사용&lt;/li&gt;
&lt;li&gt;개발자가 MessageQueue 객체를 직접 참조하여 Message를 전달하거나 가져와서 처리하지 않는다.&lt;/li&gt;
&lt;li&gt;Message 전달은 Message Queue에 연결된 Handler를 통해서 이루어지기 때문이다.&lt;/li&gt;
&lt;li&gt;Message Queue로부터 Message를 가져와서 처리하는 역할은 Looper가 한다.&lt;/li&gt;
&lt;li&gt;단순히 Message 객체 리스트만 관리한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3) Looper&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Message Queue로부터 Message를 가져와 해당 Message와 연결된 Handler를 호출&lt;/li&gt;
&lt;li&gt;Looper라는 이름은, Message 처리를 위해 Message Loop를 실행한다고 해서 지어진 이름&lt;/li&gt;
&lt;li&gt;안드로이드 앱의 메인 스레드에는 Looper 객체를 사용하여 Message Loop를 실행하는 코드가 이미 구현되어 있다.&lt;/li&gt;
&lt;li&gt;다시 말해, 개발자가 메인 스레드에서 Message Loop와 관련된 코드를 작성할 필요 없다.&lt;/li&gt;
&lt;li&gt;개발자는 메인 스레도로 전달할 Message 객체를 구성하고, 스레드의 Message Queue에 연결된 Handler를 통해 해당 메시지를 보내기만 하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4) Handler&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Message Queue로 메시지를 보내고 처리할 수 있게 만들어준다.&lt;/li&gt;
&lt;li&gt;메인 스레드에서 개발자가 메시지 전달과 처리를 할 수 있게 Message Queue에 접근하게 해주는 창구 역할을 한다.&lt;/li&gt;
&lt;li&gt;스레드와 관련된 Handler를 얻으려면, Handler 클래스 인스턴스를 생성하기만 하면 된다.&lt;/li&gt;
&lt;li&gt;만들어진 Handler 인스턴스는 자동으로 해당 스레드와 Message Queue에 연결(bound)된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. Handler 참고 사항&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스레드 통신을 위해서는 다른 스레드 뿐만 아니라 자기 자신인 스레드에도 Message를 보낼 수 있다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;외부 스레드에서 전달되는 Message 처리를 위해 구현한 기능을 그대로 사용하는 경우가 해당&lt;/li&gt;
&lt;li&gt;순차적으로 실행돼야 하는 코드들 사이에 시스템 이벤트가 고려되어야 하는 경우가 해당&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Handler는 여러 개 만들 수 있다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;오히려 하나의 Handler에서 모든 메시지를 처리하는 것은 좋지 않다.&lt;/li&gt;
&lt;li&gt;Message 종류 및 기능에 따라 여러 개의 Handler로 나누어 처리하는 것이 낫다.&lt;/li&gt;
&lt;li&gt;단, 스레드에서 적절한 Handler를 사용하는 것에 유의&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Handler가 뭐하는 것인지 몰랐는데 배경을 이해하고 나니 역할도 이해가 잘된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정말 간단하게 구현된 앱이 아니라면, 필수적으로 사용돼야 할 것 같은 클래스다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;번외로, &lt;b&gt;왜 스레드 통신이 되어야 하는지&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 &lt;b&gt;메인 스레드에서 모든 일을 해결하지 않는 지&lt;/b&gt;에 대한 얘기를 하고 마치도록 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메인 스레드에서 시간이 오래걸리고 무거운 task를 하지 않는 이유는 UI 처리에 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메인 스레드에서 UI를 관리하고 이 task는 사용자에게 바로 보여지게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메인 스레드에서 UI task가 아니라, 시간이 오래 걸리는 다른 task를 시행했다고 가정해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱에서는 UI를 처리해야 할 시간에 다른 task를 하게 되어 UI 처리가 늦어지게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱 화면에서 아무 반응이 없다면 사용자는 답답함을 느끼게 될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 메인 스레드에서는 반응성을 높일 수 있게 UI 처리를 대게 하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 시간이 오래 걸리는 task들은 워커 스레드에게 맡기게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후에는 Handler를 안드로이드 스튜디오에서 직접 활용하는 포스팅도 작성해볼 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://recipes4dev.tistory.com/166&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;개발자를 위한 레시피&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://brunch.co.kr/@mystoryg/84&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;안드로이드 노트&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Android/etc</category>
      <category>Android</category>
      <category>handler</category>
      <category>스레드</category>
      <category>스레드통신</category>
      <category>안드로이드</category>
      <category>안드로이드 스레드</category>
      <category>안드로이드스튜디오</category>
      <category>앱</category>
      <category>앱개발</category>
      <category>핸들러</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/25</guid>
      <comments>https://hapen385.tistory.com/25#entry25comment</comments>
      <pubDate>Tue, 7 Jun 2022 18:39:54 +0900</pubDate>
    </item>
    <item>
      <title>[React Native] iOS  폰트(Font-Family) 적용하기</title>
      <link>https://hapen385.tistory.com/24</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;일전에 React로 토이 프로젝트를 만드려고 한 적이 있었다. 그 때는 폰트 적용하는 것이 그닥 어렵지 않았던 것 같았는데..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React Native로 iOS 어플리케이션의 폰트를 적용하는 방법이 약간 번거로웠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 또한 기록해두면 나중에 또 폰트 적용할 때 도움이 되지 않을까 싶어 포스팅해본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;img.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;848&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bluG0W/btrDYd9qPOO/ONF1LHzJaoyJZKT12KzPS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bluG0W/btrDYd9qPOO/ONF1LHzJaoyJZKT12KzPS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bluG0W/btrDYd9qPOO/ONF1LHzJaoyJZKT12KzPS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbluG0W%2FbtrDYd9qPOO%2FONF1LHzJaoyJZKT12KzPS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1200&quot; height=&quot;848&quot; data-filename=&quot;img.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;848&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 서체 설치&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-05 오후 11.36.48.png&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;475&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZVOFm/btrD0r6TOq6/K2shaYY1Zz1EqoxbrzAhaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZVOFm/btrD0r6TOq6/K2shaYY1Zz1EqoxbrzAhaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZVOFm/btrD0r6TOq6/K2shaYY1Zz1EqoxbrzAhaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZVOFm%2FbtrD0r6TOq6%2FK2shaYY1Zz1EqoxbrzAhaK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;512&quot; height=&quot;475&quot; data-filename=&quot;스크린샷 2022-06-05 오후 11.36.48.png&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;475&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연한 것이지만 먼저 앱에 적용하고 싶은 폰트를 찾아, 맥에 설치해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트루타입 파일(ttf)이든, 오픈타입 파일(otf)이든 찾아서 설치해주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 파일을 클릭하고 '서체 설치' 버튼을 누른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 서체 파일 앱 내에 추가&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 디렉터리로 이동하여 해당 디렉터리의 ios 파일 내에 폰트 파일을 추가해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Finder로 직접 추가해줘도 되고, 해당 포스팅에서는 터미널에서 처리해준 방법을 소개할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654443094417&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd 프로젝트 디렉터리 명&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어를 통해 프로젝트 디렉터리로 이동한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654443112025&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd ios&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1654443141895&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mkdir Fonts&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 ios 폴더로 이동해서 여기서 Fonts 폴더를 만들어준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654443226047&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cp 폰트 파일 경로/폰트 파일.ttf(혹은 otf) ./&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cp 명령어를 통해서 폰트 파일을 해당 디렉터리에 복사해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;폰트 파일 경로의 경우, Finder에서 해당 폰트가 있는 위치에서 폰트를 터미널로 드래그하면 쉽게 적을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시는 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-06 오전 12.38.22.png&quot; data-origin-width=&quot;827&quot; data-origin-height=&quot;442&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lOQqy/btrDZu3UFmq/stQvWdc3TLM51waSr7acxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lOQqy/btrDZu3UFmq/stQvWdc3TLM51waSr7acxK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lOQqy/btrDZu3UFmq/stQvWdc3TLM51waSr7acxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlOQqy%2FbtrDZu3UFmq%2FstQvWdc3TLM51waSr7acxK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;827&quot; height=&quot;442&quot; data-filename=&quot;스크린샷 2022-06-06 오전 12.38.22.png&quot; data-origin-width=&quot;827&quot; data-origin-height=&quot;442&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 진행해주면 프로젝트 디렉터리 내, ios 디렉터리 내, Fonts 디렉터리 내에 폰트 파일이 복사된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;중간에 mkdir 명령어가 적용되지 않은 것은, 이미 Fonts 폴더를 만들어놓아서 그런 것이다.&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 프로젝트 Info.plist 파일 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;폰트 설정의 가장 핵심적인 단계다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;XCode로 해당 프로젝트의 .xcworkspace 혹은 .xcodeproj 파일을 연다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-05 오후 11.43.45.png&quot; data-origin-width=&quot;262&quot; data-origin-height=&quot;205&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsOYch/btrD0s5OH5z/IK7Wkk7ddZ9IcAh9fCaCl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsOYch/btrD0s5OH5z/IK7Wkk7ddZ9IcAh9fCaCl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsOYch/btrD0s5OH5z/IK7Wkk7ddZ9IcAh9fCaCl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsOYch%2FbtrD0s5OH5z%2FIK7Wkk7ddZ9IcAh9fCaCl1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;262&quot; height=&quot;205&quot; data-filename=&quot;스크린샷 2022-06-05 오후 11.43.45.png&quot; data-origin-width=&quot;262&quot; data-origin-height=&quot;205&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트를 열었으면, 왼쪽 상단의 폴더 아이콘을 클릭하여 Project navigator를 본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 프로젝트 명이 적힌 폴더와 Pod 파일 폴더가 나올 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 중 프로젝트 명을 클릭한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-06 오전 12.40.59.png&quot; data-origin-width=&quot;1374&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0mwEB/btrDXbW79YZ/rN4UKb3IzwkARC7wg66Fd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0mwEB/btrDXbW79YZ/rN4UKb3IzwkARC7wg66Fd0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0mwEB/btrDXbW79YZ/rN4UKb3IzwkARC7wg66Fd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0mwEB%2FbtrDXbW79YZ%2FrN4UKb3IzwkARC7wg66Fd0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1374&quot; height=&quot;593&quot; data-filename=&quot;스크린샷 2022-06-06 오전 12.40.59.png&quot; data-origin-width=&quot;1374&quot; data-origin-height=&quot;593&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 오른쪽에 위와 같은 화면이 나올 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, TARGETS이 프로젝트 명으로 적용이 되어 있어야 하고, Build Phases 를 클릭해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Build Phases 에서 Copy Bundle Resources를 클릭하여 열어본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 사진과 같이 여러 목록이 나오게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 화면에서는 폰트 파일이 추가되어 있지만 원래는 폰트 파일이 추가되어 있지 않을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 아래의 &lt;b&gt;+&lt;/b&gt; 를 클릭해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-06 오전 12.45.03.png&quot; data-origin-width=&quot;390&quot; data-origin-height=&quot;459&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4G6Qh/btrD177YuWk/aEL3Kg0sn33xpXqridLTz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4G6Qh/btrD177YuWk/aEL3Kg0sn33xpXqridLTz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4G6Qh/btrD177YuWk/aEL3Kg0sn33xpXqridLTz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4G6Qh%2FbtrD177YuWk%2FaEL3Kg0sn33xpXqridLTz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;390&quot; height=&quot;459&quot; data-filename=&quot;스크린샷 2022-06-06 오전 12.45.03.png&quot; data-origin-width=&quot;390&quot; data-origin-height=&quot;459&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;+ 를 클릭해주었다면 위와 같은 화면을 보게 될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 폰트 파일을 찾아 추가해주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Add other를 눌러서, 2. 단계에서 만들어준 Fonts 파일 내의 폰트를 추가해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;폰트가 추가 되었다면 Copy Bundle Resources 목록 내에도 폰트 파일이 추가되었을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-06 오전 12.47.55.png&quot; data-origin-width=&quot;1350&quot; data-origin-height=&quot;459&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xDJUM/btrD3SCuGza/PQ87gydQvkpQ1tUQOhE3Rk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xDJUM/btrD3SCuGza/PQ87gydQvkpQ1tUQOhE3Rk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xDJUM/btrD3SCuGza/PQ87gydQvkpQ1tUQOhE3Rk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxDJUM%2FbtrD3SCuGza%2FPQ87gydQvkpQ1tUQOhE3Rk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1350&quot; height=&quot;459&quot; data-filename=&quot;스크린샷 2022-06-06 오전 12.47.55.png&quot; data-origin-width=&quot;1350&quot; data-origin-height=&quot;459&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 Bundle Phases가 아니라 Info로 가서 설정을 해줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 사진처럼 Key라고 되어있는 것을 추가해주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-06 오전 12.49.38.png&quot; data-origin-width=&quot;366&quot; data-origin-height=&quot;89&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A1PvX/btrDYetIDv4/hZN2KYLtgu8NATHasLGFX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A1PvX/btrDYetIDv4/hZN2KYLtgu8NATHasLGFX1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A1PvX/btrDYetIDv4/hZN2KYLtgu8NATHasLGFX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA1PvX%2FbtrDYetIDv4%2FhZN2KYLtgu8NATHasLGFX1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;366&quot; height=&quot;89&quot; data-filename=&quot;스크린샷 2022-06-06 오전 12.49.38.png&quot; data-origin-width=&quot;366&quot; data-origin-height=&quot;89&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;Key 목록 중에서 아무 행이나 마우스를 갖다 대면, 위 사진과 같이 &lt;b&gt;+, -&lt;/b&gt; 표시가 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 중 + 를 클릭하여 Key를 추가해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-06 오전 12.51.26.png&quot; data-origin-width=&quot;366&quot; data-origin-height=&quot;190&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baNCJU/btrD4VFK3Hf/dwzTUlWuqu7dXU4OamciT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baNCJU/btrD4VFK3Hf/dwzTUlWuqu7dXU4OamciT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baNCJU/btrD4VFK3Hf/dwzTUlWuqu7dXU4OamciT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaNCJU%2FbtrD4VFK3Hf%2FdwzTUlWuqu7dXU4OamciT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;366&quot; height=&quot;190&quot; data-filename=&quot;스크린샷 2022-06-06 오전 12.51.26.png&quot; data-origin-width=&quot;366&quot; data-origin-height=&quot;190&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;+ 를 누르면 App Category를 선택하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fonts provided by application 카테고리를 추가해도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-06 오전 12.52.46.png&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;59&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNTkiw/btrD1frEcGc/32cniAwjFOlpvqhHo0kpx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNTkiw/btrD1frEcGc/32cniAwjFOlpvqhHo0kpx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNTkiw/btrD1frEcGc/32cniAwjFOlpvqhHo0kpx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNTkiw%2FbtrD1frEcGc%2F32cniAwjFOlpvqhHo0kpx0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;815&quot; height=&quot;59&quot; data-filename=&quot;스크린샷 2022-06-06 오전 12.52.46.png&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;59&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 카테고리 내의 아이템을 추가해줘야 폰트가 적용이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;+ 를 누르고 오른쪽의 폰트 파일 명이 적혀있는 부분은 원래 비어있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 위 사진과 같이 아이템마다 오른쪽 부분을 폰트 파일명으로 채워준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 프로젝트 내에서 Font Family 적용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;드디어 적용하는 단계다. 그말은 즉슨 마지막 단계라는 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-06 오전 12.55.30.png&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;112&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUDs9P/btrDZuJB8BV/oN3kpbbtN88VKOER4iAui1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUDs9P/btrDZuJB8BV/oN3kpbbtN88VKOER4iAui1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUDs9P/btrDZuJB8BV/oN3kpbbtN88VKOER4iAui1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUDs9P%2FbtrDZuJB8BV%2FoN3kpbbtN88VKOER4iAui1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;815&quot; height=&quot;112&quot; data-filename=&quot;스크린샷 2022-06-06 오전 12.55.30.png&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;112&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(StyleSheet를 사용해서 CSS를 적용시켜주었기 때문에 위와 같은 형태가 나온다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;styled-components의 경우, font-family로 폰트 명을 적어주면 적용이 될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 주의해야 할 점이 fontFamily의 속성 값을 적어줄 때 조심해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서체 관리자에 있는 PodScript 이름과 같게 속성 값을 적어주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-06 오전 1.00.06.png&quot; data-origin-width=&quot;999&quot; data-origin-height=&quot;520&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kIsLd/btrDYqmc95h/TWXEoCJp1cODDs2rESHIt0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kIsLd/btrDYqmc95h/TWXEoCJp1cODDs2rESHIt0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kIsLd/btrDYqmc95h/TWXEoCJp1cODDs2rESHIt0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkIsLd%2FbtrDYqmc95h%2FTWXEoCJp1cODDs2rESHIt0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;999&quot; height=&quot;520&quot; data-filename=&quot;스크린샷 2022-06-06 오전 1.00.06.png&quot; data-origin-width=&quot;999&quot; data-origin-height=&quot;520&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서체 관리자에 들어가서, 가장 왼쪽의 목록 중 모든 서체를 클릭하여 맥 내의 모든 서체를 불러온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 서체 중에서, 프로젝트에 적용할 서체를 찾는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 폰트를 클릭하면, PodScript 이름이 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PodScript 이름을&amp;nbsp; fontFamily의 속성 값으로 적용시켜주도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각보다 과정이 번거로워서 당황스러웠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 우리에게는 많은 정보들(&lt;s&gt;구글&lt;/s&gt;)이 있으니 그닥 두려워하지 않아도 된다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://juzero-space.tistory.com/257&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;JuzeroSpace&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>React Native</category>
      <category>ios</category>
      <category>React native font</category>
      <category>reactnative</category>
      <category>리액트</category>
      <category>리액트 네이티브 폰트</category>
      <category>리액트 폰트</category>
      <category>리액트네이티브</category>
      <category>앱</category>
      <category>앱 개발</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/24</guid>
      <comments>https://hapen385.tistory.com/24#entry24comment</comments>
      <pubDate>Mon, 6 Jun 2022 01:04:08 +0900</pubDate>
    </item>
    <item>
      <title>[Deep Learning] M1 맥에 Tensorflow 설치</title>
      <link>https://hapen385.tistory.com/23</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 과목에서 Tensorflow를 사용해서 퍼셉트론을 적용하게 되었다. Windows에서의 Tensorflow 설치와 맥에서 설치는 다른 부분이 있다. 설치 과정도 기록해두면 많은 사람들에게 도움이 될 것 같아 설치법을 작성하게 되었다. 생각보다 어렵지 않으니, 이 글을 보고 쉽게 설치하시는 분들이 많았으면 좋겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 이 포스팅을 Deep Learning에 넣는 것은 어떨까 싶긴한데 그래도 관련있으니까 딥러닝 카테고리에 넣어놨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1_iDQvKoz7gGHc6YXqvqWWZQ.png&quot; data-origin-width=&quot;463&quot; data-origin-height=&quot;463&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/F1XqI/btrDNT2iAlC/VJ7Ef3Y9wLwth1y7WXVGT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/F1XqI/btrDNT2iAlC/VJ7Ef3Y9wLwth1y7WXVGT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/F1XqI/btrDNT2iAlC/VJ7Ef3Y9wLwth1y7WXVGT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FF1XqI%2FbtrDNT2iAlC%2FVJ7Ef3Y9wLwth1y7WXVGT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;292&quot; height=&quot;292&quot; data-filename=&quot;1_iDQvKoz7gGHc6YXqvqWWZQ.png&quot; data-origin-width=&quot;463&quot; data-origin-height=&quot;463&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치 단계&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;PyCharm 설치&lt;/li&gt;
&lt;li&gt;miniforge 환경 구축&lt;/li&gt;
&lt;li&gt;가상 환경 구축&lt;/li&gt;
&lt;li&gt;Tensorflow 설치&lt;/li&gt;
&lt;li&gt;설치 최종 확인&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. PyCharm 설치&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-02 오후 11.31.04.png&quot; data-origin-width=&quot;1535&quot; data-origin-height=&quot;499&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wMQQc/btrDPjBwrLc/u9DcqiyZu4sJ5y3AMbKM01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wMQQc/btrDPjBwrLc/u9DcqiyZu4sJ5y3AMbKM01/img.png&quot; data-alt=&quot;출처 : Jet Brains&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wMQQc/btrDPjBwrLc/u9DcqiyZu4sJ5y3AMbKM01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwMQQc%2FbtrDPjBwrLc%2Fu9DcqiyZu4sJ5y3AMbKM01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1535&quot; height=&quot;499&quot; data-filename=&quot;스크린샷 2022-06-02 오후 11.31.04.png&quot; data-origin-width=&quot;1535&quot; data-origin-height=&quot;499&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : Jet Brains&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.jetbrains.com/ko-kr/pycharm/download/#section=mac&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;PyCharm 다운로드&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 링크를 통해 PyCharm을 설치해준다. M1 맥 이므로 , Apple Silicon 버전을 설치해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Community 버전으로도 많은 것을 할 수 있으니 무료인 Community 버전을 설치해주었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필요에 따라 Professional 버전을 사용해도 되나, Python IDE로만 사용하는 것이라면 Community 버전을 설치해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. miniforge 환경 구축&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-02 오후 11.42.40.png&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;496&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OMf2R/btrDOxUiRdG/E61oB1KrkCpEUpB1P2vqKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OMf2R/btrDOxUiRdG/E61oB1KrkCpEUpB1P2vqKK/img.png&quot; data-alt=&quot;출처 : miniforge(https://github.com/conda-forge/miniforge)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OMf2R/btrDOxUiRdG/E61oB1KrkCpEUpB1P2vqKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOMf2R%2FbtrDOxUiRdG%2FE61oB1KrkCpEUpB1P2vqKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;912&quot; height=&quot;496&quot; data-filename=&quot;스크린샷 2022-06-02 오후 11.42.40.png&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;496&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : miniforge(https://github.com/conda-forge/miniforge)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Windows에서는 Tensorflow를 사용하기 위해, anaconda를 설치해주었지만 맥 OS의 경우에는 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;anaconda 대신에 miniforge라는 환경을 구축해줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Conda-forge에서 파생한 프로젝트인 miniforge에서 유일하게 Conda 패키지를 Apple Silicon의 arm64에 지원하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/conda-forge/miniforge&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;miniforge 파일 다운로드&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 링크에서 Miniforge3-MacOSX-arm64.sh 파일을 다운로드해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치를 해주었다면 아래 코드들을 iTerm에서 실행시켜준다.&lt;/p&gt;
&lt;pre id=&quot;code_1654181056332&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;chmod +x ~/Downloads/Miniforge3-MacOSX-arm64.sh&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1654181068307&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sh ~/Downloads/Miniforge3-MacOSX-arm64.sh&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1654181081461&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;source ~/miniforge3/bin/activate&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치 중간에 y/n를 선택하는 구간이 나오면 y를 입력해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 가상 환경 구축&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상 환경을 구축해주고 Tensorflow를 본격적으로 설치한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상 환경을 구축해주는 이유는, 독립적인 작업 환경을 만들기 위해서이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Tensorflow를 설치하면서, 여러 라이브러리, 패키지들을 설치하게 될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 라이브러리들이 기존의 환경과 충돌하는 경우를 방지하기 위해서 가상 환경을 만들어주는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 패키지 혹은 라이브러리가 특정 버전과 호환하는 경우가 있으므로 이 부분을 맞춰주기 위해서 가상 환경을 만들어준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 Python 3.8 버전과 호환되는 Tensorflow를 설치할 것이기 때문에,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 버전과 호환을 맞추기 위해서 가상 환경을 만들어주는 것이라고도 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;miniforge를 설치하면 Python 3.9 버전으로 설치되므로, Tensorflow와 상응하는 3.8로 맞춰주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654182272095&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda create -n test python=3.8&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드를 작성하여 Python 3.8 버전의 가상 환경을 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;test는 만들어질 가상 환경의 이름이다. 원하는 대로 정해도 상관없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중간에 설치를 계속할 것이냐고 물을 수 있는데, 이때는 y라고 당연히 답하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654182331699&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda activate test&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드를 입력하면 아까 만들어준 test라는 가상 환경으로 전환이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-03 오전 12.07.25.png&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnCsv3/btrDOylp2Is/ZfjGUZDFrytKR4ZeGck1ok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnCsv3/btrDOylp2Is/ZfjGUZDFrytKR4ZeGck1ok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnCsv3/btrDOylp2Is/ZfjGUZDFrytKR4ZeGck1ok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnCsv3%2FbtrDOylp2Is%2FZfjGUZDFrytKR4ZeGck1ok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;537&quot; height=&quot;350&quot; data-filename=&quot;스크린샷 2022-06-03 오전 12.07.25.png&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;miniforge를 통해 anaconda 환경을 만들어주었으면, 앞에 (base) 라고 뜬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금은 base라는 가상 환경에 속해있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-03 오전 12.07.35.png&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TZe6O/btrDRhWNu7m/tjO5BOLByzIfE5rEcUOFy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TZe6O/btrDRhWNu7m/tjO5BOLByzIfE5rEcUOFy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TZe6O/btrDRhWNu7m/tjO5BOLByzIfE5rEcUOFy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTZe6O%2FbtrDRhWNu7m%2FtjO5BOLByzIfE5rEcUOFy1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;537&quot; height=&quot;350&quot; data-filename=&quot;스크린샷 2022-06-03 오전 12.07.35.png&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 conda activate test를 입력해주면 위와 같이 (test)로 가상환경이 바뀐 것을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654182388481&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda env list&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드를 통해, 현재 시스템에 있는 가상 환경들의 목록을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. Tensorflow 설치&lt;/h3&gt;
&lt;pre id=&quot;code_1654182738903&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda install -c apple tensorflow-deps&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1654182752026&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip install tensorflow-macos&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1654182760347&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip install tensorflow-metal&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드를 iterm에 입력해주면, Tensorflow 패키지 설치는 끝이 났다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654182864210&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python -m pip install tensorflow-metal&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하드웨어 가속화를 시키고 싶으면 위 코드를 옵션으로 작성해주어도 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. 설치 최종 확인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 설치해주었던 Pycharm을 통해 Tensorflow가 잘 동작하는지 최종 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5-1. PyCharm에서 새로운 프로젝트를 생성해준다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-03 오전 12.19.23.png&quot; data-origin-width=&quot;212&quot; data-origin-height=&quot;258&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yc1pi/btrDOTW3S3g/Utz9UT5A5wVnRAmV7PJyJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yc1pi/btrDOTW3S3g/Utz9UT5A5wVnRAmV7PJyJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yc1pi/btrDOTW3S3g/Utz9UT5A5wVnRAmV7PJyJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fyc1pi%2FbtrDOTW3S3g%2FUtz9UT5A5wVnRAmV7PJyJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;212&quot; height=&quot;258&quot; data-filename=&quot;스크린샷 2022-06-03 오전 12.19.23.png&quot; data-origin-width=&quot;212&quot; data-origin-height=&quot;258&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5-2. Preferences로 들어간다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-03 오전 12.22.19.png&quot; data-origin-width=&quot;224&quot; data-origin-height=&quot;580&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pgnXA/btrDNUPPyFU/LAhVaKBWwt51GUD4JSRVXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pgnXA/btrDNUPPyFU/LAhVaKBWwt51GUD4JSRVXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pgnXA/btrDNUPPyFU/LAhVaKBWwt51GUD4JSRVXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpgnXA%2FbtrDNUPPyFU%2FLAhVaKBWwt51GUD4JSRVXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;224&quot; height=&quot;580&quot; data-filename=&quot;스크린샷 2022-06-03 오전 12.22.19.png&quot; data-origin-width=&quot;224&quot; data-origin-height=&quot;580&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5-3. Project:프로젝트명 &amp;gt; Python Interpreter로 이동한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-03 오전 12.25.20.png&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;162&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2AL58/btrDPV70Ll0/gMOY3yYkBwsxkwVkkd9W00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2AL58/btrDPV70Ll0/gMOY3yYkBwsxkwVkkd9W00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2AL58/btrDPV70Ll0/gMOY3yYkBwsxkwVkkd9W00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2AL58%2FbtrDPV70Ll0%2FgMOY3yYkBwsxkwVkkd9W00%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;810&quot; height=&quot;162&quot; data-filename=&quot;스크린샷 2022-06-03 오전 12.25.20.png&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;162&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5-4. Interpreter를 추가하기 위해 Add를 클릭해준다. (Add 버튼 누르기 전에 톱니바퀴 버튼이 있다. 그러면 Add 버튼이 나온다)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-03 오전 12.27.15.png&quot; data-origin-width=&quot;190&quot; data-origin-height=&quot;357&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBWFSQ/btrDMAi9HdR/KvRFKATj3EEXlqy5Kl1P7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBWFSQ/btrDMAi9HdR/KvRFKATj3EEXlqy5Kl1P7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBWFSQ/btrDMAi9HdR/KvRFKATj3EEXlqy5Kl1P7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBWFSQ%2FbtrDMAi9HdR%2FKvRFKATj3EEXlqy5Kl1P7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;190&quot; height=&quot;357&quot; data-filename=&quot;스크린샷 2022-06-03 오전 12.27.15.png&quot; data-origin-width=&quot;190&quot; data-origin-height=&quot;357&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5-5. Conda Environment의 Interpreter를 추가해줘야 하므로, Conda Environment를 설정해준다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-03 오전 12.29.47.png&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;675&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwNQLQ/btrDPU86xON/FxKLybwGg9Stu4NY5rRhZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwNQLQ/btrDPU86xON/FxKLybwGg9Stu4NY5rRhZ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwNQLQ/btrDPU86xON/FxKLybwGg9Stu4NY5rRhZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwNQLQ%2FbtrDPU86xON%2FFxKLybwGg9Stu4NY5rRhZ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1102&quot; height=&quot;675&quot; data-filename=&quot;스크린샷 2022-06-03 오전 12.29.47.png&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;675&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5-6. Existing environment를 선택하여 Interpreter를 선택해준다.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 아까 만들어준 가상 환경 내의 Python Interpreter를 지정해줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 가상 환경의 디렉터리 주소에 따라 Python 파일을 찾는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;miniforge 디렉터리 &amp;gt; env 디렉터리 &amp;gt; (아까 만들어준 가상환경 이름의) 가상 환경 디렉터리 &amp;gt; bin &amp;gt; python&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 PyCharm도 설정을 해주었다면, 아래 코드로 Tensorflow가 동작하는지 테스트해보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654183952596&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import tensorflow as tf

with tf.compat.v1.Session() as sess:
  h = tf.constant(&quot;Hello&quot;)
  w = tf.constant(&quot;World!&quot;)
  hw = h + w
  ans = sess.run(hw)
  print(ans)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-06-03 오전 12.37.54.png&quot; data-origin-width=&quot;789&quot; data-origin-height=&quot;87&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ozZJ9/btrDQeM1S05/eNeLpXN3rEMnbagm2FcXck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ozZJ9/btrDQeM1S05/eNeLpXN3rEMnbagm2FcXck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ozZJ9/btrDQeM1S05/eNeLpXN3rEMnbagm2FcXck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FozZJ9%2FbtrDQeM1S05%2FeNeLpXN3rEMnbagm2FcXck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;789&quot; height=&quot;87&quot; data-filename=&quot;스크린샷 2022-06-03 오전 12.37.54.png&quot; data-origin-width=&quot;789&quot; data-origin-height=&quot;87&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; 생각보다 금방 따라할 수 있는 Tensorflow 설치다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맥 GPU를 활용하여 딥러닝을 할 수 있게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;참조&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://velog.io/@uni1023/M1-Mac-conda-miniforge&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;uni1023.log&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://chancoding.tistory.com/85&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;차밍이&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://asterisco.tistory.com/687&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;별님 블로그&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.naver.com/PostView.nhn?blogId=websearch&amp;amp;logNo=221763828445&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;파워 프로그래머&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Deep Learning/etc</category>
      <category>Ai</category>
      <category>Keras</category>
      <category>M1</category>
      <category>Mac</category>
      <category>tensorflow</category>
      <category>tensorflow 설치</category>
      <category>딥러닝</category>
      <category>맥</category>
      <category>텐서플로우</category>
      <category>텐서플로우 설치</category>
      <author>yuhee kim</author>
      <guid isPermaLink="true">https://hapen385.tistory.com/23</guid>
      <comments>https://hapen385.tistory.com/23#entry23comment</comments>
      <pubDate>Fri, 3 Jun 2022 00:42:45 +0900</pubDate>
    </item>
  </channel>
</rss>