<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>_kpk0616.log</title>
        <link>https://velog.io/</link>
        <description>가능한 한 빨리 틀렸음을 증명하려고 노력합니다.그래야만 발전을 찾을 수 있기 때문입니다.</description>
        <lastBuildDate>Wed, 28 Dec 2022 09:21:31 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>_kpk0616.log</title>
            <url>https://velog.velcdn.com/images/_kpk0616/profile/272487ed-af06-411b-be7e-371b581a93a3/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. _kpk0616.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/_kpk0616" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[UIKit /  SwiftUI /  RxSwift 차이점이 뭔데? 🙄]]></title>
            <link>https://velog.io/@_kpk0616/UIKit-SwiftUI-RxSwift-%EC%B0%A8%EC%9D%B4%EC%A0%90%EC%9D%B4-%EB%AD%94%EB%8D%B0</link>
            <guid>https://velog.io/@_kpk0616/UIKit-SwiftUI-RxSwift-%EC%B0%A8%EC%9D%B4%EC%A0%90%EC%9D%B4-%EB%AD%94%EB%8D%B0</guid>
            <pubDate>Wed, 28 Dec 2022 09:21:31 GMT</pubDate>
            <description><![CDATA[<p>여러분 안녕하세요? 아요 개발 새내기 🌱 입니다.
프로젝트를 시작하며.. 프레임워크에 대한 고민이 이 글의 시작점이 되었습니다. </p>
<p>SOPT를 하면서 SwiftUI, RxSwift 등 다양한 프레임워크 스터디가 열렸고 Swift의 &#39;S&#39;도 겨우 알아가기 시작한 저에게는 아직 먼 길이다.. 하는 생각을 했는데요. 이제는 확실히 알아보아야 할 것 같아 겉핥기라도 해 보자! 라는 마음으로 글을 씁니다.</p>
<h1 id="uikit">UIKit</h1>
<details>
<summary>iOS Framework</summary>

<p>개발을 하는 데 있어서, 각 프레임워크의 특징을 알고 프로젝트에 맞게 필요성을 알고 사용하는 것이 중요합니다. iOS 프레임워크와 프레임워크 간의 관계에 대해 알아보겠습니다.</p>
<h1 id="ios-framework">iOS Framework</h1>
<p>iOS 프레임워크는 아래 사진과 같이 구성되어있습니다. 윗단에 있을수록 상위의 프레임워크이고, 아래에 있는 프레임워크를 불러 와 사용할 수 있습니다.</p>
<p><img src="https://velog.velcdn.com/images/_kpk0616/post/8c9e32a5-2454-4d0f-a05a-bd45ac3401c9/image.png" alt=""></p>
<h2 id="cocoa--cocoa-touch">Cocoa / Cocoa Touch</h2>
<p>최상위 프레임워크로, Cocoa라는 단어는 Objective-C Runtime을 기반으로 NSObject를 상속받는 모든 클래스, 모든 객체를 가리킬 때 사용하는 단어입니다.</p>
<ul>
<li>Cocoa : Foundation, AppKit 프레임워크를 포함하고 <strong>macOS를 개발</strong>할 때 사용하는 프레임워크입니다.</li>
<li>Cocoa Touch : 앱의 다양한 기능구현에 필요한 다양한 핵심 프레임워크(UIKit, Foundation, CoreData, CoreAnimation…등)을 포함하며, <strong>iOS개발</strong>에 사용합니다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/_kpk0616/post/39fa6d32-7692-40f5-b35c-56b8e2643970/image.png" alt=""></p>
<ul>
<li>UIKit : 이름 그대로 iOS의 UI를 담당합니다. 이벤트 처리나, 뷰 그리기, 데이터전송, 등 앱을 개발하는데 필수적인 기능들을 가지고있죠.</li>
<li>Foundation : Swift 표준 라이브러리에서 기본적인 타입에 없는 기능을 사용할 수 있습니다. Foundation이 제공하는 클래스의 이름은 NS- 로 시작하며, Sorting, Date, Time, Collection 타입, String 의 일부 기능을 포함합니다.</li>
</ul>
<h2 id="media">Media</h2>
<p><img src="https://velog.velcdn.com/images/_kpk0616/post/5622b15c-7dab-41dd-b7c7-6d6051051b56/image.png" alt=""></p>
<p>그래픽 관련 서비스나 오디오와 비디오 같은 멀티미디어 관련 서비스를 제공합니다.</p>
<h2 id="core-service">Core Service</h2>
<p><img src="https://velog.velcdn.com/images/_kpk0616/post/6cd4ebae-b809-4aa7-8178-f70bcc2f56be/image.png" alt="">
앱의 사용자 인터페이스와는 직접적인 관계가 없으나 앱에 필수적인 기능을 제공합니다. 문자열 처리, 데이터 집합, 네트워크, 주소록, 환경설정 등과 GPS, 가속도 센서 등 디바이스 하드웨어 특성에 기반한 서비스를 제공합니다. XML Parsing, Keychain, Notification Center, StoreKit, Security, GCD 등의 다양한 기능을 제공합니다.</p>
<h2 id="core-os">Core OS</h2>
<p><img src="https://velog.velcdn.com/images/_kpk0616/post/5eab239c-f35e-413e-9dc9-cacb9a26e93b/image.png" alt=""></p>
<p>하드웨어와 네트워크와 관련된 low-level의 서비스를 제공합니다. 커널, 파일 시스템, 네트워크, 보안, 전원관리, 환경설정 등의 기능이 있습니다.</p>
<p>✨ Reference : <a href="https://nsios.tistory.com/82">[Swift] iOS 프레임워크 구조</a>
</br></p>
</details>

<p>이제 본격적으로 UIKit / SwiftUI / RxSwift 간의 특징과 차이점에 대해 알아봅시다.
이를 알기 위해서는 먼저 UIKit 에 대해서 알아보아야 합니다. UIKit은 제가 스위프트를 시작하며 가장 먼저 접한 프레임워크입니다. 아마도 Swift 공부를 처음 시작하신 분이라면 누구나 가장 먼저 접하는 프레임워크일 것입니다.</p>
<p>UIKit, iOS의 UI를 담당하는 친구라는 건 알고 있습니다. 그렇다면 정확히 어떤 기능을 지원하고 있을까요?</p>
<h2 id="uikit의-기능">UIKit의 기능</h2>
<p>일단, <strong>Xcode는 UI를 기반으로 앱을 빌드</strong>합니다. <strong>UI의 요소가 오브젝트(object)로써 기능</strong>하며 <strong>오브젝트들의 인터렉션이나 콘텐츠 요소를 UIKit이 지원</strong>하고 있습니다.</p>
<h2 id="uikit의-필수-요소">UIKit의 필수 요소</h2>
<p>UIKit이 사용된 애플리케이션은 다음 세 가지 요소를 필수적으로 가집니다.</p>
<ul>
<li><span style="color:#F89B00"><strong>애플리케이션 아이콘 (Application Icon)</strong></span>
  말 그대로 앱스토어에서 어플을 다운로드 받을 때 보이는 아이콘을 의미합니다. 홈 스크린, 세팅 화면, 알람(Alert)화면 등 에 표시됩니다. <strong>Assets.xcassets -&gt; AppIcon 을 통해 기기별로 보이는 아이콘의 크기를 설정할 수 있는데, 1x 2x, 3x 와 같이 &#39;포인트&#39; 단위</strong>로 나누어집니다. </li>
</ul>
<ul>
<li><p><span style="color:#F89B00"><strong>Launch screen storyboard</span> (안드로이드에서는 <span style="color:#F89B00">Splash Screen</span>라고 불리운다.)</strong>
이 파일은 프로젝트를 생성하면 LaunchScreen.storyboard 라는 이름으로 자동으로 함께 생성됩니다. 이름 그대로 애플리케이션이 시작될 때 보이는 화면을 말합니다. 보통 스플래시 스크린이라고 하죠, 앱을 시작하면 몇 초간 잠깐 보이는 화면입니다.
앱의 라이프사이클을 다루는 AppDelegate 에서 아래 코드에 sleep() 메서드를 작성해주면 런치스크린 화면을 초 단위로 표시할 수 있습니다. sleep(1) 을 작성하면 1초 동안 런치 스크린을 표시한 후 매인 뷰 컨트롤러를 시행한다고 이해하시면 됩니다.</p>
<pre><code class="language-swift">  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -&gt; Bool {
          // Override point for customization after application launch.
          sleep(1)
          return true
      }</code></pre>
</br>



</li>
</ul>
<ul>
<li><span style="color:#F89B00"><strong>필수 앱 메타 데이터(Meta Data)</strong></span>
  <strong>앱 개발에서 메타 데이터는 &#39;시스템에 대한 정보를 담은 데이터&#39;</strong> 라고 생각하면 됩니다. 애플리케이션에 <strong>Info.plist</strong>가 같이 번들되어(합쳐져서) 본 파일에 적힌 정보를 가져와 출력하게 됩니다. 메타 데이터는 앱이 특정한 하드웨어를 사용할때 허락을 구하거나 특정 상황에서 어떤 메시지를 보낼 지에 대한 부분을 담당합니다. 민감한 정보를 다루어야 할 때에도 사용될 수 있습니다. 예를 들어 카메라 디바이스, 위치 정보, 알람 기능을 사용하는데에는 개인정보가 들어가며 하드웨어를 사용하게 되는데 <strong>어떤 기능에서 &#39;허락&#39;을 구하는 행위는 선택이 아니라 필수적으로 작용</strong>합니다. 메타 데이터 섹션은, 잘 되어 있지 않으면 앱 배포를 제한할 정도로 애플이 강조하는 부분이기도 합니다.</li>
</ul>
<h2 id="uikit-코드-구조">UIKit 코드 구조</h2>
<p><img src="https://velog.velcdn.com/images/_kpk0616/post/a6fb2edc-71a7-41d3-b6d9-2e1758993a0d/image.png" alt=""></p>
<p><strong>UIKit은 앱의 메인 이벤트 루프(Main Event Loop)를 실행하고 화면에 콘텐츠를 표시하며 여러 오브젝트를 제공합니다.</strong> 그렇기에 앱의 구조가 어떻게 동작하는지 알아야 재사용 가능하고 지속가능한 코드를 짤 수 있습니다. <strong>UIKit 앱의 구조는 <span style="color:#F89B00">MVC(Model- View - Controller) 디자인 패턴을 기반</strong></span>으로 합니다.</p>
<ul>
<li>Model : 앱의 오브젝트 데이터들을 관리한다. (동작)</li>
<li>View : 데이터들의 시각적인 표현을 제공한다. (표현)</li>
<li>Controller : Model과 View 사이에서 적절한 시간에 데이터를 이동시키며 상호작용을 돕는다.</li>
</ul>
<p>우리가 아는 대표적인 컨트롤러는 <strong>ViewController</strong> 입니다. 요즘은 MVVM (Model - View - ViewModel) 디자인 패턴을 더 많이 사용하는데, MVVM이 등장하기 전에는 MVC가 대표적인 디자인패턴이었습니다.</p>
<h1 id="swiftui">SwiftUI</h1>
<p>SwiftUI는 애플에서 2019년 6월에 있었던 WWDC 2019에서 발표한 프레임워크입니다. </p>
<p>애플이 SwiftUI를 발표하며 내 건 슬로건은 아래와 같습니다.</p>
<p>*&quot;The Shortest Path to a Great App&quot;
&quot;Less code, Better code, EveryWhere&quot;*</p>
<p>말 그대로, 짧고 쉽게 더 좋은 앱을 만들기 위한 프레임워크임을 의미합니다.</p>
<h2 id="swiftui-특징">SwiftUI 특징</h2>
<p>SwiftUI는 UIKit을 기반으로 동작합니다.</p>
<p>AutoLayout은 CSS에서 사용되는 Flexible Box layout이 적용되고 HStack, VStack, ZStack 같은 개념이 적용되어 레이아웃이 한결 모던해졌으며 React Native에서도 사용되고 있는 Flexible Box Layout은 상당히 다루기 편하고 직관적이라고 합니다.</p>
<p>한 포스팅에서는 지금 시점에서 UIKit을 배우면서 SwiftUI를 필수로 배워야한다고 합니다. SwiftUI의 특징을 자세히 알아보며, 얼마나 강력한 장점이 있는지 알아보도록 합시다.</p>
<ul>
<li><p><span style="color:#F89B00"><strong>적은 코드, 더 좋은 앱</strong></span>
  UIKit 보다 더 적은 코드를 사용할 수 있는 이유는 SwiftUI가 <strong>레이아웃, 뷰 갱신, 접근성, 글자크기 조정 등 UIKit에서 일일이 설정해주었던 부분을 직접 지정하지 않고 지원</strong>해주기 때문입니다.</p>
<p>  즉, UIKit을 이용해 직접 레이아웃을 잡기 위해 사용했던 리소스를 다른 기능에 투자할 수 있게 된 것입니다.</p>
</li>
</ul>
<ul>
<li><p><span style="color:#F89B00"><strong>선언형 프로그래밍 방식 사용</strong></span>
해당 프레임워크에서는 기본적으로 코드들이 가지는 명령형이 아닌 선언형 프로그래밍 방식을 사용하고 있습니다. UIKit에서 사용하는 명령형 프로그래밍 방식은 다음과 같습니다. 버튼을 생성하고, 명령을 통해 속성을 지정하고, 버튼 하나에 대한 속성을 명령어로 각각 지정해주어야합니다.</p>
<pre><code class="language-swift">  // 버튼 선언
  let button = UIButton(type: .system)

  // 속성 지정
  button.setTitle(&quot;Hello SwiftUI&quot;, for: .normal)
  button.setTitleColor(.red, for: .normal)
  button.titleLabel?.font = .preferredFont(forTextStyle: .largeTitle)
  button.addTarget(self, action: #selector(setButtonEvent(_:)), for: .touchUpInside)

  // 버튼 추가
  self.view.addSubview(button)

  // 레이아웃
  button.translatesAutoresizingMaskIntoConstraints = false

  NSLayoutConstraint.activate([
          button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
          button.centerYAnchor.constraint(equalTo: view.centerYAnchor)
  ])

  // 이벤트 함수
  ...
  @objc func setButtonEvent(_ sender: UIButton) {
      print(&quot;is make swift code&quot;)
  }</code></pre>
 </br>
반면 선언형 프로그래밍 방식을 사용할 경우, 다음과 같이 코드 길이가 확연히 줄어드는 것을 볼 수 있습니다.

<pre><code class="language-swift">  struct ContentView: View {
      var body: some View {
          Button(action: {
              print(&quot;is make swiftUI code&quot;)
          }) {
              Text(&quot;Hello SwiftUI&quot;)
                  .font(.largeTitle)
                  .foregroundColor(.red)
          }
      }
  }</code></pre>
<p>간단하게 해석하면 폰트는 largeTitle로 해주고 글자 색깔은 빨간색으로 만들어 주고 Hello SwiftUI라는 text를 가질 거야, 그리고 버튼을 클릭하면 is make swiftUI code라는 코드를 콘솔 창으로 만들어줘 라는 것입니다. 참고로, 위에서 <code>.font</code>, <code>.foregroundColor</code> 와 같은 것들은 또 다른 뷰를 반환하기 때문에 메서드 대신 <strong>수식어</strong>라고 표현합니다. 뷰를 변경하는 게 아닌 새로운 타입의 뷰를 반환하기 때문에 많은 객체들이 Struct로 되어 있다고 합니다.</p>
<p> 이처럼 선언형은 내가 무엇을 원하는지 UI구성을 전달함으로써 SwiftUI가 알아서 처리하도록 맡길 수 있습니다.</p>
</li>
<li><p><span style="color:#F89B00"><strong>Preview</strong></span>
SwiftUI를 이용하면 시뮬레이터를 돌려서 결과를 보는 게 아니라 캔버스 영역의 프리뷰를 통해 수정한 결과를 바로바로 확인할 수 있다고 합니다. 프리뷰 사용법은 참고 링크를 첨부해놓았으니 나중에 알아보도록 하고,,</p>
<details>
<summary>Preview 사용 방법</summary>
<div markdown="1">

<p>✨ <a href="https://ios-development.tistory.com/488">[iOS - swift] UIKit에서 SwiftUI의 Preview 사용 방법</a></p>
</li>
</ul>
</div>
</details>


<ul>
<li><span style="color:#F89B00"><strong>Apple 모든 플랫폼 지원</strong></span>
애플워치를 개발하기 위해서는 WatchKit, macOS는 AppKit 프레임워크를 사용해야 합니다. 하지만 SwiftUI를 이용하면 애플 플랫폼에 해당하는 모든 기기 앱을 개발할 수 있습니다. 단, 코드 재활용이 편해졌음을 의미하는 것으로 플랫폼에 맞는 최적화는 필요합니다.</li>
</ul>
<h2 id="swiftui-4가지-원칙">SwiftUI 4가지 원칙</h2>
<ol>
<li><p><span style="color:#F89B00"><strong>선언형</strong></span></p>
<p> 위에서 설명드렸다시피 SwiftUI는 선언형 프로그래밍 방식으로 동작합니다.</p>
</li>
<li><p><span style="color:#F89B00"><strong>자동화</strong></span></p>
<p> 프레임워크가 자동으로 해결해주는 부분으로, 명령형과 달리 일일이 설정해 줄 필요가 없습니다. 레이아웃과 애니메이션 효과 기능 등이 매우 단순해졌다는 장점이 있습니다.</p>
</li>
<li><p><span style="color:#F89B00"><strong>조합</strong></span></p>
<p> <strong>큰 뷰를 하나의 기능을 가진 작은 뷰들로 자르거나 각각의 뷰를 조합해서 원하는 뷰를 쉽게 만들 수 있도록 지원</strong>합니다.</p>
</li>
<li><p><span style="color:#F89B00"><strong>데이터 업데이트, 최신화</strong></span></p>
<p> UIKit에서는 데이터가 변경되면 UI에도 따로 적용을 해 주어야 했습니다. 그만큼 더 많은 코드 작성을 필요로 하고 에러와 버그 위험성이 존재했습니다. 하지만 SwiftUI는 데이터가 변경되는 즉시 UI에도 자동으로 갱신해주는 것을 보장합니다. 단, 뷰의 특정한 상태를 저장할 State나 모델 객체의 변화를 관찰하는 ObservableObject 같은 데이터의 변화를 반영해 뷰에 반영해줍니다.</p>
</li>
</ol>
<h1 id="rxswift">RxSwift</h1>
<p>대망의 세 번째 프레임워크, RxSwift에 대해 알아봅시다! RxSwift,, 비동기 프로그래밍을 지원한다,, 정말 많이 들었는데 대체 비동기 프로그래밍이 뭐야? 왜 그렇게 편리한데? 하는 궁금증을 정말 많이 갖고 있었습니다.</p>
<h2 id="비동기-프로그래밍">비동기 프로그래밍</h2>
<details>
<summary>비동기 프로그래밍이란?</summary>
<div markdown="1">

<p> 아래 영상을 보시면 쉽게 이해할 수 있습니다!
 ✨ <a href="https://www.yalco.kr/21_async/">비동기 프로그래밍이 뭔가요?</a></p>
</div>
</details>


<ul>
<li>동기적(Synchronous) 프로그래밍 : 코드가 반드시 작성된 순서 그대로 실행된다.</li>
<li><span style="color:#F89B00"><strong>비동기적(Asynchronous) 프로그래밍</strong></span> : 작성된 순서대로 동작하지 않는다. <strong>쓰레드가 프로세스가 여럿 돌 수 있는 멀티태스킹이 가능함</strong>을 의미한다.</li>
</ul>
<p>RxJava, RxKotlin 등 다른 언어에도 Rx 라이브러리가 존재합니다. Rx의 풀네임은 ReactiveX인데, 리액티브 프로그래밍, 즉 <span style="color:#F89B00"><strong>반응형 프로그래밍</strong></span>을 의미합니다. Rx 라이브러리는 비동기와 데이터 동기화의 중요성이 늘어나면서 비동기 프로그래밍이 중요해지면서 등장하게 되었습니다.</p>
<p>비동기 실행을 통해 <span style="color:#F89B00"><strong>앱의 속도를 향상시키고 정보를 가져오는 속도가 빨라지며 안정성 또한 증가하는 장점</strong></span>을 가지기 때문입니다. RxSwift는 Swift의 비동기 프로그래밍을 지원하는 라이브러리이며, 이 라이브러리가 없으면 비동기 실행에 관한 정확한 예측이 힘들어집니다. </p>
<p>자, 여러분!! 이제 UIKit / SwiftUI / RxSwift 의 차이점에 대해 이해가 가셨나요?
부디 조금이라도 도움이 되셨기를 바라며,, 이만 글을 마치겠습니다,, 안뇽~! 🙌</p>
<details>
<summary>✨ Reference</summary>
<div markdown="1">

<ul>
<li><a href="https://velog.io/@leoyang/iOS-%EA%B0%9C%EB%B0%9C-%EC%95%A0%ED%94%8C-%EC%95%B1%EC%9D%98-%ED%95%B5%EC%8B%AC-UIKit-%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C">[iOS 개발] 애플 앱의 핵심? UIKit 는 무엇일까!</a></li>
<li><a href="https://boidevelop.tistory.com/115">[SwiftUI] SwiftUI란? UIKit와의 차이란? 대체 얼마나 좋길래 개발자분들 모두 칭찬을 하는거지?</a></li>
</ul>
</div>
</details>]]></description>
        </item>
        <item>
            <title><![CDATA[[ENG] 12 Rules to Learn to Code (7)]]></title>
            <link>https://velog.io/@_kpk0616/ENG-12-Rules-to-Learn-to-Code-7</link>
            <guid>https://velog.io/@_kpk0616/ENG-12-Rules-to-Learn-to-Code-7</guid>
            <pubDate>Tue, 20 Sep 2022 07:57:39 GMT</pubDate>
            <description><![CDATA[<h1 id="책임감을-가져라">책임감을 가져라</h1>
<blockquote>
<p><strong>12 Rules to Learn to Code</strong>
by Angela Yu</p>
</blockquote>
<p>누군가에게 책임감을 지녀라. 당신의 작품을 보여주어라.</p>
<p>온라인 코딩 코스의 가장 큰 문제점은 책임감의 결여이다. Coursera, Udacity, Udemy, Skillshare 와 같은 크고 오픈된 온라인 코스 (Massive Open Online Courses, 약자로 MOOCs) 의 여정은 결코 의심할 여지가 없이 훌륭하다. 그러나 당신이 숙제를 하지 않거나 한 달간 강의에 결석하는 이유는 무엇인가? 아무것도, 아무도 신경쓰지 않는다는 것이다.</p>
<p>문제에 직면하라. 우리 중 누구도 내적 동기는 강하지 않다. 우리는 항상 &quot;Netflix 보면서 놀고 먹기&quot; 에 유혹되는 이유를 찾을 수 있다. 내가 회원가입하고 나중에는 한 강의도 듣지 않거나 코스의 단 한 부분만 끝낸 강의가 셀 수 없을 만큼 얼마나 많은지 모른다. </p>
<p>당신은 배움에 대한 책임감과 약속이 필요하다. 대학에 다니던 시절을 생각해보라. 아무것도 달려 있지 않았다면 새벽 3시까지 고통받으며 에세이를 끝내기 위해 노력했을까? 낙제에 신경쓰지 않았다면 과연 강의를 들으러 갔을 것인가?</p>
<p>이게 우리가 강좌에 대한 책임감을 언급한 이유이다. 우리는 학생들을 버디와 함께 매칭시켜 주는 것이 도움이 된다는 것을 깨달았다. 당신과 비슷한 레벨에 있는, 어떤 때는 당신을 도와주고 다른 때에는 당신이 도움을 주는, 초보자를 말이다. 때때로 사람들의 학습 속도가 갈라지거나 당신이 게으름 버거를 한 입 베어물게 된다면 당신은 원래 버디를 바꾸고 새로운 버디를 찾을 수도 있다. 이 시스템은 전체적으로 자발적인 시스템이기 때문에, 팀워크가 좋은 사람에 대한 자기 만족도가 있고 다른 사람들에 의해 동기부여받을 수 있다. 파트너가 있으면 헬스장에 더 자주 갈 수 있는 것과 같이, 코딩 버디가 있으면 더 자주 공부할 수 있다.</p>
<p>당신이 우리 코스를 수강하고 있지 않다면 당신 스스로 찾으면 된다. 코딩을 배우는 사람들을 위해 존재하는 수많은 페이스북 그룹들이 있다. 이를 위한 전체 하위 레딧(r/learnprogramming) 들이 있다. 난 당신이 온라인이든 오프라인이든 마음에 드는 사람들을 찾을 수 있을 것이라 확신한다.</p>
<p>다음으로 말할 것은 논란거리가 될 것이다. 우리는 사람들이 가치없는 것은 소중히 여기지 않는다고 믿는다. Coursera 가 무료 강좌를 다수 철거하는 것이 그 이유이다. Coursera 는 수만명의 사람들이 회원가입하고 아무도 어떠한 강좌도 프로젝트를 완수하지 않는 것을 알았다. 무료 강좌를 제공하는 것은 사실 학생들의 학습에 해로웠다. 우리는 모두 어느정도 사재기하는 경향이 있고, 당신이 고통받을 수도 있는 미래의 해야 할 수많은 일들을 위해 회원가입하는 것은 매우 쉬운 일이다. 항상 내일은 존재한다고들 말한다.</p>
<p>만약 내부보다 외부 동기에 의해 이끌린다면 당신의 학습을 이끌기 위해 약간의 재정적인 동기를 이용하도록 시도해보아라. 삶의 기술이 당신에게 얼마나 가치있는지 생각해보고 당신의 의도가 있는 곳에 돈을 투자해라. 재정적 부담 여부에 관계 없이 과정의 콘텐츠에 참여하고 있는지를 확인하라. 규칙적인 학습 습관을 위해 당신을 동기부여하기에 충분한 것에 투자할 수 있는 곳은 많다. 이 법칙의 최종적인 부분은 평가 받는 방법을 찾기 위해 노력하는 것이다. 사람들이 얼마나 즐기는지에 관해서라면 죽음과 세금 바로 위에 평가 받는 것이 있다. (그만큼 싫어한다는 말씀이지~) 그러나 무엇이든 배울 때에는, 피드백을 받는 것이 항상 중요하다. 당신은 임포스터가 된 것 같은 기분을 느끼거나 거짓된 자신감으로 넘쳐 흐르는 것 대신, 현재의 기술 레벨에 대한 객관적인 평가를 받을 것이다. Coursera 는 학생들이 각자 서로의 작업물에 마크할 수 있는 시스템을 가지고 있다. App Brewery 에서 우리는 당신의 코드에 있는 버그와 문제를 살펴보고 테스트할 수 있는 Github 교육을 활용한다. 그러나 당신이 이런 시스템을 가지지 않은 코딩 교육 과정을 이수 중이라면, 피드백을 주고 코드를 리뷰할 수 있는 코드 멘토를 찾는 것이 도움이 될 것이다. 오직 측정된 것만이 개선될 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ENG] 12 Rules to Learn to Code (6)]]></title>
            <link>https://velog.io/@_kpk0616/ENG-12-Rules-to-Learn-to-Code-6</link>
            <guid>https://velog.io/@_kpk0616/ENG-12-Rules-to-Learn-to-Code-6</guid>
            <pubDate>Sat, 17 Sep 2022 07:36:34 GMT</pubDate>
            <description><![CDATA[<h1 id="카피캣이-되어라">카피캣이 되어라</h1>
<blockquote>
<p><strong>12 Rules to Learn to Code</strong>
by Angela Yu</p>
</blockquote>
<p>내 코딩 여정의 시작에서 나는 코딩을 배우는 방법은 수많은 책을 읽는 것뿐이라고 생각했다. 나는 C++, C#, Java, 그보다 더 많은 책들을 샀다. 당신이 무얼 말하든 가지고 있었다. 그러나 그 책들은 나를 더 혼란스럽게 만드는 것에 그칠 뿐이었다.</p>
<p>읽고, 줄 치고, 잊어버리고, 잠들고.</p>
<p>책들은 레퍼런스로써는 아주 좋다. 당신이 딜리게이트와 프로토콜을 깊이 알기를 원한다면 그에 해당하는 챕터를 읽으면 된다. 그러나 배우기를 원한다면, 무언가를 만들어야 한다.</p>
<p>그런데 무얼 만들어야할까?</p>
<p>아이디어가 부족한가? 그렇다면 카피캣이 되어라. 자신만의 노트패드, MSPaint, 피아노를 만들어라. 게임에 관심이 있다면 minesweeper, Tetris, Flappy Bird 를 만들어라. 도움이 될 뿐만 아니라, 당신이 어떻게 해야하는지를 알아내고 도움을 찾는 경험을 할 수 있는 완벽한 기회가 될 것이다. 홀로그래픽 스마트폰 투영법과 같은 새로운 것을 만들기 위해서는, 아무도 당신을 도울 수 없을 것이다. 카피캣 앱이나 프로그램을 만들면서 당신 이전에 많은 사람들이 걸었던 길을 따라 걷게 될 것이다. 이 방법은 누군가 당신이 막힐 때 조언해주고, 당신에게 도움을 줄 수 있는 기회를 극대화시키는 방법이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ENG] 12 Rules to Learn to Code (4)]]></title>
            <link>https://velog.io/@_kpk0616/ENG-12-Rules-to-Learn-to-Code-4</link>
            <guid>https://velog.io/@_kpk0616/ENG-12-Rules-to-Learn-to-Code-4</guid>
            <pubDate>Thu, 15 Sep 2022 07:47:17 GMT</pubDate>
            <description><![CDATA[<h1 id="무엇을-쓰고-있는지-이해하라">무엇을 쓰고 있는지 이해하라.</h1>
<blockquote>
<p><strong>12 Rules to Learn to Code</strong>
by Angela Yu</p>
</blockquote>
<p>나는 대부분의 프로그래밍 튜토리얼들이 쓰여진 방법이 가진 문제점을 알고 있다.
아래의 &quot;이것이 당신이 올빼미를 그릴 수 있는 방법입니다.&quot; 와 같은 튜토리얼들이 너무나 많다.</p>
<p><img src="https://velog.velcdn.com/images/_kpk0616/post/41e39708-9ce4-48c6-98c3-2944a0bd4c6b/image.png" alt=""></p>
<p>마치 프로그래머가 좋은 의도를 가지고 당신이 어떻게 모든 것을 해야 하는지 단계적으로 보여주는 것과 같다. 그러나 어느 시점에 그는 완수할 수 없는 임무에 승선한 것을 깨닫고 포기한다. 나는 저자가 고통스러울만큼 어려운 단계의 디테일을 시작으로, 중간에 &quot;이제 클라우드 데이터베이스를 설정하기만 하면 됩니다.&quot;며 되돌아가는 튜토리얼을 본 적이 있다. 초보자를 위한 튜토리얼이니 참고해라!</p>
<p>이건 여러 문제들을 야기한다. 가장 흔한 문제는 학생이 튜토리얼의 코드를 그대로 베끼고 그 코드가 무엇을 하는지 어떠한 것도 알지 못한다는 것이다. JSON 을 파싱한 후 왜 추가 행을 덧붙이는가? 왜 이 딕셔너리를 이전에 만든 것과 다르게 만들고 있는가?</p>
<p>이런 유형의 튜토리얼은 &quot;Flappy Bird&quot; 나 &quot;Candy Crush&quot; 를 어떻게 만드는지 가르쳐준다고 약속하기 때문에, 이런 유형의 튜토리얼에 무릎을 꿇는 것은 굉장히 쉽다. 그러나 이와 같은 방법의 3분의 2에서는 여러분이 입력하는 코드는 말이 되지 않고 당신은 화면에 나타난 빨간 줄들만을 바라보기 시작할 것이다. 버그, 그것도 많은 양의 버그 말이다. 왜 이런 것일까? 전혀 모르고, 아무것도 동작하지 않는다. 마지막 남은 3시간은 코드를 복사하는 데 쓰이고 당신은 코딩이 짜증난다는 것 말고는 아무것도 배우지 못한다.</p>
<p>이런 함정에 빠지지 말라. 당신이 단 세 줄만으로 초보자에서 숙련자로 건너뛰고, &quot;간단히&quot; 라는 단어를 너무 자유롭게 남용하거나 코드에 대해 아무런 설명도 해 주지 않는 튜토리얼을 보게 된다면, 당장 멈추고 그 튜토리얼을 떠나라.</p>
<p>바다에는 수많은 물고기가 있다.</p>
<p>때때로, 저자는 그들이 뭘 하고 있는지 설명하기 위해 노력할 것이다. 그러나 당신이 여전히 그들이 하는 말을 알아듣지 못한다면 당신은 프로그래밍 실력을 올려주지 못할 숙련된 튜토리얼을 보고 있는 것이다. 무언가 대단한 것을 만들고 싶은 유혹이 들 수 있다. 특히 블로그가 누구나 할 수 있는 일이라고 약속할 때 말이다. 그러나 당신이 무슨 일이 일어나는지 알지 못한다면, 더 나은 기반을 구축함으로써 더 나은 도움을 받을 수도 있는 것이다.</p>
<p><img src="https://velog.velcdn.com/images/_kpk0616/post/7c134441-6edc-4550-a437-9eb1523fa666/image.png" alt=""></p>
<p>코딩을 배우는 데 있어서 핵심은 램핑(경사로)에 관한 것이다. 당신은 계속해서 뻗어나가고, 지식이 이전의 지식 위에 구축되기를 원한다. <strong>경사가 너무 가파르다면, 당신은 실패할 것이다. 경사가 너무 완만하다면, 지루함을 느낄 것이다. 알맞는 경사도는 사람마다 다르다.</strong> 이게 우리가 학생들이 우리의 튜토리얼에 자유롭게 속도 변경 기능을 사용하도록 권장하는 이유이다. 이 방법으로 당신은 개념에 친숙하다면 2배 빠르게, 개념에 낯설고 이해하고 흡수할 시간이 필요하다면 절반 느린 속도로 들을 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ENG] 12 Rules to Learn to Code (5)]]></title>
            <link>https://velog.io/@_kpk0616/ENG-12-Rules-to-Learn-to-Code-5</link>
            <guid>https://velog.io/@_kpk0616/ENG-12-Rules-to-Learn-to-Code-5</guid>
            <pubDate>Wed, 14 Sep 2022 17:51:06 GMT</pubDate>
            <description><![CDATA[<h1 id="몰라도-괜찮다">몰라도 괜찮다</h1>
<blockquote>
<p><strong>12 Rules to Learn to Code</strong>
by Dr. Angela Yu</p>
</blockquote>
<p>소프트웨어 엔지니어는 임포스터 증후군 환자가 많은 직업군으로 알려져 있다. <strong>임포스터 신드롬은 자신의 기술과 능력을 지나치게 과소평가하고, 스스로를 사기꾼처럼 느끼는 심리적 현상이다.</strong>
<img src="https://velog.velcdn.com/images/_kpk0616/post/c7c7ef5f-6d7f-44b2-892e-42d32e3533f1/image.png" alt=""></p>
<p>프로그래머들은 자기비난적이고, 자신을 제외한 모두가 자기보다 프로그래밍을 잘 한다고 끊임없이 생각하는 경향이 있다. 만약 당신이 이런 느낌을 겪은 적이 있다면, 연구들이 70퍼센트의 사람이 임포스터 증후군을 겪는다고 보여주는 것처럼 이 문제는 당신 혼자 겪는 것이 아니다.</p>
<p>나는 최근 Quora 사이트에 누군가가 올린 Q&amp;A 게시글을 본 적이 있다. : &quot;StackOverflow 를 참조해서 사용하다가 적발되면 Google(또는 다른 큰 테크 회사) 에서 해고될까요?&quot;</p>
<p>그는 구글, 아마존, 다른 주요 테크 회사에서 일하는 엔지니어들로부터 많은 양의 답변을 받았다. 소프트웨어 엔지니어로 일하는 누구나 당신에게 레퍼런스를 보지 않는 것이 훨씬 더 눈살을 찌푸리게 할 것이라고 말할 것이다. 실제로 당신에게 Stack Overflow 를 사용하지 않는 구글 프로그래머가 있는지 찾아보라고 하고 싶다. (Stack Overflow 는 프로그래머들을 위한 공유 Q&amp;A 사이트이다.)</p>
<p>수많은 신입 프로그래머들이 레퍼런스를 확인하고 사람들에게 질문함으로써 스스로를 프로그래밍 할 줄 모르는 사기꾼이라고 밝히게 될까봐 두려워한다. 그 누구도 머릿속에 모든 관련 정보를 기억할 수 있는 사람은 없다. 예를 들어, iOS 메소드의 이름은 이렇다. 
: <code>- (id)initWithBitmapDataPlanes:(​unsigned​ ​char​ **)planes pixelsWide:(​NSInteger​)width pixelsHigh:(​NSInteger​)height bitsPerSample:(​NSInteger​)bps samplesPerPixel:(​NSInteger​)spp hasAlpha:(BOOL)alpha isPlanar:(BOOL)isPlanar colorSpaceName:(​NSString​ *)colorSpaceName bitmapFormat:(​NSBitmapFormat​)bitmapFormat bytesPerRow:(​NSInteger​)rowBytes bitsPerPixel:(​NSInteger​)pixelBits;</code></p>
<p>거의 400 글자이다!</p>
<p>iOS 프로그래밍에는 800개 이상의 클래스들과 9000 개의 메소드들이 있고, 더욱 더 늘어나고 있다. 웹 개발에는 매주 새로운 프레임워크가 나온다. 아무도 당신이 코드를 기억할 수 있다고 기대하지 않는다. 컴퓨터가 우리를 위해 지루한 일들을 수행하도록 하는 게 우리가 프로그래머인 정확한 이유이다. 예를 들어 소리를 녹음하는 코드를 짧은 검색으로 찾아낼 수 있는데, 왜 굳이 기억할 필요가 있겠는가? 대부분의 고용자들이 채용을 할 때 찾는 기술은 생각하는 능력이다. 정보를 얻기 어려운 세상에서는 지식이 가치있다. 1800년대에는 오로지 부유한 사람만이 좋은 책과 좋은 강사를 접할 수 있었다. 지금은 모두가 마우스 탭 한 번으로 그들이 가지고 있던 모든 정보와 더 많은 정보들을 얻을 수 있다. 정보는 가치를 잃어가고 있으며, <strong>생각하는 능력은 매수해야하는 주식과 다름 없다</strong>. 그러니 <strong>검색하는 것, StackOverflow 에 질문하는 것, 당신의 이슈를 해결하는 데 도움이 되는 자료들을 찾는 것을 두려워하지 말라.</strong> 최고의 프로그래머들 또한 그렇게 한다.</p>
<p>당신이 연마해야 할 기술은 <strong>좋은 질문을 하고 답변을 이해하는 것</strong>이다. 당신이 코드가 어떻게 동작하는지 단서를 찾지 못한다면 StackOverflow 답변에서 코드를 복사해 붙여넣는 것은 도움이 되지 않는다. StackOverflow 는 평판 시스템을 기반으로 동작하기 때문에, 찬성표를 모으고 올바른 답변으로 표시하기 위해 답변에 가능한 한 명확하게 하는 것이 중요하다. </p>
<p>대부분의 경우 막힐 때마다 StackOverflow 에 검색하는 것은 의미가 없다. 첫 번째 옵션은 항상 스스로 알아내려고 노력해야한다는 것이다. 그래서 당신의 프로그램이 기대하는 대로 동작하지 않지만, 마지막 코드 세 줄을 쓰기 전에 잘 동작하고 있었다면, 마지막 3줄 중 앱을 망가뜨린 코드는 무엇인지 찾아보면 된다.</p>
<p>정말 못 찾겠다면 구글링을 하기 시작하면 된다. 질문을 검색하거나, 버그가 났다면 에러 코드나 에러 메세지를 붙여 넣어라. 초보자일수록 당신의 프로그래밍 문제는 매우 흔할 것이며 누군가 당신이 겪은 버그를 해결하기 위한 명확하고 간결한 튜토리얼을 작성하는 데 시간을 들였을 것이다. 숙련된 프로그래머로 성장할수록 당신이 맞닥뜨릴 문제는 점점 더 모호해질 것이다. 그러나 희망적으로, 당신이 다른 열한가지 법칙을 따랐다면 유능한 프로그래머가 될 것이고 스스로 해결책을 찾아내거나 도움을 요청할 곳을 정확히 알게 될 것이다. </p>
<p>당신이 구글링을 해야 하는 또 다른 이유는 StackOverflow 의 검색 알고리즘이 질문과 정답을 인기순이 아니라 최신순으로 정렬하기 때문이다. 당신이 시작하는 동안 맞닥뜨릴 수많은 문제는 몇 년 전 질문되고 답변되었지만 여전히 인기가 많을 것이다.</p>
<p>그래서 지혜롭게 질문하면 커뮤니티로부터 이익을 거둘 것이다. 언젠가 스스로 코드 마스터가 되었다고 느끼게 되면, 같은 커뮤니티에 받은 도움을 되돌려주고 다음 세대의 프로그래머들을 도울 것이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ENG] 12 Rules to Learn to Code (3)]]></title>
            <link>https://velog.io/@_kpk0616/ENG-12-Rules-to-Learn-to-Code-3</link>
            <guid>https://velog.io/@_kpk0616/ENG-12-Rules-to-Learn-to-Code-3</guid>
            <pubDate>Tue, 13 Sep 2022 14:14:21 GMT</pubDate>
            <description><![CDATA[<h1 id="배우기에-완벽한-언어는-없다">&quot;배우기에 완벽한 언어&quot;는 없다</h1>
<blockquote>
<p><strong>12 Rules to Learn to Code</strong>
by Dr. Angela Yu</p>
</blockquote>
<p>내가 연설을 할 때마다, &quot;처음 공부를 시작할 때 배워야 할 프로그래밍 언어는 무엇인가요?&quot;라고 묻는 사람이 항상 있었다. 초보 프로그래머를 위한 완벽한 언어가 어딘가 있을 거라는 일반적인 인식이 있다. 어떤 이는 파이썬을, 어떤 이는 스위프트를 처음 배워야 할 언어라고 주장한다.</p>
<p>하지만 그 말은 모두 잘못됐다.</p>
<p>프로그래밍 언어는 단순히 도구에 불과할 뿐이다. 당신의 하드웨어 박스 안에 있는 다른 도구들과 다를 바가 전혀 없다. 당신이 못을 박기를 원한다면 망치를 사용해야 한다. 수도관을 고치기를 원한다면 스패너를 사용해야 한다. 스패너의 옆면을 이용해 못을 박을 수도 있는데, 이건 마치 같은 프로그래밍 언어로 다른 유형의 문제를 푸는 것과도 마찬가지이다. 목수는 자신이 가장 좋아하는 도구가 망치라고 할 것이고, 배관공은 스패너라고 할 것이다. 하지만 여전히 그것이 &quot;무언가를 고치기 위한 최고의 도구&quot;가 되지는 않는다.</p>
<p>웹 개발자는 JavaScript 가 초보자가 배우기에 가장 좋은 언어라고 할 것이고, 통계학자는 R 프로그래밍 언어가 가장  좋을 것이라 조언할 것이다. 하지만 결국에는 모든 문제는 당신의 도구로 당신이 풀기 위해 노력해야 하는 것이다. 당신이 iOS 앱을 만들기를 원한다면, 스위프트를 배우면 된다. 웹사이트를 만들고 싶다면, JavaScript 를 배우면 된다. 좋은 소식은 핵심적인 프로그래밍 개념이 있다는 것이다 : 반복문, 조건문, 함수, 등은 어느 언어에서나 같다. 다른 점은 문법적인 요소일 뿐이다. 영어로는 werewolves, 독일어로는 Werwölfe 라고 하듯이 말이다. 이 단어가 보름달이 뜰 동안만 나타나는 셔츠를 찢는 포유류를 뜻하는 것은 같다. 단지 쓰는 법이 다를 뿐이다.</p>
<p>Swift 에서 콘솔에 프린트할 때에는 <code>print(&quot;Hello Werewolves”)</code> ,
Java 에서 콘솔에 프린트할 때에는 <code>println(“Hello Werwölfe”)</code> 라고 쓰듯이.</p>
<p>그러니까 성취하고 싶은 작업을 결정한 뒤에, 그걸 수행하기 위한 최고의 도구를 고르면 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ENG] 12 Rules to Learn to Code (2)]]></title>
            <link>https://velog.io/@_kpk0616/ENG-12-Rules-to-Learn-to-Code-2</link>
            <guid>https://velog.io/@_kpk0616/ENG-12-Rules-to-Learn-to-Code-2</guid>
            <pubDate>Sun, 11 Sep 2022 10:53:53 GMT</pubDate>
            <description><![CDATA[<h1 id="목적을-가지고-코딩하라">목적을 가지고 코딩하라.</h1>
<blockquote>
<p><strong>12 Rules to Learn to Code</strong>
Dr. Angela Yu</p>
</blockquote>
<p>내가 처음 코딩을 배우기 시작할 때, 선택하고 포기한 순간이 수없이 많았다. 이건 독학을 한 코더들 사이의 흔한 이야기이다. 돌아보면 많은 학생들을 가르치고 난 후에서야 마침내 어떤 일이 일어나고 있는지 깨달았다. 많은 비기너들이 임의의 언어를 선택해서 코딩을 배우기 시작하고 많은 튜토리얼을 따라 한다. 한 줄 한 줄 코드를 복사하고, 소수를 계산하기 위해 코드를 쓴다던가 짝수를 찾기 위한 코드를 쓴다. 그런데 그걸 아는가? 나는 소수를 구글링으로 더 빨리 찾을 수 있고 짝수만을 찾아내는 것에는 어떠한 흥미도 없다.</p>
<p>사실은 이렇다. 당신이 그저 코딩을 배우기 위해 코딩을 배운다면, 그걸 잘 해내기란 매우 어려울 것이다. 프로그래밍 같은, 연마하기 위해 많은 시간을 필요로 하는 기술은 깊은 내적 동기부여를 필요로 한다. 그 안에서의 무언가가 당신이 먹고 자는 것을 잊게 만든다. 솔직히 말해서 나는 내 프로젝트에서 한 코딩이 내가 한 가장 즐거운 일들 중 하나라고 할 수 있다. 내적 동기부여는 논리적 사고와 창의서을 결합해 결국 당신이 무언가를 만들어내게 할 것이다. 대부분 세상이 본 적 없는 것, 당신의 삶과 사람들의 삶의 길을 간편하고 즐겁게 만들어주는 것일 것이다. 마치 차고가 필요 없거나 부품에 한 푼도 쓰지 않고 차고에서 미친 듯이 아름다운 커스텀 오토바이를 만든 것처럼 말이다.</p>
<p>코딩은 대부분의 사람들을 동기부여하게 만든다. 창조하고 만들어내는 부분이 말이다. 그래서 나는 당신에게 무언가를 만드는 튜토리얼을 따라 시작하기를 추천한다. 물론 처음부터 당신이 Clash of Clans 이나 League of Legends 처럼 코딩을 할 수 있지는 않을 것이다. 하지만 당신은 흥미로운 무언가를 만들어낼 수 있다. 주사위 게임이나 카드 뒤집이 앱 같은 것들 말이다. 튜토리얼이 끝날 때쯤, 여러분은 이용하고 가지고 놀 수 있는 무언가를 만들었을 것이고, 당신은 끝까지 코딩하는 것에 훨씬 더 동기부여가 될 것이다.</p>
<p>우리는 수업 동안, 항상 학생들에게 만들고 싶은 간단한 앱을 생각하라고 한다. 본 코스에서 배운 기술을 사용하지만 새로운 기능을 포함하는 방법을 찾아야하기 때문에 조금 더 확장시킨 앱을 생각하라고 한다.</p>
<p>매일 1분씩 일찍 깨우는 앱을 만든 학생이 있었다. 기상 시간을 빠르게 하는 것을 쉽게 하기 위해서였다. 어머니의 생일 선물로 커스텀 슬라이드 쇼 앱을 만든 학생도 있었다. 무게와 두께를 바탕으로 완벽한 스테이크를 만드는 타이머 앱을 만든 사람도 있었다.</p>
<p>당신의 상상력에는 한계가 없다. 당신이 자신만의 앱을 만드는 것은 단계적 지침이 없기 때문에 어렵게 느껴질 것이지만 당신의 코딩 실력에 어마어마한 발전을 가져올 것이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ENG] 12 Rules to Learn to Code (1)]]></title>
            <link>https://velog.io/@_kpk0616/ENG-12-Rules-to-Learn-to-Code-1</link>
            <guid>https://velog.io/@_kpk0616/ENG-12-Rules-to-Learn-to-Code-1</guid>
            <pubDate>Thu, 08 Sep 2022 08:04:44 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>12 Rules to Learn to Code</strong> 
