<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>sin prisa pero sin pausa</title>
        <link>https://velog.io/</link>
        <description>You only get one life. It's actually your duty to live it as fully as possible.</description>
        <lastBuildDate>Fri, 28 Jul 2023 08:10:15 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>sin prisa pero sin pausa</title>
            <url>https://images.velog.io/images/wanderer-s/profile/f213e6c4-cb88-4d7c-80e3-1591301a90f6/Screenshot_20220103-145642_Instagram.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. sin prisa pero sin pausa. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/wanderer-s" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[2023 INFCON 갈 수 있을까?]]></title>
            <link>https://velog.io/@wanderer-s/2023-INFCON-%EA%B0%88-%EC%88%98-%EC%9E%88%EC%9D%84%EA%B9%8C</link>
            <guid>https://velog.io/@wanderer-s/2023-INFCON-%EA%B0%88-%EC%88%98-%EC%9E%88%EC%9D%84%EA%B9%8C</guid>
            <pubDate>Fri, 28 Jul 2023 08:10:15 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/wanderer-s/post/2bfb94ad-3e1b-4243-9f41-1b3c36ce7e10/image.png" alt=""></p>
<p>되더라도 듣고싶은게 겹치는 시간들이 있는데..
뭘 선택해서 들어야 할지 끝없이 고민이 된다</p>
<p>김칫국부터 마시지 말자 일단 되야지 아이고</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Leetcode - Contiguous Array]]></title>
            <link>https://velog.io/@wanderer-s/Leetcode-Contiguous-Array</link>
            <guid>https://velog.io/@wanderer-s/Leetcode-Contiguous-Array</guid>
            <pubDate>Fri, 04 Feb 2022 14:01:28 GMT</pubDate>
            <description><![CDATA[<h2 id="problem">Problem</h2>
<p><a href="https://leetcode.com/problems/contiguous-array/">Contiguous Array</a>
Given a binary array <code>nums</code>, return <em>the maximum length of a contiguous subarray with an equal number of <code>0</code> and <code>1</code></em>.</p>
<h4 id="example-1">Example 1:</h4>
<pre><code class="language-js">Input: nums = [0,1]
Output: 2
Explanation: [0, 1] is the longest contiguous subarray with an equal number of 0 and 1.</code></pre>
<h4 id="example-2">Example 2:</h4>
<pre><code class="language-js">Input: nums = [0,1,0]
Output: 2
Explanation: [0, 1] (or [1, 0]) is a longest contiguous subarray with equal number of 0 and 1.</code></pre>
<h4 id="constraints">Constraints:</h4>
<ul>
<li><p><code>1 &lt;= nums.length &lt;= 10⁵</code></p>
</li>
<li><p><code>nums[i]</code> is either <code>0</code> or <code>1</code>.</p>
<h2 id="solution">Solution</h2>
<h4 id="javascript">JavaScript</h4>
<pre><code class="language-js">/**
* @param {number[]} nums
* @return {number}
*/
var findMaxLength = function(nums) {
  const numHash = {}
  let count = 0,
      longestLength = 0

  for(let i = 0; i &lt; nums.length; i++) {
      if(nums[i] === 0) count--
      else count++

      if (count === 0) longestLength = i + 1

      if(count in numHash) {
          longestLength = Math.max(longestLength, i - numHash[count])
      } else {
          numHash[count] = i
      }
  }

  return longestLength
};</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Leetcode - 4Sum II]]></title>
            <link>https://velog.io/@wanderer-s/Leetcode-4Sum-II</link>
            <guid>https://velog.io/@wanderer-s/Leetcode-4Sum-II</guid>
            <pubDate>Thu, 03 Feb 2022 14:55:52 GMT</pubDate>
            <description><![CDATA[<h2 id="problem">Problem</h2>
<p><a href="https://leetcode.com/problems/4sum-ii/">4Sum II</a></p>
<p>Given four integer arrays <code>nums1</code>, <code>nums2</code>, <code>nums3</code>, and <code>nums4</code> all of length <code>n</code>, return the number of tuples <code>(i, j, k, l)</code> such that:</p>
<ul>
<li><code>0 &lt;= i, j, k, l &lt; n</code></li>
<li><code>nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0</code></li>
</ul>
<p>4개의 정수 배열 <code>nums1</code>, <code>nums2</code>, <code>nums3</code>, <code>nums4</code> 이 주어지고 모든 배열의 길이는 <code>n</code> 일때 다음과 같은 조건을 충족하는 tuples <code>(i, j, k, l)</code> 의 갯수를 구하시오 (간단히 말하면, 더해서 0이 될 수 있는 경우의 수를 구하시오)</p>
<h4 id="example-1">Example 1:</h4>
<pre><code class="language-js">Input: nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2]
Output: 2
Explanation:
The two tuples are:
1. (0, 0, 0, 1) -&gt; nums1[0] + nums2[0] + nums3[0] + nums4[1] = 1 + (-2) + (-1) + 2 = 0
2. (1, 1, 0, 0) -&gt; nums1[1] + nums2[1] + nums3[0] + nums4[0] = 2 + (-1) + (-1) + 0 = 0</code></pre>
<h4 id="example-2">Example 2:</h4>
<pre><code class="language-js">Input: (nums1 = [0]), (nums2 = [0]), (nums3 = [0]), (nums4 = [0]);
Output: 1;</code></pre>
<h4 id="constraints">Constraints:</h4>
<ul>
<li><code>n == nums1.length</code></li>
<li><code>n == nums2.length</code></li>
<li><code>n == nums3.length</code></li>
<li><code>n == nums4.length</code></li>
<li><code>1 &lt;= n &lt;= 200</code></li>
<li><code>-2²⁸ &lt;= nums1[i], nums2[i], nums3[i], nums4[i] &lt;= 2²⁸</code></li>
</ul>
<h2 id="solution">Solution</h2>
<h4 id="javascript">JavaScript</h4>
<pre><code class="language-js">/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @param {number[]} nums3
 * @param {number[]} nums4
 * @return {number}
 */
var fourSumCount = function (nums1, nums2, nums3, nums4) {
  let count = 0;
  const numObj = {};

  for (const a of nums1) {
    for (const b of nums2) {
      const sum = a + b;

      if (!numObj[sum]) {
        numObj[sum] = 0;
      }

      numObj[sum]++;
    }
  }

  for (const c of nums3) {
    for (const d of nums4) {
      const sum = c + d;

      if (numObj[-sum]) {
        count += numObj[-sum];
      }
    }
  }

  return count;
};
</code></pre>
<p><em>Feedback은 언제나 환영입니다</em>🤗</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Leetcode - Find All Anagrams in a String]]></title>
            <link>https://velog.io/@wanderer-s/Leetcode-Find-All-Anagrams-in-a-String</link>
            <guid>https://velog.io/@wanderer-s/Leetcode-Find-All-Anagrams-in-a-String</guid>
            <pubDate>Wed, 02 Feb 2022 12:34:13 GMT</pubDate>
            <description><![CDATA[<h2 id="problem">Problem</h2>
<p><a href="https://leetcode.com/problems/find-all-anagrams-in-a-string/">Find All Anagrams in a String</a>
Given two strings <code>s</code> and <code>p</code>, return <em>an array of all the start indices of <code>p</code>&#39;s anagrams in <code>s</code>.</em> You may return the answer in <strong>any order</strong>.</p>
<p>An <strong>Anagram</strong> is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.</p>
<h4 id="example-1">Example 1:</h4>
<pre><code class="language-js">Input: s = &quot;cbaebabacd&quot;, p = &quot;abc&quot;
Output: [0,6]
Explanation:
The substring with start index = 0 is &quot;cba&quot;, which is an anagram of &quot;abc&quot;.
The substring with start index = 6 is &quot;bac&quot;, which is an anagram of &quot;abc&quot;.</code></pre>
<h4 id="example-2">Example 2:</h4>
<pre><code class="language-js">Input: s = &quot;abab&quot;, p = &quot;ab&quot;
Output: [0,1,2]
Explanation:
The substring with start index = 0 is &quot;ab&quot;, which is an anagram of &quot;ab&quot;.
The substring with start index = 1 is &quot;ba&quot;, which is an anagram of &quot;ab&quot;.
The substring with start index = 2 is &quot;ab&quot;, which is an anagram of &quot;ab&quot;.</code></pre>
<h4 id="constraints">Constraints:</h4>
<ul>
<li><p><code>1 &lt;= s.length, p.length &lt;= 3 * 10⁴</code></p>
</li>
<li><p><code>s</code> and <code>p</code> consist of lowercase English letters.</p>
<h2 id="solution">Solution</h2>
<h4 id="javascript">JavaScript</h4>
<pre><code class="language-js">/**
* @param {string} s
* @param {string} p
* @return {number[]}
*/
var findAnagrams = function(s, p) {
  const pObj = {}

  for(const key of p) {
      if(!(key in pObj)) {
          pObj[key] = 0
      }
      pObj[key]++
  }

  let left = 0
  let right = 0
  let checkCount = p.length
  const result = []
  while(right &lt; s.length) {
      if(pObj[s[right]] &gt; 0) checkCount--

      pObj[s[right]]--
      right++

      if(checkCount === 0) result.push(left)

      if(right - left === p.length) {
          if(pObj[s[left]] &gt;= 0) checkCount++
          pObj[s[left]]++
          left++
      }
  }
  return result
};</code></pre>
</li>
<li><p>Feedback은 언제나 환영입니다*🤗</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Leetcode - Best Time to Buy and Sell Stock]]></title>
            <link>https://velog.io/@wanderer-s/Leetcode-Best-Time-to-Buy-and-Sell-Stock</link>
            <guid>https://velog.io/@wanderer-s/Leetcode-Best-Time-to-Buy-and-Sell-Stock</guid>
            <pubDate>Tue, 01 Feb 2022 13:57:24 GMT</pubDate>
            <description><![CDATA[<h2 id="problem">Problem</h2>
<p><a href="https://leetcode.com/problems/best-time-to-buy-and-sell-stock/">Best Time to Buy and Sell Stock</a>
You are given an array <code>prices</code> where <code>prices[i]</code> is the price of a given stock on the <code>ith</code> day.</p>
<p><code>prices</code>라는 배열이 주어지고 <code>prices[i]</code> 는 <code>ith</code> 날의 주가 일때</p>
<p>You want to maximize your profit by choosing a <strong>single day</strong> to buy one stock and choosing a <strong>different day in the future</strong> to sell that stock.</p>
<p>한 주식을 매수할 날을 선택하고, 매도 할 미래의 다른 날을 선택하여 이익을 최대화 하려고 한다 </p>
<p>Return <em>the maximum profit you can achieve from this transaction.</em> If you cannot achieve any profit, return <code>0</code>.</p>
<p>이 거래에서 얻을 수 있는 최대 이익을 구하시오. 만약 이익이 없다면 0을 반환한다</p>
<h4 id="example-1">Example 1:</h4>
<pre><code class="language-js">Input: prices = [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
Note that buying on day 2 and selling on day 1 is not allowed because you must buy before you sell.</code></pre>
<h4 id="example-2">Example 2:</h4>
<pre><code class="language-js">Input: prices = [7,6,4,3,1]
Output: 0
Explanation: In this case, no transactions are done and the max profit = 0.</code></pre>
<h4 id="constraints">Constraints:</h4>
<ul>
<li><p><code>1 &lt;= prices.length &lt;= 10⁵</code></p>
</li>
<li><p><code>0 &lt;= prices[i] &lt;= 10⁴</code></p>
<h2 id="solution">Solution</h2>
<h4 id="javascript">JavaScript</h4>
<pre><code class="language-js">/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function(prices) {
  let left = 0
  let profit = 0

  for(let right = 0; right &lt; prices.length; right++) {
      if(prices[left] &gt; prices[right]) left = right

      profit = Math.max(profit, prices[right] - prices[left])
  }

  return profit
};</code></pre>
</li>
<li><p>Feedback은 언제나 환영입니다*🤗</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Leetcode - Richest Customer Wealth]]></title>
            <link>https://velog.io/@wanderer-s/Leetcode-Richest-Customer-Wealth</link>
            <guid>https://velog.io/@wanderer-s/Leetcode-Richest-Customer-Wealth</guid>
            <pubDate>Mon, 31 Jan 2022 14:05:40 GMT</pubDate>
            <description><![CDATA[<h2 id="problem">Problem</h2>
<p><a href="https://leetcode.com/problems/richest-customer-wealth/">Richest Customer Wealth</a></p>
<p>You are given an <code>m x n</code> integer grid <code>accounts</code> where <code>accounts[i][j]</code> is the amount of money the <code>ith</code> customer has in the <code>jth</code> bank. Return <em>the <strong>wealth</strong> that the richest customer has.</em></p>
<p><code>m x n</code> 형태의 정수로 이루어진 2중배열 <code>accounts</code>이 주어졌을 때, <code>accounts[i][j]</code>는 <code>ith</code> 손님이 <code>jth</code> 은행에 가지고 있는 돈의 액수다
가장 돈이 많은 손님의 재산의 금액을 구하시오</p>
<p>A customer&#39;s <strong>wealth</strong> is the amount of money they have in all their bank accounts. The richest customer is the customer that has the maximum <strong>wealth.</strong></p>
<p>손님의 재산은 은행에 가지고 있는 모든 돈의 양이며, 가장 돈이 많은 손님은 재산이 가장 많은 손님이다. <em>(굳이 이러한 설명이..??)</em></p>
<h4 id="example-1">Example 1:</h4>
<pre><code class="language-js">Input: accounts = [[1,2,3],[3,2,1]]
Output: 6
Explanation:
1st customer has wealth = 1 + 2 + 3 = 6
2nd customer has wealth = 3 + 2 + 1 = 6
Both customers are considered the richest with a wealth of 6 each, so return 6.</code></pre>
<h4 id="example-2">Example 2:</h4>
<pre><code class="language-js">Input: accounts = [[1,5],[7,3],[3,5]]
Output: 10
Explanation: 
1st customer has wealth = 6
2nd customer has wealth = 10 
3rd customer has wealth = 8
The 2nd customer is the richest with a wealth of 10.</code></pre>
<h4 id="example-3">Example 3:</h4>
<pre><code class="language-js">Input: accounts = [[2,8,7],[7,1,3],[1,9,5]]
Output: 17</code></pre>
<h4 id="constraints">Constraints:</h4>
<ul>
<li><code>m == accounts.length</code></li>
<li><code>n == accounts[i].length</code></li>
<li><code>1 &lt;= m, n &lt;= 50</code></li>
<li><code>1 &lt;= accounts[i][j] &lt;= 100</code></li>
</ul>
<h2 id="solution">Solution</h2>
<h4 id="javascript">JavaScript</h4>
<ol>
<li>첫번째 시도<pre><code class="language-js">/**
* @param {number[][]} accounts
* @return {number}
*/
var maximumWealth = function(accounts) {
 let maxCount = 0
 accounts.forEach(account =&gt; {
     let sum = 0
     account.forEach((money) =&gt; {
         sum += money
     })
     maxCount = Math.max(maxCount, sum)
 })
 return maxCount
};</code></pre>
</li>
<li>두번째 시도 (더 간편히 할 수 있을거 같아서)<pre><code class="language-js">var maximumWealth = function(accounts) {
return Math.max(...accounts.map(account =&gt; {
 return account.reduce((sum, money) =&gt; sum + money, 0)
}))
};</code></pre>
</li>
</ol>
<p><em>Feedback은 언제나 환영입니다</em>🤗</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Leetcode - Rotate Array]]></title>
            <link>https://velog.io/@wanderer-s/Leetcode-Rotate-Array</link>
            <guid>https://velog.io/@wanderer-s/Leetcode-Rotate-Array</guid>
            <pubDate>Sun, 30 Jan 2022 14:32:52 GMT</pubDate>
            <description><![CDATA[<h2 id="problem">Problem</h2>
<p><a href="https://leetcode.com/problems/rotate-array/">Rotate Array</a>
Given an array, rotate the array to the right by <code>k</code> steps, where <code>k</code> is non-negative.</p>
<p>주어진 배열을 <code>k</code> 단계만큼 회전 시키세요. <code>k</code>는 양수 입니다</p>
<h4 id="example-1">Example 1:</h4>
<pre><code class="language-js">Input: nums = [1,2,3,4,5,6,7], k = 3
Output: [5,6,7,1,2,3,4]
Explanation:
rotate 1 steps to the right: [7,1,2,3,4,5,6]
rotate 2 steps to the right: [6,7,1,2,3,4,5]
rotate 3 steps to the right: [5,6,7,1,2,3,4]</code></pre>
<h4 id="example-2">Example 2:</h4>
<pre><code class="language-js">Input: nums = [-1,-100,3,99], k = 2
Output: [3,99,-1,-100]
Explanation: 
rotate 1 steps to the right: [99,-1,-100,3]
rotate 2 steps to the right: [3,99,-1,-100]</code></pre>
<h4 id="constraints">Constraints:</h4>
<ul>
<li><code>1 &lt;= nums.length &lt;= 10⁵</code></li>
<li><code>-2³¹ &lt;= nums[i] &lt;= 2³¹ - 1</code></li>
<li><code>0 &lt;= k &lt;= 10⁵</code></li>
</ul>
<h2 id="solution">Solution</h2>
<h4 id="javascript">JavaScript</h4>
<pre><code class="language-js">/**
 * @param {number[]} nums
 * @param {number} k
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var rotate = function(nums, k) {
    const size = nums.length
    const rest = k % size

    const tempArr = nums.splice(size - rest ,rest)
    nums.splice(0, 0, ...tempArr)
};</code></pre>
<p><em>Feedback은 언제나 환영입니다</em>🤗</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Leetcode - Maximum XOR of Two Numbers in an Array]]></title>
            <link>https://velog.io/@wanderer-s/Leetcode-Maximum-XOR-of-Two-Numbers-in-an-Array</link>
            <guid>https://velog.io/@wanderer-s/Leetcode-Maximum-XOR-of-Two-Numbers-in-an-Array</guid>
            <pubDate>Thu, 27 Jan 2022 15:26:28 GMT</pubDate>
            <description><![CDATA[<h2 id="problem">Problem</h2>
<p><a href="https://leetcode.com/problems/maximum-xor-of-two-numbers-in-an-array/">Maximum XOR of Two Numbers in an Array</a></p>
<p>Given an integer array <code>nums</code>, return <em>the maximum result of</em> <code>nums[i] XOR nums[j]</code>, where <code>0 &lt;= i &lt;= j &lt; n.</code></p>
<p>정주로 이루어진 배열 <code>nums</code>가 주어질 때<code>0 &lt;= i &lt;= j &lt; n.</code> 조건하에 <code>nums[i] XOR nums[j]</code>의 결과중 가장 큰 값을 구하시오. </p>
<h4 id="example-1">Example 1:</h4>
<pre><code class="language-js">Input: nums = [3,10,5,25,2,8]
Output: 28
Explanation: The maximum result is 5 XOR 25 = 28.</code></pre>
<h4 id="example-2">Example 2:</h4>
<pre><code class="language-js">Input: nums = [14,70,53,83,49,91,36,80,92,51,66,70]
Output: 127</code></pre>
<h4 id="constraints">Constraints:</h4>
<ul>
<li><code>1 &lt;= nums.length &lt;= 2 * 10⁵</code></li>
<li><code>0 &lt;= nums[i] &lt;= 2³¹ - 1</code></li>
</ul>
<h2 id="solution">Solution</h2>
<h4 id="javascript">JavaScript</h4>
<ol>
<li><p>첫번째 시도</p>
<pre><code class="language-js">/**
* @param {number[]} nums
* @return {number}
*/
var findMaximumXOR = function(nums) {
 let maxResult = 0
 for(let i = 0; i &lt; nums.length; i++) {
     for(let j = i + 1; j &lt; nums.length; j++) {
         const xorResult = nums[i] ^ nums[j]
         maxResult = Math.max(maxResult, xorResult)
     }
 }
 return maxResult
};</code></pre>
<p>안타깝게도 <span style="color:#E64646">Time Limit Exceeded</span>에 걸렸다
근데 최대값을 다 해봐야 한다고 생각했기에.. 방법을 더 강구해본 결과..!!</p>
</li>
<li><p>두번째 시도</p>
</li>
</ol>
<pre><code class="language-js">/**
 * @param {number[]} nums
 * @return {number}
 */
var findMaximumXOR = function(nums) {
    const sets = [...new Set(nums)] // set을 통해 중복되는 요소를 제거했다

    let maxResult = 0
    for(let i = 0; i &lt; sets.length; i++) {
        for(let j = i + 1; j &lt; sets.length; j++) {
            maxResult = Math.max(sets[i] ^ sets[j], maxResult)
        }
    }
    return maxResult
}</code></pre>
<p>비트연산자를 알 수 있었던 시간..!</p>
<p><em>Feedback은 언제나 환영입니다</em>🤗</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Leetcode - All Elements in Two Binary Search Trees]]></title>
            <link>https://velog.io/@wanderer-s/Leetcode-All-Elements-in-Two-Binary-Search-Trees</link>
            <guid>https://velog.io/@wanderer-s/Leetcode-All-Elements-in-Two-Binary-Search-Trees</guid>
            <pubDate>Wed, 26 Jan 2022 16:22:42 GMT</pubDate>
            <description><![CDATA[<h2 id="problem">Problem</h2>
<p><a href="https://leetcode.com/problems/all-elements-in-two-binary-search-trees/">All Elements in Two Binary Search Trees</a></p>
<p>Given two binary search trees <code>root1</code> and <code>root2</code>, return <em>a list containing all the integers from both trees sorted in <strong>ascending</strong> order.</em></p>
<p>주어진 두 이진 검색 트리 <code>root1</code>, <code>root2</code>의 정수들이 오름차순으로 정렬된 하나의 리스트를 반환하시오</p>
<h4 id="example-1">Example 1:</h4>
<p><img src="https://images.velog.io/images/wanderer-s/post/4f5fed6f-00f0-43da-913a-d2c3eded9c23/image.png" alt=""></p>
<pre><code class="language-js">Input: root1 = [2,1,4], root2 = [1,0,3]
Output: [0,1,1,2,3,4]</code></pre>
<h4 id="example-2">Example 2:</h4>
<p><img src="https://images.velog.io/images/wanderer-s/post/fd5f4c33-24ed-46e0-a68f-2799c4273003/image.png" alt=""></p>
<pre><code class="language-js">Input: root1 = [1,null,8], root2 = [8,1]
Output: [1,1,8,8]</code></pre>
<h4 id="constraints">Constraints:</h4>
<ul>
<li>The number of nodes in each tree is in the range [0, 5000].</li>
<li><code>-10⁵ &lt;= Node.val &lt;= 10⁵</code></li>
</ul>
<h2 id="solution">Solution</h2>
<h4 id="javascript">JavaScript</h4>
<pre><code class="language-js">/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root1
 * @param {TreeNode} root2
 * @return {number[]}
 */
var getAllElements = function(root1, root2) {
    const array1 = []
    const array2 = []

    //주어진 이진 트리를 두개의 array에 오름차순으로 정렬
    extractValues(root1, array1)
    extractValues(root2, array2)

    const resultArray = []

    let idx1 = idx2 = 0

    while(idx1 &lt; array1.length &amp;&amp; idx2 &lt; array2.length) {
      // 각 array를 비교해여 더 작은 수를 resultArray에 추가 후 idx +1
        array1[idx1] &lt; array2[idx2] ? resultArray.push(array1[idx1++]) : resultArray.push(array2[idx2++])
    }

  //상단의 반복문이 끝나면 array1 또는 array2에 값이 남아있기에 그걸 처리하기 위한 반복문
    while(idx1 &lt; array1.length) resultArray.push(array1[idx1++])
    while(idx2 &lt; array2.length) resultArray.push(array2[idx2++])

    return resultArray

    function extractValues(node, array) {
        if(!node) return
        extractValues(node.left, array)
        array.push(node.val)
        extractValues(node.right, array)
    }
};</code></pre>
<p><em>Feedback은 언제나 환영입니다</em>🤗</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Leetcode - Valid Mountain Array]]></title>
            <link>https://velog.io/@wanderer-s/Leetcode-Valid-Mountain-Array</link>
            <guid>https://velog.io/@wanderer-s/Leetcode-Valid-Mountain-Array</guid>
            <pubDate>Tue, 25 Jan 2022 17:27:54 GMT</pubDate>
            <description><![CDATA[<h2 id="problem">Problem</h2>
<p><a href="https://leetcode.com/problems/valid-mountain-array/">Valid Mountain Array</a>
Given an array of integers <code>arr</code>, return <em><code>true</code> if and only if it is a valid mountain array.</em>
주어진 정수 배열이 산 배열이면 <code>true</code>를 반환하시오</p>
<p>Recall that arr is a mountain array if and only if:
다음 경우에만 산 배열이라는 것을 기억할 것</p>
<ul>
<li><code>arr.length &gt;= 3</code></li>
<li>There exists some <code>i</code> with <code>0 &lt; i &lt; arr.length - 1</code> such that:<ul>
<li><code>arr[0] &lt; arr[1] &lt; ... &lt; arr[i - 1] &lt; arr[i]</code></li>
<li><code>arr[i] &gt; arr[i + 1] &gt; ... &gt; arr[arr.length - 1]</code>
<img src="https://images.velog.io/images/wanderer-s/post/e81cb8e5-9707-4d83-8b47-56f9bc428d7c/image.png" alt=""><h4 id="example-1">Example 1:</h4>
<pre><code class="language-js">Input: arr = [2,1]
Output: false</code></pre>
<h4 id="example-2">Example 2:</h4>
<pre><code class="language-js">Input: arr = [3,5,5]
Output: false</code></pre>
<h4 id="example-3">Example 3:</h4>
<pre><code class="language-js">Input: arr = [0,3,2,1]
Output: true</code></pre>
</li>
</ul>
</li>
</ul>
<h4 id="constraints">Constraints:</h4>
<ul>
<li><p><code>1 &lt;= arr.length &lt;= 10⁴</code></p>
</li>
<li><p><code>0 &lt;= arr[i] &lt;= 10⁴</code></p>
<h2 id="solution">Solution</h2>
<h4 id="javascript">JavaScript</h4>
<pre><code class="language-js">/**
* @param {number[]} arr
* @return {boolean}
*/
var validMountainArray = function(arr) {
  if(arr.length &lt; 3) return false // 길이가 3보다 작으면 산 배열이 아님

  const biggest_num = Math.max(...arr)
  const biggest_num_idx = arr.indexOf(biggest_num)

  // 가장 큰 수가 배열의 첫번째에 있거나 제일 마지막에 있으면 산 배열이 될 수 없음
  if(biggest_num_idx === 0 || biggest_num_idx === arr.length - 1) return false

  for(let i = 1; i &lt; arr.length; i++) {
      if( i &lt;= biggest_num_idx ) {
        // 가장 큰 수를 기준으로 분기점 (산 배열이니 오르락 내리락을 판단이 필요)
          if(arr[i - 1] &gt;= arr[i]) return false
      } else {
          if(arr[i - 1] &lt;= arr[i]) return false
      }
  }
  return true
};</code></pre>
<p>runtime 속도는 다른 사람들보다 좀 걸리는 편이지만 메모리 사용이 적은 방법이었다</p>
</li>
</ul>
<p><em>Feedback은 언제나 환영입니다</em>🤗</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Leetcode - Koko Eating Bananas]]></title>
            <link>https://velog.io/@wanderer-s/Leetcode-Koko-Eating-Bananas</link>
            <guid>https://velog.io/@wanderer-s/Leetcode-Koko-Eating-Bananas</guid>
            <pubDate>Thu, 20 Jan 2022 18:11:28 GMT</pubDate>
            <description><![CDATA[<h2 id="problem">Problem</h2>
<p><a href="https://leetcode.com/problems/koko-eating-bananas/">Koko Eating Bananas</a>
Koko loves to eat bananas. There are <code>n</code> piles of bananas, the <code>ith</code> pile has <code>piles[i]</code> bananas. The guards have gone and will come back in <code>h</code> hours.</p>
<p>koko는 바나나 먹는것을 정말 좋아한다. n개의 바나나 더미가 있고, <code>i</code>번째 바나나 더미에는 <code>piles[i]</code>개의 바나나가 있다.
경비원들은 <code>h</code>시간이 지나면 돌아온다.</p>
<p>Koko can decide her bananas-per-hour eating speed of <code>k</code>. Each hour, she chooses some pile of bananas and eats <code>k</code> bananas from that pile. If the pile has less than <code>k</code> bananas, she eats all of them instead and will not eat any more bananas during this hour.</p>
<p>koko는 바나나를 시간당 바나나를 먹는 속도 <code>k</code>를 정할 수 있다. 매 시간마다 그녀는 바나나 더미를 선택해서 <code>k</code>개의 바나나를 먹는다. 만약 바나나더미의 바나나 개수가 <code>k</code>보다 적다면, 그녀는 모든 바나나를 먹고 남은 시간동안 바나나를 더 이상 먹지 않는다</p>
<p>Koko likes to eat slowly but still wants to finish eating all the bananas before the guards return.</p>
<p>koko는 바나나를 천천히 먹기를 원하지만 경비원들이 돌아오기 전에 모든 바나나를 먹길 원한다. (욕심쟁이네)</p>
<p>Return <em>the minimum integer</em> <code>k</code> <em>such that she can eat all the bananas within</em> <code>h</code> hours.</p>
<p><code>h</code>시간 안에 그녀가 바나나를 전부 먹을 수 있는 최소한의 정수 <code>k</code>를 구하시오</p>
<h4 id="example-1">Example 1:</h4>
<pre><code class="language-js">Input: piles = [3,6,7,11], h = 8
Output: 4</code></pre>
<h4 id="example-2">Example 2:</h4>
<pre><code class="language-js">Input: piles = [30,11,23,4,20], h = 5
Output: 30</code></pre>
<h4 id="example-3">Example 3:</h4>
<pre><code class="language-js">Input: piles = [30,11,23,4,20], h = 6
Output: 23</code></pre>
<h4 id="constraints">Constraints:</h4>
<ul>
<li><p><code>1 &lt;= piles.length &lt;= 1 ** 4</code></p>
</li>
<li><p><code>piles.length &lt;= h &lt;= 1 ** 9</code></p>
</li>
<li><p><code>1 &lt;= piles[i] &lt;= 10 ** 9</code></p>
<h2 id="solution">Solution</h2>
<h4 id="javascript">JavaScript</h4>
<pre><code class="language-js">/**
* @param {number[]} piles
* @param {number} h
* @return {number}
*/
var minEatingSpeed = function(piles, h) {
  const pilesCount = piles.length
  let min = 1,
      max = Math.max(...piles),
      k = max
  if(pilesCount === h) {
    // 더미 개수와 주어진 시간이 같으면 시간 당 바나나더미 하나씩 먹었다는 의미
    // 따라서 더미중 가장 바나나가 많은 갯수가 K 가됨
      return max
  }

  function findTime(hourPerEat) {
    // 시간당 몇개를 먹는지 넣으면 총 시간을 찾아주는 함수
      return piles.reduce((time, banana) =&gt; {
        // 다 먹고 시간이 남아도 더 이상 먹지 않으니 Math.ceil로 올림 해주어야 함
          time += Math.ceil(banana/hourPerEat)
          return time
      }, 0)
  }
  // 이진탐색
  while(min &lt;= max) {
      const mid = Math.floor((max + min) / 2)

      if(findTime(mid) &lt;= h) {
          k = mid
          max = mid - 1
      } else {
          min = mid + 1
      }
  }
  return k
};</code></pre>
</li>
<li><p>Feedback은 언제나 환영입니다*🤗</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Leetcode - Binary Tree Level Order Traversal]]></title>
            <link>https://velog.io/@wanderer-s/Leetcode-Binary-Tree-Level-Order-Traversal</link>
            <guid>https://velog.io/@wanderer-s/Leetcode-Binary-Tree-Level-Order-Traversal</guid>
            <pubDate>Fri, 14 Jan 2022 13:32:34 GMT</pubDate>
            <description><![CDATA[<h2 id="problem">Problem</h2>
<p><a href="https://leetcode.com/problems/binary-tree-level-order-traversal/">Binary Tree Level Order Traversal</a></p>
<p>Given the <code>root</code> of a binary tree, return <em>the level order traversal of its nodes&#39; values.</em> (i.e., from left to right, level by level).</p>
<p>이진트리 root가 주어 졌을 때, 계층의 순서대로 순회하는 값을 구하시오.
(좌측부터 우측으로, 계층별로)</p>
<h4 id="example-1">Example 1:</h4>
<p><img src="https://images.velog.io/images/wanderer-s/post/bf40dcbb-0fde-468d-9fbb-4adad022c8c6/image.png" alt=""></p>
<pre><code class="language-js">Input: root = [3,9,20,null,null,15,7]
Output: [[3],[9,20],[15,7]]</code></pre>
<h4 id="example-2">Example 2:</h4>
<pre><code class="language-js">Input: root = [1]
Output: [[1]]</code></pre>
<h4 id="example-3">Example 3:</h4>
<pre><code class="language-js">Input: root = []
Output: []</code></pre>
<h4 id="constraints">Constraints:</h4>
<ul>
<li>The number of nodes in the tree is in the range <code>[0, 2000].</code></li>
<li>-1000 &lt;= Node.val &lt;= 1000<h2 id="solution">Solution</h2>
<h4 id="javascript">JavaScript</h4>
<pre><code class="language-js">/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
*     this.val = (val===undefined ? 0 : val)
*     this.left = (left===undefined ? null : left)
*     this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrder = function(root) {
  const result = []
  if(root === null) return result
  const queue = []
  queue.push(root)
  while(queue.length &gt; 0) {
      let levelSize = queue.length
      const currentLevel = []
      for(let i = 0; i &lt; levelSize; i++) {
         let currentNode = queue.shift()
         currentLevel.push(currentNode.val)
          if(currentNode.left !== null) queue.push(currentNode.left)
          if(currentNode.right !== null) queue.push(currentNode.right)
      }
      result.push(currentLevel)
  }
  return result</code></pre>
</li>
<li>Feedback은 언제나 환영입니다*🤗</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Programmers - 프린터]]></title>
            <link>https://velog.io/@wanderer-s/Programmers-%ED%94%84%EB%A6%B0%ED%84%B0</link>
            <guid>https://velog.io/@wanderer-s/Programmers-%ED%94%84%EB%A6%B0%ED%84%B0</guid>
            <pubDate>Tue, 11 Jan 2022 15:29:15 GMT</pubDate>
            <description><![CDATA[<h2 id="문제-설명">문제 설명</h2>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/42587">프린터</a>
일반적인 프린터는 인쇄 요청이 들어온 순서대로 인쇄합니다. 그렇기 때문에 중요한 문서가 나중에 인쇄될 수 있습니다. 이런 문제를 보완하기 위해 중요도가 높은 문서를 먼저 인쇄하는 프린터를 개발했습니다. 이 새롭게 개발한 프린터는 아래와 같은 방식으로 인쇄 작업을 수행합니다.</p>
<pre><code class="language-js">1. 인쇄 대기목록의 가장 앞에 있는 문서(J)를 대기목록에서 꺼냅니다.
2. 나머지 인쇄 대기목록에서 J보다 중요도가 높은 문서가 한 개라도 존재하면 J를 대기목록의 가장 마지막에 넣습니다.
3. 그렇지 않으면 J를 인쇄합니다.</code></pre>
<p>예를 들어, 4개의 문서(A, B, C, D)가 순서대로 인쇄 대기목록에 있고 중요도가 2 1 3 2 라면 C D A B 순으로 인쇄하게 됩니다.</p>
<p>내가 인쇄를 요청한 문서가 몇 번째로 인쇄되는지 알고 싶습니다. 위의 예에서 C는 1번째로, A는 3번째로 인쇄됩니다.</p>
<p>현재 대기목록에 있는 문서의 중요도가 순서대로 담긴 배열 priorities와 내가 인쇄를 요청한 문서가 현재 대기목록의 어떤 위치에 있는지를 알려주는 location이 매개변수로 주어질 때, 내가 인쇄를 요청한 문서가 몇 번째로 인쇄되는지 return 하도록 solution 함수를 작성해주세요.</p>
<p><strong>제한사항</strong></p>
<ul>
<li>현재 대기목록에는 1개 이상 100개 이하의 문서가 있습니다.</li>
<li>인쇄 작업의 중요도는 1~9로 표현하며 숫자가 클수록 중요하다는 뜻입니다.</li>
<li>location은 0 이상 (현재 대기목록에 있는 작업 수 -1) 이하의 값을 가지며 대기목록의 가장 앞에 있으면 0, 두 번째에 있으면 1로 표현합니다.</li>
</ul>
<p><strong>입출력 예</strong></p>
<table>
<thead>
<tr>
<th>priorities</th>
<th>location</th>
<th>return</th>
</tr>
</thead>
<tbody><tr>
<td>[2, 1, 3, 2]</td>
<td>2</td>
<td>1</td>
</tr>
<tr>
<td>[1, 1, 9, 1, 1, 1]</td>
<td>0</td>
<td>5</td>
</tr>
</tbody></table>
<p><strong>입출력 예 설명</strong>
예제 #1</p>
<p>문제에 나온 예와 같습니다.</p>
<p>예제 #2</p>
<p>6개의 문서(A, B, C, D, E, F)가 인쇄 대기목록에 있고 중요도가 1 1 9 1 1 1 이므로 C D E F A B 순으로 인쇄합니다.</p>
<h2 id="solution">Solution</h2>
<h4 id="javascript">JavaScript</h4>
<pre><code class="language-js">function solution(priorities, location) {
    let newArr = priorities.map((ele, index) =&gt; [ele, index])
    let length = priorities.length
    let printOrder = []

    while(printOrder.length &lt; length) {
        if(newArr[0][0] === Math.max(...newArr.map(ele =&gt; ele[0]))) {
            printOrder.push(newArr.shift())
        } else {
            newArr.push(newArr.shift())
        }
    }
    return printOrder.findIndex(ele =&gt; ele[1] === location) + 1
}</code></pre>
<p><em>Feedback은 언제나 환영입니다</em>🤗</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[그런 REST API로 괜찮은가]]></title>
            <link>https://velog.io/@wanderer-s/%EA%B7%B8%EB%9F%B0-REST-API%EB%A1%9C-%EA%B4%9C%EC%B0%AE%EC%9D%80%EA%B0%80-ncgtasiy</link>
            <guid>https://velog.io/@wanderer-s/%EA%B7%B8%EB%9F%B0-REST-API%EB%A1%9C-%EA%B4%9C%EC%B0%AE%EC%9D%80%EA%B0%80-ncgtasiy</guid>
            <pubDate>Thu, 06 Jan 2022 16:22:16 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>DEVIEW 2017의 <a href="https://tv.naver.com/v/2292653#comment_focus">그런 REST API로 괜찮은가</a>를 보고 정리한 내용입니다</p>
</blockquote>
<h1 id="rest란">REST란?</h1>
<h2 id="span-stylecolore64646respanpresetational-span-stylecolore64646sspantate-span-stylecolore64646tspanransfer"><span style="color:#E64646"><strong>Re</span>presetational <span style="color:#E64646">S</span>tate <span style="color:#E64646">T</span>ransfer</strong></h2>
<blockquote>
<p>Representational state transfer (REST) is a software architectural style that was created to guide the design and development of the architecture for the World Wide Web.<br><br>World Wide Web의 개발과 디자인을 위한 아키텍쳐 스타일
<a href="https://en.wikipedia.org/wiki/Representational_state_transfer">Representational state transfer</a></p>
</blockquote>
<p>해당 영상에서는 <em>분산 하이퍼미디어 시스템(Web)을 위한 아키텍쳐 스타일</em> 이라고 말하며 이것만 보면 감이 전혀 잡히지 않는다
그래서 단순히 쓰여진 영어 단어만 보게되면 아래와 같다</p>
<p><strong>Representational</strong> - 묘사한, 표현한, 나타낸
<strong>State</strong> - 상태
<strong>Transfer</strong> - 이전, 이동, 이송</p>
<p>따라서 위의 내용과 영어단어만을 보고 유추 해보자면 Web에서 data를 전송할 때 상태를 나타내는 방식? 이라고 일단 생각하고 다음으로 넘어가자
여기서 중요한건 data가 상태를 표현 한다는 것!</p>
<h2 id="rest가-나온-배경">REST가 나온 배경</h2>
<p><em>인터넷으로 어떻게 하면 정보를 잘 공유할 수 있을까?</em> 의 대한 해답으로 WWW가 Tim Berners-Lee에 의해 탄생한다 (심지어 이사람은 물리학자)
<img src="https://images.velog.io/images/wanderer-s/post/34d0b9b4-7593-427f-a156-d509fe16f3a2/image.png" alt=""></p>
<p>WWW로 풀어낸 해결책은 <strong>정보들을 하이퍼텍스트로 연결한다!!</strong></p>
<ul>
<li>표현 형식: HTML</li>
<li>식별자 : URI</li>
<li>전송방법: HTTP</li>
</ul>
<p>여기서 Roy T. Fielding 이라는 사람이 나오는데 이미 HTTP가 web의 전송 프로토콜로 이용되고 있는 시점에서 HTTP 1.0 설계에 참여하게 된다. (당시 대학원생)
<img src="https://images.velog.io/images/wanderer-s/post/53b7d102-418e-4f63-b47b-278e8ce2b8fb/image.png" alt=""></p>
<blockquote>
<p>&quot;How do I improve HTTP without breaking the Web&quot;</p>
</blockquote>
<p>Roy가 해결책으로 제시한 것은 <strong>HTTP object model</strong> 이며 이것을 1998년도에 <strong>REST</strong>라는 이름으로 발표를 하게 되고 2년 후 2000년에
박사 논문(<a href="https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm">Architectural styles and the design of network-based software architectures</a>)까지 발표한다. </p>
<h2 id="api">API</h2>
<p>Microsoft가 원격으로 다른 시스템의 메소드를 호출 할 수 있는 <strong>XML-RPC</strong> 라는 프로토콜을 만드는데(1998) 이게 나중에 <strong>SOAP</strong> 이라는 이름으로 바뀐다.
이 후 2000년도에 Salesforce 라는 회사에서 API를 공개하는 데 이러한 느낌이다.
<img src="https://images.velog.io/images/wanderer-s/post/4039e70f-b2df-4c23-b2bf-e37ab5673fa6/image.png" alt="">
이것만 딱 봐도 복잡해서 쓰기 힘들거 같다(와우 urn을 쓰네)</p>
<p>그런데 4년 후 2004년에 flickr(와 내가 쓰는 그 <a href="https://www.flickr.com/photos/tags/history/">flickr</a>인가 신기하다)에서 SOAP과 REST라는 이름으로 다양한 API를 발표한다</p>
<p><strong>SOAP</strong>
<img src="https://images.velog.io/images/wanderer-s/post/e27a7aca-f545-468a-b04e-3f37764b5ef1/image.png" alt="">
<strong>REST</strong>
<img src="https://images.velog.io/images/wanderer-s/post/1fcf922a-7d12-4da8-924e-e7ce9653c0d6/image.png" alt="">
딱 봐도 SOAP에 비해서 훨신 간단해 보인다.
자연스럽게 SOAP의 사용량은 점점 줄어들고 REST의 사용량은 증가하게 된다.
<img src="https://images.velog.io/images/wanderer-s/post/e0d95031-e5b4-4716-b0f3-47e610096a4a/image.png" alt=""></p>
<p>Microsoft에서 2016년 REST API Guidelines을 만들었다.</p>
<ul>
<li>URI는 https://{serviceRoot}/{collection}/{id} 형식이어야 한다</li>
<li>GET, PUT, DELETE, POST, HEAD, PATCH, OPTION 를 지원해야 한다</li>
<li>etc..</li>
</ul>
<p>내용은 보통 우리가 생각하는 REST API의 구성으로 되어있으나 정작 REST를 정립한 Roy는 이것은 REST API가 아니니까 HTTP API라고 해야 된다고 했다.
<strong>사람들이 생각하는 REST와 Roy Fielding이 생각하는 REST가 다르다..!?</strong></p>
<h1 id="rest-api">REST API</h1>
<p>REST가 무엇인지는 위에서 대강 다루었다.
<strong>World Wide Web의 개발과 디자인을 위한 아키텍쳐 스타일</strong> 또는 <strong>분산 하이퍼미디어 시스템(Web)을 위한 아키텍쳐 스타일</strong>
그러면 아키텍쳐 스타일이란? 제약조건들의 집합이며 제약조건을 다 지켜야 한다
따라서 REST API란 REST의 제약조건을 모두 지키는 API를 일컫는다</p>
<h2 id="rest-구성하는-스타일">REST 구성하는 스타일</h2>
<ul>
<li>client-server</li>
<li>stateless</li>
<li>cache</li>
<li><span style="color:#E64646">uniform interface</span></li>
<li>layered system</li>
<li>code-on-demand(optional): 서버에서 코드를 클라이언트로 보내서 실행 하는 것</li>
</ul>
<p>HTTP만 따라도 언급된 제약조건의 대부분을 지킬 수 있는데 이 중에서 보통 uniform interface가 지켜지지 않아 Roy가 이를 REST라고 인정하지 않고 있다.</p>
<h3 id="uniform-interface">Uniform Interface</h3>
<ul>
<li>identification of resources 식별 가능한 자원</li>
<li>manipulation of resources through representations </li>
<li><span style="color:#E64646"><em>self-descriptive message</em></span></li>
<li><span style="color:#E64646"><em>HATEOAS</em></span></li>
</ul>
<p>이 중에서 세번째, 네번째 제약조건들이 지켜지지 못하고있는 실정이다.</p>
<h4 id="identification-of-resources">Identification of Resources</h4>
<p>식별가능한 자원</p>
<pre><code>GET /users/1 HTTP/1.1
Host: www.test.com</code></pre><p>id가 1인 user를 불러온다는 것으로 식별이 가능하다</p>
<h4 id="manipulation-of-resources-through-representations">Manipulation of Resources Through Representations</h4>
<p>묘사 또는 표현을 통한 자원의 조작</p>
<pre><code class="language-js">POST /users HTTP/1.1
Host: www.test.com
Content-Type: application/json

{
    &quot;username&quot; : &quot;hello&quot;
}</code></pre>
<pre><code class="language-js">DELETE /users/1 HTTP/1.1
Host: www.test.com</code></pre>
<p>POST 또는 DELETE로 자원의 조작을 표현하고 있다</p>
<h4 id="self-descriptive-message">self-descriptive message</h4>
<p>메세지는 스스로를 설명해야 한다</p>
<pre><code class="language-js">HTTP/1.1 200 OK
Content-Type: application/json

[ { &quot;op&quot; : &quot;remove&quot;, &quot;path&quot; : &quot;a/b/c/&quot; }]</code></pre>
<p>json이라는 형태는 주어졌으나 그것만으로는 &quot;op&quot;가 의미하는 것, &quot;path&quot;가 의미하는 것을 알 수가 없기에 아래와 같은 형태를 취해야한다</p>
<pre><code class="language-js">HTTP/1.1 200 OK
Content-Type: application/json-patch+json

[ { &quot;op&quot; : &quot;remove&quot;, &quot;path&quot; : &quot;a/b/c/&quot; }]</code></pre>
<p>현재 REST라고 일컬어 지는 API들은 media type을 단순히 json만을 명시하기 때문에 이것만 보고는 message를 해석 할 수 없으니 self-descriptive 하다고 할 수 없다.</p>
<h4 id="hateoas---hypermedia-as-the-engine-of-application-state">HATEOAS - Hypermedia as the Engine of Application State</h4>
<p>애플리케이션의 상태는 Hyperlink를 이용해 전이되어야 한다.
<img src="https://images.velog.io/images/wanderer-s/post/094cb3e4-497e-4575-8a97-fec05317d8d8/image.png" alt="">
메인페이지 -&gt; 글 목록보기 -&gt; 글 쓰기..... -&gt; 목록 얻기
와 같은 일련의 과정들이 페이지에 있는 링크를 따라서 상태가 전이되었기 때문에 HATEOAS라고 말할 수 있다.</p>
<pre><code class="language-html">HTTP/1.1 200 OK
Content-Type: text/html

&lt;html&gt;
    &lt;head&gt;&lt;/head&gt;
    &lt;body&gt;&lt;a href=&quot;/test&quot;&gt;test&lt;/a&gt;&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>HTML같은 경우 a tag로 하이퍼링크가 나와있고 이를 통해서 다음상태로 전이가 가능하기 때문에 HATEOAS가 만족된다</p>
<pre><code class="language-js">HTTP/1.1 200 OK
Content-Type: application/json
Link: &lt;/articles/1&gt;; rel=&quot;previous&quot;,
      &lt;/articles/3&gt;; rel=&quot;next&quot;;

{
  &quot;title&quot; : &quot;The second article&quot;,
  &quot;contents&quot;: &quot;This is the second articles... blah blah&quot;
}</code></pre>
<p>Link라는 header가 표준으로 문서가 나와있기 때문에 메세지를 이해할 수 있으며, 이 메세지를 통해서 이전 게시글 또는 다음 게시글의 링크로 상태전이가 가능하기에 json을 사용하더라도 HATEOAS가 만족된다. 단지 이렇게 사용되지 않을뿐</p>
<h3 id="왜-uniform-interface가-필요한가">왜 Uniform Interface가 필요한가</h3>
<h4 id="독립적-진화">독립적 진화</h4>
<p>서버와 클라이언트가 각각 독립적으로 진화한다. 따라서 서버의 기능이 변경되어도 클라이언트를 업데이트할 필요가 없다.
REST를 만든 계기가 *&quot;How do I improve HTTP without breaking the web&quot;* 이로부터 시작이 되었으며, 이 고민에 대해서 나온 결과가 REST이기 때문에 REST의 목적은 독립적인 진화이다.
독립적인 진화를 달성하기 위해서는 Uniform interface가 반듯이 만족이 되어야 한다</p>
<h3 id="실제로-잘-지켜지고-있는가">실제로 잘 지켜지고 있는가</h3>
<p>REST를 잘 지키고 있는 사례는 web이다.</p>
<ul>
<li>웹 페이지를 변경했다고 웹 브라우저를 업데이트 할 필요는 없다</li>
<li>웹 브라우저를 업데이트 했다고 웹 페이지를 변경할 필요도 없다</li>
<li>HTTP 명세가 변경되어도 웹은 잘 동작한다</li>
<li>HTML 명세가 변경되어도 웹은 잘 동작한다</li>
</ul>
<p>웹은 독립적으로 진화하고 있기에 REST는 성공이라고 볼 수 있다.</p>
<h2 id="rest-api는-왜-잘-안되나">REST API는 왜 잘 안되나?</h2>
<p>REST가 성공적인 web과 비교하면 아래와 같다</p>
<table>
<thead>
<tr>
<th></th>
<th>흔한 웹 페이지</th>
<th>HTTP API</th>
</tr>
</thead>
<tbody><tr>
<td>Protocol</td>
<td>HTTP</td>
<td>HTTP</td>
</tr>
<tr>
<td>Communication</td>
<td>사람 - 기계</td>
<td>기계 - 기계</td>
</tr>
<tr>
<td>Media Type</td>
<td>HTML</td>
<td>JSON</td>
</tr>
</tbody></table>
<p>웹 페이지는 사람이 보는 것이기에 communication방식이 프로그램간 이루어지는 API와 다를 수 밖에 없고 그러다 보니 media type도 서로 다르다.
따라서 media type이 REST API가 잘 안되는 원인이라고 유추할 수 있다</p>
<p>HTML과 JSON을 단순하게 비교하면 이렇다</p>
<table>
<thead>
<tr>
<th></th>
<th>HTML</th>
<th>JSON</th>
</tr>
</thead>
<tbody><tr>
<td>Hyperlink</td>
<td>됨 (a tag 등)</td>
<td>정의되어 있지 않음</td>
</tr>
<tr>
<td>Self-descriptive</td>
<td>됨 (HTML 명세)</td>
<td>불완전*</td>
</tr>
</tbody></table>
<p>self-descriptive가 불완전하기 때문에 메세지의 해석을 위해서는 별도의 문서가 필요하다.</p>
<h4 id="html">HTML</h4>
<pre><code class="language-HTML">GET /todos HTTP/1.1
Host: example.org

HTTP/1.1 200 OK
Content-Type: text/html

&lt;html&gt;
  &lt;body&gt;
    &lt;a href=&quot;https://todos/1&quot;&gt;회사 가기&lt;/a&gt;
    &lt;a href=&quot;https://todos/2&quot;&gt;집에 가기&lt;/a&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre>
<p><strong>self-descriptive 만족</strong></p>
<ol>
<li>응답 메세지의 Content-Type을 보고 media type이 text/html임을 확인</li>
<li>HTTP 명세에 media type은 IANA에 등록되어 있다고 하므로, IANA에서 test/html의 설명을 찾음</li>
<li>IANA 따르면 text/html의 명세는 <a href="http://www.w3.org/TR/html">http://www.w3.org/TR/html</a> 이므로 링크를 찾아가 명세를 해석 (엄청 타고타고 간다..)</li>
<li>명세에 모든 태그의 해석방법이 구체적으로 나와있으므로 이 메세지를 온전히 해석할 수 있다</li>
</ol>
<p><strong>HATEOAS 만족</strong></p>
<ol>
<li>a tag를 이용해 표현된 링크를 통해 다음 상태로 전이 가능</li>
</ol>
<h4 id="json">JSON</h4>
<pre><code class="language-js">GET /todos HTTP/1.1
Host: example.org

HTTP/1.1 200 OK
Content-Type: application/json

[
  {&quot;id&quot;: 1, &quot;title&quot;: &quot;회사 가기&quot;},
  {&quot;id&quot;: 2, &quot;title&quot;: &quot;집에 가기&quot;}
]</code></pre>
<p><strong>self-descriptive 충족 X</strong></p>
<ol>
<li>응답 메세지의 Content-Type을 보고 media type이 application/json임을 확인</li>
<li>HTTP 명세에 media type은 IANA에 등록되어 있다고 하므로, IANA에서 application/json의 설명을 찾음</li>
<li>IANA 따르면 application/json의 명세는 draft-ietf-jsonbis-rfc7159bis-04 이므로 링크를 찾아가 명세를 해석</li>
<li>명세에 json문서를 파싱하는 방법이 명시되어 있으므로 성공적으로 파싱에 성공한다. <strong>그러나 &quot;id&quot;가 무엇을 의미하고, &quot;title&quot;이 무엇을 의미하는지 알 방법이 없다</strong></li>
</ol>
<p><strong>HATEOAS 충족 X</strong></p>
<ol>
<li>다음 상태로 전이할 링크가 없다</li>
</ol>
<h3 id="rest를-꼭-따라야-하나">REST를 꼭 따라야 하나..?</h3>
<p><em>If you think you have control over the system or aren&#39;t interested in evolvability, don&#39;t waste your time arguing about REST<br>시스템 전체를 통제할 수 있다고 생각하거나, 진화에 관심이 없다면, REST에 대해 따지느라 시간을 낭비하지 마라</em></p>
<p>라고 Roy Fielding이 말했으니 필수로 따를 필요는 없으나 REST를 따르지 않으면서 REST API라고 하면 Roy가 싫어한다</p>
<h1 id="정리">정리</h1>
<ul>
<li>오늘날 대부분의 REST API는 사실 REST를 따르지 않고 있다</li>
<li>REST의 제약조건 중에서 self-descriptive와 HATEOAS를 만족하지 못한다</li>
<li>REST는 긴 시간에 걸쳐 진화하는 웹 애플리케이션을 위한 것이다</li>
<li>REST를 따를 것인지는 API를 설계하는 이들이 스스로 판단하여 결정해야한다</li>
</ul>
<hr>
<p>REST, RESTful 에 대해서 막연하게 알고만 있던것을 이 영상을 보면서 알게 되었고, 엄밀하게는 많은 사람들이 제대로 잘 쓰지 못하는 것도 알게되었다.
영상을 그냥 보는 것보다 확실히 정리를 하게되면서 이것저것 더 찾아보기도 하고, 글로 옮기는 과정에서 보다 더 정제된 채로 습득이 되는 느낌이다.</p>
<p>그동안 보았던 영상들도 다시 한번 보면서 정리를 해봐야겠다.</p>
<p>확실히 인터넷에는 좋은 자료들이 많다. 과거에 힘들게 공부하던 이전 세대보다 확실히 좋은 환경인것만은 분명하다.</p>
<p><strong>링크가 첨부된 영상을 꼭 보시길 권장합니다</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Programmers - 가장 큰 수]]></title>
            <link>https://velog.io/@wanderer-s/Programmers-%EA%B0%80%EC%9E%A5-%ED%81%B0-%EC%88%98</link>
            <guid>https://velog.io/@wanderer-s/Programmers-%EA%B0%80%EC%9E%A5-%ED%81%B0-%EC%88%98</guid>
            <pubDate>Wed, 05 Jan 2022 17:33:07 GMT</pubDate>
            <description><![CDATA[<h2 id="문제-설명">문제 설명</h2>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/42746">가장 큰 수</a>
0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요.</p>
<p>예를 들어, 주어진 정수가 [6, 10, 2]라면 [6102, 6210, 1062, 1026, 2610, 2106]를 만들 수 있고, 이중 가장 큰 수는 6210입니다.</p>
<p>0 또는 양의 정수가 담긴 배열 numbers가 매개변수로 주어질 때, 순서를 재배치하여 만들 수 있는 가장 큰 수를 문자열로 바꾸어 return 하도록 solution 함수를 작성해주세요.</p>
<p><strong>제한 사항</strong></p>
<ul>
<li>numbers의 길이는 1 이상 100,000 이하입니다.</li>
<li>numbers의 원소는 0 이상 1,000 이하입니다.</li>
<li>정답이 너무 클 수 있으니 문자열로 바꾸어 return 합니다.</li>
</ul>
<p><strong>입출력 예</strong></p>
<table>
<thead>
<tr>
<th>numbers</th>
<th>return</th>
</tr>
</thead>
<tbody><tr>
<td>[6, 10, 2]</td>
<td>&quot;6210&quot;</td>
</tr>
<tr>
<td>[3, 30, 34, 5, 9]</td>
<td>&quot;9534330&quot;</td>
</tr>
</tbody></table>
<h2 id="solution">Solution</h2>
<h4 id="javascript">JavaScript</h4>
<pre><code class="language-js">function solution(numbers) {
    // 1. numbers의 배열을 정열
    // 2. 정열한 순서대로 문자열화 하여 이어 붙인다

    // [3, 30, 34, 5, 9] 
    // 9 5 34 30 3
    // [9, 5, 34, 3, 30]
    // &#39;9534330&#39;

    let sortedNum = numbers.sort((a, b) =&gt; ((String(b) + String(a)) - (String(a) + String(b))))
    let result = sortedNum.join(&#39;&#39;)
    return result[0] === &#39;0&#39; ? &#39;0&#39; : result
}</code></pre>
<p><em>Feedback은 언제나 환영입니다</em>🤗</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Leetcode - Validate Binary Search Tree]]></title>
            <link>https://velog.io/@wanderer-s/Leetcode-Validate-Binary-Search-Tree</link>
            <guid>https://velog.io/@wanderer-s/Leetcode-Validate-Binary-Search-Tree</guid>
            <pubDate>Tue, 04 Jan 2022 14:28:56 GMT</pubDate>
            <description><![CDATA[<h2 id="problem">Problem</h2>
<p><a href="https://leetcode.com/problems/validate-binary-search-tree/">Validate Binary Search Tree</a>
Given the <code>root</code> of a binary tree, <em>determine if it is a valid binary search tree (BST).</em></p>
<p>주어진 이진트리가 유효한 지 밝혀내라</p>
<p>A <strong>valid BST</strong> is defined as follows:</p>
<ul>
<li>The left subtree of a node contains only nodes with keys <strong>less than</strong> the node&#39;s key.</li>
<li>The right subtree of a node contains only nodes with keys <strong>greater than</strong> the node&#39;s key.</li>
<li>Both the left and right subtrees must also be binary search trees.</li>
</ul>
<p><strong>유효한 이진트리</strong>는 다음의 규칙들을 충족한다</p>
<ul>
<li><p>노드의 좌측 하위 트리는 <strong>작은 노드의 값</strong>만 포함한다</p>
</li>
<li><p>노드의 우측 하위 트리는 <strong>큰 노드의 값</strong>만 포함한다</p>
</li>
<li><p>좌측과 우측 하위 트리 모두 이진트리여야 한다</p>
<h4 id="example-1">Example 1:</h4>
<p><img src="https://images.velog.io/images/wanderer-s/post/6722d6f9-27ed-4296-adbe-6318db13b7f2/tree1.jpg" alt=""></p>
<pre><code class="language-js">Input: root = [2,1,3]
Output: true</code></pre>
<h4 id="example-2">Example 2:</h4>
<p><img src="https://images.velog.io/images/wanderer-s/post/0cbbeadb-626d-44aa-9a3b-41974419108a/tree2.jpg" alt=""></p>
<pre><code class="language-js">Input: root = [5,1,4,null,null,3,6]
Output: false
Explanation: &quot;The root node&#39;s value is 5 but its right child&#39;s value is 4.&quot;</code></pre>
<h4 id="constraints">Constraints:</h4>
</li>
<li><p>The number of nodes in the tree is in the range <code>[1, 104].</code></p>
</li>
<li><p><code>-2³¹ &lt;= Node.val &lt;= 2³¹ - 1</code></p>
<h2 id="solution">Solution</h2>
<h4 id="javascript">JavaScript</h4>
<pre><code class="language-js">/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
*     this.val = (val===undefined ? 0 : val)
*     this.left = (left===undefined ? null : left)
*     this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {boolean}
*/
var isValidBST = function(root) {
//하위의 트리까지 모두 이진트리여야 하기 때문에 재귀로 접근
  return _isValidBST(root, -(2**31) - 1 , 2**31) // 제약조건에서 주어진 Node.val의 범위

  function _isValidBST(root, lower, higher) {
      if(!root) return true 

    // 위에 언급된 유효한 이진트리의 조건을 그대로 나열
      return root.val &gt; lower &amp;&amp; root.val &lt; higher &amp;&amp; _isValidBST(root.left, lower, root.val) &amp;&amp; _isValidBST(root.right, root.val, higher)
  }
};</code></pre>
</li>
<li><p>Feedback은 언제나 환영입니다*🤗</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[기본을 탄탄히]]></title>
            <link>https://velog.io/@wanderer-s/%EA%B8%B0%EB%B3%B8%EC%9D%84-%ED%83%84%ED%83%84%ED%9E%88</link>
            <guid>https://velog.io/@wanderer-s/%EA%B8%B0%EB%B3%B8%EC%9D%84-%ED%83%84%ED%83%84%ED%9E%88</guid>
            <pubDate>Mon, 03 Jan 2022 01:49:52 GMT</pubDate>
            <description><![CDATA[<p>최근 개발자 지인으로 부터 하나의 사진을 받았다
<img src="https://images.velog.io/images/wanderer-s/post/8aa86fd9-6994-4156-92f2-1a3f28bb0e1d/image.png" alt=""></p>
<p>뭐 하나 틀린말이 없다. 
한창 무협지에 빠져있을 때 기억이 새록새록 돋아나며
주인공 또는 주인공의 대척점에 있었던 인물의 칼질 한번, 주먹질 한번에 이름조차 나오지 않고 산화한 엑스트라들이 스쳐지나갔다.</p>
<p>나도 화산파가서 매화검법을 배우고 싶은데.. 아니면 사파도 좋은..
<img src="https://images.velog.io/images/wanderer-s/post/c3755793-957b-4adc-9568-deee438bc4e5/image.png" alt="">
생각해보면 모든 주인공들이 유명한 명문 소속은 아니었던 것으로 기억한다. 보통 기연을 얻지..
나에게 기연은 있는 것인가!!!!</p>
<p>어쨋든 주인공들은 기연을 얻든 말든 무공수련에 게으르지 않았다.
특히 기본기를 대충 떼우고 상승무공으로 넘어가는 다른 인물들과 달리 모든것의 근간이 된다며 기본기를 아주 탄탄하게 다지는 장면이 많이 나왔던 것으로 기억한다.</p>
<p>나에게도 언제 기연이 찾아올 지 모르니 기본기를 보다 더 탄탄하게 다져야 하지 않을까 하는 생각이 들었다.
아니면 기본기를 쌓는 도중 깨달음이 와서 절정고수가 되는 주인공같은 시나리오를 만들 수 있을까</p>
<p><strong>그렇다면 개발자에게 기본이란?</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[개발자 직업병인가]]></title>
            <link>https://velog.io/@wanderer-s/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%A7%81%EC%97%85%EB%B3%91%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@wanderer-s/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%A7%81%EC%97%85%EB%B3%91%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Sat, 01 Jan 2022 12:28:46 GMT</pubDate>
            <description><![CDATA[<h2 id="심야괴담회를-보다가">심야괴담회를 보다가</h2>
<p>설거지를 할 때 유튜브를 틀어놓고 이런저런 컨텐츠를 보는데 보통 <strong>심야괴담회</strong> 라는 프로를 자주 본다.
최근에도 이 심야괴담회를 보며 설거지를 하고 있었는데 한 사연을 듣다가 나도 개발자 다 됬구나 하는 생각이 드는 순간이 있었다</p>
<p><a href="https://www.youtube.com/watch?v=cSwxsq09y6s"><img src="https://img.youtube.com/vi/cSwxsq09y6s/0.jpg" alt="심야괴담회"></a>
<em>해당 사연의 영상. 그렇게 무섭지는 않지만 그래도 마음의 준비를 하고 보기를 권장!</em></p>
<h3 id="스포주의">스포주의</h3>
<p>해당 사연을 간추리자면
한 형제가 방학을 맞아 시골에 갔다가 한 산을 올라가게 되었다. 시골이라 해가 빨리 지기 때문에 집으로 다시 돌아가는 와중 사연의 주인공이 산 속에서 예쁜 누나가 이 형제를 바라보고 있는 것을 발견했다.
형에게 말했으나 형은 누가 있긴 있냐고 하며 어서 집으로 가자고 보챌뿐이었다.
그 예쁜 누나는 계속 형제들을 따라왔고, 어느 순간 마치 사냥감을 살피는 듯이 형제의 주위를 네발로 기며 맴돌기 시작했다.
집으로 돌아오지 않는 형제를 찾으러 온 아버지가 왔고 그 여자를 향해 총을 쏴버렸다. 총소리에 눈을 감았던 주인공이 눈을 뜨니 그 예쁜 누나는 사라져있었다.</p>
<p>사연의 주인공이 누나는 어디갔냐고 묻자. 형이 대답하길 사람의 형태가 아니였다고 대답했으며 그것을 들은 아버지도 같은 것을 봤다고 대답했다.</p>
<p>나중에 알고보니 사냥을 즐겨했던 아버지와 종종 아버지를 따라 사냥을 했던 형에겐 기괴한 모습으로 보였고 한번도 사냥을 따라가지 않았던 동생에게는 사람의 형태로 보인것이였다.</p>
<h3 id="조건부">조건부??</h3>
<p>이 사연을 듣자마자 든 생각은 <em>귀신이 조건부로 보이는 형태가 다르구만</em> 이였다.
다른 개발자들도 같은 생각을 하지 않았을까..? 나만 그런가..</p>
<p>생각이 든 김에 코드를 한번 써보자</p>
<pre><code class="language-js">class Person {
  constructor(huntExperience) {
    this.huntExperience = huntExperience
  }

  seeSomething(huntExperience) {
    if(this.huntExperience) {
      return &#39;a ghost&#39;
    } else {
      return &#39;a pretty girl&#39;
    }
  }
}

const father = new Person(true),
    olderBro = new Person(true),
    youngerBro = new Person(false)

father.seeSomething() // a ghost
olderBro.seeSomething() // a ghost
youngerBro.seeSomething() // a pretty girl
</code></pre>
<p>이것을 보다 전통적인 JavaScript의 Prototype 방식으로 해본다면</p>
<pre><code class="language-js">function Person(huntExperience) {
  this.huntExperience = huntExperience
}

Person.prototype.seeSomething = function() {
  if(this.huntExperience) {
      return &#39;a ghost&#39;
    } else {
      return &#39;a pretty girl&#39;
    }
}

const father = new Person(true),
    olderBro = new Person(true),
    youngerBro = new Person(false)

father.seeSomething() // a ghost
olderBro.seeSomething() // a ghost
youngerBro.seeSomething() // a pretty girl</code></pre>
<p>이렇게 할 수 있을거 같다.</p>
<h3 id="결론">결론</h3>
<p>사냥을 즐기지 말자 그러면 우리모두 이쁜 누나를 볼 수 있다!</p>
<h2 id="스파이더맨을-보고나서">스파이더맨을 보고나서</h2>
<p>이것은 예고편에도 등장하는 내용이라 스포가 아님을 명시한다 !!!</p>
<p>전편에서 미스테리오의 계락으로 정체가 까발려진 피터는 평범한 일상생활이 불가능해지고 자신이 사랑하는 사람들이 본인으로 인해 피해를 보는 것이 힘들어 닥터 스트레인지를 찾아간다.</p>
<p>*&quot;혹시 없던 일로 만들어 주시면 안되나요&quot;*</p>
<p>전우애가 솟아난 닥터 스트레인지는 전 세계의 모든 사람이 피터 파커는 스파이더맨이다 라는 사실을 잊게 마법 주문을 준비하는데..</p>
<p>*&quot; 잠깐만요.. 엠제이도 잊게되나요?
음.. 네드는 제 절친인데.. 메이는요?
아 해피도 있어요!! &quot;*</p>
<h3 id="느낀점">느낀점</h3>
<p><img src="https://images.velog.io/images/wanderer-s/post/640f700d-f2e4-4053-88a4-4c043fdb82f7/image.png" alt="">
개발도중에 자꾸 뭔가를 바꾸지 말자</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2021 회고]]></title>
            <link>https://velog.io/@wanderer-s/2021-%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@wanderer-s/2021-%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Fri, 31 Dec 2021 14:39:01 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/wanderer-s/post/2bf4bc28-e1f4-4b63-a3a8-19c96fab072c/image.png" alt=""></p>
<h1 id="2021년을-돌아보며">2021년을 돌아보며</h1>
<h2 id="그-놈의-코로나">그 놈의 코로나</h2>
<p>작년. 아니 재작년에 <strong>&quot;내년이면 끝나겠지&quot;</strong> 했던 그 코로나는 결국 끝나지 않았다. 어느새 외출 할 때 마스크가 없는게 이상할 정도로 마스크는 생활화되었고, 많은 회사들이 재택근무를 지향하여 나도 재택근무를 많이 하게 되었다. 사실 재택근무를 하게 되면 금전적 및 시간적으로 장점이 많다. 점심을 사먹어야 하는 식비와 출퇴근에 써야하는 교통비 그리고 통근시간들 특히 그 아침에 일어나서 잠에 취해서 씻고, 주섬주섬 옷을 입고 콩나물 시루 같은 지하철에 몸을 싣는 과정이 없는게 최고다.
<img src="https://images.velog.io/images/wanderer-s/post/e5e89a22-3a99-4f61-afd0-eac03900b3f2/image.png" alt="">
그래도 코로나는 끝났으면 좋겠다.. 제발.. 마스크 없이 나가서 숨좀 쉬어보자 🤦🏻</p>
<h2 id="아쉬운-프로젝트">아쉬운 프로젝트</h2>
<h3 id="첫-프로젝트">첫 프로젝트</h3>
<p>부트캠프를 통해 알게된 개발자 지인으로 부터 프로젝트 제의가 들어왔다. 뒤늦게 합류하는 거였고, 회사 업무와 개인 공부 그리고 집안 일과 병행 할 수 있을지 걱정했으나 부담갖지 않고 편하게 해도 된다는 말에 백엔드 개발자로 합류하게 되었다.</p>
<p>그런데 이미 프론트는 개발이 어느정도 진행된 상태였고, 백엔드는 이제 막 개발이 시작되는 단계였다. 프론트 개발자 분들이 백엔드 api를 사용할 수 있어야 한다는 생각에 마음이 조금 조급했는데 같이 백엔드를 맡으신 분은 회사 이슈로 거의 참여하지 못하셨서 결국에 혼자서 백엔드를 맡게 되었다.
혼자서 개발을 하다가 기획이 명확하지 않은 부분들을 프론트 개발자 분들과 조율을 하는 과정에서 프로젝트가 늘어지게 되었는데 안타깝게도 결국은 중간에 중단되고 말았다.
처음으로 시도했던 회사 밖의 프로젝트이며, 처음으로 typescript를 사용한 프로젝트라 많이 아쉬워 혼자서라도 한다고 팀원들한테 말했지만 사실상 중단된 프로젝트가 되었다.</p>
<p><strong>이 경험을 통해서 기획과 일정관리가 얼마나 중요한지 배울 수 있었다.</strong></p>
<p>사실 이 프로젝트를 한창 할 때는 typescript를 제대로 활용하지 못했다. 그래서 사용하면서도 너무 불편하다는 생각이 들었는데 협업 할 때는 역시 typescript가 짱짱맨이라는 걸 이제는 알게되었다.
<img src="https://images.velog.io/images/wanderer-s/post/457d73b9-26f3-4d8b-85db-e86444306692/image.png" alt=""></p>
<h3 id="두번째-프로젝트">두번째 프로젝트</h3>
<p>첫번째 프로젝트가 너무 지지부진 하여 두번째 프로젝트를 시작했다. 이 프로젝트는 서비스 아이디어 자체가 너무 매력적이였고 실제로도 있었으면 하는 서비스였기 때문에 의욕이 가득한 상태로 참여했다. 백엔드는 다른 개발자 한 분을 포함하여 총 2명이 맡기로 했고 NestJs로 개발을 하기로 하였고 우리는 업무 분장을 했으나.. 그 분이 갑자기 이탈을 하며 그 동안 작업한게 하나도 없다고 하는 바람에.. 🤭</p>
<p>새로운 백엔드 개발자분이 합류하셨고, 그 분은 역량이 엄청나신 분이였다. 그 분을 통해 프로젝트 참여자 모두가 많은 것들을 알게 되고 배울 수 있었던 것 같다. 그분처럼 역량을 키우고 싶어서 1대1로 많은 대화를 나누게 되었는데 좋은 회사를 가서 정말 좋은 분을 만났다는 얘기를 해주셨고, 좋은 회사로 이직을 시도하라는 조언도 해주셨다.</p>
<p>2개의 프로젝트를 해보니 회사를 다니면서 사이드 프로젝트를 하는 것이 쉽지 않다는 것을 알게 되었고, 끝까지 가지 못하고 중간에 엎어지는 프로젝트가 많다는 것도 알게되었다.
이 프로젝트는 끝까지 마무리가 잘 되었으면 좋겠고 그 끝에 나도 함께 하기를..!!!</p>
<h2 id="성장에-대한-갈증">성장에 대한 갈증</h2>
<p>다른 업종에서 일을 했었고, 개발을 전공으로 공부하지 않아 남들보다 뒤늦게 시작한것이 아닌가 하는 생각에 항상 성장에 대한 갈증이 있었다.
처음으로 입사한 회사에는 사수가 없었다. 아이러니하게도 그 덕분에 혼자서 문제를 해결해야 했기 때문에 그러한 경험은 개발자로써 좋은 자양분이 된다고 생각한다.
그렇지만 혼자서 개발을 하다보니 내가 작성한 코드가 좋은 코드로 짜여진 것인지, 성장하고 있는지 의문이 항상 나를 따라다녔다.</p>
<p>CTO님께 코드리뷰를 요청드린 적이 있었으나 회사 일정 상 코드리뷰는 어렵다고 하셨기에 어쩔 수 없이 혼자서 공부를 하는 수 밖에 없었다.
<img src="https://images.velog.io/images/wanderer-s/post/b9e75e2d-91dd-4274-be2c-3fe31af3687b/image.png" alt="">(나도 코드리뷰 좀.. 😢)</p>
<p>개인적으로 효율적인 코드, 깨끗한 코드에 대한 욕심이 있었기 때문에 <strong>로버트 마틴</strong>의 <a href="https://book.naver.com/bookdb/book_detail.naver?bid=7390287">Clean Code</a>를 구매했고 아직까지 다 읽지 못했다... (다음부터는 전자책이 아니고 종이책으로 사야겠다는 자기합리화)
그리고 <strong>마틴 파울러</strong>의 <a href="https://book.naver.com/bookdb/book_detail.nhn?bid=16311029">리팩터링 2판</a>을 종이책으로 구매해서 보고 있는데 우선은 Test code의 중요성을 알게되었다. 개인적으로 예제가 Javascript라는 점이 맘에 들어서 그런지 클린코드보다 뭔가 손이 더 자주 간다.(종이책이라서 그런 거일지도...) 계속해서 보다보면 내 코드가 개선되지 않을까 희망을 걸어본다.</p>
<p>혹시 JavaScript 로 개발을 하시는 분이 계신다면 꼭 한번 읽어보기를 강력하게 추천드린다.</p>
<p><a href="https://www.youtube.com/channel/UCSEOUzkGNCT_29EU_vnBYjg">개발바닥</a> 이라는 Youtube 채널을 알게 되었다. 😮 <a href="https://www.youtube.com/watch?v=V9AGvwPmnZU&amp;t=540s">이 영상</a>으로 알게 된 이동욱님이 언급했던 내용중 머리에 화살처럼 날아와 박힌 것이 있다.
<img src="https://images.velog.io/images/wanderer-s/post/8dc03490-514f-4da8-9891-aed850c698fd/image.png" alt=""></p>
<blockquote>
<p>&quot;좋은 개발자, 좋은 코드가 어떤 모습인지 알아야 하는데 접해 보지 않으면 좋은지 안좋은지도 모르게 된다.
좋은 코드를 짤 수 있는 사람의 가장 중요한 역량은 좋은 코드를 알아보는 눈이 먼저 있어야 하기 때문에, 이런것들에 대한 방향성을 제시해 줄 수 있는 좋은 선임이 있는 곳으로 가야한다&quot;</p>
</blockquote>
<p>더 더욱 좋은 개발자가 있는 좋은 회사에 가고 싶다는 생각이 강해졌다. 아니 가야만 한다!!!!!!
<img src="https://images.velog.io/images/wanderer-s/post/04befdc4-2186-4dc1-ada2-3de14cc6bdc4/image.png" alt="">
(인프랩 저를 데려가주세요!!)</p>
<p>그럴려면 또 공부를 해야하니.. 역시나 결론은 공부로 귀결되는 것 같다.
2021년도에 보았던 괜찮은 강의가 몇가지 있는데</p>
<ol>
<li>edwith의 <a href="https://www.edwith.org/cs50">컴퓨터 사이언스 CS 50</a></li>
<li>인프런의 <a href="https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC">모든 개발자를 위한 HTTP 웹 기본지식</a></li>
</ol>
<p>이 2가지 강의는 너무나도 감명깊게 보아서 특히 비전공자 주니어 분들이 보시면 너무나도 좋을 것 같다.</p>
<p>매일매일이 시험기간인것마냥 열심히 공부를 하는건 아니지만 그래도 꾸준히 공부를 하고있는 와중에 내가 공부하고 있는 이 방향이 맞는 것인지, 실무에서 어떤식으로 적용할 수 있을지 고민거리가 많은데</p>
<p>시작조차 늦은 상황에서 시간이 지나면서 연차는 쌓이는데 그 연차에 걸맞는 개발자가 되지 않을까하는 걱정도 가득하다.
2022년에는 좋은 선임이 있는 좋은 회사에 가서 이러한 고민거리가 조금 해결되는 한 해가 되기를 희망한다.</p>
<h2 id="새-가족">새 가족</h2>
<p>2021년에 가장 큰 변화라고 한다면 우리 집에 새 가족이 생긴 것이다.
마음의 준비가 제대로 되지 않은 상태에서 온 어마어마한 변화라서 초창기엔 정말 힘이 많이 들었다. 지금도 물론 힘이 들지만 인간이 적응의 동물이라는 것을 확실히 체감하고 있다.
하지만 절대적으로 잠잘 시간이 줄어버린 상태에서 회사 업무를 마치고 퇴근하고 집에 오면 체력과 에너지가 넘치는 녀석이 기다리고 있기에 정말 힘들다.
이러한 상황에서 사이드 프로젝트와 개인 공부까지 하려니 정말 죽을 맛이긴 한데.. 그래도 인간은 적응의 동물이니 이것도 적응이 되지 않을까 작은 기대를 해본다.
미리미리 운동으로 체력을 키워놨어야 하는건데.. 내년엔 운동도 꾸준히 해야겠다는 생각이 들면서도 그럴 시간이 있을지 또한 물음표가 따라온다.</p>
<h2 id="velog">velog</h2>
<p>온라인에 공개적으로 올리는 글은 잘 써야 하고, 완벽해야 한다는 생각에 velog를 거의 안했고 개인적으로 notion에 이것저것 끄적인 글만 가득해졌다.
하지만 그렇다보니 내가 쓴 글이지만 나중에 봤을 때 <em>이게 뭐지</em> 한 것들도 있고, 이력서에 블로그를 첨부할 수가 없게 되어 늦더라도 velog에 글을 꾸준히 올려보려고 한다.
그 마음가짐을 담아서 블로그 이름도 바꿔놓았다</p>
<blockquote>
<p>sin prisa pero sin pausa</p>
</blockquote>
<p>빠르지 않더라도 꾸준히 velog를 채워나갈 생각이다.</p>
<h1 id="2022년을-기대하며">2022년을 기대하며</h1>
<p>코로나의 종결로 마스크 없는 일상과, 좋은 회사에서 좋은 동료들과 함께 성장하는 내모습을 그리며 2021년의 회고는 여기까지 하려고 한다.
하루하루의 기억들이 모여서 &#39;내&#39;가 된다고 생각하기에 일기를 썼었는데 어느 새 부턴가 일기 쓰는 것을 중단하게 되었다. 그러다 보니 곱씹을 추억이 과거에 비해서 적어진 느낌이 든다.</p>
<p>2022년에는 매일은 아니더라도 종종 일기를 써야겠다는 생각이 든다.
일기와 함께 나의 성장도 꾸준히 쌓이기를 바래본다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Programmers - 위장]]></title>
            <link>https://velog.io/@wanderer-s/Programmers-%EC%9C%84%EC%9E%A5</link>
            <guid>https://velog.io/@wanderer-s/Programmers-%EC%9C%84%EC%9E%A5</guid>
            <pubDate>Tue, 28 Dec 2021 15:22:55 GMT</pubDate>
            <description><![CDATA[<h2 id="문제설명">문제설명</h2>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/42578">위장</a></p>
<p>스파이들은 매일 다른 옷을 조합하여 입어 자신을 위장합니다.</p>
<p>예를 들어 스파이가 가진 옷이 아래와 같고 오늘 스파이가 동그란 안경, 긴 코트, 파란색 티셔츠를 입었다면 다음날은 청바지를 추가로 입거나 동그란 안경 대신 검정 선글라스를 착용하거나 해야 합니다.</p>
<table>
<thead>
<tr>
<th>종류</th>
<th>이름</th>
</tr>
</thead>
<tbody><tr>
<td>얼굴</td>
<td>동그란 안경, 검정 선글라스</td>
</tr>
<tr>
<td>상의</td>
<td>파란색 티셔츠</td>
</tr>
<tr>
<td>하의</td>
<td>청바지</td>
</tr>
<tr>
<td>겉옷</td>
<td>긴 코트</td>
</tr>
<tr>
<td>스파이가 가진 의상들이 담긴 2차원 배열 clothes가 주어질 때 서로 다른 옷의 조합의 수를 return 하도록 solution 함수를 작성해주세요.</td>
<td></td>
</tr>
</tbody></table>
<p><strong>제한사항</strong></p>
<ul>
<li>clothes의 각 행은 [의상의 이름, 의상의 종류]로 이루어져 있습니다.</li>
<li>스파이가 가진 의상의 수는 1개 이상 30개 이하입니다.</li>
<li>같은 이름을 가진 의상은 존재하지 않습니다.</li>
<li>clothes의 모든 원소는 문자열로 이루어져 있습니다.</li>
<li>모든 문자열의 길이는 1 이상 20 이하인 자연수이고 알파벳 소문자 또는 &#39;_&#39; 로만 이루어져 있습니다.</li>
<li>스파이는 하루에 최소 한 개의 의상은 입습니다.</li>
</ul>
<p><strong>입출력 예</strong></p>
<table>
<thead>
<tr>
<th>clothes</th>
<th>return</th>
</tr>
</thead>
<tbody><tr>
<td>[[yellow_hat, headgear], [blue_sunglasses, eyewear], [green_turban, headgear]]</td>
<td>5</td>
</tr>
<tr>
<td>[[crow_mask, face], [blue_sunglasses, face], [smoky_makeup, face]]</td>
<td>3</td>
</tr>
</tbody></table>
<p><strong>입출력 예 설명</strong></p>
<p>예제 #1</p>
<p>headgear에 해당하는 의상이 yellow_hat, green_turban이고 eyewear에 해당하는 의상이 blue_sunglasses이므로 아래와 같이 5개의 조합이 가능합니다.</p>
<pre><code class="language-js">1. yellow_hat
2. blue_sunglasses
3. green_turban
4. yellow_hat + blue_sunglasses
5. green_turban + blue_sunglasses</code></pre>
<p>예제 #2</p>
<p>face에 해당하는 의상이 crow_mask, blue_sunglasses, smoky_makeup이므로 아래와 같이 3개의 조합이 가능합니다.</p>
<pre><code class="language-js">1. crow_mask
2. blue_sunglasses
3. smoky_makeup</code></pre>
<h2 id="solution">Solution</h2>
<h4 id="javascript">JavaScript</h4>
<pre><code class="language-js">function solution(clothes) {
    const clothes_obj = {}

    for(let content of clothes) {
        if(clothes_obj[content[1]]) {
            clothes_obj[content[1]] += 1
        } else {
            clothes_obj[content[1]] = 1
        }
    }

    console.log(Object.values(clothes_obj))
    return Object.values(clothes_obj).reduce((acc, curr) =&gt; {
        return acc * (curr + 1)
    }, 1) - 1
}</code></pre>
<p><em>Feedback은 언제나 환영입니다</em>🤗</p>
]]></description>
        </item>
    </channel>
</rss>