<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>허니의 테크수다</title>
    <link>https://techsuda.tistory.com/</link>
    <description>오래된 프로그래머의 요즘 이야기</description>
    <language>ko</language>
    <pubDate>Sun, 14 Jun 2026 15:38:01 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>쭝허니</managingEditor>
    <image>
      <title>허니의 테크수다</title>
      <url>https://tistory1.daumcdn.net/tistory/6538986/attach/008452bda3a949769f0d8fe0ac45f9ce</url>
      <link>https://techsuda.tistory.com</link>
    </image>
    <item>
      <title>[IT Trend] 내가 결제하지 않는 시대, '프록시 경제(Proxy Economy)'가 온다!</title>
      <link>https://techsuda.tistory.com/entry/IT-Trends-%EB%82%B4%EA%B0%80-%EA%B2%B0%EC%A0%9C%ED%95%98%EC%A7%80-%EC%95%8A%EB%8A%94-%EC%8B%9C%EB%8C%80-%ED%94%84%EB%A1%9D%EC%8B%9C-%EA%B2%BD%EC%A0%9CProxy-Economy%EA%B0%80-%EC%98%A8%EB%8B%A4</link>
      <description>&lt;script src=&quot;https://cdn.tailwindcss.com&quot;&gt;&lt;/script&gt;
&lt;script&gt;
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        pastelBlue: {
                            50: '#F0F7FF',
                            100: '#EBF5FF',
                            200: '#D1E9FF',
                            500: '#3B82F6',
                            600: '#2563EB',
                        },
                        charcoal: '#333333',
                        softGray: '#666666',
                    },
                    fontFamily: {
                        display: ['Outfit', 'Noto Sans KR', 'sans-serif'],
                        body: ['Noto Sans KR', 'sans-serif'],
                    },
                }
            }
        }
    &lt;/script&gt;
&lt;p&gt;&lt;img class=&quot;w-full h-full object-cover&quot; style=&quot;letter-spacing: 0px;&quot; src=&quot;https://opal.google/board/blobs/f230e868-ebf8-4bb9-9334-fb315143e687&quot; alt=&quot;Proxy Economy Concept Illustration&quot; /&gt;&lt;/p&gt;
&lt;header class=&quot;w-full hero-gradient pt-8 pb-12 px-4&quot;&gt;
&lt;div class=&quot;max-w-6xl mx-auto&quot;&gt;&lt;!-- Header &amp; Metadata --&gt;
&lt;div class=&quot;text-center space-y-6&quot;&gt;
&lt;h1 class=&quot;text-3xl md:text-5xl font-bold font-display leading-tight text-charcoal tracking-tight max-w-4xl mx-auto&quot;&gt;내가 결제하지 않는 시대,&lt;br /&gt;&lt;span class=&quot;text-pastelBlue-500&quot;&gt;'프록시 경제(Proxy Economy)'&lt;/span&gt;가 온다!&lt;/h1&gt;
&lt;div class=&quot;flex items-center justify-center gap-6 text-softGray text-sm font-medium&quot;&gt;&lt;u&gt;&lt;i&gt;&lt;b&gt;&lt;span class=&quot;flex items-center gap-2&quot;&gt; 테크/비즈니스&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;/u&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/header&gt;&lt;!-- Main Content --&gt;&lt;main class=&quot;content-container mx-auto px-6 pb-24&quot;&gt;&lt;!-- Intro Section --&gt;
&lt;section class=&quot;py-8 text-lg text-charcoal/90&quot;&gt;
&lt;p class=&quot;mb-6&quot; data-ke-size=&quot;size16&quot;&gt;Fintech쪽 추진하고 있는 SCF(공급망금융) 사업이 하나 있습니다.&lt;br /&gt;이런 저런 자료 수집하고 몰랐던 용어들 공부하다보니, 떡~~~ 하니 익숙한 단어가 하나 나왔습니다. 프록시~~~&lt;br /&gt;어라? 근데 프록시경제?? 뭐지??? 내가 아는 그 프록시 아닌가? 프록시, 웹서버, Nginx 설정할때 proxy_path 설정에 사용하던 그거 아냐? 필자와 같은 궁금증을 가지신 분들 잘 찾아오셨습니다요. ㅎㅎ&lt;/p&gt;
&lt;p class=&quot;mb-6&quot; data-ke-size=&quot;size16&quot;&gt;최근 판교 테크노벨리의 카페나 벤처기업 회의실, 혹은 심도 있는 IT 트렌드 뉴스에서 &lt;b&gt;'프록시 경제(Proxy Economy)'&lt;/b&gt;라는 용어를 심심치 않게 접해보셨을 것입니다. 단어 자체는 다소 생소하고 어렵게 느껴질 수 있지만, 그 핵심은 매우 명확하고 우리의 삶을 송두리째 바꿀 만큼 파괴적입니다. 간단히 말해 프록시 경제란, &lt;span class=&quot;bg-pastelBlue-100 px-1 font-semibold&quot;&gt;&quot;나를 대신해 AI가 돈을 쓰고, 결정을 내리며, 일상과 업무를 완벽하게 처리하는 미래 경제 시스템&quot;&lt;/span&gt;을 뜻합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 질문에 답을 해주는 챗봇의 시대를 넘어, 내 지갑을 관리하고 나의 스케줄을 통제하는 &lt;b&gt;AI 에이전트(AI Agent)&lt;/b&gt;의 등장. 이 혁명적인 변화가 우리의 일상과 비즈니스 생태계를 어떻게 바꿔놓을지, 매우 현실적이고 흥미로운 일상 속 예시를 통해 자세히 파헤쳐 보겠습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;!-- Table of Contents --&gt;&lt;nav class=&quot;my-12 p-8 rounded-2xl bg-pastelBlue-50 border border-pastelBlue-100&quot;&gt;
&lt;h4 class=&quot;font-display font-bold text-xl mb-6 text-charcoal&quot; data-ke-size=&quot;size20&quot;&gt;목차&lt;/h4&gt;
&lt;ul class=&quot;space-y-4&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a class=&quot;toc-link flex items-center text-softGray font-medium&quot; href=&quot;#sec1&quot;&gt;&lt;span class=&quot;text-pastelBlue-500 mr-3&quot;&gt;01&lt;/span&gt; '프록시'의 정의와 경제의 결합&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;toc-link flex items-center text-softGray font-medium&quot; href=&quot;#sec2&quot;&gt;&lt;span class=&quot;text-pastelBlue-500 mr-3&quot;&gt;02&lt;/span&gt; 가상 시나리오: 판교 직장인의 금요일&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;toc-link flex items-center text-softGray font-medium&quot; href=&quot;#sec3&quot;&gt;&lt;span class=&quot;text-pastelBlue-500 mr-3&quot;&gt;03&lt;/span&gt; 비즈니스와 일상의 변화 (B2A 마케팅)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;toc-link flex items-center text-softGray font-medium&quot; href=&quot;#sec4&quot;&gt;&lt;span class=&quot;text-pastelBlue-500 mr-3&quot;&gt;04&lt;/span&gt; 프록시 경제의 그림자와 리스크&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/nav&gt;&lt;!-- Section 1 --&gt;
&lt;article id=&quot;sec1&quot; class=&quot;py-10&quot;&gt;
&lt;h2 class=&quot;text-2xl md:text-3xl font-bold text-charcoal mb-8 leading-tight&quot; data-ke-size=&quot;size26&quot;&gt;1. '프록시(Proxy)'란 도대체 무엇이며, 경제와 어떻게 만났을까?&lt;/h2&gt;
&lt;div class=&quot;space-y-6 text-[17px] text-charcoal/90&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본래 컴퓨터 공학에서 '프록시(Proxy)'는 '대리인' 혹은 '대리 서버'를 의미하는 용어입니다. 사용자가 인터넷 망 속에서 직접 상대방(서버)과 통신하는 것이 아니라, 중간에 든든한 대리인을 두고 안전하고 빠르게 데이터를 주고받는 방식을 말하죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 기술적 개념이 고도화된 인공지능(AI)과 결합하여 경제 용어로 확장된 것이 바로 '프록시 경제'입니다.&lt;/p&gt;
&lt;div class=&quot;grid md:grid-cols-2 gap-6 mt-8&quot;&gt;
&lt;div class=&quot;p-6 rounded-xl bg-white border border-gray-100 shadow-sm&quot;&gt;
&lt;h4 class=&quot;font-bold text-softGray mb-3 flex items-center gap-2&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span class=&quot;w-2 h-2 rounded-full bg-gray-300&quot;&gt;&lt;/span&gt; 과거와 현재의 경제&lt;/h4&gt;
&lt;p class=&quot;text-sm&quot; data-ke-size=&quot;size16&quot;&gt;우리가 직접 상품을 검색하고, 리뷰를 비교한 뒤, 생체인증을 하고 결제 버튼을 누르는 능동적 소비 시대입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;p-6 rounded-xl bg-pastelBlue-50 border border-pastelBlue-100 shadow-sm&quot;&gt;
&lt;h4 class=&quot;font-bold text-pastelBlue-600 mb-3 flex items-center gap-2&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span class=&quot;w-2 h-2 rounded-full bg-pastelBlue-500&quot;&gt;&lt;/span&gt; 프록시 경제 (미래)&lt;/h4&gt;
&lt;p class=&quot;text-sm&quot; data-ke-size=&quot;size16&quot;&gt;나의 취향과 데이터를 파악한 AI 에이전트가 나를 대리합니다. 지시 없이도 최적의 상품을 쇼핑하고 자산을 투자하는 생태계입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/article&gt;
&lt;!-- Section 2: Scenario (Callout Box) --&gt;
&lt;article id=&quot;sec2&quot; class=&quot;py-10&quot;&gt;
&lt;h2 class=&quot;text-2xl md:text-3xl font-bold text-charcoal mb-8 leading-tight&quot; data-ke-size=&quot;size26&quot;&gt;2. 흥미진진한 가상 시나리오: 판교 직장인 민준 씨의 완벽한 금요일&lt;/h2&gt;
&lt;div class=&quot;relative bg-pastelBlue-50/50 rounded-3xl p-8 md:p-12 border border-pastelBlue-100 overflow-hidden&quot;&gt;
&lt;div class=&quot;absolute top-0 right-0 p-8 opacity-10&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;h4 class=&quot;text-xl font-bold mb-6 text-pastelBlue-600 font-display&quot; data-ke-size=&quot;size20&quot;&gt;[서울 판교 IT 개발자 쭝쓰의 금요일]&lt;/h4&gt;
&lt;blockquote class=&quot;space-y-8 relative z-10&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;div class=&quot;flex gap-4&quot;&gt;
&lt;div class=&quot;flex-shrink-0 w-10 h-10 rounded-full bg-white flex items-center justify-center shadow-sm&quot;&gt;&lt;span class=&quot;text-pastelBlue-500 font-bold&quot;&gt;AI&lt;/span&gt;&lt;/div&gt;
&lt;p class=&quot;bg-white p-4 rounded-2xl rounded-tl-none shadow-sm text-[16px]&quot; data-ke-size=&quot;size16&quot;&gt;&quot;쭝쓰님, 고생 많으셨습니다. 집에 우유가 떨어졌는데, 마침 자주 이용하시는 마트에서 20% 타임 세일을 하기에 &lt;b&gt;자동 주문해 두었습니다.&lt;/b&gt; 내일 아침 7시 문 앞으로 배송됩니다.&quot;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;flex gap-4&quot;&gt;
&lt;div class=&quot;flex-shrink-0 w-10 h-10 rounded-full bg-white flex items-center justify-center shadow-sm&quot;&gt;&lt;span class=&quot;text-pastelBlue-500 font-bold&quot;&gt;AI&lt;/span&gt;&lt;/div&gt;
&lt;p class=&quot;bg-white p-4 rounded-2xl rounded-tl-none shadow-sm text-[16px]&quot; data-ke-size=&quot;size16&quot;&gt;&quot;주말 폭우 예보로 이태원 루프탑은 &lt;b&gt;위약금 없이 대리 취소&lt;/b&gt;했습니다. 대신 평소 취향인 DDP 미디어 아트 VIP 티켓을 예매했습니다. 저녁은 건강검진 수치를 반영해 &lt;b&gt;저염식 포케로 자동 주문&lt;/b&gt; 완료했습니다.&quot;&lt;/p&gt;
&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;mt-10 pt-8 border-t border-pastelBlue-100/50 text-[17px] text-charcoal/80 leading-relaxed italic&quot;&gt;이 시나리오에서 쭝쓰는 손가락 하나 까딱하지 않았습니다. 소비의 주도권이 '인간'에서 'AI 에이전트'로 완전히 이동한 것, 이것이 프록시 경제가 가져올 경이로운 일상입니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/article&gt;
&lt;!-- Section 3 --&gt;
&lt;article id=&quot;sec3&quot; class=&quot;py-10&quot;&gt;
&lt;h2 class=&quot;text-2xl md:text-3xl font-bold text-charcoal mb-10 leading-tight&quot; data-ke-size=&quot;size26&quot;&gt;3. 프록시 경제가 가져올 비즈니스와 일상의 놀라운 변화들&lt;/h2&gt;
&lt;div class=&quot;space-y-12&quot;&gt;&lt;!-- Change 1 --&gt;
&lt;div class=&quot;group&quot;&gt;
&lt;h3 class=&quot;text-xl font-bold text-charcoal mb-4 group-hover:text-pastelBlue-600 transition-colors&quot; data-ke-size=&quot;size23&quot;&gt;① 마케팅 패러다임의 전환: B2A (Business to AI) 마케팅의 부상&lt;/h3&gt;
&lt;p class=&quot;text-charcoal/90 mb-4&quot; data-ke-size=&quot;size16&quot;&gt;지금까지 마케팅의 핵심은 '사람의 감성을 자극하는 것'이었습니다. 하지만 프록시 경제에서는 기업들이 인간이 아닌 &lt;b&gt;'AI 에이전트'를 설득&lt;/b&gt;해야 합니다. AI는 감성 광고에 흔들리지 않습니다. 오직 데이터와 알고리즘만을 보고 주인을 위한 최적의 구매를 결정합니다. 기업들은 이제 B2A(Business to AI) 마케팅에 사활을 걸게 될 것입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;!-- Change 2 --&gt;
&lt;div class=&quot;group&quot;&gt;
&lt;h3 class=&quot;text-xl font-bold text-charcoal mb-4 group-hover:text-pastelBlue-600 transition-colors&quot; data-ke-size=&quot;size23&quot;&gt;② 현대인의 고질병, '선택 장애'의 종말&lt;/h3&gt;
&lt;p class=&quot;text-charcoal/90 mb-4&quot; data-ke-size=&quot;size16&quot;&gt;우리는 매일같이 정보의 홍수 속에서 피곤한 결정의 순간을 맞이합니다. 프록시 경제에서는 나의 심박수, 과거 시청 패턴, 기분까지 수치화하여 파악한 AI가 &lt;b&gt;&quot;지금 당신에게 가장 완벽한 선택지&quot;&lt;/b&gt;를 단 하나로 좁혀 제안하거나 곧바로 실행해 줍니다. 인간은 의사결정의 피로에서 해방됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;!-- Change 3 --&gt;
&lt;div class=&quot;group&quot;&gt;
&lt;h3 class=&quot;text-xl font-bold text-charcoal mb-4 group-hover:text-pastelBlue-600 transition-colors&quot; data-ke-size=&quot;size23&quot;&gt;③ 유례없는 '초개인화(Hyper-personalization)' 서비스의 완성&lt;/h3&gt;
&lt;p class=&quot;text-charcoal/90&quot; data-ke-size=&quot;size16&quot;&gt;단순히 이름을 불러주는 마케팅을 넘어섭니다. 스마트 헤어브러시가 수집한 내 두피의 유분기 데이터를 AI가 분석하여, 현재 내 두피 상태에 가장 잘 맞는 성분이 포함된 새로운 브랜드의 샴푸를 찾아 알아서 결제하고 배송시킵니다. 오직 '나'라는 개인만을 위한 맞춤형 공급망이 완성되는 것입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/article&gt;
&lt;!-- Section 4 (Alert Style) --&gt;
&lt;article id=&quot;sec4&quot; class=&quot;py-10&quot;&gt;
&lt;h2 class=&quot;text-2xl md:text-3xl font-bold text-charcoal mb-8 leading-tight&quot; data-ke-size=&quot;size26&quot;&gt;4. 편리함 이면에 숨겨진 프록시 경제의 그림자&lt;/h2&gt;
&lt;div class=&quot;grid gap-4&quot;&gt;
&lt;div class=&quot;p-6 rounded-2xl bg-gray-50 border-l-4 border-gray-300&quot;&gt;
&lt;h4 class=&quot;font-bold text-charcoal mb-2&quot; data-ke-size=&quot;size20&quot;&gt;우연이 주는 뜻밖의 즐거움(Serendipity) 상실&lt;/h4&gt;
&lt;p class=&quot;text-sm text-softGray&quot; data-ke-size=&quot;size16&quot;&gt;AI가 모든 것을 합리적으로 예측하다 보니, 낯선 골목에서 우연히 발견한 카페의 감동 같은 '우연의 미학'이 사라질 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;p-6 rounded-2xl bg-gray-50 border-l-4 border-gray-300&quot;&gt;
&lt;h4 class=&quot;font-bold text-charcoal mb-2&quot; data-ke-size=&quot;size20&quot;&gt;견고해지는 필터 버블과 확증 편향&lt;/h4&gt;
&lt;p class=&quot;text-sm text-softGray&quot; data-ke-size=&quot;size16&quot;&gt;AI는 과거 데이터를 기반으로 안전한 추천만 합니다. 결국 나의 취향이 좁은 알고리즘 안에 갇히게 될 위험이 높습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;p-6 rounded-2xl bg-pastelBlue-50 border-l-4 border-pastelBlue-500&quot;&gt;
&lt;h4 class=&quot;font-bold text-pastelBlue-600 mb-2&quot; data-ke-size=&quot;size20&quot;&gt;치명적인 보안과 프라이버시 리스크&lt;/h4&gt;
&lt;p class=&quot;text-sm text-softGray&quot; data-ke-size=&quot;size16&quot;&gt;개인의 계좌 정보, 건강 기록, 실시간 위치까지 파악해야 하므로 해킹 시 '디지털 자아' 전체가 유출되는 결과를 초래할 수 있습니다.&lt;/p&gt;
&lt;p class=&quot;text-sm text-softGray&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/article&gt;
&lt;!-- Conclusion --&gt;
&lt;section class=&quot;mt-20 py-12 px-8 rounded-3xl bg-charcoal text-white text-center&quot;&gt;
&lt;div class=&quot;max-w-2xl mx-auto space-y-6&quot;&gt;
&lt;div class=&quot;text-pastelBlue-200 font-bold tracking-widest text-sm uppercase&quot;&gt;Conclusion&lt;/div&gt;
&lt;h3 class=&quot;text-pastelBlue-200 text-2xl md:text-3xl font-bold font-display&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;AI를 '도구'로 쓰던 시대를 넘어,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;'아바타'로 삼는 미래 경제로&lt;/span&gt;&lt;/h3&gt;
&lt;p class=&quot;text-pastelBlue-200 text-[17px] leading-relaxed&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;복잡한 과정은 이제 똑똑한 대리인에게 맡겨두십시오. 다가오는 프록시 경제 속에서 인간은 자잘한 선택의 피로감에서 벗어나, 오직 인간만이 할 수 있는 더 깊은 사유와 창의적인 활동, 가치 있는 일에 온전히 시간을 쏟게 될 것입니다.&lt;/span&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;p class=&quot;text-pastelBlue-200 text-[17px] leading-relaxed&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;text-pastelBlue-200 text-[17px] leading-relaxed&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #006dd7; font-size: 1.25em; letter-spacing: -1px; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span style=&quot;color: #781b33;&quot;&gt;&lt;b&gt;아~~~ 프록시경제의 의미를 이제 알 것 같습니다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #781b33;&quot;&gt;&lt;b&gt;근데 개인적으로 필요한 물건 직접 골라보고, 후기도 검색 해가면서 몰랐던 정보도 알게 되고, &lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #781b33;&quot;&gt;&lt;b&gt;무엇보다도 내가 힘들게 번돈이니 내가 직접 쓰고 싶을 뿐입니다. 카드를 긁던 현금을 내던 힘들게 벌어 쓰는 맛도 있는건데, 왜 AI가 쓰게하는지 좀 거시기 하네요. ㅎㅎ&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #781b33;&quot;&gt;&lt;b&gt;AI 가 주는 편리함과 소비의 쾌락을 바꾸고 싶지는 않을 뿐입니다.&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;text-pastelBlue-200 text-[17px] leading-relaxed&quot; data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7; font-size: 1.25em; letter-spacing: -1px; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이상 &lt;span style=&quot;color: #9d9d9d;&quot;&gt;오래된 프로그래머&lt;/span&gt;였습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/main&gt;</description>
      <category>Tech Story</category>
      <category>AI</category>
      <category>AI대리인</category>
      <category>economy</category>
      <category>Proxy</category>
      <category>경제</category>
      <category>디지털 자아</category>
      <category>프록시</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/83</guid>
      <comments>https://techsuda.tistory.com/entry/IT-Trends-%EB%82%B4%EA%B0%80-%EA%B2%B0%EC%A0%9C%ED%95%98%EC%A7%80-%EC%95%8A%EB%8A%94-%EC%8B%9C%EB%8C%80-%ED%94%84%EB%A1%9D%EC%8B%9C-%EA%B2%BD%EC%A0%9CProxy-Economy%EA%B0%80-%EC%98%A8%EB%8B%A4#entry83comment</comments>
      <pubDate>Sat, 16 May 2026 18:10:21 +0900</pubDate>
    </item>
    <item>
      <title>[Fintech] 기업 성장의 핵심 키워드: 공급망 금융(SCF)</title>
      <link>https://techsuda.tistory.com/entry/Fin</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://cdn.tailwindcss.com&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        brand: {
                            50: '#F0F9FF',
                            100: '#E0F2FE',
                            200: '#BAE6FD',
                            500: '#0EA5E9',
                            800: '#1E40AF',
                            900: '#1E293B',
                        },
                        neutral: {
                            50: '#F8FAFC',
                        }
                    },
                    fontFamily: {
                        sans: ['Inter', 'system-ui', 'sans-serif'],
                        display: ['Outfit', 'sans-serif'],
                    },
                }
            }
        }
    &lt;/script&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1344&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRaqTm/dJMcaaFi1qb/8f7C5WdJzpaF0sUbmTMwyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRaqTm/dJMcaaFi1qb/8f7C5WdJzpaF0sUbmTMwyk/img.png&quot; data-alt=&quot;공급망 금융(Supply Chain Finance, SCF)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRaqTm/dJMcaaFi1qb/8f7C5WdJzpaF0sUbmTMwyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRaqTm%2FdJMcaaFi1qb%2F8f7C5WdJzpaF0sUbmTMwyk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1344&quot; height=&quot;768&quot; data-origin-width=&quot;1344&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;공급망 금융(Supply Chain Finance, SCF)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;article class=&quot;max-w-[850px] mx-auto px-6 pt-12 pb-24 md:pt-20&quot;&gt;&lt;header class=&quot;mb-16 animate-fade-in&quot;&gt;
&lt;div class=&quot;space-y-4&quot;&gt;
&lt;div class=&quot;flex items-center gap-2 text-brand-500 font-bold tracking-widest text-sm uppercase&quot;&gt;&lt;span&gt;Finance&lt;/span&gt; &lt;span class=&quot;w-8 h-[1px] bg-brand-200&quot;&gt;&lt;/span&gt; &lt;span&gt;Supply Chain&lt;/span&gt;&lt;/div&gt;
&lt;h1 class=&quot;text-4xl md:text-5xl font-display font-extrabold text-brand-900 leading-[1.15] tracking-tight&quot;&gt;기업 성장의 핵심 키워드: &lt;span class=&quot;text-transparent bg-clip-text bg-gradient-to-r from-brand-800 to-brand-500&quot;&gt;공급망 금융(SCF)&lt;/span&gt; 도입으로 현금 유동성 극대화하기&lt;/h1&gt;
&lt;/div&gt;
&lt;/header&gt;&lt;!-- Introduction Section --&gt;
&lt;section class=&quot;prose max-w-none animate-fade-in&quot; style=&quot;animation-delay: 0.1s;&quot;&gt;
&lt;p class=&quot;text-xl font-medium leading-relaxed text-slate-600 border-l-4 border-brand-200 pl-6 italic&quot; data-ke-size=&quot;size16&quot;&gt;최근 글로벌 경기 변동성이 커지면서 기업의 &lt;b&gt;운전자본 관리(Working Capital Management)&lt;/b&gt; 능력이 생존과 직결되는 시대가 되었습니다. 특히 자금 조달에 어려움을 겪는 중소기업(SME)과 공급망 안정을 꾀하는 대기업 모두에게 &lt;b&gt;공급망 금융(Supply Chain Finance, SCF)&lt;/b&gt;은 필수적인 전략으로 자리 잡고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글에서는 SCF의 정의부터 작동 원리, 그리고 2026년 최신 트렌드인 ESG 연계 및 선정산 플랫폼 활용 방안까지 상세히 살펴보겠습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;!-- Table of Contents Component --&gt;
&lt;section class=&quot;my-16 animate-fade-in&quot; style=&quot;animation-delay: 0.2s;&quot;&gt;
&lt;div class=&quot;glass-card rounded-3xl p-8 md:p-10&quot;&gt;
&lt;h4 class=&quot;font-display font-bold text-xl text-brand-900 mb-6 flex items-center gap-3&quot; data-ke-size=&quot;size20&quot;&gt;Article Outline&lt;/h4&gt;
&lt;nav&gt;
&lt;ul class=&quot;space-y-4&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a class=&quot;toc-link flex items-center gap-4 transition-all duration-300 font-semibold text-slate-700&quot; href=&quot;#1-scf란-무엇인가&quot;&gt; &lt;span class=&quot;text-brand-500 text-sm opacity-50&quot;&gt;01&lt;/span&gt; &lt;span&gt;SCF란 무엇인가? 정의와 작동 원리&lt;/span&gt; &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;toc-link flex items-center gap-4 transition-all duration-300 font-semibold text-slate-700&quot; href=&quot;#2-왜-지금-scf인가&quot;&gt; &lt;span class=&quot;text-brand-500 text-sm opacity-50&quot;&gt;02&lt;/span&gt; &lt;span&gt;왜 지금 SCF인가? 비즈니스 환경의 변화&lt;/span&gt; &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;toc-link flex items-center gap-4 transition-all duration-300 font-semibold text-slate-700&quot; href=&quot;#3-도입-시-이점&quot;&gt; &lt;span class=&quot;text-brand-500 text-sm opacity-50&quot;&gt;03&lt;/span&gt; &lt;span&gt;도입 시 이점: 구매기업 vs 판매기업&lt;/span&gt; &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;toc-link flex items-center gap-4 transition-all duration-300 font-semibold text-slate-700&quot; href=&quot;#4-최신-트렌드&quot;&gt; &lt;span class=&quot;text-brand-500 text-sm opacity-50&quot;&gt;04&lt;/span&gt; &lt;span&gt;2026년 최신 트렌드: ESG 연계 및 플랫폼&lt;/span&gt; &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;toc-link flex items-center gap-4 transition-all duration-300 font-semibold text-slate-700&quot; href=&quot;#5-결론&quot;&gt; &lt;span class=&quot;text-brand-500 text-sm opacity-50&quot;&gt;05&lt;/span&gt; &lt;span&gt;결론: 성공적인 SCF 도입을 위한 제언&lt;/span&gt; &lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/nav&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;!-- Body Content --&gt;
&lt;div class=&quot;prose max-w-none&quot;&gt;
&lt;section id=&quot;1-scf란-무엇인가&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. SCF란 무엇인가? 공급망 금융의 정의와 작동 원리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공급망 금융(Supply Chain Finance, SCF)&lt;/b&gt;은 구매기업(대기업), 판매기업(공급업체), 그리고 금융기관이 디지털 플랫폼을 통해 결제 프로세스를 연결하여 &lt;b&gt;현금 유동성&lt;/b&gt;을 최적화하는 금융 서비스입니다.&lt;/p&gt;
&lt;div class=&quot;bg-white rounded-2xl p-8 border border-brand-100 shadow-sm mt-8&quot;&gt;
&lt;h4 class=&quot;font-bold text-brand-800 mb-6 text-lg&quot; data-ke-size=&quot;size20&quot;&gt;SCF의 작동 원리 (3자 관계)&lt;/h4&gt;
&lt;div class=&quot;space-y-6&quot;&gt;
&lt;div class=&quot;flex gap-4&quot;&gt;&lt;span class=&quot;flex-shrink-0 w-8 h-8 rounded-full bg-brand-500 text-white flex items-center justify-center font-bold text-sm&quot;&gt;1&lt;/span&gt;
&lt;div&gt;
&lt;p class=&quot;font-bold text-brand-900 mb-1&quot; data-ke-size=&quot;size16&quot;&gt;구매-판매 발생&lt;/p&gt;
&lt;p class=&quot;text-slate-600 text-sm leading-relaxed m-0&quot; data-ke-size=&quot;size16&quot;&gt;판매기업이 물품을 납품하고 구매기업에 송장(Invoice)을 발행합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;flex gap-4&quot;&gt;&lt;span class=&quot;flex-shrink-0 w-8 h-8 rounded-full bg-brand-500 text-white flex items-center justify-center font-bold text-sm&quot;&gt;2&lt;/span&gt;
&lt;div&gt;
&lt;p class=&quot;font-bold text-brand-900 mb-1&quot; data-ke-size=&quot;size16&quot;&gt;송장 승인&lt;/p&gt;
&lt;p class=&quot;text-slate-600 text-sm leading-relaxed m-0&quot; data-ke-size=&quot;size16&quot;&gt;구매기업은 송장을 확인하고 결제를 승인합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;flex gap-4&quot;&gt;&lt;span class=&quot;flex-shrink-0 w-8 h-8 rounded-full bg-brand-500 text-white flex items-center justify-center font-bold text-sm&quot;&gt;3&lt;/span&gt;
&lt;div&gt;
&lt;p class=&quot;font-bold text-brand-900 mb-1&quot; data-ke-size=&quot;size16&quot;&gt;조기 대금 지급(선정산)&lt;/p&gt;
&lt;p class=&quot;text-slate-600 text-sm leading-relaxed m-0&quot; data-ke-size=&quot;size16&quot;&gt;판매기업은 금융기관에 승인된 송장을 담보로 대금을 조기에 지급해 줄 것을 요청합니다. 이때 구매기업의 신용도를 바탕으로 낮은 금리가 적용됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;flex gap-4&quot;&gt;&lt;span class=&quot;flex-shrink-0 w-8 h-8 rounded-full bg-brand-500 text-white flex items-center justify-center font-bold text-sm&quot;&gt;4&lt;/span&gt;
&lt;div&gt;
&lt;p class=&quot;font-bold text-brand-900 mb-1&quot; data-ke-size=&quot;size16&quot;&gt;최종 결제&lt;/p&gt;
&lt;p class=&quot;text-slate-600 text-sm leading-relaxed m-0&quot; data-ke-size=&quot;size16&quot;&gt;원래의 결제 기일에 구매기업이 금융기관에 대금을 상환합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;2-왜-지금-scf인가&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 왜 지금 SCF인가? 비즈니스 환경의 변화&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과거의 기업 금융이 개별 기업의 재무제표에만 의존했다면, 현재의 &lt;b&gt;운전자본 관리&lt;/b&gt;는 공급망 전체의 건강함을 지향합니다.&lt;/p&gt;
&lt;ul class=&quot;custom-bullet space-y-4 pl-0&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li class=&quot;pl-6 font-medium text-slate-700&quot;&gt;&lt;b&gt;고금리 시대의 자금 조달:&lt;/b&gt; 중소기업은 높은 은행 문턱 대신 대기업의 신용을 활용한 저금리 &lt;b&gt;선정산&lt;/b&gt; 서비스를 선호합니다.&lt;/li&gt;
&lt;li class=&quot;pl-6 font-medium text-slate-700&quot;&gt;&lt;b&gt;공급망 안정성 확보:&lt;/b&gt; 원자재 가격 상승과 물류 불안정 속에서 협력사의 파산을 막는 것이 대기업의 리스크 관리 핵심이 되었습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id=&quot;3-도입-시-이점&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 도입 시 이점: 구매기업 vs 판매기업&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SCF는 어느 한쪽만 이득을 보는 구조가 아닌, 공급망 생태계 전체가 윈-윈(Win-Win)하는 모델입니다.&lt;/p&gt;
&lt;div class=&quot;overflow-x-auto my-8 rounded-2xl border border-brand-100 shadow-sm&quot;&gt;
&lt;table class=&quot;w-full text-left border-collapse bg-white&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr class=&quot;bg-brand-50&quot;&gt;
&lt;th class=&quot;p-6 text-brand-900 font-bold border-b border-brand-100&quot;&gt;구분&lt;/th&gt;
&lt;th class=&quot;p-6 text-brand-900 font-bold border-b border-brand-100&quot;&gt;구매기업 (Buyer)&lt;/th&gt;
&lt;th class=&quot;p-6 text-brand-900 font-bold border-b border-brand-100&quot;&gt;판매기업 (Supplier)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody class=&quot;divide-y divide-slate-100&quot;&gt;
&lt;tr&gt;
&lt;td class=&quot;p-6 font-bold text-brand-800 bg-brand-50/30&quot;&gt;핵심 이점&lt;/td&gt;
&lt;td class=&quot;p-6 font-bold text-brand-500&quot;&gt;현금 흐름 최적화&lt;/td&gt;
&lt;td class=&quot;p-6 font-bold text-brand-500&quot;&gt;즉각적인 유동성 확보&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;p-6 font-bold text-brand-800 bg-brand-50/30&quot;&gt;상세 내용&lt;/td&gt;
&lt;td class=&quot;p-6 text-slate-600 text-sm&quot;&gt;결제 대금 지급 기간(DPO) 연장을 통해 사내 현금 보유량을 늘릴 수 있습니다.&lt;/td&gt;
&lt;td class=&quot;p-6 text-slate-600 text-sm&quot;&gt;외상매출채권을 즉시 현금화하여(DSO 단축) 재투자 자금을 확보합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;p-6 font-bold text-brand-800 bg-brand-50/30&quot;&gt;리스크 관리&lt;/td&gt;
&lt;td class=&quot;p-6 text-slate-600 text-sm&quot;&gt;주요 협력사의 자금난으로 인한 공급 중단 리스크를 사전에 방지합니다.&lt;/td&gt;
&lt;td class=&quot;p-6 text-slate-600 text-sm&quot;&gt;자체 신용도보다 낮은 금리로 자금을 조달하여 금융 비용을 절감합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;4-최신-트렌드&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 2026년 최신 트렌드: ESG 연계 및 플랫폼 기반 선정산&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2026년 현재, SCF는 단순한 자금 조달을 넘어 기술과 가치가 결합된 형태로 진화하고 있습니다.&lt;/p&gt;
&lt;div class=&quot;grid md:grid-rows-2 gap-8 mt-10&quot;&gt;
&lt;div class=&quot;bg-brand-50 rounded-3xl p-8 hover:shadow-md transition-shadow duration-300&quot;&gt;
&lt;h3 class=&quot;mt-0 text-brand-800 text-xl font-bold mb-4&quot; data-ke-size=&quot;size23&quot;&gt;① ESG 연계 공급망 금융&lt;/h3&gt;
&lt;p class=&quot;text-sm m-0 leading-relaxed text-slate-600&quot; data-ke-size=&quot;size16&quot;&gt;글로벌 규제 강화에 따라, 협력사가 탄소 배출 저감이나 인권 보호 등 ESG 지표를 달성할 경우 금융기관이 더 낮은 &lt;b&gt;선정산&lt;/b&gt; 금리를 제공하는 모델이 확산되고 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;bg-brand-50 rounded-3xl p-8 hover:shadow-md transition-shadow duration-300&quot;&gt;
&lt;h3 class=&quot;mt-0 text-brand-800 text-xl font-bold mb-4&quot; data-ke-size=&quot;size23&quot;&gt;② 핀테크 및 플랫폼 기반 DX&lt;/h3&gt;
&lt;p class=&quot;text-sm m-0 leading-relaxed text-slate-600&quot; data-ke-size=&quot;size16&quot;&gt;이커머스 플랫폼(쿠팡, 네이버 등)과 연계된 핀테크 SCF는 실시간 매출 데이터를 분석하여 단 몇 분 만에 자금을 집행합니다. 블록체인 기술을 통한 딥티어 금융도 본격화되었습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;5-결론&quot; class=&quot;mt-20&quot;&gt;
&lt;div class=&quot;bg-brand-100 rounded-[32px] p-10 text-white relative overflow-hidden&quot;&gt;
&lt;div class=&quot;absolute top-0 right-0 w-64 h-64 bg-brand-100 rounded-full blur-[120px] opacity-20 -mr-32 -mt-32&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;h2 class=&quot;text-white mt-0 mb-8 border-b border-brand-800 pb-6 text-2xl font-display&quot; data-ke-size=&quot;size26&quot;&gt;5. 결론: 성공적인 SCF 도입을 위한 제언&lt;/h2&gt;
&lt;p class=&quot;text-brand-100 text-lg mb-8&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공급망 금융(SCF)&lt;/b&gt;은 더 이상 선택이 아닌 필수적인 &lt;b&gt;운전자본 관리&lt;/b&gt; 전략입니다.&lt;/p&gt;
&lt;div class=&quot;space-y-6&quot;&gt;
&lt;div class=&quot;flex items-start gap-4&quot;&gt;
&lt;div class=&quot;w-2 h-2 rounded-full bg-brand-500 mt-2 flex-shrink-0&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p class=&quot;m-0 text-brand-50&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;중소기업 대표님:&lt;/b&gt; 높은 금리의 대출 대신, 거래처(구매기업)의 신용을 활용한 &lt;b&gt;선정산&lt;/b&gt; 서비스를 적극 검토하여 자금 유동성을 확보하십시오.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;flex items-start gap-4&quot;&gt;
&lt;div class=&quot;w-2 h-2 rounded-full bg-brand-500 mt-2 flex-shrink-0&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p class=&quot;m-0 text-brand-50&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;대기업 재무 담당자:&lt;/b&gt; 디지털 SCF 플랫폼 도입을 통해 협력사와의 상생 결제 생태계를 구축하고, 기업의 ESG 평가 지수를 높이는 기회로 삼으시길 바랍니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class=&quot;mt-10 font-medium text-brand-200&quot; data-ke-size=&quot;size16&quot;&gt;미래의 비즈니스 경쟁력은 단일 기업의 능력이 아닌, 그 기업이 속한 공급망이 얼마나 유연하고 건강하게 자금을 회전시키느냐에 달려 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/div&gt;
&lt;!-- Meta/Tags --&gt;
&lt;div class=&quot;mt-16 pt-8 border-t border-slate-200 flex flex-wrap gap-2&quot;&gt;&lt;span class=&quot;px-4 py-1.5 bg-slate-100 text-slate-500 text-xs font-bold rounded-full&quot;&gt;#SCF&lt;/span&gt; &lt;span class=&quot;px-4 py-1.5 bg-slate-100 text-slate-500 text-xs font-bold rounded-full&quot;&gt;#공급망금융&lt;/span&gt; &lt;span class=&quot;px-4 py-1.5 bg-slate-100 text-slate-500 text-xs font-bold rounded-full&quot;&gt;#운전자본관리&lt;/span&gt; &lt;span class=&quot;px-4 py-1.5 bg-slate-100 text-slate-500 text-xs font-bold rounded-full&quot;&gt;#현금유동성&lt;/span&gt; &lt;span class=&quot;px-4 py-1.5 bg-slate-100 text-slate-500 text-xs font-bold rounded-full&quot;&gt;#선정산&lt;/span&gt; &lt;span class=&quot;px-4 py-1.5 bg-slate-100 text-slate-500 text-xs font-bold rounded-full&quot;&gt;#ESG경영&lt;/span&gt; &lt;span class=&quot;px-4 py-1.5 bg-slate-100 text-slate-500 text-xs font-bold rounded-full&quot;&gt;#핀테크&lt;/span&gt;&lt;/div&gt;
&lt;/article&gt;
&lt;script&gt;
        // Simple scroll reveal or subtle interactions can go here
        document.addEventListener('DOMContentLoaded', () =&gt; {
            const sections = document.querySelectorAll('section');
            const observerOptions = {
                threshold: 0.1
            };

            const observer = new IntersectionObserver((entries) =&gt; {
                entries.forEach(entry =&gt; {
                    if (entry.isIntersecting) {
                        entry.target.classList.add('opacity-100');
                        entry.target.classList.remove('opacity-0');
                    }
                });
            }, observerOptions);

            sections.forEach(section =&gt; {
                section.classList.add('transition-opacity', 'duration-1000');
            });
        });
    &lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <category>ESG경영</category>
      <category>scf</category>
      <category>공급망금융</category>
      <category>선정산</category>
      <category>운전자본관리</category>
      <category>핀테크</category>
      <category>현금유동성</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/82</guid>
      <comments>https://techsuda.tistory.com/entry/Fin#entry82comment</comments>
      <pubDate>Tue, 12 May 2026 17:14:06 +0900</pubDate>
    </item>
    <item>
      <title>[AI] Claude Code 비용 절감 및 Ollama 로컬 LLM 가이드</title>
      <link>https://techsuda.tistory.com/entry/AI-Claude-Code-%EB%B9%84%EC%9A%A9-%EC%A0%88%EA%B0%90-%EB%B0%8F-Ollama-%EB%A1%9C%EC%BB%AC-LLM-%EA%B0%80%EC%9D%B4%EB%93%9C</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DeTMx/dJMcahEmFuX/jdM5IxkMg5kEGEg2XbKkD0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DeTMx/dJMcahEmFuX/jdM5IxkMg5kEGEg2XbKkD0/img.jpg&quot; data-alt=&quot;ClaudeCode &amp;amp;amp; Ollama&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DeTMx/dJMcahEmFuX/jdM5IxkMg5kEGEg2XbKkD0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDeTMx%2FdJMcahEmFuX%2FjdM5IxkMg5kEGEg2XbKkD0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1376&quot; height=&quot;768&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ClaudeCode &amp;amp; Ollama&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://cdn.tailwindcss.com&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        brand: {
                            50: '#F0F9FF',
                            100: '#E0F2FE',
                            200: '#BAE6FD',
                            500: '#0EA5E9',
                            800: '#1E40AF',
                            900: '#1E293B',
                        },
                        surface: '#F8FAFC',
                    },
                    fontFamily: {
                        sans: ['Inter', 'system-ui', 'sans-serif'],
                        display: ['Outfit', 'Inter', 'sans-serif'],
                    },
                },
            },
        }
    &lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;article class=&quot;max-w-[800px] mx-auto px-6 py-12 md:py-20&quot;&gt;&lt;!-- Hero Section --&gt;&lt;header class=&quot;mb-16&quot;&gt;
&lt;h1 class=&quot;font-display text-4xl md:text-5xl lg:text-6xl text-brand-900 leading-[1.15] tracking-tight mb-8&quot;&gt;클로드 코드(Claude Code) 토큰 비용 줄이는 법 &amp;amp; Ollama 로컬 LLM 맞춤 모델 추천&lt;/h1&gt;
&lt;p class=&quot;text-xl text-slate-600 leading-relaxed italic border-l-4 border-brand-200 pl-6&quot; data-ke-size=&quot;size16&quot;&gt;최근 Anthropic에서 출시한 클로드 코드(Claude Code)는 강력한 코딩 성능을 발휘하지만, 종량제 방식의 특성상 비용 최적화가 필수입니다. 효율적인 AI 개발 환경 구축을 위한 모든 노하우를 공개합니다.&lt;/p&gt;
&lt;/header&gt;&lt;!-- Outline Card (Table of Contents) --&gt;&lt;nav class=&quot;glass-card rounded-2xl p-8 mb-20 bg-brand-50/50&quot;&gt;
&lt;h2 class=&quot;font-display text-lg uppercase tracking-wider text-brand-500 mb-4&quot; data-ke-size=&quot;size26&quot;&gt;Article Outline&lt;/h2&gt;
&lt;ul class=&quot;space-y-3&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a class=&quot;outline-link block text-brand-900 font-medium&quot; href=&quot;#section-1&quot;&gt;1. Claude Code 비용 체계 이해와 컨텍스트 오버헤드&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;outline-link block text-brand-900 font-medium&quot; href=&quot;#section-2&quot;&gt;2. Claude Code 토큰 비용을 줄이는 4가지 핵심 팁&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;outline-link block text-brand-900 font-medium&quot; href=&quot;#section-3&quot;&gt;3. API 비용 걱정 없는 Ollama 로컬 LLM 활용법&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;outline-link block text-brand-900 font-medium&quot; href=&quot;#section-4&quot;&gt;4. 업무별 최적의 로컬 코딩 모델 추천&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;outline-link block text-brand-900 font-medium&quot; href=&quot;#section-5&quot;&gt;5. 결론: 가성비와 성능의 균형 잡기&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/nav&gt;&lt;!-- Body Content --&gt;
&lt;div class=&quot;space-y-24&quot;&gt;
&lt;section id=&quot;section-1&quot;&gt;
&lt;h2 class=&quot;font-display text-3xl text-brand-900 mb-6&quot; data-ke-size=&quot;size26&quot;&gt;1. Claude Code 비용 체계와 컨텍스트 오버헤드&lt;/h2&gt;
&lt;div class=&quot;text-lg text-slate-700 space-y-4&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Claude Code는 별도의 월 구독료 없이 &lt;b&gt;사용량 기반(Pay-as-you-go)&lt;/b&gt;으로 과금됩니다. Anthropic Console 계정의 크레딧에서 사용한 토큰(입력 및 출력)만큼 차감되는 방식입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주의할 점은 CLI 에이전트의 특성상 &lt;b&gt;'컨텍스트 오버헤드'&lt;/b&gt;가 발생한다는 것입니다. 에이전트가 파일 구조를 분석하고, 이전 대화 기록과 쉘 명령어 실행 결과를 계속해서 맥락에 포함시키기 때문에 대화가 길어질수록 토큰 소모량이 가파르게 상승합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;section-2&quot;&gt;
&lt;h2 class=&quot;font-display text-3xl text-brand-900 mb-6&quot; data-ke-size=&quot;size26&quot;&gt;2. Claude Code 토큰 비용을 줄이는 4가지 핵심 팁&lt;/h2&gt;
&lt;p class=&quot;text-lg text-slate-700 mb-8&quot; data-ke-size=&quot;size16&quot;&gt;비용 효율적인 AI 코딩을 위해 다음의 설정과 습관을 반드시 적용해 보세요.&lt;/p&gt;
&lt;div class=&quot;grid gap-6&quot;&gt;
&lt;div class=&quot;p-6 rounded-xl border border-slate-100 hover:border-brand-200 transition-colors&quot;&gt;
&lt;h3 class=&quot;font-bold text-xl text-brand-800 mb-3&quot; data-ke-size=&quot;size23&quot;&gt;① .claudeignore 파일 활용&lt;/h3&gt;
&lt;p class=&quot;text-slate-600&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트 루트 폴더에 &lt;code&gt;.claudeignore&lt;/code&gt; 파일을 생성하세요. &lt;code&gt;node_modules&lt;/code&gt;, 빌드 결과물, 대용량 이미지 등을 제외하면 초기 인덱싱 시 소모되는 토큰을 대폭 줄일 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;p-6 rounded-xl border border-slate-100 hover:border-brand-200 transition-colors&quot;&gt;
&lt;h3 class=&quot;font-bold text-xl text-brand-800 mb-3&quot; data-ke-size=&quot;size23&quot;&gt;② 주기적인 /clear 명령 사용&lt;/h3&gt;
&lt;p class=&quot;text-slate-600&quot; data-ke-size=&quot;size16&quot;&gt;특정 작업이 완료되었거나 주제를 바꿀 때는 &lt;code&gt;/clear&lt;/code&gt; 명령어를 사용하여 대화 이력을 초기화하는 것이 좋습니다. 불필요한 정보 전송을 막아줍니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;p-6 rounded-xl border border-slate-100 hover:border-brand-200 transition-colors&quot;&gt;
&lt;h3 class=&quot;font-bold text-xl text-brand-800 mb-3&quot; data-ke-size=&quot;size23&quot;&gt;③ 질문의 구체화 및 범위 한정&lt;/h3&gt;
&lt;p class=&quot;text-slate-600&quot; data-ke-size=&quot;size16&quot;&gt;&quot;이 프로젝트 전체를 설명해줘&quot;와 같은 포괄적인 질문은 피하세요. &quot;A 파일의 B 함수 로직을 수정해줘&quot;와 같이 명확한 범위를 지정하는 것이 경제적입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;p-6 rounded-xl border border-slate-100 hover:border-brand-200 transition-colors&quot;&gt;
&lt;h3 class=&quot;font-bold text-xl text-brand-800 mb-3&quot; data-ke-size=&quot;size23&quot;&gt;④ --compact 모드 활용&lt;/h3&gt;
&lt;p class=&quot;text-slate-600&quot; data-ke-size=&quot;size16&quot;&gt;Claude의 장황한 설명을 줄이고 코드 위주의 답변을 원한다면 &lt;code&gt;--compact&lt;/code&gt; 모드를 사용하세요. 출력 토큰 수를 절약하여 비용을 아낄 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;section-3&quot;&gt;
&lt;h2 class=&quot;font-display text-3xl text-brand-900 mb-6&quot; data-ke-size=&quot;size26&quot;&gt;3. API 비용 걱정 없는 Ollama 로컬 LLM 활용법&lt;/h2&gt;
&lt;div class=&quot;bg-brand-50 rounded-2xl p-8 space-y-6&quot;&gt;
&lt;p class=&quot;text-lg text-slate-700&quot; data-ke-size=&quot;size16&quot;&gt;API 비용이 부담스럽다면 자신의 PC 리소스(GPU/RAM)를 사용하는 &lt;b&gt;Ollama&lt;/b&gt;가 훌륭한 대안이 됩니다.&lt;/p&gt;
&lt;ul class=&quot;space-y-4&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li class=&quot;custom-bullet text-slate-700&quot;&gt;&lt;b&gt;비용 Zero:&lt;/b&gt; 외부 API를 호출하지 않으므로 비용이 전혀 발생하지 않습니다.&lt;/li&gt;
&lt;li class=&quot;custom-bullet text-slate-700&quot;&gt;&lt;b&gt;프라이버시 보안:&lt;/b&gt; 코드가 외부 서버로 전송되지 않아 보안이 중요한 기업용 프로젝트에 적합합니다.&lt;/li&gt;
&lt;li class=&quot;custom-bullet text-slate-700&quot;&gt;&lt;b&gt;무제한 테스트:&lt;/b&gt; 복잡한 리팩토링이나 대규모 파일 분석도 비용 부담 없이 무한 반복할 수 있습니다.&lt;/li&gt;
&lt;li class=&quot;custom-bullet text-slate-700&quot;&gt;&lt;b&gt;도구 결합:&lt;/b&gt; &lt;code&gt;Aider&lt;/code&gt;나 &lt;code&gt;Continue&lt;/code&gt;와 같은 오픈소스 도구의 백엔드를 Ollama로 설정하면 유사한 경험을 누릴 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;section-4&quot;&gt;
&lt;h2 class=&quot;font-display text-3xl text-brand-900 mb-6&quot; data-ke-size=&quot;size26&quot;&gt;4. 업무별 최적의 로컬 코딩 모델 추천&lt;/h2&gt;
&lt;div class=&quot;overflow-x-auto&quot;&gt;
&lt;table class=&quot;w-full text-left border-collapse border border-slate-200 rounded-lg&quot; style=&quot;height: 177px;&quot; width=&quot;837&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr class=&quot;bg-slate-50&quot;&gt;
&lt;th class=&quot;p-4 border border-slate-200 font-bold text-brand-900&quot;&gt;활용 상황&lt;/th&gt;
&lt;th class=&quot;p-4 border border-slate-200 font-bold text-brand-900&quot;&gt;추천 모델&lt;/th&gt;
&lt;th class=&quot;p-4 border border-slate-200 font-bold text-brand-900&quot;&gt;특징&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody class=&quot;text-slate-700&quot;&gt;
&lt;tr&gt;
&lt;td class=&quot;p-4 border border-slate-200 font-medium&quot;&gt;일반 코딩 및 로직&lt;/td&gt;
&lt;td class=&quot;p-4 border border-slate-200&quot;&gt;Codestral (22B)&lt;/td&gt;
&lt;td class=&quot;p-4 border border-slate-200 text-sm&quot;&gt;80개 이상 언어 지원, 강력한 파이썬 성능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;bg-brand-50/30&quot;&gt;
&lt;td class=&quot;p-4 border border-slate-200 font-medium&quot;&gt;빠른 자동완성&lt;/td&gt;
&lt;td class=&quot;p-4 border border-slate-200&quot;&gt;Qwen2.5-Coder (7B)&lt;/td&gt;
&lt;td class=&quot;p-4 border border-slate-200 text-sm&quot;&gt;로컬 성능 1위 기록, 매우 가볍고 빠른 응답&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;p-4 border border-slate-200 font-medium&quot;&gt;심층 추론 및 설계&lt;/td&gt;
&lt;td class=&quot;p-4 border border-slate-200&quot;&gt;DeepSeek-R1 (32B/70B)&lt;/td&gt;
&lt;td class=&quot;p-4 border border-slate-200 text-sm&quot;&gt;복잡한 알고리즘 및 아키텍처 설계에 탁월&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;bg-brand-50/30&quot;&gt;
&lt;td class=&quot;p-4 border border-slate-200 font-medium&quot;&gt;문서화 및 주석&lt;/td&gt;
&lt;td class=&quot;p-4 border border-slate-200&quot;&gt;Llama 3.1 (8B)&lt;/td&gt;
&lt;td class=&quot;p-4 border border-slate-200 text-sm&quot;&gt;한국어 지원 능력 우수, 한글 주석 작성 최적&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;section-5&quot;&gt;
&lt;h2 class=&quot;font-display text-3xl text-brand-900 mb-6&quot; data-ke-size=&quot;size26&quot;&gt;5. 결론: 가성비와 성능의 균형 잡기&lt;/h2&gt;
&lt;div class=&quot;prose prose-lg text-slate-700&quot;&gt;
&lt;p class=&quot;mb-6&quot; data-ke-size=&quot;size16&quot;&gt;가장 현명한 전략은 &lt;b&gt;'하이브리드' 방식&lt;/b&gt;을 채택하는 것입니다.&lt;/p&gt;
&lt;ol class=&quot;space-y-4 list-decimal pl-5 marker:text-brand-500 marker:font-bold&quot; style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;단순 코드 수정, 주석 작성, 로컬 테스트:&lt;/b&gt; 비용이 들지 않는 &lt;b&gt;Ollama(Qwen2.5-Coder, DeepSeek-R1)&lt;/b&gt;를 사용합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;복잡한 전체 비즈니스 로직 수정 및 고난도 문제 해결:&lt;/b&gt; 최고의 성능을 자랑하는 &lt;b&gt;Claude Code(Claude 3.5 Sonnet)&lt;/b&gt;를 사용하되, 앞서 언급한 절약 팁을 적용합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p class=&quot;mt-8 font-medium text-brand-900 bg-brand-100/50 p-6 rounded-xl text-center&quot; data-ke-size=&quot;size16&quot;&gt;이러한 최적화 전략을 통해 비용 부담은 최소화하면서, 최신 AI 기술을 활용한 압도적인 개발 생산성을 경험해 보시기 바랍니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/div&gt;
&lt;/article&gt;
&lt;script&gt;
        // Smooth scroll for outline links
        document.querySelectorAll('.outline-link').forEach(anchor =&gt; {
            anchor.addEventListener('click', function (e) {
                e.preventDefault();
                const targetId = this.getAttribute('href');
                document.querySelector(targetId).scrollIntoView({
                    behavior: 'smooth'
                });
            });
        });

        // Simple reveal animation on scroll
        const observerOptions = {
            threshold: 0.1
        };

        const observer = new IntersectionObserver((entries) =&gt; {
            entries.forEach(entry =&gt; {
                if (entry.isIntersecting) {
                    entry.target.style.opacity = &quot;1&quot;;
                    entry.target.style.transform = &quot;translateY(0)&quot;;
                }
            });
        }, observerOptions);

        document.querySelectorAll('section').forEach(section =&gt; {
            section.style.opacity = &quot;0&quot;;
            section.style.transform = &quot;translateY(20px)&quot;;
            section.style.transition = &quot;all 0.6s ease-out&quot;;
            observer.observe(section);
        });
    &lt;/script&gt;</description>
      <category>Tech Story</category>
      <category>claude code</category>
      <category>ollama</category>
      <category>로컬llm</category>
      <category>비용</category>
      <category>클로드코드</category>
      <category>토큰</category>
      <category>하이브리드</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/81</guid>
      <comments>https://techsuda.tistory.com/entry/AI-Claude-Code-%EB%B9%84%EC%9A%A9-%EC%A0%88%EA%B0%90-%EB%B0%8F-Ollama-%EB%A1%9C%EC%BB%AC-LLM-%EA%B0%80%EC%9D%B4%EB%93%9C#entry81comment</comments>
      <pubDate>Mon, 11 May 2026 23:49:30 +0900</pubDate>
    </item>
    <item>
      <title>[Flutter] Flutter 백그라운드 처리 가이드</title>
      <link>https://techsuda.tistory.com/entry/Flutter-Flutter-%EB%B0%B1%EA%B7%B8%EB%9D%BC%EC%9A%B4%EB%93%9C-%EC%B2%98%EB%A6%AC-%EA%B0%80%EC%9D%B4%EB%93%9C</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://cdn.tailwindcss.com&quot;&gt;&lt;/script&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sziDX/dJMcaciJa24/KUfh83WOrGLYiZkKBLpuPK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sziDX/dJMcaciJa24/KUfh83WOrGLYiZkKBLpuPK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sziDX/dJMcaciJa24/KUfh83WOrGLYiZkKBLpuPK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsziDX%2FdJMcaciJa24%2FKUfh83WOrGLYiZkKBLpuPK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1376&quot; height=&quot;768&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;script&gt;
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        brand: {
                            50: '#F0F9FF',
                            100: '#E0F2FE',
                            200: '#BAE6FD',
                            500: '#0EA5E9',
                            600: '#0284C7',
                            900: '#0F172A',
                        },
                        neutral: {
                            50: '#F8FAFC',
                            900: '#1E293B',
                        }
                    },
                    fontFamily: {
                        sans: ['Inter', 'system-ui', 'sans-serif'],
                        display: ['Outfit', 'sans-serif'],
                    },
                    animation: {
                        'fade-in': 'fadeIn 0.8s ease-out forwards',
                        'slide-up': 'slideUp 0.6s ease-out forwards',
                    },
                    keyframes: {
                        fadeIn: {
                            '0%': { opacity: '0' },
                            '100%': { opacity: '1' },
                        },
                        slideUp: {
                            '0%': { transform: 'translateY(20px)', opacity: '0' },
                            '100%': { transform: 'translateY(0)', opacity: '1' },
                        }
                    }
                }
            }
        }
    &lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;article class=&quot;max-w-[800px] mx-auto px-6 py-12 md:py-20 animate-fade-in&quot;&gt;&lt;header class=&quot;mb-16&quot;&gt;
&lt;div class=&quot;space-y-4&quot;&gt;
&lt;h1 class=&quot;text-4xl md:text-5xl lg:text-6xl font-display font-extrabold text-brand-900 leading-[1.1] tracking-tight&quot;&gt;Flutter 백그라운드 처리 가이드: Workmanager부터 Isolate까지&lt;/h1&gt;
&lt;p class=&quot;text-lg text-slate-500 font-medium&quot; data-ke-size=&quot;size16&quot;&gt;최신 OS 정책을 고려한 효율적인 앱 백그라운드 전략 수립하기&lt;/p&gt;
&lt;/div&gt;
&lt;/header&gt;
&lt;!-- Introduction Section --&gt;
&lt;section class=&quot;prose mb-16&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flutter 앱을 개발하다 보면 앱이 화면에 보이지 않는 상태(Background)에서도 데이터를 동기화하거나, 위치 정보를 수집하거나, 로컬 알림을 보내야 하는 상황이 발생합니다. 하지만 모바일 OS(Android, iOS)는 배터리 효율을 위해 백그라운드 작업을 엄격하게 제한하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 포스팅에서는 최근 기술 트렌드를 반영하여, Flutter에서 백그라운드 처리를 효율적으로 구현하는 방법을 가볍게 정리하고자 합니다.&lt;/p&gt;
&lt;/section&gt;
&lt;!-- Table of Contents (Outline Card) --&gt;&lt;nav class=&quot;mb-20 p-8 rounded-3xl bg-brand-50 border border-brand-100 animate-slide-up&quot; style=&quot;animation-delay: 0.1s;&quot;&gt;
&lt;h2 class=&quot;text-xl font-display font-bold text-brand-900 mb-6 flex items-center&quot; data-ke-size=&quot;size26&quot;&gt;Article Outline&lt;/h2&gt;
&lt;div class=&quot;grid grid-cols-1&quot;&gt;&lt;a class=&quot;toc-link text-slate-600 font-medium&quot; href=&quot;#1-백그라운드-처리의-개념과-중요성&quot;&gt;1. 백그라운드 처리의 개념과 중요성&lt;/a&gt; &lt;a class=&quot;toc-link text-slate-600 font-medium&quot; href=&quot;#2-dart의-동시성-모델-isolate-이해하기&quot;&gt;2. Dart의 동시성 모델: Isolate 이해하기&lt;/a&gt; &lt;a class=&quot;toc-link text-slate-600 font-medium&quot; href=&quot;#3-주요-백그라운드-작업-유형&quot;&gt;3. 주요 백그라운드 작업 유형&lt;/a&gt; &lt;a class=&quot;toc-link text-slate-600 font-medium&quot; href=&quot;#4-추천-패키지 및-구현-방법&quot;&gt;4. 추천 패키지 및 구현 방법&lt;/a&gt; &lt;a class=&quot;toc-link text-slate-600 font-medium&quot; href=&quot;#5-플랫폼별-고려사항-android-vs-ios&quot;&gt;5. 플랫폼별 고려사항 (Android vs iOS)&lt;/a&gt; &lt;a class=&quot;toc-link text-slate-600 font-medium&quot; href=&quot;#6-성능-최적화 및-주의사항&quot;&gt;6. 성능 최적화 및 주의사항&lt;/a&gt; &lt;a class=&quot;toc-link text-slate-600 font-medium&quot; href=&quot;#7-결론&quot;&gt;7. 결론&lt;/a&gt;&lt;/div&gt;
&lt;/nav&gt;&lt;!-- Content Body --&gt;
&lt;div class=&quot;prose&quot;&gt;
&lt;section id=&quot;1-백그라운드-처리의-개념과-중요성&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 백그라운드 처리의 개념과 중요성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백그라운드 처리는 사용자가 앱을 사용하지 않을 때(앱이 종료되었거나 백그라운드 상태일 때) 코드를 실행하는 기술을 말합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;사용자 경험 향상:&lt;/b&gt; 최신 데이터를 미리 로드하여 앱 실행 시 대기 시간 단축.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;지속적 서비스 제공:&lt;/b&gt; 음악 재생, GPS 트래킹, 실시간 채팅 수신.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;시스템 자동화:&lt;/b&gt; 정기적인 데이터 백업 및 서버 동기화.&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id=&quot;2-dart의-동시성-모델-isolate-이해하기&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Dart의 동시성 모델: Isolate 이해하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flutter의 기본 언어인 Dart는 단일 스레드(Single-threaded)로 동작하지만, &lt;b&gt;Isolate&lt;/b&gt;라는 개념을 통해 병렬 처리를 지원합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Main Isolate:&lt;/b&gt; UI 렌더링과 사용자 이벤트를 처리합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Background Isolate:&lt;/b&gt; 무거운 연산이나 백그라운드 작업을 UI 스레드 방해 없이 수행합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최신 트렌드:&lt;/b&gt; &lt;code&gt;Isolate.run()&lt;/code&gt; 메서드를 통해 복잡한 설정 없이도 간단한 연산을 다른 isolate로 보낼 수 있게 되었습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id=&quot;3-주요-백그라운드-작업-유형&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 주요 백그라운드 작업 유형&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱의 요구사항에 따라 적절한 전략을 선택해야 합니다.&lt;/p&gt;
&lt;ol class=&quot;list-decimal pl-5 space-y-4&quot; style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span class=&quot;font-bold text-brand-900&quot;&gt;일시적 작업 (Temporary Tasks):&lt;/span&gt; HTTP 요청이나 파일 저장 등 짧은 시간에 끝나는 작업.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;font-bold text-brand-900&quot;&gt;예약/주기적 작업 (Periodic Tasks):&lt;/span&gt; 15분마다 날씨 업데이트, 매일 밤 데이터 동기화.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;font-bold text-brand-900&quot;&gt;장기 실행 작업 (Long-running Tasks):&lt;/span&gt; 음악 스트리밍, 운동 경로 추적(GPS).&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;font-bold text-brand-900&quot;&gt;푸시 기반 작업 (Triggered Tasks):&lt;/span&gt; 서버에서 보낸 푸시 알림에 반응하여 데이터를 처리.&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id=&quot;4-추천-패키지 및-구현-방법&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 추천 패키지 및 구현 방법&lt;/h2&gt;
&lt;div class=&quot;my-8 space-y-6&quot;&gt;
&lt;div class=&quot;p-6 rounded-2xl bg-white border border-slate-100 shadow-sm&quot;&gt;
&lt;h3 class=&quot;!mt-0&quot; data-ke-size=&quot;size23&quot;&gt;Workmanager (가장 대중적)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Android의 WorkManager와 iOS의 PerformFetch를 래핑한 패키지로, 주기적인 작업을 실행할 때 표준으로 사용됩니다.&lt;/p&gt;
&lt;ul class=&quot;text-sm&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;주요 특징:&lt;/b&gt; 앱이 종료되어도 실행 보장, 배터리 최적화 고려.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;사용 예시:&lt;/b&gt; &lt;code&gt;Workmanager().registerPeriodicTask(&quot;1&quot;, &quot;simplePeriodicTask&quot;, frequency: Duration(minutes: 15))&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;p-6 rounded-2xl bg-white border border-slate-100 shadow-sm&quot;&gt;
&lt;h3 class=&quot;!mt-0&quot; data-ke-size=&quot;size23&quot;&gt;flutter_background_service&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱이 백그라운드에서도 종료되지 않고 계속해서 실행되어야 할 때 사용합니다.&lt;/p&gt;
&lt;ul class=&quot;text-sm&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;주요 특징:&lt;/b&gt; 포그라운드 서비스(Foreground Service)를 활용하여 OS에 의해 종료될 확률을 낮춤.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;용도:&lt;/b&gt; 실시간 위치 추적, 타이머 앱.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;p-6 rounded-2xl bg-white border border-slate-100 shadow-sm&quot;&gt;
&lt;h3 class=&quot;!mt-0&quot; data-ke-size=&quot;size23&quot;&gt;background_fetch&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주로 iOS의 백그라운드 업데이트 제한에 맞추어 설계된 패키지로, 약 15~30분 간격으로 깨어나 짧은 작업을 수행하는 데 최적화되어 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;5-플랫폼별-고려사항-android-vs-ios&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 플랫폼별 고려사항 (Android vs iOS)&lt;/h2&gt;
&lt;div class=&quot;grid md:grid-cols-2 gap-8 mt-8&quot;&gt;
&lt;div class=&quot;bg-blue-50/50 p-6 rounded-3xl border border-blue-100&quot;&gt;
&lt;h3 class=&quot;!mt-0 flex items-center&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;w-8 h-8 rounded-full bg-blue-500 text-white flex items-center justify-center text-sm mr-2&quot;&gt;A&lt;/span&gt; Android&lt;/h3&gt;
&lt;p class=&quot;text-sm&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;배터리 최적화 (Doze Mode):&lt;/b&gt; Android 12 이상부터는 백그라운드 실행 제한이 더 엄격해졌습니다. &lt;code&gt;Exact Alarm&lt;/code&gt; 권한이나 포그라운드 서비스 알림이 필수적일 수 있습니다.&lt;/p&gt;
&lt;p class=&quot;text-sm&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;제조사별 정책:&lt;/b&gt; 삼성, 샤오미 등 제조사마다 백그라운드 앱을 강제 종료하는 정책이 다르므로 테스트가 필수입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;bg-slate-50 p-6 rounded-3xl border border-slate-200&quot;&gt;
&lt;h3 class=&quot;!mt-0 flex items-center&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span class=&quot;w-8 h-8 rounded-full bg-slate-800 text-white flex items-center justify-center text-sm mr-2&quot;&gt;i&lt;/span&gt; iOS&lt;/h3&gt;
&lt;p class=&quot;text-sm&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;시간 제한:&lt;/b&gt; iOS는 백그라운드 작업에 매우 보수적입니다. 보통 한 번 깨어났을 때 약 30초 내외의 시간만 주어집니다.&lt;/p&gt;
&lt;p class=&quot;text-sm&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Background Tasks Framework:&lt;/b&gt; &lt;code&gt;BGTaskScheduler&lt;/code&gt;를 등록하여 OS가 적절한 타이밍(충전 중, Wi-Fi 연결 등)에 작업을 실행하도록 맡겨야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;6-성능-최적화 및-주의사항&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 성능 최적화 및 주의사항&lt;/h2&gt;
&lt;div class=&quot;grid grid-cols-1 gap-4&quot;&gt;
&lt;div class=&quot;flex items-start p-4 bg-white border border-slate-100 rounded-xl&quot;&gt;
&lt;div class=&quot;mr-4 mt-1 text-brand-500 font-bold&quot;&gt;1&lt;/div&gt;
&lt;div&gt;
&lt;p class=&quot;font-bold mb-1 !text-brand-900&quot; data-ke-size=&quot;size16&quot;&gt;최소한의 리소스 사용&lt;/p&gt;
&lt;p class=&quot;text-sm !mb-0 text-slate-500&quot; data-ke-size=&quot;size16&quot;&gt;백그라운드에서는 메모리와 CPU 사용량을 최소화해야 합니다. 과도한 사용은 OS에 의한 강제 종료의 주원인입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;flex items-start p-4 bg-white border border-slate-100 rounded-xl&quot;&gt;
&lt;div class=&quot;mr-4 mt-1 text-brand-500 font-bold&quot;&gt;2&lt;/div&gt;
&lt;div&gt;
&lt;p class=&quot;font-bold mb-1 !text-brand-900&quot; data-ke-size=&quot;size16&quot;&gt;네트워크 상태 체크&lt;/p&gt;
&lt;p class=&quot;text-sm !mb-0 text-slate-500&quot; data-ke-size=&quot;size16&quot;&gt;데이터가 필요한 작업의 경우, 네트워크가 연결되었을 때만 실행되도록 제약 조건을 설정하세요.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;flex items-start p-4 bg-white border border-slate-100 rounded-xl&quot;&gt;
&lt;div class=&quot;mr-4 mt-1 text-brand-500 font-bold&quot;&gt;3&lt;/div&gt;
&lt;div&gt;
&lt;p class=&quot;font-bold mb-1 !text-brand-900&quot; data-ke-size=&quot;size16&quot;&gt;플러그인 초기화&lt;/p&gt;
&lt;p class=&quot;text-sm !mb-0 text-slate-500&quot; data-ke-size=&quot;size16&quot;&gt;백그라운드 Isolate는 메인 앱과 별개의 메모리 공간을 갖습니다. 따라서 &lt;code&gt;WidgetsFlutterBinding.ensureInitialized()&lt;/code&gt;를 호출해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;flex items-start p-4 bg-white border border-slate-100 rounded-xl&quot;&gt;
&lt;div class=&quot;mr-4 mt-1 text-brand-500 font-bold&quot;&gt;4&lt;/div&gt;
&lt;div&gt;
&lt;p class=&quot;font-bold mb-1 !text-brand-900&quot; data-ke-size=&quot;size16&quot;&gt;에러 핸들링&lt;/p&gt;
&lt;p class=&quot;text-sm !mb-0 text-slate-500&quot; data-ke-size=&quot;size16&quot;&gt;로그를 저장하거나 로컬 알림(flutter_local_notifications)을 통해 상태를 알려야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;7-결론&quot; class=&quot;bg-brand-900 text-white p-10 rounded-[2.5rem] mt-20&quot;&gt;
&lt;h2 class=&quot;!text-white !mt-0 mb-6&quot; data-ke-size=&quot;size26&quot;&gt;7. 결론&lt;/h2&gt;
&lt;p class=&quot;!text-brand-100&quot; data-ke-size=&quot;size16&quot;&gt;Flutter에서 백그라운드 처리를 구현하는 것은 앱의 완성도를 결정짓는 핵심 요소입니다.&lt;/p&gt;
&lt;div class=&quot;space-y-3 mb-8&quot;&gt;
&lt;div class=&quot;flex items-center text-brand-200&quot;&gt;간단한 주기적 작업은 Workmanager를 선택하세요.&lt;/div&gt;
&lt;div class=&quot;flex items-center text-brand-200&quot;&gt;지속적인 실행이 필요하다면 flutter_background_service를 고려하세요.&lt;/div&gt;
&lt;div class=&quot;flex items-center text-brand-200&quot;&gt;무거운 연산이 필요하다면 Isolate를 활용하세요.&lt;/div&gt;
&lt;/div&gt;
&lt;!-- 
                &lt;p class=&quot;text-sm opacity-80 !mb-0 italic border-t border-white/10 pt-6&quot;&gt;
	            --&gt;
&lt;p class=&quot;!text-brand-100&quot; data-ke-size=&quot;size16&quot;&gt;최근 현재, 모바일 OS는 개인정보 보호와 배터리 수명을 위해 더욱 엄격한 백그라운드 제한을 적용하고 있습니다. 항상 최신 플랫폼 정책을 모니터링하고, 사용자의 배터리를 존중하는 설계를 지향하시기 바랍니다.&lt;/p&gt;
&lt;/section&gt;
&lt;/div&gt;
&lt;!--
        &lt;div class=&quot;mt-20 pt-10 border-t border-slate-200&quot;&gt;
            &lt;div class=&quot;flex flex-wrap gap-2&quot;&gt;
                &lt;span class=&quot;px-3 py-1 bg-slate-100 text-slate-600 rounded-lg text-sm font-medium&quot;&gt;#Flutter&lt;/span&gt;
                &lt;span class=&quot;px-3 py-1 bg-slate-100 text-slate-600 rounded-lg text-sm font-medium&quot;&gt;#백그라운드처리&lt;/span&gt;
                &lt;span class=&quot;px-3 py-1 bg-slate-100 text-slate-600 rounded-lg text-sm font-medium&quot;&gt;#Workmanager&lt;/span&gt;
                &lt;span class=&quot;px-3 py-1 bg-slate-100 text-slate-600 rounded-lg text-sm font-medium&quot;&gt;#Isolate&lt;/span&gt;
                &lt;span class=&quot;px-3 py-1 bg-slate-100 text-slate-600 rounded-lg text-sm font-medium&quot;&gt;#앱라이프사이클&lt;/span&gt;
                &lt;span class=&quot;px-3 py-1 bg-slate-100 text-slate-600 rounded-lg text-sm font-medium&quot;&gt;#Flutter개발&lt;/span&gt;
                &lt;span class=&quot;px-3 py-1 bg-slate-100 text-slate-600 rounded-lg text-sm font-medium&quot;&gt;#안드로이드백그라운드&lt;/span&gt;
                &lt;span class=&quot;px-3 py-1 bg-slate-100 text-slate-600 rounded-lg text-sm font-medium&quot;&gt;#iOS백그라운드&lt;/span&gt;
                &lt;span class=&quot;px-3 py-1 bg-slate-100 text-slate-600 rounded-lg text-sm font-medium&quot;&gt;#모바일앱개발&lt;/span&gt;
            &lt;/div&gt;
        &lt;/div&gt;
		--&gt;&lt;/article&gt;
&lt;!-- Simple Scroll to Top Button --&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <category>Background</category>
      <category>Flutter</category>
      <category>Isolate</category>
      <category>WorkManager</category>
      <category>모바일앱개발</category>
      <category>백그라운드</category>
      <category>앱라이프사이클</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/80</guid>
      <comments>https://techsuda.tistory.com/entry/Flutter-Flutter-%EB%B0%B1%EA%B7%B8%EB%9D%BC%EC%9A%B4%EB%93%9C-%EC%B2%98%EB%A6%AC-%EA%B0%80%EC%9D%B4%EB%93%9C#entry80comment</comments>
      <pubDate>Mon, 11 May 2026 17:36:51 +0900</pubDate>
    </item>
    <item>
      <title>[AI] 내 손안의 AI 혁명: Ollama와 엣지 컴퓨팅</title>
      <link>https://techsuda.tistory.com/entry/%EB%82%B4-%EC%86%90%EC%95%88%EC%9D%98-AI-%ED%98%81%EB%AA%85-Ollama%EC%99%80-%EC%97%A3%EC%A7%80-%EC%BB%B4%ED%93%A8%ED%8C%85</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnLzef/dJMcafmhgDF/KNUuNCH8n22wYv6DRa2Td1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnLzef/dJMcafmhgDF/KNUuNCH8n22wYv6DRa2Td1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnLzef/dJMcafmhgDF/KNUuNCH8n22wYv6DRa2Td1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnLzef%2FdJMcafmhgDF%2FKNUuNCH8n22wYv6DRa2Td1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1376&quot; height=&quot;768&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;max-w-[800px] mx-auto px-6 lg:px-0&quot;&gt;&lt;header class=&quot;pt-12 md:pt-20&quot;&gt;
&lt;div class=&quot;space-y-4&quot;&gt;
&lt;h1 class=&quot;font-display font-800 text-4xl md:text-5xl lg:text-6xl text-slate-900 leading-tight tracking-tight&quot;&gt;내 컴퓨터가 똑똑해진다!&lt;br /&gt;Ollama와 엣지 컴퓨팅으로 시작하는 프라이빗 AI 혁명&lt;/h1&gt;
&lt;/div&gt;
&lt;/header&gt;&lt;!-- Introduction --&gt;
&lt;div class=&quot;mt-12 text-xl text-slate-600 font-light leading-relaxed prose-custom&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2026년 현재, 인공지능(AI)은 우리 삶 깊숙이 들어와 있습니다. 하지만 클라우드 AI를 사용할 때마다 따라오는 &lt;b&gt;'데이터 유출 우려'&lt;/b&gt;와 &lt;b&gt;'비싼 구독료'&lt;/b&gt;는 늘 고민거리였죠. 이러한 문제를 해결할 열쇠로 &lt;span class=&quot;text-brand-500 font-bold underline decoration-brand-200 underline-offset-4&quot;&gt;Ollama(올라마)&lt;/span&gt;와 &lt;span class=&quot;text-brand-500 font-bold underline decoration-brand-200 underline-offset-4&quot;&gt;엣지 컴퓨팅(Edge Computing)&lt;/span&gt;의 결합이 주목받고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전문가는 물론 일반인도 쉽게 이해할 수 있도록, 2026년 5월 최신 트렌드를 반영한 '내 손안의 AI' 이야기를 시작합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;!-- Table of Contents Card --&gt;&lt;nav class=&quot;my-16 p-8 rounded-3xl bg-brand-50 border border-brand-100&quot;&gt;
&lt;h2 class=&quot;font-display font-bold text-xl text-brand-900 mb-6 flex items-center gap-2&quot; data-ke-size=&quot;size26&quot;&gt;Article Outline&lt;/h2&gt;
&lt;ul class=&quot;grid grid-cols-1 md:grid-cols-2 gap-4&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a class=&quot;text-slate-700 hover:text-brand-500 transition-colors flex items-center gap-2 font-medium&quot; href=&quot;#section-1&quot;&gt;&lt;span&gt;01&lt;/span&gt; 서론: 왜 지금 '로컬 AI'인가?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;text-slate-700 hover:text-brand-500 transition-colors flex items-center gap-2 font-medium&quot; href=&quot;#section-2&quot;&gt;&lt;span&gt;02&lt;/span&gt; Ollama란 무엇인가?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;text-slate-700 hover:text-brand-500 transition-colors flex items-center gap-2 font-medium&quot; href=&quot;#section-3&quot;&gt;&lt;span&gt;03&lt;/span&gt; 엣지 컴퓨팅의 정의&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;text-slate-700 hover:text-brand-500 transition-colors flex items-center gap-2 font-medium&quot; href=&quot;#section-4&quot;&gt;&lt;span&gt;04&lt;/span&gt; 기술의 시너지와 혁신&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;text-slate-700 hover:text-brand-500 transition-colors flex items-center gap-2 font-medium&quot; href=&quot;#section-5&quot;&gt;&lt;span&gt;05&lt;/span&gt; 일상생활 활용 사례&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;text-slate-700 hover:text-brand-500 transition-colors flex items-center gap-2 font-medium&quot; href=&quot;#section-6&quot;&gt;&lt;span&gt;06&lt;/span&gt; 결론 및 향후 전망&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/nav&gt;&lt;!-- Main Content --&gt;
&lt;article class=&quot;prose-custom text-slate-800 text-lg&quot;&gt;
&lt;section id=&quot;section-1&quot; class=&quot;section-spacing&quot;&gt;
&lt;h2 class=&quot;font-display font-800 text-3xl text-slate-900 mb-8 flex items-baseline gap-4&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span class=&quot;text-brand-200 text-5xl&quot;&gt;01&lt;/span&gt; 서론: 왜 지금 '로컬 AI'와 '엣지 컴퓨팅'인가?&lt;/h2&gt;
&lt;div class=&quot;pl-4 border-l-4 border-brand-100&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 몇 년간 우리는 챗GPT 같은 강력한 AI를 경험해 왔습니다. 하지만 이들은 거대한 데이터 센터(클라우드)에서 작동하기 때문에, 인터넷이 끊기면 사용할 수 없고 나의 사적인 대화가 서버에 저장된다는 불안감이 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2026년 현재, 이러한 한계를 극복하기 위해 &lt;b&gt;'프라이빗 AI'&lt;/b&gt;가 대세로 떠올랐습니다. 그 중심에는 누구나 쉽게 내 기기에서 AI를 돌리게 해주는 &lt;b&gt;Ollama&lt;/b&gt;와, 데이터를 현장에서 즉시 처리하는 &lt;b&gt;엣지 컴퓨팅&lt;/b&gt; 기술이 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;section-2&quot; class=&quot;section-spacing&quot;&gt;
&lt;h2 class=&quot;font-display font-800 text-3xl text-slate-900 mb-8 flex items-baseline gap-4&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span class=&quot;text-brand-200 text-5xl&quot;&gt;02&lt;/span&gt; Ollama란 무엇인가? (AI를 내 컴퓨터로 가져오는 법)&lt;/h2&gt;
&lt;div class=&quot;bg-white rounded-3xl p-8 border border-slate-100 shadow-sm mb-8&quot;&gt;
&lt;p class=&quot;mb-6&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Ollama&lt;/b&gt;는 복잡한 인공지능 모델을 마치 스마트폰 앱을 설치하듯 내 컴퓨터에 내려받아 실행할 수 있게 도와주는 소프트웨어입니다.&lt;/p&gt;
&lt;ul class=&quot;space-y-4&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li class=&quot;flex gap-4&quot;&gt;&lt;span class=&quot;shrink-0 w-6 h-6 rounded-full bg-brand-500 text-white flex items-center justify-center text-xs&quot;&gt;✓&lt;/span&gt; &lt;span&gt;&lt;b&gt;2026년의 Ollama&lt;/b&gt;: 과거에는 고성능 그래픽카드(GPU)가 필수였지만, 이제 Ollama는 최신 'AI PC'에 탑재된 &lt;b&gt;NPU(신경망 처리 장치)&lt;/b&gt;를 완벽하게 지원합니다. 덕분에 일반 노트북에서도 Llama 4나 Gemma 4 같은 최신 로컬 LLM을 아주 빠르게 실행할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li class=&quot;flex gap-4&quot;&gt;&lt;span class=&quot;shrink-0 w-6 h-6 rounded-full bg-brand-500 text-white flex items-center justify-center text-xs&quot;&gt;✓&lt;/span&gt; &lt;span&gt;&lt;b&gt;쉬운 사용법&lt;/b&gt;: 명령어 한 줄이면 AI 설치가 끝납니다. 전문 지식이 없어도 나만의 인공지능 친구를 만들 수 있는 도구입니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;section-3&quot; class=&quot;section-spacing&quot;&gt;
&lt;h2 class=&quot;font-display font-800 text-3xl text-slate-900 mb-8 flex items-baseline gap-4&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span class=&quot;text-brand-200 text-5xl&quot;&gt;03&lt;/span&gt; 엣지 컴퓨팅이란 무엇인가? (내 곁의 AI)&lt;/h2&gt;
&lt;div class=&quot;grid grid-cols-1 md:grid-cols-2 gap-6 mb-8&quot;&gt;
&lt;div class=&quot;p-6 rounded-2xl bg-slate-100 border border-slate-200&quot;&gt;
&lt;h4 class=&quot;font-bold text-slate-900 mb-3&quot; data-ke-size=&quot;size20&quot;&gt;클라우드 컴퓨팅&lt;/h4&gt;
&lt;p class=&quot;text-sm&quot; data-ke-size=&quot;size16&quot;&gt;멀리 떨어진 서버에서 계산합니다. 전송 과정에서 시간이 걸리고 보안 위험이 존재합니다. (마치 멀리 있는 대형 도서관)&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;p-6 rounded-2xl bg-brand-100 border border-brand-200&quot;&gt;
&lt;h4 class=&quot;font-bold text-brand-900 mb-3&quot; data-ke-size=&quot;size20&quot;&gt;엣지 컴퓨팅&lt;/h4&gt;
&lt;p class=&quot;text-sm&quot; data-ke-size=&quot;size16&quot;&gt;스마트폰, 노트북, 가전 등 데이터가 발생하는 '현장(Edge)'에서 즉시 계산합니다. 데이터가 외부로 나가지 않아 안전합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전통적인 방식이 '서울에 있는 거대 도서관'에 매번 전화를 걸어 정보를 묻는 방식이라면, &lt;b&gt;엣지 컴퓨팅&lt;/b&gt;은 '내 책상 위에 백과사전'을 두는 것과 같습니다.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;section-4&quot; class=&quot;section-spacing&quot;&gt;
&lt;h2 class=&quot;font-display font-800 text-3xl text-slate-900 mb-8 flex items-baseline gap-4&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span class=&quot;text-brand-200 text-5xl&quot;&gt;04&lt;/span&gt; Ollama와 엣지 컴퓨팅의 시너지&lt;/h2&gt;
&lt;div class=&quot;space-y-6&quot;&gt;
&lt;div class=&quot;group p-6 rounded-2xl hover:bg-white hover:shadow-xl transition-all duration-300 border border-transparent hover:border-brand-100&quot;&gt;
&lt;h4 class=&quot;font-bold text-lg text-slate-900 mb-2 flex items-center gap-3&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span class=&quot;w-8 h-8 flex items-center justify-center bg-brand-50 text-brand-500 rounded-lg group-hover:bg-brand-500 group-hover:text-white transition-colors&quot;&gt;1&lt;/span&gt; 강력한 데이터 보안 (Private AI)&lt;/h4&gt;
&lt;p class=&quot;text-slate-600 pl-11&quot; data-ke-size=&quot;size16&quot;&gt;모든 대화가 내 기기 안에서만 처리됩니다. 기업 비밀이나 개인적인 일기를 AI와 상담해도 유출 걱정이 전혀 없습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;group p-6 rounded-2xl hover:bg-white hover:shadow-xl transition-all duration-300 border border-transparent hover:border-brand-100&quot;&gt;
&lt;h4 class=&quot;font-bold text-lg text-slate-900 mb-2 flex items-center gap-3&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span class=&quot;w-8 h-8 flex items-center justify-center bg-brand-50 text-brand-500 rounded-lg group-hover:bg-brand-500 group-hover:text-white transition-colors&quot;&gt;2&lt;/span&gt; 초저지연(Low Latency) 인공지능&lt;/h4&gt;
&lt;p class=&quot;text-slate-600 pl-11&quot; data-ke-size=&quot;size16&quot;&gt;인터넷 연결 상태와 상관없이 즉각적인 답변을 얻을 수 있습니다. 실시간 통번역이나 자율주행 기술에서 매우 중요합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;group p-6 rounded-2xl hover:bg-white hover:shadow-xl transition-all duration-300 border border-transparent hover:border-brand-100&quot;&gt;
&lt;h4 class=&quot;font-bold text-lg text-slate-900 mb-2 flex items-center gap-3&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span class=&quot;w-8 h-8 flex items-center justify-center bg-brand-50 text-brand-500 rounded-lg group-hover:bg-brand-500 group-hover:text-white transition-colors&quot;&gt;3&lt;/span&gt; 비용 절감&lt;/h4&gt;
&lt;p class=&quot;text-slate-600 pl-11&quot; data-ke-size=&quot;size16&quot;&gt;매달 결제해야 하는 구독료가 없습니다. 한 번 설정해두면 내 기기의 자원을 사용하므로 추가 비용 없이 무제한으로 이용 가능합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;section-5&quot; class=&quot;section-spacing&quot;&gt;
&lt;h2 class=&quot;font-display font-800 text-3xl text-slate-900 mb-8 flex items-baseline gap-4&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span class=&quot;text-brand-200 text-5xl&quot;&gt;05&lt;/span&gt; 우리 일상을 바꾸는 활용 사례&lt;/h2&gt;
&lt;div class=&quot;grid grid-cols-1 gap-6&quot;&gt;
&lt;div class=&quot;flex gap-6 items-start p-6 bg-white rounded-3xl border border-slate-100&quot;&gt;
&lt;div class=&quot;w-12 h-12 bg-blue-50 flex-shrink-0 rounded-2xl flex items-center justify-center text-2xl&quot;&gt; &lt;/div&gt;
&lt;div&gt;
&lt;h4 class=&quot;font-bold text-slate-900 mb-1&quot; data-ke-size=&quot;size20&quot;&gt;진정한 스마트 홈&lt;/h4&gt;
&lt;p class=&quot;text-slate-600 text-sm&quot; data-ke-size=&quot;size16&quot;&gt;인터넷이 끊겨도 음성 제어로 집안 가전을 조절하고, CCTV 영상을 로컬에서 분석해 위험을 알립니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;flex gap-6 items-start p-6 bg-white rounded-3xl border border-slate-100&quot;&gt;
&lt;div class=&quot;w-12 h-12 bg-blue-50 flex-shrink-0 rounded-2xl flex items-center justify-center text-2xl&quot;&gt; &lt;/div&gt;
&lt;div&gt;
&lt;h4 class=&quot;font-bold text-slate-900 mb-1&quot; data-ke-size=&quot;size20&quot;&gt;개인 맞춤형 업무 비서&lt;/h4&gt;
&lt;p class=&quot;text-slate-600 text-sm&quot; data-ke-size=&quot;size16&quot;&gt;구독료 없이 내 컴퓨터의 파일을 분석하고 코딩을 도와줍니다. 보안이 생명인 개발자들의 필수 도구입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;flex gap-6 items-start p-6 bg-white rounded-3xl border border-slate-100&quot;&gt;
&lt;div class=&quot;w-12 h-12 bg-blue-50 flex-shrink-0 rounded-2xl flex items-center justify-center text-2xl&quot;&gt; &lt;/div&gt;
&lt;div&gt;
&lt;h4 class=&quot;font-bold text-slate-900 mb-1&quot; data-ke-size=&quot;size20&quot;&gt;오프라인 교육 비서&lt;/h4&gt;
&lt;p class=&quot;text-slate-600 text-sm&quot; data-ke-size=&quot;size16&quot;&gt;인터넷 환경이 좋지 않은 오지에서도 고성능 AI 선생님과 대화하며 학습할 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&quot;section-6&quot; class=&quot;section-spacing pb-12&quot;&gt;
&lt;h2 class=&quot;font-display font-800 text-3xl text-slate-900 mb-8 flex items-baseline gap-4&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span class=&quot;text-brand-200 text-5xl&quot;&gt;06&lt;/span&gt; 결론: 요약 및 향후 전망&lt;/h2&gt;
&lt;div class=&quot;bg-brand-500 text-white rounded-[32px] p-10 relative overflow-hidden&quot;&gt;
&lt;div class=&quot;absolute top-0 right-0 w-32 h-32 bg-brand-500 opacity-20 rounded-full -mr-16 -mt-16&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;relative z-10&quot;&gt;
&lt;p class=&quot;text-lg leading-relaxed mb-6 opacity-90&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Ollama&lt;/b&gt;와 &lt;b&gt;엣지 컴퓨팅&lt;/b&gt;의 결합은 AI의 권력을 거대 기업의 클라우드에서 '개인의 기기'로 되찾아오는 혁명입니다. 이제 AI는 더 이상 멀리 있는 존재가 아니라, 내 노트북과 스마트폰 속에서 나만을 위해 안전하게 작동하는 든든한 조력자가 되었습니다.&lt;/p&gt;
&lt;p class=&quot;text-lg leading-relaxed opacity-90&quot; data-ke-size=&quot;size16&quot;&gt;앞으로는 더욱 작고 효율적인 &lt;b&gt;소규모 언어 모델(SLM)&lt;/b&gt;이 발전하면서, 냉장고나 전등 스위치 같은 아주 작은 기기에도 Ollama와 같은 엔진이 탑재될 것입니다. 여러분도 지금 바로 Ollama를 통해 나만의 프라이빗 AI 시대를 경험해 보세요!&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/article&gt;
&lt;/div&gt;</description>
      <category>Tech Story</category>
      <category>AI트렌드</category>
      <category>edge</category>
      <category>LLM</category>
      <category>ollama</category>
      <category>에지컴퓨팅</category>
      <category>엣지컴퓨팅</category>
      <category>올라마</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/79</guid>
      <comments>https://techsuda.tistory.com/entry/%EB%82%B4-%EC%86%90%EC%95%88%EC%9D%98-AI-%ED%98%81%EB%AA%85-Ollama%EC%99%80-%EC%97%A3%EC%A7%80-%EC%BB%B4%ED%93%A8%ED%8C%85#entry79comment</comments>
      <pubDate>Mon, 11 May 2026 16:33:57 +0900</pubDate>
    </item>
    <item>
      <title>[AI] DeepSeek V4와 소라(Sora)로 끝내는 2026 AI 동영상 제작 가이드</title>
      <link>https://techsuda.tistory.com/entry/DeepSeek-V4%EC%99%80-%EC%86%8C%EB%9D%BCSora%EB%A1%9C-%EB%81%9D%EB%82%B4%EB%8A%94-2026-AI-%EB%8F%99%EC%98%81%EC%83%81-%EC%A0%9C%EC%9E%91-%EA%B0%80%EC%9D%B4%EB%93%9C</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;  AI 영상제작 가이드: 딥시크 V4 + 소라 2.0 완벽 활용법&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 구글 트렌드를 살펴보면 AI 분야의 검색 양상이 단순히 '질문'하는 수준을 넘어, '직접 무엇인가를 만들어내는 도구'에 집중되고 있습니다. 특히 2026년 들어 가장 뜨거운 감자로 떠오른 &lt;b&gt;딥시크(DeepSeek) V4&lt;/b&gt;와 드디어 일반 사용자에게도 익숙해진 소라(Sora)의 조합은 크리에이터들에게 새로운 기회를 열어주고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글에서는 &lt;b&gt;딥시크 V4&lt;/b&gt;로 프로 수준의 프롬프트를 설계하고, &lt;b&gt;소라 2.0&lt;/b&gt;으로 시네마틱 영상을 생성하는 &lt;b&gt;실전 워크플로우&lt;/b&gt;를 단계별로 알려드리겠습니다. 비용은 최소화하면서 퀄리티는 극대화하는 2026년형 AI 영상 제작법을 만나보세요!  &lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  1. 왜 지금 '딥시크(DeepSeek) V4'인가?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 검색량이 폭발한 딥시크 V4는 기존의 유료 AI 모델들과 어깨를 나란히 하면서도 &lt;b&gt;압도적인 가성비&lt;/b&gt;를 보여줍니다. 특히나 한국어 환경에서 놀라운 효율성을 발휘하고 있어, 영상 크리에이터들 사이에서 곧 기본기가 될 필수 도구입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;한국어 맥락 이해도 상승:&lt;/b&gt; 이전 버전보다 한국어 특유의 뉘앙스를 훨씬 잘 파악합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;논리적 추론 강화:&lt;/b&gt; 복잡한 영상 스크립트나 구도를 설계할 때 매우 정교한 가이드를 제공합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;효율성:&lt;/b&gt; 저렴한 비용(혹은 무료 제공 범위)으로 고성능 LLM을 사용할 수 있다는 점이 큰 매력입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  2. 영상 혁명의 중심, OpenAI 소라(Sora) 2.0 업데이트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;텍스트 투 비디오(Text-to-Video)의 선두주자인 소라는 이제 단순히 화면을 생성하는 것을 넘어 &lt;b&gt;'오디오 동시 생성'&lt;/b&gt; 기능까지 탑재하며 완성도를 높였습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;일관성 유지:&lt;/b&gt; 영상 내 캐릭터와 배경이 바뀌지 않고 유지되는 능력이 비약적으로 발전했습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;시네마틱 품질:&lt;/b&gt; 조명, 질감, 물리 법칙 적용이 실제 촬영본과 구분하기 어려울 정도입니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;편집 편의성:&lt;/b&gt; 생성된 영상의 특정 부분만 수정하거나 리믹스하는 기능이 추가되었습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;⚡ 3. 딥시크와 소라를 활용한 3단계 영상 제작 워크플로우&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 1: 딥시크 V4로 정교한 프롬프트 설계하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소라에서 좋은 영상을 얻으려면 '프롬프트'가 핵심입니다. 딥시크 V4에게 다음과 같이 요청해 보세요.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;지브리 스타일의 한국 골목길 풍경을 묘사하는 소라(Sora) 전용 영문 프롬프트를 작성해 줘.&lt;br /&gt;햇살의 각도와 나뭇잎의 흔들림까지 상세하게 포함해.&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 2: 소라(Sora)에서 영상 생성 및 리믹스&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥시크가 만든 프롬프트를 Sora.com에 입력합니다. 이때 2026년 최신 기능인 &lt;b&gt;'오디오 생성 옵션'&lt;/b&gt;을 반드시 체크하여 배경음과 효과음을 한 번에 얻으세요.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 3: 결과물 검토 및 최종 최적화&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 영상이 의도와 다르다면, 소라의 &lt;b&gt;'Re-cut'&lt;/b&gt; 기능을 활용해 특정 구간의 연출만 다시 수정할 수 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  4. 실무 워크플로우 요약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 설명한 내용을 정리하면, AI 영상 제작은 다음 3단계로 간단히 요약됩니다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Step 1:&lt;/b&gt; 딥시크 V4에서 상세 프롬프트 설계&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Step 2:&lt;/b&gt; 소라 2.0에서 오디오 포함 영상 생성&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Step 3:&lt;/b&gt; Re-cut 기능으로 미세 조정&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  실제 생성된 AI 영상 결과물 확인하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 위의 프롬프트와 프로세스를 통해 생성된 소라(Sora)의 2026년 최신 결과물 샘플입니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 237px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 237px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 237px; text-align: center;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1161&quot; data-origin-height=&quot;658&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5tdnh/dJMcajhPRlD/oapNYWYJkgy7JDj840yE3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5tdnh/dJMcajhPRlD/oapNYWYJkgy7JDj840yE3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5tdnh/dJMcajhPRlD/oapNYWYJkgy7JDj840yE3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5tdnh%2FdJMcajhPRlD%2FoapNYWYJkgy7JDj840yE3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1161&quot; height=&quot;658&quot; data-origin-width=&quot;1161&quot; data-origin-height=&quot;658&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;a style=&quot;letter-spacing: 0px;&quot; title=&quot;  생성 동영상 1&quot; href=&quot;https://drive.google.com/file/d/1yNm0FYmM6O0cIs9jEZxXUZW1gHlsxdFU/view?usp=drive_link&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;  AI 생성 동영상 1 새창에서 보기&lt;/a&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 237px; text-align: center;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1240&quot; data-origin-height=&quot;699&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8JlVg/dJMcacXk6dE/vXLtTZrGvZ7w5QEYBcBPZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8JlVg/dJMcacXk6dE/vXLtTZrGvZ7w5QEYBcBPZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8JlVg/dJMcacXk6dE/vXLtTZrGvZ7w5QEYBcBPZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8JlVg%2FdJMcacXk6dE%2FvXLtTZrGvZ7w5QEYBcBPZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1240&quot; height=&quot;699&quot; data-origin-width=&quot;1240&quot; data-origin-height=&quot;699&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;a title=&quot;  생성 동영상 2&quot; href=&quot;https://drive.google.com/file/d/1eJeDAtiZKvFsqHGFNiuBYpgufkbE6GzJ/view?usp=drive_link&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;  AI 생성 동영상 2 새창에서 보기&lt;/a&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  마치며: AI와 함께하는 새로운 영상 시대&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 AI는 선택이 아닌 &lt;b&gt;필수&lt;/b&gt;인 시대입니다.&lt;br /&gt;딥시크 V4로 &lt;b&gt;브레인을 얻고&lt;/b&gt;, 소라로 &lt;b&gt;눈을 얻으세요.&lt;br /&gt;&lt;/b&gt; 여러분의 창의력이 기술을 만날 때 진정한 가치가 만들어집니다.&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #e8f5e9; border-left: 4px solid #2e7d32; font-weight: bold; margin: 1em 0; padding: 16px 24px; text-align: center;&quot; data-ke-style=&quot;style1&quot;&gt;  궁금한 점이 있으시면 댓글로 남겨주세요!&lt;/blockquote&gt;
&lt;hr style=&quot;border-top: 1px solid #e0e0e0; border: none; margin: 2em 0;&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p style=&quot;color: #666666; font-size: 0.9em; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;  도움이 되셨다면 좋아요와 구독은 필수!   알림 설정도 잊지 마세요.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/78</guid>
      <comments>https://techsuda.tistory.com/entry/DeepSeek-V4%EC%99%80-%EC%86%8C%EB%9D%BCSora%EB%A1%9C-%EB%81%9D%EB%82%B4%EB%8A%94-2026-AI-%EB%8F%99%EC%98%81%EC%83%81-%EC%A0%9C%EC%9E%91-%EA%B0%80%EC%9D%B4%EB%93%9C#entry78comment</comments>
      <pubDate>Sat, 9 May 2026 14:01:12 +0900</pubDate>
    </item>
    <item>
      <title>부모님께 디지털앨범 선물</title>
      <link>https://techsuda.tistory.com/entry/%EB%B6%80%EB%AA%A8%EB%8B%98%EA%BB%98-%EB%94%94%EC%A7%80%ED%84%B8%EC%95%A8%EB%B2%94-%EC%84%A0%EB%AC%BC</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1128&quot; data-origin-height=&quot;455&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8Th2n/dJMcab4aF8A/Dp6JURts6rCrtbOEMdNfA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8Th2n/dJMcab4aF8A/Dp6JURts6rCrtbOEMdNfA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8Th2n/dJMcab4aF8A/Dp6JURts6rCrtbOEMdNfA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8Th2n%2FdJMcab4aF8A%2FDp6JURts6rCrtbOEMdNfA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1128&quot; height=&quot;455&quot; data-origin-width=&quot;1128&quot; data-origin-height=&quot;455&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;오래전 부터 전자앨범(디지털액자)을 하나 만들어서 부모님댁에 하나 놓아 드리고 싶었다. 애들이 어렸을때야 자주 찾아 뵈었지만, 애들도 다 커서 성인들이 되면서 자기들 생활 반경이 크고 넓어지다 보니 자주 찾아 뵙지 못하게 되는듯 하다.&lt;br /&gt;그래서 아쉬운 대로 전자 액자라도 하나 큰걸로 만들어 드릴까 했는데 최근에서야 하나 제작해서 부모님 댁에 하나 설치해 드렸다.&lt;br /&gt;거실 TV옆에 설치해 놓으니, 아버지도 어머니도 무척 마음에 들어 하셨다.&lt;br /&gt;처음에는 판매하는 전자액자를 살려고도 했었는데, 전반적으로 화면이 너무 작았고 화면이 크면 금액이 너무 비싸졌고, 클라우드 스토리지를 사용하는 제품들은 금액이나 화면 크기가 맘에 드는 것이 하나도 없었기에 일찌기 Diy 하는 방향으로 정보들을 수집해 왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;적당한 금액에 화면은 커야하고, 현재 운영중인 시놀로지 NAS가 있으니 NAS를 최대한 활용할 수 있는 방법을 모색해 왔고 조건은 다음과 같다.&lt;br /&gt;&amp;nbsp;1. 식구들 모두 쉽게 사진을 업로드 할 수 있고(시놀로지), 업로드 되면 바로 부모님이 사진을 보실 수 있어야 함.&lt;br /&gt;&amp;nbsp;2. 적당한 금액에 가장 큰 모니터 확보.&lt;br /&gt;&amp;nbsp;3. 인터넷 연결 가능 및 리모컨으로 기기 On/Off 가능.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;일단 유료 앱을 활용할 생각으로 몇가지 후보군에서 살펴봤던 앱들이 있었는데, 내 NAS를 지원하지 않아서 결국 전자앨범 프로그램(앱)은 직접 제작 하기로 했다. NAS에서 지원하는 SynologyPhoto 프로그램을 이용해서 공유앨범을 만들고 식구들에게는 사진 업로드 URL을 공유해서 각자 자유롭게 업로드 할 수 있도록 하고, 해당 공유폴더를 설정되어 있는 조건대로 반복적으로 화면에 보여주는 웹앱을 하나 만들어서 슬라이드쇼처럼 반복해서 보여주면 될 것 같아 여기저기 자료 찾아 보면서 앱제작에 나섰다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;작성한 앱 (OS:Android TV) 이 실행될 환경은 안드로이드 TV스틱( or TV Box) 으로 해주면 많은 부분이 편해질 것 같아, 2개의 TV스틱도 준비했다.&lt;br /&gt;App은 플러터로 작성했다. &lt;br /&gt;작동 시간 및 사진을 보여주는 시간, 그리고 야간에는 날짜와 시간, 경기 일산의 날씨 정보를 가져와서 Dark모드에서 Display 하는 기능들을 설정할 수 있는 환경설정 부분과, NAS에 저장된 공유사진 리스트를 업데이트 하는 부분(이 부분은 슬라이드쇼가 끝날때마다 업데이트를 적용하게 작업함).&lt;br /&gt;이렇게 크게 두부분으로 구성했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;준비물 : 안드로이드TV스틱(리모콘 지원), 휴대용 모니터 (18.5 inch 로 결정), HDMI 연장케이블 (혹시 몰라서...)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;575&quot; data-origin-height=&quot;127&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cTYMMO/dJMcaivqM16/vkGAIrpf23PCnbVxpzIRp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cTYMMO/dJMcaivqM16/vkGAIrpf23PCnbVxpzIRp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cTYMMO/dJMcaivqM16/vkGAIrpf23PCnbVxpzIRp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcTYMMO%2FdJMcaivqM16%2FvkGAIrpf23PCnbVxpzIRp1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;575&quot; height=&quot;127&quot; data-origin-width=&quot;575&quot; data-origin-height=&quot;127&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;611&quot; data-origin-height=&quot;127&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lGTuz/dJMcaivqM2F/rZz2o5NtB7YRIbaYzwyXB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lGTuz/dJMcaivqM2F/rZz2o5NtB7YRIbaYzwyXB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lGTuz/dJMcaivqM2F/rZz2o5NtB7YRIbaYzwyXB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlGTuz%2FdJMcaivqM2F%2FrZz2o5NtB7YRIbaYzwyXB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;611&quot; height=&quot;127&quot; data-origin-width=&quot;611&quot; data-origin-height=&quot;127&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;613&quot; data-origin-height=&quot;114&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPGuTN/dJMcadARwfH/nsju7B5A7zBOfedPNH3EQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPGuTN/dJMcadARwfH/nsju7B5A7zBOfedPNH3EQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPGuTN/dJMcadARwfH/nsju7B5A7zBOfedPNH3EQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPGuTN%2FdJMcadARwfH%2Fnsju7B5A7zBOfedPNH3EQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;613&quot; height=&quot;114&quot; data-origin-width=&quot;613&quot; data-origin-height=&quot;114&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;605&quot; data-origin-height=&quot;105&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btzyKh/dJMcaflc0in/NSfFaWmudMB4bOyDgV8IP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btzyKh/dJMcaflc0in/NSfFaWmudMB4bOyDgV8IP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btzyKh/dJMcaflc0in/NSfFaWmudMB4bOyDgV8IP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtzyKh%2FdJMcaflc0in%2FNSfFaWmudMB4bOyDgV8IP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;605&quot; height=&quot;105&quot; data-origin-width=&quot;605&quot; data-origin-height=&quot;105&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;준비는 위와 같이 주문했는데, 실제 사용은 부피가 작은 TV스틱과 모니터 만 사용했다.&lt;br /&gt;ZeusLap 모니터를 선택한 이유는 후면 USB가 PD기능이 지원되어서 TV스틱용 전원으로 사용해도 괜찮을 것 같았고, 금액대비 사이즈가 크다보니 부모님들 보시기에 적당할 것 같아서 터치기능없는 모니터를 선택한 것이다. (결론은 탁월한 Choice였다!! 모니터 전원 하나만 연결하면 문제가 없었다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그동안 플러터로 만든 앱은 모두가 휴대폰 기반 (안드로이드 &amp;amp; iOS) 이었는데, TV스틱에서 실행되는 앱은 처음 만들어 보는 거라, 검색을 좀 열심히 했던 것 같다. Wifi 무선연결하고 adb 로 TV스틱에 앱설치 완료. 아이콘도 하나 쁘띠쁘띠하게 AI한테 맹글어 달라고 하고, 날씨 정보를 가져오기 위해 위치정보를 가져와야 하는데 TV스틱별로 위치정보 GPS가져오는 기능이 케바케 인듯 하여, 일단 Default로 경기 일산을 고정해 놓았다. 그리고 가족사진 여러장 NAS에 공유앨범으로 만들고 테스트. 음~~~ 봐줄만하다. 바빠서 짜투리 시간에 작업하느라 시간은 좀 오래 걸렸지만 나름 봐줄만한 전자앨범이 하나 맹글어 졌다.&lt;br /&gt;다른 사람들이 많이 작업하던 모니터에 맞게 액자(표구)까지 작업할 까 생각했었지만 전원 연결하는게 좀 껄끄럽고 해서 걍 이대로 본가에 설치해 드리기로 했다. D-Day는 어머니 생신때...&lt;br /&gt;식구들 모두 모여 생신 축하해 드리고, 저녁에 설치해 드렸다. 아부지도 어무이도 내심 좋아하셨다. ㅎㅎ&lt;br /&gt;&lt;a href=&quot;https://youtu.be/yO0xUi5lymQ&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtu.be/yO0xUi5lymQ&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=yO0xUi5lymQ&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/derLCG/dJMb85WO8YY/GQAsvEfnzFpCFFJYQuHsNK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/ELdkn/dJMb81GS3An/Ag1Iy2qy9eC5vqTfyehn71/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/VydK0/dJMb82MyU7q/GhCPtEJet45tZyc9SF4v7K/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;디지털앨범&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/yO0xUi5lymQ&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;</description>
      <category>Life Story</category>
      <category>tv스틱</category>
      <category>디지털액자</category>
      <category>모니터</category>
      <category>시놀로지</category>
      <category>액자</category>
      <category>앨범</category>
      <category>전자앨범</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/77</guid>
      <comments>https://techsuda.tistory.com/entry/%EB%B6%80%EB%AA%A8%EB%8B%98%EA%BB%98-%EB%94%94%EC%A7%80%ED%84%B8%EC%95%A8%EB%B2%94-%EC%84%A0%EB%AC%BC#entry77comment</comments>
      <pubDate>Tue, 10 Feb 2026 18:16:15 +0900</pubDate>
    </item>
    <item>
      <title>[AI / n8n] 유튭에서 봤던 멋진 영상을 직접 구현</title>
      <link>https://techsuda.tistory.com/entry/AI-n8n-%EC%9C%A0%ED%8A%AD%EC%97%90%EC%84%9C-%EB%B4%A4%EB%8D%98-%EB%A9%8B%EC%A7%84-%EC%98%81%EC%83%81%EC%9D%84-%EC%A7%81%EC%A0%91-%EA%B5%AC%ED%98%84</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BlHMx/dJMcaiPHn6x/3Pq3U9HVSdukXUkhPF9KIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BlHMx/dJMcaiPHn6x/3Pq3U9HVSdukXUkhPF9KIK/img.png&quot; data-origin-width=&quot;421&quot; data-origin-height=&quot;746&quot; data-is-animation=&quot;false&quot; width=&quot;345&quot; height=&quot;611&quot; style=&quot;width: 32.5777%; margin-right: 10px;&quot; data-widthpercent=&quot;33.35&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BlHMx/dJMcaiPHn6x/3Pq3U9HVSdukXUkhPF9KIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBlHMx%2FdJMcaiPHn6x%2F3Pq3U9HVSdukXUkhPF9KIK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;421&quot; height=&quot;746&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byGY86/dJMcadnkTJ3/0CUuSU0E2myEsrGHd2iDE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byGY86/dJMcadnkTJ3/0CUuSU0E2myEsrGHd2iDE1/img.png&quot; data-origin-width=&quot;424&quot; data-origin-height=&quot;750&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.6349%; margin-right: 10px;&quot; data-widthpercent=&quot;33.41&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byGY86/dJMcadnkTJ3/0CUuSU0E2myEsrGHd2iDE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyGY86%2FdJMcadnkTJ3%2F0CUuSU0E2myEsrGHd2iDE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;424&quot; height=&quot;750&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kwS0l/dJMcag5ubqX/mzQusBHnpXKlXn3kck9uPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kwS0l/dJMcag5ubqX/mzQusBHnpXKlXn3kck9uPK/img.png&quot; width=&quot;226&quot; data-origin-width=&quot;424&quot; data-origin-height=&quot;754&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.4618%;&quot; data-widthpercent=&quot;33.24&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kwS0l/dJMcag5ubqX/mzQusBHnpXKlXn3kck9uPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkwS0l%2FdJMcag5ubqX%2FmzQusBHnpXKlXn3kck9uPK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;424&quot; height=&quot;754&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유튭에서 우연히 보게된 멋진 동영상~~~&lt;br /&gt;배경음악과 함께 각 나라를 대표하는 의인화 된 동물과 문화 및 의상을 표현한 동영상들을 보다보니 나도 함 만들어 보고 싶어졌다.&lt;br /&gt;딱 봐도 AI로 만들어 졌음을 짐작할 만 했고, 프롬프트만 잘 만들면 비슷하게 만들 수 있겠다 싶었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 찾아보게 된 사이트 &lt;a href=&quot;https://replicate.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://replicate.com/&lt;/a&gt;&amp;nbsp;&lt;br /&gt;여기는 한마디로 &quot;클라우드에서 오픈소스 AI 모델을 아주 쉽게 실행하고 배포할 수 있게 해주는 플랫폼&quot; 이라고 보면 된다.&lt;br /&gt;API 를 제공하기 때문에 n8n 에 연동하기도 매우 쉽다.&lt;br /&gt;테스트겸 정상 작동되는지 확인해 보니, 생성된 이미지 및 동영상 품질이 나의 막눈에는 너무 좋았다.&lt;br /&gt;바로 거금 10$ 만 일단 결제해서 사용해 보기로 결정하고 n8n 에 워크플로우 부터 작성하기 시작했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1066&quot; data-origin-height=&quot;311&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/di9mVZ/dJMcac9MQ5B/wLnk69kPavV14Jw5KkQVk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/di9mVZ/dJMcac9MQ5B/wLnk69kPavV14Jw5KkQVk1/img.png&quot; data-alt=&quot;&amp;amp;lt; 내 서버에 호스팅하고 있는 n8n 에서 사용하는 Shorts 제작 워크플로우 &amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/di9mVZ/dJMcac9MQ5B/wLnk69kPavV14Jw5KkQVk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdi9mVZ%2FdJMcac9MQ5B%2FwLnk69kPavV14Jw5KkQVk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1066&quot; height=&quot;311&quot; data-origin-width=&quot;1066&quot; data-origin-height=&quot;311&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt; 내 서버에 호스팅하고 있는 n8n 에서 사용하는 Shorts 제작 워크플로우 &amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 GenSpark.ai 사이트(이 사이트는 정기 구독 중)에서도 비슷한 컨셉의 프롬프트로 동영상을 만들고 비교해 봤다.&lt;br /&gt;동영상이나 이미지 관련해서는 replicate.com 사이트가 좀 더 좋아 보인다. (genspark는 약간 호랑이탈 을 쓴것 같은 느낌?)&lt;br /&gt;genspark.ai : &lt;a href=&quot;https://youtu.be/0-dgjTmtudQ&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtu.be/0-dgjTmtudQ&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=0-dgjTmtudQ&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/bkKMBQ/dJMb84p4mgK/xlh0k6ulUCky3o5om1DxkK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=700_178_744_226,https://scrap.kakaocdn.net/dn/byP4Kx/dJMb81fOfrj/YacJwcmuMJpvdYRoKos0Kk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=700_178_744_226,https://scrap.kakaocdn.net/dn/vsL4Y/dJMb82MyEVk/1Nlx272NGKLypa13noOJFk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=700_178_744_226&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;GenSpark KOREA&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/0-dgjTmtudQ&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;replicate.com :&lt;br /&gt;&lt;a href=&quot;https://youtube.com/shorts/qeGL4l-dOBQ&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/shorts/qeGL4l-dOBQ&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/shorts/qeGL4l-dOBQ&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/cHMHr1/dJMb88F0vJx/8Xaw1txB3e1xK1oggDpqH1/img.jpg?width=408&amp;amp;height=720&amp;amp;face=281_250_320_292,https://scrap.kakaocdn.net/dn/vyMok/dJMb84p4mgZ/jQIvtCy8QNsRmB5NvePZQ0/img.jpg?width=408&amp;amp;height=720&amp;amp;face=281_250_320_292,https://scrap.kakaocdn.net/dn/cWW8on/dJMb86OXqX7/Jp1WA2ed6IBgI9ARLBuink/img.jpg?width=408&amp;amp;height=720&amp;amp;face=281_250_320_292&quot; data-video-width=&quot;408&quot; data-video-height=&quot;720&quot; data-video-origin-width=&quot;408&quot; data-video-origin-height=&quot;720&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;AI Korea1&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/qeGL4l-dOBQ&quot; width=&quot;408&quot; height=&quot;720&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://youtube.com/shorts/OFJ14ejXD_8&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/shorts/OFJ14ejXD_8&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/shorts/OFJ14ejXD_8&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/dMl0fF/dJMb8SXtqFL/exi2SOcOZlPONAzLemk1hk/img.jpg?width=408&amp;amp;height=720&amp;amp;face=264_248_293_280,https://scrap.kakaocdn.net/dn/buSijt/dJMb8WevdsZ/Fpc0xhne7eRfcgJ65FaF80/img.jpg?width=408&amp;amp;height=720&amp;amp;face=264_248_293_280,https://scrap.kakaocdn.net/dn/NJ5NL/dJMb9bvXVTw/vBMWItLVacuKTrwXTDKRrk/img.jpg?width=408&amp;amp;height=720&amp;amp;face=264_248_293_280&quot; data-video-width=&quot;408&quot; data-video-height=&quot;720&quot; data-video-origin-width=&quot;408&quot; data-video-origin-height=&quot;720&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;AI Korea2&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/OFJ14ejXD_8&quot; width=&quot;408&quot; height=&quot;720&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://youtube.com/shorts/4oiLgxtGn1k&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/shorts/4oiLgxtGn1k&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/shorts/4oiLgxtGn1k&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/wprL3/dJMb9iICJ69/6A30zxaG37T0mEKosrOhf0/img.jpg?width=408&amp;amp;height=720&amp;amp;face=273_252_297_279,https://scrap.kakaocdn.net/dn/bnQHWa/dJMb9frA5r3/cDxW5RaxMj5j9YakkFIO8K/img.jpg?width=408&amp;amp;height=720&amp;amp;face=273_252_297_279,https://scrap.kakaocdn.net/dn/imdUa/dJMb9gxg0ec/jKf1QwrvvBNShEKdN1Hko1/img.jpg?width=408&amp;amp;height=720&amp;amp;face=273_252_297_279&quot; data-video-width=&quot;408&quot; data-video-height=&quot;720&quot; data-video-origin-width=&quot;408&quot; data-video-origin-height=&quot;720&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;AI Mexico&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/4oiLgxtGn1k&quot; width=&quot;408&quot; height=&quot;720&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 통합본 :&lt;a href=&quot;https://youtube.com/shorts/72AhDqczipg?feature=share&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/shorts/72AhDqczipg?feature=share&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/shorts/72AhDqczipg&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/cdtYa5/dJMb8864ME7/YN2kCShl0qLGRC2nnY9Ykk/img.jpg?width=405&amp;amp;height=720&amp;amp;face=279_254_320_299,https://scrap.kakaocdn.net/dn/cigMhc/dJMb83SeIAx/xh9q2XW2v6FwxYDpsb1hrK/img.jpg?width=405&amp;amp;height=720&amp;amp;face=279_254_320_299,https://scrap.kakaocdn.net/dn/bwmwuB/dJMb87NSfyf/8kIBFE2kJ8GXWSJzzkHRvK/img.jpg?width=405&amp;amp;height=720&amp;amp;face=279_254_320_299&quot; data-video-width=&quot;405&quot; data-video-height=&quot;720&quot; data-video-origin-width=&quot;405&quot; data-video-origin-height=&quot;720&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;AI로 만들어 봤어요&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/72AhDqczipg&quot; width=&quot;405&quot; height=&quot;720&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프롬프트 만으로도 이렇게 멋진 동영상을 만들어 볼 수 있음에 놀라지 않을 수 없었다.&lt;br /&gt;시간 좀 늘리고 많은 나라를 추가하면 꽤 괜찮은 동영상이 만들어 질 것 같다.&lt;br /&gt;다음에는 짧은 영화 함 맹글어 볼까나? ㅎㅎ&lt;/p&gt;</description>
      <category>Tech Story</category>
      <category>AI</category>
      <category>n8n</category>
      <category>shorts</category>
      <category>동영상</category>
      <category>전통</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/76</guid>
      <comments>https://techsuda.tistory.com/entry/AI-n8n-%EC%9C%A0%ED%8A%AD%EC%97%90%EC%84%9C-%EB%B4%A4%EB%8D%98-%EB%A9%8B%EC%A7%84-%EC%98%81%EC%83%81%EC%9D%84-%EC%A7%81%EC%A0%91-%EA%B5%AC%ED%98%84#entry76comment</comments>
      <pubDate>Sat, 7 Feb 2026 23:54:11 +0900</pubDate>
    </item>
    <item>
      <title>[IT장비] PC 2대와 KVM 공유 환경 구축</title>
      <link>https://techsuda.tistory.com/entry/IT%EC%9E%A5%EB%B9%84-PC-2%EB%8C%80%EC%99%80-KVM-%EA%B3%B5%EC%9C%A0-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;필자는 프로그램 개발자다. 주로 Windows PC를 메인으로 사용하고, iOS 개발을 위해 Mac mini 를 같이 사용하고 있다.&lt;br /&gt;여러 프로그램들을 화면에 띄워 놓고 사용하기 위해 Dual Monitor 를 사용하고 있었다.&lt;br /&gt;PC 1대만 사용할 때는 불편함이 없지만 Mac mini를 추가로 같이 사용하다 보니 예상되는 불편함이 바로 키보드와 마우스, 그리고 듀얼모니터로 사용하는 2대의 모니터를 사용할 PC에 연결하는 작업이었다. Mac을 사용하기 위해 여분으로 가지고 있던 키보드와 마우스, 그리고 사용하지 않던 모니터 한대를 Mac에 연결해 놓고 보니, 좁은 책상에 여유공간이 없고 너무 불편해 지는 것 이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 불편함을 해결해 주는 장치가 바로 KVM Switch 이다.&lt;br /&gt;KVM은&lt;span&gt;&amp;nbsp;&lt;/span&gt;키보드(Keyboard), 비디오(Video), 마우스(Mouse)의 약자&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;로, 이러한 입출력 장치를 하나의 세트로 여러 컴퓨터를 선택, 전환하며 제어할 수 있도록 하는 장치를 의미한다.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvNjRK/dJMcaia8fjM/DlomaZxWXkbmks2e4jdQ9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvNjRK/dJMcaia8fjM/DlomaZxWXkbmks2e4jdQ9K/img.png&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;448&quot; data-is-animation=&quot;false&quot; width=&quot;391&quot; data-widthpercent=&quot;50.11&quot; data-filename=&quot;blob&quot; style=&quot;width: 49.528%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvNjRK/dJMcaia8fjM/DlomaZxWXkbmks2e4jdQ9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvNjRK%2FdJMcaia8fjM%2FDlomaZxWXkbmks2e4jdQ9K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;753&quot; height=&quot;448&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lk5OH/dJMcac2ZOFI/frIKTNE3KMncgwE1CFYMh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lk5OH/dJMcac2ZOFI/frIKTNE3KMncgwE1CFYMh1/img.png&quot; width=&quot;344&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;447&quot; data-origin-width=&quot;748&quot; data-widthpercent=&quot;49.89&quot; data-filename=&quot;blob&quot; style=&quot;width: 49.3092%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lk5OH/dJMcac2ZOFI/frIKTNE3KMncgwE1CFYMh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Flk5OH%2FdJMcac2ZOFI%2FfrIKTNE3KMncgwE1CFYMh1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;748&quot; height=&quot;447&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;KVM 도입전&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Windows PC 를 사용할 때는 왼쪽 그림과 같이 키보드, 모니터 2개, 마우스 (이하 KVM) 를 연결해서 사용하다가, Mac을 사용해야 할 때는 사용하던 키보드와 모니터, 그리고 마우스를 윈도우 피씨에서 맥으로 바꾸어 연결 후 맥에서의 작업이 끝나면 다시 윈도우 PC로 연결해주곤 했다. (미리 예상해서 알리에 KVM 스위치를 주문하고 맥을 구입했었는데, 맥 설치 후 알리 배송이 2~3일 정도 더 걸리는 바람에 몇일동안은 수작업으로 연결을 바꿔가면서 작업했다. ㅋ~~ 너무 불편했다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 불편함을 말끔하게 해소하는 장치가 바로 KVM Switch 이다.&lt;br /&gt;종류도 무진장 많기는 하지만, 필자의 선택 기준은 비교적 명확했다.&lt;br /&gt;1. 듀얼 모니터 지원 (어차피 해상도 좋은 모니터는 아니기에 해상도는 신경 안 썼다.)&lt;br /&gt;2. 되도록 이면 가성비 좋은 장비 (알리 기준 3~4만원대...)&lt;br /&gt;그래서 선택한 장치가 바로 이것이다. (똑같은 장치를 한국에서도 살수 있었으나, 역시 가격문제로 알리에서 구매함)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;869&quot; data-origin-height=&quot;525&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kEniJ/dJMb99LZog6/g445ydLmKROuQsJKbnkC80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kEniJ/dJMb99LZog6/g445ydLmKROuQsJKbnkC80/img.png&quot; data-alt=&quot;위 : 후면 아래 : 전면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kEniJ/dJMb99LZog6/g445ydLmKROuQsJKbnkC80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkEniJ%2FdJMb99LZog6%2Fg445ydLmKROuQsJKbnkC80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;582&quot; height=&quot;525&quot; data-origin-width=&quot;869&quot; data-origin-height=&quot;525&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;위 : 후면 아래 : 전면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복잡해 보이긴 해도 별거 없다. 후면에 KVM Set 를 장치에 연결하고, 각각의 피씨(윈도우즈 &amp;amp; 맥)를 PC1, PC2에 듀얼모니터로 사용할 HDMI 2개 와 USB를 각각 연결해주면 된다. 전면에는 공유해서 사용할 마우스, 키보드, 스피커 등을 연결해 주면 설치는 끝!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1105&quot; data-origin-height=&quot;552&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cG5XsT/dJMb99SMjk1/7dkQrE4WMFhthtyrLW8wQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cG5XsT/dJMb99SMjk1/7dkQrE4WMFhthtyrLW8wQK/img.png&quot; data-alt=&quot;KVM 스위치는 2대의 PC가 두대의 모니터와 키보드, 마우스, 그리고 USB로 연결가능한 기타 장비들(동글 포함)을 전환 사용 할 수 있도록 해준다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cG5XsT/dJMb99SMjk1/7dkQrE4WMFhthtyrLW8wQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcG5XsT%2FdJMb99SMjk1%2F7dkQrE4WMFhthtyrLW8wQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1105&quot; height=&quot;552&quot; data-origin-width=&quot;1105&quot; data-origin-height=&quot;552&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;KVM 스위치는 2대의 PC가 두대의 모니터와 키보드, 마우스, 그리고 USB로 연결가능한 기타 장비들(동글 포함)을 전환 사용 할 수 있도록 해준다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비교적 저렴한 스위칭 장비지만 책상을 효율적으로 사용하고, 기기간 전환을 쉽게 전환 할 수 있다는 것 만으로도 없으면 안될 너무도 소중한 기능이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 필자에게 해당되는 기기의 문제점(?)이 하나 있었다.&lt;br /&gt;바로 이 제품이 지원하는 HotKey 기능인데, 쉽게 얘기하자면 Switch 버튼이나 리모컨으로 2대의 PC를 사용하도록(전환) 하는게 아니라, 키보드의 특정 키 조합(Hotkey)으로 사용할 PC를 전환하게 해 주는 기능이다. &lt;br /&gt;이 기능이 필자에게는 큰 문제인데 바로 Hotkey 로 사용되는 키 조합이 Ctrl + Shift + 1 or 2 이고, 여러 프로그램에서 자주 사용하는 키 조합이 바로 Ctrl + Shift 조합키라는 것이다. (워드단위 선택 등...)&lt;br /&gt;그래서 Hotkey 를 '사용안함'으로 설정했더니, Ctrl + Shift 동시 키 입력 자체를 막아버리는 것이 아닌가?&lt;br /&gt;그렇다고 사용하는 프로그램들의 설정에서 키 조합을 모두 바꿀 수도 없는 노릇이고... (빈대잡자고 집을 태우는 격... ㅠㅠ)&lt;br /&gt;한참 고민했는데 의외로 해결방법은 간단한 곳에 있었다. &lt;br /&gt;&lt;b&gt;키보드를 Hotkey 포트에 연결하지 않고, 일반 USB포트에 연결하면 해결&lt;/b&gt; 된다.&lt;br /&gt;그러면 Hotkey 기능을 사용하지 않고 키보드의 Ctrl + Shift 조합키를 평소와 같이 동일하게 사용할 수 있게 된다.&lt;br /&gt;마지막으로 KVM을 사용하는 동영상을 첨부하니 참고하시기 바란다.&lt;br /&gt;&lt;a href=&quot;https://youtu.be/DPd6e1uHg8s&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtu.be/DPd6e1uHg8s&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=DPd6e1uHg8s&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/deLDat/dJMb82eIEiP/ZdYatgFaVlk0nqEEe9P0KK/img.jpg?width=480&amp;amp;height=360&amp;amp;face=0_0_480_360,https://scrap.kakaocdn.net/dn/cRfe1b/dJMb87f10ha/wR55LVK5U5l1nxlBdIVUgK/img.jpg?width=480&amp;amp;height=360&amp;amp;face=0_0_480_360,https://scrap.kakaocdn.net/dn/crU7OH/dJMb83Sermj/S4XhTtzmQWo0rHzV0gHMM0/img.jpg?width=480&amp;amp;height=360&amp;amp;face=0_0_480_360&quot; data-video-width=&quot;480&quot; data-video-height=&quot;360&quot; data-video-origin-width=&quot;480&quot; data-video-origin-height=&quot;360&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;KVM Switch : Dual monitor &amp;amp; 2 PC&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/DPd6e1uHg8s&quot; width=&quot;480&quot; height=&quot;360&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2대의 PC가 듀얼모니터를 같이 사용해야 한다면 2X2 KVM Switch 사용하세요~~~&lt;/p&gt;</description>
      <category>Tech Story</category>
      <category>2 by 2</category>
      <category>2x2</category>
      <category>dual monitor</category>
      <category>HDMI</category>
      <category>kvm</category>
      <category>switch</category>
      <category>모니터공유</category>
      <category>스위치</category>
      <category>전환</category>
      <category>책상공간</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/75</guid>
      <comments>https://techsuda.tistory.com/entry/IT%EC%9E%A5%EB%B9%84-PC-2%EB%8C%80%EC%99%80-KVM-%EA%B3%B5%EC%9C%A0-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95#entry75comment</comments>
      <pubDate>Mon, 2 Feb 2026 22:57:21 +0900</pubDate>
    </item>
    <item>
      <title>2025 제주에서...</title>
      <link>https://techsuda.tistory.com/entry/2025-%EC%A0%9C%EC%A3%BC%EC%97%90%EC%84%9C</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;생일기념여행. 올해도 어김없이 제주에서 보내다.&lt;br /&gt;올레18코스와 어음리 억새 군락지에서 억새를 진하게 느껴볼수 있었다.&lt;br /&gt;한적한 길을 천천히 걸으며 차타고 다니면서는 볼수 없었던 풍광을 카메라에, 그리고 기억속에 담아본다.&lt;br /&gt;바쁘던 시간속에서 가족과 함께 여유로운 생일파티를 오붓하게 보내며......&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 여행 사진은 2만원이 채 안되는 캐논마운트 60mm F8 Holga 렌즈가 한 몫 했다.&lt;br /&gt;큰 기대 없었고 재밌겠다 싶어서 구매한 플라스틱 토이렌즈인데, 의외로 내맘에 쏙~ 드는 결과물을 보여 주었다.&lt;br /&gt;풀프레임 바디인지라 비네팅이 크게 있고, 애써 플레어를 신경쓰지도 않았더니 디지털카메라의 선명함 보다는 투박한 느낌이 나름 좋게 느껴진다. 디카로 즐기는 필카 느낌이라고나 할까?&lt;br /&gt;오래된 흑백필름 시절을 느껴보기 위해 몇장은 흑백으로 바꿔보았는데 내눈에는 나름 봐줄만 한 것 같다.&lt;br /&gt;어차피 누군가에게 보여주기 위한 사진이 아니고, 내 생활의 기록이 되는 취미사진이니 내맘에 들면 그것으로 충분하다. ㅎㅎ&lt;br /&gt;앞으로 자주 사용하게 될 것 같은 느낌이 드는 저렴이 렌즈다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0729.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YU2pJ/dJMcabCHve5/qUvi9QkdbntlRVpSpQkHuk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YU2pJ/dJMcabCHve5/qUvi9QkdbntlRVpSpQkHuk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YU2pJ/dJMcabCHve5/qUvi9QkdbntlRVpSpQkHuk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYU2pJ%2FdJMcabCHve5%2FqUvi9QkdbntlRVpSpQkHuk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0729.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0737.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjxukq/dJMcabCHve0/Hjt9m8zFXH7n1YZuQN4Ydk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjxukq/dJMcabCHve0/Hjt9m8zFXH7n1YZuQN4Ydk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjxukq/dJMcabCHve0/Hjt9m8zFXH7n1YZuQN4Ydk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcjxukq%2FdJMcabCHve0%2FHjt9m8zFXH7n1YZuQN4Ydk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0737.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0740.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjQoZg/dJMcaiV48gi/Itwn90SxzHCIDxhUyuR67K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjQoZg/dJMcaiV48gi/Itwn90SxzHCIDxhUyuR67K/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjQoZg/dJMcaiV48gi/Itwn90SxzHCIDxhUyuR67K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjQoZg%2FdJMcaiV48gi%2FItwn90SxzHCIDxhUyuR67K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0740.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0741.JPG&quot; data-origin-width=&quot;5472&quot; data-origin-height=&quot;3648&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dsW50i/dJMcahJHju4/KxGIzUzUk4kQk18WBNpkU0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dsW50i/dJMcahJHju4/KxGIzUzUk4kQk18WBNpkU0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dsW50i/dJMcahJHju4/KxGIzUzUk4kQk18WBNpkU0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdsW50i%2FdJMcahJHju4%2FKxGIzUzUk4kQk18WBNpkU0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5472&quot; height=&quot;3648&quot; data-filename=&quot;IMG_0741.JPG&quot; data-origin-width=&quot;5472&quot; data-origin-height=&quot;3648&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0755.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ATU1N/dJMcahJHjuT/flJn0hBgTyL6Vs87Grp801/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ATU1N/dJMcahJHjuT/flJn0hBgTyL6Vs87Grp801/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ATU1N/dJMcahJHjuT/flJn0hBgTyL6Vs87Grp801/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FATU1N%2FdJMcahJHjuT%2FflJn0hBgTyL6Vs87Grp801%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0755.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0757.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rNC5g/dJMcabCHve2/BxGZ1TZKTk3ABi1XKx1Rtk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rNC5g/dJMcabCHve2/BxGZ1TZKTk3ABi1XKx1Rtk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rNC5g/dJMcabCHve2/BxGZ1TZKTk3ABi1XKx1Rtk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrNC5g%2FdJMcabCHve2%2FBxGZ1TZKTk3ABi1XKx1Rtk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0757.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0763.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTQfkj/dJMcahJHjuW/SaTyfx76R6QZcIKrBeibJ1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTQfkj/dJMcahJHjuW/SaTyfx76R6QZcIKrBeibJ1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTQfkj/dJMcahJHjuW/SaTyfx76R6QZcIKrBeibJ1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTQfkj%2FdJMcahJHjuW%2FSaTyfx76R6QZcIKrBeibJ1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0763.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0767.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dkawRd/dJMcaiV48gf/XxJbdAPll7x5FUyG8AOsr1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dkawRd/dJMcaiV48gf/XxJbdAPll7x5FUyG8AOsr1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dkawRd/dJMcaiV48gf/XxJbdAPll7x5FUyG8AOsr1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdkawRd%2FdJMcaiV48gf%2FXxJbdAPll7x5FUyG8AOsr1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0767.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0775.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GBRf6/dJMcahJHjuX/JdU4kfdOsR3lMmfXFz9bs1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GBRf6/dJMcahJHjuX/JdU4kfdOsR3lMmfXFz9bs1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GBRf6/dJMcahJHjuX/JdU4kfdOsR3lMmfXFz9bs1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGBRf6%2FdJMcahJHjuX%2FJdU4kfdOsR3lMmfXFz9bs1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0775.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0779_BW.JPG&quot; data-origin-width=&quot;5472&quot; data-origin-height=&quot;3648&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgE8YL/dJMcahJHju1/0HDqRD4el5ajlZBfZl0Kh0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgE8YL/dJMcahJHju1/0HDqRD4el5ajlZBfZl0Kh0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgE8YL/dJMcahJHju1/0HDqRD4el5ajlZBfZl0Kh0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcgE8YL%2FdJMcahJHju1%2F0HDqRD4el5ajlZBfZl0Kh0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5472&quot; height=&quot;3648&quot; data-filename=&quot;IMG_0779_BW.JPG&quot; data-origin-width=&quot;5472&quot; data-origin-height=&quot;3648&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0782.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJ7JbN/dJMcaiV48gj/wn2obOZbCawrS7hRCMJg40/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJ7JbN/dJMcaiV48gj/wn2obOZbCawrS7hRCMJg40/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJ7JbN/dJMcaiV48gj/wn2obOZbCawrS7hRCMJg40/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJ7JbN%2FdJMcaiV48gj%2Fwn2obOZbCawrS7hRCMJg40%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0782.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0784_BW.JPG&quot; data-origin-width=&quot;5472&quot; data-origin-height=&quot;3648&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dJSWlf/dJMcabCHvfd/GIIgVQmhHY4DPRiTRksFkK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dJSWlf/dJMcabCHvfd/GIIgVQmhHY4DPRiTRksFkK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dJSWlf/dJMcabCHvfd/GIIgVQmhHY4DPRiTRksFkK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdJSWlf%2FdJMcabCHvfd%2FGIIgVQmhHY4DPRiTRksFkK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5472&quot; height=&quot;3648&quot; data-filename=&quot;IMG_0784_BW.JPG&quot; data-origin-width=&quot;5472&quot; data-origin-height=&quot;3648&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0785.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FEJrV/dJMcahJHjuV/RK03ktoYJ8H2jH7O8viPB0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FEJrV/dJMcahJHjuV/RK03ktoYJ8H2jH7O8viPB0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FEJrV/dJMcahJHjuV/RK03ktoYJ8H2jH7O8viPB0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFEJrV%2FdJMcahJHjuV%2FRK03ktoYJ8H2jH7O8viPB0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0785.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0788_BW.JPG&quot; data-origin-width=&quot;5472&quot; data-origin-height=&quot;3648&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cLJDBQ/dJMb99LEvss/p8qcQPaRkbv7c7KScIZyx0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cLJDBQ/dJMb99LEvss/p8qcQPaRkbv7c7KScIZyx0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cLJDBQ/dJMb99LEvss/p8qcQPaRkbv7c7KScIZyx0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcLJDBQ%2FdJMb99LEvss%2Fp8qcQPaRkbv7c7KScIZyx0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5472&quot; height=&quot;3648&quot; data-filename=&quot;IMG_0788_BW.JPG&quot; data-origin-width=&quot;5472&quot; data-origin-height=&quot;3648&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0790.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SqiLR/dJMcabCHve4/9iKA4WNjTN66m1fJojXMN1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SqiLR/dJMcabCHve4/9iKA4WNjTN66m1fJojXMN1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SqiLR/dJMcabCHve4/9iKA4WNjTN66m1fJojXMN1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSqiLR%2FdJMcabCHve4%2F9iKA4WNjTN66m1fJojXMN1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0790.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0818.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RcyNb/dJMb99LEvsl/4DD2ttaKyGUNOhkcsxF7xk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RcyNb/dJMb99LEvsl/4DD2ttaKyGUNOhkcsxF7xk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RcyNb/dJMb99LEvsl/4DD2ttaKyGUNOhkcsxF7xk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRcyNb%2FdJMb99LEvsl%2F4DD2ttaKyGUNOhkcsxF7xk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0818.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0823.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7pLpm/dJMcahJHjuU/1V9fr5CSAB2OoJ4W8Dunak/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7pLpm/dJMcahJHjuU/1V9fr5CSAB2OoJ4W8Dunak/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7pLpm/dJMcahJHjuU/1V9fr5CSAB2OoJ4W8Dunak/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7pLpm%2FdJMcahJHjuU%2F1V9fr5CSAB2OoJ4W8Dunak%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0823.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0825.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AKkiZ/dJMcaiV48gh/4wG6Ms0VNGgrCqkgsppyhK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AKkiZ/dJMcaiV48gh/4wG6Ms0VNGgrCqkgsppyhK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AKkiZ/dJMcaiV48gh/4wG6Ms0VNGgrCqkgsppyhK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAKkiZ%2FdJMcaiV48gh%2F4wG6Ms0VNGgrCqkgsppyhK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0825.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0829.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dy4SMV/dJMcaiV48gg/LZDR7vOTRLyuXyxK6JVj5k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dy4SMV/dJMcaiV48gg/LZDR7vOTRLyuXyxK6JVj5k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dy4SMV/dJMcaiV48gg/LZDR7vOTRLyuXyxK6JVj5k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdy4SMV%2FdJMcaiV48gg%2FLZDR7vOTRLyuXyxK6JVj5k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0829.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0834.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ePyosI/dJMcaiV48gk/u6XW0Q3EQXEAgpMDFagTJ0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ePyosI/dJMcaiV48gk/u6XW0Q3EQXEAgpMDFagTJ0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ePyosI/dJMcaiV48gk/u6XW0Q3EQXEAgpMDFagTJ0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FePyosI%2FdJMcaiV48gk%2Fu6XW0Q3EQXEAgpMDFagTJ0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0834.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0838_BW.JPG&quot; data-origin-width=&quot;5472&quot; data-origin-height=&quot;3648&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k2hCx/dJMcahJHju2/k3GQkZ5ekk2s7RdwCOUqA1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k2hCx/dJMcahJHju2/k3GQkZ5ekk2s7RdwCOUqA1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k2hCx/dJMcahJHju2/k3GQkZ5ekk2s7RdwCOUqA1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk2hCx%2FdJMcahJHju2%2Fk3GQkZ5ekk2s7RdwCOUqA1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5472&quot; height=&quot;3648&quot; data-filename=&quot;IMG_0838_BW.JPG&quot; data-origin-width=&quot;5472&quot; data-origin-height=&quot;3648&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0857_BW.JPG&quot; data-origin-width=&quot;5472&quot; data-origin-height=&quot;3648&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lIVkY/dJMcaiV48gu/DfS8W01YAS6kgwjQyH3xAk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lIVkY/dJMcaiV48gu/DfS8W01YAS6kgwjQyH3xAk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lIVkY/dJMcaiV48gu/DfS8W01YAS6kgwjQyH3xAk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlIVkY%2FdJMcaiV48gu%2FDfS8W01YAS6kgwjQyH3xAk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5472&quot; height=&quot;3648&quot; data-filename=&quot;IMG_0857_BW.JPG&quot; data-origin-width=&quot;5472&quot; data-origin-height=&quot;3648&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0860.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WHdCi/dJMb99LEvsm/fIF6os07z1rburP46FkHo1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WHdCi/dJMb99LEvsm/fIF6os07z1rburP46FkHo1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WHdCi/dJMb99LEvsm/fIF6os07z1rburP46FkHo1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWHdCi%2FdJMb99LEvsm%2FfIF6os07z1rburP46FkHo1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0860.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0861.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfJ2QX/dJMcaiV48gq/zq6yIeze7EypQKY72ClQs1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfJ2QX/dJMcaiV48gq/zq6yIeze7EypQKY72ClQs1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfJ2QX/dJMcaiV48gq/zq6yIeze7EypQKY72ClQs1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfJ2QX%2FdJMcaiV48gq%2Fzq6yIeze7EypQKY72ClQs1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0861.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0878.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vVaJ9/dJMcabCHve7/UxigqV6kYDemK3NEdTjeDK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vVaJ9/dJMcabCHve7/UxigqV6kYDemK3NEdTjeDK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vVaJ9/dJMcabCHve7/UxigqV6kYDemK3NEdTjeDK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvVaJ9%2FdJMcabCHve7%2FUxigqV6kYDemK3NEdTjeDK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0878.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0895.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNiwvC/dJMcaiV48go/HgSBaANlEH4GkJAVj4gPzk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNiwvC/dJMcaiV48go/HgSBaANlEH4GkJAVj4gPzk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNiwvC/dJMcaiV48go/HgSBaANlEH4GkJAVj4gPzk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNiwvC%2FdJMcaiV48go%2FHgSBaANlEH4GkJAVj4gPzk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0895.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0897.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JnSq2/dJMcaiV48gm/nEFbGPbcFecj7D4YJU45e1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JnSq2/dJMcaiV48gm/nEFbGPbcFecj7D4YJU45e1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JnSq2/dJMcaiV48gm/nEFbGPbcFecj7D4YJU45e1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJnSq2%2FdJMcaiV48gm%2FnEFbGPbcFecj7D4YJU45e1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0897.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0908.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EX2LD/dJMcabCHvfa/3KklzWOpJCKvzpkg4mMGM1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EX2LD/dJMcabCHvfa/3KklzWOpJCKvzpkg4mMGM1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EX2LD/dJMcabCHvfa/3KklzWOpJCKvzpkg4mMGM1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEX2LD%2FdJMcabCHvfa%2F3KklzWOpJCKvzpkg4mMGM1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0908.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0912.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d5EeRh/dJMcaiV48gn/jFjKkiGegEWGEi2jUJUDH0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d5EeRh/dJMcaiV48gn/jFjKkiGegEWGEi2jUJUDH0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d5EeRh/dJMcaiV48gn/jFjKkiGegEWGEi2jUJUDH0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd5EeRh%2FdJMcaiV48gn%2FjFjKkiGegEWGEi2jUJUDH0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0912.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0913.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bahuTJ/dJMcabCHve9/VdTLTNO6kUsGnE7wQZRF7K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bahuTJ/dJMcabCHve9/VdTLTNO6kUsGnE7wQZRF7K/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bahuTJ/dJMcabCHve9/VdTLTNO6kUsGnE7wQZRF7K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbahuTJ%2FdJMcabCHve9%2FVdTLTNO6kUsGnE7wQZRF7K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0913.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0915.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cTyAGs/dJMcabCHve6/TPYtI3SATkGDKj95fLzJV0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cTyAGs/dJMcabCHve6/TPYtI3SATkGDKj95fLzJV0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cTyAGs/dJMcabCHve6/TPYtI3SATkGDKj95fLzJV0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcTyAGs%2FdJMcabCHve6%2FTPYtI3SATkGDKj95fLzJV0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0915.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0926.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ooAj6/dJMcabCHvfc/obvrIwCjvWHwgZ3FkdSpw1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ooAj6/dJMcabCHvfc/obvrIwCjvWHwgZ3FkdSpw1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ooAj6/dJMcabCHvfc/obvrIwCjvWHwgZ3FkdSpw1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FooAj6%2FdJMcabCHvfc%2FobvrIwCjvWHwgZ3FkdSpw1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0926.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0934.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pvgjG/dJMcaiV48gs/Gl6ILE83Qc3NxBd2ZLnJb1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pvgjG/dJMcaiV48gs/Gl6ILE83Qc3NxBd2ZLnJb1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pvgjG/dJMcaiV48gs/Gl6ILE83Qc3NxBd2ZLnJb1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpvgjG%2FdJMcaiV48gs%2FGl6ILE83Qc3NxBd2ZLnJb1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0934.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0942.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kBL1U/dJMcahJHju0/BeFfFsVNK6kfkTEQ5IdlF1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kBL1U/dJMcahJHju0/BeFfFsVNK6kfkTEQ5IdlF1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kBL1U/dJMcahJHju0/BeFfFsVNK6kfkTEQ5IdlF1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkBL1U%2FdJMcahJHju0%2FBeFfFsVNK6kfkTEQ5IdlF1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0942.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0946.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/egeb3K/dJMcahJHjuZ/j22kCDESqxOMrbnwLbfKk1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/egeb3K/dJMcahJHjuZ/j22kCDESqxOMrbnwLbfKk1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/egeb3K/dJMcahJHjuZ/j22kCDESqxOMrbnwLbfKk1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fegeb3K%2FdJMcahJHjuZ%2Fj22kCDESqxOMrbnwLbfKk1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0946.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0948.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qIQxW/dJMcabCHvfb/JKZSSDujMxyZOziGR5DPX0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qIQxW/dJMcabCHvfb/JKZSSDujMxyZOziGR5DPX0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qIQxW/dJMcabCHvfb/JKZSSDujMxyZOziGR5DPX0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqIQxW%2FdJMcabCHvfb%2FJKZSSDujMxyZOziGR5DPX0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0948.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0949.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yXWFR/dJMb99LEvsn/toUlHVENcG7I7q1AJHS4Dk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yXWFR/dJMb99LEvsn/toUlHVENcG7I7q1AJHS4Dk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yXWFR/dJMb99LEvsn/toUlHVENcG7I7q1AJHS4Dk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyXWFR%2FdJMb99LEvsn%2FtoUlHVENcG7I7q1AJHS4Dk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0949.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0956.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNH6DT/dJMb99LEvsp/8wXLoBxzRdRP9TjKGhAfS0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNH6DT/dJMb99LEvsp/8wXLoBxzRdRP9TjKGhAfS0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNH6DT/dJMb99LEvsp/8wXLoBxzRdRP9TjKGhAfS0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNH6DT%2FdJMb99LEvsp%2F8wXLoBxzRdRP9TjKGhAfS0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0956.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0961.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OWT7u/dJMb99LEvsr/zQp3GM33cjkcPQnFk8dwq1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OWT7u/dJMb99LEvsr/zQp3GM33cjkcPQnFk8dwq1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OWT7u/dJMb99LEvsr/zQp3GM33cjkcPQnFk8dwq1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOWT7u%2FdJMb99LEvsr%2FzQp3GM33cjkcPQnFk8dwq1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0961.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0973.JPG&quot; data-origin-width=&quot;5472&quot; data-origin-height=&quot;3648&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vzp5I/dJMb99LEvYF/1DV6s9OU2Xuc3i5cmHbod0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vzp5I/dJMb99LEvYF/1DV6s9OU2Xuc3i5cmHbod0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vzp5I/dJMb99LEvYF/1DV6s9OU2Xuc3i5cmHbod0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fvzp5I%2FdJMb99LEvYF%2F1DV6s9OU2Xuc3i5cmHbod0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5472&quot; height=&quot;3648&quot; data-filename=&quot;IMG_0973.JPG&quot; data-origin-width=&quot;5472&quot; data-origin-height=&quot;3648&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0983.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0X3dB/dJMcaiV48gt/3J2gjkz44GQ2ggTbyq6ol0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0X3dB/dJMcaiV48gt/3J2gjkz44GQ2ggTbyq6ol0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0X3dB/dJMcaiV48gt/3J2gjkz44GQ2ggTbyq6ol0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0X3dB%2FdJMcaiV48gt%2F3J2gjkz44GQ2ggTbyq6ol0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_0983.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_1018.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A4Obm/dJMb99LEvso/vJL9nbqyKy69PNyCfb0iKK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A4Obm/dJMb99LEvso/vJL9nbqyKy69PNyCfb0iKK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A4Obm/dJMb99LEvso/vJL9nbqyKy69PNyCfb0iKK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA4Obm%2FdJMb99LEvso%2FvJL9nbqyKy69PNyCfb0iKK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_1018.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_1025.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ldlxb/dJMb99LEvsq/6QJSVyvlnK3mQlZPT2aGn0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ldlxb/dJMb99LEvsq/6QJSVyvlnK3mQlZPT2aGn0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ldlxb/dJMb99LEvsq/6QJSVyvlnK3mQlZPT2aGn0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLdlxb%2FdJMb99LEvsq%2F6QJSVyvlnK3mQlZPT2aGn0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3648&quot; height=&quot;2432&quot; data-filename=&quot;IMG_1025.JPG&quot; data-origin-width=&quot;3648&quot; data-origin-height=&quot;2432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Gallery</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/74</guid>
      <comments>https://techsuda.tistory.com/entry/2025-%EC%A0%9C%EC%A3%BC%EC%97%90%EC%84%9C#entry74comment</comments>
      <pubDate>Sun, 7 Dec 2025 23:28:35 +0900</pubDate>
    </item>
    <item>
      <title>[Python] System에 반복 및 예약 실행 설정 (Scheduler)</title>
      <link>https://techsuda.tistory.com/entry/Python-System%EC%97%90-%EB%B0%98%EB%B3%B5-%EB%B0%8F-%EC%98%88%EC%95%BD-%EC%8B%A4%ED%96%89-%EC%84%A4%EC%A0%95-Scheduler-1</link>
      <description>&lt;h1&gt;&lt;span style=&quot;color: #366091;&quot;&gt;Python으로 시스템 자동화하기&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3gopm/btsO1GFG9Uq/mN1YyJjBXkCndD9NhExCzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3gopm/btsO1GFG9Uq/mN1YyJjBXkCndD9NhExCzk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3gopm/btsO1GFG9Uq/mN1YyJjBXkCndD9NhExCzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3gopm%2FbtsO1GFG9Uq%2FmN1YyJjBXkCndD9NhExCzk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;318&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파이썬, 당신의 손 안의 마법 지팡이! 오늘은 이 마법 지팡이로 시스템을 똑똑하게 만들어주는 방법에 대해 이야기해 보겠습니다.&lt;br /&gt;바로 '반복 및 예약 실행 설정', 즉 스케줄러(Scheduler)입니다. 마치 시계처럼, 정해진 시간에, 정해진 일을 척척 해내는 자동 비서 같은 녀석이죠.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;1. 왜 스케줄러가 필요할까요?&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;스케줄러는 우리 삶의 편리함을 넘어, 시스템 운영의 효율성을 극대화하는 핵심 도구입니다.&lt;br /&gt;다음은 스케줄러가 필요한 몇 가지 이유입니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자동화된 작업 실행:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 특정 시간, 날짜 또는 간격으로 작업을 자동으로 실행하여 수동 작업을 줄입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자원 관리 최적화:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 시스템 자원을 효율적으로 사용하도록 작업을 예약하여 시스템 과부하를 방지합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;유지보수 및 백업:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 정기적인 데이터 백업, 시스템 유지보수 작업을 자동화하여 데이터 손실 및 시스템 오류를 예방합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시간 절약 및 생산성 향상:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 반복적인 작업을 자동화하여 개발자 및 운영자의 시간을 절약하고, 다른 중요한 업무에 집중할 수 있도록 돕습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;2. Python 스케줄러 라이브러리 소개&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파이썬에는 다양한 스케줄러 라이브러리가 존재합니다. 각 라이브러리는 사용 편의성, 기능, 그리고 시스템 환경에 따라 장단점을 가지고 있습니다. 다음은 몇 가지 인기 있는 라이브러리입니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;2.1. &lt;/span&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;schedule&lt;/span&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt; 라이브러리&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;schedule&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 라이브러리는 가장 간단하고 사용하기 쉬운 스케줄러입니다. 몇 줄의 코드로 작업을 예약할 수 있어, 초보자도 쉽게 접근할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;import schedule&lt;br /&gt;import time&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;def job():&lt;br /&gt;&amp;nbsp; &amp;nbsp; print(&quot;I'm working...&quot;)&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp; # 매일 오전 10시에 job 함수 실행&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; schedule.every().day.at(&quot;10:00&quot;).do(job)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; # 매 10초마다 job 함수 실행&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; schedule.every(10).seconds.do(job)&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; # 매주 월요일 job 함수 실행&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp; schedule.every().monday.do(job)&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; while True:&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; schedule.run_pending()&amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; time.sleep(1)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위 코드는 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;schedule&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 라이브러리를 사용하여 다양한 시간 간격으로 작업을 예약하는 예시입니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;2.2. &lt;/span&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;APScheduler&lt;/span&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt; 라이브러리&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;APScheduler&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;는 더 강력하고 유연한 스케줄러입니다. 다양한 트리거(trigger) 방식을 지원하며, 작업의 지속적인 실행, 중단, 재시작을 관리할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;from apscheduler.schedulers.background &lt;br /&gt;import BackgroundScheduler&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;import time&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;def job():&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp; print(&quot;APScheduler is working...&quot;)&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; scheduler = BackgroundScheduler()&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp; # 매 분마다 job 함수 실행&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; scheduler.add_job(job, 'interval', minutes=1)&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp; # 특정 날짜와 시간에 job 함수 실행&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; scheduler.add_job(job, 'date', run_date='2024-05-20 10:00:00')&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp; scheduler.start()&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; try:&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # 스케줄러가 실행되도록 유지&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; while True:&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; time.sleep(2)&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;except (KeyboardInterrupt, SystemExit):&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp;# 종료 시 스케줄러 정리&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;scheduler.shutdown()&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;APScheduler&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;는 백그라운드에서 작업을 실행하며, 다양한 트리거 옵션을 제공하여 보다 정교한 스케줄링을 가능하게 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;3. 실전 예제: 파일 백업 자동화&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;스케줄러를 사용하여 파일 백업을 자동화하는 예제를 살펴보겠습니다. 이 예제는 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;schedule&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 라이브러리를 사용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;import schedule&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;import time&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;import shutil&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;import os&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;# 백업할 폴더와 백업본을 저장할 폴더 지정&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;source_folder = &quot;/path/to/your/source/folder&quot;&amp;nbsp; &lt;br /&gt;# 백업할 폴더 경로&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;backup_folder = &quot;/path/to/your/backup/folder&quot;&amp;nbsp; &lt;br /&gt;# 백업본 저장 폴더 경로&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;def backup_files():&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp; &quot;&quot;&quot;파일 백업 함수&quot;&quot;&quot;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp; try:&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # 백업 폴더가 없으면 생성&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if not os.path.exists(backup_folder):&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; os.makedirs(backup_folder)&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # shutil.copytree()를 사용하여 폴더 복사 (덮어쓰기)&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; shutil.copytree(source_folder, os.path.join(backup_folder, &quot;backup_&quot; + time.strftime(&quot;%Y%m%d_%H%M%S&quot;)), dirs_exist_ok=True)&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; print(f&quot;백업 완료: {time.strftime('%Y-%m-%d %H:%M:%S')}&quot;)&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; except Exception as e:&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;print(f&quot;백업 중 오류 발생: {e}&quot;)&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp;# 매일 자정에 백업 실행&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;schedule.every().day.at(&quot;00:00&quot;).do(backup_files)&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp;while True:&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; schedule.run_pending()&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; time.sleep(60) # 1분마다 확인&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 코드는 매일 자정에 지정된 폴더의 내용을 백업 폴더로 복사합니다. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;shutil&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 라이브러리를 사용하여 폴더를 복사하고, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;time&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 라이브러리를 사용하여 백업 시간을 기록합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;4. 팁과 트릭&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;에러 처리:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 작업 실행 중 발생할 수 있는 예외 상황에 대비하여 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;try-except&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 블록을 사용하여 에러를 처리하세요.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로깅:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 작업의 성공 여부와 관련된 로그를 기록하여 문제 발생 시 디버깅을 용이하게 하세요.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;테스트:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 실제 환경에서 스케줄러를 실행하기 전에 테스트 환경에서 충분히 테스트하세요.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;환경 변수:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 민감한 정보(API 키, 데이터베이스 비밀번호 등)는 코드에 직접 하드코딩하지 말고 환경 변수를 사용하세요.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;5. 마무리&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파이썬 스케줄러를 사용하면 시스템 자동화의 세계로 한 발짝 더 다가갈 수 있습니다. 오늘 배운 내용을 바탕으로, 여러분의 프로젝트에 스케줄러를 적용하여 업무 효율성을 높여보세요! 마치 마법처럼, 여러분의 시스템이 알아서 척척 움직이는 모습을 보며 뿌듯함을 느낄 수 있을 겁니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/73</guid>
      <comments>https://techsuda.tistory.com/entry/Python-System%EC%97%90-%EB%B0%98%EB%B3%B5-%EB%B0%8F-%EC%98%88%EC%95%BD-%EC%8B%A4%ED%96%89-%EC%84%A4%EC%A0%95-Scheduler-1#entry73comment</comments>
      <pubDate>Wed, 2 Jul 2025 23:45:31 +0900</pubDate>
    </item>
    <item>
      <title>[Flutter] Dialog 에서 setState() 사용하기</title>
      <link>https://techsuda.tistory.com/entry/Flutter-Dialog-%EC%97%90%EC%84%9C-setState-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</link>
      <description>&lt;h1&gt;&lt;span style=&quot;color: #366091;&quot;&gt;Flutter 대화상자에서 setState() 사용하기&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c73Vl0/btsO2zFwZpR/aGbVNKgiXEyaqCIHULVFD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c73Vl0/btsO2zFwZpR/aGbVNKgiXEyaqCIHULVFD0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c73Vl0/btsO2zFwZpR/aGbVNKgiXEyaqCIHULVFD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc73Vl0%2FbtsO2zFwZpR%2FaGbVNKgiXEyaqCIHULVFD0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;318&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Flutter 개발을 하다 보면, 사용자 인터랙션에 따라 UI를 업데이트해야 하는 경우가 많습니다.&lt;br /&gt;이때 핵심적인 역할을 하는 것이 바로 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setState()&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 메서드입니다. &lt;br /&gt;특히 대화상자(Dialog) 내에서 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setState()&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를 어떻게 활용하는지, 그리고 그 과정에서 발생할 수 있는 문제점과 해결책을 살펴보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;1. &lt;/span&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;setState()&lt;/span&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;란 무엇인가?&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setState()&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;는 Flutter 위젯의 상태를 변경하고, 변경된 상태에 따라 UI를 다시 그리는(rebuild) 역할을 합니다. 즉, 위젯 내부의 데이터가 변경되었음을 Flutter 프레임워크에 알리는 역할을 수행합니다. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setState()&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;가 호출되면 Flutter는 해당 위젯과 하위 위젯들을 다시 빌드하여 UI를 업데이트합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;2. 대화상자(Dialog)와 &lt;/span&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;setState()&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Flutter에서 대화상자는 사용자에게 정보를 표시하거나, 사용자 입력을 받기 위해 사용됩니다. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;showDialog()&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 함수를 사용하여 대화상자를 표시하며, 대화상자 내에서 사용자의 상호작용(버튼 클릭, 텍스트 입력 등)에 따라 UI를 업데이트해야 할 경우가 발생합니다. 이때 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setState()&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를 사용하여 대화상자 내부의 위젯 상태를 변경하고 UI를 갱신합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;2.1. 간단한 예제: 카운터 대화상자&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다음은 대화상자 내에서 버튼 클릭 시 카운터를 증가시키는 간단한 예제입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;import 'package:flutter/material.dart';&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;void main() {&lt;br /&gt;&amp;nbsp; runApp(MyApp());&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;class MyApp extends StatelessWidget {&lt;br /&gt;&amp;nbsp; @override&lt;br /&gt;&amp;nbsp; Widget build(BuildContext context) {&lt;br /&gt;&amp;nbsp; &amp;nbsp; return MaterialApp(&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; title: 'Flutter Demo',&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; theme: ThemeData(&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; primarySwatch: Colors.blue,&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; ),&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; home: MyHomePage(title: 'Flutter Demo Home Page'),&lt;br /&gt;&amp;nbsp; &amp;nbsp; );&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;class MyHomePage extends StatefulWidget {&lt;br /&gt;&amp;nbsp; MyHomePage({Key? key, required this.title}) : super(key: key);&lt;br /&gt;&amp;nbsp; final String title;&lt;br /&gt;&amp;nbsp; @override&lt;br /&gt;&amp;nbsp; _MyHomePageState createState() =&amp;gt; _MyHomePageState();&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;class _MyHomePageState extends State {&lt;br /&gt;&amp;nbsp; int _counter = 0;&lt;br /&gt;&amp;nbsp; void _showCounterDialog(BuildContext context) {&lt;br /&gt;&amp;nbsp; &amp;nbsp; int dialogCounter = 0; // 대화상자 내부 카운터&lt;br /&gt;&amp;nbsp; &amp;nbsp; showDialog(&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; context: context,&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; builder: (BuildContext context) {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return AlertDialog(&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; title: Text(&quot;Counter Dialog&quot;),&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; content: StatefulBuilder( // StatefulBuilder를 사용하여 대화상자 내부에서 setState 사용&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; builder: (BuildContext context, StateSetter setState) {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return Column(&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mainAxisSize: MainAxisSize.min,&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; children: [&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Text('Counter: $dialogCounter'),&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ElevatedButton(&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; child: Text('Increment'),&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; onPressed: () {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; setState(() {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dialogCounter++;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; });&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; },&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ),&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ],&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; );&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; },&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ),&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; actions: [&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; TextButton(&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; child: Text(&quot;Close&quot;),&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; onPressed: () {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Navigator.of(context).pop();&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; },&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ),&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ],&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; );&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; },&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; );&lt;br /&gt;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; @override&lt;br /&gt;&amp;nbsp; Widget build(BuildContext context) {&lt;br /&gt;&amp;nbsp; &amp;nbsp; return Scaffold(&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; appBar: AppBar(&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; title: Text(widget.title),&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; ),&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; body: Center(&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; child: Column(&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mainAxisAlignment: MainAxisAlignment.center,&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; children: [&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Text(&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 'Main Counter: $_counter',&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ),&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ElevatedButton(&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; onPressed: () {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _showCounterDialog(context);&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; },&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; child: Text('Show Counter Dialog'),&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ),&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ],&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ),&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; ),&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; floatingActionButton: FloatingActionButton(&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; onPressed: () {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; setState(() {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _counter++;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; });&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; },&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; tooltip: 'Increment',&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; child: Icon(Icons.add),&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; ),&lt;br /&gt;&amp;nbsp; &amp;nbsp; );&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위 코드에서 중요한 부분은 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;StatefulBuilder&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 위젯입니다. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;StatefulBuilder&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를 사용하면 대화상자 내부에서 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setState()&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를 호출하여 UI를 업데이트할 수 있습니다. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;StatefulBuilder&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;는 자체적인 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;State&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를 관리하며, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setState()&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 호출 시 해당 부분만 다시 빌드합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dh6wZ4/btsO3fzwAdy/5HRINzw8R0tAiTTjElHQKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dh6wZ4/btsO3fzwAdy/5HRINzw8R0tAiTTjElHQKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dh6wZ4/btsO3fzwAdy/5HRINzw8R0tAiTTjElHQKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdh6wZ4%2FbtsO3fzwAdy%2F5HRINzw8R0tAiTTjElHQKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;318&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;3. &lt;/span&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;setState()&lt;/span&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt; 사용 시 주의사항&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setState()&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를 사용할 때 몇 가지 주의해야 할 사항이 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;상태 관리의 범위:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setState()&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;는 해당 위젯의 상태만 변경합니다. 다른 위젯의 상태를 변경하려면, 상태를 공유하거나(예: Provider, Riverpod), 콜백 함수를 통해 부모 위젯에 상태 변경을 알리고 부모 위젯에서 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setState()&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를 호출해야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;성능:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 과도한 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setState()&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 호출은 UI를 불필요하게 다시 그리게 하여 성능 저하를 유발할 수 있습니다. UI 업데이트가 필요한 부분에만 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setState()&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를 사용하도록 주의해야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;StatefulBuilder 사용:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 대화상자 내부에서 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setState()&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를 사용하려면 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;StatefulBuilder&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를 사용하는 것이 일반적입니다. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;StatefulBuilder&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;는 대화상자 내에서 독립적인 상태를 관리할 수 있게 해줍니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;팁:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 복잡한 상태 관리가 필요한 경우, Provider, Riverpod, BLoC/Cubit과 같은 상태 관리 라이브러리를 사용하는 것을 고려해 보세요. 이러한 라이브러리는 상태 관리의 효율성을 높이고, 코드의 유지보수성을 향상시킵니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;4. 결론&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Flutter에서 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setState()&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;는 UI 업데이트의 핵심이며, 대화상자 내에서도 중요한 역할을 합니다. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;StatefulBuilder&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를 사용하여 대화상자 내부의 상태를 관리하고, UI를 효과적으로 업데이트할 수 있습니다. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;setState()&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 사용 시 주의사항을 염두에 두고, 효율적이고 유지보수 가능한 코드를 작성하는 것이 중요합니다.&lt;/span&gt;&lt;/b&gt; &lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/72</guid>
      <comments>https://techsuda.tistory.com/entry/Flutter-Dialog-%EC%97%90%EC%84%9C-setState-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0#entry72comment</comments>
      <pubDate>Wed, 2 Jul 2025 23:25:27 +0900</pubDate>
    </item>
    <item>
      <title>[Docker / NginX] 하나의 Domain으로 여러 개의 웹사이트 운영</title>
      <link>https://techsuda.tistory.com/entry/Docker-NginX-%ED%95%98%EB%82%98%EC%9D%98-Domain%EC%9C%BC%EB%A1%9C-%EC%97%AC%EB%9F%AC-%EA%B0%9C%EC%9D%98-%EC%9B%B9%EC%82%AC%EC%9D%B4%ED%8A%B8-%EC%9A%B4%EC%98%81</link>
      <description>&lt;h1&gt;&lt;span style=&quot;color: #366091;&quot;&gt;Docker와 Nginx로 멀티 사이트 운영하기&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bA4zVo/btsO2qoui6m/eS2V7f3usnMHf1zaL8kCCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bA4zVo/btsO2qoui6m/eS2V7f3usnMHf1zaL8kCCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bA4zVo/btsO2qoui6m/eS2V7f3usnMHf1zaL8kCCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbA4zVo%2FbtsO2qoui6m%2FeS2V7f3usnMHf1zaL8kCCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;318&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여러 개의 웹사이트를 운영해야 하는데, 도메인은 하나만 가지고 있다면?&lt;br /&gt;걱정 마세요! Docker와 Nginx를 사용하면 하나의 도메인으로 여러 웹사이트를 효율적으로 운영할 수 있습니다.&lt;br /&gt;이 글에서는 Docker와 Nginx를 활용하여 멀티 사이트를 구축하는 방법을 자세히 알아보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;1. 왜 Docker와 Nginx를 사용해야 할까요?&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Docker와 Nginx는 멀티 사이트 운영에 최적화된 조합입니다. 각각의 장점을 살펴보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Docker:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 애플리케이션을 컨테이너로 격리하여 실행 환경을 일관성 있게 유지합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Nginx:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 고성능 웹 서버이자 리버스 프록시로, 트래픽을 효율적으로 분산하고 SSL/TLS 암호화를 처리합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Docker를 사용하면 각 웹사이트를 독립적인 컨테이너에서 실행할 수 있으며, Nginx는 이러한 컨테이너로 트래픽을 라우팅하여 하나의 도메인으로 여러 웹사이트를 서비스할 수 있도록 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;2. Docker 환경 설정&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;먼저 Docker 환경을 설정해야 합니다. Docker가 설치되어 있지 않다면, Docker 공식 웹사이트에서 설치 가이드를 참조하여 설치하세요.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;2.1. 웹사이트 컨테이너 생성 (예시: 두 개의 웹사이트)&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;각 웹사이트를 위한 Docker 컨테이너를 생성합니다. 여기서는 간단한 HTML 파일을 제공하는 두 개의 웹사이트를 예시로 사용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;웹사이트 1 (site1):&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;# site1/index.html&lt;br /&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;lt;html&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;head&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;title&amp;gt;Site 1&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/head&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;body&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;h1&amp;gt;Welcome to Site 1&amp;lt;/h1&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;웹사이트 2 (site2):&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;# site2/index.html&lt;br /&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;head&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;title&amp;gt;Site 2&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/head&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;body&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;h1&amp;gt;Welcome to Site 2&amp;lt;/h1&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;각 웹사이트의 Dockerfile을 작성합니다. 각 웹사이트의 루트 디렉토리에 Dockerfile을 생성합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;site1/Dockerfile:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;FROM nginx:latest&lt;br /&gt;COPY index.html /usr/share/nginx/html&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;site2/Dockerfile:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;FROM nginx:latest&lt;br /&gt;COPY index.html /usr/share/nginx/html&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;각 Dockerfile을 빌드하여 이미지를 생성합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker build -t site1 .&amp;nbsp; # site1 디렉토리에서 실행&lt;br /&gt;docker build -t site2 .&amp;nbsp; # site2 디렉토리에서 실행&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;생성된 이미지를 기반으로 컨테이너를 실행합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker run -d --name site1_container -p 8001:80 site1&lt;br /&gt;docker run -d --name site2_container -p 8002:80 site2&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;3. Nginx 설정: 리버스 프록시 및 가상 호스트&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Nginx 설정을 통해 각 웹사이트로 트래픽을 라우팅합니다. Nginx 컨테이너를 생성하고, 설정 파일을 작성합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;3.1. Nginx 컨테이너 생성&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Nginx 컨테이너를 위한 Dockerfile을 작성합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;# nginx/Dockerfile&lt;br /&gt;FROM nginx:latest&lt;br /&gt;COPY nginx.conf /etc/nginx/conf.d/default.conf&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Nginx 설정을 위한 파일을 생성합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;# nginx/nginx.conf&lt;br /&gt;server {&lt;br /&gt;&amp;nbsp; &amp;nbsp; listen 80;&lt;br /&gt;&amp;nbsp; &amp;nbsp; server_name yourdomain.com;&amp;nbsp; # 실제 도메인으로 변경&lt;br /&gt;&amp;nbsp; &amp;nbsp; location / {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; proxy_pass http://site1_container:80;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; proxy_set_header Host $host;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; proxy_set_header X-Real-IP $remote_addr;&lt;br /&gt;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;&amp;nbsp; &amp;nbsp; location /site2/ {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; proxy_pass http://site2_container:80;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; proxy_set_header Host $host;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; proxy_set_header X-Real-IP $remote_addr;&lt;br /&gt;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Dockerfile을 빌드하고 컨테이너를 실행합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker build -t nginx . # nginx 디렉토리에서 실행&lt;br /&gt;docker run -d --name nginx_container -p 80:80 --network host nginx&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위 설정에서 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;yourdomain.com&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;을 실제 도메인으로 변경하고, &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;/site2/&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;와 같은 경로를 사용하여 두 번째 웹사이트에 접근하도록 설정했습니다. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;proxy_pass&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;는 트래픽을 해당 컨테이너로 전달합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;4. DNS 설정&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;도메인 DNS 설정을 통해 Nginx 컨테이너의 IP 주소를 가리키도록 설정합니다. 도메인 등록 기관에서 A 레코드를 추가하여 Nginx 컨테이너가 실행되는 서버의 IP 주소를 지정합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;5. SSL/TLS 설정 (HTTPS)&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;보안을 위해 SSL/TLS를 설정하여 HTTPS를 사용합니다. Let's Encrypt와 같은 서비스를 사용하여 SSL 인증서를 발급받고, Nginx 설정에 추가합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Nginx 설정 (HTTPS):&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;server {&lt;br /&gt;&amp;nbsp; &amp;nbsp; listen 443 ssl;&lt;br /&gt;&amp;nbsp; &amp;nbsp; server_name yourdomain.com;&lt;br /&gt;&amp;nbsp; &amp;nbsp; ssl_certificate /etc/nginx/ssl/yourdomain.com.crt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; ssl_certificate_key /etc/nginx/ssl/yourdomain.com.key;&lt;br /&gt;&amp;nbsp; &amp;nbsp; location / {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; proxy_pass http://site1_container:80;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; proxy_set_header Host $host;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; proxy_set_header X-Real-IP $remote_addr;&lt;br /&gt;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;&amp;nbsp; &amp;nbsp; location /site2/ {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; proxy_pass http://site2_container:80;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; proxy_set_header Host $host;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; proxy_set_header X-Real-IP $remote_addr;&lt;br /&gt;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;6. 배포 및 관리 팁&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Docker Compose:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; Docker Compose를 사용하여 여러 컨테이너를 쉽게 관리하고 배포할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자동화:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; CI/CD 파이프라인을 구축하여 자동 배포를 구현합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;모니터링:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; Prometheus와 Grafana를 사용하여 컨테이너 및 서버의 성능을 모니터링합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로그 관리:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; ELK 스택(Elasticsearch, Logstash, Kibana) 또는 Fluentd를 사용하여 로그를 수집하고 분석합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;7. 결론&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Docker와 Nginx를 활용하면 하나의 도메인으로 여러 웹사이트를 효율적으로 운영할 수 있습니다.&lt;br /&gt;이 가이드를 통해 멀티 사이트 구축의 기본을 이해하고, 실제 환경에 적용해 보세요.&lt;br /&gt;Docker의 유연성과 Nginx의 강력한 성능을 통해 웹사이트 운영의 효율성을 높일 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/71</guid>
      <comments>https://techsuda.tistory.com/entry/Docker-NginX-%ED%95%98%EB%82%98%EC%9D%98-Domain%EC%9C%BC%EB%A1%9C-%EC%97%AC%EB%9F%AC-%EA%B0%9C%EC%9D%98-%EC%9B%B9%EC%82%AC%EC%9D%B4%ED%8A%B8-%EC%9A%B4%EC%98%81#entry71comment</comments>
      <pubDate>Wed, 2 Jul 2025 23:09:10 +0900</pubDate>
    </item>
    <item>
      <title>[AI] 속행이독 원행이중 (速行而獨 遠行而衆)</title>
      <link>https://techsuda.tistory.com/entry/AI-%EC%86%8D%ED%96%89%EC%9D%B4%EB%8F%85-%EC%9B%90%ED%96%89%EC%9D%B4%EC%A4%91-%E9%80%9F%E8%A1%8C%E8%80%8C%E7%8D%A8-%E9%81%A0%E8%A1%8C%E8%80%8C%E8%A1%86</link>
      <description>&lt;h1&gt;&lt;span style=&quot;color: #366091;&quot;&gt;AI 시대, 혼자서 빠르게, 함께 멀리&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BZ9M4/btsOUWPdZUu/6EhZp597dTzXeVYM5dCnnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BZ9M4/btsOUWPdZUu/6EhZp597dTzXeVYM5dCnnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BZ9M4/btsOUWPdZUu/6EhZp597dTzXeVYM5dCnnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBZ9M4%2FbtsOUWPdZUu%2F6EhZp597dTzXeVYM5dCnnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;318&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;速行而獨 遠行而衆&quot; 이라는 고사성어는 AI 시대를 살아가는 우리에게 시사하는 바가 큽니다. 빠르게 변화하는 기술의 흐름 속에서 개인의 역량 강화는 필수적이며, 동시에 더 큰 목표를 달성하기 위해서는 협력의 중요성을 잊지 말아야 합니다. AI 기술은 이러한 두 가지 측면을 모두 충족시키는 데 기여하고 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;1. 速行而獨: AI와 함께, 개인의 역량 극대화&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;AI 기술은 개인의 학습 속도를 획기적으로 높이고, 창의적인 아이디어를 발현하도록 돕습니다. &lt;br /&gt;마치 개인 비서처럼, AI는 방대한 정보를 빠르게 분석하고, 맞춤형 솔루션을 제시하며, 반복적인 작업을 자동화하여 개인의 시간을 절약해줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;맞춤형 학습:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;AI 기반의 교육 플랫폼은 개인의 학습 속도와 수준에 맞춰 최적화된 학습 콘텐츠를 제공합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;아이디어 발상:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;AI는 데이터 분석을 통해 새로운 트렌드를 파악하고, 창의적인 아이디어를 제시하는 데 도움을 줍니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자동화:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;반복적인 업무를 자동화하여, 핵심 업무에 집중할 수 있도록 돕습니다. 예를 들어, 챗봇을 활용한 고객 응대 자동화는 상담원의 업무 부담을 줄여줍니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;2. 遠行而衆: AI 기술, 협력의 새로운 지평을 열다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;AI 기술은 여러 사람이 함께 더 큰 목표를 달성할 수 있도록 돕습니다.&lt;br /&gt;AI는 방대한 데이터를 분석하고, 예측 모델을 구축하여, 의사 결정을 지원하고, 협업의 효율성을 높입니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데이터 분석 및 예측:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;AI는 복잡한 데이터를 분석하여, 미래를 예측하고, 전략 수립에 필요한 정보를 제공합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;의사 결정 지원:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;AI 기반의 의사 결정 시스템은 객관적인 데이터를 기반으로, 더 나은 결정을 내릴 수 있도록 돕습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;협업 효율성 증대:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;AI는 프로젝트 관리, 회의록 작성, 번역 등 다양한 방식으로 협업의 효율성을 높입니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예를 들어, 자율 주행 기술은 여러 대의 차량이 서로 정보를 공유하고, 협력하여 안전하고 효율적인 운송 시스템을 구축하는 데 기여합니다. 또한, AI 기반의 번역 시스템은 서로 다른 언어를 사용하는 사람들이 원활하게 소통할 수 있도록 돕습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PYfIR/btsOTPXwjvL/nbeAOm2dOkPSmHhHYL6ijk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PYfIR/btsOTPXwjvL/nbeAOm2dOkPSmHhHYL6ijk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PYfIR/btsOTPXwjvL/nbeAOm2dOkPSmHhHYL6ijk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPYfIR%2FbtsOTPXwjvL%2FnbeAOm2dOkPSmHhHYL6ijk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;318&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;3. AI 시대, 균형 잡힌 시각의 중요성&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;AI 기술은 강력한 도구이지만, 맹목적인 의존은 경계해야 합니다. AI의 장점을 최대한 활용하면서, 인간의 창의성과 판단력을 잃지 않도록 균형을 유지하는 것이 중요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;비판적 사고&lt;/b&gt;:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;AI가 제공하는 정보를 맹목적으로 수용하기보다는, 비판적인 시각으로 분석하고, 검증하는 자세가 필요&lt;/b&gt;&lt;/span&gt;합니다.&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;(개인적으로 가장 중요하게 생각하고 있습니다. AI에게 전적으로 의지하기 보다는 AI가 내게 맞추어 응답 하도록 프롬프트 엔지니어링에 많은 노력을 기울입니다. 의외로 대화형AI는 전체적으로 잘 하지만, 빈틈과 논리적오류도 무척 많습니다.)&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;윤리적 책임:&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;AI 기술의 개발과 활용에 있어서, 윤리적인 문제를 고려하고, 사회적 책임을 다해야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;지속적인 학습:&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;AI 기술은 끊임없이 발전하고 있습니다. 새로운 기술을 배우고, 적응하려는 노력이 필요합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;AI 시대에는 &quot;速行而獨&quot;과 &quot;遠行而衆&quot;의 균형을 이루는 것이 성공의 핵심입니다. &lt;br /&gt;개인의 역량을 끊임없이 발전시키면서, 협력을 통해 더 큰 목표를 달성하는 여정을 함께 걸어가야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7s8Ab/btsOUxa5ugj/CvoYMHgo93jGYvKNOGzDUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7s8Ab/btsOUxa5ugj/CvoYMHgo93jGYvKNOGzDUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7s8Ab/btsOUxa5ugj/CvoYMHgo93jGYvKNOGzDUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7s8Ab%2FbtsOUxa5ugj%2FCvoYMHgo93jGYvKNOGzDUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;318&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <category>AI</category>
      <category>chatGPT</category>
      <category>GEMINI</category>
      <category>대화형AI</category>
      <category>속행이독</category>
      <category>원행이중</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/70</guid>
      <comments>https://techsuda.tistory.com/entry/AI-%EC%86%8D%ED%96%89%EC%9D%B4%EB%8F%85-%EC%9B%90%ED%96%89%EC%9D%B4%EC%A4%91-%E9%80%9F%E8%A1%8C%E8%80%8C%E7%8D%A8-%E9%81%A0%E8%A1%8C%E8%80%8C%E8%A1%86#entry70comment</comments>
      <pubDate>Fri, 27 Jun 2025 21:27:31 +0900</pubDate>
    </item>
    <item>
      <title>[AI] 업무 자동화 툴 선택의 기준</title>
      <link>https://techsuda.tistory.com/entry/AI-%EC%97%85%EB%AC%B4-%EC%9E%90%EB%8F%99%ED%99%94-%ED%88%B4-%EC%84%A0%ED%83%9D%EC%9D%98-%EA%B8%B0%EC%A4%80</link>
      <description>&lt;h1&gt;&lt;span style=&quot;color: #366091;&quot;&gt;당신의 일상을 혁신할 마법의 지팡이를 찾아라!&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Kj9qA/btsOVJue9eW/IPL1GsS98C2q6Hl2hEmhZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Kj9qA/btsOVJue9eW/IPL1GsS98C2q6Hl2hEmhZ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Kj9qA/btsOVJue9eW/IPL1GsS98C2q6Hl2hEmhZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKj9qA%2FbtsOVJue9eW%2FIPL1GsS98C2q6Hl2hEmhZ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;318&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;혹시 이런 생각 해보신 적 있나요? &quot;아, 이 지루한 반복 업무, 좀 누가 대신 해줬으면 좋겠다!&quot;&lt;br /&gt;네, 당신의 간절한 바람을 현실로 만들어 줄 AI 업무 자동화 툴들이 드디어 등장했습니다! 마치 영화 속 마법처럼, 클릭 몇 번으로 뚝딱 업무를 처리해주는 놀라운 녀석들이죠. 하지만, 수많은 툴 중에서 과연 어떤 녀석이 내게 딱 맞는 '마법의 지팡이'일까요? 지금부터 저와 함께 업무 자동화 툴 선택의 기준을 꼼꼼히 파헤쳐 봅시다!&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;1. 업무 자동화 툴, 너, 정체가 뭐니?&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;업무 자동화 툴은 간단히 말해, 사람이 일일이 하던 반복적인 업무를 대신 처리해주는 똑똑한 소프트웨어입니다. 이메일 발송, 데이터 입력, 보고서 작성 등 지루하고 시간 잡아먹는 일들을 척척 해내죠. 덕분에 우리는 더 중요한 일에 집중할 수 있게 됩니다. 마치 시간 관리 마법사를 고용한 것과 같달까요?&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;2. 업무 자동화 툴, 종류별 특징 톺아보기&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자, 이제 본격적으로 다양한 업무 자동화 툴들을 살펴볼 시간입니다. 각 툴의 특징과 장단점을 꼼꼼히 비교해보고, 당신에게 맞는 '소울메이트'를 찾아보세요!&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;2.1. Make (구 Integromat)&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;간략 기능/특징:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다양한 앱과 서비스를 연결하여 복잡한 워크플로우를 쉽게 만들 수 있습니다. 시각적인 인터페이스를 통해 직관적으로 자동화 흐름을 설계할 수 있다는 것이 큰 장점입니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;장점:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 다양한 앱 연동: 1,000개 이상의 앱과 서비스를 지원하여 높은 확장성을 제공합니다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 시각적 워크플로우: 드래그 앤 드롭 방식으로 워크플로우를 쉽게 구축하고 관리할 수 있습니다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 유연성: 조건 분기, 반복 작업 등 복잡한 로직을 구현할 수 있습니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;단점:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;학습 곡선: 처음 사용하는 사용자에게는 다소 어려울 수 있습니다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 가격: 사용량에 따라 비용이 증가할 수 있습니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;비용:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;무료 플랜부터 시작하여 사용량에 따라 유료 플랜을 선택할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;2.2. n8n&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;간략 기능/특징:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;오픈 소스 기반의 강력한 자동화 툴로, 자체 호스팅이 가능하여 데이터 보안에 민감한 사용자에게 적합합니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;장점:&lt;br /&gt;- &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;오픈 소스: 자유로운 커스터마이징과 확장이 가능합니다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 자체 호스팅: 데이터 보안 및 개인 정보 보호에 유리합니다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 다양한 트리거 및 액션: 다양한 앱과 서비스를 연동할 수 있습니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;단점:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 기술적 지식 필요: 설치 및 관리에 기술적인 지식이 필요합니다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- UI: Make에 비해 UI가 직관적이지 않을 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;비용:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;오픈 소스이므로 기본적으로 무료이며, 자체 호스팅 비용만 발생합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;2.3. Zapier&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;간략 기능/특징:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;가장 널리 사용되는 자동화 툴 중 하나로, 사용하기 쉬운 인터페이스와 방대한 앱 연동을 지원합니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;장점:&lt;br /&gt;- &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용 편의성: 직관적인 인터페이스로 쉽게 자동화를 시작할 수 있습니다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 다양한 앱 연동: 5,000개 이상의 앱과 서비스를 지원합니다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 빠른 설정: 템플릿을 활용하여 빠르게 자동화를 구축할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;단점:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 제한적인 기능: Make나 n8n에 비해 복잡한 로직 구현에 제한이 있을 수 있습니다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 가격: 사용량에 따라 비용이 증가하며, 고급 기능은 유료 플랜에서만 제공됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;비용:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;무료 플랜부터 시작하여 사용량에 따라 유료 플랜을 선택할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;2.4. UiPath&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;간략 기능/특징:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;기업용 RPA (Robotic Process Automation) 솔루션으로, 복잡한 업무 프로세스를 자동화하는 데 특화되어 있습니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;장점:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 강력한 자동화 기능: 복잡한 업무 프로세스를 자동화할 수 있습니다.&lt;br /&gt;-&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;기업 환경에 적합: 대규모 조직에서 사용하기에 적합한 기능을 제공합니다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 확장성: 다양한 시스템과의 연동을 지원합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;단점:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 높은 비용: 다른 툴에 비해 비용이 비쌉니다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 복잡한 사용법: 전문적인 교육과 숙련된 사용자가 필요합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;비용:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;기업용 솔루션으로, 사용 규모에 따라 맞춤형 가격 정책이 적용됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;3. 툴 선택, 무엇을 고려해야 할까?&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자, 이제 각 툴의 특징을 꼼꼼히 살펴보았으니, 당신에게 맞는 툴을 선택하기 위한 핵심 기준들을 알아볼까요? 마치 맞춤형 마법 주문을 외우는 것처럼, 당신의 상황에 맞는 툴을 선택하는 것이 중요합니다!&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자동화할 업무의 종류와 규모:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;어떤 업무를 자동화할 것인지, 얼마나 많은 양의 데이터를 처리해야 하는지에 따라 적합한 툴이 달라집니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예산:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;툴의 가격, 유지보수 비용, 추가 기능 등을 고려하여 예산에 맞는 툴을 선택해야 합니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용 편의성:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;툴을 얼마나 쉽게 사용할 수 있는지, 사용법을 익히는 데 얼마나 시간이 걸리는지 등을 고려해야 합니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;확장성:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;툴이 얼마나 다양한 앱과 서비스를 지원하는지, 향후 확장 가능성은 얼마나 되는지 등을 고려해야 합니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;보안:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;데이터 보안이 중요한 경우, 자체 호스팅을 지원하는 툴이나 보안 기능이 강화된 툴을 선택해야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;4. 유지보수, 꼼꼼하게 챙기세요!&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자동화 툴은 한 번 설치하면 끝이 아닙니다. 지속적인 유지보수가 필요하죠. 마치 마법의 지팡이를 관리하는 것처럼 말이죠!&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;업데이트 관리:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;툴의 최신 버전을 유지하고, 보안 패치를 적용하여 안정성을 확보해야 합니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;모니터링:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;자동화 흐름이 제대로 작동하는지, 오류는 없는지 지속적으로 모니터링해야 합니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문제 해결:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;오류 발생 시 신속하게 문제를 해결하고, 필요한 경우 기술 지원을 받아야 합니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;변경 사항 관리:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;자동화된 업무 프로세스에 변경 사항이 발생하면, 툴 설정도 함께 업데이트해야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;5. 성공적인 업무 자동화를 위한 팁!&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자, 이제 마지막으로 성공적인 업무 자동화를 위한 팁을 알려드릴게요! 마치 마법 주문을 외우는 연습처럼, 꾸준히 노력하면 당신도 업무 자동화 전문가가 될 수 있습니다!&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;작은 것부터 시작:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;처음부터 너무 복잡한 자동화를 시도하지 말고, 간단한 업무부터 시작하여 점차 범위를 넓혀가세요.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자동화 목표 설정:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;자동화를 통해 무엇을 얻고 싶은지 명확한 목표를 설정하고, 목표 달성을 위한 지표를 측정하세요.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문서화:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;자동화 흐름을 문서화하여, 다른 사람들과 공유하고 유지보수를 용이하게 하세요.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;지속적인 학습:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;br /&gt;자동화 툴의 새로운 기능과 트렌드를 꾸준히 학습하고, 자동화 기술을 향상시키세요.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자, 어떠셨나요? &lt;br /&gt;이제 당신은 업무 자동화 툴 선택의 '마법사'가 될 준비가 되셨나요? &lt;br /&gt;오늘 알려드린 정보들을 바탕으로, 당신의 일상을 혁신할 최고의 '마법의 지팡이'를 찾아보세요!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbiKmT/btsOUC4yDcG/h6UXUdhFrojTbL0qUnMhfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbiKmT/btsOUC4yDcG/h6UXUdhFrojTbL0qUnMhfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbiKmT/btsOUC4yDcG/h6UXUdhFrojTbL0qUnMhfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbiKmT%2FbtsOUC4yDcG%2Fh6UXUdhFrojTbL0qUnMhfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;318&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <category>AI</category>
      <category>make</category>
      <category>n8n</category>
      <category>UiPath</category>
      <category>Zapier</category>
      <category>네이튼</category>
      <category>업무자동화</category>
      <category>자동화</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/69</guid>
      <comments>https://techsuda.tistory.com/entry/AI-%EC%97%85%EB%AC%B4-%EC%9E%90%EB%8F%99%ED%99%94-%ED%88%B4-%EC%84%A0%ED%83%9D%EC%9D%98-%EA%B8%B0%EC%A4%80#entry69comment</comments>
      <pubDate>Fri, 27 Jun 2025 16:36:06 +0900</pubDate>
    </item>
    <item>
      <title>[AI] 프롬프트 엔지니어링</title>
      <link>https://techsuda.tistory.com/entry/AI-%ED%94%84%EB%A1%AC%ED%94%84%ED%8A%B8-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4%EB%A7%81</link>
      <description>&lt;h1&gt;&lt;span style=&quot;color: #366091;&quot;&gt;AI 시대의 핵심 기술: 프롬프트 엔지니어링 간략 소개&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mFYl3/btsOVDt1f7D/pdANH0OzVvPtkKxNk9qBP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mFYl3/btsOVDt1f7D/pdANH0OzVvPtkKxNk9qBP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mFYl3/btsOVDt1f7D/pdANH0OzVvPtkKxNk9qBP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmFYl3%2FbtsOVDt1f7D%2FpdANH0OzVvPtkKxNk9qBP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;557&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;안녕하세요! 오늘은 인공지능(AI) 시대를 살아가는 우리에게 필수적인 기술, 프롬프트 엔지니어링에 대해 알아보겠습니다. 마치 요리의 레시피처럼, AI에게 원하는 결과를 얻기 위한 효과적인 '요청'을 만드는 기술이죠. 이 글에서는 프롬프트 엔지니어링에 대한 간략한 소개의 내용을 담아 봤습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;1. 프롬프트 엔지니어링이란 무엇인가?&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프롬프트 엔지니어링은 AI 모델, 특히 대규모 언어 모델(LLM)에게 특정 작업을 수행하도록 지시하는 기술입니다. 쉽게 말해, AI와 효과적으로 소통하는 방법이죠. 마치 친구에게 부탁을 할 때, &quot;야, 이것 좀 들어줘.&quot;라고 하는 것보다 &quot;내가 양손에 짐이 많아서 그런데, 이것 좀 나눠서 들어줄 수 있을까?&quot;라고 하는 것이 더 좋은 결과를 얻을 수 있는 것과 같은 이치입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JxYCn/btsOUtsWtKL/p1POCKcrKmjeTDm52oakw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JxYCn/btsOUtsWtKL/p1POCKcrKmjeTDm52oakw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JxYCn/btsOUtsWtKL/p1POCKcrKmjeTDm52oakw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJxYCn%2FbtsOUtsWtKL%2Fp1POCKcrKmjeTDm52oakw0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;557&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프롬프트 엔지니어링은 단순히 질문을 던지는 것을 넘어, AI가 원하는 정보를 정확하게 이해하고, 적절한 형식으로 응답하도록 유도하는 일련의 기술을 포함합니다. 이는 AI 모델의 성능을 극대화하고, 우리가 원하는 결과를 얻는 데 결정적인 역할을 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;2. 프롬프트 엔지니어링의 중요성&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;AI 모델은 훌륭한 도구이지만, 제대로 사용하지 않으면 무용지물입니다. 프롬프트 엔지니어링은 AI 모델의 잠재력을 최대한 활용하기 위한 핵심 기술입니다. 다음은 프롬프트 엔지니어링이 중요한 몇 가지 이유입니다:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;정확성 향상:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 효과적인 프롬프트는 AI가 더 정확하고 관련성 높은 정보를 제공하도록 돕습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;창의성 증대:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 창의적인 프롬프트를 통해 AI가 새로운 아이디어를 생성하고, 다양한 관점을 제시하도록 유도할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;생산성 향상:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 잘 만들어진 프롬프트는 반복적인 작업을 자동화하고, 시간과 노력을 절약해 줍니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;맞춤형 결과:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 특정 요구 사항에 맞는 맞춤형 결과를 얻을 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;3. 프롬프트 엔지니어링의 기본 원리&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프롬프트 엔지니어링은 몇 가지 기본 원리를 따릅니다. 이를 통해 AI 모델과의 효과적인 소통을 위한 기반을 다질 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;명확성:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 질문이나 지시 사항은 최대한 명확하고 구체적이어야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구체성:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 원하는 결과의 형식, 길이, 스타일 등을 명시합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문맥 제공:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; AI 모델이 작업에 필요한 배경 정보를 제공합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;제한 설정:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; AI 모델이 특정 주제나 형식에 집중하도록 제한을 설정합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;4. 실전 프롬프트 엔지니어링 팁&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이제 실전에서 사용할 수 있는 프롬프트 엔지니어링 팁을 살펴보겠습니다. 이러한 팁들을 활용하면 AI 모델과의 소통 능력을 향상시킬 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;4.1. 역할 부여 (Role-Playing)&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;AI에게 특정 역할을 부여하여, 해당 역할에 맞는 답변을 생성하도록 유도합니다. 예를 들어, &quot;당신은 뛰어난 마케팅 전문가입니다. 다음 제품에 대한 5가지 마케팅 아이디어를 제안해 주세요.&quot;와 같이 프롬프트를 구성할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCbPPo/btsOUsHzY9s/tkjRve1XtkkRvBdKV7BZj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCbPPo/btsOUsHzY9s/tkjRve1XtkkRvBdKV7BZj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCbPPo/btsOUsHzY9s/tkjRve1XtkkRvBdKV7BZj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCbPPo%2FbtsOUsHzY9s%2FtkjRve1XtkkRvBdKV7BZj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;557&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;4.2. 예시 제공 (Few-Shot Learning)&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;AI 모델에게 원하는 결과의 예시를 제공하여, 모델이 원하는 형식을 학습하도록 돕습니다. 예를 들어, &quot;다음 문장의 감정을 분석하고, 긍정/부정/중립으로 분류하세요. 예시: '오늘 날씨가 맑다.' - 긍정&quot;과 같이 프롬프트를 구성할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;4.3. 단계별 지시 (Step-by-Step Instructions)&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;복잡한 작업을 여러 단계로 나누어, 각 단계별로 AI에게 지시합니다. 이렇게 하면 AI가 작업을 더 정확하게 수행할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;4.4. 제한 설정 (Constraints)&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;AI 모델의 응답에 대한 제한을 설정하여, 원하는 결과의 범위를 좁힙니다. 예를 들어, &quot;50단어 이내로 요약해 주세요.&quot;와 같이 프롬프트를 구성할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;4.5. 긍정적/부정적 프롬프트 (Positive/Negative Prompting)&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;원하는 것을 명시하는 긍정적 프롬프트와, 원하지 않는 것을 명시하는 부정적 프롬프트를 함께 사용하여, 더욱 정확한 결과를 얻을 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;5. 프롬프트 엔지니어링의 최신 동향&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프롬프트 엔지니어링은 끊임없이 발전하고 있습니다. 최근에는 다음과 같은 트렌드가 주목받고 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자동 프롬프트 생성:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; AI 모델이 스스로 프롬프트를 생성하는 기술&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;멀티모달 프롬프트:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 텍스트, 이미지, 음성 등 다양한 형태의 입력을 활용하는 프롬프트&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프롬프트 최적화 도구:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 프롬프트의 성능을 향상시키는 데 도움을 주는 도구&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;6. 프롬프트 엔지니어링 적용 사례&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프롬프트 엔지니어링은 다양한 분야에서 활용되고 있습니다. 다음은 몇 가지 적용 사례입니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;콘텐츠 제작:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 블로그 게시물, 소셜 미디어 콘텐츠, 마케팅 카피 생성&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데이터 분석:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 데이터 요약, 인사이트 도출, 시각화&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;고객 서비스:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 챗봇, FAQ 자동 응답&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;소프트웨어 개발:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 코드 생성, 버그 수정, 문서 자동화&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;7. 결론&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프롬프트 엔지니어링은 AI 시대를 살아가는 우리에게 필수적인 기술입니다. 이 글을 통해 프롬프트 엔지니어링의 기본 원리와 실전 팁을 익히고, AI 모델과의 소통 능력을 향상시키세요. 앞으로 프롬프트 엔지니어링은 더욱 발전하여, 우리의 삶과 일에 더 많은 영향을 미칠 것입니다. 끊임없이 배우고, 실험하고, AI와 함께 성장하는 여정을 즐기세요!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;궁금한 점이나 더 알고 싶은 내용이 있다면 언제든지 댓글로 질문해주세요!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/68</guid>
      <comments>https://techsuda.tistory.com/entry/AI-%ED%94%84%EB%A1%AC%ED%94%84%ED%8A%B8-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4%EB%A7%81#entry68comment</comments>
      <pubDate>Fri, 27 Jun 2025 15:07:33 +0900</pubDate>
    </item>
    <item>
      <title>[THINK] 바이브 코딩</title>
      <link>https://techsuda.tistory.com/entry/THINK-%EB%B0%94%EC%9D%B4%EB%B8%8C-%EC%BD%94%EB%94%A9</link>
      <description>&lt;h1&gt;&lt;span style=&quot;color: #366091;&quot;&gt;바이브 코딩 - 당신의 코딩, 바이브를 입다&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;코딩, 마치 낯선 춤과 같다고요? 복잡한 문법과 오류의 늪에 빠져 허우적거린 경험, 누구나 한 번쯤은 있을 겁니다. 하지만 걱정 마세요! 오늘 우리는 코딩에 '바이브'를 더해, 마치 좋아하는 음악을 듣는 것처럼 즐겁게 코딩하는 방법을 찾아볼 겁니다.&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;바이브 코딩은 단순히 코드를 작성하는 것을 넘어, 개발자의 '바이브(Vibe)' 즉, 개인적인 경험, 감성, 그리고 창의성을 코드에 녹여내는 접근 방식을 의미합니다. 이는 단순히 기술적인 측면뿐만 아니라, 개발자의 개성과 철학을 반영하여 더욱 풍부하고 매력적인 소프트웨어를 만드는 데 기여합니다.&lt;/span&gt;&lt;/b&gt; &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;딱딱한 코딩 세상에 생기를 불어넣어, 당신의 코딩 여정을 더욱 특별하게 만들어 보세요!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bE7gkF/btsOUqJI73M/jZ9IxOkJe5KZtt1kClp730/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bE7gkF/btsOUqJI73M/jZ9IxOkJe5KZtt1kClp730/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bE7gkF/btsOUqJI73M/jZ9IxOkJe5KZtt1kClp730/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbE7gkF%2FbtsOUqJI73M%2FjZ9IxOkJe5KZtt1kClp730%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;318&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;1. 코딩, 왜 이렇게 어려울까?&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;코딩이 어렵게 느껴지는 이유는 여러 가지가 있습니다. 마치 외국어를 배우는 것처럼, 생소한 문법과 용어에 압도당할 수 있습니다. 또한, 끊임없이 발생하는 오류는 마치 미로 속을 헤매는 듯한 좌절감을 안겨주죠. 하지만, 코딩의 본질은 문제 해결 능력과 창의력을 발휘하는 즐거움에 있다는 것을 기억하세요.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;2. 바이브를 입은 코딩, 어떻게 가능할까?&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자, 이제 코딩에 '바이브'를 더하는 방법을 알아봅시다. 마치 좋아하는 음악을 들을 때처럼, 코딩도 즐거움으로 가득 채울 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자신만의 스타일을 찾아라:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 좋아하는 음악 장르가 있듯이, 코딩에도 자신에게 맞는 스타일이 있습니다. 파이썬의 간결함, 자바스크립트의 동적인 매력 등, 다양한 언어를 경험하며 자신에게 맞는 스타일을 찾아보세요.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;작은 목표부터 시작하라:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 거대한 프로젝트에 압도되지 않도록, 작은 목표를 설정하고 하나씩 달성해 나가는 즐거움을 느껴보세요. &quot;Hello, world!&quot;를 출력하는 것부터 시작해도 괜찮습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;커뮤니티와 함께하라:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 혼자서 모든 것을 해결하려 하지 마세요. 온라인 커뮤니티, 스터디 그룹을 통해 질문하고, 배우고, 함께 성장하는 즐거움을 만끽하세요.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;끊임없이 배우고 시도하라:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 코딩은 끊임없이 변화하는 분야입니다. 새로운 기술을 배우고, 다양한 프로젝트에 도전하며, 자신만의 코딩 바이브를 만들어가세요.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;3. 바이브 코딩, 실전 팁&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자, 이제 실전 팁을 통해 코딩에 바이브를 더해봅시다!&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;3.1. 나만의 개발 환경 구축&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자신에게 맞는 개발 환경을 구축하는 것은 매우 중요합니다. 마치 편안한 의자와 좋은 조명이 작업 효율을 높이는 것처럼, 자신에게 맞는 에디터, 테마, 단축키 등을 설정하여 코딩 환경을 최적화하세요.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kylJb/btsOVeOP3hA/0QP10sdZTXkSKlJVXDcsp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kylJb/btsOVeOP3hA/0QP10sdZTXkSKlJVXDcsp0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kylJb/btsOVeOP3hA/0QP10sdZTXkSKlJVXDcsp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkylJb%2FbtsOVeOP3hA%2F0QP10sdZTXkSKlJVXDcsp0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;318&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;3.2. 코드 스타일 가이드 준수&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;코드 스타일 가이드를 준수하여 코드를 깔끔하고 가독성 있게 작성하세요. 마치 악보를 보듯이, 다른 사람이 쉽게 이해할 수 있는 코드를 작성하는 것은 협업과 유지보수에 매우 중요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;# 파이썬 코드 예시&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; def calculate_sum(a, b):&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;&quot;&quot;두 숫자의 합을 계산하는 함수&quot;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; result = a + b&amp;nbsp; # a와 b를 더하여 result에 저장&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return result&amp;nbsp; &amp;nbsp; # result 반환&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # 함수 호출 및 결과 출력&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; num1 = 5&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; num2 = 3&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; sum_result = calculate_sum(num1, num2)&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; print(f&quot;The sum of {num1} and {num2} is: {sum_result}&quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;코드 설명:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;def calculate_sum(a, b):&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: 두 개의 인자를 받는 함수를 정의합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;&quot;&quot;두 숫자의 합을 계산하는 함수&quot;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: 함수의 기능을 설명하는 docstring입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;result = a + b&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: 두 인자의 합을 계산하여 result 변수에 저장합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;return result&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: 계산된 합을 반환합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;print(f&quot;The sum of {num1} and {num2} is: {sum_result}&quot;)&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: 결과를 출력합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;3.3. 즐거운 코딩을 위한 팁&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;오류를 두려워하지 마세요:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 오류는 학습의 기회입니다. 오류 메시지를 꼼꼼히 읽고, 문제 해결 과정을 즐기세요.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다양한 프로젝트에 도전하세요:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 웹 개발, 게임 개발, 데이터 분석 등, 다양한 분야의 프로젝트에 도전하며 코딩 실력을 향상시키세요.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;꾸준히 연습하세요:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 코딩은 꾸준한 연습이 중요합니다. 매일 조금씩이라도 코딩하는 습관을 들이세요.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kPbLW/btsOUHdnO2o/RxfgrjIFb1fdqAUtrgxfW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kPbLW/btsOUHdnO2o/RxfgrjIFb1fdqAUtrgxfW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kPbLW/btsOUHdnO2o/RxfgrjIFb1fdqAUtrgxfW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkPbLW%2FbtsOUHdnO2o%2FRxfgrjIFb1fdqAUtrgxfW0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;318&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;4. 마치며&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;코딩, 이제 더 이상 어렵고 지루한 숙제가 아닙니다. 자신만의 바이브를 찾아, 코딩을 즐거운 놀이로 만들어 보세요! 끊임없이 배우고, 시도하고, 즐기면서, 당신만의 특별한 코딩 세계를 만들어가시길 바랍니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/67</guid>
      <comments>https://techsuda.tistory.com/entry/THINK-%EB%B0%94%EC%9D%B4%EB%B8%8C-%EC%BD%94%EB%94%A9#entry67comment</comments>
      <pubDate>Fri, 27 Jun 2025 14:56:33 +0900</pubDate>
    </item>
    <item>
      <title>구독 플랫폼이 뭐야?</title>
      <link>https://techsuda.tistory.com/entry/%EA%B5%AC%EB%8F%85-%ED%94%8C%EB%9E%AB%ED%8F%BC%EC%9D%B4-%EB%AD%90%EC%95%BC</link>
      <description>&lt;h1&gt;&lt;span style=&quot;color: #366091;&quot;&gt;구독 플랫폼, 당신의 삶을 윤택하게 하는 마법의 열쇠&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구독 경제 시대, 우리는 매달, 매주, 혹은 매일같이 새로운 구독 서비스를 접하며 살아가고 있습니다. 음악 스트리밍, 영화, 소프트웨어, 심지어는 식료품까지! 이 모든 것이 구독이라는 마법의 열쇠로 연결되어 있습니다. 오늘은 이 매력적인 구독 플랫폼의 세계를 탐험하며, 당신의 삶을 더욱 풍요롭게 만들 수 있는 방법을 찾아보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IrdAQ/btsOT92rYls/lbL1R1KC5MJKhq78eSt5pk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IrdAQ/btsOT92rYls/lbL1R1KC5MJKhq78eSt5pk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IrdAQ/btsOT92rYls/lbL1R1KC5MJKhq78eSt5pk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIrdAQ%2FbtsOT92rYls%2FlbL1R1KC5MJKhq78eSt5pk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;318&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;구독 경제란 무엇인가?&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구독 경제는 제품이나 서비스를 소유하는 대신, 일정 기간 동안 사용 권한을 얻기 위해 비용을 지불하는 경제 모델입니다. 이 모델은 소비자에게 유연성과 접근성을 제공하며, 기업에게는 안정적인 수익을 보장합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;구독 플랫폼의 장점&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;편리함:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 원하는 서비스를 언제 어디서든 이용할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;유연성:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 필요에 따라 구독을 변경하거나 취소할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;비용 효율성:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 장기적으로 볼 때 소유하는 것보다 저렴할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;구독 플랫폼의 다양한 예시&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구독 플랫폼은 정말 다양한 형태로 존재합니다. 다음은 몇 가지 예시입니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;OTT 서비스:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 넷플릭스, 디즈니+, 왓챠 등&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;음악 스트리밍:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; Spotify, Apple Music, Melon 등&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;소프트웨어:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; Adobe Creative Cloud, Microsoft 365 등&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;식료품:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 밀키트, 커피, 간식 등&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;멤버십 서비스:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 쿠팡 로켓와우, Amazon Prime 등&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;구독 플랫폼 성공 전략&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구독 플랫폼을 성공적으로 운영하기 위한 몇 가지 핵심 전략을 소개합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li style=&quot;list-style-type: decimal; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;고객 중심의 서비스:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 고객의 니즈를 파악하고, 그에 맞는 서비스를 제공해야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;맞춤형 경험:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 개인화된 추천, 맞춤형 콘텐츠 제공을 통해 고객 만족도를 높입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;지속적인 가치 제공:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 고객이 구독을 유지하도록 끊임없이 새로운 가치를 창출해야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sWZkN/btsOUraJSwO/64hgGq9U9spOZnMEoQDpC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sWZkN/btsOUraJSwO/64hgGq9U9spOZnMEoQDpC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sWZkN/btsOUraJSwO/64hgGq9U9spOZnMEoQDpC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsWZkN%2FbtsOUraJSwO%2F64hgGq9U9spOZnMEoQDpC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;318&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;구독 플랫폼의 미래&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구독 경제는 앞으로 더욱 성장할 것입니다. 인공지능, 빅데이터 기술과 결합하여 더욱 개인화되고, 예측 가능한 서비스를 제공할 것입니다. 또한, 구독 모델은 새로운 산업 분야로 확장될 것이며, 우리 삶의 다양한 측면에 영향을 미칠 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #4f81bd;&quot;&gt;구독 플랫폼, 당신의 삶을 디자인하세요&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구독 플랫폼은 단순히 서비스를 이용하는 것을 넘어, 당신의 삶을 더욱 편리하고 풍요롭게 만들어주는 도구입니다. 자신에게 맞는 구독 서비스를 선택하고, 구독 경제의 혜택을 누려보세요! 구독은 이제 선택이 아닌 필수적인 삶의 일부가 될 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Life Story</category>
      <category>구독</category>
      <category>구독경제</category>
      <category>구독플랫폼</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/66</guid>
      <comments>https://techsuda.tistory.com/entry/%EA%B5%AC%EB%8F%85-%ED%94%8C%EB%9E%AB%ED%8F%BC%EC%9D%B4-%EB%AD%90%EC%95%BC#entry66comment</comments>
      <pubDate>Fri, 27 Jun 2025 14:52:33 +0900</pubDate>
    </item>
    <item>
      <title>[GITHUB / VSCode] 개발 중간에 github 에 올리기</title>
      <link>https://techsuda.tistory.com/entry/GITHUB-VSCode-%EA%B0%9C%EB%B0%9C-%EC%A4%91%EA%B0%84%EC%97%90-github-%EC%97%90-%EC%98%AC%EB%A6%AC%EA%B8%B0</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1055&quot; data-origin-height=&quot;703&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WABnN/btsOrC4mddK/wJgtZ6ppSdcHJrXaKMgen0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WABnN/btsOrC4mddK/wJgtZ6ppSdcHJrXaKMgen0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WABnN/btsOrC4mddK/wJgtZ6ppSdcHJrXaKMgen0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWABnN%2FbtsOrC4mddK%2FwJgtZ6ppSdcHJrXaKMgen0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1055&quot; height=&quot;703&quot; data-origin-width=&quot;1055&quot; data-origin-height=&quot;703&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;급하게 시작하다 보면 꼭 중간에 git 등록 하지 않았던게 영 찜찜 할때가 있다. 중간에라도 등록할라 치면 이미지처럼 복잡하기만 하고...&lt;br /&gt;겁먹지 말고 원격지 백업은 항상 신경쓰고, 반드시 백업해주자.&lt;br /&gt;왼쪽의 변경 사항은 거의 대부분이 Flutter framework (외부패키지) 관련 커밋들이다.&lt;br /&gt;VSCode에서 &lt;b&gt;프로젝트 루트&lt;/b&gt;가 아닌, Flutter SDK나 workspace 전체를 저장소로 인식할 때 이런 현상이 자주 발생하고,&lt;br /&gt;외부 의존성 (ex: .pub-cache,&amp;nbsp; .dart_tool 등)이 git 관리 대상에 포함되어 있을 경우 위와 같이 git 추적 목록이 과도하게 많아질 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;일단, 정리를 하려면 다음과 같이 진행해 보기 바란다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;-&amp;nbsp; 올바른 프로젝트 폴더에서 git init 수행 : Flutter project Root (pubspec.yaml 파일이 있는 폴더)에서 git 사용&lt;br /&gt;-&amp;nbsp; 외부파일 / 폴더 git 관리대상에서 제외하기 ( &lt;b&gt;.gitignore&lt;/b&gt; )&lt;br /&gt;&amp;nbsp; &amp;nbsp;.&amp;nbsp; .pub-cache/, .dart_tool/, build/ 등은 &lt;b&gt;.gitignore&lt;/b&gt;에 반드시 포함시켜 준다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(이미 git 에 등록된 외부 폴더는 삭제 후 재추가가 필요할 수 있다)&lt;br /&gt;-&amp;nbsp; 올바른 저장소 상태 확인&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;598&quot; data-origin-height=&quot;107&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l6vGd/btsOrvxJCTD/wduMvBAwCUbOR9Xq61GJBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l6vGd/btsOrvxJCTD/wduMvBAwCUbOR9Xq61GJBK/img.png&quot; data-alt=&quot;--&amp;amp;gt; 내 프로젝트의 파일만 나와야 정상 (외부 프레임워크 파일이 뜨면 저장소 위치 다시 확인)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l6vGd/btsOrvxJCTD/wduMvBAwCUbOR9Xq61GJBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl6vGd%2FbtsOrvxJCTD%2FwduMvBAwCUbOR9Xq61GJBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;598&quot; height=&quot;107&quot; data-origin-width=&quot;598&quot; data-origin-height=&quot;107&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;--&amp;gt; 내 프로젝트의 파일만 나와야 정상 (외부 프레임워크 파일이 뜨면 저장소 위치 다시 확인)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;-&amp;nbsp; Flutter SDK 저장소와 분리 : Flutter SDK (프레임워크) 폴더에서는 절대 git 작업을 하지 말고, 앱 프로젝트 루트 폴더에서만 git 작업 진행&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;1. 기존 .git 폴더 삭제 (Windows 기준)&lt;/b&gt;&lt;br /&gt;Powershell 명령어 : Remove-Item -Recurse -Force .git&lt;br /&gt;명령프롬프트(cmd) : rmdir /s /q .git&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IvjcQ/btsOqgH1xjC/4wVasUL96CYUJPMEqOid71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IvjcQ/btsOqgH1xjC/4wVasUL96CYUJPMEqOid71/img.png&quot; data-origin-width=&quot;292&quot; data-origin-height=&quot;107&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;49.27&quot; style=&quot;width: 48.6999%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IvjcQ/btsOqgH1xjC/4wVasUL96CYUJPMEqOid71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIvjcQ%2FbtsOqgH1xjC%2F4wVasUL96CYUJPMEqOid71%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;292&quot; height=&quot;107&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dMfZ1J/btsOqQWnXgL/mDgtipxskt547F3UlWEES0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dMfZ1J/btsOqQWnXgL/mDgtipxskt547F3UlWEES0/img.png&quot; data-origin-width=&quot;295&quot; data-origin-height=&quot;105&quot; data-is-animation=&quot;false&quot; style=&quot;width: 50.1373%;&quot; data-widthpercent=&quot;50.73&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dMfZ1J/btsOqQWnXgL/mDgtipxskt547F3UlWEES0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdMfZ1J%2FbtsOqQWnXgL%2FmDgtipxskt547F3UlWEES0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;295&quot; height=&quot;105&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;2. 새로운 git 저장소 초기화 및 첫 커밋&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock floatLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;268&quot; data-origin-height=&quot;118&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EReEW/btsOqd5AgdH/Cff6jHQySklNiY7VR0hUj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EReEW/btsOqd5AgdH/Cff6jHQySklNiY7VR0hUj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EReEW/btsOqd5AgdH/Cff6jHQySklNiY7VR0hUj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEReEW%2FbtsOqd5AgdH%2FCff6jHQySklNiY7VR0hUj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;256&quot; height=&quot;118&quot; data-origin-width=&quot;268&quot; data-origin-height=&quot;118&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; -&amp;nbsp; git init&lt;br /&gt;&amp;nbsp; -&amp;nbsp; git add .&lt;br /&gt;&amp;nbsp; -&amp;nbsp; git commit -m &quot;Initial commit&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;3. 원격 저장소 연결&lt;/b&gt;&lt;br /&gt;&amp;nbsp; -&amp;nbsp; git remote add origin &amp;lt;원격저장소주소&amp;gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;4. main branch 이름 통일 &lt;/b&gt;(GitHub에서는 기본 브랜치가 main 임. 내 로컬 브랜치도 main인지 반드시 확인 후, 아니라면 이름 변경)&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&amp;nbsp; -&amp;nbsp; git branch -M main&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;5. 최초 Push (원격지에 올리기)&lt;br /&gt;&lt;/b&gt;&amp;nbsp; -&amp;nbsp; git&amp;nbsp;push&amp;nbsp;-u&amp;nbsp;origin&amp;nbsp;main&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &lt;span style=&quot;color: #006dd7;&quot;&gt;-u 옵션: 이후 git push만으로도 자동으로 main 브랜치가 연동됨 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;6. VSCode 종료 후 재 실행&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1377&quot; data-origin-height=&quot;255&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpRKdl/btsOra8DFBx/STq6ojNWJysTVeaskfxJl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpRKdl/btsOra8DFBx/STq6ojNWJysTVeaskfxJl0/img.png&quot; data-alt=&quot;깔끔하게 내 프로젝트만 보여지고 있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpRKdl/btsOra8DFBx/STq6ojNWJysTVeaskfxJl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpRKdl%2FbtsOra8DFBx%2FSTq6ojNWJysTVeaskfxJl0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1377&quot; height=&quot;255&quot; data-origin-width=&quot;1377&quot; data-origin-height=&quot;255&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;깔끔하게 내 프로젝트만 보여지고 있다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <category>Branch</category>
      <category>commit</category>
      <category>Flutter</category>
      <category>Git</category>
      <category>GitHub</category>
      <category>gitignore</category>
      <category>origin</category>
      <category>push</category>
      <category>VSCode</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/65</guid>
      <comments>https://techsuda.tistory.com/entry/GITHUB-VSCode-%EA%B0%9C%EB%B0%9C-%EC%A4%91%EA%B0%84%EC%97%90-github-%EC%97%90-%EC%98%AC%EB%A6%AC%EA%B8%B0#entry65comment</comments>
      <pubDate>Thu, 5 Jun 2025 22:45:29 +0900</pubDate>
    </item>
    <item>
      <title>바퀴는 다시 발명하지 말라</title>
      <link>https://techsuda.tistory.com/entry/%EB%B0%94%ED%80%B4%EB%A5%BC-%EB%8B%A4%EC%8B%9C-%EB%B0%9C%EB%AA%85%ED%95%98%EC%A7%80-%EB%A7%90%EB%9D%BC</link>
      <description>&lt;head&gt;&lt;script async src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-6283204784895770&quot;
     crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;&lt;/head&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;바퀴는 이미 완벽하다: 괜히 다시 발명하지 마세요!&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;바퀴는 다시 발명할 필요가 없다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이미 완벽한 것을 개선하려 애쓰기보다는, 그 기반 위에 새로운 혁신을 쌓아 올리세요!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;오래되었지만, 여전히 강력한 발명품: 바퀴&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여러분, 주변을 한번 둘러보세요. 자동차, 자전거, 쇼핑 카트, 심지어 여러분의 사무실 의자까지! 굴러가는 모든 것들의 핵심에는 바로 '바퀴'가 있습니다. 인류 역사상 가장 위대한 발명 중 하나로 꼽히는 이 단순한 원형 물체는 수천 년 동안 우리의 삶을 편리하게 만들어 왔습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그런데 가끔 이런 생각을 해봅니다. 우리는 왜 이미 완벽에 가까운 이 발명품을 굳이 다시 '발명'하려고 할까요? 마치 매번 집을 지을 때마다 벽돌을 새로 만들려고 하는 것과 같습니다. 효율적이지 못할뿐더러, 시간과 노력을 불필요하게 낭비하는 일입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;'다시 발명하지 말라'는 개발 철학&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;소프트웨어 개발 분야에도 이와 똑같은 중요한 원칙이 있습니다. 바로 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;Don't Repeat Yourself (DRY)&quot;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, 우리말로 하자면 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;반복하지 말라&quot;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;는 것입니다. 이미 잘 작동하는 코드가 있다면, 굳이 똑같은 기능을 처음부터 다시 만들 필요가 없습니다. 대신, 기존의 코드를 활용하고 개선하여 더 나은 결과물을 만들어내는 데 집중해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예를 들어, 웹 페이지에서 달력을 표시하는 기능을 구현한다고 생각해 봅시다. 수많은 개발자들이 이미 훌륭한 달력 라이브러리들을 만들어 공개해 놓았습니다. &lt;/span&gt;&lt;a href=&quot;https://fullcalendar.io/&quot;&gt;&lt;span style=&quot;color: #0000ee;&quot;&gt;FullCalendar&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt;나 &lt;/span&gt;&lt;a href=&quot;https://jqueryui.com/datepicker/&quot;&gt;&lt;span style=&quot;color: #0000ee;&quot;&gt;jQuery UI Datepicker&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #000000;&quot;&gt;와 같은 라이브러리들을 사용하면, 우리는 단 몇 줄의 코드만으로 멋진 달력을 웹 페이지에 통합할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;lt;!-- jQuery UI CSS 추가 --&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css&quot;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;lt;!-- jQuery 라이브러리 추가 --&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;script src=&quot;&amp;lt;a href=https://code.jquery.com/jquery-3.7.0.js&amp;gt;https://code.jquery.com/jquery-3.7.0.js&amp;lt;/a&amp;gt;&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;lt;!-- jQuery UI 라이브러리 추가 --&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;script src=&quot;&amp;lt;a href=https://code.jquery.com/ui/1.13.2/jquery-ui.js&amp;gt;https://code.jquery.com/ui/1.13.2/jquery-ui.js&amp;lt;/a&amp;gt;&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;lt;div id=&quot;datepicker&quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; $( function() {&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; $( &quot;#datepicker&quot; ).datepicker();&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; } );&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위의 간단한 HTML 코드만으로도 우리는 사용자가 날짜를 쉽게 선택할 수 있는 달력을 만들 수 있습니다. 만약 우리가 이 기능을 처음부터 직접 구현하려고 했다면, 훨씬 더 많은 시간과 노력이 필요했을 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;바퀴를 재발명하는 대신, 더 나은 자동차를 만들자&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;물론, 때로는 기존의 기술이나 아이디어를 완전히 새로운 방식으로 혁신해야 할 때도 있습니다. 하지만 대부분의 경우, 이미 검증된 기반 위에 새로운 아이디어를 더하고 발전시키는 것이 훨씬 효율적입니다. 바퀴를 다시 발명하려고 에너지를 낭비하는 대신, 우리는 그 바퀴를 이용하여 더 빠르고 안전하며 친환경적인 자동차를 만드는 데 집중해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;소프트웨어 개발에서도 마찬가지입니다. 이미 훌륭한 프레임워크, 라이브러리, 디자인 패턴들이 존재합니다. 우리는 이러한 '바퀴'들을 잘 이해하고 활용하여, 사용자들에게 더 가치 있는 새로운 기능과 서비스를 제공하는 데 집중해야 합니다. 오픈 소스 프로젝트에 기여하거나, 기존 라이브러리의 한계를 극복하는 새로운 확장 기능을 개발하는 것도 좋은 방법입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;결론: 현명한 혁신가가 되자&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;결론적으로, 우리는 이미 훌륭한 발명품과 기술 위에 살고 있습니다. 때로는 완전히 새로운 것을 만드는 것도 중요하지만, 대부분의 경우 이미 존재하는 것들을 잘 활용하고 개선하는 것이 더욱 현명한 선택입니다. '바퀴를 다시 발명하지 말라'는 격언을 기억하고, 우리의 시간과 노력을 더 가치 있는 혁신에 집중하여 더 나은 미래를 만들어 나갑시다!&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;</description>
      <category>Life Story</category>
      <category>dry원칙</category>
      <category>개발철학</category>
      <category>기존기술활용</category>
      <category>소프트웨어개발</category>
      <category>재발명은no</category>
      <category>혁신</category>
      <category>효율성</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/63</guid>
      <comments>https://techsuda.tistory.com/entry/%EB%B0%94%ED%80%B4%EB%A5%BC-%EB%8B%A4%EC%8B%9C-%EB%B0%9C%EB%AA%85%ED%95%98%EC%A7%80-%EB%A7%90%EB%9D%BC#entry63comment</comments>
      <pubDate>Wed, 4 Jun 2025 21:32:23 +0900</pubDate>
    </item>
    <item>
      <title>[Flutter / SQLiTE]SQLiTE의 장단점 및 Flutter와 함께 사용 시 주의사항</title>
      <link>https://techsuda.tistory.com/entry/Flutter-SQLiTESQLiTE%EC%9D%98-%EC%9E%A5%EB%8B%A8%EC%A0%90-%EB%B0%8F-Flutter%EC%99%80-%ED%95%A8%EA%BB%98-%EC%82%AC%EC%9A%A9-%EC%8B%9C-%EC%A3%BC%EC%9D%98%EC%82%AC%ED%95%AD</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SQLite란 무엇인가?&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SQLite는 별도의 서버 프로세스 없이 작동하는 서버리스(Serverless), 자기 완결형(Self-Contained), 트랜잭션 안전(Transactional) SQL 데이터베이스 엔진입니다. SQLite 데이터베이스는 하나의 파일로 구성되어 관리가 용이하며, 임베디드 시스템, 모바일 애플리케이션, 소규모 데스크톱 애플리케이션 등 다양한 환경에서 널리 사용됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SQLite의 역사&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SQLite는 2000년에 D. Richard Hipp에 의해 개발되었습니다. 원래는 미 해군의 함선에 탑재될 소프트웨어에 사용하기 위해 개발되었으며, 상업적 및 개인적 용도로 자유롭게 사용할 수 있는 퍼블릭 도메인 소프트웨어입니다. 시간이 지나면서 SQLite는 단순함, 이식성, 안정성 덕분에 많은 개발자들에게 사랑받는 데이터베이스 엔진이 되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SQLite의 장점&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;서버리스:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 별도의 데이터베이스 서버 설치 및 구성이 필요 없어 개발 및 배포가 간편합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자기 완결형:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 전체 데이터베이스가 하나의 파일에 저장되므로 백업, 복사, 이동이 용이합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이식성:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 다양한 운영체제 및 플랫폼에서 동일한 데이터베이스 파일을 사용할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;경량성:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 작은 설치 공간과 낮은 메모리 사용량으로 리소스 제약적인 환경에 적합합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;트랜잭션 지원:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; ACID(Atomicity, Consistency, Isolation, Durability) 속성을 보장하여 데이터의 무결성을 유지합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SQL 표준 준수:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 대부분의 SQL 표준 문법을 지원하여 기존 SQL 지식을 활용하기 용이합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;간단한 API:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 사용하기 쉬운 API를 제공하여 개발자가 쉽게 데이터베이스를 조작할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SQLite의 단점&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;동시성 제한:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 파일 기반으로 작동하므로 높은 동시성 환경에서는 성능 저하가 발생할 수 있습니다. 쓰기 작업은 직렬화됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;네트워크 기능 부재:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 별도의 서버 프로세스가 없으므로 네트워크를 통한 데이터베이스 공유가 어렵습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;대규모 데이터 처리의 한계:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 매우 큰 규모의 데이터셋을 처리하거나 복잡한 쿼리를 실행하는 경우 다른 엔터프라이즈급 데이터베이스에 비해 성능이 떨어질 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;제한적인 사용자 관리:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 별도의 사용자 계정 및 권한 관리 기능이 내장되어 있지 않습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Flutter와 SQLite&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Flutter는 다양한 플랫폼에서 실행되는 모바일, 웹, 데스크톱 애플리케이션을 개발하기 위한 UI 프레임워크입니다. SQLite는 Flutter 애플리케이션에서 로컬 데이터를 저장하고 관리하는 데 널리 사용될 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Flutter에서 SQLite 사용 시 주의사항&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;비동기 처리:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 데이터베이스 작업은 I/O 작업이므로 UI 스레드를 차단하지 않도록 비동기적으로 처리해야 합니다. async/await 키워드나 Future API를 활용하여 비동기 작업을 구현해야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데이터베이스 접근 관리:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 애플리케이션 내에서 데이터베이스에 대한 일관된 접근 방식을 유지하는 것이 중요합니다. 데이터베이스 연결 및 쿼리 실행을 관리하는 별도의 클래스나 Helper 함수를 만드는 것을 고려해볼 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SQL Injection 방지:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 사용자 입력을 기반으로 SQL 쿼리를 동적으로 생성할 때 SQL Injection 공격에 취약해질 수 있습니다. Prepared Statement 또는 Parameterized Query를 사용하여 이를 방지해야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데이터 모델링:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 애플리케이션의 데이터 구조를 명확히 정의하고, 이에 맞는 적절한 테이블 스키마를 설계하는 것이 중요합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;테스트:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 데이터베이스 관련 로직에 대한 충분한 단위 테스트 및 통합 테스트를 수행하여 안정성을 확보해야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;플랫폼별 고려사항:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; iOS 및 Android 등 각 플랫폼에서 SQLite 데이터베이스 파일의 저장 경로 및 접근 방식에 약간의 차이가 있을 수 있습니다. 이를 고려하여 플랫폼별로 적절한 설정을 적용해야 할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;라이브러리 활용:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; Flutter에서 SQLite를 쉽게 사용할 수 있도록 다양한 third-party 라이브러리(예: sqflite)를 제공합니다. 이러한 라이브러리를 활용하면 데이터베이스 연동 코드를 간결하게 작성하고 관리할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Flutter SQLite 예시 (sqflite 라이브러리 사용)&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;import 'package:sqflite/sqflite.dart';&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;import 'package:path/path.dart';&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;class DatabaseHelper {&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; static Database? _database;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; static final DatabaseHelper instance = DatabaseHelper._internal();&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; factory DatabaseHelper() =&amp;gt; instance;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; DatabaseHelper._internal();&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; Future&amp;lt;Database&amp;gt; get database async {&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; if (_database != null) return _database!;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; _database = await _initDatabase();&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; return _database!;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; }&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; Future&amp;lt;Database&amp;gt; _initDatabase() async {&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; String path = join(await getDatabasesPath(), 'my_database.db');&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; return await openDatabase(&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; path,&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; version: 1,&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; onCreate: _createDb,&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; );&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; }&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; Future&amp;lt;void&amp;gt; _createDb(Database db, int version) async {&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; await db.execute('''&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; CREATE TABLE IF NOT EXISTS items (&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; id INTEGER PRIMARY KEY AUTOINCREMENT,&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; name TEXT NOT NULL,&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; description TEXT&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; ''');&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; }&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; Future&amp;lt;int&amp;gt; insertItem(Map&amp;lt;String, dynamic&amp;gt; item) async {&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; final db = await database;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; return await db.insert('items', item);&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; }&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; Future&amp;lt;List&amp;lt;Map&amp;gt;&amp;gt; getItems() async {&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; final db = await database;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; return await db.query('items');&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; }&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위 예시 코드는 sqflite 라이브러리를 사용하여 데이터베이스를 초기화하고, 테이블을 생성하며, 데이터를 삽입하고 조회하는 기본적인 방법을 보여줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;결론&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SQLite는 간편하고 효율적인 로컬 데이터 저장 솔루션으로, 특히 서버리스 환경이나 모바일 애플리케이션 개발에 유용합니다. Flutter 애플리케이션에서 SQLite를 사용할 때는 비동기 처리, 데이터 접근 관리, SQL Injection 방지 등 몇 가지 주의사항을 염두에 두어야 안정적이고 효율적인 애플리케이션을 개발할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <category>Flutter</category>
      <category>SQLite</category>
      <category>데이터베이스</category>
      <category>로컬데이터</category>
      <category>모바일개발</category>
      <category>서버리스</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/62</guid>
      <comments>https://techsuda.tistory.com/entry/Flutter-SQLiTESQLiTE%EC%9D%98-%EC%9E%A5%EB%8B%A8%EC%A0%90-%EB%B0%8F-Flutter%EC%99%80-%ED%95%A8%EA%BB%98-%EC%82%AC%EC%9A%A9-%EC%8B%9C-%EC%A3%BC%EC%9D%98%EC%82%AC%ED%95%AD#entry62comment</comments>
      <pubDate>Sun, 1 Jun 2025 19:44:17 +0900</pubDate>
    </item>
    <item>
      <title>[ISSUE] No Code 툴, 과연 초보자도 쉽게 쓸 수 있을까?</title>
      <link>https://techsuda.tistory.com/entry/%ED%85%8C%EC%8A%A4%ED%8A%B8</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;최근 IT 분야에서 'No Code' 툴에 대한 관심이 뜨겁습니다. 코딩 없이도 웹사이트, 앱, 자동화 워크플로우 등을 만들 수 있다는 매력적인 장점 때문에 많은 사람들이 No Code 툴을 배우고 활용하려 합니다. 하지만 정말 초보자도 쉽게 사용할 수 있을까요? 이 글에서는 No Code 툴의 현황과 함께 초보자의 접근성에 대해 자세히 알아보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;No Code 툴이란 무엇일까요?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;No Code 툴은 복잡한 프로그래밍 코드 작성 없이 시각적인 인터페이스( drag-and-drop, UI 컴포넌트 등)를 통해 소프트웨어나 자동화된 프로세스를 구축할 수 있도록 돕는 도구입니다. 이는 코딩에 대한 깊은 이해가 없어도 아이디어를 현실로 만들 수 있는 가능성을 열어줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다양한 No Code 툴의 종류&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;No Code 툴은 다양한 목적과 기능을 가지고 있으며, 몇 가지 주요 카테고리로 분류할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;웹사이트 빌더:&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; Wix, Squarespace, Webflow 등 드래그 앤 드롭 방식으로 쉽게 웹사이트를 제작할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;앱 빌더:&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; Adalo, Glide, AppGyver (SAP Build Apps) 등 코딩 없이 모바일 앱을 만들 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;자동화 플랫폼:&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; Zapier, Make (Integromat), IFTTT 등 다양한 앱과 서비스를 연결하여 자동화된 워크플로우를 구축합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;데이터베이스 및 백엔드:&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; Airtable, Notion, Supabase 등 데이터를 관리하고 간단한 백엔드 기능을 No Code로 구현할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;업무 도구:&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; Monday.com, Asana 등 프로젝트 관리 및 협업 도구를 No Code 방식으로 커스터마이징할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;No Code 툴의 장점과 단점&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;No Code 툴은 분명 매력적인 장점을 가지고 있지만, 동시에 고려해야 할 단점들도 존재합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;장점&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;빠른 개발 속도:&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; 코딩 없이 시각적으로 개발하므로 시간과 노력을 절약할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;낮은 진입 장벽:&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; 프로그래밍 지식이 없어도 아이디어를 쉽게 구현할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;비용 절감:&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; 개발자 채용 비용이나 외주 개발 비용을 줄일 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;유연성 및 사용자 주도 개발:&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; 사용자가 직접 기능을 추가하고 수정할 수 있어 유연성이 높습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;단점&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;기능 제한:&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; 복잡하거나 고도화된 기능 구현에는 제약이 있을 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;커스터마이징의 한계:&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; 제공되는 템플릿이나 컴포넌트 외의 세밀한 디자인이나 기능 변경이 어려울 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;플랫폼 종속성:&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; 특정 No Code 플랫폼에 종속되어 데이터 이전이나 시스템 확장이 어려울 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;성능 문제:&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; 복잡한 로직이나 많은 데이터를 처리할 때 성능 문제가 발생할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;보안 및 안정성:&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; 플랫폼 제공 업체의 보안 정책이나 안정성에 의존해야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;초보자가 No Code 툴을 쉽게 사용할 수 있을까?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;No Code 툴은 분명 코딩에 대한 부담 없이 시작할 수 있다는 점에서 초보자에게 매우 매력적입니다. 직관적인 인터페이스와 풍부한 템플릿, 튜토리얼 등을 제공하는 툴들이 많아 기본적인 기능은 비교적 쉽게 익힐 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;하지만 몇 가지 현실적인 어려움도 존재합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;기능 이해 및 선택:&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; 다양한 No Code 툴 중에서 자신의 목적에 맞는 툴을 선택하고, 제공하는 기능을 제대로 이해하는 데 시간이 걸릴 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;논리적 사고의 필요성:&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; 코딩 없이 개발하더라도 원하는 기능을 구현하기 위한 논리적인 사고와 설계 능력은 여전히 중요합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;문제 해결 능력:&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; 예상치 못한 오류나 작동 방식에 대한 이해가 부족하면 문제 해결에 어려움을 겪을 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;심화 기능 학습의 필요성:&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; 기본적인 사용법은 쉽지만, 더 복잡하고 효율적인 시스템을 구축하기 위해서는 각 툴의 심화 기능을 학습해야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;따라서 No Code 툴이 초보자에게 완전히 쉽다고 단정하기는 어렵습니다. 기본적인 웹사이트나 간단한 자동화 정도는 쉽게 만들 수 있지만, 복잡한 앱이나 고도화된 시스템 구축에는 학습과 노력이 필요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;결론&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;No Code 툴은 코딩 없이도 아이디어를 현실로 만들 수 있는 강력한 도구이며, 초보자도 비교적 쉽게 접근할 수 있는 것은 사실입니다. 하지만 그 가능성과 편리함 뒤에는 기능 제한, 플랫폼 종속성, 심화 학습의 필요성과 같은 고려 사항들이 존재합니다. No Code 툴을 성공적으로 활용하기 위해서는 자신의 목표와 필요에 맞는 툴을 신중하게 선택하고, 꾸준히 학습하며 문제 해결 능력을 키우는 노력이 필요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #555555;&quot;&gt;No Code 툴을 통해 디지털 전환을 꿈꾸는 모든 초보자분들을 응원합니다!&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/61</guid>
      <comments>https://techsuda.tistory.com/entry/%ED%85%8C%EC%8A%A4%ED%8A%B8#entry61comment</comments>
      <pubDate>Sun, 1 Jun 2025 16:48:01 +0900</pubDate>
    </item>
    <item>
      <title>[Docker] docker compose 와 Container 저장소 연결</title>
      <link>https://techsuda.tistory.com/entry/Docker-docker-compose-%EC%99%80-Container-%EC%A0%80%EC%9E%A5%EC%86%8C-%EC%97%B0%EA%B2%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;친구와 함께 배우는 Docker 마스터 클래스: 컨테이너 호스팅부터 사설 레지스트리까지!&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;친구랑 같이 배우는 Docker 정복기: 컨테이너 호스팅부터 사설 레지스트리까지! (feat. XpressEngine 게시판)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;안녕 친구들! 오늘은 나랑 같이 Docker를 좀 더 깊이 파헤쳐 보는 시간을 갖도록 할게.&amp;nbsp; Docker 초보 탈출을 꿈꾸는 너에게 딱 맞는 내용이야!&amp;nbsp; 이번 포스팅에서는 컨테이너 호스팅, 사설 저장소 구축, 그리고 Docker Compose까지, Docker의 핵심 기능들을 실습 위주로 알아볼 거야.&amp;nbsp; 자, 준비됐어?&amp;nbsp;  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**Part 1: XpressEngine 게시판과 함께하는 컨테이너 호스팅!**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;먼저, CentOS 7 기반의 XpressEngine(XE) 게시판을 Docker 컨테이너로 호스팅하는 방법을 알아볼게.&amp;nbsp; XE는 괜찮은 오픈소스 게시판이니까 한번 써보면 좋을 거야!&amp;nbsp; 이 실습에서는 XE 컨테이너와 MySQL 컨테이너를 연결해서 사용할 거야.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**1. XE 이미지 만들기 (Dockerfile)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;먼저, XE를 실행하기 위한 환경을 담은 Docker 이미지를 만들어야 해. 이를 위해 `Dockerfile` 이라는 파일을 만들고 다음과 같은 내용을 작성해줘.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```dockerfile&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;FROM centos:7&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RUN yum clean all &amp;amp;&amp;amp; yum update -y&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RUN yum -y install wget git httpd&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RUN wget &lt;a href=&quot;http://rpms.famillecollet.com/enterprise/remi-release-7.rpm&quot;&gt;http://rpms.famillecollet.com/enterprise/remi-release-7.rpm&lt;/a&gt; &amp;amp;&amp;amp; yum -y localinstall remi-release-7.rpm&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RUN yum -y install epel-release yum-utils&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RUN yum-config-manager --enable remi-php74&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RUN yum -y install php php-fpm php-gd php-mysql php-xml&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RUN git clone &lt;a href=&quot;https://github.com/xpressengine/xe-core.git&quot;&gt;https://github.com/xpressengine/xe-core.git&lt;/a&gt; /var/www/html/xe&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;WORKDIR /var/www/html/xe&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;WORKDIR /var/www/html&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RUN chmod -R 707 xe &amp;amp;&amp;amp; chown -R apache:apache xe&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;EXPOSE 80&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;CMD [&quot;httpd&quot;, &quot;-D&quot;, &quot;FOREGROUND&quot;]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**설명:**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* `FROM centos:7`: CentOS 7 이미지를 기반으로 이미지를 만들겠다는 뜻이야.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* `RUN`:&amp;nbsp; CentOS 패키지 매니저인 yum을 이용해서 필요한 패키지들을 설치하는 명령어들이야.&amp;nbsp; wget, git, httpd(Apache 웹 서버), php 관련 패키지들을 설치하고 XE 소스 코드를 git clone으로 받아와.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* `WORKDIR`: 작업 디렉토리를 변경하는 명령어야.&amp;nbsp; XE 소스 코드를 놓을 위치를 설정해주는 거지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* `EXPOSE 80`: 80번 포트를 열어 외부에서 접근할 수 있도록 해주는 거야.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* `CMD`: 컨테이너가 시작될 때 실행할 명령어야.&amp;nbsp; 여기서는 Apache 웹 서버를 foreground 모드로 실행하도록 설정했어.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 `Dockerfile`을 저장하고, 다음 명령어를 실행하면 XE 이미지를 만들 수 있어.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```bash&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker build -t xe:1.0 .&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;&amp;lt;a href=https://velog.velcdn.com/images/ptah0414/post/2b38d33b-d115-4efe-ae8c-678004584b3d/image.png&amp;gt;https://velog.velcdn.com/images/ptah0414/post/2b38d33b-d115-4efe-ae8c-678004584b3d/image.png&amp;lt;/a&amp;gt;&quot; alt=&quot;Dockerfile Build&quot; /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**2. MySQL 컨테이너 배포 (db1)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다음은 MySQL 컨테이너를 배포하는 명령어야.&amp;nbsp; root 비밀번호를 `test123`으로, 데이터베이스 이름을 `xe`로 설정했어.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```bash&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker run -d --name db1 -e MYSQL_ROOT_PASSWORD=test123 -e MYSQL_DATABASE=xe mysql:5.7&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**3. XE 컨테이너 배포 (xe1)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;마지막으로, 위에서 만든 XE 이미지를 이용해서 XE 컨테이너를 배포하고, MySQL 컨테이너(db1)과 연결해줘. 외부 8888번 포트를 XE 컨테이너의 80번 포트에 매핑했어.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```bash&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker run -it --name xe1 --link db1:mysql -p 8888:80 xe:1.0&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;`--link db1:mysql` 옵션을 통해 XE 컨테이너는 `db1` 컨테이너를 `mysql` 이라는 이름으로 접근할 수 있어.&amp;nbsp; XE 설치 과정에서 MySQL 접속 정보 입력 시 호스트 이름으로 `db1`을 입력하면 돼!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;&amp;lt;a href=https://velog.velcdn.com/images/ptah0414/post/54abb9cf-5398-4a6a-9a92-c465f8dc131a/image.png&amp;gt;https://velog.velcdn.com/images/ptah0414/post/54abb9cf-5398-4a6a-9a92-c465f8dc131a/image.png&amp;lt;/a&amp;gt;&quot; alt=&quot;XE 설치 화면&quot; /&gt;&lt;img src=&quot;&amp;lt;a href=https://velog.velcdn.com/images/ptah0414/post/08062a75-cbdf-4f43-910a-acbdb6ffa4a9/image.png&amp;gt;https://velog.velcdn.com/images/ptah0414/post/08062a75-cbdf-4f43-910a-acbdb6ffa4a9/image.png&amp;lt;/a&amp;gt;&quot; alt=&quot;DB 설정 화면&quot; /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이제 `http://[가상머신 IP]:8888/xe` 주소로 접속해서 XE를 설치하고 게시판을 사용할 수 있어!  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**Part 2: 나만의 Private Registry 만들기!**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;공개 레지스트리인 Docker Hub 말고, 나만의 사설 레지스트리를 만들어 이미지를 안전하게 관리해 보자!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**1. 레지스트리 컨테이너 배포**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;먼저, 레지스트리 컨테이너를 배포해줘.&amp;nbsp; 여기서는 `registry` 이미지를 사용할 거야.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```bash&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker container run -d -p 5000:5000 --restart=always --name registry -v /home/rapa/registry:/var/lib/registry registry&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;`/home/rapa/registry` 디렉토리는 레지스트리의 데이터를 저장할 볼륨이야.&amp;nbsp; 이 디렉토리를 미리 만들어줘야 해.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**2. 레지스트리 웹 GUI 배포**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;레지스트리 관리를 더 편하게 하려면 웹 GUI를 사용하는 게 좋아. `hyper/docker-registry-web` 이미지를 사용해볼게.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```bash&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker run -d -p 8080:8080 --name registry-web --link registry:private -e REGISTRY_URL=http://[가상머신 IP]:5000/v2 -e REGISTRY_NAME=[가상머신 IP]:5000 --restart=always hyper/docker-registry-web&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;`REGISTRY_URL`과 `REGISTRY_NAME`은 네트워크 환경에 맞게 수정해줘야 해.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;&amp;lt;a href=https://velog.velcdn.com/images/ptah0414/post/81dcf25e-41e6-4cfd-81d6-3785f7525c19/image.png&amp;gt;https://velog.velcdn.com/images/ptah0414/post/81dcf25e-41e6-4cfd-81d6-3785f7525c19/image.png&amp;lt;/a&amp;gt;&quot; alt=&quot;Registry Web GUI&quot; /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**3. 이미지 태깅 및 PUSH**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이제 만들어 놓은 이미지를 사설 레지스트리에 올려보자.&amp;nbsp; 먼저 이미지에 태그를 설정하고, `docker push` 명령어로 사설 레지스트리에 push 해줘.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```bash&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker tag centos:7 localhost:5000/mycentos:1.0&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker push localhost:5000/mycentos:1.0&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**4. 이미지 PULL**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다시 사설 레지스트리에서 이미지를 가져와보자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```bash&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker pull localhost:5000/mycentos:1.0&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**Part 3: 남의 Private Registry에 이미지 PUSH하기 (주의! 보안)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다른 사람의 사설 레지스트리에 이미지를 push하는 것은 보안 문제 때문에 권장하지 않아.&amp;nbsp; 하지만 실습을 위해 `--insecure-registry` 옵션을 사용하는 방법을 보여줄게.&amp;nbsp; **실제 운영 환경에서는 절대 사용하지 마세요!**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```bash&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;# /etc/docker/daemon.json 에 다음 내용 추가&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&quot;insecure-registries&quot;: [&quot;192.168.1.117:5000&quot;]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;# docker daemon 재시작&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sudo systemctl restart docker&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker tag centos:7 192.168.1.117:5000/myweb:gunwoo&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker push 192.168.1.117:5000/myweb:gunwoo&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**Part 4: Docker Compose로 편하게 컨테이너 관리하기!**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Docker Compose를 이용하면 여러 개의 컨테이너를 YAML 파일 하나로 정의하고 관리할 수 있어.&amp;nbsp; 정말 편리하다는 거!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**1. docker-compose.yml 파일 작성**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다음은 WordPress와 MySQL을 함께 배포하는 `docker-compose.yml` 파일의 예시야.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```yaml&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;version: '3.0'&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;services:&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;wordpress:&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;image: wordpress&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ports:&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- &quot;8888:80&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;environment:&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- WORDPRESS_DB_PASSWORD=test123&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- WORDPRESS_DB_NAME=wpdb&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- WORDPRESS_DB_USER=root&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;depends_on:&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- db&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;links:&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- db:mysql&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;db:&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;image: mysql:5.7&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;environment:&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- MYSQL_ROOT_PASSWORD=test123&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- MYSQL_DATABASE=wpdb&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**2. 배포 및 확인**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;`docker-compose up -d` 명령어로 컨테이너들을 배포하고, `docker container ls` 명령어로 배포 상태를 확인할 수 있어.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;&amp;lt;a href=https://velog.velcdn.com/images/ptah0414/post/2eae07e6-bbc8-4569-b870-166effbaadc6/image.png&amp;gt;https://velog.velcdn.com/images/ptah0414/post/2eae07e6-bbc8-4569-b870-166effbaadc6/image.png&amp;lt;/a&amp;gt;&quot; alt=&quot;WordPress 접속 화면&quot; /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자, 이렇게 컨테이너 호스팅부터 사설 레지스트리, Docker Compose까지 Docker의 다양한 기능들을 알아봤어.&amp;nbsp; 처음에는 어렵게 느껴질 수 있지만, 하나씩 따라 해 보면 금방 익숙해질 거야!&amp;nbsp; 다음 시간에는 더욱 심화된 Docker 내용으로 돌아올게! &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/60</guid>
      <comments>https://techsuda.tistory.com/entry/Docker-docker-compose-%EC%99%80-Container-%EC%A0%80%EC%9E%A5%EC%86%8C-%EC%97%B0%EA%B2%B0#entry60comment</comments>
      <pubDate>Sat, 31 May 2025 21:36:50 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 배열 복사 (흔히 하는 실수?)</title>
      <link>https://techsuda.tistory.com/entry/Python-%EB%B0%B0%EC%97%B4-%EB%B3%B5%EC%82%AC-%ED%9D%94%ED%9E%88-%ED%95%98%EB%8A%94-%EC%8B%A4%EC%88%98</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파이썬 할당과 복사의 핵심: 얕은 복사 vs 깊은 복사, 이제 헷갈리지 마세요!&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파이썬 할당, 복사 얘기 좀 해볼까? 얕은 복사? 깊은 복사? 뭔 소리야?!  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;어이 친구! 오늘은 파이썬에서 엄청 중요하지만, 은근히 헷갈리는 할당과 복사에 대해서 얘기 좀 해볼까 해. 특히 얕은 복사(shallow copy)랑 깊은 복사(deep copy)는 진짜 헷갈리거든!&amp;nbsp; 내가 그림도 잔뜩 넣고, 코드도 보여주면서 쉽게 설명해줄 테니까, 끝까지 따라와 봐!  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;### 1. 할당 vs 복사: 같은 건가, 다른 건가?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;먼저 리스트를 예로 들어볼게.&amp;nbsp; 리스트 `a`를 `b`에 할당해보자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```python&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;a = [1, 2, 3]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;b = a&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이렇게 하면 `a`와 `b`는 같은 리스트를 가리키게 돼.&amp;nbsp; 마치 같은 방의 다른 문짝을 열어본 것과 같은 거야.&amp;nbsp; 하나의 리스트가 메모리에 존재하고, `a`와 `b`는 그 주소를 참조하고 있는 거지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;![리스트 할당 이미지](&lt;a href=&quot;https://velog.velcdn.com/images%2Fkkamyang%2Fpost%2Fbbc9d428-9e80-46ea-9ebf-5ba7b82fdf35%2Fimage.png)&quot;&gt;https://velog.velcdn.com/images%2Fkkamyang%2Fpost%2Fbbc9d428-9e80-46ea-9ebf-5ba7b82fdf35%2Fimage.png)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이걸 확인하는 방법은 `is` 연산자를 사용하면 돼. `is`는 메모리 주소를 비교하는 거야.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```python&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;print(a is b)&amp;nbsp; # True 출력!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그래서 `b`의 요소를 바꾸면 `a`도 같이 바뀌어.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```python&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;b[1] = 5&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;print(a)&amp;nbsp; # [1, 5, 3] 출력&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;print(b)&amp;nbsp; # [1, 5, 3] 출력&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;![할당 그림](&lt;a href=&quot;https://velog.velcdn.com/images%2Fkkamyang%2Fpost%2F7d0fbb04-c042-4fca-a2d0-2ca2bc8c1b0c%2Fimage.png)&quot;&gt;https://velog.velcdn.com/images%2Fkkamyang%2Fpost%2F7d0fbb04-c042-4fca-a2d0-2ca2bc8c1b0c%2Fimage.png)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자, 이번에는 복사를 해볼게.&amp;nbsp; `copy()` 메서드를 사용하면 돼.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```python&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;a = [1, 2, 3]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;b = a.copy()&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이번에는 `a`와 `b`가 서로 다른 리스트를 가리키게 돼.&amp;nbsp; 서로 다른 방에 있는 같은 내용의 리스트를 가지고 있는 거야.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;![복사 후 리스트 비교](&lt;a href=&quot;https://velog.velcdn.com/images%2Fkkamyang%2Fpost%2Ff10f7acb-d7b4-4405-82c3-29699c183604%2Fimage.png)&quot;&gt;https://velog.velcdn.com/images%2Fkkamyang%2Fpost%2Ff10f7acb-d7b4-4405-82c3-29699c183604%2Fimage.png)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```python&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;print(a is b)&amp;nbsp; # False 출력!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;print(a == b)&amp;nbsp; # True 출력!&amp;nbsp; (내용은 같다는 뜻)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;`b`의 요소를 바꿔도 `a`는 그대로야.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```python&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;b[1] = 5&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;print(a)&amp;nbsp; # [1, 2, 3] 출력&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;print(b)&amp;nbsp; # [1, 5, 3] 출력&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;![할당과 복사 비교 그림](&lt;a href=&quot;https://velog.velcdn.com/images%2Fkkamyang%2Fpost%2F4b85933b-61ef-448c-8277-3808555be935%2Fimage.png)&quot;&gt;https://velog.velcdn.com/images%2Fkkamyang%2Fpost%2F4b85933b-61ef-448c-8277-3808555be935%2Fimage.png)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;### 2. 가변 객체(mutable)와 불변 객체(immutable):&amp;nbsp; 핵심 차이!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자, 여기서 중요한 개념이 하나 나와. 바로 **가변 객체(mutable)**와 **불변 객체(immutable)**이야.&amp;nbsp; 리스트처럼 생성 후 값을 바꿀 수 있는 객체가 가변 객체이고, 튜플처럼 생성 후 값을 바꿀 수 없는 객체가 불변 객체야.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;![가변, 불변 객체 표](&lt;a href=&quot;https://velog.velcdn.com/images%2Fkkamyang%2Fpost%2F90bad738-3206-409b-80a1-dbaf557afab2%2Fimage.png)&quot;&gt;https://velog.velcdn.com/images%2Fkkamyang%2Fpost%2F90bad738-3206-409b-80a1-dbaf557afab2%2Fimage.png)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;튜플을 예로 들어보면,&amp;nbsp; `copy()` 메서드를 사용할 수 없어.&amp;nbsp; 에러가 나지!&amp;nbsp; 왜냐하면 튜플은 변경이 불가능하니까.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```python&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;a = (1, 2, 3)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;# b = a.copy()&amp;nbsp; # AttributeError: 'tuple' object has no attribute 'copy'&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;![튜플 할당 이미지](&lt;a href=&quot;https://velog.velcdn.com/images%2Fkkamyang%2Fpost%2Fa8956ed2-8292-47cd-be40-436e86ffc1f4%2Fimage.png)&quot;&gt;https://velog.velcdn.com/images%2Fkkamyang%2Fpost%2Fa8956ed2-8292-47cd-be40-436e86ffc1f4%2Fimage.png)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;### 3. 얕은 복사(shallow copy): 겉만 베끼기!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이제 얕은 복사를 알아볼까? `copy` 모듈의 `copy()` 함수를 사용해.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```python&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;import copy&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;a = [1, 2, [3, 4]]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;b = copy.copy(a)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;`b`는 `a`의 얕은 복사본이야.&amp;nbsp; 가장 바깥쪽 리스트만 복사하고, 안쪽 리스트는 같은 것을 참조해.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;![얕은 복사 초기 그림](&lt;a href=&quot;https://velog.velcdn.com/images%2Fkkamyang%2Fpost%2Ffcf0f80f-953e-4d92-bc05-909c39bce008%2Fimage.png)&quot;&gt;https://velog.velcdn.com/images%2Fkkamyang%2Fpost%2Ffcf0f80f-953e-4d92-bc05-909c39bce008%2Fimage.png)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그래서 바깥쪽 요소를 바꾸면 `a`에는 영향을 안 주지만, 안쪽 리스트를 바꾸면 `a`에도 영향을 줘.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```python&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;b[0] = 5&amp;nbsp; # a는 변경되지 않음&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;b[2].append(5)&amp;nbsp; # a도 변경됨!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;![얕은 복사 바깥 요소 변경](&lt;a href=&quot;https://velog.velcdn.com/images%2Fkkamyang%2Fpost%2Fae990d20-b588-4de7-92ac-7b23f0d70f89%2Fimage.png)&quot;&gt;https://velog.velcdn.com/images%2Fkkamyang%2Fpost%2Fae990d20-b588-4de7-92ac-7b23f0d70f89%2Fimage.png)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;![얕은 복사 안쪽 요소 변경](&lt;a href=&quot;https://velog.velcdn.com/images%2Fkkamyang%2Fpost%2Fb29011e0-abdd-4072-89fb-84d6d73eff25%2Fimage.png)&quot;&gt;https://velog.velcdn.com/images%2Fkkamyang%2Fpost%2Fb29011e0-abdd-4072-89fb-84d6d73eff25%2Fimage.png)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;### 4. 깊은 복사(deep copy): 속까지 똑같이 만들기!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;진짜 완벽하게 복사하고 싶다면 `copy.deepcopy()`를 사용해. 이 함수는 안쪽 리스트까지 완전히 새로운 복사본을 만들어.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```python&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;import copy&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;a = [1, 2, [3, 4]]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;b = copy.deepcopy(a)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;b[2].append(5)&amp;nbsp; # a는 변경되지 않음!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;![깊은 복사 그림](&lt;a href=&quot;https://velog.velcdn.com/images%2Fkkamyang%2Fpost%2F965f60f9-27b7-4164-8310-6174d81fd4b7%2Fimage.png)&quot;&gt;https://velog.velcdn.com/images%2Fkkamyang%2Fpost%2F965f60f9-27b7-4164-8310-6174d81fd4b7%2Fimage.png)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이제 할당과 복사, 그리고 얕은 복사와 깊은 복사의 차이를 확실히 알겠지?&amp;nbsp; 이 개념을 잘 이해해야 파이썬 프로그래밍에서 예상치 못한 버그를 피할 수 있어!&amp;nbsp; 잘 기억해두고, 궁금한 점 있으면 언제든지 물어봐!  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/59</guid>
      <comments>https://techsuda.tistory.com/entry/Python-%EB%B0%B0%EC%97%B4-%EB%B3%B5%EC%82%AC-%ED%9D%94%ED%9E%88-%ED%95%98%EB%8A%94-%EC%8B%A4%EC%88%98#entry59comment</comments>
      <pubDate>Sat, 31 May 2025 21:35:23 +0900</pubDate>
    </item>
    <item>
      <title>[Python] Flask vs Django 특징 및 장단점 비교</title>
      <link>https://techsuda.tistory.com/entry/Python-Flask-vs-Django-%ED%8A%B9%EC%A7%95-%EB%B0%8F-%EC%9E%A5%EB%8B%A8%EC%A0%90-%EB%B9%84%EA%B5%90</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;장고 vs 플라스크: 나에게 맞는 파이썬 웹 프레임워크 찾기!&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;오늘은 파이썬 웹 개발의 양대 산맥, 장고(Django)와 플라스크(Flask)에 대해 흥미진진한 비교 분석을 해볼 거야!&amp;nbsp; 어떤 프레임워크가 나에게 딱 맞을지 고민하는 친구들을 위해 준비했으니, 팝콘   챙겨서 편하게 읽어봐 ㅎㅎ&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**  먼저 둘의 차이는 뭘까?**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;간단하게 말하면, 장고는 '풀옵션 자동차'이고, 플라스크는 '내가 꾸미는 자전거'야.&amp;nbsp; 둘 다 A 지점에서 B 지점으로 데려다주는 건 똑같지만, 방식이 다르다는 거지.&amp;nbsp; 장고는 필요한 기능들이 다 갖춰져 있어서 바로 달릴 수 있지만, 플라스크는 내가 원하는 부품을 직접 골라서 조립해야 해.&amp;nbsp; 그래서 상황에 따라 최고의 선택지는 달라진다는 거지!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**✨ 장고(Django)의 매력 포인트!**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;장고는 '배터리 포함'이야!&amp;nbsp; ORM(Object-Relational Mapper), 관리자 패널, 인증 시스템 등 웹 개발에 필요한 필수 기능들이 기본적으로 제공돼.&amp;nbsp; 웹 개발 경험이 많지 않더라도 빠르게 프로젝트를 시작할 수 있다는 큰 장점이 있지.&amp;nbsp; 게다가 엄격한 릴리즈 사이클 덕분에 안정성도 높고, 하위 호환성도 좋아서 유지보수가 편해.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**장고 ORM 살펴보기:**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;장고의 ORM은 정말 강력해!&amp;nbsp; SQLite, PostgreSQL, MySQL 등 다양한 관계형 데이터베이스를 지원하고, 마이그레이션 기능까지 제공해서 데이터베이스 관리도 쉬워.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```python&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;# models.py&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;from django.db import models&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;class BlogPost(models.Model):&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title = models.CharField(max_length=200)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;content = models.TextField()&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;created_at = models.DateTimeField(auto_now_add=True)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def __str__(self):&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return self.title&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이렇게 간단한 코드만으로도 데이터베이스 모델을 정의할 수 있어!&amp;nbsp; CRUD(Create, Read, Update, Delete) 작업도 ORM을 통해 간편하게 처리 가능하지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**  플라스크(Flask)의 매력 포인트!**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;플라스크는 '자유로운 영혼'이야!&amp;nbsp; 최소한의 기능만 제공하고, 나머지는 내가 원하는 대로 확장하고 커스터마이징 할 수 있어.&amp;nbsp; 가볍고 유연해서 마이크로서비스나 서버리스 환경에 적합하고,&amp;nbsp; 직접 코드를 제어하기 때문에 성능 최적화에도 유리해.&amp;nbsp; 하지만, 자유에는 책임이 따르는 법!&amp;nbsp; 필요한 기능들을 직접 구현해야 하기 때문에 개발 시간이 더 오래 걸릴 수도 있고,&amp;nbsp; 초보자에게는 진입 장벽이 조금 높을 수도 있어.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**플라스크 라우팅 예시:**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```python&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;from flask import Flask, render_template&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;app = Flask(__name__)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;@app.route('/')&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;def index():&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return render_template('index.html')&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;if __name__ == '__main__':&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app.run(debug=True)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이처럼 간결한 코드로 웹 애플리케이션을 만들 수 있어.&amp;nbsp; 내가 원하는대로 라우팅을 설정하고, 템플릿 엔진을 사용해서 동적인 웹 페이지를 만들 수 있지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**  이미지로 비교 분석!**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(여기에 장고와 플라스크의 특징을 비교하는 이미지를 넣어보자. 예를 들어, 장고는 풀옵션 자동차 이미지, 플라스크는 자전거를 조립하는 이미지 등을 사용하면 좋을 것 같아.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**결론은?  **&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;어떤 프레임워크가 더 좋다고 단정 지을 수는 없어!&amp;nbsp; 프로젝트의 규모, 개발 기간, 개발팀의 경험, 그리고 필요한 기능 등 여러 요소를 고려해서 선택해야 해.&amp;nbsp; 만약 빠르게 프로젝트를 진행하고 싶고, 안정적인 시스템을 원한다면 장고를,&amp;nbsp; 유연성과 커스터마이징이 중요하고,&amp;nbsp; 직접 코드를 제어하고 싶다면 플라스크를 선택하는 것이 좋을 거야.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/58</guid>
      <comments>https://techsuda.tistory.com/entry/Python-Flask-vs-Django-%ED%8A%B9%EC%A7%95-%EB%B0%8F-%EC%9E%A5%EB%8B%A8%EC%A0%90-%EB%B9%84%EA%B5%90#entry58comment</comments>
      <pubDate>Sat, 31 May 2025 21:33:55 +0900</pubDate>
    </item>
    <item>
      <title>[Python] Dictionary 와 JSon 비교 및 변환</title>
      <link>https://techsuda.tistory.com/entry/Python-Dictionary-%EC%99%80-JSon-%EB%B9%84%EA%B5%90-%EB%B0%8F-%EB%B3%80%ED%99%98</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;야! Python 딕셔너리, JSON으로 변환하는 거 졸라 쉽다!&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;오늘은 Python에서 딕셔너리를 JSON으로 변환하는 방법에 대해 얘기해볼까 해.&amp;nbsp; 웹 개발하다 보면 Python으로 백엔드 짜고, 자바스크립트로 프론트엔드 짜는 경우가 많은데, 이때 데이터 주고받는 게 좀 귀찮잖아?&amp;nbsp; 그럴 때 JSON이 딱인데, Python 딕셔너리랑 JSON 변환하는 게 얼마나 쉬운지 보여줄게!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**1. 왜 JSON이 필요할까?**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;API로 데이터 주고받을 때 JSON 형식 많이 쓰잖아?&amp;nbsp; Python에선 딕셔너리가 JSON이랑 엄청 비슷하게 생겨서 변환하기 편해.&amp;nbsp; 자바스크립트에서도 JSON 다루기 쉽고, 다른 언어들도 마찬가지야.&amp;nbsp; 그래서 데이터 교환에 딱이지!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**2. Python 딕셔너리 -&amp;gt; JSON 변환: `json.dumps()`**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자, 이제 본격적으로 코드를 볼까?&amp;nbsp; 일단 `json` 모듈을 불러와야 해.&amp;nbsp; 그리고 `json.dumps()` 함수를 이용하면 딕셔너리를 JSON 문자열로 변환할 수 있어.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```python&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;import json&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;# 딕셔너리 생성&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;my_dict = {&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;'name': '철수',&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;'age': 30,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;'city': '서울'&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;# 딕셔너리를 JSON 문자열로 변환&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;json_string = json.dumps(my_dict, ensure_ascii=False) # ensure_ascii=False는 한글깨짐 방지!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;# 결과 출력&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;print(f&quot;딕셔너리: {my_dict}&quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;print(f&quot;JSON 문자열: {json_string}&quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;print(f&quot;데이터 타입: {type(json_string)}&quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(이미지 삽입: 코드 실행 결과 스크린샷)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자, 실행해보면 `json_string`에는 JSON 형태의 문자열이 들어있어.&amp;nbsp; `type(json_string)`을 보면 `&amp;lt;class 'str'&amp;gt;`이라고 나오는걸 확인할 수 있지.&amp;nbsp; 딕셔너리랑 다르게 문자열이 됐다는 뜻이야.&amp;nbsp; 그래서 딕셔너리처럼 `json_string['name']` 이렇게 접근하면 에러가 나!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**3. JSON -&amp;gt; Python 딕셔너리 변환: `json.loads()`**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;반대로 JSON 문자열을 다시 Python 딕셔너리로 변환하고 싶으면 `json.loads()` 함수를 사용하면 돼.&amp;nbsp; 아주 간단하지?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```python&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;import json&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;json_string = '{&quot;name&quot;: &quot;철수&quot;, &quot;age&quot;: 30, &quot;city&quot;: &quot;서울&quot;}'&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;# JSON 문자열을 딕셔너리로 변환&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;my_dict = json.loads(json_string)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;# 결과 출력&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;print(f&quot;JSON 문자열: {json_string}&quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;print(f&quot;딕셔너리: {my_dict}&quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;print(f&quot;데이터 타입: {type(my_dict)}&quot;)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(이미지 삽입: 코드 실행 결과 스크린샷)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이번엔 `my_dict`의 타입이 `&amp;lt;class 'dict'&amp;gt;`로 나오는 걸 볼 수 있지? 이제 다시 딕셔너리처럼 `my_dict['name']` 이렇게 접근해서 값을 꺼낼 수 있어!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**4.&amp;nbsp; 더 자세한 내용은?**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Python 공식 문서에도 `json` 모듈에 대한 설명이 자세하게 나와있어.&amp;nbsp; 궁금한 점 있으면 [&lt;a href=&quot;https://docs.python.org/3/library/json.html](https://docs.python.org/3/library/json.html)&quot;&gt;https://docs.python.org/3/library/json.html](https://docs.python.org/3/library/json.html)&lt;/a&gt;&amp;nbsp; 여기서 확인해봐! (Python 3 기준 링크임!)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**5. 마무리**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Python 딕셔너리와 JSON 변환, 생각보다 엄청 쉽지?&amp;nbsp; `json.dumps()`와 `json.loads()` 함수만 알면 웹 개발할 때 데이터 주고받는 게 훨씬 수월해질 거야!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/57</guid>
      <comments>https://techsuda.tistory.com/entry/Python-Dictionary-%EC%99%80-JSon-%EB%B9%84%EA%B5%90-%EB%B0%8F-%EB%B3%80%ED%99%98#entry57comment</comments>
      <pubDate>Sat, 31 May 2025 21:30:44 +0900</pubDate>
    </item>
    <item>
      <title>[SQL] SQL vs No-SQL</title>
      <link>https://techsuda.tistory.com/entry/SQL-SQL-vs-No-SQL</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데이터베이스 선택 고민 끝! SQL vs NoSQL&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;안녕 친구! 요즘 데이터베이스(DB) 고르는 게 은근 고민이지?&amp;nbsp; SQL이니 NoSQL이니&amp;hellip;&amp;nbsp; 용어만 봐도 머리 아프잖아.&amp;nbsp; 내가 오늘 쉽게 정리해줄게!&amp;nbsp; 마치 친구끼리 수다 떠는 것처럼!  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**1. SQL: 깔끔한 정리정돈, 딱! 정해진 틀!**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;상상해봐. 너의 방이 항상 깔끔하게 정리되어 있고, 모든 물건이 제 자리에 있는 모습!&amp;nbsp; SQL 데이터베이스가 바로 그런 거야.&amp;nbsp; 모든 데이터가 **테이블**이라는 칸에, **행(row)**과 **열(column)** 형태로 딱 정해진 틀 안에 가지런히 정리되어 있어.&amp;nbsp; 마치 엑셀 시트처럼 말이지!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SQL은 데이터를 관리하는 **구조화된 질의어(Structured Query Language)**야.&amp;nbsp; 데이터를 추가, 삭제, 수정, 조회할 때 사용하는 명령어 집합이라고 생각하면 돼.&amp;nbsp; SQL 문법을 배우면, 데이터를 아주 효율적으로 관리할 수 있어!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**SQL 예시 (MySQL):**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```sql&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-- 새로운 사용자 추가&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;INSERT INTO users (name, email) VALUES ('친구', 'friend@example.com');&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-- 이메일이 'friend@example.com'인 사용자 정보 조회&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SELECT * FROM users WHERE email = 'friend@example.com';&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;lt;img src=&quot;[이미지링크주소1: SQL 데이터베이스 테이블 예시 이미지. 예를 들어, 사용자 이름, 이메일, 가입일 등의 열을 가진 테이블 이미지]&quot; alt=&quot;SQL 데이터베이스 테이블 예시&quot;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**장점:**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* 데이터 무결성이 높아 (데이터가 깔끔하게 정리되니까 오류가 적어!)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* 복잡한 질의가 가능해 (데이터 간의 관계를 쉽게 파악하고 분석 가능!)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* 트랜잭션 처리가 안전해 (데이터 수정 시 오류 발생을 방지!)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**2. NoSQL: 자유로운 융통성, 마음껏 펼쳐봐!**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;반대로, 너의 방이 조금 어수선하지만, 필요한 물건은 금방 찾을 수 있게 잘 정리된 경우를 생각해봐.&amp;nbsp; NoSQL 데이터베이스는 바로 그런 거야!&amp;nbsp; 정해진 틀 없이, 데이터의 형태에 맞춰 유연하게 저장할 수 있어.&amp;nbsp; 문서, 키-값 쌍, 그래프 등 다양한 형태로 데이터를 저장할 수 있다는 뜻이야!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;lt;img src=&quot;[이미지링크주소2: NoSQL 데이터베이스의 다양한 형태 예시 이미지. 예를 들어, JSON 문서, 키-값 쌍, 그래프 데이터 등을 보여주는 이미지]&quot; alt=&quot;NoSQL 데이터베이스 다양한 형태 예시&quot;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**NoSQL 예시 (MongoDB - JSON 문서):**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```json&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&quot;name&quot;: &quot;친구&quot;,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&quot;email&quot;: &quot;friend@example.com&quot;,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&quot;address&quot;: {&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;street&quot;: &quot;어딘가&quot;,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;city&quot;: &quot;어디시&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**장점:**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* 확장성이 뛰어나 (데이터가 많아져도 쉽게 처리 가능!)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* 유연성이 높아 (데이터 형식이 바뀌어도 문제없어!)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* 속도가 빠르다 (특정 데이터를 빠르게 찾을 수 있어!)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**3. SQL vs NoSQL: 어떤 걸 골라야 할까?  **&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자, 이제 중요한 질문!&amp;nbsp; SQL과 NoSQL 중 어떤 데이터베이스를 선택해야 할까?&amp;nbsp; 정답은 없어!&amp;nbsp; 너의 프로젝트 목표와 데이터 특징에 따라 달라진다는 거지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **SQL이 적합한 경우:**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* 데이터 간의 관계가 복잡하고, 데이터 무결성이 중요한 경우 (예: 은행 시스템)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* 복잡한 질의와 트랜잭션 처리가 필요한 경우&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* 데이터 양이 크지 않고, 확장성이 크게 필요하지 않은 경우&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **NoSQL이 적합한 경우:**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* 데이터 양이 매우 크고, 확장성이 중요한 경우 (예: 소셜 미디어)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* 데이터 형식이 다양하고, 유연성이 필요한 경우&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* 빠른 속도로 데이터를 읽고 쓸 필요가 있는 경우 (예: 게임 서버)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**4. 마무리:**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SQL과 NoSQL, 이제 좀 감이 잡히지?&amp;nbsp; 어려운 전문 용어 대신 친구처럼 쉽게 설명해 봤어.&amp;nbsp; 더 궁금한 점이 있다면 언제든지 물어봐!&amp;nbsp; 함께 고민하고, 최고의 데이터베이스를 선택해 보자!  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/55</guid>
      <comments>https://techsuda.tistory.com/entry/SQL-SQL-vs-No-SQL#entry55comment</comments>
      <pubDate>Sat, 31 May 2025 21:29:06 +0900</pubDate>
    </item>
    <item>
      <title>[Flutter] 대화상자에서 setState() 사용</title>
      <link>https://techsuda.tistory.com/entry/Flutter-%EB%8C%80%ED%99%94%EC%83%81%EC%9E%90%EC%97%90%EC%84%9C-setState-%EC%82%AC%EC%9A%A9</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a title=&quot;여기로 글 옮겼습니다.&quot; href=&quot;https://techsuda.tistory.com/72&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여기로 글 옮겼습니다.&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;Flutter의 Dialog 안에서 setState 하기&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;오늘은 Flutter 개발 중에 꽤나 골치 아팠던 문제, 바로 **Dialog 안에서 setState를 사용하는 방법**에 대해 속 시원하게 알려드리려고 합니다.&amp;nbsp; 저도 처음에 이 문제 때문에 몇 시간이고 끙끙댔던 기억이 나네요  &amp;nbsp; 하지만 이제 걱정 끝! 이 글을 읽고 나면 Dialog 안에서 데이터 변경을 깔끔하게 처리할 수 있을 거예요.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;**문제 상황: 왜 Dialog 안에서 setState가 안될까요?**&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;대부분의 Flutter 개발자들은 화면 업데이트를 위해 `setState`를 사용하는데 익숙하죠. 하지만 Dialog 안에서는 `setState`를 사용해도 화면이 갱신되지 않는 답답한 상황에 직면하게 됩니다.&amp;nbsp; 왜 그럴까요?&amp;nbsp; 간단히 말해, `setState`는 **해당 위젯 트리**를 재빌드하는 역할을 하기 때문입니다. Dialog는 메인 화면의 위젯 트리와는 별개의 트리를 가지고 있어서, Dialog 안에서 `setState`를 호출해도 메인 화면의 `setState`만 호출되는 겁니다.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;**해결 방법: StatefulBuilder를 활용하세요! ✨**&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;자, 이제 해결책을 알려드릴게요! 바로 `StatefulBuilder` 위젯을 사용하는 겁니다.&amp;nbsp; `StatefulBuilder`는 자신만의 독립적인 상태를 관리하고, 내부에서 `StateSetter`를 이용해 UI를 업데이트할 수 있도록 해줍니다.&amp;nbsp; 말로만 설명하면 어려우니, 바로 코드로 보여드릴게요!&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;**1. 프로젝트 구조**&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;먼저 프로젝트를 다음과 같이 구성해 봅시다. 간단하게 `main.dart`, `alter_dialog.dart`, `basic_button.dart` 세 개의 파일로 구성했습니다.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;**2. main.dart**&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;```dart&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;import 'package:flutter/material.dart';&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;import 'alter_dialog.dart';&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;void main() {&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;runApp(const MyApp());&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;}&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;class MyApp extends StatelessWidget {&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;const MyApp({super.key});&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;@override&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;Widget build(BuildContext context) {&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return MaterialApp(&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title: 'Flutter Demo',&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;theme: ThemeData(&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;primarySwatch: Colors.blue,&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;),&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;home: const DialogSetState(),&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;}&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;}&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;class DialogSetState extends StatefulWidget {&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;const DialogSetState({super.key});&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;@override&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;State&amp;lt;DialogSetState&amp;gt; createState() =&amp;gt; _DialogSetStateState();&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;}&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;class _DialogSetStateState extends State&amp;lt;DialogSetState&amp;gt; {&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;int goalCount = 0;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;@override&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;Widget build(BuildContext context) {&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return Scaffold(&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;appBar: AppBar(&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title: const Text('Dialog SetState Example'),&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;),&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;body: Center(&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;child: ElevatedButton(&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onPressed: () =&amp;gt; alterDialogSetState(&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;goalCount: goalCount,&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;context: context,&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;closePressed: () {&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;setState(() {&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// Dialog 닫을 때 메인 화면의 상태 업데이트 (필요에 따라 추가)&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Navigator.pop(context);&amp;nbsp;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;),&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;child: const Text('Show Dialog'),&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;),&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;),&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;}&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;}&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;```&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;**3. alter_dialog.dart (핵심!)**&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;```dart&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;import 'package:flutter/material.dart';&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;// 재사용 가능한 버튼 위젯&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;Widget basicTextButton({required String buttonText, required VoidCallback onPressed}) {&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;return TextButton(&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onPressed: onPressed,&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;child: Text(buttonText, style: const TextStyle(fontSize: 15)),&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;);&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;}&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;alterDialogSetState({&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;required BuildContext context,&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;required Function() closePressed,&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;required int goalCount,&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;}) {&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;showDialog(&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;context: context,&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;builder: (context) =&amp;gt; StatefulBuilder( // StatefulBuilder 사용!&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;builder: (BuildContext context, StateSetter setDialog) { // StateSetter 받아오기&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return AlertDialog(&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title: const Text('Goal Counter'),&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;content: Column(&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mainAxisSize: MainAxisSize.min,&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;children: [&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Image.asset(&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;'assets/son.png', // 이미지 경로 설정&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;width: 120,&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;height: 100,&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;),&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;basicTextButton(&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;buttonText: 'Goal!',&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onPressed: () {&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;setDialog(() { // StateSetter 사용하여 상태 업데이트&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;goalCount++;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;),&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Text('Goal Count: $goalCount'),&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;],&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;),&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;actions: [&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;basicTextButton(buttonText: 'Close', onPressed: closePressed),&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;],&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;),&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;);&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;}&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;```&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;**4. assets/son.png**&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;`pubspec.yaml` 파일에 assets를 추가하고, assets 폴더에 적절한 이미지를 추가하세요. 예를 들어, 축구 선수 사진을 사용할 수 있습니다.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;```yaml&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;flutter:&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;assets:&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- assets/son.png&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;```&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;**핵심 코드 설명:**&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;* `StatefulBuilder`: Dialog의 내부 상태를 독립적으로 관리합니다.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;* `StateSetter setDialog`: `StatefulBuilder`에서 제공하는 함수로, Dialog 내부의 상태를 변경하고 UI를 업데이트합니다.&amp;nbsp; `setDialog(() { ... });` 안에서 상태 변경 로직을 작성하면 됩니다.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;**실행 결과 GIF**&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;(여기에 실행 결과 GIF를 삽입하세요.&amp;nbsp; 위에 제공된 GIF 링크를 사용하거나, 직접 실행하여 GIF를 생성하여 삽입하면 됩니다.)&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;**결론:**&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;`StatefulBuilder`와 `StateSetter`를 사용하면 Dialog 안에서도 깔끔하게 데이터를 업데이트하고 화면을 갱신할 수 있습니다.&amp;nbsp; 이제 Dialog 안에서 setState 때문에 고민할 필요가 없겠죠?&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/54</guid>
      <comments>https://techsuda.tistory.com/entry/Flutter-%EB%8C%80%ED%99%94%EC%83%81%EC%9E%90%EC%97%90%EC%84%9C-setState-%EC%82%AC%EC%9A%A9#entry54comment</comments>
      <pubDate>Sat, 31 May 2025 21:27:37 +0900</pubDate>
    </item>
    <item>
      <title>[Flutter] RestfulAPI 호출 방법 (Debugging &amp;amp; Release Mode)</title>
      <link>https://techsuda.tistory.com/entry/Flutter-RestfulAPI-%ED%98%B8%EC%B6%9C-%EB%B0%A9%EB%B2%95-Debugging-Release-Mode</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Flutter 빌드 모드: 개발부터 배포까지, 어떤 모드를 선택해야 할까요?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;오늘은 Flutter 개발에서 빼놓을 수 없는 중요한 주제, 바로 **빌드 모드**에 대해 알아보는 시간을 갖도록 하겠습니다.&amp;nbsp; Flutter는 앱을 빌드할 때 개발 단계에 따라 `디버그`, `프로필`, `릴리스` 세 가지 모드를 제공하고, 테스트를 위한 `헤드리스` 모드도 지원합니다.&amp;nbsp; 어떤 모드를 선택해야 할지 고민이시라구요?&amp;nbsp; 걱정 마세요!&amp;nbsp; 지금부터 친절하게 설명해 드릴게요!  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;### 1. 핫 리로드의 친구, 개발 모드: 디버그 모드  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;개발 중이라면 단연 **디버그 모드**가 최고의 선택입니다!&amp;nbsp;  &amp;nbsp; 이 모드는 핫 리로드를 지원하여 코드 변경 후 바로 결과를 확인할 수 있도록 최적화되어 있습니다.&amp;nbsp; 덕분에 개발 속도가 엄청나게 빨라지죠!&amp;nbsp; 하지만 속도가 빠른 대신 앱의 크기가 커지고 실행 속도가 느릴 수 있다는 점은 감안해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**디버그 모드의 특징:**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **어설션 활성화:**&amp;nbsp; 코드 오류를 쉽게 찾을 수 있도록 도와줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **서비스 확장 활성화:**&amp;nbsp; 디버깅을 위한 추가 기능들을 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **빠른 개발 주기:** 핫 리로드를 통해 빠르게 코드 수정 및 테스트가 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **소스 수준 디버깅 지원:** DevTools와 같은 디버깅 도구를 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**Android Studio에서 디버그 모드 실행:**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;`실행 &amp;gt; 디버그...` 메뉴 또는 프로젝트 페이지의 녹색 버그 아이콘을 클릭하세요!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**코드 예시 (Flutter 실행 명령):**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```bash&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;flutter run&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(기본적으로 `flutter run` 명령어는 디버그 모드로 실행됩니다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;![디버그 모드 실행 화면 예시](debug_mode_screenshot.png)&amp;nbsp; *(여기에 Android Studio의 디버그 실행 버튼 이미지를 넣어주세요)*&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;### 2. 성능 분석의 핵심, 프로파일 모드  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;앱의 성능을 분석하고 최적화하고 싶다면 **프로필 모드**를 사용하세요!&amp;nbsp;  &amp;nbsp; 프로필 모드는 릴리스 모드에 가까운 성능을 보여주면서도 성능 분석에 필요한 정보들을 제공합니다.&amp;nbsp; 에뮬레이터나 시뮬레이터에서는 실제 성능을 정확하게 반영하지 못하기 때문에 실제 기기에서 프로필 모드로 테스트하는 것이 중요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**프로필 모드의 특징:**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **어느 정도의 디버깅 기능 유지:**&amp;nbsp; 오류를 찾는 데 필요한 최소한의 기능은 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **성능 오버레이 활성화:**&amp;nbsp; 실행 중인 앱의 성능을 실시간으로 모니터링할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **추적 활성화:**&amp;nbsp; 앱의 성능 병목 현상을 찾는 데 도움이 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **트리 셰이킹:** 불필요한 코드 제거로 앱 크기 최소화&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**Android Studio에서 프로필 모드 실행:**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;`실행 &amp;gt; 프로필...` 메뉴를 사용하세요!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**코드 예시 (Flutter 실행 명령):**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```bash&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;flutter run --profile&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**DevTools 활용:**&amp;nbsp; 프로필 모드에서 얻은 데이터를 DevTools를 이용하여 분석하고 성능을 개선해 보세요!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;![프로필 모드 실행 및 DevTools 분석 화면 예시](profile_mode_screenshot.png) *(여기에 Android Studio의 프로필 실행 버튼 이미지와 DevTools 화면 이미지를 넣어주세요)*&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;### 3. 최적화의 완성, 배포 모드: 릴리스 모드  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;앱 출시를 앞두고 있다면 **릴리스 모드**가 정답입니다!  &amp;nbsp; 릴리스 모드는 앱의 크기를 최소화하고 실행 속도를 최대화하기 위해 코드를 최적화합니다.&amp;nbsp; 디버깅 정보는 제거되고, 어설션은 비활성화됩니다.&amp;nbsp; 에뮬레이터나 시뮬레이터에서는 실행되지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**릴리스 모드의 특징:**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **어설션 비활성화:**&amp;nbsp; 오류 검사 기능을 제거하여 앱의 크기와 실행 속도를 향상시킵니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **디버깅 정보 제거:**&amp;nbsp; 디버깅에 필요한 정보를 제거하여 앱의 크기를 줄입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **최적화된 컴파일:**&amp;nbsp; 앱의 실행 속도와 크기를 최적화합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **서비스 확장 비활성화:**&amp;nbsp; 불필요한 기능을 제거합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **코드 축소 및 트리 셰이킹:** 불필요한 코드 제거로 앱 크기 최소화&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**Android Studio에서 릴리스 모드 빌드:**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;`빌드 &amp;gt; flavor 선택 &amp;gt; 릴리스` 메뉴를 통해 빌드하거나, `실행 &amp;gt; 실행...` 메뉴의 실행 버튼을 사용하세요.&amp;nbsp; (버튼의 아이콘은 일반 실행 버튼입니다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**코드 예시 (Flutter 실행 및 빌드 명령):**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```bash&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;flutter run --release&amp;nbsp; // 실행&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;flutter build apk --release // 안드로이드 릴리스 빌드 (APK 생성)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;flutter build ios --release // iOS 릴리스 빌드&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;![릴리스 모드 빌드 화면 예시](release_mode_screenshot.png) *(여기에 Android Studio의 릴리스 빌드 관련 화면 이미지를 넣어주세요)*&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;### 4. 숨겨진 영웅, 헤드리스 테스트 모드  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;마지막으로,&amp;nbsp; **헤드리스 테스트 모드**는 UI 없이 자동화된 테스트를 실행할 때 사용합니다.&amp;nbsp; 자동화된 테스트를 통해 앱의 안정성을 높이고 버그를 조기에 발견하는 데 도움이 됩니다.&amp;nbsp; 자세한 내용은 Flutter의 공식 문서를 참고하세요!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이제 Flutter 빌드 모드에 대해 잘 이해하셨나요?&amp;nbsp; 각 모드의 특징을 잘 파악하고 개발 단계에 맞는 모드를 선택하여 효율적인 개발을 진행하시길 바랍니다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/53</guid>
      <comments>https://techsuda.tistory.com/entry/Flutter-RestfulAPI-%ED%98%B8%EC%B6%9C-%EB%B0%A9%EB%B2%95-Debugging-Release-Mode#entry53comment</comments>
      <pubDate>Sat, 31 May 2025 21:26:08 +0900</pubDate>
    </item>
    <item>
      <title>[Docker / NginX] Docker 와 NginX</title>
      <link>https://techsuda.tistory.com/entry/Docker-NginX-Docker-%EC%99%80-NginX</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Docker와 Nginx를 활용한 Reverse Proxy 구축 및 다중 애플리케이션 배포 전략&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**초록:** 본 논문에서는 Docker와 Nginx를 활용하여 다중 애플리케이션(Spring Boot, React)을 배포하고, Nginx를 Reverse Proxy로 활용하여 효율적인 트래픽 라우팅을 구현하는 과정을 상세히 기술한다.&amp;nbsp; Ubuntu 22.04 LTS 개발 환경과 Debian 기반 가상 머신(VM) 환경에서의 실제 구축 과정과 발생 가능한 문제점 및 해결 방안을 제시하며,&amp;nbsp; Dockerfile 작성, 이미지 빌드 및 배포, Nginx 설정 등의 구체적인 단계를 소스 코드와 함께 제시한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**1. 서론**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;현대적인 웹 애플리케이션 개발 환경에서는 Docker와 Nginx의 활용이 필수적이다. Docker는 애플리케이션의 컨테이너화를 통해 개발, 배포, 운영 환경의 일관성을 유지하며, Nginx는 Reverse Proxy 및 로드 밸런싱 기능을 제공하여 안정적이고 효율적인 서비스 운영을 가능하게 한다. 본 연구에서는 Spring Boot와 React 애플리케이션을 Docker로 컨테이너화하고, Nginx를 이용하여 Reverse Proxy를 구축하는 과정을 실제 구현 사례를 바탕으로 자세히 논의한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**2. 연구 환경 및 설계**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **개발 환경:** Ubuntu 22.04 LTS&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **배포 환경:** Debian 기반 가상 머신(VM), IP: 192.168.0.160&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **애플리케이션:** Spring Boot (Port 8080), React (Port 3000, 8082), Node.js (Port 8083)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **도구:** Docker, Docker Compose, Nginx&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**3. Docker 설치 및 이미지 구축**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Debian 기반 VM에 Docker를 설치하는 과정은 다음과 같다.&amp;nbsp; 각 명령어는 실제 실행 결과와 함께 제시된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(1) 시스템 업데이트 및 필수 패키지 설치**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```bash&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sudo apt-get update&amp;nbsp; # 패키지 목록 업데이트&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sudo apt-get upgrade&amp;nbsp; # 시스템 업그레이드&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sudo apt-get install ca-certificates curl gnupg lsb-release&amp;nbsp; # Docker 설치에 필요한 패키지 설치&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(2) Docker GPG 키 추가 및 저장소 설정**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```bash&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sudo mkdir -p /etc/apt/keyrings&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;curl -fsSL &lt;a href=&quot;https://download.docker.com/linux/debian/gpg&quot;&gt;https://download.docker.com/linux/debian/gpg&lt;/a&gt; | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;echo 'deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] &lt;a href=&quot;https://download.docker.com/linux/debian&quot;&gt;https://download.docker.com/linux/debian&lt;/a&gt; $(lsb_release -cs) stable' | sudo tee /etc/apt/sources.list.d/docker.list &amp;gt; /dev/null&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(3) Docker 엔진 설치 및 서비스 관리**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```bash&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sudo apt-get update&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sudo systemctl start docker&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sudo systemctl enable docker&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(4) 설치 확인:** `sudo docker run hello-world` 명령어를 실행하여 &quot;Hello from Docker!&quot; 메시지 출력 확인&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(5) Dockerfile 작성 및 이미지 빌드**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **Node.js 애플리케이션 Dockerfile (Dockerfile_node.txt)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```dockerfile&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;FROM node:18&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;WORKDIR /app&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;COPY package*.json ./&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RUN npm install&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;COPY . .&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;EXPOSE 8083&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;CMD ['node', 'app.js']&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **Spring Boot 애플리케이션 Dockerfile (Dockerfile_spring.txt)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```dockerfile&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;FROM openjdk:18-jdk-alpine&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;WORKDIR /app&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;COPY target/my-spring-boot-app.jar my-spring-boot-app.jar&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ENTRYPOINT [&quot;java&quot;,&quot;-jar&quot;,&quot;my-spring-boot-app.jar&quot;]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;EXPOSE 8080&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이미지 빌드는 다음 명령어를 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```bash&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker build -t my-node-app .&amp;nbsp; # Node.js 애플리케이션 이미지 빌드&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker build -t my-spring-boot-app . # Spring Boot 애플리케이션 이미지 빌드&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(6) 이미지 배포:**&amp;nbsp; 로컬에서 생성된 Docker 이미지를 VM으로 전송하기 위해 `docker save` 및 `scp` 명령어를 사용하여 tar 파일로 저장 후 전송한다. VM에서는 `docker load` 명령어로 이미지를 로드한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**4. Nginx Reverse Proxy 설정**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;VM에 Nginx를 설치하고 `/etc/nginx/sites-available/default` 파일을 다음과 같이 수정한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```nginx&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;server {&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;listen 1000;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;server_name 192.168.0.160;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;location / {&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_pass http://localhost:8083; # Node.js 애플리케이션&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;server {&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;listen 1001;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;server_name 192.168.0.160;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;location / {&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_pass http://localhost:8080; # Spring Boot 애플리케이션&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;server {&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;listen 1002;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;server_name 192.168.0.160;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;location / {&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_pass http://localhost:8082; # React 애플리케이션 2&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Nginx 설정을 테스트하고 재시작한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```bash&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sudo nginx -t&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sudo systemctl restart nginx&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(7) Docker 컨테이너 실행:**&amp;nbsp; 각 애플리케이션을 Docker 컨테이너로 실행한다.&amp;nbsp; (예: `docker run -d -p 8080:8080 --name spring-boot-app my-spring-boot-app`)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**5. 결과 및 고찰**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;브라우저에서 다음 주소를 통해 각 애플리케이션에 접속하여 정상 동작 여부를 확인한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* `http://192.168.0.160:1000/` (Node.js)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* `http://192.168.0.160:1001/` (Spring Boot)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* `http://192.168.0.160:1002/` (React)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(이미지 삽입:&amp;nbsp; React, SpringBoot 결과 화면)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;본 연구에서는 Docker와 Nginx를 활용하여 다중 애플리케이션을 효율적으로 배포하고 관리하는 방법을 제시하였다.&amp;nbsp; 하지만 데이터베이스 연동 및 아키텍처 설계 부분에 대한 추가적인 연구가 필요하다.&amp;nbsp; 특히, 데이터베이스를 Docker 컨테이너로 운영하고 애플리케이션과의 연결을 구성하는 것은 향후 과제이다.&amp;nbsp; 또한,&amp;nbsp; 보다 안정적이고 확장 가능한 시스템 구축을 위해서는 로드 밸런싱, 모니터링, 로그 관리 등에 대한 고려가 필요하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(Node.js, Spring Boot, React 애플리케이션 아키텍처 다이어그램 삽입)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**6. 결론**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;본 연구를 통해 Docker와 Nginx를 활용한 Reverse Proxy 구축 및 다중 애플리케이션 배포 전략을 성공적으로 구현하였다.&amp;nbsp; 실제 환경에서의 적용을 통해 얻은 경험은 향후 더욱 복잡하고 확장 가능한 시스템 개발에 귀중한 자산이 될 것이다.&amp;nbsp; 향후 연구에서는 데이터베이스 통합 및&amp;nbsp; 더욱 발전된 아키텍처 설계를 통해 시스템의 안정성과 확장성을 향상시키는 데 집중할 계획이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/52</guid>
      <comments>https://techsuda.tistory.com/entry/Docker-NginX-Docker-%EC%99%80-NginX#entry52comment</comments>
      <pubDate>Sat, 31 May 2025 21:25:00 +0900</pubDate>
    </item>
    <item>
      <title>[Docker / NginX] 하나의 Domain을 Multi Site로 운영</title>
      <link>https://techsuda.tistory.com/entry/Docker-NginX-%ED%95%98%EB%82%98%EC%9D%98-Domain%EC%9D%84-Multi-Site%EB%A1%9C-%EC%9A%B4%EC%98%81</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a title=&quot;이곳으로 글을 옮겼습니다.&quot; href=&quot;https://techsuda.tistory.com/71&quot; rel=&quot;noopener&quot;&gt;https://techsuda.tistory.com/71&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;&lt;b&gt;하나의 Docker 컨테이너로 무한한 웹사이트 운영의 세계를 경험하세요&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;요즘 웹 개발은 멀티사이트 운영 없이는 살아남기 힘든 시대입니다.&amp;nbsp; 개발 환경, 테스트 환경, 심지어는 여러 개의 서비스를 동시에 운영해야 할 경우도 많죠.&amp;nbsp; 이럴 때마다 서버를 여러 대 띄워야 한다면?&amp;nbsp; 비용과 관리의 부담은 상상을 초월할 겁니다.&amp;nbsp; 하지만 오늘, 여러분의 고민을 해결해 줄 혁신적인 방법을 소개합니다! 바로 Docker와 Nginx를 활용한 멀티사이트 운영입니다.&amp;nbsp; 단 하나의 Nginx 컨테이너로 여러 웹사이트를 효율적으로 관리하는 마법을 함께 경험해보시죠.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;**1. Nginx 가상 호스트:&amp;nbsp; 한 서버, 여러 웹사이트의 마술**&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;Nginx는 웹 서버이자 강력한 리버스 프록시 역할도 수행하는 만능 도구입니다.&amp;nbsp; 핵심은 바로 &quot;가상 호스트(Virtual Hosts)&quot; 기능입니다.&amp;nbsp; 가상 호스트는 단 하나의 서버에서 여러 웹사이트를 운영할 수 있도록 해주는 기술이죠.&amp;nbsp; 마치 한 건물에 여러 개의 사무실이 있는 것과 같습니다.&amp;nbsp; Nginx는 포트 기반 또는 도메인 기반으로 가상 호스트를 설정할 수 있습니다.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;**(이미지 삽입:&amp;nbsp; 한 건물에 여러 사무실이 있는 이미지, 각 사무실은 다른 웹사이트를 나타내도록 함)**&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;**포트 기반 가상 호스트:**&amp;nbsp; 각 웹사이트에 다른 포트 번호를 할당하여 구분하는 방식입니다.&amp;nbsp; 예를 들어,&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;* `http://localhost:8081`:&amp;nbsp; 사이트 1&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;* `http://localhost:8082`:&amp;nbsp; 사이트 2&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;* `http://localhost:8083`:&amp;nbsp; 사이트 3&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;**도메인 기반 가상 호스트:**&amp;nbsp; 각 웹사이트에 다른 도메인 이름을 할당하여 구분하는 방식입니다. (이 부분은 후속 포스팅에서 자세히 다루겠습니다.)&amp;nbsp; 예를 들어,&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;* `&lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;http://site1.example.com&quot;&gt;http://site1.example.com&lt;/a&gt;`:&amp;nbsp; 사이트 1&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;* `&lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;http://site2.example.com&quot;&gt;http://site2.example.com&lt;/a&gt;`:&amp;nbsp; 사이트 2&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;* `&lt;a style=&quot;color: #9d9d9d;&quot; href=&quot;http://site3.example.com&quot;&gt;http://site3.example.com&lt;/a&gt;`:&amp;nbsp; 사이트 3&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;**2. 실전 투입! Docker와 Nginx를 이용한 멀티사이트 설정**&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;이제 본격적으로 Docker와 Nginx를 이용하여 멀티사이트를 구축하는 과정을 살펴보겠습니다.&amp;nbsp; 포트 기반 가상 호스트를 예시로 설명합니다.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;**1) 웹사이트 디렉토리 및 파일 생성:**&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;먼저, 각 웹사이트를 위한 디렉토리를 생성하고, 간단한 `index.html` 파일을 만들어 봅시다. 다음 명령어를 사용합니다.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;```bash&lt;br /&gt;mkdir -p /c/docker-nginx/web/site1&lt;br /&gt;mkdir -p /c/docker-nginx/web/site2&lt;br /&gt;mkdir -p /c/docker-nginx/web/site3&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;echo '&amp;lt;h1&amp;gt;Site 1&amp;lt;/h1&amp;gt;' &amp;gt; /c/docker-nginx/web/site1/index.html&lt;br /&gt;echo '&amp;lt;h1&amp;gt;Site 2&amp;lt;/h1&amp;gt;' &amp;gt; /c/docker-nginx/web/site2/index.html&lt;br /&gt;echo '&amp;lt;h1&amp;gt;Site 3&amp;lt;/h1&amp;gt;' &amp;gt; /c/docker-nginx/web/site3/index.html&lt;br /&gt;```&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;**2) Nginx 설정 파일 수정:**&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;Nginx 설정 파일(`/etc/nginx/nginx.conf`)을 수정하여 각 포트에 대한 가상 호스트를 정의해야 합니다.&amp;nbsp; 다음은 `nginx.conf` 파일의 예시입니다.&amp;nbsp; `/c/docker-nginx/conf` 디렉토리에 `nginx.conf` 파일을 생성하고 아래 내용을 작성합니다.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;```nginx&lt;br /&gt;worker_processes 1;&lt;br /&gt;&lt;b&gt;&lt;/b&gt;events {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;worker_connections 1024;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;/b&gt;http {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;include &amp;nbsp; &amp;nbsp; &amp;nbsp; mime.types;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sendfile&amp;nbsp; &amp;nbsp; &amp;nbsp; on;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;/b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# Site 1 (포트 8081)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;server {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;listen 8081;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;server_name localhost;&lt;b&gt;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;location / {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root /web/site1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;index index.html;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# Site 2 (포트 8082)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;server {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;listen 8082;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;server_name localhost;&lt;b&gt;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;location / {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root /web/site2;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;index index.html;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# Site 3 (포트 8083)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;server {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;listen 8083;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;server_name localhost;&lt;b&gt;&lt;/b&gt;&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;location / {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root /web/site3;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;index index.html;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;```&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;**3) Docker 컨테이너 실행:**&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;다음 명령어를 사용하여 Nginx 컨테이너를 실행합니다.&amp;nbsp; `-v` 옵션을 통해 호스트의 디렉토리를 컨테이너 내부에 마운트하여 설정 파일과 웹사이트 파일을 공유합니다.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;```bash&lt;br /&gt;docker run -d --name nginx-multisite -p 8081:8081 -p 8082:8082 -p 8083:8083 \&lt;br /&gt;&amp;nbsp;&amp;nbsp;-v /c/docker-nginx/conf/nginx.conf:/etc/nginx/nginx.conf \&lt;br /&gt;&amp;nbsp;&amp;nbsp;-v /c/docker-nginx/web:/web \&lt;br /&gt;&amp;nbsp;&amp;nbsp;nginx:latest&lt;br /&gt;```&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;**(이미지 삽입: Docker 컨테이너가 실행되는 시각적인 이미지)**&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;**4) 설정 확인 및 브라우저 테스트:**&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;`docker ps` 명령어를 통해 컨테이너가 정상적으로 실행되었는지 확인하고, 브라우저에서 `http://localhost:8081`, `http://localhost:8082`, `http://localhost:8083`으로 접속하여 각 웹사이트가 정상적으로 작동하는지 확인합니다.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;**3. 장점과 활용 사례:&amp;nbsp; 멀티사이트 운영의 새로운 지평**&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;이 방법의 장점은 무엇일까요?&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;* **단일 컨테이너 관리:**&amp;nbsp; 여러 웹사이트를 단 하나의 Docker 컨테이너로 관리할 수 있어 효율적입니다.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;* **환경 격리:**&amp;nbsp; 개발 환경을 오염시키지 않고 안전하게 개발 및 테스트를 진행할 수 있습니다.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;* **빠른 개발/테스트:**&amp;nbsp; 설정 변경 후 바로 결과를 확인할 수 있어 개발 속도를 높일 수 있습니다.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;* **리버스 프록시 활용:**&amp;nbsp; 리버스 프록시 기능을 활용하여 보안 및 성능 향상을 도모할 수 있습니다.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;* **실시간 설정 변경:** Docker 볼륨을 이용해 설정 파일을 실시간으로 변경하고 적용할 수 있습니다.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;&lt;br /&gt;**활용 사례:**&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;* 프론트엔드, 백엔드, API 서버 등 다양한 서비스를 하나의 서버에서 운영&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;* 마이크로서비스 아키텍처(MSA) 환경 구축&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;* 다양한 버전의 웹사이트를 동시에 운영하는 테스트 환경 구축&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;&lt;br /&gt;**결론:&amp;nbsp; Docker와 Nginx로 멀티사이트 운영의 꿈을 이루세요!**&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;이제 Docker와 Nginx를 이용한 멀티사이트 운영의 효율성을 직접 경험하셨을 것입니다. 더 이상 복잡한 서버 관리에 시간을 낭비하지 마세요!&amp;nbsp; Docker와 Nginx를 활용하여 여러분의 웹 개발 역량을 한 단계 더 발전시켜 보세요! &lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/51</guid>
      <comments>https://techsuda.tistory.com/entry/Docker-NginX-%ED%95%98%EB%82%98%EC%9D%98-Domain%EC%9D%84-Multi-Site%EB%A1%9C-%EC%9A%B4%EC%98%81#entry51comment</comments>
      <pubDate>Sat, 31 May 2025 21:23:25 +0900</pubDate>
    </item>
    <item>
      <title>[Python] System에 반복 및 예약 실행 설정 (Scheduler)</title>
      <link>https://techsuda.tistory.com/entry/Python-System%EC%97%90-%EB%B0%98%EB%B3%B5-%EB%B0%8F-%EC%98%88%EC%95%BD-%EC%8B%A4%ED%96%89-%EC%84%A4%EC%A0%95-Scheduler</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a title=&quot;글 내용을 이곳으로 이동했습니다.&quot; href=&quot;https://techsuda.tistory.com/73&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;내용을 이곳으로 이동했습니다.&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;b&gt;파이썬 스케줄러의 꽃, APScheduler로 시간 여행을 떠나요! &lt;/b&gt;&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;오늘은 여러분의 파이썬 코드에 마법 같은 시간 관리 기능을 불어넣어 줄 APScheduler(Advanced Python Scheduler)에 대해 이야기 나눠볼까 합니다. APScheduler의 매력에 흠뻑 빠져 볼까요?&amp;nbsp; ☕️&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;APScheduler는 마치 정교한 시계 장치와 같아요. 여러분의 파이썬 애플리케이션에서 특정 시간이나 주기에 맞춰 작업을 자동으로 실행시켜주는 강력한 도구죠.&amp;nbsp; 작은 규모의 작업부터 분산된 작업까지, 다양한 상황에 유연하게 대처할 수 있답니다.&amp;nbsp; 복잡한 시스템을 구축하는데 필요한 핵심 부품이라고 생각하면 될 것 같아요.&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;**APScheduler의 심장: 네 가지 핵심 요소**&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;APScheduler는 크게 네 가지 중요한 요소로 이루어져 있어요. 마치 잘 만들어진 오케스트라처럼, 각 요소가 조화롭게 작동해야 아름다운 선율, 즉 완벽한 스케줄링을 만들어낼 수 있답니다.&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;1. **Triggers (트리거):** 작업의 시작 시간을 정의하는 부분이에요.&amp;nbsp; 다양한 종류의 트리거가 있어서, 여러분의 필요에 맞춰 자유롭게 설정할 수 있죠.&amp;nbsp; 마치 악보의 박자표처럼, 작업의 시작 시점을 정확하게 알려주는 역할을 해요.&amp;nbsp; Cron 표현식, 일정 간격, 특정 날짜 등 다양한 방법으로 작업 실행 시점을 설정할 수 있습니다.&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;2. **Job Stores (잡 스토어):** 예약된 작업들의 상태를 저장하고 관리하는 저장소입니다.&amp;nbsp; 작업이 언제 실행될 예정인지, 이미 실행되었는지, 오류가 발생했는지 등의 정보를 안전하게 보관해주는 데이터베이스와 같은 역할을 하죠.&amp;nbsp; 마치 오케스트라의 악보 보관함과 같다고 할 수 있겠네요.&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;3. **Executors (실행기):** 실제로 작업을 실행하는 부분이에요.&amp;nbsp; 스레드나 프로세스 풀을 사용하여 여러 작업을 동시에 또는 순차적으로 처리할 수 있답니다.&amp;nbsp; 마치 오케스트라의 지휘자처럼, 각 악기(작업)들이 제때 연주(실행)되도록 관리해주죠.&amp;nbsp; 작업 완료를 스케줄러에 알리고, 필요한 이벤트를 전송하는 역할도 수행합니다.&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;4. **Schedulers (스케줄러):**&amp;nbsp; 스케줄링된 작업들을 관리하고 실행하는 중추적인 역할을 합니다.&amp;nbsp; 다양한 종류의 스케줄러가 있어서, 여러분의 애플리케이션 환경에 맞게 선택할 수 있답니다.&amp;nbsp; 마치 오케스트라의 지휘대처럼, 전체적인 스케줄링을 관리하고 조율하는 역할을 수행하죠.&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;**스케줄러의 종류:**&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;APScheduler는 다양한 스케줄러를 제공합니다. 각 스케줄러는 각기 다른 특징을 가지고 있으니, 여러분의 애플리케이션에 맞는 스케줄러를 선택하는 것이 중요합니다.&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;* **BlockingScheduler:** 단일 스케줄러로, 애플리케이션의 메인 스레드에서 실행됩니다.&amp;nbsp; 간단한 작업에 적합하지만, 메인 스레드를 차단하기 때문에 다른 작업을 처리할 수 없다는 단점이 있어요.&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;* **BackgroundScheduler:** 가장 일반적으로 사용되는 스케줄러로, 백그라운드 스레드에서 실행됩니다. 메인 스레드를 차단하지 않아 다른 작업을 병행 처리할 수 있어요.&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;* **AsyncIOScheduler, GeventScheduler, TornadoScheduler, TwistedScheduler, QtScheduler:** 비동기 프로그래밍 환경에서 사용되는 스케줄러입니다.&amp;nbsp; 각각 Asyncio, Gevent, Tornado, Twisted, Qt 프레임워크와 통합되어 사용됩니다.&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;**(이미지 삽입: 각 스케줄러의 특징을 비교하는 표)**&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;**실제로 APScheduler를 사용해 볼까요?**&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;이제 간단한 예제를 통해 APScheduler를 사용하는 방법을 알아볼까요?&amp;nbsp; 마치 요리 레시피처럼, 단계별로 따라 해보면 어렵지 않아요!&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;**1. 설치:**&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;```bash&lt;br /&gt;pip install apscheduler&lt;br /&gt;```&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;**2. 스케줄러 생성 및 작업 추가:**&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;```python&lt;br /&gt;from apscheduler.schedulers.background import BackgroundScheduler&lt;br /&gt;import time&lt;br /&gt;def my_job():&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&quot;Hello, APScheduler!&quot;)&lt;br /&gt;&lt;b&gt;&lt;/b&gt;scheduler = BackgroundScheduler()&lt;br /&gt;scheduler.add_job(my_job, 'interval', seconds=5) # 5초마다 my_job 함수 실행&lt;br /&gt;scheduler.start()&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;try:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while True:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;time.sleep(1)&lt;br /&gt;except (KeyboardInterrupt, SystemExit):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;scheduler.shutdown()&lt;br /&gt;```&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;이 코드는 5초마다 `my_job` 함수를 실행하는 간단한 스케줄러를 만듭니다.&amp;nbsp; `add_job` 함수의 첫 번째 인자는 실행할 함수, 두 번째 인자는 트리거 타입, 세 번째 인자는 트리거 설정입니다.&amp;nbsp; 여기서는 `interval` 트리거를 사용하여 5초 간격으로 작업을 실행하도록 설정했어요.&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;**3. 다양한 트리거 사용하기:**&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;* **CronTrigger:**&amp;nbsp; Linux/Unix의 cron 표현식을 사용하여 복잡한 스케줄을 설정할 수 있어요.&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;```python&lt;br /&gt;&lt;span style=&quot;text-align: start;&quot;&gt;# 월요일부터 금요일까지 오전 10시 30분에 실행&lt;/span&gt; &lt;br /&gt;scheduler.add_job(my_job, 'cron', day_of_week='mon-fri', hour=10, minute=30)&lt;br /&gt;```&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;* **DateTrigger:** 특정 날짜에 한 번만 작업을 실행할 때 사용해요.&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;```python&lt;br /&gt;from datetime import datetime&lt;br /&gt;&lt;span style=&quot;text-align: start;&quot;&gt;# 2024년 1월 1일 12시에 실행&lt;/span&gt; &lt;br /&gt;scheduler.add_job(my_job, 'date', run_date=datetime(2024, 1, 1, 12, 0, 0))&lt;br /&gt;```&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;* **IntervalTrigger:** 일정 간격으로 작업을 반복 실행할 때 사용합니다.&amp;nbsp; 위 예제에서 사용한 `interval` 트리거와 같아요.&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;**(이미지 삽입: Cron 표현식 예시와 설명)**&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;**마무리하며...**&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;APScheduler는 파이썬 애플리케이션에 강력한 스케줄링 기능을 추가하는 데 유용한 도구입니다.&amp;nbsp; 다양한 트리거와 스케줄러를 통해 여러분의 필요에 맞는 스케줄링 시스템을 구축할 수 있답니다.&amp;nbsp; 이제 여러분의 파이썬 코드에 시간의 마법을 더해보세요!&lt;/span&gt;&lt;/s&gt;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/50</guid>
      <comments>https://techsuda.tistory.com/entry/Python-System%EC%97%90-%EB%B0%98%EB%B3%B5-%EB%B0%8F-%EC%98%88%EC%95%BD-%EC%8B%A4%ED%96%89-%EC%84%A4%EC%A0%95-Scheduler#entry50comment</comments>
      <pubDate>Sat, 31 May 2025 21:18:35 +0900</pubDate>
    </item>
    <item>
      <title>[Flutter] API 호출을 위해 Debugging Mode에서 인증 회피</title>
      <link>https://techsuda.tistory.com/entry/Flutter-API-%ED%98%B8%EC%B6%9C%EC%9D%84-%EC%9C%84%ED%95%B4-Debugging-Mode%EC%97%90%EC%84%9C-%EC%9D%B8%EC%A6%9D-%ED%9A%8C%ED%94%BC</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Flutter API 호출 완전 정복: 삽질은 이제 그만!&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;오늘은 Flutter 개발하면서 늘 마주치는 골칫덩어리, 바로 **API 호출**에 대해 속 시원하게 파헤쳐 보려고 합니다.&amp;nbsp; API 호출, 간단해 보이죠?&amp;nbsp; 하지만 실제로는 네트워크 에러, 서버 장애, 인증 문제 등 온갖 잡것들이 숨어있어서 멘탈 붕괴를 경험하게 만들 수 있습니다.&amp;nbsp; 저도 숱하게 삽질을 했기에&amp;hellip; 이제 여러분은 제 삽질 경험을 통해 똑똑하게 API 호출을 마스터할 수 있을 겁니다!  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**1. 믿을 수 없는 네트워크, 철저한 예외 처리가 답이다!**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;네트워크는 언제나 변수입니다.&amp;nbsp; 끊어질 수도 있고, 서버가 응답하지 않을 수도 있죠.&amp;nbsp; `try-catch` 블록 없이 API 호출을 한다면?&amp;nbsp; 앱 크래시는 순식간입니다.&amp;nbsp; 절대 잊지 마세요!&amp;nbsp; 항상 `try-catch`로 에러를 잡아야 합니다!&amp;nbsp; 그리고 사용자에게는 이해하기 쉬운 에러 메시지를 보여주는 센스!&amp;nbsp; '네트워크 연결을 확인해주세요' 정도면 충분합니다.&amp;nbsp; 그리고 로그? 당연히 남겨야죠!&amp;nbsp; 디버깅의 생명줄입니다.&amp;nbsp; `logger` 패키지를 추천합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```dart&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;import 'package:http/http.dart' as http;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;import 'package:logger/logger.dart';&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;final logger = Logger();&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Future&amp;lt;Map&amp;lt;String, dynamic&amp;gt;?&amp;gt; fetchUserData() async {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;try {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;final response = await http.get(Uri.parse('YOUR_API_ENDPOINT'));&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (response.statusCode == 200) {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return jsonDecode(response.body);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} else {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;logger.e('API 요청 실패: ${response.statusCode}');&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw Exception('API 요청 실패: ${response.statusCode} - ${response.reasonPhrase}');&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;} catch (e) {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;logger.e('API 요청 중 오류 발생: $e');&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 사용자에게 에러 메시지 표시 (예: SnackBar, Dialog)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return null;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(이미지: try-catch 블록을 사용한 예외 처리 과정을 보여주는 다이어그램)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**2. 재시도와 서킷 브레이커: 끈기는 좋지만, 무한정은 안돼!**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;서버가 잠깐 맛이 간 경우, 재시도는 효과적입니다.&amp;nbsp; 하지만 무한정 재시도하면 앱이 멈추는 참사가&amp;hellip;&amp;nbsp; `dio`와 `retry_interceptor` 패키지를 사용하면 최대 재시도 횟수와 시간 제한을 설정할 수 있습니다.&amp;nbsp; 더 나아가 서킷 브레이커를 구현하면 일정 횟수 이상 실패 시 일정 시간 동안 요청을 차단하여 앱을 보호할 수 있습니다.&amp;nbsp; 저는 이 방법 강력 추천합니다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```dart&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;import 'package:dio/dio.dart';&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;import 'package:retry/retry.dart';&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;final dio = Dio();&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Future&amp;lt;Map&amp;lt;String, dynamic&amp;gt;?&amp;gt; fetchDataWithRetry() async {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;try {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;final response = await retry(&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;() =&amp;gt; dio.get('YOUR_API_ENDPOINT'),&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;retryIf: (e) =&amp;gt; e is DioError &amp;amp;&amp;amp; e.response?.statusCode != 200,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;maxAttempts: 3,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;delayFactor: const Duration(seconds: 2),&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return response.data;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;} on DioError catch (e) {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;logger.e('API 요청 실패(재시도 후): ${e.message}');&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return null;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(이미지:&amp;nbsp; retry_interceptor를 이용한 재시도 로직 다이어그램)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**3. DEBOUNCE &amp;amp; THROTTLE:&amp;nbsp; 폭주하는 API 요청, 진정시켜줄게!**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용자 입력마다 API를 호출하면 서버 부하가 엄청납니다.&amp;nbsp; `debounce`는 마지막 입력 후 일정 시간 동안 입력이 없을 때만 호출하고, `throttle`은 일정 주기마다 한 번만 호출합니다.&amp;nbsp; 이 둘은 검색 자동완성이나 실시간 필터링에 필수입니다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(이미지: debounce와 throttle의 비교 다이어그램)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(코드 예시:&amp;nbsp; `rxdart`를 활용한 debounce 및 throttle 구현)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**4. API 호출 시점:&amp;nbsp; 적절한 타이밍을 잡아라!**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;`initState`, `build`, `onTap`&amp;hellip; API 호출 위치가 중요합니다.&amp;nbsp; `initState`에서 호출하면 앱 시작과 동시에 API 요청을 보내게 되는 것이죠.&amp;nbsp; `build`에서 호출하면 UI 렌더링마다 호출됩니다.&amp;nbsp; `FutureBuilder` 또는 `FutureProvider`를 사용하여 API 호출 시점을 명확히 하고 불필요한 호출을 방지할 수 있습니다.&amp;nbsp; `mounted` 체크도 잊지 마세요!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(이미지:&amp;nbsp; API 호출 시점에 따른 UI 렌더링 과정 다이어그램)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(코드 예시: FutureBuilder를 사용한 API 호출)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**5. 로딩 상태 관리:&amp;nbsp; 빙글빙글 돌아가는 인디케이터는 사용자에게 안심을 준다!**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;API 응답이 느리면 사용자는 앱이 멈췄다고 생각합니다.&amp;nbsp; `CircularProgressIndicator`, `Shimmer` 등으로 로딩 상태를 표시하여 사용자에게 피드백을 제공해야 합니다.&amp;nbsp; `riverpod`나 `bloc` 같은 상태 관리 패키지를 활용하면 로딩 상태를 효율적으로 관리할 수 있습니다.&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(이미지: 로딩 인디케이터를 사용한 UI 예시)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(코드 예시: Provider를 사용한 로딩 상태 관리)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(이하 6~10번까지 동일한 형식으로 설명 및 코드, 이미지 추가)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**결론:&amp;nbsp; API 호출은 단순하지 않다!**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Flutter API 호출은 간단해 보이지만, 위에서 살펴본 것처럼 많은 고려사항들이 있습니다.&amp;nbsp; 이 글이 여러분의 Flutter 개발 여정에 도움이 되길 바라며,&amp;nbsp; 더 궁금한 점이 있다면 언제든지 댓글 남겨주세요!&amp;nbsp; 함께 성장해 나가요! &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/49</guid>
      <comments>https://techsuda.tistory.com/entry/Flutter-API-%ED%98%B8%EC%B6%9C%EC%9D%84-%EC%9C%84%ED%95%B4-Debugging-Mode%EC%97%90%EC%84%9C-%EC%9D%B8%EC%A6%9D-%ED%9A%8C%ED%94%BC#entry49comment</comments>
      <pubDate>Sat, 31 May 2025 21:14:59 +0900</pubDate>
    </item>
    <item>
      <title>[Docker / Nginx] Proxy 설정</title>
      <link>https://techsuda.tistory.com/entry/Docker-Nginx-Proxy-%EC%84%A4%EC%A0%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;혼자 공부하는 Docker Nginx Reverse Proxy: 포트와 경로 기반 라우팅 마스터하기&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;오늘은 제가 며칠 밤낮으로 씨름했던 Docker와 Nginx를 이용한 Reverse Proxy 설정에 대한 꿀팁을 공유하려고 합니다.&amp;nbsp; 사실 처음엔 막막했는데, 이제는 제법 자신감이 생겼어요!&amp;nbsp; (뿌듯)&amp;nbsp; 이 글을 통해 여러분도 Reverse Proxy의 세계에 쉽게 발을 들여놓으실 수 있도록, 제가 겪었던 시행착오와 해결 과정을 상세히 설명해 드리겠습니다.&amp;nbsp; 자, 시작해볼까요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;### 1. Reverse Proxy란 무엇일까요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;먼저 Reverse Proxy의 개념을 간단히 짚고 넘어가겠습니다.&amp;nbsp; Forward Proxy가 클라이언트의 외부 네트워크 접근을 중개하는 역할이라면, Reverse Proxy는&amp;nbsp; **여러 개의 내부 서버들을 외부 클라이언트에게 하나의 엔트리 포인트로 보여주는 역할**을 합니다.&amp;nbsp; 마치 여러 개의 방을 가진 건물의 안내데스크 같은 거죠. 클라이언트는 데스크(Reverse Proxy)에 요청하고, 데스크는 요청에 맞는 방(내부 서버)으로 안내해줍니다.&amp;nbsp; 상용 서비스 운영에 필수적인 기술이라고 생각하시면 됩니다.&amp;nbsp; 웹 서버 여러 대를 운영하면서 부하 분산이나 보안 강화에 굉장히 유용하게 쓰이죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;### 2. Docker와 Nginx를 이용한 Reverse Proxy 구현: 포트 기반 라우팅&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자, 이제 본격적으로 Docker와 Nginx를 이용하여 Reverse Proxy를 구현하는 방법을 알려드리겠습니다.&amp;nbsp; 저는 먼저 **포트 기반 라우팅**부터 시작했습니다.&amp;nbsp; 각 내부 서버에 다른 포트를 할당하고, Nginx는 요청받은 포트에 따라 해당 서버로 요청을 전달하도록 설정하는 방식이죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**먼저, 아래와 같이 `docker-compose.yml` 파일을 작성합니다.**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```yaml&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;version: &quot;3.9&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;services:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;nginx:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;image: nginx:latest&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ports:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- &quot;80:80&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- &quot;8081:8081&quot; # 내부 서버 A의 포트&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;volumes:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;depends_on:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- server_a&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- server_b&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;server_a:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;image: nginx:latest&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ports:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- &quot;8081:80&quot; # 내부 서버 A의 포트&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;volumes:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- ./server_a:/usr/share/nginx/html&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp;server_b:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;image: nginx:latest&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ports:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- &quot;8082:80&quot; # 내부 서버 B의 포트 (포트 8081을 사용하는 이유는 나중에 경로 기반 라우팅에서 설명)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;volumes:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- ./server_b:/usr/share/nginx/html&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**그리고 `nginx/nginx.conf` 파일은 다음과 같이 설정합니다.**&amp;nbsp; (이 부분이 가장 중요합니다!)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```nginx&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;upstream backend_a {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;server server_a:80;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;upstream backend_b {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;server server_b:80;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;server {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;listen 80;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;server_name localhost;&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;location / {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_pass http://backend_a;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header Host $host;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header X-Real-IP $remote_addr;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header X-Forwarded-Host $host;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header X-Forwarded-Proto $scheme;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;location /api { # 포트 8081로 요청이 들어왔을 때 서버 A로 전달&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;listen 8081;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_pass http://backend_a;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header Host $host;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header X-Real-IP $remote_addr;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header X-Forwarded-Host $host;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header X-Forwarded-Proto $scheme;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;location /blog { # 포트 8082로 요청이 들어왔을 때 서버 B로 전달&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;listen 8082;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_pass http://backend_b;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header Host $host;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header X-Real-IP $remote_addr;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header X-Forwarded-Host $host;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header X-Forwarded-Proto $scheme;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위 설정에서 중요한 부분은 `upstream` 블록과 `location` 블록입니다. `upstream`은 내부 서버들을 정의하고, `location`은 특정 포트로 들어오는 요청을 어떤 `upstream`으로 전달할지 지정합니다.&amp;nbsp; `proxy_set_header` 지시어는 클라이언트의 IP 주소와 같은 정보를 내부 서버에 전달하는 역할을 합니다.&amp;nbsp; 이 설정이 없으면 내부 서버는 클라이언트의 정보를 알 수 없게 되죠.&amp;nbsp; (로그인 시스템 등을 구현할 때 중요합니다!)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(그림1) docker-compose.yml 파일 예시 이미지 삽입**&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(그림2) nginx/nginx.conf 파일 예시 이미지 삽입**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;### 3. Docker와 Nginx를 이용한 Reverse Proxy 구현: 경로 기반 라우팅&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;포트 기반 라우팅은 간단하지만, 서버 수가 많아지면 관리하기 어렵습니다.&amp;nbsp; 그래서 저는 **경로 기반 라우팅**도 시도해봤습니다.&amp;nbsp; 이 방법은 URL 경로에 따라 다른 내부 서버로 요청을 전달하는 방식입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이번에는 `docker-compose.yml` 파일은 위와 동일하게 사용하고, `nginx/nginx.conf` 파일을 아래와 같이 수정합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```nginx&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;upstream backend_a {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;server server_a:80;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;upstream backend_b {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;server server_b:80;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;server {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;listen 80;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;server_name localhost;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;location /blog {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000; letter-spacing: 0px;&quot;&gt;&amp;nbsp; &amp;nbsp; proxy_pass http://backend_a;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header Host $host;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header X-Real-IP $remote_addr;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header X-Forwarded-Host $host;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header X-Forwarded-Proto $scheme;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;location /community {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_pass http://backend_b;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header Host $host;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header X-Real-IP $remote_addr;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header X-Forwarded-Host $host;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header X-Forwarded-Proto $scheme;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이제 `/blog` 경로로 접근하면 `backend_a` (서버 A), `/community` 경로로 접근하면 `backend_b` (서버 B)로 요청이 전달됩니다.&amp;nbsp; 훨씬 간결하고 관리하기 쉽죠?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(그림3) 수정된 nginx/nginx.conf 파일 예시 이미지 삽입**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;### 4. 경로 재작성 (Rewrite)을 이용한 고급 라우팅&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;더 나아가,&amp;nbsp; 기존 서비스에 새로운 서버를 추가할 때,&amp;nbsp; 내부 서버의 경로 구조를 변경하지 않고 Reverse Proxy에서 경로만 변경하여 라우팅하는 방법도 있습니다.&amp;nbsp; 이를 위해 `rewrite` 지시어를 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예를 들어, 클라이언트가 `/blog/test.html`로 요청했을 때, 실제로는 `/test.html`로 내부 서버에 요청을 전달하고 싶다면, 아래와 같이 설정할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```nginx&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;server {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;listen 80;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;server_name localhost;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;location / {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rewrite ^/blog(.*) $1 break;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_pass http://backend_a;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# ... (기존 proxy_set_header 설정) ...&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;# ... (기타 location 설정) ...&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;`rewrite ^/blog(.*) $1 break;` 라인은 `/blog`로 시작하는 모든 요청을 `/blog` 접두어를 제거한 후 내부 서버로 전달하도록 설정합니다.&amp;nbsp; `break`는 다른 `location`으로의 무한 루프를 방지합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(그림4) rewrite 설정을 포함한 nginx/nginx.conf 파일 예시 이미지 삽입**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;### 5.&amp;nbsp; Nginx Location Match Tester&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Nginx 설정에서 여러 개의 `location`을 사용할 때, 어떤 URL이 어떤 `location`에 매치되는지 궁금할 때가 있죠.&amp;nbsp; 이럴 때 유용한 사이트가 바로 **Nginx Location Match Tester ([&lt;a href=&quot;https://nginx.viraptor.info/](https://nginx.viraptor.info/))**입니다.&quot;&gt;https://nginx.viraptor.info/](https://nginx.viraptor.info/))**입니다.&lt;/a&gt;&amp;nbsp; 여기에 `nginx.conf` 파일의 `server` 블록을 복사해서 붙여넣으면,&amp;nbsp; 다양한 URL을 입력해보고 어떤 `location`으로 요청이 전달되는지 확인할 수 있습니다.&amp;nbsp; 강력 추천합니다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이것으로 Docker와 Nginx를 이용한 Reverse Proxy 설정에 대한 제 이야기는 끝입니다. 처음에는 어려웠지만, 하나씩 설정을 따라 해보면서 Reverse Proxy의 매력에 빠져들었네요. 여러분도 이 글을 통해 Reverse Proxy 설정에 자신감을 얻으셨기를 바랍니다!&lt;/span&gt;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/47</guid>
      <comments>https://techsuda.tistory.com/entry/Docker-Nginx-Proxy-%EC%84%A4%EC%A0%95#entry47comment</comments>
      <pubDate>Sat, 31 May 2025 21:11:08 +0900</pubDate>
    </item>
    <item>
      <title>[SQL] SQLiTE 장단점</title>
      <link>https://techsuda.tistory.com/entry/SQL-SQLiTE-%EC%9E%A5%EB%8B%A8%EC%A0%90</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SQLite, 나 혼자 쓰기 딱 좋은 간편 데이터베이스?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;혼잣말로 풀어보는 SQLite 이야기: 장점, 단점, 그리고 내가 선택해야 할 때!&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;아, 오늘은 SQLite에 대해 혼잣말처럼 떠들어볼까 해.&amp;nbsp; 요즘 프로젝트 하면서 SQLite를 써볼까 말까 고민이 많거든.&amp;nbsp; 일단 장점부터 짚어보자!&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**1. 가볍고, 심플하고, 그냥 딱 내 스타일! (경량성 및 내장형)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SQLite는 진짜 가벼워.&amp;nbsp; 설치 따로 할 필요 없이, 파일 하나로 뚝딱!&amp;nbsp; 내장형이라서 배포도 엄청 쉽고, 관리도 간편해.&amp;nbsp; 마치 내가 좋아하는 간편한 컵라면 같은 느낌?&amp;nbsp; 서버 따로 돌릴 필요도 없으니 자원 낭비도 없고!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**소스코드 예시 (Python):**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```python&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;import sqlite3&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;conn = sqlite3.connect('mydatabase.db') # 파일 하나로 데이터베이스 생성 및 연결&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;cursor = conn.cursor()&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;cursor.execute('''&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CREATE TABLE IF NOT EXISTS users (&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;id INTEGER PRIMARY KEY,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;name TEXT,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;email TEXT&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;''')&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;cursor.execute(&quot;INSERT INTO users (name, email) VALUES (?, ?)&quot;, ('John Doe', 'john.doe@example.com'))&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;conn.commit()&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;cursor.execute(&quot;SELECT * FROM users&quot;)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;results = cursor.fetchall()&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;for row in results:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(row)&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;conn.close()&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 코드처럼 간단하게 데이터베이스를 만들고, 데이터를 넣고, 꺼낼 수 있어.&amp;nbsp; 진짜 쉽지?&amp;nbsp; 이미지로 보면 더 와닿겠지?&amp;nbsp; (아래 이미지 추가 예정 - 간단한 다이어그램으로 SQLite 파일과 Python 코드 간의 연결을 시각적으로 보여줌)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**(이미지 추가: SQLite 파일과 Python 코드 연결 다이어그램)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**2. 돈 안 들고, 마음 편하게 쓸 수 있어! (무료 및 오픈 소스)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;오픈 소스라서 라이선스 걱정 없이 마음껏 쓸 수 있어.&amp;nbsp; 게다가 무료!&amp;nbsp; 돈 아끼는 것도 중요하지.&amp;nbsp; 프로젝트 예산 아껴서 맛있는 거 먹어야지!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**3. SQL 문법이 쉽다니? 나도 할 수 있겠어! (간단한 사용법)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SQL 문법을 지원해서 데이터베이스를 다루는 게 어렵지 않아.&amp;nbsp; SQL 좀 다뤄봤다면 금방 익숙해질 수 있을 거야.&amp;nbsp; 초보자도 쉽게 사용할 수 있다는 점이 가장 큰 매력이지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**4. 읽기는 정말 빠르다! (효율적인 읽기 작업)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;읽기 작업 속도가 엄청 빨라.&amp;nbsp; 읽기 중심의 애플리케이션이라면 SQLite가 최고의 선택일 수 있어.&amp;nbsp; 데이터를 많이 읽어야 하는 경우에는 정말 빛을 발하지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**5. 어디서든 쓸 수 있어! (데이터 이식성)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일 기반이라서 플랫폼에 구애받지 않고 어디서든 쓸 수 있다는 점도 장점이야.&amp;nbsp; 윈도우, 맥, 리눅스&amp;hellip; 상관없어!&amp;nbsp; 내가 원하는 곳 어디든 데려갈 수 있지.&lt;/span&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;하지만... 모든 게 장점일 순 없잖아?&amp;nbsp; 단점도 분명히 존재해.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**1. 여러 명이 동시에 쓰면 힘들어! (다중 사용자 지원 한계)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;동시에 여러 명이 접근해서 데이터를 수정하면 문제가 생길 수 있어.&amp;nbsp; 다중 사용자 지원이 제한적이라 대규모 트랜잭션에는 적합하지 않아.&amp;nbsp; 혼자 쓰거나, 동시 접근자가 적은 경우에만 적합해.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**2. 쓰기 속도가 느려! (쓰기 작업 성능)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;읽기는 빠르지만, 쓰기 속도는 다른 데이터베이스에 비해 느린 편이야.&amp;nbsp; 데이터를 자주 추가하거나 수정해야 한다면 고려해야 할 부분이지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**3. 기능이 부족해! (제한된 기능)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;고급 기능이나 복잡한 쿼리가 필요하다면 SQLite는 부족할 수 있어.&amp;nbsp; 더 강력한 기능을 제공하는 다른 데이터베이스를 선택해야 할 수도 있지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**4. 파일이 너무 커지면 느려져! (파일 기반 구조의 제약)**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파일 크기가 커지면 성능이 저하될 수 있다는 점도 고려해야 해.&amp;nbsp; 데이터 용량이 계속 늘어날 것으로 예상된다면 다른 솔루션을 찾아봐야겠지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**그래서, 결론은?**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SQLite는 경량이고 간편한 데이터베이스야.&amp;nbsp; 혼자 쓰는 프로젝트나, 소규모 프로젝트,&amp;nbsp; 읽기 중심의 애플리케이션에 적합해.&amp;nbsp; 하지만 대규모 프로젝트나 다중 사용자 환경에서는 MySQL, PostgreSQL, MSSQL 등 다른 데이터베이스를 고려하는 게 좋아.&amp;nbsp; 나 같은 경우에는&amp;hellip;&amp;nbsp; (고민 중&amp;hellip;)&amp;nbsp; 프로젝트 규모와 특성에 따라 신중하게 선택해야겠어!&amp;nbsp; 아직 결정은 못 내렸지만,&amp;nbsp; 이렇게 정리하고 나니 좀 더 객관적으로 판단할 수 있을 것 같아.&amp;nbsp; 다음에는 다른 데이터베이스도 비교해봐야겠다!&lt;/span&gt;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/46</guid>
      <comments>https://techsuda.tistory.com/entry/SQL-SQLiTE-%EC%9E%A5%EB%8B%A8%EC%A0%90#entry46comment</comments>
      <pubDate>Sat, 31 May 2025 21:03:54 +0900</pubDate>
    </item>
    <item>
      <title>[SQL] MongoDB 활용</title>
      <link>https://techsuda.tistory.com/entry/SQL-MongoDB-%ED%99%9C%EC%9A%A9</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SQL 개발자, 이제 MongoDB로 날아오르자!&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;안녕하세요 여러분! 오늘은 제가 몽고DB(MongoDB)에 대해 샅샅이 파헤쳐 보는 시간을 갖도록 하겠습니다.&amp;nbsp; SQL 개발자인 저에게도 처음엔 낯설었던 몽고DB였지만,&amp;nbsp; 이제는 그 매력에 푹 빠져버렸죠.&amp;nbsp; 이 글을 통해 몽고DB의 세계로 여러분을 초대하고,&amp;nbsp; SQL과 비교하며 쉽고 빠르게 이해할 수 있도록 도와드리겠습니다.&amp;nbsp; 자, 함께 떠나볼까요?  &lt;/span&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;### 1. 몽고DB vs SQL: 기본 개념부터 차근차근&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;먼저, 몽고DB와 SQL 데이터베이스의 가장 큰 차이점을 간략하게 비교해보겠습니다.&amp;nbsp; SQL은 관계형 데이터베이스(RDBMS)이고,&amp;nbsp; 몽고DB는 NoSQL 데이터베이스 중 하나인 문서형 데이터베이스입니다.&amp;nbsp; 이게 무슨 말이냐구요?  &lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **SQL (관계형 데이터베이스):**&amp;nbsp; 데이터를 테이블 형태로 저장하고, 테이블 간의 관계를 통해 데이터를 관리합니다.&amp;nbsp; 데이터의 무결성과 정확성을 유지하는 데 탁월하지만,&amp;nbsp; 복잡한 관계를 다루는 데 어려움을 느낄 수 있습니다.&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **몽고DB (문서형 데이터베이스):**&amp;nbsp; 데이터를 JSON 형태의 문서로 저장합니다.&amp;nbsp; 테이블과 행, 열 대신 컬렉션과 문서, 필드라는 용어를 사용합니다.&amp;nbsp; 유연성이 높고,&amp;nbsp; 스키마가 자유로워 데이터 모델링이 자유롭다는 장점이 있습니다.&lt;/span&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;| SQL 용어/개념 | MongoDB 용어/개념 | 설명 |&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;|---|---|---|&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;| database | database | 데이터베이스 자체 |&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;| 테이블 | 컬렉션 (Collection) | 데이터를 담는 용기 |&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;| 행 | 문서 (Document) | JSON 형태의 데이터 |&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;| 열 | 필드 (Field) | 문서의 속성 |&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;| index | index | 데이터 검색 속도 향상을 위한 인덱스 |&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;| 테이블 결합 | $lookup (Aggregation 연산자) | 컬렉션 간 데이터 결합 |&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;| 기본 키 | _id 필드 | 자동 생성되는 고유 식별자 |&lt;/span&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자, 이제 몽고DB의 기본적인 개념을 이해했으니, 실제로 데이터를 다루는 CRUD 작업을 살펴보겠습니다.&lt;/span&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;### 2. CRUD 작업: 데이터의 핵심!&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;몽고DB에서 데이터를 조작하는 CRUD(Create, Read, Update, Delete) 작업은 다음과 같은 메서드와 연산자를 사용합니다.&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**2.1 데이터 삽입 (Insert):**&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;`db.collection.insertOne()`&amp;nbsp; 메서드를 사용하여 하나의 문서를 삽입하고,&amp;nbsp; `db.collection.insertMany()` 메서드를 사용하여 여러 개의 문서를 한 번에 삽입할 수 있습니다.&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```javascript&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;// 하나의 문서 삽입&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;db.people.insertOne({ user_id: 'abc123', age: 30, status: 'A' });&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;// 여러 문서 삽입&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;db.people.insertMany([&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;{ user_id: 'def456', age: 25, status: 'B' },&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;{ user_id: 'ghi789', age: 40, status: 'A' }&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;]);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**2.2 데이터 조회 (Read):**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;`db.collection.find()` 메서드를 사용하여 데이터를 조회합니다.&amp;nbsp; 조건을 추가하여 원하는 데이터만 검색할 수 있으며,&amp;nbsp; `sort()`, `limit()`, `skip()` 메서드를 이용하여 정렬, 제한, 건너뛰기를 할 수 있습니다.&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```javascript&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;// 모든 문서 조회&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;db.people.find();&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;// status가 'A'인 문서 조회&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;db.people.find({ status: 'A' });&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;// age가 30보다 큰 문서를 age 기준으로 내림차순 정렬 후 5개만 조회&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;db.people.find({ age: { $gt: 30 } }).sort({ age: -1 }).limit(5);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**2.3 데이터 수정 (Update):**&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;`db.collection.updateOne()` 또는 `db.collection.updateMany()` 메서드를 사용하여 데이터를 수정합니다.&amp;nbsp; `$set`, `$inc`, `$push` 등의 업데이트 연산자를 사용하여 다양한 수정 작업을 수행할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```javascript&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;// age가 30인 문서의 status를 'C'로 변경&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;db.people.updateOne({ age: 30 }, { $set: { status: 'C' } });&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;// status가 'A'인 모든 문서의 age에 1을 더함&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;db.people.updateMany({ status: 'A' }, { $inc: { age: 1 } });&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;**2.4 데이터 삭제 (Delete):**&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;`db.collection.deleteOne()` 또는 `db.collection.deleteMany()` 메서드를 사용하여 데이터를 삭제합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```javascript&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;// status가 'B'인 문서 하나 삭제&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;db.people.deleteOne({ status: 'B' });&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;// status가 'A'인 모든 문서 삭제&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;db.people.deleteMany({ status: 'A' });&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;```&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;### 3.&amp;nbsp; 몽고DB의 강력한 기능들: 집계, 인덱스, 트랜잭션&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;몽고DB는 CRUD 작업 외에도 다양한 강력한 기능들을 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **집계 (Aggregation):**&amp;nbsp; 데이터를 분석하고 요약하는 데 사용됩니다.&amp;nbsp; `$group`, `$match`, `$sort` 등의 연산자를 사용하여 복잡한 데이터 처리가 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **인덱스 (Indexes):**&amp;nbsp; 데이터 검색 속도를 향상시키기 위해 사용됩니다.&amp;nbsp; 적절한 인덱스를 생성하는 것은 몽고DB 성능 최적화의 핵심입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* **트랜잭션 (Transactions):**&amp;nbsp; 여러 작업을 하나의 원자적 작업으로 처리하여 데이터의 일관성을 유지합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;### 4. SQL에서 몽고DB로의 전환: 팁과 고려사항&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SQL 개발자라면 몽고DB로 전환할 때 어려움을 느낄 수 있습니다.&amp;nbsp; 하지만 차근차근 개념을 이해하고,&amp;nbsp; SQL과 몽고DB의 차이점을 명확히 인지한다면&amp;nbsp; 문제없이 적응할 수 있습니다.&amp;nbsp; 데이터 모델링 전략을 신중하게 계획하고,&amp;nbsp; 몽고DB의 특징을 활용하여 효율적인 데이터 관리 방식을 구축하는 것이 중요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;### 5. 마치며&amp;hellip;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 글에서는 몽고DB의 기본적인 내용과 SQL과의 비교, 그리고 핵심 기능들을 간략하게 살펴보았습니다.&amp;nbsp; 몽고DB는&amp;nbsp; 웹 애플리케이션, IoT,&amp;nbsp; 빅데이터 등 다양한 분야에서 활용되고 있으며,&amp;nbsp; 그 유연성과 확장성은&amp;nbsp; 많은 개발자들에게 매력적인 선택지입니다.&amp;nbsp; 이 글이 여러분의 몽고DB 학습에 도움이 되었기를 바랍니다!&lt;/span&gt;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/45</guid>
      <comments>https://techsuda.tistory.com/entry/SQL-MongoDB-%ED%99%9C%EC%9A%A9#entry45comment</comments>
      <pubDate>Sat, 31 May 2025 21:00:42 +0900</pubDate>
    </item>
    <item>
      <title>나가사키 가족 여행</title>
      <link>https://techsuda.tistory.com/entry/%EB%82%98%EA%B0%80%EC%82%AC%ED%82%A4-%EA%B0%80%EC%A1%B1-%EC%97%AC%ED%96%89</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;우리 가족은 여행 스타일이 좀 독특하다. 사람들이 많이 가는 유명한 관광지 보다는 비교적 조용하고 한적하면서 편안하게 힐링할 수 있는 그러한 곳을 선호하는 편이다.&lt;br /&gt;이번 일본 여행 또한 그러했다. 기차를 타고 치와타역을 찾아 갔었는데 일몰과 함께 고즈넉한 마을이 너무도 인상깊었던 곳이다. 올레길처럼 산책하기 좋은 길이 바다와 철길 옆으로 이어져 있고, 오래된 치와타역 플랫폼 벤치에서 바라보는 멋진 일몰, 그리고 분위기 좋은 카페와 조용한 마을......&lt;br /&gt;이번 여행은 딸래미가 찍은 필름을 현상해서 내가 직접 스캔한 사진도 같이 올려본다. (먼지 좀 털어냈어야 하는데...)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;무제-5.jpg&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1259&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A4mxO/btsL9MBgtyi/EpvkBKF2NBK65jsDbkxct0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A4mxO/btsL9MBgtyi/EpvkBKF2NBK65jsDbkxct0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A4mxO/btsL9MBgtyi/EpvkBKF2NBK65jsDbkxct0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA4mxO%2FbtsL9MBgtyi%2FEpvkBKF2NBK65jsDbkxct0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1259&quot; data-filename=&quot;무제-5.jpg&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1259&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;무제-6_1.jpg&quot; data-origin-width=&quot;3732&quot; data-origin-height=&quot;2480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfftaS/btsL9QDDACD/ys4a8ULWygk3iKQa29YEtK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfftaS/btsL9QDDACD/ys4a8ULWygk3iKQa29YEtK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfftaS/btsL9QDDACD/ys4a8ULWygk3iKQa29YEtK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfftaS%2FbtsL9QDDACD%2Fys4a8ULWygk3iKQa29YEtK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3732&quot; height=&quot;2480&quot; data-filename=&quot;무제-6_1.jpg&quot; data-origin-width=&quot;3732&quot; data-origin-height=&quot;2480&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;무제-12_1.jpg&quot; data-origin-width=&quot;3460&quot; data-origin-height=&quot;2296&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DWWhq/btsMayPOLtQ/vsklPi0rZiRWtOyaYj6Ko0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DWWhq/btsMayPOLtQ/vsklPi0rZiRWtOyaYj6Ko0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DWWhq/btsMayPOLtQ/vsklPi0rZiRWtOyaYj6Ko0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDWWhq%2FbtsMayPOLtQ%2FvsklPi0rZiRWtOyaYj6Ko0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3460&quot; height=&quot;2296&quot; data-filename=&quot;무제-12_1.jpg&quot; data-origin-width=&quot;3460&quot; data-origin-height=&quot;2296&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;무제-13.jpg&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1259&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVoOvQ/btsL9vmc9Du/v9hx0Vzwoh5slVAtfb5uz0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVoOvQ/btsL9vmc9Du/v9hx0Vzwoh5slVAtfb5uz0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVoOvQ/btsL9vmc9Du/v9hx0Vzwoh5slVAtfb5uz0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVoOvQ%2FbtsL9vmc9Du%2Fv9hx0Vzwoh5slVAtfb5uz0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1259&quot; data-filename=&quot;무제-13.jpg&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1259&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;무제-14.jpg&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1308&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgbJXB/btsMavS4IOD/KWOoCsuOdl3HYcNodHzMbK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgbJXB/btsMavS4IOD/KWOoCsuOdl3HYcNodHzMbK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgbJXB/btsMavS4IOD/KWOoCsuOdl3HYcNodHzMbK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcgbJXB%2FbtsMavS4IOD%2FKWOoCsuOdl3HYcNodHzMbK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1308&quot; data-filename=&quot;무제-14.jpg&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1308&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;무제-21_1.jpg&quot; data-origin-width=&quot;3717&quot; data-origin-height=&quot;2489&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbhpgi/btsMavZQ1BQ/vXqytBQn52KZTRu9xRjVxK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbhpgi/btsMavZQ1BQ/vXqytBQn52KZTRu9xRjVxK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbhpgi/btsMavZQ1BQ/vXqytBQn52KZTRu9xRjVxK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbbhpgi%2FbtsMavZQ1BQ%2FvXqytBQn52KZTRu9xRjVxK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3717&quot; height=&quot;2489&quot; data-filename=&quot;무제-21_1.jpg&quot; data-origin-width=&quot;3717&quot; data-origin-height=&quot;2489&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;무제-23_1.jpg&quot; data-origin-width=&quot;3724&quot; data-origin-height=&quot;2456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rGVSn/btsL8M3klVB/x0k2lVafKkK1zHkgvZvbb1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rGVSn/btsL8M3klVB/x0k2lVafKkK1zHkgvZvbb1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rGVSn/btsL8M3klVB/x0k2lVafKkK1zHkgvZvbb1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrGVSn%2FbtsL8M3klVB%2Fx0k2lVafKkK1zHkgvZvbb1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3724&quot; height=&quot;2456&quot; data-filename=&quot;무제-23_1.jpg&quot; data-origin-width=&quot;3724&quot; data-origin-height=&quot;2456&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;무제-27_1.jpg&quot; data-origin-width=&quot;3729&quot; data-origin-height=&quot;2429&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8nu8Q/btsMaM77lmG/WzvIW8WfYOK7hcKHmJySsk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8nu8Q/btsMaM77lmG/WzvIW8WfYOK7hcKHmJySsk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8nu8Q/btsMaM77lmG/WzvIW8WfYOK7hcKHmJySsk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8nu8Q%2FbtsMaM77lmG%2FWzvIW8WfYOK7hcKHmJySsk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3729&quot; height=&quot;2429&quot; data-filename=&quot;무제-27_1.jpg&quot; data-origin-width=&quot;3729&quot; data-origin-height=&quot;2429&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;무제-29.jpg&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lML3v/btsMaM1lh59/UYecbSNh51i0DTNNhgdKVK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lML3v/btsMaM1lh59/UYecbSNh51i0DTNNhgdKVK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lML3v/btsMaM1lh59/UYecbSNh51i0DTNNhgdKVK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlML3v%2FbtsMaM1lh59%2FUYecbSNh51i0DTNNhgdKVK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1284&quot; data-filename=&quot;무제-29.jpg&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;무제-32.jpg&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1255&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZCFfD/btsL8LwzdpS/mISvdlaWL93pqhbLcPH450/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZCFfD/btsL8LwzdpS/mISvdlaWL93pqhbLcPH450/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZCFfD/btsL8LwzdpS/mISvdlaWL93pqhbLcPH450/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZCFfD%2FbtsL8LwzdpS%2FmISvdlaWL93pqhbLcPH450%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1255&quot; data-filename=&quot;무제-32.jpg&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1255&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0004.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3ITHu/btsL87seCuK/bSfUwH02w6GSe1KOFI4dmK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3ITHu/btsL87seCuK/bSfUwH02w6GSe1KOFI4dmK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3ITHu/btsL87seCuK/bSfUwH02w6GSe1KOFI4dmK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3ITHu%2FbtsL87seCuK%2FbSfUwH02w6GSe1KOFI4dmK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2736&quot; height=&quot;1824&quot; data-filename=&quot;IMG_0004.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0044.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/I9NBl/btsMaDKhPp3/xkPwLKWxsdKahcLaMQBHYk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/I9NBl/btsMaDKhPp3/xkPwLKWxsdKahcLaMQBHYk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/I9NBl/btsMaDKhPp3/xkPwLKWxsdKahcLaMQBHYk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI9NBl%2FbtsMaDKhPp3%2FxkPwLKWxsdKahcLaMQBHYk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2736&quot; height=&quot;1824&quot; data-filename=&quot;IMG_0044.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0081.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRi1K7/btsL98jFmJ1/rTn7RSrEZfiCQFHviFfgYk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRi1K7/btsL98jFmJ1/rTn7RSrEZfiCQFHviFfgYk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRi1K7/btsL98jFmJ1/rTn7RSrEZfiCQFHviFfgYk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRi1K7%2FbtsL98jFmJ1%2FrTn7RSrEZfiCQFHviFfgYk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2736&quot; height=&quot;1824&quot; data-filename=&quot;IMG_0081.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_9519.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HL8Cs/btsL9plWdIi/k5dFjJLktLLf56sFW3jyHk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HL8Cs/btsL9plWdIi/k5dFjJLktLLf56sFW3jyHk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HL8Cs/btsL9plWdIi/k5dFjJLktLLf56sFW3jyHk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHL8Cs%2FbtsL9plWdIi%2Fk5dFjJLktLLf56sFW3jyHk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2736&quot; height=&quot;1824&quot; data-filename=&quot;IMG_9519.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_9543.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5Nu0a/btsMaiGrU8t/RClabX4Vkiw8F5v6IhUMb1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5Nu0a/btsMaiGrU8t/RClabX4Vkiw8F5v6IhUMb1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5Nu0a/btsMaiGrU8t/RClabX4Vkiw8F5v6IhUMb1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5Nu0a%2FbtsMaiGrU8t%2FRClabX4Vkiw8F5v6IhUMb1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2736&quot; height=&quot;1824&quot; data-filename=&quot;IMG_9543.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_9562.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xYz2B/btsMaQ3GrEB/xIJxnnI3RkrkkqBo4V5RP0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xYz2B/btsMaQ3GrEB/xIJxnnI3RkrkkqBo4V5RP0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xYz2B/btsMaQ3GrEB/xIJxnnI3RkrkkqBo4V5RP0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxYz2B%2FbtsMaQ3GrEB%2FxIJxnnI3RkrkkqBo4V5RP0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2736&quot; height=&quot;1824&quot; data-filename=&quot;IMG_9562.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_9630.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cGvmm3/btsL98xdyvz/OIk2pyr5kMVDIZcwdgIjKK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cGvmm3/btsL98xdyvz/OIk2pyr5kMVDIZcwdgIjKK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cGvmm3/btsL98xdyvz/OIk2pyr5kMVDIZcwdgIjKK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcGvmm3%2FbtsL98xdyvz%2FOIk2pyr5kMVDIZcwdgIjKK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2736&quot; height=&quot;1824&quot; data-filename=&quot;IMG_9630.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_9646.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ESvzQ/btsL97yjO6W/kcRKkAkFT6Ppg6UsDwl60K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ESvzQ/btsL97yjO6W/kcRKkAkFT6Ppg6UsDwl60K/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ESvzQ/btsL97yjO6W/kcRKkAkFT6Ppg6UsDwl60K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FESvzQ%2FbtsL97yjO6W%2FkcRKkAkFT6Ppg6UsDwl60K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2736&quot; height=&quot;1824&quot; data-filename=&quot;IMG_9646.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_9721.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqsLyt/btsL97E7E4F/EflD0qkK3QbwvIAQqAuBP1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqsLyt/btsL97E7E4F/EflD0qkK3QbwvIAQqAuBP1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqsLyt/btsL97E7E4F/EflD0qkK3QbwvIAQqAuBP1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqsLyt%2FbtsL97E7E4F%2FEflD0qkK3QbwvIAQqAuBP1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2736&quot; height=&quot;1824&quot; data-filename=&quot;IMG_9721.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_9729.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o6yu2/btsL9nuSYe6/OvIozhbIAx4YnLWAh3k7r1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o6yu2/btsL9nuSYe6/OvIozhbIAx4YnLWAh3k7r1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o6yu2/btsL9nuSYe6/OvIozhbIAx4YnLWAh3k7r1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo6yu2%2FbtsL9nuSYe6%2FOvIozhbIAx4YnLWAh3k7r1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2736&quot; height=&quot;1824&quot; data-filename=&quot;IMG_9729.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_9733.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dnbRCh/btsL9RvKgV2/fkYKb4ternXqTpqq4A0i1K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dnbRCh/btsL9RvKgV2/fkYKb4ternXqTpqq4A0i1K/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dnbRCh/btsL9RvKgV2/fkYKb4ternXqTpqq4A0i1K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdnbRCh%2FbtsL9RvKgV2%2FfkYKb4ternXqTpqq4A0i1K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2736&quot; height=&quot;1824&quot; data-filename=&quot;IMG_9733.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_9757.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bubO50/btsMaUdWPR8/L2AkqMkSYLsuOOvDNphhD1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bubO50/btsMaUdWPR8/L2AkqMkSYLsuOOvDNphhD1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bubO50/btsMaUdWPR8/L2AkqMkSYLsuOOvDNphhD1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbubO50%2FbtsMaUdWPR8%2FL2AkqMkSYLsuOOvDNphhD1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2736&quot; height=&quot;1824&quot; data-filename=&quot;IMG_9757.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_9774.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUemVG/btsL86tmvjM/BUciX4hid2KcGSc90MtJn0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUemVG/btsL86tmvjM/BUciX4hid2KcGSc90MtJn0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUemVG/btsL86tmvjM/BUciX4hid2KcGSc90MtJn0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUemVG%2FbtsL86tmvjM%2FBUciX4hid2KcGSc90MtJn0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2736&quot; height=&quot;1824&quot; data-filename=&quot;IMG_9774.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_9817.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kXHiF/btsMaifgTw7/Bu1UAFFRbzJKeMHDBtAoJk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kXHiF/btsMaifgTw7/Bu1UAFFRbzJKeMHDBtAoJk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kXHiF/btsMaifgTw7/Bu1UAFFRbzJKeMHDBtAoJk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkXHiF%2FbtsMaifgTw7%2FBu1UAFFRbzJKeMHDBtAoJk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2736&quot; height=&quot;1824&quot; data-filename=&quot;IMG_9817.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_9839.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxxfqe/btsL9PSbzns/71utZ1OCkXs3AZkCC6ZT0K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxxfqe/btsL9PSbzns/71utZ1OCkXs3AZkCC6ZT0K/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxxfqe/btsL9PSbzns/71utZ1OCkXs3AZkCC6ZT0K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcxxfqe%2FbtsL9PSbzns%2F71utZ1OCkXs3AZkCC6ZT0K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2736&quot; height=&quot;1824&quot; data-filename=&quot;IMG_9839.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_9849.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yBPkD/btsL98RwAxt/EgcB1kLlXBLSTAzwdRxQJ1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yBPkD/btsL98RwAxt/EgcB1kLlXBLSTAzwdRxQJ1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yBPkD/btsL98RwAxt/EgcB1kLlXBLSTAzwdRxQJ1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyBPkD%2FbtsL98RwAxt%2FEgcB1kLlXBLSTAzwdRxQJ1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2736&quot; height=&quot;1824&quot; data-filename=&quot;IMG_9849.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_9859.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nPfJt/btsL97ZlRYB/sDt0KIQBQq9yIHUhgf0LwK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nPfJt/btsL97ZlRYB/sDt0KIQBQq9yIHUhgf0LwK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nPfJt/btsL97ZlRYB/sDt0KIQBQq9yIHUhgf0LwK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnPfJt%2FbtsL97ZlRYB%2FsDt0KIQBQq9yIHUhgf0LwK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2736&quot; height=&quot;1824&quot; data-filename=&quot;IMG_9859.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_9868.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4CWmr/btsL8Ht7W1L/MKE87f2WAnCEodhkHUrQSk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4CWmr/btsL8Ht7W1L/MKE87f2WAnCEodhkHUrQSk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4CWmr/btsL8Ht7W1L/MKE87f2WAnCEodhkHUrQSk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4CWmr%2FbtsL8Ht7W1L%2FMKE87f2WAnCEodhkHUrQSk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2736&quot; height=&quot;1824&quot; data-filename=&quot;IMG_9868.JPG&quot; data-origin-width=&quot;2736&quot; data-origin-height=&quot;1824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_9973.JPG&quot; data-origin-width=&quot;1824&quot; data-origin-height=&quot;2736&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TcTuf/btsL9NGSLZr/s8qbz5NEaloGKRPkkGtTJ1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TcTuf/btsL9NGSLZr/s8qbz5NEaloGKRPkkGtTJ1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TcTuf/btsL9NGSLZr/s8qbz5NEaloGKRPkkGtTJ1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTcTuf%2FbtsL9NGSLZr%2Fs8qbz5NEaloGKRPkkGtTJ1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1824&quot; height=&quot;2736&quot; data-filename=&quot;IMG_9973.JPG&quot; data-origin-width=&quot;1824&quot; data-origin-height=&quot;2736&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Gallery</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/44</guid>
      <comments>https://techsuda.tistory.com/entry/%EB%82%98%EA%B0%80%EC%82%AC%ED%82%A4-%EA%B0%80%EC%A1%B1-%EC%97%AC%ED%96%89#entry44comment</comments>
      <pubDate>Thu, 6 Feb 2025 19:57:44 +0900</pubDate>
    </item>
    <item>
      <title>About Honey</title>
      <link>https://techsuda.tistory.com/entry/About-Honey</link>
      <description>&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;현 아티스테크(주) 대표&amp;nbsp; 조 중 헌&lt;br /&gt;Database / Python / C++ / Delphi / Flutter / DOCKER / System consulting&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;연세대학교 공학석사&lt;br /&gt;재능대학교 컴퓨터정보과 겸임교수 역임&lt;br /&gt;전 인스컴퍼니 기술이사 역임&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;사진과 골프를 즐기며 컴퓨터관련 수다떨기를 좋아합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;mail : jackyjuju@itgosuda.com / jackyjuju@yonsei.ac.kr&lt;/p&gt;</description>
      <category>About</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/43</guid>
      <comments>https://techsuda.tistory.com/entry/About-Honey#entry43comment</comments>
      <pubDate>Fri, 17 Jan 2025 20:34:34 +0900</pubDate>
    </item>
    <item>
      <title>다시 제주에...</title>
      <link>https://techsuda.tistory.com/entry/%EB%8B%A4%EC%8B%9C-%EC%A0%9C%EC%A3%BC%EC%97%90</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;이번엔 거의 1년 만에 제주에 방문했다.&lt;br /&gt;1년간 거의 삼실, 집, 삼실, 집 ... 뺑뺑이 생활이었다. 아~~~ 지친다 지쳐.&lt;br /&gt;그래서 작년 생일기념과 마찬가지로 올해 생파 또한 와이프와 함께 제주에서...&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;이번에도 어김없이 오름 한곳을 둘러보았다. 정물오름~~~&lt;br /&gt;이맘때면 제주 어느곳이든 억새가 볼만하고 걷기에 딱 좋다.&lt;br /&gt;정물오름 꼭대기에 올라 탁 트인 바다와 맑은 하늘아래 한라산까지 둘러보며&lt;br /&gt;시원한 바람과 그 속에서 흔들리는 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;억새들의&lt;span&gt; &lt;/span&gt;&lt;/span&gt;소리에 귀 기울이다 보면&lt;br /&gt;가슴이 뻥 뚫리는 듯 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;그리고 수산한못 이라는 연못도 다녀왔었는데 사진 좋아하는 사람들이 자주 찾는다고 한다.&lt;br /&gt;고장난 캐논L(24-70)렌즈 고쳐서 다음에 다시 한번 가봐야 겠다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20241111_131318.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;1868&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKE8T6/btsKQAVJMy4/BPg04hLcjhx93k8Z6mHxK0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKE8T6/btsKQAVJMy4/BPg04hLcjhx93k8Z6mHxK0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKE8T6/btsKQAVJMy4/BPg04hLcjhx93k8Z6mHxK0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKE8T6%2FbtsKQAVJMy4%2FBPg04hLcjhx93k8Z6mHxK0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;1868&quot; data-filename=&quot;20241111_131318.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;1868&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20241111_140417.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;1868&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBUmyX/btsKQ9jfuU1/KUABIaVIboIgj2RLV4FYV1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBUmyX/btsKQ9jfuU1/KUABIaVIboIgj2RLV4FYV1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBUmyX/btsKQ9jfuU1/KUABIaVIboIgj2RLV4FYV1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBUmyX%2FbtsKQ9jfuU1%2FKUABIaVIboIgj2RLV4FYV1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;1868&quot; data-filename=&quot;20241111_140417.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;1868&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20241111_141511.jpg&quot; data-origin-width=&quot;12432&quot; data-origin-height=&quot;2592&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m1LjN/btsKPSiw0ob/Jg3EwqYgEGDgTNLxKE9yA1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m1LjN/btsKPSiw0ob/Jg3EwqYgEGDgTNLxKE9yA1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m1LjN/btsKPSiw0ob/Jg3EwqYgEGDgTNLxKE9yA1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm1LjN%2FbtsKPSiw0ob%2FJg3EwqYgEGDgTNLxKE9yA1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;12432&quot; height=&quot;2592&quot; data-filename=&quot;20241111_141511.jpg&quot; data-origin-width=&quot;12432&quot; data-origin-height=&quot;2592&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20241111_141834.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;1868&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cb8QTc/btsKQ9Q5l0q/Nvh7vFYudDWM5MPYqwEuUK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cb8QTc/btsKQ9Q5l0q/Nvh7vFYudDWM5MPYqwEuUK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cb8QTc/btsKQ9Q5l0q/Nvh7vFYudDWM5MPYqwEuUK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcb8QTc%2FbtsKQ9Q5l0q%2FNvh7vFYudDWM5MPYqwEuUK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;1868&quot; data-filename=&quot;20241111_141834.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;1868&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20241111_141930.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;1868&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgc3CO/btsKONJdakC/KAnRbBxbkVcDJmUwWym3n1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgc3CO/btsKONJdakC/KAnRbBxbkVcDJmUwWym3n1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgc3CO/btsKONJdakC/KAnRbBxbkVcDJmUwWym3n1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbgc3CO%2FbtsKONJdakC%2FKAnRbBxbkVcDJmUwWym3n1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;1868&quot; data-filename=&quot;20241111_141930.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;1868&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20241111_171907.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;1868&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brr1xG/btsKPNg7Bvm/OBnKAZ32f1ELaa9YWu6Kzk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brr1xG/btsKPNg7Bvm/OBnKAZ32f1ELaa9YWu6Kzk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brr1xG/btsKPNg7Bvm/OBnKAZ32f1ELaa9YWu6Kzk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbrr1xG%2FbtsKPNg7Bvm%2FOBnKAZ32f1ELaa9YWu6Kzk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;1868&quot; data-filename=&quot;20241111_171907.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;1868&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20241112_145641.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmPXLJ/btsKOo3Uyvw/cOwSAy6un9mVvT2bODxojk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmPXLJ/btsKOo3Uyvw/cOwSAy6un9mVvT2bODxojk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmPXLJ/btsKOo3Uyvw/cOwSAy6un9mVvT2bODxojk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmPXLJ%2FbtsKOo3Uyvw%2FcOwSAy6un9mVvT2bODxojk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;2252&quot; data-filename=&quot;20241112_145641.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2252&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20241112_145846.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvc5u1/btsKRaJeJKb/1NVi6cqPTCHxFSkI8etEM0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvc5u1/btsKRaJeJKb/1NVi6cqPTCHxFSkI8etEM0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvc5u1/btsKRaJeJKb/1NVi6cqPTCHxFSkI8etEM0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbvc5u1%2FbtsKRaJeJKb%2F1NVi6cqPTCHxFSkI8etEM0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;20241112_145846.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20241112_145908.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btrvqE/btsKPESmmfS/r2EKmGEkaGuIJlYVkxDSLK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btrvqE/btsKPESmmfS/r2EKmGEkaGuIJlYVkxDSLK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btrvqE/btsKPESmmfS/r2EKmGEkaGuIJlYVkxDSLK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtrvqE%2FbtsKPESmmfS%2Fr2EKmGEkaGuIJlYVkxDSLK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;20241112_145908.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20241112_150523.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qteC2/btsKOUaAmuR/ltYMo9fy228ijTk08AES61/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qteC2/btsKOUaAmuR/ltYMo9fy228ijTk08AES61/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qteC2/btsKOUaAmuR/ltYMo9fy228ijTk08AES61/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqteC2%2FbtsKOUaAmuR%2FltYMo9fy228ijTk08AES61%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;20241112_150523.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20241111142212_IMG_2369.JPG&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAKp6C/btsKQEjr61u/69p9dSKzaT38dHrdifdR6K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAKp6C/btsKQEjr61u/69p9dSKzaT38dHrdifdR6K/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAKp6C/btsKQEjr61u/69p9dSKzaT38dHrdifdR6K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAKp6C%2FbtsKQEjr61u%2F69p9dSKzaT38dHrdifdR6K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1280&quot; data-filename=&quot;20241111142212_IMG_2369.JPG&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20241111152122_IMG_2433.JPG&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bToSIU/btsKQFilNjl/NyZd7zjAATl24VCDXMyUMk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bToSIU/btsKQFilNjl/NyZd7zjAATl24VCDXMyUMk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bToSIU/btsKQFilNjl/NyZd7zjAATl24VCDXMyUMk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbToSIU%2FbtsKQFilNjl%2FNyZd7zjAATl24VCDXMyUMk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1280&quot; data-filename=&quot;20241111152122_IMG_2433.JPG&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20241111152154_IMG_2437.JPG&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bROMib/btsKRcNJs6T/lb6npI0k4HNX4zomfK64X0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bROMib/btsKRcNJs6T/lb6npI0k4HNX4zomfK64X0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bROMib/btsKRcNJs6T/lb6npI0k4HNX4zomfK64X0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbROMib%2FbtsKRcNJs6T%2Flb6npI0k4HNX4zomfK64X0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1280&quot; data-filename=&quot;20241111152154_IMG_2437.JPG&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20241111174242_IMG_2479.JPG&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZZzFd/btsKQw0lFWr/FNeVJjiK2JNBOYaPakP08K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZZzFd/btsKQw0lFWr/FNeVJjiK2JNBOYaPakP08K/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZZzFd/btsKQw0lFWr/FNeVJjiK2JNBOYaPakP08K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZZzFd%2FbtsKQw0lFWr%2FFNeVJjiK2JNBOYaPakP08K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1280&quot; data-filename=&quot;20241111174242_IMG_2479.JPG&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20241111184434_IMG_2511.JPG&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bShY7Y/btsKQMBL0c6/Zl4QUjlc20TMzaSCRvEHs0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bShY7Y/btsKQMBL0c6/Zl4QUjlc20TMzaSCRvEHs0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bShY7Y/btsKQMBL0c6/Zl4QUjlc20TMzaSCRvEHs0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbShY7Y%2FbtsKQMBL0c6%2FZl4QUjlc20TMzaSCRvEHs0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1280&quot; data-filename=&quot;20241111184434_IMG_2511.JPG&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Gallery</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/41</guid>
      <comments>https://techsuda.tistory.com/entry/%EB%8B%A4%EC%8B%9C-%EC%A0%9C%EC%A3%BC%EC%97%90#entry41comment</comments>
      <pubDate>Wed, 20 Nov 2024 15:01:56 +0900</pubDate>
    </item>
    <item>
      <title>몇년만에 베트남 골프</title>
      <link>https://techsuda.tistory.com/entry/%EB%AA%87%EB%85%84%EB%A7%8C%EC%97%90-%EB%B2%A0%ED%8A%B8%EB%82%A8-%EA%B3%A8%ED%94%84</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;코로나 시작 무렵 베트남 방문했었는데, 이번에 대학원 동문 몇몇의 모임으로 베트남 하이퐁 방문.&lt;br /&gt;골프도 너무 오래 손 놓고 있었더니 스코어는 형편없었지만 재미는 만땅~~~&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240215_102314.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHQvbi/btsFckx2bdD/nO74durmHwDKNlmOl1mzbk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHQvbi/btsFckx2bdD/nO74durmHwDKNlmOl1mzbk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHQvbi/btsFckx2bdD/nO74durmHwDKNlmOl1mzbk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHQvbi%2FbtsFckx2bdD%2FnO74durmHwDKNlmOl1mzbk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;IMG_20240215_102314.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240215_125527.jpg&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Er6zS/btsFckdKK3C/6fHBBObQIKjMBoJtQmIei0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Er6zS/btsFckdKK3C/6fHBBObQIKjMBoJtQmIei0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Er6zS/btsFckdKK3C/6fHBBObQIKjMBoJtQmIei0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEr6zS%2FbtsFckdKK3C%2F6fHBBObQIKjMBoJtQmIei0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;4000&quot; data-filename=&quot;IMG_20240215_125527.jpg&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240215_134749.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cSll0P/btsFcPq4ulp/aA7oACqhEErskd4ADEEK9K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cSll0P/btsFcPq4ulp/aA7oACqhEErskd4ADEEK9K/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cSll0P/btsFcPq4ulp/aA7oACqhEErskd4ADEEK9K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcSll0P%2FbtsFcPq4ulp%2FaA7oACqhEErskd4ADEEK9K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;2252&quot; data-filename=&quot;IMG_20240215_134749.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2252&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240215_145719.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dSeboB/btsFdWci81u/HV5fCqDG5Mef0w3APdor7K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dSeboB/btsFdWci81u/HV5fCqDG5Mef0w3APdor7K/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dSeboB/btsFdWci81u/HV5fCqDG5Mef0w3APdor7K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdSeboB%2FbtsFdWci81u%2FHV5fCqDG5Mef0w3APdor7K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;IMG_20240215_145719.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240215_134749.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFY6lG/btsE99qIBME/4szO6j9OZpvMazREBOxhIk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFY6lG/btsE99qIBME/4szO6j9OZpvMazREBOxhIk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFY6lG/btsE99qIBME/4szO6j9OZpvMazREBOxhIk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFY6lG%2FbtsE99qIBME%2F4szO6j9OZpvMazREBOxhIk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;2252&quot; data-filename=&quot;IMG_20240215_134749.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;2252&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240215_191457.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IpZhn/btsFb7Tawhb/eZKD6OkrZ76WjHdubqkBR0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IpZhn/btsFb7Tawhb/eZKD6OkrZ76WjHdubqkBR0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IpZhn/btsFb7Tawhb/eZKD6OkrZ76WjHdubqkBR0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIpZhn%2FbtsFb7Tawhb%2FeZKD6OkrZ76WjHdubqkBR0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;IMG_20240215_191457.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vAyG0/btsFeTMUKsU/08AWi00EdYTrPSUdZLuX5k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vAyG0/btsFeTMUKsU/08AWi00EdYTrPSUdZLuX5k/img.jpg&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;1868&quot; data-origin-height=&quot;4000&quot; data-filename=&quot;IMG_20240215_191526.jpg&quot; style=&quot;width: 37.9269%; margin-right: 10px;&quot; data-widthpercent=&quot;38.37&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vAyG0/btsFeTMUKsU/08AWi00EdYTrPSUdZLuX5k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvAyG0%2FbtsFeTMUKsU%2F08AWi00EdYTrPSUdZLuX5k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1868&quot; height=&quot;4000&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s6sVn/btsFcCFogfA/QRfmLj0PbQ6GhwgmPE9ou1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s6sVn/btsFcCFogfA/QRfmLj0PbQ6GhwgmPE9ou1/img.jpg&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&quot; data-filename=&quot;IMG_20240216_181631.jpg&quot; style=&quot;width: 60.9104%;&quot; data-widthpercent=&quot;61.63&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s6sVn/btsFcCFogfA/QRfmLj0PbQ6GhwgmPE9ou1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs6sVn%2FbtsFcCFogfA%2FQRfmLj0PbQ6GhwgmPE9ou1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;4000&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240216_181551.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYoYGs/btsFesPy6Cc/RNbExSACs3crLCpuCoK8e1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYoYGs/btsFesPy6Cc/RNbExSACs3crLCpuCoK8e1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYoYGs/btsFesPy6Cc/RNbExSACs3crLCpuCoK8e1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYoYGs%2FbtsFesPy6Cc%2FRNbExSACs3crLCpuCoK8e1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;IMG_20240216_181551.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240217_172421.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3R9I5/btsE970NK8z/Y2k3k39KmCOmjPnCFBC5v1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3R9I5/btsE970NK8z/Y2k3k39KmCOmjPnCFBC5v1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3R9I5/btsE970NK8z/Y2k3k39KmCOmjPnCFBC5v1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3R9I5%2FbtsE970NK8z%2FY2k3k39KmCOmjPnCFBC5v1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;IMG_20240217_172421.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240217_172927.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9gAeP/btsFcm3HVOT/4JeK0kKxeajXBD5YdXdPq1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9gAeP/btsFcm3HVOT/4JeK0kKxeajXBD5YdXdPq1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9gAeP/btsFcm3HVOT/4JeK0kKxeajXBD5YdXdPq1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9gAeP%2FbtsFcm3HVOT%2F4JeK0kKxeajXBD5YdXdPq1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;IMG_20240217_172927.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240217_172955.jpg&quot; data-origin-width=&quot;3392&quot; data-origin-height=&quot;1580&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CLcUF/btsFb6Nuyat/Ki8A1ukuORbmodWo5N1yak/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CLcUF/btsFb6Nuyat/Ki8A1ukuORbmodWo5N1yak/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CLcUF/btsFb6Nuyat/Ki8A1ukuORbmodWo5N1yak/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCLcUF%2FbtsFb6Nuyat%2FKi8A1ukuORbmodWo5N1yak%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3392&quot; height=&quot;1580&quot; data-filename=&quot;IMG_20240217_172955.jpg&quot; data-origin-width=&quot;3392&quot; data-origin-height=&quot;1580&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240217_173012.jpg&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DxpUA/btsFbWEngW2/7XyrMkJXNCt5Ql4orDAjaK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DxpUA/btsFbWEngW2/7XyrMkJXNCt5Ql4orDAjaK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DxpUA/btsFbWEngW2/7XyrMkJXNCt5Ql4orDAjaK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDxpUA%2FbtsFbWEngW2%2F7XyrMkJXNCt5Ql4orDAjaK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;4000&quot; data-filename=&quot;IMG_20240217_173012.jpg&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240217_180624.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dx5w3K/btsFdqdFzQm/rc4YHWXwvBSNhJ7nOFUG71/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dx5w3K/btsFdqdFzQm/rc4YHWXwvBSNhJ7nOFUG71/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dx5w3K/btsFdqdFzQm/rc4YHWXwvBSNhJ7nOFUG71/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdx5w3K%2FbtsFdqdFzQm%2Frc4YHWXwvBSNhJ7nOFUG71%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;IMG_20240217_180624.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240217_180733.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2VSij/btsFdnuqzwL/30iQKGFXiNpkP07t0J80uK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2VSij/btsFdnuqzwL/30iQKGFXiNpkP07t0J80uK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2VSij/btsFdnuqzwL/30iQKGFXiNpkP07t0J80uK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2VSij%2FbtsFdnuqzwL%2F30iQKGFXiNpkP07t0J80uK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;IMG_20240217_180733.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240217_180918.jpg&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dD4ajn/btsFbUT6Y7F/FLVKyzzMPCngLXImmirRT1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dD4ajn/btsFbUT6Y7F/FLVKyzzMPCngLXImmirRT1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dD4ajn/btsFbUT6Y7F/FLVKyzzMPCngLXImmirRT1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdD4ajn%2FbtsFbUT6Y7F%2FFLVKyzzMPCngLXImmirRT1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;4000&quot; data-filename=&quot;IMG_20240217_180918.jpg&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240217_181116.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clyTG3/btsFbXC7Prj/toKDtTPFV8L1vbSrkLn1ak/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clyTG3/btsFbXC7Prj/toKDtTPFV8L1vbSrkLn1ak/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clyTG3/btsFbXC7Prj/toKDtTPFV8L1vbSrkLn1ak/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclyTG3%2FbtsFbXC7Prj%2FtoKDtTPFV8L1vbSrkLn1ak%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;IMG_20240217_181116.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240217_181212.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/F24hd/btsFdoGT1vB/mOXDkKgKaGJ7KKXwxGhme1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/F24hd/btsFdoGT1vB/mOXDkKgKaGJ7KKXwxGhme1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/F24hd/btsFdoGT1vB/mOXDkKgKaGJ7KKXwxGhme1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FF24hd%2FbtsFdoGT1vB%2FmOXDkKgKaGJ7KKXwxGhme1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;IMG_20240217_181212.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240217_181221.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bO8Dxw/btsFbhotrkI/8GTUB9sgXWFRtoaqSr4jcK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bO8Dxw/btsFbhotrkI/8GTUB9sgXWFRtoaqSr4jcK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bO8Dxw/btsFbhotrkI/8GTUB9sgXWFRtoaqSr4jcK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbO8Dxw%2FbtsFbhotrkI%2F8GTUB9sgXWFRtoaqSr4jcK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;IMG_20240217_181221.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240217_181425.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c1yoJs/btsFeDwDBid/ToDSmNPCZPuMqQU7FkGST0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c1yoJs/btsFeDwDBid/ToDSmNPCZPuMqQU7FkGST0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c1yoJs/btsFeDwDBid/ToDSmNPCZPuMqQU7FkGST0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc1yoJs%2FbtsFeDwDBid%2FToDSmNPCZPuMqQU7FkGST0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;IMG_20240217_181425.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240217_203815.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIQqAq/btsFdECPXBE/NX5qL8TYEKkL8671xcy7fK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIQqAq/btsFdECPXBE/NX5qL8TYEKkL8671xcy7fK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIQqAq/btsFdECPXBE/NX5qL8TYEKkL8671xcy7fK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIQqAq%2FbtsFdECPXBE%2FNX5qL8TYEKkL8671xcy7fK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;IMG_20240217_203815.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240217_193341.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bodmnv/btsFbhIKK6v/IeKkbCvPDnzJCnul3hOC9k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bodmnv/btsFbhIKK6v/IeKkbCvPDnzJCnul3hOC9k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bodmnv/btsFbhIKK6v/IeKkbCvPDnzJCnul3hOC9k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbodmnv%2FbtsFbhIKK6v%2FIeKkbCvPDnzJCnul3hOC9k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;IMG_20240217_193341.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240217_203829.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bElO7G/btsFbfxqyfD/8O82ktazTiEOStYPbEmAAK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bElO7G/btsFbfxqyfD/8O82ktazTiEOStYPbEmAAK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bElO7G/btsFbfxqyfD/8O82ktazTiEOStYPbEmAAK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbElO7G%2FbtsFbfxqyfD%2F8O82ktazTiEOStYPbEmAAK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;IMG_20240217_203829.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_20240217_205744.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Uw0fX/btsFdWi5trD/aH0dT6RRVA9TNyWQVrm0sk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Uw0fX/btsFdWi5trD/aH0dT6RRVA9TNyWQVrm0sk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Uw0fX/btsFdWi5trD/aH0dT6RRVA9TNyWQVrm0sk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUw0fX%2FbtsFdWi5trD%2FaH0dT6RRVA9TNyWQVrm0sk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4000&quot; height=&quot;3000&quot; data-filename=&quot;IMG_20240217_205744.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Gallery</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/40</guid>
      <comments>https://techsuda.tistory.com/entry/%EB%AA%87%EB%85%84%EB%A7%8C%EC%97%90-%EB%B2%A0%ED%8A%B8%EB%82%A8-%EA%B3%A8%ED%94%84#entry40comment</comments>
      <pubDate>Thu, 22 Feb 2024 16:37:14 +0900</pubDate>
    </item>
    <item>
      <title>[ Flutter / Python ] 좌표 (위도, 경도) 값으로 국내/해외 판단</title>
      <link>https://techsuda.tistory.com/entry/Flutter-Python-%EC%A2%8C%ED%91%9C-%EC%9C%84%EB%8F%84-%EA%B2%BD%EB%8F%84-%EA%B0%92%EC%9C%BC%EB%A1%9C-%EA%B5%AD%EB%82%B4%ED%95%B4%EC%99%B8-%ED%8C%90%EB%8B%A8</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;요즘 위치정보 관련한 나만의 프로젝트를 진행하고 있는데 POI, Geocoding, Reverse Geo, 경로찾기 등 지도 위에서 할수 있는 많은 기능들이 필요한 상황이다. 그중 국내 POI정보는 우리나라 지도제공업체가 너무도 좋은데 결정적으로 무료 조회건수를 넘어가면 유료로 사용해야 하는 기능들이다. (현재 Naver, Kakao, SK, V-World 이렇게 사용해 봤는데 개인적으로 V-World API 가 가장 좋은 것 같다. 정부에서 제공하는 API 서비스이며 내게 필요한 서비스들은 거의 무료로 이용이 가능하다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;다국어 버전을 지원하려고 하다보니, 국내 지도에서 필요한 POI검색, Geocoding, Reverse Geo 부분은 V-World API를 사용하고 우리나라를 제외한 모든 국가에서는 Python 의 geopy 를 사용한다. (이 또한 무료건수가 정해져 있기는 하나, 해외 버전은 추후 다시 고민하고자 한다.)&lt;br /&gt;지도는 OSM(OpenStreetMap) 을 사용하고 있다.&lt;br /&gt;이러한 상황이다 보니 해외 정보를 사용할때는 geopy 로 만든 API를 호출하고 국내 정보를 사용할때는 V-World API를 호출하려고 했는데, 딸랑 좌표( 위도/경도 )&amp;nbsp; 정보만 가지고 국내외 구분을 하려니 도대체가 방법을 모르겠다는...... 한참 고민했는데 누군가의 블로그에서 그 해답을 찾았다. (&lt;s&gt;근데 그 블로그를 못찾겠다. 지금 설명하려는 멋진 방법을 일러줬는데...... 추후 혹 다시 찾게 되면 출처를 분명히 하도록 하겠다.&lt;/s&gt;&lt;br /&gt;여기에 잘 설명되어 있다 - &lt;a href=&quot;https://bowbowbow.tistory.com/24&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://bowbowbow.tistory.com/24&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;결론부터 쉽게 설명하자면 주어진 위치정보의 좌표값이 해당 영역 Polygon 내에 존재하는지 판단하는 방법은 좌표값의 경도보다 크고, 좌표의 위도(latitude)값을 포함하는 Polygon 선분의 교차점 수가 짝수 인지 홀수 인지만 판단하면 된다.&lt;br /&gt;홀수 이면 Polygon 영역 내부에 존재(국내)하며, 0 또는 짝수 이면 Polygon 영역 외부에 존재(해외) 하는것으로 정의할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;412&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dckAWp/btsDIuJJ4Ch/zA2WfgR4Q0rTCBCt6EEDd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dckAWp/btsDIuJJ4Ch/zA2WfgR4Q0rTCBCt6EEDd0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dckAWp/btsDIuJJ4Ch/zA2WfgR4Q0rTCBCt6EEDd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdckAWp%2FbtsDIuJJ4Ch%2FzA2WfgR4Q0rTCBCt6EEDd0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1168&quot; height=&quot;412&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;412&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;좌측&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;의&lt;/span&gt;&amp;nbsp;경우 중심좌표의 경도보다 크고 Polygon 동일한 위도와의 교차점 갯수 5개 이므로 국내&lt;br /&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;우측의 경우 중심좌표의 경도보다 크고 Polygon 동일한 위도와의 교차점 갯수 4개 이므로&lt;span&gt; &lt;/span&gt;&lt;/span&gt;해외 라고 판단한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;자 그럼 판단 방식은 알았으니 Flutter로 구현해 보자.&lt;br /&gt;우선 우리나라를 구분하기 위한 Polygon 값을 통해서 지정해 주자. (필자는 GoogleMap 에서 좌표를 읽어오는 것이 가장 편했던 것 같다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock floatLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;647&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PoALh/btsDHr0K2kS/tForTvhRGetRBcR0l9GzY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PoALh/btsDHr0K2kS/tForTvhRGetRBcR0l9GzY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PoALh/btsDHr0K2kS/tForTvhRGetRBcR0l9GzY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPoALh%2FbtsDHr0K2kS%2FtForTvhRGetRBcR0l9GzY1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;257&quot; height=&quot;232&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;647&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;좌측의 그림과 같이 임의로 우리나라를 경계지을 수 있는 Polygon 꼭지점들을 지정하고 그 좌표값(위도/경도)들을 Polygon List변수에 저장해 둔다.&lt;br /&gt;그리고 Parameter로 전달받은 좌표가 국내인지 해외인지 판단 여부는, Loop를 돌면서 전달 좌표의 위도를 포함하는 Polygon 선분인지, 그리고 전달 좌표의 경도보다 큰 값을 포함하는 Polygon의 접점 갯수를 판단하면 된다. 좌측 그림의 경우 Polygon을 구성하는 각각의 선분 갯수는 10개 이므로 전달좌표의 경도값보다 크고 전달좌표의 위도값을 포함하는 각 선분의 교차점 수를 확인하면 된다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #1a5490;&quot;&gt;하나 주의해야 할 점은 Polygon 영역을 설정할때 위도와 경도의 범위이다. 경도값의 범위는 영국 본초자오선을 기준으로 동경 (+)180˚ 서경 (-)180˚ 이므로 본초자오선(0˚) 이하 서경이 포함되는 국가의 Polygon을 설정할때는 경도 범위가 -180˚&amp;nbsp; ~&amp;nbsp; +180˚&amp;nbsp; 임을 감안하여 수정해야 할 것이다. 또한 위도의 경우 북반구/남반구 로 구분되어지며 -90&lt;b&gt;&lt;span style=&quot;color: #1a5490;&quot;&gt;˚&lt;/span&gt;&lt;/b&gt; ~ +90&lt;b&gt;&lt;span style=&quot;color: #1a5490;&quot;&gt;˚ 이므로 잘 구분해서 사용하면 될 것 같다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;필자의 경우 우리나라만 구분하면 되었기 때문에 서경 처리는 들어가 있지 않다.&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #4d5156; text-align: left;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #1f1f1f; color: #cccccc;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// ==========================================================================================&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// 해당 위치의 국내 여부를 Return (국내이면 V-World API Call, 아니면 &amp;nbsp;GeoPY Call)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;//&lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt; ==========================================================================================&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;Future&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;bool&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;getKoreaInOut&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;LatLng&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;param&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;&amp;nbsp; List&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;LatLng&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;koreaPolygon&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; [&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;LatLng&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;37.6831695&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;125.6191259&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;),&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;LatLng&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;38.3667171&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;127.1262549&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;),&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;LatLng&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;38.66153134451637&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;128.11958997893478&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;),&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;LatLng&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;38.83072480089188&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;128.33652521686935&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;),&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;LatLng&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;37.23575633088098&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;132.1635851464025&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;),&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;LatLng&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;34.76303366422911&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;129.3075404873899&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;),&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;LatLng&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;32.447247860726925&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;126.6921063701961&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;),&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;LatLng&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;33.8033764&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;124.7198601&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;),&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;LatLng&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;37.128143428704334&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;124.27747776186246&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; ];&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;pLen&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;span style=&quot;color: #9cdcfe; text-align: start;&quot;&gt;koreaPolygon&lt;/span&gt; &lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;pLen&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;) {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;bool&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;isIn&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;prev&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;pLen&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;cur&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;cur&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;pLen&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;cur&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;) {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;LatLng&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;curPos&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;span style=&quot;color: #9cdcfe; text-align: start;&quot;&gt;koreaPolygon&lt;/span&gt; &lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;cur&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;];&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;LatLng&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;prevPos&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;span style=&quot;color: #9cdcfe; text-align: start;&quot;&gt;koreaPolygon&lt;/span&gt; &lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;prev&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;];&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;max&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;curPos&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;latitude&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;prevPos&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;latitude&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;param&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;latitude&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;min&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;curPos&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;latitude&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;prevPos&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;latitude&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;param&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;latitude&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;) {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;curPos&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;longitude&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;+ &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;((&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;param&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;latitude&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;curPos&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;latitude&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;/ &lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;prevPos&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;latitude&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;curPos&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;latitude&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;)) &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;* &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;prevPos&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;longitude&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;curPos&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;longitude&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;param&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;longitude&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;) {&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;isIn&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;isIn&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;prev&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;cur&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; }&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;isIn&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;showToast&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;'국내'&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;'t'&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;showToast&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;'해외'&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;'t'&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;isIn&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;위 코드와 같이 우리나라를 경계할 수 있는 Polygon영역을 좌표로 지정한 후, 직선 방정식 y2 - y1 = M * (x2 - x1) 의 x좌표를 경도로 y좌표를 위도로 치환시켜 작성한 코드이다. 이를 실행해 보면 국내외 판단결과를 정상적으로 리턴해 주는 것을 확인할 수 있을 것이다.&lt;br /&gt;필자의 경우 해당 위치의 POI검색 또는 Geocode/RevGeocode API 호출 시 국내이면 V-World API를 호출하고, 해외의 경우 ORM의 API호출 하도록 작성했다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/39</guid>
      <comments>https://techsuda.tistory.com/entry/Flutter-Python-%EC%A2%8C%ED%91%9C-%EC%9C%84%EB%8F%84-%EA%B2%BD%EB%8F%84-%EA%B0%92%EC%9C%BC%EB%A1%9C-%EA%B5%AD%EB%82%B4%ED%95%B4%EC%99%B8-%ED%8C%90%EB%8B%A8#entry39comment</comments>
      <pubDate>Mon, 22 Jan 2024 13:29:07 +0900</pubDate>
    </item>
    <item>
      <title>[ SQLiTE ] Local DB Update process (2)</title>
      <link>https://techsuda.tistory.com/entry/SQLiTE-Local-DB-Update-process-2</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;이전글 : &lt;a href=&quot;https://techsuda.tistory.com/36&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;[ SQLiTE ] Local DB Update process (1)&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;현재까지 Flutter 로 만든 앱들의 동작 환경을 살펴보면 휴대폰 내부에서는 SQLiTE 를 사용하고, 서버는 주로 Docker 로 구축한 MariaDB (또는 MySQL)로 되어있다. 서버와의 통신은 Python 으로 만든 RestAPI 호출로 운영하고 있으며 SSL 적용한 WEB Server 도 컨테이너로 돌아가고 있다.&amp;nbsp; &amp;nbsp;(참고 : &lt;a title=&quot;필자의 개발환경에 대해&quot; href=&quot;https://blog.itgosuda.com/32&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[Environment] 개발 환경에 대해... )&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;처음에는 Database Update를 위해 효율 보다는 빠른 구축이 먼저였기에 서버의 API를 통해 버전번호를 체크/비교하면서 변경된 데이터를 조회해 온 후 휴대폰 내부의 SQLiTE에 Insert 와 Update 쿼리를 사용해 업데이트를 하면서 서버 Data와 Sync(동기화)를 해오고 있었다.&lt;br /&gt;하지만 사용자가 많이 늘어나고 조금씩이지만 Update해야할 데이터들이 계속 누적되다 보면 Update를 위한 API 호출할 때 마다 응답받는 결과값의 사이즈는 계속 증가될 수 밖에 없으며 Connection 유지 시간 내에 데이터 처리를 못하게 되는 경우도 발생할 수 있기 때문에, API 호출 횟수를 여러번에 나눠서 호출해야 하는 경우도 발생 할 수 있다. 업데이트 시간을 조금이라도 더 줄이기 위해 Batch 처리를 하더라도, 이는 곧 서버에 주는 부하가 증가할 수 밖에 없음을 의미한다. 이러한 방식은 시간이 흐를 수록 신규 유저와 가끔 앱을 실행시키는 유저에게는 업데이트 하는 시간이 무척이나 길고도 지루한 기다림이 될 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;그렇다면 해결 방법은?&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;업데이트 해야 할 데이터를 RestAPI 를 호출해서 응답받고 처리하고, 호출하고 응답 받고 처리하고... &lt;br /&gt;이러한 방식 보다는 DB파일을 다운로드 받아서 통으로 교체하는 것이 훨씬 더 빠르게 처리 될 수 있지 않겠는가?&lt;br /&gt;물론 서버에 최신의 DB파일이 준비되어 있어야 하고, 이를 위해 서버에서 스케쥴링 된 프로그램도 미리 만들어 두고, 다운로드를 위한 WEB 서버도 운영을 해야한다는 전제 조건이 있으며, DB파일의 사이즈도 제대로 비교/분석 해봐야 겠지만, 대개의 일반적인 경우 장점이 훨씬 더 많기에 필자는 DB파일 교체 방식을 더 선호하고 있다. 파일 다운로드는 비교적 수초 이내에 완료 되며 API 호출 결과값으로 DB를 업데이트 하는 방식보다는 월등히 빠르고 서버의 API 호출 부하를 크게 낮출 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1693&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCW8ZY/btsCwQURU5c/KXdvYUvmDauRHStTZsWcdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCW8ZY/btsCwQURU5c/KXdvYUvmDauRHStTZsWcdk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCW8ZY/btsCwQURU5c/KXdvYUvmDauRHStTZsWcdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCW8ZY%2FbtsCwQURU5c%2FKXdvYUvmDauRHStTZsWcdk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1693&quot; height=&quot;593&quot; data-origin-width=&quot;1693&quot; data-origin-height=&quot;593&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;대략 위 도표와 같은 프로세스로 휴대폰 내부의 SQLiTE 파일을 업데이트 할 수 있다.&lt;br /&gt;핵심 포인트는 사용자정보 테이블의 내용은 사용자별로 계속 유지할 수 있도록, Attach 명령과 함께 Dot명령(.dump) 을 대신하는 Query를 사용 했다는 점이다.&lt;/p&gt;</description>
      <category>Tech Story</category>
      <category>API</category>
      <category>Attach</category>
      <category>database</category>
      <category>Flutter</category>
      <category>MariaDB</category>
      <category>MySQL</category>
      <category>Python</category>
      <category>SQLite</category>
      <category>Update</category>
      <category>버전</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/38</guid>
      <comments>https://techsuda.tistory.com/entry/SQLiTE-Local-DB-Update-process-2#entry38comment</comments>
      <pubDate>Fri, 22 Dec 2023 22:32:08 +0900</pubDate>
    </item>
    <item>
      <title>어린 시절 소중한 벗들과 송년 모임</title>
      <link>https://techsuda.tistory.com/entry/%EC%96%B4%EB%A6%B0-%EC%8B%9C%EC%A0%88-%EC%86%8C%EC%A4%91%ED%95%9C-%EB%B2%97%EB%93%A4%EA%B3%BC-%EC%86%A1%EB%85%84-%EB%AA%A8%EC%9E%84</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;연말이면 항상 지나온 1년을 돌이켜 보면서 다가올 1년을 준비하는 때여서 그런가? 저녁마다 모임도 많고 정신없이 바쁠때이다.&lt;br /&gt;많은 모임들 가운데 가장 기다려지고 반가운 모임은 역시 꼬꼬마 어린 시절 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;중딩때 부터&lt;span&gt; &lt;/span&gt;&lt;/span&gt;의 추억을 공유하고 있는 동네 친구들이 아닐까 싶다.&lt;br /&gt;지금은 다들 대학에서, 기업에서, 자영업에서 각자가 선택하고 준비한 인생을 최선을 다해 살고 있다. 연말 요맘때 즈음 이렇게 만나면 각자의 마음속에 간직하고 있던 추억의 단편들을 하나씩 하나씩 꺼내어 서로 나누고 공유하게 된다.&lt;br /&gt;이렇게 소중한 친구들과 함께하는 저녁 시간은, 다시 다가오는 한해를 헤쳐나갈 자신감이 되기도 하고 힘든 기억이 있었다면 그에 대한 위로가 되기도 한다.&lt;br /&gt;&lt;br /&gt;나는 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;또 이렇게&lt;span&gt; &lt;/span&gt;&lt;/span&gt;소중한 추억을 만들고 기억속에 담아 본다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVySjs/btsCtoKwN9c/uBUVVHKA4AkoBQWy3vtGzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVySjs/btsCtoKwN9c/uBUVVHKA4AkoBQWy3vtGzk/img.png&quot; data-origin-width=&quot;1293&quot; data-origin-height=&quot;696&quot; data-is-animation=&quot;false&quot; style=&quot;width: 40.806%; margin-right: 10px;&quot; data-widthpercent=&quot;41.78&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVySjs/btsCtoKwN9c/uBUVVHKA4AkoBQWy3vtGzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVySjs%2FbtsCtoKwN9c%2FuBUVVHKA4AkoBQWy3vtGzk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1293&quot; height=&quot;696&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdH6Ld/btsCuZjbHLu/uW7pKZ5B5tW29I7hJ9PDdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdH6Ld/btsCuZjbHLu/uW7pKZ5B5tW29I7hJ9PDdk/img.png&quot; data-origin-width=&quot;402&quot; data-origin-height=&quot;468&quot; data-is-animation=&quot;false&quot; style=&quot;width: 18.8675%; margin-right: 10px;&quot; data-widthpercent=&quot;19.32&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdH6Ld/btsCuZjbHLu/uW7pKZ5B5tW29I7hJ9PDdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdH6Ld%2FbtsCuZjbHLu%2FuW7pKZ5B5tW29I7hJ9PDdk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;402&quot; height=&quot;468&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d4QL4m/btsCt4dZD3v/atKuqKTFH8XADBBu9F4EE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d4QL4m/btsCt4dZD3v/atKuqKTFH8XADBBu9F4EE0/img.png&quot; data-origin-width=&quot;1019&quot; data-origin-height=&quot;589&quot; data-is-animation=&quot;false&quot; style=&quot;width: 38.0009%;&quot; data-widthpercent=&quot;38.9&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d4QL4m/btsCt4dZD3v/atKuqKTFH8XADBBu9F4EE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd4QL4m%2FbtsCt4dZD3v%2FatKuqKTFH8XADBBu9F4EE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1019&quot; height=&quot;589&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Life Story</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/37</guid>
      <comments>https://techsuda.tistory.com/entry/%EC%96%B4%EB%A6%B0-%EC%8B%9C%EC%A0%88-%EC%86%8C%EC%A4%91%ED%95%9C-%EB%B2%97%EB%93%A4%EA%B3%BC-%EC%86%A1%EB%85%84-%EB%AA%A8%EC%9E%84#entry37comment</comments>
      <pubDate>Fri, 22 Dec 2023 15:38:42 +0900</pubDate>
    </item>
    <item>
      <title>[ SQLiTE ] Local DB Update process (1)</title>
      <link>https://techsuda.tistory.com/entry/SQLiTE-Local-DB-Update-process</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;일전에 지자체에서 운영하는 Android 와 iOS &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;앱을&lt;span&gt; &lt;/span&gt;&lt;/span&gt;개발해준 적이 있다. 지자체 서버에서 제공하는 API를 호출하고 그 결과를 앱에 표현해 주는 앱인데 API호출 회수를 최소화 하기 위해 대부분의 데이터는 휴대폰의 SQLiTE 에 저장하고 사용했다. 또한 서버와의 동기화(S&lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: left;&quot;&gt;ynchronization&lt;/span&gt;)를 위해 &lt;span style=&quot;color: #202124;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;Update가 필요한 테이블별 Version No를 Check하여 Local 과 Server 의 &lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot;&gt;DB&lt;/span&gt; 동기화를 진행해 왔다.&lt;br /&gt;&lt;br /&gt;고도화 작업까지 완료된 꽤 긴 기간동안 작업했던 앱이었기에, 초기의 앱과 비교해 보면 디자인부터 기능까지 무척이나 많은 변화를 간직하고 있는 앱이다. 오늘은 수많은 변화 중 Database 의 Table data Update 관련한 몇가지를 얘기하고자 한다.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #202124;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;우선 서버는 Oracle &lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot;&gt;DB&lt;/span&gt; (가끔 Ora~~~ 어쩌고 저쩌고 하는 장애가 발생한 적이 있었다) 이며, 필자가 만든 앱 이외에도 기존에 사용해 왔고 현재도 계속 사용중인 몇몇 앱들이 더 있다. 동일한 Data를 바라보는 앱들이 몇몇 있다보니 Rest API를 쉽게 수정하기는 힘들었을 테니 서버의 Data가 변경되면 각각의 앱들이 각자 알아서 Local DB를 업데이트 할 수 있게끔 Version번호라는 것을 상황별로 이용하게끔 마련되어 있다.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #202124;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;br /&gt;개발 초기에 업데이트 모듈을 만들기 위해 첫번째 사용했던 방법은 로컬에 SQLiTE 파일 존재여부에 따라 존재하는 경우에는 버전번호를 비교하여 변경된 데이터만 API로 전달받아 Local DB를 업데이트 하고, SQLiTE파일 없는 경우에는 DDL (Data Definition Language) 을 사용해서 필요한 테이블들을 만들고 난 후 필요한 모든 Data는 &lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot;&gt;서버로부터&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; API 를 반복 호출하여 테이블에 Insert 했는데 이 과정이 너무 오래걸리고 서버에 부하를 너무 주게되어 바로 두번째 방법으로 프로세스를 변경했다.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #202124;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;br /&gt;그 두번째 방법은 버전번호로 업데이트하는 로직은 그대로 두고, DB 파일이 없을 경우에만 (앱을 최초에 설치할때만 DB파일이 없음) 미리 APK 파일 내부에 현행화 된 최신 버전의 DB 파일을 넣어두고 필요 시 앱 실행폴더로 Copy후 기존의 버전업데이트 작업을 진행했으며 현재 이 방식으로 User들의 앱내 DB Update는 순조롭게 진행 되고 있다.&lt;br /&gt;&lt;br /&gt;세번째 업데이트 방식은&amp;nbsp; DB File 교체방식인데 필자의 개인서버에 구축하고 테스트까지 했는데 주관사 요청에 의해 현재는 사용되지 않고 있다. 간단히 설명하자면 최신 내용의 DB를 유지하기 위해 모든 사용자가 Version Check API 와 Update API를 호출하는 것이 아니라, 최신상태의 SQLiTE DB 파일을 다운로드 받을 수 있도록 별도의 다운로드 서버를 운영하고 (끽해봐야 10MB 내외 사이즈의 DB 파일을 다운로드 할 수 있으면 되며, DIO 가 가장 편리했던 것 같다), 파이썬으로 새벽시간대에 한두번 그리고 오전에 한번 정도 스케쥴링 배치작업으로 최신데이터 현행화한 DB파일을 주기적으로 만들어서 다운로드 폴더에 복사하는 자동화 작업을 하는 것이다. 가장 안정적인 업데이트가 가능하고 지자체 서버에 업데이트 관련 API 호출은 &lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot;&gt;Python 예약한 작업시간에 호출하는 경우&lt;/span&gt; 외 일반 사용자 업데이트 호출은 전혀 없기 때문에 서버의 부하도 크게 줄일 수 있는데...... 암튼 지금은 사용하지 않고 있는 업데이트 방식이다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #202124;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;업데이트 모듈을 구성할때 가장 고심했던 것 중 하나가 바로 사용자 정의 데이터 유지 문제였다. 회원가입이 필요하지도 않고 앱을 제거하면 로컬 디비라든가 모든 정보들이 다 삭제되기 때문에, 재설치를 한다고 해도 이전 사용자 정의 데이터가 남아 있지 않기 때문이다.&lt;br /&gt;뭐 꼭 해결해야 한다면 유지해야 할 Data를 추출해서 파일로 생성해서 앱영역이 아닌 사용자 접근영역에 별도로 옮겨놓거나 하고 필요할때 복원할 수 있게 만들 수도 있겠으나 복잡하게 만들면 또 다른 민원을 불러오게 된다.&lt;br /&gt;필자도 딱 거기까지만 지원해주기로 했다. 재설치를 제외한 업데이트는 사용자가 설정한 정보가 그대로 유지되게끔......&lt;br /&gt;여러가지 방법이 있겠으나 익숙한 것을 사용해야겠다 싶어서 shared_preferences 을 이용해 사용자 설정 정보를 Key:Value 방식으로 잠깐 저장해 두었다가 DB 업데이트가 종료되면 해당 테이블의 내용 Delete 후 임시저장한 내용을 테이블에 Insert 하는 방식을 사용했다.&lt;br /&gt;Format 이 바뀌거나 하면 코드를 재수정해야 한다는 부담이 있지만 바뀔 가능성이 거의 없는 기본 포맷이었고 데이터도 그다지 많지 않기 때문에 마음에는 안들지만 이 문제로 시끄러울 일은 없다고 판단되며 현재까지도 아직 문제 발생은 없었다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #202124;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;Local에서 SQLiTE 를 사용할 경우 다음과 같은 몇가지 특성은 정확히 인지하고 있어야 할 것 같다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #202124;&quot;&gt;&lt;span style=&quot;color: #202124;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;- &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;SQLiTE File 1 개 = Database 1 개&lt;/b&gt; &lt;/span&gt;: MySQL 이나 MariaDB 처럼 하나의 파일안에 여러개의 데이터베이스가 존재할 수 없고, 하나의 파일에는 하나의 데이터베이스만 존재함&lt;br /&gt;&lt;br /&gt;- &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;TRUNCATE&lt;/span&gt; 명령의 부재&lt;/b&gt; : Truncate명령은 없지만 DELETE 명령으로 Data삭제 후 sequence 값을 초기화하면 TRUNCATE 동일하게 수행&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;ex)&amp;nbsp; &amp;nbsp; DELETE FROM 테이블명;&amp;nbsp; &amp;nbsp;// Truncate 할 대상 테이블의 데이터 모두 삭제&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;UPDATE SQLITE_SEQUENCE SET seq = 0 where name = 테이블명;&amp;nbsp; &amp;nbsp; &amp;nbsp;// 대상 테이블의&amp;nbsp; &lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;sequence 값을 초기화&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;- Dot Command 사용 : SQLiTE에도 .dump 같은 DOT명령을 사용할 수 있으나 OS 터미널에서 사용할 수 있기에 Flutter 의 sqflite 패키지 내에서 사용할 수 있는 방법이 없는 듯 하다. (Dot 명령어는 Query 문장이 아니기 때문에 사용할 수 없는 것 아닐까? Dot명령어를 Flutter 패키지 내에서 사용할 수 있는 방법을 알고 계신 분 계시면 힌트라도 좀...... )&amp;nbsp;&lt;br /&gt;필자의 경우 .dump 명령이 절실했는데 도트명령을 사용할 방법이 없어서 다른 방법을 찾아 해결했다.&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;color: #6164c6;&quot;&gt;&lt;b&gt;=====&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; 이 부분은 다음 포스팅 할때 좀 더 자세히 설명 하고자 한다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; 다음글 : &lt;a title=&quot;[ SQLiTE ] Local DB Update process (2)&quot; href=&quot;https://techsuda.tistory.com/38&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[ SQLiTE ] Local DB Update process (2)&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XbbHG/btsCtHCuCMY/dSkk06mslKmPoKSpesSsf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XbbHG/btsCtHCuCMY/dSkk06mslKmPoKSpesSsf1/img.png&quot; data-origin-width=&quot;942&quot; data-origin-height=&quot;881&quot; data-is-animation=&quot;false&quot; width=&quot;464&quot; height=&quot;434&quot; data-widthpercent=&quot;46.8&quot; style=&quot;width: 46.2581%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XbbHG/btsCtHCuCMY/dSkk06mslKmPoKSpesSsf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXbbHG%2FbtsCtHCuCMY%2FdSkk06mslKmPoKSpesSsf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;942&quot; height=&quot;881&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nN2x6/btsCuMp5cFG/DA4UkZHvZh5iFkrWWwgJk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nN2x6/btsCuMp5cFG/DA4UkZHvZh5iFkrWWwgJk1/img.png&quot; data-origin-width=&quot;491&quot; data-origin-height=&quot;404&quot; data-is-animation=&quot;false&quot; style=&quot;width: 52.5791%;&quot; data-widthpercent=&quot;53.2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nN2x6/btsCuMp5cFG/DA4UkZHvZh5iFkrWWwgJk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnN2x6%2FbtsCuMp5cFG%2FDA4UkZHvZh5iFkrWWwgJk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;491&quot; height=&quot;404&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #202124;&quot;&gt;&lt;span style=&quot;color: #202124;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #6164c6;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #202124;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <category>.dump</category>
      <category>Dot Command</category>
      <category>DOT명령</category>
      <category>Flutter</category>
      <category>MariaDB</category>
      <category>SQLite</category>
      <category>trunc</category>
      <category>Update</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/36</guid>
      <comments>https://techsuda.tistory.com/entry/SQLiTE-Local-DB-Update-process#entry36comment</comments>
      <pubDate>Fri, 22 Dec 2023 14:15:05 +0900</pubDate>
    </item>
    <item>
      <title>나의 대학시절 문화와 추억의 요모조모</title>
      <link>https://techsuda.tistory.com/entry/%EB%82%98%EC%9D%98-%EB%8C%80%ED%95%99%EC%8B%9C%EC%A0%88-%EC%B2%A8%EB%8B%A8-%EB%AC%B8%ED%99%94%EC%99%80-%EC%B6%94%EC%96%B5%EC%9D%98-%EC%9A%94%EB%AA%A8%EC%A1%B0%EB%AA%A8</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;컴퓨터 그중에서도 소프트웨어쪽을 전공했으니 대학때부터 시작해볼까?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/44MRJ/btsCkmdOzI5/ifzdLJgrNJHCJvw5s1UMQ0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/44MRJ/btsCkmdOzI5/ifzdLJgrNJHCJvw5s1UMQ0/img.jpg&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;395&quot; data-is-animation=&quot;false&quot; style=&quot;width: 37.2152%; margin-right: 10px;&quot; data-widthpercent=&quot;38.1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/44MRJ/btsCkmdOzI5/ifzdLJgrNJHCJvw5s1UMQ0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F44MRJ%2FbtsCkmdOzI5%2FifzdLJgrNJHCJvw5s1UMQ0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;395&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/diSQUf/btsCfZc6azV/yR9ZsgLXIUpUVKTpfQkO8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/diSQUf/btsCfZc6azV/yR9ZsgLXIUpUVKTpfQkO8k/img.png&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;643&quot; data-is-animation=&quot;false&quot; style=&quot;width: 23.7379%; margin-right: 10px;&quot; data-widthpercent=&quot;24.3&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/diSQUf/btsCfZc6azV/yR9ZsgLXIUpUVKTpfQkO8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdiSQUf%2FbtsCfZc6azV%2FyR9ZsgLXIUpUVKTpfQkO8k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;623&quot; height=&quot;643&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vCiw9/btsCc2VIUKT/Iw9WfRCbnHgR2U9ZcjVV60/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vCiw9/btsCc2VIUKT/Iw9WfRCbnHgR2U9ZcjVV60/img.jpg&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;427&quot; data-is-animation=&quot;false&quot; style=&quot;width: 36.7213%;&quot; data-widthpercent=&quot;37.6&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vCiw9/btsCc2VIUKT/Iw9WfRCbnHgR2U9ZcjVV60/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvCiw9%2FbtsCc2VIUKT%2FIw9WfRCbnHgR2U9ZcjVV60%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;640&quot; height=&quot;427&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;MS-DOS, 프롬프트, z80, 8088, 80286/386..., 모노크롬, 허큘리스, 5.25inch, 3.5inch, 플로피디스켓, 01410, ATDT, PC통신, 하이텔, 천리안, 나우누리, 베네치아, 모뎀, 사운드블라스터, 옥소리, 도깨비한글, 조합형/완성형한글, 오토마타, 램상주프로그램, 이야기, 하늘소, 핑퐁바이러스, 크리스마스바이러스, 양파바이러스, 백신, 어셈블리, Turbo-C, MASM, Inline-Assembly,&amp;nbsp; Pascal, COBOL, FORTRAN, GW-Basic, DBase+, CLIPPER, CRT, 흑백/컬러모니터, 도트프린터(80,136), 아래한글, 하나워드(군대에서 사용), 용산전자상가(내가 중학교때만해도 그냥 용산시장 이었던... 요때 난 원효로에 살고 있었다)...... 그리고 필자는 아마추어무선기사 3급 자격증도 있었는데 (HAM) 기기가 없어서 통신을 해본적은 한번도 없다. ㅎㅎ. 대충 생각나는 몇개만 적어보았는데 ..... ㅋㅋ. 그러고 보니 이런내용들이 나오는 영화도 몇개 생각나는게 있군. 접속, 동감 등등......&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;요즘의 젊고 스마트한 개발자님들에겐 다소 생소할 수도 있겠지만, 필자의 경우 요때를 머리속에 떠올리기만 해도 당시의 레트로 감성이 철철 넘쳐 마음속이 훈훈해져 오는 추억에 가끔 젖어들곤 한다. 추억이라 말할만큼 많은 세월을 지내온 것 이겠지만 말이다. 컴퓨터 조립해주고 수고비 받는 알바도 가끔 해보고, 집에서는 전화선을 이용하는 모뎀으로 PC통신도 하고, 통신 중 식구 중 누군가가 전화수화기를 들면 PC통신은 끊어져 버리는데 그럴때 마다 어머니가 말씀하신다. 전화비 많이 나온다. 작작 좀 해라. 그리고는 곧바로 날아오는 전광석화와도 같은 등짝 스매싱... ㅋㅋ. 아직까지도 모뎀 접속하는 소리가 기억속에 생생하다.&lt;br /&gt;아 그리고 추억의 소리가 하나 더 있다. 학교 전산실에서 들려오는 도트프린터의 출력소리... 페이지마다 뜯어낼 수 있도록 되어 박스안에 지그재그 식으로 길게 포개어져 있는 80컬럼 용지나 136컬럼 용지를 롤러 양끝에 있는 구멍에 맞춰넣고 출력하면 헤드가 좌우로 왔다 갔다하며 헤드앞 먹지 리본 위를 때리는 식으로 한줄씩 출력한다. 헤드에 핀 하나라도 고장나면 출력결과물에 하얀 줄이 생기고, 먹지는 쓸수록 색이 연해지므로 보일때 까지는 어떻게든 오래쓰려고 노력했었던 때이다. 출력할 양이 좀 많기라도 하면 밖에 나가 바람이라도 쏘이고 들어오면 출력이 끝난 용지가 차곡차곡 이쁘게 포개져 있는 모습을 볼 수 있었다. 에러가 없었을때... ㅋㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;아~~~ 오늘따라 대학때 친구들이 많이 보고싶네. 보고 싶으면 봐야지. 오랜만에...... ㅎㅎ&lt;/p&gt;</description>
      <category>Life Story</category>
      <category>PC통신</category>
      <category>도트프린터</category>
      <category>동감</category>
      <category>모뎀소리</category>
      <category>접속</category>
      <category>천리안</category>
      <category>추억</category>
      <category>하이텔</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/35</guid>
      <comments>https://techsuda.tistory.com/entry/%EB%82%98%EC%9D%98-%EB%8C%80%ED%95%99%EC%8B%9C%EC%A0%88-%EC%B2%A8%EB%8B%A8-%EB%AC%B8%ED%99%94%EC%99%80-%EC%B6%94%EC%96%B5%EC%9D%98-%EC%9A%94%EB%AA%A8%EC%A1%B0%EB%AA%A8#entry35comment</comments>
      <pubDate>Tue, 19 Dec 2023 19:19:41 +0900</pubDate>
    </item>
    <item>
      <title>[ Flutter ] Class, List, Map 등의 복사 (깊은복사, 얕은복사)</title>
      <link>https://techsuda.tistory.com/entry/Flutter-Class-List-Map-%EB%93%B1%EC%9D%98-%EB%B3%B5%EC%82%AC-%EA%B9%8A%EC%9D%80%EB%B3%B5%EC%82%AC-%EC%96%95%EC%9D%80%EB%B3%B5%EC%82%AC</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1351&quot; data-origin-height=&quot;229&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c2mZJn/btsB7WNn88x/MnAWn1dod7W8gBJ8Jq9IOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c2mZJn/btsB7WNn88x/MnAWn1dod7W8gBJ8Jq9IOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c2mZJn/btsB7WNn88x/MnAWn1dod7W8gBJ8Jq9IOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc2mZJn%2FbtsB7WNn88x%2FMnAWn1dod7W8gBJ8Jq9IOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1351&quot; height=&quot;229&quot; data-origin-width=&quot;1351&quot; data-origin-height=&quot;229&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;옛날에 한참 C, C++ 코딩할때는 포인터를 사용하는 Call by reference, Call by value 요렇게 2가지 타입 중 적절한 방법으로 자료처리를 해던 기억이 있다. 그때 당시는 주소참조방식 과 값참조방식 뭐 이렇게 이해하고 있었는데, 요즘은 이를 지칭하는 표현(단어)도 많이 바뀌어 있는 듯 하다( 내가 옛날사람이긴 한가 봐. ㅠㅠ). 플러터나 자바쪽에서는 깊은복사 와 얕은복사라는 표현을 주로 사용하고 있던데 개인적으로는 직관적이지 않아 아직도 헷갈리는 단어다. 그래서 요 부분에 대한 개인적인 정리 차원에서 블로그에 남겨두고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;Flutter(DART)에서 class, list, map 같은 객체(Object)를 다루다가 값이 이상하다는 생각이 들 때가 있다. 필자의 경우 코딩하면서 잠깐 복사해둔 리스트의 내용이 자꾸 바뀌기에 멀쩡한 다른 코드만 마구마구 변경하는 삽질의 시간을 보내고 난 후 알았다.&lt;br /&gt;List 복사는 Call by value 가 아니라 Call by reference 가 기본이라는 사실을.....&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;깊은복사(Deep copy) : 복사할 객체의 값(Value)를 복사&lt;/b&gt;&lt;br /&gt;&lt;b&gt;얕은복사(Shallow copy) : 복사할 객체가 저장되어 있는 참조값(주소 reference or address)을 복사&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;아마도 얕은복사라는 의미는 객체의 크기에는 상관없이 객체가 저장되어 있는 메모리의 시작 주소값 만을 가볍게 가져오기 때문에 그런것 같고, 같은 의미로 깊은 복사라 하면 객체의 크기만큼 똑같은 크기의 객체를 하나 더 만든다는 의미가 아닐까? 필자가 사용해왔던 몇가지 프로그래밍 언어들은 주로 깊은 복사( Call by value )가 기본이었던 것 같다. C 또는 Pascal 의 경우 얕은복사(Call by reference)를 위해서는 포인터연산자(*)를 써야만 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;하지만 플러터의 경우 String, 숫자형, bool, null 과 같은 기본데이터타입(단일형)을 제외한 모든 객체의 복사는 Call by reference 가 기본인 듯 하다. (Class, List, Map 등)&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;934&quot; data-origin-height=&quot;773&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TN9fn/btsB6lmRMzH/gw3u8OU7bGdFyNWGgecOXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TN9fn/btsB6lmRMzH/gw3u8OU7bGdFyNWGgecOXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TN9fn/btsB6lmRMzH/gw3u8OU7bGdFyNWGgecOXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTN9fn%2FbtsB6lmRMzH%2Fgw3u8OU7bGdFyNWGgecOXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;934&quot; height=&quot;773&quot; data-origin-width=&quot;934&quot; data-origin-height=&quot;773&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;296&quot; data-origin-height=&quot;185&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbIXVw/btsB7i36VzW/nx2t4Lsb69Qhu5pfCgt261/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbIXVw/btsB7i36VzW/nx2t4Lsb69Qhu5pfCgt261/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbIXVw/btsB7i36VzW/nx2t4Lsb69Qhu5pfCgt261/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbIXVw%2FbtsB7i36VzW%2Fnx2t4Lsb69Qhu5pfCgt261%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;296&quot; height=&quot;185&quot; data-origin-width=&quot;296&quot; data-origin-height=&quot;185&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;예제 화면에 출력값을 잘 살펴보면 Call by reference 와 Call by value 의 차이점을 알 수 있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;그리고 코드에 보면 [...list1] 이렇게 코딩되어 있는 부분을 볼 수 있다. Dot 3개가 있는 이것을 스프레드(Spread) 연산자 &quot;...&quot; 라고 하는데 Call by value 방식의 연산자 이다. 즉 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;새로운 저장공간을 생성하고 저장영역을 할당 후,&lt;/span&gt; 객체가 가지고 있는 Value들을 그대로 복사하고 새주소를 Return 하기 때문에 원본 객체의 변화에 영향을 받지 않는 Call by value 방식에 사용되어 진다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1211&quot; data-origin-height=&quot;326&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpjOhK/btsB8TJDWxC/GLs3DTVjgKYseMx6Pkvn01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpjOhK/btsB8TJDWxC/GLs3DTVjgKYseMx6Pkvn01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpjOhK/btsB8TJDWxC/GLs3DTVjgKYseMx6Pkvn01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpjOhK%2FbtsB8TJDWxC%2FGLs3DTVjgKYseMx6Pkvn01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1211&quot; height=&quot;326&quot; data-origin-width=&quot;1211&quot; data-origin-height=&quot;326&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;위에서 보면 list1 과 list2 의 HashCode 값이 동일함을 알 수 있다. 얕은복사를 통해 list1 과 list2 가 같은 메모리 주소를 가리키고 있기 때문에 List1 과 List2 어느 한쪽에서든 값을 변경하면 2개의 List가 영향을 받게 된다.&amp;nbsp;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <category>class</category>
      <category>dart</category>
      <category>deep copy</category>
      <category>Flutter</category>
      <category>list</category>
      <category>map</category>
      <category>Shallow</category>
      <category>깊은복사</category>
      <category>얕은복사</category>
      <category>플러터</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/34</guid>
      <comments>https://techsuda.tistory.com/entry/Flutter-Class-List-Map-%EB%93%B1%EC%9D%98-%EB%B3%B5%EC%82%AC-%EA%B9%8A%EC%9D%80%EB%B3%B5%EC%82%AC-%EC%96%95%EC%9D%80%EB%B3%B5%EC%82%AC#entry34comment</comments>
      <pubDate>Sun, 17 Dec 2023 15:38:58 +0900</pubDate>
    </item>
    <item>
      <title>[ Environment ] 개발 환경에 대해...</title>
      <link>https://techsuda.tistory.com/entry/Environment-%EA%B0%9C%EB%B0%9C-%ED%99%98%EA%B2%BD%EC%97%90-%EB%8C%80%ED%95%B4</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;MS-DOS때 부터 프로그래머의 길을 걷기 시작해 오늘날까지, 주로 접해왔던 언어는 C, Delphi(Object pascal), Visual Basic, Shell, SQL, Python, JAVA 찔끔, PHP랑 ASP도 찔끔, 최근에는 Flutter(dart) 를 주로 사용한다.&lt;br /&gt;Delphi는 Ver1.0때 부터 꽤 오랜기간 사용했었고, 지금까지도 그래왔지만 DB를 사용하지 않는 프로젝트는 거의 없다고 봐야 하니 SQL은 꾸준히 손 놓을 수 없는 언어이다. 과거에는 C/S 환경의 3Tier 환경이 대세였기에 규모가 좀 되는 프로젝트는 Unix 와 Oracle(Pro-C)은 필수였기에 자연스레 손에 익혔던 것 같다.&lt;br /&gt;옛날얘기는 이쯤에서 접고......&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;요즘 내가 활용하는 개발환경에 대해 잠깐 얘기해 보고자 한다. 먹고 살기 위해서라도 모바일 쪽을 안할 수 는 없겠다 싶어서 AndroidStudio, JAVA 그리고 iOS 개발을 위해 Object-C, Swift 까지 잠깐 접해 봤으나 괜시리 내 코딩 성향과는 맞지 않는 언어인 듯 하고 어려워서 인지 약간의 거부감이 들어 일찌감치 접었다. 그러던 와중에 크로스플랫폼 중 Flutter 라는 녀석을 몇년전에 처음 접해 보고 받은 느낌을 설명해 보자면, 내가 Delphi 초기 버전을 구해서 IDE 환경의 프로그램을 처음 실행시켜보던 그때의 느낌이 살짝 들었다. Dart라는 언어를 처음 접하면서도 필자가 포기할 수 없었던 중요한 챠밍포인트는 바로 크로스플랫폼 프레임웤 이라는 점과 구글의 인지도, 그리고 Material Design 이었다.&lt;br /&gt;(델파이로 안드로이드 &amp;amp; iOS 앱을 Tutorial 해본 경험에 비춰보면, 크로스플랫폼 플러터로 모바일을 지원하는 방식은 완전히 신세계였다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;그래서 지금 현재의 개발환경은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;CLIENT : FLUTTER (DART &amp;amp; SQLiTE)&lt;br /&gt;Ubuntu 에 DOCKER 로 서버 환경 구축 (Container)&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;MariaDB (or MySQL), REDIS&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;NginX (Letsencript SSL 적용)&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;Python (Restful API 제작)&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;지금은 Flutter 가 WEB 까지도 지원 영역이 넓어 졌으니 웹 프로그래밍이 부족한 필자는 WEB개발도 도전 해 볼 계획이다.&lt;br /&gt;Flutter 와 Docker 면 웬만한 환경은 커버 가능하리라 보고 있으며, 특히 도커 환경만 잘 구축해 놓으면 서비스 확장도 무척 심플하기 때문에 확장성에서도 무척 유리한 점이 많으니, Start up 이나 소규모의 프로젝트라면 충분히 선택할 만한 개발환경으로 부족함이 없을 듯 하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1305&quot; data-origin-height=&quot;264&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btePtR/btsB6oi9oWr/uIba9ajnaxlPMhYO1bsrO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btePtR/btsB6oi9oWr/uIba9ajnaxlPMhYO1bsrO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btePtR/btsB6oi9oWr/uIba9ajnaxlPMhYO1bsrO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtePtR%2FbtsB6oi9oWr%2FuIba9ajnaxlPMhYO1bsrO0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1305&quot; height=&quot;264&quot; data-origin-width=&quot;1305&quot; data-origin-height=&quot;264&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Tech Story</category>
      <category>container</category>
      <category>dart</category>
      <category>docker</category>
      <category>Flutter</category>
      <category>Python</category>
      <category>ubuntu</category>
      <category>개발환경</category>
      <category>도커</category>
      <category>파이썬</category>
      <category>플러터</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/32</guid>
      <comments>https://techsuda.tistory.com/entry/Environment-%EA%B0%9C%EB%B0%9C-%ED%99%98%EA%B2%BD%EC%97%90-%EB%8C%80%ED%95%B4#entry32comment</comments>
      <pubDate>Fri, 15 Dec 2023 23:38:02 +0900</pubDate>
    </item>
    <item>
      <title>일하다가 잠깐... 쉬던 중...</title>
      <link>https://techsuda.tistory.com/entry/%EC%9D%BC%ED%95%98%EB%8B%A4%EA%B0%80-%EC%9E%A0%EA%B9%90-%EC%89%AC%EB%8A%94-%EC%8B%9C%EA%B0%84%EC%97%90</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1707&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4Uj4S/btsBMRMZwps/FnyHqNKvvBRjgmzZKfaPKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4Uj4S/btsBMRMZwps/FnyHqNKvvBRjgmzZKfaPKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4Uj4S/btsBMRMZwps/FnyHqNKvvBRjgmzZKfaPKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4Uj4S%2FbtsBMRMZwps%2FFnyHqNKvvBRjgmzZKfaPKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1707&quot; height=&quot;1280&quot; data-origin-width=&quot;1707&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Gallery</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/31</guid>
      <comments>https://techsuda.tistory.com/entry/%EC%9D%BC%ED%95%98%EB%8B%A4%EA%B0%80-%EC%9E%A0%EA%B9%90-%EC%89%AC%EB%8A%94-%EC%8B%9C%EA%B0%84%EC%97%90#entry31comment</comments>
      <pubDate>Tue, 12 Dec 2023 16:17:37 +0900</pubDate>
    </item>
    <item>
      <title>나는 Boss 인가? 아니면 Leader 인가?</title>
      <link>https://techsuda.tistory.com/entry/%EB%82%98%EB%8A%94-Boss-%EC%9D%B8%EA%B0%80-%EC%95%84%EB%8B%88%EB%A9%B4-Leader-%EC%9D%B8%EA%B0%80-1</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccHJSX/btsBQQfKndx/1SHiNs1noNkwviB3tQWFY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccHJSX/btsBQQfKndx/1SHiNs1noNkwviB3tQWFY0/img.png&quot; data-origin-width=&quot;580&quot; data-origin-height=&quot;274&quot; data-is-animation=&quot;false&quot; width=&quot;288&quot; data-filename=&quot;blob&quot; height=&quot;136&quot; data-widthpercent=&quot;52.01&quot; style=&quot;width: 51.4092%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccHJSX/btsBQQfKndx/1SHiNs1noNkwviB3tQWFY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccHJSX%2FbtsBQQfKndx%2F1SHiNs1noNkwviB3tQWFY0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;580&quot; height=&quot;274&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OUjXH/btsBQRlsesW/s9e3YWIFJIlZYTMjpXYtyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OUjXH/btsBQRlsesW/s9e3YWIFJIlZYTMjpXYtyK/img.png&quot; data-origin-width=&quot;580&quot; data-origin-height=&quot;297&quot; data-is-animation=&quot;false&quot; data-filename=&quot;blob&quot; width=&quot;404&quot; style=&quot;width: 47.428%;&quot; data-widthpercent=&quot;47.99&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OUjXH/btsBQRlsesW/s9e3YWIFJIlZYTMjpXYtyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOUjXH%2FbtsBQRlsesW%2Fs9e3YWIFJIlZYTMjpXYtyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;580&quot; height=&quot;297&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;잠깐 사이에 너무도 많은 생각에 잠기게 된다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;오래전 직장생활 시작 초기의 나에게, 보스 와 리더의 구분 기준은 내게 잘해주는 상사와 그렇지 않은 상사. 이렇게 두 부류로 나누었던 것 같다. 이후로 세월의 강을 따라 흘러오다 문득 뒤돌아 봤더니, 어느덧 희끗해져가는 모습과 함께 누군가의 보스 또는 리더가 되어 있었다.&lt;br /&gt;나는 과연 Boss인가 아니면 Leader 인가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;조직의 규모와 팀원들의 정서, 그리고 그들의 능력치, 본인의 책임감, 때론 과감하면서도 섣부르지 않은 행동에 기인한 신중함 그리고 결단력 등등... 많은 부분을 헤아려 고민해봐야 할 문제가 아닐 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;흠.... 내가 생각하는 나는...&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;Boss(30%) Leader(50%) 정도?&lt;br /&gt;그럼 나머지 20% 는....... 상황에 따라 Boss 가 되거나 Leader가 될 수도 있는 경우의 수로 남겨두고 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #1a5490;&quot;&gt;&lt;b&gt;살아보니 현실속에는 Boss도 필요 하더라.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>Life Story</category>
      <category>boss</category>
      <category>leader</category>
      <category>리더</category>
      <category>보스</category>
      <category>조직</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/30</guid>
      <comments>https://techsuda.tistory.com/entry/%EB%82%98%EB%8A%94-Boss-%EC%9D%B8%EA%B0%80-%EC%95%84%EB%8B%88%EB%A9%B4-Leader-%EC%9D%B8%EA%B0%80-1#entry30comment</comments>
      <pubDate>Tue, 12 Dec 2023 16:16:56 +0900</pubDate>
    </item>
    <item>
      <title>[ SQL ] Query 작성 시 count() 함수의 함정</title>
      <link>https://techsuda.tistory.com/entry/SQL-Query-%EC%9E%91%EC%84%B1-%EC%8B%9C-count-%ED%95%A8%EC%88%98%EC%9D%98-%ED%95%A8%EC%A0%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;많은 개발자들이 Database Query 작성할때 습관적으로&amp;nbsp; ... count(*) ... 이렇게 사용하는 사람들이 많다.&lt;br /&gt;대개의 경우 큰 문제가 생기지는 않으나, 혹 실행 결과값이 다를 수 있음을 인지하고 사용하는 개발자는 그리 많지 않은 듯 하다. 바로 Field의 값이 Null 이냐 아니냐에 따라 리턴되는 count() 함수의 결과값이 달라질 수 있다. 예제를 보자&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nawbM/btsBuuECBbq/NwBiyOBAhBXJiLOkDkzHVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nawbM/btsBuuECBbq/NwBiyOBAhBXJiLOkDkzHVk/img.png&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;103&quot; data-is-animation=&quot;false&quot; style=&quot;width: 83.8735%; margin-right: 10px;&quot; data-widthpercent=&quot;84.86&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nawbM/btsBuuECBbq/NwBiyOBAhBXJiLOkDkzHVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnawbM%2FbtsBuuECBbq%2FNwBiyOBAhBXJiLOkDkzHVk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;461&quot; height=&quot;103&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7KMC7/btsBxegUvNl/viLniV8xpE6W0p2G1wvhz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7KMC7/btsBxegUvNl/viLniV8xpE6W0p2G1wvhz1/img.png&quot; data-widthpercent=&quot;15.14&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;134&quot; data-origin-width=&quot;107&quot; style=&quot;width: 14.9637%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7KMC7/btsBxegUvNl/viLniV8xpE6W0p2G1wvhz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7KMC7%2FbtsBxegUvNl%2FviLniV8xpE6W0p2G1wvhz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;107&quot; height=&quot;134&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예제에서 사용한 테이블 t1 은 간단하게 Nullable 속성의 2개 필드를 가지고 있고, PrimaryKey 설정도 하지 않았으며, 테스트를 위한 Record 6개를 넣은 후 전체 조회한 결과는 우측 이미지와 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;다음과 같이 3개의 쿼리를 던져보면 받는 결과값이 다름을 알 수 있으며, 필자가 얘기하려는 바가 무엇인지 바로 알 수 있을 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QI6NF/btsBy6PYczB/tv9CdGk4BvKeq6GAkDqex0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QI6NF/btsBy6PYczB/tv9CdGk4BvKeq6GAkDqex0/img.png&quot; width=&quot;245&quot; height=&quot;67&quot; data-origin-width=&quot;223&quot; data-origin-height=&quot;61&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;38.93&quot; style=&quot;width: 38.4761%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QI6NF/btsBy6PYczB/tv9CdGk4BvKeq6GAkDqex0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQI6NF%2FbtsBy6PYczB%2Ftv9CdGk4BvKeq6GAkDqex0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;223&quot; height=&quot;61&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Vfwh8/btsBrebGG31/VRy1f7yioIVWw5Tp1bige1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Vfwh8/btsBrebGG31/VRy1f7yioIVWw5Tp1bige1/img.png&quot; data-origin-width=&quot;866&quot; data-origin-height=&quot;151&quot; data-is-animation=&quot;false&quot; style=&quot;width: 60.3611%;&quot; data-widthpercent=&quot;61.07&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Vfwh8/btsBrebGG31/VRy1f7yioIVWw5Tp1bige1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVfwh8%2FbtsBrebGG31%2FVRy1f7yioIVWw5Tp1bige1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;866&quot; height=&quot;151&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;&amp;nbsp; &amp;nbsp;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다. 바로 NULL 데이터의 유무에 따라 결과값이 달라지는 것 이다.&lt;br /&gt;count(*) 의 경우 NULL 도 데이터로 인식하기 때문에 Counting 에 포함되지만, 필드를 지정하면 해당 필드의 Value 가 NULL 인 녀석들은 Counting 에서 제외 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;프로젝트 진행 시&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;Logical 오류를 디버깅할 경우는 너무도 비일비재 하다. 혹시 Query의 결과값 갯수가 예상과 다르다면 이러한 부분을 잘 살펴보기 바란다. Error번호라도 뱉어내면 바로 수정할 수 있겠지만 예상과 다른 리턴값을 받으면 골치 아프다. (사실 대부분의 개발자들이 에러가 안나면, 결과값에 대한 의심을 못하고 다른 곳만 열나게 수정하다가 DB 가 문제라고 하는 이들도 허다하다. 예전에 잘난척 오진 울 직원 하나도 그랬는데... 개뿔~~ 쭉정이였다. 누구라고는 말 못해. ㅋㅋ)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;암튼, count() 함수 사용 시 count(*) 와 count(컬럼명) 의 차이점에 대해 명확히 인지하고, 잘 사용하자.&lt;br /&gt;안 그럼 소중한 시간 낭비 후에 DB가 꼬졌다는 둥, 업그레이드를 해야 한다는 둥 말도 안되는 소리만 지껄이게 된다.&lt;/p&gt;</description>
      <category>Tech Story</category>
      <category>count</category>
      <category>count(*)</category>
      <category>database</category>
      <category>db</category>
      <category>MariaDB</category>
      <category>MySQL</category>
      <category>query</category>
      <category>데이터베이스</category>
      <category>집계함수</category>
      <category>쿼리</category>
      <author>쭝허니</author>
      <guid isPermaLink="true">https://techsuda.tistory.com/28</guid>
      <comments>https://techsuda.tistory.com/entry/SQL-Query-%EC%9E%91%EC%84%B1-%EC%8B%9C-count-%ED%95%A8%EC%88%98%EC%9D%98-%ED%95%A8%EC%A0%95#entry28comment</comments>
      <pubDate>Wed, 6 Dec 2023 17:51:41 +0900</pubDate>
    </item>
  </channel>
</rss>