<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>MooMiz</title>
        <link>https://velog.io/</link>
        <description>밍구르기</description>
        <lastBuildDate>Sun, 13 Jul 2025 23:57:08 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>MooMiz</title>
            <url>https://velog.velcdn.com/images/moo_miz/profile/93d65cfd-aa81-4290-81e3-5a8261284fd8/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. MooMiz. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/moo_miz" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[Daily] Reset CSS와 Normalize CSS]]></title>
            <link>https://velog.io/@moo_miz/Daily-Reset-CSS%EC%99%80-Normalize-CSS</link>
            <guid>https://velog.io/@moo_miz/Daily-Reset-CSS%EC%99%80-Normalize-CSS</guid>
            <pubDate>Sun, 13 Jul 2025 23:57:08 GMT</pubDate>
            <description><![CDATA[<h2 id="reset-css와-normalize-css">Reset CSS와 Normalize CSS</h2>
<h3 id="용도-">용도 :</h3>
<p>브라우저 간의 스타일 차이를 줄이기 위해 사용되는 CSS 파일 </p>
<h3 id="reset-css--모든-브라우저의-기본-스타일을-완전히-제거하는-방식">Reset CSS : 모든 브라우저의 기본 스타일을 완전히 제거하는 방식</h3>
<pre><code>/* 모든 요소의 기본 스타일을 초기화 */
* {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
}</code></pre><p>장점 : 완전한 스타일 통일 
단점 : 모든 요소를 초기화 하기 때문에, 스타일을 새로 작성해야한다. 
사용 예시 : 디자인 시스템과 같이 모든 것을 직접 스타일링 하는 것이 중요한 상황 </p>
<h3 id="normalize-css--브라우저-간-스타일-차이를-줄이는데-중점을-둔-방식">Normalize CSS : 브라우저 간 스타일 차이를 줄이는데 중점을 둔 방식</h3>
<p>장점 : 모든 요소의 기본 스타일을 완전히 제거하지 않고, 일관 되지 않은 스타일만 수정한다.
단점 : 통일성이 비교적 떨어진다.
사용 예시 : 데드라인이 넉넉하지 않은 프로젝트 </p>
<pre><code>/* 브라우저 기본 스타일을 일관되게 유지 */
h1 {
  font-size: 2em;
  margin: 0.67em 0;
}
a {
  background-color: transparent;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Daily]HTML link 요소 rel 속성 값 preconnect, preload, prefetch ]]></title>
            <link>https://velog.io/@moo_miz/DailyHTML-link-%EC%9A%94%EC%86%8C-rel-%EC%86%8D%EC%84%B1-%EA%B0%92-preconnect-preload-prefetch</link>
            <guid>https://velog.io/@moo_miz/DailyHTML-link-%EC%9A%94%EC%86%8C-rel-%EC%86%8D%EC%84%B1-%EA%B0%92-preconnect-preload-prefetch</guid>
            <pubDate>Wed, 09 Jul 2025 00:27:41 GMT</pubDate>
            <description><![CDATA[<h2 id="link-요소">link 요소</h2>
<p>: 외부 리소스와의 연결을 돕는 요소, rel 속성 값인 preconnect , preload, prefetch는 리소스 로드의 우선순위를 설정하여 로드 성능을 최적화하기 위해 사용된다. </p>
<h3 id="1-preconnect">1. preconnect</h3>
<p>: 브라우저가 특정 origin에 대한 네트워크 연결을 미리 설정하도록 지시한다. 
→ DNS 조회, TLS 핸드셰이크, TCP 연결을 미리 완료하여 리소스 로드 지연을 줄일 수 있다. 
→ 외부 API나 CDN의 리소스를 사용할 경우에 사용하면 첫 번째 요청의 대기 시간을 줄일 수 있다. </p>
<pre><code>&lt;link rel=&quot;preconnect&quot; href=&quot;https://external-resource.com&quot; crossorigin=&quot;anonymous&quot;&gt;</code></pre><h3 id="2-preload">2. preload</h3>
<p>:특정 리소스를 미리 가져오도록 브라우저에 지시한다.
ex) 웹 폰트 preload → 리소스가 실제로 사용되기 전에 다운로드가 완료 된다. </p>
<pre><code>&lt;link rel=&quot;preload&quot; href=&quot;/fonts/my-font.woff2&quot; as=&quot;font&quot; crossorigin=&quot;anonymous&quot;&gt;</code></pre><h3 id="3-prefetch">3. prefetch</h3>
<p>: 브라우저가 향후 필요할 가능성이 있는 리소스를 미리 가져오도록 지시한다. 
→ preload와 다른점: 현재 화면에 즉시 필요하지 않지만 다음에 필요할 가능성이 있는 리소스를 미리 로드하는 역할을 한다.
→ 다른 속성 값에 비해 우선 순위가 낮다. </p>
<pre><code>  &lt;link rel=&quot;prefetch&quot; href=&quot;/next-page.css&quot; as=&quot;style&quot;&gt;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Daily] 쌓임 맥락에 대해 설명해주세요]]></title>
            <link>https://velog.io/@moo_miz/Daily-%EC%8C%93%EC%9E%84-%EB%A7%A5%EB%9D%BD%EC%97%90-%EB%8C%80%ED%95%B4-%EC%84%A4%EB%AA%85%ED%95%B4%EC%A3%BC%EC%84%B8%EC%9A%94</link>
            <guid>https://velog.io/@moo_miz/Daily-%EC%8C%93%EC%9E%84-%EB%A7%A5%EB%9D%BD%EC%97%90-%EB%8C%80%ED%95%B4-%EC%84%A4%EB%AA%85%ED%95%B4%EC%A3%BC%EC%84%B8%EC%9A%94</guid>
            <pubDate>Tue, 08 Jul 2025 01:57:34 GMT</pubDate>
            <description><![CDATA[<h2 id="쌓임-맥락stacking-context">쌓임 맥락(Stacking Context)</h2>
<p>: 가상의 z축을 상정하여 HTML 요소들을 3차원으로 개념화 한 것.</p>
<ul>
<li><p>요소들이 쌓이는 순서에 영향을 미친다. 
→ HTML 요소는 DOM 순서에 따라 쌓인다.
→ position 속성이 적용 되어 있는 요소들은 z-index 값이 낮을수록 아래쪽으로, 높을수록 위쪽으로 쌓인다.</p>
</li>
<li><p>특정 조건이 충족되면 새로운 쌓임 맥락이 생성된다. 
→ 독립적인 3차원 공간을 만들며, 부모 쌓임 맥락의 영향을 받지 않고 해당 쌓임 맥락 내에서만 비교가 이뤄진다. </p>
</li>
</ul>
<h3 id="쌓임-맥락이-생성되는-조건">쌓임 맥락이 생성되는 조건</h3>
<ul>
<li>position 속성이 relative 또는 absolute이고 z-index 값이 auto가 아닌 경우 </li>
<li>position 속성이 fixed 또는 sticky인 경우 </li>
<li>display가 flex 또는 grid이고, z-index가 설정 된 경우 </li>
<li>opacity 값이 1미만인 경우 </li>
<li>transform,filter, backdrip-filter 등의 속성이 적용되는 경우 </li>
</ul>
<pre><code>&lt;div style=&quot;position: relative; z-index: 1;&quot;&gt;
    A 요소 (z-index: 1)
    &lt;div style=&quot;position: absolute; z-index: 999;&quot;&gt;
        A-1 요소 (z-index: 999)
    &lt;/div&gt;
&lt;/div&gt;

&lt;div style=&quot;position: relative; z-index: 2;&quot;&gt;
    B 요소 (z-index: 2)
&lt;/div&gt;
</code></pre><p>(top) B 요소 → A-1 요소 → A 요소 (bottom)
 : Z-index 요소가 B가 가장 큼 , 쌓임 맥락 비교 A-1이 z-index 값이 더 크기 때문에 A-1 , 마지막으로 A 요소 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Daily] css - transform과 position]]></title>
            <link>https://velog.io/@moo_miz/Daily-css-transform%EA%B3%BC-position</link>
            <guid>https://velog.io/@moo_miz/Daily-css-transform%EA%B3%BC-position</guid>
            <pubDate>Wed, 02 Jul 2025 05:46:50 GMT</pubDate>
            <description><![CDATA[<h2 id="위치를-동적으로-변경할-때-css-속성-중-transform과-position-중-어떤-것을-선호-하시나요">위치를 동적으로 변경할 때 css 속성 중 transform과 position 중 어떤 것을 선호 하시나요?</h2>
<h3 id="transform----애니메이션이나-동적인-위치-변경이-필요한-경우">transform  - 애니메이션이나 동적인 위치 변경이 필요한 경우</h3>
<ul>
<li>선호하는 이유 ? <ul>
<li>성능이 중요한 상황 (ex: 모바일 환경)
→ 브라우저의 composite 단계에서 실행 
→ reflow나 repaint를 유발하지 않아 성능 상 이점이 있다.</li>
<li>애니메이션이나 빈번한 위치 변경이 필요할 때</li>
<li>다른 요소의 레이아웃에 영향을 주지 않아야 할 때</li>
</ul>
</li>
</ul>
<h3 id="position---레이아웃의-구조를-잡거나-부모를-기준으로-위치를-조정하는-경우">position - 레이아웃의 구조를 잡거나, 부모를 기준으로 위치를 조정하는 경우</h3>
<ul>
<li>정적인 레이아웃 구성 시 </li>
<li>요소의 위치 변경이 다른 요소의 레이아웃에 영향을 줘야 할 때 </li>
<li>복잡한 레이아웃 구조에서 요소를 배치할 때 </li>
<li>reflow와 repaint를 유발한다.
→ top, left 등의 속성을 변경하면 브라우저는 주변 요소들의 위치를 다시 계산하는 과정부터 다시 수행 
→ 성능 부하를 높힌다. </li>
</ul>
<h3 id="transform-과-position의-차이점">transform 과 position의 차이점</h3>
<ol>
<li>렌더링 과정의 차이점 </li>
</ol>
<ul>
<li><p>렌더링 과정</p>
<ul>
<li>** Layout(Reflow)** : 요소의 크기와 위치 계산 (position 처리 단계) </li>
<li>** Paint ** : 색상, 이미지, 테두리 등을 그림</li>
<li>** Composite**: 여러 레이어를 합성 (transform 처리 단계)</li>
</ul>
</li>
<li><p>예시</p>
<ul>
<li>html<pre><code class="language-html">&lt;div class=&quot;container&quot;&gt;
&lt;div class=&quot;box translate&quot;&gt;Translate&lt;/div&gt;
&lt;div class=&quot;box position&quot;&gt;Position&lt;/div&gt;
&lt;/div&gt;</code></pre>
</li>
<li>css<pre><code class="language-css">.box {
width: 100px;
height: 100px;
background-color: #3498db;
display: flex;
justify-content: center;
align-items: center;
color: white;
cursor: pointer;
}
</code></pre>
</li>
</ul>
<p>.translate {
  transition: transform 0.3s ease;
}</p>
<p>.translate:hover {
  transform: translateY(30px);
}</p>
<p>.position {
  position: relative;
  transition: top 0.3s ease;
}</p>
<p>.position:hover {
  top: 30px;
}</p>
<pre><code>
* translate 박스 
  * composition 레이어에서만 변화가 일어난다. → 다른 요소의 레이아웃에 영향을 주지 않는다.
* position 박스 
  * Layout 단계부터 다시 계산이 시작 된다. → 주변 요소의 레이아웃에 영향을 줄 수 있다. 

</code></pre></li>
</ul>
<p> 출처:</p>
<ul>
<li>매일메일 - 위치를 동적으로 변경할 때 css 속성 중 transform과 position 중 어떤 것을 선호 하시나요? </li>
<li><a href="https://www.books.weniv.co.kr/essentials-html-css/chapter15/15-1#1.6%20translate%20vs%20position">css transform</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Daily] CI/CD란? ]]></title>
            <link>https://velog.io/@moo_miz/Daily-CICD%EB%9E%80</link>
            <guid>https://velog.io/@moo_miz/Daily-CICD%EB%9E%80</guid>
            <pubDate>Tue, 01 Jul 2025 01:06:54 GMT</pubDate>
            <description><![CDATA[<h2 id="ci-continuous-integration">CI (Continuous Integration)</h2>
<p>: 지속적인 통합 </p>
<p>→ 개발자들이 코드 변경사항을 <strong>주기적</strong>으로 메인 브랜치에 병합하는 과정을 <strong>자동화</strong> 한 것. </p>
<p>→ 코드 변경 사항이 발생할 때 마다 자동으로 빌드와 테스트를 수행하여 문제를 조기에 발견 할 수 있다. </p>
<h2 id="cd-continuous-delivery-or-deployment">CD (Continuous Delivery or Deployment)</h2>
<p>: 지속적 전달 or 지속적 배포 </p>
<p>→  CI 이후 <strong>단계를 자동화</strong> 하는 것. 애플리케이션의 변경 사항을 production 환경으로 배포하는 과정을 자동화 한 것. </p>
<p>→ Continuous Delivery (지속적 전달) : 배포 가능한 상태로 준비하는 과정까지만 자동화 (실제 배포는 사람의 승인을 거쳐 수동 진행)</p>
<p>→ Continuous Deployment (지속적 배포) : 환경에서 배포하는 과정까지 자동화</p>
<h2 id="현업에서-사용-하는-cicd-도구">현업에서 사용 하는 CI/CD 도구</h2>
<p>: GitHub Actions, Jenkins, GitLab CI 드으이 도구를 사용하여 파이프라인을 구축합니다. 
→ 개발자가 PR을 올리면 자동으로 테스트 / 빌드 실행 
→ 테스트/빌드를 성공한 경우 메인 브랜치로의 머지 활성화 
→ 메인 브랜치 머지 시 production 환경으로 자동 배포 </p>
<p>출처:
매일메일 - CI/CD란 무엇인지 설명하시오 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Daily] CORS 설정 없이 SOP를 우회하여 외부 서버와 통신하는 방법]]></title>
            <link>https://velog.io/@moo_miz/Daily-CORS-%EC%84%A4%EC%A0%95-%EC%97%86%EC%9D%B4-SOP%EB%A5%BC-%EC%9A%B0%ED%9A%8C%ED%95%98%EC%97%AC-%EC%99%B8%EB%B6%80-%EC%84%9C%EB%B2%84%EC%99%80-%ED%86%B5%EC%8B%A0%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@moo_miz/Daily-CORS-%EC%84%A4%EC%A0%95-%EC%97%86%EC%9D%B4-SOP%EB%A5%BC-%EC%9A%B0%ED%9A%8C%ED%95%98%EC%97%AC-%EC%99%B8%EB%B6%80-%EC%84%9C%EB%B2%84%EC%99%80-%ED%86%B5%EC%8B%A0%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Fri, 27 Jun 2025 07:01:28 GMT</pubDate>
            <description><![CDATA[<h2 id="프록시-서버">프록시 서버</h2>
<p>: 브라우저 대신 외부 서버에 요청을 보내고 응답을 받는 역할을 대리 수행하는 서버.
브라우저 측에서 직접 외부 서버에 요청을 보내지 않고, 클라이언트와 동일한 origin의 프록시 서버를 통해 요청을 보내면 SOP의 제한을 피할 수 있다. </p>
<h2 id="cor-cross-origin-resource-sharing">COR (Cross-Origin Resource Sharing)</h2>
<p>: 서로 다른 출처라도 리소스 요청, 응답을 허용할 수 있도록 하는 정책 </p>
<ul>
<li><p>교차 출처 리소스 공유 </p>
</li>
<li><p>도메인(Hostname): myshop.com </p>
</li>
<li><p>출처 (Origin): <a href="https://www.myshop.com">https://www.myshop.com</a> 
<img src="https://velog.velcdn.com/images/moo_miz/post/b2abd6a0-309c-4999-95d4-ca57ade5f2d2/image.png" alt="">
=&gt; 출처가 다른 서버간의 리소스 공유 </p>
</li>
<li><p>예전에는 프론트 , 백을 따로 구성하지 않아서 모든 처리가 같은 도메인 안에서 가능했다.
→ 시간이 지나면서 클라이언트에서 API를 직접 호출하는 방식이 당연해짐 
→  클라이언트와 API는 다른 도메인 
=&gt; CORS 정책이 생김 (출처가 다르더라고 요청과 응답을 주고 받을 수 있도록 서버에 리소스 호출이 허용된 출처를 명시) </p>
<h3 id="cors-에러-대응법">CORS 에러 대응법</h3>
</li>
<li><ul>
<li>서버에서 Access-Control-Allow-Origin 응답 헤더 세팅하기 **</li>
</ul>
</li>
<li><p>서버에서 Access-Control-Allow-Origin 헤더를 설정해서 요청을 수락할 출처를 명시적으로 지정할 수 있다. </p>
</li>
<li><p>해당 해더를 세팅하면 출처가 다르더라도 <a href="https://myshop.com">https://myshop.com</a> 리소스 요청을 허용 가능하게 됨. </p>
<pre><code>&#39;Access-Control-Allow-Origin&#39;: &lt;origin&gt; | * // 보안 취약 </code></pre></li>
</ul>
<p><span style="background-color:#f5f5f5; color:#fa8072;"> * </span> 설정 →  출처에 상관없이 리소스에 접근할 수 있는 와일드카드이기 때문에 보안에 취약해진다.  </p>
<pre><code>&#39;Access-Control-Allow-Origin&#39;: https://myshop.com // 직접 허용할 출처 세팅 추천</code></pre><p>** 프록시 서버 사용 **
: 프록시 서버를 사용하여 웹 애플리케이션에서 리소스로의 요청을 전달하는 방법 
ex) 웹 어플리케이션 :<a href="http://example.com">http://example.com</a> <span style="background-color:#f5f5f5; color:#fa8072;">- 데이터 요청 -&gt;</span> <a href="http://api.example.com">http://api.example.com</a></p>
<pre><code>웹 애플리케이션 → http://example.com/api/proxy → (서버 내부 요청) → http://api.example.com</code></pre><ul>
<li>웹 애플리케이션 대신 같은 출처에 위치한 프락시 서버를 통해 API 요청을 중계하도록 구성한다. 
→  브라우저 입장에선 <a href="http://example.com%EC%97%90">http://example.com에</a> 요청한 것 처럼 보여서 CORS 검사 없이 응답 가능! <h3 id="sop">SOP</h3>
: 서로 다른 출처일 때 리소스 요청과 응답을 차단하는 정책 </li>
<li>SOP 부합 예시 
<img src="https://velog.velcdn.com/images/moo_miz/post/fa2b7e66-a740-4ebc-bc5b-e31292d971ab/image.png" alt=""></li>
</ul>
<h3 id="실무-때-겪은-cors---관련-에러">실무 때 겪은 CORS ?  관련 에러</h3>
<ul>
<li>문제 상황 :  작년에 로봇의 실시간 데이터를 주고 받는 UI를 개발하는 프로젝트를 수행 하였는데, 로봇 내의 로컬 배포를 해야 하는 상황에서 cors 에러를 마주한 상황이 있었다. 
노트북으로 로컬 배포한 페이지에 접속 했을 땐 사이트가 보였지만, 테블릿 or 다른 기기를 로봇 와이파이에 연결 후 접속 하였을 땐 CORS 에러로 사이트가 뜨지 않는 상황이 일어 났었다.</li>
</ul>
<ol>
<li><p>라이브러리 사용의 문제 </p>
<ul>
<li>nginx의 존재는 알았지만 모르는 프레임워크를 깔아서 책임 질 수 있을까? 에 대한 고민으로 <span style="background-color:#f5f5f5; color:#fa8072;"> http-proxy-middleware </span>라는 패키지를 사용 했는데, 로컬용이라 배포했을 때 동작을 하지 않는다는 답변을 들었다. ( 정적 파일을 배포하면 프록시 기능은 사라지고 그냥 브라우저 요청만 남게 됨) </li>
</ul>
</li>
<li><p>노트북에선 동일 출처로 인식하여 사용 가능 했음 </p>
</li>
<li><p>테블릿 -&gt; IP 주소: 포트 로 접속하여 다른 출처로 인식 -&gt; 에러 발생 </p>
</li>
</ol>
<ul>
<li>해결 방법 : nginx 사용 </li>
<li>nginx<ul>
<li>정적파일 제공 </li>
<li>프록시 서버 역할 가능 </li>
</ul>
</li>
</ul>
<p>출처 :
매일메일 서비스 (질문 출처)
<a href="https://docs.tosspayments.com/resources/glossary/cors#%ED%94%84%EB%9D%BD%EC%8B%9C-%EC%84%9C%EB%B2%84-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0">토스 - CORS(교차 출처 리소스 공유)</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Daily] css box-sizing 속성]]></title>
            <link>https://velog.io/@moo_miz/Daily-css-box-sizing-%EC%86%8D%EC%84%B1</link>
            <guid>https://velog.io/@moo_miz/Daily-css-box-sizing-%EC%86%8D%EC%84%B1</guid>
            <pubDate>Thu, 26 Jun 2025 03:01:34 GMT</pubDate>
            <description><![CDATA[<h1 id="box-sizing">box-sizing</h1>
<h2 id="-css에서-요소의-크기를-어떻게-계산-할-지를-결정하는-속성">: css에서 요소의 크기를 어떻게 계산 할 지를 결정하는 속성</h2>
<h3 id="1-box-sizing--content-box">1. box-sizing : content-box</h3>
<ul>
<li>content-box는 box-sizing 속성의 기본값</li>
<li>적용시 요소의 width와 height 값의 내용 영역만의 크기를 나타냅니다. </li>
<li><blockquote>
<p>width와 heigth는 요소의 실제 콘텐츠 크기만을 정의하고, 그 안에 추가되는 padding과 border는 크기에 포함되지 않습니다. </p>
</blockquote>
</li>
</ul>
<h3 id="2-box-sizing--border-box">2. box-sizing : border-box</h3>
<ul>
<li>border-box를 적용하면 width와 height 값이 내용영역, padding,border를 모두 포함하는 크기를 나타냅니다. </li>
<li>width와 height는 실제 콘텐츠의 크기뿐만 아니라 패딩과 테두리까지 포함된 크기로 설정된다.
ex ) width : 200px , padding: 20px, border: 2px 
=&gt;  실제 콘텐츠 영역의 크기: 200px - 20px * 2px * 2 = 156px</li>
<li>직관적으로 레이아웃의 크기를 예측하기 용이</li>
</ul>
<h3 id="예시">예시</h3>
<p><strong>HTML</strong></p>
<pre><code class="language-HTML">&lt;div class=&quot;content-box&quot;&gt;Content box&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;border-box&quot;&gt;Border box&lt;/div&gt;
</code></pre>
<p><strong>css</strong></p>
<pre><code class="language-css">
div {
  width: 160px;
  height: 80px;
  padding: 20px;
  border: 8px solid red;
  background: yellow;
}

.content-box {
  box-sizing: content-box;
  /* Total width: 160px + (2 * 20px) + (2 * 8px) = 216px
     Total height: 80px + (2 * 20px) + (2 * 8px) = 136px
     Content box width: 160px
     Content box height: 80px */
}

.border-box {
  box-sizing: border-box;
  /* Total width: 160px
     Total height: 80px
     Content box width: 160px - (2 * 20px) - (2 * 8px) = 104px
     Content box height: 80px - (2 * 20px) - (2 * 8px) = 24px */
}
</code></pre>
<p>결과
<img src="https://velog.velcdn.com/images/moo_miz/post/5cdf8b5f-8d0d-4a58-b254-509377dce3cf/image.png" alt=""></p>
<p>출처 : 
메일메일 -css box-sizing 속성에 대해 설명해주세요. 
<a href="https://developer.mozilla.org/ko/docs/Web/CSS/box-sizing">https://developer.mozilla.org/ko/docs/Web/CSS/box-sizing</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Daily] 이미지 포맷과 각 포맷별 특징 ]]></title>
            <link>https://velog.io/@moo_miz/Daily-%EC%9D%B4%EB%AF%B8%EC%A7%80-%ED%8F%AC%EB%A7%B7%EA%B3%BC-%EA%B0%81-%ED%8F%AC%EB%A7%B7%EB%B3%84-%ED%8A%B9%EC%A7%95</link>
            <guid>https://velog.io/@moo_miz/Daily-%EC%9D%B4%EB%AF%B8%EC%A7%80-%ED%8F%AC%EB%A7%B7%EA%B3%BC-%EA%B0%81-%ED%8F%AC%EB%A7%B7%EB%B3%84-%ED%8A%B9%EC%A7%95</guid>
            <pubDate>Wed, 25 Jun 2025 00:48:48 GMT</pubDate>
            <description><![CDATA[<h1 id="1-jpeg-joint-photographic-expert-group">1. JPEG (Joint Photographic Expert Group)</h1>
<ul>
<li>손실 압축 방식을 사용하는 이미지 포맷, 사진과 같이 복잡한 색상과 그라데이션이 있는 이미지에 적합하다. </li>
<li>장점<ul>
<li>파일 크기를 효율적으로 줄일 수 있다.</li>
</ul>
</li>
<li>단점 <ul>
<li>이미지를 저장할 때마다 데이터가 손실되어 화질이 점점 나빠지는 현상이 발생한다. </li>
</ul>
</li>
</ul>
<h1 id="2-pngportable-network-griphics">2. PNG(Portable Network Griphics)</h1>
<ul>
<li>무손실 압축 방식을 사용하는 이미지 포맷 </li>
<li>투명도를 지원한다. </li>
<li>JPEG보다 파일 크기가 크다. </li>
<li>회사 로고나 아이콘 같이 선명한 텍스트나 투명 색상이 있는 이미지에 적합하다. </li>
</ul>
<h1 id="3-webp">3. WebP</h1>
<ul>
<li>웹 환경을 위해 개발한 최신 이미지 포맷 </li>
<li>손실 / 무손실 압축 모두 지원, 투명도 지원 </li>
<li>JPEG나 PNG보다 더 나은 압축률을 제공하면서도 화질을 유지 할 수 있어 웹 최적화에 적합하다. </li>
<li>비교적 최신 포맷이기 때문에 지원하지 않는 브라우저가 존재한다. (호환성 문제 유의) 
<a href="https://developers.google.com/speed/webp/faq?hl=ko#:~:text=%EC%96%B4%EB%96%A4%20%EC%9B%B9%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EA%B0%80%20WebP%EB%A5%BC%20%EA%B8%B0%EB%B3%B8%EC%A0%81%EC%9C%BC%EB%A1%9C%20%EC%A7%80%EC%9B%90%ED%95%98%EB%82%98%EC%9A%94?%20*%20Chrome,%EC%9D%B4%EC%83%81%20(iOS%2014%20%EC%9D%B4%EC%83%81%2C%20macOS%20Big%20Sur+)">WebP 지원하는 웹 브라우저 목록</a></li>
</ul>
<h1 id="4-svg--scalable-vector-griphics">4. SVG ( Scalable Vector Griphics)</h1>
<ul>
<li>백터 기반의 이미지 포맷, 로고 아이콘 단순한 일러스트레이션에 사용된다. </li>
<li>XML 형식으로 이루어져 있다. </li>
<li>장점<ul>
<li>크기를 조절해도 이미지 품질 저하가 없다.</li>
<li>파일 크기가 작다.</li>
</ul>
</li>
<li>단점<ul>
<li>이미지 형태가 복잡할 경우, XML 기만의 코드가 매우 길어져 파일 크기가 커지고 연산이 무거워 진다.</li>
</ul>
</li>
</ul>
<p>출처:
매일 메일 - 알고 있는 이미지 포맷과 각 포맷별 특징을 알려주세요. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Daily] 클로저란? ]]></title>
            <link>https://velog.io/@moo_miz/Daily-%ED%81%B4%EB%A1%9C%EC%A0%80%EB%9E%80</link>
            <guid>https://velog.io/@moo_miz/Daily-%ED%81%B4%EB%A1%9C%EC%A0%80%EB%9E%80</guid>
            <pubDate>Tue, 24 Jun 2025 01:33:26 GMT</pubDate>
            <description><![CDATA[<h1 id="클로저">클로저</h1>
<blockquote>
<p>: 함수가 선언될 때의 스코프를 기억하여, 함수가 생성된 이후에도 그 스코프에 접근할 수 있는 기능 </p>
</blockquote>
<ul>
<li>*<em>스코프 (Scope): 단어 그대로 범위라는 의미를 가짐, 변수에 접근 할 수 있는 범위   *</em></li>
</ul>
<blockquote>
<p>클로저는 자바스크립트의 함수가 일급 객체라는 특성과 렉시컬 스코프의 조합으로 만들어 진다. </p>
</blockquote>
<ul>
<li>** 일급 객체: 다른 객체들에 일반적으로 적용 가능한 연산을 모드 지원하는 객체** <ul>
<li>일반적으로 적용 가능한 연산 :<ul>
<li>변수에 할당할 수 있다.</li>
<li>다른 함수를 인자로 전달 받는다.</li>
<li>다른 함수의 결과로서 리턴될 수 있다. </li>
</ul>
</li>
</ul>
</li>
</ul>
<ul>
<li><p>** 렉시컬 스코프(Lexical Scope): 함수를 어디서 선언했는지가 아닌 <em>함수를 어디에 선언 하였는지에 따라 결정되는 것</em>, 정적 스코프(Static scope)라 부르기도 함 **</p>
<ul>
<li>예시<pre><code class="language-js">let x = 1; // global 
</code></pre>
</li>
</ul>
<p>function first(){
 var x = 10; 
 second(); 
}</p>
<p>function second(){</p>
<pre><code>console.log(x);</code></pre><p>}</p>
<p>first();
second();</p>
<p>// 결과 : 1 1 </p>
<pre><code>
자바스크립트에서는 위와 같은 코드를 작성할 때 이미 실행 단계에세 코드들의 스코프를 결정한다. 
렉시컬 스코프를 따르기 때문에 함수를 선언한 시점에서 상위 스코프가 결정됨. 
**=&gt; 함수를 어디에서 호출하였는지는 스코프 결정에 아무런 의미를 주지 않는다. **
&lt;span style=&quot;background-color:#f5f5f5; color:#fa8072;&quot;&gt;second()&lt;/span&gt; 함수가 &lt;span style=&quot;background-color:#f5f5f5; color:#fa8072;&quot;&gt;first()&lt;/span&gt; 함수 안에서 호출 된 것과 상관 없이 &lt;span style=&quot;background-color:#f5f5f5; color:#fa8072;&quot;&gt;second()&lt;/span&gt; 함수는 global 범위에 선언 되어 있으므로, global 범위에 있는 변수 &lt;span style=&quot;background-color:#f5f5f5; color:#fa8072;&quot;&gt;x&lt;/span&gt;의 값 1이 두 번 출력된 것이다. 
</code></pre></li>
</ul>
<h3 id="클로저-예시-코드">클로저 예시 코드</h3>
<pre><code class="language-js">function outerFunction(outerVariable){
    return function innnerFunction(innerVariable){
        console.log(&#39;Outer Variable:&#39;+ outerVariable);
        console.log(&#39;Inner Variable:&#39;+ innerVariable);
    };
}

const newFunction = outerFunction(&#39;outside&#39;);
newFunction(&#39;inside&#39;);</code></pre>
<p>** 실행 흐름** </p>
<ol>
<li><span style="background-color:#f5f5f5; color:#fa8072;">outerFunction(&#39;outside&#39;)</span> 호출</li>
</ol>
<p>-&gt; <span style="background-color:#f5f5f5; color:#fa8072;">outerVariable</span>은 &#39;outside&#39;로 설정 
-&gt; 리턴값: <span style="background-color:#f5f5f5; color:#fa8072;">innerFunction</span>
2. <span style="background-color:#f5f5f5; color:#fa8072;">const newFunction = outerFunction(&#39;outside&#39;)</span>
-&gt; 이제 <span style="background-color:#f5f5f5; color:#fa8072;">newFunction</span>은 <span style="background-color:#f5f5f5; color:#fa8072;">innerFunction(innerVariable)</span>을 가리킴 
-&gt; <span style="background-color:#f5f5f5; color:#fa8072;">innerFunction</span>은 <span style="background-color:#f5f5f5; color:#fa8072;">outerVariable</span>이 무엇이었는지 기억함
3. <span style="background-color:#f5f5f5; color:#fa8072;">newFunction(&#39;inside&#39;)</span>호출 </p>
<pre><code class="language-js">  Outer Variable: outer
  Inner variable: inside</code></pre>
<p>** 클로저 동작 방식 : **</p>
<ul>
<li><span style="background-color:#f5f5f5; color:#fa8072;">innerFunction </span>은 <span style="background-color:#f5f5f5; color:#fa8072;">outerFunction </span>의 내부에 정의되어 있다. </li>
<li><span style="background-color:#f5f5f5; color:#fa8072;">innerFunction </span>은 자신이 생성된 스코프, 즉 <span style="background-color:#f5f5f5; color:#fa8072;">outerFunction </span>를 기억하고, <span style="background-color:#f5f5f5; color:#fa8072;">outerFunction </span>의 호출이 완료된 이후에도 그 스코프에 접근할 수 있습니다. </li>
<li>그리고 이에 따라 <span style="background-color:#f5f5f5; color:#fa8072;">innerFunction </span>은<span style="background-color:#f5f5f5; color:#fa8072;">outerFunction</span>에도 접근할 수 있습니다.</li>
</ul>
<p>=&gt; JavaScript는 함수가 return으로 다른 함수를 반환할 경우, 그 내부에서 사용된 외부 변수(= 자유 변수) 들을 함께 기억함.</p>
<h3 id="클로저의-활용">클로저의 활용</h3>
<blockquote>
<p>변수와 함수의 접근 범위를 제어하고 특정 데이터와 상태를 유지하기 위해 자주 활용 된다. </p>
</blockquote>
<ol>
<li>데이터 은닉 
: 클로저는 외부에서 접근 할 수 없는 비공개 변수와 함수를 만들 수 있다. </li>
</ol>
<p>-&gt; 데이터를 은닉하여 외부 접근을 막고, 데이터 무결성을 유지할 수 있다.
2. 비동기 작업
: 클로저는 비동기 작업에서 이전의 실행 컨텍스트를 유지해야 할 때 유용하다. 
-&gt; 콜백 함수가 비동기적으로 실행될 때 클로저를 사용하면 함수 실행 시점의 변수를 참조 할 수 있다. 
*예시</p>
<pre><code class="language-js">function createLogger(name){
    return function(){
          console.log(`Logger:${name}`);
    };
}
const logger = createLogger(&#39;MyApp&#39;)&#39;;
setTimeout(logger,1000); // 1초 후에 &#39;Logger: MyApp&#39; 출력</code></pre>
<ol start="3">
<li><p>모듈 패턴 구현
: 모듈 패턴은 특정 기능을 캡슐화하고, 외부에 공개하고자 하는 부분만 선택적으로 노출하여 코드의 응집력을 높이고, 유지보수성을 향상 시키는 패턴 
-&gt; 클로저를 활용하면 필요한 함수와 데이터만 외부로 노출함으로써 모듈 패턴을 쉽게 구현할 수 있다. </p>
<p>참고 및 출처: 
메일메일- 클로저란? </p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[면접 후기] 2023년 롯데e커머스 채용연계형 1차 코딩테스트 & 기술면접 후기! ]]></title>
            <link>https://velog.io/@moo_miz/2023%EB%85%84-%EB%A1%AF%EB%8D%B0e%EC%BB%A4%EB%A8%B8%EC%8A%A4-%EC%B1%84%EC%9A%A9%EC%97%B0%EA%B3%84%ED%98%95-1%EC%B0%A8-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B8%B0%EC%88%A0%EB%A9%B4%EC%A0%91-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@moo_miz/2023%EB%85%84-%EB%A1%AF%EB%8D%B0e%EC%BB%A4%EB%A8%B8%EC%8A%A4-%EC%B1%84%EC%9A%A9%EC%97%B0%EA%B3%84%ED%98%95-1%EC%B0%A8-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B8%B0%EC%88%A0%EB%A9%B4%EC%A0%91-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Mon, 16 Jun 2025 02:33:41 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/moo_miz/post/825dd0a4-aa61-4d02-a6d5-a9ed473f71cd/image.png" alt=""></p>
<p>7월 11일에 급하게 낸 서류가 붙었다..! </p>
<p>서류를 작성한 이유도 괜찮은 회사라고 생각해서 + 주 1~2회 이상 서류를 넣는 목표 달성을 위해 넣는다고 급하게 넣었는데 붙었다.. </p>
<p>공고에도 적혀있다 싶이 자바 수기 테스트가 마음에 걸려서 면접에 갈지 말지 엄청 고민하였다.
(필자는 java를 학습한 적이 한번도 없었다... ) </p>
<p>하지만 같이 교육을 들었던 친구들이 먼저 면접을 보고 와서 나에게 이야기 해준 것들이 고마웠고, 이 또한 경험이 될 것이란 판단이 들어 4시간을 걸쳐서 서울로 올라와 면접을 보았다. </p>
<p>결론적으로 누군가 왕복 8시간을 이동 할 만큼의 가치가 있는 면접이였는가? 를 묻는다면 아니라고 대답할 것이다. 
하지만 새로운 인간군상을 보는 것을 좋아하는 특성과 교육기관 밖의 다른 취준생들의 이야기를 들을 수 있는 경험으로는 좋았다고 생각한다! </p>
<h2 id="1차-면접-프로세스">1차 면접 프로세스</h2>
<blockquote>
<p>java 수기테스트 (1시간) - 대기(30분) - 단체 면접 (2시간) </p>
</blockquote>
<p>위와 같이 진행 되었고 </p>
<h3 id="1-java-수기테스트">1. java 수기테스트</h3>
<ul>
<li>후기 글 봤을 때 대학교 자바프로그래밍 기말고사 같다고 했었는데, 대학교 때 쳤던 시스템 프로그래밍 기말고사보다 쉬웠다고 생각한다.(자바를 물론 벼락치기로 급하게 공부해서 정확한 난이도 측정을 불가능 했지만)</li>
<li>또한 대기하는 동안 감독관 분께서(비트 컴퓨터 관계자 느낌)  면접 때 어떤 질문을 받을 것이고, 회장님(면접관)님의 기준을 말씀해주셨는데 자바(백엔드) 경험위주로 말하는게 좋다고 해주셨는데 경험 없어서 이 때부터 그냥 진행하고 있는 프로젝트 기능 어떤 방식으로 구현 할지 멍 때린것 같다.(필자는 프론트 경험 밖에 없다.) </li>
<li>알고리즘 관련 문제가 아닌 java 문법을 아느냐를 더 테스트 해보는 시험이였다. </li>
</ul>
<h3 id="2-대기">2. 대기</h3>
<ul>
<li>시험 끝나고 난 후 시험 친 곳에서 대기 하는데, 그 때 롯데 채용 담당자 분께서 들어오셔서 질문을 할 수 있는 시간이 있었다. </li>
<li>이 때 비트 컴퓨터는 롯데가 위탁교육을 맡긴 협업하는 곳이라 면접의 합불과 롯데 2차 합불 결과는 다를 수 있다는 말씀을 해주셨다. </li>
</ul>
<h3 id="3-단체면접">3. 단체면접</h3>
<ul>
<li><p>사실 악명 높은 면접으로 후기를 많이 들은 터라 서울에 갈지 말지 고민을 했었으나 이미 서울에 온 거 구경하자는 마음으로 면접을 보았다. </p>
</li>
<li><p>시작하기 전에 말씀해주시는데 면접하는 회장님 분의 기준치? 를 설명해주셨다.
(내년 면접 보는 분들도 들으실꺼라 예상하지만 프로젝트의 규모와 기술 스택? 을 많이 보는 느낌이였다) </p>
<ul>
<li>프로젝트 명과 기술 스택만 말하고 기능은 설명하지 말라고 하셨다. </li>
</ul>
</li>
<li><p>면접 순서가 앞 순서였기에 비전공자인 나에게 교육 어디서 받았는지 부터 물어보셔서 싸피를 언급 하였더니 거의 기계처럼 기간, 캠퍼스 등을 물어보셨다. </p>
<ul>
<li>그리고 안한걸 했다고 거짓말 하기 싫어서 프론트 경험을 이야기 했었는데,</li>
<li>텍스트 에디터, 뷰어 라이브러리 없이 구현 =&gt; 라이브러리 있는데 왜 굳이? </li>
<li>웰컴 페이지 =&gt; 토이프로젝트 규모아니냐</li>
<li>면접방 상세 페이지 =&gt; 라이브러리 다 사용하면 코드 치는게 있는가? </li>
</ul>
</li>
</ul>
<p>말씀 하셨고, 텍스트 에디터는 서비스 특성 상 블럭 형태로 구현해야했기에 기존의 나와 있는 라이브러리를 사용 할 수 없어 직접 구현하였다고 말씀 드렸고, 나머지는 솔직히 들었을 때 공통 특화 프로젝트를 하고 고민했던 점과 일치하여 인정하였다.</p>
<ul>
<li><p>그 후 빠르게 엑스표 친 서류가 왼쪽으로 갔다.</p>
</li>
<li><p>이 후 마음 편하게 지원자들의 이야기를 들었는데, </p>
<ul>
<li>전공자: 플젝 적게 했으면 혼남</li>
<li>비전공자: 교육없이 독학하면 말할 기회 없음 </li>
<li>싸피(백엔드): 다 들어보시긴 하나 다 있는건데 코드를 짠게 있냐는 질문을 하심 </li>
<li>타 국비교육: 국비교육의 레벨을 체크하시는 듯 함</li>
</ul>
<p>의 느낌이 들었다. </p>
<p>또한 다소 심하게 말씀을 들은 몇몇 분들의 멘탈도 조금 걱정 되었다. </p>
<p>(그것도 악명에 비해 그렇게 심하게 말씀하시진 않으니 너무 걱정은 안하셔도 될 듯 하다.)</p>
</li>
</ul>
<hr>
<p>엄청 옛날에 작성하고 안 올린건데 혹시 아직도 이 교육이 있는지 궁금하다.
혹시 있다면 참고하면 좋을꺼 같아서 올립니다~ </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[이해한 대로 적어보는 알고리즘(JS) - 2. BFS]]></title>
            <link>https://velog.io/@moo_miz/%EC%9D%B4%ED%95%B4%ED%95%9C-%EB%8C%80%EB%A1%9C-%EC%A0%81%EC%96%B4%EB%B3%B4%EB%8A%94-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98JS-2.-BFS</link>
            <guid>https://velog.io/@moo_miz/%EC%9D%B4%ED%95%B4%ED%95%9C-%EB%8C%80%EB%A1%9C-%EC%A0%81%EC%96%B4%EB%B3%B4%EB%8A%94-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98JS-2.-BFS</guid>
            <pubDate>Wed, 30 Apr 2025 02:05:21 GMT</pubDate>
            <description><![CDATA[<h1 id="1bfs를-알기-전에-필요한-개념">1.BFS를 알기 전에 필요한 개념</h1>
<h2 id="📖-그래프란">📖 그래프란?</h2>
<blockquote>
<p>여러 개의 노드(node)와 이들을 연결하는 간선(Edge)으로 이루어진 자료구조이다.</p>
</blockquote>
<h2 id="📖-queue란">📖 queue란?</h2>
<blockquote>
<p>한쪽 끝에서만 삽입이 이루어지고, 다른 한쪽 끝에서는 삭제 연산만 이루어 지는 유한 순서 리스트.
선입 선출, First in First Out(FIFO) 먼저 들어온 것이 먼저 나감! </p>
</blockquote>
<h1 id="2bfs-너비-우선-탐색-breadth-first-search">2.BFS (너비 우선 탐색, Breadth first Search)</h1>
<blockquote>
<p>시작점에서 가까운 정점부터 순서대로 방문하는 탐색 알고리즘 
<img src="https://velog.velcdn.com/images/moo_miz/post/be0a94c9-f27d-4118-a87d-76401a446a30/image.gif" alt=""></p>
</blockquote>
<h2 id="bfs-탐색-방법">BFS 탐색 방법</h2>
<ul>
<li><p>BFS는 시작점에서 가까운 정점부터 탐색하기 위해 방문이 필요한 노드를 큐에 담아놓고 하나씩 방문한다.
→ 1번을 시작으로 큐에 2,3,4번 노드를 담아놓는다.
( visited = [1] , queue = [2,3,4])
→ 큐에 가장 먼저 들어간 2번을 꺼내서 방문하고 2번 노드와 인접한 5번을 큐에 담는다.
( visited = [1,2], queue = [3,4,5])
→ 위와 같은 방법으로 먼저 들어간 노드 방문한 다음 해당 노드와 인접한 노드 큐에 담기 반복 
( visited = [1,2,3], queue = [ 4,5,6,7])
→ ( visited = [1,2,3,4] , queue = [5,6,7,8])
→ ( visited = [1,2,3,4,5] , queue = [6,7,8,9])
→ (visited = [1,2,3,4,5,6] , queue = [7,8,9,10])
→ 7,8,9,10번은 방문하지 않은 노드 중  인접한 노드가 없으므로 
→ (visited = [1,2,3,4,5,6,7] , queue = [8,9,10])
→ (visited = [1,2,3,4,5,6,7,8] , queue = [9,10])
→ (visited = [1,2,3,4,5,6,7,8,9] , queue = [10])
→ (visited = [1,2,3,4,5,6,7,8,9,10] , queue = [])</p>
</li>
<li><p>stack과 재귀 방식 둘 다 사용 가능한 DFS 와 달리 *<em>BFS는 큐를 사용해서 구현한다. *</em></p>
</li>
</ul>
<h2 id="bfs-알고리즘을-주로-사용하는-문제">BFS 알고리즘을 주로 사용하는 문제</h2>
<blockquote>
<p>최단거리 구하기 , 단계별 탐색 , 완전 탐색 (DFS보다 빠름) 등의 문제에서 사용할 수 있다. </p>
</blockquote>
<h2 id="bfs-코드-구현-js-버전">BFS 코드 구현 (JS 버전)</h2>
<ul>
<li>1편인 dfs 와 같은 인접 리스트? 형태의 graph 라고 생각해보자! <pre><code class="language-javascript">const graph = [[],[2,5,9],[1,3],[2,4],[3],[1,6,8],[5,7],[6],[5],[1,10],[9]]
// 리스트 자리수 : 연결된 노드
// 1번 노드 : [2,5,9] 번 노드와 연결 
</code></pre>
</li>
</ul>
<pre><code>bfs 코드 작성해보면 
```javascript
function bfs(graph,startNode){
    const visited = []; // 방문한 노드들 
      let needVisit = []; // 방문이 필요한 노드들 
      needVisit.push(startNode); // 처음 방문을 시작할 노드 

  while (needVisit !== 0){ // 1. 방문할 노드가 존재 한다면
      const node = needVisit.shift(); // 1. 선입선출(FIFO) 구조라 shift 함수 사용
      if(!visited.includes(node){
       visited.push(node)
          const nodes = graph[node].slice().sort((a,b) =&gt; a - b); // 복사 후 오름차순 정렬 
           needVisit = [...needVisit, ...nodes] ; // queue 형태를 사용하니까 나중에 방문할 데이터 쌓아 놓기 
       }

  }
  return visited 
}

bfs(graph,1)</code></pre><p>이런 구조로 흘러가게 된다 
근데 사실 위에 풀이는 백준의 <span style="background-color:#BDBDBD; color:white;">&amp;nbsp 1260.DFS와 BFS &amp;nbsp</span>문제를 풀때 사용했던 방식이라 문제에 따라 맞게 쓰는 풀이들도 적어 볼려고 한다! </p>
<h2 id="bfs-최단거리-문제-js-버전">BFS 최단거리 문제 (JS 버전)</h2>
<p>백준의 <span style="background-color:#BDBDBD; color:white;">&amp;nbsp 2178.미로탐색 &amp;nbsp</span> 문제를 예시로 들어보겠다. 
해당 문제는 시작점에서 도착 위치까지의 최단 거리를 구하는 문제이고, 1로 된 곳으로만 이동이 가능하다.  </p>
<pre><code class="language-javascript">const graph = [
  [ 1, 0, 1, 1, 1, 1 ],
  [ 1, 0, 1, 0, 1, 0 ],
  [ 1, 0, 1, 0, 1, 1 ],
  [ 1, 1, 1, 0, 1, 1 ]
]
const M = 6; // x 최대 길이 
const N = 4; // y 최대 길이 </code></pre>
<pre><code class="language-javascript">dx = [0,0,-1,1]; // 상하좌우 
dy = [-1,1,0,0]; // 상하좌우</code></pre>
<p><img src="https://velog.velcdn.com/images/moo_miz/post/ce5572d8-fda3-4711-8579-6a141140ca1b/image.png" alt="">
해당 표를 보면 기준 좌표(0,0)에 따라 이동할 값을 리스트 형태로 작성하였다. </p>
<pre><code class="language-javascript">function bfs(start_x,start_y,cnt){
  const queue = [];
  queue.push([start_x,start_y,cnt]); // 시작하는 x,y,cnt 값 큐에 담기

  while(queue.length!==0){ // 방문해야 할 위치가 큐에 담긴 경우
  const [x,y,cnt] = queue.shift(); // 가장 먼저 담겨있던 노드 꺼냄
  for(let i = 0; i&lt;4; i++){ // 상하좌우 탐색을 위한 for 문 
      const nx = x+dx[i]
    const ny = y+dy[i]
    if(nx&gt;=0 &amp;&amp; nx &lt; N &amp;&amp; ny &gt;= 0 &amp;&amp; ny &lt; M){ // graph 범위안에 들어오고  
      if(graph[nx][ny] == 1){ // 이동 가능한 구간인 경우 
          graph[nx][ny] = cnt+1 // 해당 칸에 누적 이동거리 + 1 을 해준다. 
          queue.push([nx,ny,cnt+1]) // 해당 위치에서 이동 가능한 곳이 있는지 확인하기 위해 queue에 담아준다. 
      }    
     }
      }
  }
 return graph[N-1][M-1] // 도착위치에 최단거리를 확인 할 수 있다. 
}
bfs(0,0,1)</code></pre>
<h2 id="✍️-후기">✍️ 후기</h2>
<ul>
<li>dfs 작성하고 bfs 문제도 어느정도 다 푼 상태에서 글을 작성하니까 이전 보다 좀 더 빨리 작성한 느낌이 들었다. </li>
<li>미래의 내가 안까먹었으면 좋겠지만.. 까먹었을 때 잘 참고해서 빨리 기억하길 바란다... </li>
<li>이전에는 개념을 덜 숙지한 상태에서 문제를 많이 풀어서 코테를 준비한것 같은데, 이번엔 개념 -&gt; 문제 순서의 정석으로 하니까 오히려 빠른거 같다는 생각이 들었다. 꾸준히 해야지! </li>
</ul>
<p> 출처: </p>
<ol>
<li><a href="https://developer-mac.tistory.com/64">https://developer-mac.tistory.com/64</a></li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[이해한 대로 적어보는 알고리즘(JS) - 1. 
DFS]]></title>
            <link>https://velog.io/@moo_miz/%EC%9D%B4%ED%95%B4%ED%95%9C-%EB%8C%80%EB%A1%9C-%EC%A0%81%EC%96%B4%EB%B3%B4%EB%8A%94-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98JS-1.-DFS</link>
            <guid>https://velog.io/@moo_miz/%EC%9D%B4%ED%95%B4%ED%95%9C-%EB%8C%80%EB%A1%9C-%EC%A0%81%EC%96%B4%EB%B3%B4%EB%8A%94-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98JS-1.-DFS</guid>
            <pubDate>Fri, 25 Apr 2025 07:04:21 GMT</pubDate>
            <description><![CDATA[<h1 id="1dfs를-알기-전에-필요한-개념">1.DFS를 알기 전에 필요한 개념</h1>
<h3 id="📖-그래프란">📖 그래프란?</h3>
<blockquote>
<p> 여러 개의 노드(node)와 이들을 연결하는 간선(Edge)으로 이루어진 자료구조이다. </p>
</blockquote>
<h3 id="📖--stack이란">📖  stack이란?</h3>
<blockquote>
<p> 한쪽 끝에서 자료를 넣거나 뺄 수 있는, 데이터를 제한적으로 접근할 수 있는 구조 ,
(LIFO)후입-선출 구조 : 뜻이 후입 (list끝) 선출(list 앞)아니라 list 끝에 넣고 최근에 넣은걸 뺀다는 뜻!</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/moo_miz/post/efe73e3d-a0dc-4cb3-9fab-0b864c151b91/image.png" alt=""></p>
<h3 id="📖--재귀-함수">📖  재귀 함수</h3>
<blockquote>
<p>함수 안에 자신의 함수를 다시 호출하는 함수를 의미한다. 
이러한 재귀함수는 자신의 로직을 내부적으로 반복하다가, 일정한 조건이 만족되면 함수를 이탈하여 결과를 도출한다. </p>
</blockquote>
<h2 id="2dfs-깊이-우선-탐색-depth-first-search란">2.DFS (깊이 우선 탐색, Depth-First Search)란?</h2>
<p><img src="https://velog.velcdn.com/images/moo_miz/post/b2c0f146-0547-4d72-9dcc-cfe7079ecba5/image.gif" alt=""></p>
<h3 id="dfs-탐색-방법">DFS 탐색 방법</h3>
<ul>
<li><p>DFS는 하나의 방향을 결정하면 그 방향을 따라 끝까지 도달한다. 
  해당 그림을 예시로 들면, 
  → 1번을 시작으로 인접한 2,5,9번 노드 중 왼쪽 노드 부터 탐색한다. 
  → 2번 노드와 인접한 3번 탐색 
  → 3번과 인접한 4번 탐색
  → 4번과 인접한 노드가 없으므로 이전 노드로 이동 (4-&gt;3-&gt;2-&gt;1)
  → 1번과 인접한 남은 노드 중 가장 왼쪽에 있는 5번 노드로 이동 
  → 5번 노드와 인접한 6,8번 중 왼쪽에 있는 6번 노드 탐색 
  → 6번 노드와 인접한 7번 노드를 탐색한다 
  → 7번과 인접한 노드가 없으므로 이전 노드로 이동 (7-&gt;6-&gt;5) 
  → 5번 노드와 인접한 노드 중 방문하지 못했던 8번 노드 방문 
  → 이전노드 (8-&gt;5-&gt;1) 로 이동하여 남은 9번 노드 방문 
  → 9번의 인접 노드인 10번 노드 방문 </p>
</li>
<li><p>그림을 보면 느낌이 오겠지만,stack을 사용해서도 구현이 가능하고 재귀 형태로도 구현이 가능하다! </p>
</li>
<li><p>효율면에서는 stack이 좀 더 좋지만, 재귀가 구현이 좀 더 쉽고 빠르다. </p>
</li>
</ul>
<h3 id="dfs-코드-구현-js-stack-버전">DFS 코드 구현 (JS Stack 버전)</h3>
<p>우선 해당 dfs 코드를 사용하기 위해선 graph가 필요한데, 
해당 보기 그래프를 리스트로 만들어보면 </p>
<pre><code class="language-javascript">const graph = [[],[2,5,9],[1,3],[2,4],[3],[1,6,8],[5,7],[6],[5],[1,10],[9]]
// 리스트 자리수 : 연결된 노드
// 1번 노드 : [2,5,9] 번 노드와 연결 </code></pre>
<p>해당 형태를 통해 인접리스트 형태의 그래프를 만들 수 있다. </p>
<pre><code class="language-javascript">function dfs(graph, startNode){
    const visited = [] // 방문한 노드들 
    let needVisit = [] // 방문이 필요한 노드들 

    needVisit.push(startNode) // 방문 시작할 노드 

    while(needVisit.length !==0){ // 방문할 노드가 존재한다면
    const node = needVisit.pop(); // DFS는 stack 사용 =&gt; LIFO(후입 선출)구조 
    if(!visited.includes(node)){ // 해당 노드에서 방문 한 적 없는 노드라면
        visited.push(node) //  방문 노드 처리 
        const nodes = graph[node].slice().sort((a, b) =&gt; b - a); // 복사 후 내림차순 정렬
        needVisit.push(...nodes);// 뒤에 추가 LIFO(후입 선출) 
     }
    }
   return visited;
}

dfs(graph, 1)</code></pre>
<p>방문 시작할 때 :visited = [], needVisit = [1] 
→ 방문할 노드 존재 (while문으로 들어감) : visited = [], needVisit = [1] 
→ DFS는 stack 사용 (LIFO(후입 선출)구조) :   node = 1 , visited = [], needVisit = []
→ 방문 노드 처리 -&gt; visited = [1] needVisit = []
→ 복사 후 내림차순 정렬 -&gt;nodes = [9,5,2], visited = [1], needVisit=[]
→ 뒤에 추가 LIFO(후입 선출) -&gt; visited = [1], needVisit=[9,5,2]</p>
<p>→ 방문할 노드 존재 (while문으로 들어감) : visited = [1], needVisit =  [9,5,2] 
→ DFS는 stack 사용 (LIFO(후입 선출)구조) : node = 2 , visited = [1], needVisit = [9,5]
→ 방문 노드 처리 -&gt; visited = [1,2] needVisit = [9,5]
→ 복사 후 내림차순 정렬 -&gt;nodes = [3,1], visited = [1,2], needVisit=[9,5]
→ 뒤에 추가 LIFO(후입 선출) -&gt; visited = [1,2], needVisit=[9,5,3,1]</p>
<p>→ 방문할 노드 존재 (while문으로 들어감) -&gt;  visited = [1,2], needVisit=[9,5,3,1]
→ DFS는 stack 사용 (LIFO(후입 선출)구조) : node = 1 , visited = [1,2], needVisit=[9,5,3]
→ 이미 방문 했으므로 다시 시작 
.
.
.
이런 구조로 흘러가게 된다. </p>
<h3 id="dfs-코드-구현-js-재귀-버전">DFS 코드 구현 (JS 재귀 버전)</h3>
<pre><code class="language-javascript">function dfs(graph,node,visited){
    if(!visited.includes(node)){
        visited.push(node); // 현재 노드 방문 

    for(let n of graph[node]){ 인접 노드 
        dfs(graph,n,visited); //인접 노드 재귀 호출 
     }
    }
    return visited;
}</code></pre>
<ul>
<li><p>1단계: dfs(graph, 1, [])
방문: 1 → visited = [1]
인접 노드 순회: [2, 5, 9]</p>
</li>
<li><p>2단계: dfs(graph, 2, [1])
방문: 2 → visited = [1, 2]
인접 노드: [1, 3]</p>
<p>dfs(graph, 1, [1,2]) → 이미 방문, 무시
dfs(graph, 3, [1,2]) 호출</p>
</li>
<li><p>3단계: dfs(graph, 3, [1,2])
방문: 3 → visited = [1,2,3]
인접 노드: [2, 4]</p>
<p>dfs(graph, 2, ...) → 이미 방문
dfs(graph, 4, ...) 호출</p>
</li>
<li><p>4단계: dfs(graph, 4, [1,2,3])
방문: 4 → visited = [1,2,3,4]</p>
<p>인접 노드: [3] → 이미 방문, 종료</p>
<p>이후 재귀가 되돌아가서 1의 다음 인접 노드인 5에 대해 재귀 호출됨:</p>
</li>
<li><p>5단계: dfs(graph, 5, [1,2,3,4])
방문: 5 → visited = [1,2,3,4,5]
인접 노드: [1, 6, 8]</p>
<p>dfs(graph, 1, ...) → 이미 방문</p>
<p>dfs(graph, 6, ...) 호출</p>
</li>
<li><p>6단계: dfs(graph, 6, [1,2,3,4,5])
방문: 6 → visited = [1,2,3,4,5,6]
인접 노드: [5, 7]</p>
<p>dfs(graph, 5, ...) → 이미 방문</p>
<p>dfs(graph, 7, ...) 호출</p>
</li>
<li><p>7단계: dfs(graph, 7, [1,2,3,4,5,6])
방문: 7 → visited = [1,2,3,4,5,6,7]
인접 노드: [6] → 이미 방문</p>
<p>되돌아가서 dfs(graph, 8, ...) 실행:</p>
<p>방문: 8 → visited = [1,2,3,4,5,6,7,8]
마지막으로 dfs(graph, 9, ...) 실행:</p>
<p>방문: 9 → visited = [1,2,3,4,5,6,7,8,9]</p>
</li>
</ul>
<h2 id="✍️-후기">✍️ 후기</h2>
<ul>
<li>노션에 막 적을 때보단 누군가 볼 수도 있다구 생각해서 최대한 정리해서 적었지만.........
시간이 너무 오래걸렸다. 다음 글은 더 빨리 적을 수 있도록 해야겠다. </li>
</ul>
<p>출처: 
<a href="https://hhejo.github.io/posts/dfs-with-javascript/">https://hhejo.github.io/posts/dfs-with-javascript/</a> 
<a href="https://velog.io/@hyhy9501/3-1.-%EC%8A%A4%ED%83%9DStack">https://velog.io/@hyhy9501/3-1.-%EC%8A%A4%ED%83%9DStack</a>
<a href="https://data-marketing-bk.tistory.com/entry/%EC%9E%AC%EA%B7%80%ED%95%A8%EC%88%98%EC%9D%98-%EC%99%84%EB%B2%BD-%EC%9D%B4%ED%95%B4-%EB%B0%8F-%EA%B5%AC%ED%98%84Recursive-Function">https://data-marketing-bk.tistory.com/entry/%EC%9E%AC%EA%B7%80%ED%95%A8%EC%88%98%EC%9D%98-%EC%99%84%EB%B2%BD-%EC%9D%B4%ED%95%B4-%EB%B0%8F-%EA%B5%AC%ED%98%84Recursive-Function</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[이해한 대로 적어보는 알고리즘(JS) - 0. 작성 규칙 ]]></title>
            <link>https://velog.io/@moo_miz/%EC%9D%B4%ED%95%B4%ED%95%9C-%EB%8C%80%EB%A1%9C-%EC%A0%81%EC%96%B4%EB%B3%B4%EB%8A%94-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98JS-0.-%EC%9E%91%EC%84%B1-%EA%B7%9C%EC%B9%99</link>
            <guid>https://velog.io/@moo_miz/%EC%9D%B4%ED%95%B4%ED%95%9C-%EB%8C%80%EB%A1%9C-%EC%A0%81%EC%96%B4%EB%B3%B4%EB%8A%94-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98JS-0.-%EC%9E%91%EC%84%B1-%EA%B7%9C%EC%B9%99</guid>
            <pubDate>Wed, 23 Apr 2025 08:03:02 GMT</pubDate>
            <description><![CDATA[<p>코딩 테스트 준비할 때 마다 개념들을 노션 혹은 노트에 적었더니,
둘다 혼자 본다는 생각에 대충 적는 감이 있다고 생각하여 포스팅을 작성하기로 마음 먹었다. </p>
<p>1.알고리즘을 이해하기 위해 필요한 개념 
2.알고리즘 개념
    2-1. 알고리즘 원리
    2-2. 장단점 
    2-3. 알고리즘 코드 
3. 사용 해야하는 곳 </p>
<p>큰 틀로는 이렇게 맞춰서 적는 형식으로 나가야겠다! </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS][프로그래머스][LV.2] 피보나치 수열 ]]></title>
            <link>https://velog.io/@moo_miz/JS%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV.2-%ED%94%BC%EB%B3%B4%EB%82%98%EC%B9%98-%EC%88%98%EC%97%B4</link>
            <guid>https://velog.io/@moo_miz/JS%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4LV.2-%ED%94%BC%EB%B3%B4%EB%82%98%EC%B9%98-%EC%88%98%EC%97%B4</guid>
            <pubDate>Mon, 27 Jan 2025 08:55:06 GMT</pubDate>
            <description><![CDATA[<p>업무하면서 내가 짜는 코드가 너무 효율적이지 못한 것 같다는 생각과 함께 다시 풀기 시작한 코테.. </p>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/12945">https://school.programmers.co.kr/learn/courses/30/lessons/12945</a></p>
<p>문제 설명
피보나치 수는 F(0) = 0, F(1) = 1일 때, 1 이상의 n에 대하여 F(n) = F(n-1) + F(n-2) 가 적용되는 수 입니다.</p>
<p>예를들어</p>
<ul>
<li>F(2) = F(0) + F(1) = 0 + 1 = 1</li>
<li>F(3) = F(1) + F(2) = 1 + 1 = 2</li>
<li>F(4) = F(2) + F(3) = 1 + 2 = 3</li>
<li>F(5) = F(3) + F(4) = 2 + 3 = 5
와 같이 이어집니다.</li>
</ul>
<p>2 이상의 n이 입력되었을 때, n번째 피보나치 수를 1234567으로 나눈 나머지를 리턴하는 함수, solution을 완성해 주세요.</p>
<p>제한 사항</p>
<ul>
<li>n은 2 이상 100,000 이하인 자연수입니다.</li>
</ul>
<p>처음에 짠 코드 </p>
<pre><code>function solution(n) {
    var answer = F(n);
    return answer;
}

function F(n){
    if(n==0){
        return 0
    }else if(n==1){
        return 1
    }else{
        return F(n-1)+F(n-2)%1234567
    }
}</code></pre><p>그냥 문제 읽고 문제를 그대로 코드화, 재귀를 사용 했는데,</p>
<p><img src="https://velog.velcdn.com/images/moo_miz/post/fb3de83a-d188-4f07-91e0-72aabf0b2976/image.png" alt=""></p>
<p>.... 시간초과랑 런타임 에러가 나버렸다.. </p>
<p>다시 생각해보니 재귀를 쓰면 매번 F(n)을 새로 계산해서 중복 계산을 하니까 시간이 엄청 오래걸린다고 생각을 했다. </p>
<p>이 후 다시 짠 코드 </p>
<pre><code>function solution(n) {
    const fibonacci = new Array(n+1).fill(0);
    fibonacci[1] = 1;

    for(let i = 2; i &lt;= n; i++) {
        fibonacci[i] = (fibonacci[i-1] + fibonacci[i-2]) % 1234567;
    }

    return fibonacci[n];
}</code></pre><p>재귀 대산 반복문으로, 배열로 이전 값을 저장하도록 변경하였다. </p>
<p>코드의 시간 복잡도도 
재귀 : O(2^n)
반복문: O(n)
으로 확실히 줄었다</p>
<p>결론: 재귀는 만능이 아니다 ( 싸피 할 때도 느꼈지만.. 재활하는 중이니까 다시 상기하기 위해 작성하였다. )</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[schadcn/ui 기본 폴더 변경]]></title>
            <link>https://velog.io/@moo_miz/schadcnui-%EA%B8%B0%EB%B3%B8-%ED%8F%B4%EB%8D%94-%EB%B3%80%EA%B2%BD</link>
            <guid>https://velog.io/@moo_miz/schadcnui-%EA%B8%B0%EB%B3%B8-%ED%8F%B4%EB%8D%94-%EB%B3%80%EA%B2%BD</guid>
            <pubDate>Tue, 29 Oct 2024 00:45:34 GMT</pubDate>
            <description><![CDATA[<p>FSD 구조를 사용하고 나서 schadcn/ui를 도입했는데, 
default 폴더인 components가 구조와 맞지 않아서 shared/ui로 옮기려고 했다.
하지만 옮기고 나서 css가 적용이 안 되어 여러 방법을 시도해보았지만 안되어 고민하던 찰나 방법을 알게 되어 짧게 공유하려 한다. 
<img src="https://velog.velcdn.com/images/moo_miz/post/c37b1735-a684-4adc-898b-ac92726faf9c/image.png" alt="components.json">
aliases에 components는 ui 설치 경로였고 실질적으로 css 적용하기 위해서는 </p>
<p><img src="https://velog.velcdn.com/images/moo_miz/post/f35518a0-794b-4715-af2c-cc14ef87cedc/image.png" alt="">
<img src="https://velog.velcdn.com/images/moo_miz/post/4b1cddc1-18d7-497f-9005-5ca12e6881a9/image.png" alt=""></p>
<p>tailwind.config.ts의 components 경로로 설정 되어 있는걸 shared로 변경해주면 된다! </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 땅따먹기]]></title>
            <link>https://velog.io/@moo_miz/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EB%95%85%EB%94%B0%EB%A8%B9%EA%B8%B0</link>
            <guid>https://velog.io/@moo_miz/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EB%95%85%EB%94%B0%EB%A8%B9%EA%B8%B0</guid>
            <pubDate>Sat, 29 Jul 2023 05:15:46 GMT</pubDate>
            <description><![CDATA[<h2 id="문제-설명">문제 설명</h2>
<p>땅따먹기 게임을 하려고 합니다. 땅따먹기 게임의 땅(land)은 총 N행 4열로 이루어져 있고, 모든 칸에는 점수가 쓰여 있습니다. 1행부터 땅을 밟으며 한 행씩 내려올 때, 각 행의 4칸 중 한 칸만 밟으면서 내려와야 합니다. 단, 땅따먹기 게임에는 한 행씩 내려올 때, 같은 열을 연속해서 밟을 수 없는 특수 규칙이 있습니다.</p>
<p>예를 들면,</p>
<p>| 1 | 2 | 3 | 5 |</p>
<p>| 5 | 6 | 7 | 8 |</p>
<p>| 4 | 3 | 2 | 1 |</p>
<p>로 땅이 주어졌다면, 1행에서 네번째 칸 (5)를 밟았으면, 2행의 네번째 칸 (8)은 밟을 수 없습니다.</p>
<p>마지막 행까지 모두 내려왔을 때, 얻을 수 있는 점수의 최대값을 return하는 solution 함수를 완성해 주세요. 위 예의 경우, 1행의 네번째 칸 (5), 2행의 세번째 칸 (7), 3행의 첫번째 칸 (4) 땅을 밟아 16점이 최고점이 되므로 16을 return 하면 됩니다.</p>
<h3 id="제한-사항">제한 사항</h3>
<p>행의 개수 N : 100,000 이하의 자연수
열의 개수는 4개이고, 땅(land)은 2차원 배열로 주어집니다.
점수 : 100 이하의 자연수</p>
<h3 id="입출력-예">입출력 예</h3>
<p><img src="https://velog.velcdn.com/images/moo_miz/post/2b176233-577e-4b95-a73a-48a45f542423/image.png" alt=""></p>
<h3 id="문제-풀이">문제 풀이</h3>
<ul>
<li><p>문제를 처음에 읽었을 때는 줄에서 큰 값을 구하고 그 값의 인덱스를 구해 비교해 일치 할 경우 작은 값 줄의 두번째 값을 구해야하나..? 생각했는데 번거롭게 하는거 보다 DP로 풀면 해결 되겠다고 생각이 들어 DP로 풀었다! </p>
</li>
<li><p>N행 4열로 되어 있기 때문에 4열을 고정임을 알 수 있었고,두번째 줄부터 이전 줄에서 해당하는 인덱스 값을 제외한 값들 중에 가장 큰 값을 더하는 형식으로 진행해 마지막줄에 가장 큰 값을 정답으로 도출하는 형식으로 만들었다! </p>
</li>
</ul>
<pre><code>function solution(land) {
    var answer = 0;
    // N행 4열로 이루어져 있음
    const len = land.length; 
    for(let i = 0; i &lt; land.length-1; i++){
        land[i+1][0] += Math.max(land[i][1],land[i][2],land[i][3])
        land[i+1][1] += Math.max(land[i][0],land[i][2],land[i][3])
        land[i+1][2] += Math.max(land[i][0],land[i][1],land[i][3])
        land[i+1][3] += Math.max(land[i][0],land[i][1],land[i][2])
    }
    answer = Math.max(...land[len-1])
    return answer;
}</code></pre><p><img src="https://velog.velcdn.com/images/moo_miz/post/8b0ef343-6d97-4522-b623-a6f8668699c2/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[정권 찌르기[리팩토링 6-8일차]: text editor 에러 개선 및 XSS 공격을 방지하기 위한 고민 ]]></title>
            <link>https://velog.io/@moo_miz/%EC%A0%95%EA%B6%8C-%EC%B0%8C%EB%A5%B4%EA%B8%B0%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81-6-8%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@moo_miz/%EC%A0%95%EA%B6%8C-%EC%B0%8C%EB%A5%B4%EA%B8%B0%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81-6-8%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Fri, 21 Jul 2023 12:51:53 GMT</pubDate>
            <description><![CDATA[<p>롯데 e커머스 채용연계형 면접으로 보고와서 적는 리팩토링 글! 
물론 떨어졌기에 큰 도움은 안되겠지만 내년에 면접 볼 분들을 위해 후기를 작성 할 생각이다.</p>
<h1 id="💥-문제">💥 문제</h1>
<p> 5일차 포스팅에 문제에 대한 고민을 팀원들과 함께 의논을 해 본 결과..</p>
<blockquote>
</blockquote>
<p>ㅎㄱ 님: 노션은 드래그 앤 드랍과 엔터치면 새로운 블록 생성되는 기능 둘 다 있지 않나요..? </p>
<p>생각해보니 맞는 말이다. 그래서 둘 다 개발하는 걸로!
( 드래그 앤 드랍은 다음 포스팅에서 다룰 예정 입니다)</p>
<h3 id="1-contenteditable-무한-렌더링-에러">1. contentEditable 무한 렌더링 에러</h3>
<p>-&gt; 사실 리팩토링하면서 계속 에디터를 고도화 하기 위해 공부하는데
contentEditable 속성에 문제점에 대한 글을 보게 되었다. 
우선 공식적으로 정해진 표준이 아니기에 브라우저마다 동작이 다르다(일관성이 없다)는 문제점이 있었고, 또한 React에서 사용할 땐 input과 동작방식이 많은 차이점이 있다는 사실을 알게 되었다 .(아래 링크 참조) 
<a href="https://www.bucketplace.com/post/2020-09-18-%EC%9B%90%ED%99%9C%ED%95%9C-%EC%BD%98%ED%85%90%EC%B8%A0-%EC%9E%91%EC%84%B1%EC%9D%84-%EC%9C%84%ED%95%9C-%EC%97%90%EB%94%94%ED%84%B0-%EA%B0%9C%EB%B0%9C%EA%B8%B0/">https://www.bucketplace.com/post/2020-09-18-%EC%9B%90%ED%99%9C%ED%95%9C-%EC%BD%98%ED%85%90%EC%B8%A0-%EC%9E%91%EC%84%B1%EC%9D%84-%EC%9C%84%ED%95%9C-%EC%97%90%EB%94%94%ED%84%B0-%EA%B0%9C%EB%B0%9C%EA%B8%B0/</a></p>
<h3 id="2-dangerouslysetinnerhtml-사용으로-인한-xss-공격의-위험성">2. dangerouslySetInnerHTML 사용으로 인한 XSS 공격의 위험성</h3>
<blockquote>
<p>dangerouslySetInnerHTML 란?
브라우저 DOM에서 innerHTML을 사용하기 위한 REACT의 대체 방법으로 이 태그를 통해 직접적으로 HTML을 삽입 할 수 있다.</p>
</blockquote>
<blockquote>
<h3 id="xss란-cross-site-script">XSS란 (Cross Site Script)</h3>
<p>XSS 공격은 공격자에 의해 작성된 스크립트가 다른 사용자에게 전달되는 기법이다. 다른 사용자의 웹 브라우저에서 적절한 검증 없이 실행되기 때문에 사용자의 세션을 탈취하거나 , 웹 사이트 변조 또는 악의적인 사이트로 사용자를 이동시킬 수 있다.</p>
</blockquote>
<pre><code>    &lt;TextBlock
          key={content.idx}
          contentEditable=&quot;true&quot;
          suppressContentEditableWarning
          onInput={handleChange}
          onCompositionStart={handleCompositionStart}
          onCompositionEnd={handleCompositionEnd}
          ref={textRef}
          dangerouslySetInnerHTML={{ __html: content.context }}
          onContextMenu={handleContextMenu}
        /&gt;</code></pre><p>당시에 위 코드를 통해 HTML 코드가 포함된 context를 그대로 보여주었다.
프로젝트 당시에도 가능하며 사용하지 않는게 좋은 태그인걸 알고 있었지만(이름부터 위험하다..) 프로젝트 마감 일정에 맞추기 위해 사용하였다. </p>
<h1 id="💡방법">💡방법:</h1>
<h3 id="1-1-react-contenteditable-사용하기">1-1. react-contentEditable 사용하기</h3>
<ul>
<li>input과 textarea에서는 bold, italic, color 적용한 결과를 보여줄 수 없기에 div 태그를 수정 할 수있는 contentEditable 속성 사용을 불가피하다는 생각을 하였다.
(혹시 더 좋은 방법을 알고 계신분은 알려주신다면 감사하겠습니다) 
또한 동작원리를 모르고 라이브러리를 사용하는게 싫어 라이브러리를 잘 사용하지 않았었는데, </li>
</ul>
<p>react-contenteditable 링크 : <a href="https://www.npmjs.com/package/react-contenteditable">https://www.npmjs.com/package/react-contenteditable</a></p>
<p>태그 커스텀이 필요하였기 때문에 
Advenced example 예시 : <a href="https://codesandbox.io/s/l91xvkox9l">https://codesandbox.io/s/l91xvkox9l</a> 
를 참조하였다. 
해당 코드를 참조하면 </p>
<pre><code> &lt;ContentEditable
          className=&quot;editable&quot;
          tagName=&quot;pre&quot;
          html={this.state.html} // innerHTML of the editable div
          disabled={!this.state.editable} // use true to disable edition
          onChange={this.handleChange} // handle innerHTML change
          onBlur={this.sanitize}
        /&gt;</code></pre><p>html 속성에서 innerHTML 속성을 사용하는 것을 알 수 있다. 
위 예시에서는 XSS에 취약한 innerHTML 속성의 문제점을 해결하기 위해 sanitize-html 라이브러리를 사용하였다.</p>
<blockquote>
<h3 id="sanitize-란">sanitize 란?</h3>
<p>sanitize(소독)은 html의 input 또는 textarea 또는 기타등등의 사용자 입력정보에 
<img src="https://velog.velcdn.com/images/moo_miz/post/011b34d0-34b1-4c1c-9df1-a77eac2203d7/image.png" alt="">와 같은 문자열을 적을시, 웹브라우저에서 문자열이 txt가 아닌 script 기술로 받아들여서 생기는 문제를 방지하는 모듈이다.
사용자가 이를 악용하여 태그들을 삽입해서 악성 스크립트로 변질시켜 실행 시킬 수 있기 때문이다.</p>
</blockquote>
<p>HTML Sanitization 할 수 있는 방법은 3가지가 있는데,</p>
<ul>
<li><p>sanitize-html 라이브러리 사용하기
<a href="https://www.npmjs.com/package/sanitize-html">https://www.npmjs.com/package/sanitize-html</a></p>
<blockquote>
<h3 id="sanitize-html란">Sanitize-html란?</h3>
<p>허용된 태그와 속성 외에 html 태그를 허용하지 않는다. 허용되지 않는 속성이 있다면 지워진다. 기본값으로 하면 디폴트로 허용된 태그들이 존재한다. 허용하는 태그와 허용하지 않는 태그를 따로 지정할 수 있다.</p>
</blockquote>
</li>
<li><p>HTML Sanitizer API 사용하기
:<a href="https://ui.toast.com/weekly-pick/ko_2021124">https://ui.toast.com/weekly-pick/ko_2021124</a></p>
</li>
<li><p>DOM Purify 라이브러리 사용하기
<a href="https://github.com/cure53/DOMPurify">https://github.com/cure53/DOMPurify</a></p>
<blockquote>
<h3 id="dompurify란">DOMPurify란?</h3>
<p>DOM 레벨에서 HTML을 sanitize 해주고 XSS 공격을 막아준다. jsdom 을 사용하면 node 와 같은 서버 레벨에서도 사용 가능하다. DOMPurify는 화이트리스트 접근 방식을 취하는데 특정한 태그와 속성, 프로토콜만 허용한다.</p>
</blockquote>
</li>
</ul>
<p>등의 방법이 있었다... </p>
<h2 id="⚽결론">⚽결론</h2>
<h3 id="1-react-contenteditable-라이브러리-활용">1. react contentEditable 라이브러리 활용</h3>
<p> : 라이브러리를 사용하면 모르고 사용하는 느낌이 싫어 프로젝트에서 거의 사용하지 않았었는데, 
 리팩토링 이전에 contentEditable 속성을 사용하면서 사용했을때의 문제점과 에러를 고치는 과정을 직접 해봤기에 이번엔 라이브러리를 도입하여 사용하기로 하였다. </p>
<h3 id="2-xss-문제-해결을-위한-html-sanitization-할-수-있는-라이브러리-or-api-도입">2. XSS 문제 해결을 위한 HTML Sanitization 할 수 있는 라이브러리 or api 도입</h3>
<p>: 마찬가지로 위에 조사한 내용 이외에 작동 원리를 조사하여 프로젝트에 맞는 라이브러리 or api를 도입 할 예정이다. 
프로젝트 당시에 XSS 공격 문제 때문에 고민을 많이 했었는데, 그때는 기간 내에 작동하는 프로젝트를 만드는 것이 우선순위여서 특정 태그를 파싱하여 사용하지 못하도록 임시 조취만 취했는데 이번엔 제대로 XSS 문제를 방지 할 수 있을 것이란 기대가 된다! 
완성한 후에 테스트 해서 XSS 공격이 방지가 되는지 테스트 해서 포스팅을 작성하는것을 목표로 하고 있다.</p>
<h2 id="😮참고-자료">😮참고 자료</h2>
<ol>
<li><p><a href="https://inpa.tistory.com/entry/NODE-%EB%B3%B4%EC%95%88-%F0%9F%93%9A-sanitize-html-%EB%AA%A8%EB%93%88-%EC%82%AC%EC%9A%A9%EB%B2%95">https://inpa.tistory.com/entry/NODE-%EB%B3%B4%EC%95%88-%F0%9F%93%9A-sanitize-html-%EB%AA%A8%EB%93%88-%EC%82%AC%EC%9A%A9%EB%B2%95</a></p>
</li>
<li><p><a href="https://velog.io/@pock11/innerHTML-dangerouslySetInnerHTML">https://velog.io/@pock11/innerHTML-dangerouslySetInnerHTML</a></p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[정권 찌르기[리팩토링 5일차]: 블록 수정, 추가, 생성 방식 개편을 위한 고민]]></title>
            <link>https://velog.io/@moo_miz/%EC%B7%A8%EC%97%85%EC%9D%84-%EC%9C%84%ED%95%9C-%EC%A0%95%EA%B6%8C-%EC%B0%8C%EB%A5%B4%EA%B8%B0%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81-%ED%8E%B8-5%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@moo_miz/%EC%B7%A8%EC%97%85%EC%9D%84-%EC%9C%84%ED%95%9C-%EC%A0%95%EA%B6%8C-%EC%B0%8C%EB%A5%B4%EA%B8%B0%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81-%ED%8E%B8-5%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Mon, 17 Jul 2023 16:43:00 GMT</pubDate>
            <description><![CDATA[<p>저번주 선약 이슈로 평일 하루 개발을 못하여서 월요일인 오늘이 5일차!</p>
<h1 id="💥문제">💥문제</h1>
<h2 id="1-이미-작성된-텍스트-블록-사이에-블록을-추가-할-수-있는-방법이-없다">1. 이미 작성된 텍스트 블록 사이에 블록을 추가 할 수 있는 방법이 없다.</h2>
<ul>
<li><p>과거 프로젝트 당시 드래그 앤 드랍 기능을 추가 할려고 계획 하였으나. 드래그 앤 드랍으로 옮겼을 때 idx 값이 number 였고 순서가 바뀌었을 때 에러가 날 것을 생각하여 추가 하지않았다. </p>
</li>
<li><p>하지만 텍스트 에디터를 사용하여 글을 작성하는 작가 입장에서 블록 사이에 내용을 추가 하지 못하는건 엄청난 불편함이 있기에 기능을 추가하려고 한다. </p>
</li>
</ul>
<h2 id="2수정-시-무한-렌더링-오류">2.수정 시 무한 렌더링 오류</h2>
<ul>
<li>text 블록 클릭시 contentEditable 속성을 사용해서 수정 할 수 있도록 작성해놨는데, text style 적용하는 코드와 충돌이 나면서 무한 렌더링 오류가 발생하였다.. </li>
</ul>
<h1 id="💡방법">💡방법</h1>
<h2 id="1-1-drag--drop-방식-도입">1-1. drag &amp; drop 방식 도입</h2>
<ul>
<li>react dnd (라이브러리) 사용 </li>
<li>Drag and Drop api 사용 </li>
</ul>
<h2 id="1-2-생성된-텍스트-블록에서-엔터키-눌렀을-시-새로운-블록-생성-되도록-하기">1-2. 생성된 텍스트 블록에서 엔터키 눌렀을 시 새로운 블록 생성 되도록 하기</h2>
<p><img src="https://velog.velcdn.com/images/moo_miz/post/7b4ab8eb-4c8d-469e-9f23-6c65da291371/image.gif" alt=""></p>
<ul>
<li><p>해당 이미지는 에디터 구현 할 때 많이 참조 하였던 오늘의 집 에디터이다. </p>
</li>
<li><p>위와 같은 방식으로 구현 할 시 EditorMainInput 컴포넌트가 가지고 있던 기존 input을 제거하고, 클릭 시 contents 배열안에 content 객체를 바로 생성 하는 방법으로 구현하는 방법으로 변경 해야 할 것으로 예상된다. </p>
</li>
</ul>
<h1 id="🧐추가적인-생각">🧐추가적인 생각</h1>
<ul>
<li><p>1-2 방법을 사용 할 경우에 content가 &quot;&quot; 일 때 backspace를 누르면 삭제 하는 기능을 추가 하고 x 버튼을 삭제하는게 좋을 것 같다는 생각을 하였다. </p>
</li>
<li><p>적고 보니 1-1 보다 1-2가 더 익숙한 형식 일꺼 같다고 생각이 들어 수정해볼려고 한다.. 대신 시간이 오래 걸릴꺼 같다..</p>
</li>
</ul>
<h1 id="⚽결과">⚽결과</h1>
<ul>
<li>오늘은 build 에러를 수정하고 위에 적은 방법에 대해 고민하는 시간을 가졌다. 
해당 문제과 고민에 대한 결과는 다음 정권찌르기에서 계속 진행 될 예정이다! 
글 작성이 완료 되면 아래에 추가로 링크를 남길 예정이다. </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 최솟값 만들기 ]]></title>
            <link>https://velog.io/@moo_miz/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%B5%9C%EC%86%9F%EA%B0%92-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@moo_miz/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%B5%9C%EC%86%9F%EA%B0%92-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Mon, 17 Jul 2023 14:48:56 GMT</pubDate>
            <description><![CDATA[<h3 id="문제-설명">문제 설명</h3>
<p>길이가 같은 배열 A, B 두개가 있습니다. 각 배열은 자연수로 이루어져 있습니다.
배열 A, B에서 각각 한 개의 숫자를 뽑아 두 수를 곱합니다. 이러한 과정을 배열의 길이만큼 반복하며, 두 수를 곱한 값을 누적하여 더합니다. 이때 최종적으로 누적된 값이 최소가 되도록 만드는 것이 목표입니다. (단, 각 배열에서 k번째 숫자를 뽑았다면 다음에 k번째 숫자는 다시 뽑을 수 없습니다.)</p>
<p>예를 들어 A = [1, 4, 2] , B = [5, 4, 4] 라면</p>
<ul>
<li>A에서 첫번째 숫자인 1, B에서 첫번째 숫자인 5를 뽑아 곱하여 더합니다. (누적된 값 : 0 + 5(1x5) = 5)</li>
<li>A에서 두번째 숫자인 4, B에서 세번째 숫자인 4를 뽑아 곱하여 더합니다. (누적된 값 : 5 + 16(4x4) = 21)</li>
<li>A에서 세번째 숫자인 2, B에서 두번째 숫자인 4를 뽑아 곱하여 더합니다. (누적된 값 : 21 + 8(2x4) = 29)
즉, 이 경우가 최소가 되므로 29를 return 합니다.</li>
</ul>
<p>배열 A, B가 주어질 때 최종적으로 누적된 최솟값을 return 하는 solution 함수를 완성해 주세요.</p>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>배열 A, B의 크기 : 1,000 이하의 자연수</li>
<li>배열 A, B의 원소의 크기 : 1,000 이하의 자연수</li>
</ul>
<h3 id="입출력-예">입출력 예</h3>
<p><img src="https://velog.velcdn.com/images/moo_miz/post/12856933-a0ac-4fc2-8b9e-efb9b887db31/image.png" alt=""></p>
<h3 id="입출력-예-설명">입출력 예 설명</h3>
<ul>
<li><p>입출력 예 #1
문제의 예시와 같습니다.</p>
</li>
<li><p>입출력 예 #2
A에서 첫번째 숫자인 1, B에서 두번째 숫자인 4를 뽑아 곱하여 더합니다. (누적된 값 : 4) 다음, A에서 두번째 숫자인 2, B에서 첫번째 숫자인 3을 뽑아 곱하여 더합니다. (누적된 값 : 4 + 6 = 10)
이 경우가 최소이므로 10을 return 합니다.</p>
</li>
</ul>
<h3 id="풀이">풀이</h3>
<h4 id="1-틀린-풀이">1. 틀린 풀이</h4>
<pre><code>function solution(A,B){
    var answer = 0;
    // 둘 다 오름차순 정렬 후 
    A.sort();
    B.sort();
    B.reverse();
    for(let i = 0; i &lt; A.length; i++){
        answer += A[i] *B[i]
    }

    return answer;
}</code></pre><h4 id="2-남의-풀이">2. 남의 풀이</h4>
<pre><code>function solution(a,b){
    var answer = 0;
    const res1 = a.sort((a,b)=&gt; a-b)
    const res2 = b.sort((a,b)=&gt; b-a)
    for(i=0;i&lt;res1.length;i++){
      answer += res1[i] * res2[i]
    }
    return answer;
}
</code></pre><h4 id="3-고친-풀이">3. 고친 풀이</h4>
<pre><code>function solution(A,B){
    var answer = 0;
    // 둘 다 오름차순 정렬 후 
    A.sort((a,b)=&gt;a-b);
    B.sort((a,b)=&gt;b-a);
    for(let i = 0; i &lt; A.length; i++){
        answer += A[i] *B[i]
    }

    return answer;
}
</code></pre><h4 id="4-의문점">4. 의문점</h4>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] JadenCase 문자열 만들기
]]></title>
            <link>https://velog.io/@moo_miz/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-JadenCase-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@moo_miz/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-JadenCase-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Mon, 17 Jul 2023 08:49:14 GMT</pubDate>
            <description><![CDATA[<h3 id="문제-설명">문제 설명</h3>
<p>JadenCase란 모든 단어의 첫 문자가 대문자이고, 그 외의 알파벳은 소문자인 문자열입니다. 단, 첫 문자가 알파벳이 아닐 때에는 이어지는 알파벳은 소문자로 쓰면 됩니다. (첫 번째 입출력 예 참고)
문자열 s가 주어졌을 때, s를 JadenCase로 바꾼 문자열을 리턴하는 함수, solution을 완성해주세요.</p>
<h3 id="제한-사항">제한 사항</h3>
<ul>
<li>s는 길이 1 이상 200 이하인 문자열입니다.</li>
<li>s는 알파벳과 숫자, 공백문자(&quot; &quot;)로 이루어져 있습니다.<ul>
<li>숫자는 단어의 첫 문자로만 나옵니다.</li>
<li>숫자로만 이루어진 단어는 없습니다.</li>
<li>공백문자가 연속해서 나올 수 있습니다.<h3 id="입출력-예">입출력 예</h3>
<img src="https://velog.velcdn.com/images/moo_miz/post/c0857ad4-83d9-417c-a5f1-3dbb7a2ca58d/image.png" alt=""></li>
</ul>
</li>
</ul>
<h3 id="풀이">풀이</h3>
<pre><code>function solution(s) {
    var answer = &#39;&#39;;
    // 첫 문자가 대문자이고, 알파벳은 소문자 
    let array = s.split(&#39; &#39;);
    // split(&#39; &#39;):split 함수를 이용하면 공백 기준으로 배열로 변환해서 저장함! 
    let result = array.map(x =&gt; x.charAt(0).toUpperCase()+ x.slice(1).toLowerCase());
    // .map(): map 함수를 통해 배열 내부의 값을 조건에 밎게 변형시키고 새로운 배열을 뽑아내서 result2에 저장

    //charAt(): charAt()을 통해 result2의 각각 배열값인 x에 대하여 0번째 글자를 선택
// toUpperCase(): 0번째에 대한 글자를 대문자로 변환
// slice(): slice(1)을 통해 인덱스가 1값부터 마지막값까지를 설정
// toLowerCase(): 인덱스값이 1인 부분부터는 소문자로 변환
    answer = result.join(&quot; &quot;)
// join(): 배열의 모든 요소를 연결해 하나의 문자열로 변환
    return answer;
}</code></pre>]]></description>
        </item>
    </channel>
</rss>