Dr. Angela Yu</p>
</blockquote>
<h1 id="20분의-법칙으로-당신의-뇌를-속여라">20분의 법칙으로 당신의 뇌를 속여라</h1>
<p>코딩을 배우는 것은 헬스장에 가는 것과 비슷합니다. 주말 내내 헬스장에서 시간을 보내고 최선을 다했다 하더라도, 당신의 몸에 눈에 띄는 변화가 나타나지는 않습니다. 코딩을 정기적으로 할수록 당신의 코딩 근육이 찢기는 것을 더 많이 볼 수 있을 것입니다. (이런 아이러니가 결코 손해는 아닙니다.)</p>
<p>하지만 문제는 &#39;어디서 시간을 낼 것인가?&#39; 입니다. 풀 타임 근무에 가족, 생활 관리에 시간을 쓰면서 대체 언제 앉아서 &quot;daily coding&quot; 을 실천할 수 있을까요?</p>
<p>의사로 일을 하던 때에 저는 약 12시간씩 병원에서 보냈고 통근으로 1시간, 식사와 같은 생명 유지 활동으로 대략 2시간을 보냈습니다. 그래서 제 하루에는 오직 9시간이라는 시간만이 남아 있었죠. 이론적으로 2시간은 코딩 연습을 하는 데에, 7시간은 잠을 자는 데에 할당할 수 있었습니다. 그러나 일에 찌들어있는 뇌를 아이스크림 한 통과 함께 왕좌의 게임을 시청할 수 있는 시간에 앉아서 공부를 하게 하는 것은 세상 가장 어려운 일임에 틀림없었습니다.</p>
<p>하지만 전 하나의 트릭을 찾았어요.</p>
<p>인간으로서 우리는 관성을 가집니다. 이 관성이라는 것은 우리에게 나쁘게 작용할 수 있지요. (24시간이라는 box set 에 들어가있는 당신을 찾아볼 수 있듯이) 하지만, 우리는 이 관성을 우리의 장점으로 바꿀 수 있습니다. 저는 한 번 코딩을 시작하고 무언가를 만들기 시작하면, 프로젝트에 빠져서 더 이상 TV, 음식, 수면의 필요성을 느끼지 않는다는 것을 깨달았어요. 해가 뜰 때까지 코딩하는 주말을 보낸 적도 꽤 많았습니다.</p>
<p>그렇다면 우리는 이 관성을 어떻게 이용할 수 있을까요? 첫번째로, <strong>작업을 전환하는 것이 매우 어렵다는 것을 이해해야 합니다.</strong> 하던 일을 바꾸는 것은 많은 동기 부여를 필요로 해요. 집에 도착하자마자 당신이 소파에 널브러져 TV를 켜면 당신은 이미 그 날 오후를 몽땅 버린 것입니다. 먹기나 잠자기 같은 진화에 의해 주도되지 않는 일을 하는 데 필요한 동기 부여를 하는 것이 엄청나게 큰 힘이 드는 일이기 때문입니다.</p>
<p>그래서 당신이 문을 열고 새로운 환경으로 들어오는 순간이 가장 중요한 것입니다. <strong>이 중요한 순간 딱 20분 동안만 코딩 연습을 하자고 다짐한다면, 당신은 끝내 한 시간 이상 공부하게 되는 관성을 이용하는 데에 성공하게 될 것입니다.</strong> 뇌는 20분 동안 많은 노력 하지 않고 오후 시간을 활용하도록 당신의 뇌를 속이게 되겠지요.</p>
<p>그 다음 단계는 습관을 기르는 것입니다. 연구에 따르면 새로운 습관을 기르기 위해서는 한 달 동안 매일 그 일을 수행해야 한다고 합니다. 저는 운동 대신 코딩으로, 다른 일을 하는 데에 이 방법을 적용했는데 이 역시 예외 없이 매력적으로 작용했습니다. 이 트릭을 서문하기 위해, 다섯 개의 그림이 걸려 있는 벽을 상상해보시길 바랍니다. 그 중 네 개는 완벽히 수평으로 정렬되어 있고 한 개는 삐뚤어져 있습니다. 그 중 고치고 싶은 부분이 있는지 상상해보세요.</p>
<p>이제 각각의 날을 나타내는 상자들이 있는 달력을 상상해 봅시다. 만약 여러분이 특정한 날 새로운 습관을 길러왔다면, 여러분은 그 날들을 통해 하나의 선을 그을 것입니다. 다음 날 습관을 실천하는 데 성공했다면 그 선을 계속 연장시키게 될 것입니다. 계속되는 선을 망가뜨리지 않는 것은 사람들이 계속해서 습관을 기르는 데에 동기부여가 됩니다. 이상한 소리처럼 들릴 수 있지만 제가 포기하고 싶은 많은 순간들에 하나의 긴, 이어지는 선을 만드는 것이 습관을 계속 실천하게 하는 데에 많은 도움이 되었습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[iOS] Naver BoostCourse - MusicPlayer]]></title>
            <link>https://velog.io/@_kpk0616/iOS-Naver-BoostCourse-MusicPlayer</link>
            <guid>https://velog.io/@_kpk0616/iOS-Naver-BoostCourse-MusicPlayer</guid>
            <pubDate>Sun, 28 Aug 2022 13:06:19 GMT</pubDate>
            <description><![CDATA[<p>처음 iOS 개발을 접하는 입장에서 Swift 문법이나 앱 개발에 필요한 개념, 사용되는 메소드 등에 대한 지식이 전무한 상태인지라 필요한 지식을 기록하고 습득하기 위해 해당 코드가 왜 이렇게 작성되었는지 분석하는 시간을 가졌습니다.</p>
<h1 id="-1"># 1</h1>
<h2 id="guard-let">guard let</h2>
<pre><code>guard let soundAsset: NSDataAsset = NSDataAsset(name: &quot;sound&quot;) else {
            print(&quot;음원 파일 에셋을 가져올 수 없습니다&quot;)
            return
        }</code></pre><p>guard let 으로 지정한 변수는 if let 과는 다르게 전역변수로 사용 가능하다. 또한 else 문에서 <code>return, break, continue, throw</code> 와 같이 상위 코드 블록을 종료하는 코드가 필수적으로 들어가야 한다.</p>
<h3 id="참고">참고</h3>
<p><a href="https://velog.io/@dev-lena/guard-let%EA%B3%BC-if-let%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90">https://velog.io/@dev-lena/guard-let과-if-let의-차이점</a>
<a href="https://jud00.tistory.com/entry/%EC%98%A4%EB%8A%98%EC%9D%98-Swift-%EC%A7%80%EC%8B%9D-if-let-%EA%B3%BC-guard-let%EC%9D%98-%EC%B0%A8%EC%9D%B4%EB%8A%94">https://jud00.tistory.com/entry/오늘의-Swift-지식-if-let-과-guard-let의-차이는</a></p>
<h2 id="nsdataasset">NSDataAsset</h2>
<pre><code>guard let soundAsset: NSDataAsset = NSDataAsset(name: &quot;sound&quot;) else {
            print(&quot;음원 파일 에셋을 가져올 수 없습니다&quot;)
            return
        }</code></pre><p>개체의 콘텐츠는 연결된 디바이스 속성을 가진 하나 이상의 파일 집합으로 저장이 되는데 (assets), 이 sets 는 NSDataAsset 을 통해 on-demand 리소스로 사용할 수 있도록 태그를 지정할 수 있다. </p>
<h1 id="-2"># 2</h1>
<pre><code>var player: AVAudioPlayer!

...

do {
            try self.player = AVAudioPlayer(data: soundAsset.data)
            self.player.delegate = self
        } catch let error as NSError {
            print(&quot;플레이어 초기화 실패&quot;)
            print(&quot;코드 : \(error.code), 메세지 : \(error.localizedDescription)&quot;)
        }</code></pre><h2 id="do---try---catch">do - try - catch</h2>
<p>error handling 을 위해 swift 에서 사용하는 방식이다.
예제 코드는 아래와 같다.</p>
<pre><code>do {
    // Create audio player object
    audioPlayer = try AVAudioPlayer(contentsOf: soundURL)

    // Play the sound
    audioPlayer?.play()
}
catch {
    // Couldn&#39;t create audio player object, log the error
    print(&quot;Couldn&#39;t create the audio player for file \(soundFilename)&quot;)
}</code></pre><h3 id="참고-1">참고</h3>
<p><a href="https://codewithchris.com/swift-try-catch/">https://codewithchris.com/swift-try-catch/</a></p>
<h2 id="player-가-아닌-selfplayser-로-사용하는-이유는"><code>player</code> 가 아닌 <code>self.playser</code> 로 사용하는 이유는?</h2>
<p>self 란 보통 클래스나 구조체 자신을 가리킬 때 사용한다.
아래 예제에서 self.name 은 Student class 의 name 변수를 의미하고 name 은 매개변수로 받아온 변수 name 을 의미한다.</p>
<pre><code>class Student {
    var name = &quot;&quot;
    func setName(name: String) -&gt; () {
        self.name = name
    }
}</code></pre><p><code>self.player.delegate = self</code> 에서 <code>self.player</code> 는 <code>var player: AVAudioPlayer!</code> 로 정의된 변수 player 를 가리키게 된다. 그런데 <code>player</code> 만으로도 가리킬 수 있는 변수임에도 불구하고 <code>self.player</code> 로 명시해주는 이유는 무엇일까?
<strong>인스턴스는 클래스 외부에서만 접근할 수 있기 때문에 클래스 내부에서는 어느 인스턴스에 할당된 것인지 알기 힘들다.</strong>
이러한 이유 때문에 인스턴스 이름 대신 self 키워드를 이용해 자신의 인스턴스라는 것을 표현한다.
self 키워드는 생략이 가능하며, 실제로 생략을 많이 한다.
하지만 만약 프로퍼티와 일반 변수의 이름이 같을 경우 구분을 위해 self 를 꼭 써주어야한다.</p>
<h3 id="참고-2">참고</h3>
<ul>
<li>self 키워드 : <a href="https://m.blog.naver.com/hjleesm/221223019546">https://m.blog.naver.com/hjleesm/221223019546</a></li>
<li>self.프로퍼티명 : <a href="https://velog.io/@junsuboy/Swift-self%EB%9E%80">https://velog.io/@junsuboy/Swift-self란</a></li>
</ul>
<h2 id="delegate">delegate</h2>
<p>Delegation은 클래스 또는 구조체가 다른 유형의 인스턴스로 책임을 전달 또는 위임할 수 있도록 하는 디자인 패턴이다.
이 디자인 패턴은 delegate라고 알려진 위임 기능을 제공하도록 보장하는 프로토콜을 정의함으로써 실행이 된다.
AVAudioPlayer 클래스에 해당하는 변수 player 를 새로 만들어주었으니, 이 변수가 자신의 메소드를 사용할 수 있도록 하기 위해 delegate 를 이용해 위임해준다.</p>
<h3 id="참고-3">참고</h3>
<ul>
<li>self : <a href="https://hodev.tistory.com/107">https://hodev.tistory.com/107</a></li>
<li>delegate : <a href="https://minosaekki.tistory.com/14">https://minosaekki.tistory.com/14</a></li>
</ul>
<h2 id="catch-let-error-as-nserror"><code>catch let error as NSError</code></h2>
<p>앞에 <code>NS</code> 가 붙은 타입은 대부분 Objective-C 의 타입이다. 
do-try-catch 구문에서 catch 에서 catch 뒤에 <em>매개변수 패턴</em> 등을 명시하지 않으면 암묵적으로 <code>error</code> 라는 이름으로 Swift의 Error 타입의 인스턴스가 전달되는데, 이 Error 타입의 인스턴스를 Objective_C 의 <code>NSError</code> 타입으로 <em>브릿징(Bridging)</em> 하여 사용하기 위해 작성한 것이다.</p>
<h3 id="참고-4">참고</h3>
<p><a href="https://yagom.net/forums/topic/%EA%B8%B0%EC%B4%88%EC%A0%81%EC%9D%B8-swift-%EB%AC%B8%EB%B2%95-%EC%A7%88%EB%AC%B8%EB%93%9C%EB%A6%BD%EB%8B%88%EB%8B%A4-%E3%85%A0%E3%85%A0/">https://yagom.net/forums/topic/기초적인-swift-문법-질문드립니다-ㅠㅠ/</a></p>
<h2 id="avaudioplayer">AVAudioPlayer</h2>
<p>AVAudioPlayer 를 사용하기 위해서는 AVFoundation 프레임워크를 import 해야한다. (<code>import AVFoundation</code>)
AVAudioPlayer(contentsOf:) 또는 AVAudioPlayer(data:) 로 플레이어를 생성할 수 있다.
네트워크 상 존재하는 파일일 경우 URL로부터 Data 를 추출하고 AVAudioPlayer(data:) 로 생성할 수 있다. getDataFrom(url:) 메서드를 사용하면 된다.</p>
<h3 id="참고-5">참고</h3>
<p><a href="https://yurimac.tistory.com/57">https://yurimac.tistory.com/57</a></p>
<h1 id="-3"># 3</h1>
<pre><code>self.progressSlider.maximumValue = Float(self.player.duration)
        // self.player.duration 값이 얼마?
        self.progressSlider.minimumValue = 0
        self.progressSlider.value = Float(self.player.currentTime)</code></pre><h2 id="avaudioplayer-의-속성">AVAudioPlayer 의 속성</h2>
<p>duration 은 플레이어 오디오의 총 지속 시간(초 단위) 이다. 따라서 progressSlider 의 최대값을 player 의 duration 으로 설정해준 것이다.
progressSlider 의 현재 값은 player 의 currentTime 으로 지정해 나타낼 수 있다.</p>
<h3 id="참고-6">참고</h3>
<p><a href="https://developer.apple.com/documentation/avfaudio/avaudioplayer/1388395-duration">https://developer.apple.com/documentation/avfaudio/avaudioplayer/1388395-duration</a></p>
<h1 id="-4"># 4</h1>
<pre><code>// TimeLabel 업데이트 함수
    func updateTimeLabelText(time: TimeInterval) {
        let minute: Int = Int(time / 60)
        let second: Int = Int(time.truncatingRemainder(dividingBy: 60))
        let milisecond: Int = Int(time.truncatingRemainder(dividingBy: 1) * 100)

        let timeText: String = String(format: &quot;%02ld:%02ld:%02ld&quot;, minute, second, milisecond)

        self.timeLabel.text = timeText
    }</code></pre><h2 id="timeinterval">TimeInterval</h2>
<p>초 단위를 의미한다.</p>
<h2 id="truncatingremainderdividingby">truncatingRemainder(dividingBy:)</h2>
<p>truncatingRemainder(dividingBy:) 은 소수점이 있는 Double 이나 Float 의 나머지 값을 구할 때에도 사용되는데, truncating division 을 이용해 주어진 값으로 나눈 값의 나머지를 반환한다.</p>
<h1 id="-5"># 5</h1>
<pre><code>// 타이머 생성 및 실행 함수

func makeAndFireTimer() {
        // 타이머 생성
        self.timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true, block: { [unowned self] (timer: Timer) in

            if self.progressSlider.isTracking { return }

            self.updateTimeLabelText(time: self.player.currentTime)
            self.progressSlider.value = Float(self.player.currentTime)
        })
        // 타이머 실행
        self.timer.fire()
    }</code></pre><h2 id="scheduledtimerwithtimeintervalrepeatsblock">scheduledTimer(withTimeInterval:repeats:block:)</h2>
<p>타이머를 생성하고 타이머를 현재 실행 루프에서 디폴트 모드로 스케쥴한다.</p>
<h3 id="parameters">Parameters</h3>
<ul>
<li>interval : 타이머 실행(firings) 사이의 시간(초)이다. interval 이 0.0 보다 작거나 같으면 음수가 아닌 값인 0.0001 초를 선택한다.</li>
<li>repeats : true 인 경우 타이머는 무효화될 때까지 반복적으로 리스케쥴한다. false 인 경우 타이머가 실행(fire) 된 후 무효화된다.</li>
<li>block : 타이머가 실행될 때 실행할 블록이다. 하나의 NSTimer 파라미터만을 사용하며 return value 가  없다.<h3 id="return-value">return value</h3>
지정된 매개변수에 따라 구성된 새로운 NSTimer 객체를 리턴한다.</li>
</ul>
<h2 id="istracking">isTracking</h2>
<p>유저가 스크롤을 시작하기 위해 콘텐츠를 터치했는지 여부를 나타내는 boolean 값이다.</p>
<p>위의 <code>makeAndFireTimer</code> 함수는 타이머를 생성 및 실행하는 함수이다.
타이머 생성 시 사용자가 스크롤을 시작하면 타이머 생성을 중단하고, timelabel 의 텍스트와 progressSlider 의 값을 player 의 현재 시간으로 초기화한다.</p>
<h3 id="참고-7">참고</h3>
<p><a href="https://developer.apple.com/documentation/uikit/uiscrollview/1619413-istracking">https://developer.apple.com/documentation/uikit/uiscrollview/1619413-istracking</a></p>
<h1 id="-6"># 6</h1>
<pre><code>// 타이머 무효화 함수
    func invalidateTimer() {
        self.timer.invalidate()
        self.timer = nil
    }</code></pre><h2 id="nil">nil</h2>
<p>Siwft 에서 nil 은 <strong>특정 타입에 대한 값의 부재</strong>를 의미한다.
Object-C 와 Swift 에서 쓰이는 것으로, C 언어의 NULL 과 유사하지만 다르다.
Object-C 의 nil 은 Object-C 객체의 클래스의 부재를 나타내고 (존재하지 않는 객체에 대한 포인터), Swift 의 nil 은 Objective-C 객체의 부재를 나타낸다 (포인터가 아닌 특정 타입에 대한 값의 부재를 보여줌).</p>
<pre><code>import Foundation

let str1 = &quot;123a&quot;
let str2 = &quot;123&quot;

print(Int(str1) == nil ? 0 : 1)
print(Int(str2) == nil ? 0 : 1)

// 출력 결과
0
1</code></pre><p>문자열을 Int 형으로 변환했을 때, Int 형으로 변환할 수 없는 문자열이 포함된 str1 의 경우에는 0을 출력하는 모습을 볼 수 있다.</p>
<h3 id="참고-8">참고</h3>
<p><a href="https://seolhee2750.tistory.com/10">https://seolhee2750.tistory.com/10</a></p>
<h1 id="-7"># 7</h1>
<pre><code>func addPlayPauseButton() {
        let button: UIButton = UIButton(type: UIButton.ButtonType.custom)
        button.translatesAutoresizingMaskIntoConstraints = false

        self.view.addSubview(button)

        button.setImage(UIImage(named: &quot;button_play&quot;), for: UIControl.State.normal)
        button.setImage(UIImage(named: &quot;button_pause&quot;), for: UIControl.State.selected)

        button.addTarget(self, action: #selector(self.touchUpPlayPauseButton(_:)), for: UIControl.Event.touchUpInside)

...</code></pre><h2 id="translatesautoresizingmaskintoconstraints">translatesAutoresizingMaskIntoConstraints</h2>
<p>translatesAutoresizingMaskIntoConstraints 는 UIView 의 인스턴스 프로퍼티이다.
런타임 시 뷰를 추가, 삭제하기 위해 Suto Layout 을 코드로 제약 조건을 생성, 추가, 삭제 및 적용할 수 있는데 그러기 위해 translatesAutoresizingMaskIntoConstraints 값을 false 로 주어야한다.
뷰의 autoresizing mask 가 constraint 를 기반 레이아웃 시스템으로 변환할지 말지 여부를 나타내는 boolean 값이다.</p>
<h3 id="참고-9">참고</h3>
<p><a href="https://ios-development.tistory.com/672">https://ios-development.tistory.com/672</a></p>
<h2 id="viewaddsubview">view.addSubview</h2>
<p><code>addSubview(_:)</code> 는 리시버의 subview 리스트의 맨 끝에 뷰를 추가한다.
맨 끝에 추가된 뷰는 다른 subview 들보다 위에 나타난다.</p>
<h3 id="참고-10">참고</h3>
<p><a href="https://developer.apple.com/documentation/uikit/uiview/1622616-addsubview">https://developer.apple.com/documentation/uikit/uiview/1622616-addsubview</a></p>
<h2 id="addtarget_actionfor">addTarget(<em>_:action:for:)</em></h2>
<p>타겟 객체와 메서드를 컨트롤과 연결한다.</p>
<h3 id="parameters-1">parameters</h3>
<ul>
<li>target : 메서드가 호출되는 객체이다.</li>
<li>action : 호출할 작업 메서드를 식별하는 셀렉터이다. 이름이 일치하는 셀렉터를 지정할 수 있다. nil 이 아니어야 한다.</li>
<li>controlEvents : 액션 메서드가 호출되는 컨트롤별 이벤트를 지정하는 비트 마스크이다. 항상 하나 이상의 상수를 지정해야한다. 가능한 상수 목록은 UIContro.Event 를 참조하면 된다.<h3 id="참고-11">참고</h3>
<a href="https://developer.apple.com/documentation/uikit/uicontrol/1618259-addtarget">https://developer.apple.com/documentation/uikit/uicontrol/1618259-addtarget</a></li>
</ul>
<h2 id="selector">#selector</h2>
<p>셀렉터는 메서드를 식별할 수 있는 고유한 이름이다. Swift 에서는 구조체 (struct) 타입이며 컴파일 타임에 지정된다.
UIKit 내부에 Objective-C 런타임으로 실행되는 메서드가 셀렉터를 파라미터로 전달받을 때, 전달에 필요한 셀렉터 인스턴스 생성을 위해 사용한다.</p>
<h3 id="참고-12">참고</h3>
<p><a href="https://woozzang.tistory.com/120">https://woozzang.tistory.com/120</a></p>
<h2 id="uicontroleventtouchupinside">UIControl.Event.touchUpInside</h2>
<p>손가락이 컨트롤 가능한 바운드 내에 있는 터치업 이벤트이다.</p>
<h1 id="-8"># 8</h1>
<pre><code>...
        let centerX: NSLayoutConstraint
        centerX = button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor)

        let centerY: NSLayoutConstraint
        centerY = NSLayoutConstraint(item: button, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.view, attribute: NSLayoutConstraint.Attribute.centerY, multiplier: 0.8, constant: 0)

        let width: NSLayoutConstraint
        width = button.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: 0.5)

        let ratio: NSLayoutConstraint
        ratio = button.heightAnchor.constraint(equalTo: button.widthAnchor, multiplier: 1)

        centerX.isActive = true
        centerY.isActive = true
        width.isActive = true
        ratio.isActive = true

        self.playPauseButton = button
    }</code></pre><h2 id="nslayoutconstraint">NSLayoutConstraint</h2>
<p>constraint 기반 레이아웃 시스템이 충족해야하는 두 UI 객체 간의 관계를 나타낸다.
<code>item1.attribute1 = multiplier × item2.attribute2 + constant</code> 와 같이 선형 방정식 형태여야한다.</p>
<h3 id="참고-13">참고</h3>
<p><a href="http://minsone.github.io/mac/ios/nslayoutconstraint">http://minsone.github.io/mac/ios/nslayoutconstraint</a>
<a href="https://developer.apple.com/documentation/uikit/nslayoutconstraint">https://developer.apple.com/documentation/uikit/nslayoutconstraint</a></p>
<h2 id="centerxanchor">centerXAnchor</h2>
<p>뷰 프레임의 수평 중심을 나타내는 레이아웃 앵커이다.</p>
<h2 id="isactive--true">.isActive = true</h2>
<p>iOS 8부터는 isActive 속성을 설정해 제약 조건을 활성화해야한다. 제약 조건을 포함하는 배열을 전달해 여러 제약 조건을 활성화할 수도 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[iOS] Naver BoostCourse - MusicPlayer]]></title>
            <link>https://velog.io/@_kpk0616/iOS-Naver-BoostCourse-MusicPlayer-d4h59c63</link>
            <guid>https://velog.io/@_kpk0616/iOS-Naver-BoostCourse-MusicPlayer-d4h59c63</guid>
            <pubDate>Sun, 28 Aug 2022 12:38:14 GMT</pubDate>
            <description><![CDATA[<p>강의를 들으며 알게 된 개념을 정리한 페이지입니다.
사진이 많고 템플릿이 깨지는 관계로 노션 링크를 첨부합니다.
<a href="https://www.notion.so/75f22e4c16f64156bcb45ce21a6a8cc2">https://www.notion.so/75f22e4c16f64156bcb45ce21a6a8cc2</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[git] Fork 한 repository 최신으로 동기화하기]]></title>
            <link>https://velog.io/@_kpk0616/git-Fork-%ED%95%9C-repository-%EC%B5%9C%EC%8B%A0%EC%9C%BC%EB%A1%9C-%EB%8F%99%EA%B8%B0%ED%99%94%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@_kpk0616/git-Fork-%ED%95%9C-repository-%EC%B5%9C%EC%8B%A0%EC%9C%BC%EB%A1%9C-%EB%8F%99%EA%B8%B0%ED%99%94%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 26 Aug 2022 06:02:54 GMT</pubDate>
            <description><![CDATA[<ol>
<li><p>fork 해 온 repository 에서 remote repository 를 확인하면 아래와 같이 나온다.</p>
<pre><code>% git remote -v
origin  https://github.com/kpk0616/uftrace.git (fetch)
origin  https://github.com/kpk0616/uftrace.git (push)</code></pre></li>
<li><p>동기화해오고 싶은 원본 repository 를 <code>upstream</code> 이라는 이름으로 추가해준다.</p>
<pre><code>% git remote add upstream https://github.com/namhyung/uftrace.git</code></pre></li>
<li><p>upstream repository 가 제대로 추가되었는지 확인한다.</p>
<pre><code>% git remote -v
origin  https://github.com/kpk0616/uftrace.git (fetch)
origin  https://github.com/kpk0616/uftrace.git (push)
upstream        https://github.com/namhyung/uftrace.git (fetch)
upstream        https://github.com/namhyung/uftrace.git (push)</code></pre></li>
<li><p>upstream repository 로부터 최신 업데이트를 가져온다.
git 의 fetch 명령어를 이용해 upstream repository 의 내용을 불러온다.</p>
<pre><code>% git fetch upstream
remote: Enumerating objects: 415, done.
remote: Counting objects: 100% (415/415), done.
remote: Compressing objects: 100% (130/130), done.
remote: Total 415 (delta 271), reused 368 (delta 271), pack-reused 0
Receiving objects: 100% (415/415), 275.94 KiB | 2.24 MiB/s, done.
Resolving deltas: 100% (271/271), completed with 121 local objects.
From https://github.com/namhyung/uftrace</code></pre></li>
<li><p>upstream repository 의 master branch (혹은 원하는 branch) 로부터 나의 local master branch 로 merge 한다.</p>
<pre><code>% git checkout master
Already on &#39;master&#39;
Your branch is up to date with &#39;origin/master&#39;.
</code></pre></li>
</ol>
<p>% git merge upstream/master
Merge made by the &#39;recursive&#39; strategy.</p>
<pre><code>
6. 이 과정까지는 local repository 에서 일어난 것이므로 push 를 통해 remote repository 에도 적용시켜주면 된다.</code></pre><p>% git push origin master</p>
<p>```</p>
<h1 id="참고">참고</h1>
<p><a href="https://json.postype.com/post/210431">https://json.postype.com/post/210431</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[iOS] LifeCycle 에 대하여]]></title>
            <link>https://velog.io/@_kpk0616/iOS-LifeCycle-%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC</link>
            <guid>https://velog.io/@_kpk0616/iOS-LifeCycle-%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC</guid>
            <pubDate>Wed, 24 Aug 2022 13:04:08 GMT</pubDate>
            <description><![CDATA[<p>네이버 부스트코스 강의를 수강하다가 LifeCycle 개념에 대해 알아야 할 필요성을 느끼게 되었습니다.
대충 앱이 실행되고 어떻게 동작하는지에 대한 사이클을 나타내는 개념이라는 것은 알고 있는데, 검색을 해 보니 안드로이드 / React / iOS 에서 나타내는 LifeCycle 이 각각 다른 특징을 가진 것 같았습니다. 뿐만 아니라 어느 포스팅에서든 LifeCycle 을 아는 것이 중요하다고 강조를 하는데, 정확히 어떤 개념이고 어느 포인트에서 중요한지를 알아야겠다는 생각이 들었습니다.</p>
<pre><code>    // MARK: Life Cycle
    override func viewDidLoad() {
        super.viewDidLoad()
        self.initializePlayer()
    }</code></pre><h1 id="lifecycle-이란">LifeCycle 이란?</h1>
<p>라이프사이클은 생명주기, 생애주기라는 사전적 의미를 가지고 있습니다.
소프트웨어공학에서 의미하는 라이프사이클은 프로젝트 라이프사이클, 소프트웨어 배포 라이프사이클, 소프트웨어 개발 라이프사이클 등이 있습니다. 
모바일 앱에서는 앱, 화면에서도 생명주기가 있는데, 홈 화면을 눌렀을 때 어플이 종료되지 않고 대기하거나 뒤로가기를 두 번 눌렀을 때 앱이 종료되는 등이 이에 해당됩니다. </p>
<h1 id="ios-lifecycle">iOS LifeCycle</h1>
<h2 id="state">state</h2>
<p>모든 iOS 앱은 LifeCycle 에 따라 동작하므로, 개발자들은 애플리케이션의 동작을 이해하기 위해 LifeCycle 에 대해 숙지해야 할 필요가 있습니다.
<img src="https://velog.velcdn.com/images/_kpk0616/post/4e65ad70-e5c6-4b52-8a14-ec4bd7c81496/image.png" alt=""></p>
<ol>
<li><strong>Not Running</strong> : 앱이 아직 시작되지 않았거나 시스템 혹은 유저에 의해 종료되었을 때의 상태를 의미합니다.</li>
<li><strong>Inactive</strong> : 앱이 실행된 상태이지만 이벤트를 받지 못하는 경우를 의미합니다. 앱이 다른 상태로 전환하기 위해 잠시 머무는 브릳지 상태라고 할 수 있습니다.</li>
<li><strong>Active</strong> : 앱이 실행되어 있으며 유저 이벤트를 받을 수 있는 평범한 앱의 상태를 의미합니다.</li>
<li><strong>Background</strong> : 유저가 홈 화면을 탭하거나 앱이 약간의 추가 실행 시간이 필요한 경우 background 상태로 전환됩니다. 앱이 일시정지된 상태에도 background 로 전환됩니다. 이 상태에서는 앱이 백그라운드에 남아 코드를 실행합니다.</li>
<li><strong>Suspended</strong> : 앱이 백그라운드에 남아 있지만 코드를 실행하지 않는 상태입니다. 앱은 자동으로 이 상태로 전환됩니다. suspended 상태가 되면 앱은 메모리에 남아 있으나 foreground 앱이 suspended 앱보다 항상 우선순위를 갖고 suspended 앱은 에고 없이 종료될 수 있습니다.</li>
</ol>
<h2 id="uiapplicationdelegate-methods">UIApplicationDelegate methods</h2>
<p>iOS 앱은 UIApplicationDelegate 를 주축으로 빌드되고 실행됩니다.
UIApplicationDelegate 는 앱이 백그라운드 / 포그라운드로 이동, 푸시 알림 등과 같은 여러 사용자 이벤트를 알리기 위해 애플리케이션이 구현해야 하는 프로토콜입니다.
UIApplicationDelegate 는 앱이 실행을 시작할 때 명시되는 app lifecycle method 를 포함합니다.</p>
<ol>
<li><strong>application: didFinishLaunchingWithOptions:-&gt; Bool</strong> : 앱이 처음 시작될 때 호출되는 메소드입니다. 이 메소드를 이용해 firebase 구성, 유저 네비게이션 등 애플리케이션에 대한 초기 설정을 할 수 있습니다. 이 시점에서 스토리보드가 로드되지만, 상태 복원(state restoration) 을 유지할 수 있습니다.</li>
<li><strong>applicationWillEnterForeground</strong> : didFinishLaunchingWithOptions 이 실행된 후에 호출되는 메소드입니다. 애플리케이션을 백그라운드에서 포그라운드로 불러오는 역할을 합니다.</li>
<li><strong>applicationDidBecomeActive</strong> : applicationWillEnterForeground 이 실행된 후 호출되는 메소드입니다. 앱이 포그라운드로 나올 때 글꼴 업데이트 등과 같은 특정 작업을 수행해야 하는 경우 이 메소드 안에 코드를 배치시킬 수 있습니다.</li>
<li><strong>applicationWillResignActive</strong> : 애플리케이션이 inactive 될 때에 실행되는(notified 되는) 메소드입니다. (ex : 유저가 전화를 받을 때, 유저가 홈 버튼을 누를 때)</li>
<li><strong>applicationDidEnterBackground</strong> : 앱이 inactive 상태가 된 후 백그라운드 상태로 전환될 때 실행되는(notified 되는) 메소드입니다.</li>
<li><strong>applicationWillTerminate</strong> : 앱이 메모리에서 최종적으로 종료될 때 호출되는 메소드입니다. 최종적인 클린업을 해야 하는 경우 이 메서드에 코드를 배치할 수 있습니다.</li>
</ol>
<p>앱 실행 시 실행할 코드는 <strong>didFinishLaunchingWithOptions</strong> 메서드 안에 배치할 수 있습니다. 예를 들어 앱 사용을 위해 유저 로그인을 필요로 하는 앱에서 유저가 이비 로그인했는지를 UserDefaults 를 체크하는 것을 통해 확인할 수 있습니다. 만약 유저가 이미 로그인 한 상태라면 유저를 홈 스크린으로 이동시키고, 그렇지 않다면 로그인 화면으로 이동시키도록 말이지요.</p>
<h1 id="참고">참고</h1>
<ul>
<li>iOS app lifecycle : <a href="https://www.javatpoint.com/ios-app-lifecycle">https://www.javatpoint.com/ios-app-lifecycle</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Swift] 10989 : 수 정렬하기 3]]></title>
            <link>https://velog.io/@_kpk0616/Swift-10989-%EC%88%98-%EC%A0%95%EB%A0%AC%ED%95%98%EA%B8%B0-3</link>
            <guid>https://velog.io/@_kpk0616/Swift-10989-%EC%88%98-%EC%A0%95%EB%A0%AC%ED%95%98%EA%B8%B0-3</guid>
            <pubDate>Tue, 16 Aug 2022 09:45:16 GMT</pubDate>
            <description><![CDATA[<h1 id="시간-초과">시간 초과</h1>
<p>Swift 문법에 익숙해지기 위해 Swift 를 이용해 문제를 풀고 있는데, 시간 초과가 정말 많이 납니다. 오름차순으로 수를 정렬해 출력하는 <strong>수 정렬하기 3</strong> 문제에서 swift 가 제공하는 sort 함수를 이용해 문제를 풀면 어김 없이 시간 초과가 납니다.</p>
<p><img src="https://velog.velcdn.com/images/_kpk0616/post/7cd5b2cb-59a3-4a78-93d9-6ed35e676da1/image.png" alt=""></p>
<pre><code>import Foundation

let N = Int(readLine()!)!
var arr = [Int](repeating: 0, count: N)

for i in 0...N-1 {
    arr[i] = Int(readLine()!)!
}
arr.sort()

for i in 0...N-1 {
    print(arr[i])
}</code></pre><h1 id="알고리즘">알고리즘</h1>
<p>그러면 시간복잡도가 <em>O(n+k)</em> 인 <strong>counting sort</strong> 를 이용해 문제를 풀면 어떨까요?</p>
<blockquote>
<h2 id="counting-sort-란">counting sort 란?</h2>
<p>*<em>Link : *</em><a href="https://www.cs.miami.edu/home/burt/learning/Csc517.091/workbook/countingsort.html">애니메이션</a>
숫자에 해당하는 인덱스를 가지는 counting array 를 만들어놓고, 배열의 값에는 숫자가 등장하는 빈도수를 저장해놓습니다.
counting array 에 대해 직전 요소들의 값을 더해준 뒤, 입력 배열과 동일한 크기의 출력 배열을 만들어 입력 배열의 역순으로 출력 배열을 채워 줍니다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/_kpk0616/post/b7cd0678-a6e5-40b4-8cd0-132030bbdf62/image.png" alt=""></p>
<p>counting sort 또한 시간 초과가 납니다. 코드는 아래와 같습니다.</p>
<pre><code>import Foundation

let N = Int(readLine()!)!
var arr = [Int](repeating: 0, count: 10001)
var result = &quot;&quot;

for _ in 0..&lt;N {
    let n = Int(readLine()!)!
    arr[n] += 1
}

for i in 1...10000 where arr[i] &gt; 0 {
    for _ in 0..&lt;arr[i] {
        print(i)
    }
}
</code></pre><h1 id="swift-시간-초과-줄이기--입출력">Swift 시간 초과 줄이기 : 입출력</h1>
<p>Swift 는 입출력이 상당히 느린 편이고, 백준에서도 Swift 에 대한 추가 시간을 주지 않는다고 합니다. 따라서 입출력 속도를 향상시키기 위한 방안을 활용해야 시간 초과 문제를 해결할 수 있습니다.
Swift 문제 풀이에 최적화된 입력 유틸리티 클래스를 사용하면 시간 초과 문제가 해결됩니다.
<img src="https://velog.velcdn.com/images/_kpk0616/post/a0c180b7-4f09-4437-88f1-79b0b867814f/image.png" alt=""></p>
<blockquote>
<p><strong>Link :</strong> <a href="https://gist.github.com/JCSooHwanCho/30be4b669321e7a135b84a1e9b075f88">Swift 입력 유틸리티 클래스</a></p>
</blockquote>
<pre><code>import Foundation

final class FileIO {
    private var buffer:[UInt8]
    private var index: Int

    init(fileHandle: FileHandle = FileHandle.standardInput) {
        buffer = Array(fileHandle.readDataToEndOfFile())+[UInt8(0)] // 인덱스 범위 넘어가는 것 방지
        index = 0
    }

    @inline(__always) private func read() -&gt; UInt8 {
        defer { index += 1 }

        return buffer.withUnsafeBufferPointer { $0[index] }
    }

    @inline(__always) func readInt() -&gt; Int {
        var sum = 0
        var now = read()
        var isPositive = true

        while now == 10
            || now == 32 { now = read() } // 공백과 줄바꿈 무시
        if now == 45{ isPositive.toggle(); now = read() } // 음수 처리
        while now &gt;= 48, now &lt;= 57 {
            sum = sum * 10 + Int(now-48)
            now = read()
        }

        return sum * (isPositive ? 1:-1)
    }

    @inline(__always) func readString() -&gt; String {
        var str = &quot;&quot;
        var now = read()

        while now == 10
            || now == 32 { now = read() } // 공백과 줄바꿈 무시

        while now != 10
            &amp;&amp; now != 32 &amp;&amp; now != 0 {
                str += String(bytes: [now], encoding: .ascii)!
                now = read()
        }

        return str
    }
}

let file = FileIO()

let N = file.readInt()
var arr = [Int](repeating: 0, count: 10001)


for _ in 0..&lt;N {
    let n = file.readInt()
    arr[n] += 1
}

var answer = &quot;&quot;
for i in 1...10000 {
    answer += String(repeating:&quot;\(i)\n&quot;,count:arr[i])
}
print(answer)
</code></pre><h1 id="참고">참고</h1>
<ul>
<li>counting sort : <a href="https://soobarkbar.tistory.com/101">https://soobarkbar.tistory.com/101</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Swift] 1929 : 소수 구하기]]></title>
            <link>https://velog.io/@_kpk0616/BOJ-1929-%EC%86%8C%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@_kpk0616/BOJ-1929-%EC%86%8C%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sat, 13 Aug 2022 07:40:46 GMT</pubDate>
            <description><![CDATA[<h1 id="시간-초과">시간 초과</h1>
<p><img src="https://velog.velcdn.com/images/_kpk0616/post/4be8b3da-7704-4cfd-8c6a-70dde4e2d05a/image.png" alt=""></p>
<pre><code>import Foundation

let input = readLine()!.split(separator: &quot; &quot;).map{ Int(String($0))! }
var result = &quot;&quot;

let m = input[0]
let n = input[1]
var y = 2

for x in m...n { // x : 소수 판별 당할 아이
    y = 2
    while (y &lt;= x - 1) { // y : x 가 소수인지 판별할, 나누어줄 아이
        if (x % y == 0) { break }
        y += 1
    }
    if (y == x) { print(String(x)) }
}
</code></pre><p>일반적인 반복문을 이용해 풀었더니 시간 초과가 나서, 에라토스테네스의 체 알고리즘을 이용해 풀었습니다.
스위프트를 이용해서 문제를 푼 게 처음이라 입출력부터 배열 선언, 반복문까지 스위프트 문법에 대해 찾아 보며 풀었습니다.</p>
<h1 id="알고리즘">알고리즘</h1>
<h2 id="에라토스테네스의-체-알고리즘">에라토스테네스의 체 알고리즘</h2>
<p><code>에라토스테네스의 체 알고리즘</code> 은 소수 판별에 사용되는 효율적인 알고리즘입니다.
1 부터 n 까지의 수에서 소수를 판별한다고 할 때,
n 만큼의 0 이 아닌 수로 초기화 된 배열을 만들어놓은 후 소수인 수는 0으로 배열의 값을 채워줍니다.
2 부터 n / 2 까지 j 의 값을 1 씩 증가시키면서, j 의 배수에 해당하는 수는 소수가 아닌 수에 해당하므로 해당 인덱스의 값을 0 으로 만들어줍니다.
배수를 확인할 때에는 7 x 1, 7 x 2, ... 로 확인하지 않고 7 x 7, 7 x 8 부터 확인해줍니다.
7 x 6 같은 경우 6 의 배수를 확인할 때 이미 확인이 완료되었기 때문입니다.
이런 식으로 n 까지 소수인지를 판별한 후, 최종적으로 인덱스의 값이 0 이 아닌 수들만 프린트해주면 됩니다.</p>
<h2 id="코드">코드</h2>
<pre><code>import Foundation

let input = readLine()!.split(separator: &quot; &quot;).map{ Int($0)! }

let M = input[0]
let N = input[1]

var arr: [Int] = Array(repeating: 0, count: N + 1)
for i in 2...N {
    arr[i] = i
}

for j in 2...N {
    if arr[j] == 0 { continue }
    for k in stride(from: j + j, through: N, by: j) {
        arr[k] = 0
    }
}

for w in M...N {
    if arr[w] != 0 {
        print(&quot;\(arr[w])&quot;)
    }
}</code></pre><h1 id="swift-문법">Swift 문법</h1>
<h2 id="swift-정수-여러-개-입력받기">Swift 정수 여러 개 입력받기</h2>
<pre><code>let input = readLine()!.split(separator: &quot; &quot;).map{ Int($0)! }

let M = input[0]
let N = input[1]</code></pre><p><code>readLine</code> 을 이용해 한 줄로 입력받은 문자열을 &quot; &quot; 를 기준으로 <code>split</code> 해준 뒤, <code>map</code> 을 이용해 Int 형으로 저장합니다.
배열 형태로 input 에 저장되고, 인덱스를 이용해 M 과 N 을 뽑아내면 됩니다.</p>
<h2 id="stridefrom-through-by">stride(from, through, by)</h2>
<p>아래 두 경우와 같이 사용되는데, <code>from</code> 은 초기화, <code>through</code> 는 end 값, <code>by</code> 는 값과 값 사이 넘어가는 연산 수를 의미합니다.</p>
<pre><code>for countdown in stride(from: 3, through: 1, by: -1) {
    print(&quot;\(countdown)...&quot;)
}
// 3...
// 2...
// 1...</code></pre><pre><code>for multipleOfThree in stride(from: 3, through: 10, by: 3) {
    print(multipleOfThree)
}
// 3
// 6
// 9</code></pre><h1 id="참고">참고</h1>
<ul>
<li>에라토스테네스의 체 : <a href="https://codevang.tistory.com/65">https://codevang.tistory.com/65</a></li>
<li>Swift 정수 여러 개 입력받기 : <a href="https://please-amend.tistory.com/entry/%EB%B0%B1%EC%A4%80-%EC%8A%A4%EC%9C%84%ED%94%84%ED%8A%B8Swift%EB%A1%9C-%ED%92%80%EA%B8%B0-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%83%9D%EC%84%B1-%EC%9E%85%EB%A0%A5-%EB%B0%9B%EB%8A%94-%EB%B2%95">https://please-amend.tistory.com/entry/백준-스위프트Swift로-풀기-프로젝트-생성-입력-받는-법</a></li>
<li>stride(from, through, by) : <a href="https://developer.apple.com/documentation/swift/stride(from:through:by:)">https://developer.apple.com/documentation/swift/stride(from:through:by:)</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React Native] The Basics : React Fundamentals]]></title>
            <link>https://velog.io/@_kpk0616/React-Native-The-Basics-React-Fundamentals</link>
            <guid>https://velog.io/@_kpk0616/React-Native-The-Basics-React-Fundamentals</guid>
            <pubDate>Mon, 08 Aug 2022 12:15:36 GMT</pubDate>
            <description><![CDATA[<p>React Native는 JavaScript와 사용자 인터페이스를 구축하는 데 널리 사용된 오픈 소스 라이브러리인 React에서 실행됩니다. React Native를 최대한 활용하기 위해서는 React 자체를 이해하는 것이 도움이 됩니다.</p>
<p>React의 핵심 개념에 대해 알아봅시다. :</p>
<ul>
<li>components</li>
<li>JSX</li>
<li>props</li>
<li>state</li>
</ul>
<p>더 파고들고 싶다면, <a href="https://reactjs.org/docs/getting-started.html">React 공식 문서</a>를 확인하길 권장합니다.</p>
<h3 id="your-first-component">Your first component</h3>
<p>React에 대한 이 도입부의 나머지 부분에서는 고양이(친근하고 접하기 쉬운 동물)를 예시로 들 것입니다. 다음은 첫 번째 Cat component입니다.</p>
<h4 id="function-component-your-cat">Function Component (Your Cat)</h4>
<pre><code>import React from &#39;react&#39;;
import { Text } from &#39;react-native&#39;;

const Cat = () =&gt; {
  return (
    &lt;Text&gt;Hello, I am your cat!&lt;/Text&gt;
  );
}

export default Cat;</code></pre><h4 id="class-component-your-cat">Class Component (Your Cat)</h4>
<pre><code>import React, { Component } from &#39;react&#39;;
import { Text } from &#39;react-native&#39;;

class Cat extends Component {
  render() {
    return (
      &lt;Text&gt;Hello, I am your cat!&lt;/Text&gt;
    );
  }
}

export default Cat;</code></pre><p>추가로 React에서 <code>Component</code>를 import합니다.</p>
<pre><code>import React, { Component } from &#39;react&#39;;</code></pre><p>Component가 함수로써가 아닌 <code>Component</code>를 확장하는 클래스로 시작됩니다.</p>
<pre><code>class Cat extends Component {}</code></pre><p>class components는 <code>render()</code>함수를 가지고 있습니다. 리턴되는 내용은 모두 React 요소로 렌더링됩니다.</p>
<pre><code>class Cat extends Component {
  render() {
    return &lt;Text&gt;Hello, I am your cat!&lt;/Text&gt;;
  }
}</code></pre><p>또한 function components를 가지고 class component를 export할 수 있습니다.</p>
<pre><code>class Cat extends Component {
  render() {
    return &lt;Text&gt;Hello, I am your cat!&lt;/Text&gt;;
  }
}

export default Cat;</code></pre><blockquote>
<p>component를 export하는 수많은 방법 중 한 가지입니다. 이런 export는 Snack Plyer를 이용해 잘 작동됩니다. 하지만 앱의 파일 구조에 따라 다른 convention을 이용해야 할 수 있습니다. <a href="https://medium.com/dailyjs/javascript-module-cheatsheet-7bd474f1d829">JavaScript imports and exports에 대한 cheatsheet</a>가 도움이 될 것입니다.</p>
</blockquote>
<p>이제 <code>return</code>문을 자세히 보십시오. <code>&lt;Text&gt;Hello, I am your cat!&lt;/Text&gt;</code>는 요소를 편리하게 작성하게 하는 JavaScript 구문인 JSX를 사용하고 있습니다.</p>
<h3 id="jsx">JSX</h3>
<p>React와 React Native는 <code>&lt;Text&gt;Hello, I am your cat!&lt;/Text&gt;</code>와 같이 JavaScript 내부에 요소를 작성할 수 있는 구문인 <strong>JSX</strong>를 사용합니다. React 문서는 <a href="https://reactjs.org/docs/jsx-in-depth.html">JSX에 대한 포괄적인 가이드</a>를 포함하고 있습니다. 자세한 내용은 JSX를 참조하세요. JSX는 JavaScript이기 때문에, 안에 변수를 사용할 수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React Native] The Basics : Core Components and Native Components]]></title>
            <link>https://velog.io/@_kpk0616/React-Native-The-Basics-Core-Components-and-Native-Components</link>
            <guid>https://velog.io/@_kpk0616/React-Native-The-Basics-Core-Components-and-Native-Components</guid>
            <pubDate>Mon, 08 Aug 2022 12:14:45 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://reactnative.dev/docs/0.64/intro-react-native-components">Core Components and Native Components</a>
0.64 Version 을 기준으로 번역하였습니다.
모든 이미지의 출처는 React Native 공식 홈페이지에 있습니다.</p>
</blockquote>
<h3 id="core-components-and-native-components">Core Components and Native Components</h3>
<p>React Native 는 React와 앱 플랫폼의 기본 기능을 이용하여 Android 와 iOS 어플리케이션 구축을 위한 오픈 소스 프레임워크입니다. React Native에서 당신은 JavaScript를 이용해 React 컴포넌츠(재사용 가능하고 중첩 가능한 코드)를 이용한 UI의 모양 및 동작을 설명할 수 있을 뿐만 아니라 플랫폼의 API를 액세스할 수 있습니다. 다음 섹션에서 React에 대해 더 알아보도록 합시다. 그 전에 먼저, React Native에서 컴포넌츠가 어떻게 동작하는지를 살펴봅시다.</p>
<h3 id="views-and-mobile-development">Views and mobile development</h3>
<p>안드로이드와 iOS 개발에 있어서 <strong>view</strong>는 UI를 구성하는 가장 기본적인 요소입니다. : 텍스트, 이미지를 보여주거나 유저의 입력에 반응하기 위해 사용되는 스크린의 작은 직사각형 요소입니다. 한 줄의 텍스트나 하나의 버튼같이 앱의 가장 작은 시각적 요소에서조차 view에 해당합니다. 몇 종류의 view는 다른 view들을 포함합니다. 아래 보이는 모든 것들이 view 입니다!
<img src="https://images.velog.io/images/kpk0616/post/2371a542-f493-46b1-95d8-4e2d22739a2f/image.png" alt=""></p>
<h3 id="native-components">Native Components</h3>
<p>안드로이드 개발에서는 Kotlin 이나 Java로 view를 작성하고, iOS 개발에서는 Swift나 Objective-C를 이용합니다. React Native를 이용하면 React Components를 사용하여 JavaScript로 이런 views를 호출할 수 있습니다. 런타임에 React Native는 해당 components에 대한 안드로이드와 iOS views를 생성합니다. React Native components는 Andriod와 iOS와 동일한 views를 통해 백업되기 때문에, React Native 앱들은 다른 앱들과 모양, 느낌 및 성능이 동일하게 대응됩니다. 이런 플랫폼 지원 components를 <strong>Native Components</strong>라고 합니다.</p>
<p>React Native는 바로 사용할 수 있는 필수 Native Components 세트가 함께 제공됩니다. 이것을 React Native의 <strong>Core Components</strong>라고 합니다.</p>
<p>또한 React Native를 사용하면 앱의 특정한 needs에 맞게 Android 및 iOS용 Native Components를 직접 구축할 수 있습니다. 또 이런 풍부한 community-contributed components 생태계를 가지고 있습니다. 커뮤니티가 작성한 내용을 확인하려면 <a href="https://reactnative.directory/">Native Directory</a>를 확인하십시오.</p>
<h3 id="core-components">Core Components</h3>
<p>React Native는 form controls부터 activity indicators까지 모든 것을 위한 많은 Core Components 를 가지고 있습니다. 당신은 <a href="https://reactnative.dev/docs/0.64/components-and-apis">API 섹션</a>에서 모든 문서들을 확인할 수 있습니다. 주로 다음과 같은 핵심 구성 요소로 작업합니다.</p>
<h4 id="view"><code>&lt;View&gt;</code></h4>
<ul>
<li>flexbox, style, some touch handling, and accessibility controls 레이아웃을 지원하는 컨테이너</li>
<li>Android : <code>&lt;ViewGroup&gt;</code></li>
<li>IOS : <code>&lt;UIView&gt;</code></li>
<li>Web Analog : A non-scrolling <code>&lt;div&gt;</code></li>
</ul>
<h4 id="text"><code>&lt;Text&gt;</code></h4>
<ul>
<li>텍스트 문자열을 표시, 디자인, 묶고 터치 이벤트를 처리한다.</li>
<li>Android : <code>&lt;TextView&gt;</code></li>
<li>IOS : <code>&lt;UITextView&gt;</code></li>
<li>Web Analog : <code>&lt;p&gt;</code></li>
</ul>
<h4 id="image"><code>&lt;Image&gt;</code></h4>
<ul>
<li>다른 타입의 이미지들을 표시한다.</li>
<li>Android : <code>&lt;ImageView&gt;</code></li>
<li>IOS : <code>&lt;UIImageView&gt;</code></li>
<li>Web Analog : <code>&lt;img&gt;</code></li>
</ul>
<h4 id="scrollview"><code>&lt;ScrollView&gt;</code></h4>
<ul>
<li>여러 components와 views를 포함할 수 있는 일반적인 스크롤 컨테이너</li>
<li>Android : <code>&lt;ScrollView&gt;</code></li>
<li>IOS : <code>&lt;UIScrollView&gt;</code></li>
<li>Web Analog : <code>&lt;div&gt;</code></li>
</ul>
<h4 id="textinput"><code>&lt;TextInput&gt;</code></h4>
<ul>
<li>유저가 텍스트를 입력하게 한다.</li>
<li><code>&lt;EditText&gt;</code></li>
<li><code>&lt;UITextField&gt;</code></li>
<li><code>&lt;input type=&quot;text&quot;&gt;</code></li>
</ul>
<p>다음 섹션에서, Core Components를 조합하여 React가 어떻게 돌아가는지에 대해 알아봅시다.</p>
<pre><code>import React from &#39;react&#39;;
import { View, Text, Image, ScrollView, TextInput } from &#39;react-native&#39;;

const App = () =&gt; {
  return (
    &lt;ScrollView&gt;
      &lt;Text&gt;Some text&lt;/Text&gt;
      &lt;View&gt;
        &lt;Text&gt;Some more text&lt;/Text&gt;
        &lt;Image
          source={{
            uri: &#39;https://reactnative.dev/docs/assets/p_cat2.png&#39;,
          }}
          style={{ width: 200, height: 200 }}
        /&gt;
      &lt;/View&gt;
      &lt;TextInput
        style={{
          height: 40,
          borderColor: &#39;gray&#39;,
          borderWidth: 1
        }}
        defaultValue=&quot;You can type in me&quot;
      /&gt;
    &lt;/ScrollView&gt;
  );
}

export default App;</code></pre><p>React Native는 React components와 동일한 API구조를 사용하기 때문에, React component API를 이해할 필요가 있습니다. <a href="https://reactnative.dev/docs/0.64/intro-react">다음 섹션</a>에서는 이 주제에 대해 간단히 소개해보도록 하겠습니다. 만약 당신이 React에 익숙하다면 자유롭게 <a href="https://reactnative.dev/docs/0.64/handling-text-input">스킵</a>해도 좋습니다.
<img src="https://images.velog.io/images/kpk0616/post/f03c393b-dbf6-42c5-ab00-0c6b4c65427b/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React Native] The Basics : Introduction]]></title>
            <link>https://velog.io/@_kpk0616/React-Native-The-Basics-Introduction</link>
            <guid>https://velog.io/@_kpk0616/React-Native-The-Basics-Introduction</guid>
            <pubDate>Mon, 08 Aug 2022 12:14:09 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://reactnative.dev/docs/0.64/getting-started">Introduction</a>
0.64 Version 을 기준으로 번역했습니다.</p>
</blockquote>
<p>많은 다양한 종류의 사람들이 React Native를 사용합니다. : 숙련된 iOS 개발자부터 리액트 초보자, 커리어에서 처음으로 프로그래밍을 시작한 사람들까지. 이 공식문서는 경험 수준이나 배경에 상관없이 모든 학습자들을 위해 작성되었습니다.</p>
<h3 id="공식-문서-활용하는-법">공식 문서 활용하는 법</h3>
<p>당신은 여기서부터 시작해 이 공식문서를 책처럼 쭉 읽어나가거나, 당신이 필요한 특정 부분만 읽을 수 있습니다. 이미 React에 익숙하신가요? 그렇다면 <a href="https://reactnative.dev/docs/0.64/intro-react">해당 섹션</a>을 스킵할 수 있습니다. - 가벼운 복습을 위해 읽어보세요.</p>
<h3 id="필수-구성-요소-prerequisites">필수 구성 요소 (Prerequisites)</h3>
<p>React Native 로 작업하기 위해서는 JavaScript 핵심요소에 대한 이해가 필요합니다. 만약 당신이 JavaScript에 새롭거나 추가학습이 필요하다면 Mozilla Developer Network 를 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript">복습</a>하거나 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript">공부</a>하면 됩니다.</p>
<blockquote>
<p>우리는 React, Android, iOS 개발에 대한 사전 지식이 없는 것을 가정하기 위해 최선을 다하고 있지만, 이것들은 React Native 개발 지망생들에게 중요한 주제입니다. 합리적으로 우리는 심층적인 자료와 기사와 연결지었습니다.</p>
</blockquote>
<h3 id="interactive-examples">Interactive examples</h3>
<p>이 도입부에서는 브라우저를 이용해 다음과 같은 대화형 예제로 즉시 시작해볼 수 있게 합니다.</p>
<pre><code>import React from &#39;react&#39;;
import { Text, View } from &#39;react-native&#39;;

const YourApp = () =&gt; {
  return (
    &lt;View style={{ flex: 1, justifyContent: &quot;center&quot;, alignItems: &quot;center&quot; }}&gt;
      &lt;Text&gt;
        Try editing me! 🎉
      &lt;/Text&gt;
    &lt;/View&gt;
  );
}

export default YourApp;</code></pre><p>위는 Snack Player 입니다. Snack Player는 Expo에서 React Native 프로젝트를 내장하여 실행하고 프로젝트가 Android 와 iOS 같은 플랫폼에서 어떻게 렌더링되는지를 공유하기 위해 만든 손쉬운 툴입니다. 코드는 활성화 상태이고 편집 가능하므로 당신의 브라우저에서 직접 실행시킬 수 있습니다. 바로 위의 &quot;Try deiting me!&quot; 텍스트를 &quot;Hello, world!&quot;로 바꿔보세요.</p>
<blockquote>
<p>추가적으로, local 개발 환경을 갖추길 원한다면 <a href="https://reactnative.dev/docs/0.64/environment-setup">우리의 가이드를 따라서 당신의 로컬 머신 환경을 세팅</a>하고 당신의 <code>App.js</code> 파일에 코드 예제를 붙여넣기 하세요. (만약 당신이 웹 개발자라면, 이미 모바일 브라우저를 위한 로컬 환경 설정이 되어있을 것입니다!)</p>
</blockquote>
<h3 id="function-components-와-class-components">Function Components 와 Class Components</h3>
<p>React로 당신은 클래스나 함수를 사용하여 컴포넌츠를 만들 수 있습니다.
원래 class components 는 state를 가진 유일한 컴포넌츠였습니다. 그러나 React&#39;s Hooks API 가 도입된 이후로 function components 에 state 등을 추가할 수 있게 되었습니다.
<a href="https://reactnative.dev/blog/2019/03/12/releasing-react-native-059">Hooks 는 React Native 0.59 에 도입되었습니다</a>. Hooks 는 React 컴포넌츠를 작성하는 미래지향적인 방법이기 때문에 우리는 function component 예제를 이용해 이 서론을 작성했습니다. 우리는 또한 다음과 같은 토글 아래에 class components를 다룹니다. </p>
<h4 id="function-component">Function Component</h4>
<pre><code>import React from &#39;react&#39;;
import { Text, View } from &#39;react-native&#39;;

const HelloWorldApp = () =&gt; {
  return (
    &lt;View style={{
        flex: 1,
        justifyContent: &#39;center&#39;,
        alignItems: &#39;center&#39;
      }}&gt;
      &lt;Text&gt;Hello, world!&lt;/Text&gt;
    &lt;/View&gt;
  );
}

export default HelloWorldApp;</code></pre><h4 id="class-component">Class Component</h4>
<pre><code>import React, { Component } from &#39;react&#39;;
import { Text, View } from &#39;react-native&#39;;

class HelloWorldApp extends Component {
  render() {
    return (
      &lt;View style={{
          flex: 1,
          justifyContent: &quot;center&quot;,
          alignItems: &quot;center&quot;
        }}&gt;
        &lt;Text&gt;Hello, world!&lt;/Text&gt;
      &lt;/View&gt;
    );
  }
}

export default HelloWorldApp;</code></pre><p>당신은 <a href="https://reactnative.dev/versions">이 문서의 이전 버전</a>에서 더 많은 class components 예제를 찾을 수 있습니다.</p>
<h3 id="developer-notes">Developer Notes</h3>
<p>많은 다른 개발 환경을 가진 사람들이 React Native 를 배우고 있습니다. 당신은 웹에서 Android 나 iOS 등의 다양한 기술을 사용해 본 경험이 있을 것입니다. 우리는 모든 환경의 개발자들을 위해 글을 쓰려고 노력합니다. 때로 우리는 하나의 혹은 다른 특정한 플랫폼에만 다음과 같은 설명을 제공합니다.
&#39;&#39;Android/iOS/Web 개발자들은 이 개념에 익숙할 것입니다.&#39;&#39;</p>
<h3 id="formatting">Formatting</h3>
<p>메뉴의 경로는 bold 체로 작성되며, 하위 메뉴를 탐색할 때의 주의사항을 사용합니다.
예 : <strong>Android Studio &gt; Preferences</strong></p>
<hr>
<p>이제 당신은 이 가이드가 어떻게 돌아가는지 알았으니, React Native의 기초인 <a href="https://reactnative.dev/docs/0.64/intro-react-native-components">Native Components</a> 에 대해 알아볼 시간입니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[git] git repository 클릭이 안 될 때]]></title>
            <link>https://velog.io/@_kpk0616/git-git-repository-%ED%81%B4%EB%A6%AD%EC%9D%B4-%EC%95%88-%EB%90%A0-%EB%95%8C</link>
            <guid>https://velog.io/@_kpk0616/git-git-repository-%ED%81%B4%EB%A6%AD%EC%9D%B4-%EC%95%88-%EB%90%A0-%EB%95%8C</guid>
            <pubDate>Mon, 08 Aug 2022 10:55:41 GMT</pubDate>
            <description><![CDATA[<h1 id="문제">문제</h1>
<p><img src="https://velog.velcdn.com/images/_kpk0616/post/42fd8e5a-4690-4db2-af15-e3e9fc88adf5/image.png" alt="">
github에 폴더를 커밋했을 때, 위 사진같이 폴더가 클릭이 안 되는 경우가 있습니다!</p>
<h1 id="원인">원인</h1>
<p>해당 문제의 원인은 폴더 안에 .git 폴더 혹은 그 잔여 파일이 남아있기 때문입니다. 
<code>ls -al</code> 을 이용해 파일 리스트를 확인했을 때 <code>.git</code> 파일이 존재하지 않는데도 문제가 지속된다!? 
그렇다면 캐시 파일을 삭제해주지 않았기 때문입니다.</p>
<h1 id="해결">해결</h1>
<ol>
<li><code>.git</code> 숨김 폴더를 제거해줍니다.<pre><code>rm -rf .git</code></pre></li>
<li><code>스테이지 파일</code> 을 제거해줍니다.<pre><code>rm --cached . -rf</code></pre></li>
<li>이후 다시 <code>add, commit, push</code> 해주면 됩니다.<pre><code>git add .
git commit -m &quot;test&quot;
git push</code></pre></li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[get_next_line] 정리]]></title>
            <link>https://velog.io/@_kpk0616/getnextline-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@_kpk0616/getnextline-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Mon, 01 Aug 2022 07:45:54 GMT</pubDate>
            <description><![CDATA[<h1 id="get_next_line-의-목적">get_next_line 의 목적</h1>
<p>get_next_line은 반복문 안에서 외부 파일의 내용을 개행문자까지 또는 EOF를 만날때까지 출력하는 함수입니다. 개행문자를 만났다면 해당 라인을 출력하고 다시 get_next_line 함수를 호출하면서 출력한 문자열의 다음 라인부터 출력합니다. 매개변수로 fd(파일디스크립터 값) 를 받습니다. 지역 변수나 매개 변수는 스택 영역에 할당되어집니다. 스택 영역은 함수의 호출과 함께 할당되고, 함수의 호출이 종료되면 소멸합니다.</p>
<h1 id="get_next_line-의-로직">get_next_line 의 로직</h1>
<p>일단 유효성 검사를 진행합니다. 들어온 fd 가 유효한 fd 인지 (0 미만의 값이면 유효하지 않은 값이라고 인식), 버퍼 사이즈는 유효한지 (0 이하일 경우 유효하지 않은 값으로 인식) 검사를 해준 후, 필요한 만큼의 메모리를 buffer 에 할당해줍니다. 이 버퍼는 read 함수를 이용해 원하는 바이트만큼 fd 를 읽어 줄 임시 버퍼로 사용될 것입니다.
ft_read_line 함수를 통해 read 함수로 읽어 온 문자열을 line 에 저장해줍니다. 이 때의 line 에는 여러 개의 \n 을 포함한 여러 문장이 들어가 있을 것입니다. ft_read_line 이 동작하는 과정은 다음과 같습니다.
우선 무한 반복문을 통해 count 변수에 read 함수가 뱉어낸 값을 저장해줍니다. count 가 -1이라면 fd 를 읽는 과정에서 오류가 났다는 의미이므로 함수를 종료시켜주고, 0이라면 파일의 종료를 의미하는 EOF를 만난 것이므로 반복문을 중단시켜줍니다. 에러가 난 경우에는 line 이 NULL 값을 갖게 되고, EOF 를 만난 경우라면 지금까지 읽어들인 문자열의 값을 갖게 될 것입니다.
count 가 0 초과의 값으로 fd 를 잘 읽어들였다면, 우선 버퍼의 마지막에는 문자열의 끝을 의미하는 \0 값을 넣어줍니다. save 가 NULL 값을 가진다면 fd 에 대해 get_next_line 을 처음 실행한 것이므로 strdup 을 이용해 빈 문자열을 할당해줍니다. 이후 strjoin 을 이용해 buffer 에 저장되어 있는 읽어 온 문자열을 붙여 준 새로운 문자열을 save 에 저장해줍니다. 버퍼에 \n 을 포함하고 있다면 반복문을 중단시키고 save 를 return 해줍니다. \n 을 기준으로 인덱스를 이동시킨 뒤, strdup 으로 한 문장을 제외한 뒷부분을 save 에 저장한 후 line 은 한 문장만을 포함하도록 해준 뒤 본 함수에서 line 을 리턴해줍니다.</p>
<h1 id="plus-지식">Plus 지식</h1>
<h2 id="read-함수">read 함수</h2>
<ul>
<li><p>함수 원형</p>
<pre><code>#include &lt;unistd.h&gt;
ssize_t read(int fd, void *buf, size_t nbytes);</code></pre></li>
<li><p>매개변수</p>
<pre><code>int fd
읽을 파일의 파일 디스크립터
</code></pre></li>
</ul>
<p>void *buf
읽어들인 데이터를 저장할 버퍼(배열)</p>
<p>size_t nbytes
읽어들일 데이터의 최대 길이 (buf의 길이보다 길어선 안됨)</p>
<p>return value
읽어들이는 작업에 성공하면 읽어들인 데이터의 길이를 반환하고,
실패하면 -1을 반환하면서 errno를 설정한다.
무조건 nbytes 가 리턴되는 것은 아니다.
반환값이 0인 경우가 있는데, 읽을 바이트가 남아 있지 않다는 뜻이다.
즉, EOF를 만난 경우이다.
EOF와는 달리, len바이트만큼 읽으라고 요청했지만 더 읽을 게 없다면 그건 에러로 취급된다.
다시 말해 사용 가능한 데이터가 없는 것과 파일 끝에 도착한 것은 차이가 있다.</p>
<pre><code>
## 정적 변수
정적변수(static variable)는 프로그램이 종료되기 전까지 메모리가 소멸되지 않는 변수입니다. 함수를 벗어나도 변수가 사라지지 않고 유지되는데, get_next_line 에서는 \n 을 포함한 한 줄을 return 한 뒤에도 읽어들인 문자열을 유지해놓는 변수가 필요하기 때문에 정적 변수의 사용을 필요로 합니다.
정적 변수를 초기화할 때 반드시 상수로 초기화 해야하며, 초깃값을 지정하지 않으면 디폴트값 0으로 자동 초기화 됩니다.
**정적변수는 프로그램이 시작될 때 생성 및 초기화 되고 프로그램이 끝날 때 사라집니다.**
또한 함수의 매개변수로 사용할 수 없다는 특징이 있습니다.

## malloc 과 free
malloc 함수는 크기가 고정되어 있는 배열과는 달리 변수에 **동적으로 메모리를 할당**해주는 함수입니다. 동적으로 메모리를 할당하면 사용되지 않는 메모리의 낭비를 줄일  수 있고, 실행중에 필요한 메모리양을 판단해서 할당함으로써 효율적으로 메모리를 관리할 수 있습니다. 단 메모리를 할당하기 위해 malloc 을 이용할 때에 제대로 메모리가 할당되었는지 체크해주는 과정(NULL guard) 이 필요합니다.
동적 메모리를 할당한 메모리를 해제하기 위해 free 함수를 사용하는데, 정적 변수를 사용 시 유의해야 할 점은 free 를 이용해 정적 변수에 할당된 메모리를 해제하려 할 경우 오류가 발생한다는 점입니다.
**정적 변수는 컴파일 시에 메모리에 할당되며, 프로그램이 종료 시 메모리가 해제**됩니다.</code></pre><p>#include &lt;stdio.h&gt;</p>
<p>int test(void)
{
    int count = 0;
    count++;</p>
<pre><code>return (count);</code></pre><p>}</p>
<p>int main()
{
    printf(&quot;%d\n&quot;, test());
    printf(&quot;%d\n&quot;, test());
    return (0);
}</p>
<p>```
위의 코드에서 <strong>main() 함수의 printf() 함수로 test() 를 호출할 때에 비로소 count 변수에 대한 메모리가 할당되며 초기화된다는 것</strong>입니다.
따라서 이중 포인터가 아닌 static 변수를 사용할 때에, 그 변수를 직접 free 해줄 수는 없습니다. </p>
<h1 id="bonus-part">Bonus Part</h1>
<p>하나의 정적 변수 사용해서 여러 개의 fd 를 읽어들이는 get_next_line을 구현하면 됩니다.</p>
<h1 id="참고">참고</h1>
<ul>
<li>감구마님의 get_next_line : <a href="https://gamguma.dev/post/2022/02/get_next_line">https://gamguma.dev/post/2022/02/get_next_line</a></li>
<li>get_next_line 목적 : <a href="https://velog.io/@bahn/getnextline">https://velog.io/@bahn/getnextline</a></li>
<li>read 함수 : <a href="https://bubble-dev.tistory.com/entry/CC-read-%ED%95%A8%EC%88%98-%ED%8C%8C%EC%9D%BC%EC%9D%84-%EC%9D%BD%EB%8A%94-%ED%95%A8%EC%88%98">https://bubble-dev.tistory.com/entry/CC-read-%ED%95%A8%EC%88%98-%ED%8C%8C%EC%9D%BC%EC%9D%84-%EC%9D%BD%EB%8A%94-%ED%95%A8%EC%88%98</a></li>
<li>정적 변수 : <a href="https://code4human.tistory.com/128">https://code4human.tistory.com/128</a>, <a href="https://yeolco.tistory.com/132">https://yeolco.tistory.com/132</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CentOS] command not found : ifconfig]]></title>
            <link>https://velog.io/@_kpk0616/CentOS-command-not-found-ifconfig</link>
            <guid>https://velog.io/@_kpk0616/CentOS-command-not-found-ifconfig</guid>
            <pubDate>Mon, 25 Jul 2022 05:59:36 GMT</pubDate>
            <description><![CDATA[<h1 id="원인">원인</h1>
<p><code>ifconfig</code> 명령어를 쳤더니 <code>not found</code> 로 뜬다.
CentOS 7 부터는  네트워크 관련 패키지가 자동으로 설치되지 않는다고 한다.
<img src="https://velog.velcdn.com/images/_kpk0616/post/11d97ecf-68cd-4f5b-936e-20301f82b005/image.png" alt=""></p>
<h1 id="해결">해결</h1>
<p><code>yum</code> 명령어로 <code>net-tools</code> 를 설치해준다.</p>
<pre><code>yum install net-tools</code></pre><p>다시 <code>ifconfig</code> 를 실행해보면 아래와 같이 잘 작동된다.
<img src="https://velog.velcdn.com/images/_kpk0616/post/c8a63af8-1314-4e87-a1be-bc828bf9fd07/image.png" alt=""></p>
<h1 id="참고">참고</h1>
<p><a href="https://devkingdom.tistory.com/166">https://devkingdom.tistory.com/166</a></p>
]]></description>
        </item>
    </channel>
</rss>